From 6b7067630602ab662cf2d14793b538425700ec71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Fri, 22 Jul 2016 17:07:00 +0200 Subject: FreeType: Reduce diff with upstream 2.5.0 version The Godot specific changes to ftoption.h are indicated with a `// -Godot-` comment for clarity. See #5859 for details. --- drivers/freetype/SCsub | 8 +- .../freetype/include/freetype/config/ftoption.h | 6 +- drivers/freetype/freetype/include/ft2build.h | 40 + drivers/freetype/freetype/include/ftoption.h | 833 --------------------- drivers/freetype/ft2build.h | 41 - 5 files changed, 46 insertions(+), 882 deletions(-) create mode 100644 drivers/freetype/freetype/include/ft2build.h delete mode 100644 drivers/freetype/freetype/include/ftoption.h delete mode 100644 drivers/freetype/ft2build.h (limited to 'drivers') diff --git a/drivers/freetype/SCsub b/drivers/freetype/SCsub index c0921c683a..206da8dbe4 100644 --- a/drivers/freetype/SCsub +++ b/drivers/freetype/SCsub @@ -49,11 +49,11 @@ ft_sources=[\ if (env["freetype"]=="builtin"): -#fix for windows command line i too long, split in two libraries + # fix for Windows' shell miserably failing on long lines, split in two libraries half1=[] half2=[] for x in ft_sources: - if (x.find("freetype/src/base")==0): + if (x.find("freetype/src/base")==0 or x.find("freetype/src/sfnt")==0): half2.append(x) else: half1.append(x) @@ -63,9 +63,7 @@ if (env["freetype"]=="builtin"): lib = env.Library("freetype_builtin2",half1) env.Append(LIBS=[lib]) -# lib = env.Library("freetype_builtin",ft_sources) -# env.Prepend(LIBS=[lib]) - + env.Append(CPPPATH=["#drivers/freetype/freetype/include"]) Export('env') diff --git a/drivers/freetype/freetype/include/freetype/config/ftoption.h b/drivers/freetype/freetype/include/freetype/config/ftoption.h index d162780665..b9d840b41f 100644 --- a/drivers/freetype/freetype/include/freetype/config/ftoption.h +++ b/drivers/freetype/freetype/include/freetype/config/ftoption.h @@ -148,7 +148,7 @@ FT_BEGIN_HEADER /* */ /* Define this macro if you want to enable this `feature'. */ /* */ -#define FT_CONFIG_OPTION_USE_LZW +/* #define FT_CONFIG_OPTION_USE_LZW */ // -GODOT- /*************************************************************************/ @@ -163,7 +163,7 @@ FT_BEGIN_HEADER /* Define this macro if you want to enable this `feature'. See also */ /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ -#define FT_CONFIG_OPTION_USE_ZLIB +/* #define FT_CONFIG_OPTION_USE_ZLIB */ // -GODOT- /*************************************************************************/ @@ -765,7 +765,7 @@ FT_BEGIN_HEADER /* switch between the two engines using the `hinting-engine' property of */ /* the cff driver module. */ /* */ -#define CFF_CONFIG_OPTION_OLD_ENGINE +/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ // -GODOT- /*************************************************************************/ diff --git a/drivers/freetype/freetype/include/ft2build.h b/drivers/freetype/freetype/include/ft2build.h new file mode 100644 index 0000000000..cb23b8e24b --- /dev/null +++ b/drivers/freetype/freetype/include/ft2build.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* (Generic version) */ +/* */ +/* Copyright 1996-2001, 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file corresponds to the default `ft2build.h' file for */ + /* FreeType 2. It uses the `freetype' include root. */ + /* */ + /* Note that specific platforms might use a different configuration. */ + /* See builds/unix/ft2unix.h for an example. */ + /* */ + /*************************************************************************/ + + +#ifndef __FT2_BUILD_GENERIC_H__ +#define __FT2_BUILD_GENERIC_H__ + +#define FT2_BUILD_LIBRARY +#include + +#endif /* __FT2_BUILD_GENERIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/freetype/include/ftoption.h b/drivers/freetype/freetype/include/ftoption.h deleted file mode 100644 index c9f4708691..0000000000 --- a/drivers/freetype/freetype/include/ftoption.h +++ /dev/null @@ -1,833 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoption.h (for development) */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2013 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 __FTOPTION_H__ -#define __FTOPTION_H__ - - -#include - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* This file contains the default configuration macro definitions for */ - /* a standard build of the FreeType library. There are three ways to */ - /* use this file to build project-specific versions of the library: */ - /* */ - /* - You can modify this file by hand, but this is not recommended in */ - /* cases where you would like to build several versions of the */ - /* library from a single source directory. */ - /* */ - /* - You can put a copy of this file in your build directory, more */ - /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ - /* is the name of a directory that is included _before_ the FreeType */ - /* include path during compilation. */ - /* */ - /* The default FreeType Makefiles and Jamfiles use the build */ - /* directory `builds/' by default, but you can easily change */ - /* that for your own projects. */ - /* */ - /* - Copy the file to `$BUILD/ft2build.h' and modify it */ - /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ - /* locate this file during the build. For example, */ - /* */ - /* #define FT_CONFIG_OPTIONS_H */ - /* #include */ - /* */ - /* will use `$BUILD/myftoptions.h' instead of this file for macro */ - /* definitions. */ - /* */ - /* Note also that you can similarly pre-define the macro */ - /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ - /* that are statically linked to the library at compile time. By */ - /* default, this file is . */ - /* */ - /* We highly recommend using the third method whenever possible. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* 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 wider than */ - /* the original size in case this macro isn't defined; however, 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 */ - /* by FreeType to speed up some computations. However, this will create */ - /* some problems when compiling the library in strict ANSI mode. */ - /* */ - /* For this reason, the use of 64-bit integers is normally disabled when */ - /* the __STDC__ macro is defined. You can however disable this by */ - /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ - /* */ - /* For most compilers, this will only create compilation warnings when */ - /* building the library. */ - /* */ - /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file `ftconfig.h' either statically or through the */ - /* `configure' script on supported platforms. */ - /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 - - - /*************************************************************************/ - /* */ - /* If this macro is defined, do not try to use an assembler version of */ - /* performance-critical functions (e.g. FT_MulFix). You should only do */ - /* that to verify that the assembler function works properly, or to */ - /* execute benchmark tests of the various implementations. */ -/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ - - - /*************************************************************************/ - /* */ - /* If this macro is defined, try to use an inlined assembler version of */ - /* the `FT_MulFix' function, which is a `hotspot' when loading and */ - /* hinting glyphs, and which should be executed as fast as possible. */ - /* */ - /* Note that if your compiler or CPU is not supported, this will default */ - /* to the standard and portable implementation found in `ftcalc.c'. */ - /* */ -#define FT_CONFIG_OPTION_INLINE_MULFIX - - - /*************************************************************************/ - /* */ - /* LZW-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `compress' program. This is mostly used to parse many of the PCF */ - /* files that come with various X11 distributions. The implementation */ - /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ - /* (see src/lzw/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#undef FT_CONFIG_OPTION_USE_LZW - - - /*************************************************************************/ - /* */ - /* Gzip-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. See also */ - /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ - /* */ -#undef FT_CONFIG_OPTION_USE_ZLIB - - - /*************************************************************************/ - /* */ - /* ZLib library selection */ - /* */ - /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's `ftgzip' component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ - /* Unix or VMS where it generally is already available. */ - /* */ - /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ - /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ - /* _and_ ZLib without linking conflicts. */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ - - - /*************************************************************************/ - /* */ - /* Bzip2-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `bzip2' program. This is mostly used to parse many of the PCF */ - /* files that come with XFree86. The implementation uses `libbz2' to */ - /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ - /* Contrary to gzip, bzip2 currently is not included and need to use */ - /* the system available bzip2 implementation. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#undef FT_CONFIG_OPTION_USE_BZIP2 - - - /*************************************************************************/ - /* */ - /* PNG bitmap support. */ - /* */ - /* FreeType now handles loading color bitmap glyphs in the PNG format. */ - /* This requires help from the external libpng library. Uncompressed */ - /* color bitmaps do not need any external libraries and will be */ - /* supported regardless of this configuration. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#undef FT_CONFIG_OPTION_USE_PNG - - - /*************************************************************************/ - /* */ - /* Define to disable the use of file stream functions and types, FILE, */ - /* fopen() etc. Enables the use of smaller system libraries on embedded */ - /* systems that have multiple system libraries, some with or without */ - /* file stream support, in the cases where file stream support is not */ - /* necessary such as memory loading of font files. */ - /* */ -/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - - - /*************************************************************************/ - /* */ - /* DLL export compilation */ - /* */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special keyword in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ - /* */ - /* FT_EXPORT( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT and */ - /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ - /* will be later automatically defined as `extern return_type' to */ - /* allow normal compilation. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ - - - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `psnames' module. This */ - /* module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `psnames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ - /* */ - /* - The Type 1 driver will not be able to synthesize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ -#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthesize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ -#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /*************************************************************************/ - /* */ - /* Support for Mac fonts */ - /* */ - /* Define this macro if you want support for outline fonts in Mac */ - /* format (mac dfont, mac resource, macbinary containing a mac */ - /* resource) on non-Mac platforms. */ - /* */ - /* Note that the `FOND' resource isn't checked. */ - /* */ -#define FT_CONFIG_OPTION_MAC_FONTS - - - /*************************************************************************/ - /* */ - /* Guessing methods to access embedded resource forks */ - /* */ - /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ - /* GNU/Linux). */ - /* */ - /* Resource forks which include fonts data are stored sometimes in */ - /* locations which users or developers don't expected. In some cases, */ - /* resource forks start with some offset from the head of a file. In */ - /* other cases, the actual resource fork is stored in file different */ - /* from what the user specifies. If this option is activated, */ - /* FreeType tries to guess whether such offsets or different file */ - /* names must be used. */ - /* */ - /* Note that normal, direct access of resource forks is controlled via */ - /* the FT_CONFIG_OPTION_MAC_FONTS option. */ - /* */ -#ifdef FT_CONFIG_OPTION_MAC_FONTS -#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#endif - - - /*************************************************************************/ - /* */ - /* Allow the use of FT_Incremental_Interface to load typefaces that */ - /* contain no glyph data, but supply it via a callback function. */ - /* This is required by clients supporting document formats which */ - /* supply font data incrementally as the document is parsed, such */ - /* as the Ghostscript interpreter for the PostScript language. */ - /* */ -#define FT_CONFIG_OPTION_INCREMENTAL - - - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ - /* This must be greater than 4KByte if you use FreeType to rasterize */ - /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ - /* allocation of the render pool. */ - /* */ -#define FT_RENDER_POOL_SIZE 16384L - - - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 32 is the default. */ - /* */ -#define FT_MAX_MODULES 32 - - - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -#define FT_DEBUG_LEVEL_ERROR -#define FT_DEBUG_LEVEL_TRACE - - - /*************************************************************************/ - /* */ - /* Autofitter debugging */ - /* */ - /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ - /* control the autofitter behaviour for debugging purposes with global */ - /* boolean variables (consequently, you should *never* enable this */ - /* while compiling in `release' mode): */ - /* */ - /* _af_debug_disable_horz_hints */ - /* _af_debug_disable_vert_hints */ - /* _af_debug_disable_blue_hints */ - /* */ - /* Additionally, the following functions provide dumps of various */ - /* internal autofit structures to stdout (using `printf'): */ - /* */ - /* af_glyph_hints_dump_points */ - /* af_glyph_hints_dump_segments */ - /* af_glyph_hints_dump_edges */ - /* */ - /* As an argument, they use another global variable: */ - /* */ - /* _af_debug_hints */ - /* */ - /* Please have a look at the `ftgrid' demo program to see how those */ - /* variables and macros should be used. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -#define FT_DEBUG_AUTOFIT - - - /*************************************************************************/ - /* */ - /* Memory Debugging */ - /* */ - /* FreeType now comes with an integrated memory debugger that is */ - /* capable of detecting simple errors like memory leaks or double */ - /* deletes. To compile it within your build of the library, you */ - /* should define FT_DEBUG_MEMORY here. */ - /* */ - /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -#define FT_DEBUG_MEMORY - - - /*************************************************************************/ - /* */ - /* Module errors */ - /* */ - /* If this macro is set (which is _not_ the default), the higher byte */ - /* of an error code gives the module in which the error has occurred, */ - /* while the lower byte is the real error code. */ - /* */ - /* Setting this macro makes sense for debugging purposes only, since */ - /* it would break source compatibility of certain programs that use */ - /* FreeType 2. */ - /* */ - /* More details can be found in the files ftmoderr.h and fterrors.h. */ - /* */ -#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS - - - /*************************************************************************/ - /* */ - /* Position Independent Code */ - /* */ - /* If this macro is set (which is _not_ the default), FreeType2 will */ - /* avoid creating constants that require address fixups. Instead the */ - /* constants will be moved into a struct and additional intialization */ - /* code will be used. */ - /* */ - /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. */ - /* */ -/* #define FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ -#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ -#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftsnames.h'. */ - /* */ -#define TT_CONFIG_OPTION_SFNT_NAMES - - - /*************************************************************************/ - /* */ - /* TrueType CMap support */ - /* */ - /* Here you can fine-tune which TrueType CMap table format shall be */ - /* supported. */ -#define TT_CONFIG_CMAP_FORMAT_0 -#define TT_CONFIG_CMAP_FORMAT_2 -#define TT_CONFIG_CMAP_FORMAT_4 -#define TT_CONFIG_CMAP_FORMAT_6 -#define TT_CONFIG_CMAP_FORMAT_8 -#define TT_CONFIG_CMAP_FORMAT_10 -#define TT_CONFIG_CMAP_FORMAT_12 -#define TT_CONFIG_CMAP_FORMAT_13 -#define TT_CONFIG_CMAP_FORMAT_14 - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ - /* Do not #undef this macro here, since the build system might */ - /* define it for certain configurations only. */ - /* */ -#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ - /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ - /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ -#define TT_CONFIG_OPTION_SUBPIXEL_HINTING - - - /*************************************************************************/ - /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ - /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ - /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ - /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ - /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ - /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ - /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ - /* */ - /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ - /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ - /* bytecode interpreter with a huge switch statement, rather than a call */ - /* table. This results in smaller and faster code for a number of */ - /* architectures. */ - /* */ - /* Note however that on some compiler/processor combinations, undefining */ - /* this macro will generate faster, though larger, code. */ - /* */ -#define TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ - /* TrueType glyph loader to use Apple's definition of how to handle */ - /* component offsets in composite glyphs. */ - /* */ - /* Apple and MS disagree on the default behavior of component offsets */ - /* in composites. Apple says that they should be scaled by the scaling */ - /* factors in the transformation matrix (roughly, it's more complex) */ - /* while MS says they should not. OpenType defines two bits in the */ - /* composite flags array which can be used to disambiguate, but old */ - /* fonts will not have them. */ - /* */ - /* http://www.microsoft.com/typography/otspec/glyf.htm */ - /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ - /* */ -#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ - /* support for Apple's distortable font technology (fvar, gvar, cvar, */ - /* and avar tables). This has many similarities to Type 1 Multiple */ - /* Masters support. */ - /* */ -#define TT_CONFIG_OPTION_GX_VAR_SUPPORT - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ - /* an embedded `BDF ' table within SFNT-based bitmap formats. */ - /* */ -#define TT_CONFIG_OPTION_BDF - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ -#define T1_MAX_DICT_DEPTH 5 - - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 16 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ - /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 256 - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ -#undef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ -#undef T1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** C F F D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the cff driver module. */ - /* */ -/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ - /* support. */ - /* */ -#define AF_CONFIG_OPTION_CJK - - /*************************************************************************/ - /* */ - /* Compile autofit module with Indic script support. */ - /* */ -#define AF_CONFIG_OPTION_INDIC - - /*************************************************************************/ - /* */ - /* Compile autofit module with warp hinting. The idea of the warping */ - /* code is to slightly scale and shift a glyph within a single dimension */ - /* so that as much of its segments are aligned (more or less) on the */ - /* grid. To find out the optimal scaling and shifting value, various */ - /* parameter combinations are tried and scored. */ - /* */ - /* This experimental option is only active if the render mode is */ - /* FT_RENDER_MODE_LIGHT. */ - /* */ -#define AF_CONFIG_OPTION_USE_WARPER - - /* */ - - - /* - * This macro is obsolete. Support has been removed in FreeType - * version 2.5. - */ -/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ - - - /* - * This macro 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 -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER -#endif - -FT_END_HEADER - - -#endif /* __FTOPTION_H__ */ - - -/* END */ diff --git a/drivers/freetype/ft2build.h b/drivers/freetype/ft2build.h deleted file mode 100644 index 5137b50f38..0000000000 --- a/drivers/freetype/ft2build.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* ft2build.h */ -/* */ -/* FreeType 2 build and setup macros. */ -/* (Generic version) */ -/* */ -/* Copyright 1996-2001, 2003, 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. */ -/* */ -/***************************************************************************/ - - - /* - * This is a development version of that is used - * to build the library in debug mode. Its only difference with - * the reference is that it forces the use of the local `ftoption.h' - * which contains different settings for all configuration macros. - * - * To use it, you must define the environment variable FT2_BUILD_INCLUDE - * to point to the directory containing these two files (`ft2build.h' and - * `ftoption.h'), then invoke Jam as usual. - */ - -#ifndef __FT2_BUILD_DEVEL_H__ -#define __FT2_BUILD_DEVEL_H__ - -#define FT_CONFIG_OPTIONS_H -#define FT2_BUILD_LIBRARY -#include - -#endif /* __FT2_BUILD_DEVEL_H__ */ - - -/* END */ -- cgit v1.2.3 From b13bbcecc31851099d49ac7f435ea7c80de5d9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Fri, 22 Jul 2016 22:01:16 +0200 Subject: FreeType: Remove unnecessary subfolder Also sort sources alphabetically for clarity. --- drivers/freetype/SCsub | 91 +- .../freetype/include/freetype/config/ftconfig.h | 598 -- .../freetype/include/freetype/config/ftheader.h | 832 -- .../freetype/include/freetype/config/ftmodule.h | 32 - .../freetype/include/freetype/config/ftoption.h | 833 -- .../freetype/include/freetype/config/ftstdlib.h | 174 - .../freetype/freetype/include/freetype/freetype.h | 4012 --------- .../freetype/freetype/include/freetype/ftadvanc.h | 182 - .../freetype/freetype/include/freetype/ftautoh.h | 357 - .../freetype/freetype/include/freetype/ftbbox.h | 102 - drivers/freetype/freetype/include/freetype/ftbdf.h | 209 - .../freetype/freetype/include/freetype/ftbitmap.h | 227 - .../freetype/freetype/include/freetype/ftbzip2.h | 102 - .../freetype/freetype/include/freetype/ftcache.h | 1057 --- .../freetype/freetype/include/freetype/ftcffdrv.h | 151 - .../freetype/include/freetype/ftchapters.h | 120 - drivers/freetype/freetype/include/freetype/ftcid.h | 166 - .../freetype/freetype/include/freetype/fterrdef.h | 249 - .../freetype/freetype/include/freetype/fterrors.h | 198 - .../freetype/freetype/include/freetype/ftgasp.h | 128 - .../freetype/freetype/include/freetype/ftglyph.h | 620 -- .../freetype/freetype/include/freetype/ftgxval.h | 358 - .../freetype/freetype/include/freetype/ftgzip.h | 102 - .../freetype/freetype/include/freetype/ftimage.h | 1322 --- .../freetype/freetype/include/freetype/ftincrem.h | 353 - .../freetype/freetype/include/freetype/ftlcdfil.h | 251 - .../freetype/freetype/include/freetype/ftlist.h | 277 - drivers/freetype/freetype/include/freetype/ftlzw.h | 99 - drivers/freetype/freetype/include/freetype/ftmac.h | 274 - drivers/freetype/freetype/include/freetype/ftmm.h | 378 - .../freetype/freetype/include/freetype/ftmodapi.h | 641 -- .../freetype/freetype/include/freetype/ftmoderr.h | 194 - .../freetype/freetype/include/freetype/ftotval.h | 203 - .../freetype/freetype/include/freetype/ftoutln.h | 560 -- drivers/freetype/freetype/include/freetype/ftpfr.h | 172 - .../freetype/freetype/include/freetype/ftrender.h | 238 - .../freetype/freetype/include/freetype/ftsizes.h | 159 - .../freetype/freetype/include/freetype/ftsnames.h | 200 - .../freetype/freetype/include/freetype/ftstroke.h | 751 -- .../freetype/freetype/include/freetype/ftsynth.h | 81 - .../freetype/freetype/include/freetype/ftsystem.h | 347 - .../freetype/freetype/include/freetype/fttrigon.h | 350 - .../freetype/freetype/include/freetype/ftttdrv.h | 150 - .../freetype/freetype/include/freetype/fttypes.h | 598 -- .../freetype/freetype/include/freetype/ftwinfnt.h | 274 - .../freetype/freetype/include/freetype/ftxf86.h | 83 - .../freetype/include/freetype/internal/autohint.h | 244 - .../freetype/include/freetype/internal/ftcalc.h | 167 - .../freetype/include/freetype/internal/ftdebug.h | 255 - .../freetype/include/freetype/internal/ftdriver.h | 409 - .../freetype/include/freetype/internal/ftgloadr.h | 168 - .../freetype/include/freetype/internal/ftmemory.h | 378 - .../freetype/include/freetype/internal/ftobjs.h | 1569 ---- .../freetype/include/freetype/internal/ftpic.h | 71 - .../freetype/include/freetype/internal/ftrfork.h | 258 - .../freetype/include/freetype/internal/ftserv.h | 763 -- .../freetype/include/freetype/internal/ftstream.h | 536 -- .../freetype/include/freetype/internal/fttrace.h | 152 - .../freetype/include/freetype/internal/ftvalid.h | 161 - .../freetype/include/freetype/internal/internal.h | 63 - .../freetype/include/freetype/internal/psaux.h | 877 -- .../freetype/include/freetype/internal/pshints.h | 722 -- .../include/freetype/internal/services/svbdf.h | 82 - .../include/freetype/internal/services/svcid.h | 89 - .../include/freetype/internal/services/svgldict.h | 88 - .../include/freetype/internal/services/svgxval.h | 72 - .../include/freetype/internal/services/svkern.h | 51 - .../include/freetype/internal/services/svmm.h | 113 - .../include/freetype/internal/services/svotval.h | 55 - .../include/freetype/internal/services/svpfr.h | 66 - .../include/freetype/internal/services/svpostnm.h | 81 - .../include/freetype/internal/services/svprop.h | 81 - .../include/freetype/internal/services/svpscmap.h | 177 - .../include/freetype/internal/services/svpsinfo.h | 111 - .../include/freetype/internal/services/svsfnt.h | 103 - .../include/freetype/internal/services/svttcmap.h | 107 - .../include/freetype/internal/services/svtteng.h | 53 - .../include/freetype/internal/services/svttglyf.h | 68 - .../include/freetype/internal/services/svwinfnt.h | 50 - .../include/freetype/internal/services/svxf86nm.h | 55 - .../freetype/include/freetype/internal/sfnt.h | 707 -- .../freetype/include/freetype/internal/t1types.h | 255 - .../freetype/include/freetype/internal/tttypes.h | 1440 ---- .../freetype/freetype/include/freetype/t1tables.h | 662 -- .../freetype/freetype/include/freetype/ttnameid.h | 1237 --- .../freetype/freetype/include/freetype/tttables.h | 777 -- .../freetype/freetype/include/freetype/tttags.h | 109 - .../freetype/freetype/include/freetype/ttunpat.h | 59 - drivers/freetype/freetype/include/ft2build.h | 40 - drivers/freetype/freetype/src/Jamfile | 25 - drivers/freetype/freetype/src/autofit/Jamfile | 39 - drivers/freetype/freetype/src/autofit/afangles.c | 345 - drivers/freetype/freetype/src/autofit/afangles.h | 7 - drivers/freetype/freetype/src/autofit/afcjk.c | 2275 ----- drivers/freetype/freetype/src/autofit/afcjk.h | 142 - drivers/freetype/freetype/src/autofit/afdummy.c | 62 - drivers/freetype/freetype/src/autofit/afdummy.h | 42 - drivers/freetype/freetype/src/autofit/aferrors.h | 41 - drivers/freetype/freetype/src/autofit/afglobal.c | 304 - drivers/freetype/freetype/src/autofit/afglobal.h | 109 - drivers/freetype/freetype/src/autofit/afhints.c | 1321 --- drivers/freetype/freetype/src/autofit/afhints.h | 467 - drivers/freetype/freetype/src/autofit/afindic.c | 157 - drivers/freetype/freetype/src/autofit/afindic.h | 40 - drivers/freetype/freetype/src/autofit/aflatin.c | 2486 ------ drivers/freetype/freetype/src/autofit/aflatin.h | 202 - drivers/freetype/freetype/src/autofit/aflatin2.c | 2406 ------ drivers/freetype/freetype/src/autofit/aflatin2.h | 39 - drivers/freetype/freetype/src/autofit/afloader.c | 561 -- drivers/freetype/freetype/src/autofit/afloader.h | 85 - drivers/freetype/freetype/src/autofit/afmodule.c | 264 - drivers/freetype/freetype/src/autofit/afmodule.h | 58 - drivers/freetype/freetype/src/autofit/afpic.c | 137 - drivers/freetype/freetype/src/autofit/afpic.h | 96 - drivers/freetype/freetype/src/autofit/aftypes.h | 378 - drivers/freetype/freetype/src/autofit/afwarp.c | 374 - drivers/freetype/freetype/src/autofit/afwarp.h | 64 - drivers/freetype/freetype/src/autofit/autofit.c | 41 - drivers/freetype/freetype/src/autofit/module.mk | 23 - drivers/freetype/freetype/src/autofit/rules.mk | 79 - drivers/freetype/freetype/src/base/Jamfile | 60 - drivers/freetype/freetype/src/base/basepic.c | 108 - drivers/freetype/freetype/src/base/basepic.h | 90 - drivers/freetype/freetype/src/base/ftadvanc.c | 162 - drivers/freetype/freetype/src/base/ftapi.c | 121 - drivers/freetype/freetype/src/base/ftbase.c | 41 - drivers/freetype/freetype/src/base/ftbase.h | 69 - drivers/freetype/freetype/src/base/ftbbox.c | 649 -- drivers/freetype/freetype/src/base/ftbdf.c | 88 - drivers/freetype/freetype/src/base/ftbitmap.c | 758 -- drivers/freetype/freetype/src/base/ftcalc.c | 974 --- drivers/freetype/freetype/src/base/ftcid.c | 117 - drivers/freetype/freetype/src/base/ftdbgmem.c | 992 --- drivers/freetype/freetype/src/base/ftdebug.c | 266 - drivers/freetype/freetype/src/base/ftfstype.c | 62 - drivers/freetype/freetype/src/base/ftgasp.c | 61 - drivers/freetype/freetype/src/base/ftgloadr.c | 405 - drivers/freetype/freetype/src/base/ftglyph.c | 629 -- drivers/freetype/freetype/src/base/ftgxval.c | 142 - drivers/freetype/freetype/src/base/ftinit.c | 282 - drivers/freetype/freetype/src/base/ftlcdfil.c | 378 - drivers/freetype/freetype/src/base/ftmac.c | 1061 --- drivers/freetype/freetype/src/base/ftmm.c | 204 - drivers/freetype/freetype/src/base/ftobjs.c | 4870 ----------- drivers/freetype/freetype/src/base/ftotval.c | 91 - drivers/freetype/freetype/src/base/ftoutln.c | 1081 --- drivers/freetype/freetype/src/base/ftpatent.c | 286 - drivers/freetype/freetype/src/base/ftpfr.c | 146 - drivers/freetype/freetype/src/base/ftpic.c | 55 - drivers/freetype/freetype/src/base/ftrfork.c | 849 -- drivers/freetype/freetype/src/base/ftsnames.c | 94 - drivers/freetype/freetype/src/base/ftstream.c | 865 -- drivers/freetype/freetype/src/base/ftstroke.c | 2418 ------ drivers/freetype/freetype/src/base/ftsynth.c | 153 - drivers/freetype/freetype/src/base/ftsystem.c | 320 - drivers/freetype/freetype/src/base/fttrigon.c | 492 -- drivers/freetype/freetype/src/base/fttype1.c | 120 - drivers/freetype/freetype/src/base/ftutil.c | 436 - drivers/freetype/freetype/src/base/ftwinfnt.c | 51 - drivers/freetype/freetype/src/base/ftxf86.c | 40 - drivers/freetype/freetype/src/base/md5.c | 295 - drivers/freetype/freetype/src/base/md5.h | 45 - drivers/freetype/freetype/src/base/rules.mk | 99 - drivers/freetype/freetype/src/bdf/Jamfile | 29 - drivers/freetype/freetype/src/bdf/README | 148 - drivers/freetype/freetype/src/bdf/bdf.c | 34 - drivers/freetype/freetype/src/bdf/bdf.h | 297 - drivers/freetype/freetype/src/bdf/bdfdrivr.c | 878 -- drivers/freetype/freetype/src/bdf/bdfdrivr.h | 80 - drivers/freetype/freetype/src/bdf/bdferror.h | 45 - drivers/freetype/freetype/src/bdf/bdflib.c | 2625 ------ drivers/freetype/freetype/src/bdf/module.mk | 34 - drivers/freetype/freetype/src/bdf/rules.mk | 81 - drivers/freetype/freetype/src/cache/Jamfile | 43 - drivers/freetype/freetype/src/cache/ftcache.c | 31 - drivers/freetype/freetype/src/cache/ftcbasic.c | 602 -- drivers/freetype/freetype/src/cache/ftccache.c | 621 -- drivers/freetype/freetype/src/cache/ftccache.h | 352 - drivers/freetype/freetype/src/cache/ftccback.h | 91 - drivers/freetype/freetype/src/cache/ftccmap.c | 337 - drivers/freetype/freetype/src/cache/ftcerror.h | 41 - drivers/freetype/freetype/src/cache/ftcglyph.c | 219 - drivers/freetype/freetype/src/cache/ftcglyph.h | 329 - drivers/freetype/freetype/src/cache/ftcimage.c | 163 - drivers/freetype/freetype/src/cache/ftcimage.h | 107 - drivers/freetype/freetype/src/cache/ftcmanag.c | 693 -- drivers/freetype/freetype/src/cache/ftcmanag.h | 175 - drivers/freetype/freetype/src/cache/ftcmru.c | 357 - drivers/freetype/freetype/src/cache/ftcmru.h | 246 - drivers/freetype/freetype/src/cache/ftcsbits.c | 421 - drivers/freetype/freetype/src/cache/ftcsbits.h | 103 - drivers/freetype/freetype/src/cache/rules.mk | 80 - drivers/freetype/freetype/src/cff/Jamfile | 29 - drivers/freetype/freetype/src/cff/cf2arrst.c | 241 - drivers/freetype/freetype/src/cff/cf2arrst.h | 100 - drivers/freetype/freetype/src/cff/cf2blues.c | 578 -- drivers/freetype/freetype/src/cff/cf2blues.h | 185 - drivers/freetype/freetype/src/cff/cf2error.c | 52 - drivers/freetype/freetype/src/cff/cf2error.h | 119 - drivers/freetype/freetype/src/cff/cf2fixed.h | 95 - drivers/freetype/freetype/src/cff/cf2font.c | 403 - drivers/freetype/freetype/src/cff/cf2font.h | 114 - drivers/freetype/freetype/src/cff/cf2ft.c | 639 -- drivers/freetype/freetype/src/cff/cf2ft.h | 147 - drivers/freetype/freetype/src/cff/cf2glue.h | 144 - drivers/freetype/freetype/src/cff/cf2hints.c | 1734 ---- drivers/freetype/freetype/src/cff/cf2hints.h | 287 - drivers/freetype/freetype/src/cff/cf2intrp.c | 1538 ---- drivers/freetype/freetype/src/cff/cf2intrp.h | 83 - drivers/freetype/freetype/src/cff/cf2read.c | 112 - drivers/freetype/freetype/src/cff/cf2read.h | 68 - drivers/freetype/freetype/src/cff/cf2stack.c | 205 - drivers/freetype/freetype/src/cff/cf2stack.h | 106 - drivers/freetype/freetype/src/cff/cf2types.h | 78 - drivers/freetype/freetype/src/cff/cff.c | 41 - drivers/freetype/freetype/src/cff/cffcmap.c | 210 - drivers/freetype/freetype/src/cff/cffcmap.h | 67 - drivers/freetype/freetype/src/cff/cffdrivr.c | 786 -- drivers/freetype/freetype/src/cff/cffdrivr.h | 38 - drivers/freetype/freetype/src/cff/cfferrs.h | 42 - drivers/freetype/freetype/src/cff/cffgload.c | 3068 ------- drivers/freetype/freetype/src/cff/cffgload.h | 240 - drivers/freetype/freetype/src/cff/cffload.c | 1696 ---- drivers/freetype/freetype/src/cff/cffload.h | 83 - drivers/freetype/freetype/src/cff/cffobjs.c | 1077 --- drivers/freetype/freetype/src/cff/cffobjs.h | 183 - drivers/freetype/freetype/src/cff/cffparse.c | 1177 --- drivers/freetype/freetype/src/cff/cffparse.h | 106 - drivers/freetype/freetype/src/cff/cffpic.c | 138 - drivers/freetype/freetype/src/cff/cffpic.h | 108 - drivers/freetype/freetype/src/cff/cfftoken.h | 97 - drivers/freetype/freetype/src/cff/cfftypes.h | 284 - drivers/freetype/freetype/src/cff/module.mk | 23 - drivers/freetype/freetype/src/cff/rules.mk | 86 - drivers/freetype/freetype/src/cid/Jamfile | 29 - drivers/freetype/freetype/src/cid/ciderrs.h | 41 - drivers/freetype/freetype/src/cid/cidgload.c | 442 - drivers/freetype/freetype/src/cid/cidgload.h | 51 - drivers/freetype/freetype/src/cid/cidload.c | 690 -- drivers/freetype/freetype/src/cid/cidload.h | 53 - drivers/freetype/freetype/src/cid/cidobjs.c | 491 -- drivers/freetype/freetype/src/cid/cidobjs.h | 154 - drivers/freetype/freetype/src/cid/cidparse.c | 225 - drivers/freetype/freetype/src/cid/cidparse.h | 123 - drivers/freetype/freetype/src/cid/cidriver.c | 236 - drivers/freetype/freetype/src/cid/cidriver.h | 43 - drivers/freetype/freetype/src/cid/cidtoken.h | 112 - drivers/freetype/freetype/src/cid/module.mk | 23 - drivers/freetype/freetype/src/cid/rules.mk | 70 - drivers/freetype/freetype/src/cid/type1cid.c | 29 - drivers/freetype/freetype/src/gxvalid/Jamfile | 33 - drivers/freetype/freetype/src/gxvalid/README | 532 -- drivers/freetype/freetype/src/gxvalid/gxvalid.c | 46 - drivers/freetype/freetype/src/gxvalid/gxvalid.h | 107 - drivers/freetype/freetype/src/gxvalid/gxvbsln.c | 333 - drivers/freetype/freetype/src/gxvalid/gxvcommn.c | 1744 ---- drivers/freetype/freetype/src/gxvalid/gxvcommn.h | 582 -- drivers/freetype/freetype/src/gxvalid/gxverror.h | 51 - drivers/freetype/freetype/src/gxvalid/gxvfeat.c | 339 - drivers/freetype/freetype/src/gxvalid/gxvfeat.h | 172 - drivers/freetype/freetype/src/gxvalid/gxvfgen.c | 482 -- drivers/freetype/freetype/src/gxvalid/gxvjust.c | 717 -- drivers/freetype/freetype/src/gxvalid/gxvkern.c | 920 -- drivers/freetype/freetype/src/gxvalid/gxvlcar.c | 223 - drivers/freetype/freetype/src/gxvalid/gxvmod.c | 285 - drivers/freetype/freetype/src/gxvalid/gxvmod.h | 50 - drivers/freetype/freetype/src/gxvalid/gxvmort.c | 297 - drivers/freetype/freetype/src/gxvalid/gxvmort.h | 93 - drivers/freetype/freetype/src/gxvalid/gxvmort0.c | 151 - drivers/freetype/freetype/src/gxvalid/gxvmort1.c | 259 - drivers/freetype/freetype/src/gxvalid/gxvmort2.c | 311 - drivers/freetype/freetype/src/gxvalid/gxvmort4.c | 125 - drivers/freetype/freetype/src/gxvalid/gxvmort5.c | 233 - drivers/freetype/freetype/src/gxvalid/gxvmorx.c | 199 - drivers/freetype/freetype/src/gxvalid/gxvmorx.h | 67 - drivers/freetype/freetype/src/gxvalid/gxvmorx0.c | 111 - drivers/freetype/freetype/src/gxvalid/gxvmorx1.c | 277 - drivers/freetype/freetype/src/gxvalid/gxvmorx2.c | 327 - drivers/freetype/freetype/src/gxvalid/gxvmorx4.c | 55 - drivers/freetype/freetype/src/gxvalid/gxvmorx5.c | 225 - drivers/freetype/freetype/src/gxvalid/gxvopbd.c | 217 - drivers/freetype/freetype/src/gxvalid/gxvprop.c | 329 - drivers/freetype/freetype/src/gxvalid/gxvtrak.c | 286 - drivers/freetype/freetype/src/gxvalid/module.mk | 23 - drivers/freetype/freetype/src/gxvalid/rules.mk | 94 - drivers/freetype/freetype/src/otvalid/Jamfile | 29 - drivers/freetype/freetype/src/otvalid/module.mk | 23 - drivers/freetype/freetype/src/otvalid/otvalid.c | 31 - drivers/freetype/freetype/src/otvalid/otvalid.h | 78 - drivers/freetype/freetype/src/otvalid/otvbase.c | 318 - drivers/freetype/freetype/src/otvalid/otvcommn.c | 1086 --- drivers/freetype/freetype/src/otvalid/otvcommn.h | 437 - drivers/freetype/freetype/src/otvalid/otverror.h | 42 - drivers/freetype/freetype/src/otvalid/otvgdef.c | 224 - drivers/freetype/freetype/src/otvalid/otvgpos.c | 1017 --- drivers/freetype/freetype/src/otvalid/otvgpos.h | 36 - drivers/freetype/freetype/src/otvalid/otvgsub.c | 585 -- drivers/freetype/freetype/src/otvalid/otvjstf.c | 258 - drivers/freetype/freetype/src/otvalid/otvmath.c | 453 - drivers/freetype/freetype/src/otvalid/otvmod.c | 282 - drivers/freetype/freetype/src/otvalid/otvmod.h | 43 - drivers/freetype/freetype/src/otvalid/rules.mk | 78 - drivers/freetype/freetype/src/pcf/Jamfile | 29 - drivers/freetype/freetype/src/pcf/README | 96 - drivers/freetype/freetype/src/pcf/module.mk | 34 - drivers/freetype/freetype/src/pcf/pcf.c | 36 - drivers/freetype/freetype/src/pcf/pcf.h | 237 - drivers/freetype/freetype/src/pcf/pcfdrivr.c | 713 -- drivers/freetype/freetype/src/pcf/pcfdrivr.h | 48 - drivers/freetype/freetype/src/pcf/pcferror.h | 41 - drivers/freetype/freetype/src/pcf/pcfread.c | 1269 --- drivers/freetype/freetype/src/pcf/pcfread.h | 45 - drivers/freetype/freetype/src/pcf/pcfutil.c | 104 - drivers/freetype/freetype/src/pcf/pcfutil.h | 55 - drivers/freetype/freetype/src/pcf/rules.mk | 79 - drivers/freetype/freetype/src/pfr/Jamfile | 29 - drivers/freetype/freetype/src/pfr/module.mk | 23 - drivers/freetype/freetype/src/pfr/pfr.c | 29 - drivers/freetype/freetype/src/pfr/pfrcmap.c | 168 - drivers/freetype/freetype/src/pfr/pfrcmap.h | 46 - drivers/freetype/freetype/src/pfr/pfrdrivr.c | 210 - drivers/freetype/freetype/src/pfr/pfrdrivr.h | 43 - drivers/freetype/freetype/src/pfr/pfrerror.h | 41 - drivers/freetype/freetype/src/pfr/pfrgload.c | 844 -- drivers/freetype/freetype/src/pfr/pfrgload.h | 49 - drivers/freetype/freetype/src/pfr/pfrload.c | 941 -- drivers/freetype/freetype/src/pfr/pfrload.h | 118 - drivers/freetype/freetype/src/pfr/pfrobjs.c | 593 -- drivers/freetype/freetype/src/pfr/pfrobjs.h | 96 - drivers/freetype/freetype/src/pfr/pfrsbit.c | 698 -- drivers/freetype/freetype/src/pfr/pfrsbit.h | 36 - drivers/freetype/freetype/src/pfr/pfrtypes.h | 362 - drivers/freetype/freetype/src/pfr/rules.mk | 73 - drivers/freetype/freetype/src/psaux/Jamfile | 31 - drivers/freetype/freetype/src/psaux/afmparse.c | 964 --- drivers/freetype/freetype/src/psaux/afmparse.h | 88 - drivers/freetype/freetype/src/psaux/module.mk | 23 - drivers/freetype/freetype/src/psaux/psaux.c | 34 - drivers/freetype/freetype/src/psaux/psauxerr.h | 42 - drivers/freetype/freetype/src/psaux/psauxmod.c | 139 - drivers/freetype/freetype/src/psaux/psauxmod.h | 42 - drivers/freetype/freetype/src/psaux/psconv.c | 602 -- drivers/freetype/freetype/src/psaux/psconv.h | 71 - drivers/freetype/freetype/src/psaux/psobjs.c | 1765 ---- drivers/freetype/freetype/src/psaux/psobjs.h | 212 - drivers/freetype/freetype/src/psaux/rules.mk | 73 - drivers/freetype/freetype/src/psaux/t1cmap.c | 341 - drivers/freetype/freetype/src/psaux/t1cmap.h | 105 - drivers/freetype/freetype/src/psaux/t1decode.c | 1620 ---- drivers/freetype/freetype/src/psaux/t1decode.h | 64 - drivers/freetype/freetype/src/pshinter/Jamfile | 29 - drivers/freetype/freetype/src/pshinter/module.mk | 23 - drivers/freetype/freetype/src/pshinter/pshalgo.c | 2305 ----- drivers/freetype/freetype/src/pshinter/pshalgo.h | 246 - drivers/freetype/freetype/src/pshinter/pshglob.c | 797 -- drivers/freetype/freetype/src/pshinter/pshglob.h | 196 - drivers/freetype/freetype/src/pshinter/pshinter.c | 29 - drivers/freetype/freetype/src/pshinter/pshmod.c | 119 - drivers/freetype/freetype/src/pshinter/pshmod.h | 39 - drivers/freetype/freetype/src/pshinter/pshnterr.h | 41 - drivers/freetype/freetype/src/pshinter/pshpic.c | 76 - drivers/freetype/freetype/src/pshinter/pshpic.h | 63 - drivers/freetype/freetype/src/pshinter/pshrec.c | 1225 --- drivers/freetype/freetype/src/pshinter/pshrec.h | 176 - drivers/freetype/freetype/src/pshinter/rules.mk | 73 - drivers/freetype/freetype/src/psnames/Jamfile | 29 - drivers/freetype/freetype/src/psnames/module.mk | 23 - drivers/freetype/freetype/src/psnames/psmodule.c | 609 -- drivers/freetype/freetype/src/psnames/psmodule.h | 38 - drivers/freetype/freetype/src/psnames/psnamerr.h | 42 - drivers/freetype/freetype/src/psnames/psnames.c | 26 - drivers/freetype/freetype/src/psnames/pspic.c | 97 - drivers/freetype/freetype/src/psnames/pspic.h | 66 - drivers/freetype/freetype/src/psnames/pstables.h | 4170 --------- drivers/freetype/freetype/src/psnames/rules.mk | 71 - drivers/freetype/freetype/src/raster/Jamfile | 29 - drivers/freetype/freetype/src/raster/ftmisc.h | 142 - drivers/freetype/freetype/src/raster/ftraster.c | 3640 -------- drivers/freetype/freetype/src/raster/ftraster.h | 46 - drivers/freetype/freetype/src/raster/ftrend1.c | 306 - drivers/freetype/freetype/src/raster/ftrend1.h | 44 - drivers/freetype/freetype/src/raster/module.mk | 23 - drivers/freetype/freetype/src/raster/raster.c | 27 - drivers/freetype/freetype/src/raster/rasterrs.h | 42 - drivers/freetype/freetype/src/raster/rastpic.c | 103 - drivers/freetype/freetype/src/raster/rastpic.h | 69 - drivers/freetype/freetype/src/raster/rules.mk | 70 - drivers/freetype/freetype/src/sfnt/Jamfile | 29 - drivers/freetype/freetype/src/sfnt/module.mk | 23 - drivers/freetype/freetype/src/sfnt/pngshim.c | 336 - drivers/freetype/freetype/src/sfnt/pngshim.h | 48 - drivers/freetype/freetype/src/sfnt/rules.mk | 78 - drivers/freetype/freetype/src/sfnt/sfdriver.c | 529 -- drivers/freetype/freetype/src/sfnt/sfdriver.h | 38 - drivers/freetype/freetype/src/sfnt/sferrors.h | 40 - drivers/freetype/freetype/src/sfnt/sfnt.c | 43 - drivers/freetype/freetype/src/sfnt/sfntpic.c | 143 - drivers/freetype/freetype/src/sfnt/sfntpic.h | 114 - drivers/freetype/freetype/src/sfnt/sfobjs.c | 1163 --- drivers/freetype/freetype/src/sfnt/sfobjs.h | 54 - drivers/freetype/freetype/src/sfnt/ttbdf.c | 250 - drivers/freetype/freetype/src/sfnt/ttbdf.h | 46 - drivers/freetype/freetype/src/sfnt/ttcmap.c | 3557 -------- drivers/freetype/freetype/src/sfnt/ttcmap.h | 158 - drivers/freetype/freetype/src/sfnt/ttcmapc.h | 56 - drivers/freetype/freetype/src/sfnt/ttkern.c | 306 - drivers/freetype/freetype/src/sfnt/ttkern.h | 52 - drivers/freetype/freetype/src/sfnt/ttload.c | 1269 --- drivers/freetype/freetype/src/sfnt/ttload.h | 112 - drivers/freetype/freetype/src/sfnt/ttmtx.c | 279 - drivers/freetype/freetype/src/sfnt/ttmtx.h | 55 - drivers/freetype/freetype/src/sfnt/ttpost.c | 563 -- drivers/freetype/freetype/src/sfnt/ttpost.h | 46 - drivers/freetype/freetype/src/sfnt/ttsbit.c | 1177 --- drivers/freetype/freetype/src/sfnt/ttsbit.h | 63 - drivers/freetype/freetype/src/smooth/Jamfile | 29 - drivers/freetype/freetype/src/smooth/ftgrays.c | 2132 ----- drivers/freetype/freetype/src/smooth/ftgrays.h | 58 - drivers/freetype/freetype/src/smooth/ftsmerrs.h | 42 - drivers/freetype/freetype/src/smooth/ftsmooth.c | 534 -- drivers/freetype/freetype/src/smooth/ftsmooth.h | 49 - drivers/freetype/freetype/src/smooth/ftspic.c | 118 - drivers/freetype/freetype/src/smooth/ftspic.h | 74 - drivers/freetype/freetype/src/smooth/module.mk | 27 - drivers/freetype/freetype/src/smooth/rules.mk | 70 - drivers/freetype/freetype/src/smooth/smooth.c | 27 - drivers/freetype/freetype/src/truetype/Jamfile | 29 - drivers/freetype/freetype/src/truetype/module.mk | 23 - drivers/freetype/freetype/src/truetype/rules.mk | 74 - drivers/freetype/freetype/src/truetype/truetype.c | 38 - drivers/freetype/freetype/src/truetype/ttdriver.c | 572 -- drivers/freetype/freetype/src/truetype/ttdriver.h | 38 - drivers/freetype/freetype/src/truetype/tterrors.h | 41 - drivers/freetype/freetype/src/truetype/ttgload.c | 2328 ----- drivers/freetype/freetype/src/truetype/ttgload.h | 61 - drivers/freetype/freetype/src/truetype/ttgxvar.c | 1532 ---- drivers/freetype/freetype/src/truetype/ttgxvar.h | 182 - drivers/freetype/freetype/src/truetype/ttinterp.c | 8948 -------------------- drivers/freetype/freetype/src/truetype/ttinterp.h | 397 - drivers/freetype/freetype/src/truetype/ttobjs.c | 1331 --- drivers/freetype/freetype/src/truetype/ttobjs.h | 442 - drivers/freetype/freetype/src/truetype/ttpic.c | 101 - drivers/freetype/freetype/src/truetype/ttpic.h | 81 - drivers/freetype/freetype/src/truetype/ttpload.c | 599 -- drivers/freetype/freetype/src/truetype/ttpload.h | 75 - drivers/freetype/freetype/src/truetype/ttsubpix.c | 1011 --- drivers/freetype/freetype/src/truetype/ttsubpix.h | 110 - drivers/freetype/freetype/src/type1/Jamfile | 29 - drivers/freetype/freetype/src/type1/module.mk | 23 - drivers/freetype/freetype/src/type1/rules.mk | 73 - drivers/freetype/freetype/src/type1/t1afm.c | 396 - drivers/freetype/freetype/src/type1/t1afm.h | 54 - drivers/freetype/freetype/src/type1/t1driver.c | 726 -- drivers/freetype/freetype/src/type1/t1driver.h | 42 - drivers/freetype/freetype/src/type1/t1errors.h | 41 - drivers/freetype/freetype/src/type1/t1gload.c | 517 -- drivers/freetype/freetype/src/type1/t1gload.h | 53 - drivers/freetype/freetype/src/type1/t1load.c | 2267 ----- drivers/freetype/freetype/src/type1/t1load.h | 102 - drivers/freetype/freetype/src/type1/t1objs.c | 616 -- drivers/freetype/freetype/src/type1/t1objs.h | 160 - drivers/freetype/freetype/src/type1/t1parse.c | 497 -- drivers/freetype/freetype/src/type1/t1parse.h | 135 - drivers/freetype/freetype/src/type1/t1tokens.h | 143 - drivers/freetype/freetype/src/type1/type1.c | 33 - drivers/freetype/freetype/src/type42/Jamfile | 29 - drivers/freetype/freetype/src/type42/module.mk | 23 - drivers/freetype/freetype/src/type42/rules.mk | 70 - drivers/freetype/freetype/src/type42/t42drivr.c | 244 - drivers/freetype/freetype/src/type42/t42drivr.h | 42 - drivers/freetype/freetype/src/type42/t42error.h | 41 - drivers/freetype/freetype/src/type42/t42objs.c | 682 -- drivers/freetype/freetype/src/type42/t42objs.h | 124 - drivers/freetype/freetype/src/type42/t42parse.c | 1187 --- drivers/freetype/freetype/src/type42/t42parse.h | 90 - drivers/freetype/freetype/src/type42/t42types.h | 56 - drivers/freetype/freetype/src/type42/type42.c | 25 - drivers/freetype/freetype/src/winfonts/Jamfile | 16 - drivers/freetype/freetype/src/winfonts/fnterrs.h | 42 - drivers/freetype/freetype/src/winfonts/module.mk | 23 - drivers/freetype/freetype/src/winfonts/rules.mk | 65 - drivers/freetype/freetype/src/winfonts/winfnt.c | 1155 --- drivers/freetype/freetype/src/winfonts/winfnt.h | 171 - .../freetype/include/freetype/config/ftconfig.h | 598 ++ .../freetype/include/freetype/config/ftheader.h | 832 ++ .../freetype/include/freetype/config/ftmodule.h | 32 + .../freetype/include/freetype/config/ftoption.h | 833 ++ .../freetype/include/freetype/config/ftstdlib.h | 174 + drivers/freetype/include/freetype/freetype.h | 4012 +++++++++ drivers/freetype/include/freetype/ftadvanc.h | 182 + drivers/freetype/include/freetype/ftautoh.h | 357 + drivers/freetype/include/freetype/ftbbox.h | 102 + drivers/freetype/include/freetype/ftbdf.h | 209 + drivers/freetype/include/freetype/ftbitmap.h | 227 + drivers/freetype/include/freetype/ftbzip2.h | 102 + drivers/freetype/include/freetype/ftcache.h | 1057 +++ drivers/freetype/include/freetype/ftcffdrv.h | 151 + drivers/freetype/include/freetype/ftchapters.h | 120 + drivers/freetype/include/freetype/ftcid.h | 166 + drivers/freetype/include/freetype/fterrdef.h | 249 + drivers/freetype/include/freetype/fterrors.h | 198 + drivers/freetype/include/freetype/ftgasp.h | 128 + drivers/freetype/include/freetype/ftglyph.h | 620 ++ drivers/freetype/include/freetype/ftgxval.h | 358 + drivers/freetype/include/freetype/ftgzip.h | 102 + drivers/freetype/include/freetype/ftimage.h | 1322 +++ drivers/freetype/include/freetype/ftincrem.h | 353 + drivers/freetype/include/freetype/ftlcdfil.h | 251 + drivers/freetype/include/freetype/ftlist.h | 277 + drivers/freetype/include/freetype/ftlzw.h | 99 + drivers/freetype/include/freetype/ftmac.h | 274 + drivers/freetype/include/freetype/ftmm.h | 378 + drivers/freetype/include/freetype/ftmodapi.h | 641 ++ drivers/freetype/include/freetype/ftmoderr.h | 194 + drivers/freetype/include/freetype/ftotval.h | 203 + drivers/freetype/include/freetype/ftoutln.h | 560 ++ drivers/freetype/include/freetype/ftpfr.h | 172 + drivers/freetype/include/freetype/ftrender.h | 238 + drivers/freetype/include/freetype/ftsizes.h | 159 + drivers/freetype/include/freetype/ftsnames.h | 200 + drivers/freetype/include/freetype/ftstroke.h | 751 ++ drivers/freetype/include/freetype/ftsynth.h | 81 + drivers/freetype/include/freetype/ftsystem.h | 347 + drivers/freetype/include/freetype/fttrigon.h | 350 + drivers/freetype/include/freetype/ftttdrv.h | 150 + drivers/freetype/include/freetype/fttypes.h | 598 ++ drivers/freetype/include/freetype/ftwinfnt.h | 274 + drivers/freetype/include/freetype/ftxf86.h | 83 + .../freetype/include/freetype/internal/autohint.h | 244 + .../freetype/include/freetype/internal/ftcalc.h | 167 + .../freetype/include/freetype/internal/ftdebug.h | 255 + .../freetype/include/freetype/internal/ftdriver.h | 409 + .../freetype/include/freetype/internal/ftgloadr.h | 168 + .../freetype/include/freetype/internal/ftmemory.h | 378 + .../freetype/include/freetype/internal/ftobjs.h | 1569 ++++ drivers/freetype/include/freetype/internal/ftpic.h | 71 + .../freetype/include/freetype/internal/ftrfork.h | 258 + .../freetype/include/freetype/internal/ftserv.h | 763 ++ .../freetype/include/freetype/internal/ftstream.h | 536 ++ .../freetype/include/freetype/internal/fttrace.h | 152 + .../freetype/include/freetype/internal/ftvalid.h | 161 + .../freetype/include/freetype/internal/internal.h | 63 + drivers/freetype/include/freetype/internal/psaux.h | 877 ++ .../freetype/include/freetype/internal/pshints.h | 722 ++ .../include/freetype/internal/services/svbdf.h | 82 + .../include/freetype/internal/services/svcid.h | 89 + .../include/freetype/internal/services/svgldict.h | 88 + .../include/freetype/internal/services/svgxval.h | 72 + .../include/freetype/internal/services/svkern.h | 51 + .../include/freetype/internal/services/svmm.h | 113 + .../include/freetype/internal/services/svotval.h | 55 + .../include/freetype/internal/services/svpfr.h | 66 + .../include/freetype/internal/services/svpostnm.h | 81 + .../include/freetype/internal/services/svprop.h | 81 + .../include/freetype/internal/services/svpscmap.h | 177 + .../include/freetype/internal/services/svpsinfo.h | 111 + .../include/freetype/internal/services/svsfnt.h | 103 + .../include/freetype/internal/services/svttcmap.h | 107 + .../include/freetype/internal/services/svtteng.h | 53 + .../include/freetype/internal/services/svttglyf.h | 68 + .../include/freetype/internal/services/svwinfnt.h | 50 + .../include/freetype/internal/services/svxf86nm.h | 55 + drivers/freetype/include/freetype/internal/sfnt.h | 707 ++ .../freetype/include/freetype/internal/t1types.h | 255 + .../freetype/include/freetype/internal/tttypes.h | 1440 ++++ drivers/freetype/include/freetype/t1tables.h | 662 ++ drivers/freetype/include/freetype/ttnameid.h | 1237 +++ drivers/freetype/include/freetype/tttables.h | 777 ++ drivers/freetype/include/freetype/tttags.h | 109 + drivers/freetype/include/freetype/ttunpat.h | 59 + drivers/freetype/include/ft2build.h | 40 + drivers/freetype/src/Jamfile | 25 + drivers/freetype/src/autofit/Jamfile | 39 + drivers/freetype/src/autofit/afangles.c | 345 + drivers/freetype/src/autofit/afangles.h | 7 + drivers/freetype/src/autofit/afcjk.c | 2275 +++++ drivers/freetype/src/autofit/afcjk.h | 142 + drivers/freetype/src/autofit/afdummy.c | 62 + drivers/freetype/src/autofit/afdummy.h | 42 + drivers/freetype/src/autofit/aferrors.h | 41 + drivers/freetype/src/autofit/afglobal.c | 304 + drivers/freetype/src/autofit/afglobal.h | 109 + drivers/freetype/src/autofit/afhints.c | 1321 +++ drivers/freetype/src/autofit/afhints.h | 467 + drivers/freetype/src/autofit/afindic.c | 157 + drivers/freetype/src/autofit/afindic.h | 40 + drivers/freetype/src/autofit/aflatin.c | 2486 ++++++ drivers/freetype/src/autofit/aflatin.h | 202 + drivers/freetype/src/autofit/aflatin2.c | 2406 ++++++ drivers/freetype/src/autofit/aflatin2.h | 39 + drivers/freetype/src/autofit/afloader.c | 561 ++ drivers/freetype/src/autofit/afloader.h | 85 + drivers/freetype/src/autofit/afmodule.c | 264 + drivers/freetype/src/autofit/afmodule.h | 58 + drivers/freetype/src/autofit/afpic.c | 137 + drivers/freetype/src/autofit/afpic.h | 96 + drivers/freetype/src/autofit/aftypes.h | 378 + drivers/freetype/src/autofit/afwarp.c | 374 + drivers/freetype/src/autofit/afwarp.h | 64 + drivers/freetype/src/autofit/autofit.c | 41 + drivers/freetype/src/autofit/module.mk | 23 + drivers/freetype/src/autofit/rules.mk | 79 + drivers/freetype/src/base/Jamfile | 60 + drivers/freetype/src/base/basepic.c | 108 + drivers/freetype/src/base/basepic.h | 90 + drivers/freetype/src/base/ftadvanc.c | 162 + drivers/freetype/src/base/ftapi.c | 121 + drivers/freetype/src/base/ftbase.c | 41 + drivers/freetype/src/base/ftbase.h | 69 + drivers/freetype/src/base/ftbbox.c | 649 ++ drivers/freetype/src/base/ftbdf.c | 88 + drivers/freetype/src/base/ftbitmap.c | 758 ++ drivers/freetype/src/base/ftcalc.c | 974 +++ drivers/freetype/src/base/ftcid.c | 117 + drivers/freetype/src/base/ftdbgmem.c | 992 +++ drivers/freetype/src/base/ftdebug.c | 266 + drivers/freetype/src/base/ftfstype.c | 62 + drivers/freetype/src/base/ftgasp.c | 61 + drivers/freetype/src/base/ftgloadr.c | 405 + drivers/freetype/src/base/ftglyph.c | 629 ++ drivers/freetype/src/base/ftgxval.c | 142 + drivers/freetype/src/base/ftinit.c | 282 + drivers/freetype/src/base/ftlcdfil.c | 378 + drivers/freetype/src/base/ftmac.c | 1061 +++ drivers/freetype/src/base/ftmm.c | 204 + drivers/freetype/src/base/ftobjs.c | 4870 +++++++++++ drivers/freetype/src/base/ftotval.c | 91 + drivers/freetype/src/base/ftoutln.c | 1081 +++ drivers/freetype/src/base/ftpatent.c | 286 + drivers/freetype/src/base/ftpfr.c | 146 + drivers/freetype/src/base/ftpic.c | 55 + drivers/freetype/src/base/ftrfork.c | 849 ++ drivers/freetype/src/base/ftsnames.c | 94 + drivers/freetype/src/base/ftstream.c | 865 ++ drivers/freetype/src/base/ftstroke.c | 2418 ++++++ drivers/freetype/src/base/ftsynth.c | 153 + drivers/freetype/src/base/ftsystem.c | 320 + drivers/freetype/src/base/fttrigon.c | 492 ++ drivers/freetype/src/base/fttype1.c | 120 + drivers/freetype/src/base/ftutil.c | 436 + drivers/freetype/src/base/ftwinfnt.c | 51 + drivers/freetype/src/base/ftxf86.c | 40 + drivers/freetype/src/base/md5.c | 295 + drivers/freetype/src/base/md5.h | 45 + drivers/freetype/src/base/rules.mk | 99 + drivers/freetype/src/bdf/Jamfile | 29 + drivers/freetype/src/bdf/README | 148 + drivers/freetype/src/bdf/bdf.c | 34 + drivers/freetype/src/bdf/bdf.h | 297 + drivers/freetype/src/bdf/bdfdrivr.c | 878 ++ drivers/freetype/src/bdf/bdfdrivr.h | 80 + drivers/freetype/src/bdf/bdferror.h | 45 + drivers/freetype/src/bdf/bdflib.c | 2625 ++++++ drivers/freetype/src/bdf/module.mk | 34 + drivers/freetype/src/bdf/rules.mk | 81 + drivers/freetype/src/cache/Jamfile | 43 + drivers/freetype/src/cache/ftcache.c | 31 + drivers/freetype/src/cache/ftcbasic.c | 602 ++ drivers/freetype/src/cache/ftccache.c | 621 ++ drivers/freetype/src/cache/ftccache.h | 352 + drivers/freetype/src/cache/ftccback.h | 91 + drivers/freetype/src/cache/ftccmap.c | 337 + drivers/freetype/src/cache/ftcerror.h | 41 + drivers/freetype/src/cache/ftcglyph.c | 219 + drivers/freetype/src/cache/ftcglyph.h | 329 + drivers/freetype/src/cache/ftcimage.c | 163 + drivers/freetype/src/cache/ftcimage.h | 107 + drivers/freetype/src/cache/ftcmanag.c | 693 ++ drivers/freetype/src/cache/ftcmanag.h | 175 + drivers/freetype/src/cache/ftcmru.c | 357 + drivers/freetype/src/cache/ftcmru.h | 246 + drivers/freetype/src/cache/ftcsbits.c | 421 + drivers/freetype/src/cache/ftcsbits.h | 103 + drivers/freetype/src/cache/rules.mk | 80 + drivers/freetype/src/cff/Jamfile | 29 + drivers/freetype/src/cff/cf2arrst.c | 241 + drivers/freetype/src/cff/cf2arrst.h | 100 + drivers/freetype/src/cff/cf2blues.c | 578 ++ drivers/freetype/src/cff/cf2blues.h | 185 + drivers/freetype/src/cff/cf2error.c | 52 + drivers/freetype/src/cff/cf2error.h | 119 + drivers/freetype/src/cff/cf2fixed.h | 95 + drivers/freetype/src/cff/cf2font.c | 403 + drivers/freetype/src/cff/cf2font.h | 114 + drivers/freetype/src/cff/cf2ft.c | 639 ++ drivers/freetype/src/cff/cf2ft.h | 147 + drivers/freetype/src/cff/cf2glue.h | 144 + drivers/freetype/src/cff/cf2hints.c | 1734 ++++ drivers/freetype/src/cff/cf2hints.h | 287 + drivers/freetype/src/cff/cf2intrp.c | 1538 ++++ drivers/freetype/src/cff/cf2intrp.h | 83 + drivers/freetype/src/cff/cf2read.c | 112 + drivers/freetype/src/cff/cf2read.h | 68 + drivers/freetype/src/cff/cf2stack.c | 205 + drivers/freetype/src/cff/cf2stack.h | 106 + drivers/freetype/src/cff/cf2types.h | 78 + drivers/freetype/src/cff/cff.c | 41 + drivers/freetype/src/cff/cffcmap.c | 210 + drivers/freetype/src/cff/cffcmap.h | 67 + drivers/freetype/src/cff/cffdrivr.c | 786 ++ drivers/freetype/src/cff/cffdrivr.h | 38 + drivers/freetype/src/cff/cfferrs.h | 42 + drivers/freetype/src/cff/cffgload.c | 3068 +++++++ drivers/freetype/src/cff/cffgload.h | 240 + drivers/freetype/src/cff/cffload.c | 1696 ++++ drivers/freetype/src/cff/cffload.h | 83 + drivers/freetype/src/cff/cffobjs.c | 1077 +++ drivers/freetype/src/cff/cffobjs.h | 183 + drivers/freetype/src/cff/cffparse.c | 1177 +++ drivers/freetype/src/cff/cffparse.h | 106 + drivers/freetype/src/cff/cffpic.c | 138 + drivers/freetype/src/cff/cffpic.h | 108 + drivers/freetype/src/cff/cfftoken.h | 97 + drivers/freetype/src/cff/cfftypes.h | 284 + drivers/freetype/src/cff/module.mk | 23 + drivers/freetype/src/cff/rules.mk | 86 + drivers/freetype/src/cid/Jamfile | 29 + drivers/freetype/src/cid/ciderrs.h | 41 + drivers/freetype/src/cid/cidgload.c | 442 + drivers/freetype/src/cid/cidgload.h | 51 + drivers/freetype/src/cid/cidload.c | 690 ++ drivers/freetype/src/cid/cidload.h | 53 + drivers/freetype/src/cid/cidobjs.c | 491 ++ drivers/freetype/src/cid/cidobjs.h | 154 + drivers/freetype/src/cid/cidparse.c | 225 + drivers/freetype/src/cid/cidparse.h | 123 + drivers/freetype/src/cid/cidriver.c | 236 + drivers/freetype/src/cid/cidriver.h | 43 + drivers/freetype/src/cid/cidtoken.h | 112 + drivers/freetype/src/cid/module.mk | 23 + drivers/freetype/src/cid/rules.mk | 70 + drivers/freetype/src/cid/type1cid.c | 29 + drivers/freetype/src/gxvalid/Jamfile | 33 + drivers/freetype/src/gxvalid/README | 532 ++ drivers/freetype/src/gxvalid/gxvalid.c | 46 + drivers/freetype/src/gxvalid/gxvalid.h | 107 + drivers/freetype/src/gxvalid/gxvbsln.c | 333 + drivers/freetype/src/gxvalid/gxvcommn.c | 1744 ++++ drivers/freetype/src/gxvalid/gxvcommn.h | 582 ++ drivers/freetype/src/gxvalid/gxverror.h | 51 + drivers/freetype/src/gxvalid/gxvfeat.c | 339 + drivers/freetype/src/gxvalid/gxvfeat.h | 172 + drivers/freetype/src/gxvalid/gxvfgen.c | 482 ++ drivers/freetype/src/gxvalid/gxvjust.c | 717 ++ drivers/freetype/src/gxvalid/gxvkern.c | 920 ++ drivers/freetype/src/gxvalid/gxvlcar.c | 223 + drivers/freetype/src/gxvalid/gxvmod.c | 285 + drivers/freetype/src/gxvalid/gxvmod.h | 50 + drivers/freetype/src/gxvalid/gxvmort.c | 297 + drivers/freetype/src/gxvalid/gxvmort.h | 93 + drivers/freetype/src/gxvalid/gxvmort0.c | 151 + drivers/freetype/src/gxvalid/gxvmort1.c | 259 + drivers/freetype/src/gxvalid/gxvmort2.c | 311 + drivers/freetype/src/gxvalid/gxvmort4.c | 125 + drivers/freetype/src/gxvalid/gxvmort5.c | 233 + drivers/freetype/src/gxvalid/gxvmorx.c | 199 + drivers/freetype/src/gxvalid/gxvmorx.h | 67 + drivers/freetype/src/gxvalid/gxvmorx0.c | 111 + drivers/freetype/src/gxvalid/gxvmorx1.c | 277 + drivers/freetype/src/gxvalid/gxvmorx2.c | 327 + drivers/freetype/src/gxvalid/gxvmorx4.c | 55 + drivers/freetype/src/gxvalid/gxvmorx5.c | 225 + drivers/freetype/src/gxvalid/gxvopbd.c | 217 + drivers/freetype/src/gxvalid/gxvprop.c | 329 + drivers/freetype/src/gxvalid/gxvtrak.c | 286 + drivers/freetype/src/gxvalid/module.mk | 23 + drivers/freetype/src/gxvalid/rules.mk | 94 + drivers/freetype/src/otvalid/Jamfile | 29 + drivers/freetype/src/otvalid/module.mk | 23 + drivers/freetype/src/otvalid/otvalid.c | 31 + drivers/freetype/src/otvalid/otvalid.h | 78 + drivers/freetype/src/otvalid/otvbase.c | 318 + drivers/freetype/src/otvalid/otvcommn.c | 1086 +++ drivers/freetype/src/otvalid/otvcommn.h | 437 + drivers/freetype/src/otvalid/otverror.h | 42 + drivers/freetype/src/otvalid/otvgdef.c | 224 + drivers/freetype/src/otvalid/otvgpos.c | 1017 +++ drivers/freetype/src/otvalid/otvgpos.h | 36 + drivers/freetype/src/otvalid/otvgsub.c | 585 ++ drivers/freetype/src/otvalid/otvjstf.c | 258 + drivers/freetype/src/otvalid/otvmath.c | 453 + drivers/freetype/src/otvalid/otvmod.c | 282 + drivers/freetype/src/otvalid/otvmod.h | 43 + drivers/freetype/src/otvalid/rules.mk | 78 + drivers/freetype/src/pcf/Jamfile | 29 + drivers/freetype/src/pcf/README | 96 + drivers/freetype/src/pcf/module.mk | 34 + drivers/freetype/src/pcf/pcf.c | 36 + drivers/freetype/src/pcf/pcf.h | 237 + drivers/freetype/src/pcf/pcfdrivr.c | 713 ++ drivers/freetype/src/pcf/pcfdrivr.h | 48 + drivers/freetype/src/pcf/pcferror.h | 41 + drivers/freetype/src/pcf/pcfread.c | 1269 +++ drivers/freetype/src/pcf/pcfread.h | 45 + drivers/freetype/src/pcf/pcfutil.c | 104 + drivers/freetype/src/pcf/pcfutil.h | 55 + drivers/freetype/src/pcf/rules.mk | 79 + drivers/freetype/src/pfr/Jamfile | 29 + drivers/freetype/src/pfr/module.mk | 23 + drivers/freetype/src/pfr/pfr.c | 29 + drivers/freetype/src/pfr/pfrcmap.c | 168 + drivers/freetype/src/pfr/pfrcmap.h | 46 + drivers/freetype/src/pfr/pfrdrivr.c | 210 + drivers/freetype/src/pfr/pfrdrivr.h | 43 + drivers/freetype/src/pfr/pfrerror.h | 41 + drivers/freetype/src/pfr/pfrgload.c | 844 ++ drivers/freetype/src/pfr/pfrgload.h | 49 + drivers/freetype/src/pfr/pfrload.c | 941 ++ drivers/freetype/src/pfr/pfrload.h | 118 + drivers/freetype/src/pfr/pfrobjs.c | 593 ++ drivers/freetype/src/pfr/pfrobjs.h | 96 + drivers/freetype/src/pfr/pfrsbit.c | 698 ++ drivers/freetype/src/pfr/pfrsbit.h | 36 + drivers/freetype/src/pfr/pfrtypes.h | 362 + drivers/freetype/src/pfr/rules.mk | 73 + drivers/freetype/src/psaux/Jamfile | 31 + drivers/freetype/src/psaux/afmparse.c | 964 +++ drivers/freetype/src/psaux/afmparse.h | 88 + drivers/freetype/src/psaux/module.mk | 23 + drivers/freetype/src/psaux/psaux.c | 34 + drivers/freetype/src/psaux/psauxerr.h | 42 + drivers/freetype/src/psaux/psauxmod.c | 139 + drivers/freetype/src/psaux/psauxmod.h | 42 + drivers/freetype/src/psaux/psconv.c | 602 ++ drivers/freetype/src/psaux/psconv.h | 71 + drivers/freetype/src/psaux/psobjs.c | 1765 ++++ drivers/freetype/src/psaux/psobjs.h | 212 + drivers/freetype/src/psaux/rules.mk | 73 + drivers/freetype/src/psaux/t1cmap.c | 341 + drivers/freetype/src/psaux/t1cmap.h | 105 + drivers/freetype/src/psaux/t1decode.c | 1620 ++++ drivers/freetype/src/psaux/t1decode.h | 64 + drivers/freetype/src/pshinter/Jamfile | 29 + drivers/freetype/src/pshinter/module.mk | 23 + drivers/freetype/src/pshinter/pshalgo.c | 2305 +++++ drivers/freetype/src/pshinter/pshalgo.h | 246 + drivers/freetype/src/pshinter/pshglob.c | 797 ++ drivers/freetype/src/pshinter/pshglob.h | 196 + drivers/freetype/src/pshinter/pshinter.c | 29 + drivers/freetype/src/pshinter/pshmod.c | 119 + drivers/freetype/src/pshinter/pshmod.h | 39 + drivers/freetype/src/pshinter/pshnterr.h | 41 + drivers/freetype/src/pshinter/pshpic.c | 76 + drivers/freetype/src/pshinter/pshpic.h | 63 + drivers/freetype/src/pshinter/pshrec.c | 1225 +++ drivers/freetype/src/pshinter/pshrec.h | 176 + drivers/freetype/src/pshinter/rules.mk | 73 + drivers/freetype/src/psnames/Jamfile | 29 + drivers/freetype/src/psnames/module.mk | 23 + drivers/freetype/src/psnames/psmodule.c | 609 ++ drivers/freetype/src/psnames/psmodule.h | 38 + drivers/freetype/src/psnames/psnamerr.h | 42 + drivers/freetype/src/psnames/psnames.c | 26 + drivers/freetype/src/psnames/pspic.c | 97 + drivers/freetype/src/psnames/pspic.h | 66 + drivers/freetype/src/psnames/pstables.h | 4170 +++++++++ drivers/freetype/src/psnames/rules.mk | 71 + drivers/freetype/src/raster/Jamfile | 29 + drivers/freetype/src/raster/ftmisc.h | 142 + drivers/freetype/src/raster/ftraster.c | 3640 ++++++++ drivers/freetype/src/raster/ftraster.h | 46 + drivers/freetype/src/raster/ftrend1.c | 306 + drivers/freetype/src/raster/ftrend1.h | 44 + drivers/freetype/src/raster/module.mk | 23 + drivers/freetype/src/raster/raster.c | 27 + drivers/freetype/src/raster/rasterrs.h | 42 + drivers/freetype/src/raster/rastpic.c | 103 + drivers/freetype/src/raster/rastpic.h | 69 + drivers/freetype/src/raster/rules.mk | 70 + drivers/freetype/src/sfnt/Jamfile | 29 + drivers/freetype/src/sfnt/module.mk | 23 + drivers/freetype/src/sfnt/pngshim.c | 336 + drivers/freetype/src/sfnt/pngshim.h | 48 + drivers/freetype/src/sfnt/rules.mk | 78 + drivers/freetype/src/sfnt/sfdriver.c | 529 ++ drivers/freetype/src/sfnt/sfdriver.h | 38 + drivers/freetype/src/sfnt/sferrors.h | 40 + drivers/freetype/src/sfnt/sfnt.c | 43 + drivers/freetype/src/sfnt/sfntpic.c | 143 + drivers/freetype/src/sfnt/sfntpic.h | 114 + drivers/freetype/src/sfnt/sfobjs.c | 1163 +++ drivers/freetype/src/sfnt/sfobjs.h | 54 + drivers/freetype/src/sfnt/ttbdf.c | 250 + drivers/freetype/src/sfnt/ttbdf.h | 46 + drivers/freetype/src/sfnt/ttcmap.c | 3557 ++++++++ drivers/freetype/src/sfnt/ttcmap.h | 158 + drivers/freetype/src/sfnt/ttcmapc.h | 56 + drivers/freetype/src/sfnt/ttkern.c | 306 + drivers/freetype/src/sfnt/ttkern.h | 52 + drivers/freetype/src/sfnt/ttload.c | 1269 +++ drivers/freetype/src/sfnt/ttload.h | 112 + drivers/freetype/src/sfnt/ttmtx.c | 279 + drivers/freetype/src/sfnt/ttmtx.h | 55 + drivers/freetype/src/sfnt/ttpost.c | 563 ++ drivers/freetype/src/sfnt/ttpost.h | 46 + drivers/freetype/src/sfnt/ttsbit.c | 1177 +++ drivers/freetype/src/sfnt/ttsbit.h | 63 + drivers/freetype/src/smooth/Jamfile | 29 + drivers/freetype/src/smooth/ftgrays.c | 2132 +++++ drivers/freetype/src/smooth/ftgrays.h | 58 + drivers/freetype/src/smooth/ftsmerrs.h | 42 + drivers/freetype/src/smooth/ftsmooth.c | 534 ++ drivers/freetype/src/smooth/ftsmooth.h | 49 + drivers/freetype/src/smooth/ftspic.c | 118 + drivers/freetype/src/smooth/ftspic.h | 74 + drivers/freetype/src/smooth/module.mk | 27 + drivers/freetype/src/smooth/rules.mk | 70 + drivers/freetype/src/smooth/smooth.c | 27 + drivers/freetype/src/truetype/Jamfile | 29 + drivers/freetype/src/truetype/module.mk | 23 + drivers/freetype/src/truetype/rules.mk | 74 + drivers/freetype/src/truetype/truetype.c | 38 + drivers/freetype/src/truetype/ttdriver.c | 572 ++ drivers/freetype/src/truetype/ttdriver.h | 38 + drivers/freetype/src/truetype/tterrors.h | 41 + drivers/freetype/src/truetype/ttgload.c | 2328 +++++ drivers/freetype/src/truetype/ttgload.h | 61 + drivers/freetype/src/truetype/ttgxvar.c | 1532 ++++ drivers/freetype/src/truetype/ttgxvar.h | 182 + drivers/freetype/src/truetype/ttinterp.c | 8948 ++++++++++++++++++++ drivers/freetype/src/truetype/ttinterp.h | 397 + drivers/freetype/src/truetype/ttobjs.c | 1331 +++ drivers/freetype/src/truetype/ttobjs.h | 442 + drivers/freetype/src/truetype/ttpic.c | 101 + drivers/freetype/src/truetype/ttpic.h | 81 + drivers/freetype/src/truetype/ttpload.c | 599 ++ drivers/freetype/src/truetype/ttpload.h | 75 + drivers/freetype/src/truetype/ttsubpix.c | 1011 +++ drivers/freetype/src/truetype/ttsubpix.h | 110 + drivers/freetype/src/type1/Jamfile | 29 + drivers/freetype/src/type1/module.mk | 23 + drivers/freetype/src/type1/rules.mk | 73 + drivers/freetype/src/type1/t1afm.c | 396 + drivers/freetype/src/type1/t1afm.h | 54 + drivers/freetype/src/type1/t1driver.c | 726 ++ drivers/freetype/src/type1/t1driver.h | 42 + drivers/freetype/src/type1/t1errors.h | 41 + drivers/freetype/src/type1/t1gload.c | 517 ++ drivers/freetype/src/type1/t1gload.h | 53 + drivers/freetype/src/type1/t1load.c | 2267 +++++ drivers/freetype/src/type1/t1load.h | 102 + drivers/freetype/src/type1/t1objs.c | 616 ++ drivers/freetype/src/type1/t1objs.h | 160 + drivers/freetype/src/type1/t1parse.c | 497 ++ drivers/freetype/src/type1/t1parse.h | 135 + drivers/freetype/src/type1/t1tokens.h | 143 + drivers/freetype/src/type1/type1.c | 33 + drivers/freetype/src/type42/Jamfile | 29 + drivers/freetype/src/type42/module.mk | 23 + drivers/freetype/src/type42/rules.mk | 70 + drivers/freetype/src/type42/t42drivr.c | 244 + drivers/freetype/src/type42/t42drivr.h | 42 + drivers/freetype/src/type42/t42error.h | 41 + drivers/freetype/src/type42/t42objs.c | 682 ++ drivers/freetype/src/type42/t42objs.h | 124 + drivers/freetype/src/type42/t42parse.c | 1187 +++ drivers/freetype/src/type42/t42parse.h | 90 + drivers/freetype/src/type42/t42types.h | 56 + drivers/freetype/src/type42/type42.c | 25 + drivers/freetype/src/winfonts/Jamfile | 16 + drivers/freetype/src/winfonts/fnterrs.h | 42 + drivers/freetype/src/winfonts/module.mk | 23 + drivers/freetype/src/winfonts/rules.mk | 65 + drivers/freetype/src/winfonts/winfnt.c | 1155 +++ drivers/freetype/src/winfonts/winfnt.h | 171 + 965 files changed, 179922 insertions(+), 179923 deletions(-) delete mode 100644 drivers/freetype/freetype/include/freetype/config/ftconfig.h delete mode 100644 drivers/freetype/freetype/include/freetype/config/ftheader.h delete mode 100644 drivers/freetype/freetype/include/freetype/config/ftmodule.h delete mode 100644 drivers/freetype/freetype/include/freetype/config/ftoption.h delete mode 100644 drivers/freetype/freetype/include/freetype/config/ftstdlib.h delete mode 100644 drivers/freetype/freetype/include/freetype/freetype.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftadvanc.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftautoh.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftbbox.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftbdf.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftbitmap.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftbzip2.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftcache.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftcffdrv.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftchapters.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftcid.h delete mode 100644 drivers/freetype/freetype/include/freetype/fterrdef.h delete mode 100644 drivers/freetype/freetype/include/freetype/fterrors.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftgasp.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftglyph.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftgxval.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftgzip.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftimage.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftincrem.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftlcdfil.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftlist.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftlzw.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftmac.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftmm.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftmodapi.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftmoderr.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftotval.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftoutln.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftpfr.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftrender.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftsizes.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftsnames.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftstroke.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftsynth.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftsystem.h delete mode 100644 drivers/freetype/freetype/include/freetype/fttrigon.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftttdrv.h delete mode 100644 drivers/freetype/freetype/include/freetype/fttypes.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftwinfnt.h delete mode 100644 drivers/freetype/freetype/include/freetype/ftxf86.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/autohint.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftcalc.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftdebug.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftdriver.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftgloadr.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftmemory.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftobjs.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftpic.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftrfork.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftserv.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftstream.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/fttrace.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/ftvalid.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/internal.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/psaux.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/pshints.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svbdf.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svcid.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svgldict.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svgxval.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svkern.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svmm.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svotval.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svpfr.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svpostnm.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svprop.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svpscmap.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svpsinfo.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svsfnt.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svttcmap.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svtteng.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svttglyf.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svwinfnt.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/services/svxf86nm.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/sfnt.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/t1types.h delete mode 100644 drivers/freetype/freetype/include/freetype/internal/tttypes.h delete mode 100644 drivers/freetype/freetype/include/freetype/t1tables.h delete mode 100644 drivers/freetype/freetype/include/freetype/ttnameid.h delete mode 100644 drivers/freetype/freetype/include/freetype/tttables.h delete mode 100644 drivers/freetype/freetype/include/freetype/tttags.h delete mode 100644 drivers/freetype/freetype/include/freetype/ttunpat.h delete mode 100644 drivers/freetype/freetype/include/ft2build.h delete mode 100644 drivers/freetype/freetype/src/Jamfile delete mode 100644 drivers/freetype/freetype/src/autofit/Jamfile delete mode 100644 drivers/freetype/freetype/src/autofit/afangles.c delete mode 100644 drivers/freetype/freetype/src/autofit/afangles.h delete mode 100644 drivers/freetype/freetype/src/autofit/afcjk.c delete mode 100644 drivers/freetype/freetype/src/autofit/afcjk.h delete mode 100644 drivers/freetype/freetype/src/autofit/afdummy.c delete mode 100644 drivers/freetype/freetype/src/autofit/afdummy.h delete mode 100644 drivers/freetype/freetype/src/autofit/aferrors.h delete mode 100644 drivers/freetype/freetype/src/autofit/afglobal.c delete mode 100644 drivers/freetype/freetype/src/autofit/afglobal.h delete mode 100644 drivers/freetype/freetype/src/autofit/afhints.c delete mode 100644 drivers/freetype/freetype/src/autofit/afhints.h delete mode 100644 drivers/freetype/freetype/src/autofit/afindic.c delete mode 100644 drivers/freetype/freetype/src/autofit/afindic.h delete mode 100644 drivers/freetype/freetype/src/autofit/aflatin.c delete mode 100644 drivers/freetype/freetype/src/autofit/aflatin.h delete mode 100644 drivers/freetype/freetype/src/autofit/aflatin2.c delete mode 100644 drivers/freetype/freetype/src/autofit/aflatin2.h delete mode 100644 drivers/freetype/freetype/src/autofit/afloader.c delete mode 100644 drivers/freetype/freetype/src/autofit/afloader.h delete mode 100644 drivers/freetype/freetype/src/autofit/afmodule.c delete mode 100644 drivers/freetype/freetype/src/autofit/afmodule.h delete mode 100644 drivers/freetype/freetype/src/autofit/afpic.c delete mode 100644 drivers/freetype/freetype/src/autofit/afpic.h delete mode 100644 drivers/freetype/freetype/src/autofit/aftypes.h delete mode 100644 drivers/freetype/freetype/src/autofit/afwarp.c delete mode 100644 drivers/freetype/freetype/src/autofit/afwarp.h delete mode 100644 drivers/freetype/freetype/src/autofit/autofit.c delete mode 100644 drivers/freetype/freetype/src/autofit/module.mk delete mode 100644 drivers/freetype/freetype/src/autofit/rules.mk delete mode 100644 drivers/freetype/freetype/src/base/Jamfile delete mode 100644 drivers/freetype/freetype/src/base/basepic.c delete mode 100644 drivers/freetype/freetype/src/base/basepic.h delete mode 100644 drivers/freetype/freetype/src/base/ftadvanc.c delete mode 100644 drivers/freetype/freetype/src/base/ftapi.c delete mode 100644 drivers/freetype/freetype/src/base/ftbase.c delete mode 100644 drivers/freetype/freetype/src/base/ftbase.h delete mode 100644 drivers/freetype/freetype/src/base/ftbbox.c delete mode 100644 drivers/freetype/freetype/src/base/ftbdf.c delete mode 100644 drivers/freetype/freetype/src/base/ftbitmap.c delete mode 100644 drivers/freetype/freetype/src/base/ftcalc.c delete mode 100644 drivers/freetype/freetype/src/base/ftcid.c delete mode 100644 drivers/freetype/freetype/src/base/ftdbgmem.c delete mode 100644 drivers/freetype/freetype/src/base/ftdebug.c delete mode 100644 drivers/freetype/freetype/src/base/ftfstype.c delete mode 100644 drivers/freetype/freetype/src/base/ftgasp.c delete mode 100644 drivers/freetype/freetype/src/base/ftgloadr.c delete mode 100644 drivers/freetype/freetype/src/base/ftglyph.c delete mode 100644 drivers/freetype/freetype/src/base/ftgxval.c delete mode 100644 drivers/freetype/freetype/src/base/ftinit.c delete mode 100644 drivers/freetype/freetype/src/base/ftlcdfil.c delete mode 100644 drivers/freetype/freetype/src/base/ftmac.c delete mode 100644 drivers/freetype/freetype/src/base/ftmm.c delete mode 100644 drivers/freetype/freetype/src/base/ftobjs.c delete mode 100644 drivers/freetype/freetype/src/base/ftotval.c delete mode 100644 drivers/freetype/freetype/src/base/ftoutln.c delete mode 100644 drivers/freetype/freetype/src/base/ftpatent.c delete mode 100644 drivers/freetype/freetype/src/base/ftpfr.c delete mode 100644 drivers/freetype/freetype/src/base/ftpic.c delete mode 100644 drivers/freetype/freetype/src/base/ftrfork.c delete mode 100644 drivers/freetype/freetype/src/base/ftsnames.c delete mode 100644 drivers/freetype/freetype/src/base/ftstream.c delete mode 100644 drivers/freetype/freetype/src/base/ftstroke.c delete mode 100644 drivers/freetype/freetype/src/base/ftsynth.c delete mode 100644 drivers/freetype/freetype/src/base/ftsystem.c delete mode 100644 drivers/freetype/freetype/src/base/fttrigon.c delete mode 100644 drivers/freetype/freetype/src/base/fttype1.c delete mode 100644 drivers/freetype/freetype/src/base/ftutil.c delete mode 100644 drivers/freetype/freetype/src/base/ftwinfnt.c delete mode 100644 drivers/freetype/freetype/src/base/ftxf86.c delete mode 100644 drivers/freetype/freetype/src/base/md5.c delete mode 100644 drivers/freetype/freetype/src/base/md5.h delete mode 100644 drivers/freetype/freetype/src/base/rules.mk delete mode 100644 drivers/freetype/freetype/src/bdf/Jamfile delete mode 100644 drivers/freetype/freetype/src/bdf/README delete mode 100644 drivers/freetype/freetype/src/bdf/bdf.c delete mode 100644 drivers/freetype/freetype/src/bdf/bdf.h delete mode 100644 drivers/freetype/freetype/src/bdf/bdfdrivr.c delete mode 100644 drivers/freetype/freetype/src/bdf/bdfdrivr.h delete mode 100644 drivers/freetype/freetype/src/bdf/bdferror.h delete mode 100644 drivers/freetype/freetype/src/bdf/bdflib.c delete mode 100644 drivers/freetype/freetype/src/bdf/module.mk delete mode 100644 drivers/freetype/freetype/src/bdf/rules.mk delete mode 100644 drivers/freetype/freetype/src/cache/Jamfile delete mode 100644 drivers/freetype/freetype/src/cache/ftcache.c delete mode 100644 drivers/freetype/freetype/src/cache/ftcbasic.c delete mode 100644 drivers/freetype/freetype/src/cache/ftccache.c delete mode 100644 drivers/freetype/freetype/src/cache/ftccache.h delete mode 100644 drivers/freetype/freetype/src/cache/ftccback.h delete mode 100644 drivers/freetype/freetype/src/cache/ftccmap.c delete mode 100644 drivers/freetype/freetype/src/cache/ftcerror.h delete mode 100644 drivers/freetype/freetype/src/cache/ftcglyph.c delete mode 100644 drivers/freetype/freetype/src/cache/ftcglyph.h delete mode 100644 drivers/freetype/freetype/src/cache/ftcimage.c delete mode 100644 drivers/freetype/freetype/src/cache/ftcimage.h delete mode 100644 drivers/freetype/freetype/src/cache/ftcmanag.c delete mode 100644 drivers/freetype/freetype/src/cache/ftcmanag.h delete mode 100644 drivers/freetype/freetype/src/cache/ftcmru.c delete mode 100644 drivers/freetype/freetype/src/cache/ftcmru.h delete mode 100644 drivers/freetype/freetype/src/cache/ftcsbits.c delete mode 100644 drivers/freetype/freetype/src/cache/ftcsbits.h delete mode 100644 drivers/freetype/freetype/src/cache/rules.mk delete mode 100644 drivers/freetype/freetype/src/cff/Jamfile delete mode 100644 drivers/freetype/freetype/src/cff/cf2arrst.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2arrst.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2blues.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2blues.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2error.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2error.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2fixed.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2font.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2font.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2ft.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2ft.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2glue.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2hints.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2hints.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2intrp.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2intrp.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2read.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2read.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2stack.c delete mode 100644 drivers/freetype/freetype/src/cff/cf2stack.h delete mode 100644 drivers/freetype/freetype/src/cff/cf2types.h delete mode 100644 drivers/freetype/freetype/src/cff/cff.c delete mode 100644 drivers/freetype/freetype/src/cff/cffcmap.c delete mode 100644 drivers/freetype/freetype/src/cff/cffcmap.h delete mode 100644 drivers/freetype/freetype/src/cff/cffdrivr.c delete mode 100644 drivers/freetype/freetype/src/cff/cffdrivr.h delete mode 100644 drivers/freetype/freetype/src/cff/cfferrs.h delete mode 100644 drivers/freetype/freetype/src/cff/cffgload.c delete mode 100644 drivers/freetype/freetype/src/cff/cffgload.h delete mode 100644 drivers/freetype/freetype/src/cff/cffload.c delete mode 100644 drivers/freetype/freetype/src/cff/cffload.h delete mode 100644 drivers/freetype/freetype/src/cff/cffobjs.c delete mode 100644 drivers/freetype/freetype/src/cff/cffobjs.h delete mode 100644 drivers/freetype/freetype/src/cff/cffparse.c delete mode 100644 drivers/freetype/freetype/src/cff/cffparse.h delete mode 100644 drivers/freetype/freetype/src/cff/cffpic.c delete mode 100644 drivers/freetype/freetype/src/cff/cffpic.h delete mode 100644 drivers/freetype/freetype/src/cff/cfftoken.h delete mode 100644 drivers/freetype/freetype/src/cff/cfftypes.h delete mode 100644 drivers/freetype/freetype/src/cff/module.mk delete mode 100644 drivers/freetype/freetype/src/cff/rules.mk delete mode 100644 drivers/freetype/freetype/src/cid/Jamfile delete mode 100644 drivers/freetype/freetype/src/cid/ciderrs.h delete mode 100644 drivers/freetype/freetype/src/cid/cidgload.c delete mode 100644 drivers/freetype/freetype/src/cid/cidgload.h delete mode 100644 drivers/freetype/freetype/src/cid/cidload.c delete mode 100644 drivers/freetype/freetype/src/cid/cidload.h delete mode 100644 drivers/freetype/freetype/src/cid/cidobjs.c delete mode 100644 drivers/freetype/freetype/src/cid/cidobjs.h delete mode 100644 drivers/freetype/freetype/src/cid/cidparse.c delete mode 100644 drivers/freetype/freetype/src/cid/cidparse.h delete mode 100644 drivers/freetype/freetype/src/cid/cidriver.c delete mode 100644 drivers/freetype/freetype/src/cid/cidriver.h delete mode 100644 drivers/freetype/freetype/src/cid/cidtoken.h delete mode 100644 drivers/freetype/freetype/src/cid/module.mk delete mode 100644 drivers/freetype/freetype/src/cid/rules.mk delete mode 100644 drivers/freetype/freetype/src/cid/type1cid.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/Jamfile delete mode 100644 drivers/freetype/freetype/src/gxvalid/README delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvalid.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvalid.h delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvbsln.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvcommn.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvcommn.h delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxverror.h delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvfeat.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvfeat.h delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvfgen.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvjust.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvkern.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvlcar.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmod.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmod.h delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmort.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmort.h delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmort0.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmort1.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmort2.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmort4.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmort5.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmorx.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmorx.h delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmorx0.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmorx1.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmorx2.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmorx4.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvmorx5.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvopbd.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvprop.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/gxvtrak.c delete mode 100644 drivers/freetype/freetype/src/gxvalid/module.mk delete mode 100644 drivers/freetype/freetype/src/gxvalid/rules.mk delete mode 100644 drivers/freetype/freetype/src/otvalid/Jamfile delete mode 100644 drivers/freetype/freetype/src/otvalid/module.mk delete mode 100644 drivers/freetype/freetype/src/otvalid/otvalid.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvalid.h delete mode 100644 drivers/freetype/freetype/src/otvalid/otvbase.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvcommn.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvcommn.h delete mode 100644 drivers/freetype/freetype/src/otvalid/otverror.h delete mode 100644 drivers/freetype/freetype/src/otvalid/otvgdef.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvgpos.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvgpos.h delete mode 100644 drivers/freetype/freetype/src/otvalid/otvgsub.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvjstf.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvmath.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvmod.c delete mode 100644 drivers/freetype/freetype/src/otvalid/otvmod.h delete mode 100644 drivers/freetype/freetype/src/otvalid/rules.mk delete mode 100644 drivers/freetype/freetype/src/pcf/Jamfile delete mode 100644 drivers/freetype/freetype/src/pcf/README delete mode 100644 drivers/freetype/freetype/src/pcf/module.mk delete mode 100644 drivers/freetype/freetype/src/pcf/pcf.c delete mode 100644 drivers/freetype/freetype/src/pcf/pcf.h delete mode 100644 drivers/freetype/freetype/src/pcf/pcfdrivr.c delete mode 100644 drivers/freetype/freetype/src/pcf/pcfdrivr.h delete mode 100644 drivers/freetype/freetype/src/pcf/pcferror.h delete mode 100644 drivers/freetype/freetype/src/pcf/pcfread.c delete mode 100644 drivers/freetype/freetype/src/pcf/pcfread.h delete mode 100644 drivers/freetype/freetype/src/pcf/pcfutil.c delete mode 100644 drivers/freetype/freetype/src/pcf/pcfutil.h delete mode 100644 drivers/freetype/freetype/src/pcf/rules.mk delete mode 100644 drivers/freetype/freetype/src/pfr/Jamfile delete mode 100644 drivers/freetype/freetype/src/pfr/module.mk delete mode 100644 drivers/freetype/freetype/src/pfr/pfr.c delete mode 100644 drivers/freetype/freetype/src/pfr/pfrcmap.c delete mode 100644 drivers/freetype/freetype/src/pfr/pfrcmap.h delete mode 100644 drivers/freetype/freetype/src/pfr/pfrdrivr.c delete mode 100644 drivers/freetype/freetype/src/pfr/pfrdrivr.h delete mode 100644 drivers/freetype/freetype/src/pfr/pfrerror.h delete mode 100644 drivers/freetype/freetype/src/pfr/pfrgload.c delete mode 100644 drivers/freetype/freetype/src/pfr/pfrgload.h delete mode 100644 drivers/freetype/freetype/src/pfr/pfrload.c delete mode 100644 drivers/freetype/freetype/src/pfr/pfrload.h delete mode 100644 drivers/freetype/freetype/src/pfr/pfrobjs.c delete mode 100644 drivers/freetype/freetype/src/pfr/pfrobjs.h delete mode 100644 drivers/freetype/freetype/src/pfr/pfrsbit.c delete mode 100644 drivers/freetype/freetype/src/pfr/pfrsbit.h delete mode 100644 drivers/freetype/freetype/src/pfr/pfrtypes.h delete mode 100644 drivers/freetype/freetype/src/pfr/rules.mk delete mode 100644 drivers/freetype/freetype/src/psaux/Jamfile delete mode 100644 drivers/freetype/freetype/src/psaux/afmparse.c delete mode 100644 drivers/freetype/freetype/src/psaux/afmparse.h delete mode 100644 drivers/freetype/freetype/src/psaux/module.mk delete mode 100644 drivers/freetype/freetype/src/psaux/psaux.c delete mode 100644 drivers/freetype/freetype/src/psaux/psauxerr.h delete mode 100644 drivers/freetype/freetype/src/psaux/psauxmod.c delete mode 100644 drivers/freetype/freetype/src/psaux/psauxmod.h delete mode 100644 drivers/freetype/freetype/src/psaux/psconv.c delete mode 100644 drivers/freetype/freetype/src/psaux/psconv.h delete mode 100644 drivers/freetype/freetype/src/psaux/psobjs.c delete mode 100644 drivers/freetype/freetype/src/psaux/psobjs.h delete mode 100644 drivers/freetype/freetype/src/psaux/rules.mk delete mode 100644 drivers/freetype/freetype/src/psaux/t1cmap.c delete mode 100644 drivers/freetype/freetype/src/psaux/t1cmap.h delete mode 100644 drivers/freetype/freetype/src/psaux/t1decode.c delete mode 100644 drivers/freetype/freetype/src/psaux/t1decode.h delete mode 100644 drivers/freetype/freetype/src/pshinter/Jamfile delete mode 100644 drivers/freetype/freetype/src/pshinter/module.mk delete mode 100644 drivers/freetype/freetype/src/pshinter/pshalgo.c delete mode 100644 drivers/freetype/freetype/src/pshinter/pshalgo.h delete mode 100644 drivers/freetype/freetype/src/pshinter/pshglob.c delete mode 100644 drivers/freetype/freetype/src/pshinter/pshglob.h delete mode 100644 drivers/freetype/freetype/src/pshinter/pshinter.c delete mode 100644 drivers/freetype/freetype/src/pshinter/pshmod.c delete mode 100644 drivers/freetype/freetype/src/pshinter/pshmod.h delete mode 100644 drivers/freetype/freetype/src/pshinter/pshnterr.h delete mode 100644 drivers/freetype/freetype/src/pshinter/pshpic.c delete mode 100644 drivers/freetype/freetype/src/pshinter/pshpic.h delete mode 100644 drivers/freetype/freetype/src/pshinter/pshrec.c delete mode 100644 drivers/freetype/freetype/src/pshinter/pshrec.h delete mode 100644 drivers/freetype/freetype/src/pshinter/rules.mk delete mode 100644 drivers/freetype/freetype/src/psnames/Jamfile delete mode 100644 drivers/freetype/freetype/src/psnames/module.mk delete mode 100644 drivers/freetype/freetype/src/psnames/psmodule.c delete mode 100644 drivers/freetype/freetype/src/psnames/psmodule.h delete mode 100644 drivers/freetype/freetype/src/psnames/psnamerr.h delete mode 100644 drivers/freetype/freetype/src/psnames/psnames.c delete mode 100644 drivers/freetype/freetype/src/psnames/pspic.c delete mode 100644 drivers/freetype/freetype/src/psnames/pspic.h delete mode 100644 drivers/freetype/freetype/src/psnames/pstables.h delete mode 100644 drivers/freetype/freetype/src/psnames/rules.mk delete mode 100644 drivers/freetype/freetype/src/raster/Jamfile delete mode 100644 drivers/freetype/freetype/src/raster/ftmisc.h delete mode 100644 drivers/freetype/freetype/src/raster/ftraster.c delete mode 100644 drivers/freetype/freetype/src/raster/ftraster.h delete mode 100644 drivers/freetype/freetype/src/raster/ftrend1.c delete mode 100644 drivers/freetype/freetype/src/raster/ftrend1.h delete mode 100644 drivers/freetype/freetype/src/raster/module.mk delete mode 100644 drivers/freetype/freetype/src/raster/raster.c delete mode 100644 drivers/freetype/freetype/src/raster/rasterrs.h delete mode 100644 drivers/freetype/freetype/src/raster/rastpic.c delete mode 100644 drivers/freetype/freetype/src/raster/rastpic.h delete mode 100644 drivers/freetype/freetype/src/raster/rules.mk delete mode 100644 drivers/freetype/freetype/src/sfnt/Jamfile delete mode 100644 drivers/freetype/freetype/src/sfnt/module.mk delete mode 100644 drivers/freetype/freetype/src/sfnt/pngshim.c delete mode 100644 drivers/freetype/freetype/src/sfnt/pngshim.h delete mode 100644 drivers/freetype/freetype/src/sfnt/rules.mk delete mode 100644 drivers/freetype/freetype/src/sfnt/sfdriver.c delete mode 100644 drivers/freetype/freetype/src/sfnt/sfdriver.h delete mode 100644 drivers/freetype/freetype/src/sfnt/sferrors.h delete mode 100644 drivers/freetype/freetype/src/sfnt/sfnt.c delete mode 100644 drivers/freetype/freetype/src/sfnt/sfntpic.c delete mode 100644 drivers/freetype/freetype/src/sfnt/sfntpic.h delete mode 100644 drivers/freetype/freetype/src/sfnt/sfobjs.c delete mode 100644 drivers/freetype/freetype/src/sfnt/sfobjs.h delete mode 100644 drivers/freetype/freetype/src/sfnt/ttbdf.c delete mode 100644 drivers/freetype/freetype/src/sfnt/ttbdf.h delete mode 100644 drivers/freetype/freetype/src/sfnt/ttcmap.c delete mode 100644 drivers/freetype/freetype/src/sfnt/ttcmap.h delete mode 100644 drivers/freetype/freetype/src/sfnt/ttcmapc.h delete mode 100644 drivers/freetype/freetype/src/sfnt/ttkern.c delete mode 100644 drivers/freetype/freetype/src/sfnt/ttkern.h delete mode 100644 drivers/freetype/freetype/src/sfnt/ttload.c delete mode 100644 drivers/freetype/freetype/src/sfnt/ttload.h delete mode 100644 drivers/freetype/freetype/src/sfnt/ttmtx.c delete mode 100644 drivers/freetype/freetype/src/sfnt/ttmtx.h delete mode 100644 drivers/freetype/freetype/src/sfnt/ttpost.c delete mode 100644 drivers/freetype/freetype/src/sfnt/ttpost.h delete mode 100644 drivers/freetype/freetype/src/sfnt/ttsbit.c delete mode 100644 drivers/freetype/freetype/src/sfnt/ttsbit.h delete mode 100644 drivers/freetype/freetype/src/smooth/Jamfile delete mode 100644 drivers/freetype/freetype/src/smooth/ftgrays.c delete mode 100644 drivers/freetype/freetype/src/smooth/ftgrays.h delete mode 100644 drivers/freetype/freetype/src/smooth/ftsmerrs.h delete mode 100644 drivers/freetype/freetype/src/smooth/ftsmooth.c delete mode 100644 drivers/freetype/freetype/src/smooth/ftsmooth.h delete mode 100644 drivers/freetype/freetype/src/smooth/ftspic.c delete mode 100644 drivers/freetype/freetype/src/smooth/ftspic.h delete mode 100644 drivers/freetype/freetype/src/smooth/module.mk delete mode 100644 drivers/freetype/freetype/src/smooth/rules.mk delete mode 100644 drivers/freetype/freetype/src/smooth/smooth.c delete mode 100644 drivers/freetype/freetype/src/truetype/Jamfile delete mode 100644 drivers/freetype/freetype/src/truetype/module.mk delete mode 100644 drivers/freetype/freetype/src/truetype/rules.mk delete mode 100644 drivers/freetype/freetype/src/truetype/truetype.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttdriver.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttdriver.h delete mode 100644 drivers/freetype/freetype/src/truetype/tterrors.h delete mode 100644 drivers/freetype/freetype/src/truetype/ttgload.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttgload.h delete mode 100644 drivers/freetype/freetype/src/truetype/ttgxvar.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttgxvar.h delete mode 100644 drivers/freetype/freetype/src/truetype/ttinterp.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttinterp.h delete mode 100644 drivers/freetype/freetype/src/truetype/ttobjs.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttobjs.h delete mode 100644 drivers/freetype/freetype/src/truetype/ttpic.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttpic.h delete mode 100644 drivers/freetype/freetype/src/truetype/ttpload.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttpload.h delete mode 100644 drivers/freetype/freetype/src/truetype/ttsubpix.c delete mode 100644 drivers/freetype/freetype/src/truetype/ttsubpix.h delete mode 100644 drivers/freetype/freetype/src/type1/Jamfile delete mode 100644 drivers/freetype/freetype/src/type1/module.mk delete mode 100644 drivers/freetype/freetype/src/type1/rules.mk delete mode 100644 drivers/freetype/freetype/src/type1/t1afm.c delete mode 100644 drivers/freetype/freetype/src/type1/t1afm.h delete mode 100644 drivers/freetype/freetype/src/type1/t1driver.c delete mode 100644 drivers/freetype/freetype/src/type1/t1driver.h delete mode 100644 drivers/freetype/freetype/src/type1/t1errors.h delete mode 100644 drivers/freetype/freetype/src/type1/t1gload.c delete mode 100644 drivers/freetype/freetype/src/type1/t1gload.h delete mode 100644 drivers/freetype/freetype/src/type1/t1load.c delete mode 100644 drivers/freetype/freetype/src/type1/t1load.h delete mode 100644 drivers/freetype/freetype/src/type1/t1objs.c delete mode 100644 drivers/freetype/freetype/src/type1/t1objs.h delete mode 100644 drivers/freetype/freetype/src/type1/t1parse.c delete mode 100644 drivers/freetype/freetype/src/type1/t1parse.h delete mode 100644 drivers/freetype/freetype/src/type1/t1tokens.h delete mode 100644 drivers/freetype/freetype/src/type1/type1.c delete mode 100644 drivers/freetype/freetype/src/type42/Jamfile delete mode 100644 drivers/freetype/freetype/src/type42/module.mk delete mode 100644 drivers/freetype/freetype/src/type42/rules.mk delete mode 100644 drivers/freetype/freetype/src/type42/t42drivr.c delete mode 100644 drivers/freetype/freetype/src/type42/t42drivr.h delete mode 100644 drivers/freetype/freetype/src/type42/t42error.h delete mode 100644 drivers/freetype/freetype/src/type42/t42objs.c delete mode 100644 drivers/freetype/freetype/src/type42/t42objs.h delete mode 100644 drivers/freetype/freetype/src/type42/t42parse.c delete mode 100644 drivers/freetype/freetype/src/type42/t42parse.h delete mode 100644 drivers/freetype/freetype/src/type42/t42types.h delete mode 100644 drivers/freetype/freetype/src/type42/type42.c delete mode 100644 drivers/freetype/freetype/src/winfonts/Jamfile delete mode 100644 drivers/freetype/freetype/src/winfonts/fnterrs.h delete mode 100644 drivers/freetype/freetype/src/winfonts/module.mk delete mode 100644 drivers/freetype/freetype/src/winfonts/rules.mk delete mode 100644 drivers/freetype/freetype/src/winfonts/winfnt.c delete mode 100644 drivers/freetype/freetype/src/winfonts/winfnt.h create mode 100644 drivers/freetype/include/freetype/config/ftconfig.h create mode 100644 drivers/freetype/include/freetype/config/ftheader.h create mode 100644 drivers/freetype/include/freetype/config/ftmodule.h create mode 100644 drivers/freetype/include/freetype/config/ftoption.h create mode 100644 drivers/freetype/include/freetype/config/ftstdlib.h create mode 100644 drivers/freetype/include/freetype/freetype.h create mode 100644 drivers/freetype/include/freetype/ftadvanc.h create mode 100644 drivers/freetype/include/freetype/ftautoh.h create mode 100644 drivers/freetype/include/freetype/ftbbox.h create mode 100644 drivers/freetype/include/freetype/ftbdf.h create mode 100644 drivers/freetype/include/freetype/ftbitmap.h create mode 100644 drivers/freetype/include/freetype/ftbzip2.h create mode 100644 drivers/freetype/include/freetype/ftcache.h create mode 100644 drivers/freetype/include/freetype/ftcffdrv.h create mode 100644 drivers/freetype/include/freetype/ftchapters.h create mode 100644 drivers/freetype/include/freetype/ftcid.h create mode 100644 drivers/freetype/include/freetype/fterrdef.h create mode 100644 drivers/freetype/include/freetype/fterrors.h create mode 100644 drivers/freetype/include/freetype/ftgasp.h create mode 100644 drivers/freetype/include/freetype/ftglyph.h create mode 100644 drivers/freetype/include/freetype/ftgxval.h create mode 100644 drivers/freetype/include/freetype/ftgzip.h create mode 100644 drivers/freetype/include/freetype/ftimage.h create mode 100644 drivers/freetype/include/freetype/ftincrem.h create mode 100644 drivers/freetype/include/freetype/ftlcdfil.h create mode 100644 drivers/freetype/include/freetype/ftlist.h create mode 100644 drivers/freetype/include/freetype/ftlzw.h create mode 100644 drivers/freetype/include/freetype/ftmac.h create mode 100644 drivers/freetype/include/freetype/ftmm.h create mode 100644 drivers/freetype/include/freetype/ftmodapi.h create mode 100644 drivers/freetype/include/freetype/ftmoderr.h create mode 100644 drivers/freetype/include/freetype/ftotval.h create mode 100644 drivers/freetype/include/freetype/ftoutln.h create mode 100644 drivers/freetype/include/freetype/ftpfr.h create mode 100644 drivers/freetype/include/freetype/ftrender.h create mode 100644 drivers/freetype/include/freetype/ftsizes.h create mode 100644 drivers/freetype/include/freetype/ftsnames.h create mode 100644 drivers/freetype/include/freetype/ftstroke.h create mode 100644 drivers/freetype/include/freetype/ftsynth.h create mode 100644 drivers/freetype/include/freetype/ftsystem.h create mode 100644 drivers/freetype/include/freetype/fttrigon.h create mode 100644 drivers/freetype/include/freetype/ftttdrv.h create mode 100644 drivers/freetype/include/freetype/fttypes.h create mode 100644 drivers/freetype/include/freetype/ftwinfnt.h create mode 100644 drivers/freetype/include/freetype/ftxf86.h create mode 100644 drivers/freetype/include/freetype/internal/autohint.h create mode 100644 drivers/freetype/include/freetype/internal/ftcalc.h create mode 100644 drivers/freetype/include/freetype/internal/ftdebug.h create mode 100644 drivers/freetype/include/freetype/internal/ftdriver.h create mode 100644 drivers/freetype/include/freetype/internal/ftgloadr.h create mode 100644 drivers/freetype/include/freetype/internal/ftmemory.h create mode 100644 drivers/freetype/include/freetype/internal/ftobjs.h create mode 100644 drivers/freetype/include/freetype/internal/ftpic.h create mode 100644 drivers/freetype/include/freetype/internal/ftrfork.h create mode 100644 drivers/freetype/include/freetype/internal/ftserv.h create mode 100644 drivers/freetype/include/freetype/internal/ftstream.h create mode 100644 drivers/freetype/include/freetype/internal/fttrace.h create mode 100644 drivers/freetype/include/freetype/internal/ftvalid.h create mode 100644 drivers/freetype/include/freetype/internal/internal.h create mode 100644 drivers/freetype/include/freetype/internal/psaux.h create mode 100644 drivers/freetype/include/freetype/internal/pshints.h create mode 100644 drivers/freetype/include/freetype/internal/services/svbdf.h create mode 100644 drivers/freetype/include/freetype/internal/services/svcid.h create mode 100644 drivers/freetype/include/freetype/internal/services/svgldict.h create mode 100644 drivers/freetype/include/freetype/internal/services/svgxval.h create mode 100644 drivers/freetype/include/freetype/internal/services/svkern.h create mode 100644 drivers/freetype/include/freetype/internal/services/svmm.h create mode 100644 drivers/freetype/include/freetype/internal/services/svotval.h create mode 100644 drivers/freetype/include/freetype/internal/services/svpfr.h create mode 100644 drivers/freetype/include/freetype/internal/services/svpostnm.h create mode 100644 drivers/freetype/include/freetype/internal/services/svprop.h create mode 100644 drivers/freetype/include/freetype/internal/services/svpscmap.h create mode 100644 drivers/freetype/include/freetype/internal/services/svpsinfo.h create mode 100644 drivers/freetype/include/freetype/internal/services/svsfnt.h create mode 100644 drivers/freetype/include/freetype/internal/services/svttcmap.h create mode 100644 drivers/freetype/include/freetype/internal/services/svtteng.h create mode 100644 drivers/freetype/include/freetype/internal/services/svttglyf.h create mode 100644 drivers/freetype/include/freetype/internal/services/svwinfnt.h create mode 100644 drivers/freetype/include/freetype/internal/services/svxf86nm.h create mode 100644 drivers/freetype/include/freetype/internal/sfnt.h create mode 100644 drivers/freetype/include/freetype/internal/t1types.h create mode 100644 drivers/freetype/include/freetype/internal/tttypes.h create mode 100644 drivers/freetype/include/freetype/t1tables.h create mode 100644 drivers/freetype/include/freetype/ttnameid.h create mode 100644 drivers/freetype/include/freetype/tttables.h create mode 100644 drivers/freetype/include/freetype/tttags.h create mode 100644 drivers/freetype/include/freetype/ttunpat.h create mode 100644 drivers/freetype/include/ft2build.h create mode 100644 drivers/freetype/src/Jamfile create mode 100644 drivers/freetype/src/autofit/Jamfile create mode 100644 drivers/freetype/src/autofit/afangles.c create mode 100644 drivers/freetype/src/autofit/afangles.h create mode 100644 drivers/freetype/src/autofit/afcjk.c create mode 100644 drivers/freetype/src/autofit/afcjk.h create mode 100644 drivers/freetype/src/autofit/afdummy.c create mode 100644 drivers/freetype/src/autofit/afdummy.h create mode 100644 drivers/freetype/src/autofit/aferrors.h create mode 100644 drivers/freetype/src/autofit/afglobal.c create mode 100644 drivers/freetype/src/autofit/afglobal.h create mode 100644 drivers/freetype/src/autofit/afhints.c create mode 100644 drivers/freetype/src/autofit/afhints.h create mode 100644 drivers/freetype/src/autofit/afindic.c create mode 100644 drivers/freetype/src/autofit/afindic.h create mode 100644 drivers/freetype/src/autofit/aflatin.c create mode 100644 drivers/freetype/src/autofit/aflatin.h create mode 100644 drivers/freetype/src/autofit/aflatin2.c create mode 100644 drivers/freetype/src/autofit/aflatin2.h create mode 100644 drivers/freetype/src/autofit/afloader.c create mode 100644 drivers/freetype/src/autofit/afloader.h create mode 100644 drivers/freetype/src/autofit/afmodule.c create mode 100644 drivers/freetype/src/autofit/afmodule.h create mode 100644 drivers/freetype/src/autofit/afpic.c create mode 100644 drivers/freetype/src/autofit/afpic.h create mode 100644 drivers/freetype/src/autofit/aftypes.h create mode 100644 drivers/freetype/src/autofit/afwarp.c create mode 100644 drivers/freetype/src/autofit/afwarp.h create mode 100644 drivers/freetype/src/autofit/autofit.c create mode 100644 drivers/freetype/src/autofit/module.mk create mode 100644 drivers/freetype/src/autofit/rules.mk create mode 100644 drivers/freetype/src/base/Jamfile create mode 100644 drivers/freetype/src/base/basepic.c create mode 100644 drivers/freetype/src/base/basepic.h create mode 100644 drivers/freetype/src/base/ftadvanc.c create mode 100644 drivers/freetype/src/base/ftapi.c create mode 100644 drivers/freetype/src/base/ftbase.c create mode 100644 drivers/freetype/src/base/ftbase.h create mode 100644 drivers/freetype/src/base/ftbbox.c create mode 100644 drivers/freetype/src/base/ftbdf.c create mode 100644 drivers/freetype/src/base/ftbitmap.c create mode 100644 drivers/freetype/src/base/ftcalc.c create mode 100644 drivers/freetype/src/base/ftcid.c create mode 100644 drivers/freetype/src/base/ftdbgmem.c create mode 100644 drivers/freetype/src/base/ftdebug.c create mode 100644 drivers/freetype/src/base/ftfstype.c create mode 100644 drivers/freetype/src/base/ftgasp.c create mode 100644 drivers/freetype/src/base/ftgloadr.c create mode 100644 drivers/freetype/src/base/ftglyph.c create mode 100644 drivers/freetype/src/base/ftgxval.c create mode 100644 drivers/freetype/src/base/ftinit.c create mode 100644 drivers/freetype/src/base/ftlcdfil.c create mode 100644 drivers/freetype/src/base/ftmac.c create mode 100644 drivers/freetype/src/base/ftmm.c create mode 100644 drivers/freetype/src/base/ftobjs.c create mode 100644 drivers/freetype/src/base/ftotval.c create mode 100644 drivers/freetype/src/base/ftoutln.c create mode 100644 drivers/freetype/src/base/ftpatent.c create mode 100644 drivers/freetype/src/base/ftpfr.c create mode 100644 drivers/freetype/src/base/ftpic.c create mode 100644 drivers/freetype/src/base/ftrfork.c create mode 100644 drivers/freetype/src/base/ftsnames.c create mode 100644 drivers/freetype/src/base/ftstream.c create mode 100644 drivers/freetype/src/base/ftstroke.c create mode 100644 drivers/freetype/src/base/ftsynth.c create mode 100644 drivers/freetype/src/base/ftsystem.c create mode 100644 drivers/freetype/src/base/fttrigon.c create mode 100644 drivers/freetype/src/base/fttype1.c create mode 100644 drivers/freetype/src/base/ftutil.c create mode 100644 drivers/freetype/src/base/ftwinfnt.c create mode 100644 drivers/freetype/src/base/ftxf86.c create mode 100644 drivers/freetype/src/base/md5.c create mode 100644 drivers/freetype/src/base/md5.h create mode 100644 drivers/freetype/src/base/rules.mk create mode 100644 drivers/freetype/src/bdf/Jamfile create mode 100644 drivers/freetype/src/bdf/README create mode 100644 drivers/freetype/src/bdf/bdf.c create mode 100644 drivers/freetype/src/bdf/bdf.h create mode 100644 drivers/freetype/src/bdf/bdfdrivr.c create mode 100644 drivers/freetype/src/bdf/bdfdrivr.h create mode 100644 drivers/freetype/src/bdf/bdferror.h create mode 100644 drivers/freetype/src/bdf/bdflib.c create mode 100644 drivers/freetype/src/bdf/module.mk create mode 100644 drivers/freetype/src/bdf/rules.mk create mode 100644 drivers/freetype/src/cache/Jamfile create mode 100644 drivers/freetype/src/cache/ftcache.c create mode 100644 drivers/freetype/src/cache/ftcbasic.c create mode 100644 drivers/freetype/src/cache/ftccache.c create mode 100644 drivers/freetype/src/cache/ftccache.h create mode 100644 drivers/freetype/src/cache/ftccback.h create mode 100644 drivers/freetype/src/cache/ftccmap.c create mode 100644 drivers/freetype/src/cache/ftcerror.h create mode 100644 drivers/freetype/src/cache/ftcglyph.c create mode 100644 drivers/freetype/src/cache/ftcglyph.h create mode 100644 drivers/freetype/src/cache/ftcimage.c create mode 100644 drivers/freetype/src/cache/ftcimage.h create mode 100644 drivers/freetype/src/cache/ftcmanag.c create mode 100644 drivers/freetype/src/cache/ftcmanag.h create mode 100644 drivers/freetype/src/cache/ftcmru.c create mode 100644 drivers/freetype/src/cache/ftcmru.h create mode 100644 drivers/freetype/src/cache/ftcsbits.c create mode 100644 drivers/freetype/src/cache/ftcsbits.h create mode 100644 drivers/freetype/src/cache/rules.mk create mode 100644 drivers/freetype/src/cff/Jamfile create mode 100644 drivers/freetype/src/cff/cf2arrst.c create mode 100644 drivers/freetype/src/cff/cf2arrst.h create mode 100644 drivers/freetype/src/cff/cf2blues.c create mode 100644 drivers/freetype/src/cff/cf2blues.h create mode 100644 drivers/freetype/src/cff/cf2error.c create mode 100644 drivers/freetype/src/cff/cf2error.h create mode 100644 drivers/freetype/src/cff/cf2fixed.h create mode 100644 drivers/freetype/src/cff/cf2font.c create mode 100644 drivers/freetype/src/cff/cf2font.h create mode 100644 drivers/freetype/src/cff/cf2ft.c create mode 100644 drivers/freetype/src/cff/cf2ft.h create mode 100644 drivers/freetype/src/cff/cf2glue.h create mode 100644 drivers/freetype/src/cff/cf2hints.c create mode 100644 drivers/freetype/src/cff/cf2hints.h create mode 100644 drivers/freetype/src/cff/cf2intrp.c create mode 100644 drivers/freetype/src/cff/cf2intrp.h create mode 100644 drivers/freetype/src/cff/cf2read.c create mode 100644 drivers/freetype/src/cff/cf2read.h create mode 100644 drivers/freetype/src/cff/cf2stack.c create mode 100644 drivers/freetype/src/cff/cf2stack.h create mode 100644 drivers/freetype/src/cff/cf2types.h create mode 100644 drivers/freetype/src/cff/cff.c create mode 100644 drivers/freetype/src/cff/cffcmap.c create mode 100644 drivers/freetype/src/cff/cffcmap.h create mode 100644 drivers/freetype/src/cff/cffdrivr.c create mode 100644 drivers/freetype/src/cff/cffdrivr.h create mode 100644 drivers/freetype/src/cff/cfferrs.h create mode 100644 drivers/freetype/src/cff/cffgload.c create mode 100644 drivers/freetype/src/cff/cffgload.h create mode 100644 drivers/freetype/src/cff/cffload.c create mode 100644 drivers/freetype/src/cff/cffload.h create mode 100644 drivers/freetype/src/cff/cffobjs.c create mode 100644 drivers/freetype/src/cff/cffobjs.h create mode 100644 drivers/freetype/src/cff/cffparse.c create mode 100644 drivers/freetype/src/cff/cffparse.h create mode 100644 drivers/freetype/src/cff/cffpic.c create mode 100644 drivers/freetype/src/cff/cffpic.h create mode 100644 drivers/freetype/src/cff/cfftoken.h create mode 100644 drivers/freetype/src/cff/cfftypes.h create mode 100644 drivers/freetype/src/cff/module.mk create mode 100644 drivers/freetype/src/cff/rules.mk create mode 100644 drivers/freetype/src/cid/Jamfile create mode 100644 drivers/freetype/src/cid/ciderrs.h create mode 100644 drivers/freetype/src/cid/cidgload.c create mode 100644 drivers/freetype/src/cid/cidgload.h create mode 100644 drivers/freetype/src/cid/cidload.c create mode 100644 drivers/freetype/src/cid/cidload.h create mode 100644 drivers/freetype/src/cid/cidobjs.c create mode 100644 drivers/freetype/src/cid/cidobjs.h create mode 100644 drivers/freetype/src/cid/cidparse.c create mode 100644 drivers/freetype/src/cid/cidparse.h create mode 100644 drivers/freetype/src/cid/cidriver.c create mode 100644 drivers/freetype/src/cid/cidriver.h create mode 100644 drivers/freetype/src/cid/cidtoken.h create mode 100644 drivers/freetype/src/cid/module.mk create mode 100644 drivers/freetype/src/cid/rules.mk create mode 100644 drivers/freetype/src/cid/type1cid.c create mode 100644 drivers/freetype/src/gxvalid/Jamfile create mode 100644 drivers/freetype/src/gxvalid/README create mode 100644 drivers/freetype/src/gxvalid/gxvalid.c create mode 100644 drivers/freetype/src/gxvalid/gxvalid.h create mode 100644 drivers/freetype/src/gxvalid/gxvbsln.c create mode 100644 drivers/freetype/src/gxvalid/gxvcommn.c create mode 100644 drivers/freetype/src/gxvalid/gxvcommn.h create mode 100644 drivers/freetype/src/gxvalid/gxverror.h create mode 100644 drivers/freetype/src/gxvalid/gxvfeat.c create mode 100644 drivers/freetype/src/gxvalid/gxvfeat.h create mode 100644 drivers/freetype/src/gxvalid/gxvfgen.c create mode 100644 drivers/freetype/src/gxvalid/gxvjust.c create mode 100644 drivers/freetype/src/gxvalid/gxvkern.c create mode 100644 drivers/freetype/src/gxvalid/gxvlcar.c create mode 100644 drivers/freetype/src/gxvalid/gxvmod.c create mode 100644 drivers/freetype/src/gxvalid/gxvmod.h create mode 100644 drivers/freetype/src/gxvalid/gxvmort.c create mode 100644 drivers/freetype/src/gxvalid/gxvmort.h create mode 100644 drivers/freetype/src/gxvalid/gxvmort0.c create mode 100644 drivers/freetype/src/gxvalid/gxvmort1.c create mode 100644 drivers/freetype/src/gxvalid/gxvmort2.c create mode 100644 drivers/freetype/src/gxvalid/gxvmort4.c create mode 100644 drivers/freetype/src/gxvalid/gxvmort5.c create mode 100644 drivers/freetype/src/gxvalid/gxvmorx.c create mode 100644 drivers/freetype/src/gxvalid/gxvmorx.h create mode 100644 drivers/freetype/src/gxvalid/gxvmorx0.c create mode 100644 drivers/freetype/src/gxvalid/gxvmorx1.c create mode 100644 drivers/freetype/src/gxvalid/gxvmorx2.c create mode 100644 drivers/freetype/src/gxvalid/gxvmorx4.c create mode 100644 drivers/freetype/src/gxvalid/gxvmorx5.c create mode 100644 drivers/freetype/src/gxvalid/gxvopbd.c create mode 100644 drivers/freetype/src/gxvalid/gxvprop.c create mode 100644 drivers/freetype/src/gxvalid/gxvtrak.c create mode 100644 drivers/freetype/src/gxvalid/module.mk create mode 100644 drivers/freetype/src/gxvalid/rules.mk create mode 100644 drivers/freetype/src/otvalid/Jamfile create mode 100644 drivers/freetype/src/otvalid/module.mk create mode 100644 drivers/freetype/src/otvalid/otvalid.c create mode 100644 drivers/freetype/src/otvalid/otvalid.h create mode 100644 drivers/freetype/src/otvalid/otvbase.c create mode 100644 drivers/freetype/src/otvalid/otvcommn.c create mode 100644 drivers/freetype/src/otvalid/otvcommn.h create mode 100644 drivers/freetype/src/otvalid/otverror.h create mode 100644 drivers/freetype/src/otvalid/otvgdef.c create mode 100644 drivers/freetype/src/otvalid/otvgpos.c create mode 100644 drivers/freetype/src/otvalid/otvgpos.h create mode 100644 drivers/freetype/src/otvalid/otvgsub.c create mode 100644 drivers/freetype/src/otvalid/otvjstf.c create mode 100644 drivers/freetype/src/otvalid/otvmath.c create mode 100644 drivers/freetype/src/otvalid/otvmod.c create mode 100644 drivers/freetype/src/otvalid/otvmod.h create mode 100644 drivers/freetype/src/otvalid/rules.mk create mode 100644 drivers/freetype/src/pcf/Jamfile create mode 100644 drivers/freetype/src/pcf/README create mode 100644 drivers/freetype/src/pcf/module.mk create mode 100644 drivers/freetype/src/pcf/pcf.c create mode 100644 drivers/freetype/src/pcf/pcf.h create mode 100644 drivers/freetype/src/pcf/pcfdrivr.c create mode 100644 drivers/freetype/src/pcf/pcfdrivr.h create mode 100644 drivers/freetype/src/pcf/pcferror.h create mode 100644 drivers/freetype/src/pcf/pcfread.c create mode 100644 drivers/freetype/src/pcf/pcfread.h create mode 100644 drivers/freetype/src/pcf/pcfutil.c create mode 100644 drivers/freetype/src/pcf/pcfutil.h create mode 100644 drivers/freetype/src/pcf/rules.mk create mode 100644 drivers/freetype/src/pfr/Jamfile create mode 100644 drivers/freetype/src/pfr/module.mk create mode 100644 drivers/freetype/src/pfr/pfr.c create mode 100644 drivers/freetype/src/pfr/pfrcmap.c create mode 100644 drivers/freetype/src/pfr/pfrcmap.h create mode 100644 drivers/freetype/src/pfr/pfrdrivr.c create mode 100644 drivers/freetype/src/pfr/pfrdrivr.h create mode 100644 drivers/freetype/src/pfr/pfrerror.h create mode 100644 drivers/freetype/src/pfr/pfrgload.c create mode 100644 drivers/freetype/src/pfr/pfrgload.h create mode 100644 drivers/freetype/src/pfr/pfrload.c create mode 100644 drivers/freetype/src/pfr/pfrload.h create mode 100644 drivers/freetype/src/pfr/pfrobjs.c create mode 100644 drivers/freetype/src/pfr/pfrobjs.h create mode 100644 drivers/freetype/src/pfr/pfrsbit.c create mode 100644 drivers/freetype/src/pfr/pfrsbit.h create mode 100644 drivers/freetype/src/pfr/pfrtypes.h create mode 100644 drivers/freetype/src/pfr/rules.mk create mode 100644 drivers/freetype/src/psaux/Jamfile create mode 100644 drivers/freetype/src/psaux/afmparse.c create mode 100644 drivers/freetype/src/psaux/afmparse.h create mode 100644 drivers/freetype/src/psaux/module.mk create mode 100644 drivers/freetype/src/psaux/psaux.c create mode 100644 drivers/freetype/src/psaux/psauxerr.h create mode 100644 drivers/freetype/src/psaux/psauxmod.c create mode 100644 drivers/freetype/src/psaux/psauxmod.h create mode 100644 drivers/freetype/src/psaux/psconv.c create mode 100644 drivers/freetype/src/psaux/psconv.h create mode 100644 drivers/freetype/src/psaux/psobjs.c create mode 100644 drivers/freetype/src/psaux/psobjs.h create mode 100644 drivers/freetype/src/psaux/rules.mk create mode 100644 drivers/freetype/src/psaux/t1cmap.c create mode 100644 drivers/freetype/src/psaux/t1cmap.h create mode 100644 drivers/freetype/src/psaux/t1decode.c create mode 100644 drivers/freetype/src/psaux/t1decode.h create mode 100644 drivers/freetype/src/pshinter/Jamfile create mode 100644 drivers/freetype/src/pshinter/module.mk create mode 100644 drivers/freetype/src/pshinter/pshalgo.c create mode 100644 drivers/freetype/src/pshinter/pshalgo.h create mode 100644 drivers/freetype/src/pshinter/pshglob.c create mode 100644 drivers/freetype/src/pshinter/pshglob.h create mode 100644 drivers/freetype/src/pshinter/pshinter.c create mode 100644 drivers/freetype/src/pshinter/pshmod.c create mode 100644 drivers/freetype/src/pshinter/pshmod.h create mode 100644 drivers/freetype/src/pshinter/pshnterr.h create mode 100644 drivers/freetype/src/pshinter/pshpic.c create mode 100644 drivers/freetype/src/pshinter/pshpic.h create mode 100644 drivers/freetype/src/pshinter/pshrec.c create mode 100644 drivers/freetype/src/pshinter/pshrec.h create mode 100644 drivers/freetype/src/pshinter/rules.mk create mode 100644 drivers/freetype/src/psnames/Jamfile create mode 100644 drivers/freetype/src/psnames/module.mk create mode 100644 drivers/freetype/src/psnames/psmodule.c create mode 100644 drivers/freetype/src/psnames/psmodule.h create mode 100644 drivers/freetype/src/psnames/psnamerr.h create mode 100644 drivers/freetype/src/psnames/psnames.c create mode 100644 drivers/freetype/src/psnames/pspic.c create mode 100644 drivers/freetype/src/psnames/pspic.h create mode 100644 drivers/freetype/src/psnames/pstables.h create mode 100644 drivers/freetype/src/psnames/rules.mk create mode 100644 drivers/freetype/src/raster/Jamfile create mode 100644 drivers/freetype/src/raster/ftmisc.h create mode 100644 drivers/freetype/src/raster/ftraster.c create mode 100644 drivers/freetype/src/raster/ftraster.h create mode 100644 drivers/freetype/src/raster/ftrend1.c create mode 100644 drivers/freetype/src/raster/ftrend1.h create mode 100644 drivers/freetype/src/raster/module.mk create mode 100644 drivers/freetype/src/raster/raster.c create mode 100644 drivers/freetype/src/raster/rasterrs.h create mode 100644 drivers/freetype/src/raster/rastpic.c create mode 100644 drivers/freetype/src/raster/rastpic.h create mode 100644 drivers/freetype/src/raster/rules.mk create mode 100644 drivers/freetype/src/sfnt/Jamfile create mode 100644 drivers/freetype/src/sfnt/module.mk create mode 100644 drivers/freetype/src/sfnt/pngshim.c create mode 100644 drivers/freetype/src/sfnt/pngshim.h create mode 100644 drivers/freetype/src/sfnt/rules.mk create mode 100644 drivers/freetype/src/sfnt/sfdriver.c create mode 100644 drivers/freetype/src/sfnt/sfdriver.h create mode 100644 drivers/freetype/src/sfnt/sferrors.h create mode 100644 drivers/freetype/src/sfnt/sfnt.c create mode 100644 drivers/freetype/src/sfnt/sfntpic.c create mode 100644 drivers/freetype/src/sfnt/sfntpic.h create mode 100644 drivers/freetype/src/sfnt/sfobjs.c create mode 100644 drivers/freetype/src/sfnt/sfobjs.h create mode 100644 drivers/freetype/src/sfnt/ttbdf.c create mode 100644 drivers/freetype/src/sfnt/ttbdf.h create mode 100644 drivers/freetype/src/sfnt/ttcmap.c create mode 100644 drivers/freetype/src/sfnt/ttcmap.h create mode 100644 drivers/freetype/src/sfnt/ttcmapc.h create mode 100644 drivers/freetype/src/sfnt/ttkern.c create mode 100644 drivers/freetype/src/sfnt/ttkern.h create mode 100644 drivers/freetype/src/sfnt/ttload.c create mode 100644 drivers/freetype/src/sfnt/ttload.h create mode 100644 drivers/freetype/src/sfnt/ttmtx.c create mode 100644 drivers/freetype/src/sfnt/ttmtx.h create mode 100644 drivers/freetype/src/sfnt/ttpost.c create mode 100644 drivers/freetype/src/sfnt/ttpost.h create mode 100644 drivers/freetype/src/sfnt/ttsbit.c create mode 100644 drivers/freetype/src/sfnt/ttsbit.h create mode 100644 drivers/freetype/src/smooth/Jamfile create mode 100644 drivers/freetype/src/smooth/ftgrays.c create mode 100644 drivers/freetype/src/smooth/ftgrays.h create mode 100644 drivers/freetype/src/smooth/ftsmerrs.h create mode 100644 drivers/freetype/src/smooth/ftsmooth.c create mode 100644 drivers/freetype/src/smooth/ftsmooth.h create mode 100644 drivers/freetype/src/smooth/ftspic.c create mode 100644 drivers/freetype/src/smooth/ftspic.h create mode 100644 drivers/freetype/src/smooth/module.mk create mode 100644 drivers/freetype/src/smooth/rules.mk create mode 100644 drivers/freetype/src/smooth/smooth.c create mode 100644 drivers/freetype/src/truetype/Jamfile create mode 100644 drivers/freetype/src/truetype/module.mk create mode 100644 drivers/freetype/src/truetype/rules.mk create mode 100644 drivers/freetype/src/truetype/truetype.c create mode 100644 drivers/freetype/src/truetype/ttdriver.c create mode 100644 drivers/freetype/src/truetype/ttdriver.h create mode 100644 drivers/freetype/src/truetype/tterrors.h create mode 100644 drivers/freetype/src/truetype/ttgload.c create mode 100644 drivers/freetype/src/truetype/ttgload.h create mode 100644 drivers/freetype/src/truetype/ttgxvar.c create mode 100644 drivers/freetype/src/truetype/ttgxvar.h create mode 100644 drivers/freetype/src/truetype/ttinterp.c create mode 100644 drivers/freetype/src/truetype/ttinterp.h create mode 100644 drivers/freetype/src/truetype/ttobjs.c create mode 100644 drivers/freetype/src/truetype/ttobjs.h create mode 100644 drivers/freetype/src/truetype/ttpic.c create mode 100644 drivers/freetype/src/truetype/ttpic.h create mode 100644 drivers/freetype/src/truetype/ttpload.c create mode 100644 drivers/freetype/src/truetype/ttpload.h create mode 100644 drivers/freetype/src/truetype/ttsubpix.c create mode 100644 drivers/freetype/src/truetype/ttsubpix.h create mode 100644 drivers/freetype/src/type1/Jamfile create mode 100644 drivers/freetype/src/type1/module.mk create mode 100644 drivers/freetype/src/type1/rules.mk create mode 100644 drivers/freetype/src/type1/t1afm.c create mode 100644 drivers/freetype/src/type1/t1afm.h create mode 100644 drivers/freetype/src/type1/t1driver.c create mode 100644 drivers/freetype/src/type1/t1driver.h create mode 100644 drivers/freetype/src/type1/t1errors.h create mode 100644 drivers/freetype/src/type1/t1gload.c create mode 100644 drivers/freetype/src/type1/t1gload.h create mode 100644 drivers/freetype/src/type1/t1load.c create mode 100644 drivers/freetype/src/type1/t1load.h create mode 100644 drivers/freetype/src/type1/t1objs.c create mode 100644 drivers/freetype/src/type1/t1objs.h create mode 100644 drivers/freetype/src/type1/t1parse.c create mode 100644 drivers/freetype/src/type1/t1parse.h create mode 100644 drivers/freetype/src/type1/t1tokens.h create mode 100644 drivers/freetype/src/type1/type1.c create mode 100644 drivers/freetype/src/type42/Jamfile create mode 100644 drivers/freetype/src/type42/module.mk create mode 100644 drivers/freetype/src/type42/rules.mk create mode 100644 drivers/freetype/src/type42/t42drivr.c create mode 100644 drivers/freetype/src/type42/t42drivr.h create mode 100644 drivers/freetype/src/type42/t42error.h create mode 100644 drivers/freetype/src/type42/t42objs.c create mode 100644 drivers/freetype/src/type42/t42objs.h create mode 100644 drivers/freetype/src/type42/t42parse.c create mode 100644 drivers/freetype/src/type42/t42parse.h create mode 100644 drivers/freetype/src/type42/t42types.h create mode 100644 drivers/freetype/src/type42/type42.c create mode 100644 drivers/freetype/src/winfonts/Jamfile create mode 100644 drivers/freetype/src/winfonts/fnterrs.h create mode 100644 drivers/freetype/src/winfonts/module.mk create mode 100644 drivers/freetype/src/winfonts/rules.mk create mode 100644 drivers/freetype/src/winfonts/winfnt.c create mode 100644 drivers/freetype/src/winfonts/winfnt.h (limited to 'drivers') diff --git a/drivers/freetype/SCsub b/drivers/freetype/SCsub index 206da8dbe4..0ea29d25ab 100644 --- a/drivers/freetype/SCsub +++ b/drivers/freetype/SCsub @@ -1,50 +1,49 @@ Import('env') ft_sources=[\ -"freetype/src/pfr/pfr.c",\ -"freetype/src/psaux/psaux.c",\ -"freetype/src/pcf/pcf.c",\ -"freetype/src/otvalid/otvalid.c",\ -"freetype/src/raster/raster.c",\ -"freetype/src/type1/type1.c",\ -"freetype/src/pshinter/pshinter.c",\ -"freetype/src/cff/cff.c",\ -"freetype/src/truetype/truetype.c",\ -"freetype/src/bdf/bdf.c",\ -"freetype/src/cache/ftcache.c",\ -"freetype/src/sfnt/sfnt.c",\ -"freetype/src/winfonts/winfnt.c",\ -"freetype/src/psnames/psnames.c",\ -"freetype/src/cid/type1cid.c",\ -"freetype/src/autofit/autofit.c",\ -"freetype/src/gxvalid/gxvalid.c",\ -"freetype/src/smooth/smooth.c",\ -"freetype/src/type42/type42.c",\ -"freetype/src/base/ftapi.c",\ -"freetype/src/base/ftbase.c",\ -"freetype/src/base/ftbbox.c",\ -"freetype/src/base/ftbdf.c",\ -"freetype/src/base/ftbitmap.c",\ -"freetype/src/base/ftcid.c",\ -"freetype/src/base/ftdebug.c",\ -"freetype/src/base/ftfstype.c",\ -"freetype/src/base/ftgasp.c",\ -"freetype/src/base/ftglyph.c",\ -"freetype/src/base/ftgxval.c",\ -"freetype/src/base/ftinit.c",\ -"freetype/src/base/ftlcdfil.c",\ -"freetype/src/base/ftmm.c",\ -"freetype/src/base/ftotval.c",\ -"freetype/src/base/ftpatent.c",\ -"freetype/src/base/ftpfr.c",\ -"freetype/src/base/ftpic.c",\ -"freetype/src/base/ftstroke.c",\ -"freetype/src/base/ftsynth.c",\ -"freetype/src/base/ftsystem.c",\ -"freetype/src/base/fttype1.c",\ -"freetype/src/base/ftwinfnt.c",\ -"freetype/src/base/ftxf86.c",\ - +"src/autofit/autofit.c",\ +"src/base/ftapi.c",\ +"src/base/ftbase.c",\ +"src/base/ftbbox.c",\ +"src/base/ftbdf.c",\ +"src/base/ftbitmap.c",\ +"src/base/ftcid.c",\ +"src/base/ftdebug.c",\ +"src/base/ftfstype.c",\ +"src/base/ftgasp.c",\ +"src/base/ftglyph.c",\ +"src/base/ftgxval.c",\ +"src/base/ftinit.c",\ +"src/base/ftlcdfil.c",\ +"src/base/ftmm.c",\ +"src/base/ftotval.c",\ +"src/base/ftpatent.c",\ +"src/base/ftpfr.c",\ +"src/base/ftpic.c",\ +"src/base/ftstroke.c",\ +"src/base/ftsynth.c",\ +"src/base/ftsystem.c",\ +"src/base/fttype1.c",\ +"src/base/ftwinfnt.c",\ +"src/base/ftxf86.c",\ +"src/bdf/bdf.c",\ +"src/cache/ftcache.c",\ +"src/cff/cff.c",\ +"src/cid/type1cid.c",\ +"src/gxvalid/gxvalid.c",\ +"src/otvalid/otvalid.c",\ +"src/pcf/pcf.c",\ +"src/pfr/pfr.c",\ +"src/psaux/psaux.c",\ +"src/pshinter/pshinter.c",\ +"src/psnames/psnames.c",\ +"src/raster/raster.c",\ +"src/sfnt/sfnt.c",\ +"src/smooth/smooth.c",\ +"src/truetype/truetype.c",\ +"src/type1/type1.c",\ +"src/type42/type42.c",\ +"src/winfonts/winfnt.c",\ ] @@ -53,7 +52,7 @@ if (env["freetype"]=="builtin"): half1=[] half2=[] for x in ft_sources: - if (x.find("freetype/src/base")==0 or x.find("freetype/src/sfnt")==0): + if (x.find("src/base")==0 or x.find("src/sfnt")==0): half2.append(x) else: half1.append(x) @@ -63,7 +62,7 @@ if (env["freetype"]=="builtin"): lib = env.Library("freetype_builtin2",half1) env.Append(LIBS=[lib]) - env.Append(CPPPATH=["#drivers/freetype/freetype/include"]) + env.Append(CPPPATH=["#drivers/freetype/include"]) Export('env') diff --git a/drivers/freetype/freetype/include/freetype/config/ftconfig.h b/drivers/freetype/freetype/include/freetype/config/ftconfig.h deleted file mode 100644 index 5dce30ef3e..0000000000 --- a/drivers/freetype/freetype/include/freetype/config/ftconfig.h +++ /dev/null @@ -1,598 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftconfig.h */ -/* */ -/* ANSI-specific configuration file (specification only). */ -/* */ -/* Copyright 1996-2004, 2006-2008, 2010-2011, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This header file contains a number of macro definitions that are used */ - /* by the rest of the engine. Most of the macros here are automatically */ - /* determined at compile time, and you should not need to change it to */ - /* port FreeType, except to compile the library with a non-ANSI */ - /* compiler. */ - /* */ - /* Note however that if some specific modifications are needed, we */ - /* advise you to place a modified copy in your build directory. */ - /* */ - /* The build directory is usually `freetype/builds/', and */ - /* contains system-specific files that are always included first when */ - /* building the library. */ - /* */ - /* This ANSI version should stay in `include/freetype/config'. */ - /* */ - /*************************************************************************/ - -#ifndef __FTCONFIG_H__ -#define __FTCONFIG_H__ - -#include -#include FT_CONFIG_OPTIONS_H -#include FT_CONFIG_STANDARD_LIBRARY_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled to suit a specific system. The current */ - /* ones are defaults used to compile FreeType in an ANSI C environment */ - /* (16bit compilers are also supported). Copy this file to your own */ - /* `freetype/builds/' directory, and edit it to port the engine. */ - /* */ - /*************************************************************************/ - - - /* There are systems (like the Texas Instruments 'C54x) where a `char' */ - /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ - /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ - /* is probably unexpected. */ - /* */ - /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ - /* `char' type. */ - -#ifndef FT_CHAR_BIT -#define FT_CHAR_BIT CHAR_BIT -#endif - - - /* The size of an `int' type. */ -#if FT_UINT_MAX == 0xFFFFUL -#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) -#elif FT_UINT_MAX == 0xFFFFFFFFUL -#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) -#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL -#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) -#else -#error "Unsupported size of `int' type!" -#endif - - /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ - /* DM642) is recognized but avoided. */ -#if FT_ULONG_MAX == 0xFFFFFFFFUL -#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) -#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL -#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) -#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL -#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) -#else -#error "Unsupported size of `long' type!" -#endif - - - /* FT_UNUSED is a macro used to indicate that a given parameter is not */ - /* used -- this is only used to get rid of unpleasant compiler warnings */ -#ifndef FT_UNUSED -#define FT_UNUSED( arg ) ( (arg) = (arg) ) -#endif - - - /*************************************************************************/ - /* */ - /* AUTOMATIC CONFIGURATION MACROS */ - /* */ - /* These macros are computed from the ones defined above. Don't touch */ - /* their definition, unless you know precisely what you are doing. No */ - /* porter should need to mess with them. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Mac support */ - /* */ - /* This is the only necessary change, so it is defined here instead */ - /* providing a new configuration file. */ - /* */ -#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) - /* no Carbon frameworks for 64bit 10.4.x */ - /* AvailabilityMacros.h is available since Mac OS X 10.2, */ - /* so guess the system version by maximum errno before inclusion */ -#include -#ifdef ECANCELED /* defined since 10.2 */ -#include "AvailabilityMacros.h" -#endif -#if defined( __LP64__ ) && \ - ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) -#undef FT_MACINTOSH -#endif - -#elif defined( __SC__ ) || defined( __MRC__ ) - /* Classic MacOS compilers */ -#include "ConditionalMacros.h" -#if TARGET_OS_MAC -#define FT_MACINTOSH 1 -#endif - -#endif - - - /*************************************************************************/ - /* */ - /*
*/ - /* basic_types */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Int16 */ - /* */ - /* */ - /* A typedef for a 16bit signed integer type. */ - /* */ - typedef signed short FT_Int16; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt16 */ - /* */ - /* */ - /* A typedef for a 16bit unsigned integer type. */ - /* */ - typedef unsigned short FT_UInt16; - - /* */ - - - /* this #if 0 ... #endif clause is for documentation purposes */ -#if 0 - - /*************************************************************************/ - /* */ - /* */ - /* FT_Int32 */ - /* */ - /* */ - /* A typedef for a 32bit signed integer type. The size depends on */ - /* the configuration. */ - /* */ - typedef signed XXX FT_Int32; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt32 */ - /* */ - /* A typedef for a 32bit unsigned integer type. The size depends on */ - /* the configuration. */ - /* */ - typedef unsigned XXX FT_UInt32; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Int64 */ - /* */ - /* A typedef for a 64bit signed integer type. The size depends on */ - /* the configuration. Only defined if there is real 64bit support; */ - /* otherwise, it gets emulated with a structure (if necessary). */ - /* */ - typedef signed XXX FT_Int64; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt64 */ - /* */ - /* A typedef for a 64bit unsigned integer type. The size depends on */ - /* the configuration. Only defined if there is real 64bit support; */ - /* otherwise, it gets emulated with a structure (if necessary). */ - /* */ - typedef unsigned XXX FT_UInt64; - - /* */ - -#endif - -#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) - - typedef signed int FT_Int32; - typedef unsigned int FT_UInt32; - -#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) - - typedef signed long FT_Int32; - typedef unsigned long FT_UInt32; - -#else -#error "no 32bit type found -- please check your configuration files" -#endif - - - /* look up an integer type that is at least 32 bits */ -#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) - - typedef int FT_Fast; - typedef unsigned int FT_UFast; - -#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) - - typedef long FT_Fast; - typedef unsigned long FT_UFast; - -#endif - - - /* determine whether we have a 64-bit int type for platforms without */ - /* Autoconf */ -#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) - - /* FT_LONG64 must be defined if a 64-bit type is available */ -#define FT_LONG64 -#define FT_INT64 long -#define FT_UINT64 unsigned long - -#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ - - /* this compiler provides the __int64 type */ -#define FT_LONG64 -#define FT_INT64 __int64 -#define FT_UINT64 unsigned __int64 - -#elif defined( __BORLANDC__ ) /* Borland C++ */ - - /* XXXX: We should probably check the value of __BORLANDC__ in order */ - /* to test the compiler version. */ - - /* this compiler provides the __int64 type */ -#define FT_LONG64 -#define FT_INT64 __int64 -#define FT_UINT64 unsigned __int64 - -#elif defined( __WATCOMC__ ) /* Watcom C++ */ - - /* Watcom doesn't provide 64-bit data types */ - -#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ - -#define FT_LONG64 -#define FT_INT64 long long int -#define FT_UINT64 unsigned long long int - -#elif defined( __GNUC__ ) - - /* GCC provides the `long long' type */ -#define FT_LONG64 -#define FT_INT64 long long int -#define FT_UINT64 unsigned long long int - -#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ - - - /*************************************************************************/ - /* */ - /* A 64-bit data type will create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ - /* is defined. You can however ignore this rule by defining the */ - /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ - /* */ -#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) - -#ifdef __STDC__ - - /* undefine the 64-bit macros in strict ANSI compilation mode */ -#undef FT_LONG64 -#undef FT_INT64 - -#endif /* __STDC__ */ - -#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ - -#ifdef FT_LONG64 - typedef FT_INT64 FT_Int64; - typedef FT_UINT64 FT_UInt64; -#endif - - -#define FT_BEGIN_STMNT do { -#define FT_END_STMNT } while ( 0 ) -#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT - - -#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER - /* Provide assembler fragments for performance-critical functions. */ - /* These must be defined `static __inline__' with GCC. */ - -#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm - { - smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ - mov a, t, asr #31 /* a = (hi >> 31) */ - add a, a, #0x8000 /* a += 0x8000 */ - adds t2, t2, a /* t2 += a */ - adc t, t, #0 /* t += carry */ - mov a, t2, lsr #16 /* a = t2 >> 16 */ - orr a, a, t, lsl #16 /* a |= t << 16 */ - } - return a; - } - -#endif /* __CC_ARM || __ARMCC__ */ - - -#ifdef __GNUC__ - -#if defined( __arm__ ) && !defined( __thumb__ ) && \ - !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm__ __volatile__ ( - "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ - "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ - "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ - "adds %1, %1, %0\n\t" /* %1 += %0 */ - "adc %2, %2, #0\n\t" /* %2 += carry */ - "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ - "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ - : "=r"(a), "=&r"(t2), "=&r"(t) - : "r"(a), "r"(b) - : "cc" ); - return a; - } - -#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */ - -#if defined( __i386__ ) -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 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" - : "=a"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx", "cc" ); - return result; - } - -#endif /* i386 */ - -#endif /* __GNUC__ */ - - -#ifdef _MSC_VER /* Visual C++ */ - -#ifdef _M_IX86 - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - __asm - { - mov eax, a - mov edx, b - imul edx - mov ecx, edx - sar ecx, 31 - add ecx, 8000h - add eax, ecx - adc edx, 0 - shr eax, 16 - shl edx, 16 - add eax, edx - mov result, eax - } - return result; - } - -#endif /* _M_IX86 */ - -#endif /* _MSC_VER */ - -#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ - - -#ifdef FT_CONFIG_OPTION_INLINE_MULFIX -#ifdef FT_MULFIX_ASSEMBLER -#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER -#endif -#endif - - -#ifdef FT_MAKE_OPTION_SINGLE_OBJECT - -#define FT_LOCAL( x ) static x -#define FT_LOCAL_DEF( x ) static x - -#else - -#ifdef __cplusplus -#define FT_LOCAL( x ) extern "C" x -#define FT_LOCAL_DEF( x ) extern "C" x -#else -#define FT_LOCAL( x ) extern x -#define FT_LOCAL_DEF( x ) x -#endif - -#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ - - -#ifndef FT_BASE - -#ifdef __cplusplus -#define FT_BASE( x ) extern "C" x -#else -#define FT_BASE( x ) extern x -#endif - -#endif /* !FT_BASE */ - - -#ifndef FT_BASE_DEF - -#ifdef __cplusplus -#define FT_BASE_DEF( x ) x -#else -#define FT_BASE_DEF( x ) x -#endif - -#endif /* !FT_BASE_DEF */ - - -#ifndef FT_EXPORT - -#ifdef __cplusplus -#define FT_EXPORT( x ) extern "C" x -#else -#define FT_EXPORT( x ) extern x -#endif - -#endif /* !FT_EXPORT */ - - -#ifndef FT_EXPORT_DEF - -#ifdef __cplusplus -#define FT_EXPORT_DEF( x ) extern "C" x -#else -#define FT_EXPORT_DEF( x ) extern x -#endif - -#endif /* !FT_EXPORT_DEF */ - - -#ifndef FT_EXPORT_VAR - -#ifdef __cplusplus -#define FT_EXPORT_VAR( x ) extern "C" x -#else -#define FT_EXPORT_VAR( x ) extern x -#endif - -#endif /* !FT_EXPORT_VAR */ - - /* The following macros are needed to compile the library with a */ - /* C++ compiler and with 16bit compilers. */ - /* */ - - /* This is special. Within C++, you must specify `extern "C"' for */ - /* functions which are used via function pointers, and you also */ - /* must do that for structures which contain function pointers to */ - /* assure C linkage -- it's not possible to have (local) anonymous */ - /* functions which are accessed by (global) function pointers. */ - /* */ - /* */ - /* FT_CALLBACK_DEF is used to _define_ a callback function. */ - /* */ - /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ - /* contains pointers to callback functions. */ - /* */ - /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ - /* that contains pointers to callback functions. */ - /* */ - /* */ - /* Some 16bit compilers have to redefine these macros to insert */ - /* the infamous `_cdecl' or `__fastcall' declarations. */ - /* */ -#ifndef FT_CALLBACK_DEF -#ifdef __cplusplus -#define FT_CALLBACK_DEF( x ) extern "C" x -#else -#define FT_CALLBACK_DEF( x ) static x -#endif -#endif /* FT_CALLBACK_DEF */ - -#ifndef FT_CALLBACK_TABLE -#ifdef __cplusplus -#define FT_CALLBACK_TABLE extern "C" -#define FT_CALLBACK_TABLE_DEF extern "C" -#else -#define FT_CALLBACK_TABLE extern -#define FT_CALLBACK_TABLE_DEF /* nothing */ -#endif -#endif /* FT_CALLBACK_TABLE */ - - -FT_END_HEADER - - -#endif /* __FTCONFIG_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/config/ftheader.h b/drivers/freetype/freetype/include/freetype/config/ftheader.h deleted file mode 100644 index 8371a31611..0000000000 --- a/drivers/freetype/freetype/include/freetype/config/ftheader.h +++ /dev/null @@ -1,832 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftheader.h */ -/* */ -/* Build macros of the FreeType 2 library. */ -/* */ -/* Copyright 1996-2008, 2010, 2012, 2013 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_HEADER_H__ -#define __FT_HEADER_H__ - - - /*@***********************************************************************/ - /* */ - /* */ - /* FT_BEGIN_HEADER */ - /* */ - /* */ - /* This macro is used in association with @FT_END_HEADER in header */ - /* files to ensure that the declarations within are properly */ - /* encapsulated in an `extern "C" { .. }' block when included from a */ - /* C++ compiler. */ - /* */ -#ifdef __cplusplus -#define FT_BEGIN_HEADER extern "C" { -#else -#define FT_BEGIN_HEADER /* nothing */ -#endif - - - /*@***********************************************************************/ - /* */ - /* */ - /* FT_END_HEADER */ - /* */ - /* */ - /* This macro is used in association with @FT_BEGIN_HEADER in header */ - /* files to ensure that the declarations within are properly */ - /* encapsulated in an `extern "C" { .. }' block when included from a */ - /* C++ compiler. */ - /* */ -#ifdef __cplusplus -#define FT_END_HEADER } -#else -#define FT_END_HEADER /* nothing */ -#endif - - - /*************************************************************************/ - /* */ - /* Aliases for the FreeType 2 public and configuration files. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /*
*/ - /* header_file_macros */ - /* */ - /* */ - /* Header File Macros */ - /* */ - /* <Abstract> */ - /* Macro definitions used to #include specific header files. */ - /* */ - /* <Description> */ - /* The following macros are defined to the name of specific */ - /* FreeType~2 header files. They can be used directly in #include */ - /* statements as in: */ - /* */ - /* { */ - /* #include FT_FREETYPE_H */ - /* #include FT_MULTIPLE_MASTERS_H */ - /* #include FT_GLYPH_H */ - /* } */ - /* */ - /* There are several reasons why we are now using macros to name */ - /* public header files. The first one is that such macros are not */ - /* 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 it allows for more flexibility in the */ - /* way FreeType~2 is installed on a given system. */ - /* */ - /*************************************************************************/ - - - /* configuration files */ - - /************************************************************************* - * - * @macro: - * FT_CONFIG_CONFIG_H - * - * @description: - * A macro used in #include statements to name the file containing - * FreeType~2 configuration data. - * - */ -#ifndef FT_CONFIG_CONFIG_H -#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> -#endif - - - /************************************************************************* - * - * @macro: - * FT_CONFIG_STANDARD_LIBRARY_H - * - * @description: - * A macro used in #include statements to name the file containing - * FreeType~2 interface to the standard C library functions. - * - */ -#ifndef FT_CONFIG_STANDARD_LIBRARY_H -#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h> -#endif - - - /************************************************************************* - * - * @macro: - * FT_CONFIG_OPTIONS_H - * - * @description: - * A macro used in #include statements to name the file containing - * FreeType~2 project-specific configuration options. - * - */ -#ifndef FT_CONFIG_OPTIONS_H -#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h> -#endif - - - /************************************************************************* - * - * @macro: - * FT_CONFIG_MODULES_H - * - * @description: - * A macro used in #include statements to name the file containing the - * list of FreeType~2 modules that are statically linked to new library - * instances in @FT_Init_FreeType. - * - */ -#ifndef FT_CONFIG_MODULES_H -#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h> -#endif - - /* */ - - /* public headers */ - - /************************************************************************* - * - * @macro: - * FT_FREETYPE_H - * - * @description: - * A macro used in #include statements to name the file containing the - * base FreeType~2 API. - * - */ -#define FT_FREETYPE_H <freetype/freetype.h> - - - /************************************************************************* - * - * @macro: - * FT_ERRORS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * list of FreeType~2 error codes (and messages). - * - * It is included by @FT_FREETYPE_H. - * - */ -#define FT_ERRORS_H <freetype/fterrors.h> - - - /************************************************************************* - * - * @macro: - * FT_MODULE_ERRORS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * list of FreeType~2 module error offsets (and messages). - * - */ -#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> - - - /************************************************************************* - * - * @macro: - * FT_SYSTEM_H - * - * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 interface to low-level operations (i.e., memory management - * and stream i/o). - * - * It is included by @FT_FREETYPE_H. - * - */ -#define FT_SYSTEM_H <freetype/ftsystem.h> - - - /************************************************************************* - * - * @macro: - * FT_IMAGE_H - * - * @description: - * A macro used in #include statements to name the file containing type - * definitions related to glyph images (i.e., bitmaps, outlines, - * scan-converter parameters). - * - * It is included by @FT_FREETYPE_H. - * - */ -#define FT_IMAGE_H <freetype/ftimage.h> - - - /************************************************************************* - * - * @macro: - * FT_TYPES_H - * - * @description: - * A macro used in #include statements to name the file containing the - * basic data types defined by FreeType~2. - * - * It is included by @FT_FREETYPE_H. - * - */ -#define FT_TYPES_H <freetype/fttypes.h> - - - /************************************************************************* - * - * @macro: - * FT_LIST_H - * - * @description: - * A macro used in #include statements to name the file containing the - * list management API of FreeType~2. - * - * (Most applications will never need to include this file.) - * - */ -#define FT_LIST_H <freetype/ftlist.h> - - - /************************************************************************* - * - * @macro: - * FT_OUTLINE_H - * - * @description: - * A macro used in #include statements to name the file containing the - * scalable outline management API of FreeType~2. - * - */ -#define FT_OUTLINE_H <freetype/ftoutln.h> - - - /************************************************************************* - * - * @macro: - * FT_SIZES_H - * - * @description: - * A macro used in #include statements to name the file containing the - * API which manages multiple @FT_Size objects per face. - * - */ -#define FT_SIZES_H <freetype/ftsizes.h> - - - /************************************************************************* - * - * @macro: - * FT_MODULE_H - * - * @description: - * A macro used in #include statements to name the file containing the - * module management API of FreeType~2. - * - */ -#define FT_MODULE_H <freetype/ftmodapi.h> - - - /************************************************************************* - * - * @macro: - * FT_RENDER_H - * - * @description: - * A macro used in #include statements to name the file containing the - * renderer module management API of FreeType~2. - * - */ -#define FT_RENDER_H <freetype/ftrender.h> - - - /************************************************************************* - * - * @macro: - * FT_AUTOHINTER_H - * - * @description: - * A macro used in #include statements to name the file containing - * structures and macros related to the auto-hinting module. - * - */ -#define FT_AUTOHINTER_H <freetype/ftautoh.h> - - - /************************************************************************* - * - * @macro: - * FT_CFF_DRIVER_H - * - * @description: - * A macro used in #include statements to name the file containing - * structures and macros related to the CFF driver module. - * - */ -#define FT_CFF_DRIVER_H <freetype/ftcffdrv.h> - - - /************************************************************************* - * - * @macro: - * FT_TRUETYPE_DRIVER_H - * - * @description: - * A macro used in #include statements to name the file containing - * structures and macros related to the TrueType driver module. - * - */ -#define FT_TRUETYPE_DRIVER_H <freetype/ftttdrv.h> - - - /************************************************************************* - * - * @macro: - * FT_TYPE1_TABLES_H - * - * @description: - * A macro used in #include statements to name the file containing the - * types and API specific to the Type~1 format. - * - */ -#define FT_TYPE1_TABLES_H <freetype/t1tables.h> - - - /************************************************************************* - * - * @macro: - * FT_TRUETYPE_IDS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * 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> - - - /************************************************************************* - * - * @macro: - * FT_TRUETYPE_TABLES_H - * - * @description: - * A macro used in #include statements to name the file containing the - * types and API specific to the TrueType (as well as OpenType) format. - * - */ -#define FT_TRUETYPE_TABLES_H <freetype/tttables.h> - - - /************************************************************************* - * - * @macro: - * FT_TRUETYPE_TAGS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * definitions of TrueType four-byte `tags' which identify blocks in - * SFNT-based font formats (i.e., TrueType and OpenType). - * - */ -#define FT_TRUETYPE_TAGS_H <freetype/tttags.h> - - - /************************************************************************* - * - * @macro: - * FT_BDF_H - * - * @description: - * A macro used in #include statements to name the file containing the - * definitions of an API which accesses BDF-specific strings from a - * face. - * - */ -#define FT_BDF_H <freetype/ftbdf.h> - - - /************************************************************************* - * - * @macro: - * FT_CID_H - * - * @description: - * A macro used in #include statements to name the file containing the - * definitions of an API which access CID font information from a - * face. - * - */ -#define FT_CID_H <freetype/ftcid.h> - - - /************************************************************************* - * - * @macro: - * FT_GZIP_H - * - * @description: - * A macro used in #include statements to name the file containing the - * definitions of an API which supports gzip-compressed files. - * - */ -#define FT_GZIP_H <freetype/ftgzip.h> - - - /************************************************************************* - * - * @macro: - * FT_LZW_H - * - * @description: - * A macro used in #include statements to name the file containing the - * definitions of an API which supports LZW-compressed files. - * - */ -#define FT_LZW_H <freetype/ftlzw.h> - - - /************************************************************************* - * - * @macro: - * FT_BZIP2_H - * - * @description: - * A macro used in #include statements to name the file containing the - * definitions of an API which supports bzip2-compressed files. - * - */ -#define FT_BZIP2_H <freetype/ftbzip2.h> - - - /************************************************************************* - * - * @macro: - * FT_WINFONTS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * definitions of an API which supports Windows FNT files. - * - */ -#define FT_WINFONTS_H <freetype/ftwinfnt.h> - - - /************************************************************************* - * - * @macro: - * FT_GLYPH_H - * - * @description: - * A macro used in #include statements to name the file containing the - * API of the optional glyph management component. - * - */ -#define FT_GLYPH_H <freetype/ftglyph.h> - - - /************************************************************************* - * - * @macro: - * FT_BITMAP_H - * - * @description: - * A macro used in #include statements to name the file containing the - * API of the optional bitmap conversion component. - * - */ -#define FT_BITMAP_H <freetype/ftbitmap.h> - - - /************************************************************************* - * - * @macro: - * FT_BBOX_H - * - * @description: - * A macro used in #include statements to name the file containing the - * API of the optional exact bounding box computation routines. - * - */ -#define FT_BBOX_H <freetype/ftbbox.h> - - - /************************************************************************* - * - * @macro: - * FT_CACHE_H - * - * @description: - * A macro used in #include statements to name the file containing the - * API of the optional FreeType~2 cache sub-system. - * - */ -#define FT_CACHE_H <freetype/ftcache.h> - - - /************************************************************************* - * - * @macro: - * FT_CACHE_IMAGE_H - * - * @description: - * A macro used in #include statements to name the file containing the - * `glyph image' API of the FreeType~2 cache sub-system. - * - * It is used to define a cache for @FT_Glyph elements. You can also - * 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 - * glyph image-related cache declarations. - * - */ -#define FT_CACHE_IMAGE_H FT_CACHE_H - - - /************************************************************************* - * - * @macro: - * FT_CACHE_SMALL_BITMAPS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * `small bitmaps' API of the FreeType~2 cache sub-system. - * - * It is used to define a cache for small glyph bitmaps in a relatively - * memory-efficient way. You can also use the API defined in - * @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, - * including scalable outlines. - * - * This macro is deprecated. Simply include @FT_CACHE_H to have all - * small bitmaps-related cache declarations. - * - */ -#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H - - - /************************************************************************* - * - * @macro: - * FT_CACHE_CHARMAP_H - * - * @description: - * A macro used in #include statements to name the file containing the - * `charmap' API of the FreeType~2 cache sub-system. - * - * This macro is deprecated. Simply include @FT_CACHE_H to have all - * charmap-based cache declarations. - * - */ -#define FT_CACHE_CHARMAP_H FT_CACHE_H - - - /************************************************************************* - * - * @macro: - * FT_MAC_H - * - * @description: - * A macro used in #include statements to name the file containing the - * Macintosh-specific FreeType~2 API. The latter is used to access - * fonts embedded in resource forks. - * - * This header file must be explicitly included by client applications - * compiled on the Mac (note that the base API still works though). - * - */ -#define FT_MAC_H <freetype/ftmac.h> - - - /************************************************************************* - * - * @macro: - * FT_MULTIPLE_MASTERS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * optional multiple-masters management API of FreeType~2. - * - */ -#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> - - - /************************************************************************* - * - * @macro: - * FT_SFNT_NAMES_H - * - * @description: - * A macro used in #include statements to name the file containing the - * optional FreeType~2 API which accesses embedded `name' strings in - * SFNT-based font formats (i.e., TrueType and OpenType). - * - */ -#define FT_SFNT_NAMES_H <freetype/ftsnames.h> - - - /************************************************************************* - * - * @macro: - * FT_OPENTYPE_VALIDATE_H - * - * @description: - * A macro used in #include statements to name the file containing the - * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, - * GPOS, GSUB, JSTF). - * - */ -#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h> - - - /************************************************************************* - * - * @macro: - * FT_GX_VALIDATE_H - * - * @description: - * A macro used in #include statements to name the file containing the - * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, - * mort, morx, bsln, just, kern, opbd, trak, prop). - * - */ -#define FT_GX_VALIDATE_H <freetype/ftgxval.h> - - - /************************************************************************* - * - * @macro: - * FT_PFR_H - * - * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which accesses PFR-specific data. - * - */ -#define FT_PFR_H <freetype/ftpfr.h> - - - /************************************************************************* - * - * @macro: - * FT_STROKER_H - * - * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which provides functions to stroke outline paths. - */ -#define FT_STROKER_H <freetype/ftstroke.h> - - - /************************************************************************* - * - * @macro: - * FT_SYNTHESIS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs artificial obliquing and emboldening. - */ -#define FT_SYNTHESIS_H <freetype/ftsynth.h> - - - /************************************************************************* - * - * @macro: - * FT_XFREE86_H - * - * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which provides functions specific to the XFree86 and - * X.Org X11 servers. - */ -#define FT_XFREE86_H <freetype/ftxf86.h> - - - /************************************************************************* - * - * @macro: - * FT_TRIGONOMETRY_H - * - * @description: - * A macro used in #include statements to name the file containing the - * 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_UNPATENTED_HINTING_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_UNPATENTED_HINTING_H <freetype/ttunpat.h> - - - /************************************************************************* - * - * @macro: - * FT_INCREMENTAL_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_INCREMENTAL_H <freetype/ftincrem.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> - - - /************************************************************************* - * - * @macro: - * FT_ADVANCES_H - * - * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which returns individual and ranged glyph advances. - */ -#define FT_ADVANCES_H <freetype/ftadvanc.h> - - - /* */ - -#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h> - - - /* The internals of the cache sub-system are no longer exposed. We */ - /* default to FT_CACHE_H at the moment just in case, but we know of */ - /* no rogue client that uses them. */ - /* */ -#define FT_CACHE_MANAGER_H <freetype/ftcache.h> -#define FT_CACHE_INTERNAL_MRU_H <freetype/ftcache.h> -#define FT_CACHE_INTERNAL_MANAGER_H <freetype/ftcache.h> -#define FT_CACHE_INTERNAL_CACHE_H <freetype/ftcache.h> -#define FT_CACHE_INTERNAL_GLYPH_H <freetype/ftcache.h> -#define FT_CACHE_INTERNAL_IMAGE_H <freetype/ftcache.h> -#define FT_CACHE_INTERNAL_SBITS_H <freetype/ftcache.h> - - -#define FT_INCREMENTAL_H <freetype/ftincrem.h> - -#define FT_TRUETYPE_UNPATENTED_H <freetype/ttunpat.h> - - - /* - * Include internal headers definitions from <freetype/internal/...> - * only when building the library. - */ -#ifdef FT2_BUILD_LIBRARY -#define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> -#include FT_INTERNAL_INTERNAL_H -#endif /* FT2_BUILD_LIBRARY */ - - -#endif /* __FT2_BUILD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/config/ftmodule.h b/drivers/freetype/freetype/include/freetype/config/ftmodule.h deleted file mode 100644 index 76d271a74b..0000000000 --- a/drivers/freetype/freetype/include/freetype/config/ftmodule.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file registers the FreeType modules compiled into the library. - * - * If you use GNU make, this file IS NOT USED! Instead, it is created in - * the objects directory (normally `<topdir>/objs/') based on information - * from `<topdir>/modules.cfg'. - * - * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile - * FreeType without GNU make. - * - */ - -FT_USE_MODULE( FT_Module_Class, autofit_module_class ) -FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) -FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) -FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) -FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) -FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) -FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) -FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) -FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) -FT_USE_MODULE( FT_Module_Class, psaux_module_class ) -FT_USE_MODULE( FT_Module_Class, psnames_module_class ) -FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) -FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) -FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) - -/* EOF */ diff --git a/drivers/freetype/freetype/include/freetype/config/ftoption.h b/drivers/freetype/freetype/include/freetype/config/ftoption.h deleted file mode 100644 index b9d840b41f..0000000000 --- a/drivers/freetype/freetype/include/freetype/config/ftoption.h +++ /dev/null @@ -1,833 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoption.h */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2013 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 __FTOPTION_H__ -#define __FTOPTION_H__ - - -#include <ft2build.h> - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* This file contains the default configuration macro definitions for */ - /* a standard build of the FreeType library. There are three ways to */ - /* use this file to build project-specific versions of the library: */ - /* */ - /* - You can modify this file by hand, but this is not recommended in */ - /* cases where you would like to build several versions of the */ - /* library from a single source directory. */ - /* */ - /* - You can put a copy of this file in your build directory, more */ - /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ - /* is the name of a directory that is included _before_ the FreeType */ - /* include path during compilation. */ - /* */ - /* The default FreeType Makefiles and Jamfiles use the build */ - /* directory `builds/<system>' by default, but you can easily change */ - /* that for your own projects. */ - /* */ - /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ - /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ - /* locate this file during the build. For example, */ - /* */ - /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ - /* #include <freetype/config/ftheader.h> */ - /* */ - /* will use `$BUILD/myftoptions.h' instead of this file for macro */ - /* definitions. */ - /* */ - /* Note also that you can similarly pre-define the macro */ - /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ - /* that are statically linked to the library at compile time. By */ - /* default, this file is <freetype/config/ftmodule.h>. */ - /* */ - /* We highly recommend using the third method whenever possible. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* 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 wider than */ - /* the original size in case this macro isn't defined; however, 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 */ - /* by FreeType to speed up some computations. However, this will create */ - /* some problems when compiling the library in strict ANSI mode. */ - /* */ - /* For this reason, the use of 64-bit integers is normally disabled when */ - /* the __STDC__ macro is defined. You can however disable this by */ - /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ - /* */ - /* For most compilers, this will only create compilation warnings when */ - /* building the library. */ - /* */ - /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file `ftconfig.h' either statically or through the */ - /* `configure' script on supported platforms. */ - /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 - - - /*************************************************************************/ - /* */ - /* If this macro is defined, do not try to use an assembler version of */ - /* performance-critical functions (e.g. FT_MulFix). You should only do */ - /* that to verify that the assembler function works properly, or to */ - /* execute benchmark tests of the various implementations. */ -/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ - - - /*************************************************************************/ - /* */ - /* If this macro is defined, try to use an inlined assembler version of */ - /* the `FT_MulFix' function, which is a `hotspot' when loading and */ - /* hinting glyphs, and which should be executed as fast as possible. */ - /* */ - /* Note that if your compiler or CPU is not supported, this will default */ - /* to the standard and portable implementation found in `ftcalc.c'. */ - /* */ -#define FT_CONFIG_OPTION_INLINE_MULFIX - - - /*************************************************************************/ - /* */ - /* LZW-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `compress' program. This is mostly used to parse many of the PCF */ - /* files that come with various X11 distributions. The implementation */ - /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ - /* (see src/lzw/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -/* #define FT_CONFIG_OPTION_USE_LZW */ // -GODOT- - - - /*************************************************************************/ - /* */ - /* Gzip-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. See also */ - /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ - /* */ -/* #define FT_CONFIG_OPTION_USE_ZLIB */ // -GODOT- - - - /*************************************************************************/ - /* */ - /* ZLib library selection */ - /* */ - /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's `ftgzip' component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ - /* Unix or VMS where it generally is already available. */ - /* */ - /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ - /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ - /* _and_ ZLib without linking conflicts. */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ - - - /*************************************************************************/ - /* */ - /* Bzip2-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `bzip2' program. This is mostly used to parse many of the PCF */ - /* files that come with XFree86. The implementation uses `libbz2' to */ - /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ - /* Contrary to gzip, bzip2 currently is not included and need to use */ - /* the system available bzip2 implementation. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -/* #define FT_CONFIG_OPTION_USE_BZIP2 */ - - - /*************************************************************************/ - /* */ - /* Define to disable the use of file stream functions and types, FILE, */ - /* fopen() etc. Enables the use of smaller system libraries on embedded */ - /* systems that have multiple system libraries, some with or without */ - /* file stream support, in the cases where file stream support is not */ - /* necessary such as memory loading of font files. */ - /* */ -/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - - - /*************************************************************************/ - /* */ - /* PNG bitmap support. */ - /* */ - /* FreeType now handles loading color bitmap glyphs in the PNG format. */ - /* This requires help from the external libpng library. Uncompressed */ - /* color bitmaps do not need any external libraries and will be */ - /* supported regardless of this configuration. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -/* #define FT_CONFIG_OPTION_USE_PNG */ - - - /*************************************************************************/ - /* */ - /* DLL export compilation */ - /* */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special keyword in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ - /* */ - /* FT_EXPORT( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT and */ - /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ - /* will be later automatically defined as `extern return_type' to */ - /* allow normal compilation. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ - - - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `psnames' module. This */ - /* module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `psnames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ - /* */ - /* - The Type 1 driver will not be able to synthesize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ -#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthesize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ -#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /*************************************************************************/ - /* */ - /* Support for Mac fonts */ - /* */ - /* Define this macro if you want support for outline fonts in Mac */ - /* format (mac dfont, mac resource, macbinary containing a mac */ - /* resource) on non-Mac platforms. */ - /* */ - /* Note that the `FOND' resource isn't checked. */ - /* */ -#define FT_CONFIG_OPTION_MAC_FONTS - - - /*************************************************************************/ - /* */ - /* Guessing methods to access embedded resource forks */ - /* */ - /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ - /* GNU/Linux). */ - /* */ - /* Resource forks which include fonts data are stored sometimes in */ - /* locations which users or developers don't expected. In some cases, */ - /* resource forks start with some offset from the head of a file. In */ - /* other cases, the actual resource fork is stored in file different */ - /* from what the user specifies. If this option is activated, */ - /* FreeType tries to guess whether such offsets or different file */ - /* names must be used. */ - /* */ - /* Note that normal, direct access of resource forks is controlled via */ - /* the FT_CONFIG_OPTION_MAC_FONTS option. */ - /* */ -#ifdef FT_CONFIG_OPTION_MAC_FONTS -#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#endif - - - /*************************************************************************/ - /* */ - /* Allow the use of FT_Incremental_Interface to load typefaces that */ - /* contain no glyph data, but supply it via a callback function. */ - /* This is required by clients supporting document formats which */ - /* supply font data incrementally as the document is parsed, such */ - /* as the Ghostscript interpreter for the PostScript language. */ - /* */ -#define FT_CONFIG_OPTION_INCREMENTAL - - - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ - /* This must be greater than 4KByte if you use FreeType to rasterize */ - /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ - /* allocation of the render pool. */ - /* */ -#define FT_RENDER_POOL_SIZE 16384L - - - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 32 is the default. */ - /* */ -#define FT_MAX_MODULES 32 - - - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_DEBUG_LEVEL_ERROR */ -/* #define FT_DEBUG_LEVEL_TRACE */ - - - /*************************************************************************/ - /* */ - /* Autofitter debugging */ - /* */ - /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ - /* control the autofitter behaviour for debugging purposes with global */ - /* boolean variables (consequently, you should *never* enable this */ - /* while compiling in `release' mode): */ - /* */ - /* _af_debug_disable_horz_hints */ - /* _af_debug_disable_vert_hints */ - /* _af_debug_disable_blue_hints */ - /* */ - /* Additionally, the following functions provide dumps of various */ - /* internal autofit structures to stdout (using `printf'): */ - /* */ - /* af_glyph_hints_dump_points */ - /* af_glyph_hints_dump_segments */ - /* af_glyph_hints_dump_edges */ - /* */ - /* As an argument, they use another global variable: */ - /* */ - /* _af_debug_hints */ - /* */ - /* Please have a look at the `ftgrid' demo program to see how those */ - /* variables and macros should be used. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_DEBUG_AUTOFIT */ - - - /*************************************************************************/ - /* */ - /* Memory Debugging */ - /* */ - /* FreeType now comes with an integrated memory debugger that is */ - /* capable of detecting simple errors like memory leaks or double */ - /* deletes. To compile it within your build of the library, you */ - /* should define FT_DEBUG_MEMORY here. */ - /* */ - /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -/* #define FT_DEBUG_MEMORY */ - - - /*************************************************************************/ - /* */ - /* Module errors */ - /* */ - /* If this macro is set (which is _not_ the default), the higher byte */ - /* of an error code gives the module in which the error has occurred, */ - /* while the lower byte is the real error code. */ - /* */ - /* Setting this macro makes sense for debugging purposes only, since */ - /* it would break source compatibility of certain programs that use */ - /* FreeType 2. */ - /* */ - /* More details can be found in the files ftmoderr.h and fterrors.h. */ - /* */ -#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS - - - /*************************************************************************/ - /* */ - /* Position Independent Code */ - /* */ - /* If this macro is set (which is _not_ the default), FreeType2 will */ - /* avoid creating constants that require address fixups. Instead the */ - /* constants will be moved into a struct and additional intialization */ - /* code will be used. */ - /* */ - /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. */ - /* */ -/* #define FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ -#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ -#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftsnames.h'. */ - /* */ -#define TT_CONFIG_OPTION_SFNT_NAMES - - - /*************************************************************************/ - /* */ - /* TrueType CMap support */ - /* */ - /* Here you can fine-tune which TrueType CMap table format shall be */ - /* supported. */ -#define TT_CONFIG_CMAP_FORMAT_0 -#define TT_CONFIG_CMAP_FORMAT_2 -#define TT_CONFIG_CMAP_FORMAT_4 -#define TT_CONFIG_CMAP_FORMAT_6 -#define TT_CONFIG_CMAP_FORMAT_8 -#define TT_CONFIG_CMAP_FORMAT_10 -#define TT_CONFIG_CMAP_FORMAT_12 -#define TT_CONFIG_CMAP_FORMAT_13 -#define TT_CONFIG_CMAP_FORMAT_14 - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ - /* Do not #undef this macro here, since the build system might */ - /* define it for certain configurations only. */ - /* */ -#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ - /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ - /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /*************************************************************************/ - /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ - /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ - /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ - /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ - /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ - /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ - /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ - /* */ - /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ - /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ - /* bytecode interpreter with a huge switch statement, rather than a call */ - /* table. This results in smaller and faster code for a number of */ - /* architectures. */ - /* */ - /* Note however that on some compiler/processor combinations, undefining */ - /* this macro will generate faster, though larger, code. */ - /* */ -#define TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ - /* TrueType glyph loader to use Apple's definition of how to handle */ - /* component offsets in composite glyphs. */ - /* */ - /* Apple and MS disagree on the default behavior of component offsets */ - /* in composites. Apple says that they should be scaled by the scaling */ - /* factors in the transformation matrix (roughly, it's more complex) */ - /* while MS says they should not. OpenType defines two bits in the */ - /* composite flags array which can be used to disambiguate, but old */ - /* fonts will not have them. */ - /* */ - /* http://www.microsoft.com/typography/otspec/glyf.htm */ - /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ - /* */ -#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ - /* support for Apple's distortable font technology (fvar, gvar, cvar, */ - /* and avar tables). This has many similarities to Type 1 Multiple */ - /* Masters support. */ - /* */ -#define TT_CONFIG_OPTION_GX_VAR_SUPPORT - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ - /* an embedded `BDF ' table within SFNT-based bitmap formats. */ - /* */ -#define TT_CONFIG_OPTION_BDF - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ -#define T1_MAX_DICT_DEPTH 5 - - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 16 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ - /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 256 - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ -#undef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ -#undef T1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** C F F D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the cff driver module. */ - /* */ -/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ // -GODOT- - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ - /* support. */ - /* */ -#define AF_CONFIG_OPTION_CJK - - /*************************************************************************/ - /* */ - /* Compile autofit module with Indic script support. */ - /* */ -#define AF_CONFIG_OPTION_INDIC - - /*************************************************************************/ - /* */ - /* Compile autofit module with warp hinting. The idea of the warping */ - /* code is to slightly scale and shift a glyph within a single dimension */ - /* so that as much of its segments are aligned (more or less) on the */ - /* grid. To find out the optimal scaling and shifting value, various */ - /* parameter combinations are tried and scored. */ - /* */ - /* This experimental option is only active if the render mode is */ - /* FT_RENDER_MODE_LIGHT. */ - /* */ -/* #define AF_CONFIG_OPTION_USE_WARPER */ - - /* */ - - - /* - * This macro is obsolete. Support has been removed in FreeType - * version 2.5. - */ -/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ - - - /* - * This macro 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 -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER -#endif - -FT_END_HEADER - - -#endif /* __FTOPTION_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/config/ftstdlib.h b/drivers/freetype/freetype/include/freetype/config/ftstdlib.h deleted file mode 100644 index b940efc427..0000000000 --- a/drivers/freetype/freetype/include/freetype/config/ftstdlib.h +++ /dev/null @@ -1,174 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstdlib.h */ -/* */ -/* ANSI-specific library and header configuration file (specification */ -/* only). */ -/* */ -/* Copyright 2002-2007, 2009, 2011-2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to group all #includes to the ANSI C library that */ - /* FreeType normally requires. It also defines macros to rename the */ - /* standard functions within the FreeType source code. */ - /* */ - /* Load a file which defines __FTSTDLIB_H__ before this one to override */ - /* it. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTSTDLIB_H__ -#define __FTSTDLIB_H__ - - -#include <stddef.h> - -#define ft_ptrdiff_t ptrdiff_t - - - /**********************************************************************/ - /* */ - /* integer limits */ - /* */ - /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ - /* of `int' and `long' in bytes at compile-time. So far, this works */ - /* for all platforms the library has been tested on. */ - /* */ - /* Note that on the extremely rare platforms that do not provide */ - /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ - /* old Crays where `int' is 36 bits), we do not make any guarantee */ - /* about the correct behaviour of FT2 with all fonts. */ - /* */ - /* In these case, `ftconfig.h' will refuse to compile anyway with a */ - /* message like `couldn't find 32-bit type' or something similar. */ - /* */ - /**********************************************************************/ - - -#include <limits.h> - -#define FT_CHAR_BIT CHAR_BIT -#define FT_USHORT_MAX USHRT_MAX -#define FT_INT_MAX INT_MAX -#define FT_INT_MIN INT_MIN -#define FT_UINT_MAX UINT_MAX -#define FT_ULONG_MAX ULONG_MAX - - - /**********************************************************************/ - /* */ - /* character and string processing */ - /* */ - /**********************************************************************/ - - -#include <string.h> - -#define ft_memchr memchr -#define ft_memcmp memcmp -#define ft_memcpy memcpy -#define ft_memmove memmove -#define ft_memset memset -#define ft_strcat strcat -#define ft_strcmp strcmp -#define ft_strcpy strcpy -#define ft_strlen strlen -#define ft_strncmp strncmp -#define ft_strncpy strncpy -#define ft_strrchr strrchr -#define ft_strstr strstr - - - /**********************************************************************/ - /* */ - /* file handling */ - /* */ - /**********************************************************************/ - - -#include <stdio.h> - -#define FT_FILE FILE -#define ft_fclose fclose -#define ft_fopen fopen -#define ft_fread fread -#define ft_fseek fseek -#define ft_ftell ftell -#define ft_sprintf sprintf - - - /**********************************************************************/ - /* */ - /* sorting */ - /* */ - /**********************************************************************/ - - -#include <stdlib.h> - -#define ft_qsort qsort - - - /**********************************************************************/ - /* */ - /* memory allocation */ - /* */ - /**********************************************************************/ - - -#define ft_scalloc calloc -#define ft_sfree free -#define ft_smalloc malloc -#define ft_srealloc realloc - - - /**********************************************************************/ - /* */ - /* miscellaneous */ - /* */ - /**********************************************************************/ - - -#define ft_atol atol -#define ft_labs labs - - - /**********************************************************************/ - /* */ - /* execution control */ - /* */ - /**********************************************************************/ - - -#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_longjmp longjmp -#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */ - - - /* the following is only used for debugging purposes, i.e., if */ - /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ - -#include <stdarg.h> - - -#endif /* __FTSTDLIB_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/freetype.h b/drivers/freetype/freetype/include/freetype/freetype.h deleted file mode 100644 index fe46d22978..0000000000 --- a/drivers/freetype/freetype/include/freetype/freetype.h +++ /dev/null @@ -1,4012 +0,0 @@ -/***************************************************************************/ -/* */ -/* freetype.h */ -/* */ -/* FreeType high-level API and common types (specification only). */ -/* */ -/* Copyright 1996-2013 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 __FREETYPE_H__ -#define __FREETYPE_H__ - - -#ifndef FT_FREETYPE_H -#error "`ft2build.h' hasn't been included yet!" -#error "Please always use macros to include FreeType header files." -#error "Example:" -#error " #include <ft2build.h>" -#error " #include FT_FREETYPE_H" -#endif - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_TYPES_H -#include FT_ERRORS_H - - -FT_BEGIN_HEADER - - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* user_allocation */ - /* */ - /* <Title> */ - /* User allocation */ - /* */ - /* <Abstract> */ - /* How client applications should allocate FreeType data structures. */ - /* */ - /* <Description> */ - /* FreeType assumes that structures allocated by the user and passed */ - /* as arguments are zeroed out except for the actual data. In other */ - /* words, it is recommended to use `calloc' (or variants of it) */ - /* instead of `malloc' for allocation. */ - /* */ - /*************************************************************************/ - - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* B A S I C T Y P E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* base_interface */ - /* */ - /* <Title> */ - /* Base Interface */ - /* */ - /* <Abstract> */ - /* The FreeType~2 base font interface. */ - /* */ - /* <Description> */ - /* This section describes the public high-level API of FreeType~2. */ - /* */ - /* <Order> */ - /* FT_Library */ - /* FT_Face */ - /* FT_Size */ - /* FT_GlyphSlot */ - /* FT_CharMap */ - /* FT_Encoding */ - /* */ - /* FT_FaceRec */ - /* */ - /* FT_FACE_FLAG_SCALABLE */ - /* FT_FACE_FLAG_FIXED_SIZES */ - /* FT_FACE_FLAG_FIXED_WIDTH */ - /* FT_FACE_FLAG_HORIZONTAL */ - /* FT_FACE_FLAG_VERTICAL */ - /* FT_FACE_FLAG_SFNT */ - /* FT_FACE_FLAG_KERNING */ - /* FT_FACE_FLAG_MULTIPLE_MASTERS */ - /* FT_FACE_FLAG_GLYPH_NAMES */ - /* FT_FACE_FLAG_EXTERNAL_STREAM */ - /* FT_FACE_FLAG_FAST_GLYPHS */ - /* FT_FACE_FLAG_HINTER */ - /* */ - /* FT_STYLE_FLAG_BOLD */ - /* FT_STYLE_FLAG_ITALIC */ - /* */ - /* FT_SizeRec */ - /* FT_Size_Metrics */ - /* */ - /* FT_GlyphSlotRec */ - /* FT_Glyph_Metrics */ - /* FT_SubGlyph */ - /* */ - /* FT_Bitmap_Size */ - /* */ - /* FT_Init_FreeType */ - /* FT_Done_FreeType */ - /* */ - /* FT_New_Face */ - /* FT_Done_Face */ - /* FT_New_Memory_Face */ - /* FT_Open_Face */ - /* FT_Open_Args */ - /* FT_Parameter */ - /* FT_Attach_File */ - /* FT_Attach_Stream */ - /* */ - /* FT_Set_Char_Size */ - /* FT_Set_Pixel_Sizes */ - /* FT_Request_Size */ - /* FT_Select_Size */ - /* FT_Size_Request_Type */ - /* FT_Size_Request */ - /* FT_Set_Transform */ - /* FT_Load_Glyph */ - /* FT_Get_Char_Index */ - /* FT_Get_Name_Index */ - /* FT_Load_Char */ - /* */ - /* FT_OPEN_MEMORY */ - /* FT_OPEN_STREAM */ - /* FT_OPEN_PATHNAME */ - /* FT_OPEN_DRIVER */ - /* FT_OPEN_PARAMS */ - /* */ - /* FT_LOAD_DEFAULT */ - /* FT_LOAD_RENDER */ - /* FT_LOAD_MONOCHROME */ - /* FT_LOAD_LINEAR_DESIGN */ - /* FT_LOAD_NO_SCALE */ - /* FT_LOAD_NO_HINTING */ - /* FT_LOAD_NO_BITMAP */ - /* FT_LOAD_CROP_BITMAP */ - /* */ - /* FT_LOAD_VERTICAL_LAYOUT */ - /* FT_LOAD_IGNORE_TRANSFORM */ - /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ - /* FT_LOAD_FORCE_AUTOHINT */ - /* FT_LOAD_NO_RECURSE */ - /* FT_LOAD_PEDANTIC */ - /* */ - /* FT_LOAD_TARGET_NORMAL */ - /* FT_LOAD_TARGET_LIGHT */ - /* FT_LOAD_TARGET_MONO */ - /* FT_LOAD_TARGET_LCD */ - /* FT_LOAD_TARGET_LCD_V */ - /* */ - /* FT_Render_Glyph */ - /* FT_Render_Mode */ - /* FT_Get_Kerning */ - /* FT_Kerning_Mode */ - /* FT_Get_Track_Kerning */ - /* FT_Get_Glyph_Name */ - /* FT_Get_Postscript_Name */ - /* */ - /* FT_CharMapRec */ - /* FT_Select_Charmap */ - /* FT_Set_Charmap */ - /* FT_Get_Charmap_Index */ - /* */ - /* FT_FSTYPE_INSTALLABLE_EMBEDDING */ - /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING */ - /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING */ - /* FT_FSTYPE_EDITABLE_EMBEDDING */ - /* FT_FSTYPE_NO_SUBSETTING */ - /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY */ - /* */ - /* FT_Get_FSType_Flags */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Glyph_Metrics */ - /* */ - /* <Description> */ - /* A structure used to model the metrics of a single glyph. The */ - /* values are expressed in 26.6 fractional pixel format; if the flag */ - /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ - /* are expressed in font units instead. */ - /* */ - /* <Fields> */ - /* width :: */ - /* The glyph's width. */ - /* */ - /* height :: */ - /* The glyph's height. */ - /* */ - /* horiBearingX :: */ - /* Left side bearing for horizontal layout. */ - /* */ - /* horiBearingY :: */ - /* Top side bearing for horizontal layout. */ - /* */ - /* horiAdvance :: */ - /* Advance width for horizontal layout. */ - /* */ - /* vertBearingX :: */ - /* Left side bearing for vertical layout. */ - /* */ - /* vertBearingY :: */ - /* Top side bearing for vertical layout. Larger positive values */ - /* mean further below the vertical glyph origin. */ - /* */ - /* vertAdvance :: */ - /* Advance height for vertical layout. Positive values mean the */ - /* glyph has a positive advance downward. */ - /* */ - /* <Note> */ - /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ - /* dimensions of the hinted glyph (in case hinting is applicable). */ - /* */ - /* Stroking a glyph with an outside border does not increase */ - /* `horiAdvance' or `vertAdvance'; you have to manually adjust these */ - /* values to account for the added width and height. */ - /* */ - typedef struct FT_Glyph_Metrics_ - { - FT_Pos width; - FT_Pos height; - - FT_Pos horiBearingX; - FT_Pos horiBearingY; - FT_Pos horiAdvance; - - FT_Pos vertBearingX; - FT_Pos vertBearingY; - FT_Pos vertAdvance; - - } FT_Glyph_Metrics; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Bitmap_Size */ - /* */ - /* <Description> */ - /* This structure models the metrics of a bitmap strike (i.e., a set */ - /* of glyphs for a given point size and resolution) in a bitmap font. */ - /* It is used for the `available_sizes' field of @FT_Face. */ - /* */ - /* <Fields> */ - /* height :: The vertical distance, in pixels, between two */ - /* consecutive baselines. It is always positive. */ - /* */ - /* width :: The average width, in pixels, of all glyphs in the */ - /* strike. */ - /* */ - /* size :: The nominal size of the strike in 26.6 fractional */ - /* points. This field is not very useful. */ - /* */ - /* x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional */ - /* pixels. */ - /* */ - /* y_ppem :: The vertical ppem (nominal height) in 26.6 fractional */ - /* pixels. */ - /* */ - /* <Note> */ - /* Windows FNT: */ - /* The nominal size given in a FNT font is not reliable. Thus when */ - /* the driver finds it incorrect, it sets `size' to some calculated */ - /* values and sets `x_ppem' and `y_ppem' to the pixel width and */ - /* height given in the font, respectively. */ - /* */ - /* TrueType embedded bitmaps: */ - /* `size', `width', and `height' values are not contained in the */ - /* bitmap strike itself. They are computed from the global font */ - /* parameters. */ - /* */ - typedef struct FT_Bitmap_Size_ - { - FT_Short height; - FT_Short width; - - FT_Pos size; - - FT_Pos x_ppem; - FT_Pos y_ppem; - - } FT_Bitmap_Size; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* O B J E C T C L A S S E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Library */ - /* */ - /* <Description> */ - /* A handle to a FreeType library instance. Each `library' is */ - /* completely independent from the others; it is the `root' of a set */ - /* of objects like fonts, faces, sizes, etc. */ - /* */ - /* It also embeds a memory manager (see @FT_Memory), as well as a */ - /* scan-line converter object (see @FT_Raster). */ - /* */ - /* In multi-threaded applications, make sure that the same FT_Library */ - /* object or any of its children doesn't get accessed in parallel. */ - /* */ - /* <Note> */ - /* Library objects are normally created by @FT_Init_FreeType, and */ - /* destroyed with @FT_Done_FreeType. If you need reference-counting */ - /* (cf. @FT_Reference_Library), use @FT_New_Library and */ - /* @FT_Done_Library. */ - /* */ - typedef struct FT_LibraryRec_ *FT_Library; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Module */ - /* */ - /* <Description> */ - /* A handle to a given FreeType module object. Each module can be a */ - /* font driver, a renderer, or anything else that provides services */ - /* to the formers. */ - /* */ - typedef struct FT_ModuleRec_* FT_Module; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Driver */ - /* */ - /* <Description> */ - /* A handle to a given FreeType font driver object. Each font driver */ - /* is a special module capable of creating faces from font files. */ - /* */ - typedef struct FT_DriverRec_* FT_Driver; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Renderer */ - /* */ - /* <Description> */ - /* A handle to a given FreeType renderer. A renderer is a special */ - /* module in charge of converting a glyph image to a bitmap, when */ - /* necessary. Each renderer supports a given glyph image format, and */ - /* one or more target surface depths. */ - /* */ - typedef struct FT_RendererRec_* FT_Renderer; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Face */ - /* */ - /* <Description> */ - /* A handle to a given typographic face object. A face object models */ - /* a given typeface, in a given style. */ - /* */ - /* <Note> */ - /* Each face object also owns a single @FT_GlyphSlot object, as well */ - /* as one or more @FT_Size objects. */ - /* */ - /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ - /* a given filepathname or a custom input stream. */ - /* */ - /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ - /* */ - /* <Also> */ - /* See @FT_FaceRec for the publicly accessible fields of a given face */ - /* object. */ - /* */ - typedef struct FT_FaceRec_* FT_Face; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Size */ - /* */ - /* <Description> */ - /* A handle to an object used to model a face scaled to a given */ - /* character size. */ - /* */ - /* <Note> */ - /* Each @FT_Face has an _active_ @FT_Size object that is used by */ - /* functions like @FT_Load_Glyph to determine the scaling */ - /* transformation which is used to load and hint glyphs and metrics. */ - /* */ - /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ - /* @FT_Request_Size or even @FT_Select_Size to change the content */ - /* (i.e., the scaling values) of the active @FT_Size. */ - /* */ - /* You can use @FT_New_Size to create additional size objects for a */ - /* given @FT_Face, but they won't be used by other functions until */ - /* you activate it through @FT_Activate_Size. Only one size can be */ - /* activated at any given time per face. */ - /* */ - /* <Also> */ - /* See @FT_SizeRec for the publicly accessible fields of a given size */ - /* object. */ - /* */ - typedef struct FT_SizeRec_* FT_Size; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to a given `glyph slot'. A slot is a container where it */ - /* is possible to load any of the glyphs contained in its parent */ - /* face. */ - /* */ - /* In other words, each time you call @FT_Load_Glyph or */ - /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ - /* i.e., the glyph's metrics, its image (bitmap or outline), and */ - /* other control information. */ - /* */ - /* <Also> */ - /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ - /* */ - typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_CharMap */ - /* */ - /* <Description> */ - /* A handle to a given character map. A charmap is used to translate */ - /* character codes in a given encoding into glyph indexes for its */ - /* parent's face. Some font formats may provide several charmaps per */ - /* font. */ - /* */ - /* Each face object owns zero or more charmaps, but only one of them */ - /* can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char. */ - /* */ - /* The list of available charmaps in a face is available through the */ - /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ - /* */ - /* The currently active charmap is available as `face->charmap'. */ - /* You should call @FT_Set_Charmap to change it. */ - /* */ - /* <Note> */ - /* When a new face is created (either through @FT_New_Face or */ - /* @FT_Open_Face), the library looks for a Unicode charmap within */ - /* the list and automatically activates it. */ - /* */ - /* <Also> */ - /* See @FT_CharMapRec for the publicly accessible fields of a given */ - /* character map. */ - /* */ - typedef struct FT_CharMapRec_* FT_CharMap; - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_ENC_TAG */ - /* */ - /* <Description> */ - /* This macro converts four-letter tags into an unsigned long. It is */ - /* used to define `encoding' identifiers (see @FT_Encoding). */ - /* */ - /* <Note> */ - /* Since many 16-bit compilers don't like 32-bit enumerations, you */ - /* should redefine this macro in case of problems to something like */ - /* this: */ - /* */ - /* { */ - /* #define FT_ENC_TAG( value, a, b, c, d ) value */ - /* } */ - /* */ - /* to get a simple enumeration without assigning special numbers. */ - /* */ - -#ifndef FT_ENC_TAG -#define FT_ENC_TAG( value, a, b, c, d ) \ - value = ( ( (FT_UInt32)(a) << 24 ) | \ - ( (FT_UInt32)(b) << 16 ) | \ - ( (FT_UInt32)(c) << 8 ) | \ - (FT_UInt32)(d) ) - -#endif /* FT_ENC_TAG */ - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Encoding */ - /* */ - /* <Description> */ - /* An enumeration used to specify character sets supported by */ - /* charmaps. Used in the @FT_Select_Charmap API function. */ - /* */ - /* <Note> */ - /* Despite the name, this enumeration lists specific character */ - /* repertories (i.e., charsets), and not text encoding methods (e.g., */ - /* UTF-8, UTF-16, etc.). */ - /* */ - /* Other encodings might be defined in the future. */ - /* */ - /* <Values> */ - /* FT_ENCODING_NONE :: */ - /* The encoding value~0 is reserved. */ - /* */ - /* FT_ENCODING_UNICODE :: */ - /* Corresponds to the Unicode character set. This value covers */ - /* all versions of the Unicode repertoire, including ASCII and */ - /* Latin-1. Most fonts include a Unicode charmap, but not all */ - /* of them. */ - /* */ - /* For example, if you want to access Unicode value U+1F028 (and */ - /* the font contains it), use value 0x1F028 as the input value for */ - /* @FT_Get_Char_Index. */ - /* */ - /* FT_ENCODING_MS_SYMBOL :: */ - /* Corresponds to the Microsoft Symbol encoding, used to encode */ - /* mathematical symbols in the 32..255 character code range. For */ - /* more information, see `http://www.ceviz.net/symbol.htm'. */ - /* */ - /* FT_ENCODING_SJIS :: */ - /* Corresponds to Japanese SJIS encoding. More info at */ - /* at `http://langsupport.japanreference.com/encoding.shtml'. */ - /* See note on multi-byte encodings below. */ - /* */ - /* FT_ENCODING_GB2312 :: */ - /* Corresponds to an encoding system for Simplified Chinese as used */ - /* used in mainland China. */ - /* */ - /* FT_ENCODING_BIG5 :: */ - /* Corresponds to an encoding system for Traditional Chinese as */ - /* used in Taiwan and Hong Kong. */ - /* */ - /* FT_ENCODING_WANSUNG :: */ - /* Corresponds to the Korean encoding system known as Wansung. */ - /* For more information see */ - /* `http://www.microsoft.com/typography/unicode/949.txt'. */ - /* */ - /* FT_ENCODING_JOHAB :: */ - /* The Korean standard character set (KS~C 5601-1992), which */ - /* corresponds to MS Windows code page 1361. This character set */ - /* includes all possible Hangeul character combinations. */ - /* */ - /* FT_ENCODING_ADOBE_LATIN_1 :: */ - /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ - /* PostScript font. It is limited to 256 character codes. */ - /* */ - /* FT_ENCODING_ADOBE_STANDARD :: */ - /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ - /* */ - /* FT_ENCODING_ADOBE_EXPERT :: */ - /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ - /* */ - /* FT_ENCODING_ADOBE_CUSTOM :: */ - /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ - /* OpenType/CFF fonts. It is limited to 256 character codes. */ - /* */ - /* FT_ENCODING_APPLE_ROMAN :: */ - /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ - /* and OpenType fonts contain a charmap for this encoding, since */ - /* older versions of Mac OS are able to use it. */ - /* */ - /* FT_ENCODING_OLD_LATIN_2 :: */ - /* This value is deprecated and was never used nor reported by */ - /* FreeType. Don't use or test for it. */ - /* */ - /* FT_ENCODING_MS_SJIS :: */ - /* Same as FT_ENCODING_SJIS. Deprecated. */ - /* */ - /* FT_ENCODING_MS_GB2312 :: */ - /* Same as FT_ENCODING_GB2312. Deprecated. */ - /* */ - /* FT_ENCODING_MS_BIG5 :: */ - /* Same as FT_ENCODING_BIG5. Deprecated. */ - /* */ - /* FT_ENCODING_MS_WANSUNG :: */ - /* Same as FT_ENCODING_WANSUNG. Deprecated. */ - /* */ - /* FT_ENCODING_MS_JOHAB :: */ - /* Same as FT_ENCODING_JOHAB. Deprecated. */ - /* */ - /* <Note> */ - /* By default, FreeType automatically synthesizes a Unicode charmap */ - /* for PostScript fonts, using their glyph names dictionaries. */ - /* However, it also reports the encodings defined explicitly in the */ - /* font file, for the cases when they are needed, with the Adobe */ - /* values as well. */ - /* */ - /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ - /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ - /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ - /* which encoding is really present. If, for example, the */ - /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ - /* the font is encoded in KOI8-R. */ - /* */ - /* FT_ENCODING_NONE is always set (with a single exception) by the */ - /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ - /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ - /* which encoding is really present. For example, */ - /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ - /* Russian). */ - /* */ - /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ - /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ - /* FT_ENCODING_APPLE_ROMAN). */ - /* */ - /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ - /* @FT_Get_CMap_Language_ID to query the Mac language ID which may */ - /* be needed to be able to distinguish Apple encoding variants. See */ - /* */ - /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ - /* */ - /* to get an idea how to do that. Basically, if the language ID */ - /* is~0, don't use it, otherwise subtract 1 from the language ID. */ - /* Then examine `encoding_id'. If, for example, `encoding_id' is */ - /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ - /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ - /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ - /* variant the Arabic encoding. */ - /* */ - typedef enum FT_Encoding_ - { - FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), - - FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), - FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), - - FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), - FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ), - FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), - FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), - FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), - - /* for backwards compatibility */ - FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, - FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312, - FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, - FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, - FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, - - FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), - FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), - FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ), - FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ), - - FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ), - - FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' ) - - } FT_Encoding; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_encoding_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated; use the corresponding @FT_Encoding */ - /* values instead. */ - /* */ -#define ft_encoding_none FT_ENCODING_NONE -#define ft_encoding_unicode FT_ENCODING_UNICODE -#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL -#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 -#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 -#define ft_encoding_sjis FT_ENCODING_SJIS -#define ft_encoding_gb2312 FT_ENCODING_GB2312 -#define ft_encoding_big5 FT_ENCODING_BIG5 -#define ft_encoding_wansung FT_ENCODING_WANSUNG -#define ft_encoding_johab FT_ENCODING_JOHAB - -#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD -#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT -#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM -#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_CharMapRec */ - /* */ - /* <Description> */ - /* The base charmap structure. */ - /* */ - /* <Fields> */ - /* face :: A handle to the parent face object. */ - /* */ - /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ - /* this with @FT_Select_Charmap. */ - /* */ - /* platform_id :: An ID number describing the platform for the */ - /* following encoding ID. This comes directly from */ - /* the TrueType specification and should be emulated */ - /* for other formats. */ - /* */ - /* encoding_id :: A platform specific encoding number. This also */ - /* comes from the TrueType specification and should be */ - /* emulated similarly. */ - /* */ - typedef struct FT_CharMapRec_ - { - FT_Face face; - FT_Encoding encoding; - FT_UShort platform_id; - FT_UShort encoding_id; - - } FT_CharMapRec; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* B A S E O B J E C T C L A S S E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Face_Internal */ - /* */ - /* <Description> */ - /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ - /* model private data of a given @FT_Face object. */ - /* */ - /* This structure might change between releases of FreeType~2 and is */ - /* not generally available to client applications. */ - /* */ - typedef struct FT_Face_InternalRec_* FT_Face_Internal; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_FaceRec */ - /* */ - /* <Description> */ - /* FreeType root face class structure. A face object models a */ - /* typeface in a font file. */ - /* */ - /* <Fields> */ - /* num_faces :: The number of faces in the font file. Some */ - /* font formats can have multiple faces in */ - /* a font file. */ - /* */ - /* face_index :: The index of the face in the font file. It */ - /* is set to~0 if there is only one face in */ - /* the font file. */ - /* */ - /* face_flags :: A set of bit flags that give important */ - /* information about the face; see */ - /* @FT_FACE_FLAG_XXX for the details. */ - /* */ - /* style_flags :: A set of bit flags indicating the style of */ - /* the face; see @FT_STYLE_FLAG_XXX for the */ - /* details. */ - /* */ - /* num_glyphs :: The number of glyphs in the face. If the */ - /* face is scalable and has sbits (see */ - /* `num_fixed_sizes'), it is set to the number */ - /* of outline glyphs. */ - /* */ - /* For CID-keyed fonts, this value gives the */ - /* highest CID used in the font. */ - /* */ - /* family_name :: The face's family name. This is an ASCII */ - /* string, usually in English, which describes */ - /* the typeface's family (like `Times New */ - /* Roman', `Bodoni', `Garamond', etc). This */ - /* is a least common denominator used to list */ - /* fonts. Some formats (TrueType & OpenType) */ - /* provide localized and Unicode versions of */ - /* this string. Applications should use the */ - /* format specific interface to access them. */ - /* Can be NULL (e.g., in fonts embedded in a */ - /* PDF file). */ - /* */ - /* style_name :: The face's style name. This is an ASCII */ - /* string, usually in English, which describes */ - /* the typeface's style (like `Italic', */ - /* `Bold', `Condensed', etc). Not all font */ - /* formats provide a style name, so this field */ - /* is optional, and can be set to NULL. As */ - /* for `family_name', some formats provide */ - /* localized and Unicode versions of this */ - /* string. Applications should use the format */ - /* specific interface to access them. */ - /* */ - /* num_fixed_sizes :: The number of bitmap strikes in the face. */ - /* Even if the face is scalable, there might */ - /* still be bitmap strikes, which are called */ - /* `sbits' in that case. */ - /* */ - /* available_sizes :: An array of @FT_Bitmap_Size for all bitmap */ - /* strikes in the face. It is set to NULL if */ - /* there is no bitmap strike. */ - /* */ - /* num_charmaps :: The number of charmaps in the face. */ - /* */ - /* charmaps :: An array of the charmaps of the face. */ - /* */ - /* generic :: A field reserved for client uses. See the */ - /* @FT_Generic type description. */ - /* */ - /* bbox :: The font bounding box. Coordinates are */ - /* expressed in font units (see */ - /* `units_per_EM'). The box is large enough */ - /* to contain any glyph from the font. Thus, */ - /* `bbox.yMax' can be seen as the `maximum */ - /* ascender', and `bbox.yMin' as the `minimum */ - /* descender'. Only relevant for scalable */ - /* formats. */ - /* */ - /* Note that the bounding box might be off by */ - /* (at least) one pixel for hinted fonts. See */ - /* @FT_Size_Metrics for further discussion. */ - /* */ - /* units_per_EM :: The number of font units per EM square for */ - /* this face. This is typically 2048 for */ - /* TrueType fonts, and 1000 for Type~1 fonts. */ - /* Only relevant for scalable formats. */ - /* */ - /* ascender :: The typographic ascender of the face, */ - /* expressed in font units. For font formats */ - /* not having this information, it is set to */ - /* `bbox.yMax'. Only relevant for scalable */ - /* formats. */ - /* */ - /* descender :: The typographic descender of the face, */ - /* expressed in font units. For font formats */ - /* not having this information, it is set to */ - /* `bbox.yMin'. Note that this field is */ - /* usually negative. Only relevant for */ - /* scalable formats. */ - /* */ - /* height :: This value is the vertical distance */ - /* between two consecutive baselines, */ - /* expressed in font units. It is always */ - /* positive. Only relevant for scalable */ - /* formats. */ - /* */ - /* If you want the global glyph height, use */ - /* `ascender - descender'. */ - /* */ - /* max_advance_width :: The maximum advance width, in font units, */ - /* for all glyphs in this face. This can be */ - /* used to make word wrapping computations */ - /* faster. Only relevant for scalable */ - /* formats. */ - /* */ - /* max_advance_height :: The maximum advance height, in font units, */ - /* for all glyphs in this face. This is only */ - /* relevant for vertical layouts, and is set */ - /* to `height' for fonts that do not provide */ - /* vertical metrics. Only relevant for */ - /* scalable formats. */ - /* */ - /* underline_position :: The position, in font units, of the */ - /* underline line for this face. It is the */ - /* center of the underlining stem. Only */ - /* relevant for scalable formats. */ - /* */ - /* underline_thickness :: The thickness, in font units, of the */ - /* underline for this face. Only relevant for */ - /* scalable formats. */ - /* */ - /* glyph :: The face's associated glyph slot(s). */ - /* */ - /* size :: The current active size for this face. */ - /* */ - /* charmap :: The current active charmap for this face. */ - /* */ - /* <Note> */ - /* Fields may be changed after a call to @FT_Attach_File or */ - /* @FT_Attach_Stream. */ - /* */ - typedef struct FT_FaceRec_ - { - FT_Long num_faces; - FT_Long face_index; - - FT_Long face_flags; - FT_Long style_flags; - - FT_Long num_glyphs; - - FT_String* family_name; - FT_String* style_name; - - FT_Int num_fixed_sizes; - FT_Bitmap_Size* available_sizes; - - FT_Int num_charmaps; - FT_CharMap* charmaps; - - FT_Generic generic; - - /*# 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; - FT_Short ascender; - FT_Short descender; - FT_Short height; - - FT_Short max_advance_width; - FT_Short max_advance_height; - - FT_Short underline_position; - FT_Short underline_thickness; - - FT_GlyphSlot glyph; - FT_Size size; - FT_CharMap charmap; - - /*@private begin */ - - FT_Driver driver; - FT_Memory memory; - FT_Stream stream; - - FT_ListRec sizes_list; - - FT_Generic autohint; /* face-specific auto-hinter data */ - void* extensions; /* unused */ - - FT_Face_Internal internal; - - /*@private end */ - - } FT_FaceRec; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_FACE_FLAG_XXX */ - /* */ - /* <Description> */ - /* A list of bit flags used in the `face_flags' field of the */ - /* @FT_FaceRec structure. They inform client applications of */ - /* properties of the corresponding face. */ - /* */ - /* <Values> */ - /* FT_FACE_FLAG_SCALABLE :: */ - /* Indicates that the face contains outline glyphs. This doesn't */ - /* prevent bitmap strikes, i.e., a face can have both this and */ - /* and @FT_FACE_FLAG_FIXED_SIZES set. */ - /* */ - /* FT_FACE_FLAG_FIXED_SIZES :: */ - /* Indicates that the face contains bitmap strikes. See also the */ - /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ - /* */ - /* FT_FACE_FLAG_FIXED_WIDTH :: */ - /* Indicates that the face contains fixed-width characters (like */ - /* Courier, Lucido, MonoType, etc.). */ - /* */ - /* FT_FACE_FLAG_SFNT :: */ - /* Indicates that the face uses the `sfnt' storage scheme. For */ - /* now, this means TrueType and OpenType. */ - /* */ - /* FT_FACE_FLAG_HORIZONTAL :: */ - /* Indicates that the face contains horizontal glyph metrics. This */ - /* should be set for all common formats. */ - /* */ - /* FT_FACE_FLAG_VERTICAL :: */ - /* Indicates that the face contains vertical glyph metrics. This */ - /* is only available in some formats, not all of them. */ - /* */ - /* FT_FACE_FLAG_KERNING :: */ - /* Indicates that the face contains kerning information. If set, */ - /* the kerning distance can be retrieved through the function */ - /* @FT_Get_Kerning. Otherwise the function always return the */ - /* vector (0,0). Note that FreeType doesn't handle kerning data */ - /* from the `GPOS' table (as present in some OpenType fonts). */ - /* */ - /* FT_FACE_FLAG_FAST_GLYPHS :: */ - /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ - /* */ - /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ - /* Indicates that the font contains multiple masters and is capable */ - /* of interpolating between them. See the multiple-masters */ - /* specific API for details. */ - /* */ - /* FT_FACE_FLAG_GLYPH_NAMES :: */ - /* Indicates that the font contains glyph names that can be */ - /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ - /* fonts contain broken glyph name tables. Use the function */ - /* @FT_Has_PS_Glyph_Names when needed. */ - /* */ - /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ - /* Used internally by FreeType to indicate that a face's stream was */ - /* provided by the client application and should not be destroyed */ - /* when @FT_Done_Face is called. Don't read or test this flag. */ - /* */ - /* FT_FACE_FLAG_HINTER :: */ - /* Set if the font driver has a hinting machine of its own. For */ - /* example, with TrueType fonts, it makes sense to use data from */ - /* the SFNT `gasp' table only if the native TrueType hinting engine */ - /* (with the bytecode interpreter) is available and active. */ - /* */ - /* FT_FACE_FLAG_CID_KEYED :: */ - /* Set if the font is CID-keyed. In that case, the font is not */ - /* accessed by glyph indices but by CID values. For subsetted */ - /* CID-keyed fonts this has the consequence that not all index */ - /* values are a valid argument to FT_Load_Glyph. Only the CID */ - /* values for which corresponding glyphs in the subsetted font */ - /* exist make FT_Load_Glyph return successfully; in all other cases */ - /* you get an `FT_Err_Invalid_Argument' error. */ - /* */ - /* Note that CID-keyed fonts which are in an SFNT wrapper don't */ - /* have this flag set since the glyphs are accessed in the normal */ - /* way (using contiguous indices); the `CID-ness' isn't visible to */ - /* the application. */ - /* */ - /* FT_FACE_FLAG_TRICKY :: */ - /* Set if the font is `tricky', this is, it always needs the */ - /* font format's native hinting engine to get a reasonable result. */ - /* A typical example is the Chinese font `mingli.ttf' which uses */ - /* TrueType bytecode instructions to move and scale all of its */ - /* subglyphs. */ - /* */ - /* It is not possible to autohint such fonts using */ - /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ - /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */ - /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ - /* probably never want this except for demonstration purposes. */ - /* */ - /* Currently, there are about a dozen TrueType fonts in the list of */ - /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ - /* */ -#define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) -#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) -#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) -#define FT_FACE_FLAG_SFNT ( 1L << 3 ) -#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 ) -#define FT_FACE_FLAG_VERTICAL ( 1L << 5 ) -#define FT_FACE_FLAG_KERNING ( 1L << 6 ) -#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 ) -#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 ) -#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) -#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) -#define FT_FACE_FLAG_HINTER ( 1L << 11 ) -#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) -#define FT_FACE_FLAG_TRICKY ( 1L << 13 ) - - - /************************************************************************* - * - * @macro: - * FT_HAS_HORIZONTAL( face ) - * - * @description: - * A macro that returns true whenever a face object contains - * horizontal metrics (this is true for all font formats though). - * - * @also: - * @FT_HAS_VERTICAL can be used to check for vertical metrics. - * - */ -#define FT_HAS_HORIZONTAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) - - - /************************************************************************* - * - * @macro: - * FT_HAS_VERTICAL( face ) - * - * @description: - * A macro that returns true whenever a face object contains real - * vertical metrics (and not only synthesized ones). - * - */ -#define FT_HAS_VERTICAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_VERTICAL ) - - - /************************************************************************* - * - * @macro: - * FT_HAS_KERNING( face ) - * - * @description: - * A macro that returns true whenever a face object contains kerning - * data that can be accessed with @FT_Get_Kerning. - * - */ -#define FT_HAS_KERNING( face ) \ - ( face->face_flags & FT_FACE_FLAG_KERNING ) - - - /************************************************************************* - * - * @macro: - * FT_IS_SCALABLE( face ) - * - * @description: - * A macro that returns true whenever a face object contains a scalable - * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, - * and PFR font formats. - * - */ -#define FT_IS_SCALABLE( face ) \ - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) - - - /************************************************************************* - * - * @macro: - * FT_IS_SFNT( face ) - * - * @description: - * A macro that returns true whenever a face object contains a font - * whose format is based on the SFNT storage scheme. This usually - * means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded - * bitmap fonts. - * - * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and - * @FT_TRUETYPE_TABLES_H are available. - * - */ -#define FT_IS_SFNT( face ) \ - ( face->face_flags & FT_FACE_FLAG_SFNT ) - - - /************************************************************************* - * - * @macro: - * FT_IS_FIXED_WIDTH( face ) - * - * @description: - * A macro that returns true whenever a face object contains a font face - * that contains fixed-width (or `monospace', `fixed-pitch', etc.) - * glyphs. - * - */ -#define FT_IS_FIXED_WIDTH( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) - - - /************************************************************************* - * - * @macro: - * FT_HAS_FIXED_SIZES( face ) - * - * @description: - * A macro that returns true whenever a face object contains some - * embedded bitmaps. See the `available_sizes' field of the - * @FT_FaceRec structure. - * - */ -#define FT_HAS_FIXED_SIZES( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) - - - /************************************************************************* - * - * @macro: - * FT_HAS_FAST_GLYPHS( face ) - * - * @description: - * Deprecated. - * - */ -#define FT_HAS_FAST_GLYPHS( face ) 0 - - - /************************************************************************* - * - * @macro: - * FT_HAS_GLYPH_NAMES( face ) - * - * @description: - * A macro that returns true whenever a face object contains some glyph - * names that can be accessed through @FT_Get_Glyph_Name. - * - */ -#define FT_HAS_GLYPH_NAMES( face ) \ - ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) - - - /************************************************************************* - * - * @macro: - * FT_HAS_MULTIPLE_MASTERS( face ) - * - * @description: - * A macro that returns true whenever a face object contains some - * multiple masters. The functions provided by @FT_MULTIPLE_MASTERS_H - * are then available to choose the exact design you want. - * - */ -#define FT_HAS_MULTIPLE_MASTERS( face ) \ - ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) - - - /************************************************************************* - * - * @macro: - * FT_IS_CID_KEYED( face ) - * - * @description: - * A macro that returns true whenever a face object contains a CID-keyed - * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more - * details. - * - * If this macro is true, all functions defined in @FT_CID_H are - * available. - * - */ -#define FT_IS_CID_KEYED( face ) \ - ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) - - - /************************************************************************* - * - * @macro: - * FT_IS_TRICKY( face ) - * - * @description: - * A macro that returns true whenever a face represents a `tricky' font. - * See the discussion of @FT_FACE_FLAG_TRICKY for more details. - * - */ -#define FT_IS_TRICKY( face ) \ - ( face->face_flags & FT_FACE_FLAG_TRICKY ) - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* FT_STYLE_FLAG_XXX */ - /* */ - /* <Description> */ - /* A list of bit-flags used to indicate the style of a given face. */ - /* These are used in the `style_flags' field of @FT_FaceRec. */ - /* */ - /* <Values> */ - /* FT_STYLE_FLAG_ITALIC :: */ - /* Indicates that a given face style is italic or oblique. */ - /* */ - /* FT_STYLE_FLAG_BOLD :: */ - /* Indicates that a given face is bold. */ - /* */ - /* <Note> */ - /* The style information as provided by FreeType is very basic. More */ - /* details are beyond the scope and should be done on a higher level */ - /* (for example, by analyzing various fields of the `OS/2' table in */ - /* SFNT based fonts). */ - /* */ -#define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) -#define FT_STYLE_FLAG_BOLD ( 1 << 1 ) - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Size_Internal */ - /* */ - /* <Description> */ - /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ - /* model private data of a given @FT_Size object. */ - /* */ - typedef struct FT_Size_InternalRec_* FT_Size_Internal; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Size_Metrics */ - /* */ - /* <Description> */ - /* The size metrics structure gives the metrics of a size object. */ - /* */ - /* <Fields> */ - /* x_ppem :: The width of the scaled EM square in pixels, hence */ - /* the term `ppem' (pixels per EM). It is also */ - /* referred to as `nominal width'. */ - /* */ - /* y_ppem :: The height of the scaled EM square in pixels, */ - /* hence the term `ppem' (pixels per EM). It is also */ - /* referred to as `nominal height'. */ - /* */ - /* x_scale :: A 16.16 fractional scaling value used to convert */ - /* horizontal metrics from font units to 26.6 */ - /* fractional pixels. Only relevant for scalable */ - /* font formats. */ - /* */ - /* y_scale :: A 16.16 fractional scaling value used to convert */ - /* vertical metrics from font units to 26.6 */ - /* fractional pixels. Only relevant for scalable */ - /* font formats. */ - /* */ - /* ascender :: The ascender in 26.6 fractional pixels. See */ - /* @FT_FaceRec for the details. */ - /* */ - /* descender :: The descender in 26.6 fractional pixels. See */ - /* @FT_FaceRec for the details. */ - /* */ - /* height :: The height in 26.6 fractional pixels. See */ - /* @FT_FaceRec for the details. */ - /* */ - /* max_advance :: The maximum advance width in 26.6 fractional */ - /* pixels. See @FT_FaceRec for the details. */ - /* */ - /* <Note> */ - /* The scaling values, if relevant, are determined first during a */ - /* size changing operation. The remaining fields are then set by the */ - /* driver. For scalable formats, they are usually set to scaled */ - /* values of the corresponding fields in @FT_FaceRec. */ - /* */ - /* Note that due to glyph hinting, these values might not be exact */ - /* for certain fonts. Thus they must be treated as unreliable */ - /* with an error margin of at least one pixel! */ - /* */ - /* Indeed, the only way to get the exact metrics is to render _all_ */ - /* 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 */ - FT_UShort y_ppem; /* vertical pixels per EM */ - - FT_Fixed x_scale; /* scaling values used to convert font */ - FT_Fixed y_scale; /* units to 26.6 fractional pixels */ - - FT_Pos ascender; /* ascender in 26.6 frac. pixels */ - FT_Pos descender; /* descender in 26.6 frac. pixels */ - FT_Pos height; /* text height in 26.6 frac. pixels */ - FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ - - } FT_Size_Metrics; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_SizeRec */ - /* */ - /* <Description> */ - /* FreeType root size class structure. A size object models a face */ - /* object at a given size. */ - /* */ - /* <Fields> */ - /* face :: Handle to the parent face object. */ - /* */ - /* generic :: A typeless pointer, which is unused by the FreeType */ - /* library or any of its drivers. It can be used by */ - /* client applications to link their own data to each size */ - /* object. */ - /* */ - /* metrics :: Metrics for this size object. This field is read-only. */ - /* */ - typedef struct FT_SizeRec_ - { - FT_Face face; /* parent face object */ - FT_Generic generic; /* generic pointer for client uses */ - FT_Size_Metrics metrics; /* size metrics */ - FT_Size_Internal internal; - - } FT_SizeRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_SubGlyph */ - /* */ - /* <Description> */ - /* The subglyph structure is an internal object used to describe */ - /* subglyphs (for example, in the case of composites). */ - /* */ - /* <Note> */ - /* The subglyph implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - /* You can however retrieve subglyph information with */ - /* @FT_Get_SubGlyph_Info. */ - /* */ - typedef struct FT_SubGlyphRec_* FT_SubGlyph; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Slot_Internal */ - /* */ - /* <Description> */ - /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ - /* model private data of a given @FT_GlyphSlot object. */ - /* */ - typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_GlyphSlotRec */ - /* */ - /* <Description> */ - /* FreeType root glyph slot class structure. A glyph slot is a */ - /* container where individual glyphs can be loaded, be they in */ - /* outline or bitmap format. */ - /* */ - /* <Fields> */ - /* library :: A handle to the FreeType library instance */ - /* this slot belongs to. */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* next :: In some cases (like some font tools), several */ - /* glyph slots per face object can be a good */ - /* thing. As this is rare, the glyph slots are */ - /* listed through a direct, single-linked list */ - /* using its `next' field. */ - /* */ - /* generic :: A typeless pointer which is unused by the */ - /* FreeType library or any of its drivers. It */ - /* can be used by client applications to link */ - /* their own data to each glyph slot object. */ - /* */ - /* metrics :: The metrics of the last loaded glyph in the */ - /* slot. The returned values depend on the last */ - /* load flags (see the @FT_Load_Glyph API */ - /* function) and can be expressed either in 26.6 */ - /* fractional pixels or font units. */ - /* */ - /* Note that even when the glyph image is */ - /* transformed, the metrics are not. */ - /* */ - /* linearHoriAdvance :: The advance width of the unhinted glyph. */ - /* Its value is expressed in 16.16 fractional */ - /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ - /* when loading the glyph. This field can be */ - /* important to perform correct WYSIWYG layout. */ - /* Only relevant for outline glyphs. */ - /* */ - /* linearVertAdvance :: The advance height of the unhinted glyph. */ - /* Its value is expressed in 16.16 fractional */ - /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ - /* when loading the glyph. This field can be */ - /* important to perform correct WYSIWYG layout. */ - /* Only relevant for outline glyphs. */ - /* */ - /* advance :: This shorthand is, depending on */ - /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ - /* advance width for the glyph (in 26.6 */ - /* fractional pixel format). As specified with */ - /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ - /* `horiAdvance' or the `vertAdvance' value of */ - /* `metrics' field. */ - /* */ - /* format :: This field indicates the format of the image */ - /* contained in the glyph slot. Typically */ - /* @FT_GLYPH_FORMAT_BITMAP, */ - /* @FT_GLYPH_FORMAT_OUTLINE, or */ - /* @FT_GLYPH_FORMAT_COMPOSITE, but others are */ - /* possible. */ - /* */ - /* bitmap :: This field is used as a bitmap descriptor */ - /* when the slot format is */ - /* @FT_GLYPH_FORMAT_BITMAP. Note that the */ - /* address and content of the bitmap buffer can */ - /* change between calls of @FT_Load_Glyph and a */ - /* few other functions. */ - /* */ - /* bitmap_left :: This is the bitmap's left bearing expressed */ - /* in integer pixels. Of course, this is only */ - /* valid if the format is */ - /* @FT_GLYPH_FORMAT_BITMAP. */ - /* */ - /* bitmap_top :: This is the bitmap's top bearing expressed in */ - /* integer pixels. Remember that this is the */ - /* distance from the baseline to the top-most */ - /* glyph scanline, upwards y~coordinates being */ - /* *positive*. */ - /* */ - /* outline :: The outline descriptor for the current glyph */ - /* image if its format is */ - /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ - /* loaded, `outline' can be transformed, */ - /* distorted, embolded, etc. However, it must */ - /* not be freed. */ - /* */ - /* num_subglyphs :: The number of subglyphs in a composite glyph. */ - /* This field is only valid for the composite */ - /* glyph format that should normally only be */ - /* loaded with the @FT_LOAD_NO_RECURSE flag. */ - /* For now this is internal to FreeType. */ - /* */ - /* subglyphs :: An array of subglyph descriptors for */ - /* composite glyphs. There are `num_subglyphs' */ - /* elements in there. Currently internal to */ - /* FreeType. */ - /* */ - /* control_data :: Certain font drivers can also return the */ - /* control data for a given glyph image (e.g. */ - /* TrueType bytecode, Type~1 charstrings, etc.). */ - /* This field is a pointer to such data. */ - /* */ - /* control_len :: This is the length in bytes of the control */ - /* data. */ - /* */ - /* other :: Really wicked formats can use this pointer to */ - /* present their own glyph image to client */ - /* applications. Note that the application */ - /* needs to know about the image format. */ - /* */ - /* lsb_delta :: The difference between hinted and unhinted */ - /* left side bearing while autohinting is */ - /* active. Zero otherwise. */ - /* */ - /* rsb_delta :: The difference between hinted and unhinted */ - /* right side bearing while autohinting is */ - /* active. Zero otherwise. */ - /* */ - /* <Note> */ - /* If @FT_Load_Glyph is called with default flags (see */ - /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ - /* its native format (e.g., an outline glyph for TrueType and Type~1 */ - /* formats). */ - /* */ - /* This image can later be converted into a bitmap by calling */ - /* @FT_Render_Glyph. This function finds the current renderer for */ - /* the native image's format, then invokes it. */ - /* */ - /* The renderer is in charge of transforming the native image through */ - /* the slot's face transformation fields, then converting it into a */ - /* bitmap that is returned in `slot->bitmap'. */ - /* */ - /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ - /* to specify the position of the bitmap relative to the current pen */ - /* position (e.g., coordinates (0,0) on the baseline). Of course, */ - /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ - /* */ - /* <Note> */ - /* Here a small pseudo code fragment which shows how to use */ - /* `lsb_delta' and `rsb_delta': */ - /* */ - /* { */ - /* FT_Pos origin_x = 0; */ - /* FT_Pos prev_rsb_delta = 0; */ - /* */ - /* */ - /* for all glyphs do */ - /* <compute kern between current and previous glyph and add it to */ - /* `origin_x'> */ - /* */ - /* <load glyph with `FT_Load_Glyph'> */ - /* */ - /* if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 ) */ - /* origin_x -= 64; */ - /* else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 ) */ - /* origin_x += 64; */ - /* */ - /* prev_rsb_delta = face->glyph->rsb_delta; */ - /* */ - /* <save glyph image, or render glyph, or ...> */ - /* */ - /* origin_x += face->glyph->advance.x; */ - /* endfor */ - /* } */ - /* */ - typedef struct FT_GlyphSlotRec_ - { - FT_Library library; - FT_Face face; - FT_GlyphSlot next; - FT_UInt reserved; /* retained for binary compatibility */ - FT_Generic generic; - - FT_Glyph_Metrics metrics; - FT_Fixed linearHoriAdvance; - FT_Fixed linearVertAdvance; - FT_Vector advance; - - FT_Glyph_Format format; - - FT_Bitmap bitmap; - FT_Int bitmap_left; - FT_Int bitmap_top; - - FT_Outline outline; - - FT_UInt num_subglyphs; - FT_SubGlyph subglyphs; - - void* control_data; - long control_len; - - FT_Pos lsb_delta; - FT_Pos rsb_delta; - - void* other; - - FT_Slot_Internal internal; - - } FT_GlyphSlotRec; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* F U N C T I O N S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Init_FreeType */ - /* */ - /* <Description> */ - /* Initialize a new FreeType library object. The set of modules */ - /* that are registered by this function is determined at build time. */ - /* */ - /* <Output> */ - /* alibrary :: A handle to a new library object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* In case you want to provide your own memory allocating routines, */ - /* use @FT_New_Library instead, followed by a call to */ - /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ - /* */ - /* For multi-threading applications each thread should have its own */ - /* FT_Library object. */ - /* */ - /* If you need reference-counting (cf. @FT_Reference_Library), use */ - /* @FT_New_Library and @FT_Done_Library. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Init_FreeType( FT_Library *alibrary ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_FreeType */ - /* */ - /* <Description> */ - /* Destroy a given FreeType library object and all of its children, */ - /* including resources, drivers, faces, sizes, etc. */ - /* */ - /* <Input> */ - /* library :: A handle to the target library object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Done_FreeType( FT_Library library ); - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_OPEN_XXX */ - /* */ - /* <Description> */ - /* A list of bit-field constants used within the `flags' field of the */ - /* @FT_Open_Args structure. */ - /* */ - /* <Values> */ - /* FT_OPEN_MEMORY :: This is a memory-based stream. */ - /* */ - /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ - /* */ - /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ - /* name. */ - /* */ - /* FT_OPEN_DRIVER :: Use the `driver' field. */ - /* */ - /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ - /* */ - /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ - /* */ - /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ - /* */ - /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ - /* */ - /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ - /* */ - /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ - /* */ - /* <Note> */ - /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ - /* flags are mutually exclusive. */ - /* */ -#define FT_OPEN_MEMORY 0x1 -#define FT_OPEN_STREAM 0x2 -#define FT_OPEN_PATHNAME 0x4 -#define FT_OPEN_DRIVER 0x8 -#define FT_OPEN_PARAMS 0x10 - -#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ -#define ft_open_stream FT_OPEN_STREAM /* deprecated */ -#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ -#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ -#define ft_open_params FT_OPEN_PARAMS /* deprecated */ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Parameter */ - /* */ - /* <Description> */ - /* A simple structure used to pass more or less generic parameters to */ - /* @FT_Open_Face. */ - /* */ - /* <Fields> */ - /* tag :: A four-byte identification tag. */ - /* */ - /* data :: A pointer to the parameter data. */ - /* */ - /* <Note> */ - /* The ID and function of parameters are driver-specific. See the */ - /* various FT_PARAM_TAG_XXX flags for more information. */ - /* */ - typedef struct FT_Parameter_ - { - FT_ULong tag; - FT_Pointer data; - - } FT_Parameter; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Open_Args */ - /* */ - /* <Description> */ - /* A structure used to indicate how to open a new font file or */ - /* stream. A pointer to such a structure can be used as a parameter */ - /* for the functions @FT_Open_Face and @FT_Attach_Stream. */ - /* */ - /* <Fields> */ - /* flags :: A set of bit flags indicating how to use the */ - /* structure. */ - /* */ - /* memory_base :: The first byte of the file in memory. */ - /* */ - /* memory_size :: The size in bytes of the file in memory. */ - /* */ - /* pathname :: A pointer to an 8-bit file pathname. */ - /* */ - /* stream :: A handle to a source stream object. */ - /* */ - /* driver :: This field is exclusively used by @FT_Open_Face; */ - /* it simply specifies the font driver to use to open */ - /* the face. If set to~0, FreeType tries to load the */ - /* face with each one of the drivers in its list. */ - /* */ - /* num_params :: The number of extra parameters. */ - /* */ - /* params :: Extra parameters passed to the font driver when */ - /* opening a new face. */ - /* */ - /* <Note> */ - /* The stream type is determined by the contents of `flags' which */ - /* are tested in the following order by @FT_Open_Face: */ - /* */ - /* If the `FT_OPEN_MEMORY' bit is set, assume that this is a */ - /* memory file of `memory_size' bytes, located at `memory_address'. */ - /* The data are are not copied, and the client is responsible for */ - /* releasing and destroying them _after_ the corresponding call to */ - /* @FT_Done_Face. */ - /* */ - /* Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a */ - /* custom input stream `stream' is used. */ - /* */ - /* Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this */ - /* is a normal file and use `pathname' to open it. */ - /* */ - /* If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to */ - /* open the file with the driver whose handler is in `driver'. */ - /* */ - /* If the `FT_OPEN_PARAMS' bit is set, the parameters given by */ - /* `num_params' and `params' is used. They are ignored otherwise. */ - /* */ - /* Ideally, both the `pathname' and `params' fields should be tagged */ - /* as `const'; this is missing for API backwards compatibility. In */ - /* other words, applications should treat them as read-only. */ - /* */ - typedef struct FT_Open_Args_ - { - FT_UInt flags; - const FT_Byte* memory_base; - FT_Long memory_size; - FT_String* pathname; - FT_Stream stream; - FT_Module driver; - FT_Int num_params; - FT_Parameter* params; - - } FT_Open_Args; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face */ - /* */ - /* <Description> */ - /* This function calls @FT_Open_Face to open a font by its pathname. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* pathname :: A path to the font file. */ - /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ - /* */ - /* <Output> */ - /* aface :: A handle to a new face object. If `face_index' is */ - /* greater than or equal to zero, it must be non-NULL. */ - /* See @FT_Open_Face for more details. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Use @FT_Done_Face to destroy the created @FT_Face object (along */ - /* with its slot and sizes). */ - /* */ - FT_EXPORT( FT_Error ) - FT_New_Face( FT_Library library, - const char* filepathname, - FT_Long face_index, - FT_Face *aface ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Memory_Face */ - /* */ - /* <Description> */ - /* This function calls @FT_Open_Face to open a font which has been */ - /* loaded into memory. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* file_base :: A pointer to the beginning of the font data. */ - /* */ - /* file_size :: The size of the memory chunk used by the font data. */ - /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ - /* */ - /* <Output> */ - /* aface :: A handle to a new face object. If `face_index' is */ - /* greater than or equal to zero, it must be non-NULL. */ - /* See @FT_Open_Face for more details. */ - /* */ - /* <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, - FT_Long file_size, - FT_Long face_index, - FT_Face *aface ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Open_Face */ - /* */ - /* <Description> */ - /* Create a face object from a given resource described by */ - /* @FT_Open_Args. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* args :: A pointer to an `FT_Open_Args' structure which must */ - /* be filled by the caller. */ - /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ - /* */ - /* <Output> */ - /* aface :: A handle to a new face object. If `face_index' is */ - /* greater than or equal to zero, it must be non-NULL. */ - /* See note below. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* FT_Open_Face can be used to quickly check whether the font */ - /* format of a given font resource is supported by FreeType. If the */ - /* `face_index' field is negative, the function's return value is~0 */ - /* if the font format is recognized, or non-zero otherwise; */ - /* the function returns a more or less empty face handle in `*aface' */ - /* (if `aface' isn't NULL). The only useful field in this special */ - /* case is `face->num_faces' which gives the number of faces within */ - /* the font file. After examination, the returned @FT_Face structure */ - /* should be deallocated with a call to @FT_Done_Face. */ - /* */ - /* Each new face object created with this function also owns a */ - /* default @FT_Size object, accessible as `face->size'. */ - /* */ - /* One @FT_Library instance can have multiple face objects, this is, */ - /* @FT_Open_Face and its siblings can be called multiple times using */ - /* the same `library' argument. */ - /* */ - /* See the discussion of reference counters in the description of */ - /* @FT_Reference_Face. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Open_Face( FT_Library library, - const FT_Open_Args* args, - FT_Long face_index, - FT_Face *aface ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Attach_File */ - /* */ - /* <Description> */ - /* This function calls @FT_Attach_Stream to attach a file. */ - /* */ - /* <InOut> */ - /* face :: The target face object. */ - /* */ - /* <Input> */ - /* filepathname :: The pathname. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Attach_File( FT_Face face, - const char* filepathname ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Attach_Stream */ - /* */ - /* <Description> */ - /* `Attach' data to a face object. Normally, this is used to read */ - /* additional information for the face object. For example, you can */ - /* attach an AFM file that comes with a Type~1 font to get the */ - /* kerning values and other metrics. */ - /* */ - /* <InOut> */ - /* face :: The target face object. */ - /* */ - /* <Input> */ - /* parameters :: A pointer to @FT_Open_Args which must be filled by */ - /* the caller. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The meaning of the `attach' (i.e., what really happens when the */ - /* new file is read) is not fixed by FreeType itself. It really */ - /* depends on the font format (and thus the font driver). */ - /* */ - /* Client applications are expected to know what they are doing */ - /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Attach_Stream( FT_Face face, - FT_Open_Args* parameters ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Reference_Face */ - /* */ - /* <Description> */ - /* A counter gets initialized to~1 at the time an @FT_Face structure */ - /* is created. This function increments the counter. @FT_Done_Face */ - /* then only destroys a face if the counter is~1, otherwise it simply */ - /* decrements the counter. */ - /* */ - /* This function helps in managing life-cycles of structures which */ - /* reference @FT_Face objects. */ - /* */ - /* <Input> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Since> */ - /* 2.4.2 */ - /* */ - FT_EXPORT( FT_Error ) - FT_Reference_Face( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Face */ - /* */ - /* <Description> */ - /* Discard a given face object, as well as all of its child slots and */ - /* sizes. */ - /* */ - /* <Input> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* See the discussion of reference counters in the description of */ - /* @FT_Reference_Face. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Done_Face( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Select_Size */ - /* */ - /* <Description> */ - /* Select a bitmap strike. */ - /* */ - /* <InOut> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Input> */ - /* strike_index :: The index of the bitmap strike in the */ - /* `available_sizes' field of @FT_FaceRec structure. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Select_Size( FT_Face face, - FT_Int strike_index ); - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Size_Request_Type */ - /* */ - /* <Description> */ - /* An enumeration type that lists the supported size request types. */ - /* */ - /* <Values> */ - /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ - /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ - /* used to determine both scaling values. */ - /* */ - /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ - /* The real dimension. The sum of the the `ascender' and (minus */ - /* of) the `descender' fields of @FT_FaceRec are used to determine */ - /* both scaling values. */ - /* */ - /* FT_SIZE_REQUEST_TYPE_BBOX :: */ - /* The font bounding box. The width and height of the `bbox' field */ - /* of @FT_FaceRec are used to determine the horizontal and vertical */ - /* scaling value, respectively. */ - /* */ - /* FT_SIZE_REQUEST_TYPE_CELL :: */ - /* The `max_advance_width' field of @FT_FaceRec is used to */ - /* determine the horizontal scaling value; the vertical scaling */ - /* value is determined the same way as */ - /* @FT_SIZE_REQUEST_TYPE_REAL_DIM does. Finally, both scaling */ - /* values are set to the smaller one. This type is useful if you */ - /* want to specify the font size for, say, a window of a given */ - /* dimension and 80x24 cells. */ - /* */ - /* FT_SIZE_REQUEST_TYPE_SCALES :: */ - /* Specify the scaling values directly. */ - /* */ - /* <Note> */ - /* The above descriptions only apply to scalable formats. For bitmap */ - /* formats, the behaviour is up to the driver. */ - /* */ - /* See the note section of @FT_Size_Metrics if you wonder how size */ - /* requesting relates to scaling values. */ - /* */ - typedef enum FT_Size_Request_Type_ - { - FT_SIZE_REQUEST_TYPE_NOMINAL, - FT_SIZE_REQUEST_TYPE_REAL_DIM, - FT_SIZE_REQUEST_TYPE_BBOX, - FT_SIZE_REQUEST_TYPE_CELL, - FT_SIZE_REQUEST_TYPE_SCALES, - - FT_SIZE_REQUEST_TYPE_MAX - - } FT_Size_Request_Type; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Size_RequestRec */ - /* */ - /* <Description> */ - /* A structure used to model a size request. */ - /* */ - /* <Fields> */ - /* type :: See @FT_Size_Request_Type. */ - /* */ - /* width :: The desired width. */ - /* */ - /* height :: The desired height. */ - /* */ - /* horiResolution :: The horizontal resolution. If set to zero, */ - /* `width' is treated as a 26.6 fractional pixel */ - /* value. */ - /* */ - /* vertResolution :: The vertical resolution. If set to zero, */ - /* `height' is treated as a 26.6 fractional pixel */ - /* value. */ - /* */ - /* <Note> */ - /* If `width' is zero, then the horizontal scaling value is set equal */ - /* to the vertical scaling value, and vice versa. */ - /* */ - typedef struct FT_Size_RequestRec_ - { - FT_Size_Request_Type type; - FT_Long width; - FT_Long height; - FT_UInt horiResolution; - FT_UInt vertResolution; - - } FT_Size_RequestRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Size_Request */ - /* */ - /* <Description> */ - /* A handle to a size request structure. */ - /* */ - typedef struct FT_Size_RequestRec_ *FT_Size_Request; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Request_Size */ - /* */ - /* <Description> */ - /* Resize the scale of the active @FT_Size object in a face. */ - /* */ - /* <InOut> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Input> */ - /* req :: A pointer to a @FT_Size_RequestRec. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Although drivers may select the bitmap strike matching the */ - /* request, you should not rely on this if you intend to select a */ - /* particular bitmap strike. Use @FT_Select_Size instead in that */ - /* case. */ - /* */ - /* The relation between the requested size and the resulting glyph */ - /* size is dependent entirely on how the size is defined in the */ - /* source face. The font designer chooses the final size of each */ - /* glyph relative to this size. For more information refer to */ - /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */ - /* */ - FT_EXPORT( FT_Error ) - FT_Request_Size( FT_Face face, - FT_Size_Request req ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Char_Size */ - /* */ - /* <Description> */ - /* This function calls @FT_Request_Size to request the nominal size */ - /* (in points). */ - /* */ - /* <InOut> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Input> */ - /* char_width :: The nominal width, in 26.6 fractional points. */ - /* */ - /* char_height :: The nominal height, in 26.6 fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution in dpi. */ - /* */ - /* vert_resolution :: The vertical resolution in dpi. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* If either the character width or height is zero, it is set equal */ - /* to the other value. */ - /* */ - /* If either the horizontal or vertical resolution is zero, it is set */ - /* equal to the other value. */ - /* */ - /* A character width or height smaller than 1pt is set to 1pt; if */ - /* both resolution values are zero, they are set to 72dpi. */ - /* */ - /* Don't use this function if you are using the FreeType cache API. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Set_Char_Size( FT_Face face, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Pixel_Sizes */ - /* */ - /* <Description> */ - /* This function calls @FT_Request_Size to request the nominal size */ - /* (in pixels). */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Input> */ - /* pixel_width :: The nominal width, in pixels. */ - /* */ - /* pixel_height :: The nominal height, in pixels. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* You should not rely on the resulting glyphs matching, or being */ - /* constrained, to this pixel size. Refer to @FT_Request_Size to */ - /* understand how requested sizes relate to actual sizes. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Set_Pixel_Sizes( FT_Face face, - FT_UInt pixel_width, - FT_UInt pixel_height ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Load_Glyph */ - /* */ - /* <Description> */ - /* A function used to load a single glyph into the glyph slot of a */ - /* face object. */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object where the glyph */ - /* is loaded. */ - /* */ - /* <Input> */ - /* glyph_index :: The index of the glyph in the font file. For */ - /* CID-keyed fonts (either in PS or in CFF format) */ - /* this argument specifies the CID value. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* @FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The loaded glyph may be transformed. See @FT_Set_Transform for */ - /* the details. */ - /* */ - /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ - /* returned for invalid CID values (this is, for CID values which */ - /* don't have a corresponding glyph in the font). See the discussion */ - /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Load_Glyph( FT_Face face, - FT_UInt glyph_index, - FT_Int32 load_flags ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Load_Char */ - /* */ - /* <Description> */ - /* A function used to load a single glyph into the glyph slot of a */ - /* face object, according to its character code. */ - /* */ - /* <InOut> */ - /* face :: A handle to a target face object where the glyph */ - /* is loaded. */ - /* */ - /* <Input> */ - /* char_code :: The glyph's character code, according to the */ - /* current charmap used in the face. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* @FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Load_Char( FT_Face face, - FT_ULong char_code, - FT_Int32 load_flags ); - - - /************************************************************************* - * - * @enum: - * FT_LOAD_XXX - * - * @description: - * A list of bit-field constants used with @FT_Load_Glyph to indicate - * what kind of operations to perform during glyph loading. - * - * @values: - * FT_LOAD_DEFAULT :: - * Corresponding to~0, this value is used as the default glyph load - * operation. In this case, the following happens: - * - * 1. FreeType looks for a bitmap for the glyph corresponding to the - * face's current size. If one is found, the function returns. - * The bitmap data can be accessed from the glyph slot (see note - * below). - * - * 2. If no embedded bitmap is searched or found, FreeType looks for a - * scalable outline. If one is found, it is loaded from the font - * file, scaled to device pixels, then `hinted' to the pixel grid - * in order to optimize it. The outline data can be accessed from - * the glyph slot (see note below). - * - * Note that by default, the glyph loader doesn't render outlines into - * bitmaps. The following flags are used to modify this default - * behaviour to more specific and useful cases. - * - * FT_LOAD_NO_SCALE :: - * Don't scale the loaded outline glyph but keep it in font units. - * - * This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and - * unsets @FT_LOAD_RENDER. - * - * If the font is `tricky' (see @FT_FACE_FLAG_TRICKY for more), using - * FT_LOAD_NO_SCALE usually yields meaningless outlines because the - * subglyphs must be scaled and positioned with hinting instructions. - * This can be solved by loading the font without FT_LOAD_NO_SCALE and - * setting the character size to `font->units_per_EM'. - * - * FT_LOAD_NO_HINTING :: - * Disable hinting. This generally generates `blurrier' bitmap glyphs - * when the glyph are rendered in any of the anti-aliased modes. See - * also the note below. - * - * This flag is implied by @FT_LOAD_NO_SCALE. - * - * FT_LOAD_RENDER :: - * Call @FT_Render_Glyph after the glyph is loaded. By default, the - * glyph is rendered in @FT_RENDER_MODE_NORMAL mode. This can be - * overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME. - * - * This flag is unset by @FT_LOAD_NO_SCALE. - * - * FT_LOAD_NO_BITMAP :: - * Ignore bitmap strikes when loading. Bitmap-only fonts ignore this - * flag. - * - * @FT_LOAD_NO_SCALE always sets this flag. - * - * FT_LOAD_VERTICAL_LAYOUT :: - * Load the glyph for vertical text layout. In particular, the - * `advance' value in the @FT_GlyphSlotRec structure is set to the - * `vertAdvance' value of the `metrics' field. - * - * In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use - * this flag currently. Reason is that in this case vertical metrics - * get synthesized, and those values are not always consistent across - * various font formats. - * - * FT_LOAD_FORCE_AUTOHINT :: - * Indicates that the auto-hinter is preferred over the font's native - * hinter. See also the note below. - * - * FT_LOAD_CROP_BITMAP :: - * Indicates that the font driver should crop the loaded bitmap glyph - * (i.e., remove all space around its black bits). Not all drivers - * implement this. - * - * FT_LOAD_PEDANTIC :: - * Indicates that the font driver should perform pedantic verifications - * during glyph loading. This is mostly used to detect broken glyphs - * in fonts. By default, FreeType tries to handle broken fonts also. - * - * In particular, errors from the TrueType bytecode engine are not - * passed to the application if this flag is not set; this might - * result in partially hinted or distorted glyphs in case a glyph's - * bytecode is buggy. - * - * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: - * Ignored. Deprecated. - * - * FT_LOAD_NO_RECURSE :: - * This flag is only used internally. It merely indicates that the - * font driver should not load composite glyphs recursively. Instead, - * it should set the `num_subglyph' and `subglyphs' values of the - * glyph slot accordingly, and set `glyph->format' to - * @FT_GLYPH_FORMAT_COMPOSITE. - * - * The description of sub-glyphs is not available to client - * applications for now. - * - * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. - * - * FT_LOAD_IGNORE_TRANSFORM :: - * Indicates that the transform matrix set by @FT_Set_Transform should - * be ignored. - * - * FT_LOAD_MONOCHROME :: - * This flag is used with @FT_LOAD_RENDER to indicate that you want to - * render an outline glyph to a 1-bit monochrome bitmap glyph, with - * 8~pixels packed into each byte of the bitmap data. - * - * Note that this has no effect on the hinting algorithm used. You - * should rather use @FT_LOAD_TARGET_MONO so that the - * monochrome-optimized hinting algorithm is used. - * - * FT_LOAD_LINEAR_DESIGN :: - * Indicates that the `linearHoriAdvance' and `linearVertAdvance' - * fields of @FT_GlyphSlotRec should be kept in font units. See - * @FT_GlyphSlotRec for details. - * - * FT_LOAD_NO_AUTOHINT :: - * Disable auto-hinter. See also the note below. - * - * FT_LOAD_COLOR :: - * This flag is used to request loading of color embedded-bitmap - * images. The resulting color bitmaps, if available, will have the - * @FT_PIXEL_MODE_BGRA format. When the flag is not used and color - * bitmaps are found, they will be converted to 256-level gray - * bitmaps transparently. Those bitmaps will be in the - * @FT_PIXEL_MODE_GRAY format. - * - * @note: - * By default, hinting is enabled and the font's native hinter (see - * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can - * disable hinting by setting @FT_LOAD_NO_HINTING or change the - * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set - * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be - * used at all. - * - * See the description of @FT_FACE_FLAG_TRICKY for a special exception - * (affecting only a handful of Asian fonts). - * - * Besides deciding which hinter to use, you can also decide which - * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. - * - * Note that the auto-hinter needs a valid Unicode cmap (either a native - * one or synthesized by FreeType) for producing correct results. If a - * font provides an incorrect mapping (for example, assigning the - * character code U+005A, LATIN CAPITAL LETTER Z, to a glyph depicting a - * mathematical integral sign), the auto-hinter might produce useless - * results. - * - */ -#define FT_LOAD_DEFAULT 0x0 -#define FT_LOAD_NO_SCALE ( 1L << 0 ) -#define FT_LOAD_NO_HINTING ( 1L << 1 ) -#define FT_LOAD_RENDER ( 1L << 2 ) -#define FT_LOAD_NO_BITMAP ( 1L << 3 ) -#define FT_LOAD_VERTICAL_LAYOUT ( 1L << 4 ) -#define FT_LOAD_FORCE_AUTOHINT ( 1L << 5 ) -#define FT_LOAD_CROP_BITMAP ( 1L << 6 ) -#define FT_LOAD_PEDANTIC ( 1L << 7 ) -#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ( 1L << 9 ) -#define FT_LOAD_NO_RECURSE ( 1L << 10 ) -#define FT_LOAD_IGNORE_TRANSFORM ( 1L << 11 ) -#define FT_LOAD_MONOCHROME ( 1L << 12 ) -#define FT_LOAD_LINEAR_DESIGN ( 1L << 13 ) -#define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) - /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ -#define FT_LOAD_COLOR ( 1L << 20 ) - - /* */ - - /* used internally only by certain font drivers! */ -#define FT_LOAD_ADVANCE_ONLY ( 1L << 8 ) -#define FT_LOAD_SBITS_ONLY ( 1L << 14 ) - - - /************************************************************************** - * - * @enum: - * FT_LOAD_TARGET_XXX - * - * @description: - * A list of values that are used to select a specific hinting algorithm - * to use by the hinter. You should OR one of these values to your - * `load_flags' when calling @FT_Load_Glyph. - * - * Note that font's native hinters may ignore the hinting algorithm you - * have specified (e.g., the TrueType bytecode interpreter). You can set - * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. - * - * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it - * always implies @FT_LOAD_FORCE_AUTOHINT. - * - * @values: - * FT_LOAD_TARGET_NORMAL :: - * This corresponds to the default hinting algorithm, optimized for - * standard gray-level rendering. For monochrome output, use - * @FT_LOAD_TARGET_MONO instead. - * - * FT_LOAD_TARGET_LIGHT :: - * A lighter hinting algorithm for non-monochrome modes. Many - * generated glyphs are more fuzzy but better resemble its original - * shape. A bit like rendering on Mac OS~X. - * - * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. - * - * FT_LOAD_TARGET_MONO :: - * Strong hinting algorithm that should only be used for monochrome - * output. The result is probably unpleasant if the glyph is rendered - * in non-monochrome modes. - * - * FT_LOAD_TARGET_LCD :: - * A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally - * decimated LCD displays. - * - * FT_LOAD_TARGET_LCD_V :: - * A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically - * decimated LCD displays. - * - * @note: - * You should use only _one_ of the FT_LOAD_TARGET_XXX values in your - * `load_flags'. They can't be ORed. - * - * If @FT_LOAD_RENDER is also set, the glyph is rendered in the - * corresponding mode (i.e., the mode which matches the used algorithm - * best). An exeption is FT_LOAD_TARGET_MONO since it implies - * @FT_LOAD_MONOCHROME. - * - * You can use a hinting algorithm that doesn't correspond to the same - * rendering mode. As an example, it is possible to use the `light' - * hinting algorithm and have the results rendered in horizontal LCD - * pixel mode, with code like - * - * { - * FT_Load_Glyph( face, glyph_index, - * load_flags | FT_LOAD_TARGET_LIGHT ); - * - * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); - * } - * - */ -#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) - -#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) -#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) -#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) -#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) -#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) - - - /************************************************************************** - * - * @macro: - * FT_LOAD_TARGET_MODE - * - * @description: - * Return the @FT_Render_Mode corresponding to a given - * @FT_LOAD_TARGET_XXX value. - * - */ -#define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Transform */ - /* */ - /* <Description> */ - /* A function used to set the transformation that is applied to glyph */ - /* images when they are loaded into a glyph slot through */ - /* @FT_Load_Glyph. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Input> */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ - /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use~0 for the null */ - /* vector. */ - /* */ - /* <Note> */ - /* The transformation is only applied to scalable image formats after */ - /* the glyph has been loaded. It means that hinting is unaltered by */ - /* the transformation and is performed on the character size given in */ - /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ - /* */ - /* Note that this also transforms the `face.glyph.advance' field, but */ - /* *not* the values in `face.glyph.metrics'. */ - /* */ - FT_EXPORT( void ) - FT_Set_Transform( FT_Face face, - FT_Matrix* matrix, - FT_Vector* delta ); - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Render_Mode */ - /* */ - /* <Description> */ - /* An enumeration type that lists the render modes supported by */ - /* FreeType~2. Each mode corresponds to a specific type of scanline */ - /* conversion performed on the outline. */ - /* */ - /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ - /* field in the @FT_GlyphSlotRec structure gives the format of the */ - /* returned bitmap. */ - /* */ - /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ - /* */ - /* <Values> */ - /* FT_RENDER_MODE_NORMAL :: */ - /* This is the default render mode; it corresponds to 8-bit */ - /* anti-aliased bitmaps. */ - /* */ - /* FT_RENDER_MODE_LIGHT :: */ - /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ - /* defined as a separate value because render modes are also used */ - /* indirectly to define hinting algorithm selectors. See */ - /* @FT_LOAD_TARGET_XXX for details. */ - /* */ - /* FT_RENDER_MODE_MONO :: */ - /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ - /* opacity). */ - /* */ - /* FT_RENDER_MODE_LCD :: */ - /* This mode corresponds to horizontal RGB and BGR sub-pixel */ - /* displays like LCD screens. It produces 8-bit bitmaps that are */ - /* 3~times the width of the original glyph outline in pixels, and */ - /* which use the @FT_PIXEL_MODE_LCD mode. */ - /* */ - /* FT_RENDER_MODE_LCD_V :: */ - /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ - /* (like PDA screens, rotated LCD displays, etc.). It produces */ - /* 8-bit bitmaps that are 3~times the height of the original */ - /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ - /* */ - /* <Note> */ - /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ - /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ - /* (not active in the default builds). It is up to the caller to */ - /* either call @FT_Library_SetLcdFilter (if available) or do the */ - /* filtering itself. */ - /* */ - /* The selected render mode only affects vector glyphs of a font. */ - /* Embedded bitmaps often have a different pixel mode like */ - /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ - /* them into 8-bit pixmaps. */ - /* */ - typedef enum FT_Render_Mode_ - { - FT_RENDER_MODE_NORMAL = 0, - FT_RENDER_MODE_LIGHT, - FT_RENDER_MODE_MONO, - FT_RENDER_MODE_LCD, - FT_RENDER_MODE_LCD_V, - - FT_RENDER_MODE_MAX - - } FT_Render_Mode; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_render_mode_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated. Use the corresponding */ - /* @FT_Render_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ - /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ - /* */ -#define ft_render_mode_normal FT_RENDER_MODE_NORMAL -#define ft_render_mode_mono FT_RENDER_MODE_MONO - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Render_Glyph */ - /* */ - /* <Description> */ - /* Convert a given glyph image to a bitmap. It does so by inspecting */ - /* the glyph image format, finding the relevant renderer, and */ - /* invoking it. */ - /* */ - /* <InOut> */ - /* slot :: A handle to the glyph slot containing the image to */ - /* convert. */ - /* */ - /* <Input> */ - /* render_mode :: This is the render mode used to render the glyph */ - /* image into a bitmap. See @FT_Render_Mode for a */ - /* list of possible values. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Render_Glyph( FT_GlyphSlot slot, - FT_Render_Mode render_mode ); - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Kerning_Mode */ - /* */ - /* <Description> */ - /* An enumeration used to specify which kerning values to return in */ - /* @FT_Get_Kerning. */ - /* */ - /* <Values> */ - /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ - /* distances (value is~0). */ - /* */ - /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ - /* distances. */ - /* */ - /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ - /* units. */ - /* */ - typedef enum FT_Kerning_Mode_ - { - FT_KERNING_DEFAULT = 0, - FT_KERNING_UNFITTED, - FT_KERNING_UNSCALED - - } FT_Kerning_Mode; - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_default */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_DEFAULT */ - /* instead. */ - /* */ -#define ft_kerning_default FT_KERNING_DEFAULT - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_unfitted */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_UNFITTED */ - /* instead. */ - /* */ -#define ft_kerning_unfitted FT_KERNING_UNFITTED - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_unscaled */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_UNSCALED */ - /* instead. */ - /* */ -#define ft_kerning_unscaled FT_KERNING_UNSCALED - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Kerning */ - /* */ - /* <Description> */ - /* Return the kerning vector between two glyphs of a same face. */ - /* */ - /* <Input> */ - /* face :: A handle to a source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* kern_mode :: See @FT_Kerning_Mode for more information. */ - /* Determines the scale and dimension of the returned */ - /* kerning vector. */ - /* */ - /* <Output> */ - /* akerning :: The kerning vector. This is either in font units */ - /* or in pixels (26.6 format) for scalable formats, */ - /* and in pixels for fixed-sizes formats. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this method. Other layouts, or more sophisticated */ - /* kernings, are out of the scope of this API function -- they can be */ - /* implemented through format-specific interfaces. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_Kerning( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_UInt kern_mode, - FT_Vector *akerning ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Track_Kerning */ - /* */ - /* <Description> */ - /* Return the track kerning for a given face object at a given size. */ - /* */ - /* <Input> */ - /* face :: A handle to a source face object. */ - /* */ - /* point_size :: The point size in 16.16 fractional points. */ - /* */ - /* degree :: The degree of tightness. Increasingly negative */ - /* values represent tighter track kerning, while */ - /* increasingly positive values represent looser track */ - /* kerning. Value zero means no track kerning. */ - /* */ - /* <Output> */ - /* akerning :: The kerning in 16.16 fractional points, to be */ - /* uniformly applied between all glyphs. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Currently, only the Type~1 font driver supports track kerning, */ - /* using data from AFM files (if attached with @FT_Attach_File or */ - /* @FT_Attach_Stream). */ - /* */ - /* Only very few AFM files come with track kerning data; please refer */ - /* to the Adobe's AFM specification for more details. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_Track_Kerning( FT_Face face, - FT_Fixed point_size, - FT_Int degree, - FT_Fixed* akerning ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Glyph_Name */ - /* */ - /* <Description> */ - /* Retrieve the ASCII name of a given glyph in a face. This only */ - /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ - /* */ - /* <Input> */ - /* face :: A handle to a source face object. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* buffer_max :: The maximum number of bytes available in the */ - /* buffer. */ - /* */ - /* <Output> */ - /* buffer :: A pointer to a target buffer where the name is */ - /* copied to. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* An error is returned if the face doesn't provide glyph names or if */ - /* the glyph index is invalid. In all cases of failure, the first */ - /* byte of `buffer' is set to~0 to indicate an empty name. */ - /* */ - /* The glyph name is truncated to fit within the buffer if it is too */ - /* long. The returned string is always zero-terminated. */ - /* */ - /* Be aware that FreeType reorders glyph indices internally so that */ - /* glyph index~0 always corresponds to the `missing glyph' (called */ - /* `.notdef'). */ - /* */ - /* This function is not compiled within the library if the config */ - /* macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in */ - /* `include/freetype/config/ftoptions.h'. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_Glyph_Name( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Postscript_Name */ - /* */ - /* <Description> */ - /* Retrieve the ASCII PostScript name of a given face, if available. */ - /* This only works with PostScript and TrueType fonts. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Return> */ - /* A pointer to the face's PostScript name. NULL if unavailable. */ - /* */ - /* <Note> */ - /* The returned pointer is owned by the face and is destroyed with */ - /* it. */ - /* */ - FT_EXPORT( const char* ) - FT_Get_Postscript_Name( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Select_Charmap */ - /* */ - /* <Description> */ - /* Select a given charmap by its encoding tag (as listed in */ - /* `freetype.h'). */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Input> */ - /* encoding :: A handle to the selected encoding. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function returns an error if no charmap in the face */ - /* corresponds to the encoding queried here. */ - /* */ - /* Because many fonts contain more than a single cmap for Unicode */ - /* encoding, this function has some special code to select the one */ - /* which covers Unicode best (`best' in the sense that a UCS-4 cmap */ - /* is preferred to a UCS-2 cmap). It is thus preferable to */ - /* @FT_Set_Charmap in this case. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Select_Charmap( FT_Face face, - FT_Encoding encoding ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Charmap */ - /* */ - /* <Description> */ - /* Select a given charmap for character code to glyph index mapping. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Input> */ - /* charmap :: A handle to the selected charmap. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function returns an error if the charmap is not part of */ - /* the face (i.e., if it is not listed in the `face->charmaps' */ - /* table). */ - /* */ - /* It also fails if a type~14 charmap is selected. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Set_Charmap( FT_Face face, - FT_CharMap charmap ); - - - /************************************************************************* - * - * @function: - * FT_Get_Charmap_Index - * - * @description: - * Retrieve index of a given charmap. - * - * @input: - * charmap :: - * A handle to a charmap. - * - * @return: - * The index into the array of character maps within the face to which - * `charmap' belongs. If an error occurs, -1 is returned. - * - */ - FT_EXPORT( FT_Int ) - FT_Get_Charmap_Index( FT_CharMap charmap ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Char_Index */ - /* */ - /* <Description> */ - /* Return the glyph index of a given character code. This function */ - /* uses a charmap object to do the mapping. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* charcode :: The character code. */ - /* */ - /* <Return> */ - /* The glyph index. 0~means `undefined character code'. */ - /* */ - /* <Note> */ - /* If you use FreeType to manipulate the contents of font files */ - /* directly, be aware that the glyph index returned by this function */ - /* doesn't always correspond to the internal indices used within the */ - /* file. This is done to ensure that value~0 always corresponds to */ - /* the `missing glyph'. If the first glyph is not named `.notdef', */ - /* then for Type~1 and Type~42 fonts, `.notdef' will be moved into */ - /* the glyph ID~0 position, and whatever was there will be moved to */ - /* the position `.notdef' had. For Type~1 fonts, if there is no */ - /* `.notdef' glyph at all, then one will be created at index~0 and */ - /* whatever was there will be moved to the last index -- Type~42 */ - /* fonts are considered invalid under this condition. */ - /* */ - FT_EXPORT( FT_UInt ) - FT_Get_Char_Index( FT_Face face, - FT_ULong charcode ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_First_Char */ - /* */ - /* <Description> */ - /* This function is used to return the first character code in the */ - /* current charmap of a given face. It also returns the */ - /* corresponding glyph index. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Output> */ - /* agindex :: Glyph index of first character code. 0~if charmap is */ - /* empty. */ - /* */ - /* <Return> */ - /* The charmap's first character code. */ - /* */ - /* <Note> */ - /* You should use this function with @FT_Get_Next_Char to be able to */ - /* parse all character codes available in a given charmap. The code */ - /* should look like this: */ - /* */ - /* { */ - /* FT_ULong charcode; */ - /* FT_UInt gindex; */ - /* */ - /* */ - /* charcode = FT_Get_First_Char( face, &gindex ); */ - /* while ( gindex != 0 ) */ - /* { */ - /* ... do something with (charcode,gindex) pair ... */ - /* */ - /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ - /* } */ - /* } */ - /* */ - /* Note that `*agindex' is set to~0 if the charmap is empty. The */ - /* result itself can be~0 in two cases: if the charmap is empty or */ - /* if the value~0 is the first valid character code. */ - /* */ - FT_EXPORT( FT_ULong ) - FT_Get_First_Char( FT_Face face, - FT_UInt *agindex ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Next_Char */ - /* */ - /* <Description> */ - /* This function is used to return the next character code in the */ - /* current charmap of a given face following the value `char_code', */ - /* as well as the corresponding glyph index. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* char_code :: The starting character code. */ - /* */ - /* <Output> */ - /* agindex :: Glyph index of next character code. 0~if charmap */ - /* is empty. */ - /* */ - /* <Return> */ - /* The charmap's next character code. */ - /* */ - /* <Note> */ - /* You should use this function with @FT_Get_First_Char to walk */ - /* over all character codes available in a given charmap. See the */ - /* note for this function for a simple code example. */ - /* */ - /* Note that `*agindex' is set to~0 when there are no more codes in */ - /* the charmap. */ - /* */ - FT_EXPORT( FT_ULong ) - FT_Get_Next_Char( FT_Face face, - FT_ULong char_code, - FT_UInt *agindex ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Name_Index */ - /* */ - /* <Description> */ - /* Return the glyph index of a given glyph name. This function uses */ - /* driver specific objects to do the translation. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* glyph_name :: The glyph name. */ - /* */ - /* <Return> */ - /* The glyph index. 0~means `undefined character code'. */ - /* */ - FT_EXPORT( FT_UInt ) - FT_Get_Name_Index( FT_Face face, - FT_String* glyph_name ); - - - /************************************************************************* - * - * @macro: - * FT_SUBGLYPH_FLAG_XXX - * - * @description: - * A list of constants used to describe subglyphs. Please refer to the - * TrueType specification for the meaning of the various flags. - * - * @values: - * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: - * FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES :: - * FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID :: - * FT_SUBGLYPH_FLAG_SCALE :: - * FT_SUBGLYPH_FLAG_XY_SCALE :: - * FT_SUBGLYPH_FLAG_2X2 :: - * FT_SUBGLYPH_FLAG_USE_MY_METRICS :: - * - */ -#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 -#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 -#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 -#define FT_SUBGLYPH_FLAG_SCALE 8 -#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 -#define FT_SUBGLYPH_FLAG_2X2 0x80 -#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 - - - /************************************************************************* - * - * @func: - * FT_Get_SubGlyph_Info - * - * @description: - * Retrieve a description of a given subglyph. Only use it if - * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is - * returned otherwise. - * - * @input: - * glyph :: - * The source glyph slot. - * - * sub_index :: - * The index of the subglyph. Must be less than - * `glyph->num_subglyphs'. - * - * @output: - * p_index :: - * The glyph index of the subglyph. - * - * p_flags :: - * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. - * - * p_arg1 :: - * The subglyph's first argument (if any). - * - * p_arg2 :: - * The subglyph's second argument (if any). - * - * p_transform :: - * The subglyph transformation (if any). - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be - * interpreted depending on the flags returned in `*p_flags'. See the - * TrueType specification for details. - * - */ - FT_EXPORT( FT_Error ) - FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, - FT_UInt sub_index, - FT_Int *p_index, - FT_UInt *p_flags, - FT_Int *p_arg1, - FT_Int *p_arg2, - FT_Matrix *p_transform ); - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_FSTYPE_XXX */ - /* */ - /* <Description> */ - /* A list of bit flags used in the `fsType' field of the OS/2 table */ - /* in a TrueType or OpenType font and the `FSType' entry in a */ - /* PostScript font. These bit flags are returned by */ - /* @FT_Get_FSType_Flags; they inform client applications of embedding */ - /* and subsetting restrictions associated with a font. */ - /* */ - /* See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for */ - /* more details. */ - /* */ - /* <Values> */ - /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ - /* Fonts with no fsType bit set may be embedded and permanently */ - /* installed on the remote system by an application. */ - /* */ - /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ - /* Fonts that have only this bit set must not be modified, embedded */ - /* or exchanged in any manner without first obtaining permission of */ - /* the font software copyright owner. */ - /* */ - /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ - /* If this bit is set, the font may be embedded and temporarily */ - /* loaded on the remote system. Documents containing Preview & */ - /* Print fonts must be opened `read-only'; no edits can be applied */ - /* to the document. */ - /* */ - /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ - /* If this bit is set, the font may be embedded but must only be */ - /* installed temporarily on other systems. In contrast to Preview */ - /* & Print fonts, documents containing editable fonts may be opened */ - /* for reading, editing is permitted, and changes may be saved. */ - /* */ - /* FT_FSTYPE_NO_SUBSETTING :: */ - /* If this bit is set, the font may not be subsetted prior to */ - /* embedding. */ - /* */ - /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ - /* If this bit is set, only bitmaps contained in the font may be */ - /* embedded; no outline data may be embedded. If there are no */ - /* bitmaps available in the font, then the font is unembeddable. */ - /* */ - /* <Note> */ - /* While the fsType flags can indicate that a font may be embedded, a */ - /* license with the font vendor may be separately required to use the */ - /* font in this way. */ - /* */ -#define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 -#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 -#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 -#define FT_FSTYPE_EDITABLE_EMBEDDING 0x0008 -#define FT_FSTYPE_NO_SUBSETTING 0x0100 -#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_FSType_Flags */ - /* */ - /* <Description> */ - /* Return the fsType flags for a font. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Return> */ - /* The fsType flags, @FT_FSTYPE_XXX. */ - /* */ - /* <Note> */ - /* Use this function rather than directly reading the `fs_type' field */ - /* in the @PS_FontInfoRec structure which is only guaranteed to */ - /* return the correct results for Type~1 fonts. */ - /* */ - /* <Since> */ - /* 2.3.8 */ - /* */ - FT_EXPORT( FT_UShort ) - FT_Get_FSType_Flags( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* glyph_variants */ - /* */ - /* <Title> */ - /* Glyph Variants */ - /* */ - /* <Abstract> */ - /* The FreeType~2 interface to Unicode Ideographic Variation */ - /* Sequences (IVS), using the SFNT cmap format~14. */ - /* */ - /* <Description> */ - /* Many CJK characters have variant forms. They are a sort of grey */ - /* area somewhere between being totally irrelevant and semantically */ - /* distinct; for this reason, the Unicode consortium decided to */ - /* introduce Ideographic Variation Sequences (IVS), consisting of a */ - /* Unicode base character and one of 240 variant selectors */ - /* (U+E0100-U+E01EF), instead of further extending the already huge */ - /* code range for CJK characters. */ - /* */ - /* An IVS is registered and unique; for further details please refer */ - /* to Unicode Technical Standard #37, the Ideographic Variation */ - /* Database: */ - /* */ - /* http://www.unicode.org/reports/tr37/ */ - /* */ - /* To date (November 2012), the character with the most variants is */ - /* U+9089, having 31 such IVS. */ - /* */ - /* Adobe and MS decided to support IVS with a new cmap subtable */ - /* (format~14). It is an odd subtable because it is not a mapping of */ - /* input code points to glyphs, but contains lists of all variants */ - /* supported by the font. */ - /* */ - /* A variant may be either `default' or `non-default'. A default */ - /* variant is the one you will get for that code point if you look it */ - /* up in the standard Unicode cmap. A non-default variant is a */ - /* different glyph. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetCharVariantIndex */ - /* */ - /* <Description> */ - /* Return the glyph index of a given character code as modified by */ - /* the variation selector. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* charcode :: */ - /* The character code point in Unicode. */ - /* */ - /* variantSelector :: */ - /* The Unicode code point of the variation selector. */ - /* */ - /* <Return> */ - /* The glyph index. 0~means either `undefined character code', or */ - /* `undefined selector code', or `no variation selector cmap */ - /* subtable', or `current CharMap is not Unicode'. */ - /* */ - /* <Note> */ - /* If you use FreeType to manipulate the contents of font files */ - /* directly, be aware that the glyph index returned by this function */ - /* doesn't always correspond to the internal indices used within */ - /* the file. This is done to ensure that value~0 always corresponds */ - /* to the `missing glyph'. */ - /* */ - /* This function is only meaningful if */ - /* a) the font has a variation selector cmap sub table, */ - /* and */ - /* b) the current charmap has a Unicode encoding. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ - FT_EXPORT( FT_UInt ) - FT_Face_GetCharVariantIndex( FT_Face face, - FT_ULong charcode, - FT_ULong variantSelector ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetCharVariantIsDefault */ - /* */ - /* <Description> */ - /* Check whether this variant of this Unicode character is the one to */ - /* be found in the `cmap'. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* charcode :: */ - /* The character codepoint in Unicode. */ - /* */ - /* variantSelector :: */ - /* The Unicode codepoint of the variation selector. */ - /* */ - /* <Return> */ - /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ - /* variation selector cmap, or -1 if it is not a variant. */ - /* */ - /* <Note> */ - /* This function is only meaningful if the font has a variation */ - /* selector cmap subtable. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ - FT_EXPORT( FT_Int ) - FT_Face_GetCharVariantIsDefault( FT_Face face, - FT_ULong charcode, - FT_ULong variantSelector ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetVariantSelectors */ - /* */ - /* <Description> */ - /* Return a zero-terminated list of Unicode variant selectors found */ - /* in the font. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* <Return> */ - /* A pointer to an array of selector code points, or NULL if there is */ - /* no valid variant selector cmap subtable. */ - /* */ - /* <Note> */ - /* The last item in the array is~0; the array is owned by the */ - /* @FT_Face object but can be overwritten or released on the next */ - /* call to a FreeType function. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ - FT_EXPORT( FT_UInt32* ) - FT_Face_GetVariantSelectors( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetVariantsOfChar */ - /* */ - /* <Description> */ - /* Return a zero-terminated list of Unicode variant selectors found */ - /* for the specified character code. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* charcode :: */ - /* The character codepoint in Unicode. */ - /* */ - /* <Return> */ - /* A pointer to an array of variant selector code points which are */ - /* active for the given character, or NULL if the corresponding list */ - /* is empty. */ - /* */ - /* <Note> */ - /* The last item in the array is~0; the array is owned by the */ - /* @FT_Face object but can be overwritten or released on the next */ - /* call to a FreeType function. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ - FT_EXPORT( FT_UInt32* ) - FT_Face_GetVariantsOfChar( FT_Face face, - FT_ULong charcode ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetCharsOfVariant */ - /* */ - /* <Description> */ - /* Return a zero-terminated list of Unicode character codes found for */ - /* the specified variant selector. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* variantSelector :: */ - /* The variant selector code point in Unicode. */ - /* */ - /* <Return> */ - /* A list of all the code points which are specified by this selector */ - /* (both default and non-default codes are returned) or NULL if there */ - /* is no valid cmap or the variant selector is invalid. */ - /* */ - /* <Note> */ - /* The last item in the array is~0; the array is owned by the */ - /* @FT_Face object but can be overwritten or released on the next */ - /* call to a FreeType function. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ - FT_EXPORT( FT_UInt32* ) - FT_Face_GetCharsOfVariant( FT_Face face, - FT_ULong variantSelector ); - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* computations */ - /* */ - /* <Title> */ - /* Computations */ - /* */ - /* <Abstract> */ - /* Crunching fixed numbers and vectors. */ - /* */ - /* <Description> */ - /* This section contains various functions used to perform */ - /* computations on 16.16 fixed-float numbers or 2d vectors. */ - /* */ - /* <Order> */ - /* FT_MulDiv */ - /* FT_MulFix */ - /* FT_DivFix */ - /* FT_RoundFix */ - /* FT_CeilFix */ - /* FT_FloorFix */ - /* FT_Vector_Transform */ - /* FT_Matrix_Multiply */ - /* FT_Matrix_Invert */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_MulDiv */ - /* */ - /* <Description> */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* with maximum accuracy (it uses a 64-bit intermediate integer */ - /* whenever necessary). */ - /* */ - /* This function isn't necessarily as fast as some processor specific */ - /* operations, but is at least completely portable. */ - /* */ - /* <Input> */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. */ - /* c :: The divisor. */ - /* */ - /* <Return> */ - /* The result of `(a*b)/c'. This function never traps when trying to */ - /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ - /* on the signs of `a' and `b'. */ - /* */ - FT_EXPORT( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ); - - - /* */ - - /* The following #if 0 ... #endif is for the documentation formatter, */ - /* hiding the internal `FT_MULFIX_INLINED' macro. */ - -#if 0 - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_MulFix */ - /* */ - /* <Description> */ - /* A very simple function used to perform the computation */ - /* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */ - /* used to multiply a given value by a 16.16 fixed-point factor. */ - /* */ - /* <Input> */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* <Return> */ - /* The result of `(a*b)/0x10000'. */ - /* */ - /* <Note> */ - /* This function has been optimized for the case where the absolute */ - /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ - /* As this happens mainly when scaling from notional units to */ - /* fractional pixels in FreeType, it resulted in noticeable speed */ - /* improvements between versions 2.x and 1.x. */ - /* */ - /* As a conclusion, always try to place a 16.16 factor as the */ - /* _second_ argument of this function; this can make a great */ - /* difference. */ - /* */ - FT_EXPORT( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ); - - /* */ -#endif - -#ifdef FT_MULFIX_INLINED -#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b ) -#else - FT_EXPORT( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ); -#endif - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_DivFix */ - /* */ - /* <Description> */ - /* A very simple function used to perform the computation */ - /* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */ - /* used to divide a given value by a 16.16 fixed-point factor. */ - /* */ - /* <Input> */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* <Return> */ - /* The result of `(a*0x10000)/b'. */ - /* */ - /* <Note> */ - /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ - /* 32~bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of @FT_MulDiv. */ - /* */ - FT_EXPORT( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_RoundFix */ - /* */ - /* <Description> */ - /* A very simple function used to round a 16.16 fixed number. */ - /* */ - /* <Input> */ - /* a :: The number to be rounded. */ - /* */ - /* <Return> */ - /* The result of `(a + 0x8000) & -0x10000'. */ - /* */ - FT_EXPORT( FT_Fixed ) - FT_RoundFix( FT_Fixed a ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_CeilFix */ - /* */ - /* <Description> */ - /* A very simple function used to compute the ceiling function of a */ - /* 16.16 fixed number. */ - /* */ - /* <Input> */ - /* a :: The number for which the ceiling function is to be computed. */ - /* */ - /* <Return> */ - /* The result of `(a + 0x10000 - 1) & -0x10000'. */ - /* */ - FT_EXPORT( FT_Fixed ) - FT_CeilFix( FT_Fixed a ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_FloorFix */ - /* */ - /* <Description> */ - /* A very simple function used to compute the floor function of a */ - /* 16.16 fixed number. */ - /* */ - /* <Input> */ - /* a :: The number for which the floor function is to be computed. */ - /* */ - /* <Return> */ - /* The result of `a & -0x10000'. */ - /* */ - FT_EXPORT( FT_Fixed ) - FT_FloorFix( FT_Fixed a ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Vector_Transform */ - /* */ - /* <Description> */ - /* Transform a single vector through a 2x2 matrix. */ - /* */ - /* <InOut> */ - /* vector :: The target vector to transform. */ - /* */ - /* <Input> */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* <Note> */ - /* The result is undefined if either `vector' or `matrix' is invalid. */ - /* */ - FT_EXPORT( void ) - FT_Vector_Transform( FT_Vector* vec, - const FT_Matrix* matrix ); - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* version */ - /* */ - /* <Title> */ - /* FreeType Version */ - /* */ - /* <Abstract> */ - /* Functions and macros related to FreeType versions. */ - /* */ - /* <Description> */ - /* Note that those functions and macros are of limited use because */ - /* even a new release of FreeType with only documentation changes */ - /* increases the version number. */ - /* */ - /*************************************************************************/ - - - /************************************************************************* - * - * @enum: - * FREETYPE_XXX - * - * @description: - * These three macros identify the FreeType source code version. - * Use @FT_Library_Version to access them at runtime. - * - * @values: - * FREETYPE_MAJOR :: The major version number. - * FREETYPE_MINOR :: The minor version number. - * FREETYPE_PATCH :: The patch level. - * - * @note: - * The version number of FreeType if built as a dynamic link library - * with the `libtool' package is _not_ controlled by these three - * macros. - * - */ -#define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 5 -#define FREETYPE_PATCH 0 - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Library_Version */ - /* */ - /* <Description> */ - /* Return the version of the FreeType library being used. This is */ - /* useful when dynamically linking to the library, since one cannot */ - /* use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and */ - /* @FREETYPE_PATCH. */ - /* */ - /* <Input> */ - /* library :: A source library handle. */ - /* */ - /* <Output> */ - /* amajor :: The major version number. */ - /* */ - /* aminor :: The minor version number. */ - /* */ - /* apatch :: The patch version number. */ - /* */ - /* <Note> */ - /* The reason why this function takes a `library' argument is because */ - /* certain programs implement library initialization in a custom way */ - /* that doesn't use @FT_Init_FreeType. */ - /* */ - /* In such cases, the library version might not be available before */ - /* the library object has been created. */ - /* */ - FT_EXPORT( void ) - FT_Library_Version( FT_Library library, - FT_Int *amajor, - FT_Int *aminor, - FT_Int *apatch ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_CheckTrueTypePatents */ - /* */ - /* <Description> */ - /* Parse all bytecode instructions of a TrueType font file to check */ - /* whether any of the patented opcodes are used. This is only useful */ - /* if you want to be able to use the unpatented hinter with */ - /* fonts that do *not* use these opcodes. */ - /* */ - /* Note that this function parses *all* glyph instructions in the */ - /* font file, which may be slow. */ - /* */ - /* <Input> */ - /* face :: A face handle. */ - /* */ - /* <Return> */ - /* 1~if this is a TrueType font that uses one of the patented */ - /* opcodes, 0~otherwise. */ - /* */ - /* <Note> */ - /* Since May 2010, TrueType hinting is no longer patented. */ - /* */ - /* <Since> */ - /* 2.3.5 */ - /* */ - FT_EXPORT( FT_Bool ) - FT_Face_CheckTrueTypePatents( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_SetUnpatentedHinting */ - /* */ - /* <Description> */ - /* Enable or disable the unpatented hinter for a given face. */ - /* Only enable it if you have determined that the face doesn't */ - /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ - /* */ - /* <Input> */ - /* face :: A face handle. */ - /* */ - /* value :: New boolean setting. */ - /* */ - /* <Return> */ - /* The old setting value. This will always be false if this is not */ - /* an SFNT font, or if the unpatented hinter is not compiled in this */ - /* instance of the library. */ - /* */ - /* <Note> */ - /* Since May 2010, TrueType hinting is no longer patented. */ - /* */ - /* <Since> */ - /* 2.3.5 */ - /* */ - FT_EXPORT( FT_Bool ) - FT_Face_SetUnpatentedHinting( FT_Face face, - FT_Bool value ); - - /* */ - - -FT_END_HEADER - -#endif /* __FREETYPE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftadvanc.h b/drivers/freetype/freetype/include/freetype/ftadvanc.h deleted file mode 100644 index 012b74b812..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftadvanc.h +++ /dev/null @@ -1,182 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftadvanc.h */ -/* */ -/* Quick computation of advance widths (specification only). */ -/* */ -/* Copyright 2008, 2013 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 __FTADVANC_H__ -#define __FTADVANC_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /************************************************************************** - * - * @section: - * quick_advance - * - * @title: - * Quick retrieval of advance values - * - * @abstract: - * Retrieve horizontal and vertical advance values without processing - * glyph outlines, if possible. - * - * @description: - * This section contains functions to quickly extract advance values - * without handling glyph outlines, if possible. - */ - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* FT_ADVANCE_FLAG_FAST_ONLY */ - /* */ - /* <Description> */ - /* A bit-flag to be OR-ed with the `flags' parameter of the */ - /* @FT_Get_Advance and @FT_Get_Advances functions. */ - /* */ - /* If set, it indicates that you want these functions to fail if the */ - /* corresponding hinting mode or font driver doesn't allow for very */ - /* quick advance computation. */ - /* */ - /* Typically, glyphs which are either unscaled, unhinted, bitmapped, */ - /* or light-hinted can have their advance width computed very */ - /* quickly. */ - /* */ - /* Normal and bytecode hinted modes, which require loading, scaling, */ - /* and hinting of the glyph outline, are extremely slow by */ - /* comparison. */ - /* */ -#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000UL - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Advance */ - /* */ - /* <Description> */ - /* Retrieve the advance value of a given glyph outline in an */ - /* @FT_Face. */ - /* */ - /* <Input> */ - /* face :: The source @FT_Face handle. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* load_flags :: A set of bit flags similar to those used when */ - /* calling @FT_Load_Glyph, used to determine what kind */ - /* of advances you need. */ - /* <Output> */ - /* padvance :: The advance value. If scaling is performed (based on */ - /* the value of `load_flags'), the advance value is in */ - /* 16.16 format. Otherwise, it is in font units. */ - /* */ - /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ - /* vertical advance corresponding to a vertical layout. */ - /* Otherwise, it is the horizontal advance in a */ - /* horizontal layout. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ - /* if the corresponding font backend doesn't have a quick way to */ - /* retrieve the advances. */ - /* */ - /* A scaled advance is returned in 16.16 format but isn't transformed */ - /* by the affine transformation specified by @FT_Set_Transform. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_Advance( FT_Face face, - FT_UInt gindex, - FT_Int32 load_flags, - FT_Fixed *padvance ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Advances */ - /* */ - /* <Description> */ - /* Retrieve the advance values of several glyph outlines in an */ - /* @FT_Face. */ - /* */ - /* <Input> */ - /* face :: The source @FT_Face handle. */ - /* */ - /* start :: The first glyph index. */ - /* */ - /* count :: The number of advance values you want to retrieve. */ - /* */ - /* load_flags :: A set of bit flags similar to those used when */ - /* calling @FT_Load_Glyph. */ - /* */ - /* <Output> */ - /* padvance :: The advance values. This array, to be provided by the */ - /* caller, must contain at least `count' elements. */ - /* */ - /* If scaling is performed (based on the value of */ - /* `load_flags'), the advance values are in 16.16 format. */ - /* Otherwise, they are in font units. */ - /* */ - /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ - /* vertical advances corresponding to a vertical layout. */ - /* Otherwise, they are the horizontal advances in a */ - /* horizontal layout. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ - /* if the corresponding font backend doesn't have a quick way to */ - /* retrieve the advances. */ - /* */ - /* Scaled advances are returned in 16.16 format but aren't */ - /* transformed by the affine transformation specified by */ - /* @FT_Set_Transform. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_Advances( FT_Face face, - FT_UInt start, - FT_UInt count, - FT_Int32 load_flags, - FT_Fixed *padvances ); - -/* */ - - -FT_END_HEADER - -#endif /* __FTADVANC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftautoh.h b/drivers/freetype/freetype/include/freetype/ftautoh.h deleted file mode 100644 index 5e1153a1c1..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftautoh.h +++ /dev/null @@ -1,357 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftautoh.h */ -/* */ -/* FreeType API for controlling the auto-hinter (specification only). */ -/* */ -/* Copyright 2012, 2013 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 __FTAUTOH_H__ -#define __FTAUTOH_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /************************************************************************** - * - * @section: - * auto_hinter - * - * @title: - * The auto-hinter - * - * @abstract: - * Controlling the auto-hinting module. - * - * @description: - * While FreeType's auto-hinter doesn't expose API functions by itself, - * it is possible to control its behaviour with @FT_Property_Set and - * @FT_Property_Get. The following lists the available properties - * together with the necessary macros and structures. - * - * Note that the auto-hinter's module name is `autofitter' for - * historical reasons. - * - */ - - - /************************************************************************** - * - * @property: - * glyph-to-script-map - * - * @description: - * *Experimental* *only* - * - * The auto-hinter provides various script modules to hint glyphs. - * Examples of supported scripts are Latin or CJK. Before a glyph is - * auto-hinted, the Unicode character map of the font gets examined, and - * the script is then determined based on Unicode character ranges, see - * below. - * - * OpenType fonts, however, often provide much more glyphs than - * character codes (small caps, superscripts, ligatures, swashes, etc.), - * to be controlled by so-called `features'. Handling OpenType features - * can be quite complicated and thus needs a separate library on top of - * FreeType. - * - * The mapping between glyph indices and scripts (in the auto-hinter - * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an - * array with `num_glyphs' elements, as found in the font's @FT_Face - * structure. The `glyph-to-script-map' property returns a pointer to - * this array which can be modified as needed. Note that the - * modification should happen before the first glyph gets processed by - * the auto-hinter so that the global analysis of the font shapes - * actually uses the modified mapping. - * - * The following example code demonstrates how to access it (omitting - * the error handling). - * - * { - * FT_Library library; - * FT_Face face; - * FT_Prop_GlyphToScriptMap prop; - * - * - * FT_Init_FreeType( &library ); - * FT_New_Face( library, "foo.ttf", 0, &face ); - * - * prop.face = face; - * - * FT_Property_Get( library, "autofitter", - * "glyph-to-script-map", &prop ); - * - * // adjust `prop.map' as needed right here - * - * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT ); - * } - * - */ - - - /************************************************************************** - * - * @enum: - * FT_AUTOHINTER_SCRIPT_XXX - * - * @description: - * *Experimental* *only* - * - * A list of constants used for the @glyph-to-script-map property to - * specify the script submodule the auto-hinter should use for hinting a - * particular glyph. - * - * @values: - * FT_AUTOHINTER_SCRIPT_NONE :: - * Don't auto-hint this glyph. - * - * FT_AUTOHINTER_SCRIPT_LATIN :: - * Apply the latin auto-hinter. For the auto-hinter, `latin' is a - * very broad term, including Cyrillic and Greek also since characters - * from those scripts share the same design constraints. - * - * By default, characters from the following Unicode ranges are - * assigned to this submodule. - * - * { - * U+0020 - U+007F // Basic Latin (no control characters) - * U+00A0 - U+00FF // Latin-1 Supplement (no control characters) - * U+0100 - U+017F // Latin Extended-A - * U+0180 - U+024F // Latin Extended-B - * U+0250 - U+02AF // IPA Extensions - * U+02B0 - U+02FF // Spacing Modifier Letters - * U+0300 - U+036F // Combining Diacritical Marks - * U+0370 - U+03FF // Greek and Coptic - * U+0400 - U+04FF // Cyrillic - * U+0500 - U+052F // Cyrillic Supplement - * U+1D00 - U+1D7F // Phonetic Extensions - * U+1D80 - U+1DBF // Phonetic Extensions Supplement - * U+1DC0 - U+1DFF // Combining Diacritical Marks Supplement - * U+1E00 - U+1EFF // Latin Extended Additional - * U+1F00 - U+1FFF // Greek Extended - * U+2000 - U+206F // General Punctuation - * U+2070 - U+209F // Superscripts and Subscripts - * U+20A0 - U+20CF // Currency Symbols - * U+2150 - U+218F // Number Forms - * U+2460 - U+24FF // Enclosed Alphanumerics - * U+2C60 - U+2C7F // Latin Extended-C - * U+2DE0 - U+2DFF // Cyrillic Extended-A - * U+2E00 - U+2E7F // Supplemental Punctuation - * U+A640 - U+A69F // Cyrillic Extended-B - * U+A720 - U+A7FF // Latin Extended-D - * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligatures) - * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols - * U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement - * } - * - * FT_AUTOHINTER_SCRIPT_CJK :: - * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old - * Vietnamese, and some other scripts. - * - * By default, characters from the following Unicode ranges are - * assigned to this submodule. - * - * { - * U+1100 - U+11FF // Hangul Jamo - * U+2E80 - U+2EFF // CJK Radicals Supplement - * U+2F00 - U+2FDF // Kangxi Radicals - * U+2FF0 - U+2FFF // Ideographic Description Characters - * U+3000 - U+303F // CJK Symbols and Punctuation - * U+3040 - U+309F // Hiragana - * U+30A0 - U+30FF // Katakana - * U+3100 - U+312F // Bopomofo - * U+3130 - U+318F // Hangul Compatibility Jamo - * U+3190 - U+319F // Kanbun - * U+31A0 - U+31BF // Bopomofo Extended - * U+31C0 - U+31EF // CJK Strokes - * U+31F0 - U+31FF // Katakana Phonetic Extensions - * U+3200 - U+32FF // Enclosed CJK Letters and Months - * U+3300 - U+33FF // CJK Compatibility - * U+3400 - U+4DBF // CJK Unified Ideographs Extension A - * U+4DC0 - U+4DFF // Yijing Hexagram Symbols - * U+4E00 - U+9FFF // CJK Unified Ideographs - * U+A960 - U+A97F // Hangul Jamo Extended-A - * U+AC00 - U+D7AF // Hangul Syllables - * U+D7B0 - U+D7FF // Hangul Jamo Extended-B - * U+F900 - U+FAFF // CJK Compatibility Ideographs - * U+FE10 - U+FE1F // Vertical forms - * U+FE30 - U+FE4F // CJK Compatibility Forms - * U+FF00 - U+FFEF // Halfwidth and Fullwidth Forms - * U+1B000 - U+1B0FF // Kana Supplement - * U+1D300 - U+1D35F // Tai Xuan Hing Symbols - * U+1F200 - U+1F2FF // Enclosed Ideographic Supplement - * U+20000 - U+2A6DF // CJK Unified Ideographs Extension B - * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C - * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D - * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement - * } - * - * FT_AUTOHINTER_SCRIPT_INDIC :: - * Apply the indic auto-hinter, covering all major scripts from the - * Indian sub-continent and some other related scripts like Thai, Lao, - * or Tibetan. - * - * By default, characters from the following Unicode ranges are - * assigned to this submodule. - * - * { - * U+0900 - U+0DFF // Indic Range - * U+0F00 - U+0FFF // Tibetan - * U+1900 - U+194F // Limbu - * U+1B80 - U+1BBF // Sundanese - * U+1C80 - U+1CDF // Meetei Mayak - * U+A800 - U+A82F // Syloti Nagri - * U+11800 - U+118DF // Sharada - * } - * - * Note that currently Indic support is rudimentary only, missing blue - * zone support. - * - */ -#define FT_AUTOHINTER_SCRIPT_NONE 0 -#define FT_AUTOHINTER_SCRIPT_LATIN 1 -#define FT_AUTOHINTER_SCRIPT_CJK 2 -#define FT_AUTOHINTER_SCRIPT_INDIC 3 - - - /************************************************************************** - * - * @struct: - * FT_Prop_GlyphToScriptMap - * - * @description: - * *Experimental* *only* - * - * The data exchange structure for the @glyph-to-script-map property. - * - */ - typedef struct FT_Prop_GlyphToScriptMap_ - { - FT_Face face; - FT_Byte* map; - - } FT_Prop_GlyphToScriptMap; - - - /************************************************************************** - * - * @property: - * fallback-script - * - * @description: - * *Experimental* *only* - * - * If no auto-hinter script module can be assigned to a glyph, a - * fallback script gets assigned to it (see also the - * @glyph-to-script-map property). By default, this is - * @FT_AUTOHINTER_SCRIPT_CJK. Using the `fallback-script' property, - * this fallback value can be changed. - * - * { - * FT_Library library; - * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "autofitter", - * "fallback-script", &fallback_script ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - * It's important to use the right timing for changing this value: The - * creation of the glyph-to-script map which eventually uses the - * fallback script value gets triggered either by setting or reading a - * face-specific property like @glyph-to-script-map, or by auto-hinting - * any glyph from that face. In particular, if you have already created - * an @FT_Face structure but not loaded any glyph (using the - * auto-hinter), a change of the fallback glyph will affect this face. - * - */ - - - /************************************************************************** - * - * @property: - * increase-x-height - * - * @description: - * For ppem values in the range 6~<= ppem <= `increase-x-height', round - * up the font's x~height much more often than normally. If the value - * is set to~0, which is the default, this feature is switched off. Use - * this property to improve the legibility of small font sizes if - * necessary. - * - * { - * FT_Library library; - * FT_Face face; - * FT_Prop_IncreaseXHeight prop; - * - * - * FT_Init_FreeType( &library ); - * FT_New_Face( library, "foo.ttf", 0, &face ); - * FT_Set_Char_Size( face, 10 * 64, 0, 72, 0 ); - * - * prop.face = face; - * prop.limit = 14; - * - * FT_Property_Set( library, "autofitter", - * "increase-x-height", &prop ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - * Set this value right after calling @FT_Set_Char_Size, but before - * loading any glyph (using the auto-hinter). - * - */ - - - /************************************************************************** - * - * @struct: - * FT_Prop_IncreaseXHeight - * - * @description: - * The data exchange structure for the @increase-x-height property. - * - */ - typedef struct FT_Prop_IncreaseXHeight_ - { - FT_Face face; - FT_UInt limit; - - } FT_Prop_IncreaseXHeight; - - - /* */ - -FT_END_HEADER - -#endif /* __FTAUTOH_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftbbox.h b/drivers/freetype/freetype/include/freetype/ftbbox.h deleted file mode 100644 index 976691956f..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftbbox.h +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbbox.h */ -/* */ -/* FreeType exact bbox computation (specification). */ -/* */ -/* Copyright 1996-2001, 2003, 2007, 2011 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This component has a _single_ role: to compute exact outline bounding */ - /* boxes. */ - /* */ - /* It is separated from the rest of the engine for various technical */ - /* reasons. It may well be integrated in `ftoutln' later. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTBBOX_H__ -#define __FTBBOX_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* outline_processing */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Get_BBox */ - /* */ - /* <Description> */ - /* Compute the exact bounding box of an outline. This is slower */ - /* than computing the control box. However, it uses an advanced */ - /* algorithm which returns _very_ quickly when the two boxes */ - /* coincide. Otherwise, the outline Bézier arcs are traversed to */ - /* extract their extrema. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source outline. */ - /* */ - /* <Output> */ - /* abbox :: The outline's exact bounding box. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* If the font is tricky and the glyph has been loaded with */ - /* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */ - /* reasonable values for the BBox it is necessary to load the glyph */ - /* at a large ppem value (so that the hinting instructions can */ - /* properly shift and scale the subglyphs), then extracting the BBox */ - /* which can be eventually converted back to font units. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_Get_BBox( FT_Outline* outline, - FT_BBox *abbox ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTBBOX_H__ */ - - -/* END */ - - -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ diff --git a/drivers/freetype/freetype/include/freetype/ftbdf.h b/drivers/freetype/freetype/include/freetype/ftbdf.h deleted file mode 100644 index 4f8baf8401..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftbdf.h +++ /dev/null @@ -1,209 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbdf.h */ -/* */ -/* FreeType API for accessing BDF-specific strings (specification). */ -/* */ -/* Copyright 2002, 2003, 2004, 2006, 2009 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 __FTBDF_H__ -#define __FTBDF_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* bdf_fonts */ - /* */ - /* <Title> */ - /* BDF and PCF Files */ - /* */ - /* <Abstract> */ - /* BDF and PCF specific API. */ - /* */ - /* <Description> */ - /* This section contains the declaration of functions specific to BDF */ - /* and PCF fonts. */ - /* */ - /*************************************************************************/ - - - /********************************************************************** - * - * @enum: - * FT_PropertyType - * - * @description: - * A list of BDF property types. - * - * @values: - * BDF_PROPERTY_TYPE_NONE :: - * Value~0 is used to indicate a missing property. - * - * BDF_PROPERTY_TYPE_ATOM :: - * Property is a string atom. - * - * BDF_PROPERTY_TYPE_INTEGER :: - * Property is a 32-bit signed integer. - * - * BDF_PROPERTY_TYPE_CARDINAL :: - * Property is a 32-bit unsigned integer. - */ - typedef enum BDF_PropertyType_ - { - BDF_PROPERTY_TYPE_NONE = 0, - BDF_PROPERTY_TYPE_ATOM = 1, - BDF_PROPERTY_TYPE_INTEGER = 2, - BDF_PROPERTY_TYPE_CARDINAL = 3 - - } BDF_PropertyType; - - - /********************************************************************** - * - * @type: - * BDF_Property - * - * @description: - * A handle to a @BDF_PropertyRec structure to model a given - * BDF/PCF property. - */ - typedef struct BDF_PropertyRec_* BDF_Property; - - - /********************************************************************** - * - * @struct: - * BDF_PropertyRec - * - * @description: - * This structure models a given BDF/PCF property. - * - * @fields: - * type :: - * The property type. - * - * u.atom :: - * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. - * - * u.integer :: - * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. - * - * u.cardinal :: - * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. - */ - typedef struct BDF_PropertyRec_ - { - BDF_PropertyType type; - union { - const char* atom; - FT_Int32 integer; - FT_UInt32 cardinal; - - } u; - - } BDF_PropertyRec; - - - /********************************************************************** - * - * @function: - * FT_Get_BDF_Charset_ID - * - * @description: - * Retrieve a BDF font character set identity, according to - * the BDF specification. - * - * @input: - * face :: - * A handle to the input face. - * - * @output: - * acharset_encoding :: - * Charset encoding, as a C~string, owned by the face. - * - * acharset_registry :: - * Charset registry, as a C~string, owned by the face. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with BDF faces, returning an error otherwise. - */ - FT_EXPORT( FT_Error ) - FT_Get_BDF_Charset_ID( FT_Face face, - const char* *acharset_encoding, - const char* *acharset_registry ); - - - /********************************************************************** - * - * @function: - * FT_Get_BDF_Property - * - * @description: - * Retrieve a BDF property from a BDF or PCF font file. - * - * @input: - * face :: A handle to the input face. - * - * name :: The property name. - * - * @output: - * aproperty :: The property. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function works with BDF _and_ PCF fonts. It returns an error - * otherwise. It also returns an error if the property is not in the - * font. - * - * A `property' is a either key-value pair within the STARTPROPERTIES - * ... ENDPROPERTIES block of a BDF font or a key-value pair from the - * `info->props' array within a `FontRec' structure of a PCF font. - * - * Integer properties are always stored as `signed' within PCF fonts; - * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value - * for BDF fonts only. - * - * In case of error, `aproperty->type' is always set to - * @BDF_PROPERTY_TYPE_NONE. - */ - FT_EXPORT( FT_Error ) - FT_Get_BDF_Property( FT_Face face, - const char* prop_name, - BDF_PropertyRec *aproperty ); - - /* */ - -FT_END_HEADER - -#endif /* __FTBDF_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftbitmap.h b/drivers/freetype/freetype/include/freetype/ftbitmap.h deleted file mode 100644 index 7dbf5ba3fe..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftbitmap.h +++ /dev/null @@ -1,227 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbitmap.h */ -/* */ -/* FreeType utility functions for bitmaps (specification). */ -/* */ -/* Copyright 2004-2006, 2008, 2013 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 __FTBITMAP_H__ -#define __FTBITMAP_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* bitmap_handling */ - /* */ - /* <Title> */ - /* Bitmap Handling */ - /* */ - /* <Abstract> */ - /* Handling FT_Bitmap objects. */ - /* */ - /* <Description> */ - /* This section contains functions for converting FT_Bitmap objects. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_New */ - /* */ - /* <Description> */ - /* Initialize a pointer to an @FT_Bitmap structure. */ - /* */ - /* <InOut> */ - /* abitmap :: A pointer to the bitmap structure. */ - /* */ - FT_EXPORT( void ) - FT_Bitmap_New( FT_Bitmap *abitmap ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Copy */ - /* */ - /* <Description> */ - /* Copy a bitmap into another one. */ - /* */ - /* <Input> */ - /* library :: A handle to a library object. */ - /* */ - /* source :: A handle to the source bitmap. */ - /* */ - /* <Output> */ - /* target :: A handle to the target bitmap. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Bitmap_Copy( FT_Library library, - const FT_Bitmap *source, - FT_Bitmap *target); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Embolden */ - /* */ - /* <Description> */ - /* Embolden a bitmap. The new bitmap will be about `xStrength' */ - /* pixels wider and `yStrength' pixels higher. The left and bottom */ - /* borders are kept unchanged. */ - /* */ - /* <Input> */ - /* library :: A handle to a library object. */ - /* */ - /* xStrength :: How strong the glyph is emboldened horizontally. */ - /* Expressed in 26.6 pixel format. */ - /* */ - /* yStrength :: How strong the glyph is emboldened vertically. */ - /* Expressed in 26.6 pixel format. */ - /* */ - /* <InOut> */ - /* bitmap :: A handle to the target bitmap. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The current implementation restricts `xStrength' to be less than */ - /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ - /* */ - /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ - /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Bitmap_Embolden( FT_Library library, - FT_Bitmap* bitmap, - FT_Pos xStrength, - FT_Pos yStrength ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Convert */ - /* */ - /* <Description> */ - /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp */ - /* to a bitmap object with depth 8bpp, making the number of used */ - /* bytes line (a.k.a. the `pitch') a multiple of `alignment'. */ - /* */ - /* <Input> */ - /* library :: A handle to a library object. */ - /* */ - /* source :: The source bitmap. */ - /* */ - /* alignment :: The pitch of the bitmap is a multiple of this */ - /* parameter. Common values are 1, 2, or 4. */ - /* */ - /* <Output> */ - /* target :: The target bitmap. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* It is possible to call @FT_Bitmap_Convert multiple times without */ - /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ - /* */ - /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ - /* */ - /* The `library' argument is taken to have access to FreeType's */ - /* memory handling functions. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Bitmap_Convert( FT_Library library, - const FT_Bitmap *source, - FT_Bitmap *target, - FT_Int alignment ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_GlyphSlot_Own_Bitmap */ - /* */ - /* <Description> */ - /* Make sure that a glyph slot owns `slot->bitmap'. */ - /* */ - /* <Input> */ - /* slot :: The glyph slot. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function is to be used in combination with */ - /* @FT_Bitmap_Embolden. */ - /* */ - FT_EXPORT( FT_Error ) - FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Done */ - /* */ - /* <Description> */ - /* Destroy a bitmap object created with @FT_Bitmap_New. */ - /* */ - /* <Input> */ - /* library :: A handle to a library object. */ - /* */ - /* bitmap :: The bitmap object to be freed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The `library' argument is taken to have access to FreeType's */ - /* memory handling functions. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Bitmap_Done( FT_Library library, - FT_Bitmap *bitmap ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTBITMAP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftbzip2.h b/drivers/freetype/freetype/include/freetype/ftbzip2.h deleted file mode 100644 index 1bf81b15e8..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftbzip2.h +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbzip2.h */ -/* */ -/* Bzip2-compressed stream support. */ -/* */ -/* Copyright 2010 by */ -/* Joel Klinghed. */ -/* */ -/* 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 __FTBZIP2_H__ -#define __FTBZIP2_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* <Section> */ - /* bzip2 */ - /* */ - /* <Title> */ - /* BZIP2 Streams */ - /* */ - /* <Abstract> */ - /* Using bzip2-compressed font files. */ - /* */ - /* <Description> */ - /* This section contains the declaration of Bzip2-specific functions. */ - /* */ - /*************************************************************************/ - - - /************************************************************************ - * - * @function: - * FT_Stream_OpenBzip2 - * - * @description: - * Open a new stream to parse bzip2-compressed font files. This is - * mainly used to support the compressed `*.pcf.bz2' fonts that come - * with XFree86. - * - * @input: - * stream :: - * The target embedding stream. - * - * source :: - * The source stream. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The source stream must be opened _before_ calling this function. - * - * Calling the internal function `FT_Stream_Close' on the new stream will - * *not* call `FT_Stream_Close' on the source stream. None of the stream - * objects will be released to the heap. - * - * The stream implementation is very basic and resets the decompression - * process each time seeking backwards is needed within the stream. - * - * In certain builds of the library, bzip2 compression recognition is - * automatically handled when calling @FT_New_Face or @FT_Open_Face. - * This means that if no font driver is capable of handling the raw - * compressed file, the library will try to open a bzip2 compressed stream - * from it and re-open the face with it. - * - * This function may return `FT_Err_Unimplemented_Feature' if your build - * of FreeType was not compiled with bzip2 support. - */ - FT_EXPORT( FT_Error ) - FT_Stream_OpenBzip2( FT_Stream stream, - FT_Stream source ); - - /* */ - - -FT_END_HEADER - -#endif /* __FTBZIP2_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftcache.h b/drivers/freetype/freetype/include/freetype/ftcache.h deleted file mode 100644 index 4ec9587cf6..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftcache.h +++ /dev/null @@ -1,1057 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcache.h */ -/* */ -/* FreeType Cache subsystem (specification). */ -/* */ -/* Copyright 1996-2008, 2010, 2013 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 __FTCACHE_H__ -#define __FTCACHE_H__ - - -#include <ft2build.h> -#include FT_GLYPH_H - - -FT_BEGIN_HEADER - - - /************************************************************************* - * - * <Section> - * cache_subsystem - * - * <Title> - * Cache Sub-System - * - * <Abstract> - * How to cache face, size, and glyph data with FreeType~2. - * - * <Description> - * This section describes the FreeType~2 cache sub-system, which is used - * to limit the number of concurrently opened @FT_Face and @FT_Size - * objects, as well as caching information like character maps and glyph - * images while limiting their maximum memory usage. - * - * Note that all types and functions begin with the `FTC_' prefix. - * - * The cache is highly portable and thus doesn't know anything about the - * fonts installed on your system, or how to access them. This implies - * the following scheme: - * - * First, available or installed font faces are uniquely identified by - * @FTC_FaceID values, provided to the cache by the client. Note that - * the cache only stores and compares these values, and doesn't try to - * interpret them in any way. - * - * Second, the cache calls, only when needed, a client-provided function - * to convert an @FTC_FaceID into a new @FT_Face object. The latter is - * then completely managed by the cache, including its termination - * through @FT_Done_Face. To monitor termination of face objects, the - * finalizer callback in the `generic' field of the @FT_Face object can - * be used, which might also be used to store the @FTC_FaceID of the - * face. - * - * Clients are free to map face IDs to anything else. The most simple - * usage is to associate them to a (pathname,face_index) pair that is - * used to call @FT_New_Face. However, more complex schemes are also - * possible. - * - * Note that for the cache to work correctly, the face ID values must be - * *persistent*, which means that the contents they point to should not - * change at runtime, or that their value should not become invalid. - * - * If this is unavoidable (e.g., when a font is uninstalled at runtime), - * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let - * the cache get rid of any references to the old @FTC_FaceID it may - * keep internally. Failure to do so will lead to incorrect behaviour - * or even crashes. - * - * To use the cache, start with calling @FTC_Manager_New to create a new - * @FTC_Manager object, which models a single cache instance. You can - * then look up @FT_Face and @FT_Size objects with - * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively. - * - * If you want to use the charmap caching, call @FTC_CMapCache_New, then - * later use @FTC_CMapCache_Lookup to perform the equivalent of - * @FT_Get_Char_Index, only much faster. - * - * If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then - * later use @FTC_ImageCache_Lookup to retrieve the corresponding - * @FT_Glyph objects from the cache. - * - * If you need lots of small bitmaps, it is much more memory efficient - * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This - * returns @FTC_SBitRec structures, which are used to store small - * bitmaps directly. (A small bitmap is one whose metrics and - * dimensions all fit into 8-bit integers). - * - * We hope to also provide a kerning cache in the near future. - * - * - * <Order> - * FTC_Manager - * FTC_FaceID - * FTC_Face_Requester - * - * FTC_Manager_New - * FTC_Manager_Reset - * FTC_Manager_Done - * FTC_Manager_LookupFace - * FTC_Manager_LookupSize - * FTC_Manager_RemoveFaceID - * - * FTC_Node - * FTC_Node_Unref - * - * FTC_ImageCache - * FTC_ImageCache_New - * FTC_ImageCache_Lookup - * - * FTC_SBit - * FTC_SBitCache - * FTC_SBitCache_New - * FTC_SBitCache_Lookup - * - * FTC_CMapCache - * FTC_CMapCache_New - * FTC_CMapCache_Lookup - * - *************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** BASIC TYPE DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /************************************************************************* - * - * @type: FTC_FaceID - * - * @description: - * An opaque pointer type that is used to identity face objects. The - * contents of such objects is application-dependent. - * - * These pointers are typically used to point to a user-defined - * structure containing a font file path, and face index. - * - * @note: - * Never use NULL as a valid @FTC_FaceID. - * - * Face IDs are passed by the client to the cache manager, which calls, - * when needed, the @FTC_Face_Requester to translate them into new - * @FT_Face objects. - * - * If the content of a given face ID changes at runtime, or if the value - * becomes invalid (e.g., when uninstalling a font), you should - * immediately call @FTC_Manager_RemoveFaceID before any other cache - * function. - * - * Failure to do so will result in incorrect behaviour or even - * memory leaks and crashes. - */ - typedef FT_Pointer FTC_FaceID; - - - /************************************************************************ - * - * @functype: - * FTC_Face_Requester - * - * @description: - * A callback function provided by client applications. It is used by - * the cache manager to translate a given @FTC_FaceID into a new valid - * @FT_Face object, on demand. - * - * <Input> - * face_id :: - * The face ID to resolve. - * - * library :: - * A handle to a FreeType library object. - * - * req_data :: - * Application-provided request data (see note below). - * - * <Output> - * aface :: - * A new @FT_Face handle. - * - * <Return> - * FreeType error code. 0~means success. - * - * <Note> - * The third parameter `req_data' is the same as the one passed by the - * client when @FTC_Manager_New is called. - * - * The face requester should not perform funny things on the returned - * face object, like creating a new @FT_Size for it, or setting a - * transformation through @FT_Set_Transform! - */ - typedef FT_Error - (*FTC_Face_Requester)( FTC_FaceID face_id, - FT_Library library, - FT_Pointer request_data, - FT_Face* aface ); - - /* */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE MANAGER OBJECT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_Manager */ - /* */ - /* <Description> */ - /* This object corresponds to one instance of the cache-subsystem. */ - /* It is used to cache one or more @FT_Face objects, along with */ - /* corresponding @FT_Size objects. */ - /* */ - /* The manager intentionally limits the total number of opened */ - /* @FT_Face and @FT_Size objects to control memory usage. See the */ - /* `max_faces' and `max_sizes' parameters of @FTC_Manager_New. */ - /* */ - /* The manager is also used to cache `nodes' of various types while */ - /* limiting their total memory usage. */ - /* */ - /* All limitations are enforced by keeping lists of managed objects */ - /* in most-recently-used order, and flushing old nodes to make room */ - /* for new ones. */ - /* */ - typedef struct FTC_ManagerRec_* FTC_Manager; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_Node */ - /* */ - /* <Description> */ - /* An opaque handle to a cache node object. Each cache node is */ - /* reference-counted. A node with a count of~0 might be flushed */ - /* out of a full cache whenever a lookup request is performed. */ - /* */ - /* If you look up nodes, you have the ability to `acquire' them, */ - /* i.e., to increment their reference count. This will prevent the */ - /* node from being flushed out of the cache until you explicitly */ - /* `release' it (see @FTC_Node_Unref). */ - /* */ - /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ - /* */ - typedef struct FTC_NodeRec_* FTC_Node; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_New */ - /* */ - /* <Description> */ - /* Create a new cache manager. */ - /* */ - /* <Input> */ - /* library :: The parent FreeType library handle to use. */ - /* */ - /* max_faces :: Maximum number of opened @FT_Face objects managed by */ - /* this cache instance. Use~0 for defaults. */ - /* */ - /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ - /* this cache instance. Use~0 for defaults. */ - /* */ - /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ - /* Use~0 for defaults. Note that this value does not */ - /* account for managed @FT_Face and @FT_Size objects. */ - /* */ - /* requester :: An application-provided callback used to translate */ - /* face IDs into real @FT_Face objects. */ - /* */ - /* req_data :: A generic pointer that is passed to the requester */ - /* each time it is called (see @FTC_Face_Requester). */ - /* */ - /* <Output> */ - /* amanager :: A handle to a new manager object. 0~in case of */ - /* failure. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_Manager_New( FT_Library library, - FT_UInt max_faces, - FT_UInt max_sizes, - FT_ULong max_bytes, - FTC_Face_Requester requester, - FT_Pointer req_data, - FTC_Manager *amanager ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_Reset */ - /* */ - /* <Description> */ - /* Empty a given cache manager. This simply gets rid of all the */ - /* currently cached @FT_Face and @FT_Size objects within the manager. */ - /* */ - /* <InOut> */ - /* manager :: A handle to the manager. */ - /* */ - FT_EXPORT( void ) - FTC_Manager_Reset( FTC_Manager manager ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_Done */ - /* */ - /* <Description> */ - /* Destroy a given manager after emptying it. */ - /* */ - /* <Input> */ - /* manager :: A handle to the target cache manager object. */ - /* */ - FT_EXPORT( void ) - FTC_Manager_Done( FTC_Manager manager ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_LookupFace */ - /* */ - /* <Description> */ - /* Retrieve the @FT_Face object that corresponds to a given face ID */ - /* through a cache manager. */ - /* */ - /* <Input> */ - /* manager :: A handle to the cache manager. */ - /* */ - /* face_id :: The ID of the face object. */ - /* */ - /* <Output> */ - /* aface :: A handle to the face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The returned @FT_Face object is always owned by the manager. You */ - /* should never try to discard it yourself. */ - /* */ - /* The @FT_Face object doesn't necessarily have a current size object */ - /* (i.e., face->size can be~0). If you need a specific `font size', */ - /* use @FTC_Manager_LookupSize instead. */ - /* */ - /* Never change the face's transformation matrix (i.e., never call */ - /* the @FT_Set_Transform function) on a returned face! If you need */ - /* to transform glyphs, do it yourself after glyph loading. */ - /* */ - /* When you perform a lookup, out-of-memory errors are detected */ - /* _within_ the lookup and force incremental flushes of the cache */ - /* until enough memory is released for the lookup to succeed. */ - /* */ - /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ - /* already been completely flushed, and still no memory was available */ - /* for the operation. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_Manager_LookupFace( FTC_Manager manager, - FTC_FaceID face_id, - FT_Face *aface ); - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FTC_ScalerRec */ - /* */ - /* <Description> */ - /* A structure used to describe a given character size in either */ - /* pixels or points to the cache manager. See */ - /* @FTC_Manager_LookupSize. */ - /* */ - /* <Fields> */ - /* face_id :: The source face ID. */ - /* */ - /* width :: The character width. */ - /* */ - /* height :: The character height. */ - /* */ - /* pixel :: A Boolean. If 1, the `width' and `height' fields are */ - /* interpreted as integer pixel character sizes. */ - /* Otherwise, they are expressed as 1/64th of points. */ - /* */ - /* x_res :: Only used when `pixel' is value~0 to indicate the */ - /* horizontal resolution in dpi. */ - /* */ - /* y_res :: Only used when `pixel' is value~0 to indicate the */ - /* vertical resolution in dpi. */ - /* */ - /* <Note> */ - /* This type is mainly used to retrieve @FT_Size objects through the */ - /* cache manager. */ - /* */ - typedef struct FTC_ScalerRec_ - { - FTC_FaceID face_id; - FT_UInt width; - FT_UInt height; - FT_Int pixel; - FT_UInt x_res; - FT_UInt y_res; - - } FTC_ScalerRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FTC_Scaler */ - /* */ - /* <Description> */ - /* A handle to an @FTC_ScalerRec structure. */ - /* */ - typedef struct FTC_ScalerRec_* FTC_Scaler; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_LookupSize */ - /* */ - /* <Description> */ - /* Retrieve the @FT_Size object that corresponds to a given */ - /* @FTC_ScalerRec pointer through a cache manager. */ - /* */ - /* <Input> */ - /* manager :: A handle to the cache manager. */ - /* */ - /* scaler :: A scaler handle. */ - /* */ - /* <Output> */ - /* asize :: A handle to the size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The returned @FT_Size object is always owned by the manager. You */ - /* should never try to discard it by yourself. */ - /* */ - /* You can access the parent @FT_Face object simply as `size->face' */ - /* if you need it. Note that this object is also owned by the */ - /* manager. */ - /* */ - /* <Note> */ - /* When you perform a lookup, out-of-memory errors are detected */ - /* _within_ the lookup and force incremental flushes of the cache */ - /* until enough memory is released for the lookup to succeed. */ - /* */ - /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ - /* already been completely flushed, and still no memory is available */ - /* for the operation. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_Manager_LookupSize( FTC_Manager manager, - FTC_Scaler scaler, - FT_Size *asize ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Node_Unref */ - /* */ - /* <Description> */ - /* Decrement a cache node's internal reference count. When the count */ - /* reaches 0, it is not destroyed but becomes eligible for subsequent */ - /* cache flushes. */ - /* */ - /* <Input> */ - /* node :: The cache node handle. */ - /* */ - /* manager :: The cache manager handle. */ - /* */ - FT_EXPORT( void ) - FTC_Node_Unref( FTC_Node node, - FTC_Manager manager ); - - - /************************************************************************* - * - * @function: - * FTC_Manager_RemoveFaceID - * - * @description: - * A special function used to indicate to the cache manager that - * a given @FTC_FaceID is no longer valid, either because its - * content changed, or because it was deallocated or uninstalled. - * - * @input: - * manager :: - * The cache manager handle. - * - * face_id :: - * The @FTC_FaceID to be removed. - * - * @note: - * This function flushes all nodes from the cache corresponding to this - * `face_id', with the exception of nodes with a non-null reference - * count. - * - * Such nodes are however modified internally so as to never appear - * in later lookups with the same `face_id' value, and to be immediately - * destroyed when released by all their users. - * - */ - FT_EXPORT( void ) - FTC_Manager_RemoveFaceID( FTC_Manager manager, - FTC_FaceID face_id ); - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* cache_subsystem */ - /* */ - /*************************************************************************/ - - /************************************************************************* - * - * @type: - * FTC_CMapCache - * - * @description: - * An opaque handle used to model a charmap cache. This cache is to - * hold character codes -> glyph indices mappings. - * - */ - typedef struct FTC_CMapCacheRec_* FTC_CMapCache; - - - /************************************************************************* - * - * @function: - * FTC_CMapCache_New - * - * @description: - * Create a new charmap cache. - * - * @input: - * manager :: - * A handle to the cache manager. - * - * @output: - * acache :: - * A new cache handle. NULL in case of error. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * Like all other caches, this one will be destroyed with the cache - * manager. - * - */ - FT_EXPORT( FT_Error ) - FTC_CMapCache_New( FTC_Manager manager, - FTC_CMapCache *acache ); - - - /************************************************************************ - * - * @function: - * FTC_CMapCache_Lookup - * - * @description: - * Translate a character code into a glyph index, using the charmap - * cache. - * - * @input: - * cache :: - * A charmap cache handle. - * - * face_id :: - * The source face ID. - * - * cmap_index :: - * The index of the charmap in the source face. Any negative value - * means to use the cache @FT_Face's default charmap. - * - * char_code :: - * The character code (in the corresponding charmap). - * - * @return: - * Glyph index. 0~means `no glyph'. - * - */ - FT_EXPORT( FT_UInt ) - FTC_CMapCache_Lookup( FTC_CMapCache cache, - FTC_FaceID face_id, - FT_Int cmap_index, - FT_UInt32 char_code ); - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* cache_subsystem */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** IMAGE CACHE OBJECT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /************************************************************************* - * - * @struct: - * FTC_ImageTypeRec - * - * @description: - * A structure used to model the type of images in a glyph cache. - * - * @fields: - * face_id :: - * The face ID. - * - * width :: - * The width in pixels. - * - * height :: - * The height in pixels. - * - * flags :: - * The load flags, as in @FT_Load_Glyph. - * - */ - typedef struct FTC_ImageTypeRec_ - { - FTC_FaceID face_id; - FT_Int width; - FT_Int height; - FT_Int32 flags; - - } FTC_ImageTypeRec; - - - /************************************************************************* - * - * @type: - * FTC_ImageType - * - * @description: - * A handle to an @FTC_ImageTypeRec structure. - * - */ - typedef struct FTC_ImageTypeRec_* FTC_ImageType; - - - /* */ - - -#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ - ( (d1)->face_id == (d2)->face_id && \ - (d1)->width == (d2)->width && \ - (d1)->flags == (d2)->flags ) - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_ImageCache */ - /* */ - /* <Description> */ - /* A handle to a glyph image cache object. They are designed to */ - /* hold many distinct glyph images while not exceeding a certain */ - /* memory threshold. */ - /* */ - typedef struct FTC_ImageCacheRec_* FTC_ImageCache; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_ImageCache_New */ - /* */ - /* <Description> */ - /* Create a new glyph image cache. */ - /* */ - /* <Input> */ - /* manager :: The parent manager for the image cache. */ - /* */ - /* <Output> */ - /* acache :: A handle to the new glyph image cache object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_ImageCache_New( FTC_Manager manager, - FTC_ImageCache *acache ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_ImageCache_Lookup */ - /* */ - /* <Description> */ - /* Retrieve a given glyph image from a glyph image cache. */ - /* */ - /* <Input> */ - /* cache :: A handle to the source glyph image cache. */ - /* */ - /* type :: A pointer to a glyph image type descriptor. */ - /* */ - /* gindex :: The glyph index to retrieve. */ - /* */ - /* <Output> */ - /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ - /* failure. */ - /* */ - /* anode :: Used to return the address of of the corresponding cache */ - /* node after incrementing its reference count (see note */ - /* below). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The returned glyph is owned and managed by the glyph image cache. */ - /* Never try to transform or discard it manually! You can however */ - /* create a copy with @FT_Glyph_Copy and modify the new one. */ - /* */ - /* If `anode' is _not_ NULL, it receives the address of the cache */ - /* node containing the glyph image, after increasing its reference */ - /* count. This ensures that the node (as well as the @FT_Glyph) will */ - /* always be kept in the cache until you call @FTC_Node_Unref to */ - /* `release' it. */ - /* */ - /* If `anode' is NULL, the cache node is left unchanged, which means */ - /* that the @FT_Glyph could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ - FT_EXPORT( FT_Error ) - FTC_ImageCache_Lookup( FTC_ImageCache cache, - FTC_ImageType type, - FT_UInt gindex, - FT_Glyph *aglyph, - FTC_Node *anode ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_ImageCache_LookupScaler */ - /* */ - /* <Description> */ - /* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */ - /* to specify the face ID and its size. */ - /* */ - /* <Input> */ - /* cache :: A handle to the source glyph image cache. */ - /* */ - /* scaler :: A pointer to a scaler descriptor. */ - /* */ - /* load_flags :: The corresponding load flags. */ - /* */ - /* gindex :: The glyph index to retrieve. */ - /* */ - /* <Output> */ - /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ - /* failure. */ - /* */ - /* anode :: Used to return the address of of the corresponding */ - /* cache node after incrementing its reference count */ - /* (see note below). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The returned glyph is owned and managed by the glyph image cache. */ - /* Never try to transform or discard it manually! You can however */ - /* create a copy with @FT_Glyph_Copy and modify the new one. */ - /* */ - /* If `anode' is _not_ NULL, it receives the address of the cache */ - /* node containing the glyph image, after increasing its reference */ - /* count. This ensures that the node (as well as the @FT_Glyph) will */ - /* always be kept in the cache until you call @FTC_Node_Unref to */ - /* `release' it. */ - /* */ - /* If `anode' is NULL, the cache node is left unchanged, which means */ - /* that the @FT_Glyph could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ - /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ - /* glyphs; you should always use the FreeType cache API instead. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_ImageCache_LookupScaler( FTC_ImageCache cache, - FTC_Scaler scaler, - FT_ULong load_flags, - FT_UInt gindex, - FT_Glyph *aglyph, - FTC_Node *anode ); - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_SBit */ - /* */ - /* <Description> */ - /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ - /* structure for details. */ - /* */ - typedef struct FTC_SBitRec_* FTC_SBit; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FTC_SBitRec */ - /* */ - /* <Description> */ - /* A very compact structure used to describe a small glyph bitmap. */ - /* */ - /* <Fields> */ - /* width :: The bitmap width in pixels. */ - /* */ - /* height :: The bitmap height in pixels. */ - /* */ - /* left :: The horizontal distance from the pen position to the */ - /* left bitmap border (a.k.a. `left side bearing', or */ - /* `lsb'). */ - /* */ - /* top :: The vertical distance from the pen position (on the */ - /* baseline) to the upper bitmap border (a.k.a. `top */ - /* side bearing'). The distance is positive for upwards */ - /* y~coordinates. */ - /* */ - /* format :: The format of the glyph bitmap (monochrome or gray). */ - /* */ - /* max_grays :: Maximum gray level value (in the range 1 to~255). */ - /* */ - /* pitch :: The number of bytes per bitmap line. May be positive */ - /* or negative. */ - /* */ - /* xadvance :: The horizontal advance width in pixels. */ - /* */ - /* yadvance :: The vertical advance height in pixels. */ - /* */ - /* buffer :: A pointer to the bitmap pixels. */ - /* */ - typedef struct FTC_SBitRec_ - { - FT_Byte width; - FT_Byte height; - FT_Char left; - FT_Char top; - - FT_Byte format; - FT_Byte max_grays; - FT_Short pitch; - FT_Char xadvance; - FT_Char yadvance; - - FT_Byte* buffer; - - } FTC_SBitRec; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_SBitCache */ - /* */ - /* <Description> */ - /* A handle to a small bitmap cache. These are special cache objects */ - /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ - /* much more efficient way than the traditional glyph image cache */ - /* implemented by @FTC_ImageCache. */ - /* */ - typedef struct FTC_SBitCacheRec_* FTC_SBitCache; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_SBitCache_New */ - /* */ - /* <Description> */ - /* Create a new cache to store small glyph bitmaps. */ - /* */ - /* <Input> */ - /* manager :: A handle to the source cache manager. */ - /* */ - /* <Output> */ - /* acache :: A handle to the new sbit cache. NULL in case of error. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_SBitCache_New( FTC_Manager manager, - FTC_SBitCache *acache ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_SBitCache_Lookup */ - /* */ - /* <Description> */ - /* Look up a given small glyph bitmap in a given sbit cache and */ - /* `lock' it to prevent its flushing from the cache until needed. */ - /* */ - /* <Input> */ - /* cache :: A handle to the source sbit cache. */ - /* */ - /* type :: A pointer to the glyph image type descriptor. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* <Output> */ - /* sbit :: A handle to a small bitmap descriptor. */ - /* */ - /* anode :: Used to return the address of of the corresponding cache */ - /* node after incrementing its reference count (see note */ - /* below). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The small bitmap descriptor and its bit buffer are owned by the */ - /* cache and should never be freed by the application. They might */ - /* as well disappear from memory on the next cache lookup, so don't */ - /* treat them as persistent data. */ - /* */ - /* The descriptor's `buffer' field is set to~0 to indicate a missing */ - /* glyph bitmap. */ - /* */ - /* If `anode' is _not_ NULL, it receives the address of the cache */ - /* node containing the bitmap, after increasing its reference count. */ - /* This ensures that the node (as well as the image) will always be */ - /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ - /* */ - /* If `anode' is NULL, the cache node is left unchanged, which means */ - /* that the bitmap could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ - FT_EXPORT( FT_Error ) - FTC_SBitCache_Lookup( FTC_SBitCache cache, - FTC_ImageType type, - FT_UInt gindex, - FTC_SBit *sbit, - FTC_Node *anode ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_SBitCache_LookupScaler */ - /* */ - /* <Description> */ - /* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */ - /* to specify the face ID and its size. */ - /* */ - /* <Input> */ - /* cache :: A handle to the source sbit cache. */ - /* */ - /* scaler :: A pointer to the scaler descriptor. */ - /* */ - /* load_flags :: The corresponding load flags. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* <Output> */ - /* sbit :: A handle to a small bitmap descriptor. */ - /* */ - /* anode :: Used to return the address of of the corresponding */ - /* cache node after incrementing its reference count */ - /* (see note below). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The small bitmap descriptor and its bit buffer are owned by the */ - /* cache and should never be freed by the application. They might */ - /* as well disappear from memory on the next cache lookup, so don't */ - /* treat them as persistent data. */ - /* */ - /* The descriptor's `buffer' field is set to~0 to indicate a missing */ - /* glyph bitmap. */ - /* */ - /* If `anode' is _not_ NULL, it receives the address of the cache */ - /* node containing the bitmap, after increasing its reference count. */ - /* This ensures that the node (as well as the image) will always be */ - /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ - /* */ - /* If `anode' is NULL, the cache node is left unchanged, which means */ - /* that the bitmap could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ - FT_EXPORT( FT_Error ) - FTC_SBitCache_LookupScaler( FTC_SBitCache cache, - FTC_Scaler scaler, - FT_ULong load_flags, - FT_UInt gindex, - FTC_SBit *sbit, - FTC_Node *anode ); - - - /* */ - -FT_END_HEADER - -#endif /* __FTCACHE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftcffdrv.h b/drivers/freetype/freetype/include/freetype/ftcffdrv.h deleted file mode 100644 index ccbcbccaa8..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftcffdrv.h +++ /dev/null @@ -1,151 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcffdrv.h */ -/* */ -/* FreeType API for controlling the CFF driver (specification only). */ -/* */ -/* Copyright 2013 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 __FTCFFDRV_H__ -#define __FTCFFDRV_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /************************************************************************** - * - * @section: - * cff_driver - * - * @title: - * The CFF driver - * - * @abstract: - * Controlling the CFF driver module. - * - * @description: - * While FreeType's CFF driver doesn't expose API functions by itself, - * it is possible to control its behaviour with @FT_Property_Set and - * @FT_Property_Get. The following lists the available properties - * together with the necessary macros and structures. - * - * The CFF driver's module name is `cff'. - * - */ - - - /************************************************************************** - * - * @property: - * hinting-engine - * - * @description: - * Thanks to Adobe, which contributed a new hinting (and parsing) - * engine, an application can select between `freetype' and `adobe' if - * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration - * macro isn't defined, `hinting-engine' does nothing. - * - * The default engine is `freetype' if CFF_CONFIG_OPTION_OLD_ENGINE is - * defined, and `adobe' otherwise. - * - * The following example code demonstrates how to select Adobe's hinting - * engine (omitting the error handling). - * - * { - * FT_Library library; - * FT_Face face; - * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "cff", - * "hinting-engine", &hinting_engine ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - */ - - - /************************************************************************** - * - * @enum: - * FT_CFF_HINTING_XXX - * - * @description: - * A list of constants used for the @hinting-engine property to select - * the hinting engine for CFF fonts. - * - * @values: - * FT_CFF_HINTING_FREETYPE :: - * Use the old FreeType hinting engine. - * - * FT_CFF_HINTING_ADOBE :: - * Use the hinting engine contributed by Adobe. - * - */ -#define FT_CFF_HINTING_FREETYPE 0 -#define FT_CFF_HINTING_ADOBE 1 - - - /************************************************************************** - * - * @property: - * no-stem-darkening - * - * @description: - * By default, the Adobe CFF engine darkens stems at smaller sizes, - * regardless of hinting, to enhance contrast. Setting this property, - * stem darkening gets switched off. - * - * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. - * - * { - * FT_Library library; - * FT_Face face; - * FT_Bool no_stem_darkening = TRUE; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "cff", - * "no-stem-darkening", &no_stem_darkening ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - */ - - - /* */ - -FT_END_HEADER - - -#endif /* __FTCFFDRV_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftchapters.h b/drivers/freetype/freetype/include/freetype/ftchapters.h deleted file mode 100644 index c55670d1d2..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftchapters.h +++ /dev/null @@ -1,120 +0,0 @@ -/***************************************************************************/ -/* */ -/* This file defines the structure of the FreeType reference. */ -/* It is used by the python script which generates the HTML files. */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* general_remarks */ -/* */ -/* <Title> */ -/* General Remarks */ -/* */ -/* <Sections> */ -/* user_allocation */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* core_api */ -/* */ -/* <Title> */ -/* Core API */ -/* */ -/* <Sections> */ -/* version */ -/* basic_types */ -/* base_interface */ -/* glyph_variants */ -/* glyph_management */ -/* mac_specific */ -/* sizes_management */ -/* header_file_macros */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* format_specific */ -/* */ -/* <Title> */ -/* Format-Specific API */ -/* */ -/* <Sections> */ -/* multiple_masters */ -/* truetype_tables */ -/* type1_tables */ -/* sfnt_names */ -/* bdf_fonts */ -/* cid_fonts */ -/* pfr_fonts */ -/* winfnt_fonts */ -/* font_formats */ -/* gasp_table */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* module_specific */ -/* */ -/* <Title> */ -/* Controlling FreeType Modules */ -/* */ -/* <Sections> */ -/* auto_hinter */ -/* cff_driver */ -/* tt_driver */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* cache_subsystem */ -/* */ -/* <Title> */ -/* Cache Sub-System */ -/* */ -/* <Sections> */ -/* cache_subsystem */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* support_api */ -/* */ -/* <Title> */ -/* Support API */ -/* */ -/* <Sections> */ -/* computations */ -/* list_processing */ -/* outline_processing */ -/* quick_advance */ -/* bitmap_handling */ -/* raster */ -/* glyph_stroker */ -/* system_interface */ -/* module_management */ -/* gzip */ -/* lzw */ -/* bzip2 */ -/* lcd_filtering */ -/* */ -/***************************************************************************/ diff --git a/drivers/freetype/freetype/include/freetype/ftcid.h b/drivers/freetype/freetype/include/freetype/ftcid.h deleted file mode 100644 index 203a30caf8..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftcid.h +++ /dev/null @@ -1,166 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcid.h */ -/* */ -/* FreeType API for accessing CID font information (specification). */ -/* */ -/* Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal. */ -/* */ -/* 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 __FTCID_H__ -#define __FTCID_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* cid_fonts */ - /* */ - /* <Title> */ - /* CID Fonts */ - /* */ - /* <Abstract> */ - /* CID-keyed font specific API. */ - /* */ - /* <Description> */ - /* This section contains the declaration of CID-keyed font specific */ - /* functions. */ - /* */ - /*************************************************************************/ - - - /********************************************************************** - * - * @function: - * FT_Get_CID_Registry_Ordering_Supplement - * - * @description: - * Retrieve the Registry/Ordering/Supplement triple (also known as the - * "R/O/S") from a CID-keyed font. - * - * @input: - * face :: - * A handle to the input face. - * - * @output: - * registry :: - * The registry, as a C~string, owned by the face. - * - * ordering :: - * The ordering, as a C~string, owned by the face. - * - * supplement :: - * The supplement. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with CID faces, returning an error - * otherwise. - * - * @since: - * 2.3.6 - */ - FT_EXPORT( FT_Error ) - FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, - const char* *registry, - const char* *ordering, - FT_Int *supplement); - - - /********************************************************************** - * - * @function: - * FT_Get_CID_Is_Internally_CID_Keyed - * - * @description: - * Retrieve the type of the input face, CID keyed or not. In - * constrast to the @FT_IS_CID_KEYED macro this function returns - * successfully also for CID-keyed fonts in an SNFT wrapper. - * - * @input: - * face :: - * A handle to the input face. - * - * @output: - * is_cid :: - * The type of the face as an @FT_Bool. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with CID faces and OpenType fonts, - * returning an error otherwise. - * - * @since: - * 2.3.9 - */ - FT_EXPORT( FT_Error ) - FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, - FT_Bool *is_cid ); - - - /********************************************************************** - * - * @function: - * FT_Get_CID_From_Glyph_Index - * - * @description: - * Retrieve the CID of the input glyph index. - * - * @input: - * face :: - * A handle to the input face. - * - * glyph_index :: - * The input glyph index. - * - * @output: - * cid :: - * The CID as an @FT_UInt. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with CID faces and OpenType fonts, - * returning an error otherwise. - * - * @since: - * 2.3.9 - */ - FT_EXPORT( FT_Error ) - FT_Get_CID_From_Glyph_Index( FT_Face face, - FT_UInt glyph_index, - FT_UInt *cid ); - - /* */ - -FT_END_HEADER - -#endif /* __FTCID_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/fterrdef.h b/drivers/freetype/freetype/include/freetype/fterrdef.h deleted file mode 100644 index 76c7b9e36f..0000000000 --- a/drivers/freetype/freetype/include/freetype/fterrdef.h +++ /dev/null @@ -1,249 +0,0 @@ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 2010-2013 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. */ -/* */ -/***************************************************************************/ - - - /*******************************************************************/ - /*******************************************************************/ - /***** *****/ - /***** LIST OF ERROR CODES/MESSAGES *****/ - /***** *****/ - /*******************************************************************/ - /*******************************************************************/ - - - /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */ - /* including this file. */ - - - /* generic errors */ - - FT_NOERRORDEF_( Ok, 0x00, \ - "no error" ) - - FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ - "cannot open resource" ) - FT_ERRORDEF_( Unknown_File_Format, 0x02, \ - "unknown file format" ) - FT_ERRORDEF_( Invalid_File_Format, 0x03, \ - "broken file" ) - FT_ERRORDEF_( Invalid_Version, 0x04, \ - "invalid FreeType version" ) - FT_ERRORDEF_( Lower_Module_Version, 0x05, \ - "module version is too low" ) - FT_ERRORDEF_( Invalid_Argument, 0x06, \ - "invalid argument" ) - FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ - "unimplemented feature" ) - FT_ERRORDEF_( Invalid_Table, 0x08, \ - "broken table" ) - FT_ERRORDEF_( Invalid_Offset, 0x09, \ - "broken offset within table" ) - FT_ERRORDEF_( Array_Too_Large, 0x0A, \ - "array allocation size too large" ) - FT_ERRORDEF_( Missing_Module, 0x0B, \ - "missing module" ) - FT_ERRORDEF_( Missing_Property, 0x0C, \ - "missing property" ) - - /* glyph/character errors */ - - FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ - "invalid glyph index" ) - FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ - "invalid character code" ) - FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ - "unsupported glyph image format" ) - FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ - "cannot render this glyph format" ) - FT_ERRORDEF_( Invalid_Outline, 0x14, \ - "invalid outline" ) - FT_ERRORDEF_( Invalid_Composite, 0x15, \ - "invalid composite glyph" ) - FT_ERRORDEF_( Too_Many_Hints, 0x16, \ - "too many hints" ) - FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ - "invalid pixel size" ) - - /* handle errors */ - - FT_ERRORDEF_( Invalid_Handle, 0x20, \ - "invalid object handle" ) - FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ - "invalid library handle" ) - FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ - "invalid module handle" ) - FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ - "invalid face handle" ) - FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ - "invalid size handle" ) - FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ - "invalid glyph slot handle" ) - FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ - "invalid charmap handle" ) - FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ - "invalid cache manager handle" ) - FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ - "invalid stream handle" ) - - /* driver errors */ - - FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ - "too many modules" ) - FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ - "too many extensions" ) - - /* memory errors */ - - FT_ERRORDEF_( Out_Of_Memory, 0x40, \ - "out of memory" ) - FT_ERRORDEF_( Unlisted_Object, 0x41, \ - "unlisted object" ) - - /* stream errors */ - - FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ - "cannot open stream" ) - FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ - "invalid stream seek" ) - FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ - "invalid stream skip" ) - FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ - "invalid stream read" ) - FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ - "invalid stream operation" ) - FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ - "invalid frame operation" ) - FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ - "nested frame access" ) - FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ - "invalid frame read" ) - - /* raster errors */ - - FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ - "raster uninitialized" ) - FT_ERRORDEF_( Raster_Corrupted, 0x61, \ - "raster corrupted" ) - FT_ERRORDEF_( Raster_Overflow, 0x62, \ - "raster overflow" ) - FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ - "negative height while rastering" ) - - /* cache errors */ - - FT_ERRORDEF_( Too_Many_Caches, 0x70, \ - "too many registered caches" ) - - /* TrueType and SFNT errors */ - - FT_ERRORDEF_( Invalid_Opcode, 0x80, \ - "invalid opcode" ) - FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ - "too few arguments" ) - FT_ERRORDEF_( Stack_Overflow, 0x82, \ - "stack overflow" ) - FT_ERRORDEF_( Code_Overflow, 0x83, \ - "code overflow" ) - FT_ERRORDEF_( Bad_Argument, 0x84, \ - "bad argument" ) - FT_ERRORDEF_( Divide_By_Zero, 0x85, \ - "division by zero" ) - FT_ERRORDEF_( Invalid_Reference, 0x86, \ - "invalid reference" ) - FT_ERRORDEF_( Debug_OpCode, 0x87, \ - "found debug opcode" ) - FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ - "found ENDF opcode in execution stream" ) - FT_ERRORDEF_( Nested_DEFS, 0x89, \ - "nested DEFS" ) - FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ - "invalid code range" ) - FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ - "execution context too long" ) - FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ - "too many function definitions" ) - FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ - "too many instruction definitions" ) - FT_ERRORDEF_( Table_Missing, 0x8E, \ - "SFNT font table missing" ) - FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ - "horizontal header (hhea) table missing" ) - FT_ERRORDEF_( Locations_Missing, 0x90, \ - "locations (loca) table missing" ) - FT_ERRORDEF_( Name_Table_Missing, 0x91, \ - "name table missing" ) - FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ - "character map (cmap) table missing" ) - FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ - "horizontal metrics (hmtx) table missing" ) - FT_ERRORDEF_( Post_Table_Missing, 0x94, \ - "PostScript (post) table missing" ) - FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ - "invalid horizontal metrics" ) - FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ - "invalid character map (cmap) format" ) - FT_ERRORDEF_( Invalid_PPem, 0x97, \ - "invalid ppem value" ) - FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ - "invalid vertical metrics" ) - FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ - "could not find context" ) - FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ - "invalid PostScript (post) table format" ) - FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ - "invalid PostScript (post) table" ) - - /* CFF, CID, and Type 1 errors */ - - FT_ERRORDEF_( Syntax_Error, 0xA0, \ - "opcode syntax error" ) - FT_ERRORDEF_( Stack_Underflow, 0xA1, \ - "argument stack underflow" ) - FT_ERRORDEF_( Ignore, 0xA2, \ - "ignore" ) - FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \ - "no Unicode glyph name found" ) - FT_ERRORDEF_( Glyph_Too_Big, 0xA4, \ - "glyph to big for hinting" ) - - /* BDF errors */ - - FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ - "`STARTFONT' field missing" ) - FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ - "`FONT' field missing" ) - FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ - "`SIZE' field missing" ) - FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, \ - "`FONTBOUNDINGBOX' field missing" ) - FT_ERRORDEF_( Missing_Chars_Field, 0xB4, \ - "`CHARS' field missing" ) - FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, \ - "`STARTCHAR' field missing" ) - FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, \ - "`ENCODING' field missing" ) - FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, \ - "`BBX' field missing" ) - FT_ERRORDEF_( Bbx_Too_Big, 0xB8, \ - "`BBX' too big" ) - FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, \ - "Font header corrupted or missing fields" ) - FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, \ - "Font glyphs corrupted or missing fields" ) - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/fterrors.h b/drivers/freetype/freetype/include/freetype/fterrors.h deleted file mode 100644 index 0fa3e4dce1..0000000000 --- a/drivers/freetype/freetype/include/freetype/fterrors.h +++ /dev/null @@ -1,198 +0,0 @@ -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2002, 2004, 2007, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This special header file is used to define the handling of FT2 */ - /* enumeration constants. It can also be used to generate error message */ - /* strings with a small macro trick explained below. */ - /* */ - /* I - Error Formats */ - /* ----------------- */ - /* */ - /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ - /* defined in ftoption.h in order to make the higher byte indicate */ - /* the module where the error has happened (this is not compatible */ - /* with standard builds of FreeType 2). See the file `ftmoderr.h' for */ - /* more details. */ - /* */ - /* */ - /* II - Error Message strings */ - /* -------------------------- */ - /* */ - /* The error definitions below are made through special macros that */ - /* allow client applications to build a table of error message strings */ - /* if they need it. The strings are not included in a normal build of */ - /* FreeType 2 to save space (most client applications do not use */ - /* them). */ - /* */ - /* To do so, you have to define the following macros before including */ - /* this file: */ - /* */ - /* FT_ERROR_START_LIST :: */ - /* This macro is called before anything else to define the start of */ - /* the error list. It is followed by several FT_ERROR_DEF calls */ - /* (see below). */ - /* */ - /* FT_ERROR_DEF( e, v, s ) :: */ - /* This macro is called to define one single error. */ - /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ - /* `v' is the error numerical value. */ - /* `s' is the corresponding error string. */ - /* */ - /* FT_ERROR_END_LIST :: */ - /* This macro ends the list. */ - /* */ - /* Additionally, you have to undefine __FTERRORS_H__ before #including */ - /* this file. */ - /* */ - /* Here is a simple example: */ - /* */ - /* { */ - /* #undef __FTERRORS_H__ */ - /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ - /* #define FT_ERROR_START_LIST { */ - /* #define FT_ERROR_END_LIST { 0, 0 } }; */ - /* */ - /* const struct */ - /* { */ - /* int err_code; */ - /* const char* err_msg; */ - /* } ft_errors[] = */ - /* */ - /* #include FT_ERRORS_H */ - /* } */ - /* */ - /*************************************************************************/ - - -#ifndef __FTERRORS_H__ -#define __FTERRORS_H__ - - - /* include module base error codes */ -#include FT_MODULE_ERRORS_H - - - /*******************************************************************/ - /*******************************************************************/ - /***** *****/ - /***** SETUP MACROS *****/ - /***** *****/ - /*******************************************************************/ - /*******************************************************************/ - - -#undef FT_NEED_EXTERN_C - - - /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ - /* By default, we use `FT_Err_'. */ - /* */ -#ifndef FT_ERR_PREFIX -#define FT_ERR_PREFIX FT_Err_ -#endif - - - /* FT_ERR_BASE is used as the base for module-specific errors. */ - /* */ -#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS - -#ifndef FT_ERR_BASE -#define FT_ERR_BASE FT_Mod_Err_Base -#endif - -#else - -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 - -#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ - - - /* If FT_ERRORDEF is not defined, we need to define a simple */ - /* enumeration type. */ - /* */ -#ifndef FT_ERRORDEF - -#define FT_ERRORDEF( e, v, s ) e = v, -#define FT_ERROR_START_LIST enum { -#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; - -#ifdef __cplusplus -#define FT_NEED_EXTERN_C - extern "C" { -#endif - -#endif /* !FT_ERRORDEF */ - - - /* this macro is used to define an error */ -#define FT_ERRORDEF_( e, v, s ) \ - FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) - - /* this is only used for <module>_Err_Ok, which must be 0! */ -#define FT_NOERRORDEF_( e, v, s ) \ - FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) - - -#ifdef FT_ERROR_START_LIST - FT_ERROR_START_LIST -#endif - - - /* now include the error codes */ -#include FT_ERROR_DEFINITIONS_H - - -#ifdef FT_ERROR_END_LIST - FT_ERROR_END_LIST -#endif - - - /*******************************************************************/ - /*******************************************************************/ - /***** *****/ - /***** SIMPLE CLEANUP *****/ - /***** *****/ - /*******************************************************************/ - /*******************************************************************/ - -#ifdef FT_NEED_EXTERN_C - } -#endif - -#undef FT_ERROR_START_LIST -#undef FT_ERROR_END_LIST - -#undef FT_ERRORDEF -#undef FT_ERRORDEF_ -#undef FT_NOERRORDEF_ - -#undef FT_NEED_EXTERN_C -#undef FT_ERR_BASE - - /* FT_ERR_PREFIX is needed internally */ -#ifndef FT2_BUILD_LIBRARY -#undef FT_ERR_PREFIX -#endif - -#endif /* __FTERRORS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftgasp.h b/drivers/freetype/freetype/include/freetype/ftgasp.h deleted file mode 100644 index 453d4fa42c..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftgasp.h +++ /dev/null @@ -1,128 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgasp.h */ -/* */ -/* Access of TrueType's `gasp' table (specification). */ -/* */ -/* Copyright 2007, 2008, 2011 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 - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - - /*************************************************************************** - * - * @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 its `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. If this bit - * is not set, no hinting gets applied. - * - * FT_GASP_DO_GRAY :: - * Anti-aliased rendering should be performed at the specified ppem. - * If not set, do monochrome rendering. - * - * FT_GASP_SYMMETRIC_SMOOTHING :: - * If set, smoothing along multiple axes must be used with ClearType. - * - * FT_GASP_SYMMETRIC_GRIDFIT :: - * Grid-fitting must be used with ClearType's symmetric smoothing. - * - * @note: - * The bit-flags `FT_GASP_DO_GRIDFIT' and `FT_GASP_DO_GRAY' are to be - * used for standard font rasterization only. Independently of that, - * `FT_GASP_SYMMETRIC_SMOOTHING' and `FT_GASP_SYMMETRIC_GRIDFIT' are to - * be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT' and - * `FT_GASP_DO_GRAY' are consequently ignored). - * - * `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 if 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 */ diff --git a/drivers/freetype/freetype/include/freetype/ftglyph.h b/drivers/freetype/freetype/include/freetype/ftglyph.h deleted file mode 100644 index 31dc33187d..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftglyph.h +++ /dev/null @@ -1,620 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftglyph.h */ -/* */ -/* FreeType convenience functions to handle glyphs (specification). */ -/* */ -/* Copyright 1996-2003, 2006, 2008, 2009, 2011 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file contains the definition of several convenience functions */ - /* that can be used by client applications to easily retrieve glyph */ - /* bitmaps and outlines from a given face. */ - /* */ - /* These functions should be optional if you are writing a font server */ - /* or text layout engine on top of FreeType. However, they are pretty */ - /* handy for many other simple uses of the library. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTGLYPH_H__ -#define __FTGLYPH_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* glyph_management */ - /* */ - /* <Title> */ - /* Glyph Management */ - /* */ - /* <Abstract> */ - /* Generic interface to manage individual glyph data. */ - /* */ - /* <Description> */ - /* This section contains definitions used to manage glyph data */ - /* through generic FT_Glyph objects. Each of them can contain a */ - /* bitmap, a vector outline, or even images in other formats. */ - /* */ - /*************************************************************************/ - - - /* forward declaration to a private type */ - typedef struct FT_Glyph_Class_ FT_Glyph_Class; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Glyph */ - /* */ - /* <Description> */ - /* Handle to an object used to model generic glyph images. It is a */ - /* pointer to the @FT_GlyphRec structure and can contain a glyph */ - /* bitmap or pointer. */ - /* */ - /* <Note> */ - /* Glyph objects are not owned by the library. You must thus release */ - /* them manually (through @FT_Done_Glyph) _before_ calling */ - /* @FT_Done_FreeType. */ - /* */ - typedef struct FT_GlyphRec_* FT_Glyph; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_GlyphRec */ - /* */ - /* <Description> */ - /* The root glyph structure contains a given glyph image plus its */ - /* advance width in 16.16 fixed-point format. */ - /* */ - /* <Fields> */ - /* library :: A handle to the FreeType library object. */ - /* */ - /* clazz :: A pointer to the glyph's class. Private. */ - /* */ - /* format :: The format of the glyph's image. */ - /* */ - /* advance :: A 16.16 vector that gives the glyph's advance width. */ - /* */ - typedef struct FT_GlyphRec_ - { - FT_Library library; - const FT_Glyph_Class* clazz; - FT_Glyph_Format format; - FT_Vector advance; - - } FT_GlyphRec; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_BitmapGlyph */ - /* */ - /* <Description> */ - /* A handle to an object used to model a bitmap glyph image. This is */ - /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ - /* */ - typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_BitmapGlyphRec */ - /* */ - /* <Description> */ - /* A structure used for bitmap glyph images. This really is a */ - /* `sub-class' of @FT_GlyphRec. */ - /* */ - /* <Fields> */ - /* root :: The root @FT_Glyph fields. */ - /* */ - /* left :: The left-side bearing, i.e., the horizontal distance */ - /* from the current pen position to the left border of the */ - /* glyph bitmap. */ - /* */ - /* top :: The top-side bearing, i.e., the vertical distance from */ - /* the current pen position to the top border of the glyph */ - /* bitmap. This distance is positive for upwards~y! */ - /* */ - /* bitmap :: A descriptor for the bitmap. */ - /* */ - /* <Note> */ - /* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have */ - /* `glyph->format == FT_GLYPH_FORMAT_BITMAP'. This lets you access */ - /* the bitmap's contents easily. */ - /* */ - /* The corresponding pixel buffer is always owned by @FT_BitmapGlyph */ - /* and is thus created and destroyed with it. */ - /* */ - typedef struct FT_BitmapGlyphRec_ - { - FT_GlyphRec root; - FT_Int left; - FT_Int top; - FT_Bitmap bitmap; - - } FT_BitmapGlyphRec; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_OutlineGlyph */ - /* */ - /* <Description> */ - /* A handle to an object used to model an outline glyph image. This */ - /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ - /* */ - typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_OutlineGlyphRec */ - /* */ - /* <Description> */ - /* A structure used for outline (vectorial) glyph images. This */ - /* really is a `sub-class' of @FT_GlyphRec. */ - /* */ - /* <Fields> */ - /* root :: The root @FT_Glyph fields. */ - /* */ - /* outline :: A descriptor for the outline. */ - /* */ - /* <Note> */ - /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ - /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ - /* the outline's content easily. */ - /* */ - /* As the outline is extracted from a glyph slot, its coordinates are */ - /* expressed normally in 26.6 pixels, unless the flag */ - /* @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */ - /* */ - /* The outline's tables are always owned by the object and are */ - /* destroyed with it. */ - /* */ - typedef struct FT_OutlineGlyphRec_ - { - FT_GlyphRec root; - FT_Outline outline; - - } FT_OutlineGlyphRec; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Glyph */ - /* */ - /* <Description> */ - /* A function used to extract a glyph image from a slot. Note that */ - /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ - /* */ - /* <Input> */ - /* slot :: A handle to the source glyph slot. */ - /* */ - /* <Output> */ - /* aglyph :: A handle to the glyph object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_Glyph( FT_GlyphSlot slot, - FT_Glyph *aglyph ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Glyph_Copy */ - /* */ - /* <Description> */ - /* A function used to copy a glyph image. Note that the created */ - /* @FT_Glyph object must be released with @FT_Done_Glyph. */ - /* */ - /* <Input> */ - /* source :: A handle to the source glyph object. */ - /* */ - /* <Output> */ - /* target :: A handle to the target glyph object. 0~in case of */ - /* error. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Glyph_Copy( FT_Glyph source, - FT_Glyph *target ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Glyph_Transform */ - /* */ - /* <Description> */ - /* Transform a glyph image if its format is scalable. */ - /* */ - /* <InOut> */ - /* glyph :: A handle to the target glyph object. */ - /* */ - /* <Input> */ - /* matrix :: A pointer to a 2x2 matrix to apply. */ - /* */ - /* delta :: A pointer to a 2d vector to apply. Coordinates are */ - /* expressed in 1/64th of a pixel. */ - /* */ - /* <Return> */ - /* FreeType error code (if not 0, the glyph format is not scalable). */ - /* */ - /* <Note> */ - /* The 2x2 transformation matrix is also applied to the glyph's */ - /* advance vector. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Glyph_Transform( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ); - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Glyph_BBox_Mode */ - /* */ - /* <Description> */ - /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ - /* */ - /* <Values> */ - /* FT_GLYPH_BBOX_UNSCALED :: */ - /* Return unscaled font units. */ - /* */ - /* FT_GLYPH_BBOX_SUBPIXELS :: */ - /* Return unfitted 26.6 coordinates. */ - /* */ - /* FT_GLYPH_BBOX_GRIDFIT :: */ - /* Return grid-fitted 26.6 coordinates. */ - /* */ - /* FT_GLYPH_BBOX_TRUNCATE :: */ - /* Return coordinates in integer pixels. */ - /* */ - /* FT_GLYPH_BBOX_PIXELS :: */ - /* Return grid-fitted pixel coordinates. */ - /* */ - typedef enum FT_Glyph_BBox_Mode_ - { - FT_GLYPH_BBOX_UNSCALED = 0, - FT_GLYPH_BBOX_SUBPIXELS = 0, - FT_GLYPH_BBOX_GRIDFIT = 1, - FT_GLYPH_BBOX_TRUNCATE = 2, - FT_GLYPH_BBOX_PIXELS = 3 - - } FT_Glyph_BBox_Mode; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_glyph_bbox_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated. Use the corresponding */ - /* @FT_Glyph_BBox_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_glyph_bbox_unscaled :: See @FT_GLYPH_BBOX_UNSCALED. */ - /* ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS. */ - /* ft_glyph_bbox_gridfit :: See @FT_GLYPH_BBOX_GRIDFIT. */ - /* ft_glyph_bbox_truncate :: See @FT_GLYPH_BBOX_TRUNCATE. */ - /* ft_glyph_bbox_pixels :: See @FT_GLYPH_BBOX_PIXELS. */ - /* */ -#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED -#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS -#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT -#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE -#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Glyph_Get_CBox */ - /* */ - /* <Description> */ - /* Return a glyph's `control box'. The control box encloses all the */ - /* outline's points, including Bézier control points. Though it */ - /* coincides with the exact bounding box for most glyphs, it can be */ - /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bézier outside arcs). */ - /* */ - /* Computing the control box is very fast, while getting the bounding */ - /* box can take much more time as it needs to walk over all segments */ - /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ - /* */ - /* <Input> */ - /* glyph :: A handle to the source glyph object. */ - /* */ - /* mode :: The mode which indicates how to interpret the returned */ - /* bounding box values. */ - /* */ - /* <Output> */ - /* acbox :: The glyph coordinate bounding box. Coordinates are */ - /* expressed in 1/64th of pixels if it is grid-fitted. */ - /* */ - /* <Note> */ - /* Coordinates are relative to the glyph origin, using the y~upwards */ - /* convention. */ - /* */ - /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ - /* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font */ - /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ - /* is another name for this constant. */ - /* */ - /* If the font is tricky and the glyph has been loaded with */ - /* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */ - /* reasonable values for the CBox it is necessary to load the glyph */ - /* at a large ppem value (so that the hinting instructions can */ - /* properly shift and scale the subglyphs), then extracting the CBox */ - /* which can be eventually converted back to font units. */ - /* */ - /* Note that the maximum coordinates are exclusive, which means that */ - /* one can compute the width and height of the glyph image (be it in */ - /* integer or 26.6 pixels) as: */ - /* */ - /* { */ - /* width = bbox.xMax - bbox.xMin; */ - /* height = bbox.yMax - bbox.yMin; */ - /* } */ - /* */ - /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ - /* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, */ - /* which corresponds to: */ - /* */ - /* { */ - /* bbox.xMin = FLOOR(bbox.xMin); */ - /* bbox.yMin = FLOOR(bbox.yMin); */ - /* bbox.xMax = CEILING(bbox.xMax); */ - /* bbox.yMax = CEILING(bbox.yMax); */ - /* } */ - /* */ - /* To get the bbox in pixel coordinates, set `bbox_mode' to */ - /* @FT_GLYPH_BBOX_TRUNCATE. */ - /* */ - /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ - /* to @FT_GLYPH_BBOX_PIXELS. */ - /* */ - FT_EXPORT( void ) - FT_Glyph_Get_CBox( FT_Glyph glyph, - FT_UInt bbox_mode, - FT_BBox *acbox ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Glyph_To_Bitmap */ - /* */ - /* <Description> */ - /* Convert a given glyph object to a bitmap glyph object. */ - /* */ - /* <InOut> */ - /* the_glyph :: A pointer to a handle to the target glyph. */ - /* */ - /* <Input> */ - /* render_mode :: An enumeration that describes how the data is */ - /* rendered. */ - /* */ - /* origin :: A pointer to a vector used to translate the glyph */ - /* image before rendering. Can be~0 (if no */ - /* translation). The origin is expressed in */ - /* 26.6 pixels. */ - /* */ - /* destroy :: A boolean that indicates that the original glyph */ - /* image should be destroyed by this function. It is */ - /* never destroyed in case of error. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function does nothing if the glyph format isn't scalable. */ - /* */ - /* The glyph image is translated with the `origin' vector before */ - /* rendering. */ - /* */ - /* The first parameter is a pointer to an @FT_Glyph handle, that will */ - /* be _replaced_ by this function (with newly allocated data). */ - /* Typically, you would use (omitting error handling): */ - /* */ - /* */ - /* { */ - /* FT_Glyph glyph; */ - /* FT_BitmapGlyph glyph_bitmap; */ - /* */ - /* */ - /* // load glyph */ - /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ - /* */ - /* // extract glyph image */ - /* error = FT_Get_Glyph( face->glyph, &glyph ); */ - /* */ - /* // convert to a bitmap (default render mode + destroying old) */ - /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ - /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ - /* 0, 1 ); */ - /* if ( error ) // `glyph' unchanged */ - /* ... */ - /* } */ - /* */ - /* // access bitmap content by typecasting */ - /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ - /* */ - /* // do funny stuff with it, like blitting/drawing */ - /* ... */ - /* */ - /* // discard glyph image (bitmap or not) */ - /* FT_Done_Glyph( glyph ); */ - /* } */ - /* */ - /* */ - /* Here another example, again without error handling: */ - /* */ - /* */ - /* { */ - /* FT_Glyph glyphs[MAX_GLYPHS] */ - /* */ - /* */ - /* ... */ - /* */ - /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ - /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ - /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ - /* */ - /* ... */ - /* */ - /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ - /* { */ - /* FT_Glyph bitmap = glyphs[idx]; */ - /* */ - /* */ - /* ... */ - /* */ - /* // after this call, `bitmap' no longer points into */ - /* // the `glyphs' array (and the old value isn't destroyed) */ - /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ - /* */ - /* ... */ - /* */ - /* FT_Done_Glyph( bitmap ); */ - /* } */ - /* */ - /* ... */ - /* */ - /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ - /* FT_Done_Glyph( glyphs[idx] ); */ - /* } */ - /* */ - FT_EXPORT( FT_Error ) - FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, - FT_Render_Mode render_mode, - FT_Vector* origin, - FT_Bool destroy ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Glyph */ - /* */ - /* <Description> */ - /* Destroy a given glyph. */ - /* */ - /* <Input> */ - /* glyph :: A handle to the target glyph object. */ - /* */ - FT_EXPORT( void ) - FT_Done_Glyph( FT_Glyph glyph ); - - /* */ - - - /* other helpful functions */ - - /*************************************************************************/ - /* */ - /* <Section> */ - /* computations */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Matrix_Multiply */ - /* */ - /* <Description> */ - /* Perform the matrix operation `b = a*b'. */ - /* */ - /* <Input> */ - /* a :: A pointer to matrix `a'. */ - /* */ - /* <InOut> */ - /* b :: A pointer to matrix `b'. */ - /* */ - /* <Note> */ - /* The result is undefined if either `a' or `b' is zero. */ - /* */ - FT_EXPORT( void ) - FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix* b ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Matrix_Invert */ - /* */ - /* <Description> */ - /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ - /* */ - /* <InOut> */ - /* matrix :: A pointer to the target matrix. Remains untouched in */ - /* case of error. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Matrix_Invert( FT_Matrix* matrix ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTGLYPH_H__ */ - - -/* END */ - - -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ diff --git a/drivers/freetype/freetype/include/freetype/ftgxval.h b/drivers/freetype/freetype/include/freetype/ftgxval.h deleted file mode 100644 index 497015c101..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftgxval.h +++ /dev/null @@ -1,358 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgxval.h */ -/* */ -/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ -/* */ -/* Copyright 2004, 2005, 2006 by */ -/* Masatake YAMATO, Redhat K.K, */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTGXVAL_H__ -#define __FTGXVAL_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* gx_validation */ - /* */ - /* <Title> */ - /* TrueTypeGX/AAT Validation */ - /* */ - /* <Abstract> */ - /* An API to validate TrueTypeGX/AAT tables. */ - /* */ - /* <Description> */ - /* This section contains the declaration of functions to validate */ - /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ - /* trak, prop, lcar). */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Warning: Use FT_VALIDATE_XXX to validate a table. */ - /* Following definitions are for gxvalid developers. */ - /* */ - /* */ - /*************************************************************************/ - -#define FT_VALIDATE_feat_INDEX 0 -#define FT_VALIDATE_mort_INDEX 1 -#define FT_VALIDATE_morx_INDEX 2 -#define FT_VALIDATE_bsln_INDEX 3 -#define FT_VALIDATE_just_INDEX 4 -#define FT_VALIDATE_kern_INDEX 5 -#define FT_VALIDATE_opbd_INDEX 6 -#define FT_VALIDATE_trak_INDEX 7 -#define FT_VALIDATE_prop_INDEX 8 -#define FT_VALIDATE_lcar_INDEX 9 -#define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX - - - /************************************************************************* - * - * @macro: - * FT_VALIDATE_GX_LENGTH - * - * @description: - * The number of tables checked in this module. Use it as a parameter - * for the `table-length' argument of function @FT_TrueTypeGX_Validate. - */ -#define FT_VALIDATE_GX_LENGTH (FT_VALIDATE_GX_LAST_INDEX + 1) - - /* */ - - /* Up to 0x1000 is used by otvalid. - Ox2xxx is reserved for feature OT extension. */ -#define FT_VALIDATE_GX_START 0x4000 -#define FT_VALIDATE_GX_BITFIELD( tag ) \ - ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) - - - /********************************************************************** - * - * @enum: - * FT_VALIDATE_GXXXX - * - * @description: - * A list of bit-field constants used with @FT_TrueTypeGX_Validate to - * indicate which TrueTypeGX/AAT Type tables should be validated. - * - * @values: - * FT_VALIDATE_feat :: - * Validate `feat' table. - * - * FT_VALIDATE_mort :: - * Validate `mort' table. - * - * FT_VALIDATE_morx :: - * Validate `morx' table. - * - * FT_VALIDATE_bsln :: - * Validate `bsln' table. - * - * FT_VALIDATE_just :: - * Validate `just' table. - * - * FT_VALIDATE_kern :: - * Validate `kern' table. - * - * FT_VALIDATE_opbd :: - * Validate `opbd' table. - * - * FT_VALIDATE_trak :: - * Validate `trak' table. - * - * FT_VALIDATE_prop :: - * Validate `prop' table. - * - * FT_VALIDATE_lcar :: - * Validate `lcar' table. - * - * FT_VALIDATE_GX :: - * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, - * opbd, trak, prop and lcar). - * - */ - -#define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat ) -#define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort ) -#define FT_VALIDATE_morx FT_VALIDATE_GX_BITFIELD( morx ) -#define FT_VALIDATE_bsln FT_VALIDATE_GX_BITFIELD( bsln ) -#define FT_VALIDATE_just FT_VALIDATE_GX_BITFIELD( just ) -#define FT_VALIDATE_kern FT_VALIDATE_GX_BITFIELD( kern ) -#define FT_VALIDATE_opbd FT_VALIDATE_GX_BITFIELD( opbd ) -#define FT_VALIDATE_trak FT_VALIDATE_GX_BITFIELD( trak ) -#define FT_VALIDATE_prop FT_VALIDATE_GX_BITFIELD( prop ) -#define FT_VALIDATE_lcar FT_VALIDATE_GX_BITFIELD( lcar ) - -#define FT_VALIDATE_GX ( FT_VALIDATE_feat | \ - FT_VALIDATE_mort | \ - FT_VALIDATE_morx | \ - FT_VALIDATE_bsln | \ - FT_VALIDATE_just | \ - FT_VALIDATE_kern | \ - FT_VALIDATE_opbd | \ - FT_VALIDATE_trak | \ - FT_VALIDATE_prop | \ - FT_VALIDATE_lcar ) - - - /* */ - - /********************************************************************** - * - * @function: - * FT_TrueTypeGX_Validate - * - * @description: - * Validate various TrueTypeGX tables to assure that all offsets and - * indices are valid. The idea is that a higher-level library which - * actually does the text layout can access those tables without - * error checking (which can be quite time consuming). - * - * @input: - * face :: - * A handle to the input face. - * - * validation_flags :: - * A bit field which specifies the tables to be validated. See - * @FT_VALIDATE_GXXXX for possible values. - * - * table_length :: - * The size of the `tables' array. Normally, @FT_VALIDATE_GX_LENGTH - * should be passed. - * - * @output: - * tables :: - * The array where all validated sfnt tables are stored. - * The array itself must be allocated by a client. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with TrueTypeGX fonts, returning an error - * otherwise. - * - * After use, the application should deallocate the buffers pointed to by - * each `tables' element, by calling @FT_TrueTypeGX_Free. A NULL value - * indicates that the table either doesn't exist in the font, the - * application hasn't asked for validation, or the validator doesn't have - * the ability to validate the sfnt table. - */ - FT_EXPORT( FT_Error ) - FT_TrueTypeGX_Validate( FT_Face face, - FT_UInt validation_flags, - FT_Bytes tables[FT_VALIDATE_GX_LENGTH], - FT_UInt table_length ); - - - /* */ - - /********************************************************************** - * - * @function: - * FT_TrueTypeGX_Free - * - * @description: - * Free the buffer allocated by TrueTypeGX validator. - * - * @input: - * face :: - * A handle to the input face. - * - * table :: - * The pointer to the buffer allocated by - * @FT_TrueTypeGX_Validate. - * - * @note: - * This function must be used to free the buffer allocated by - * @FT_TrueTypeGX_Validate only. - */ - FT_EXPORT( void ) - FT_TrueTypeGX_Free( FT_Face face, - FT_Bytes table ); - - - /* */ - - /********************************************************************** - * - * @enum: - * FT_VALIDATE_CKERNXXX - * - * @description: - * A list of bit-field constants used with @FT_ClassicKern_Validate - * to indicate the classic kern dialect or dialects. If the selected - * type doesn't fit, @FT_ClassicKern_Validate regards the table as - * invalid. - * - * @values: - * FT_VALIDATE_MS :: - * Handle the `kern' table as a classic Microsoft kern table. - * - * FT_VALIDATE_APPLE :: - * Handle the `kern' table as a classic Apple kern table. - * - * FT_VALIDATE_CKERN :: - * Handle the `kern' as either classic Apple or Microsoft kern table. - */ -#define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 ) -#define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 ) - -#define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) - - - /* */ - - /********************************************************************** - * - * @function: - * FT_ClassicKern_Validate - * - * @description: - * Validate classic (16-bit format) kern table to assure that the offsets - * and indices are valid. The idea is that a higher-level library which - * actually does the text layout can access those tables without error - * checking (which can be quite time consuming). - * - * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both - * the new 32-bit format and the classic 16-bit format, while - * FT_ClassicKern_Validate only supports the classic 16-bit format. - * - * @input: - * face :: - * A handle to the input face. - * - * validation_flags :: - * A bit field which specifies the dialect to be validated. See - * @FT_VALIDATE_CKERNXXX for possible values. - * - * @output: - * ckern_table :: - * A pointer to the kern table. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * After use, the application should deallocate the buffers pointed to by - * `ckern_table', by calling @FT_ClassicKern_Free. A NULL value - * indicates that the table doesn't exist in the font. - */ - FT_EXPORT( FT_Error ) - FT_ClassicKern_Validate( FT_Face face, - FT_UInt validation_flags, - FT_Bytes *ckern_table ); - - - /* */ - - /********************************************************************** - * - * @function: - * FT_ClassicKern_Free - * - * @description: - * Free the buffer allocated by classic Kern validator. - * - * @input: - * face :: - * A handle to the input face. - * - * table :: - * The pointer to the buffer that is allocated by - * @FT_ClassicKern_Validate. - * - * @note: - * This function must be used to free the buffer allocated by - * @FT_ClassicKern_Validate only. - */ - FT_EXPORT( void ) - FT_ClassicKern_Free( FT_Face face, - FT_Bytes table ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTGXVAL_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftgzip.h b/drivers/freetype/freetype/include/freetype/ftgzip.h deleted file mode 100644 index acbc4f0327..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftgzip.h +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgzip.h */ -/* */ -/* Gzip-compressed stream support. */ -/* */ -/* 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, */ -/* 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 __FTGZIP_H__ -#define __FTGZIP_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* <Section> */ - /* gzip */ - /* */ - /* <Title> */ - /* GZIP Streams */ - /* */ - /* <Abstract> */ - /* Using gzip-compressed font files. */ - /* */ - /* <Description> */ - /* This section contains the declaration of Gzip-specific functions. */ - /* */ - /*************************************************************************/ - - - /************************************************************************ - * - * @function: - * FT_Stream_OpenGzip - * - * @description: - * Open a new stream to parse gzip-compressed font files. This is - * mainly used to support the compressed `*.pcf.gz' fonts that come - * with XFree86. - * - * @input: - * stream :: - * The target embedding stream. - * - * source :: - * The source stream. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The source stream must be opened _before_ calling this function. - * - * Calling the internal function `FT_Stream_Close' on the new stream will - * *not* call `FT_Stream_Close' on the source stream. None of the stream - * objects will be released to the heap. - * - * The stream implementation is very basic and resets the decompression - * process each time seeking backwards is needed within the stream. - * - * In certain builds of the library, gzip compression recognition is - * automatically handled when calling @FT_New_Face or @FT_Open_Face. - * This means that if no font driver is capable of handling the raw - * compressed file, the library will try to open a gzipped stream from - * it and re-open the face with it. - * - * This function may return `FT_Err_Unimplemented_Feature' if your build - * of FreeType was not compiled with zlib support. - */ - FT_EXPORT( FT_Error ) - FT_Stream_OpenGzip( FT_Stream stream, - FT_Stream source ); - - /* */ - - -FT_END_HEADER - -#endif /* __FTGZIP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftimage.h b/drivers/freetype/freetype/include/freetype/ftimage.h deleted file mode 100644 index 3b826b1d32..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftimage.h +++ /dev/null @@ -1,1322 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftimage.h */ -/* */ -/* FreeType glyph image formats and default raster interface */ -/* (specification). */ -/* */ -/* Copyright 1996-2010, 2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Note: A `raster' is simply a scan-line converter, used to render */ - /* FT_Outlines into FT_Bitmaps. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTIMAGE_H__ -#define __FTIMAGE_H__ - - - /* _STANDALONE_ is from ftgrays.c */ -#ifndef _STANDALONE_ -#include <ft2build.h> -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* basic_types */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Pos */ - /* */ - /* <Description> */ - /* The type FT_Pos is used to store vectorial coordinates. Depending */ - /* on the context, these can represent distances in integer font */ - /* units, or 16.16, or 26.6 fixed-point pixel coordinates. */ - /* */ - typedef signed long FT_Pos; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Vector */ - /* */ - /* <Description> */ - /* A simple structure used to store a 2D vector; coordinates are of */ - /* the FT_Pos type. */ - /* */ - /* <Fields> */ - /* x :: The horizontal coordinate. */ - /* y :: The vertical coordinate. */ - /* */ - typedef struct FT_Vector_ - { - FT_Pos x; - FT_Pos y; - - } FT_Vector; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_BBox */ - /* */ - /* <Description> */ - /* A structure used to hold an outline's bounding box, i.e., the */ - /* coordinates of its extrema in the horizontal and vertical */ - /* directions. */ - /* */ - /* <Fields> */ - /* xMin :: The horizontal minimum (left-most). */ - /* */ - /* yMin :: The vertical minimum (bottom-most). */ - /* */ - /* xMax :: The horizontal maximum (right-most). */ - /* */ - /* yMax :: The vertical maximum (top-most). */ - /* */ - /* <Note> */ - /* The bounding box is specified with the coordinates of the lower */ - /* left and the upper right corner. In PostScript, those values are */ - /* often called (llx,lly) and (urx,ury), respectively. */ - /* */ - /* If `yMin' is negative, this value gives the glyph's descender. */ - /* Otherwise, the glyph doesn't descend below the baseline. */ - /* Similarly, if `ymax' is positive, this value gives the glyph's */ - /* ascender. */ - /* */ - /* `xMin' gives the horizontal distance from the glyph's origin to */ - /* the left edge of the glyph's bounding box. If `xMin' is negative, */ - /* the glyph extends to the left of the origin. */ - /* */ - typedef struct FT_BBox_ - { - FT_Pos xMin, yMin; - FT_Pos xMax, yMax; - - } FT_BBox; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Pixel_Mode */ - /* */ - /* <Description> */ - /* An enumeration type used to describe the format of pixels in a */ - /* given bitmap. Note that additional formats may be added in the */ - /* future. */ - /* */ - /* <Values> */ - /* FT_PIXEL_MODE_NONE :: */ - /* Value~0 is reserved. */ - /* */ - /* FT_PIXEL_MODE_MONO :: */ - /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ - /* are stored in most-significant order (MSB), which means that */ - /* the left-most pixel in a byte has value 128. */ - /* */ - /* FT_PIXEL_MODE_GRAY :: */ - /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ - /* images. Each pixel is stored in one byte. Note that the number */ - /* of `gray' levels is stored in the `num_grays' field of the */ - /* @FT_Bitmap structure (it generally is 256). */ - /* */ - /* FT_PIXEL_MODE_GRAY2 :: */ - /* A 2-bit per pixel bitmap, used to represent embedded */ - /* anti-aliased bitmaps in font files according to the OpenType */ - /* specification. We haven't found a single font using this */ - /* format, however. */ - /* */ - /* FT_PIXEL_MODE_GRAY4 :: */ - /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ - /* bitmaps in font files according to the OpenType specification. */ - /* We haven't found a single font using this format, however. */ - /* */ - /* FT_PIXEL_MODE_LCD :: */ - /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ - /* used for display on LCD displays; the bitmap is three times */ - /* wider than the original glyph image. See also */ - /* @FT_RENDER_MODE_LCD. */ - /* */ - /* FT_PIXEL_MODE_LCD_V :: */ - /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ - /* used for display on rotated LCD displays; the bitmap is three */ - /* times taller than the original glyph image. See also */ - /* @FT_RENDER_MODE_LCD_V. */ - /* */ - /* FT_PIXEL_MODE_BGRA :: */ - /* An image with four 8-bit channels per pixel, representing a */ - /* color image (such as emoticons) with alpha channel. For each */ - /* pixel, the format is BGRA, which means, the blue channel comes */ - /* first in memory. The color channels are pre-multiplied and in */ - /* the sRGB colorspace. For example, full red at half-translucent */ - /* opacity will be represented as `00,00,80,80', not `00,00,FF,80'. */ - /* See also @FT_LOAD_COLOR. */ - /* */ - typedef enum FT_Pixel_Mode_ - { - FT_PIXEL_MODE_NONE = 0, - FT_PIXEL_MODE_MONO, - FT_PIXEL_MODE_GRAY, - FT_PIXEL_MODE_GRAY2, - FT_PIXEL_MODE_GRAY4, - FT_PIXEL_MODE_LCD, - FT_PIXEL_MODE_LCD_V, - FT_PIXEL_MODE_BGRA, - - FT_PIXEL_MODE_MAX /* do not remove */ - - } FT_Pixel_Mode; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_pixel_mode_xxx */ - /* */ - /* <Description> */ - /* A list of deprecated constants. Use the corresponding */ - /* @FT_Pixel_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_pixel_mode_none :: See @FT_PIXEL_MODE_NONE. */ - /* ft_pixel_mode_mono :: See @FT_PIXEL_MODE_MONO. */ - /* ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY. */ - /* ft_pixel_mode_pal2 :: See @FT_PIXEL_MODE_GRAY2. */ - /* ft_pixel_mode_pal4 :: See @FT_PIXEL_MODE_GRAY4. */ - /* */ -#define ft_pixel_mode_none FT_PIXEL_MODE_NONE -#define ft_pixel_mode_mono FT_PIXEL_MODE_MONO -#define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY -#define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 -#define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 - - /* */ - -#if 0 - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Palette_Mode */ - /* */ - /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT! */ - /* */ - /* An enumeration type to describe the format of a bitmap palette, */ - /* used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ - /* */ - /* <Values> */ - /* ft_palette_mode_rgb :: The palette is an array of 3-byte RGB */ - /* records. */ - /* */ - /* ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA */ - /* records. */ - /* */ - /* <Note> */ - /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ - /* FreeType, these types are not handled by the library itself. */ - /* */ - typedef enum FT_Palette_Mode_ - { - ft_palette_mode_rgb = 0, - ft_palette_mode_rgba, - - ft_palette_mode_max /* do not remove */ - - } FT_Palette_Mode; - - /* */ - -#endif - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Bitmap */ - /* */ - /* <Description> */ - /* A structure used to describe a bitmap or pixmap to the raster. */ - /* Note that we now manage pixmaps of various depths through the */ - /* `pixel_mode' field. */ - /* */ - /* <Fields> */ - /* rows :: The number of bitmap rows. */ - /* */ - /* width :: The number of pixels in bitmap row. */ - /* */ - /* pitch :: The pitch's absolute value is the number of bytes */ - /* taken by one bitmap row, including padding. */ - /* However, the pitch is positive when the bitmap has */ - /* a `down' flow, and negative when it has an `up' */ - /* flow. In all cases, the pitch is an offset to add */ - /* to a bitmap pointer in order to go down one row. */ - /* */ - /* Note that `padding' means the alignment of a */ - /* bitmap to a byte border, and FreeType functions */ - /* normally align to the smallest possible integer */ - /* value. */ - /* */ - /* For the B/W rasterizer, `pitch' is always an even */ - /* number. */ - /* */ - /* To change the pitch of a bitmap (say, to make it a */ - /* multiple of 4), use @FT_Bitmap_Convert. */ - /* Alternatively, you might use callback functions to */ - /* directly render to the application's surface; see */ - /* the file `example2.cpp' in the tutorial for a */ - /* demonstration. */ - /* */ - /* buffer :: A typeless pointer to the bitmap buffer. This */ - /* value should be aligned on 32-bit boundaries in */ - /* most cases. */ - /* */ - /* num_grays :: This field is only used with */ - /* @FT_PIXEL_MODE_GRAY; it gives the number of gray */ - /* levels used in the bitmap. */ - /* */ - /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ - /* See @FT_Pixel_Mode for possible values. */ - /* */ - /* palette_mode :: This field is intended for paletted pixel modes; */ - /* it indicates how the palette is stored. Not */ - /* used currently. */ - /* */ - /* palette :: A typeless pointer to the bitmap palette; this */ - /* field is intended for paletted pixel modes. Not */ - /* used currently. */ - /* */ - /* <Note> */ - /* For now, the only pixel modes supported by FreeType are mono and */ - /* grays. However, drivers might be added in the future to support */ - /* more `colorful' options. */ - /* */ - typedef struct FT_Bitmap_ - { - int rows; - int width; - int pitch; - unsigned char* buffer; - short num_grays; - char pixel_mode; - char palette_mode; - void* palette; - - } FT_Bitmap; - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* outline_processing */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Outline */ - /* */ - /* <Description> */ - /* This structure is used to describe an outline to the scan-line */ - /* converter. */ - /* */ - /* <Fields> */ - /* n_contours :: The number of contours in the outline. */ - /* */ - /* n_points :: The number of points in the outline. */ - /* */ - /* points :: A pointer to an array of `n_points' @FT_Vector */ - /* elements, giving the outline's point coordinates. */ - /* */ - /* tags :: A pointer to an array of `n_points' chars, giving */ - /* each outline point's type. */ - /* */ - /* If bit~0 is unset, the point is `off' the curve, */ - /* i.e., a Bézier control point, while it is `on' if */ - /* set. */ - /* */ - /* Bit~1 is meaningful for `off' points only. If set, */ - /* it indicates a third-order Bézier arc control point; */ - /* and a second-order control point if unset. */ - /* */ - /* If bit~2 is set, bits 5-7 contain the drop-out mode */ - /* (as defined in the OpenType specification; the value */ - /* is the same as the argument to the SCANMODE */ - /* instruction). */ - /* */ - /* Bits 3 and~4 are reserved for internal purposes. */ - /* */ - /* contours :: An array of `n_contours' shorts, giving the end */ - /* point of each contour within the outline. For */ - /* example, the first contour is defined by the points */ - /* `0' to `contours[0]', the second one is defined by */ - /* the points `contours[0]+1' to `contours[1]', etc. */ - /* */ - /* flags :: A set of bit flags used to characterize the outline */ - /* and give hints to the scan-converter and hinter on */ - /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ - /* */ - /* <Note> */ - /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ - /* first point of each contour. The drop-out mode as given with */ - /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ - /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ - /* */ - typedef struct FT_Outline_ - { - short n_contours; /* number of contours in glyph */ - short n_points; /* number of points in the glyph */ - - FT_Vector* points; /* the outline's points */ - char* tags; /* the points flags */ - short* contours; /* the contour end points */ - - int flags; /* outline masks */ - - } FT_Outline; - - /* Following limits must be consistent with */ - /* FT_Outline.{n_contours,n_points} */ -#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX -#define FT_OUTLINE_POINTS_MAX SHRT_MAX - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_OUTLINE_FLAGS */ - /* */ - /* <Description> */ - /* A list of bit-field constants use for the flags in an outline's */ - /* `flags' field. */ - /* */ - /* <Values> */ - /* FT_OUTLINE_NONE :: */ - /* Value~0 is reserved. */ - /* */ - /* FT_OUTLINE_OWNER :: */ - /* If set, this flag indicates that the outline's field arrays */ - /* (i.e., `points', `flags', and `contours') are `owned' by the */ - /* outline object, and should thus be freed when it is destroyed. */ - /* */ - /* FT_OUTLINE_EVEN_ODD_FILL :: */ - /* By default, outlines are filled using the non-zero winding rule. */ - /* If set to 1, the outline will be filled using the even-odd fill */ - /* rule (only works with the smooth rasterizer). */ - /* */ - /* FT_OUTLINE_REVERSE_FILL :: */ - /* By default, outside contours of an outline are oriented in */ - /* clock-wise direction, as defined in the TrueType specification. */ - /* This flag is set if the outline uses the opposite direction */ - /* (typically for Type~1 fonts). This flag is ignored by the scan */ - /* converter. */ - /* */ - /* FT_OUTLINE_IGNORE_DROPOUTS :: */ - /* By default, the scan converter will try to detect drop-outs in */ - /* an outline and correct the glyph bitmap to ensure consistent */ - /* shape continuity. If set, this flag hints the scan-line */ - /* converter to ignore such cases. See below for more information. */ - /* */ - /* FT_OUTLINE_SMART_DROPOUTS :: */ - /* Select smart dropout control. If unset, use simple dropout */ - /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ - /* below for more information. */ - /* */ - /* FT_OUTLINE_INCLUDE_STUBS :: */ - /* If set, turn pixels on for `stubs', otherwise exclude them. */ - /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ - /* more information. */ - /* */ - /* FT_OUTLINE_HIGH_PRECISION :: */ - /* This flag indicates that the scan-line converter should try to */ - /* convert this outline to bitmaps with the highest possible */ - /* quality. It is typically set for small character sizes. Note */ - /* that this is only a hint that might be completely ignored by a */ - /* given scan-converter. */ - /* */ - /* FT_OUTLINE_SINGLE_PASS :: */ - /* This flag is set to force a given scan-converter to only use a */ - /* single pass over the outline to render a bitmap glyph image. */ - /* Normally, it is set for very large character sizes. It is only */ - /* a hint that might be completely ignored by a given */ - /* scan-converter. */ - /* */ - /* <Note> */ - /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ - /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ - /* rasterizer. */ - /* */ - /* There exists a second mechanism to pass the drop-out mode to the */ - /* B/W rasterizer; see the `tags' field in @FT_Outline. */ - /* */ - /* Please refer to the description of the `SCANTYPE' instruction in */ - /* the OpenType specification (in file `ttinst1.doc') how simple */ - /* drop-outs, smart drop-outs, and stubs are defined. */ - /* */ -#define FT_OUTLINE_NONE 0x0 -#define FT_OUTLINE_OWNER 0x1 -#define FT_OUTLINE_EVEN_ODD_FILL 0x2 -#define FT_OUTLINE_REVERSE_FILL 0x4 -#define FT_OUTLINE_IGNORE_DROPOUTS 0x8 -#define FT_OUTLINE_SMART_DROPOUTS 0x10 -#define FT_OUTLINE_INCLUDE_STUBS 0x20 - -#define FT_OUTLINE_HIGH_PRECISION 0x100 -#define FT_OUTLINE_SINGLE_PASS 0x200 - - - /************************************************************************* - * - * @enum: - * ft_outline_flags - * - * @description: - * These constants are deprecated. Please use the corresponding - * @FT_OUTLINE_FLAGS values. - * - * @values: - * ft_outline_none :: See @FT_OUTLINE_NONE. - * ft_outline_owner :: See @FT_OUTLINE_OWNER. - * ft_outline_even_odd_fill :: See @FT_OUTLINE_EVEN_ODD_FILL. - * ft_outline_reverse_fill :: See @FT_OUTLINE_REVERSE_FILL. - * ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS. - * ft_outline_high_precision :: See @FT_OUTLINE_HIGH_PRECISION. - * ft_outline_single_pass :: See @FT_OUTLINE_SINGLE_PASS. - */ -#define ft_outline_none FT_OUTLINE_NONE -#define ft_outline_owner FT_OUTLINE_OWNER -#define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL -#define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL -#define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS -#define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION -#define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS - - /* */ - -#define FT_CURVE_TAG( flag ) ( flag & 3 ) - -#define FT_CURVE_TAG_ON 1 -#define FT_CURVE_TAG_CONIC 0 -#define FT_CURVE_TAG_CUBIC 2 - -#define FT_CURVE_TAG_HAS_SCANMODE 4 - -#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ -#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ - -#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ - FT_CURVE_TAG_TOUCH_Y ) - -#define FT_Curve_Tag_On FT_CURVE_TAG_ON -#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC -#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC -#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X -#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Outline_MoveToFunc */ - /* */ - /* <Description> */ - /* A function pointer type used to describe the signature of a `move */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `move to' is emitted to start a new contour in an outline. */ - /* */ - /* <Input> */ - /* to :: A pointer to the target point of the `move to'. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of the */ - /* decomposition function. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ - typedef int - (*FT_Outline_MoveToFunc)( const FT_Vector* to, - void* user ); - -#define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Outline_LineToFunc */ - /* */ - /* <Description> */ - /* A function pointer type used to describe the signature of a `line */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `line to' is emitted to indicate a segment in the outline. */ - /* */ - /* <Input> */ - /* to :: A pointer to the target point of the `line to'. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of the */ - /* decomposition function. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ - typedef int - (*FT_Outline_LineToFunc)( const FT_Vector* to, - void* user ); - -#define FT_Outline_LineTo_Func FT_Outline_LineToFunc - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Outline_ConicToFunc */ - /* */ - /* <Description> */ - /* A function pointer type used to describe the signature of a `conic */ - /* to' function during outline walking or decomposition. */ - /* */ - /* A `conic to' is emitted to indicate a second-order Bézier arc in */ - /* the outline. */ - /* */ - /* <Input> */ - /* control :: An intermediate control point between the last position */ - /* and the new target in `to'. */ - /* */ - /* to :: A pointer to the target end point of the conic arc. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of */ - /* the decomposition function. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ - typedef int - (*FT_Outline_ConicToFunc)( const FT_Vector* control, - const FT_Vector* to, - void* user ); - -#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Outline_CubicToFunc */ - /* */ - /* <Description> */ - /* A function pointer type used to describe the signature of a `cubic */ - /* to' function during outline walking or decomposition. */ - /* */ - /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ - /* */ - /* <Input> */ - /* control1 :: A pointer to the first Bézier control point. */ - /* */ - /* control2 :: A pointer to the second Bézier control point. */ - /* */ - /* to :: A pointer to the target end point. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of */ - /* the decomposition function. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ - typedef int - (*FT_Outline_CubicToFunc)( const FT_Vector* control1, - const FT_Vector* control2, - const FT_Vector* to, - void* user ); - -#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Outline_Funcs */ - /* */ - /* <Description> */ - /* A structure to hold various function pointers used during outline */ - /* decomposition in order to emit segments, conic, and cubic Béziers. */ - /* */ - /* <Fields> */ - /* move_to :: The `move to' emitter. */ - /* */ - /* line_to :: The segment emitter. */ - /* */ - /* conic_to :: The second-order Bézier arc emitter. */ - /* */ - /* cubic_to :: The third-order Bézier arc emitter. */ - /* */ - /* shift :: The shift that is applied to coordinates before they */ - /* are sent to the emitter. */ - /* */ - /* delta :: The delta that is applied to coordinates before they */ - /* are sent to the emitter, but after the shift. */ - /* */ - /* <Note> */ - /* The point coordinates sent to the emitters are the transformed */ - /* version of the original coordinates (this is important for high */ - /* accuracy during scan-conversion). The transformation is simple: */ - /* */ - /* { */ - /* x' = (x << shift) - delta */ - /* y' = (x << shift) - delta */ - /* } */ - /* */ - /* Set the values of `shift' and `delta' to~0 to get the original */ - /* point coordinates. */ - /* */ - typedef struct FT_Outline_Funcs_ - { - FT_Outline_MoveToFunc move_to; - FT_Outline_LineToFunc line_to; - FT_Outline_ConicToFunc conic_to; - FT_Outline_CubicToFunc cubic_to; - - int shift; - FT_Pos delta; - - } FT_Outline_Funcs; - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* basic_types */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_IMAGE_TAG */ - /* */ - /* <Description> */ - /* This macro converts four-letter tags to an unsigned long type. */ - /* */ - /* <Note> */ - /* Since many 16-bit compilers don't like 32-bit enumerations, you */ - /* should redefine this macro in case of problems to something like */ - /* this: */ - /* */ - /* { */ - /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ - /* } */ - /* */ - /* to get a simple enumeration without assigning special numbers. */ - /* */ -#ifndef FT_IMAGE_TAG -#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ - value = ( ( (unsigned long)_x1 << 24 ) | \ - ( (unsigned long)_x2 << 16 ) | \ - ( (unsigned long)_x3 << 8 ) | \ - (unsigned long)_x4 ) -#endif /* FT_IMAGE_TAG */ - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Glyph_Format */ - /* */ - /* <Description> */ - /* An enumeration type used to describe the format of a given glyph */ - /* image. Note that this version of FreeType only supports two image */ - /* formats, even though future font drivers will be able to register */ - /* their own format. */ - /* */ - /* <Values> */ - /* FT_GLYPH_FORMAT_NONE :: */ - /* The value~0 is reserved. */ - /* */ - /* FT_GLYPH_FORMAT_COMPOSITE :: */ - /* The glyph image is a composite of several other images. This */ - /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ - /* report compound glyphs (like accented characters). */ - /* */ - /* FT_GLYPH_FORMAT_BITMAP :: */ - /* The glyph image is a bitmap, and can be described as an */ - /* @FT_Bitmap. You generally need to access the `bitmap' field of */ - /* the @FT_GlyphSlotRec structure to read it. */ - /* */ - /* FT_GLYPH_FORMAT_OUTLINE :: */ - /* The glyph image is a vectorial outline made of line segments */ - /* and Bézier arcs; it can be described as an @FT_Outline; you */ - /* generally want to access the `outline' field of the */ - /* @FT_GlyphSlotRec structure to read it. */ - /* */ - /* FT_GLYPH_FORMAT_PLOTTER :: */ - /* The glyph image is a vectorial path with no inside and outside */ - /* contours. Some Type~1 fonts, like those in the Hershey family, */ - /* contain glyphs in this format. These are described as */ - /* @FT_Outline, but FreeType isn't currently capable of rendering */ - /* them correctly. */ - /* */ - typedef enum FT_Glyph_Format_ - { - FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), - - FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ), - FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ), - FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ), - FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ) - - } FT_Glyph_Format; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_glyph_format_xxx */ - /* */ - /* <Description> */ - /* A list of deprecated constants. Use the corresponding */ - /* @FT_Glyph_Format values instead. */ - /* */ - /* <Values> */ - /* ft_glyph_format_none :: See @FT_GLYPH_FORMAT_NONE. */ - /* ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE. */ - /* ft_glyph_format_bitmap :: See @FT_GLYPH_FORMAT_BITMAP. */ - /* ft_glyph_format_outline :: See @FT_GLYPH_FORMAT_OUTLINE. */ - /* ft_glyph_format_plotter :: See @FT_GLYPH_FORMAT_PLOTTER. */ - /* */ -#define ft_glyph_format_none FT_GLYPH_FORMAT_NONE -#define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE -#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP -#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE -#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** R A S T E R D E F I N I T I O N S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* A raster is a scan converter, in charge of rendering an outline into */ - /* a a bitmap. This section contains the public API for rasters. */ - /* */ - /* Note that in FreeType 2, all rasters are now encapsulated within */ - /* specific modules called `renderers'. See `freetype/ftrender.h' for */ - /* more details on renderers. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* raster */ - /* */ - /* <Title> */ - /* Scanline Converter */ - /* */ - /* <Abstract> */ - /* How vectorial outlines are converted into bitmaps and pixmaps. */ - /* */ - /* <Description> */ - /* This section contains technical definitions. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Raster */ - /* */ - /* <Description> */ - /* A handle (pointer) to a raster object. Each object can be used */ - /* independently to convert an outline into a bitmap or pixmap. */ - /* */ - typedef struct FT_RasterRec_* FT_Raster; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Span */ - /* */ - /* <Description> */ - /* A structure used to model a single span of gray (or black) pixels */ - /* when rendering a monochrome or anti-aliased bitmap. */ - /* */ - /* <Fields> */ - /* x :: The span's horizontal start position. */ - /* */ - /* len :: The span's length in pixels. */ - /* */ - /* coverage :: The span color/coverage, ranging from 0 (background) */ - /* to 255 (foreground). Only used for anti-aliased */ - /* rendering. */ - /* */ - /* <Note> */ - /* This structure is used by the span drawing callback type named */ - /* @FT_SpanFunc which takes the y~coordinate of the span as a */ - /* a parameter. */ - /* */ - /* The coverage value is always between 0 and 255. If you want less */ - /* gray values, the callback function has to reduce them. */ - /* */ - typedef struct FT_Span_ - { - short x; - unsigned short len; - unsigned char coverage; - - } FT_Span; - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_SpanFunc */ - /* */ - /* <Description> */ - /* A function used as a call-back by the anti-aliased renderer in */ - /* order to let client applications draw themselves the gray pixel */ - /* spans on each scan line. */ - /* */ - /* <Input> */ - /* y :: The scanline's y~coordinate. */ - /* */ - /* count :: The number of spans to draw on this scanline. */ - /* */ - /* spans :: A table of `count' spans to draw on the scanline. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* <Note> */ - /* This callback allows client applications to directly render the */ - /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ - /* */ - /* This can be used to write anti-aliased outlines directly to a */ - /* given background bitmap, and even perform translucency. */ - /* */ - /* Note that the `count' field cannot be greater than a fixed value */ - /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ - /* `ftoption.h'. By default, this value is set to~32, which means */ - /* that if there are more than 32~spans on a given scanline, the */ - /* callback is called several times with the same `y' parameter in */ - /* order to draw all callbacks. */ - /* */ - /* Otherwise, the callback is only called once per scan-line, and */ - /* only for those scanlines that do have `gray' pixels on them. */ - /* */ - typedef void - (*FT_SpanFunc)( int y, - int count, - const FT_Span* spans, - void* user ); - -#define FT_Raster_Span_Func FT_SpanFunc - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_BitTest_Func */ - /* */ - /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to test whether a given target pixel is already set to the drawing */ - /* `color'. These tests are crucial to implement drop-out control */ - /* per-se the TrueType spec. */ - /* */ - /* <Input> */ - /* y :: The pixel's y~coordinate. */ - /* */ - /* x :: The pixel's x~coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* <Return> */ - /* 1~if the pixel is `set', 0~otherwise. */ - /* */ - typedef int - (*FT_Raster_BitTest_Func)( int y, - int x, - void* user ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_BitSet_Func */ - /* */ - /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to set an individual target pixel. This is crucial to implement */ - /* drop-out control according to the TrueType specification. */ - /* */ - /* <Input> */ - /* y :: The pixel's y~coordinate. */ - /* */ - /* x :: The pixel's x~coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* <Return> */ - /* 1~if the pixel is `set', 0~otherwise. */ - /* */ - typedef void - (*FT_Raster_BitSet_Func)( int y, - int x, - void* user ); - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_RASTER_FLAG_XXX */ - /* */ - /* <Description> */ - /* A list of bit flag constants as used in the `flags' field of a */ - /* @FT_Raster_Params structure. */ - /* */ - /* <Values> */ - /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ - /* */ - /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ - /* anti-aliased glyph image should be */ - /* generated. Otherwise, it will be */ - /* monochrome (1-bit). */ - /* */ - /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ - /* rendering. In this mode, client */ - /* applications must provide their own span */ - /* callback. This lets them directly */ - /* draw or compose over an existing bitmap. */ - /* If this bit is not set, the target */ - /* pixmap's buffer _must_ be zeroed before */ - /* rendering. */ - /* */ - /* Note that for now, direct rendering is */ - /* only possible with anti-aliased glyphs. */ - /* */ - /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ - /* rendering mode. If set, the output will */ - /* be clipped to a box specified in the */ - /* `clip_box' field of the */ - /* @FT_Raster_Params structure. */ - /* */ - /* Note that by default, the glyph bitmap */ - /* is clipped to the target pixmap, except */ - /* in direct rendering mode where all spans */ - /* are generated if no clipping box is set. */ - /* */ -#define FT_RASTER_FLAG_DEFAULT 0x0 -#define FT_RASTER_FLAG_AA 0x1 -#define FT_RASTER_FLAG_DIRECT 0x2 -#define FT_RASTER_FLAG_CLIP 0x4 - - /* deprecated */ -#define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT -#define ft_raster_flag_aa FT_RASTER_FLAG_AA -#define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT -#define ft_raster_flag_clip FT_RASTER_FLAG_CLIP - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Raster_Params */ - /* */ - /* <Description> */ - /* A structure to hold the arguments used by a raster's render */ - /* function. */ - /* */ - /* <Fields> */ - /* target :: The target bitmap. */ - /* */ - /* source :: A pointer to the source glyph image (e.g., an */ - /* @FT_Outline). */ - /* */ - /* flags :: The rendering flags. */ - /* */ - /* gray_spans :: The gray span drawing callback. */ - /* */ - /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ - /* */ - /* bit_test :: The bit test callback. UNIMPLEMENTED! */ - /* */ - /* bit_set :: The bit set callback. UNIMPLEMENTED! */ - /* */ - /* user :: User-supplied data that is passed to each drawing */ - /* callback. */ - /* */ - /* clip_box :: An optional clipping box. It is only used in */ - /* direct rendering mode. Note that coordinates here */ - /* should be expressed in _integer_ pixels (and not in */ - /* 26.6 fixed-point units). */ - /* */ - /* <Note> */ - /* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA */ - /* bit flag is set in the `flags' field, otherwise a monochrome */ - /* bitmap is generated. */ - /* */ - /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ - /* raster will call the `gray_spans' callback to draw gray pixel */ - /* spans, in the case of an aa glyph bitmap, it will call */ - /* `black_spans', and `bit_test' and `bit_set' in the case of a */ - /* monochrome bitmap. This allows direct composition over a */ - /* pre-existing bitmap through user-provided callbacks to perform the */ - /* span drawing/composition. */ - /* */ - /* Note that the `bit_test' and `bit_set' callbacks are required when */ - /* rendering a monochrome bitmap, as they are crucial to implement */ - /* correct drop-out control as defined in the TrueType specification. */ - /* */ - typedef struct FT_Raster_Params_ - { - const FT_Bitmap* target; - const void* source; - int flags; - FT_SpanFunc gray_spans; - FT_SpanFunc black_spans; /* doesn't work! */ - FT_Raster_BitTest_Func bit_test; /* doesn't work! */ - FT_Raster_BitSet_Func bit_set; /* doesn't work! */ - void* user; - FT_BBox clip_box; - - } FT_Raster_Params; - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_NewFunc */ - /* */ - /* <Description> */ - /* A function used to create a new raster object. */ - /* */ - /* <Input> */ - /* memory :: A handle to the memory allocator. */ - /* */ - /* <Output> */ - /* raster :: A handle to the new raster object. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ - /* <Note> */ - /* The `memory' parameter is a typeless pointer in order to avoid */ - /* un-wanted dependencies on the rest of the FreeType code. In */ - /* practice, it is an @FT_Memory object, i.e., a handle to the */ - /* standard FreeType memory allocator. However, this field can be */ - /* completely ignored by a given raster implementation. */ - /* */ - typedef int - (*FT_Raster_NewFunc)( void* memory, - FT_Raster* raster ); - -#define FT_Raster_New_Func FT_Raster_NewFunc - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_DoneFunc */ - /* */ - /* <Description> */ - /* A function used to destroy a given raster object. */ - /* */ - /* <Input> */ - /* raster :: A handle to the raster object. */ - /* */ - typedef void - (*FT_Raster_DoneFunc)( FT_Raster raster ); - -#define FT_Raster_Done_Func FT_Raster_DoneFunc - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_ResetFunc */ - /* */ - /* <Description> */ - /* FreeType provides an area of memory called the `render pool', */ - /* available to all registered rasters. This pool can be freely used */ - /* during a given scan-conversion but is shared by all rasters. Its */ - /* content is thus transient. */ - /* */ - /* This function is called each time the render pool changes, or just */ - /* after a new raster object is created. */ - /* */ - /* <Input> */ - /* raster :: A handle to the new raster object. */ - /* */ - /* pool_base :: The address in memory of the render pool. */ - /* */ - /* pool_size :: The size in bytes of the render pool. */ - /* */ - /* <Note> */ - /* Rasters can ignore the render pool and rely on dynamic memory */ - /* allocation if they want to (a handle to the memory allocator is */ - /* passed to the raster constructor). However, this is not */ - /* recommended for efficiency purposes. */ - /* */ - typedef void - (*FT_Raster_ResetFunc)( FT_Raster raster, - unsigned char* pool_base, - unsigned long pool_size ); - -#define FT_Raster_Reset_Func FT_Raster_ResetFunc - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_SetModeFunc */ - /* */ - /* <Description> */ - /* This function is a generic facility to change modes or attributes */ - /* in a given raster. This can be used for debugging purposes, or */ - /* simply to allow implementation-specific `features' in a given */ - /* raster module. */ - /* */ - /* <Input> */ - /* raster :: A handle to the new raster object. */ - /* */ - /* mode :: A 4-byte tag used to name the mode or property. */ - /* */ - /* args :: A pointer to the new mode/property to use. */ - /* */ - typedef int - (*FT_Raster_SetModeFunc)( FT_Raster raster, - unsigned long mode, - void* args ); - -#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_RenderFunc */ - /* */ - /* <Description> */ - /* Invoke a given raster to scan-convert a given glyph image into a */ - /* target bitmap. */ - /* */ - /* <Input> */ - /* raster :: A handle to the raster object. */ - /* */ - /* params :: A pointer to an @FT_Raster_Params structure used to */ - /* store the rendering parameters. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ - /* <Note> */ - /* The exact format of the source image depends on the raster's glyph */ - /* format defined in its @FT_Raster_Funcs structure. It can be an */ - /* @FT_Outline or anything else in order to support a large array of */ - /* glyph formats. */ - /* */ - /* Note also that the render function can fail and return a */ - /* `FT_Err_Unimplemented_Feature' error code if the raster used does */ - /* not support direct composition. */ - /* */ - /* XXX: For now, the standard raster doesn't support direct */ - /* composition but this should change for the final release (see */ - /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ - /* for examples of distinct implementations which support direct */ - /* composition). */ - /* */ - typedef int - (*FT_Raster_RenderFunc)( FT_Raster raster, - const FT_Raster_Params* params ); - -#define FT_Raster_Render_Func FT_Raster_RenderFunc - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Raster_Funcs */ - /* */ - /* <Description> */ - /* A structure used to describe a given raster class to the library. */ - /* */ - /* <Fields> */ - /* glyph_format :: The supported glyph format for this raster. */ - /* */ - /* raster_new :: The raster constructor. */ - /* */ - /* raster_reset :: Used to reset the render pool within the raster. */ - /* */ - /* raster_render :: A function to render a glyph into a given bitmap. */ - /* */ - /* raster_done :: The raster destructor. */ - /* */ - typedef struct FT_Raster_Funcs_ - { - FT_Glyph_Format glyph_format; - FT_Raster_NewFunc raster_new; - FT_Raster_ResetFunc raster_reset; - FT_Raster_SetModeFunc raster_set_mode; - FT_Raster_RenderFunc raster_render; - FT_Raster_DoneFunc raster_done; - - } FT_Raster_Funcs; - - - /* */ - - -FT_END_HEADER - -#endif /* __FTIMAGE_H__ */ - - -/* END */ - - -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ diff --git a/drivers/freetype/freetype/include/freetype/ftincrem.h b/drivers/freetype/freetype/include/freetype/ftincrem.h deleted file mode 100644 index aaf689ff16..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftincrem.h +++ /dev/null @@ -1,353 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftincrem.h */ -/* */ -/* FreeType incremental loading (specification). */ -/* */ -/* Copyright 2002, 2003, 2006, 2007, 2008, 2010 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 __FTINCREM_H__ -#define __FTINCREM_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - /*************************************************************************** - * - * @section: - * incremental - * - * @title: - * Incremental Loading - * - * @abstract: - * Custom Glyph Loading. - * - * @description: - * This section contains various functions used to perform so-called - * `incremental' glyph loading. This is a mode where all glyphs loaded - * from a given @FT_Face are provided by the client application, - * - * Apart from that, all other tables are loaded normally from the font - * file. This mode is useful when FreeType is used within another - * engine, e.g., a PostScript Imaging Processor. - * - * To enable this mode, you must use @FT_Open_Face, passing an - * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an - * @FT_Incremental_Interface value. See the comments for - * @FT_Incremental_InterfaceRec for an example. - * - */ - - - /*************************************************************************** - * - * @type: - * FT_Incremental - * - * @description: - * An opaque type describing a user-provided object used to implement - * `incremental' glyph loading within FreeType. This is used to support - * embedded fonts in certain environments (e.g., PostScript interpreters), - * where the glyph data isn't in the font file, or must be overridden by - * different values. - * - * @note: - * It is up to client applications to create and implement @FT_Incremental - * objects, as long as they provide implementations for the methods - * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc - * and @FT_Incremental_GetGlyphMetricsFunc. - * - * See the description of @FT_Incremental_InterfaceRec to understand how - * to use incremental objects with FreeType. - * - */ - typedef struct FT_IncrementalRec_* FT_Incremental; - - - /*************************************************************************** - * - * @struct: - * FT_Incremental_MetricsRec - * - * @description: - * A small structure used to contain the basic glyph metrics returned - * by the @FT_Incremental_GetGlyphMetricsFunc method. - * - * @fields: - * bearing_x :: - * Left bearing, in font units. - * - * bearing_y :: - * Top bearing, in font units. - * - * advance :: - * Horizontal component of glyph advance, in font units. - * - * advance_v :: - * Vertical component of glyph advance, in font units. - * - * @note: - * These correspond to horizontal or vertical metrics depending on the - * value of the `vertical' argument to the function - * @FT_Incremental_GetGlyphMetricsFunc. - * - */ - typedef struct FT_Incremental_MetricsRec_ - { - FT_Long bearing_x; - FT_Long bearing_y; - FT_Long advance; - FT_Long advance_v; /* since 2.3.12 */ - - } FT_Incremental_MetricsRec; - - - /*************************************************************************** - * - * @struct: - * FT_Incremental_Metrics - * - * @description: - * A handle to an @FT_Incremental_MetricsRec structure. - * - */ - typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; - - - /*************************************************************************** - * - * @type: - * FT_Incremental_GetGlyphDataFunc - * - * @description: - * A function called by FreeType to access a given glyph's data bytes - * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is - * enabled. - * - * Note that the format of the glyph's data bytes depends on the font - * file format. For TrueType, it must correspond to the raw bytes within - * the `glyf' table. For PostScript formats, it must correspond to the - * *unencrypted* charstring bytes, without any `lenIV' header. It is - * undefined for any other format. - * - * @input: - * incremental :: - * Handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * glyph_index :: - * Index of relevant glyph. - * - * @output: - * adata :: - * A structure describing the returned glyph data bytes (which will be - * accessed as a read-only byte block). - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If this function returns successfully the method - * @FT_Incremental_FreeGlyphDataFunc will be called later to release - * the data bytes. - * - * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for - * compound glyphs. - * - */ - typedef FT_Error - (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, - FT_UInt glyph_index, - FT_Data* adata ); - - - /*************************************************************************** - * - * @type: - * FT_Incremental_FreeGlyphDataFunc - * - * @description: - * A function used to release the glyph data bytes returned by a - * successful call to @FT_Incremental_GetGlyphDataFunc. - * - * @input: - * incremental :: - * A handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * data :: - * A structure describing the glyph data bytes (which will be accessed - * as a read-only byte block). - * - */ - typedef void - (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, - FT_Data* data ); - - - /*************************************************************************** - * - * @type: - * FT_Incremental_GetGlyphMetricsFunc - * - * @description: - * A function used to retrieve the basic metrics of a given glyph index - * before accessing its data. This is necessary because, in certain - * formats like TrueType, the metrics are stored in a different place from - * the glyph images proper. - * - * @input: - * incremental :: - * A handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * glyph_index :: - * Index of relevant glyph. - * - * vertical :: - * If true, return vertical metrics. - * - * ametrics :: - * This parameter is used for both input and output. - * The original glyph metrics, if any, in font units. If metrics are - * not available all the values must be set to zero. - * - * @output: - * ametrics :: - * The replacement glyph metrics in font units. - * - */ - typedef FT_Error - (*FT_Incremental_GetGlyphMetricsFunc) - ( FT_Incremental incremental, - FT_UInt glyph_index, - FT_Bool vertical, - FT_Incremental_MetricsRec *ametrics ); - - - /************************************************************************** - * - * @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. - * - * free_glyph_data :: - * The function to release glyph data. Must not be null. - * - * get_glyph_metrics :: - * The function to get glyph metrics. May be null if the font does - * not provide overriding glyph metrics. - * - */ - typedef struct FT_Incremental_FuncsRec_ - { - FT_Incremental_GetGlyphDataFunc get_glyph_data; - FT_Incremental_FreeGlyphDataFunc free_glyph_data; - FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; - - } FT_Incremental_FuncsRec; - - - /*************************************************************************** - * - * @struct: - * FT_Incremental_InterfaceRec - * - * @description: - * A structure to be used with @FT_Open_Face to indicate that the user - * wants to support incremental glyph loading. You should use it with - * @FT_PARAM_TAG_INCREMENTAL as in the following example: - * - * { - * FT_Incremental_InterfaceRec inc_int; - * FT_Parameter parameter; - * FT_Open_Args open_args; - * - * - * // set up incremental descriptor - * inc_int.funcs = my_funcs; - * inc_int.object = my_object; - * - * // set up optional parameter - * parameter.tag = FT_PARAM_TAG_INCREMENTAL; - * parameter.data = &inc_int; - * - * // set up FT_Open_Args structure - * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; - * open_args.pathname = my_font_pathname; - * open_args.num_params = 1; - * open_args.params = ¶meter; // we use one optional argument - * - * // open the font - * error = FT_Open_Face( library, &open_args, index, &face ); - * ... - * } - * - */ - typedef struct FT_Incremental_InterfaceRec_ - { - const FT_Incremental_FuncsRec* funcs; - FT_Incremental object; - - } FT_Incremental_InterfaceRec; - - - /*************************************************************************** - * - * @type: - * FT_Incremental_Interface - * - * @description: - * A pointer to an @FT_Incremental_InterfaceRec structure. - * - */ - typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; - - - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_INCREMENTAL - * - * @description: - * A constant used as the tag of @FT_Parameter structures to indicate - * an incremental loading object to be used by FreeType. - * - */ -#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) - - /* */ - -FT_END_HEADER - -#endif /* __FTINCREM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftlcdfil.h b/drivers/freetype/freetype/include/freetype/ftlcdfil.h deleted file mode 100644 index 8b253f118b..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftlcdfil.h +++ /dev/null @@ -1,251 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlcdfil.h */ -/* */ -/* FreeType API for color filtering of subpixel bitmap glyphs */ -/* (specification). */ -/* */ -/* Copyright 2006, 2007, 2008, 2010 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 - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -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. - * - * FreeType generates alpha coverage maps, which are linear by nature. - * For instance, the value 0x80 in bitmap representation means that - * (within numerical precision) 0x80/0xff fraction of that pixel is - * covered by the glyph's outline. The blending function for placing - * text over a background is - * - * { - * dst = alpha * src + (1 - alpha) * dst , - * } - * - * which is known as OVER. However, when calculating the output of the - * OVER operator, the source colors should first be transformed to a - * linear color space, then alpha blended in that space, and transformed - * back to the output color space. - * - * When linear light blending is used, the default FIR5 filtering - * weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as - * they have been designed for black on white rendering while lacking - * gamma correction. To preserve color neutrality, weights for a FIR5 - * filter should be chosen according to two free parameters `a' and `c', - * and the FIR weights should be - * - * { - * [a - c, a + c, 2 * a, a + c, a - c] . - * } - * - * This formula generates equal weights for all the color primaries - * across the filter kernel, which makes it colorless. One suggested - * set of weights is - * - * { - * [0x10, 0x50, 0x60, 0x50, 0x10] , - * } - * - * where `a' has value 0x30 and `b' value 0x20. The weights in filter - * may have a sum larger than 0x100, which increases coloration slightly - * but also improves contrast. - */ - - - /**************************************************************************** - * - * @enum: - * 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_LcdFilter_ - { - 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 ); - - - /************************************************************************** - * - * @func: - * FT_Library_SetLcdFilterWeights - * - * @description: - * Use this function to override the filter weights selected by - * @FT_Library_SetLcdFilter. By default, FreeType uses the quintuple - * (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10, - * 0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and - * FT_LCD_FILTER_LEGACY. - * - * @input: - * library :: - * A handle to the target library instance. - * - * weights :: - * A pointer to an array; the function copies the first five bytes and - * uses them to specify the filter weights. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * 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. - * - * This function must be called after @FT_Library_SetLcdFilter to have - * any effect. - * - * @since: - * 2.4.0 - */ - FT_EXPORT( FT_Error ) - FT_Library_SetLcdFilterWeights( FT_Library library, - unsigned char *weights ); - - /* */ - - -FT_END_HEADER - -#endif /* __FT_LCD_FILTER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftlist.h b/drivers/freetype/freetype/include/freetype/ftlist.h deleted file mode 100644 index bb6f7f119d..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftlist.h +++ /dev/null @@ -1,277 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlist.h */ -/* */ -/* Generic list support for FreeType (specification). */ -/* */ -/* Copyright 1996-2001, 2003, 2007, 2010 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file implements functions relative to list processing. Its */ - /* data structures are defined in `freetype.h'. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTLIST_H__ -#define __FTLIST_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* list_processing */ - /* */ - /* <Title> */ - /* List Processing */ - /* */ - /* <Abstract> */ - /* Simple management of lists. */ - /* */ - /* <Description> */ - /* This section contains various definitions related to list */ - /* processing using doubly-linked nodes. */ - /* */ - /* <Order> */ - /* FT_List */ - /* FT_ListNode */ - /* FT_ListRec */ - /* FT_ListNodeRec */ - /* */ - /* FT_List_Add */ - /* FT_List_Insert */ - /* FT_List_Find */ - /* FT_List_Remove */ - /* FT_List_Up */ - /* FT_List_Iterate */ - /* FT_List_Iterator */ - /* FT_List_Finalize */ - /* FT_List_Destructor */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Find */ - /* */ - /* <Description> */ - /* Find the list node for a given listed object. */ - /* */ - /* <Input> */ - /* list :: A pointer to the parent list. */ - /* data :: The address of the listed object. */ - /* */ - /* <Return> */ - /* List node. NULL if it wasn't found. */ - /* */ - FT_EXPORT( FT_ListNode ) - FT_List_Find( FT_List list, - void* data ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Add */ - /* */ - /* <Description> */ - /* Append an element to the end of a list. */ - /* */ - /* <InOut> */ - /* list :: A pointer to the parent list. */ - /* node :: The node to append. */ - /* */ - FT_EXPORT( void ) - FT_List_Add( FT_List list, - FT_ListNode node ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Insert */ - /* */ - /* <Description> */ - /* Insert an element at the head of a list. */ - /* */ - /* <InOut> */ - /* list :: A pointer to parent list. */ - /* node :: The node to insert. */ - /* */ - FT_EXPORT( void ) - FT_List_Insert( FT_List list, - FT_ListNode node ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Remove */ - /* */ - /* <Description> */ - /* Remove a node from a list. This function doesn't check whether */ - /* the node is in the list! */ - /* */ - /* <Input> */ - /* node :: The node to remove. */ - /* */ - /* <InOut> */ - /* list :: A pointer to the parent list. */ - /* */ - FT_EXPORT( void ) - FT_List_Remove( FT_List list, - FT_ListNode node ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Up */ - /* */ - /* <Description> */ - /* Move a node to the head/top of a list. Used to maintain LRU */ - /* lists. */ - /* */ - /* <InOut> */ - /* list :: A pointer to the parent list. */ - /* node :: The node to move. */ - /* */ - FT_EXPORT( void ) - FT_List_Up( FT_List list, - FT_ListNode node ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_List_Iterator */ - /* */ - /* <Description> */ - /* An FT_List iterator function which is called during a list parse */ - /* by @FT_List_Iterate. */ - /* */ - /* <Input> */ - /* node :: The current iteration list node. */ - /* */ - /* user :: A typeless pointer passed to @FT_List_Iterate. */ - /* Can be used to point to the iteration's state. */ - /* */ - typedef FT_Error - (*FT_List_Iterator)( FT_ListNode node, - void* user ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Iterate */ - /* */ - /* <Description> */ - /* Parse a list and calls a given iterator function on each element. */ - /* Note that parsing is stopped as soon as one of the iterator calls */ - /* returns a non-zero value. */ - /* */ - /* <Input> */ - /* list :: A handle to the list. */ - /* iterator :: An iterator function, called on each node of the list. */ - /* user :: A user-supplied field which is passed as the second */ - /* argument to the iterator. */ - /* */ - /* <Return> */ - /* The result (a FreeType error code) of the last iterator call. */ - /* */ - FT_EXPORT( FT_Error ) - FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_List_Destructor */ - /* */ - /* <Description> */ - /* An @FT_List iterator function which is called during a list */ - /* finalization by @FT_List_Finalize to destroy all elements in a */ - /* given list. */ - /* */ - /* <Input> */ - /* system :: The current system object. */ - /* */ - /* data :: The current object to destroy. */ - /* */ - /* user :: A typeless pointer passed to @FT_List_Iterate. It can */ - /* be used to point to the iteration's state. */ - /* */ - typedef void - (*FT_List_Destructor)( FT_Memory memory, - void* data, - void* user ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Finalize */ - /* */ - /* <Description> */ - /* Destroy all elements in the list as well as the list itself. */ - /* */ - /* <Input> */ - /* list :: A handle to the list. */ - /* */ - /* destroy :: A list destructor that will be applied to each element */ - /* of the list. */ - /* */ - /* memory :: The current memory object which handles deallocation. */ - /* */ - /* user :: A user-supplied field which is passed as the last */ - /* argument to the destructor. */ - /* */ - /* <Note> */ - /* This function expects that all nodes added by @FT_List_Add or */ - /* @FT_List_Insert have been dynamically allocated. */ - /* */ - FT_EXPORT( void ) - FT_List_Finalize( FT_List list, - FT_List_Destructor destroy, - FT_Memory memory, - void* user ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTLIST_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftlzw.h b/drivers/freetype/freetype/include/freetype/ftlzw.h deleted file mode 100644 index 00d40169a7..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftlzw.h +++ /dev/null @@ -1,99 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlzw.h */ -/* */ -/* LZW-compressed stream support. */ -/* */ -/* Copyright 2004, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTLZW_H__ -#define __FTLZW_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* <Section> */ - /* lzw */ - /* */ - /* <Title> */ - /* LZW Streams */ - /* */ - /* <Abstract> */ - /* Using LZW-compressed font files. */ - /* */ - /* <Description> */ - /* This section contains the declaration of LZW-specific functions. */ - /* */ - /*************************************************************************/ - - /************************************************************************ - * - * @function: - * FT_Stream_OpenLZW - * - * @description: - * Open a new stream to parse LZW-compressed font files. This is - * mainly used to support the compressed `*.pcf.Z' fonts that come - * with XFree86. - * - * @input: - * stream :: The target embedding stream. - * - * source :: The source stream. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The source stream must be opened _before_ calling this function. - * - * Calling the internal function `FT_Stream_Close' on the new stream will - * *not* call `FT_Stream_Close' on the source stream. None of the stream - * objects will be released to the heap. - * - * The stream implementation is very basic and resets the decompression - * process each time seeking backwards is needed within the stream - * - * In certain builds of the library, LZW compression recognition is - * automatically handled when calling @FT_New_Face or @FT_Open_Face. - * This means that if no font driver is capable of handling the raw - * compressed file, the library will try to open a LZW stream from it - * and re-open the face with it. - * - * This function may return `FT_Err_Unimplemented_Feature' if your build - * of FreeType was not compiled with LZW support. - */ - FT_EXPORT( FT_Error ) - FT_Stream_OpenLZW( FT_Stream stream, - FT_Stream source ); - - /* */ - - -FT_END_HEADER - -#endif /* __FTLZW_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftmac.h b/drivers/freetype/freetype/include/freetype/ftmac.h deleted file mode 100644 index ab5bab5170..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftmac.h +++ /dev/null @@ -1,274 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmac.h */ -/* */ -/* Additional Mac-specific API. */ -/* */ -/* Copyright 1996-2001, 2004, 2006, 2007 by */ -/* Just van Rossum, 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. */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* NOTE: Include this file after <freetype/freetype.h> and after any */ -/* Mac-specific headers (because this header uses Mac types such as */ -/* Handle, FSSpec, FSRef, etc.) */ -/* */ -/***************************************************************************/ - - -#ifndef __FTMAC_H__ -#define __FTMAC_H__ - - -#include <ft2build.h> - - -FT_BEGIN_HEADER - - -/* gcc-3.4.1 and later can warn about functions tagged as deprecated */ -#ifndef FT_DEPRECATED_ATTRIBUTE -#if defined(__GNUC__) && \ - ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) -#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) -#else -#define FT_DEPRECATED_ATTRIBUTE -#endif -#endif - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* mac_specific */ - /* */ - /* <Title> */ - /* Mac Specific Interface */ - /* */ - /* <Abstract> */ - /* Only available on the Macintosh. */ - /* */ - /* <Description> */ - /* The following definitions are only available if FreeType is */ - /* compiled on a Macintosh. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FOND */ - /* */ - /* <Description> */ - /* Create a new face object from a FOND resource. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* fond :: A FOND resource. */ - /* */ - /* face_index :: Only supported for the -1 `sanity check' special */ - /* case. */ - /* */ - /* <Output> */ - /* aface :: A handle to a new face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Notes> */ - /* This function can be used to create @FT_Face objects from fonts */ - /* that are installed in the system as follows. */ - /* */ - /* { */ - /* fond = GetResource( 'FOND', fontName ); */ - /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ - /* } */ - /* */ - FT_EXPORT( FT_Error ) - FT_New_Face_From_FOND( FT_Library library, - Handle fond, - FT_Long face_index, - FT_Face *aface ) - FT_DEPRECATED_ATTRIBUTE; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_GetFile_From_Mac_Name */ - /* */ - /* <Description> */ - /* Return an FSSpec for the disk file containing the named font. */ - /* */ - /* <Input> */ - /* fontName :: Mac OS name of the font (e.g., Times New Roman */ - /* Bold). */ - /* */ - /* <Output> */ - /* pathSpec :: FSSpec to the file. For passing to */ - /* @FT_New_Face_From_FSSpec. */ - /* */ - /* face_index :: Index of the face. For passing to */ - /* @FT_New_Face_From_FSSpec. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_GetFile_From_Mac_Name( const char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) - FT_DEPRECATED_ATTRIBUTE; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_GetFile_From_Mac_ATS_Name */ - /* */ - /* <Description> */ - /* Return an FSSpec for the disk file containing the named font. */ - /* */ - /* <Input> */ - /* fontName :: Mac OS name of the font in ATS framework. */ - /* */ - /* <Output> */ - /* pathSpec :: FSSpec to the file. For passing to */ - /* @FT_New_Face_From_FSSpec. */ - /* */ - /* face_index :: Index of the face. For passing to */ - /* @FT_New_Face_From_FSSpec. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_GetFile_From_Mac_ATS_Name( const char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) - FT_DEPRECATED_ATTRIBUTE; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_GetFilePath_From_Mac_ATS_Name */ - /* */ - /* <Description> */ - /* Return a pathname of the disk file and face index for given font */ - /* name which is handled by ATS framework. */ - /* */ - /* <Input> */ - /* fontName :: Mac OS name of the font in ATS framework. */ - /* */ - /* <Output> */ - /* path :: Buffer to store pathname of the file. For passing */ - /* to @FT_New_Face. The client must allocate this */ - /* buffer before calling this function. */ - /* */ - /* maxPathSize :: Lengths of the buffer `path' that client allocated. */ - /* */ - /* face_index :: Index of the face. For passing to @FT_New_Face. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, - UInt8* path, - UInt32 maxPathSize, - FT_Long* face_index ) - FT_DEPRECATED_ATTRIBUTE; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FSSpec */ - /* */ - /* <Description> */ - /* Create a new face object from a given resource and typeface index */ - /* using an FSSpec to the font file. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* spec :: FSSpec to the font file. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index~0. */ - /* <Output> */ - /* aface :: A handle to a new face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ - /* it accepts an FSSpec instead of a path. */ - /* */ - FT_EXPORT( FT_Error ) - FT_New_Face_From_FSSpec( FT_Library library, - const FSSpec *spec, - FT_Long face_index, - FT_Face *aface ) - FT_DEPRECATED_ATTRIBUTE; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FSRef */ - /* */ - /* <Description> */ - /* Create a new face object from a given resource and typeface index */ - /* using an FSRef to the font file. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* spec :: FSRef to the font file. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index~0. */ - /* <Output> */ - /* aface :: A handle to a new face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ - /* it accepts an FSRef instead of a path. */ - /* */ - FT_EXPORT( FT_Error ) - FT_New_Face_From_FSRef( FT_Library library, - const FSRef *ref, - FT_Long face_index, - FT_Face *aface ) - FT_DEPRECATED_ATTRIBUTE; - - /* */ - - -FT_END_HEADER - - -#endif /* __FTMAC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftmm.h b/drivers/freetype/freetype/include/freetype/ftmm.h deleted file mode 100644 index 3aefb9e4f2..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftmm.h +++ /dev/null @@ -1,378 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmm.h */ -/* */ -/* FreeType Multiple Master font interface (specification). */ -/* */ -/* Copyright 1996-2001, 2003, 2004, 2006, 2009 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 __FTMM_H__ -#define __FTMM_H__ - - -#include <ft2build.h> -#include FT_TYPE1_TABLES_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* multiple_masters */ - /* */ - /* <Title> */ - /* Multiple Masters */ - /* */ - /* <Abstract> */ - /* How to manage Multiple Masters fonts. */ - /* */ - /* <Description> */ - /* The following types and functions are used to manage Multiple */ - /* Master fonts, i.e., the selection of specific design instances by */ - /* setting design axis coordinates. */ - /* */ - /* George Williams has extended this interface to make it work with */ - /* both Type~1 Multiple Masters fonts and GX distortable (var) */ - /* fonts. Some of these routines only work with MM fonts, others */ - /* will work with both types. They are similar enough that a */ - /* consistent interface makes sense. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_MM_Axis */ - /* */ - /* <Description> */ - /* A simple structure used to model a given axis in design space for */ - /* Multiple Masters fonts. */ - /* */ - /* This structure can't be used for GX var fonts. */ - /* */ - /* <Fields> */ - /* name :: The axis's name. */ - /* */ - /* minimum :: The axis's minimum design coordinate. */ - /* */ - /* maximum :: The axis's maximum design coordinate. */ - /* */ - typedef struct FT_MM_Axis_ - { - FT_String* name; - FT_Long minimum; - FT_Long maximum; - - } FT_MM_Axis; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Multi_Master */ - /* */ - /* <Description> */ - /* A structure used to model the axes and space of a Multiple Masters */ - /* font. */ - /* */ - /* This structure can't be used for GX var fonts. */ - /* */ - /* <Fields> */ - /* num_axis :: Number of axes. Cannot exceed~4. */ - /* */ - /* num_designs :: Number of designs; should be normally 2^num_axis */ - /* even though the Type~1 specification strangely */ - /* allows for intermediate designs to be present. This */ - /* number cannot exceed~16. */ - /* */ - /* axis :: A table of axis descriptors. */ - /* */ - typedef struct FT_Multi_Master_ - { - FT_UInt num_axis; - FT_UInt num_designs; - FT_MM_Axis axis[T1_MAX_MM_AXIS]; - - } FT_Multi_Master; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Var_Axis */ - /* */ - /* <Description> */ - /* A simple structure used to model a given axis in design space for */ - /* Multiple Masters and GX var fonts. */ - /* */ - /* <Fields> */ - /* name :: The axis's name. */ - /* Not always meaningful for GX. */ - /* */ - /* minimum :: The axis's minimum design coordinate. */ - /* */ - /* def :: The axis's default design coordinate. */ - /* FreeType computes meaningful default values for MM; it */ - /* is then an integer value, not in 16.16 format. */ - /* */ - /* maximum :: The axis's maximum design coordinate. */ - /* */ - /* tag :: The axis's tag (the GX equivalent to `name'). */ - /* FreeType provides default values for MM if possible. */ - /* */ - /* strid :: The entry in `name' table (another GX version of */ - /* `name'). */ - /* Not meaningful for MM. */ - /* */ - typedef struct FT_Var_Axis_ - { - FT_String* name; - - FT_Fixed minimum; - FT_Fixed def; - FT_Fixed maximum; - - FT_ULong tag; - FT_UInt strid; - - } FT_Var_Axis; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Var_Named_Style */ - /* */ - /* <Description> */ - /* A simple structure used to model a named style in a GX var font. */ - /* */ - /* This structure can't be used for MM fonts. */ - /* */ - /* <Fields> */ - /* coords :: The design coordinates for this style. */ - /* This is an array with one entry for each axis. */ - /* */ - /* strid :: The entry in `name' table identifying this style. */ - /* */ - typedef struct FT_Var_Named_Style_ - { - FT_Fixed* coords; - FT_UInt strid; - - } FT_Var_Named_Style; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_MM_Var */ - /* */ - /* <Description> */ - /* A structure used to model the axes and space of a Multiple Masters */ - /* or GX var distortable font. */ - /* */ - /* Some fields are specific to one format and not to the other. */ - /* */ - /* <Fields> */ - /* num_axis :: The number of axes. The maximum value is~4 for */ - /* MM; no limit in GX. */ - /* */ - /* num_designs :: The number of designs; should be normally */ - /* 2^num_axis for MM fonts. Not meaningful for GX */ - /* (where every glyph could have a different */ - /* number of designs). */ - /* */ - /* num_namedstyles :: The number of named styles; only meaningful for */ - /* GX which allows certain design coordinates to */ - /* have a string ID (in the `name' table) */ - /* associated with them. The font can tell the */ - /* user that, for example, Weight=1.5 is `Bold'. */ - /* */ - /* axis :: A table of axis descriptors. */ - /* GX fonts contain slightly more data than MM. */ - /* */ - /* namedstyles :: A table of named styles. */ - /* Only meaningful with GX. */ - /* */ - typedef struct FT_MM_Var_ - { - FT_UInt num_axis; - FT_UInt num_designs; - FT_UInt num_namedstyles; - FT_Var_Axis* axis; - FT_Var_Named_Style* namedstyle; - - } FT_MM_Var; - - - /* */ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Multi_Master */ - /* */ - /* <Description> */ - /* Retrieve the Multiple Master descriptor of a given font. */ - /* */ - /* This function can't be used with GX fonts. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* <Output> */ - /* amaster :: The Multiple Masters descriptor. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_Multi_Master( FT_Face face, - FT_Multi_Master *amaster ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_MM_Var */ - /* */ - /* <Description> */ - /* Retrieve the Multiple Master/GX var descriptor of a given font. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* <Output> */ - /* amaster :: The Multiple Masters/GX var descriptor. */ - /* Allocates a data structure, which the user must free */ - /* (a single call to FT_FREE will do it). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_MM_Var( FT_Face face, - FT_MM_Var* *amaster ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_MM_Design_Coordinates */ - /* */ - /* <Description> */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through design coordinates. */ - /* */ - /* This function can't be used with GX fonts. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face. */ - /* */ - /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: An array of design coordinates. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Set_MM_Design_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Var_Design_Coordinates */ - /* */ - /* <Description> */ - /* For Multiple Master or GX Var fonts, choose an interpolated font */ - /* design through design coordinates. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face. */ - /* */ - /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: An array of design coordinates. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Set_Var_Design_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_MM_Blend_Coordinates */ - /* */ - /* <Description> */ - /* For Multiple Masters and GX var fonts, choose an interpolated font */ - /* design through normalized blend coordinates. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face. */ - /* */ - /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: The design coordinates array (each element must be */ - /* between 0 and 1.0). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Set_MM_Blend_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Var_Blend_Coordinates */ - /* */ - /* <Description> */ - /* This is another name of @FT_Set_MM_Blend_Coordinates. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Set_Var_Blend_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTMM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftmodapi.h b/drivers/freetype/freetype/include/freetype/ftmodapi.h deleted file mode 100644 index 8abffb558f..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftmodapi.h +++ /dev/null @@ -1,641 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmodapi.h */ -/* */ -/* FreeType modules public interface (specification). */ -/* */ -/* Copyright 1996-2003, 2006, 2008-2010, 2012, 2013 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 __FTMODAPI_H__ -#define __FTMODAPI_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* module_management */ - /* */ - /* <Title> */ - /* Module Management */ - /* */ - /* <Abstract> */ - /* How to add, upgrade, remove, and control modules from FreeType. */ - /* */ - /* <Description> */ - /* The definitions below are used to manage modules within FreeType. */ - /* Modules can be added, upgraded, and removed at runtime. */ - /* Additionally, some module properties can be controlled also. */ - /* */ - /* Here is a list of possible values of the `module_name' field in */ - /* the @FT_Module_Class structure. */ - /* */ - /* { */ - /* autofitter */ - /* bdf */ - /* cff */ - /* gxvalid */ - /* otvalid */ - /* pcf */ - /* pfr */ - /* psaux */ - /* pshinter */ - /* psnames */ - /* raster1, raster5 */ - /* sfnt */ - /* smooth, smooth-lcd, smooth-lcdv */ - /* truetype */ - /* type1 */ - /* type42 */ - /* t1cid */ - /* winfonts */ - /* } */ - /* */ - /* Note that the FreeType Cache sub-system is not a FreeType module. */ - /* */ - /*************************************************************************/ - - - /* module bit flags */ -#define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ -#define FT_MODULE_RENDERER 2 /* this module is a renderer */ -#define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ -#define FT_MODULE_STYLER 8 /* this module is a styler */ - -#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ - /* scalable fonts */ -#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ - /* support vector outlines */ -#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ - /* own hinter */ - - - /* deprecated values */ -#define ft_module_font_driver FT_MODULE_FONT_DRIVER -#define ft_module_renderer FT_MODULE_RENDERER -#define ft_module_hinter FT_MODULE_HINTER -#define ft_module_styler FT_MODULE_STYLER - -#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE -#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES -#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER - - - typedef FT_Pointer FT_Module_Interface; - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Constructor */ - /* */ - /* <Description> */ - /* A function used to initialize (not create) a new module object. */ - /* */ - /* <Input> */ - /* module :: The module to initialize. */ - /* */ - typedef FT_Error - (*FT_Module_Constructor)( FT_Module module ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Destructor */ - /* */ - /* <Description> */ - /* A function used to finalize (not destroy) a given module object. */ - /* */ - /* <Input> */ - /* module :: The module to finalize. */ - /* */ - typedef void - (*FT_Module_Destructor)( FT_Module module ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Requester */ - /* */ - /* <Description> */ - /* A function used to query a given module for a specific interface. */ - /* */ - /* <Input> */ - /* module :: The module to be searched. */ - /* */ - /* name :: The name of the interface in the module. */ - /* */ - typedef FT_Module_Interface - (*FT_Module_Requester)( FT_Module module, - const char* name ); - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Module_Class */ - /* */ - /* <Description> */ - /* The module class descriptor. */ - /* */ - /* <Fields> */ - /* module_flags :: Bit flags describing the module. */ - /* */ - /* module_size :: The size of one module object/instance in */ - /* bytes. */ - /* */ - /* module_name :: The name of the module. */ - /* */ - /* module_version :: The version, as a 16.16 fixed number */ - /* (major.minor). */ - /* */ - /* module_requires :: The version of FreeType this module requires, */ - /* as a 16.16 fixed number (major.minor). Starts */ - /* at version 2.0, i.e., 0x20000. */ - /* */ - /* module_init :: The initializing function. */ - /* */ - /* module_done :: The finalizing function. */ - /* */ - /* get_interface :: The interface requesting function. */ - /* */ - typedef struct FT_Module_Class_ - { - FT_ULong module_flags; - FT_Long module_size; - const FT_String* module_name; - FT_Fixed module_version; - FT_Fixed module_requires; - - const void* module_interface; - - FT_Module_Constructor module_init; - FT_Module_Destructor module_done; - FT_Module_Requester get_interface; - - } FT_Module_Class; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Add_Module */ - /* */ - /* <Description> */ - /* Add a new module to a given library instance. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library object. */ - /* */ - /* <Input> */ - /* clazz :: A pointer to class descriptor for the module. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Add_Module( FT_Library library, - const FT_Module_Class* clazz ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Module */ - /* */ - /* <Description> */ - /* Find a module by its name. */ - /* */ - /* <Input> */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* <Return> */ - /* A module handle. 0~if none was found. */ - /* */ - /* <Note> */ - /* FreeType's internal modules aren't documented very well, and you */ - /* should look up the source code for details. */ - /* */ - FT_EXPORT( FT_Module ) - FT_Get_Module( FT_Library library, - const char* module_name ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Remove_Module */ - /* */ - /* <Description> */ - /* Remove a given module from a library instance. */ - /* */ - /* <InOut> */ - /* library :: A handle to a library object. */ - /* */ - /* <Input> */ - /* module :: A handle to a module object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The module object is destroyed by the function in case of success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Remove_Module( FT_Library library, - FT_Module module ); - - - /********************************************************************** - * - * @function: - * FT_Property_Set - * - * @description: - * Set a property for a given module. - * - * @input: - * library :: - * A handle to the library the module is part of. - * - * module_name :: - * The module name. - * - * property_name :: - * The property name. Properties are described in the `Synopsis' - * subsection of the module's documentation. - * - * Note that only a few modules have properties. - * - * value :: - * A generic pointer to a variable or structure which gives the new - * value of the property. The exact definition of `value' is - * dependent on the property; see the `Synopsis' subsection of the - * module's documentation. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If `module_name' isn't a valid module name, or `property_name' - * doesn't specify a valid property, or if `value' doesn't represent a - * valid value for the given property, an error is returned. - * - * The following example sets property `bar' (a simple integer) in - * module `foo' to value~1. - * - * { - * FT_UInt bar; - * - * - * bar = 1; - * FT_Property_Set( library, "foo", "bar", &bar ); - * } - * - * Note that the FreeType Cache sub-system doesn't recognize module - * property changes. To avoid glyph lookup confusion within the cache - * you should call @FTC_Manager_Reset to completely flush the cache if - * a module property gets changed after @FTC_Manager_New has been - * called. - * - * It is not possible to set properties of the FreeType Cache - * sub-system itself with FT_Property_Set; use @FTC_Property_Set - * instead. - * - * @since: - * 2.4.11 - * - */ - FT_EXPORT( FT_Error ) - FT_Property_Set( FT_Library library, - const FT_String* module_name, - const FT_String* property_name, - const void* value ); - - - /********************************************************************** - * - * @function: - * FT_Property_Get - * - * @description: - * Get a module's property value. - * - * @input: - * library :: - * A handle to the library the module is part of. - * - * module_name :: - * The module name. - * - * property_name :: - * The property name. Properties are described in the `Synopsis' - * subsection of the module's documentation. - * - * @inout: - * value :: - * A generic pointer to a variable or structure which gives the - * value of the property. The exact definition of `value' is - * dependent on the property; see the `Synopsis' subsection of the - * module's documentation. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If `module_name' isn't a valid module name, or `property_name' - * doesn't specify a valid property, or if `value' doesn't represent a - * valid value for the given property, an error is returned. - * - * The following example gets property `baz' (a range) in module `foo'. - * - * { - * typedef range_ - * { - * FT_Int32 min; - * FT_Int32 max; - * - * } range; - * - * range baz; - * - * - * FT_Property_Get( library, "foo", "baz", &baz ); - * } - * - * It is not possible to retrieve properties of the FreeType Cache - * sub-system with FT_Property_Get; use @FTC_Property_Get instead. - * - * @since: - * 2.4.11 - * - */ - FT_EXPORT( FT_Error ) - FT_Property_Get( FT_Library library, - const FT_String* module_name, - const FT_String* property_name, - void* value ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Reference_Library */ - /* */ - /* <Description> */ - /* A counter gets initialized to~1 at the time an @FT_Library */ - /* structure is created. This function increments the counter. */ - /* @FT_Done_Library then only destroys a library if the counter is~1, */ - /* otherwise it simply decrements the counter. */ - /* */ - /* This function helps in managing life-cycles of structures which */ - /* reference @FT_Library objects. */ - /* */ - /* <Input> */ - /* library :: A handle to a target library object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Since> */ - /* 2.4.2 */ - /* */ - FT_EXPORT( FT_Error ) - FT_Reference_Library( FT_Library library ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Library */ - /* */ - /* <Description> */ - /* This function is used to create a new FreeType library instance */ - /* from a given memory object. It is thus possible to use libraries */ - /* with distinct memory allocators within the same program. */ - /* */ - /* Normally, you would call this function (followed by a call to */ - /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ - /* instead of @FT_Init_FreeType to initialize the FreeType library. */ - /* */ - /* Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a */ - /* library instance. */ - /* */ - /* <Input> */ - /* memory :: A handle to the original memory object. */ - /* */ - /* <Output> */ - /* alibrary :: A pointer to handle of a new library object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* See the discussion of reference counters in the description of */ - /* @FT_Reference_Library. */ - /* */ - FT_EXPORT( FT_Error ) - FT_New_Library( FT_Memory memory, - FT_Library *alibrary ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Library */ - /* */ - /* <Description> */ - /* Discard a given library object. This closes all drivers and */ - /* discards all resource objects. */ - /* */ - /* <Input> */ - /* library :: A handle to the target library. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* See the discussion of reference counters in the description of */ - /* @FT_Reference_Library. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Done_Library( FT_Library library ); - -/* */ - - typedef void - (*FT_DebugHook_Func)( void* arg ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Debug_Hook */ - /* */ - /* <Description> */ - /* Set a debug hook function for debugging the interpreter of a font */ - /* format. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library object. */ - /* */ - /* <Input> */ - /* hook_index :: The index of the debug hook. You should use the */ - /* values defined in `ftobjs.h', e.g., */ - /* `FT_DEBUG_HOOK_TRUETYPE'. */ - /* */ - /* debug_hook :: The function used to debug the interpreter. */ - /* */ - /* <Note> */ - /* Currently, four debug hook slots are available, but only two (for */ - /* the TrueType and the Type~1 interpreter) are defined. */ - /* */ - /* Since the internal headers of FreeType are no longer installed, */ - /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ - /* This is a bug and will be fixed in a forthcoming release. */ - /* */ - FT_EXPORT( void ) - FT_Set_Debug_Hook( FT_Library library, - FT_UInt hook_index, - FT_DebugHook_Func debug_hook ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Add_Default_Modules */ - /* */ - /* <Description> */ - /* Add the set of default drivers to a given library object. */ - /* This is only useful when you create a library object with */ - /* @FT_New_Library (usually to plug a custom memory manager). */ - /* */ - /* <InOut> */ - /* library :: A handle to a new library object. */ - /* */ - FT_EXPORT( void ) - FT_Add_Default_Modules( FT_Library library ); - - - - /************************************************************************** - * - * @section: - * truetype_engine - * - * @title: - * The TrueType Engine - * - * @abstract: - * TrueType bytecode support. - * - * @description: - * This section contains a function used to query the level of TrueType - * bytecode support compiled in this version of the library. - * - */ - - - /************************************************************************** - * - * @enum: - * FT_TrueTypeEngineType - * - * @description: - * A list of values describing which kind of TrueType bytecode - * engine is implemented in a given FT_Library instance. It is used - * by the @FT_Get_TrueType_Engine_Type function. - * - * @values: - * FT_TRUETYPE_ENGINE_TYPE_NONE :: - * The library doesn't implement any kind of bytecode interpreter. - * - * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: - * The library implements a bytecode interpreter that doesn't - * support the patented operations of the TrueType virtual machine. - * - * Its main use is to load certain Asian fonts which position and - * scale glyph components with bytecode instructions. It produces - * bad output for most other fonts. - * - * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: - * The library implements a bytecode interpreter that covers - * the full instruction set of the TrueType virtual machine (this - * was governed by patents until May 2010, hence the name). - * - * @since: - * 2.2 - * - */ - typedef enum FT_TrueTypeEngineType_ - { - FT_TRUETYPE_ENGINE_TYPE_NONE = 0, - FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, - FT_TRUETYPE_ENGINE_TYPE_PATENTED - - } FT_TrueTypeEngineType; - - - /************************************************************************** - * - * @func: - * FT_Get_TrueType_Engine_Type - * - * @description: - * Return an @FT_TrueTypeEngineType value to indicate which level of - * the TrueType virtual machine a given library instance supports. - * - * @input: - * library :: - * A library instance. - * - * @return: - * A value indicating which level is supported. - * - * @since: - * 2.2 - * - */ - FT_EXPORT( FT_TrueTypeEngineType ) - FT_Get_TrueType_Engine_Type( FT_Library library ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTMODAPI_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftmoderr.h b/drivers/freetype/freetype/include/freetype/ftmoderr.h deleted file mode 100644 index 5a27db151a..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftmoderr.h +++ /dev/null @@ -1,194 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmoderr.h */ -/* */ -/* FreeType module error offsets (specification). */ -/* */ -/* Copyright 2001-2005, 2010, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the FreeType module error codes. */ - /* */ - /* If the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in `ftoption.h' is */ - /* set, the lower byte of an error value identifies the error code as */ - /* usual. In addition, the higher byte identifies the module. For */ - /* example, the error `FT_Err_Invalid_File_Format' has value 0x0003, the */ - /* error `TT_Err_Invalid_File_Format' has value 0x1303, the error */ - /* `T1_Err_Invalid_File_Format' has value 0x1403, etc. */ - /* */ - /* Note that `FT_Err_Ok', `TT_Err_Ok', etc. are always equal to zero, */ - /* including the high byte. */ - /* */ - /* If FT_CONFIG_OPTION_USE_MODULE_ERRORS isn't set, the higher byte of */ - /* an error value is set to zero. */ - /* */ - /* To hide the various `XXX_Err_' prefixes in the source code, FreeType */ - /* provides some macros in `fttypes.h'. */ - /* */ - /* FT_ERR( err ) */ - /* Add current error module prefix (as defined with the */ - /* `FT_ERR_PREFIX' macro) to `err'. For example, in the BDF module */ - /* the line */ - /* */ - /* error = FT_ERR( Invalid_Outline ); */ - /* */ - /* expands to */ - /* */ - /* error = BDF_Err_Invalid_Outline; */ - /* */ - /* For simplicity, you can always use `FT_Err_Ok' directly instead */ - /* of `FT_ERR( Ok )'. */ - /* */ - /* FT_ERR_EQ( errcode, err ) */ - /* FT_ERR_NEQ( errcode, err ) */ - /* Compare error code `errcode' with the error `err' for equality */ - /* and inequality, respectively. Example: */ - /* */ - /* if ( FT_ERR_EQ( error, Invalid_Outline ) ) */ - /* ... */ - /* */ - /* Using this macro you don't have to think about error prefixes. */ - /* Of course, if module errors are not active, the above example is */ - /* the same as */ - /* */ - /* if ( error == FT_Err_Invalid_Outline ) */ - /* ... */ - /* */ - /* FT_ERROR_BASE( errcode ) */ - /* FT_ERROR_MODULE( errcode ) */ - /* Get base error and module error code, respectively. */ - /* */ - /* */ - /* It can also be used to create a module error message table easily */ - /* with something like */ - /* */ - /* { */ - /* #undef __FTMODERR_H__ */ - /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ - /* #define FT_MODERR_START_LIST { */ - /* #define FT_MODERR_END_LIST { 0, 0 } }; */ - /* */ - /* const struct */ - /* { */ - /* int mod_err_offset; */ - /* const char* mod_err_msg */ - /* } ft_mod_errors[] = */ - /* */ - /* #include FT_MODULE_ERRORS_H */ - /* } */ - /* */ - /*************************************************************************/ - - -#ifndef __FTMODERR_H__ -#define __FTMODERR_H__ - - - /*******************************************************************/ - /*******************************************************************/ - /***** *****/ - /***** SETUP MACROS *****/ - /***** *****/ - /*******************************************************************/ - /*******************************************************************/ - - -#undef FT_NEED_EXTERN_C - -#ifndef FT_MODERRDEF - -#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS -#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = v, -#else -#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, -#endif - -#define FT_MODERR_START_LIST enum { -#define FT_MODERR_END_LIST FT_Mod_Err_Max }; - -#ifdef __cplusplus -#define FT_NEED_EXTERN_C - extern "C" { -#endif - -#endif /* !FT_MODERRDEF */ - - - /*******************************************************************/ - /*******************************************************************/ - /***** *****/ - /***** LIST MODULE ERROR BASES *****/ - /***** *****/ - /*******************************************************************/ - /*******************************************************************/ - - -#ifdef FT_MODERR_START_LIST - FT_MODERR_START_LIST -#endif - - - FT_MODERRDEF( Base, 0x000, "base module" ) - FT_MODERRDEF( Autofit, 0x100, "autofitter module" ) - FT_MODERRDEF( BDF, 0x200, "BDF module" ) - FT_MODERRDEF( Bzip2, 0x300, "Bzip2 module" ) - FT_MODERRDEF( Cache, 0x400, "cache module" ) - FT_MODERRDEF( CFF, 0x500, "CFF module" ) - FT_MODERRDEF( CID, 0x600, "CID module" ) - FT_MODERRDEF( Gzip, 0x700, "Gzip module" ) - FT_MODERRDEF( LZW, 0x800, "LZW module" ) - FT_MODERRDEF( OTvalid, 0x900, "OpenType validation module" ) - FT_MODERRDEF( PCF, 0xA00, "PCF module" ) - FT_MODERRDEF( PFR, 0xB00, "PFR module" ) - FT_MODERRDEF( PSaux, 0xC00, "PS auxiliary module" ) - FT_MODERRDEF( PShinter, 0xD00, "PS hinter module" ) - FT_MODERRDEF( PSnames, 0xE00, "PS names module" ) - FT_MODERRDEF( Raster, 0xF00, "raster module" ) - FT_MODERRDEF( SFNT, 0x1000, "SFNT module" ) - FT_MODERRDEF( Smooth, 0x1100, "smooth raster module" ) - FT_MODERRDEF( TrueType, 0x1200, "TrueType module" ) - FT_MODERRDEF( Type1, 0x1300, "Type 1 module" ) - FT_MODERRDEF( Type42, 0x1400, "Type 42 module" ) - FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" ) - FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" ) - - -#ifdef FT_MODERR_END_LIST - FT_MODERR_END_LIST -#endif - - - /*******************************************************************/ - /*******************************************************************/ - /***** *****/ - /***** CLEANUP *****/ - /***** *****/ - /*******************************************************************/ - /*******************************************************************/ - - -#ifdef FT_NEED_EXTERN_C - } -#endif - -#undef FT_MODERR_START_LIST -#undef FT_MODERR_END_LIST -#undef FT_MODERRDEF -#undef FT_NEED_EXTERN_C - - -#endif /* __FTMODERR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftotval.h b/drivers/freetype/freetype/include/freetype/ftotval.h deleted file mode 100644 index 027f2e8865..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftotval.h +++ /dev/null @@ -1,203 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftotval.h */ -/* */ -/* FreeType API for validating OpenType tables (specification). */ -/* */ -/* 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, */ -/* 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. */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* */ -/* Warning: This module might be moved to a different library in the */ -/* future to avoid a tight dependency between FreeType and the */ -/* OpenType specification. */ -/* */ -/* */ -/***************************************************************************/ - - -#ifndef __FTOTVAL_H__ -#define __FTOTVAL_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* ot_validation */ - /* */ - /* <Title> */ - /* OpenType Validation */ - /* */ - /* <Abstract> */ - /* An API to validate OpenType tables. */ - /* */ - /* <Description> */ - /* This section contains the declaration of functions to validate */ - /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ - /* */ - /*************************************************************************/ - - - /********************************************************************** - * - * @enum: - * FT_VALIDATE_OTXXX - * - * @description: - * A list of bit-field constants used with @FT_OpenType_Validate to - * indicate which OpenType tables should be validated. - * - * @values: - * FT_VALIDATE_BASE :: - * Validate BASE table. - * - * FT_VALIDATE_GDEF :: - * Validate GDEF table. - * - * FT_VALIDATE_GPOS :: - * Validate GPOS table. - * - * FT_VALIDATE_GSUB :: - * Validate GSUB table. - * - * FT_VALIDATE_JSTF :: - * Validate JSTF table. - * - * FT_VALIDATE_MATH :: - * Validate MATH table. - * - * FT_VALIDATE_OT :: - * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). - * - */ -#define FT_VALIDATE_BASE 0x0100 -#define FT_VALIDATE_GDEF 0x0200 -#define FT_VALIDATE_GPOS 0x0400 -#define FT_VALIDATE_GSUB 0x0800 -#define FT_VALIDATE_JSTF 0x1000 -#define FT_VALIDATE_MATH 0x2000 - -#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ - FT_VALIDATE_GDEF | \ - FT_VALIDATE_GPOS | \ - FT_VALIDATE_GSUB | \ - FT_VALIDATE_JSTF | \ - FT_VALIDATE_MATH - - /* */ - - /********************************************************************** - * - * @function: - * FT_OpenType_Validate - * - * @description: - * Validate various OpenType tables to assure that all offsets and - * indices are valid. The idea is that a higher-level library which - * actually does the text layout can access those tables without - * error checking (which can be quite time consuming). - * - * @input: - * face :: - * A handle to the input face. - * - * validation_flags :: - * A bit field which specifies the tables to be validated. See - * @FT_VALIDATE_OTXXX for possible values. - * - * @output: - * BASE_table :: - * A pointer to the BASE table. - * - * GDEF_table :: - * A pointer to the GDEF table. - * - * GPOS_table :: - * A pointer to the GPOS table. - * - * GSUB_table :: - * A pointer to the GSUB table. - * - * JSTF_table :: - * A pointer to the JSTF table. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with OpenType fonts, returning an error - * otherwise. - * - * After use, the application should deallocate the five tables with - * @FT_OpenType_Free. A NULL value indicates that the table either - * doesn't exist in the font, or the application hasn't asked for - * validation. - */ - 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 *JSTF_table ); - - /* */ - - /********************************************************************** - * - * @function: - * FT_OpenType_Free - * - * @description: - * Free the buffer allocated by OpenType validator. - * - * @input: - * face :: - * A handle to the input face. - * - * table :: - * The pointer to the buffer that is allocated by - * @FT_OpenType_Validate. - * - * @note: - * This function must be used to free the buffer allocated by - * @FT_OpenType_Validate only. - */ - FT_EXPORT( void ) - FT_OpenType_Free( FT_Face face, - FT_Bytes table ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTOTVAL_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftoutln.h b/drivers/freetype/freetype/include/freetype/ftoutln.h deleted file mode 100644 index fd69f28292..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftoutln.h +++ /dev/null @@ -1,560 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoutln.h */ -/* */ -/* Support for the FT_Outline type used to store glyph shapes of */ -/* most scalable font formats (specification). */ -/* */ -/* Copyright 1996-2003, 2005-2012 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 __FTOUTLN_H__ -#define __FTOUTLN_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* outline_processing */ - /* */ - /* <Title> */ - /* Outline Processing */ - /* */ - /* <Abstract> */ - /* Functions to create, transform, and render vectorial glyph images. */ - /* */ - /* <Description> */ - /* This section contains routines used to create and destroy scalable */ - /* glyph images known as `outlines'. These can also be measured, */ - /* transformed, and converted into bitmaps and pixmaps. */ - /* */ - /* <Order> */ - /* FT_Outline */ - /* FT_OUTLINE_FLAGS */ - /* FT_Outline_New */ - /* FT_Outline_Done */ - /* FT_Outline_Copy */ - /* FT_Outline_Translate */ - /* FT_Outline_Transform */ - /* FT_Outline_Embolden */ - /* FT_Outline_EmboldenXY */ - /* FT_Outline_Reverse */ - /* FT_Outline_Check */ - /* */ - /* FT_Outline_Get_CBox */ - /* FT_Outline_Get_BBox */ - /* */ - /* FT_Outline_Get_Bitmap */ - /* FT_Outline_Render */ - /* */ - /* FT_Outline_Decompose */ - /* FT_Outline_Funcs */ - /* FT_Outline_MoveTo_Func */ - /* FT_Outline_LineTo_Func */ - /* FT_Outline_ConicTo_Func */ - /* FT_Outline_CubicTo_Func */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Decompose */ - /* */ - /* <Description> */ - /* Walk over an outline's structure to decompose it into individual */ - /* segments and Bézier arcs. This function also emits `move to' */ - /* operations to indicate the start of new contours in the outline. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source target. */ - /* */ - /* func_interface :: A table of `emitters', i.e., function pointers */ - /* called during decomposition to indicate path */ - /* operations. */ - /* */ - /* <InOut> */ - /* user :: A typeless pointer which is passed to each */ - /* emitter during the decomposition. It can be */ - /* used to store the state during the */ - /* decomposition. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_Decompose( FT_Outline* outline, - const FT_Outline_Funcs* func_interface, - void* user ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_New */ - /* */ - /* <Description> */ - /* Create a new outline of a given size. */ - /* */ - /* <Input> */ - /* library :: A handle to the library object from where the */ - /* outline is allocated. Note however that the new */ - /* outline will *not* necessarily be *freed*, when */ - /* destroying the library, by @FT_Done_FreeType. */ - /* */ - /* numPoints :: The maximum number of points within the outline. */ - /* Must be smaller than or equal to 0xFFFF (65535). */ - /* */ - /* numContours :: The maximum number of contours within the outline. */ - /* This value must be in the range 0 to `numPoints'. */ - /* */ - /* <Output> */ - /* anoutline :: A handle to the new outline. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The reason why this function takes a `library' parameter is simply */ - /* to use the library's memory allocator. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_New( FT_Library library, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ); - - - FT_EXPORT( FT_Error ) - FT_Outline_New_Internal( FT_Memory memory, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Done */ - /* */ - /* <Description> */ - /* Destroy an outline created with @FT_Outline_New. */ - /* */ - /* <Input> */ - /* library :: A handle of the library object used to allocate the */ - /* outline. */ - /* */ - /* outline :: A pointer to the outline object to be discarded. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* If the outline's `owner' field is not set, only the outline */ - /* descriptor will be released. */ - /* */ - /* The reason why this function takes an `library' parameter is */ - /* simply to use ft_mem_free(). */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_Done( FT_Library library, - FT_Outline* outline ); - - - FT_EXPORT( FT_Error ) - FT_Outline_Done_Internal( FT_Memory memory, - FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Check */ - /* */ - /* <Description> */ - /* Check the contents of an outline descriptor. */ - /* */ - /* <Input> */ - /* outline :: A handle to a source outline. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_Check( FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Get_CBox */ - /* */ - /* <Description> */ - /* Return an outline's `control box'. The control box encloses all */ - /* the outline's points, including Bézier control points. Though it */ - /* coincides with the exact bounding box for most glyphs, it can be */ - /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bézier outside arcs). */ - /* */ - /* Computing the control box is very fast, while getting the bounding */ - /* box can take much more time as it needs to walk over all segments */ - /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* <Output> */ - /* acbox :: The outline's control box. */ - /* */ - /* <Note> */ - /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ - /* */ - FT_EXPORT( void ) - FT_Outline_Get_CBox( const FT_Outline* outline, - FT_BBox *acbox ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Translate */ - /* */ - /* <Description> */ - /* Apply a simple translation to the points of an outline. */ - /* */ - /* <InOut> */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* <Input> */ - /* xOffset :: The horizontal offset. */ - /* */ - /* yOffset :: The vertical offset. */ - /* */ - FT_EXPORT( void ) - FT_Outline_Translate( const FT_Outline* outline, - FT_Pos xOffset, - FT_Pos yOffset ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Copy */ - /* */ - /* <Description> */ - /* Copy an outline into another one. Both objects must have the */ - /* same sizes (number of points & number of contours) when this */ - /* function is called. */ - /* */ - /* <Input> */ - /* source :: A handle to the source outline. */ - /* */ - /* <Output> */ - /* target :: A handle to the target outline. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_Copy( const FT_Outline* source, - FT_Outline *target ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Transform */ - /* */ - /* <Description> */ - /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ - /* for applying rotations, slanting, flipping, etc. */ - /* */ - /* <InOut> */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* <Input> */ - /* matrix :: A pointer to the transformation matrix. */ - /* */ - /* <Note> */ - /* You can use @FT_Outline_Translate if you need to translate the */ - /* outline's points. */ - /* */ - FT_EXPORT( void ) - FT_Outline_Transform( const FT_Outline* outline, - const FT_Matrix* matrix ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Embolden */ - /* */ - /* <Description> */ - /* Embolden an outline. The new outline will be at most 4~times */ - /* `strength' pixels wider and higher. You may think of the left and */ - /* bottom borders as unchanged. */ - /* */ - /* Negative `strength' values to reduce the outline thickness are */ - /* possible also. */ - /* */ - /* <InOut> */ - /* outline :: A handle to the target outline. */ - /* */ - /* <Input> */ - /* strength :: How strong the glyph is emboldened. Expressed in */ - /* 26.6 pixel format. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The used algorithm to increase or decrease the thickness of the */ - /* glyph doesn't change the number of points; this means that certain */ - /* situations like acute angles or intersections are sometimes */ - /* handled incorrectly. */ - /* */ - /* If you need `better' metrics values you should call */ - /* @FT_Outline_Get_CBox or @FT_Outline_Get_BBox. */ - /* */ - /* Example call: */ - /* */ - /* { */ - /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ - /* if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE ) */ - /* FT_Outline_Embolden( &face->slot->outline, strength ); */ - /* } */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_Embolden( FT_Outline* outline, - FT_Pos strength ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_EmboldenXY */ - /* */ - /* <Description> */ - /* Embolden an outline. The new outline will be `xstrength' pixels */ - /* wider and `ystrength' pixels higher. Otherwise, it is similar to */ - /* @FT_Outline_Embolden, which uses the same strength in both */ - /* directions. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_EmboldenXY( FT_Outline* outline, - FT_Pos xstrength, - FT_Pos ystrength ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Reverse */ - /* */ - /* <Description> */ - /* Reverse the drawing direction of an outline. This is used to */ - /* ensure consistent fill conventions for mirrored glyphs. */ - /* */ - /* <InOut> */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* <Note> */ - /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ - /* the outline's `flags' field. */ - /* */ - /* It shouldn't be used by a normal client application, unless it */ - /* knows what it is doing. */ - /* */ - FT_EXPORT( void ) - FT_Outline_Reverse( FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Get_Bitmap */ - /* */ - /* <Description> */ - /* Render an outline within a bitmap. The outline's image is simply */ - /* OR-ed to the target bitmap. */ - /* */ - /* <Input> */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* <InOut> */ - /* abitmap :: A pointer to the target bitmap descriptor. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function does NOT CREATE the bitmap, it only renders an */ - /* outline image within the one you pass to it! Consequently, the */ - /* various fields in `abitmap' should be set accordingly. */ - /* */ - /* It will use the raster corresponding to the default glyph format. */ - /* */ - /* The value of the `num_grays' field in `abitmap' is ignored. If */ - /* you select the gray-level rasterizer, and you want less than 256 */ - /* gray levels, you have to use @FT_Outline_Render directly. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_Get_Bitmap( FT_Library library, - FT_Outline* outline, - const FT_Bitmap *abitmap ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Render */ - /* */ - /* <Description> */ - /* Render an outline within a bitmap using the current scan-convert. */ - /* This function uses an @FT_Raster_Params structure as an argument, */ - /* allowing advanced features like direct composition, translucency, */ - /* etc. */ - /* */ - /* <Input> */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* <InOut> */ - /* params :: A pointer to an @FT_Raster_Params structure used to */ - /* describe the rendering operation. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* You should know what you are doing and how @FT_Raster_Params works */ - /* to use this function. */ - /* */ - /* The field `params.source' will be set to `outline' before the scan */ - /* converter is called, which means that the value you give to it is */ - /* actually ignored. */ - /* */ - /* The gray-level rasterizer always uses 256 gray levels. If you */ - /* want less gray levels, you have to provide your own span callback. */ - /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ - /* @FT_Raster_Params structure for more details. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Outline_Render( FT_Library library, - FT_Outline* outline, - FT_Raster_Params* params ); - - - /************************************************************************** - * - * @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 - * be filled, and counter-clockwise ones must be unfilled. - * - * FT_ORIENTATION_POSTSCRIPT :: - * According to the PostScript specification, counter-clockwise contours - * must be filled, and clockwise ones must be unfilled. - * - * FT_ORIENTATION_FILL_RIGHT :: - * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to - * remember that in TrueType, everything that is to the right of - * the drawing direction of a contour must be filled. - * - * FT_ORIENTATION_FILL_LEFT :: - * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to - * remember that in PostScript, everything that is to the left of - * the drawing direction of a contour must be filled. - * - * FT_ORIENTATION_NONE :: - * The orientation cannot be determined. That is, different parts of - * the glyph have different orientation. - * - */ - typedef enum FT_Orientation_ - { - FT_ORIENTATION_TRUETYPE = 0, - FT_ORIENTATION_POSTSCRIPT = 1, - FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, - FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT, - FT_ORIENTATION_NONE - - } FT_Orientation; - - - /************************************************************************** - * - * @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 - * the direction of each global horizontal and/or vertical extrema - * within the outline. - * - * Note that this will return @FT_ORIENTATION_TRUETYPE for empty - * outlines. - * - * @input: - * outline :: - * A handle to the source outline. - * - * @return: - * The orientation. - * - */ - FT_EXPORT( FT_Orientation ) - FT_Outline_Get_Orientation( FT_Outline* outline ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTOUTLN_H__ */ - - -/* END */ - - -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ diff --git a/drivers/freetype/freetype/include/freetype/ftpfr.h b/drivers/freetype/freetype/include/freetype/ftpfr.h deleted file mode 100644 index 0b7b7d427c..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftpfr.h +++ /dev/null @@ -1,172 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpfr.h */ -/* */ -/* FreeType API for accessing PFR-specific data (specification only). */ -/* */ -/* Copyright 2002, 2003, 2004, 2006, 2008, 2009 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 __FTPFR_H__ -#define __FTPFR_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* pfr_fonts */ - /* */ - /* <Title> */ - /* PFR Fonts */ - /* */ - /* <Abstract> */ - /* PFR/TrueDoc specific API. */ - /* */ - /* <Description> */ - /* This section contains the declaration of PFR-specific functions. */ - /* */ - /*************************************************************************/ - - - /********************************************************************** - * - * @function: - * FT_Get_PFR_Metrics - * - * @description: - * Return the outline and metrics resolutions of a given PFR face. - * - * @input: - * face :: Handle to the input face. It can be a non-PFR face. - * - * @output: - * aoutline_resolution :: - * Outline resolution. This is equivalent to `face->units_per_EM' - * for non-PFR fonts. Optional (parameter can be NULL). - * - * ametrics_resolution :: - * Metrics resolution. This is equivalent to `outline_resolution' - * for non-PFR fonts. Optional (parameter can be NULL). - * - * ametrics_x_scale :: - * A 16.16 fixed-point number used to scale distance expressed - * in metrics units to device sub-pixels. This is equivalent to - * `face->size->x_scale', but for metrics only. Optional (parameter - * can be NULL). - * - * ametrics_y_scale :: - * Same as `ametrics_x_scale' but for the vertical direction. - * optional (parameter can be NULL). - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If the input face is not a PFR, this function will return an error. - * However, in all cases, it will return valid values. - */ - FT_EXPORT( FT_Error ) - FT_Get_PFR_Metrics( FT_Face face, - FT_UInt *aoutline_resolution, - FT_UInt *ametrics_resolution, - FT_Fixed *ametrics_x_scale, - FT_Fixed *ametrics_y_scale ); - - - /********************************************************************** - * - * @function: - * FT_Get_PFR_Kerning - * - * @description: - * Return the kerning pair corresponding to two glyphs in a PFR face. - * The distance is expressed in metrics units, unlike the result of - * @FT_Get_Kerning. - * - * @input: - * face :: A handle to the input face. - * - * left :: Index of the left glyph. - * - * right :: Index of the right glyph. - * - * @output: - * avector :: A kerning vector. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function always return distances in original PFR metrics - * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED - * mode, which always returns distances converted to outline units. - * - * You can use the value of the `x_scale' and `y_scale' parameters - * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. - */ - FT_EXPORT( FT_Error ) - FT_Get_PFR_Kerning( FT_Face face, - FT_UInt left, - FT_UInt right, - FT_Vector *avector ); - - - /********************************************************************** - * - * @function: - * FT_Get_PFR_Advance - * - * @description: - * Return a given glyph advance, expressed in original metrics units, - * from a PFR font. - * - * @input: - * face :: A handle to the input face. - * - * gindex :: The glyph index. - * - * @output: - * aadvance :: The glyph advance in metrics units. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics - * to convert the advance to device sub-pixels (i.e., 1/64th of pixels). - */ - FT_EXPORT( FT_Error ) - FT_Get_PFR_Advance( FT_Face face, - FT_UInt gindex, - FT_Pos *aadvance ); - - /* */ - - -FT_END_HEADER - -#endif /* __FTPFR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftrender.h b/drivers/freetype/freetype/include/freetype/ftrender.h deleted file mode 100644 index dd0229b815..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftrender.h +++ /dev/null @@ -1,238 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrender.h */ -/* */ -/* FreeType renderer modules public interface (specification). */ -/* */ -/* Copyright 1996-2001, 2005, 2006, 2010 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 __FTRENDER_H__ -#define __FTRENDER_H__ - - -#include <ft2build.h> -#include FT_MODULE_H -#include FT_GLYPH_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* module_management */ - /* */ - /*************************************************************************/ - - - /* create a new glyph object */ - typedef FT_Error - (*FT_Glyph_InitFunc)( FT_Glyph glyph, - FT_GlyphSlot slot ); - - /* destroys a given glyph object */ - typedef void - (*FT_Glyph_DoneFunc)( FT_Glyph glyph ); - - typedef void - (*FT_Glyph_TransformFunc)( FT_Glyph glyph, - const FT_Matrix* matrix, - const FT_Vector* delta ); - - typedef void - (*FT_Glyph_GetBBoxFunc)( FT_Glyph glyph, - FT_BBox* abbox ); - - typedef FT_Error - (*FT_Glyph_CopyFunc)( FT_Glyph source, - FT_Glyph target ); - - typedef FT_Error - (*FT_Glyph_PrepareFunc)( FT_Glyph glyph, - FT_GlyphSlot slot ); - -/* deprecated */ -#define FT_Glyph_Init_Func FT_Glyph_InitFunc -#define FT_Glyph_Done_Func FT_Glyph_DoneFunc -#define FT_Glyph_Transform_Func FT_Glyph_TransformFunc -#define FT_Glyph_BBox_Func FT_Glyph_GetBBoxFunc -#define FT_Glyph_Copy_Func FT_Glyph_CopyFunc -#define FT_Glyph_Prepare_Func FT_Glyph_PrepareFunc - - - struct FT_Glyph_Class_ - { - FT_Long glyph_size; - FT_Glyph_Format glyph_format; - FT_Glyph_InitFunc glyph_init; - FT_Glyph_DoneFunc glyph_done; - FT_Glyph_CopyFunc glyph_copy; - FT_Glyph_TransformFunc glyph_transform; - FT_Glyph_GetBBoxFunc glyph_bbox; - FT_Glyph_PrepareFunc glyph_prepare; - }; - - - typedef FT_Error - (*FT_Renderer_RenderFunc)( FT_Renderer renderer, - FT_GlyphSlot slot, - FT_UInt mode, - const FT_Vector* origin ); - - typedef FT_Error - (*FT_Renderer_TransformFunc)( FT_Renderer renderer, - FT_GlyphSlot slot, - const FT_Matrix* matrix, - const FT_Vector* delta ); - - - typedef void - (*FT_Renderer_GetCBoxFunc)( FT_Renderer renderer, - FT_GlyphSlot slot, - FT_BBox* cbox ); - - - typedef FT_Error - (*FT_Renderer_SetModeFunc)( FT_Renderer renderer, - FT_ULong mode_tag, - FT_Pointer mode_ptr ); - -/* deprecated identifiers */ -#define FTRenderer_render FT_Renderer_RenderFunc -#define FTRenderer_transform FT_Renderer_TransformFunc -#define FTRenderer_getCBox FT_Renderer_GetCBoxFunc -#define FTRenderer_setMode FT_Renderer_SetModeFunc - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Renderer_Class */ - /* */ - /* <Description> */ - /* The renderer module class descriptor. */ - /* */ - /* <Fields> */ - /* root :: The root @FT_Module_Class fields. */ - /* */ - /* glyph_format :: The glyph image format this renderer handles. */ - /* */ - /* render_glyph :: A method used to render the image that is in a */ - /* given glyph slot into a bitmap. */ - /* */ - /* transform_glyph :: A method used to transform the image that is in */ - /* a given glyph slot. */ - /* */ - /* get_glyph_cbox :: A method used to access the glyph's cbox. */ - /* */ - /* set_mode :: A method used to pass additional parameters. */ - /* */ - /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ - /* This is a pointer to its raster's class. */ - /* */ - typedef struct FT_Renderer_Class_ - { - FT_Module_Class root; - - FT_Glyph_Format glyph_format; - - FT_Renderer_RenderFunc render_glyph; - FT_Renderer_TransformFunc transform_glyph; - FT_Renderer_GetCBoxFunc get_glyph_cbox; - FT_Renderer_SetModeFunc set_mode; - - FT_Raster_Funcs* raster_class; - - } FT_Renderer_Class; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Renderer */ - /* */ - /* <Description> */ - /* Retrieve the current renderer for a given glyph format. */ - /* */ - /* <Input> */ - /* library :: A handle to the library object. */ - /* */ - /* format :: The glyph format. */ - /* */ - /* <Return> */ - /* A renderer handle. 0~if none found. */ - /* */ - /* <Note> */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - /* To add a new renderer, simply use @FT_Add_Module. To retrieve a */ - /* renderer by its name, use @FT_Get_Module. */ - /* */ - FT_EXPORT( FT_Renderer ) - FT_Get_Renderer( FT_Library library, - FT_Glyph_Format format ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Renderer */ - /* */ - /* <Description> */ - /* Set the current renderer to use, and set additional mode. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library object. */ - /* */ - /* <Input> */ - /* renderer :: A handle to the renderer object. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* parameters :: Additional parameters. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* In case of success, the renderer will be used to convert glyph */ - /* images in the renderer's known format into bitmaps. */ - /* */ - /* This doesn't change the current renderer for other formats. */ - /* */ - /* Currently, only the B/W renderer, if compiled with */ - /* FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels */ - /* anti-aliasing mode; this option must be set directly in */ - /* `ftraster.c' and is undefined by default) accepts a single tag */ - /* `pal5' to set its gray palette as a character string with */ - /* 5~elements. Consequently, the third and fourth argument are zero */ - /* normally. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Set_Renderer( FT_Library library, - FT_Renderer renderer, - FT_UInt num_params, - FT_Parameter* parameters ); - - - /* */ - - -FT_END_HEADER - -#endif /* __FTRENDER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftsizes.h b/drivers/freetype/freetype/include/freetype/ftsizes.h deleted file mode 100644 index 3e548cc39f..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftsizes.h +++ /dev/null @@ -1,159 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsizes.h */ -/* */ -/* FreeType size objects management (specification). */ -/* */ -/* Copyright 1996-2001, 2003, 2004, 2006, 2009 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Typical application would normally not need to use these functions. */ - /* However, they have been placed in a public API for the rare cases */ - /* where they are needed. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTSIZES_H__ -#define __FTSIZES_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* sizes_management */ - /* */ - /* <Title> */ - /* Size Management */ - /* */ - /* <Abstract> */ - /* Managing multiple sizes per face. */ - /* */ - /* <Description> */ - /* When creating a new face object (e.g., with @FT_New_Face), an */ - /* @FT_Size object is automatically created and used to store all */ - /* pixel-size dependent information, available in the `face->size' */ - /* field. */ - /* */ - /* It is however possible to create more sizes for a given face, */ - /* mostly in order to manage several character pixel sizes of the */ - /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ - /* */ - /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ - /* modify the contents of the current `active' size; you thus need */ - /* to use @FT_Activate_Size to change it. */ - /* */ - /* 99% of applications won't need the functions provided here, */ - /* especially if they use the caching sub-system, so be cautious */ - /* when using these. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Size */ - /* */ - /* <Description> */ - /* Create a new size object from a given face object. */ - /* */ - /* <Input> */ - /* face :: A handle to a parent face object. */ - /* */ - /* <Output> */ - /* asize :: A handle to a new size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* You need to call @FT_Activate_Size in order to select the new size */ - /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ - /* @FT_Load_Glyph, @FT_Load_Char, etc. */ - /* */ - FT_EXPORT( FT_Error ) - FT_New_Size( FT_Face face, - FT_Size* size ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Size */ - /* */ - /* <Description> */ - /* Discard a given size object. Note that @FT_Done_Face */ - /* automatically discards all size objects allocated with */ - /* @FT_New_Size. */ - /* */ - /* <Input> */ - /* size :: A handle to a target size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Done_Size( FT_Size size ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Activate_Size */ - /* */ - /* <Description> */ - /* Even though it is possible to create several size objects for a */ - /* given face (see @FT_New_Size for details), functions like */ - /* @FT_Load_Glyph or @FT_Load_Char only use the one which has been */ - /* activated last to determine the `current character pixel size'. */ - /* */ - /* This function can be used to `activate' a previously created size */ - /* object. */ - /* */ - /* <Input> */ - /* size :: A handle to a target size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* If `face' is the size's parent face object, this function changes */ - /* the value of `face->size' to the input size handle. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Activate_Size( FT_Size size ); - - /* */ - - -FT_END_HEADER - -#endif /* __FTSIZES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftsnames.h b/drivers/freetype/freetype/include/freetype/ftsnames.h deleted file mode 100644 index 485e4e162e..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftsnames.h +++ /dev/null @@ -1,200 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsnames.h */ -/* */ -/* Simple interface to access SFNT name tables (which are used */ -/* to hold font names, copyright info, notices, etc.) (specification). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 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_SFNT_NAMES_H__ -#define __FT_SFNT_NAMES_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* sfnt_names */ - /* */ - /* <Title> */ - /* SFNT Names */ - /* */ - /* <Abstract> */ - /* Access the names embedded in TrueType and OpenType files. */ - /* */ - /* <Description> */ - /* The TrueType and OpenType specifications allow the inclusion of */ - /* a special `names table' in font files. This table contains */ - /* textual (and internationalized) information regarding the font, */ - /* like family name, copyright, version, etc. */ - /* */ - /* The definitions below are used to access them if available. */ - /* */ - /* Note that this has nothing to do with glyph names! */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_SfntName */ - /* */ - /* <Description> */ - /* A structure used to model an SFNT `name' table entry. */ - /* */ - /* <Fields> */ - /* platform_id :: The platform ID for `string'. */ - /* */ - /* encoding_id :: The encoding ID for `string'. */ - /* */ - /* language_id :: The language ID for `string'. */ - /* */ - /* name_id :: An identifier for `string'. */ - /* */ - /* string :: The `name' string. Note that its format differs */ - /* depending on the (platform,encoding) pair. It can */ - /* be a Pascal String, a UTF-16 one, etc. */ - /* */ - /* Generally speaking, the string is not */ - /* zero-terminated. Please refer to the TrueType */ - /* specification for details. */ - /* */ - /* string_len :: The length of `string' in bytes. */ - /* */ - /* <Note> */ - /* Possible values for `platform_id', `encoding_id', `language_id', */ - /* and `name_id' are given in the file `ttnameid.h'. For details */ - /* please refer to the TrueType or OpenType specification. */ - /* */ - /* See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ - /* @TT_ISO_ID_XXX, and @TT_MS_ID_XXX. */ - /* */ - typedef struct FT_SfntName_ - { - FT_UShort platform_id; - FT_UShort encoding_id; - FT_UShort language_id; - FT_UShort name_id; - - FT_Byte* string; /* this string is *not* null-terminated! */ - FT_UInt string_len; /* in bytes */ - - } FT_SfntName; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Sfnt_Name_Count */ - /* */ - /* <Description> */ - /* Retrieve the number of name strings in the SFNT `name' table. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* <Return> */ - /* The number of strings in the `name' table. */ - /* */ - FT_EXPORT( FT_UInt ) - FT_Get_Sfnt_Name_Count( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Sfnt_Name */ - /* */ - /* <Description> */ - /* Retrieve a string of the SFNT `name' table for a given index. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* idx :: The index of the `name' string. */ - /* */ - /* <Output> */ - /* aname :: The indexed @FT_SfntName structure. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The `string' array returned in the `aname' structure is not */ - /* null-terminated. The application should deallocate it if it is no */ - /* longer in use. */ - /* */ - /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ - /* `name' table entries, then do a loop until you get the right */ - /* platform, encoding, and name ID. */ - /* */ - FT_EXPORT( FT_Error ) - FT_Get_Sfnt_Name( FT_Face face, - FT_UInt idx, - FT_SfntName *aname ); - - - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY - * - * @description: - * A constant used as the tag of @FT_Parameter structures to make - * FT_Open_Face() ignore preferred family subfamily names in `name' - * table since OpenType version 1.4. For backwards compatibility with - * legacy systems which has 4-face-per-family restriction. - * - */ -#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) - - - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY - * - * @description: - * A constant used as the tag of @FT_Parameter structures to make - * FT_Open_Face() ignore preferred subfamily names in `name' table since - * OpenType version 1.4. For backwards compatibility with legacy - * systems which has 4-face-per-family restriction. - * - */ -#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) - - /* */ - - -FT_END_HEADER - -#endif /* __FT_SFNT_NAMES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftstroke.h b/drivers/freetype/freetype/include/freetype/ftstroke.h deleted file mode 100644 index a498e4a883..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftstroke.h +++ /dev/null @@ -1,751 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstroke.h */ -/* */ -/* FreeType path stroker (specification). */ -/* */ -/* Copyright 2002-2006, 2008, 2009, 2011-2012 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_STROKE_H__ -#define __FT_STROKE_H__ - -#include <ft2build.h> -#include FT_OUTLINE_H -#include FT_GLYPH_H - - -FT_BEGIN_HEADER - - - /************************************************************************ - * - * @section: - * glyph_stroker - * - * @title: - * Glyph Stroker - * - * @abstract: - * Generating bordered and stroked glyphs. - * - * @description: - * This component generates stroked outlines of a given vectorial - * glyph. It also allows you to retrieve the `outside' and/or the - * `inside' borders of the stroke. - * - * This can be useful to generate `bordered' glyph, i.e., glyphs - * displayed with a coloured (and anti-aliased) border around their - * shape. - */ - - - /************************************************************** - * - * @type: - * FT_Stroker - * - * @description: - * Opaque handler to a path stroker object. - */ - typedef struct FT_StrokerRec_* FT_Stroker; - - - /************************************************************** - * - * @enum: - * FT_Stroker_LineJoin - * - * @description: - * These values determine how two joining lines are rendered - * in a stroker. - * - * @values: - * FT_STROKER_LINEJOIN_ROUND :: - * Used to render rounded line joins. Circular arcs are used - * to join two lines smoothly. - * - * FT_STROKER_LINEJOIN_BEVEL :: - * Used to render beveled line joins. The outer corner of - * the joined lines is filled by enclosing the triangular - * region of the corner with a straight line between the - * outer corners of each stroke. - * - * FT_STROKER_LINEJOIN_MITER_FIXED :: - * Used to render mitered line joins, with fixed bevels if the - * miter limit is exceeded. The outer edges of the strokes - * for the two segments are extended until they meet at an - * angle. If the segments meet at too sharp an angle (such - * that the miter would extend from the intersection of the - * segments a distance greater than the product of the miter - * limit value and the border radius), then a bevel join (see - * above) is used instead. This prevents long spikes being - * created. FT_STROKER_LINEJOIN_MITER_FIXED generates a miter - * line join as used in PostScript and PDF. - * - * FT_STROKER_LINEJOIN_MITER_VARIABLE :: - * FT_STROKER_LINEJOIN_MITER :: - * Used to render mitered line joins, with variable bevels if - * the miter limit is exceeded. The intersection of the - * strokes is clipped at a line perpendicular to the bisector - * of the angle between the strokes, at the distance from the - * intersection of the segments equal to the product of the - * miter limit value and the border radius. This prevents - * long spikes being created. - * FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line - * join as used in XPS. FT_STROKER_LINEJOIN_MITER is an alias - * for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for - * backwards compatibility. - */ - typedef enum FT_Stroker_LineJoin_ - { - FT_STROKER_LINEJOIN_ROUND = 0, - FT_STROKER_LINEJOIN_BEVEL = 1, - FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, - FT_STROKER_LINEJOIN_MITER = FT_STROKER_LINEJOIN_MITER_VARIABLE, - FT_STROKER_LINEJOIN_MITER_FIXED = 3 - - } FT_Stroker_LineJoin; - - - /************************************************************** - * - * @enum: - * FT_Stroker_LineCap - * - * @description: - * These values determine how the end of opened sub-paths are - * rendered in a stroke. - * - * @values: - * FT_STROKER_LINECAP_BUTT :: - * The end of lines is rendered as a full stop on the last - * point itself. - * - * FT_STROKER_LINECAP_ROUND :: - * The end of lines is rendered as a half-circle around the - * last point. - * - * FT_STROKER_LINECAP_SQUARE :: - * The end of lines is rendered as a square around the - * last point. - */ - typedef enum FT_Stroker_LineCap_ - { - FT_STROKER_LINECAP_BUTT = 0, - FT_STROKER_LINECAP_ROUND, - FT_STROKER_LINECAP_SQUARE - - } FT_Stroker_LineCap; - - - /************************************************************** - * - * @enum: - * FT_StrokerBorder - * - * @description: - * These values are used to select a given stroke border - * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. - * - * @values: - * FT_STROKER_BORDER_LEFT :: - * Select the left border, relative to the drawing direction. - * - * FT_STROKER_BORDER_RIGHT :: - * Select the right border, relative to the drawing direction. - * - * @note: - * Applications are generally interested in the `inside' and `outside' - * borders. However, there is no direct mapping between these and the - * `left' and `right' ones, since this really depends on the glyph's - * drawing orientation, which varies between font formats. - * - * You can however use @FT_Outline_GetInsideBorder and - * @FT_Outline_GetOutsideBorder to get these. - */ - typedef enum FT_StrokerBorder_ - { - FT_STROKER_BORDER_LEFT = 0, - FT_STROKER_BORDER_RIGHT - - } FT_StrokerBorder; - - - /************************************************************** - * - * @function: - * FT_Outline_GetInsideBorder - * - * @description: - * Retrieve the @FT_StrokerBorder value corresponding to the - * `inside' borders of a given outline. - * - * @input: - * outline :: - * The source outline handle. - * - * @return: - * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid - * outlines. - */ - FT_EXPORT( FT_StrokerBorder ) - FT_Outline_GetInsideBorder( FT_Outline* outline ); - - - /************************************************************** - * - * @function: - * FT_Outline_GetOutsideBorder - * - * @description: - * Retrieve the @FT_StrokerBorder value corresponding to the - * `outside' borders of a given outline. - * - * @input: - * outline :: - * The source outline handle. - * - * @return: - * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid - * outlines. - */ - FT_EXPORT( FT_StrokerBorder ) - FT_Outline_GetOutsideBorder( FT_Outline* outline ); - - - /************************************************************** - * - * @function: - * FT_Stroker_New - * - * @description: - * Create a new stroker object. - * - * @input: - * library :: - * FreeType library handle. - * - * @output: - * astroker :: - * A new stroker object handle. NULL in case of error. - * - * @return: - * FreeType error code. 0~means success. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_New( FT_Library library, - FT_Stroker *astroker ); - - - /************************************************************** - * - * @function: - * FT_Stroker_Set - * - * @description: - * Reset a stroker object's attributes. - * - * @input: - * stroker :: - * The target stroker handle. - * - * radius :: - * The border radius. - * - * line_cap :: - * The line cap style. - * - * line_join :: - * The line join style. - * - * miter_limit :: - * The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and - * FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles, - * expressed as 16.16 fixed-point value. - * - * @note: - * The radius is expressed in the same units as the outline - * coordinates. - */ - FT_EXPORT( void ) - FT_Stroker_Set( FT_Stroker stroker, - FT_Fixed radius, - FT_Stroker_LineCap line_cap, - FT_Stroker_LineJoin line_join, - FT_Fixed miter_limit ); - - - /************************************************************** - * - * @function: - * FT_Stroker_Rewind - * - * @description: - * Reset a stroker object without changing its attributes. - * You should call this function before beginning a new - * series of calls to @FT_Stroker_BeginSubPath or - * @FT_Stroker_EndSubPath. - * - * @input: - * stroker :: - * The target stroker handle. - */ - FT_EXPORT( void ) - FT_Stroker_Rewind( FT_Stroker stroker ); - - - /************************************************************** - * - * @function: - * FT_Stroker_ParseOutline - * - * @description: - * A convenience function used to parse a whole outline with - * the stroker. The resulting outline(s) can be retrieved - * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. - * - * @input: - * stroker :: - * The target stroker handle. - * - * outline :: - * The source outline. - * - * opened :: - * A boolean. If~1, the outline is treated as an open path instead - * of a closed one. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If `opened' is~0 (the default), the outline is treated as a closed - * path, and the stroker generates two distinct `border' outlines. - * - * If `opened' is~1, the outline is processed as an open path, and the - * stroker generates a single `stroke' outline. - * - * This function calls @FT_Stroker_Rewind automatically. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_ParseOutline( FT_Stroker stroker, - FT_Outline* outline, - FT_Bool opened ); - - - /************************************************************** - * - * @function: - * FT_Stroker_BeginSubPath - * - * @description: - * Start a new sub-path in the stroker. - * - * @input: - * stroker :: - * The target stroker handle. - * - * to :: - * A pointer to the start vector. - * - * open :: - * A boolean. If~1, the sub-path is treated as an open one. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function is useful when you need to stroke a path that is - * not stored as an @FT_Outline object. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_BeginSubPath( FT_Stroker stroker, - FT_Vector* to, - FT_Bool open ); - - - /************************************************************** - * - * @function: - * FT_Stroker_EndSubPath - * - * @description: - * Close the current sub-path in the stroker. - * - * @input: - * stroker :: - * The target stroker handle. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * You should call this function after @FT_Stroker_BeginSubPath. - * If the subpath was not `opened', this function `draws' a - * single line segment to the start position when needed. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_EndSubPath( FT_Stroker stroker ); - - - /************************************************************** - * - * @function: - * FT_Stroker_LineTo - * - * @description: - * `Draw' a single line segment in the stroker's current sub-path, - * from the last position. - * - * @input: - * stroker :: - * The target stroker handle. - * - * to :: - * A pointer to the destination point. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * You should call this function between @FT_Stroker_BeginSubPath and - * @FT_Stroker_EndSubPath. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_LineTo( FT_Stroker stroker, - FT_Vector* to ); - - - /************************************************************** - * - * @function: - * FT_Stroker_ConicTo - * - * @description: - * `Draw' a single quadratic Bézier in the stroker's current sub-path, - * from the last position. - * - * @input: - * stroker :: - * The target stroker handle. - * - * control :: - * A pointer to a Bézier control point. - * - * to :: - * A pointer to the destination point. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * You should call this function between @FT_Stroker_BeginSubPath and - * @FT_Stroker_EndSubPath. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_ConicTo( FT_Stroker stroker, - FT_Vector* control, - FT_Vector* to ); - - - /************************************************************** - * - * @function: - * FT_Stroker_CubicTo - * - * @description: - * `Draw' a single cubic Bézier in the stroker's current sub-path, - * from the last position. - * - * @input: - * stroker :: - * The target stroker handle. - * - * control1 :: - * A pointer to the first Bézier control point. - * - * control2 :: - * A pointer to second Bézier control point. - * - * to :: - * A pointer to the destination point. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * You should call this function between @FT_Stroker_BeginSubPath and - * @FT_Stroker_EndSubPath. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_CubicTo( FT_Stroker stroker, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ); - - - /************************************************************** - * - * @function: - * FT_Stroker_GetBorderCounts - * - * @description: - * Call this function once you have finished parsing your paths - * with the stroker. It returns the number of points and - * contours necessary to export one of the `border' or `stroke' - * outlines generated by the stroker. - * - * @input: - * stroker :: - * The target stroker handle. - * - * border :: - * The border index. - * - * @output: - * anum_points :: - * The number of points. - * - * anum_contours :: - * The number of contours. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * When an outline, or a sub-path, is `closed', the stroker generates - * two independent `border' outlines, named `left' and `right'. - * - * When the outline, or a sub-path, is `opened', the stroker merges - * the `border' outlines with caps. The `left' border receives all - * points, while the `right' border becomes empty. - * - * Use the function @FT_Stroker_GetCounts instead if you want to - * retrieve the counts associated to both borders. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_GetBorderCounts( FT_Stroker stroker, - FT_StrokerBorder border, - FT_UInt *anum_points, - FT_UInt *anum_contours ); - - - /************************************************************** - * - * @function: - * FT_Stroker_ExportBorder - * - * @description: - * Call this function after @FT_Stroker_GetBorderCounts to - * export the corresponding border to your own @FT_Outline - * structure. - * - * Note that this function appends the border points and - * contours to your outline, but does not try to resize its - * arrays. - * - * @input: - * stroker :: - * The target stroker handle. - * - * border :: - * The border index. - * - * outline :: - * The target outline handle. - * - * @note: - * Always call this function after @FT_Stroker_GetBorderCounts to - * get sure that there is enough room in your @FT_Outline object to - * receive all new data. - * - * When an outline, or a sub-path, is `closed', the stroker generates - * two independent `border' outlines, named `left' and `right' - * - * When the outline, or a sub-path, is `opened', the stroker merges - * the `border' outlines with caps. The `left' border receives all - * points, while the `right' border becomes empty. - * - * Use the function @FT_Stroker_Export instead if you want to - * retrieve all borders at once. - */ - FT_EXPORT( void ) - FT_Stroker_ExportBorder( FT_Stroker stroker, - FT_StrokerBorder border, - FT_Outline* outline ); - - - /************************************************************** - * - * @function: - * FT_Stroker_GetCounts - * - * @description: - * Call this function once you have finished parsing your paths - * with the stroker. It returns the number of points and - * contours necessary to export all points/borders from the stroked - * outline/path. - * - * @input: - * stroker :: - * The target stroker handle. - * - * @output: - * anum_points :: - * The number of points. - * - * anum_contours :: - * The number of contours. - * - * @return: - * FreeType error code. 0~means success. - */ - FT_EXPORT( FT_Error ) - FT_Stroker_GetCounts( FT_Stroker stroker, - FT_UInt *anum_points, - FT_UInt *anum_contours ); - - - /************************************************************** - * - * @function: - * FT_Stroker_Export - * - * @description: - * Call this function after @FT_Stroker_GetBorderCounts to - * export all borders to your own @FT_Outline structure. - * - * Note that this function appends the border points and - * contours to your outline, but does not try to resize its - * arrays. - * - * @input: - * stroker :: - * The target stroker handle. - * - * outline :: - * The target outline handle. - */ - FT_EXPORT( void ) - FT_Stroker_Export( FT_Stroker stroker, - FT_Outline* outline ); - - - /************************************************************** - * - * @function: - * FT_Stroker_Done - * - * @description: - * Destroy a stroker object. - * - * @input: - * stroker :: - * A stroker handle. Can be NULL. - */ - FT_EXPORT( void ) - FT_Stroker_Done( FT_Stroker stroker ); - - - /************************************************************** - * - * @function: - * FT_Glyph_Stroke - * - * @description: - * Stroke a given outline glyph object with a given stroker. - * - * @inout: - * pglyph :: - * Source glyph handle on input, new glyph handle on output. - * - * @input: - * stroker :: - * A stroker handle. - * - * destroy :: - * A Boolean. If~1, the source glyph object is destroyed - * on success. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The source glyph is untouched in case of error. - * - * Adding stroke may yield a significantly wider and taller glyph - * depending on how large of a radius was used to stroke the glyph. You - * may need to manually adjust horizontal and vertical advance amounts - * to account for this added size. - */ - FT_EXPORT( FT_Error ) - FT_Glyph_Stroke( FT_Glyph *pglyph, - FT_Stroker stroker, - FT_Bool destroy ); - - - /************************************************************** - * - * @function: - * FT_Glyph_StrokeBorder - * - * @description: - * Stroke a given outline glyph object with a given stroker, but - * only return either its inside or outside border. - * - * @inout: - * pglyph :: - * Source glyph handle on input, new glyph handle on output. - * - * @input: - * stroker :: - * A stroker handle. - * - * inside :: - * A Boolean. If~1, return the inside border, otherwise - * the outside border. - * - * destroy :: - * A Boolean. If~1, the source glyph object is destroyed - * on success. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The source glyph is untouched in case of error. - * - * Adding stroke may yield a significantly wider and taller glyph - * depending on how large of a radius was used to stroke the glyph. You - * may need to manually adjust horizontal and vertical advance amounts - * to account for this added size. - */ - FT_EXPORT( FT_Error ) - FT_Glyph_StrokeBorder( FT_Glyph *pglyph, - FT_Stroker stroker, - FT_Bool inside, - FT_Bool destroy ); - - /* */ - -FT_END_HEADER - -#endif /* __FT_STROKE_H__ */ - - -/* END */ - - -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ diff --git a/drivers/freetype/freetype/include/freetype/ftsynth.h b/drivers/freetype/freetype/include/freetype/ftsynth.h deleted file mode 100644 index 2074503cf6..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftsynth.h +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsynth.h */ -/* */ -/* FreeType synthesizing code for emboldening and slanting */ -/* (specification). */ -/* */ -/* Copyright 2000-2001, 2003, 2006, 2008, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********* *********/ - /********* WARNING, THIS IS ALPHA CODE! THIS API *********/ - /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ - /********* FREETYPE DEVELOPMENT TEAM *********/ - /********* *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* Main reason for not lifting the functions in this module to a */ - /* `standard' API is that the used parameters for emboldening and */ - /* slanting are not configurable. Consider the functions as a */ - /* code resource which should be copied into the application and */ - /* adapted to the particular needs. */ - - -#ifndef __FTSYNTH_H__ -#define __FTSYNTH_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ - /* taste). This function is actually a convenience function, providing */ - /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ - /* */ - /* For emboldened outlines the height, width, and advance metrics are */ - /* increased by the strength of the emboldening. You can also call */ - /* @FT_Outline_Get_CBox to get precise values. */ - FT_EXPORT( void ) - FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); - - /* Slant an outline glyph to the right by about 12 degrees. */ - FT_EXPORT( void ) - FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); - - /* */ - -FT_END_HEADER - -#endif /* __FTSYNTH_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftsystem.h b/drivers/freetype/freetype/include/freetype/ftsystem.h deleted file mode 100644 index e07460c55d..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftsystem.h +++ /dev/null @@ -1,347 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsystem.h */ -/* */ -/* FreeType low-level system interface definition (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2005, 2010 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 __FTSYSTEM_H__ -#define __FTSYSTEM_H__ - - -#include <ft2build.h> - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* system_interface */ - /* */ - /* <Title> */ - /* System Interface */ - /* */ - /* <Abstract> */ - /* How FreeType manages memory and i/o. */ - /* */ - /* <Description> */ - /* This section contains various definitions related to memory */ - /* management and i/o access. You need to understand this */ - /* information if you want to use a custom memory manager or you own */ - /* i/o streams. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* M E M O R Y M A N A G E M E N T */ - /* */ - /*************************************************************************/ - - - /************************************************************************* - * - * @type: - * FT_Memory - * - * @description: - * A handle to a given memory manager object, defined with an - * @FT_MemoryRec structure. - * - */ - typedef struct FT_MemoryRec_* FT_Memory; - - - /************************************************************************* - * - * @functype: - * FT_Alloc_Func - * - * @description: - * A function used to allocate `size' bytes from `memory'. - * - * @input: - * memory :: - * A handle to the source memory manager. - * - * size :: - * The size in bytes to allocate. - * - * @return: - * Address of new memory block. 0~in case of failure. - * - */ - typedef void* - (*FT_Alloc_Func)( FT_Memory memory, - long size ); - - - /************************************************************************* - * - * @functype: - * FT_Free_Func - * - * @description: - * A function used to release a given block of memory. - * - * @input: - * memory :: - * A handle to the source memory manager. - * - * block :: - * The address of the target memory block. - * - */ - typedef void - (*FT_Free_Func)( FT_Memory memory, - void* block ); - - - /************************************************************************* - * - * @functype: - * FT_Realloc_Func - * - * @description: - * A function used to re-allocate a given block of memory. - * - * @input: - * memory :: - * A handle to the source memory manager. - * - * cur_size :: - * The block's current size in bytes. - * - * new_size :: - * The block's requested new size. - * - * block :: - * The block's current address. - * - * @return: - * New block address. 0~in case of memory shortage. - * - * @note: - * In case of error, the old block must still be available. - * - */ - typedef void* - (*FT_Realloc_Func)( FT_Memory memory, - long cur_size, - long new_size, - void* block ); - - - /************************************************************************* - * - * @struct: - * FT_MemoryRec - * - * @description: - * A structure used to describe a given memory manager to FreeType~2. - * - * @fields: - * user :: - * A generic typeless pointer for user data. - * - * alloc :: - * A pointer type to an allocation function. - * - * free :: - * A pointer type to an memory freeing function. - * - * realloc :: - * A pointer type to a reallocation function. - * - */ - struct FT_MemoryRec_ - { - void* user; - FT_Alloc_Func alloc; - FT_Free_Func free; - FT_Realloc_Func realloc; - }; - - - /*************************************************************************/ - /* */ - /* I / O M A N A G E M E N T */ - /* */ - /*************************************************************************/ - - - /************************************************************************* - * - * @type: - * FT_Stream - * - * @description: - * A handle to an input stream. - * - */ - typedef struct FT_StreamRec_* FT_Stream; - - - /************************************************************************* - * - * @struct: - * FT_StreamDesc - * - * @description: - * A union type used to store either a long or a pointer. This is used - * to store a file descriptor or a `FILE*' in an input stream. - * - */ - typedef union FT_StreamDesc_ - { - long value; - void* pointer; - - } FT_StreamDesc; - - - /************************************************************************* - * - * @functype: - * FT_Stream_IoFunc - * - * @description: - * A function used to seek and read data from a given input stream. - * - * @input: - * stream :: - * A handle to the source stream. - * - * offset :: - * The offset of read in stream (always from start). - * - * buffer :: - * The address of the read buffer. - * - * count :: - * The number of bytes to read from the stream. - * - * @return: - * The number of bytes effectively read by the stream. - * - * @note: - * This function might be called to perform a seek or skip operation - * with a `count' of~0. A non-zero return value then indicates an - * error. - * - */ - typedef unsigned long - (*FT_Stream_IoFunc)( FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count ); - - - /************************************************************************* - * - * @functype: - * FT_Stream_CloseFunc - * - * @description: - * A function used to close a given input stream. - * - * @input: - * stream :: - * A handle to the target stream. - * - */ - typedef void - (*FT_Stream_CloseFunc)( FT_Stream stream ); - - - /************************************************************************* - * - * @struct: - * FT_StreamRec - * - * @description: - * A structure used to describe an input stream. - * - * @input: - * base :: - * For memory-based streams, this is the address of the first stream - * byte in memory. This field should always be set to NULL for - * disk-based streams. - * - * size :: - * The stream size in bytes. - * - * pos :: - * The current position within the stream. - * - * descriptor :: - * This field is a union that can hold an integer or a pointer. It is - * used by stream implementations to store file descriptors or `FILE*' - * pointers. - * - * pathname :: - * This field is completely ignored by FreeType. However, it is often - * useful during debugging to use it to store the stream's filename - * (where available). - * - * read :: - * The stream's input function. - * - * close :: - * The stream's close function. - * - * memory :: - * The memory manager to use to preload frames. This is set - * internally by FreeType and shouldn't be touched by stream - * implementations. - * - * cursor :: - * This field is set and used internally by FreeType when parsing - * frames. - * - * limit :: - * This field is set and used internally by FreeType when parsing - * frames. - * - */ - typedef struct FT_StreamRec_ - { - unsigned char* base; - unsigned long size; - unsigned long pos; - - FT_StreamDesc descriptor; - FT_StreamDesc pathname; - FT_Stream_IoFunc read; - FT_Stream_CloseFunc close; - - FT_Memory memory; - unsigned char* cursor; - unsigned char* limit; - - } FT_StreamRec; - - - /* */ - - -FT_END_HEADER - -#endif /* __FTSYSTEM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/fttrigon.h b/drivers/freetype/freetype/include/freetype/fttrigon.h deleted file mode 100644 index 65143cb8c8..0000000000 --- a/drivers/freetype/freetype/include/freetype/fttrigon.h +++ /dev/null @@ -1,350 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttrigon.h */ -/* */ -/* FreeType trigonometric functions (specification). */ -/* */ -/* Copyright 2001, 2003, 2005, 2007, 2013 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 __FTTRIGON_H__ -#define __FTTRIGON_H__ - -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* computations */ - /* */ - /*************************************************************************/ - - - /************************************************************************* - * - * @type: - * FT_Angle - * - * @description: - * This type is used to model angle values in FreeType. Note that the - * angle is a 16.16 fixed-point value expressed in degrees. - * - */ - typedef FT_Fixed FT_Angle; - - - /************************************************************************* - * - * @macro: - * FT_ANGLE_PI - * - * @description: - * The angle pi expressed in @FT_Angle units. - * - */ -#define FT_ANGLE_PI ( 180L << 16 ) - - - /************************************************************************* - * - * @macro: - * FT_ANGLE_2PI - * - * @description: - * The angle 2*pi expressed in @FT_Angle units. - * - */ -#define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) - - - /************************************************************************* - * - * @macro: - * FT_ANGLE_PI2 - * - * @description: - * The angle pi/2 expressed in @FT_Angle units. - * - */ -#define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) - - - /************************************************************************* - * - * @macro: - * FT_ANGLE_PI4 - * - * @description: - * The angle pi/4 expressed in @FT_Angle units. - * - */ -#define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) - - - /************************************************************************* - * - * @function: - * FT_Sin - * - * @description: - * Return the sinus of a given angle in fixed-point format. - * - * @input: - * angle :: - * The input angle. - * - * @return: - * The sinus value. - * - * @note: - * If you need both the sinus and cosinus for a given angle, use the - * function @FT_Vector_Unit. - * - */ - FT_EXPORT( FT_Fixed ) - FT_Sin( FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * FT_Cos - * - * @description: - * Return the cosinus of a given angle in fixed-point format. - * - * @input: - * angle :: - * The input angle. - * - * @return: - * The cosinus value. - * - * @note: - * If you need both the sinus and cosinus for a given angle, use the - * function @FT_Vector_Unit. - * - */ - FT_EXPORT( FT_Fixed ) - FT_Cos( FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * FT_Tan - * - * @description: - * Return the tangent of a given angle in fixed-point format. - * - * @input: - * angle :: - * The input angle. - * - * @return: - * The tangent value. - * - */ - FT_EXPORT( FT_Fixed ) - FT_Tan( FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * FT_Atan2 - * - * @description: - * Return the arc-tangent corresponding to a given vector (x,y) in - * the 2d plane. - * - * @input: - * x :: - * The horizontal vector coordinate. - * - * y :: - * The vertical vector coordinate. - * - * @return: - * The arc-tangent value (i.e. angle). - * - */ - FT_EXPORT( FT_Angle ) - FT_Atan2( FT_Fixed x, - FT_Fixed y ); - - - /************************************************************************* - * - * @function: - * FT_Angle_Diff - * - * @description: - * Return the difference between two angles. The result is always - * constrained to the ]-PI..PI] interval. - * - * @input: - * angle1 :: - * First angle. - * - * angle2 :: - * Second angle. - * - * @return: - * Constrained value of `value2-value1'. - * - */ - FT_EXPORT( FT_Angle ) - FT_Angle_Diff( FT_Angle angle1, - FT_Angle angle2 ); - - - /************************************************************************* - * - * @function: - * FT_Vector_Unit - * - * @description: - * Return the unit vector corresponding to a given angle. After the - * call, the value of `vec.x' will be `sin(angle)', and the value of - * `vec.y' will be `cos(angle)'. - * - * This function is useful to retrieve both the sinus and cosinus of a - * given angle quickly. - * - * @output: - * vec :: - * The address of target vector. - * - * @input: - * angle :: - * The address of angle. - * - */ - FT_EXPORT( void ) - FT_Vector_Unit( FT_Vector* vec, - FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * FT_Vector_Rotate - * - * @description: - * Rotate a vector by a given angle. - * - * @inout: - * vec :: - * The address of target vector. - * - * @input: - * angle :: - * The address of angle. - * - */ - FT_EXPORT( void ) - FT_Vector_Rotate( FT_Vector* vec, - FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * FT_Vector_Length - * - * @description: - * Return the length of a given vector. - * - * @input: - * vec :: - * The address of target vector. - * - * @return: - * The vector length, expressed in the same units that the original - * vector coordinates. - * - */ - FT_EXPORT( FT_Fixed ) - FT_Vector_Length( FT_Vector* vec ); - - - /************************************************************************* - * - * @function: - * FT_Vector_Polarize - * - * @description: - * Compute both the length and angle of a given vector. - * - * @input: - * vec :: - * The address of source vector. - * - * @output: - * length :: - * The vector length. - * - * angle :: - * The vector angle. - * - */ - FT_EXPORT( void ) - FT_Vector_Polarize( FT_Vector* vec, - FT_Fixed *length, - FT_Angle *angle ); - - - /************************************************************************* - * - * @function: - * FT_Vector_From_Polar - * - * @description: - * Compute vector coordinates from a length and angle. - * - * @output: - * vec :: - * The address of source vector. - * - * @input: - * length :: - * The vector length. - * - * angle :: - * The vector angle. - * - */ - FT_EXPORT( void ) - FT_Vector_From_Polar( FT_Vector* vec, - FT_Fixed length, - FT_Angle angle ); - - /* */ - - -FT_END_HEADER - -#endif /* __FTTRIGON_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftttdrv.h b/drivers/freetype/freetype/include/freetype/ftttdrv.h deleted file mode 100644 index d5d3f1ccc1..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftttdrv.h +++ /dev/null @@ -1,150 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftttdrv.h */ -/* */ -/* FreeType API for controlling the TrueType driver */ -/* (specification only). */ -/* */ -/* Copyright 2013 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 __FTTTDRV_H__ -#define __FTTTDRV_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /************************************************************************** - * - * @section: - * tt_driver - * - * @title: - * The TrueType driver - * - * @abstract: - * Controlling the TrueType driver module. - * - * @description: - * While FreeType's TrueType driver doesn't expose API functions by - * itself, it is possible to control its behaviour with @FT_Property_Set - * and @FT_Property_Get. The following lists the available properties - * together with the necessary macros and structures. - * - * The TrueType driver's module name is `truetype'. - * - */ - - - /************************************************************************** - * - * @property: - * interpreter-version - * - * @description: - * Currently, two versions are available which represent the bytecode - * interpreter with and without subpixel hinting support, - * respectively. The default is subpixel support if - * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel - * support otherwise (since it isn't available then). - * - * If subpixel hinting is on, many TrueType bytecode instructions - * behave differently compared to B/W or grayscale rendering. The - * main idea is to render at a much increased horizontal resolution, - * then sampling down the created output to subpixel precision. - * However, many older fonts are not suited to this and must be - * specially taken care of by applying (hardcoded) font-specific - * tweaks. - * - * Details on subpixel hinting and some of the necessary tweaks can be - * found in Greg Hitchcock's whitepaper at - * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. - * - * The following example code demonstrates how to activate subpixel - * hinting (omitting the error handling). - * - * { - * FT_Library library; - * FT_Face face; - * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_38; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "truetype", - * "interpreter-version", - * &interpreter_version ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - */ - - - /************************************************************************** - * - * @enum: - * TT_INTERPRETER_VERSION_XXX - * - * @description: - * A list of constants used for the @interpreter-version property to - * select the hinting engine for Truetype fonts. - * - * The numeric value in the constant names represents the version - * number as returned by the `GETINFO' bytecode instruction. - * - * @values: - * TT_INTERPRETER_VERSION_35 :: - * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in - * Windows~98; only grayscale and B/W rasterizing is supported. - * - * TT_INTERPRETER_VERSION_38 :: - * Version~38 corresponds to MS rasterizer v.1.9; it is roughly - * equivalent to the hinting provided by DirectWrite ClearType (as - * can be found, for example, in the Internet Explorer~9 running on - * Windows~7). - * - * @note: - * This property controls the behaviour of the bytecode interpreter - * and thus how outlines get hinted. It does *not* control how glyph - * get rasterized! In particular, it does not control subpixel color - * filtering. - * - * If FreeType has not been compiled with configuration option - * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an - * `FT_Err_Unimplemented_Feature' error. - * - */ -#define TT_INTERPRETER_VERSION_35 35 -#define TT_INTERPRETER_VERSION_38 38 - - - /* */ - -FT_END_HEADER - - -#endif /* __FTTTDRV_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/fttypes.h b/drivers/freetype/freetype/include/freetype/fttypes.h deleted file mode 100644 index 027e59ce11..0000000000 --- a/drivers/freetype/freetype/include/freetype/fttypes.h +++ /dev/null @@ -1,598 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttypes.h */ -/* */ -/* FreeType simple types definitions (specification only). */ -/* */ -/* Copyright 1996-2002, 2004, 2006-2009, 2012, 2013 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 __FTTYPES_H__ -#define __FTTYPES_H__ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_SYSTEM_H -#include FT_IMAGE_H - -#include <stddef.h> - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* basic_types */ - /* */ - /* <Title> */ - /* Basic Data Types */ - /* */ - /* <Abstract> */ - /* The basic data types defined by the library. */ - /* */ - /* <Description> */ - /* This section contains the basic data types defined by FreeType~2, */ - /* ranging from simple scalar types to bitmap descriptors. More */ - /* font-specific structures are defined in a different section. */ - /* */ - /* <Order> */ - /* FT_Byte */ - /* FT_Bytes */ - /* FT_Char */ - /* FT_Int */ - /* FT_UInt */ - /* FT_Int16 */ - /* FT_UInt16 */ - /* FT_Int32 */ - /* FT_UInt32 */ - /* FT_Short */ - /* FT_UShort */ - /* FT_Long */ - /* FT_ULong */ - /* FT_Bool */ - /* FT_Offset */ - /* FT_PtrDist */ - /* FT_String */ - /* FT_Tag */ - /* FT_Error */ - /* FT_Fixed */ - /* FT_Pointer */ - /* FT_Pos */ - /* FT_Vector */ - /* FT_BBox */ - /* FT_Matrix */ - /* FT_FWord */ - /* FT_UFWord */ - /* FT_F2Dot14 */ - /* FT_UnitVector */ - /* FT_F26Dot6 */ - /* */ - /* */ - /* FT_Generic */ - /* FT_Generic_Finalizer */ - /* */ - /* FT_Bitmap */ - /* FT_Pixel_Mode */ - /* FT_Palette_Mode */ - /* FT_Glyph_Format */ - /* FT_IMAGE_TAG */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Bool */ - /* */ - /* <Description> */ - /* A typedef of unsigned char, used for simple booleans. As usual, */ - /* values 1 and~0 represent true and false, respectively. */ - /* */ - typedef unsigned char FT_Bool; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_FWord */ - /* */ - /* <Description> */ - /* A signed 16-bit integer used to store a distance in original font */ - /* units. */ - /* */ - typedef signed short FT_FWord; /* distance in FUnits */ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_UFWord */ - /* */ - /* <Description> */ - /* An unsigned 16-bit integer used to store a distance in original */ - /* font units. */ - /* */ - typedef unsigned short FT_UFWord; /* unsigned distance */ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Char */ - /* */ - /* <Description> */ - /* A simple typedef for the _signed_ char type. */ - /* */ - typedef signed char FT_Char; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Byte */ - /* */ - /* <Description> */ - /* A simple typedef for the _unsigned_ char type. */ - /* */ - typedef unsigned char FT_Byte; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Bytes */ - /* */ - /* <Description> */ - /* A typedef for constant memory areas. */ - /* */ - typedef const FT_Byte* FT_Bytes; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Tag */ - /* */ - /* <Description> */ - /* A typedef for 32-bit tags (as used in the SFNT format). */ - /* */ - typedef FT_UInt32 FT_Tag; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_String */ - /* */ - /* <Description> */ - /* A simple typedef for the char type, usually used for strings. */ - /* */ - typedef char FT_String; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Short */ - /* */ - /* <Description> */ - /* A typedef for signed short. */ - /* */ - typedef signed short FT_Short; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_UShort */ - /* */ - /* <Description> */ - /* A typedef for unsigned short. */ - /* */ - typedef unsigned short FT_UShort; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Int */ - /* */ - /* <Description> */ - /* A typedef for the int type. */ - /* */ - typedef signed int FT_Int; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_UInt */ - /* */ - /* <Description> */ - /* A typedef for the unsigned int type. */ - /* */ - typedef unsigned int FT_UInt; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Long */ - /* */ - /* <Description> */ - /* A typedef for signed long. */ - /* */ - typedef signed long FT_Long; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_ULong */ - /* */ - /* <Description> */ - /* A typedef for unsigned long. */ - /* */ - typedef unsigned long FT_ULong; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_F2Dot14 */ - /* */ - /* <Description> */ - /* A signed 2.14 fixed-point type used for unit vectors. */ - /* */ - typedef signed short FT_F2Dot14; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_F26Dot6 */ - /* */ - /* <Description> */ - /* A signed 26.6 fixed-point type used for vectorial pixel */ - /* coordinates. */ - /* */ - typedef signed long FT_F26Dot6; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Fixed */ - /* */ - /* <Description> */ - /* This type is used to store 16.16 fixed-point values, like scaling */ - /* values or matrix coefficients. */ - /* */ - typedef signed long FT_Fixed; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Error */ - /* */ - /* <Description> */ - /* The FreeType error code type. A value of~0 is always interpreted */ - /* as a successful operation. */ - /* */ - typedef int FT_Error; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Pointer */ - /* */ - /* <Description> */ - /* A simple typedef for a typeless pointer. */ - /* */ - typedef void* FT_Pointer; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Offset */ - /* */ - /* <Description> */ - /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ - /* _unsigned_ integer type used to express a file size or position, */ - /* or a memory block size. */ - /* */ - typedef size_t FT_Offset; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_PtrDist */ - /* */ - /* <Description> */ - /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ - /* largest _signed_ integer type used to express the distance */ - /* between two pointers. */ - /* */ - typedef ft_ptrdiff_t FT_PtrDist; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_UnitVector */ - /* */ - /* <Description> */ - /* A simple structure used to store a 2D vector unit vector. Uses */ - /* FT_F2Dot14 types. */ - /* */ - /* <Fields> */ - /* x :: Horizontal coordinate. */ - /* */ - /* y :: Vertical coordinate. */ - /* */ - typedef struct FT_UnitVector_ - { - FT_F2Dot14 x; - FT_F2Dot14 y; - - } FT_UnitVector; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Matrix */ - /* */ - /* <Description> */ - /* A simple structure used to store a 2x2 matrix. Coefficients are */ - /* in 16.16 fixed-point format. The computation performed is: */ - /* */ - /* { */ - /* x' = x*xx + y*xy */ - /* y' = x*yx + y*yy */ - /* } */ - /* */ - /* <Fields> */ - /* xx :: Matrix coefficient. */ - /* */ - /* xy :: Matrix coefficient. */ - /* */ - /* yx :: Matrix coefficient. */ - /* */ - /* yy :: Matrix coefficient. */ - /* */ - typedef struct FT_Matrix_ - { - FT_Fixed xx, xy; - FT_Fixed yx, yy; - - } FT_Matrix; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Data */ - /* */ - /* <Description> */ - /* Read-only binary data represented as a pointer and a length. */ - /* */ - /* <Fields> */ - /* pointer :: The data. */ - /* */ - /* length :: The length of the data in bytes. */ - /* */ - typedef struct FT_Data_ - { - const FT_Byte* pointer; - FT_Int length; - - } FT_Data; - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Generic_Finalizer */ - /* */ - /* <Description> */ - /* Describe a function used to destroy the `client' data of any */ - /* FreeType object. See the description of the @FT_Generic type for */ - /* details of usage. */ - /* */ - /* <Input> */ - /* The address of the FreeType object which is under finalization. */ - /* Its client data is accessed through its `generic' field. */ - /* */ - typedef void (*FT_Generic_Finalizer)(void* object); - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Generic */ - /* */ - /* <Description> */ - /* Client applications often need to associate their own data to a */ - /* variety of FreeType core objects. For example, a text layout API */ - /* might want to associate a glyph cache to a given size object. */ - /* */ - /* Some FreeType object contains a `generic' field, of type */ - /* FT_Generic, which usage is left to client applications and font */ - /* servers. */ - /* */ - /* It can be used to store a pointer to client-specific data, as well */ - /* as the address of a `finalizer' function, which will be called by */ - /* FreeType when the object is destroyed (for example, the previous */ - /* client example would put the address of the glyph cache destructor */ - /* in the `finalizer' field). */ - /* */ - /* <Fields> */ - /* data :: A typeless pointer to any client-specified data. This */ - /* field is completely ignored by the FreeType library. */ - /* */ - /* finalizer :: A pointer to a `generic finalizer' function, which */ - /* will be called when the object is destroyed. If this */ - /* field is set to NULL, no code will be called. */ - /* */ - typedef struct FT_Generic_ - { - void* data; - FT_Generic_Finalizer finalizer; - - } FT_Generic; - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_MAKE_TAG */ - /* */ - /* <Description> */ - /* This macro converts four-letter tags which are used to label */ - /* TrueType tables into an unsigned long to be used within FreeType. */ - /* */ - /* <Note> */ - /* The produced values *must* be 32-bit integers. Don't redefine */ - /* this macro. */ - /* */ -#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ - (FT_Tag) \ - ( ( (FT_ULong)_x1 << 24 ) | \ - ( (FT_ULong)_x2 << 16 ) | \ - ( (FT_ULong)_x3 << 8 ) | \ - (FT_ULong)_x4 ) - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* L I S T M A N A G E M E N T */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* list_processing */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_ListNode */ - /* */ - /* <Description> */ - /* Many elements and objects in FreeType are listed through an */ - /* @FT_List record (see @FT_ListRec). As its name suggests, an */ - /* FT_ListNode is a handle to a single list element. */ - /* */ - typedef struct FT_ListNodeRec_* FT_ListNode; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_List */ - /* */ - /* <Description> */ - /* A handle to a list record (see @FT_ListRec). */ - /* */ - typedef struct FT_ListRec_* FT_List; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_ListNodeRec */ - /* */ - /* <Description> */ - /* A structure used to hold a single list element. */ - /* */ - /* <Fields> */ - /* prev :: The previous element in the list. NULL if first. */ - /* */ - /* next :: The next element in the list. NULL if last. */ - /* */ - /* data :: A typeless pointer to the listed object. */ - /* */ - typedef struct FT_ListNodeRec_ - { - FT_ListNode prev; - FT_ListNode next; - void* data; - - } FT_ListNodeRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_ListRec */ - /* */ - /* <Description> */ - /* A structure used to hold a simple doubly-linked list. These are */ - /* used in many parts of FreeType. */ - /* */ - /* <Fields> */ - /* head :: The head (first element) of doubly-linked list. */ - /* */ - /* tail :: The tail (last element) of doubly-linked list. */ - /* */ - typedef struct FT_ListRec_ - { - FT_ListNode head; - FT_ListNode tail; - - } FT_ListRec; - - - /* */ - -#define FT_IS_EMPTY( list ) ( (list).head == 0 ) -#define FT_BOOL( x ) ( (FT_Bool)( x ) ) - - /* concatenate C tokens */ -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) - - /* see `ftmoderr.h' for descriptions of the following macros */ - -#define FT_ERR( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) - -#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) -#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) - -#define FT_ERR_EQ( x, e ) \ - ( FT_ERROR_BASE( x ) == FT_ERROR_BASE( FT_ERR( e ) ) ) -#define FT_ERR_NEQ( x, e ) \ - ( FT_ERROR_BASE( x ) != FT_ERROR_BASE( FT_ERR( e ) ) ) - - -FT_END_HEADER - -#endif /* __FTTYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftwinfnt.h b/drivers/freetype/freetype/include/freetype/ftwinfnt.h deleted file mode 100644 index ea33353536..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftwinfnt.h +++ /dev/null @@ -1,274 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftwinfnt.h */ -/* */ -/* FreeType API for accessing Windows fnt-specific data. */ -/* */ -/* Copyright 2003, 2004, 2008 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 __FTWINFNT_H__ -#define __FTWINFNT_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* winfnt_fonts */ - /* */ - /* <Title> */ - /* Window FNT Files */ - /* */ - /* <Abstract> */ - /* Windows FNT specific API. */ - /* */ - /* <Description> */ - /* This section contains the declaration of Windows FNT specific */ - /* functions. */ - /* */ - /*************************************************************************/ - - - /************************************************************************* - * - * @enum: - * FT_WinFNT_ID_XXX - * - * @description: - * A list of valid values for the `charset' byte in - * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX - * encodings (except for cp1361) can be found at ftp://ftp.unicode.org - * in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory. cp1361 is - * roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. - * - * @values: - * FT_WinFNT_ID_DEFAULT :: - * 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 - * return value (of the related Windows API) simply denotes failure. - * - * FT_WinFNT_ID_SYMBOL :: - * There is no known mapping table available. - * - * FT_WinFNT_ID_MAC :: - * Mac Roman encoding. - * - * FT_WinFNT_ID_OEM :: - * From Michael Pöttgen <michael@poettgen.de>: - * - * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM - * is used for the charset of vector fonts, like `modern.fon', - * `roman.fon', and `script.fon' on Windows. - * - * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value - * specifies a character set that is operating-system dependent. - * - * The `IFIMETRICS' documentation from the `Windows Driver - * Development Kit' says: This font supports an OEM-specific - * character set. The OEM character set is system dependent. - * - * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the - * second default codepage that most international versions of - * 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. - * - * FT_WinFNT_ID_CP874 :: - * A superset of Thai TIS 620 and ISO 8859-11. - * - * FT_WinFNT_ID_CP932 :: - * A superset of Japanese Shift-JIS (with minor deviations). - * - * FT_WinFNT_ID_CP936 :: - * A superset of simplified Chinese GB 2312-1980 (with different - * ordering and minor deviations). - * - * FT_WinFNT_ID_CP949 :: - * A superset of Korean Hangul KS~C 5601-1987 (with different - * ordering and minor deviations). - * - * FT_WinFNT_ID_CP950 :: - * A superset of traditional Chinese Big~5 ETen (with different - * ordering and minor deviations). - * - * FT_WinFNT_ID_CP1250 :: - * A superset of East European ISO 8859-2 (with slightly different - * ordering). - * - * FT_WinFNT_ID_CP1251 :: - * A superset of Russian ISO 8859-5 (with different ordering). - * - * FT_WinFNT_ID_CP1252 :: - * ANSI encoding. A superset of ISO 8859-1. - * - * 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). - * - * FT_WinFNT_ID_CP1256 :: - * A superset of Arabic ISO 8859-6 (with different ordering). - * - * FT_WinFNT_ID_CP1257 :: - * A superset of Baltic ISO 8859-13 (with some deviations). - * - * FT_WinFNT_ID_CP1258 :: - * For Vietnamese. This encoding doesn't cover all necessary - * characters. - * - * FT_WinFNT_ID_CP1361 :: - * Korean (Johab). - */ - -#define FT_WinFNT_ID_CP1252 0 -#define FT_WinFNT_ID_DEFAULT 1 -#define FT_WinFNT_ID_SYMBOL 2 -#define FT_WinFNT_ID_MAC 77 -#define FT_WinFNT_ID_CP932 128 -#define FT_WinFNT_ID_CP949 129 -#define FT_WinFNT_ID_CP1361 130 -#define FT_WinFNT_ID_CP936 134 -#define FT_WinFNT_ID_CP950 136 -#define FT_WinFNT_ID_CP1253 161 -#define FT_WinFNT_ID_CP1254 162 -#define FT_WinFNT_ID_CP1258 163 -#define FT_WinFNT_ID_CP1255 177 -#define FT_WinFNT_ID_CP1256 178 -#define FT_WinFNT_ID_CP1257 186 -#define FT_WinFNT_ID_CP1251 204 -#define FT_WinFNT_ID_CP874 222 -#define FT_WinFNT_ID_CP1250 238 -#define FT_WinFNT_ID_OEM 255 - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_WinFNT_HeaderRec */ - /* */ - /* <Description> */ - /* Windows FNT Header info. */ - /* */ - typedef struct FT_WinFNT_HeaderRec_ - { - FT_UShort version; - FT_ULong file_size; - FT_Byte copyright[60]; - FT_UShort file_type; - FT_UShort nominal_point_size; - FT_UShort vertical_resolution; - FT_UShort horizontal_resolution; - FT_UShort ascent; - FT_UShort internal_leading; - FT_UShort external_leading; - FT_Byte italic; - FT_Byte underline; - FT_Byte strike_out; - FT_UShort weight; - FT_Byte charset; - FT_UShort pixel_width; - FT_UShort pixel_height; - FT_Byte pitch_and_family; - FT_UShort avg_width; - FT_UShort max_width; - FT_Byte first_char; - FT_Byte last_char; - FT_Byte default_char; - FT_Byte break_char; - FT_UShort bytes_per_row; - FT_ULong device_offset; - FT_ULong face_name_offset; - FT_ULong bits_pointer; - FT_ULong bits_offset; - FT_Byte reserved; - FT_ULong flags; - FT_UShort A_space; - FT_UShort B_space; - FT_UShort C_space; - FT_UShort color_table_offset; - FT_ULong reserved1[4]; - - } FT_WinFNT_HeaderRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_WinFNT_Header */ - /* */ - /* <Description> */ - /* A handle to an @FT_WinFNT_HeaderRec structure. */ - /* */ - typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; - - - /********************************************************************** - * - * @function: - * FT_Get_WinFNT_Header - * - * @description: - * Retrieve a Windows FNT font info header. - * - * @input: - * face :: A handle to the input face. - * - * @output: - * aheader :: The WinFNT header. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with Windows FNT faces, returning an error - * otherwise. - */ - FT_EXPORT( FT_Error ) - FT_Get_WinFNT_Header( FT_Face face, - FT_WinFNT_HeaderRec *aheader ); - - - /* */ - -FT_END_HEADER - -#endif /* __FTWINFNT_H__ */ - - -/* END */ - - -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ diff --git a/drivers/freetype/freetype/include/freetype/ftxf86.h b/drivers/freetype/freetype/include/freetype/ftxf86.h deleted file mode 100644 index 8c68afdcc5..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftxf86.h +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftxf86.h */ -/* */ -/* Support functions for X11. */ -/* */ -/* Copyright 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, */ -/* 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 __FTXF86_H__ -#define __FTXF86_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* font_formats */ - /* */ - /* <Title> */ - /* Font Formats */ - /* */ - /* <Abstract> */ - /* Getting the font format. */ - /* */ - /* <Description> */ - /* 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, in spite of FreeType's uniform API. */ - /* */ - /* This function is in the X11/xf86 namespace for historical reasons */ - /* and in no way depends on that windowing system. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <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. */ - /* */ - /* <Return> */ - /* Font format string. NULL in case of error. */ - /* */ - FT_EXPORT( const char* ) - FT_Get_X11_Font_Format( FT_Face face ); - - /* */ - -FT_END_HEADER - -#endif /* __FTXF86_H__ */ diff --git a/drivers/freetype/freetype/include/freetype/internal/autohint.h b/drivers/freetype/freetype/include/freetype/internal/autohint.h deleted file mode 100644 index 545de938c2..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/autohint.h +++ /dev/null @@ -1,244 +0,0 @@ -/***************************************************************************/ -/* */ -/* autohint.h */ -/* */ -/* High-level `autohint' module-specific interface (specification). */ -/* */ -/* Copyright 1996-2002, 2007, 2009, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The auto-hinter is used to load and automatically hint glyphs if a */ - /* format-specific hinter isn't available. */ - /* */ - /*************************************************************************/ - - -#ifndef __AUTOHINT_H__ -#define __AUTOHINT_H__ - - - /*************************************************************************/ - /* */ - /* A small technical note regarding automatic hinting in order to */ - /* clarify this module interface. */ - /* */ - /* An automatic hinter might compute two kinds of data for a given face: */ - /* */ - /* - global hints: Usually some metrics that describe global properties */ - /* of the face. It is computed by scanning more or less */ - /* aggressively the glyphs in the face, and thus can be */ - /* very slow to compute (even if the size of global */ - /* hints is really small). */ - /* */ - /* - glyph hints: These describe some important features of the glyph */ - /* outline, as well as how to align them. They are */ - /* generally much faster to compute than global hints. */ - /* */ - /* The current FreeType auto-hinter does a pretty good job while */ - /* performing fast computations for both global and glyph hints. */ - /* However, we might be interested in introducing more complex and */ - /* powerful algorithms in the future, like the one described in the John */ - /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ - /* */ - /* Because a sufficiently sophisticated font management system would */ - /* typically implement an LRU cache of opened face objects to reduce */ - /* memory usage, it is a good idea to be able to avoid recomputing */ - /* global hints every time the same face is re-opened. */ - /* */ - /* We thus provide the ability to cache global hints outside of the face */ - /* object, in order to speed up font re-opening time. Of course, this */ - /* feature is purely optional, so most client programs won't even notice */ - /* it. */ - /* */ - /* I initially thought that it would be a good idea to cache the glyph */ - /* hints too. However, my general idea now is that if you really need */ - /* to cache these too, you are simply in need of a new font format, */ - /* where all this information could be stored within the font file and */ - /* decoded on the fly. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H - - -FT_BEGIN_HEADER - - - typedef struct FT_AutoHinterRec_ *FT_AutoHinter; - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_AutoHinter_GlobalGetFunc */ - /* */ - /* <Description> */ - /* Retrieve the global hints computed for a given face object. The */ - /* resulting data is dissociated from the face and will survive a */ - /* call to FT_Done_Face(). It must be discarded through the API */ - /* FT_AutoHinter_GlobalDoneFunc(). */ - /* */ - /* <Input> */ - /* hinter :: A handle to the source auto-hinter. */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* <Output> */ - /* global_hints :: A typeless pointer to the global hints. */ - /* */ - /* global_len :: The size in bytes of the global hints. */ - /* */ - typedef void - (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter hinter, - FT_Face face, - void** global_hints, - long* global_len ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_AutoHinter_GlobalDoneFunc */ - /* */ - /* <Description> */ - /* Discard the global hints retrieved through */ - /* FT_AutoHinter_GlobalGetFunc(). This is the only way these hints */ - /* are freed from memory. */ - /* */ - /* <Input> */ - /* hinter :: A handle to the auto-hinter module. */ - /* */ - /* global :: A pointer to retrieved global hints to discard. */ - /* */ - typedef void - (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter hinter, - void* global ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_AutoHinter_GlobalResetFunc */ - /* */ - /* <Description> */ - /* This function is used to recompute the global metrics in a given */ - /* font. This is useful when global font data changes (e.g. Multiple */ - /* Masters fonts where blend coordinates change). */ - /* */ - /* <Input> */ - /* hinter :: A handle to the source auto-hinter. */ - /* */ - /* face :: A handle to the face. */ - /* */ - typedef void - (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter hinter, - FT_Face face ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_AutoHinter_GlyphLoadFunc */ - /* */ - /* <Description> */ - /* This function is used to load, scale, and automatically hint a */ - /* glyph from a given face. */ - /* */ - /* <Input> */ - /* face :: A handle to the face. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* load_flags :: The load flags. */ - /* */ - /* <Note> */ - /* This function is capable of loading composite glyphs by hinting */ - /* each sub-glyph independently (which improves quality). */ - /* */ - /* It will call the font driver with @FT_Load_Glyph, with */ - /* @FT_LOAD_NO_SCALE set. */ - /* */ - typedef FT_Error - (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter hinter, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ); - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_AutoHinter_InterfaceRec */ - /* */ - /* <Description> */ - /* The auto-hinter module's interface. */ - /* */ - typedef struct FT_AutoHinter_InterfaceRec_ - { - FT_AutoHinter_GlobalResetFunc reset_face; - FT_AutoHinter_GlobalGetFunc get_global_hints; - FT_AutoHinter_GlobalDoneFunc done_global_hints; - FT_AutoHinter_GlyphLoadFunc load_glyph; - - } FT_AutoHinter_InterfaceRec, *FT_AutoHinter_Interface; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_AUTOHINTER_INTERFACE( \ - class_, \ - reset_face_, \ - get_global_hints_, \ - done_global_hints_, \ - load_glyph_ ) \ - FT_CALLBACK_TABLE_DEF \ - const FT_AutoHinter_InterfaceRec class_ = \ - { \ - reset_face_, \ - get_global_hints_, \ - done_global_hints_, \ - load_glyph_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_AUTOHINTER_INTERFACE( \ - class_, \ - reset_face_, \ - get_global_hints_, \ - done_global_hints_, \ - load_glyph_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_AutoHinter_InterfaceRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->reset_face = reset_face_; \ - clazz->get_global_hints = get_global_hints_; \ - clazz->done_global_hints = done_global_hints_; \ - clazz->load_glyph = load_glyph_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - -FT_END_HEADER - -#endif /* __AUTOHINT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftcalc.h b/drivers/freetype/freetype/include/freetype/internal/ftcalc.h deleted file mode 100644 index faac3a3867..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftcalc.h +++ /dev/null @@ -1,167 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcalc.h */ -/* */ -/* Arithmetic computations (specification). */ -/* */ -/* Copyright 1996-2006, 2008, 2009, 2012-2013 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 __FTCALC_H__ -#define __FTCALC_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_FixedSqrt */ - /* */ - /* <Description> */ - /* Computes the square root of a 16.16 fixed-point value. */ - /* */ - /* <Input> */ - /* x :: The value to compute the root for. */ - /* */ - /* <Return> */ - /* The result of `sqrt(x)'. */ - /* */ - /* <Note> */ - /* This function is not very fast. */ - /* */ - FT_BASE( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ); - - - /*************************************************************************/ - /* */ - /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_MulDiv_No_Round */ - /* */ - /* <Description> */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* (without rounding) with maximum accuracy (it uses a 64-bit */ - /* intermediate integer whenever necessary). */ - /* */ - /* This function isn't necessarily as fast as some processor specific */ - /* operations, but is at least completely portable. */ - /* */ - /* <Input> */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. */ - /* c :: The divisor. */ - /* */ - /* <Return> */ - /* The result of `(a*b)/c'. This function never traps when trying to */ - /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ - /* on the signs of `a' and `b'. */ - /* */ - FT_BASE( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ); - - - /* - * A variant of FT_Matrix_Multiply which scales its result afterwards. - * The idea is that both `a' and `b' are scaled by factors of 10 so that - * the values are as precise as possible to get a correct result during - * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of - * `a' and `b', respectively, then the scaling factor of the result is - * `sa*sb'. - */ - FT_BASE( void ) - FT_Matrix_Multiply_Scaled( const FT_Matrix* a, - FT_Matrix *b, - FT_Long scaling ); - - - /* - * A variant of FT_Vector_Transform. See comments for - * FT_Matrix_Multiply_Scaled. - */ - FT_BASE( void ) - FT_Vector_Transform_Scaled( FT_Vector* vector, - const FT_Matrix* matrix, - FT_Long scaling ); - - - /* - * 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 ); - - - /* - * Return the most significant bit index. - */ - FT_BASE( FT_Int ) - FT_MSB( FT_UInt32 z ); - - - /* - * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses - * two fixed-point arguments instead. - */ - FT_BASE( FT_Fixed ) - FT_Hypot( FT_Fixed x, - FT_Fixed y ); - - -#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) -#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) -#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) -#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) -#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) -#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) - -#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ - : ( -( ( 32 - (x) ) & -64 ) ) ) - - -FT_END_HEADER - -#endif /* __FTCALC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftdebug.h b/drivers/freetype/freetype/include/freetype/internal/ftdebug.h deleted file mode 100644 index 58a3916d7e..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftdebug.h +++ /dev/null @@ -1,255 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdebug.h */ -/* */ -/* Debugging and logging component (specification). */ -/* */ -/* Copyright 1996-2002, 2004, 2006-2009, 2013 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. */ -/* */ -/* */ -/* IMPORTANT: A description of FreeType's debugging support can be */ -/* found in `docs/DEBUG.TXT'. Read it if you need to use or */ -/* understand this code. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTDEBUG_H__ -#define __FTDEBUG_H__ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_FREETYPE_H - - -FT_BEGIN_HEADER - - - /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ - /* is already defined; this simplifies the following #ifdefs */ - /* */ -#ifdef FT_DEBUG_LEVEL_TRACE -#undef FT_DEBUG_LEVEL_ERROR -#define FT_DEBUG_LEVEL_ERROR -#endif - - - /*************************************************************************/ - /* */ - /* Define the trace enums as well as the trace levels array when they */ - /* are needed. */ - /* */ - /*************************************************************************/ - -#ifdef FT_DEBUG_LEVEL_TRACE - -#define FT_TRACE_DEF( x ) trace_ ## x , - - /* defining the enumeration */ - typedef enum FT_Trace_ - { -#include FT_INTERNAL_TRACE_H - trace_count - - } FT_Trace; - - - /* defining the array of trace levels, provided by `src/base/ftdebug.c' */ - extern int ft_trace_levels[trace_count]; - -#undef FT_TRACE_DEF - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - - /*************************************************************************/ - /* */ - /* Define the FT_TRACE macro */ - /* */ - /* IMPORTANT! */ - /* */ - /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ - /* value before using any TRACE macro. */ - /* */ - /*************************************************************************/ - -#ifdef FT_DEBUG_LEVEL_TRACE - -#define FT_TRACE( level, varformat ) \ - do \ - { \ - if ( ft_trace_levels[FT_COMPONENT] >= level ) \ - FT_Message varformat; \ - } while ( 0 ) - -#else /* !FT_DEBUG_LEVEL_TRACE */ - -#define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */ - -#endif /* !FT_DEBUG_LEVEL_TRACE */ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Trace_Get_Count */ - /* */ - /* <Description> */ - /* Return the number of available trace components. */ - /* */ - /* <Return> */ - /* The number of trace components. 0 if FreeType 2 is not built with */ - /* FT_DEBUG_LEVEL_TRACE definition. */ - /* */ - /* <Note> */ - /* This function may be useful if you want to access elements of */ - /* the internal `ft_trace_levels' array by an index. */ - /* */ - FT_BASE( FT_Int ) - FT_Trace_Get_Count( void ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Trace_Get_Name */ - /* */ - /* <Description> */ - /* Return the name of a trace component. */ - /* */ - /* <Input> */ - /* The index of the trace component. */ - /* */ - /* <Return> */ - /* The name of the trace component. This is a statically allocated */ - /* C string, so do not free it after use. NULL if FreeType 2 is not */ - /* built with FT_DEBUG_LEVEL_TRACE definition. */ - /* */ - /* <Note> */ - /* Use @FT_Trace_Get_Count to get the number of available trace */ - /* components. */ - /* */ - /* This function may be useful if you want to control FreeType 2's */ - /* debug level in your application. */ - /* */ - FT_BASE( const char * ) - FT_Trace_Get_Name( FT_Int idx ); - - - /*************************************************************************/ - /* */ - /* You need two opening and closing parentheses! */ - /* */ - /* Example: FT_TRACE0(( "Value is %i", foo )) */ - /* */ - /* Output of the FT_TRACEX macros is sent to stderr. */ - /* */ - /*************************************************************************/ - -#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) -#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) -#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat ) -#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat ) -#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat ) -#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat ) -#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat ) -#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) - - - /*************************************************************************/ - /* */ - /* Define the FT_ERROR macro. */ - /* */ - /* Output of this macro is sent to stderr. */ - /* */ - /*************************************************************************/ - -#ifdef FT_DEBUG_LEVEL_ERROR - -#define FT_ERROR( varformat ) FT_Message varformat - -#else /* !FT_DEBUG_LEVEL_ERROR */ - -#define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */ - -#endif /* !FT_DEBUG_LEVEL_ERROR */ - - - /*************************************************************************/ - /* */ - /* Define the FT_ASSERT and FT_THROW macros. The call to `FT_Throw' */ - /* makes it possible to easily set a breakpoint at this function. */ - /* */ - /*************************************************************************/ - -#ifdef FT_DEBUG_LEVEL_ERROR - -#define FT_ASSERT( condition ) \ - do \ - { \ - if ( !( condition ) ) \ - FT_Panic( "assertion failed on line %d of file %s\n", \ - __LINE__, __FILE__ ); \ - } while ( 0 ) - -#define FT_THROW( e ) \ - ( FT_Throw( FT_ERR_CAT( FT_ERR_PREFIX, e ), \ - __LINE__, \ - __FILE__ ) | \ - FT_ERR_CAT( FT_ERR_PREFIX, e ) ) - -#else /* !FT_DEBUG_LEVEL_ERROR */ - -#define FT_ASSERT( condition ) do { } while ( 0 ) - -#define FT_THROW( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) - -#endif /* !FT_DEBUG_LEVEL_ERROR */ - - - /*************************************************************************/ - /* */ - /* Define `FT_Message' and `FT_Panic' when needed. */ - /* */ - /*************************************************************************/ - -#ifdef FT_DEBUG_LEVEL_ERROR - -#include "stdio.h" /* for vfprintf() */ - - /* print a message */ - FT_BASE( void ) - FT_Message( const char* fmt, - ... ); - - /* print a message and exit */ - FT_BASE( void ) - FT_Panic( const char* fmt, - ... ); - - /* report file name and line number of an error */ - FT_BASE( int ) - FT_Throw( FT_Error error, - int line, - const char* file ); - -#endif /* FT_DEBUG_LEVEL_ERROR */ - - - FT_BASE( void ) - ft_debug_init( void ); - -FT_END_HEADER - -#endif /* __FTDEBUG_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftdriver.h b/drivers/freetype/freetype/include/freetype/internal/ftdriver.h deleted file mode 100644 index 940218e62d..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftdriver.h +++ /dev/null @@ -1,409 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdriver.h */ -/* */ -/* FreeType font driver interface (specification). */ -/* */ -/* Copyright 1996-2003, 2006, 2008, 2011-2013 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 __FTDRIVER_H__ -#define __FTDRIVER_H__ - - -#include <ft2build.h> -#include FT_MODULE_H - - -FT_BEGIN_HEADER - - - typedef FT_Error - (*FT_Face_InitFunc)( FT_Stream stream, - FT_Face face, - FT_Int typeface_index, - FT_Int num_params, - FT_Parameter* parameters ); - - typedef void - (*FT_Face_DoneFunc)( FT_Face face ); - - - typedef FT_Error - (*FT_Size_InitFunc)( FT_Size size ); - - typedef void - (*FT_Size_DoneFunc)( FT_Size size ); - - - typedef FT_Error - (*FT_Slot_InitFunc)( FT_GlyphSlot slot ); - - typedef void - (*FT_Slot_DoneFunc)( FT_GlyphSlot slot ); - - - typedef FT_Error - (*FT_Size_RequestFunc)( FT_Size size, - FT_Size_Request req ); - - typedef FT_Error - (*FT_Size_SelectFunc)( FT_Size size, - FT_ULong size_index ); - - typedef FT_Error - (*FT_Slot_LoadFunc)( FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ); - - - typedef FT_UInt - (*FT_CharMap_CharIndexFunc)( FT_CharMap charmap, - FT_Long charcode ); - - typedef FT_Long - (*FT_CharMap_CharNextFunc)( FT_CharMap charmap, - FT_Long charcode ); - - - typedef FT_Error - (*FT_Face_GetKerningFunc)( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ); - - - typedef FT_Error - (*FT_Face_AttachFunc)( FT_Face face, - FT_Stream stream ); - - - typedef FT_Error - (*FT_Face_GetAdvancesFunc)( FT_Face face, - FT_UInt first, - FT_UInt count, - FT_Int32 flags, - FT_Fixed* advances ); - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Driver_ClassRec */ - /* */ - /* <Description> */ - /* The font driver class. This structure mostly contains pointers to */ - /* driver methods. */ - /* */ - /* <Fields> */ - /* root :: The parent module. */ - /* */ - /* face_object_size :: The size of a face object in bytes. */ - /* */ - /* size_object_size :: The size of a size object in bytes. */ - /* */ - /* slot_object_size :: The size of a glyph object in bytes. */ - /* */ - /* init_face :: The format-specific face constructor. */ - /* */ - /* done_face :: The format-specific face destructor. */ - /* */ - /* init_size :: The format-specific size constructor. */ - /* */ - /* done_size :: The format-specific size destructor. */ - /* */ - /* init_slot :: The format-specific slot constructor. */ - /* */ - /* done_slot :: The format-specific slot destructor. */ - /* */ - /* */ - /* load_glyph :: A function handle to load a glyph to a slot. */ - /* This field is mandatory! */ - /* */ - /* get_kerning :: A function handle to return the unscaled */ - /* kerning for a given pair of glyphs. Can be */ - /* set to 0 if the format doesn't support */ - /* kerning. */ - /* */ - /* attach_file :: This function handle is used to read */ - /* additional data for a face from another */ - /* file/stream. For example, this can be used to */ - /* add data from AFM or PFM files on a Type 1 */ - /* face, or a CIDMap on a CID-keyed face. */ - /* */ - /* get_advances :: A function handle used to return advance */ - /* widths of `count' glyphs (in font units), */ - /* starting at `first'. The `vertical' flag must */ - /* be set to get vertical advance heights. The */ - /* `advances' buffer is caller-allocated. */ - /* The idea of this function is to be able to */ - /* perform device-independent text layout without */ - /* loading a single glyph image. */ - /* */ - /* request_size :: A handle to a function used to request the new */ - /* character size. Can be set to 0 if the */ - /* scaling done in the base layer suffices. */ - /* */ - /* select_size :: A handle to a function used to select a new */ - /* fixed size. It is used only if */ - /* @FT_FACE_FLAG_FIXED_SIZES is set. Can be set */ - /* to 0 if the scaling done in the base layer */ - /* suffices. */ - /* <Note> */ - /* Most function pointers, with the exception of `load_glyph', can be */ - /* set to 0 to indicate a default behaviour. */ - /* */ - typedef struct FT_Driver_ClassRec_ - { - FT_Module_Class root; - - FT_Long face_object_size; - FT_Long size_object_size; - FT_Long slot_object_size; - - FT_Face_InitFunc init_face; - FT_Face_DoneFunc done_face; - - FT_Size_InitFunc init_size; - FT_Size_DoneFunc done_size; - - FT_Slot_InitFunc init_slot; - FT_Slot_DoneFunc done_slot; - - FT_Slot_LoadFunc load_glyph; - - FT_Face_GetKerningFunc get_kerning; - FT_Face_AttachFunc attach_file; - FT_Face_GetAdvancesFunc get_advances; - - /* since version 2.2 */ - FT_Size_RequestFunc request_size; - FT_Size_SelectFunc select_size; - - } FT_Driver_ClassRec, *FT_Driver_Class; - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DECLARE_DRIVER */ - /* */ - /* <Description> */ - /* Used to create a forward declaration of an FT_Driver_ClassRec */ - /* struct instance. */ - /* */ - /* <Macro> */ - /* FT_DEFINE_DRIVER */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Driver_ClassRec struct. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' function has to be */ - /* called with a pointer where the allocated structure is returned. */ - /* And when it is no longer needed a `destroy' function needs to be */ - /* called to release that allocation. */ - /* */ - /* `fcinit.c' (ft_create_default_module_classes) already contains a */ - /* mechanism to call these functions for the default modules */ - /* described in `ftmodule.h'. */ - /* */ - /* Notice that the created `create' and `destroy' functions call */ - /* `pic_init' and `pic_free' to allow you to manually allocate and */ - /* initialize any additional global data, like a module specific */ - /* interface, and put them in the global pic container defined in */ - /* `ftpic.h'. If you don't need them just implement the functions as */ - /* empty to resolve the link error. Also the `pic_init' and */ - /* `pic_free' functions should be declared in `pic.h', to be referred */ - /* by driver definition calling `FT_DEFINE_DRIVER' in following. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro is */ - /* used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DECLARE_DRIVER( class_ ) \ - FT_CALLBACK_TABLE \ - const FT_Driver_ClassRec class_; - -#define FT_DEFINE_DRIVER( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_, \ - face_object_size_, \ - size_object_size_, \ - slot_object_size_, \ - init_face_, \ - done_face_, \ - init_size_, \ - done_size_, \ - init_slot_, \ - done_slot_, \ - load_glyph_, \ - get_kerning_, \ - attach_file_, \ - get_advances_, \ - request_size_, \ - select_size_ ) \ - FT_CALLBACK_TABLE_DEF \ - const FT_Driver_ClassRec class_ = \ - { \ - FT_DEFINE_ROOT_MODULE( flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - \ - face_object_size_, \ - size_object_size_, \ - slot_object_size_, \ - \ - init_face_, \ - done_face_, \ - \ - init_size_, \ - done_size_, \ - \ - init_slot_, \ - done_slot_, \ - \ - load_glyph_, \ - \ - get_kerning_, \ - attach_file_, \ - get_advances_, \ - \ - request_size_, \ - select_size_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DECLARE_DRIVER( class_ ) FT_DECLARE_MODULE( class_ ) - -#define FT_DEFINE_DRIVER( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_, \ - face_object_size_, \ - size_object_size_, \ - slot_object_size_, \ - init_face_, \ - done_face_, \ - init_size_, \ - done_size_, \ - init_slot_, \ - done_slot_, \ - load_glyph_, \ - get_kerning_, \ - attach_file_, \ - get_advances_, \ - request_size_, \ - select_size_ ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_Module_Class* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \ - \ - \ - class_ ## _pic_free( library ); \ - if ( dclazz ) \ - FT_FREE( dclazz ); \ - } \ - \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_Module_Class** output_class ) \ - { \ - FT_Driver_Class clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ - return error; \ - \ - error = class_ ## _pic_init( library ); \ - if ( error ) \ - { \ - FT_FREE( clazz ); \ - return error; \ - } \ - \ - FT_DEFINE_ROOT_MODULE( flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - \ - clazz->face_object_size = face_object_size_; \ - clazz->size_object_size = size_object_size_; \ - clazz->slot_object_size = slot_object_size_; \ - \ - clazz->init_face = init_face_; \ - clazz->done_face = done_face_; \ - \ - clazz->init_size = init_size_; \ - clazz->done_size = done_size_; \ - \ - clazz->init_slot = init_slot_; \ - clazz->done_slot = done_slot_; \ - \ - clazz->load_glyph = load_glyph_; \ - \ - clazz->get_kerning = get_kerning_; \ - clazz->attach_file = attach_file_; \ - clazz->get_advances = get_advances_; \ - \ - clazz->request_size = request_size_; \ - clazz->select_size = select_size_; \ - \ - *output_class = (FT_Module_Class*)clazz; \ - \ - return FT_Err_Ok; \ - } - - -#endif /* FT_CONFIG_OPTION_PIC */ - -FT_END_HEADER - -#endif /* __FTDRIVER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftgloadr.h b/drivers/freetype/freetype/include/freetype/internal/ftgloadr.h deleted file mode 100644 index ce4dc6c9cc..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftgloadr.h +++ /dev/null @@ -1,168 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgloadr.h */ -/* */ -/* The FreeType glyph loader (specification). */ -/* */ -/* Copyright 2002, 2003, 2005, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTGLOADR_H__ -#define __FTGLOADR_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_GlyphLoader */ - /* */ - /* <Description> */ - /* The glyph loader is an internal object used to load several glyphs */ - /* together (for example, in the case of composites). */ - /* */ - /* <Note> */ - /* The glyph loader implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; - - -#if 0 /* moved to freetype.h in version 2.2 */ -#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 -#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 -#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 -#define FT_SUBGLYPH_FLAG_SCALE 8 -#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 -#define FT_SUBGLYPH_FLAG_2X2 0x80 -#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 -#endif - - - typedef struct FT_SubGlyphRec_ - { - FT_Int index; - FT_UShort flags; - FT_Int arg1; - FT_Int arg2; - FT_Matrix transform; - - } FT_SubGlyphRec; - - - typedef struct FT_GlyphLoadRec_ - { - 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 */ - - } FT_GlyphLoadRec, *FT_GlyphLoad; - - - typedef struct FT_GlyphLoaderRec_ - { - FT_Memory memory; - FT_UInt max_points; - FT_UInt max_contours; - FT_UInt max_subglyphs; - FT_Bool use_extra; - - FT_GlyphLoadRec base; - FT_GlyphLoadRec current; - - void* other; /* for possible future extension? */ - - } FT_GlyphLoaderRec; - - - /* create new empty glyph loader */ - FT_BASE( FT_Error ) - FT_GlyphLoader_New( FT_Memory memory, - FT_GlyphLoader *aloader ); - - /* add an extra points table to a glyph loader */ - FT_BASE( FT_Error ) - FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ); - - /* destroy a glyph loader */ - FT_BASE( void ) - FT_GlyphLoader_Done( FT_GlyphLoader loader ); - - /* reset a glyph loader (frees everything int it) */ - FT_BASE( void ) - FT_GlyphLoader_Reset( FT_GlyphLoader loader ); - - /* rewind a glyph loader */ - FT_BASE( void ) - FT_GlyphLoader_Rewind( FT_GlyphLoader loader ); - - /* check that there is enough space to add `n_points' and `n_contours' */ - /* to the glyph loader */ - FT_BASE( FT_Error ) - FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, - FT_UInt n_points, - FT_UInt n_contours ); - - -#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ - ( (_count) == 0 || ((_loader)->base.outline.n_points + \ - (_loader)->current.outline.n_points + \ - (unsigned long)(_count)) <= (_loader)->max_points ) - -#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ - ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ - (_loader)->current.outline.n_contours + \ - (unsigned long)(_count)) <= (_loader)->max_contours ) - -#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ - ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ - FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ - ? 0 \ - : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) ) - - - /* check that there is enough space to add `n_subs' sub-glyphs to */ - /* a glyph loader */ - FT_BASE( FT_Error ) - FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, - FT_UInt n_subs ); - - /* prepare a glyph loader, i.e. empty the current glyph */ - FT_BASE( void ) - FT_GlyphLoader_Prepare( FT_GlyphLoader loader ); - - /* add the current glyph to the base glyph */ - FT_BASE( void ) - FT_GlyphLoader_Add( FT_GlyphLoader loader ); - - /* copy points from one glyph loader to another */ - FT_BASE( FT_Error ) - FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, - FT_GlyphLoader source ); - - /* */ - - -FT_END_HEADER - -#endif /* __FTGLOADR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftmemory.h b/drivers/freetype/freetype/include/freetype/internal/ftmemory.h deleted file mode 100644 index 3d51aeec69..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftmemory.h +++ /dev/null @@ -1,378 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmemory.h */ -/* */ -/* The FreeType memory management macros (specification). */ -/* */ -/* Copyright 1996-2002, 2004-2007, 2010, 2013 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 __FTMEMORY_H__ -#define __FTMEMORY_H__ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_TYPES_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_SET_ERROR */ - /* */ - /* <Description> */ - /* This macro is used to set an implicit `error' variable to a given */ - /* expression's value (usually a function call), and convert it to a */ - /* boolean which is set whenever the value is != 0. */ - /* */ -#undef FT_SET_ERROR -#define FT_SET_ERROR( expression ) \ - ( ( error = (expression) ) != 0 ) - - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M E M O R Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* - * C++ refuses to handle statements like p = (void*)anything, with `p' a - * typed pointer. Since we don't have a `typeof' operator in standard - * C++, we have to use a template to emulate it. - */ - -#ifdef __cplusplus - - extern "C++" - template <typename T> inline T* - cplusplus_typeof( T*, - void *v ) - { - return static_cast <T*> ( v ); - } - -#define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) ) - -#else - -#define FT_ASSIGNP( p, val ) (p) = (val) - -#endif - - - -#ifdef FT_DEBUG_MEMORY - - FT_BASE( const char* ) _ft_debug_file; - FT_BASE( long ) _ft_debug_lineno; - -#define FT_DEBUG_INNER( exp ) ( _ft_debug_file = __FILE__, \ - _ft_debug_lineno = __LINE__, \ - (exp) ) - -#define FT_ASSIGNP_INNER( p, exp ) ( _ft_debug_file = __FILE__, \ - _ft_debug_lineno = __LINE__, \ - FT_ASSIGNP( p, exp ) ) - -#else /* !FT_DEBUG_MEMORY */ - -#define FT_DEBUG_INNER( exp ) (exp) -#define FT_ASSIGNP_INNER( p, exp ) FT_ASSIGNP( p, exp ) - -#endif /* !FT_DEBUG_MEMORY */ - - - /* - * The allocation functions return a pointer, and the error code - * is written to through the `p_error' parameter. See below for - * for documentation. - */ - - FT_BASE( FT_Pointer ) - ft_mem_alloc( FT_Memory memory, - FT_Long size, - FT_Error *p_error ); - - FT_BASE( FT_Pointer ) - ft_mem_qalloc( FT_Memory memory, - FT_Long size, - FT_Error *p_error ); - - FT_BASE( FT_Pointer ) - ft_mem_realloc( FT_Memory memory, - FT_Long item_size, - FT_Long cur_count, - FT_Long new_count, - void* block, - FT_Error *p_error ); - - FT_BASE( FT_Pointer ) - ft_mem_qrealloc( FT_Memory memory, - FT_Long item_size, - FT_Long cur_count, - FT_Long new_count, - void* block, - FT_Error *p_error ); - - FT_BASE( void ) - ft_mem_free( FT_Memory memory, - const void* P ); - - -#define FT_MEM_ALLOC( ptr, size ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, \ - (FT_Long)(size), \ - &error ) ) - -#define FT_MEM_FREE( ptr ) \ - FT_BEGIN_STMNT \ - ft_mem_free( memory, (ptr) ); \ - (ptr) = NULL; \ - FT_END_STMNT - -#define FT_MEM_NEW( ptr ) \ - FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) ) - -#define FT_MEM_REALLOC( ptr, cursz, newsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ - 1, \ - (FT_Long)(cursz), \ - (FT_Long)(newsz), \ - (ptr), \ - &error ) ) - -#define FT_MEM_QALLOC( ptr, size ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, \ - (FT_Long)(size), \ - &error ) ) - -#define FT_MEM_QNEW( ptr ) \ - FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) ) - -#define FT_MEM_QREALLOC( ptr, cursz, newsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ - 1, \ - (FT_Long)(cursz), \ - (FT_Long)(newsz), \ - (ptr), \ - &error ) ) - -#define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ - (FT_Long)(item_size), \ - 0, \ - (FT_Long)(count), \ - NULL, \ - &error ) ) - -#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ - (FT_Long)(itmsz), \ - (FT_Long)(oldcnt), \ - (FT_Long)(newcnt), \ - (ptr), \ - &error ) ) - -#define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ - (FT_Long)(item_size), \ - 0, \ - (FT_Long)(count), \ - NULL, \ - &error ) ) - -#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ - (FT_Long)(itmsz), \ - (FT_Long)(oldcnt), \ - (FT_Long)(newcnt), \ - (ptr), \ - &error ) ) - - -#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) - - -#define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) - -#define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) - -#define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) - - -#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) - -#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) - - -#define FT_ARRAY_ZERO( dest, count ) \ - FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) ) - -#define FT_ARRAY_COPY( dest, source, count ) \ - FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) ) - -#define FT_ARRAY_MOVE( dest, source, count ) \ - FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) ) - - - /* - * Return the maximum number of addressable elements in an array. - * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid - * any problems. - */ -#define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) ) - -#define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) ) - - - /*************************************************************************/ - /* */ - /* The following functions macros expect that their pointer argument is */ - /* _typed_ in order to automatically compute array element sizes. */ - /* */ - -#define FT_MEM_NEW_ARRAY( ptr, count ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ - sizeof ( *(ptr) ), \ - 0, \ - (FT_Long)(count), \ - NULL, \ - &error ) ) - -#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ - sizeof ( *(ptr) ), \ - (FT_Long)(cursz), \ - (FT_Long)(newsz), \ - (ptr), \ - &error ) ) - -#define FT_MEM_QNEW_ARRAY( ptr, count ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ - sizeof ( *(ptr) ), \ - 0, \ - (FT_Long)(count), \ - NULL, \ - &error ) ) - -#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ - sizeof ( *(ptr) ), \ - (FT_Long)(cursz), \ - (FT_Long)(newsz), \ - (ptr), \ - &error ) ) - -#define FT_ALLOC( ptr, size ) \ - FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) ) - -#define FT_REALLOC( ptr, cursz, newsz ) \ - FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) ) - -#define FT_ALLOC_MULT( ptr, count, item_size ) \ - FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) ) - -#define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ - FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt, \ - newcnt, itmsz ) ) - -#define FT_QALLOC( ptr, size ) \ - FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) ) - -#define FT_QREALLOC( ptr, cursz, newsz ) \ - FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) ) - -#define FT_QALLOC_MULT( ptr, count, item_size ) \ - FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) ) - -#define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ - FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt, \ - newcnt, itmsz ) ) - -#define FT_FREE( ptr ) FT_MEM_FREE( ptr ) - -#define FT_NEW( ptr ) FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) ) - -#define FT_NEW_ARRAY( ptr, count ) \ - FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) - -#define FT_RENEW_ARRAY( ptr, curcnt, newcnt ) \ - FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) - -#define FT_QNEW( ptr ) \ - FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) - -#define FT_QNEW_ARRAY( ptr, count ) \ - FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) - -#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ - FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) - - - FT_BASE( FT_Pointer ) - ft_mem_strdup( FT_Memory memory, - const char* str, - FT_Error *p_error ); - - FT_BASE( FT_Pointer ) - ft_mem_dup( FT_Memory memory, - const void* address, - FT_ULong size, - FT_Error *p_error ); - - -#define FT_MEM_STRDUP( dst, str ) \ - (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) - -#define FT_STRDUP( dst, str ) \ - FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) - -#define FT_MEM_DUP( dst, address, size ) \ - (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) - -#define FT_DUP( dst, address, size ) \ - FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) - - - /* Return >= 1 if a truncation occurs. */ - /* Return 0 if the source string fits the buffer. */ - /* This is *not* the same as strlcpy(). */ - FT_BASE( FT_Int ) - ft_mem_strcpyn( char* dst, - const char* src, - FT_ULong size ); - -#define FT_STRCPYN( dst, src, size ) \ - ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) ) - - /* */ - - -FT_END_HEADER - -#endif /* __FTMEMORY_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftobjs.h b/drivers/freetype/freetype/include/freetype/internal/ftobjs.h deleted file mode 100644 index 701c850eb7..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftobjs.h +++ /dev/null @@ -1,1569 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftobjs.h */ -/* */ -/* The FreeType private base classes (specification). */ -/* */ -/* Copyright 1996-2006, 2008, 2010, 2012-2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file contains the definition of all internal FreeType classes. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTOBJS_H__ -#define __FTOBJS_H__ - -#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 -#include FT_INTERNAL_AUTOHINT_H -#include FT_INTERNAL_SERVICE_H -#include FT_INTERNAL_PIC_H - -#ifdef FT_CONFIG_OPTION_INCREMENTAL -#include FT_INCREMENTAL_H -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* Some generic definitions. */ - /* */ -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL (void*)0 -#endif - - - /*************************************************************************/ - /* */ - /* The min and max functions missing in C. As usual, be careful not to */ - /* write things like FT_MIN( a++, b++ ) to avoid side effects. */ - /* */ -#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) -#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) - -#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) - - -#define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) ) -#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) -#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) - -#define FT_PIX_FLOOR( x ) ( (x) & ~63 ) -#define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) -#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) - - - /* - * Return the highest power of 2 that is <= value; this correspond to - * the highest bit in a given 32-bit value. - */ - FT_BASE( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ); - - - /* - * character classification functions -- since these are used to parse - * font files, we must not use those in <ctypes.h> which are - * locale-dependent - */ -#define ft_isdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U ) - -#define ft_isxdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U || \ - ( (unsigned)(x) - 'a' ) < 6U || \ - ( (unsigned)(x) - 'A' ) < 6U ) - - /* the next two macros assume ASCII representation */ -#define ft_isupper( x ) ( ( (unsigned)(x) - 'A' ) < 26U ) -#define ft_islower( x ) ( ( (unsigned)(x) - 'a' ) < 26U ) - -#define ft_isalpha( x ) ( ft_isupper( x ) || ft_islower( x ) ) -#define ft_isalnum( x ) ( ft_isdigit( x ) || ft_isalpha( x ) ) - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C H A R M A P S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* handle to internal charmap object */ - typedef struct FT_CMapRec_* FT_CMap; - - /* handle to charmap class structure */ - typedef const struct FT_CMap_ClassRec_* FT_CMap_Class; - - /* internal charmap object structure */ - typedef struct FT_CMapRec_ - { - FT_CharMapRec charmap; - FT_CMap_Class clazz; - - } FT_CMapRec; - - /* typecase any pointer to a charmap handle */ -#define FT_CMAP( x ) ((FT_CMap)( x )) - - /* obvious macros */ -#define FT_CMAP_PLATFORM_ID( x ) FT_CMAP( x )->charmap.platform_id -#define FT_CMAP_ENCODING_ID( x ) FT_CMAP( x )->charmap.encoding_id -#define FT_CMAP_ENCODING( x ) FT_CMAP( x )->charmap.encoding -#define FT_CMAP_FACE( x ) FT_CMAP( x )->charmap.face - - - /* class method definitions */ - typedef FT_Error - (*FT_CMap_InitFunc)( FT_CMap cmap, - FT_Pointer init_data ); - - typedef void - (*FT_CMap_DoneFunc)( FT_CMap cmap ); - - typedef FT_UInt - (*FT_CMap_CharIndexFunc)( FT_CMap cmap, - FT_UInt32 char_code ); - - typedef FT_UInt - (*FT_CMap_CharNextFunc)( FT_CMap cmap, - FT_UInt32 *achar_code ); - - typedef FT_UInt - (*FT_CMap_CharVarIndexFunc)( FT_CMap cmap, - FT_CMap unicode_cmap, - FT_UInt32 char_code, - FT_UInt32 variant_selector ); - - typedef FT_Bool - (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap, - FT_UInt32 char_code, - FT_UInt32 variant_selector ); - - typedef FT_UInt32 * - (*FT_CMap_VariantListFunc)( FT_CMap cmap, - FT_Memory mem ); - - typedef FT_UInt32 * - (*FT_CMap_CharVariantListFunc)( FT_CMap cmap, - FT_Memory mem, - FT_UInt32 char_code ); - - typedef FT_UInt32 * - (*FT_CMap_VariantCharListFunc)( FT_CMap cmap, - FT_Memory mem, - FT_UInt32 variant_selector ); - - - typedef struct FT_CMap_ClassRec_ - { - FT_ULong size; - FT_CMap_InitFunc init; - FT_CMap_DoneFunc done; - FT_CMap_CharIndexFunc char_index; - FT_CMap_CharNextFunc char_next; - - /* Subsequent entries are special ones for format 14 -- the variant */ - /* selector subtable which behaves like no other */ - - FT_CMap_CharVarIndexFunc char_var_index; - FT_CMap_CharVarIsDefaultFunc char_var_default; - FT_CMap_VariantListFunc variant_list; - FT_CMap_CharVariantListFunc charvariant_list; - FT_CMap_VariantCharListFunc variantchar_list; - - } FT_CMap_ClassRec; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DECLARE_CMAP_CLASS( class_ ) \ - FT_CALLBACK_TABLE const FT_CMap_ClassRec class_; - -#define FT_DEFINE_CMAP_CLASS( \ - class_, \ - size_, \ - init_, \ - done_, \ - char_index_, \ - char_next_, \ - char_var_index_, \ - char_var_default_, \ - variant_list_, \ - charvariant_list_, \ - variantchar_list_ ) \ - FT_CALLBACK_TABLE_DEF \ - const FT_CMap_ClassRec class_ = \ - { \ - size_, \ - init_, \ - done_, \ - char_index_, \ - char_next_, \ - char_var_index_, \ - char_var_default_, \ - variant_list_, \ - charvariant_list_, \ - variantchar_list_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DECLARE_CMAP_CLASS( class_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_CMap_ClassRec* clazz ); - -#define FT_DEFINE_CMAP_CLASS( \ - class_, \ - size_, \ - init_, \ - done_, \ - char_index_, \ - char_next_, \ - char_var_index_, \ - char_var_default_, \ - variant_list_, \ - charvariant_list_, \ - variantchar_list_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_CMap_ClassRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->size = size_; \ - clazz->init = init_; \ - clazz->done = done_; \ - clazz->char_index = char_index_; \ - clazz->char_next = char_next_; \ - clazz->char_var_index = char_var_index_; \ - clazz->char_var_default = char_var_default_; \ - clazz->variant_list = variant_list_; \ - clazz->charvariant_list = charvariant_list_; \ - clazz->variantchar_list = variantchar_list_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /* create a new charmap and add it to charmap->face */ - FT_BASE( FT_Error ) - FT_CMap_New( FT_CMap_Class clazz, - FT_Pointer init_data, - FT_CharMap charmap, - FT_CMap *acmap ); - - /* destroy a charmap and remove it from face's list */ - FT_BASE( void ) - FT_CMap_Done( FT_CMap cmap ); - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Face_InternalRec */ - /* */ - /* <Description> */ - /* This structure contains the internal fields of each FT_Face */ - /* object. These fields may change between different releases of */ - /* FreeType. */ - /* */ - /* <Fields> */ - /* max_points :: */ - /* The maximum number of points used to store the vectorial outline */ - /* of any glyph in this face. If this value cannot be known in */ - /* advance, or if the face isn't scalable, this should be set to 0. */ - /* Only relevant for scalable formats. */ - /* */ - /* max_contours :: */ - /* The maximum number of contours used to store the vectorial */ - /* outline of any glyph in this face. If this value cannot be */ - /* known in advance, or if the face isn't scalable, this should be */ - /* set to 0. Only relevant for scalable formats. */ - /* */ - /* transform_matrix :: */ - /* A 2x2 matrix of 16.16 coefficients used to transform glyph */ - /* outlines after they are loaded from the font. Only used by the */ - /* convenience functions. */ - /* */ - /* transform_delta :: */ - /* A translation vector used to transform glyph outlines after they */ - /* are loaded from the font. Only used by the convenience */ - /* functions. */ - /* */ - /* transform_flags :: */ - /* Some flags used to classify the transform. Only used by the */ - /* convenience functions. */ - /* */ - /* services :: */ - /* A cache for frequently used services. It should be only */ - /* accessed with the macro `FT_FACE_LOOKUP_SERVICE'. */ - /* */ - /* incremental_interface :: */ - /* If non-null, the interface through which glyph data and metrics */ - /* are loaded incrementally for faces that do not provide all of */ - /* 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. */ - /* */ - /* refcount :: */ - /* A counter initialized to~1 at the time an @FT_Face structure is */ - /* created. @FT_Reference_Face increments this counter, and */ - /* @FT_Done_Face only destroys a face if the counter is~1, */ - /* otherwise it simply decrements it. */ - /* */ - typedef struct FT_Face_InternalRec_ - { - FT_Matrix transform_matrix; - FT_Vector transform_delta; - FT_Int transform_flags; - - FT_ServiceCacheRec services; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - FT_Incremental_InterfaceRec* incremental_interface; -#endif - - FT_Bool ignore_unpatented_hinter; - FT_Int refcount; - - } FT_Face_InternalRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Slot_InternalRec */ - /* */ - /* <Description> */ - /* This structure contains the internal fields of each FT_GlyphSlot */ - /* object. These fields may change between different releases of */ - /* FreeType. */ - /* */ - /* <Fields> */ - /* loader :: The glyph loader object used to load outlines */ - /* into the glyph slot. */ - /* */ - /* flags :: Possible values are zero or */ - /* FT_GLYPH_OWN_BITMAP. The latter indicates */ - /* that the FT_GlyphSlot structure owns the */ - /* bitmap buffer. */ - /* */ - /* glyph_transformed :: Boolean. Set to TRUE when the loaded glyph */ - /* must be transformed through a specific */ - /* font transformation. This is _not_ the same */ - /* as the face transform set through */ - /* FT_Set_Transform(). */ - /* */ - /* glyph_matrix :: The 2x2 matrix corresponding to the glyph */ - /* transformation, if necessary. */ - /* */ - /* glyph_delta :: The 2d translation vector corresponding to */ - /* the glyph transformation, if necessary. */ - /* */ - /* glyph_hints :: Format-specific glyph hints management. */ - /* */ - -#define FT_GLYPH_OWN_BITMAP 0x1 - - typedef struct FT_Slot_InternalRec_ - { - FT_GlyphLoader loader; - FT_UInt flags; - FT_Bool glyph_transformed; - FT_Matrix glyph_matrix; - FT_Vector glyph_delta; - void* glyph_hints; - - } FT_GlyphSlot_InternalRec; - - -#if 0 - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Size_InternalRec */ - /* */ - /* <Description> */ - /* This structure contains the internal fields of each FT_Size */ - /* object. Currently, it's empty. */ - /* */ - /*************************************************************************/ - - typedef struct FT_Size_InternalRec_ - { - /* empty */ - - } FT_Size_InternalRec; - -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M O D U L E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_ModuleRec */ - /* */ - /* <Description> */ - /* A module object instance. */ - /* */ - /* <Fields> */ - /* clazz :: A pointer to the module's class. */ - /* */ - /* library :: A handle to the parent library object. */ - /* */ - /* memory :: A handle to the memory manager. */ - /* */ - typedef struct FT_ModuleRec_ - { - FT_Module_Class* clazz; - FT_Library library; - FT_Memory memory; - - } FT_ModuleRec; - - - /* typecast an object to an FT_Module */ -#define FT_MODULE( x ) ((FT_Module)( x )) -#define FT_MODULE_CLASS( x ) FT_MODULE( x )->clazz -#define FT_MODULE_LIBRARY( x ) FT_MODULE( x )->library -#define FT_MODULE_MEMORY( x ) FT_MODULE( x )->memory - - -#define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - FT_MODULE_FONT_DRIVER ) - -#define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - FT_MODULE_RENDERER ) - -#define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - FT_MODULE_HINTER ) - -#define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - FT_MODULE_STYLER ) - -#define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - FT_MODULE_DRIVER_SCALABLE ) - -#define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS( x )->module_flags & \ - FT_MODULE_DRIVER_NO_OUTLINES ) - -#define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - FT_MODULE_DRIVER_HAS_HINTER ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Module_Interface */ - /* */ - /* <Description> */ - /* Finds a module and returns its specific interface as a typeless */ - /* pointer. */ - /* */ - /* <Input> */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* <Return> */ - /* A module-specific interface if available, 0 otherwise. */ - /* */ - /* <Note> */ - /* You should better be familiar with FreeType internals to know */ - /* which module to look for, and what its interface is :-) */ - /* */ - FT_BASE( const void* ) - FT_Get_Module_Interface( FT_Library library, - const char* mod_name ); - - FT_BASE( FT_Pointer ) - ft_module_get_service( FT_Module module, - const char* service_id ); - - /* */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F A C E, S I Z E & G L Y P H S L O T O B J E C T S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* a few macros used to perform easy typecasts with minimal brain damage */ - -#define FT_FACE( x ) ((FT_Face)(x)) -#define FT_SIZE( x ) ((FT_Size)(x)) -#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) - -#define FT_FACE_DRIVER( x ) FT_FACE( x )->driver -#define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library -#define FT_FACE_MEMORY( x ) FT_FACE( x )->memory -#define FT_FACE_STREAM( x ) FT_FACE( x )->stream - -#define FT_SIZE_FACE( x ) FT_SIZE( x )->face -#define FT_SLOT_FACE( x ) FT_SLOT( x )->face - -#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph -#define FT_FACE_SIZE( x ) FT_FACE( x )->size - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_GlyphSlot */ - /* */ - /* <Description> */ - /* It is sometimes useful to have more than one glyph slot for a */ - /* given face object. This function is used to create additional */ - /* slots. All of them are automatically discarded when the face is */ - /* destroyed. */ - /* */ - /* <Input> */ - /* face :: A handle to a parent face object. */ - /* */ - /* <Output> */ - /* aslot :: A handle to a new glyph slot object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_BASE( FT_Error ) - FT_New_GlyphSlot( FT_Face face, - FT_GlyphSlot *aslot ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_GlyphSlot */ - /* */ - /* <Description> */ - /* Destroys a given glyph slot. Remember however that all slots are */ - /* automatically destroyed with its parent. Using this function is */ - /* not always mandatory. */ - /* */ - /* <Input> */ - /* slot :: A handle to a target glyph slot. */ - /* */ - FT_BASE( void ) - FT_Done_GlyphSlot( FT_GlyphSlot slot ); - - /* */ - -#define FT_REQUEST_WIDTH( req ) \ - ( (req)->horiResolution \ - ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \ - : (req)->width ) - -#define FT_REQUEST_HEIGHT( req ) \ - ( (req)->vertResolution \ - ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \ - : (req)->height ) - - - /* Set the metrics according to a bitmap strike. */ - FT_BASE( void ) - FT_Select_Metrics( FT_Face face, - FT_ULong strike_index ); - - - /* Set the metrics according to a size request. */ - FT_BASE( void ) - FT_Request_Metrics( FT_Face face, - FT_Size_Request req ); - - - /* Match a size request against `available_sizes'. */ - FT_BASE( FT_Error ) - FT_Match_Size( FT_Face face, - FT_Size_Request req, - FT_Bool ignore_width, - FT_ULong* size_index ); - - - /* Use the horizontal metrics to synthesize the vertical metrics. */ - /* If `advance' is zero, it is also synthesized. */ - FT_BASE( void ) - ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, - FT_Pos advance ); - - - /* Free the bitmap of a given glyphslot when needed (i.e., only when it */ - /* was allocated with ft_glyphslot_alloc_bitmap). */ - FT_BASE( void ) - ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); - - - /* Allocate a new bitmap buffer in a glyph slot. */ - FT_BASE( FT_Error ) - ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, - FT_ULong size ); - - - /* Set the bitmap buffer in a glyph slot to a given pointer. The buffer */ - /* will not be freed by a later call to ft_glyphslot_free_bitmap. */ - FT_BASE( void ) - ft_glyphslot_set_bitmap( FT_GlyphSlot slot, - FT_Byte* buffer ); - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** R E N D E R E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define FT_RENDERER( x ) ((FT_Renderer)( x )) -#define FT_GLYPH( x ) ((FT_Glyph)( x )) -#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) -#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) - - - typedef struct FT_RendererRec_ - { - FT_ModuleRec root; - FT_Renderer_Class* clazz; - FT_Glyph_Format glyph_format; - FT_Glyph_Class glyph_class; - - FT_Raster raster; - FT_Raster_Render_Func raster_render; - FT_Renderer_RenderFunc render; - - } FT_RendererRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F O N T D R I V E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* typecast a module into a driver easily */ -#define FT_DRIVER( x ) ((FT_Driver)(x)) - - /* typecast a module as a driver, and get its driver class */ -#define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_DriverRec */ - /* */ - /* <Description> */ - /* The root font driver class. A font driver is responsible for */ - /* managing and loading font files of a given format. */ - /* */ - /* <Fields> */ - /* root :: Contains the fields of the root module class. */ - /* */ - /* clazz :: A pointer to the font driver's class. Note that */ - /* this is NOT root.clazz. `class' wasn't used */ - /* as it is a reserved word in C++. */ - /* */ - /* faces_list :: The list of faces currently opened by this */ - /* driver. */ - /* */ - /* glyph_loader :: The glyph loader for all faces managed by this */ - /* driver. This object isn't defined for unscalable */ - /* formats. */ - /* */ - typedef struct FT_DriverRec_ - { - FT_ModuleRec root; - FT_Driver_Class clazz; - FT_ListRec faces_list; - FT_GlyphLoader glyph_loader; - - } FT_DriverRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** L I B R A R I E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* This hook is used by the TrueType debugger. It must be set to an */ - /* alternate truetype bytecode interpreter function. */ -#define FT_DEBUG_HOOK_TRUETYPE 0 - - - /* Set this debug hook to a non-null pointer to force unpatented hinting */ - /* 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> */ - /* FT_LibraryRec */ - /* */ - /* <Description> */ - /* The FreeType library class. This is the root of all FreeType */ - /* data. Use FT_New_Library() to create a library object, and */ - /* FT_Done_Library() to discard it and all child objects. */ - /* */ - /* <Fields> */ - /* memory :: The library's memory object. Manages memory */ - /* allocation. */ - /* */ - /* version_major :: The major version number of the library. */ - /* */ - /* version_minor :: The minor version number of the library. */ - /* */ - /* version_patch :: The current patch level of the library. */ - /* */ - /* num_modules :: The number of modules currently registered */ - /* within this library. This is set to 0 for new */ - /* libraries. New modules are added through the */ - /* FT_Add_Module() API function. */ - /* */ - /* modules :: A table used to store handles to the currently */ - /* registered modules. Note that each font driver */ - /* contains a list of its opened faces. */ - /* */ - /* renderers :: The list of renderers currently registered */ - /* within the library. */ - /* */ - /* cur_renderer :: The current outline renderer. This is a */ - /* shortcut used to avoid parsing the list on */ - /* each call to FT_Outline_Render(). It is a */ - /* handle to the current renderer for the */ - /* FT_GLYPH_FORMAT_OUTLINE format. */ - /* */ - /* auto_hinter :: XXX */ - /* */ - /* raster_pool :: The raster object's render pool. This can */ - /* ideally be changed dynamically at run-time. */ - /* */ - /* raster_pool_size :: The size of the render pool in bytes. */ - /* */ - /* debug_hooks :: XXX */ - /* */ - /* lcd_filter :: If subpixel rendering is activated, the */ - /* selected LCD filter mode. */ - /* */ - /* lcd_extra :: If subpixel rendering is activated, the number */ - /* of extra pixels needed for the LCD filter. */ - /* */ - /* lcd_weights :: If subpixel rendering is activated, the LCD */ - /* filter weights, if any. */ - /* */ - /* lcd_filter_func :: If subpixel rendering is activated, the LCD */ - /* filtering callback function. */ - /* */ - /* pic_container :: Contains global structs and tables, instead */ - /* of defining them globallly. */ - /* */ - /* refcount :: A counter initialized to~1 at the time an */ - /* @FT_Library structure is created. */ - /* @FT_Reference_Library increments this counter, */ - /* and @FT_Done_Library only destroys a library */ - /* if the counter is~1, otherwise it simply */ - /* decrements it. */ - /* */ - typedef struct FT_LibraryRec_ - { - FT_Memory memory; /* library's memory manager */ - - FT_Int version_major; - FT_Int version_minor; - FT_Int version_patch; - - FT_UInt num_modules; - FT_Module modules[FT_MAX_MODULES]; /* module objects */ - - FT_ListRec renderers; /* list of renderers */ - FT_Renderer cur_renderer; /* current outline renderer */ - FT_Module auto_hinter; - - FT_Byte* raster_pool; /* scan-line conversion */ - /* render pool */ - FT_ULong raster_pool_size; /* size of render pool in bytes */ - - 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 - -#ifdef FT_CONFIG_OPTION_PIC - FT_PIC_Container pic_container; -#endif - - FT_Int refcount; - - } FT_LibraryRec; - - - FT_BASE( FT_Renderer ) - FT_Lookup_Renderer( FT_Library library, - FT_Glyph_Format format, - FT_ListNode* node ); - - FT_BASE( FT_Error ) - FT_Render_Glyph_Internal( FT_Library library, - FT_GlyphSlot slot, - FT_Render_Mode render_mode ); - - typedef const char* - (*FT_Face_GetPostscriptNameFunc)( FT_Face face ); - - typedef FT_Error - (*FT_Face_GetGlyphNameFunc)( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ); - - typedef FT_UInt - (*FT_Face_GetGlyphNameIndexFunc)( FT_Face face, - FT_String* glyph_name ); - - -#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Memory */ - /* */ - /* <Description> */ - /* Creates a new memory object. */ - /* */ - /* <Return> */ - /* A pointer to the new memory object. 0 in case of error. */ - /* */ - FT_BASE( FT_Memory ) - FT_New_Memory( void ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Memory */ - /* */ - /* <Description> */ - /* Discards memory manager. */ - /* */ - /* <Input> */ - /* memory :: A handle to the memory manager. */ - /* */ - FT_BASE( void ) - FT_Done_Memory( FT_Memory memory ); - -#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ - - - /* Define default raster's interface. The default raster is located in */ - /* `src/base/ftraster.c'. */ - /* */ - /* Client applications can register new rasters through the */ - /* FT_Set_Raster() API. */ - -#ifndef FT_NO_DEFAULT_RASTER - FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** P I C S U P P O R T ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* PIC support macros for ftimage.h */ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DEFINE_OUTLINE_FUNCS */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Outline_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_OUTLINE_FUNCS( \ - class_, \ - move_to_, \ - line_to_, \ - conic_to_, \ - cubic_to_, \ - shift_, \ - delta_ ) \ - static const FT_Outline_Funcs class_ = \ - { \ - move_to_, \ - line_to_, \ - conic_to_, \ - cubic_to_, \ - shift_, \ - delta_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_OUTLINE_FUNCS( \ - class_, \ - move_to_, \ - line_to_, \ - conic_to_, \ - cubic_to_, \ - shift_, \ - delta_ ) \ - static FT_Error \ - Init_Class_ ## class_( FT_Outline_Funcs* clazz ) \ - { \ - clazz->move_to = move_to_; \ - clazz->line_to = line_to_; \ - clazz->conic_to = conic_to_; \ - clazz->cubic_to = cubic_to_; \ - clazz->shift = shift_; \ - clazz->delta = delta_; \ - \ - return FT_Err_Ok; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DEFINE_RASTER_FUNCS */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Raster_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_RASTER_FUNCS( \ - class_, \ - glyph_format_, \ - raster_new_, \ - raster_reset_, \ - raster_set_mode_, \ - raster_render_, \ - raster_done_ ) \ - const FT_Raster_Funcs class_ = \ - { \ - glyph_format_, \ - raster_new_, \ - raster_reset_, \ - raster_set_mode_, \ - raster_render_, \ - raster_done_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_RASTER_FUNCS( \ - class_, \ - glyph_format_, \ - raster_new_, \ - raster_reset_, \ - raster_set_mode_, \ - raster_render_, \ - raster_done_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Raster_Funcs* clazz ) \ - { \ - clazz->glyph_format = glyph_format_; \ - clazz->raster_new = raster_new_; \ - clazz->raster_reset = raster_reset_; \ - clazz->raster_set_mode = raster_set_mode_; \ - clazz->raster_render = raster_render_; \ - clazz->raster_done = raster_done_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /* PIC support macros for ftrender.h */ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DEFINE_GLYPH */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Glyph_Class struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated stcture to be filled. */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_GLYPH( \ - class_, \ - size_, \ - format_, \ - init_, \ - done_, \ - copy_, \ - transform_, \ - bbox_, \ - prepare_ ) \ - FT_CALLBACK_TABLE_DEF \ - const FT_Glyph_Class class_ = \ - { \ - size_, \ - format_, \ - init_, \ - done_, \ - copy_, \ - transform_, \ - bbox_, \ - prepare_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_GLYPH( \ - class_, \ - size_, \ - format_, \ - init_, \ - done_, \ - copy_, \ - transform_, \ - bbox_, \ - prepare_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Glyph_Class* clazz ) \ - { \ - clazz->glyph_size = size_; \ - clazz->glyph_format = format_; \ - clazz->glyph_init = init_; \ - clazz->glyph_done = done_; \ - clazz->glyph_copy = copy_; \ - clazz->glyph_transform = transform_; \ - clazz->glyph_bbox = bbox_; \ - clazz->glyph_prepare = prepare_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DECLARE_RENDERER */ - /* */ - /* <Description> */ - /* Used to create a forward declaration of a */ - /* FT_Renderer_Class struct instance. */ - /* */ - /* <Macro> */ - /* FT_DEFINE_RENDERER */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Renderer_Class struct. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need */ - /* to be called with a pointer where the allocated structure is */ - /* returned. And when it is no longer needed a `destroy' function */ - /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ - /* a mechanism to call these functions for the default modules */ - /* described in `ftmodule.h'. */ - /* */ - /* Notice that the created `create' and `destroy' functions call */ - /* `pic_init' and `pic_free' to allow you to manually allocate and */ - /* initialize any additional global data, like a module specific */ - /* interface, and put them in the global pic container defined in */ - /* `ftpic.h'. If you don't need them just implement the functions as */ - /* empty to resolve the link error. Also the `pic_init' and */ - /* `pic_free' functions should be declared in `pic.h', to be referred */ - /* by the renderer definition calling `FT_DEFINE_RENDERER' in the */ - /* following. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DECLARE_RENDERER( class_ ) \ - FT_EXPORT_VAR( const FT_Renderer_Class ) class_; - -#define FT_DEFINE_RENDERER( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_, \ - glyph_format_, \ - render_glyph_, \ - transform_glyph_, \ - get_glyph_cbox_, \ - set_mode_, \ - raster_class_ ) \ - FT_CALLBACK_TABLE_DEF \ - const FT_Renderer_Class class_ = \ - { \ - FT_DEFINE_ROOT_MODULE( flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - glyph_format_, \ - \ - render_glyph_, \ - transform_glyph_, \ - get_glyph_cbox_, \ - set_mode_, \ - \ - raster_class_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DECLARE_RENDERER( class_ ) FT_DECLARE_MODULE( class_ ) - -#define FT_DEFINE_RENDERER( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_, \ - glyph_format_, \ - render_glyph_, \ - transform_glyph_, \ - get_glyph_cbox_, \ - set_mode_, \ - raster_class_ ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_Module_Class* clazz ) \ - { \ - FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \ - FT_Memory memory = library->memory; \ - \ - \ - class_ ## _pic_free( library ); \ - if ( rclazz ) \ - FT_FREE( rclazz ); \ - } \ - \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_Module_Class** output_class ) \ - { \ - FT_Renderer_Class* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ - return error; \ - \ - error = class_ ## _pic_init( library ); \ - if ( error ) \ - { \ - FT_FREE( clazz ); \ - return error; \ - } \ - \ - FT_DEFINE_ROOT_MODULE( flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - \ - clazz->glyph_format = glyph_format_; \ - \ - clazz->render_glyph = render_glyph_; \ - clazz->transform_glyph = transform_glyph_; \ - clazz->get_glyph_cbox = get_glyph_cbox_; \ - clazz->set_mode = set_mode_; \ - \ - clazz->raster_class = raster_class_; \ - \ - *output_class = (FT_Module_Class*)clazz; \ - \ - return FT_Err_Ok; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /* PIC support macros for ftmodapi.h **/ - - -#ifdef FT_CONFIG_OPTION_PIC - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Creator */ - /* */ - /* <Description> */ - /* A function used to create (allocate) a new module class object. */ - /* The object's members are initialized, but the module itself is */ - /* not. */ - /* */ - /* <Input> */ - /* memory :: A handle to the memory manager. */ - /* output_class :: Initialized with the newly allocated class. */ - /* */ - typedef FT_Error - (*FT_Module_Creator)( FT_Memory memory, - FT_Module_Class** output_class ); - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Destroyer */ - /* */ - /* <Description> */ - /* A function used to destroy (deallocate) a module class object. */ - /* */ - /* <Input> */ - /* memory :: A handle to the memory manager. */ - /* clazz :: Module class to destroy. */ - /* */ - typedef void - (*FT_Module_Destroyer)( FT_Memory memory, - FT_Module_Class* clazz ); - -#endif - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DECLARE_MODULE */ - /* */ - /* <Description> */ - /* Used to create a forward declaration of a */ - /* FT_Module_Class struct instance. */ - /* */ - /* <Macro> */ - /* FT_DEFINE_MODULE */ - /* */ - /* <Description> */ - /* Used to initialize an instance of an FT_Module_Class struct. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to */ - /* be called with a pointer where the allocated structure is */ - /* returned. And when it is no longer needed a `destroy' function */ - /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ - /* a mechanism to call these functions for the default modules */ - /* described in `ftmodule.h'. */ - /* */ - /* Notice that the created `create' and `destroy' functions call */ - /* `pic_init' and `pic_free' to allow you to manually allocate and */ - /* initialize any additional global data, like a module specific */ - /* interface, and put them in the global pic container defined in */ - /* `ftpic.h'. If you don't need them just implement the functions as */ - /* empty to resolve the link error. Also the `pic_init' and */ - /* `pic_free' functions should be declared in `pic.h', to be referred */ - /* by the module definition calling `FT_DEFINE_MODULE' in the */ - /* following. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ - /* <Macro> */ - /* FT_DEFINE_ROOT_MODULE */ - /* */ - /* <Description> */ - /* Used to initialize an instance of an FT_Module_Class struct inside */ - /* another struct that contains it or in a function that initializes */ - /* that containing struct. */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DECLARE_MODULE( class_ ) \ - FT_CALLBACK_TABLE \ - const FT_Module_Class class_; - -#define FT_DEFINE_ROOT_MODULE( \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - { \ - flags_, \ - size_, \ - \ - name_, \ - version_, \ - requires_, \ - \ - interface_, \ - \ - init_, \ - done_, \ - get_interface_, \ - }, - -#define FT_DEFINE_MODULE( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - FT_CALLBACK_TABLE_DEF \ - const FT_Module_Class class_ = \ - { \ - flags_, \ - size_, \ - \ - name_, \ - version_, \ - requires_, \ - \ - interface_, \ - \ - init_, \ - done_, \ - get_interface_, \ - }; - - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DECLARE_MODULE( class_ ) \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_Module_Class** output_class ); \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_Module_Class* clazz ); - -#define FT_DEFINE_ROOT_MODULE( \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - clazz->root.module_flags = flags_; \ - clazz->root.module_size = size_; \ - clazz->root.module_name = name_; \ - clazz->root.module_version = version_; \ - clazz->root.module_requires = requires_; \ - \ - clazz->root.module_interface = interface_; \ - \ - clazz->root.module_init = init_; \ - clazz->root.module_done = done_; \ - clazz->root.get_interface = get_interface_; - -#define FT_DEFINE_MODULE( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_Module_Class* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - class_ ## _pic_free( library ); \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_Module_Class** output_class ) \ - { \ - FT_Memory memory = library->memory; \ - FT_Module_Class* clazz = NULL; \ - FT_Error error; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ - return error; \ - error = class_ ## _pic_init( library ); \ - if ( error ) \ - { \ - FT_FREE( clazz ); \ - return error; \ - } \ - \ - clazz->module_flags = flags_; \ - clazz->module_size = size_; \ - clazz->module_name = name_; \ - clazz->module_version = version_; \ - clazz->module_requires = requires_; \ - \ - clazz->module_interface = interface_; \ - \ - clazz->module_init = init_; \ - clazz->module_done = done_; \ - clazz->get_interface = get_interface_; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -FT_END_HEADER - -#endif /* __FTOBJS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftpic.h b/drivers/freetype/freetype/include/freetype/internal/ftpic.h deleted file mode 100644 index 485ce7a24e..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftpic.h +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpic.h */ -/* */ -/* The FreeType position independent code services (declaration). */ -/* */ -/* Copyright 2009, 2012 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Modules that ordinarily have const global data that need address */ - /* can instead define pointers here. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTPIC_H__ -#define __FTPIC_H__ - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC - - typedef struct FT_PIC_Container_ - { - /* pic containers for base */ - void* base; - - /* pic containers for modules */ - void* autofit; - void* cff; - void* pshinter; - void* psnames; - void* raster; - void* sfnt; - void* smooth; - void* truetype; - - } FT_PIC_Container; - - - /* Initialize the various function tables, structs, etc. */ - /* stored in the container. */ - FT_BASE( FT_Error ) - ft_pic_container_init( FT_Library library ); - - - /* Destroy the contents of the container. */ - FT_BASE( void ) - ft_pic_container_destroy( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __FTPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftrfork.h b/drivers/freetype/freetype/include/freetype/internal/ftrfork.h deleted file mode 100644 index 6307f2d0c5..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftrfork.h +++ /dev/null @@ -1,258 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrfork.h */ -/* */ -/* Embedded resource forks accessor (specification). */ -/* */ -/* Copyright 2004, 2006, 2007, 2012 by */ -/* Masatake YAMATO and Redhat K.K. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* Development of the code in this file is support of */ -/* Information-technology Promotion Agency, Japan. */ -/***************************************************************************/ - - -#ifndef __FTRFORK_H__ -#define __FTRFORK_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H - - -FT_BEGIN_HEADER - - - /* Number of guessing rules supported in `FT_Raccess_Guess'. */ - /* Don't forget to increment the number if you add a new guessing rule. */ -#define FT_RACCESS_N_RULES 9 - - - /* A structure to describe a reference in a resource by its resource ID */ - /* and internal offset. The `POST' resource expects to be concatenated */ - /* by the order of resource IDs instead of its appearance in the file. */ - - typedef struct FT_RFork_Ref_ - { - FT_UShort res_id; - FT_ULong offset; - - } FT_RFork_Ref; - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK - typedef FT_Error - (*ft_raccess_guess_func)( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - typedef enum FT_RFork_Rule_ { - FT_RFork_Rule_invalid = -2, - FT_RFork_Rule_uknown, /* -1 */ - FT_RFork_Rule_apple_double, - FT_RFork_Rule_apple_single, - FT_RFork_Rule_darwin_ufs_export, - FT_RFork_Rule_darwin_newvfs, - FT_RFork_Rule_darwin_hfsplus, - FT_RFork_Rule_vfat, - FT_RFork_Rule_linux_cap, - FT_RFork_Rule_linux_double, - FT_RFork_Rule_linux_netatalk - } FT_RFork_Rule; - - /* For fast translation between rule index and rule type, - * the macros FT_RFORK_xxx should be kept consistent with - * the raccess_guess_funcs table - */ - typedef struct ft_raccess_guess_rec_ { - ft_raccess_guess_func func; - FT_RFork_Rule type; - } ft_raccess_guess_rec; - -#ifndef FT_CONFIG_OPTION_PIC - - /* this array is a storage in non-PIC mode, so ; is needed in END */ -#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ - const type name[] = { -#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ - { raccess_guess_ ## func_suffix, \ - FT_RFork_Rule_ ## type_suffix }, -#define CONST_FT_RFORK_RULE_ARRAY_END }; - -#else /* FT_CONFIG_OPTION_PIC */ - - /* this array is a function in PIC mode, so no ; is needed in END */ -#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ - void \ - FT_Init_ ## name( type* storage ) \ - { \ - type* local = storage; \ - \ - \ - int i = 0; -#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ - local[i].func = raccess_guess_ ## func_suffix; \ - local[i].type = FT_RFork_Rule_ ## type_suffix; \ - i++; -#define CONST_FT_RFORK_RULE_ARRAY_END } - -#endif /* FT_CONFIG_OPTION_PIC */ - -#endif /* FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Raccess_Guess */ - /* */ - /* <Description> */ - /* Guess a file name and offset where the actual resource fork is */ - /* stored. The macro FT_RACCESS_N_RULES holds the number of */ - /* guessing rules; the guessed result for the Nth rule is */ - /* represented as a triplet: a new file name (new_names[N]), a file */ - /* offset (offsets[N]), and an error code (errors[N]). */ - /* */ - /* <Input> */ - /* library :: */ - /* A FreeType library instance. */ - /* */ - /* stream :: */ - /* A file stream containing the resource fork. */ - /* */ - /* base_name :: */ - /* The (base) file name of the resource fork used for some */ - /* guessing rules. */ - /* */ - /* <Output> */ - /* new_names :: */ - /* An array of guessed file names in which the resource forks may */ - /* exist. If `new_names[N]' is NULL, the guessed file name is */ - /* equal to `base_name'. */ - /* */ - /* offsets :: */ - /* An array of guessed file offsets. `offsets[N]' holds the file */ - /* offset of the possible start of the resource fork in file */ - /* `new_names[N]'. */ - /* */ - /* errors :: */ - /* An array of FreeType error codes. `errors[N]' is the error */ - /* code of Nth guessing rule function. If `errors[N]' is not */ - /* FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless. */ - /* */ - FT_BASE( void ) - FT_Raccess_Guess( FT_Library library, - FT_Stream stream, - char* base_name, - char** new_names, - FT_Long* offsets, - FT_Error* errors ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Raccess_Get_HeaderInfo */ - /* */ - /* <Description> */ - /* Get the information from the header of resource fork. The */ - /* information includes the file offset where the resource map */ - /* starts, and the file offset where the resource data starts. */ - /* `FT_Raccess_Get_DataOffsets' requires these two data. */ - /* */ - /* <Input> */ - /* library :: */ - /* A FreeType library instance. */ - /* */ - /* stream :: */ - /* A file stream containing the resource fork. */ - /* */ - /* rfork_offset :: */ - /* The file offset where the resource fork starts. */ - /* */ - /* <Output> */ - /* map_offset :: */ - /* The file offset where the resource map starts. */ - /* */ - /* rdata_pos :: */ - /* The file offset where the resource data starts. */ - /* */ - /* <Return> */ - /* FreeType error code. FT_Err_Ok means success. */ - /* */ - FT_BASE( FT_Error ) - FT_Raccess_Get_HeaderInfo( FT_Library library, - FT_Stream stream, - FT_Long rfork_offset, - FT_Long *map_offset, - FT_Long *rdata_pos ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Raccess_Get_DataOffsets */ - /* */ - /* <Description> */ - /* Get the data offsets for a tag in a resource fork. Offsets are */ - /* stored in an array because, in some cases, resources in a resource */ - /* fork have the same tag. */ - /* */ - /* <Input> */ - /* library :: */ - /* A FreeType library instance. */ - /* */ - /* stream :: */ - /* A file stream containing the resource fork. */ - /* */ - /* map_offset :: */ - /* The file offset where the resource map starts. */ - /* */ - /* rdata_pos :: */ - /* The file offset where the resource data starts. */ - /* */ - /* tag :: */ - /* The resource tag. */ - /* */ - /* <Output> */ - /* offsets :: */ - /* The stream offsets for the resource data specified by `tag'. */ - /* This array is allocated by the function, so you have to call */ - /* @ft_mem_free after use. */ - /* */ - /* count :: */ - /* The length of offsets array. */ - /* */ - /* <Return> */ - /* FreeType error code. FT_Err_Ok means success. */ - /* */ - /* <Note> */ - /* Normally you should use `FT_Raccess_Get_HeaderInfo' to get the */ - /* value for `map_offset' and `rdata_pos'. */ - /* */ - FT_BASE( FT_Error ) - FT_Raccess_Get_DataOffsets( FT_Library library, - FT_Stream stream, - FT_Long map_offset, - FT_Long rdata_pos, - FT_Long tag, - FT_Long **offsets, - FT_Long *count ); - - -FT_END_HEADER - -#endif /* __FTRFORK_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftserv.h b/drivers/freetype/freetype/include/freetype/internal/ftserv.h deleted file mode 100644 index cd5fbd0fac..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftserv.h +++ /dev/null @@ -1,763 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftserv.h */ -/* */ -/* The FreeType services (specification only). */ -/* */ -/* Copyright 2003-2007, 2009, 2012, 2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Each module can export one or more `services'. Each service is */ - /* identified by a constant string and modeled by a pointer; the latter */ - /* generally corresponds to a structure containing function pointers. */ - /* */ - /* Note that a service's data cannot be a mere function pointer because */ - /* in C it is possible that function pointers might be implemented */ - /* differently than data pointers (e.g. 48 bits instead of 32). */ - /* */ - /*************************************************************************/ - - -#ifndef __FTSERV_H__ -#define __FTSERV_H__ - - -FT_BEGIN_HEADER - - /* - * @macro: - * FT_FACE_FIND_SERVICE - * - * @description: - * This macro is used to look up a service from a face's driver module. - * - * @input: - * face :: - * The source face handle. - * - * id :: - * A string describing the service as defined in the service's - * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to - * `multi-masters'). It is automatically prefixed with - * `FT_SERVICE_ID_'. - * - * @output: - * ptr :: - * A variable that receives the service pointer. Will be NULL - * if not found. - */ -#ifdef __cplusplus - -#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_ = NULL; \ - FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ - \ - \ - if ( module->clazz->get_interface ) \ - _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ - *_pptr_ = _tmp_; \ - FT_END_STMNT - -#else /* !C++ */ - -#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_ = NULL; \ - \ - if ( module->clazz->get_interface ) \ - _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ - ptr = _tmp_; \ - FT_END_STMNT - -#endif /* !C++ */ - - - /* - * @macro: - * FT_FACE_FIND_GLOBAL_SERVICE - * - * @description: - * This macro is used to look up a service from all modules. - * - * @input: - * face :: - * The source face handle. - * - * id :: - * A string describing the service as defined in the service's - * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to - * `multi-masters'). It is automatically prefixed with - * `FT_SERVICE_ID_'. - * - * @output: - * ptr :: - * A variable that receives the service pointer. Will be NULL - * if not found. - */ -#ifdef __cplusplus - -#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_; \ - FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ - \ - \ - _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ - *_pptr_ = _tmp_; \ - FT_END_STMNT - -#else /* !C++ */ - -#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_; \ - \ - \ - _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ - ptr = _tmp_; \ - FT_END_STMNT - -#endif /* !C++ */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** S E R V I C E D E S C R I P T O R S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * The following structure is used to _describe_ a given service - * to the library. This is useful to build simple static service lists. - */ - typedef struct FT_ServiceDescRec_ - { - const char* serv_id; /* service name */ - const void* serv_data; /* service pointer/data */ - - } FT_ServiceDescRec; - - typedef const FT_ServiceDescRec* FT_ServiceDesc; - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DEFINE_SERVICEDESCREC1 */ - /* FT_DEFINE_SERVICEDESCREC2 */ - /* FT_DEFINE_SERVICEDESCREC3 */ - /* FT_DEFINE_SERVICEDESCREC4 */ - /* FT_DEFINE_SERVICEDESCREC5 */ - /* FT_DEFINE_SERVICEDESCREC6 */ - /* FT_DEFINE_SERVICEDESCREC7 */ - /* */ - /* <Description> */ - /* Used to initialize an array of FT_ServiceDescRec structures. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs to */ - /* be called with a pointer to return an allocated array. As soon as */ - /* it is no longer needed, a `destroy' function needs to be called to */ - /* release that allocation. */ - /* */ - /* These functions should be manually called from the `pic_init' and */ - /* `pic_free' functions of your module (see FT_DEFINE_MODULE). */ - /* */ - /* When FT_CONFIG_OPTION_PIC is not defined the array will be */ - /* allocated in the global scope (or the scope where the macro is */ - /* used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICEDESCREC1( class_, \ - serv_id_1, serv_data_1 ) \ - static const FT_ServiceDescRec class_[] = \ - { \ - { serv_id_1, serv_data_1 }, \ - { NULL, NULL } \ - }; - -#define FT_DEFINE_SERVICEDESCREC2( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2 ) \ - static const FT_ServiceDescRec class_[] = \ - { \ - { serv_id_1, serv_data_1 }, \ - { serv_id_2, serv_data_2 }, \ - { NULL, NULL } \ - }; - -#define FT_DEFINE_SERVICEDESCREC3( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3 ) \ - static const FT_ServiceDescRec class_[] = \ - { \ - { serv_id_1, serv_data_1 }, \ - { serv_id_2, serv_data_2 }, \ - { serv_id_3, serv_data_3 }, \ - { NULL, NULL } \ - }; - -#define FT_DEFINE_SERVICEDESCREC4( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4 ) \ - static const FT_ServiceDescRec class_[] = \ - { \ - { serv_id_1, serv_data_1 }, \ - { serv_id_2, serv_data_2 }, \ - { serv_id_3, serv_data_3 }, \ - { serv_id_4, serv_data_4 }, \ - { NULL, NULL } \ - }; - -#define FT_DEFINE_SERVICEDESCREC5( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5 ) \ - static const FT_ServiceDescRec class_[] = \ - { \ - { serv_id_1, serv_data_1 }, \ - { serv_id_2, serv_data_2 }, \ - { serv_id_3, serv_data_3 }, \ - { serv_id_4, serv_data_4 }, \ - { serv_id_5, serv_data_5 }, \ - { NULL, NULL } \ - }; - -#define FT_DEFINE_SERVICEDESCREC6( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6 ) \ - static const FT_ServiceDescRec class_[] = \ - { \ - { serv_id_1, serv_data_1 }, \ - { serv_id_2, serv_data_2 }, \ - { serv_id_3, serv_data_3 }, \ - { serv_id_4, serv_data_4 }, \ - { serv_id_5, serv_data_5 }, \ - { serv_id_6, serv_data_6 }, \ - { NULL, NULL } \ - }; - -#define FT_DEFINE_SERVICEDESCREC7( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6, \ - serv_id_7, serv_data_7 ) \ - static const FT_ServiceDescRec class_[] = \ - { \ - { serv_id_1, serv_data_1 }, \ - { serv_id_2, serv_data_2 }, \ - { serv_id_3, serv_data_3 }, \ - { serv_id_4, serv_data_4 }, \ - { serv_id_5, serv_data_5 }, \ - { serv_id_6, serv_data_6 }, \ - { serv_id_7, serv_data_7 }, \ - { NULL, NULL } \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICEDESCREC1( class_, \ - serv_id_1, serv_data_1 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = NULL; \ - clazz[1].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC2( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = NULL; \ - clazz[2].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC3( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = NULL; \ - clazz[3].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC4( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = NULL; \ - clazz[4].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC5( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = serv_id_5; \ - clazz[4].serv_data = serv_data_5; \ - clazz[5].serv_id = NULL; \ - clazz[5].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC6( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = serv_id_5; \ - clazz[4].serv_data = serv_data_5; \ - clazz[5].serv_id = serv_id_6; \ - clazz[5].serv_data = serv_data_6; \ - clazz[6].serv_id = NULL; \ - clazz[6].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC7( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6, \ - serv_id_7, serv_data_7 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = serv_id_5; \ - clazz[4].serv_data = serv_data_5; \ - clazz[5].serv_id = serv_id_6; \ - clazz[5].serv_data = serv_data_6; \ - clazz[6].serv_id = serv_id_7; \ - clazz[6].serv_data = serv_data_7; \ - clazz[7].serv_id = NULL; \ - clazz[7].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /* - * Parse a list of FT_ServiceDescRec descriptors and look for - * a specific service by ID. Note that the last element in the - * array must be { NULL, NULL }, and that the function should - * return NULL if the service isn't available. - * - * This function can be used by modules to implement their - * `get_service' method. - */ - FT_BASE( FT_Pointer ) - ft_service_list_lookup( FT_ServiceDesc service_descriptors, - const char* service_id ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** S E R V I C E S C A C H E *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * This structure is used to store a cache for several frequently used - * services. It is the type of `face->internal->services'. You - * should only use FT_FACE_LOOKUP_SERVICE to access it. - * - * All fields should have the type FT_Pointer to relax compilation - * dependencies. We assume the developer isn't completely stupid. - * - * Each field must be named `service_XXXX' where `XXX' corresponds to - * the correct FT_SERVICE_ID_XXXX macro. See the definition of - * FT_FACE_LOOKUP_SERVICE below how this is implemented. - * - */ - typedef struct FT_ServiceCacheRec_ - { - FT_Pointer service_POSTSCRIPT_FONT_NAME; - FT_Pointer service_MULTI_MASTERS; - FT_Pointer service_GLYPH_DICT; - FT_Pointer service_PFR_METRICS; - FT_Pointer service_WINFNT; - - } FT_ServiceCacheRec, *FT_ServiceCache; - - - /* - * A magic number used within the services cache. - */ - - /* ensure that value `1' has the same width as a pointer */ -#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~(FT_PtrDist)1) - - - /* - * @macro: - * FT_FACE_LOOKUP_SERVICE - * - * @description: - * This macro is used to lookup a service from a face's driver module - * using its cache. - * - * @input: - * face:: - * The source face handle containing the cache. - * - * field :: - * The field name in the cache. - * - * id :: - * The service ID. - * - * @output: - * ptr :: - * A variable receiving the service data. NULL if not available. - */ -#ifdef __cplusplus - -#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Pointer svc; \ - FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \ - \ - \ - svc = FT_FACE( face )->internal->services. service_ ## id; \ - if ( svc == FT_SERVICE_UNAVAILABLE ) \ - svc = NULL; \ - else if ( svc == NULL ) \ - { \ - FT_FACE_FIND_SERVICE( face, svc, id ); \ - \ - FT_FACE( face )->internal->services. service_ ## id = \ - (FT_Pointer)( svc != NULL ? svc \ - : FT_SERVICE_UNAVAILABLE ); \ - } \ - *Pptr = svc; \ - FT_END_STMNT - -#else /* !C++ */ - -#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Pointer svc; \ - \ - \ - svc = FT_FACE( face )->internal->services. service_ ## id; \ - if ( svc == FT_SERVICE_UNAVAILABLE ) \ - svc = NULL; \ - else if ( svc == NULL ) \ - { \ - FT_FACE_FIND_SERVICE( face, svc, id ); \ - \ - FT_FACE( face )->internal->services. service_ ## id = \ - (FT_Pointer)( svc != NULL ? svc \ - : FT_SERVICE_UNAVAILABLE ); \ - } \ - ptr = svc; \ - FT_END_STMNT - -#endif /* !C++ */ - - /* - * A macro used to define new service structure types. - */ - -#define FT_DEFINE_SERVICE( name ) \ - typedef struct FT_Service_ ## name ## Rec_ \ - FT_Service_ ## name ## Rec ; \ - typedef struct FT_Service_ ## name ## Rec_ \ - const * FT_Service_ ## name ; \ - struct FT_Service_ ## name ## Rec_ - - /* */ - - /* - * The header files containing the services. - */ - -#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> -#define FT_SERVICE_CID_H <freetype/internal/services/svcid.h> -#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> -#define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> -#define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> -#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> -#define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h> -#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> -#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h> -#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h> -#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h> -#define FT_SERVICE_PROPERTIES_H <freetype/internal/services/svprop.h> -#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> -#define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> -#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> -#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> -#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> -#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> - - /* */ - -FT_END_HEADER - -#endif /* __FTSERV_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftstream.h b/drivers/freetype/freetype/include/freetype/internal/ftstream.h deleted file mode 100644 index 2661858320..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftstream.h +++ /dev/null @@ -1,536 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstream.h */ -/* */ -/* Stream handling (specification). */ -/* */ -/* Copyright 1996-2002, 2004-2006, 2011, 2013 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 __FTSTREAM_H__ -#define __FTSTREAM_H__ - - -#include <ft2build.h> -#include FT_SYSTEM_H -#include FT_INTERNAL_OBJECTS_H - - -FT_BEGIN_HEADER - - - /* format of an 8-bit frame_op value: */ - /* */ - /* bit 76543210 */ - /* xxxxxxes */ - /* */ - /* s is set to 1 if the value is signed. */ - /* e is set to 1 if the value is little-endian. */ - /* xxx is a command. */ - -#define FT_FRAME_OP_SHIFT 2 -#define FT_FRAME_OP_SIGNED 1 -#define FT_FRAME_OP_LITTLE 2 -#define FT_FRAME_OP_COMMAND( x ) ( x >> FT_FRAME_OP_SHIFT ) - -#define FT_MAKE_FRAME_OP( command, little, sign ) \ - ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign ) - -#define FT_FRAME_OP_END 0 -#define FT_FRAME_OP_START 1 /* start a new frame */ -#define FT_FRAME_OP_BYTE 2 /* read 1-byte value */ -#define FT_FRAME_OP_SHORT 3 /* read 2-byte value */ -#define FT_FRAME_OP_LONG 4 /* read 4-byte value */ -#define FT_FRAME_OP_OFF3 5 /* read 3-byte value */ -#define FT_FRAME_OP_BYTES 6 /* read a bytes sequence */ - - - typedef enum FT_Frame_Op_ - { - ft_frame_end = 0, - ft_frame_start = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ), - - ft_frame_byte = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 0 ), - ft_frame_schar = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 1 ), - - ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ), - ft_frame_short_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ), - ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ), - ft_frame_short_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ), - - ft_frame_ulong_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ), - ft_frame_long_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ), - ft_frame_ulong_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ), - ft_frame_long_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ), - - ft_frame_uoff3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ), - ft_frame_off3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ), - ft_frame_uoff3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ), - ft_frame_off3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ), - - ft_frame_bytes = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ), - ft_frame_skip = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 ) - - } FT_Frame_Op; - - - typedef struct FT_Frame_Field_ - { - FT_Byte value; - FT_Byte size; - FT_UShort offset; - - } FT_Frame_Field; - - - /* Construct an FT_Frame_Field out of a structure type and a field name. */ - /* The structure type must be set in the FT_STRUCTURE macro before */ - /* calling the FT_FRAME_START() macro. */ - /* */ -#define FT_FIELD_SIZE( f ) \ - (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f ) - -#define FT_FIELD_SIZE_DELTA( f ) \ - (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] ) - -#define FT_FIELD_OFFSET( f ) \ - (FT_UShort)( offsetof( FT_STRUCTURE, f ) ) - -#define FT_FRAME_FIELD( frame_op, field ) \ - { \ - frame_op, \ - FT_FIELD_SIZE( field ), \ - FT_FIELD_OFFSET( field ) \ - } - -#define FT_MAKE_EMPTY_FIELD( frame_op ) { frame_op, 0, 0 } - -#define FT_FRAME_START( size ) { ft_frame_start, 0, size } -#define FT_FRAME_END { ft_frame_end, 0, 0 } - -#define FT_FRAME_LONG( f ) FT_FRAME_FIELD( ft_frame_long_be, f ) -#define FT_FRAME_ULONG( f ) FT_FRAME_FIELD( ft_frame_ulong_be, f ) -#define FT_FRAME_SHORT( f ) FT_FRAME_FIELD( ft_frame_short_be, f ) -#define FT_FRAME_USHORT( f ) FT_FRAME_FIELD( ft_frame_ushort_be, f ) -#define FT_FRAME_OFF3( f ) FT_FRAME_FIELD( ft_frame_off3_be, f ) -#define FT_FRAME_UOFF3( f ) FT_FRAME_FIELD( ft_frame_uoff3_be, f ) -#define FT_FRAME_BYTE( f ) FT_FRAME_FIELD( ft_frame_byte, f ) -#define FT_FRAME_CHAR( f ) FT_FRAME_FIELD( ft_frame_schar, f ) - -#define FT_FRAME_LONG_LE( f ) FT_FRAME_FIELD( ft_frame_long_le, f ) -#define FT_FRAME_ULONG_LE( f ) FT_FRAME_FIELD( ft_frame_ulong_le, f ) -#define FT_FRAME_SHORT_LE( f ) FT_FRAME_FIELD( ft_frame_short_le, f ) -#define FT_FRAME_USHORT_LE( f ) FT_FRAME_FIELD( ft_frame_ushort_le, f ) -#define FT_FRAME_OFF3_LE( f ) FT_FRAME_FIELD( ft_frame_off3_le, f ) -#define FT_FRAME_UOFF3_LE( f ) FT_FRAME_FIELD( ft_frame_uoff3_le, f ) - -#define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } -#define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } -#define FT_FRAME_SKIP_BYTE { ft_frame_byte, 0, 0 } - -#define FT_FRAME_BYTES( field, count ) \ - { \ - ft_frame_bytes, \ - count, \ - FT_FIELD_OFFSET( field ) \ - } - -#define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } - - - /*************************************************************************/ - /* */ - /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */ - /* type `char*' or equivalent (1-byte elements). */ - /* */ - -#define FT_BYTE_( p, i ) ( ((const FT_Byte*)(p))[(i)] ) - -#define FT_INT16( x ) ( (FT_Int16)(x) ) -#define FT_UINT16( x ) ( (FT_UInt16)(x) ) -#define FT_INT32( x ) ( (FT_Int32)(x) ) -#define FT_UINT32( x ) ( (FT_UInt32)(x) ) - - -#define FT_BYTE_U16( p, i, s ) ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) ) -#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) - - -#define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8) | \ - FT_BYTE_U16( p, 1, 0) ) - -#define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \ - FT_BYTE_U16( p, 1, 0 ) ) - -#define FT_PEEK_LONG( p ) FT_INT32( FT_BYTE_U32( p, 0, 24 ) | \ - FT_BYTE_U32( p, 1, 16 ) | \ - FT_BYTE_U32( p, 2, 8 ) | \ - FT_BYTE_U32( p, 3, 0 ) ) - -#define FT_PEEK_ULONG( p ) FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \ - FT_BYTE_U32( p, 1, 16 ) | \ - FT_BYTE_U32( p, 2, 8 ) | \ - FT_BYTE_U32( p, 3, 0 ) ) - -#define FT_PEEK_OFF3( p ) FT_INT32( FT_BYTE_U32( p, 0, 16 ) | \ - FT_BYTE_U32( p, 1, 8 ) | \ - FT_BYTE_U32( p, 2, 0 ) ) - -#define FT_PEEK_UOFF3( p ) FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \ - FT_BYTE_U32( p, 1, 8 ) | \ - FT_BYTE_U32( p, 2, 0 ) ) - -#define FT_PEEK_SHORT_LE( p ) FT_INT16( FT_BYTE_U16( p, 1, 8 ) | \ - FT_BYTE_U16( p, 0, 0 ) ) - -#define FT_PEEK_USHORT_LE( p ) FT_UINT16( FT_BYTE_U16( p, 1, 8 ) | \ - FT_BYTE_U16( p, 0, 0 ) ) - -#define FT_PEEK_LONG_LE( p ) FT_INT32( FT_BYTE_U32( p, 3, 24 ) | \ - FT_BYTE_U32( p, 2, 16 ) | \ - FT_BYTE_U32( p, 1, 8 ) | \ - FT_BYTE_U32( p, 0, 0 ) ) - -#define FT_PEEK_ULONG_LE( p ) FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \ - FT_BYTE_U32( p, 2, 16 ) | \ - FT_BYTE_U32( p, 1, 8 ) | \ - FT_BYTE_U32( p, 0, 0 ) ) - -#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_BYTE_U32( p, 2, 16 ) | \ - FT_BYTE_U32( p, 1, 8 ) | \ - FT_BYTE_U32( p, 0, 0 ) ) - -#define FT_PEEK_UOFF3_LE( p ) FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \ - FT_BYTE_U32( p, 1, 8 ) | \ - FT_BYTE_U32( p, 0, 0 ) ) - - -#define FT_NEXT_CHAR( buffer ) \ - ( (signed char)*buffer++ ) - -#define FT_NEXT_BYTE( buffer ) \ - ( (unsigned char)*buffer++ ) - -#define FT_NEXT_SHORT( buffer ) \ - ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) ) - -#define FT_NEXT_USHORT( buffer ) \ - ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) ) - -#define FT_NEXT_OFF3( buffer ) \ - ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) ) - -#define FT_NEXT_UOFF3( buffer ) \ - ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) ) - -#define FT_NEXT_LONG( buffer ) \ - ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) ) - -#define FT_NEXT_ULONG( buffer ) \ - ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) ) - - -#define FT_NEXT_SHORT_LE( buffer ) \ - ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) ) - -#define FT_NEXT_USHORT_LE( buffer ) \ - ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) ) - -#define FT_NEXT_OFF3_LE( buffer ) \ - ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) ) - -#define FT_NEXT_UOFF3_LE( buffer ) \ - ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) ) - -#define FT_NEXT_LONG_LE( buffer ) \ - ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) ) - -#define FT_NEXT_ULONG_LE( buffer ) \ - ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) ) - - - /*************************************************************************/ - /* */ - /* Each GET_xxxx() macro uses an implicit `stream' variable. */ - /* */ -#if 0 -#define FT_GET_MACRO( type ) FT_NEXT_ ## type ( stream->cursor ) - -#define FT_GET_CHAR() FT_GET_MACRO( CHAR ) -#define FT_GET_BYTE() FT_GET_MACRO( BYTE ) -#define FT_GET_SHORT() FT_GET_MACRO( SHORT ) -#define FT_GET_USHORT() FT_GET_MACRO( USHORT ) -#define FT_GET_OFF3() FT_GET_MACRO( OFF3 ) -#define FT_GET_UOFF3() FT_GET_MACRO( UOFF3 ) -#define FT_GET_LONG() FT_GET_MACRO( LONG ) -#define FT_GET_ULONG() FT_GET_MACRO( ULONG ) -#define FT_GET_TAG4() FT_GET_MACRO( ULONG ) - -#define FT_GET_SHORT_LE() FT_GET_MACRO( SHORT_LE ) -#define FT_GET_USHORT_LE() FT_GET_MACRO( USHORT_LE ) -#define FT_GET_LONG_LE() FT_GET_MACRO( LONG_LE ) -#define FT_GET_ULONG_LE() FT_GET_MACRO( ULONG_LE ) - -#else -#define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) - -#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char ) -#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte ) -#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_Short ) -#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort ) -#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_Long ) -#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong ) -#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetULong, FT_Long ) -#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong ) -#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong ) - -#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short ) -#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort ) -#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long ) -#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong ) -#endif - -#define FT_READ_MACRO( func, type, var ) \ - ( var = (type)func( stream, &error ), \ - error != FT_Err_Ok ) - -#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) -#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) -#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var ) -#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var ) -#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_Long, var ) -#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var ) -#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var ) -#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var ) - -#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Short, var ) -#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UShort, var ) -#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Long, var ) -#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_ULong, var ) - - -#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM - - /* initialize a stream for reading a regular system stream */ - FT_BASE( FT_Error ) - FT_Stream_Open( FT_Stream stream, - const char* filepathname ); - -#endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ - - - /* create a new (input) stream from an FT_Open_Args structure */ - FT_BASE( FT_Error ) - FT_Stream_New( FT_Library library, - const FT_Open_Args* args, - FT_Stream *astream ); - - /* free a stream */ - FT_BASE( void ) - FT_Stream_Free( FT_Stream stream, - FT_Int external ); - - /* initialize a stream for reading in-memory data */ - FT_BASE( void ) - FT_Stream_OpenMemory( FT_Stream stream, - const FT_Byte* base, - FT_ULong size ); - - /* close a stream (does not destroy the stream structure) */ - FT_BASE( void ) - FT_Stream_Close( FT_Stream stream ); - - - /* seek within a stream. position is relative to start of stream */ - FT_BASE( FT_Error ) - FT_Stream_Seek( FT_Stream stream, - FT_ULong pos ); - - /* skip bytes in a stream */ - FT_BASE( FT_Error ) - FT_Stream_Skip( FT_Stream stream, - FT_Long distance ); - - /* return current stream position */ - FT_BASE( FT_Long ) - FT_Stream_Pos( FT_Stream stream ); - - /* read bytes from a stream into a user-allocated buffer, returns an */ - /* error if not all bytes could be read. */ - FT_BASE( FT_Error ) - FT_Stream_Read( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ); - - /* read bytes from a stream at a given position */ - FT_BASE( FT_Error ) - FT_Stream_ReadAt( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ); - - /* try to read bytes at the end of a stream; return number of bytes */ - /* really available */ - FT_BASE( FT_ULong ) - FT_Stream_TryRead( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ); - - /* Enter a frame of `count' consecutive bytes in a stream. Returns an */ - /* error if the frame could not be read/accessed. The caller can use */ - /* the FT_Stream_Get_XXX functions to retrieve frame data without */ - /* error checks. */ - /* */ - /* You must _always_ call FT_Stream_ExitFrame() once you have entered */ - /* a stream frame! */ - /* */ - FT_BASE( FT_Error ) - FT_Stream_EnterFrame( FT_Stream stream, - FT_ULong count ); - - /* exit a stream frame */ - FT_BASE( void ) - FT_Stream_ExitFrame( FT_Stream stream ); - - /* Extract a stream frame. If the stream is disk-based, a heap block */ - /* is allocated and the frame bytes are read into it. If the stream */ - /* is memory-based, this function simply set a pointer to the data. */ - /* */ - /* Useful to optimize access to memory-based streams transparently. */ - /* */ - /* All extracted frames must be `freed' with a call to the function */ - /* FT_Stream_ReleaseFrame(). */ - /* */ - FT_BASE( FT_Error ) - FT_Stream_ExtractFrame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ); - - /* release an extract frame (see FT_Stream_ExtractFrame) */ - FT_BASE( void ) - FT_Stream_ReleaseFrame( FT_Stream stream, - FT_Byte** pbytes ); - - /* read a byte from an entered frame */ - FT_BASE( FT_Char ) - FT_Stream_GetChar( FT_Stream stream ); - - /* read a 16-bit big-endian unsigned integer from an entered frame */ - FT_BASE( FT_UShort ) - FT_Stream_GetUShort( FT_Stream stream ); - - /* read a 24-bit big-endian unsigned integer from an entered frame */ - FT_BASE( FT_ULong ) - FT_Stream_GetUOffset( FT_Stream stream ); - - /* read a 32-bit big-endian unsigned integer from an entered frame */ - FT_BASE( FT_ULong ) - FT_Stream_GetULong( FT_Stream stream ); - - /* read a 16-bit little-endian unsigned integer from an entered frame */ - FT_BASE( FT_UShort ) - FT_Stream_GetUShortLE( FT_Stream stream ); - - /* read a 32-bit little-endian unsigned integer from an entered frame */ - FT_BASE( FT_ULong ) - FT_Stream_GetULongLE( FT_Stream stream ); - - - /* read a byte from a stream */ - FT_BASE( FT_Char ) - FT_Stream_ReadChar( FT_Stream stream, - FT_Error* error ); - - /* read a 16-bit big-endian unsigned integer from a stream */ - FT_BASE( FT_UShort ) - FT_Stream_ReadUShort( FT_Stream stream, - FT_Error* error ); - - /* read a 24-bit big-endian unsigned integer from a stream */ - FT_BASE( FT_ULong ) - FT_Stream_ReadUOffset( FT_Stream stream, - FT_Error* error ); - - /* read a 32-bit big-endian integer from a stream */ - FT_BASE( FT_ULong ) - FT_Stream_ReadULong( FT_Stream stream, - FT_Error* error ); - - /* read a 16-bit little-endian unsigned integer from a stream */ - FT_BASE( FT_UShort ) - FT_Stream_ReadUShortLE( FT_Stream stream, - FT_Error* error ); - - /* read a 32-bit little-endian unsigned integer from a stream */ - FT_BASE( FT_ULong ) - FT_Stream_ReadULongLE( FT_Stream stream, - FT_Error* error ); - - /* Read a structure from a stream. The structure must be described */ - /* by an array of FT_Frame_Field records. */ - FT_BASE( FT_Error ) - FT_Stream_ReadFields( FT_Stream stream, - const FT_Frame_Field* fields, - void* structure ); - - -#define FT_STREAM_POS() \ - FT_Stream_Pos( stream ) - -#define FT_STREAM_SEEK( position ) \ - FT_SET_ERROR( FT_Stream_Seek( stream, \ - (FT_ULong)(position) ) ) - -#define FT_STREAM_SKIP( distance ) \ - FT_SET_ERROR( FT_Stream_Skip( stream, \ - (FT_Long)(distance) ) ) - -#define FT_STREAM_READ( buffer, count ) \ - FT_SET_ERROR( FT_Stream_Read( stream, \ - (FT_Byte*)(buffer), \ - (FT_ULong)(count) ) ) - -#define FT_STREAM_READ_AT( position, buffer, count ) \ - FT_SET_ERROR( FT_Stream_ReadAt( stream, \ - (FT_ULong)(position), \ - (FT_Byte*)buffer, \ - (FT_ULong)(count) ) ) - -#define FT_STREAM_READ_FIELDS( fields, object ) \ - FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) ) - - -#define FT_FRAME_ENTER( size ) \ - FT_SET_ERROR( \ - FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, \ - (FT_ULong)(size) ) ) ) - -#define FT_FRAME_EXIT() \ - FT_DEBUG_INNER( FT_Stream_ExitFrame( stream ) ) - -#define FT_FRAME_EXTRACT( size, bytes ) \ - FT_SET_ERROR( \ - FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, \ - (FT_ULong)(size), \ - (FT_Byte**)&(bytes) ) ) ) - -#define FT_FRAME_RELEASE( bytes ) \ - FT_DEBUG_INNER( FT_Stream_ReleaseFrame( stream, \ - (FT_Byte**)&(bytes) ) ) - - -FT_END_HEADER - -#endif /* __FTSTREAM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/fttrace.h b/drivers/freetype/freetype/include/freetype/internal/fttrace.h deleted file mode 100644 index a9d98b60aa..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/fttrace.h +++ /dev/null @@ -1,152 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttrace.h */ -/* */ -/* Tracing handling (specification only). */ -/* */ -/* Copyright 2002, 2004-2007, 2009, 2011-2013 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. */ -/* */ -/***************************************************************************/ - - - /* definitions of trace levels for FreeType 2 */ - - /* the first level must always be `trace_any' */ -FT_TRACE_DEF( any ) - - /* base components */ -FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ -FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ -FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ -FT_TRACE_DEF( io ) /* i/o interface (ftsystem.c) */ -FT_TRACE_DEF( list ) /* list management (ftlist.c) */ -FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ -FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ -FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ -FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ -FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ - -FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ -FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ -FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ -FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ -FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ -FT_TRACE_DEF( bitmap ) /* bitmap checksum (ftobjs.c) */ - - /* Cache sub-system */ -FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ - - /* SFNT driver components */ -FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ -FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ -FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ -FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ -FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ -FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ -FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ -FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ -FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ - - /* TrueType driver components */ -FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ -FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */ -FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */ -FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */ -FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ -FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ - - /* Type 1 driver components */ -FT_TRACE_DEF( t1afm ) -FT_TRACE_DEF( t1driver ) -FT_TRACE_DEF( t1gload ) -FT_TRACE_DEF( t1hint ) -FT_TRACE_DEF( t1load ) -FT_TRACE_DEF( t1objs ) -FT_TRACE_DEF( t1parse ) - - /* PostScript helper module `psaux' */ -FT_TRACE_DEF( t1decode ) -FT_TRACE_DEF( psobjs ) -FT_TRACE_DEF( psconv ) - - /* PostScript hinting module `pshinter' */ -FT_TRACE_DEF( pshrec ) -FT_TRACE_DEF( pshalgo1 ) -FT_TRACE_DEF( pshalgo2 ) - - /* Type 2 driver components */ -FT_TRACE_DEF( cffdriver ) -FT_TRACE_DEF( cffgload ) -FT_TRACE_DEF( cffload ) -FT_TRACE_DEF( cffobjs ) -FT_TRACE_DEF( cffparse ) - -FT_TRACE_DEF( cf2blues ) -FT_TRACE_DEF( cf2hints ) -FT_TRACE_DEF( cf2interp ) - - /* Type 42 driver component */ -FT_TRACE_DEF( t42 ) - - /* CID driver components */ -FT_TRACE_DEF( cidafm ) -FT_TRACE_DEF( ciddriver ) -FT_TRACE_DEF( cidgload ) -FT_TRACE_DEF( cidload ) -FT_TRACE_DEF( cidobjs ) -FT_TRACE_DEF( cidparse ) - - /* Windows font component */ -FT_TRACE_DEF( winfnt ) - - /* PCF font components */ -FT_TRACE_DEF( pcfdriver ) -FT_TRACE_DEF( pcfread ) - - /* BDF font components */ -FT_TRACE_DEF( bdfdriver ) -FT_TRACE_DEF( bdflib ) - - /* PFR font component */ -FT_TRACE_DEF( pfr ) - - /* OpenType validation components */ -FT_TRACE_DEF( otvmodule ) -FT_TRACE_DEF( otvcommon ) -FT_TRACE_DEF( otvbase ) -FT_TRACE_DEF( otvgdef ) -FT_TRACE_DEF( otvgpos ) -FT_TRACE_DEF( otvgsub ) -FT_TRACE_DEF( otvjstf ) -FT_TRACE_DEF( otvmath ) - - /* TrueTypeGX/AAT validation components */ -FT_TRACE_DEF( gxvmodule ) -FT_TRACE_DEF( gxvcommon ) -FT_TRACE_DEF( gxvfeat ) -FT_TRACE_DEF( gxvmort ) -FT_TRACE_DEF( gxvmorx ) -FT_TRACE_DEF( gxvbsln ) -FT_TRACE_DEF( gxvjust ) -FT_TRACE_DEF( gxvkern ) -FT_TRACE_DEF( gxvopbd ) -FT_TRACE_DEF( gxvtrak ) -FT_TRACE_DEF( gxvprop ) -FT_TRACE_DEF( gxvlcar ) - - /* autofit components */ -FT_TRACE_DEF( afmodule ) -FT_TRACE_DEF( afhints ) -FT_TRACE_DEF( afcjk ) -FT_TRACE_DEF( aflatin ) -FT_TRACE_DEF( aflatin2 ) -FT_TRACE_DEF( afwarp ) - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftvalid.h b/drivers/freetype/freetype/include/freetype/internal/ftvalid.h deleted file mode 100644 index 12ad03685a..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/ftvalid.h +++ /dev/null @@ -1,161 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftvalid.h */ -/* */ -/* FreeType validation support (specification). */ -/* */ -/* Copyright 2004, 2013 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 __FTVALID_H__ -#define __FTVALID_H__ - -#include <ft2build.h> -#include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** V A L I D A T I O N ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* handle to a validation object */ - typedef struct FT_ValidatorRec_ volatile* FT_Validator; - - - /*************************************************************************/ - /* */ - /* There are three distinct validation levels defined here: */ - /* */ - /* FT_VALIDATE_DEFAULT :: */ - /* A table that passes this validation level can be used reliably by */ - /* FreeType. It generally means that all offsets have been checked to */ - /* prevent out-of-bound reads, that array counts are correct, etc. */ - /* */ - /* FT_VALIDATE_TIGHT :: */ - /* A table that passes this validation level can be used reliably and */ - /* doesn't contain invalid data. For example, a charmap table that */ - /* returns invalid glyph indices will not pass, even though it can */ - /* be used with FreeType in default mode (the library will simply */ - /* return an error later when trying to load the glyph). */ - /* */ - /* It also checks that fields which must be a multiple of 2, 4, or 8, */ - /* don't have incorrect values, etc. */ - /* */ - /* FT_VALIDATE_PARANOID :: */ - /* Only for font debugging. Checks that a table follows the */ - /* specification by 100%. Very few fonts will be able to pass this */ - /* level anyway but it can be useful for certain tools like font */ - /* editors/converters. */ - /* */ - typedef enum FT_ValidationLevel_ - { - FT_VALIDATE_DEFAULT = 0, - FT_VALIDATE_TIGHT, - FT_VALIDATE_PARANOID - - } FT_ValidationLevel; - - -#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ - /* We disable the warning `structure was padded due to */ - /* __declspec(align())' in order to compile cleanly with */ - /* the maximum level of warnings. */ -#pragma warning( push ) -#pragma warning( disable : 4324 ) -#endif /* _MSC_VER */ - - /* validator structure */ - typedef struct FT_ValidatorRec_ - { - const FT_Byte* base; /* address of table in memory */ - const FT_Byte* limit; /* `base' + sizeof(table) in memory */ - FT_ValidationLevel level; /* validation level */ - FT_Error error; /* error returned. 0 means success */ - - ft_jmp_buf jump_buffer; /* used for exception handling */ - - } FT_ValidatorRec; - -#if defined( _MSC_VER ) -#pragma warning( pop ) -#endif - -#define FT_VALIDATOR( x ) ( (FT_Validator)( x ) ) - - - FT_BASE( void ) - ft_validator_init( FT_Validator valid, - const FT_Byte* base, - 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 ); - - /* Sets the error field in a validator, then calls `longjmp' to return */ - /* to high-level caller. Using `setjmp/longjmp' avoids many stupid */ - /* error checks within the validation routines. */ - /* */ - FT_BASE( void ) - ft_validator_error( FT_Validator valid, - FT_Error error ); - - - /* Calls ft_validate_error. Assumes that the `valid' local variable */ - /* holds a pointer to the current validator object. */ - /* */ - /* Use preprocessor prescan to pass FT_ERR_PREFIX. */ - /* */ -#define FT_INVALID( _prefix, _error ) FT_INVALID_( _prefix, _error ) -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid, _prefix ## _error ) - - /* called when a broken table is detected */ -#define FT_INVALID_TOO_SHORT \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) - - /* called when an invalid offset is detected */ -#define FT_INVALID_OFFSET \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Offset ) - - /* called when an invalid format/value is detected */ -#define FT_INVALID_FORMAT \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) - - /* called when an invalid glyph index is detected */ -#define FT_INVALID_GLYPH_ID \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index ) - - /* called when an invalid field value is detected */ -#define FT_INVALID_DATA \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) - - -FT_END_HEADER - -#endif /* __FTVALID_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/internal.h b/drivers/freetype/freetype/include/freetype/internal/internal.h deleted file mode 100644 index 262afcfa8a..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/internal.h +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************/ -/* */ -/* internal.h */ -/* */ -/* Internal header files (specification only). */ -/* */ -/* Copyright 1996-2004, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is automatically included by `ft2build.h'. */ - /* Do not include it manually! */ - /* */ - /*************************************************************************/ - - -#define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> -#define FT_INTERNAL_PIC_H <freetype/internal/ftpic.h> -#define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> -#define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> -#define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> -#define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> -#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> -#define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> -#define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> -#define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> -#define FT_INTERNAL_SERVICE_H <freetype/internal/ftserv.h> -#define FT_INTERNAL_RFORK_H <freetype/internal/ftrfork.h> -#define FT_INTERNAL_VALIDATE_H <freetype/internal/ftvalid.h> - -#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> -#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> - -#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> -#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> -#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> - -#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> - - -#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ - - /* We disable the warning `conditional expression is constant' here */ - /* in order to compile cleanly with the maximum level of warnings. */ - /* In particular, the warning complains about stuff like `while(0)' */ - /* which is very useful in macro definitions. There is no benefit */ - /* in having it enabled. */ -#pragma warning( disable : 4127 ) - -#endif /* _MSC_VER */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/psaux.h b/drivers/freetype/freetype/include/freetype/internal/psaux.h deleted file mode 100644 index e903114f84..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/psaux.h +++ /dev/null @@ -1,877 +0,0 @@ -/***************************************************************************/ -/* */ -/* psaux.h */ -/* */ -/* Auxiliary functions and data structures related to PostScript fonts */ -/* (specification). */ -/* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2012 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 __PSAUX_H__ -#define __PSAUX_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_TYPE1_TYPES_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1_TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - typedef struct PS_TableRec_* PS_Table; - typedef const struct PS_Table_FuncsRec_* PS_Table_Funcs; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_Table_FuncsRec */ - /* */ - /* <Description> */ - /* A set of function pointers to manage PS_Table objects. */ - /* */ - /* <Fields> */ - /* table_init :: Used to initialize a table. */ - /* */ - /* table_done :: Finalizes resp. destroy a given table. */ - /* */ - /* table_add :: Adds a new object to a table. */ - /* */ - /* table_release :: Releases table data, then finalizes it. */ - /* */ - typedef struct PS_Table_FuncsRec_ - { - FT_Error - (*init)( PS_Table table, - FT_Int count, - FT_Memory memory ); - - void - (*done)( PS_Table table ); - - FT_Error - (*add)( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ); - - void - (*release)( PS_Table table ); - - } PS_Table_FuncsRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_TableRec */ - /* */ - /* <Description> */ - /* A PS_Table is a simple object used to store an array of objects in */ - /* a single memory block. */ - /* */ - /* <Fields> */ - /* block :: The address in memory of the growheap's block. This */ - /* can change between two object adds, due to */ - /* reallocation. */ - /* */ - /* cursor :: The current top of the grow heap within its block. */ - /* */ - /* capacity :: The current size of the heap block. Increments by */ - /* 1kByte chunks. */ - /* */ - /* init :: Set to 0xDEADBEEF if `elements' and `lengths' have */ - /* been allocated. */ - /* */ - /* max_elems :: The maximum number of elements in table. */ - /* */ - /* num_elems :: The current number of elements in table. */ - /* */ - /* elements :: A table of element addresses within the block. */ - /* */ - /* lengths :: A table of element sizes within the block. */ - /* */ - /* memory :: The object used for memory operations */ - /* (alloc/realloc). */ - /* */ - /* funcs :: A table of method pointers for this object. */ - /* */ - typedef struct PS_TableRec_ - { - FT_Byte* block; /* current memory block */ - FT_Offset cursor; /* current cursor in memory block */ - FT_Offset capacity; /* current size of memory block */ - FT_Long init; - - FT_Int max_elems; - FT_Int num_elems; - FT_Byte** elements; /* addresses of table elements */ - FT_PtrDist* lengths; /* lengths of table elements */ - - FT_Memory memory; - PS_Table_FuncsRec funcs; - - } PS_TableRec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1 FIELDS & TOKENS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct PS_ParserRec_* PS_Parser; - - typedef struct T1_TokenRec_* T1_Token; - - typedef struct T1_FieldRec_* T1_Field; - - - /* simple enumeration type used to identify token types */ - typedef enum T1_TokenType_ - { - T1_TOKEN_TYPE_NONE = 0, - 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 - - } T1_TokenType; - - - /* a simple structure used to identify tokens */ - typedef struct T1_TokenRec_ - { - FT_Byte* start; /* first character of token in input stream */ - FT_Byte* limit; /* first character after the token */ - T1_TokenType type; /* type of token */ - - } T1_TokenRec; - - - /* enumeration type used to identify object fields */ - typedef enum T1_FieldType_ - { - T1_FIELD_TYPE_NONE = 0, - T1_FIELD_TYPE_BOOL, - T1_FIELD_TYPE_INTEGER, - T1_FIELD_TYPE_FIXED, - T1_FIELD_TYPE_FIXED_1000, - T1_FIELD_TYPE_STRING, - T1_FIELD_TYPE_KEY, - T1_FIELD_TYPE_BBOX, - T1_FIELD_TYPE_MM_BBOX, - T1_FIELD_TYPE_INTEGER_ARRAY, - T1_FIELD_TYPE_FIXED_ARRAY, - T1_FIELD_TYPE_CALLBACK, - - /* do not remove */ - T1_FIELD_TYPE_MAX - - } T1_FieldType; - - - typedef enum T1_FieldLocation_ - { - T1_FIELD_LOCATION_CID_INFO, - T1_FIELD_LOCATION_FONT_DICT, - T1_FIELD_LOCATION_FONT_EXTRA, - 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 - - } T1_FieldLocation; - - - typedef void - (*T1_Field_ParseFunc)( FT_Face face, - FT_Pointer parser ); - - - /* structure type used to model object fields */ - typedef struct T1_FieldRec_ - { - const char* ident; /* field identifier */ - T1_FieldLocation location; - T1_FieldType type; /* type of field */ - T1_Field_ParseFunc reader; - FT_UInt offset; /* offset of field in object */ - FT_Byte size; /* size of field in bytes */ - FT_UInt array_max; /* maximum number of elements for */ - /* array */ - FT_UInt count_offset; /* offset of element count for */ - /* arrays; must not be zero if in */ - /* use -- in other words, a */ - /* `num_FOO' element must not */ - /* start the used structure if we */ - /* parse a `FOO' array */ - 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, _dict ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE( _fname ), \ - 0, 0, \ - _dict \ - }, - -#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, _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, _dict ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _max, 0, \ - _dict \ - }, - - -#define T1_FIELD_BOOL( _ident, _fname, _dict ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict ) - -#define T1_FIELD_NUM( _ident, _fname, _dict ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict ) - -#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, _dict ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \ - _dict ) - -#define T1_FIELD_STRING( _ident, _fname, _dict ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict ) - -#define T1_FIELD_KEY( _ident, _fname, _dict ) \ - T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict ) - -#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, _dict ) \ - T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ - _fname, _fmax, _dict ) - -#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict ) \ - T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ - _fname, _fmax, _dict ) - -#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict ) \ - T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ - _fname, _fmax, _dict ) - -#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict ) \ - T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ - _fname, _fmax, _dict ) - -#define T1_FIELD_CALLBACK( _ident, _name, _dict ) \ - T1_NEW_CALLBACK_FIELD( _ident, _name, _dict ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1 PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef const struct PS_Parser_FuncsRec_* PS_Parser_Funcs; - - typedef struct PS_Parser_FuncsRec_ - { - void - (*init)( PS_Parser parser, - FT_Byte* base, - FT_Byte* limit, - FT_Memory memory ); - - void - (*done)( PS_Parser parser ); - - void - (*skip_spaces)( PS_Parser parser ); - void - (*skip_PS_token)( PS_Parser parser ); - - FT_Long - (*to_int)( PS_Parser parser ); - FT_Fixed - (*to_fixed)( PS_Parser parser, - FT_Int power_ten ); - - FT_Error - (*to_bytes)( PS_Parser parser, - FT_Byte* bytes, - FT_Offset max_bytes, - FT_Long* pnum_bytes, - FT_Bool delimiters ); - - FT_Int - (*to_coord_array)( PS_Parser parser, - FT_Int max_coords, - FT_Short* coords ); - FT_Int - (*to_fixed_array)( PS_Parser parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ); - - void - (*to_token)( PS_Parser parser, - T1_Token token ); - void - (*to_token_array)( PS_Parser parser, - T1_Token tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ); - - FT_Error - (*load_field)( PS_Parser parser, - const T1_Field field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ); - - FT_Error - (*load_field_table)( PS_Parser parser, - const T1_Field field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ); - - } PS_Parser_FuncsRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_ParserRec */ - /* */ - /* <Description> */ - /* A PS_Parser is an object used to parse a Type 1 font very quickly. */ - /* */ - /* <Fields> */ - /* cursor :: The current position in the text. */ - /* */ - /* base :: Start of the processed text. */ - /* */ - /* limit :: End of the processed text. */ - /* */ - /* error :: The last error returned. */ - /* */ - /* memory :: The object used for memory operations (alloc/realloc). */ - /* */ - /* funcs :: A table of functions for the parser. */ - /* */ - typedef struct PS_ParserRec_ - { - FT_Byte* cursor; - FT_Byte* base; - FT_Byte* limit; - FT_Error error; - FT_Memory memory; - - PS_Parser_FuncsRec funcs; - - } PS_ParserRec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1 BUILDER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - typedef struct T1_BuilderRec_* T1_Builder; - - - typedef FT_Error - (*T1_Builder_Check_Points_Func)( T1_Builder builder, - FT_Int count ); - - typedef void - (*T1_Builder_Add_Point_Func)( T1_Builder builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ); - - typedef FT_Error - (*T1_Builder_Add_Point1_Func)( T1_Builder builder, - FT_Pos x, - FT_Pos y ); - - typedef FT_Error - (*T1_Builder_Add_Contour_Func)( T1_Builder builder ); - - typedef FT_Error - (*T1_Builder_Start_Point_Func)( T1_Builder builder, - FT_Pos x, - FT_Pos y ); - - typedef void - (*T1_Builder_Close_Contour_Func)( T1_Builder builder ); - - - typedef const struct T1_Builder_FuncsRec_* T1_Builder_Funcs; - - typedef struct T1_Builder_FuncsRec_ - { - void - (*init)( T1_Builder builder, - FT_Face face, - FT_Size size, - FT_GlyphSlot slot, - FT_Bool hinting ); - - void - (*done)( T1_Builder builder ); - - T1_Builder_Check_Points_Func check_points; - T1_Builder_Add_Point_Func add_point; - T1_Builder_Add_Point1_Func add_point1; - T1_Builder_Add_Contour_Func add_contour; - T1_Builder_Start_Point_Func start_point; - T1_Builder_Close_Contour_Func close_contour; - - } T1_Builder_FuncsRec; - - - /* an enumeration type to handle charstring parsing states */ - typedef enum T1_ParseState_ - { - T1_Parse_Start, - T1_Parse_Have_Width, - T1_Parse_Have_Moveto, - T1_Parse_Have_Path - - } T1_ParseState; - - - /*************************************************************************/ - /* */ - /* <Structure> */ - /* T1_BuilderRec */ - /* */ - /* <Description> */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* <Fields> */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: XXX */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* max_points :: maximum points in builder outline */ - /* */ - /* max_contours :: Maximum number of contours in builder outline. */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* parse_state :: An enumeration which controls the charstring */ - /* parsing state. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - /* funcs :: An array of function pointers for the builder. */ - /* */ - typedef struct T1_BuilderRec_ - { - FT_Memory memory; - FT_Face face; - FT_GlyphSlot glyph; - FT_GlyphLoader loader; - FT_Outline* base; - FT_Outline* current; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - T1_ParseState parse_state; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Bool metrics_only; - - void* hints_funcs; /* hinter-specific */ - void* hints_globals; /* hinter-specific */ - - T1_Builder_FuncsRec funcs; - - } T1_BuilderRec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1 DECODER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#if 0 - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 8 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 32 - -#endif /* 0 */ - - - typedef struct T1_Decoder_ZoneRec_ - { - FT_Byte* cursor; - FT_Byte* base; - FT_Byte* limit; - - } T1_Decoder_ZoneRec, *T1_Decoder_Zone; - - - typedef struct T1_DecoderRec_* T1_Decoder; - typedef const struct T1_Decoder_FuncsRec_* T1_Decoder_Funcs; - - - typedef FT_Error - (*T1_Decoder_Callback)( T1_Decoder decoder, - FT_UInt glyph_index ); - - - typedef struct T1_Decoder_FuncsRec_ - { - FT_Error - (*init)( T1_Decoder decoder, - FT_Face face, - FT_Size size, - FT_GlyphSlot slot, - FT_Byte** glyph_names, - PS_Blend blend, - FT_Bool hinting, - FT_Render_Mode hint_mode, - T1_Decoder_Callback callback ); - - void - (*done)( T1_Decoder decoder ); - - FT_Error - (*parse_charstrings)( T1_Decoder decoder, - FT_Byte* base, - FT_UInt len ); - - } T1_Decoder_FuncsRec; - - - typedef struct T1_DecoderRec_ - { - T1_BuilderRec builder; - - FT_Long stack[T1_MAX_CHARSTRINGS_OPERANDS]; - FT_Long* top; - - T1_Decoder_ZoneRec zones[T1_MAX_SUBRS_CALLS + 1]; - T1_Decoder_Zone zone; - - FT_Service_PsCMaps psnames; /* for seac */ - FT_UInt num_glyphs; - FT_Byte** glyph_names; - - FT_Int lenIV; /* internal for sub routine calls */ - FT_UInt num_subrs; - FT_Byte** subrs; - FT_PtrDist* subrs_len; /* array of subrs length (optional) */ - - FT_Matrix font_matrix; - FT_Vector font_offset; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - PS_Blend blend; /* for multiple master support */ - - FT_Render_Mode hint_mode; - - T1_Decoder_Callback parse_callback; - T1_Decoder_FuncsRec funcs; - - FT_Long* buildchar; - FT_UInt len_buildchar; - - FT_Bool seac; - - } T1_DecoderRec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** AFM PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct AFM_ParserRec_* AFM_Parser; - - typedef struct AFM_Parser_FuncsRec_ - { - FT_Error - (*init)( AFM_Parser parser, - FT_Memory memory, - FT_Byte* base, - FT_Byte* limit ); - - void - (*done)( AFM_Parser parser ); - - FT_Error - (*parse)( AFM_Parser parser ); - - } AFM_Parser_FuncsRec; - - - typedef struct AFM_StreamRec_* AFM_Stream; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* AFM_ParserRec */ - /* */ - /* <Description> */ - /* An AFM_Parser is a parser for the AFM files. */ - /* */ - /* <Fields> */ - /* memory :: The object used for memory operations (alloc and */ - /* realloc). */ - /* */ - /* stream :: This is an opaque object. */ - /* */ - /* FontInfo :: The result will be stored here. */ - /* */ - /* get_index :: A user provided function to get a glyph index by its */ - /* name. */ - /* */ - typedef struct AFM_ParserRec_ - { - FT_Memory memory; - AFM_Stream stream; - - AFM_FontInfo FontInfo; - - FT_Int - (*get_index)( const char* name, - FT_Offset len, - void* user_data ); - - void* user_data; - - } AFM_ParserRec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE1 CHARMAPS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef const struct T1_CMap_ClassesRec_* T1_CMap_Classes; - - typedef struct T1_CMap_ClassesRec_ - { - FT_CMap_Class standard; - FT_CMap_Class expert; - FT_CMap_Class custom; - FT_CMap_Class unicode; - - } T1_CMap_ClassesRec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PSAux Module Interface *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct PSAux_ServiceRec_ - { - /* don't use `PS_Table_Funcs' and friends to avoid compiler warnings */ - const PS_Table_FuncsRec* ps_table_funcs; - const PS_Parser_FuncsRec* ps_parser_funcs; - const T1_Builder_FuncsRec* t1_builder_funcs; - const T1_Decoder_FuncsRec* t1_decoder_funcs; - - void - (*t1_decrypt)( FT_Byte* buffer, - FT_Offset length, - FT_UShort seed ); - - T1_CMap_Classes t1_cmap_classes; - - /* fields after this comment line were added after version 2.1.10 */ - const AFM_Parser_FuncsRec* afm_parser_funcs; - - } PSAux_ServiceRec, *PSAux_Service; - - /* 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__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/pshints.h b/drivers/freetype/freetype/include/freetype/internal/pshints.h deleted file mode 100644 index 3fb18dc2d5..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/pshints.h +++ /dev/null @@ -1,722 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshints.h */ -/* */ -/* Interface to Postscript-specific (Type 1 and Type 2) hints */ -/* recorders (specification only). These are used to support native */ -/* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ -/* */ -/* Copyright 2001-2003, 2005-2007, 2009, 2012 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 __PSHINTS_H__ -#define __PSHINTS_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_TYPE1_TABLES_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** INTERNAL REPRESENTATION OF GLOBALS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct PSH_GlobalsRec_* PSH_Globals; - - typedef FT_Error - (*PSH_Globals_NewFunc)( FT_Memory memory, - T1_Private* private_dict, - PSH_Globals* aglobals ); - - typedef FT_Error - (*PSH_Globals_SetScaleFunc)( PSH_Globals globals, - FT_Fixed x_scale, - FT_Fixed y_scale, - FT_Fixed x_delta, - FT_Fixed y_delta ); - - typedef void - (*PSH_Globals_DestroyFunc)( PSH_Globals globals ); - - - typedef struct PSH_Globals_FuncsRec_ - { - PSH_Globals_NewFunc create; - PSH_Globals_SetScaleFunc set_scale; - PSH_Globals_DestroyFunc destroy; - - } PSH_Globals_FuncsRec, *PSH_Globals_Funcs; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PUBLIC TYPE 1 HINTS RECORDER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /************************************************************************* - * - * @type: - * T1_Hints - * - * @description: - * This is a handle to an opaque structure used to record glyph hints - * from a Type 1 character glyph character string. - * - * The methods used to operate on this object are defined by the - * @T1_Hints_FuncsRec structure. Recording glyph hints is normally - * achieved through the following scheme: - * - * - Open a new hint recording session by calling the `open' method. - * This rewinds the recorder and prepare it for new input. - * - * - For each hint found in the glyph charstring, call the corresponding - * method (`stem', `stem3', or `reset'). Note that these functions do - * not return an error code. - * - * - Close the recording session by calling the `close' method. It - * returns an error code if the hints were invalid or something - * strange happened (e.g., memory shortage). - * - * The hints accumulated in the object can later be used by the - * PostScript hinter. - * - */ - typedef struct T1_HintsRec_* T1_Hints; - - - /************************************************************************* - * - * @type: - * T1_Hints_Funcs - * - * @description: - * A pointer to the @T1_Hints_FuncsRec structure that defines the API of - * a given @T1_Hints object. - * - */ - typedef const struct T1_Hints_FuncsRec_* T1_Hints_Funcs; - - - /************************************************************************* - * - * @functype: - * T1_Hints_OpenFunc - * - * @description: - * A method of the @T1_Hints class used to prepare it for a new Type 1 - * hints recording session. - * - * @input: - * hints :: - * A handle to the Type 1 hints recorder. - * - * @note: - * You should always call the @T1_Hints_CloseFunc method in order to - * close an opened recording session. - * - */ - typedef void - (*T1_Hints_OpenFunc)( T1_Hints hints ); - - - /************************************************************************* - * - * @functype: - * T1_Hints_SetStemFunc - * - * @description: - * A method of the @T1_Hints class used to record a new horizontal or - * vertical stem. This corresponds to the Type 1 `hstem' and `vstem' - * operators. - * - * @input: - * hints :: - * A handle to the Type 1 hints recorder. - * - * dimension :: - * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). - * - * coords :: - * Array of 2 coordinates in 16.16 format, used as (position,length) - * stem descriptor. - * - * @note: - * Use vertical coordinates (y) for horizontal stems (dim=0). Use - * horizontal coordinates (x) for vertical stems (dim=1). - * - * `coords[0]' is the absolute stem position (lowest coordinate); - * `coords[1]' is the length. - * - * The length can be negative, in which case it must be either -20 or - * -21. It is interpreted as a `ghost' stem, according to the Type 1 - * specification. - * - * If the length is -21 (corresponding to a bottom ghost stem), then - * the real stem position is `coords[0]+coords[1]'. - * - */ - typedef void - (*T1_Hints_SetStemFunc)( T1_Hints hints, - FT_UInt dimension, - FT_Fixed* coords ); - - - /************************************************************************* - * - * @functype: - * T1_Hints_SetStem3Func - * - * @description: - * A method of the @T1_Hints class used to record three - * counter-controlled horizontal or vertical stems at once. - * - * @input: - * hints :: - * A handle to the Type 1 hints recorder. - * - * dimension :: - * 0 for horizontal stems, 1 for vertical ones. - * - * coords :: - * An array of 6 values in 16.16 format, holding 3 (position,length) - * pairs for the counter-controlled stems. - * - * @note: - * Use vertical coordinates (y) for horizontal stems (dim=0). Use - * horizontal coordinates (x) for vertical stems (dim=1). - * - * The lengths cannot be negative (ghost stems are never - * counter-controlled). - * - */ - typedef void - (*T1_Hints_SetStem3Func)( T1_Hints hints, - FT_UInt dimension, - FT_Fixed* coords ); - - - /************************************************************************* - * - * @functype: - * T1_Hints_ResetFunc - * - * @description: - * A method of the @T1_Hints class used to reset the stems hints in a - * recording session. - * - * @input: - * hints :: - * A handle to the Type 1 hints recorder. - * - * end_point :: - * The index of the last point in the input glyph in which the - * previously defined hints apply. - * - */ - typedef void - (*T1_Hints_ResetFunc)( T1_Hints hints, - FT_UInt end_point ); - - - /************************************************************************* - * - * @functype: - * T1_Hints_CloseFunc - * - * @description: - * A method of the @T1_Hints class used to close a hint recording - * session. - * - * @input: - * hints :: - * A handle to the Type 1 hints recorder. - * - * end_point :: - * The index of the last point in the input glyph. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * The error code is set to indicate that an error occurred during the - * recording session. - * - */ - typedef FT_Error - (*T1_Hints_CloseFunc)( T1_Hints hints, - FT_UInt end_point ); - - - /************************************************************************* - * - * @functype: - * T1_Hints_ApplyFunc - * - * @description: - * A method of the @T1_Hints class used to apply hints to the - * corresponding glyph outline. Must be called once all hints have been - * recorded. - * - * @input: - * hints :: - * A handle to the Type 1 hints recorder. - * - * outline :: - * A pointer to the target outline descriptor. - * - * globals :: - * The hinter globals for this font. - * - * hint_mode :: - * Hinting information. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * On input, all points within the outline are in font coordinates. On - * output, they are in 1/64th of pixels. - * - * The scaling transformation is taken from the `globals' object which - * must correspond to the same font as the glyph. - * - */ - typedef FT_Error - (*T1_Hints_ApplyFunc)( T1_Hints hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ); - - - /************************************************************************* - * - * @struct: - * T1_Hints_FuncsRec - * - * @description: - * The structure used to provide the API to @T1_Hints objects. - * - * @fields: - * hints :: - * A handle to the T1 Hints recorder. - * - * open :: - * The function to open a recording session. - * - * close :: - * The function to close a recording session. - * - * stem :: - * The function to set a simple stem. - * - * stem3 :: - * The function to set counter-controlled stems. - * - * reset :: - * The function to reset stem hints. - * - * apply :: - * The function to apply the hints to the corresponding glyph outline. - * - */ - typedef struct T1_Hints_FuncsRec_ - { - T1_Hints hints; - T1_Hints_OpenFunc open; - T1_Hints_CloseFunc close; - T1_Hints_SetStemFunc stem; - T1_Hints_SetStem3Func stem3; - T1_Hints_ResetFunc reset; - T1_Hints_ApplyFunc apply; - - } T1_Hints_FuncsRec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PUBLIC TYPE 2 HINTS RECORDER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /************************************************************************* - * - * @type: - * T2_Hints - * - * @description: - * This is a handle to an opaque structure used to record glyph hints - * from a Type 2 character glyph character string. - * - * The methods used to operate on this object are defined by the - * @T2_Hints_FuncsRec structure. Recording glyph hints is normally - * achieved through the following scheme: - * - * - Open a new hint recording session by calling the `open' method. - * This rewinds the recorder and prepare it for new input. - * - * - For each hint found in the glyph charstring, call the corresponding - * method (`stems', `hintmask', `counters'). Note that these - * functions do not return an error code. - * - * - Close the recording session by calling the `close' method. It - * returns an error code if the hints were invalid or something - * strange happened (e.g., memory shortage). - * - * The hints accumulated in the object can later be used by the - * Postscript hinter. - * - */ - typedef struct T2_HintsRec_* T2_Hints; - - - /************************************************************************* - * - * @type: - * T2_Hints_Funcs - * - * @description: - * A pointer to the @T2_Hints_FuncsRec structure that defines the API of - * a given @T2_Hints object. - * - */ - typedef const struct T2_Hints_FuncsRec_* T2_Hints_Funcs; - - - /************************************************************************* - * - * @functype: - * T2_Hints_OpenFunc - * - * @description: - * A method of the @T2_Hints class used to prepare it for a new Type 2 - * hints recording session. - * - * @input: - * hints :: - * A handle to the Type 2 hints recorder. - * - * @note: - * You should always call the @T2_Hints_CloseFunc method in order to - * close an opened recording session. - * - */ - typedef void - (*T2_Hints_OpenFunc)( T2_Hints hints ); - - - /************************************************************************* - * - * @functype: - * T2_Hints_StemsFunc - * - * @description: - * A method of the @T2_Hints class used to set the table of stems in - * either the vertical or horizontal dimension. Equivalent to the - * `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators. - * - * @input: - * hints :: - * A handle to the Type 2 hints recorder. - * - * dimension :: - * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). - * - * count :: - * The number of stems. - * - * coords :: - * An array of `count' (position,length) pairs in 16.16 format. - * - * @note: - * Use vertical coordinates (y) for horizontal stems (dim=0). Use - * horizontal coordinates (x) for vertical stems (dim=1). - * - * There are `2*count' elements in the `coords' array. Each even - * element is an absolute position in font units, each odd element is a - * length in font units. - * - * A length can be negative, in which case it must be either -20 or - * -21. It is interpreted as a `ghost' stem, according to the Type 1 - * specification. - * - */ - typedef void - (*T2_Hints_StemsFunc)( T2_Hints hints, - FT_UInt dimension, - FT_UInt count, - FT_Fixed* coordinates ); - - - /************************************************************************* - * - * @functype: - * T2_Hints_MaskFunc - * - * @description: - * A method of the @T2_Hints class used to set a given hintmask (this - * corresponds to the `hintmask' Type 2 operator). - * - * @input: - * hints :: - * A handle to the Type 2 hints recorder. - * - * end_point :: - * The glyph index of the last point to which the previously defined - * or activated hints apply. - * - * bit_count :: - * The number of bits in the hint mask. - * - * bytes :: - * An array of bytes modelling the hint mask. - * - * @note: - * If the hintmask starts the charstring (before any glyph point - * definition), the value of `end_point' should be 0. - * - * `bit_count' is the number of meaningful bits in the `bytes' array; it - * must be equal to the total number of hints defined so far (i.e., - * horizontal+verticals). - * - * The `bytes' array can come directly from the Type 2 charstring and - * respects the same format. - * - */ - typedef void - (*T2_Hints_MaskFunc)( T2_Hints hints, - FT_UInt end_point, - FT_UInt bit_count, - const FT_Byte* bytes ); - - - /************************************************************************* - * - * @functype: - * T2_Hints_CounterFunc - * - * @description: - * A method of the @T2_Hints class used to set a given counter mask - * (this corresponds to the `hintmask' Type 2 operator). - * - * @input: - * hints :: - * A handle to the Type 2 hints recorder. - * - * end_point :: - * A glyph index of the last point to which the previously defined or - * active hints apply. - * - * bit_count :: - * The number of bits in the hint mask. - * - * bytes :: - * An array of bytes modelling the hint mask. - * - * @note: - * If the hintmask starts the charstring (before any glyph point - * definition), the value of `end_point' should be 0. - * - * `bit_count' is the number of meaningful bits in the `bytes' array; it - * must be equal to the total number of hints defined so far (i.e., - * horizontal+verticals). - * - * The `bytes' array can come directly from the Type 2 charstring and - * respects the same format. - * - */ - typedef void - (*T2_Hints_CounterFunc)( T2_Hints hints, - FT_UInt bit_count, - const FT_Byte* bytes ); - - - /************************************************************************* - * - * @functype: - * T2_Hints_CloseFunc - * - * @description: - * A method of the @T2_Hints class used to close a hint recording - * session. - * - * @input: - * hints :: - * A handle to the Type 2 hints recorder. - * - * end_point :: - * The index of the last point in the input glyph. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * The error code is set to indicate that an error occurred during the - * recording session. - * - */ - typedef FT_Error - (*T2_Hints_CloseFunc)( T2_Hints hints, - FT_UInt end_point ); - - - /************************************************************************* - * - * @functype: - * T2_Hints_ApplyFunc - * - * @description: - * A method of the @T2_Hints class used to apply hints to the - * corresponding glyph outline. Must be called after the `close' - * method. - * - * @input: - * hints :: - * A handle to the Type 2 hints recorder. - * - * outline :: - * A pointer to the target outline descriptor. - * - * globals :: - * The hinter globals for this font. - * - * hint_mode :: - * Hinting information. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * On input, all points within the outline are in font coordinates. On - * output, they are in 1/64th of pixels. - * - * The scaling transformation is taken from the `globals' object which - * must correspond to the same font than the glyph. - * - */ - typedef FT_Error - (*T2_Hints_ApplyFunc)( T2_Hints hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ); - - - /************************************************************************* - * - * @struct: - * T2_Hints_FuncsRec - * - * @description: - * The structure used to provide the API to @T2_Hints objects. - * - * @fields: - * hints :: - * A handle to the T2 hints recorder object. - * - * open :: - * The function to open a recording session. - * - * close :: - * The function to close a recording session. - * - * stems :: - * The function to set the dimension's stems table. - * - * hintmask :: - * The function to set hint masks. - * - * counter :: - * The function to set counter masks. - * - * apply :: - * The function to apply the hints on the corresponding glyph outline. - * - */ - typedef struct T2_Hints_FuncsRec_ - { - T2_Hints hints; - T2_Hints_OpenFunc open; - T2_Hints_CloseFunc close; - T2_Hints_StemsFunc stems; - T2_Hints_MaskFunc hintmask; - T2_Hints_CounterFunc counter; - T2_Hints_ApplyFunc apply; - - } T2_Hints_FuncsRec; - - - /* */ - - - typedef struct PSHinter_Interface_ - { - PSH_Globals_Funcs (*get_globals_funcs)( FT_Module module ); - T1_Hints_Funcs (*get_t1_funcs) ( FT_Module module ); - T2_Hints_Funcs (*get_t2_funcs) ( FT_Module module ); - - } PSHinter_Interface; - - typedef PSHinter_Interface* PSHinter_Service; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_PSHINTER_INTERFACE( \ - class_, \ - get_globals_funcs_, \ - get_t1_funcs_, \ - get_t2_funcs_ ) \ - static const PSHinter_Interface class_ = \ - { \ - get_globals_funcs_, \ - get_t1_funcs_, \ - get_t2_funcs_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_PSHINTER_INTERFACE( \ - class_, \ - get_globals_funcs_, \ - get_t1_funcs_, \ - get_t2_funcs_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - PSHinter_Interface* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_globals_funcs = get_globals_funcs_; \ - clazz->get_t1_funcs = get_t1_funcs_; \ - clazz->get_t2_funcs = get_t2_funcs_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - -FT_END_HEADER - -#endif /* __PSHINTS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svbdf.h b/drivers/freetype/freetype/include/freetype/internal/services/svbdf.h deleted file mode 100644 index 0974752a79..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svbdf.h +++ /dev/null @@ -1,82 +0,0 @@ -/***************************************************************************/ -/* */ -/* svbdf.h */ -/* */ -/* The FreeType BDF services (specification). */ -/* */ -/* Copyright 2003, 2009, 2012 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 __SVBDF_H__ -#define __SVBDF_H__ - -#include FT_BDF_H -#include FT_INTERNAL_SERVICE_H - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_BDF "bdf" - - typedef FT_Error - (*FT_BDF_GetCharsetIdFunc)( FT_Face face, - const char* *acharset_encoding, - const char* *acharset_registry ); - - typedef FT_Error - (*FT_BDF_GetPropertyFunc)( FT_Face face, - const char* prop_name, - BDF_PropertyRec *aproperty ); - - - FT_DEFINE_SERVICE( BDF ) - { - FT_BDF_GetCharsetIdFunc get_charset_id; - FT_BDF_GetPropertyFunc get_property; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_BDFRec( class_, \ - get_charset_id_, \ - get_property_ ) \ - static const FT_Service_BDFRec class_ = \ - { \ - get_charset_id_, get_property_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_BDFRec( class_, \ - get_charset_id_, \ - get_property_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_BDFRec* clazz ) \ - { \ - clazz->get_charset_id = get_charset_id_; \ - clazz->get_property = get_property_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - - -#endif /* __SVBDF_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svcid.h b/drivers/freetype/freetype/include/freetype/internal/services/svcid.h deleted file mode 100644 index 6be3f9374d..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svcid.h +++ /dev/null @@ -1,89 +0,0 @@ -/***************************************************************************/ -/* */ -/* svcid.h */ -/* */ -/* The FreeType CID font services (specification). */ -/* */ -/* Copyright 2007, 2009, 2012 by Derek Clegg, Michael Toftdal. */ -/* */ -/* 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 __SVCID_H__ -#define __SVCID_H__ - -#include FT_INTERNAL_SERVICE_H - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_CID "CID" - - typedef FT_Error - (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face face, - const char* *registry, - const char* *ordering, - FT_Int *supplement ); - typedef FT_Error - (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face face, - FT_Bool *is_cid ); - typedef FT_Error - (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face face, - FT_UInt glyph_index, - FT_UInt *cid ); - - FT_DEFINE_SERVICE( CID ) - { - FT_CID_GetRegistryOrderingSupplementFunc get_ros; - FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid; - FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_CIDREC( class_, \ - get_ros_, \ - get_is_cid_, \ - get_cid_from_glyph_index_ ) \ - static const FT_Service_CIDRec class_ = \ - { \ - get_ros_, get_is_cid_, get_cid_from_glyph_index_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_CIDREC( class_, \ - get_ros_, \ - get_is_cid_, \ - get_cid_from_glyph_index_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_CIDRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_ros = get_ros_; \ - clazz->get_is_cid = get_is_cid_; \ - clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - - -#endif /* __SVCID_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svgldict.h b/drivers/freetype/freetype/include/freetype/internal/services/svgldict.h deleted file mode 100644 index 1d12534725..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svgldict.h +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************/ -/* */ -/* svgldict.h */ -/* */ -/* The FreeType glyph dictionary services (specification). */ -/* */ -/* Copyright 2003, 2009, 2012 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 __SVGLDICT_H__ -#define __SVGLDICT_H__ - -#include FT_INTERNAL_SERVICE_H - - -FT_BEGIN_HEADER - - - /* - * A service used to retrieve glyph names, as well as to find the - * index of a given glyph name in a font. - * - */ - -#define FT_SERVICE_ID_GLYPH_DICT "glyph-dict" - - - typedef FT_Error - (*FT_GlyphDict_GetNameFunc)( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ); - - typedef FT_UInt - (*FT_GlyphDict_NameIndexFunc)( FT_Face face, - FT_String* glyph_name ); - - - FT_DEFINE_SERVICE( GlyphDict ) - { - FT_GlyphDict_GetNameFunc get_name; - FT_GlyphDict_NameIndexFunc name_index; /* optional */ - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ - get_name_, \ - name_index_) \ - static const FT_Service_GlyphDictRec class_ = \ - { \ - get_name_, name_index_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ - get_name_, \ - name_index_) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_GlyphDictRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_name = get_name_; \ - clazz->name_index = name_index_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - - -#endif /* __SVGLDICT_H__ */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svgxval.h b/drivers/freetype/freetype/include/freetype/internal/services/svgxval.h deleted file mode 100644 index 2cdab50655..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svgxval.h +++ /dev/null @@ -1,72 +0,0 @@ -/***************************************************************************/ -/* */ -/* svgxval.h */ -/* */ -/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ -/* */ -/* Copyright 2004, 2005 by */ -/* Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#ifndef __SVGXVAL_H__ -#define __SVGXVAL_H__ - -#include FT_GX_VALIDATE_H -#include FT_INTERNAL_VALIDATE_H - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_GX_VALIDATE "truetypegx-validate" -#define FT_SERVICE_ID_CLASSICKERN_VALIDATE "classickern-validate" - - typedef FT_Error - (*gxv_validate_func)( FT_Face face, - FT_UInt gx_flags, - FT_Bytes tables[FT_VALIDATE_GX_LENGTH], - FT_UInt table_length ); - - - typedef FT_Error - (*ckern_validate_func)( FT_Face face, - FT_UInt ckern_flags, - FT_Bytes *ckern_table ); - - - FT_DEFINE_SERVICE( GXvalidate ) - { - gxv_validate_func validate; - }; - - FT_DEFINE_SERVICE( CKERNvalidate ) - { - ckern_validate_func validate; - }; - - /* */ - - -FT_END_HEADER - - -#endif /* __SVGXVAL_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svkern.h b/drivers/freetype/freetype/include/freetype/internal/services/svkern.h deleted file mode 100644 index 1488adf493..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svkern.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************/ -/* */ -/* svkern.h */ -/* */ -/* The FreeType Kerning service (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __SVKERN_H__ -#define __SVKERN_H__ - -#include FT_INTERNAL_SERVICE_H -#include FT_TRUETYPE_TABLES_H - - -FT_BEGIN_HEADER - -#define FT_SERVICE_ID_KERNING "kerning" - - - typedef FT_Error - (*FT_Kerning_TrackGetFunc)( FT_Face face, - FT_Fixed point_size, - FT_Int degree, - FT_Fixed* akerning ); - - FT_DEFINE_SERVICE( Kerning ) - { - FT_Kerning_TrackGetFunc get_track; - }; - - /* */ - - -FT_END_HEADER - - -#endif /* __SVKERN_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svmm.h b/drivers/freetype/freetype/include/freetype/internal/services/svmm.h deleted file mode 100644 index b08a663d66..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svmm.h +++ /dev/null @@ -1,113 +0,0 @@ -/***************************************************************************/ -/* */ -/* svmm.h */ -/* */ -/* The FreeType Multiple Masters and GX var services (specification). */ -/* */ -/* Copyright 2003, 2004, 2009, 2012 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 __SVMM_H__ -#define __SVMM_H__ - -#include FT_INTERNAL_SERVICE_H - - -FT_BEGIN_HEADER - - - /* - * A service used to manage multiple-masters data in a given face. - * - * See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H). - * - */ - -#define FT_SERVICE_ID_MULTI_MASTERS "multi-masters" - - - typedef FT_Error - (*FT_Get_MM_Func)( FT_Face face, - FT_Multi_Master* master ); - - typedef FT_Error - (*FT_Get_MM_Var_Func)( FT_Face face, - FT_MM_Var* *master ); - - typedef FT_Error - (*FT_Set_MM_Design_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - typedef FT_Error - (*FT_Set_Var_Design_Func)( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - typedef FT_Error - (*FT_Set_MM_Blend_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - - FT_DEFINE_SERVICE( MultiMasters ) - { - FT_Get_MM_Func get_mm; - FT_Set_MM_Design_Func set_mm_design; - FT_Set_MM_Blend_Func set_mm_blend; - FT_Get_MM_Var_Func get_mm_var; - FT_Set_Var_Design_Func set_var_design; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ - { \ - clazz->get_mm = get_mm_; \ - clazz->set_mm_design = set_mm_design_; \ - clazz->set_mm_blend = set_mm_blend_; \ - clazz->get_mm_var = get_mm_var_; \ - clazz->set_var_design = set_var_design_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - -#endif /* __SVMM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svotval.h b/drivers/freetype/freetype/include/freetype/internal/services/svotval.h deleted file mode 100644 index 970bbd5759..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svotval.h +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************/ -/* */ -/* svotval.h */ -/* */ -/* The FreeType OpenType validation service (specification). */ -/* */ -/* Copyright 2004, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __SVOTVAL_H__ -#define __SVOTVAL_H__ - -#include FT_OPENTYPE_VALIDATE_H -#include FT_INTERNAL_VALIDATE_H - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_OPENTYPE_VALIDATE "opentype-validate" - - - typedef FT_Error - (*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 ) - { - otv_validate_func validate; - }; - - /* */ - - -FT_END_HEADER - - -#endif /* __SVOTVAL_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svpfr.h b/drivers/freetype/freetype/include/freetype/internal/services/svpfr.h deleted file mode 100644 index 462786f9ce..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svpfr.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************/ -/* */ -/* svpfr.h */ -/* */ -/* Internal PFR service functions (specification). */ -/* */ -/* Copyright 2003, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __SVPFR_H__ -#define __SVPFR_H__ - -#include FT_PFR_H -#include FT_INTERNAL_SERVICE_H - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_PFR_METRICS "pfr-metrics" - - - typedef FT_Error - (*FT_PFR_GetMetricsFunc)( FT_Face face, - FT_UInt *aoutline, - FT_UInt *ametrics, - FT_Fixed *ax_scale, - FT_Fixed *ay_scale ); - - typedef FT_Error - (*FT_PFR_GetKerningFunc)( FT_Face face, - FT_UInt left, - FT_UInt right, - FT_Vector *avector ); - - typedef FT_Error - (*FT_PFR_GetAdvanceFunc)( FT_Face face, - FT_UInt gindex, - FT_Pos *aadvance ); - - - FT_DEFINE_SERVICE( PfrMetrics ) - { - FT_PFR_GetMetricsFunc get_metrics; - FT_PFR_GetKerningFunc get_kerning; - FT_PFR_GetAdvanceFunc get_advance; - - }; - - /* */ - -FT_END_HEADER - -#endif /* __SVPFR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svpostnm.h b/drivers/freetype/freetype/include/freetype/internal/services/svpostnm.h deleted file mode 100644 index a76b4fe057..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svpostnm.h +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************************/ -/* */ -/* svpostnm.h */ -/* */ -/* The FreeType PostScript name services (specification). */ -/* */ -/* Copyright 2003, 2007, 2009, 2012 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 __SVPOSTNM_H__ -#define __SVPOSTNM_H__ - -#include FT_INTERNAL_SERVICE_H - - -FT_BEGIN_HEADER - - /* - * A trivial service used to retrieve the PostScript name of a given - * font when available. The `get_name' field should never be NULL. - * - * The corresponding function can return NULL to indicate that the - * PostScript name is not available. - * - * The name is owned by the face and will be destroyed with it. - */ - -#define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME "postscript-font-name" - - - typedef const char* - (*FT_PsName_GetFunc)( FT_Face face ); - - - FT_DEFINE_SERVICE( PsFontName ) - { - FT_PsName_GetFunc get_ps_font_name; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ - static const FT_Service_PsFontNameRec class_ = \ - { \ - get_ps_font_name_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_PsFontNameRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_ps_font_name = get_ps_font_name_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - - -#endif /* __SVPOSTNM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svprop.h b/drivers/freetype/freetype/include/freetype/internal/services/svprop.h deleted file mode 100644 index 22da0bbc69..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svprop.h +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************************/ -/* */ -/* svprop.h */ -/* */ -/* The FreeType property service (specification). */ -/* */ -/* Copyright 2012 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 __SVPROP_H__ -#define __SVPROP_H__ - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_PROPERTIES "properties" - - - typedef FT_Error - (*FT_Properties_SetFunc)( FT_Module module, - const char* property_name, - const void* value ); - - typedef FT_Error - (*FT_Properties_GetFunc)( FT_Module module, - const char* property_name, - void* value ); - - - FT_DEFINE_SERVICE( Properties ) - { - FT_Properties_SetFunc set_property; - FT_Properties_GetFunc get_property; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ - set_property_, \ - get_property_ ) \ - static const FT_Service_PropertiesRec class_ = \ - { \ - set_property_, \ - get_property_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ - set_property_, \ - get_property_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_PropertiesRec* clazz ) \ - { \ - clazz->set_property = set_property_; \ - clazz->get_property = get_property_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - - -#endif /* __SVPROP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svpscmap.h b/drivers/freetype/freetype/include/freetype/internal/services/svpscmap.h deleted file mode 100644 index 030948ea64..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svpscmap.h +++ /dev/null @@ -1,177 +0,0 @@ -/***************************************************************************/ -/* */ -/* svpscmap.h */ -/* */ -/* The FreeType PostScript charmap service (specification). */ -/* */ -/* Copyright 2003, 2006, 2009, 2012 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 __SVPSCMAP_H__ -#define __SVPSCMAP_H__ - -#include FT_INTERNAL_OBJECTS_H - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_POSTSCRIPT_CMAPS "postscript-cmaps" - - - /* - * Adobe glyph name to unicode value. - */ - typedef FT_UInt32 - (*PS_Unicode_ValueFunc)( const char* glyph_name ); - - /* - * Macintosh name id to glyph name. NULL if invalid index. - */ - typedef const char* - (*PS_Macintosh_NameFunc)( FT_UInt name_index ); - - /* - * Adobe standard string ID to glyph name. NULL if invalid index. - */ - typedef const char* - (*PS_Adobe_Std_StringsFunc)( FT_UInt string_index ); - - - /* - * Simple unicode -> glyph index charmap built from font glyph names - * table. - */ - typedef struct PS_UniMap_ - { - FT_UInt32 unicode; /* bit 31 set: is glyph variant */ - FT_UInt glyph_index; - - } PS_UniMap; - - - typedef struct PS_UnicodesRec_* PS_Unicodes; - - typedef struct PS_UnicodesRec_ - { - FT_CMapRec cmap; - FT_UInt num_maps; - PS_UniMap* maps; - - } PS_UnicodesRec; - - - /* - * A function which returns a glyph name for a given index. Returns - * NULL if invalid index. - */ - typedef const char* - (*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_GetGlyphNameFunc get_glyph_name, - PS_FreeGlyphNameFunc free_glyph_name, - FT_Pointer glyph_data ); - - typedef FT_UInt - (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, - FT_UInt32 unicode ); - - typedef FT_UInt32 - (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, - FT_UInt32 *unicode ); - - - FT_DEFINE_SERVICE( PsCMaps ) - { - PS_Unicode_ValueFunc unicode_value; - - PS_Unicodes_InitFunc unicodes_init; - PS_Unicodes_CharIndexFunc unicodes_char_index; - PS_Unicodes_CharNextFunc unicodes_char_next; - - PS_Macintosh_NameFunc macintosh_name; - PS_Adobe_Std_StringsFunc adobe_std_strings; - const unsigned short* adobe_std_encoding; - const unsigned short* adobe_expert_encoding; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_PSCMAPSREC( class_, \ - unicode_value_, \ - unicodes_init_, \ - unicodes_char_index_, \ - unicodes_char_next_, \ - macintosh_name_, \ - adobe_std_strings_, \ - adobe_std_encoding_, \ - adobe_expert_encoding_ ) \ - static const FT_Service_PsCMapsRec class_ = \ - { \ - unicode_value_, unicodes_init_, \ - unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ - adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_PSCMAPSREC( class_, \ - unicode_value_, \ - unicodes_init_, \ - unicodes_char_index_, \ - unicodes_char_next_, \ - macintosh_name_, \ - adobe_std_strings_, \ - adobe_std_encoding_, \ - adobe_expert_encoding_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_PsCMapsRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->unicode_value = unicode_value_; \ - clazz->unicodes_init = unicodes_init_; \ - clazz->unicodes_char_index = unicodes_char_index_; \ - clazz->unicodes_char_next = unicodes_char_next_; \ - clazz->macintosh_name = macintosh_name_; \ - clazz->adobe_std_strings = adobe_std_strings_; \ - clazz->adobe_std_encoding = adobe_std_encoding_; \ - clazz->adobe_expert_encoding = adobe_expert_encoding_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - - -#endif /* __SVPSCMAP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svpsinfo.h b/drivers/freetype/freetype/include/freetype/internal/services/svpsinfo.h deleted file mode 100644 index 4bfb506711..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svpsinfo.h +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************/ -/* */ -/* svpsinfo.h */ -/* */ -/* The FreeType PostScript info service (specification). */ -/* */ -/* Copyright 2003, 2004, 2009, 2011, 2012 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 __SVPSINFO_H__ -#define __SVPSINFO_H__ - -#include FT_INTERNAL_SERVICE_H -#include FT_INTERNAL_TYPE1_TYPES_H - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_POSTSCRIPT_INFO "postscript-info" - - - typedef FT_Error - (*PS_GetFontInfoFunc)( FT_Face face, - PS_FontInfoRec* afont_info ); - - typedef FT_Error - (*PS_GetFontExtraFunc)( FT_Face face, - PS_FontExtraRec* afont_extra ); - - typedef FT_Int - (*PS_HasGlyphNamesFunc)( FT_Face face ); - - typedef FT_Error - (*PS_GetFontPrivateFunc)( FT_Face face, - PS_PrivateRec* afont_private ); - - typedef FT_Long - (*PS_GetFontValueFunc)( FT_Face face, - PS_Dict_Keys key, - FT_UInt idx, - void *value, - FT_Long value_len ); - - - FT_DEFINE_SERVICE( PsInfo ) - { - PS_GetFontInfoFunc ps_get_font_info; - PS_GetFontExtraFunc ps_get_font_extra; - PS_HasGlyphNamesFunc ps_has_glyph_names; - PS_GetFontPrivateFunc ps_get_font_private; - PS_GetFontValueFunc ps_get_font_value; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_PSINFOREC( class_, \ - get_font_info_, \ - ps_get_font_extra_, \ - has_glyph_names_, \ - get_font_private_, \ - get_font_value_ ) \ - static const FT_Service_PsInfoRec class_ = \ - { \ - get_font_info_, ps_get_font_extra_, has_glyph_names_, \ - get_font_private_, get_font_value_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_PSINFOREC( class_, \ - get_font_info_, \ - ps_get_font_extra_, \ - has_glyph_names_, \ - get_font_private_, \ - get_font_value_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_PsInfoRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->ps_get_font_info = get_font_info_; \ - clazz->ps_get_font_extra = ps_get_font_extra_; \ - clazz->ps_has_glyph_names = has_glyph_names_; \ - clazz->ps_get_font_private = get_font_private_; \ - clazz->ps_get_font_value = get_font_value_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - - -#endif /* __SVPSINFO_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svsfnt.h b/drivers/freetype/freetype/include/freetype/internal/services/svsfnt.h deleted file mode 100644 index d3835aa1c2..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svsfnt.h +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************/ -/* */ -/* svsfnt.h */ -/* */ -/* The FreeType SFNT table loading service (specification). */ -/* */ -/* Copyright 2003, 2004, 2009, 2012 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 __SVSFNT_H__ -#define __SVSFNT_H__ - -#include FT_INTERNAL_SERVICE_H -#include FT_TRUETYPE_TABLES_H - - -FT_BEGIN_HEADER - - - /* - * SFNT table loading service. - */ - -#define FT_SERVICE_ID_SFNT_TABLE "sfnt-table" - - - /* - * Used to implement FT_Load_Sfnt_Table(). - */ - typedef FT_Error - (*FT_SFNT_TableLoadFunc)( FT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); - - /* - * Used to implement FT_Get_Sfnt_Table(). - */ - typedef void* - (*FT_SFNT_TableGetFunc)( FT_Face face, - FT_Sfnt_Tag tag ); - - - /* - * Used to implement FT_Sfnt_Table_Info(). - */ - typedef FT_Error - (*FT_SFNT_TableInfoFunc)( FT_Face face, - FT_UInt idx, - FT_ULong *tag, - FT_ULong *offset, - FT_ULong *length ); - - - FT_DEFINE_SERVICE( SFNT_Table ) - { - FT_SFNT_TableLoadFunc load_table; - FT_SFNT_TableGetFunc get_table; - FT_SFNT_TableInfoFunc table_info; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ - static const FT_Service_SFNT_TableRec class_ = \ - { \ - load_, get_, info_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_SFNT_TableRec* clazz ) \ - { \ - clazz->load_table = load_; \ - clazz->get_table = get_; \ - clazz->table_info = info_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - - -#endif /* __SVSFNT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svttcmap.h b/drivers/freetype/freetype/include/freetype/internal/services/svttcmap.h deleted file mode 100644 index 83994aaf8a..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svttcmap.h +++ /dev/null @@ -1,107 +0,0 @@ -/***************************************************************************/ -/* */ -/* svttcmap.h */ -/* */ -/* The FreeType TrueType/sfnt cmap extra information service. */ -/* */ -/* Copyright 2003 by */ -/* Masatake YAMATO, Redhat K.K. */ -/* */ -/* Copyright 2003, 2008, 2009, 2012 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. */ -/* */ -/***************************************************************************/ - -/* Development of this service is support of - Information-technology Promotion Agency, Japan. */ - -#ifndef __SVTTCMAP_H__ -#define __SVTTCMAP_H__ - -#include FT_INTERNAL_SERVICE_H -#include FT_TRUETYPE_TABLES_H - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_TT_CMAP "tt-cmaps" - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_CMapInfo */ - /* */ - /* <Description> */ - /* A structure used to store TrueType/sfnt specific cmap information */ - /* which is not covered by the generic @FT_CharMap structure. This */ - /* structure can be accessed with the @FT_Get_TT_CMap_Info function. */ - /* */ - /* <Fields> */ - /* language :: */ - /* The language ID used in Mac fonts. Definitions of values are in */ - /* freetype/ttnameid.h. */ - /* */ - /* format :: */ - /* The cmap format. OpenType 1.5 defines the formats 0 (byte */ - /* encoding table), 2~(high-byte mapping through table), 4~(segment */ - /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ - /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ - /* coverage), and 14 (Unicode Variation Sequences). */ - /* */ - typedef struct TT_CMapInfo_ - { - FT_ULong language; - FT_Long format; - - } TT_CMapInfo; - - - typedef FT_Error - (*TT_CMap_Info_GetFunc)( FT_CharMap charmap, - TT_CMapInfo *cmap_info ); - - - FT_DEFINE_SERVICE( TTCMaps ) - { - TT_CMap_Info_GetFunc get_cmap_info; - }; - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ - static const FT_Service_TTCMapsRec class_ = \ - { \ - get_cmap_info_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_TTCMapsRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_cmap_info = get_cmap_info_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - -#endif /* __SVTTCMAP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svtteng.h b/drivers/freetype/freetype/include/freetype/internal/services/svtteng.h deleted file mode 100644 index 58e02a6f9d..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svtteng.h +++ /dev/null @@ -1,53 +0,0 @@ -/***************************************************************************/ -/* */ -/* svtteng.h */ -/* */ -/* The FreeType TrueType engine query service (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __SVTTENG_H__ -#define __SVTTENG_H__ - -#include FT_INTERNAL_SERVICE_H -#include FT_MODULE_H - - -FT_BEGIN_HEADER - - - /* - * SFNT table loading service. - */ - -#define FT_SERVICE_ID_TRUETYPE_ENGINE "truetype-engine" - - /* - * Used to implement FT_Get_TrueType_Engine_Type - */ - - FT_DEFINE_SERVICE( TrueTypeEngine ) - { - FT_TrueTypeEngineType engine_type; - }; - - /* */ - - -FT_END_HEADER - - -#endif /* __SVTTENG_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svttglyf.h b/drivers/freetype/freetype/include/freetype/internal/services/svttglyf.h deleted file mode 100644 index 369eb8421b..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svttglyf.h +++ /dev/null @@ -1,68 +0,0 @@ -/***************************************************************************/ -/* */ -/* svttglyf.h */ -/* */ -/* The FreeType TrueType glyph service. */ -/* */ -/* Copyright 2007, 2009, 2012 by David Turner. */ -/* */ -/* 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 __SVTTGLYF_H__ -#define __SVTTGLYF_H__ - -#include FT_INTERNAL_SERVICE_H -#include FT_TRUETYPE_TABLES_H - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_TT_GLYF "tt-glyf" - - - typedef FT_ULong - (*TT_Glyf_GetLocationFunc)( FT_Face face, - FT_UInt gindex, - FT_ULong *psize ); - - FT_DEFINE_SERVICE( TTGlyf ) - { - TT_Glyf_GetLocationFunc get_location; - }; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ - static const FT_Service_TTGlyfRec class_ = \ - { \ - get_location_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_TTGlyfRec* clazz ) \ - { \ - clazz->get_location = get_location_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - -#endif /* __SVTTGLYF_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svwinfnt.h b/drivers/freetype/freetype/include/freetype/internal/services/svwinfnt.h deleted file mode 100644 index 57f7765d92..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svwinfnt.h +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************************/ -/* */ -/* svwinfnt.h */ -/* */ -/* The FreeType Windows FNT/FONT service (specification). */ -/* */ -/* Copyright 2003 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 __SVWINFNT_H__ -#define __SVWINFNT_H__ - -#include FT_INTERNAL_SERVICE_H -#include FT_WINFONTS_H - - -FT_BEGIN_HEADER - - -#define FT_SERVICE_ID_WINFNT "winfonts" - - typedef FT_Error - (*FT_WinFnt_GetHeaderFunc)( FT_Face face, - FT_WinFNT_HeaderRec *aheader ); - - - FT_DEFINE_SERVICE( WinFnt ) - { - FT_WinFnt_GetHeaderFunc get_header; - }; - - /* */ - - -FT_END_HEADER - - -#endif /* __SVWINFNT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svxf86nm.h b/drivers/freetype/freetype/include/freetype/internal/services/svxf86nm.h deleted file mode 100644 index ca5d884a83..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/services/svxf86nm.h +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************/ -/* */ -/* svxf86nm.h */ -/* */ -/* The FreeType XFree86 services (specification only). */ -/* */ -/* Copyright 2003 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 __SVXF86NM_H__ -#define __SVXF86NM_H__ - -#include FT_INTERNAL_SERVICE_H - - -FT_BEGIN_HEADER - - - /* - * A trivial service used to return the name of a face's font driver, - * according to the XFree86 nomenclature. Note that the service data - * is a simple constant string pointer. - */ - -#define FT_SERVICE_ID_XF86_NAME "xf86-driver-name" - -#define FT_XF86_FORMAT_TRUETYPE "TrueType" -#define FT_XF86_FORMAT_TYPE_1 "Type 1" -#define FT_XF86_FORMAT_BDF "BDF" -#define FT_XF86_FORMAT_PCF "PCF" -#define FT_XF86_FORMAT_TYPE_42 "Type 42" -#define FT_XF86_FORMAT_CID "CID Type 1" -#define FT_XF86_FORMAT_CFF "CFF" -#define FT_XF86_FORMAT_PFR "PFR" -#define FT_XF86_FORMAT_WINFNT "Windows FNT" - - /* */ - - -FT_END_HEADER - - -#endif /* __SVXF86NM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/sfnt.h b/drivers/freetype/freetype/include/freetype/internal/sfnt.h deleted file mode 100644 index 6b5e41f1ad..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/sfnt.h +++ /dev/null @@ -1,707 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfnt.h */ -/* */ -/* High-level `sfnt' driver interface (specification). */ -/* */ -/* Copyright 1996-2006, 2009, 2012-2013 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 __SFNT_H__ -#define __SFNT_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H -#include FT_INTERNAL_TRUETYPE_TYPES_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Init_Face_Func */ - /* */ - /* <Description> */ - /* First part of the SFNT face object initialization. This finds */ - /* the face in a SFNT file or collection, and load its format tag in */ - /* face->format_tag. */ - /* */ - /* <Input> */ - /* stream :: The input stream. */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* params :: Optional additional parameters. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The stream cursor must be at the font file's origin. */ - /* */ - /* This function recognizes fonts embedded in a `TrueType */ - /* collection'. */ - /* */ - /* Once the format tag has been validated by the font driver, it */ - /* should then call the TT_Load_Face_Func() callback to read the rest */ - /* of the SFNT tables in the object. */ - /* */ - typedef FT_Error - (*TT_Init_Face_Func)( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Face_Func */ - /* */ - /* <Description> */ - /* Second part of the SFNT face object initialization. This loads */ - /* the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the */ - /* face object. */ - /* */ - /* <Input> */ - /* stream :: The input stream. */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* params :: Optional additional parameters. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* This function must be called after TT_Init_Face_Func(). */ - /* */ - typedef FT_Error - (*TT_Load_Face_Func)( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Done_Face_Func */ - /* */ - /* <Description> */ - /* A callback used to delete the common SFNT data from a face. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Note> */ - /* This function does NOT destroy the face object. */ - /* */ - typedef void - (*TT_Done_Face_Func)( TT_Face face ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Any_Func */ - /* */ - /* <Description> */ - /* Load any font table into client memory. */ - /* */ - /* <Input> */ - /* face :: The face object to look for. */ - /* */ - /* tag :: The tag of table to load. Use the value 0 if you want */ - /* to access the whole font file, else set this parameter */ - /* to a valid TrueType table tag that you can forge with */ - /* the MAKE_TT_TAG macro. */ - /* */ - /* offset :: The starting offset in the table (or the file if */ - /* tag == 0). */ - /* */ - /* length :: The address of the decision variable: */ - /* */ - /* If length == NULL: */ - /* Loads the whole table. Returns an error if */ - /* `offset' == 0! */ - /* */ - /* If *length == 0: */ - /* Exits immediately; returning the length of the given */ - /* table or of the font file, depending on the value of */ - /* `tag'. */ - /* */ - /* If *length != 0: */ - /* Loads the next `length' bytes of table or font, */ - /* starting at offset `offset' (in table or font too). */ - /* */ - /* <Output> */ - /* buffer :: The address of target buffer. */ - /* */ - /* <Return> */ - /* TrueType error code. 0 means success. */ - /* */ - typedef FT_Error - (*TT_Load_Any_Func)( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte *buffer, - FT_ULong* length ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Find_SBit_Image_Func */ - /* */ - /* <Description> */ - /* Check whether an embedded bitmap (an `sbit') exists for a given */ - /* glyph, at a given strike. */ - /* */ - /* <Input> */ - /* face :: The target face object. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* strike_index :: The current strike index. */ - /* */ - /* <Output> */ - /* arange :: The SBit range containing the glyph index. */ - /* */ - /* astrike :: The SBit strike containing the glyph index. */ - /* */ - /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. Returns */ - /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ - /* glyph. */ - /* */ - typedef FT_Error - (*TT_Find_SBit_Image_Func)( TT_Face face, - FT_UInt glyph_index, - FT_ULong strike_index, - TT_SBit_Range *arange, - TT_SBit_Strike *astrike, - FT_ULong *aglyph_offset ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_SBit_Metrics_Func */ - /* */ - /* <Description> */ - /* Get the big metrics for a given embedded bitmap. */ - /* */ - /* <Input> */ - /* stream :: The input stream. */ - /* */ - /* range :: The SBit range containing the glyph. */ - /* */ - /* <Output> */ - /* big_metrics :: A big SBit metrics structure for the glyph. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The stream cursor must be positioned at the glyph's offset within */ - /* the `EBDT' table before the call. */ - /* */ - /* If the image format uses variable metrics, the stream cursor is */ - /* positioned just after the metrics header in the `EBDT' table on */ - /* function exit. */ - /* */ - typedef FT_Error - (*TT_Load_SBit_Metrics_Func)( FT_Stream stream, - TT_SBit_Range range, - TT_SBit_Metrics metrics ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_SBit_Image_Func */ - /* */ - /* <Description> */ - /* Load a given glyph sbit image from the font resource. This also */ - /* returns its metrics. */ - /* */ - /* <Input> */ - /* face :: */ - /* The target face object. */ - /* */ - /* strike_index :: */ - /* The strike index. */ - /* */ - /* glyph_index :: */ - /* The current glyph index. */ - /* */ - /* load_flags :: */ - /* The current load flags. */ - /* */ - /* stream :: */ - /* The input stream. */ - /* */ - /* <Output> */ - /* amap :: */ - /* The target pixmap. */ - /* */ - /* ametrics :: */ - /* A big sbit metrics structure for the glyph image. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* glyph sbit exists for the index. */ - /* */ - /* <Note> */ - /* The `map.buffer' field is always freed before the glyph is loaded. */ - /* */ - typedef FT_Error - (*TT_Load_SBit_Image_Func)( TT_Face face, - FT_ULong strike_index, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap *amap, - TT_SBit_MetricsRec *ametrics ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Set_SBit_Strike_Func */ - /* */ - /* <Description> */ - /* Select an sbit strike for a given size request. */ - /* */ - /* <Input> */ - /* face :: The target face object. */ - /* */ - /* req :: The size request. */ - /* */ - /* <Output> */ - /* astrike_index :: The index of the sbit strike. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* sbit strike exists for the selected ppem values. */ - /* */ - typedef FT_Error - (*TT_Set_SBit_Strike_Func)( TT_Face face, - FT_Size_Request req, - FT_ULong* astrike_index ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Strike_Metrics_Func */ - /* */ - /* <Description> */ - /* Load the metrics of a given strike. */ - /* */ - /* <Input> */ - /* face :: The target face object. */ - /* */ - /* strike_index :: The strike index. */ - /* */ - /* <Output> */ - /* metrics :: the metrics of the strike. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* such sbit strike exists. */ - /* */ - typedef FT_Error - (*TT_Load_Strike_Metrics_Func)( TT_Face face, - FT_ULong strike_index, - FT_Size_Metrics* metrics ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Get_PS_Name_Func */ - /* */ - /* <Description> */ - /* Get the PostScript glyph name of a glyph. */ - /* */ - /* <Input> */ - /* idx :: The glyph index. */ - /* */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ - /* */ - /* You must not modify the returned string! */ - /* */ - /* <Output> */ - /* FreeType error code. 0 means success. */ - /* */ - typedef FT_Error - (*TT_Get_PS_Name_Func)( TT_Face face, - FT_UInt idx, - FT_String** PSname ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Metrics_Func */ - /* */ - /* <Description> */ - /* Load a metrics table, which is a table with a horizontal and a */ - /* vertical version. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load the vertical one. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - typedef FT_Error - (*TT_Load_Metrics_Func)( TT_Face face, - FT_Stream stream, - FT_Bool vertical ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Get_Metrics_Func */ - /* */ - /* <Description> */ - /* Load the horizontal or vertical header in a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load vertical metrics. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - typedef FT_Error - (*TT_Get_Metrics_Func)( TT_Face face, - FT_Bool vertical, - FT_UInt gindex, - FT_Short* abearing, - FT_UShort* aadvance ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Table_Func */ - /* */ - /* <Description> */ - /* Load a given TrueType table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The function uses `face->goto_table' to seek the stream to the */ - /* start of the table, except while loading the font directory. */ - /* */ - typedef FT_Error - (*TT_Load_Table_Func)( TT_Face face, - FT_Stream stream ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Free_Table_Func */ - /* */ - /* <Description> */ - /* Free a given TrueType table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - typedef void - (*TT_Free_Table_Func)( TT_Face face ); - - - /* - * @functype: - * TT_Face_GetKerningFunc - * - * @description: - * Return the horizontal kerning value between two glyphs. - * - * @input: - * face :: A handle to the source face object. - * left_glyph :: The left glyph index. - * right_glyph :: The right glyph index. - * - * @return: - * The kerning value in font units. - */ - typedef FT_Int - (*TT_Face_GetKerningFunc)( TT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph ); - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* SFNT_Interface */ - /* */ - /* <Description> */ - /* This structure holds pointers to the functions used to load and */ - /* free the basic tables that are required in a `sfnt' font file. */ - /* */ - /* <Fields> */ - /* Check the various xxx_Func() descriptions for details. */ - /* */ - typedef struct SFNT_Interface_ - { - TT_Loader_GotoTableFunc goto_table; - - TT_Init_Face_Func init_face; - TT_Load_Face_Func load_face; - TT_Done_Face_Func done_face; - FT_Module_Requester get_interface; - - TT_Load_Any_Func load_any; - - /* these functions are called by `load_face' but they can also */ - /* be called from external modules, if there is a need to do so */ - TT_Load_Table_Func load_head; - TT_Load_Metrics_Func load_hhea; - TT_Load_Table_Func load_cmap; - TT_Load_Table_Func load_maxp; - TT_Load_Table_Func load_os2; - TT_Load_Table_Func load_post; - - TT_Load_Table_Func load_name; - TT_Free_Table_Func free_name; - - /* this field was called `load_kerning' up to version 2.1.10 */ - TT_Load_Table_Func load_kern; - - TT_Load_Table_Func load_gasp; - TT_Load_Table_Func load_pclt; - - /* see `ttload.h'; this field was called `load_bitmap_header' up to */ - /* version 2.1.10 */ - TT_Load_Table_Func load_bhed; - - TT_Load_SBit_Image_Func load_sbit_image; - - /* see `ttpost.h' */ - TT_Get_PS_Name_Func get_psname; - TT_Free_Table_Func free_psnames; - - /* starting here, the structure differs from version 2.1.7 */ - - /* this field was introduced in version 2.1.8, named `get_psname' */ - TT_Face_GetKerningFunc get_kerning; - - /* new elements introduced after version 2.1.10 */ - - /* load the font directory, i.e., the offset table and */ - /* 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; - - - /* transitional */ - typedef SFNT_Interface* SFNT_Service; - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SFNT_INTERFACE( \ - class_, \ - goto_table_, \ - init_face_, \ - load_face_, \ - done_face_, \ - get_interface_, \ - load_any_, \ - load_head_, \ - load_hhea_, \ - load_cmap_, \ - load_maxp_, \ - load_os2_, \ - load_post_, \ - load_name_, \ - free_name_, \ - load_kern_, \ - load_gasp_, \ - load_pclt_, \ - load_bhed_, \ - load_sbit_image_, \ - get_psname_, \ - free_psnames_, \ - get_kerning_, \ - load_font_dir_, \ - load_hmtx_, \ - load_eblc_, \ - free_eblc_, \ - set_sbit_strike_, \ - load_strike_metrics_, \ - get_metrics_ ) \ - static const SFNT_Interface class_ = \ - { \ - goto_table_, \ - init_face_, \ - load_face_, \ - done_face_, \ - get_interface_, \ - load_any_, \ - load_head_, \ - load_hhea_, \ - load_cmap_, \ - load_maxp_, \ - load_os2_, \ - load_post_, \ - load_name_, \ - free_name_, \ - load_kern_, \ - load_gasp_, \ - load_pclt_, \ - load_bhed_, \ - load_sbit_image_, \ - get_psname_, \ - free_psnames_, \ - get_kerning_, \ - load_font_dir_, \ - load_hmtx_, \ - load_eblc_, \ - free_eblc_, \ - set_sbit_strike_, \ - load_strike_metrics_, \ - get_metrics_, \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_INTERNAL( a, a_ ) \ - clazz->a = a_; - -#define FT_DEFINE_SFNT_INTERFACE( \ - class_, \ - goto_table_, \ - init_face_, \ - load_face_, \ - done_face_, \ - get_interface_, \ - load_any_, \ - load_head_, \ - load_hhea_, \ - load_cmap_, \ - load_maxp_, \ - load_os2_, \ - load_post_, \ - load_name_, \ - free_name_, \ - load_kern_, \ - load_gasp_, \ - load_pclt_, \ - load_bhed_, \ - load_sbit_image_, \ - get_psname_, \ - free_psnames_, \ - get_kerning_, \ - load_font_dir_, \ - load_hmtx_, \ - load_eblc_, \ - free_eblc_, \ - set_sbit_strike_, \ - load_strike_metrics_, \ - get_metrics_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - SFNT_Interface* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->goto_table = goto_table_; \ - clazz->init_face = init_face_; \ - clazz->load_face = load_face_; \ - clazz->done_face = done_face_; \ - clazz->get_interface = get_interface_; \ - clazz->load_any = load_any_; \ - clazz->load_head = load_head_; \ - clazz->load_hhea = load_hhea_; \ - clazz->load_cmap = load_cmap_; \ - clazz->load_maxp = load_maxp_; \ - clazz->load_os2 = load_os2_; \ - clazz->load_post = load_post_; \ - clazz->load_name = load_name_; \ - clazz->free_name = free_name_; \ - clazz->load_kern = load_kern_; \ - clazz->load_gasp = load_gasp_; \ - clazz->load_pclt = load_pclt_; \ - clazz->load_bhed = load_bhed_; \ - clazz->load_sbit_image = load_sbit_image_; \ - clazz->get_psname = get_psname_; \ - clazz->free_psnames = free_psnames_; \ - clazz->get_kerning = get_kerning_; \ - clazz->load_font_dir = load_font_dir_; \ - clazz->load_hmtx = load_hmtx_; \ - clazz->load_eblc = load_eblc_; \ - clazz->free_eblc = free_eblc_; \ - clazz->set_sbit_strike = set_sbit_strike_; \ - clazz->load_strike_metrics = load_strike_metrics_; \ - clazz->get_metrics = get_metrics_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - -FT_END_HEADER - -#endif /* __SFNT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/t1types.h b/drivers/freetype/freetype/include/freetype/internal/t1types.h deleted file mode 100644 index e20237c14d..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/t1types.h +++ /dev/null @@ -1,255 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1types.h */ -/* */ -/* Basic Type1/Type2 type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 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 __T1TYPES_H__ -#define __T1TYPES_H__ - - -#include <ft2build.h> -#include FT_TYPE1_TABLES_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H -#include FT_INTERNAL_SERVICE_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* T1_EncodingRec */ - /* */ - /* <Description> */ - /* A structure modeling a custom encoding. */ - /* */ - /* <Fields> */ - /* num_chars :: The number of character codes in the encoding. */ - /* Usually 256. */ - /* */ - /* code_first :: The lowest valid character code in the encoding. */ - /* */ - /* code_last :: The highest valid character code in the encoding */ - /* + 1. When equal to code_first there are no valid */ - /* character codes. */ - /* */ - /* char_index :: An array of corresponding glyph indices. */ - /* */ - /* char_name :: An array of corresponding glyph names. */ - /* */ - typedef struct T1_EncodingRecRec_ - { - FT_Int num_chars; - FT_Int code_first; - FT_Int code_last; - - FT_UShort* char_index; - FT_String** char_name; - - } T1_EncodingRec, *T1_Encoding; - - - /* used to hold extra data of PS_FontInfoRec that - * cannot be stored in the publicly defined structure. - * - * Note these can't be blended with multiple-masters. - */ - typedef struct PS_FontExtraRec_ - { - FT_UShort fs_type; - - } PS_FontExtraRec; - - - typedef struct T1_FontRec_ - { - PS_FontInfoRec font_info; /* font info dictionary */ - PS_FontExtraRec font_extra; /* font info extra fields */ - PS_PrivateRec private_dict; /* private dictionary */ - FT_String* font_name; /* top-level dictionary */ - - T1_EncodingType encoding_type; - T1_EncodingRec encoding; - - FT_Byte* subrs_block; - FT_Byte* charstrings_block; - FT_Byte* glyph_names_block; - - FT_Int num_subrs; - FT_Byte** subrs; - FT_PtrDist* subrs_len; - - FT_Int num_glyphs; - FT_String** glyph_names; /* array of glyph names */ - FT_Byte** charstrings; /* array of glyph charstrings */ - FT_PtrDist* charstrings_len; - - FT_Byte paint_type; - FT_Byte font_type; - FT_Matrix font_matrix; - FT_Vector font_offset; - FT_BBox font_bbox; - FT_Long font_id; - - FT_Fixed stroke_width; - - } T1_FontRec, *T1_Font; - - - typedef struct CID_SubrsRec_ - { - FT_UInt num_subrs; - FT_Byte** code; - - } CID_SubrsRec, *CID_Subrs; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** AFM FONT INFORMATION STRUCTURES ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct AFM_TrackKernRec_ - { - FT_Int degree; - FT_Fixed min_ptsize; - FT_Fixed min_kern; - FT_Fixed max_ptsize; - FT_Fixed max_kern; - - } AFM_TrackKernRec, *AFM_TrackKern; - - typedef struct AFM_KernPairRec_ - { - FT_Int index1; - FT_Int index2; - FT_Int x; - FT_Int y; - - } AFM_KernPairRec, *AFM_KernPair; - - typedef struct AFM_FontInfoRec_ - { - FT_Bool IsCIDFont; - FT_BBox FontBBox; - FT_Fixed Ascender; - FT_Fixed Descender; - AFM_TrackKern TrackKerns; /* free if non-NULL */ - FT_Int NumTrackKern; - AFM_KernPair KernPairs; /* free if non-NULL */ - FT_Int NumKernPair; - - } AFM_FontInfoRec, *AFM_FontInfo; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** ORIGINAL T1_FACE CLASS DEFINITION ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - typedef struct T1_FaceRec_* T1_Face; - typedef struct CID_FaceRec_* CID_Face; - - - typedef struct T1_FaceRec_ - { - FT_FaceRec root; - T1_FontRec type1; - const void* psnames; - const void* psaux; - const void* afm_data; - FT_CharMapRec charmaprecs[2]; - FT_CharMap charmaps[2]; - - /* 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_Long* buildchar; - - /* since version 2.1 - interface to PostScript hinter */ - const void* pshinter; - - } T1_FaceRec; - - - typedef struct CID_FaceRec_ - { - FT_FaceRec root; - void* psnames; - void* psaux; - CID_FaceInfoRec cid; - PS_FontExtraRec font_extra; -#if 0 - void* afm_data; -#endif - CID_Subrs subrs; - - /* since version 2.1 - interface to PostScript hinter */ - void* pshinter; - - /* since version 2.1.8, but was originally positioned after `afm_data' */ - FT_Byte* binary_data; /* used if hex data has been converted */ - FT_Stream cid_stream; - - } CID_FaceRec; - - -FT_END_HEADER - -#endif /* __T1TYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/tttypes.h b/drivers/freetype/freetype/include/freetype/internal/tttypes.h deleted file mode 100644 index 1bbfe499c5..0000000000 --- a/drivers/freetype/freetype/include/freetype/internal/tttypes.h +++ /dev/null @@ -1,1440 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttypes.h */ -/* */ -/* Basic SFNT/TrueType type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2002, 2004-2008, 2012-2013 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 __TTTYPES_H__ -#define __TTTYPES_H__ - - -#include <ft2build.h> -#include FT_TRUETYPE_TABLES_H -#include FT_INTERNAL_OBJECTS_H - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#include FT_MULTIPLE_MASTERS_H -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TTC_HeaderRec */ - /* */ - /* <Description> */ - /* TrueType collection header. This table contains the offsets of */ - /* the font headers of each distinct TrueType face in the file. */ - /* */ - /* <Fields> */ - /* tag :: Must be `ttc ' to indicate a TrueType collection. */ - /* */ - /* version :: The version number. */ - /* */ - /* count :: The number of faces in the collection. The */ - /* specification says this should be an unsigned long, but */ - /* we use a signed long since we need the value -1 for */ - /* specific purposes. */ - /* */ - /* offsets :: The offsets of the font headers, one per face. */ - /* */ - typedef struct TTC_HeaderRec_ - { - FT_ULong tag; - FT_Fixed version; - FT_Long count; - FT_ULong* offsets; - - } TTC_HeaderRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* SFNT_HeaderRec */ - /* */ - /* <Description> */ - /* SFNT file format header. */ - /* */ - /* <Fields> */ - /* format_tag :: The font format tag. */ - /* */ - /* num_tables :: The number of tables in file. */ - /* */ - /* search_range :: Must be `16 * (max power of 2 <= num_tables)'. */ - /* */ - /* entry_selector :: Must be log2 of `search_range / 16'. */ - /* */ - /* range_shift :: Must be `num_tables * 16 - search_range'. */ - /* */ - typedef struct SFNT_HeaderRec_ - { - FT_ULong format_tag; - FT_UShort num_tables; - FT_UShort search_range; - FT_UShort entry_selector; - FT_UShort range_shift; - - FT_ULong offset; /* not in file */ - - } SFNT_HeaderRec, *SFNT_Header; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_TableRec */ - /* */ - /* <Description> */ - /* This structure describes a given table of a TrueType font. */ - /* */ - /* <Fields> */ - /* Tag :: A four-bytes tag describing the table. */ - /* */ - /* CheckSum :: The table checksum. This value can be ignored. */ - /* */ - /* Offset :: The offset of the table from the start of the TrueType */ - /* font in its resource. */ - /* */ - /* Length :: The table length (in bytes). */ - /* */ - typedef struct TT_TableRec_ - { - FT_ULong Tag; /* table type */ - FT_ULong CheckSum; /* table checksum */ - FT_ULong Offset; /* table file offset */ - FT_ULong Length; /* table length */ - - } TT_TableRec, *TT_Table; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_LongMetricsRec */ - /* */ - /* <Description> */ - /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ - /* TrueType tables. The values are expressed in font units. */ - /* */ - /* <Fields> */ - /* advance :: The advance width or height for the glyph. */ - /* */ - /* bearing :: The left-side or top-side bearing for the glyph. */ - /* */ - typedef struct TT_LongMetricsRec_ - { - FT_UShort advance; - FT_Short bearing; - - } TT_LongMetricsRec, *TT_LongMetrics; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_ShortMetrics */ - /* */ - /* <Description> */ - /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ - /* tables. */ - /* */ - typedef FT_Short TT_ShortMetrics; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_NameEntryRec */ - /* */ - /* <Description> */ - /* A structure modeling TrueType name records. Name records are used */ - /* to store important strings like family name, style name, */ - /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ - /* etc). */ - /* */ - /* <Fields> */ - /* platformID :: The ID of the name's encoding platform. */ - /* */ - /* encodingID :: The platform-specific ID for the name's encoding. */ - /* */ - /* languageID :: The platform-specific ID for the name's language. */ - /* */ - /* nameID :: The ID specifying what kind of name this is. */ - /* */ - /* stringLength :: The length of the string in bytes. */ - /* */ - /* stringOffset :: The offset to the string in the `name' table. */ - /* */ - /* string :: A pointer to the string's bytes. Note that these */ - /* are usually UTF-16 encoded characters. */ - /* */ - typedef struct TT_NameEntryRec_ - { - FT_UShort platformID; - FT_UShort encodingID; - FT_UShort languageID; - FT_UShort nameID; - FT_UShort stringLength; - FT_ULong stringOffset; - - /* this last field is not defined in the spec */ - /* but used by the FreeType engine */ - - FT_Byte* string; - - } TT_NameEntryRec, *TT_NameEntry; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_NameTableRec */ - /* */ - /* <Description> */ - /* A structure modeling the TrueType name table. */ - /* */ - /* <Fields> */ - /* format :: The format of the name table. */ - /* */ - /* numNameRecords :: The number of names in table. */ - /* */ - /* storageOffset :: The offset of the name table in the `name' */ - /* TrueType table. */ - /* */ - /* names :: An array of name records. */ - /* */ - /* stream :: the file's input stream. */ - /* */ - typedef struct TT_NameTableRec_ - { - FT_UShort format; - FT_UInt numNameRecords; - FT_UInt storageOffset; - TT_NameEntryRec* names; - FT_Stream stream; - - } TT_NameTableRec, *TT_NameTable; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_GaspRangeRec */ - /* */ - /* <Description> */ - /* A tiny structure used to model a gasp range according to the */ - /* TrueType specification. */ - /* */ - /* <Fields> */ - /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ - /* */ - /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ - /* modes to be used. */ - /* */ - typedef struct TT_GaspRangeRec_ - { - FT_UShort maxPPEM; - FT_UShort gaspFlag; - - } TT_GaspRangeRec, *TT_GaspRange; - - -#define TT_GASP_GRIDFIT 0x01 -#define TT_GASP_DOGRAY 0x02 - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_GaspRec */ - /* */ - /* <Description> */ - /* A structure modeling the TrueType `gasp' table used to specify */ - /* grid-fitting and anti-aliasing behaviour. */ - /* */ - /* <Fields> */ - /* version :: The version number. */ - /* */ - /* numRanges :: The number of gasp ranges in table. */ - /* */ - /* gaspRanges :: An array of gasp ranges. */ - /* */ - typedef struct TT_Gasp_ - { - FT_UShort version; - FT_UShort numRanges; - TT_GaspRange gaspRanges; - - } TT_GaspRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** EMBEDDED BITMAPS SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_MetricsRec */ - /* */ - /* <Description> */ - /* A structure used to hold the big metrics of a given glyph bitmap */ - /* in a TrueType or OpenType font. These are usually found in the */ - /* `EBDT' (Microsoft) or `bloc' (Apple) table. */ - /* */ - /* <Fields> */ - /* height :: The glyph height in pixels. */ - /* */ - /* width :: The glyph width in pixels. */ - /* */ - /* horiBearingX :: The horizontal left bearing. */ - /* */ - /* horiBearingY :: The horizontal top bearing. */ - /* */ - /* horiAdvance :: The horizontal advance. */ - /* */ - /* vertBearingX :: The vertical left bearing. */ - /* */ - /* vertBearingY :: The vertical top bearing. */ - /* */ - /* vertAdvance :: The vertical advance. */ - /* */ - typedef struct TT_SBit_MetricsRec_ - { - FT_Byte height; - FT_Byte width; - - FT_Char horiBearingX; - FT_Char horiBearingY; - FT_Byte horiAdvance; - - FT_Char vertBearingX; - FT_Char vertBearingY; - FT_Byte vertAdvance; - - } TT_SBit_MetricsRec, *TT_SBit_Metrics; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_SmallMetricsRec */ - /* */ - /* <Description> */ - /* A structure used to hold the small metrics of a given glyph bitmap */ - /* in a TrueType or OpenType font. These are usually found in the */ - /* `EBDT' (Microsoft) or the `bdat' (Apple) table. */ - /* */ - /* <Fields> */ - /* height :: The glyph height in pixels. */ - /* */ - /* width :: The glyph width in pixels. */ - /* */ - /* bearingX :: The left-side bearing. */ - /* */ - /* bearingY :: The top-side bearing. */ - /* */ - /* advance :: The advance width or height. */ - /* */ - typedef struct TT_SBit_Small_Metrics_ - { - FT_Byte height; - FT_Byte width; - - FT_Char bearingX; - FT_Char bearingY; - FT_Byte advance; - - } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_LineMetricsRec */ - /* */ - /* <Description> */ - /* A structure used to describe the text line metrics of a given */ - /* bitmap strike, for either a horizontal or vertical layout. */ - /* */ - /* <Fields> */ - /* ascender :: The ascender in pixels. */ - /* */ - /* descender :: The descender in pixels. */ - /* */ - /* max_width :: The maximum glyph width in pixels. */ - /* */ - /* caret_slope_enumerator :: Rise of the caret slope, typically set */ - /* to 1 for non-italic fonts. */ - /* */ - /* caret_slope_denominator :: Rise of the caret slope, typically set */ - /* to 0 for non-italic fonts. */ - /* */ - /* caret_offset :: Offset in pixels to move the caret for */ - /* proper positioning. */ - /* */ - /* min_origin_SB :: Minimum of horiBearingX (resp. */ - /* vertBearingY). */ - /* min_advance_SB :: Minimum of */ - /* */ - /* horizontal advance - */ - /* ( horiBearingX + width ) */ - /* */ - /* resp. */ - /* */ - /* vertical advance - */ - /* ( vertBearingY + height ) */ - /* */ - /* max_before_BL :: Maximum of horiBearingY (resp. */ - /* vertBearingY). */ - /* */ - /* min_after_BL :: Minimum of */ - /* */ - /* horiBearingY - height */ - /* */ - /* resp. */ - /* */ - /* vertBearingX - width */ - /* */ - /* pads :: Unused (to make the size of the record */ - /* a multiple of 32 bits. */ - /* */ - typedef struct TT_SBit_LineMetricsRec_ - { - FT_Char ascender; - FT_Char descender; - FT_Byte max_width; - FT_Char caret_slope_numerator; - FT_Char caret_slope_denominator; - FT_Char caret_offset; - FT_Char min_origin_SB; - FT_Char min_advance_SB; - FT_Char max_before_BL; - FT_Char min_after_BL; - FT_Char pads[2]; - - } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_RangeRec */ - /* */ - /* <Description> */ - /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ - /* (Microsoft) or `bloc' (Apple) tables. */ - /* */ - /* <Fields> */ - /* first_glyph :: The first glyph index in the range. */ - /* */ - /* last_glyph :: The last glyph index in the range. */ - /* */ - /* index_format :: The format of index table. Valid values are 1 */ - /* to 5. */ - /* */ - /* image_format :: The format of `EBDT' image data. */ - /* */ - /* image_offset :: The offset to image data in `EBDT'. */ - /* */ - /* image_size :: For index formats 2 and 5. This is the size in */ - /* bytes of each glyph bitmap. */ - /* */ - /* big_metrics :: For index formats 2 and 5. This is the big */ - /* metrics for each glyph bitmap. */ - /* */ - /* num_glyphs :: For index formats 4 and 5. This is the number of */ - /* glyphs in the code array. */ - /* */ - /* glyph_offsets :: For index formats 1 and 3. */ - /* */ - /* glyph_codes :: For index formats 4 and 5. */ - /* */ - /* table_offset :: The offset of the index table in the `EBLC' */ - /* table. Only used during strike loading. */ - /* */ - typedef struct TT_SBit_RangeRec_ - { - FT_UShort first_glyph; - FT_UShort last_glyph; - - FT_UShort index_format; - FT_UShort image_format; - FT_ULong image_offset; - - FT_ULong image_size; - TT_SBit_MetricsRec metrics; - FT_ULong num_glyphs; - - FT_ULong* glyph_offsets; - FT_UShort* glyph_codes; - - FT_ULong table_offset; - - } TT_SBit_RangeRec, *TT_SBit_Range; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_StrikeRec */ - /* */ - /* <Description> */ - /* A structure used describe a given bitmap strike in the `EBLC' */ - /* (Microsoft) or `bloc' (Apple) tables. */ - /* */ - /* <Fields> */ - /* num_index_ranges :: The number of index ranges. */ - /* */ - /* index_ranges :: An array of glyph index ranges. */ - /* */ - /* color_ref :: Unused. `color_ref' is put in for future */ - /* enhancements, but these fields are already */ - /* in use by other platforms (e.g. Newton). */ - /* For details, please see */ - /* */ - /* http://fonts.apple.com/ */ - /* TTRefMan/RM06/Chap6bloc.html */ - /* */ - /* hori :: The line metrics for horizontal layouts. */ - /* */ - /* vert :: The line metrics for vertical layouts. */ - /* */ - /* start_glyph :: The lowest glyph index for this strike. */ - /* */ - /* end_glyph :: The highest glyph index for this strike. */ - /* */ - /* x_ppem :: The number of horizontal pixels per EM. */ - /* */ - /* y_ppem :: The number of vertical pixels per EM. */ - /* */ - /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ - /* and 8. */ - /* */ - /* flags :: Is this a vertical or horizontal strike? For */ - /* details, please see */ - /* */ - /* http://fonts.apple.com/ */ - /* TTRefMan/RM06/Chap6bloc.html */ - /* */ - typedef struct TT_SBit_StrikeRec_ - { - FT_Int num_ranges; - TT_SBit_Range sbit_ranges; - FT_ULong ranges_offset; - - FT_ULong color_ref; - - TT_SBit_LineMetricsRec hori; - TT_SBit_LineMetricsRec vert; - - FT_UShort start_glyph; - FT_UShort end_glyph; - - FT_Byte x_ppem; - FT_Byte y_ppem; - - FT_Byte bit_depth; - FT_Char flags; - - } TT_SBit_StrikeRec, *TT_SBit_Strike; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_ComponentRec */ - /* */ - /* <Description> */ - /* A simple structure to describe a compound sbit element. */ - /* */ - /* <Fields> */ - /* glyph_code :: The element's glyph index. */ - /* */ - /* x_offset :: The element's left bearing. */ - /* */ - /* y_offset :: The element's top bearing. */ - /* */ - typedef struct TT_SBit_ComponentRec_ - { - FT_UShort glyph_code; - FT_Char x_offset; - FT_Char y_offset; - - } TT_SBit_ComponentRec, *TT_SBit_Component; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_ScaleRec */ - /* */ - /* <Description> */ - /* A structure used describe a given bitmap scaling table, as defined */ - /* in the `EBSC' table. */ - /* */ - /* <Fields> */ - /* hori :: The horizontal line metrics. */ - /* */ - /* vert :: The vertical line metrics. */ - /* */ - /* x_ppem :: The number of horizontal pixels per EM. */ - /* */ - /* y_ppem :: The number of vertical pixels per EM. */ - /* */ - /* x_ppem_substitute :: Substitution x_ppem value. */ - /* */ - /* y_ppem_substitute :: Substitution y_ppem value. */ - /* */ - typedef struct TT_SBit_ScaleRec_ - { - TT_SBit_LineMetricsRec hori; - TT_SBit_LineMetricsRec vert; - - FT_Byte x_ppem; - FT_Byte y_ppem; - - FT_Byte x_ppem_substitute; - FT_Byte y_ppem_substitute; - - } TT_SBit_ScaleRec, *TT_SBit_Scale; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Post_20Rec */ - /* */ - /* <Description> */ - /* Postscript names sub-table, format 2.0. Stores the PS name of */ - /* each glyph in the font face. */ - /* */ - /* <Fields> */ - /* num_glyphs :: The number of named glyphs in the table. */ - /* */ - /* num_names :: The number of PS names stored in the table. */ - /* */ - /* glyph_indices :: The indices of the glyphs in the names arrays. */ - /* */ - /* glyph_names :: The PS names not in Mac Encoding. */ - /* */ - typedef struct TT_Post_20Rec_ - { - FT_UShort num_glyphs; - FT_UShort num_names; - FT_UShort* glyph_indices; - FT_Char** glyph_names; - - } TT_Post_20Rec, *TT_Post_20; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Post_25Rec */ - /* */ - /* <Description> */ - /* Postscript names sub-table, format 2.5. Stores the PS name of */ - /* each glyph in the font face. */ - /* */ - /* <Fields> */ - /* num_glyphs :: The number of glyphs in the table. */ - /* */ - /* offsets :: An array of signed offsets in a normal Mac */ - /* Postscript name encoding. */ - /* */ - typedef struct TT_Post_25_ - { - FT_UShort num_glyphs; - FT_Char* offsets; - - } TT_Post_25Rec, *TT_Post_25; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Post_NamesRec */ - /* */ - /* <Description> */ - /* Postscript names table, either format 2.0 or 2.5. */ - /* */ - /* <Fields> */ - /* loaded :: A flag to indicate whether the PS names are loaded. */ - /* */ - /* format_20 :: The sub-table used for format 2.0. */ - /* */ - /* format_25 :: The sub-table used for format 2.5. */ - /* */ - typedef struct TT_Post_NamesRec_ - { - FT_Bool loaded; - - union - { - TT_Post_20Rec format_20; - TT_Post_25Rec format_25; - - } names; - - } TT_Post_NamesRec, *TT_Post_Names; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** GX VARIATION TABLE SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - typedef struct GX_BlendRec_ *GX_Blend; -#endif - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** EMBEDDED BDF PROPERTIES TABLE SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * These types are used to support a `BDF ' table that isn't part of the - * official TrueType specification. It is mainly used in SFNT-based - * bitmap fonts that were generated from a set of BDF fonts. - * - * The format of the table is as follows. - * - * USHORT version `BDF ' table version number, should be 0x0001. - * USHORT strikeCount Number of strikes (bitmap sizes) in this table. - * ULONG stringTable Offset (from start of BDF table) to string - * table. - * - * This is followed by an array of `strikeCount' descriptors, having the - * following format. - * - * USHORT ppem Vertical pixels per EM for this strike. - * USHORT numItems Number of items for this strike (properties and - * atoms). Maximum is 255. - * - * This array in turn is followed by `strikeCount' value sets. Each - * `value set' is an array of `numItems' items with the following format. - * - * ULONG item_name Offset in string table to item name. - * USHORT item_type The item type. Possible values are - * 0 => string (e.g., COMMENT) - * 1 => atom (e.g., FONT or even SIZE) - * 2 => int32 - * 3 => uint32 - * 0x10 => A flag to indicate a properties. This - * is ORed with the above values. - * ULONG item_value For strings => Offset into string table without - * the corresponding double quotes. - * For atoms => Offset into string table. - * For integers => Direct value. - * - * All strings in the string table consist of bytes and are - * zero-terminated. - * - */ - -#ifdef TT_CONFIG_OPTION_BDF - - typedef struct TT_BDFRec_ - { - FT_Byte* table; - FT_Byte* table_end; - FT_Byte* strings; - FT_ULong strings_size; - FT_UInt num_strikes; - FT_Bool loaded; - - } TT_BDFRec, *TT_BDF; - -#endif /* TT_CONFIG_OPTION_BDF */ - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** ORIGINAL TT_FACE CLASS DEFINITION ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This structure/class is defined here because it is common to the */ - /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ - /* */ - /* Note, however, that the classes TT_Size and TT_GlyphSlot are not */ - /* shared between font drivers, and are thus defined in `ttobjs.h'. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_Face */ - /* */ - /* <Description> */ - /* A handle to a TrueType face/font object. A TT_Face encapsulates */ - /* the resolution and scaling independent parts of a TrueType font */ - /* resource. */ - /* */ - /* <Note> */ - /* The TT_Face structure is also used as a `parent class' for the */ - /* OpenType-CFF class (T2_Face). */ - /* */ - typedef struct TT_FaceRec_* TT_Face; - - - /* a function type used for the truetype bytecode interpreter hooks */ - typedef FT_Error - (*TT_Interpreter)( void* exec_context ); - - /* forward declaration */ - typedef struct TT_LoaderRec_* TT_Loader; - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Loader_GotoTableFunc */ - /* */ - /* <Description> */ - /* Seeks a stream to the start of a given TrueType table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* tag :: A 4-byte tag used to name the table. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Output> */ - /* length :: The length of the table in bytes. Set to 0 if not */ - /* needed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The stream cursor must be at the font file's origin. */ - /* */ - typedef FT_Error - (*TT_Loader_GotoTableFunc)( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Loader_StartGlyphFunc */ - /* */ - /* <Description> */ - /* Seeks a stream to the start of a given glyph element, and opens a */ - /* frame for it. */ - /* */ - /* <Input> */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - /* glyph index :: The index of the glyph to access. */ - /* */ - /* offset :: The offset of the glyph according to the */ - /* `locations' table. */ - /* */ - /* byte_count :: The size of the frame in bytes. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* This function is normally equivalent to FT_STREAM_SEEK(offset) */ - /* followed by FT_FRAME_ENTER(byte_count) with the loader's stream, */ - /* but alternative formats (e.g. compressed ones) might use something */ - /* different. */ - /* */ - typedef FT_Error - (*TT_Loader_StartGlyphFunc)( TT_Loader loader, - FT_UInt glyph_index, - FT_ULong offset, - FT_UInt byte_count ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Loader_ReadGlyphFunc */ - /* */ - /* <Description> */ - /* Reads one glyph element (its header, a simple glyph, or a */ - /* composite) from the loader's current stream frame. */ - /* */ - /* <Input> */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - typedef FT_Error - (*TT_Loader_ReadGlyphFunc)( TT_Loader loader ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Loader_EndGlyphFunc */ - /* */ - /* <Description> */ - /* Closes the current loader stream frame for the glyph. */ - /* */ - /* <Input> */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - typedef void - (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); - - - /*************************************************************************/ - /* */ - /* TrueType Face Type */ - /* */ - /* <Struct> */ - /* TT_Face */ - /* */ - /* <Description> */ - /* The TrueType face class. These objects model the resolution and */ - /* point-size independent data found in a TrueType font file. */ - /* */ - /* <Fields> */ - /* root :: The base FT_Face structure, managed by the */ - /* base layer. */ - /* */ - /* ttc_header :: The TrueType collection header, used when */ - /* the file is a `ttc' rather than a `ttf'. */ - /* For ordinary font files, the field */ - /* `ttc_header.count' is set to 0. */ - /* */ - /* format_tag :: The font format tag. */ - /* */ - /* num_tables :: The number of TrueType tables in this font */ - /* file. */ - /* */ - /* dir_tables :: The directory of TrueType tables for this */ - /* font file. */ - /* */ - /* header :: The font's font header (`head' table). */ - /* Read on font opening. */ - /* */ - /* horizontal :: The font's horizontal header (`hhea' */ - /* table). This field also contains the */ - /* associated horizontal metrics table */ - /* (`hmtx'). */ - /* */ - /* max_profile :: The font's maximum profile table. Read on */ - /* font opening. Note that some maximum */ - /* values cannot be taken directly from this */ - /* table. We thus define additional fields */ - /* below to hold the computed maxima. */ - /* */ - /* vertical_info :: A boolean which is set when the font file */ - /* contains vertical metrics. If not, the */ - /* value of the `vertical' field is */ - /* undefined. */ - /* */ - /* vertical :: The font's vertical header (`vhea' table). */ - /* This field also contains the associated */ - /* vertical metrics table (`vmtx'), if found. */ - /* IMPORTANT: The contents of this field is */ - /* undefined if the `verticalInfo' field is */ - /* unset. */ - /* */ - /* num_names :: The number of name records within this */ - /* TrueType font. */ - /* */ - /* name_table :: The table of name records (`name'). */ - /* */ - /* os2 :: The font's OS/2 table (`OS/2'). */ - /* */ - /* postscript :: The font's PostScript table (`post' */ - /* table). The PostScript glyph names are */ - /* not loaded by the driver on face opening. */ - /* See the `ttpost' module for more details. */ - /* */ - /* cmap_table :: Address of the face's `cmap' SFNT table */ - /* in memory (it's an extracted frame). */ - /* */ - /* cmap_size :: The size in bytes of the `cmap_table' */ - /* described above. */ - /* */ - /* goto_table :: A function called by each TrueType table */ - /* loader to position a stream's cursor to */ - /* the start of a given table according to */ - /* its tag. It defaults to TT_Goto_Face but */ - /* can be different for strange formats (e.g. */ - /* Type 42). */ - /* */ - /* access_glyph_frame :: A function used to access the frame of a */ - /* given glyph within the face's font file. */ - /* */ - /* forget_glyph_frame :: A function used to forget the frame of a */ - /* given glyph when all data has been loaded. */ - /* */ - /* read_glyph_header :: A function used to read a glyph header. */ - /* It must be called between an `access' and */ - /* `forget'. */ - /* */ - /* read_simple_glyph :: A function used to read a simple glyph. */ - /* It must be called after the header was */ - /* read, and before the `forget'. */ - /* */ - /* read_composite_glyph :: A function used to read a composite glyph. */ - /* It must be called after the header was */ - /* read, and before the `forget'. */ - /* */ - /* sfnt :: A pointer to the SFNT service. */ - /* */ - /* psnames :: A pointer to the PostScript names service. */ - /* */ - /* hdmx :: The face's horizontal device metrics */ - /* (`hdmx' table). This table is optional in */ - /* TrueType/OpenType fonts. */ - /* */ - /* gasp :: The grid-fitting and scaling properties */ - /* table (`gasp'). This table is optional in */ - /* TrueType/OpenType fonts. */ - /* */ - /* pclt :: The `pclt' SFNT table. */ - /* */ - /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ - /* sizes, embedded in this font. */ - /* */ - /* sbit_strikes :: An array of sbit strikes embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ - /* num_sbit_scales :: The number of sbit scales for this font. */ - /* */ - /* sbit_scales :: Array of sbit scales embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ - /* postscript_names :: A table used to store the Postscript names */ - /* of the glyphs for this font. See the */ - /* file `ttconfig.h' for comments on the */ - /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ - /* */ - /* num_locations :: The number of glyph locations in this */ - /* TrueType file. This should be */ - /* identical to the number of glyphs. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* glyph_locations :: An array of longs. These are offsets to */ - /* glyph data within the `glyf' table. */ - /* Ignored for Type 2 font faces. */ - /* */ - /* glyf_len :: The length of the `glyf' table. Needed */ - /* for malformed `loca' tables. */ - /* */ - /* font_program_size :: Size in bytecodes of the face's font */ - /* program. 0 if none defined. Ignored for */ - /* Type 2 fonts. */ - /* */ - /* font_program :: The face's font program (bytecode stream) */ - /* executed at load time, also used during */ - /* glyph rendering. Comes from the `fpgm' */ - /* table. Ignored for Type 2 font fonts. */ - /* */ - /* cvt_program_size :: The size in bytecodes of the face's cvt */ - /* program. Ignored for Type 2 fonts. */ - /* */ - /* cvt_program :: The face's cvt program (bytecode stream) */ - /* executed each time an instance/size is */ - /* changed/reset. Comes from the `prep' */ - /* table. Ignored for Type 2 fonts. */ - /* */ - /* cvt_size :: Size of the control value table (in */ - /* entries). Ignored for Type 2 fonts. */ - /* */ - /* cvt :: The face's original control value table. */ - /* Coordinates are expressed in unscaled font */ - /* units. Comes from the `cvt ' table. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* num_kern_pairs :: The number of kerning pairs present in the */ - /* font file. The engine only loads the */ - /* first horizontal format 0 kern table it */ - /* finds in the font file. Ignored for */ - /* Type 2 fonts. */ - /* */ - /* kern_table_index :: The index of the kerning table in the font */ - /* kerning directory. Ignored for Type 2 */ - /* fonts. */ - /* */ - /* interpreter :: A pointer to the TrueType bytecode */ - /* interpreters field is also used to hook */ - /* the debugger in `ttdebug'. */ - /* */ - /* unpatented_hinting :: If true, use only unpatented methods in */ - /* the bytecode interpreter. */ - /* */ - /* doblend :: A boolean which is set if the font should */ - /* be blended (this is for GX var). */ - /* */ - /* blend :: Contains the data needed to control GX */ - /* variation tables (rather like Multiple */ - /* Master data). */ - /* */ - /* extra :: Reserved for third-party font drivers. */ - /* */ - /* postscript_name :: The PS name of the font. Used by the */ - /* postscript name service. */ - /* */ - typedef struct TT_FaceRec_ - { - FT_FaceRec root; - - TTC_HeaderRec ttc_header; - - FT_ULong format_tag; - FT_UShort num_tables; - TT_Table dir_tables; - - TT_Header header; /* TrueType header table */ - TT_HoriHeader horizontal; /* TrueType horizontal header */ - - TT_MaxProfile max_profile; - - FT_Bool vertical_info; - TT_VertHeader vertical; /* TT Vertical header, if present */ - - FT_UShort num_names; /* number of name records */ - TT_NameTableRec name_table; /* name table */ - - TT_OS2 os2; /* TrueType OS/2 table */ - TT_Postscript postscript; /* TrueType Postscript table */ - - FT_Byte* cmap_table; /* extracted `cmap' table */ - FT_ULong cmap_size; - - TT_Loader_GotoTableFunc goto_table; - - TT_Loader_StartGlyphFunc access_glyph_frame; - TT_Loader_EndGlyphFunc forget_glyph_frame; - TT_Loader_ReadGlyphFunc read_glyph_header; - TT_Loader_ReadGlyphFunc read_simple_glyph; - TT_Loader_ReadGlyphFunc read_composite_glyph; - - /* a typeless pointer to the SFNT_Interface table used to load */ - /* the basic TrueType tables in the face object */ - void* sfnt; - - /* a typeless pointer to the FT_Service_PsCMapsRec table used to */ - /* handle glyph names <-> unicode & Mac values */ - void* psnames; - - - /***********************************************************************/ - /* */ - /* Optional TrueType/OpenType tables */ - /* */ - /***********************************************************************/ - - /* grid-fitting and scaling table */ - TT_GaspRec gasp; /* the `gasp' table */ - - /* PCL 5 table */ - TT_PCLT pclt; - - /* embedded bitmaps support */ - FT_ULong num_sbit_scales; - TT_SBit_Scale sbit_scales; - - /* postscript names table */ - TT_Post_NamesRec postscript_names; - - - /***********************************************************************/ - /* */ - /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ - /* */ - /***********************************************************************/ - - /* the font program, if any */ - FT_ULong font_program_size; - FT_Byte* font_program; - - /* the cvt program, if any */ - FT_ULong cvt_program_size; - FT_Byte* cvt_program; - - /* the original, unscaled, control value table */ - FT_ULong cvt_size; - FT_Short* cvt; - - /* A pointer to the bytecode interpreter to use. This is also */ - /* used to hook the debugger for the `ttdebug' utility. */ - TT_Interpreter interpreter; - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Use unpatented hinting only. */ - FT_Bool unpatented_hinting; -#endif - - /***********************************************************************/ - /* */ - /* Other tables or fields. This is used by derivative formats like */ - /* OpenType. */ - /* */ - /***********************************************************************/ - - FT_Generic extra; - - const char* postscript_name; - - FT_ULong glyf_len; - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Bool doblend; - GX_Blend blend; -#endif - - /* since version 2.2 */ - - FT_Byte* horz_metrics; - FT_ULong horz_metrics_size; - - FT_Byte* vert_metrics; - FT_ULong vert_metrics_size; - - FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ - FT_Byte* glyph_locations; - - FT_Byte* hdmx_table; - FT_ULong hdmx_table_size; - FT_UInt hdmx_record_count; - FT_ULong hdmx_record_size; - FT_Byte* hdmx_record_sizes; - - FT_Byte* sbit_table; - FT_ULong sbit_table_size; - FT_UInt sbit_num_strikes; - - FT_Byte* kern_table; - FT_ULong kern_table_size; - FT_UInt num_kern_tables; - FT_UInt32 kern_avail_bits; - FT_UInt32 kern_order_bits; - -#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; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* since 2.4.12 */ - FT_ULong sph_found_func_flags; /* special functions found */ - /* for this face */ - FT_Bool sph_compatibility_mode; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - } TT_FaceRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_GlyphZoneRec */ - /* */ - /* <Description> */ - /* A glyph zone is used to load, scale and hint glyph outline */ - /* coordinates. */ - /* */ - /* <Fields> */ - /* memory :: A handle to the memory manager. */ - /* */ - /* max_points :: The maximum size in points of the zone. */ - /* */ - /* max_contours :: Max size in links contours of the zone. */ - /* */ - /* n_points :: The current number of points in the zone. */ - /* */ - /* n_contours :: The current number of contours in the zone. */ - /* */ - /* org :: The original glyph coordinates (font */ - /* units/scaled). */ - /* */ - /* cur :: The current glyph coordinates (scaled/hinted). */ - /* */ - /* tags :: The point control tags. */ - /* */ - /* 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_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_UShort first_point; /* offset of first (#0) point */ - - } TT_GlyphZoneRec, *TT_GlyphZone; - - - /* handle to execution context */ - typedef struct TT_ExecContextRec_* TT_ExecContext; - - /* glyph loader structure */ - typedef struct TT_LoaderRec_ - { - FT_Face face; - FT_Size size; - FT_GlyphSlot glyph; - FT_GlyphLoader gloader; - - FT_ULong load_flags; - FT_UInt glyph_index; - - FT_Stream stream; - FT_Int byte_len; - - FT_Short n_contours; - FT_BBox bbox; - FT_Int left_bearing; - FT_Int advance; - FT_Int linear; - FT_Bool linear_def; - FT_Bool preserve_pps; - FT_Vector pp1; - FT_Vector pp2; - - FT_ULong glyf_offset; - - /* the zone where we load our glyphs */ - TT_GlyphZoneRec base; - TT_GlyphZoneRec zone; - - TT_ExecContext exec; - FT_Byte* instructions; - FT_ULong ins_pos; - - /* for possible extensibility in other formats */ - void* other; - - /* since version 2.1.8 */ - FT_Int top_bearing; - FT_Int vadvance; - FT_Vector pp3; - FT_Vector pp4; - - /* since version 2.2.1 */ - FT_Byte* cursor; - FT_Byte* limit; - - } TT_LoaderRec; - - -FT_END_HEADER - -#endif /* __TTTYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/t1tables.h b/drivers/freetype/freetype/include/freetype/t1tables.h deleted file mode 100644 index a14255e5f5..0000000000 --- a/drivers/freetype/freetype/include/freetype/t1tables.h +++ /dev/null @@ -1,662 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1tables.h */ -/* */ -/* Basic Type 1/Type 2 tables definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011 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 __T1TABLES_H__ -#define __T1TABLES_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* type1_tables */ - /* */ - /* <Title> */ - /* Type 1 Tables */ - /* */ - /* <Abstract> */ - /* Type~1 (PostScript) specific font tables. */ - /* */ - /* <Description> */ - /* This section contains the definition of Type 1-specific tables, */ - /* including structures related to other PostScript font formats. */ - /* */ - /*************************************************************************/ - - - /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ - /* structures in order to support Multiple Master fonts. */ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_FontInfoRec */ - /* */ - /* <Description> */ - /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ - /* Note that for Multiple Master fonts, each instance has its own */ - /* FontInfo dictionary. */ - /* */ - typedef struct PS_FontInfoRec_ - { - FT_String* version; - FT_String* notice; - FT_String* full_name; - FT_String* family_name; - FT_String* weight; - FT_Long italic_angle; - FT_Bool is_fixed_pitch; - FT_Short underline_position; - FT_UShort underline_thickness; - - } PS_FontInfoRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_FontInfo */ - /* */ - /* <Description> */ - /* A handle to a @PS_FontInfoRec structure. */ - /* */ - typedef struct PS_FontInfoRec_* PS_FontInfo; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* T1_FontInfo */ - /* */ - /* <Description> */ - /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ - /* kept to maintain source compatibility between various versions of */ - /* FreeType. */ - /* */ - typedef PS_FontInfoRec T1_FontInfo; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_PrivateRec */ - /* */ - /* <Description> */ - /* A structure used to model a Type~1 or Type~2 private dictionary. */ - /* Note that for Multiple Master fonts, each instance has its own */ - /* Private dictionary. */ - /* */ - typedef struct PS_PrivateRec_ - { - FT_Int unique_id; - FT_Int lenIV; - - FT_Byte num_blue_values; - FT_Byte num_other_blues; - FT_Byte num_family_blues; - FT_Byte num_family_other_blues; - - FT_Short blue_values[14]; - FT_Short other_blues[10]; - - FT_Short family_blues [14]; - FT_Short family_other_blues[10]; - - FT_Fixed blue_scale; - FT_Int blue_shift; - FT_Int blue_fuzz; - - FT_UShort standard_width[1]; - FT_UShort standard_height[1]; - - FT_Byte num_snap_widths; - FT_Byte num_snap_heights; - FT_Bool force_bold; - FT_Bool round_stem_up; - - FT_Short snap_widths [13]; /* including std width */ - FT_Short snap_heights[13]; /* including std height */ - - FT_Fixed expansion_factor; - - FT_Long language_group; - FT_Long password; - - FT_Short min_feature[2]; - - } PS_PrivateRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_Private */ - /* */ - /* <Description> */ - /* A handle to a @PS_PrivateRec structure. */ - /* */ - typedef struct PS_PrivateRec_* PS_Private; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* T1_Private */ - /* */ - /* <Description> */ - /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ - /* kept to maintain source compatibility between various versions of */ - /* FreeType. */ - /* */ - typedef PS_PrivateRec T1_Private; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* T1_Blend_Flags */ - /* */ - /* <Description> */ - /* A set of flags used to indicate which fields are present in a */ - /* given blend dictionary (font info or private). Used to support */ - /* Multiple Masters fonts. */ - /* */ - typedef enum T1_Blend_Flags_ - { - /*# required fields in a FontInfo blend dictionary */ - T1_BLEND_UNDERLINE_POSITION = 0, - T1_BLEND_UNDERLINE_THICKNESS, - T1_BLEND_ITALIC_ANGLE, - - /*# required fields in a Private blend dictionary */ - T1_BLEND_BLUE_VALUES, - T1_BLEND_OTHER_BLUES, - T1_BLEND_STANDARD_WIDTH, - T1_BLEND_STANDARD_HEIGHT, - T1_BLEND_STEM_SNAP_WIDTHS, - T1_BLEND_STEM_SNAP_HEIGHTS, - T1_BLEND_BLUE_SCALE, - T1_BLEND_BLUE_SHIFT, - T1_BLEND_FAMILY_BLUES, - T1_BLEND_FAMILY_OTHER_BLUES, - T1_BLEND_FORCE_BOLD, - - /*# never remove */ - T1_BLEND_MAX - - } T1_Blend_Flags; - - /* */ - - - /*# backwards compatible definitions */ -#define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION -#define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS -#define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE -#define t1_blend_blue_values T1_BLEND_BLUE_VALUES -#define t1_blend_other_blues T1_BLEND_OTHER_BLUES -#define t1_blend_standard_widths T1_BLEND_STANDARD_WIDTH -#define t1_blend_standard_height T1_BLEND_STANDARD_HEIGHT -#define t1_blend_stem_snap_widths T1_BLEND_STEM_SNAP_WIDTHS -#define t1_blend_stem_snap_heights T1_BLEND_STEM_SNAP_HEIGHTS -#define t1_blend_blue_scale T1_BLEND_BLUE_SCALE -#define t1_blend_blue_shift T1_BLEND_BLUE_SHIFT -#define t1_blend_family_blues T1_BLEND_FAMILY_BLUES -#define t1_blend_family_other_blues T1_BLEND_FAMILY_OTHER_BLUES -#define t1_blend_force_bold T1_BLEND_FORCE_BOLD -#define t1_blend_max T1_BLEND_MAX - - - /* maximum number of Multiple Masters designs, as defined in the spec */ -#define T1_MAX_MM_DESIGNS 16 - - /* maximum number of Multiple Masters axes, as defined in the spec */ -#define T1_MAX_MM_AXIS 4 - - /* maximum number of elements in a design map */ -#define T1_MAX_MM_MAP_POINTS 20 - - - /* this structure is used to store the BlendDesignMap entry for an axis */ - typedef struct PS_DesignMap_ - { - FT_Byte num_points; - FT_Long* design_points; - FT_Fixed* blend_points; - - } PS_DesignMapRec, *PS_DesignMap; - - /* backwards-compatible definition */ - typedef PS_DesignMapRec T1_DesignMap; - - - typedef struct PS_BlendRec_ - { - FT_UInt num_designs; - FT_UInt num_axis; - - FT_String* axis_names[T1_MAX_MM_AXIS]; - FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; - PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; - - FT_Fixed* weight_vector; - FT_Fixed* default_weight_vector; - - PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; - PS_Private privates [T1_MAX_MM_DESIGNS + 1]; - - FT_ULong blend_bitflags; - - 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; - - - /* backwards-compatible definition */ - typedef PS_BlendRec T1_Blend; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FaceDictRec */ - /* */ - /* <Description> */ - /* A structure used to represent data in a CID top-level dictionary. */ - /* */ - typedef struct CID_FaceDictRec_ - { - PS_PrivateRec private_dict; - - FT_UInt len_buildchar; - FT_Fixed forcebold_threshold; - FT_Pos stroke_width; - FT_Fixed expansion_factor; - - FT_Byte paint_type; - FT_Byte font_type; - FT_Matrix font_matrix; - FT_Vector font_offset; - - FT_UInt num_subrs; - FT_ULong subrmap_offset; - FT_Int sd_bytes; - - } CID_FaceDictRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FaceDict */ - /* */ - /* <Description> */ - /* A handle to a @CID_FaceDictRec structure. */ - /* */ - typedef struct CID_FaceDictRec_* CID_FaceDict; - - /* */ - - - /* backwards-compatible definition */ - typedef CID_FaceDictRec CID_FontDict; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FaceInfoRec */ - /* */ - /* <Description> */ - /* A structure used to represent CID Face information. */ - /* */ - typedef struct CID_FaceInfoRec_ - { - FT_String* cid_font_name; - FT_Fixed cid_version; - FT_Int cid_font_type; - - FT_String* registry; - FT_String* ordering; - FT_Int supplement; - - PS_FontInfoRec font_info; - FT_BBox font_bbox; - FT_ULong uid_base; - - FT_Int num_xuid; - FT_ULong xuid[16]; - - FT_ULong cidmap_offset; - FT_Int fd_bytes; - FT_Int gd_bytes; - FT_ULong cid_count; - - FT_Int num_dicts; - CID_FaceDict font_dicts; - - FT_ULong data_offset; - - } CID_FaceInfoRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FaceInfo */ - /* */ - /* <Description> */ - /* A handle to a @CID_FaceInfoRec structure. */ - /* */ - typedef struct CID_FaceInfoRec_* CID_FaceInfo; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_Info */ - /* */ - /* <Description> */ - /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ - /* kept to maintain source compatibility between various versions of */ - /* FreeType. */ - /* */ - typedef CID_FaceInfoRec CID_Info; - - - /************************************************************************ - * - * @function: - * FT_Has_PS_Glyph_Names - * - * @description: - * Return true if a given face provides reliable PostScript glyph - * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, - * except that certain fonts (mostly TrueType) contain incorrect - * glyph name tables. - * - * When this function returns true, the caller is sure that the glyph - * names returned by @FT_Get_Glyph_Name are reliable. - * - * @input: - * face :: - * face handle - * - * @return: - * Boolean. True if glyph names are reliable. - * - */ - FT_EXPORT( FT_Int ) - FT_Has_PS_Glyph_Names( FT_Face face ); - - - /************************************************************************ - * - * @function: - * FT_Get_PS_Font_Info - * - * @description: - * Retrieve the @PS_FontInfoRec structure corresponding to a given - * PostScript font. - * - * @input: - * face :: - * PostScript face handle. - * - * @output: - * afont_info :: - * Output font info structure pointer. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The string pointers within the font info structure are owned by - * the face and don't need to be freed by the caller. - * - * If the font's format is not PostScript-based, this function will - * return the `FT_Err_Invalid_Argument' error code. - * - */ - FT_EXPORT( FT_Error ) - FT_Get_PS_Font_Info( FT_Face face, - PS_FontInfo afont_info ); - - - /************************************************************************ - * - * @function: - * FT_Get_PS_Font_Private - * - * @description: - * Retrieve the @PS_PrivateRec structure corresponding to a given - * PostScript font. - * - * @input: - * face :: - * PostScript face handle. - * - * @output: - * afont_private :: - * Output private dictionary structure pointer. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The string pointers within the @PS_PrivateRec structure are owned by - * the face and don't need to be freed by the caller. - * - * If the font's format is not PostScript-based, this function returns - * the `FT_Err_Invalid_Argument' error code. - * - */ - FT_EXPORT( FT_Error ) - FT_Get_PS_Font_Private( FT_Face face, - PS_Private afont_private ); - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* T1_EncodingType */ - /* */ - /* <Description> */ - /* An enumeration describing the `Encoding' entry in a Type 1 */ - /* dictionary. */ - /* */ - typedef enum T1_EncodingType_ - { - T1_ENCODING_TYPE_NONE = 0, - T1_ENCODING_TYPE_ARRAY, - T1_ENCODING_TYPE_STANDARD, - T1_ENCODING_TYPE_ISOLATIN1, - T1_ENCODING_TYPE_EXPERT - - } T1_EncodingType; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* PS_Dict_Keys */ - /* */ - /* <Description> */ - /* An enumeration used in calls to @FT_Get_PS_Font_Value to identify */ - /* the Type~1 dictionary entry to retrieve. */ - /* */ - typedef enum PS_Dict_Keys_ - { - /* conventionally in the font dictionary */ - PS_DICT_FONT_TYPE, /* FT_Byte */ - PS_DICT_FONT_MATRIX, /* FT_Fixed */ - PS_DICT_FONT_BBOX, /* FT_Fixed */ - PS_DICT_PAINT_TYPE, /* FT_Byte */ - PS_DICT_FONT_NAME, /* FT_String* */ - PS_DICT_UNIQUE_ID, /* FT_Int */ - PS_DICT_NUM_CHAR_STRINGS, /* FT_Int */ - PS_DICT_CHAR_STRING_KEY, /* FT_String* */ - PS_DICT_CHAR_STRING, /* FT_String* */ - PS_DICT_ENCODING_TYPE, /* T1_EncodingType */ - PS_DICT_ENCODING_ENTRY, /* FT_String* */ - - /* conventionally in the font Private dictionary */ - PS_DICT_NUM_SUBRS, /* FT_Int */ - PS_DICT_SUBR, /* FT_String* */ - PS_DICT_STD_HW, /* FT_UShort */ - PS_DICT_STD_VW, /* FT_UShort */ - PS_DICT_NUM_BLUE_VALUES, /* FT_Byte */ - PS_DICT_BLUE_VALUE, /* FT_Short */ - PS_DICT_BLUE_FUZZ, /* FT_Int */ - PS_DICT_NUM_OTHER_BLUES, /* FT_Byte */ - PS_DICT_OTHER_BLUE, /* FT_Short */ - PS_DICT_NUM_FAMILY_BLUES, /* FT_Byte */ - PS_DICT_FAMILY_BLUE, /* FT_Short */ - PS_DICT_NUM_FAMILY_OTHER_BLUES, /* FT_Byte */ - PS_DICT_FAMILY_OTHER_BLUE, /* FT_Short */ - PS_DICT_BLUE_SCALE, /* FT_Fixed */ - PS_DICT_BLUE_SHIFT, /* FT_Int */ - PS_DICT_NUM_STEM_SNAP_H, /* FT_Byte */ - PS_DICT_STEM_SNAP_H, /* FT_Short */ - PS_DICT_NUM_STEM_SNAP_V, /* FT_Byte */ - PS_DICT_STEM_SNAP_V, /* FT_Short */ - PS_DICT_FORCE_BOLD, /* FT_Bool */ - PS_DICT_RND_STEM_UP, /* FT_Bool */ - PS_DICT_MIN_FEATURE, /* FT_Short */ - PS_DICT_LEN_IV, /* FT_Int */ - PS_DICT_PASSWORD, /* FT_Long */ - PS_DICT_LANGUAGE_GROUP, /* FT_Long */ - - /* conventionally in the font FontInfo dictionary */ - PS_DICT_VERSION, /* FT_String* */ - PS_DICT_NOTICE, /* FT_String* */ - PS_DICT_FULL_NAME, /* FT_String* */ - PS_DICT_FAMILY_NAME, /* FT_String* */ - PS_DICT_WEIGHT, /* FT_String* */ - PS_DICT_IS_FIXED_PITCH, /* FT_Bool */ - PS_DICT_UNDERLINE_POSITION, /* FT_Short */ - PS_DICT_UNDERLINE_THICKNESS, /* FT_UShort */ - PS_DICT_FS_TYPE, /* FT_UShort */ - PS_DICT_ITALIC_ANGLE, /* FT_Long */ - - PS_DICT_MAX = PS_DICT_ITALIC_ANGLE - - } PS_Dict_Keys; - - - /************************************************************************ - * - * @function: - * FT_Get_PS_Font_Value - * - * @description: - * Retrieve the value for the supplied key from a PostScript font. - * - * @input: - * face :: - * PostScript face handle. - * - * key :: - * An enumeration value representing the dictionary key to retrieve. - * - * idx :: - * For array values, this specifies the index to be returned. - * - * value :: - * A pointer to memory into which to write the value. - * - * valen_len :: - * The size, in bytes, of the memory supplied for the value. - * - * @output: - * value :: - * The value matching the above key, if it exists. - * - * @return: - * The amount of memory (in bytes) required to hold the requested - * value (if it exists, -1 otherwise). - * - * @note: - * The values returned are not pointers into the internal structures of - * the face, but are `fresh' copies, so that the memory containing them - * belongs to the calling application. This also enforces the - * `read-only' nature of these values, i.e., this function cannot be - * used to manipulate the face. - * - * `value' is a void pointer because the values returned can be of - * various types. - * - * If either `value' is NULL or `value_len' is too small, just the - * required memory size for the requested entry is returned. - * - * The `idx' parameter is used, not only to retrieve elements of, for - * example, the FontMatrix or FontBBox, but also to retrieve name keys - * from the CharStrings dictionary, and the charstrings themselves. It - * is ignored for atomic values. - * - * PS_DICT_BLUE_SCALE returns a value that is scaled up by 1000. To - * get the value as in the font stream, you need to divide by - * 65536000.0 (to remove the FT_Fixed scale, and the x1000 scale). - * - * IMPORTANT: Only key/value pairs read by the FreeType interpreter can - * be retrieved. So, for example, PostScript procedures such as NP, - * ND, and RD are not available. Arbitrary keys are, obviously, not be - * available either. - * - * If the font's format is not PostScript-based, this function returns - * the `FT_Err_Invalid_Argument' error code. - * - */ - FT_EXPORT( FT_Long ) - FT_Get_PS_Font_Value( FT_Face face, - PS_Dict_Keys key, - FT_UInt idx, - void *value, - FT_Long value_len ); - - /* */ - -FT_END_HEADER - -#endif /* __T1TABLES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ttnameid.h b/drivers/freetype/freetype/include/freetype/ttnameid.h deleted file mode 100644 index 173f88c950..0000000000 --- a/drivers/freetype/freetype/include/freetype/ttnameid.h +++ /dev/null @@ -1,1237 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttnameid.h */ -/* */ -/* TrueType name ID definitions (specification only). */ -/* */ -/* Copyright 1996-2004, 2006-2008, 2012 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 __TTNAMEID_H__ -#define __TTNAMEID_H__ - - -#include <ft2build.h> - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* truetype_tables */ - /* */ - - - /*************************************************************************/ - /* */ - /* Possible values for the `platform' identifier code in the name */ - /* records of the TTF `name' table. */ - /* */ - /*************************************************************************/ - - - /*********************************************************************** - * - * @enum: - * TT_PLATFORM_XXX - * - * @description: - * A list of valid values for the `platform_id' identifier code in - * @FT_CharMapRec and @FT_SfntName structures. - * - * @values: - * TT_PLATFORM_APPLE_UNICODE :: - * Used by Apple to indicate a Unicode character map and/or name entry. - * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note - * that name entries in this format are coded as big-endian UCS-2 - * character codes _only_. - * - * TT_PLATFORM_MACINTOSH :: - * Used by Apple to indicate a MacOS-specific charmap and/or name entry. - * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that - * most TrueType fonts contain an Apple roman charmap to be usable on - * MacOS systems (even if they contain a Microsoft charmap as well). - * - * TT_PLATFORM_ISO :: - * This value was used to specify ISO/IEC 10646 charmaps. It is however - * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding - * `encoding_id' values. - * - * TT_PLATFORM_MICROSOFT :: - * Used by Microsoft to indicate Windows-specific charmaps. See - * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. - * Note that most fonts contain a Unicode charmap using - * (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). - * - * TT_PLATFORM_CUSTOM :: - * Used to indicate application-specific charmaps. - * - * TT_PLATFORM_ADOBE :: - * This value isn't part of any font format specification, but is used - * by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec - * structure. See @TT_ADOBE_ID_XXX. - */ - -#define TT_PLATFORM_APPLE_UNICODE 0 -#define TT_PLATFORM_MACINTOSH 1 -#define TT_PLATFORM_ISO 2 /* deprecated */ -#define TT_PLATFORM_MICROSOFT 3 -#define TT_PLATFORM_CUSTOM 4 -#define TT_PLATFORM_ADOBE 7 /* artificial */ - - - /*********************************************************************** - * - * @enum: - * TT_APPLE_ID_XXX - * - * @description: - * A list of valid values for the `encoding_id' for - * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. - * - * @values: - * TT_APPLE_ID_DEFAULT :: - * Unicode version 1.0. - * - * TT_APPLE_ID_UNICODE_1_1 :: - * Unicode 1.1; specifies Hangul characters starting at U+34xx. - * - * TT_APPLE_ID_ISO_10646 :: - * Deprecated (identical to preceding). - * - * TT_APPLE_ID_UNICODE_2_0 :: - * Unicode 2.0 and beyond (UTF-16 BMP only). - * - * TT_APPLE_ID_UNICODE_32 :: - * Unicode 3.1 and beyond, using UTF-32. - * - * TT_APPLE_ID_VARIANT_SELECTOR :: - * From Adobe, not Apple. Not a normal cmap. Specifies variations - * on a real cmap. - */ - -#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ -#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ -#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ -#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ -#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ -#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ - - - /*********************************************************************** - * - * @enum: - * TT_MAC_ID_XXX - * - * @description: - * A list of valid values for the `encoding_id' for - * @TT_PLATFORM_MACINTOSH charmaps and name entries. - * - * @values: - * TT_MAC_ID_ROMAN :: - * TT_MAC_ID_JAPANESE :: - * TT_MAC_ID_TRADITIONAL_CHINESE :: - * TT_MAC_ID_KOREAN :: - * TT_MAC_ID_ARABIC :: - * TT_MAC_ID_HEBREW :: - * TT_MAC_ID_GREEK :: - * TT_MAC_ID_RUSSIAN :: - * TT_MAC_ID_RSYMBOL :: - * TT_MAC_ID_DEVANAGARI :: - * TT_MAC_ID_GURMUKHI :: - * TT_MAC_ID_GUJARATI :: - * TT_MAC_ID_ORIYA :: - * TT_MAC_ID_BENGALI :: - * TT_MAC_ID_TAMIL :: - * TT_MAC_ID_TELUGU :: - * TT_MAC_ID_KANNADA :: - * TT_MAC_ID_MALAYALAM :: - * TT_MAC_ID_SINHALESE :: - * TT_MAC_ID_BURMESE :: - * TT_MAC_ID_KHMER :: - * TT_MAC_ID_THAI :: - * TT_MAC_ID_LAOTIAN :: - * TT_MAC_ID_GEORGIAN :: - * TT_MAC_ID_ARMENIAN :: - * TT_MAC_ID_MALDIVIAN :: - * TT_MAC_ID_SIMPLIFIED_CHINESE :: - * TT_MAC_ID_TIBETAN :: - * TT_MAC_ID_MONGOLIAN :: - * TT_MAC_ID_GEEZ :: - * TT_MAC_ID_SLAVIC :: - * TT_MAC_ID_VIETNAMESE :: - * TT_MAC_ID_SINDHI :: - * TT_MAC_ID_UNINTERP :: - */ - -#define TT_MAC_ID_ROMAN 0 -#define TT_MAC_ID_JAPANESE 1 -#define TT_MAC_ID_TRADITIONAL_CHINESE 2 -#define TT_MAC_ID_KOREAN 3 -#define TT_MAC_ID_ARABIC 4 -#define TT_MAC_ID_HEBREW 5 -#define TT_MAC_ID_GREEK 6 -#define TT_MAC_ID_RUSSIAN 7 -#define TT_MAC_ID_RSYMBOL 8 -#define TT_MAC_ID_DEVANAGARI 9 -#define TT_MAC_ID_GURMUKHI 10 -#define TT_MAC_ID_GUJARATI 11 -#define TT_MAC_ID_ORIYA 12 -#define TT_MAC_ID_BENGALI 13 -#define TT_MAC_ID_TAMIL 14 -#define TT_MAC_ID_TELUGU 15 -#define TT_MAC_ID_KANNADA 16 -#define TT_MAC_ID_MALAYALAM 17 -#define TT_MAC_ID_SINHALESE 18 -#define TT_MAC_ID_BURMESE 19 -#define TT_MAC_ID_KHMER 20 -#define TT_MAC_ID_THAI 21 -#define TT_MAC_ID_LAOTIAN 22 -#define TT_MAC_ID_GEORGIAN 23 -#define TT_MAC_ID_ARMENIAN 24 -#define TT_MAC_ID_MALDIVIAN 25 -#define TT_MAC_ID_SIMPLIFIED_CHINESE 25 -#define TT_MAC_ID_TIBETAN 26 -#define TT_MAC_ID_MONGOLIAN 27 -#define TT_MAC_ID_GEEZ 28 -#define TT_MAC_ID_SLAVIC 29 -#define TT_MAC_ID_VIETNAMESE 30 -#define TT_MAC_ID_SINDHI 31 -#define TT_MAC_ID_UNINTERP 32 - - - /*********************************************************************** - * - * @enum: - * TT_ISO_ID_XXX - * - * @description: - * A list of valid values for the `encoding_id' for - * @TT_PLATFORM_ISO charmaps and name entries. - * - * Their use is now deprecated. - * - * @values: - * TT_ISO_ID_7BIT_ASCII :: - * ASCII. - * TT_ISO_ID_10646 :: - * ISO/10646. - * TT_ISO_ID_8859_1 :: - * Also known as Latin-1. - */ - -#define TT_ISO_ID_7BIT_ASCII 0 -#define TT_ISO_ID_10646 1 -#define TT_ISO_ID_8859_1 2 - - - /*********************************************************************** - * - * @enum: - * TT_MS_ID_XXX - * - * @description: - * A list of valid values for the `encoding_id' for - * @TT_PLATFORM_MICROSOFT charmaps and name entries. - * - * @values: - * TT_MS_ID_SYMBOL_CS :: - * Corresponds to Microsoft symbol encoding. See - * @FT_ENCODING_MS_SYMBOL. - * - * TT_MS_ID_UNICODE_CS :: - * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See - * @FT_ENCODING_UNICODE. - * - * TT_MS_ID_SJIS :: - * Corresponds to SJIS Japanese encoding. See @FT_ENCODING_SJIS. - * - * TT_MS_ID_GB2312 :: - * Corresponds to Simplified Chinese as used in Mainland China. See - * @FT_ENCODING_GB2312. - * - * TT_MS_ID_BIG_5 :: - * Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. - * See @FT_ENCODING_BIG5. - * - * TT_MS_ID_WANSUNG :: - * Corresponds to Korean Wansung encoding. See @FT_ENCODING_WANSUNG. - * - * TT_MS_ID_JOHAB :: - * Corresponds to Johab encoding. See @FT_ENCODING_JOHAB. - * - * TT_MS_ID_UCS_4 :: - * Corresponds to UCS-4 or UTF-32 charmaps. This has been added to - * the OpenType specification version 1.4 (mid-2001.) - */ - -#define TT_MS_ID_SYMBOL_CS 0 -#define TT_MS_ID_UNICODE_CS 1 -#define TT_MS_ID_SJIS 2 -#define TT_MS_ID_GB2312 3 -#define TT_MS_ID_BIG_5 4 -#define TT_MS_ID_WANSUNG 5 -#define TT_MS_ID_JOHAB 6 -#define TT_MS_ID_UCS_4 10 - - - /*********************************************************************** - * - * @enum: - * TT_ADOBE_ID_XXX - * - * @description: - * A list of valid values for the `encoding_id' for - * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! - * - * @values: - * TT_ADOBE_ID_STANDARD :: - * Adobe standard encoding. - * TT_ADOBE_ID_EXPERT :: - * Adobe expert encoding. - * TT_ADOBE_ID_CUSTOM :: - * Adobe custom encoding. - * TT_ADOBE_ID_LATIN_1 :: - * Adobe Latin~1 encoding. - */ - -#define TT_ADOBE_ID_STANDARD 0 -#define TT_ADOBE_ID_EXPERT 1 -#define TT_ADOBE_ID_CUSTOM 2 -#define TT_ADOBE_ID_LATIN_1 3 - - - /*************************************************************************/ - /* */ - /* Possible values of the language identifier field in the name records */ - /* of the TTF `name' table if the `platform' identifier code is */ - /* TT_PLATFORM_MACINTOSH. These values are also used as return values */ - /* for function @FT_Get_CMap_Language_ID. */ - /* */ - /* The canonical source for the Apple assigned Language ID's is at */ - /* */ - /* https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html */ - /* */ -#define TT_MAC_LANGID_ENGLISH 0 -#define TT_MAC_LANGID_FRENCH 1 -#define TT_MAC_LANGID_GERMAN 2 -#define TT_MAC_LANGID_ITALIAN 3 -#define TT_MAC_LANGID_DUTCH 4 -#define TT_MAC_LANGID_SWEDISH 5 -#define TT_MAC_LANGID_SPANISH 6 -#define TT_MAC_LANGID_DANISH 7 -#define TT_MAC_LANGID_PORTUGUESE 8 -#define TT_MAC_LANGID_NORWEGIAN 9 -#define TT_MAC_LANGID_HEBREW 10 -#define TT_MAC_LANGID_JAPANESE 11 -#define TT_MAC_LANGID_ARABIC 12 -#define TT_MAC_LANGID_FINNISH 13 -#define TT_MAC_LANGID_GREEK 14 -#define TT_MAC_LANGID_ICELANDIC 15 -#define TT_MAC_LANGID_MALTESE 16 -#define TT_MAC_LANGID_TURKISH 17 -#define TT_MAC_LANGID_CROATIAN 18 -#define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 -#define TT_MAC_LANGID_URDU 20 -#define TT_MAC_LANGID_HINDI 21 -#define TT_MAC_LANGID_THAI 22 -#define TT_MAC_LANGID_KOREAN 23 -#define TT_MAC_LANGID_LITHUANIAN 24 -#define TT_MAC_LANGID_POLISH 25 -#define TT_MAC_LANGID_HUNGARIAN 26 -#define TT_MAC_LANGID_ESTONIAN 27 -#define TT_MAC_LANGID_LETTISH 28 -#define TT_MAC_LANGID_SAAMISK 29 -#define TT_MAC_LANGID_FAEROESE 30 -#define TT_MAC_LANGID_FARSI 31 -#define TT_MAC_LANGID_RUSSIAN 32 -#define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 -#define TT_MAC_LANGID_FLEMISH 34 -#define TT_MAC_LANGID_IRISH 35 -#define TT_MAC_LANGID_ALBANIAN 36 -#define TT_MAC_LANGID_ROMANIAN 37 -#define TT_MAC_LANGID_CZECH 38 -#define TT_MAC_LANGID_SLOVAK 39 -#define TT_MAC_LANGID_SLOVENIAN 40 -#define TT_MAC_LANGID_YIDDISH 41 -#define TT_MAC_LANGID_SERBIAN 42 -#define TT_MAC_LANGID_MACEDONIAN 43 -#define TT_MAC_LANGID_BULGARIAN 44 -#define TT_MAC_LANGID_UKRAINIAN 45 -#define TT_MAC_LANGID_BYELORUSSIAN 46 -#define TT_MAC_LANGID_UZBEK 47 -#define TT_MAC_LANGID_KAZAKH 48 -#define TT_MAC_LANGID_AZERBAIJANI 49 -#define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT 49 -#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 -#define TT_MAC_LANGID_ARMENIAN 51 -#define TT_MAC_LANGID_GEORGIAN 52 -#define TT_MAC_LANGID_MOLDAVIAN 53 -#define TT_MAC_LANGID_KIRGHIZ 54 -#define TT_MAC_LANGID_TAJIKI 55 -#define TT_MAC_LANGID_TURKMEN 56 -#define TT_MAC_LANGID_MONGOLIAN 57 -#define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT 57 -#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 -#define TT_MAC_LANGID_PASHTO 59 -#define TT_MAC_LANGID_KURDISH 60 -#define TT_MAC_LANGID_KASHMIRI 61 -#define TT_MAC_LANGID_SINDHI 62 -#define TT_MAC_LANGID_TIBETAN 63 -#define TT_MAC_LANGID_NEPALI 64 -#define TT_MAC_LANGID_SANSKRIT 65 -#define TT_MAC_LANGID_MARATHI 66 -#define TT_MAC_LANGID_BENGALI 67 -#define TT_MAC_LANGID_ASSAMESE 68 -#define TT_MAC_LANGID_GUJARATI 69 -#define TT_MAC_LANGID_PUNJABI 70 -#define TT_MAC_LANGID_ORIYA 71 -#define TT_MAC_LANGID_MALAYALAM 72 -#define TT_MAC_LANGID_KANNADA 73 -#define TT_MAC_LANGID_TAMIL 74 -#define TT_MAC_LANGID_TELUGU 75 -#define TT_MAC_LANGID_SINHALESE 76 -#define TT_MAC_LANGID_BURMESE 77 -#define TT_MAC_LANGID_KHMER 78 -#define TT_MAC_LANGID_LAO 79 -#define TT_MAC_LANGID_VIETNAMESE 80 -#define TT_MAC_LANGID_INDONESIAN 81 -#define TT_MAC_LANGID_TAGALOG 82 -#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 -#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 -#define TT_MAC_LANGID_AMHARIC 85 -#define TT_MAC_LANGID_TIGRINYA 86 -#define TT_MAC_LANGID_GALLA 87 -#define TT_MAC_LANGID_SOMALI 88 -#define TT_MAC_LANGID_SWAHILI 89 -#define TT_MAC_LANGID_RUANDA 90 -#define TT_MAC_LANGID_RUNDI 91 -#define TT_MAC_LANGID_CHEWA 92 -#define TT_MAC_LANGID_MALAGASY 93 -#define TT_MAC_LANGID_ESPERANTO 94 -#define TT_MAC_LANGID_WELSH 128 -#define TT_MAC_LANGID_BASQUE 129 -#define TT_MAC_LANGID_CATALAN 130 -#define TT_MAC_LANGID_LATIN 131 -#define TT_MAC_LANGID_QUECHUA 132 -#define TT_MAC_LANGID_GUARANI 133 -#define TT_MAC_LANGID_AYMARA 134 -#define TT_MAC_LANGID_TATAR 135 -#define TT_MAC_LANGID_UIGHUR 136 -#define TT_MAC_LANGID_DZONGKHA 137 -#define TT_MAC_LANGID_JAVANESE 138 -#define TT_MAC_LANGID_SUNDANESE 139 - - -#if 0 /* these seem to be errors that have been dropped */ - -#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 -#define TT_MAC_LANGID_IRISH_GAELIC 141 - -#endif - - - /* The following codes are new as of 2000-03-10 */ -#define TT_MAC_LANGID_GALICIAN 140 -#define TT_MAC_LANGID_AFRIKAANS 141 -#define TT_MAC_LANGID_BRETON 142 -#define TT_MAC_LANGID_INUKTITUT 143 -#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 -#define TT_MAC_LANGID_MANX_GAELIC 145 -#define TT_MAC_LANGID_IRISH_GAELIC 146 -#define TT_MAC_LANGID_TONGAN 147 -#define TT_MAC_LANGID_GREEK_POLYTONIC 148 -#define TT_MAC_LANGID_GREELANDIC 149 -#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 - - - /*************************************************************************/ - /* */ - /* Possible values of the language identifier field in the name records */ - /* of the TTF `name' table if the `platform' identifier code is */ - /* TT_PLATFORM_MICROSOFT. */ - /* */ - /* The canonical source for the MS assigned LCIDs is */ - /* */ - /* http://www.microsoft.com/globaldev/reference/lcid-all.mspx */ - /* */ - -#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 -#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 -#define TT_MS_LANGID_ARABIC_IRAQ 0x0801 -#define TT_MS_LANGID_ARABIC_EGYPT 0x0c01 -#define TT_MS_LANGID_ARABIC_LIBYA 0x1001 -#define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 -#define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 -#define TT_MS_LANGID_ARABIC_TUNISIA 0x1c01 -#define TT_MS_LANGID_ARABIC_OMAN 0x2001 -#define TT_MS_LANGID_ARABIC_YEMEN 0x2401 -#define TT_MS_LANGID_ARABIC_SYRIA 0x2801 -#define TT_MS_LANGID_ARABIC_JORDAN 0x2c01 -#define TT_MS_LANGID_ARABIC_LEBANON 0x3001 -#define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 -#define TT_MS_LANGID_ARABIC_UAE 0x3801 -#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3c01 -#define TT_MS_LANGID_ARABIC_QATAR 0x4001 -#define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 -#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 -#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 -#define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 -#define TT_MS_LANGID_CHINESE_PRC 0x0804 -#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0c04 -#define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 - -#if 1 /* this looks like the correct value */ -#define TT_MS_LANGID_CHINESE_MACAU 0x1404 -#else /* but beware, Microsoft may change its mind... - the most recent Word reference has the following: */ -#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG -#endif - -#if 0 /* used only with .NET `cultures'; commented out */ -#define TT_MS_LANGID_CHINESE_TRADITIONAL 0x7C04 -#endif - -#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 -#define TT_MS_LANGID_DANISH_DENMARK 0x0406 -#define TT_MS_LANGID_GERMAN_GERMANY 0x0407 -#define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 -#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0c07 -#define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 -#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 -#define TT_MS_LANGID_GREEK_GREECE 0x0408 - - /* don't ask what this one means... It is commented out currently. */ -#if 0 -#define TT_MS_LANGID_GREEK_GREECE2 0x2008 -#endif - -#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 -#define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 -#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 -#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0c09 -#define TT_MS_LANGID_ENGLISH_CANADA 0x1009 -#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 -#define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 -#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1c09 -#define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 -#define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 -#define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 -#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2c09 -#define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 -#define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 -#define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 -#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3c09 -#define TT_MS_LANGID_ENGLISH_INDIA 0x4009 -#define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 -#define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 -#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040a -#define TT_MS_LANGID_SPANISH_MEXICO 0x080a -#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0c0a -#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100a -#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140a -#define TT_MS_LANGID_SPANISH_PANAMA 0x180a -#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1c0a -#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200a -#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240a -#define TT_MS_LANGID_SPANISH_PERU 0x280a -#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2c0a -#define TT_MS_LANGID_SPANISH_ECUADOR 0x300a -#define TT_MS_LANGID_SPANISH_CHILE 0x340a -#define TT_MS_LANGID_SPANISH_URUGUAY 0x380a -#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3c0a -#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400a -#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440a -#define TT_MS_LANGID_SPANISH_HONDURAS 0x480a -#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4c0a -#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500a -#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540a - /* The following ID blatantly violate MS specs by using a */ - /* sublanguage > 0x1F. */ -#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40aU -#define TT_MS_LANGID_FINNISH_FINLAND 0x040b -#define TT_MS_LANGID_FRENCH_FRANCE 0x040c -#define TT_MS_LANGID_FRENCH_BELGIUM 0x080c -#define TT_MS_LANGID_FRENCH_CANADA 0x0c0c -#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100c -#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140c -#define TT_MS_LANGID_FRENCH_MONACO 0x180c -#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1c0c -#define TT_MS_LANGID_FRENCH_REUNION 0x200c -#define TT_MS_LANGID_FRENCH_CONGO 0x240c - /* which was formerly: */ -#define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO -#define TT_MS_LANGID_FRENCH_SENEGAL 0x280c -#define TT_MS_LANGID_FRENCH_CAMEROON 0x2c0c -#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300c -#define TT_MS_LANGID_FRENCH_MALI 0x340c -#define TT_MS_LANGID_FRENCH_MOROCCO 0x380c -#define TT_MS_LANGID_FRENCH_HAITI 0x3c0c - /* and another violation of the spec (see 0xE40aU) */ -#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40cU -#define TT_MS_LANGID_HEBREW_ISRAEL 0x040d -#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040e -#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040f -#define TT_MS_LANGID_ITALIAN_ITALY 0x0410 -#define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 -#define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 -#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 -#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 -#define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 -#define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 -#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 -#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 -#define TT_MS_LANGID_POLISH_POLAND 0x0415 -#define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 -#define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 -#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 -#define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 -#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 -#define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 -#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 -#define TT_MS_LANGID_CROATIAN_CROATIA 0x041a -#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081a -#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0c1a - -#if 0 /* this used to be this value, but it looks like we were wrong */ -#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101a -#else /* current sources say */ -#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101a -#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141a - /* and XPsp2 Platform SDK added (2004-07-26) */ - /* Names are shortened to be significant within 40 chars. */ -#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181a -#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181a -#endif - -#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041b -#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041c -#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041d -#define TT_MS_LANGID_SWEDISH_FINLAND 0x081d -#define TT_MS_LANGID_THAI_THAILAND 0x041e -#define TT_MS_LANGID_TURKISH_TURKEY 0x041f -#define TT_MS_LANGID_URDU_PAKISTAN 0x0420 -#define TT_MS_LANGID_URDU_INDIA 0x0820 -#define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 -#define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 -#define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 -#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 -#define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 -#define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 -#define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 -#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 -#define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 -#define TT_MS_LANGID_FARSI_IRAN 0x0429 -#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042a -#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042b -#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042c -#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082c -#define TT_MS_LANGID_BASQUE_SPAIN 0x042d -#define TT_MS_LANGID_SORBIAN_GERMANY 0x042e -#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042f -#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 -#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 -#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 -#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 -#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 -#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 -#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 -#define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 -#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 -#define TT_MS_LANGID_HINDI_INDIA 0x0439 -#define TT_MS_LANGID_MALTESE_MALTA 0x043a - /* Added by XPsp2 Platform SDK (2004-07-26) */ -#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043b -#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083b -#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3b -#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103b -#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143b -#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183b -#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3b -#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203b -#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243b - /* ... and we also keep our old identifier... */ -#define TT_MS_LANGID_SAAMI_LAPONIA 0x043b - -#if 0 /* this seems to be a previous inversion */ -#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c -#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c -#else -#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c -#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c -#endif - -#define TT_MS_LANGID_YIDDISH_GERMANY 0x043d -#define TT_MS_LANGID_MALAY_MALAYSIA 0x043e -#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083e -#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043f -#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 - /* alias declared in Windows 2000 */ -#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ - TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN - -#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 -#define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 -#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 -#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 -#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 -#define TT_MS_LANGID_BENGALI_INDIA 0x0445 -#define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 -#define TT_MS_LANGID_PUNJABI_INDIA 0x0446 -#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 -#define TT_MS_LANGID_GUJARATI_INDIA 0x0447 -#define TT_MS_LANGID_ORIYA_INDIA 0x0448 -#define TT_MS_LANGID_TAMIL_INDIA 0x0449 -#define TT_MS_LANGID_TELUGU_INDIA 0x044a -#define TT_MS_LANGID_KANNADA_INDIA 0x044b -#define TT_MS_LANGID_MALAYALAM_INDIA 0x044c -#define TT_MS_LANGID_ASSAMESE_INDIA 0x044d -#define TT_MS_LANGID_MARATHI_INDIA 0x044e -#define TT_MS_LANGID_SANSKRIT_INDIA 0x044f -#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 -#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 -#define TT_MS_LANGID_TIBETAN_CHINA 0x0451 - /* Don't use the next constant! It has */ - /* (1) the wrong spelling (Dzonghka) */ - /* (2) Microsoft doesn't officially define it -- */ - /* at least it is not in the List of Local */ - /* ID Values. */ - /* (3) Dzongkha is not the same language as */ - /* Tibetan, so merging it is wrong anyway. */ - /* */ - /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW. */ -#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 - -#if 0 - /* the following used to be defined */ -#define TT_MS_LANGID_TIBETAN_BHUTAN 0x0451 - /* ... but it was changed; */ -#else - /* So we will continue to #define it, but with the correct value */ -#define TT_MS_LANGID_TIBETAN_BHUTAN TT_MS_LANGID_DZONGHKA_BHUTAN -#endif - -#define TT_MS_LANGID_WELSH_WALES 0x0452 -#define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 -#define TT_MS_LANGID_LAO_LAOS 0x0454 -#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 -#define TT_MS_LANGID_GALICIAN_SPAIN 0x0456 -#define TT_MS_LANGID_KONKANI_INDIA 0x0457 -#define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 -#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 -#define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 - /* Missing a LCID for Sindhi in Devanagari script */ -#define TT_MS_LANGID_SYRIAC_SYRIA 0x045a -#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045b -#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045c -#define TT_MS_LANGID_INUKTITUT_CANADA 0x045d -#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045e -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045f -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085f - /* Missing a LCID for Tifinagh script */ -#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 - /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ - /* script is yet unclear... might be Arabic, Nagari or Sharada */ -#define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 - /* ... and aliased (by MS) for compatibility reasons. */ -#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA -#define TT_MS_LANGID_NEPALI_NEPAL 0x0461 -#define TT_MS_LANGID_NEPALI_INDIA 0x0861 -#define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 -#define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 -#define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 -#define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 - /* alias declared in Windows 2000 */ -#define TT_MS_LANGID_DIVEHI_MALDIVES TT_MS_LANGID_DHIVEHI_MALDIVES -#define TT_MS_LANGID_EDO_NIGERIA 0x0466 -#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 -#define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 -#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 -#define TT_MS_LANGID_YORUBA_NIGERIA 0x046a -#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046b -#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086b -#define TT_MS_LANGID_QUECHUA_PERU 0x0c6b -#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046c - /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ -#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ - TT_MS_LANGID_SEPEDI_SOUTH_AFRICA - /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */ -#define TT_MS_LANGID_IGBO_NIGERIA 0x0470 -#define TT_MS_LANGID_KANURI_NIGERIA 0x0471 -#define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 -#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 -#define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 - /* also spelled in the `Passport SDK' list as: */ -#define TT_MS_LANGID_TIGRIGNA_ERYTREA TT_MS_LANGID_TIGRIGNA_ERYTHREA -#define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 -#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 -#define TT_MS_LANGID_LATIN 0x0476 -#define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 - /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */ - /* not written (but OTOH the peculiar writing system is worth */ - /* studying). */ -#define TT_MS_LANGID_YI_CHINA 0x0478 -#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 - /* language codes from 0x047a to 0x047f are (still) unknown. */ -#define TT_MS_LANGID_UIGHUR_CHINA 0x0480 -#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 - -#if 0 /* not deemed useful for fonts */ -#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04ff -#endif - - - /*************************************************************************/ - /* */ - /* Possible values of the `name' identifier field in the name records of */ - /* the TTF `name' table. These values are platform independent. */ - /* */ -#define TT_NAME_ID_COPYRIGHT 0 -#define TT_NAME_ID_FONT_FAMILY 1 -#define TT_NAME_ID_FONT_SUBFAMILY 2 -#define TT_NAME_ID_UNIQUE_ID 3 -#define TT_NAME_ID_FULL_NAME 4 -#define TT_NAME_ID_VERSION_STRING 5 -#define TT_NAME_ID_PS_NAME 6 -#define TT_NAME_ID_TRADEMARK 7 - - /* the following values are from the OpenType spec */ -#define TT_NAME_ID_MANUFACTURER 8 -#define TT_NAME_ID_DESIGNER 9 -#define TT_NAME_ID_DESCRIPTION 10 -#define TT_NAME_ID_VENDOR_URL 11 -#define TT_NAME_ID_DESIGNER_URL 12 -#define TT_NAME_ID_LICENSE 13 -#define TT_NAME_ID_LICENSE_URL 14 - /* number 15 is reserved */ -#define TT_NAME_ID_PREFERRED_FAMILY 16 -#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 -#define TT_NAME_ID_MAC_FULL_NAME 18 - - /* The following code is new as of 2000-01-21 */ -#define TT_NAME_ID_SAMPLE_TEXT 19 - - /* This is new in OpenType 1.3 */ -#define TT_NAME_ID_CID_FINDFONT_NAME 20 - - /* This is new in OpenType 1.5 */ -#define TT_NAME_ID_WWS_FAMILY 21 -#define TT_NAME_ID_WWS_SUBFAMILY 22 - - - /*************************************************************************/ - /* */ - /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ - /* */ - /* Updated 08-Nov-2008. */ - /* */ - - /* Bit 0 Basic Latin */ -#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ - /* Bit 1 C1 Controls and Latin-1 Supplement */ -#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ - /* Bit 2 Latin Extended-A */ -#define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ - /* Bit 3 Latin Extended-B */ -#define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ - /* Bit 4 IPA Extensions */ - /* Phonetic Extensions */ - /* Phonetic Extensions Supplement */ -#define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ - /* U+1D00-U+1D7F */ - /* U+1D80-U+1DBF */ - /* Bit 5 Spacing Modifier Letters */ - /* Modifier Tone Letters */ -#define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ - /* U+A700-U+A71F */ - /* Bit 6 Combining Diacritical Marks */ - /* Combining Diacritical Marks Supplement */ -#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ - /* U+1DC0-U+1DFF */ - /* Bit 7 Greek and Coptic */ -#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ - /* Bit 8 Coptic */ -#define TT_UCR_COPTIC (1L << 8) /* U+2C80-U+2CFF */ - /* Bit 9 Cyrillic */ - /* Cyrillic Supplement */ - /* Cyrillic Extended-A */ - /* Cyrillic Extended-B */ -#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ - /* U+0500-U+052F */ - /* U+2DE0-U+2DFF */ - /* U+A640-U+A69F */ - /* Bit 10 Armenian */ -#define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ - /* Bit 11 Hebrew */ -#define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ - /* Bit 12 Vai */ -#define TT_UCR_VAI (1L << 12) /* U+A500-U+A63F */ - /* Bit 13 Arabic */ - /* Arabic Supplement */ -#define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ - /* U+0750-U+077F */ - /* Bit 14 NKo */ -#define TT_UCR_NKO (1L << 14) /* U+07C0-U+07FF */ - /* Bit 15 Devanagari */ -#define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ - /* Bit 16 Bengali */ -#define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ - /* Bit 17 Gurmukhi */ -#define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ - /* Bit 18 Gujarati */ -#define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ - /* Bit 19 Oriya */ -#define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ - /* Bit 20 Tamil */ -#define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ - /* Bit 21 Telugu */ -#define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ - /* Bit 22 Kannada */ -#define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ - /* Bit 23 Malayalam */ -#define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ - /* Bit 24 Thai */ -#define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ - /* Bit 25 Lao */ -#define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ - /* Bit 26 Georgian */ - /* Georgian Supplement */ -#define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ - /* U+2D00-U+2D2F */ - /* Bit 27 Balinese */ -#define TT_UCR_BALINESE (1L << 27) /* U+1B00-U+1B7F */ - /* Bit 28 Hangul Jamo */ -#define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ - /* Bit 29 Latin Extended Additional */ - /* Latin Extended-C */ - /* Latin Extended-D */ -#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ - /* U+2C60-U+2C7F */ - /* U+A720-U+A7FF */ - /* Bit 30 Greek Extended */ -#define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ - /* Bit 31 General Punctuation */ - /* Supplemental Punctuation */ -#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ - /* U+2E00-U+2E7F */ - /* Bit 32 Superscripts And Subscripts */ -#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ - /* Bit 33 Currency Symbols */ -#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ - /* Bit 34 Combining Diacritical Marks For Symbols */ -#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ - /* Bit 35 Letterlike Symbols */ -#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ - /* Bit 36 Number Forms */ -#define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ - /* Bit 37 Arrows */ - /* Supplemental Arrows-A */ - /* Supplemental Arrows-B */ - /* Miscellaneous Symbols and Arrows */ -#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ - /* U+27F0-U+27FF */ - /* U+2900-U+297F */ - /* U+2B00-U+2BFF */ - /* Bit 38 Mathematical Operators */ - /* Supplemental Mathematical Operators */ - /* Miscellaneous Mathematical Symbols-A */ - /* Miscellaneous Mathematical Symbols-B */ -#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ - /* U+2A00-U+2AFF */ - /* U+27C0-U+27EF */ - /* U+2980-U+29FF */ - /* Bit 39 Miscellaneous Technical */ -#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ - /* Bit 40 Control Pictures */ -#define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ - /* Bit 41 Optical Character Recognition */ -#define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ - /* Bit 42 Enclosed Alphanumerics */ -#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ - /* Bit 43 Box Drawing */ -#define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ - /* Bit 44 Block Elements */ -#define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ - /* Bit 45 Geometric Shapes */ -#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ - /* Bit 46 Miscellaneous Symbols */ -#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ - /* Bit 47 Dingbats */ -#define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ - /* Bit 48 CJK Symbols and Punctuation */ -#define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ - /* Bit 49 Hiragana */ -#define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ - /* Bit 50 Katakana */ - /* Katakana Phonetic Extensions */ -#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ - /* U+31F0-U+31FF */ - /* Bit 51 Bopomofo */ - /* Bopomofo Extended */ -#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ - /* U+31A0-U+31BF */ - /* Bit 52 Hangul Compatibility Jamo */ -#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ - /* Bit 53 Phags-Pa */ -#define TT_UCR_CJK_MISC (1L << 21) /* U+A840-U+A87F */ -#define TT_UCR_KANBUN TT_UCR_CJK_MISC /* deprecated */ -#define TT_UCR_PHAGSPA - /* Bit 54 Enclosed CJK Letters and Months */ -#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ - /* Bit 55 CJK Compatibility */ -#define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ - /* Bit 56 Hangul Syllables */ -#define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ - /* Bit 57 High Surrogates */ - /* High Private Use Surrogates */ - /* Low Surrogates */ - /* */ - /* According to OpenType specs v.1.3+, */ - /* setting bit 57 implies that there is */ - /* at least one codepoint beyond the */ - /* Basic Multilingual Plane that is */ - /* supported by this font. So it really */ - /* means >= U+10000 */ -#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ - /* U+DB80-U+DBFF */ - /* U+DC00-U+DFFF */ -#define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES - /* Bit 58 Phoenician */ -#define TT_UCR_PHOENICIAN (1L << 26) /*U+10900-U+1091F*/ - /* Bit 59 CJK Unified Ideographs */ - /* CJK Radicals Supplement */ - /* Kangxi Radicals */ - /* Ideographic Description Characters */ - /* CJK Unified Ideographs Extension A */ - /* CJK Unified Ideographs Extension B */ - /* Kanbun */ -#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ - /* U+2E80-U+2EFF */ - /* U+2F00-U+2FDF */ - /* U+2FF0-U+2FFF */ - /* U+3400-U+4DB5 */ - /*U+20000-U+2A6DF*/ - /* U+3190-U+319F */ - /* Bit 60 Private Use */ -#define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ - /* Bit 61 CJK Strokes */ - /* CJK Compatibility Ideographs */ - /* CJK Compatibility Ideographs Supplement */ -#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+31C0-U+31EF */ - /* U+F900-U+FAFF */ - /*U+2F800-U+2FA1F*/ - /* Bit 62 Alphabetic Presentation Forms */ -#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ - /* Bit 63 Arabic Presentation Forms-A */ -#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ - /* Bit 64 Combining Half Marks */ -#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ - /* Bit 65 Vertical forms */ - /* CJK Compatibility Forms */ -#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE10-U+FE1F */ - /* U+FE30-U+FE4F */ - /* Bit 66 Small Form Variants */ -#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ - /* Bit 67 Arabic Presentation Forms-B */ -#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFE */ - /* Bit 68 Halfwidth and Fullwidth Forms */ -#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ - /* Bit 69 Specials */ -#define TT_UCR_SPECIALS (1L << 5) /* U+FFF0-U+FFFD */ - /* Bit 70 Tibetan */ -#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FFF */ - /* Bit 71 Syriac */ -#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ - /* Bit 72 Thaana */ -#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ - /* Bit 73 Sinhala */ -#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ - /* Bit 74 Myanmar */ -#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ - /* Bit 75 Ethiopic */ - /* Ethiopic Supplement */ - /* Ethiopic Extended */ -#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ - /* U+1380-U+139F */ - /* U+2D80-U+2DDF */ - /* Bit 76 Cherokee */ -#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ - /* Bit 77 Unified Canadian Aboriginal Syllabics */ -#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+167F */ - /* Bit 78 Ogham */ -#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ - /* Bit 79 Runic */ -#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ - /* Bit 80 Khmer */ - /* Khmer Symbols */ -#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ - /* U+19E0-U+19FF */ - /* Bit 81 Mongolian */ -#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ - /* Bit 82 Braille Patterns */ -#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ - /* Bit 83 Yi Syllables */ - /* Yi Radicals */ -#define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ - /* U+A490-U+A4CF */ - /* Bit 84 Tagalog */ - /* Hanunoo */ - /* Buhid */ - /* Tagbanwa */ -#define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ - /* U+1720-U+173F */ - /* U+1740-U+175F */ - /* U+1760-U+177F */ - /* Bit 85 Old Italic */ -#define TT_UCR_OLD_ITALIC (1L << 21) /*U+10300-U+1032F*/ - /* Bit 86 Gothic */ -#define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ - /* Bit 87 Deseret */ -#define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ - /* Bit 88 Byzantine Musical Symbols */ - /* Musical Symbols */ - /* Ancient Greek Musical Notation */ -#define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ - /*U+1D100-U+1D1FF*/ - /*U+1D200-U+1D24F*/ - /* Bit 89 Mathematical Alphanumeric Symbols */ -#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ - /* Bit 90 Private Use (plane 15) */ - /* Private Use (plane 16) */ -#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ - /*U+100000-U+10FFFD*/ - /* Bit 91 Variation Selectors */ - /* Variation Selectors Supplement */ -#define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ - /*U+E0100-U+E01EF*/ - /* Bit 92 Tags */ -#define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ - /* Bit 93 Limbu */ -#define TT_UCR_LIMBU (1L << 29) /* U+1900-U+194F */ - /* Bit 94 Tai Le */ -#define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ - /* Bit 95 New Tai Lue */ -#define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ - /* Bit 96 Buginese */ -#define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ - /* Bit 97 Glagolitic */ -#define TT_UCR_GLAGOLITIC (1L << 1) /* U+2C00-U+2C5F */ - /* Bit 98 Tifinagh */ -#define TT_UCR_TIFINAGH (1L << 2) /* U+2D30-U+2D7F */ - /* Bit 99 Yijing Hexagram Symbols */ -#define TT_UCR_YIJING (1L << 3) /* U+4DC0-U+4DFF */ - /* Bit 100 Syloti Nagri */ -#define TT_UCR_SYLOTI_NAGRI (1L << 4) /* U+A800-U+A82F */ - /* Bit 101 Linear B Syllabary */ - /* Linear B Ideograms */ - /* Aegean Numbers */ -#define TT_UCR_LINEAR_B (1L << 5) /*U+10000-U+1007F*/ - /*U+10080-U+100FF*/ - /*U+10100-U+1013F*/ - /* Bit 102 Ancient Greek Numbers */ -#define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) /*U+10140-U+1018F*/ - /* Bit 103 Ugaritic */ -#define TT_UCR_UGARITIC (1L << 7) /*U+10380-U+1039F*/ - /* Bit 104 Old Persian */ -#define TT_UCR_OLD_PERSIAN (1L << 8) /*U+103A0-U+103DF*/ - /* Bit 105 Shavian */ -#define TT_UCR_SHAVIAN (1L << 9) /*U+10450-U+1047F*/ - /* Bit 106 Osmanya */ -#define TT_UCR_OSMANYA (1L << 10) /*U+10480-U+104AF*/ - /* Bit 107 Cypriot Syllabary */ -#define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) /*U+10800-U+1083F*/ - /* Bit 108 Kharoshthi */ -#define TT_UCR_KHAROSHTHI (1L << 12) /*U+10A00-U+10A5F*/ - /* Bit 109 Tai Xuan Jing Symbols */ -#define TT_UCR_TAI_XUAN_JING (1L << 13) /*U+1D300-U+1D35F*/ - /* Bit 110 Cuneiform */ - /* Cuneiform Numbers and Punctuation */ -#define TT_UCR_CUNEIFORM (1L << 14) /*U+12000-U+123FF*/ - /*U+12400-U+1247F*/ - /* Bit 111 Counting Rod Numerals */ -#define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) /*U+1D360-U+1D37F*/ - /* Bit 112 Sundanese */ -#define TT_UCR_SUNDANESE (1L << 16) /* U+1B80-U+1BBF */ - /* Bit 113 Lepcha */ -#define TT_UCR_LEPCHA (1L << 17) /* U+1C00-U+1C4F */ - /* Bit 114 Ol Chiki */ -#define TT_UCR_OL_CHIKI (1L << 18) /* U+1C50-U+1C7F */ - /* Bit 115 Saurashtra */ -#define TT_UCR_SAURASHTRA (1L << 19) /* U+A880-U+A8DF */ - /* Bit 116 Kayah Li */ -#define TT_UCR_KAYAH_LI (1L << 20) /* U+A900-U+A92F */ - /* Bit 117 Rejang */ -#define TT_UCR_REJANG (1L << 21) /* U+A930-U+A95F */ - /* Bit 118 Cham */ -#define TT_UCR_CHAM (1L << 22) /* U+AA00-U+AA5F */ - /* Bit 119 Ancient Symbols */ -#define TT_UCR_ANCIENT_SYMBOLS (1L << 23) /*U+10190-U+101CF*/ - /* Bit 120 Phaistos Disc */ -#define TT_UCR_PHAISTOS_DISC (1L << 24) /*U+101D0-U+101FF*/ - /* Bit 121 Carian */ - /* Lycian */ - /* Lydian */ -#define TT_UCR_OLD_ANATOLIAN (1L << 25) /*U+102A0-U+102DF*/ - /*U+10280-U+1029F*/ - /*U+10920-U+1093F*/ - /* Bit 122 Domino Tiles */ - /* Mahjong Tiles */ -#define TT_UCR_GAME_TILES (1L << 26) /*U+1F030-U+1F09F*/ - /*U+1F000-U+1F02F*/ - /* Bit 123-127 Reserved for process-internal usage */ - - - /*************************************************************************/ - /* */ - /* Some compilers have a very limited length of identifiers. */ - /* */ -#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) -#define HAVE_LIMIT_ON_IDENTS -#endif - - -#ifndef HAVE_LIMIT_ON_IDENTS - - - /*************************************************************************/ - /* */ - /* Here some alias #defines in order to be clearer. */ - /* */ - /* These are not always #defined to stay within the 31~character limit */ - /* which some compilers have. */ - /* */ - /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ - /* Borland compilers (read: from BC++ 3.1 on) can increase this limit. */ - /* If you get a warning with such a compiler, use the -i40 switch. */ - /* */ -#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ - TT_UCR_ARABIC_PRESENTATIONS_A -#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ - TT_UCR_ARABIC_PRESENTATIONS_B - -#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ - TT_UCR_COMBINING_DIACRITICS -#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ - TT_UCR_COMBINING_DIACRITICS_SYMB - - -#endif /* !HAVE_LIMIT_ON_IDENTS */ - - -FT_END_HEADER - -#endif /* __TTNAMEID_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/tttables.h b/drivers/freetype/freetype/include/freetype/tttables.h deleted file mode 100644 index fe07117b0b..0000000000 --- a/drivers/freetype/freetype/include/freetype/tttables.h +++ /dev/null @@ -1,777 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttables.h */ -/* */ -/* Basic SFNT/TrueType tables definitions and interface */ -/* (specification only). */ -/* */ -/* Copyright 1996-2005, 2008-2012 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 __TTTABLES_H__ -#define __TTTABLES_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* <Section> */ - /* truetype_tables */ - /* */ - /* <Title> */ - /* TrueType Tables */ - /* */ - /* <Abstract> */ - /* TrueType specific table types and functions. */ - /* */ - /* <Description> */ - /* This section contains the definition of TrueType-specific tables */ - /* as well as some routines used to access and process them. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Header */ - /* */ - /* <Description> */ - /* A structure used to model a TrueType font header table. All */ - /* fields follow the TrueType specification. */ - /* */ - typedef struct TT_Header_ - { - FT_Fixed Table_Version; - FT_Fixed Font_Revision; - - FT_Long CheckSum_Adjust; - FT_Long Magic_Number; - - FT_UShort Flags; - FT_UShort Units_Per_EM; - - FT_Long Created [2]; - FT_Long Modified[2]; - - FT_Short xMin; - FT_Short yMin; - FT_Short xMax; - FT_Short yMax; - - FT_UShort Mac_Style; - FT_UShort Lowest_Rec_PPEM; - - FT_Short Font_Direction; - FT_Short Index_To_Loc_Format; - FT_Short Glyph_Data_Format; - - } TT_Header; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_HoriHeader */ - /* */ - /* <Description> */ - /* A structure used to model a TrueType horizontal header, the `hhea' */ - /* table, as well as the corresponding horizontal metrics table, */ - /* i.e., the `hmtx' table. */ - /* */ - /* <Fields> */ - /* Version :: The table version. */ - /* */ - /* Ascender :: The font's ascender, i.e., the distance */ - /* from the baseline to the top-most of all */ - /* glyph points found in the font. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of the */ - /* glyphs found in the font (maybe ASCII). */ - /* */ - /* You should use the `sTypoAscender' field */ - /* of the OS/2 table instead if you want */ - /* the correct one. */ - /* */ - /* Descender :: The font's descender, i.e., the distance */ - /* from the baseline to the bottom-most of */ - /* all glyph points found in the font. It */ - /* is negative. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of the */ - /* glyphs found in the font (maybe ASCII). */ - /* */ - /* You should use the `sTypoDescender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Line_Gap :: The font's line gap, i.e., the distance */ - /* to add to the ascender and descender to */ - /* get the BTB, i.e., the */ - /* baseline-to-baseline distance for the */ - /* font. */ - /* */ - /* advance_Width_Max :: This field is the maximum of all advance */ - /* widths found in the font. It can be */ - /* used to compute the maximum width of an */ - /* arbitrary string of text. */ - /* */ - /* min_Left_Side_Bearing :: The minimum left side bearing of all */ - /* glyphs within the font. */ - /* */ - /* min_Right_Side_Bearing :: The minimum right side bearing of all */ - /* glyphs within the font. */ - /* */ - /* xMax_Extent :: The maximum horizontal extent (i.e., the */ - /* `width' of a glyph's bounding box) for */ - /* all glyphs in the font. */ - /* */ - /* caret_Slope_Rise :: The rise coefficient of the cursor's */ - /* slope of the cursor (slope=rise/run). */ - /* */ - /* caret_Slope_Run :: The run coefficient of the cursor's */ - /* slope. */ - /* */ - /* Reserved :: 8~reserved bytes. */ - /* */ - /* metric_Data_Format :: Always~0. */ - /* */ - /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ - /* table -- this value can be smaller than */ - /* the total number of glyphs in the font. */ - /* */ - /* long_metrics :: A pointer into the `hmtx' table. */ - /* */ - /* short_metrics :: A pointer into the `hmtx' table. */ - /* */ - /* <Note> */ - /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ - /* */ - /* This ensures that a single function in the `ttload' */ - /* module is able to read both the horizontal and vertical */ - /* headers. */ - /* */ - typedef struct TT_HoriHeader_ - { - FT_Fixed Version; - FT_Short Ascender; - FT_Short Descender; - FT_Short Line_Gap; - - FT_UShort advance_Width_Max; /* advance width maximum */ - - FT_Short min_Left_Side_Bearing; /* minimum left-sb */ - FT_Short min_Right_Side_Bearing; /* minimum right-sb */ - FT_Short xMax_Extent; /* xmax extents */ - FT_Short caret_Slope_Rise; - FT_Short caret_Slope_Run; - FT_Short caret_Offset; - - FT_Short Reserved[4]; - - FT_Short metric_Data_Format; - FT_UShort number_Of_HMetrics; - - /* The following fields are not defined by the TrueType specification */ - /* but they are used to connect the metrics header to the relevant */ - /* `HMTX' table. */ - - void* long_metrics; - void* short_metrics; - - } TT_HoriHeader; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_VertHeader */ - /* */ - /* <Description> */ - /* A structure used to model a TrueType vertical header, the `vhea' */ - /* table, as well as the corresponding vertical metrics table, i.e., */ - /* the `vmtx' table. */ - /* */ - /* <Fields> */ - /* Version :: The table version. */ - /* */ - /* Ascender :: The font's ascender, i.e., the distance */ - /* from the baseline to the top-most of */ - /* all glyph points found in the font. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of */ - /* the glyphs found in the font (maybe */ - /* ASCII). */ - /* */ - /* You should use the `sTypoAscender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Descender :: The font's descender, i.e., the */ - /* distance from the baseline to the */ - /* bottom-most of all glyph points found */ - /* in the font. It is negative. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of */ - /* the glyphs found in the font (maybe */ - /* ASCII). */ - /* */ - /* You should use the `sTypoDescender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Line_Gap :: The font's line gap, i.e., the distance */ - /* to add to the ascender and descender to */ - /* get the BTB, i.e., the */ - /* baseline-to-baseline distance for the */ - /* font. */ - /* */ - /* advance_Height_Max :: This field is the maximum of all */ - /* advance heights found in the font. It */ - /* can be used to compute the maximum */ - /* height of an arbitrary string of text. */ - /* */ - /* min_Top_Side_Bearing :: The minimum top side bearing of all */ - /* glyphs within the font. */ - /* */ - /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ - /* glyphs within the font. */ - /* */ - /* yMax_Extent :: The maximum vertical extent (i.e., the */ - /* `height' of a glyph's bounding box) for */ - /* all glyphs in the font. */ - /* */ - /* caret_Slope_Rise :: The rise coefficient of the cursor's */ - /* slope of the cursor (slope=rise/run). */ - /* */ - /* caret_Slope_Run :: The run coefficient of the cursor's */ - /* slope. */ - /* */ - /* caret_Offset :: The cursor's offset for slanted fonts. */ - /* This value is `reserved' in vmtx */ - /* version 1.0. */ - /* */ - /* Reserved :: 8~reserved bytes. */ - /* */ - /* metric_Data_Format :: Always~0. */ - /* */ - /* number_Of_HMetrics :: Number of VMetrics entries in the */ - /* `vmtx' table -- this value can be */ - /* smaller than the total number of glyphs */ - /* in the font. */ - /* */ - /* long_metrics :: A pointer into the `vmtx' table. */ - /* */ - /* short_metrics :: A pointer into the `vmtx' table. */ - /* */ - /* <Note> */ - /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ - /* */ - /* This ensures that a single function in the `ttload' */ - /* module is able to read both the horizontal and vertical */ - /* headers. */ - /* */ - typedef struct TT_VertHeader_ - { - FT_Fixed Version; - FT_Short Ascender; - FT_Short Descender; - FT_Short Line_Gap; - - FT_UShort advance_Height_Max; /* advance height maximum */ - - FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ - FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ - FT_Short yMax_Extent; /* xmax or ymax extents */ - FT_Short caret_Slope_Rise; - FT_Short caret_Slope_Run; - FT_Short caret_Offset; - - FT_Short Reserved[4]; - - FT_Short metric_Data_Format; - FT_UShort number_Of_VMetrics; - - /* The following fields are not defined by the TrueType specification */ - /* but they're used to connect the metrics header to the relevant */ - /* `HMTX' or `VMTX' table. */ - - void* long_metrics; - void* short_metrics; - - } TT_VertHeader; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_OS2 */ - /* */ - /* <Description> */ - /* A structure used to model a TrueType OS/2 table. This is the long */ - /* table version. All fields comply to the TrueType specification. */ - /* */ - /* Note that we now support old Mac fonts which do not include an */ - /* OS/2 table. In this case, the `version' field is always set to */ - /* 0xFFFF. */ - /* */ - typedef struct TT_OS2_ - { - FT_UShort version; /* 0x0001 - more or 0xFFFF */ - FT_Short xAvgCharWidth; - FT_UShort usWeightClass; - FT_UShort usWidthClass; - FT_Short fsType; - FT_Short ySubscriptXSize; - FT_Short ySubscriptYSize; - FT_Short ySubscriptXOffset; - FT_Short ySubscriptYOffset; - FT_Short ySuperscriptXSize; - FT_Short ySuperscriptYSize; - FT_Short ySuperscriptXOffset; - FT_Short ySuperscriptYOffset; - FT_Short yStrikeoutSize; - FT_Short yStrikeoutPosition; - FT_Short sFamilyClass; - - FT_Byte panose[10]; - - FT_ULong ulUnicodeRange1; /* Bits 0-31 */ - FT_ULong ulUnicodeRange2; /* Bits 32-63 */ - FT_ULong ulUnicodeRange3; /* Bits 64-95 */ - FT_ULong ulUnicodeRange4; /* Bits 96-127 */ - - FT_Char achVendID[4]; - - FT_UShort fsSelection; - FT_UShort usFirstCharIndex; - FT_UShort usLastCharIndex; - FT_Short sTypoAscender; - FT_Short sTypoDescender; - FT_Short sTypoLineGap; - FT_UShort usWinAscent; - FT_UShort usWinDescent; - - /* only version 1 tables: */ - - FT_ULong ulCodePageRange1; /* Bits 0-31 */ - FT_ULong ulCodePageRange2; /* Bits 32-63 */ - - /* only version 2 tables: */ - - FT_Short sxHeight; - FT_Short sCapHeight; - FT_UShort usDefaultChar; - FT_UShort usBreakChar; - FT_UShort usMaxContext; - - } TT_OS2; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Postscript */ - /* */ - /* <Description> */ - /* A structure used to model a TrueType PostScript table. All fields */ - /* comply to the TrueType specification. This structure does not */ - /* reference the PostScript glyph names, which can be nevertheless */ - /* accessed with the `ttpost' module. */ - /* */ - typedef struct TT_Postscript_ - { - FT_Fixed FormatType; - FT_Fixed italicAngle; - FT_Short underlinePosition; - FT_Short underlineThickness; - FT_ULong isFixedPitch; - FT_ULong minMemType42; - FT_ULong maxMemType42; - FT_ULong minMemType1; - FT_ULong maxMemType1; - - /* Glyph names follow in the file, but we don't */ - /* load them by default. See the ttpost.c file. */ - - } TT_Postscript; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_PCLT */ - /* */ - /* <Description> */ - /* A structure used to model a TrueType PCLT table. All fields */ - /* comply to the TrueType specification. */ - /* */ - typedef struct TT_PCLT_ - { - FT_Fixed Version; - FT_ULong FontNumber; - FT_UShort Pitch; - FT_UShort xHeight; - FT_UShort Style; - FT_UShort TypeFamily; - FT_UShort CapHeight; - FT_UShort SymbolSet; - FT_Char TypeFace[16]; - FT_Char CharacterComplement[8]; - FT_Char FileName[6]; - FT_Char StrokeWeight; - FT_Char WidthType; - FT_Byte SerifStyle; - FT_Byte Reserved; - - } TT_PCLT; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_MaxProfile */ - /* */ - /* <Description> */ - /* The maximum profile is a table containing many max values which */ - /* can be used to pre-allocate arrays. This ensures that no memory */ - /* allocation occurs during a glyph load. */ - /* */ - /* <Fields> */ - /* version :: The version number. */ - /* */ - /* numGlyphs :: The number of glyphs in this TrueType */ - /* font. */ - /* */ - /* maxPoints :: The maximum number of points in a */ - /* non-composite TrueType glyph. See also */ - /* the structure element */ - /* `maxCompositePoints'. */ - /* */ - /* maxContours :: The maximum number of contours in a */ - /* non-composite TrueType glyph. See also */ - /* the structure element */ - /* `maxCompositeContours'. */ - /* */ - /* maxCompositePoints :: The maximum number of points in a */ - /* composite TrueType glyph. See also the */ - /* structure element `maxPoints'. */ - /* */ - /* maxCompositeContours :: The maximum number of contours in a */ - /* composite TrueType glyph. See also the */ - /* structure element `maxContours'. */ - /* */ - /* maxZones :: The maximum number of zones used for */ - /* glyph hinting. */ - /* */ - /* maxTwilightPoints :: The maximum number of points in the */ - /* twilight zone used for glyph hinting. */ - /* */ - /* maxStorage :: The maximum number of elements in the */ - /* storage area used for glyph hinting. */ - /* */ - /* maxFunctionDefs :: The maximum number of function */ - /* definitions in the TrueType bytecode for */ - /* this font. */ - /* */ - /* maxInstructionDefs :: The maximum number of instruction */ - /* definitions in the TrueType bytecode for */ - /* this font. */ - /* */ - /* maxStackElements :: The maximum number of stack elements used */ - /* during bytecode interpretation. */ - /* */ - /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ - /* used for glyph hinting. */ - /* */ - /* maxComponentElements :: The maximum number of simple (i.e., non- */ - /* composite) glyphs in a composite glyph. */ - /* */ - /* maxComponentDepth :: The maximum nesting depth of composite */ - /* glyphs. */ - /* */ - /* <Note> */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_MaxProfile_ - { - FT_Fixed version; - FT_UShort numGlyphs; - FT_UShort maxPoints; - FT_UShort maxContours; - FT_UShort maxCompositePoints; - FT_UShort maxCompositeContours; - FT_UShort maxZones; - FT_UShort maxTwilightPoints; - FT_UShort maxStorage; - FT_UShort maxFunctionDefs; - FT_UShort maxInstructionDefs; - FT_UShort maxStackElements; - FT_UShort maxSizeOfInstructions; - FT_UShort maxComponentElements; - FT_UShort maxComponentDepth; - - } TT_MaxProfile; - - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Sfnt_Tag */ - /* */ - /* <Description> */ - /* An enumeration used to specify the index of an SFNT table. */ - /* Used in the @FT_Get_Sfnt_Table API function. */ - /* */ - typedef enum FT_Sfnt_Tag_ - { - ft_sfnt_head = 0, /* TT_Header */ - ft_sfnt_maxp = 1, /* TT_MaxProfile */ - ft_sfnt_os2 = 2, /* TT_OS2 */ - ft_sfnt_hhea = 3, /* TT_HoriHeader */ - ft_sfnt_vhea = 4, /* TT_VertHeader */ - ft_sfnt_post = 5, /* TT_Postscript */ - ft_sfnt_pclt = 6, /* TT_PCLT */ - - sfnt_max /* internal end mark */ - - } FT_Sfnt_Tag; - - /* */ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Sfnt_Table */ - /* */ - /* <Description> */ - /* Return a pointer to a given SFNT table within a face. */ - /* */ - /* <Input> */ - /* face :: A handle to the source. */ - /* */ - /* tag :: The index of the SFNT table. */ - /* */ - /* <Return> */ - /* A type-less pointer to the table. This will be~0 in case of */ - /* error, or if the corresponding table was not found *OR* loaded */ - /* from the file. */ - /* */ - /* Use a typecast according to `tag' to access the structure */ - /* elements. */ - /* */ - /* <Note> */ - /* The table is owned by the face object and disappears with it. */ - /* */ - /* This function is only useful to access SFNT tables that are loaded */ - /* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */ - /* a list. */ - /* */ - /* Here an example how to access the `vhea' table: */ - /* */ - /* { */ - /* TT_VertHeader* vert_header; */ - /* */ - /* */ - /* vert_header = */ - /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, ft_sfnt_vhea ); */ - /* } */ - /* */ - FT_EXPORT( void* ) - FT_Get_Sfnt_Table( FT_Face face, - FT_Sfnt_Tag tag ); - - - /************************************************************************** - * - * @function: - * FT_Load_Sfnt_Table - * - * @description: - * Load any font table into client memory. - * - * @input: - * face :: - * A handle to the source face. - * - * tag :: - * The four-byte tag of the table to load. Use the value~0 if you want - * 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). - * - * @output: - * buffer :: - * The target buffer address. The client must ensure that the memory - * array is big enough to hold the data. - * - * @inout: - * length :: - * 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 - * table's (or file) full size in it. - * - * Else the number of bytes to read from the table or file, from the - * starting offset. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If you need to determine the table's length you should first call this - * function with `*length' set to~0, as in the following example: - * - * { - * FT_ULong length = 0; - * - * - * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); - * if ( error ) { ... table does not exist ... } - * - * buffer = malloc( length ); - * if ( buffer == NULL ) { ... not enough memory ... } - * - * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); - * if ( error ) { ... could not load table ... } - * } - */ - FT_EXPORT( FT_Error ) - FT_Load_Sfnt_Table( FT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); - - - /************************************************************************** - * - * @function: - * FT_Sfnt_Table_Info - * - * @description: - * Return information on an SFNT table. - * - * @input: - * face :: - * A handle to the source face. - * - * table_index :: - * The index of an SFNT table. The function returns - * FT_Err_Table_Missing for an invalid value. - * - * @inout: - * tag :: - * The name tag of the SFNT table. If the value is NULL, `table_index' - * is ignored, and `length' returns the number of SFNT tables in the - * font. - * - * @output: - * length :: - * The length of the SFNT table (or the number of SFNT tables, depending - * on `tag'). - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * While parsing fonts, FreeType handles SFNT tables with length zero as - * missing. - * - */ - FT_EXPORT( FT_Error ) - FT_Sfnt_Table_Info( FT_Face face, - FT_UInt table_index, - FT_ULong *tag, - FT_ULong *length ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_CMap_Language_ID */ - /* */ - /* <Description> */ - /* Return TrueType/sfnt specific cmap language ID. Definitions of */ - /* language ID values are in `freetype/ttnameid.h'. */ - /* */ - /* <Input> */ - /* charmap :: */ - /* The target charmap. */ - /* */ - /* <Return> */ - /* The language ID of `charmap'. If `charmap' doesn't belong to a */ - /* TrueType/sfnt face, just return~0 as the default value. */ - /* */ - /* For a format~14 cmap (to access Unicode IVS), the return value is */ - /* 0xFFFFFFFF. */ - /* */ - FT_EXPORT( FT_ULong ) - FT_Get_CMap_Language_ID( FT_CharMap charmap ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_CMap_Format */ - /* */ - /* <Description> */ - /* Return TrueType/sfnt specific cmap format. */ - /* */ - /* <Input> */ - /* charmap :: */ - /* The target charmap. */ - /* */ - /* <Return> */ - /* The format of `charmap'. If `charmap' doesn't belong to a */ - /* TrueType/sfnt face, return -1. */ - /* */ - FT_EXPORT( FT_Long ) - FT_Get_CMap_Format( FT_CharMap charmap ); - - /* */ - - -FT_END_HEADER - -#endif /* __TTTABLES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/tttags.h b/drivers/freetype/freetype/include/freetype/tttags.h deleted file mode 100644 index be8c524edb..0000000000 --- a/drivers/freetype/freetype/include/freetype/tttags.h +++ /dev/null @@ -1,109 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttags.h */ -/* */ -/* Tags for TrueType and OpenType tables (specification only). */ -/* */ -/* Copyright 1996-2001, 2004, 2005, 2007, 2008, 2013 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 __TTAGS_H__ -#define __TTAGS_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - -#define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' ) -#define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' ) -#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) -#define TTAG_BDF FT_MAKE_TAG( 'B', 'D', 'F', ' ' ) -#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) -#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) -#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) -#define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' ) -#define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' ) -#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) -#define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) -#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) -#define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) -#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) -#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) -#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) -#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) -#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) -#define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) -#define TTAG_FOND FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) -#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) -#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) -#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) -#define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' ) -#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) -#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) -#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) -#define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) -#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) -#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) -#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) -#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) -#define TTAG_JSTF FT_MAKE_TAG( 'J', 'S', 'T', 'F' ) -#define TTAG_just FT_MAKE_TAG( 'j', 'u', 's', 't' ) -#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) -#define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) -#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) -#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) -#define TTAG_LWFN FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) -#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) -#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) -#define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) -#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) -#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) -#define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) -#define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) -#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) -#define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) -#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) -#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) -#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) -#define TTAG_POST FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) -#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) -#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) -#define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) -#define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) -#define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) -#define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) -#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) -#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) -#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) -#define TTAG_TYP1 FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) -#define TTAG_typ1 FT_MAKE_TAG( 't', 'y', 'p', '1' ) -#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) -#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) -#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) - - -FT_END_HEADER - -#endif /* __TTAGS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ttunpat.h b/drivers/freetype/freetype/include/freetype/ttunpat.h deleted file mode 100644 index a0162759b7..0000000000 --- a/drivers/freetype/freetype/include/freetype/ttunpat.h +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttunpat.h */ -/* */ -/* Definitions for the unpatented TrueType hinting system */ -/* */ -/* Copyright 2003, 2006 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* Written by Graham Asher <graham.asher@btinternet.com> */ -/* */ -/* 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 __TTUNPAT_H__ -#define __TTUNPAT_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_UNPATENTED_HINTING - * - * @description: - * A constant used as the tag of an @FT_Parameter structure to indicate - * that unpatented methods only should be used by the TrueType bytecode - * interpreter for a typeface opened by @FT_Open_Face. - * - */ -#define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) - - /* */ - -FT_END_HEADER - - -#endif /* __TTUNPAT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/ft2build.h b/drivers/freetype/freetype/include/ft2build.h deleted file mode 100644 index cb23b8e24b..0000000000 --- a/drivers/freetype/freetype/include/ft2build.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* ft2build.h */ -/* */ -/* FreeType 2 build and setup macros. */ -/* (Generic version) */ -/* */ -/* Copyright 1996-2001, 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file corresponds to the default `ft2build.h' file for */ - /* FreeType 2. It uses the `freetype' include root. */ - /* */ - /* Note that specific platforms might use a different configuration. */ - /* See builds/unix/ft2unix.h for an example. */ - /* */ - /*************************************************************************/ - - -#ifndef __FT2_BUILD_GENERIC_H__ -#define __FT2_BUILD_GENERIC_H__ - -#define FT2_BUILD_LIBRARY -#include <freetype/config/ftheader.h> - -#endif /* __FT2_BUILD_GENERIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/Jamfile b/drivers/freetype/freetype/src/Jamfile deleted file mode 100644 index 76ee0f46e6..0000000000 --- a/drivers/freetype/freetype/src/Jamfile +++ /dev/null @@ -1,25 +0,0 @@ -# FreeType 2 src Jamfile -# -# Copyright 2001, 2002 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) ; - -# The file <freetype/internal/internal.h> is used to define macros that are -# later used in #include statements. It needs to be parsed in order to -# record these definitions. -# -HDRMACRO [ FT2_SubDir $(FT2_INCLUDE_DIR) internal internal.h ] ; - -for xx in $(FT2_COMPONENTS) -{ - SubInclude FT2_TOP $(FT2_SRC_DIR) $(xx) ; -} - -# end of src Jamfile diff --git a/drivers/freetype/freetype/src/autofit/Jamfile b/drivers/freetype/freetype/src/autofit/Jamfile deleted file mode 100644 index 2714765b5b..0000000000 --- a/drivers/freetype/freetype/src/autofit/Jamfile +++ /dev/null @@ -1,39 +0,0 @@ -# FreeType 2 src/autofit Jamfile -# -# Copyright 2003, 2004, 2005, 2006, 2007, 2009 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. - -SubDir FT2_TOP src autofit ; - -{ - local _sources ; - - # define FT2_AUTOFIT2 to enable experimental latin hinter replacement - if $(FT2_AUTOFIT2) - { - DEFINES += FT_OPTION_AUTOFIT2 ; - } - if $(FT2_MULTI) - { - _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp afpic ; - - if $(FT2_AUTOFIT2) - { - _sources += aflatin2 ; - } - } - else - { - _sources = autofit ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/autofit Jamfile diff --git a/drivers/freetype/freetype/src/autofit/afangles.c b/drivers/freetype/freetype/src/autofit/afangles.c deleted file mode 100644 index b44a5ba2c6..0000000000 --- a/drivers/freetype/freetype/src/autofit/afangles.c +++ /dev/null @@ -1,345 +0,0 @@ -/***************************************************************************/ -/* */ -/* afangles.c */ -/* */ -/* Routines used to compute vector angles with limited accuracy */ -/* and very high speed. It also contains sorting routines (body). */ -/* */ -/* Copyright 2003-2006, 2011-2012 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 "aftypes.h" - - -#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 /* 0 */ - - - /* - * 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 */ - -#define AF_ATAN_BITS 8 - - static const FT_Byte af_arctan[1L << AF_ATAN_BITS] = - { - 0, 0, 1, 1, 1, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 5, - 5, 5, 6, 6, 6, 7, 7, 7, - 8, 8, 8, 9, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 12, 12, 12, - 13, 13, 13, 14, 14, 14, 14, 15, - 15, 15, 16, 16, 16, 17, 17, 17, - 18, 18, 18, 18, 19, 19, 19, 20, - 20, 20, 21, 21, 21, 21, 22, 22, - 22, 23, 23, 23, 24, 24, 24, 24, - 25, 25, 25, 26, 26, 26, 26, 27, - 27, 27, 28, 28, 28, 28, 29, 29, - 29, 30, 30, 30, 30, 31, 31, 31, - 31, 32, 32, 32, 33, 33, 33, 33, - 34, 34, 34, 34, 35, 35, 35, 35, - 36, 36, 36, 36, 37, 37, 37, 38, - 38, 38, 38, 39, 39, 39, 39, 40, - 40, 40, 40, 41, 41, 41, 41, 42, - 42, 42, 42, 42, 43, 43, 43, 43, - 44, 44, 44, 44, 45, 45, 45, 45, - 46, 46, 46, 46, 46, 47, 47, 47, - 47, 48, 48, 48, 48, 48, 49, 49, - 49, 49, 50, 50, 50, 50, 50, 51, - 51, 51, 51, 51, 52, 52, 52, 52, - 52, 53, 53, 53, 53, 53, 54, 54, - 54, 54, 54, 55, 55, 55, 55, 55, - 56, 56, 56, 56, 56, 57, 57, 57, - 57, 57, 57, 58, 58, 58, 58, 58, - 59, 59, 59, 59, 59, 59, 60, 60, - 60, 60, 60, 61, 61, 61, 61, 61, - 61, 62, 62, 62, 62, 62, 62, 63, - 63, 63, 63, 63, 63, 64, 64, 64 - }; - - - FT_LOCAL_DEF( AF_Angle ) - af_angle_atan( FT_Fixed dx, - FT_Fixed dy ) - { - AF_Angle angle; - - - /* check trivial cases */ - if ( dy == 0 ) - { - angle = 0; - if ( dx < 0 ) - angle = AF_ANGLE_PI; - return angle; - } - else if ( dx == 0 ) - { - angle = AF_ANGLE_PI2; - if ( dy < 0 ) - angle = -AF_ANGLE_PI2; - return angle; - } - - angle = 0; - if ( dx < 0 ) - { - dx = -dx; - dy = -dy; - angle = AF_ANGLE_PI; - } - - if ( dy < 0 ) - { - FT_Pos tmp; - - - tmp = dx; - dx = -dy; - dy = tmp; - angle -= AF_ANGLE_PI2; - } - - if ( dx == 0 && dy == 0 ) - return 0; - - if ( dx == dy ) - angle += AF_ANGLE_PI4; - else if ( dx > dy ) - angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )]; - else - angle += AF_ANGLE_PI2 - - af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )]; - - if ( angle > AF_ANGLE_PI ) - angle -= AF_ANGLE_2PI; - - return angle; - } - - -#endif /* 0 */ - - - FT_LOCAL_DEF( void ) - af_sort_pos( FT_UInt count, - FT_Pos* table ) - { - FT_UInt i, j; - FT_Pos swap; - - - for ( i = 1; i < count; i++ ) - { - for ( j = i; j > 0; j-- ) - { - if ( table[j] >= table[j - 1] ) - break; - - swap = table[j]; - table[j] = table[j - 1]; - table[j - 1] = swap; - } - } - } - - - FT_LOCAL_DEF( void ) - af_sort_and_quantize_widths( FT_UInt* count, - AF_Width table, - FT_Pos threshold ) - { - FT_UInt i, j; - FT_UInt cur_idx; - FT_Pos cur_val; - FT_Pos sum; - AF_WidthRec swap; - - - if ( *count == 1 ) - return; - - /* sort */ - for ( i = 1; i < *count; i++ ) - { - for ( j = i; j > 0; j-- ) - { - if ( table[j].org >= table[j - 1].org ) - break; - - swap = table[j]; - table[j] = table[j - 1]; - table[j - 1] = swap; - } - } - - cur_idx = 0; - cur_val = table[cur_idx].org; - - /* compute and use mean values for clusters not larger than */ - /* `threshold'; this is very primitive and might not yield */ - /* the best result, but normally, using reference character */ - /* `o', `*count' is 2, so the code below is fully sufficient */ - for ( i = 1; i < *count; i++ ) - { - if ( table[i].org - cur_val > threshold || - i == *count - 1 ) - { - sum = 0; - - /* fix loop for end of array */ - if ( table[i].org - cur_val <= threshold && - i == *count - 1 ) - i++; - - for ( j = cur_idx; j < i; j++ ) - { - sum += table[j].org; - table[j].org = 0; - } - table[cur_idx].org = sum / j; - - if ( i < *count - 1 ) - { - cur_idx = i + 1; - cur_val = table[cur_idx].org; - } - } - } - - cur_idx = 1; - - /* compress array to remove zero values */ - for ( i = 1; i < *count; i++ ) - { - if ( table[i].org ) - table[cur_idx++] = table[i]; - } - - *count = cur_idx; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afangles.h b/drivers/freetype/freetype/src/autofit/afangles.h deleted file mode 100644 index f33f9e108e..0000000000 --- a/drivers/freetype/freetype/src/autofit/afangles.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * afangles.h - * - * This is a dummy file, used to please the build system. It is never - * included by the auto-fitter sources. - * - */ diff --git a/drivers/freetype/freetype/src/autofit/afcjk.c b/drivers/freetype/freetype/src/autofit/afcjk.c deleted file mode 100644 index f69a528e3b..0000000000 --- a/drivers/freetype/freetype/src/autofit/afcjk.c +++ /dev/null @@ -1,2275 +0,0 @@ -/***************************************************************************/ -/* */ -/* afcjk.c */ -/* */ -/* Auto-fitter hinting routines for CJK script (body). */ -/* */ -/* Copyright 2006-2013 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. */ -/* */ -/***************************************************************************/ - - /* - * The algorithm is based on akito's autohint patch, available here: - * - * http://www.kde.gr.jp/~akito/patch/freetype2/ - * - */ - -#include <ft2build.h> -#include FT_ADVANCES_H -#include FT_INTERNAL_DEBUG_H - -#include "aftypes.h" -#include "aflatin.h" - - -#ifdef AF_CONFIG_OPTION_CJK - -#undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - -#include "afcjk.h" -#include "aferrors.h" - - -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.h" -#endif - - - /*************************************************************************/ - /* */ - /* 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_afcjk - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** C J K G L O B A L M E T R I C S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* Basically the Latin version with AF_CJKMetrics */ - /* to replace AF_LatinMetrics. */ - - FT_LOCAL_DEF( void ) - af_cjk_metrics_init_widths( AF_CJKMetrics metrics, - FT_Face face ) - { - /* scan the array of segments in each direction */ - AF_GlyphHintsRec hints[1]; - - - af_glyph_hints_init( hints, face->memory ); - - metrics->axis[AF_DIMENSION_HORZ].width_count = 0; - metrics->axis[AF_DIMENSION_VERT].width_count = 0; - - { - FT_Error error; - FT_UInt glyph_index; - int dim; - AF_CJKMetricsRec dummy[1]; - AF_Scaler scaler = &dummy->root.scaler; - - - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); - if ( glyph_index == 0 ) - goto Exit; - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || face->glyph->outline.n_points <= 0 ) - goto Exit; - - FT_ZERO( dummy ); - - dummy->units_per_em = metrics->units_per_em; - - scaler->x_scale = 0x10000L; - scaler->y_scale = 0x10000L; - scaler->x_delta = 0; - scaler->y_delta = 0; - - scaler->face = face; - scaler->render_mode = FT_RENDER_MODE_NORMAL; - scaler->flags = 0; - - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); - - error = af_glyph_hints_reload( hints, &face->glyph->outline ); - if ( error ) - goto Exit; - - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_CJKAxis axis = &metrics->axis[dim]; - AF_AxisHints axhints = &hints->axis[dim]; - AF_Segment seg, limit, link; - FT_UInt num_widths = 0; - - - error = af_latin_hints_compute_segments( hints, (AF_Dimension)dim ); - if ( error ) - goto Exit; - - af_latin_hints_link_segments( hints, (AF_Dimension)dim ); - - seg = axhints->segments; - limit = seg + axhints->num_segments; - - for ( ; seg < limit; seg++ ) - { - link = seg->link; - - /* we only consider stem segments there! */ - if ( link && link->link == seg && link > seg ) - { - FT_Pos dist; - - - dist = seg->pos - link->pos; - if ( dist < 0 ) - dist = -dist; - - if ( num_widths < AF_CJK_MAX_WIDTHS ) - axis->widths[num_widths++].org = dist; - } - } - - /* this also replaces multiple almost identical stem widths */ - /* with a single one (the value 100 is heuristic) */ - af_sort_and_quantize_widths( &num_widths, axis->widths, - dummy->units_per_em / 100 ); - axis->width_count = num_widths; - } - - Exit: - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_CJKAxis axis = &metrics->axis[dim]; - FT_Pos stdw; - - - stdw = ( axis->width_count > 0 ) ? axis->widths[0].org - : AF_LATIN_CONSTANT( metrics, 50 ); - - /* let's try 20% of the smallest width */ - axis->edge_distance_threshold = stdw / 5; - axis->standard_width = stdw; - axis->extra_light = 0; - } - } - - af_glyph_hints_done( hints ); - } - - -#define AF_CJK_MAX_TEST_CHARACTERS 32 - - - /* Each blue zone has two types of fill and unfill, this is, */ - /* filling the entire glyph square or not. */ - - enum - { - AF_CJK_BLUE_TYPE_FILL, - AF_CJK_BLUE_TYPE_UNFILL, - AF_CJK_BLUE_TYPE_MAX - }; - - - /* Put some common and representative Han Ideographs characters here. */ - static const FT_ULong af_cjk_hani_blue_chars[AF_CJK_BLUE_MAX] - [AF_CJK_BLUE_TYPE_MAX] - [AF_CJK_MAX_TEST_CHARACTERS] = - { - { - { - 0x4ED6, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730, - 0x5BF9, 0x5C0D, 0x5C31, 0x5E2D, 0x6211, 0x65F6, 0x6642, 0x6703, - 0x6765, 0x70BA, 0x80FD, 0x8230, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019, - 0x9F4A /* top fill */ - }, - { - 0x519B, 0x540C, 0x5DF2, 0x613F, 0x65E2, 0x661F, 0x662F, 0x666F, - 0x6C11, 0x7167, 0x73B0, 0x73FE, 0x7406, 0x7528, 0x7F6E, 0x8981, - 0x8ECD, 0x90A3, 0x914D, 0x91CC, 0x958B, 0x96F7, 0x9732, 0x9762, - 0x987E /* top unfill */ - } - }, - { - { - 0x4E2A, 0x4E3A, 0x4EBA, 0x4ED6, 0x4EE5, 0x4EEC, 0x4F60, 0x4F86, - 0x500B, 0x5011, 0x5230, 0x548C, 0x5927, 0x5BF9, 0x5C0D, 0x5C31, - 0x6211, 0x65F6, 0x6642, 0x6709, 0x6765, 0x70BA, 0x8981, 0x8AAA, - 0x8BF4 /* bottom fill */ - }, - { - 0x4E3B, 0x4E9B, 0x56E0, 0x5B83, 0x60F3, 0x610F, 0x7406, 0x751F, - 0x7576, 0x770B, 0x7740, 0x7F6E, 0x8005, 0x81EA, 0x8457, 0x88E1, - 0x8FC7, 0x8FD8, 0x8FDB, 0x9032, 0x904E, 0x9053, 0x9084, 0x91CC, - 0x9762 /* bottom unfill */ - } - }, -#ifndef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - { {0x0000}, {0x0000} }, - { {0x0000}, {0x0000} } -#else - { - { - 0x4E9B, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730, - 0x5979, 0x5C06, 0x5C07, 0x5C31, 0x5E74, 0x5F97, 0x60C5, 0x6700, - 0x6837, 0x6A23, 0x7406, 0x80FD, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019, - 0x901A /* left fill */ - }, - { - 0x5373, 0x5417, 0x5427, 0x542C, 0x5462, 0x54C1, 0x54CD, 0x55CE, - 0x5E08, 0x5E2B, 0x6536, 0x65AD, 0x65B7, 0x660E, 0x773C, 0x9593, - 0x95F4, 0x9645, 0x9648, 0x9650, 0x9664, 0x9673, 0x968F, 0x969B, - 0x96A8 /* left unfill */ - } - }, - { - { - 0x4E8B, 0x524D, 0x5B78, 0x5C06, 0x5C07, 0x60C5, 0x60F3, 0x6216, - 0x653F, 0x65AF, 0x65B0, 0x6837, 0x6A23, 0x6C11, 0x6C92, 0x6CA1, - 0x7136, 0x7279, 0x73B0, 0x73FE, 0x7403, 0x7B2C, 0x7D93, 0x8C01, - 0x8D77 /* right fill */ - }, - { - 0x4F8B, 0x5225, 0x522B, 0x5236, 0x52A8, 0x52D5, 0x5417, 0x55CE, - 0x589E, 0x6307, 0x660E, 0x671D, 0x671F, 0x6784, 0x7269, 0x786E, - 0x79CD, 0x8ABF, 0x8C03, 0x8CBB, 0x8D39, 0x90A3, 0x90FD, 0x9593, - 0x95F4 /* right unfill */ - } - } -#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ - }; - - - /* Calculate blue zones for all the CJK_BLUE_XXX's. */ - - static void - af_cjk_metrics_init_blues( AF_CJKMetrics metrics, - FT_Face face, - const FT_ULong blue_chars - [AF_CJK_BLUE_MAX] - [AF_CJK_BLUE_TYPE_MAX] - [AF_CJK_MAX_TEST_CHARACTERS] ) - { - FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS]; - FT_Pos flats[AF_CJK_MAX_TEST_CHARACTERS]; - - FT_Int num_fills; - FT_Int num_flats; - - FT_Int bb; - AF_CJKBlue blue; - FT_Error error; - AF_CJKAxis axis; - FT_GlyphSlot glyph = face->glyph; - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_String* cjk_blue_name[AF_CJK_BLUE_MAX] = { - (FT_String*)"top", - (FT_String*)"bottom", - (FT_String*)"left", - (FT_String*)"right" - }; - FT_String* cjk_blue_type_name[AF_CJK_BLUE_TYPE_MAX] = { - (FT_String*)"filled", - (FT_String*)"unfilled" - }; -#endif - - - /* We compute the blues simply by loading each character from the */ - /* `blue_chars[blues]' string, then computing its extreme points */ - /* (depending blue zone type etc.). */ - - FT_TRACE5(( "cjk blue zones computation\n" )); - FT_TRACE5(( "------------------------------------------------\n" )); - - for ( bb = 0; bb < AF_CJK_BLUE_MAX; bb++ ) - { - FT_Int fill_type; - FT_Pos* blue_ref; - FT_Pos* blue_shoot; - - - num_fills = 0; - num_flats = 0; - - for ( fill_type = 0; fill_type < AF_CJK_BLUE_TYPE_MAX; fill_type++ ) - { - const FT_ULong* p = blue_chars[bb][fill_type]; - const FT_ULong* limit = p + AF_CJK_MAX_TEST_CHARACTERS; - FT_Bool fill = FT_BOOL( - fill_type == AF_CJK_BLUE_TYPE_FILL ); - - - FT_TRACE5(( "cjk blue %s/%s\n", cjk_blue_name[bb], - cjk_blue_type_name[fill_type] )); - - - for ( ; p < limit && *p; p++ ) - { - FT_UInt glyph_index; - FT_Pos best_pos; /* same as points.y */ - FT_Int best_point; - FT_Vector* points; - - - FT_TRACE5(( " U+%lX...", *p )); - - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, *p ); - if ( glyph_index == 0 ) - { - FT_TRACE5(( "unavailable\n" )); - continue; - } - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || glyph->outline.n_points <= 0 ) - { - FT_TRACE5(( "no outline\n" )); - continue; - } - - /* now compute min or max point indices and coordinates */ - points = glyph->outline.points; - best_point = -1; - best_pos = 0; /* make compiler happy */ - - { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; - - - for ( nn = 0; - nn < glyph->outline.n_contours; - first = last + 1, nn++ ) - { - FT_Int pp; - - - last = glyph->outline.contours[nn]; - - /* Avoid single-point contours since they are never */ - /* rasterized. In some fonts, they correspond to mark */ - /* attachment points which are way outside of the glyph's */ - /* real outline. */ - if ( last <= first ) - continue; - - switch ( bb ) - { - case AF_CJK_BLUE_TOP: - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_pos ) - { - best_point = pp; - best_pos = points[pp].y; - } - break; - - case AF_CJK_BLUE_BOTTOM: - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_pos ) - { - best_point = pp; - best_pos = points[pp].y; - } - break; - - case AF_CJK_BLUE_LEFT: - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].x < best_pos ) - { - best_point = pp; - best_pos = points[pp].x; - } - break; - - case AF_CJK_BLUE_RIGHT: - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].x > best_pos ) - { - best_point = pp; - best_pos = points[pp].x; - } - break; - - default: - ; - } - } - FT_TRACE5(( "best_pos=%5ld\n", best_pos )); - } - - if ( fill ) - fills[num_fills++] = best_pos; - else - flats[num_flats++] = best_pos; - } - } - - if ( num_flats == 0 && num_fills == 0 ) - { - /* - * we couldn't find a single glyph to compute this blue zone, - * we will simply ignore it then - */ - FT_TRACE5(( "empty\n" )); - continue; - } - - /* we have computed the contents of the `fill' and `flats' tables, */ - /* now determine the reference position of the blue -- */ - /* we simply take the median value after a simple sort */ - af_sort_pos( num_flats, flats ); - af_sort_pos( num_fills, fills ); - - if ( AF_CJK_BLUE_TOP == bb || AF_CJK_BLUE_BOTTOM == bb ) - axis = &metrics->axis[AF_DIMENSION_VERT]; - else - axis = &metrics->axis[AF_DIMENSION_HORZ]; - - blue = & axis->blues[axis->blue_count]; - blue_ref = & blue->ref.org; - blue_shoot = & blue->shoot.org; - - axis->blue_count++; - if ( num_flats == 0 ) - { - *blue_ref = fills[num_fills / 2]; - *blue_shoot = fills[num_fills / 2]; - } - else if ( num_fills == 0 ) - { - *blue_ref = flats[num_flats / 2]; - *blue_shoot = flats[num_flats / 2]; - } - else - { - *blue_ref = fills[num_fills / 2]; - *blue_shoot = flats[num_flats / 2]; - } - - /* make sure blue_ref >= blue_shoot for top/right or */ - /* vice versa for bottom/left */ - if ( *blue_shoot != *blue_ref ) - { - FT_Pos ref = *blue_ref; - FT_Pos shoot = *blue_shoot; - FT_Bool under_ref = FT_BOOL( shoot < ref ); - - - if ( ( AF_CJK_BLUE_TOP == bb || - AF_CJK_BLUE_RIGHT == bb ) ^ under_ref ) - *blue_shoot = *blue_ref = ( shoot + ref ) / 2; - } - - blue->flags = 0; - if ( AF_CJK_BLUE_TOP == bb ) - blue->flags |= AF_CJK_BLUE_IS_TOP; - else if ( AF_CJK_BLUE_RIGHT == bb ) - blue->flags |= AF_CJK_BLUE_IS_RIGHT; - - FT_TRACE5(( "-- cjk %s bluezone ref = %ld shoot = %ld\n", - cjk_blue_name[bb], *blue_ref, *blue_shoot )); - } - - return; - } - - - /* Basically the Latin version with type AF_CJKMetrics for metrics. */ - FT_LOCAL_DEF( void ) - af_cjk_metrics_check_digits( AF_CJKMetrics metrics, - FT_Face face ) - { - FT_UInt i; - FT_Bool started = 0, same_width = 1; - FT_Fixed advance, old_advance = 0; - - - /* check whether all ASCII digits have the same advance width; */ - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) - { - FT_UInt glyph_index; - - - glyph_index = FT_Get_Char_Index( face, i ); - if ( glyph_index == 0 ) - continue; - - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) - continue; - - if ( started ) - { - if ( advance != old_advance ) - { - same_width = 0; - break; - } - } - else - { - old_advance = advance; - started = 1; - } - } - - metrics->root.digits_have_same_width = same_width; - } - - - FT_LOCAL_DEF( FT_Error ) - af_cjk_metrics_init( AF_CJKMetrics metrics, - FT_Face face ) - { - FT_CharMap oldmap = face->charmap; - - - metrics->units_per_em = face->units_per_EM; - - if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) - face->charmap = NULL; - else - { - af_cjk_metrics_init_widths( metrics, face ); - af_cjk_metrics_init_blues( metrics, face, af_cjk_hani_blue_chars ); - af_cjk_metrics_check_digits( metrics, face ); - } - - FT_Set_Charmap( face, oldmap ); - - return FT_Err_Ok; - } - - - static void - af_cjk_metrics_scale_dim( AF_CJKMetrics metrics, - AF_Scaler scaler, - AF_Dimension dim ) - { - FT_Fixed scale; - FT_Pos delta; - AF_CJKAxis axis; - FT_UInt nn; - - - axis = &metrics->axis[dim]; - - if ( dim == AF_DIMENSION_HORZ ) - { - scale = scaler->x_scale; - delta = scaler->x_delta; - } - else - { - scale = scaler->y_scale; - delta = scaler->y_delta; - } - - if ( axis->org_scale == scale && axis->org_delta == delta ) - return; - - axis->org_scale = scale; - axis->org_delta = delta; - - axis->scale = scale; - axis->delta = delta; - - /* scale the blue zones */ - for ( nn = 0; nn < axis->blue_count; nn++ ) - { - AF_CJKBlue blue = &axis->blues[nn]; - FT_Pos dist; - - - blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; - blue->ref.fit = blue->ref.cur; - blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; - blue->shoot.fit = blue->shoot.cur; - blue->flags &= ~AF_CJK_BLUE_ACTIVE; - - /* a blue zone is only active if it is less than 3/4 pixels tall */ - dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); - if ( dist <= 48 && dist >= -48 ) - { - FT_Pos delta1, delta2; - - - blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); - - /* shoot is under shoot for cjk */ - delta1 = FT_DivFix( blue->ref.fit, scale ) - blue->shoot.org; - delta2 = delta1; - if ( delta1 < 0 ) - delta2 = -delta2; - - delta2 = FT_MulFix( delta2, scale ); - - FT_TRACE5(( "delta: %d", delta1 )); - if ( delta2 < 32 ) - delta2 = 0; -#if 0 - else if ( delta2 < 64 ) - delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); -#endif - else - delta2 = FT_PIX_ROUND( delta2 ); - FT_TRACE5(( "/%d\n", delta2 )); - - if ( delta1 < 0 ) - delta2 = -delta2; - - blue->shoot.fit = blue->ref.fit - delta2; - - FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]: " - "ref: cur=%.2f fit=%.2f shoot: cur=%.2f fit=%.2f\n", - ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V', - nn, blue->ref.org, blue->shoot.org, - blue->ref.cur / 64.0, blue->ref.fit / 64.0, - blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); - - blue->flags |= AF_CJK_BLUE_ACTIVE; - } - } - } - - - FT_LOCAL_DEF( void ) - af_cjk_metrics_scale( AF_CJKMetrics metrics, - AF_Scaler scaler ) - { - metrics->root.scaler = *scaler; - - af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); - af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** C J K G L Y P H A N A L Y S I S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_Error - af_cjk_hints_compute_segments( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; - FT_Error error; - AF_Segment seg; - - - error = af_latin_hints_compute_segments( hints, dim ); - if ( error ) - return error; - - /* a segment is round if it doesn't have successive */ - /* on-curve points. */ - for ( seg = segments; seg < segment_limit; seg++ ) - { - AF_Point pt = seg->first; - AF_Point last = seg->last; - AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); - AF_Flags f1; - - - seg->flags &= ~AF_EDGE_ROUND; - - for ( ; pt != last; f0 = f1 ) - { - pt = pt->next; - f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); - - if ( !f0 && !f1 ) - break; - - if ( pt == last ) - seg->flags |= AF_EDGE_ROUND; - } - } - - return FT_Err_Ok; - } - - - static void - af_cjk_hints_link_segments( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; - AF_Direction major_dir = axis->major_dir; - AF_Segment seg1, seg2; - FT_Pos len_threshold; - FT_Pos dist_threshold; - - - len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); - - dist_threshold = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale - : hints->y_scale; - dist_threshold = FT_DivFix( 64 * 3, dist_threshold ); - - /* now compare each segment to the others */ - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - /* the fake segments are for metrics hinting only */ - if ( seg1->first == seg1->last ) - continue; - - if ( seg1->dir != major_dir ) - continue; - - for ( seg2 = segments; seg2 < segment_limit; seg2++ ) - if ( seg2 != seg1 && seg1->dir + seg2->dir == 0 ) - { - FT_Pos dist = seg2->pos - seg1->pos; - - - if ( dist < 0 ) - continue; - - { - FT_Pos min = seg1->min_coord; - FT_Pos max = seg1->max_coord; - FT_Pos len; - - - if ( min < seg2->min_coord ) - min = seg2->min_coord; - - if ( max > seg2->max_coord ) - max = seg2->max_coord; - - len = max - min; - if ( len >= len_threshold ) - { - if ( dist * 8 < seg1->score * 9 && - ( dist * 8 < seg1->score * 7 || seg1->len < len ) ) - { - seg1->score = dist; - seg1->len = len; - seg1->link = seg2; - } - - if ( dist * 8 < seg2->score * 9 && - ( dist * 8 < seg2->score * 7 || seg2->len < len ) ) - { - seg2->score = dist; - seg2->len = len; - seg2->link = seg1; - } - } - } - } - } - - /* - * now compute the `serif' segments - * - * In Hanzi, some strokes are wider on one or both of the ends. - * We either identify the stems on the ends as serifs or remove - * the linkage, depending on the length of the stems. - * - */ - - { - AF_Segment link1, link2; - - - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - link1 = seg1->link; - if ( !link1 || link1->link != seg1 || link1->pos <= seg1->pos ) - continue; - - if ( seg1->score >= dist_threshold ) - continue; - - for ( seg2 = segments; seg2 < segment_limit; seg2++ ) - { - if ( seg2->pos > seg1->pos || seg1 == seg2 ) - continue; - - link2 = seg2->link; - if ( !link2 || link2->link != seg2 || link2->pos < link1->pos ) - continue; - - if ( seg1->pos == seg2->pos && link1->pos == link2->pos ) - continue; - - if ( seg2->score <= seg1->score || seg1->score * 4 <= seg2->score ) - continue; - - /* seg2 < seg1 < link1 < link2 */ - - if ( seg1->len >= seg2->len * 3 ) - { - AF_Segment seg; - - - for ( seg = segments; seg < segment_limit; seg++ ) - { - AF_Segment link = seg->link; - - - if ( link == seg2 ) - { - seg->link = 0; - seg->serif = link1; - } - else if ( link == link2 ) - { - seg->link = 0; - seg->serif = seg1; - } - } - } - else - { - seg1->link = link1->link = 0; - - break; - } - } - } - } - - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - seg2 = seg1->link; - - if ( seg2 ) - { - seg2->num_linked++; - if ( seg2->link != seg1 ) - { - seg1->link = 0; - - if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 ) - seg1->serif = seg2->link; - else - seg2->num_linked--; - } - } - } - } - - - static FT_Error - af_cjk_hints_compute_edges( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - FT_Error error = FT_Err_Ok; - FT_Memory memory = hints->memory; - AF_CJKAxis laxis = &((AF_CJKMetrics)hints->metrics)->axis[dim]; - - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; - AF_Segment seg; - - FT_Fixed scale; - FT_Pos edge_distance_threshold; - - - axis->num_edges = 0; - - scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale - : hints->y_scale; - - /*********************************************************************/ - /* */ - /* We begin by generating a sorted table of edges for the current */ - /* direction. To do so, we simply scan each segment and try to find */ - /* an edge in our table that corresponds to its position. */ - /* */ - /* If no edge is found, we create and insert a new edge in the */ - /* sorted table. Otherwise, we simply add the segment to the edge's */ - /* list which is then processed in the second step to compute the */ - /* edge's properties. */ - /* */ - /* Note that the edges table is sorted along the segment/edge */ - /* position. */ - /* */ - /*********************************************************************/ - - edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, - scale ); - if ( edge_distance_threshold > 64 / 4 ) - edge_distance_threshold = FT_DivFix( 64 / 4, scale ); - else - edge_distance_threshold = laxis->edge_distance_threshold; - - for ( seg = segments; seg < segment_limit; seg++ ) - { - AF_Edge found = 0; - FT_Pos best = 0xFFFFU; - FT_Int ee; - - - /* look for an edge corresponding to the segment */ - for ( ee = 0; ee < axis->num_edges; ee++ ) - { - AF_Edge edge = axis->edges + ee; - FT_Pos dist; - - - if ( edge->dir != seg->dir ) - continue; - - dist = seg->pos - edge->fpos; - if ( dist < 0 ) - dist = -dist; - - if ( dist < edge_distance_threshold && dist < best ) - { - AF_Segment link = seg->link; - - - /* check whether all linked segments of the candidate edge */ - /* can make a single edge. */ - if ( link ) - { - AF_Segment seg1 = edge->first; - FT_Pos dist2 = 0; - - - do - { - AF_Segment link1 = seg1->link; - - - if ( link1 ) - { - dist2 = AF_SEGMENT_DIST( link, link1 ); - if ( dist2 >= edge_distance_threshold ) - break; - } - - } while ( ( seg1 = seg1->edge_next ) != edge->first ); - - if ( dist2 >= edge_distance_threshold ) - continue; - } - - best = dist; - found = edge; - } - } - - if ( !found ) - { - AF_Edge edge; - - - /* insert a new edge in the list and */ - /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, - (AF_Direction)seg->dir, - memory, &edge ); - if ( error ) - goto Exit; - - /* add the segment to the new edge's list */ - FT_ZERO( edge ); - - edge->first = seg; - edge->last = seg; - edge->fpos = seg->pos; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); - seg->edge_next = seg; - edge->dir = seg->dir; - } - else - { - /* if an edge was found, simply add the segment to the edge's */ - /* list */ - seg->edge_next = found->first; - found->last->edge_next = seg; - found->last = seg; - } - } - - /*********************************************************************/ - /* */ - /* Good, we now compute each edge's properties according to segments */ - /* found on its position. Basically, these are as follows. */ - /* */ - /* - edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straight or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /*********************************************************************/ - - /* first of all, set the `edge' field in each segment -- this is */ - /* required in order to compute edge links */ - /* */ - /* Note that removing this loop and setting the `edge' field of each */ - /* segment directly in the code above slows down execution speed for */ - /* some reasons on platforms like the Sun. */ - - { - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - AF_Edge edge; - - - for ( edge = edges; edge < edge_limit; edge++ ) - { - seg = edge->first; - if ( seg ) - do - { - seg->edge = edge; - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - - /* now compute each edge properties */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - FT_Int is_round = 0; /* does it contain round segments? */ - FT_Int is_straight = 0; /* does it contain straight segments? */ - - - seg = edge->first; - - do - { - FT_Bool is_serif; - - - /* check for roundness of segment */ - if ( seg->flags & AF_EDGE_ROUND ) - is_round++; - else - is_straight++; - - /* check for links -- if seg->serif is set, then seg->link must */ - /* be ignored */ - is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge ); - - if ( seg->link || is_serif ) - { - AF_Edge edge2; - AF_Segment seg2; - - - edge2 = edge->link; - seg2 = seg->link; - - if ( is_serif ) - { - seg2 = seg->serif; - edge2 = edge->serif; - } - - if ( edge2 ) - { - FT_Pos edge_delta; - FT_Pos seg_delta; - - - edge_delta = edge->fpos - edge2->fpos; - if ( edge_delta < 0 ) - edge_delta = -edge_delta; - - seg_delta = AF_SEGMENT_DIST( seg, seg2 ); - - if ( seg_delta < edge_delta ) - edge2 = seg2->edge; - } - else - edge2 = seg2->edge; - - if ( is_serif ) - { - edge->serif = edge2; - edge2->flags |= AF_EDGE_SERIF; - } - else - edge->link = edge2; - } - - seg = seg->edge_next; - - } while ( seg != edge->first ); - - /* set the round/straight flags */ - edge->flags = AF_EDGE_NORMAL; - - if ( is_round > 0 && is_round >= is_straight ) - edge->flags |= AF_EDGE_ROUND; - - /* get rid of serifs if link is set */ - /* XXX: This gets rid of many unpleasant artefacts! */ - /* Example: the `c' in cour.pfa at size 13 */ - - if ( edge->serif && edge->link ) - edge->serif = 0; - } - } - - Exit: - return error; - } - - - static FT_Error - af_cjk_hints_detect_features( AF_GlyphHints hints, - AF_Dimension dim ) - { - FT_Error error; - - - error = af_cjk_hints_compute_segments( hints, dim ); - if ( !error ) - { - af_cjk_hints_link_segments( hints, dim ); - - error = af_cjk_hints_compute_edges( hints, dim ); - } - return error; - } - - - FT_LOCAL_DEF( void ) - af_cjk_hints_compute_blue_edges( AF_GlyphHints hints, - AF_CJKMetrics metrics, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Edge edge = axis->edges; - AF_Edge edge_limit = edge + axis->num_edges; - AF_CJKAxis cjk = &metrics->axis[dim]; - FT_Fixed scale = cjk->scale; - FT_Pos best_dist0; /* initial threshold */ - - - /* compute the initial threshold as a fraction of the EM size */ - best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); - - if ( best_dist0 > 64 / 2 ) /* maximum 1/2 pixel */ - best_dist0 = 64 / 2; - - /* compute which blue zones are active, i.e. have their scaled */ - /* size < 3/4 pixels */ - - /* If the distant between an edge and a blue zone is shorter than */ - /* best_dist0, set the blue zone for the edge. Then search for */ - /* the blue zone with the smallest best_dist to the edge. */ - - for ( ; edge < edge_limit; edge++ ) - { - FT_UInt bb; - AF_Width best_blue = NULL; - FT_Pos best_dist = best_dist0; - - - for ( bb = 0; bb < cjk->blue_count; bb++ ) - { - AF_CJKBlue blue = cjk->blues + bb; - FT_Bool is_top_right_blue, is_major_dir; - - - /* skip inactive blue zones (i.e., those that are too small) */ - if ( !( blue->flags & AF_CJK_BLUE_ACTIVE ) ) - continue; - - /* if it is a top zone, check for right edges -- if it is a bottom */ - /* zone, check for left edges */ - /* */ - /* of course, that's for TrueType */ - is_top_right_blue = - FT_BOOL( ( ( blue->flags & AF_CJK_BLUE_IS_TOP ) != 0 ) || - ( ( blue->flags & AF_CJK_BLUE_IS_RIGHT ) != 0 ) ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); - - /* if it is a top zone, the edge must be against the major */ - /* direction; if it is a bottom zone, it must be in the major */ - /* direction */ - if ( is_top_right_blue ^ is_major_dir ) - { - FT_Pos dist; - AF_Width compare; - - - /* Compare the edge to the closest blue zone type */ - if ( FT_ABS( edge->fpos - blue->ref.org ) > - FT_ABS( edge->fpos - blue->shoot.org ) ) - compare = &blue->shoot; - else - compare = &blue->ref; - - dist = edge->fpos - compare->org; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = compare; - } - } - } - - if ( best_blue ) - edge->blue_edge = best_blue; - } - } - - - FT_LOCAL_DEF( FT_Error ) - af_cjk_hints_init( AF_GlyphHints hints, - AF_CJKMetrics metrics ) - { - FT_Render_Mode mode; - FT_UInt32 scaler_flags, other_flags; - - - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); - - /* - * correct x_scale and y_scale when needed, since they may have - * been modified af_cjk_scale_dim above - */ - hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; - hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; - hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; - hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; - - /* compute flags depending on render mode, etc. */ - mode = metrics->root.scaler.render_mode; - -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) - metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; -#endif - - scaler_flags = hints->scaler_flags; - other_flags = 0; - - /* - * We snap the width of vertical stems for the monochrome and - * horizontal LCD rendering targets only. - */ - if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) - other_flags |= AF_LATIN_HINTS_HORZ_SNAP; - - /* - * We snap the width of horizontal stems for the monochrome and - * vertical LCD rendering targets only. - */ - if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) - other_flags |= AF_LATIN_HINTS_VERT_SNAP; - - /* - * We adjust stems to full pixels only if we don't use the `light' mode. - */ - if ( mode != FT_RENDER_MODE_LIGHT ) - other_flags |= AF_LATIN_HINTS_STEM_ADJUST; - - if ( mode == FT_RENDER_MODE_MONO ) - other_flags |= AF_LATIN_HINTS_MONO; - - scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE; - - hints->scaler_flags = scaler_flags; - hints->other_flags = other_flags; - - return 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** C J K G L Y P H G R I D - F I T T I N G *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* snap a given width in scaled coordinates to one of the */ - /* current standard widths */ - - static FT_Pos - af_cjk_snap_width( AF_Width widths, - FT_Int count, - FT_Pos width ) - { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; - - - for ( n = 0; n < count; n++ ) - { - FT_Pos w; - FT_Pos dist; - - - w = widths[n].cur; - dist = width - w; - if ( dist < 0 ) - dist = -dist; - if ( dist < best ) - { - best = dist; - reference = w; - } - } - - scaled = FT_PIX_ROUND( reference ); - - if ( width >= reference ) - { - if ( width < scaled + 48 ) - width = reference; - } - else - { - if ( width > scaled - 48 ) - width = reference; - } - - return width; - } - - - /* compute the snapped width of a given stem */ - - static FT_Pos - af_cjk_compute_stem_width( AF_GlyphHints hints, - AF_Dimension dim, - FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) - { - AF_CJKMetrics metrics = (AF_CJKMetrics) hints->metrics; - AF_CJKAxis axis = & metrics->axis[dim]; - FT_Pos dist = width; - FT_Int sign = 0; - FT_Bool vertical = FT_BOOL( dim == AF_DIMENSION_VERT ); - - FT_UNUSED( base_flags ); - FT_UNUSED( stem_flags ); - - - if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) - return width; - - if ( dist < 0 ) - { - dist = -width; - sign = 1; - } - - if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || - ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) - { - /* smooth hinting process: very lightly quantize the stem width */ - - if ( axis->width_count > 0 ) - { - if ( FT_ABS( dist - axis->widths[0].cur ) < 40 ) - { - dist = axis->widths[0].cur; - if ( dist < 48 ) - dist = 48; - - goto Done_Width; - } - } - - if ( dist < 54 ) - dist += ( 54 - dist ) / 2 ; - else if ( dist < 3 * 64 ) - { - FT_Pos delta; - - - delta = dist & 63; - dist &= -64; - - if ( delta < 10 ) - dist += delta; - else if ( delta < 22 ) - dist += 10; - else if ( delta < 42 ) - dist += delta; - else if ( delta < 54 ) - dist += 54; - else - dist += delta; - } - } - else - { - /* strong hinting process: snap the stem width to integer pixels */ - - dist = af_cjk_snap_width( axis->widths, axis->width_count, dist ); - - if ( vertical ) - { - /* in the case of vertical hinting, always round */ - /* the stem heights to integer pixels */ - - if ( dist >= 64 ) - dist = ( dist + 16 ) & ~63; - else - dist = 64; - } - else - { - if ( AF_LATIN_HINTS_DO_MONO( hints ) ) - { - /* monochrome horizontal hinting: snap widths to integer pixels */ - /* with a different threshold */ - - if ( dist < 64 ) - dist = 64; - else - dist = ( dist + 32 ) & ~63; - } - else - { - /* for horizontal anti-aliased hinting, we adopt a more subtle */ - /* approach: we strengthen small stems, round stems whose size */ - /* is between 1 and 2 pixels to an integer, otherwise nothing */ - - if ( dist < 48 ) - dist = ( dist + 64 ) >> 1; - - else if ( dist < 128 ) - dist = ( dist + 22 ) & ~63; - else - /* round otherwise to prevent color fringes in LCD mode */ - dist = ( dist + 32 ) & ~63; - } - } - } - - Done_Width: - if ( sign ) - dist = -dist; - - return dist; - } - - - /* align one stem edge relative to the previous stem edge */ - - static void - af_cjk_align_linked_edge( AF_GlyphHints hints, - AF_Dimension dim, - AF_Edge base_edge, - AF_Edge stem_edge ) - { - FT_Pos dist = stem_edge->opos - base_edge->opos; - - FT_Pos fitted_width = af_cjk_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); - - - stem_edge->pos = base_edge->pos + fitted_width; - } - - - static void - af_cjk_align_serif_edge( AF_GlyphHints hints, - AF_Edge base, - AF_Edge serif ) - { - FT_UNUSED( hints ); - - serif->pos = base->pos + ( serif->opos - base->opos ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** E D G E H I N T I N G ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define AF_LIGHT_MODE_MAX_HORZ_GAP 9 -#define AF_LIGHT_MODE_MAX_VERT_GAP 15 -#define AF_LIGHT_MODE_MAX_DELTA_ABS 14 - - - static FT_Pos - af_hint_normal_stem( AF_GlyphHints hints, - AF_Edge edge, - AF_Edge edge2, - FT_Pos anchor, - AF_Dimension dim ) - { - FT_Pos org_len, cur_len, org_center; - FT_Pos cur_pos1, cur_pos2; - FT_Pos d_off1, u_off1, d_off2, u_off2, delta; - FT_Pos offset; - FT_Pos threshold = 64; - - - if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) - { - if ( ( edge->flags & AF_EDGE_ROUND ) && - ( edge2->flags & AF_EDGE_ROUND ) ) - { - if ( dim == AF_DIMENSION_VERT ) - threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP; - else - threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP; - } - else - { - if ( dim == AF_DIMENSION_VERT ) - threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP / 3; - else - threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP / 3; - } - } - - org_len = edge2->opos - edge->opos; - cur_len = af_cjk_compute_stem_width( hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); - - org_center = ( edge->opos + edge2->opos ) / 2 + anchor; - cur_pos1 = org_center - cur_len / 2; - cur_pos2 = cur_pos1 + cur_len; - d_off1 = cur_pos1 - FT_PIX_FLOOR( cur_pos1 ); - d_off2 = cur_pos2 - FT_PIX_FLOOR( cur_pos2 ); - u_off1 = 64 - d_off1; - u_off2 = 64 - d_off2; - delta = 0; - - - if ( d_off1 == 0 || d_off2 == 0 ) - goto Exit; - - if ( cur_len <= threshold ) - { - if ( d_off2 < cur_len ) - { - if ( u_off1 <= d_off2 ) - delta = u_off1; - else - delta = -d_off2; - } - - goto Exit; - } - - if ( threshold < 64 ) - { - if ( d_off1 >= threshold || u_off1 >= threshold || - d_off2 >= threshold || u_off2 >= threshold ) - goto Exit; - } - - offset = cur_len & 63; - - if ( offset < 32 ) - { - if ( u_off1 <= offset || d_off2 <= offset ) - goto Exit; - } - else - offset = 64 - threshold; - - d_off1 = threshold - u_off1; - u_off1 = u_off1 - offset; - u_off2 = threshold - d_off2; - d_off2 = d_off2 - offset; - - if ( d_off1 <= u_off1 ) - u_off1 = -d_off1; - - if ( d_off2 <= u_off2 ) - u_off2 = -d_off2; - - if ( FT_ABS( u_off1 ) <= FT_ABS( u_off2 ) ) - delta = u_off1; - else - delta = u_off2; - - Exit: - -#if 1 - if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) - { - if ( delta > AF_LIGHT_MODE_MAX_DELTA_ABS ) - delta = AF_LIGHT_MODE_MAX_DELTA_ABS; - else if ( delta < -AF_LIGHT_MODE_MAX_DELTA_ABS ) - delta = -AF_LIGHT_MODE_MAX_DELTA_ABS; - } -#endif - - cur_pos1 += delta; - - if ( edge->opos < edge2->opos ) - { - edge->pos = cur_pos1; - edge2->pos = cur_pos1 + cur_len; - } - else - { - edge->pos = cur_pos1 + cur_len; - edge2->pos = cur_pos1; - } - - return delta; - } - - - static void - af_cjk_hint_edges( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - FT_PtrDist n_edges; - AF_Edge edge; - AF_Edge anchor = 0; - FT_Pos delta = 0; - FT_Int skipped = 0; - FT_Bool has_last_stem = FALSE; - FT_Pos last_stem_pos = 0; - - - /* we begin by aligning all stems relative to the blue zone */ - FT_TRACE5(( "==== cjk hinting %s edges =====\n", - dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); - - if ( AF_HINTS_DO_BLUES( hints ) ) - { - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Width blue; - AF_Edge edge1, edge2; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - blue = edge->blue_edge; - edge1 = NULL; - edge2 = edge->link; - - if ( blue ) - { - edge1 = edge; - } - else if ( edge2 && edge2->blue_edge ) - { - blue = edge2->blue_edge; - edge1 = edge2; - edge2 = edge; - } - - if ( !edge1 ) - continue; - - FT_TRACE5(( "CJKBLUE: edge %d @%d (opos=%.2f) snapped to (%.2f), " - "was (%.2f)\n", - edge1-edges, edge1->fpos, edge1->opos / 64.0, blue->fit / 64.0, - edge1->pos / 64.0 )); - - edge1->pos = blue->fit; - edge1->flags |= AF_EDGE_DONE; - - if ( edge2 && !edge2->blue_edge ) - { - af_cjk_align_linked_edge( hints, dim, edge1, edge2 ); - edge2->flags |= AF_EDGE_DONE; - } - - if ( !anchor ) - anchor = edge; - } - } - - /* now we align all stem edges. */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Edge edge2; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - /* skip all non-stem edges */ - edge2 = edge->link; - if ( !edge2 ) - { - skipped++; - continue; - } - - /* Some CJK characters have so many stems that - * the hinter is likely to merge two adjacent ones. - * To solve this problem, if either edge of a stem - * is too close to the previous one, we avoid - * aligning the two edges, but rather interpolate - * their locations at the end of this function in - * order to preserve the space between the stems. - */ - if ( has_last_stem && - ( edge->pos < last_stem_pos + 64 || - edge2->pos < last_stem_pos + 64 ) ) - { - skipped++; - continue; - } - - /* now align the stem */ - /* this should not happen, but it's better to be safe */ - if ( edge2->blue_edge ) - { - FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges )); - - af_cjk_align_linked_edge( hints, dim, edge2, edge ); - edge->flags |= AF_EDGE_DONE; - continue; - } - - if ( edge2 < edge ) - { - af_cjk_align_linked_edge( hints, dim, edge2, edge ); - edge->flags |= AF_EDGE_DONE; - /* We rarely reaches here it seems; - * usually the two edges belonging - * to one stem are marked as DONE together - */ - has_last_stem = TRUE; - last_stem_pos = edge->pos; - continue; - } - - if ( dim != AF_DIMENSION_VERT && !anchor ) - { - -#if 0 - if ( fixedpitch ) - { - AF_Edge left = edge; - AF_Edge right = edge_limit - 1; - AF_EdgeRec left1, left2, right1, right2; - FT_Pos target, center1, center2; - FT_Pos delta1, delta2, d1, d2; - - - while ( right > left && !right->link ) - right--; - - left1 = *left; - left2 = *left->link; - right1 = *right->link; - right2 = *right; - - delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2; - target = left->opos + ( right->opos - left->opos ) / 2 + delta - 16; - - delta1 = delta; - delta1 += af_hint_normal_stem( hints, left, left->link, - delta1, 0 ); - - if ( left->link != right ) - af_hint_normal_stem( hints, right->link, right, delta1, 0 ); - - center1 = left->pos + ( right->pos - left->pos ) / 2; - - if ( center1 >= target ) - delta2 = delta - 32; - else - delta2 = delta + 32; - - delta2 += af_hint_normal_stem( hints, &left1, &left2, delta2, 0 ); - - if ( delta1 != delta2 ) - { - if ( left->link != right ) - af_hint_normal_stem( hints, &right1, &right2, delta2, 0 ); - - center2 = left1.pos + ( right2.pos - left1.pos ) / 2; - - d1 = center1 - target; - d2 = center2 - target; - - if ( FT_ABS( d2 ) < FT_ABS( d1 ) ) - { - left->pos = left1.pos; - left->link->pos = left2.pos; - - if ( left->link != right ) - { - right->link->pos = right1.pos; - right->pos = right2.pos; - } - - delta1 = delta2; - } - } - - delta = delta1; - right->link->flags |= AF_EDGE_DONE; - right->flags |= AF_EDGE_DONE; - } - else - -#endif /* 0 */ - - delta = af_hint_normal_stem( hints, edge, edge2, 0, - AF_DIMENSION_HORZ ); - } - else - af_hint_normal_stem( hints, edge, edge2, delta, dim ); - -#if 0 - printf( "stem (%d,%d) adjusted (%.1f,%.1f)\n", - edge - edges, edge2 - edges, - ( edge->pos - edge->opos ) / 64.0, - ( edge2->pos - edge2->opos ) / 64.0 ); -#endif - - anchor = edge; - edge->flags |= AF_EDGE_DONE; - edge2->flags |= AF_EDGE_DONE; - has_last_stem = TRUE; - last_stem_pos = edge2->pos; - } - - /* make sure that lowercase m's maintain their symmetry */ - - /* In general, lowercase m's have six vertical edges if they are sans */ - /* serif, or twelve if they are with serifs. This implementation is */ - /* based on that assumption, and seems to work very well with most */ - /* faces. However, if for a certain face this assumption is not */ - /* true, the m is just rendered like before. In addition, any stem */ - /* correction will only be applied to symmetrical glyphs (even if the */ - /* glyph is not an m), so the potential for unwanted distortion is */ - /* relatively low. */ - - /* We don't handle horizontal edges since we can't easily assure that */ - /* the third (lowest) stem aligns with the base line; it might end up */ - /* one pixel higher or lower. */ - - n_edges = edge_limit - edges; - if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) - { - AF_Edge edge1, edge2, edge3; - FT_Pos dist1, dist2, span; - - - if ( n_edges == 6 ) - { - edge1 = edges; - edge2 = edges + 2; - edge3 = edges + 4; - } - else - { - edge1 = edges + 1; - edge2 = edges + 5; - edge3 = edges + 9; - } - - dist1 = edge2->opos - edge1->opos; - dist2 = edge3->opos - edge2->opos; - - span = dist1 - dist2; - if ( span < 0 ) - span = -span; - - if ( edge1->link == edge1 + 1 && - edge2->link == edge2 + 1 && - edge3->link == edge3 + 1 && span < 8 ) - { - delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); - edge3->pos -= delta; - if ( edge3->link ) - edge3->link->pos -= delta; - - /* move the serifs along with the stem */ - if ( n_edges == 12 ) - { - ( edges + 8 )->pos -= delta; - ( edges + 11 )->pos -= delta; - } - - edge3->flags |= AF_EDGE_DONE; - if ( edge3->link ) - edge3->link->flags |= AF_EDGE_DONE; - } - } - - if ( !skipped ) - return; - - /* - * now hint the remaining edges (serifs and single) in order - * to complete our processing - */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - if ( edge->flags & AF_EDGE_DONE ) - continue; - - if ( edge->serif ) - { - af_cjk_align_serif_edge( hints, edge->serif, edge ); - edge->flags |= AF_EDGE_DONE; - skipped--; - } - } - - if ( !skipped ) - return; - - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Edge before, after; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - before = after = edge; - - while ( --before >= edges ) - if ( before->flags & AF_EDGE_DONE ) - break; - - while ( ++after < edge_limit ) - if ( after->flags & AF_EDGE_DONE ) - break; - - if ( before >= edges || after < edge_limit ) - { - if ( before < edges ) - af_cjk_align_serif_edge( hints, after, edge ); - else if ( after >= edge_limit ) - af_cjk_align_serif_edge( hints, before, edge ); - else - { - if ( after->fpos == before->fpos ) - edge->pos = before->pos; - else - edge->pos = before->pos + - FT_MulDiv( edge->fpos - before->fpos, - after->pos - before->pos, - after->fpos - before->fpos ); - } - } - } - } - - - static void - af_cjk_align_edge_points( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = & hints->axis[dim]; - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - AF_Edge edge; - FT_Bool snapping; - - - snapping = FT_BOOL( ( dim == AF_DIMENSION_HORZ && - AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) || - ( dim == AF_DIMENSION_VERT && - AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ); - - for ( edge = edges; edge < edge_limit; edge++ ) - { - /* move the points of each segment */ - /* in each edge to the edge's position */ - AF_Segment seg = edge->first; - - - if ( snapping ) - { - do - { - AF_Point point = seg->first; - - - for (;;) - { - if ( dim == AF_DIMENSION_HORZ ) - { - point->x = edge->pos; - point->flags |= AF_FLAG_TOUCH_X; - } - else - { - point->y = edge->pos; - point->flags |= AF_FLAG_TOUCH_Y; - } - - if ( point == seg->last ) - break; - - point = point->next; - } - - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - else - { - FT_Pos delta = edge->pos - edge->opos; - - - do - { - AF_Point point = seg->first; - - - for (;;) - { - if ( dim == AF_DIMENSION_HORZ ) - { - point->x += delta; - point->flags |= AF_FLAG_TOUCH_X; - } - else - { - point->y += delta; - point->flags |= AF_FLAG_TOUCH_Y; - } - - if ( point == seg->last ) - break; - - point = point->next; - } - - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - } - } - - - FT_LOCAL_DEF( FT_Error ) - af_cjk_hints_apply( AF_GlyphHints hints, - FT_Outline* outline, - AF_CJKMetrics metrics ) - { - FT_Error error; - int dim; - - FT_UNUSED( metrics ); - - - error = af_glyph_hints_reload( hints, outline ); - if ( error ) - goto Exit; - - /* analyze glyph outline */ - if ( AF_HINTS_DO_HORIZONTAL( hints ) ) - { - error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ ); - if ( error ) - goto Exit; - - af_cjk_hints_compute_blue_edges( hints, metrics, AF_DIMENSION_HORZ ); - } - - if ( AF_HINTS_DO_VERTICAL( hints ) ) - { - error = af_cjk_hints_detect_features( hints, AF_DIMENSION_VERT ); - if ( error ) - goto Exit; - - af_cjk_hints_compute_blue_edges( hints, metrics, AF_DIMENSION_VERT ); - } - - /* grid-fit the outline */ - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || - ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) - { - -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL ) - { - AF_WarperRec warper; - FT_Fixed scale; - FT_Pos delta; - - - af_warper_compute( &warper, hints, (AF_Dimension)dim, - &scale, &delta ); - af_glyph_hints_scale_dim( hints, (AF_Dimension)dim, - scale, delta ); - continue; - } -#endif /* AF_CONFIG_OPTION_USE_WARPER */ - - af_cjk_hint_edges( hints, (AF_Dimension)dim ); - af_cjk_align_edge_points( hints, (AF_Dimension)dim ); - af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); - af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); - } - } - -#if 0 - af_glyph_hints_dump_points( hints ); - af_glyph_hints_dump_segments( hints ); - af_glyph_hints_dump_edges( hints ); -#endif - - af_glyph_hints_save( hints, outline ); - - Exit: - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** C J K S C R I P T C L A S S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* this corresponds to Unicode 6.0 */ - - static const AF_Script_UniRangeRec af_cjk_uniranges[] = - { - AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), /* Hangul Jamo */ - AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ - AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ - AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), /* Ideographic Description Characters */ - AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ - AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ - AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ - AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ - AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ - AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), /* Kanbun */ - AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ - AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ - AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ - AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */ - AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ - AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ - AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ - AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ - AF_UNIRANGE_REC( 0xA960UL, 0xA97FUL ), /* Hangul Jamo Extended-A */ - AF_UNIRANGE_REC( 0xAC00UL, 0xD7AFUL ), /* Hangul Syllables */ - AF_UNIRANGE_REC( 0xD7B0UL, 0xD7FFUL ), /* Hangul Jamo Extended-B */ - AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ - AF_UNIRANGE_REC( 0xFE10UL, 0xFE1FUL ), /* Vertical forms */ - AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ - AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ - AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ), /* Kana Supplement */ - AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ), /* Tai Xuan Hing Symbols */ - AF_UNIRANGE_REC( 0x1F200UL, 0x1F2FFUL ), /* Enclosed Ideographic Supplement */ - AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ - AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ), /* CJK Unified Ideographs Extension C */ - AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ), /* CJK Unified Ideographs Extension D */ - AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class, - AF_SCRIPT_CJK, - af_cjk_uniranges, - 0x7530, /* 田 */ - - sizeof ( AF_CJKMetricsRec ), - - (AF_Script_InitMetricsFunc) af_cjk_metrics_init, - (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, - - (AF_Script_InitHintsFunc) af_cjk_hints_init, - (AF_Script_ApplyHintsFunc) af_cjk_hints_apply - ) - -#else /* !AF_CONFIG_OPTION_CJK */ - - static const AF_Script_UniRangeRec af_cjk_uniranges[] = - { - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class, - AF_SCRIPT_CJK, - af_cjk_uniranges, - 0, - - sizeof ( AF_CJKMetricsRec ), - - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, - - (AF_Script_InitHintsFunc) NULL, - (AF_Script_ApplyHintsFunc) NULL - ) - -#endif /* !AF_CONFIG_OPTION_CJK */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afcjk.h b/drivers/freetype/freetype/src/autofit/afcjk.h deleted file mode 100644 index ab816f20b1..0000000000 --- a/drivers/freetype/freetype/src/autofit/afcjk.h +++ /dev/null @@ -1,142 +0,0 @@ -/***************************************************************************/ -/* */ -/* afcjk.h */ -/* */ -/* Auto-fitter hinting routines for CJK script (specification). */ -/* */ -/* Copyright 2006, 2007, 2011, 2012 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 __AFCJK_H__ -#define __AFCJK_H__ - -#include "afhints.h" -#include "aflatin.h" - - -FT_BEGIN_HEADER - - - /* the CJK-specific script class */ - - AF_DECLARE_SCRIPT_CLASS( af_cjk_script_class ) - - /* CJK (global) metrics management */ - - /* - * CJK glyphs tend to fill the square. So we have both vertical and - * horizontal blue zones. But some glyphs have flat bounding strokes that - * leave some space between neighbour glyphs. - */ - enum - { - AF_CJK_BLUE_TOP, - AF_CJK_BLUE_BOTTOM, - AF_CJK_BLUE_LEFT, - AF_CJK_BLUE_RIGHT, - - AF_CJK_BLUE_MAX - }; - - -#define AF_CJK_MAX_WIDTHS 16 -#define AF_CJK_MAX_BLUES AF_CJK_BLUE_MAX - - - enum - { - AF_CJK_BLUE_ACTIVE = 1 << 0, - AF_CJK_BLUE_IS_TOP = 1 << 1, - AF_CJK_BLUE_IS_RIGHT = 1 << 2, - AF_CJK_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment */ - /* optimization */ - AF_CJK_BLUE_FLAG_MAX - }; - - - typedef struct AF_CJKBlueRec_ - { - AF_WidthRec ref; - AF_WidthRec shoot; /* undershoot */ - FT_UInt flags; - - } AF_CJKBlueRec, *AF_CJKBlue; - - - typedef struct AF_CJKAxisRec_ - { - FT_Fixed scale; - FT_Pos delta; - - FT_UInt width_count; - AF_WidthRec widths[AF_CJK_MAX_WIDTHS]; - FT_Pos edge_distance_threshold; - FT_Pos standard_width; - FT_Bool extra_light; - - /* used for horizontal metrics too for CJK */ - FT_Bool control_overshoot; - FT_UInt blue_count; - AF_CJKBlueRec blues[AF_CJK_BLUE_MAX]; - - FT_Fixed org_scale; - FT_Pos org_delta; - - } AF_CJKAxisRec, *AF_CJKAxis; - - - typedef struct AF_CJKMetricsRec_ - { - AF_ScriptMetricsRec root; - FT_UInt units_per_em; - AF_CJKAxisRec axis[AF_DIMENSION_MAX]; - - } AF_CJKMetricsRec, *AF_CJKMetrics; - - -#ifdef AF_CONFIG_OPTION_CJK - FT_LOCAL( FT_Error ) - af_cjk_metrics_init( AF_CJKMetrics metrics, - FT_Face face ); - - FT_LOCAL( void ) - af_cjk_metrics_scale( AF_CJKMetrics metrics, - AF_Scaler scaler ); - - FT_LOCAL( FT_Error ) - af_cjk_hints_init( AF_GlyphHints hints, - AF_CJKMetrics metrics ); - - FT_LOCAL( FT_Error ) - af_cjk_hints_apply( AF_GlyphHints hints, - FT_Outline* outline, - AF_CJKMetrics metrics ); - - /* shared; called from afindic.c */ - FT_LOCAL( void ) - af_cjk_metrics_check_digits( AF_CJKMetrics metrics, - FT_Face face ); - - FT_LOCAL( void ) - af_cjk_metrics_init_widths( AF_CJKMetrics metrics, - FT_Face face ); -#endif /* AF_CONFIG_OPTION_CJK */ - - -/* */ - -FT_END_HEADER - -#endif /* __AFCJK_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afdummy.c b/drivers/freetype/freetype/src/autofit/afdummy.c deleted file mode 100644 index 22944559da..0000000000 --- a/drivers/freetype/freetype/src/autofit/afdummy.c +++ /dev/null @@ -1,62 +0,0 @@ -/***************************************************************************/ -/* */ -/* afdummy.c */ -/* */ -/* Auto-fitter dummy routines to be used if no hinting should be */ -/* performed (body). */ -/* */ -/* Copyright 2003-2005, 2011, 2013 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 "afdummy.h" -#include "afhints.h" -#include "aferrors.h" - - - static FT_Error - af_dummy_hints_init( AF_GlyphHints hints, - AF_ScriptMetrics metrics ) - { - af_glyph_hints_rescale( hints, - metrics ); - return FT_Err_Ok; - } - - - static FT_Error - af_dummy_hints_apply( AF_GlyphHints hints, - FT_Outline* outline ) - { - FT_UNUSED( hints ); - FT_UNUSED( outline ); - - return FT_Err_Ok; - } - - - AF_DEFINE_SCRIPT_CLASS( af_dummy_script_class, - AF_SCRIPT_DUMMY, - NULL, - 0, - - sizeof ( AF_ScriptMetricsRec ), - - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, - - (AF_Script_InitHintsFunc) af_dummy_hints_init, - (AF_Script_ApplyHintsFunc) af_dummy_hints_apply - ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afdummy.h b/drivers/freetype/freetype/src/autofit/afdummy.h deleted file mode 100644 index 95d8f8cf19..0000000000 --- a/drivers/freetype/freetype/src/autofit/afdummy.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* afdummy.h */ -/* */ -/* Auto-fitter dummy routines to be used if no hinting should be */ -/* performed (specification). */ -/* */ -/* Copyright 2003-2005, 2011 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 __AFDUMMY_H__ -#define __AFDUMMY_H__ - -#include "aftypes.h" - - -FT_BEGIN_HEADER - - /* A dummy script metrics class used when no hinting should - * be performed. This is the default for non-latin glyphs! - */ - - AF_DECLARE_SCRIPT_CLASS( af_dummy_script_class ) - -/* */ - -FT_END_HEADER - - -#endif /* __AFDUMMY_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/aferrors.h b/drivers/freetype/freetype/src/autofit/aferrors.h deleted file mode 100644 index 50e1a22dd5..0000000000 --- a/drivers/freetype/freetype/src/autofit/aferrors.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* aferrors.h */ -/* */ -/* Autofitter error codes (specification only). */ -/* */ -/* Copyright 2005, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the Autofitter error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ - -#ifndef __AFERRORS_H__ -#define __AFERRORS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX AF_Err_ -#define FT_ERR_BASE FT_Mod_Err_Autofit - -#include FT_ERRORS_H - -#endif /* __AFERRORS_H__ */ - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afglobal.c b/drivers/freetype/freetype/src/autofit/afglobal.c deleted file mode 100644 index 3e41465756..0000000000 --- a/drivers/freetype/freetype/src/autofit/afglobal.c +++ /dev/null @@ -1,304 +0,0 @@ -/***************************************************************************/ -/* */ -/* afglobal.c */ -/* */ -/* Auto-fitter routines to compute global hinting values (body). */ -/* */ -/* Copyright 2003-2013 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 "afglobal.h" -#include "afdummy.h" -#include "aflatin.h" -#include "afcjk.h" -#include "afindic.h" -#include "afpic.h" - -#include "aferrors.h" - -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.h" -#endif - -#ifndef FT_CONFIG_OPTION_PIC - - /* when updating this table, don't forget to update */ - /* AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ - - /* populate this list when you add new scripts */ - static AF_ScriptClass const af_script_classes[] = - { - &af_dummy_script_class, -#ifdef FT_OPTION_AUTOFIT2 - &af_latin2_script_class, -#endif - &af_latin_script_class, - &af_cjk_script_class, - &af_indic_script_class, - NULL /* do not remove */ - }; - -#endif /* !FT_CONFIG_OPTION_PIC */ - - - /* Compute the script index of each glyph within a given face. */ - - static FT_Error - af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) - { - FT_Error error; - FT_Face face = globals->face; - FT_CharMap old_charmap = face->charmap; - FT_Byte* gscripts = globals->glyph_scripts; - FT_UInt ss; - FT_UInt i; - - - /* the value AF_SCRIPT_NONE means `uncovered glyph' */ - FT_MEM_SET( globals->glyph_scripts, - AF_SCRIPT_NONE, - globals->glyph_count ); - - error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); - if ( error ) - { - /* - * Ignore this error; we simply use the fallback script. - * XXX: Shouldn't we rather disable hinting? - */ - error = FT_Err_Ok; - goto Exit; - } - - /* scan each script in a Unicode charmap */ - for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) - { - AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; - AF_Script_UniRange range; - - - if ( clazz->script_uni_ranges == NULL ) - continue; - - /* - * Scan all Unicode points in the range and set the corresponding - * glyph script index. - */ - for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) - { - FT_ULong charcode = range->first; - FT_UInt gindex; - - - gindex = FT_Get_Char_Index( face, charcode ); - - if ( gindex != 0 && - gindex < (FT_ULong)globals->glyph_count && - gscripts[gindex] == AF_SCRIPT_NONE ) - gscripts[gindex] = (FT_Byte)ss; - - for (;;) - { - charcode = FT_Get_Next_Char( face, charcode, &gindex ); - - if ( gindex == 0 || charcode > range->last ) - break; - - if ( gindex < (FT_ULong)globals->glyph_count && - gscripts[gindex] == AF_SCRIPT_NONE ) - gscripts[gindex] = (FT_Byte)ss; - } - } - } - - /* mark ASCII digits */ - for ( i = 0x30; i <= 0x39; i++ ) - { - FT_UInt gindex = FT_Get_Char_Index( face, i ); - - - if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) - gscripts[gindex] |= AF_DIGIT; - } - - Exit: - /* - * By default, all uncovered glyphs are set to the fallback script. - * XXX: Shouldn't we disable hinting or do something similar? - */ - if ( globals->module->fallback_script != AF_SCRIPT_NONE ) - { - FT_Long nn; - - - for ( nn = 0; nn < globals->glyph_count; nn++ ) - { - if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_NONE ) - { - gscripts[nn] &= ~AF_SCRIPT_NONE; - gscripts[nn] |= globals->module->fallback_script; - } - } - } - - FT_Set_Charmap( face, old_charmap ); - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - af_face_globals_new( FT_Face face, - AF_FaceGlobals *aglobals, - AF_Module module ) - { - FT_Error error; - FT_Memory memory; - AF_FaceGlobals globals = NULL; - - - memory = face->memory; - - if ( FT_ALLOC( globals, sizeof ( *globals ) + - face->num_glyphs * sizeof ( FT_Byte ) ) ) - goto Exit; - - globals->face = face; - globals->glyph_count = face->num_glyphs; - globals->glyph_scripts = (FT_Byte*)( globals + 1 ); - globals->module = module; - - error = af_face_globals_compute_script_coverage( globals ); - if ( error ) - { - af_face_globals_free( globals ); - globals = NULL; - } - - globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; - - Exit: - *aglobals = globals; - return error; - } - - - FT_LOCAL_DEF( void ) - af_face_globals_free( AF_FaceGlobals globals ) - { - if ( globals ) - { - FT_Memory memory = globals->face->memory; - FT_UInt nn; - - - for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ ) - { - if ( globals->metrics[nn] ) - { - AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[nn]; - - - FT_ASSERT( globals->metrics[nn]->clazz == clazz ); - - if ( clazz->script_metrics_done ) - clazz->script_metrics_done( globals->metrics[nn] ); - - FT_FREE( globals->metrics[nn] ); - } - } - - globals->glyph_count = 0; - globals->glyph_scripts = NULL; /* no need to free this one! */ - globals->face = NULL; - - FT_FREE( globals ); - } - } - - - FT_LOCAL_DEF( FT_Error ) - af_face_globals_get_metrics( AF_FaceGlobals globals, - FT_UInt gindex, - FT_UInt options, - AF_ScriptMetrics *ametrics ) - { - AF_ScriptMetrics metrics = NULL; - FT_UInt gidx; - AF_ScriptClass clazz; - FT_UInt script = options & 15; - const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / - sizeof ( AF_SCRIPT_CLASSES_GET[0] ); - FT_Error error = FT_Err_Ok; - - - if ( gindex >= (FT_ULong)globals->glyph_count ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - gidx = script; - if ( gidx == 0 || gidx + 1 >= script_max ) - gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_NONE; - - clazz = AF_SCRIPT_CLASSES_GET[gidx]; - if ( script == 0 ) - script = clazz->script; - - metrics = globals->metrics[clazz->script]; - if ( metrics == NULL ) - { - /* create the global metrics object if necessary */ - FT_Memory memory = globals->face->memory; - - - if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) - goto Exit; - - metrics->clazz = clazz; - metrics->globals = globals; - - if ( clazz->script_metrics_init ) - { - error = clazz->script_metrics_init( metrics, globals->face ); - if ( error ) - { - if ( clazz->script_metrics_done ) - clazz->script_metrics_done( metrics ); - - FT_FREE( metrics ); - goto Exit; - } - } - - globals->metrics[clazz->script] = metrics; - } - - Exit: - *ametrics = metrics; - - return error; - } - - - FT_LOCAL_DEF( FT_Bool ) - af_face_globals_is_digit( AF_FaceGlobals globals, - FT_UInt gindex ) - { - if ( gindex < (FT_ULong)globals->glyph_count ) - return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); - - return (FT_Bool)0; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afglobal.h b/drivers/freetype/freetype/src/autofit/afglobal.h deleted file mode 100644 index 2e24900822..0000000000 --- a/drivers/freetype/freetype/src/autofit/afglobal.h +++ /dev/null @@ -1,109 +0,0 @@ -/***************************************************************************/ -/* */ -/* afglobal.h */ -/* */ -/* Auto-fitter routines to compute global hinting values */ -/* (specification). */ -/* */ -/* Copyright 2003-2005, 2007, 2009, 2011-2012 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 __AFGLOBAL_H__ -#define __AFGLOBAL_H__ - - -#include "aftypes.h" -#include "afmodule.h" - - -FT_BEGIN_HEADER - - - /* - * Default values and flags for both autofitter globals (found in - * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec). - */ - - /* index of fallback script in `af_script_classes' */ -#define AF_SCRIPT_FALLBACK 2 - /* a bit mask indicating an uncovered glyph */ -#define AF_SCRIPT_NONE 0x7F - /* if this flag is set, we have an ASCII digit */ -#define AF_DIGIT 0x80 - - /* `increase-x-height' property */ -#define AF_PROP_INCREASE_X_HEIGHT_MIN 6 -#define AF_PROP_INCREASE_X_HEIGHT_MAX 0 - - - /************************************************************************/ - /************************************************************************/ - /***** *****/ - /***** F A C E G L O B A L S *****/ - /***** *****/ - /************************************************************************/ - /************************************************************************/ - - - /* - * Note that glyph_scripts[] is used to map each glyph into - * an index into the `af_script_classes' array. - * - */ - typedef struct AF_FaceGlobalsRec_ - { - FT_Face face; - FT_Long glyph_count; /* same as face->num_glyphs */ - FT_Byte* glyph_scripts; - - /* per-face auto-hinter properties */ - FT_UInt increase_x_height; - - AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; - - AF_Module module; /* to access global properties */ - - } AF_FaceGlobalsRec; - - - /* - * model the global hints data for a given face, decomposed into - * script-specific items - */ - - FT_LOCAL( FT_Error ) - af_face_globals_new( FT_Face face, - AF_FaceGlobals *aglobals, - AF_Module module ); - - FT_LOCAL( FT_Error ) - af_face_globals_get_metrics( AF_FaceGlobals globals, - FT_UInt gindex, - FT_UInt options, - AF_ScriptMetrics *ametrics ); - - FT_LOCAL( void ) - af_face_globals_free( AF_FaceGlobals globals ); - - FT_LOCAL_DEF( FT_Bool ) - af_face_globals_is_digit( AF_FaceGlobals globals, - FT_UInt gindex ); - - /* */ - - -FT_END_HEADER - -#endif /* __AFGLOBAL_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afhints.c b/drivers/freetype/freetype/src/autofit/afhints.c deleted file mode 100644 index e8defaa88d..0000000000 --- a/drivers/freetype/freetype/src/autofit/afhints.c +++ /dev/null @@ -1,1321 +0,0 @@ -/***************************************************************************/ -/* */ -/* afhints.c */ -/* */ -/* Auto-fitter hinting routines (body). */ -/* */ -/* Copyright 2003-2007, 2009-2013 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 "afhints.h" -#include "aferrors.h" -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_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_afhints - - - /* Get new segment for given axis. */ - - FT_LOCAL_DEF( FT_Error ) - af_axis_hints_new_segment( AF_AxisHints axis, - FT_Memory memory, - AF_Segment *asegment ) - { - FT_Error error = FT_Err_Ok; - AF_Segment segment = NULL; - - - if ( axis->num_segments >= axis->max_segments ) - { - FT_Int old_max = axis->max_segments; - FT_Int new_max = old_max; - FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) ); - - - if ( old_max >= big_max ) - { - error = FT_THROW( Out_Of_Memory ); - goto Exit; - } - - new_max += ( new_max >> 2 ) + 4; - if ( new_max < old_max || new_max > big_max ) - new_max = big_max; - - if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) - goto Exit; - - axis->max_segments = new_max; - } - - segment = axis->segments + axis->num_segments++; - - Exit: - *asegment = segment; - return error; - } - - - /* Get new edge for given axis, direction, and position. */ - - FT_LOCAL( FT_Error ) - af_axis_hints_new_edge( AF_AxisHints axis, - FT_Int fpos, - AF_Direction dir, - FT_Memory memory, - AF_Edge *anedge ) - { - FT_Error error = FT_Err_Ok; - AF_Edge edge = NULL; - AF_Edge edges; - - - if ( axis->num_edges >= axis->max_edges ) - { - FT_Int old_max = axis->max_edges; - FT_Int new_max = old_max; - FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); - - - if ( old_max >= big_max ) - { - error = FT_THROW( Out_Of_Memory ); - goto Exit; - } - - new_max += ( new_max >> 2 ) + 4; - if ( new_max < old_max || new_max > big_max ) - new_max = big_max; - - if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) - goto Exit; - - axis->max_edges = new_max; - } - - edges = axis->edges; - edge = edges + axis->num_edges; - - while ( edge > edges ) - { - if ( edge[-1].fpos < fpos ) - break; - - /* we want the edge with same position and minor direction */ - /* to appear before those in the major one in the list */ - if ( edge[-1].fpos == fpos && dir == axis->major_dir ) - break; - - edge[0] = edge[-1]; - edge--; - } - - axis->num_edges++; - - FT_ZERO( edge ); - edge->fpos = (FT_Short)fpos; - edge->dir = (FT_Char)dir; - - Exit: - *anedge = edge; - return error; - } - - -#ifdef FT_DEBUG_AUTOFIT - -#include FT_CONFIG_STANDARD_LIBRARY_H - - static const char* - af_dir_str( AF_Direction dir ) - { - const char* result; - - - switch ( dir ) - { - case AF_DIR_UP: - result = "up"; - break; - case AF_DIR_DOWN: - result = "down"; - break; - case AF_DIR_LEFT: - result = "left"; - break; - case AF_DIR_RIGHT: - result = "right"; - break; - default: - result = "none"; - } - - return result; - } - - -#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 ) - - -#ifdef __cplusplus - extern "C" { -#endif - void - af_glyph_hints_dump_points( AF_GlyphHints hints ) - { - AF_Point points = hints->points; - AF_Point limit = points + hints->num_points; - AF_Point point; - - - FT_TRACE7(( "Table of points:\n" - " [ index | xorg | yorg | xscale | yscale" - " | xfit | yfit | flags ]\n" )); - - for ( point = points; point < limit; point++ ) - FT_TRACE7(( " [ %5d | %5d | %5d | %6.2f | %6.2f" - " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n", - point - points, - point->fx, - point->fy, - point->ox / 64.0, - point->oy / 64.0, - point->x / 64.0, - point->y / 64.0, - ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', - ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', - ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', - ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ', - ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ', - ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' ')); - FT_TRACE7(( "\n" )); - } -#ifdef __cplusplus - } -#endif - - - static const char* - af_edge_flags_to_string( AF_Edge_Flags flags ) - { - static char temp[32]; - int pos = 0; - - - if ( flags & AF_EDGE_ROUND ) - { - ft_memcpy( temp + pos, "round", 5 ); - pos += 5; - } - if ( flags & AF_EDGE_SERIF ) - { - if ( pos > 0 ) - temp[pos++] = ' '; - ft_memcpy( temp + pos, "serif", 5 ); - pos += 5; - } - if ( pos == 0 ) - return "normal"; - - temp[pos] = '\0'; - - return temp; - } - - - /* Dump the array of linked segments. */ - -#ifdef __cplusplus - extern "C" { -#endif - void - af_glyph_hints_dump_segments( AF_GlyphHints hints ) - { - FT_Int dimension; - - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AF_AxisHints axis = &hints->axis[dimension]; - AF_Point points = hints->points; - AF_Edge edges = axis->edges; - AF_Segment segments = axis->segments; - AF_Segment limit = segments + axis->num_segments; - AF_Segment seg; - - - FT_TRACE7(( "Table of %s segments:\n", - dimension == AF_DIMENSION_HORZ ? "vertical" - : "horizontal" )); - if ( axis->num_segments ) - FT_TRACE7(( " [ index | pos | dir | from" - " | to | link | serif | edge" - " | height | extra | flags ]\n" )); - else - FT_TRACE7(( " (none)\n" )); - - for ( seg = segments; seg < limit; seg++ ) - FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d" - " | %4d | %4d | %5d | %4d" - " | %6d | %5d | %11s ]\n", - seg - segments, - dimension == AF_DIMENSION_HORZ - ? (int)seg->first->ox / 64.0 - : (int)seg->first->oy / 64.0, - af_dir_str( (AF_Direction)seg->dir ), - AF_INDEX_NUM( seg->first, points ), - AF_INDEX_NUM( seg->last, points ), - AF_INDEX_NUM( seg->link, segments ), - AF_INDEX_NUM( seg->serif, segments ), - AF_INDEX_NUM( seg->edge, edges ), - seg->height, - seg->height - ( seg->max_coord - seg->min_coord ), - af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) )); - FT_TRACE7(( "\n" )); - } - } -#ifdef __cplusplus - } -#endif - - - /* Fetch number of segments. */ - -#ifdef __cplusplus - extern "C" { -#endif - FT_Error - af_glyph_hints_get_num_segments( AF_GlyphHints hints, - FT_Int dimension, - FT_Int* num_segments ) - { - AF_Dimension dim; - AF_AxisHints axis; - - - dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; - - axis = &hints->axis[dim]; - *num_segments = axis->num_segments; - - return FT_Err_Ok; - } -#ifdef __cplusplus - } -#endif - - - /* Fetch offset of segments into user supplied offset array. */ - -#ifdef __cplusplus - extern "C" { -#endif - FT_Error - af_glyph_hints_get_segment_offset( AF_GlyphHints hints, - FT_Int dimension, - FT_Int idx, - FT_Pos* offset ) - { - AF_Dimension dim; - AF_AxisHints axis; - AF_Segment seg; - - - if ( !offset ) - return FT_THROW( Invalid_Argument ); - - dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; - - axis = &hints->axis[dim]; - - if ( idx < 0 || idx >= axis->num_segments ) - return FT_THROW( Invalid_Argument ); - - seg = &axis->segments[idx]; - *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox - : seg->first->oy; - - return FT_Err_Ok; - } -#ifdef __cplusplus - } -#endif - - - /* Dump the array of linked edges. */ - -#ifdef __cplusplus - extern "C" { -#endif - void - af_glyph_hints_dump_edges( AF_GlyphHints hints ) - { - FT_Int dimension; - - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AF_AxisHints axis = &hints->axis[dimension]; - AF_Edge edges = axis->edges; - AF_Edge limit = edges + axis->num_edges; - AF_Edge edge; - - - /* - * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges - * since they have a constant X coordinate. - */ - FT_TRACE7(( "Table of %s edges:\n", - dimension == AF_DIMENSION_HORZ ? "vertical" - : "horizontal" )); - if ( axis->num_edges ) - FT_TRACE7(( " [ index | pos | dir | link" - " | serif | blue | opos | pos | flags ]\n" )); - else - FT_TRACE7(( " (none)\n" )); - - for ( edge = edges; edge < limit; edge++ ) - FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d" - " | %5d | %c | %5.2f | %5.2f | %11s ]\n", - edge - edges, - (int)edge->opos / 64.0, - af_dir_str( (AF_Direction)edge->dir ), - AF_INDEX_NUM( edge->link, edges ), - AF_INDEX_NUM( edge->serif, edges ), - edge->blue_edge ? 'y' : 'n', - edge->opos / 64.0, - edge->pos / 64.0, - af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) )); - FT_TRACE7(( "\n" )); - } - } -#ifdef __cplusplus - } -#endif - -#else /* !FT_DEBUG_AUTOFIT */ - - /* these empty stubs are only used to link the `ftgrid' test program */ - /* if debugging is disabled */ - -#ifdef __cplusplus - extern "C" { -#endif - - void - af_glyph_hints_dump_points( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - - - void - af_glyph_hints_dump_segments( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - - - FT_Error - af_glyph_hints_get_num_segments( AF_GlyphHints hints, - FT_Int dimension, - FT_Int* num_segments ) - { - FT_UNUSED( hints ); - FT_UNUSED( dimension ); - FT_UNUSED( num_segments ); - - return 0; - } - - - FT_Error - af_glyph_hints_get_segment_offset( AF_GlyphHints hints, - FT_Int dimension, - FT_Int idx, - FT_Pos* offset ) - { - FT_UNUSED( hints ); - FT_UNUSED( dimension ); - FT_UNUSED( idx ); - FT_UNUSED( offset ); - - return 0; - } - - - void - af_glyph_hints_dump_edges( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - -#ifdef __cplusplus - } -#endif - -#endif /* !FT_DEBUG_AUTOFIT */ - - - /* Compute the direction value of a given vector. */ - - FT_LOCAL_DEF( AF_Direction ) - af_direction_compute( FT_Pos dx, - FT_Pos dy ) - { - FT_Pos ll, ss; /* long and short arm lengths */ - AF_Direction dir; /* candidate direction */ - - - if ( dy >= dx ) - { - if ( dy >= -dx ) - { - dir = AF_DIR_UP; - ll = dy; - ss = dx; - } - else - { - dir = AF_DIR_LEFT; - ll = -dx; - ss = dy; - } - } - else /* dy < dx */ - { - if ( dy >= -dx ) - { - dir = AF_DIR_RIGHT; - ll = dx; - ss = dy; - } - else - { - dir = AF_DIR_DOWN; - ll = dy; - ss = dx; - } - } - - /* return no direction if arm lengths differ too much */ - /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */ - ss *= 14; - if ( FT_ABS( ll ) <= FT_ABS( ss ) ) - dir = AF_DIR_NONE; - - return dir; - } - - - FT_LOCAL_DEF( void ) - af_glyph_hints_init( AF_GlyphHints hints, - FT_Memory memory ) - { - FT_ZERO( hints ); - hints->memory = memory; - } - - - FT_LOCAL_DEF( void ) - af_glyph_hints_done( AF_GlyphHints hints ) - { - FT_Memory memory = hints->memory; - int dim; - - - if ( !( hints && hints->memory ) ) - return; - - /* - * note that we don't need to free the segment and edge - * buffers since they are really within the hints->points array - */ - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_AxisHints axis = &hints->axis[dim]; - - - axis->num_segments = 0; - axis->max_segments = 0; - FT_FREE( axis->segments ); - - axis->num_edges = 0; - axis->max_edges = 0; - FT_FREE( axis->edges ); - } - - FT_FREE( hints->contours ); - hints->max_contours = 0; - hints->num_contours = 0; - - FT_FREE( hints->points ); - hints->num_points = 0; - hints->max_points = 0; - - hints->memory = NULL; - } - - - /* Reset metrics. */ - - FT_LOCAL_DEF( void ) - af_glyph_hints_rescale( AF_GlyphHints hints, - AF_ScriptMetrics metrics ) - { - hints->metrics = metrics; - hints->scaler_flags = metrics->scaler.flags; - } - - - /* Recompute all AF_Point in AF_GlyphHints from the definitions */ - /* in a source outline. */ - - FT_LOCAL_DEF( FT_Error ) - af_glyph_hints_reload( AF_GlyphHints hints, - FT_Outline* outline ) - { - FT_Error error = FT_Err_Ok; - AF_Point points; - FT_UInt old_max, new_max; - FT_Fixed x_scale = hints->x_scale; - FT_Fixed y_scale = hints->y_scale; - FT_Pos x_delta = hints->x_delta; - FT_Pos y_delta = hints->y_delta; - FT_Memory memory = hints->memory; - - - hints->num_points = 0; - hints->num_contours = 0; - - hints->axis[0].num_segments = 0; - hints->axis[0].num_edges = 0; - hints->axis[1].num_segments = 0; - hints->axis[1].num_edges = 0; - - /* first of all, reallocate the contours array if necessary */ - new_max = (FT_UInt)outline->n_contours; - old_max = hints->max_contours; - if ( new_max > old_max ) - { - new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */ - - if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) - goto Exit; - - hints->max_contours = new_max; - } - - /* - * then reallocate the points arrays if necessary -- - * note that we reserve two additional point positions, used to - * hint metrics appropriately - */ - new_max = (FT_UInt)( outline->n_points + 2 ); - old_max = hints->max_points; - if ( new_max > old_max ) - { - new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */ - - if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) - goto Exit; - - hints->max_points = new_max; - } - - hints->num_points = outline->n_points; - hints->num_contours = outline->n_contours; - - /* We can't rely on the value of `FT_Outline.flags' to know the fill */ - /* direction used for a glyph, given that some fonts are broken (e.g., */ - /* the Arphic ones). We thus recompute it each time we need to. */ - /* */ - hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP; - hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT; - - if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) - { - hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN; - hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT; - } - - hints->x_scale = x_scale; - hints->y_scale = y_scale; - hints->x_delta = x_delta; - hints->y_delta = y_delta; - - hints->xmin_delta = 0; - hints->xmax_delta = 0; - - points = hints->points; - if ( hints->num_points == 0 ) - goto Exit; - - { - AF_Point point; - AF_Point point_limit = points + hints->num_points; - - - /* compute coordinates & Bezier flags, next and prev */ - { - FT_Vector* vec = outline->points; - char* tag = outline->tags; - AF_Point end = points + outline->contours[0]; - AF_Point prev = end; - FT_Int contour_index = 0; - - - for ( point = points; point < point_limit; point++, vec++, tag++ ) - { - point->fx = (FT_Short)vec->x; - point->fy = (FT_Short)vec->y; - point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; - point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; - - switch ( FT_CURVE_TAG( *tag ) ) - { - case FT_CURVE_TAG_CONIC: - point->flags = AF_FLAG_CONIC; - break; - case FT_CURVE_TAG_CUBIC: - point->flags = AF_FLAG_CUBIC; - break; - default: - point->flags = AF_FLAG_NONE; - } - - point->prev = prev; - prev->next = point; - prev = point; - - if ( point == end ) - { - if ( ++contour_index < outline->n_contours ) - { - end = points + outline->contours[contour_index]; - prev = end; - } - } - } - } - - /* set up the contours array */ - { - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; - short* end = outline->contours; - short idx = 0; - - - for ( ; contour < contour_limit; contour++, end++ ) - { - contour[0] = points + idx; - idx = (short)( end[0] + 1 ); - } - } - - /* compute directions of in & out vectors */ - { - AF_Point first = points; - AF_Point prev = NULL; - FT_Pos in_x = 0; - FT_Pos in_y = 0; - AF_Direction in_dir = AF_DIR_NONE; - - - for ( point = points; point < point_limit; point++ ) - { - AF_Point next; - FT_Pos out_x, out_y; - - - if ( point == first ) - { - prev = first->prev; - in_x = first->fx - prev->fx; - in_y = first->fy - prev->fy; - in_dir = af_direction_compute( in_x, in_y ); - first = prev + 1; - } - - point->in_dir = (FT_Char)in_dir; - - next = point->next; - out_x = next->fx - point->fx; - out_y = next->fy - point->fy; - - in_dir = af_direction_compute( out_x, out_y ); - point->out_dir = (FT_Char)in_dir; - - /* check for weak points */ - - if ( point->flags & AF_FLAG_CONTROL ) - { - Is_Weak_Point: - point->flags |= AF_FLAG_WEAK_INTERPOLATION; - } - else if ( point->out_dir == point->in_dir ) - { - 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 if ( point->in_dir == -point->out_dir ) - goto Is_Weak_Point; - - in_x = out_x; - in_y = out_y; - prev = point; - } - } - } - - Exit: - return error; - } - - - /* Store the hinted outline in an FT_Outline structure. */ - - FT_LOCAL_DEF( void ) - af_glyph_hints_save( AF_GlyphHints hints, - FT_Outline* outline ) - { - AF_Point point = hints->points; - AF_Point limit = point + hints->num_points; - FT_Vector* vec = outline->points; - char* tag = outline->tags; - - - for ( ; point < limit; point++, vec++, tag++ ) - { - vec->x = point->x; - vec->y = point->y; - - if ( point->flags & AF_FLAG_CONIC ) - tag[0] = FT_CURVE_TAG_CONIC; - else if ( point->flags & AF_FLAG_CUBIC ) - tag[0] = FT_CURVE_TAG_CUBIC; - else - tag[0] = FT_CURVE_TAG_ON; - } - } - - - /**************************************************************** - * - * EDGE POINT GRID-FITTING - * - ****************************************************************/ - - - /* Align all points of an edge to the same coordinate value, */ - /* either horizontally or vertically. */ - - FT_LOCAL_DEF( void ) - af_glyph_hints_align_edge_points( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = & hints->axis[dim]; - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; - AF_Segment seg; - - - if ( dim == AF_DIMENSION_HORZ ) - { - for ( seg = segments; seg < segment_limit; seg++ ) - { - AF_Edge edge = seg->edge; - AF_Point point, first, last; - - - if ( edge == NULL ) - continue; - - first = seg->first; - last = seg->last; - point = first; - for (;;) - { - point->x = edge->pos; - point->flags |= AF_FLAG_TOUCH_X; - - if ( point == last ) - break; - - point = point->next; - } - } - } - else - { - for ( seg = segments; seg < segment_limit; seg++ ) - { - AF_Edge edge = seg->edge; - AF_Point point, first, last; - - - if ( edge == NULL ) - continue; - - first = seg->first; - last = seg->last; - point = first; - for (;;) - { - point->y = edge->pos; - point->flags |= AF_FLAG_TOUCH_Y; - - if ( point == last ) - break; - - point = point->next; - } - } - } - } - - - /**************************************************************** - * - * STRONG POINT INTERPOLATION - * - ****************************************************************/ - - - /* Hint the strong points -- this is equivalent to the TrueType `IP' */ - /* hinting instruction. */ - - FT_LOCAL_DEF( void ) - af_glyph_hints_align_strong_points( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_Point points = hints->points; - AF_Point point_limit = points + hints->num_points; - AF_AxisHints axis = &hints->axis[dim]; - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - AF_Flags touch_flag; - - - if ( dim == AF_DIMENSION_HORZ ) - touch_flag = AF_FLAG_TOUCH_X; - else - touch_flag = AF_FLAG_TOUCH_Y; - - if ( edges < edge_limit ) - { - AF_Point point; - AF_Edge edge; - - - for ( point = points; point < point_limit; point++ ) - { - FT_Pos u, ou, fu; /* point position */ - FT_Pos delta; - - - if ( point->flags & touch_flag ) - continue; - - /* if this point is candidate to weak interpolation, we */ - /* interpolate it after all strong points have been processed */ - - if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && - !( point->flags & AF_FLAG_INFLECTION ) ) - continue; - - if ( dim == AF_DIMENSION_VERT ) - { - u = point->fy; - ou = point->oy; - } - else - { - u = point->fx; - ou = point->ox; - } - - fu = u; - - /* is the point before the first edge? */ - edge = edges; - delta = edge->fpos - u; - if ( delta >= 0 ) - { - u = edge->pos - ( edge->opos - ou ); - goto Store_Point; - } - - /* is the point after the last edge? */ - edge = edge_limit - 1; - delta = u - edge->fpos; - if ( delta >= 0 ) - { - u = edge->pos + ( ou - edge->opos ); - goto Store_Point; - } - - { - FT_PtrDist min, max, mid; - FT_Pos fpos; - - - /* find enclosing edges */ - min = 0; - max = edge_limit - edges; - -#if 1 - /* for a small number of edges, a linear search is better */ - if ( max <= 8 ) - { - FT_PtrDist nn; - - - for ( nn = 0; nn < max; nn++ ) - if ( edges[nn].fpos >= u ) - break; - - if ( edges[nn].fpos == u ) - { - u = edges[nn].pos; - goto Store_Point; - } - min = nn; - } - else -#endif - while ( min < max ) - { - mid = ( max + min ) >> 1; - edge = edges + mid; - fpos = edge->fpos; - - if ( u < fpos ) - max = mid; - else if ( u > fpos ) - min = mid + 1; - else - { - /* we are on the edge */ - u = edge->pos; - goto Store_Point; - } - } - - /* point is not on an edge */ - { - AF_Edge before = edges + min - 1; - AF_Edge after = edges + min + 0; - - - /* assert( before && after && before != after ) */ - if ( before->scale == 0 ) - before->scale = FT_DivFix( after->pos - before->pos, - after->fpos - before->fpos ); - - u = before->pos + FT_MulFix( fu - before->fpos, - before->scale ); - } - } - - Store_Point: - /* save the point position */ - if ( dim == AF_DIMENSION_HORZ ) - point->x = u; - else - point->y = u; - - point->flags |= touch_flag; - } - } - } - - - /**************************************************************** - * - * WEAK POINT INTERPOLATION - * - ****************************************************************/ - - - /* Shift the original coordinates of all points between `p1' and */ - /* `p2' to get hinted coordinates, using the same difference as */ - /* given by `ref'. */ - - static void - af_iup_shift( AF_Point p1, - AF_Point p2, - AF_Point ref ) - { - AF_Point p; - FT_Pos delta = ref->u - ref->v; - - - if ( delta == 0 ) - return; - - for ( p = p1; p < ref; p++ ) - p->u = p->v + delta; - - for ( p = ref + 1; p <= p2; p++ ) - p->u = p->v + delta; - } - - - /* Interpolate the original coordinates of all points between `p1' and */ - /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */ - /* reference points. The `u' and `v' members are the current and */ - /* original coordinate values, respectively. */ - /* */ - /* Details can be found in the TrueType bytecode specification. */ - - static void - af_iup_interp( AF_Point p1, - AF_Point p2, - AF_Point ref1, - AF_Point ref2 ) - { - AF_Point p; - FT_Pos u; - FT_Pos v1 = ref1->v; - FT_Pos v2 = ref2->v; - FT_Pos d1 = ref1->u - v1; - FT_Pos d2 = ref2->u - v2; - - - if ( p1 > p2 ) - return; - - if ( v1 == v2 ) - { - for ( p = p1; p <= p2; p++ ) - { - u = p->v; - - if ( u <= v1 ) - u += d1; - else - u += d2; - - p->u = u; - } - return; - } - - if ( v1 < v2 ) - { - for ( p = p1; p <= p2; p++ ) - { - u = p->v; - - if ( u <= v1 ) - u += d1; - else if ( u >= v2 ) - u += d2; - else - u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); - - p->u = u; - } - } - else - { - for ( p = p1; p <= p2; p++ ) - { - u = p->v; - - if ( u <= v2 ) - u += d2; - else if ( u >= v1 ) - u += d1; - else - u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); - - p->u = u; - } - } - } - - - /* Hint the weak points -- this is equivalent to the TrueType `IUP' */ - /* hinting instruction. */ - - FT_LOCAL_DEF( void ) - af_glyph_hints_align_weak_points( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_Point points = hints->points; - AF_Point point_limit = points + hints->num_points; - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; - AF_Flags touch_flag; - AF_Point point; - AF_Point end_point; - AF_Point first_point; - - - /* PASS 1: Move segment points to edge positions */ - - if ( dim == AF_DIMENSION_HORZ ) - { - touch_flag = AF_FLAG_TOUCH_X; - - for ( point = points; point < point_limit; point++ ) - { - point->u = point->x; - point->v = point->ox; - } - } - else - { - touch_flag = AF_FLAG_TOUCH_Y; - - for ( point = points; point < point_limit; point++ ) - { - point->u = point->y; - point->v = point->oy; - } - } - - point = points; - - for ( ; contour < contour_limit; contour++ ) - { - AF_Point first_touched, last_touched; - - - point = *contour; - end_point = point->prev; - first_point = point; - - /* find first touched point */ - for (;;) - { - if ( point > end_point ) /* no touched point in contour */ - goto NextContour; - - if ( point->flags & touch_flag ) - break; - - point++; - } - - first_touched = point; - last_touched = point; - - for (;;) - { - FT_ASSERT( point <= end_point && - ( point->flags & touch_flag ) != 0 ); - - /* skip any touched neighbours */ - while ( point < end_point && - ( point[1].flags & touch_flag ) != 0 ) - point++; - - last_touched = point; - - /* find the next touched point, if any */ - point++; - for (;;) - { - if ( point > end_point ) - goto EndContour; - - if ( ( point->flags & touch_flag ) != 0 ) - break; - - point++; - } - - /* interpolate between last_touched and point */ - af_iup_interp( last_touched + 1, point - 1, - last_touched, point ); - } - - EndContour: - /* special case: only one point was touched */ - if ( last_touched == first_touched ) - af_iup_shift( first_point, end_point, first_touched ); - - else /* interpolate the last part */ - { - if ( last_touched < end_point ) - af_iup_interp( last_touched + 1, end_point, - last_touched, first_touched ); - - if ( first_touched > points ) - af_iup_interp( first_point, first_touched - 1, - last_touched, first_touched ); - } - - NextContour: - ; - } - - /* now save the interpolated values back to x/y */ - if ( dim == AF_DIMENSION_HORZ ) - { - for ( point = points; point < point_limit; point++ ) - point->x = point->u; - } - else - { - for ( point = points; point < point_limit; point++ ) - point->y = point->u; - } - } - - -#ifdef AF_CONFIG_OPTION_USE_WARPER - - /* Apply (small) warp scale and warp delta for given dimension. */ - - FT_LOCAL_DEF( void ) - af_glyph_hints_scale_dim( AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed scale, - FT_Pos delta ) - { - AF_Point points = hints->points; - AF_Point points_limit = points + hints->num_points; - AF_Point point; - - - if ( dim == AF_DIMENSION_HORZ ) - { - for ( point = points; point < points_limit; point++ ) - point->x = FT_MulFix( point->fx, scale ) + delta; - } - else - { - for ( point = points; point < points_limit; point++ ) - point->y = FT_MulFix( point->fy, scale ) + delta; - } - } - -#endif /* AF_CONFIG_OPTION_USE_WARPER */ - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afhints.h b/drivers/freetype/freetype/src/autofit/afhints.h deleted file mode 100644 index 776b3c844e..0000000000 --- a/drivers/freetype/freetype/src/autofit/afhints.h +++ /dev/null @@ -1,467 +0,0 @@ -/***************************************************************************/ -/* */ -/* afhints.h */ -/* */ -/* Auto-fitter hinting routines (specification). */ -/* */ -/* Copyright 2003-2008, 2010-2012 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 __AFHINTS_H__ -#define __AFHINTS_H__ - -#include "aftypes.h" - -#define xxAF_SORT_SEGMENTS - -FT_BEGIN_HEADER - - /* - * The definition of outline glyph hints. These are shared by all - * script analysis routines (until now). - */ - - typedef enum AF_Dimension_ - { - AF_DIMENSION_HORZ = 0, /* x coordinates, */ - /* i.e., vertical segments & edges */ - AF_DIMENSION_VERT = 1, /* y coordinates, */ - /* i.e., horizontal segments & edges */ - - AF_DIMENSION_MAX /* do not remove */ - - } AF_Dimension; - - - /* hint directions -- the values are computed so that two vectors are */ - /* in opposite directions iff `dir1 + dir2 == 0' */ - typedef enum AF_Direction_ - { - AF_DIR_NONE = 4, - AF_DIR_RIGHT = 1, - AF_DIR_LEFT = -1, - AF_DIR_UP = 2, - AF_DIR_DOWN = -2 - - } AF_Direction; - - - /* - * The following explanations are mostly taken from the article - * - * Real-Time Grid Fitting of Typographic Outlines - * - * by David Turner and Werner Lemberg - * - * http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf - * - * - * Segments - * - * `af_{cjk,latin,...}_hints_compute_segments' are the functions to - * find segments in an outline. A segment is a series of consecutive - * points that are approximately aligned along a coordinate axis. The - * analysis to do so is specific to a script. - * - * A segment must have at least two points, except in the case of - * `fake' segments that are generated to hint metrics appropriately, - * and which consist of a single point. - * - * - * Edges - * - * As soon as segments are defined, the auto-hinter groups them into - * edges. An edge corresponds to a single position on the main - * dimension that collects one or more segments (allowing for a small - * threshold). - * - * The auto-hinter first tries to grid fit edges, then to align - * segments on the edges unless it detects that they form a serif. - * - * `af_{cjk,latin,...}_hints_compute_edges' are the functions to find - * edges; they are specific to a script. - * - * - * A H - * | | - * | | - * | | - * | | - * C | | F - * +------<-----+ +-----<------+ - * | B G | - * | | - * | | - * +--------------->------------------+ - * D E - * - * - * Stems - * - * Segments need to be `linked' to other ones in order to detect stems. - * A stem is made of two segments that face each other in opposite - * directions and that are sufficiently close to each other. Using - * vocabulary from the TrueType specification, stem segments form a - * `black distance'. - * - * In the above ASCII drawing, the horizontal segments are BC, DE, and - * FG; the vertical segments are AB, CD, EF, and GH. - * - * Each segment has at most one `best' candidate to form a black - * distance, or no candidate at all. Notice that two distinct segments - * can have the same candidate, which frequently means a serif. - * - * A stem is recognized by the following condition: - * - * best segment_1 = segment_2 && best segment_2 = segment_1 - * - * The best candidate is stored in field `link' in structure - * `AF_Segment'. - * - * Stems are detected by `af_{cjk,latin,...}_hint_edges'. - * - * In the above ASCII drawing, the best candidate for both AB and CD is - * GH, while the best candidate for GH is AB. Similarly, the best - * candidate for EF and GH is AB, while the best candidate for AB is - * GH. - * - * - * Serifs - * - * On the opposite, a serif has - * - * best segment_1 = segment_2 && best segment_2 != segment_1 - * - * where segment_1 corresponds to the serif segment (CD and EF in the - * above ASCII drawing). - * - * The best candidate is stored in field `serif' in structure - * `AF_Segment' (and `link' is set to NULL). - * - * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. - * - * - * Touched points - * - * A point is called `touched' if it has been processed somehow by the - * auto-hinter. It basically means that it shouldn't be moved again - * (or moved only under certain constraints to preserve the already - * applied processing). - * - * - * Flat and round segments - * - * Segments are `round' or `flat', depending on the series of points - * that define them. A segment is round if the next and previous point - * of an extremum (which can be either a single point or sequence of - * points) are both conic or cubic control points. Otherwise, a - * segment with an extremum is flat. - * - * - * Strong Points - * - * Experience has shown that points which are not part of an edge need - * to be interpolated linearly between their two closest edges, even if - * these are not part of the contour of those particular points. - * Typical candidates for this are - * - * - angle points (i.e., points where the `in' and `out' direction - * differ greatly) - * - * - inflection points (i.e., where the `in' and `out' angles are the - * same, but the curvature changes sign) - * - * `af_glyph_hints_align_strong_points' is the function which takes - * care of such situations; it is equivalent to the TrueType `IP' - * hinting instruction. - * - * - * Weak Points - * - * Other points in the outline must be interpolated using the - * coordinates of their previous and next unfitted contour neighbours. - * These are called `weak points' and are touched by the function - * `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP' - * hinting instruction. Typical candidates are control points and - * points on the contour without a major direction. - * - * The major effect is to reduce possible distortion caused by - * alignment of edges and strong points, thus weak points are processed - * after strong points. - */ - - - /* point hint flags */ - typedef enum AF_Flags_ - { - AF_FLAG_NONE = 0, - - /* point type flags */ - AF_FLAG_CONIC = 1 << 0, - AF_FLAG_CUBIC = 1 << 1, - AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, - - /* point extremum flags */ - AF_FLAG_EXTREMA_X = 1 << 2, - AF_FLAG_EXTREMA_Y = 1 << 3, - - /* point roundness flags */ - AF_FLAG_ROUND_X = 1 << 4, - AF_FLAG_ROUND_Y = 1 << 5, - - /* point touch flags */ - AF_FLAG_TOUCH_X = 1 << 6, - AF_FLAG_TOUCH_Y = 1 << 7, - - /* candidates for weak interpolation have this flag set */ - AF_FLAG_WEAK_INTERPOLATION = 1 << 8, - - /* all inflection points in the outline have this flag set */ - AF_FLAG_INFLECTION = 1 << 9 - - } AF_Flags; - - - /* edge hint flags */ - typedef enum AF_Edge_Flags_ - { - AF_EDGE_NORMAL = 0, - AF_EDGE_ROUND = 1 << 0, - AF_EDGE_SERIF = 1 << 1, - AF_EDGE_DONE = 1 << 2 - - } AF_Edge_Flags; - - - typedef struct AF_PointRec_* AF_Point; - typedef struct AF_SegmentRec_* AF_Segment; - typedef struct AF_EdgeRec_* AF_Edge; - - - typedef struct AF_PointRec_ - { - FT_UShort flags; /* point flags used by hinter */ - FT_Char in_dir; /* direction of inwards vector */ - FT_Char out_dir; /* direction of outwards vector */ - - FT_Pos ox, oy; /* original, scaled position */ - FT_Short fx, fy; /* original, unscaled position (in font units) */ - FT_Pos x, y; /* current position */ - FT_Pos u, v; /* current (x,y) or (y,x) depending on context */ - - AF_Point next; /* next point in contour */ - AF_Point prev; /* previous point in contour */ - - } AF_PointRec; - - - typedef struct AF_SegmentRec_ - { - FT_Byte flags; /* edge/segment flags for this segment */ - FT_Char dir; /* segment direction */ - 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 */ - - AF_Segment link; /* (stem) link segment */ - AF_Segment serif; /* primary segment for serifs */ - FT_Pos num_linked; /* number of linked segments */ - FT_Pos score; /* used during stem matching */ - FT_Pos len; /* used during stem matching */ - - AF_Point first; /* first point in edge segment */ - AF_Point last; /* last point in edge segment */ - - } AF_SegmentRec; - - - typedef struct AF_EdgeRec_ - { - FT_Short fpos; /* original, unscaled position (in font units) */ - FT_Pos opos; /* original, scaled position */ - FT_Pos pos; /* current position */ - - FT_Byte flags; /* edge flags */ - FT_Char dir; /* edge direction */ - FT_Fixed scale; /* used to speed up interpolation between edges */ - - AF_Width blue_edge; /* non-NULL if this is a blue edge */ - AF_Edge link; /* link edge */ - AF_Edge serif; /* primary edge for serifs */ - FT_Short num_linked; /* number of linked edges */ - FT_Int score; /* used during stem matching */ - - AF_Segment first; /* first segment in edge */ - AF_Segment last; /* last segment in edge */ - - } AF_EdgeRec; - - - typedef struct AF_AxisHintsRec_ - { - FT_Int num_segments; /* number of used segments */ - FT_Int max_segments; /* number of allocated segments */ - AF_Segment segments; /* segments array */ -#ifdef AF_SORT_SEGMENTS - FT_Int mid_segments; -#endif - - FT_Int num_edges; /* number of used edges */ - FT_Int max_edges; /* number of allocated edges */ - AF_Edge edges; /* edges array */ - - AF_Direction major_dir; /* either vertical or horizontal */ - - } AF_AxisHintsRec, *AF_AxisHints; - - - typedef struct AF_GlyphHintsRec_ - { - FT_Memory memory; - - FT_Fixed x_scale; - FT_Pos x_delta; - - FT_Fixed y_scale; - FT_Pos y_delta; - - FT_Int max_points; /* number of allocated points */ - FT_Int num_points; /* number of used points */ - AF_Point points; /* points array */ - - FT_Int max_contours; /* number of allocated contours */ - FT_Int num_contours; /* number of used contours */ - AF_Point* contours; /* contours array */ - - AF_AxisHintsRec axis[AF_DIMENSION_MAX]; - - FT_UInt32 scaler_flags; /* copy of scaler flags */ - FT_UInt32 other_flags; /* free for script-specific */ - /* implementations */ - AF_ScriptMetrics metrics; - - FT_Pos xmin_delta; /* used for warping */ - FT_Pos xmax_delta; - - } AF_GlyphHintsRec; - - -#define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) ) -#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) ) - - -#ifdef FT_DEBUG_AUTOFIT - -#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 /* !FT_DEBUG_AUTOFIT */ - -#define AF_HINTS_DO_HORIZONTAL( h ) \ - !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) - -#define AF_HINTS_DO_VERTICAL( h ) \ - !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 ) 1 - -#endif /* !FT_DEBUG_AUTOFIT */ - - - FT_LOCAL( AF_Direction ) - af_direction_compute( FT_Pos dx, - FT_Pos dy ); - - - FT_LOCAL( FT_Error ) - af_axis_hints_new_segment( AF_AxisHints axis, - FT_Memory memory, - AF_Segment *asegment ); - - FT_LOCAL( FT_Error) - af_axis_hints_new_edge( AF_AxisHints axis, - FT_Int fpos, - AF_Direction dir, - FT_Memory memory, - AF_Edge *edge ); - - FT_LOCAL( void ) - af_glyph_hints_init( AF_GlyphHints hints, - FT_Memory memory ); - - FT_LOCAL( void ) - af_glyph_hints_rescale( AF_GlyphHints hints, - AF_ScriptMetrics metrics ); - - FT_LOCAL( FT_Error ) - af_glyph_hints_reload( AF_GlyphHints hints, - FT_Outline* outline ); - - FT_LOCAL( void ) - af_glyph_hints_save( AF_GlyphHints hints, - FT_Outline* outline ); - - FT_LOCAL( void ) - af_glyph_hints_align_edge_points( AF_GlyphHints hints, - AF_Dimension dim ); - - FT_LOCAL( void ) - af_glyph_hints_align_strong_points( AF_GlyphHints hints, - AF_Dimension dim ); - - FT_LOCAL( void ) - af_glyph_hints_align_weak_points( AF_GlyphHints hints, - AF_Dimension dim ); - -#ifdef AF_CONFIG_OPTION_USE_WARPER - FT_LOCAL( void ) - af_glyph_hints_scale_dim( AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed scale, - FT_Pos delta ); -#endif - - FT_LOCAL( void ) - af_glyph_hints_done( AF_GlyphHints hints ); - -/* */ - -#define AF_SEGMENT_LEN( seg ) ( (seg)->max_coord - (seg)->min_coord ) - -#define AF_SEGMENT_DIST( seg1, seg2 ) ( ( (seg1)->pos > (seg2)->pos ) \ - ? (seg1)->pos - (seg2)->pos \ - : (seg2)->pos - (seg1)->pos ) - - -FT_END_HEADER - -#endif /* __AFHINTS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afindic.c b/drivers/freetype/freetype/src/autofit/afindic.c deleted file mode 100644 index 8c24972598..0000000000 --- a/drivers/freetype/freetype/src/autofit/afindic.c +++ /dev/null @@ -1,157 +0,0 @@ -/***************************************************************************/ -/* */ -/* afindic.c */ -/* */ -/* Auto-fitter hinting routines for Indic scripts (body). */ -/* */ -/* Copyright 2007, 2011-2013 by */ -/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ -/* */ -/* 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 "aftypes.h" -#include "aflatin.h" - - -#ifdef AF_CONFIG_OPTION_INDIC - -#include "afindic.h" -#include "aferrors.h" -#include "afcjk.h" - - -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.h" -#endif - - - static FT_Error - af_indic_metrics_init( AF_CJKMetrics metrics, - FT_Face face ) - { - /* skip blue zone init in CJK routines */ - FT_CharMap oldmap = face->charmap; - - - metrics->units_per_em = face->units_per_EM; - - if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) - face->charmap = NULL; - else - { - af_cjk_metrics_init_widths( metrics, face ); -#if 0 - /* either need indic specific blue_chars[] or just skip blue zones */ - af_cjk_metrics_init_blues( metrics, face, af_cjk_blue_chars ); -#endif - af_cjk_metrics_check_digits( metrics, face ); - } - - FT_Set_Charmap( face, oldmap ); - - return FT_Err_Ok; - } - - - static void - af_indic_metrics_scale( AF_CJKMetrics metrics, - AF_Scaler scaler ) - { - /* use CJK routines */ - af_cjk_metrics_scale( metrics, scaler ); - } - - - static FT_Error - af_indic_hints_init( AF_GlyphHints hints, - AF_CJKMetrics metrics ) - { - /* use CJK routines */ - return af_cjk_hints_init( hints, metrics ); - } - - - static FT_Error - af_indic_hints_apply( AF_GlyphHints hints, - FT_Outline* outline, - AF_CJKMetrics metrics ) - { - /* use CJK routines */ - return af_cjk_hints_apply( hints, outline, metrics ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** I N D I C S C R I P T C L A S S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - static const AF_Script_UniRangeRec af_indic_uniranges[] = - { -#if 0 - AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ -#endif - AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ - AF_UNIRANGE_REC( 0x0F00UL, 0x0FFFUL), /* Tibetan */ - AF_UNIRANGE_REC( 0x1900UL, 0x194FUL), /* Limbu */ - AF_UNIRANGE_REC( 0x1B80UL, 0x1BBFUL), /* Sundanese */ - AF_UNIRANGE_REC( 0x1C80UL, 0x1CDFUL), /* Meetei Mayak */ - AF_UNIRANGE_REC( 0xA800UL, 0xA82FUL), /* Syloti Nagri */ - AF_UNIRANGE_REC( 0x11800UL, 0x118DFUL), /* Sharada */ - AF_UNIRANGE_REC( 0UL, 0UL) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, - AF_SCRIPT_INDIC, - af_indic_uniranges, - 'o', /* XXX */ - - sizeof ( AF_CJKMetricsRec ), - - (AF_Script_InitMetricsFunc) af_indic_metrics_init, - (AF_Script_ScaleMetricsFunc)af_indic_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, - - (AF_Script_InitHintsFunc) af_indic_hints_init, - (AF_Script_ApplyHintsFunc) af_indic_hints_apply - ) - -#else /* !AF_CONFIG_OPTION_INDIC */ - - static const AF_Script_UniRangeRec af_indic_uniranges[] = - { - { 0, 0 } - }; - - - AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, - AF_SCRIPT_INDIC, - af_indic_uniranges, - 0, - - sizeof ( AF_CJKMetricsRec ), - - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, - - (AF_Script_InitHintsFunc) NULL, - (AF_Script_ApplyHintsFunc) NULL - ) - -#endif /* !AF_CONFIG_OPTION_INDIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afindic.h b/drivers/freetype/freetype/src/autofit/afindic.h deleted file mode 100644 index c252cf20da..0000000000 --- a/drivers/freetype/freetype/src/autofit/afindic.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* afindic.h */ -/* */ -/* Auto-fitter hinting routines for Indic scripts (specification). */ -/* */ -/* Copyright 2007, 2012 by */ -/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ -/* */ -/* 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 __AFINDIC_H__ -#define __AFINDIC_H__ - -#include "afhints.h" - - -FT_BEGIN_HEADER - - - /* the Indic-specific script class */ - - AF_DECLARE_SCRIPT_CLASS( af_indic_script_class ) - - -/* */ - -FT_END_HEADER - -#endif /* __AFINDIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/aflatin.c b/drivers/freetype/freetype/src/autofit/aflatin.c deleted file mode 100644 index ef0157a13e..0000000000 --- a/drivers/freetype/freetype/src/autofit/aflatin.c +++ /dev/null @@ -1,2486 +0,0 @@ -/***************************************************************************/ -/* */ -/* aflatin.c */ -/* */ -/* Auto-fitter hinting routines for latin script (body). */ -/* */ -/* Copyright 2003-2013 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_ADVANCES_H -#include FT_INTERNAL_DEBUG_H - -#include "afglobal.h" -#include "aflatin.h" -#include "aferrors.h" - - -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.h" -#endif - - - /*************************************************************************/ - /* */ - /* 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_aflatin - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L O B A L M E T R I C S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* Find segments and links, compute all stem widths, and initialize */ - /* standard width and height for the glyph with given charcode. */ - - FT_LOCAL_DEF( void ) - af_latin_metrics_init_widths( AF_LatinMetrics metrics, - FT_Face face ) - { - /* scan the array of segments in each direction */ - AF_GlyphHintsRec hints[1]; - - - FT_TRACE5(( "standard widths computation\n" - "===========================\n\n" )); - - af_glyph_hints_init( hints, face->memory ); - - metrics->axis[AF_DIMENSION_HORZ].width_count = 0; - metrics->axis[AF_DIMENSION_VERT].width_count = 0; - - { - FT_Error error; - FT_UInt glyph_index; - int dim; - AF_LatinMetricsRec dummy[1]; - AF_Scaler scaler = &dummy->root.scaler; - - - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); - if ( glyph_index == 0 ) - goto Exit; - - FT_TRACE5(( "standard character: 0x%X (glyph index %d)\n", - metrics->root.clazz->standard_char, glyph_index )); - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || face->glyph->outline.n_points <= 0 ) - goto Exit; - - FT_ZERO( dummy ); - - dummy->units_per_em = metrics->units_per_em; - - scaler->x_scale = 0x10000L; - scaler->y_scale = 0x10000L; - scaler->x_delta = 0; - scaler->y_delta = 0; - - scaler->face = face; - scaler->render_mode = FT_RENDER_MODE_NORMAL; - scaler->flags = 0; - - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); - - error = af_glyph_hints_reload( hints, &face->glyph->outline ); - if ( error ) - goto Exit; - - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_LatinAxis axis = &metrics->axis[dim]; - AF_AxisHints axhints = &hints->axis[dim]; - AF_Segment seg, limit, link; - FT_UInt num_widths = 0; - - - error = af_latin_hints_compute_segments( hints, - (AF_Dimension)dim ); - if ( error ) - goto Exit; - - af_latin_hints_link_segments( hints, - (AF_Dimension)dim ); - - seg = axhints->segments; - limit = seg + axhints->num_segments; - - for ( ; seg < limit; seg++ ) - { - link = seg->link; - - /* we only consider stem segments there! */ - if ( link && link->link == seg && link > seg ) - { - FT_Pos dist; - - - dist = seg->pos - link->pos; - if ( dist < 0 ) - dist = -dist; - - if ( num_widths < AF_LATIN_MAX_WIDTHS ) - axis->widths[num_widths++].org = dist; - } - } - - /* this also replaces multiple almost identical stem widths */ - /* with a single one (the value 100 is heuristic) */ - af_sort_and_quantize_widths( &num_widths, axis->widths, - dummy->units_per_em / 100 ); - axis->width_count = num_widths; - } - - Exit: - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_LatinAxis axis = &metrics->axis[dim]; - FT_Pos stdw; - - - stdw = ( axis->width_count > 0 ) - ? axis->widths[0].org - : AF_LATIN_CONSTANT( metrics, 50 ); - - /* let's try 20% of the smallest width */ - axis->edge_distance_threshold = stdw / 5; - axis->standard_width = stdw; - axis->extra_light = 0; - -#ifdef FT_DEBUG_LEVEL_TRACE - { - FT_UInt i; - - - FT_TRACE5(( "%s widths:\n", - dim == AF_DIMENSION_VERT ? "horizontal" - : "vertical" )); - - FT_TRACE5(( " %d (standard)", axis->standard_width )); - for ( i = 1; i < axis->width_count; i++ ) - FT_TRACE5(( " %d", axis->widths[i].org )); - - FT_TRACE5(( "\n" )); - } -#endif - } - } - - FT_TRACE5(( "\n" )); - - af_glyph_hints_done( hints ); - } - - - -#define AF_LATIN_MAX_TEST_CHARACTERS 12 - - - static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] - [AF_LATIN_MAX_TEST_CHARACTERS + 1] = - { - "THEZOCQS", - "HEZLOCUS", - "fijkdbh", - "xzroesc", - "xzroesc", - "pqgjy" - }; - - - /* Find all blue zones. Flat segments give the reference points, */ - /* round segments the overshoot positions. */ - - static void - af_latin_metrics_init_blues( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Int num_flats; - FT_Int num_rounds; - FT_Int bb; - AF_LatinBlue blue; - FT_Error error; - AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; - FT_Outline outline; - - - /* we compute the blues simply by loading each character from the */ - /* `af_latin_blue_chars[blues]' string, then finding its top-most or */ - /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ - - FT_TRACE5(( "blue zones computation\n" - "======================\n\n" )); - - for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) - { - const char* p = af_latin_blue_chars[bb]; - const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; - FT_Pos* blue_ref; - FT_Pos* blue_shoot; - - - FT_TRACE5(( "blue zone %d:\n", bb )); - - num_flats = 0; - num_rounds = 0; - - for ( ; p < limit && *p; p++ ) - { - FT_UInt glyph_index; - FT_Pos best_y; /* same as points.y */ - FT_Int best_point, best_contour_first, best_contour_last; - FT_Vector* points; - FT_Bool round = 0; - - - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); - if ( glyph_index == 0 ) - continue; - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - outline = face->glyph->outline; - if ( error || outline.n_points <= 0 ) - continue; - - /* now compute min or max point indices and coordinates */ - points = outline.points; - best_point = -1; - best_y = 0; /* make compiler happy */ - best_contour_first = 0; /* ditto */ - best_contour_last = 0; /* ditto */ - - { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; - - - for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) - { - FT_Int old_best_point = best_point; - FT_Int pp; - - - last = outline.contours[nn]; - - /* Avoid single-point contours since they are never rasterized. */ - /* In some fonts, they correspond to mark attachment points */ - /* which are way outside of the glyph's real outline. */ - if ( last <= first ) - continue; - - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_y ) - { - best_point = pp; - best_y = points[pp].y; - } - } - else - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_y ) - { - best_point = pp; - best_y = points[pp].y; - } - } - - if ( best_point != old_best_point ) - { - best_contour_first = first; - best_contour_last = last; - } - } - FT_TRACE5(( " %c %ld", *p, best_y )); - } - - /* now check whether the point belongs to a straight or round */ - /* segment; we first need to find in which contour the extremum */ - /* lies, then inspect its previous and next points */ - if ( best_point >= 0 ) - { - FT_Pos best_x = points[best_point].x; - FT_Int prev, next; - FT_Int best_on_point_first, best_on_point_last; - FT_Pos dist; - - - if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) - { - best_on_point_first = best_point; - best_on_point_last = best_point; - } - else - { - best_on_point_first = -1; - best_on_point_last = -1; - } - - /* look for the previous and next points that are not on the */ - /* same Y coordinate, then threshold the `closeness'... */ - prev = best_point; - next = prev; - - do - { - if ( prev > best_contour_first ) - prev--; - else - prev = best_contour_last; - - dist = FT_ABS( points[prev].y - best_y ); - /* accept a small distance or a small angle (both values are */ - /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ - if ( dist > 5 ) - if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) - break; - - if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) - { - best_on_point_first = prev; - if ( best_on_point_last < 0 ) - best_on_point_last = prev; - } - - } while ( prev != best_point ); - - do - { - if ( next < best_contour_last ) - next++; - else - next = best_contour_first; - - dist = FT_ABS( points[next].y - best_y ); - if ( dist > 5 ) - if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) - break; - - if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) - { - best_on_point_last = next; - if ( best_on_point_first < 0 ) - best_on_point_first = next; - } - - } while ( next != best_point ); - - /* now set the `round' flag depending on the segment's kind */ - /* (value 8 is heuristic) */ - if ( best_on_point_first >= 0 && - best_on_point_last >= 0 && - (FT_UInt)( FT_ABS( points[best_on_point_last].x - - points[best_on_point_first].x ) ) > - metrics->units_per_em / 8 ) - round = 0; - else - round = FT_BOOL( - FT_CURVE_TAG( outline.tags[prev] ) != FT_CURVE_TAG_ON || - FT_CURVE_TAG( outline.tags[next] ) != FT_CURVE_TAG_ON ); - - FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); - } - - if ( round ) - rounds[num_rounds++] = best_y; - else - flats[num_flats++] = best_y; - } - - if ( num_flats == 0 && num_rounds == 0 ) - { - /* - * we couldn't find a single glyph to compute this blue zone, - * we will simply ignore it then - */ - FT_TRACE5(( " empty\n" )); - continue; - } - - /* we have computed the contents of the `rounds' and `flats' tables, */ - /* now determine the reference and overshoot position of the blue -- */ - /* we simply take the median value after a simple sort */ - af_sort_pos( num_rounds, rounds ); - af_sort_pos( num_flats, flats ); - - blue = &axis->blues[axis->blue_count]; - blue_ref = &blue->ref.org; - blue_shoot = &blue->shoot.org; - - axis->blue_count++; - - if ( num_flats == 0 ) - { - *blue_ref = - *blue_shoot = rounds[num_rounds / 2]; - } - else if ( num_rounds == 0 ) - { - *blue_ref = - *blue_shoot = flats[num_flats / 2]; - } - else - { - *blue_ref = flats[num_flats / 2]; - *blue_shoot = rounds[num_rounds / 2]; - } - - /* there are sometimes problems: if the overshoot position of top */ - /* zones is under its reference position, or the opposite for bottom */ - /* zones. We must thus check everything there and correct the errors */ - if ( *blue_shoot != *blue_ref ) - { - FT_Pos ref = *blue_ref; - FT_Pos shoot = *blue_shoot; - FT_Bool over_ref = FT_BOOL( shoot > ref ); - - - if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) - { - *blue_ref = - *blue_shoot = ( shoot + ref ) / 2; - - FT_TRACE5(( " [overshoot smaller than reference," - " taking mean value]\n" )); - } - } - - blue->flags = 0; - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) - blue->flags |= AF_LATIN_BLUE_TOP; - - /* - * The following flag is used later to adjust the y and x scales - * in order to optimize the pixel grid alignment of the top of small - * letters. - */ - if ( bb == AF_LATIN_BLUE_SMALL_TOP ) - blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; - - FT_TRACE5(( " -> reference = %ld\n" - " overshoot = %ld\n", - *blue_ref, *blue_shoot )); - } - - FT_TRACE5(( "\n" )); - - return; - } - - - /* Check whether all ASCII digits have the same advance width. */ - - FT_LOCAL_DEF( void ) - af_latin_metrics_check_digits( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_UInt i; - FT_Bool started = 0, same_width = 1; - FT_Fixed advance, old_advance = 0; - - - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) - { - FT_UInt glyph_index; - - - glyph_index = FT_Get_Char_Index( face, i ); - if ( glyph_index == 0 ) - continue; - - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) - continue; - - if ( started ) - { - if ( advance != old_advance ) - { - same_width = 0; - break; - } - } - else - { - old_advance = advance; - started = 1; - } - } - - metrics->root.digits_have_same_width = same_width; - } - - - /* Initialize global metrics. */ - - FT_LOCAL_DEF( FT_Error ) - af_latin_metrics_init( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_CharMap oldmap = face->charmap; - - - metrics->units_per_em = face->units_per_EM; - - if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) - { - af_latin_metrics_init_widths( metrics, face ); - af_latin_metrics_init_blues( metrics, face ); - af_latin_metrics_check_digits( metrics, face ); - } - - FT_Set_Charmap( face, oldmap ); - return FT_Err_Ok; - } - - - /* Adjust scaling value, then scale and shift widths */ - /* and blue zones (if applicable) for given dimension. */ - - static void - af_latin_metrics_scale_dim( AF_LatinMetrics metrics, - AF_Scaler scaler, - AF_Dimension dim ) - { - FT_Fixed scale; - FT_Pos delta; - AF_LatinAxis axis; - FT_UInt nn; - - - if ( dim == AF_DIMENSION_HORZ ) - { - scale = scaler->x_scale; - delta = scaler->x_delta; - } - else - { - scale = scaler->y_scale; - delta = scaler->y_delta; - } - - axis = &metrics->axis[dim]; - - if ( axis->org_scale == scale && axis->org_delta == delta ) - return; - - axis->org_scale = scale; - axis->org_delta = delta; - - /* - * correct X and Y scale to optimize the alignment of the top of small - * letters to the pixel grid - */ - { - AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT]; - AF_LatinBlue blue = NULL; - - - for ( nn = 0; nn < Axis->blue_count; nn++ ) - { - if ( Axis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) - { - blue = &Axis->blues[nn]; - break; - } - } - - if ( blue ) - { - FT_Pos scaled; - FT_Pos threshold; - FT_Pos fitted; - FT_UInt limit; - FT_UInt ppem; - - - scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); - ppem = metrics->root.scaler.face->size->metrics.x_ppem; - limit = metrics->root.globals->increase_x_height; - threshold = 40; - - /* if the `increase-x-height' property is active, */ - /* we round up much more often */ - if ( limit && - ppem <= limit && - ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN ) - threshold = 52; - - fitted = ( scaled + threshold ) & ~63; - - if ( scaled != fitted ) - { -#if 0 - if ( dim == AF_DIMENSION_HORZ ) - { - if ( fitted < scaled ) - scale -= scale / 50; /* scale *= 0.98 */ - } - else -#endif - if ( dim == AF_DIMENSION_VERT ) - scale = FT_MulDiv( scale, fitted, scaled ); - } - } - } - - axis->scale = scale; - axis->delta = delta; - - if ( dim == AF_DIMENSION_HORZ ) - { - metrics->root.scaler.x_scale = scale; - metrics->root.scaler.x_delta = delta; - } - else - { - metrics->root.scaler.y_scale = scale; - metrics->root.scaler.y_delta = delta; - } - - /* scale the widths */ - for ( nn = 0; nn < axis->width_count; nn++ ) - { - AF_Width width = axis->widths + nn; - - - width->cur = FT_MulFix( width->org, scale ); - width->fit = width->cur; - } - - /* an extra-light axis corresponds to a standard width that is */ - /* smaller than 5/8 pixels */ - axis->extra_light = - (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); - - if ( dim == AF_DIMENSION_VERT ) - { - /* scale the blue zones */ - for ( nn = 0; nn < axis->blue_count; nn++ ) - { - AF_LatinBlue blue = &axis->blues[nn]; - FT_Pos dist; - - - blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; - blue->ref.fit = blue->ref.cur; - blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; - blue->shoot.fit = blue->shoot.cur; - blue->flags &= ~AF_LATIN_BLUE_ACTIVE; - - /* a blue zone is only active if it is less than 3/4 pixels tall */ - dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); - if ( dist <= 48 && dist >= -48 ) - { -#if 0 - FT_Pos delta1; -#endif - FT_Pos delta2; - - - /* use discrete values for blue zone widths */ - -#if 0 - - /* generic, original code */ - delta1 = blue->shoot.org - blue->ref.org; - delta2 = delta1; - if ( delta1 < 0 ) - delta2 = -delta2; - - delta2 = FT_MulFix( delta2, scale ); - - if ( delta2 < 32 ) - delta2 = 0; - else if ( delta2 < 64 ) - delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); - else - delta2 = FT_PIX_ROUND( delta2 ); - - if ( delta1 < 0 ) - delta2 = -delta2; - - blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); - blue->shoot.fit = blue->ref.fit + delta2; - -#else - - /* simplified version due to abs(dist) <= 48 */ - delta2 = dist; - if ( dist < 0 ) - delta2 = -delta2; - - if ( delta2 < 32 ) - delta2 = 0; - else if ( delta2 < 48 ) - delta2 = 32; - else - delta2 = 64; - - if ( dist < 0 ) - delta2 = -delta2; - - blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); - blue->shoot.fit = blue->ref.fit - delta2; - -#endif - - blue->flags |= AF_LATIN_BLUE_ACTIVE; - } - } - } - } - - - /* Scale global values in both directions. */ - - FT_LOCAL_DEF( void ) - af_latin_metrics_scale( AF_LatinMetrics metrics, - AF_Scaler scaler ) - { - metrics->root.scaler.render_mode = scaler->render_mode; - metrics->root.scaler.face = scaler->face; - metrics->root.scaler.flags = scaler->flags; - - af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); - af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H A N A L Y S I S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* Walk over all contours and compute its segments. */ - - FT_LOCAL_DEF( FT_Error ) - af_latin_hints_compute_segments( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - FT_Memory memory = hints->memory; - FT_Error error = FT_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; - - - FT_ZERO( &seg0 ); - seg0.score = 32000; - seg0.flags = AF_EDGE_NORMAL; - - major_dir = (AF_Direction)FT_ABS( axis->major_dir ); - segment_dir = major_dir; - - axis->num_segments = 0; - - /* set up (u,v) in each point */ - if ( dim == AF_DIMENSION_HORZ ) - { - AF_Point point = hints->points; - AF_Point limit = point + hints->num_points; - - - for ( ; point < limit; point++ ) - { - point->u = point->fx; - point->v = point->fy; - } - } - else - { - AF_Point point = hints->points; - AF_Point limit = point + hints->num_points; - - - for ( ; point < limit; point++ ) - { - point->u = point->fy; - point->v = point->fx; - } - } - - /* do each contour separately */ - for ( ; contour < contour_limit; contour++ ) - { - AF_Point point = contour[0]; - AF_Point last = point->prev; - int on_edge = 0; - FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */ - FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ - FT_Bool passed; - - - if ( point == last ) /* skip singletons -- just in case */ - continue; - - if ( FT_ABS( last->out_dir ) == major_dir && - FT_ABS( point->out_dir ) == major_dir ) - { - /* we are already on an edge, try to locate its start */ - last = point; - - for (;;) - { - point = point->prev; - if ( FT_ABS( point->out_dir ) != major_dir ) - { - point = point->next; - break; - } - if ( point == last ) - break; - } - } - - last = point; - passed = 0; - - for (;;) - { - FT_Pos u, v; - - - if ( on_edge ) - { - u = point->u; - if ( u < min_pos ) - min_pos = u; - if ( u > max_pos ) - max_pos = u; - - if ( point->out_dir != segment_dir || point == last ) - { - /* we are just leaving an edge; record a new segment! */ - segment->last = point; - segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); - - /* a segment is round if either its first or last point */ - /* is a control point */ - if ( ( segment->first->flags | point->flags ) & - AF_FLAG_CONTROL ) - segment->flags |= AF_EDGE_ROUND; - - /* compute segment size */ - min_pos = max_pos = point->v; - - v = segment->first->v; - if ( v < min_pos ) - min_pos = v; - if ( v > max_pos ) - max_pos = v; - - 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; - /* fall through */ - } - } - - /* now exit if we are at the start/end point */ - if ( point == last ) - { - if ( passed ) - break; - passed = 1; - } - - if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) - { - /* this is the start of a new segment! */ - segment_dir = (AF_Direction)point->out_dir; - - /* clear all segment fields */ - error = af_axis_hints_new_segment( axis, memory, &segment ); - if ( error ) - goto Exit; - - segment[0] = seg0; - segment->dir = (FT_Char)segment_dir; - min_pos = max_pos = point->u; - segment->first = point; - segment->last = point; - on_edge = 1; - } - - point = point->next; - } - - } /* contours */ - - - /* now slightly increase the height of segments if 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 ) ); - } - } - } - - Exit: - return error; - } - - - /* Link segments to form stems and serifs. */ - - FT_LOCAL_DEF( void ) - af_latin_hints_link_segments( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; - FT_Pos len_threshold, len_score; - AF_Segment seg1, seg2; - - - len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); - if ( len_threshold == 0 ) - len_threshold = 1; - - len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); - - /* now compare each segment to the others */ - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) - continue; - - /* search for stems having opposite directions, */ - /* with seg1 to the `left' of seg2 */ - for ( seg2 = segments; seg2 < segment_limit; seg2++ ) - { - FT_Pos pos1 = seg1->pos; - FT_Pos pos2 = seg2->pos; - - - if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 ) - { - /* compute distance between the two segments */ - FT_Pos dist = pos2 - pos1; - FT_Pos min = seg1->min_coord; - FT_Pos max = seg1->max_coord; - FT_Pos len, score; - - - if ( min < seg2->min_coord ) - min = seg2->min_coord; - - if ( max > seg2->max_coord ) - max = seg2->max_coord; - - /* compute maximum coordinate difference of the two segments */ - len = max - min; - if ( len >= len_threshold ) - { - /* small coordinate differences cause a higher score, and */ - /* segments with a greater distance cause a higher score also */ - score = dist + len_score / len; - - /* and we search for the smallest score */ - /* of the sum of the two values */ - if ( score < seg1->score ) - { - seg1->score = score; - seg1->link = seg2; - } - - if ( score < seg2->score ) - { - seg2->score = score; - seg2->link = seg1; - } - } - } - } - } - - /* now compute the `serif' segments, cf. explanations in `afhints.h' */ - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - seg2 = seg1->link; - - if ( seg2 ) - { - if ( seg2->link != seg1 ) - { - seg1->link = 0; - seg1->serif = seg2->link; - } - } - } - } - - - /* Link segments to edges, using feature analysis for selection. */ - - FT_LOCAL_DEF( FT_Error ) - af_latin_hints_compute_edges( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - FT_Error error = FT_Err_Ok; - FT_Memory memory = hints->memory; - AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; - - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; - AF_Segment seg; - -#if 0 - AF_Direction up_dir; -#endif - FT_Fixed scale; - FT_Pos edge_distance_threshold; - FT_Pos segment_length_threshold; - - - axis->num_edges = 0; - - scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale - : hints->y_scale; - -#if 0 - up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP - : AF_DIR_RIGHT; -#endif - - /* - * We ignore all segments that are less than 1 pixel 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( 64, hints->y_scale ); - else - segment_length_threshold = 0; - - /*********************************************************************/ - /* */ - /* We begin by generating a sorted table of edges for the current */ - /* direction. To do so, we simply scan each segment and try to find */ - /* an edge in our table that corresponds to its position. */ - /* */ - /* If no edge is found, we create and insert a new edge in the */ - /* sorted table. Otherwise, we simply add the segment to the edge's */ - /* list which gets processed in the second step to compute the */ - /* edge's properties. */ - /* */ - /* Note that the table of edges is sorted along the segment/edge */ - /* position. */ - /* */ - /*********************************************************************/ - - /* assure that edge distance threshold is at most 0.25px */ - edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, - scale ); - if ( edge_distance_threshold > 64 / 4 ) - edge_distance_threshold = 64 / 4; - - edge_distance_threshold = FT_DivFix( edge_distance_threshold, - scale ); - - for ( seg = segments; seg < segment_limit; seg++ ) - { - AF_Edge found = NULL; - FT_Int ee; - - - if ( seg->height < segment_length_threshold ) - continue; - - /* A special case for serif edges: If they are smaller than */ - /* 1.5 pixels we ignore them. */ - if ( seg->serif && - 2 * seg->height < 3 * segment_length_threshold ) - continue; - - /* look for an edge corresponding to the segment */ - for ( ee = 0; ee < axis->num_edges; ee++ ) - { - AF_Edge edge = axis->edges + ee; - FT_Pos dist; - - - dist = seg->pos - edge->fpos; - if ( dist < 0 ) - dist = -dist; - - if ( dist < edge_distance_threshold && edge->dir == seg->dir ) - { - found = edge; - break; - } - } - - if ( !found ) - { - AF_Edge edge; - - - /* insert a new edge in the list and */ - /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, - (AF_Direction)seg->dir, - memory, &edge ); - if ( error ) - goto Exit; - - /* add the segment to the new edge's list */ - FT_ZERO( edge ); - - edge->first = seg; - edge->last = seg; - edge->dir = seg->dir; - edge->fpos = seg->pos; - edge->opos = FT_MulFix( seg->pos, scale ); - edge->pos = edge->opos; - seg->edge_next = seg; - } - else - { - /* if an edge was found, simply add the segment to the edge's */ - /* list */ - seg->edge_next = found->first; - found->last->edge_next = seg; - found->last = seg; - } - } - - - /******************************************************************/ - /* */ - /* Good, we now compute each edge's properties according to the */ - /* segments found on its position. Basically, these are */ - /* */ - /* - the edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straight or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /******************************************************************/ - - /* first of all, set the `edge' field in each segment -- this is */ - /* required in order to compute edge links */ - - /* - * Note that removing this loop and setting the `edge' field of each - * segment directly in the code above slows down execution speed for - * some reasons on platforms like the Sun. - */ - { - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - AF_Edge edge; - - - for ( edge = edges; edge < edge_limit; edge++ ) - { - seg = edge->first; - if ( seg ) - do - { - seg->edge = edge; - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - - /* now compute each edge properties */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - FT_Int is_round = 0; /* does it contain round segments? */ - FT_Int is_straight = 0; /* does it contain straight segments? */ -#if 0 - FT_Pos ups = 0; /* number of upwards segments */ - FT_Pos downs = 0; /* number of downwards segments */ -#endif - - - seg = edge->first; - - do - { - FT_Bool is_serif; - - - /* check for roundness of segment */ - if ( seg->flags & AF_EDGE_ROUND ) - is_round++; - else - is_straight++; - -#if 0 - /* check for segment direction */ - if ( seg->dir == up_dir ) - ups += seg->max_coord - seg->min_coord; - else - downs += seg->max_coord - seg->min_coord; -#endif - - /* check for links -- if seg->serif is set, then seg->link must */ - /* be ignored */ - is_serif = (FT_Bool)( seg->serif && - seg->serif->edge && - seg->serif->edge != edge ); - - if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) - { - AF_Edge edge2; - AF_Segment seg2; - - - edge2 = edge->link; - seg2 = seg->link; - - if ( is_serif ) - { - seg2 = seg->serif; - edge2 = edge->serif; - } - - if ( edge2 ) - { - FT_Pos edge_delta; - FT_Pos seg_delta; - - - edge_delta = edge->fpos - edge2->fpos; - if ( edge_delta < 0 ) - edge_delta = -edge_delta; - - seg_delta = seg->pos - seg2->pos; - if ( seg_delta < 0 ) - seg_delta = -seg_delta; - - if ( seg_delta < edge_delta ) - edge2 = seg2->edge; - } - else - edge2 = seg2->edge; - - if ( is_serif ) - { - edge->serif = edge2; - edge2->flags |= AF_EDGE_SERIF; - } - else - edge->link = edge2; - } - - seg = seg->edge_next; - - } while ( seg != edge->first ); - - /* set the round/straight flags */ - edge->flags = AF_EDGE_NORMAL; - - if ( is_round > 0 && is_round >= is_straight ) - edge->flags |= AF_EDGE_ROUND; - -#if 0 - /* set the edge's main direction */ - edge->dir = AF_DIR_NONE; - - if ( ups > downs ) - edge->dir = (FT_Char)up_dir; - - else if ( ups < downs ) - edge->dir = (FT_Char)-up_dir; - - else if ( ups == downs ) - edge->dir = 0; /* both up and down! */ -#endif - - /* get rid of serifs if link is set */ - /* XXX: This gets rid of many unpleasant artefacts! */ - /* Example: the `c' in cour.pfa at size 13 */ - - if ( edge->serif && edge->link ) - edge->serif = 0; - } - } - - Exit: - return error; - } - - - /* Detect segments and edges for given dimension. */ - - FT_LOCAL_DEF( FT_Error ) - af_latin_hints_detect_features( AF_GlyphHints hints, - AF_Dimension dim ) - { - FT_Error error; - - - error = af_latin_hints_compute_segments( hints, dim ); - if ( !error ) - { - af_latin_hints_link_segments( hints, dim ); - - error = af_latin_hints_compute_edges( hints, dim ); - } - - return error; - } - - - /* Compute all edges which lie within blue zones. */ - - FT_LOCAL_DEF( void ) - af_latin_hints_compute_blue_edges( AF_GlyphHints hints, - AF_LatinMetrics metrics ) - { - AF_AxisHints axis = &hints->axis[AF_DIMENSION_VERT]; - AF_Edge edge = axis->edges; - AF_Edge edge_limit = edge + axis->num_edges; - AF_LatinAxis latin = &metrics->axis[AF_DIMENSION_VERT]; - FT_Fixed scale = latin->scale; - - - /* compute which blue zones are active, i.e. have their scaled */ - /* size < 3/4 pixels */ - - /* for each horizontal edge search the blue zone which is closest */ - for ( ; edge < edge_limit; edge++ ) - { - FT_UInt bb; - AF_Width best_blue = NULL; - FT_Pos best_dist; /* initial threshold */ - - - /* compute the initial threshold as a fraction of the EM size */ - /* (the value 40 is heuristic) */ - best_dist = FT_MulFix( metrics->units_per_em / 40, scale ); - - /* assure a minimum distance of 0.5px */ - if ( best_dist > 64 / 2 ) - best_dist = 64 / 2; - - for ( bb = 0; bb < latin->blue_count; bb++ ) - { - AF_LatinBlue blue = latin->blues + bb; - FT_Bool is_top_blue, is_major_dir; - - - /* skip inactive blue zones (i.e., those that are too large) */ - if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) - continue; - - /* if it is a top zone, check for right edges -- if it is a bottom */ - /* zone, check for left edges */ - /* */ - /* of course, that's for TrueType */ - is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); - - /* if it is a top zone, the edge must be against the major */ - /* direction; if it is a bottom zone, it must be in the major */ - /* direction */ - if ( is_top_blue ^ is_major_dir ) - { - FT_Pos dist; - - - /* first of all, compare it to the reference position */ - dist = edge->fpos - blue->ref.org; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = &blue->ref; - } - - /* now compare it to the overshoot position and check whether */ - /* the edge is rounded, and whether the edge is over the */ - /* reference position of a top zone, or under the reference */ - /* position of a bottom zone */ - if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) - { - FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); - - - if ( is_top_blue ^ is_under_ref ) - { - dist = edge->fpos - blue->shoot.org; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = &blue->shoot; - } - } - } - } - } - - if ( best_blue ) - edge->blue_edge = best_blue; - } - } - - - /* Initalize hinting engine. */ - - static FT_Error - af_latin_hints_init( AF_GlyphHints hints, - AF_LatinMetrics metrics ) - { - FT_Render_Mode mode; - FT_UInt32 scaler_flags, other_flags; - FT_Face face = metrics->root.scaler.face; - - - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); - - /* - * correct x_scale and y_scale if needed, since they may have - * been modified by `af_latin_metrics_scale_dim' above - */ - hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; - hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; - hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; - hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; - - /* compute flags depending on render mode, etc. */ - mode = metrics->root.scaler.render_mode; - -#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ - if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) - metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; -#endif - - scaler_flags = hints->scaler_flags; - other_flags = 0; - - /* - * We snap the width of vertical stems for the monochrome and - * horizontal LCD rendering targets only. - */ - if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) - other_flags |= AF_LATIN_HINTS_HORZ_SNAP; - - /* - * We snap the width of horizontal stems for the monochrome and - * vertical LCD rendering targets only. - */ - if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) - other_flags |= AF_LATIN_HINTS_VERT_SNAP; - - /* - * We adjust stems to full pixels only if we don't use the `light' mode. - */ - if ( mode != FT_RENDER_MODE_LIGHT ) - other_flags |= AF_LATIN_HINTS_STEM_ADJUST; - - if ( mode == FT_RENDER_MODE_MONO ) - other_flags |= AF_LATIN_HINTS_MONO; - - /* - * In `light' hinting mode we disable horizontal hinting completely. - * We also do it if the face is italic. - */ - if ( mode == FT_RENDER_MODE_LIGHT || - ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) - scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; - - hints->scaler_flags = scaler_flags; - hints->other_flags = other_flags; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* Snap a given width in scaled coordinates to one of the */ - /* current standard widths. */ - - static FT_Pos - af_latin_snap_width( AF_Width widths, - FT_Int count, - FT_Pos width ) - { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; - - - for ( n = 0; n < count; n++ ) - { - FT_Pos w; - FT_Pos dist; - - - w = widths[n].cur; - dist = width - w; - if ( dist < 0 ) - dist = -dist; - if ( dist < best ) - { - best = dist; - reference = w; - } - } - - scaled = FT_PIX_ROUND( reference ); - - if ( width >= reference ) - { - if ( width < scaled + 48 ) - width = reference; - } - else - { - if ( width > scaled - 48 ) - width = reference; - } - - return width; - } - - - /* Compute the snapped width of a given stem, ignoring very thin ones. */ - /* There is a lot of voodoo in this function; changing the hard-coded */ - /* parameters influence the whole hinting process. */ - - static FT_Pos - af_latin_compute_stem_width( AF_GlyphHints hints, - AF_Dimension dim, - FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) - { - AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; - AF_LatinAxis axis = & metrics->axis[dim]; - FT_Pos dist = width; - FT_Int sign = 0; - FT_Int vertical = ( dim == AF_DIMENSION_VERT ); - - - if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || - axis->extra_light ) - return width; - - if ( dist < 0 ) - { - dist = -width; - sign = 1; - } - - if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || - ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) - { - /* smooth hinting process: very lightly quantize the stem width */ - - /* leave the widths of serifs alone */ - if ( ( stem_flags & AF_EDGE_SERIF ) && - vertical && - ( dist < 3 * 64 ) ) - goto Done_Width; - - else if ( base_flags & AF_EDGE_ROUND ) - { - if ( dist < 80 ) - dist = 64; - } - else if ( dist < 56 ) - dist = 56; - - if ( axis->width_count > 0 ) - { - FT_Pos delta; - - - /* compare to standard width */ - delta = dist - axis->widths[0].cur; - - if ( delta < 0 ) - delta = -delta; - - if ( delta < 40 ) - { - dist = axis->widths[0].cur; - if ( dist < 48 ) - dist = 48; - - goto Done_Width; - } - - if ( dist < 3 * 64 ) - { - delta = dist & 63; - dist &= -64; - - if ( delta < 10 ) - dist += delta; - - else if ( delta < 32 ) - dist += 10; - - else if ( delta < 54 ) - dist += 54; - - else - dist += delta; - } - else - dist = ( dist + 32 ) & ~63; - } - } - 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 ); - - if ( vertical ) - { - /* in the case of vertical hinting, always round */ - /* the stem heights to integer pixels */ - - if ( dist >= 64 ) - dist = ( dist + 16 ) & ~63; - else - dist = 64; - } - else - { - if ( AF_LATIN_HINTS_DO_MONO( hints ) ) - { - /* monochrome horizontal hinting: snap widths to integer pixels */ - /* with a different threshold */ - - if ( dist < 64 ) - dist = 64; - else - dist = ( dist + 32 ) & ~63; - } - else - { - /* for horizontal anti-aliased hinting, we adopt a more subtle */ - /* approach: we strengthen small stems, round stems whose size */ - /* is between 1 and 2 pixels to an integer, otherwise nothing */ - - if ( dist < 48 ) - 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_Pos 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; - } - } - } - - Done_Width: - if ( sign ) - dist = -dist; - - return dist; - } - - - /* Align one stem edge relative to the previous stem edge. */ - - static void - af_latin_align_linked_edge( AF_GlyphHints hints, - AF_Dimension dim, - AF_Edge base_edge, - AF_Edge stem_edge ) - { - FT_Pos dist = stem_edge->opos - base_edge->opos; - - FT_Pos fitted_width = af_latin_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); - - - stem_edge->pos = base_edge->pos + fitted_width; - - FT_TRACE5(( " 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 )); - } - - - /* Shift the coordinates of the `serif' edge by the same amount */ - /* as the corresponding `base' edge has been moved already. */ - - static void - af_latin_align_serif_edge( AF_GlyphHints hints, - AF_Edge base, - AF_Edge serif ) - { - FT_UNUSED( hints ); - - serif->pos = base->pos + ( serif->opos - base->opos ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** E D G E H I N T I N G ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* The main grid-fitting routine. */ - - FT_LOCAL_DEF( void ) - af_latin_hint_edges( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - FT_PtrDist n_edges; - AF_Edge edge; - AF_Edge anchor = NULL; - FT_Int has_serifs = 0; - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_UInt num_actions = 0; -#endif - - - FT_TRACE5(( "%s edge hinting\n", - dim == AF_DIMENSION_VERT ? "horizontal" : "vertical" )); - - /* we begin by aligning all stems relative to the blue zone */ - /* if needed -- that's only for horizontal edges */ - - if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) - { - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Width blue; - AF_Edge edge1, edge2; /* these edges form the stem to check */ - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - blue = edge->blue_edge; - edge1 = NULL; - edge2 = edge->link; - - if ( blue ) - edge1 = edge; - - /* flip edges if the other stem is aligned to a blue zone */ - else if ( edge2 && edge2->blue_edge ) - { - blue = edge2->blue_edge; - edge1 = edge2; - edge2 = edge; - } - - if ( !edge1 ) - continue; - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( !anchor ) - FT_TRACE5(( " BLUE_ANCHOR: edge %d (opos=%.2f) snapped to %.2f," - " was %.2f (anchor=edge %d)\n", - edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0, - edge1->pos / 64.0, edge - edges )); - else - FT_TRACE5(( " 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 )); - - num_actions++; -#endif - - edge1->pos = blue->fit; - edge1->flags |= AF_EDGE_DONE; - - if ( edge2 && !edge2->blue_edge ) - { - af_latin_align_linked_edge( hints, dim, edge1, edge2 ); - edge2->flags |= AF_EDGE_DONE; - -#ifdef FT_DEBUG_LEVEL_TRACE - num_actions++; -#endif - } - - if ( !anchor ) - anchor = edge; - } - } - - /* now we align all other stem edges, trying to maintain the */ - /* relative order of stems in the glyph */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Edge edge2; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - /* skip all non-stem edges */ - edge2 = edge->link; - if ( !edge2 ) - { - has_serifs++; - continue; - } - - /* now align the stem */ - - /* this should not happen, but it's better to be safe */ - if ( edge2->blue_edge ) - { - FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2-edges )); - - af_latin_align_linked_edge( hints, dim, edge2, edge ); - edge->flags |= AF_EDGE_DONE; - -#ifdef FT_DEBUG_LEVEL_TRACE - num_actions++; -#endif - continue; - } - - if ( !anchor ) - { - /* if we reach this if clause, no stem has been aligned yet */ - - FT_Pos org_len, org_center, cur_len; - FT_Pos cur_pos1, error1, error2, u_off, d_off; - - - org_len = edge2->opos - edge->opos; - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); - - /* some voodoo to specially round edges for small stem widths; */ - /* the idea is to align the center of a stem, then shifting */ - /* the stem edges to suitable positions */ - if ( cur_len <= 64 ) - { - /* width <= 1px */ - u_off = 32; - d_off = 32; - } - else - { - /* 1px < width < 1.5px */ - u_off = 38; - d_off = 26; - } - - if ( cur_len < 96 ) - { - org_center = edge->opos + ( org_len >> 1 ); - cur_pos1 = FT_PIX_ROUND( org_center ); - - error1 = org_center - ( cur_pos1 - u_off ); - if ( error1 < 0 ) - error1 = -error1; - - error2 = org_center - ( cur_pos1 + d_off ); - if ( error2 < 0 ) - error2 = -error2; - - if ( error1 < error2 ) - cur_pos1 -= u_off; - else - cur_pos1 += d_off; - - edge->pos = cur_pos1 - cur_len / 2; - edge2->pos = edge->pos + cur_len; - } - else - edge->pos = FT_PIX_ROUND( edge->opos ); - - anchor = edge; - edge->flags |= AF_EDGE_DONE; - - FT_TRACE5(( " ANCHOR: edge %d (opos=%.2f) and %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 )); - - af_latin_align_linked_edge( hints, dim, edge, edge2 ); - -#ifdef FT_DEBUG_LEVEL_TRACE - num_actions += 2; -#endif - } - else - { - FT_Pos org_pos, org_len, org_center, cur_len; - FT_Pos cur_pos1, cur_pos2, delta1, delta2; - - - org_pos = anchor->pos + ( edge->opos - anchor->opos ); - org_len = edge2->opos - edge->opos; - org_center = org_pos + ( org_len >> 1 ); - - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); - - if ( edge2->flags & AF_EDGE_DONE ) - { - FT_TRACE5(( " ADJUST: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, - ( edge2->pos - cur_len ) / 64.0 )); - - edge->pos = edge2->pos - cur_len; - } - - else if ( cur_len < 96 ) - { - FT_Pos u_off, d_off; - - - cur_pos1 = FT_PIX_ROUND( org_center ); - - if ( cur_len <= 64 ) - { - u_off = 32; - d_off = 32; - } - else - { - u_off = 38; - d_off = 26; - } - - delta1 = org_center - ( cur_pos1 - u_off ); - if ( delta1 < 0 ) - delta1 = -delta1; - - delta2 = org_center - ( cur_pos1 + d_off ); - if ( delta2 < 0 ) - delta2 = -delta2; - - if ( delta1 < delta2 ) - cur_pos1 -= u_off; - else - cur_pos1 += d_off; - - edge->pos = cur_pos1 - cur_len / 2; - edge2->pos = cur_pos1 + cur_len / 2; - - FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked 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 - { - org_pos = anchor->pos + ( edge->opos - anchor->opos ); - org_len = edge2->opos - edge->opos; - org_center = org_pos + ( org_len >> 1 ); - - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); - - cur_pos1 = FT_PIX_ROUND( org_pos ); - delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center; - if ( delta1 < 0 ) - delta1 = -delta1; - - cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; - delta2 = cur_pos2 + ( cur_len >> 1 ) - org_center; - if ( delta2 < 0 ) - delta2 = -delta2; - - edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; - edge2->pos = edge->pos + cur_len; - - FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked 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 )); - } - -#ifdef FT_DEBUG_LEVEL_TRACE - num_actions++; -#endif - - edge->flags |= AF_EDGE_DONE; - edge2->flags |= AF_EDGE_DONE; - - if ( edge > edges && edge->pos < edge[-1].pos ) - { -#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); - - num_actions++; -#endif - - edge->pos = edge[-1].pos; - } - } - } - - /* make sure that lowercase m's maintain their symmetry */ - - /* In general, lowercase m's have six vertical edges if they are sans */ - /* serif, or twelve if they are with serifs. This implementation is */ - /* based on that assumption, and seems to work very well with most */ - /* faces. However, if for a certain face this assumption is not */ - /* true, the m is just rendered like before. In addition, any stem */ - /* correction will only be applied to symmetrical glyphs (even if the */ - /* glyph is not an m), so the potential for unwanted distortion is */ - /* relatively low. */ - - /* We don't handle horizontal edges since we can't easily assure that */ - /* the third (lowest) stem aligns with the base line; it might end up */ - /* one pixel higher or lower. */ - - n_edges = edge_limit - edges; - if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) - { - AF_Edge edge1, edge2, edge3; - FT_Pos dist1, dist2, span, delta; - - - if ( n_edges == 6 ) - { - edge1 = edges; - edge2 = edges + 2; - edge3 = edges + 4; - } - else - { - edge1 = edges + 1; - edge2 = edges + 5; - edge3 = edges + 9; - } - - dist1 = edge2->opos - edge1->opos; - dist2 = edge3->opos - edge2->opos; - - span = dist1 - dist2; - if ( span < 0 ) - span = -span; - - if ( span < 8 ) - { - delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); - edge3->pos -= delta; - if ( edge3->link ) - edge3->link->pos -= delta; - - /* move the serifs along with the stem */ - if ( n_edges == 12 ) - { - ( edges + 8 )->pos -= delta; - ( edges + 11 )->pos -= delta; - } - - edge3->flags |= AF_EDGE_DONE; - if ( edge3->link ) - edge3->link->flags |= AF_EDGE_DONE; - } - } - - if ( has_serifs || !anchor ) - { - /* - * now hint the remaining edges (serifs and single) in order - * to complete our processing - */ - 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 ); - FT_TRACE5(( " 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 ) - { - edge->pos = FT_PIX_ROUND( edge->opos ); - anchor = edge; - FT_TRACE5(( " SERIF_ANCHOR: edge %d (opos=%.2f)" - " snapped to %.2f\n", - edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); - } - else - { - 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 ) - { - if ( after->opos == before->opos ) - edge->pos = before->pos; - else - edge->pos = before->pos + - FT_MulDiv( edge->opos - before->opos, - after->pos - before->pos, - after->opos - before->opos ); - - FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to %.2f" - " from %d (opos=%.2f)\n", - edge - edges, edge->opos / 64.0, - edge->pos / 64.0, - before - edges, before->opos / 64.0 )); - } - else - { - edge->pos = anchor->pos + - ( ( edge->opos - anchor->opos + 16 ) & ~31 ); - FT_TRACE5(( " SERIF_LINK2: edge %d (opos=%.2f)" - " snapped to %.2f\n", - edge - edges, edge->opos / 64.0, edge->pos / 64.0 )); - } - } - -#ifdef FT_DEBUG_LEVEL_TRACE - num_actions++; -#endif - edge->flags |= AF_EDGE_DONE; - - if ( edge > edges && edge->pos < edge[-1].pos ) - { -#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); - - num_actions++; -#endif - edge->pos = edge[-1].pos; - } - - if ( edge + 1 < edge_limit && - edge[1].flags & AF_EDGE_DONE && - edge->pos > edge[1].pos ) - { -#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 )); - - num_actions++; -#endif - - edge->pos = edge[1].pos; - } - } - } - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( !num_actions ) - FT_TRACE5(( " (none)\n" )); - FT_TRACE5(( "\n" )); -#endif - } - - - /* Apply the complete hinting algorithm to a latin glyph. */ - - static FT_Error - af_latin_hints_apply( AF_GlyphHints hints, - FT_Outline* outline, - AF_LatinMetrics metrics ) - { - FT_Error error; - int dim; - - - error = af_glyph_hints_reload( hints, outline ); - if ( error ) - goto Exit; - - /* analyze glyph outline */ -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || - AF_HINTS_DO_HORIZONTAL( hints ) ) -#else - if ( AF_HINTS_DO_HORIZONTAL( hints ) ) -#endif - { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); - if ( error ) - goto Exit; - } - - if ( AF_HINTS_DO_VERTICAL( hints ) ) - { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); - if ( error ) - goto Exit; - - af_latin_hints_compute_blue_edges( hints, metrics ); - } - - /* grid-fit the outline */ - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) - { - AF_WarperRec warper; - FT_Fixed scale; - FT_Pos delta; - - - af_warper_compute( &warper, hints, (AF_Dimension)dim, - &scale, &delta ); - af_glyph_hints_scale_dim( hints, (AF_Dimension)dim, - scale, delta ); - continue; - } -#endif - - if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || - ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) - { - af_latin_hint_edges( hints, (AF_Dimension)dim ); - af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim ); - af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); - af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); - } - } - af_glyph_hints_save( hints, outline ); - - Exit: - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N S C R I P T C L A S S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* XXX: this should probably fine tuned to differentiate better between */ - /* scripts... */ - - static const AF_Script_UniRangeRec af_latin_uniranges[] = - { - AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ - AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ - AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ - AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ - AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ - AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ - AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ - AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ - AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ - AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ - AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ - AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ - AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ - AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ - AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ - AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ - AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ - AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ - AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ - AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ - AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ - AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ - AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */ - AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ - AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ - AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ - AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ - AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_latin_script_class, - AF_SCRIPT_LATIN, - af_latin_uniranges, - 'o', - - sizeof ( AF_LatinMetricsRec ), - - (AF_Script_InitMetricsFunc) af_latin_metrics_init, - (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, - - (AF_Script_InitHintsFunc) af_latin_hints_init, - (AF_Script_ApplyHintsFunc) af_latin_hints_apply - ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/aflatin.h b/drivers/freetype/freetype/src/autofit/aflatin.h deleted file mode 100644 index d9170b3dcc..0000000000 --- a/drivers/freetype/freetype/src/autofit/aflatin.h +++ /dev/null @@ -1,202 +0,0 @@ -/***************************************************************************/ -/* */ -/* aflatin.h */ -/* */ -/* Auto-fitter hinting routines for latin script (specification). */ -/* */ -/* Copyright 2003-2007, 2009, 2011-2012 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 __AFLATIN_H__ -#define __AFLATIN_H__ - -#include "afhints.h" - - -FT_BEGIN_HEADER - - - /* the latin-specific script class */ - - AF_DECLARE_SCRIPT_CLASS( af_latin_script_class ) - - - /* constants are given with units_per_em == 2048 in mind */ -#define AF_LATIN_CONSTANT( metrics, c ) \ - ( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L O B A L M E T R I C S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* - * The following declarations could be embedded in the file `aflatin.c'; - * they have been made semi-public to allow alternate script hinters to - * re-use some of them. - */ - - - /* Latin (global) metrics management */ - - enum - { - AF_LATIN_BLUE_CAPITAL_TOP, - AF_LATIN_BLUE_CAPITAL_BOTTOM, - AF_LATIN_BLUE_SMALL_F_TOP, - AF_LATIN_BLUE_SMALL_TOP, - AF_LATIN_BLUE_SMALL_BOTTOM, - AF_LATIN_BLUE_SMALL_MINOR, - - AF_LATIN_BLUE_MAX - }; - - -#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \ - (b) == AF_LATIN_BLUE_SMALL_F_TOP || \ - (b) == AF_LATIN_BLUE_SMALL_TOP ) - -#define AF_LATIN_MAX_WIDTHS 16 -#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX - - - enum - { - AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */ - AF_LATIN_BLUE_TOP = 1 << 1, /* result of AF_LATIN_IS_TOP_BLUE */ - AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */ - /* optimization */ - AF_LATIN_BLUE_FLAG_MAX - }; - - - typedef struct AF_LatinBlueRec_ - { - AF_WidthRec ref; - AF_WidthRec shoot; - FT_UInt flags; - - } AF_LatinBlueRec, *AF_LatinBlue; - - - typedef struct AF_LatinAxisRec_ - { - FT_Fixed scale; - FT_Pos delta; - - FT_UInt width_count; /* number of used widths */ - AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]; /* widths array */ - FT_Pos edge_distance_threshold; /* used for creating edges */ - FT_Pos standard_width; /* the default stem thickness */ - FT_Bool extra_light; /* is standard width very light? */ - - /* ignored for horizontal metrics */ - FT_UInt blue_count; - AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX]; - - FT_Fixed org_scale; - FT_Pos org_delta; - - } AF_LatinAxisRec, *AF_LatinAxis; - - - typedef struct AF_LatinMetricsRec_ - { - AF_ScriptMetricsRec root; - FT_UInt units_per_em; - AF_LatinAxisRec axis[AF_DIMENSION_MAX]; - - } AF_LatinMetricsRec, *AF_LatinMetrics; - - - FT_LOCAL( FT_Error ) - af_latin_metrics_init( AF_LatinMetrics metrics, - FT_Face face ); - - FT_LOCAL( void ) - af_latin_metrics_scale( AF_LatinMetrics metrics, - AF_Scaler scaler ); - - FT_LOCAL( void ) - af_latin_metrics_init_widths( AF_LatinMetrics metrics, - FT_Face face ); - - FT_LOCAL( void ) - af_latin_metrics_check_digits( AF_LatinMetrics metrics, - FT_Face face ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H A N A L Y S I S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - enum - { - AF_LATIN_HINTS_HORZ_SNAP = 1 << 0, /* enable stem width snapping */ - AF_LATIN_HINTS_VERT_SNAP = 1 << 1, /* enable stem height snapping */ - AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, /* enable stem width/height */ - /* adjustment */ - AF_LATIN_HINTS_MONO = 1 << 3 /* indicate monochrome */ - /* rendering */ - }; - - -#define AF_LATIN_HINTS_DO_HORZ_SNAP( h ) \ - AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP ) - -#define AF_LATIN_HINTS_DO_VERT_SNAP( h ) \ - AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP ) - -#define AF_LATIN_HINTS_DO_STEM_ADJUST( h ) \ - AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST ) - -#define AF_LATIN_HINTS_DO_MONO( h ) \ - AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO ) - - - /* - * The next functions shouldn't normally be exported. However, other - * scripts might like to use these functions as-is. - */ - FT_LOCAL( FT_Error ) - af_latin_hints_compute_segments( AF_GlyphHints hints, - AF_Dimension dim ); - - FT_LOCAL( void ) - af_latin_hints_link_segments( AF_GlyphHints hints, - AF_Dimension dim ); - - FT_LOCAL( FT_Error ) - af_latin_hints_compute_edges( AF_GlyphHints hints, - AF_Dimension dim ); - - FT_LOCAL( FT_Error ) - af_latin_hints_detect_features( AF_GlyphHints hints, - AF_Dimension dim ); - -/* */ - -FT_END_HEADER - -#endif /* __AFLATIN_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/aflatin2.c b/drivers/freetype/freetype/src/autofit/aflatin2.c deleted file mode 100644 index b1e9658d5d..0000000000 --- a/drivers/freetype/freetype/src/autofit/aflatin2.c +++ /dev/null @@ -1,2406 +0,0 @@ -/***************************************************************************/ -/* */ -/* aflatin2.c */ -/* */ -/* Auto-fitter hinting routines for latin script (body). */ -/* */ -/* Copyright 2003-2013 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 FT_ADVANCES_H - -#include "afglobal.h" -#include "aflatin.h" -#include "aflatin2.h" -#include "aferrors.h" - - -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.h" -#endif - - - /*************************************************************************/ - /* */ - /* 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_aflatin2 - - - FT_LOCAL_DEF( FT_Error ) - af_latin2_hints_compute_segments( AF_GlyphHints hints, - AF_Dimension dim ); - - FT_LOCAL_DEF( void ) - af_latin2_hints_link_segments( AF_GlyphHints hints, - AF_Dimension dim ); - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L O B A L M E T R I C S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - af_latin2_metrics_init_widths( AF_LatinMetrics metrics, - FT_Face face ) - { - /* scan the array of segments in each direction */ - AF_GlyphHintsRec hints[1]; - - - af_glyph_hints_init( hints, face->memory ); - - metrics->axis[AF_DIMENSION_HORZ].width_count = 0; - metrics->axis[AF_DIMENSION_VERT].width_count = 0; - - { - FT_Error error; - FT_UInt glyph_index; - int dim; - AF_LatinMetricsRec dummy[1]; - AF_Scaler scaler = &dummy->root.scaler; - - - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); - if ( glyph_index == 0 ) - goto Exit; - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || face->glyph->outline.n_points <= 0 ) - goto Exit; - - FT_ZERO( dummy ); - - dummy->units_per_em = metrics->units_per_em; - scaler->x_scale = scaler->y_scale = 0x10000L; - scaler->x_delta = scaler->y_delta = 0; - scaler->face = face; - scaler->render_mode = FT_RENDER_MODE_NORMAL; - scaler->flags = 0; - - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); - - error = af_glyph_hints_reload( hints, &face->glyph->outline ); - if ( error ) - goto Exit; - - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_LatinAxis axis = &metrics->axis[dim]; - AF_AxisHints axhints = &hints->axis[dim]; - AF_Segment seg, limit, link; - FT_UInt num_widths = 0; - - - error = af_latin2_hints_compute_segments( hints, - (AF_Dimension)dim ); - if ( error ) - goto Exit; - - af_latin2_hints_link_segments( hints, - (AF_Dimension)dim ); - - seg = axhints->segments; - limit = seg + axhints->num_segments; - - for ( ; seg < limit; seg++ ) - { - link = seg->link; - - /* we only consider stem segments there! */ - if ( link && link->link == seg && link > seg ) - { - FT_Pos dist; - - - dist = seg->pos - link->pos; - if ( dist < 0 ) - dist = -dist; - - if ( num_widths < AF_LATIN_MAX_WIDTHS ) - axis->widths[num_widths++].org = dist; - } - } - - af_sort_widths( num_widths, axis->widths ); - axis->width_count = num_widths; - } - - Exit: - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_LatinAxis axis = &metrics->axis[dim]; - FT_Pos stdw; - - - stdw = ( axis->width_count > 0 ) - ? axis->widths[0].org - : AF_LATIN_CONSTANT( metrics, 50 ); - - /* let's try 20% of the smallest width */ - axis->edge_distance_threshold = stdw / 5; - axis->standard_width = stdw; - axis->extra_light = 0; - } - } - - af_glyph_hints_done( hints ); - } - - - -#define AF_LATIN_MAX_TEST_CHARACTERS 12 - - - static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES] - [AF_LATIN_MAX_TEST_CHARACTERS+1] = - { - "THEZOCQS", - "HEZLOCUS", - "fijkdbh", - "xzroesc", - "xzroesc", - "pqgjy" - }; - - - static void - af_latin2_metrics_init_blues( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Int num_flats; - FT_Int num_rounds; - FT_Int bb; - AF_LatinBlue blue; - FT_Error error; - AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; - FT_GlyphSlot glyph = face->glyph; - - - /* we compute the blues simply by loading each character from the */ - /* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */ - /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ - - FT_TRACE5(( "blue zones computation\n" - "======================\n\n" )); - - for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) - { - const char* p = af_latin2_blue_chars[bb]; - const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; - FT_Pos* blue_ref; - FT_Pos* blue_shoot; - - - FT_TRACE5(( "blue zone %d:\n", bb )); - - num_flats = 0; - num_rounds = 0; - - for ( ; p < limit && *p; p++ ) - { - FT_UInt glyph_index; - FT_Int best_point, best_y, best_first, best_last; - FT_Vector* points; - FT_Bool round; - - - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); - if ( glyph_index == 0 ) - continue; - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || glyph->outline.n_points <= 0 ) - continue; - - /* now compute min or max point indices and coordinates */ - points = glyph->outline.points; - best_point = -1; - best_y = 0; /* make compiler happy */ - best_first = 0; /* ditto */ - best_last = 0; /* ditto */ - - { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; - - - for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ ) - { - FT_Int old_best_point = best_point; - FT_Int pp; - - - last = glyph->outline.contours[nn]; - - /* Avoid single-point contours since they are never rasterized. */ - /* In some fonts, they correspond to mark attachment points */ - /* which are way outside of the glyph's real outline. */ - if ( last == first ) - continue; - - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_y ) - { - best_point = pp; - best_y = points[pp].y; - } - } - else - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_y ) - { - best_point = pp; - best_y = points[pp].y; - } - } - - if ( best_point != old_best_point ) - { - best_first = first; - best_last = last; - } - } - FT_TRACE5(( " %c %d", *p, best_y )); - } - - /* now check whether the point belongs to a straight or round */ - /* segment; we first need to find in which contour the extremum */ - /* lies, then inspect its previous and next points */ - { - FT_Pos best_x = points[best_point].x; - FT_Int start, end, prev, next; - FT_Pos dist; - - - /* now look for the previous and next points that are not on the */ - /* same Y coordinate. Threshold the `closeness'... */ - start = end = best_point; - - do - { - prev = start - 1; - if ( prev < best_first ) - prev = best_last; - - dist = FT_ABS( points[prev].y - best_y ); - /* accept a small distance or a small angle (both values are */ - /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ - if ( dist > 5 ) - if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) - break; - - start = prev; - - } while ( start != best_point ); - - do - { - next = end + 1; - if ( next > best_last ) - next = best_first; - - dist = FT_ABS( points[next].y - best_y ); - if ( dist > 5 ) - if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) - break; - - end = next; - - } while ( end != best_point ); - - /* now, set the `round' flag depending on the segment's kind */ - round = FT_BOOL( - FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON || - FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON ); - - FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); - } - - if ( round ) - rounds[num_rounds++] = best_y; - else - flats[num_flats++] = best_y; - } - - if ( num_flats == 0 && num_rounds == 0 ) - { - /* - * we couldn't find a single glyph to compute this blue zone, - * we will simply ignore it then - */ - FT_TRACE5(( " empty\n" )); - continue; - } - - /* we have computed the contents of the `rounds' and `flats' tables, */ - /* now determine the reference and overshoot position of the blue -- */ - /* we simply take the median value after a simple sort */ - af_sort_pos( num_rounds, rounds ); - af_sort_pos( num_flats, flats ); - - blue = & axis->blues[axis->blue_count]; - blue_ref = & blue->ref.org; - blue_shoot = & blue->shoot.org; - - axis->blue_count++; - - if ( num_flats == 0 ) - { - *blue_ref = - *blue_shoot = rounds[num_rounds / 2]; - } - else if ( num_rounds == 0 ) - { - *blue_ref = - *blue_shoot = flats[num_flats / 2]; - } - else - { - *blue_ref = flats[num_flats / 2]; - *blue_shoot = rounds[num_rounds / 2]; - } - - /* there are sometimes problems: if the overshoot position of top */ - /* zones is under its reference position, or the opposite for bottom */ - /* zones. We must thus check everything there and correct the errors */ - if ( *blue_shoot != *blue_ref ) - { - FT_Pos ref = *blue_ref; - FT_Pos shoot = *blue_shoot; - FT_Bool over_ref = FT_BOOL( shoot > ref ); - - - if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) - { - *blue_ref = - *blue_shoot = ( shoot + ref ) / 2; - - FT_TRACE5(( " [overshoot smaller than reference," - " taking mean value]\n" )); - } - } - - blue->flags = 0; - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) - blue->flags |= AF_LATIN_BLUE_TOP; - - /* - * The following flags is used later to adjust the y and x scales - * in order to optimize the pixel grid alignment of the top of small - * letters. - */ - if ( bb == AF_LATIN_BLUE_SMALL_TOP ) - blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; - - FT_TRACE5(( " -> reference = %ld\n" - " overshoot = %ld\n", - *blue_ref, *blue_shoot )); - } - - return; - } - - - FT_LOCAL_DEF( void ) - af_latin2_metrics_check_digits( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_UInt i; - FT_Bool started = 0, same_width = 1; - FT_Fixed advance, old_advance = 0; - - - /* check whether all ASCII digits have the same advance width; */ - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) - { - FT_UInt glyph_index; - - - glyph_index = FT_Get_Char_Index( face, i ); - if ( glyph_index == 0 ) - continue; - - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) - continue; - - if ( started ) - { - if ( advance != old_advance ) - { - same_width = 0; - break; - } - } - else - { - old_advance = advance; - started = 1; - } - } - - metrics->root.digits_have_same_width = same_width; - } - - - FT_LOCAL_DEF( FT_Error ) - af_latin2_metrics_init( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_Error error = FT_Err_Ok; - FT_CharMap oldmap = face->charmap; - FT_UInt ee; - - static const FT_Encoding latin_encodings[] = - { - FT_ENCODING_UNICODE, - FT_ENCODING_APPLE_ROMAN, - FT_ENCODING_ADOBE_STANDARD, - FT_ENCODING_ADOBE_LATIN_1, - FT_ENCODING_NONE /* end of list */ - }; - - - metrics->units_per_em = face->units_per_EM; - - /* do we have a latin charmap in there? */ - for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ ) - { - error = FT_Select_Charmap( face, latin_encodings[ee] ); - if ( !error ) - break; - } - - if ( !error ) - { - af_latin2_metrics_init_widths( metrics, face ); - af_latin2_metrics_init_blues( metrics, face ); - af_latin2_metrics_check_digits( metrics, face ); - } - - FT_Set_Charmap( face, oldmap ); - return FT_Err_Ok; - } - - - static void - af_latin2_metrics_scale_dim( AF_LatinMetrics metrics, - AF_Scaler scaler, - AF_Dimension dim ) - { - FT_Fixed scale; - FT_Pos delta; - AF_LatinAxis axis; - FT_UInt nn; - - - if ( dim == AF_DIMENSION_HORZ ) - { - scale = scaler->x_scale; - delta = scaler->x_delta; - } - else - { - scale = scaler->y_scale; - delta = scaler->y_delta; - } - - axis = &metrics->axis[dim]; - - if ( axis->org_scale == scale && axis->org_delta == delta ) - return; - - axis->org_scale = scale; - axis->org_delta = delta; - - /* - * correct Y scale to optimize the alignment of the top of small - * letters to the pixel grid - */ - if ( dim == AF_DIMENSION_VERT ) - { - AF_LatinAxis vaxis = &metrics->axis[AF_DIMENSION_VERT]; - AF_LatinBlue blue = NULL; - - - for ( nn = 0; nn < vaxis->blue_count; nn++ ) - { - if ( vaxis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) - { - blue = &vaxis->blues[nn]; - break; - } - } - - if ( blue ) - { - FT_Pos scaled; - FT_Pos threshold; - FT_Pos fitted; - FT_UInt limit; - FT_UInt ppem; - - - scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); - ppem = metrics->root.scaler.face->size->metrics.x_ppem; - limit = metrics->root.globals->increase_x_height; - threshold = 40; - - /* if the `increase-x-height' property is active, */ - /* we round up much more often */ - if ( limit && - ppem <= limit && - ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN ) - threshold = 52; - - fitted = ( scaled + threshold ) & ~63; - -#if 1 - if ( scaled != fitted ) - { - scale = FT_MulDiv( scale, fitted, scaled ); - FT_TRACE5(( "== scaled x-top = %.2g" - " fitted = %.2g, scaling = %.4g\n", - scaled / 64.0, fitted / 64.0, - ( fitted * 1.0 ) / scaled )); - } -#endif - } - } - - axis->scale = scale; - axis->delta = delta; - - if ( dim == AF_DIMENSION_HORZ ) - { - metrics->root.scaler.x_scale = scale; - metrics->root.scaler.x_delta = delta; - } - else - { - metrics->root.scaler.y_scale = scale; - metrics->root.scaler.y_delta = delta; - } - - /* scale the standard widths */ - for ( nn = 0; nn < axis->width_count; nn++ ) - { - AF_Width width = axis->widths + nn; - - - width->cur = FT_MulFix( width->org, scale ); - width->fit = width->cur; - } - - /* an extra-light axis corresponds to a standard width that is */ - /* smaller than 5/8 pixels */ - axis->extra_light = - (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); - - if ( dim == AF_DIMENSION_VERT ) - { - /* scale the blue zones */ - for ( nn = 0; nn < axis->blue_count; nn++ ) - { - AF_LatinBlue blue = &axis->blues[nn]; - FT_Pos dist; - - - blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; - blue->ref.fit = blue->ref.cur; - blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; - blue->shoot.fit = blue->shoot.cur; - blue->flags &= ~AF_LATIN_BLUE_ACTIVE; - - /* a blue zone is only active if it is less than 3/4 pixels tall */ - dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); - if ( dist <= 48 && dist >= -48 ) - { - FT_Pos delta1, delta2; - - delta1 = blue->shoot.org - blue->ref.org; - delta2 = delta1; - if ( delta1 < 0 ) - delta2 = -delta2; - - delta2 = FT_MulFix( delta2, scale ); - - if ( delta2 < 32 ) - delta2 = 0; - else if ( delta2 < 64 ) - delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); - else - delta2 = FT_PIX_ROUND( delta2 ); - - if ( delta1 < 0 ) - delta2 = -delta2; - - blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); - blue->shoot.fit = blue->ref.fit + delta2; - - FT_TRACE5(( ">> activating blue zone %d:" - " ref.cur=%.2g ref.fit=%.2g" - " shoot.cur=%.2g shoot.fit=%.2g\n", - nn, blue->ref.cur / 64.0, blue->ref.fit / 64.0, - blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); - - blue->flags |= AF_LATIN_BLUE_ACTIVE; - } - } - } - } - - - FT_LOCAL_DEF( void ) - af_latin2_metrics_scale( AF_LatinMetrics metrics, - AF_Scaler scaler ) - { - metrics->root.scaler.render_mode = scaler->render_mode; - metrics->root.scaler.face = scaler->face; - metrics->root.scaler.flags = scaler->flags; - - af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); - af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H A N A L Y S I S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define SORT_SEGMENTS - - FT_LOCAL_DEF( FT_Error ) - af_latin2_hints_compute_segments( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - FT_Memory memory = hints->memory; - FT_Error error = FT_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; - - - FT_ZERO( &seg0 ); - seg0.score = 32000; - seg0.flags = AF_EDGE_NORMAL; - - major_dir = (AF_Direction)FT_ABS( axis->major_dir ); - segment_dir = major_dir; - - axis->num_segments = 0; - - /* set up (u,v) in each point */ - if ( dim == AF_DIMENSION_HORZ ) - { - AF_Point point = hints->points; - AF_Point limit = point + hints->num_points; - - - for ( ; point < limit; point++ ) - { - point->u = point->fx; - point->v = point->fy; - } - } - else - { - AF_Point point = hints->points; - AF_Point limit = point + hints->num_points; - - - for ( ; point < limit; point++ ) - { - point->u = point->fy; - point->v = point->fx; - } - } - - /* do each contour separately */ - for ( ; contour < contour_limit; contour++ ) - { - AF_Point point = contour[0]; - AF_Point start = point; - AF_Point last = point->prev; - - - if ( point == last ) /* skip singletons -- just in case */ - continue; - - /* already on an edge ?, backtrack to find its start */ - if ( FT_ABS( point->in_dir ) == major_dir ) - { - point = point->prev; - - while ( point->in_dir == start->in_dir ) - point = point->prev; - } - else /* otherwise, find first segment start, if any */ - { - while ( FT_ABS( point->out_dir ) != major_dir ) - { - point = point->next; - - if ( point == start ) - goto NextContour; - } - } - - start = point; - - for (;;) - { - AF_Point first; - FT_Pos min_u, min_v, max_u, max_v; - - /* we're at the start of a new segment */ - FT_ASSERT( FT_ABS( point->out_dir ) == major_dir && - point->in_dir != point->out_dir ); - first = point; - - min_u = max_u = point->u; - min_v = max_v = point->v; - - point = point->next; - - while ( point->out_dir == first->out_dir ) - { - point = point->next; - - if ( point->u < min_u ) - min_u = point->u; - - if ( point->u > max_u ) - max_u = point->u; - } - - if ( point->v < min_v ) - min_v = point->v; - - if ( point->v > max_v ) - max_v = point->v; - - /* record new segment */ - error = af_axis_hints_new_segment( axis, memory, &segment ); - if ( error ) - goto Exit; - - segment[0] = seg0; - segment->dir = first->out_dir; - segment->first = first; - segment->last = point; - segment->pos = (FT_Short)( ( min_u + max_u ) >> 1 ); - segment->min_coord = (FT_Short) min_v; - segment->max_coord = (FT_Short) max_v; - segment->height = (FT_Short)( max_v - min_v ); - - /* a segment is round if it doesn't have successive */ - /* on-curve points. */ - { - AF_Point pt = first; - AF_Point last = point; - AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); - AF_Flags f1; - - - segment->flags &= ~AF_EDGE_ROUND; - - for ( ; pt != last; f0 = f1 ) - { - pt = pt->next; - f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); - - if ( !f0 && !f1 ) - break; - - if ( pt == last ) - segment->flags |= AF_EDGE_ROUND; - } - } - - /* this can happen in the case of a degenerate contour - * e.g. a 2-point vertical contour - */ - if ( point == start ) - break; - - /* jump to the start of the next segment, if any */ - while ( FT_ABS( point->out_dir ) != major_dir ) - { - point = point->next; - - if ( point == start ) - goto NextContour; - } - } - - NextContour: - ; - } /* 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; - AF_Point p; - FT_Pos first_v = first->v; - FT_Pos last_v = last->v; - - - if ( first == last ) - continue; - - if ( first_v < last_v ) - { - 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 - { - 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_SORT_SEGMENTS - /* place all segments with a negative direction to the start - * of the array, used to speed up segment linking later... - */ - { - AF_Segment segments = axis->segments; - FT_UInt count = axis->num_segments; - FT_UInt ii, jj; - - for ( ii = 0; ii < count; ii++ ) - { - if ( segments[ii].dir > 0 ) - { - for ( jj = ii + 1; jj < count; jj++ ) - { - if ( segments[jj].dir < 0 ) - { - AF_SegmentRec tmp; - - - tmp = segments[ii]; - segments[ii] = segments[jj]; - segments[jj] = tmp; - - break; - } - } - - if ( jj == count ) - break; - } - } - axis->mid_segments = ii; - } -#endif - - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - af_latin2_hints_link_segments( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; -#ifdef AF_SORT_SEGMENTS - AF_Segment segment_mid = segments + axis->mid_segments; -#endif - FT_Pos len_threshold, len_score; - AF_Segment seg1, seg2; - - - len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); - if ( len_threshold == 0 ) - len_threshold = 1; - - len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); - -#ifdef AF_SORT_SEGMENTS - for ( seg1 = segments; seg1 < segment_mid; seg1++ ) - { - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) - continue; - - for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ ) -#else - /* now compare each segment to the others */ - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) - continue; - - for ( seg2 = segments; seg2 < segment_limit; seg2++ ) - if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos ) -#endif - { - FT_Pos pos1 = seg1->pos; - FT_Pos pos2 = seg2->pos; - FT_Pos dist = pos2 - pos1; - - - if ( dist < 0 ) - continue; - - { - FT_Pos min = seg1->min_coord; - FT_Pos max = seg1->max_coord; - FT_Pos len, score; - - - if ( min < seg2->min_coord ) - min = seg2->min_coord; - - if ( max > seg2->max_coord ) - max = seg2->max_coord; - - len = max - min; - if ( len >= len_threshold ) - { - score = dist + len_score / len; - if ( score < seg1->score ) - { - seg1->score = score; - seg1->link = seg2; - } - - if ( score < seg2->score ) - { - seg2->score = score; - seg2->link = seg1; - } - } - } - } - } -#if 0 - } -#endif - - /* now, compute the `serif' segments */ - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - seg2 = seg1->link; - - if ( seg2 ) - { - if ( seg2->link != seg1 ) - { - seg1->link = 0; - seg1->serif = seg2->link; - } - } - } - } - - - FT_LOCAL_DEF( FT_Error ) - af_latin2_hints_compute_edges( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - FT_Error error = FT_Err_Ok; - FT_Memory memory = hints->memory; - AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; - - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; - AF_Segment seg; - - AF_Direction up_dir; - FT_Fixed scale; - FT_Pos edge_distance_threshold; - FT_Pos segment_length_threshold; - - - axis->num_edges = 0; - - scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale - : hints->y_scale; - - up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP - : AF_DIR_RIGHT; - - /* - * We want to ignore very small (mostly serif) segments, we do that - * by ignoring those that whose length is less than a given fraction - * of the standard width. If there is no standard width, we ignore - * those that are less than a given size in pixels - * - * also, unlink serif segments that are linked to segments farther - * than 50% of the standard width - */ - if ( dim == AF_DIMENSION_HORZ ) - { - if ( laxis->width_count > 0 ) - segment_length_threshold = ( laxis->standard_width * 10 ) >> 4; - else - segment_length_threshold = FT_DivFix( 64, hints->y_scale ); - } - else - segment_length_threshold = 0; - - /*********************************************************************/ - /* */ - /* We will begin by generating a sorted table of edges for the */ - /* current direction. To do so, we simply scan each segment and try */ - /* to find an edge in our table that corresponds to its position. */ - /* */ - /* If no edge is found, we create and insert a new edge in the */ - /* sorted table. Otherwise, we simply add the segment to the edge's */ - /* list which will be processed in the second step to compute the */ - /* edge's properties. */ - /* */ - /* Note that the edges table is sorted along the segment/edge */ - /* position. */ - /* */ - /*********************************************************************/ - - edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, - scale ); - if ( edge_distance_threshold > 64 / 4 ) - edge_distance_threshold = 64 / 4; - - edge_distance_threshold = FT_DivFix( edge_distance_threshold, - scale ); - - for ( seg = segments; seg < segment_limit; seg++ ) - { - AF_Edge found = 0; - FT_Int ee; - - - if ( seg->height < segment_length_threshold ) - continue; - - /* A special case for serif edges: If they are smaller than */ - /* 1.5 pixels we ignore them. */ - if ( seg->serif ) - { - FT_Pos dist = seg->serif->pos - seg->pos; - - - if ( dist < 0 ) - dist = -dist; - - if ( dist >= laxis->standard_width >> 1 ) - { - /* unlink this serif, it is too distant from its reference stem */ - seg->serif = NULL; - } - else if ( 2*seg->height < 3 * segment_length_threshold ) - continue; - } - - /* look for an edge corresponding to the segment */ - for ( ee = 0; ee < axis->num_edges; ee++ ) - { - AF_Edge edge = axis->edges + ee; - FT_Pos dist; - - - dist = seg->pos - edge->fpos; - if ( dist < 0 ) - dist = -dist; - - if ( dist < edge_distance_threshold && edge->dir == seg->dir ) - { - found = edge; - break; - } - } - - if ( !found ) - { - AF_Edge edge; - - - /* insert a new edge in the list and */ - /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, - memory, &edge ); - if ( error ) - goto Exit; - - /* add the segment to the new edge's list */ - FT_ZERO( edge ); - - edge->first = seg; - edge->last = seg; - edge->fpos = seg->pos; - edge->dir = seg->dir; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); - seg->edge_next = seg; - } - else - { - /* if an edge was found, simply add the segment to the edge's */ - /* list */ - seg->edge_next = found->first; - found->last->edge_next = seg; - found->last = seg; - } - } - - - /*********************************************************************/ - /* */ - /* Good, we will now compute each edge's properties according to */ - /* segments found on its position. Basically, these are: */ - /* */ - /* - edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straight or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /*********************************************************************/ - - /* first of all, set the `edge' field in each segment -- this is */ - /* required in order to compute edge links */ - - /* - * Note that removing this loop and setting the `edge' field of each - * segment directly in the code above slows down execution speed for - * some reasons on platforms like the Sun. - */ - { - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - AF_Edge edge; - - - for ( edge = edges; edge < edge_limit; edge++ ) - { - seg = edge->first; - if ( seg ) - do - { - seg->edge = edge; - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - - /* now, compute each edge properties */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - FT_Int is_round = 0; /* does it contain round segments? */ - FT_Int is_straight = 0; /* does it contain straight segments? */ -#if 0 - FT_Pos ups = 0; /* number of upwards segments */ - FT_Pos downs = 0; /* number of downwards segments */ -#endif - - - seg = edge->first; - - do - { - FT_Bool is_serif; - - - /* check for roundness of segment */ - if ( seg->flags & AF_EDGE_ROUND ) - is_round++; - else - is_straight++; - -#if 0 - /* check for segment direction */ - if ( seg->dir == up_dir ) - ups += seg->max_coord-seg->min_coord; - else - downs += seg->max_coord-seg->min_coord; -#endif - - /* check for links -- if seg->serif is set, then seg->link must */ - /* be ignored */ - is_serif = (FT_Bool)( seg->serif && - seg->serif->edge && - seg->serif->edge != edge ); - - if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) - { - AF_Edge edge2; - AF_Segment seg2; - - - edge2 = edge->link; - seg2 = seg->link; - - if ( is_serif ) - { - seg2 = seg->serif; - edge2 = edge->serif; - } - - if ( edge2 ) - { - FT_Pos edge_delta; - FT_Pos seg_delta; - - - edge_delta = edge->fpos - edge2->fpos; - if ( edge_delta < 0 ) - edge_delta = -edge_delta; - - seg_delta = seg->pos - seg2->pos; - if ( seg_delta < 0 ) - seg_delta = -seg_delta; - - if ( seg_delta < edge_delta ) - edge2 = seg2->edge; - } - else - edge2 = seg2->edge; - - if ( is_serif ) - { - edge->serif = edge2; - edge2->flags |= AF_EDGE_SERIF; - } - else - edge->link = edge2; - } - - seg = seg->edge_next; - - } while ( seg != edge->first ); - - /* set the round/straight flags */ - edge->flags = AF_EDGE_NORMAL; - - if ( is_round > 0 && is_round >= is_straight ) - edge->flags |= AF_EDGE_ROUND; - -#if 0 - /* set the edge's main direction */ - edge->dir = AF_DIR_NONE; - - if ( ups > downs ) - edge->dir = (FT_Char)up_dir; - - else if ( ups < downs ) - edge->dir = (FT_Char)-up_dir; - - else if ( ups == downs ) - edge->dir = 0; /* both up and down! */ -#endif - - /* gets rid of serifs if link is set */ - /* XXX: This gets rid of many unpleasant artefacts! */ - /* Example: the `c' in cour.pfa at size 13 */ - - if ( edge->serif && edge->link ) - edge->serif = 0; - } - } - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - af_latin2_hints_detect_features( AF_GlyphHints hints, - AF_Dimension dim ) - { - FT_Error error; - - - error = af_latin2_hints_compute_segments( hints, dim ); - if ( !error ) - { - af_latin2_hints_link_segments( hints, dim ); - - error = af_latin2_hints_compute_edges( hints, dim ); - } - return error; - } - - - FT_LOCAL_DEF( void ) - af_latin2_hints_compute_blue_edges( AF_GlyphHints hints, - AF_LatinMetrics metrics ) - { - AF_AxisHints axis = &hints->axis[AF_DIMENSION_VERT]; - AF_Edge edge = axis->edges; - AF_Edge edge_limit = edge + axis->num_edges; - AF_LatinAxis latin = &metrics->axis[AF_DIMENSION_VERT]; - FT_Fixed scale = latin->scale; - FT_Pos best_dist0; /* initial threshold */ - - - /* compute the initial threshold as a fraction of the EM size */ - best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); - - if ( best_dist0 > 64 / 2 ) - best_dist0 = 64 / 2; - - /* compute which blue zones are active, i.e. have their scaled */ - /* size < 3/4 pixels */ - - /* for each horizontal edge search the blue zone which is closest */ - for ( ; edge < edge_limit; edge++ ) - { - FT_Int bb; - AF_Width best_blue = NULL; - FT_Pos best_dist = best_dist0; - - for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) - { - AF_LatinBlue blue = latin->blues + bb; - FT_Bool is_top_blue, is_major_dir; - - - /* skip inactive blue zones (i.e., those that are too small) */ - if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) - continue; - - /* if it is a top zone, check for right edges -- if it is a bottom */ - /* zone, check for left edges */ - /* */ - /* of course, that's for TrueType */ - is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); - - /* if it is a top zone, the edge must be against the major */ - /* direction; if it is a bottom zone, it must be in the major */ - /* direction */ - if ( is_top_blue ^ is_major_dir ) - { - FT_Pos dist; - AF_Width compare; - - - /* if it's a rounded edge, compare it to the overshoot position */ - /* if it's a flat edge, compare it to the reference position */ - if ( edge->flags & AF_EDGE_ROUND ) - compare = &blue->shoot; - else - compare = &blue->ref; - - dist = edge->fpos - compare->org; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = compare; - } - -#if 0 - /* now, compare it to the overshoot position if the edge is */ - /* rounded, and if the edge is over the reference position of a */ - /* top zone, or under the reference position of a bottom zone */ - if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) - { - FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); - - - if ( is_top_blue ^ is_under_ref ) - { - blue = latin->blues + bb; - dist = edge->fpos - blue->shoot.org; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = & blue->shoot; - } - } - } -#endif - } - } - - if ( best_blue ) - edge->blue_edge = best_blue; - } - } - - - static FT_Error - af_latin2_hints_init( AF_GlyphHints hints, - AF_LatinMetrics metrics ) - { - FT_Render_Mode mode; - FT_UInt32 scaler_flags, other_flags; - FT_Face face = metrics->root.scaler.face; - - - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); - - /* - * correct x_scale and y_scale if needed, since they may have - * been modified `af_latin2_metrics_scale_dim' above - */ - hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; - hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; - hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; - hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; - - /* compute flags depending on render mode, etc. */ - mode = metrics->root.scaler.render_mode; - -#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ - if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) - { - metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; - } -#endif - - scaler_flags = hints->scaler_flags; - other_flags = 0; - - /* - * We snap the width of vertical stems for the monochrome and - * horizontal LCD rendering targets only. - */ - if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) - other_flags |= AF_LATIN_HINTS_HORZ_SNAP; - - /* - * We snap the width of horizontal stems for the monochrome and - * vertical LCD rendering targets only. - */ - if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) - other_flags |= AF_LATIN_HINTS_VERT_SNAP; - - /* - * We adjust stems to full pixels only if we don't use the `light' mode. - */ - if ( mode != FT_RENDER_MODE_LIGHT ) - other_flags |= AF_LATIN_HINTS_STEM_ADJUST; - - if ( mode == FT_RENDER_MODE_MONO ) - other_flags |= AF_LATIN_HINTS_MONO; - - /* - * In `light' hinting mode we disable horizontal hinting completely. - * We also do it if the face is italic. - */ - if ( mode == FT_RENDER_MODE_LIGHT || - ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) - scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; - - hints->scaler_flags = scaler_flags; - hints->other_flags = other_flags; - - return 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* snap a given width in scaled coordinates to one of the */ - /* current standard widths */ - - static FT_Pos - af_latin2_snap_width( AF_Width widths, - FT_Int count, - FT_Pos width ) - { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; - - - for ( n = 0; n < count; n++ ) - { - FT_Pos w; - FT_Pos dist; - - - w = widths[n].cur; - dist = width - w; - if ( dist < 0 ) - dist = -dist; - if ( dist < best ) - { - best = dist; - reference = w; - } - } - - scaled = FT_PIX_ROUND( reference ); - - if ( width >= reference ) - { - if ( width < scaled + 48 ) - width = reference; - } - else - { - if ( width > scaled - 48 ) - width = reference; - } - - return width; - } - - - /* compute the snapped width of a given stem */ - - static FT_Pos - af_latin2_compute_stem_width( AF_GlyphHints hints, - AF_Dimension dim, - FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) - { - AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; - AF_LatinAxis axis = & metrics->axis[dim]; - FT_Pos dist = width; - FT_Int sign = 0; - FT_Int vertical = ( dim == AF_DIMENSION_VERT ); - - FT_UNUSED( base_flags ); - - - if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || - axis->extra_light ) - return width; - - if ( dist < 0 ) - { - dist = -width; - sign = 1; - } - - if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || - ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) - { - /* smooth hinting process: very lightly quantize the stem width */ - - /* leave the widths of serifs alone */ - - if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) - goto Done_Width; - -#if 0 - else if ( ( base_flags & AF_EDGE_ROUND ) ) - { - if ( dist < 80 ) - dist = 64; - } - else if ( dist < 56 ) - dist = 56; -#endif - if ( axis->width_count > 0 ) - { - FT_Pos delta; - - - /* compare to standard width */ - if ( axis->width_count > 0 ) - { - delta = dist - axis->widths[0].cur; - - if ( delta < 0 ) - delta = -delta; - - if ( delta < 40 ) - { - dist = axis->widths[0].cur; - if ( dist < 48 ) - dist = 48; - - goto Done_Width; - } - } - - if ( dist < 3 * 64 ) - { - delta = dist & 63; - dist &= -64; - - if ( delta < 10 ) - dist += delta; - - else if ( delta < 32 ) - dist += 10; - - else if ( delta < 54 ) - dist += 54; - - else - dist += delta; - } - else - dist = ( dist + 32 ) & ~63; - } - } - else - { - /* strong hinting process: snap the stem width to integer pixels */ - FT_Pos org_dist = dist; - - - dist = af_latin2_snap_width( axis->widths, axis->width_count, dist ); - - if ( vertical ) - { - /* in the case of vertical hinting, always round */ - /* the stem heights to integer pixels */ - - if ( dist >= 64 ) - dist = ( dist + 16 ) & ~63; - else - dist = 64; - } - else - { - if ( AF_LATIN_HINTS_DO_MONO( hints ) ) - { - /* monochrome horizontal hinting: snap widths to integer pixels */ - /* with a different threshold */ - - if ( dist < 64 ) - dist = 64; - else - dist = ( dist + 32 ) & ~63; - } - else - { - /* for horizontal anti-aliased hinting, we adopt a more subtle */ - /* approach: we strengthen small stems, round stems whose size */ - /* is between 1 and 2 pixels to an integer, otherwise nothing */ - - if ( dist < 48 ) - 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; - } - } - } - - Done_Width: - if ( sign ) - dist = -dist; - - return dist; - } - - - /* align one stem edge relative to the previous stem edge */ - - static void - af_latin2_align_linked_edge( AF_GlyphHints hints, - AF_Dimension dim, - AF_Edge base_edge, - AF_Edge stem_edge ) - { - FT_Pos dist = stem_edge->opos - base_edge->opos; - - FT_Pos fitted_width = af_latin2_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); - - - stem_edge->pos = base_edge->pos + fitted_width; - - FT_TRACE5(( "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 )); - } - - - static void - af_latin2_align_serif_edge( AF_GlyphHints hints, - AF_Edge base, - AF_Edge serif ) - { - FT_UNUSED( hints ); - - serif->pos = base->pos + ( serif->opos - base->opos ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** E D G E H I N T I N G ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL_DEF( void ) - af_latin2_hint_edges( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - AF_Edge edge; - AF_Edge anchor = 0; - FT_Int has_serifs = 0; - FT_Pos anchor_drift = 0; - - - - FT_TRACE5(( "==== hinting %s edges =====\n", - dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); - - /* we begin by aligning all stems relative to the blue zone */ - /* if needed -- that's only for horizontal edges */ - - if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) - { - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Width blue; - AF_Edge edge1, edge2; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - blue = edge->blue_edge; - edge1 = NULL; - edge2 = edge->link; - - if ( blue ) - { - edge1 = edge; - } - else if ( edge2 && edge2->blue_edge ) - { - blue = edge2->blue_edge; - edge1 = edge2; - edge2 = edge; - } - - if ( !edge1 ) - continue; - - FT_TRACE5(( "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; - - if ( edge2 && !edge2->blue_edge ) - { - af_latin2_align_linked_edge( hints, dim, edge1, edge2 ); - edge2->flags |= AF_EDGE_DONE; - } - - if ( !anchor ) - { - anchor = edge; - - anchor_drift = ( anchor->pos - anchor->opos ); - if ( edge2 ) - anchor_drift = ( anchor_drift + - ( edge2->pos - edge2->opos ) ) >> 1; - } - } - } - - /* now we will align all stem edges, trying to maintain the */ - /* relative order of stems in the glyph */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Edge edge2; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - /* skip all non-stem edges */ - edge2 = edge->link; - if ( !edge2 ) - { - has_serifs++; - continue; - } - - /* now align the stem */ - - /* this should not happen, but it's better to be safe */ - if ( edge2->blue_edge ) - { - FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges )); - - af_latin2_align_linked_edge( hints, dim, edge2, edge ); - edge->flags |= AF_EDGE_DONE; - continue; - } - - if ( !anchor ) - { - FT_Pos org_len, org_center, cur_len; - FT_Pos cur_pos1, error1, error2, u_off, d_off; - - - org_len = edge2->opos - edge->opos; - cur_len = af_latin2_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); - if ( cur_len <= 64 ) - u_off = d_off = 32; - else - { - u_off = 38; - d_off = 26; - } - - if ( cur_len < 96 ) - { - org_center = edge->opos + ( org_len >> 1 ); - - cur_pos1 = FT_PIX_ROUND( org_center ); - - error1 = org_center - ( cur_pos1 - u_off ); - if ( error1 < 0 ) - error1 = -error1; - - error2 = org_center - ( cur_pos1 + d_off ); - if ( error2 < 0 ) - error2 = -error2; - - if ( error1 < error2 ) - cur_pos1 -= u_off; - else - cur_pos1 += d_off; - - edge->pos = cur_pos1 - cur_len / 2; - edge2->pos = edge->pos + cur_len; - } - else - edge->pos = FT_PIX_ROUND( edge->opos ); - - FT_TRACE5(( "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; - - af_latin2_align_linked_edge( hints, dim, edge, edge2 ); - - edge2->flags |= AF_EDGE_DONE; - - anchor_drift = ( ( anchor->pos - anchor->opos ) + - ( edge2->pos - edge2->opos ) ) >> 1; - - FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 )); - } - else - { - FT_Pos org_pos, org_len, org_center, cur_center, cur_len; - FT_Pos org_left, org_right; - - - org_pos = edge->opos + anchor_drift; - org_len = edge2->opos - edge->opos; - org_center = org_pos + ( org_len >> 1 ); - - cur_len = af_latin2_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); - - org_left = org_pos + ( ( org_len - cur_len ) >> 1 ); - org_right = org_pos + ( ( org_len + cur_len ) >> 1 ); - - FT_TRACE5(( "ALIGN: left=%.2f right=%.2f ", - org_left / 64.0, org_right / 64.0 )); - cur_center = org_center; - - if ( edge2->flags & AF_EDGE_DONE ) - { - FT_TRACE5(( "\n" )); - edge->pos = edge2->pos - cur_len; - } - else - { - /* we want to compare several displacement, and choose - * the one that increases fitness while minimizing - * distortion as well - */ - FT_Pos displacements[6], scores[6], org, fit, delta; - FT_UInt count = 0; - - /* note: don't even try to fit tiny stems */ - if ( cur_len < 32 ) - { - FT_TRACE5(( "tiny stem\n" )); - goto AlignStem; - } - - /* if the span is within a single pixel, don't touch it */ - if ( FT_PIX_FLOOR( org_left ) == FT_PIX_CEIL( org_right ) ) - { - FT_TRACE5(( "single pixel stem\n" )); - goto AlignStem; - } - - if ( cur_len <= 96 ) - { - /* we want to avoid the absolute worst case which is - * when the left and right edges of the span each represent - * about 50% of the gray. we'd better want to change this - * to 25/75%, since this is much more pleasant to the eye with - * very acceptable distortion - */ - FT_Pos frac_left = org_left & 63; - FT_Pos frac_right = org_right & 63; - - if ( frac_left >= 22 && frac_left <= 42 && - frac_right >= 22 && frac_right <= 42 ) - { - org = frac_left; - fit = ( org <= 32 ) ? 16 : 48; - delta = FT_ABS( fit - org ); - displacements[count] = fit - org; - scores[count++] = delta; - FT_TRACE5(( "dispA=%.2f (%d) ", ( fit - org ) / 64.0, delta )); - - org = frac_right; - fit = ( org <= 32 ) ? 16 : 48; - delta = FT_ABS( fit - org ); - displacements[count] = fit - org; - scores[count++] = delta; - FT_TRACE5(( "dispB=%.2f (%d) ", ( fit - org ) / 64.0, delta )); - } - } - - /* snapping the left edge to the grid */ - org = org_left; - fit = FT_PIX_ROUND( org ); - delta = FT_ABS( fit - org ); - displacements[count] = fit - org; - scores[count++] = delta; - FT_TRACE5(( "dispC=%.2f (%d) ", ( fit - org ) / 64.0, delta )); - - /* snapping the right edge to the grid */ - org = org_right; - fit = FT_PIX_ROUND( org ); - delta = FT_ABS( fit - org ); - displacements[count] = fit - org; - scores[count++] = delta; - FT_TRACE5(( "dispD=%.2f (%d) ", ( fit - org ) / 64.0, delta )); - - /* now find the best displacement */ - { - FT_Pos best_score = scores[0]; - FT_Pos best_disp = displacements[0]; - FT_UInt nn; - - for ( nn = 1; nn < count; nn++ ) - { - if ( scores[nn] < best_score ) - { - best_score = scores[nn]; - best_disp = displacements[nn]; - } - } - - cur_center = org_center + best_disp; - } - FT_TRACE5(( "\n" )); - } - - AlignStem: - edge->pos = cur_center - ( cur_len >> 1 ); - edge2->pos = edge->pos + cur_len; - - FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)" - " snapped to (%.2f) and (%.2f)," - " org_len=%.2f cur_len=%.2f\n", - edge-edges, edge->opos / 64.0, - edge2-edges, edge2->opos / 64.0, - edge->pos / 64.0, edge2->pos / 64.0, - org_len / 64.0, cur_len / 64.0 )); - - edge->flags |= AF_EDGE_DONE; - edge2->flags |= AF_EDGE_DONE; - - if ( edge > edges && edge->pos < edge[-1].pos ) - { - FT_TRACE5(( "BOUND: %d (pos=%.2f) to (%.2f)\n", - edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); - edge->pos = edge[-1].pos; - } - } - } - - /* make sure that lowercase m's maintain their symmetry */ - - /* In general, lowercase m's have six vertical edges if they are sans */ - /* serif, or twelve if they are with serifs. This implementation is */ - /* based on that assumption, and seems to work very well with most */ - /* faces. However, if for a certain face this assumption is not */ - /* true, the m is just rendered like before. In addition, any stem */ - /* correction will only be applied to symmetrical glyphs (even if the */ - /* glyph is not an m), so the potential for unwanted distortion is */ - /* relatively low. */ - - /* We don't handle horizontal edges since we can't easily assure that */ - /* the third (lowest) stem aligns with the base line; it might end up */ - /* one pixel higher or lower. */ - -#if 0 - { - FT_Int n_edges = edge_limit - edges; - - - if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) - { - AF_Edge edge1, edge2, edge3; - FT_Pos dist1, dist2, span, delta; - - - if ( n_edges == 6 ) - { - edge1 = edges; - edge2 = edges + 2; - edge3 = edges + 4; - } - else - { - edge1 = edges + 1; - edge2 = edges + 5; - edge3 = edges + 9; - } - - dist1 = edge2->opos - edge1->opos; - dist2 = edge3->opos - edge2->opos; - - span = dist1 - dist2; - if ( span < 0 ) - span = -span; - - if ( span < 8 ) - { - delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); - edge3->pos -= delta; - if ( edge3->link ) - edge3->link->pos -= delta; - - /* move the serifs along with the stem */ - if ( n_edges == 12 ) - { - ( edges + 8 )->pos -= delta; - ( edges + 11 )->pos -= delta; - } - - edge3->flags |= AF_EDGE_DONE; - if ( edge3->link ) - edge3->link->flags |= AF_EDGE_DONE; - } - } - } -#endif - - if ( has_serifs || !anchor ) - { - /* - * now hint the remaining edges (serifs and single) in order - * to complete our processing - */ - 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_latin2_align_serif_edge( hints, edge->serif, edge ); - FT_TRACE5(( "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 ) - { - FT_TRACE5(( "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 - { - 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 ) - { - if ( after->opos == before->opos ) - edge->pos = before->pos; - else - edge->pos = before->pos + - FT_MulDiv( edge->opos - before->opos, - after->pos - before->pos, - after->opos - before->opos ); - FT_TRACE5(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)" - " from %d (opos=%.2f)\n", - edge-edges, edge->opos / 64.0, edge->pos / 64.0, - before - edges, before->opos / 64.0 )); - } - else - { - edge->pos = anchor->pos + - ( ( edge->opos - anchor->opos + 16 ) & ~31 ); - - FT_TRACE5(( "SERIF_LINK2: edge %d (opos=%.2f)" - " snapped to (%.2f)\n", - edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); - } - } - - edge->flags |= AF_EDGE_DONE; - - if ( edge > edges && edge->pos < edge[-1].pos ) - edge->pos = edge[-1].pos; - - if ( edge + 1 < edge_limit && - edge[1].flags & AF_EDGE_DONE && - edge->pos > edge[1].pos ) - edge->pos = edge[1].pos; - } - } - } - - - static FT_Error - af_latin2_hints_apply( AF_GlyphHints hints, - FT_Outline* outline, - AF_LatinMetrics metrics ) - { - FT_Error error; - int dim; - - - error = af_glyph_hints_reload( hints, outline ); - if ( error ) - goto Exit; - - /* analyze glyph outline */ -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || - AF_HINTS_DO_HORIZONTAL( hints ) ) -#else - if ( AF_HINTS_DO_HORIZONTAL( hints ) ) -#endif - { - error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ ); - if ( error ) - goto Exit; - } - - if ( AF_HINTS_DO_VERTICAL( hints ) ) - { - error = af_latin2_hints_detect_features( hints, AF_DIMENSION_VERT ); - if ( error ) - goto Exit; - - af_latin2_hints_compute_blue_edges( hints, metrics ); - } - - /* grid-fit the outline */ - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) ) - { - AF_WarperRec warper; - FT_Fixed scale; - FT_Pos delta; - - - af_warper_compute( &warper, hints, dim, &scale, &delta ); - af_glyph_hints_scale_dim( hints, dim, scale, delta ); - continue; - } -#endif - - if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || - ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) - { - af_latin2_hint_edges( hints, (AF_Dimension)dim ); - af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim ); - af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); - af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); - } - } - af_glyph_hints_save( hints, outline ); - - Exit: - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N S C R I P T C L A S S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - static const AF_Script_UniRangeRec af_latin2_uniranges[] = - { - AF_UNIRANGE_REC( 32UL, 127UL ), /* TODO: Add new Unicode ranges here! */ - AF_UNIRANGE_REC( 160UL, 255UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_latin2_script_class, - AF_SCRIPT_LATIN2, - af_latin2_uniranges, - 'o', - - sizeof ( AF_LatinMetricsRec ), - - (AF_Script_InitMetricsFunc) af_latin2_metrics_init, - (AF_Script_ScaleMetricsFunc)af_latin2_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, - - (AF_Script_InitHintsFunc) af_latin2_hints_init, - (AF_Script_ApplyHintsFunc) af_latin2_hints_apply - ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/aflatin2.h b/drivers/freetype/freetype/src/autofit/aflatin2.h deleted file mode 100644 index cbfa395522..0000000000 --- a/drivers/freetype/freetype/src/autofit/aflatin2.h +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************************/ -/* */ -/* aflatin2.h */ -/* */ -/* Auto-fitter hinting routines for latin script (specification). */ -/* */ -/* Copyright 2003-2007, 2012 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 __AFLATIN2_H__ -#define __AFLATIN2_H__ - -#include "afhints.h" - - -FT_BEGIN_HEADER - - - /* the latin-specific script class */ - - AF_DECLARE_SCRIPT_CLASS( af_latin2_script_class ) - -/* */ - -FT_END_HEADER - -#endif /* __AFLATIN_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afloader.c b/drivers/freetype/freetype/src/autofit/afloader.c deleted file mode 100644 index 17a6fb7c3b..0000000000 --- a/drivers/freetype/freetype/src/autofit/afloader.c +++ /dev/null @@ -1,561 +0,0 @@ -/***************************************************************************/ -/* */ -/* afloader.c */ -/* */ -/* Auto-fitter glyph loading routines (body). */ -/* */ -/* Copyright 2003-2009, 2011-2013 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 "afglobal.h" -#include "afloader.h" -#include "afhints.h" -#include "aferrors.h" -#include "afmodule.h" - - - /* Initialize glyph loader. */ - - FT_LOCAL_DEF( FT_Error ) - af_loader_init( AF_Module module ) - { - AF_Loader loader = module->loader; - FT_Memory memory = module->root.library->memory; - - - FT_ZERO( loader ); - - af_glyph_hints_init( &loader->hints, memory ); -#ifdef FT_DEBUG_AUTOFIT - _af_debug_hints = &loader->hints; -#endif - return FT_GlyphLoader_New( memory, &loader->gloader ); - } - - - /* Reset glyph loader and compute globals if necessary. */ - - FT_LOCAL_DEF( FT_Error ) - af_loader_reset( AF_Module module, - FT_Face face ) - { - FT_Error error = FT_Err_Ok; - AF_Loader loader = module->loader; - - - loader->face = face; - loader->globals = (AF_FaceGlobals)face->autohint.data; - - FT_GlyphLoader_Rewind( loader->gloader ); - - if ( loader->globals == NULL ) - { - error = af_face_globals_new( face, &loader->globals, module ); - if ( !error ) - { - face->autohint.data = - (FT_Pointer)loader->globals; - face->autohint.finalizer = - (FT_Generic_Finalizer)af_face_globals_free; - } - } - - return error; - } - - - /* Finalize glyph loader. */ - - FT_LOCAL_DEF( void ) - af_loader_done( AF_Module module ) - { - AF_Loader loader = module->loader; - - - af_glyph_hints_done( &loader->hints ); - - loader->face = NULL; - loader->globals = NULL; - -#ifdef FT_DEBUG_AUTOFIT - _af_debug_hints = NULL; -#endif - FT_GlyphLoader_Done( loader->gloader ); - loader->gloader = NULL; - } - - - /* Load a single glyph component. This routine calls itself */ - /* recursively, if necessary, and does the main work of */ - /* `af_loader_load_glyph.' */ - - static FT_Error - af_loader_load_g( AF_Loader loader, - AF_Scaler scaler, - FT_UInt glyph_index, - FT_Int32 load_flags, - FT_UInt depth ) - { - FT_Error error; - FT_Face face = loader->face; - FT_GlyphLoader gloader = loader->gloader; - AF_ScriptMetrics metrics = loader->metrics; - AF_GlyphHints hints = &loader->hints; - FT_GlyphSlot slot = face->glyph; - FT_Slot_Internal internal = slot->internal; - FT_Int32 flags; - - - flags = load_flags | FT_LOAD_LINEAR_DESIGN; - error = FT_Load_Glyph( face, glyph_index, flags ); - if ( error ) - goto Exit; - - loader->transformed = internal->glyph_transformed; - if ( loader->transformed ) - { - FT_Matrix inverse; - - - loader->trans_matrix = internal->glyph_matrix; - loader->trans_delta = internal->glyph_delta; - - inverse = loader->trans_matrix; - FT_Matrix_Invert( &inverse ); - FT_Vector_Transform( &loader->trans_delta, &inverse ); - } - - switch ( slot->format ) - { - case FT_GLYPH_FORMAT_OUTLINE: - /* translate the loaded glyph when an internal transform is needed */ - if ( loader->transformed ) - FT_Outline_Translate( &slot->outline, - loader->trans_delta.x, - loader->trans_delta.y ); - - /* copy the outline points in the loader's current */ - /* extra points which are used to keep original glyph coordinates */ - error = FT_GLYPHLOADER_CHECK_POINTS( gloader, - slot->outline.n_points + 4, - slot->outline.n_contours ); - if ( error ) - goto Exit; - - FT_ARRAY_COPY( gloader->current.outline.points, - slot->outline.points, - slot->outline.n_points ); - - FT_ARRAY_COPY( gloader->current.outline.contours, - slot->outline.contours, - slot->outline.n_contours ); - - FT_ARRAY_COPY( gloader->current.outline.tags, - slot->outline.tags, - slot->outline.n_points ); - - gloader->current.outline.n_points = slot->outline.n_points; - gloader->current.outline.n_contours = slot->outline.n_contours; - - /* compute original horizontal phantom points (and ignore */ - /* vertical ones) */ - loader->pp1.x = hints->x_delta; - loader->pp1.y = hints->y_delta; - loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, - hints->x_scale ) + hints->x_delta; - loader->pp2.y = hints->y_delta; - - /* be sure to check for spacing glyphs */ - if ( slot->outline.n_points == 0 ) - goto Hint_Metrics; - - /* now load the slot image into the auto-outline and run the */ - /* automatic hinting process */ - if ( metrics->clazz->script_hints_apply ) - metrics->clazz->script_hints_apply( hints, - &gloader->current.outline, - metrics ); - - /* we now need to adjust the metrics according to the change in */ - /* width/positioning that occurred during the hinting process */ - if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) - { - FT_Pos old_rsb, old_lsb, new_lsb; - FT_Pos pp1x_uh, pp2x_uh; - AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; - AF_Edge edge1 = axis->edges; /* leftmost edge */ - AF_Edge edge2 = edge1 + - axis->num_edges - 1; /* rightmost edge */ - - - if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) - { - old_rsb = loader->pp2.x - edge2->opos; - old_lsb = edge1->opos; - new_lsb = edge1->pos; - - /* remember unhinted values to later account */ - /* for rounding errors */ - - pp1x_uh = new_lsb - old_lsb; - pp2x_uh = edge2->pos + old_rsb; - - /* prefer too much space over too little space */ - /* for very small sizes */ - - if ( old_lsb < 24 ) - pp1x_uh -= 8; - - if ( old_rsb < 24 ) - pp2x_uh += 8; - - loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); - loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); - - if ( loader->pp1.x >= new_lsb && old_lsb > 0 ) - loader->pp1.x -= 64; - - if ( loader->pp2.x <= edge2->pos && old_rsb > 0 ) - loader->pp2.x += 64; - - slot->lsb_delta = loader->pp1.x - pp1x_uh; - slot->rsb_delta = loader->pp2.x - pp2x_uh; - } - else - { - FT_Pos pp1x = loader->pp1.x; - FT_Pos pp2x = loader->pp2.x; - - - loader->pp1.x = FT_PIX_ROUND( pp1x ); - loader->pp2.x = FT_PIX_ROUND( pp2x ); - - slot->lsb_delta = loader->pp1.x - pp1x; - slot->rsb_delta = loader->pp2.x - pp2x; - } - } - else - { - FT_Pos pp1x = loader->pp1.x; - FT_Pos pp2x = loader->pp2.x; - - - loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); - loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); - - slot->lsb_delta = loader->pp1.x - pp1x; - slot->rsb_delta = loader->pp2.x - pp2x; - } - - /* good, we simply add the glyph to our loader's base */ - FT_GlyphLoader_Add( gloader ); - break; - - case FT_GLYPH_FORMAT_COMPOSITE: - { - FT_UInt nn, num_subglyphs = slot->num_subglyphs; - FT_UInt num_base_subgs, start_point; - FT_SubGlyph subglyph; - - - start_point = gloader->base.outline.n_points; - - /* first of all, copy the subglyph descriptors in the glyph loader */ - error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs ); - if ( error ) - goto Exit; - - FT_ARRAY_COPY( gloader->current.subglyphs, - slot->subglyphs, - num_subglyphs ); - - gloader->current.num_subglyphs = num_subglyphs; - num_base_subgs = gloader->base.num_subglyphs; - - /* now read each subglyph independently */ - for ( nn = 0; nn < num_subglyphs; nn++ ) - { - FT_Vector pp1, pp2; - FT_Pos x, y; - FT_UInt num_points, num_new_points, num_base_points; - - - /* gloader.current.subglyphs can change during glyph loading due */ - /* to re-allocation -- we must recompute the current subglyph on */ - /* each iteration */ - subglyph = gloader->base.subglyphs + num_base_subgs + nn; - - pp1 = loader->pp1; - pp2 = loader->pp2; - - num_base_points = gloader->base.outline.n_points; - - error = af_loader_load_g( loader, scaler, subglyph->index, - load_flags, depth + 1 ); - if ( error ) - goto Exit; - - /* recompute subglyph pointer */ - subglyph = gloader->base.subglyphs + num_base_subgs + nn; - - if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) - { - pp1 = loader->pp1; - pp2 = loader->pp2; - } - else - { - loader->pp1 = pp1; - loader->pp2 = pp2; - } - - num_points = gloader->base.outline.n_points; - num_new_points = num_points - num_base_points; - - /* now perform the transformation required for this subglyph */ - - if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | - FT_SUBGLYPH_FLAG_XY_SCALE | - FT_SUBGLYPH_FLAG_2X2 ) ) - { - FT_Vector* cur = gloader->base.outline.points + - num_base_points; - FT_Vector* limit = cur + num_new_points; - - - for ( ; cur < limit; cur++ ) - FT_Vector_Transform( cur, &subglyph->transform ); - } - - /* apply offset */ - - if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) - { - FT_Int k = subglyph->arg1; - FT_UInt l = subglyph->arg2; - FT_Vector* p1; - FT_Vector* p2; - - - if ( start_point + k >= num_base_points || - l >= (FT_UInt)num_new_points ) - { - error = FT_THROW( Invalid_Composite ); - goto Exit; - } - - l += num_base_points; - - /* for now, only use the current point coordinates; */ - /* we eventually may consider another approach */ - p1 = gloader->base.outline.points + start_point + k; - p2 = gloader->base.outline.points + start_point + l; - - x = p1->x - p2->x; - y = p1->y - p2->y; - } - else - { - x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; - y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; - - x = FT_PIX_ROUND( x ); - y = FT_PIX_ROUND( y ); - } - - { - FT_Outline dummy = gloader->base.outline; - - - dummy.points += num_base_points; - dummy.n_points = (short)num_new_points; - - FT_Outline_Translate( &dummy, x, y ); - } - } - } - break; - - default: - /* we don't support other formats (yet?) */ - error = FT_THROW( Unimplemented_Feature ); - } - - Hint_Metrics: - if ( depth == 0 ) - { - FT_BBox bbox; - FT_Vector vvector; - - - vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; - vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; - vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale ); - vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale ); - - /* transform the hinted outline if needed */ - if ( loader->transformed ) - { - FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); - FT_Vector_Transform( &vvector, &loader->trans_matrix ); - } -#if 1 - /* we must translate our final outline by -pp1.x and compute */ - /* the new metrics */ - if ( loader->pp1.x ) - FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); -#endif - FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); - - bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); - bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); - bbox.xMax = FT_PIX_CEIL( bbox.xMax ); - bbox.yMax = FT_PIX_CEIL( bbox.yMax ); - - slot->metrics.width = bbox.xMax - bbox.xMin; - slot->metrics.height = bbox.yMax - bbox.yMin; - slot->metrics.horiBearingX = bbox.xMin; - slot->metrics.horiBearingY = bbox.yMax; - - slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x ); - slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); - - /* for mono-width fonts (like Andale, Courier, etc.) we need */ - /* to keep the original rounded advance width; ditto for */ - /* digits if all have the same advance width */ -#if 0 - if ( !FT_IS_FIXED_WIDTH( slot->face ) ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - else - slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, - x_scale ); -#else - if ( scaler->render_mode != FT_RENDER_MODE_LIGHT && - ( FT_IS_FIXED_WIDTH( slot->face ) || - ( af_face_globals_is_digit( loader->globals, glyph_index ) && - metrics->digits_have_same_width ) ) ) - { - slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, - metrics->scaler.x_scale ); - - /* Set delta values to 0. Otherwise code that uses them is */ - /* going to ruin the fixed advance width. */ - slot->lsb_delta = 0; - slot->rsb_delta = 0; - } - else - { - /* non-spacing glyphs must stay as-is */ - if ( slot->metrics.horiAdvance ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - } -#endif - - slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, - metrics->scaler.y_scale ); - - slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); - slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); - - /* now copy outline into glyph slot */ - FT_GlyphLoader_Rewind( internal->loader ); - error = FT_GlyphLoader_CopyPoints( internal->loader, gloader ); - if ( error ) - goto Exit; - - /* reassign all outline fields except flags to protect them */ - slot->outline.n_contours = internal->loader->base.outline.n_contours; - slot->outline.n_points = internal->loader->base.outline.n_points; - slot->outline.points = internal->loader->base.outline.points; - slot->outline.tags = internal->loader->base.outline.tags; - slot->outline.contours = internal->loader->base.outline.contours; - - slot->format = FT_GLYPH_FORMAT_OUTLINE; - } - - Exit: - return error; - } - - - /* Load a glyph. */ - - FT_LOCAL_DEF( FT_Error ) - af_loader_load_glyph( AF_Module module, - FT_Face face, - FT_UInt gindex, - FT_Int32 load_flags ) - { - FT_Error error; - FT_Size size = face->size; - AF_Loader loader = module->loader; - AF_ScalerRec scaler; - - - if ( !size ) - return FT_THROW( Invalid_Argument ); - - FT_ZERO( &scaler ); - - scaler.face = face; - scaler.x_scale = size->metrics.x_scale; - scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ - scaler.y_scale = size->metrics.y_scale; - scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ - - scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); - scaler.flags = 0; /* XXX: fix this */ - - error = af_loader_reset( module, face ); - if ( !error ) - { - AF_ScriptMetrics metrics; - FT_UInt options = 0; - - -#ifdef FT_OPTION_AUTOFIT2 - /* XXX: undocumented hook to activate the latin2 hinter */ - if ( load_flags & ( 1UL << 20 ) ) - options = 2; -#endif - - error = af_face_globals_get_metrics( loader->globals, gindex, - options, &metrics ); - if ( !error ) - { - loader->metrics = metrics; - - if ( metrics->clazz->script_metrics_scale ) - metrics->clazz->script_metrics_scale( metrics, &scaler ); - else - metrics->scaler = scaler; - - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; - load_flags &= ~FT_LOAD_RENDER; - - if ( metrics->clazz->script_hints_init ) - { - error = metrics->clazz->script_hints_init( &loader->hints, - metrics ); - if ( error ) - goto Exit; - } - - error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); - } - } - Exit: - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afloader.h b/drivers/freetype/freetype/src/autofit/afloader.h deleted file mode 100644 index 1f34d17cce..0000000000 --- a/drivers/freetype/freetype/src/autofit/afloader.h +++ /dev/null @@ -1,85 +0,0 @@ -/***************************************************************************/ -/* */ -/* afloader.h */ -/* */ -/* Auto-fitter glyph loading routines (specification). */ -/* */ -/* Copyright 2003-2005, 2011-2012 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 __AFLOADER_H__ -#define __AFLOADER_H__ - -#include "afhints.h" -#include "afglobal.h" - - -FT_BEGIN_HEADER - - typedef struct AF_ModuleRec_* AF_Module; - - /* - * The autofitter module's (global) data structure to communicate with - * actual fonts. If necessary, `local' data like the current face, the - * current face's auto-hint data, or the current glyph's parameters - * relevant to auto-hinting are `swapped in'. Cf. functions like - * `af_loader_reset' and `af_loader_load_g'. - */ - - typedef struct AF_LoaderRec_ - { - /* current face data */ - FT_Face face; - AF_FaceGlobals globals; - - /* current glyph data */ - FT_GlyphLoader gloader; - AF_GlyphHintsRec hints; - AF_ScriptMetrics metrics; - FT_Bool transformed; - FT_Matrix trans_matrix; - FT_Vector trans_delta; - FT_Vector pp1; - FT_Vector pp2; - /* we don't handle vertical phantom points */ - - } AF_LoaderRec, *AF_Loader; - - - FT_LOCAL( FT_Error ) - af_loader_init( AF_Module module ); - - - FT_LOCAL( FT_Error ) - af_loader_reset( AF_Module module, - FT_Face face ); - - - FT_LOCAL( void ) - af_loader_done( AF_Module module ); - - - FT_LOCAL( FT_Error ) - af_loader_load_glyph( AF_Module module, - FT_Face face, - FT_UInt gindex, - FT_Int32 load_flags ); - -/* */ - - -FT_END_HEADER - -#endif /* __AFLOADER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afmodule.c b/drivers/freetype/freetype/src/autofit/afmodule.c deleted file mode 100644 index b1bb5ee0ed..0000000000 --- a/drivers/freetype/freetype/src/autofit/afmodule.c +++ /dev/null @@ -1,264 +0,0 @@ -/***************************************************************************/ -/* */ -/* afmodule.c */ -/* */ -/* Auto-fitter module implementation (body). */ -/* */ -/* Copyright 2003-2006, 2009, 2011-2013 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 "afglobal.h" -#include "afmodule.h" -#include "afloader.h" -#include "aferrors.h" -#include "afpic.h" - -#ifdef FT_DEBUG_AUTOFIT - 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 -#include FT_INTERNAL_DEBUG_H -#include FT_AUTOHINTER_H -#include FT_SERVICE_PROPERTIES_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_afmodule - - - FT_Error - af_property_get_face_globals( FT_Face face, - AF_FaceGlobals* aglobals, - AF_Module module ) - { - FT_Error error = FT_Err_Ok; - AF_FaceGlobals globals; - - - if ( !face ) - return FT_THROW( Invalid_Argument ); - - globals = (AF_FaceGlobals)face->autohint.data; - if ( !globals ) - { - /* trigger computation of the global script data */ - /* in case it hasn't been done yet */ - error = af_face_globals_new( face, &globals, module ); - if ( !error ) - { - face->autohint.data = - (FT_Pointer)globals; - face->autohint.finalizer = - (FT_Generic_Finalizer)af_face_globals_free; - } - } - - if ( !error ) - *aglobals = globals; - - return error; - } - - - FT_Error - af_property_set( FT_Module ft_module, - const char* property_name, - const void* value ) - { - FT_Error error = FT_Err_Ok; - AF_Module module = (AF_Module)ft_module; - - - if ( !ft_strcmp( property_name, "fallback-script" ) ) - { - FT_UInt* fallback_script = (FT_UInt*)value; - - - module->fallback_script = *fallback_script; - - return error; - } - else if ( !ft_strcmp( property_name, "increase-x-height" ) ) - { - FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; - AF_FaceGlobals globals; - - - error = af_property_get_face_globals( prop->face, &globals, module ); - if ( !error ) - globals->increase_x_height = prop->limit; - - return error; - } - - FT_TRACE0(( "af_property_set: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - FT_Error - af_property_get( FT_Module ft_module, - const char* property_name, - void* value ) - { - FT_Error error = FT_Err_Ok; - AF_Module module = (AF_Module)ft_module; - FT_UInt fallback_script = module->fallback_script; - - - if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) - { - FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value; - AF_FaceGlobals globals; - - - error = af_property_get_face_globals( prop->face, &globals, module ); - if ( !error ) - prop->map = globals->glyph_scripts; - - return error; - } - else if ( !ft_strcmp( property_name, "fallback-script" ) ) - { - FT_UInt* val = (FT_UInt*)value; - - - *val = fallback_script; - - return error; - } - else if ( !ft_strcmp( property_name, "increase-x-height" ) ) - { - FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; - AF_FaceGlobals globals; - - - error = af_property_get_face_globals( prop->face, &globals, module ); - if ( !error ) - prop->limit = globals->increase_x_height; - - return error; - } - - - FT_TRACE0(( "af_property_get: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - FT_DEFINE_SERVICE_PROPERTIESREC( - af_service_properties, - (FT_Properties_SetFunc)af_property_set, - (FT_Properties_GetFunc)af_property_get ) - - - FT_DEFINE_SERVICEDESCREC1( - af_services, - FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) - - - FT_CALLBACK_DEF( FT_Module_Interface ) - af_get_interface( FT_Module module, - const char* module_interface ) - { - /* AF_SERVICES_GET derefers `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - FT_Library library; - - - if ( !module ) - return NULL; - library = module->library; - if ( !library ) - return NULL; -#else - FT_UNUSED( module ); -#endif - - return ft_service_list_lookup( AF_SERVICES_GET, module_interface ); - } - - - FT_CALLBACK_DEF( FT_Error ) - af_autofitter_init( FT_Module ft_module ) /* AF_Module */ - { - AF_Module module = (AF_Module)ft_module; - - - module->fallback_script = AF_SCRIPT_FALLBACK; - - return af_loader_init( module ); - } - - - FT_CALLBACK_DEF( void ) - af_autofitter_done( FT_Module ft_module ) /* AF_Module */ - { - AF_Module module = (AF_Module)ft_module; - - - af_loader_done( module ); - } - - - FT_CALLBACK_DEF( FT_Error ) - af_autofitter_load_glyph( AF_Module module, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - FT_UNUSED( size ); - - return af_loader_load_glyph( module, slot->face, - glyph_index, load_flags ); - } - - - FT_DEFINE_AUTOHINTER_INTERFACE( - af_autofitter_interface, - NULL, /* reset_face */ - NULL, /* get_global_hints */ - NULL, /* done_global_hints */ - (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph ) /* load_glyph */ - - - FT_DEFINE_MODULE( - autofit_module_class, - - FT_MODULE_HINTER, - sizeof ( AF_ModuleRec ), - - "autofitter", - 0x10000L, /* version 1.0 of the autofitter */ - 0x20000L, /* requires FreeType 2.0 or above */ - - (const void*)&AF_INTERFACE_GET, - - (FT_Module_Constructor)af_autofitter_init, - (FT_Module_Destructor) af_autofitter_done, - (FT_Module_Requester) af_get_interface ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afmodule.h b/drivers/freetype/freetype/src/autofit/afmodule.h deleted file mode 100644 index c4e8f8f66a..0000000000 --- a/drivers/freetype/freetype/src/autofit/afmodule.h +++ /dev/null @@ -1,58 +0,0 @@ -/***************************************************************************/ -/* */ -/* afmodule.h */ -/* */ -/* Auto-fitter module implementation (specification). */ -/* */ -/* Copyright 2003, 2004, 2005 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __AFMODULE_H__ -#define __AFMODULE_H__ - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_MODULE_H - -#include "afloader.h" - - -FT_BEGIN_HEADER - - - /* - * This is the `extended' FT_Module structure which holds the - * autofitter's global data. Right before hinting a glyph, the data - * specific to the glyph's face (blue zones, stem widths, etc.) are - * loaded into `loader' (see function `af_loader_reset'). - */ - - typedef struct AF_ModuleRec_ - { - FT_ModuleRec root; - - FT_UInt fallback_script; - - AF_LoaderRec loader[1]; - - } AF_ModuleRec; - - -FT_DECLARE_MODULE(autofit_module_class) - - -FT_END_HEADER - -#endif /* __AFMODULE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afpic.c b/drivers/freetype/freetype/src/autofit/afpic.c deleted file mode 100644 index 45e1448c08..0000000000 --- a/drivers/freetype/freetype/src/autofit/afpic.c +++ /dev/null @@ -1,137 +0,0 @@ -/***************************************************************************/ -/* */ -/* afpic.c */ -/* */ -/* The FreeType position independent code services for autofit module. */ -/* */ -/* Copyright 2009-2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "afpic.h" -#include "aferrors.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from afmodule.c */ - FT_Error - FT_Create_Class_af_services( FT_Library library, - FT_ServiceDescRec** output_class ); - - void - FT_Destroy_Class_af_services( FT_Library library, - FT_ServiceDescRec* clazz ); - - void - FT_Init_Class_af_service_properties( FT_Service_PropertiesRec* clazz ); - - void FT_Init_Class_af_autofitter_interface( - FT_Library library, - FT_AutoHinter_InterfaceRec* clazz ); - - - /* forward declaration of PIC init functions from script classes */ -#include "aflatin.h" -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.h" -#endif -#include "afcjk.h" -#include "afdummy.h" -#include "afindic.h" - - - void - autofit_module_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->autofit ) - { - AFModulePIC* container = (AFModulePIC*)pic_container->autofit; - - - if ( container->af_services ) - FT_Destroy_Class_af_services( library, - container->af_services ); - container->af_services = NULL; - - FT_FREE( container ); - pic_container->autofit = NULL; - } - } - - - FT_Error - autofit_module_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_UInt ss; - FT_Error error = FT_Err_Ok; - AFModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC ( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->autofit = container; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - error = FT_Create_Class_af_services( library, - &container->af_services ); - if ( error ) - goto Exit; - - FT_Init_Class_af_service_properties( &container->af_service_properties ); - - for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) - { - container->af_script_classes[ss] = - &container->af_script_classes_rec[ss]; - } - container->af_script_classes[AF_SCRIPT_CLASSES_COUNT - 1] = NULL; - - /* add call to initialization function when you add new scripts */ - ss = 0; - FT_Init_Class_af_dummy_script_class( - &container->af_script_classes_rec[ss++] ); -#ifdef FT_OPTION_AUTOFIT2 - FT_Init_Class_af_latin2_script_class( - &container->af_script_classes_rec[ss++] ); -#endif - FT_Init_Class_af_latin_script_class( - &container->af_script_classes_rec[ss++] ); - FT_Init_Class_af_cjk_script_class( - &container->af_script_classes_rec[ss++] ); - FT_Init_Class_af_indic_script_class( - &container->af_script_classes_rec[ss++] ); - - FT_Init_Class_af_autofitter_interface( - library, &container->af_autofitter_interface ); - - Exit: - if ( error ) - autofit_module_class_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afpic.h b/drivers/freetype/freetype/src/autofit/afpic.h deleted file mode 100644 index 0acf803894..0000000000 --- a/drivers/freetype/freetype/src/autofit/afpic.h +++ /dev/null @@ -1,96 +0,0 @@ -/***************************************************************************/ -/* */ -/* afpic.h */ -/* */ -/* The FreeType position independent code services for autofit module. */ -/* */ -/* Copyright 2009, 2011-2012 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __AFPIC_H__ -#define __AFPIC_H__ - - -FT_BEGIN_HEADER - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define AF_SERVICES_GET af_services -#define AF_SERVICE_PROPERTIES_GET af_service_properties - -#define AF_SCRIPT_CLASSES_GET af_script_classes -#define AF_INTERFACE_GET af_autofitter_interface - -#else /* FT_CONFIG_OPTION_PIC */ - - /* some include files required for members of AFModulePIC */ -#include FT_SERVICE_PROPERTIES_H - -#include "aftypes.h" - - /* increase these when you add new scripts, */ - /* and update autofit_module_class_pic_init */ -#ifdef FT_OPTION_AUTOFIT2 -#define AF_SCRIPT_CLASSES_COUNT 6 -#else -#define AF_SCRIPT_CLASSES_COUNT 5 -#endif - -#define AF_SCRIPT_CLASSES_REC_COUNT ( AF_SCRIPT_CLASSES_COUNT - 1 ) - - - typedef struct AFModulePIC_ - { - FT_ServiceDescRec* af_services; - FT_Service_PropertiesRec af_service_properties; - - AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; - AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; - FT_AutoHinter_InterfaceRec af_autofitter_interface; - - } AFModulePIC; - - -#define GET_PIC( lib ) \ - ( (AFModulePIC*)((lib)->pic_container.autofit) ) - -#define AF_SERVICES_GET \ - ( GET_PIC( library )->af_services ) -#define AF_SERVICE_PROPERTIES_GET \ - ( GET_PIC( library )->af_service_properties ) - -#define AF_SCRIPT_CLASSES_GET \ - ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_script_classes ) -#define AF_INTERFACE_GET \ - ( GET_PIC( library )->af_autofitter_interface ) - - - /* see afpic.c for the implementation */ - void - autofit_module_class_pic_free( FT_Library library ); - - FT_Error - autofit_module_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __AFPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/aftypes.h b/drivers/freetype/freetype/src/autofit/aftypes.h deleted file mode 100644 index 9acd7ad6d2..0000000000 --- a/drivers/freetype/freetype/src/autofit/aftypes.h +++ /dev/null @@ -1,378 +0,0 @@ -/***************************************************************************/ -/* */ -/* aftypes.h */ -/* */ -/* Auto-fitter types (specification only). */ -/* */ -/* Copyright 2003-2009, 2011-2012 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. */ -/* */ -/***************************************************************************/ - - - /************************************************************************* - * - * The auto-fitter is a complete rewrite of the old auto-hinter. - * Its main feature is the ability to differentiate between different - * scripts in order to apply language-specific rules. - * - * The code has also been compartmentized into several entities that - * should make algorithmic experimentation easier than with the old - * code. - * - * Finally, we get rid of the Catharon license, since this code is - * released under the FreeType one. - * - *************************************************************************/ - - -#ifndef __AFTYPES_H__ -#define __AFTYPES_H__ - -#include <ft2build.h> - -#include FT_FREETYPE_H -#include FT_OUTLINE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** D E B U G G I N G *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#ifdef FT_DEBUG_AUTOFIT - -#include FT_CONFIG_STANDARD_LIBRARY_H - -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; - -#endif /* FT_DEBUG_AUTOFIT */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** U T I L I T Y S T U F F *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct AF_WidthRec_ - { - FT_Pos org; /* original position/width in font units */ - FT_Pos cur; /* current/scaled position/width in device sub-pixels */ - FT_Pos fit; /* current/fitted position/width in device sub-pixels */ - - } AF_WidthRec, *AF_Width; - - - FT_LOCAL( void ) - af_sort_pos( FT_UInt count, - FT_Pos* table ); - - FT_LOCAL( void ) - af_sort_and_quantize_widths( FT_UInt* count, - AF_Width widths, - FT_Pos threshold ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** A N G L E T Y P E S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * The auto-fitter doesn't need a very high angular accuracy; - * this allows us to speed up some computations considerably with a - * light Cordic algorithm (see afangles.c). - */ - - typedef FT_Int AF_Angle; - - -#define AF_ANGLE_PI 256 -#define AF_ANGLE_2PI ( AF_ANGLE_PI * 2 ) -#define AF_ANGLE_PI2 ( AF_ANGLE_PI / 2 ) -#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 ) - - -#if 0 - /* - * compute the angle of a given 2-D vector - */ - FT_LOCAL( AF_Angle ) - af_angle_atan( FT_Pos dx, - FT_Pos dy ); - - - /* - * compute `angle2 - angle1'; the result is always within - * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] - */ - FT_LOCAL( AF_Angle ) - af_angle_diff( AF_Angle angle1, - AF_Angle angle2 ); -#endif /* 0 */ - - -#define AF_ANGLE_DIFF( result, angle1, angle2 ) \ - FT_BEGIN_STMNT \ - 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; \ - \ - result = _delta; \ - FT_END_STMNT - - - /* opaque handle to glyph-specific hints -- see `afhints.h' for more - * details - */ - typedef struct AF_GlyphHintsRec_* AF_GlyphHints; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** S C A L E R S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * A scaler models the target pixel device that will receive the - * auto-hinted glyph image. - */ - - typedef enum AF_ScalerFlags_ - { - AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ - AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ - AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */ - - } AF_ScalerFlags; - - - typedef struct AF_ScalerRec_ - { - FT_Face face; /* source font face */ - FT_Fixed x_scale; /* from font units to 1/64th device pixels */ - FT_Fixed y_scale; /* from font units to 1/64th device pixels */ - FT_Pos x_delta; /* in 1/64th device pixels */ - FT_Pos y_delta; /* in 1/64th device pixels */ - FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc. */ - FT_UInt32 flags; /* additional control flags, see above */ - - } AF_ScalerRec, *AF_Scaler; - - -#define AF_SCALER_EQUAL_SCALES( a, b ) \ - ( (a)->x_scale == (b)->x_scale && \ - (a)->y_scale == (b)->y_scale && \ - (a)->x_delta == (b)->x_delta && \ - (a)->y_delta == (b)->y_delta ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** S C R I P T S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * The list of known scripts. Each different script corresponds to the - * following information: - * - * - A set of Unicode ranges to test whether the face supports the - * script. - * - * - A specific global analyzer that will compute global metrics - * specific to the script. - * - * - A specific glyph analyzer that will compute segments and - * edges for each glyph covered by the script. - * - * - A specific grid-fitting algorithm that will distort the - * scaled glyph outline according to the results of the glyph - * analyzer. - * - * Note that a given analyzer and/or grid-fitting algorithm can be - * used by more than one script. - */ - - typedef enum AF_Script_ - { - AF_SCRIPT_DUMMY = 0, - AF_SCRIPT_LATIN = 1, - AF_SCRIPT_CJK = 2, - AF_SCRIPT_INDIC = 3, -#ifdef FT_OPTION_AUTOFIT2 - AF_SCRIPT_LATIN2 = 4, -#endif - - /* add new scripts here. Don't forget to update the list in */ - /* `afglobal.c'. */ - - AF_SCRIPT_MAX /* do not remove */ - - } AF_Script; - - - typedef struct AF_ScriptClassRec_ const* AF_ScriptClass; - typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; - - typedef struct AF_ScriptMetricsRec_ - { - AF_ScriptClass clazz; - AF_ScalerRec scaler; - FT_Bool digits_have_same_width; - - AF_FaceGlobals globals; /* to access properties */ - - } AF_ScriptMetricsRec, *AF_ScriptMetrics; - - - /* This function parses an FT_Face to compute global metrics for - * a specific script. - */ - typedef FT_Error - (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, - FT_Face face ); - - typedef void - (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics, - AF_Scaler scaler ); - - typedef void - (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics ); - - - typedef FT_Error - (*AF_Script_InitHintsFunc)( AF_GlyphHints hints, - AF_ScriptMetrics metrics ); - - typedef void - (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints, - FT_Outline* outline, - AF_ScriptMetrics metrics ); - - - typedef struct AF_Script_UniRangeRec_ - { - FT_UInt32 first; - FT_UInt32 last; - - } AF_Script_UniRangeRec; - -#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } - - typedef const AF_Script_UniRangeRec *AF_Script_UniRange; - - - typedef struct AF_ScriptClassRec_ - { - AF_Script script; - AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ - FT_UInt32 standard_char; /* for default width and height */ - - FT_Offset script_metrics_size; - AF_Script_InitMetricsFunc script_metrics_init; - AF_Script_ScaleMetricsFunc script_metrics_scale; - AF_Script_DoneMetricsFunc script_metrics_done; - - AF_Script_InitHintsFunc script_hints_init; - AF_Script_ApplyHintsFunc script_hints_apply; - - } AF_ScriptClassRec; - - - /* Declare and define vtables for classes */ -#ifndef FT_CONFIG_OPTION_PIC - -#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ - FT_CALLBACK_TABLE const AF_ScriptClassRec \ - script_class; - -#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \ - m_size, \ - m_init, m_scale, m_done, h_init, h_apply ) \ - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec script_class = \ - { \ - script_, \ - ranges, \ - def_char, \ - \ - m_size, \ - \ - m_init, \ - m_scale, \ - m_done, \ - \ - h_init, \ - h_apply \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ - FT_LOCAL( void ) \ - FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ); - -#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \ - m_size, \ - m_init, m_scale, m_done, h_init, h_apply ) \ - FT_LOCAL_DEF( void ) \ - FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \ - { \ - ac->script = script_; \ - ac->script_uni_ranges = ranges; \ - ac->default_char = def_char; \ - \ - ac->script_metrics_size = m_size; \ - \ - ac->script_metrics_init = m_init; \ - ac->script_metrics_scale = m_scale; \ - ac->script_metrics_done = m_done; \ - \ - ac->script_hints_init = h_init; \ - ac->script_hints_apply = h_apply; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* */ - -FT_END_HEADER - -#endif /* __AFTYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afwarp.c b/drivers/freetype/freetype/src/autofit/afwarp.c deleted file mode 100644 index 34a97ffc57..0000000000 --- a/drivers/freetype/freetype/src/autofit/afwarp.c +++ /dev/null @@ -1,374 +0,0 @@ -/***************************************************************************/ -/* */ -/* afwarp.c */ -/* */ -/* Auto-fitter warping algorithm (body). */ -/* */ -/* Copyright 2006, 2007, 2011 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. */ -/* */ -/***************************************************************************/ - - - /* - * The idea of the warping code is to slightly scale and shift a glyph - * within a single dimension so that as much of its segments are aligned - * (more or less) on the grid. To find out the optimal scaling and - * shifting value, various parameter combinations are tried and scored. - */ - -#include "afwarp.h" - -#ifdef AF_CONFIG_OPTION_USE_WARPER - - /*************************************************************************/ - /* */ - /* 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_afwarp - - - /* The weights cover the range 0/64 - 63/64 of a pixel. Obviously, */ - /* values around a half pixel (which means exactly between two grid */ - /* lines) gets the worst weight. */ -#if 1 - static const AF_WarpScore - af_warper_weights[64] = - { - 35, 32, 30, 25, 20, 15, 12, 10, 5, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30, - - -30,-30,-20,-20,-10,-10, -8, -5, -2, -1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 5, 10, 12, 15, 20, 25, 30, 32, - }; -#else - static const AF_WarpScore - af_warper_weights[64] = - { - 30, 20, 10, 5, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -1, -2, -2, -5, -5,-10,-10,-15,-20, - - -20,-15,-15,-10,-10, -5, -5, -2, -2, -1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 5, 10, 20, - }; -#endif - - - /* Score segments for a given `scale' and `delta' in the range */ - /* `xx1' to `xx2', and store the best result in `warper'. If */ - /* the new best score is equal to the old one, prefer the */ - /* value with a smaller distortion (around `base_distort'). */ - - static void - af_warper_compute_line_best( AF_Warper warper, - FT_Fixed scale, - FT_Pos delta, - FT_Pos xx1, - FT_Pos xx2, - AF_WarpScore base_distort, - AF_Segment segments, - FT_UInt num_segments ) - { - FT_Int idx_min, idx_max, idx0; - FT_UInt nn; - AF_WarpScore scores[65]; - - - for ( nn = 0; nn < 65; nn++ ) - scores[nn] = 0; - - idx0 = xx1 - warper->t1; - - /* compute minimum and maximum indices */ - { - FT_Pos xx1min = warper->x1min; - FT_Pos xx1max = warper->x1max; - FT_Pos w = xx2 - xx1; - - - if ( xx1min + w < warper->x2min ) - xx1min = warper->x2min - w; - - xx1max = warper->x1max; - if ( xx1max + w > warper->x2max ) - xx1max = warper->x2max - w; - - idx_min = xx1min - warper->t1; - idx_max = xx1max - warper->t1; - - if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 ) - { - FT_TRACE5(( "invalid indices:\n" - " min=%d max=%d, xx1=%ld xx2=%ld,\n" - " x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n", - idx_min, idx_max, xx1, xx2, - warper->x1min, warper->x1max, - warper->x2min, warper->x2max )); - return; - } - } - - for ( nn = 0; nn < num_segments; nn++ ) - { - FT_Pos len = segments[nn].max_coord - segments[nn].min_coord; - FT_Pos y0 = FT_MulFix( segments[nn].pos, scale ) + delta; - FT_Pos y = y0 + ( idx_min - idx0 ); - FT_Int idx; - - - /* score the length of the segments for the given range */ - for ( idx = idx_min; idx <= idx_max; idx++, y++ ) - scores[idx] += af_warper_weights[y & 63] * len; - } - - /* find best score */ - { - FT_Int idx; - - - for ( idx = idx_min; idx <= idx_max; idx++ ) - { - AF_WarpScore score = scores[idx]; - AF_WarpScore distort = base_distort + ( idx - idx0 ); - - - if ( score > warper->best_score || - ( score == warper->best_score && - distort < warper->best_distort ) ) - { - warper->best_score = score; - warper->best_distort = distort; - warper->best_scale = scale; - warper->best_delta = delta + ( idx - idx0 ); - } - } - } - } - - - /* Compute optimal scaling and delta values for a given glyph and */ - /* dimension. */ - - FT_LOCAL_DEF( void ) - af_warper_compute( AF_Warper warper, - AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed *a_scale, - FT_Pos *a_delta ) - { - AF_AxisHints axis; - AF_Point points; - - FT_Fixed org_scale; - FT_Pos org_delta; - - FT_UInt nn, num_points, num_segments; - FT_Int X1, X2; - FT_Int w; - - AF_WarpScore base_distort; - AF_Segment segments; - - - /* get original scaling transformation */ - if ( dim == AF_DIMENSION_VERT ) - { - org_scale = hints->y_scale; - org_delta = hints->y_delta; - } - else - { - org_scale = hints->x_scale; - org_delta = hints->x_delta; - } - - warper->best_scale = org_scale; - warper->best_delta = org_delta; - warper->best_score = INT_MIN; - warper->best_distort = 0; - - axis = &hints->axis[dim]; - segments = axis->segments; - num_segments = axis->num_segments; - points = hints->points; - num_points = hints->num_points; - - *a_scale = org_scale; - *a_delta = org_delta; - - /* get X1 and X2, minimum and maximum in original coordinates */ - if ( num_segments < 1 ) - return; - -#if 1 - X1 = X2 = points[0].fx; - for ( nn = 1; nn < num_points; nn++ ) - { - FT_Int X = points[nn].fx; - - - if ( X < X1 ) - X1 = X; - if ( X > X2 ) - X2 = X; - } -#else - X1 = X2 = segments[0].pos; - for ( nn = 1; nn < num_segments; nn++ ) - { - FT_Int X = segments[nn].pos; - - - if ( X < X1 ) - X1 = X; - if ( X > X2 ) - X2 = X; - } -#endif - - if ( X1 >= X2 ) - return; - - warper->x1 = FT_MulFix( X1, org_scale ) + org_delta; - warper->x2 = FT_MulFix( X2, org_scale ) + org_delta; - - warper->t1 = AF_WARPER_FLOOR( warper->x1 ); - warper->t2 = AF_WARPER_CEIL( warper->x2 ); - - /* examine a half pixel wide range around the maximum coordinates */ - warper->x1min = warper->x1 & ~31; - warper->x1max = warper->x1min + 32; - warper->x2min = warper->x2 & ~31; - warper->x2max = warper->x2min + 32; - - if ( warper->x1max > warper->x2 ) - warper->x1max = warper->x2; - - if ( warper->x2min < warper->x1 ) - warper->x2min = warper->x1; - - warper->w0 = warper->x2 - warper->x1; - - if ( warper->w0 <= 64 ) - { - warper->x1max = warper->x1; - warper->x2min = warper->x2; - } - - /* examine (at most) a pixel wide range around the natural width */ - warper->wmin = warper->x2min - warper->x1max; - warper->wmax = warper->x2max - warper->x1min; - -#if 1 - /* some heuristics to reduce the number of widths to be examined */ - { - int margin = 16; - - - if ( warper->w0 <= 128 ) - { - margin = 8; - if ( warper->w0 <= 96 ) - margin = 4; - } - - if ( warper->wmin < warper->w0 - margin ) - warper->wmin = warper->w0 - margin; - - if ( warper->wmax > warper->w0 + margin ) - warper->wmax = warper->w0 + margin; - } - - if ( warper->wmin < warper->w0 * 3 / 4 ) - warper->wmin = warper->w0 * 3 / 4; - - if ( warper->wmax > warper->w0 * 5 / 4 ) - warper->wmax = warper->w0 * 5 / 4; -#else - /* no scaling, just translation */ - warper->wmin = warper->wmax = warper->w0; -#endif - - for ( w = warper->wmin; w <= warper->wmax; w++ ) - { - FT_Fixed new_scale; - FT_Pos new_delta; - FT_Pos xx1, xx2; - - - /* compute min and max positions for given width, */ - /* assuring that they stay within the coordinate ranges */ - xx1 = warper->x1; - xx2 = warper->x2; - if ( w >= warper->w0 ) - { - xx1 -= w - warper->w0; - if ( xx1 < warper->x1min ) - { - xx2 += warper->x1min - xx1; - xx1 = warper->x1min; - } - } - else - { - xx1 -= w - warper->w0; - if ( xx1 > warper->x1max ) - { - xx2 -= xx1 - warper->x1max; - xx1 = warper->x1max; - } - } - - if ( xx1 < warper->x1 ) - base_distort = warper->x1 - xx1; - else - base_distort = xx1 - warper->x1; - - if ( xx2 < warper->x2 ) - base_distort += warper->x2 - xx2; - else - base_distort += xx2 - warper->x2; - - /* give base distortion a greater weight while scoring */ - base_distort *= 10; - - new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 ); - new_delta = xx1 - FT_MulFix( X1, new_scale ); - - af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2, - base_distort, - segments, num_segments ); - } - - { - FT_Fixed best_scale = warper->best_scale; - FT_Pos best_delta = warper->best_delta; - - - hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale ) - + best_delta; - hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale ) - + best_delta; - - *a_scale = best_scale; - *a_delta = best_delta; - } - } - -#else /* !AF_CONFIG_OPTION_USE_WARPER */ - - /* ANSI C doesn't like empty source files */ - typedef int _af_warp_dummy; - -#endif /* !AF_CONFIG_OPTION_USE_WARPER */ - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afwarp.h b/drivers/freetype/freetype/src/autofit/afwarp.h deleted file mode 100644 index 7343fdd5ef..0000000000 --- a/drivers/freetype/freetype/src/autofit/afwarp.h +++ /dev/null @@ -1,64 +0,0 @@ -/***************************************************************************/ -/* */ -/* afwarp.h */ -/* */ -/* Auto-fitter warping algorithm (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 __AFWARP_H__ -#define __AFWARP_H__ - -#include "afhints.h" - -FT_BEGIN_HEADER - -#define AF_WARPER_SCALE - -#define AF_WARPER_FLOOR( x ) ( (x) & ~63 ) -#define AF_WARPER_CEIL( x ) AF_WARPER_FLOOR( (x) + 63 ) - - - typedef FT_Int32 AF_WarpScore; - - typedef struct AF_WarperRec_ - { - FT_Pos x1, x2; - FT_Pos t1, t2; - FT_Pos x1min, x1max; - FT_Pos x2min, x2max; - FT_Pos w0, wmin, wmax; - - FT_Fixed best_scale; - FT_Pos best_delta; - AF_WarpScore best_score; - AF_WarpScore best_distort; - - } AF_WarperRec, *AF_Warper; - - - FT_LOCAL( void ) - af_warper_compute( AF_Warper warper, - AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed *a_scale, - FT_Fixed *a_delta ); - - -FT_END_HEADER - - -#endif /* __AFWARP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/autofit.c b/drivers/freetype/freetype/src/autofit/autofit.c deleted file mode 100644 index 3883a0a706..0000000000 --- a/drivers/freetype/freetype/src/autofit/autofit.c +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* autofit.c */ -/* */ -/* Auto-fitter module (body). */ -/* */ -/* Copyright 2003-2007, 2011 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT -#include <ft2build.h> -#include "afpic.c" -#include "afangles.c" -#include "afglobal.c" -#include "afhints.c" - -#include "afdummy.c" -#include "aflatin.c" -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.c" -#endif -#include "afcjk.c" -#include "afindic.c" - -#include "afloader.c" -#include "afmodule.c" - -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.c" -#endif - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/module.mk b/drivers/freetype/freetype/src/autofit/module.mk deleted file mode 100644 index 6ec60912ab..0000000000 --- a/drivers/freetype/freetype/src/autofit/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 auto-fitter module definition -# - - -# 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, 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. - - -FTMODULE_H_COMMANDS += AUTOFIT_MODULE - -define AUTOFIT_MODULE -$(OPEN_DRIVER) FT_Module_Class, autofit_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)autofit $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/autofit/rules.mk b/drivers/freetype/freetype/src/autofit/rules.mk deleted file mode 100644 index b76bb79ab4..0000000000 --- a/drivers/freetype/freetype/src/autofit/rules.mk +++ /dev/null @@ -1,79 +0,0 @@ -# -# FreeType 2 auto-fitter module configuration rules -# - - -# Copyright 2003, 2004, 2005, 2006, 2007, 2011 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. - - -# AUTOF driver directory -# -AUTOF_DIR := $(SRC_DIR)/autofit - - -# compilation flags for the driver -# -AUTOF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR)) - - -# AUTOF driver sources (i.e., C files) -# -AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ - $(AUTOF_DIR)/afcjk.c \ - $(AUTOF_DIR)/afdummy.c \ - $(AUTOF_DIR)/afglobal.c \ - $(AUTOF_DIR)/afhints.c \ - $(AUTOF_DIR)/afindic.c \ - $(AUTOF_DIR)/aflatin.c \ - $(AUTOF_DIR)/afloader.c \ - $(AUTOF_DIR)/afmodule.c \ - $(AUTOF_DIR)/afpic.c \ - $(AUTOF_DIR)/afwarp.c - -# AUTOF driver headers -# -AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ - $(AUTOF_DIR)/aferrors.h \ - $(AUTOF_DIR)/aftypes.h - - -# AUTOF driver object(s) -# -# AUTOF_DRV_OBJ_M is used during `multi' builds. -# AUTOF_DRV_OBJ_S is used during `single' builds. -# -AUTOF_DRV_OBJ_M := $(AUTOF_DRV_SRC:$(AUTOF_DIR)/%.c=$(OBJ_DIR)/%.$O) -AUTOF_DRV_OBJ_S := $(OBJ_DIR)/autofit.$O - -# AUTOF driver source file for single build -# -AUTOF_DRV_SRC_S := $(AUTOF_DIR)/autofit.c - - -# AUTOF driver - single object -# -$(AUTOF_DRV_OBJ_S): $(AUTOF_DRV_SRC_S) $(AUTOF_DRV_SRC) \ - $(FREETYPE_H) $(AUTOF_DRV_H) - $(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(AUTOF_DRV_SRC_S)) - - -# AUTOF driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(AUTOF_DIR)/%.c $(FREETYPE_H) $(AUTOF_DRV_H) - $(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(AUTOF_DRV_OBJ_S) -DRV_OBJS_M += $(AUTOF_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/base/Jamfile b/drivers/freetype/freetype/src/base/Jamfile deleted file mode 100644 index 832e8b8424..0000000000 --- a/drivers/freetype/freetype/src/base/Jamfile +++ /dev/null @@ -1,60 +0,0 @@ -# FreeType 2 src/base Jamfile -# -# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) base ; - - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = ftadvanc ftcalc ftdbgmem ftgloadr - ftobjs ftoutln ftrfork ftsnames - ftstream fttrigon ftutil - basepic ftpic - ; - } - else - { - _sources = ftbase ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# Add the optional/replaceable files. -# -{ - local _sources = bbox bdf bitmap debug gasp - glyph gxval init lcdfil mm - otval pfr stroke synth system - type1 winfnt xf86 patent - ; - - Library $(FT2_LIB) : ft$(_sources).c ; -} - -# Add Macintosh-specific file to the library when necessary. -# -if $(MAC) -{ - Library $(FT2_LIB) : ftmac.c ; -} -else if $(OS) = MACOSX -{ - if $(FT2_MULTI) - { - Library $(FT2_LIB) : ftmac.c ; - } -} - -# end of src/base Jamfile diff --git a/drivers/freetype/freetype/src/base/basepic.c b/drivers/freetype/freetype/src/base/basepic.c deleted file mode 100644 index 0af770ebc2..0000000000 --- a/drivers/freetype/freetype/src/base/basepic.c +++ /dev/null @@ -1,108 +0,0 @@ -/***************************************************************************/ -/* */ -/* basepic.c */ -/* */ -/* The FreeType position independent code services for base. */ -/* */ -/* Copyright 2009, 2012 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "basepic.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from ftglyph.c */ - void - FT_Init_Class_ft_outline_glyph_class( FT_Glyph_Class* clazz ); - - void - FT_Init_Class_ft_bitmap_glyph_class( FT_Glyph_Class* clazz ); - -#ifdef FT_CONFIG_OPTION_MAC_FONTS - /* forward declaration of PIC init function from ftrfork.c */ - /* (not modularized) */ - void - FT_Init_Table_raccess_guess_table( ft_raccess_guess_rec* record ); -#endif - - /* forward declaration of PIC init functions from ftinit.c */ - FT_Error - ft_create_default_module_classes( FT_Library library ); - - void - ft_destroy_default_module_classes( FT_Library library ); - - - void - ft_base_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->base ) - { - /* destroy default module classes */ - /* (in case FT_Add_Default_Modules was used) */ - ft_destroy_default_module_classes( library ); - - FT_FREE( pic_container->base ); - pic_container->base = NULL; - } - } - - - FT_Error - ft_base_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - BasePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->base = container; - - /* initialize default modules list and pointers */ - error = ft_create_default_module_classes( library ); - if ( error ) - goto Exit; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - FT_Init_Class_ft_outline_glyph_class( - &container->ft_outline_glyph_class ); - FT_Init_Class_ft_bitmap_glyph_class( - &container->ft_bitmap_glyph_class ); -#ifdef FT_CONFIG_OPTION_MAC_FONTS - FT_Init_Table_raccess_guess_table( - (ft_raccess_guess_rec*)&container->ft_raccess_guess_table ); -#endif - - Exit: - if ( error ) - ft_base_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/basepic.h b/drivers/freetype/freetype/src/base/basepic.h deleted file mode 100644 index 329d7c8fd6..0000000000 --- a/drivers/freetype/freetype/src/base/basepic.h +++ /dev/null @@ -1,90 +0,0 @@ -/***************************************************************************/ -/* */ -/* basepic.h */ -/* */ -/* The FreeType position independent code services for base. */ -/* */ -/* Copyright 2009 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __BASEPIC_H__ -#define __BASEPIC_H__ - - -FT_BEGIN_HEADER - -#include FT_INTERNAL_PIC_H - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class -#define FT_BITMAP_GLYPH_CLASS_GET &ft_bitmap_glyph_class -#define FT_DEFAULT_MODULES_GET ft_default_modules - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#define FT_RACCESS_GUESS_TABLE_GET ft_raccess_guess_table -#endif - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_GLYPH_H - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#include FT_INTERNAL_RFORK_H -#endif - - - typedef struct BasePIC_ - { - FT_Module_Class** default_module_classes; - FT_Glyph_Class ft_outline_glyph_class; - FT_Glyph_Class ft_bitmap_glyph_class; - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK - ft_raccess_guess_rec ft_raccess_guess_table[FT_RACCESS_N_RULES]; -#endif - - } BasePIC; - - -#define GET_PIC( lib ) ( (BasePIC*)( (lib)->pic_container.base ) ) - -#define FT_OUTLINE_GLYPH_CLASS_GET \ - ( &GET_PIC( library )->ft_outline_glyph_class ) -#define FT_BITMAP_GLYPH_CLASS_GET \ - ( &GET_PIC( library )->ft_bitmap_glyph_class ) -#define FT_DEFAULT_MODULES_GET \ - ( GET_PIC( library )->default_module_classes ) - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#define FT_RACCESS_GUESS_TABLE_GET \ - ( GET_PIC( library )->ft_raccess_guess_table ) -#endif - - - /* see basepic.c for the implementation */ - void - ft_base_pic_free( FT_Library library ); - - FT_Error - ft_base_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __BASEPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftadvanc.c b/drivers/freetype/freetype/src/base/ftadvanc.c deleted file mode 100644 index 52078478df..0000000000 --- a/drivers/freetype/freetype/src/base/ftadvanc.c +++ /dev/null @@ -1,162 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftadvanc.c */ -/* */ -/* Quick computation of advance widths (body). */ -/* */ -/* Copyright 2008, 2009, 2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_ADVANCES_H -#include FT_INTERNAL_OBJECTS_H - - - static FT_Error - _ft_face_scale_advances( FT_Face face, - FT_Fixed* advances, - FT_UInt count, - FT_Int32 flags ) - { - FT_Fixed scale; - FT_UInt nn; - - - if ( flags & FT_LOAD_NO_SCALE ) - return FT_Err_Ok; - - if ( face->size == NULL ) - return FT_THROW( Invalid_Size_Handle ); - - if ( flags & FT_LOAD_VERTICAL_LAYOUT ) - scale = face->size->metrics.y_scale; - else - scale = face->size->metrics.x_scale; - - /* this must be the same scaling as to get linear{Hori,Vert}Advance */ - /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */ - - for ( nn = 0; nn < count; nn++ ) - advances[nn] = FT_MulDiv( advances[nn], scale, 64 ); - - return FT_Err_Ok; - } - - - /* at the moment, we can perform fast advance retrieval only in */ - /* the following cases: */ - /* */ - /* - unscaled load */ - /* - unhinted load */ - /* - light-hinted load */ - -#define LOAD_ADVANCE_FAST_CHECK( flags ) \ - ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ - FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) - - - /* documentation is in ftadvanc.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Advance( FT_Face face, - FT_UInt gindex, - FT_Int32 flags, - FT_Fixed *padvance ) - { - FT_Face_GetAdvancesFunc func; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - if ( gindex >= (FT_UInt)face->num_glyphs ) - return FT_THROW( Invalid_Glyph_Index ); - - func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) - { - FT_Error error; - - - error = func( face, gindex, 1, flags, padvance ); - if ( !error ) - return _ft_face_scale_advances( face, padvance, 1, flags ); - - if ( FT_ERR_NEQ( error, Unimplemented_Feature ) ) - return error; - } - - return FT_Get_Advances( face, gindex, 1, flags, padvance ); - } - - - /* documentation is in ftadvanc.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Advances( FT_Face face, - FT_UInt start, - FT_UInt count, - FT_Int32 flags, - FT_Fixed *padvances ) - { - FT_Face_GetAdvancesFunc func; - FT_UInt num, end, nn; - FT_Error error = FT_Err_Ok; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - num = (FT_UInt)face->num_glyphs; - end = start + count; - if ( start >= num || end < start || end > num ) - return FT_THROW( Invalid_Glyph_Index ); - - if ( count == 0 ) - return FT_Err_Ok; - - func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) - { - error = func( face, start, count, flags, padvances ); - if ( !error ) - return _ft_face_scale_advances( face, padvances, count, flags ); - - if ( FT_ERR_NEQ( error, Unimplemented_Feature ) ) - return error; - } - - error = FT_Err_Ok; - - if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) - return FT_THROW( Unimplemented_Feature ); - - flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; - for ( nn = 0; nn < count; nn++ ) - { - error = FT_Load_Glyph( face, start + nn, flags ); - if ( error ) - break; - - /* scale from 26.6 to 16.16 */ - padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) - ? face->glyph->advance.y << 10 - : face->glyph->advance.x << 10; - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftapi.c b/drivers/freetype/freetype/src/base/ftapi.c deleted file mode 100644 index 8914d1f4e9..0000000000 --- a/drivers/freetype/freetype/src/base/ftapi.c +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftapi.c */ -/* */ -/* The FreeType compatibility functions (body). */ -/* */ -/* Copyright 2002 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_LIST_H -#include FT_OUTLINE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TABLES_H -#include FT_OUTLINE_H - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C O M P A T I B I L I T Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* backwards compatibility API */ - - FT_BASE_DEF( void ) - FT_New_Memory_Stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream stream ) - { - FT_UNUSED( library ); - - FT_Stream_OpenMemory( stream, base, size ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Seek_Stream( FT_Stream stream, - FT_ULong pos ) - { - return FT_Stream_Seek( stream, pos ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Skip_Stream( FT_Stream stream, - FT_Long distance ) - { - return FT_Stream_Skip( stream, distance ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Read_Stream( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Stream_Read( stream, buffer, count ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Read_Stream_At( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Stream_ReadAt( stream, pos, buffer, count ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Extract_Frame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ) - { - return FT_Stream_ExtractFrame( stream, count, pbytes ); - } - - - FT_BASE_DEF( void ) - FT_Release_Frame( FT_Stream stream, - 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 ) - FT_Forget_Frame( FT_Stream stream ) - { - FT_Stream_ExitFrame( stream ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftbase.c b/drivers/freetype/freetype/src/base/ftbase.c deleted file mode 100644 index 5e5d70ec4b..0000000000 --- a/drivers/freetype/freetype/src/base/ftbase.c +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbase.c */ -/* */ -/* Single object library component (body only). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 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> - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include "ftpic.c" -#include "basepic.c" -#include "ftadvanc.c" -#include "ftcalc.c" -#include "ftdbgmem.c" -#include "ftgloadr.c" -#include "ftobjs.c" -#include "ftoutln.c" -#include "ftrfork.c" -#include "ftsnames.c" -#include "ftstream.c" -#include "fttrigon.c" -#include "ftutil.c" - -#ifdef FT_MACINTOSH -#include "ftmac.c" -#endif - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftbase.h b/drivers/freetype/freetype/src/base/ftbase.h deleted file mode 100644 index 51a1db18b8..0000000000 --- a/drivers/freetype/freetype/src/base/ftbase.h +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbase.h */ -/* */ -/* The FreeType private functions used in base module (specification). */ -/* */ -/* Copyright 2008, 2010 by */ -/* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ -/* */ -/* 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 __FTBASE_H__ -#define __FTBASE_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H - - -FT_BEGIN_HEADER - - - /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ - /* font, and try to load a face specified by the face_index. */ - FT_LOCAL( FT_Error ) - open_face_PS_from_sfnt_stream( FT_Library library, - FT_Stream stream, - FT_Long face_index, - FT_Int num_params, - FT_Parameter *params, - FT_Face *aface ); - - - /* Create a new FT_Face given a buffer and a driver name. */ - /* From ftmac.c. */ - FT_LOCAL( FT_Error ) - open_face_from_buffer( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Long face_index, - const char* driver_name, - FT_Face *aface ); - - -#if defined( FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK ) && \ - !defined( FT_MACINTOSH ) - /* Mac OS X/Darwin kernel often changes recommended method to access */ - /* the resource fork and older methods makes the kernel issue the */ - /* warning of deprecated method. To calm it down, the methods based */ - /* on Darwin VFS should be grouped and skip the rest methods after */ - /* the case the resource is opened but found to lack a font in it. */ - FT_LOCAL( FT_Bool ) - ft_raccess_rule_by_darwin_vfs( FT_Library library, FT_UInt rule_index ); -#endif - - -FT_END_HEADER - -#endif /* __FTBASE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftbbox.c b/drivers/freetype/freetype/src/base/ftbbox.c deleted file mode 100644 index 6d1c44cb2e..0000000000 --- a/drivers/freetype/freetype/src/base/ftbbox.c +++ /dev/null @@ -1,649 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbbox.c */ -/* */ -/* FreeType bbox computation (body). */ -/* */ -/* Copyright 1996-2002, 2004, 2006, 2010, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This component has a _single_ role: to compute exact outline bounding */ - /* boxes. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_BBOX_H -#include FT_IMAGE_H -#include FT_OUTLINE_H -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_OBJECTS_H - - - typedef struct TBBox_Rec_ - { - FT_Vector last; - FT_BBox bbox; - - } TBBox_Rec; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Move_To */ - /* */ - /* <Description> */ - /* This function is used as a `move_to' and `line_to' emitter during */ - /* FT_Outline_Decompose(). It simply records the destination point */ - /* in `user->last'; no further computations are necessary since we */ - /* use the cbox as the starting bbox which must be refined. */ - /* */ - /* <Input> */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: A pointer to the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ - static int - BBox_Move_To( FT_Vector* to, - TBBox_Rec* user ) - { - user->last = *to; - - return 0; - } - - -#define CHECK_X( p, bbox ) \ - ( p->x < bbox.xMin || p->x > bbox.xMax ) - -#define CHECK_Y( p, bbox ) \ - ( p->y < bbox.yMin || p->y > bbox.yMax ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Conic_Check */ - /* */ - /* <Description> */ - /* Finds the extrema of a 1-dimensional conic Bezier curve and update */ - /* a bounding range. This version uses direct computation, as it */ - /* doesn't need square roots. */ - /* */ - /* <Input> */ - /* y1 :: The start coordinate. */ - /* */ - /* y2 :: The coordinate of the control point. */ - /* */ - /* y3 :: The end coordinate. */ - /* */ - /* <InOut> */ - /* min :: The address of the current minimum. */ - /* */ - /* max :: The address of the current maximum. */ - /* */ - static void - BBox_Conic_Check( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos* min, - FT_Pos* max ) - { - if ( y1 <= y3 && y2 == y1 ) /* flat arc */ - goto Suite; - - if ( y1 < y3 ) - { - if ( y2 >= y1 && y2 <= y3 ) /* ascending arc */ - goto Suite; - } - else - { - if ( y2 >= y3 && y2 <= y1 ) /* descending arc */ - { - y2 = y1; - y1 = y3; - y3 = y2; - goto Suite; - } - } - - y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 ); - - Suite: - if ( y1 < *min ) *min = y1; - if ( y3 > *max ) *max = y3; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Conic_To */ - /* */ - /* <Description> */ - /* This function is used as a `conic_to' emitter during */ - /* FT_Outline_Decompose(). It checks a conic Bezier curve with the */ - /* current bounding box, and computes its extrema if necessary to */ - /* update it. */ - /* */ - /* <Input> */ - /* control :: A pointer to a control point. */ - /* */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: The address of the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ - /* <Note> */ - /* In the case of a non-monotonous arc, we compute directly the */ - /* extremum coordinates, as it is sufficiently fast. */ - /* */ - static int - BBox_Conic_To( FT_Vector* control, - FT_Vector* to, - TBBox_Rec* user ) - { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ - - if ( CHECK_X( control, user->bbox ) ) - BBox_Conic_Check( user->last.x, - control->x, - to->x, - &user->bbox.xMin, - &user->bbox.xMax ); - - if ( CHECK_Y( control, user->bbox ) ) - BBox_Conic_Check( user->last.y, - control->y, - to->y, - &user->bbox.yMin, - &user->bbox.yMax ); - - user->last = *to; - - return 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Cubic_Check */ - /* */ - /* <Description> */ - /* Finds the extrema of a 1-dimensional cubic Bezier curve and */ - /* updates a bounding range. This version uses splitting because we */ - /* don't want to use square roots and extra accuracy. */ - /* */ - /* <Input> */ - /* p1 :: The start coordinate. */ - /* */ - /* p2 :: The coordinate of the first control point. */ - /* */ - /* p3 :: The coordinate of the second control point. */ - /* */ - /* p4 :: The end coordinate. */ - /* */ - /* <InOut> */ - /* min :: The address of the current minimum. */ - /* */ - /* max :: The address of the current maximum. */ - /* */ - -#if 0 - - static void - BBox_Cubic_Check( FT_Pos p1, - FT_Pos p2, - FT_Pos p3, - FT_Pos p4, - FT_Pos* min, - FT_Pos* max ) - { - FT_Pos q1, q2, q3, q4; - - - q1 = p1; - q2 = p2; - q3 = p3; - q4 = p4; - - /* for a conic segment to possibly reach new maximum */ - /* one of its off-points must be above the current value */ - while ( q2 > *max || q3 > *max ) - { - /* determine which half contains the maximum and split */ - if ( q1 + q2 > q3 + q4 ) /* first half */ - { - q4 = q4 + q3; - q3 = q3 + q2; - q2 = q2 + q1; - q4 = q4 + q3; - q3 = q3 + q2; - q4 = ( q4 + q3 ) / 8; - q3 = q3 / 4; - q2 = q2 / 2; - } - else /* second half */ - { - q1 = q1 + q2; - q2 = q2 + q3; - q3 = q3 + q4; - q1 = q1 + q2; - q2 = q2 + q3; - q1 = ( q1 + q2 ) / 8; - q2 = q2 / 4; - q3 = q3 / 2; - } - - /* check if either end reached the maximum */ - if ( q1 == q2 && q1 >= q3 ) - { - *max = q1; - break; - } - if ( q3 == q4 && q2 <= q4 ) - { - *max = q4; - break; - } - } - - q1 = p1; - q2 = p2; - q3 = p3; - q4 = p4; - - /* for a conic segment to possibly reach new minimum */ - /* one of its off-points must be below the current value */ - while ( q2 < *min || q3 < *min ) - { - /* determine which half contains the minimum and split */ - if ( q1 + q2 < q3 + q4 ) /* first half */ - { - q4 = q4 + q3; - q3 = q3 + q2; - q2 = q2 + q1; - q4 = q4 + q3; - q3 = q3 + q2; - q4 = ( q4 + q3 ) / 8; - q3 = q3 / 4; - q2 = q2 / 2; - } - else /* second half */ - { - q1 = q1 + q2; - q2 = q2 + q3; - q3 = q3 + q4; - q1 = q1 + q2; - q2 = q2 + q3; - q1 = ( q1 + q2 ) / 8; - q2 = q2 / 4; - q3 = q3 / 2; - } - - /* check if either end reached the minimum */ - if ( q1 == q2 && q1 <= q3 ) - { - *min = q1; - break; - } - if ( q3 == q4 && q2 >= q4 ) - { - *min = q4; - break; - } - } - } - -#else - - static void - test_cubic_extrema( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos y4, - FT_Fixed u, - FT_Pos* min, - FT_Pos* max ) - { - /* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */ - FT_Pos b = y3 - 2*y2 + y1; - FT_Pos c = y2 - y1; - FT_Pos d = y1; - FT_Pos y; - FT_Fixed uu; - - FT_UNUSED ( y4 ); - - - /* The polynomial is */ - /* */ - /* P(x) = a*x^3 + 3b*x^2 + 3c*x + d , */ - /* */ - /* dP/dx = 3a*x^2 + 6b*x + 3c . */ - /* */ - /* However, we also have */ - /* */ - /* dP/dx(u) = 0 , */ - /* */ - /* which implies by subtraction that */ - /* */ - /* P(u) = b*u^2 + 2c*u + d . */ - - if ( u > 0 && u < 0x10000L ) - { - uu = FT_MulFix( u, u ); - y = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu ); - - if ( y < *min ) *min = y; - if ( y > *max ) *max = y; - } - } - - - static void - BBox_Cubic_Check( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos y4, - FT_Pos* min, - FT_Pos* max ) - { - /* always compare first and last points */ - if ( y1 < *min ) *min = y1; - else if ( y1 > *max ) *max = y1; - - if ( y4 < *min ) *min = y4; - else if ( y4 > *max ) *max = y4; - - /* now, try to see if there are split points here */ - if ( y1 <= y4 ) - { - /* flat or ascending arc test */ - if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) - return; - } - else /* y1 > y4 */ - { - /* descending arc test */ - if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) - return; - } - - /* There are some split points. Find them. */ - /* We already made sure that a, b, and c below cannot be all zero. */ - { - FT_Pos a = y4 - 3*y3 + 3*y2 - y1; - FT_Pos b = y3 - 2*y2 + y1; - FT_Pos c = y2 - y1; - FT_Pos d; - FT_Fixed t; - FT_Int shift; - - - /* We need to solve `ax^2+2bx+c' here, without floating points! */ - /* The trick is to normalize to a different representation in order */ - /* to use our 16.16 fixed-point routines. */ - /* */ - /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */ - /* These values must fit into a single 16.16 value. */ - /* */ - /* We normalize a, b, and c to `8.16' fixed-point values to ensure */ - /* that their product is held in a `16.16' value including the sign. */ - /* Necessarily, we need to shift `a', `b', and `c' so that the most */ - /* significant bit of their absolute values is at position 22. */ - /* */ - /* This also means that we are using 23 bits of precision to compute */ - /* the zeros, independently of the range of the original polynomial */ - /* coefficients. */ - /* */ - /* This algorithm should ensure reasonably accurate values for the */ - /* zeros. Note that they are only expressed with 16 bits when */ - /* computing the extrema (the zeros need to be in 0..1 exclusive */ - /* to be considered part of the arc). */ - - shift = FT_MSB( FT_ABS( a ) | FT_ABS( b ) | FT_ABS( c ) ); - - if ( shift > 22 ) - { - shift -= 22; - - /* this loses some bits of precision, but we use 23 of them */ - /* for the computation anyway */ - a >>= shift; - b >>= shift; - c >>= shift; - } - else - { - shift = 22 - shift; - - a <<= shift; - b <<= shift; - c <<= shift; - } - - /* handle a == 0 */ - if ( a == 0 ) - { - if ( b != 0 ) - { - t = - FT_DivFix( c, b ) / 2; - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - } - else - { - /* solve the equation now */ - d = FT_MulFix( b, b ) - FT_MulFix( a, c ); - if ( d < 0 ) - return; - - if ( d == 0 ) - { - /* there is a single split point at -b/a */ - t = - FT_DivFix( b, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - else - { - /* there are two solutions; we need to filter them */ - d = FT_SqrtFixed( (FT_Int32)d ); - t = - FT_DivFix( b - d, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - - t = - FT_DivFix( b + d, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - } - } - } - -#endif - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Cubic_To */ - /* */ - /* <Description> */ - /* This function is used as a `cubic_to' emitter during */ - /* FT_Outline_Decompose(). It checks a cubic Bezier curve with the */ - /* current bounding box, and computes its extrema if necessary to */ - /* update it. */ - /* */ - /* <Input> */ - /* control1 :: A pointer to the first control point. */ - /* */ - /* control2 :: A pointer to the second control point. */ - /* */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: The address of the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ - /* <Note> */ - /* In the case of a non-monotonous arc, we don't compute directly */ - /* extremum coordinates, we subdivide instead. */ - /* */ - static int - BBox_Cubic_To( FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to, - TBBox_Rec* user ) - { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ - - if ( CHECK_X( control1, user->bbox ) || - CHECK_X( control2, user->bbox ) ) - BBox_Cubic_Check( user->last.x, - control1->x, - control2->x, - to->x, - &user->bbox.xMin, - &user->bbox.xMax ); - - if ( CHECK_Y( control1, user->bbox ) || - CHECK_Y( control2, user->bbox ) ) - BBox_Cubic_Check( user->last.y, - control1->y, - control2->y, - to->y, - &user->bbox.yMin, - &user->bbox.yMax ); - - user->last = *to; - - return 0; - } - -FT_DEFINE_OUTLINE_FUNCS(bbox_interface, - (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Move_To, - (FT_Outline_ConicTo_Func)BBox_Conic_To, - (FT_Outline_CubicTo_Func)BBox_Cubic_To, - 0, 0 - ) - - /* documentation is in ftbbox.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Get_BBox( FT_Outline* outline, - FT_BBox *abbox ) - { - FT_BBox cbox; - FT_BBox bbox; - FT_Vector* vec; - FT_UShort n; - - - if ( !abbox ) - return FT_THROW( Invalid_Argument ); - - if ( !outline ) - return FT_THROW( Invalid_Outline ); - - /* if outline is empty, return (0,0,0,0) */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - { - abbox->xMin = abbox->xMax = 0; - abbox->yMin = abbox->yMax = 0; - return 0; - } - - /* We compute the control box as well as the bounding box of */ - /* all `on' points in the outline. Then, if the two boxes */ - /* coincide, we exit immediately. */ - - vec = outline->points; - bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x; - bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y; - vec++; - - for ( n = 1; n < outline->n_points; n++ ) - { - FT_Pos x = vec->x; - FT_Pos y = vec->y; - - - /* update control box */ - if ( x < cbox.xMin ) cbox.xMin = x; - if ( x > cbox.xMax ) cbox.xMax = x; - - if ( y < cbox.yMin ) cbox.yMin = y; - if ( y > cbox.yMax ) cbox.yMax = y; - - if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) - { - /* update bbox for `on' points only */ - if ( x < bbox.xMin ) bbox.xMin = x; - if ( x > bbox.xMax ) bbox.xMax = x; - - if ( y < bbox.yMin ) bbox.yMin = y; - if ( y > bbox.yMax ) bbox.yMax = y; - } - - vec++; - } - - /* test two boxes for equality */ - if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax || - cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax ) - { - /* the two boxes are different, now walk over the outline to */ - /* get the Bezier arc extrema. */ - - FT_Error error; - TBBox_Rec user; - -#ifdef FT_CONFIG_OPTION_PIC - FT_Outline_Funcs bbox_interface; - Init_Class_bbox_interface(&bbox_interface); -#endif - - user.bbox = bbox; - - error = FT_Outline_Decompose( outline, &bbox_interface, &user ); - if ( error ) - return error; - - *abbox = user.bbox; - } - else - *abbox = bbox; - - return FT_Err_Ok; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftbdf.c b/drivers/freetype/freetype/src/base/ftbdf.c deleted file mode 100644 index 5755f8558d..0000000000 --- a/drivers/freetype/freetype/src/base/ftbdf.c +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbdf.c */ -/* */ -/* FreeType API for accessing BDF-specific strings (body). */ -/* */ -/* Copyright 2002-2004, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_BDF_H - - - /* documentation is in ftbdf.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_BDF_Charset_ID( FT_Face face, - const char* *acharset_encoding, - const char* *acharset_registry ) - { - FT_Error error; - const char* encoding = NULL; - const char* registry = NULL; - - - error = FT_ERR( Invalid_Argument ); - - if ( face ) - { - FT_Service_BDF service; - - - FT_FACE_FIND_SERVICE( face, service, BDF ); - - if ( service && service->get_charset_id ) - error = service->get_charset_id( face, &encoding, ®istry ); - } - - if ( acharset_encoding ) - *acharset_encoding = encoding; - - if ( acharset_registry ) - *acharset_registry = registry; - - return error; - } - - - /* documentation is in ftbdf.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_BDF_Property( FT_Face face, - const char* prop_name, - BDF_PropertyRec *aproperty ) - { - FT_Error error; - - - error = FT_ERR( Invalid_Argument ); - - aproperty->type = BDF_PROPERTY_TYPE_NONE; - - if ( face ) - { - FT_Service_BDF service; - - - FT_FACE_FIND_SERVICE( face, service, BDF ); - - if ( service && service->get_property ) - error = service->get_property( face, prop_name, aproperty ); - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftbitmap.c b/drivers/freetype/freetype/src/base/ftbitmap.c deleted file mode 100644 index 975818e14f..0000000000 --- a/drivers/freetype/freetype/src/base/ftbitmap.c +++ /dev/null @@ -1,758 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbitmap.c */ -/* */ -/* FreeType utility functions for bitmaps (body). */ -/* */ -/* Copyright 2004-2009, 2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_BITMAP_H -#include FT_IMAGE_H -#include FT_INTERNAL_OBJECTS_H - - - static - const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( void ) - FT_Bitmap_New( FT_Bitmap *abitmap ) - { - *abitmap = null_bitmap; - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Bitmap_Copy( FT_Library library, - const FT_Bitmap *source, - FT_Bitmap *target) - { - FT_Memory memory = library->memory; - FT_Error error = FT_Err_Ok; - FT_Int pitch = source->pitch; - FT_ULong size; - - - if ( source == target ) - return FT_Err_Ok; - - if ( source->buffer == NULL ) - { - *target = *source; - - return FT_Err_Ok; - } - - if ( pitch < 0 ) - pitch = -pitch; - size = (FT_ULong)( pitch * source->rows ); - - if ( target->buffer ) - { - FT_Int target_pitch = target->pitch; - FT_ULong target_size; - - - if ( target_pitch < 0 ) - target_pitch = -target_pitch; - target_size = (FT_ULong)( target_pitch * target->rows ); - - if ( target_size != size ) - (void)FT_QREALLOC( target->buffer, target_size, size ); - } - else - (void)FT_QALLOC( target->buffer, size ); - - if ( !error ) - { - unsigned char *p; - - - p = target->buffer; - *target = *source; - target->buffer = p; - - FT_MEM_COPY( target->buffer, source->buffer, size ); - } - - return error; - } - - - static FT_Error - ft_bitmap_assure_buffer( FT_Memory memory, - FT_Bitmap* bitmap, - FT_UInt xpixels, - FT_UInt ypixels ) - { - FT_Error error; - int pitch; - int new_pitch; - FT_UInt bpp; - FT_Int i, width, height; - unsigned char* buffer = NULL; - - - width = bitmap->width; - height = bitmap->rows; - pitch = bitmap->pitch; - if ( pitch < 0 ) - pitch = -pitch; - - switch ( bitmap->pixel_mode ) - { - case FT_PIXEL_MODE_MONO: - bpp = 1; - new_pitch = ( width + xpixels + 7 ) >> 3; - break; - case FT_PIXEL_MODE_GRAY2: - bpp = 2; - new_pitch = ( width + xpixels + 3 ) >> 2; - break; - case FT_PIXEL_MODE_GRAY4: - bpp = 4; - new_pitch = ( width + xpixels + 1 ) >> 1; - break; - case FT_PIXEL_MODE_GRAY: - case FT_PIXEL_MODE_LCD: - case FT_PIXEL_MODE_LCD_V: - bpp = 8; - new_pitch = ( width + xpixels ); - break; - default: - return FT_THROW( Invalid_Glyph_Format ); - } - - /* if no need to allocate memory */ - if ( ypixels == 0 && new_pitch <= pitch ) - { - /* zero the padding */ - FT_Int bit_width = pitch * 8; - FT_Int bit_last = ( width + xpixels ) * bpp; - - - if ( bit_last < bit_width ) - { - FT_Byte* line = bitmap->buffer + ( bit_last >> 3 ); - FT_Byte* end = bitmap->buffer + pitch; - FT_Int shift = bit_last & 7; - FT_UInt mask = 0xFF00U >> shift; - FT_Int count = height; - - - for ( ; count > 0; count--, line += pitch, end += pitch ) - { - FT_Byte* write = line; - - - if ( shift > 0 ) - { - write[0] = (FT_Byte)( write[0] & mask ); - write++; - } - if ( write < end ) - FT_MEM_ZERO( write, end-write ); - } - } - - return FT_Err_Ok; - } - - if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) - return error; - - if ( bitmap->pitch > 0 ) - { - FT_Int len = ( width * bpp + 7 ) >> 3; - - - for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ), - bitmap->buffer + pitch * i, len ); - } - else - { - FT_Int len = ( width * bpp + 7 ) >> 3; - - - for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * i, - bitmap->buffer + pitch * i, len ); - } - - FT_FREE( bitmap->buffer ); - bitmap->buffer = buffer; - - if ( bitmap->pitch < 0 ) - new_pitch = -new_pitch; - - /* set pitch only, width and height are left untouched */ - bitmap->pitch = new_pitch; - - return FT_Err_Ok; - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Bitmap_Embolden( FT_Library library, - FT_Bitmap* bitmap, - FT_Pos xStrength, - FT_Pos yStrength ) - { - FT_Error error; - unsigned char* p; - FT_Int i, x, y, pitch; - FT_Int xstr, ystr; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( !bitmap || !bitmap->buffer ) - return FT_THROW( Invalid_Argument ); - - if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || - ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) - return FT_THROW( Invalid_Argument ); - - xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6; - ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6; - - if ( xstr == 0 && ystr == 0 ) - return FT_Err_Ok; - else if ( xstr < 0 || ystr < 0 ) - return FT_THROW( Invalid_Argument ); - - switch ( bitmap->pixel_mode ) - { - case FT_PIXEL_MODE_GRAY2: - case FT_PIXEL_MODE_GRAY4: - { - FT_Bitmap tmp; - FT_Int align; - - - if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 ) - align = ( bitmap->width + xstr + 3 ) / 4; - else - align = ( bitmap->width + xstr + 1 ) / 2; - - FT_Bitmap_New( &tmp ); - - error = FT_Bitmap_Convert( library, bitmap, &tmp, align ); - if ( error ) - return error; - - FT_Bitmap_Done( library, bitmap ); - *bitmap = tmp; - } - break; - - case FT_PIXEL_MODE_MONO: - if ( xstr > 8 ) - xstr = 8; - break; - - case FT_PIXEL_MODE_LCD: - xstr *= 3; - break; - - case FT_PIXEL_MODE_LCD_V: - ystr *= 3; - break; - - case FT_PIXEL_MODE_BGRA: - /* We don't embolden color glyphs. */ - return FT_Err_Ok; - } - - error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); - if ( error ) - return error; - - pitch = bitmap->pitch; - if ( pitch > 0 ) - p = bitmap->buffer + pitch * ystr; - else - { - pitch = -pitch; - p = bitmap->buffer + pitch * ( bitmap->rows - 1 ); - } - - /* for each row */ - for ( y = 0; y < bitmap->rows ; y++ ) - { - /* - * Horizontally: - * - * From the last pixel on, make each pixel or'ed with the - * `xstr' pixels before it. - */ - for ( x = pitch - 1; x >= 0; x-- ) - { - unsigned char tmp; - - - tmp = p[x]; - for ( i = 1; i <= xstr; i++ ) - { - if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO ) - { - p[x] |= tmp >> i; - - /* the maximum value of 8 for `xstr' comes from here */ - if ( x > 0 ) - p[x] |= p[x - 1] << ( 8 - i ); - -#if 0 - if ( p[x] == 0xff ) - break; -#endif - } - else - { - if ( x - i >= 0 ) - { - if ( p[x] + p[x - i] > bitmap->num_grays - 1 ) - { - p[x] = (unsigned char)(bitmap->num_grays - 1); - break; - } - else - { - p[x] = (unsigned char)(p[x] + p[x-i]); - if ( p[x] == bitmap->num_grays - 1 ) - break; - } - } - else - break; - } - } - } - - /* - * Vertically: - * - * Make the above `ystr' rows or'ed with it. - */ - for ( x = 1; x <= ystr; x++ ) - { - unsigned char* q; - - - q = p - bitmap->pitch * x; - for ( i = 0; i < pitch; i++ ) - q[i] |= p[i]; - } - - p += bitmap->pitch; - } - - bitmap->width += xstr; - bitmap->rows += ystr; - - return FT_Err_Ok; - } - - - FT_Byte - ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra ) - { - FT_Long a = bgra[3]; - FT_Long b = bgra[0]; - FT_Long g = bgra[1]; - FT_Long r = bgra[2]; - FT_Long l; - - - /* - * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722 - * coefficients for RGB channels *on the linear colors*. - * A gamma of 2.2 is fair to assume. And then, we need to - * undo the premultiplication too. - * - * http://accessibility.kde.org/hsl-adjusted.php - * - * We do the computation with integers only. - */ - - /* Undo premultification, get the number in a 16.16 form. */ - b = FT_MulDiv( b, 65536, a ); - g = FT_MulDiv( g, 65536, a ); - r = FT_MulDiv( r, 65536, a ); - a = a * 256; - - /* Apply gamma of 2.0 instead of 2.2. */ - b = FT_MulFix( b, b ); - g = FT_MulFix( g, g ); - r = FT_MulFix( r, r ); - - /* Apply coefficients. */ - b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ ); - g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ ); - r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ ); - - l = r + g + b; - - /* - * Final transparency can be determined this way: - * - * - If alpha is zero, we want 0. - * - If alpha is zero and luminosity is zero, we want 255. - * - If alpha is zero and luminosity is one, we want 0. - * - * So the formula is a * (1 - l). - */ - - return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 ); - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Bitmap_Convert( FT_Library library, - const FT_Bitmap *source, - FT_Bitmap *target, - FT_Int alignment ) - { - FT_Error error = FT_Err_Ok; - FT_Memory memory; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - memory = library->memory; - - switch ( source->pixel_mode ) - { - case FT_PIXEL_MODE_MONO: - case FT_PIXEL_MODE_GRAY: - case FT_PIXEL_MODE_GRAY2: - case FT_PIXEL_MODE_GRAY4: - case FT_PIXEL_MODE_LCD: - case FT_PIXEL_MODE_LCD_V: - case FT_PIXEL_MODE_BGRA: - { - FT_Int pad; - FT_Long old_size; - - - old_size = target->rows * target->pitch; - if ( old_size < 0 ) - old_size = -old_size; - - target->pixel_mode = FT_PIXEL_MODE_GRAY; - target->rows = source->rows; - target->width = source->width; - - pad = 0; - if ( alignment > 0 ) - { - pad = source->width % alignment; - if ( pad != 0 ) - pad = alignment - pad; - } - - target->pitch = source->width + pad; - - if ( target->pitch > 0 && - (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch ) - return FT_THROW( Invalid_Argument ); - - if ( target->rows * target->pitch > old_size && - FT_QREALLOC( target->buffer, - old_size, target->rows * target->pitch ) ) - return error; - } - break; - - default: - error = FT_THROW( Invalid_Argument ); - } - - switch ( source->pixel_mode ) - { - case FT_PIXEL_MODE_MONO: - { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; - - - target->num_grays = 2; - - for ( i = source->rows; i > 0; i-- ) - { - FT_Byte* ss = s; - FT_Byte* tt = t; - FT_Int j; - - - /* get the full bytes */ - for ( j = source->width >> 3; j > 0; j-- ) - { - FT_Int val = ss[0]; /* avoid a byte->int cast on each line */ - - - tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 ); - tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 ); - tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 ); - tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 ); - tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 ); - tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 ); - tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 ); - tt[7] = (FT_Byte)( val & 0x01 ); - - tt += 8; - ss += 1; - } - - /* get remaining pixels (if any) */ - j = source->width & 7; - if ( j > 0 ) - { - FT_Int val = *ss; - - - for ( ; j > 0; j-- ) - { - tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7); - val <<= 1; - tt += 1; - } - } - - s += source->pitch; - t += target->pitch; - } - } - break; - - - case FT_PIXEL_MODE_GRAY: - case FT_PIXEL_MODE_LCD: - case FT_PIXEL_MODE_LCD_V: - { - FT_Int width = source->width; - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; - - - target->num_grays = 256; - - for ( i = source->rows; i > 0; i-- ) - { - FT_ARRAY_COPY( t, s, width ); - - s += s_pitch; - t += t_pitch; - } - } - break; - - - case FT_PIXEL_MODE_GRAY2: - { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; - - - target->num_grays = 4; - - for ( i = source->rows; i > 0; i-- ) - { - FT_Byte* ss = s; - FT_Byte* tt = t; - FT_Int j; - - - /* get the full bytes */ - for ( j = source->width >> 2; j > 0; j-- ) - { - FT_Int val = ss[0]; - - - tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 ); - tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 ); - tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 ); - tt[3] = (FT_Byte)( ( val & 0x03 ) ); - - ss += 1; - tt += 4; - } - - j = source->width & 3; - if ( j > 0 ) - { - FT_Int val = ss[0]; - - - for ( ; j > 0; j-- ) - { - tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 ); - val <<= 2; - tt += 1; - } - } - - s += source->pitch; - t += target->pitch; - } - } - break; - - - case FT_PIXEL_MODE_GRAY4: - { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; - - - target->num_grays = 16; - - for ( i = source->rows; i > 0; i-- ) - { - FT_Byte* ss = s; - FT_Byte* tt = t; - FT_Int j; - - - /* get the full bytes */ - for ( j = source->width >> 1; j > 0; j-- ) - { - FT_Int val = ss[0]; - - - tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 ); - tt[1] = (FT_Byte)( ( val & 0x0F ) ); - - ss += 1; - tt += 2; - } - - if ( source->width & 1 ) - tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 ); - - s += source->pitch; - t += target->pitch; - } - } - break; - - case FT_PIXEL_MODE_BGRA: - { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; - - - target->num_grays = 256; - - for ( i = source->rows; i > 0; i-- ) - { - FT_Byte* ss = s; - FT_Byte* tt = t; - FT_Int j; - - - for ( j = source->width; j > 0; j-- ) - { - tt[0] = ft_gray_for_premultiplied_srgb_bgra( ss ); - - ss += 4; - tt += 1; - } - - s += s_pitch; - t += t_pitch; - } - } - break; - - default: - ; - } - - return error; - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ) - { - if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP && - !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) - { - FT_Bitmap bitmap; - FT_Error error; - - - FT_Bitmap_New( &bitmap ); - error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); - if ( error ) - return error; - - slot->bitmap = bitmap; - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - } - - return FT_Err_Ok; - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Bitmap_Done( FT_Library library, - FT_Bitmap *bitmap ) - { - FT_Memory memory; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( !bitmap ) - return FT_THROW( Invalid_Argument ); - - memory = library->memory; - - FT_FREE( bitmap->buffer ); - *bitmap = null_bitmap; - - return FT_Err_Ok; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftcalc.c b/drivers/freetype/freetype/src/base/ftcalc.c deleted file mode 100644 index 0ec0d78930..0000000000 --- a/drivers/freetype/freetype/src/base/ftcalc.c +++ /dev/null @@ -1,974 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcalc.c */ -/* */ -/* Arithmetic computations (body). */ -/* */ -/* Copyright 1996-2006, 2008, 2012-2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Support for 1-complement arithmetic has been totally dropped in this */ - /* release. You can still write your own code if you need it. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Implementing basic computation routines. */ - /* */ - /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ - /* and FT_FloorFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_GLYPH_H -#include FT_TRIGONOMETRY_H -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H - -#ifdef FT_MULFIX_INLINED -#undef FT_MulFix -#endif - -/* we need to emulate a 64-bit data type if a real one isn't available */ - -#ifndef FT_LONG64 - - typedef struct FT_Int64_ - { - FT_UInt32 lo; - FT_UInt32 hi; - - } FT_Int64; - -#endif /* !FT_LONG64 */ - - - /*************************************************************************/ - /* */ - /* 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_calc - - - /* The following three functions are available regardless of whether */ - /* FT_LONG64 is defined. */ - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_RoundFix( FT_Fixed a ) - { - return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL - : -((-a + 0x8000L ) & ~0xFFFFL ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_CeilFix( FT_Fixed a ) - { - return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL - : -((-a + 0xFFFFL ) & ~0xFFFFL ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_FloorFix( FT_Fixed a ) - { - return ( a >= 0 ) ? a & ~0xFFFFL - : -((-a) & ~0xFFFFL ); - } - - - FT_BASE_DEF ( FT_Int ) - FT_MSB( FT_UInt32 z ) - { - FT_Int shift = 0; - - /* determine msb bit index in `shift' */ - if ( z >= ( 1L << 16 ) ) - { - z >>= 16; - shift += 16; - } - if ( z >= ( 1L << 8 ) ) - { - z >>= 8; - shift += 8; - } - if ( z >= ( 1L << 4 ) ) - { - z >>= 4; - shift += 4; - } - if ( z >= ( 1L << 2 ) ) - { - z >>= 2; - shift += 2; - } - if ( z >= ( 1L << 1 ) ) - { - z >>= 1; - shift += 1; - } - - return shift; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Fixed ) - FT_Hypot( FT_Fixed x, - FT_Fixed y ) - { - FT_Vector v; - - - v.x = x; - v.y = y; - - return FT_Vector_Length( &v ); - } - - -#ifdef FT_LONG64 - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) - { -#ifdef FT_MULFIX_ASSEMBLER - - return FT_MULFIX_ASSEMBLER( a, b ); - -#else - - FT_Int s = 1; - FT_Long c; - - - if ( a < 0 ) - { - a = -a; - s = -1; - } - - if ( b < 0 ) - { - b = -b; - s = -s; - } - - c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); - - return ( s > 0 ) ? c : -c; - -#endif /* FT_MULFIX_ASSEMBLER */ - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = 1; - if ( a < 0 ) - { - a = -a; - s = -1; - } - if ( b < 0 ) - { - b = -b; - s = -s; - } - - if ( b == 0 ) - /* check for division by 0 */ - q = 0x7FFFFFFFL; - else - /* compute result directly */ - q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b ); - - return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); - } - - -#else /* !FT_LONG64 */ - - - static void - ft_multo64( FT_UInt32 x, - FT_UInt32 y, - FT_Int64 *z ) - { - FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; - - - lo1 = x & 0x0000FFFFU; hi1 = x >> 16; - lo2 = y & 0x0000FFFFU; hi2 = y >> 16; - - lo = lo1 * lo2; - i1 = lo1 * hi2; - i2 = lo2 * hi1; - hi = hi1 * hi2; - - /* Check carry overflow of i1 + i2 */ - i1 += i2; - hi += (FT_UInt32)( i1 < i2 ) << 16; - - hi += i1 >> 16; - i1 = i1 << 16; - - /* Check carry overflow of i1 + lo */ - lo += i1; - hi += ( lo < i1 ); - - z->lo = lo; - z->hi = hi; - } - - - static FT_UInt32 - ft_div64by32( FT_UInt32 hi, - FT_UInt32 lo, - FT_UInt32 y ) - { - FT_UInt32 r, q; - FT_Int i; - - - q = 0; - r = hi; - - if ( r >= y ) - return (FT_UInt32)0x7FFFFFFFL; - - i = 32; - do - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } while ( --i ); - - return q; - } - - - static void - FT_Add64( FT_Int64* x, - FT_Int64* y, - FT_Int64 *z ) - { - register FT_UInt32 lo, hi; - - - lo = x->lo + y->lo; - hi = x->hi + y->hi + ( lo < x->lo ); - - z->lo = lo; - z->hi = hi; - } - - - /* 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, - FT_Long c ) - { - long s; - - - /* XXX: this function does not allow 64-bit arguments */ - if ( a == 0 || b == c ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); - - if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) - a = ( a * b + ( c >> 1 ) ) / c; - - else if ( (FT_Int32)c > 0 ) - { - FT_Int64 temp, temp2; - - - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); - - temp2.hi = 0; - temp2.lo = (FT_UInt32)(c >> 1); - FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); - } - else - a = 0x7FFFFFFFL; - - return ( s < 0 ? -a : a ); - } - - - FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) - { - long s; - - - if ( a == 0 || b == c ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); - - if ( a <= 46340L && b <= 46340L && c > 0 ) - a = a * b / c; - - else if ( (FT_Int32)c > 0 ) - { - FT_Int64 temp; - - - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); - } - else - a = 0x7FFFFFFFL; - - return ( s < 0 ? -a : a ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) - { -#ifdef FT_MULFIX_ASSEMBLER - - return FT_MULFIX_ASSEMBLER( a, b ); - -#elif 0 - - /* - * This code is nonportable. See comment below. - * - * However, on a platform where right-shift of a signed quantity fills - * the leftmost bits by copying the sign bit, it might be faster. - */ - - FT_Long sa, sb; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - /* - * This is a clever way of converting a signed number `a' into its - * absolute value (stored back into `a') and its sign. The sign is - * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' - * was negative. (Similarly for `b' and `sb'). - * - * Unfortunately, it doesn't work (at least not portably). - * - * It makes the assumption that right-shift on a negative signed value - * fills the leftmost bits by copying the sign bit. This is wrong. - * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, - * the result of right-shift of a negative signed value is - * implementation-defined. At least one implementation fills the - * leftmost bits with 0s (i.e., it is exactly the same as an unsigned - * right shift). This means that when `a' is negative, `sa' ends up - * with the value 1 rather than -1. After that, everything else goes - * wrong. - */ - sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); - a = ( a ^ sa ) - sa; - sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); - b = ( b ^ sb ) - sb; - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000U ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFU; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); - } - - sa ^= sb, - ua = (FT_ULong)(( ua ^ sa ) - sa); - - return (FT_Long)ua; - -#else /* 0 */ - - FT_Long s; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - 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 + 0x8000UL ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFUL; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); - } - - return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); - -#endif /* 0 */ - - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) - { - FT_Int32 s; - FT_UInt32 q; - - - /* XXX: this function does not allow 64-bit arguments */ - s = (FT_Int32)a; a = FT_ABS( a ); - s ^= (FT_Int32)b; b = FT_ABS( b ); - - if ( (FT_UInt32)b == 0 ) - { - /* check for division by 0 */ - q = (FT_UInt32)0x7FFFFFFFL; - } - else if ( ( a >> 16 ) == 0 ) - { - /* compute result directly */ - q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; - } - else - { - /* we need more bits; we have to do it by hand */ - FT_Int64 temp, temp2; - - - temp.hi = (FT_Int32)( a >> 16 ); - temp.lo = (FT_UInt32)a << 16; - temp2.hi = 0; - temp2.lo = (FT_UInt32)( b >> 1 ); - FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - -#if 0 - - /* documentation is in ftcalc.h */ - - FT_EXPORT_DEF( void ) - FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64 *z ) - { - FT_Int32 s; - - - s = x; x = FT_ABS( x ); - s ^= y; y = FT_ABS( y ); - - ft_multo64( x, y, z ); - - if ( s < 0 ) - { - z->lo = (FT_UInt32)-(FT_Int32)z->lo; - z->hi = ~z->hi + !( z->lo ); - } - } - - - /* apparently, the second version of this code is not compiled correctly */ - /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ - -#if 1 - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q, r, i, lo; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = x->lo / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - r = x->hi; - lo = x->lo; - - 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! */ - q = 0; - for ( i = 0; i < 32; i++ ) - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= (FT_UInt32)y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#else /* 0 */ - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = ( x->lo + ( y >> 1 ) ) / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - q = ft_div64by32( x->hi, x->lo, y ); - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#endif /* 0 */ - -#endif /* 0 */ - - -#endif /* FT_LONG64 */ - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix *b ) - { - FT_Fixed xx, xy, yx, yy; - - - if ( !a || !b ) - return; - - xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); - xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); - yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); - yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Matrix_Invert( FT_Matrix* matrix ) - { - FT_Pos delta, xx, yy; - - - if ( !matrix ) - return FT_THROW( Invalid_Argument ); - - /* compute discriminant */ - delta = FT_MulFix( matrix->xx, matrix->yy ) - - FT_MulFix( matrix->xy, matrix->yx ); - - if ( !delta ) - return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */ - - matrix->xy = - FT_DivFix( matrix->xy, delta ); - matrix->yx = - FT_DivFix( matrix->yx, delta ); - - xx = matrix->xx; - yy = matrix->yy; - - matrix->xx = FT_DivFix( yy, delta ); - matrix->yy = FT_DivFix( xx, delta ); - - return FT_Err_Ok; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( void ) - FT_Matrix_Multiply_Scaled( const FT_Matrix* a, - FT_Matrix *b, - FT_Long scaling ) - { - FT_Fixed xx, xy, yx, yy; - - FT_Long val = 0x10000L * scaling; - - - if ( !a || !b ) - return; - - xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); - xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); - yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); - yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( void ) - FT_Vector_Transform_Scaled( FT_Vector* vector, - const FT_Matrix* matrix, - FT_Long scaling ) - { - FT_Pos xz, yz; - - FT_Long val = 0x10000L * scaling; - - - if ( !vector || !matrix ) - return; - - xz = FT_MulDiv( vector->x, matrix->xx, val ) + - FT_MulDiv( vector->y, matrix->xy, val ); - - yz = FT_MulDiv( vector->x, matrix->yx, val ) + - FT_MulDiv( vector->y, matrix->yy, val ); - - vector->x = xz; - vector->y = yz; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ) - { - FT_UInt32 root, rem_hi, rem_lo, test_div; - FT_Int count; - - - root = 0; - - if ( x > 0 ) - { - rem_hi = 0; - rem_lo = x; - count = 24; - do - { - rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); - rem_lo <<= 2; - root <<= 1; - test_div = ( root << 1 ) + 1; - - if ( rem_hi >= test_div ) - { - rem_hi -= test_div; - root += 1; - } - } while ( --count ); - } - - return (FT_Int32)root; - } - - - /* 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_Long result; /* avoid overflow on 16-bit system */ - - - /* 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; - - - /* XXX: this function does not allow 64-bit arguments */ - ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); - ft_multo64( (FT_Int32)in_y, (FT_Int32)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 - } - - /* XXX: only the sign of return value, +1/0/-1 must be used */ - return (FT_Int)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 */ diff --git a/drivers/freetype/freetype/src/base/ftcid.c b/drivers/freetype/freetype/src/base/ftcid.c deleted file mode 100644 index 741879d922..0000000000 --- a/drivers/freetype/freetype/src/base/ftcid.c +++ /dev/null @@ -1,117 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcid.c */ -/* */ -/* FreeType API for accessing CID font information. */ -/* */ -/* Copyright 2007, 2009, 2013 by Derek Clegg, Michael Toftdal. */ -/* */ -/* 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_CID_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_CID_H - - - /* documentation is in ftcid.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, - const char* *registry, - const char* *ordering, - FT_Int *supplement) - { - FT_Error error; - const char* r = NULL; - const char* o = NULL; - FT_Int s = 0; - - - error = FT_ERR( Invalid_Argument ); - - if ( face ) - { - FT_Service_CID service; - - - FT_FACE_FIND_SERVICE( face, service, CID ); - - if ( service && service->get_ros ) - error = service->get_ros( face, &r, &o, &s ); - } - - if ( registry ) - *registry = r; - - if ( ordering ) - *ordering = o; - - if ( supplement ) - *supplement = s; - - return error; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, - FT_Bool *is_cid ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Bool ic = 0; - - - if ( face ) - { - FT_Service_CID service; - - - FT_FACE_FIND_SERVICE( face, service, CID ); - - if ( service && service->get_is_cid ) - error = service->get_is_cid( face, &ic); - } - - if ( is_cid ) - *is_cid = ic; - - return error; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_Get_CID_From_Glyph_Index( FT_Face face, - FT_UInt glyph_index, - FT_UInt *cid ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_UInt c = 0; - - - if ( face ) - { - FT_Service_CID service; - - - FT_FACE_FIND_SERVICE( face, service, CID ); - - if ( service && service->get_cid_from_glyph_index ) - error = service->get_cid_from_glyph_index( face, glyph_index, &c); - } - - if ( cid ) - *cid = c; - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftdbgmem.c b/drivers/freetype/freetype/src/base/ftdbgmem.c deleted file mode 100644 index 6fb86fe77d..0000000000 --- a/drivers/freetype/freetype/src/base/ftdbgmem.c +++ /dev/null @@ -1,992 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdbgmem.c */ -/* */ -/* Memory debugger (body). */ -/* */ -/* Copyright 2001-2006, 2009, 2013 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_CONFIG_CONFIG_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_MEMORY_H -#include FT_SYSTEM_H -#include FT_ERRORS_H -#include FT_TYPES_H - - -#ifdef FT_DEBUG_MEMORY - -#define KEEPALIVE /* `Keep alive' means that freed blocks aren't released - * to the heap. This is useful to detect double-frees - * or weird heap corruption, but it uses large amounts of - * memory, however. - */ - -#include FT_CONFIG_STANDARD_LIBRARY_H - - FT_BASE_DEF( const char* ) _ft_debug_file = 0; - FT_BASE_DEF( long ) _ft_debug_lineno = 0; - - extern void - FT_DumpMemory( FT_Memory memory ); - - - typedef struct FT_MemSourceRec_* FT_MemSource; - typedef struct FT_MemNodeRec_* FT_MemNode; - typedef struct FT_MemTableRec_* FT_MemTable; - - -#define FT_MEM_VAL( addr ) ((FT_PtrDist)(FT_Pointer)( addr )) - - /* - * This structure holds statistics for a single allocation/release - * site. This is useful to know where memory operations happen the - * most. - */ - typedef struct FT_MemSourceRec_ - { - const char* file_name; - long line_no; - - FT_Long cur_blocks; /* current number of allocated blocks */ - FT_Long max_blocks; /* max. number of allocated blocks */ - FT_Long all_blocks; /* total number of blocks allocated */ - - FT_Long cur_size; /* current cumulative allocated size */ - FT_Long max_size; /* maximum cumulative allocated size */ - FT_Long all_size; /* total cumulative allocated size */ - - FT_Long cur_max; /* current maximum allocated size */ - - FT_UInt32 hash; - FT_MemSource link; - - } FT_MemSourceRec; - - - /* - * We don't need a resizable array for the memory sources, because - * their number is pretty limited within FreeType. - */ -#define FT_MEM_SOURCE_BUCKETS 128 - - /* - * This structure holds information related to a single allocated - * memory block. If KEEPALIVE is defined, blocks that are freed by - * FreeType are never released to the system. Instead, their `size' - * field is set to -size. This is mainly useful to detect double frees, - * at the price of large memory footprint during execution. - */ - typedef struct FT_MemNodeRec_ - { - FT_Byte* address; - FT_Long size; /* < 0 if the block was freed */ - - FT_MemSource source; - -#ifdef KEEPALIVE - const char* free_file_name; - FT_Long free_line_no; -#endif - - FT_MemNode link; - - } FT_MemNodeRec; - - - /* - * The global structure, containing compound statistics and all hash - * tables. - */ - typedef struct FT_MemTableRec_ - { - FT_ULong size; - FT_ULong nodes; - FT_MemNode* buckets; - - FT_ULong alloc_total; - FT_ULong alloc_current; - FT_ULong alloc_max; - FT_ULong alloc_count; - - FT_Bool bound_total; - FT_ULong alloc_total_max; - - FT_Bool bound_count; - FT_ULong alloc_count_max; - - FT_MemSource sources[FT_MEM_SOURCE_BUCKETS]; - - FT_Bool keep_alive; - - FT_Memory memory; - FT_Pointer memory_user; - FT_Alloc_Func alloc; - FT_Free_Func free; - FT_Realloc_Func realloc; - - } FT_MemTableRec; - - -#define FT_MEM_SIZE_MIN 7 -#define FT_MEM_SIZE_MAX 13845163 - -#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") - - - /* - * Prime numbers are ugly to handle. It would be better to implement - * L-Hashing, which is 10% faster and doesn't require divisions. - */ - static const FT_UInt ft_mem_primes[] = - { - 7, - 11, - 19, - 37, - 73, - 109, - 163, - 251, - 367, - 557, - 823, - 1237, - 1861, - 2777, - 4177, - 6247, - 9371, - 14057, - 21089, - 31627, - 47431, - 71143, - 106721, - 160073, - 240101, - 360163, - 540217, - 810343, - 1215497, - 1823231, - 2734867, - 4102283, - 6153409, - 9230113, - 13845163, - }; - - - static FT_ULong - ft_mem_closest_prime( FT_ULong num ) - { - FT_UInt i; - - - for ( i = 0; - i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ ) - if ( ft_mem_primes[i] > num ) - return ft_mem_primes[i]; - - return FT_MEM_SIZE_MAX; - } - - - extern void - ft_mem_debug_panic( const char* fmt, - ... ) - { - va_list ap; - - - printf( "FreeType.Debug: " ); - - va_start( ap, fmt ); - vprintf( fmt, ap ); - va_end( ap ); - - printf( "\n" ); - exit( EXIT_FAILURE ); - } - - - static FT_Pointer - ft_mem_table_alloc( FT_MemTable table, - FT_Long size ) - { - FT_Memory memory = table->memory; - FT_Pointer block; - - - memory->user = table->memory_user; - block = table->alloc( memory, size ); - memory->user = table; - - return block; - } - - - static void - ft_mem_table_free( FT_MemTable table, - FT_Pointer block ) - { - FT_Memory memory = table->memory; - - - memory->user = table->memory_user; - table->free( memory, block ); - memory->user = table; - } - - - static void - ft_mem_table_resize( FT_MemTable table ) - { - FT_ULong new_size; - - - new_size = ft_mem_closest_prime( table->nodes ); - if ( new_size != table->size ) - { - FT_MemNode* new_buckets; - FT_ULong i; - - - new_buckets = (FT_MemNode *) - ft_mem_table_alloc( table, - new_size * sizeof ( FT_MemNode ) ); - if ( new_buckets == NULL ) - return; - - FT_ARRAY_ZERO( new_buckets, new_size ); - - for ( i = 0; i < table->size; i++ ) - { - FT_MemNode node, next, *pnode; - FT_PtrDist hash; - - - node = table->buckets[i]; - while ( node ) - { - next = node->link; - hash = FT_MEM_VAL( node->address ) % new_size; - pnode = new_buckets + hash; - - node->link = pnode[0]; - pnode[0] = node; - - node = next; - } - } - - if ( table->buckets ) - ft_mem_table_free( table, table->buckets ); - - table->buckets = new_buckets; - table->size = new_size; - } - } - - - static FT_MemTable - ft_mem_table_new( FT_Memory memory ) - { - FT_MemTable table; - - - table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); - if ( table == NULL ) - goto Exit; - - FT_ZERO( table ); - - table->size = FT_MEM_SIZE_MIN; - table->nodes = 0; - - table->memory = memory; - - table->memory_user = memory->user; - - table->alloc = memory->alloc; - table->realloc = memory->realloc; - table->free = memory->free; - - table->buckets = (FT_MemNode *) - memory->alloc( memory, - table->size * sizeof ( FT_MemNode ) ); - if ( table->buckets ) - FT_ARRAY_ZERO( table->buckets, table->size ); - else - { - memory->free( memory, table ); - table = NULL; - } - - Exit: - return table; - } - - - static void - ft_mem_table_destroy( FT_MemTable table ) - { - FT_ULong i; - FT_Long leak_count = 0; - FT_ULong leaks = 0; - - - FT_DumpMemory( table->memory ); - - /* remove all blocks from the table, revealing leaked ones */ - for ( i = 0; i < table->size; i++ ) - { - FT_MemNode *pnode = table->buckets + i, next, node = *pnode; - - - while ( node ) - { - next = node->link; - node->link = 0; - - if ( node->size > 0 ) - { - printf( - "leaked memory block at address %p, size %8ld in (%s:%ld)\n", - node->address, node->size, - FT_FILENAME( node->source->file_name ), - node->source->line_no ); - - leak_count++; - leaks += node->size; - - ft_mem_table_free( table, node->address ); - } - - node->address = NULL; - node->size = 0; - - ft_mem_table_free( table, node ); - node = next; - } - table->buckets[i] = 0; - } - - ft_mem_table_free( table, table->buckets ); - table->buckets = NULL; - - table->size = 0; - table->nodes = 0; - - /* remove all sources */ - for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ ) - { - FT_MemSource source, next; - - - for ( source = table->sources[i]; source != NULL; source = next ) - { - next = source->link; - ft_mem_table_free( table, source ); - } - - table->sources[i] = NULL; - } - - printf( "FreeType: total memory allocations = %ld\n", - table->alloc_total ); - printf( "FreeType: maximum memory footprint = %ld\n", - table->alloc_max ); - - ft_mem_table_free( table, table ); - - if ( leak_count > 0 ) - ft_mem_debug_panic( - "FreeType: %ld bytes of memory leaked in %ld blocks\n", - leaks, leak_count ); - - printf( "FreeType: no memory leaks detected\n" ); - } - - - static FT_MemNode* - ft_mem_table_get_nodep( FT_MemTable table, - FT_Byte* address ) - { - FT_PtrDist hash; - FT_MemNode *pnode, node; - - - hash = FT_MEM_VAL( address ); - pnode = table->buckets + ( hash % table->size ); - - for (;;) - { - node = pnode[0]; - if ( !node ) - break; - - if ( node->address == address ) - break; - - pnode = &node->link; - } - return pnode; - } - - - static FT_MemSource - ft_mem_table_get_source( FT_MemTable table ) - { - FT_UInt32 hash; - FT_MemSource node, *pnode; - - - /* 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]; - - for ( ;; ) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( node->file_name == _ft_debug_file && - node->line_no == _ft_debug_lineno ) - goto Exit; - - pnode = &node->link; - } - - node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) - ft_mem_debug_panic( - "not enough memory to perform memory debugging\n" ); - - node->file_name = _ft_debug_file; - node->line_no = _ft_debug_lineno; - - node->cur_blocks = 0; - node->max_blocks = 0; - node->all_blocks = 0; - - node->cur_size = 0; - node->max_size = 0; - node->all_size = 0; - - node->cur_max = 0; - - node->link = NULL; - node->hash = hash; - *pnode = node; - - Exit: - return node; - } - - - static void - ft_mem_table_set( FT_MemTable table, - FT_Byte* address, - FT_ULong size, - FT_Long delta ) - { - FT_MemNode *pnode, node; - - - if ( table ) - { - FT_MemSource source; - - - pnode = ft_mem_table_get_nodep( table, address ); - node = *pnode; - if ( node ) - { - if ( node->size < 0 ) - { - /* This block was already freed. Our memory is now completely */ - /* corrupted! */ - /* This can only happen in keep-alive mode. */ - ft_mem_debug_panic( - "memory heap corrupted (allocating freed block)" ); - } - else - { - /* This block was already allocated. This means that our memory */ - /* is also corrupted! */ - ft_mem_debug_panic( - "memory heap corrupted (re-allocating allocated block at" - " %p, of size %ld)\n" - "org=%s:%d new=%s:%d\n", - node->address, node->size, - FT_FILENAME( node->source->file_name ), node->source->line_no, - FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); - } - } - - /* we need to create a new node in this table */ - node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) - ft_mem_debug_panic( "not enough memory to run memory tests" ); - - node->address = address; - node->size = size; - node->source = source = ft_mem_table_get_source( table ); - - if ( delta == 0 ) - { - /* this is an allocation */ - source->all_blocks++; - source->cur_blocks++; - if ( source->cur_blocks > source->max_blocks ) - source->max_blocks = source->cur_blocks; - } - - if ( size > (FT_ULong)source->cur_max ) - source->cur_max = size; - - if ( delta != 0 ) - { - /* we are growing or shrinking a reallocated block */ - source->cur_size += delta; - table->alloc_current += delta; - } - else - { - /* we are allocating a new block */ - source->cur_size += size; - table->alloc_current += size; - } - - source->all_size += size; - - if ( source->cur_size > source->max_size ) - source->max_size = source->cur_size; - - node->free_file_name = NULL; - node->free_line_no = 0; - - node->link = pnode[0]; - - pnode[0] = node; - table->nodes++; - - table->alloc_total += size; - - if ( table->alloc_current > table->alloc_max ) - table->alloc_max = table->alloc_current; - - if ( table->nodes * 3 < table->size || - table->size * 3 < table->nodes ) - ft_mem_table_resize( table ); - } - } - - - static void - ft_mem_table_remove( FT_MemTable table, - FT_Byte* address, - FT_Long delta ) - { - if ( table ) - { - FT_MemNode *pnode, node; - - - pnode = ft_mem_table_get_nodep( table, address ); - node = *pnode; - if ( node ) - { - FT_MemSource source; - - - if ( node->size < 0 ) - ft_mem_debug_panic( - "freeing memory block at %p more than once at (%s:%ld)\n" - "block allocated at (%s:%ld) and released at (%s:%ld)", - address, - FT_FILENAME( _ft_debug_file ), _ft_debug_lineno, - FT_FILENAME( node->source->file_name ), node->source->line_no, - FT_FILENAME( node->free_file_name ), node->free_line_no ); - - /* scramble the node's content for additional safety */ - FT_MEM_SET( address, 0xF3, node->size ); - - if ( delta == 0 ) - { - source = node->source; - - source->cur_blocks--; - source->cur_size -= node->size; - - table->alloc_current -= node->size; - } - - if ( table->keep_alive ) - { - /* we simply invert the node's size to indicate that the node */ - /* was freed. */ - node->size = -node->size; - node->free_file_name = _ft_debug_file; - node->free_line_no = _ft_debug_lineno; - } - else - { - table->nodes--; - - *pnode = node->link; - - node->size = 0; - node->source = NULL; - - ft_mem_table_free( table, node ); - - if ( table->nodes * 3 < table->size || - table->size * 3 < table->nodes ) - ft_mem_table_resize( table ); - } - } - else - ft_mem_debug_panic( - "trying to free unknown block at %p in (%s:%ld)\n", - address, - FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); - } - } - - - extern FT_Pointer - ft_mem_debug_alloc( FT_Memory memory, - FT_Long size ) - { - FT_MemTable table = (FT_MemTable)memory->user; - FT_Byte* block; - - - if ( size <= 0 ) - ft_mem_debug_panic( "negative block size allocation (%ld)", size ); - - /* return NULL if the maximum number of allocations was reached */ - if ( table->bound_count && - table->alloc_count >= table->alloc_count_max ) - return NULL; - - /* return NULL if this allocation would overflow the maximum heap size */ - if ( table->bound_total && - table->alloc_total_max - table->alloc_current > (FT_ULong)size ) - return NULL; - - block = (FT_Byte *)ft_mem_table_alloc( table, size ); - if ( block ) - { - ft_mem_table_set( table, block, (FT_ULong)size, 0 ); - - table->alloc_count++; - } - - _ft_debug_file = "<unknown>"; - _ft_debug_lineno = 0; - - return (FT_Pointer)block; - } - - - extern void - ft_mem_debug_free( FT_Memory memory, - FT_Pointer block ) - { - FT_MemTable table = (FT_MemTable)memory->user; - - - if ( block == NULL ) - ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", - FT_FILENAME( _ft_debug_file ), - _ft_debug_lineno ); - - ft_mem_table_remove( table, (FT_Byte*)block, 0 ); - - if ( !table->keep_alive ) - ft_mem_table_free( table, block ); - - table->alloc_count--; - - _ft_debug_file = "<unknown>"; - _ft_debug_lineno = 0; - } - - - extern FT_Pointer - ft_mem_debug_realloc( FT_Memory memory, - FT_Long cur_size, - FT_Long new_size, - FT_Pointer block ) - { - FT_MemTable table = (FT_MemTable)memory->user; - FT_MemNode node, *pnode; - FT_Pointer new_block; - FT_Long delta; - - const char* file_name = FT_FILENAME( _ft_debug_file ); - FT_Long line_no = _ft_debug_lineno; - - - /* unlikely, but possible */ - if ( new_size == cur_size ) - return block; - - /* the following is valid according to ANSI C */ -#if 0 - if ( block == NULL || cur_size == 0 ) - ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", - file_name, line_no ); -#endif - - /* while the following is allowed in ANSI C also, we abort since */ - /* such case should be handled by FreeType. */ - if ( new_size <= 0 ) - ft_mem_debug_panic( - "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)", - block, cur_size, file_name, line_no ); - - /* check `cur_size' value */ - pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block ); - node = *pnode; - if ( !node ) - ft_mem_debug_panic( - "trying to reallocate unknown block at %p in (%s:%ld)", - block, file_name, line_no ); - - if ( node->size <= 0 ) - ft_mem_debug_panic( - "trying to reallocate freed block at %p in (%s:%ld)", - block, file_name, line_no ); - - if ( node->size != cur_size ) - ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is " - "%ld instead of %ld in (%s:%ld)", - block, cur_size, node->size, file_name, line_no ); - - /* return NULL if the maximum number of allocations was reached */ - if ( table->bound_count && - table->alloc_count >= table->alloc_count_max ) - return NULL; - - delta = (FT_Long)( new_size - cur_size ); - - /* return NULL if this allocation would overflow the maximum heap size */ - if ( delta > 0 && - table->bound_total && - table->alloc_current + (FT_ULong)delta > table->alloc_total_max ) - return NULL; - - new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size ); - if ( new_block == NULL ) - return NULL; - - ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); - - ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); - - ft_mem_table_remove( table, (FT_Byte*)block, delta ); - - _ft_debug_file = "<unknown>"; - _ft_debug_lineno = 0; - - if ( !table->keep_alive ) - ft_mem_table_free( table, block ); - - return new_block; - } - - - extern FT_Int - ft_mem_debug_init( FT_Memory memory ) - { - FT_MemTable table; - FT_Int result = 0; - - - if ( getenv( "FT2_DEBUG_MEMORY" ) ) - { - table = ft_mem_table_new( memory ); - if ( table ) - { - const char* p; - - - memory->user = table; - memory->alloc = ft_mem_debug_alloc; - memory->realloc = ft_mem_debug_realloc; - memory->free = ft_mem_debug_free; - - p = getenv( "FT2_ALLOC_TOTAL_MAX" ); - if ( p != NULL ) - { - FT_Long total_max = ft_atol( p ); - - - if ( total_max > 0 ) - { - table->bound_total = 1; - table->alloc_total_max = (FT_ULong)total_max; - } - } - - p = getenv( "FT2_ALLOC_COUNT_MAX" ); - if ( p != NULL ) - { - FT_Long total_count = ft_atol( p ); - - - if ( total_count > 0 ) - { - table->bound_count = 1; - table->alloc_count_max = (FT_ULong)total_count; - } - } - - p = getenv( "FT2_KEEP_ALIVE" ); - if ( p != NULL ) - { - FT_Long keep_alive = ft_atol( p ); - - - if ( keep_alive > 0 ) - table->keep_alive = 1; - } - - result = 1; - } - } - return result; - } - - - extern void - ft_mem_debug_done( FT_Memory memory ) - { - FT_MemTable table = (FT_MemTable)memory->user; - - - if ( table ) - { - memory->free = table->free; - memory->realloc = table->realloc; - memory->alloc = table->alloc; - - ft_mem_table_destroy( table ); - memory->user = NULL; - } - } - - - - static int - ft_mem_source_compare( const void* p1, - const void* p2 ) - { - FT_MemSource s1 = *(FT_MemSource*)p1; - FT_MemSource s2 = *(FT_MemSource*)p2; - - - if ( s2->max_size > s1->max_size ) - return 1; - else if ( s2->max_size < s1->max_size ) - return -1; - else - return 0; - } - - - extern void - FT_DumpMemory( FT_Memory memory ) - { - FT_MemTable table = (FT_MemTable)memory->user; - - - if ( table ) - { - FT_MemSource* bucket = table->sources; - FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; - FT_MemSource* sources; - FT_UInt nn, count; - const char* fmt; - - - count = 0; - for ( ; bucket < limit; bucket++ ) - { - FT_MemSource source = *bucket; - - - for ( ; source; source = source->link ) - count++; - } - - sources = (FT_MemSource*)ft_mem_table_alloc( - table, sizeof ( *sources ) * count ); - - count = 0; - for ( bucket = table->sources; bucket < limit; bucket++ ) - { - FT_MemSource source = *bucket; - - - for ( ; source; source = source->link ) - sources[count++] = source; - } - - ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare ); - - printf( "FreeType Memory Dump: " - "current=%ld max=%ld total=%ld count=%ld\n", - table->alloc_current, table->alloc_max, - table->alloc_total, table->alloc_count ); - printf( " block block sizes sizes sizes source\n" ); - printf( " count high sum highsum max location\n" ); - printf( "-------------------------------------------------\n" ); - - fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n"; - - for ( nn = 0; nn < count; nn++ ) - { - FT_MemSource source = sources[nn]; - - - printf( fmt, - source->cur_blocks, source->max_blocks, - source->cur_size, source->max_size, source->cur_max, - FT_FILENAME( source->file_name ), - source->line_no ); - } - printf( "------------------------------------------------\n" ); - - ft_mem_table_free( table, sources ); - } - } - -#else /* !FT_DEBUG_MEMORY */ - - /* ANSI C doesn't like empty source files */ - typedef int _debug_mem_dummy; - -#endif /* !FT_DEBUG_MEMORY */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftdebug.c b/drivers/freetype/freetype/src/base/ftdebug.c deleted file mode 100644 index b9156d15ee..0000000000 --- a/drivers/freetype/freetype/src/base/ftdebug.c +++ /dev/null @@ -1,266 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdebug.c */ -/* */ -/* Debugging and logging component (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2004, 2008, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This component contains various macros and functions used to ease the */ - /* debugging of the FreeType engine. Its main purpose is in assertion */ - /* checking, tracing, and error detection. */ - /* */ - /* There are now three debugging modes: */ - /* */ - /* - trace mode */ - /* */ - /* Error and trace messages are sent to the log file (which can be the */ - /* standard error output). */ - /* */ - /* - error mode */ - /* */ - /* Only error messages are generated. */ - /* */ - /* - release mode: */ - /* */ - /* No error message is sent or generated. The code is free from any */ - /* debugging parts. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_DEBUG_H - - -#ifdef FT_DEBUG_LEVEL_ERROR - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( void ) - FT_Message( const char* fmt, - ... ) - { - va_list ap; - - - va_start( ap, fmt ); - vfprintf( stderr, fmt, ap ); - va_end( ap ); - } - - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( void ) - FT_Panic( const char* fmt, - ... ) - { - va_list ap; - - - va_start( ap, fmt ); - vfprintf( stderr, fmt, ap ); - va_end( ap ); - - exit( EXIT_FAILURE ); - } - - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( int ) - FT_Throw( FT_Error error, - int line, - const char* file ) - { - FT_UNUSED( error ); - FT_UNUSED( line ); - FT_UNUSED( file ); - - return 0; - } - -#endif /* FT_DEBUG_LEVEL_ERROR */ - - - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* array of trace levels, initialized to 0 */ - int ft_trace_levels[trace_count]; - - - /* define array of trace toggle names */ -#define FT_TRACE_DEF( x ) #x , - - static const char* ft_trace_toggles[trace_count + 1] = - { -#include FT_INTERNAL_TRACE_H - NULL - }; - -#undef FT_TRACE_DEF - - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( FT_Int ) - FT_Trace_Get_Count( void ) - { - return trace_count; - } - - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( const char * ) - FT_Trace_Get_Name( FT_Int idx ) - { - int max = FT_Trace_Get_Count(); - - - if ( idx < max ) - return ft_trace_toggles[idx]; - else - return NULL; - } - - - /*************************************************************************/ - /* */ - /* Initialize the tracing sub-system. This is done by retrieving the */ - /* value of the `FT2_DEBUG' environment variable. It must be a list of */ - /* toggles, separated by spaces, `;', or `,'. Example: */ - /* */ - /* export FT2_DEBUG="any:3 memory:7 stream:5" */ - /* */ - /* This requests that all levels be set to 3, except the trace level for */ - /* the memory and stream components which are set to 7 and 5, */ - /* respectively. */ - /* */ - /* See the file <include/freetype/internal/fttrace.h> for details of the */ - /* available toggle names. */ - /* */ - /* The level must be between 0 and 7; 0 means quiet (except for serious */ - /* runtime errors), and 7 means _very_ verbose. */ - /* */ - FT_BASE_DEF( void ) - ft_debug_init( void ) - { - const char* ft2_debug = getenv( "FT2_DEBUG" ); - - - if ( ft2_debug ) - { - const char* p = ft2_debug; - const char* q; - - - for ( ; *p; p++ ) - { - /* skip leading whitespace and separators */ - if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) - continue; - - /* read toggle name, followed by ':' */ - q = p; - while ( *p && *p != ':' ) - p++; - - if ( !*p ) - break; - - if ( *p == ':' && p > q ) - { - FT_Int n, i, len = (FT_Int)( p - q ); - FT_Int level = -1, found = -1; - - - for ( n = 0; n < trace_count; n++ ) - { - const char* toggle = ft_trace_toggles[n]; - - - for ( i = 0; i < len; i++ ) - { - if ( toggle[i] != q[i] ) - break; - } - - if ( i == len && toggle[i] == 0 ) - { - found = n; - break; - } - } - - /* read level */ - p++; - if ( *p ) - { - level = *p - '0'; - if ( level < 0 || level > 7 ) - level = -1; - } - - if ( found >= 0 && level >= 0 ) - { - if ( found == trace_any ) - { - /* special case for `any' */ - for ( n = 0; n < trace_count; n++ ) - ft_trace_levels[n] = level; - } - else - ft_trace_levels[found] = level; - } - } - } - } - } - - -#else /* !FT_DEBUG_LEVEL_TRACE */ - - - FT_BASE_DEF( void ) - ft_debug_init( void ) - { - /* nothing */ - } - - - FT_BASE_DEF( FT_Int ) - FT_Trace_Get_Count( void ) - { - return 0; - } - - - FT_BASE_DEF( const char * ) - FT_Trace_Get_Name( FT_Int idx ) - { - FT_UNUSED( idx ); - - return NULL; - } - - -#endif /* !FT_DEBUG_LEVEL_TRACE */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftfstype.c b/drivers/freetype/freetype/src/base/ftfstype.c deleted file mode 100644 index d0ef7b7c1b..0000000000 --- a/drivers/freetype/freetype/src/base/ftfstype.c +++ /dev/null @@ -1,62 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftfstype.c */ -/* */ -/* FreeType utility file to access FSType data (body). */ -/* */ -/* Copyright 2008, 2009 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_TYPE1_TABLES_H -#include FT_TRUETYPE_TABLES_H -#include FT_INTERNAL_SERVICE_H -#include FT_SERVICE_POSTSCRIPT_INFO_H - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UShort ) - FT_Get_FSType_Flags( FT_Face face ) - { - TT_OS2* os2; - - - /* first, try to get the fs_type directly from the font */ - if ( face ) - { - FT_Service_PsInfo service = NULL; - - - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - - if ( service && service->ps_get_font_extra ) - { - PS_FontExtraRec extra; - - - if ( !service->ps_get_font_extra( face, &extra ) && - extra.fs_type != 0 ) - return extra.fs_type; - } - } - - /* look at FSType before fsType for Type42 */ - - if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL && - os2->version != 0xFFFFU ) - return os2->fsType; - - return 0; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftgasp.c b/drivers/freetype/freetype/src/base/ftgasp.c deleted file mode 100644 index 8485d29259..0000000000 --- a/drivers/freetype/freetype/src/base/ftgasp.c +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************/ -/* */ -/* 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 */ diff --git a/drivers/freetype/freetype/src/base/ftgloadr.c b/drivers/freetype/freetype/src/base/ftgloadr.c deleted file mode 100644 index 3cc5c7a805..0000000000 --- a/drivers/freetype/freetype/src/base/ftgloadr.c +++ /dev/null @@ -1,405 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgloadr.c */ -/* */ -/* The FreeType glyph loader (body). */ -/* */ -/* Copyright 2002-2006, 2010, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_GLYPH_LOADER_H -#include FT_INTERNAL_MEMORY_H -#include FT_INTERNAL_OBJECTS_H - -#undef FT_COMPONENT -#define FT_COMPONENT trace_gloader - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** *****/ - /***** G L Y P H L O A D E R *****/ - /***** *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* The glyph loader is a simple object which is used to load a set of */ - /* glyphs easily. It is critical for the correct loading of composites. */ - /* */ - /* Ideally, one can see it as a stack of abstract `glyph' objects. */ - /* */ - /* loader.base Is really the bottom of the stack. It describes a */ - /* single glyph image made of the juxtaposition of */ - /* several glyphs (those `in the stack'). */ - /* */ - /* loader.current Describes the top of the stack, on which a new */ - /* glyph can be loaded. */ - /* */ - /* Rewind Clears the stack. */ - /* Prepare Set up `loader.current' for addition of a new glyph */ - /* image. */ - /* Add Add the `current' glyph image to the `base' one, */ - /* and prepare for another one. */ - /* */ - /* The glyph loader is now a base object. Each driver used to */ - /* re-implement it in one way or the other, which wasted code and */ - /* energy. */ - /* */ - /*************************************************************************/ - - - /* create a new glyph loader */ - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_New( FT_Memory memory, - FT_GlyphLoader *aloader ) - { - FT_GlyphLoader loader = NULL; - FT_Error error; - - - if ( !FT_NEW( loader ) ) - { - loader->memory = memory; - *aloader = loader; - } - return error; - } - - - /* rewind the glyph loader - reset counters to 0 */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Rewind( FT_GlyphLoader loader ) - { - FT_GlyphLoad base = &loader->base; - FT_GlyphLoad current = &loader->current; - - - base->outline.n_points = 0; - base->outline.n_contours = 0; - base->num_subglyphs = 0; - - *current = *base; - } - - - /* reset the glyph loader, frees all allocated tables */ - /* and starts from zero */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Reset( FT_GlyphLoader loader ) - { - FT_Memory memory = loader->memory; - - - FT_FREE( loader->base.outline.points ); - FT_FREE( loader->base.outline.tags ); - FT_FREE( loader->base.outline.contours ); - 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; - - FT_GlyphLoader_Rewind( loader ); - } - - - /* delete a glyph loader */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Done( FT_GlyphLoader loader ) - { - if ( loader ) - { - FT_Memory memory = loader->memory; - - - FT_GlyphLoader_Reset( loader ); - FT_FREE( loader ); - } - } - - - /* re-adjust the `current' outline fields */ - static void - FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader ) - { - FT_Outline* base = &loader->base.outline; - FT_Outline* current = &loader->current.outline; - - - current->points = base->points + base->n_points; - current->tags = base->tags + base->n_points; - current->contours = base->contours + base->n_contours; - - /* handle extra points table - if any */ - if ( loader->use_extra ) - { - loader->current.extra_points = loader->base.extra_points + - base->n_points; - - loader->current.extra_points2 = loader->base.extra_points2 + - base->n_points; - } - } - - - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ) - { - FT_Error error; - FT_Memory memory = loader->memory; - - - if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) ) - { - loader->use_extra = 1; - loader->base.extra_points2 = loader->base.extra_points + - loader->max_points; - - FT_GlyphLoader_Adjust_Points( loader ); - } - return error; - } - - - /* re-adjust the `current' subglyphs field */ - static void - FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader ) - { - FT_GlyphLoad base = &loader->base; - FT_GlyphLoad current = &loader->current; - - - current->subglyphs = base->subglyphs + base->num_subglyphs; - } - - - /* Ensure that we can add `n_points' and `n_contours' to our glyph. */ - /* This function reallocates its outline tables if necessary. Note that */ - /* it DOESN'T change the number of points within the loader! */ - /* */ - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, - FT_UInt n_points, - FT_UInt n_contours ) - { - FT_Memory memory = loader->memory; - FT_Error error = FT_Err_Ok; - FT_Outline* base = &loader->base.outline; - FT_Outline* current = &loader->current.outline; - FT_Bool adjust = 0; - - FT_UInt new_max, old_max; - - - /* check points & tags */ - new_max = base->n_points + current->n_points + n_points; - old_max = loader->max_points; - - if ( new_max > old_max ) - { - new_max = FT_PAD_CEIL( new_max, 8 ); - - if ( new_max > FT_OUTLINE_POINTS_MAX ) - return FT_THROW( Array_Too_Large ); - - if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || - FT_RENEW_ARRAY( base->tags, 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; - } - - /* check contours */ - old_max = loader->max_contours; - new_max = base->n_contours + current->n_contours + - n_contours; - if ( new_max > old_max ) - { - new_max = FT_PAD_CEIL( new_max, 4 ); - - if ( new_max > FT_OUTLINE_CONTOURS_MAX ) - return FT_THROW( Array_Too_Large ); - - if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) - goto Exit; - - adjust = 1; - loader->max_contours = new_max; - } - - if ( adjust ) - FT_GlyphLoader_Adjust_Points( loader ); - - Exit: - if ( error ) - FT_GlyphLoader_Reset( loader ); - - return error; - } - - - /* Ensure that we can add `n_subglyphs' to our glyph. this function */ - /* reallocates its subglyphs table if necessary. Note that it DOES */ - /* NOT change the number of subglyphs within the loader! */ - /* */ - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, - FT_UInt n_subs ) - { - FT_Memory memory = loader->memory; - FT_Error error = FT_Err_Ok; - FT_UInt new_max, old_max; - - FT_GlyphLoad base = &loader->base; - FT_GlyphLoad current = &loader->current; - - - new_max = base->num_subglyphs + current->num_subglyphs + n_subs; - old_max = loader->max_subglyphs; - if ( new_max > old_max ) - { - new_max = FT_PAD_CEIL( new_max, 2 ); - if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) ) - goto Exit; - - loader->max_subglyphs = new_max; - - FT_GlyphLoader_Adjust_Subglyphs( loader ); - } - - Exit: - return error; - } - - - /* prepare loader for the addition of a new glyph on top of the base one */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Prepare( FT_GlyphLoader loader ) - { - FT_GlyphLoad current = &loader->current; - - - current->outline.n_points = 0; - current->outline.n_contours = 0; - current->num_subglyphs = 0; - - FT_GlyphLoader_Adjust_Points ( loader ); - FT_GlyphLoader_Adjust_Subglyphs( loader ); - } - - - /* add current glyph to the base image -- and prepare for another */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Add( FT_GlyphLoader loader ) - { - FT_GlyphLoad base; - FT_GlyphLoad current; - - FT_UInt n_curr_contours; - FT_UInt n_base_points; - FT_UInt n; - - - if ( !loader ) - return; - - base = &loader->base; - current = &loader->current; - - n_curr_contours = current->outline.n_contours; - n_base_points = base->outline.n_points; - - base->outline.n_points = - (short)( base->outline.n_points + current->outline.n_points ); - base->outline.n_contours = - (short)( base->outline.n_contours + current->outline.n_contours ); - - base->num_subglyphs += current->num_subglyphs; - - /* adjust contours count in newest outline */ - for ( n = 0; n < n_curr_contours; n++ ) - current->outline.contours[n] = - (short)( current->outline.contours[n] + n_base_points ); - - /* prepare for another new glyph image */ - FT_GlyphLoader_Prepare( loader ); - } - - - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, - FT_GlyphLoader source ) - { - FT_Error error; - FT_UInt num_points = source->base.outline.n_points; - FT_UInt num_contours = source->base.outline.n_contours; - - - error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); - if ( !error ) - { - FT_Outline* out = &target->base.outline; - FT_Outline* in = &source->base.outline; - - - FT_ARRAY_COPY( out->points, in->points, - num_points ); - FT_ARRAY_COPY( out->tags, in->tags, - num_points ); - FT_ARRAY_COPY( out->contours, in->contours, - num_contours ); - - /* 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; - - FT_GlyphLoader_Adjust_Points( target ); - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftglyph.c b/drivers/freetype/freetype/src/base/ftglyph.c deleted file mode 100644 index 5dd28a8c52..0000000000 --- a/drivers/freetype/freetype/src/base/ftglyph.c +++ /dev/null @@ -1,629 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftglyph.c */ -/* */ -/* FreeType convenience functions to handle glyphs (body). */ -/* */ -/* Copyright 1996-2005, 2007, 2008, 2010, 2012, 2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file contains the definition of several convenience functions */ - /* that can be used by client applications to easily retrieve glyph */ - /* bitmaps and outlines from a given face. */ - /* */ - /* These functions should be optional if you are writing a font server */ - /* or text layout engine on top of FreeType. However, they are pretty */ - /* handy for many other simple uses of the library. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_GLYPH_H -#include FT_OUTLINE_H -#include FT_BITMAP_H -#include FT_INTERNAL_OBJECTS_H - -#include "basepic.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_glyph - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_BitmapGlyph support ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_CALLBACK_DEF( FT_Error ) - ft_bitmap_glyph_init( FT_Glyph bitmap_glyph, - FT_GlyphSlot slot ) - { - FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - FT_Error error = FT_Err_Ok; - FT_Library library = FT_GLYPH( glyph )->library; - - - if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) - { - error = FT_THROW( Invalid_Glyph_Format ); - goto Exit; - } - - glyph->left = slot->bitmap_left; - glyph->top = slot->bitmap_top; - - /* do lazy copying whenever possible */ - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { - glyph->bitmap = slot->bitmap; - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - else - { - FT_Bitmap_New( &glyph->bitmap ); - error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap ); - } - - Exit: - return error; - } - - - FT_CALLBACK_DEF( FT_Error ) - ft_bitmap_glyph_copy( FT_Glyph bitmap_source, - FT_Glyph bitmap_target ) - { - FT_Library library = bitmap_source->library; - FT_BitmapGlyph source = (FT_BitmapGlyph)bitmap_source; - FT_BitmapGlyph target = (FT_BitmapGlyph)bitmap_target; - - - target->left = source->left; - target->top = source->top; - - return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap ); - } - - - FT_CALLBACK_DEF( void ) - ft_bitmap_glyph_done( FT_Glyph bitmap_glyph ) - { - FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - FT_Library library = FT_GLYPH( glyph )->library; - - - FT_Bitmap_Done( library, &glyph->bitmap ); - } - - - FT_CALLBACK_DEF( void ) - ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph, - FT_BBox* cbox ) - { - FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - - - cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); - cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); - } - - - FT_DEFINE_GLYPH(ft_bitmap_glyph_class, - sizeof ( FT_BitmapGlyphRec ), - FT_GLYPH_FORMAT_BITMAP, - - ft_bitmap_glyph_init, - ft_bitmap_glyph_done, - ft_bitmap_glyph_copy, - 0, /* FT_Glyph_TransformFunc */ - ft_bitmap_glyph_bbox, - 0 /* FT_Glyph_PrepareFunc */ - ) - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_OutlineGlyph support ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - ft_outline_glyph_init( FT_Glyph outline_glyph, - FT_GlyphSlot slot ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - FT_Error error = FT_Err_Ok; - FT_Library library = FT_GLYPH( glyph )->library; - FT_Outline* source = &slot->outline; - FT_Outline* target = &glyph->outline; - - - /* check format in glyph slot */ - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) - { - error = FT_THROW( Invalid_Glyph_Format ); - goto Exit; - } - - /* allocate new outline */ - error = FT_Outline_New( library, source->n_points, source->n_contours, - &glyph->outline ); - if ( error ) - goto Exit; - - FT_Outline_Copy( source, target ); - - Exit: - return error; - } - - - FT_CALLBACK_DEF( void ) - ft_outline_glyph_done( FT_Glyph outline_glyph ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - - - FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline ); - } - - - FT_CALLBACK_DEF( FT_Error ) - ft_outline_glyph_copy( FT_Glyph outline_source, - FT_Glyph outline_target ) - { - FT_OutlineGlyph source = (FT_OutlineGlyph)outline_source; - FT_OutlineGlyph target = (FT_OutlineGlyph)outline_target; - FT_Error error; - FT_Library library = FT_GLYPH( source )->library; - - - error = FT_Outline_New( library, source->outline.n_points, - source->outline.n_contours, &target->outline ); - if ( !error ) - FT_Outline_Copy( &source->outline, &target->outline ); - - return error; - } - - - FT_CALLBACK_DEF( void ) - ft_outline_glyph_transform( FT_Glyph outline_glyph, - const FT_Matrix* matrix, - const FT_Vector* delta ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - - - if ( matrix ) - FT_Outline_Transform( &glyph->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &glyph->outline, delta->x, delta->y ); - } - - - FT_CALLBACK_DEF( void ) - ft_outline_glyph_bbox( FT_Glyph outline_glyph, - FT_BBox* bbox ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - - - FT_Outline_Get_CBox( &glyph->outline, bbox ); - } - - - FT_CALLBACK_DEF( FT_Error ) - ft_outline_glyph_prepare( FT_Glyph outline_glyph, - FT_GlyphSlot slot ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - - - slot->format = FT_GLYPH_FORMAT_OUTLINE; - slot->outline = glyph->outline; - slot->outline.flags &= ~FT_OUTLINE_OWNER; - - return FT_Err_Ok; - } - - - FT_DEFINE_GLYPH( ft_outline_glyph_class, - sizeof ( FT_OutlineGlyphRec ), - FT_GLYPH_FORMAT_OUTLINE, - - ft_outline_glyph_init, - ft_outline_glyph_done, - ft_outline_glyph_copy, - ft_outline_glyph_transform, - ft_outline_glyph_bbox, - ft_outline_glyph_prepare - ) - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_Glyph class and API ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_Error - ft_new_glyph( FT_Library library, - const FT_Glyph_Class* clazz, - FT_Glyph* aglyph ) - { - FT_Memory memory = library->memory; - FT_Error error; - FT_Glyph glyph = NULL; - - - *aglyph = 0; - - if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) - { - glyph->library = library; - glyph->clazz = clazz; - glyph->format = clazz->glyph_format; - - *aglyph = glyph; - } - - return error; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_Copy( FT_Glyph source, - FT_Glyph *target ) - { - FT_Glyph copy; - FT_Error error; - const FT_Glyph_Class* clazz; - - - /* check arguments */ - if ( !target ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - *target = 0; - - if ( !source || !source->clazz ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - clazz = source->clazz; - error = ft_new_glyph( source->library, clazz, © ); - if ( error ) - goto Exit; - - copy->advance = source->advance; - copy->format = source->format; - - if ( clazz->glyph_copy ) - error = clazz->glyph_copy( source, copy ); - - if ( error ) - FT_Done_Glyph( copy ); - else - *target = copy; - - Exit: - return error; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Glyph( FT_GlyphSlot slot, - FT_Glyph *aglyph ) - { - FT_Library library; - FT_Error error; - FT_Glyph glyph; - - const FT_Glyph_Class* clazz = 0; - - - if ( !slot ) - return FT_THROW( Invalid_Slot_Handle ); - - library = slot->library; - - if ( !aglyph ) - return FT_THROW( Invalid_Argument ); - - /* if it is a bitmap, that's easy :-) */ - if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - clazz = FT_BITMAP_GLYPH_CLASS_GET; - - /* if it is an outline */ - else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - clazz = FT_OUTLINE_GLYPH_CLASS_GET; - - else - { - /* try to find a renderer that supports the glyph image format */ - FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); - - - if ( render ) - clazz = &render->glyph_class; - } - - if ( !clazz ) - { - error = FT_THROW( Invalid_Glyph_Format ); - goto Exit; - } - - /* create FT_Glyph object */ - error = ft_new_glyph( library, clazz, &glyph ); - if ( error ) - goto Exit; - - /* copy advance while converting it to 16.16 format */ - glyph->advance.x = slot->advance.x << 10; - glyph->advance.y = slot->advance.y << 10; - - /* now import the image from the glyph slot */ - error = clazz->glyph_init( glyph, slot ); - - /* if an error occurred, destroy the glyph */ - if ( error ) - FT_Done_Glyph( glyph ); - else - *aglyph = glyph; - - Exit: - return error; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_Transform( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ) - { - const FT_Glyph_Class* clazz; - FT_Error error = FT_Err_Ok; - - - if ( !glyph || !glyph->clazz ) - error = FT_THROW( Invalid_Argument ); - else - { - clazz = glyph->clazz; - if ( clazz->glyph_transform ) - { - /* transform glyph image */ - clazz->glyph_transform( glyph, matrix, delta ); - - /* transform advance vector */ - if ( matrix ) - FT_Vector_Transform( &glyph->advance, matrix ); - } - else - error = FT_THROW( Invalid_Glyph_Format ); - } - return error; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Glyph_Get_CBox( FT_Glyph glyph, - FT_UInt bbox_mode, - FT_BBox *acbox ) - { - const FT_Glyph_Class* clazz; - - - if ( !acbox ) - return; - - acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0; - - if ( !glyph || !glyph->clazz ) - return; - else - { - clazz = glyph->clazz; - if ( !clazz->glyph_bbox ) - return; - else - { - /* retrieve bbox in 26.6 coordinates */ - clazz->glyph_bbox( glyph, acbox ); - - /* perform grid fitting if needed */ - if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || - bbox_mode == FT_GLYPH_BBOX_PIXELS ) - { - acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); - acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); - acbox->xMax = FT_PIX_CEIL( acbox->xMax ); - acbox->yMax = FT_PIX_CEIL( acbox->yMax ); - } - - /* convert to integer pixels if needed */ - if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || - bbox_mode == FT_GLYPH_BBOX_PIXELS ) - { - acbox->xMin >>= 6; - acbox->yMin >>= 6; - acbox->xMax >>= 6; - acbox->yMax >>= 6; - } - } - } - return; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, - FT_Render_Mode render_mode, - FT_Vector* origin, - FT_Bool destroy ) - { - FT_GlyphSlotRec dummy; - FT_GlyphSlot_InternalRec dummy_internal; - FT_Error error = FT_Err_Ok; - FT_Glyph b, glyph; - FT_BitmapGlyph bitmap = NULL; - const FT_Glyph_Class* clazz; - - /* FT_BITMAP_GLYPH_CLASS_GET derefers `library' in PIC mode */ - FT_Library library; - - - /* check argument */ - if ( !the_glyph ) - goto Bad; - glyph = *the_glyph; - if ( !glyph ) - goto Bad; - - clazz = glyph->clazz; - library = glyph->library; - if ( !library || !clazz ) - goto Bad; - - /* when called with a bitmap glyph, do nothing and return successfully */ - if ( clazz == FT_BITMAP_GLYPH_CLASS_GET ) - goto Exit; - - if ( !clazz->glyph_prepare ) - goto Bad; - - /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ - /* then calling FT_Render_Glyph_Internal() */ - - FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); - FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); - dummy.internal = &dummy_internal; - dummy.library = library; - dummy.format = clazz->glyph_format; - - /* create result bitmap glyph */ - error = ft_new_glyph( library, FT_BITMAP_GLYPH_CLASS_GET, &b ); - if ( error ) - goto Exit; - bitmap = (FT_BitmapGlyph)b; - -#if 1 - /* if `origin' is set, translate the glyph image */ - if ( origin ) - FT_Glyph_Transform( glyph, 0, origin ); -#else - FT_UNUSED( origin ); -#endif - - /* prepare dummy slot for rendering */ - error = clazz->glyph_prepare( glyph, &dummy ); - if ( !error ) - error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); - -#if 1 - if ( !destroy && origin ) - { - FT_Vector v; - - - v.x = -origin->x; - v.y = -origin->y; - FT_Glyph_Transform( glyph, 0, &v ); - } -#endif - - if ( error ) - goto Exit; - - /* in case of success, copy the bitmap to the glyph bitmap */ - error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy ); - if ( error ) - goto Exit; - - /* copy advance */ - bitmap->root.advance = glyph->advance; - - if ( destroy ) - FT_Done_Glyph( glyph ); - - *the_glyph = FT_GLYPH( bitmap ); - - Exit: - if ( error && bitmap ) - FT_Done_Glyph( FT_GLYPH( bitmap ) ); - - return error; - - Bad: - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Done_Glyph( FT_Glyph glyph ) - { - if ( glyph ) - { - FT_Memory memory = glyph->library->memory; - const FT_Glyph_Class* clazz = glyph->clazz; - - - if ( clazz->glyph_done ) - clazz->glyph_done( glyph ); - - FT_FREE( glyph ); - } - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftgxval.c b/drivers/freetype/freetype/src/base/ftgxval.c deleted file mode 100644 index a8ec44ac00..0000000000 --- a/drivers/freetype/freetype/src/base/ftgxval.c +++ /dev/null @@ -1,142 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgxval.c */ -/* */ -/* FreeType API for validating TrueTyepGX/AAT tables (body). */ -/* */ -/* Copyright 2004-2006, 2010, 2013 by */ -/* Masatake YAMATO, Redhat K.K, */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_GX_VALIDATE_H - - - /* documentation is in ftgxval.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_TrueTypeGX_Validate( FT_Face face, - FT_UInt validation_flags, - FT_Bytes tables[FT_VALIDATE_GX_LENGTH], - FT_UInt table_length ) - { - FT_Service_GXvalidate service; - FT_Error error; - - - if ( !face ) - { - error = FT_THROW( Invalid_Face_Handle ); - goto Exit; - } - - if ( tables == NULL ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - FT_FACE_FIND_GLOBAL_SERVICE( face, service, GX_VALIDATE ); - - if ( service ) - error = service->validate( face, - validation_flags, - tables, - table_length ); - else - error = FT_THROW( Unimplemented_Feature ); - - Exit: - return error; - } - - - FT_EXPORT_DEF( void ) - FT_TrueTypeGX_Free( FT_Face face, - FT_Bytes table ) - { - FT_Memory memory; - - - if ( !face ) - return; - - memory = FT_FACE_MEMORY( face ); - - FT_FREE( table ); - } - - - FT_EXPORT_DEF( FT_Error ) - FT_ClassicKern_Validate( FT_Face face, - FT_UInt validation_flags, - FT_Bytes *ckern_table ) - { - FT_Service_CKERNvalidate service; - FT_Error error; - - - if ( !face ) - { - error = FT_THROW( Invalid_Face_Handle ); - goto Exit; - } - - if ( ckern_table == NULL ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - FT_FACE_FIND_GLOBAL_SERVICE( face, service, CLASSICKERN_VALIDATE ); - - if ( service ) - error = service->validate( face, - validation_flags, - ckern_table ); - else - error = FT_THROW( Unimplemented_Feature ); - - Exit: - return error; - } - - - FT_EXPORT_DEF( void ) - FT_ClassicKern_Free( FT_Face face, - FT_Bytes table ) - { - FT_Memory memory; - - - if ( !face ) - return; - - memory = FT_FACE_MEMORY( face ); - - - FT_FREE( table ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftinit.c b/drivers/freetype/freetype/src/base/ftinit.c deleted file mode 100644 index 85f321fd2d..0000000000 --- a/drivers/freetype/freetype/src/base/ftinit.c +++ /dev/null @@ -1,282 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftinit.c */ -/* */ -/* FreeType initialization layer (body). */ -/* */ -/* Copyright 1996-2002, 2005, 2007, 2009, 2012, 2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* The purpose of this file is to implement the following two */ - /* functions: */ - /* */ - /* FT_Add_Default_Modules(): */ - /* This function is used to add the set of default modules to a */ - /* fresh new library object. The set is taken from the header file */ - /* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */ - /* Build System' for more information. */ - /* */ - /* FT_Init_FreeType(): */ - /* This function creates a system object for the current platform, */ - /* builds a library out of it, then calls FT_Default_Drivers(). */ - /* */ - /* Note that even if FT_Init_FreeType() uses the implementation of the */ - /* system object defined at build time, client applications are still */ - /* able to provide their own `ftsystem.c'. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_MODULE_H -#include "basepic.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_init - - -#ifndef FT_CONFIG_OPTION_PIC - - -#undef FT_USE_MODULE -#ifdef __cplusplus -#define FT_USE_MODULE( type, x ) extern "C" const type x; -#else -#define FT_USE_MODULE( type, x ) extern const type x; -#endif - -#include FT_CONFIG_MODULES_H - -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) (const FT_Module_Class*)&(x), - - static - const FT_Module_Class* const ft_default_modules[] = - { -#include FT_CONFIG_MODULES_H - 0 - }; - - -#else /* FT_CONFIG_OPTION_PIC */ - - -#ifdef __cplusplus -#define FT_EXTERNC extern "C" -#else -#define FT_EXTERNC extern -#endif - - /* declare the module's class creation/destruction functions */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) \ - FT_EXTERNC FT_Error \ - FT_Create_Class_ ## x( FT_Library library, \ - FT_Module_Class* *output_class ); \ - FT_EXTERNC void \ - FT_Destroy_Class_ ## x( FT_Library library, \ - FT_Module_Class* clazz ); - -#include FT_CONFIG_MODULES_H - - /* count all module classes */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) MODULE_CLASS_ ## x, - - enum - { -#include FT_CONFIG_MODULES_H - FT_NUM_MODULE_CLASSES - }; - - /* destroy all module classes */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) \ - if ( classes[i] ) \ - { \ - FT_Destroy_Class_ ## x( library, classes[i] ); \ - } \ - i++; - - - FT_BASE_DEF( void ) - ft_destroy_default_module_classes( FT_Library library ) - { - FT_Module_Class* *classes; - FT_Memory memory; - FT_UInt i; - BasePIC* pic_container = (BasePIC*)library->pic_container.base; - - - if ( !pic_container->default_module_classes ) - return; - - memory = library->memory; - classes = pic_container->default_module_classes; - i = 0; - -#include FT_CONFIG_MODULES_H - - FT_FREE( classes ); - pic_container->default_module_classes = 0; - } - - - /* initialize all module classes and the pointer table */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) \ - error = FT_Create_Class_ ## x( library, &clazz ); \ - if ( error ) \ - goto Exit; \ - classes[i++] = clazz; - - - FT_BASE_DEF( FT_Error ) - ft_create_default_module_classes( FT_Library library ) - { - FT_Error error; - FT_Memory memory; - FT_Module_Class* *classes = NULL; - FT_Module_Class* clazz; - FT_UInt i; - BasePIC* pic_container = (BasePIC*)library->pic_container.base; - - - memory = library->memory; - - pic_container->default_module_classes = 0; - - if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) * - ( FT_NUM_MODULE_CLASSES + 1 ) ) ) - return error; - - /* initialize all pointers to 0, especially the last one */ - for ( i = 0; i < FT_NUM_MODULE_CLASSES; i++ ) - classes[i] = 0; - classes[FT_NUM_MODULE_CLASSES] = 0; - - i = 0; - -#include FT_CONFIG_MODULES_H - - Exit: - if ( error ) - ft_destroy_default_module_classes( library ); - else - pic_container->default_module_classes = classes; - - return error; - } - - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( void ) - FT_Add_Default_Modules( FT_Library library ) - { - FT_Error error; - const FT_Module_Class* const* cur; - - - /* FT_DEFAULT_MODULES_GET dereferences `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - if ( !library ) - return; -#endif - - /* GCC 4.6 warns the type difference: - * FT_Module_Class** != const FT_Module_Class* const* - */ - cur = (const FT_Module_Class* const*)FT_DEFAULT_MODULES_GET; - - /* test for valid `library' delayed to FT_Add_Module() */ - while ( *cur ) - { - error = FT_Add_Module( library, *cur ); - /* notify errors, but don't stop */ - if ( error ) - FT_TRACE0(( "FT_Add_Default_Module:" - " Cannot install `%s', error = 0x%x\n", - (*cur)->module_name, error )); - cur++; - } - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Init_FreeType( FT_Library *alibrary ) - { - FT_Error error; - FT_Memory memory; - - - /* First of all, allocate a new system object -- this function is part */ - /* of the system-specific component, i.e. `ftsystem.c'. */ - - memory = FT_New_Memory(); - if ( !memory ) - { - FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" )); - return FT_THROW( Unimplemented_Feature ); - } - - /* build a library out of it, then fill it with the set of */ - /* default drivers. */ - - error = FT_New_Library( memory, alibrary ); - if ( error ) - FT_Done_Memory( memory ); - else - FT_Add_Default_Modules( *alibrary ); - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Done_FreeType( FT_Library library ) - { - if ( library ) - { - FT_Memory memory = library->memory; - - - /* Discard the library object */ - FT_Done_Library( library ); - - /* discard memory manager */ - FT_Done_Memory( memory ); - } - - return FT_Err_Ok; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftlcdfil.c b/drivers/freetype/freetype/src/base/ftlcdfil.c deleted file mode 100644 index 852fb32982..0000000000 --- a/drivers/freetype/freetype/src/base/ftlcdfil.c +++ /dev/null @@ -1,378 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlcdfil.c */ -/* */ -/* FreeType API for color filtering of subpixel bitmap glyphs (body). */ -/* */ -/* Copyright 2006, 2008-2010, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_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 - - /* intra-pixel filter used by the legacy filter */ - 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 intra-pixel 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_DEF( FT_Error ) - FT_Library_SetLcdFilterWeights( FT_Library library, - unsigned char *weights ) - { - if ( !library || !weights ) - return FT_THROW( Invalid_Argument ); - - ft_memcpy( library->lcd_weights, weights, 5 ); - - return FT_Err_Ok; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_Library_SetLcdFilter( FT_Library library, - FT_LcdFilter filter ) - { - static const FT_Byte light_filter[5] = - { 0x00, 0x55, 0x56, 0x55, 0x00 }; - /* 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 ) - return FT_THROW( 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 ) - - ft_memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#else - - ft_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: - ft_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_THROW( Invalid_Argument ); - } - - library->lcd_filter = filter; - - return FT_Err_Ok; - } - -#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - FT_EXPORT_DEF( FT_Error ) - FT_Library_SetLcdFilterWeights( FT_Library library, - unsigned char *weights ) - { - FT_UNUSED( library ); - FT_UNUSED( weights ); - - return FT_THROW( Unimplemented_Feature ); - } - - - FT_EXPORT_DEF( FT_Error ) - FT_Library_SetLcdFilter( FT_Library library, - FT_LcdFilter filter ) - { - FT_UNUSED( library ); - FT_UNUSED( filter ); - - return FT_THROW( Unimplemented_Feature ); - } - -#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftmac.c b/drivers/freetype/freetype/src/base/ftmac.c deleted file mode 100644 index 5b5aae61cc..0000000000 --- a/drivers/freetype/freetype/src/base/ftmac.c +++ /dev/null @@ -1,1061 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmac.c */ -/* */ -/* Mac FOND support. Written by just@letterror.com. */ -/* 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-2009, 2013 by */ -/* Just van Rossum, 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. */ -/* */ -/***************************************************************************/ - - - /* - Notes - - Mac suitcase files can (and often do!) contain multiple fonts. To - support this I use the face_index argument of FT_(Open|New)_Face() - functions, and pretend the suitcase file is a collection. - - Warning: fbit and NFNT bitmap resources are not supported yet. In old - sfnt fonts, bitmap glyph data for each size is stored in each `NFNT' - resources instead of the `bdat' table in the sfnt resource. Therefore, - face->num_fixed_sizes is set to 0, because bitmap data in `NFNT' - resource is unavailable at present. - - The Mac FOND support works roughly like this: - - - Check whether the offered stream points to a Mac suitcase file. This - is done by checking the file type: it has to be 'FFIL' or 'tfil'. The - stream that gets passed to our init_face() routine is a stdio stream, - which isn't usable for us, since the FOND resources live in the - resource fork. So we just grab the stream->pathname field. - - - Read the FOND resource into memory, then check whether there is a - TrueType font and/or(!) a Type 1 font available. - - - If there is a Type 1 font available (as a separate `LWFN' file), read - its data into memory, massage it slightly so it becomes PFB data, wrap - it into a memory stream, load the Type 1 driver and delegate the rest - of the work to it by calling FT_Open_Face(). (XXX TODO: after this - has been done, the kerning data from the FOND resource should be - appended to the face: On the Mac there are usually no AFM files - available. However, this is tricky since we need to map Mac char - codes to ps glyph names to glyph ID's...) - - - 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. - */ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_TRUETYPE_TAGS_H -#include FT_INTERNAL_STREAM_H -#include "ftbase.h" - - /* This is for Mac OS X. Without redefinition, OS_INLINE */ - /* expands to `static inline' which doesn't survive the */ - /* -ansi compilation flag of GCC. */ -#if !HAVE_ANSI_OS_INLINE -#undef OS_INLINE -#define OS_INLINE static __inline__ -#endif - - /* `configure' checks the availability of `ResourceIndex' strictly */ - /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always. If it is */ - /* not set (e.g., a build without `configure'), the availability */ - /* is guessed from the SDK version. */ -#ifndef HAVE_TYPE_RESOURCE_INDEX -#if !defined( MAC_OS_X_VERSION_10_5 ) || \ - ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 ) -#define HAVE_TYPE_RESOURCE_INDEX 0 -#else -#define HAVE_TYPE_RESOURCE_INDEX 1 -#endif -#endif /* !HAVE_TYPE_RESOURCE_INDEX */ - -#if ( HAVE_TYPE_RESOURCE_INDEX == 0 ) - typedef short ResourceIndex; -#endif - -#include <CoreServices/CoreServices.h> -#include <ApplicationServices/ApplicationServices.h> -#include <sys/syslimits.h> /* PATH_MAX */ - - /* Don't want warnings about our own use of deprecated functions. */ -#define FT_DEPRECATED_ATTRIBUTE - -#include FT_MAC_H - -#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */ -#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault -#endif - - - /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over - TrueType in case *both* are available (this is not common, - but it *is* possible). */ -#ifndef PREFER_LWFN -#define PREFER_LWFN 1 -#endif - - -#ifdef FT_MACINTOSH - - /* This function is deprecated because FSSpec is deprecated in Mac OS X */ - FT_EXPORT_DEF( FT_Error ) - FT_GetFile_From_Mac_Name( const char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) - { - FT_UNUSED( fontName ); - FT_UNUSED( pathSpec ); - FT_UNUSED( face_index ); - - return FT_THROW( Unimplemented_Feature ); - } - - - /* Private function. */ - /* The FSSpec type has been discouraged for a long time, */ - /* unfortunately an FSRef replacement API for */ - /* ATSFontGetFileSpecification() is only available in */ - /* Mac OS X 10.5 and later. */ - static OSStatus - FT_ATSFontGetFileReference( ATSFontRef ats_font_id, - FSRef* ats_font_ref ) - { -#if defined( MAC_OS_X_VERSION_10_5 ) && \ - ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) - - OSStatus err; - - err = ATSFontGetFileReference( ats_font_id, ats_font_ref ); - - return err; -#elif __LP64__ /* No 64bit Carbon API on legacy platforms */ - FT_UNUSED( ats_font_id ); - FT_UNUSED( ats_font_ref ); - - - return fnfErr; -#else /* 32bit Carbon API on legacy platforms */ - OSStatus err; - FSSpec spec; - - - err = ATSFontGetFileSpecification( ats_font_id, &spec ); - if ( noErr == err ) - err = FSpMakeFSRef( &spec, ats_font_ref ); - - return err; -#endif - } - - - static FT_Error - FT_GetFileRef_From_Mac_ATS_Name( const char* fontName, - FSRef* ats_font_ref, - FT_Long* face_index ) - { - CFStringRef cf_fontName; - ATSFontRef ats_font_id; - - - *face_index = 0; - - cf_fontName = CFStringCreateWithCString( NULL, fontName, - kCFStringEncodingMacRoman ); - ats_font_id = ATSFontFindFromName( cf_fontName, - kATSOptionFlagsUnRestrictedScope ); - CFRelease( cf_fontName ); - - if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL ) - return FT_THROW( Unknown_File_Format ); - - if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) ) - return FT_THROW( Unknown_File_Format ); - - /* face_index calculation by searching preceding fontIDs */ - /* with same FSRef */ - { - ATSFontRef id2 = ats_font_id - 1; - FSRef ref2; - - - while ( id2 > 0 ) - { - if ( noErr != FT_ATSFontGetFileReference( id2, &ref2 ) ) - break; - if ( noErr != FSCompareFSRefs( ats_font_ref, &ref2 ) ) - break; - - id2 --; - } - *face_index = ats_font_id - ( id2 + 1 ); - } - - return FT_Err_Ok; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, - UInt8* path, - UInt32 maxPathSize, - FT_Long* face_index ) - { - FSRef ref; - FT_Error err; - - - err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); - if ( err ) - return err; - - if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) ) - return FT_THROW( Unknown_File_Format ); - - return FT_Err_Ok; - } - - - /* This function is deprecated because FSSpec is deprecated in Mac OS X */ - FT_EXPORT_DEF( FT_Error ) - FT_GetFile_From_Mac_ATS_Name( const char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) - { -#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ - ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) - FT_UNUSED( fontName ); - FT_UNUSED( pathSpec ); - FT_UNUSED( face_index ); - - return FT_THROW( Unimplemented_Feature ); -#else - FSRef ref; - FT_Error err; - - - err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); - if ( err ) - return err; - - if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, - pathSpec, NULL ) ) - return FT_THROW( Unknown_File_Format ); - - return FT_Err_Ok; -#endif - } - - - static OSErr - FT_FSPathMakeRes( const UInt8* pathname, - ResFileRefNum* res ) - { - OSErr err; - FSRef ref; - - - if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) - return FT_THROW( Cannot_Open_Resource ); - - /* at present, no support for dfont format */ - err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res ); - if ( noErr == err ) - return err; - - /* fallback to original resource-fork font */ - *res = FSOpenResFile( &ref, fsRdPerm ); - err = ResError(); - - return err; - } - - - /* Return the file type for given pathname */ - static OSType - get_file_type_from_path( const UInt8* pathname ) - { - FSRef ref; - FSCatalogInfo info; - - - if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) - return ( OSType ) 0; - - if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info, - NULL, NULL, NULL ) ) - return ( OSType ) 0; - - return ((FInfo *)(info.finderInfo))->fdType; - } - - - /* Given a PostScript font name, create the Macintosh LWFN file name. */ - static void - create_lwfn_name( char* ps_name, - Str255 lwfn_file_name ) - { - int max = 5, count = 0; - FT_Byte* p = lwfn_file_name; - FT_Byte* q = (FT_Byte*)ps_name; - - - lwfn_file_name[0] = 0; - - while ( *q ) - { - if ( ft_isupper( *q ) ) - { - if ( count ) - max = 3; - count = 0; - } - if ( count < max && ( ft_isalnum( *q ) || *q == '_' ) ) - { - *++p = *q; - lwfn_file_name[0]++; - count++; - } - q++; - } - } - - - static short - count_faces_sfnt( char* fond_data ) - { - /* The count is 1 greater than the value in the FOND. */ - /* Isn't that cute? :-) */ - - return EndianS16_BtoN( *( (short*)( fond_data + - sizeof ( FamRec ) ) ) ) + 1; - } - - - static short - count_faces_scalable( char* fond_data ) - { - AsscEntry* assoc; - short i, face, face_all; - - - 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 == EndianS16_BtoN( assoc[i].fontSize ) ) - face++; - } - return face; - } - - - /* Look inside the FOND data, answer whether there should be an SFNT - resource, and answer the name of a possible LWFN Type 1 file. - - Thanks to Paul Miller (paulm@profoundeffects.com) for the fix - to load a face OTHER than the first one in the FOND! - */ - - - static void - parse_fond( char* fond_data, - short* have_sfnt, - ResID* sfnt_id, - Str255 lwfn_file_name, - short face_index ) - { - AsscEntry* assoc; - AsscEntry* base_assoc; - FamRec* fond; - - - *sfnt_id = 0; - *have_sfnt = 0; - lwfn_file_name[0] = 0; - - fond = (FamRec*)fond_data; - assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); - base_assoc = assoc; - - /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */ - if ( 47 < face_index ) - return; - - /* Let's do a little range checking before we get too excited here */ - if ( face_index < count_faces_sfnt( fond_data ) ) - { - assoc += face_index; /* add on the face_index! */ - - /* if the face at this index is not scalable, - fall back to the first one (old behavior) */ - if ( EndianS16_BtoN( assoc->fontSize ) == 0 ) - { - *have_sfnt = 1; - *sfnt_id = EndianS16_BtoN( assoc->fontID ); - } - else if ( base_assoc->fontSize == 0 ) - { - *have_sfnt = 1; - *sfnt_id = EndianS16_BtoN( base_assoc->fontID ); - } - } - - if ( EndianS32_BtoN( fond->ffStylOff ) ) - { - unsigned char* p = (unsigned char*)fond_data; - StyleTable* style; - unsigned short string_count; - char ps_name[256]; - unsigned char* names[64]; - int i; - - - p += EndianS32_BtoN( fond->ffStylOff ); - style = (StyleTable*)p; - p += sizeof ( StyleTable ); - string_count = EndianS16_BtoN( *(short*)(p) ); - p += sizeof ( short ); - - for ( i = 0; i < string_count && i < 64; i++ ) - { - names[i] = p; - p += names[i][0]; - p++; - } - - { - size_t ps_name_len = (size_t)names[0][0]; - - - if ( ps_name_len != 0 ) - { - ft_memcpy(ps_name, names[0] + 1, ps_name_len); - ps_name[ps_name_len] = 0; - } - if ( style->indexes[face_index] > 1 && - style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) - { - unsigned char* suffixes = names[style->indexes[face_index] - 1]; - - - for ( i = 1; i <= suffixes[0]; i++ ) - { - unsigned char* s; - size_t j = suffixes[i] - 1; - - - if ( j < string_count && ( s = names[j] ) != NULL ) - { - size_t s_len = (size_t)s[0]; - - - if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) ) - { - ft_memcpy( ps_name + ps_name_len, s + 1, s_len ); - ps_name_len += s_len; - ps_name[ps_name_len] = 0; - } - } - } - } - } - - create_lwfn_name( ps_name, lwfn_file_name ); - } - } - - - static FT_Error - lookup_lwfn_by_fond( const UInt8* path_fond, - ConstStr255Param base_lwfn, - UInt8* path_lwfn, - size_t path_size ) - { - FSRef ref, par_ref; - size_t dirname_len; - - - /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */ - /* We should not extract parent directory by string manipulation. */ - - if ( noErr != FSPathMakeRef( path_fond, &ref, FALSE ) ) - return FT_THROW( Invalid_Argument ); - - if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, - NULL, NULL, NULL, &par_ref ) ) - return FT_THROW( Invalid_Argument ); - - if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) ) - return FT_THROW( Invalid_Argument ); - - if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size ) - return FT_THROW( Invalid_Argument ); - - /* now we have absolute dirname in path_lwfn */ - ft_strcat( (char *)path_lwfn, "/" ); - dirname_len = ft_strlen( (char *)path_lwfn ); - ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 ); - path_lwfn[dirname_len + base_lwfn[0]] = '\0'; - - if ( noErr != FSPathMakeRef( path_lwfn, &ref, FALSE ) ) - return FT_THROW( Cannot_Open_Resource ); - - if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, - NULL, NULL, NULL, NULL ) ) - return FT_THROW( Cannot_Open_Resource ); - - return FT_Err_Ok; - } - - - static short - count_faces( Handle fond, - const UInt8* pathname ) - { - ResID sfnt_id; - short have_sfnt, have_lwfn; - Str255 lwfn_file_name; - UInt8 buff[PATH_MAX]; - FT_Error err; - short num_faces; - - - have_sfnt = have_lwfn = 0; - - parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 ); - - if ( lwfn_file_name[0] ) - { - err = lookup_lwfn_by_fond( pathname, lwfn_file_name, - buff, sizeof ( buff ) ); - if ( !err ) - have_lwfn = 1; - } - - if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) - num_faces = 1; - else - num_faces = count_faces_scalable( *fond ); - - return num_faces; - } - - - /* Read Type 1 data from the POST resources inside the LWFN file, - return a PFB buffer. This is somewhat convoluted because the FT2 - PFB parser wants the ASCII header as one chunk, and the LWFN - chunks are often not organized that way, so we glue chunks - of the same type together. */ - static FT_Error - read_lwfn( FT_Memory memory, - ResFileRefNum res, - FT_Byte** pfb_data, - FT_ULong* size ) - { - FT_Error error = FT_Err_Ok; - ResID res_id; - unsigned char *buffer, *p, *size_p = NULL; - FT_ULong total_size = 0; - FT_ULong old_total_size = 0; - FT_ULong post_size, pfb_chunk_size; - Handle post_data; - char code, last_code; - - - UseResFile( res ); - - /* First pass: load all POST resources, and determine the size of */ - /* the output buffer. */ - res_id = 501; - last_code = -1; - - for (;;) - { - post_data = Get1Resource( TTAG_POST, res_id++ ); - if ( post_data == NULL ) - break; /* we are done */ - - code = (*post_data)[0]; - - if ( code != last_code ) - { - if ( code == 5 ) - total_size += 2; /* just the end code */ - else - total_size += 6; /* code + 4 bytes chunk length */ - } - - total_size += GetHandleSize( post_data ) - 2; - last_code = code; - - /* detect integer overflows */ - if ( total_size < old_total_size ) - { - error = FT_THROW( Array_Too_Large ); - goto Error; - } - - old_total_size = total_size; - } - - if ( FT_ALLOC( buffer, (FT_Long)total_size ) ) - goto Error; - - /* Second pass: append all POST data to the buffer, add PFB fields. */ - /* Glue all consecutive chunks of the same type together. */ - p = buffer; - res_id = 501; - last_code = -1; - pfb_chunk_size = 0; - - for (;;) - { - post_data = Get1Resource( TTAG_POST, res_id++ ); - if ( post_data == NULL ) - break; /* we are done */ - - post_size = (FT_ULong)GetHandleSize( post_data ) - 2; - code = (*post_data)[0]; - - if ( code != last_code ) - { - if ( last_code != -1 ) - { - /* we are done adding a chunk, fill in the size field */ - if ( size_p != NULL ) - { - *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF ); - *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF ); - *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF ); - *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF ); - } - pfb_chunk_size = 0; - } - - *p++ = 0x80; - if ( code == 5 ) - *p++ = 0x03; /* the end */ - else if ( code == 2 ) - *p++ = 0x02; /* binary segment */ - else - *p++ = 0x01; /* ASCII segment */ - - if ( code != 5 ) - { - size_p = p; /* save for later */ - p += 4; /* make space for size field */ - } - } - - ft_memcpy( p, *post_data + 2, post_size ); - pfb_chunk_size += post_size; - p += post_size; - last_code = code; - } - - *pfb_data = buffer; - *size = total_size; - - Error: - CloseResFile( res ); - return error; - } - - - /* Create a new FT_Face from a file path to an LWFN file. */ - static FT_Error - FT_New_Face_From_LWFN( FT_Library library, - const UInt8* pathname, - FT_Long face_index, - FT_Face* aface ) - { - FT_Byte* pfb_data; - FT_ULong pfb_size; - FT_Error error; - ResFileRefNum res; - - - if ( noErr != FT_FSPathMakeRes( pathname, &res ) ) - return FT_THROW( Cannot_Open_Resource ); - - pfb_data = NULL; - pfb_size = 0; - error = read_lwfn( library->memory, res, &pfb_data, &pfb_size ); - CloseResFile( res ); /* PFB is already loaded, useless anymore */ - if ( error ) - return error; - - return open_face_from_buffer( library, - pfb_data, - pfb_size, - face_index, - "type1", - aface ); - } - - - /* Create a new FT_Face from an SFNT resource, specified by res ID. */ - static FT_Error - FT_New_Face_From_SFNT( FT_Library library, - ResID sfnt_id, - FT_Long face_index, - FT_Face* aface ) - { - Handle sfnt = NULL; - FT_Byte* sfnt_data; - size_t sfnt_size; - FT_Error error = FT_Err_Ok; - FT_Memory memory = library->memory; - int is_cff, is_sfnt_ps; - - - sfnt = GetResource( TTAG_sfnt, sfnt_id ); - if ( sfnt == NULL ) - return FT_THROW( Invalid_Handle ); - - sfnt_size = (FT_ULong)GetHandleSize( sfnt ); - if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) - { - ReleaseResource( sfnt ); - return error; - } - - ft_memcpy( sfnt_data, *sfnt, sfnt_size ); - ReleaseResource( sfnt ); - - is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); - is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 ); - - if ( is_sfnt_ps ) - { - FT_Stream stream; - - - if ( FT_NEW( stream ) ) - goto Try_OpenType; - - FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size ); - if ( !open_face_PS_from_sfnt_stream( library, - stream, - face_index, - 0, NULL, - aface ) ) - { - FT_Stream_Close( stream ); - FT_FREE( stream ); - FT_FREE( sfnt_data ); - goto Exit; - } - - FT_FREE( stream ); - } - Try_OpenType: - error = open_face_from_buffer( library, - sfnt_data, - sfnt_size, - face_index, - is_cff ? "cff" : "truetype", - aface ); - Exit: - return error; - } - - - /* Create a new FT_Face from a file path to a suitcase file. */ - static FT_Error - FT_New_Face_From_Suitcase( FT_Library library, - const UInt8* pathname, - FT_Long face_index, - FT_Face* aface ) - { - FT_Error error = FT_ERR( Cannot_Open_Resource ); - ResFileRefNum res_ref; - ResourceIndex res_index; - Handle fond; - short num_faces_in_res; - - - if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) - return FT_THROW( Cannot_Open_Resource ); - - UseResFile( res_ref ); - if ( ResError() ) - return FT_THROW( Cannot_Open_Resource ); - - num_faces_in_res = 0; - for ( res_index = 1; ; ++res_index ) - { - short num_faces_in_fond; - - - fond = Get1IndResource( TTAG_FOND, res_index ); - if ( ResError() ) - break; - - num_faces_in_fond = count_faces( fond, pathname ); - num_faces_in_res += num_faces_in_fond; - - if ( 0 <= face_index && face_index < num_faces_in_fond && error ) - error = FT_New_Face_From_FOND( library, fond, face_index, aface ); - - face_index -= num_faces_in_fond; - } - - CloseResFile( res_ref ); - if ( !error && aface && *aface ) - (*aface)->num_faces = num_faces_in_res; - return error; - } - - - /* documentation is in ftmac.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Face_From_FOND( FT_Library library, - Handle fond, - FT_Long face_index, - FT_Face* aface ) - { - short have_sfnt, have_lwfn = 0; - ResID sfnt_id, fond_id; - OSType fond_type; - Str255 fond_name; - Str255 lwfn_file_name; - UInt8 path_lwfn[PATH_MAX]; - OSErr err; - FT_Error error = FT_Err_Ok; - - - GetResInfo( fond, &fond_id, &fond_type, fond_name ); - if ( ResError() != noErr || fond_type != TTAG_FOND ) - return FT_THROW( Invalid_File_Format ); - - parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); - - if ( lwfn_file_name[0] ) - { - ResFileRefNum res; - - - res = HomeResFile( fond ); - if ( noErr != ResError() ) - goto found_no_lwfn_file; - - { - UInt8 path_fond[PATH_MAX]; - FSRef ref; - - - err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum, - NULL, NULL, NULL, &ref, NULL ); - if ( noErr != err ) - goto found_no_lwfn_file; - - err = FSRefMakePath( &ref, 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 ( !error ) - have_lwfn = 1; - } - } - - if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) - error = FT_New_Face_From_LWFN( library, - path_lwfn, - face_index, - aface ); - else - error = FT_THROW( Unknown_File_Format ); - - found_no_lwfn_file: - if ( have_sfnt && error ) - error = FT_New_Face_From_SFNT( library, - sfnt_id, - face_index, - aface ); - - return error; - } - - - /* Common function to load a new FT_Face from a resource file. */ - static FT_Error - FT_New_Face_From_Resource( FT_Library library, - const UInt8* pathname, - FT_Long face_index, - FT_Face* aface ) - { - OSType file_type; - FT_Error error; - - - /* LWFN is a (very) specific file format, check for it explicitly */ - file_type = get_file_type_from_path( pathname ); - if ( file_type == TTAG_LWFN ) - return FT_New_Face_From_LWFN( library, pathname, face_index, aface ); - - /* Otherwise the file type doesn't matter (there are more than */ - /* `FFIL' and `tfil'). Just try opening it as a font suitcase; */ - /* if it works, fine. */ - - error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface ); - if ( error == 0 ) - return error; - - /* let it fall through to normal loader (.ttf, .otf, etc.); */ - /* we signal this by returning no error and no FT_Face */ - *aface = NULL; - return 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face */ - /* */ - /* <Description> */ - /* This is the Mac-specific implementation of FT_New_Face. In */ - /* addition to the standard FT_New_Face() functionality, it also */ - /* accepts pathnames to Mac suitcase files. For further */ - /* documentation see the original FT_New_Face() in freetype.h. */ - /* */ - FT_EXPORT_DEF( FT_Error ) - FT_New_Face( FT_Library library, - const char* pathname, - FT_Long face_index, - FT_Face* aface ) - { - FT_Open_Args args; - FT_Error error; - - - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ - if ( !pathname ) - return FT_THROW( Invalid_Argument ); - - error = FT_Err_Ok; - *aface = NULL; - - /* try resourcefork based font: LWFN, FFIL */ - error = FT_New_Face_From_Resource( library, (UInt8 *)pathname, - face_index, aface ); - if ( error != 0 || *aface != NULL ) - return error; - - /* let it fall through to normal loader (.ttf, .otf, etc.) */ - args.flags = FT_OPEN_PATHNAME; - args.pathname = (char*)pathname; - return FT_Open_Face( library, &args, face_index, aface ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FSRef */ - /* */ - /* <Description> */ - /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ - /* accepts an FSRef instead of a path. */ - /* */ - /* This function is deprecated because Carbon data types (FSRef) */ - /* are not cross-platform, and thus not suitable for the freetype API. */ - FT_EXPORT_DEF( FT_Error ) - FT_New_Face_From_FSRef( FT_Library library, - const FSRef* ref, - FT_Long face_index, - FT_Face* aface ) - { - FT_Error error; - FT_Open_Args args; - OSErr err; - UInt8 pathname[PATH_MAX]; - - - if ( !ref ) - return FT_THROW( Invalid_Argument ); - - err = FSRefMakePath( ref, pathname, sizeof ( pathname ) ); - if ( err ) - error = FT_THROW( 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 ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FSSpec */ - /* */ - /* <Description> */ - /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ - /* accepts an FSSpec instead of a path. */ - /* */ - /* This function is deprecated because FSSpec is deprecated in Mac OS X */ - FT_EXPORT_DEF( FT_Error ) - FT_New_Face_From_FSSpec( FT_Library library, - const FSSpec* spec, - FT_Long face_index, - FT_Face* aface ) - { -#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ - ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) - FT_UNUSED( library ); - FT_UNUSED( spec ); - FT_UNUSED( face_index ); - FT_UNUSED( aface ); - - return FT_THROW( Unimplemented_Feature ); -#else - FSRef ref; - - - if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr ) - return FT_THROW( Invalid_Argument ); - else - return FT_New_Face_From_FSRef( library, &ref, face_index, aface ); -#endif - } - -#endif /* FT_MACINTOSH */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftmm.c b/drivers/freetype/freetype/src/base/ftmm.c deleted file mode 100644 index 18ff879bfc..0000000000 --- a/drivers/freetype/freetype/src/base/ftmm.c +++ /dev/null @@ -1,204 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmm.c */ -/* */ -/* Multiple Master font support (body). */ -/* */ -/* Copyright 1996-2001, 2003, 2004, 2009, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_MULTIPLE_MASTERS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_MULTIPLE_MASTERS_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_mm - - - static FT_Error - ft_face_get_mm_service( FT_Face face, - FT_Service_MultiMasters *aservice ) - { - FT_Error error; - - - *aservice = NULL; - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - error = FT_ERR( Invalid_Argument ); - - if ( FT_HAS_MULTIPLE_MASTERS( face ) ) - { - FT_FACE_LOOKUP_SERVICE( face, - *aservice, - MULTI_MASTERS ); - - if ( *aservice ) - error = FT_Err_Ok; - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Multi_Master( FT_Face face, - FT_Multi_Master *amaster ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_ERR( Invalid_Argument ); - if ( service->get_mm ) - error = service->get_mm( face, amaster ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_MM_Var( FT_Face face, - FT_MM_Var* *amaster ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_ERR( Invalid_Argument ); - if ( service->get_mm_var ) - error = service->get_mm_var( face, amaster ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_MM_Design_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_design ) - error = service->set_mm_design( face, num_coords, coords ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Var_Design_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_ERR( Invalid_Argument ); - if ( service->set_var_design ) - error = service->set_var_design( face, num_coords, coords ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_MM_Blend_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - /* This is exactly the same as the previous function. It exists for */ - /* orthogonality. */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Var_Blend_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftobjs.c b/drivers/freetype/freetype/src/base/ftobjs.c deleted file mode 100644 index 157bf45634..0000000000 --- a/drivers/freetype/freetype/src/base/ftobjs.c +++ /dev/null @@ -1,4870 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftobjs.c */ -/* */ -/* The FreeType private base classes (body). */ -/* */ -/* Copyright 1996-2013 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_LIST_H -#include FT_OUTLINE_H -#include FT_INTERNAL_VALIDATE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_RFORK_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ -#include FT_TRUETYPE_TABLES_H -#include FT_TRUETYPE_TAGS_H -#include FT_TRUETYPE_IDS_H - -#include FT_SERVICE_PROPERTIES_H -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_TT_CMAP_H -#include FT_SERVICE_KERNING_H -#include FT_SERVICE_TRUETYPE_ENGINE_H - -#ifdef FT_CONFIG_OPTION_MAC_FONTS -#include "ftbase.h" -#endif - - -#ifdef FT_DEBUG_LEVEL_TRACE - -#include FT_BITMAP_H - -#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ - /* We disable the warning `conversion from XXX to YYY, */ - /* possible loss of data' in order to compile cleanly with */ - /* the maximum level of warnings: `md5.c' is non-FreeType */ - /* code, and it gets used during development builds only. */ -#pragma warning( push ) -#pragma warning( disable : 4244 ) -#endif /* _MSC_VER */ - - /* it's easiest to include `md5.c' directly */ -#define free md5_free /* suppress a shadow warning */ -#include "md5.c" -#undef free - -#if defined( _MSC_VER ) -#pragma warning( pop ) -#endif - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - -#define GRID_FIT_METRICS - - - FT_BASE_DEF( FT_Pointer ) - ft_service_list_lookup( FT_ServiceDesc service_descriptors, - const char* service_id ) - { - FT_Pointer result = NULL; - FT_ServiceDesc desc = service_descriptors; - - - if ( desc && service_id ) - { - for ( ; desc->serv_id != NULL; desc++ ) - { - if ( ft_strcmp( desc->serv_id, service_id ) == 0 ) - { - result = (FT_Pointer)desc->serv_data; - break; - } - } - } - - return result; - } - - - FT_BASE_DEF( void ) - ft_validator_init( FT_Validator valid, - const FT_Byte* base, - const FT_Byte* limit, - FT_ValidationLevel level ) - { - valid->base = base; - valid->limit = limit; - valid->level = level; - valid->error = FT_Err_Ok; - } - - - FT_BASE_DEF( FT_Int ) - ft_validator_run( FT_Validator valid ) - { - /* This function doesn't work! None should call it. */ - FT_UNUSED( valid ); - - return -1; - } - - - FT_BASE_DEF( void ) - 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 ft_jmp_buf* jump_buffer = &valid->jump_buffer; - - - valid->error = error; - - /* throw away volatileness; use `jump_buffer' or the */ - /* compiler may warn about an unused local variable */ - ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** S T R E A M ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* create a new input stream from an FT_Open_Args structure */ - /* */ - FT_BASE_DEF( FT_Error ) - FT_Stream_New( FT_Library library, - const FT_Open_Args* args, - FT_Stream *astream ) - { - FT_Error error; - FT_Memory memory; - FT_Stream stream = NULL; - - - *astream = 0; - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( !args ) - return FT_THROW( Invalid_Argument ); - - memory = library->memory; - - if ( FT_NEW( stream ) ) - goto Exit; - - stream->memory = memory; - - if ( args->flags & FT_OPEN_MEMORY ) - { - /* create a memory-based stream */ - FT_Stream_OpenMemory( stream, - (const FT_Byte*)args->memory_base, - args->memory_size ); - } - -#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT - - else if ( args->flags & FT_OPEN_PATHNAME ) - { - /* create a normal system stream */ - error = FT_Stream_Open( stream, args->pathname ); - stream->pathname.pointer = args->pathname; - } - else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) - { - /* use an existing, user-provided stream */ - - /* in this case, we do not need to allocate a new stream object */ - /* since the caller is responsible for closing it himself */ - FT_FREE( stream ); - stream = args->stream; - } - -#endif - - else - error = FT_THROW( Invalid_Argument ); - - if ( error ) - FT_FREE( stream ); - else - stream->memory = memory; /* just to be certain */ - - *astream = stream; - - Exit: - return error; - } - - - FT_BASE_DEF( void ) - FT_Stream_Free( FT_Stream stream, - FT_Int external ) - { - if ( stream ) - { - FT_Memory memory = stream->memory; - - - FT_Stream_Close( stream ); - - if ( !external ) - FT_FREE( stream ); - } - } - - - /*************************************************************************/ - /* */ - /* 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_objs - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static FT_Error - ft_glyphslot_init( FT_GlyphSlot slot ) - { - FT_Driver driver = slot->face->driver; - FT_Driver_Class clazz = driver->clazz; - FT_Memory memory = driver->root.memory; - FT_Error error = FT_Err_Ok; - FT_Slot_Internal internal = NULL; - - - slot->library = driver->root.library; - - if ( FT_NEW( internal ) ) - goto Exit; - - slot->internal = internal; - - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - error = FT_GlyphLoader_New( memory, &internal->loader ); - - if ( !error && clazz->init_slot ) - error = clazz->init_slot( slot ); - - Exit: - return error; - } - - - FT_BASE_DEF( void ) - ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) - { - if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - - - FT_FREE( slot->bitmap.buffer ); - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - else - { - /* assume that the bitmap buffer was stolen or not */ - /* allocated from the heap */ - slot->bitmap.buffer = NULL; - } - } - - - FT_BASE_DEF( void ) - ft_glyphslot_set_bitmap( FT_GlyphSlot slot, - FT_Byte* buffer ) - { - ft_glyphslot_free_bitmap( slot ); - - slot->bitmap.buffer = buffer; - - FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 ); - } - - - FT_BASE_DEF( FT_Error ) - ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, - FT_ULong size ) - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - FT_Error error; - - - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - FT_FREE( slot->bitmap.buffer ); - else - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - - (void)FT_ALLOC( slot->bitmap.buffer, size ); - return error; - } - - - static void - ft_glyphslot_clear( FT_GlyphSlot slot ) - { - /* free bitmap if needed */ - ft_glyphslot_free_bitmap( slot ); - - /* clear all public fields in the glyph slot */ - FT_ZERO( &slot->metrics ); - FT_ZERO( &slot->outline ); - - slot->bitmap.width = 0; - slot->bitmap.rows = 0; - slot->bitmap.pitch = 0; - slot->bitmap.pixel_mode = 0; - /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */ - - slot->bitmap_left = 0; - slot->bitmap_top = 0; - slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; - slot->control_len = 0; - slot->other = 0; - slot->format = FT_GLYPH_FORMAT_NONE; - - slot->linearHoriAdvance = 0; - slot->linearVertAdvance = 0; - slot->lsb_delta = 0; - slot->rsb_delta = 0; - } - - - static void - ft_glyphslot_done( FT_GlyphSlot slot ) - { - FT_Driver driver = slot->face->driver; - FT_Driver_Class clazz = driver->clazz; - FT_Memory memory = driver->root.memory; - - - if ( clazz->done_slot ) - clazz->done_slot( slot ); - - /* free bitmap buffer if needed */ - ft_glyphslot_free_bitmap( slot ); - - /* slot->internal might be NULL in out-of-memory situations */ - if ( slot->internal ) - { - /* free glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - { - FT_GlyphLoader_Done( slot->internal->loader ); - slot->internal->loader = 0; - } - - FT_FREE( slot->internal ); - } - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( FT_Error ) - FT_New_GlyphSlot( FT_Face face, - FT_GlyphSlot *aslot ) - { - FT_Error error; - FT_Driver driver; - FT_Driver_Class clazz; - FT_Memory memory; - FT_GlyphSlot slot = NULL; - - - if ( !face || !face->driver ) - return FT_THROW( Invalid_Argument ); - - driver = face->driver; - clazz = driver->clazz; - memory = driver->root.memory; - - FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); - if ( !FT_ALLOC( slot, clazz->slot_object_size ) ) - { - slot->face = face; - - error = ft_glyphslot_init( slot ); - if ( error ) - { - ft_glyphslot_done( slot ); - FT_FREE( slot ); - goto Exit; - } - - slot->next = face->glyph; - face->glyph = slot; - - if ( aslot ) - *aslot = slot; - } - else if ( aslot ) - *aslot = 0; - - - Exit: - FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); - return error; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( void ) - FT_Done_GlyphSlot( FT_GlyphSlot slot ) - { - if ( slot ) - { - FT_Driver driver = slot->face->driver; - FT_Memory memory = driver->root.memory; - FT_GlyphSlot prev; - FT_GlyphSlot cur; - - - /* Remove slot from its parent face's list */ - prev = NULL; - cur = slot->face->glyph; - - while ( cur ) - { - if ( cur == slot ) - { - if ( !prev ) - slot->face->glyph = cur->next; - else - prev->next = cur->next; - - /* finalize client-specific data */ - if ( slot->generic.finalizer ) - slot->generic.finalizer( slot ); - - ft_glyphslot_done( slot ); - FT_FREE( slot ); - break; - } - prev = cur; - cur = cur->next; - } - } - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( void ) - FT_Set_Transform( FT_Face face, - FT_Matrix* matrix, - FT_Vector* delta ) - { - FT_Face_Internal internal; - - - if ( !face ) - return; - - internal = face->internal; - - internal->transform_flags = 0; - - if ( !matrix ) - { - internal->transform_matrix.xx = 0x10000L; - internal->transform_matrix.xy = 0; - internal->transform_matrix.yx = 0; - internal->transform_matrix.yy = 0x10000L; - matrix = &internal->transform_matrix; - } - else - internal->transform_matrix = *matrix; - - /* set transform_flags bit flag 0 if `matrix' isn't the identity */ - if ( ( matrix->xy | matrix->yx ) || - matrix->xx != 0x10000L || - matrix->yy != 0x10000L ) - internal->transform_flags |= 1; - - if ( !delta ) - { - internal->transform_delta.x = 0; - internal->transform_delta.y = 0; - delta = &internal->transform_delta; - } - else - internal->transform_delta = *delta; - - /* set transform_flags bit flag 1 if `delta' isn't the null vector */ - if ( delta->x | delta->y ) - internal->transform_flags |= 2; - } - - - static FT_Renderer - ft_lookup_glyph_renderer( FT_GlyphSlot slot ); - - -#ifdef GRID_FIT_METRICS - static void - ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot, - FT_Bool vertical ) - { - FT_Glyph_Metrics* metrics = &slot->metrics; - FT_Pos right, bottom; - - - if ( vertical ) - { - metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); - metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); - - right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width ); - bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); - - metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); - metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - - metrics->width = right - metrics->vertBearingX; - metrics->height = bottom - metrics->vertBearingY; - } - else - { - metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); - metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - - right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); - bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); - - metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); - metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); - - metrics->width = right - metrics->horiBearingX; - metrics->height = metrics->horiBearingY - bottom; - } - - metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); - metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - } -#endif /* GRID_FIT_METRICS */ - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Load_Glyph( FT_Face face, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - FT_Error error; - FT_Driver driver; - FT_GlyphSlot slot; - FT_Library library; - FT_Bool autohint = FALSE; - FT_Module hinter; - TT_Face ttface = (TT_Face)face; - - - if ( !face || !face->size || !face->glyph ) - return FT_THROW( Invalid_Face_Handle ); - - /* The validity test for `glyph_index' is performed by the */ - /* font drivers. */ - - slot = face->glyph; - ft_glyphslot_clear( slot ); - - driver = face->driver; - library = driver->root.library; - hinter = library->auto_hinter; - - /* resolve load flags dependencies */ - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | - FT_LOAD_IGNORE_TRANSFORM; - - if ( load_flags & FT_LOAD_NO_SCALE ) - { - load_flags |= FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP; - - load_flags &= ~FT_LOAD_RENDER; - } - - /* - * 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 and/or rotations by integer multiples of 90 degrees. - * - * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't - * have a native font hinter. - * - * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't - * any hinting bytecode in the TrueType/OpenType font. - * - * - Exception: The font is `tricky' and requires the native hinter to - * load properly. - */ - - if ( hinter && - !( load_flags & FT_LOAD_NO_HINTING ) && - !( load_flags & FT_LOAD_NO_AUTOHINT ) && - FT_DRIVER_IS_SCALABLE( driver ) && - FT_DRIVER_USES_OUTLINES( driver ) && - !FT_IS_TRICKY( face ) && - ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) || - ( face->internal->transform_matrix.yx == 0 && - face->internal->transform_matrix.xx != 0 ) || - ( face->internal->transform_matrix.xx == 0 && - face->internal->transform_matrix.yx != 0 ) ) ) - { - if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) || - !FT_DRIVER_HAS_HINTER( driver ) ) - autohint = TRUE; - else - { - FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); - - - /* the check for `num_locations' assures that we actually */ - /* test for instructions in a TTF and not in a CFF-based OTF */ - if ( mode == FT_RENDER_MODE_LIGHT || - face->internal->ignore_unpatented_hinter || - ( FT_IS_SFNT( face ) && - ttface->num_locations && - ttface->max_profile.maxSizeOfInstructions == 0 ) ) - autohint = TRUE; - } - } - - if ( autohint ) - { - FT_AutoHinter_Interface hinting; - - - /* try to load embedded bitmaps first if available */ - /* */ - /* XXX: This is really a temporary hack that should disappear */ - /* promptly with FreeType 2.1! */ - /* */ - if ( FT_HAS_FIXED_SIZES( face ) && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) - { - error = driver->clazz->load_glyph( slot, face->size, - glyph_index, - load_flags | FT_LOAD_SBITS_ONLY ); - - if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP ) - goto Load_Ok; - } - - { - FT_Face_Internal internal = face->internal; - FT_Int transform_flags = internal->transform_flags; - - - /* since the auto-hinter calls FT_Load_Glyph by itself, */ - /* make sure that glyphs aren't transformed */ - internal->transform_flags = 0; - - /* load auto-hinted outline */ - hinting = (FT_AutoHinter_Interface)hinter->clazz->module_interface; - - error = hinting->load_glyph( (FT_AutoHinter)hinter, - slot, face->size, - glyph_index, load_flags ); - - internal->transform_flags = transform_flags; - } - } - else - { - error = driver->clazz->load_glyph( slot, - face->size, - glyph_index, - load_flags ); - if ( error ) - goto Exit; - - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* check that the loaded outline is correct */ - error = FT_Outline_Check( &slot->outline ); - if ( error ) - goto Exit; - -#ifdef GRID_FIT_METRICS - if ( !( load_flags & FT_LOAD_NO_HINTING ) ) - ft_glyphslot_grid_fit_metrics( slot, - FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); -#endif - } - } - - Load_Ok: - /* compute the advance */ - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - slot->advance.x = 0; - slot->advance.y = slot->metrics.vertAdvance; - } - else - { - slot->advance.x = slot->metrics.horiAdvance; - slot->advance.y = 0; - } - - /* compute the linear advance in 16.16 pixels */ - if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && - ( FT_IS_SCALABLE( face ) ) ) - { - FT_Size_Metrics* metrics = &face->size->metrics; - - - /* it's tricky! */ - slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, - metrics->x_scale, 64 ); - - slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, - metrics->y_scale, 64 ); - } - - if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) - { - FT_Face_Internal internal = face->internal; - - - /* now, transform the glyph image if needed */ - if ( internal->transform_flags ) - { - /* get renderer */ - FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); - - - if ( renderer ) - error = renderer->clazz->transform_glyph( - renderer, slot, - &internal->transform_matrix, - &internal->transform_delta ); - else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* apply `standard' transformation if no renderer is available */ - if ( internal->transform_flags & 1 ) - FT_Outline_Transform( &slot->outline, - &internal->transform_matrix ); - - if ( internal->transform_flags & 2 ) - FT_Outline_Translate( &slot->outline, - internal->transform_delta.x, - internal->transform_delta.y ); - } - - /* transform advance */ - FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); - } - } - - FT_TRACE5(( " x advance: %d\n" , slot->advance.x )); - FT_TRACE5(( " y advance: %d\n" , slot->advance.y )); - - FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance )); - FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance )); - - /* do we need to render the image now? */ - if ( !error && - slot->format != FT_GLYPH_FORMAT_BITMAP && - slot->format != FT_GLYPH_FORMAT_COMPOSITE && - load_flags & FT_LOAD_RENDER ) - { - FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); - - - if ( mode == FT_RENDER_MODE_NORMAL && - (load_flags & FT_LOAD_MONOCHROME ) ) - mode = FT_RENDER_MODE_MONO; - - error = FT_Render_Glyph( slot, mode ); - } - - Exit: - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Load_Char( FT_Face face, - FT_ULong char_code, - FT_Int32 load_flags ) - { - FT_UInt glyph_index; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - glyph_index = (FT_UInt)char_code; - if ( face->charmap ) - glyph_index = FT_Get_Char_Index( face, char_code ); - - return FT_Load_Glyph( face, glyph_index, load_flags ); - } - - - /* destructor for sizes list */ - static void - destroy_size( FT_Memory memory, - FT_Size size, - FT_Driver driver ) - { - /* finalize client-specific data */ - if ( size->generic.finalizer ) - size->generic.finalizer( size ); - - /* finalize format-specific stuff */ - if ( driver->clazz->done_size ) - driver->clazz->done_size( size ); - - FT_FREE( size->internal ); - FT_FREE( size ); - } - - - static void - ft_cmap_done_internal( FT_CMap cmap ); - - - static void - destroy_charmaps( FT_Face face, - FT_Memory memory ) - { - FT_Int n; - - - if ( !face ) - return; - - for ( n = 0; n < face->num_charmaps; n++ ) - { - FT_CMap cmap = FT_CMAP( face->charmaps[n] ); - - - ft_cmap_done_internal( cmap ); - - face->charmaps[n] = NULL; - } - - FT_FREE( face->charmaps ); - face->num_charmaps = 0; - } - - - /* destructor for faces list */ - static void - destroy_face( FT_Memory memory, - FT_Face face, - FT_Driver driver ) - { - FT_Driver_Class clazz = driver->clazz; - - - /* discard auto-hinting data */ - if ( face->autohint.finalizer ) - face->autohint.finalizer( face->autohint.data ); - - /* Discard glyph slots for this face. */ - /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */ - while ( face->glyph ) - FT_Done_GlyphSlot( face->glyph ); - - /* discard all sizes for this face */ - FT_List_Finalize( &face->sizes_list, - (FT_List_Destructor)destroy_size, - memory, - driver ); - face->size = 0; - - /* now discard client data */ - if ( face->generic.finalizer ) - face->generic.finalizer( face ); - - /* discard charmaps */ - destroy_charmaps( face, memory ); - - /* finalize format-specific stuff */ - if ( clazz->done_face ) - clazz->done_face( face ); - - /* close the stream for this face if needed */ - FT_Stream_Free( - face->stream, - ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); - - face->stream = 0; - - /* get rid of it */ - if ( face->internal ) - { - FT_FREE( face->internal ); - } - FT_FREE( face ); - } - - - static void - Destroy_Driver( FT_Driver driver ) - { - FT_List_Finalize( &driver->faces_list, - (FT_List_Destructor)destroy_face, - driver->root.memory, - driver ); - - /* check whether we need to drop the driver's glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* find_unicode_charmap */ - /* */ - /* <Description> */ - /* This function finds a Unicode charmap, if there is one. */ - /* And if there is more than one, it tries to favour the more */ - /* extensive one, i.e., one that supports UCS-4 against those which */ - /* are limited to the BMP (said UCS-2 encoding.) */ - /* */ - /* This function is called from open_face() (just below), and also */ - /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ - /* */ - static FT_Error - find_unicode_charmap( FT_Face face ) - { - FT_CharMap* first; - FT_CharMap* cur; - - - /* caller should have already checked that `face' is valid */ - FT_ASSERT( face ); - - first = face->charmaps; - - if ( !first ) - return FT_THROW( Invalid_CharMap_Handle ); - - /* - * The original TrueType specification(s) only specified charmap - * formats that are capable of mapping 8 or 16 bit character codes to - * glyph indices. - * - * However, recent updates to the Apple and OpenType specifications - * introduced new formats that are capable of mapping 32-bit character - * codes as well. And these are already used on some fonts, mainly to - * map non-BMP Asian ideographs as defined in Unicode. - * - * For compatibility purposes, these fonts generally come with - * *several* Unicode charmaps: - * - * - One of them in the "old" 16-bit format, that cannot access - * all glyphs in the font. - * - * - Another one in the "new" 32-bit format, that can access all - * the glyphs. - * - * This function has been written to always favor a 32-bit charmap - * when found. Otherwise, a 16-bit one is returned when found. - */ - - /* Since the `interesting' table, with IDs (3,10), is normally the */ - /* last one, we loop backwards. This loses with type1 fonts with */ - /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */ - /* chars (.01% ?), and this is the same about 99.99% of the time! */ - - cur = first + face->num_charmaps; /* points after the last one */ - - for ( ; --cur >= first; ) - { - if ( cur[0]->encoding == FT_ENCODING_UNICODE ) - { - /* XXX If some new encodings to represent UCS-4 are added, */ - /* they should be added here. */ - if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && - cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || - ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) - { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif - face->charmap = cur[0]; - return FT_Err_Ok; - } - } - } - - /* We do not have any UCS-4 charmap. */ - /* Do the loop again and search for UCS-2 charmaps. */ - cur = first + face->num_charmaps; - - for ( ; --cur >= first; ) - { - if ( cur[0]->encoding == FT_ENCODING_UNICODE ) - { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif - face->charmap = cur[0]; - return FT_Err_Ok; - } - } - - return FT_THROW( Invalid_CharMap_Handle ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* find_variant_selector_charmap */ - /* */ - /* <Description> */ - /* This function finds the variant selector charmap, if there is one. */ - /* There can only be one (platform=0, specific=5, format=14). */ - /* */ - static FT_CharMap - find_variant_selector_charmap( FT_Face face ) - { - FT_CharMap* first; - FT_CharMap* end; - FT_CharMap* cur; - - - /* caller should have already checked that `face' is valid */ - FT_ASSERT( face ); - - first = face->charmaps; - - if ( !first ) - return NULL; - - end = first + face->num_charmaps; /* points after the last one */ - - for ( cur = first; cur < end; ++cur ) - { - if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && - FT_Get_CMap_Format( cur[0] ) == 14 ) - { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UVS cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif - return cur[0]; - } - } - - return NULL; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* open_face */ - /* */ - /* <Description> */ - /* This function does some work for FT_Open_Face(). */ - /* */ - static FT_Error - open_face( FT_Driver driver, - FT_Stream stream, - FT_Long face_index, - FT_Int num_params, - FT_Parameter* params, - FT_Face *aface ) - { - FT_Memory memory; - FT_Driver_Class clazz; - FT_Face face = 0; - FT_Error error, error2; - FT_Face_Internal internal = NULL; - - - clazz = driver->clazz; - memory = driver->root.memory; - - /* allocate the face object and perform basic initialization */ - if ( FT_ALLOC( face, clazz->face_object_size ) ) - goto Fail; - - face->driver = driver; - face->memory = memory; - face->stream = stream; - - if ( FT_NEW( internal ) ) - goto Fail; - - face->internal = internal; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - { - int i; - - - face->internal->incremental_interface = 0; - for ( i = 0; i < num_params && !face->internal->incremental_interface; - i++ ) - if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) - face->internal->incremental_interface = - (FT_Incremental_Interface)params[i].data; - } -#endif - - if ( clazz->init_face ) - error = clazz->init_face( stream, - face, - (FT_Int)face_index, - num_params, - params ); - if ( error ) - goto Fail; - - /* select Unicode charmap by default */ - error2 = find_unicode_charmap( face ); - - /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */ - /* is returned. */ - - /* no error should happen, but we want to play safe */ - if ( error2 && FT_ERR_NEQ( error2, Invalid_CharMap_Handle ) ) - { - error = error2; - goto Fail; - } - - *aface = face; - - Fail: - if ( error ) - { - destroy_charmaps( face, memory ); - if ( clazz->done_face ) - clazz->done_face( face ); - FT_FREE( internal ); - FT_FREE( face ); - *aface = 0; - } - - return error; - } - - - /* there's a Mac-specific extended implementation of FT_New_Face() */ - /* in src/base/ftmac.c */ - -#ifndef FT_MACINTOSH - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Face( FT_Library library, - const char* pathname, - FT_Long face_index, - FT_Face *aface ) - { - FT_Open_Args args; - - - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ - if ( !pathname ) - return FT_THROW( Invalid_Argument ); - - args.flags = FT_OPEN_PATHNAME; - args.pathname = (char*)pathname; - args.stream = NULL; - - return FT_Open_Face( library, &args, face_index, aface ); - } - -#endif - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Memory_Face( FT_Library library, - const FT_Byte* file_base, - FT_Long file_size, - FT_Long face_index, - FT_Face *aface ) - { - FT_Open_Args args; - - - /* test for valid `library' and `face' delayed to FT_Open_Face() */ - if ( !file_base ) - return FT_THROW( Invalid_Argument ); - - args.flags = FT_OPEN_MEMORY; - args.memory_base = file_base; - args.memory_size = file_size; - args.stream = NULL; - - return FT_Open_Face( library, &args, face_index, aface ); - } - - -#ifdef FT_CONFIG_OPTION_MAC_FONTS - - /* The behavior here is very similar to that in base/ftmac.c, but it */ - /* is designed to work on non-mac systems, so no mac specific calls. */ - /* */ - /* We look at the file and determine if it is a mac dfont file or a mac */ - /* resource file, or a macbinary file containing a mac resource file. */ - /* */ - /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */ - /* the point, especially since there may be multiple `FOND' resources. */ - /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */ - /* they occur in the file. */ - /* */ - /* Note that multiple `POST' resources do not mean multiple postscript */ - /* fonts; they all get jammed together to make what is essentially a */ - /* pfb file. */ - /* */ - /* We aren't interested in `NFNT' or `FONT' bitmap resources. */ - /* */ - /* As soon as we get an `sfnt' load it into memory and pass it off to */ - /* FT_Open_Face. */ - /* */ - /* If we have a (set of) `POST' resources, massage them into a (memory) */ - /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */ - /* going to try to save the kerning info. After all that lives in the */ - /* `FOND' which isn't in the file containing the `POST' resources so */ - /* we don't really have access to it. */ - - - /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ - /* It frees the memory it uses. */ - /* From ftmac.c. */ - static void - memory_stream_close( FT_Stream stream ) - { - FT_Memory memory = stream->memory; - - - FT_FREE( stream->base ); - - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Create a new memory stream from a buffer and a size. */ - /* From ftmac.c. */ - static FT_Error - new_memory_stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream_CloseFunc close, - FT_Stream *astream ) - { - FT_Error error; - FT_Memory memory; - FT_Stream stream = NULL; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( !base ) - return FT_THROW( Invalid_Argument ); - - *astream = 0; - memory = library->memory; - if ( FT_NEW( stream ) ) - goto Exit; - - FT_Stream_OpenMemory( stream, base, size ); - - stream->close = close; - - *astream = stream; - - Exit: - return error; - } - - - /* Create a new FT_Face given a buffer and a driver name. */ - /* from ftmac.c */ - FT_LOCAL_DEF( FT_Error ) - open_face_from_buffer( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Long face_index, - const char* driver_name, - FT_Face *aface ) - { - FT_Open_Args args; - FT_Error error; - FT_Stream stream = NULL; - FT_Memory memory = library->memory; - - - error = new_memory_stream( library, - base, - size, - memory_stream_close, - &stream ); - if ( error ) - { - FT_FREE( base ); - return error; - } - - args.flags = FT_OPEN_STREAM; - args.stream = stream; - if ( driver_name ) - { - args.flags = args.flags | FT_OPEN_DRIVER; - args.driver = FT_Get_Module( library, driver_name ); - } - -#ifdef FT_MACINTOSH - /* At this point, face_index has served its purpose; */ - /* whoever calls this function has already used it to */ - /* locate the correct font data. We should not propagate */ - /* this index to FT_Open_Face() (unless it is negative). */ - - if ( face_index > 0 ) - face_index = 0; -#endif - - error = FT_Open_Face( library, &args, face_index, aface ); - - if ( error == FT_Err_Ok ) - (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; - else -#ifdef FT_MACINTOSH - FT_Stream_Free( stream, 0 ); -#else - { - FT_Stream_Close( stream ); - FT_FREE( stream ); - } -#endif - - return error; - } - - - /* Look up `TYP1' or `CID ' table from sfnt table directory. */ - /* `offset' and `length' must exclude the binary header in tables. */ - - /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ - /* format too. Here, since we can't expect that the TrueType font */ - /* driver is loaded unconditially, we must parse the font by */ - /* ourselves. We are only interested in the name of the table and */ - /* the offset. */ - - static FT_Error - ft_lookup_PS_in_sfnt_stream( FT_Stream stream, - FT_Long face_index, - FT_ULong* offset, - FT_ULong* length, - FT_Bool* is_sfnt_cid ) - { - FT_Error error; - FT_UShort numTables; - FT_Long pstable_index; - FT_ULong tag; - int i; - - - *offset = 0; - *length = 0; - *is_sfnt_cid = FALSE; - - /* TODO: support for sfnt-wrapped PS/CID in TTC format */ - - /* version check for 'typ1' (should be ignored?) */ - if ( FT_READ_ULONG( tag ) ) - return error; - if ( tag != TTAG_typ1 ) - return FT_THROW( Unknown_File_Format ); - - if ( FT_READ_USHORT( numTables ) ) - return error; - if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */ - return error; - - pstable_index = -1; - *is_sfnt_cid = FALSE; - - for ( i = 0; i < numTables; i++ ) - { - if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) || - FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) ) - return error; - - if ( tag == TTAG_CID ) - { - pstable_index++; - *offset += 22; - *length -= 22; - *is_sfnt_cid = TRUE; - if ( face_index < 0 ) - return FT_Err_Ok; - } - else if ( tag == TTAG_TYP1 ) - { - pstable_index++; - *offset += 24; - *length -= 24; - *is_sfnt_cid = FALSE; - if ( face_index < 0 ) - return FT_Err_Ok; - } - if ( face_index >= 0 && pstable_index == face_index ) - return FT_Err_Ok; - } - return FT_THROW( Table_Missing ); - } - - - FT_LOCAL_DEF( FT_Error ) - open_face_PS_from_sfnt_stream( FT_Library library, - FT_Stream stream, - FT_Long face_index, - FT_Int num_params, - FT_Parameter *params, - FT_Face *aface ) - { - FT_Error error; - FT_Memory memory = library->memory; - FT_ULong offset, length; - FT_Long pos; - FT_Bool is_sfnt_cid; - FT_Byte* sfnt_ps = NULL; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - - - pos = FT_Stream_Pos( stream ); - - error = ft_lookup_PS_in_sfnt_stream( stream, - face_index, - &offset, - &length, - &is_sfnt_cid ); - if ( error ) - goto Exit; - - if ( FT_Stream_Seek( stream, pos + offset ) ) - goto Exit; - - if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) - goto Exit; - - error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); - if ( error ) - goto Exit; - - error = open_face_from_buffer( library, - sfnt_ps, - length, - FT_MIN( face_index, 0 ), - is_sfnt_cid ? "cid" : "type1", - aface ); - Exit: - { - FT_Error error1; - - - if ( FT_ERR_EQ( error, Unknown_File_Format ) ) - { - error1 = FT_Stream_Seek( stream, pos ); - if ( error1 ) - return error1; - } - - return error; - } - } - - -#ifndef FT_MACINTOSH - - /* The resource header says we've got resource_cnt `POST' (type1) */ - /* resources in this file. They all need to be coalesced into */ - /* one lump which gets passed on to the type1 driver. */ - /* Here can be only one PostScript font in a file so face_index */ - /* must be 0 (or -1). */ - /* */ - static FT_Error - Mac_Read_POST_Resource( FT_Library library, - FT_Stream stream, - FT_Long *offsets, - FT_Long resource_cnt, - FT_Long face_index, - FT_Face *aface ) - { - FT_Error error = FT_ERR( Cannot_Open_Resource ); - FT_Memory memory = library->memory; - FT_Byte* pfb_data = NULL; - int i, type, flags; - FT_Long len; - FT_Long pfb_len, pfb_pos, pfb_lenpos; - FT_Long rlen, temp; - - - if ( face_index == -1 ) - face_index = 0; - if ( face_index != 0 ) - return error; - - /* Find the length of all the POST resources, concatenated. Assume */ - /* worst case (each resource in its own section). */ - pfb_len = 0; - for ( i = 0; i < resource_cnt; ++i ) - { - error = FT_Stream_Seek( stream, offsets[i] ); - if ( error ) - goto Exit; - if ( FT_READ_LONG( temp ) ) - goto Exit; - pfb_len += temp + 6; - } - - if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) - goto Exit; - - pfb_data[0] = 0x80; - pfb_data[1] = 1; /* Ascii section */ - pfb_data[2] = 0; /* 4-byte length, fill in later */ - pfb_data[3] = 0; - pfb_data[4] = 0; - pfb_data[5] = 0; - pfb_pos = 6; - pfb_lenpos = 2; - - len = 0; - type = 1; - for ( i = 0; i < resource_cnt; ++i ) - { - error = FT_Stream_Seek( stream, offsets[i] ); - if ( error ) - goto Exit2; - if ( FT_READ_LONG( rlen ) ) - goto Exit; - if ( FT_READ_USHORT( flags ) ) - goto Exit; - FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", - i, offsets[i], rlen, flags )); - - /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ - if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ - continue; - - /* the flags are part of the resource, so rlen >= 2. */ - /* but some fonts declare rlen = 0 for empty fragment */ - if ( rlen > 2 ) - rlen -= 2; - else - rlen = 0; - - if ( ( flags >> 8 ) == type ) - len += rlen; - else - { - if ( pfb_lenpos + 3 > pfb_len + 2 ) - goto Exit2; - pfb_data[pfb_lenpos ] = (FT_Byte)( len ); - pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); - pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); - pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); - - if ( ( flags >> 8 ) == 5 ) /* End of font mark */ - break; - - if ( pfb_pos + 6 > pfb_len + 2 ) - goto Exit2; - pfb_data[pfb_pos++] = 0x80; - - type = flags >> 8; - len = rlen; - - pfb_data[pfb_pos++] = (FT_Byte)type; - pfb_lenpos = pfb_pos; - pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */ - pfb_data[pfb_pos++] = 0; - pfb_data[pfb_pos++] = 0; - pfb_data[pfb_pos++] = 0; - } - - error = FT_ERR( Cannot_Open_Resource ); - if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len ) - goto Exit2; - - error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); - if ( error ) - goto Exit2; - pfb_pos += rlen; - } - - if ( pfb_pos + 2 > pfb_len + 2 ) - goto Exit2; - pfb_data[pfb_pos++] = 0x80; - pfb_data[pfb_pos++] = 3; - - if ( pfb_lenpos + 3 > pfb_len + 2 ) - goto Exit2; - pfb_data[pfb_lenpos ] = (FT_Byte)( len ); - pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); - pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); - pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); - - return open_face_from_buffer( library, - pfb_data, - pfb_pos, - face_index, - "type1", - aface ); - - Exit2: - FT_FREE( pfb_data ); - - Exit: - return error; - } - - - /* The resource header says we've got resource_cnt `sfnt' */ - /* (TrueType/OpenType) resources in this file. Look through */ - /* them for the one indicated by face_index, load it into mem, */ - /* pass it on the the truetype driver and return it. */ - /* */ - static FT_Error - Mac_Read_sfnt_Resource( FT_Library library, - FT_Stream stream, - FT_Long *offsets, - FT_Long resource_cnt, - FT_Long face_index, - FT_Face *aface ) - { - FT_Memory memory = library->memory; - FT_Byte* sfnt_data = NULL; - FT_Error error; - FT_Long flag_offset; - FT_Long rlen; - int is_cff; - FT_Long face_index_in_resource = 0; - - - if ( face_index == -1 ) - face_index = 0; - if ( face_index >= resource_cnt ) - return FT_THROW( Cannot_Open_Resource ); - - flag_offset = offsets[face_index]; - error = FT_Stream_Seek( stream, flag_offset ); - if ( error ) - goto Exit; - - if ( FT_READ_LONG( rlen ) ) - goto Exit; - if ( rlen == -1 ) - return FT_THROW( Cannot_Open_Resource ); - - error = open_face_PS_from_sfnt_stream( library, - stream, - face_index, - 0, NULL, - aface ); - if ( !error ) - goto Exit; - - /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ - if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) - goto Exit; - - if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) - return error; - error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); - if ( error ) - goto Exit; - - is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); - error = open_face_from_buffer( library, - sfnt_data, - rlen, - face_index_in_resource, - is_cff ? "cff" : "truetype", - aface ); - - Exit: - return error; - } - - - /* Check for a valid resource fork header, or a valid dfont */ - /* header. In a resource fork the first 16 bytes are repeated */ - /* at the location specified by bytes 4-7. In a dfont bytes */ - /* 4-7 point to 16 bytes of zeroes instead. */ - /* */ - static FT_Error - IsMacResource( FT_Library library, - FT_Stream stream, - FT_Long resource_offset, - FT_Long face_index, - FT_Face *aface ) - { - FT_Memory memory = library->memory; - FT_Error error; - FT_Long map_offset, rdara_pos; - FT_Long *data_offsets; - FT_Long count; - - - error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, - &map_offset, &rdara_pos ); - if ( error ) - return error; - - error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, - TTAG_POST, - &data_offsets, &count ); - if ( !error ) - { - 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; - } - - error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, - TTAG_sfnt, - &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_internal, aface ); - FT_FREE( data_offsets ); - if ( !error ) - (*aface)->num_faces = count; - } - - return error; - } - - - /* Check for a valid macbinary header, and if we find one */ - /* check that the (flattened) resource fork in it is valid. */ - /* */ - static FT_Error - IsMacBinary( FT_Library library, - FT_Stream stream, - FT_Long face_index, - FT_Face *aface ) - { - unsigned char header[128]; - FT_Error error; - FT_Long dlen, offset; - - - if ( NULL == stream ) - return FT_THROW( Invalid_Stream_Operation ); - - error = FT_Stream_Seek( stream, 0 ); - if ( error ) - goto Exit; - - error = FT_Stream_Read( stream, (FT_Byte*)header, 128 ); - if ( error ) - goto Exit; - - if ( header[ 0] != 0 || - header[74] != 0 || - header[82] != 0 || - header[ 1] == 0 || - header[ 1] > 33 || - header[63] != 0 || - header[2 + header[1]] != 0 ) - return FT_THROW( Unknown_File_Format ); - - dlen = ( header[0x53] << 24 ) | - ( header[0x54] << 16 ) | - ( header[0x55] << 8 ) | - header[0x56]; -#if 0 - rlen = ( header[0x57] << 24 ) | - ( header[0x58] << 16 ) | - ( header[0x59] << 8 ) | - header[0x5a]; -#endif /* 0 */ - offset = 128 + ( ( dlen + 127 ) & ~127 ); - - return IsMacResource( library, stream, offset, face_index, aface ); - - Exit: - return error; - } - - - static FT_Error - load_face_in_embedded_rfork( FT_Library library, - FT_Stream stream, - FT_Long face_index, - FT_Face *aface, - const FT_Open_Args *args ) - { - -#undef FT_COMPONENT -#define FT_COMPONENT trace_raccess - - FT_Memory memory = library->memory; - FT_Error error = FT_ERR( Unknown_File_Format ); - int i; - - char * file_names[FT_RACCESS_N_RULES]; - FT_Long offsets[FT_RACCESS_N_RULES]; - FT_Error errors[FT_RACCESS_N_RULES]; - FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ - - FT_Open_Args args2; - FT_Stream stream2 = 0; - - - FT_Raccess_Guess( library, stream, - args->pathname, file_names, offsets, errors ); - - for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) - { - is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i ); - if ( is_darwin_vfs && vfs_rfork_has_no_font ) - { - FT_TRACE3(( "Skip rule %d: darwin vfs resource fork" - " is already checked and" - " no font is found\n", i )); - continue; - } - - if ( errors[i] ) - { - FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); - continue; - } - - args2.flags = FT_OPEN_PATHNAME; - args2.pathname = file_names[i] ? file_names[i] : args->pathname; - - FT_TRACE3(( "Try rule %d: %s (offset=%d) ...", - i, args2.pathname, offsets[i] )); - - error = FT_Stream_New( library, &args2, &stream2 ); - if ( is_darwin_vfs && FT_ERR_EQ( error, Cannot_Open_Stream ) ) - vfs_rfork_has_no_font = TRUE; - - if ( error ) - { - FT_TRACE3(( "failed\n" )); - continue; - } - - error = IsMacResource( library, stream2, offsets[i], - face_index, aface ); - FT_Stream_Free( stream2, 0 ); - - FT_TRACE3(( "%s\n", error ? "failed": "successful" )); - - if ( !error ) - break; - else if ( is_darwin_vfs ) - vfs_rfork_has_no_font = TRUE; - } - - for (i = 0; i < FT_RACCESS_N_RULES; i++) - { - if ( file_names[i] ) - FT_FREE( file_names[i] ); - } - - /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */ - if ( error ) - error = FT_ERR( Unknown_File_Format ); - - return error; - -#undef FT_COMPONENT -#define FT_COMPONENT trace_objs - - } - - - /* Check for some macintosh formats without Carbon framework. */ - /* Is this a macbinary file? If so look at the resource fork. */ - /* Is this a mac dfont file? */ - /* Is this an old style resource fork? (in data) */ - /* Else call load_face_in_embedded_rfork to try extra rules */ - /* (defined in `ftrfork.c'). */ - /* */ - static FT_Error - load_mac_face( FT_Library library, - FT_Stream stream, - FT_Long face_index, - FT_Face *aface, - const FT_Open_Args *args ) - { - FT_Error error; - FT_UNUSED( args ); - - - error = IsMacBinary( library, stream, face_index, aface ); - if ( FT_ERR_EQ( error, Unknown_File_Format ) ) - { - -#undef FT_COMPONENT -#define FT_COMPONENT trace_raccess - - FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); - - error = IsMacResource( library, stream, 0, face_index, aface ); - - FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); - -#undef FT_COMPONENT -#define FT_COMPONENT trace_objs - - } - - if ( ( FT_ERR_EQ( error, Unknown_File_Format ) || - FT_ERR_EQ( error, Invalid_Stream_Operation ) ) && - ( args->flags & FT_OPEN_PATHNAME ) ) - error = load_face_in_embedded_rfork( library, stream, - face_index, aface, args ); - return error; - } -#endif - -#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Open_Face( FT_Library library, - const FT_Open_Args* args, - FT_Long face_index, - FT_Face *aface ) - { - FT_Error error; - FT_Driver driver = NULL; - FT_Memory memory = NULL; - FT_Stream stream = NULL; - FT_Face face = NULL; - FT_ListNode node = NULL; - FT_Bool external_stream; - FT_Module* cur; - FT_Module* limit; - - - /* test for valid `library' delayed to */ - /* FT_Stream_New() */ - - if ( ( !aface && face_index >= 0 ) || !args ) - return FT_THROW( Invalid_Argument ); - - external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) && - args->stream ); - - /* create input stream */ - error = FT_Stream_New( library, args, &stream ); - if ( error ) - goto Fail3; - - memory = library->memory; - - /* If the font driver is specified in the `args' structure, use */ - /* it. Otherwise, we scan the list of registered drivers. */ - if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver ) - { - driver = FT_DRIVER( args->driver ); - - /* not all modules are drivers, so check... */ - if ( FT_MODULE_IS_DRIVER( driver ) ) - { - FT_Int num_params = 0; - FT_Parameter* params = 0; - - - if ( args->flags & FT_OPEN_PARAMS ) - { - num_params = args->num_params; - params = args->params; - } - - error = open_face( driver, stream, face_index, - num_params, params, &face ); - if ( !error ) - goto Success; - } - else - error = FT_THROW( Invalid_Handle ); - - FT_Stream_Free( stream, external_stream ); - goto Fail; - } - else - { - error = FT_ERR( Missing_Module ); - - /* check each font driver for an appropriate format */ - cur = library->modules; - limit = cur + library->num_modules; - - for ( ; cur < limit; cur++ ) - { - /* not all modules are font drivers, so check... */ - if ( FT_MODULE_IS_DRIVER( cur[0] ) ) - { - FT_Int num_params = 0; - FT_Parameter* params = 0; - - - driver = FT_DRIVER( cur[0] ); - - if ( args->flags & FT_OPEN_PARAMS ) - { - num_params = args->num_params; - params = args->params; - } - - error = open_face( driver, stream, face_index, - num_params, params, &face ); - if ( !error ) - goto Success; - -#ifdef FT_CONFIG_OPTION_MAC_FONTS - if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && - FT_ERR_EQ( error, Table_Missing ) ) - { - /* TrueType but essential tables are missing */ - if ( FT_Stream_Seek( stream, 0 ) ) - break; - - error = open_face_PS_from_sfnt_stream( library, - stream, - face_index, - num_params, - params, - aface ); - if ( !error ) - { - FT_Stream_Free( stream, external_stream ); - return error; - } - } -#endif - - if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) - goto Fail3; - } - } - - Fail3: - /* If we are on the mac, and we get an */ - /* FT_Err_Invalid_Stream_Operation it may be because we have an */ - /* empty data fork, so we need to check the resource fork. */ - if ( FT_ERR_NEQ( error, Cannot_Open_Stream ) && - FT_ERR_NEQ( error, Unknown_File_Format ) && - FT_ERR_NEQ( error, Invalid_Stream_Operation ) ) - goto Fail2; - -#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) - error = load_mac_face( library, stream, face_index, aface, args ); - if ( !error ) - { - /* We don't want to go to Success here. We've already done that. */ - /* On the other hand, if we succeeded we still need to close this */ - /* stream (we opened a different stream which extracted the */ - /* interesting information out of this stream here. That stream */ - /* will still be open and the face will point to it). */ - FT_Stream_Free( stream, external_stream ); - return error; - } - - if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) - goto Fail2; -#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ - - /* no driver is able to handle this format */ - error = FT_THROW( Unknown_File_Format ); - - Fail2: - FT_Stream_Free( stream, external_stream ); - goto Fail; - } - - Success: - FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); - - /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ - if ( external_stream ) - face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; - - /* add the face object to its driver's list */ - if ( FT_NEW( node ) ) - goto Fail; - - node->data = face; - /* don't assume driver is the same as face->driver, so use */ - /* face->driver instead. */ - FT_List_Add( &face->driver->faces_list, node ); - - /* now allocate a glyph slot object for the face */ - FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); - - if ( face_index >= 0 ) - { - error = FT_New_GlyphSlot( face, NULL ); - if ( error ) - goto Fail; - - /* finally, allocate a size object for the face */ - { - FT_Size size; - - - FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); - - error = FT_New_Size( face, &size ); - if ( error ) - goto Fail; - - face->size = size; - } - } - - /* some checks */ - - if ( FT_IS_SCALABLE( face ) ) - { - if ( face->height < 0 ) - face->height = (FT_Short)-face->height; - - if ( !FT_HAS_VERTICAL( face ) ) - face->max_advance_height = (FT_Short)face->height; - } - - if ( FT_HAS_FIXED_SIZES( face ) ) - { - FT_Int i; - - - for ( i = 0; i < face->num_fixed_sizes; i++ ) - { - FT_Bitmap_Size* bsize = face->available_sizes + i; - - - if ( bsize->height < 0 ) - bsize->height = (FT_Short)-bsize->height; - if ( bsize->x_ppem < 0 ) - bsize->x_ppem = (FT_Short)-bsize->x_ppem; - if ( bsize->y_ppem < 0 ) - bsize->y_ppem = -bsize->y_ppem; - } - } - - /* initialize internal face data */ - { - FT_Face_Internal internal = face->internal; - - - internal->transform_matrix.xx = 0x10000L; - internal->transform_matrix.xy = 0; - internal->transform_matrix.yx = 0; - internal->transform_matrix.yy = 0x10000L; - - internal->transform_delta.x = 0; - internal->transform_delta.y = 0; - - internal->refcount = 1; - } - - if ( aface ) - *aface = face; - else - FT_Done_Face( face ); - - goto Exit; - - Fail: - if ( node ) - FT_Done_Face( face ); /* face must be in the driver's list */ - else if ( face ) - destroy_face( memory, face, driver ); - - Exit: - FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Attach_File( FT_Face face, - const char* filepathname ) - { - FT_Open_Args open; - - - /* test for valid `face' delayed to FT_Attach_Stream() */ - - if ( !filepathname ) - return FT_THROW( Invalid_Argument ); - - open.stream = NULL; - open.flags = FT_OPEN_PATHNAME; - open.pathname = (char*)filepathname; - - return FT_Attach_Stream( face, &open ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Attach_Stream( FT_Face face, - FT_Open_Args* parameters ) - { - FT_Stream stream; - FT_Error error; - FT_Driver driver; - - FT_Driver_Class clazz; - - - /* test for valid `parameters' delayed to FT_Stream_New() */ - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - driver = face->driver; - if ( !driver ) - return FT_THROW( Invalid_Driver_Handle ); - - error = FT_Stream_New( driver->root.library, parameters, &stream ); - if ( error ) - goto Exit; - - /* we implement FT_Attach_Stream in each driver through the */ - /* `attach_file' interface */ - - error = FT_ERR( Unimplemented_Feature ); - clazz = driver->clazz; - if ( clazz->attach_file ) - error = clazz->attach_file( face, stream ); - - /* close the attached stream */ - FT_Stream_Free( stream, - (FT_Bool)( parameters->stream && - ( parameters->flags & FT_OPEN_STREAM ) ) ); - - Exit: - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Reference_Face( FT_Face face ) - { - face->internal->refcount++; - - return FT_Err_Ok; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Done_Face( FT_Face face ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_ListNode node; - - - error = FT_ERR( Invalid_Face_Handle ); - if ( face && face->driver ) - { - face->internal->refcount--; - if ( face->internal->refcount > 0 ) - error = FT_Err_Ok; - else - { - driver = face->driver; - memory = driver->root.memory; - - /* find face in driver's list */ - node = FT_List_Find( &driver->faces_list, face ); - if ( node ) - { - /* remove face object from the driver's list */ - FT_List_Remove( &driver->faces_list, node ); - FT_FREE( node ); - - /* now destroy the object proper */ - destroy_face( memory, face, driver ); - error = FT_Err_Ok; - } - } - } - - return error; - } - - - /* documentation is in ftobjs.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Size( FT_Face face, - FT_Size *asize ) - { - FT_Error error; - FT_Memory memory; - FT_Driver driver; - FT_Driver_Class clazz; - - FT_Size size = 0; - FT_ListNode node = 0; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - if ( !asize ) - return FT_THROW( Invalid_Size_Handle ); - - if ( !face->driver ) - return FT_THROW( Invalid_Driver_Handle ); - - *asize = 0; - - driver = face->driver; - clazz = driver->clazz; - memory = face->memory; - - /* Allocate new size object and perform basic initialisation */ - if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) - goto Exit; - - size->face = face; - - /* for now, do not use any internal fields in size objects */ - size->internal = 0; - - if ( clazz->init_size ) - error = clazz->init_size( size ); - - /* in case of success, add to the face's list */ - if ( !error ) - { - *asize = size; - node->data = size; - FT_List_Add( &face->sizes_list, node ); - } - - Exit: - if ( error ) - { - FT_FREE( node ); - FT_FREE( size ); - } - - return error; - } - - - /* documentation is in ftobjs.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Done_Size( FT_Size size ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_Face face; - FT_ListNode node; - - - if ( !size ) - return FT_THROW( Invalid_Size_Handle ); - - face = size->face; - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - driver = face->driver; - if ( !driver ) - return FT_THROW( Invalid_Driver_Handle ); - - memory = driver->root.memory; - - error = FT_Err_Ok; - node = FT_List_Find( &face->sizes_list, size ); - if ( node ) - { - FT_List_Remove( &face->sizes_list, node ); - FT_FREE( node ); - - if ( face->size == size ) - { - face->size = 0; - if ( face->sizes_list.head ) - face->size = (FT_Size)(face->sizes_list.head->data); - } - - destroy_size( memory, size, driver ); - } - else - error = FT_THROW( Invalid_Size_Handle ); - - return error; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( FT_Error ) - FT_Match_Size( FT_Face face, - FT_Size_Request req, - FT_Bool ignore_width, - FT_ULong* size_index ) - { - FT_Int i; - FT_Long w, h; - - - if ( !FT_HAS_FIXED_SIZES( face ) ) - return FT_THROW( Invalid_Face_Handle ); - - /* FT_Bitmap_Size doesn't provide enough info... */ - if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) - return FT_THROW( Unimplemented_Feature ); - - w = FT_REQUEST_WIDTH ( req ); - h = FT_REQUEST_HEIGHT( req ); - - if ( req->width && !req->height ) - h = w; - else if ( !req->width && req->height ) - w = h; - - w = FT_PIX_ROUND( w ); - h = FT_PIX_ROUND( h ); - - for ( i = 0; i < face->num_fixed_sizes; i++ ) - { - FT_Bitmap_Size* bsize = face->available_sizes + i; - - - if ( h != FT_PIX_ROUND( bsize->y_ppem ) ) - continue; - - if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width ) - { - FT_TRACE3(( "FT_Match_Size: bitmap strike %d matches\n", i )); - - if ( size_index ) - *size_index = (FT_ULong)i; - - return FT_Err_Ok; - } - } - - return FT_THROW( Invalid_Pixel_Size ); - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( void ) - ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, - FT_Pos advance ) - { - FT_Pos height = metrics->height; - - - /* compensate for glyph with bbox above/below the baseline */ - if ( metrics->horiBearingY < 0 ) - { - if ( height < metrics->horiBearingY ) - height = metrics->horiBearingY; - } - else if ( metrics->horiBearingY > 0 ) - height -= metrics->horiBearingY; - - /* the factor 1.2 is a heuristical value */ - if ( !advance ) - advance = height * 12 / 10; - - metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; - metrics->vertBearingY = ( advance - height ) / 2; - metrics->vertAdvance = advance; - } - - - static void - ft_recompute_scaled_metrics( FT_Face face, - FT_Size_Metrics* metrics ) - { - /* Compute root ascender, descender, test height, and max_advance */ - -#ifdef GRID_FIT_METRICS - metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender, - metrics->y_scale ) ); - - metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender, - metrics->y_scale ) ); - - metrics->height = FT_PIX_ROUND( FT_MulFix( face->height, - metrics->y_scale ) ); - - metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width, - metrics->x_scale ) ); -#else /* !GRID_FIT_METRICS */ - metrics->ascender = FT_MulFix( face->ascender, - metrics->y_scale ); - - metrics->descender = FT_MulFix( face->descender, - metrics->y_scale ); - - metrics->height = FT_MulFix( face->height, - metrics->y_scale ); - - metrics->max_advance = FT_MulFix( face->max_advance_width, - metrics->x_scale ); -#endif /* !GRID_FIT_METRICS */ - } - - - FT_BASE_DEF( void ) - FT_Select_Metrics( FT_Face face, - FT_ULong strike_index ) - { - FT_Size_Metrics* metrics; - FT_Bitmap_Size* bsize; - - - metrics = &face->size->metrics; - bsize = face->available_sizes + strike_index; - - metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 ); - metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 ); - - if ( FT_IS_SCALABLE( face ) ) - { - metrics->x_scale = FT_DivFix( bsize->x_ppem, - face->units_per_EM ); - metrics->y_scale = FT_DivFix( bsize->y_ppem, - face->units_per_EM ); - - ft_recompute_scaled_metrics( face, metrics ); - } - else - { - metrics->x_scale = 1L << 16; - metrics->y_scale = 1L << 16; - metrics->ascender = bsize->y_ppem; - metrics->descender = 0; - metrics->height = bsize->height << 6; - metrics->max_advance = bsize->x_ppem; - } - - FT_TRACE5(( "FT_Select_Metrics:\n" )); - FT_TRACE5(( " x scale: %d (%f)\n", - metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", - metrics->y_scale, metrics->y_scale / 65536.0 )); - FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); - FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); - FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); - FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); - FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); - FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); - } - - - FT_BASE_DEF( void ) - FT_Request_Metrics( FT_Face face, - FT_Size_Request req ) - { - FT_Size_Metrics* metrics; - - - metrics = &face->size->metrics; - - if ( FT_IS_SCALABLE( face ) ) - { - FT_Long w = 0, h = 0, scaled_w = 0, scaled_h = 0; - - - switch ( req->type ) - { - case FT_SIZE_REQUEST_TYPE_NOMINAL: - w = h = face->units_per_EM; - break; - - case FT_SIZE_REQUEST_TYPE_REAL_DIM: - w = h = face->ascender - face->descender; - break; - - case FT_SIZE_REQUEST_TYPE_BBOX: - w = face->bbox.xMax - face->bbox.xMin; - h = face->bbox.yMax - face->bbox.yMin; - break; - - case FT_SIZE_REQUEST_TYPE_CELL: - w = face->max_advance_width; - h = face->ascender - face->descender; - break; - - case FT_SIZE_REQUEST_TYPE_SCALES: - metrics->x_scale = (FT_Fixed)req->width; - metrics->y_scale = (FT_Fixed)req->height; - if ( !metrics->x_scale ) - metrics->x_scale = metrics->y_scale; - else if ( !metrics->y_scale ) - metrics->y_scale = metrics->x_scale; - goto Calculate_Ppem; - - case FT_SIZE_REQUEST_TYPE_MAX: - break; - } - - /* to be on the safe side */ - if ( w < 0 ) - w = -w; - - if ( h < 0 ) - h = -h; - - scaled_w = FT_REQUEST_WIDTH ( req ); - scaled_h = FT_REQUEST_HEIGHT( req ); - - /* determine scales */ - if ( req->width ) - { - metrics->x_scale = FT_DivFix( scaled_w, w ); - - if ( req->height ) - { - metrics->y_scale = FT_DivFix( scaled_h, h ); - - if ( req->type == FT_SIZE_REQUEST_TYPE_CELL ) - { - if ( metrics->y_scale > metrics->x_scale ) - metrics->y_scale = metrics->x_scale; - else - metrics->x_scale = metrics->y_scale; - } - } - else - { - metrics->y_scale = metrics->x_scale; - scaled_h = FT_MulDiv( scaled_w, h, w ); - } - } - else - { - metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h ); - scaled_w = FT_MulDiv( scaled_h, w, h ); - } - - Calculate_Ppem: - /* calculate the ppems */ - if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) - { - scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale ); - scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale ); - } - - metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 ); - metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 ); - - ft_recompute_scaled_metrics( face, metrics ); - } - else - { - FT_ZERO( metrics ); - metrics->x_scale = 1L << 16; - metrics->y_scale = 1L << 16; - } - - FT_TRACE5(( "FT_Request_Metrics:\n" )); - FT_TRACE5(( " x scale: %d (%f)\n", - metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", - metrics->y_scale, metrics->y_scale / 65536.0 )); - FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); - FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); - FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); - FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); - FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); - FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Select_Size( FT_Face face, - FT_Int strike_index ) - { - FT_Driver_Class clazz; - - - if ( !face || !FT_HAS_FIXED_SIZES( face ) ) - return FT_THROW( Invalid_Face_Handle ); - - if ( strike_index < 0 || strike_index >= face->num_fixed_sizes ) - return FT_THROW( Invalid_Argument ); - - clazz = face->driver->clazz; - - if ( clazz->select_size ) - { - FT_Error error; - - - error = clazz->select_size( face->size, (FT_ULong)strike_index ); - -#ifdef FT_DEBUG_LEVEL_TRACE - { - FT_Size_Metrics* metrics = &face->size->metrics; - - - FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" )); - FT_TRACE5(( " x scale: %d (%f)\n", - metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", - metrics->y_scale, metrics->y_scale / 65536.0 )); - FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); - FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); - FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); - FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); - FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); - FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); - } -#endif - - return error; - } - - FT_Select_Metrics( face, (FT_ULong)strike_index ); - - return FT_Err_Ok; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Request_Size( FT_Face face, - FT_Size_Request req ) - { - FT_Driver_Class clazz; - FT_ULong strike_index; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - if ( !req || req->width < 0 || req->height < 0 || - req->type >= FT_SIZE_REQUEST_TYPE_MAX ) - return FT_THROW( Invalid_Argument ); - - clazz = face->driver->clazz; - - if ( clazz->request_size ) - { - FT_Error error; - - - error = clazz->request_size( face->size, req ); - -#ifdef FT_DEBUG_LEVEL_TRACE - { - FT_Size_Metrics* metrics = &face->size->metrics; - - - FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" )); - FT_TRACE5(( " x scale: %d (%f)\n", - metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", - metrics->y_scale, metrics->y_scale / 65536.0 )); - FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); - FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); - FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); - FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); - FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); - FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); - } -#endif - - return error; - } - - /* - * The reason that a driver doesn't have `request_size' defined is - * either that the scaling here suffices or that the supported formats - * are bitmap-only and size matching is not implemented. - * - * In the latter case, a simple size matching is done. - */ - if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) ) - { - FT_Error error; - - - error = FT_Match_Size( face, req, 0, &strike_index ); - if ( error ) - return error; - - return FT_Select_Size( face, (FT_Int)strike_index ); - } - - FT_Request_Metrics( face, req ); - - return FT_Err_Ok; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Char_Size( FT_Face face, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - FT_Size_RequestRec req; - - - if ( !char_width ) - char_width = char_height; - else if ( !char_height ) - char_height = char_width; - - if ( !horz_resolution ) - horz_resolution = vert_resolution; - else if ( !vert_resolution ) - vert_resolution = horz_resolution; - - if ( char_width < 1 * 64 ) - char_width = 1 * 64; - if ( char_height < 1 * 64 ) - char_height = 1 * 64; - - if ( !horz_resolution ) - horz_resolution = vert_resolution = 72; - - req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = char_width; - req.height = char_height; - req.horiResolution = horz_resolution; - req.vertResolution = vert_resolution; - - return FT_Request_Size( face, &req ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Pixel_Sizes( FT_Face face, - FT_UInt pixel_width, - FT_UInt pixel_height ) - { - FT_Size_RequestRec req; - - - if ( pixel_width == 0 ) - pixel_width = pixel_height; - else if ( pixel_height == 0 ) - pixel_height = pixel_width; - - if ( pixel_width < 1 ) - pixel_width = 1; - if ( pixel_height < 1 ) - pixel_height = 1; - - /* use `>=' to avoid potential compiler warning on 16bit platforms */ - if ( pixel_width >= 0xFFFFU ) - pixel_width = 0xFFFFU; - if ( pixel_height >= 0xFFFFU ) - pixel_height = 0xFFFFU; - - req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = pixel_width << 6; - req.height = pixel_height << 6; - req.horiResolution = 0; - req.vertResolution = 0; - - return FT_Request_Size( face, &req ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Kerning( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_UInt kern_mode, - FT_Vector *akerning ) - { - FT_Error error = FT_Err_Ok; - FT_Driver driver; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - if ( !akerning ) - return FT_THROW( Invalid_Argument ); - - driver = face->driver; - - akerning->x = 0; - akerning->y = 0; - - if ( driver->clazz->get_kerning ) - { - error = driver->clazz->get_kerning( face, - left_glyph, - right_glyph, - akerning ); - if ( !error ) - { - if ( kern_mode != FT_KERNING_UNSCALED ) - { - akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale ); - akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale ); - - if ( kern_mode != FT_KERNING_UNFITTED ) - { - /* we scale down kerning values for small ppem values */ - /* to avoid that rounding makes them too big. */ - /* `25' has been determined heuristically. */ - if ( face->size->metrics.x_ppem < 25 ) - akerning->x = FT_MulDiv( akerning->x, - face->size->metrics.x_ppem, 25 ); - if ( face->size->metrics.y_ppem < 25 ) - akerning->y = FT_MulDiv( akerning->y, - face->size->metrics.y_ppem, 25 ); - - akerning->x = FT_PIX_ROUND( akerning->x ); - akerning->y = FT_PIX_ROUND( akerning->y ); - } - } - } - } - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Track_Kerning( FT_Face face, - FT_Fixed point_size, - FT_Int degree, - FT_Fixed* akerning ) - { - FT_Service_Kerning service; - FT_Error error = FT_Err_Ok; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - if ( !akerning ) - return FT_THROW( Invalid_Argument ); - - FT_FACE_FIND_SERVICE( face, service, KERNING ); - if ( !service ) - return FT_THROW( Unimplemented_Feature ); - - error = service->get_track( face, - point_size, - degree, - akerning ); - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Select_Charmap( FT_Face face, - FT_Encoding encoding ) - { - FT_CharMap* cur; - FT_CharMap* limit; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - if ( encoding == FT_ENCODING_NONE ) - return FT_THROW( 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. */ - /* */ - /* This is done by find_unicode_charmap() above, to share code. */ - if ( encoding == FT_ENCODING_UNICODE ) - return find_unicode_charmap( face ); - - cur = face->charmaps; - if ( !cur ) - return FT_THROW( Invalid_CharMap_Handle ); - - limit = cur + face->num_charmaps; - - for ( ; cur < limit; cur++ ) - { - if ( cur[0]->encoding == encoding ) - { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), " - "but in too late position to cache\n", - cur - face->charmaps )); - continue; - } -#endif - face->charmap = cur[0]; - return 0; - } - } - - return FT_THROW( Invalid_Argument ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Charmap( FT_Face face, - FT_CharMap charmap ) - { - FT_CharMap* cur; - FT_CharMap* limit; - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - cur = face->charmaps; - if ( !cur ) - return FT_THROW( Invalid_CharMap_Handle ); - if ( FT_Get_CMap_Format( charmap ) == 14 ) - return FT_THROW( Invalid_Argument ); - - limit = cur + face->num_charmaps; - - for ( ; cur < limit; cur++ ) - { - if ( cur[0] == charmap ) - { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), " - "but in too late position to cache\n", - cur - face->charmaps )); - continue; - } -#endif - face->charmap = cur[0]; - return 0; - } - } - return FT_THROW( Invalid_Argument ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Int ) - FT_Get_Charmap_Index( FT_CharMap charmap ) - { - FT_Int i; - - - if ( !charmap || !charmap->face ) - return -1; - - for ( i = 0; i < charmap->face->num_charmaps; i++ ) - if ( charmap->face->charmaps[i] == charmap ) - break; - - FT_ASSERT( i < charmap->face->num_charmaps ); - -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( i > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), " - "but in too late position to cache\n", - i )); - return -i; - } -#endif - return i; - } - - - static void - ft_cmap_done_internal( FT_CMap cmap ) - { - FT_CMap_Class clazz = cmap->clazz; - FT_Face face = cmap->charmap.face; - FT_Memory memory = FT_FACE_MEMORY( face ); - - - if ( clazz->done ) - clazz->done( cmap ); - - FT_FREE( cmap ); - } - - - FT_BASE_DEF( void ) - FT_CMap_Done( FT_CMap cmap ) - { - if ( cmap ) - { - FT_Face face = cmap->charmap.face; - FT_Memory memory = FT_FACE_MEMORY( face ); - FT_Error error; - FT_Int i, j; - - - for ( i = 0; i < face->num_charmaps; i++ ) - { - if ( (FT_CMap)face->charmaps[i] == cmap ) - { - FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1]; - - - if ( FT_RENEW_ARRAY( face->charmaps, - face->num_charmaps, - face->num_charmaps - 1 ) ) - return; - - /* remove it from our list of charmaps */ - for ( j = i + 1; j < face->num_charmaps; j++ ) - { - if ( j == face->num_charmaps - 1 ) - face->charmaps[j - 1] = last_charmap; - else - face->charmaps[j - 1] = face->charmaps[j]; - } - - face->num_charmaps--; - - if ( (FT_CMap)face->charmap == cmap ) - face->charmap = NULL; - - ft_cmap_done_internal( cmap ); - - break; - } - } - } - } - - - FT_BASE_DEF( FT_Error ) - FT_CMap_New( FT_CMap_Class clazz, - FT_Pointer init_data, - FT_CharMap charmap, - FT_CMap *acmap ) - { - FT_Error error = FT_Err_Ok; - FT_Face face; - FT_Memory memory; - FT_CMap cmap = NULL; - - - if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) - return FT_THROW( Invalid_Argument ); - - face = charmap->face; - memory = FT_FACE_MEMORY( face ); - - if ( !FT_ALLOC( cmap, clazz->size ) ) - { - cmap->charmap = *charmap; - cmap->clazz = clazz; - - if ( clazz->init ) - { - error = clazz->init( cmap, init_data ); - if ( error ) - goto Fail; - } - - /* add it to our list of charmaps */ - if ( FT_RENEW_ARRAY( face->charmaps, - face->num_charmaps, - face->num_charmaps + 1 ) ) - goto Fail; - - face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; - } - - Exit: - if ( acmap ) - *acmap = cmap; - - return error; - - Fail: - ft_cmap_done_internal( cmap ); - cmap = NULL; - goto Exit; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Get_Char_Index( FT_Face face, - FT_ULong charcode ) - { - FT_UInt result = 0; - - - if ( face && face->charmap ) - { - FT_CMap cmap = FT_CMAP( face->charmap ); - - - if ( charcode > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); - FT_TRACE1(( " 0x%x is truncated\n", charcode )); - } - result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); - } - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_ULong ) - FT_Get_First_Char( FT_Face face, - FT_UInt *agindex ) - { - FT_ULong result = 0; - FT_UInt gindex = 0; - - - if ( face && face->charmap && face->num_glyphs ) - { - gindex = FT_Get_Char_Index( face, 0 ); - if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs ) - result = FT_Get_Next_Char( face, 0, &gindex ); - } - - if ( agindex ) - *agindex = gindex; - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_ULong ) - FT_Get_Next_Char( FT_Face face, - FT_ULong charcode, - FT_UInt *agindex ) - { - FT_ULong result = 0; - FT_UInt gindex = 0; - - - if ( face && face->charmap && face->num_glyphs ) - { - FT_UInt32 code = (FT_UInt32)charcode; - FT_CMap cmap = FT_CMAP( face->charmap ); - - - do { - gindex = cmap->clazz->char_next( cmap, &code ); - } while ( gindex >= (FT_UInt)face->num_glyphs ); - - result = ( gindex == 0 ) ? 0 : code; - } - - if ( agindex ) - *agindex = gindex; - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Face_GetCharVariantIndex( FT_Face face, - FT_ULong charcode, - FT_ULong variantSelector ) - { - FT_UInt result = 0; - - - if ( face && face->charmap && - face->charmap->encoding == FT_ENCODING_UNICODE ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - FT_CMap ucmap = FT_CMAP( face->charmap ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - - - if ( charcode > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); - FT_TRACE1(( " 0x%x is truncated\n", charcode )); - } - if ( variantSelector > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); - FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); - } - - result = vcmap->clazz->char_var_index( vcmap, ucmap, - (FT_UInt32)charcode, - (FT_UInt32)variantSelector ); - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Int ) - FT_Face_GetCharVariantIsDefault( FT_Face face, - FT_ULong charcode, - FT_ULong variantSelector ) - { - FT_Int result = -1; - - - if ( face ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - - - if ( charcode > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); - FT_TRACE1(( " 0x%x is truncated\n", charcode )); - } - if ( variantSelector > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); - FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); - } - - result = vcmap->clazz->char_var_default( vcmap, - (FT_UInt32)charcode, - (FT_UInt32)variantSelector ); - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt32* ) - FT_Face_GetVariantSelectors( FT_Face face ) - { - FT_UInt32 *result = NULL; - - - if ( face ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - FT_Memory memory = FT_FACE_MEMORY( face ); - - - result = vcmap->clazz->variant_list( vcmap, memory ); - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt32* ) - FT_Face_GetVariantsOfChar( FT_Face face, - FT_ULong charcode ) - { - FT_UInt32 *result = NULL; - - - if ( face ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - FT_Memory memory = FT_FACE_MEMORY( face ); - - - if ( charcode > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); - FT_TRACE1(( " 0x%x is truncated\n", charcode )); - } - - result = vcmap->clazz->charvariant_list( vcmap, memory, - (FT_UInt32)charcode ); - } - } - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt32* ) - FT_Face_GetCharsOfVariant( FT_Face face, - FT_ULong variantSelector ) - { - FT_UInt32 *result = NULL; - - - if ( face ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - FT_Memory memory = FT_FACE_MEMORY( face ); - - - if ( variantSelector > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); - FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); - } - - result = vcmap->clazz->variantchar_list( vcmap, memory, - (FT_UInt32)variantSelector ); - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Get_Name_Index( FT_Face face, - FT_String* glyph_name ) - { - FT_UInt result = 0; - - - if ( face && FT_HAS_GLYPH_NAMES( face ) ) - { - FT_Service_GlyphDict service; - - - FT_FACE_LOOKUP_SERVICE( face, - service, - GLYPH_DICT ); - - if ( service && service->name_index ) - result = service->name_index( face, glyph_name ); - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Glyph_Name( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - - - /* clean up buffer */ - if ( buffer && buffer_max > 0 ) - ((FT_Byte*)buffer)[0] = 0; - - if ( face && - (FT_Long)glyph_index <= face->num_glyphs && - FT_HAS_GLYPH_NAMES( face ) ) - { - FT_Service_GlyphDict service; - - - FT_FACE_LOOKUP_SERVICE( face, - service, - GLYPH_DICT ); - - if ( service && service->get_name ) - error = service->get_name( face, glyph_index, buffer, buffer_max ); - } - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( const char* ) - FT_Get_Postscript_Name( FT_Face face ) - { - const char* result = NULL; - - - if ( !face ) - goto Exit; - - if ( !result ) - { - FT_Service_PsFontName service; - - - FT_FACE_LOOKUP_SERVICE( face, - service, - POSTSCRIPT_FONT_NAME ); - - if ( service && service->get_ps_font_name ) - result = service->get_ps_font_name( face ); - } - - Exit: - return result; - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( void* ) - FT_Get_Sfnt_Table( FT_Face face, - FT_Sfnt_Tag tag ) - { - void* table = 0; - FT_Service_SFNT_Table service; - - - if ( face && FT_IS_SFNT( face ) ) - { - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service != NULL ) - table = service->get_table( face, tag ); - } - - return table; - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Load_Sfnt_Table( FT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ) - { - FT_Service_SFNT_Table service; - - - if ( !face || !FT_IS_SFNT( face ) ) - return FT_THROW( Invalid_Face_Handle ); - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) - return FT_THROW( Unimplemented_Feature ); - - return service->load_table( face, tag, offset, buffer, length ); - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Sfnt_Table_Info( FT_Face face, - FT_UInt table_index, - FT_ULong *tag, - FT_ULong *length ) - { - FT_Service_SFNT_Table service; - FT_ULong offset; - - - if ( !face || !FT_IS_SFNT( face ) ) - return FT_THROW( Invalid_Face_Handle ); - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) - return FT_THROW( Unimplemented_Feature ); - - return service->table_info( face, table_index, tag, &offset, length ); - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( FT_ULong ) - FT_Get_CMap_Language_ID( FT_CharMap charmap ) - { - FT_Service_TTCMaps service; - FT_Face face; - TT_CMapInfo cmap_info; - - - if ( !charmap || !charmap->face ) - return 0; - - face = charmap->face; - FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) - return 0; - if ( service->get_cmap_info( charmap, &cmap_info )) - return 0; - - return cmap_info.language; - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_Get_CMap_Format( FT_CharMap charmap ) - { - FT_Service_TTCMaps service; - FT_Face face; - TT_CMapInfo cmap_info; - - - if ( !charmap || !charmap->face ) - return -1; - - face = charmap->face; - FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) - return -1; - if ( service->get_cmap_info( charmap, &cmap_info )) - return -1; - - return cmap_info.format; - } - - - /* documentation is in ftsizes.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Activate_Size( FT_Size size ) - { - FT_Face face; - - - if ( size == NULL ) - return FT_THROW( Invalid_Argument ); - - face = size->face; - if ( face == NULL || face->driver == NULL ) - return FT_THROW( Invalid_Argument ); - - /* we don't need anything more complex than that; all size objects */ - /* are already listed by the face */ - face->size = size; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** R E N D E R E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* lookup a renderer by glyph format in the library's list */ - FT_BASE_DEF( FT_Renderer ) - FT_Lookup_Renderer( FT_Library library, - FT_Glyph_Format format, - FT_ListNode* node ) - { - FT_ListNode cur; - FT_Renderer result = 0; - - - if ( !library ) - goto Exit; - - cur = library->renderers.head; - - if ( node ) - { - if ( *node ) - cur = (*node)->next; - *node = 0; - } - - while ( cur ) - { - FT_Renderer renderer = FT_RENDERER( cur->data ); - - - if ( renderer->glyph_format == format ) - { - if ( node ) - *node = cur; - - result = renderer; - break; - } - cur = cur->next; - } - - Exit: - return result; - } - - - static FT_Renderer - ft_lookup_glyph_renderer( FT_GlyphSlot slot ) - { - FT_Face face = slot->face; - FT_Library library = FT_FACE_LIBRARY( face ); - FT_Renderer result = library->cur_renderer; - - - if ( !result || result->glyph_format != slot->format ) - result = FT_Lookup_Renderer( library, slot->format, 0 ); - - return result; - } - - - static void - ft_set_current_renderer( FT_Library library ) - { - FT_Renderer renderer; - - - renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 ); - library->cur_renderer = renderer; - } - - - static FT_Error - ft_add_renderer( FT_Module module ) - { - FT_Library library = module->library; - FT_Memory memory = library->memory; - FT_Error error; - FT_ListNode node = NULL; - - - if ( FT_NEW( node ) ) - goto Exit; - - { - FT_Renderer render = FT_RENDERER( module ); - FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; - - - render->clazz = clazz; - render->glyph_format = clazz->glyph_format; - - /* allocate raster object if needed */ - if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - clazz->raster_class->raster_new ) - { - error = clazz->raster_class->raster_new( memory, &render->raster ); - if ( error ) - goto Fail; - - render->raster_render = clazz->raster_class->raster_render; - render->render = clazz->render_glyph; - } - - /* add to list */ - node->data = module; - FT_List_Add( &library->renderers, node ); - - ft_set_current_renderer( library ); - } - - Fail: - if ( error ) - FT_FREE( node ); - - Exit: - return error; - } - - - static void - ft_remove_renderer( FT_Module module ) - { - FT_Library library = module->library; - FT_Memory memory = library->memory; - FT_ListNode node; - - - node = FT_List_Find( &library->renderers, module ); - if ( node ) - { - FT_Renderer render = FT_RENDERER( module ); - - - /* release raster object, if any */ - if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - render->raster ) - render->clazz->raster_class->raster_done( render->raster ); - - /* remove from list */ - FT_List_Remove( &library->renderers, node ); - FT_FREE( node ); - - ft_set_current_renderer( library ); - } - } - - - /* documentation is in ftrender.h */ - - FT_EXPORT_DEF( FT_Renderer ) - FT_Get_Renderer( FT_Library library, - FT_Glyph_Format format ) - { - /* test for valid `library' delayed to FT_Lookup_Renderer() */ - - return FT_Lookup_Renderer( library, format, 0 ); - } - - - /* documentation is in ftrender.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Renderer( FT_Library library, - FT_Renderer renderer, - FT_UInt num_params, - FT_Parameter* parameters ) - { - FT_ListNode node; - FT_Error error = FT_Err_Ok; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( !renderer ) - return FT_THROW( Invalid_Argument ); - - node = FT_List_Find( &library->renderers, renderer ); - if ( !node ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - FT_List_Up( &library->renderers, node ); - - if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) - library->cur_renderer = renderer; - - if ( num_params > 0 ) - { - FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; - - - for ( ; num_params > 0; num_params-- ) - { - error = set_mode( renderer, parameters->tag, parameters->data ); - if ( error ) - break; - parameters++; - } - } - - Exit: - return error; - } - - - FT_BASE_DEF( FT_Error ) - FT_Render_Glyph_Internal( FT_Library library, - FT_GlyphSlot slot, - FT_Render_Mode render_mode ) - { - FT_Error error = FT_Err_Ok; - FT_Renderer renderer; - - - /* if it is already a bitmap, no need to do anything */ - switch ( slot->format ) - { - case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ - break; - - default: - { - FT_ListNode node = 0; - FT_Bool update = 0; - - - /* small shortcut for the very common case */ - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - renderer = library->cur_renderer; - node = library->renderers.head; - } - else - renderer = FT_Lookup_Renderer( library, slot->format, &node ); - - error = FT_ERR( Unimplemented_Feature ); - while ( renderer ) - { - error = renderer->render( renderer, slot, render_mode, NULL ); - if ( !error || - FT_ERR_NEQ( error, Cannot_Render_Glyph ) ) - break; - - /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ - /* is unsupported by the current renderer for this glyph image */ - /* format. */ - - /* now, look for another renderer that supports the same */ - /* format. */ - renderer = FT_Lookup_Renderer( library, slot->format, &node ); - update = 1; - } - - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); - } - } - -#ifdef FT_DEBUG_LEVEL_TRACE - -#undef FT_COMPONENT -#define FT_COMPONENT trace_bitmap - - /* we convert to a single bitmap format for computing the checksum */ - { - FT_Bitmap bitmap; - FT_Error err; - - - FT_Bitmap_New( &bitmap ); - - err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); - if ( !err ) - { - MD5_CTX ctx; - unsigned char md5[16]; - int i; - - - MD5_Init( &ctx); - MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch ); - MD5_Final( md5, &ctx ); - - FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" - " ", - bitmap.rows, bitmap.pitch )); - for ( i = 0; i < 16; i++ ) - FT_TRACE3(( "%02X", md5[i] )); - FT_TRACE3(( "\n" )); - } - - FT_Bitmap_Done( library, &bitmap ); - } - -#undef FT_COMPONENT -#define FT_COMPONENT trace_objs - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Render_Glyph( FT_GlyphSlot slot, - FT_Render_Mode render_mode ) - { - FT_Library library; - - - if ( !slot || !slot->face ) - return FT_THROW( Invalid_Argument ); - - library = FT_FACE_LIBRARY( slot->face ); - - return FT_Render_Glyph_Internal( library, slot, render_mode ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M O D U L E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Destroy_Module */ - /* */ - /* <Description> */ - /* Destroys a given module object. For drivers, this also destroys */ - /* all child faces. */ - /* */ - /* <InOut> */ - /* module :: A handle to the target driver object. */ - /* */ - /* <Note> */ - /* The driver _must_ be LOCKED! */ - /* */ - static void - Destroy_Module( FT_Module module ) - { - FT_Memory memory = module->memory; - FT_Module_Class* clazz = module->clazz; - FT_Library library = module->library; - - - if ( library && library->auto_hinter == module ) - library->auto_hinter = 0; - - /* if the module is a renderer */ - if ( FT_MODULE_IS_RENDERER( module ) ) - ft_remove_renderer( module ); - - /* if the module is a font driver, add some steps */ - if ( FT_MODULE_IS_DRIVER( module ) ) - Destroy_Driver( FT_DRIVER( module ) ); - - /* finalize the module object */ - if ( clazz->module_done ) - clazz->module_done( module ); - - /* discard it */ - FT_FREE( module ); - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Add_Module( FT_Library library, - const FT_Module_Class* clazz ) - { - FT_Error error; - FT_Memory memory; - FT_Module module; - FT_UInt nn; - - -#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ - FREETYPE_MINOR ) - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( !clazz ) - return FT_THROW( Invalid_Argument ); - - /* check freetype version */ - if ( clazz->module_requires > FREETYPE_VER_FIXED ) - return FT_THROW( Invalid_Version ); - - /* look for a module with the same name in the library's table */ - for ( nn = 0; nn < library->num_modules; nn++ ) - { - module = library->modules[nn]; - if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) - { - /* this installed module has the same name, compare their versions */ - if ( clazz->module_version <= module->clazz->module_version ) - return FT_THROW( Lower_Module_Version ); - - /* remove the module from our list, then exit the loop to replace */ - /* it by our new version.. */ - FT_Remove_Module( library, module ); - break; - } - } - - memory = library->memory; - error = FT_Err_Ok; - - if ( library->num_modules >= FT_MAX_MODULES ) - { - error = FT_THROW( Too_Many_Drivers ); - goto Exit; - } - - /* allocate module object */ - if ( FT_ALLOC( module, clazz->module_size ) ) - goto Exit; - - /* base initialization */ - module->library = library; - module->memory = memory; - module->clazz = (FT_Module_Class*)clazz; - - /* check whether the module is a renderer - this must be performed */ - /* before the normal module initialization */ - if ( FT_MODULE_IS_RENDERER( module ) ) - { - /* add to the renderers list */ - error = ft_add_renderer( module ); - if ( error ) - goto Fail; - } - - /* is the module a auto-hinter? */ - if ( FT_MODULE_IS_HINTER( module ) ) - library->auto_hinter = module; - - /* if the module is a font driver */ - if ( FT_MODULE_IS_DRIVER( module ) ) - { - /* allocate glyph loader if needed */ - FT_Driver driver = FT_DRIVER( module ); - - - driver->clazz = (FT_Driver_Class)module->clazz; - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - { - error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); - if ( error ) - goto Fail; - } - } - - if ( clazz->module_init ) - { - error = clazz->module_init( module ); - if ( error ) - goto Fail; - } - - /* add module to the library's table */ - library->modules[library->num_modules++] = module; - - Exit: - return error; - - Fail: - if ( FT_MODULE_IS_DRIVER( module ) ) - { - FT_Driver driver = FT_DRIVER( module ); - - - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); - } - - if ( FT_MODULE_IS_RENDERER( module ) ) - { - FT_Renderer renderer = FT_RENDERER( module ); - - - if ( renderer->clazz && - renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - renderer->raster ) - renderer->clazz->raster_class->raster_done( renderer->raster ); - } - - FT_FREE( module ); - goto Exit; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Module ) - FT_Get_Module( FT_Library library, - const char* module_name ) - { - FT_Module result = 0; - FT_Module* cur; - FT_Module* limit; - - - if ( !library || !module_name ) - return result; - - cur = library->modules; - limit = cur + library->num_modules; - - for ( ; cur < limit; cur++ ) - if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) - { - result = cur[0]; - break; - } - - return result; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( const void* ) - FT_Get_Module_Interface( FT_Library library, - const char* mod_name ) - { - FT_Module module; - - - /* test for valid `library' delayed to FT_Get_Module() */ - - module = FT_Get_Module( library, mod_name ); - - return module ? module->clazz->module_interface : 0; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_module_get_service( FT_Module module, - const char* service_id ) - { - FT_Pointer result = NULL; - - - if ( module ) - { - FT_ASSERT( module->clazz && module->clazz->get_interface ); - - /* first, look for the service in the module */ - if ( module->clazz->get_interface ) - result = module->clazz->get_interface( module, service_id ); - - if ( result == NULL ) - { - /* we didn't find it, look in all other modules then */ - FT_Library library = module->library; - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; - - - for ( ; cur < limit; cur++ ) - { - if ( cur[0] != module ) - { - FT_ASSERT( cur[0]->clazz ); - - if ( cur[0]->clazz->get_interface ) - { - result = cur[0]->clazz->get_interface( cur[0], service_id ); - if ( result != NULL ) - break; - } - } - } - } - } - - return result; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Remove_Module( FT_Library library, - FT_Module module ) - { - /* try to find the module from the table, then remove it from there */ - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( module ) - { - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; - - - for ( ; cur < limit; cur++ ) - { - if ( cur[0] == module ) - { - /* remove it from the table */ - library->num_modules--; - limit--; - while ( cur < limit ) - { - cur[0] = cur[1]; - cur++; - } - limit[0] = 0; - - /* destroy the module */ - Destroy_Module( module ); - - return FT_Err_Ok; - } - } - } - return FT_THROW( Invalid_Driver_Handle ); - } - - - FT_Error - ft_property_do( FT_Library library, - const FT_String* module_name, - const FT_String* property_name, - void* value, - FT_Bool set ) - { - FT_Module* cur; - FT_Module* limit; - FT_Module_Interface interface; - - FT_Service_Properties service; - -#ifdef FT_DEBUG_LEVEL_ERROR - const FT_String* set_name = "FT_Property_Set"; - const FT_String* get_name = "FT_Property_Get"; - const FT_String* func_name = set ? set_name : get_name; -#endif - - FT_Bool missing_func; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( !module_name || !property_name || !value ) - return FT_THROW( Invalid_Argument ); - - cur = library->modules; - limit = cur + library->num_modules; - - /* search module */ - for ( ; cur < limit; cur++ ) - if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) ) - break; - - if ( cur == limit ) - { - FT_ERROR(( "%s: can't find module `%s'\n", - func_name, module_name )); - return FT_THROW( Missing_Module ); - } - - /* check whether we have a service interface */ - if ( !cur[0]->clazz->get_interface ) - { - FT_ERROR(( "%s: module `%s' doesn't support properties\n", - func_name, module_name )); - return FT_THROW( Unimplemented_Feature ); - } - - /* search property service */ - interface = cur[0]->clazz->get_interface( cur[0], - FT_SERVICE_ID_PROPERTIES ); - if ( !interface ) - { - FT_ERROR(( "%s: module `%s' doesn't support properties\n", - func_name, module_name )); - return FT_THROW( Unimplemented_Feature ); - } - - service = (FT_Service_Properties)interface; - - if ( set ) - missing_func = (FT_Bool)( !service->set_property ); - else - missing_func = (FT_Bool)( !service->get_property ); - - if ( missing_func ) - { - FT_ERROR(( "%s: property service of module `%s' is broken\n", - func_name, module_name )); - return FT_THROW( Unimplemented_Feature ); - } - - return set ? service->set_property( cur[0], property_name, value ) - : service->get_property( cur[0], property_name, value ); - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Property_Set( FT_Library library, - const FT_String* module_name, - const FT_String* property_name, - const void* value ) - { - return ft_property_do( library, - module_name, - property_name, - (void*)value, - TRUE ); - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Property_Get( FT_Library library, - const FT_String* module_name, - const FT_String* property_name, - void* value ) - { - return ft_property_do( library, - module_name, - property_name, - value, - FALSE ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** L I B R A R Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Reference_Library( FT_Library library ) - { - library->refcount++; - - return FT_Err_Ok; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Library( FT_Memory memory, - FT_Library *alibrary ) - { - FT_Library library = NULL; - FT_Error error; - - - if ( !memory ) - return FT_THROW( Invalid_Argument ); - -#ifdef FT_DEBUG_LEVEL_ERROR - /* init debugging support */ - ft_debug_init(); -#endif - - /* first of all, allocate the library object */ - if ( FT_NEW( library ) ) - return error; - - library->memory = memory; - -#ifdef FT_CONFIG_OPTION_PIC - /* initialize position independent code containers */ - error = ft_pic_container_init( library ); - if ( error ) - goto Fail; -#endif - - /* allocate the render pool */ - library->raster_pool_size = FT_RENDER_POOL_SIZE; -#if FT_RENDER_POOL_SIZE > 0 - if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; -#endif - - library->version_major = FREETYPE_MAJOR; - library->version_minor = FREETYPE_MINOR; - library->version_patch = FREETYPE_PATCH; - - library->refcount = 1; - - /* That's ok now */ - *alibrary = library; - - return FT_Err_Ok; - - Fail: -#ifdef FT_CONFIG_OPTION_PIC - ft_pic_container_destroy( library ); -#endif - FT_FREE( library ); - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( void ) - FT_Library_Version( FT_Library library, - FT_Int *amajor, - FT_Int *aminor, - FT_Int *apatch ) - { - FT_Int major = 0; - FT_Int minor = 0; - FT_Int patch = 0; - - - if ( library ) - { - major = library->version_major; - minor = library->version_minor; - patch = library->version_patch; - } - - if ( amajor ) - *amajor = major; - - if ( aminor ) - *aminor = minor; - - if ( apatch ) - *apatch = patch; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Done_Library( FT_Library library ) - { - FT_Memory memory; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - library->refcount--; - if ( library->refcount > 0 ) - goto Exit; - - memory = library->memory; - - /* - * 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 - * - * Some faces are dependent on other faces, like Type42 faces that - * depend on TrueType faces synthesized internally. - * - * The order of drivers should be specified in driver_name[]. - */ - { - FT_UInt m, n; - const char* driver_name[] = { "type42", NULL }; - - - for ( m = 0; - m < sizeof ( driver_name ) / sizeof ( driver_name[0] ); - m++ ) - { - for ( n = 0; n < library->num_modules; n++ ) - { - FT_Module module = library->modules[n]; - const char* module_name = module->clazz->module_name; - FT_List faces; - - - if ( driver_name[m] && - ft_strcmp( module_name, driver_name[m] ) != 0 ) - continue; - - if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 ) - continue; - - FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name )); - - faces = &FT_DRIVER( module )->faces_list; - while ( faces->head ) - { - FT_Done_Face( FT_FACE( faces->head->data ) ); - if ( faces->head ) - FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" )); - } - } - } - } - - /* 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 */ - /* avoids double free in some occasions. It is a hack. */ - while ( library->num_modules > 0 ) - FT_Remove_Module( library, - library->modules[library->num_modules - 1] ); -#else - { - FT_UInt n; - - - for ( n = 0; n < library->num_modules; n++ ) - { - FT_Module module = library->modules[n]; - - - if ( module ) - { - Destroy_Module( module ); - library->modules[n] = 0; - } - } - } -#endif - - /* Destroy raster objects */ - FT_FREE( library->raster_pool ); - library->raster_pool_size = 0; - -#ifdef FT_CONFIG_OPTION_PIC - /* Destroy pic container contents */ - ft_pic_container_destroy( library ); -#endif - - FT_FREE( library ); - - Exit: - return FT_Err_Ok; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( void ) - FT_Set_Debug_Hook( FT_Library library, - FT_UInt hook_index, - FT_DebugHook_Func debug_hook ) - { - if ( library && debug_hook && - hook_index < - ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) - library->debug_hooks[hook_index] = debug_hook; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_TrueTypeEngineType ) - FT_Get_TrueType_Engine_Type( FT_Library library ) - { - FT_TrueTypeEngineType result = FT_TRUETYPE_ENGINE_TYPE_NONE; - - - if ( library ) - { - FT_Module module = FT_Get_Module( library, "truetype" ); - - - if ( module ) - { - FT_Service_TrueTypeEngine service; - - - service = (FT_Service_TrueTypeEngine) - ft_module_get_service( module, - FT_SERVICE_ID_TRUETYPE_ENGINE ); - if ( service ) - result = service->engine_type; - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, - FT_UInt sub_index, - FT_Int *p_index, - FT_UInt *p_flags, - FT_Int *p_arg1, - FT_Int *p_arg2, - FT_Matrix *p_transform ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - - - if ( glyph && - glyph->subglyphs && - 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; - *p_arg1 = subg->arg1; - *p_arg2 = subg->arg2; - *p_transform = subg->transform; - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftotval.c b/drivers/freetype/freetype/src/base/ftotval.c deleted file mode 100644 index 5fc73d76ab..0000000000 --- a/drivers/freetype/freetype/src/base/ftotval.c +++ /dev/null @@ -1,91 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftotval.c */ -/* */ -/* FreeType API for validating OpenType tables (body). */ -/* */ -/* Copyright 2004, 2006, 2008, 2010, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_OPENTYPE_VALIDATE_H -#include FT_OPENTYPE_VALIDATE_H - - - /* documentation is in ftotval.h */ - - FT_EXPORT_DEF( 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 *JSTF_table ) - { - FT_Service_OTvalidate service; - FT_Error error; - - - if ( !face ) - { - error = FT_THROW( Invalid_Face_Handle ); - goto Exit; - } - - if ( !( BASE_table && - GDEF_table && - GPOS_table && - GSUB_table && - JSTF_table ) ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - FT_FACE_FIND_GLOBAL_SERVICE( face, service, OPENTYPE_VALIDATE ); - - if ( service ) - error = service->validate( face, - validation_flags, - BASE_table, - GDEF_table, - GPOS_table, - GSUB_table, - JSTF_table ); - else - error = FT_THROW( Unimplemented_Feature ); - - Exit: - return error; - } - - - FT_EXPORT_DEF( void ) - FT_OpenType_Free( FT_Face face, - FT_Bytes table ) - { - FT_Memory memory; - - - if ( !face ) - return; - - memory = FT_FACE_MEMORY( face ); - - FT_FREE( table ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftoutln.c b/drivers/freetype/freetype/src/base/ftoutln.c deleted file mode 100644 index 54ca5cdcf6..0000000000 --- a/drivers/freetype/freetype/src/base/ftoutln.c +++ /dev/null @@ -1,1081 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoutln.c */ -/* */ -/* FreeType outline management (body). */ -/* */ -/* Copyright 1996-2008, 2010, 2012-2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* All functions are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_OUTLINE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_H -#include FT_TRIGONOMETRY_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_outline - - - static - const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Decompose( FT_Outline* outline, - const FT_Outline_Funcs* func_interface, - void* user ) - { -#undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) - - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - FT_Error error; - - FT_Int n; /* index of contour in outline */ - FT_UInt first; /* index of first point in contour */ - FT_Int tag; /* current point's state */ - - FT_Int shift; - FT_Pos delta; - - - if ( !outline || !func_interface ) - return FT_THROW( Invalid_Argument ); - - shift = func_interface->shift; - delta = func_interface->delta; - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - FT_Int last; /* index of last point in contour */ - - - FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); - - last = outline->contours[n]; - if ( last < 0 ) - goto Invalid_Outline; - limit = outline->points + last; - - v_start = outline->points[first]; - v_start.x = SCALED( v_start.x ); - v_start.y = SCALED( v_start.y ); - - v_last = outline->points[last]; - v_last.x = SCALED( v_last.x ); - v_last.y = SCALED( v_last.y ); - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_CURVE_TAG_CONIC ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - FT_TRACE5(( " move to (%.2f, %.2f)\n", - v_start.x / 64.0, v_start.y / 64.0 )); - error = func_interface->move_to( &v_start, user ); - if ( error ) - goto Exit; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - switch ( tag ) - { - case FT_CURVE_TAG_ON: /* emit a single line_to */ - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - FT_TRACE5(( " line to (%.2f, %.2f)\n", - vec.x / 64.0, vec.y / 64.0 )); - error = func_interface->line_to( &vec, user ); - if ( error ) - goto Exit; - continue; - } - - case FT_CURVE_TAG_CONIC: /* consume conic arcs */ - v_control.x = SCALED( point->x ); - v_control.y = SCALED( point->y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - if ( tag == FT_CURVE_TAG_ON ) - { - FT_TRACE5(( " conic to (%.2f, %.2f)" - " with control (%.2f, %.2f)\n", - vec.x / 64.0, vec.y / 64.0, - v_control.x / 64.0, v_control.y / 64.0 )); - error = func_interface->conic_to( &v_control, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_CURVE_TAG_CONIC ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - FT_TRACE5(( " conic to (%.2f, %.2f)" - " with control (%.2f, %.2f)\n", - v_middle.x / 64.0, v_middle.y / 64.0, - v_control.x / 64.0, v_control.y / 64.0 )); - error = func_interface->conic_to( &v_control, &v_middle, user ); - if ( error ) - goto Exit; - - v_control = vec; - goto Do_Conic; - } - - FT_TRACE5(( " conic to (%.2f, %.2f)" - " with control (%.2f, %.2f)\n", - v_start.x / 64.0, v_start.y / 64.0, - v_control.x / 64.0, v_control.y / 64.0 )); - error = func_interface->conic_to( &v_control, &v_start, user ); - goto Close; - - default: /* FT_CURVE_TAG_CUBIC */ - { - FT_Vector vec1, vec2; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1.x = SCALED( point[-2].x ); - vec1.y = SCALED( point[-2].y ); - - vec2.x = SCALED( point[-1].x ); - vec2.y = SCALED( point[-1].y ); - - if ( point <= limit ) - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - FT_TRACE5(( " cubic to (%.2f, %.2f)" - " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", - vec.x / 64.0, vec.y / 64.0, - vec1.x / 64.0, vec1.y / 64.0, - vec2.x / 64.0, vec2.y / 64.0 )); - error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - FT_TRACE5(( " cubic to (%.2f, %.2f)" - " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", - v_start.x / 64.0, v_start.y / 64.0, - vec1.x / 64.0, vec1.y / 64.0, - vec2.x / 64.0, vec2.y / 64.0 )); - error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); - goto Close; - } - } - } - - /* close the contour with a line segment */ - FT_TRACE5(( " line to (%.2f, %.2f)\n", - v_start.x / 64.0, v_start.y / 64.0 )); - error = func_interface->line_to( &v_start, user ); - - Close: - if ( error ) - goto Exit; - - first = last + 1; - } - - FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); - return FT_Err_Ok; - - Exit: - FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); - return error; - - Invalid_Outline: - return FT_THROW( Invalid_Outline ); - } - - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_New_Internal( FT_Memory memory, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ) - { - FT_Error error; - - - if ( !anoutline || !memory ) - return FT_THROW( Invalid_Argument ); - - *anoutline = null_outline; - - if ( numContours < 0 || - (FT_UInt)numContours > numPoints ) - return FT_THROW( Invalid_Argument ); - - if ( numPoints > FT_OUTLINE_POINTS_MAX ) - return FT_THROW( Array_Too_Large ); - - if ( FT_NEW_ARRAY( anoutline->points, numPoints ) || - FT_NEW_ARRAY( anoutline->tags, numPoints ) || - FT_NEW_ARRAY( anoutline->contours, numContours ) ) - goto Fail; - - anoutline->n_points = (FT_UShort)numPoints; - anoutline->n_contours = (FT_Short)numContours; - anoutline->flags |= FT_OUTLINE_OWNER; - - return FT_Err_Ok; - - Fail: - anoutline->flags |= FT_OUTLINE_OWNER; - FT_Outline_Done_Internal( memory, anoutline ); - - return error; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_New( FT_Library library, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ) - { - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - return FT_Outline_New_Internal( library->memory, numPoints, - numContours, anoutline ); - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Check( FT_Outline* outline ) - { - if ( outline ) - { - FT_Int n_points = outline->n_points; - FT_Int n_contours = outline->n_contours; - FT_Int end0, end; - FT_Int n; - - - /* empty glyph? */ - if ( n_points == 0 && n_contours == 0 ) - return 0; - - /* check point and contour counts */ - if ( n_points <= 0 || n_contours <= 0 ) - goto Bad; - - end0 = end = -1; - for ( n = 0; n < n_contours; n++ ) - { - end = outline->contours[n]; - - /* note that we don't accept empty contours */ - if ( end <= end0 || end >= n_points ) - goto Bad; - - end0 = end; - } - - if ( end != n_points - 1 ) - goto Bad; - - /* XXX: check the tags array */ - return 0; - } - - Bad: - return FT_THROW( Invalid_Argument ); - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Copy( const FT_Outline* source, - FT_Outline *target ) - { - FT_Int is_owner; - - - if ( !source || !target || - source->n_points != target->n_points || - source->n_contours != target->n_contours ) - return FT_THROW( Invalid_Argument ); - - if ( source == target ) - return FT_Err_Ok; - - FT_ARRAY_COPY( target->points, source->points, source->n_points ); - - FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); - - FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); - - /* copy all flags, except the `FT_OUTLINE_OWNER' one */ - is_owner = target->flags & FT_OUTLINE_OWNER; - target->flags = source->flags; - - target->flags &= ~FT_OUTLINE_OWNER; - target->flags |= is_owner; - - return FT_Err_Ok; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Done_Internal( FT_Memory memory, - FT_Outline* outline ) - { - if ( memory && outline ) - { - if ( outline->flags & FT_OUTLINE_OWNER ) - { - FT_FREE( outline->points ); - FT_FREE( outline->tags ); - FT_FREE( outline->contours ); - } - *outline = null_outline; - - return FT_Err_Ok; - } - else - return FT_THROW( Invalid_Argument ); - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Done( FT_Library library, - FT_Outline* outline ) - { - /* check for valid `outline' in FT_Outline_Done_Internal() */ - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - return FT_Outline_Done_Internal( library->memory, outline ); - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( void ) - FT_Outline_Get_CBox( const FT_Outline* outline, - FT_BBox *acbox ) - { - FT_Pos xMin, yMin, xMax, yMax; - - - if ( outline && acbox ) - { - if ( outline->n_points == 0 ) - { - xMin = 0; - yMin = 0; - xMax = 0; - yMax = 0; - } - else - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - xMin = xMax = vec->x; - yMin = yMax = vec->y; - vec++; - - for ( ; vec < limit; vec++ ) - { - FT_Pos x, y; - - - x = vec->x; - if ( x < xMin ) xMin = x; - if ( x > xMax ) xMax = x; - - y = vec->y; - if ( y < yMin ) yMin = y; - if ( y > yMax ) yMax = y; - } - } - acbox->xMin = xMin; - acbox->xMax = xMax; - acbox->yMin = yMin; - acbox->yMax = yMax; - } - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( void ) - FT_Outline_Translate( const FT_Outline* outline, - FT_Pos xOffset, - FT_Pos yOffset ) - { - FT_UShort n; - FT_Vector* vec; - - - if ( !outline ) - return; - - vec = outline->points; - - for ( n = 0; n < outline->n_points; n++ ) - { - vec->x += xOffset; - vec->y += yOffset; - vec++; - } - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( void ) - FT_Outline_Reverse( FT_Outline* outline ) - { - FT_UShort n; - FT_Int first, last; - - - if ( !outline ) - return; - - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - last = outline->contours[n]; - - /* reverse point table */ - { - FT_Vector* p = outline->points + first; - FT_Vector* q = outline->points + last; - FT_Vector swap; - - - while ( p < q ) - { - swap = *p; - *p = *q; - *q = swap; - p++; - q--; - } - } - - /* reverse tags table */ - { - char* p = outline->tags + first; - char* q = outline->tags + last; - char swap; - - - while ( p < q ) - { - swap = *p; - *p = *q; - *q = swap; - p++; - q--; - } - } - - first = last + 1; - } - - outline->flags ^= FT_OUTLINE_REVERSE_FILL; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Render( FT_Library library, - FT_Outline* outline, - FT_Raster_Params* params ) - { - FT_Error error; - FT_Bool update = FALSE; - FT_Renderer renderer; - FT_ListNode node; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - if ( !outline || !params ) - return FT_THROW( Invalid_Argument ); - - renderer = library->cur_renderer; - node = library->renderers.head; - - params->source = (void*)outline; - - error = FT_ERR( Cannot_Render_Glyph ); - while ( renderer ) - { - error = renderer->raster_render( renderer->raster, params ); - if ( !error || FT_ERR_NEQ( error, Cannot_Render_Glyph ) ) - break; - - /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ - /* is unsupported by the current renderer for this glyph image */ - /* format */ - - /* now, look for another renderer that supports the same */ - /* format */ - renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, - &node ); - update = TRUE; - } - - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); - - return error; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Get_Bitmap( FT_Library library, - FT_Outline* outline, - const FT_Bitmap *abitmap ) - { - FT_Raster_Params params; - - - if ( !abitmap ) - return FT_THROW( Invalid_Argument ); - - /* other checks are delayed to FT_Outline_Render() */ - - params.target = abitmap; - params.flags = 0; - - if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY || - abitmap->pixel_mode == FT_PIXEL_MODE_LCD || - abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V ) - params.flags |= FT_RASTER_FLAG_AA; - - return FT_Outline_Render( library, outline, ¶ms ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_Transform( FT_Vector* vector, - const FT_Matrix* matrix ) - { - FT_Pos xz, yz; - - - if ( !vector || !matrix ) - return; - - xz = FT_MulFix( vector->x, matrix->xx ) + - FT_MulFix( vector->y, matrix->xy ); - - yz = FT_MulFix( vector->x, matrix->yx ) + - FT_MulFix( vector->y, matrix->yy ); - - vector->x = xz; - vector->y = yz; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( void ) - FT_Outline_Transform( const FT_Outline* outline, - const FT_Matrix* matrix ) - { - FT_Vector* vec; - FT_Vector* limit; - - - if ( !outline || !matrix ) - return; - - vec = outline->points; - limit = vec + outline->n_points; - - for ( ; vec < limit; vec++ ) - FT_Vector_Transform( vec, matrix ); - } - - -#if 0 - -#define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \ - do { \ - (first) = ( c > 0 ) ? (outline)->points + \ - (outline)->contours[c - 1] + 1 \ - : (outline)->points; \ - (last) = (outline)->points + (outline)->contours[c]; \ - } while ( 0 ) - - - /* Is a point in some contour? */ - /* */ - /* We treat every point of the contour as if it */ - /* it were ON. That is, we allow false positives, */ - /* but disallow false negatives. (XXX really?) */ - static FT_Bool - ft_contour_has( FT_Outline* outline, - FT_Short c, - FT_Vector* point ) - { - FT_Vector* first; - FT_Vector* last; - FT_Vector* a; - FT_Vector* b; - FT_UInt n = 0; - - - FT_OUTLINE_GET_CONTOUR( outline, c, first, last ); - - for ( a = first; a <= last; a++ ) - { - FT_Pos x; - FT_Int intersect; - - - b = ( a == last ) ? first : a + 1; - - intersect = ( a->y - point->y ) ^ ( b->y - point->y ); - - /* a and b are on the same side */ - if ( intersect >= 0 ) - { - if ( intersect == 0 && a->y == point->y ) - { - if ( ( a->x <= point->x && b->x >= point->x ) || - ( a->x >= point->x && b->x <= point->x ) ) - return 1; - } - - continue; - } - - x = a->x + ( b->x - a->x ) * (point->y - a->y ) / ( b->y - a->y ); - - if ( x < point->x ) - n++; - else if ( x == point->x ) - return 1; - } - - return n & 1; - } - - - static FT_Bool - ft_contour_enclosed( FT_Outline* outline, - FT_UShort c ) - { - FT_Vector* first; - FT_Vector* last; - FT_Short i; - - - FT_OUTLINE_GET_CONTOUR( outline, c, first, last ); - - for ( i = 0; i < outline->n_contours; i++ ) - { - if ( i != c && ft_contour_has( outline, i, first ) ) - { - FT_Vector* pt; - - - for ( pt = first + 1; pt <= last; pt++ ) - if ( !ft_contour_has( outline, i, pt ) ) - return 0; - - return 1; - } - } - - return 0; - } - - - /* This version differs from the public one in that each */ - /* part (contour not enclosed in another contour) of the */ - /* outline is checked for orientation. This is */ - /* necessary for some buggy CJK fonts. */ - static FT_Orientation - ft_outline_get_orientation( FT_Outline* outline ) - { - FT_Short i; - FT_Vector* first; - FT_Vector* last; - FT_Orientation orient = FT_ORIENTATION_NONE; - - - first = outline->points; - for ( i = 0; i < outline->n_contours; i++, first = last + 1 ) - { - FT_Vector* point; - FT_Vector* xmin_point; - FT_Pos xmin; - - - last = outline->points + outline->contours[i]; - - /* skip degenerate contours */ - if ( last < first + 2 ) - continue; - - if ( ft_contour_enclosed( outline, i ) ) - continue; - - xmin = first->x; - xmin_point = first; - - for ( point = first + 1; point <= last; point++ ) - { - if ( point->x < xmin ) - { - xmin = point->x; - xmin_point = point; - } - } - - /* check the orientation of the contour */ - { - FT_Vector* prev; - FT_Vector* next; - FT_Orientation o; - - - prev = ( xmin_point == first ) ? last : xmin_point - 1; - next = ( xmin_point == last ) ? first : xmin_point + 1; - - 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 ) ) - o = FT_ORIENTATION_POSTSCRIPT; - else - o = FT_ORIENTATION_TRUETYPE; - - if ( orient == FT_ORIENTATION_NONE ) - orient = o; - else if ( orient != o ) - return FT_ORIENTATION_NONE; - } - } - - return orient; - } - -#endif /* 0 */ - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Embolden( FT_Outline* outline, - FT_Pos strength ) - { - return FT_Outline_EmboldenXY( outline, strength, strength ); - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_EmboldenXY( FT_Outline* outline, - FT_Pos xstrength, - FT_Pos ystrength ) - { - FT_Vector* points; - FT_Vector v_prev, v_first, v_next, v_cur; - FT_Int c, n, first; - FT_Int orientation; - - - if ( !outline ) - return FT_THROW( Invalid_Argument ); - - xstrength /= 2; - ystrength /= 2; - if ( xstrength == 0 && ystrength == 0 ) - return FT_Err_Ok; - - orientation = FT_Outline_Get_Orientation( outline ); - if ( orientation == FT_ORIENTATION_NONE ) - { - if ( outline->n_contours ) - return FT_THROW( Invalid_Argument ); - else - return FT_Err_Ok; - } - - points = outline->points; - - first = 0; - for ( c = 0; c < outline->n_contours; c++ ) - { - FT_Vector in, out, shift; - FT_Fixed l_in, l_out, l, q, d; - int last = outline->contours[c]; - - - v_first = points[first]; - v_prev = points[last]; - v_cur = v_first; - - /* compute incoming normalized vector */ - in.x = v_cur.x - v_prev.x; - in.y = v_cur.y - v_prev.y; - l_in = FT_Vector_Length( &in ); - if ( l_in ) - { - in.x = FT_DivFix( in.x, l_in ); - in.y = FT_DivFix( in.y, l_in ); - } - - for ( n = first; n <= last; n++ ) - { - if ( n < last ) - v_next = points[n + 1]; - else - v_next = v_first; - - /* compute outgoing normalized vector */ - out.x = v_next.x - v_cur.x; - out.y = v_next.y - v_cur.y; - l_out = FT_Vector_Length( &out ); - if ( l_out ) - { - out.x = FT_DivFix( out.x, l_out ); - out.y = FT_DivFix( out.y, l_out ); - } - - d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); - - /* shift only if turn is less than ~160 degrees */ - if ( d > -0xF000L ) - { - d = d + 0x10000L; - - /* shift components are aligned along lateral bisector */ - /* and directed according to the outline orientation. */ - shift.x = in.y + out.y; - shift.y = in.x + out.x; - - if ( orientation == FT_ORIENTATION_TRUETYPE ) - shift.x = -shift.x; - else - shift.y = -shift.y; - - /* restrict shift magnitude to better handle collapsing segments */ - q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x ); - if ( orientation == FT_ORIENTATION_TRUETYPE ) - q = -q; - - l = FT_MIN( l_in, l_out ); - - /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ - if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) ) - shift.x = FT_MulDiv( shift.x, xstrength, d ); - else - shift.x = FT_MulDiv( shift.x, l, q ); - - - if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) ) - shift.y = FT_MulDiv( shift.y, ystrength, d ); - else - shift.y = FT_MulDiv( shift.y, l, q ); - } - else - shift.x = shift.y = 0; - - outline->points[n].x = v_cur.x + xstrength + shift.x; - outline->points[n].y = v_cur.y + ystrength + shift.y; - - in = out; - l_in = l_out; - v_cur = v_next; - } - - first = last + 1; - } - - return FT_Err_Ok; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Orientation ) - FT_Outline_Get_Orientation( FT_Outline* outline ) - { - FT_BBox cbox; - FT_Int xshift, yshift; - FT_Vector* points; - FT_Vector v_prev, v_cur; - FT_Int c, n, first; - FT_Pos area = 0; - - - 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. */ - - FT_Outline_Get_CBox( outline, &cbox ); - - xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14; - xshift = FT_MAX( xshift, 0 ); - - yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14; - yshift = FT_MAX( yshift, 0 ); - - points = outline->points; - - first = 0; - for ( c = 0; c < outline->n_contours; c++ ) - { - FT_Int last = outline->contours[c]; - - - v_prev = points[last]; - - for ( n = first; n <= last; n++ ) - { - v_cur = points[n]; - area += ( ( v_cur.y - v_prev.y ) >> yshift ) * - ( ( v_cur.x + v_prev.x ) >> xshift ); - v_prev = v_cur; - } - - first = last + 1; - } - - if ( area > 0 ) - return FT_ORIENTATION_POSTSCRIPT; - else if ( area < 0 ) - return FT_ORIENTATION_TRUETYPE; - else - return FT_ORIENTATION_NONE; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftpatent.c b/drivers/freetype/freetype/src/base/ftpatent.c deleted file mode 100644 index 82b42f0343..0000000000 --- a/drivers/freetype/freetype/src/base/ftpatent.c +++ /dev/null @@ -1,286 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpatent.c */ -/* */ -/* FreeType API for checking patented TrueType bytecode instructions */ -/* (body). */ -/* */ -/* Copyright 2007, 2008, 2010 by David Turner. */ -/* */ -/* 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_FREETYPE_H -#include FT_TRUETYPE_TAGS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_STREAM_H -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_TRUETYPE_GLYF_H - - - static FT_Bool - _tt_check_patents_in_range( FT_Stream stream, - FT_ULong size ) - { - FT_Bool result = FALSE; - FT_Error error; - FT_Bytes p, end; - - - if ( FT_FRAME_ENTER( size ) ) - return 0; - - p = stream->cursor; - end = p + size; - - while ( p < end ) - { - switch (p[0]) - { - case 0x06: /* SPvTL // */ - case 0x07: /* SPvTL + */ - case 0x08: /* SFvTL // */ - case 0x09: /* SFvTL + */ - case 0x0A: /* SPvFS */ - case 0x0B: /* SFvFS */ - result = TRUE; - goto Exit; - - case 0x40: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] + 2; - break; - - case 0x41: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] * 2 + 2; - break; - - case 0x71: /* DELTAP2 */ - case 0x72: /* DELTAP3 */ - case 0x73: /* DELTAC0 */ - case 0x74: /* DELTAC1 */ - case 0x75: /* DELTAC2 */ - result = TRUE; - goto Exit; - - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - p += ( p[0] - 0xB0 ) + 2; - break; - - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - p += ( p[0] - 0xB8 ) * 2 + 3; - break; - - default: - p += 1; - break; - } - } - - Exit: - FT_UNUSED( error ); - FT_FRAME_EXIT(); - return result; - } - - - static FT_Bool - _tt_check_patents_in_table( FT_Face face, - FT_ULong tag ) - { - FT_Stream stream = face->stream; - FT_Error error = FT_Err_Ok; - FT_Service_SFNT_Table service; - FT_Bool result = FALSE; - - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - - if ( service ) - { - FT_UInt i = 0; - FT_ULong tag_i = 0, offset_i = 0, length_i = 0; - - - for ( i = 0; !error && tag_i != tag ; i++ ) - error = service->table_info( face, i, - &tag_i, &offset_i, &length_i ); - - if ( error || - FT_STREAM_SEEK( offset_i ) ) - goto Exit; - - result = _tt_check_patents_in_range( stream, length_i ); - } - - Exit: - return result; - } - - - static FT_Bool - _tt_face_check_patents( FT_Face face ) - { - FT_Stream stream = face->stream; - FT_UInt gindex; - FT_Error error; - FT_Bool result; - - FT_Service_TTGlyf service; - - - result = _tt_check_patents_in_table( face, TTAG_fpgm ); - if ( result ) - goto Exit; - - result = _tt_check_patents_in_table( face, TTAG_prep ); - if ( result ) - goto Exit; - - FT_FACE_FIND_SERVICE( face, service, TT_GLYF ); - if ( service == NULL ) - goto Exit; - - for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ ) - { - FT_ULong offset, num_ins, size; - FT_Int num_contours; - - - offset = service->get_location( face, gindex, &size ); - if ( size == 0 ) - continue; - - if ( FT_STREAM_SEEK( offset ) || - FT_READ_SHORT( num_contours ) ) - continue; - - if ( num_contours >= 0 ) /* simple glyph */ - { - if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) ) - continue; - } - else /* compound glyph */ - { - FT_Bool has_instr = 0; - - - if ( FT_STREAM_SKIP( 8 ) ) - continue; - - /* now read each component */ - for (;;) - { - FT_UInt flags, toskip; - - - if( FT_READ_USHORT( flags ) ) - break; - - toskip = 2 + 1 + 1; - - if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */ - toskip += 2; - - if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */ - toskip += 2; - else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */ - toskip += 4; - else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */ - toskip += 8; - - if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */ - has_instr = 1; - - if ( FT_STREAM_SKIP( toskip ) ) - goto NextGlyph; - - if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */ - break; - } - - if ( !has_instr ) - goto NextGlyph; - } - - if ( FT_READ_USHORT( num_ins ) ) - continue; - - result = _tt_check_patents_in_range( stream, num_ins ); - if ( result ) - goto Exit; - - NextGlyph: - ; - } - - Exit: - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Bool ) - FT_Face_CheckTrueTypePatents( FT_Face face ) - { - FT_Bool result = FALSE; - - - if ( face && FT_IS_SFNT( face ) ) - result = _tt_face_check_patents( face ); - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Bool ) - FT_Face_SetUnpatentedHinting( FT_Face face, - FT_Bool value ) - { - FT_Bool result = FALSE; - - -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) - if ( face && FT_IS_SFNT( face ) ) - { - result = !face->internal->ignore_unpatented_hinter; - face->internal->ignore_unpatented_hinter = !value; - } -#else - FT_UNUSED( face ); - FT_UNUSED( value ); -#endif - - return result; - } - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftpfr.c b/drivers/freetype/freetype/src/base/ftpfr.c deleted file mode 100644 index 0ba955f01f..0000000000 --- a/drivers/freetype/freetype/src/base/ftpfr.c +++ /dev/null @@ -1,146 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpfr.c */ -/* */ -/* FreeType API for accessing PFR-specific data (body). */ -/* */ -/* Copyright 2002-2004, 2008, 2010, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_PFR_H - - - /* check the format */ - static FT_Service_PfrMetrics - ft_pfr_check( FT_Face face ) - { - FT_Service_PfrMetrics service = NULL; - - - if ( face ) - FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS ); - - return service; - } - - - /* documentation is in ftpfr.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_PFR_Metrics( FT_Face face, - FT_UInt *aoutline_resolution, - FT_UInt *ametrics_resolution, - FT_Fixed *ametrics_x_scale, - FT_Fixed *ametrics_y_scale ) - { - FT_Error error = FT_Err_Ok; - FT_Service_PfrMetrics service; - - - if ( !face ) - return FT_THROW( Invalid_Argument ); - - service = ft_pfr_check( face ); - if ( service ) - { - error = service->get_metrics( face, - aoutline_resolution, - ametrics_resolution, - ametrics_x_scale, - ametrics_y_scale ); - } - else - { - FT_Fixed x_scale, y_scale; - - - /* this is not a PFR font */ - if ( aoutline_resolution ) - *aoutline_resolution = face->units_per_EM; - - if ( ametrics_resolution ) - *ametrics_resolution = face->units_per_EM; - - x_scale = y_scale = 0x10000L; - if ( face->size ) - { - x_scale = face->size->metrics.x_scale; - y_scale = face->size->metrics.y_scale; - } - - if ( ametrics_x_scale ) - *ametrics_x_scale = x_scale; - - if ( ametrics_y_scale ) - *ametrics_y_scale = y_scale; - - error = FT_THROW( Unknown_File_Format ); - } - - return error; - } - - - /* documentation is in ftpfr.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_PFR_Kerning( FT_Face face, - FT_UInt left, - FT_UInt right, - FT_Vector *avector ) - { - FT_Error error; - FT_Service_PfrMetrics service; - - - if ( !face ) - return FT_THROW( Invalid_Argument ); - - service = ft_pfr_check( face ); - if ( service ) - error = service->get_kerning( face, left, right, avector ); - else - error = FT_Get_Kerning( face, left, right, - FT_KERNING_UNSCALED, avector ); - - return error; - } - - - /* documentation is in ftpfr.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_PFR_Advance( FT_Face face, - FT_UInt gindex, - FT_Pos *aadvance ) - { - FT_Error error; - FT_Service_PfrMetrics service; - - - service = ft_pfr_check( face ); - if ( service ) - { - error = service->get_advance( face, gindex, aadvance ); - } - else - /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */ - error = FT_THROW( Invalid_Argument ); - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftpic.c b/drivers/freetype/freetype/src/base/ftpic.c deleted file mode 100644 index 1c87101696..0000000000 --- a/drivers/freetype/freetype/src/base/ftpic.c +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpic.c */ -/* */ -/* The FreeType position independent code services (body). */ -/* */ -/* Copyright 2009 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "basepic.h" - -#ifdef FT_CONFIG_OPTION_PIC - - /* documentation is in ftpic.h */ - - FT_BASE_DEF( FT_Error ) - ft_pic_container_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - - - FT_MEM_SET( pic_container, 0, sizeof ( *pic_container ) ); - - error = ft_base_pic_init( library ); - if ( error ) - return error; - - return FT_Err_Ok; - } - - - /* Destroy the contents of the container. */ - FT_BASE_DEF( void ) - ft_pic_container_destroy( FT_Library library ) - { - ft_base_pic_free( library ); - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftrfork.c b/drivers/freetype/freetype/src/base/ftrfork.c deleted file mode 100644 index 804911721d..0000000000 --- a/drivers/freetype/freetype/src/base/ftrfork.c +++ /dev/null @@ -1,849 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrfork.c */ -/* */ -/* Embedded resource forks accessor (body). */ -/* */ -/* Copyright 2004-2010, 2013 by */ -/* Masatake YAMATO and Redhat K.K. */ -/* */ -/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ -/* derived from ftobjs.c. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* Development of the code in this file is support of */ -/* Information-technology Promotion Agency, Japan. */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_RFORK_H -#include "basepic.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_raccess - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** Resource fork directory access ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - FT_BASE_DEF( FT_Error ) - FT_Raccess_Get_HeaderInfo( FT_Library library, - FT_Stream stream, - FT_Long rfork_offset, - FT_Long *map_offset, - FT_Long *rdata_pos ) - { - FT_Error error; - unsigned char head[16], head2[16]; - FT_Long map_pos, rdata_len; - int allzeros, allmatch, i; - FT_Long type_list; - - FT_UNUSED( library ); - - - error = FT_Stream_Seek( stream, rfork_offset ); - if ( error ) - return error; - - error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); - if ( error ) - return error; - - *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | - ( head[1] << 16 ) | - ( head[2] << 8 ) | - head[3] ); - map_pos = rfork_offset + ( ( head[4] << 24 ) | - ( head[5] << 16 ) | - ( head[6] << 8 ) | - head[7] ); - rdata_len = ( head[ 8] << 24 ) | - ( head[ 9] << 16 ) | - ( head[10] << 8 ) | - head[11]; - - /* map_len = head[12] .. head[15] */ - - if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) - return FT_THROW( Unknown_File_Format ); - - error = FT_Stream_Seek( stream, map_pos ); - if ( error ) - return error; - - head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ - - error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); - if ( error ) - return error; - - allzeros = 1; - allmatch = 1; - for ( i = 0; i < 16; ++i ) - { - if ( head2[i] != 0 ) - allzeros = 0; - if ( head2[i] != head[i] ) - allmatch = 0; - } - if ( !allzeros && !allmatch ) - return FT_THROW( Unknown_File_Format ); - - /* If we have reached this point then it is probably a mac resource */ - /* file. Now, does it contain any interesting resources? */ - /* Skip handle to next resource map, the file resource number, and */ - /* attributes. */ - (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ - + 2 /* skip file resource number */ - + 2 ); /* skip attributes */ - - if ( FT_READ_USHORT( type_list ) ) - return error; - if ( type_list == -1 ) - return FT_THROW( Unknown_File_Format ); - - error = FT_Stream_Seek( stream, map_pos + type_list ); - if ( error ) - return error; - - *map_offset = map_pos + type_list; - return FT_Err_Ok; - } - - - static int - ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, - FT_RFork_Ref* b ) - { - if ( a->res_id < b->res_id ) - return -1; - else if ( a->res_id > b->res_id ) - return 1; - else - return 0; - } - - - FT_BASE_DEF( FT_Error ) - FT_Raccess_Get_DataOffsets( FT_Library library, - FT_Stream stream, - FT_Long map_offset, - FT_Long rdata_pos, - FT_Long tag, - FT_Long **offsets, - FT_Long *count ) - { - FT_Error error; - int i, j, cnt, subcnt; - FT_Long tag_internal, rpos; - FT_Memory memory = library->memory; - FT_Long temp; - FT_Long *offsets_internal = NULL; - FT_RFork_Ref *ref = NULL; - - - error = FT_Stream_Seek( stream, map_offset ); - if ( error ) - return error; - - if ( FT_READ_USHORT( cnt ) ) - return error; - cnt++; - - for ( i = 0; i < cnt; ++i ) - { - if ( FT_READ_LONG( tag_internal ) || - FT_READ_USHORT( subcnt ) || - FT_READ_USHORT( rpos ) ) - return error; - - FT_TRACE2(( "Resource tags: %c%c%c%c\n", - (char)( 0xff & ( tag_internal >> 24 ) ), - (char)( 0xff & ( tag_internal >> 16 ) ), - (char)( 0xff & ( tag_internal >> 8 ) ), - (char)( 0xff & ( tag_internal >> 0 ) ) )); - - if ( tag_internal == tag ) - { - *count = subcnt + 1; - rpos += map_offset; - - error = FT_Stream_Seek( stream, rpos ); - if ( error ) - return error; - - if ( FT_NEW_ARRAY( ref, *count ) ) - return error; - - for ( j = 0; j < *count; ++j ) - { - if ( FT_READ_USHORT( ref[j].res_id ) ) - goto Exit; - if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ - goto Exit; - if ( FT_READ_LONG( temp ) ) - goto Exit; - if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ - goto Exit; - - ref[j].offset = temp & 0xFFFFFFL; - } - - ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); - - if ( FT_NEW_ARRAY( offsets_internal, *count ) ) - goto Exit; - - /* XXX: duplicated reference ID, - * gap between reference IDs are acceptable? - * further investigation on Apple implementation is needed. - */ - for ( j = 0; j < *count; ++j ) - offsets_internal[j] = rdata_pos + ref[j].offset; - - *offsets = offsets_internal; - error = FT_Err_Ok; - - Exit: - FT_FREE( ref ); - return error; - } - } - - return FT_THROW( Cannot_Open_Resource ); - } - - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** Guessing functions ****/ - /**** ****/ - /**** When you add a new guessing function, ****/ - /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_Error - raccess_guess_apple_double( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_apple_single( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_darwin_ufs_export( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_darwin_newvfs( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_darwin_hfsplus( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_vfat( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_linux_cap( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_linux_double( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_linux_netatalk( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - - CONST_FT_RFORK_RULE_ARRAY_BEGIN(ft_raccess_guess_table, - ft_raccess_guess_rec) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_double, apple_double) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_single, apple_single) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_ufs_export, darwin_ufs_export) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_newvfs, darwin_newvfs) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_hfsplus, darwin_hfsplus) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(vfat, vfat) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_cap, linux_cap) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_double, linux_double) - CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_netatalk, linux_netatalk) - CONST_FT_RFORK_RULE_ARRAY_END - - - /*************************************************************************/ - /**** ****/ - /**** Helper functions ****/ - /**** ****/ - /*************************************************************************/ - - static FT_Error - raccess_guess_apple_generic( FT_Library library, - FT_Stream stream, - char *base_file_name, - FT_Int32 magic, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_linux_double_from_file_name( FT_Library library, - char * file_name, - FT_Long *result_offset ); - - static char * - raccess_make_file_name( FT_Memory memory, - const char *original_name, - const char *insertion ); - - FT_BASE_DEF( void ) - FT_Raccess_Guess( FT_Library library, - FT_Stream stream, - char* base_name, - char **new_names, - FT_Long *offsets, - FT_Error *errors ) - { - FT_Int i; - - - for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) - { - new_names[i] = NULL; - if ( NULL != stream ) - errors[i] = FT_Stream_Seek( stream, 0 ); - else - errors[i] = FT_Err_Ok; - - if ( errors[i] ) - continue ; - - errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, - stream, base_name, - &(new_names[i]), - &(offsets[i]) ); - } - - return; - } - - -#ifndef FT_MACINTOSH - static FT_RFork_Rule - raccess_get_rule_type_from_rule_index( FT_Library library, - FT_UInt rule_index ) - { - FT_UNUSED( library ); - - if ( rule_index >= FT_RACCESS_N_RULES ) - return FT_RFork_Rule_invalid; - - return FT_RACCESS_GUESS_TABLE_GET[rule_index].type; - } - - - /* - * For this function, refer ftbase.h. - */ - FT_LOCAL_DEF( FT_Bool ) - ft_raccess_rule_by_darwin_vfs( FT_Library library, - FT_UInt rule_index ) - { - switch( raccess_get_rule_type_from_rule_index( library, rule_index ) ) - { - case FT_RFork_Rule_darwin_newvfs: - case FT_RFork_Rule_darwin_hfsplus: - return TRUE; - - default: - return FALSE; - } - } -#endif - - - static FT_Error - raccess_guess_apple_double( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - FT_Int32 magic = ( 0x00 << 24 ) | - ( 0x05 << 16 ) | - ( 0x16 << 8 ) | - 0x07; - - - *result_file_name = NULL; - if ( NULL == stream ) - return FT_THROW( Cannot_Open_Stream ); - - return raccess_guess_apple_generic( library, stream, base_file_name, - magic, result_offset ); - } - - - static FT_Error - raccess_guess_apple_single( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - FT_Int32 magic = ( 0x00 << 24 ) | - ( 0x05 << 16 ) | - ( 0x16 << 8 ) | - 0x00; - - - *result_file_name = NULL; - if ( NULL == stream ) - return FT_THROW( Cannot_Open_Stream ); - - return raccess_guess_apple_generic( library, stream, base_file_name, - magic, result_offset ); - } - - - static FT_Error - raccess_guess_darwin_ufs_export( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Error error; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - newpath = raccess_make_file_name( memory, base_file_name, "._" ); - if ( !newpath ) - return FT_THROW( Out_Of_Memory ); - - error = raccess_guess_linux_double_from_file_name( library, newpath, - result_offset ); - if ( !error ) - *result_file_name = newpath; - else - FT_FREE( newpath ); - - return error; - } - - - static FT_Error - raccess_guess_darwin_hfsplus( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - /* - Only meaningful on systems with hfs+ drivers (or Macs). - */ - FT_Error error; - char* newpath = NULL; - FT_Memory memory; - FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name ); - - FT_UNUSED( stream ); - - - memory = library->memory; - - if ( base_file_len + 6 > FT_INT_MAX ) - return FT_THROW( Array_Too_Large ); - - if ( FT_ALLOC( newpath, base_file_len + 6 ) ) - return error; - - FT_MEM_COPY( newpath, base_file_name, base_file_len ); - FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 ); - - *result_file_name = newpath; - *result_offset = 0; - - return FT_Err_Ok; - } - - - static FT_Error - raccess_guess_darwin_newvfs( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - /* - Only meaningful on systems with Mac OS X (> 10.1). - */ - FT_Error error; - char* newpath = NULL; - FT_Memory memory; - FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name ); - - FT_UNUSED( stream ); - - - memory = library->memory; - - if ( base_file_len + 18 > FT_INT_MAX ) - return FT_THROW( Array_Too_Large ); - - if ( FT_ALLOC( newpath, base_file_len + 18 ) ) - return error; - - FT_MEM_COPY( newpath, base_file_name, base_file_len ); - FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); - - *result_file_name = newpath; - *result_offset = 0; - - return FT_Err_Ok; - } - - - static FT_Error - raccess_guess_vfat( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - - newpath = raccess_make_file_name( memory, base_file_name, - "resource.frk/" ); - if ( !newpath ) - return FT_THROW( Out_Of_Memory ); - - *result_file_name = newpath; - *result_offset = 0; - - return FT_Err_Ok; - } - - - static FT_Error - raccess_guess_linux_cap( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - - newpath = raccess_make_file_name( memory, base_file_name, ".resource/" ); - if ( !newpath ) - return FT_THROW( Out_Of_Memory ); - - *result_file_name = newpath; - *result_offset = 0; - - return FT_Err_Ok; - } - - - static FT_Error - raccess_guess_linux_double( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Error error; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - - newpath = raccess_make_file_name( memory, base_file_name, "%" ); - if ( !newpath ) - return FT_THROW( Out_Of_Memory ); - - error = raccess_guess_linux_double_from_file_name( library, newpath, - result_offset ); - if ( !error ) - *result_file_name = newpath; - else - FT_FREE( newpath ); - - return error; - } - - - static FT_Error - raccess_guess_linux_netatalk( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Error error; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - - newpath = raccess_make_file_name( memory, base_file_name, - ".AppleDouble/" ); - if ( !newpath ) - return FT_THROW( Out_Of_Memory ); - - error = raccess_guess_linux_double_from_file_name( library, newpath, - result_offset ); - if ( !error ) - *result_file_name = newpath; - else - FT_FREE( newpath ); - - return error; - } - - - static FT_Error - raccess_guess_apple_generic( FT_Library library, - FT_Stream stream, - char *base_file_name, - FT_Int32 magic, - FT_Long *result_offset ) - { - FT_Int32 magic_from_stream; - FT_Error error; - FT_Int32 version_number = 0; - FT_UShort n_of_entries; - - int i; - FT_UInt32 entry_id, entry_offset, entry_length = 0; - - const FT_UInt32 resource_fork_entry_id = 0x2; - - FT_UNUSED( library ); - FT_UNUSED( base_file_name ); - FT_UNUSED( version_number ); - FT_UNUSED( entry_length ); - - - if ( FT_READ_LONG( magic_from_stream ) ) - return error; - if ( magic_from_stream != magic ) - return FT_THROW( Unknown_File_Format ); - - if ( FT_READ_LONG( version_number ) ) - return error; - - /* filler */ - error = FT_Stream_Skip( stream, 16 ); - if ( error ) - return error; - - if ( FT_READ_USHORT( n_of_entries ) ) - return error; - if ( n_of_entries == 0 ) - return FT_THROW( Unknown_File_Format ); - - for ( i = 0; i < n_of_entries; i++ ) - { - if ( FT_READ_LONG( entry_id ) ) - return error; - if ( entry_id == resource_fork_entry_id ) - { - if ( FT_READ_LONG( entry_offset ) || - FT_READ_LONG( entry_length ) ) - continue; - *result_offset = entry_offset; - - return FT_Err_Ok; - } - else - { - error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ - if ( error ) - return error; - } - } - - return FT_THROW( Unknown_File_Format ); - } - - - static FT_Error - raccess_guess_linux_double_from_file_name( FT_Library library, - char *file_name, - FT_Long *result_offset ) - { - FT_Open_Args args2; - FT_Stream stream2; - char * nouse = NULL; - FT_Error error; - - - args2.flags = FT_OPEN_PATHNAME; - args2.pathname = file_name; - error = FT_Stream_New( library, &args2, &stream2 ); - if ( error ) - return error; - - error = raccess_guess_apple_double( library, stream2, file_name, - &nouse, result_offset ); - - FT_Stream_Free( stream2, 0 ); - - return error; - } - - - static char* - raccess_make_file_name( FT_Memory memory, - const char *original_name, - const char *insertion ) - { - char* new_name = NULL; - const char* tmp; - const char* slash; - size_t new_length; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - new_length = ft_strlen( original_name ) + ft_strlen( insertion ); - if ( FT_ALLOC( new_name, new_length + 1 ) ) - return NULL; - - tmp = ft_strrchr( original_name, '/' ); - if ( tmp ) - { - ft_strncpy( new_name, original_name, tmp - original_name + 1 ); - new_name[tmp - original_name + 1] = '\0'; - slash = tmp + 1; - } - else - { - slash = original_name; - new_name[0] = '\0'; - } - - ft_strcat( new_name, insertion ); - ft_strcat( new_name, slash ); - - return new_name; - } - - -#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ - - - /*************************************************************************/ - /* Dummy function; just sets errors */ - /*************************************************************************/ - - FT_BASE_DEF( void ) - FT_Raccess_Guess( FT_Library library, - FT_Stream stream, - char *base_name, - char **new_names, - FT_Long *offsets, - FT_Error *errors ) - { - FT_Int i; - - FT_UNUSED( library ); - FT_UNUSED( stream ); - FT_UNUSED( base_name ); - - - for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) - { - new_names[i] = NULL; - offsets[i] = 0; - errors[i] = FT_ERR( Unimplemented_Feature ); - } - } - - -#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftsnames.c b/drivers/freetype/freetype/src/base/ftsnames.c deleted file mode 100644 index 260e91c148..0000000000 --- a/drivers/freetype/freetype/src/base/ftsnames.c +++ /dev/null @@ -1,94 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsnames.c */ -/* */ -/* Simple interface to access SFNT name tables (which are used */ -/* to hold font names, copyright info, notices, etc.) (body). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2001, 2002, 2009 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_SFNT_NAMES_H -#include FT_INTERNAL_TRUETYPE_TYPES_H -#include FT_INTERNAL_STREAM_H - - -#ifdef TT_CONFIG_OPTION_SFNT_NAMES - - - /* documentation is in ftsnames.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Get_Sfnt_Name_Count( FT_Face face ) - { - return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0; - } - - - /* documentation is in ftsnames.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Sfnt_Name( FT_Face face, - FT_UInt idx, - FT_SfntName *aname ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - - - if ( aname && face && FT_IS_SFNT( face ) ) - { - TT_Face ttface = (TT_Face)face; - - - if ( idx < (FT_UInt)ttface->num_names ) - { - TT_NameEntryRec* entry = ttface->name_table.names + idx; - - - /* load name on demand */ - if ( entry->stringLength > 0 && entry->string == NULL ) - { - FT_Memory memory = face->memory; - FT_Stream stream = face->stream; - - - if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || - FT_STREAM_SEEK( entry->stringOffset ) || - FT_STREAM_READ( entry->string, entry->stringLength ) ) - { - FT_FREE( entry->string ); - entry->stringLength = 0; - } - } - - aname->platform_id = entry->platformID; - aname->encoding_id = entry->encodingID; - aname->language_id = entry->languageID; - aname->name_id = entry->nameID; - aname->string = (FT_Byte*)entry->string; - aname->string_len = entry->stringLength; - - error = FT_Err_Ok; - } - } - - return error; - } - - -#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftstream.c b/drivers/freetype/freetype/src/base/ftstream.c deleted file mode 100644 index d965333daa..0000000000 --- a/drivers/freetype/freetype/src/base/ftstream.c +++ /dev/null @@ -1,865 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstream.c */ -/* */ -/* I/O stream support (body). */ -/* */ -/* Copyright 2000-2002, 2004-2006, 2008-2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_DEBUG_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_stream - - - FT_BASE_DEF( void ) - FT_Stream_OpenMemory( FT_Stream stream, - const FT_Byte* base, - FT_ULong size ) - { - stream->base = (FT_Byte*) base; - stream->size = size; - stream->pos = 0; - stream->cursor = 0; - stream->read = 0; - stream->close = 0; - } - - - FT_BASE_DEF( void ) - FT_Stream_Close( FT_Stream stream ) - { - if ( stream && stream->close ) - stream->close( stream ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_Seek( FT_Stream stream, - FT_ULong pos ) - { - FT_Error error = FT_Err_Ok; - - - if ( stream->read ) - { - if ( stream->read( stream, pos, 0, 0 ) ) - { - FT_ERROR(( "FT_Stream_Seek:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - error = FT_THROW( Invalid_Stream_Operation ); - } - } - /* note that seeking to the first position after the file is valid */ - else if ( pos > stream->size ) - { - FT_ERROR(( "FT_Stream_Seek:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - error = FT_THROW( Invalid_Stream_Operation ); - } - - if ( !error ) - stream->pos = pos; - - return error; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_Skip( FT_Stream stream, - FT_Long distance ) - { - if ( distance < 0 ) - return FT_THROW( Invalid_Stream_Operation ); - - return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); - } - - - FT_BASE_DEF( FT_Long ) - FT_Stream_Pos( FT_Stream stream ) - { - return stream->pos; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_Read( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Stream_ReadAt( stream, stream->pos, buffer, count ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_ReadAt( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ) - { - FT_Error error = FT_Err_Ok; - FT_ULong read_bytes; - - - if ( pos >= stream->size ) - { - FT_ERROR(( "FT_Stream_ReadAt:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - return FT_THROW( Invalid_Stream_Operation ); - } - - if ( stream->read ) - read_bytes = stream->read( stream, pos, buffer, count ); - else - { - read_bytes = stream->size - pos; - if ( read_bytes > count ) - read_bytes = count; - - FT_MEM_COPY( buffer, stream->base + pos, read_bytes ); - } - - stream->pos = pos + read_bytes; - - if ( read_bytes < count ) - { - FT_ERROR(( "FT_Stream_ReadAt:" - " invalid read; expected %lu bytes, got %lu\n", - count, read_bytes )); - - error = FT_THROW( Invalid_Stream_Operation ); - } - - return error; - } - - - FT_BASE_DEF( FT_ULong ) - FT_Stream_TryRead( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ) - { - FT_ULong read_bytes = 0; - - - if ( stream->pos >= stream->size ) - goto Exit; - - if ( stream->read ) - read_bytes = stream->read( stream, stream->pos, buffer, count ); - else - { - read_bytes = stream->size - stream->pos; - if ( read_bytes > count ) - read_bytes = count; - - FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes ); - } - - stream->pos += read_bytes; - - Exit: - return read_bytes; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_ExtractFrame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ) - { - FT_Error error; - - - error = FT_Stream_EnterFrame( stream, count ); - if ( !error ) - { - *pbytes = (FT_Byte*)stream->cursor; - - /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ - stream->cursor = 0; - stream->limit = 0; - } - - return error; - } - - - FT_BASE_DEF( void ) - FT_Stream_ReleaseFrame( FT_Stream stream, - FT_Byte** pbytes ) - { - if ( stream && stream->read ) - { - FT_Memory memory = stream->memory; - -#ifdef FT_DEBUG_MEMORY - ft_mem_free( memory, *pbytes ); - *pbytes = NULL; -#else - FT_FREE( *pbytes ); -#endif - } - *pbytes = 0; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_EnterFrame( FT_Stream stream, - FT_ULong count ) - { - FT_Error error = FT_Err_Ok; - FT_ULong read_bytes; - - - /* check for nested frame access */ - FT_ASSERT( stream && stream->cursor == 0 ); - - if ( stream->read ) - { - /* allocate the frame in memory */ - FT_Memory memory = stream->memory; - - - /* simple sanity check */ - if ( count > stream->size ) - { - FT_ERROR(( "FT_Stream_EnterFrame:" - " frame size (%lu) larger than stream size (%lu)\n", - count, stream->size )); - - error = FT_THROW( Invalid_Stream_Operation ); - goto Exit; - } - -#ifdef FT_DEBUG_MEMORY - /* assume _ft_debug_file and _ft_debug_lineno are already set */ - stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error ); - if ( error ) - goto Exit; -#else - if ( FT_QALLOC( stream->base, count ) ) - goto Exit; -#endif - /* read it */ - read_bytes = stream->read( stream, stream->pos, - stream->base, count ); - if ( read_bytes < count ) - { - FT_ERROR(( "FT_Stream_EnterFrame:" - " invalid read; expected %lu bytes, got %lu\n", - count, read_bytes )); - - FT_FREE( stream->base ); - error = FT_THROW( Invalid_Stream_Operation ); - } - stream->cursor = stream->base; - stream->limit = stream->cursor + count; - stream->pos += read_bytes; - } - else - { - /* check current and new position */ - if ( stream->pos >= stream->size || - stream->size - stream->pos < count ) - { - FT_ERROR(( "FT_Stream_EnterFrame:" - " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", - stream->pos, count, stream->size )); - - error = FT_THROW( Invalid_Stream_Operation ); - goto Exit; - } - - /* set cursor */ - stream->cursor = stream->base + stream->pos; - stream->limit = stream->cursor + count; - stream->pos += count; - } - - Exit: - return error; - } - - - FT_BASE_DEF( void ) - FT_Stream_ExitFrame( FT_Stream stream ) - { - /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */ - /* that it is possible to access a frame of length 0 in */ - /* some weird fonts (usually, when accessing an array of */ - /* 0 records, like in some strange kern tables). */ - /* */ - /* In this case, the loader code handles the 0-length table */ - /* gracefully; however, stream.cursor is really set to 0 by the */ - /* FT_Stream_EnterFrame() call, and this is not an error. */ - /* */ - FT_ASSERT( stream ); - - if ( stream->read ) - { - FT_Memory memory = stream->memory; - -#ifdef FT_DEBUG_MEMORY - ft_mem_free( memory, stream->base ); - stream->base = NULL; -#else - FT_FREE( stream->base ); -#endif - } - stream->cursor = 0; - stream->limit = 0; - } - - - FT_BASE_DEF( FT_Char ) - FT_Stream_GetChar( FT_Stream stream ) - { - FT_Char result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - if ( stream->cursor < stream->limit ) - result = *stream->cursor++; - - return result; - } - - - FT_BASE_DEF( FT_UShort ) - FT_Stream_GetUShort( FT_Stream stream ) - { - FT_Byte* p; - FT_Short result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 1 < stream->limit ) - result = FT_NEXT_USHORT( p ); - stream->cursor = p; - - return result; - } - - - FT_BASE_DEF( FT_UShort ) - FT_Stream_GetUShortLE( FT_Stream stream ) - { - FT_Byte* p; - FT_Short result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 1 < stream->limit ) - result = FT_NEXT_USHORT_LE( p ); - stream->cursor = p; - - return result; - } - - - FT_BASE_DEF( FT_ULong ) - FT_Stream_GetUOffset( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 2 < stream->limit ) - result = FT_NEXT_UOFF3( p ); - stream->cursor = p; - return result; - } - - - FT_BASE_DEF( FT_ULong ) - FT_Stream_GetULong( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 3 < stream->limit ) - result = FT_NEXT_ULONG( p ); - stream->cursor = p; - return result; - } - - - FT_BASE_DEF( FT_ULong ) - FT_Stream_GetULongLE( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 3 < stream->limit ) - result = FT_NEXT_ULONG_LE( p ); - stream->cursor = p; - return result; - } - - - FT_BASE_DEF( FT_Char ) - FT_Stream_ReadChar( FT_Stream stream, - FT_Error* error ) - { - FT_Byte result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) - goto Fail; - } - else - { - if ( stream->pos < stream->size ) - result = stream->base[stream->pos]; - else - goto Fail; - } - stream->pos++; - - return result; - - Fail: - *error = FT_THROW( Invalid_Stream_Operation ); - FT_ERROR(( "FT_Stream_ReadChar:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_UShort ) - FT_Stream_ReadUShort( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 1 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_USHORT( p ); - } - else - goto Fail; - - stream->pos += 2; - - return result; - - Fail: - *error = FT_THROW( Invalid_Stream_Operation ); - FT_ERROR(( "FT_Stream_ReadUShort:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_UShort ) - FT_Stream_ReadUShortLE( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 1 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_USHORT_LE( p ); - } - else - goto Fail; - - stream->pos += 2; - - return result; - - Fail: - *error = FT_THROW( Invalid_Stream_Operation ); - FT_ERROR(( "FT_Stream_ReadUShortLE:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_ULong ) - FT_Stream_ReadUOffset( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[3]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 2 < stream->size ) - { - if ( stream->read ) - { - if (stream->read( stream, stream->pos, reads, 3L ) != 3L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_UOFF3( p ); - } - else - goto Fail; - - stream->pos += 3; - - return result; - - Fail: - *error = FT_THROW( Invalid_Stream_Operation ); - FT_ERROR(( "FT_Stream_ReadUOffset:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_ULong ) - FT_Stream_ReadULong( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 3 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_ULONG( p ); - } - else - goto Fail; - - stream->pos += 4; - - return result; - - Fail: - *error = FT_THROW( Invalid_Stream_Operation ); - FT_ERROR(( "FT_Stream_ReadULong:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_ULong ) - FT_Stream_ReadULongLE( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 3 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_ULONG_LE( p ); - } - else - goto Fail; - - stream->pos += 4; - - return result; - - Fail: - *error = FT_THROW( Invalid_Stream_Operation ); - FT_ERROR(( "FT_Stream_ReadULongLE:" - " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_ReadFields( FT_Stream stream, - const FT_Frame_Field* fields, - void* structure ) - { - FT_Error error; - FT_Bool frame_accessed = 0; - FT_Byte* cursor; - - - if ( !fields || !stream ) - return FT_THROW( Invalid_Argument ); - - cursor = stream->cursor; - - error = FT_Err_Ok; - do - { - FT_ULong value; - FT_Int sign_shift; - FT_Byte* p; - - - switch ( fields->value ) - { - case ft_frame_start: /* access a new frame */ - error = FT_Stream_EnterFrame( stream, fields->offset ); - if ( error ) - goto Exit; - - frame_accessed = 1; - cursor = stream->cursor; - fields++; - continue; /* loop! */ - - case ft_frame_bytes: /* read a byte sequence */ - case ft_frame_skip: /* skip some bytes */ - { - FT_UInt len = fields->size; - - - if ( cursor + len > stream->limit ) - { - error = FT_THROW( Invalid_Stream_Operation ); - goto Exit; - } - - if ( fields->value == ft_frame_bytes ) - { - p = (FT_Byte*)structure + fields->offset; - FT_MEM_COPY( p, cursor, len ); - } - cursor += len; - fields++; - continue; - } - - case ft_frame_byte: - case ft_frame_schar: /* read a single byte */ - value = FT_NEXT_BYTE( cursor ); - sign_shift = 24; - break; - - case ft_frame_short_be: - case ft_frame_ushort_be: /* read a 2-byte big-endian short */ - value = FT_NEXT_USHORT( cursor) ; - sign_shift = 16; - break; - - case ft_frame_short_le: - case ft_frame_ushort_le: /* read a 2-byte little-endian short */ - value = FT_NEXT_USHORT_LE( cursor ); - sign_shift = 16; - break; - - case ft_frame_long_be: - case ft_frame_ulong_be: /* read a 4-byte big-endian long */ - value = FT_NEXT_ULONG( cursor ); - sign_shift = 0; - break; - - case ft_frame_long_le: - case ft_frame_ulong_le: /* read a 4-byte little-endian long */ - value = FT_NEXT_ULONG_LE( cursor ); - sign_shift = 0; - break; - - case ft_frame_off3_be: - case ft_frame_uoff3_be: /* read a 3-byte big-endian long */ - value = FT_NEXT_UOFF3( cursor ); - sign_shift = 8; - break; - - case ft_frame_off3_le: - case ft_frame_uoff3_le: /* read a 3-byte little-endian long */ - value = FT_NEXT_UOFF3_LE( cursor ); - sign_shift = 8; - break; - - default: - /* otherwise, exit the loop */ - stream->cursor = cursor; - goto Exit; - } - - /* now, compute the signed value is necessary */ - if ( fields->value & FT_FRAME_OP_SIGNED ) - value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); - - /* finally, store the value in the object */ - - p = (FT_Byte*)structure + fields->offset; - switch ( fields->size ) - { - case ( 8 / FT_CHAR_BIT ): - *(FT_Byte*)p = (FT_Byte)value; - break; - - case ( 16 / FT_CHAR_BIT ): - *(FT_UShort*)p = (FT_UShort)value; - break; - - case ( 32 / FT_CHAR_BIT ): - *(FT_UInt32*)p = (FT_UInt32)value; - break; - - default: /* for 64-bit systems */ - *(FT_ULong*)p = (FT_ULong)value; - } - - /* go to next field */ - fields++; - } - while ( 1 ); - - Exit: - /* close the frame if it was opened by this read */ - if ( frame_accessed ) - FT_Stream_ExitFrame( stream ); - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftstroke.c b/drivers/freetype/freetype/src/base/ftstroke.c deleted file mode 100644 index ee61ceca0e..0000000000 --- a/drivers/freetype/freetype/src/base/ftstroke.c +++ /dev/null @@ -1,2418 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstroke.c */ -/* */ -/* FreeType path stroker (body). */ -/* */ -/* Copyright 2002-2006, 2008-2011, 2013 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_STROKER_H -#include FT_TRIGONOMETRY_H -#include FT_OUTLINE_H -#include FT_INTERNAL_MEMORY_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_StrokerBorder ) - FT_Outline_GetInsideBorder( FT_Outline* outline ) - { - FT_Orientation o = FT_Outline_Get_Orientation( outline ); - - - return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT - : FT_STROKER_BORDER_LEFT; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_StrokerBorder ) - FT_Outline_GetOutsideBorder( FT_Outline* outline ) - { - FT_Orientation o = FT_Outline_Get_Orientation( outline ); - - - return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT - : FT_STROKER_BORDER_RIGHT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** BEZIER COMPUTATIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define FT_SMALL_CONIC_THRESHOLD ( FT_ANGLE_PI / 6 ) -#define FT_SMALL_CUBIC_THRESHOLD ( FT_ANGLE_PI / 8 ) - -#define FT_EPSILON 2 - -#define FT_IS_SMALL( x ) ( (x) > -FT_EPSILON && (x) < FT_EPSILON ) - - - static FT_Pos - ft_pos_abs( FT_Pos x ) - { - return x >= 0 ? x : -x; - } - - - static void - ft_conic_split( FT_Vector* base ) - { - FT_Pos a, b; - - - base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; - - base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; - } - - - static FT_Bool - ft_conic_is_small_enough( FT_Vector* base, - FT_Angle *angle_in, - FT_Angle *angle_out ) - { - FT_Vector d1, d2; - FT_Angle theta; - FT_Int close1, close2; - - - d1.x = base[1].x - base[2].x; - d1.y = base[1].y - base[2].y; - d2.x = base[0].x - base[1].x; - d2.y = base[0].y - base[1].y; - - close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); - close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); - - if ( close1 ) - { - if ( close2 ) - { - /* basically a point; */ - /* do nothing to retain original direction */ - } - else - { - *angle_in = - *angle_out = FT_Atan2( d2.x, d2.y ); - } - } - else /* !close1 */ - { - if ( close2 ) - { - *angle_in = - *angle_out = FT_Atan2( d1.x, d1.y ); - } - else - { - *angle_in = FT_Atan2( d1.x, d1.y ); - *angle_out = FT_Atan2( d2.x, d2.y ); - } - } - - theta = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_out ) ); - - return FT_BOOL( theta < FT_SMALL_CONIC_THRESHOLD ); - } - - - static void - ft_cubic_split( FT_Vector* base ) - { - FT_Pos a, b, c, d; - - - base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c ) / 2; - base[5].x = b = ( base[3].x + d ) / 2; - c = ( c + d ) / 2; - base[2].x = a = ( a + c ) / 2; - base[4].x = b = ( b + c ) / 2; - base[3].x = ( a + b ) / 2; - - base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c ) / 2; - base[5].y = b = ( base[3].y + d ) / 2; - c = ( c + d ) / 2; - base[2].y = a = ( a + c ) / 2; - base[4].y = b = ( b + c ) / 2; - base[3].y = ( a + b ) / 2; - } - - - /* Return the average of `angle1' and `angle2'. */ - /* This gives correct result even if `angle1' and `angle2' */ - /* have opposite signs. */ - static FT_Angle - ft_angle_mean( FT_Angle angle1, - FT_Angle angle2 ) - { - return angle1 + FT_Angle_Diff( angle1, angle2 ) / 2; - } - - - static FT_Bool - ft_cubic_is_small_enough( FT_Vector* base, - FT_Angle *angle_in, - FT_Angle *angle_mid, - FT_Angle *angle_out ) - { - FT_Vector d1, d2, d3; - FT_Angle theta1, theta2; - FT_Int close1, close2, close3; - - - d1.x = base[2].x - base[3].x; - d1.y = base[2].y - base[3].y; - d2.x = base[1].x - base[2].x; - d2.y = base[1].y - base[2].y; - d3.x = base[0].x - base[1].x; - d3.y = base[0].y - base[1].y; - - close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); - close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); - close3 = FT_IS_SMALL( d3.x ) && FT_IS_SMALL( d3.y ); - - if ( close1 ) - { - if ( close2 ) - { - if ( close3 ) - { - /* basically a point; */ - /* do nothing to retain original direction */ - } - else /* !close3 */ - { - *angle_in = - *angle_mid = - *angle_out = FT_Atan2( d3.x, d3.y ); - } - } - else /* !close2 */ - { - if ( close3 ) - { - *angle_in = - *angle_mid = - *angle_out = FT_Atan2( d2.x, d2.y ); - } - else /* !close3 */ - { - *angle_in = - *angle_mid = FT_Atan2( d2.x, d2.y ); - *angle_out = FT_Atan2( d3.x, d3.y ); - } - } - } - else /* !close1 */ - { - if ( close2 ) - { - if ( close3 ) - { - *angle_in = - *angle_mid = - *angle_out = FT_Atan2( d1.x, d1.y ); - } - else /* !close3 */ - { - *angle_in = FT_Atan2( d1.x, d1.y ); - *angle_out = FT_Atan2( d3.x, d3.y ); - *angle_mid = ft_angle_mean( *angle_in, *angle_out ); - } - } - else /* !close2 */ - { - if ( close3 ) - { - *angle_in = FT_Atan2( d1.x, d1.y ); - *angle_mid = - *angle_out = FT_Atan2( d2.x, d2.y ); - } - else /* !close3 */ - { - *angle_in = FT_Atan2( d1.x, d1.y ); - *angle_mid = FT_Atan2( d2.x, d2.y ); - *angle_out = FT_Atan2( d3.x, d3.y ); - } - } - } - - theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_mid ) ); - theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) ); - - return FT_BOOL( theta1 < FT_SMALL_CUBIC_THRESHOLD && - theta2 < FT_SMALL_CUBIC_THRESHOLD ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** STROKE BORDERS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef enum FT_StrokeTags_ - { - FT_STROKE_TAG_ON = 1, /* on-curve point */ - FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ - FT_STROKE_TAG_BEGIN = 4, /* sub-path start */ - FT_STROKE_TAG_END = 8 /* sub-path end */ - - } FT_StrokeTags; - -#define FT_STROKE_TAG_BEGIN_END ( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ) - - typedef struct FT_StrokeBorderRec_ - { - FT_UInt num_points; - FT_UInt max_points; - FT_Vector* points; - FT_Byte* tags; - FT_Bool movable; /* TRUE for ends of lineto borders */ - FT_Int start; /* index of current sub-path start point */ - FT_Memory memory; - FT_Bool valid; - - } FT_StrokeBorderRec, *FT_StrokeBorder; - - - static FT_Error - ft_stroke_border_grow( FT_StrokeBorder border, - FT_UInt new_points ) - { - FT_UInt old_max = border->max_points; - FT_UInt new_max = border->num_points + new_points; - FT_Error error = FT_Err_Ok; - - - if ( new_max > old_max ) - { - FT_UInt cur_max = old_max; - FT_Memory memory = border->memory; - - - while ( cur_max < new_max ) - cur_max += ( cur_max >> 1 ) + 16; - - if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) || - FT_RENEW_ARRAY( border->tags, old_max, cur_max ) ) - goto Exit; - - border->max_points = cur_max; - } - - Exit: - return error; - } - - - static void - ft_stroke_border_close( FT_StrokeBorder border, - FT_Bool reverse ) - { - FT_UInt start = border->start; - FT_UInt count = border->num_points; - - - FT_ASSERT( border->start >= 0 ); - - /* don't record empty paths! */ - if ( count <= start + 1U ) - border->num_points = start; - else - { - /* copy the last point to the start of this sub-path, since */ - /* it contains the `adjusted' starting coordinates */ - border->num_points = --count; - border->points[start] = border->points[count]; - - if ( reverse ) - { - /* reverse the points */ - { - FT_Vector* vec1 = border->points + start + 1; - FT_Vector* vec2 = border->points + count - 1; - - - for ( ; vec1 < vec2; vec1++, vec2-- ) - { - FT_Vector tmp; - - - tmp = *vec1; - *vec1 = *vec2; - *vec2 = tmp; - } - } - - /* then the tags */ - { - FT_Byte* tag1 = border->tags + start + 1; - FT_Byte* tag2 = border->tags + count - 1; - - - for ( ; tag1 < tag2; tag1++, tag2-- ) - { - FT_Byte tmp; - - - tmp = *tag1; - *tag1 = *tag2; - *tag2 = tmp; - } - } - } - - border->tags[start ] |= FT_STROKE_TAG_BEGIN; - border->tags[count - 1] |= FT_STROKE_TAG_END; - } - - border->start = -1; - border->movable = FALSE; - } - - - static FT_Error - ft_stroke_border_lineto( FT_StrokeBorder border, - FT_Vector* to, - FT_Bool movable ) - { - FT_Error error = FT_Err_Ok; - - - FT_ASSERT( border->start >= 0 ); - - if ( border->movable ) - { - /* move last point */ - border->points[border->num_points - 1] = *to; - } - else - { - /* don't add zero-length lineto */ - if ( border->num_points > 0 && - FT_IS_SMALL( border->points[border->num_points - 1].x - to->x ) && - FT_IS_SMALL( border->points[border->num_points - 1].y - to->y ) ) - return error; - - /* add one point */ - error = ft_stroke_border_grow( border, 1 ); - if ( !error ) - { - FT_Vector* vec = border->points + border->num_points; - FT_Byte* tag = border->tags + border->num_points; - - - vec[0] = *to; - tag[0] = FT_STROKE_TAG_ON; - - border->num_points += 1; - } - } - border->movable = movable; - return error; - } - - - static FT_Error - ft_stroke_border_conicto( FT_StrokeBorder border, - FT_Vector* control, - FT_Vector* to ) - { - FT_Error error; - - - FT_ASSERT( border->start >= 0 ); - - error = ft_stroke_border_grow( border, 2 ); - if ( !error ) - { - FT_Vector* vec = border->points + border->num_points; - FT_Byte* tag = border->tags + border->num_points; - - - vec[0] = *control; - vec[1] = *to; - - tag[0] = 0; - tag[1] = FT_STROKE_TAG_ON; - - border->num_points += 2; - } - - border->movable = FALSE; - - return error; - } - - - static FT_Error - ft_stroke_border_cubicto( FT_StrokeBorder border, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) - { - FT_Error error; - - - FT_ASSERT( border->start >= 0 ); - - error = ft_stroke_border_grow( border, 3 ); - if ( !error ) - { - FT_Vector* vec = border->points + border->num_points; - FT_Byte* tag = border->tags + border->num_points; - - - vec[0] = *control1; - vec[1] = *control2; - vec[2] = *to; - - tag[0] = FT_STROKE_TAG_CUBIC; - tag[1] = FT_STROKE_TAG_CUBIC; - tag[2] = FT_STROKE_TAG_ON; - - border->num_points += 3; - } - - border->movable = FALSE; - - return error; - } - - -#define FT_ARC_CUBIC_ANGLE ( FT_ANGLE_PI / 2 ) - - - static FT_Error - ft_stroke_border_arcto( FT_StrokeBorder border, - FT_Vector* center, - FT_Fixed radius, - FT_Angle angle_start, - FT_Angle angle_diff ) - { - FT_Angle total, angle, step, rotate, next, theta; - FT_Vector a, b, a2, b2; - FT_Fixed length; - FT_Error error = FT_Err_Ok; - - - /* compute start point */ - FT_Vector_From_Polar( &a, radius, angle_start ); - a.x += center->x; - a.y += center->y; - - total = angle_diff; - angle = angle_start; - rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2; - - while ( total != 0 ) - { - step = total; - if ( step > FT_ARC_CUBIC_ANGLE ) - step = FT_ARC_CUBIC_ANGLE; - - else if ( step < -FT_ARC_CUBIC_ANGLE ) - step = -FT_ARC_CUBIC_ANGLE; - - next = angle + step; - theta = step; - if ( theta < 0 ) - theta = -theta; - - theta >>= 1; - - /* compute end point */ - FT_Vector_From_Polar( &b, radius, next ); - b.x += center->x; - b.y += center->y; - - /* compute first and second control points */ - length = FT_MulDiv( radius, FT_Sin( theta ) * 4, - ( 0x10000L + FT_Cos( theta ) ) * 3 ); - - FT_Vector_From_Polar( &a2, length, angle + rotate ); - a2.x += a.x; - a2.y += a.y; - - FT_Vector_From_Polar( &b2, length, next - rotate ); - b2.x += b.x; - b2.y += b.y; - - /* add cubic arc */ - error = ft_stroke_border_cubicto( border, &a2, &b2, &b ); - if ( error ) - break; - - /* process the rest of the arc ?? */ - a = b; - total -= step; - angle = next; - } - - return error; - } - - - static FT_Error - ft_stroke_border_moveto( FT_StrokeBorder border, - FT_Vector* to ) - { - /* close current open path if any ? */ - if ( border->start >= 0 ) - ft_stroke_border_close( border, FALSE ); - - border->start = border->num_points; - border->movable = FALSE; - - return ft_stroke_border_lineto( border, to, FALSE ); - } - - - static void - ft_stroke_border_init( FT_StrokeBorder border, - FT_Memory memory ) - { - border->memory = memory; - border->points = NULL; - border->tags = NULL; - - border->num_points = 0; - border->max_points = 0; - border->start = -1; - border->valid = FALSE; - } - - - static void - ft_stroke_border_reset( FT_StrokeBorder border ) - { - border->num_points = 0; - border->start = -1; - border->valid = FALSE; - } - - - static void - ft_stroke_border_done( FT_StrokeBorder border ) - { - FT_Memory memory = border->memory; - - - FT_FREE( border->points ); - FT_FREE( border->tags ); - - border->num_points = 0; - border->max_points = 0; - border->start = -1; - border->valid = FALSE; - } - - - static FT_Error - ft_stroke_border_get_counts( FT_StrokeBorder border, - FT_UInt *anum_points, - FT_UInt *anum_contours ) - { - FT_Error error = FT_Err_Ok; - FT_UInt num_points = 0; - FT_UInt num_contours = 0; - - FT_UInt count = border->num_points; - FT_Vector* point = border->points; - FT_Byte* tags = border->tags; - FT_Int in_contour = 0; - - - for ( ; count > 0; count--, num_points++, point++, tags++ ) - { - if ( tags[0] & FT_STROKE_TAG_BEGIN ) - { - if ( in_contour != 0 ) - goto Fail; - - in_contour = 1; - } - else if ( in_contour == 0 ) - goto Fail; - - if ( tags[0] & FT_STROKE_TAG_END ) - { - in_contour = 0; - num_contours++; - } - } - - if ( in_contour != 0 ) - goto Fail; - - border->valid = TRUE; - - Exit: - *anum_points = num_points; - *anum_contours = num_contours; - return error; - - Fail: - num_points = 0; - num_contours = 0; - goto Exit; - } - - - static void - ft_stroke_border_export( FT_StrokeBorder border, - FT_Outline* outline ) - { - /* copy point locations */ - FT_ARRAY_COPY( outline->points + outline->n_points, - border->points, - border->num_points ); - - /* copy tags */ - { - FT_UInt count = border->num_points; - FT_Byte* read = border->tags; - FT_Byte* write = (FT_Byte*)outline->tags + outline->n_points; - - - for ( ; count > 0; count--, read++, write++ ) - { - if ( *read & FT_STROKE_TAG_ON ) - *write = FT_CURVE_TAG_ON; - else if ( *read & FT_STROKE_TAG_CUBIC ) - *write = FT_CURVE_TAG_CUBIC; - else - *write = FT_CURVE_TAG_CONIC; - } - } - - /* copy contours */ - { - FT_UInt count = border->num_points; - FT_Byte* tags = border->tags; - FT_Short* write = outline->contours + outline->n_contours; - FT_Short idx = (FT_Short)outline->n_points; - - - for ( ; count > 0; count--, tags++, idx++ ) - { - if ( *tags & FT_STROKE_TAG_END ) - { - *write++ = idx; - outline->n_contours++; - } - } - } - - outline->n_points = (short)( outline->n_points + border->num_points ); - - FT_ASSERT( FT_Outline_Check( outline ) == 0 ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** STROKER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define FT_SIDE_TO_ROTATE( s ) ( FT_ANGLE_PI2 - (s) * FT_ANGLE_PI ) - - typedef struct FT_StrokerRec_ - { - FT_Angle angle_in; /* direction into curr join */ - FT_Angle angle_out; /* direction out of join */ - FT_Vector center; /* current position */ - FT_Fixed line_length; /* length of last lineto */ - FT_Bool first_point; /* is this the start? */ - FT_Bool subpath_open; /* is the subpath open? */ - FT_Angle subpath_angle; /* subpath start direction */ - FT_Vector subpath_start; /* subpath start position */ - FT_Fixed subpath_line_length; /* subpath start lineto len */ - FT_Bool handle_wide_strokes; /* use wide strokes logic? */ - - FT_Stroker_LineCap line_cap; - FT_Stroker_LineJoin line_join; - FT_Stroker_LineJoin line_join_saved; - FT_Fixed miter_limit; - FT_Fixed radius; - - FT_StrokeBorderRec borders[2]; - FT_Library library; - - } FT_StrokerRec; - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_New( FT_Library library, - FT_Stroker *astroker ) - { - FT_Error error; /* assigned in FT_NEW */ - FT_Memory memory; - FT_Stroker stroker = NULL; - - - if ( !library ) - return FT_THROW( Invalid_Argument ); - - memory = library->memory; - - if ( !FT_NEW( stroker ) ) - { - stroker->library = library; - - ft_stroke_border_init( &stroker->borders[0], memory ); - ft_stroke_border_init( &stroker->borders[1], memory ); - } - - *astroker = stroker; - - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_Set( FT_Stroker stroker, - FT_Fixed radius, - FT_Stroker_LineCap line_cap, - FT_Stroker_LineJoin line_join, - FT_Fixed miter_limit ) - { - stroker->radius = radius; - stroker->line_cap = line_cap; - stroker->line_join = line_join; - stroker->miter_limit = miter_limit; - - /* ensure miter limit has sensible value */ - if ( stroker->miter_limit < 0x10000 ) - stroker->miter_limit = 0x10000; - - /* save line join style: */ - /* line join style can be temporarily changed when stroking curves */ - stroker->line_join_saved = line_join; - - FT_Stroker_Rewind( stroker ); - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_Rewind( FT_Stroker stroker ) - { - if ( stroker ) - { - ft_stroke_border_reset( &stroker->borders[0] ); - ft_stroke_border_reset( &stroker->borders[1] ); - } - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_Done( FT_Stroker stroker ) - { - if ( stroker ) - { - FT_Memory memory = stroker->library->memory; - - - ft_stroke_border_done( &stroker->borders[0] ); - ft_stroke_border_done( &stroker->borders[1] ); - - stroker->library = NULL; - FT_FREE( stroker ); - } - } - - - /* create a circular arc at a corner or cap */ - static FT_Error - ft_stroker_arcto( FT_Stroker stroker, - FT_Int side ) - { - FT_Angle total, rotate; - FT_Fixed radius = stroker->radius; - FT_Error error = FT_Err_Ok; - FT_StrokeBorder border = stroker->borders + side; - - - rotate = FT_SIDE_TO_ROTATE( side ); - - total = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - if ( total == FT_ANGLE_PI ) - total = -rotate * 2; - - error = ft_stroke_border_arcto( border, - &stroker->center, - radius, - stroker->angle_in + rotate, - total ); - border->movable = FALSE; - return error; - } - - - /* add a cap at the end of an opened path */ - static FT_Error - ft_stroker_cap( FT_Stroker stroker, - FT_Angle angle, - FT_Int side ) - { - FT_Error error = FT_Err_Ok; - - - if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) - { - /* add a round cap */ - stroker->angle_in = angle; - stroker->angle_out = angle + FT_ANGLE_PI; - - error = ft_stroker_arcto( stroker, side ); - } - else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE ) - { - /* add a square cap */ - FT_Vector delta, delta2; - FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); - FT_Fixed radius = stroker->radius; - FT_StrokeBorder border = stroker->borders + side; - - - FT_Vector_From_Polar( &delta2, radius, angle + rotate ); - FT_Vector_From_Polar( &delta, radius, angle ); - - delta.x += stroker->center.x + delta2.x; - delta.y += stroker->center.y + delta2.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - FT_Vector_From_Polar( &delta2, radius, angle - rotate ); - FT_Vector_From_Polar( &delta, radius, angle ); - - delta.x += delta2.x + stroker->center.x; - delta.y += delta2.y + stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT ) - { - /* add a butt ending */ - FT_Vector delta; - FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); - FT_Fixed radius = stroker->radius; - FT_StrokeBorder border = stroker->borders + side; - - - FT_Vector_From_Polar( &delta, radius, angle + rotate ); - - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - FT_Vector_From_Polar( &delta, radius, angle - rotate ); - - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - - Exit: - return error; - } - - - /* process an inside corner, i.e. compute intersection */ - static FT_Error - ft_stroker_inside( FT_Stroker stroker, - FT_Int side, - FT_Fixed line_length ) - { - FT_StrokeBorder border = stroker->borders + side; - FT_Angle phi, theta, rotate; - FT_Fixed length, thcos; - FT_Vector delta; - FT_Error error = FT_Err_Ok; - FT_Bool intersect; /* use intersection of lines? */ - - - rotate = FT_SIDE_TO_ROTATE( side ); - - theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ) / 2; - - /* Only intersect borders if between two lineto's and both */ - /* lines are long enough (line_length is zero for curves). */ - if ( !border->movable || line_length == 0 ) - intersect = FALSE; - else - { - /* compute minimum required length of lines */ - FT_Fixed min_length = ft_pos_abs( FT_MulFix( stroker->radius, - FT_Tan( theta ) ) ); - - - intersect = FT_BOOL( stroker->line_length >= min_length && - line_length >= min_length ); - } - - if ( !intersect ) - { - FT_Vector_From_Polar( &delta, stroker->radius, - stroker->angle_out + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - border->movable = FALSE; - } - else - { - /* compute median angle */ - phi = stroker->angle_in + theta; - - thcos = FT_Cos( theta ); - - length = FT_DivFix( stroker->radius, thcos ); - - FT_Vector_From_Polar( &delta, length, phi + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - } - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - - return error; - } - - - /* process an outside corner, i.e. compute bevel/miter/round */ - static FT_Error - ft_stroker_outside( FT_Stroker stroker, - FT_Int side, - FT_Fixed line_length ) - { - FT_StrokeBorder border = stroker->borders + side; - FT_Error error; - FT_Angle rotate; - - - if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) - error = ft_stroker_arcto( stroker, side ); - else - { - /* this is a mitered (pointed) or beveled (truncated) corner */ - FT_Fixed sigma = 0, radius = stroker->radius; - FT_Angle theta = 0, phi = 0; - FT_Fixed thcos = 0; - FT_Bool bevel, fixed_bevel; - - - rotate = FT_SIDE_TO_ROTATE( side ); - - bevel = - FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_BEVEL ); - - fixed_bevel = - FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_MITER_VARIABLE ); - - if ( !bevel ) - { - theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - - if ( theta == FT_ANGLE_PI ) - { - theta = rotate; - phi = stroker->angle_in; - } - else - { - theta /= 2; - phi = stroker->angle_in + theta + rotate; - } - - thcos = FT_Cos( theta ); - sigma = FT_MulFix( stroker->miter_limit, thcos ); - - /* is miter limit exceeded? */ - if ( sigma < 0x10000L ) - { - /* don't create variable bevels for very small deviations; */ - /* FT_Sin(x) = 0 for x <= 57 */ - if ( fixed_bevel || ft_pos_abs( theta ) > 57 ) - bevel = TRUE; - } - } - - if ( bevel ) /* this is a bevel (broken angle) */ - { - if ( fixed_bevel ) - { - /* the outer corners are simply joined together */ - FT_Vector delta; - - - /* add bevel */ - FT_Vector_From_Polar( &delta, - radius, - stroker->angle_out + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - border->movable = FALSE; - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - else /* variable bevel */ - { - /* the miter is truncated */ - FT_Vector middle, delta; - FT_Fixed length; - - - /* compute middle point */ - FT_Vector_From_Polar( &middle, - FT_MulFix( radius, stroker->miter_limit ), - phi ); - middle.x += stroker->center.x; - middle.y += stroker->center.y; - - /* compute first angle point */ - length = FT_MulDiv( radius, 0x10000L - sigma, - ft_pos_abs( FT_Sin( theta ) ) ); - - FT_Vector_From_Polar( &delta, length, phi + rotate ); - delta.x += middle.x; - delta.y += middle.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - /* compute second angle point */ - FT_Vector_From_Polar( &delta, length, phi - rotate ); - delta.x += middle.x; - delta.y += middle.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - /* finally, add an end point; only needed if not lineto */ - /* (line_length is zero for curves) */ - if ( line_length == 0 ) - { - FT_Vector_From_Polar( &delta, - radius, - stroker->angle_out + rotate ); - - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - } - } - else /* this is a miter (intersection) */ - { - FT_Fixed length; - FT_Vector delta; - - - length = FT_DivFix( stroker->radius, thcos ); - - FT_Vector_From_Polar( &delta, length, phi ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - /* now add an end point; only needed if not lineto */ - /* (line_length is zero for curves) */ - if ( line_length == 0 ) - { - FT_Vector_From_Polar( &delta, - stroker->radius, - stroker->angle_out + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - } - } - - Exit: - return error; - } - - - static FT_Error - ft_stroker_process_corner( FT_Stroker stroker, - FT_Fixed line_length ) - { - FT_Error error = FT_Err_Ok; - FT_Angle turn; - FT_Int inside_side; - - - turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - - /* no specific corner processing is required if the turn is 0 */ - if ( turn == 0 ) - goto Exit; - - /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; - - /* process the inside side */ - error = ft_stroker_inside( stroker, inside_side, line_length ); - if ( error ) - goto Exit; - - /* process the outside side */ - error = ft_stroker_outside( stroker, 1 - inside_side, line_length ); - - Exit: - return error; - } - - - /* add two points to the left and right borders corresponding to the */ - /* start of the subpath */ - static FT_Error - ft_stroker_subpath_start( FT_Stroker stroker, - FT_Angle start_angle, - FT_Fixed line_length ) - { - FT_Vector delta; - FT_Vector point; - FT_Error error; - FT_StrokeBorder border; - - - FT_Vector_From_Polar( &delta, stroker->radius, - start_angle + FT_ANGLE_PI2 ); - - point.x = stroker->center.x + delta.x; - point.y = stroker->center.y + delta.y; - - border = stroker->borders; - error = ft_stroke_border_moveto( border, &point ); - if ( error ) - goto Exit; - - point.x = stroker->center.x - delta.x; - point.y = stroker->center.y - delta.y; - - border++; - error = ft_stroke_border_moveto( border, &point ); - - /* save angle, position, and line length for last join */ - /* (line_length is zero for curves) */ - stroker->subpath_angle = start_angle; - stroker->first_point = FALSE; - stroker->subpath_line_length = line_length; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_LineTo( FT_Stroker stroker, - FT_Vector* to ) - { - FT_Error error = FT_Err_Ok; - FT_StrokeBorder border; - FT_Vector delta; - FT_Angle angle; - FT_Int side; - FT_Fixed line_length; - - - delta.x = to->x - stroker->center.x; - delta.y = to->y - stroker->center.y; - - /* a zero-length lineto is a no-op; avoid creating a spurious corner */ - if ( delta.x == 0 && delta.y == 0 ) - goto Exit; - - /* compute length of line */ - line_length = FT_Vector_Length( &delta ); - - angle = FT_Atan2( delta.x, delta.y ); - FT_Vector_From_Polar( &delta, stroker->radius, angle + FT_ANGLE_PI2 ); - - /* process corner if necessary */ - if ( stroker->first_point ) - { - /* This is the first segment of a subpath. We need to */ - /* add a point to each border at their respective starting */ - /* point locations. */ - error = ft_stroker_subpath_start( stroker, angle, line_length ); - if ( error ) - goto Exit; - } - else - { - /* process the current corner */ - stroker->angle_out = angle; - error = ft_stroker_process_corner( stroker, line_length ); - if ( error ) - goto Exit; - } - - /* now add a line segment to both the `inside' and `outside' paths */ - for ( border = stroker->borders, side = 1; side >= 0; side--, border++ ) - { - FT_Vector point; - - - point.x = to->x + delta.x; - point.y = to->y + delta.y; - - /* the ends of lineto borders are movable */ - error = ft_stroke_border_lineto( border, &point, TRUE ); - if ( error ) - goto Exit; - - delta.x = -delta.x; - delta.y = -delta.y; - } - - stroker->angle_in = angle; - stroker->center = *to; - stroker->line_length = line_length; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_ConicTo( FT_Stroker stroker, - FT_Vector* control, - FT_Vector* to ) - { - FT_Error error = FT_Err_Ok; - FT_Vector bez_stack[34]; - FT_Vector* arc; - FT_Vector* limit = bez_stack + 30; - FT_Bool first_arc = TRUE; - - - /* if all control points are coincident, this is a no-op; */ - /* avoid creating a spurious corner */ - if ( FT_IS_SMALL( stroker->center.x - control->x ) && - FT_IS_SMALL( stroker->center.y - control->y ) && - FT_IS_SMALL( control->x - to->x ) && - FT_IS_SMALL( control->y - to->y ) ) - { - stroker->center = *to; - goto Exit; - } - - arc = bez_stack; - arc[0] = *to; - arc[1] = *control; - arc[2] = stroker->center; - - while ( arc >= bez_stack ) - { - FT_Angle angle_in, angle_out; - - - /* initialize with current direction */ - angle_in = angle_out = stroker->angle_in; - - if ( arc < limit && - !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) ) - { - if ( stroker->first_point ) - stroker->angle_in = angle_in; - - ft_conic_split( arc ); - arc += 2; - continue; - } - - if ( first_arc ) - { - first_arc = FALSE; - - /* process corner if necessary */ - if ( stroker->first_point ) - error = ft_stroker_subpath_start( stroker, angle_in, 0 ); - else - { - stroker->angle_out = angle_in; - error = ft_stroker_process_corner( stroker, 0 ); - } - } - else if ( ft_pos_abs( FT_Angle_Diff( stroker->angle_in, angle_in ) ) > - FT_SMALL_CONIC_THRESHOLD / 4 ) - { - /* if the deviation from one arc to the next is too great, */ - /* add a round corner */ - stroker->center = arc[2]; - stroker->angle_out = angle_in; - stroker->line_join = FT_STROKER_LINEJOIN_ROUND; - - error = ft_stroker_process_corner( stroker, 0 ); - - /* reinstate line join style */ - stroker->line_join = stroker->line_join_saved; - } - - if ( error ) - goto Exit; - - /* the arc's angle is small enough; we can add it directly to each */ - /* border */ - { - FT_Vector ctrl, end; - FT_Angle theta, phi, rotate, alpha0 = 0; - FT_Fixed length; - FT_StrokeBorder border; - FT_Int side; - - - theta = FT_Angle_Diff( angle_in, angle_out ) / 2; - phi = angle_in + theta; - length = FT_DivFix( stroker->radius, FT_Cos( theta ) ); - - /* compute direction of original arc */ - if ( stroker->handle_wide_strokes ) - alpha0 = FT_Atan2( arc[0].x - arc[2].x, arc[0].y - arc[2].y ); - - for ( border = stroker->borders, side = 0; - side <= 1; - side++, border++ ) - { - rotate = FT_SIDE_TO_ROTATE( side ); - - /* compute control point */ - FT_Vector_From_Polar( &ctrl, length, phi + rotate ); - ctrl.x += arc[1].x; - ctrl.y += arc[1].y; - - /* compute end point */ - FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); - end.x += arc[0].x; - end.y += arc[0].y; - - if ( stroker->handle_wide_strokes ) - { - FT_Vector start; - FT_Angle alpha1; - - - /* determine whether the border radius is greater than the */ - /* radius of curvature of the original arc */ - start = border->points[border->num_points - 1]; - - alpha1 = FT_Atan2( end.x - start.x, end.y - start.y ); - - /* is the direction of the border arc opposite to */ - /* that of the original arc? */ - if ( ft_pos_abs( FT_Angle_Diff( alpha0, alpha1 ) ) > - FT_ANGLE_PI / 2 ) - { - FT_Angle beta, gamma; - FT_Vector bvec, delta; - FT_Fixed blen, sinA, sinB, alen; - - - /* use the sine rule to find the intersection point */ - beta = FT_Atan2( arc[2].x - start.x, arc[2].y - start.y ); - gamma = FT_Atan2( arc[0].x - end.x, arc[0].y - end.y ); - - bvec.x = end.x - start.x; - bvec.y = end.y - start.y; - - blen = FT_Vector_Length( &bvec ); - - sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) ); - sinB = ft_pos_abs( FT_Sin( beta - gamma ) ); - - alen = FT_MulDiv( blen, sinA, sinB ); - - FT_Vector_From_Polar( &delta, alen, beta ); - delta.x += start.x; - delta.y += start.y; - - /* circumnavigate the negative sector backwards */ - border->movable = FALSE; - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - error = ft_stroke_border_lineto( border, &end, FALSE ); - if ( error ) - goto Exit; - error = ft_stroke_border_conicto( border, &ctrl, &start ); - if ( error ) - goto Exit; - /* and then move to the endpoint */ - error = ft_stroke_border_lineto( border, &end, FALSE ); - if ( error ) - goto Exit; - - continue; - } - - /* else fall through */ - } - - /* simply add an arc */ - error = ft_stroke_border_conicto( border, &ctrl, &end ); - if ( error ) - goto Exit; - } - } - - arc -= 2; - - stroker->angle_in = angle_out; - } - - stroker->center = *to; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_CubicTo( FT_Stroker stroker, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) - { - FT_Error error = FT_Err_Ok; - FT_Vector bez_stack[37]; - FT_Vector* arc; - FT_Vector* limit = bez_stack + 32; - FT_Bool first_arc = TRUE; - - - /* if all control points are coincident, this is a no-op; */ - /* avoid creating a spurious corner */ - if ( FT_IS_SMALL( stroker->center.x - control1->x ) && - FT_IS_SMALL( stroker->center.y - control1->y ) && - FT_IS_SMALL( control1->x - control2->x ) && - FT_IS_SMALL( control1->y - control2->y ) && - FT_IS_SMALL( control2->x - to->x ) && - FT_IS_SMALL( control2->y - to->y ) ) - { - stroker->center = *to; - goto Exit; - } - - arc = bez_stack; - arc[0] = *to; - arc[1] = *control2; - arc[2] = *control1; - arc[3] = stroker->center; - - while ( arc >= bez_stack ) - { - FT_Angle angle_in, angle_mid, angle_out; - - - /* initialize with current direction */ - angle_in = angle_out = angle_mid = stroker->angle_in; - - if ( arc < limit && - !ft_cubic_is_small_enough( arc, &angle_in, - &angle_mid, &angle_out ) ) - { - if ( stroker->first_point ) - stroker->angle_in = angle_in; - - ft_cubic_split( arc ); - arc += 3; - continue; - } - - if ( first_arc ) - { - first_arc = FALSE; - - /* process corner if necessary */ - if ( stroker->first_point ) - error = ft_stroker_subpath_start( stroker, angle_in, 0 ); - else - { - stroker->angle_out = angle_in; - error = ft_stroker_process_corner( stroker, 0 ); - } - } - else if ( ft_pos_abs( FT_Angle_Diff( stroker->angle_in, angle_in ) ) > - FT_SMALL_CUBIC_THRESHOLD / 4 ) - { - /* if the deviation from one arc to the next is too great, */ - /* add a round corner */ - stroker->center = arc[3]; - stroker->angle_out = angle_in; - stroker->line_join = FT_STROKER_LINEJOIN_ROUND; - - error = ft_stroker_process_corner( stroker, 0 ); - - /* reinstate line join style */ - stroker->line_join = stroker->line_join_saved; - } - - if ( error ) - goto Exit; - - /* the arc's angle is small enough; we can add it directly to each */ - /* border */ - { - FT_Vector ctrl1, ctrl2, end; - FT_Angle theta1, phi1, theta2, phi2, rotate, alpha0 = 0; - FT_Fixed length1, length2; - FT_StrokeBorder border; - FT_Int side; - - - theta1 = FT_Angle_Diff( angle_in, angle_mid ) / 2; - theta2 = FT_Angle_Diff( angle_mid, angle_out ) / 2; - phi1 = ft_angle_mean( angle_in, angle_mid ); - phi2 = ft_angle_mean( angle_mid, angle_out ); - length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); - length2 = FT_DivFix( stroker->radius, FT_Cos( theta2 ) ); - - /* compute direction of original arc */ - if ( stroker->handle_wide_strokes ) - alpha0 = FT_Atan2( arc[0].x - arc[3].x, arc[0].y - arc[3].y ); - - for ( border = stroker->borders, side = 0; - side <= 1; - side++, border++ ) - { - rotate = FT_SIDE_TO_ROTATE( side ); - - /* compute control points */ - FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate ); - ctrl1.x += arc[2].x; - ctrl1.y += arc[2].y; - - FT_Vector_From_Polar( &ctrl2, length2, phi2 + rotate ); - ctrl2.x += arc[1].x; - ctrl2.y += arc[1].y; - - /* compute end point */ - FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); - end.x += arc[0].x; - end.y += arc[0].y; - - if ( stroker->handle_wide_strokes ) - { - FT_Vector start; - FT_Angle alpha1; - - - /* determine whether the border radius is greater than the */ - /* radius of curvature of the original arc */ - start = border->points[border->num_points - 1]; - - alpha1 = FT_Atan2( end.x - start.x, end.y - start.y ); - - /* is the direction of the border arc opposite to */ - /* that of the original arc? */ - if ( ft_pos_abs( FT_Angle_Diff( alpha0, alpha1 ) ) > - FT_ANGLE_PI / 2 ) - { - FT_Angle beta, gamma; - FT_Vector bvec, delta; - FT_Fixed blen, sinA, sinB, alen; - - - /* use the sine rule to find the intersection point */ - beta = FT_Atan2( arc[3].x - start.x, arc[3].y - start.y ); - gamma = FT_Atan2( arc[0].x - end.x, arc[0].y - end.y ); - - bvec.x = end.x - start.x; - bvec.y = end.y - start.y; - - blen = FT_Vector_Length( &bvec ); - - sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) ); - sinB = ft_pos_abs( FT_Sin( beta - gamma ) ); - - alen = FT_MulDiv( blen, sinA, sinB ); - - FT_Vector_From_Polar( &delta, alen, beta ); - delta.x += start.x; - delta.y += start.y; - - /* circumnavigate the negative sector backwards */ - border->movable = FALSE; - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - error = ft_stroke_border_lineto( border, &end, FALSE ); - if ( error ) - goto Exit; - error = ft_stroke_border_cubicto( border, - &ctrl2, - &ctrl1, - &start ); - if ( error ) - goto Exit; - /* and then move to the endpoint */ - error = ft_stroke_border_lineto( border, &end, FALSE ); - if ( error ) - goto Exit; - - continue; - } - - /* else fall through */ - } - - /* simply add an arc */ - error = ft_stroke_border_cubicto( border, &ctrl1, &ctrl2, &end ); - if ( error ) - goto Exit; - } - } - - arc -= 3; - - stroker->angle_in = angle_out; - } - - stroker->center = *to; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_BeginSubPath( FT_Stroker stroker, - FT_Vector* to, - FT_Bool open ) - { - /* We cannot process the first point, because there is not enough */ - /* information regarding its corner/cap. The latter will be processed */ - /* in the `FT_Stroker_EndSubPath' routine. */ - /* */ - stroker->first_point = TRUE; - stroker->center = *to; - stroker->subpath_open = open; - - /* Determine if we need to check whether the border radius is greater */ - /* than the radius of curvature of a curve, to handle this case */ - /* specially. This is only required if bevel joins or butt caps may */ - /* be created, because round & miter joins and round & square caps */ - /* cover the negative sector created with wide strokes. */ - stroker->handle_wide_strokes = - FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_ROUND || - ( stroker->subpath_open && - stroker->line_cap == FT_STROKER_LINECAP_BUTT ) ); - - /* record the subpath start point for each border */ - stroker->subpath_start = *to; - - stroker->angle_in = 0; - - return FT_Err_Ok; - } - - - static FT_Error - ft_stroker_add_reverse_left( FT_Stroker stroker, - FT_Bool open ) - { - FT_StrokeBorder right = stroker->borders + 0; - FT_StrokeBorder left = stroker->borders + 1; - FT_Int new_points; - FT_Error error = FT_Err_Ok; - - - FT_ASSERT( left->start >= 0 ); - - new_points = left->num_points - left->start; - if ( new_points > 0 ) - { - error = ft_stroke_border_grow( right, (FT_UInt)new_points ); - if ( error ) - goto Exit; - - { - FT_Vector* dst_point = right->points + right->num_points; - FT_Byte* dst_tag = right->tags + right->num_points; - FT_Vector* src_point = left->points + left->num_points - 1; - FT_Byte* src_tag = left->tags + left->num_points - 1; - - - while ( src_point >= left->points + left->start ) - { - *dst_point = *src_point; - *dst_tag = *src_tag; - - if ( open ) - dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END; - else - { - FT_Byte ttag = - (FT_Byte)( dst_tag[0] & FT_STROKE_TAG_BEGIN_END ); - - - /* switch begin/end tags if necessary */ - if ( ttag == FT_STROKE_TAG_BEGIN || - ttag == FT_STROKE_TAG_END ) - dst_tag[0] ^= FT_STROKE_TAG_BEGIN_END; - } - - src_point--; - src_tag--; - dst_point++; - dst_tag++; - } - } - - left->num_points = left->start; - right->num_points += new_points; - - right->movable = FALSE; - left->movable = FALSE; - } - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - /* there's a lot of magic in this function! */ - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_EndSubPath( FT_Stroker stroker ) - { - FT_Error error = FT_Err_Ok; - - - if ( stroker->subpath_open ) - { - FT_StrokeBorder right = stroker->borders; - - - /* All right, this is an opened path, we need to add a cap between */ - /* right & left, add the reverse of left, then add a final cap */ - /* between left & right. */ - error = ft_stroker_cap( stroker, stroker->angle_in, 0 ); - if ( error ) - goto Exit; - - /* add reversed points from `left' to `right' */ - error = ft_stroker_add_reverse_left( stroker, TRUE ); - if ( error ) - goto Exit; - - /* now add the final cap */ - stroker->center = stroker->subpath_start; - error = ft_stroker_cap( stroker, - stroker->subpath_angle + FT_ANGLE_PI, 0 ); - if ( error ) - goto Exit; - - /* Now end the right subpath accordingly. The left one is */ - /* rewind and doesn't need further processing. */ - ft_stroke_border_close( right, FALSE ); - } - else - { - FT_Angle turn; - FT_Int inside_side; - - - /* close the path if needed */ - if ( stroker->center.x != stroker->subpath_start.x || - stroker->center.y != stroker->subpath_start.y ) - { - error = FT_Stroker_LineTo( stroker, &stroker->subpath_start ); - if ( error ) - goto Exit; - } - - /* process the corner */ - stroker->angle_out = stroker->subpath_angle; - turn = FT_Angle_Diff( stroker->angle_in, - stroker->angle_out ); - - /* no specific corner processing is required if the turn is 0 */ - if ( turn != 0 ) - { - /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; - - error = ft_stroker_inside( stroker, - inside_side, - stroker->subpath_line_length ); - if ( error ) - goto Exit; - - /* process the outside side */ - error = ft_stroker_outside( stroker, - 1 - inside_side, - stroker->subpath_line_length ); - if ( error ) - goto Exit; - } - - /* then end our two subpaths */ - ft_stroke_border_close( stroker->borders + 0, FALSE ); - ft_stroke_border_close( stroker->borders + 1, TRUE ); - } - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_GetBorderCounts( FT_Stroker stroker, - FT_StrokerBorder border, - FT_UInt *anum_points, - FT_UInt *anum_contours ) - { - FT_UInt num_points = 0, num_contours = 0; - FT_Error error; - - - if ( !stroker || border > 1 ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - error = ft_stroke_border_get_counts( stroker->borders + border, - &num_points, &num_contours ); - Exit: - if ( anum_points ) - *anum_points = num_points; - - if ( anum_contours ) - *anum_contours = num_contours; - - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_GetCounts( FT_Stroker stroker, - FT_UInt *anum_points, - FT_UInt *anum_contours ) - { - FT_UInt count1, count2, num_points = 0; - FT_UInt count3, count4, num_contours = 0; - FT_Error error; - - - error = ft_stroke_border_get_counts( stroker->borders + 0, - &count1, &count2 ); - if ( error ) - goto Exit; - - error = ft_stroke_border_get_counts( stroker->borders + 1, - &count3, &count4 ); - if ( error ) - goto Exit; - - num_points = count1 + count3; - num_contours = count2 + count4; - - Exit: - *anum_points = num_points; - *anum_contours = num_contours; - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_ExportBorder( FT_Stroker stroker, - FT_StrokerBorder border, - FT_Outline* outline ) - { - if ( border == FT_STROKER_BORDER_LEFT || - border == FT_STROKER_BORDER_RIGHT ) - { - FT_StrokeBorder sborder = & stroker->borders[border]; - - - if ( sborder->valid ) - ft_stroke_border_export( sborder, outline ); - } - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_Export( FT_Stroker stroker, - FT_Outline* outline ) - { - FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_LEFT, outline ); - FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_RIGHT, outline ); - } - - - /* documentation is in ftstroke.h */ - - /* - * The following is very similar to FT_Outline_Decompose, except - * that we do support opened paths, and do not scale the outline. - */ - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_ParseOutline( FT_Stroker stroker, - FT_Outline* outline, - FT_Bool opened ) - { - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - FT_Error error; - - FT_Int n; /* index of contour in outline */ - FT_UInt first; /* index of first point in contour */ - FT_Int tag; /* current point's state */ - - - if ( !outline || !stroker ) - return FT_THROW( Invalid_Argument ); - - FT_Stroker_Rewind( stroker ); - - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - FT_UInt last; /* index of last point in contour */ - - - last = outline->contours[n]; - limit = outline->points + last; - - /* skip empty points; we don't stroke these */ - if ( last <= first ) - { - first = last + 1; - continue; - } - - v_start = outline->points[first]; - v_last = outline->points[last]; - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_CURVE_TAG_CONIC ) - { - /* First point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - } - point--; - tags--; - } - - error = FT_Stroker_BeginSubPath( stroker, &v_start, opened ); - if ( error ) - goto Exit; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - switch ( tag ) - { - case FT_CURVE_TAG_ON: /* emit a single line_to */ - { - FT_Vector vec; - - - vec.x = point->x; - vec.y = point->y; - - error = FT_Stroker_LineTo( stroker, &vec ); - if ( error ) - goto Exit; - continue; - } - - case FT_CURVE_TAG_CONIC: /* consume conic arcs */ - v_control.x = point->x; - v_control.y = point->y; - - Do_Conic: - if ( point < limit ) - { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec = point[0]; - - if ( tag == FT_CURVE_TAG_ON ) - { - error = FT_Stroker_ConicTo( stroker, &v_control, &vec ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_CURVE_TAG_CONIC ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle ); - if ( error ) - goto Exit; - - v_control = vec; - goto Do_Conic; - } - - error = FT_Stroker_ConicTo( stroker, &v_control, &v_start ); - goto Close; - - default: /* FT_CURVE_TAG_CUBIC */ - { - FT_Vector vec1, vec2; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1 = point[-2]; - vec2 = point[-1]; - - if ( point <= limit ) - { - FT_Vector vec; - - - vec = point[0]; - - error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec ); - if ( error ) - goto Exit; - continue; - } - - error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start ); - goto Close; - } - } - } - - Close: - if ( error ) - goto Exit; - - /* don't try to end the path if no segments have been generated */ - if ( !stroker->first_point ) - { - error = FT_Stroker_EndSubPath( stroker ); - if ( error ) - goto Exit; - } - - first = last + 1; - } - - return FT_Err_Ok; - - Exit: - return error; - - Invalid_Outline: - return FT_THROW( Invalid_Outline ); - } - - - /* declare an extern to access `ft_outline_glyph_class' globally */ - /* allocated in `ftglyph.c', and use the FT_OUTLINE_GLYPH_CLASS_GET */ - /* macro to access it when FT_CONFIG_OPTION_PIC is defined */ -#ifndef FT_CONFIG_OPTION_PIC - extern const FT_Glyph_Class ft_outline_glyph_class; -#endif -#include "basepic.h" - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_Stroke( FT_Glyph *pglyph, - FT_Stroker stroker, - FT_Bool destroy ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Glyph glyph = NULL; - FT_Library library = stroker->library; - - FT_UNUSED( library ); - - - if ( pglyph == NULL ) - goto Exit; - - glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) - goto Exit; - - { - FT_Glyph copy; - - - error = FT_Glyph_Copy( glyph, © ); - if ( error ) - goto Exit; - - glyph = copy; - } - - { - FT_OutlineGlyph oglyph = (FT_OutlineGlyph)glyph; - FT_Outline* outline = &oglyph->outline; - FT_UInt num_points, num_contours; - - - error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); - if ( error ) - goto Fail; - - (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); - - FT_Outline_Done( glyph->library, outline ); - - error = FT_Outline_New( glyph->library, - num_points, num_contours, outline ); - if ( error ) - goto Fail; - - outline->n_points = 0; - outline->n_contours = 0; - - FT_Stroker_Export( stroker, outline ); - } - - if ( destroy ) - FT_Done_Glyph( *pglyph ); - - *pglyph = glyph; - goto Exit; - - Fail: - FT_Done_Glyph( glyph ); - glyph = NULL; - - if ( !destroy ) - *pglyph = NULL; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_StrokeBorder( FT_Glyph *pglyph, - FT_Stroker stroker, - FT_Bool inside, - FT_Bool destroy ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Glyph glyph = NULL; - FT_Library library = stroker->library; - - FT_UNUSED( library ); - - - if ( pglyph == NULL ) - goto Exit; - - glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) - goto Exit; - - { - FT_Glyph copy; - - - error = FT_Glyph_Copy( glyph, © ); - if ( error ) - goto Exit; - - glyph = copy; - } - - { - FT_OutlineGlyph oglyph = (FT_OutlineGlyph)glyph; - FT_StrokerBorder border; - FT_Outline* outline = &oglyph->outline; - FT_UInt num_points, num_contours; - - - border = FT_Outline_GetOutsideBorder( outline ); - if ( inside ) - { - if ( border == FT_STROKER_BORDER_LEFT ) - border = FT_STROKER_BORDER_RIGHT; - else - border = FT_STROKER_BORDER_LEFT; - } - - error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); - if ( error ) - goto Fail; - - (void)FT_Stroker_GetBorderCounts( stroker, border, - &num_points, &num_contours ); - - FT_Outline_Done( glyph->library, outline ); - - error = FT_Outline_New( glyph->library, - num_points, - num_contours, - outline ); - if ( error ) - goto Fail; - - outline->n_points = 0; - outline->n_contours = 0; - - FT_Stroker_ExportBorder( stroker, border, outline ); - } - - if ( destroy ) - FT_Done_Glyph( *pglyph ); - - *pglyph = glyph; - goto Exit; - - Fail: - FT_Done_Glyph( glyph ); - glyph = NULL; - - if ( !destroy ) - *pglyph = NULL; - - Exit: - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftsynth.c b/drivers/freetype/freetype/src/base/ftsynth.c deleted file mode 100644 index 241d37f426..0000000000 --- a/drivers/freetype/freetype/src/base/ftsynth.c +++ /dev/null @@ -1,153 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsynth.c */ -/* */ -/* FreeType synthesizing code for emboldening and slanting (body). */ -/* */ -/* Copyright 2000-2006, 2010, 2012 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_SYNTHESIS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_OUTLINE_H -#include FT_BITMAP_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_synth - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** EXPERIMENTAL OBLIQUING SUPPORT ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /* documentation is in ftsynth.h */ - - FT_EXPORT_DEF( void ) - FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) - { - FT_Matrix transform; - FT_Outline* outline = &slot->outline; - - - /* only oblique outline glyphs */ - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) - return; - - /* we don't touch the advance width */ - - /* For italic, simply apply a shear transform, with an angle */ - /* of about 12 degrees. */ - - transform.xx = 0x10000L; - transform.yx = 0x00000L; - - transform.xy = 0x0366AL; - transform.yy = 0x10000L; - - FT_Outline_Transform( outline, &transform ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** EXPERIMENTAL EMBOLDENING SUPPORT ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* documentation is in ftsynth.h */ - - FT_EXPORT_DEF( void ) - FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) - { - FT_Library library = slot->library; - FT_Face face = slot->face; - FT_Error error; - FT_Pos xstr, ystr; - - - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && - slot->format != FT_GLYPH_FORMAT_BITMAP ) - return; - - /* some reasonable strength */ - xstr = FT_MulFix( face->units_per_EM, - face->size->metrics.y_scale ) / 24; - ystr = xstr; - - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* ignore error */ - (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); - } - else /* slot->format == FT_GLYPH_FORMAT_BITMAP */ - { - /* round to full pixels */ - xstr &= ~63; - if ( xstr == 0 ) - xstr = 1 << 6; - ystr &= ~63; - - /* - * XXX: overflow check for 16-bit system, for compatibility - * with FT_GlyphSlot_Embolden() since freetype-2.1.10. - * unfortunately, this function return no informations - * about the cause of error. - */ - if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN ) - { - FT_TRACE1(( "FT_GlyphSlot_Embolden:" )); - FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr )); - return; - } - error = FT_GlyphSlot_Own_Bitmap( slot ); - if ( error ) - return; - - error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr ); - if ( error ) - return; - } - - if ( slot->advance.x ) - slot->advance.x += xstr; - - if ( slot->advance.y ) - slot->advance.y += ystr; - - slot->metrics.width += xstr; - slot->metrics.height += ystr; - slot->metrics.horiAdvance += xstr; - slot->metrics.vertAdvance += ystr; - - /* XXX: 16-bit overflow case must be excluded before here */ - if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - slot->bitmap_top += (FT_Int)( ystr >> 6 ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftsystem.c b/drivers/freetype/freetype/src/base/ftsystem.c deleted file mode 100644 index 2c6ddac10c..0000000000 --- a/drivers/freetype/freetype/src/base/ftsystem.c +++ /dev/null @@ -1,320 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsystem.c */ -/* */ -/* ANSI-specific FreeType low-level system interface (body). */ -/* */ -/* Copyright 1996-2002, 2006, 2008-2011, 2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file contains the default interface used by FreeType to access */ - /* low-level, i.e. memory management, i/o access as well as thread */ - /* synchronisation. It can be replaced by user-specific routines if */ - /* necessary. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_SYSTEM_H -#include FT_ERRORS_H -#include FT_TYPES_H - - - /*************************************************************************/ - /* */ - /* MEMORY MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* It is not necessary to do any error checking for the */ - /* allocation-related functions. This will be done by the higher level */ - /* routines like ft_mem_alloc() or ft_mem_realloc(). */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_alloc */ - /* */ - /* <Description> */ - /* The memory allocation function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* size :: The requested size in bytes. */ - /* */ - /* <Return> */ - /* The address of newly allocated block. */ - /* */ - FT_CALLBACK_DEF( void* ) - ft_alloc( FT_Memory memory, - long size ) - { - FT_UNUSED( memory ); - - return ft_smalloc( size ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_realloc */ - /* */ - /* <Description> */ - /* The memory reallocation function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* cur_size :: The current size of the allocated memory block. */ - /* */ - /* new_size :: The newly requested size in bytes. */ - /* */ - /* block :: The current address of the block in memory. */ - /* */ - /* <Return> */ - /* The address of the reallocated memory block. */ - /* */ - FT_CALLBACK_DEF( void* ) - ft_realloc( FT_Memory memory, - long cur_size, - long new_size, - void* block ) - { - FT_UNUSED( memory ); - FT_UNUSED( cur_size ); - - return ft_srealloc( block, new_size ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_free */ - /* */ - /* <Description> */ - /* The memory release function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* block :: The address of block in memory to be freed. */ - /* */ - FT_CALLBACK_DEF( void ) - ft_free( FT_Memory memory, - void* block ) - { - FT_UNUSED( memory ); - - ft_sfree( block ); - } - - - /*************************************************************************/ - /* */ - /* RESOURCE MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - -#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT - - /*************************************************************************/ - /* */ - /* 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_io - - /* We use the macro STREAM_FILE for convenience to extract the */ - /* system-specific stream handle from a given FreeType stream object */ -#define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_ansi_stream_close */ - /* */ - /* <Description> */ - /* The function to close a stream. */ - /* */ - /* <Input> */ - /* stream :: A pointer to the stream object. */ - /* */ - FT_CALLBACK_DEF( void ) - ft_ansi_stream_close( FT_Stream stream ) - { - ft_fclose( STREAM_FILE( stream ) ); - - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_ansi_stream_io */ - /* */ - /* <Description> */ - /* The function to open a stream. */ - /* */ - /* <Input> */ - /* stream :: A pointer to the stream object. */ - /* */ - /* offset :: The position in the data stream to start reading. */ - /* */ - /* buffer :: The address of buffer to store the read data. */ - /* */ - /* count :: The number of bytes to read from the stream. */ - /* */ - /* <Return> */ - /* The number of bytes actually read. If `count' is zero (this is, */ - /* the function is used for seeking), a non-zero return value */ - /* indicates an error. */ - /* */ - FT_CALLBACK_DEF( unsigned long ) - ft_ansi_stream_io( FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count ) - { - FT_FILE* file; - - - if ( !count && offset > stream->size ) - return 1; - - file = STREAM_FILE( stream ); - - if ( stream->pos != offset ) - ft_fseek( file, offset, SEEK_SET ); - - return (unsigned long)ft_fread( buffer, 1, count, file ); - } - - - /* documentation is in ftstream.h */ - - FT_BASE_DEF( FT_Error ) - FT_Stream_Open( FT_Stream stream, - const char* filepathname ) - { - FT_FILE* file; - - - if ( !stream ) - return FT_THROW( Invalid_Stream_Handle ); - - stream->descriptor.pointer = NULL; - stream->pathname.pointer = (char*)filepathname; - stream->base = 0; - stream->pos = 0; - stream->read = NULL; - stream->close = NULL; - - file = ft_fopen( filepathname, "rb" ); - if ( !file ) - { - FT_ERROR(( "FT_Stream_Open:" - " could not open `%s'\n", filepathname )); - - return FT_THROW( Cannot_Open_Resource ); - } - - ft_fseek( file, 0, SEEK_END ); - stream->size = ft_ftell( file ); - if ( !stream->size ) - { - FT_ERROR(( "FT_Stream_Open:" )); - FT_ERROR(( " opened `%s' but zero-sized\n", filepathname )); - ft_fclose( file ); - return FT_THROW( Cannot_Open_Stream ); - } - ft_fseek( file, 0, SEEK_SET ); - - stream->descriptor.pointer = file; - stream->read = ft_ansi_stream_io; - stream->close = ft_ansi_stream_close; - - FT_TRACE1(( "FT_Stream_Open:" )); - FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", - filepathname, stream->size )); - - return FT_Err_Ok; - } - -#endif /* !FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - -#ifdef FT_DEBUG_MEMORY - - extern FT_Int - ft_mem_debug_init( FT_Memory memory ); - - extern void - ft_mem_debug_done( FT_Memory memory ); - -#endif - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( FT_Memory ) - FT_New_Memory( void ) - { - FT_Memory memory; - - - memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) ); - if ( memory ) - { - memory->user = 0; - memory->alloc = ft_alloc; - memory->realloc = ft_realloc; - memory->free = ft_free; -#ifdef FT_DEBUG_MEMORY - ft_mem_debug_init( memory ); -#endif - } - - return memory; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( void ) - FT_Done_Memory( FT_Memory memory ) - { -#ifdef FT_DEBUG_MEMORY - ft_mem_debug_done( memory ); -#endif - ft_sfree( memory ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/fttrigon.c b/drivers/freetype/freetype/src/base/fttrigon.c deleted file mode 100644 index 4ffdcb77f1..0000000000 --- a/drivers/freetype/freetype/src/base/fttrigon.c +++ /dev/null @@ -1,492 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttrigon.c */ -/* */ -/* FreeType trigonometric functions (body). */ -/* */ -/* Copyright 2001-2005, 2012-2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This is a fixed-point CORDIC implementation of trigonometric */ - /* functions as well as transformations between Cartesian and polar */ - /* coordinates. The angles are represented as 16.16 fixed-point values */ - /* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */ - /* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */ - /* discrete Cartesian grid can have the same or better angular */ - /* resolution. Therefore, to maintain this precision, some functions */ - /* require an interim upscaling of the vectors, whereas others operate */ - /* with 24-bit long vectors directly. */ - /* */ - /*************************************************************************/ - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_CALC_H -#include FT_TRIGONOMETRY_H - - - /* the Cordic shrink factor 0.858785336480436 * 2^32 */ -#define FT_TRIG_SCALE 0xDBD95B16UL - - /* the highest bit in overflow-safe vector components, */ - /* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */ -#define FT_TRIG_SAFE_MSB 29 - - /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ -#define FT_TRIG_MAX_ITERS 23 - - static const FT_Fixed - ft_trig_arctan_table[] = - { - 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, - 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, - 57L, 29L, 14L, 7L, 4L, 2L, 1L - }; - - -#ifdef FT_LONG64 - - /* multiply a given value by the CORDIC shrink factor */ - static FT_Fixed - ft_trig_downscale( FT_Fixed val ) - { - FT_Fixed s; - FT_Int64 v; - - - s = val; - val = FT_ABS( val ); - - v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; - val = (FT_Fixed)( v >> 32 ); - - return ( s >= 0 ) ? val : -val; - } - -#else /* !FT_LONG64 */ - - /* multiply a given value by the CORDIC shrink factor */ - static FT_Fixed - ft_trig_downscale( FT_Fixed val ) - { - FT_Fixed s; - FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; - - - s = val; - val = FT_ABS( val ); - - v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)( val & 0xFFFFL ); - - k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ - k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL ); /* constant */ - - hi = k1 * v1; - lo1 = k1 * v2 + k2 * v1; /* can't overflow */ - - lo2 = ( k2 * v2 ) >> 16; - lo3 = FT_MAX( lo1, lo2 ); - lo1 += lo2; - - hi += lo1 >> 16; - if ( lo1 < lo3 ) - hi += (FT_UInt32)0x10000UL; - - val = (FT_Fixed)hi; - - return ( s >= 0 ) ? val : -val; - } - -#endif /* !FT_LONG64 */ - - - static FT_Int - ft_trig_prenorm( FT_Vector* vec ) - { - FT_Pos x, y; - FT_Int shift; - - - x = vec->x; - y = vec->y; - - shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) ); - - if ( shift <= FT_TRIG_SAFE_MSB ) - { - shift = FT_TRIG_SAFE_MSB - shift; - vec->x = (FT_Pos)( (FT_ULong)x << shift ); - vec->y = (FT_Pos)( (FT_ULong)y << shift ); - } - else - { - shift -= FT_TRIG_SAFE_MSB; - vec->x = x >> shift; - vec->y = y >> shift; - shift = -shift; - } - - return shift; - } - - - static void - ft_trig_pseudo_rotate( FT_Vector* vec, - FT_Angle theta ) - { - FT_Int i; - FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; - - - x = vec->x; - y = vec->y; - - /* Rotate inside [-PI/4,PI/4] sector */ - while ( theta < -FT_ANGLE_PI4 ) - { - xtemp = y; - y = -x; - x = xtemp; - theta += FT_ANGLE_PI2; - } - - while ( theta > FT_ANGLE_PI4 ) - { - xtemp = -y; - y = x; - x = xtemp; - theta -= FT_ANGLE_PI2; - } - - arctanptr = ft_trig_arctan_table; - - /* Pseudorotations, with right shifts */ - for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ ) - { - if ( theta < 0 ) - { - xtemp = x + ( ( y + b ) >> i ); - y = y - ( ( x + b ) >> i ); - x = xtemp; - theta += *arctanptr++; - } - else - { - xtemp = x - ( ( y + b ) >> i ); - y = y + ( ( x + b ) >> i ); - x = xtemp; - theta -= *arctanptr++; - } - } - - vec->x = x; - vec->y = y; - } - - - static void - ft_trig_pseudo_polarize( FT_Vector* vec ) - { - FT_Angle theta; - FT_Int i; - FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; - - - x = vec->x; - y = vec->y; - - /* Get the vector into [-PI/4,PI/4] sector */ - if ( y > x ) - { - if ( y > -x ) - { - theta = FT_ANGLE_PI2; - xtemp = y; - y = -x; - x = xtemp; - } - else - { - theta = y > 0 ? FT_ANGLE_PI : -FT_ANGLE_PI; - x = -x; - y = -y; - } - } - else - { - if ( y < -x ) - { - theta = -FT_ANGLE_PI2; - xtemp = -y; - y = x; - x = xtemp; - } - else - { - theta = 0; - } - } - - arctanptr = ft_trig_arctan_table; - - /* Pseudorotations, with right shifts */ - for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ ) - { - if ( y > 0 ) - { - xtemp = x + ( ( y + b ) >> i ); - y = y - ( ( x + b ) >> i ); - x = xtemp; - theta += *arctanptr++; - } - else - { - xtemp = x - ( ( y + b ) >> i ); - y = y + ( ( x + b ) >> i ); - x = xtemp; - theta -= *arctanptr++; - } - } - - /* round theta */ - if ( theta >= 0 ) - theta = FT_PAD_ROUND( theta, 32 ); - else - theta = -FT_PAD_ROUND( -theta, 32 ); - - vec->x = x; - vec->y = theta; - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_Cos( FT_Angle angle ) - { - FT_Vector v; - - - v.x = FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); - - return ( v.x + 0x80L ) >> 8; - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_Sin( FT_Angle angle ) - { - return FT_Cos( FT_ANGLE_PI2 - angle ); - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_Tan( FT_Angle angle ) - { - FT_Vector v; - - - v.x = FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); - - return FT_DivFix( v.y, v.x ); - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Angle ) - FT_Atan2( FT_Fixed dx, - FT_Fixed dy ) - { - FT_Vector v; - - - if ( dx == 0 && dy == 0 ) - return 0; - - v.x = dx; - v.y = dy; - ft_trig_prenorm( &v ); - ft_trig_pseudo_polarize( &v ); - - return v.y; - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_Unit( FT_Vector* vec, - FT_Angle angle ) - { - vec->x = FT_TRIG_SCALE >> 8; - vec->y = 0; - ft_trig_pseudo_rotate( vec, angle ); - vec->x = ( vec->x + 0x80L ) >> 8; - vec->y = ( vec->y + 0x80L ) >> 8; - } - - - /* these macros return 0 for positive numbers, - and -1 for negative ones */ -#define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) ) -#define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) ) -#define FT_SIGN_INT32( x ) ( (x) >> 31 ) -#define FT_SIGN_INT16( x ) ( (x) >> 15 ) - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_Rotate( FT_Vector* vec, - FT_Angle angle ) - { - FT_Int shift; - FT_Vector v; - - - v.x = vec->x; - v.y = vec->y; - - if ( angle && ( v.x != 0 || v.y != 0 ) ) - { - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_rotate( &v, angle ); - v.x = ft_trig_downscale( v.x ); - v.y = ft_trig_downscale( v.y ); - - if ( shift > 0 ) - { - FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); - - - vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; - vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; - } - else - { - shift = -shift; - vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); - vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); - } - } - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_Vector_Length( FT_Vector* vec ) - { - FT_Int shift; - FT_Vector v; - - - v = *vec; - - /* handle trivial cases */ - if ( v.x == 0 ) - { - return FT_ABS( v.y ); - } - else if ( v.y == 0 ) - { - return FT_ABS( v.x ); - } - - /* general case */ - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_polarize( &v ); - - v.x = ft_trig_downscale( v.x ); - - if ( shift > 0 ) - return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift; - - return (FT_Fixed)( (FT_UInt32)v.x << -shift ); - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_Polarize( FT_Vector* vec, - FT_Fixed *length, - FT_Angle *angle ) - { - FT_Int shift; - FT_Vector v; - - - v = *vec; - - if ( v.x == 0 && v.y == 0 ) - return; - - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_polarize( &v ); - - v.x = ft_trig_downscale( v.x ); - - *length = ( shift >= 0 ) ? ( v.x >> shift ) - : (FT_Fixed)( (FT_UInt32)v.x << -shift ); - *angle = v.y; - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_From_Polar( FT_Vector* vec, - FT_Fixed length, - FT_Angle angle ) - { - vec->x = length; - vec->y = 0; - - FT_Vector_Rotate( vec, angle ); - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Angle ) - FT_Angle_Diff( FT_Angle angle1, - FT_Angle angle2 ) - { - FT_Angle delta = angle2 - angle1; - - - delta %= FT_ANGLE_2PI; - if ( delta < 0 ) - delta += FT_ANGLE_2PI; - - if ( delta > FT_ANGLE_PI ) - delta -= FT_ANGLE_2PI; - - return delta; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/fttype1.c b/drivers/freetype/freetype/src/base/fttype1.c deleted file mode 100644 index c1f9931dbb..0000000000 --- a/drivers/freetype/freetype/src/base/fttype1.c +++ /dev/null @@ -1,120 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttype1.c */ -/* */ -/* FreeType utility file for PS names support (body). */ -/* */ -/* Copyright 2002-2004, 2011 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_SERVICE_H -#include FT_SERVICE_POSTSCRIPT_INFO_H - - - /* documentation is in t1tables.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_PS_Font_Info( FT_Face face, - PS_FontInfoRec* afont_info ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - - - if ( face ) - { - FT_Service_PsInfo service = NULL; - - - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - - if ( service && service->ps_get_font_info ) - error = service->ps_get_font_info( face, afont_info ); - } - - return error; - } - - - /* documentation is in t1tables.h */ - - FT_EXPORT_DEF( FT_Int ) - FT_Has_PS_Glyph_Names( FT_Face face ) - { - FT_Int result = 0; - FT_Service_PsInfo service = NULL; - - - if ( face ) - { - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - - if ( service && service->ps_has_glyph_names ) - result = service->ps_has_glyph_names( face ); - } - - return result; - } - - - /* documentation is in t1tables.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_PS_Font_Private( FT_Face face, - PS_PrivateRec* afont_private ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - - - if ( face ) - { - FT_Service_PsInfo service = NULL; - - - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - - if ( service && service->ps_get_font_private ) - error = service->ps_get_font_private( face, afont_private ); - } - - return error; - } - - - /* documentation is in t1tables.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_Get_PS_Font_Value( FT_Face face, - PS_Dict_Keys key, - FT_UInt idx, - void *value, - FT_Long value_len ) - { - FT_Int result = 0; - FT_Service_PsInfo service = NULL; - - - if ( face ) - { - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - - if ( service && service->ps_get_font_value ) - result = service->ps_get_font_value( face, key, idx, - value, value_len ); - } - - return result; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftutil.c b/drivers/freetype/freetype/src/base/ftutil.c deleted file mode 100644 index 879d027529..0000000000 --- a/drivers/freetype/freetype/src/base/ftutil.c +++ /dev/null @@ -1,436 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftutil.c */ -/* */ -/* FreeType utility file for memory and list management (body). */ -/* */ -/* Copyright 2002, 2004-2007, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_MEMORY_H -#include FT_INTERNAL_OBJECTS_H -#include FT_LIST_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_memory - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** *****/ - /***** M E M O R Y M A N A G E M E N T *****/ - /***** *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_alloc( FT_Memory memory, - FT_Long size, - FT_Error *p_error ) - { - FT_Error error; - FT_Pointer block = ft_mem_qalloc( memory, size, &error ); - - if ( !error && size > 0 ) - FT_MEM_ZERO( block, size ); - - *p_error = error; - return block; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_qalloc( FT_Memory memory, - FT_Long size, - FT_Error *p_error ) - { - FT_Error error = FT_Err_Ok; - FT_Pointer block = NULL; - - - if ( size > 0 ) - { - block = memory->alloc( memory, size ); - if ( block == NULL ) - error = FT_THROW( Out_Of_Memory ); - } - else if ( size < 0 ) - { - /* may help catch/prevent security issues */ - error = FT_THROW( Invalid_Argument ); - } - - *p_error = error; - return block; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_realloc( FT_Memory memory, - FT_Long item_size, - FT_Long cur_count, - FT_Long new_count, - void* block, - FT_Error *p_error ) - { - FT_Error error = FT_Err_Ok; - - - block = ft_mem_qrealloc( memory, item_size, - cur_count, new_count, block, &error ); - if ( !error && new_count > cur_count ) - FT_MEM_ZERO( (char*)block + cur_count * item_size, - ( new_count - cur_count ) * item_size ); - - *p_error = error; - return block; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_qrealloc( FT_Memory memory, - FT_Long item_size, - FT_Long cur_count, - FT_Long new_count, - void* block, - FT_Error *p_error ) - { - FT_Error error = FT_Err_Ok; - - - /* 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_THROW( Invalid_Argument ); - } - else if ( new_count == 0 || item_size == 0 ) - { - ft_mem_free( memory, block ); - block = NULL; - } - else if ( new_count > FT_INT_MAX/item_size ) - { - error = FT_THROW( Array_Too_Large ); - } - else if ( cur_count == 0 ) - { - FT_ASSERT( block == NULL ); - - block = ft_mem_alloc( memory, new_count*item_size, &error ); - } - else - { - FT_Pointer block2; - FT_Long cur_size = cur_count*item_size; - FT_Long new_size = new_count*item_size; - - - block2 = memory->realloc( memory, cur_size, new_size, block ); - if ( block2 == NULL ) - error = FT_THROW( Out_Of_Memory ); - else - block = block2; - } - - *p_error = error; - return block; - } - - - FT_BASE_DEF( void ) - ft_mem_free( FT_Memory memory, - const void *P ) - { - if ( P ) - memory->free( memory, (void*)P ); - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_dup( FT_Memory memory, - const void* address, - FT_ULong size, - FT_Error *p_error ) - { - FT_Error error; - FT_Pointer p = ft_mem_qalloc( memory, size, &error ); - - - if ( !error && address ) - ft_memcpy( p, address, size ); - - *p_error = error; - return p; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_strdup( FT_Memory memory, - const char* str, - FT_Error *p_error ) - { - FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1 - : 0; - - - return ft_mem_dup( memory, str, len, p_error ); - } - - - FT_BASE_DEF( FT_Int ) - ft_mem_strcpyn( char* dst, - const char* src, - FT_ULong size ) - { - while ( size > 1 && *src != 0 ) - { - *dst++ = *src++; - size--; - } - - *dst = 0; /* always zero-terminate */ - - return *src != 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** *****/ - /***** D O U B L Y L I N K E D L I S T S *****/ - /***** *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - -#undef FT_COMPONENT -#define FT_COMPONENT trace_list - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( FT_ListNode ) - FT_List_Find( FT_List list, - void* data ) - { - FT_ListNode cur; - - - cur = list->head; - while ( cur ) - { - if ( cur->data == data ) - return cur; - - cur = cur->next; - } - - return (FT_ListNode)0; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Add( FT_List list, - FT_ListNode node ) - { - FT_ListNode before = list->tail; - - - node->next = 0; - node->prev = before; - - if ( before ) - before->next = node; - else - list->head = node; - - list->tail = node; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Insert( FT_List list, - FT_ListNode node ) - { - FT_ListNode after = list->head; - - - node->next = after; - node->prev = 0; - - if ( !after ) - list->tail = node; - else - after->prev = node; - - list->head = node; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Remove( FT_List list, - FT_ListNode node ) - { - FT_ListNode before, after; - - - before = node->prev; - after = node->next; - - if ( before ) - before->next = after; - else - list->head = after; - - if ( after ) - after->prev = before; - else - list->tail = before; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Up( FT_List list, - FT_ListNode node ) - { - FT_ListNode before, after; - - - before = node->prev; - after = node->next; - - /* check whether we are already on top of the list */ - if ( !before ) - return; - - before->next = after; - - if ( after ) - after->prev = before; - else - list->tail = before; - - node->prev = 0; - node->next = list->head; - list->head->prev = node; - list->head = node; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ) - { - FT_ListNode cur = list->head; - FT_Error error = FT_Err_Ok; - - - while ( cur ) - { - FT_ListNode next = cur->next; - - - error = iterator( cur, user ); - if ( error ) - break; - - cur = next; - } - - return error; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Finalize( FT_List list, - FT_List_Destructor destroy, - FT_Memory memory, - void* user ) - { - FT_ListNode cur; - - - cur = list->head; - while ( cur ) - { - FT_ListNode next = cur->next; - void* data = cur->data; - - - if ( destroy ) - destroy( memory, data, user ); - - FT_FREE( cur ); - cur = next; - } - - list->head = 0; - list->tail = 0; - } - - - FT_BASE_DEF( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ) - { - FT_UInt32 value2; - - - /* - * We simply clear the lowest bit in each iteration. When - * we reach 0, we know that the previous value was our result. - */ - for ( ;; ) - { - value2 = value & (value - 1); /* clear lowest bit */ - if ( value2 == 0 ) - break; - - value = value2; - } - return value; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftwinfnt.c b/drivers/freetype/freetype/src/base/ftwinfnt.c deleted file mode 100644 index 463ae761d8..0000000000 --- a/drivers/freetype/freetype/src/base/ftwinfnt.c +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftwinfnt.c */ -/* */ -/* FreeType API for accessing Windows FNT specific info (body). */ -/* */ -/* Copyright 2003, 2004 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_WINFONTS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_WINFNT_H - - - /* documentation is in ftwinfnt.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_WinFNT_Header( FT_Face face, - FT_WinFNT_HeaderRec *header ) - { - FT_Service_WinFnt service; - FT_Error error; - - - error = FT_ERR( Invalid_Argument ); - - if ( face != NULL ) - { - FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); - - if ( service != NULL ) - { - error = service->get_header( face, header ); - } - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftxf86.c b/drivers/freetype/freetype/src/base/ftxf86.c deleted file mode 100644 index a4bf767dfa..0000000000 --- a/drivers/freetype/freetype/src/base/ftxf86.c +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftxf86.c */ -/* */ -/* FreeType utility file for X11 support (body). */ -/* */ -/* Copyright 2002, 2003, 2004 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_XFREE86_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_XFREE86_NAME_H - - - /* documentation is in ftxf86.h */ - - FT_EXPORT_DEF( const char* ) - FT_Get_X11_Font_Format( FT_Face face ) - { - const char* result = NULL; - - - if ( face ) - FT_FACE_FIND_SERVICE( face, result, XF86_NAME ); - - return result; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/md5.c b/drivers/freetype/freetype/src/base/md5.c deleted file mode 100644 index 2f01c9302c..0000000000 --- a/drivers/freetype/freetype/src/base/md5.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * (This is a heavily cut-down "BSD license".) - * - * This differs from Colin Plumb's older public domain implementation in that - * no exactly 32-bit integer data type is required (any 32-bit or wider - * unsigned integer data type will do), there's no compile-time endianness - * configuration, and the function prototypes match OpenSSL's. No code from - * Colin Plumb's implementation has been reused; this comment merely compares - * the properties of the two independent implementations. - * - * The primary goals of this implementation are portability and ease of use. - * It is meant to be fast, but not as fast as possible. Some known - * optimizations are not included to reduce source code size and avoid - * compile-time configuration. - */ - -#ifndef HAVE_OPENSSL - -#include <string.h> - -#include "md5.h" - -/* - * The basic MD5 functions. - * - * F and G are optimized compared to their RFC 1321 definitions for - * architectures that lack an AND-NOT instruction, just like in Colin Plumb's - * implementation. - */ -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | ~(z))) - -/* - * The MD5 transformation for all four rounds. - */ -#define STEP(f, a, b, c, d, x, t, s) \ - (a) += f((b), (c), (d)) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); - -/* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. - * - * The check for little-endian architectures that tolerate unaligned - * memory accesses is just an optimization. Nothing will break if it - * doesn't work. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -#define SET(n) \ - (*(MD5_u32plus *)&ptr[(n) * 4]) -#define GET(n) \ - SET(n) -#else -#define SET(n) \ - (ctx->block[(n)] = \ - (MD5_u32plus)ptr[(n) * 4] | \ - ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ - ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ - ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) -#define GET(n) \ - (ctx->block[(n)]) -#endif - -/* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. - */ -static void *body(MD5_CTX *ctx, void *data, unsigned long size) -{ - unsigned char *ptr; - MD5_u32plus a, b, c, d; - MD5_u32plus saved_a, saved_b, saved_c, saved_d; - - ptr = (unsigned char *)data; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - -/* Round 1 */ - STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) - STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) - STEP(F, c, d, a, b, SET(2), 0x242070db, 17) - STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) - STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) - STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) - STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) - STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) - STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) - STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) - STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) - STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) - STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) - STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) - STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) - STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) - -/* Round 2 */ - STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) - STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) - STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) - STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) - STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) - STEP(G, d, a, b, c, GET(10), 0x02441453, 9) - STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) - STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) - STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) - STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) - STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) - STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) - STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) - STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) - STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) - STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) - -/* Round 3 */ - STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) - STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) - STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) - STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) - STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) - STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) - STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) - STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) - STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) - STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) - STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) - STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) - STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) - STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) - STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) - STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) - -/* Round 4 */ - STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) - STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) - STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) - STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) - STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) - STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) - STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) - STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) - STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) - STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) - STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) - STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) - STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) - STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) - STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) - STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while (size -= 64); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - return ptr; -} - -void MD5_Init(MD5_CTX *ctx) -{ - ctx->a = 0x67452301; - ctx->b = 0xefcdab89; - ctx->c = 0x98badcfe; - ctx->d = 0x10325476; - - ctx->lo = 0; - ctx->hi = 0; -} - -void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) -{ - MD5_u32plus saved_lo; - unsigned long used, free; - - saved_lo = ctx->lo; - if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) - ctx->hi++; - ctx->hi += size >> 29; - - used = saved_lo & 0x3f; - - if (used) { - free = 64 - used; - - if (size < free) { - memcpy(&ctx->buffer[used], data, size); - return; - } - - memcpy(&ctx->buffer[used], data, free); - data = (unsigned char *)data + free; - size -= free; - body(ctx, ctx->buffer, 64); - } - - if (size >= 64) { - data = body(ctx, data, size & ~(unsigned long)0x3f); - size &= 0x3f; - } - - memcpy(ctx->buffer, data, size); -} - -void MD5_Final(unsigned char *result, MD5_CTX *ctx) -{ - unsigned long used, free; - - used = ctx->lo & 0x3f; - - ctx->buffer[used++] = 0x80; - - free = 64 - used; - - if (free < 8) { - memset(&ctx->buffer[used], 0, free); - body(ctx, ctx->buffer, 64); - used = 0; - free = 64; - } - - memset(&ctx->buffer[used], 0, free - 8); - - ctx->lo <<= 3; - ctx->buffer[56] = ctx->lo; - ctx->buffer[57] = ctx->lo >> 8; - ctx->buffer[58] = ctx->lo >> 16; - ctx->buffer[59] = ctx->lo >> 24; - ctx->buffer[60] = ctx->hi; - ctx->buffer[61] = ctx->hi >> 8; - ctx->buffer[62] = ctx->hi >> 16; - ctx->buffer[63] = ctx->hi >> 24; - - body(ctx, ctx->buffer, 64); - - result[0] = ctx->a; - result[1] = ctx->a >> 8; - result[2] = ctx->a >> 16; - result[3] = ctx->a >> 24; - result[4] = ctx->b; - result[5] = ctx->b >> 8; - result[6] = ctx->b >> 16; - result[7] = ctx->b >> 24; - result[8] = ctx->c; - result[9] = ctx->c >> 8; - result[10] = ctx->c >> 16; - result[11] = ctx->c >> 24; - result[12] = ctx->d; - result[13] = ctx->d >> 8; - result[14] = ctx->d >> 16; - result[15] = ctx->d >> 24; - - memset(ctx, 0, sizeof(*ctx)); -} - -#endif diff --git a/drivers/freetype/freetype/src/base/md5.h b/drivers/freetype/freetype/src/base/md5.h deleted file mode 100644 index f1a6857640..0000000000 --- a/drivers/freetype/freetype/src/base/md5.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * See md5.c for more information. - */ - -#ifdef HAVE_OPENSSL -#include <openssl/md5.h> -#elif !defined(_MD5_H) -#define _MD5_H - -/* Any 32-bit or wider unsigned integer data type will do */ -typedef unsigned int MD5_u32plus; - -typedef struct { - MD5_u32plus lo, hi; - MD5_u32plus a, b, c, d; - unsigned char buffer[64]; - MD5_u32plus block[16]; -} MD5_CTX; - -extern void MD5_Init(MD5_CTX *ctx); -extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size); -extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); - -#endif diff --git a/drivers/freetype/freetype/src/base/rules.mk b/drivers/freetype/freetype/src/base/rules.mk deleted file mode 100644 index e932191157..0000000000 --- a/drivers/freetype/freetype/src/base/rules.mk +++ /dev/null @@ -1,99 +0,0 @@ -# -# FreeType 2 base layer configuration rules -# - - -# Copyright 1996-2000, 2002-2009, 2013 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. - - -# It sets the following variables which are used by the master Makefile -# after the call: -# -# BASE_OBJ_S: The single-object base layer. -# BASE_OBJ_M: A list of all objects for a multiple-objects build. -# BASE_EXT_OBJ: A list of base layer extensions, i.e., components found -# in `freetype/src/base' which are not compiled within the -# base layer proper. - - -BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) - - -# Base layer sources -# -# ftsystem, ftinit, and ftdebug are handled by freetype.mk -# -# All files listed here should be included in `ftbase.c' (for a `single' -# build). -# -BASE_SRC := $(BASE_DIR)/ftadvanc.c \ - $(BASE_DIR)/ftcalc.c \ - $(BASE_DIR)/ftdbgmem.c \ - $(BASE_DIR)/ftgloadr.c \ - $(BASE_DIR)/ftobjs.c \ - $(BASE_DIR)/ftoutln.c \ - $(BASE_DIR)/ftrfork.c \ - $(BASE_DIR)/ftsnames.c \ - $(BASE_DIR)/ftstream.c \ - $(BASE_DIR)/fttrigon.c \ - $(BASE_DIR)/ftutil.c - - -ifneq ($(ftmac_c),) - BASE_SRC += $(BASE_DIR)/$(ftmac_c) -endif - -# for simplicity, we also handle `md5.c' (which gets included by `ftobjs.h') -BASE_H := $(BASE_DIR)/ftbase.h \ - $(BASE_DIR)/md5.c \ - $(BASE_DIR)/md5.h - -# Base layer `extensions' sources -# -# An extension is added to the library file as a separate object. It is -# then linked to the final executable only if one of its symbols is used by -# the application. -# -BASE_EXT_SRC := $(patsubst %,$(BASE_DIR)/%,$(BASE_EXTENSIONS)) - -# Default extensions objects -# -BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_DIR)/%.c=$(OBJ_DIR)/%.$O) - - -# Base layer object(s) -# -# BASE_OBJ_M is used during `multi' builds (each base source file compiles -# to a single object file). -# -# BASE_OBJ_S is used during `single' builds (the whole base layer is -# compiled as a single object file using ftbase.c). -# -BASE_OBJ_M := $(BASE_SRC:$(BASE_DIR)/%.c=$(OBJ_DIR)/%.$O) -BASE_OBJ_S := $(OBJ_DIR)/ftbase.$O - -# Base layer root source file for single build -# -BASE_SRC_S := $(BASE_DIR)/ftbase.c - - -# Base layer - single object build -# -$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) $(BASE_H) - $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BASE_SRC_S)) - - -# Multiple objects build + extensions -# -$(OBJ_DIR)/%.$O: $(BASE_DIR)/%.c $(FREETYPE_H) $(BASE_H) - $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# EOF diff --git a/drivers/freetype/freetype/src/bdf/Jamfile b/drivers/freetype/freetype/src/bdf/Jamfile deleted file mode 100644 index da23ccd0ad..0000000000 --- a/drivers/freetype/freetype/src/bdf/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/bdf Jamfile -# -# Copyright 2002 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) bdf ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = bdfdrivr bdflib ; - } - else - { - _sources = bdf ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/bdf Jamfile diff --git a/drivers/freetype/freetype/src/bdf/README b/drivers/freetype/freetype/src/bdf/README deleted file mode 100644 index b761aba2b2..0000000000 --- a/drivers/freetype/freetype/src/bdf/README +++ /dev/null @@ -1,148 +0,0 @@ - FreeType font driver for BDF fonts - - Francesco Zappa Nardelli - <francesco.zappa.nardelli@ens.fr> - - -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. -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/public/developer/en/font/5005.BDF_Spec.pdf - -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. - - -Encodings -********* - -The variety of encodings that accompanies bdf fonts appears to encompass the -small set defined in freetype.h. On the other hand, two properties that -specify encoding and registry are usually defined in bdf fonts. - -I decided to make these two properties directly accessible, leaving to the -client application the work of interpreting them. For instance: - - - #include FT_INTERNAL_BDF_TYPES_H - - FT_Face face; - BDF_Public_Face bdfface; - - - FT_New_Face( library, ..., &face ); - - bdfface = (BDF_Public_Face)face; - - if ( ( bdfface->charset_registry == "ISO10646" ) && - ( bdfface->charset_encoding == "1" ) ) - [..] - - -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. - -If the two properties are not available, Adobe Standard Encoding should be -assumed. - - -Anti-Aliased Bitmaps -******************** - -The driver supports an extension to the BDF format as used in Mark Leisher's -xmbdfed bitmap font editor. Microsoft's SBIT tool expects bitmap fonts in -that format for adding anti-aliased them to TrueType fonts. It introduces a -fourth field to the `SIZE' keyword which gives the bpp value (bits per -pixel) of the glyph data in the font. Possible values are 1 (the default), -2 (four gray levels), 4 (16 gray levels), and 8 (256 gray levels). The -driver returns either a bitmap with 1 bit per pixel or a pixmap with 8bits -per pixel (using 4, 16, and 256 gray levels, respectively). - - -Known problems -************** - -- A font is entirely loaded into memory. Obviously, this is not the Right - Thing(TM). If you have big fonts I suggest you convert them into PCF - format (using the bdftopcf utility): the PCF font drive of FreeType can - perform incremental glyph loading. - -When I have some time, I will implement on-demand glyph parsing. - -- Except for encodings properties, client applications have no visibility of - the PCF_Face object. This means that applications cannot directly access - font tables and must trust FreeType. - -- Currently, glyph names are ignored. - - I plan to give full visibility of the BDF_Face object in an upcoming - revision of the driver, thus implementing also glyph names. - -- As I have never seen a BDF font that defines vertical metrics, vertical - metrics are (parsed and) discarded. If you own a BDF font that defines - vertical metrics, please let me know (I will implement them in 5-10 - minutes). - - -License -******* - -Copyright (C) 2001-2002 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 to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*** Portions of the driver (that is, bdflib.c and bdf.h): - -Copyright 2000 Computing Research Labs, New Mexico State University -Copyright 2001-2002, 2011 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 to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT -OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -Credits -******* - -This driver is based on excellent Mark Leisher's bdf library. If you -find something good in this driver you should probably thank him, not -me. diff --git a/drivers/freetype/freetype/src/bdf/bdf.c b/drivers/freetype/freetype/src/bdf/bdf.c deleted file mode 100644 index f95fb76225..0000000000 --- a/drivers/freetype/freetype/src/bdf/bdf.c +++ /dev/null @@ -1,34 +0,0 @@ -/* bdf.c - - FreeType font driver for bdf files - - Copyright (C) 2001, 2002 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "bdflib.c" -#include "bdfdrivr.c" - - -/* END */ diff --git a/drivers/freetype/freetype/src/bdf/bdf.h b/drivers/freetype/freetype/src/bdf/bdf.h deleted file mode 100644 index d11be6f147..0000000000 --- a/drivers/freetype/freetype/src/bdf/bdf.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001-2004, 2011 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 to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef __BDF_H__ -#define __BDF_H__ - - -/* - * Based on bdf.h,v 1.16 2000/03/16 20:08:51 mleisher - */ - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_STREAM_H - - -FT_BEGIN_HEADER - - -/* Imported from bdfP.h */ - -#define _bdf_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] & ( 1 << ( (e) & 31 ) ) ) -#define _bdf_set_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] |= ( 1 << ( (e) & 31 ) ) ) -#define _bdf_clear_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] &= ~( 1 << ( (e) & 31 ) ) ) - -/* end of bdfP.h */ - - - /*************************************************************************/ - /* */ - /* BDF font options macros and types. */ - /* */ - /*************************************************************************/ - - -#define BDF_CORRECT_METRICS 0x01 /* Correct invalid metrics when loading. */ -#define BDF_KEEP_COMMENTS 0x02 /* Preserve the font comments. */ -#define BDF_KEEP_UNENCODED 0x04 /* Keep the unencoded glyphs. */ -#define BDF_PROPORTIONAL 0x08 /* Font has proportional spacing. */ -#define BDF_MONOWIDTH 0x10 /* Font has mono width. */ -#define BDF_CHARCELL 0x20 /* Font has charcell spacing. */ - -#define BDF_ALL_SPACING ( BDF_PROPORTIONAL | \ - BDF_MONOWIDTH | \ - BDF_CHARCELL ) - -#define BDF_DEFAULT_LOAD_OPTIONS ( BDF_CORRECT_METRICS | \ - BDF_KEEP_COMMENTS | \ - BDF_KEEP_UNENCODED | \ - BDF_PROPORTIONAL ) - - - typedef struct bdf_options_t_ - { - int correct_metrics; - int keep_unencoded; - int keep_comments; - int font_spacing; - - } bdf_options_t; - - - /* Callback function type for unknown configuration options. */ - typedef int - (*bdf_options_callback_t)( bdf_options_t* opts, - char** params, - unsigned long nparams, - void* client_data ); - - - /*************************************************************************/ - /* */ - /* BDF font property macros and types. */ - /* */ - /*************************************************************************/ - - -#define BDF_ATOM 1 -#define BDF_INTEGER 2 -#define BDF_CARDINAL 3 - - - /* This structure represents a particular property of a font. */ - /* There are a set of defaults and each font has their own. */ - typedef struct bdf_property_t_ - { - char* name; /* Name of the property. */ - int format; /* Format of the property. */ - int builtin; /* A builtin property. */ - union - { - char* atom; - long l; - unsigned long ul; - - } value; /* Value of the property. */ - - } bdf_property_t; - - - /*************************************************************************/ - /* */ - /* BDF font metric and glyph types. */ - /* */ - /*************************************************************************/ - - - typedef struct bdf_bbx_t_ - { - unsigned short width; - unsigned short height; - - short x_offset; - short y_offset; - - short ascent; - short descent; - - } bdf_bbx_t; - - - typedef struct bdf_glyph_t_ - { - char* name; /* Glyph name. */ - long encoding; /* Glyph encoding. */ - unsigned short swidth; /* Scalable width. */ - unsigned short dwidth; /* Device width. */ - bdf_bbx_t bbx; /* Glyph bounding box. */ - unsigned char* bitmap; /* Glyph bitmap. */ - unsigned long bpr; /* Number of bytes used per row. */ - unsigned short bytes; /* Number of bytes used for the bitmap. */ - - } bdf_glyph_t; - - - typedef struct _hashnode_ - { - const char* key; - size_t data; - - } _hashnode, *hashnode; - - - typedef struct hashtable_ - { - int limit; - int size; - int used; - hashnode* table; - - } hashtable; - - - typedef struct bdf_glyphlist_t_ - { - unsigned short pad; /* Pad to 4-byte boundary. */ - unsigned short bpp; /* Bits per pixel. */ - long start; /* Beginning encoding value of glyphs. */ - long end; /* Ending encoding value of glyphs. */ - bdf_glyph_t* glyphs; /* Glyphs themselves. */ - unsigned long glyphs_size; /* Glyph structures allocated. */ - unsigned long glyphs_used; /* Glyph structures used. */ - bdf_bbx_t bbx; /* Overall bounding box of glyphs. */ - - } bdf_glyphlist_t; - - - typedef struct bdf_font_t_ - { - char* name; /* Name of the font. */ - bdf_bbx_t bbx; /* Font bounding box. */ - - long point_size; /* Point size of the font. */ - unsigned long resolution_x; /* Font horizontal resolution. */ - unsigned long resolution_y; /* Font vertical resolution. */ - - int spacing; /* Font spacing value. */ - - unsigned short monowidth; /* Logical width for monowidth font. */ - - long default_char; /* Encoding of the default glyph. */ - - long font_ascent; /* Font ascent. */ - long font_descent; /* Font descent. */ - - unsigned long glyphs_size; /* Glyph structures allocated. */ - unsigned long glyphs_used; /* Glyph structures used. */ - bdf_glyph_t* glyphs; /* Glyphs themselves. */ - - unsigned long unencoded_size; /* Unencoded glyph struct. allocated. */ - unsigned long unencoded_used; /* Unencoded glyph struct. used. */ - bdf_glyph_t* unencoded; /* Unencoded glyphs themselves. */ - - unsigned long props_size; /* Font properties allocated. */ - unsigned long props_used; /* Font properties used. */ - bdf_property_t* props; /* Font properties themselves. */ - - char* comments; /* Font comments. */ - unsigned long comments_len; /* Length of comment string. */ - - bdf_glyphlist_t overflow; /* Storage used for glyph insertion. */ - - void* internal; /* Internal data for the font. */ - - /* The size of the next two arrays must be in sync with the */ - /* size of the `have' array in the `bdf_parse_t' structure. */ - unsigned long nmod[34816]; /* Bitmap indicating modified glyphs. */ - unsigned long umod[34816]; /* Bitmap indicating modified */ - /* unencoded glyphs. */ - unsigned short modified; /* Boolean indicating font modified. */ - unsigned short bpp; /* Bits per pixel. */ - - FT_Memory memory; - - bdf_property_t* user_props; - unsigned long nuser_props; - hashtable proptbl; - - } bdf_font_t; - - - /*************************************************************************/ - /* */ - /* Types for load/save callbacks. */ - /* */ - /*************************************************************************/ - - - /* Error codes. */ -#define BDF_MISSING_START -1 -#define BDF_MISSING_FONTNAME -2 -#define BDF_MISSING_SIZE -3 -#define BDF_MISSING_CHARS -4 -#define BDF_MISSING_STARTCHAR -5 -#define BDF_MISSING_ENCODING -6 -#define BDF_MISSING_BBX -7 - -#define BDF_OUT_OF_MEMORY -20 - -#define BDF_INVALID_LINE -100 - - - /*************************************************************************/ - /* */ - /* BDF font API. */ - /* */ - /*************************************************************************/ - - FT_LOCAL( FT_Error ) - bdf_load_font( FT_Stream stream, - FT_Memory memory, - bdf_options_t* opts, - bdf_font_t* *font ); - - FT_LOCAL( void ) - bdf_free_font( bdf_font_t* font ); - - FT_LOCAL( bdf_property_t * ) - bdf_get_property( char* name, - bdf_font_t* font ); - - FT_LOCAL( bdf_property_t * ) - bdf_get_font_property( bdf_font_t* font, - const char* name ); - - -FT_END_HEADER - - -#endif /* __BDF_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/bdf/bdfdrivr.c b/drivers/freetype/freetype/src/bdf/bdfdrivr.c deleted file mode 100644 index 0ea0a5ea5e..0000000000 --- a/drivers/freetype/freetype/src/bdf/bdfdrivr.c +++ /dev/null @@ -1,878 +0,0 @@ -/* bdfdrivr.c - - FreeType font driver for bdf files - - Copyright (C) 2001-2008, 2011, 2013 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include <ft2build.h> - -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_OBJECTS_H -#include FT_BDF_H -#include FT_TRUETYPE_IDS_H - -#include FT_SERVICE_BDF_H -#include FT_SERVICE_XFREE86_NAME_H - -#include "bdf.h" -#include "bdfdrivr.h" - -#include "bdferror.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_bdfdriver - - - typedef struct BDF_CMapRec_ - { - FT_CMapRec cmap; - FT_ULong num_encodings; /* ftobjs.h: FT_CMap->clazz->size */ - BDF_encoding_el* encodings; - - } BDF_CMapRec, *BDF_CMap; - - - FT_CALLBACK_DEF( FT_Error ) - bdf_cmap_init( FT_CMap bdfcmap, - FT_Pointer init_data ) - { - BDF_CMap cmap = (BDF_CMap)bdfcmap; - BDF_Face face = (BDF_Face)FT_CMAP_FACE( cmap ); - FT_UNUSED( init_data ); - - - cmap->num_encodings = face->bdffont->glyphs_used; - cmap->encodings = face->en_table; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( void ) - bdf_cmap_done( FT_CMap bdfcmap ) - { - BDF_CMap cmap = (BDF_CMap)bdfcmap; - - - cmap->encodings = NULL; - cmap->num_encodings = 0; - } - - - FT_CALLBACK_DEF( FT_UInt ) - bdf_cmap_char_index( FT_CMap bdfcmap, - FT_UInt32 charcode ) - { - BDF_CMap cmap = (BDF_CMap)bdfcmap; - BDF_encoding_el* encodings = cmap->encodings; - FT_ULong min, max, mid; /* num_encodings */ - FT_UShort result = 0; /* encodings->glyph */ - - - min = 0; - max = cmap->num_encodings; - - while ( min < max ) - { - FT_ULong code; - - - mid = ( min + max ) >> 1; - code = encodings[mid].enc; - - if ( charcode == code ) - { - /* increase glyph index by 1 -- */ - /* we reserve slot 0 for the undefined glyph */ - result = encodings[mid].glyph + 1; - break; - } - - if ( charcode < code ) - max = mid; - else - min = mid + 1; - } - - return result; - } - - - FT_CALLBACK_DEF( FT_UInt ) - bdf_cmap_char_next( FT_CMap bdfcmap, - FT_UInt32 *acharcode ) - { - BDF_CMap cmap = (BDF_CMap)bdfcmap; - BDF_encoding_el* encodings = cmap->encodings; - FT_ULong min, max, mid; /* num_encodings */ - FT_UShort result = 0; /* encodings->glyph */ - FT_ULong charcode = *acharcode + 1; - - - min = 0; - max = cmap->num_encodings; - - while ( min < max ) - { - FT_ULong code; /* same as BDF_encoding_el.enc */ - - - mid = ( min + max ) >> 1; - code = encodings[mid].enc; - - if ( charcode == code ) - { - /* increase glyph index by 1 -- */ - /* we reserve slot 0 for the undefined glyph */ - result = encodings[mid].glyph + 1; - goto Exit; - } - - if ( charcode < code ) - max = mid; - else - min = mid + 1; - } - - charcode = 0; - if ( min < cmap->num_encodings ) - { - charcode = encodings[min].enc; - result = encodings[min].glyph + 1; - } - - Exit: - if ( charcode > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" )); - *acharcode = 0; - /* XXX: result should be changed to indicate an overflow error */ - } - else - *acharcode = (FT_UInt32)charcode; - return result; - } - - - FT_CALLBACK_TABLE_DEF - const FT_CMap_ClassRec bdf_cmap_class = - { - sizeof ( BDF_CMapRec ), - bdf_cmap_init, - bdf_cmap_done, - bdf_cmap_char_index, - bdf_cmap_char_next, - - NULL, NULL, NULL, NULL, NULL - }; - - - static FT_Error - bdf_interpret_style( BDF_Face bdf ) - { - FT_Error error = FT_Err_Ok; - FT_Face face = FT_FACE( bdf ); - FT_Memory memory = face->memory; - bdf_font_t* font = bdf->bdffont; - bdf_property_t* prop; - - char* strings[4] = { NULL, NULL, NULL, NULL }; - size_t nn, len, lengths[4]; - - - face->style_flags = 0; - - prop = bdf_get_font_property( font, (char *)"SLANT" ); - if ( prop && prop->format == BDF_ATOM && - prop->value.atom && - ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || - *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) - { - face->style_flags |= FT_STYLE_FLAG_ITALIC; - strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) - ? (char *)"Oblique" - : (char *)"Italic"; - } - - prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); - if ( prop && prop->format == BDF_ATOM && - prop->value.atom && - ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) - { - face->style_flags |= FT_STYLE_FLAG_BOLD; - strings[1] = (char *)"Bold"; - } - - prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" ); - if ( prop && prop->format == BDF_ATOM && - prop->value.atom && *(prop->value.atom) && - !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) - strings[3] = (char *)(prop->value.atom); - - prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" ); - if ( prop && prop->format == BDF_ATOM && - prop->value.atom && *(prop->value.atom) && - !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) - strings[0] = (char *)(prop->value.atom); - - len = 0; - - for ( len = 0, nn = 0; nn < 4; nn++ ) - { - lengths[nn] = 0; - if ( strings[nn] ) - { - lengths[nn] = ft_strlen( strings[nn] ); - len += lengths[nn] + 1; - } - } - - if ( len == 0 ) - { - strings[0] = (char *)"Regular"; - lengths[0] = ft_strlen( strings[0] ); - len = lengths[0] + 1; - } - - { - char* s; - - - if ( FT_ALLOC( face->style_name, len ) ) - return error; - - s = face->style_name; - - for ( nn = 0; nn < 4; nn++ ) - { - char* src = strings[nn]; - - - len = lengths[nn]; - - if ( src == NULL ) - continue; - - /* separate elements with a space */ - if ( s != face->style_name ) - *s++ = ' '; - - ft_memcpy( s, src, len ); - - /* need to convert spaces to dashes for */ - /* add_style_name and setwidth_name */ - if ( nn == 0 || nn == 3 ) - { - size_t mm; - - - for ( mm = 0; mm < len; mm++ ) - if ( s[mm] == ' ' ) - s[mm] = '-'; - } - - s += len; - } - *s = 0; - } - - return error; - } - - - FT_CALLBACK_DEF( void ) - BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */ - { - BDF_Face face = (BDF_Face)bdfface; - FT_Memory memory; - - - if ( !face ) - return; - - memory = FT_FACE_MEMORY( face ); - - bdf_free_font( face->bdffont ); - - FT_FREE( face->en_table ); - - FT_FREE( face->charset_encoding ); - FT_FREE( face->charset_registry ); - FT_FREE( bdfface->family_name ); - FT_FREE( bdfface->style_name ); - - FT_FREE( bdfface->available_sizes ); - - FT_FREE( face->bdffont ); - } - - - FT_CALLBACK_DEF( FT_Error ) - BDF_Face_Init( FT_Stream stream, - FT_Face bdfface, /* BDF_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error = FT_Err_Ok; - BDF_Face face = (BDF_Face)bdfface; - FT_Memory memory = FT_FACE_MEMORY( face ); - - bdf_font_t* font = NULL; - bdf_options_t options; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - - - FT_TRACE2(( "BDF driver\n" )); - - if ( FT_STREAM_SEEK( 0 ) ) - goto Exit; - - options.correct_metrics = 1; /* FZ XXX: options semantics */ - options.keep_unencoded = 1; - options.keep_comments = 0; - options.font_spacing = BDF_PROPORTIONAL; - - error = bdf_load_font( stream, memory, &options, &font ); - if ( FT_ERR_EQ( error, Missing_Startfont_Field ) ) - { - FT_TRACE2(( " not a BDF file\n" )); - goto Fail; - } - else if ( error ) - goto Exit; - - /* we have a bdf font: let's construct the face object */ - face->bdffont = font; - { - bdf_property_t* prop = NULL; - - - FT_TRACE4(( " number of glyphs: allocated %d (used %d)\n", - font->glyphs_size, - font->glyphs_used )); - FT_TRACE4(( " number of unencoded glyphs: allocated %d (used %d)\n", - font->unencoded_size, - font->unencoded_used )); - - bdfface->num_faces = 1; - bdfface->face_index = 0; - bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_FAST_GLYPHS; - - prop = bdf_get_font_property( font, "SPACING" ); - if ( prop && prop->format == BDF_ATOM && - prop->value.atom && - ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' || - *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) ) - bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ - /* FZ XXX: I need a font to implement this */ - - prop = bdf_get_font_property( font, "FAMILY_NAME" ); - if ( prop && prop->value.atom ) - { - if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) ) - goto Exit; - } - else - bdfface->family_name = 0; - - if ( ( error = bdf_interpret_style( face ) ) != 0 ) - goto Exit; - - /* the number of glyphs (with one slot for the undefined glyph */ - /* at position 0 and all unencoded glyphs) */ - bdfface->num_glyphs = font->glyphs_size + 1; - - bdfface->num_fixed_sizes = 1; - if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) ) - goto Exit; - - { - FT_Bitmap_Size* bsize = bdfface->available_sizes; - FT_Short resolution_x = 0, resolution_y = 0; - - - FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); - - bsize->height = (FT_Short)( font->font_ascent + font->font_descent ); - - prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); - if ( prop ) - bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); - else - bsize->width = (FT_Short)( bsize->height * 2/3 ); - - prop = bdf_get_font_property( font, "POINT_SIZE" ); - if ( prop ) - /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = - (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); - else - bsize->size = bsize->width << 6; - - prop = bdf_get_font_property( font, "PIXEL_SIZE" ); - if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.l << 6; - - prop = bdf_get_font_property( font, "RESOLUTION_X" ); - if ( prop ) - resolution_x = (FT_Short)prop->value.l; - - prop = bdf_get_font_property( font, "RESOLUTION_Y" ); - if ( prop ) - resolution_y = (FT_Short)prop->value.l; - - if ( bsize->y_ppem == 0 ) - { - bsize->y_ppem = bsize->size; - if ( resolution_y ) - bsize->y_ppem = bsize->y_ppem * resolution_y / 72; - } - if ( resolution_x && resolution_y ) - bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; - else - bsize->x_ppem = bsize->y_ppem; - } - - /* encoding table */ - { - bdf_glyph_t* cur = font->glyphs; - unsigned long n; - - - if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) ) - goto Exit; - - face->default_glyph = 0; - for ( n = 0; n < font->glyphs_size; n++ ) - { - (face->en_table[n]).enc = cur[n].encoding; - FT_TRACE4(( " idx %d, val 0x%lX\n", n, cur[n].encoding )); - (face->en_table[n]).glyph = (FT_Short)n; - - if ( cur[n].encoding == font->default_char ) - { - if ( n < FT_UINT_MAX ) - face->default_glyph = (FT_UInt)n; - else - FT_TRACE1(( "BDF_Face_Init:" - " idx %d is too large for this system\n", n )); - } - } - } - - /* charmaps */ - { - bdf_property_t *charset_registry = 0, *charset_encoding = 0; - FT_Bool unicode_charmap = 0; - - - charset_registry = - bdf_get_font_property( font, "CHARSET_REGISTRY" ); - charset_encoding = - bdf_get_font_property( font, "CHARSET_ENCODING" ); - if ( charset_registry && charset_encoding ) - { - if ( charset_registry->format == BDF_ATOM && - charset_encoding->format == BDF_ATOM && - charset_registry->value.atom && - charset_encoding->value.atom ) - { - const char* s; - - - if ( FT_STRDUP( face->charset_encoding, - charset_encoding->value.atom ) || - FT_STRDUP( face->charset_registry, - charset_registry->value.atom ) ) - goto Exit; - - /* Uh, oh, compare first letters manually to avoid dependency */ - /* on locales. */ - s = face->charset_registry; - if ( ( s[0] == 'i' || s[0] == 'I' ) && - ( s[1] == 's' || s[1] == 'S' ) && - ( s[2] == 'o' || s[2] == 'O' ) ) - { - s += 3; - if ( !ft_strcmp( s, "10646" ) || - ( !ft_strcmp( s, "8859" ) && - !ft_strcmp( face->charset_encoding, "1" ) ) ) - unicode_charmap = 1; - } - - { - FT_CharMapRec charmap; - - - charmap.face = FT_FACE( face ); - charmap.encoding = FT_ENCODING_NONE; - /* initial platform/encoding should indicate unset status? */ - charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; - charmap.encoding_id = TT_APPLE_ID_DEFAULT; - - if ( unicode_charmap ) - { - charmap.encoding = FT_ENCODING_UNICODE; - charmap.platform_id = TT_PLATFORM_MICROSOFT; - charmap.encoding_id = TT_MS_ID_UNICODE_CS; - } - - error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( bdfface->num_charmaps ) - bdfface->charmap = bdfface->charmaps[0]; -#endif - } - - goto Exit; - } - } - - /* otherwise assume Adobe standard encoding */ - - { - FT_CharMapRec charmap; - - - charmap.face = FT_FACE( face ); - charmap.encoding = FT_ENCODING_ADOBE_STANDARD; - charmap.platform_id = TT_PLATFORM_ADOBE; - charmap.encoding_id = TT_ADOBE_ID_STANDARD; - - error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); - - /* Select default charmap */ - if ( bdfface->num_charmaps ) - bdfface->charmap = bdfface->charmaps[0]; - } - } - } - - Exit: - return error; - - Fail: - BDF_Face_Done( bdfface ); - return FT_THROW( Unknown_File_Format ); - } - - - FT_CALLBACK_DEF( FT_Error ) - BDF_Size_Select( FT_Size size, - FT_ULong strike_index ) - { - bdf_font_t* bdffont = ( (BDF_Face)size->face )->bdffont; - - - FT_Select_Metrics( size->face, strike_index ); - - size->metrics.ascender = bdffont->font_ascent << 6; - size->metrics.descender = -bdffont->font_descent << 6; - size->metrics.max_advance = bdffont->bbx.width << 6; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_Error ) - BDF_Size_Request( FT_Size size, - FT_Size_Request req ) - { - FT_Face face = size->face; - FT_Bitmap_Size* bsize = face->available_sizes; - bdf_font_t* bdffont = ( (BDF_Face)face )->bdffont; - FT_Error error = FT_ERR( Invalid_Pixel_Size ); - FT_Long height; - - - height = FT_REQUEST_HEIGHT( req ); - height = ( height + 32 ) >> 6; - - switch ( req->type ) - { - case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) - error = FT_Err_Ok; - break; - - case FT_SIZE_REQUEST_TYPE_REAL_DIM: - if ( height == ( bdffont->font_ascent + - bdffont->font_descent ) ) - error = FT_Err_Ok; - break; - - default: - error = FT_THROW( Unimplemented_Feature ); - break; - } - - if ( error ) - return error; - else - return BDF_Size_Select( size, 0 ); - } - - - - FT_CALLBACK_DEF( FT_Error ) - BDF_Glyph_Load( FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size ); - FT_Face face = FT_FACE( bdf ); - FT_Error error = FT_Err_Ok; - FT_Bitmap* bitmap = &slot->bitmap; - bdf_glyph_t glyph; - int bpp = bdf->bdffont->bpp; - - FT_UNUSED( load_flags ); - - - if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* index 0 is the undefined glyph */ - if ( glyph_index == 0 ) - glyph_index = bdf->default_glyph; - else - glyph_index--; - - /* slot, bitmap => freetype, glyph => bdflib */ - glyph = bdf->bdffont->glyphs[glyph_index]; - - bitmap->rows = glyph.bbx.height; - bitmap->width = glyph.bbx.width; - if ( glyph.bpr > INT_MAX ) - FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n", - glyph.bpr )); - bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */ - - /* note: we don't allocate a new array to hold the bitmap; */ - /* we can simply point to it */ - ft_glyphslot_set_bitmap( slot, glyph.bitmap ); - - switch ( bpp ) - { - case 1: - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - break; - case 2: - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2; - break; - case 4: - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4; - break; - case 8: - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->num_grays = 256; - break; - } - - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = glyph.bbx.x_offset; - slot->bitmap_top = glyph.bbx.ascent; - - slot->metrics.horiAdvance = glyph.dwidth << 6; - slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; - slot->metrics.horiBearingY = glyph.bbx.ascent << 6; - slot->metrics.width = bitmap->width << 6; - slot->metrics.height = bitmap->rows << 6; - - /* - * XXX DWIDTH1 and VVECTOR should be parsed and - * used here, provided such fonts do exist. - */ - ft_synthesize_vertical_metrics( &slot->metrics, - bdf->bdffont->bbx.height << 6 ); - - Exit: - return error; - } - - - /* - * - * BDF SERVICE - * - */ - - static FT_Error - bdf_get_bdf_property( BDF_Face face, - const char* prop_name, - BDF_PropertyRec *aproperty ) - { - bdf_property_t* prop; - - - FT_ASSERT( face && face->bdffont ); - - prop = bdf_get_font_property( face->bdffont, prop_name ); - if ( prop ) - { - switch ( prop->format ) - { - case BDF_ATOM: - aproperty->type = BDF_PROPERTY_TYPE_ATOM; - aproperty->u.atom = prop->value.atom; - break; - - case BDF_INTEGER: - if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) - { - FT_TRACE1(( "bdf_get_bdf_property:" - " too large integer 0x%x is truncated\n" )); - } - aproperty->type = BDF_PROPERTY_TYPE_INTEGER; - aproperty->u.integer = (FT_Int32)prop->value.l; - break; - - case BDF_CARDINAL: - if ( prop->value.ul > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "bdf_get_bdf_property:" - " too large cardinal 0x%x is truncated\n" )); - } - aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; - aproperty->u.cardinal = (FT_UInt32)prop->value.ul; - break; - - default: - goto Fail; - } - return 0; - } - - Fail: - return FT_THROW( Invalid_Argument ); - } - - - static FT_Error - bdf_get_charset_id( BDF_Face face, - const char* *acharset_encoding, - const char* *acharset_registry ) - { - *acharset_encoding = face->charset_encoding; - *acharset_registry = face->charset_registry; - - return 0; - } - - - static const FT_Service_BDFRec bdf_service_bdf = - { - (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, - (FT_BDF_GetPropertyFunc) bdf_get_bdf_property - }; - - - /* - * - * SERVICES LIST - * - */ - - static const FT_ServiceDescRec bdf_services[] = - { - { FT_SERVICE_ID_BDF, &bdf_service_bdf }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF }, - { NULL, NULL } - }; - - - FT_CALLBACK_DEF( FT_Module_Interface ) - bdf_driver_requester( FT_Module module, - const char* name ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( bdf_services, name ); - } - - - - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec bdf_driver_class = - { - { - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_NO_OUTLINES, - sizeof ( FT_DriverRec ), - - "bdf", - 0x10000L, - 0x20000L, - - 0, - - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - bdf_driver_requester - }, - - sizeof ( BDF_FaceRec ), - sizeof ( FT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - - BDF_Face_Init, - BDF_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ - - BDF_Glyph_Load, - - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ - - BDF_Size_Request, - BDF_Size_Select - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/bdf/bdfdrivr.h b/drivers/freetype/freetype/src/bdf/bdfdrivr.h deleted file mode 100644 index ca0dae50d2..0000000000 --- a/drivers/freetype/freetype/src/bdf/bdfdrivr.h +++ /dev/null @@ -1,80 +0,0 @@ -/* bdfdrivr.h - - FreeType font driver for bdf fonts - - Copyright (C) 2001, 2002, 2003, 2004 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - - -#ifndef __BDFDRIVR_H__ -#define __BDFDRIVR_H__ - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H - -#include "bdf.h" - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - - typedef struct BDF_encoding_el_ - { - FT_ULong enc; - FT_UShort glyph; - - } BDF_encoding_el; - - - typedef struct BDF_FaceRec_ - { - FT_FaceRec root; - - char* charset_encoding; - char* charset_registry; - - bdf_font_t* bdffont; - - BDF_encoding_el* en_table; - - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ - - FT_UInt default_glyph; - - } BDF_FaceRec, *BDF_Face; - - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) bdf_driver_class; - - -FT_END_HEADER - - -#endif /* __BDFDRIVR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/bdf/bdferror.h b/drivers/freetype/freetype/src/bdf/bdferror.h deleted file mode 100644 index ea545aca06..0000000000 --- a/drivers/freetype/freetype/src/bdf/bdferror.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2001, 2002, 2012 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 to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - /*************************************************************************/ - /* */ - /* This file is used to define the BDF error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __BDFERROR_H__ -#define __BDFERROR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX BDF_Err_ -#define FT_ERR_BASE FT_Mod_Err_BDF - -#include FT_ERRORS_H - -#endif /* __BDFERROR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/bdf/bdflib.c b/drivers/freetype/freetype/src/bdf/bdflib.c deleted file mode 100644 index 0b8412d9eb..0000000000 --- a/drivers/freetype/freetype/src/bdf/bdflib.c +++ /dev/null @@ -1,2625 +0,0 @@ -/* - * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001-2013 - * 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 to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - /*************************************************************************/ - /* */ - /* This file is based on bdf.c,v 1.22 2000/03/16 20:08:50 */ - /* */ - /* taken from Mark Leisher's xmbdfed package */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> - -#include FT_FREETYPE_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_OBJECTS_H - -#include "bdf.h" -#include "bdferror.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_bdflib - - - /*************************************************************************/ - /* */ - /* Default BDF font options. */ - /* */ - /*************************************************************************/ - - - static const bdf_options_t _bdf_opts = - { - 1, /* Correct metrics. */ - 1, /* Preserve unencoded glyphs. */ - 0, /* Preserve comments. */ - BDF_PROPORTIONAL /* Default spacing. */ - }; - - - /*************************************************************************/ - /* */ - /* Builtin BDF font properties. */ - /* */ - /*************************************************************************/ - - /* List of most properties that might appear in a font. Doesn't include */ - /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts. */ - - static const bdf_property_t _bdf_properties[] = - { - { (char *)"ADD_STYLE_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, - { (char *)"CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } }, - { (char *)"CHARSET_ENCODING", BDF_ATOM, 1, { 0 } }, - { (char *)"CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } }, - { (char *)"COMMENT", BDF_ATOM, 1, { 0 } }, - { (char *)"COPYRIGHT", BDF_ATOM, 1, { 0 } }, - { (char *)"DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } }, - { (char *)"DESTINATION", BDF_CARDINAL, 1, { 0 } }, - { (char *)"DEVICE_FONT_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"END_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"FACE_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"FAMILY_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"FONT", BDF_ATOM, 1, { 0 } }, - { (char *)"FONTNAME_REGISTRY", BDF_ATOM, 1, { 0 } }, - { (char *)"FONT_ASCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"FONT_DESCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"FOUNDRY", BDF_ATOM, 1, { 0 } }, - { (char *)"FULL_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"ITALIC_ANGLE", BDF_INTEGER, 1, { 0 } }, - { (char *)"MAX_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"MIN_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"NORM_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"NOTICE", BDF_ATOM, 1, { 0 } }, - { (char *)"PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"POINT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_ASCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_DESCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_END_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_MAX_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_MIN_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_NORM_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_POINT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_PIXELSIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_POINTSIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_X_HEIGHT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RELATIVE_SETWIDTH", BDF_CARDINAL, 1, { 0 } }, - { (char *)"RELATIVE_WEIGHT", BDF_CARDINAL, 1, { 0 } }, - { (char *)"RESOLUTION", BDF_INTEGER, 1, { 0 } }, - { (char *)"RESOLUTION_X", BDF_CARDINAL, 1, { 0 } }, - { (char *)"RESOLUTION_Y", BDF_CARDINAL, 1, { 0 } }, - { (char *)"SETWIDTH_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"SLANT", BDF_ATOM, 1, { 0 } }, - { (char *)"SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"SPACING", BDF_ATOM, 1, { 0 } }, - { (char *)"STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, - { (char *)"UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, - { (char *)"UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, - { (char *)"WEIGHT", BDF_CARDINAL, 1, { 0 } }, - { (char *)"WEIGHT_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"X_HEIGHT", BDF_INTEGER, 1, { 0 } }, - { (char *)"_MULE_BASELINE_OFFSET", BDF_INTEGER, 1, { 0 } }, - { (char *)"_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } }, - }; - - static const unsigned long - _num_bdf_properties = sizeof ( _bdf_properties ) / - sizeof ( _bdf_properties[0] ); - - - /* Auto correction messages. */ -#define ACMSG1 "FONT_ASCENT property missing. " \ - "Added `FONT_ASCENT %hd'.\n" -#define ACMSG2 "FONT_DESCENT property missing. " \ - "Added `FONT_DESCENT %hd'.\n" -#define ACMSG3 "Font width != actual width. Old: %hd New: %hd.\n" -#define ACMSG4 "Font left bearing != actual left bearing. " \ - "Old: %hd New: %hd.\n" -#define ACMSG5 "Font ascent != actual ascent. Old: %hd New: %hd.\n" -#define ACMSG6 "Font descent != actual descent. Old: %hd New: %hd.\n" -#define ACMSG7 "Font height != actual height. Old: %hd New: %hd.\n" -#define ACMSG8 "Glyph scalable width (SWIDTH) adjustments made.\n" -#define ACMSG9 "SWIDTH field missing at line %ld. Set automatically.\n" -#define ACMSG10 "DWIDTH field missing at line %ld. Set to glyph width.\n" -#define ACMSG11 "SIZE bits per pixel field adjusted to %hd.\n" -#define ACMSG12 "Duplicate encoding %ld (%s) changed to unencoded.\n" -#define ACMSG13 "Glyph %ld extra rows removed.\n" -#define ACMSG14 "Glyph %ld extra columns removed.\n" -#define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" -#define ACMSG16 "Glyph %ld missing columns padded with zero bits.\n" - - /* Error messages. */ -#define ERRMSG1 "[line %ld] Missing `%s' line.\n" -#define ERRMSG2 "[line %ld] Font header corrupted or missing fields.\n" -#define ERRMSG3 "[line %ld] Font glyphs corrupted or missing fields.\n" -#define ERRMSG4 "[line %ld] BBX too big.\n" -#define ERRMSG5 "[line %ld] `%s' value too big.\n" -#define ERRMSG6 "[line %ld] Input line too long.\n" -#define ERRMSG7 "[line %ld] Font name too long.\n" -#define ERRMSG8 "[line %ld] Invalid `%s' value.\n" -#define ERRMSG9 "[line %ld] Invalid keyword.\n" - - /* Debug messages. */ -#define DBGMSG1 " [%6ld] %s" /* no \n */ -#define DBGMSG2 " (0x%lX)\n" - - - /*************************************************************************/ - /* */ - /* Hash table utilities for the properties. */ - /* */ - /*************************************************************************/ - - /* XXX: Replace this with FreeType's hash functions */ - - -#define INITIAL_HT_SIZE 241 - - typedef void - (*hash_free_func)( hashnode node ); - - static hashnode* - hash_bucket( const char* key, - hashtable* ht ) - { - const char* kp = key; - unsigned long res = 0; - hashnode* bp = ht->table, *ndp; - - - /* Mocklisp hash function. */ - while ( *kp ) - res = ( res << 5 ) - res + *kp++; - - ndp = bp + ( res % ht->size ); - while ( *ndp ) - { - kp = (*ndp)->key; - if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 ) - break; - ndp--; - if ( ndp < bp ) - ndp = bp + ( ht->size - 1 ); - } - - return ndp; - } - - - static FT_Error - hash_rehash( hashtable* ht, - FT_Memory memory ) - { - hashnode* obp = ht->table, *bp, *nbp; - int i, sz = ht->size; - FT_Error error = FT_Err_Ok; - - - ht->size <<= 1; - ht->limit = ht->size / 3; - - if ( FT_NEW_ARRAY( ht->table, ht->size ) ) - goto Exit; - - for ( i = 0, bp = obp; i < sz; i++, bp++ ) - { - if ( *bp ) - { - nbp = hash_bucket( (*bp)->key, ht ); - *nbp = *bp; - } - } - FT_FREE( obp ); - - Exit: - return error; - } - - - static FT_Error - hash_init( hashtable* ht, - FT_Memory memory ) - { - int sz = INITIAL_HT_SIZE; - FT_Error error = FT_Err_Ok; - - - ht->size = sz; - ht->limit = sz / 3; - ht->used = 0; - - if ( FT_NEW_ARRAY( ht->table, sz ) ) - goto Exit; - - Exit: - return error; - } - - - static void - hash_free( hashtable* ht, - FT_Memory memory ) - { - if ( ht != 0 ) - { - int i, sz = ht->size; - hashnode* bp = ht->table; - - - for ( i = 0; i < sz; i++, bp++ ) - FT_FREE( *bp ); - - FT_FREE( ht->table ); - } - } - - - static FT_Error - hash_insert( char* key, - size_t data, - hashtable* ht, - FT_Memory memory ) - { - hashnode nn; - hashnode* bp = hash_bucket( key, ht ); - FT_Error error = FT_Err_Ok; - - - nn = *bp; - if ( !nn ) - { - if ( FT_NEW( nn ) ) - goto Exit; - *bp = nn; - - nn->key = key; - nn->data = data; - - if ( ht->used >= ht->limit ) - { - error = hash_rehash( ht, memory ); - if ( error ) - goto Exit; - } - ht->used++; - } - else - nn->data = data; - - Exit: - return error; - } - - - static hashnode - hash_lookup( const char* key, - hashtable* ht ) - { - hashnode *np = hash_bucket( key, ht ); - - - return *np; - } - - - /*************************************************************************/ - /* */ - /* Utility types and functions. */ - /* */ - /*************************************************************************/ - - - /* Function type for parsing lines of a BDF font. */ - - typedef FT_Error - (*_bdf_line_func_t)( char* line, - unsigned long linelen, - unsigned long lineno, - void* call_data, - void* client_data ); - - - /* List structure for splitting lines into fields. */ - - typedef struct _bdf_list_t_ - { - char** field; - unsigned long size; - unsigned long used; - FT_Memory memory; - - } _bdf_list_t; - - - /* Structure used while loading BDF fonts. */ - - typedef struct _bdf_parse_t_ - { - unsigned long flags; - unsigned long cnt; - unsigned long row; - - short minlb; - short maxlb; - short maxrb; - short maxas; - short maxds; - - short rbearing; - - char* glyph_name; - long glyph_enc; - - bdf_font_t* font; - bdf_options_t* opts; - - unsigned long have[34816]; /* must be in sync with `nmod' and `umod' */ - /* arrays from `bdf_font_t' structure */ - _bdf_list_t list; - - FT_Memory memory; - - } _bdf_parse_t; - - -#define setsbit( m, cc ) \ - ( m[(FT_Byte)(cc) >> 3] |= (FT_Byte)( 1 << ( (cc) & 7 ) ) ) -#define sbitset( m, cc ) \ - ( m[(FT_Byte)(cc) >> 3] & ( 1 << ( (cc) & 7 ) ) ) - - - static void - _bdf_list_init( _bdf_list_t* list, - FT_Memory memory ) - { - FT_ZERO( list ); - list->memory = memory; - } - - - static void - _bdf_list_done( _bdf_list_t* list ) - { - FT_Memory memory = list->memory; - - - if ( memory ) - { - FT_FREE( list->field ); - FT_ZERO( list ); - } - } - - - static FT_Error - _bdf_list_ensure( _bdf_list_t* list, - unsigned long num_items ) /* same as _bdf_list_t.used */ - { - FT_Error error = FT_Err_Ok; - - - if ( num_items > list->size ) - { - unsigned long oldsize = list->size; /* same as _bdf_list_t.size */ - unsigned long newsize = oldsize + ( oldsize >> 1 ) + 5; - unsigned long bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) ); - FT_Memory memory = list->memory; - - - if ( oldsize == bigsize ) - { - error = FT_THROW( Out_Of_Memory ); - goto Exit; - } - else if ( newsize < oldsize || newsize > bigsize ) - newsize = bigsize; - - if ( FT_RENEW_ARRAY( list->field, oldsize, newsize ) ) - goto Exit; - - list->size = newsize; - } - - Exit: - return error; - } - - - static void - _bdf_list_shift( _bdf_list_t* list, - unsigned long n ) - { - unsigned long i, u; - - - if ( list == 0 || list->used == 0 || n == 0 ) - return; - - if ( n >= list->used ) - { - list->used = 0; - return; - } - - for ( u = n, i = 0; u < list->used; i++, u++ ) - list->field[i] = list->field[u]; - list->used -= n; - } - - - /* An empty string for empty fields. */ - - static const char empty[1] = { 0 }; /* XXX eliminate this */ - - - static char * - _bdf_list_join( _bdf_list_t* list, - int c, - unsigned long *alen ) - { - unsigned long i, j; - char* dp; - - - *alen = 0; - - if ( list == 0 || list->used == 0 ) - return 0; - - dp = list->field[0]; - for ( i = j = 0; i < list->used; i++ ) - { - char* fp = list->field[i]; - - - while ( *fp ) - dp[j++] = *fp++; - - if ( i + 1 < list->used ) - dp[j++] = (char)c; - } - if ( dp != empty ) - dp[j] = 0; - - *alen = j; - return dp; - } - - - /* The code below ensures that we have at least 4 + 1 `field' */ - /* elements in `list' (which are possibly NULL) so that we */ - /* don't have to check the number of fields in most cases. */ - - static FT_Error - _bdf_list_split( _bdf_list_t* list, - char* separators, - char* line, - unsigned long linelen ) - { - int mult, final_empty; - char *sp, *ep, *end; - char seps[32]; - FT_Error error = FT_Err_Ok; - - - /* Initialize the list. */ - list->used = 0; - if ( list->size ) - { - list->field[0] = (char*)empty; - list->field[1] = (char*)empty; - list->field[2] = (char*)empty; - list->field[3] = (char*)empty; - list->field[4] = (char*)empty; - } - - /* If the line is empty, then simply return. */ - if ( linelen == 0 || line[0] == 0 ) - goto Exit; - - /* In the original code, if the `separators' parameter is NULL or */ - /* empty, the list is split into individual bytes. We don't need */ - /* this, so an error is signaled. */ - if ( separators == 0 || *separators == 0 ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* Prepare the separator bitmap. */ - FT_MEM_ZERO( seps, 32 ); - - /* If the very last character of the separator string is a plus, then */ - /* set the `mult' flag to indicate that multiple separators should be */ - /* collapsed into one. */ - for ( mult = 0, sp = separators; sp && *sp; sp++ ) - { - if ( *sp == '+' && *( sp + 1 ) == 0 ) - mult = 1; - else - setsbit( seps, *sp ); - } - - /* Break the line up into fields. */ - for ( final_empty = 0, sp = ep = line, end = sp + linelen; - sp < end && *sp; ) - { - /* Collect everything that is not a separator. */ - for ( ; *ep && !sbitset( seps, *ep ); ep++ ) - ; - - /* Resize the list if necessary. */ - if ( list->used == list->size ) - { - error = _bdf_list_ensure( list, list->used + 1 ); - if ( error ) - goto Exit; - } - - /* Assign the field appropriately. */ - list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty; - - sp = ep; - - if ( mult ) - { - /* If multiple separators should be collapsed, do it now by */ - /* setting all the separator characters to 0. */ - for ( ; *ep && sbitset( seps, *ep ); ep++ ) - *ep = 0; - } - else if ( *ep != 0 ) - /* Don't collapse multiple separators by making them 0, so just */ - /* make the one encountered 0. */ - *ep++ = 0; - - final_empty = ( ep > sp && *ep == 0 ); - sp = ep; - } - - /* Finally, NULL-terminate the list. */ - if ( list->used + final_empty >= list->size ) - { - error = _bdf_list_ensure( list, list->used + final_empty + 1 ); - if ( error ) - goto Exit; - } - - if ( final_empty ) - list->field[list->used++] = (char*)empty; - - list->field[list->used] = 0; - - Exit: - return error; - } - - -#define NO_SKIP 256 /* this value cannot be stored in a 'char' */ - - - static FT_Error - _bdf_readstream( FT_Stream stream, - _bdf_line_func_t callback, - void* client_data, - unsigned long *lno ) - { - _bdf_line_func_t cb; - unsigned long lineno, buf_size; - int refill, hold, to_skip; - ptrdiff_t bytes, start, end, cursor, avail; - char* buf = 0; - FT_Memory memory = stream->memory; - FT_Error error = FT_Err_Ok; - - - if ( callback == 0 ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* initial size and allocation of the input buffer */ - buf_size = 1024; - - if ( FT_NEW_ARRAY( buf, buf_size ) ) - goto Exit; - - cb = callback; - lineno = 1; - buf[0] = 0; - start = 0; - end = 0; - avail = 0; - cursor = 0; - refill = 1; - to_skip = NO_SKIP; - bytes = 0; /* make compiler happy */ - - for (;;) - { - if ( refill ) - { - bytes = (ptrdiff_t)FT_Stream_TryRead( - stream, (FT_Byte*)buf + cursor, - (FT_ULong)( buf_size - cursor ) ); - avail = cursor + bytes; - cursor = 0; - refill = 0; - } - - end = start; - - /* should we skip an optional character like \n or \r? */ - if ( start < avail && buf[start] == to_skip ) - { - start += 1; - to_skip = NO_SKIP; - continue; - } - - /* try to find the end of the line */ - while ( end < avail && buf[end] != '\n' && buf[end] != '\r' ) - end++; - - /* if we hit the end of the buffer, try shifting its content */ - /* or even resizing it */ - if ( end >= avail ) - { - if ( bytes == 0 ) /* last line in file doesn't end in \r or \n */ - break; /* ignore it then exit */ - - if ( start == 0 ) - { - /* this line is definitely too long; try resizing the input */ - /* buffer a bit to handle it. */ - FT_ULong new_size; - - - if ( buf_size >= 65536UL ) /* limit ourselves to 64KByte */ - { - FT_ERROR(( "_bdf_readstream: " ERRMSG6, lineno )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - new_size = buf_size * 2; - if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) - goto Exit; - - cursor = buf_size; - buf_size = new_size; - } - else - { - bytes = avail - start; - - FT_MEM_MOVE( buf, buf + start, bytes ); - - cursor = bytes; - avail -= bytes; - start = 0; - } - refill = 1; - continue; - } - - /* Temporarily NUL-terminate the line. */ - hold = buf[end]; - buf[end] = 0; - - /* XXX: Use encoding independent value for 0x1a */ - if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) - { - error = (*cb)( buf + start, (unsigned long)( end - start ), lineno, - (void*)&cb, client_data ); - /* Redo if we have encountered CHARS without properties. */ - if ( error == -1 ) - error = (*cb)( buf + start, (unsigned long)( end - start ), lineno, - (void*)&cb, client_data ); - if ( error ) - break; - } - - lineno += 1; - buf[end] = (char)hold; - start = end + 1; - - if ( hold == '\n' ) - to_skip = '\r'; - else if ( hold == '\r' ) - to_skip = '\n'; - else - to_skip = NO_SKIP; - } - - *lno = lineno; - - Exit: - FT_FREE( buf ); - return error; - } - - - /* XXX: make this work with EBCDIC also */ - - static const unsigned char a2i[128] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - static const unsigned char odigits[32] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - static const unsigned char ddigits[32] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - static const unsigned char hdigits[32] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, - 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - - /* Routine to convert an ASCII string into an unsigned long integer. */ - static unsigned long - _bdf_atoul( char* s, - char** end, - int base ) - { - unsigned long v; - const unsigned char* dmap; - - - if ( s == 0 || *s == 0 ) - return 0; - - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = v * base + a2i[(int)*s]; - - if ( end != 0 ) - *end = s; - - return v; - } - - - /* Routine to convert an ASCII string into an signed long integer. */ - static long - _bdf_atol( char* s, - char** end, - int base ) - { - long v, neg; - const unsigned char* dmap; - - - if ( s == 0 || *s == 0 ) - return 0; - - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - - /* Check for a minus sign. */ - neg = 0; - if ( *s == '-' ) - { - s++; - neg = 1; - } - - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = v * base + a2i[(int)*s]; - - if ( end != 0 ) - *end = s; - - return ( !neg ) ? v : -v; - } - - - /* Routine to convert an ASCII string into an signed short integer. */ - static short - _bdf_atos( char* s, - char** end, - int base ) - { - short v, neg; - const unsigned char* dmap; - - - if ( s == 0 || *s == 0 ) - return 0; - - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - - /* Check for a minus. */ - neg = 0; - if ( *s == '-' ) - { - s++; - neg = 1; - } - - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = (short)( v * base + a2i[(int)*s] ); - - if ( end != 0 ) - *end = s; - - return (short)( ( !neg ) ? v : -v ); - } - - - /* Routine to compare two glyphs by encoding so they can be sorted. */ - static int - by_encoding( const void* a, - const void* b ) - { - bdf_glyph_t *c1, *c2; - - - c1 = (bdf_glyph_t *)a; - c2 = (bdf_glyph_t *)b; - - if ( c1->encoding < c2->encoding ) - return -1; - - if ( c1->encoding > c2->encoding ) - return 1; - - return 0; - } - - - static FT_Error - bdf_create_property( char* name, - int format, - bdf_font_t* font ) - { - size_t n; - bdf_property_t* p; - FT_Memory memory = font->memory; - FT_Error error = FT_Err_Ok; - - - /* First check whether the property has */ - /* already been added or not. If it has, then */ - /* simply ignore it. */ - if ( hash_lookup( name, &(font->proptbl) ) ) - goto Exit; - - if ( FT_RENEW_ARRAY( font->user_props, - font->nuser_props, - font->nuser_props + 1 ) ) - goto Exit; - - p = font->user_props + font->nuser_props; - FT_ZERO( p ); - - n = ft_strlen( name ) + 1; - if ( n > FT_ULONG_MAX ) - return FT_THROW( Invalid_Argument ); - - if ( FT_NEW_ARRAY( p->name, n ) ) - goto Exit; - - FT_MEM_COPY( (char *)p->name, name, n ); - - p->format = format; - p->builtin = 0; - - n = _num_bdf_properties + font->nuser_props; - - error = hash_insert( p->name, n, &(font->proptbl), memory ); - if ( error ) - goto Exit; - - font->nuser_props++; - - Exit: - return error; - } - - - FT_LOCAL_DEF( bdf_property_t * ) - bdf_get_property( char* name, - bdf_font_t* font ) - { - hashnode hn; - size_t propid; - - - if ( name == 0 || *name == 0 ) - return 0; - - if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) - return 0; - - propid = hn->data; - if ( propid >= _num_bdf_properties ) - return font->user_props + ( propid - _num_bdf_properties ); - - return (bdf_property_t*)_bdf_properties + propid; - } - - - /*************************************************************************/ - /* */ - /* BDF font file parsing flags and functions. */ - /* */ - /*************************************************************************/ - - - /* Parse flags. */ - -#define _BDF_START 0x0001 -#define _BDF_FONT_NAME 0x0002 -#define _BDF_SIZE 0x0004 -#define _BDF_FONT_BBX 0x0008 -#define _BDF_PROPS 0x0010 -#define _BDF_GLYPHS 0x0020 -#define _BDF_GLYPH 0x0040 -#define _BDF_ENCODING 0x0080 -#define _BDF_SWIDTH 0x0100 -#define _BDF_DWIDTH 0x0200 -#define _BDF_BBX 0x0400 -#define _BDF_BITMAP 0x0800 - -#define _BDF_SWIDTH_ADJ 0x1000 - -#define _BDF_GLYPH_BITS ( _BDF_GLYPH | \ - _BDF_ENCODING | \ - _BDF_SWIDTH | \ - _BDF_DWIDTH | \ - _BDF_BBX | \ - _BDF_BITMAP ) - -#define _BDF_GLYPH_WIDTH_CHECK 0x40000000UL -#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000UL - - - static FT_Error - _bdf_add_comment( bdf_font_t* font, - char* comment, - unsigned long len ) - { - char* cp; - FT_Memory memory = font->memory; - FT_Error error = FT_Err_Ok; - - - if ( FT_RENEW_ARRAY( font->comments, - font->comments_len, - font->comments_len + len + 1 ) ) - goto Exit; - - cp = font->comments + font->comments_len; - - FT_MEM_COPY( cp, comment, len ); - cp[len] = '\n'; - - font->comments_len += len + 1; - - Exit: - return error; - } - - - /* Set the spacing from the font name if it exists, or set it to the */ - /* default specified in the options. */ - static FT_Error - _bdf_set_default_spacing( bdf_font_t* font, - bdf_options_t* opts, - unsigned long lineno ) - { - size_t len; - char name[256]; - _bdf_list_t list; - FT_Memory memory; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( lineno ); /* only used in debug mode */ - - - if ( font == 0 || font->name == 0 || font->name[0] == 0 ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - memory = font->memory; - - _bdf_list_init( &list, memory ); - - font->spacing = opts->font_spacing; - - len = ft_strlen( font->name ) + 1; - /* Limit ourselves to 256 characters in the font name. */ - if ( len >= 256 ) - { - FT_ERROR(( "_bdf_set_default_spacing: " ERRMSG7, lineno )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - FT_MEM_COPY( name, font->name, len ); - - error = _bdf_list_split( &list, (char *)"-", name, (unsigned long)len ); - if ( error ) - goto Fail; - - if ( list.used == 15 ) - { - switch ( list.field[11][0] ) - { - case 'C': - case 'c': - font->spacing = BDF_CHARCELL; - break; - case 'M': - case 'm': - font->spacing = BDF_MONOWIDTH; - break; - case 'P': - case 'p': - font->spacing = BDF_PROPORTIONAL; - break; - } - } - - Fail: - _bdf_list_done( &list ); - - Exit: - return error; - } - - - /* Determine whether the property is an atom or not. If it is, then */ - /* clean it up so the double quotes are removed if they exist. */ - static int - _bdf_is_atom( char* line, - unsigned long linelen, - char** name, - char** value, - bdf_font_t* font ) - { - int hold; - char *sp, *ep; - bdf_property_t* p; - - - *name = sp = ep = line; - - while ( *ep && *ep != ' ' && *ep != '\t' ) - ep++; - - hold = -1; - if ( *ep ) - { - hold = *ep; - *ep = 0; - } - - p = bdf_get_property( sp, font ); - - /* Restore the character that was saved before any return can happen. */ - if ( hold != -1 ) - *ep = (char)hold; - - /* If the property exists and is not an atom, just return here. */ - if ( p && p->format != BDF_ATOM ) - return 0; - - /* The property is an atom. Trim all leading and trailing whitespace */ - /* and double quotes for the atom value. */ - sp = ep; - ep = line + linelen; - - /* Trim the leading whitespace if it exists. */ - if ( *sp ) - *sp++ = 0; - while ( *sp && - ( *sp == ' ' || *sp == '\t' ) ) - sp++; - - /* Trim the leading double quote if it exists. */ - if ( *sp == '"' ) - sp++; - *value = sp; - - /* Trim the trailing whitespace if it exists. */ - while ( ep > sp && - ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) ) - *--ep = 0; - - /* Trim the trailing double quote if it exists. */ - if ( ep > sp && *( ep - 1 ) == '"' ) - *--ep = 0; - - return 1; - } - - - static FT_Error - _bdf_add_property( bdf_font_t* font, - char* name, - char* value, - unsigned long lineno ) - { - size_t propid; - hashnode hn; - bdf_property_t *prop, *fp; - FT_Memory memory = font->memory; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( lineno ); /* only used in debug mode */ - - - /* First, check whether the property already exists in the font. */ - if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 ) - { - /* The property already exists in the font, so simply replace */ - /* the value of the property with the current value. */ - fp = font->props + hn->data; - - switch ( fp->format ) - { - case BDF_ATOM: - /* Delete the current atom if it exists. */ - FT_FREE( fp->value.atom ); - - if ( value && value[0] != 0 ) - { - if ( FT_STRDUP( fp->value.atom, value ) ) - goto Exit; - } - break; - - case BDF_INTEGER: - fp->value.l = _bdf_atol( value, 0, 10 ); - break; - - case BDF_CARDINAL: - fp->value.ul = _bdf_atoul( value, 0, 10 ); - break; - - default: - ; - } - - goto Exit; - } - - /* See whether this property type exists yet or not. */ - /* If not, create it. */ - hn = hash_lookup( name, &(font->proptbl) ); - if ( hn == 0 ) - { - error = bdf_create_property( name, BDF_ATOM, font ); - if ( error ) - goto Exit; - hn = hash_lookup( name, &(font->proptbl) ); - } - - /* Allocate another property if this is overflow. */ - if ( font->props_used == font->props_size ) - { - if ( font->props_size == 0 ) - { - if ( FT_NEW_ARRAY( font->props, 1 ) ) - goto Exit; - } - else - { - if ( FT_RENEW_ARRAY( font->props, - font->props_size, - font->props_size + 1 ) ) - goto Exit; - } - - fp = font->props + font->props_size; - FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) ); - font->props_size++; - } - - propid = hn->data; - if ( propid >= _num_bdf_properties ) - prop = font->user_props + ( propid - _num_bdf_properties ); - else - prop = (bdf_property_t*)_bdf_properties + propid; - - fp = font->props + font->props_used; - - fp->name = prop->name; - fp->format = prop->format; - fp->builtin = prop->builtin; - - switch ( prop->format ) - { - case BDF_ATOM: - fp->value.atom = 0; - if ( value != 0 && value[0] ) - { - if ( FT_STRDUP( fp->value.atom, value ) ) - goto Exit; - } - break; - - case BDF_INTEGER: - fp->value.l = _bdf_atol( value, 0, 10 ); - break; - - case BDF_CARDINAL: - fp->value.ul = _bdf_atoul( value, 0, 10 ); - break; - } - - /* If the property happens to be a comment, then it doesn't need */ - /* to be added to the internal hash table. */ - if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) - { - /* Add the property to the font property table. */ - error = hash_insert( fp->name, - font->props_used, - (hashtable *)font->internal, - memory ); - if ( error ) - goto Exit; - } - - font->props_used++; - - /* Some special cases need to be handled here. The DEFAULT_CHAR */ - /* property needs to be located if it exists in the property list, the */ - /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are */ - /* present, and the SPACING property should override the default */ - /* spacing. */ - if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 ) - font->default_char = fp->value.l; - else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 ) - font->font_ascent = fp->value.l; - else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 ) - font->font_descent = fp->value.l; - else if ( ft_memcmp( name, "SPACING", 7 ) == 0 ) - { - if ( !fp->value.atom ) - { - FT_ERROR(( "_bdf_add_property: " ERRMSG8, lineno, "SPACING" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' ) - font->spacing = BDF_PROPORTIONAL; - else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' ) - font->spacing = BDF_MONOWIDTH; - else if ( fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C' ) - font->spacing = BDF_CHARCELL; - } - - Exit: - return error; - } - - - static const unsigned char nibble_mask[8] = - { - 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE - }; - - - /* Actually parse the glyph info and bitmaps. */ - static FT_Error - _bdf_parse_glyphs( char* line, - unsigned long linelen, - unsigned long lineno, - void* call_data, - void* client_data ) - { - int c, mask_index; - char* s; - unsigned char* bp; - unsigned long i, slen, nibbles; - - _bdf_parse_t* p; - bdf_glyph_t* glyph; - bdf_font_t* font; - - FT_Memory memory; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( call_data ); - FT_UNUSED( lineno ); /* only used in debug mode */ - - - p = (_bdf_parse_t *)client_data; - - font = p->font; - memory = font->memory; - - /* Check for a comment. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) - { - linelen -= 7; - - s = line + 7; - if ( *s != 0 ) - { - s++; - linelen--; - } - error = _bdf_add_comment( p->font, s, linelen ); - goto Exit; - } - - /* The very first thing expected is the number of glyphs. */ - if ( !( p->flags & _BDF_GLYPHS ) ) - { - if ( ft_memcmp( line, "CHARS", 5 ) != 0 ) - { - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" )); - error = FT_THROW( Missing_Chars_Field ); - goto Exit; - } - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 ); - - /* Make sure the number of glyphs is non-zero. */ - if ( p->cnt == 0 ) - font->glyphs_size = 64; - - /* Limit ourselves to 1,114,112 glyphs in the font (this is the */ - /* number of code points available in Unicode). */ - if ( p->cnt >= 0x110000UL ) - { - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "CHARS" )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) ) - goto Exit; - - p->flags |= _BDF_GLYPHS; - - goto Exit; - } - - /* Check for the ENDFONT field. */ - if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 ) - { - /* Sort the glyphs by encoding. */ - ft_qsort( (char *)font->glyphs, - font->glyphs_used, - sizeof ( bdf_glyph_t ), - by_encoding ); - - p->flags &= ~_BDF_START; - - goto Exit; - } - - /* Check for the ENDCHAR field. */ - if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 ) - { - p->glyph_enc = 0; - p->flags &= ~_BDF_GLYPH_BITS; - - goto Exit; - } - - /* Check whether a glyph is being scanned but should be */ - /* ignored because it is an unencoded glyph. */ - if ( ( p->flags & _BDF_GLYPH ) && - p->glyph_enc == -1 && - p->opts->keep_unencoded == 0 ) - goto Exit; - - /* Check for the STARTCHAR field. */ - if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 ) - { - /* Set the character name in the parse info first until the */ - /* encoding can be checked for an unencoded character. */ - FT_FREE( p->glyph_name ); - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - - _bdf_list_shift( &p->list, 1 ); - - s = _bdf_list_join( &p->list, ' ', &slen ); - - if ( !s ) - { - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG8, lineno, "STARTCHAR" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) ) - goto Exit; - - FT_MEM_COPY( p->glyph_name, s, slen + 1 ); - - p->flags |= _BDF_GLYPH; - - FT_TRACE4(( DBGMSG1, lineno, s )); - - goto Exit; - } - - /* Check for the ENCODING field. */ - if ( ft_memcmp( line, "ENCODING", 8 ) == 0 ) - { - if ( !( p->flags & _BDF_GLYPH ) ) - { - /* Missing STARTCHAR field. */ - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" )); - error = FT_THROW( Missing_Startchar_Field ); - goto Exit; - } - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - - p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 ); - - /* Normalize negative encoding values. The specification only */ - /* allows -1, but we can be more generous here. */ - if ( p->glyph_enc < -1 ) - p->glyph_enc = -1; - - /* Check for alternative encoding format. */ - if ( p->glyph_enc == -1 && p->list.used > 2 ) - p->glyph_enc = _bdf_atol( p->list.field[2], 0, 10 ); - - if ( p->glyph_enc < -1 ) - p->glyph_enc = -1; - - FT_TRACE4(( DBGMSG2, p->glyph_enc )); - - /* Check that the encoding is in the Unicode range because */ - /* otherwise p->have (a bitmap with static size) overflows. */ - if ( p->glyph_enc > 0 && - (size_t)p->glyph_enc >= sizeof ( p->have ) / - sizeof ( unsigned long ) * 32 ) - { - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "ENCODING" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* Check whether this encoding has already been encountered. */ - /* If it has then change it to unencoded so it gets added if */ - /* indicated. */ - if ( p->glyph_enc >= 0 ) - { - if ( _bdf_glyph_modified( p->have, p->glyph_enc ) ) - { - /* Emit a message saying a glyph has been moved to the */ - /* unencoded area. */ - FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12, - p->glyph_enc, p->glyph_name )); - p->glyph_enc = -1; - font->modified = 1; - } - else - _bdf_set_glyph_modified( p->have, p->glyph_enc ); - } - - if ( p->glyph_enc >= 0 ) - { - /* Make sure there are enough glyphs allocated in case the */ - /* number of characters happen to be wrong. */ - if ( font->glyphs_used == font->glyphs_size ) - { - if ( FT_RENEW_ARRAY( font->glyphs, - font->glyphs_size, - font->glyphs_size + 64 ) ) - goto Exit; - - font->glyphs_size += 64; - } - - glyph = font->glyphs + font->glyphs_used++; - glyph->name = p->glyph_name; - glyph->encoding = p->glyph_enc; - - /* Reset the initial glyph info. */ - p->glyph_name = 0; - } - else - { - /* Unencoded glyph. Check whether it should */ - /* be added or not. */ - if ( p->opts->keep_unencoded != 0 ) - { - /* Allocate the next unencoded glyph. */ - if ( font->unencoded_used == font->unencoded_size ) - { - if ( FT_RENEW_ARRAY( font->unencoded , - font->unencoded_size, - font->unencoded_size + 4 ) ) - goto Exit; - - font->unencoded_size += 4; - } - - glyph = font->unencoded + font->unencoded_used; - glyph->name = p->glyph_name; - glyph->encoding = font->unencoded_used++; - } - else - /* Free up the glyph name if the unencoded shouldn't be */ - /* kept. */ - FT_FREE( p->glyph_name ); - - p->glyph_name = 0; - } - - /* Clear the flags that might be added when width and height are */ - /* checked for consistency. */ - p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK ); - - p->flags |= _BDF_ENCODING; - - goto Exit; - } - - /* Point at the glyph being constructed. */ - if ( p->glyph_enc == -1 ) - glyph = font->unencoded + ( font->unencoded_used - 1 ); - else - glyph = font->glyphs + ( font->glyphs_used - 1 ); - - /* Check whether a bitmap is being constructed. */ - if ( p->flags & _BDF_BITMAP ) - { - /* If there are more rows than are specified in the glyph metrics, */ - /* ignore the remaining lines. */ - if ( p->row >= (unsigned long)glyph->bbx.height ) - { - if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) ) - { - FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding )); - p->flags |= _BDF_GLYPH_HEIGHT_CHECK; - font->modified = 1; - } - - goto Exit; - } - - /* Only collect the number of nibbles indicated by the glyph */ - /* metrics. If there are more columns, they are simply ignored. */ - nibbles = glyph->bpr << 1; - bp = glyph->bitmap + p->row * glyph->bpr; - - for ( i = 0; i < nibbles; i++ ) - { - c = line[i]; - if ( !sbitset( hdigits, c ) ) - break; - *bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] ); - if ( i + 1 < nibbles && ( i & 1 ) ) - *++bp = 0; - } - - /* If any line has not enough columns, */ - /* indicate they have been padded with zero bits. */ - if ( i < nibbles && - !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) - { - FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding )); - p->flags |= _BDF_GLYPH_WIDTH_CHECK; - font->modified = 1; - } - - /* Remove possible garbage at the right. */ - mask_index = ( glyph->bbx.width * p->font->bpp ) & 7; - if ( glyph->bbx.width ) - *bp &= nibble_mask[mask_index]; - - /* If any line has extra columns, indicate they have been removed. */ - if ( i == nibbles && - sbitset( hdigits, line[nibbles] ) && - !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) - { - FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); - p->flags |= _BDF_GLYPH_WIDTH_CHECK; - font->modified = 1; - } - - p->row++; - goto Exit; - } - - /* Expect the SWIDTH (scalable width) field next. */ - if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 ) - { - if ( !( p->flags & _BDF_ENCODING ) ) - goto Missing_Encoding; - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - - glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); - p->flags |= _BDF_SWIDTH; - - goto Exit; - } - - /* Expect the DWIDTH (scalable width) field next. */ - if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) - { - if ( !( p->flags & _BDF_ENCODING ) ) - goto Missing_Encoding; - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - - glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); - - if ( !( p->flags & _BDF_SWIDTH ) ) - { - /* Missing SWIDTH field. Emit an auto correction message and set */ - /* the scalable width from the device width. */ - FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG9, lineno )); - - glyph->swidth = (unsigned short)FT_MulDiv( - glyph->dwidth, 72000L, - (FT_Long)( font->point_size * - font->resolution_x ) ); - } - - p->flags |= _BDF_DWIDTH; - goto Exit; - } - - /* Expect the BBX field next. */ - if ( ft_memcmp( line, "BBX", 3 ) == 0 ) - { - if ( !( p->flags & _BDF_ENCODING ) ) - goto Missing_Encoding; - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - - glyph->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); - glyph->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); - glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); - glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); - - /* Generate the ascent and descent of the character. */ - glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset ); - glyph->bbx.descent = (short)( -glyph->bbx.y_offset ); - - /* Determine the overall font bounding box as the characters are */ - /* loaded so corrections can be done later if indicated. */ - p->maxas = (short)FT_MAX( glyph->bbx.ascent, p->maxas ); - p->maxds = (short)FT_MAX( glyph->bbx.descent, p->maxds ); - - p->rbearing = (short)( glyph->bbx.width + glyph->bbx.x_offset ); - - p->maxrb = (short)FT_MAX( p->rbearing, p->maxrb ); - p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb ); - p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb ); - - if ( !( p->flags & _BDF_DWIDTH ) ) - { - /* Missing DWIDTH field. Emit an auto correction message and set */ - /* the device width to the glyph width. */ - FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG10, lineno )); - glyph->dwidth = glyph->bbx.width; - } - - /* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */ - /* value if necessary. */ - if ( p->opts->correct_metrics != 0 ) - { - /* Determine the point size of the glyph. */ - unsigned short sw = (unsigned short)FT_MulDiv( - glyph->dwidth, 72000L, - (FT_Long)( font->point_size * - font->resolution_x ) ); - - - if ( sw != glyph->swidth ) - { - glyph->swidth = sw; - - if ( p->glyph_enc == -1 ) - _bdf_set_glyph_modified( font->umod, - font->unencoded_used - 1 ); - else - _bdf_set_glyph_modified( font->nmod, glyph->encoding ); - - p->flags |= _BDF_SWIDTH_ADJ; - font->modified = 1; - } - } - - p->flags |= _BDF_BBX; - goto Exit; - } - - /* And finally, gather up the bitmap. */ - if ( ft_memcmp( line, "BITMAP", 6 ) == 0 ) - { - unsigned long bitmap_size; - - - if ( !( p->flags & _BDF_BBX ) ) - { - /* Missing BBX field. */ - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" )); - error = FT_THROW( Missing_Bbx_Field ); - goto Exit; - } - - /* Allocate enough space for the bitmap. */ - glyph->bpr = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3; - - bitmap_size = glyph->bpr * glyph->bbx.height; - if ( glyph->bpr > 0xFFFFU || bitmap_size > 0xFFFFU ) - { - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG4, lineno )); - error = FT_THROW( Bbx_Too_Big ); - goto Exit; - } - else - glyph->bytes = (unsigned short)bitmap_size; - - if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) ) - goto Exit; - - p->row = 0; - p->flags |= _BDF_BITMAP; - - goto Exit; - } - - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG9, lineno )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - - Missing_Encoding: - /* Missing ENCODING field. */ - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" )); - error = FT_THROW( Missing_Encoding_Field ); - - Exit: - if ( error && ( p->flags & _BDF_GLYPH ) ) - FT_FREE( p->glyph_name ); - - return error; - } - - - /* Load the font properties. */ - static FT_Error - _bdf_parse_properties( char* line, - unsigned long linelen, - unsigned long lineno, - void* call_data, - void* client_data ) - { - unsigned long vlen; - _bdf_line_func_t* next; - _bdf_parse_t* p; - char* name; - char* value; - char nbuf[128]; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( lineno ); - - - next = (_bdf_line_func_t *)call_data; - p = (_bdf_parse_t *) client_data; - - /* Check for the end of the properties. */ - if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 ) - { - /* If the FONT_ASCENT or FONT_DESCENT properties have not been */ - /* encountered yet, then make sure they are added as properties and */ - /* make sure they are set from the font bounding box info. */ - /* */ - /* This is *always* done regardless of the options, because X11 */ - /* requires these two fields to compile fonts. */ - if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 ) - { - p->font->font_ascent = p->font->bbx.ascent; - ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); - error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", - nbuf, lineno ); - if ( error ) - goto Exit; - - FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent )); - p->font->modified = 1; - } - - if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 ) - { - p->font->font_descent = p->font->bbx.descent; - ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); - error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", - nbuf, lineno ); - if ( error ) - goto Exit; - - FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent )); - p->font->modified = 1; - } - - p->flags &= ~_BDF_PROPS; - *next = _bdf_parse_glyphs; - - goto Exit; - } - - /* Ignore the _XFREE86_GLYPH_RANGES properties. */ - if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 ) - goto Exit; - - /* Handle COMMENT fields and properties in a special way to preserve */ - /* the spacing. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) - { - name = value = line; - value += 7; - if ( *value ) - *value++ = 0; - error = _bdf_add_property( p->font, name, value, lineno ); - if ( error ) - goto Exit; - } - else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) ) - { - error = _bdf_add_property( p->font, name, value, lineno ); - if ( error ) - goto Exit; - } - else - { - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - name = p->list.field[0]; - - _bdf_list_shift( &p->list, 1 ); - value = _bdf_list_join( &p->list, ' ', &vlen ); - - error = _bdf_add_property( p->font, name, value, lineno ); - if ( error ) - goto Exit; - } - - Exit: - return error; - } - - - /* Load the font header. */ - static FT_Error - _bdf_parse_start( char* line, - unsigned long linelen, - unsigned long lineno, - void* call_data, - void* client_data ) - { - unsigned long slen; - _bdf_line_func_t* next; - _bdf_parse_t* p; - bdf_font_t* font; - char *s; - - FT_Memory memory = NULL; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( lineno ); /* only used in debug mode */ - - - next = (_bdf_line_func_t *)call_data; - p = (_bdf_parse_t *) client_data; - - if ( p->font ) - memory = p->font->memory; - - /* Check for a comment. This is done to handle those fonts that have */ - /* comments before the STARTFONT line for some reason. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) - { - if ( p->opts->keep_comments != 0 && p->font != 0 ) - { - linelen -= 7; - - s = line + 7; - if ( *s != 0 ) - { - s++; - linelen--; - } - - error = _bdf_add_comment( p->font, s, linelen ); - if ( error ) - goto Exit; - /* here font is not defined! */ - } - - goto Exit; - } - - if ( !( p->flags & _BDF_START ) ) - { - memory = p->memory; - - if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 ) - { - /* we don't emit an error message since this code gets */ - /* explicitly caught one level higher */ - error = FT_THROW( Missing_Startfont_Field ); - goto Exit; - } - - p->flags = _BDF_START; - font = p->font = 0; - - if ( FT_NEW( font ) ) - goto Exit; - p->font = font; - - font->memory = p->memory; - p->memory = 0; - - { /* setup */ - size_t i; - bdf_property_t* prop; - - - error = hash_init( &(font->proptbl), memory ); - if ( error ) - goto Exit; - for ( i = 0, prop = (bdf_property_t*)_bdf_properties; - i < _num_bdf_properties; i++, prop++ ) - { - error = hash_insert( prop->name, i, - &(font->proptbl), memory ); - if ( error ) - goto Exit; - } - } - - if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) ) - goto Exit; - error = hash_init( (hashtable *)p->font->internal,memory ); - if ( error ) - goto Exit; - p->font->spacing = p->opts->font_spacing; - p->font->default_char = -1; - - goto Exit; - } - - /* Check for the start of the properties. */ - if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 ) - { - if ( !( p->flags & _BDF_FONT_BBX ) ) - { - /* Missing the FONTBOUNDINGBOX field. */ - FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); - error = FT_THROW( Missing_Fontboundingbox_Field ); - goto Exit; - } - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - /* at this point, `p->font' can't be NULL */ - p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); - - if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) - { - p->font->props_size = 0; - goto Exit; - } - - p->flags |= _BDF_PROPS; - *next = _bdf_parse_properties; - - goto Exit; - } - - /* Check for the FONTBOUNDINGBOX field. */ - if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) - { - if ( !( p->flags & _BDF_SIZE ) ) - { - /* Missing the SIZE field. */ - FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" )); - error = FT_THROW( Missing_Size_Field ); - goto Exit; - } - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - - p->font->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); - p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); - - p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); - p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); - - p->font->bbx.ascent = (short)( p->font->bbx.height + - p->font->bbx.y_offset ); - - p->font->bbx.descent = (short)( -p->font->bbx.y_offset ); - - p->flags |= _BDF_FONT_BBX; - - goto Exit; - } - - /* The next thing to check for is the FONT field. */ - if ( ft_memcmp( line, "FONT", 4 ) == 0 ) - { - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - _bdf_list_shift( &p->list, 1 ); - - s = _bdf_list_join( &p->list, ' ', &slen ); - - if ( !s ) - { - FT_ERROR(( "_bdf_parse_start: " ERRMSG8, lineno, "FONT" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */ - FT_FREE( p->font->name ); - - if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) ) - goto Exit; - FT_MEM_COPY( p->font->name, s, slen + 1 ); - - /* If the font name is an XLFD name, set the spacing to the one in */ - /* the font name. If there is no spacing fall back on the default. */ - error = _bdf_set_default_spacing( p->font, p->opts, lineno ); - if ( error ) - goto Exit; - - p->flags |= _BDF_FONT_NAME; - - goto Exit; - } - - /* Check for the SIZE field. */ - if ( ft_memcmp( line, "SIZE", 4 ) == 0 ) - { - if ( !( p->flags & _BDF_FONT_NAME ) ) - { - /* Missing the FONT field. */ - FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" )); - error = FT_THROW( Missing_Font_Field ); - goto Exit; - } - - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); - if ( error ) - goto Exit; - - p->font->point_size = _bdf_atoul( p->list.field[1], 0, 10 ); - p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 ); - p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 ); - - /* Check for the bits per pixel field. */ - if ( p->list.used == 5 ) - { - unsigned short bitcount, i, shift; - - - p->font->bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 ); - - /* Only values 1, 2, 4, 8 are allowed. */ - shift = p->font->bpp; - bitcount = 0; - for ( i = 0; shift > 0; i++ ) - { - if ( shift & 1 ) - bitcount = i; - shift >>= 1; - } - - shift = (short)( ( bitcount > 3 ) ? 8 : ( 1 << bitcount ) ); - - if ( p->font->bpp > shift || p->font->bpp != shift ) - { - /* select next higher value */ - p->font->bpp = (unsigned short)( shift << 1 ); - FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp )); - } - } - else - p->font->bpp = 1; - - p->flags |= _BDF_SIZE; - - goto Exit; - } - - /* Check for the CHARS field -- font properties are optional */ - if ( ft_memcmp( line, "CHARS", 5 ) == 0 ) - { - char nbuf[128]; - - - if ( !( p->flags & _BDF_FONT_BBX ) ) - { - /* Missing the FONTBOUNDINGBOX field. */ - FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); - error = FT_THROW( Missing_Fontboundingbox_Field ); - goto Exit; - } - - /* Add the two standard X11 properties which are required */ - /* for compiling fonts. */ - p->font->font_ascent = p->font->bbx.ascent; - ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); - error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", - nbuf, lineno ); - if ( error ) - goto Exit; - FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent )); - - p->font->font_descent = p->font->bbx.descent; - ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); - error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", - nbuf, lineno ); - if ( error ) - goto Exit; - FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent )); - - p->font->modified = 1; - - *next = _bdf_parse_glyphs; - - /* A special return value. */ - error = -1; - goto Exit; - } - - FT_ERROR(( "_bdf_parse_start: " ERRMSG9, lineno )); - error = FT_THROW( Invalid_File_Format ); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* API. */ - /* */ - /*************************************************************************/ - - - FT_LOCAL_DEF( FT_Error ) - bdf_load_font( FT_Stream stream, - FT_Memory extmemory, - bdf_options_t* opts, - bdf_font_t* *font ) - { - unsigned long lineno = 0; /* make compiler happy */ - _bdf_parse_t *p = NULL; - - FT_Memory memory = extmemory; - FT_Error error = FT_Err_Ok; - - - if ( FT_NEW( p ) ) - goto Exit; - - memory = NULL; - p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); - p->minlb = 32767; - p->memory = extmemory; /* only during font creation */ - - _bdf_list_init( &p->list, extmemory ); - - error = _bdf_readstream( stream, _bdf_parse_start, - (void *)p, &lineno ); - if ( error ) - goto Fail; - - if ( p->font != 0 ) - { - /* If the font is not proportional, set the font's monowidth */ - /* field to the width of the font bounding box. */ - memory = p->font->memory; - - if ( p->font->spacing != BDF_PROPORTIONAL ) - p->font->monowidth = p->font->bbx.width; - - /* If the number of glyphs loaded is not that of the original count, */ - /* indicate the difference. */ - if ( p->cnt != p->font->glyphs_used + p->font->unencoded_used ) - { - FT_TRACE2(( "bdf_load_font: " ACMSG15, p->cnt, - p->font->glyphs_used + p->font->unencoded_used )); - p->font->modified = 1; - } - - /* Once the font has been loaded, adjust the overall font metrics if */ - /* necessary. */ - if ( p->opts->correct_metrics != 0 && - ( p->font->glyphs_used > 0 || p->font->unencoded_used > 0 ) ) - { - if ( p->maxrb - p->minlb != p->font->bbx.width ) - { - FT_TRACE2(( "bdf_load_font: " ACMSG3, - p->font->bbx.width, p->maxrb - p->minlb )); - p->font->bbx.width = (unsigned short)( p->maxrb - p->minlb ); - p->font->modified = 1; - } - - if ( p->font->bbx.x_offset != p->minlb ) - { - FT_TRACE2(( "bdf_load_font: " ACMSG4, - p->font->bbx.x_offset, p->minlb )); - p->font->bbx.x_offset = p->minlb; - p->font->modified = 1; - } - - if ( p->font->bbx.ascent != p->maxas ) - { - FT_TRACE2(( "bdf_load_font: " ACMSG5, - p->font->bbx.ascent, p->maxas )); - p->font->bbx.ascent = p->maxas; - p->font->modified = 1; - } - - if ( p->font->bbx.descent != p->maxds ) - { - FT_TRACE2(( "bdf_load_font: " ACMSG6, - p->font->bbx.descent, p->maxds )); - p->font->bbx.descent = p->maxds; - p->font->bbx.y_offset = (short)( -p->maxds ); - p->font->modified = 1; - } - - if ( p->maxas + p->maxds != p->font->bbx.height ) - { - FT_TRACE2(( "bdf_load_font: " ACMSG7, - p->font->bbx.height, p->maxas + p->maxds )); - p->font->bbx.height = (unsigned short)( p->maxas + p->maxds ); - } - - if ( p->flags & _BDF_SWIDTH_ADJ ) - FT_TRACE2(( "bdf_load_font: " ACMSG8 )); - } - } - - if ( p->flags & _BDF_START ) - { - /* The ENDFONT field was never reached or did not exist. */ - if ( !( p->flags & _BDF_GLYPHS ) ) - { - /* Error happened while parsing header. */ - FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); - error = FT_THROW( Corrupted_Font_Header ); - goto Exit; - } - else - { - /* Error happened when parsing glyphs. */ - FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); - error = FT_THROW( Corrupted_Font_Glyphs ); - goto Exit; - } - } - - if ( p->font != 0 ) - { - /* Make sure the comments are NULL terminated if they exist. */ - memory = p->font->memory; - - if ( p->font->comments_len > 0 ) - { - if ( FT_RENEW_ARRAY( p->font->comments, - p->font->comments_len, - p->font->comments_len + 1 ) ) - goto Fail; - - p->font->comments[p->font->comments_len] = 0; - } - } - else if ( error == FT_Err_Ok ) - error = FT_THROW( Invalid_File_Format ); - - *font = p->font; - - Exit: - if ( p ) - { - _bdf_list_done( &p->list ); - - memory = extmemory; - - FT_FREE( p ); - } - - return error; - - Fail: - bdf_free_font( p->font ); - - memory = extmemory; - - FT_FREE( p->font ); - - goto Exit; - } - - - FT_LOCAL_DEF( void ) - bdf_free_font( bdf_font_t* font ) - { - bdf_property_t* prop; - unsigned long i; - bdf_glyph_t* glyphs; - FT_Memory memory; - - - if ( font == 0 ) - return; - - memory = font->memory; - - FT_FREE( font->name ); - - /* Free up the internal hash table of property names. */ - if ( font->internal ) - { - hash_free( (hashtable *)font->internal, memory ); - FT_FREE( font->internal ); - } - - /* Free up the comment info. */ - FT_FREE( font->comments ); - - /* Free up the properties. */ - for ( i = 0; i < font->props_size; i++ ) - { - if ( font->props[i].format == BDF_ATOM ) - FT_FREE( font->props[i].value.atom ); - } - - FT_FREE( font->props ); - - /* Free up the character info. */ - for ( i = 0, glyphs = font->glyphs; - i < font->glyphs_used; i++, glyphs++ ) - { - FT_FREE( glyphs->name ); - FT_FREE( glyphs->bitmap ); - } - - for ( i = 0, glyphs = font->unencoded; i < font->unencoded_used; - i++, glyphs++ ) - { - FT_FREE( glyphs->name ); - FT_FREE( glyphs->bitmap ); - } - - FT_FREE( font->glyphs ); - FT_FREE( font->unencoded ); - - /* Free up the overflow storage if it was used. */ - for ( i = 0, glyphs = font->overflow.glyphs; - i < font->overflow.glyphs_used; i++, glyphs++ ) - { - FT_FREE( glyphs->name ); - FT_FREE( glyphs->bitmap ); - } - - FT_FREE( font->overflow.glyphs ); - - /* bdf_cleanup */ - hash_free( &(font->proptbl), memory ); - - /* Free up the user defined properties. */ - for ( prop = font->user_props, i = 0; - i < font->nuser_props; i++, prop++ ) - { - FT_FREE( prop->name ); - if ( prop->format == BDF_ATOM ) - FT_FREE( prop->value.atom ); - } - - FT_FREE( font->user_props ); - - /* FREE( font ); */ /* XXX Fixme */ - } - - - FT_LOCAL_DEF( bdf_property_t * ) - bdf_get_font_property( bdf_font_t* font, - const char* name ) - { - hashnode hn; - - - if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) - return 0; - - hn = hash_lookup( name, (hashtable *)font->internal ); - - return hn ? ( font->props + hn->data ) : 0; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/bdf/module.mk b/drivers/freetype/freetype/src/bdf/module.mk deleted file mode 100644 index fe06ae8e06..0000000000 --- a/drivers/freetype/freetype/src/bdf/module.mk +++ /dev/null @@ -1,34 +0,0 @@ -# -# FreeType 2 BDF module definition -# - -# 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 -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - -FTMODULE_H_COMMANDS += BDF_DRIVER - -define BDF_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, bdf_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)bdf $(ECHO_DRIVER_DESC)bdf bitmap fonts$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/bdf/rules.mk b/drivers/freetype/freetype/src/bdf/rules.mk deleted file mode 100644 index 6ff1614dde..0000000000 --- a/drivers/freetype/freetype/src/bdf/rules.mk +++ /dev/null @@ -1,81 +0,0 @@ -# -# FreeType 2 bdf driver configuration rules -# - - -# Copyright (C) 2001, 2002, 2003, 2008 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 -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - - - -# bdf driver directory -# -BDF_DIR := $(SRC_DIR)/bdf - - -BDF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) - - -# bdf driver sources (i.e., C files) -# -BDF_DRV_SRC := $(BDF_DIR)/bdflib.c \ - $(BDF_DIR)/bdfdrivr.c - - -# bdf driver headers -# -BDF_DRV_H := $(BDF_DIR)/bdf.h \ - $(BDF_DIR)/bdfdrivr.h \ - $(BDF_DIR)/bdferror.h - -# bdf driver object(s) -# -# BDF_DRV_OBJ_M is used during `multi' builds -# BDF_DRV_OBJ_S is used during `single' builds -# -BDF_DRV_OBJ_M := $(BDF_DRV_SRC:$(BDF_DIR)/%.c=$(OBJ_DIR)/%.$O) -BDF_DRV_OBJ_S := $(OBJ_DIR)/bdf.$O - -# bdf driver source file for single build -# -BDF_DRV_SRC_S := $(BDF_DIR)/bdf.c - - -# bdf driver - single object -# -$(BDF_DRV_OBJ_S): $(BDF_DRV_SRC_S) $(BDF_DRV_SRC) $(FREETYPE_H) $(BDF_DRV_H) - $(BDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BDF_DRV_SRC_S)) - - -# bdf driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(BDF_DIR)/%.c $(FREETYPE_H) $(BDF_DRV_H) - $(BDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(BDF_DRV_OBJ_S) -DRV_OBJS_M += $(BDF_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/cache/Jamfile b/drivers/freetype/freetype/src/cache/Jamfile deleted file mode 100644 index 340cff7742..0000000000 --- a/drivers/freetype/freetype/src/cache/Jamfile +++ /dev/null @@ -1,43 +0,0 @@ -# FreeType 2 src/cache Jamfile -# -# Copyright 2001, 2003, 2004 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) cache ; - -# The file <freetype/ftcache.h> contains some macro definitions that are -# later used in #include statements related to the cache sub-system. It -# needs to be parsed through a HDRMACRO rule for macro definitions. -# -HDRMACRO [ FT2_SubDir include ftcache.h ] ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = ftcmru - ftcmanag - ftccache - ftcglyph - ftcsbits - ftcimage - ftcbasic - ftccmap - ; - } - else - { - _sources = ftcache ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/cache Jamfile diff --git a/drivers/freetype/freetype/src/cache/ftcache.c b/drivers/freetype/freetype/src/cache/ftcache.c deleted file mode 100644 index d41e91e5ec..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcache.c +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcache.c */ -/* */ -/* The FreeType Caching sub-system (body only). */ -/* */ -/* Copyright 2000-2001, 2003 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "ftcmru.c" -#include "ftcmanag.c" -#include "ftccache.c" -#include "ftccmap.c" -#include "ftcglyph.c" -#include "ftcimage.c" -#include "ftcsbits.c" -#include "ftcbasic.c" - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcbasic.c b/drivers/freetype/freetype/src/cache/ftcbasic.c deleted file mode 100644 index 84d336d5d6..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcbasic.c +++ /dev/null @@ -1,602 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcbasic.c */ -/* */ -/* The FreeType basic cache interface (body). */ -/* */ -/* Copyright 2003-2007, 2009-2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_CACHE_H -#include "ftcglyph.h" -#include "ftcimage.h" -#include "ftcsbits.h" - -#include "ftccback.h" -#include "ftcerror.h" - -#define FT_COMPONENT trace_cache - - - /* - * Basic Families - * - */ - typedef struct FTC_BasicAttrRec_ - { - FTC_ScalerRec scaler; - FT_UInt load_flags; - - } FTC_BasicAttrRec, *FTC_BasicAttrs; - -#define FTC_BASIC_ATTR_COMPARE( a, b ) \ - FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ - (a)->load_flags == (b)->load_flags ) - -#define FTC_BASIC_ATTR_HASH( a ) \ - ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags ) - - - typedef struct FTC_BasicQueryRec_ - { - FTC_GQueryRec gquery; - FTC_BasicAttrRec attrs; - - } FTC_BasicQueryRec, *FTC_BasicQuery; - - - typedef struct FTC_BasicFamilyRec_ - { - FTC_FamilyRec family; - FTC_BasicAttrRec attrs; - - } FTC_BasicFamilyRec, *FTC_BasicFamily; - - - FT_CALLBACK_DEF( FT_Bool ) - ftc_basic_family_compare( FTC_MruNode ftcfamily, - FT_Pointer ftcquery ) - { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; - - - return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ); - } - - - FT_CALLBACK_DEF( FT_Error ) - ftc_basic_family_init( FTC_MruNode ftcfamily, - FT_Pointer ftcquery, - FT_Pointer ftccache ) - { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; - FTC_Cache cache = (FTC_Cache)ftccache; - - - FTC_Family_Init( FTC_FAMILY( family ), cache ); - family->attrs = query->attrs; - return 0; - } - - - FT_CALLBACK_DEF( FT_UInt ) - ftc_basic_family_get_count( FTC_Family ftcfamily, - FTC_Manager manager ) - { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FT_Error error; - FT_Face face; - FT_UInt result = 0; - - - error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, - &face ); - - if ( error || !face ) - return result; - - if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs ) - { - FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " )); - FT_TRACE1(( "in this face, truncated\n", face->num_glyphs )); - } - - if ( !error ) - result = (FT_UInt)face->num_glyphs; - - return result; - } - - - FT_CALLBACK_DEF( FT_Error ) - ftc_basic_family_load_bitmap( FTC_Family ftcfamily, - FT_UInt gindex, - FTC_Manager manager, - FT_Face *aface ) - { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FT_Error error; - FT_Size size; - - - error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size ); - if ( !error ) - { - FT_Face face = size->face; - - - error = FT_Load_Glyph( face, gindex, - family->attrs.load_flags | FT_LOAD_RENDER ); - if ( !error ) - *aface = face; - } - - return error; - } - - - FT_CALLBACK_DEF( FT_Error ) - ftc_basic_family_load_glyph( FTC_Family ftcfamily, - FT_UInt gindex, - FTC_Cache cache, - FT_Glyph *aglyph ) - { - FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; - FT_Error error; - FTC_Scaler scaler = &family->attrs.scaler; - FT_Face face; - FT_Size size; - - - /* we will now load the glyph image */ - error = FTC_Manager_LookupSize( cache->manager, - scaler, - &size ); - if ( !error ) - { - face = size->face; - - error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); - if ( !error ) - { - if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || - face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* ok, copy it */ - FT_Glyph glyph; - - - error = FT_Get_Glyph( face->glyph, &glyph ); - if ( !error ) - { - *aglyph = glyph; - goto Exit; - } - } - else - error = FT_THROW( Invalid_Argument ); - } - } - - Exit: - return error; - } - - - FT_CALLBACK_DEF( FT_Bool ) - ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode, - FT_Pointer ftcface_id, - FTC_Cache cache, - FT_Bool* list_changed ) - { - FTC_GNode gnode = (FTC_GNode)ftcgnode; - FTC_FaceID face_id = (FTC_FaceID)ftcface_id; - FTC_BasicFamily family = (FTC_BasicFamily)gnode->family; - FT_Bool result; - - - if ( list_changed ) - *list_changed = FALSE; - result = FT_BOOL( family->attrs.scaler.face_id == face_id ); - if ( result ) - { - /* we must call this function to avoid this node from appearing - * in later lookups with the same face_id! - */ - FTC_GNode_UnselectFamily( gnode, cache ); - } - return result; - } - - - /* - * - * basic image cache - * - */ - - FT_CALLBACK_TABLE_DEF - const FTC_IFamilyClassRec ftc_basic_image_family_class = - { - { - sizeof ( FTC_BasicFamilyRec ), - ftc_basic_family_compare, - ftc_basic_family_init, - 0, /* FTC_MruNode_ResetFunc */ - 0 /* FTC_MruNode_DoneFunc */ - }, - ftc_basic_family_load_glyph - }; - - - FT_CALLBACK_TABLE_DEF - const FTC_GCacheClassRec ftc_basic_image_cache_class = - { - { - ftc_inode_new, - ftc_inode_weight, - ftc_gnode_compare, - ftc_basic_gnode_compare_faceid, - ftc_inode_free, - - sizeof ( FTC_GCacheRec ), - ftc_gcache_init, - ftc_gcache_done - }, - (FTC_MruListClass)&ftc_basic_image_family_class - }; - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_ImageCache_New( FTC_Manager manager, - FTC_ImageCache *acache ) - { - return FTC_GCache_New( manager, &ftc_basic_image_cache_class, - (FTC_GCache*)acache ); - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_ImageCache_Lookup( FTC_ImageCache cache, - FTC_ImageType type, - FT_UInt gindex, - FT_Glyph *aglyph, - FTC_Node *anode ) - { - FTC_BasicQueryRec query; - FTC_Node node = 0; /* make compiler happy */ - FT_Error error; - FT_PtrDist hash; - - - /* some argument checks are delayed to FTC_Cache_Lookup */ - if ( !aglyph ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - *aglyph = NULL; - if ( anode ) - *anode = NULL; - - { - if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); - } - - query.attrs.scaler.face_id = type->face_id; - query.attrs.scaler.width = type->width; - query.attrs.scaler.height = type->height; - query.attrs.load_flags = (FT_UInt)type->flags; - } - - query.attrs.scaler.pixel = 1; - query.attrs.scaler.x_res = 0; /* make compilers happy */ - query.attrs.scaler.y_res = 0; - - hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; - -#if 1 /* inlining is about 50% faster! */ - FTC_GCACHE_LOOKUP_CMP( cache, - ftc_basic_family_compare, - FTC_GNode_Compare, - hash, gindex, - &query, - node, - error ); -#else - error = FTC_GCache_Lookup( FTC_GCACHE( cache ), - hash, gindex, - FTC_GQUERY( &query ), - &node ); -#endif - if ( !error ) - { - *aglyph = FTC_INODE( node )->glyph; - - if ( anode ) - { - *anode = node; - node->ref_count++; - } - } - - Exit: - return error; - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_ImageCache_LookupScaler( FTC_ImageCache cache, - FTC_Scaler scaler, - FT_ULong load_flags, - FT_UInt gindex, - FT_Glyph *aglyph, - FTC_Node *anode ) - { - FTC_BasicQueryRec query; - FTC_Node node = 0; /* make compiler happy */ - FT_Error error; - FT_PtrDist hash; - - - /* some argument checks are delayed to FTC_Cache_Lookup */ - if ( !aglyph || !scaler ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - *aglyph = NULL; - if ( anode ) - *anode = NULL; - - /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ - if ( load_flags > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); - } - - query.attrs.scaler = scaler[0]; - query.attrs.load_flags = (FT_UInt)load_flags; - - hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; - - FTC_GCACHE_LOOKUP_CMP( cache, - ftc_basic_family_compare, - FTC_GNode_Compare, - hash, gindex, - &query, - node, - error ); - if ( !error ) - { - *aglyph = FTC_INODE( node )->glyph; - - if ( anode ) - { - *anode = node; - node->ref_count++; - } - } - - Exit: - return error; - } - - - /* - * - * basic small bitmap cache - * - */ - - FT_CALLBACK_TABLE_DEF - const FTC_SFamilyClassRec ftc_basic_sbit_family_class = - { - { - sizeof ( FTC_BasicFamilyRec ), - ftc_basic_family_compare, - ftc_basic_family_init, - 0, /* FTC_MruNode_ResetFunc */ - 0 /* FTC_MruNode_DoneFunc */ - }, - ftc_basic_family_get_count, - ftc_basic_family_load_bitmap - }; - - - FT_CALLBACK_TABLE_DEF - const FTC_GCacheClassRec ftc_basic_sbit_cache_class = - { - { - ftc_snode_new, - ftc_snode_weight, - ftc_snode_compare, - ftc_basic_gnode_compare_faceid, - ftc_snode_free, - - sizeof ( FTC_GCacheRec ), - ftc_gcache_init, - ftc_gcache_done - }, - (FTC_MruListClass)&ftc_basic_sbit_family_class - }; - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_SBitCache_New( FTC_Manager manager, - FTC_SBitCache *acache ) - { - return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class, - (FTC_GCache*)acache ); - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_SBitCache_Lookup( FTC_SBitCache cache, - FTC_ImageType type, - FT_UInt gindex, - FTC_SBit *ansbit, - FTC_Node *anode ) - { - FT_Error error; - FTC_BasicQueryRec query; - FTC_Node node = 0; /* make compiler happy */ - FT_PtrDist hash; - - - if ( anode ) - *anode = NULL; - - /* other argument checks delayed to FTC_Cache_Lookup */ - if ( !ansbit ) - return FT_THROW( Invalid_Argument ); - - *ansbit = NULL; - - { - if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); - } - - query.attrs.scaler.face_id = type->face_id; - query.attrs.scaler.width = type->width; - query.attrs.scaler.height = type->height; - query.attrs.load_flags = (FT_UInt)type->flags; - } - - query.attrs.scaler.pixel = 1; - query.attrs.scaler.x_res = 0; /* make compilers happy */ - query.attrs.scaler.y_res = 0; - - /* beware, the hash must be the same for all glyph ranges! */ - hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + - gindex / FTC_SBIT_ITEMS_PER_NODE; - -#if 1 /* inlining is about 50% faster! */ - FTC_GCACHE_LOOKUP_CMP( cache, - ftc_basic_family_compare, - FTC_SNode_Compare, - hash, gindex, - &query, - node, - error ); -#else - error = FTC_GCache_Lookup( FTC_GCACHE( cache ), - hash, - gindex, - FTC_GQUERY( &query ), - &node ); -#endif - if ( error ) - goto Exit; - - *ansbit = FTC_SNODE( node )->sbits + - ( gindex - FTC_GNODE( node )->gindex ); - - if ( anode ) - { - *anode = node; - node->ref_count++; - } - - Exit: - return error; - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_SBitCache_LookupScaler( FTC_SBitCache cache, - FTC_Scaler scaler, - FT_ULong load_flags, - FT_UInt gindex, - FTC_SBit *ansbit, - FTC_Node *anode ) - { - FT_Error error; - FTC_BasicQueryRec query; - FTC_Node node = 0; /* make compiler happy */ - FT_PtrDist hash; - - - if ( anode ) - *anode = NULL; - - /* other argument checks delayed to FTC_Cache_Lookup */ - if ( !ansbit || !scaler ) - return FT_THROW( Invalid_Argument ); - - *ansbit = NULL; - - /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ - if ( load_flags > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); - } - - query.attrs.scaler = scaler[0]; - query.attrs.load_flags = (FT_UInt)load_flags; - - /* beware, the hash must be the same for all glyph ranges! */ - hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + - gindex / FTC_SBIT_ITEMS_PER_NODE; - - FTC_GCACHE_LOOKUP_CMP( cache, - ftc_basic_family_compare, - FTC_SNode_Compare, - hash, gindex, - &query, - node, - error ); - if ( error ) - goto Exit; - - *ansbit = FTC_SNODE( node )->sbits + - ( gindex - FTC_GNODE( node )->gindex ); - - if ( anode ) - { - *anode = node; - node->ref_count++; - } - - Exit: - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftccache.c b/drivers/freetype/freetype/src/cache/ftccache.c deleted file mode 100644 index f20dd4502c..0000000000 --- a/drivers/freetype/freetype/src/cache/ftccache.c +++ /dev/null @@ -1,621 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftccache.c */ -/* */ -/* The FreeType internal cache interface (body). */ -/* */ -/* Copyright 2000-2007, 2009-2011, 2013 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 "ftcmanag.h" -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H - -#include "ftccback.h" -#include "ftcerror.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_cache - - -#define FTC_HASH_MAX_LOAD 2 -#define FTC_HASH_MIN_LOAD 1 -#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD ) - - /* this one _must_ be a power of 2! */ -#define FTC_HASH_INITIAL_SIZE 8 - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE NODE DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* add a new node to the head of the manager's circular MRU list */ - static void - ftc_node_mru_link( FTC_Node node, - FTC_Manager manager ) - { - void *nl = &manager->nodes_list; - - - FTC_MruNode_Prepend( (FTC_MruNode*)nl, - (FTC_MruNode)node ); - manager->num_nodes++; - } - - - /* remove a node from the manager's MRU list */ - static void - ftc_node_mru_unlink( FTC_Node node, - FTC_Manager manager ) - { - void *nl = &manager->nodes_list; - - - FTC_MruNode_Remove( (FTC_MruNode*)nl, - (FTC_MruNode)node ); - manager->num_nodes--; - } - - -#ifndef FTC_INLINE - - /* move a node to the head of the manager's MRU list */ - static void - ftc_node_mru_up( FTC_Node node, - FTC_Manager manager ) - { - FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, - (FTC_MruNode)node ); - } - - - /* get a top bucket for specified hash from cache, - * body for FTC_NODE__TOP_FOR_HASH( cache, hash ) - */ - FT_LOCAL_DEF( FTC_Node* ) - ftc_get_top_node_for_hash( FTC_Cache cache, - FT_PtrDist hash ) - { - FTC_Node* pnode; - FT_UInt idx; - - - idx = (FT_UInt)( hash & cache->mask ); - if ( idx < cache->p ) - idx = (FT_UInt)( hash & ( 2 * cache->mask + 1 ) ); - pnode = cache->buckets + idx; - return pnode; - } - -#endif /* !FTC_INLINE */ - - - /* Note that this function cannot fail. If we cannot re-size the - * buckets array appropriately, we simply degrade the hash table's - * performance! - */ - static void - ftc_cache_resize( FTC_Cache cache ) - { - for (;;) - { - FTC_Node node, *pnode; - FT_UFast p = cache->p; - FT_UFast mask = cache->mask; - FT_UFast count = mask + p + 1; /* number of buckets */ - - - /* do we need to shrink the buckets array? */ - if ( cache->slack < 0 ) - { - FTC_Node new_list = NULL; - - - /* try to expand the buckets array _before_ splitting - * the bucket lists - */ - if ( p >= mask ) - { - FT_Memory memory = cache->memory; - FT_Error error; - - - /* if we can't expand the array, leave immediately */ - if ( FT_RENEW_ARRAY( cache->buckets, - ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) ) - break; - } - - /* split a single bucket */ - pnode = cache->buckets + p; - - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( node->hash & ( mask + 1 ) ) - { - *pnode = node->link; - node->link = new_list; - new_list = node; - } - else - pnode = &node->link; - } - - cache->buckets[p + mask + 1] = new_list; - - cache->slack += FTC_HASH_MAX_LOAD; - - if ( p >= mask ) - { - cache->mask = 2 * mask + 1; - cache->p = 0; - } - else - cache->p = p + 1; - } - - /* do we need to expand the buckets array? */ - else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) - { - FT_UFast old_index = p + mask; - FTC_Node* pold; - - - if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE ) - break; - - if ( p == 0 ) - { - FT_Memory memory = cache->memory; - FT_Error error; - - - /* if we can't shrink the array, leave immediately */ - if ( FT_RENEW_ARRAY( cache->buckets, - ( mask + 1 ) * 2, mask + 1 ) ) - break; - - cache->mask >>= 1; - p = cache->mask; - } - else - p--; - - pnode = cache->buckets + p; - while ( *pnode ) - pnode = &(*pnode)->link; - - pold = cache->buckets + old_index; - *pnode = *pold; - *pold = NULL; - - cache->slack -= FTC_HASH_MAX_LOAD; - cache->p = p; - } - - /* otherwise, the hash table is balanced */ - else - break; - } - } - - - /* remove a node from its cache's hash table */ - static void - ftc_node_hash_unlink( FTC_Node node0, - FTC_Cache cache ) - { - FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node0->hash ); - - - for (;;) - { - FTC_Node node = *pnode; - - - if ( node == NULL ) - { - FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" )); - return; - } - - if ( node == node0 ) - break; - - pnode = &(*pnode)->link; - } - - *pnode = node0->link; - node0->link = NULL; - - cache->slack++; - ftc_cache_resize( cache ); - } - - - /* add a node to the `top' of its cache's hash table */ - static void - ftc_node_hash_link( FTC_Node node, - FTC_Cache cache ) - { - FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node->hash ); - - - node->link = *pnode; - *pnode = node; - - cache->slack--; - ftc_cache_resize( cache ); - } - - - /* remove a node from the cache manager */ - FT_LOCAL_DEF( void ) - ftc_node_destroy( FTC_Node node, - FTC_Manager manager ) - { - FTC_Cache cache; - - -#ifdef FT_DEBUG_ERROR - /* find node's cache */ - if ( node->cache_index >= manager->num_caches ) - { - FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); - return; - } -#endif - - cache = manager->caches[node->cache_index]; - -#ifdef FT_DEBUG_ERROR - if ( cache == NULL ) - { - FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); - return; - } -#endif - - manager->cur_weight -= cache->clazz.node_weight( node, cache ); - - /* remove node from mru list */ - ftc_node_mru_unlink( node, manager ); - - /* remove node from cache's hash table */ - ftc_node_hash_unlink( node, cache ); - - /* now finalize it */ - cache->clazz.node_free( node, cache ); - -#if 0 - /* check, just in case of general corruption :-) */ - if ( manager->num_nodes == 0 ) - FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n", - manager->num_nodes )); -#endif - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** ABSTRACT CACHE CLASS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL_DEF( FT_Error ) - FTC_Cache_Init( FTC_Cache cache ) - { - return ftc_cache_init( cache ); - } - - - FT_LOCAL_DEF( FT_Error ) - ftc_cache_init( FTC_Cache cache ) - { - FT_Memory memory = cache->memory; - FT_Error error; - - - cache->p = 0; - cache->mask = FTC_HASH_INITIAL_SIZE - 1; - cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; - - (void)FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ); - return error; - } - - - static void - FTC_Cache_Clear( FTC_Cache cache ) - { - if ( cache && cache->buckets ) - { - FTC_Manager manager = cache->manager; - FT_UFast i; - FT_UFast count; - - - count = cache->p + cache->mask + 1; - - for ( i = 0; i < count; i++ ) - { - FTC_Node *pnode = cache->buckets + i, next, node = *pnode; - - - while ( node ) - { - next = node->link; - node->link = NULL; - - /* remove node from mru list */ - ftc_node_mru_unlink( node, manager ); - - /* now finalize it */ - manager->cur_weight -= cache->clazz.node_weight( node, cache ); - - cache->clazz.node_free( node, cache ); - node = next; - } - cache->buckets[i] = NULL; - } - ftc_cache_resize( cache ); - } - } - - - FT_LOCAL_DEF( void ) - ftc_cache_done( FTC_Cache cache ) - { - if ( cache->memory ) - { - FT_Memory memory = cache->memory; - - - FTC_Cache_Clear( cache ); - - FT_FREE( cache->buckets ); - cache->mask = 0; - cache->p = 0; - cache->slack = 0; - - cache->memory = NULL; - } - } - - - FT_LOCAL_DEF( void ) - FTC_Cache_Done( FTC_Cache cache ) - { - ftc_cache_done( cache ); - } - - - static void - ftc_cache_add( FTC_Cache cache, - FT_PtrDist hash, - FTC_Node node ) - { - node->hash = hash; - node->cache_index = (FT_UInt16)cache->index; - node->ref_count = 0; - - ftc_node_hash_link( node, cache ); - ftc_node_mru_link( node, cache->manager ); - - { - FTC_Manager manager = cache->manager; - - - manager->cur_weight += cache->clazz.node_weight( node, cache ); - - if ( manager->cur_weight >= manager->max_weight ) - { - node->ref_count++; - FTC_Manager_Compress( manager ); - node->ref_count--; - } - } - } - - - FT_LOCAL_DEF( FT_Error ) - FTC_Cache_NewNode( FTC_Cache cache, - FT_PtrDist hash, - FT_Pointer query, - FTC_Node *anode ) - { - FT_Error error; - FTC_Node node; - - - /* - * We use the FTC_CACHE_TRYLOOP macros to support out-of-memory - * errors (OOM) correctly, i.e., by flushing the cache progressively - * in order to make more room. - */ - - FTC_CACHE_TRYLOOP( cache ) - { - error = cache->clazz.node_new( &node, query, cache ); - } - FTC_CACHE_TRYLOOP_END( NULL ); - - if ( error ) - node = NULL; - else - { - /* don't assume that the cache has the same number of buckets, since - * our allocation request might have triggered global cache flushing - */ - ftc_cache_add( cache, hash, node ); - } - - *anode = node; - return error; - } - - -#ifndef FTC_INLINE - - FT_LOCAL_DEF( FT_Error ) - FTC_Cache_Lookup( FTC_Cache cache, - FT_PtrDist hash, - FT_Pointer query, - FTC_Node *anode ) - { - FTC_Node* bucket; - FTC_Node* pnode; - FTC_Node node; - FT_Error error = FT_Err_Ok; - FT_Bool list_changed = FALSE; - - FTC_Node_CompareFunc compare = cache->clazz.node_compare; - - - if ( cache == NULL || anode == NULL ) - return FT_THROW( Invalid_Argument ); - - /* Go to the `top' node of the list sharing same masked hash */ - bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); - - /* Lookup a node with exactly same hash and queried properties. */ - /* NOTE: _nodcomp() may change the linked list to reduce memory. */ - for (;;) - { - node = *pnode; - if ( node == NULL ) - goto NewNode; - - if ( node->hash == hash && - compare( node, query, cache, &list_changed ) ) - break; - - pnode = &node->link; - } - - if ( list_changed ) - { - /* Update bucket by modified linked list */ - bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); - - /* Update pnode by modified linked list */ - while ( *pnode != node ) - { - if ( *pnode == NULL ) - { - FT_ERROR(( "FTC_Cache_Lookup: oops!!! node missing\n" )); - goto NewNode; - } - else - pnode = &((*pnode)->link); - } - } - - /* Reorder the list to move the found node to the `top' */ - if ( node != *bucket ) - { - *pnode = node->link; - node->link = *bucket; - *bucket = node; - } - - /* move to head of MRU list */ - { - FTC_Manager manager = cache->manager; - - - if ( node != manager->nodes_list ) - ftc_node_mru_up( node, manager ); - } - *anode = node; - - return error; - - NewNode: - return FTC_Cache_NewNode( cache, hash, query, anode ); - } - -#endif /* !FTC_INLINE */ - - - FT_LOCAL_DEF( void ) - FTC_Cache_RemoveFaceID( FTC_Cache cache, - FTC_FaceID face_id ) - { - FT_UFast i, count; - FTC_Manager manager = cache->manager; - FTC_Node frees = NULL; - - - count = cache->p + cache->mask + 1; - for ( i = 0; i < count; i++ ) - { - FTC_Node* bucket = cache->buckets + i; - FTC_Node* pnode = bucket; - - - for ( ;; ) - { - FTC_Node node = *pnode; - FT_Bool list_changed = FALSE; - - - if ( node == NULL ) - break; - - if ( cache->clazz.node_remove_faceid( node, face_id, - cache, &list_changed ) ) - { - *pnode = node->link; - node->link = frees; - frees = node; - } - else - pnode = &node->link; - } - } - - /* remove all nodes in the free list */ - while ( frees ) - { - FTC_Node node; - - - node = frees; - frees = node->link; - - manager->cur_weight -= cache->clazz.node_weight( node, cache ); - ftc_node_mru_unlink( node, manager ); - - cache->clazz.node_free( node, cache ); - - cache->slack++; - } - - ftc_cache_resize( cache ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftccache.h b/drivers/freetype/freetype/src/cache/ftccache.h deleted file mode 100644 index 4155f320e0..0000000000 --- a/drivers/freetype/freetype/src/cache/ftccache.h +++ /dev/null @@ -1,352 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftccache.h */ -/* */ -/* FreeType internal cache interface (specification). */ -/* */ -/* Copyright 2000-2007, 2009-2011, 2013 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 __FTCCACHE_H__ -#define __FTCCACHE_H__ - - -#include "ftcmru.h" - -FT_BEGIN_HEADER - -#define _FTC_FACE_ID_HASH( i ) \ - ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 ))) - - /* handle to cache object */ - typedef struct FTC_CacheRec_* FTC_Cache; - - /* handle to cache class */ - typedef const struct FTC_CacheClassRec_* FTC_CacheClass; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE NODE DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Each cache controls one or more cache nodes. Each node is part of */ - /* the global_lru list of the manager. Its `data' field however is used */ - /* as a reference count for now. */ - /* */ - /* A node can be anything, depending on the type of information held by */ - /* the cache. It can be an individual glyph image, a set of bitmaps */ - /* glyphs for a given size, some metrics, etc. */ - /* */ - /*************************************************************************/ - - /* structure size should be 20 bytes on 32-bits machines */ - typedef struct FTC_NodeRec_ - { - FTC_MruNodeRec mru; /* circular mru list pointer */ - FTC_Node link; /* used for hashing */ - FT_PtrDist hash; /* used for hashing too */ - FT_UShort cache_index; /* index of cache the node belongs to */ - FT_Short ref_count; /* reference count for this node */ - - } FTC_NodeRec; - - -#define FTC_NODE( x ) ( (FTC_Node)(x) ) -#define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) - -#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next ) -#define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) - -#ifdef FTC_INLINE -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ - ( ( cache )->buckets + \ - ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \ - ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \ - : ( ( hash ) & ( cache )->mask ) ) ) -#else - FT_LOCAL( FTC_Node* ) - ftc_get_top_node_for_hash( FTC_Cache cache, - FT_PtrDist hash ); -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ - ftc_get_top_node_for_hash( ( cache ), ( hash ) ) -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* initialize a new cache node */ - typedef FT_Error - (*FTC_Node_NewFunc)( FTC_Node *pnode, - FT_Pointer query, - FTC_Cache cache ); - - typedef FT_Offset - (*FTC_Node_WeightFunc)( FTC_Node node, - FTC_Cache cache ); - - /* compare a node to a given key pair */ - typedef FT_Bool - (*FTC_Node_CompareFunc)( FTC_Node node, - FT_Pointer key, - FTC_Cache cache, - FT_Bool* list_changed ); - - - typedef void - (*FTC_Node_FreeFunc)( FTC_Node node, - FTC_Cache cache ); - - typedef FT_Error - (*FTC_Cache_InitFunc)( FTC_Cache cache ); - - typedef void - (*FTC_Cache_DoneFunc)( FTC_Cache cache ); - - - typedef struct FTC_CacheClassRec_ - { - FTC_Node_NewFunc node_new; - FTC_Node_WeightFunc node_weight; - FTC_Node_CompareFunc node_compare; - FTC_Node_CompareFunc node_remove_faceid; - FTC_Node_FreeFunc node_free; - - FT_Offset cache_size; - FTC_Cache_InitFunc cache_init; - FTC_Cache_DoneFunc cache_done; - - } FTC_CacheClassRec; - - - /* each cache really implements a dynamic hash table to manage its nodes */ - typedef struct FTC_CacheRec_ - { - FT_UFast p; - FT_UFast mask; - FT_Long slack; - FTC_Node* buckets; - - FTC_CacheClassRec clazz; /* local copy, for speed */ - - FTC_Manager manager; - FT_Memory memory; - FT_UInt index; /* in manager's table */ - - FTC_CacheClass org_class; /* original class pointer */ - - } FTC_CacheRec; - - -#define FTC_CACHE( x ) ( (FTC_Cache)(x) ) -#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) - - - /* default cache initialize */ - FT_LOCAL( FT_Error ) - FTC_Cache_Init( FTC_Cache cache ); - - /* default cache finalizer */ - FT_LOCAL( void ) - FTC_Cache_Done( FTC_Cache cache ); - - /* Call this function to look up the cache. If no corresponding - * node is found, a new one is automatically created. This function - * is capable of flushing the cache adequately to make room for the - * new cache object. - */ - -#ifndef FTC_INLINE - FT_LOCAL( FT_Error ) - FTC_Cache_Lookup( FTC_Cache cache, - FT_PtrDist hash, - FT_Pointer query, - FTC_Node *anode ); -#endif - - FT_LOCAL( FT_Error ) - FTC_Cache_NewNode( FTC_Cache cache, - FT_PtrDist hash, - FT_Pointer query, - FTC_Node *anode ); - - /* Remove all nodes that relate to a given face_id. This is useful - * when un-installing fonts. Note that if a cache node relates to - * the face_id but is locked (i.e., has `ref_count > 0'), the node - * will _not_ be destroyed, but its internal face_id reference will - * be modified. - * - * The final result will be that the node will never come back - * in further lookup requests, and will be flushed on demand from - * the cache normally when its reference count reaches 0. - */ - FT_LOCAL( void ) - FTC_Cache_RemoveFaceID( FTC_Cache cache, - FTC_FaceID face_id ); - - -#ifdef FTC_INLINE - -#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ - FT_BEGIN_STMNT \ - FTC_Node *_bucket, *_pnode, _node; \ - FTC_Cache _cache = FTC_CACHE(cache); \ - FT_PtrDist _hash = (FT_PtrDist)(hash); \ - FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ - FT_Bool _list_changed = FALSE; \ - \ - \ - error = FT_Err_Ok; \ - node = NULL; \ - \ - /* Go to the `top' node of the list sharing same masked hash */ \ - _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ - \ - /* Look up a node with identical hash and queried properties. */ \ - /* NOTE: _nodcomp() may change the linked list to reduce memory. */ \ - for (;;) \ - { \ - _node = *_pnode; \ - if ( _node == NULL ) \ - goto _NewNode; \ - \ - if ( _node->hash == _hash && \ - _nodcomp( _node, query, _cache, &_list_changed ) ) \ - break; \ - \ - _pnode = &_node->link; \ - } \ - \ - if ( _list_changed ) \ - { \ - /* Update _bucket by possibly modified linked list */ \ - _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ - \ - /* Update _pnode by possibly modified linked list */ \ - while ( *_pnode != _node ) \ - { \ - if ( *_pnode == NULL ) \ - { \ - FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \ - goto _NewNode; \ - } \ - else \ - _pnode = &((*_pnode)->link); \ - } \ - } \ - \ - /* Reorder the list to move the found node to the `top' */ \ - if ( _node != *_bucket ) \ - { \ - *_pnode = _node->link; \ - _node->link = *_bucket; \ - *_bucket = _node; \ - } \ - \ - /* Update MRU list */ \ - { \ - FTC_Manager _manager = _cache->manager; \ - void* _nl = &_manager->nodes_list; \ - \ - \ - if ( _node != _manager->nodes_list ) \ - FTC_MruNode_Up( (FTC_MruNode*)_nl, \ - (FTC_MruNode)_node ); \ - } \ - goto _Ok; \ - \ - _NewNode: \ - error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ - \ - _Ok: \ - node = _node; \ - FT_END_STMNT - -#else /* !FTC_INLINE */ - -#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ - FT_BEGIN_STMNT \ - error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, \ - (FTC_Node*)&(node) ); \ - FT_END_STMNT - -#endif /* !FTC_INLINE */ - - - /* - * This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry - * loop to flush the cache repeatedly in case of memory overflows. - * - * It is used when creating a new cache node, or within a lookup - * that needs to allocate data (e.g. the sbit cache lookup). - * - * Example: - * - * { - * FTC_CACHE_TRYLOOP( cache ) - * error = load_data( ... ); - * FTC_CACHE_TRYLOOP_END() - * } - * - */ -#define FTC_CACHE_TRYLOOP( cache ) \ - { \ - FTC_Manager _try_manager = FTC_CACHE( cache )->manager; \ - FT_UInt _try_count = 4; \ - \ - \ - for (;;) \ - { \ - FT_UInt _try_done; - - -#define FTC_CACHE_TRYLOOP_END( list_changed ) \ - if ( !error || FT_ERR_NEQ( error, Out_Of_Memory ) ) \ - break; \ - \ - _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ - if ( _try_done > 0 && ( list_changed ) ) \ - *(FT_Bool*)( list_changed ) = TRUE; \ - \ - if ( _try_done == 0 ) \ - break; \ - \ - if ( _try_done == _try_count ) \ - { \ - _try_count *= 2; \ - if ( _try_count < _try_done || \ - _try_count > _try_manager->num_nodes ) \ - _try_count = _try_manager->num_nodes; \ - } \ - } \ - } - - /* */ - -FT_END_HEADER - - -#endif /* __FTCCACHE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftccback.h b/drivers/freetype/freetype/src/cache/ftccback.h deleted file mode 100644 index 9528279273..0000000000 --- a/drivers/freetype/freetype/src/cache/ftccback.h +++ /dev/null @@ -1,91 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftccback.h */ -/* */ -/* Callback functions of the caching sub-system (specification only). */ -/* */ -/* Copyright 2004-2006, 2011, 2013 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 __FTCCBACK_H__ -#define __FTCCBACK_H__ - -#include <ft2build.h> -#include FT_CACHE_H -#include "ftcmru.h" -#include "ftcimage.h" -#include "ftcmanag.h" -#include "ftcglyph.h" -#include "ftcsbits.h" - - - FT_LOCAL( void ) - ftc_inode_free( FTC_Node inode, - FTC_Cache cache ); - - FT_LOCAL( FT_Error ) - ftc_inode_new( FTC_Node *pinode, - FT_Pointer gquery, - FTC_Cache cache ); - - FT_LOCAL( FT_Offset ) - ftc_inode_weight( FTC_Node inode, - FTC_Cache cache ); - - - FT_LOCAL( void ) - ftc_snode_free( FTC_Node snode, - FTC_Cache cache ); - - FT_LOCAL( FT_Error ) - ftc_snode_new( FTC_Node *psnode, - FT_Pointer gquery, - FTC_Cache cache ); - - FT_LOCAL( FT_Offset ) - ftc_snode_weight( FTC_Node snode, - FTC_Cache cache ); - - FT_LOCAL( FT_Bool ) - ftc_snode_compare( FTC_Node snode, - FT_Pointer gquery, - FTC_Cache cache, - FT_Bool* list_changed ); - - - FT_LOCAL( FT_Bool ) - ftc_gnode_compare( FTC_Node gnode, - FT_Pointer gquery, - FTC_Cache cache, - FT_Bool* list_changed ); - - - FT_LOCAL( FT_Error ) - ftc_gcache_init( FTC_Cache cache ); - - FT_LOCAL( void ) - ftc_gcache_done( FTC_Cache cache ); - - - FT_LOCAL( FT_Error ) - ftc_cache_init( FTC_Cache cache ); - - FT_LOCAL( void ) - ftc_cache_done( FTC_Cache cache ); - - FT_LOCAL( void ) - ftc_node_destroy( FTC_Node node, - FTC_Manager manager ); - - -#endif /* __FTCCBACK_H__ */ - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftccmap.c b/drivers/freetype/freetype/src/cache/ftccmap.c deleted file mode 100644 index 848349be2d..0000000000 --- a/drivers/freetype/freetype/src/cache/ftccmap.c +++ /dev/null @@ -1,337 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftccmap.c */ -/* */ -/* FreeType CharMap cache (body) */ -/* */ -/* Copyright 2000-2013 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_FREETYPE_H -#include FT_CACHE_H -#include "ftcmanag.h" -#include FT_INTERNAL_MEMORY_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H - -#include "ftccback.h" -#include "ftcerror.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_cache - - - /*************************************************************************/ - /* */ - /* Each FTC_CMapNode contains a simple array to map a range of character */ - /* codes to equivalent glyph indices. */ - /* */ - /* For now, the implementation is very basic: Each node maps a range of */ - /* 128 consecutive character codes to their corresponding glyph indices. */ - /* */ - /* We could do more complex things, but I don't think it is really very */ - /* useful. */ - /* */ - /*************************************************************************/ - - - /* number of glyph indices / character code per node */ -#define FTC_CMAP_INDICES_MAX 128 - - /* compute a query/node hash */ -#define FTC_CMAP_HASH( faceid, index, charcode ) \ - ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ - ( (charcode) / FTC_CMAP_INDICES_MAX ) ) - - /* the charmap query */ - typedef struct FTC_CMapQueryRec_ - { - FTC_FaceID face_id; - FT_UInt cmap_index; - FT_UInt32 char_code; - - } FTC_CMapQueryRec, *FTC_CMapQuery; - -#define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) -#define FTC_CMAP_QUERY_HASH( x ) \ - FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) - - /* the cmap cache node */ - typedef struct FTC_CMapNodeRec_ - { - FTC_NodeRec node; - FTC_FaceID face_id; - FT_UInt cmap_index; - FT_UInt32 first; /* first character in node */ - FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ - - } FTC_CMapNodeRec, *FTC_CMapNode; - -#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) -#define FTC_CMAP_NODE_HASH( x ) \ - FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) - - /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ - /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ -#define FTC_CMAP_UNKNOWN (FT_UInt16)~0 - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CHARMAP NODES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( void ) - ftc_cmap_node_free( FTC_Node ftcnode, - FTC_Cache cache ) - { - FTC_CMapNode node = (FTC_CMapNode)ftcnode; - FT_Memory memory = cache->memory; - - - FT_FREE( node ); - } - - - /* initialize a new cmap node */ - FT_CALLBACK_DEF( FT_Error ) - ftc_cmap_node_new( FTC_Node *ftcanode, - FT_Pointer ftcquery, - FTC_Cache cache ) - { - FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode; - FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; - FT_Error error; - FT_Memory memory = cache->memory; - FTC_CMapNode node = NULL; - FT_UInt nn; - - - if ( !FT_NEW( node ) ) - { - node->face_id = query->face_id; - node->cmap_index = query->cmap_index; - node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * - FTC_CMAP_INDICES_MAX; - - for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) - node->indices[nn] = FTC_CMAP_UNKNOWN; - } - - *anode = node; - return error; - } - - - /* compute the weight of a given cmap node */ - FT_CALLBACK_DEF( FT_Offset ) - ftc_cmap_node_weight( FTC_Node cnode, - FTC_Cache cache ) - { - FT_UNUSED( cnode ); - FT_UNUSED( cache ); - - return sizeof ( *cnode ); - } - - - /* compare a cmap node to a given query */ - FT_CALLBACK_DEF( FT_Bool ) - ftc_cmap_node_compare( FTC_Node ftcnode, - FT_Pointer ftcquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - FTC_CMapNode node = (FTC_CMapNode)ftcnode; - FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; - FT_UNUSED( cache ); - - - if ( list_changed ) - *list_changed = FALSE; - if ( node->face_id == query->face_id && - node->cmap_index == query->cmap_index ) - { - FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); - - - return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); - } - - return 0; - } - - - FT_CALLBACK_DEF( FT_Bool ) - ftc_cmap_node_remove_faceid( FTC_Node ftcnode, - FT_Pointer ftcface_id, - FTC_Cache cache, - FT_Bool* list_changed ) - { - FTC_CMapNode node = (FTC_CMapNode)ftcnode; - FTC_FaceID face_id = (FTC_FaceID)ftcface_id; - FT_UNUSED( cache ); - - - if ( list_changed ) - *list_changed = FALSE; - return FT_BOOL( node->face_id == face_id ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH IMAGE CACHE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_TABLE_DEF - const FTC_CacheClassRec ftc_cmap_cache_class = - { - ftc_cmap_node_new, - ftc_cmap_node_weight, - ftc_cmap_node_compare, - ftc_cmap_node_remove_faceid, - ftc_cmap_node_free, - - sizeof ( FTC_CacheRec ), - ftc_cache_init, - ftc_cache_done, - }; - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_CMapCache_New( FTC_Manager manager, - FTC_CMapCache *acache ) - { - return FTC_Manager_RegisterCache( manager, - &ftc_cmap_cache_class, - FTC_CACHE_P( acache ) ); - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_UInt ) - FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, - FTC_FaceID face_id, - FT_Int cmap_index, - FT_UInt32 char_code ) - { - FTC_Cache cache = FTC_CACHE( cmap_cache ); - FTC_CMapQueryRec query; - FTC_Node node; - FT_Error error; - FT_UInt gindex = 0; - FT_PtrDist hash; - FT_Int no_cmap_change = 0; - - - if ( cmap_index < 0 ) - { - /* Treat a negative cmap index as a special value, meaning that you */ - /* don't want to change the FT_Face's character map through this */ - /* call. This can be useful if the face requester callback already */ - /* sets the face's charmap to the appropriate value. */ - - no_cmap_change = 1; - cmap_index = 0; - } - - if ( !cache ) - { - FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); - return 0; - } - - query.face_id = face_id; - query.cmap_index = (FT_UInt)cmap_index; - query.char_code = char_code; - - hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); - -#if 1 - FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, - node, error ); -#else - error = FTC_Cache_Lookup( cache, hash, &query, &node ); -#endif - if ( error ) - goto Exit; - - FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < - FTC_CMAP_INDICES_MAX ); - - /* something rotten can happen with rogue clients */ - if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= - FTC_CMAP_INDICES_MAX ) ) - return 0; /* XXX: should return appropriate error */ - - gindex = FTC_CMAP_NODE( node )->indices[char_code - - FTC_CMAP_NODE( node )->first]; - if ( gindex == FTC_CMAP_UNKNOWN ) - { - FT_Face face; - - - gindex = 0; - - error = FTC_Manager_LookupFace( cache->manager, - FTC_CMAP_NODE( node )->face_id, - &face ); - if ( error ) - goto Exit; - -#ifdef FT_MAX_CHARMAP_CACHEABLE - /* something rotten can happen with rogue clients */ - if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE ) - return 0; /* XXX: should return appropriate error */ -#endif - - if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) - { - FT_CharMap old, cmap = NULL; - - - old = face->charmap; - cmap = face->charmaps[cmap_index]; - - if ( old != cmap && !no_cmap_change ) - FT_Set_Charmap( face, cmap ); - - gindex = FT_Get_Char_Index( face, char_code ); - - if ( old != cmap && !no_cmap_change ) - FT_Set_Charmap( face, old ); - } - - FTC_CMAP_NODE( node )->indices[char_code - - FTC_CMAP_NODE( node )->first] - = (FT_UShort)gindex; - } - - Exit: - return gindex; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcerror.h b/drivers/freetype/freetype/src/cache/ftcerror.h deleted file mode 100644 index 0e055709bb..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcerror.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcerror.h */ -/* */ -/* Caching sub-system error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the caching sub-system error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ - -#ifndef __FTCERROR_H__ -#define __FTCERROR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX FTC_Err_ -#define FT_ERR_BASE FT_Mod_Err_Cache - -#include FT_ERRORS_H - -#endif /* __FTCERROR_H__ */ - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcglyph.c b/drivers/freetype/freetype/src/cache/ftcglyph.c deleted file mode 100644 index 441e177238..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcglyph.c +++ /dev/null @@ -1,219 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcglyph.c */ -/* */ -/* FreeType Glyph Image (FT_Glyph) cache (body). */ -/* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2009, 2011 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_CACHE_H -#include "ftcglyph.h" -#include FT_ERRORS_H - -#include "ftccback.h" -#include "ftcerror.h" - - - /* create a new chunk node, setting its cache index and ref count */ - FT_LOCAL_DEF( void ) - FTC_GNode_Init( FTC_GNode gnode, - FT_UInt gindex, - FTC_Family family ) - { - gnode->family = family; - gnode->gindex = gindex; - family->num_nodes++; - } - - - FT_LOCAL_DEF( void ) - FTC_GNode_UnselectFamily( FTC_GNode gnode, - FTC_Cache cache ) - { - FTC_Family family = gnode->family; - - - gnode->family = NULL; - if ( family && --family->num_nodes == 0 ) - FTC_FAMILY_FREE( family, cache ); - } - - - FT_LOCAL_DEF( void ) - FTC_GNode_Done( FTC_GNode gnode, - FTC_Cache cache ) - { - /* finalize the node */ - gnode->gindex = 0; - - FTC_GNode_UnselectFamily( gnode, cache ); - } - - - FT_LOCAL_DEF( FT_Bool ) - ftc_gnode_compare( FTC_Node ftcgnode, - FT_Pointer ftcgquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - FTC_GNode gnode = (FTC_GNode)ftcgnode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - FT_UNUSED( cache ); - - - if ( list_changed ) - *list_changed = FALSE; - return FT_BOOL( gnode->family == gquery->family && - gnode->gindex == gquery->gindex ); - } - - -#ifdef FTC_INLINE - - FT_LOCAL_DEF( FT_Bool ) - FTC_GNode_Compare( FTC_GNode gnode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - return ftc_gnode_compare( FTC_NODE( gnode ), gquery, - cache, list_changed ); - } - -#endif - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CHUNK SETS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - FTC_Family_Init( FTC_Family family, - FTC_Cache cache ) - { - FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); - - - family->clazz = clazz->family_class; - family->num_nodes = 0; - family->cache = cache; - } - - - FT_LOCAL_DEF( FT_Error ) - ftc_gcache_init( FTC_Cache ftccache ) - { - FTC_GCache cache = (FTC_GCache)ftccache; - FT_Error error; - - - error = FTC_Cache_Init( FTC_CACHE( cache ) ); - if ( !error ) - { - FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; - - FTC_MruList_Init( &cache->families, - clazz->family_class, - 0, /* no maximum here! */ - cache, - FTC_CACHE( cache )->memory ); - } - - return error; - } - - -#if 0 - - FT_LOCAL_DEF( FT_Error ) - FTC_GCache_Init( FTC_GCache cache ) - { - return ftc_gcache_init( FTC_CACHE( cache ) ); - } - -#endif /* 0 */ - - - FT_LOCAL_DEF( void ) - ftc_gcache_done( FTC_Cache ftccache ) - { - FTC_GCache cache = (FTC_GCache)ftccache; - - - FTC_Cache_Done( (FTC_Cache)cache ); - FTC_MruList_Done( &cache->families ); - } - - -#if 0 - - FT_LOCAL_DEF( void ) - FTC_GCache_Done( FTC_GCache cache ) - { - ftc_gcache_done( FTC_CACHE( cache ) ); - } - -#endif /* 0 */ - - - FT_LOCAL_DEF( FT_Error ) - FTC_GCache_New( FTC_Manager manager, - FTC_GCacheClass clazz, - FTC_GCache *acache ) - { - return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz, - (FTC_Cache*)acache ); - } - - -#ifndef FTC_INLINE - - FT_LOCAL_DEF( FT_Error ) - FTC_GCache_Lookup( FTC_GCache cache, - FT_PtrDist hash, - FT_UInt gindex, - FTC_GQuery query, - FTC_Node *anode ) - { - FT_Error error; - - - query->gindex = gindex; - - FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); - if ( !error ) - { - FTC_Family family = query->family; - - - /* prevent the family from being destroyed too early when an */ - /* out-of-memory condition occurs during glyph node initialization. */ - family->num_nodes++; - - error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); - - if ( --family->num_nodes == 0 ) - FTC_FAMILY_FREE( family, cache ); - } - return error; - } - -#endif /* !FTC_INLINE */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcglyph.h b/drivers/freetype/freetype/src/cache/ftcglyph.h deleted file mode 100644 index 5fed19cb8f..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcglyph.h +++ /dev/null @@ -1,329 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcglyph.h */ -/* */ -/* FreeType abstract glyph cache (specification). */ -/* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 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. */ -/* */ -/***************************************************************************/ - - - /* - * - * FTC_GCache is an _abstract_ cache object optimized to store glyph - * data. It works as follows: - * - * - It manages FTC_GNode objects. Each one of them can hold one or more - * glyph `items'. Item types are not specified in the FTC_GCache but - * in classes that extend it. - * - * - Glyph attributes, like face ID, character size, render mode, etc., - * can be grouped into abstract `glyph families'. This avoids storing - * the attributes within the FTC_GCache, since it is likely that many - * FTC_GNodes will belong to the same family in typical uses. - * - * - Each FTC_GNode is thus an FTC_Node with two additional fields: - * - * * gindex: A glyph index, or the first index in a glyph range. - * * family: A pointer to a glyph `family'. - * - * - Family types are not fully specific in the FTC_Family type, but - * by classes that extend it. - * - * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. - * They share an FTC_Family sub-class called FTC_BasicFamily which is - * used to store the following data: face ID, pixel/point sizes, load - * flags. For more details see the file `src/cache/ftcbasic.c'. - * - * Client applications can extend FTC_GNode with their own FTC_GNode - * and FTC_Family sub-classes to implement more complex caches (e.g., - * handling automatic synthesis, like obliquing & emboldening, colored - * glyphs, etc.). - * - * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and - * `ftcsbits.h', which both extend FTC_GCache with additional - * optimizations. - * - * A typical FTC_GCache implementation must provide at least the - * following: - * - * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: - * my_node_new (must call FTC_GNode_Init) - * my_node_free (must call FTC_GNode_Done) - * my_node_compare (must call FTC_GNode_Compare) - * my_node_remove_faceid (must call ftc_gnode_unselect in case - * of match) - * - * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: - * my_family_compare - * my_family_init - * my_family_reset (optional) - * my_family_done - * - * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query - * data. - * - * - Constant structures for a FTC_GNodeClass. - * - * - MyCacheNew() can be implemented easily as a call to the convenience - * function FTC_GCache_New. - * - * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will - * automatically: - * - * - Search for the corresponding family in the cache, or create - * a new one if necessary. Put it in FTC_GQUERY(myquery).family - * - * - Call FTC_Cache_Lookup. - * - * If it returns NULL, you should create a new node, then call - * ftc_cache_add as usual. - */ - - - /*************************************************************************/ - /* */ - /* Important: The functions defined in this file are only used to */ - /* implement an abstract glyph cache class. You need to */ - /* provide additional logic to implement a complete cache. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********* *********/ - /********* WARNING, THIS IS BETA CODE. *********/ - /********* *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#ifndef __FTCGLYPH_H__ -#define __FTCGLYPH_H__ - - -#include <ft2build.h> -#include "ftcmanag.h" - - -FT_BEGIN_HEADER - - - /* - * We can group glyphs into `families'. Each family correspond to a - * given face ID, character size, transform, etc. - * - * Families are implemented as MRU list nodes. They are - * reference-counted. - */ - - typedef struct FTC_FamilyRec_ - { - FTC_MruNodeRec mrunode; - FT_UInt num_nodes; /* current number of nodes in this family */ - FTC_Cache cache; - FTC_MruListClass clazz; - - } FTC_FamilyRec, *FTC_Family; - -#define FTC_FAMILY(x) ( (FTC_Family)(x) ) -#define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) - - - typedef struct FTC_GNodeRec_ - { - FTC_NodeRec node; - FTC_Family family; - FT_UInt gindex; - - } FTC_GNodeRec, *FTC_GNode; - -#define FTC_GNODE( x ) ( (FTC_GNode)(x) ) -#define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) - - - typedef struct FTC_GQueryRec_ - { - FT_UInt gindex; - FTC_Family family; - - } FTC_GQueryRec, *FTC_GQuery; - -#define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) - - - /*************************************************************************/ - /* */ - /* These functions are exported so that they can be called from */ - /* user-provided cache classes; otherwise, they are really part of the */ - /* cache sub-system internals. */ - /* */ - - /* must be called by derived FTC_Node_InitFunc routines */ - FT_LOCAL( void ) - FTC_GNode_Init( FTC_GNode node, - FT_UInt gindex, /* glyph index for node */ - FTC_Family family ); - -#ifdef FTC_INLINE - - /* returns TRUE iff the query's glyph index correspond to the node; */ - /* this assumes that the `family' and `hash' fields of the query are */ - /* already correctly set */ - FT_LOCAL( FT_Bool ) - FTC_GNode_Compare( FTC_GNode gnode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed ); - -#endif - - /* call this function to clear a node's family -- this is necessary */ - /* to implement the `node_remove_faceid' cache method correctly */ - FT_LOCAL( void ) - FTC_GNode_UnselectFamily( FTC_GNode gnode, - FTC_Cache cache ); - - /* must be called by derived FTC_Node_DoneFunc routines */ - FT_LOCAL( void ) - FTC_GNode_Done( FTC_GNode node, - FTC_Cache cache ); - - - FT_LOCAL( void ) - FTC_Family_Init( FTC_Family family, - FTC_Cache cache ); - - typedef struct FTC_GCacheRec_ - { - FTC_CacheRec cache; - FTC_MruListRec families; - - } FTC_GCacheRec, *FTC_GCache; - -#define FTC_GCACHE( x ) ((FTC_GCache)(x)) - - -#if 0 - /* can be used as @FTC_Cache_InitFunc */ - FT_LOCAL( FT_Error ) - FTC_GCache_Init( FTC_GCache cache ); -#endif - - -#if 0 - /* can be used as @FTC_Cache_DoneFunc */ - FT_LOCAL( void ) - FTC_GCache_Done( FTC_GCache cache ); -#endif - - - /* the glyph cache class adds fields for the family implementation */ - typedef struct FTC_GCacheClassRec_ - { - FTC_CacheClassRec clazz; - FTC_MruListClass family_class; - - } FTC_GCacheClassRec; - - typedef const FTC_GCacheClassRec* FTC_GCacheClass; - -#define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) - -#define FTC_CACHE__GCACHE_CLASS( x ) \ - FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) -#define FTC_CACHE__FAMILY_CLASS( x ) \ - ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) - - - /* convenience function; use it instead of FTC_Manager_Register_Cache */ - FT_LOCAL( FT_Error ) - FTC_GCache_New( FTC_Manager manager, - FTC_GCacheClass clazz, - FTC_GCache *acache ); - -#ifndef FTC_INLINE - FT_LOCAL( FT_Error ) - FTC_GCache_Lookup( FTC_GCache cache, - FT_PtrDist hash, - FT_UInt gindex, - FTC_GQuery query, - FTC_Node *anode ); -#endif - - - /* */ - - -#define FTC_FAMILY_FREE( family, cache ) \ - FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \ - (FTC_MruNode)(family) ) - - -#ifdef FTC_INLINE - -#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ - gindex, query, node, error ) \ - FT_BEGIN_STMNT \ - FTC_GCache _gcache = FTC_GCACHE( cache ); \ - FTC_GQuery _gquery = (FTC_GQuery)( query ); \ - FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ - FTC_MruNode _mrunode; \ - \ - \ - _gquery->gindex = (gindex); \ - \ - FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ - _mrunode, error ); \ - _gquery->family = FTC_FAMILY( _mrunode ); \ - if ( !error ) \ - { \ - FTC_Family _gqfamily = _gquery->family; \ - \ - \ - _gqfamily->num_nodes++; \ - \ - FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ - \ - if ( --_gqfamily->num_nodes == 0 ) \ - FTC_FAMILY_FREE( _gqfamily, _gcache ); \ - } \ - FT_END_STMNT - /* */ - -#else /* !FTC_INLINE */ - -#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ - gindex, query, node, error ) \ - FT_BEGIN_STMNT \ - \ - error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ - FTC_GQUERY( query ), &node ); \ - \ - FT_END_STMNT - -#endif /* !FTC_INLINE */ - - -FT_END_HEADER - - -#endif /* __FTCGLYPH_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcimage.c b/drivers/freetype/freetype/src/cache/ftcimage.c deleted file mode 100644 index c242ece021..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcimage.c +++ /dev/null @@ -1,163 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcimage.c */ -/* */ -/* FreeType Image cache (body). */ -/* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2010 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_CACHE_H -#include "ftcimage.h" -#include FT_INTERNAL_MEMORY_H - -#include "ftccback.h" -#include "ftcerror.h" - - - /* finalize a given glyph image node */ - FT_LOCAL_DEF( void ) - ftc_inode_free( FTC_Node ftcinode, - FTC_Cache cache ) - { - FTC_INode inode = (FTC_INode)ftcinode; - FT_Memory memory = cache->memory; - - - if ( inode->glyph ) - { - FT_Done_Glyph( inode->glyph ); - inode->glyph = NULL; - } - - FTC_GNode_Done( FTC_GNODE( inode ), cache ); - FT_FREE( inode ); - } - - - FT_LOCAL_DEF( void ) - FTC_INode_Free( FTC_INode inode, - FTC_Cache cache ) - { - ftc_inode_free( FTC_NODE( inode ), cache ); - } - - - /* initialize a new glyph image node */ - FT_LOCAL_DEF( FT_Error ) - FTC_INode_New( FTC_INode *pinode, - FTC_GQuery gquery, - FTC_Cache cache ) - { - FT_Memory memory = cache->memory; - FT_Error error; - FTC_INode inode = NULL; - - - if ( !FT_NEW( inode ) ) - { - FTC_GNode gnode = FTC_GNODE( inode ); - FTC_Family family = gquery->family; - FT_UInt gindex = gquery->gindex; - FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); - - - /* initialize its inner fields */ - FTC_GNode_Init( gnode, gindex, family ); - - /* we will now load the glyph image */ - error = clazz->family_load_glyph( family, gindex, cache, - &inode->glyph ); - if ( error ) - { - FTC_INode_Free( inode, cache ); - inode = NULL; - } - } - - *pinode = inode; - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - ftc_inode_new( FTC_Node *ftcpinode, - FT_Pointer ftcgquery, - FTC_Cache cache ) - { - FTC_INode *pinode = (FTC_INode*)ftcpinode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - - - return FTC_INode_New( pinode, gquery, cache ); - } - - - FT_LOCAL_DEF( FT_Offset ) - ftc_inode_weight( FTC_Node ftcinode, - FTC_Cache ftccache ) - { - FTC_INode inode = (FTC_INode)ftcinode; - FT_Offset size = 0; - FT_Glyph glyph = inode->glyph; - - FT_UNUSED( ftccache ); - - - switch ( glyph->format ) - { - case FT_GLYPH_FORMAT_BITMAP: - { - FT_BitmapGlyph bitg; - - - bitg = (FT_BitmapGlyph)glyph; - size = bitg->bitmap.rows * ft_labs( bitg->bitmap.pitch ) + - sizeof ( *bitg ); - } - break; - - case FT_GLYPH_FORMAT_OUTLINE: - { - FT_OutlineGlyph outg; - - - outg = (FT_OutlineGlyph)glyph; - size = outg->outline.n_points * - ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + - outg->outline.n_contours * sizeof ( FT_Short ) + - sizeof ( *outg ); - } - break; - - default: - ; - } - - size += sizeof ( *inode ); - return size; - } - - -#if 0 - - FT_LOCAL_DEF( FT_Offset ) - FTC_INode_Weight( FTC_INode inode ) - { - return ftc_inode_weight( FTC_NODE( inode ), NULL ); - } - -#endif /* 0 */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcimage.h b/drivers/freetype/freetype/src/cache/ftcimage.h deleted file mode 100644 index 20d5d3e07d..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcimage.h +++ /dev/null @@ -1,107 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcimage.h */ -/* */ -/* FreeType Generic Image cache (specification) */ -/* */ -/* Copyright 2000-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, */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /* - * FTC_ICache is an _abstract_ cache used to store a single FT_Glyph - * image per cache node. - * - * FTC_ICache extends FTC_GCache. For an implementation example, - * see FTC_ImageCache in `src/cache/ftbasic.c'. - */ - - - /*************************************************************************/ - /* */ - /* Each image cache really manages FT_Glyph objects. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTCIMAGE_H__ -#define __FTCIMAGE_H__ - - -#include <ft2build.h> -#include FT_CACHE_H -#include "ftcglyph.h" - -FT_BEGIN_HEADER - - - /* the FT_Glyph image node type - we store only 1 glyph per node */ - typedef struct FTC_INodeRec_ - { - FTC_GNodeRec gnode; - FT_Glyph glyph; - - } FTC_INodeRec, *FTC_INode; - -#define FTC_INODE( x ) ( (FTC_INode)( x ) ) -#define FTC_INODE_GINDEX( x ) FTC_GNODE(x)->gindex -#define FTC_INODE_FAMILY( x ) FTC_GNODE(x)->family - - typedef FT_Error - (*FTC_IFamily_LoadGlyphFunc)( FTC_Family family, - FT_UInt gindex, - FTC_Cache cache, - FT_Glyph *aglyph ); - - typedef struct FTC_IFamilyClassRec_ - { - FTC_MruListClassRec clazz; - FTC_IFamily_LoadGlyphFunc family_load_glyph; - - } FTC_IFamilyClassRec; - - typedef const FTC_IFamilyClassRec* FTC_IFamilyClass; - -#define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) - -#define FTC_CACHE__IFAMILY_CLASS( x ) \ - FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) - - - /* can be used as a @FTC_Node_FreeFunc */ - FT_LOCAL( void ) - FTC_INode_Free( FTC_INode inode, - FTC_Cache cache ); - - /* Can be used as @FTC_Node_NewFunc. `gquery.index' and `gquery.family' - * must be set correctly. This function will call the `family_load_glyph' - * method to load the FT_Glyph into the cache node. - */ - FT_LOCAL( FT_Error ) - FTC_INode_New( FTC_INode *pinode, - FTC_GQuery gquery, - FTC_Cache cache ); - -#if 0 - /* can be used as @FTC_Node_WeightFunc */ - FT_LOCAL( FT_ULong ) - FTC_INode_Weight( FTC_INode inode ); -#endif - - - /* */ - -FT_END_HEADER - -#endif /* __FTCIMAGE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcmanag.c b/drivers/freetype/freetype/src/cache/ftcmanag.c deleted file mode 100644 index 4eb2c5bfd6..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcmanag.c +++ /dev/null @@ -1,693 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcmanag.c */ -/* */ -/* FreeType Cache Manager (body). */ -/* */ -/* Copyright 2000-2006, 2008-2010, 2013 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_CACHE_H -#include "ftcmanag.h" -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_SIZES_H - -#include "ftccback.h" -#include "ftcerror.h" - -#ifdef FT_CONFIG_OPTION_PIC -#error "cache system does not support PIC yet" -#endif - - -#undef FT_COMPONENT -#define FT_COMPONENT trace_cache - -#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) - - - static FT_Error - ftc_scaler_lookup_size( FTC_Manager manager, - FTC_Scaler scaler, - FT_Size *asize ) - { - FT_Face face; - FT_Size size = NULL; - FT_Error error; - - - error = FTC_Manager_LookupFace( manager, scaler->face_id, &face ); - if ( error ) - goto Exit; - - error = FT_New_Size( face, &size ); - if ( error ) - goto Exit; - - FT_Activate_Size( size ); - - if ( scaler->pixel ) - error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); - else - error = FT_Set_Char_Size( face, scaler->width, scaler->height, - scaler->x_res, scaler->y_res ); - if ( error ) - { - FT_Done_Size( size ); - size = NULL; - } - - Exit: - *asize = size; - return error; - } - - - typedef struct FTC_SizeNodeRec_ - { - FTC_MruNodeRec node; - FT_Size size; - FTC_ScalerRec scaler; - - } FTC_SizeNodeRec, *FTC_SizeNode; - -#define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) ) - - - FT_CALLBACK_DEF( void ) - ftc_size_node_done( FTC_MruNode ftcnode, - FT_Pointer data ) - { - FTC_SizeNode node = (FTC_SizeNode)ftcnode; - FT_Size size = node->size; - FT_UNUSED( data ); - - - if ( size ) - FT_Done_Size( size ); - } - - - FT_CALLBACK_DEF( FT_Bool ) - ftc_size_node_compare( FTC_MruNode ftcnode, - FT_Pointer ftcscaler ) - { - FTC_SizeNode node = (FTC_SizeNode)ftcnode; - FTC_Scaler scaler = (FTC_Scaler)ftcscaler; - FTC_Scaler scaler0 = &node->scaler; - - - if ( FTC_SCALER_COMPARE( scaler0, scaler ) ) - { - FT_Activate_Size( node->size ); - return 1; - } - return 0; - } - - - FT_CALLBACK_DEF( FT_Error ) - ftc_size_node_init( FTC_MruNode ftcnode, - FT_Pointer ftcscaler, - FT_Pointer ftcmanager ) - { - FTC_SizeNode node = (FTC_SizeNode)ftcnode; - FTC_Scaler scaler = (FTC_Scaler)ftcscaler; - FTC_Manager manager = (FTC_Manager)ftcmanager; - - - node->scaler = scaler[0]; - - return ftc_scaler_lookup_size( manager, scaler, &node->size ); - } - - - FT_CALLBACK_DEF( FT_Error ) - ftc_size_node_reset( FTC_MruNode ftcnode, - FT_Pointer ftcscaler, - FT_Pointer ftcmanager ) - { - FTC_SizeNode node = (FTC_SizeNode)ftcnode; - FTC_Scaler scaler = (FTC_Scaler)ftcscaler; - FTC_Manager manager = (FTC_Manager)ftcmanager; - - - FT_Done_Size( node->size ); - - node->scaler = scaler[0]; - - return ftc_scaler_lookup_size( manager, scaler, &node->size ); - } - - - FT_CALLBACK_TABLE_DEF - const FTC_MruListClassRec ftc_size_list_class = - { - sizeof ( FTC_SizeNodeRec ), - ftc_size_node_compare, - ftc_size_node_init, - ftc_size_node_reset, - ftc_size_node_done - }; - - - /* helper function used by ftc_face_node_done */ - static FT_Bool - ftc_size_node_compare_faceid( FTC_MruNode ftcnode, - FT_Pointer ftcface_id ) - { - FTC_SizeNode node = (FTC_SizeNode)ftcnode; - FTC_FaceID face_id = (FTC_FaceID)ftcface_id; - - - return FT_BOOL( node->scaler.face_id == face_id ); - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_Manager_LookupSize( FTC_Manager manager, - FTC_Scaler scaler, - FT_Size *asize ) - { - FT_Error error; - FTC_MruNode mrunode; - - - if ( asize == NULL ) - return FT_THROW( Invalid_Argument ); - - *asize = NULL; - - if ( !manager ) - return FT_THROW( Invalid_Cache_Handle ); - -#ifdef FTC_INLINE - - FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, - mrunode, error ); - -#else - error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode ); -#endif - - if ( !error ) - *asize = FTC_SIZE_NODE( mrunode )->size; - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FACE MRU IMPLEMENTATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct FTC_FaceNodeRec_ - { - FTC_MruNodeRec node; - FTC_FaceID face_id; - FT_Face face; - - } FTC_FaceNodeRec, *FTC_FaceNode; - -#define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) ) - - - FT_CALLBACK_DEF( FT_Error ) - ftc_face_node_init( FTC_MruNode ftcnode, - FT_Pointer ftcface_id, - FT_Pointer ftcmanager ) - { - FTC_FaceNode node = (FTC_FaceNode)ftcnode; - FTC_FaceID face_id = (FTC_FaceID)ftcface_id; - FTC_Manager manager = (FTC_Manager)ftcmanager; - FT_Error error; - - - node->face_id = face_id; - - error = manager->request_face( face_id, - manager->library, - manager->request_data, - &node->face ); - if ( !error ) - { - /* destroy initial size object; it will be re-created later */ - if ( node->face->size ) - FT_Done_Size( node->face->size ); - } - - return error; - } - - - FT_CALLBACK_DEF( void ) - ftc_face_node_done( FTC_MruNode ftcnode, - FT_Pointer ftcmanager ) - { - FTC_FaceNode node = (FTC_FaceNode)ftcnode; - FTC_Manager manager = (FTC_Manager)ftcmanager; - - - /* we must begin by removing all scalers for the target face */ - /* from the manager's list */ - FTC_MruList_RemoveSelection( &manager->sizes, - ftc_size_node_compare_faceid, - node->face_id ); - - /* all right, we can discard the face now */ - FT_Done_Face( node->face ); - node->face = NULL; - node->face_id = NULL; - } - - - FT_CALLBACK_DEF( FT_Bool ) - ftc_face_node_compare( FTC_MruNode ftcnode, - FT_Pointer ftcface_id ) - { - FTC_FaceNode node = (FTC_FaceNode)ftcnode; - FTC_FaceID face_id = (FTC_FaceID)ftcface_id; - - - return FT_BOOL( node->face_id == face_id ); - } - - - FT_CALLBACK_TABLE_DEF - const FTC_MruListClassRec ftc_face_list_class = - { - sizeof ( FTC_FaceNodeRec), - - ftc_face_node_compare, - ftc_face_node_init, - 0, /* FTC_MruNode_ResetFunc */ - ftc_face_node_done - }; - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_Manager_LookupFace( FTC_Manager manager, - FTC_FaceID face_id, - FT_Face *aface ) - { - FT_Error error; - FTC_MruNode mrunode; - - - if ( aface == NULL ) - return FT_THROW( Invalid_Argument ); - - *aface = NULL; - - if ( !manager ) - return FT_THROW( Invalid_Cache_Handle ); - - /* we break encapsulation for the sake of speed */ -#ifdef FTC_INLINE - - FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, - mrunode, error ); - -#else - error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode ); -#endif - - if ( !error ) - *aface = FTC_FACE_NODE( mrunode )->face; - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE MANAGER ROUTINES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_Manager_New( FT_Library library, - FT_UInt max_faces, - FT_UInt max_sizes, - FT_ULong max_bytes, - FTC_Face_Requester requester, - FT_Pointer req_data, - FTC_Manager *amanager ) - { - FT_Error error; - FT_Memory memory; - FTC_Manager manager = 0; - - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - memory = library->memory; - - if ( FT_NEW( manager ) ) - goto Exit; - - if ( max_faces == 0 ) - max_faces = FTC_MAX_FACES_DEFAULT; - - if ( max_sizes == 0 ) - max_sizes = FTC_MAX_SIZES_DEFAULT; - - if ( max_bytes == 0 ) - max_bytes = FTC_MAX_BYTES_DEFAULT; - - manager->library = library; - manager->memory = memory; - manager->max_weight = max_bytes; - - manager->request_face = requester; - manager->request_data = req_data; - - FTC_MruList_Init( &manager->faces, - &ftc_face_list_class, - max_faces, - manager, - memory ); - - FTC_MruList_Init( &manager->sizes, - &ftc_size_list_class, - max_sizes, - manager, - memory ); - - *amanager = manager; - - Exit: - return error; - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( void ) - FTC_Manager_Done( FTC_Manager manager ) - { - FT_Memory memory; - FT_UInt idx; - - - if ( !manager || !manager->library ) - return; - - memory = manager->memory; - - /* now discard all caches */ - for (idx = manager->num_caches; idx-- > 0; ) - { - FTC_Cache cache = manager->caches[idx]; - - - if ( cache ) - { - cache->clazz.cache_done( cache ); - FT_FREE( cache ); - manager->caches[idx] = NULL; - } - } - manager->num_caches = 0; - - /* discard faces and sizes */ - FTC_MruList_Done( &manager->sizes ); - FTC_MruList_Done( &manager->faces ); - - manager->library = NULL; - manager->memory = NULL; - - FT_FREE( manager ); - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( void ) - FTC_Manager_Reset( FTC_Manager manager ) - { - if ( manager ) - { - FTC_MruList_Reset( &manager->sizes ); - FTC_MruList_Reset( &manager->faces ); - } - - FTC_Manager_FlushN( manager, manager->num_nodes ); - } - - -#ifdef FT_DEBUG_ERROR - - static void - FTC_Manager_Check( FTC_Manager manager ) - { - FTC_Node node, first; - - - first = manager->nodes_list; - - /* check node weights */ - if ( first ) - { - FT_Offset weight = 0; - - - node = first; - - do - { - FTC_Cache cache = manager->caches[node->cache_index]; - - - if ( (FT_UInt)node->cache_index >= manager->num_caches ) - FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %ld\n", - node->cache_index )); - else - weight += cache->clazz.node_weight( node, cache ); - - node = FTC_NODE__NEXT( node ); - - } while ( node != first ); - - if ( weight != manager->cur_weight ) - FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", - manager->cur_weight, weight )); - } - - /* check circular list */ - if ( first ) - { - FT_UFast count = 0; - - - node = first; - do - { - count++; - node = FTC_NODE__NEXT( node ); - - } while ( node != first ); - - if ( count != manager->num_nodes ) - FT_TRACE0(( "FTC_Manager_Check:" - " invalid cache node count %d instead of %d\n", - manager->num_nodes, count )); - } - } - -#endif /* FT_DEBUG_ERROR */ - - - /* `Compress' the manager's data, i.e., get rid of old cache nodes */ - /* that are not referenced anymore in order to limit the total */ - /* memory used by the cache. */ - - /* documentation is in ftcmanag.h */ - - FT_LOCAL_DEF( void ) - FTC_Manager_Compress( FTC_Manager manager ) - { - FTC_Node node, first; - - - if ( !manager ) - return; - - first = manager->nodes_list; - -#ifdef FT_DEBUG_ERROR - FTC_Manager_Check( manager ); - - FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n", - manager->cur_weight, manager->max_weight, - manager->num_nodes )); -#endif - - if ( manager->cur_weight < manager->max_weight || first == NULL ) - return; - - /* go to last node -- it's a circular list */ - node = FTC_NODE__PREV( first ); - do - { - FTC_Node prev; - - - prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); - - if ( node->ref_count <= 0 ) - ftc_node_destroy( node, manager ); - - node = prev; - - } while ( node && manager->cur_weight > manager->max_weight ); - } - - - /* documentation is in ftcmanag.h */ - - FT_LOCAL_DEF( FT_Error ) - FTC_Manager_RegisterCache( FTC_Manager manager, - FTC_CacheClass clazz, - FTC_Cache *acache ) - { - FT_Error error = FT_ERR( Invalid_Argument ); - FTC_Cache cache = NULL; - - - if ( manager && clazz && acache ) - { - FT_Memory memory = manager->memory; - - - if ( manager->num_caches >= FTC_MAX_CACHES ) - { - error = FT_THROW( Too_Many_Caches ); - FT_ERROR(( "FTC_Manager_RegisterCache:" - " too many registered caches\n" )); - goto Exit; - } - - if ( !FT_ALLOC( cache, clazz->cache_size ) ) - { - cache->manager = manager; - cache->memory = memory; - cache->clazz = clazz[0]; - cache->org_class = clazz; - - /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ - /* IF IT IS NOT SET CORRECTLY */ - cache->index = manager->num_caches; - - error = clazz->cache_init( cache ); - if ( error ) - { - clazz->cache_done( cache ); - FT_FREE( cache ); - goto Exit; - } - - manager->caches[manager->num_caches++] = cache; - } - } - - Exit: - if ( acache ) - *acache = cache; - return error; - } - - - FT_LOCAL_DEF( FT_UInt ) - FTC_Manager_FlushN( FTC_Manager manager, - FT_UInt count ) - { - FTC_Node first = manager->nodes_list; - FTC_Node node; - FT_UInt result; - - - /* try to remove `count' nodes from the list */ - if ( first == NULL ) /* empty list! */ - return 0; - - /* go to last node - it's a circular list */ - node = FTC_NODE__PREV(first); - for ( result = 0; result < count; ) - { - FTC_Node prev = FTC_NODE__PREV( node ); - - - /* don't touch locked nodes */ - if ( node->ref_count <= 0 ) - { - ftc_node_destroy( node, manager ); - result++; - } - - if ( node == first ) - break; - - node = prev; - } - return result; - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( void ) - FTC_Manager_RemoveFaceID( FTC_Manager manager, - FTC_FaceID face_id ) - { - FT_UInt nn; - - /* this will remove all FTC_SizeNode that correspond to - * the face_id as well - */ - FTC_MruList_RemoveSelection( &manager->faces, - ftc_face_node_compare, - face_id ); - - for ( nn = 0; nn < manager->num_caches; nn++ ) - FTC_Cache_RemoveFaceID( manager->caches[nn], face_id ); - } - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( void ) - FTC_Node_Unref( FTC_Node node, - FTC_Manager manager ) - { - if ( node && (FT_UInt)node->cache_index < manager->num_caches ) - node->ref_count--; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcmanag.h b/drivers/freetype/freetype/src/cache/ftcmanag.h deleted file mode 100644 index 0aec33c584..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcmanag.h +++ /dev/null @@ -1,175 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcmanag.h */ -/* */ -/* FreeType Cache Manager (specification). */ -/* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2010, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* A cache manager is in charge of the following: */ - /* */ - /* - Maintain a mapping between generic FTC_FaceIDs and live FT_Face */ - /* objects. The mapping itself is performed through a user-provided */ - /* callback. However, the manager maintains a small cache of FT_Face */ - /* and FT_Size objects in order to speed up things considerably. */ - /* */ - /* - Manage one or more cache objects. Each cache is in charge of */ - /* holding a varying number of `cache nodes'. Each cache node */ - /* represents a minimal amount of individually accessible cached */ - /* data. For example, a cache node can be an FT_Glyph image */ - /* containing a vector outline, or some glyph metrics, or anything */ - /* else. */ - /* */ - /* Each cache node has a certain size in bytes that is added to the */ - /* total amount of `cache memory' within the manager. */ - /* */ - /* All cache nodes are located in a global LRU list, where the oldest */ - /* node is at the tail of the list. */ - /* */ - /* Each node belongs to a single cache, and includes a reference */ - /* count to avoid destroying it (due to caching). */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********* *********/ - /********* WARNING, THIS IS BETA CODE. *********/ - /********* *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#ifndef __FTCMANAG_H__ -#define __FTCMANAG_H__ - - -#include <ft2build.h> -#include FT_CACHE_H -#include "ftcmru.h" -#include "ftccache.h" - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* cache_subsystem */ - /* */ - /*************************************************************************/ - - -#define FTC_MAX_FACES_DEFAULT 2 -#define FTC_MAX_SIZES_DEFAULT 4 -#define FTC_MAX_BYTES_DEFAULT 200000L /* ~200kByte by default */ - - /* maximum number of caches registered in a single manager */ -#define FTC_MAX_CACHES 16 - - - typedef struct FTC_ManagerRec_ - { - FT_Library library; - FT_Memory memory; - - FTC_Node nodes_list; - FT_Offset max_weight; - FT_Offset cur_weight; - FT_UInt num_nodes; - - FTC_Cache caches[FTC_MAX_CACHES]; - FT_UInt num_caches; - - FTC_MruListRec faces; - FTC_MruListRec sizes; - - FT_Pointer request_data; - FTC_Face_Requester request_face; - - } FTC_ManagerRec; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_Compress */ - /* */ - /* <Description> */ - /* This function is used to check the state of the cache manager if */ - /* its `num_bytes' field is greater than its `max_bytes' field. It */ - /* will flush as many old cache nodes as possible (ignoring cache */ - /* nodes with a non-zero reference count). */ - /* */ - /* <InOut> */ - /* manager :: A handle to the cache manager. */ - /* */ - /* <Note> */ - /* Client applications should not call this function directly. It is */ - /* normally invoked by specific cache implementations. */ - /* */ - /* The reason this function is exported is to allow client-specific */ - /* cache classes. */ - /* */ - FT_LOCAL( void ) - FTC_Manager_Compress( FTC_Manager manager ); - - - /* try to flush `count' old nodes from the cache; return the number - * of really flushed nodes - */ - FT_LOCAL( FT_UInt ) - FTC_Manager_FlushN( FTC_Manager manager, - FT_UInt count ); - - - /* this must be used internally for the moment */ - FT_LOCAL( FT_Error ) - FTC_Manager_RegisterCache( FTC_Manager manager, - FTC_CacheClass clazz, - FTC_Cache *acache ); - - /* */ - -#define FTC_SCALER_COMPARE( a, b ) \ - ( (a)->face_id == (b)->face_id && \ - (a)->width == (b)->width && \ - (a)->height == (b)->height && \ - ((a)->pixel != 0) == ((b)->pixel != 0) && \ - ( (a)->pixel || \ - ( (a)->x_res == (b)->x_res && \ - (a)->y_res == (b)->y_res ) ) ) - -#define FTC_SCALER_HASH( q ) \ - ( _FTC_FACE_ID_HASH( (q)->face_id ) + \ - (q)->width + (q)->height*7 + \ - ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) ) - - /* */ - -FT_END_HEADER - -#endif /* __FTCMANAG_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcmru.c b/drivers/freetype/freetype/src/cache/ftcmru.c deleted file mode 100644 index dc8b4cc397..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcmru.c +++ /dev/null @@ -1,357 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcmru.c */ -/* */ -/* FreeType MRU support (body). */ -/* */ -/* Copyright 2003, 2004, 2006, 2009 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_CACHE_H -#include "ftcmru.h" -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H - -#include "ftcerror.h" - - - FT_LOCAL_DEF( void ) - FTC_MruNode_Prepend( FTC_MruNode *plist, - FTC_MruNode node ) - { - FTC_MruNode first = *plist; - - - if ( first ) - { - FTC_MruNode last = first->prev; - - -#ifdef FT_DEBUG_ERROR - { - FTC_MruNode cnode = first; - - - do - { - if ( cnode == node ) - { - fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" ); - exit( 2 ); - } - cnode = cnode->next; - - } while ( cnode != first ); - } -#endif - - first->prev = node; - last->next = node; - node->next = first; - node->prev = last; - } - else - { - node->next = node; - node->prev = node; - } - *plist = node; - } - - - FT_LOCAL_DEF( void ) - FTC_MruNode_Up( FTC_MruNode *plist, - FTC_MruNode node ) - { - FTC_MruNode first = *plist; - - - FT_ASSERT( first != NULL ); - - if ( first != node ) - { - FTC_MruNode prev, next, last; - - -#ifdef FT_DEBUG_ERROR - { - FTC_MruNode cnode = first; - do - { - if ( cnode == node ) - goto Ok; - cnode = cnode->next; - - } while ( cnode != first ); - - fprintf( stderr, "FTC_MruNode_Up: invalid action\n" ); - exit( 2 ); - Ok: - } -#endif - prev = node->prev; - next = node->next; - - prev->next = next; - next->prev = prev; - - last = first->prev; - - last->next = node; - first->prev = node; - - node->next = first; - node->prev = last; - - *plist = node; - } - } - - - FT_LOCAL_DEF( void ) - FTC_MruNode_Remove( FTC_MruNode *plist, - FTC_MruNode node ) - { - FTC_MruNode first = *plist; - FTC_MruNode prev, next; - - - FT_ASSERT( first != NULL ); - -#ifdef FT_DEBUG_ERROR - { - FTC_MruNode cnode = first; - - - do - { - if ( cnode == node ) - goto Ok; - cnode = cnode->next; - - } while ( cnode != first ); - - fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" ); - exit( 2 ); - Ok: - } -#endif - - prev = node->prev; - next = node->next; - - prev->next = next; - next->prev = prev; - - if ( node == next ) - { - FT_ASSERT( first == node ); - FT_ASSERT( prev == node ); - - *plist = NULL; - } - else if ( node == first ) - *plist = next; - } - - - FT_LOCAL_DEF( void ) - FTC_MruList_Init( FTC_MruList list, - FTC_MruListClass clazz, - FT_UInt max_nodes, - FT_Pointer data, - FT_Memory memory ) - { - list->num_nodes = 0; - list->max_nodes = max_nodes; - list->nodes = NULL; - list->clazz = *clazz; - list->data = data; - list->memory = memory; - } - - - FT_LOCAL_DEF( void ) - FTC_MruList_Reset( FTC_MruList list ) - { - while ( list->nodes ) - FTC_MruList_Remove( list, list->nodes ); - - FT_ASSERT( list->num_nodes == 0 ); - } - - - FT_LOCAL_DEF( void ) - FTC_MruList_Done( FTC_MruList list ) - { - FTC_MruList_Reset( list ); - } - - -#ifndef FTC_INLINE - FT_LOCAL_DEF( FTC_MruNode ) - FTC_MruList_Find( FTC_MruList list, - FT_Pointer key ) - { - FTC_MruNode_CompareFunc compare = list->clazz.node_compare; - FTC_MruNode first, node; - - - first = list->nodes; - node = NULL; - - if ( first ) - { - node = first; - do - { - if ( compare( node, key ) ) - { - if ( node != first ) - FTC_MruNode_Up( &list->nodes, node ); - - return node; - } - - node = node->next; - - } while ( node != first); - } - - return NULL; - } -#endif - - FT_LOCAL_DEF( FT_Error ) - FTC_MruList_New( FTC_MruList list, - FT_Pointer key, - FTC_MruNode *anode ) - { - FT_Error error; - FTC_MruNode node = NULL; - FT_Memory memory = list->memory; - - - if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 ) - { - node = list->nodes->prev; - - FT_ASSERT( node ); - - if ( list->clazz.node_reset ) - { - FTC_MruNode_Up( &list->nodes, node ); - - error = list->clazz.node_reset( node, key, list->data ); - if ( !error ) - goto Exit; - } - - FTC_MruNode_Remove( &list->nodes, node ); - list->num_nodes--; - - if ( list->clazz.node_done ) - list->clazz.node_done( node, list->data ); - } - else if ( FT_ALLOC( node, list->clazz.node_size ) ) - goto Exit; - - error = list->clazz.node_init( node, key, list->data ); - if ( error ) - goto Fail; - - FTC_MruNode_Prepend( &list->nodes, node ); - list->num_nodes++; - - Exit: - *anode = node; - return error; - - Fail: - if ( list->clazz.node_done ) - list->clazz.node_done( node, list->data ); - - FT_FREE( node ); - goto Exit; - } - - -#ifndef FTC_INLINE - FT_LOCAL_DEF( FT_Error ) - FTC_MruList_Lookup( FTC_MruList list, - FT_Pointer key, - FTC_MruNode *anode ) - { - FTC_MruNode node; - - - node = FTC_MruList_Find( list, key ); - if ( node == NULL ) - return FTC_MruList_New( list, key, anode ); - - *anode = node; - return 0; - } -#endif /* FTC_INLINE */ - - FT_LOCAL_DEF( void ) - FTC_MruList_Remove( FTC_MruList list, - FTC_MruNode node ) - { - FTC_MruNode_Remove( &list->nodes, node ); - list->num_nodes--; - - { - FT_Memory memory = list->memory; - - - if ( list->clazz.node_done ) - list->clazz.node_done( node, list->data ); - - FT_FREE( node ); - } - } - - - FT_LOCAL_DEF( void ) - FTC_MruList_RemoveSelection( FTC_MruList list, - FTC_MruNode_CompareFunc selection, - FT_Pointer key ) - { - FTC_MruNode first, node, next; - - - first = list->nodes; - while ( first && ( selection == NULL || selection( first, key ) ) ) - { - FTC_MruList_Remove( list, first ); - first = list->nodes; - } - - if ( first ) - { - node = first->next; - while ( node != first ) - { - next = node->next; - - if ( selection( node, key ) ) - FTC_MruList_Remove( list, node ); - - node = next; - } - } - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcmru.h b/drivers/freetype/freetype/src/cache/ftcmru.h deleted file mode 100644 index 6fccf11781..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcmru.h +++ /dev/null @@ -1,246 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcmru.h */ -/* */ -/* Simple MRU list-cache (specification). */ -/* */ -/* Copyright 2000-2001, 2003-2006, 2010, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* An MRU is a list that cannot hold more than a certain number of */ - /* elements (`max_elements'). All elements in the list are sorted in */ - /* least-recently-used order, i.e., the `oldest' element is at the tail */ - /* of the list. */ - /* */ - /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ - /* the list is searched for an element with the corresponding key. If */ - /* it is found, the element is moved to the head of the list and is */ - /* returned. */ - /* */ - /* If no corresponding element is found, the lookup routine will try to */ - /* obtain a new element with the relevant key. If the list is already */ - /* full, the oldest element from the list is discarded and replaced by a */ - /* new one; a new element is added to the list otherwise. */ - /* */ - /* Note that it is possible to pre-allocate the element list nodes. */ - /* This is handy if `max_elements' is sufficiently small, as it saves */ - /* allocations/releases during the lookup process. */ - /* */ - /*************************************************************************/ - - -#ifndef __FTCMRU_H__ -#define __FTCMRU_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - -#define xxFT_DEBUG_ERROR -#define FTC_INLINE - -FT_BEGIN_HEADER - - typedef struct FTC_MruNodeRec_* FTC_MruNode; - - typedef struct FTC_MruNodeRec_ - { - FTC_MruNode next; - FTC_MruNode prev; - - } FTC_MruNodeRec; - - - FT_LOCAL( void ) - FTC_MruNode_Prepend( FTC_MruNode *plist, - FTC_MruNode node ); - - FT_LOCAL( void ) - FTC_MruNode_Up( FTC_MruNode *plist, - FTC_MruNode node ); - - FT_LOCAL( void ) - FTC_MruNode_Remove( FTC_MruNode *plist, - FTC_MruNode node ); - - - typedef struct FTC_MruListRec_* FTC_MruList; - - typedef struct FTC_MruListClassRec_ const * FTC_MruListClass; - - - typedef FT_Bool - (*FTC_MruNode_CompareFunc)( FTC_MruNode node, - FT_Pointer key ); - - typedef FT_Error - (*FTC_MruNode_InitFunc)( FTC_MruNode node, - FT_Pointer key, - FT_Pointer data ); - - typedef FT_Error - (*FTC_MruNode_ResetFunc)( FTC_MruNode node, - FT_Pointer key, - FT_Pointer data ); - - typedef void - (*FTC_MruNode_DoneFunc)( FTC_MruNode node, - FT_Pointer data ); - - - typedef struct FTC_MruListClassRec_ - { - FT_Offset node_size; - FTC_MruNode_CompareFunc node_compare; - FTC_MruNode_InitFunc node_init; - FTC_MruNode_ResetFunc node_reset; - FTC_MruNode_DoneFunc node_done; - - } FTC_MruListClassRec; - - typedef struct FTC_MruListRec_ - { - FT_UInt num_nodes; - FT_UInt max_nodes; - FTC_MruNode nodes; - FT_Pointer data; - FTC_MruListClassRec clazz; - FT_Memory memory; - - } FTC_MruListRec; - - - FT_LOCAL( void ) - FTC_MruList_Init( FTC_MruList list, - FTC_MruListClass clazz, - FT_UInt max_nodes, - FT_Pointer data, - FT_Memory memory ); - - FT_LOCAL( void ) - FTC_MruList_Reset( FTC_MruList list ); - - - FT_LOCAL( void ) - FTC_MruList_Done( FTC_MruList list ); - - - FT_LOCAL( FT_Error ) - FTC_MruList_New( FTC_MruList list, - FT_Pointer key, - FTC_MruNode *anode ); - - FT_LOCAL( void ) - FTC_MruList_Remove( FTC_MruList list, - FTC_MruNode node ); - - FT_LOCAL( void ) - FTC_MruList_RemoveSelection( FTC_MruList list, - FTC_MruNode_CompareFunc selection, - FT_Pointer key ); - - -#ifdef FTC_INLINE - -#define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \ - FT_BEGIN_STMNT \ - FTC_MruNode* _pfirst = &(list)->nodes; \ - FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ - FTC_MruNode _first, _node; \ - \ - \ - error = FT_Err_Ok; \ - _first = *(_pfirst); \ - _node = NULL; \ - \ - if ( _first ) \ - { \ - _node = _first; \ - do \ - { \ - if ( _compare( _node, (key) ) ) \ - { \ - if ( _node != _first ) \ - FTC_MruNode_Up( _pfirst, _node ); \ - \ - node = _node; \ - goto _MruOk; \ - } \ - _node = _node->next; \ - \ - } while ( _node != _first) ; \ - } \ - \ - error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ - _MruOk: \ - ; \ - FT_END_STMNT - -#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ - FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error ) - -#else /* !FTC_INLINE */ - - FT_LOCAL( FTC_MruNode ) - FTC_MruList_Find( FTC_MruList list, - FT_Pointer key ); - - FT_LOCAL( FT_Error ) - FTC_MruList_Lookup( FTC_MruList list, - FT_Pointer key, - FTC_MruNode *pnode ); - -#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ - error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) - -#endif /* !FTC_INLINE */ - - -#define FTC_MRULIST_LOOP( list, node ) \ - FT_BEGIN_STMNT \ - FTC_MruNode _first = (list)->nodes; \ - \ - \ - if ( _first ) \ - { \ - FTC_MruNode _node = _first; \ - \ - \ - do \ - { \ - *(FTC_MruNode*)&(node) = _node; - - -#define FTC_MRULIST_LOOP_END() \ - _node = _node->next; \ - \ - } while ( _node != _first ); \ - } \ - FT_END_STMNT - - /* */ - -FT_END_HEADER - - -#endif /* __FTCMRU_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcsbits.c b/drivers/freetype/freetype/src/cache/ftcsbits.c deleted file mode 100644 index 6df1c19930..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcsbits.c +++ /dev/null @@ -1,421 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcsbits.c */ -/* */ -/* FreeType sbits manager (body). */ -/* */ -/* Copyright 2000-2006, 2009-2011, 2013 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_CACHE_H -#include "ftcsbits.h" -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_ERRORS_H - -#include "ftccback.h" -#include "ftcerror.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_cache - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SBIT CACHE NODES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - static FT_Error - ftc_sbit_copy_bitmap( FTC_SBit sbit, - FT_Bitmap* bitmap, - FT_Memory memory ) - { - FT_Error error; - FT_Int pitch = bitmap->pitch; - FT_ULong size; - - - if ( pitch < 0 ) - pitch = -pitch; - - size = (FT_ULong)( pitch * bitmap->rows ); - - if ( !FT_ALLOC( sbit->buffer, size ) ) - FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); - - return error; - } - - - FT_LOCAL_DEF( void ) - ftc_snode_free( FTC_Node ftcsnode, - FTC_Cache cache ) - { - FTC_SNode snode = (FTC_SNode)ftcsnode; - FTC_SBit sbit = snode->sbits; - FT_UInt count = snode->count; - FT_Memory memory = cache->memory; - - - for ( ; count > 0; sbit++, count-- ) - FT_FREE( sbit->buffer ); - - FTC_GNode_Done( FTC_GNODE( snode ), cache ); - - FT_FREE( snode ); - } - - - FT_LOCAL_DEF( void ) - FTC_SNode_Free( FTC_SNode snode, - FTC_Cache cache ) - { - ftc_snode_free( FTC_NODE( snode ), cache ); - } - - - /* - * This function tries to load a small bitmap within a given FTC_SNode. - * Note that it returns a non-zero error code _only_ in the case of - * out-of-memory condition. For all other errors (e.g., corresponding - * to a bad font file), this function will mark the sbit as `unavailable' - * and return a value of 0. - * - * You should also read the comment within the @ftc_snode_compare - * function below to see how out-of-memory is handled during a lookup. - */ - static FT_Error - ftc_snode_load( FTC_SNode snode, - FTC_Manager manager, - FT_UInt gindex, - FT_ULong *asize ) - { - FT_Error error; - FTC_GNode gnode = FTC_GNODE( snode ); - FTC_Family family = gnode->family; - FT_Memory memory = manager->memory; - FT_Face face; - FTC_SBit sbit; - FTC_SFamilyClass clazz; - - - if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) - { - FT_ERROR(( "ftc_snode_load: invalid glyph index" )); - return FT_THROW( Invalid_Argument ); - } - - sbit = snode->sbits + ( gindex - gnode->gindex ); - clazz = (FTC_SFamilyClass)family->clazz; - - sbit->buffer = 0; - - error = clazz->family_load_glyph( family, gindex, manager, &face ); - if ( error ) - goto BadGlyph; - - { - FT_Int temp; - FT_GlyphSlot slot = face->glyph; - FT_Bitmap* bitmap = &slot->bitmap; - FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */ - - - if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) - { - FT_TRACE0(( "ftc_snode_load:" - " glyph loaded didn't return a bitmap\n" )); - goto BadGlyph; - } - - /* Check that our values fit into 8-bit containers! */ - /* If this is not the case, our bitmap is too large */ - /* and we will leave it as `missing' with sbit.buffer = 0 */ - -#define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) -#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) - - /* horizontal advance in pixels */ - xadvance = ( slot->advance.x + 32 ) >> 6; - yadvance = ( slot->advance.y + 32 ) >> 6; - - if ( !CHECK_BYTE( bitmap->rows ) || - !CHECK_BYTE( bitmap->width ) || - !CHECK_CHAR( bitmap->pitch ) || - !CHECK_CHAR( slot->bitmap_left ) || - !CHECK_CHAR( slot->bitmap_top ) || - !CHECK_CHAR( xadvance ) || - !CHECK_CHAR( yadvance ) ) - { - FT_TRACE2(( "ftc_snode_load:" - " glyph too large for small bitmap cache\n")); - goto BadGlyph; - } - - sbit->width = (FT_Byte)bitmap->width; - sbit->height = (FT_Byte)bitmap->rows; - sbit->pitch = (FT_Char)bitmap->pitch; - sbit->left = (FT_Char)slot->bitmap_left; - sbit->top = (FT_Char)slot->bitmap_top; - sbit->xadvance = (FT_Char)xadvance; - sbit->yadvance = (FT_Char)yadvance; - sbit->format = (FT_Byte)bitmap->pixel_mode; - sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); - - /* copy the bitmap into a new buffer -- ignore error */ - error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); - - /* now, compute size */ - if ( asize ) - *asize = FT_ABS( sbit->pitch ) * sbit->height; - - } /* glyph loading successful */ - - /* ignore the errors that might have occurred -- */ - /* we mark unloaded glyphs with `sbit.buffer == 0' */ - /* and `width == 255', `height == 0' */ - /* */ - if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) ) - { - BadGlyph: - sbit->width = 255; - sbit->height = 0; - sbit->buffer = NULL; - error = FT_Err_Ok; - if ( asize ) - *asize = 0; - } - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - FTC_SNode_New( FTC_SNode *psnode, - FTC_GQuery gquery, - FTC_Cache cache ) - { - FT_Memory memory = cache->memory; - FT_Error error; - FTC_SNode snode = NULL; - FT_UInt gindex = gquery->gindex; - FTC_Family family = gquery->family; - - FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); - FT_UInt total; - FT_UInt node_count; - - - total = clazz->family_get_count( family, cache->manager ); - if ( total == 0 || gindex >= total ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( !FT_NEW( snode ) ) - { - FT_UInt count, start; - - - start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE ); - count = total - start; - if ( count > FTC_SBIT_ITEMS_PER_NODE ) - count = FTC_SBIT_ITEMS_PER_NODE; - - FTC_GNode_Init( FTC_GNODE( snode ), start, family ); - - snode->count = count; - for ( node_count = 0; node_count < count; node_count++ ) - { - snode->sbits[node_count].width = 255; - } - - error = ftc_snode_load( snode, - cache->manager, - gindex, - NULL ); - if ( error ) - { - FTC_SNode_Free( snode, cache ); - snode = NULL; - } - } - - Exit: - *psnode = snode; - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - ftc_snode_new( FTC_Node *ftcpsnode, - FT_Pointer ftcgquery, - FTC_Cache cache ) - { - FTC_SNode *psnode = (FTC_SNode*)ftcpsnode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - - - return FTC_SNode_New( psnode, gquery, cache ); - } - - - FT_LOCAL_DEF( FT_Offset ) - ftc_snode_weight( FTC_Node ftcsnode, - FTC_Cache cache ) - { - FTC_SNode snode = (FTC_SNode)ftcsnode; - FT_UInt count = snode->count; - FTC_SBit sbit = snode->sbits; - FT_Int pitch; - FT_Offset size; - - FT_UNUSED( cache ); - - - FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE ); - - /* the node itself */ - size = sizeof ( *snode ); - - for ( ; count > 0; count--, sbit++ ) - { - if ( sbit->buffer ) - { - pitch = sbit->pitch; - if ( pitch < 0 ) - pitch = -pitch; - - /* add the size of a given glyph image */ - size += pitch * sbit->height; - } - } - - return size; - } - - -#if 0 - - FT_LOCAL_DEF( FT_Offset ) - FTC_SNode_Weight( FTC_SNode snode ) - { - return ftc_snode_weight( FTC_NODE( snode ), NULL ); - } - -#endif /* 0 */ - - - FT_LOCAL_DEF( FT_Bool ) - ftc_snode_compare( FTC_Node ftcsnode, - FT_Pointer ftcgquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - FTC_SNode snode = (FTC_SNode)ftcsnode; - FTC_GQuery gquery = (FTC_GQuery)ftcgquery; - FTC_GNode gnode = FTC_GNODE( snode ); - FT_UInt gindex = gquery->gindex; - FT_Bool result; - - - if (list_changed) - *list_changed = FALSE; - result = FT_BOOL( gnode->family == gquery->family && - (FT_UInt)( gindex - gnode->gindex ) < snode->count ); - if ( result ) - { - /* check if we need to load the glyph bitmap now */ - FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex ); - - - /* - * The following code illustrates what to do when you want to - * perform operations that may fail within a lookup function. - * - * Here, we want to load a small bitmap on-demand; we thus - * need to call the `ftc_snode_load' function which may return - * a non-zero error code only when we are out of memory (OOM). - * - * The correct thing to do is to use @FTC_CACHE_TRYLOOP and - * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop - * that is capable of flushing the cache incrementally when - * an OOM errors occur. - * - * However, we need to `lock' the node before this operation to - * prevent it from being flushed within the loop. - * - * When we exit the loop, we unlock the node, then check the `error' - * variable. If it is non-zero, this means that the cache was - * completely flushed and that no usable memory was found to load - * the bitmap. - * - * We then prefer to return a value of 0 (i.e., NO MATCH). This - * ensures that the caller will try to allocate a new node. - * This operation consequently _fail_ and the lookup function - * returns the appropriate OOM error code. - * - * Note that `buffer == NULL && width == 255' is a hack used to - * tag `unavailable' bitmaps in the array. We should never try - * to load these. - * - */ - - if ( sbit->buffer == NULL && sbit->width == 255 ) - { - FT_ULong size; - FT_Error error; - - - ftcsnode->ref_count++; /* lock node to prevent flushing */ - /* in retry loop */ - - FTC_CACHE_TRYLOOP( cache ) - { - error = ftc_snode_load( snode, cache->manager, gindex, &size ); - } - FTC_CACHE_TRYLOOP_END( list_changed ); - - ftcsnode->ref_count--; /* unlock the node */ - - if ( error ) - result = 0; - else - cache->manager->cur_weight += size; - } - } - - return result; - } - - -#ifdef FTC_INLINE - - FT_LOCAL_DEF( FT_Bool ) - FTC_SNode_Compare( FTC_SNode snode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - return ftc_snode_compare( FTC_NODE( snode ), gquery, - cache, list_changed ); - } - -#endif - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcsbits.h b/drivers/freetype/freetype/src/cache/ftcsbits.h deleted file mode 100644 index df55dca806..0000000000 --- a/drivers/freetype/freetype/src/cache/ftcsbits.h +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcsbits.h */ -/* */ -/* A small-bitmap cache (specification). */ -/* */ -/* Copyright 2000-2001, 2002, 2003, 2006, 2011 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 __FTCSBITS_H__ -#define __FTCSBITS_H__ - - -#include <ft2build.h> -#include FT_CACHE_H -#include "ftcglyph.h" - - -FT_BEGIN_HEADER - -#define FTC_SBIT_ITEMS_PER_NODE 16 - - typedef struct FTC_SNodeRec_ - { - FTC_GNodeRec gnode; - FT_UInt count; - FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; - - } FTC_SNodeRec, *FTC_SNode; - - -#define FTC_SNODE( x ) ( (FTC_SNode)( x ) ) -#define FTC_SNODE_GINDEX( x ) FTC_GNODE( x )->gindex -#define FTC_SNODE_FAMILY( x ) FTC_GNODE( x )->family - - typedef FT_UInt - (*FTC_SFamily_GetCountFunc)( FTC_Family family, - FTC_Manager manager ); - - typedef FT_Error - (*FTC_SFamily_LoadGlyphFunc)( FTC_Family family, - FT_UInt gindex, - FTC_Manager manager, - FT_Face *aface ); - - typedef struct FTC_SFamilyClassRec_ - { - FTC_MruListClassRec clazz; - FTC_SFamily_GetCountFunc family_get_count; - FTC_SFamily_LoadGlyphFunc family_load_glyph; - - } FTC_SFamilyClassRec; - - typedef const FTC_SFamilyClassRec* FTC_SFamilyClass; - -#define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) - -#define FTC_CACHE__SFAMILY_CLASS( x ) \ - FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) - - - FT_LOCAL( void ) - FTC_SNode_Free( FTC_SNode snode, - FTC_Cache cache ); - - FT_LOCAL( FT_Error ) - FTC_SNode_New( FTC_SNode *psnode, - FTC_GQuery gquery, - FTC_Cache cache ); - -#if 0 - FT_LOCAL( FT_ULong ) - FTC_SNode_Weight( FTC_SNode inode ); -#endif - - -#ifdef FTC_INLINE - - FT_LOCAL( FT_Bool ) - FTC_SNode_Compare( FTC_SNode snode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed); - -#endif - - /* */ - -FT_END_HEADER - -#endif /* __FTCSBITS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cache/rules.mk b/drivers/freetype/freetype/src/cache/rules.mk deleted file mode 100644 index ed75a6a91f..0000000000 --- a/drivers/freetype/freetype/src/cache/rules.mk +++ /dev/null @@ -1,80 +0,0 @@ -# -# FreeType 2 Cache configuration rules -# - - -# Copyright 2000, 2001, 2003, 2004, 2006, 2008 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. - - -# Cache driver directory -# -CACHE_DIR := $(SRC_DIR)/cache - -# compilation flags for the driver -# -CACHE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) - - -# Cache driver sources (i.e., C files) -# -CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ - $(CACHE_DIR)/ftccache.c \ - $(CACHE_DIR)/ftccmap.c \ - $(CACHE_DIR)/ftcglyph.c \ - $(CACHE_DIR)/ftcimage.c \ - $(CACHE_DIR)/ftcmanag.c \ - $(CACHE_DIR)/ftcmru.c \ - $(CACHE_DIR)/ftcsbits.c - -# Cache driver headers -# -CACHE_DRV_H := $(CACHE_DIR)/ftccache.h \ - $(CACHE_DIR)/ftccback.h \ - $(CACHE_DIR)/ftcerror.h \ - $(CACHE_DIR)/ftcglyph.h \ - $(CACHE_DIR)/ftcimage.h \ - $(CACHE_DIR)/ftcmanag.h \ - $(CACHE_DIR)/ftcmru.h \ - $(CACHE_DIR)/ftcsbits.h - - -# Cache driver object(s) -# -# CACHE_DRV_OBJ_M is used during `multi' builds. -# CACHE_DRV_OBJ_S is used during `single' builds. -# -CACHE_DRV_OBJ_M := $(CACHE_DRV_SRC:$(CACHE_DIR)/%.c=$(OBJ_DIR)/%.$O) -CACHE_DRV_OBJ_S := $(OBJ_DIR)/ftcache.$O - -# Cache driver source file for single build -# -CACHE_DRV_SRC_S := $(CACHE_DIR)/ftcache.c - - -# Cache driver - single object -# -$(CACHE_DRV_OBJ_S): $(CACHE_DRV_SRC_S) $(CACHE_DRV_SRC) \ - $(FREETYPE_H) $(CACHE_DRV_H) - $(CACHE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CACHE_DRV_SRC_S)) - - -# Cache driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(CACHE_DIR)/%.c $(FREETYPE_H) $(CACHE_DRV_H) - $(CACHE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(CACHE_DRV_OBJ_S) -DRV_OBJS_M += $(CACHE_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/cff/Jamfile b/drivers/freetype/freetype/src/cff/Jamfile deleted file mode 100644 index 6705d3cfdb..0000000000 --- a/drivers/freetype/freetype/src/cff/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/cff Jamfile -# -# Copyright 2001, 2002 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) cff ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap cffpic ; - } - else - { - _sources = cff ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/cff Jamfile diff --git a/drivers/freetype/freetype/src/cff/cf2arrst.c b/drivers/freetype/freetype/src/cff/cf2arrst.c deleted file mode 100644 index c8d6f13098..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2arrst.c +++ /dev/null @@ -1,241 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2arrst.c */ -/* */ -/* Adobe's code for Array Stacks (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" -#include FT_INTERNAL_DEBUG_H - -#include "cf2glue.h" -#include "cf2arrst.h" - -#include "cf2error.h" - - - /* - * CF2_ArrStack uses an error pointer, to enable shared errors. - * Shared errors are necessary when multiple objects allow the program - * to continue after detecting errors. Only the first error should be - * recorded. - */ - - FT_LOCAL_DEF( void ) - cf2_arrstack_init( CF2_ArrStack arrstack, - FT_Memory memory, - FT_Error* error, - size_t sizeItem ) - { - FT_ASSERT( arrstack != NULL ); - - /* initialize the structure */ - arrstack->memory = memory; - arrstack->error = error; - arrstack->sizeItem = sizeItem; - arrstack->allocated = 0; - arrstack->chunk = 10; /* chunks of 10 items */ - arrstack->count = 0; - arrstack->totalSize = 0; - arrstack->ptr = NULL; - } - - - FT_LOCAL_DEF( void ) - cf2_arrstack_finalize( CF2_ArrStack arrstack ) - { - FT_Memory memory = arrstack->memory; /* for FT_FREE */ - - - FT_ASSERT( arrstack != NULL ); - - arrstack->allocated = 0; - arrstack->count = 0; - arrstack->totalSize = 0; - - /* free the data buffer */ - FT_FREE( arrstack->ptr ); - } - - - /* allocate or reallocate the buffer size; */ - /* return false on memory error */ - static FT_Bool - cf2_arrstack_setNumElements( CF2_ArrStack arrstack, - size_t numElements ) - { - FT_ASSERT( arrstack != NULL ); - - { - FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ - FT_Memory memory = arrstack->memory; /* for FT_REALLOC */ - - FT_Long newSize = (FT_Long)( numElements * arrstack->sizeItem ); - - - if ( numElements > LONG_MAX / arrstack->sizeItem ) - goto exit; - - - FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */ - - if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) ) - { - arrstack->allocated = numElements; - arrstack->totalSize = newSize; - - if ( arrstack->count > numElements ) - { - /* we truncated the list! */ - CF2_SET_ERROR( arrstack->error, Stack_Overflow ); - arrstack->count = numElements; - return FALSE; - } - - return TRUE; /* success */ - } - } - - exit: - /* if there's not already an error, store this one */ - CF2_SET_ERROR( arrstack->error, Out_Of_Memory ); - - return FALSE; - } - - - /* set the count, ensuring allocation is sufficient */ - FT_LOCAL_DEF( void ) - cf2_arrstack_setCount( CF2_ArrStack arrstack, - size_t numElements ) - { - FT_ASSERT( arrstack != NULL ); - - if ( numElements > arrstack->allocated ) - { - /* expand the allocation first */ - if ( !cf2_arrstack_setNumElements( arrstack, numElements ) ) - return; - } - - arrstack->count = numElements; - } - - - /* clear the count */ - FT_LOCAL_DEF( void ) - cf2_arrstack_clear( CF2_ArrStack arrstack ) - { - FT_ASSERT( arrstack != NULL ); - - arrstack->count = 0; - } - - - /* current number of items */ - FT_LOCAL_DEF( size_t ) - cf2_arrstack_size( const CF2_ArrStack arrstack ) - { - FT_ASSERT( arrstack != NULL ); - - return arrstack->count; - } - - - FT_LOCAL_DEF( void* ) - cf2_arrstack_getBuffer( const CF2_ArrStack arrstack ) - { - FT_ASSERT( arrstack != NULL ); - - return arrstack->ptr; - } - - - /* return pointer to the given element */ - FT_LOCAL_DEF( void* ) - cf2_arrstack_getPointer( const CF2_ArrStack arrstack, - size_t idx ) - { - void* newPtr; - - - FT_ASSERT( arrstack != NULL ); - - if ( idx >= arrstack->count ) - { - /* overflow */ - CF2_SET_ERROR( arrstack->error, Stack_Overflow ); - idx = 0; /* choose safe default */ - } - - newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem; - - return newPtr; - } - - - /* push (append) an element at the end of the list; */ - /* return false on memory error */ - /* TODO: should there be a length param for extra checking? */ - FT_LOCAL_DEF( void ) - cf2_arrstack_push( CF2_ArrStack arrstack, - const void* ptr ) - { - FT_ASSERT( arrstack != NULL ); - - if ( arrstack->count == arrstack->allocated ) - { - /* grow the buffer by one chunk */ - if ( !cf2_arrstack_setNumElements( - arrstack, arrstack->allocated + arrstack->chunk ) ) - { - /* on error, ignore the push */ - return; - } - } - - FT_ASSERT( ptr != NULL ); - - { - size_t offset = arrstack->count * arrstack->sizeItem; - void* newPtr = (FT_Byte*)arrstack->ptr + offset; - - - FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem ); - arrstack->count += 1; - } - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2arrst.h b/drivers/freetype/freetype/src/cff/cf2arrst.h deleted file mode 100644 index ff5ad8b126..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2arrst.h +++ /dev/null @@ -1,100 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2arrst.h */ -/* */ -/* Adobe's code for Array Stacks (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2ARRST_H__ -#define __CF2ARRST_H__ - - -#include "cf2error.h" - - -FT_BEGIN_HEADER - - - /* need to define the struct here (not opaque) so it can be allocated by */ - /* clients */ - typedef struct CF2_ArrStackRec_ - { - FT_Memory memory; - FT_Error* error; - - size_t sizeItem; /* bytes per element */ - size_t allocated; /* items allocated */ - size_t chunk; /* allocation increment in items */ - size_t count; /* number of elements allocated */ - size_t totalSize; /* total bytes allocated */ - - void* ptr; /* ptr to data */ - - } CF2_ArrStackRec, *CF2_ArrStack; - - - FT_LOCAL( void ) - cf2_arrstack_init( CF2_ArrStack arrstack, - FT_Memory memory, - FT_Error* error, - size_t sizeItem ); - FT_LOCAL( void ) - cf2_arrstack_finalize( CF2_ArrStack arrstack ); - - FT_LOCAL( void ) - cf2_arrstack_setCount( CF2_ArrStack arrstack, - size_t numElements ); - FT_LOCAL( void ) - cf2_arrstack_clear( CF2_ArrStack arrstack ); - FT_LOCAL( size_t ) - cf2_arrstack_size( const CF2_ArrStack arrstack ); - - FT_LOCAL( void* ) - cf2_arrstack_getBuffer( const CF2_ArrStack arrstack ); - FT_LOCAL( void* ) - cf2_arrstack_getPointer( const CF2_ArrStack arrstack, - size_t idx ); - - FT_LOCAL( void ) - cf2_arrstack_push( CF2_ArrStack arrstack, - const void* ptr ); - - -FT_END_HEADER - - -#endif /* __CF2ARRST_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2blues.c b/drivers/freetype/freetype/src/cff/cf2blues.c deleted file mode 100644 index 5b348398af..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2blues.c +++ /dev/null @@ -1,578 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2blues.c */ -/* */ -/* Adobe's code for handling Blue Zones (body). */ -/* */ -/* Copyright 2009-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" -#include FT_INTERNAL_DEBUG_H - -#include "cf2blues.h" -#include "cf2hints.h" -#include "cf2font.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_cf2blues - - - /* - * For blue values, the FreeType parser produces an array of integers, - * while the Adobe CFF engine produces an array of fixed. - * Define a macro to convert FreeType to fixed. - */ -#define cf2_blueToFixed( x ) cf2_intToFixed( x ) - - - FT_LOCAL_DEF( void ) - cf2_blues_init( CF2_Blues blues, - CF2_Font font ) - { - /* pointer to parsed font object */ - CFF_Decoder* decoder = font->decoder; - - CF2_Fixed zoneHeight; - CF2_Fixed maxZoneHeight = 0; - CF2_Fixed csUnitsPerPixel; - - size_t numBlueValues; - size_t numOtherBlues; - size_t numFamilyBlues; - size_t numFamilyOtherBlues; - - FT_Pos* blueValues; - FT_Pos* otherBlues; - FT_Pos* familyBlues; - FT_Pos* familyOtherBlues; - - size_t i; - CF2_Fixed emBoxBottom, emBoxTop; - - CF2_Int unitsPerEm = font->unitsPerEm; - - - if ( unitsPerEm == 0 ) - unitsPerEm = 1000; - - FT_ZERO( blues ); - blues->scale = font->innerTransform.d; - - cf2_getBlueMetrics( decoder, - &blues->blueScale, - &blues->blueShift, - &blues->blueFuzz ); - - cf2_getBlueValues( decoder, &numBlueValues, &blueValues ); - cf2_getOtherBlues( decoder, &numOtherBlues, &otherBlues ); - cf2_getFamilyBlues( decoder, &numFamilyBlues, &familyBlues ); - cf2_getFamilyOtherBlues( decoder, &numFamilyOtherBlues, &familyOtherBlues ); - - /* - * synthetic em box hint heuristic - * - * Apply this when ideographic dictionary (LanguageGroup 1) has no - * real alignment zones. Adobe tools generate dummy zones at -250 and - * 1100 for a 1000 unit em. Fonts with ICF-based alignment zones - * should not enable the heuristic. When the heuristic is enabled, - * the font's blue zones are ignored. - * - */ - - /* get em box from OS/2 typoAscender/Descender */ - /* TODO: FreeType does not parse these metrics. Skip them for now. */ -#if 0 - FCM_getHorizontalLineMetrics( &e, - font->font, - &ascender, - &descender, - &linegap ); - if ( ascender - descender == unitsPerEm ) - { - emBoxBottom = cf2_intToFixed( descender ); - emBoxTop = cf2_intToFixed( ascender ); - } - else -#endif - { - emBoxBottom = CF2_ICF_Bottom; - emBoxTop = CF2_ICF_Top; - } - - if ( cf2_getLanguageGroup( decoder ) == 1 && - ( numBlueValues == 0 || - ( numBlueValues == 4 && - cf2_blueToFixed( blueValues[0] ) < emBoxBottom && - cf2_blueToFixed( blueValues[1] ) < emBoxBottom && - cf2_blueToFixed( blueValues[2] ) > emBoxTop && - cf2_blueToFixed( blueValues[3] ) > emBoxTop ) ) ) - { - /* - * Construct hint edges suitable for synthetic ghost hints at top - * and bottom of em box. +-CF2_MIN_COUNTER allows for unhinted - * features above or below the last hinted edge. This also gives a - * net 1 pixel boost to the height of ideographic glyphs. - * - * Note: Adjust synthetic hints outward by epsilon (0x.0001) to - * avoid interference. E.g., some fonts have real hints at - * 880 and -120. - */ - - blues->emBoxBottomEdge.csCoord = emBoxBottom - CF2_FIXED_EPSILON; - blues->emBoxBottomEdge.dsCoord = cf2_fixedRound( - FT_MulFix( - blues->emBoxBottomEdge.csCoord, - blues->scale ) ) - - CF2_MIN_COUNTER; - blues->emBoxBottomEdge.scale = blues->scale; - blues->emBoxBottomEdge.flags = CF2_GhostBottom | - CF2_Locked | - CF2_Synthetic; - - blues->emBoxTopEdge.csCoord = emBoxTop + CF2_FIXED_EPSILON + - 2 * font->darkenY; - blues->emBoxTopEdge.dsCoord = cf2_fixedRound( - FT_MulFix( - blues->emBoxTopEdge.csCoord, - blues->scale ) ) + - CF2_MIN_COUNTER; - blues->emBoxTopEdge.scale = blues->scale; - blues->emBoxTopEdge.flags = CF2_GhostTop | - CF2_Locked | - CF2_Synthetic; - - blues->doEmBoxHints = TRUE; /* enable the heuristic */ - - return; - } - - /* copy `BlueValues' and `OtherBlues' to a combined array of top and */ - /* bottom zones */ - for ( i = 0; i < numBlueValues; i += 2 ) - { - blues->zone[blues->count].csBottomEdge = - cf2_blueToFixed( blueValues[i] ); - blues->zone[blues->count].csTopEdge = - cf2_blueToFixed( blueValues[i + 1] ); - - zoneHeight = blues->zone[blues->count].csTopEdge - - blues->zone[blues->count].csBottomEdge; - - if ( zoneHeight < 0 ) - { - FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" )); - continue; /* reject this zone */ - } - - if ( zoneHeight > maxZoneHeight ) - { - /* take maximum before darkening adjustment */ - /* so overshoot suppression point doesn't change */ - maxZoneHeight = zoneHeight; - } - - /* adjust both edges of top zone upward by twice darkening amount */ - if ( i != 0 ) - { - blues->zone[blues->count].csTopEdge += 2 * font->darkenY; - blues->zone[blues->count].csBottomEdge += 2 * font->darkenY; - } - - /* first `BlueValue' is bottom zone; others are top */ - if ( i == 0 ) - { - blues->zone[blues->count].bottomZone = - TRUE; - blues->zone[blues->count].csFlatEdge = - blues->zone[blues->count].csTopEdge; - } - else - { - blues->zone[blues->count].bottomZone = - FALSE; - blues->zone[blues->count].csFlatEdge = - blues->zone[blues->count].csBottomEdge; - } - - blues->count += 1; - } - - for ( i = 0; i < numOtherBlues; i += 2 ) - { - blues->zone[blues->count].csBottomEdge = - cf2_blueToFixed( otherBlues[i] ); - blues->zone[blues->count].csTopEdge = - cf2_blueToFixed( otherBlues[i + 1] ); - - zoneHeight = blues->zone[blues->count].csTopEdge - - blues->zone[blues->count].csBottomEdge; - - if ( zoneHeight < 0 ) - { - FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" )); - continue; /* reject this zone */ - } - - if ( zoneHeight > maxZoneHeight ) - { - /* take maximum before darkening adjustment */ - /* so overshoot suppression point doesn't change */ - maxZoneHeight = zoneHeight; - } - - /* Note: bottom zones are not adjusted for darkening amount */ - - /* all OtherBlues are bottom zone */ - blues->zone[blues->count].bottomZone = - TRUE; - blues->zone[blues->count].csFlatEdge = - blues->zone[blues->count].csTopEdge; - - blues->count += 1; - } - - /* Adjust for FamilyBlues */ - - /* Search for the nearest flat edge in `FamilyBlues' or */ - /* `FamilyOtherBlues'. According to the Black Book, any matching edge */ - /* must be within one device pixel */ - - csUnitsPerPixel = FT_DivFix( cf2_intToFixed( 1 ), blues->scale ); - - /* loop on all zones in this font */ - for ( i = 0; i < blues->count; i++ ) - { - size_t j; - CF2_Fixed minDiff; - CF2_Fixed flatFamilyEdge, diff; - /* value for this font */ - CF2_Fixed flatEdge = blues->zone[i].csFlatEdge; - - - if ( blues->zone[i].bottomZone ) - { - /* In a bottom zone, the top edge is the flat edge. */ - /* Search `FamilyOtherBlues' for bottom zones; look for closest */ - /* Family edge that is within the one pixel threshold. */ - - minDiff = CF2_FIXED_MAX; - - for ( j = 0; j < numFamilyOtherBlues; j += 2 ) - { - /* top edge */ - flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] ); - - diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); - - if ( diff < minDiff && diff < csUnitsPerPixel ) - { - blues->zone[i].csFlatEdge = flatFamilyEdge; - minDiff = diff; - - if ( diff == 0 ) - break; - } - } - - /* check the first member of FamilyBlues, which is a bottom zone */ - if ( numFamilyBlues >= 2 ) - { - /* top edge */ - flatFamilyEdge = cf2_blueToFixed( familyBlues[1] ); - - diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); - - if ( diff < minDiff && diff < csUnitsPerPixel ) - blues->zone[i].csFlatEdge = flatFamilyEdge; - } - } - else - { - /* In a top zone, the bottom edge is the flat edge. */ - /* Search `FamilyBlues' for top zones; skip first zone, which is a */ - /* bottom zone; look for closest Family edge that is within the */ - /* one pixel threshold */ - - minDiff = CF2_FIXED_MAX; - - for ( j = 2; j < numFamilyBlues; j += 2 ) - { - /* bottom edge */ - flatFamilyEdge = cf2_blueToFixed( familyBlues[j] ); - - /* adjust edges of top zone upward by twice darkening amount */ - flatFamilyEdge += 2 * font->darkenY; /* bottom edge */ - - diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); - - if ( diff < minDiff && diff < csUnitsPerPixel ) - { - blues->zone[i].csFlatEdge = flatFamilyEdge; - minDiff = diff; - - if ( diff == 0 ) - break; - } - } - } - } - - /* TODO: enforce separation of zones, including BlueFuzz */ - - /* Adjust BlueScale; similar to AdjustBlueScale() in coretype */ - /* `bcsetup.c'. */ - - if ( maxZoneHeight > 0 ) - { - if ( blues->blueScale > FT_DivFix( cf2_intToFixed( 1 ), - maxZoneHeight ) ) - { - /* clamp at maximum scale */ - blues->blueScale = FT_DivFix( cf2_intToFixed( 1 ), - maxZoneHeight ); - } - - /* - * TODO: Revisit the bug fix for 613448. The minimum scale - * requirement catches a number of library fonts. For - * example, with default BlueScale (.039625) and 0.4 minimum, - * the test below catches any font with maxZoneHeight < 10.1. - * There are library fonts ranging from 2 to 10 that get - * caught, including e.g., Eurostile LT Std Medium with - * maxZoneHeight of 6. - * - */ -#if 0 - if ( blueScale < .4 / maxZoneHeight ) - { - tetraphilia_assert( 0 ); - /* clamp at minimum scale, per bug 0613448 fix */ - blueScale = .4 / maxZoneHeight; - } -#endif - - } - - /* - * Suppress overshoot and boost blue zones at small sizes. Boost - * amount varies linearly from 0.5 pixel near 0 to 0 pixel at - * blueScale cutoff. - * Note: This boost amount is different from the coretype heuristic. - * - */ - - if ( blues->scale < blues->blueScale ) - { - blues->suppressOvershoot = TRUE; - - /* Change rounding threshold for `dsFlatEdge'. */ - /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */ - /* 10ppem Arial */ - - blues->boost = FT_MulFix( - cf2_floatToFixed( .6 ), - ( cf2_intToFixed( 1 ) - - FT_DivFix( blues->scale, - blues->blueScale ) ) ); - if ( blues->boost > 0x7FFF ) - { - /* boost must remain less than 0.5, or baseline could go negative */ - blues->boost = 0x7FFF; - } - } - - /* boost and darkening have similar effects; don't do both */ - if ( font->stemDarkened ) - blues->boost = 0; - - /* set device space alignment for each zone; */ - /* apply boost amount before rounding flat edge */ - - for ( i = 0; i < blues->count; i++ ) - { - if ( blues->zone[i].bottomZone ) - blues->zone[i].dsFlatEdge = cf2_fixedRound( - FT_MulFix( - blues->zone[i].csFlatEdge, - blues->scale ) - - blues->boost ); - else - blues->zone[i].dsFlatEdge = cf2_fixedRound( - FT_MulFix( - blues->zone[i].csFlatEdge, - blues->scale ) + - blues->boost ); - } - } - - - /* - * Check whether `stemHint' is captured by one of the blue zones. - * - * Zero, one or both edges may be valid; only valid edges can be - * captured. For compatibility with CoolType, search top and bottom - * zones in the same pass (see `BlueLock'). If a hint is captured, - * return true and position the edge(s) in one of 3 ways: - * - * 1) If `BlueScale' suppresses overshoot, position the captured edge - * at the flat edge of the zone. - * 2) If overshoot is not suppressed and `BlueShift' requires - * overshoot, position the captured edge a minimum of 1 device pixel - * from the flat edge. - * 3) If overshoot is not suppressed or required, position the captured - * edge at the nearest device pixel. - * - */ - FT_LOCAL_DEF( FT_Bool ) - cf2_blues_capture( const CF2_Blues blues, - CF2_Hint bottomHintEdge, - CF2_Hint topHintEdge ) - { - /* TODO: validate? */ - CF2_Fixed csFuzz = blues->blueFuzz; - - /* new position of captured edge */ - CF2_Fixed dsNew; - - /* amount that hint is moved when positioned */ - CF2_Fixed dsMove = 0; - - FT_Bool captured = FALSE; - CF2_UInt i; - - - /* assert edge flags are consistent */ - FT_ASSERT( !cf2_hint_isTop( bottomHintEdge ) && - !cf2_hint_isBottom( topHintEdge ) ); - - /* TODO: search once without blue fuzz for compatibility with coretype? */ - for ( i = 0; i < blues->count; i++ ) - { - if ( blues->zone[i].bottomZone && - cf2_hint_isBottom( bottomHintEdge ) ) - { - if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= - bottomHintEdge->csCoord && - bottomHintEdge->csCoord <= - ( blues->zone[i].csTopEdge + csFuzz ) ) - { - /* bottom edge captured by bottom zone */ - - if ( blues->suppressOvershoot ) - dsNew = blues->zone[i].dsFlatEdge; - - else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >= - blues->blueShift ) - { - /* guarantee minimum of 1 pixel overshoot */ - dsNew = FT_MIN( - cf2_fixedRound( bottomHintEdge->dsCoord ), - blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) ); - } - - else - { - /* simply round captured edge */ - dsNew = cf2_fixedRound( bottomHintEdge->dsCoord ); - } - - dsMove = dsNew - bottomHintEdge->dsCoord; - captured = TRUE; - - break; - } - } - - if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) ) - { - if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= - topHintEdge->csCoord && - topHintEdge->csCoord <= - ( blues->zone[i].csTopEdge + csFuzz ) ) - { - /* top edge captured by top zone */ - - if ( blues->suppressOvershoot ) - dsNew = blues->zone[i].dsFlatEdge; - - else if ( ( topHintEdge->csCoord - blues->zone[i].csBottomEdge ) >= - blues->blueShift ) - { - /* guarantee minimum of 1 pixel overshoot */ - dsNew = FT_MAX( - cf2_fixedRound( topHintEdge->dsCoord ), - blues->zone[i].dsFlatEdge + cf2_intToFixed( 1 ) ); - } - - else - { - /* simply round captured edge */ - dsNew = cf2_fixedRound( topHintEdge->dsCoord ); - } - - dsMove = dsNew - topHintEdge->dsCoord; - captured = TRUE; - - break; - } - } - } - - if ( captured ) - { - /* move both edges and flag them `locked' */ - if ( cf2_hint_isValid( bottomHintEdge ) ) - { - bottomHintEdge->dsCoord += dsMove; - cf2_hint_lock( bottomHintEdge ); - } - - if ( cf2_hint_isValid( topHintEdge ) ) - { - topHintEdge->dsCoord += dsMove; - cf2_hint_lock( topHintEdge ); - } - } - - return captured; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2blues.h b/drivers/freetype/freetype/src/cff/cf2blues.h deleted file mode 100644 index 2f38fcad8f..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2blues.h +++ /dev/null @@ -1,185 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2blues.h */ -/* */ -/* Adobe's code for handling Blue Zones (specification). */ -/* */ -/* Copyright 2009-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - - /* - * A `CF2_Blues' object stores the blue zones (horizontal alignment - * zones) of a font. These are specified in the CFF private dictionary - * by `BlueValues', `OtherBlues', `FamilyBlues', and `FamilyOtherBlues'. - * Each zone is defined by a top and bottom edge in character space. - * Further, each zone is either a top zone or a bottom zone, as recorded - * by `bottomZone'. - * - * The maximum number of `BlueValues' and `FamilyBlues' is 7 each. - * However, these are combined to produce a total of 7 zones. - * Similarly, the maximum number of `OtherBlues' and `FamilyOtherBlues' - * is 5 and these are combined to produce an additional 5 zones. - * - * Blue zones are used to `capture' hints and force them to a common - * alignment point. This alignment is recorded in device space in - * `dsFlatEdge'. Except for this value, a `CF2_Blues' object could be - * constructed independently of scaling. Construction may occur once - * the matrix is known. Other features implemented in the Capture - * method are overshoot suppression, overshoot enforcement, and Blue - * Boost. - * - * Capture is determined by `BlueValues' and `OtherBlues', but the - * alignment point may be adjusted to the scaled flat edge of - * `FamilyBlues' or `FamilyOtherBlues'. No alignment is done to the - * curved edge of a zone. - * - */ - - -#ifndef __CF2BLUES_H__ -#define __CF2BLUES_H__ - - -#include "cf2glue.h" - - -FT_BEGIN_HEADER - - - /* - * `CF2_Hint' is shared by `cf2hints.h' and - * `cf2blues.h', but `cf2blues.h' depends on - * `cf2hints.h', so define it here. Note: The typedef is in - * `cf2glue.h'. - * - */ - enum - { - CF2_GhostBottom = 0x1, /* a single bottom edge */ - CF2_GhostTop = 0x2, /* a single top edge */ - CF2_PairBottom = 0x4, /* the bottom edge of a stem hint */ - CF2_PairTop = 0x8, /* the top edge of a stem hint */ - CF2_Locked = 0x10, /* this edge has been aligned */ - /* by a blue zone */ - CF2_Synthetic = 0x20 /* this edge was synthesized */ - }; - - - /* - * Default value for OS/2 typoAscender/Descender when their difference - * is not equal to `unitsPerEm'. The default is based on -250 and 1100 - * in `CF2_Blues', assuming 1000 units per em here. - * - */ - enum - { - CF2_ICF_Top = cf2_intToFixed( 880 ), - CF2_ICF_Bottom = cf2_intToFixed( -120 ) - }; - - - /* - * Constant used for hint adjustment and for synthetic em box hint - * placement. - */ -#define CF2_MIN_COUNTER cf2_floatToFixed( 0.5 ) - - - /* shared typedef is in cf2glue.h */ - struct CF2_HintRec_ - { - CF2_UInt flags; /* attributes of the edge */ - size_t index; /* index in original stem hint array */ - /* (if not synthetic) */ - CF2_Fixed csCoord; - CF2_Fixed dsCoord; - CF2_Fixed scale; - }; - - - typedef struct CF2_BlueRec_ - { - CF2_Fixed csBottomEdge; - CF2_Fixed csTopEdge; - CF2_Fixed csFlatEdge; /* may be from either local or Family zones */ - CF2_Fixed dsFlatEdge; /* top edge of bottom zone or bottom edge */ - /* of top zone (rounded) */ - FT_Bool bottomZone; - - } CF2_BlueRec; - - - /* max total blue zones is 12 */ - enum - { - CF2_MAX_BLUES = 7, - CF2_MAX_OTHERBLUES = 5 - }; - - - typedef struct CF2_BluesRec_ - { - CF2_Fixed scale; - CF2_UInt count; - FT_Bool suppressOvershoot; - FT_Bool doEmBoxHints; - - CF2_Fixed blueScale; - CF2_Fixed blueShift; - CF2_Fixed blueFuzz; - - CF2_Fixed boost; - - CF2_HintRec emBoxTopEdge; - CF2_HintRec emBoxBottomEdge; - - CF2_BlueRec zone[CF2_MAX_BLUES + CF2_MAX_OTHERBLUES]; - - } CF2_BluesRec, *CF2_Blues; - - - FT_LOCAL( void ) - cf2_blues_init( CF2_Blues blues, - CF2_Font font ); - FT_LOCAL( FT_Bool ) - cf2_blues_capture( const CF2_Blues blues, - CF2_Hint bottomHintEdge, - CF2_Hint topHintEdge ); - - -FT_END_HEADER - - -#endif /* __CF2BLUES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2error.c b/drivers/freetype/freetype/src/cff/cf2error.c deleted file mode 100644 index b5595a3d1f..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2error.c +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2error.c */ -/* */ -/* Adobe's code for error handling (body). */ -/* */ -/* Copyright 2006-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" -#include "cf2error.h" - - - FT_LOCAL_DEF( void ) - cf2_setError( FT_Error* error, - FT_Error value ) - { - if ( error && *error == 0 ) - *error = value; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2error.h b/drivers/freetype/freetype/src/cff/cf2error.h deleted file mode 100644 index 6453ebcb7b..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2error.h +++ /dev/null @@ -1,119 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2error.h */ -/* */ -/* Adobe's code for error handling (specification). */ -/* */ -/* Copyright 2006-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2ERROR_H__ -#define __CF2ERROR_H__ - - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX CF2_Err_ -#define FT_ERR_BASE FT_Mod_Err_CF2 - - -#include FT_ERRORS_H -#include "cf2ft.h" - - -FT_BEGIN_HEADER - - - /* - * A poor-man error facility. - * - * This code being written in vanilla C, doesn't have the luxury of a - * language-supported exception mechanism such as the one available in - * Java. Instead, we are stuck with using error codes that must be - * carefully managed and preserved. However, it is convenient for us to - * model our error mechanism on a Java-like exception mechanism. - * When we assign an error code we are thus `throwing' an error. - * - * The perservation of an error code is done by coding convention. - * Upon a function call if the error code is anything other than - * `FT_Err_Ok', which is guaranteed to be zero, we - * will return without altering that error. This will allow the - * error to propogate and be handled at the appropriate location in - * the code. - * - * This allows a style of code where the error code is initialized - * up front and a block of calls are made with the error code only - * being checked after the block. If a new error occurs, the original - * error will be preserved and a functional no-op should result in any - * subsequent function that has an initial error code not equal to - * `FT_Err_Ok'. - * - * Errors are encoded by calling the `FT_THROW' macro. For example, - * - * { - * FT_Error e; - * - * - * ... - * e = FT_THROW( Out_Of_Memory ); - * } - * - */ - - - /* Set error code to a particular value. */ - FT_LOCAL( void ) - cf2_setError( FT_Error* error, - FT_Error value ); - - - /* - * A macro that conditionally sets an error code. - * - * This macro will first check whether `error' is set; - * if not, it will set it to `e'. - * - */ -#define CF2_SET_ERROR( error, e ) \ - cf2_setError( error, FT_THROW( e ) ) - - -FT_END_HEADER - - -#endif /* __CF2ERROR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2fixed.h b/drivers/freetype/freetype/src/cff/cf2fixed.h deleted file mode 100644 index ed1452a7da..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2fixed.h +++ /dev/null @@ -1,95 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2fixed.h */ -/* */ -/* Adobe's code for Fixed Point Mathematics (specification only). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2FIXED_H__ -#define __CF2FIXED_H__ - - -FT_BEGIN_HEADER - - - /* rasterizer integer and fixed point arithmetic must be 32-bit */ - -#define CF2_Fixed CF2_F16Dot16 - typedef FT_Int32 CF2_Frac; /* 2.30 fixed point */ - - -#define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL ) -#define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L ) -#define CF2_FIXED_ONE 0x10000L -#define CF2_FIXED_EPSILON 0x0001 - - /* in C 89, left and right shift of negative numbers is */ - /* implementation specific behaviour in the general case */ - -#define cf2_intToFixed( i ) \ - ( (CF2_Fixed)( (FT_UInt32)(i) << 16 ) ) -#define cf2_fixedToInt( x ) \ - ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) -#define cf2_fixedRound( x ) \ - ( (CF2_Fixed)( ( (x) + 0x8000 ) & 0xFFFF0000L ) ) -#define cf2_floatToFixed( f ) \ - ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) ) -#define cf2_fixedAbs( x ) \ - ( (x) < 0 ? -(x) : (x) ) -#define cf2_fixedFloor( x ) \ - ( (CF2_Fixed)( (x) & 0xFFFF0000L ) ) -#define cf2_fixedFraction( x ) \ - ( (x) - cf2_fixedFloor( x ) ) -#define cf2_fracToFixed( x ) \ - ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \ - : ( ( (x) + 0x2000 ) >> 14 ) ) - - - /* signed numeric types */ - typedef enum CF2_NumberType_ - { - CF2_NumberFixed, /* 16.16 */ - CF2_NumberFrac, /* 2.30 */ - CF2_NumberInt /* 32.0 */ - - } CF2_NumberType; - - -FT_END_HEADER - - -#endif /* __CF2FIXED_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2font.c b/drivers/freetype/freetype/src/cff/cf2font.c deleted file mode 100644 index 479d9125d1..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2font.c +++ /dev/null @@ -1,403 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2font.c */ -/* */ -/* Adobe's code for font instances (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" - -#include "cf2glue.h" -#include "cf2font.h" -#include "cf2error.h" -#include "cf2intrp.h" - - - /* Compute a stem darkening amount in character space. */ - static void - cf2_computeDarkening( CF2_Fixed emRatio, - CF2_Fixed ppem, - CF2_Fixed stemWidth, - CF2_Fixed* darkenAmount, - CF2_Fixed boldenAmount, - FT_Bool stemDarkened ) - { - /* Internal calculations are done in units per thousand for */ - /* convenience. */ - CF2_Fixed stemWidthPer1000, scaledStem; - - - *darkenAmount = 0; - - if ( boldenAmount == 0 && !stemDarkened ) - return; - - /* protect against range problems and divide by zero */ - if ( emRatio < cf2_floatToFixed( .01 ) ) - return; - - if ( stemDarkened ) - { - /* convert from true character space to 1000 unit character space; */ - /* add synthetic emboldening effect */ - - /* we have to assure that the computation of `scaledStem' */ - /* and `stemWidthPer1000' don't overflow */ - - stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio ); - - if ( emRatio > CF2_FIXED_ONE && - stemWidthPer1000 <= ( stemWidth + boldenAmount ) ) - { - stemWidthPer1000 = 0; /* to pacify compiler */ - scaledStem = cf2_intToFixed( 2333 ); - } - else - { - scaledStem = FT_MulFix( stemWidthPer1000, ppem ); - - if ( ppem > CF2_FIXED_ONE && - scaledStem <= stemWidthPer1000 ) - scaledStem = cf2_intToFixed( 2333 ); - } - - /* - * Total darkening amount is computed in 1000 unit character space - * using the modified 5 part curve as Avalon rasterizer. - * The darkening amount is smaller for thicker stems. - * It becomes zero when the stem is thicker than 2.333 pixels. - * - * In Avalon rasterizer, - * - * darkenAmount = 0.5 pixels if scaledStem <= 0.5 pixels, - * darkenAmount = 0.333 pixels if 1 <= scaledStem <= 1.667 pixels, - * darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, - * - * and piecewise linear in-between. - * - */ - if ( scaledStem < cf2_intToFixed( 500 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 400 ), ppem ); - - else if ( scaledStem < cf2_intToFixed( 1000 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 525 ), ppem ) - - FT_MulFix( stemWidthPer1000, - cf2_floatToFixed( .25 ) ); - - else if ( scaledStem < cf2_intToFixed( 1667 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 275 ), ppem ); - - else if ( scaledStem < cf2_intToFixed( 2333 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 963 ), ppem ) - - FT_MulFix( stemWidthPer1000, - cf2_floatToFixed( .413 ) ); - - /* use half the amount on each side and convert back to true */ - /* character space */ - *darkenAmount = FT_DivFix( *darkenAmount, 2 * emRatio ); - } - - /* add synthetic emboldening effect in character space */ - *darkenAmount += boldenAmount / 2; - } - - - /* set up values for the current FontDict and matrix */ - - /* caller's transform is adjusted for subpixel positioning */ - static void - cf2_font_setup( CF2_Font font, - const CF2_Matrix* transform ) - { - /* pointer to parsed font object */ - CFF_Decoder* decoder = font->decoder; - - FT_Bool needExtraSetup; - - /* character space units */ - CF2_Fixed boldenX = font->syntheticEmboldeningAmountX; - CF2_Fixed boldenY = font->syntheticEmboldeningAmountY; - - CF2_Fixed ppem; - - - /* clear previous error */ - font->error = FT_Err_Ok; - - /* if a CID fontDict has changed, we need to recompute some cached */ - /* data */ - needExtraSetup = - (FT_Bool)( font->lastSubfont != cf2_getSubfont( decoder ) ); - - /* if ppem has changed, we need to recompute some cached data */ - /* note: because of CID font matrix concatenation, ppem and transform */ - /* do not necessarily track. */ - ppem = cf2_getPpemY( decoder ); - if ( font->ppem != ppem ) - { - font->ppem = ppem; - needExtraSetup = TRUE; - } - - /* copy hinted flag on each call */ - font->hinted = (FT_Bool)( font->renderingFlags & CF2_FlagsHinted ); - - /* determine if transform has changed; */ - /* include Fontmatrix but ignore translation */ - if ( ft_memcmp( transform, - &font->currentTransform, - 4 * sizeof ( CF2_Fixed ) ) != 0 ) - { - /* save `key' information for `cache of one' matrix data; */ - /* save client transform, without the translation */ - font->currentTransform = *transform; - font->currentTransform.tx = - font->currentTransform.ty = cf2_intToFixed( 0 ); - - /* TODO: FreeType transform is simple scalar; for now, use identity */ - /* for outer */ - font->innerTransform = *transform; - font->outerTransform.a = - font->outerTransform.d = cf2_intToFixed( 1 ); - font->outerTransform.b = - font->outerTransform.c = cf2_intToFixed( 0 ); - - needExtraSetup = TRUE; - } - - /* - * font->darkened is set to true if there is a stem darkening request or - * the font is synthetic emboldened. - * font->darkened controls whether to adjust blue zones, winding order, - * and hinting. - * - */ - if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) ) - { - font->stemDarkened = - (FT_Bool)( font->renderingFlags & CF2_FlagsDarkened ); - - /* blue zones depend on darkened flag */ - needExtraSetup = TRUE; - } - - /* recompute variables that are dependent on transform or FontDict or */ - /* darken flag */ - if ( needExtraSetup ) - { - /* StdVW is found in the private dictionary; */ - /* recompute darkening amounts whenever private dictionary or */ - /* transform change */ - /* Note: a rendering flag turns darkening on or off, so we want to */ - /* store the `on' amounts; */ - /* darkening amount is computed in character space */ - /* TODO: testing size-dependent darkening here; */ - /* what to do for rotations? */ - - CF2_Fixed emRatio; - CF2_Fixed stdHW; - CF2_Int unitsPerEm = font->unitsPerEm; - - - if ( unitsPerEm == 0 ) - unitsPerEm = 1000; - - ppem = FT_MAX( cf2_intToFixed( 4 ), - font->ppem ); /* use minimum ppem of 4 */ - -#if 0 - /* since vstem is measured in the x-direction, we use the `a' member */ - /* of the fontMatrix */ - emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a ); -#endif - - /* Freetype does not preserve the fontMatrix when parsing; use */ - /* unitsPerEm instead. */ - /* TODO: check precision of this */ - emRatio = cf2_intToFixed( 1000 ) / unitsPerEm; - font->stdVW = cf2_getStdVW( decoder ); - - if ( font->stdVW <= 0 ) - font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); - - if ( boldenX > 0 ) - { - /* Ensure that boldenX is at least 1 pixel for synthetic bold font */ - /* (similar to what Avalon does) */ - boldenX = FT_MAX( boldenX, - FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) ); - - /* Synthetic emboldening adds at least 1 pixel to darkenX, while */ - /* stem darkening adds at most half pixel. Since the purpose of */ - /* stem darkening (readability at small sizes) is met with */ - /* synthetic emboldening, no need to add stem darkening for a */ - /* synthetic bold font. */ - cf2_computeDarkening( emRatio, - ppem, - font->stdVW, - &font->darkenX, - boldenX, - FALSE ); - } - else - cf2_computeDarkening( emRatio, - ppem, - font->stdVW, - &font->darkenX, - 0, - font->stemDarkened ); - -#if 0 - /* since hstem is measured in the y-direction, we use the `d' member */ - /* of the fontMatrix */ - /* TODO: use the same units per em as above; check this */ - emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d ); -#endif - - /* set the default stem width, because it must be the same for all */ - /* family members; */ - /* choose a constant for StdHW that depends on font contrast */ - stdHW = cf2_getStdHW( decoder ); - - if ( stdHW > 0 && font->stdVW > 2 * stdHW ) - font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); - else - { - /* low contrast font gets less hstem darkening */ - font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio ); - } - - cf2_computeDarkening( emRatio, - ppem, - font->stdHW, - &font->darkenY, - boldenY, - font->stemDarkened ); - - if ( font->darkenX != 0 || font->darkenY != 0 ) - font->darkened = TRUE; - else - font->darkened = FALSE; - - font->reverseWinding = FALSE; /* initial expectation is CCW */ - - /* compute blue zones for this instance */ - cf2_blues_init( &font->blues, font ); - } - } - - - /* equivalent to AdobeGetOutline */ - FT_LOCAL_DEF( FT_Error ) - cf2_getGlyphOutline( CF2_Font font, - CF2_Buffer charstring, - const CF2_Matrix* transform, - CF2_F16Dot16* glyphWidth ) - { - FT_Error lastError = FT_Err_Ok; - - FT_Vector translation; - -#if 0 - FT_Vector advancePoint; -#endif - - CF2_Fixed advWidth = 0; - FT_Bool needWinding; - - - /* Note: use both integer and fraction for outlines. This allows bbox */ - /* to come out directly. */ - - translation.x = transform->tx; - translation.y = transform->ty; - - /* set up values based on transform */ - cf2_font_setup( font, transform ); - if ( font->error ) - goto exit; /* setup encountered an error */ - - /* reset darken direction */ - font->reverseWinding = FALSE; - - /* winding order only affects darkening */ - needWinding = font->darkened; - - while ( 1 ) - { - /* reset output buffer */ - cf2_outline_reset( &font->outline ); - - /* build the outline, passing the full translation */ - cf2_interpT2CharString( font, - charstring, - (CF2_OutlineCallbacks)&font->outline, - &translation, - FALSE, - 0, - 0, - &advWidth ); - - if ( font->error ) - goto exit; - - if ( !needWinding ) - break; - - /* check winding order */ - if ( font->outline.root.windingMomentum >= 0 ) /* CFF is CCW */ - break; - - /* invert darkening and render again */ - /* TODO: this should be a parameter to getOutline-computeOffset */ - font->reverseWinding = TRUE; - - needWinding = FALSE; /* exit after next iteration */ - } - - /* finish storing client outline */ - cf2_outline_close( &font->outline ); - - exit: - /* FreeType just wants the advance width; there is no translation */ - *glyphWidth = advWidth; - - /* free resources and collect errors from objects we've used */ - cf2_setError( &font->error, lastError ); - - return font->error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2font.h b/drivers/freetype/freetype/src/cff/cf2font.h deleted file mode 100644 index f9dd1bbd40..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2font.h +++ /dev/null @@ -1,114 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2font.h */ -/* */ -/* Adobe's code for font instances (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2FONT_H__ -#define __CF2FONT_H__ - - -#include "cf2ft.h" -#include "cf2blues.h" - - -FT_BEGIN_HEADER - - -#define CF2_OPERAND_STACK_SIZE 48 -#define CF2_MAX_SUBR 10 /* maximum subroutine nesting */ - - - /* typedef is in `cf2glue.h' */ - struct CF2_FontRec_ - { - FT_Memory memory; - FT_Error error; /* shared error for this instance */ - - CF2_RenderingFlags renderingFlags; - - /* variables that depend on Transform: */ - /* the following have zero translation; */ - /* inner * outer = font * original */ - - CF2_Matrix currentTransform; /* original client matrix */ - CF2_Matrix innerTransform; /* for hinting; erect, scaled */ - CF2_Matrix outerTransform; /* post hinting; includes rotations */ - CF2_Fixed ppem; /* transform-dependent */ - - CF2_Int unitsPerEm; - - CF2_Fixed syntheticEmboldeningAmountX; /* character space units */ - CF2_Fixed syntheticEmboldeningAmountY; /* character space units */ - - /* FreeType related members */ - CF2_OutlineRec outline; /* freetype glyph outline functions */ - CFF_Decoder* decoder; - CFF_SubFont lastSubfont; /* FreeType parsed data; */ - /* top font or subfont */ - - /* these flags can vary from one call to the next */ - FT_Bool hinted; - FT_Bool darkened; /* true if stemDarkened or synthetic bold */ - /* i.e. darkenX != 0 || darkenY != 0 */ - FT_Bool stemDarkened; - - /* variables that depend on both FontDict and Transform */ - CF2_Fixed stdVW; /* in character space; depends on dict entry */ - CF2_Fixed stdHW; /* in character space; depends on dict entry */ - CF2_Fixed darkenX; /* character space units */ - CF2_Fixed darkenY; /* depends on transform */ - /* and private dict (StdVW) */ - FT_Bool reverseWinding; /* darken assuming */ - /* counterclockwise winding */ - - CF2_BluesRec blues; /* computed zone data */ - }; - - - FT_LOCAL( FT_Error ) - cf2_getGlyphOutline( CF2_Font font, - CF2_Buffer charstring, - const CF2_Matrix* transform, - CF2_F16Dot16* glyphWidth ); - - -FT_END_HEADER - - -#endif /* __CF2FONT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2ft.c b/drivers/freetype/freetype/src/cff/cf2ft.c deleted file mode 100644 index c09a0244a8..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2ft.c +++ /dev/null @@ -1,639 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2ft.c */ -/* */ -/* FreeType Glue Component to Adobe's Interpreter (body). */ -/* */ -/* Copyright 2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" -#include FT_INTERNAL_DEBUG_H - -#include "cf2font.h" -#include "cf2error.h" - - -#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */ - - - /* - * This check should avoid most internal overflow cases. Clients should - * generally respond to `Glyph_Too_Big' by getting a glyph outline - * at EM size, scaling it and filling it as a graphics operation. - * - */ - static FT_Error - cf2_checkTransform( const CF2_Matrix* transform, - CF2_Int unitsPerEm ) - { - CF2_Fixed maxScale; - - - FT_ASSERT( unitsPerEm > 0 ); - - FT_ASSERT( transform->a > 0 && transform->d > 0 ); - FT_ASSERT( transform->b == 0 && transform->c == 0 ); - FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); - - if ( unitsPerEm > 0x7FFF ) - return FT_THROW( Glyph_Too_Big ); - - maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) ); - - if ( transform->a > maxScale || transform->d > maxScale ) - return FT_THROW( Glyph_Too_Big ); - - return FT_Err_Ok; - } - - - static void - cf2_setGlyphWidth( CF2_Outline outline, - CF2_Fixed width ) - { - CFF_Decoder* decoder = outline->decoder; - - - FT_ASSERT( decoder ); - - decoder->glyph_width = cf2_fixedToInt( width ); - } - - - /* Clean up font instance. */ - static void - cf2_free_instance( void* ptr ) - { - CF2_Font font = (CF2_Font)ptr; - - - if ( font ) - { - FT_Memory memory = font->memory; - - - (void)memory; - } - } - - - /********************************************/ - /* */ - /* functions for handling client outline; */ - /* FreeType uses coordinates in 26.6 format */ - /* */ - /********************************************/ - - static void - cf2_builder_moveTo( CF2_OutlineCallbacks callbacks, - const CF2_CallbackParams params ) - { - /* downcast the object pointer */ - CF2_Outline outline = (CF2_Outline)callbacks; - CFF_Builder* builder; - - (void)params; /* only used in debug mode */ - - - FT_ASSERT( outline && outline->decoder ); - FT_ASSERT( params->op == CF2_PathOpMoveTo ); - - builder = &outline->decoder->builder; - - /* note: two successive moves simply close the contour twice */ - cff_builder_close_contour( builder ); - builder->path_begun = 0; - } - - - static void - cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, - const CF2_CallbackParams params ) - { - /* downcast the object pointer */ - CF2_Outline outline = (CF2_Outline)callbacks; - CFF_Builder* builder; - - - FT_ASSERT( outline && outline->decoder ); - FT_ASSERT( params->op == CF2_PathOpLineTo ); - - builder = &outline->decoder->builder; - - if ( !builder->path_begun ) - { - /* record the move before the line; also check points and set */ - /* `path_begun' */ - cff_builder_start_point( builder, - params->pt0.x, - params->pt0.y ); - } - - /* `cff_builder_add_point1' includes a check_points call for one point */ - cff_builder_add_point1( builder, - params->pt1.x, - params->pt1.y ); - } - - - static void - cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, - const CF2_CallbackParams params ) - { - /* downcast the object pointer */ - CF2_Outline outline = (CF2_Outline)callbacks; - CFF_Builder* builder; - - - FT_ASSERT( outline && outline->decoder ); - FT_ASSERT( params->op == CF2_PathOpCubeTo ); - - builder = &outline->decoder->builder; - - if ( !builder->path_begun ) - { - /* record the move before the line; also check points and set */ - /* `path_begun' */ - cff_builder_start_point( builder, - params->pt0.x, - params->pt0.y ); - } - - /* prepare room for 3 points: 2 off-curve, 1 on-curve */ - cff_check_points( builder, 3 ); - - cff_builder_add_point( builder, - params->pt1.x, - params->pt1.y, 0 ); - cff_builder_add_point( builder, - params->pt2.x, - params->pt2.y, 0 ); - cff_builder_add_point( builder, - params->pt3.x, - params->pt3.y, 1 ); - } - - - static void - cf2_outline_init( CF2_Outline outline, - FT_Memory memory, - FT_Error* error ) - { - FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) ); - - outline->root.memory = memory; - outline->root.error = error; - - outline->root.moveTo = cf2_builder_moveTo; - outline->root.lineTo = cf2_builder_lineTo; - outline->root.cubeTo = cf2_builder_cubeTo; - } - - - /* get scaling and hint flag from GlyphSlot */ - static void - cf2_getScaleAndHintFlag( CFF_Decoder* decoder, - CF2_Fixed* x_scale, - CF2_Fixed* y_scale, - FT_Bool* hinted, - FT_Bool* scaled ) - { - FT_ASSERT( decoder && decoder->builder.glyph ); - - /* note: FreeType scale includes a factor of 64 */ - *hinted = decoder->builder.glyph->hint; - *scaled = decoder->builder.glyph->scaled; - - if ( *hinted ) - { - *x_scale = FT_DivFix( decoder->builder.glyph->x_scale, - cf2_intToFixed( 64 ) ); - *y_scale = FT_DivFix( decoder->builder.glyph->y_scale, - cf2_intToFixed( 64 ) ); - } - else - { - /* for unhinted outlines, `cff_slot_load' does the scaling, */ - /* thus render at `unity' scale */ - - *x_scale = 0x0400; /* 1/64 as 16.16 */ - *y_scale = 0x0400; - } - } - - - /* get units per em from `FT_Face' */ - /* TODO: should handle font matrix concatenation? */ - static FT_UShort - cf2_getUnitsPerEm( CFF_Decoder* decoder ) - { - FT_ASSERT( decoder && decoder->builder.face ); - FT_ASSERT( decoder->builder.face->root.units_per_EM ); - - return decoder->builder.face->root.units_per_EM; - } - - - /* Main entry point: Render one glyph. */ - FT_LOCAL_DEF( FT_Error ) - cf2_decoder_parse_charstrings( CFF_Decoder* decoder, - FT_Byte* charstring_base, - FT_ULong charstring_len ) - { - FT_Memory memory; - FT_Error error = FT_Err_Ok; - CF2_Font font; - - - FT_ASSERT( decoder && decoder->cff ); - - memory = decoder->builder.memory; - - /* CF2 data is saved here across glyphs */ - font = (CF2_Font)decoder->cff->cf2_instance.data; - - /* on first glyph, allocate instance structure */ - if ( decoder->cff->cf2_instance.data == NULL ) - { - decoder->cff->cf2_instance.finalizer = - (FT_Generic_Finalizer)cf2_free_instance; - - if ( FT_ALLOC( decoder->cff->cf2_instance.data, - sizeof ( CF2_FontRec ) ) ) - return FT_THROW( Out_Of_Memory ); - - font = (CF2_Font)decoder->cff->cf2_instance.data; - - font->memory = memory; - - /* initialize a client outline, to be shared by each glyph rendered */ - cf2_outline_init( &font->outline, font->memory, &font->error ); - } - - /* save decoder; it is a stack variable and will be different on each */ - /* call */ - font->decoder = decoder; - font->outline.decoder = decoder; - - { - /* build parameters for Adobe engine */ - - CFF_Builder* builder = &decoder->builder; - CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face ); - - /* local error */ - FT_Error error2 = FT_Err_Ok; - CF2_BufferRec buf; - CF2_Matrix transform; - CF2_F16Dot16 glyphWidth; - - FT_Bool hinted; - FT_Bool scaled; - - - /* FreeType has already looked up the GID; convert to */ - /* `RegionBuffer', assuming that the input has been validated */ - FT_ASSERT( charstring_base + charstring_len >= charstring_base ); - - FT_ZERO( &buf ); - buf.start = - buf.ptr = charstring_base; - buf.end = charstring_base + charstring_len; - - FT_ZERO( &transform ); - - cf2_getScaleAndHintFlag( decoder, - &transform.a, - &transform.d, - &hinted, - &scaled ); - - font->renderingFlags = 0; - if ( hinted ) - font->renderingFlags |= CF2_FlagsHinted; - if ( scaled && !driver->no_stem_darkening ) - font->renderingFlags |= CF2_FlagsDarkened; - - /* now get an outline for this glyph; */ - /* also get units per em to validate scale */ - font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); - - error2 = cf2_checkTransform( &transform, font->unitsPerEm ); - if ( error2 ) - return error2; - - error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); - if ( error2 ) - return FT_ERR( Invalid_File_Format ); - - cf2_setGlyphWidth( &font->outline, glyphWidth ); - - return FT_Err_Ok; - } - } - - - /* get pointer to current FreeType subfont (based on current glyphID) */ - FT_LOCAL_DEF( CFF_SubFont ) - cf2_getSubfont( CFF_Decoder* decoder ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - return decoder->current_subfont; - } - - - /* get `y_ppem' from `CFF_Size' */ - FT_LOCAL_DEF( CF2_Fixed ) - cf2_getPpemY( CFF_Decoder* decoder ) - { - FT_ASSERT( decoder && - decoder->builder.face && - decoder->builder.face->root.size ); - FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem ); - - return cf2_intToFixed( - decoder->builder.face->root.size->metrics.y_ppem ); - } - - - /* get standard stem widths for the current subfont; */ - /* FreeType stores these as integer font units */ - /* (note: variable names seem swapped) */ - FT_LOCAL_DEF( CF2_Fixed ) - cf2_getStdVW( CFF_Decoder* decoder ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - return cf2_intToFixed( - decoder->current_subfont->private_dict.standard_height ); - } - - - FT_LOCAL_DEF( CF2_Fixed ) - cf2_getStdHW( CFF_Decoder* decoder ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - return cf2_intToFixed( - decoder->current_subfont->private_dict.standard_width ); - } - - - /* note: FreeType stores 1000 times the actual value for `BlueScale' */ - FT_LOCAL_DEF( void ) - cf2_getBlueMetrics( CFF_Decoder* decoder, - CF2_Fixed* blueScale, - CF2_Fixed* blueShift, - CF2_Fixed* blueFuzz ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - *blueScale = FT_DivFix( - decoder->current_subfont->private_dict.blue_scale, - cf2_intToFixed( 1000 ) ); - *blueShift = cf2_intToFixed( - decoder->current_subfont->private_dict.blue_shift ); - *blueFuzz = cf2_intToFixed( - decoder->current_subfont->private_dict.blue_fuzz ); - } - - - /* get blue values counts and arrays; the FreeType parser has validated */ - /* the counts and verified that each is an even number */ - FT_LOCAL_DEF( void ) - cf2_getBlueValues( CFF_Decoder* decoder, - size_t* count, - FT_Pos* *data ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - *count = decoder->current_subfont->private_dict.num_blue_values; - *data = (FT_Pos*) - &decoder->current_subfont->private_dict.blue_values; - } - - - FT_LOCAL_DEF( void ) - cf2_getOtherBlues( CFF_Decoder* decoder, - size_t* count, - FT_Pos* *data ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - *count = decoder->current_subfont->private_dict.num_other_blues; - *data = (FT_Pos*) - &decoder->current_subfont->private_dict.other_blues; - } - - - FT_LOCAL_DEF( void ) - cf2_getFamilyBlues( CFF_Decoder* decoder, - size_t* count, - FT_Pos* *data ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - *count = decoder->current_subfont->private_dict.num_family_blues; - *data = (FT_Pos*) - &decoder->current_subfont->private_dict.family_blues; - } - - - FT_LOCAL_DEF( void ) - cf2_getFamilyOtherBlues( CFF_Decoder* decoder, - size_t* count, - FT_Pos* *data ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - *count = decoder->current_subfont->private_dict.num_family_other_blues; - *data = (FT_Pos*) - &decoder->current_subfont->private_dict.family_other_blues; - } - - - FT_LOCAL_DEF( CF2_Int ) - cf2_getLanguageGroup( CFF_Decoder* decoder ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - return decoder->current_subfont->private_dict.language_group; - } - - - /* convert unbiased subroutine index to `CF2_Buffer' and */ - /* return 0 on success */ - FT_LOCAL_DEF( CF2_Int ) - cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, - CF2_Buffer buf ) - { - FT_ASSERT( decoder && decoder->globals ); - - FT_ZERO( buf ); - - idx += decoder->globals_bias; - if ( idx >= decoder->num_globals ) - return TRUE; /* error */ - - buf->start = - buf->ptr = decoder->globals[idx]; - buf->end = decoder->globals[idx + 1]; - - return FALSE; /* success */ - } - - - /* convert AdobeStandardEncoding code to CF2_Buffer; */ - /* used for seac component */ - FT_LOCAL_DEF( FT_Error ) - cf2_getSeacComponent( CFF_Decoder* decoder, - CF2_UInt code, - CF2_Buffer buf ) - { - CF2_Int gid; - FT_Byte* charstring; - FT_ULong len; - FT_Error error; - - - FT_ASSERT( decoder ); - - FT_ZERO( buf ); - - gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code ); - if ( gid < 0 ) - return FT_THROW( Invalid_Glyph_Format ); - - error = cff_get_glyph_data( decoder->builder.face, - gid, - &charstring, - &len ); - /* TODO: for now, just pass the FreeType error through */ - if ( error ) - return error; - - /* assume input has been validated */ - FT_ASSERT( charstring + len >= charstring ); - - buf->start = charstring; - buf->end = charstring + len; - buf->ptr = buf->start; - - return FT_Err_Ok; - } - - - FT_LOCAL_DEF( void ) - cf2_freeSeacComponent( CFF_Decoder* decoder, - CF2_Buffer buf ) - { - FT_ASSERT( decoder ); - - cff_free_glyph_data( decoder->builder.face, - (FT_Byte**)&buf->start, - (FT_ULong)( buf->end - buf->start ) ); - } - - - FT_LOCAL_DEF( CF2_Int ) - cf2_initLocalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, - CF2_Buffer buf ) - { - FT_ASSERT( decoder && decoder->locals ); - - FT_ZERO( buf ); - - idx += decoder->locals_bias; - if ( idx >= decoder->num_locals ) - return TRUE; /* error */ - - buf->start = - buf->ptr = decoder->locals[idx]; - buf->end = decoder->locals[idx + 1]; - - return FALSE; /* success */ - } - - - FT_LOCAL_DEF( CF2_Fixed ) - cf2_getDefaultWidthX( CFF_Decoder* decoder ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - return cf2_intToFixed( - decoder->current_subfont->private_dict.default_width ); - } - - - FT_LOCAL_DEF( CF2_Fixed ) - cf2_getNominalWidthX( CFF_Decoder* decoder ) - { - FT_ASSERT( decoder && decoder->current_subfont ); - - return cf2_intToFixed( - decoder->current_subfont->private_dict.nominal_width ); - } - - - FT_LOCAL_DEF( void ) - cf2_outline_reset( CF2_Outline outline ) - { - CFF_Decoder* decoder = outline->decoder; - - - FT_ASSERT( decoder ); - - outline->root.windingMomentum = 0; - - FT_GlyphLoader_Rewind( decoder->builder.loader ); - } - - - FT_LOCAL_DEF( void ) - cf2_outline_close( CF2_Outline outline ) - { - CFF_Decoder* decoder = outline->decoder; - - - FT_ASSERT( decoder ); - - cff_builder_close_contour( &decoder->builder ); - - FT_GlyphLoader_Add( decoder->builder.loader ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2ft.h b/drivers/freetype/freetype/src/cff/cf2ft.h deleted file mode 100644 index 731da3ca8c..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2ft.h +++ /dev/null @@ -1,147 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2ft.h */ -/* */ -/* FreeType Glue Component to Adobe's Interpreter (specification). */ -/* */ -/* Copyright 2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2FT_H__ -#define __CF2FT_H__ - - -#include "cf2types.h" - - - /* TODO: disable asserts for now */ -#define CF2_NDEBUG - - -#include FT_SYSTEM_H - -#include "cf2glue.h" -#include "cffgload.h" /* for CFF_Decoder */ - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - cf2_decoder_parse_charstrings( CFF_Decoder* decoder, - FT_Byte* charstring_base, - FT_ULong charstring_len ); - - FT_LOCAL( CFF_SubFont ) - cf2_getSubfont( CFF_Decoder* decoder ); - - - FT_LOCAL( CF2_Fixed ) - cf2_getPpemY( CFF_Decoder* decoder ); - FT_LOCAL( CF2_Fixed ) - cf2_getStdVW( CFF_Decoder* decoder ); - FT_LOCAL( CF2_Fixed ) - cf2_getStdHW( CFF_Decoder* decoder ); - - FT_LOCAL( void ) - cf2_getBlueMetrics( CFF_Decoder* decoder, - CF2_Fixed* blueScale, - CF2_Fixed* blueShift, - CF2_Fixed* blueFuzz ); - FT_LOCAL( void ) - cf2_getBlueValues( CFF_Decoder* decoder, - size_t* count, - FT_Pos* *data ); - FT_LOCAL( void ) - cf2_getOtherBlues( CFF_Decoder* decoder, - size_t* count, - FT_Pos* *data ); - FT_LOCAL( void ) - cf2_getFamilyBlues( CFF_Decoder* decoder, - size_t* count, - FT_Pos* *data ); - FT_LOCAL( void ) - cf2_getFamilyOtherBlues( CFF_Decoder* decoder, - size_t* count, - FT_Pos* *data ); - - FT_LOCAL( CF2_Int ) - cf2_getLanguageGroup( CFF_Decoder* decoder ); - - FT_LOCAL( CF2_Int ) - cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, - CF2_Buffer buf ); - FT_LOCAL( FT_Error ) - cf2_getSeacComponent( CFF_Decoder* decoder, - CF2_UInt code, - CF2_Buffer buf ); - FT_LOCAL( void ) - cf2_freeSeacComponent( CFF_Decoder* decoder, - CF2_Buffer buf ); - FT_LOCAL( CF2_Int ) - cf2_initLocalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, - CF2_Buffer buf ); - - FT_LOCAL( CF2_Fixed ) - cf2_getDefaultWidthX( CFF_Decoder* decoder ); - FT_LOCAL( CF2_Fixed ) - cf2_getNominalWidthX( CFF_Decoder* decoder ); - - - /* - * FreeType client outline - * - * process output from the charstring interpreter - */ - typedef struct CF2_OutlineRec_ - { - CF2_OutlineCallbacksRec root; /* base class must be first */ - CFF_Decoder* decoder; - - } CF2_OutlineRec, *CF2_Outline; - - - FT_LOCAL( void ) - cf2_outline_reset( CF2_Outline outline ); - FT_LOCAL( void ) - cf2_outline_close( CF2_Outline outline ); - - -FT_END_HEADER - - -#endif /* __CF2FT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2glue.h b/drivers/freetype/freetype/src/cff/cf2glue.h deleted file mode 100644 index a24da39e93..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2glue.h +++ /dev/null @@ -1,144 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2glue.h */ -/* */ -/* Adobe's code for shared stuff (specification only). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2GLUE_H__ -#define __CF2GLUE_H__ - - -/* common includes for other modules */ -#include "cf2error.h" -#include "cf2fixed.h" -#include "cf2arrst.h" -#include "cf2read.h" - - -FT_BEGIN_HEADER - - - /* rendering parameters */ - - /* apply hints to rendered glyphs */ -#define CF2_FlagsHinted 1 - /* for testing */ -#define CF2_FlagsDarkened 2 - - /* type for holding the flags */ - typedef CF2_Int CF2_RenderingFlags; - - - /* elements of a glyph outline */ - typedef enum CF2_PathOp_ - { - CF2_PathOpMoveTo = 1, /* change the current point */ - CF2_PathOpLineTo = 2, /* line */ - CF2_PathOpQuadTo = 3, /* quadratic curve */ - CF2_PathOpCubeTo = 4 /* cubic curve */ - - } CF2_PathOp; - - - /* a matrix of fixed point values */ - typedef struct CF2_Matrix_ - { - CF2_F16Dot16 a; - CF2_F16Dot16 b; - CF2_F16Dot16 c; - CF2_F16Dot16 d; - CF2_F16Dot16 tx; - CF2_F16Dot16 ty; - - } CF2_Matrix; - - - /* these typedefs are needed by more than one header file */ - /* and gcc compiler doesn't allow redefinition */ - typedef struct CF2_FontRec_ CF2_FontRec, *CF2_Font; - typedef struct CF2_HintRec_ CF2_HintRec, *CF2_Hint; - - - /* A common structure for all callback parameters. */ - /* */ - /* Some members may be unused. For example, `pt0' is not used for */ - /* `moveTo' and `pt3' is not used for `quadTo'. The initial point `pt0' */ - /* is included for each path element for generality; curve conversions */ - /* need it. The `op' parameter allows one function to handle multiple */ - /* element types. */ - - typedef struct CF2_CallbackParamsRec_ - { - FT_Vector pt0; - FT_Vector pt1; - FT_Vector pt2; - FT_Vector pt3; - - CF2_Int op; - - } CF2_CallbackParamsRec, *CF2_CallbackParams; - - - /* forward reference */ - typedef struct CF2_OutlineCallbacksRec_ CF2_OutlineCallbacksRec, - *CF2_OutlineCallbacks; - - /* callback function pointers */ - typedef void - (*CF2_Callback_Type)( CF2_OutlineCallbacks callbacks, - const CF2_CallbackParams params ); - - - struct CF2_OutlineCallbacksRec_ - { - CF2_Callback_Type moveTo; - CF2_Callback_Type lineTo; - CF2_Callback_Type quadTo; - CF2_Callback_Type cubeTo; - - CF2_Int windingMomentum; /* for winding order detection */ - - FT_Memory memory; - FT_Error* error; - }; - - -FT_END_HEADER - - -#endif /* __CF2GLUE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2hints.c b/drivers/freetype/freetype/src/cff/cf2hints.c deleted file mode 100644 index 96bd49f186..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2hints.c +++ /dev/null @@ -1,1734 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2hints.c */ -/* */ -/* Adobe's code for handling CFF hints (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" -#include FT_INTERNAL_DEBUG_H - -#include "cf2glue.h" -#include "cf2font.h" -#include "cf2hints.h" -#include "cf2intrp.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_cf2hints - - - typedef struct CF2_HintMoveRec_ - { - size_t j; /* index of upper hint map edge */ - CF2_Fixed moveUp; /* adjustment to optimum position */ - - } CF2_HintMoveRec, *CF2_HintMove; - - - /* Compute angular momentum for winding order detection. It is called */ - /* for all lines and curves, but not necessarily in element order. */ - static CF2_Int - cf2_getWindingMomentum( CF2_Fixed x1, - CF2_Fixed y1, - CF2_Fixed x2, - CF2_Fixed y2 ) - { - /* cross product of pt1 position from origin with pt2 position from */ - /* pt1; we reduce the precision so that the result fits into 32 bits */ - - return ( x1 >> 16 ) * ( ( y2 - y1 ) >> 16 ) - - ( y1 >> 16 ) * ( ( x2 - x1 ) >> 16 ); - } - - - /* - * Construct from a StemHint; this is used as a parameter to - * `cf2_blues_capture'. - * `hintOrigin' is the character space displacement of a seac accent. - * Adjust stem hint for darkening here. - * - */ - static void - cf2_hint_init( CF2_Hint hint, - const CF2_ArrStack stemHintArray, - size_t indexStemHint, - const CF2_Font font, - CF2_Fixed hintOrigin, - CF2_Fixed scale, - FT_Bool bottom ) - { - CF2_Fixed width; - const CF2_StemHintRec* stemHint; - - - FT_ZERO( hint ); - - stemHint = (const CF2_StemHintRec*)cf2_arrstack_getPointer( - stemHintArray, - indexStemHint ); - - width = stemHint->max - stemHint->min; - - if ( width == cf2_intToFixed( -21 ) ) - { - /* ghost bottom */ - - if ( bottom ) - { - hint->csCoord = stemHint->max; - hint->flags = CF2_GhostBottom; - } - else - hint->flags = 0; - } - - else if ( width == cf2_intToFixed( -20 ) ) - { - /* ghost top */ - - if ( bottom ) - hint->flags = 0; - else - { - hint->csCoord = stemHint->min; - hint->flags = CF2_GhostTop; - } - } - - else if ( width < 0 ) - { - /* inverted pair */ - - /* - * Hints with negative widths were produced by an early version of a - * non-Adobe font tool. The Type 2 spec allows edge (ghost) hints - * with negative widths, but says - * - * All other negative widths have undefined meaning. - * - * CoolType has a silent workaround that negates the hint width; for - * permissive mode, we do the same here. - * - * Note: Such fonts cannot use ghost hints, but should otherwise work. - * Note: Some poor hints in our faux fonts can produce negative - * widths at some blends. For example, see a light weight of - * `u' in ASerifMM. - * - */ - if ( bottom ) - { - hint->csCoord = stemHint->max; - hint->flags = CF2_PairBottom; - } - else - { - hint->csCoord = stemHint->min; - hint->flags = CF2_PairTop; - } - } - - else - { - /* normal pair */ - - if ( bottom ) - { - hint->csCoord = stemHint->min; - hint->flags = CF2_PairBottom; - } - else - { - hint->csCoord = stemHint->max; - hint->flags = CF2_PairTop; - } - } - - /* Now that ghost hints have been detected, adjust this edge for */ - /* darkening. Bottoms are not changed; tops are incremented by twice */ - /* `darkenY'. */ - if ( cf2_hint_isTop( hint ) ) - hint->csCoord += 2 * font->darkenY; - - hint->csCoord += hintOrigin; - hint->scale = scale; - hint->index = indexStemHint; /* index in original stem hint array */ - - /* if original stem hint has been used, use the same position */ - if ( hint->flags != 0 && stemHint->used ) - { - if ( cf2_hint_isTop( hint ) ) - hint->dsCoord = stemHint->maxDS; - else - hint->dsCoord = stemHint->minDS; - - cf2_hint_lock( hint ); - } - else - hint->dsCoord = FT_MulFix( hint->csCoord, scale ); - } - - - /* initialize an invalid hint map element */ - static void - cf2_hint_initZero( CF2_Hint hint ) - { - FT_ZERO( hint ); - } - - - FT_LOCAL_DEF( FT_Bool ) - cf2_hint_isValid( const CF2_Hint hint ) - { - return (FT_Bool)( hint->flags != 0 ); - } - - - static FT_Bool - cf2_hint_isPair( const CF2_Hint hint ) - { - return (FT_Bool)( ( hint->flags & - ( CF2_PairBottom | CF2_PairTop ) ) != 0 ); - } - - - static FT_Bool - cf2_hint_isPairTop( const CF2_Hint hint ) - { - return (FT_Bool)( ( hint->flags & CF2_PairTop ) != 0 ); - } - - - FT_LOCAL_DEF( FT_Bool ) - cf2_hint_isTop( const CF2_Hint hint ) - { - return (FT_Bool)( ( hint->flags & - ( CF2_PairTop | CF2_GhostTop ) ) != 0 ); - } - - - FT_LOCAL_DEF( FT_Bool ) - cf2_hint_isBottom( const CF2_Hint hint ) - { - return (FT_Bool)( ( hint->flags & - ( CF2_PairBottom | CF2_GhostBottom ) ) != 0 ); - } - - - static FT_Bool - cf2_hint_isLocked( const CF2_Hint hint ) - { - return (FT_Bool)( ( hint->flags & CF2_Locked ) != 0 ); - } - - - static FT_Bool - cf2_hint_isSynthetic( const CF2_Hint hint ) - { - return (FT_Bool)( ( hint->flags & CF2_Synthetic ) != 0 ); - } - - - FT_LOCAL_DEF( void ) - cf2_hint_lock( CF2_Hint hint ) - { - hint->flags |= CF2_Locked; - } - - - FT_LOCAL_DEF( void ) - cf2_hintmap_init( CF2_HintMap hintmap, - CF2_Font font, - CF2_HintMap initialMap, - CF2_ArrStack hintMoves, - CF2_Fixed scale ) - { - FT_ZERO( hintmap ); - - /* copy parameters from font instance */ - hintmap->hinted = font->hinted; - hintmap->scale = scale; - hintmap->font = font; - hintmap->initialHintMap = initialMap; - /* will clear in `cf2_hintmap_adjustHints' */ - hintmap->hintMoves = hintMoves; - } - - - static FT_Bool - cf2_hintmap_isValid( const CF2_HintMap hintmap ) - { - return hintmap->isValid; - } - - - /* transform character space coordinate to device space using hint map */ - static CF2_Fixed - cf2_hintmap_map( CF2_HintMap hintmap, - CF2_Fixed csCoord ) - { - FT_ASSERT( hintmap->isValid ); /* must call Build before Map */ - FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); - - if ( hintmap->count == 0 || ! hintmap->hinted ) - { - /* there are no hints; use uniform scale and zero offset */ - return FT_MulFix( csCoord, hintmap->scale ); - } - else - { - /* start linear search from last hit */ - CF2_UInt i = hintmap->lastIndex; - - - /* search up */ - while ( i < hintmap->count - 1 && - csCoord >= hintmap->edge[i + 1].csCoord ) - i += 1; - - /* search down */ - while ( i > 0 && csCoord < hintmap->edge[i].csCoord ) - i -= 1; - - hintmap->lastIndex = i; - - if ( i == 0 && csCoord < hintmap->edge[0].csCoord ) - { - /* special case for points below first edge: use uniform scale */ - return FT_MulFix( csCoord - hintmap->edge[0].csCoord, - hintmap->scale ) + - hintmap->edge[0].dsCoord; - } - else - { - /* - * Note: entries with duplicate csCoord are allowed. - * Use edge[i], the highest entry where csCoord >= entry[i].csCoord - */ - return FT_MulFix( csCoord - hintmap->edge[i].csCoord, - hintmap->edge[i].scale ) + - hintmap->edge[i].dsCoord; - } - } - } - - - /* - * This hinting policy moves a hint pair in device space so that one of - * its two edges is on a device pixel boundary (its fractional part is - * zero). `cf2_hintmap_insertHint' guarantees no overlap in CS - * space. Ensure here that there is no overlap in DS. - * - * In the first pass, edges are adjusted relative to adjacent hints. - * Those that are below have already been adjusted. Those that are - * above have not yet been adjusted. If a hint above blocks an - * adjustment to an optimal position, we will try again in a second - * pass. The second pass is top-down. - * - */ - - static void - cf2_hintmap_adjustHints( CF2_HintMap hintmap ) - { - size_t i, j; - - - cf2_arrstack_clear( hintmap->hintMoves ); /* working storage */ - - /* - * First pass is bottom-up (font hint order) without look-ahead. - * Locked edges are already adjusted. - * Unlocked edges begin with dsCoord from `initialHintMap'. - * Save edges that are not optimally adjusted in `hintMoves' array, - * and process them in second pass. - */ - - for ( i = 0; i < hintmap->count; i++ ) - { - FT_Bool isPair = cf2_hint_isPair( &hintmap->edge[i] ); - - - /* index of upper edge (same value for ghost hint) */ - j = isPair ? i + 1 : i; - - FT_ASSERT( j < hintmap->count ); - FT_ASSERT( cf2_hint_isValid( &hintmap->edge[i] ) ); - FT_ASSERT( cf2_hint_isValid( &hintmap->edge[j] ) ); - FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) == - cf2_hint_isLocked( &hintmap->edge[j] ) ); - - if ( !cf2_hint_isLocked( &hintmap->edge[i] ) ) - { - /* hint edge is not locked, we can adjust it */ - CF2_Fixed fracDown = cf2_fixedFraction( hintmap->edge[i].dsCoord ); - CF2_Fixed fracUp = cf2_fixedFraction( hintmap->edge[j].dsCoord ); - - /* calculate all four possibilities; moves down are negative */ - CF2_Fixed downMoveDown = 0 - fracDown; - CF2_Fixed upMoveDown = 0 - fracUp; - CF2_Fixed downMoveUp = fracDown == 0 - ? 0 - : cf2_intToFixed( 1 ) - fracDown; - CF2_Fixed upMoveUp = fracUp == 0 - ? 0 - : cf2_intToFixed( 1 ) - fracUp; - - /* smallest move up */ - CF2_Fixed moveUp = FT_MIN( downMoveUp, upMoveUp ); - /* smallest move down */ - CF2_Fixed moveDown = FT_MAX( downMoveDown, upMoveDown ); - - /* final amount to move edge or edge pair */ - CF2_Fixed move; - - CF2_Fixed downMinCounter = CF2_MIN_COUNTER; - CF2_Fixed upMinCounter = CF2_MIN_COUNTER; - FT_Bool saveEdge = FALSE; - - - /* minimum counter constraint doesn't apply when adjacent edges */ - /* are synthetic */ - /* TODO: doesn't seem a big effect; for now, reduce the code */ -#if 0 - if ( i == 0 || - cf2_hint_isSynthetic( &hintmap->edge[i - 1] ) ) - downMinCounter = 0; - - if ( j >= hintmap->count - 1 || - cf2_hint_isSynthetic( &hintmap->edge[j + 1] ) ) - upMinCounter = 0; -#endif - - /* is there room to move up? */ - /* there is if we are at top of array or the next edge is at or */ - /* beyond proposed move up? */ - if ( j >= hintmap->count - 1 || - hintmap->edge[j + 1].dsCoord >= - hintmap->edge[j].dsCoord + moveUp + upMinCounter ) - { - /* there is room to move up; is there also room to move down? */ - if ( i == 0 || - hintmap->edge[i - 1].dsCoord <= - hintmap->edge[i].dsCoord + moveDown - downMinCounter ) - { - /* move smaller absolute amount */ - move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */ - } - else - move = moveUp; - } - else - { - /* is there room to move down? */ - if ( i == 0 || - hintmap->edge[i - 1].dsCoord <= - hintmap->edge[i].dsCoord + moveDown - downMinCounter ) - { - move = moveDown; - /* true if non-optimum move */ - saveEdge = (FT_Bool)( moveUp < -moveDown ); - } - else - { - /* no room to move either way without overlapping or reducing */ - /* the counter too much */ - move = 0; - saveEdge = TRUE; - } - } - - /* Identify non-moves and moves down that aren't optimal, and save */ - /* them for second pass. */ - /* Do this only if there is an unlocked edge above (which could */ - /* possibly move). */ - if ( saveEdge && - j < hintmap->count - 1 && - !cf2_hint_isLocked( &hintmap->edge[j + 1] ) ) - { - CF2_HintMoveRec savedMove; - - - savedMove.j = j; - /* desired adjustment in second pass */ - savedMove.moveUp = moveUp - move; - - cf2_arrstack_push( hintmap->hintMoves, &savedMove ); - } - - /* move the edge(s) */ - hintmap->edge[i].dsCoord += move; - if ( isPair ) - hintmap->edge[j].dsCoord += move; - } - - /* assert there are no overlaps in device space */ - FT_ASSERT( i == 0 || - hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord ); - FT_ASSERT( i < j || - hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord ); - - /* adjust the scales, avoiding divide by zero */ - if ( i > 0 ) - { - if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord ) - hintmap->edge[i - 1].scale = - FT_DivFix( - hintmap->edge[i].dsCoord - hintmap->edge[i - 1].dsCoord, - hintmap->edge[i].csCoord - hintmap->edge[i - 1].csCoord ); - } - - if ( isPair ) - { - if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord ) - hintmap->edge[j - 1].scale = - FT_DivFix( - hintmap->edge[j].dsCoord - hintmap->edge[j - 1].dsCoord, - hintmap->edge[j].csCoord - hintmap->edge[j - 1].csCoord ); - - i += 1; /* skip upper edge on next loop */ - } - } - - /* second pass tries to move non-optimal hints up, in case there is */ - /* room now */ - for ( i = cf2_arrstack_size( hintmap->hintMoves ); i > 0; i-- ) - { - CF2_HintMove hintMove = (CF2_HintMove) - cf2_arrstack_getPointer( hintmap->hintMoves, i - 1 ); - - - j = hintMove->j; - - /* this was tested before the push, above */ - FT_ASSERT( j < hintmap->count - 1 ); - - /* is there room to move up? */ - if ( hintmap->edge[j + 1].dsCoord >= - hintmap->edge[j].dsCoord + hintMove->moveUp + CF2_MIN_COUNTER ) - { - /* there is more room now, move edge up */ - hintmap->edge[j].dsCoord += hintMove->moveUp; - - if ( cf2_hint_isPair( &hintmap->edge[j] ) ) - { - FT_ASSERT( j > 0 ); - hintmap->edge[j - 1].dsCoord += hintMove->moveUp; - } - } - } - } - - - /* insert hint edges into map, sorted by csCoord */ - static void - cf2_hintmap_insertHint( CF2_HintMap hintmap, - CF2_Hint bottomHintEdge, - CF2_Hint topHintEdge ) - { - CF2_UInt indexInsert; - - /* set default values, then check for edge hints */ - FT_Bool isPair = TRUE; - CF2_Hint firstHintEdge = bottomHintEdge; - CF2_Hint secondHintEdge = topHintEdge; - - - /* one or none of the input params may be invalid when dealing with */ - /* edge hints; at least one edge must be valid */ - FT_ASSERT( cf2_hint_isValid( bottomHintEdge ) || - cf2_hint_isValid( topHintEdge ) ); - - /* determine how many and which edges to insert */ - if ( !cf2_hint_isValid( bottomHintEdge ) ) - { - /* insert only the top edge */ - firstHintEdge = topHintEdge; - isPair = FALSE; - } - else if ( !cf2_hint_isValid( topHintEdge ) ) - { - /* insert only the bottom edge */ - isPair = FALSE; - } - - /* paired edges must be in proper order */ - FT_ASSERT( !isPair || - topHintEdge->csCoord >= bottomHintEdge->csCoord ); - - /* linear search to find index value of insertion point */ - indexInsert = 0; - for ( ; indexInsert < hintmap->count; indexInsert++ ) - { - if ( hintmap->edge[indexInsert].csCoord > firstHintEdge->csCoord ) - break; - } - - /* - * Discard any hints that overlap in character space. Most often, - * this is while building the initial map, but in theory, it can also - * occur because of darkening. - * - */ - if ( indexInsert < hintmap->count ) - { - /* we are inserting before an existing edge: */ - /* verify that a new pair does not straddle the next edge */ - if ( isPair && - hintmap->edge[indexInsert].csCoord < secondHintEdge->csCoord ) - return; /* ignore overlapping stem hint */ - - /* verify that we are not inserting between paired edges */ - if ( cf2_hint_isPairTop( &hintmap->edge[indexInsert] ) ) - return; /* ignore overlapping stem hint */ - } - - /* recompute device space locations using initial hint map */ - if ( cf2_hintmap_isValid( hintmap->initialHintMap ) && - !cf2_hint_isLocked( firstHintEdge ) ) - { - if ( isPair ) - { - /* Use hint map to position the center of stem, and nominal scale */ - /* to position the two edges. This preserves the stem width. */ - CF2_Fixed midpoint = cf2_hintmap_map( - hintmap->initialHintMap, - ( secondHintEdge->csCoord + - firstHintEdge->csCoord ) / 2 ); - CF2_Fixed halfWidth = FT_MulFix( - ( secondHintEdge->csCoord - - firstHintEdge->csCoord ) / 2, - hintmap->scale ); - - - firstHintEdge->dsCoord = midpoint - halfWidth; - secondHintEdge->dsCoord = midpoint + halfWidth; - } - else - firstHintEdge->dsCoord = cf2_hintmap_map( hintmap->initialHintMap, - firstHintEdge->csCoord ); - } - - /* discard any hints that overlap in device space; this can occur */ - /* because locked hints have been moved to align with blue zones */ - if ( indexInsert > 0 ) - { - /* we are inserting after an existing edge */ - if ( firstHintEdge->dsCoord < hintmap->edge[indexInsert - 1].dsCoord ) - return; - } - - if ( indexInsert < hintmap->count ) - { - /* we are inserting before an existing edge */ - if ( isPair ) - { - if ( secondHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord ) - return; - } - else - { - if ( firstHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord ) - return; - } - } - - /* make room to insert */ - { - CF2_Int iSrc = hintmap->count - 1; - CF2_Int iDst = isPair ? hintmap->count + 1 : hintmap->count; - - CF2_Int count = hintmap->count - indexInsert; - - - if ( iDst >= CF2_MAX_HINT_EDGES ) - { - FT_TRACE4(( "cf2_hintmap_insertHint: too many hintmaps\n" )); - return; - } - - while ( count-- ) - hintmap->edge[iDst--] = hintmap->edge[iSrc--]; - - /* insert first edge */ - hintmap->edge[indexInsert] = *firstHintEdge; /* copy struct */ - hintmap->count += 1; - - if ( isPair ) - { - /* insert second edge */ - hintmap->edge[indexInsert + 1] = *secondHintEdge; /* copy struct */ - hintmap->count += 1; - } - } - - return; - } - - - /* - * Build a map from hints and mask. - * - * This function may recur one level if `hintmap->initialHintMap' is not yet - * valid. - * If `initialMap' is true, simply build initial map. - * - * Synthetic hints are used in two ways. A hint at zero is inserted, if - * needed, in the initial hint map, to prevent translations from - * propagating across the origin. If synthetic em box hints are enabled - * for ideographic dictionaries, then they are inserted in all hint - * maps, including the initial one. - * - */ - FT_LOCAL_DEF( void ) - cf2_hintmap_build( CF2_HintMap hintmap, - CF2_ArrStack hStemHintArray, - CF2_ArrStack vStemHintArray, - CF2_HintMask hintMask, - CF2_Fixed hintOrigin, - FT_Bool initialMap ) - { - FT_Byte* maskPtr; - - CF2_Font font = hintmap->font; - CF2_HintMaskRec tempHintMask; - - size_t bitCount, i; - FT_Byte maskByte; - - - /* check whether initial map is constructed */ - if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) ) - { - /* make recursive call with initialHintMap and temporary mask; */ - /* temporary mask will get all bits set, below */ - cf2_hintmask_init( &tempHintMask, hintMask->error ); - cf2_hintmap_build( hintmap->initialHintMap, - hStemHintArray, - vStemHintArray, - &tempHintMask, - hintOrigin, - TRUE ); - } - - if ( !cf2_hintmask_isValid( hintMask ) ) - { - /* without a hint mask, assume all hints are active */ - cf2_hintmask_setAll( hintMask, - cf2_arrstack_size( hStemHintArray ) + - cf2_arrstack_size( vStemHintArray ) ); - } - - /* begin by clearing the map */ - hintmap->count = 0; - hintmap->lastIndex = 0; - - /* make a copy of the hint mask so we can modify it */ - tempHintMask = *hintMask; - maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask ); - - /* use the hStem hints only, which are first in the mask */ - /* TODO: compare this to cffhintmaskGetBitCount */ - bitCount = cf2_arrstack_size( hStemHintArray ); - - /* synthetic embox hints get highest priority */ - if ( font->blues.doEmBoxHints ) - { - CF2_HintRec dummy; - - - cf2_hint_initZero( &dummy ); /* invalid hint map element */ - - /* ghost bottom */ - cf2_hintmap_insertHint( hintmap, - &font->blues.emBoxBottomEdge, - &dummy ); - /* ghost top */ - cf2_hintmap_insertHint( hintmap, - &dummy, - &font->blues.emBoxTopEdge ); - } - - /* insert hints captured by a blue zone or already locked (higher */ - /* priority) */ - for ( i = 0, maskByte = 0x80; i < bitCount; i++ ) - { - if ( maskByte & *maskPtr ) - { - /* expand StemHint into two `CF2_Hint' elements */ - CF2_HintRec bottomHintEdge, topHintEdge; - - - cf2_hint_init( &bottomHintEdge, - hStemHintArray, - i, - font, - hintOrigin, - hintmap->scale, - TRUE /* bottom */ ); - cf2_hint_init( &topHintEdge, - hStemHintArray, - i, - font, - hintOrigin, - hintmap->scale, - FALSE /* top */ ); - - if ( cf2_hint_isLocked( &bottomHintEdge ) || - cf2_hint_isLocked( &topHintEdge ) || - cf2_blues_capture( &font->blues, - &bottomHintEdge, - &topHintEdge ) ) - { - /* insert captured hint into map */ - cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge ); - - *maskPtr &= ~maskByte; /* turn off the bit for this hint */ - } - } - - if ( ( i & 7 ) == 7 ) - { - /* move to next mask byte */ - maskPtr++; - maskByte = 0x80; - } - else - maskByte >>= 1; - } - - /* initial hint map includes only captured hints plus maybe one at 0 */ - - /* - * TODO: There is a problem here because we are trying to build a - * single hint map containing all captured hints. It is - * possible for there to be conflicts between captured hints, - * either because of darkening or because the hints are in - * separate hint zones (we are ignoring hint zones for the - * initial map). An example of the latter is MinionPro-Regular - * v2.030 glyph 883 (Greek Capital Alpha with Psili) at 15ppem. - * A stem hint for the psili conflicts with the top edge hint - * for the base character. The stem hint gets priority because - * of its sort order. In glyph 884 (Greek Capital Alpha with - * Psili and Oxia), the top of the base character gets a stem - * hint, and the psili does not. This creates different initial - * maps for the two glyphs resulting in different renderings of - * the base character. Will probably defer this either as not - * worth the cost or as a font bug. I don't think there is any - * good reason for an accent to be captured by an alignment - * zone. -darnold 2/12/10 - */ - - if ( initialMap ) - { - /* Apply a heuristic that inserts a point for (0,0), unless it's */ - /* already covered by a mapping. This locks the baseline for glyphs */ - /* that have no baseline hints. */ - - if ( hintmap->count == 0 || - hintmap->edge[0].csCoord > 0 || - hintmap->edge[hintmap->count - 1].csCoord < 0 ) - { - /* all edges are above 0 or all edges are below 0; */ - /* construct a locked edge hint at 0 */ - - CF2_HintRec edge, invalid; - - - cf2_hint_initZero( &edge ); - - edge.flags = CF2_GhostBottom | - CF2_Locked | - CF2_Synthetic; - edge.scale = hintmap->scale; - - cf2_hint_initZero( &invalid ); - cf2_hintmap_insertHint( hintmap, &edge, &invalid ); - } - } - else - { - /* insert remaining hints */ - - maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask ); - - for ( i = 0, maskByte = 0x80; i < bitCount; i++ ) - { - if ( maskByte & *maskPtr ) - { - CF2_HintRec bottomHintEdge, topHintEdge; - - - cf2_hint_init( &bottomHintEdge, - hStemHintArray, - i, - font, - hintOrigin, - hintmap->scale, - TRUE /* bottom */ ); - cf2_hint_init( &topHintEdge, - hStemHintArray, - i, - font, - hintOrigin, - hintmap->scale, - FALSE /* top */ ); - - cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge ); - } - - if ( ( i & 7 ) == 7 ) - { - /* move to next mask byte */ - maskPtr++; - maskByte = 0x80; - } - else - maskByte >>= 1; - } - } - - /* - * Note: The following line is a convenient place to break when - * debugging hinting. Examine `hintmap->edge' for the list of - * enabled hints, then step over the call to see the effect of - * adjustment. We stop here first on the recursive call that - * creates the initial map, and then on each counter group and - * hint zone. - */ - - /* adjust positions of hint edges that are not locked to blue zones */ - cf2_hintmap_adjustHints( hintmap ); - - /* save the position of all hints that were used in this hint map; */ - /* if we use them again, we'll locate them in the same position */ - if ( !initialMap ) - { - for ( i = 0; i < hintmap->count; i++ ) - { - if ( !cf2_hint_isSynthetic( &hintmap->edge[i] ) ) - { - /* Note: include both valid and invalid edges */ - /* Note: top and bottom edges are copied back separately */ - CF2_StemHint stemhint = (CF2_StemHint) - cf2_arrstack_getPointer( hStemHintArray, - hintmap->edge[i].index ); - - - if ( cf2_hint_isTop( &hintmap->edge[i] ) ) - stemhint->maxDS = hintmap->edge[i].dsCoord; - else - stemhint->minDS = hintmap->edge[i].dsCoord; - - stemhint->used = TRUE; - } - } - } - - /* hint map is ready to use */ - hintmap->isValid = TRUE; - - /* remember this mask has been used */ - cf2_hintmask_setNew( hintMask, FALSE ); - } - - - FT_LOCAL_DEF( void ) - cf2_glyphpath_init( CF2_GlyphPath glyphpath, - CF2_Font font, - CF2_OutlineCallbacks callbacks, - CF2_Fixed scaleY, - /* CF2_Fixed hShift, */ - CF2_ArrStack hStemHintArray, - CF2_ArrStack vStemHintArray, - CF2_HintMask hintMask, - CF2_Fixed hintOriginY, - const CF2_Blues blues, - const FT_Vector* fractionalTranslation ) - { - FT_ZERO( glyphpath ); - - glyphpath->font = font; - glyphpath->callbacks = callbacks; - - cf2_arrstack_init( &glyphpath->hintMoves, - font->memory, - &font->error, - sizeof ( CF2_HintMoveRec ) ); - - cf2_hintmap_init( &glyphpath->initialHintMap, - font, - &glyphpath->initialHintMap, - &glyphpath->hintMoves, - scaleY ); - cf2_hintmap_init( &glyphpath->firstHintMap, - font, - &glyphpath->initialHintMap, - &glyphpath->hintMoves, - scaleY ); - cf2_hintmap_init( &glyphpath->hintMap, - font, - &glyphpath->initialHintMap, - &glyphpath->hintMoves, - scaleY ); - - glyphpath->scaleX = font->innerTransform.a; - glyphpath->scaleC = font->innerTransform.c; - glyphpath->scaleY = font->innerTransform.d; - - glyphpath->fractionalTranslation = *fractionalTranslation; - -#if 0 - glyphpath->hShift = hShift; /* for fauxing */ -#endif - - glyphpath->hStemHintArray = hStemHintArray; - glyphpath->vStemHintArray = vStemHintArray; - glyphpath->hintMask = hintMask; /* ptr to current mask */ - glyphpath->hintOriginY = hintOriginY; - glyphpath->blues = blues; - glyphpath->darken = font->darkened; /* TODO: should we make copies? */ - glyphpath->xOffset = font->darkenX; - glyphpath->yOffset = font->darkenY; - glyphpath->miterLimit = 2 * FT_MAX( - cf2_fixedAbs( glyphpath->xOffset ), - cf2_fixedAbs( glyphpath->yOffset ) ); - - /* .1 character space unit */ - glyphpath->snapThreshold = cf2_floatToFixed( 0.1f ); - - glyphpath->moveIsPending = TRUE; - glyphpath->pathIsOpen = FALSE; - glyphpath->elemIsQueued = FALSE; - } - - - FT_LOCAL_DEF( void ) - cf2_glyphpath_finalize( CF2_GlyphPath glyphpath ) - { - cf2_arrstack_finalize( &glyphpath->hintMoves ); - } - - - /* - * Hint point in y-direction and apply outerTransform. - * Input `current' hint map (which is actually delayed by one element). - * Input x,y point in Character Space. - * Output x,y point in Device Space, including translation. - */ - static void - cf2_glyphpath_hintPoint( CF2_GlyphPath glyphpath, - CF2_HintMap hintmap, - FT_Vector* ppt, - CF2_Fixed x, - CF2_Fixed y ) - { - FT_Vector pt; /* hinted point in upright DS */ - - - pt.x = FT_MulFix( glyphpath->scaleX, x ) + - FT_MulFix( glyphpath->scaleC, y ); - pt.y = cf2_hintmap_map( hintmap, y ); - - ppt->x = FT_MulFix( glyphpath->font->outerTransform.a, pt.x ) + - FT_MulFix( glyphpath->font->outerTransform.c, pt.y ) + - glyphpath->fractionalTranslation.x; - ppt->y = FT_MulFix( glyphpath->font->outerTransform.b, pt.x ) + - FT_MulFix( glyphpath->font->outerTransform.d, pt.y ) + - glyphpath->fractionalTranslation.y; - } - - - /* - * From two line segments, (u1,u2) and (v1,v2), compute a point of - * intersection on the corresponding lines. - * Return false if no intersection is found, or if the intersection is - * too far away from the ends of the line segments, u2 and v1. - * - */ - static FT_Bool - cf2_glyphpath_computeIntersection( CF2_GlyphPath glyphpath, - const FT_Vector* u1, - const FT_Vector* u2, - const FT_Vector* v1, - const FT_Vector* v2, - FT_Vector* intersection ) - { - /* - * Let `u' be a zero-based vector from the first segment, `v' from the - * second segment. - * Let `w 'be the zero-based vector from `u1' to `v1'. - * `perp' is the `perpendicular dot product'; see - * http://mathworld.wolfram.com/PerpDotProduct.html. - * `s' is the parameter for the parametric line for the first segment - * (`u'). - * - * See notation in - * http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm. - * Calculations are done in 16.16, but must handle the squaring of - * line lengths in character space. We scale all vectors by 1/32 to - * avoid overflow. This allows values up to 4095 to be squared. The - * scale factor cancels in the divide. - * - * TODO: the scale factor could be computed from UnitsPerEm. - * - */ - -#define cf2_perp( a, b ) \ - ( FT_MulFix( a.x, b.y ) - FT_MulFix( a.y, b.x ) ) - - /* round and divide by 32 */ -#define CF2_CS_SCALE( x ) \ - ( ( (x) + 0x10 ) >> 5 ) - - FT_Vector u, v, w; /* scaled vectors */ - CF2_Fixed denominator, s; - - - u.x = CF2_CS_SCALE( u2->x - u1->x ); - u.y = CF2_CS_SCALE( u2->y - u1->y ); - v.x = CF2_CS_SCALE( v2->x - v1->x ); - v.y = CF2_CS_SCALE( v2->y - v1->y ); - w.x = CF2_CS_SCALE( v1->x - u1->x ); - w.y = CF2_CS_SCALE( v1->y - u1->y ); - - denominator = cf2_perp( u, v ); - - if ( denominator == 0 ) - return FALSE; /* parallel or coincident lines */ - - s = FT_DivFix( cf2_perp( w, v ), denominator ); - - intersection->x = u1->x + FT_MulFix( s, u2->x - u1->x ); - intersection->y = u1->y + FT_MulFix( s, u2->y - u1->y ); - - /* - * Special case snapping for horizontal and vertical lines. - * This cleans up intersections and reduces problems with winding - * order detection. - * Sample case is sbc cd KozGoPr6N-Medium.otf 20 16685. - * Note: these calculations are in character space. - * - */ - - if ( u1->x == u2->x && - cf2_fixedAbs( intersection->x - u1->x ) < glyphpath->snapThreshold ) - intersection->x = u1->x; - if ( u1->y == u2->y && - cf2_fixedAbs( intersection->y - u1->y ) < glyphpath->snapThreshold ) - intersection->y = u1->y; - - if ( v1->x == v2->x && - cf2_fixedAbs( intersection->x - v1->x ) < glyphpath->snapThreshold ) - intersection->x = v1->x; - if ( v1->y == v2->y && - cf2_fixedAbs( intersection->y - v1->y ) < glyphpath->snapThreshold ) - intersection->y = v1->y; - - /* limit the intersection distance from midpoint of u2 and v1 */ - if ( cf2_fixedAbs( intersection->x - ( u2->x + v1->x ) / 2 ) > - glyphpath->miterLimit || - cf2_fixedAbs( intersection->y - ( u2->y + v1->y ) / 2 ) > - glyphpath->miterLimit ) - return FALSE; - - return TRUE; - } - - - /* - * Push the cached element (glyphpath->prevElem*) to the outline - * consumer. When a darkening offset is used, the end point of the - * cached element may be adjusted to an intersection point or it may be - * connected by a line to the current element. This calculation must - * use a HintMap that was valid at the time the element was saved. For - * the first point in a subpath, that is a saved HintMap. For most - * elements, it just means the caller has delayed building a HintMap - * from the current HintMask. - * - * Transform each point with outerTransform and call the outline - * callbacks. This is a general 3x3 transform: - * - * x' = a*x + c*y + tx, y' = b*x + d*y + ty - * - * but it uses 4 elements from CF2_Font and the translation part - * from CF2_GlyphPath. - * - */ - static void - cf2_glyphpath_pushPrevElem( CF2_GlyphPath glyphpath, - CF2_HintMap hintmap, - FT_Vector* nextP0, - FT_Vector nextP1, - FT_Bool close ) - { - CF2_CallbackParamsRec params; - - FT_Vector* prevP0; - FT_Vector* prevP1; - - FT_Vector intersection = { 0, 0 }; - FT_Bool useIntersection = FALSE; - - - FT_ASSERT( glyphpath->prevElemOp == CF2_PathOpLineTo || - glyphpath->prevElemOp == CF2_PathOpCubeTo ); - - if ( glyphpath->prevElemOp == CF2_PathOpLineTo ) - { - prevP0 = &glyphpath->prevElemP0; - prevP1 = &glyphpath->prevElemP1; - } - else - { - prevP0 = &glyphpath->prevElemP2; - prevP1 = &glyphpath->prevElemP3; - } - - /* optimization: if previous and next elements are offset by the same */ - /* amount, then there will be no gap, and no need to compute an */ - /* intersection. */ - if ( prevP1->x != nextP0->x || prevP1->y != nextP0->y ) - { - /* previous element does not join next element: */ - /* adjust end point of previous element to the intersection */ - useIntersection = cf2_glyphpath_computeIntersection( glyphpath, - prevP0, - prevP1, - nextP0, - &nextP1, - &intersection ); - if ( useIntersection ) - { - /* modify the last point of the cached element (either line or */ - /* curve) */ - *prevP1 = intersection; - } - } - - params.pt0 = glyphpath->currentDS; - - switch( glyphpath->prevElemOp ) - { - case CF2_PathOpLineTo: - params.op = CF2_PathOpLineTo; - - /* note: pt2 and pt3 are unused */ - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt1, - glyphpath->prevElemP1.x, - glyphpath->prevElemP1.y ); - - glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); - - glyphpath->currentDS = params.pt1; - - break; - - case CF2_PathOpCubeTo: - params.op = CF2_PathOpCubeTo; - - /* TODO: should we intersect the interior joins (p1-p2 and p2-p3)? */ - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt1, - glyphpath->prevElemP1.x, - glyphpath->prevElemP1.y ); - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt2, - glyphpath->prevElemP2.x, - glyphpath->prevElemP2.y ); - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt3, - glyphpath->prevElemP3.x, - glyphpath->prevElemP3.y ); - - glyphpath->callbacks->cubeTo( glyphpath->callbacks, ¶ms ); - - glyphpath->currentDS = params.pt3; - - break; - } - - if ( !useIntersection || close ) - { - /* insert connecting line between end of previous element and start */ - /* of current one */ - /* note: at the end of a subpath, we might do both, so use `nextP0' */ - /* before we change it, below */ - - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt1, - nextP0->x, - nextP0->y ); - - if ( params.pt1.x != glyphpath->currentDS.x || - params.pt1.y != glyphpath->currentDS.y ) - { - /* length is nonzero */ - params.op = CF2_PathOpLineTo; - params.pt0 = glyphpath->currentDS; - - /* note: pt2 and pt3 are unused */ - glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); - - glyphpath->currentDS = params.pt1; - } - } - - if ( useIntersection ) - { - /* return intersection point to caller */ - *nextP0 = intersection; - } - } - - - /* push a MoveTo element based on current point and offset of current */ - /* element */ - static void - cf2_glyphpath_pushMove( CF2_GlyphPath glyphpath, - FT_Vector start ) - { - CF2_CallbackParamsRec params; - - - params.op = CF2_PathOpMoveTo; - params.pt0 = glyphpath->currentDS; - - /* Test if move has really happened yet; it would have called */ - /* `cf2_hintmap_build' to set `isValid'. */ - if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) ) - { - /* we are here iff first subpath is missing a moveto operator: */ - /* synthesize first moveTo to finish initialization of hintMap */ - cf2_glyphpath_moveTo( glyphpath, - glyphpath->start.x, - glyphpath->start.y ); - } - - cf2_glyphpath_hintPoint( glyphpath, - &glyphpath->hintMap, - ¶ms.pt1, - start.x, - start.y ); - - /* note: pt2 and pt3 are unused */ - glyphpath->callbacks->moveTo( glyphpath->callbacks, ¶ms ); - - glyphpath->currentDS = params.pt1; - glyphpath->offsetStart0 = start; - } - - - /* - * All coordinates are in character space. - * On input, (x1, y1) and (x2, y2) give line segment. - * On output, (x, y) give offset vector. - * We use a piecewise approximation to trig functions. - * - * TODO: Offset true perpendicular and proper length - * supply the y-translation for hinting here, too, - * that adds yOffset unconditionally to *y. - */ - static void - cf2_glyphpath_computeOffset( CF2_GlyphPath glyphpath, - CF2_Fixed x1, - CF2_Fixed y1, - CF2_Fixed x2, - CF2_Fixed y2, - CF2_Fixed* x, - CF2_Fixed* y ) - { - CF2_Fixed dx = x2 - x1; - CF2_Fixed dy = y2 - y1; - - - /* note: negative offsets don't work here; negate deltas to change */ - /* quadrants, below */ - if ( glyphpath->font->reverseWinding ) - { - dx = -dx; - dy = -dy; - } - - *x = *y = 0; - - if ( !glyphpath->darken ) - return; - - /* add momentum for this path element */ - glyphpath->callbacks->windingMomentum += - cf2_getWindingMomentum( x1, y1, x2, y2 ); - - /* note: allow mixed integer and fixed multiplication here */ - if ( dx >= 0 ) - { - if ( dy >= 0 ) - { - /* first quadrant, +x +y */ - - if ( dx > 2 * dy ) - { - /* +x */ - *x = 0; - *y = 0; - } - else if ( dy > 2 * dx ) - { - /* +y */ - *x = glyphpath->xOffset; - *y = glyphpath->yOffset; - } - else - { - /* +x +y */ - *x = FT_MulFix( cf2_floatToFixed( 0.7 ), - glyphpath->xOffset ); - *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ), - glyphpath->yOffset ); - } - } - else - { - /* fourth quadrant, +x -y */ - - if ( dx > -2 * dy ) - { - /* +x */ - *x = 0; - *y = 0; - } - else if ( -dy > 2 * dx ) - { - /* -y */ - *x = -glyphpath->xOffset; - *y = glyphpath->yOffset; - } - else - { - /* +x -y */ - *x = FT_MulFix( cf2_floatToFixed( -0.7 ), - glyphpath->xOffset ); - *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ), - glyphpath->yOffset ); - } - } - } - else - { - if ( dy >= 0 ) - { - /* second quadrant, -x +y */ - - if ( -dx > 2 * dy ) - { - /* -x */ - *x = 0; - *y = 2 * glyphpath->yOffset; - } - else if ( dy > -2 * dx ) - { - /* +y */ - *x = glyphpath->xOffset; - *y = glyphpath->yOffset; - } - else - { - /* -x +y */ - *x = FT_MulFix( cf2_floatToFixed( 0.7 ), - glyphpath->xOffset ); - *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ), - glyphpath->yOffset ); - } - } - else - { - /* third quadrant, -x -y */ - - if ( -dx > -2 * dy ) - { - /* -x */ - *x = 0; - *y = 2 * glyphpath->yOffset; - } - else if ( -dy > -2 * dx ) - { - /* -y */ - *x = -glyphpath->xOffset; - *y = glyphpath->xOffset; - } - else - { - /* -x -y */ - *x = FT_MulFix( cf2_floatToFixed( -0.7 ), - glyphpath->xOffset ); - *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ), - glyphpath->yOffset ); - } - } - } - } - - - FT_LOCAL_DEF( void ) - cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, - CF2_Fixed x, - CF2_Fixed y ) - { - cf2_glyphpath_closeOpenPath( glyphpath ); - - /* save the parameters of the move for later, when we'll know how to */ - /* offset it; */ - /* also save last move point */ - glyphpath->currentCS.x = glyphpath->start.x = x; - glyphpath->currentCS.y = glyphpath->start.y = y; - - glyphpath->moveIsPending = TRUE; - - /* ensure we have a valid map with current mask */ - if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) || - cf2_hintmask_isNew( glyphpath->hintMask ) ) - cf2_hintmap_build( &glyphpath->hintMap, - glyphpath->hStemHintArray, - glyphpath->vStemHintArray, - glyphpath->hintMask, - glyphpath->hintOriginY, - FALSE ); - - /* save a copy of current HintMap to use when drawing initial point */ - glyphpath->firstHintMap = glyphpath->hintMap; /* structure copy */ - } - - - FT_LOCAL_DEF( void ) - cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath, - CF2_Fixed x, - CF2_Fixed y ) - { - CF2_Fixed xOffset, yOffset; - FT_Vector P0, P1; - - - /* can't compute offset of zero length line, so ignore them */ - if ( glyphpath->currentCS.x == x && glyphpath->currentCS.y == y ) - return; - - cf2_glyphpath_computeOffset( glyphpath, - glyphpath->currentCS.x, - glyphpath->currentCS.y, - x, - y, - &xOffset, - &yOffset ); - - /* construct offset points */ - P0.x = glyphpath->currentCS.x + xOffset; - P0.y = glyphpath->currentCS.y + yOffset; - P1.x = x + xOffset; - P1.y = y + yOffset; - - if ( glyphpath->moveIsPending ) - { - /* emit offset 1st point as MoveTo */ - cf2_glyphpath_pushMove( glyphpath, P0 ); - - glyphpath->moveIsPending = FALSE; /* adjust state machine */ - glyphpath->pathIsOpen = TRUE; - - glyphpath->offsetStart1 = P1; /* record second point */ - } - - if ( glyphpath->elemIsQueued ) - { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ); - - cf2_glyphpath_pushPrevElem( glyphpath, - &glyphpath->hintMap, - &P0, - P1, - FALSE ); - } - - /* queue the current element with offset points */ - glyphpath->elemIsQueued = TRUE; - glyphpath->prevElemOp = CF2_PathOpLineTo; - glyphpath->prevElemP0 = P0; - glyphpath->prevElemP1 = P1; - - /* update current map */ - if ( cf2_hintmask_isNew( glyphpath->hintMask ) ) - cf2_hintmap_build( &glyphpath->hintMap, - glyphpath->hStemHintArray, - glyphpath->vStemHintArray, - glyphpath->hintMask, - glyphpath->hintOriginY, - FALSE ); - - glyphpath->currentCS.x = x; /* pre-offset current point */ - glyphpath->currentCS.y = y; - } - - - FT_LOCAL_DEF( void ) - cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath, - CF2_Fixed x1, - CF2_Fixed y1, - CF2_Fixed x2, - CF2_Fixed y2, - CF2_Fixed x3, - CF2_Fixed y3 ) - { - CF2_Fixed xOffset1, yOffset1, xOffset3, yOffset3; - FT_Vector P0, P1, P2, P3; - - - /* TODO: ignore zero length portions of curve?? */ - cf2_glyphpath_computeOffset( glyphpath, - glyphpath->currentCS.x, - glyphpath->currentCS.y, - x1, - y1, - &xOffset1, - &yOffset1 ); - cf2_glyphpath_computeOffset( glyphpath, - x2, - y2, - x3, - y3, - &xOffset3, - &yOffset3 ); - - /* add momentum from the middle segment */ - glyphpath->callbacks->windingMomentum += - cf2_getWindingMomentum( x1, y1, x2, y2 ); - - /* construct offset points */ - P0.x = glyphpath->currentCS.x + xOffset1; - P0.y = glyphpath->currentCS.y + yOffset1; - P1.x = x1 + xOffset1; - P1.y = y1 + yOffset1; - /* note: preserve angle of final segment by using offset3 at both ends */ - P2.x = x2 + xOffset3; - P2.y = y2 + yOffset3; - P3.x = x3 + xOffset3; - P3.y = y3 + yOffset3; - - if ( glyphpath->moveIsPending ) - { - /* emit offset 1st point as MoveTo */ - cf2_glyphpath_pushMove( glyphpath, P0 ); - - glyphpath->moveIsPending = FALSE; - glyphpath->pathIsOpen = TRUE; - - glyphpath->offsetStart1 = P1; /* record second point */ - } - - if ( glyphpath->elemIsQueued ) - { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ); - - cf2_glyphpath_pushPrevElem( glyphpath, - &glyphpath->hintMap, - &P0, - P1, - FALSE ); - } - - /* queue the current element with offset points */ - glyphpath->elemIsQueued = TRUE; - glyphpath->prevElemOp = CF2_PathOpCubeTo; - glyphpath->prevElemP0 = P0; - glyphpath->prevElemP1 = P1; - glyphpath->prevElemP2 = P2; - glyphpath->prevElemP3 = P3; - - /* update current map */ - if ( cf2_hintmask_isNew( glyphpath->hintMask ) ) - cf2_hintmap_build( &glyphpath->hintMap, - glyphpath->hStemHintArray, - glyphpath->vStemHintArray, - glyphpath->hintMask, - glyphpath->hintOriginY, - FALSE ); - - glyphpath->currentCS.x = x3; /* pre-offset current point */ - glyphpath->currentCS.y = y3; - } - - - FT_LOCAL_DEF( void ) - cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath ) - { - if ( glyphpath->pathIsOpen ) - { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->firstHintMap ) ); - - /* since we need to apply an offset to the implicit lineto, we make */ - /* it explicit here */ - cf2_glyphpath_lineTo( glyphpath, - glyphpath->start.x, - glyphpath->start.y ); - - /* Draw previous element (the explicit LineTo we just created, */ - /* above) and connect it to the start point, but with the offset we */ - /* saved from the first element. */ - /* Use the saved HintMap, too. */ - FT_ASSERT( glyphpath->elemIsQueued ); - - cf2_glyphpath_pushPrevElem( glyphpath, - &glyphpath->firstHintMap, - &glyphpath->offsetStart0, - glyphpath->offsetStart1, - TRUE ); - - /* reset state machine */ - glyphpath->moveIsPending = TRUE; - glyphpath->pathIsOpen = FALSE; - glyphpath->elemIsQueued = FALSE; - } - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2hints.h b/drivers/freetype/freetype/src/cff/cf2hints.h deleted file mode 100644 index c4fa922a39..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2hints.h +++ /dev/null @@ -1,287 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2hints.h */ -/* */ -/* Adobe's code for handling CFF hints (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2HINTS_H__ -#define __CF2HINTS_H__ - - -FT_BEGIN_HEADER - - - enum - { - CF2_MAX_HINTS = 96 /* maximum # of hints */ - }; - - - /* - * A HintMask object stores a bit mask that specifies which hints in the - * charstring are active at a given time. Hints in CFF must be declared - * at the start, before any drawing operators, with horizontal hints - * preceding vertical hints. The HintMask is ordered the same way, with - * horizontal hints immediately followed by vertical hints. Clients are - * responsible for knowing how many of each type are present. - * - * The maximum total number of hints is 96, as specified by the CFF - * specification. - * - * A HintMask is built 0 or more times while interpreting a charstring, by - * the HintMask operator. There is only one HintMask, but it is built or - * rebuilt each time there is a hint substitution (HintMask operator) in - * the charstring. A default HintMask with all bits set is built if there - * has been no HintMask operator prior to the first drawing operator. - * - */ - - typedef struct CF2_HintMaskRec_ - { - FT_Error* error; - - FT_Bool isValid; - FT_Bool isNew; - - size_t bitCount; - size_t byteCount; - - FT_Byte mask[( CF2_MAX_HINTS + 7 ) / 8]; - - } CF2_HintMaskRec, *CF2_HintMask; - - - typedef struct CF2_StemHintRec_ - { - FT_Bool used; /* DS positions are valid */ - - CF2_Fixed min; /* original character space value */ - CF2_Fixed max; - - CF2_Fixed minDS; /* DS position after first use */ - CF2_Fixed maxDS; - - } CF2_StemHintRec, *CF2_StemHint; - - - /* - * A HintMap object stores a piecewise linear function for mapping - * y-coordinates from character space to device space, providing - * appropriate pixel alignment to stem edges. - * - * The map is implemented as an array of `CF2_Hint' elements, each - * representing an edge. When edges are paired, as from stem hints, the - * bottom edge must immediately precede the top edge in the array. - * Element character space AND device space positions must both increase - * monotonically in the array. `CF2_Hint' elements are also used as - * parameters to `cf2_blues_capture'. - * - * The `cf2_hintmap_build' method must be called before any drawing - * operation (beginning with a Move operator) and at each hint - * substitution (HintMask operator). - * - * The `cf2_hintmap_map' method is called to transform y-coordinates at - * each drawing operation (move, line, curve). - * - */ - - /* TODO: make this a CF2_ArrStack and add a deep copy method */ - enum - { - CF2_MAX_HINT_EDGES = CF2_MAX_HINTS * 2 - }; - - - typedef struct CF2_HintMapRec_ - { - CF2_Font font; - - /* initial map based on blue zones */ - struct CF2_HintMapRec_* initialHintMap; - - /* working storage for 2nd pass adjustHints */ - CF2_ArrStack hintMoves; - - FT_Bool isValid; - FT_Bool hinted; - - CF2_Fixed scale; - CF2_UInt count; - - /* start search from this index */ - CF2_UInt lastIndex; - - CF2_HintRec edge[CF2_MAX_HINT_EDGES]; /* 192 */ - - } CF2_HintMapRec, *CF2_HintMap; - - - FT_LOCAL( FT_Bool ) - cf2_hint_isValid( const CF2_Hint hint ); - FT_LOCAL( FT_Bool ) - cf2_hint_isTop( const CF2_Hint hint ); - FT_LOCAL( FT_Bool ) - cf2_hint_isBottom( const CF2_Hint hint ); - FT_LOCAL( void ) - cf2_hint_lock( CF2_Hint hint ); - - - FT_LOCAL( void ) - cf2_hintmap_init( CF2_HintMap hintmap, - CF2_Font font, - CF2_HintMap initialMap, - CF2_ArrStack hintMoves, - CF2_Fixed scale ); - FT_LOCAL( void ) - cf2_hintmap_build( CF2_HintMap hintmap, - CF2_ArrStack hStemHintArray, - CF2_ArrStack vStemHintArray, - CF2_HintMask hintMask, - CF2_Fixed hintOrigin, - FT_Bool initialMap ); - - - /* - * GlyphPath is a wrapper for drawing operations that scales the - * coordinates according to the render matrix and HintMap. It also tracks - * open paths to control ClosePath and to insert MoveTo for broken fonts. - * - */ - typedef struct CF2_GlyphPathRec_ - { - /* TODO: gather some of these into a hinting context */ - - CF2_Font font; /* font instance */ - CF2_OutlineCallbacks callbacks; /* outline consumer */ - - - CF2_HintMapRec hintMap; /* current hint map */ - CF2_HintMapRec firstHintMap; /* saved copy */ - CF2_HintMapRec initialHintMap; /* based on all captured hints */ - - CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */ - - CF2_Fixed scaleX; /* matrix a */ - CF2_Fixed scaleC; /* matrix c */ - CF2_Fixed scaleY; /* matrix d */ - - FT_Vector fractionalTranslation; /* including deviceXScale */ -#if 0 - CF2_Fixed hShift; /* character space horizontal shift */ - /* (for fauxing) */ -#endif - - FT_Bool pathIsOpen; /* true after MoveTo */ - FT_Bool darken; /* true if stem darkening */ - FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */ - - /* references used to call `cf2_hintmap_build', if necessary */ - CF2_ArrStack hStemHintArray; - CF2_ArrStack vStemHintArray; - CF2_HintMask hintMask; /* ptr to the current mask */ - CF2_Fixed hintOriginY; /* copy of current origin */ - const CF2_BluesRec* blues; - - CF2_Fixed xOffset; /* character space offsets */ - CF2_Fixed yOffset; - - /* character space miter limit threshold */ - CF2_Fixed miterLimit; - /* vertical/horzizontal snap distance in character space */ - CF2_Fixed snapThreshold; - - FT_Vector offsetStart0; /* first and second points of first */ - FT_Vector offsetStart1; /* element with offset applied */ - - /* current point, character space, before offset */ - FT_Vector currentCS; - /* current point, device space */ - FT_Vector currentDS; - FT_Vector start; /* start point of subpath */ - - /* the following members constitute the `queue' of one element */ - FT_Bool elemIsQueued; - CF2_Int prevElemOp; - - FT_Vector prevElemP0; - FT_Vector prevElemP1; - FT_Vector prevElemP2; - FT_Vector prevElemP3; - - } CF2_GlyphPathRec, *CF2_GlyphPath; - - - FT_LOCAL( void ) - cf2_glyphpath_init( CF2_GlyphPath glyphpath, - CF2_Font font, - CF2_OutlineCallbacks callbacks, - CF2_Fixed scaleY, - /* CF2_Fixed hShift, */ - CF2_ArrStack hStemHintArray, - CF2_ArrStack vStemHintArray, - CF2_HintMask hintMask, - CF2_Fixed hintOrigin, - const CF2_Blues blues, - const FT_Vector* fractionalTranslation ); - FT_LOCAL( void ) - cf2_glyphpath_finalize( CF2_GlyphPath glyphpath ); - - FT_LOCAL( void ) - cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, - CF2_Fixed x, - CF2_Fixed y ); - FT_LOCAL( void ) - cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath, - CF2_Fixed x, - CF2_Fixed y ); - FT_LOCAL( void ) - cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath, - CF2_Fixed x1, - CF2_Fixed y1, - CF2_Fixed x2, - CF2_Fixed y2, - CF2_Fixed x3, - CF2_Fixed y3 ); - FT_LOCAL( void ) - cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath ); - - -FT_END_HEADER - - -#endif /* __CF2HINTS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2intrp.c b/drivers/freetype/freetype/src/cff/cf2intrp.c deleted file mode 100644 index 5610917cc3..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2intrp.c +++ /dev/null @@ -1,1538 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2intrp.c */ -/* */ -/* Adobe's CFF Interpreter (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" -#include FT_INTERNAL_DEBUG_H - -#include "cf2glue.h" -#include "cf2font.h" -#include "cf2stack.h" -#include "cf2hints.h" - -#include "cf2error.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_cf2interp - - - /* some operators are not implemented yet */ -#define CF2_FIXME FT_TRACE4(( "cf2_interpT2CharString:" \ - " operator not implemented yet\n" )) - - - - FT_LOCAL_DEF( void ) - cf2_hintmask_init( CF2_HintMask hintmask, - FT_Error* error ) - { - FT_ZERO( hintmask ); - - hintmask->error = error; - } - - - FT_LOCAL_DEF( FT_Bool ) - cf2_hintmask_isValid( const CF2_HintMask hintmask ) - { - return hintmask->isValid; - } - - - FT_LOCAL_DEF( FT_Bool ) - cf2_hintmask_isNew( const CF2_HintMask hintmask ) - { - return hintmask->isNew; - } - - - FT_LOCAL_DEF( void ) - cf2_hintmask_setNew( CF2_HintMask hintmask, - FT_Bool val ) - { - hintmask->isNew = val; - } - - - /* clients call `getMaskPtr' in order to iterate */ - /* through hint mask */ - - FT_LOCAL_DEF( FT_Byte* ) - cf2_hintmask_getMaskPtr( CF2_HintMask hintmask ) - { - return hintmask->mask; - } - - - static size_t - cf2_hintmask_setCounts( CF2_HintMask hintmask, - size_t bitCount ) - { - if ( bitCount > CF2_MAX_HINTS ) - { - /* total of h and v stems must be <= 96 */ - CF2_SET_ERROR( hintmask->error, Invalid_Glyph_Format ); - return 0; - } - - hintmask->bitCount = bitCount; - hintmask->byteCount = ( hintmask->bitCount + 7 ) / 8; - - hintmask->isValid = TRUE; - hintmask->isNew = TRUE; - - return bitCount; - } - - - /* consume the hintmask bytes from the charstring, advancing the src */ - /* pointer */ - static void - cf2_hintmask_read( CF2_HintMask hintmask, - CF2_Buffer charstring, - size_t bitCount ) - { - size_t i; - -#ifndef CF2_NDEBUG - /* these are the bits in the final mask byte that should be zero */ - /* Note: this variable is only used in an assert expression below */ - /* and then only if CF2_NDEBUG is not defined */ - CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1; -#endif - - - /* initialize counts and isValid */ - if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 ) - return; - - FT_ASSERT( hintmask->byteCount > 0 ); - - FT_TRACE4(( " (maskbytes:" )); - - /* set mask and advance interpreter's charstring pointer */ - for ( i = 0; i < hintmask->byteCount; i++ ) - { - hintmask->mask[i] = (FT_Byte)cf2_buf_readByte( charstring ); - FT_TRACE4(( " 0x%02X", hintmask->mask[i] )); - } - - FT_TRACE4(( ")\n" )); - - /* assert any unused bits in last byte are zero unless there's a prior */ - /* error */ - /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */ -#ifndef CF2_NDEBUG - FT_ASSERT( ( hintmask->mask[hintmask->byteCount - 1] & mask ) == 0 || - *hintmask->error ); -#endif - } - - - FT_LOCAL_DEF( void ) - cf2_hintmask_setAll( CF2_HintMask hintmask, - size_t bitCount ) - { - size_t i; - CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1; - - - /* initialize counts and isValid */ - if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 ) - return; - - FT_ASSERT( hintmask->byteCount > 0 ); - FT_ASSERT( hintmask->byteCount < - sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) ); - - /* set mask to all ones */ - for ( i = 0; i < hintmask->byteCount; i++ ) - hintmask->mask[i] = 0xFF; - - /* clear unused bits */ - /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */ - hintmask->mask[hintmask->byteCount - 1] &= ~mask; - } - - - /* Type2 charstring opcodes */ - enum - { - cf2_cmdRESERVED_0, /* 0 */ - cf2_cmdHSTEM, /* 1 */ - cf2_cmdRESERVED_2, /* 2 */ - cf2_cmdVSTEM, /* 3 */ - cf2_cmdVMOVETO, /* 4 */ - cf2_cmdRLINETO, /* 5 */ - cf2_cmdHLINETO, /* 6 */ - cf2_cmdVLINETO, /* 7 */ - cf2_cmdRRCURVETO, /* 8 */ - cf2_cmdRESERVED_9, /* 9 */ - cf2_cmdCALLSUBR, /* 10 */ - cf2_cmdRETURN, /* 11 */ - cf2_cmdESC, /* 12 */ - cf2_cmdRESERVED_13, /* 13 */ - cf2_cmdENDCHAR, /* 14 */ - cf2_cmdRESERVED_15, /* 15 */ - cf2_cmdRESERVED_16, /* 16 */ - cf2_cmdRESERVED_17, /* 17 */ - cf2_cmdHSTEMHM, /* 18 */ - cf2_cmdHINTMASK, /* 19 */ - cf2_cmdCNTRMASK, /* 20 */ - cf2_cmdRMOVETO, /* 21 */ - cf2_cmdHMOVETO, /* 22 */ - cf2_cmdVSTEMHM, /* 23 */ - cf2_cmdRCURVELINE, /* 24 */ - cf2_cmdRLINECURVE, /* 25 */ - cf2_cmdVVCURVETO, /* 26 */ - cf2_cmdHHCURVETO, /* 27 */ - cf2_cmdEXTENDEDNMBR, /* 28 */ - cf2_cmdCALLGSUBR, /* 29 */ - cf2_cmdVHCURVETO, /* 30 */ - cf2_cmdHVCURVETO /* 31 */ - }; - - enum - { - cf2_escDOTSECTION, /* 0 */ - cf2_escRESERVED_1, /* 1 */ - cf2_escRESERVED_2, /* 2 */ - cf2_escAND, /* 3 */ - cf2_escOR, /* 4 */ - cf2_escNOT, /* 5 */ - cf2_escRESERVED_6, /* 6 */ - cf2_escRESERVED_7, /* 7 */ - cf2_escRESERVED_8, /* 8 */ - cf2_escABS, /* 9 */ - cf2_escADD, /* 10 like otherADD */ - cf2_escSUB, /* 11 like otherSUB */ - cf2_escDIV, /* 12 */ - cf2_escRESERVED_13, /* 13 */ - cf2_escNEG, /* 14 */ - cf2_escEQ, /* 15 */ - cf2_escRESERVED_16, /* 16 */ - cf2_escRESERVED_17, /* 17 */ - cf2_escDROP, /* 18 */ - cf2_escRESERVED_19, /* 19 */ - cf2_escPUT, /* 20 like otherPUT */ - cf2_escGET, /* 21 like otherGET */ - cf2_escIFELSE, /* 22 like otherIFELSE */ - cf2_escRANDOM, /* 23 like otherRANDOM */ - cf2_escMUL, /* 24 like otherMUL */ - cf2_escRESERVED_25, /* 25 */ - cf2_escSQRT, /* 26 */ - cf2_escDUP, /* 27 like otherDUP */ - cf2_escEXCH, /* 28 like otherEXCH */ - cf2_escINDEX, /* 29 */ - cf2_escROLL, /* 30 */ - cf2_escRESERVED_31, /* 31 */ - cf2_escRESERVED_32, /* 32 */ - cf2_escRESERVED_33, /* 33 */ - cf2_escHFLEX, /* 34 */ - cf2_escFLEX, /* 35 */ - cf2_escHFLEX1, /* 36 */ - cf2_escFLEX1 /* 37 */ - }; - - - /* `stemHintArray' does not change once we start drawing the outline. */ - static void - cf2_doStems( const CF2_Font font, - CF2_Stack opStack, - CF2_ArrStack stemHintArray, - CF2_Fixed* width, - FT_Bool* haveWidth, - CF2_Fixed hintOffset ) - { - CF2_UInt i; - CF2_UInt count = cf2_stack_count( opStack ); - FT_Bool hasWidthArg = (FT_Bool)( count & 1 ); - - /* variable accumulates delta values from operand stack */ - CF2_Fixed position = hintOffset; - - if ( hasWidthArg && ! *haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + - cf2_getNominalWidthX( font->decoder ); - - if ( font->decoder->width_only ) - goto exit; - - for ( i = hasWidthArg ? 1 : 0; i < count; i += 2 ) - { - /* construct a CF2_StemHint and push it onto the list */ - CF2_StemHintRec stemhint; - - - stemhint.min = - position += cf2_stack_getReal( opStack, i ); - stemhint.max = - position += cf2_stack_getReal( opStack, i + 1 ); - - stemhint.used = FALSE; - stemhint.maxDS = - stemhint.minDS = 0; - - cf2_arrstack_push( stemHintArray, &stemhint ); /* defer error check */ - } - - cf2_stack_clear( opStack ); - - exit: - /* cf2_doStems must define a width (may be default) */ - *haveWidth = TRUE; - } - - - static void - cf2_doFlex( CF2_Stack opStack, - CF2_Fixed* curX, - CF2_Fixed* curY, - CF2_GlyphPath glyphPath, - const FT_Bool* readFromStack, - FT_Bool doConditionalLastRead ) - { - CF2_Fixed vals[14]; - CF2_UInt index; - FT_Bool isHFlex; - CF2_Int top, i, j; - - - vals[0] = *curX; - vals[1] = *curY; - index = 0; - isHFlex = readFromStack[9] == FALSE; - top = isHFlex ? 9 : 10; - - for ( i = 0; i < top; i++ ) - { - vals[i + 2] = vals[i]; - if ( readFromStack[i] ) - vals[i + 2] += cf2_stack_getReal( opStack, index++ ); - } - - if ( isHFlex ) - vals[9 + 2] = *curY; - - if ( doConditionalLastRead ) - { - FT_Bool lastIsX = (FT_Bool)( cf2_fixedAbs( vals[10] - *curX ) > - cf2_fixedAbs( vals[11] - *curY ) ); - CF2_Fixed lastVal = cf2_stack_getReal( opStack, index ); - - - if ( lastIsX ) - { - vals[12] = vals[10] + lastVal; - vals[13] = *curY; - } - else - { - vals[12] = *curX; - vals[13] = vals[11] + lastVal; - } - } - else - { - if ( readFromStack[10] ) - vals[12] = vals[10] + cf2_stack_getReal( opStack, index++ ); - else - vals[12] = *curX; - - if ( readFromStack[11] ) - vals[13] = vals[11] + cf2_stack_getReal( opStack, index ); - else - vals[13] = *curY; - } - - for ( j = 0; j < 2; j++ ) - cf2_glyphpath_curveTo( glyphPath, vals[j * 6 + 2], - vals[j * 6 + 3], - vals[j * 6 + 4], - vals[j * 6 + 5], - vals[j * 6 + 6], - vals[j * 6 + 7] ); - - cf2_stack_clear( opStack ); - - *curX = vals[12]; - *curY = vals[13]; - } - - - /* - * `error' is a shared error code used by many objects in this - * routine. Before the code continues from an error, it must check and - * record the error in `*error'. The idea is that this shared - * error code will record the first error encountered. If testing - * for an error anyway, the cost of `goto exit' is small, so we do it, - * even if continuing would be safe. In this case, `lastError' is - * set, so the testing and storing can be done in one place, at `exit'. - * - * Continuing after an error is intended for objects which do their own - * testing of `*error', e.g., array stack functions. This allows us to - * avoid an extra test after the call. - * - * Unimplemented opcodes are ignored. - * - */ - FT_LOCAL_DEF( void ) - cf2_interpT2CharString( CF2_Font font, - CF2_Buffer buf, - CF2_OutlineCallbacks callbacks, - const FT_Vector* translation, - FT_Bool doingSeac, - CF2_Fixed curX, - CF2_Fixed curY, - CF2_Fixed* width ) - { - /* lastError is used for errors that are immediately tested */ - FT_Error lastError = FT_Err_Ok; - - /* pointer to parsed font object */ - CFF_Decoder* decoder = font->decoder; - - FT_Error* error = &font->error; - FT_Memory memory = font->memory; - - CF2_Fixed scaleY = font->innerTransform.d; - CF2_Fixed nominalWidthX = cf2_getNominalWidthX( decoder ); - - /* save this for hinting seac accents */ - CF2_Fixed hintOriginY = curY; - - CF2_Stack opStack = NULL; - FT_Byte op1; /* first opcode byte */ - - /* instruction limit; 20,000,000 matches Avalon */ - FT_UInt32 instructionLimit = 20000000UL; - - CF2_ArrStackRec subrStack; - - FT_Bool haveWidth; - CF2_Buffer charstring = NULL; - - CF2_Int charstringIndex = -1; /* initialize to empty */ - - /* TODO: placeholders for hint structures */ - - /* objects used for hinting */ - CF2_ArrStackRec hStemHintArray; - CF2_ArrStackRec vStemHintArray; - - CF2_HintMaskRec hintMask; - CF2_GlyphPathRec glyphPath; - - - /* initialize the remaining objects */ - cf2_arrstack_init( &subrStack, - memory, - error, - sizeof ( CF2_BufferRec ) ); - cf2_arrstack_init( &hStemHintArray, - memory, - error, - sizeof ( CF2_StemHintRec ) ); - cf2_arrstack_init( &vStemHintArray, - memory, - error, - sizeof ( CF2_StemHintRec ) ); - - /* initialize CF2_StemHint arrays */ - cf2_hintmask_init( &hintMask, error ); - - /* initialize path map to manage drawing operations */ - - /* Note: last 4 params are used to handle `MoveToPermissive', which */ - /* may need to call `hintMap.Build' */ - /* TODO: MoveToPermissive is gone; are these still needed? */ - cf2_glyphpath_init( &glyphPath, - font, - callbacks, - scaleY, - /* hShift, */ - &hStemHintArray, - &vStemHintArray, - &hintMask, - hintOriginY, - &font->blues, - translation ); - - /* - * Initialize state for width parsing. From the CFF Spec: - * - * The first stack-clearing operator, which must be one of hstem, - * hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, - * rmoveto, or endchar, takes an additional argument - the width (as - * described earlier), which may be expressed as zero or one numeric - * argument. - * - * What we implement here uses the first validly specified width, but - * does not detect errors for specifying more than one width. - * - * If one of the above operators occurs without explicitly specifying - * a width, we assume the default width. - * - */ - haveWidth = FALSE; - *width = cf2_getDefaultWidthX( decoder ); - - /* - * Note: at this point, all pointers to resources must be NULL - * and all local objects must be initialized. - * There must be no branches to exit: above this point. - * - */ - - /* allocate an operand stack */ - opStack = cf2_stack_init( memory, error ); - if ( !opStack ) - { - lastError = FT_THROW( Out_Of_Memory ); - goto exit; - } - - /* initialize subroutine stack by placing top level charstring as */ - /* first element (max depth plus one for the charstring) */ - /* Note: Caller owns and must finalize the first charstring. */ - /* Our copy of it does not change that requirement. */ - cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 ); - - charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack ); - *charstring = *buf; /* structure copy */ - - charstringIndex = 0; /* entry is valid now */ - - /* catch errors so far */ - if ( *error ) - goto exit; - - /* main interpreter loop */ - while ( 1 ) - { - if ( cf2_buf_isEnd( charstring ) ) - { - /* If we've reached the end of the charstring, simulate a */ - /* cf2_cmdRETURN or cf2_cmdENDCHAR. */ - if ( charstringIndex ) - op1 = cf2_cmdRETURN; /* end of buffer for subroutine */ - else - op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */ - } - else - op1 = (FT_Byte)cf2_buf_readByte( charstring ); - - /* check for errors once per loop */ - if ( *error ) - goto exit; - - instructionLimit--; - if ( instructionLimit == 0 ) - { - lastError = FT_THROW( Invalid_Glyph_Format ); - goto exit; - } - - switch( op1 ) - { - case cf2_cmdRESERVED_0: - case cf2_cmdRESERVED_2: - case cf2_cmdRESERVED_9: - case cf2_cmdRESERVED_13: - case cf2_cmdRESERVED_15: - case cf2_cmdRESERVED_16: - case cf2_cmdRESERVED_17: - /* we may get here if we have a prior error */ - FT_TRACE4(( " unknown op (%d)\n", op1 )); - break; - - case cf2_cmdHSTEMHM: - case cf2_cmdHSTEM: - FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" )); - - /* never add hints after the mask is computed */ - if ( cf2_hintmask_isValid( &hintMask ) ) - FT_TRACE4(( "cf2_interpT2CharString:" - " invalid horizontal hint mask\n" )); - - cf2_doStems( font, - opStack, - &hStemHintArray, - width, - &haveWidth, - 0 ); - - if ( font->decoder->width_only ) - goto exit; - - break; - - case cf2_cmdVSTEMHM: - case cf2_cmdVSTEM: - FT_TRACE4(( op1 == cf2_cmdVSTEMHM ? " vstemhm\n" : " vstem\n" )); - - /* never add hints after the mask is computed */ - if ( cf2_hintmask_isValid( &hintMask ) ) - FT_TRACE4(( "cf2_interpT2CharString:" - " invalid vertical hint mask\n" )); - - cf2_doStems( font, - opStack, - &vStemHintArray, - width, - &haveWidth, - 0 ); - - if ( font->decoder->width_only ) - goto exit; - - break; - - case cf2_cmdVMOVETO: - FT_TRACE4(( " vmoveto\n" )); - - if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; - - /* width is defined or default after this */ - haveWidth = TRUE; - - if ( font->decoder->width_only ) - goto exit; - - curY += cf2_stack_popFixed( opStack ); - - cf2_glyphpath_moveTo( &glyphPath, curX, curY ); - - break; - - case cf2_cmdRLINETO: - { - CF2_UInt index; - CF2_UInt count = cf2_stack_count( opStack ); - - - FT_TRACE4(( " rlineto\n" )); - - for ( index = 0; index < count; index += 2 ) - { - curX += cf2_stack_getReal( opStack, index + 0 ); - curY += cf2_stack_getReal( opStack, index + 1 ); - - cf2_glyphpath_lineTo( &glyphPath, curX, curY ); - } - - cf2_stack_clear( opStack ); - } - continue; /* no need to clear stack again */ - - case cf2_cmdHLINETO: - case cf2_cmdVLINETO: - { - CF2_UInt index; - CF2_UInt count = cf2_stack_count( opStack ); - - FT_Bool isX = op1 == cf2_cmdHLINETO; - - - FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" )); - - for ( index = 0; index < count; index++ ) - { - CF2_Fixed v = cf2_stack_getReal( opStack, index ); - - - if ( isX ) - curX += v; - else - curY += v; - - isX = !isX; - - cf2_glyphpath_lineTo( &glyphPath, curX, curY ); - } - - cf2_stack_clear( opStack ); - } - continue; - - case cf2_cmdRCURVELINE: - case cf2_cmdRRCURVETO: - { - CF2_UInt count = cf2_stack_count( opStack ); - CF2_UInt index = 0; - - - FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n" - : " rrcurveto\n" )); - - while ( index + 6 <= count ) - { - CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; - CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY; - CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1; - CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1; - CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; - CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2; - - - cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); - - curX = x3; - curY = y3; - index += 6; - } - - if ( op1 == cf2_cmdRCURVELINE ) - { - curX += cf2_stack_getReal( opStack, index + 0 ); - curY += cf2_stack_getReal( opStack, index + 1 ); - - cf2_glyphpath_lineTo( &glyphPath, curX, curY ); - } - - cf2_stack_clear( opStack ); - } - continue; /* no need to clear stack again */ - - case cf2_cmdCALLGSUBR: - case cf2_cmdCALLSUBR: - { - CF2_UInt subrIndex; - - - FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr" - : " callsubr" )); - - if ( charstringIndex > CF2_MAX_SUBR ) - { - /* max subr plus one for charstring */ - lastError = FT_THROW( Invalid_Glyph_Format ); - goto exit; /* overflow of stack */ - } - - /* push our current CFF charstring region on subrStack */ - charstring = (CF2_Buffer) - cf2_arrstack_getPointer( &subrStack, - charstringIndex + 1 ); - - /* set up the new CFF region and pointer */ - subrIndex = cf2_stack_popInt( opStack ); - - switch ( op1 ) - { - case cf2_cmdCALLGSUBR: - FT_TRACE4(( "(%d)\n", subrIndex + decoder->globals_bias )); - - if ( cf2_initGlobalRegionBuffer( decoder, - subrIndex, - charstring ) ) - { - lastError = FT_THROW( Invalid_Glyph_Format ); - goto exit; /* subroutine lookup or stream error */ - } - break; - - default: - /* cf2_cmdCALLSUBR */ - FT_TRACE4(( "(%d)\n", subrIndex + decoder->locals_bias )); - - if ( cf2_initLocalRegionBuffer( decoder, - subrIndex, - charstring ) ) - { - lastError = FT_THROW( Invalid_Glyph_Format ); - goto exit; /* subroutine lookup or stream error */ - } - } - - charstringIndex += 1; /* entry is valid now */ - } - continue; /* do not clear the stack */ - - case cf2_cmdRETURN: - FT_TRACE4(( " return\n" )); - - if ( charstringIndex < 1 ) - { - /* Note: cannot return from top charstring */ - lastError = FT_THROW( Invalid_Glyph_Format ); - goto exit; /* underflow of stack */ - } - - /* restore position in previous charstring */ - charstring = (CF2_Buffer) - cf2_arrstack_getPointer( &subrStack, - --charstringIndex ); - continue; /* do not clear the stack */ - - case cf2_cmdESC: - { - FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring ); - - - switch ( op2 ) - { - case cf2_escDOTSECTION: - /* something about `flip type of locking' -- ignore it */ - FT_TRACE4(( " dotsection\n" )); - - break; - - /* TODO: should these operators be supported? */ - case cf2_escAND: /* in spec */ - FT_TRACE4(( " and\n" )); - - CF2_FIXME; - break; - - case cf2_escOR: /* in spec */ - FT_TRACE4(( " or\n" )); - - CF2_FIXME; - break; - - case cf2_escNOT: /* in spec */ - FT_TRACE4(( " not\n" )); - - CF2_FIXME; - break; - - case cf2_escABS: /* in spec */ - FT_TRACE4(( " abs\n" )); - - CF2_FIXME; - break; - - case cf2_escADD: /* in spec */ - FT_TRACE4(( " add\n" )); - - CF2_FIXME; - break; - - case cf2_escSUB: /* in spec */ - FT_TRACE4(( " sub\n" )); - - CF2_FIXME; - break; - - case cf2_escDIV: /* in spec */ - FT_TRACE4(( " div\n" )); - - CF2_FIXME; - break; - - case cf2_escNEG: /* in spec */ - FT_TRACE4(( " neg\n" )); - - CF2_FIXME; - break; - - case cf2_escEQ: /* in spec */ - FT_TRACE4(( " eq\n" )); - - CF2_FIXME; - break; - - case cf2_escDROP: /* in spec */ - FT_TRACE4(( " drop\n" )); - - CF2_FIXME; - break; - - case cf2_escPUT: /* in spec */ - FT_TRACE4(( " put\n" )); - - CF2_FIXME; - break; - - case cf2_escGET: /* in spec */ - FT_TRACE4(( " get\n" )); - - CF2_FIXME; - break; - - case cf2_escIFELSE: /* in spec */ - FT_TRACE4(( " ifelse\n" )); - - CF2_FIXME; - break; - - case cf2_escRANDOM: /* in spec */ - FT_TRACE4(( " random\n" )); - - CF2_FIXME; - break; - - case cf2_escMUL: /* in spec */ - FT_TRACE4(( " mul\n" )); - - CF2_FIXME; - break; - - case cf2_escSQRT: /* in spec */ - FT_TRACE4(( " sqrt\n" )); - - CF2_FIXME; - break; - - case cf2_escDUP: /* in spec */ - FT_TRACE4(( " dup\n" )); - - CF2_FIXME; - break; - - case cf2_escEXCH: /* in spec */ - FT_TRACE4(( " exch\n" )); - - CF2_FIXME; - break; - - case cf2_escINDEX: /* in spec */ - FT_TRACE4(( " index\n" )); - - CF2_FIXME; - break; - - case cf2_escROLL: /* in spec */ - FT_TRACE4(( " roll\n" )); - - CF2_FIXME; - break; - - case cf2_escHFLEX: - { - static const FT_Bool readFromStack[12] = - { - TRUE /* dx1 */, FALSE /* dy1 */, - TRUE /* dx2 */, TRUE /* dy2 */, - TRUE /* dx3 */, FALSE /* dy3 */, - TRUE /* dx4 */, FALSE /* dy4 */, - TRUE /* dx5 */, FALSE /* dy5 */, - TRUE /* dx6 */, FALSE /* dy6 */ - }; - - - FT_TRACE4(( " hflex\n" )); - - cf2_doFlex( opStack, - &curX, - &curY, - &glyphPath, - readFromStack, - FALSE /* doConditionalLastRead */ ); - } - continue; - - case cf2_escFLEX: - { - static const FT_Bool readFromStack[12] = - { - TRUE /* dx1 */, TRUE /* dy1 */, - TRUE /* dx2 */, TRUE /* dy2 */, - TRUE /* dx3 */, TRUE /* dy3 */, - TRUE /* dx4 */, TRUE /* dy4 */, - TRUE /* dx5 */, TRUE /* dy5 */, - TRUE /* dx6 */, TRUE /* dy6 */ - }; - - - FT_TRACE4(( " flex\n" )); - - cf2_doFlex( opStack, - &curX, - &curY, - &glyphPath, - readFromStack, - FALSE /* doConditionalLastRead */ ); - } - break; /* TODO: why is this not a continue? */ - - case cf2_escHFLEX1: - { - static const FT_Bool readFromStack[12] = - { - TRUE /* dx1 */, TRUE /* dy1 */, - TRUE /* dx2 */, TRUE /* dy2 */, - TRUE /* dx3 */, FALSE /* dy3 */, - TRUE /* dx4 */, FALSE /* dy4 */, - TRUE /* dx5 */, TRUE /* dy5 */, - TRUE /* dx6 */, FALSE /* dy6 */ - }; - - - FT_TRACE4(( " hflex1\n" )); - - cf2_doFlex( opStack, - &curX, - &curY, - &glyphPath, - readFromStack, - FALSE /* doConditionalLastRead */ ); - } - continue; - - case cf2_escFLEX1: - { - static const FT_Bool readFromStack[12] = - { - TRUE /* dx1 */, TRUE /* dy1 */, - TRUE /* dx2 */, TRUE /* dy2 */, - TRUE /* dx3 */, TRUE /* dy3 */, - TRUE /* dx4 */, TRUE /* dy4 */, - TRUE /* dx5 */, TRUE /* dy5 */, - FALSE /* dx6 */, FALSE /* dy6 */ - }; - - - FT_TRACE4(( " flex1\n" )); - - cf2_doFlex( opStack, - &curX, - &curY, - &glyphPath, - readFromStack, - TRUE /* doConditionalLastRead */ ); - } - continue; - - case cf2_escRESERVED_1: - case cf2_escRESERVED_2: - case cf2_escRESERVED_6: - case cf2_escRESERVED_7: - case cf2_escRESERVED_8: - case cf2_escRESERVED_13: - case cf2_escRESERVED_16: - case cf2_escRESERVED_17: - case cf2_escRESERVED_19: - case cf2_escRESERVED_25: - case cf2_escRESERVED_31: - case cf2_escRESERVED_32: - case cf2_escRESERVED_33: - default: - FT_TRACE4(( " unknown op (12, %d)\n", op2 )); - - }; /* end of switch statement checking `op2' */ - - } /* case cf2_cmdESC */ - break; - - case cf2_cmdENDCHAR: - FT_TRACE4(( " endchar\n" )); - - if ( cf2_stack_count( opStack ) == 1 || - cf2_stack_count( opStack ) == 5 ) - { - if ( !haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; - } - - /* width is defined or default after this */ - haveWidth = TRUE; - - if ( font->decoder->width_only ) - goto exit; - - /* close path if still open */ - cf2_glyphpath_closeOpenPath( &glyphPath ); - - if ( cf2_stack_count( opStack ) > 1 ) - { - /* must be either 4 or 5 -- */ - /* this is a (deprecated) implied `seac' operator */ - - CF2_UInt achar; - CF2_UInt bchar; - CF2_BufferRec component; - CF2_Fixed dummyWidth; /* ignore component width */ - FT_Error error2; - - - if ( doingSeac ) - { - lastError = FT_THROW( Invalid_Glyph_Format ); - goto exit; /* nested seac */ - } - - achar = cf2_stack_popInt( opStack ); - bchar = cf2_stack_popInt( opStack ); - - curY = cf2_stack_popFixed( opStack ); - curX = cf2_stack_popFixed( opStack ); - - error2 = cf2_getSeacComponent( decoder, achar, &component ); - if ( error2 ) - { - lastError = error2; /* pass FreeType error through */ - goto exit; - } - cf2_interpT2CharString( font, - &component, - callbacks, - translation, - TRUE, - curX, - curY, - &dummyWidth ); - cf2_freeSeacComponent( decoder, &component ); - - error2 = cf2_getSeacComponent( decoder, bchar, &component ); - if ( error2 ) - { - lastError = error2; /* pass FreeType error through */ - goto exit; - } - cf2_interpT2CharString( font, - &component, - callbacks, - translation, - TRUE, - 0, - 0, - &dummyWidth ); - cf2_freeSeacComponent( decoder, &component ); - } - goto exit; - - case cf2_cmdCNTRMASK: - case cf2_cmdHINTMASK: - /* the final \n in the tracing message gets added in */ - /* `cf2_hintmask_read' (which also traces the mask bytes) */ - FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" )); - - /* if there are arguments on the stack, there this is an */ - /* implied cf2_cmdVSTEMHM */ - if ( cf2_stack_count( opStack ) != 0 ) - { - /* never add hints after the mask is computed */ - if ( cf2_hintmask_isValid( &hintMask ) ) - FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" )); - } - - cf2_doStems( font, - opStack, - &vStemHintArray, - width, - &haveWidth, - 0 ); - - if ( font->decoder->width_only ) - goto exit; - - if ( op1 == cf2_cmdHINTMASK ) - { - /* consume the hint mask bytes which follow the operator */ - cf2_hintmask_read( &hintMask, - charstring, - cf2_arrstack_size( &hStemHintArray ) + - cf2_arrstack_size( &vStemHintArray ) ); - } - else - { - /* - * Consume the counter mask bytes which follow the operator: - * Build a temporary hint map, just to place and lock those - * stems participating in the counter mask. These are most - * likely the dominant hstems, and are grouped together in a - * few counter groups, not necessarily in correspondence - * with the hint groups. This reduces the chances of - * conflicts between hstems that are initially placed in - * separate hint groups and then brought together. The - * positions are copied back to `hStemHintArray', so we can - * discard `counterMask' and `counterHintMap'. - * - */ - CF2_HintMapRec counterHintMap; - CF2_HintMaskRec counterMask; - - - cf2_hintmap_init( &counterHintMap, - font, - &glyphPath.initialHintMap, - &glyphPath.hintMoves, - scaleY ); - cf2_hintmask_init( &counterMask, error ); - - cf2_hintmask_read( &counterMask, - charstring, - cf2_arrstack_size( &hStemHintArray ) + - cf2_arrstack_size( &vStemHintArray ) ); - cf2_hintmap_build( &counterHintMap, - &hStemHintArray, - &vStemHintArray, - &counterMask, - 0, - FALSE ); - } - break; - - case cf2_cmdRMOVETO: - FT_TRACE4(( " rmoveto\n" )); - - if ( cf2_stack_count( opStack ) > 2 && !haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; - - /* width is defined or default after this */ - haveWidth = TRUE; - - if ( font->decoder->width_only ) - goto exit; - - curY += cf2_stack_popFixed( opStack ); - curX += cf2_stack_popFixed( opStack ); - - cf2_glyphpath_moveTo( &glyphPath, curX, curY ); - - break; - - case cf2_cmdHMOVETO: - FT_TRACE4(( " hmoveto\n" )); - - if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) - *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; - - /* width is defined or default after this */ - haveWidth = TRUE; - - if ( font->decoder->width_only ) - goto exit; - - curX += cf2_stack_popFixed( opStack ); - - cf2_glyphpath_moveTo( &glyphPath, curX, curY ); - - break; - - case cf2_cmdRLINECURVE: - { - CF2_UInt count = cf2_stack_count( opStack ); - CF2_UInt index = 0; - - - FT_TRACE4(( " rlinecurve\n" )); - - while ( index + 6 < count ) - { - curX += cf2_stack_getReal( opStack, index + 0 ); - curY += cf2_stack_getReal( opStack, index + 1 ); - - cf2_glyphpath_lineTo( &glyphPath, curX, curY ); - index += 2; - } - - while ( index < count ) - { - CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; - CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY; - CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1; - CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1; - CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; - CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2; - - - cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); - - curX = x3; - curY = y3; - index += 6; - } - - cf2_stack_clear( opStack ); - } - continue; /* no need to clear stack again */ - - case cf2_cmdVVCURVETO: - { - CF2_UInt count = cf2_stack_count( opStack ); - CF2_UInt index = 0; - - - FT_TRACE4(( " vvcurveto\n" )); - - while ( index < count ) - { - CF2_Fixed x1, y1, x2, y2, x3, y3; - - - if ( ( count - index ) & 1 ) - { - x1 = cf2_stack_getReal( opStack, index ) + curX; - - ++index; - } - else - x1 = curX; - - y1 = cf2_stack_getReal( opStack, index + 0 ) + curY; - x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; - y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; - x3 = x2; - y3 = cf2_stack_getReal( opStack, index + 3 ) + y2; - - cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); - - curX = x3; - curY = y3; - index += 4; - } - - cf2_stack_clear( opStack ); - } - continue; /* no need to clear stack again */ - - case cf2_cmdHHCURVETO: - { - CF2_UInt count = cf2_stack_count( opStack ); - CF2_UInt index = 0; - - - FT_TRACE4(( " hhcurveto\n" )); - - while ( index < count ) - { - CF2_Fixed x1, y1, x2, y2, x3, y3; - - - if ( ( count - index ) & 1 ) - { - y1 = cf2_stack_getReal( opStack, index ) + curY; - - ++index; - } - else - y1 = curY; - - x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; - x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; - y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; - x3 = cf2_stack_getReal( opStack, index + 3 ) + x2; - y3 = y2; - - cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); - - curX = x3; - curY = y3; - index += 4; - } - - cf2_stack_clear( opStack ); - } - continue; /* no need to clear stack again */ - - case cf2_cmdVHCURVETO: - case cf2_cmdHVCURVETO: - { - CF2_UInt count = cf2_stack_count( opStack ); - CF2_UInt index = 0; - - FT_Bool alternate = op1 == cf2_cmdHVCURVETO; - - - FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" )); - - while ( index < count ) - { - CF2_Fixed x1, x2, x3, y1, y2, y3; - - - if ( alternate ) - { - x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; - y1 = curY; - x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; - y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; - y3 = cf2_stack_getReal( opStack, index + 3 ) + y2; - - if ( count - index == 5 ) - { - x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; - - ++index; - } - else - x3 = x2; - - alternate = FALSE; - } - else - { - x1 = curX; - y1 = cf2_stack_getReal( opStack, index + 0 ) + curY; - x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; - y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; - x3 = cf2_stack_getReal( opStack, index + 3 ) + x2; - - if ( count - index == 5 ) - { - y3 = cf2_stack_getReal( opStack, index + 4 ) + y2; - - ++index; - } - else - y3 = y2; - - alternate = TRUE; - } - - cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); - - curX = x3; - curY = y3; - index += 4; - } - - cf2_stack_clear( opStack ); - } - continue; /* no need to clear stack again */ - - case cf2_cmdEXTENDEDNMBR: - { - CF2_Int v; - - - v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) | - cf2_buf_readByte( charstring ) ); - - FT_TRACE4(( " %d", v )); - - cf2_stack_pushInt( opStack, v ); - } - continue; - - default: - /* numbers */ - { - if ( /* op1 >= 32 && */ op1 <= 246 ) - { - CF2_Int v; - - - v = op1 - 139; - - FT_TRACE4(( " %d", v )); - - /* -107 .. 107 */ - cf2_stack_pushInt( opStack, v ); - } - - else if ( /* op1 >= 247 && */ op1 <= 250 ) - { - CF2_Int v; - - - v = op1; - v -= 247; - v *= 256; - v += cf2_buf_readByte( charstring ); - v += 108; - - FT_TRACE4(( " %d", v )); - - /* 108 .. 1131 */ - cf2_stack_pushInt( opStack, v ); - } - - else if ( /* op1 >= 251 && */ op1 <= 254 ) - { - CF2_Int v; - - - v = op1; - v -= 251; - v *= 256; - v += cf2_buf_readByte( charstring ); - v = -v - 108; - - FT_TRACE4(( " %d", v )); - - /* -1131 .. -108 */ - cf2_stack_pushInt( opStack, v ); - } - - else /* op1 == 255 */ - { - CF2_Fixed v; - - - v = (CF2_Fixed) - ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) | - ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) | - ( (FT_UInt32)cf2_buf_readByte( charstring ) << 8 ) | - (FT_UInt32)cf2_buf_readByte( charstring ) ); - - FT_TRACE4(( " %.2f", v / 65536.0 )); - - cf2_stack_pushFixed( opStack, v ); - } - } - continue; /* don't clear stack */ - - } /* end of switch statement checking `op1' */ - - cf2_stack_clear( opStack ); - - } /* end of main interpreter loop */ - - /* we get here if the charstring ends without cf2_cmdENDCHAR */ - FT_TRACE4(( "cf2_interpT2CharString:" - " charstring ends without ENDCHAR\n" )); - - exit: - /* check whether last error seen is also the first one */ - cf2_setError( error, lastError ); - - /* free resources from objects we've used */ - cf2_glyphpath_finalize( &glyphPath ); - cf2_arrstack_finalize( &vStemHintArray ); - cf2_arrstack_finalize( &hStemHintArray ); - cf2_arrstack_finalize( &subrStack ); - cf2_stack_free( opStack ); - - FT_TRACE4(( "\n" )); - - return; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2intrp.h b/drivers/freetype/freetype/src/cff/cf2intrp.h deleted file mode 100644 index b5d8947838..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2intrp.h +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2font.h */ -/* */ -/* Adobe's CFF Interpreter (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2INTRP_H__ -#define __CF2INTRP_H__ - - -#include "cf2ft.h" -#include "cf2hints.h" - - -FT_BEGIN_HEADER - - - FT_LOCAL( void ) - cf2_hintmask_init( CF2_HintMask hintmask, - FT_Error* error ); - FT_LOCAL( FT_Bool ) - cf2_hintmask_isValid( const CF2_HintMask hintmask ); - FT_LOCAL( FT_Bool ) - cf2_hintmask_isNew( const CF2_HintMask hintmask ); - FT_LOCAL( void ) - cf2_hintmask_setNew( CF2_HintMask hintmask, - FT_Bool val ); - FT_LOCAL( FT_Byte* ) - cf2_hintmask_getMaskPtr( CF2_HintMask hintmask ); - FT_LOCAL( void ) - cf2_hintmask_setAll( CF2_HintMask hintmask, - size_t bitCount ); - - FT_LOCAL( void ) - cf2_interpT2CharString( CF2_Font font, - CF2_Buffer charstring, - CF2_OutlineCallbacks callbacks, - const FT_Vector* translation, - FT_Bool doingSeac, - CF2_Fixed curX, - CF2_Fixed curY, - CF2_Fixed* width ); - - -FT_END_HEADER - - -#endif /* __CF2INTRP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2read.c b/drivers/freetype/freetype/src/cff/cf2read.c deleted file mode 100644 index 2b429e3eeb..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2read.c +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2read.c */ -/* */ -/* Adobe's code for stream handling (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" -#include FT_INTERNAL_DEBUG_H - -#include "cf2glue.h" - -#include "cf2error.h" - - - /* Define CF2_IO_FAIL as 1 to enable random errors and random */ - /* value errors in I/O. */ -#define CF2_IO_FAIL 0 - - -#if CF2_IO_FAIL - - /* set the .00 value to a nonzero probability */ - static int - randomError2( void ) - { - /* for region buffer ReadByte (interp) function */ - return (double)rand() / RAND_MAX < .00; - } - - /* set the .00 value to a nonzero probability */ - static CF2_Int - randomValue() - { - return (double)rand() / RAND_MAX < .00 ? rand() : 0; - } - -#endif /* CF2_IO_FAIL */ - - - /* Region Buffer */ - /* */ - /* Can be constructed from a copied buffer managed by */ - /* `FCM_getDatablock'. */ - /* Reads bytes with check for end of buffer. */ - - /* reading past the end of the buffer sets error and returns zero */ - FT_LOCAL_DEF( CF2_Int ) - cf2_buf_readByte( CF2_Buffer buf ) - { - if ( buf->ptr < buf->end ) - { -#if CF2_IO_FAIL - if ( randomError2() ) - { - CF2_SET_ERROR( buf->error, Invalid_Stream_Operation ); - return 0; - } - - return *(buf->ptr)++ + randomValue(); -#else - return *(buf->ptr)++; -#endif - } - else - { - CF2_SET_ERROR( buf->error, Invalid_Stream_Operation ); - return 0; - } - } - - - /* note: end condition can occur without error */ - FT_LOCAL_DEF( FT_Bool ) - cf2_buf_isEnd( CF2_Buffer buf ) - { - return (FT_Bool)( buf->ptr >= buf->end ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2read.h b/drivers/freetype/freetype/src/cff/cf2read.h deleted file mode 100644 index 7ef7c8c149..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2read.h +++ /dev/null @@ -1,68 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2read.h */ -/* */ -/* Adobe's code for stream handling (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2READ_H__ -#define __CF2READ_H__ - - -FT_BEGIN_HEADER - - - typedef struct CF2_BufferRec_ - { - FT_Error* error; - const FT_Byte* start; - const FT_Byte* end; - const FT_Byte* ptr; - - } CF2_BufferRec, *CF2_Buffer; - - - FT_LOCAL( CF2_Int ) - cf2_buf_readByte( CF2_Buffer buf ); - FT_LOCAL( FT_Bool ) - cf2_buf_isEnd( CF2_Buffer buf ); - - -FT_END_HEADER - - -#endif /* __CF2READ_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2stack.c b/drivers/freetype/freetype/src/cff/cf2stack.c deleted file mode 100644 index 8332b5d91a..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2stack.c +++ /dev/null @@ -1,205 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2stack.c */ -/* */ -/* Adobe's code for emulating a CFF stack (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#include "cf2ft.h" -#include FT_INTERNAL_DEBUG_H - -#include "cf2glue.h" -#include "cf2font.h" -#include "cf2stack.h" - -#include "cf2error.h" - - - /* Allocate and initialize an instance of CF2_Stack. */ - /* Note: This function returns NULL on error (does not set */ - /* `error'). */ - FT_LOCAL_DEF( CF2_Stack ) - cf2_stack_init( FT_Memory memory, - FT_Error* e ) - { - FT_Error error = FT_Err_Ok; /* for FT_QNEW */ - - CF2_Stack stack = NULL; - - - if ( !FT_QNEW( stack ) ) - { - /* initialize the structure; FT_QNEW zeroes it */ - stack->memory = memory; - stack->error = e; - stack->top = &stack->buffer[0]; /* empty stack */ - } - - return stack; - } - - - FT_LOCAL_DEF( void ) - cf2_stack_free( CF2_Stack stack ) - { - if ( stack ) - { - FT_Memory memory = stack->memory; - - - /* free the main structure */ - FT_FREE( stack ); - } - } - - - FT_LOCAL_DEF( CF2_UInt ) - cf2_stack_count( CF2_Stack stack ) - { - return (CF2_UInt)( stack->top - &stack->buffer[0] ); - } - - - FT_LOCAL_DEF( void ) - cf2_stack_pushInt( CF2_Stack stack, - CF2_Int val ) - { - if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) - { - CF2_SET_ERROR( stack->error, Stack_Overflow ); - return; /* stack overflow */ - } - - stack->top->u.i = val; - stack->top->type = CF2_NumberInt; - ++stack->top; - } - - - FT_LOCAL_DEF( void ) - cf2_stack_pushFixed( CF2_Stack stack, - CF2_Fixed val ) - { - if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) - { - CF2_SET_ERROR( stack->error, Stack_Overflow ); - return; /* stack overflow */ - } - - stack->top->u.r = val; - stack->top->type = CF2_NumberFixed; - ++stack->top; - } - - - /* this function is only allowed to pop an integer type */ - FT_LOCAL_DEF( CF2_Int ) - cf2_stack_popInt( CF2_Stack stack ) - { - if ( stack->top == &stack->buffer[0] ) - { - CF2_SET_ERROR( stack->error, Stack_Underflow ); - return 0; /* underflow */ - } - if ( stack->top[-1].type != CF2_NumberInt ) - { - CF2_SET_ERROR( stack->error, Syntax_Error ); - return 0; /* type mismatch */ - } - - --stack->top; - - return stack->top->u.i; - } - - - /* Note: type mismatch is silently cast */ - /* TODO: check this */ - FT_LOCAL_DEF( CF2_Fixed ) - cf2_stack_popFixed( CF2_Stack stack ) - { - if ( stack->top == &stack->buffer[0] ) - { - CF2_SET_ERROR( stack->error, Stack_Underflow ); - return cf2_intToFixed( 0 ); /* underflow */ - } - - --stack->top; - - switch ( stack->top->type ) - { - case CF2_NumberInt: - return cf2_intToFixed( stack->top->u.i ); - case CF2_NumberFrac: - return cf2_fracToFixed( stack->top->u.f ); - default: - return stack->top->u.r; - } - } - - - /* Note: type mismatch is silently cast */ - /* TODO: check this */ - FT_LOCAL_DEF( CF2_Fixed ) - cf2_stack_getReal( CF2_Stack stack, - CF2_UInt idx ) - { - FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE ); - - if ( idx >= cf2_stack_count( stack ) ) - { - CF2_SET_ERROR( stack->error, Stack_Overflow ); - return cf2_intToFixed( 0 ); /* bounds error */ - } - - switch ( stack->buffer[idx].type ) - { - case CF2_NumberInt: - return cf2_intToFixed( stack->buffer[idx].u.i ); - case CF2_NumberFrac: - return cf2_fracToFixed( stack->buffer[idx].u.f ); - default: - return stack->buffer[idx].u.r; - } - } - - - FT_LOCAL_DEF( void ) - cf2_stack_clear( CF2_Stack stack ) - { - stack->top = &stack->buffer[0]; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2stack.h b/drivers/freetype/freetype/src/cff/cf2stack.h deleted file mode 100644 index 7d6d1961fe..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2stack.h +++ /dev/null @@ -1,106 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2stack.h */ -/* */ -/* Adobe's code for emulating a CFF stack (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2STACK_H__ -#define __CF2STACK_H__ - - -FT_BEGIN_HEADER - - - /* CFF operand stack; specified maximum of 48 or 192 values */ - typedef struct CF2_StackNumber_ - { - union - { - CF2_Fixed r; /* 16.16 fixed point */ - CF2_Frac f; /* 2.30 fixed point (for font matrix) */ - CF2_Int i; - } u; - - CF2_NumberType type; - - } CF2_StackNumber; - - - typedef struct CF2_StackRec_ - { - FT_Memory memory; - FT_Error* error; - CF2_StackNumber buffer[CF2_OPERAND_STACK_SIZE]; - CF2_StackNumber* top; - - } CF2_StackRec, *CF2_Stack; - - - FT_LOCAL( CF2_Stack ) - cf2_stack_init( FT_Memory memory, - FT_Error* error ); - FT_LOCAL( void ) - cf2_stack_free( CF2_Stack stack ); - - FT_LOCAL( CF2_UInt ) - cf2_stack_count( CF2_Stack stack ); - - FT_LOCAL( void ) - cf2_stack_pushInt( CF2_Stack stack, - CF2_Int val ); - FT_LOCAL( void ) - cf2_stack_pushFixed( CF2_Stack stack, - CF2_Fixed val ); - - FT_LOCAL( CF2_Int ) - cf2_stack_popInt( CF2_Stack stack ); - FT_LOCAL( CF2_Fixed ) - cf2_stack_popFixed( CF2_Stack stack ); - - FT_LOCAL( CF2_Fixed ) - cf2_stack_getReal( CF2_Stack stack, - CF2_UInt idx ); - - FT_LOCAL( void ) - cf2_stack_clear( CF2_Stack stack ); - - -FT_END_HEADER - - -#endif /* __CF2STACK_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2types.h b/drivers/freetype/freetype/src/cff/cf2types.h deleted file mode 100644 index ac6a02266e..0000000000 --- a/drivers/freetype/freetype/src/cff/cf2types.h +++ /dev/null @@ -1,78 +0,0 @@ -/***************************************************************************/ -/* */ -/* cf2types.h */ -/* */ -/* Adobe's code for defining data types (specification only). */ -/* */ -/* Copyright 2011-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __CF2TYPES_H__ -#define __CF2TYPES_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - - -FT_BEGIN_HEADER - - - /* - * The data models that we expect to support are as follows: - * - * name char short int long long-long pointer example - * ----------------------------------------------------- - * ILP32 8 16 32 32 64* 32 32-bit MacOS, x86 - * LLP64 8 16 32 32 64 64 x64 - * LP64 8 16 32 64 64 64 64-bit MacOS - * - * *) type may be supported by emulation on a 32-bit architecture - * - */ - - - /* integers at least 32 bits wide */ -#define CF2_UInt FT_UFast -#define CF2_Int FT_Fast - - - /* fixed-float numbers */ - typedef FT_Int32 CF2_F16Dot16; - - -FT_END_HEADER - - -#endif /* __CF2TYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cff.c b/drivers/freetype/freetype/src/cff/cff.c deleted file mode 100644 index c3840b5838..0000000000 --- a/drivers/freetype/freetype/src/cff/cff.c +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* cff.c */ -/* */ -/* FreeType OpenType driver component (body only). */ -/* */ -/* Copyright 1996-2001, 2002, 2013 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> - -#include "cffpic.c" -#include "cffdrivr.c" -#include "cffparse.c" -#include "cffload.c" -#include "cffobjs.c" -#include "cffgload.c" -#include "cffcmap.c" - -#include "cf2arrst.c" -#include "cf2blues.c" -#include "cf2error.c" -#include "cf2font.c" -#include "cf2ft.c" -#include "cf2hints.c" -#include "cf2intrp.c" -#include "cf2read.c" -#include "cf2stack.c" - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffcmap.c b/drivers/freetype/freetype/src/cff/cffcmap.c deleted file mode 100644 index f6e03c6420..0000000000 --- a/drivers/freetype/freetype/src/cff/cffcmap.c +++ /dev/null @@ -1,210 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffcmap.c */ -/* */ -/* CFF character mapping table (cmap) support (body). */ -/* */ -/* Copyright 2002-2007, 2010, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include "cffcmap.h" -#include "cffload.h" - -#include "cfferrs.h" - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_CALLBACK_DEF( FT_Error ) - cff_cmap_encoding_init( CFF_CMapStd cmap ) - { - TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); - CFF_Font cff = (CFF_Font)face->extra.data; - CFF_Encoding encoding = &cff->encoding; - - - cmap->gids = encoding->codes; - - return 0; - } - - - FT_CALLBACK_DEF( void ) - cff_cmap_encoding_done( CFF_CMapStd cmap ) - { - cmap->gids = NULL; - } - - - FT_CALLBACK_DEF( FT_UInt ) - cff_cmap_encoding_char_index( CFF_CMapStd cmap, - FT_UInt32 char_code ) - { - FT_UInt result = 0; - - - if ( char_code < 256 ) - result = cmap->gids[char_code]; - - return result; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - cff_cmap_encoding_char_next( CFF_CMapStd cmap, - FT_UInt32 *pchar_code ) - { - FT_UInt result = 0; - FT_UInt32 char_code = *pchar_code; - - - *pchar_code = 0; - - if ( char_code < 255 ) - { - FT_UInt code = (FT_UInt)(char_code + 1); - - - for (;;) - { - if ( code >= 256 ) - break; - - result = cmap->gids[code]; - if ( result != 0 ) - { - *pchar_code = code; - break; - } - - code++; - } - } - return result; - } - - - FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, - sizeof ( CFF_CMapStdRec ), - - (FT_CMap_InitFunc) cff_cmap_encoding_init, - (FT_CMap_DoneFunc) cff_cmap_encoding_done, - (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, - (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, - - NULL, NULL, NULL, NULL, NULL - ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_CALLBACK_DEF( const char* ) - 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_UInt sid = charset->sids[idx]; - - - return cff_index_get_sid_string( cff, sid ); - } - - - FT_CALLBACK_DEF( FT_Error ) - cff_cmap_unicode_init( PS_Unicodes unicodes ) - { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); - CFF_Font cff = (CFF_Font)face->extra.data; - CFF_Charset charset = &cff->charset; - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; - - - /* can't build Unicode map for CID-keyed font */ - /* because we don't know glyph names. */ - if ( !charset->sids ) - return FT_THROW( No_Unicode_Glyph_Name ); - - return psnames->unicodes_init( memory, - unicodes, - cff->num_glyphs, - (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name, - (PS_FreeGlyphNameFunc)NULL, - (FT_Pointer)face ); - } - - - FT_CALLBACK_DEF( void ) - cff_cmap_unicode_done( PS_Unicodes unicodes ) - { - FT_Face face = FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); - - - FT_FREE( unicodes->maps ); - unicodes->num_maps = 0; - } - - - FT_CALLBACK_DEF( FT_UInt ) - cff_cmap_unicode_char_index( PS_Unicodes unicodes, - FT_UInt32 char_code ) - { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - CFF_Font cff = (CFF_Font)face->extra.data; - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; - - - return psnames->unicodes_char_index( unicodes, char_code ); - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - cff_cmap_unicode_char_next( PS_Unicodes unicodes, - FT_UInt32 *pchar_code ) - { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - CFF_Font cff = (CFF_Font)face->extra.data; - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; - - - return psnames->unicodes_char_next( unicodes, pchar_code ); - } - - - FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, - sizeof ( PS_UnicodesRec ), - - (FT_CMap_InitFunc) cff_cmap_unicode_init, - (FT_CMap_DoneFunc) cff_cmap_unicode_done, - (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, - - NULL, NULL, NULL, NULL, NULL - ) - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffcmap.h b/drivers/freetype/freetype/src/cff/cffcmap.h deleted file mode 100644 index 3f7f67bbe0..0000000000 --- a/drivers/freetype/freetype/src/cff/cffcmap.h +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffcmap.h */ -/* */ -/* CFF character mapping table (cmap) support (specification). */ -/* */ -/* Copyright 2002, 2003, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __CFFCMAP_H__ -#define __CFFCMAP_H__ - -#include "cffobjs.h" - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* standard (and expert) encoding cmaps */ - typedef struct CFF_CMapStdRec_* CFF_CMapStd; - - typedef struct CFF_CMapStdRec_ - { - FT_CMapRec cmap; - FT_UShort* gids; /* up to 256 elements */ - - } CFF_CMapStdRec; - - - FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* unicode (synthetic) cmaps */ - - FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec) - - -FT_END_HEADER - -#endif /* __CFFCMAP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffdrivr.c b/drivers/freetype/freetype/src/cff/cffdrivr.c deleted file mode 100644 index c8ca96ba49..0000000000 --- a/drivers/freetype/freetype/src/cff/cffdrivr.c +++ /dev/null @@ -1,786 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffdrivr.c */ -/* */ -/* OpenType font driver implementation (body). */ -/* */ -/* Copyright 1996-2013 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_FREETYPE_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_SERVICE_CID_H -#include FT_SERVICE_POSTSCRIPT_INFO_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_TT_CMAP_H - -#include "cffdrivr.h" -#include "cffgload.h" -#include "cffload.h" -#include "cffcmap.h" -#include "cffparse.h" - -#include "cfferrs.h" -#include "cffpic.h" - -#include FT_SERVICE_XFREE86_NAME_H -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_PROPERTIES_H -#include FT_CFF_DRIVER_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_cffdriver - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F A C E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_get_kerning */ - /* */ - /* <Description> */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* <Output> */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings, are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - FT_CALLBACK_DEF( FT_Error ) - cff_get_kerning( FT_Face ttface, /* TT_Face */ - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - TT_Face face = (TT_Face)ttface; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; - - - kerning->x = 0; - kerning->y = 0; - - if ( sfnt ) - kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); - - return FT_Err_Ok; - } - - -#undef PAIR_TAG - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_glyph_load */ - /* */ - /* <Description> */ - /* A driver method used to load a glyph within a given glyph slot. */ - /* */ - /* <Input> */ - /* slot :: A handle to the target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled, loaded, etc. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_??? constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_CALLBACK_DEF( FT_Error ) - cff_glyph_load( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ - FT_Size cffsize, /* CFF_Size */ - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - FT_Error error; - CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; - CFF_Size size = (CFF_Size)cffsize; - - - if ( !slot ) - return FT_THROW( Invalid_Slot_Handle ); - - /* check whether we want a scaled outline or bitmap */ - if ( !size ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - /* reset the size object if necessary */ - if ( load_flags & FT_LOAD_NO_SCALE ) - size = NULL; - - if ( size ) - { - /* these two objects must have the same parent */ - if ( cffsize->face != cffslot->face ) - return FT_THROW( Invalid_Face_Handle ); - } - - /* now load the glyph outline if necessary */ - error = cff_slot_load( slot, size, glyph_index, load_flags ); - - /* force drop-out mode to 2 - irrelevant now */ - /* slot->outline.dropout_mode = 2; */ - - return error; - } - - - FT_CALLBACK_DEF( FT_Error ) - cff_get_advances( FT_Face face, - FT_UInt start, - FT_UInt count, - FT_Int32 flags, - FT_Fixed* advances ) - { - FT_UInt nn; - FT_Error error = FT_Err_Ok; - FT_GlyphSlot slot = face->glyph; - - - flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; - - for ( nn = 0; nn < count; nn++ ) - { - error = cff_glyph_load( slot, face->size, start + nn, flags ); - if ( error ) - break; - - advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) - ? slot->linearVertAdvance - : slot->linearHoriAdvance; - } - - return error; - } - - - /* - * GLYPH DICT SERVICE - * - */ - - static FT_Error - cff_get_glyph_name( CFF_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - CFF_Font font = (CFF_Font)face->extra.data; - FT_String* gname; - FT_UShort sid; - FT_Error error; - - - if ( !font->psnames ) - { - FT_ERROR(( "cff_get_glyph_name:" - " cannot get glyph name from CFF & CEF fonts\n" - " " - " without the `PSNames' module\n" )); - error = FT_THROW( Missing_Module ); - goto Exit; - } - - /* first, locate the sid in the charset table */ - sid = font->charset.sids[glyph_index]; - - /* now, lookup the name itself */ - gname = cff_index_get_sid_string( font, sid ); - - if ( gname ) - FT_STRCPYN( buffer, gname, buffer_max ); - - error = FT_Err_Ok; - - Exit: - return error; - } - - - static FT_UInt - cff_get_name_index( CFF_Face face, - FT_String* glyph_name ) - { - CFF_Font cff; - CFF_Charset charset; - FT_Service_PsCMaps psnames; - FT_String* name; - FT_UShort sid; - FT_UInt i; - - - cff = (CFF_FontRec *)face->extra.data; - charset = &cff->charset; - - FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); - if ( !psnames ) - return 0; - - for ( i = 0; i < cff->num_glyphs; i++ ) - { - sid = charset->sids[i]; - - if ( sid > 390 ) - name = cff_index_get_string( cff, sid - 391 ); - else - name = (FT_String *)psnames->adobe_std_strings( sid ); - - if ( !name ) - continue; - - if ( !ft_strcmp( glyph_name, name ) ) - return i; - } - - return 0; - } - - - FT_DEFINE_SERVICE_GLYPHDICTREC( - cff_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)cff_get_name_index - ) - - - /* - * POSTSCRIPT INFO SERVICE - * - */ - - static FT_Int - cff_ps_has_glyph_names( FT_Face face ) - { - return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; - } - - - 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 = NULL; - 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, - dict->version ); - font_info->notice = cff_index_get_sid_string( cff, - dict->notice ); - font_info->full_name = cff_index_get_sid_string( cff, - dict->full_name ); - font_info->family_name = cff_index_get_sid_string( cff, - dict->family_name ); - font_info->weight = cff_index_get_sid_string( cff, - dict->weight ); - 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; - } - - if ( cff ) - *afont_info = *cff->font_info; - - Fail: - return error; - } - - - FT_DEFINE_SERVICE_PSINFOREC( - cff_service_ps_info, - (PS_GetFontInfoFunc) cff_ps_get_font_info, - (PS_GetFontExtraFunc) NULL, - (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, - (PS_GetFontPrivateFunc)NULL, /* unsupported with CFF fonts */ - (PS_GetFontValueFunc) NULL /* not implemented */ - ) - - - /* - * POSTSCRIPT NAME SERVICE - * - */ - - static const char* - cff_get_ps_name( CFF_Face face ) - { - CFF_Font cff = (CFF_Font)face->extra.data; - - - return (const char*)cff->font_name; - } - - - FT_DEFINE_SERVICE_PSFONTNAMEREC( - cff_service_ps_name, - (FT_PsName_GetFunc)cff_get_ps_name - ) - - - /* - * TT CMAP INFO - * - * If the charmap is a synthetic Unicode encoding cmap or - * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO - * service defined in SFNT module. - * - * Otherwise call the service function in the sfnt module. - * - */ - static FT_Error - cff_get_cmap_info( FT_CharMap charmap, - TT_CMapInfo *cmap_info ) - { - FT_CMap cmap = FT_CMAP( charmap ); - FT_Error error = FT_Err_Ok; - - FT_Face face = FT_CMAP_FACE( cmap ); - FT_Library library = FT_FACE_LIBRARY( face ); - - - cmap_info->language = 0; - cmap_info->format = 0; - - if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET && - cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET ) - { - FT_Module sfnt = FT_Get_Module( library, "sfnt" ); - FT_Service_TTCMaps service = - (FT_Service_TTCMaps)ft_module_get_service( sfnt, - FT_SERVICE_ID_TT_CMAP ); - - - if ( service && service->get_cmap_info ) - error = service->get_cmap_info( charmap, cmap_info ); - } - - return error; - } - - - FT_DEFINE_SERVICE_TTCMAPSREC( - cff_service_get_cmap_info, - (TT_CMap_Info_GetFunc)cff_get_cmap_info - ) - - - /* - * CID INFO SERVICE - * - */ - static FT_Error - cff_get_ros( CFF_Face face, - const char* *registry, - const char* *ordering, - FT_Int *supplement ) - { - FT_Error error = FT_Err_Ok; - CFF_Font cff = (CFF_Font)face->extra.data; - - - if ( cff ) - { - CFF_FontRecDict dict = &cff->top_font.font_dict; - - - if ( dict->cid_registry == 0xFFFFU ) - { - error = FT_THROW( Invalid_Argument ); - goto Fail; - } - - if ( registry ) - { - if ( cff->registry == NULL ) - cff->registry = cff_index_get_sid_string( cff, - dict->cid_registry ); - *registry = cff->registry; - } - - if ( ordering ) - { - if ( cff->ordering == NULL ) - cff->ordering = cff_index_get_sid_string( cff, - dict->cid_ordering ); - *ordering = cff->ordering; - } - - /* - * XXX: According to Adobe TechNote #5176, the supplement in CFF - * can be a real number. We truncate it to fit public API - * since freetype-2.3.6. - */ - if ( supplement ) - { - if ( dict->cid_supplement < FT_INT_MIN || - dict->cid_supplement > FT_INT_MAX ) - FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", - dict->cid_supplement )); - *supplement = (FT_Int)dict->cid_supplement; - } - } - - Fail: - return error; - } - - - static FT_Error - cff_get_is_cid( CFF_Face face, - FT_Bool *is_cid ) - { - FT_Error error = FT_Err_Ok; - CFF_Font cff = (CFF_Font)face->extra.data; - - - *is_cid = 0; - - if ( cff ) - { - CFF_FontRecDict dict = &cff->top_font.font_dict; - - - if ( dict->cid_registry != 0xFFFFU ) - *is_cid = 1; - } - - return error; - } - - - static FT_Error - cff_get_cid_from_glyph_index( CFF_Face face, - FT_UInt glyph_index, - FT_UInt *cid ) - { - FT_Error error = FT_Err_Ok; - CFF_Font cff; - - - cff = (CFF_Font)face->extra.data; - - if ( cff ) - { - FT_UInt c; - CFF_FontRecDict dict = &cff->top_font.font_dict; - - - if ( dict->cid_registry == 0xFFFFU ) - { - error = FT_THROW( Invalid_Argument ); - goto Fail; - } - - if ( glyph_index > cff->num_glyphs ) - { - error = FT_THROW( Invalid_Argument ); - goto Fail; - } - - c = cff->charset.sids[glyph_index]; - - if ( cid ) - *cid = c; - } - - Fail: - return error; - } - - - FT_DEFINE_SERVICE_CIDREC( - cff_service_cid_info, - (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index - ) - - - /* - * PROPERTY SERVICE - * - */ - static FT_Error - cff_property_set( FT_Module module, /* CFF_Driver */ - const char* property_name, - const void* value ) - { - FT_Error error = FT_Err_Ok; - CFF_Driver driver = (CFF_Driver)module; - - - if ( !ft_strcmp( property_name, "hinting-engine" ) ) - { - FT_UInt* hinting_engine = (FT_UInt*)value; - - -#ifndef CFF_CONFIG_OPTION_OLD_ENGINE - if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) - error = FT_ERR( Unimplemented_Feature ); - else -#endif - driver->hinting_engine = *hinting_engine; - - return error; - } - else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) - { - FT_Bool* no_stem_darkening = (FT_Bool*)value; - - - driver->no_stem_darkening = *no_stem_darkening; - - return error; - } - - FT_TRACE0(( "cff_property_set: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - static FT_Error - cff_property_get( FT_Module module, /* CFF_Driver */ - const char* property_name, - const void* value ) - { - FT_Error error = FT_Err_Ok; - CFF_Driver driver = (CFF_Driver)module; - - FT_UInt hinting_engine = driver->hinting_engine; - FT_Bool no_stem_darkening = driver->no_stem_darkening; - - - if ( !ft_strcmp( property_name, "hinting-engine" ) ) - { - FT_UInt* val = (FT_UInt*)value; - - - *val = hinting_engine; - - return error; - } - else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) - { - FT_Bool* val = (FT_Bool*)value; - - - *val = no_stem_darkening; - - return error; - } - - FT_TRACE0(( "cff_property_get: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - FT_DEFINE_SERVICE_PROPERTIESREC( - cff_service_properties, - (FT_Properties_SetFunc)cff_property_set, - (FT_Properties_GetFunc)cff_property_get ) - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** D R I V E R I N T E R F A C E ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - FT_DEFINE_SERVICEDESCREC7( - cff_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, - FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, - FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, - FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, - FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET - ) -#else - FT_DEFINE_SERVICEDESCREC6( - cff_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, - FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, - FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, - FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET - ) -#endif - - - FT_CALLBACK_DEF( FT_Module_Interface ) - cff_get_interface( FT_Module driver, /* CFF_Driver */ - const char* module_interface ) - { - FT_Library library; - FT_Module sfnt; - FT_Module_Interface result; - - - /* CFF_SERVICES_GET derefers `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - if ( !driver ) - return NULL; - library = driver->library; - if ( !library ) - return NULL; -#endif - - result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); - if ( result != NULL ) - return result; - - /* `driver' is not yet evaluated in non-PIC mode */ -#ifndef FT_CONFIG_OPTION_PIC - if ( !driver ) - return NULL; - library = driver->library; - if ( !library ) - return NULL; -#endif - - /* we pass our request to the `sfnt' module */ - sfnt = FT_Get_Module( library, "sfnt" ); - - return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; - } - - - /* The FT_DriverInterface structure is defined in ftdriver.h. */ - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#define CFF_SIZE_SELECT cff_size_select -#else -#define CFF_SIZE_SELECT 0 -#endif - - FT_DEFINE_DRIVER( - cff_driver_class, - - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - FT_MODULE_DRIVER_HAS_HINTER, - - sizeof ( CFF_DriverRec ), - "cff", - 0x10000L, - 0x20000L, - - 0, /* module-specific interface */ - - cff_driver_init, - cff_driver_done, - cff_get_interface, - - /* now the specific driver fields */ - sizeof ( TT_FaceRec ), - sizeof ( CFF_SizeRec ), - sizeof ( CFF_GlyphSlotRec ), - - cff_face_init, - cff_face_done, - cff_size_init, - cff_size_done, - cff_slot_init, - cff_slot_done, - - cff_glyph_load, - - cff_get_kerning, - 0, /* FT_Face_AttachFunc */ - cff_get_advances, - - cff_size_request, - - CFF_SIZE_SELECT - ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffdrivr.h b/drivers/freetype/freetype/src/cff/cffdrivr.h deleted file mode 100644 index 50e8138701..0000000000 --- a/drivers/freetype/freetype/src/cff/cffdrivr.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffdrivr.h */ -/* */ -/* High-level OpenType driver interface (specification). */ -/* */ -/* Copyright 1996-2001, 2002 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 __CFFDRIVER_H__ -#define __CFFDRIVER_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H - - -FT_BEGIN_HEADER - - - FT_DECLARE_DRIVER( cff_driver_class ) - - -FT_END_HEADER - -#endif /* __CFFDRIVER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cfferrs.h b/drivers/freetype/freetype/src/cff/cfferrs.h deleted file mode 100644 index 801d73ec6b..0000000000 --- a/drivers/freetype/freetype/src/cff/cfferrs.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* cfferrs.h */ -/* */ -/* CFF error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the CFF error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __CFFERRS_H__ -#define __CFFERRS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX CFF_Err_ -#define FT_ERR_BASE FT_Mod_Err_CFF - - -#include FT_ERRORS_H - -#endif /* __CFFERRS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffgload.c b/drivers/freetype/freetype/src/cff/cffgload.c deleted file mode 100644 index 6a8494fa9f..0000000000 --- a/drivers/freetype/freetype/src/cff/cffgload.c +++ /dev/null @@ -1,3068 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffgload.c */ -/* */ -/* OpenType Glyph Loader (body). */ -/* */ -/* Copyright 1996-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_OUTLINE_H -#include FT_CFF_DRIVER_H - -#include "cffobjs.h" -#include "cffload.h" -#include "cffgload.h" -#include "cf2ft.h" /* for cf2_decoder_parse_charstrings */ - -#include "cfferrs.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_cffgload - - -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - - typedef enum CFF_Operator_ - { - cff_op_unknown = 0, - - cff_op_rmoveto, - cff_op_hmoveto, - cff_op_vmoveto, - - cff_op_rlineto, - cff_op_hlineto, - cff_op_vlineto, - - cff_op_rrcurveto, - cff_op_hhcurveto, - cff_op_hvcurveto, - cff_op_rcurveline, - cff_op_rlinecurve, - cff_op_vhcurveto, - cff_op_vvcurveto, - - cff_op_flex, - cff_op_hflex, - cff_op_hflex1, - cff_op_flex1, - - cff_op_endchar, - - cff_op_hstem, - cff_op_vstem, - cff_op_hstemhm, - cff_op_vstemhm, - - cff_op_hintmask, - cff_op_cntrmask, - cff_op_dotsection, /* deprecated, acts as no-op */ - - cff_op_abs, - cff_op_add, - cff_op_sub, - cff_op_div, - cff_op_neg, - cff_op_random, - cff_op_mul, - cff_op_sqrt, - - cff_op_blend, - - cff_op_drop, - cff_op_exch, - cff_op_index, - cff_op_roll, - cff_op_dup, - - cff_op_put, - cff_op_get, - cff_op_store, - cff_op_load, - - cff_op_and, - cff_op_or, - cff_op_not, - cff_op_eq, - cff_op_ifelse, - - cff_op_callsubr, - cff_op_callgsubr, - cff_op_return, - - /* Type 1 opcodes: invalid but seen in real life */ - cff_op_hsbw, - cff_op_closepath, - cff_op_callothersubr, - cff_op_pop, - cff_op_seac, - cff_op_sbw, - cff_op_setcurrentpoint, - - /* do not remove */ - cff_op_max - - } CFF_Operator; - - -#define CFF_COUNT_CHECK_WIDTH 0x80 -#define CFF_COUNT_EXACT 0x40 -#define CFF_COUNT_CLEAR_STACK 0x20 - - /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ - /* used for checking the width and requested numbers of arguments */ - /* only; they are set to zero afterwards */ - - /* the other two flags are informative only and unused currently */ - - static const FT_Byte cff_argument_counts[] = - { - 0, /* unknown */ - - 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ - 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, - 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, - - 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - - 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - - 13, /* flex */ - 7, - 9, - 11, - - 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ - - 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ - 2 | CFF_COUNT_CHECK_WIDTH, - 2 | CFF_COUNT_CHECK_WIDTH, - 2 | CFF_COUNT_CHECK_WIDTH, - - 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ - 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ - 0, /* dotsection */ - - 1, /* abs */ - 2, - 2, - 2, - 1, - 0, - 2, - 1, - - 1, /* blend */ - - 1, /* drop */ - 2, - 1, - 2, - 1, - - 2, /* put */ - 1, - 4, - 3, - - 2, /* and */ - 2, - 1, - 2, - 4, - - 1, /* callsubr */ - 1, - 0, - - 2, /* hsbw */ - 0, - 0, - 0, - 5, /* seac */ - 4, /* sbw */ - 2 /* setcurrentpoint */ - }; - -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_builder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph builder. */ - /* */ - /* <InOut> */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting is active. */ - /* */ - static void - cff_builder_init( CFF_Builder* builder, - TT_Face face, - CFF_Size size, - CFF_GlyphSlot glyph, - FT_Bool hinting ) - { - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader loader = glyph->root.internal->loader; - - - builder->loader = loader; - builder->base = &loader->base.outline; - builder->current = &loader->current.outline; - FT_GlyphLoader_Rewind( loader ); - - builder->hints_globals = 0; - builder->hints_funcs = 0; - - if ( hinting && size ) - { - CFF_Internal internal = (CFF_Internal)size->root.internal; - - - builder->hints_globals = (void *)internal->topfont; - builder->hints_funcs = glyph->root.internal->glyph_hints; - } - } - - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_builder_done */ - /* */ - /* <Description> */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* <Input> */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - static void - cff_builder_done( CFF_Builder* builder ) - { - CFF_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_compute_bias */ - /* */ - /* <Description> */ - /* Computes the bias value in dependence of the number of glyph */ - /* subroutines. */ - /* */ - /* <Input> */ - /* in_charstring_type :: The `CharstringType' value of the top DICT */ - /* dictionary. */ - /* */ - /* num_subrs :: The number of glyph subroutines. */ - /* */ - /* <Return> */ - /* The bias value. */ - static FT_Int - cff_compute_bias( FT_Int in_charstring_type, - FT_UInt num_subrs ) - { - FT_Int result; - - - if ( in_charstring_type == 1 ) - result = 0; - else if ( num_subrs < 1240 ) - result = 107; - else if ( num_subrs < 33900U ) - result = 1131; - else - result = 32768U; - - return result; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_decoder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph decoder. */ - /* */ - /* <InOut> */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* slot :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting is active. */ - /* */ - /* hint_mode :: The hinting mode. */ - /* */ - FT_LOCAL_DEF( void ) - cff_decoder_init( CFF_Decoder* decoder, - TT_Face face, - CFF_Size size, - CFF_GlyphSlot slot, - FT_Bool hinting, - FT_Render_Mode hint_mode ) - { - CFF_Font cff = (CFF_Font)face->extra.data; - - - /* clear everything */ - FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); - - /* initialize builder */ - cff_builder_init( &decoder->builder, face, size, slot, hinting ); - - /* initialize Type2 decoder */ - decoder->cff = cff; - decoder->num_globals = cff->global_subrs_index.count; - decoder->globals = cff->global_subrs; - decoder->globals_bias = cff_compute_bias( - cff->top_font.font_dict.charstring_type, - decoder->num_globals ); - - decoder->hint_mode = hint_mode; - } - - - /* this function is used to select the subfont */ - /* and the locals subrs array */ - FT_LOCAL_DEF( FT_Error ) - cff_decoder_prepare( CFF_Decoder* decoder, - CFF_Size size, - FT_UInt glyph_index ) - { - CFF_Builder *builder = &decoder->builder; - CFF_Font cff = (CFF_Font)builder->face->extra.data; - CFF_SubFont sub = &cff->top_font; - FT_Error error = FT_Err_Ok; - - - /* manage CID fonts */ - if ( cff->num_subfonts ) - { - FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); - - - if ( fd_index >= cff->num_subfonts ) - { - FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index )); - - sub = cff->subfonts[fd_index]; - - if ( builder->hints_funcs && size ) - { - CFF_Internal internal = (CFF_Internal)size->root.internal; - - - /* for CFFs without subfonts, this value has already been set */ - builder->hints_globals = (void *)internal->subfonts[fd_index]; - } - } -#ifdef FT_DEBUG_LEVEL_TRACE - else - FT_TRACE3(( "glyph index %d:\n", glyph_index )); -#endif - - decoder->num_locals = sub->local_subrs_index.count; - decoder->locals = sub->local_subrs; - decoder->locals_bias = cff_compute_bias( - decoder->cff->top_font.font_dict.charstring_type, - decoder->num_locals ); - - decoder->glyph_width = sub->private_dict.default_width; - decoder->nominal_width = sub->private_dict.nominal_width; - - decoder->current_subfont = sub; /* for Adobe's CFF handler */ - - Exit: - return error; - } - - - /* check that there is enough space for `count' more points */ - FT_LOCAL_DEF( FT_Error ) - cff_check_points( CFF_Builder* builder, - FT_Int count ) - { - return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); - } - - - /* add a new point, do not check space */ - FT_LOCAL_DEF( void ) - cff_builder_add_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) - { - FT_Outline* outline = builder->current; - - - if ( builder->load_points ) - { - FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face ); - - - if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) - { - point->x = x >> 16; - point->y = y >> 16; - } - else -#endif - { - /* cf2_decoder_parse_charstrings uses 16.16 coordinates */ - point->x = x >> 10; - point->y = y >> 10; - } - *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - } - - outline->n_points++; - } - - - /* check space for a new on-curve point, then add it */ - FT_LOCAL_DEF( FT_Error ) - cff_builder_add_point1( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - - - error = cff_check_points( builder, 1 ); - if ( !error ) - cff_builder_add_point( builder, x, y, 1 ); - - return error; - } - - - /* check space for a new contour, then add it */ - static FT_Error - cff_builder_add_contour( CFF_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Error error; - - - if ( !builder->load_points ) - { - outline->n_contours++; - return FT_Err_Ok; - } - - error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); - if ( !error ) - { - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); - - outline->n_contours++; - } - - return error; - } - - - /* if a path was begun, add its first on-curve point */ - FT_LOCAL_DEF( FT_Error ) - cff_builder_start_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error = FT_Err_Ok; - - - /* test whether we are building a new contour */ - if ( !builder->path_begun ) - { - builder->path_begun = 1; - error = cff_builder_add_contour( builder ); - if ( !error ) - error = cff_builder_add_point1( builder, x, y ); - } - - return error; - } - - - /* close the current contour */ - FT_LOCAL_DEF( void ) - cff_builder_close_contour( CFF_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Int first; - - - if ( !outline ) - return; - - first = outline->n_contours <= 1 - ? 0 : outline->contours[outline->n_contours - 2] + 1; - - /* We must not include the last point in the path if it */ - /* is located on the first point. */ - if ( outline->n_points > 1 ) - { - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - - - /* `delete' last point only if it coincides with the first */ - /* point and if it is not a control point (which can happen). */ - if ( p1->x == p2->x && p1->y == p2->y ) - if ( *control == FT_CURVE_TAG_ON ) - outline->n_points--; - } - - if ( outline->n_contours > 0 ) - { - /* Don't add contours only consisting of one point, i.e., */ - /* check whether begin point and last point are the same. */ - if ( first == outline->n_points - 1 ) - { - outline->n_contours--; - outline->n_points--; - } - else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); - } - } - - - FT_LOCAL_DEF( FT_Int ) - cff_lookup_glyph_by_stdcharcode( CFF_Font cff, - FT_Int charcode ) - { - FT_UInt n; - FT_UShort glyph_sid; - - - /* CID-keyed fonts don't have glyph names */ - if ( !cff->charset.sids ) - return -1; - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - /* Get code to SID mapping from `cff_standard_encoding'. */ - glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode ); - - for ( n = 0; n < cff->num_glyphs; n++ ) - { - if ( cff->charset.sids[n] == glyph_sid ) - return n; - } - - return -1; - } - - - FT_LOCAL_DEF( FT_Error ) - cff_get_glyph_data( TT_Face face, - FT_UInt glyph_index, - FT_Byte** pointer, - FT_ULong* length ) - { -#ifdef FT_CONFIG_OPTION_INCREMENTAL - /* For incremental fonts get the character data using the */ - /* callback function. */ - if ( face->root.internal->incremental_interface ) - { - FT_Data data; - FT_Error error = - face->root.internal->incremental_interface->funcs->get_glyph_data( - face->root.internal->incremental_interface->object, - glyph_index, &data ); - - - *pointer = (FT_Byte*)data.pointer; - *length = data.length; - - return error; - } - else -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - { - CFF_Font cff = (CFF_Font)(face->extra.data); - - - return cff_index_access_element( &cff->charstrings_index, glyph_index, - pointer, length ); - } - } - - - FT_LOCAL_DEF( void ) - cff_free_glyph_data( TT_Face face, - FT_Byte** pointer, - FT_ULong length ) - { -#ifndef FT_CONFIG_OPTION_INCREMENTAL - FT_UNUSED( length ); -#endif - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - /* For incremental fonts get the character data using the */ - /* callback function. */ - if ( face->root.internal->incremental_interface ) - { - FT_Data data; - - - data.pointer = *pointer; - data.length = length; - - face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object, &data ); - } - else -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - { - CFF_Font cff = (CFF_Font)(face->extra.data); - - - cff_index_forget_element( &cff->charstrings_index, pointer ); - } - } - - -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - - static FT_Error - cff_operator_seac( CFF_Decoder* decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - CFF_Builder* builder = &decoder->builder; - FT_Int bchar_index, achar_index; - TT_Face face = decoder->builder.face; - FT_Vector left_bearing, advance; - FT_Byte* charstring; - FT_ULong charstring_len; - FT_Pos glyph_width; - - - if ( decoder->seac ) - { - FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); - return FT_THROW( Syntax_Error ); - } - - adx += decoder->builder.left_bearing.x; - ady += decoder->builder.left_bearing.y; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - /* Incremental fonts don't necessarily have valid charsets. */ - /* They use the character code, not the glyph index, in this case. */ - if ( face->root.internal->incremental_interface ) - { - bchar_index = bchar; - achar_index = achar; - } - else -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - { - CFF_Font cff = (CFF_Font)(face->extra.data); - - - bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar ); - achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar ); - } - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "cff_operator_seac:" - " invalid seac character code arguments\n" )); - return FT_THROW( Syntax_Error ); - } - - /* If we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( builder->no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; - FT_GlyphLoader loader = glyph->internal->loader; - FT_SubGlyph subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)( adx >> 16 ); - subg->arg2 = (FT_Int)( ady >> 16 ); - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->base.subglyphs; - glyph->format = FT_GLYPH_FORMAT_COMPOSITE; - - loader->current.num_subglyphs = 2; - } - - FT_GlyphLoader_Prepare( builder->loader ); - - /* First load `bchar' in builder */ - error = cff_get_glyph_data( face, bchar_index, - &charstring, &charstring_len ); - if ( !error ) - { - /* the seac operator must not be nested */ - decoder->seac = TRUE; - error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); - decoder->seac = FALSE; - - cff_free_glyph_data( face, &charstring, charstring_len ); - - if ( error ) - goto Exit; - } - - /* Save the left bearing, advance and glyph width of the base */ - /* character as they will be erased by the next load. */ - - left_bearing = builder->left_bearing; - advance = builder->advance; - glyph_width = decoder->glyph_width; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - - builder->pos_x = adx - asb; - builder->pos_y = ady; - - /* Now load `achar' on top of the base outline. */ - error = cff_get_glyph_data( face, achar_index, - &charstring, &charstring_len ); - if ( !error ) - { - /* the seac operator must not be nested */ - decoder->seac = TRUE; - error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); - decoder->seac = FALSE; - - cff_free_glyph_data( face, &charstring, charstring_len ); - - if ( error ) - goto Exit; - } - - /* Restore the left side bearing, advance and glyph width */ - /* of the base character. */ - builder->left_bearing = left_bearing; - builder->advance = advance; - decoder->glyph_width = glyph_width; - - builder->pos_x = 0; - builder->pos_y = 0; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_decoder_parse_charstrings */ - /* */ - /* <Description> */ - /* Parses a given Type 2 charstrings program. */ - /* */ - /* <InOut> */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* <Input> */ - /* charstring_base :: The base of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - cff_decoder_parse_charstrings( CFF_Decoder* decoder, - FT_Byte* charstring_base, - FT_ULong charstring_len ) - { - FT_Error error; - CFF_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - CFF_Builder* builder = &decoder->builder; - FT_Pos x, y; - FT_Fixed seed; - FT_Fixed* stack; - FT_Int charstring_type = - decoder->cff->top_font.font_dict.charstring_type; - - T2_Hints_Funcs hinter; - - - /* set default width */ - decoder->num_hints = 0; - decoder->read_width = 1; - - /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ - (FT_PtrDist)(char*)&decoder ^ - (FT_PtrDist)(char*)&charstring_base ) & - FT_ULONG_MAX ) ; - seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; - if ( seed == 0 ) - seed = 0x7384; - - /* initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - stack = decoder->top; - - hinter = (T2_Hints_Funcs)builder->hints_funcs; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = FT_Err_Ok; - - x = builder->pos_x; - y = builder->pos_y; - - /* begin hints recording session, if any */ - if ( hinter ) - hinter->open( hinter->hints ); - - /* now execute loop */ - while ( ip < limit ) - { - CFF_Operator op; - FT_Byte v; - - - /********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - v = *ip++; - if ( v >= 32 || v == 28 ) - { - FT_Int shift = 16; - FT_Int32 val; - - - /* this is an operand, push it on the stack */ - - /* if we use shifts, all computations are done with unsigned */ - /* values; the conversion to a signed value is the last step */ - if ( v == 28 ) - { - if ( ip + 1 >= limit ) - goto Syntax_Error; - val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] ); - ip += 2; - } - else if ( v < 247 ) - val = (FT_Int32)v - 139; - else if ( v < 251 ) - { - if ( ip >= limit ) - goto Syntax_Error; - val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; - } - else if ( v < 255 ) - { - if ( ip >= limit ) - goto Syntax_Error; - val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; - } - else - { - if ( ip + 3 >= limit ) - goto Syntax_Error; - val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | - ( (FT_UInt32)ip[1] << 16 ) | - ( (FT_UInt32)ip[2] << 8 ) | - (FT_UInt32)ip[3] ); - ip += 4; - if ( charstring_type == 2 ) - shift = 0; - } - if ( decoder->top - stack >= CFF_MAX_OPERANDS ) - goto Stack_Overflow; - - val = (FT_Int32)( (FT_UInt32)val << shift ); - *decoder->top++ = val; - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( !( val & 0xFFFFL ) ) - FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) )); - else - FT_TRACE4(( " %.2f", val / 65536.0 )); -#endif - - } - else - { - /* The specification says that normally arguments are to be taken */ - /* from the bottom of the stack. However, this seems not to be */ - /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ - /* arguments similar to a PS interpreter. */ - - FT_Fixed* args = decoder->top; - FT_Int num_args = (FT_Int)( args - decoder->stack ); - FT_Int req_args; - - - /* find operator */ - op = cff_op_unknown; - - switch ( v ) - { - case 1: - op = cff_op_hstem; - break; - case 3: - op = cff_op_vstem; - break; - case 4: - op = cff_op_vmoveto; - break; - case 5: - op = cff_op_rlineto; - break; - case 6: - op = cff_op_hlineto; - break; - case 7: - op = cff_op_vlineto; - break; - case 8: - op = cff_op_rrcurveto; - break; - case 9: - op = cff_op_closepath; - break; - case 10: - op = cff_op_callsubr; - break; - case 11: - op = cff_op_return; - break; - case 12: - { - if ( ip >= limit ) - goto Syntax_Error; - v = *ip++; - - switch ( v ) - { - case 0: - op = cff_op_dotsection; - break; - case 1: /* this is actually the Type1 vstem3 operator */ - op = cff_op_vstem; - break; - case 2: /* this is actually the Type1 hstem3 operator */ - op = cff_op_hstem; - break; - case 3: - op = cff_op_and; - break; - case 4: - op = cff_op_or; - break; - case 5: - op = cff_op_not; - break; - case 6: - op = cff_op_seac; - break; - case 7: - op = cff_op_sbw; - break; - case 8: - op = cff_op_store; - break; - case 9: - op = cff_op_abs; - break; - case 10: - op = cff_op_add; - break; - case 11: - op = cff_op_sub; - break; - case 12: - op = cff_op_div; - break; - case 13: - op = cff_op_load; - break; - case 14: - op = cff_op_neg; - break; - case 15: - op = cff_op_eq; - break; - case 16: - op = cff_op_callothersubr; - break; - case 17: - op = cff_op_pop; - break; - case 18: - op = cff_op_drop; - break; - case 20: - op = cff_op_put; - break; - case 21: - op = cff_op_get; - break; - case 22: - op = cff_op_ifelse; - break; - case 23: - op = cff_op_random; - break; - case 24: - op = cff_op_mul; - break; - case 26: - op = cff_op_sqrt; - break; - case 27: - op = cff_op_dup; - break; - case 28: - op = cff_op_exch; - break; - case 29: - op = cff_op_index; - break; - case 30: - op = cff_op_roll; - break; - case 33: - op = cff_op_setcurrentpoint; - break; - case 34: - op = cff_op_hflex; - break; - case 35: - op = cff_op_flex; - break; - case 36: - op = cff_op_hflex1; - break; - case 37: - op = cff_op_flex1; - break; - default: - FT_TRACE4(( " unknown op (12, %d)\n", v )); - break; - } - } - break; - case 13: - op = cff_op_hsbw; - break; - case 14: - op = cff_op_endchar; - break; - case 16: - op = cff_op_blend; - break; - case 18: - op = cff_op_hstemhm; - break; - case 19: - op = cff_op_hintmask; - break; - case 20: - op = cff_op_cntrmask; - break; - case 21: - op = cff_op_rmoveto; - break; - case 22: - op = cff_op_hmoveto; - break; - case 23: - op = cff_op_vstemhm; - break; - case 24: - op = cff_op_rcurveline; - break; - case 25: - op = cff_op_rlinecurve; - break; - case 26: - op = cff_op_vvcurveto; - break; - case 27: - op = cff_op_hhcurveto; - break; - case 29: - op = cff_op_callgsubr; - break; - case 30: - op = cff_op_vhcurveto; - break; - case 31: - op = cff_op_hvcurveto; - break; - default: - FT_TRACE4(( " unknown op (%d)\n", v )); - break; - } - - if ( op == cff_op_unknown ) - continue; - - /* check arguments */ - req_args = cff_argument_counts[op]; - if ( req_args & CFF_COUNT_CHECK_WIDTH ) - { - if ( num_args > 0 && decoder->read_width ) - { - /* If `nominal_width' is non-zero, the number is really a */ - /* difference against `nominal_width'. Else, the number here */ - /* is truly a width, not a difference against `nominal_width'. */ - /* If the font does not set `nominal_width', then */ - /* `nominal_width' defaults to zero, and so we can set */ - /* `glyph_width' to `nominal_width' plus number on the stack */ - /* -- for either case. */ - - FT_Int set_width_ok; - - - switch ( op ) - { - case cff_op_hmoveto: - case cff_op_vmoveto: - set_width_ok = num_args & 2; - break; - - case cff_op_hstem: - case cff_op_vstem: - case cff_op_hstemhm: - case cff_op_vstemhm: - case cff_op_rmoveto: - case cff_op_hintmask: - case cff_op_cntrmask: - set_width_ok = num_args & 1; - break; - - case cff_op_endchar: - /* If there is a width specified for endchar, we either have */ - /* 1 argument or 5 arguments. We like to argue. */ - set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); - break; - - default: - set_width_ok = 0; - break; - } - - if ( set_width_ok ) - { - decoder->glyph_width = decoder->nominal_width + - ( stack[0] >> 16 ); - - if ( decoder->width_only ) - { - /* we only want the advance width; stop here */ - break; - } - - /* Consumed an argument. */ - num_args--; - } - } - - decoder->read_width = 0; - req_args = 0; - } - - req_args &= 0x000F; - if ( num_args < req_args ) - goto Stack_Underflow; - args -= req_args; - num_args -= req_args; - - /* At this point, `args' points to the first argument of the */ - /* operand in case `req_args' isn't zero. Otherwise, we have */ - /* to adjust `args' manually. */ - - /* Note that we only pop arguments from the stack which we */ - /* really need and can digest so that we can continue in case */ - /* of superfluous stack elements. */ - - switch ( op ) - { - case cff_op_hstem: - case cff_op_vstem: - case cff_op_hstemhm: - case cff_op_vstemhm: - /* the number of arguments is always even here */ - FT_TRACE4(( - op == cff_op_hstem ? " hstem\n" : - ( op == cff_op_vstem ? " vstem\n" : - ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); - - if ( hinter ) - hinter->stems( hinter->hints, - ( op == cff_op_hstem || op == cff_op_hstemhm ), - num_args / 2, - args - ( num_args & ~1 ) ); - - decoder->num_hints += num_args / 2; - args = stack; - break; - - case cff_op_hintmask: - case cff_op_cntrmask: - FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); - - /* implement vstem when needed -- */ - /* the specification doesn't say it, but this also works */ - /* with the 'cntrmask' operator */ - /* */ - if ( num_args > 0 ) - { - if ( hinter ) - hinter->stems( hinter->hints, - 0, - num_args / 2, - args - ( num_args & ~1 ) ); - - decoder->num_hints += num_args / 2; - } - - /* In a valid charstring there must be at least one byte */ - /* after `hintmask' or `cntrmask' (e.g., for a `return' */ - /* instruction). Additionally, there must be space for */ - /* `num_hints' bits. */ - - if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit ) - goto Syntax_Error; - - if ( hinter ) - { - if ( op == cff_op_hintmask ) - hinter->hintmask( hinter->hints, - builder->current->n_points, - decoder->num_hints, - ip ); - else - hinter->counter( hinter->hints, - decoder->num_hints, - ip ); - } - -#ifdef FT_DEBUG_LEVEL_TRACE - { - FT_UInt maskbyte; - - - FT_TRACE4(( " (maskbytes:" )); - - for ( maskbyte = 0; - maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 ); - maskbyte++, ip++ ) - FT_TRACE4(( " 0x%02X", *ip )); - - FT_TRACE4(( ")\n" )); - } -#else - ip += ( decoder->num_hints + 7 ) >> 3; -#endif - args = stack; - break; - - case cff_op_rmoveto: - FT_TRACE4(( " rmoveto\n" )); - - cff_builder_close_contour( builder ); - builder->path_begun = 0; - x += args[-2]; - y += args[-1]; - args = stack; - break; - - case cff_op_vmoveto: - FT_TRACE4(( " vmoveto\n" )); - - cff_builder_close_contour( builder ); - builder->path_begun = 0; - y += args[-1]; - args = stack; - break; - - case cff_op_hmoveto: - FT_TRACE4(( " hmoveto\n" )); - - cff_builder_close_contour( builder ); - builder->path_begun = 0; - x += args[-1]; - args = stack; - break; - - case cff_op_rlineto: - FT_TRACE4(( " rlineto\n" )); - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, num_args / 2 ) ) - goto Fail; - - if ( num_args < 2 ) - goto Stack_Underflow; - - args -= num_args & ~1; - while ( args < decoder->top ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 1 ); - args += 2; - } - args = stack; - break; - - case cff_op_hlineto: - case cff_op_vlineto: - { - FT_Int phase = ( op == cff_op_hlineto ); - - - FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" - : " vlineto\n" )); - - if ( num_args < 0 ) - goto Stack_Underflow; - - /* there exist subsetted fonts (found in PDFs) */ - /* which call `hlineto' without arguments */ - if ( num_args == 0 ) - break; - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, num_args ) ) - goto Fail; - - args = stack; - while ( args < decoder->top ) - { - if ( phase ) - x += args[0]; - else - y += args[0]; - - if ( cff_builder_add_point1( builder, x, y ) ) - goto Fail; - - args++; - phase ^= 1; - } - args = stack; - } - break; - - case cff_op_rrcurveto: - { - FT_Int nargs; - - - FT_TRACE4(( " rrcurveto\n" )); - - if ( num_args < 6 ) - goto Stack_Underflow; - - nargs = num_args - num_args % 6; - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, nargs / 2 ) ) - goto Fail; - - args -= nargs; - while ( args < decoder->top ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - cff_builder_add_point( builder, x, y, 1 ); - args += 6; - } - args = stack; - } - break; - - case cff_op_vvcurveto: - { - FT_Int nargs; - - - FT_TRACE4(( " vvcurveto\n" )); - - if ( num_args < 4 ) - goto Stack_Underflow; - - /* if num_args isn't of the form 4n or 4n+1, */ - /* we enforce it by clearing the second bit */ - - nargs = num_args & ~2; - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - args -= nargs; - - if ( nargs & 1 ) - { - x += args[0]; - args++; - nargs--; - } - - if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) - goto Fail; - - while ( args < decoder->top ) - { - y += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - y += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; - } - break; - - case cff_op_hhcurveto: - { - FT_Int nargs; - - - FT_TRACE4(( " hhcurveto\n" )); - - if ( num_args < 4 ) - goto Stack_Underflow; - - /* if num_args isn't of the form 4n or 4n+1, */ - /* we enforce it by clearing the second bit */ - - nargs = num_args & ~2; - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - args -= nargs; - if ( nargs & 1 ) - { - y += args[0]; - args++; - nargs--; - } - - if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) - goto Fail; - - while ( args < decoder->top ) - { - x += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; - } - break; - - case cff_op_vhcurveto: - case cff_op_hvcurveto: - { - FT_Int phase; - FT_Int nargs; - - - FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" - : " hvcurveto\n" )); - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - if ( num_args < 4 ) - goto Stack_Underflow; - - /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ - /* we enforce it by clearing the second bit */ - - nargs = num_args & ~2; - - args -= nargs; - if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) ) - goto Stack_Underflow; - - phase = ( op == cff_op_hvcurveto ); - - while ( nargs >= 4 ) - { - nargs -= 4; - if ( phase ) - { - x += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - y += args[3]; - if ( nargs == 1 ) - x += args[4]; - cff_builder_add_point( builder, x, y, 1 ); - } - else - { - y += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[3]; - if ( nargs == 1 ) - y += args[4]; - cff_builder_add_point( builder, x, y, 1 ); - } - args += 4; - phase ^= 1; - } - args = stack; - } - break; - - case cff_op_rlinecurve: - { - FT_Int num_lines; - FT_Int nargs; - - - FT_TRACE4(( " rlinecurve\n" )); - - if ( num_args < 8 ) - goto Stack_Underflow; - - nargs = num_args & ~1; - num_lines = ( nargs - 6 ) / 2; - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, num_lines + 3 ) ) - goto Fail; - - args -= nargs; - - /* first, add the line segments */ - while ( num_lines > 0 ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 1 ); - args += 2; - num_lines--; - } - - /* then the curve */ - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - cff_builder_add_point( builder, x, y, 1 ); - args = stack; - } - break; - - case cff_op_rcurveline: - { - FT_Int num_curves; - FT_Int nargs; - - - FT_TRACE4(( " rcurveline\n" )); - - if ( num_args < 8 ) - goto Stack_Underflow; - - nargs = num_args - 2; - nargs = nargs - nargs % 6 + 2; - num_curves = ( nargs - 2 ) / 6; - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, num_curves * 3 + 2 ) ) - goto Fail; - - args -= nargs; - - /* first, add the curves */ - while ( num_curves > 0 ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - cff_builder_add_point( builder, x, y, 1 ); - args += 6; - num_curves--; - } - - /* then the final line */ - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 1 ); - args = stack; - } - break; - - case cff_op_hflex1: - { - FT_Pos start_y; - - - FT_TRACE4(( " hflex1\n" )); - - /* adding five more points: 4 control points, 1 on-curve point */ - /* -- make sure we have enough space for the start point if it */ - /* needs to be added */ - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, 6 ) ) - goto Fail; - - /* record the starting point's y position for later use */ - start_y = y; - - /* first control point */ - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - - /* second control point */ - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - - /* join point; on curve, with y-value the same as the last */ - /* control point's y-value */ - x += args[4]; - cff_builder_add_point( builder, x, y, 1 ); - - /* third control point, with y-value the same as the join */ - /* point's y-value */ - x += args[5]; - cff_builder_add_point( builder, x, y, 0 ); - - /* fourth control point */ - x += args[6]; - y += args[7]; - cff_builder_add_point( builder, x, y, 0 ); - - /* ending point, with y-value the same as the start */ - x += args[8]; - y = start_y; - cff_builder_add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case cff_op_hflex: - { - FT_Pos start_y; - - - FT_TRACE4(( " hflex\n" )); - - /* adding six more points; 4 control points, 2 on-curve points */ - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, 6 ) ) - goto Fail; - - /* record the starting point's y-position for later use */ - start_y = y; - - /* first control point */ - x += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - - /* second control point */ - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - - /* join point; on curve, with y-value the same as the last */ - /* control point's y-value */ - x += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - - /* third control point, with y-value the same as the join */ - /* point's y-value */ - x += args[4]; - cff_builder_add_point( builder, x, y, 0 ); - - /* fourth control point */ - x += args[5]; - y = start_y; - cff_builder_add_point( builder, x, y, 0 ); - - /* ending point, with y-value the same as the start point's */ - /* y-value -- we don't add this point, though */ - x += args[6]; - cff_builder_add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case cff_op_flex1: - { - FT_Pos start_x, start_y; /* record start x, y values for */ - /* alter use */ - FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ - /* algorithm below */ - FT_Int horizontal, count; - FT_Fixed* temp; - - - FT_TRACE4(( " flex1\n" )); - - /* adding six more points; 4 control points, 2 on-curve points */ - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, 6 ) ) - goto Fail; - - /* record the starting point's x, y position for later use */ - start_x = x; - start_y = y; - - /* XXX: figure out whether this is supposed to be a horizontal */ - /* or vertical flex; the Type 2 specification is vague... */ - - temp = args; - - /* grab up to the last argument */ - for ( count = 5; count > 0; count-- ) - { - dx += temp[0]; - dy += temp[1]; - temp += 2; - } - - if ( dx < 0 ) - dx = -dx; - if ( dy < 0 ) - dy = -dy; - - /* strange test, but here it is... */ - horizontal = ( dx > dy ); - - for ( count = 5; count > 0; count-- ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, - (FT_Bool)( count == 3 ) ); - args += 2; - } - - /* is last operand an x- or y-delta? */ - if ( horizontal ) - { - x += args[0]; - y = start_y; - } - else - { - x = start_x; - y += args[0]; - } - - cff_builder_add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case cff_op_flex: - { - FT_UInt count; - - - FT_TRACE4(( " flex\n" )); - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, 6 ) ) - goto Fail; - - for ( count = 6; count > 0; count-- ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, - (FT_Bool)( count == 4 || count == 1 ) ); - args += 2; - } - - args = stack; - } - break; - - case cff_op_seac: - FT_TRACE4(( " seac\n" )); - - error = cff_operator_seac( decoder, - args[0], args[1], args[2], - (FT_Int)( args[3] >> 16 ), - (FT_Int)( args[4] >> 16 ) ); - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - - /* return now! */ - FT_TRACE4(( "\n" )); - return error; - - case cff_op_endchar: - FT_TRACE4(( " endchar\n" )); - - /* We are going to emulate the seac operator. */ - if ( num_args >= 4 ) - { - /* Save glyph width so that the subglyphs don't overwrite it. */ - FT_Pos glyph_width = decoder->glyph_width; - - - error = cff_operator_seac( decoder, - 0L, args[-4], args[-3], - (FT_Int)( args[-2] >> 16 ), - (FT_Int)( args[-1] >> 16 ) ); - - decoder->glyph_width = glyph_width; - } - else - { - if ( !error ) - error = FT_Err_Ok; - - cff_builder_close_contour( builder ); - - /* close hints recording session */ - if ( hinter ) - { - if ( hinter->close( hinter->hints, - builder->current->n_points ) ) - goto Syntax_Error; - - /* apply hints to the loaded glyph outline now */ - hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_mode ); - } - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - } - - /* return now! */ - FT_TRACE4(( "\n" )); - return error; - - case cff_op_abs: - FT_TRACE4(( " abs\n" )); - - if ( args[0] < 0 ) - args[0] = -args[0]; - args++; - break; - - case cff_op_add: - FT_TRACE4(( " add\n" )); - - args[0] += args[1]; - args++; - break; - - case cff_op_sub: - FT_TRACE4(( " sub\n" )); - - args[0] -= args[1]; - args++; - break; - - case cff_op_div: - FT_TRACE4(( " div\n" )); - - args[0] = FT_DivFix( args[0], args[1] ); - args++; - break; - - case cff_op_neg: - FT_TRACE4(( " neg\n" )); - - args[0] = -args[0]; - args++; - break; - - case cff_op_random: - { - FT_Fixed Rand; - - - FT_TRACE4(( " rand\n" )); - - Rand = seed; - if ( Rand >= 0x8000L ) - Rand++; - - args[0] = Rand; - seed = FT_MulFix( seed, 0x10000L - seed ); - if ( seed == 0 ) - seed += 0x2873; - args++; - } - break; - - case cff_op_mul: - FT_TRACE4(( " mul\n" )); - - args[0] = FT_MulFix( args[0], args[1] ); - args++; - break; - - case cff_op_sqrt: - FT_TRACE4(( " sqrt\n" )); - - if ( args[0] > 0 ) - { - FT_Int count = 9; - FT_Fixed root = args[0]; - FT_Fixed new_root; - - - for (;;) - { - new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; - if ( new_root == root || count <= 0 ) - break; - root = new_root; - } - args[0] = new_root; - } - else - args[0] = 0; - args++; - break; - - case cff_op_drop: - /* nothing */ - FT_TRACE4(( " drop\n" )); - - break; - - case cff_op_exch: - { - FT_Fixed tmp; - - - FT_TRACE4(( " exch\n" )); - - tmp = args[0]; - args[0] = args[1]; - args[1] = tmp; - args += 2; - } - break; - - case cff_op_index: - { - FT_Int idx = (FT_Int)( args[0] >> 16 ); - - - FT_TRACE4(( " index\n" )); - - if ( idx < 0 ) - idx = 0; - else if ( idx > num_args - 2 ) - idx = num_args - 2; - args[0] = args[-( idx + 1 )]; - args++; - } - break; - - case cff_op_roll: - { - FT_Int count = (FT_Int)( args[0] >> 16 ); - FT_Int idx = (FT_Int)( args[1] >> 16 ); - - - FT_TRACE4(( " roll\n" )); - - if ( count <= 0 ) - count = 1; - - args -= count; - if ( args < stack ) - goto Stack_Underflow; - - if ( idx >= 0 ) - { - while ( idx > 0 ) - { - FT_Fixed tmp = args[count - 1]; - FT_Int i; - - - for ( i = count - 2; i >= 0; i-- ) - args[i + 1] = args[i]; - args[0] = tmp; - idx--; - } - } - else - { - while ( idx < 0 ) - { - FT_Fixed tmp = args[0]; - FT_Int i; - - - for ( i = 0; i < count - 1; i++ ) - args[i] = args[i + 1]; - args[count - 1] = tmp; - idx++; - } - } - args += count; - } - break; - - case cff_op_dup: - FT_TRACE4(( " dup\n" )); - - args[1] = args[0]; - args += 2; - break; - - case cff_op_put: - { - FT_Fixed val = args[0]; - FT_Int idx = (FT_Int)( args[1] >> 16 ); - - - FT_TRACE4(( " put\n" )); - - if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) - decoder->buildchar[idx] = val; - } - break; - - case cff_op_get: - { - FT_Int idx = (FT_Int)( args[0] >> 16 ); - FT_Fixed val = 0; - - - FT_TRACE4(( " get\n" )); - - if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) - val = decoder->buildchar[idx]; - - args[0] = val; - args++; - } - break; - - case cff_op_store: - FT_TRACE4(( " store\n")); - - goto Unimplemented; - - case cff_op_load: - FT_TRACE4(( " load\n" )); - - goto Unimplemented; - - case cff_op_dotsection: - /* this operator is deprecated and ignored by the parser */ - FT_TRACE4(( " dotsection\n" )); - break; - - case cff_op_closepath: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " closepath (invalid op)\n" )); - - args = stack; - break; - - case cff_op_hsbw: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " hsbw (invalid op)\n" )); - - decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 ); - - decoder->builder.left_bearing.x = args[0]; - decoder->builder.left_bearing.y = 0; - - x = decoder->builder.pos_x + args[0]; - y = decoder->builder.pos_y; - args = stack; - break; - - case cff_op_sbw: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " sbw (invalid op)\n" )); - - decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 ); - - decoder->builder.left_bearing.x = args[0]; - decoder->builder.left_bearing.y = args[1]; - - x = decoder->builder.pos_x + args[0]; - y = decoder->builder.pos_y + args[1]; - args = stack; - break; - - case cff_op_setcurrentpoint: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); - - x = decoder->builder.pos_x + args[0]; - y = decoder->builder.pos_y + args[1]; - args = stack; - break; - - case cff_op_callothersubr: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " callothersubr (invalid op)\n" )); - - /* subsequent `pop' operands should add the arguments, */ - /* this is the implementation described for `unknown' other */ - /* subroutines in the Type1 spec. */ - /* */ - /* XXX Fix return arguments (see discussion below). */ - args -= 2 + ( args[-2] >> 16 ); - if ( args < stack ) - goto Stack_Underflow; - break; - - case cff_op_pop: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " pop (invalid op)\n" )); - - /* XXX Increasing `args' is wrong: After a certain number of */ - /* `pop's we get a stack overflow. Reason for doing it is */ - /* code like this (actually found in a CFF font): */ - /* */ - /* 17 1 3 callothersubr */ - /* pop */ - /* callsubr */ - /* */ - /* Since we handle `callothersubr' as a no-op, and */ - /* `callsubr' needs at least one argument, `pop' can't be a */ - /* no-op too as it basically should be. */ - /* */ - /* The right solution would be to provide real support for */ - /* `callothersubr' as done in `t1decode.c', however, given */ - /* the fact that CFF fonts with `pop' are invalid, it is */ - /* questionable whether it is worth the time. */ - args++; - break; - - case cff_op_and: - { - FT_Fixed cond = args[0] && args[1]; - - - FT_TRACE4(( " and\n" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case cff_op_or: - { - FT_Fixed cond = args[0] || args[1]; - - - FT_TRACE4(( " or\n" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case cff_op_eq: - { - FT_Fixed cond = !args[0]; - - - FT_TRACE4(( " eq\n" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case cff_op_ifelse: - { - FT_Fixed cond = ( args[2] <= args[3] ); - - - FT_TRACE4(( " ifelse\n" )); - - if ( !cond ) - args[0] = args[1]; - args++; - } - break; - - case cff_op_callsubr: - { - FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + - decoder->locals_bias ); - - - FT_TRACE4(( " callsubr(%d)\n", idx )); - - if ( idx >= decoder->num_locals ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " invalid local subr index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = decoder->locals[idx]; - zone->limit = decoder->locals[idx + 1]; - zone->cursor = zone->base; - - if ( !zone->base || zone->limit == zone->base ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case cff_op_callgsubr: - { - FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + - decoder->globals_bias ); - - - FT_TRACE4(( " callgsubr(%d)\n", idx )); - - if ( idx >= decoder->num_globals ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " invalid global subr index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = decoder->globals[idx]; - zone->limit = decoder->globals[idx + 1]; - zone->cursor = zone->base; - - if ( !zone->base || zone->limit == zone->base ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case cff_op_return: - FT_TRACE4(( " return\n" )); - - if ( decoder->zone <= decoder->zones ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " unexpected return\n" )); - goto Syntax_Error; - } - - decoder->zone--; - zone = decoder->zone; - ip = zone->cursor; - limit = zone->limit; - break; - - default: - Unimplemented: - FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); - - if ( ip[-1] == 12 ) - FT_ERROR(( " %d", ip[0] )); - FT_ERROR(( "\n" )); - - return FT_THROW( Unimplemented_Feature ); - } - - decoder->top = args; - - if ( decoder->top - stack >= CFF_MAX_OPERANDS ) - goto Stack_Overflow; - - } /* general operator processing */ - - } /* while ip < limit */ - - FT_TRACE4(( "..end..\n\n" )); - - Fail: - return error; - - Syntax_Error: - FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); - return FT_THROW( Invalid_File_Format ); - - Stack_Underflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); - return FT_THROW( Too_Few_Arguments ); - - Stack_Overflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); - return FT_THROW( Stack_Overflow ); - } - -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#if 0 /* unused until we support pure CFF fonts */ - - - FT_LOCAL_DEF( FT_Error ) - cff_compute_max_advance( TT_Face face, - FT_Int* max_advance ) - { - FT_Error error = FT_Err_Ok; - CFF_Decoder decoder; - FT_Int glyph_index; - CFF_Font cff = (CFF_Font)face->other; - - - *max_advance = 0; - - /* Initialize load decoder */ - cff_decoder_init( &decoder, face, 0, 0, 0, 0 ); - - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; - - /* For each glyph, parse the glyph charstring and extract */ - /* the advance width. */ - for ( glyph_index = 0; glyph_index < face->root.num_glyphs; - glyph_index++ ) - { - FT_Byte* charstring; - FT_ULong charstring_len; - - - /* now get load the unscaled outline */ - error = cff_get_glyph_data( face, glyph_index, - &charstring, &charstring_len ); - if ( !error ) - { - error = cff_decoder_prepare( &decoder, size, glyph_index ); - if ( !error ) - error = cff_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); - - cff_free_glyph_data( face, &charstring, &charstring_len ); - } - - /* ignore the error if one has occurred -- skip to next glyph */ - error = FT_Err_Ok; - } - - *max_advance = decoder.builder.advance.x; - - return FT_Err_Ok; - } - - -#endif /* 0 */ - - - FT_LOCAL_DEF( FT_Error ) - cff_slot_load( CFF_GlyphSlot glyph, - CFF_Size size, - 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, scaled, force_scaling; - CFF_Font cff = (CFF_Font)face->extra.data; - - FT_Matrix font_matrix; - FT_Vector font_offset; - - - force_scaling = FALSE; - - /* 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 ) - { - /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */ - if ( glyph_index != 0 ) - { - glyph_index = cff_charset_cid_to_gindex( &cff->charset, - glyph_index ); - if ( glyph_index == 0 ) - return FT_THROW( Invalid_Argument ); - } - } - else if ( glyph_index >= cff->num_glyphs ) - return FT_THROW( Invalid_Argument ); - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - glyph->x_scale = 0x10000L; - glyph->y_scale = 0x10000L; - if ( size ) - { - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; - } - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* try to load embedded bitmap if any */ - /* */ - /* XXX: The convention should be emphasized in */ - /* the documents because it can be confusing. */ - if ( size ) - { - CFF_Face cff_face = (CFF_Face)size->root.face; - SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt; - FT_Stream stream = cff_face->root.stream; - - - if ( size->strike_index != 0xFFFFFFFFUL && - sfnt->load_eblc && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) - { - TT_SBit_MetricsRec metrics; - - - error = sfnt->load_sbit_image( face, - size->strike_index, - glyph_index, - (FT_Int)load_flags, - stream, - &glyph->root.bitmap, - &metrics ); - - if ( !error ) - { - FT_Bool has_vertical_info; - FT_UShort advance; - FT_Short dummy; - - - glyph->root.outline.n_points = 0; - glyph->root.outline.n_contours = 0; - - glyph->root.metrics.width = (FT_Pos)metrics.width << 6; - glyph->root.metrics.height = (FT_Pos)metrics.height << 6; - - glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; - glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; - glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; - - glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; - glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; - glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; - - glyph->root.format = FT_GLYPH_FORMAT_BITMAP; - - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - glyph->root.bitmap_left = metrics.vertBearingX; - glyph->root.bitmap_top = metrics.vertBearingY; - } - else - { - glyph->root.bitmap_left = metrics.horiBearingX; - glyph->root.bitmap_top = metrics.horiBearingY; - } - - /* compute linear advance widths */ - - ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, - glyph_index, - &dummy, - &advance ); - glyph->root.linearHoriAdvance = advance; - - has_vertical_info = FT_BOOL( - face->vertical_info && - face->vertical.number_Of_VMetrics > 0 ); - - /* get the vertical metrics from the vtmx table if we have one */ - if ( has_vertical_info ) - { - ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, - glyph_index, - &dummy, - &advance ); - glyph->root.linearVertAdvance = advance; - } - else - { - /* make up vertical ones */ - if ( face->os2.version != 0xFFFFU ) - glyph->root.linearVertAdvance = (FT_Pos) - ( face->os2.sTypoAscender - face->os2.sTypoDescender ); - else - glyph->root.linearVertAdvance = (FT_Pos) - ( face->horizontal.Ascender - face->horizontal.Descender ); - } - - return error; - } - } - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - /* return immediately if we only want the embedded bitmaps */ - if ( load_flags & FT_LOAD_SBITS_ONLY ) - return FT_THROW( Invalid_Argument ); - - /* if we have a CID subfont, use its matrix (which has already */ - /* been multiplied with the root matrix) */ - - /* this scaling is only relevant if the PS hinter isn't active */ - if ( cff->num_subfonts ) - { - FT_ULong top_upm, sub_upm; - FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, - glyph_index ); - - - if ( fd_index >= cff->num_subfonts ) - fd_index = (FT_Byte)( cff->num_subfonts - 1 ); - - top_upm = cff->top_font.font_dict.units_per_em; - sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; - - - font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; - font_offset = cff->subfonts[fd_index]->font_dict.font_offset; - - if ( top_upm != sub_upm ) - { - glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm ); - glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm ); - - force_scaling = TRUE; - } - } - else - { - font_matrix = cff->top_font.font_dict.font_matrix; - font_offset = cff->top_font.font_dict.font_offset; - } - - glyph->root.outline.n_points = 0; - glyph->root.outline.n_contours = 0; - - /* top-level code ensures that FT_LOAD_NO_HINTING is set */ - /* if FT_LOAD_NO_SCALE is active */ - hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); - scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); - - glyph->hint = hinting; - glyph->scaled = scaled; - glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */ - - { -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face ); -#endif - - - FT_Byte* charstring; - FT_ULong charstring_len; - - - cff_decoder_init( &decoder, face, size, glyph, hinting, - FT_LOAD_TARGET_MODE( load_flags ) ); - - if ( load_flags & FT_LOAD_ADVANCE_ONLY ) - decoder.width_only = TRUE; - - decoder.builder.no_recurse = - (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); - - /* now load the unscaled outline */ - error = cff_get_glyph_data( face, glyph_index, - &charstring, &charstring_len ); - if ( error ) - goto Glyph_Build_Finished; - - error = cff_decoder_prepare( &decoder, size, glyph_index ); - if ( error ) - goto Glyph_Build_Finished; - -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - /* choose which CFF renderer to use */ - if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) - error = cff_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); - else -#endif - { - error = cf2_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); - - /* Adobe's engine uses 16.16 numbers everywhere; */ - /* as a consequence, glyphs larger than 2000ppem get rejected */ - if ( FT_ERR_EQ( error, Glyph_Too_Big ) ) - { - /* this time, we retry unhinted and scale up the glyph later on */ - /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */ - /* 0x400 for both `x_scale' and `y_scale' in this case) */ - hinting = FALSE; - force_scaling = TRUE; - glyph->hint = hinting; - - error = cf2_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); - } - } - - cff_free_glyph_data( face, &charstring, charstring_len ); - - if ( error ) - goto Glyph_Build_Finished; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - /* Control data and length may not be available for incremental */ - /* fonts. */ - if ( face->root.internal->incremental_interface ) - { - glyph->root.control_data = 0; - glyph->root.control_len = 0; - } - else -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - /* We set control_data and control_len if charstrings is loaded. */ - /* See how charstring loads at cff_index_access_element() in */ - /* cffload.c. */ - { - CFF_Index csindex = &cff->charstrings_index; - - - if ( csindex->offsets ) - { - glyph->root.control_data = csindex->bytes + - csindex->offsets[glyph_index] - 1; - glyph->root.control_len = charstring_len; - } - } - - Glyph_Build_Finished: - /* save new glyph tables, if no error */ - if ( !error ) - cff_builder_done( &decoder.builder ); - /* XXX: anything to do for broken glyph entry? */ - } - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* Incremental fonts can optionally override the metrics. */ - if ( !error && - face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) - { - FT_Incremental_MetricsRec metrics; - - - metrics.bearing_x = decoder.builder.left_bearing.x; - metrics.bearing_y = 0; - metrics.advance = decoder.builder.advance.x; - metrics.advance_v = decoder.builder.advance.y; - - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - - decoder.builder.left_bearing.x = metrics.bearing_x; - decoder.builder.advance.x = metrics.advance; - decoder.builder.advance.y = metrics.advance_v; - } - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - if ( !error ) - { - /* Now, set the metrics -- this is rather simple, as */ - /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax. */ - - /* For composite glyphs, return only left side bearing and */ - /* advance width. */ - if ( load_flags & FT_LOAD_NO_RECURSE ) - { - FT_Slot_Internal internal = glyph->root.internal; - - - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.glyph_width; - internal->glyph_matrix = font_matrix; - internal->glyph_delta = font_offset; - internal->glyph_transformed = 1; - } - else - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - FT_Vector advance; - FT_Bool has_vertical_info; - - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.glyph_width; - glyph->root.linearHoriAdvance = decoder.glyph_width; - glyph->root.internal->glyph_transformed = 0; - - has_vertical_info = FT_BOOL( face->vertical_info && - face->vertical.number_Of_VMetrics > 0 ); - - /* get the vertical metrics from the vtmx table if we have one */ - if ( has_vertical_info ) - { - FT_Short vertBearingY = 0; - FT_UShort vertAdvance = 0; - - - ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, - glyph_index, - &vertBearingY, - &vertAdvance ); - metrics->vertBearingY = vertBearingY; - metrics->vertAdvance = vertAdvance; - } - else - { - /* make up vertical ones */ - if ( face->os2.version != 0xFFFFU ) - metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender - - face->os2.sTypoDescender ); - else - metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender - - face->horizontal.Descender ); - } - - glyph->root.linearVertAdvance = metrics->vertAdvance; - - glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; - - glyph->root.outline.flags = 0; - if ( size && size->root.metrics.y_ppem < 24 ) - glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; - - glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; - - if ( !( font_matrix.xx == 0x10000L && - font_matrix.yy == 0x10000L && - font_matrix.xy == 0 && - font_matrix.yx == 0 ) ) - FT_Outline_Transform( &glyph->root.outline, &font_matrix ); - - if ( !( font_offset.x == 0 && - font_offset.y == 0 ) ) - FT_Outline_Translate( &glyph->root.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 || force_scaling ) - { - /* scale the outline and the metrics */ - FT_Int n; - FT_Outline* cur = &glyph->root.outline; - 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( &glyph->root.outline, &cbox ); - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - - if ( has_vertical_info ) - metrics->vertBearingX = metrics->horiBearingX - - metrics->horiAdvance / 2; - else - { - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); - } - } - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffgload.h b/drivers/freetype/freetype/src/cff/cffgload.h deleted file mode 100644 index 41df7db692..0000000000 --- a/drivers/freetype/freetype/src/cff/cffgload.h +++ /dev/null @@ -1,240 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffgload.h */ -/* */ -/* OpenType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2004, 2006-2009, 2013 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 __CFFGLOAD_H__ -#define __CFFGLOAD_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include "cffobjs.h" - - -FT_BEGIN_HEADER - - -#define CFF_MAX_OPERANDS 48 -#define CFF_MAX_SUBRS_CALLS 32 -#define CFF_MAX_TRANS_ELEMENTS 32 - - - /*************************************************************************/ - /* */ - /* <Structure> */ - /* CFF_Builder */ - /* */ - /* <Description> */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* <Fields> */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: The current glyph loader. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - /* hints_funcs :: Auxiliary pointer for hinting. */ - /* */ - /* hints_globals :: Auxiliary pointer for hinting. */ - /* */ - typedef struct CFF_Builder_ - { - FT_Memory memory; - TT_Face face; - CFF_GlyphSlot glyph; - FT_GlyphLoader loader; - FT_Outline* base; - FT_Outline* current; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Bool metrics_only; - - void* hints_funcs; /* hinter-specific */ - void* hints_globals; /* hinter-specific */ - - } CFF_Builder; - - - FT_LOCAL( FT_Error ) - cff_check_points( CFF_Builder* builder, - FT_Int count ); - - FT_LOCAL( void ) - cff_builder_add_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ); - FT_LOCAL( FT_Error ) - cff_builder_add_point1( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ); - FT_LOCAL( FT_Error ) - cff_builder_start_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ); - FT_LOCAL( void ) - cff_builder_close_contour( CFF_Builder* builder ); - - - FT_LOCAL( FT_Int ) - cff_lookup_glyph_by_stdcharcode( CFF_Font cff, - FT_Int charcode ); - FT_LOCAL( FT_Error ) - cff_get_glyph_data( TT_Face face, - FT_UInt glyph_index, - FT_Byte** pointer, - FT_ULong* length ); - FT_LOCAL( void ) - cff_free_glyph_data( TT_Face face, - FT_Byte** pointer, - FT_ULong length ); - - - /* execution context charstring zone */ - - typedef struct CFF_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } CFF_Decoder_Zone; - - - typedef struct CFF_Decoder_ - { - CFF_Builder builder; - CFF_Font cff; - - FT_Fixed stack[CFF_MAX_OPERANDS + 1]; - FT_Fixed* top; - - CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1]; - CFF_Decoder_Zone* zone; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - FT_Pos glyph_width; - FT_Pos nominal_width; - - FT_Bool read_width; - FT_Bool width_only; - FT_Int num_hints; - FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]; - - FT_UInt num_locals; - FT_UInt num_globals; - - FT_Int locals_bias; - FT_Int globals_bias; - - FT_Byte** locals; - FT_Byte** globals; - - FT_Byte** glyph_names; /* for pure CFF fonts only */ - FT_UInt num_glyphs; /* number of glyphs in font */ - - FT_Render_Mode hint_mode; - - FT_Bool seac; - - CFF_SubFont current_subfont; /* for current glyph_index */ - - } CFF_Decoder; - - - FT_LOCAL( void ) - cff_decoder_init( CFF_Decoder* decoder, - TT_Face face, - CFF_Size size, - CFF_GlyphSlot slot, - FT_Bool hinting, - FT_Render_Mode hint_mode ); - - FT_LOCAL( FT_Error ) - cff_decoder_prepare( CFF_Decoder* decoder, - CFF_Size size, - FT_UInt glyph_index ); - -#if 0 /* unused until we support pure CFF fonts */ - - /* Compute the maximum advance width of a font through quick parsing */ - FT_LOCAL( FT_Error ) - cff_compute_max_advance( TT_Face face, - FT_Int* max_advance ); - -#endif /* 0 */ - -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - FT_LOCAL( FT_Error ) - cff_decoder_parse_charstrings( CFF_Decoder* decoder, - FT_Byte* charstring_base, - FT_ULong charstring_len ); -#endif - - FT_LOCAL( FT_Error ) - cff_slot_load( CFF_GlyphSlot glyph, - CFF_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ); - - -FT_END_HEADER - -#endif /* __CFFGLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffload.c b/drivers/freetype/freetype/src/cff/cffload.c deleted file mode 100644 index 64b497168d..0000000000 --- a/drivers/freetype/freetype/src/cff/cffload.c +++ /dev/null @@ -1,1696 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffload.c */ -/* */ -/* OpenType and CFF data/program tables loader (body). */ -/* */ -/* Copyright 1996-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include FT_TYPE1_TABLES_H - -#include "cffload.h" -#include "cffparse.h" - -#include "cfferrs.h" - - -#if 1 - - static const FT_UShort cff_isoadobe_charset[229] = - { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228 - }; - - static const FT_UShort cff_expert_charset[166] = - { - 0, 1, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 13, 14, 15, 99, - 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 27, 28, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 109, 110, - 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 158, 155, 163, 319, - 320, 321, 322, 323, 324, 325, 326, 150, - 164, 169, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378 - }; - - static const FT_UShort cff_expertsubset_charset[87] = - { - 0, 1, 231, 232, 235, 236, 237, 238, - 13, 14, 15, 99, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 27, 28, - 249, 250, 251, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, - 266, 109, 110, 267, 268, 269, 270, 272, - 300, 301, 302, 305, 314, 315, 158, 155, - 163, 320, 321, 322, 323, 324, 325, 326, - 150, 164, 169, 327, 328, 329, 330, 331, - 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346 - }; - - static const FT_UShort cff_standard_encoding[256] = - { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, - 0, 111, 112, 113, 114, 0, 115, 116, - 117, 118, 119, 120, 121, 122, 0, 123, - 0, 124, 125, 126, 127, 128, 129, 130, - 131, 0, 132, 133, 0, 134, 135, 136, - 137, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 138, 0, 139, 0, 0, 0, 0, - 140, 141, 142, 143, 0, 0, 0, 0, - 0, 144, 0, 0, 0, 145, 0, 0, - 146, 147, 148, 149, 0, 0, 0, 0 - }; - - static const FT_UShort cff_expert_encoding[256] = - { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 229, 230, 0, 231, 232, 233, 234, - 235, 236, 237, 238, 13, 14, 15, 99, - 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 27, 28, 249, 250, 251, 252, - 0, 253, 254, 255, 256, 257, 0, 0, - 0, 258, 0, 0, 259, 260, 261, 262, - 0, 0, 263, 264, 265, 0, 266, 109, - 110, 267, 268, 269, 0, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 304, 305, 306, 0, 0, 307, 308, - 309, 310, 311, 0, 312, 0, 0, 312, - 0, 0, 314, 315, 0, 0, 316, 317, - 318, 0, 0, 0, 158, 155, 163, 319, - 320, 321, 322, 323, 324, 325, 0, 0, - 326, 150, 164, 169, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378 - }; - -#endif /* 1 */ - - - FT_LOCAL_DEF( FT_UShort ) - cff_get_standard_encoding( FT_UInt charcode ) - { - return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] - : 0 ); - } - - - /*************************************************************************/ - /* */ - /* 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_cffload - - - /* read an offset from the index's stream current position */ - static FT_ULong - cff_index_read_offset( CFF_Index idx, - FT_Error *errorp ) - { - FT_Error error; - FT_Stream stream = idx->stream; - FT_Byte tmp[4]; - FT_ULong result = 0; - - - if ( !FT_STREAM_READ( tmp, idx->off_size ) ) - { - FT_Int nn; - - - for ( nn = 0; nn < idx->off_size; nn++ ) - result = ( result << 8 ) | tmp[nn]; - } - - *errorp = error; - return result; - } - - - static FT_Error - cff_index_init( CFF_Index idx, - FT_Stream stream, - FT_Bool load ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_UShort count; - - - FT_MEM_ZERO( idx, sizeof ( *idx ) ); - - idx->stream = stream; - idx->start = FT_STREAM_POS(); - if ( !FT_READ_USHORT( count ) && - count > 0 ) - { - FT_Byte offsize; - FT_ULong size; - - - /* there is at least one element; read the offset size, */ - /* then access the offset table to compute the index's total size */ - if ( FT_READ_BYTE( offsize ) ) - goto Exit; - - if ( offsize < 1 || offsize > 4 ) - { - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - idx->count = count; - idx->off_size = offsize; - size = (FT_ULong)( count + 1 ) * offsize; - - idx->data_offset = idx->start + 3 + size; - - if ( FT_STREAM_SKIP( size - offsize ) ) - goto Exit; - - size = cff_index_read_offset( idx, &error ); - if ( error ) - goto Exit; - - if ( size == 0 ) - { - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - idx->data_size = --size; - - if ( load ) - { - /* load the data */ - if ( FT_FRAME_EXTRACT( size, idx->bytes ) ) - goto Exit; - } - else - { - /* skip the data */ - if ( FT_STREAM_SKIP( size ) ) - goto Exit; - } - } - - Exit: - if ( error ) - FT_FREE( idx->offsets ); - - return error; - } - - - static void - cff_index_done( CFF_Index idx ) - { - if ( idx->stream ) - { - FT_Stream stream = idx->stream; - FT_Memory memory = stream->memory; - - - if ( idx->bytes ) - FT_FRAME_RELEASE( idx->bytes ); - - FT_FREE( idx->offsets ); - FT_MEM_ZERO( idx, sizeof ( *idx ) ); - } - } - - - static FT_Error - cff_index_load_offsets( CFF_Index idx ) - { - FT_Error error = FT_Err_Ok; - FT_Stream stream = idx->stream; - FT_Memory memory = stream->memory; - - - if ( idx->count > 0 && idx->offsets == NULL ) - { - FT_Byte offsize = idx->off_size; - FT_ULong data_size; - FT_Byte* p; - FT_Byte* p_end; - FT_ULong* poff; - - - data_size = (FT_ULong)( idx->count + 1 ) * offsize; - - if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || - FT_STREAM_SEEK( idx->start + 3 ) || - FT_FRAME_ENTER( data_size ) ) - goto Exit; - - poff = idx->offsets; - p = (FT_Byte*)stream->cursor; - p_end = p + data_size; - - switch ( offsize ) - { - case 1: - for ( ; p < p_end; p++, poff++ ) - poff[0] = p[0]; - break; - - case 2: - for ( ; p < p_end; p += 2, poff++ ) - poff[0] = FT_PEEK_USHORT( p ); - break; - - case 3: - for ( ; p < p_end; p += 3, poff++ ) - poff[0] = FT_PEEK_OFF3( p ); - break; - - default: - for ( ; p < p_end; p += 4, poff++ ) - poff[0] = FT_PEEK_ULONG( p ); - } - - FT_FRAME_EXIT(); - } - - Exit: - if ( error ) - FT_FREE( idx->offsets ); - - return error; - } - - - /* Allocate a table containing pointers to an index's elements. */ - /* The `pool' argument makes this function convert the index */ - /* entries to C-style strings (this is, NULL-terminated). */ - static FT_Error - cff_index_get_pointers( CFF_Index idx, - FT_Byte*** table, - FT_Byte** pool ) - { - FT_Error error = FT_Err_Ok; - FT_Memory memory = idx->stream->memory; - - FT_Byte** t = NULL; - FT_Byte* new_bytes = NULL; - - - *table = NULL; - - if ( idx->offsets == NULL ) - { - error = cff_index_load_offsets( idx ); - if ( error ) - goto Exit; - } - - if ( idx->count > 0 && - !FT_NEW_ARRAY( t, idx->count + 1 ) && - ( !pool || !FT_ALLOC( new_bytes, - idx->data_size + idx->count ) ) ) - { - FT_ULong n, cur_offset; - FT_ULong extra = 0; - FT_Byte* org_bytes = idx->bytes; - - - /* at this point, `idx->offsets' can't be NULL */ - cur_offset = idx->offsets[0] - 1; - - /* sanity check */ - if ( cur_offset >= idx->data_size ) - { - FT_TRACE0(( "cff_index_get_pointers:" - " invalid first offset value %d set to zero\n", - cur_offset )); - cur_offset = 0; - } - - if ( !pool ) - t[0] = org_bytes + cur_offset; - else - t[0] = new_bytes + cur_offset; - - for ( n = 1; n <= idx->count; n++ ) - { - FT_ULong next_offset = idx->offsets[n] - 1; - - - /* empty slot + two sanity checks for invalid offset tables */ - if ( next_offset == 0 || - next_offset < cur_offset || - ( next_offset >= idx->data_size && n < idx->count ) ) - next_offset = cur_offset; - - if ( !pool ) - t[n] = org_bytes + next_offset; - else - { - t[n] = new_bytes + next_offset + extra; - - if ( next_offset != cur_offset ) - { - FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] ); - t[n][0] = '\0'; - t[n] += 1; - extra++; - } - } - - cur_offset = next_offset; - } - *table = t; - - if ( pool ) - *pool = new_bytes; - } - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - cff_index_access_element( CFF_Index idx, - FT_UInt element, - FT_Byte** pbytes, - FT_ULong* pbyte_len ) - { - FT_Error error = FT_Err_Ok; - - - if ( idx && idx->count > element ) - { - /* compute start and end offsets */ - FT_Stream stream = idx->stream; - FT_ULong off1, off2 = 0; - - - /* load offsets from file or the offset table */ - if ( !idx->offsets ) - { - FT_ULong pos = element * idx->off_size; - - - if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) - goto Exit; - - off1 = cff_index_read_offset( idx, &error ); - if ( error ) - goto Exit; - - if ( off1 != 0 ) - { - do - { - element++; - off2 = cff_index_read_offset( idx, &error ); - } - while ( off2 == 0 && element < idx->count ); - } - } - else /* use offsets table */ - { - off1 = idx->offsets[element]; - if ( off1 ) - { - do - { - element++; - off2 = idx->offsets[element]; - - } while ( off2 == 0 && element < idx->count ); - } - } - - /* XXX: should check off2 does not exceed the end of this entry; */ - /* at present, only truncate off2 at the end of this stream */ - if ( off2 > stream->size + 1 || - idx->data_offset > stream->size - off2 + 1 ) - { - FT_ERROR(( "cff_index_access_element:" - " offset to next entry (%d)" - " exceeds the end of stream (%d)\n", - off2, stream->size - idx->data_offset + 1 )); - off2 = stream->size - idx->data_offset + 1; - } - - /* access element */ - if ( off1 && off2 > off1 ) - { - *pbyte_len = off2 - off1; - - if ( idx->bytes ) - { - /* this index was completely loaded in memory, that's easy */ - *pbytes = idx->bytes + off1 - 1; - } - else - { - /* this index is still on disk/file, access it through a frame */ - if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) || - FT_FRAME_EXTRACT( off2 - off1, *pbytes ) ) - goto Exit; - } - } - else - { - /* empty index element */ - *pbytes = 0; - *pbyte_len = 0; - } - } - else - error = FT_THROW( Invalid_Argument ); - - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - cff_index_forget_element( CFF_Index idx, - FT_Byte** pbytes ) - { - if ( idx->bytes == 0 ) - { - FT_Stream stream = idx->stream; - - - FT_FRAME_RELEASE( *pbytes ); - } - } - - - /* get an entry from Name INDEX */ - FT_LOCAL_DEF( FT_String* ) - cff_index_get_name( CFF_Font font, - FT_UInt element ) - { - CFF_Index idx = &font->name_index; - FT_Memory memory = idx->stream->memory; - FT_Byte* bytes; - FT_ULong byte_len; - FT_Error error; - FT_String* name = 0; - - - error = cff_index_access_element( idx, element, &bytes, &byte_len ); - if ( error ) - goto Exit; - - if ( !FT_ALLOC( name, byte_len + 1 ) ) - { - FT_MEM_COPY( name, bytes, byte_len ); - name[byte_len] = 0; - } - cff_index_forget_element( idx, &bytes ); - - Exit: - return name; - } - - - /* get an entry from String INDEX */ - FT_LOCAL_DEF( FT_String* ) - cff_index_get_string( CFF_Font font, - FT_UInt element ) - { - return ( element < font->num_strings ) - ? (FT_String*)font->strings[element] - : NULL; - } - - - FT_LOCAL_DEF( FT_String* ) - cff_index_get_sid_string( CFF_Font font, - FT_UInt sid ) - { - /* value 0xFFFFU indicates a missing dictionary entry */ - if ( sid == 0xFFFFU ) - return NULL; - - /* if it is not a standard string, return it */ - if ( sid > 390 ) - return cff_index_get_string( font, sid - 391 ); - - /* CID-keyed CFF fonts don't have glyph names */ - if ( !font->psnames ) - return NULL; - - /* this is a standard string */ - return (FT_String *)font->psnames->adobe_std_strings( sid ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** FD Select table support ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - - - static void - CFF_Done_FD_Select( CFF_FDSelect fdselect, - FT_Stream stream ) - { - if ( fdselect->data ) - FT_FRAME_RELEASE( fdselect->data ); - - fdselect->data_size = 0; - fdselect->format = 0; - fdselect->range_count = 0; - } - - - static FT_Error - CFF_Load_FD_Select( CFF_FDSelect fdselect, - FT_UInt num_glyphs, - FT_Stream stream, - FT_ULong offset ) - { - FT_Error error; - FT_Byte format; - FT_UInt num_ranges; - - - /* read format */ - if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) ) - goto Exit; - - fdselect->format = format; - fdselect->cache_count = 0; /* clear cache */ - - switch ( format ) - { - case 0: /* format 0, that's simple */ - fdselect->data_size = num_glyphs; - goto Load_Data; - - case 3: /* format 3, a tad more complex */ - if ( FT_READ_USHORT( num_ranges ) ) - goto Exit; - - fdselect->data_size = num_ranges * 3 + 2; - - Load_Data: - if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) ) - goto Exit; - break; - - default: /* hmm... that's wrong */ - error = FT_THROW( Invalid_File_Format ); - } - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Byte ) - cff_fd_select_get( CFF_FDSelect fdselect, - FT_UInt glyph_index ) - { - FT_Byte fd = 0; - - - switch ( fdselect->format ) - { - case 0: - fd = fdselect->data[glyph_index]; - break; - - case 3: - /* first, compare to cache */ - if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < - fdselect->cache_count ) - { - fd = fdselect->cache_fd; - break; - } - - /* then, lookup the ranges array */ - { - FT_Byte* p = fdselect->data; - FT_Byte* p_limit = p + fdselect->data_size; - FT_Byte fd2; - FT_UInt first, limit; - - - first = FT_NEXT_USHORT( p ); - do - { - if ( glyph_index < first ) - break; - - fd2 = *p++; - limit = FT_NEXT_USHORT( p ); - - if ( glyph_index < limit ) - { - fd = fd2; - - /* update cache */ - fdselect->cache_first = first; - fdselect->cache_count = limit-first; - fdselect->cache_fd = fd2; - break; - } - first = limit; - - } while ( p < p_limit ); - } - break; - - default: - ; - } - - return fd; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** CFF font support ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_Error - cff_charset_compute_cids( CFF_Charset charset, - FT_UInt num_glyphs, - FT_Memory memory ) - { - FT_Error error = FT_Err_Ok; - FT_UInt i; - FT_Long j; - FT_UShort max_cid = 0; - - - if ( charset->max_cid > 0 ) - goto Exit; - - for ( i = 0; i < num_glyphs; i++ ) - { - if ( charset->sids[i] > max_cid ) - max_cid = charset->sids[i]; - } - - if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) ) - goto Exit; - - /* When multiple GIDs map to the same CID, we choose the lowest */ - /* GID. This is not described in any spec, but it matches the */ - /* behaviour of recent Acroread versions. */ - for ( j = num_glyphs - 1; j >= 0 ; j-- ) - charset->cids[charset->sids[j]] = (FT_UShort)j; - - charset->max_cid = max_cid; - charset->num_glyphs = num_glyphs; - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_UInt ) - cff_charset_cid_to_gindex( CFF_Charset charset, - FT_UInt cid ) - { - FT_UInt result = 0; - - - if ( cid <= charset->max_cid ) - result = charset->cids[cid]; - - return result; - } - - - static void - cff_charset_free_cids( CFF_Charset charset, - FT_Memory memory ) - { - FT_FREE( charset->cids ); - charset->max_cid = 0; - } - - - static void - cff_charset_done( CFF_Charset charset, - FT_Stream stream ) - { - FT_Memory memory = stream->memory; - - - cff_charset_free_cids( charset, memory ); - - FT_FREE( charset->sids ); - charset->format = 0; - charset->offset = 0; - } - - - static FT_Error - cff_charset_load( CFF_Charset charset, - FT_UInt num_glyphs, - FT_Stream stream, - FT_ULong base_offset, - FT_ULong offset, - FT_Bool invert ) - { - FT_Memory memory = stream->memory; - FT_Error error = FT_Err_Ok; - FT_UShort glyph_sid; - - - /* If the the offset is greater than 2, we have to parse the */ - /* charset table. */ - if ( offset > 2 ) - { - FT_UInt j; - - - charset->offset = base_offset + offset; - - /* Get the format of the table. */ - if ( FT_STREAM_SEEK( charset->offset ) || - FT_READ_BYTE( charset->format ) ) - goto Exit; - - /* Allocate memory for sids. */ - if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) - goto Exit; - - /* assign the .notdef glyph */ - charset->sids[0] = 0; - - switch ( charset->format ) - { - case 0: - if ( num_glyphs > 0 ) - { - if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) ) - goto Exit; - - for ( j = 1; j < num_glyphs; j++ ) - charset->sids[j] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - } - break; - - case 1: - case 2: - { - FT_UInt nleft; - FT_UInt i; - - - j = 1; - - while ( j < num_glyphs ) - { - /* Read the first glyph sid of the range. */ - if ( FT_READ_USHORT( glyph_sid ) ) - goto Exit; - - /* Read the number of glyphs in the range. */ - if ( charset->format == 2 ) - { - if ( FT_READ_USHORT( nleft ) ) - goto Exit; - } - else - { - if ( FT_READ_BYTE( nleft ) ) - goto Exit; - } - - /* try to rescue some of the SIDs if `nleft' is too large */ - if ( glyph_sid > 0xFFFFL - nleft ) - { - FT_ERROR(( "cff_charset_load: invalid SID range trimmed" - " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid )); - nleft = ( FT_UInt )( 0xFFFFL - glyph_sid ); - } - - /* Fill in the range of sids -- `nleft + 1' glyphs. */ - for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) - charset->sids[j] = glyph_sid; - } - } - break; - - default: - FT_ERROR(( "cff_charset_load: invalid table format\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - } - else - { - /* Parse default tables corresponding to offset == 0, 1, or 2. */ - /* CFF specification intimates the following: */ - /* */ - /* In order to use a predefined charset, the following must be */ - /* true: The charset constructed for the glyphs in the font's */ - /* charstrings dictionary must match the predefined charset in */ - /* the first num_glyphs. */ - - charset->offset = offset; /* record charset type */ - - switch ( (FT_UInt)offset ) - { - case 0: - if ( num_glyphs > 229 ) - { - FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe ISO-Latin)\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* Allocate memory for sids. */ - if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) - goto Exit; - - /* Copy the predefined charset into the allocated memory. */ - FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs ); - - break; - - case 1: - if ( num_glyphs > 166 ) - { - FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert)\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* Allocate memory for sids. */ - if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) - goto Exit; - - /* Copy the predefined charset into the allocated memory. */ - FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs ); - - break; - - case 2: - if ( num_glyphs > 87 ) - { - FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert Subset)\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* Allocate memory for sids. */ - if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) - goto Exit; - - /* Copy the predefined charset into the allocated memory. */ - FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs ); - - break; - - default: - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - } - - /* we have to invert the `sids' array for subsetted CID-keyed fonts */ - if ( invert ) - error = cff_charset_compute_cids( charset, num_glyphs, memory ); - - Exit: - /* Clean up if there was an error. */ - if ( error ) - { - FT_FREE( charset->sids ); - FT_FREE( charset->cids ); - charset->format = 0; - charset->offset = 0; - charset->sids = 0; - } - - return error; - } - - - static void - cff_encoding_done( CFF_Encoding encoding ) - { - encoding->format = 0; - encoding->offset = 0; - encoding->count = 0; - } - - - static FT_Error - cff_encoding_load( CFF_Encoding encoding, - CFF_Charset charset, - FT_UInt num_glyphs, - FT_Stream stream, - FT_ULong base_offset, - FT_ULong offset ) - { - FT_Error error = FT_Err_Ok; - FT_UInt count; - FT_UInt j; - FT_UShort glyph_sid; - FT_UInt glyph_code; - - - /* Check for charset->sids. If we do not have this, we fail. */ - if ( !charset->sids ) - { - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* Zero out the code to gid/sid mappings. */ - for ( j = 0; j < 256; j++ ) - { - encoding->sids [j] = 0; - encoding->codes[j] = 0; - } - - /* Note: The encoding table in a CFF font is indexed by glyph index; */ - /* the first encoded glyph index is 1. Hence, we read the character */ - /* code (`glyph_code') at index j and make the assignment: */ - /* */ - /* encoding->codes[glyph_code] = j + 1 */ - /* */ - /* We also make the assignment: */ - /* */ - /* encoding->sids[glyph_code] = charset->sids[j + 1] */ - /* */ - /* This gives us both a code to GID and a code to SID mapping. */ - - if ( offset > 1 ) - { - encoding->offset = base_offset + offset; - - /* we need to parse the table to determine its size */ - if ( FT_STREAM_SEEK( encoding->offset ) || - FT_READ_BYTE( encoding->format ) || - FT_READ_BYTE( count ) ) - goto Exit; - - switch ( encoding->format & 0x7F ) - { - case 0: - { - FT_Byte* p; - - - /* By convention, GID 0 is always ".notdef" and is never */ - /* coded in the font. Hence, the number of codes found */ - /* in the table is `count+1'. */ - /* */ - encoding->count = count + 1; - - if ( FT_FRAME_ENTER( count ) ) - goto Exit; - - p = (FT_Byte*)stream->cursor; - - for ( j = 1; j <= count; j++ ) - { - glyph_code = *p++; - - /* Make sure j is not too big. */ - if ( j < num_glyphs ) - { - /* Assign code to GID mapping. */ - encoding->codes[glyph_code] = (FT_UShort)j; - - /* Assign code to SID mapping. */ - encoding->sids[glyph_code] = charset->sids[j]; - } - } - - FT_FRAME_EXIT(); - } - break; - - case 1: - { - FT_UInt nleft; - FT_UInt i = 1; - FT_UInt k; - - - encoding->count = 0; - - /* Parse the Format1 ranges. */ - for ( j = 0; j < count; j++, i += nleft ) - { - /* Read the first glyph code of the range. */ - if ( FT_READ_BYTE( glyph_code ) ) - goto Exit; - - /* Read the number of codes in the range. */ - if ( FT_READ_BYTE( nleft ) ) - goto Exit; - - /* Increment nleft, so we read `nleft + 1' codes/sids. */ - nleft++; - - /* compute max number of character codes */ - if ( (FT_UInt)nleft > encoding->count ) - encoding->count = nleft; - - /* Fill in the range of codes/sids. */ - for ( k = i; k < nleft + i; k++, glyph_code++ ) - { - /* Make sure k is not too big. */ - if ( k < num_glyphs && glyph_code < 256 ) - { - /* Assign code to GID mapping. */ - encoding->codes[glyph_code] = (FT_UShort)k; - - /* Assign code to SID mapping. */ - encoding->sids[glyph_code] = charset->sids[k]; - } - } - } - - /* simple check; one never knows what can be found in a font */ - if ( encoding->count > 256 ) - encoding->count = 256; - } - break; - - default: - FT_ERROR(( "cff_encoding_load: invalid table format\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* Parse supplemental encodings, if any. */ - if ( encoding->format & 0x80 ) - { - FT_UInt gindex; - - - /* count supplements */ - if ( FT_READ_BYTE( count ) ) - goto Exit; - - for ( j = 0; j < count; j++ ) - { - /* Read supplemental glyph code. */ - if ( FT_READ_BYTE( glyph_code ) ) - goto Exit; - - /* Read the SID associated with this glyph code. */ - if ( FT_READ_USHORT( glyph_sid ) ) - goto Exit; - - /* Assign code to SID mapping. */ - encoding->sids[glyph_code] = glyph_sid; - - /* First, look up GID which has been assigned to */ - /* SID glyph_sid. */ - for ( gindex = 0; gindex < num_glyphs; gindex++ ) - { - if ( charset->sids[gindex] == glyph_sid ) - { - encoding->codes[glyph_code] = (FT_UShort)gindex; - break; - } - } - } - } - } - else - { - /* We take into account the fact a CFF font can use a predefined */ - /* encoding without containing all of the glyphs encoded by this */ - /* encoding (see the note at the end of section 12 in the CFF */ - /* specification). */ - - switch ( (FT_UInt)offset ) - { - case 0: - /* First, copy the code to SID mapping. */ - FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); - goto Populate; - - case 1: - /* First, copy the code to SID mapping. */ - FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); - - Populate: - /* Construct code to GID mapping from code to SID mapping */ - /* and charset. */ - - encoding->count = 0; - - error = cff_charset_compute_cids( charset, num_glyphs, - stream->memory ); - if ( error ) - goto Exit; - - for ( j = 0; j < 256; j++ ) - { - FT_UInt sid = encoding->sids[j]; - FT_UInt gid = 0; - - - if ( sid ) - gid = cff_charset_cid_to_gindex( charset, sid ); - - if ( gid != 0 ) - { - encoding->codes[j] = (FT_UShort)gid; - encoding->count = j + 1; - } - else - { - encoding->codes[j] = 0; - encoding->sids [j] = 0; - } - } - break; - - default: - FT_ERROR(( "cff_encoding_load: invalid table format\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - } - - Exit: - - /* Clean up if there was an error. */ - return error; - } - - - static FT_Error - cff_subfont_load( CFF_SubFont font, - CFF_Index idx, - FT_UInt font_index, - FT_Stream stream, - FT_ULong base_offset, - FT_Library library ) - { - FT_Error error; - CFF_ParserRec parser; - FT_Byte* dict = NULL; - FT_ULong dict_len; - CFF_FontRecDict top = &font->font_dict; - CFF_Private priv = &font->private_dict; - - - cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); - - /* set defaults */ - FT_MEM_ZERO( top, sizeof ( *top ) ); - - top->underline_position = -( 100L << 16 ); - top->underline_thickness = 50L << 16; - top->charstring_type = 2; - top->font_matrix.xx = 0x10000L; - top->font_matrix.yy = 0x10000L; - top->cid_count = 8720; - - /* we use the implementation specific SID value 0xFFFF to indicate */ - /* missing entries */ - top->version = 0xFFFFU; - top->notice = 0xFFFFU; - top->copyright = 0xFFFFU; - top->full_name = 0xFFFFU; - top->family_name = 0xFFFFU; - top->weight = 0xFFFFU; - top->embedded_postscript = 0xFFFFU; - - top->cid_registry = 0xFFFFU; - top->cid_ordering = 0xFFFFU; - top->cid_font_name = 0xFFFFU; - - error = cff_index_access_element( idx, font_index, &dict, &dict_len ); - if ( !error ) - { - FT_TRACE4(( " top dictionary:\n" )); - error = cff_parser_run( &parser, dict, dict + dict_len ); - } - - cff_index_forget_element( idx, &dict ); - - if ( error ) - goto Exit; - - /* if it is a CID font, we stop there */ - if ( top->cid_registry != 0xFFFFU ) - goto Exit; - - /* parse the private dictionary, if any */ - if ( top->private_offset && top->private_size ) - { - /* set defaults */ - FT_MEM_ZERO( priv, sizeof ( *priv ) ); - - priv->blue_shift = 7; - priv->blue_fuzz = 1; - priv->lenIV = -1; - priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); - priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - - cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); - - if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || - FT_FRAME_ENTER( font->font_dict.private_size ) ) - goto Exit; - - FT_TRACE4(( " private dictionary:\n" )); - error = cff_parser_run( &parser, - (FT_Byte*)stream->cursor, - (FT_Byte*)stream->limit ); - FT_FRAME_EXIT(); - if ( error ) - goto Exit; - - /* ensure that `num_blue_values' is even */ - priv->num_blue_values &= ~1; - } - - /* read the local subrs, if any */ - if ( priv->local_subrs_offset ) - { - if ( FT_STREAM_SEEK( base_offset + top->private_offset + - priv->local_subrs_offset ) ) - goto Exit; - - error = cff_index_init( &font->local_subrs_index, stream, 1 ); - if ( error ) - goto Exit; - - error = cff_index_get_pointers( &font->local_subrs_index, - &font->local_subrs, NULL ); - if ( error ) - goto Exit; - } - - Exit: - return error; - } - - - static void - cff_subfont_done( FT_Memory memory, - CFF_SubFont subfont ) - { - if ( subfont ) - { - cff_index_done( &subfont->local_subrs_index ); - FT_FREE( subfont->local_subrs ); - } - } - - - FT_LOCAL_DEF( FT_Error ) - cff_font_load( FT_Library library, - FT_Stream stream, - FT_Int face_index, - CFF_Font font, - FT_Bool pure_cff ) - { - static const FT_Frame_Field cff_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE CFF_FontRec - - FT_FRAME_START( 4 ), - FT_FRAME_BYTE( version_major ), - FT_FRAME_BYTE( version_minor ), - FT_FRAME_BYTE( header_size ), - FT_FRAME_BYTE( absolute_offsize ), - FT_FRAME_END - }; - - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong base_offset; - CFF_FontRecDict dict; - CFF_IndexRec string_index; - FT_Int subfont_index; - - - FT_ZERO( font ); - FT_ZERO( &string_index ); - - font->stream = stream; - font->memory = memory; - dict = &font->top_font.font_dict; - base_offset = FT_STREAM_POS(); - - /* read CFF font header */ - if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) - goto Exit; - - /* check format */ - if ( font->version_major != 1 || - font->header_size < 4 || - font->absolute_offsize > 4 ) - { - FT_TRACE2(( " not a CFF font header\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - /* skip the rest of the header */ - if ( FT_STREAM_SKIP( font->header_size - 4 ) ) - goto Exit; - - /* read the name, top dict, string and global subrs index */ - if ( FT_SET_ERROR( cff_index_init( &font->name_index, - stream, 0 ) ) || - FT_SET_ERROR( cff_index_init( &font->font_dict_index, - stream, 0 ) ) || - FT_SET_ERROR( cff_index_init( &string_index, - stream, 1 ) ) || - FT_SET_ERROR( cff_index_init( &font->global_subrs_index, - stream, 1 ) ) || - FT_SET_ERROR( cff_index_get_pointers( &string_index, - &font->strings, - &font->string_pool ) ) ) - goto Exit; - - font->num_strings = string_index.count; - - if ( pure_cff ) - { - /* well, we don't really forget the `disabled' fonts... */ - subfont_index = face_index; - - if ( subfont_index >= (FT_Int)font->name_index.count ) - { - FT_ERROR(( "cff_font_load:" - " invalid subfont index for pure CFF font (%d)\n", - subfont_index )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - font->num_faces = font->name_index.count; - } - else - { - subfont_index = 0; - - if ( font->name_index.count > 1 ) - { - FT_ERROR(( "cff_font_load:" - " invalid CFF font with multiple subfonts\n" - " " - " in SFNT wrapper\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - } - - /* in case of a font format check, simply exit now */ - if ( face_index < 0 ) - goto Exit; - - /* now, parse the top-level font dictionary */ - FT_TRACE4(( "parsing top-level\n" )); - error = cff_subfont_load( &font->top_font, - &font->font_dict_index, - subfont_index, - stream, - base_offset, - library ); - if ( error ) - goto Exit; - - if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) - goto Exit; - - error = cff_index_init( &font->charstrings_index, stream, 0 ); - if ( error ) - goto Exit; - - /* now, check for a CID font */ - if ( dict->cid_registry != 0xFFFFU ) - { - CFF_IndexRec fd_index; - CFF_SubFont sub = NULL; - FT_UInt idx; - - - /* this is a CID-keyed font, we must now allocate a table of */ - /* sub-fonts, then load each of them separately */ - if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) - goto Exit; - - error = cff_index_init( &fd_index, stream, 0 ); - if ( error ) - goto Exit; - - if ( fd_index.count > CFF_MAX_CID_FONTS ) - { - FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); - goto Fail_CID; - } - - /* allocate & read each font dict independently */ - font->num_subfonts = fd_index.count; - if ( FT_NEW_ARRAY( sub, fd_index.count ) ) - goto Fail_CID; - - /* set up pointer table */ - for ( idx = 0; idx < fd_index.count; idx++ ) - font->subfonts[idx] = sub + idx; - - /* now load each subfont independently */ - for ( idx = 0; idx < fd_index.count; idx++ ) - { - sub = font->subfonts[idx]; - FT_TRACE4(( "parsing subfont %u\n", idx )); - error = cff_subfont_load( sub, &fd_index, idx, - stream, base_offset, library ); - if ( error ) - goto Fail_CID; - } - - /* now load the FD Select array */ - error = CFF_Load_FD_Select( &font->fd_select, - font->charstrings_index.count, - stream, - base_offset + dict->cid_fd_select_offset ); - - Fail_CID: - cff_index_done( &fd_index ); - - if ( error ) - goto Exit; - } - else - font->num_subfonts = 0; - - /* read the charstrings index now */ - if ( dict->charstrings_offset == 0 ) - { - FT_ERROR(( "cff_font_load: no charstrings offset\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - font->num_glyphs = font->charstrings_index.count; - - error = cff_index_get_pointers( &font->global_subrs_index, - &font->global_subrs, NULL ); - - if ( error ) - goto Exit; - - /* read the Charset and Encoding tables if available */ - if ( font->num_glyphs > 0 ) - { - FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); - - - error = cff_charset_load( &font->charset, font->num_glyphs, stream, - base_offset, dict->charset_offset, invert ); - if ( error ) - goto Exit; - - /* CID-keyed CFFs don't have an encoding */ - if ( dict->cid_registry == 0xFFFFU ) - { - error = cff_encoding_load( &font->encoding, - &font->charset, - font->num_glyphs, - stream, - base_offset, - dict->encoding_offset ); - if ( error ) - goto Exit; - } - } - - /* get the font name (/CIDFontName for CID-keyed fonts, */ - /* /FontName otherwise) */ - font->font_name = cff_index_get_name( font, subfont_index ); - - Exit: - cff_index_done( &string_index ); - - return error; - } - - - FT_LOCAL_DEF( void ) - cff_font_done( CFF_Font font ) - { - FT_Memory memory = font->memory; - FT_UInt idx; - - - cff_index_done( &font->global_subrs_index ); - cff_index_done( &font->font_dict_index ); - cff_index_done( &font->name_index ); - cff_index_done( &font->charstrings_index ); - - /* release font dictionaries, but only if working with */ - /* a CID keyed CFF font */ - if ( font->num_subfonts > 0 ) - { - for ( idx = 0; idx < font->num_subfonts; idx++ ) - cff_subfont_done( memory, font->subfonts[idx] ); - - /* the subfonts array has been allocated as a single block */ - FT_FREE( font->subfonts[0] ); - } - - cff_encoding_done( &font->encoding ); - cff_charset_done( &font->charset, font->stream ); - - cff_subfont_done( memory, &font->top_font ); - - CFF_Done_FD_Select( &font->fd_select, font->stream ); - - FT_FREE( font->font_info ); - - FT_FREE( font->font_name ); - FT_FREE( font->global_subrs ); - FT_FREE( font->strings ); - FT_FREE( font->string_pool ); - - if ( font->cf2_instance.finalizer ) - { - font->cf2_instance.finalizer( font->cf2_instance.data ); - FT_FREE( font->cf2_instance.data ); - } - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffload.h b/drivers/freetype/freetype/src/cff/cffload.h deleted file mode 100644 index 804961964b..0000000000 --- a/drivers/freetype/freetype/src/cff/cffload.h +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffload.h */ -/* */ -/* OpenType & CFF data/program tables loader (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2007, 2008, 2010 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 __CFFLOAD_H__ -#define __CFFLOAD_H__ - - -#include <ft2build.h> -#include "cfftypes.h" - - -FT_BEGIN_HEADER - - FT_LOCAL( FT_UShort ) - cff_get_standard_encoding( FT_UInt charcode ); - - - FT_LOCAL( FT_String* ) - cff_index_get_string( CFF_Font font, - FT_UInt element ); - - FT_LOCAL( FT_String* ) - cff_index_get_sid_string( CFF_Font font, - FT_UInt sid ); - - - FT_LOCAL( FT_Error ) - cff_index_access_element( CFF_Index idx, - FT_UInt element, - FT_Byte** pbytes, - FT_ULong* pbyte_len ); - - FT_LOCAL( void ) - cff_index_forget_element( CFF_Index idx, - FT_Byte** pbytes ); - - FT_LOCAL( FT_String* ) - cff_index_get_name( CFF_Font font, - FT_UInt element ); - - - FT_LOCAL( FT_UInt ) - cff_charset_cid_to_gindex( CFF_Charset charset, - FT_UInt cid ); - - - FT_LOCAL( FT_Error ) - cff_font_load( FT_Library library, - FT_Stream stream, - FT_Int face_index, - CFF_Font font, - FT_Bool pure_cff ); - - FT_LOCAL( void ) - cff_font_done( CFF_Font font ); - - - FT_LOCAL( FT_Byte ) - cff_fd_select_get( CFF_FDSelect fdselect, - FT_UInt glyph_index ); - - -FT_END_HEADER - -#endif /* __CFFLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffobjs.c b/drivers/freetype/freetype/src/cff/cffobjs.c deleted file mode 100644 index dd750d1041..0000000000 --- a/drivers/freetype/freetype/src/cff/cffobjs.c +++ /dev/null @@ -1,1077 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffobjs.c */ -/* */ -/* OpenType objects manager (body). */ -/* */ -/* Copyright 1996-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> - -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_STREAM_H -#include FT_ERRORS_H -#include FT_TRUETYPE_IDS_H -#include FT_TRUETYPE_TAGS_H -#include FT_INTERNAL_SFNT_H -#include FT_CFF_DRIVER_H - -#include "cffobjs.h" -#include "cffload.h" -#include "cffcmap.h" -#include "cffpic.h" - -#include "cfferrs.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_cffobjs - - - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /* Note that we store the global hints in the size's `internal' root */ - /* field. */ - /* */ - /*************************************************************************/ - - - static PSH_Globals_Funcs - cff_size_get_globals_funcs( CFF_Size size ) - { - CFF_Face face = (CFF_Face)size->root.face; - CFF_Font font = (CFF_Font)face->extra.data; - PSHinter_Service pshinter = font->pshinter; - FT_Module module; - - - module = FT_Get_Module( size->root.face->driver->root.library, - "pshinter" ); - return ( module && pshinter && pshinter->get_globals_funcs ) - ? pshinter->get_globals_funcs( module ) - : 0; - } - - - FT_LOCAL_DEF( void ) - cff_size_done( FT_Size cffsize ) /* CFF_Size */ - { - CFF_Size size = (CFF_Size)cffsize; - CFF_Face face = (CFF_Face)size->root.face; - CFF_Font font = (CFF_Font)face->extra.data; - CFF_Internal internal = (CFF_Internal)cffsize->internal; - - - if ( internal ) - { - PSH_Globals_Funcs funcs; - - - funcs = cff_size_get_globals_funcs( size ); - if ( funcs ) - { - FT_UInt i; - - - funcs->destroy( internal->topfont ); - - for ( i = font->num_subfonts; i > 0; i-- ) - funcs->destroy( internal->subfonts[i - 1] ); - } - - /* `internal' is freed by destroy_size (in ftobjs.c) */ - } - } - - - /* CFF and Type 1 private dictionaries have slightly different */ - /* structures; we need to synthesize a Type 1 dictionary on the fly */ - - static void - cff_make_private_dict( CFF_SubFont subfont, - PS_Private priv ) - { - CFF_Private cpriv = &subfont->private_dict; - FT_UInt n, count; - - - FT_MEM_ZERO( priv, sizeof ( *priv ) ); - - count = priv->num_blue_values = cpriv->num_blue_values; - for ( n = 0; n < count; n++ ) - priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; - - count = priv->num_other_blues = cpriv->num_other_blues; - for ( n = 0; n < count; n++ ) - priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; - - count = priv->num_family_blues = cpriv->num_family_blues; - for ( n = 0; n < count; n++ ) - priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; - - count = priv->num_family_other_blues = cpriv->num_family_other_blues; - for ( n = 0; n < count; n++ ) - priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; - - priv->blue_scale = cpriv->blue_scale; - priv->blue_shift = (FT_Int)cpriv->blue_shift; - priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz; - - priv->standard_width[0] = (FT_UShort)cpriv->standard_width; - priv->standard_height[0] = (FT_UShort)cpriv->standard_height; - - count = priv->num_snap_widths = cpriv->num_snap_widths; - for ( n = 0; n < count; n++ ) - priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; - - count = priv->num_snap_heights = cpriv->num_snap_heights; - for ( n = 0; n < count; n++ ) - priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; - - priv->force_bold = cpriv->force_bold; - priv->language_group = cpriv->language_group; - priv->lenIV = cpriv->lenIV; - } - - - FT_LOCAL_DEF( FT_Error ) - cff_size_init( FT_Size cffsize ) /* CFF_Size */ - { - CFF_Size size = (CFF_Size)cffsize; - FT_Error error = FT_Err_Ok; - PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); - - - if ( funcs ) - { - CFF_Face face = (CFF_Face)cffsize->face; - CFF_Font font = (CFF_Font)face->extra.data; - CFF_Internal internal = NULL; - - PS_PrivateRec priv; - FT_Memory memory = cffsize->face->memory; - - FT_UInt i; - - - if ( FT_NEW( internal ) ) - goto Exit; - - cff_make_private_dict( &font->top_font, &priv ); - error = funcs->create( cffsize->face->memory, &priv, - &internal->topfont ); - if ( error ) - goto Exit; - - for ( i = font->num_subfonts; i > 0; i-- ) - { - CFF_SubFont sub = font->subfonts[i - 1]; - - - cff_make_private_dict( sub, &priv ); - error = funcs->create( cffsize->face->memory, &priv, - &internal->subfonts[i - 1] ); - if ( error ) - goto Exit; - } - - cffsize->internal = (FT_Size_Internal)(void*)internal; - } - - size->strike_index = 0xFFFFFFFFUL; - - Exit: - return error; - } - - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - FT_LOCAL_DEF( FT_Error ) - cff_size_select( FT_Size size, - FT_ULong strike_index ) - { - CFF_Size cffsize = (CFF_Size)size; - PSH_Globals_Funcs funcs; - - - cffsize->strike_index = strike_index; - - FT_Select_Metrics( size->face, strike_index ); - - funcs = cff_size_get_globals_funcs( cffsize ); - - if ( funcs ) - { - CFF_Face face = (CFF_Face)size->face; - CFF_Font font = (CFF_Font)face->extra.data; - CFF_Internal internal = (CFF_Internal)size->internal; - - FT_ULong top_upm = font->top_font.font_dict.units_per_em; - FT_UInt i; - - - funcs->set_scale( internal->topfont, - size->metrics.x_scale, size->metrics.y_scale, - 0, 0 ); - - for ( i = font->num_subfonts; i > 0; i-- ) - { - CFF_SubFont sub = font->subfonts[i - 1]; - FT_ULong sub_upm = sub->font_dict.units_per_em; - FT_Pos x_scale, y_scale; - - - if ( top_upm != sub_upm ) - { - x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); - y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); - } - else - { - x_scale = size->metrics.x_scale; - y_scale = size->metrics.y_scale; - } - - funcs->set_scale( internal->subfonts[i - 1], - x_scale, y_scale, 0, 0 ); - } - } - - return FT_Err_Ok; - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - - FT_LOCAL_DEF( FT_Error ) - cff_size_request( FT_Size size, - FT_Size_Request req ) - { - CFF_Size cffsize = (CFF_Size)size; - PSH_Globals_Funcs funcs; - - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - if ( FT_HAS_FIXED_SIZES( size->face ) ) - { - CFF_Face cffface = (CFF_Face)size->face; - SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; - FT_ULong strike_index; - - - if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) ) - cffsize->strike_index = 0xFFFFFFFFUL; - else - return cff_size_select( size, strike_index ); - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - FT_Request_Metrics( size->face, req ); - - funcs = cff_size_get_globals_funcs( cffsize ); - - if ( funcs ) - { - CFF_Face cffface = (CFF_Face)size->face; - CFF_Font font = (CFF_Font)cffface->extra.data; - CFF_Internal internal = (CFF_Internal)size->internal; - - FT_ULong top_upm = font->top_font.font_dict.units_per_em; - FT_UInt i; - - - funcs->set_scale( internal->topfont, - size->metrics.x_scale, size->metrics.y_scale, - 0, 0 ); - - for ( i = font->num_subfonts; i > 0; i-- ) - { - CFF_SubFont sub = font->subfonts[i - 1]; - FT_ULong sub_upm = sub->font_dict.units_per_em; - FT_Pos x_scale, y_scale; - - - if ( top_upm != sub_upm ) - { - x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); - y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); - } - else - { - x_scale = size->metrics.x_scale; - y_scale = size->metrics.y_scale; - } - - funcs->set_scale( internal->subfonts[i - 1], - x_scale, y_scale, 0, 0 ); - } - } - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* SLOT FUNCTIONS */ - /* */ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - cff_slot_done( FT_GlyphSlot slot ) - { - slot->internal->glyph_hints = 0; - } - - - FT_LOCAL_DEF( FT_Error ) - cff_slot_init( FT_GlyphSlot slot ) - { - CFF_Face face = (CFF_Face)slot->face; - CFF_Font font = (CFF_Font)face->extra.data; - PSHinter_Service pshinter = font->pshinter; - - - if ( pshinter ) - { - FT_Module module; - - - module = FT_Get_Module( slot->face->driver->root.library, - "pshinter" ); - if ( module ) - { - T2_Hints_Funcs funcs; - - - funcs = pshinter->get_t2_funcs( module ); - slot->internal->glyph_hints = (void*)funcs; - } - } - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - static FT_String* - cff_strcpy( FT_Memory memory, - const FT_String* source ) - { - FT_Error error; - FT_String* result; - - - (void)FT_STRDUP( result, source ); - - FT_UNUSED( error ); - - return result; - } - - - /* Strip all subset prefixes of the form `ABCDEF+'. Usually, there */ - /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold' */ - /* have been seen in the wild. */ - - static void - remove_subset_prefix( FT_String* name ) - { - FT_Int32 idx = 0; - FT_Int32 length = (FT_Int32)strlen( name ) + 1; - FT_Bool continue_search = 1; - - - while ( continue_search ) - { - if ( length >= 7 && name[6] == '+' ) - { - for ( idx = 0; idx < 6; idx++ ) - { - /* ASCII uppercase letters */ - if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) ) - continue_search = 0; - } - - if ( continue_search ) - { - for ( idx = 7; idx < length; idx++ ) - name[idx - 7] = name[idx]; - length -= 7; - } - } - else - continue_search = 0; - } - } - - - /* Remove the style part from the family name (if present). */ - - static void - remove_style( FT_String* family_name, - const FT_String* style_name ) - { - FT_Int32 family_name_length, style_name_length; - - - family_name_length = (FT_Int32)strlen( family_name ); - style_name_length = (FT_Int32)strlen( style_name ); - - if ( family_name_length > style_name_length ) - { - FT_Int idx; - - - for ( idx = 1; idx <= style_name_length; ++idx ) - { - if ( family_name[family_name_length - idx] != - style_name[style_name_length - idx] ) - break; - } - - if ( idx > style_name_length ) - { - /* family_name ends with style_name; remove it */ - idx = family_name_length - style_name_length - 1; - - /* also remove special characters */ - /* between real family name and style */ - while ( idx > 0 && - ( family_name[idx] == '-' || - family_name[idx] == ' ' || - family_name[idx] == '_' || - family_name[idx] == '+' ) ) - --idx; - - if ( idx > 0 ) - family_name[idx + 1] = '\0'; - } - } - } - - - FT_LOCAL_DEF( FT_Error ) - cff_face_init( FT_Stream stream, - FT_Face cffface, /* CFF_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - CFF_Face face = (CFF_Face)cffface; - FT_Error error; - SFNT_Service sfnt; - FT_Service_PsCMaps psnames; - PSHinter_Service pshinter; - FT_Bool pure_cff = 1; - FT_Bool sfnt_format = 0; - FT_Library library = cffface->driver->root.library; - - - sfnt = (SFNT_Service)FT_Get_Module_Interface( - library, "sfnt" ); - if ( !sfnt ) - { - FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" )); - error = FT_THROW( Missing_Module ); - goto Exit; - } - - FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); - - pshinter = (PSHinter_Service)FT_Get_Module_Interface( - library, "pshinter" ); - - FT_TRACE2(( "CFF driver\n" )); - - /* create input stream from resource */ - if ( FT_STREAM_SEEK( 0 ) ) - goto Exit; - - /* check whether we have a valid OpenType file */ - error = sfnt->init_face( stream, face, face_index, num_params, params ); - if ( !error ) - { - if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */ - { - FT_TRACE2(( " not an OpenType/CFF font\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - /* if we are performing a simple font format check, exit immediately */ - if ( face_index < 0 ) - return FT_Err_Ok; - - sfnt_format = 1; - - /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ - /* font; in the latter case it doesn't have a `head' table */ - error = face->goto_table( face, TTAG_head, stream, 0 ); - if ( !error ) - { - pure_cff = 0; - - /* load font directory */ - error = sfnt->load_face( stream, face, face_index, - num_params, params ); - if ( error ) - goto Exit; - } - else - { - /* load the `cmap' table explicitly */ - error = sfnt->load_cmap( face, stream ); - if ( error ) - goto Exit; - } - - /* now load the CFF part of the file */ - error = face->goto_table( face, TTAG_CFF, stream, 0 ); - if ( error ) - goto Exit; - } - else - { - /* rewind to start of file; we are going to load a pure-CFF font */ - if ( FT_STREAM_SEEK( 0 ) ) - goto Exit; - error = FT_Err_Ok; - } - - /* now load and parse the CFF table in the file */ - { - CFF_Font cff = NULL; - CFF_FontRecDict dict; - FT_Memory memory = cffface->memory; - FT_Int32 flags; - FT_UInt i; - - - if ( FT_NEW( cff ) ) - goto Exit; - - face->extra.data = cff; - error = cff_font_load( library, stream, face_index, cff, pure_cff ); - if ( error ) - goto Exit; - - cff->pshinter = pshinter; - cff->psnames = psnames; - - cffface->face_index = face_index; - - /* Complement the root flags with some interesting information. */ - /* Note that this is only necessary for pure CFF and CEF fonts; */ - /* SFNT based fonts use the `name' table instead. */ - - cffface->num_glyphs = cff->num_glyphs; - - dict = &cff->top_font.font_dict; - - /* we need the `PSNames' module for CFF and CEF formats */ - /* which aren't CID-keyed */ - if ( dict->cid_registry == 0xFFFFU && !psnames ) - { - FT_ERROR(( "cff_face_init:" - " cannot open CFF & CEF fonts\n" - " " - " without the `PSNames' module\n" )); - error = FT_THROW( Missing_Module ); - goto Exit; - } - -#ifdef FT_DEBUG_LEVEL_TRACE - { - FT_UInt idx; - FT_String* s; - - - FT_TRACE4(( "SIDs\n" )); - - /* dump string index, including default strings for convenience */ - for ( idx = 0; idx < cff->num_strings + 390; idx++ ) - { - s = cff_index_get_sid_string( cff, idx ); - if ( s ) - FT_TRACE4((" %5d %s\n", idx, s )); - } - } -#endif /* FT_DEBUG_LEVEL_TRACE */ - - if ( !dict->has_font_matrix ) - dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; - - /* Normalize the font matrix so that `matrix->xx' is 1; the */ - /* scaling is done with `units_per_em' then (at this point, */ - /* it already contains the scaling factor, but without */ - /* normalization of the matrix). */ - /* */ - /* Note that the offsets must be expressed in integer font */ - /* units. */ - - { - FT_Matrix* matrix = &dict->font_matrix; - FT_Vector* offset = &dict->font_offset; - FT_ULong* upm = &dict->units_per_em; - FT_Fixed temp = FT_ABS( matrix->yy ); - - - if ( temp != 0x10000L ) - { - *upm = FT_DivFix( *upm, temp ); - - matrix->xx = FT_DivFix( matrix->xx, temp ); - matrix->yx = FT_DivFix( matrix->yx, temp ); - matrix->xy = FT_DivFix( matrix->xy, temp ); - matrix->yy = FT_DivFix( matrix->yy, temp ); - offset->x = FT_DivFix( offset->x, temp ); - offset->y = FT_DivFix( offset->y, temp ); - } - - offset->x >>= 16; - offset->y >>= 16; - } - - for ( i = cff->num_subfonts; i > 0; i-- ) - { - CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; - CFF_FontRecDict top = &cff->top_font.font_dict; - - FT_Matrix* matrix; - FT_Vector* offset; - FT_ULong* upm; - FT_Fixed temp; - - - if ( sub->has_font_matrix ) - { - FT_Long scaling; - - - /* if we have a top-level matrix, */ - /* concatenate the subfont matrix */ - - if ( top->has_font_matrix ) - { - if ( top->units_per_em > 1 && sub->units_per_em > 1 ) - scaling = FT_MIN( top->units_per_em, sub->units_per_em ); - else - scaling = 1; - - FT_Matrix_Multiply_Scaled( &top->font_matrix, - &sub->font_matrix, - scaling ); - FT_Vector_Transform_Scaled( &sub->font_offset, - &top->font_matrix, - scaling ); - - sub->units_per_em = FT_MulDiv( sub->units_per_em, - top->units_per_em, - scaling ); - } - } - else - { - sub->font_matrix = top->font_matrix; - sub->font_offset = top->font_offset; - - sub->units_per_em = top->units_per_em; - } - - matrix = &sub->font_matrix; - offset = &sub->font_offset; - upm = &sub->units_per_em; - temp = FT_ABS( matrix->yy ); - - if ( temp != 0x10000L ) - { - *upm = FT_DivFix( *upm, temp ); - - matrix->xx = FT_DivFix( matrix->xx, temp ); - matrix->yx = FT_DivFix( matrix->yx, temp ); - matrix->xy = FT_DivFix( matrix->xy, temp ); - matrix->yy = FT_DivFix( matrix->yy, temp ); - offset->x = FT_DivFix( offset->x, temp ); - offset->y = FT_DivFix( offset->y, temp ); - } - - offset->x >>= 16; - offset->y >>= 16; - } - - if ( pure_cff ) - { - char* style_name = NULL; - - - /* set up num_faces */ - cffface->num_faces = cff->num_faces; - - /* compute number of glyphs */ - if ( dict->cid_registry != 0xFFFFU ) - cffface->num_glyphs = cff->charset.max_cid + 1; - else - cffface->num_glyphs = cff->charstrings_index.count; - - /* set global bbox, as well as EM size */ - cffface->bbox.xMin = dict->font_bbox.xMin >> 16; - cffface->bbox.yMin = dict->font_bbox.yMin >> 16; - /* no `U' suffix here to 0xFFFF! */ - cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16; - cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16; - - cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); - - cffface->ascender = (FT_Short)( cffface->bbox.yMax ); - cffface->descender = (FT_Short)( cffface->bbox.yMin ); - - cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 ); - if ( cffface->height < cffface->ascender - cffface->descender ) - cffface->height = (FT_Short)( cffface->ascender - cffface->descender ); - - cffface->underline_position = - (FT_Short)( dict->underline_position >> 16 ); - cffface->underline_thickness = - (FT_Short)( dict->underline_thickness >> 16 ); - - /* retrieve font family & style name */ - cffface->family_name = cff_index_get_name( cff, face_index ); - if ( cffface->family_name ) - { - char* full = cff_index_get_sid_string( cff, - dict->full_name ); - char* fullp = full; - char* family = cffface->family_name; - char* family_name = NULL; - - - remove_subset_prefix( cffface->family_name ); - - if ( dict->family_name ) - { - family_name = cff_index_get_sid_string( cff, - dict->family_name ); - if ( family_name ) - family = family_name; - } - - /* We try to extract the style name from the full name. */ - /* We need to ignore spaces and dashes during the search. */ - if ( full && family ) - { - while ( *fullp ) - { - /* skip common characters at the start of both strings */ - if ( *fullp == *family ) - { - family++; - fullp++; - continue; - } - - /* ignore spaces and dashes in full name during comparison */ - if ( *fullp == ' ' || *fullp == '-' ) - { - fullp++; - continue; - } - - /* ignore spaces and dashes in family name during comparison */ - if ( *family == ' ' || *family == '-' ) - { - family++; - continue; - } - - if ( !*family && *fullp ) - { - /* The full name begins with the same characters as the */ - /* family name, with spaces and dashes removed. In this */ - /* case, the remaining string in `fullp' will be used as */ - /* the style name. */ - style_name = cff_strcpy( memory, fullp ); - - /* remove the style part from the family name (if present) */ - remove_style( cffface->family_name, style_name ); - } - break; - } - } - } - else - { - char *cid_font_name = - cff_index_get_sid_string( cff, - dict->cid_font_name ); - - - /* do we have a `/FontName' for a CID-keyed font? */ - if ( cid_font_name ) - cffface->family_name = cff_strcpy( memory, cid_font_name ); - } - - if ( style_name ) - cffface->style_name = style_name; - else - /* assume "Regular" style if we don't know better */ - cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); - - /*******************************************************************/ - /* */ - /* Compute face flags. */ - /* */ - flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ - FT_FACE_FLAG_HINTER; /* has native hinter */ - - if ( sfnt_format ) - flags |= FT_FACE_FLAG_SFNT; - - /* fixed width font? */ - if ( dict->is_fixed_pitch ) - flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ -#if 0 - /* kerning available? */ - if ( face->kern_pairs ) - flags |= FT_FACE_FLAG_KERNING; -#endif - - cffface->face_flags = flags; - - /*******************************************************************/ - /* */ - /* Compute style flags. */ - /* */ - flags = 0; - - if ( dict->italic_angle ) - flags |= FT_STYLE_FLAG_ITALIC; - - { - char *weight = cff_index_get_sid_string( cff, - dict->weight ); - - - if ( weight ) - if ( !ft_strcmp( weight, "Bold" ) || - !ft_strcmp( weight, "Black" ) ) - flags |= FT_STYLE_FLAG_BOLD; - } - - /* double check */ - if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name ) - if ( !ft_strncmp( cffface->style_name, "Bold", 4 ) || - !ft_strncmp( cffface->style_name, "Black", 5 ) ) - flags |= FT_STYLE_FLAG_BOLD; - - cffface->style_flags = flags; - } - - -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ - /* has unset this flag because of the 3.0 `post' table. */ - if ( dict->cid_registry == 0xFFFFU ) - cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; -#endif - - if ( dict->cid_registry != 0xFFFFU && pure_cff ) - cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; - - - /*******************************************************************/ - /* */ - /* Compute char maps. */ - /* */ - - /* Try to synthesize a Unicode charmap if there is none available */ - /* already. If an OpenType font contains a Unicode "cmap", we */ - /* will use it, whatever be in the CFF part of the file. */ - { - FT_CharMapRec cmaprec; - FT_CharMap cmap; - FT_UInt nn; - CFF_Encoding encoding = &cff->encoding; - - - for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ ) - { - cmap = cffface->charmaps[nn]; - - /* Windows Unicode? */ - if ( cmap->platform_id == TT_PLATFORM_MICROSOFT && - cmap->encoding_id == TT_MS_ID_UNICODE_CS ) - goto Skip_Unicode; - - /* Apple Unicode platform id? */ - if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE ) - goto Skip_Unicode; /* Apple Unicode */ - } - - /* since CID-keyed fonts don't contain glyph names, we can't */ - /* construct a cmap */ - if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) - goto Exit; - -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "cff_face_init: no Unicode cmap is found, " - "and too many subtables (%d) to add synthesized cmap\n", - nn )); - goto Exit; - } -#endif - - /* we didn't find a Unicode charmap -- synthesize one */ - cmaprec.face = cffface; - cmaprec.platform_id = TT_PLATFORM_MICROSOFT; - cmaprec.encoding_id = TT_MS_ID_UNICODE_CS; - cmaprec.encoding = FT_ENCODING_UNICODE; - - nn = (FT_UInt)cffface->num_charmaps; - - error = FT_CMap_New( &CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, - &cmaprec, NULL ); - if ( error && - FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) - goto Exit; - error = FT_Err_Ok; - - /* if no Unicode charmap was previously selected, select this one */ - if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) - cffface->charmap = cffface->charmaps[nn]; - - Skip_Unicode: -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( nn > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "cff_face_init: Unicode cmap is found, " - "but too many preceding subtables (%d) to access\n", - nn - 1 )); - goto Exit; - } -#endif - if ( encoding->count > 0 ) - { - FT_CMap_Class clazz; - - - cmaprec.face = cffface; - cmaprec.platform_id = TT_PLATFORM_ADOBE; /* Adobe platform id */ - - if ( encoding->offset == 0 ) - { - cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; - cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; - clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; - } - else if ( encoding->offset == 1 ) - { - cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; - cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; - clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; - } - else - { - cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; - cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; - clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; - } - - error = FT_CMap_New( clazz, NULL, &cmaprec, NULL ); - } - } - } - - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - cff_face_done( FT_Face cffface ) /* CFF_Face */ - { - CFF_Face face = (CFF_Face)cffface; - FT_Memory memory; - SFNT_Service sfnt; - - - if ( !face ) - return; - - memory = cffface->memory; - sfnt = (SFNT_Service)face->sfnt; - - if ( sfnt ) - sfnt->done_face( face ); - - { - CFF_Font cff = (CFF_Font)face->extra.data; - - - if ( cff ) - { - cff_font_done( cff ); - FT_FREE( face->extra.data ); - } - } - } - - - FT_LOCAL_DEF( FT_Error ) - cff_driver_init( FT_Module module ) /* CFF_Driver */ - { - CFF_Driver driver = (CFF_Driver)module; - - - /* set default property values */ -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - driver->hinting_engine = FT_CFF_HINTING_FREETYPE; -#else - driver->hinting_engine = FT_CFF_HINTING_ADOBE; -#endif - driver->no_stem_darkening = FALSE; - - return FT_Err_Ok; - } - - - FT_LOCAL_DEF( void ) - cff_driver_done( FT_Module module ) /* CFF_Driver */ - { - FT_UNUSED( module ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffobjs.h b/drivers/freetype/freetype/src/cff/cffobjs.h deleted file mode 100644 index b375c20c74..0000000000 --- a/drivers/freetype/freetype/src/cff/cffobjs.h +++ /dev/null @@ -1,183 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffobjs.h */ -/* */ -/* OpenType objects manager (specification). */ -/* */ -/* Copyright 1996-2004, 2006-2008, 2013 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 __CFFOBJS_H__ -#define __CFFOBJS_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include "cfftypes.h" -#include FT_INTERNAL_TRUETYPE_TYPES_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_Driver */ - /* */ - /* <Description> */ - /* A handle to an OpenType driver object. */ - /* */ - typedef struct CFF_DriverRec_* CFF_Driver; - - typedef TT_Face CFF_Face; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_Size */ - /* */ - /* <Description> */ - /* A handle to an OpenType size object. */ - /* */ - typedef struct CFF_SizeRec_ - { - FT_SizeRec root; - FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ - - } CFF_SizeRec, *CFF_Size; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to an OpenType glyph slot object. */ - /* */ - typedef struct CFF_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - } CFF_GlyphSlotRec, *CFF_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_Internal */ - /* */ - /* <Description> */ - /* The interface to the `internal' field of `FT_Size'. */ - /* */ - typedef struct CFF_InternalRec_ - { - PSH_Globals topfont; - PSH_Globals subfonts[CFF_MAX_CID_FONTS]; - - } CFF_InternalRec, *CFF_Internal; - - - /*************************************************************************/ - /* */ - /* Subglyph transformation record. */ - /* */ - typedef struct CFF_Transform_ - { - FT_Fixed xx, xy; /* transformation matrix coefficients */ - FT_Fixed yx, yy; - FT_F26Dot6 ox, oy; /* offsets */ - - } CFF_Transform; - - - /***********************************************************************/ - /* */ - /* CFF driver class. */ - /* */ - typedef struct CFF_DriverRec_ - { - FT_DriverRec root; - - FT_UInt hinting_engine; - FT_Bool no_stem_darkening; - - } CFF_DriverRec; - - - FT_LOCAL( FT_Error ) - cff_size_init( FT_Size size ); /* CFF_Size */ - - FT_LOCAL( void ) - cff_size_done( FT_Size size ); /* CFF_Size */ - - FT_LOCAL( FT_Error ) - cff_size_request( FT_Size size, - FT_Size_Request req ); - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - FT_LOCAL( FT_Error ) - cff_size_select( FT_Size size, - FT_ULong strike_index ); - -#endif - - FT_LOCAL( void ) - cff_slot_done( FT_GlyphSlot slot ); - - FT_LOCAL( FT_Error ) - cff_slot_init( FT_GlyphSlot slot ); - - - /*************************************************************************/ - /* */ - /* Face functions */ - /* */ - FT_LOCAL( FT_Error ) - cff_face_init( FT_Stream stream, - FT_Face face, /* CFF_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - FT_LOCAL( void ) - cff_face_done( FT_Face face ); /* CFF_Face */ - - - /*************************************************************************/ - /* */ - /* Driver functions */ - /* */ - FT_LOCAL( FT_Error ) - cff_driver_init( FT_Module module ); /* CFF_Driver */ - - FT_LOCAL( void ) - cff_driver_done( FT_Module module ); /* CFF_Driver */ - - -FT_END_HEADER - -#endif /* __CFFOBJS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffparse.c b/drivers/freetype/freetype/src/cff/cffparse.c deleted file mode 100644 index 96222120b0..0000000000 --- a/drivers/freetype/freetype/src/cff/cffparse.c +++ /dev/null @@ -1,1177 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffparse.c */ -/* */ -/* CFF token stream parser (body) */ -/* */ -/* Copyright 1996-2004, 2007-2013 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 "cffparse.h" -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_DEBUG_H - -#include "cfferrs.h" -#include "cffpic.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_cffparse - - - FT_LOCAL_DEF( void ) - cff_parser_init( CFF_Parser parser, - FT_UInt code, - void* object, - FT_Library library) - { - FT_MEM_ZERO( parser, sizeof ( *parser ) ); - - parser->top = parser->stack; - parser->object_code = code; - parser->object = object; - parser->library = library; - } - - - /* read an integer */ - static FT_Long - cff_parse_integer( FT_Byte* start, - FT_Byte* limit ) - { - FT_Byte* p = start; - FT_Int v = *p++; - FT_Long val = 0; - - - if ( v == 28 ) - { - if ( p + 2 > limit ) - goto Bad; - - val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] ); - p += 2; - } - else if ( v == 29 ) - { - if ( p + 4 > limit ) - goto Bad; - - val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) | - ( (FT_ULong)p[1] << 16 ) | - ( (FT_ULong)p[2] << 8 ) | - (FT_ULong)p[3] ); - p += 4; - } - else if ( v < 247 ) - { - val = v - 139; - } - else if ( v < 251 ) - { - if ( p + 1 > limit ) - goto Bad; - - val = ( v - 247 ) * 256 + p[0] + 108; - p++; - } - else - { - if ( p + 1 > limit ) - goto Bad; - - val = -( v - 251 ) * 256 - p[0] - 108; - p++; - } - - Exit: - return val; - - Bad: - val = 0; - FT_TRACE4(( "!!!END OF DATA:!!!" )); - goto Exit; - } - - - static const FT_Long power_tens[] = - { - 1L, - 10L, - 100L, - 1000L, - 10000L, - 100000L, - 1000000L, - 10000000L, - 100000000L, - 1000000000L - }; - - - /* read a real */ - static FT_Fixed - cff_parse_real( FT_Byte* start, - FT_Byte* limit, - FT_Long power_ten, - FT_Long* scaling ) - { - FT_Byte* p = start; - FT_UInt nib; - FT_UInt phase; - - FT_Long result, number, exponent; - FT_Int sign = 0, exponent_sign = 0, have_overflow = 0; - FT_Long exponent_add, integer_length, fraction_length; - - - if ( scaling ) - *scaling = 0; - - result = 0; - - number = 0; - exponent = 0; - - exponent_add = 0; - integer_length = 0; - fraction_length = 0; - - /* First of all, read the integer part. */ - phase = 4; - - for (;;) - { - /* If we entered this iteration with phase == 4, we need to */ - /* read a new byte. This also skips past the initial 0x1E. */ - if ( phase ) - { - p++; - - /* Make sure we don't read past the end. */ - if ( p >= limit ) - goto Bad; - } - - /* Get the nibble. */ - nib = ( p[0] >> phase ) & 0xF; - phase = 4 - phase; - - if ( nib == 0xE ) - sign = 1; - else if ( nib > 9 ) - break; - else - { - /* Increase exponent if we can't add the digit. */ - if ( number >= 0xCCCCCCCL ) - exponent_add++; - /* Skip leading zeros. */ - else if ( nib || number ) - { - integer_length++; - number = number * 10 + nib; - } - } - } - - /* Read fraction part, if any. */ - if ( nib == 0xa ) - for (;;) - { - /* If we entered this iteration with phase == 4, we need */ - /* to read a new byte. */ - if ( phase ) - { - p++; - - /* Make sure we don't read past the end. */ - if ( p >= limit ) - goto Bad; - } - - /* Get the nibble. */ - nib = ( p[0] >> phase ) & 0xF; - phase = 4 - phase; - if ( nib >= 10 ) - break; - - /* Skip leading zeros if possible. */ - if ( !nib && !number ) - exponent_add--; - /* Only add digit if we don't overflow. */ - else if ( number < 0xCCCCCCCL && fraction_length < 9 ) - { - fraction_length++; - number = number * 10 + nib; - } - } - - /* Read exponent, if any. */ - if ( nib == 12 ) - { - exponent_sign = 1; - nib = 11; - } - - if ( nib == 11 ) - { - for (;;) - { - /* If we entered this iteration with phase == 4, */ - /* we need to read a new byte. */ - if ( phase ) - { - p++; - - /* Make sure we don't read past the end. */ - if ( p >= limit ) - goto Bad; - } - - /* Get the nibble. */ - nib = ( p[0] >> phase ) & 0xF; - phase = 4 - phase; - if ( nib >= 10 ) - break; - - /* Arbitrarily limit exponent. */ - if ( exponent > 1000 ) - have_overflow = 1; - else - exponent = exponent * 10 + nib; - } - - if ( exponent_sign ) - exponent = -exponent; - } - - if ( !number ) - goto Exit; - - if ( have_overflow ) - { - if ( exponent_sign ) - goto Underflow; - else - goto Overflow; - } - - /* We don't check `power_ten' and `exponent_add'. */ - exponent += power_ten + exponent_add; - - if ( scaling ) - { - /* Only use `fraction_length'. */ - fraction_length += integer_length; - exponent += integer_length; - - if ( fraction_length <= 5 ) - { - if ( number > 0x7FFFL ) - { - result = FT_DivFix( number, 10 ); - *scaling = exponent - fraction_length + 1; - } - else - { - if ( exponent > 0 ) - { - FT_Long new_fraction_length, shift; - - - /* Make `scaling' as small as possible. */ - new_fraction_length = FT_MIN( exponent, 5 ); - shift = new_fraction_length - fraction_length; - - if ( shift > 0 ) - { - exponent -= new_fraction_length; - number *= power_tens[shift]; - if ( number > 0x7FFFL ) - { - number /= 10; - exponent += 1; - } - } - else - exponent -= fraction_length; - } - else - exponent -= fraction_length; - - result = (FT_Long)( (FT_ULong)number << 16 ); - *scaling = exponent; - } - } - else - { - if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL ) - { - result = FT_DivFix( number, power_tens[fraction_length - 4] ); - *scaling = exponent - 4; - } - else - { - result = FT_DivFix( number, power_tens[fraction_length - 5] ); - *scaling = exponent - 5; - } - } - } - else - { - integer_length += exponent; - fraction_length -= exponent; - - if ( integer_length > 5 ) - goto Overflow; - if ( integer_length < -5 ) - goto Underflow; - - /* Remove non-significant digits. */ - if ( integer_length < 0 ) - { - number /= power_tens[-integer_length]; - fraction_length += integer_length; - } - - /* this can only happen if exponent was non-zero */ - if ( fraction_length == 10 ) - { - number /= 10; - fraction_length -= 1; - } - - /* Convert into 16.16 format. */ - if ( fraction_length > 0 ) - { - if ( ( number / power_tens[fraction_length] ) > 0x7FFFL ) - goto Exit; - - result = FT_DivFix( number, power_tens[fraction_length] ); - } - else - { - number *= power_tens[-fraction_length]; - - if ( number > 0x7FFFL ) - goto Overflow; - - result = (FT_Long)( (FT_ULong)number << 16 ); - } - } - - Exit: - if ( sign ) - result = -result; - - return result; - - Overflow: - result = 0x7FFFFFFFL; - FT_TRACE4(( "!!!OVERFLOW:!!!" )); - goto Exit; - - Underflow: - result = 0; - FT_TRACE4(( "!!!UNDERFLOW:!!!" )); - goto Exit; - - Bad: - result = 0; - FT_TRACE4(( "!!!END OF DATA:!!!" )); - goto Exit; - } - - - /* read a number, either integer or real */ - static FT_Long - cff_parse_num( FT_Byte** d ) - { - return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) - : cff_parse_integer( d[0], d[1] ); - } - - - /* read a floating point number, either integer or real */ - static FT_Fixed - do_fixed( FT_Byte** d, - FT_Long scaling ) - { - if ( **d == 30 ) - return cff_parse_real( d[0], d[1], scaling, NULL ); - else - { - FT_Long val = cff_parse_integer( d[0], d[1] ); - - - if ( scaling ) - val *= power_tens[scaling]; - - if ( val > 0x7FFF ) - { - val = 0x7FFFFFFFL; - goto Overflow; - } - else if ( val < -0x7FFF ) - { - val = -0x7FFFFFFFL; - goto Overflow; - } - - return (FT_Long)( (FT_ULong)val << 16 ); - - Overflow: - FT_TRACE4(( "!!!OVERFLOW:!!!" )); - return val; - } - } - - - /* read a floating point number, either integer or real */ - static FT_Fixed - cff_parse_fixed( FT_Byte** d ) - { - return do_fixed( d, 0 ); - } - - - /* read a floating point number, either integer or real, */ - /* but return `10^scaling' times the number read in */ - static FT_Fixed - cff_parse_fixed_scaled( FT_Byte** d, - FT_Long scaling ) - { - return do_fixed( d, scaling ); - } - - - /* read a floating point number, either integer or real, */ - /* and return it as precise as possible -- `scaling' returns */ - /* the scaling factor (as a power of 10) */ - static FT_Fixed - cff_parse_fixed_dynamic( FT_Byte** d, - FT_Long* scaling ) - { - FT_ASSERT( scaling ); - - if ( **d == 30 ) - return cff_parse_real( d[0], d[1], 0, scaling ); - else - { - FT_Long number; - FT_Int integer_length; - - - number = cff_parse_integer( d[0], d[1] ); - - if ( number > 0x7FFFL ) - { - for ( integer_length = 5; integer_length < 10; integer_length++ ) - if ( number < power_tens[integer_length] ) - break; - - if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL ) - { - *scaling = integer_length - 4; - return FT_DivFix( number, power_tens[integer_length - 4] ); - } - else - { - *scaling = integer_length - 5; - return FT_DivFix( number, power_tens[integer_length - 5] ); - } - } - else - { - *scaling = 0; - return (FT_Long)( (FT_ULong)number << 16 ); - } - } - } - - - static FT_Error - cff_parse_font_matrix( CFF_Parser parser ) - { - CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; - FT_Matrix* matrix = &dict->font_matrix; - FT_Vector* offset = &dict->font_offset; - FT_ULong* upm = &dict->units_per_em; - FT_Byte** data = parser->stack; - FT_Error error = FT_ERR( Stack_Underflow ); - - - if ( parser->top >= parser->stack + 6 ) - { - FT_Long scaling; - - - error = FT_Err_Ok; - - dict->has_font_matrix = TRUE; - - /* We expect a well-formed font matrix, this is, the matrix elements */ - /* `xx' and `yy' are of approximately the same magnitude. To avoid */ - /* loss of precision, we use the magnitude of element `xx' to scale */ - /* all other elements. The scaling factor is then contained in the */ - /* `units_per_em' value. */ - - matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); - - scaling = -scaling; - - if ( scaling < 0 || scaling > 9 ) - { - /* Return default matrix in case of unlikely values. */ - - FT_TRACE1(( "cff_parse_font_matrix:" - " strange scaling value for xx element (%d),\n" - " " - " using default matrix\n", scaling )); - - matrix->xx = 0x10000L; - matrix->yx = 0; - matrix->xy = 0; - matrix->yy = 0x10000L; - offset->x = 0; - offset->y = 0; - *upm = 1; - - goto Exit; - } - - matrix->yx = cff_parse_fixed_scaled( data++, scaling ); - matrix->xy = cff_parse_fixed_scaled( data++, scaling ); - matrix->yy = cff_parse_fixed_scaled( data++, scaling ); - offset->x = cff_parse_fixed_scaled( data++, scaling ); - offset->y = cff_parse_fixed_scaled( data, scaling ); - - *upm = power_tens[scaling]; - - FT_TRACE4(( " [%f %f %f %f %f %f]\n", - (double)matrix->xx / *upm / 65536, - (double)matrix->xy / *upm / 65536, - (double)matrix->yx / *upm / 65536, - (double)matrix->yy / *upm / 65536, - (double)offset->x / *upm / 65536, - (double)offset->y / *upm / 65536 )); - } - - Exit: - return error; - } - - - static FT_Error - cff_parse_font_bbox( CFF_Parser parser ) - { - CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; - FT_BBox* bbox = &dict->font_bbox; - FT_Byte** data = parser->stack; - FT_Error error; - - - error = FT_ERR( Stack_Underflow ); - - if ( parser->top >= parser->stack + 4 ) - { - bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) ); - error = FT_Err_Ok; - - FT_TRACE4(( " [%d %d %d %d]\n", - bbox->xMin / 65536, - bbox->yMin / 65536, - bbox->xMax / 65536, - bbox->yMax / 65536 )); - } - - return error; - } - - - static FT_Error - cff_parse_private_dict( CFF_Parser parser ) - { - CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; - FT_Byte** data = parser->stack; - FT_Error error; - - - error = FT_ERR( Stack_Underflow ); - - if ( parser->top >= parser->stack + 2 ) - { - dict->private_size = cff_parse_num( data++ ); - dict->private_offset = cff_parse_num( data ); - FT_TRACE4(( " %lu %lu\n", - dict->private_size, dict->private_offset )); - - error = FT_Err_Ok; - } - - return error; - } - - - static FT_Error - cff_parse_cid_ros( CFF_Parser parser ) - { - CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; - FT_Byte** data = parser->stack; - FT_Error error; - - - error = FT_ERR( Stack_Underflow ); - - if ( parser->top >= parser->stack + 3 ) - { - dict->cid_registry = (FT_UInt)cff_parse_num( data++ ); - dict->cid_ordering = (FT_UInt)cff_parse_num( data++ ); - if ( **data == 30 ) - FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); - dict->cid_supplement = cff_parse_num( data ); - if ( dict->cid_supplement < 0 ) - FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", - dict->cid_supplement )); - error = FT_Err_Ok; - - FT_TRACE4(( " %d %d %d\n", - dict->cid_registry, - dict->cid_ordering, - dict->cid_supplement )); - } - - return error; - } - - -#define CFF_FIELD_NUM( code, name, id ) \ - CFF_FIELD( code, name, id, cff_kind_num ) -#define CFF_FIELD_FIXED( code, name, id ) \ - CFF_FIELD( code, name, id, cff_kind_fixed ) -#define CFF_FIELD_FIXED_1000( code, name, id ) \ - CFF_FIELD( code, name, id, cff_kind_fixed_thousand ) -#define CFF_FIELD_STRING( code, name, id ) \ - CFF_FIELD( code, name, id, cff_kind_string ) -#define CFF_FIELD_BOOL( code, name, id ) \ - CFF_FIELD( code, name, id, cff_kind_bool ) - -#define CFFCODE_TOPDICT 0x1000 -#define CFFCODE_PRIVATE 0x2000 - - -#ifndef FT_CONFIG_OPTION_PIC - - -#undef CFF_FIELD -#undef CFF_FIELD_DELTA - - -#ifndef FT_DEBUG_LEVEL_TRACE - - -#define CFF_FIELD_CALLBACK( code, name, id ) \ - { \ - cff_kind_callback, \ - code | CFFCODE, \ - 0, 0, \ - cff_parse_ ## name, \ - 0, 0 \ - }, - -#define CFF_FIELD( code, name, id, kind ) \ - { \ - kind, \ - code | CFFCODE, \ - FT_FIELD_OFFSET( name ), \ - FT_FIELD_SIZE( name ), \ - 0, 0, 0 \ - }, - -#define CFF_FIELD_DELTA( code, name, max, id ) \ - { \ - cff_kind_delta, \ - code | CFFCODE, \ - FT_FIELD_OFFSET( name ), \ - FT_FIELD_SIZE_DELTA( name ), \ - 0, \ - max, \ - FT_FIELD_OFFSET( num_ ## name ) \ - }, - - static const CFF_Field_Handler cff_field_handlers[] = - { - -#include "cfftoken.h" - - { 0, 0, 0, 0, 0, 0, 0 } - }; - - -#else /* FT_DEBUG_LEVEL_TRACE */ - - - -#define CFF_FIELD_CALLBACK( code, name, id ) \ - { \ - cff_kind_callback, \ - code | CFFCODE, \ - 0, 0, \ - cff_parse_ ## name, \ - 0, 0, \ - id \ - }, - -#define CFF_FIELD( code, name, id, kind ) \ - { \ - kind, \ - code | CFFCODE, \ - FT_FIELD_OFFSET( name ), \ - FT_FIELD_SIZE( name ), \ - 0, 0, 0, \ - id \ - }, - -#define CFF_FIELD_DELTA( code, name, max, id ) \ - { \ - cff_kind_delta, \ - code | CFFCODE, \ - FT_FIELD_OFFSET( name ), \ - FT_FIELD_SIZE_DELTA( name ), \ - 0, \ - max, \ - FT_FIELD_OFFSET( num_ ## name ), \ - id \ - }, - - static const CFF_Field_Handler cff_field_handlers[] = - { - -#include "cfftoken.h" - - { 0, 0, 0, 0, 0, 0, 0, 0 } - }; - - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - -#else /* FT_CONFIG_OPTION_PIC */ - - - void - FT_Destroy_Class_cff_field_handlers( FT_Library library, - CFF_Field_Handler* clazz ) - { - FT_Memory memory = library->memory; - - - if ( clazz ) - FT_FREE( clazz ); - } - - - FT_Error - FT_Create_Class_cff_field_handlers( FT_Library library, - CFF_Field_Handler** output_class ) - { - CFF_Field_Handler* clazz = NULL; - FT_Error error; - FT_Memory memory = library->memory; - - int i = 0; - - -#undef CFF_FIELD -#define CFF_FIELD( code, name, id, kind ) i++; -#undef CFF_FIELD_DELTA -#define CFF_FIELD_DELTA( code, name, max, id ) i++; -#undef CFF_FIELD_CALLBACK -#define CFF_FIELD_CALLBACK( code, name, id ) i++; - -#include "cfftoken.h" - - i++; /* { 0, 0, 0, 0, 0, 0, 0 } */ - - if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) ) - return error; - - i = 0; - - -#ifndef FT_DEBUG_LEVEL_TRACE - - -#undef CFF_FIELD_CALLBACK -#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \ - clazz[i].kind = cff_kind_callback; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = 0; \ - clazz[i].size = 0; \ - clazz[i].reader = cff_parse_ ## name_; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - i++; - -#undef CFF_FIELD -#define CFF_FIELD( code_, name_, id_, kind_ ) \ - clazz[i].kind = kind_; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ - clazz[i].size = FT_FIELD_SIZE( name_ ); \ - clazz[i].reader = 0; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - i++; \ - -#undef CFF_FIELD_DELTA -#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \ - clazz[i].kind = cff_kind_delta; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ - clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ - clazz[i].reader = 0; \ - clazz[i].array_max = max_; \ - clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ - i++; - -#include "cfftoken.h" - - clazz[i].kind = 0; - clazz[i].code = 0; - clazz[i].offset = 0; - clazz[i].size = 0; - clazz[i].reader = 0; - clazz[i].array_max = 0; - clazz[i].count_offset = 0; - - -#else /* FT_DEBUG_LEVEL_TRACE */ - - -#undef CFF_FIELD_CALLBACK -#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \ - clazz[i].kind = cff_kind_callback; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = 0; \ - clazz[i].size = 0; \ - clazz[i].reader = cff_parse_ ## name_; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - clazz[i].id = id_; \ - i++; - -#undef CFF_FIELD -#define CFF_FIELD( code_, name_, id_, kind_ ) \ - clazz[i].kind = kind_; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ - clazz[i].size = FT_FIELD_SIZE( name_ ); \ - clazz[i].reader = 0; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - clazz[i].id = id_; \ - i++; \ - -#undef CFF_FIELD_DELTA -#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \ - clazz[i].kind = cff_kind_delta; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ - clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ - clazz[i].reader = 0; \ - clazz[i].array_max = max_; \ - clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ - clazz[i].id = id_; \ - i++; - -#include "cfftoken.h" - - clazz[i].kind = 0; - clazz[i].code = 0; - clazz[i].offset = 0; - clazz[i].size = 0; - clazz[i].reader = 0; - clazz[i].array_max = 0; - clazz[i].count_offset = 0; - clazz[i].id = 0; - - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - - *output_class = clazz; - - return FT_Err_Ok; - } - - -#endif /* FT_CONFIG_OPTION_PIC */ - - - FT_LOCAL_DEF( FT_Error ) - cff_parser_run( CFF_Parser parser, - FT_Byte* start, - FT_Byte* limit ) - { - FT_Byte* p = start; - FT_Error error = FT_Err_Ok; - FT_Library library = parser->library; - FT_UNUSED( library ); - - - parser->top = parser->stack; - parser->start = start; - parser->limit = limit; - parser->cursor = start; - - while ( p < limit ) - { - FT_UInt v = *p; - - - if ( v >= 27 && v != 31 ) - { - /* it's a number; we will push its position on the stack */ - if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) - goto Stack_Overflow; - - *parser->top ++ = p; - - /* now, skip it */ - if ( v == 30 ) - { - /* skip real number */ - p++; - for (;;) - { - /* An unterminated floating point number at the */ - /* end of a dictionary is invalid but harmless. */ - if ( p >= limit ) - goto Exit; - v = p[0] >> 4; - if ( v == 15 ) - break; - v = p[0] & 0xF; - if ( v == 15 ) - break; - p++; - } - } - else if ( v == 28 ) - p += 2; - else if ( v == 29 ) - p += 4; - else if ( v > 246 ) - p += 1; - } - else - { - /* This is not a number, hence it's an operator. Compute its code */ - /* and look for it in our current list. */ - - FT_UInt code; - FT_UInt num_args = (FT_UInt) - ( parser->top - parser->stack ); - const CFF_Field_Handler* field; - - - *parser->top = p; - code = v; - if ( v == 12 ) - { - /* two byte operator */ - p++; - if ( p >= limit ) - goto Syntax_Error; - - code = 0x100 | p[0]; - } - code = code | parser->object_code; - - for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ ) - { - if ( field->code == (FT_Int)code ) - { - /* we found our field's handler; read it */ - FT_Long val; - FT_Byte* q = (FT_Byte*)parser->object + field->offset; - - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE4(( " %s", field->id )); -#endif - - /* check that we have enough arguments -- except for */ - /* delta encoded arrays, which can be empty */ - if ( field->kind != cff_kind_delta && num_args < 1 ) - goto Stack_Underflow; - - switch ( field->kind ) - { - case cff_kind_bool: - case cff_kind_string: - case cff_kind_num: - val = cff_parse_num( parser->stack ); - goto Store_Number; - - case cff_kind_fixed: - val = cff_parse_fixed( parser->stack ); - goto Store_Number; - - case cff_kind_fixed_thousand: - val = cff_parse_fixed_scaled( parser->stack, 3 ); - - Store_Number: - switch ( field->size ) - { - case (8 / FT_CHAR_BIT): - *(FT_Byte*)q = (FT_Byte)val; - break; - - case (16 / FT_CHAR_BIT): - *(FT_Short*)q = (FT_Short)val; - break; - - case (32 / FT_CHAR_BIT): - *(FT_Int32*)q = (FT_Int)val; - break; - - default: /* for 64-bit systems */ - *(FT_Long*)q = val; - } - -#ifdef FT_DEBUG_LEVEL_TRACE - switch ( field->kind ) - { - case cff_kind_bool: - FT_TRACE4(( " %s\n", val ? "true" : "false" )); - break; - - case cff_kind_string: - FT_TRACE4(( " %ld (SID)\n", val )); - break; - - case cff_kind_num: - FT_TRACE4(( " %ld\n", val )); - break; - - case cff_kind_fixed: - FT_TRACE4(( " %f\n", (double)val / 65536 )); - break; - - case cff_kind_fixed_thousand: - FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 )); - - default: - ; /* never reached */ - } -#endif - - break; - - case cff_kind_delta: - { - FT_Byte* qcount = (FT_Byte*)parser->object + - field->count_offset; - - FT_Byte** data = parser->stack; - - - if ( num_args > field->array_max ) - num_args = field->array_max; - - FT_TRACE4(( " [" )); - - /* store count */ - *qcount = (FT_Byte)num_args; - - val = 0; - while ( num_args > 0 ) - { - val += cff_parse_num( data++ ); - switch ( field->size ) - { - case (8 / FT_CHAR_BIT): - *(FT_Byte*)q = (FT_Byte)val; - break; - - case (16 / FT_CHAR_BIT): - *(FT_Short*)q = (FT_Short)val; - break; - - case (32 / FT_CHAR_BIT): - *(FT_Int32*)q = (FT_Int)val; - break; - - default: /* for 64-bit systems */ - *(FT_Long*)q = val; - } - - FT_TRACE4(( " %ld", val )); - - q += field->size; - num_args--; - } - - FT_TRACE4(( "]\n" )); - } - break; - - default: /* callback */ - error = field->reader( parser ); - if ( error ) - goto Exit; - } - goto Found; - } - } - - /* this is an unknown operator, or it is unsupported; */ - /* we will ignore it for now. */ - - Found: - /* clear stack */ - parser->top = parser->stack; - } - p++; - } - - Exit: - return error; - - Stack_Overflow: - error = FT_THROW( Invalid_Argument ); - goto Exit; - - Stack_Underflow: - error = FT_THROW( Invalid_Argument ); - goto Exit; - - Syntax_Error: - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffparse.h b/drivers/freetype/freetype/src/cff/cffparse.h deleted file mode 100644 index 61d91ed2e2..0000000000 --- a/drivers/freetype/freetype/src/cff/cffparse.h +++ /dev/null @@ -1,106 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffparse.h */ -/* */ -/* CFF token stream parser (specification) */ -/* */ -/* Copyright 1996-2003, 2011 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 __CFF_PARSE_H__ -#define __CFF_PARSE_H__ - - -#include <ft2build.h> -#include "cfftypes.h" -#include FT_INTERNAL_OBJECTS_H - - -FT_BEGIN_HEADER - - -#define CFF_MAX_STACK_DEPTH 96 - -#define CFF_CODE_TOPDICT 0x1000 -#define CFF_CODE_PRIVATE 0x2000 - - - typedef struct CFF_ParserRec_ - { - FT_Library library; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* cursor; - - FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; - FT_Byte** top; - - FT_UInt object_code; - void* object; - - } CFF_ParserRec, *CFF_Parser; - - - FT_LOCAL( void ) - cff_parser_init( CFF_Parser parser, - FT_UInt code, - void* object, - FT_Library library); - - FT_LOCAL( FT_Error ) - cff_parser_run( CFF_Parser parser, - FT_Byte* start, - FT_Byte* limit ); - - - enum - { - cff_kind_none = 0, - cff_kind_num, - cff_kind_fixed, - cff_kind_fixed_thousand, - cff_kind_string, - cff_kind_bool, - cff_kind_delta, - cff_kind_callback, - - cff_kind_max /* do not remove */ - }; - - - /* now generate handlers for the most simple fields */ - typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); - - typedef struct CFF_Field_Handler_ - { - int kind; - int code; - FT_UInt offset; - FT_Byte size; - CFF_Field_Reader reader; - FT_UInt array_max; - FT_UInt count_offset; - -#ifdef FT_DEBUG_LEVEL_TRACE - const char* id; -#endif - - } CFF_Field_Handler; - - -FT_END_HEADER - - -#endif /* __CFF_PARSE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffpic.c b/drivers/freetype/freetype/src/cff/cffpic.c deleted file mode 100644 index f22e4f0d53..0000000000 --- a/drivers/freetype/freetype/src/cff/cffpic.c +++ /dev/null @@ -1,138 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffpic.c */ -/* */ -/* The FreeType position independent code services for cff module. */ -/* */ -/* Copyright 2009, 2010, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "cffcmap.h" -#include "cffpic.h" -#include "cfferrs.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from cffdrivr.c */ - FT_Error - FT_Create_Class_cff_services( FT_Library library, - FT_ServiceDescRec** output_class ); - void - FT_Destroy_Class_cff_services( FT_Library library, - FT_ServiceDescRec* clazz ); - void - FT_Init_Class_cff_service_ps_info( FT_Library library, - FT_Service_PsInfoRec* clazz ); - void - FT_Init_Class_cff_service_glyph_dict( FT_Library library, - FT_Service_GlyphDictRec* clazz ); - void - FT_Init_Class_cff_service_ps_name( FT_Library library, - FT_Service_PsFontNameRec* clazz ); - void - FT_Init_Class_cff_service_get_cmap_info( FT_Library library, - FT_Service_TTCMapsRec* clazz ); - void - FT_Init_Class_cff_service_cid_info( FT_Library library, - FT_Service_CIDRec* clazz ); - - /* forward declaration of PIC init functions from cffparse.c */ - FT_Error - FT_Create_Class_cff_field_handlers( FT_Library library, - CFF_Field_Handler** output_class ); - void - FT_Destroy_Class_cff_field_handlers( FT_Library library, - CFF_Field_Handler* clazz ); - - - void - cff_driver_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->cff ) - { - CffModulePIC* container = (CffModulePIC*)pic_container->cff; - - - if ( container->cff_services ) - FT_Destroy_Class_cff_services( library, - container->cff_services ); - container->cff_services = NULL; - if ( container->cff_field_handlers ) - FT_Destroy_Class_cff_field_handlers( - library, container->cff_field_handlers ); - container->cff_field_handlers = NULL; - FT_FREE( container ); - pic_container->cff = NULL; - } - } - - - FT_Error - cff_driver_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - CffModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC ( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->cff = container; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - error = FT_Create_Class_cff_services( library, - &container->cff_services ); - if ( error ) - goto Exit; - - error = FT_Create_Class_cff_field_handlers( - library, &container->cff_field_handlers ); - if ( error ) - goto Exit; - - FT_Init_Class_cff_service_ps_info( - library, &container->cff_service_ps_info ); - FT_Init_Class_cff_service_glyph_dict( - library, &container->cff_service_glyph_dict ); - FT_Init_Class_cff_service_ps_name( - library, &container->cff_service_ps_name ); - FT_Init_Class_cff_service_get_cmap_info( - library, &container->cff_service_get_cmap_info ); - FT_Init_Class_cff_service_cid_info( - library, &container->cff_service_cid_info ); - FT_Init_Class_cff_cmap_encoding_class_rec( - library, &container->cff_cmap_encoding_class_rec ); - FT_Init_Class_cff_cmap_unicode_class_rec( - library, &container->cff_cmap_unicode_class_rec ); - - Exit: - if ( error ) - cff_driver_class_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cffpic.h b/drivers/freetype/freetype/src/cff/cffpic.h deleted file mode 100644 index 50bab4c173..0000000000 --- a/drivers/freetype/freetype/src/cff/cffpic.h +++ /dev/null @@ -1,108 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffpic.h */ -/* */ -/* The FreeType position independent code services for cff module. */ -/* */ -/* Copyright 2009, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __CFFPIC_H__ -#define __CFFPIC_H__ - - -FT_BEGIN_HEADER - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define CFF_SERVICE_PS_INFO_GET cff_service_ps_info -#define CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict -#define CFF_SERVICE_PS_NAME_GET cff_service_ps_name -#define CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info -#define CFF_SERVICE_CID_INFO_GET cff_service_cid_info -#define CFF_SERVICE_PROPERTIES_GET cff_service_properties -#define CFF_SERVICES_GET cff_services -#define CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec -#define CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec -#define CFF_FIELD_HANDLERS_GET cff_field_handlers - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_SERVICE_GLYPH_DICT_H -#include "cffparse.h" -#include FT_SERVICE_POSTSCRIPT_INFO_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_TT_CMAP_H -#include FT_SERVICE_CID_H -#include FT_SERVICE_PROPERTIES_H - - - typedef struct CffModulePIC_ - { - FT_ServiceDescRec* cff_services; - CFF_Field_Handler* cff_field_handlers; - FT_Service_PsInfoRec cff_service_ps_info; - FT_Service_GlyphDictRec cff_service_glyph_dict; - FT_Service_PsFontNameRec cff_service_ps_name; - FT_Service_TTCMapsRec cff_service_get_cmap_info; - FT_Service_CIDRec cff_service_cid_info; - FT_Service_PropertiesRec cff_service_properties; - FT_CMap_ClassRec cff_cmap_encoding_class_rec; - FT_CMap_ClassRec cff_cmap_unicode_class_rec; - - } CffModulePIC; - - -#define GET_PIC( lib ) \ - ( (CffModulePIC*)( (lib)->pic_container.cff ) ) - -#define CFF_SERVICE_PS_INFO_GET \ - ( GET_PIC( library )->cff_service_ps_info ) -#define CFF_SERVICE_GLYPH_DICT_GET \ - ( GET_PIC( library )->cff_service_glyph_dict ) -#define CFF_SERVICE_PS_NAME_GET \ - ( GET_PIC( library )->cff_service_ps_name ) -#define CFF_SERVICE_GET_CMAP_INFO_GET \ - ( GET_PIC( library )->cff_service_get_cmap_info ) -#define CFF_SERVICE_CID_INFO_GET \ - ( GET_PIC( library )->cff_service_cid_info ) -#define CFF_SERVICE_PROPERTIES_GET \ - ( GET_PIC( library )->cff_service_properties ) -#define CFF_SERVICES_GET \ - ( GET_PIC( library )->cff_services ) -#define CFF_CMAP_ENCODING_CLASS_REC_GET \ - ( GET_PIC( library )->cff_cmap_encoding_class_rec ) -#define CFF_CMAP_UNICODE_CLASS_REC_GET \ - ( GET_PIC( library )->cff_cmap_unicode_class_rec ) -#define CFF_FIELD_HANDLERS_GET \ - ( GET_PIC( library )->cff_field_handlers ) - - /* see cffpic.c for the implementation */ - void - cff_driver_class_pic_free( FT_Library library ); - - FT_Error - cff_driver_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __CFFPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cfftoken.h b/drivers/freetype/freetype/src/cff/cfftoken.h deleted file mode 100644 index bcb4276a78..0000000000 --- a/drivers/freetype/freetype/src/cff/cfftoken.h +++ /dev/null @@ -1,97 +0,0 @@ -/***************************************************************************/ -/* */ -/* cfftoken.h */ -/* */ -/* CFF token definitions (specification only). */ -/* */ -/* Copyright 1996-2003, 2011 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. */ -/* */ -/***************************************************************************/ - - -#undef FT_STRUCTURE -#define FT_STRUCTURE CFF_FontRecDictRec - -#undef CFFCODE -#define CFFCODE CFFCODE_TOPDICT - - CFF_FIELD_STRING ( 0, version, "Version" ) - CFF_FIELD_STRING ( 1, notice, "Notice" ) - CFF_FIELD_STRING ( 0x100, copyright, "Copyright" ) - CFF_FIELD_STRING ( 2, full_name, "FullName" ) - CFF_FIELD_STRING ( 3, family_name, "FamilyName" ) - CFF_FIELD_STRING ( 4, weight, "Weight" ) - CFF_FIELD_BOOL ( 0x101, is_fixed_pitch, "isFixedPitch" ) - CFF_FIELD_FIXED ( 0x102, italic_angle, "ItalicAngle" ) - CFF_FIELD_FIXED ( 0x103, underline_position, "UnderlinePosition" ) - CFF_FIELD_FIXED ( 0x104, underline_thickness, "UnderlineThickness" ) - CFF_FIELD_NUM ( 0x105, paint_type, "PaintType" ) - CFF_FIELD_NUM ( 0x106, charstring_type, "CharstringType" ) - CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" ) - CFF_FIELD_NUM ( 13, unique_id, "UniqueID" ) - CFF_FIELD_CALLBACK( 5, font_bbox, "FontBBox" ) - CFF_FIELD_NUM ( 0x108, stroke_width, "StrokeWidth" ) - CFF_FIELD_NUM ( 15, charset_offset, "charset" ) - CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" ) - CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) - CFF_FIELD_CALLBACK( 18, private_dict, "Private" ) - CFF_FIELD_NUM ( 0x114, synthetic_base, "SyntheticBase" ) - CFF_FIELD_STRING ( 0x115, embedded_postscript, "PostScript" ) - -#if 0 - CFF_FIELD_STRING ( 0x116, base_font_name, "BaseFontName" ) - CFF_FIELD_DELTA ( 0x117, base_font_blend, 16, "BaseFontBlend" ) - CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" ) - CFF_FIELD_CALLBACK( 0x119, blend_axis_types, "BlendAxisTypes" ) -#endif - - CFF_FIELD_CALLBACK( 0x11E, cid_ros, "ROS" ) - CFF_FIELD_NUM ( 0x11F, cid_font_version, "CIDFontVersion" ) - CFF_FIELD_NUM ( 0x120, cid_font_revision, "CIDFontRevision" ) - CFF_FIELD_NUM ( 0x121, cid_font_type, "CIDFontType" ) - CFF_FIELD_NUM ( 0x122, cid_count, "CIDCount" ) - CFF_FIELD_NUM ( 0x123, cid_uid_base, "UIDBase" ) - CFF_FIELD_NUM ( 0x124, cid_fd_array_offset, "FDArray" ) - CFF_FIELD_NUM ( 0x125, cid_fd_select_offset, "FDSelect" ) - CFF_FIELD_STRING ( 0x126, cid_font_name, "FontName" ) - -#if 0 - CFF_FIELD_NUM ( 0x127, chameleon, "Chameleon" ) -#endif - - -#undef FT_STRUCTURE -#define FT_STRUCTURE CFF_PrivateRec -#undef CFFCODE -#define CFFCODE CFFCODE_PRIVATE - - CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) - CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) - CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" ) - CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" ) - CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" ) - CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) - CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) - CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) - CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) - CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) - CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) - CFF_FIELD_BOOL ( 0x10E, force_bold, "ForceBold" ) - CFF_FIELD_FIXED ( 0x10F, force_bold_threshold, "ForceBoldThreshold" ) - CFF_FIELD_NUM ( 0x110, lenIV, "lenIV" ) - CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) - CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) - CFF_FIELD_NUM ( 0x113, initial_random_seed, "initialRandomSeed" ) - CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) - CFF_FIELD_NUM ( 20, default_width, "defaultWidthX" ) - CFF_FIELD_NUM ( 21, nominal_width, "nominalWidthX" ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/cfftypes.h b/drivers/freetype/freetype/src/cff/cfftypes.h deleted file mode 100644 index 8727446664..0000000000 --- a/drivers/freetype/freetype/src/cff/cfftypes.h +++ /dev/null @@ -1,284 +0,0 @@ -/***************************************************************************/ -/* */ -/* cfftypes.h */ -/* */ -/* Basic OpenType/CFF type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2003, 2006-2008, 2010-2011, 2013 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 __CFFTYPES_H__ -#define __CFFTYPES_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_TYPE1_TABLES_H -#include FT_INTERNAL_SERVICE_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CFF_IndexRec */ - /* */ - /* <Description> */ - /* A structure used to model a CFF Index table. */ - /* */ - /* <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. */ - /* */ - /* data_offset :: The position of first data byte in the index's */ - /* bytes. */ - /* */ - /* 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; - - } CFF_IndexRec, *CFF_Index; - - - typedef struct CFF_EncodingRec_ - { - FT_UInt format; - FT_ULong offset; - - FT_UInt count; - FT_UShort sids [256]; /* avoid dynamic allocations */ - FT_UShort codes[256]; - - } CFF_EncodingRec, *CFF_Encoding; - - - typedef struct CFF_CharsetRec_ - { - - FT_UInt format; - FT_ULong offset; - - FT_UShort* sids; - 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; - - - typedef struct CFF_FontRecDictRec_ - { - FT_UInt version; - FT_UInt notice; - FT_UInt copyright; - FT_UInt full_name; - FT_UInt family_name; - FT_UInt weight; - FT_Bool is_fixed_pitch; - FT_Fixed italic_angle; - FT_Fixed underline_position; - FT_Fixed underline_thickness; - FT_Int paint_type; - FT_Int charstring_type; - FT_Matrix font_matrix; - FT_Bool has_font_matrix; - FT_ULong units_per_em; /* temporarily used as scaling value also */ - FT_Vector font_offset; - FT_ULong unique_id; - FT_BBox font_bbox; - FT_Pos stroke_width; - FT_ULong charset_offset; - FT_ULong encoding_offset; - FT_ULong charstrings_offset; - FT_ULong private_offset; - FT_ULong private_size; - FT_Long synthetic_base; - FT_UInt embedded_postscript; - - /* these should only be used for the top-level font dictionary */ - FT_UInt cid_registry; - FT_UInt cid_ordering; - FT_Long cid_supplement; - - FT_Long cid_font_version; - FT_Long cid_font_revision; - FT_Long cid_font_type; - FT_ULong cid_count; - FT_ULong cid_uid_base; - FT_ULong cid_fd_array_offset; - FT_ULong cid_fd_select_offset; - FT_UInt cid_font_name; - - } CFF_FontRecDictRec, *CFF_FontRecDict; - - - typedef struct CFF_PrivateRec_ - { - FT_Byte num_blue_values; - FT_Byte num_other_blues; - FT_Byte num_family_blues; - FT_Byte num_family_other_blues; - - FT_Pos blue_values[14]; - FT_Pos other_blues[10]; - FT_Pos family_blues[14]; - FT_Pos family_other_blues[10]; - - FT_Fixed blue_scale; - FT_Pos blue_shift; - FT_Pos blue_fuzz; - FT_Pos standard_width; - FT_Pos standard_height; - - FT_Byte num_snap_widths; - FT_Byte num_snap_heights; - FT_Pos snap_widths[13]; - FT_Pos snap_heights[13]; - FT_Bool force_bold; - FT_Fixed force_bold_threshold; - FT_Int lenIV; - FT_Int language_group; - FT_Fixed expansion_factor; - FT_Long initial_random_seed; - FT_ULong local_subrs_offset; - FT_Pos default_width; - FT_Pos nominal_width; - - } CFF_PrivateRec, *CFF_Private; - - - typedef struct CFF_FDSelectRec_ - { - FT_Byte format; - FT_UInt range_count; - - /* that's the table, taken from the file `as is' */ - FT_Byte* data; - FT_UInt data_size; - - /* small cache for format 3 only */ - FT_UInt cache_first; - FT_UInt cache_count; - FT_Byte cache_fd; - - } CFF_FDSelectRec, *CFF_FDSelect; - - - /* A SubFont packs a font dict and a private dict together. They are */ - /* needed to support CID-keyed CFF fonts. */ - typedef struct CFF_SubFontRec_ - { - CFF_FontRecDictRec font_dict; - CFF_PrivateRec private_dict; - - CFF_IndexRec local_subrs_index; - FT_Byte** local_subrs; /* array of pointers into Local Subrs INDEX data */ - - } CFF_SubFontRec, *CFF_SubFont; - - -#define CFF_MAX_CID_FONTS 256 - - - typedef struct CFF_FontRec_ - { - FT_Stream stream; - FT_Memory memory; - FT_UInt num_faces; - FT_UInt num_glyphs; - - FT_Byte version_major; - FT_Byte version_minor; - FT_Byte header_size; - FT_Byte absolute_offsize; - - - CFF_IndexRec name_index; - CFF_IndexRec top_dict_index; - CFF_IndexRec global_subrs_index; - - CFF_EncodingRec encoding; - CFF_CharsetRec charset; - - CFF_IndexRec charstrings_index; - CFF_IndexRec font_dict_index; - CFF_IndexRec private_index; - CFF_IndexRec local_subrs_index; - - FT_String* font_name; - - /* array of pointers into Global Subrs INDEX data */ - FT_Byte** global_subrs; - - /* array of pointers into String INDEX data stored at string_pool */ - FT_UInt num_strings; - FT_Byte** strings; - FT_Byte* string_pool; - - CFF_SubFontRec top_font; - FT_UInt num_subfonts; - CFF_SubFont subfonts[CFF_MAX_CID_FONTS]; - - CFF_FDSelectRec fd_select; - - /* interface to PostScript hinter */ - PSHinter_Service pshinter; - - /* interface to Postscript Names service */ - FT_Service_PsCMaps psnames; - - /* since version 2.3.0 */ - PS_FontInfoRec* font_info; /* font info dictionary */ - - /* since version 2.3.6 */ - FT_String* registry; - FT_String* ordering; - - /* since version 2.4.12 */ - FT_Generic cf2_instance; - - } CFF_FontRec, *CFF_Font; - - -FT_END_HEADER - -#endif /* __CFFTYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cff/module.mk b/drivers/freetype/freetype/src/cff/module.mk deleted file mode 100644 index ef1391c279..0000000000 --- a/drivers/freetype/freetype/src/cff/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 CFF module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += CFF_DRIVER - -define CFF_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, cff_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/cff/rules.mk b/drivers/freetype/freetype/src/cff/rules.mk deleted file mode 100644 index 13115c2550..0000000000 --- a/drivers/freetype/freetype/src/cff/rules.mk +++ /dev/null @@ -1,86 +0,0 @@ -# -# FreeType 2 OpenType/CFF driver configuration rules -# - - -# Copyright 1996-2001, 2003, 2011, 2013 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. - - -# OpenType driver directory -# -CFF_DIR := $(SRC_DIR)/cff - - -CFF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) - - -# CFF driver sources (i.e., C files) -# -CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \ - $(CFF_DIR)/cffdrivr.c \ - $(CFF_DIR)/cffgload.c \ - $(CFF_DIR)/cffload.c \ - $(CFF_DIR)/cffobjs.c \ - $(CFF_DIR)/cffparse.c \ - $(CFF_DIR)/cffpic.c \ - $(CFF_DIR)/cf2arrst.c \ - $(CFF_DIR)/cf2blues.c \ - $(CFF_DIR)/cf2error.c \ - $(CFF_DIR)/cf2font.c \ - $(CFF_DIR)/cf2ft.c \ - $(CFF_DIR)/cf2hints.c \ - $(CFF_DIR)/cf2intrp.c \ - $(CFF_DIR)/cf2read.c \ - $(CFF_DIR)/cf2stack.c - - -# CFF driver headers -# -CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ - $(CFF_DIR)/cfferrs.h \ - $(CFF_DIR)/cfftoken.h \ - $(CFF_DIR)/cfftypes.h \ - $(CFF_DIR)/cf2fixed.h \ - $(CFF_DIR)/cf2glue.h \ - $(CFF_DIR)/cf2types.h - - -# CFF driver object(s) -# -# CFF_DRV_OBJ_M is used during `multi' builds -# CFF_DRV_OBJ_S is used during `single' builds -# -CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR)/%.c=$(OBJ_DIR)/%.$O) -CFF_DRV_OBJ_S := $(OBJ_DIR)/cff.$O - -# CFF driver source file for single build -# -CFF_DRV_SRC_S := $(CFF_DIR)/cff.c - - -# CFF driver - single object -# -$(CFF_DRV_OBJ_S): $(CFF_DRV_SRC_S) $(CFF_DRV_SRC) $(FREETYPE_H) $(CFF_DRV_H) - $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CFF_DRV_SRC_S)) - - -# CFF driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(CFF_DIR)/%.c $(FREETYPE_H) $(CFF_DRV_H) - $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(CFF_DRV_OBJ_S) -DRV_OBJS_M += $(CFF_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/cid/Jamfile b/drivers/freetype/freetype/src/cid/Jamfile deleted file mode 100644 index ebeaed54ea..0000000000 --- a/drivers/freetype/freetype/src/cid/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/cid Jamfile -# -# Copyright 2001 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) cid ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = cidobjs cidload cidgload cidriver cidparse ; - } - else - { - _sources = type1cid ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/cid Jamfile diff --git a/drivers/freetype/freetype/src/cid/ciderrs.h b/drivers/freetype/freetype/src/cid/ciderrs.h deleted file mode 100644 index ef13155504..0000000000 --- a/drivers/freetype/freetype/src/cid/ciderrs.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* ciderrs.h */ -/* */ -/* CID error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the CID error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __CIDERRS_H__ -#define __CIDERRS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX CID_Err_ -#define FT_ERR_BASE FT_Mod_Err_CID - -#include FT_ERRORS_H - -#endif /* __CIDERRS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidgload.c b/drivers/freetype/freetype/src/cid/cidgload.c deleted file mode 100644 index a1a8658693..0000000000 --- a/drivers/freetype/freetype/src/cid/cidgload.c +++ /dev/null @@ -1,442 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidgload.c */ -/* */ -/* CID-keyed Type1 Glyph Loader (body). */ -/* */ -/* Copyright 1996-2007, 2009, 2010, 2013 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 "cidload.h" -#include "cidgload.h" -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_OUTLINE_H -#include FT_INTERNAL_CALC_H - -#include "ciderrs.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_cidgload - - - FT_CALLBACK_DEF( FT_Error ) - cid_load_glyph( T1_Decoder decoder, - FT_UInt glyph_index ) - { - CID_Face face = (CID_Face)decoder->builder.face; - CID_FaceInfo cid = &face->cid; - FT_Byte* p; - FT_UInt fd_select; - FT_Stream stream = face->cid_stream; - FT_Error error = FT_Err_Ok; - FT_Byte* charstring = 0; - FT_Memory memory = face->root.memory; - FT_ULong glyph_length = 0; - PSAux_Service psaux = (PSAux_Service)face->psaux; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - FT_Incremental_InterfaceRec *inc = - face->root.internal->incremental_interface; -#endif - - - FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index )); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* For incremental fonts get the character data using */ - /* the callback function. */ - if ( inc ) - { - FT_Data glyph_data; - - - error = inc->funcs->get_glyph_data( inc->object, - glyph_index, &glyph_data ); - if ( error ) - goto Exit; - - p = (FT_Byte*)glyph_data.pointer; - fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - - if ( glyph_data.length != 0 ) - { - glyph_length = glyph_data.length - cid->fd_bytes; - (void)FT_ALLOC( charstring, glyph_length ); - if ( !error ) - ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, - glyph_length ); - } - - inc->funcs->free_glyph_data( inc->object, &glyph_data ); - - if ( error ) - goto Exit; - } - - else - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - /* For ordinary fonts read the CID font dictionary index */ - /* and charstring offset from the CIDMap. */ - { - FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; - FT_ULong off1; - - - if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + - glyph_index * entry_len ) || - FT_FRAME_ENTER( 2 * entry_len ) ) - goto Exit; - - p = (FT_Byte*)stream->cursor; - fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); - p += cid->fd_bytes; - glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; - FT_FRAME_EXIT(); - - if ( fd_select >= (FT_UInt)cid->num_dicts ) - { - error = FT_THROW( Invalid_Offset ); - goto Exit; - } - if ( glyph_length == 0 ) - goto Exit; - if ( FT_ALLOC( charstring, glyph_length ) ) - goto Exit; - if ( FT_STREAM_READ_AT( cid->data_offset + off1, - charstring, glyph_length ) ) - goto Exit; - } - - /* Now set up the subrs array and parse the charstrings. */ - { - CID_FaceDict dict; - CID_Subrs cid_subrs = face->subrs + fd_select; - FT_Int cs_offset; - - - /* Set up subrs */ - decoder->num_subrs = cid_subrs->num_subrs; - decoder->subrs = cid_subrs->code; - decoder->subrs_len = 0; - - /* Set up font matrix */ - dict = cid->font_dicts + fd_select; - - decoder->font_matrix = dict->font_matrix; - decoder->font_offset = dict->font_offset; - decoder->lenIV = dict->private_dict.lenIV; - - /* Decode the charstring. */ - - /* Adjustment for seed bytes. */ - cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); - - /* Decrypt only if lenIV >= 0. */ - if ( decoder->lenIV >= 0 ) - psaux->t1_decrypt( charstring, glyph_length, 4330 ); - - error = decoder->funcs.parse_charstrings( - decoder, charstring + cs_offset, - (FT_Int)glyph_length - cs_offset ); - } - - FT_FREE( charstring ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* Incremental fonts can optionally override the metrics. */ - if ( !error && inc && inc->funcs->get_glyph_metrics ) - { - FT_Incremental_MetricsRec metrics; - - - metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); - metrics.bearing_y = 0; - metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); - metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); - - error = inc->funcs->get_glyph_metrics( inc->object, - glyph_index, FALSE, &metrics ); - - decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); - decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); - decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); - } - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - Exit: - return error; - } - - -#if 0 - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL_DEF( FT_Error ) - cid_face_compute_max_advance( CID_Face face, - FT_Int* max_advance ) - { - FT_Error error; - T1_DecoderRec decoder; - FT_Int glyph_index; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - *max_advance = 0; - - /* Initialize load decoder */ - error = psaux->t1_decoder_funcs->init( &decoder, - (FT_Face)face, - 0, /* size */ - 0, /* glyph slot */ - 0, /* glyph names! XXX */ - 0, /* blend == 0 */ - 0, /* hinting == 0 */ - cid_load_glyph ); - 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; - - /* for each glyph, parse the glyph charstring and extract */ - /* the advance width */ - for ( glyph_index = 0; glyph_index < face->root.num_glyphs; - glyph_index++ ) - { - /* now get load the unscaled outline */ - error = cid_load_glyph( &decoder, glyph_index ); - /* ignore the error if one occurred - skip to next glyph */ - } - - *max_advance = FIXED_TO_INT( decoder.builder.advance.x ); - - psaux->t1_decoder_funcs->done( &decoder ); - - return FT_Err_Ok; - } - - -#endif /* 0 */ - - - FT_LOCAL_DEF( FT_Error ) - cid_slot_load_glyph( FT_GlyphSlot cidglyph, /* CID_GlyphSlot */ - FT_Size cidsize, /* CID_Size */ - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - CID_GlyphSlot glyph = (CID_GlyphSlot)cidglyph; - FT_Error error; - T1_DecoderRec decoder; - CID_Face face = (CID_Face)cidglyph->face; - FT_Bool hinting; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - FT_Matrix font_matrix; - FT_Vector font_offset; - - - if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - glyph->x_scale = cidsize->metrics.x_scale; - glyph->y_scale = cidsize->metrics.y_scale; - - cidglyph->outline.n_points = 0; - cidglyph->outline.n_contours = 0; - - hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && - ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); - - 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 ); - if ( error ) - goto Exit; - - /* TODO: initialize decoder.len_buildchar and decoder.buildchar */ - /* if we ever support CID-keyed multiple master fonts */ - - /* set up the decoder */ - decoder.builder.no_recurse = FT_BOOL( - ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); - - error = cid_load_glyph( &decoder, glyph_index ); - if ( error ) - goto Exit; - - font_matrix = decoder.font_matrix; - font_offset = decoder.font_offset; - - /* 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 */ - 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 ) - { - FT_Slot_Internal internal = cidglyph->internal; - - - cidglyph->metrics.horiBearingX = - FIXED_TO_INT( decoder.builder.left_bearing.x ); - cidglyph->metrics.horiAdvance = - FIXED_TO_INT( 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 = - FIXED_TO_INT( decoder.builder.advance.x ); - cidglyph->linearHoriAdvance = - FIXED_TO_INT( 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 ( 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; - - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - /* make up vertical ones */ - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); - } - } - - Exit: - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidgload.h b/drivers/freetype/freetype/src/cid/cidgload.h deleted file mode 100644 index a0a91bfea8..0000000000 --- a/drivers/freetype/freetype/src/cid/cidgload.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidgload.h */ -/* */ -/* OpenType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2004 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 __CIDGLOAD_H__ -#define __CIDGLOAD_H__ - - -#include <ft2build.h> -#include "cidobjs.h" - - -FT_BEGIN_HEADER - - -#if 0 - - /* Compute the maximum advance width of a font through quick parsing */ - FT_LOCAL( FT_Error ) - cid_face_compute_max_advance( CID_Face face, - FT_Int* max_advance ); - -#endif /* 0 */ - - FT_LOCAL( FT_Error ) - cid_slot_load_glyph( FT_GlyphSlot glyph, /* CID_Glyph_Slot */ - FT_Size size, /* CID_Size */ - FT_UInt glyph_index, - FT_Int32 load_flags ); - - -FT_END_HEADER - -#endif /* __CIDGLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidload.c b/drivers/freetype/freetype/src/cid/cidload.c deleted file mode 100644 index f2a18ea510..0000000000 --- a/drivers/freetype/freetype/src/cid/cidload.c +++ /dev/null @@ -1,690 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidload.c */ -/* */ -/* CID-keyed Type1 font loader (body). */ -/* */ -/* Copyright 1996-2006, 2009, 2011-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_CONFIG_CONFIG_H -#include FT_MULTIPLE_MASTERS_H -#include FT_INTERNAL_TYPE1_TYPES_H - -#include "cidload.h" - -#include "ciderrs.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_cidload - - - /* read a single offset */ - FT_LOCAL_DEF( FT_Long ) - cid_get_offset( FT_Byte* *start, - FT_Byte offsize ) - { - FT_ULong result; - FT_Byte* p = *start; - - - for ( result = 0; offsize > 0; offsize-- ) - { - result <<= 8; - result |= *p++; - } - - *start = p; - return (FT_Long)result; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE 1 SYMBOL PARSING *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - static FT_Error - cid_load_keyword( CID_Face face, - CID_Loader* loader, - const T1_Field keyword ) - { - FT_Error error; - CID_Parser* parser = &loader->parser; - FT_Byte* object; - void* dummy_object; - CID_FaceInfo cid = &face->cid; - - - /* if the keyword has a dedicated callback, call it */ - if ( keyword->type == T1_FIELD_TYPE_CALLBACK ) - { - keyword->reader( (FT_Face)face, parser ); - error = parser->root.error; - goto Exit; - } - - /* we must now compute the address of our target object */ - switch ( keyword->location ) - { - case T1_FIELD_LOCATION_CID_INFO: - object = (FT_Byte*)cid; - break; - - case T1_FIELD_LOCATION_FONT_INFO: - object = (FT_Byte*)&cid->font_info; - break; - - case T1_FIELD_LOCATION_FONT_EXTRA: - object = (FT_Byte*)&face->font_extra; - break; - - case T1_FIELD_LOCATION_BBOX: - object = (FT_Byte*)&cid->font_bbox; - break; - - default: - { - CID_FaceDict dict; - - - if ( parser->num_dict < 0 || parser->num_dict >= cid->num_dicts ) - { - FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n", - keyword->ident )); - error = FT_THROW( Syntax_Error ); - goto Exit; - } - - dict = cid->font_dicts + parser->num_dict; - switch ( keyword->location ) - { - case T1_FIELD_LOCATION_PRIVATE: - object = (FT_Byte*)&dict->private_dict; - break; - - default: - object = (FT_Byte*)dict; - } - } - } - - dummy_object = object; - - /* now, load the keyword data in the object's field(s) */ - if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY || - keyword->type == T1_FIELD_TYPE_FIXED_ARRAY ) - error = cid_parser_load_field_table( &loader->parser, keyword, - &dummy_object ); - else - error = cid_parser_load_field( &loader->parser, - keyword, &dummy_object ); - Exit: - return error; - } - - - FT_CALLBACK_DEF( FT_Error ) - cid_parse_font_matrix( CID_Face face, - CID_Parser* parser ) - { - FT_Matrix* matrix; - FT_Vector* offset; - CID_FaceDict dict; - FT_Face root = (FT_Face)&face->root; - FT_Fixed temp[6]; - FT_Fixed temp_scale; - - - if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) - { - dict = face->cid.font_dicts + parser->num_dict; - matrix = &dict->font_matrix; - offset = &dict->font_offset; - - (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); - - temp_scale = FT_ABS( temp[3] ); - - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ - - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); - - /* we need to scale the values by 1.0/temp[3] */ - if ( temp_scale != 0x10000L ) - { - temp[0] = FT_DivFix( temp[0], temp_scale ); - temp[1] = FT_DivFix( temp[1], temp_scale ); - temp[2] = FT_DivFix( temp[2], temp_scale ); - temp[4] = FT_DivFix( temp[4], temp_scale ); - temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; - } - - matrix->xx = temp[0]; - matrix->yx = temp[1]; - matrix->xy = temp[2]; - matrix->yy = temp[3]; - - /* note that the font offsets are expressed in integer font units */ - offset->x = temp[4] >> 16; - offset->y = temp[5] >> 16; - } - - return FT_Err_Ok; /* this is a callback function; */ - /* we must return an error code */ - } - - - FT_CALLBACK_DEF( FT_Error ) - parse_fd_array( CID_Face face, - CID_Parser* parser ) - { - CID_FaceInfo cid = &face->cid; - FT_Memory memory = face->root.memory; - FT_Error error = FT_Err_Ok; - FT_Long num_dicts; - - - num_dicts = cid_parser_to_int( parser ); - - if ( !cid->font_dicts ) - { - FT_Int n; - - - if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) - goto Exit; - - cid->num_dicts = (FT_UInt)num_dicts; - - /* don't forget to set a few defaults */ - for ( n = 0; n < cid->num_dicts; n++ ) - { - CID_FaceDict dict = cid->font_dicts + n; - - - /* default value for lenIV */ - dict->private_dict.lenIV = 4; - } - } - - Exit: - return error; - } - - - /* by mistake, `expansion_factor' appears both in PS_PrivateRec */ - /* and CID_FaceDictRec (both are public header files and can't */ - /* changed); we simply copy the value */ - - FT_CALLBACK_DEF( FT_Error ) - parse_expansion_factor( CID_Face face, - CID_Parser* parser ) - { - CID_FaceDict dict; - - - if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) - { - dict = face->cid.font_dicts + parser->num_dict; - - dict->expansion_factor = cid_parser_to_fixed( parser, 0 ); - dict->private_dict.expansion_factor = dict->expansion_factor; - } - - return FT_Err_Ok; - } - - - static - const T1_FieldRec cid_field_records[] = - { - -#include "cidtoken.h" - - T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) - T1_FIELD_CALLBACK( "FontMatrix", cid_parse_font_matrix, 0 ) - T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 ) - - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } - }; - - - static FT_Error - cid_parse_dict( CID_Face face, - CID_Loader* loader, - FT_Byte* base, - FT_Long size ) - { - CID_Parser* parser = &loader->parser; - - - parser->root.cursor = base; - parser->root.limit = base + size; - parser->root.error = FT_Err_Ok; - - { - FT_Byte* cur = base; - FT_Byte* limit = cur + size; - - - for (;;) - { - FT_Byte* newlimit; - - - parser->root.cursor = cur; - cid_parser_skip_spaces( parser ); - - if ( parser->root.cursor >= limit ) - newlimit = limit - 1 - 17; - else - newlimit = parser->root.cursor - 17; - - /* look for `%ADOBeginFontDict' */ - for ( ; cur < newlimit; cur++ ) - { - if ( *cur == '%' && - ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) - { - /* if /FDArray was found, then cid->num_dicts is > 0, and */ - /* we can start increasing parser->num_dict */ - if ( face->cid.num_dicts > 0 ) - parser->num_dict++; - } - } - - cur = parser->root.cursor; - /* no error can occur in cid_parser_skip_spaces */ - if ( cur >= limit ) - break; - - cid_parser_skip_PS_token( parser ); - if ( parser->root.cursor >= limit || parser->root.error ) - break; - - /* look for immediates */ - if ( *cur == '/' && cur + 2 < limit ) - { - FT_PtrDist len; - - - cur++; - len = parser->root.cursor - cur; - - if ( len > 0 && len < 22 ) - { - /* now compare the immediate name to the keyword table */ - T1_Field keyword = (T1_Field)cid_field_records; - - - for (;;) - { - FT_Byte* name; - - - name = (FT_Byte*)keyword->ident; - if ( !name ) - break; - - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char*)name ) ) - { - FT_PtrDist n; - - - for ( n = 1; n < len; n++ ) - if ( cur[n] != name[n] ) - break; - - if ( n >= len ) - { - /* we found it - run the parsing callback */ - parser->root.error = cid_load_keyword( face, - loader, - keyword ); - if ( parser->root.error ) - return parser->root.error; - break; - } - } - keyword++; - } - } - } - - cur = parser->root.cursor; - } - } - return parser->root.error; - } - - - /* read the subrmap and the subrs of each font dict */ - static FT_Error - cid_read_subrs( CID_Face face ) - { - CID_FaceInfo cid = &face->cid; - FT_Memory memory = face->root.memory; - FT_Stream stream = face->cid_stream; - FT_Error error; - FT_Int n; - CID_Subrs subr; - FT_UInt max_offsets = 0; - FT_ULong* offsets = 0; - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) ) - goto Exit; - - subr = face->subrs; - for ( n = 0; n < cid->num_dicts; n++, subr++ ) - { - CID_FaceDict dict = cid->font_dicts + n; - FT_Int lenIV = dict->private_dict.lenIV; - FT_UInt count, num_subrs = dict->num_subrs; - FT_ULong data_len; - FT_Byte* p; - - - /* Check for possible overflow. */ - if ( num_subrs == FT_UINT_MAX ) - { - error = FT_THROW( Syntax_Error ); - goto Fail; - } - - /* reallocate offsets array if needed */ - if ( num_subrs + 1 > max_offsets ) - { - FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 ); - - - if ( new_max <= max_offsets ) - { - error = FT_THROW( Syntax_Error ); - goto Fail; - } - - if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) - goto Fail; - - max_offsets = new_max; - } - - /* read the subrmap's offsets */ - if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || - FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) - goto Fail; - - p = (FT_Byte*)stream->cursor; - for ( count = 0; count <= num_subrs; count++ ) - offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); - - FT_FRAME_EXIT(); - - /* offsets must be ordered */ - for ( count = 1; count <= num_subrs; count++ ) - if ( offsets[count - 1] > offsets[count] ) - goto Fail; - - /* now, compute the size of subrs charstrings, */ - /* allocate, and read them */ - data_len = offsets[num_subrs] - offsets[0]; - - if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || - FT_ALLOC( subr->code[0], data_len ) ) - goto Fail; - - if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || - FT_STREAM_READ( subr->code[0], data_len ) ) - goto Fail; - - /* set up pointers */ - for ( count = 1; count <= num_subrs; count++ ) - { - FT_ULong len; - - - len = offsets[count] - offsets[count - 1]; - subr->code[count] = subr->code[count - 1] + len; - } - - /* decrypt subroutines, but only if lenIV >= 0 */ - if ( lenIV >= 0 ) - { - for ( count = 0; count < num_subrs; count++ ) - { - FT_ULong len; - - - len = offsets[count + 1] - offsets[count]; - psaux->t1_decrypt( subr->code[count], len, 4330 ); - } - } - - subr->num_subrs = num_subrs; - } - - Exit: - FT_FREE( offsets ); - return error; - - Fail: - if ( face->subrs ) - { - for ( n = 0; n < cid->num_dicts; n++ ) - { - if ( face->subrs[n].code ) - FT_FREE( face->subrs[n].code[0] ); - - FT_FREE( face->subrs[n].code ); - } - FT_FREE( face->subrs ); - } - goto Exit; - } - - - static void - cid_init_loader( CID_Loader* loader, - CID_Face face ) - { - FT_UNUSED( face ); - - FT_MEM_ZERO( loader, sizeof ( *loader ) ); - } - - - static void - cid_done_loader( CID_Loader* loader ) - { - CID_Parser* parser = &loader->parser; - - - /* finalize parser */ - cid_parser_done( parser ); - } - - - static FT_Error - cid_hex_to_binary( FT_Byte* data, - FT_Long data_len, - FT_ULong offset, - CID_Face face ) - { - FT_Stream stream = face->root.stream; - FT_Error error; - - FT_Byte buffer[256]; - FT_Byte *p, *plimit; - FT_Byte *d, *dlimit; - FT_Byte val; - - FT_Bool upper_nibble, done; - - - if ( FT_STREAM_SEEK( offset ) ) - goto Exit; - - d = data; - dlimit = d + data_len; - p = buffer; - plimit = p; - - upper_nibble = 1; - done = 0; - - while ( d < dlimit ) - { - if ( p >= plimit ) - { - FT_ULong oldpos = FT_STREAM_POS(); - FT_ULong size = stream->size - oldpos; - - - if ( size == 0 ) - { - error = FT_THROW( Syntax_Error ); - goto Exit; - } - - if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) ) - goto Exit; - p = buffer; - plimit = p + FT_STREAM_POS() - oldpos; - } - - if ( ft_isdigit( *p ) ) - val = (FT_Byte)( *p - '0' ); - else if ( *p >= 'a' && *p <= 'f' ) - val = (FT_Byte)( *p - 'a' ); - else if ( *p >= 'A' && *p <= 'F' ) - val = (FT_Byte)( *p - 'A' + 10 ); - else if ( *p == ' ' || - *p == '\t' || - *p == '\r' || - *p == '\n' || - *p == '\f' || - *p == '\0' ) - { - p++; - continue; - } - else if ( *p == '>' ) - { - val = 0; - done = 1; - } - else - { - error = FT_THROW( Syntax_Error ); - goto Exit; - } - - if ( upper_nibble ) - *d = (FT_Byte)( val << 4 ); - else - { - *d = (FT_Byte)( *d + val ); - d++; - } - - upper_nibble = (FT_Byte)( 1 - upper_nibble ); - - if ( done ) - break; - - p++; - } - - error = FT_Err_Ok; - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - cid_face_open( CID_Face face, - FT_Int face_index ) - { - CID_Loader loader; - CID_Parser* parser; - FT_Memory memory = face->root.memory; - FT_Error error; - - - cid_init_loader( &loader, face ); - - parser = &loader.parser; - error = cid_parser_new( parser, face->root.stream, face->root.memory, - (PSAux_Service)face->psaux ); - if ( error ) - goto Exit; - - error = cid_parse_dict( face, &loader, - parser->postscript, - parser->postscript_len ); - if ( error ) - goto Exit; - - if ( face_index < 0 ) - goto Exit; - - if ( FT_NEW( face->cid_stream ) ) - goto Exit; - - if ( parser->binary_length ) - { - /* we must convert the data section from hexadecimal to binary */ - if ( FT_ALLOC( face->binary_data, parser->binary_length ) || - cid_hex_to_binary( face->binary_data, parser->binary_length, - parser->data_offset, face ) ) - goto Exit; - - FT_Stream_OpenMemory( face->cid_stream, - face->binary_data, parser->binary_length ); - face->cid.data_offset = 0; - } - else - { - *face->cid_stream = *face->root.stream; - face->cid.data_offset = loader.parser.data_offset; - } - - error = cid_read_subrs( face ); - - Exit: - cid_done_loader( &loader ); - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidload.h b/drivers/freetype/freetype/src/cid/cidload.h deleted file mode 100644 index 8c172ffee2..0000000000 --- a/drivers/freetype/freetype/src/cid/cidload.h +++ /dev/null @@ -1,53 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidload.h */ -/* */ -/* CID-keyed Type1 font loader (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004 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 __CIDLOAD_H__ -#define __CIDLOAD_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_STREAM_H -#include "cidparse.h" - - -FT_BEGIN_HEADER - - - typedef struct CID_Loader_ - { - CID_Parser parser; /* parser used to read the stream */ - FT_Int num_chars; /* number of characters in encoding */ - - } CID_Loader; - - - FT_LOCAL( FT_Long ) - cid_get_offset( FT_Byte** start, - FT_Byte offsize ); - - FT_LOCAL( FT_Error ) - cid_face_open( CID_Face face, - FT_Int face_index ); - - -FT_END_HEADER - -#endif /* __CIDLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidobjs.c b/drivers/freetype/freetype/src/cid/cidobjs.c deleted file mode 100644 index 46555e2dc8..0000000000 --- a/drivers/freetype/freetype/src/cid/cidobjs.c +++ /dev/null @@ -1,491 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidobjs.c */ -/* */ -/* CID objects manager (body). */ -/* */ -/* Copyright 1996-2006, 2008, 2010-2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H - -#include "cidgload.h" -#include "cidload.h" - -#include FT_SERVICE_POSTSCRIPT_CMAPS_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H - -#include "ciderrs.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_cidobjs - - - /*************************************************************************/ - /* */ - /* SLOT FUNCTIONS */ - /* */ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - cid_slot_done( FT_GlyphSlot slot ) - { - slot->internal->glyph_hints = 0; - } - - - FT_LOCAL_DEF( FT_Error ) - cid_slot_init( FT_GlyphSlot slot ) - { - CID_Face face; - PSHinter_Service pshinter; - - - face = (CID_Face)slot->face; - pshinter = (PSHinter_Service)face->pshinter; - - if ( pshinter ) - { - FT_Module module; - - - module = FT_Get_Module( slot->face->driver->root.library, - "pshinter" ); - if ( module ) - { - T1_Hints_Funcs funcs; - - - funcs = pshinter->get_t1_funcs( module ); - slot->internal->glyph_hints = (void*)funcs; - } - } - - return 0; - } - - - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - static PSH_Globals_Funcs - cid_size_get_globals_funcs( CID_Size size ) - { - CID_Face face = (CID_Face)size->root.face; - PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; - FT_Module module; - - - module = FT_Get_Module( size->root.face->driver->root.library, - "pshinter" ); - return ( module && pshinter && pshinter->get_globals_funcs ) - ? pshinter->get_globals_funcs( module ) - : 0; - } - - - FT_LOCAL_DEF( void ) - cid_size_done( FT_Size cidsize ) /* CID_Size */ - { - CID_Size size = (CID_Size)cidsize; - - - if ( cidsize->internal ) - { - PSH_Globals_Funcs funcs; - - - funcs = cid_size_get_globals_funcs( size ); - if ( funcs ) - funcs->destroy( (PSH_Globals)cidsize->internal ); - - cidsize->internal = 0; - } - } - - - FT_LOCAL_DEF( FT_Error ) - cid_size_init( FT_Size cidsize ) /* CID_Size */ - { - CID_Size size = (CID_Size)cidsize; - FT_Error error = FT_Err_Ok; - PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size ); - - - if ( funcs ) - { - PSH_Globals globals; - CID_Face face = (CID_Face)cidsize->face; - CID_FaceDict dict = face->cid.font_dicts + face->root.face_index; - PS_Private priv = &dict->private_dict; - - - error = funcs->create( cidsize->face->memory, priv, &globals ); - if ( !error ) - cidsize->internal = (FT_Size_Internal)(void*)globals; - } - - return error; - } - - - FT_LOCAL( FT_Error ) - cid_size_request( FT_Size size, - FT_Size_Request req ) - { - PSH_Globals_Funcs funcs; - - - FT_Request_Metrics( size->face, req ); - - funcs = cid_size_get_globals_funcs( (CID_Size)size ); - - if ( funcs ) - funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, - 0, 0 ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cid_face_done */ - /* */ - /* <Description> */ - /* Finalizes a given face object. */ - /* */ - /* <Input> */ - /* face :: A pointer to the face object to destroy. */ - /* */ - FT_LOCAL_DEF( void ) - cid_face_done( FT_Face cidface ) /* CID_Face */ - { - CID_Face face = (CID_Face)cidface; - FT_Memory memory; - CID_FaceInfo cid; - PS_FontInfo info; - - - if ( !face ) - return; - - cid = &face->cid; - info = &cid->font_info; - memory = cidface->memory; - - /* release subrs */ - if ( face->subrs ) - { - FT_Int n; - - - for ( n = 0; n < cid->num_dicts; n++ ) - { - CID_Subrs subr = face->subrs + n; - - - if ( subr->code ) - { - FT_FREE( subr->code[0] ); - FT_FREE( subr->code ); - } - } - - FT_FREE( face->subrs ); - } - - /* release FontInfo strings */ - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); - - /* release font dictionaries */ - FT_FREE( cid->font_dicts ); - cid->num_dicts = 0; - - /* release other strings */ - FT_FREE( cid->cid_font_name ); - FT_FREE( cid->registry ); - FT_FREE( cid->ordering ); - - cidface->family_name = 0; - cidface->style_name = 0; - - FT_FREE( face->binary_data ); - FT_FREE( face->cid_stream ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cid_face_init */ - /* */ - /* <Description> */ - /* Initializes a given CID face object. */ - /* */ - /* <Input> */ - /* stream :: The source font stream. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* <InOut> */ - /* face :: The newly built face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - cid_face_init( FT_Stream stream, - FT_Face cidface, /* CID_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - CID_Face face = (CID_Face)cidface; - FT_Error error; - PSAux_Service psaux; - PSHinter_Service pshinter; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( stream ); - - - cidface->num_faces = 1; - - psaux = (PSAux_Service)face->psaux; - if ( !psaux ) - { - psaux = (PSAux_Service)FT_Get_Module_Interface( - FT_FACE_LIBRARY( face ), "psaux" ); - - if ( !psaux ) - { - FT_ERROR(( "cid_face_init: cannot access `psaux' module\n" )); - error = FT_THROW( Missing_Module ); - goto Exit; - } - - face->psaux = psaux; - } - - pshinter = (PSHinter_Service)face->pshinter; - if ( !pshinter ) - { - pshinter = (PSHinter_Service)FT_Get_Module_Interface( - FT_FACE_LIBRARY( face ), "pshinter" ); - - face->pshinter = pshinter; - } - - FT_TRACE2(( "CID driver\n" )); - - /* open the tokenizer; this will also check the font format */ - if ( FT_STREAM_SEEK( 0 ) ) - goto Exit; - - error = cid_face_open( face, face_index ); - if ( error ) - goto Exit; - - /* if we just wanted to check the format, leave successfully now */ - if ( face_index < 0 ) - goto Exit; - - /* check the face index */ - /* XXX: handle CID fonts with more than a single face */ - if ( face_index != 0 ) - { - FT_ERROR(( "cid_face_init: invalid face index\n" )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* now load the font program into the face object */ - - /* initialize the face object fields */ - - /* set up root face fields */ - { - CID_FaceInfo cid = &face->cid; - PS_FontInfo info = &cid->font_info; - - - cidface->num_glyphs = cid->cid_count; - cidface->num_charmaps = 0; - - cidface->face_index = face_index; - cidface->face_flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ - FT_FACE_FLAG_HINTER; /* has native hinter */ - - if ( info->is_fixed_pitch ) - cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* XXX: TODO: add kerning with .afm support */ - - /* get style name -- be careful, some broken fonts only */ - /* have a /FontName dictionary entry! */ - cidface->family_name = info->family_name; - /* assume "Regular" style if we don't know better */ - cidface->style_name = (char *)"Regular"; - if ( cidface->family_name ) - { - char* full = info->full_name; - char* family = cidface->family_name; - - - if ( full ) - { - while ( *full ) - { - if ( *full == *family ) - { - family++; - full++; - } - else - { - if ( *full == ' ' || *full == '-' ) - full++; - else if ( *family == ' ' || *family == '-' ) - family++; - else - { - if ( !*family ) - cidface->style_name = full; - break; - } - } - } - } - } - else - { - /* do we have a `/FontName'? */ - if ( cid->cid_font_name ) - cidface->family_name = cid->cid_font_name; - } - - /* compute style flags */ - cidface->style_flags = 0; - if ( info->italic_angle ) - cidface->style_flags |= FT_STYLE_FLAG_ITALIC; - if ( info->weight ) - { - if ( !ft_strcmp( info->weight, "Bold" ) || - !ft_strcmp( info->weight, "Black" ) ) - cidface->style_flags |= FT_STYLE_FLAG_BOLD; - } - - /* no embedded bitmap support */ - cidface->num_fixed_sizes = 0; - cidface->available_sizes = 0; - - cidface->bbox.xMin = cid->font_bbox.xMin >> 16; - cidface->bbox.yMin = cid->font_bbox.yMin >> 16; - /* no `U' suffix here to 0xFFFF! */ - cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFF ) >> 16; - cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFF ) >> 16; - - if ( !cidface->units_per_EM ) - cidface->units_per_EM = 1000; - - cidface->ascender = (FT_Short)( cidface->bbox.yMax ); - cidface->descender = (FT_Short)( cidface->bbox.yMin ); - - cidface->height = (FT_Short)( ( cidface->units_per_EM * 12 ) / 10 ); - if ( cidface->height < cidface->ascender - cidface->descender ) - cidface->height = (FT_Short)( cidface->ascender - cidface->descender ); - - cidface->underline_position = (FT_Short)info->underline_position; - cidface->underline_thickness = (FT_Short)info->underline_thickness; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cid_driver_init */ - /* */ - /* <Description> */ - /* Initializes a given CID driver object. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target driver object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - cid_driver_init( FT_Module driver ) - { - FT_UNUSED( driver ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cid_driver_done */ - /* */ - /* <Description> */ - /* Finalizes a given CID driver. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target CID driver. */ - /* */ - FT_LOCAL_DEF( void ) - cid_driver_done( FT_Module driver ) - { - FT_UNUSED( driver ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidobjs.h b/drivers/freetype/freetype/src/cid/cidobjs.h deleted file mode 100644 index aee346d1c8..0000000000 --- a/drivers/freetype/freetype/src/cid/cidobjs.h +++ /dev/null @@ -1,154 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidobjs.h */ -/* */ -/* CID objects manager (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2004, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __CIDOBJS_H__ -#define __CIDOBJS_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_TYPE1_TYPES_H - - -FT_BEGIN_HEADER - - - /* The following structures must be defined by the hinter */ - typedef struct CID_Size_Hints_ CID_Size_Hints; - typedef struct CID_Glyph_Hints_ CID_Glyph_Hints; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CID_Driver */ - /* */ - /* <Description> */ - /* A handle to a Type 1 driver object. */ - /* */ - typedef struct CID_DriverRec_* CID_Driver; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CID_Size */ - /* */ - /* <Description> */ - /* A handle to a Type 1 size object. */ - /* */ - typedef struct CID_SizeRec_* CID_Size; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CID_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to a Type 1 glyph slot object. */ - /* */ - typedef struct CID_GlyphSlotRec_* CID_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CID_CharMap */ - /* */ - /* <Description> */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* <Note> */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ - typedef struct CID_CharMapRec_* CID_CharMap; - - - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE 1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ - - - typedef struct CID_SizeRec_ - { - FT_SizeRec root; - FT_Bool valid; - - } CID_SizeRec; - - - typedef struct CID_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - } CID_GlyphSlotRec; - - - FT_LOCAL( void ) - cid_slot_done( FT_GlyphSlot slot ); - - FT_LOCAL( FT_Error ) - cid_slot_init( FT_GlyphSlot slot ); - - - FT_LOCAL( void ) - cid_size_done( FT_Size size ); /* CID_Size */ - - FT_LOCAL( FT_Error ) - cid_size_init( FT_Size size ); /* CID_Size */ - - FT_LOCAL( FT_Error ) - cid_size_request( FT_Size size, /* CID_Size */ - FT_Size_Request req ); - - FT_LOCAL( FT_Error ) - cid_face_init( FT_Stream stream, - FT_Face face, /* CID_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - FT_LOCAL( void ) - cid_face_done( FT_Face face ); /* CID_Face */ - - - FT_LOCAL( FT_Error ) - cid_driver_init( FT_Module driver ); - - FT_LOCAL( void ) - cid_driver_done( FT_Module driver ); - - -FT_END_HEADER - -#endif /* __CIDOBJS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidparse.c b/drivers/freetype/freetype/src/cid/cidparse.c deleted file mode 100644 index 53df3155d1..0000000000 --- a/drivers/freetype/freetype/src/cid/cidparse.c +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidparse.c */ -/* */ -/* CID-keyed Type1 parser (body). */ -/* */ -/* Copyright 1996-2007, 2009, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_STREAM_H - -#include "cidparse.h" - -#include "ciderrs.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_cidparse - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** INPUT STREAM PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL_DEF( FT_Error ) - cid_parser_new( CID_Parser* parser, - FT_Stream stream, - FT_Memory memory, - PSAux_Service psaux ) - { - FT_Error error; - FT_ULong base_offset, offset, ps_len; - FT_Byte *cur, *limit; - FT_Byte *arg1, *arg2; - - - FT_MEM_ZERO( parser, sizeof ( *parser ) ); - psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); - - parser->stream = stream; - - base_offset = FT_STREAM_POS(); - - /* first of all, check the font format in the header */ - if ( FT_FRAME_ENTER( 31 ) ) - goto Exit; - - if ( ft_strncmp( (char *)stream->cursor, - "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) - { - FT_TRACE2(( " not a CID-keyed font\n" )); - error = FT_THROW( Unknown_File_Format ); - } - - FT_FRAME_EXIT(); - if ( error ) - goto Exit; - - Again: - /* now, read the rest of the file until we find */ - /* `StartData' or `/sfnts' */ - { - FT_Byte buffer[256 + 10]; - FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ - FT_Byte* p = buffer; - - - for ( offset = FT_STREAM_POS(); ; offset += 256 ) - { - FT_Long stream_len; /* same as signed FT_Stream->size */ - - - stream_len = stream->size - FT_STREAM_POS(); - if ( stream_len == 0 ) - { - FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - read_len = FT_MIN( read_len, stream_len ); - if ( FT_STREAM_READ( p, read_len ) ) - goto Exit; - - if ( read_len < 256 ) - p[read_len] = '\0'; - - limit = p + read_len - 10; - - for ( p = buffer; p < limit; p++ ) - { - if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) - { - /* save offset of binary data after `StartData' */ - offset += (FT_ULong)( p - buffer + 10 ); - goto Found; - } - else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) - { - offset += (FT_ULong)( p - buffer + 7 ); - goto Found; - } - } - - FT_MEM_MOVE( buffer, p, 10 ); - read_len = 256; - p = buffer + 10; - } - } - - Found: - /* 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 ) || - FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) - goto Exit; - - parser->data_offset = offset; - parser->postscript_len = ps_len; - parser->root.base = parser->postscript; - parser->root.cursor = parser->postscript; - parser->root.limit = parser->root.cursor + ps_len; - parser->num_dict = -1; - - /* 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 ); - cid_parser_skip_spaces ( parser ); - arg2 = parser->root.cursor; - cid_parser_skip_PS_token( parser ); - cid_parser_skip_spaces ( parser ); - - limit = parser->root.limit; - cur = parser->root.cursor; - - while ( cur < limit ) - { - if ( parser->root.error ) - { - error = parser->root.error; - goto Exit; - } - - 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 ); - - limit = parser->root.limit; - 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 = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - cid_parser_skip_PS_token( parser ); - cid_parser_skip_spaces ( parser ); - arg1 = arg2; - arg2 = cur; - cur = parser->root.cursor; - } - - /* we haven't found the correct `StartData'; go back and continue */ - /* searching */ - FT_FRAME_RELEASE( parser->postscript ); - if ( !FT_STREAM_SEEK( offset ) ) - goto Again; - - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - cid_parser_done( CID_Parser* parser ) - { - /* always free the private dictionary */ - if ( parser->postscript ) - { - FT_Stream stream = parser->stream; - - - FT_FRAME_RELEASE( parser->postscript ); - } - parser->root.funcs.done( &parser->root ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidparse.h b/drivers/freetype/freetype/src/cid/cidparse.h deleted file mode 100644 index ca37deab93..0000000000 --- a/drivers/freetype/freetype/src/cid/cidparse.h +++ /dev/null @@ -1,123 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidparse.h */ -/* */ -/* CID-keyed Type1 parser (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004 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 __CIDPARSE_H__ -#define __CIDPARSE_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_TYPE1_TYPES_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_Parser */ - /* */ - /* <Description> */ - /* A CID_Parser is an object used to parse a Type 1 fonts very */ - /* quickly. */ - /* */ - /* <Fields> */ - /* root :: The root PS_ParserRec fields. */ - /* */ - /* stream :: The current input stream. */ - /* */ - /* postscript :: A pointer to the data to be parsed. */ - /* */ - /* postscript_len :: The length of the data to be parsed. */ - /* */ - /* data_offset :: The start position of the binary data (i.e., the */ - /* end of the data to be parsed. */ - /* */ - /* binary_length :: The length of the data after the `StartData' */ - /* command if the data format is hexadecimal. */ - /* */ - /* cid :: A structure which holds the information about */ - /* the current font. */ - /* */ - /* num_dict :: The number of font dictionaries. */ - /* */ - typedef struct CID_Parser_ - { - PS_ParserRec root; - FT_Stream stream; - - FT_Byte* postscript; - FT_Long postscript_len; - - FT_ULong data_offset; - - FT_Long binary_length; - - CID_FaceInfo cid; - FT_Int num_dict; - - } CID_Parser; - - - FT_LOCAL( FT_Error ) - cid_parser_new( CID_Parser* parser, - FT_Stream stream, - FT_Memory memory, - PSAux_Service psaux ); - - FT_LOCAL( void ) - cid_parser_done( CID_Parser* parser ); - - - /*************************************************************************/ - /* */ - /* PARSING ROUTINES */ - /* */ - /*************************************************************************/ - -#define cid_parser_skip_spaces( p ) \ - (p)->root.funcs.skip_spaces( &(p)->root ) -#define cid_parser_skip_PS_token( p ) \ - (p)->root.funcs.skip_PS_token( &(p)->root ) - -#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) -#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) - -#define cid_parser_to_coord_array( p, m, c ) \ - (p)->root.funcs.to_coord_array( &(p)->root, m, c ) -#define cid_parser_to_fixed_array( p, m, f, t ) \ - (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) -#define cid_parser_to_token( p, t ) \ - (p)->root.funcs.to_token( &(p)->root, t ) -#define cid_parser_to_token_array( p, t, m, c ) \ - (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) - -#define cid_parser_load_field( p, f, o ) \ - (p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 ) -#define cid_parser_load_field_table( p, f, o ) \ - (p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 ) - - -FT_END_HEADER - -#endif /* __CIDPARSE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidriver.c b/drivers/freetype/freetype/src/cid/cidriver.c deleted file mode 100644 index 6132a27763..0000000000 --- a/drivers/freetype/freetype/src/cid/cidriver.c +++ /dev/null @@ -1,236 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidriver.c */ -/* */ -/* CID driver interface (body). */ -/* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 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 "cidriver.h" -#include "cidgload.h" -#include FT_INTERNAL_DEBUG_H - -#include "ciderrs.h" - -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_XFREE86_NAME_H -#include FT_SERVICE_POSTSCRIPT_INFO_H -#include FT_SERVICE_CID_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_ciddriver - - - /* - * POSTSCRIPT NAME SERVICE - * - */ - - static const char* - cid_get_postscript_name( CID_Face face ) - { - const char* result = face->cid.cid_font_name; - - - if ( result && result[0] == '/' ) - result++; - - return result; - } - - - static const FT_Service_PsFontNameRec cid_service_ps_name = - { - (FT_PsName_GetFunc) cid_get_postscript_name - }; - - - /* - * POSTSCRIPT INFO SERVICE - * - */ - - static FT_Error - cid_ps_get_font_info( FT_Face face, - PS_FontInfoRec* afont_info ) - { - *afont_info = ((CID_Face)face)->cid.font_info; - - return FT_Err_Ok; - } - - static FT_Error - cid_ps_get_font_extra( FT_Face face, - PS_FontExtraRec* afont_extra ) - { - *afont_extra = ((CID_Face)face)->font_extra; - - return FT_Err_Ok; - } - - static const FT_Service_PsInfoRec cid_service_ps_info = - { - (PS_GetFontInfoFunc) cid_ps_get_font_info, - (PS_GetFontExtraFunc) cid_ps_get_font_extra, - (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ - (PS_GetFontPrivateFunc)NULL, /* unsupported */ - (PS_GetFontValueFunc) NULL /* not implemented */ - }; - - - /* - * CID INFO SERVICE - * - */ - static FT_Error - cid_get_ros( CID_Face face, - const char* *registry, - const char* *ordering, - FT_Int *supplement ) - { - CID_FaceInfo cid = &face->cid; - - - if ( registry ) - *registry = cid->registry; - - if ( ordering ) - *ordering = cid->ordering; - - if ( supplement ) - *supplement = cid->supplement; - - return FT_Err_Ok; - } - - - static FT_Error - cid_get_is_cid( CID_Face face, - FT_Bool *is_cid ) - { - FT_Error error = FT_Err_Ok; - FT_UNUSED( face ); - - - if ( is_cid ) - *is_cid = 1; /* cid driver is only used for CID keyed fonts */ - - return error; - } - - - static FT_Error - cid_get_cid_from_glyph_index( CID_Face face, - FT_UInt glyph_index, - FT_UInt *cid ) - { - FT_Error error = FT_Err_Ok; - FT_UNUSED( face ); - - - if ( cid ) - *cid = glyph_index; /* identity mapping */ - - return error; - } - - - static const FT_Service_CIDRec cid_service_cid_info = - { - (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index - }; - - - /* - * SERVICE LIST - * - */ - - static const FT_ServiceDescRec cid_services[] = - { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, - { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, - { FT_SERVICE_ID_CID, &cid_service_cid_info }, - { NULL, NULL } - }; - - - FT_CALLBACK_DEF( FT_Module_Interface ) - cid_get_interface( FT_Module module, - const char* cid_interface ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( cid_services, cid_interface ); - } - - - - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec t1cid_driver_class = - { - /* first of all, the FT_Module_Class fields */ - { - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - FT_MODULE_DRIVER_HAS_HINTER, - - sizeof ( FT_DriverRec ), - "t1cid", /* module name */ - 0x10000L, /* version 1.0 of driver */ - 0x20000L, /* requires FreeType 2.0 */ - - 0, - - cid_driver_init, - cid_driver_done, - cid_get_interface - }, - - /* then the other font drivers fields */ - sizeof ( CID_FaceRec ), - sizeof ( CID_SizeRec ), - sizeof ( CID_GlyphSlotRec ), - - cid_face_init, - cid_face_done, - - cid_size_init, - cid_size_done, - cid_slot_init, - cid_slot_done, - - cid_slot_load_glyph, - - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - - 0, /* FT_Face_GetAdvancesFunc */ - - cid_size_request, - 0 /* FT_Size_SelectFunc */ - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidriver.h b/drivers/freetype/freetype/src/cid/cidriver.h deleted file mode 100644 index 3c45e06886..0000000000 --- a/drivers/freetype/freetype/src/cid/cidriver.h +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidriver.h */ -/* */ -/* High-level CID driver interface (specification). */ -/* */ -/* Copyright 1996-2001, 2002 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 __CIDRIVER_H__ -#define __CIDRIVER_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - - FT_CALLBACK_TABLE - const FT_Driver_ClassRec t1cid_driver_class; - - -FT_END_HEADER - -#endif /* __CIDRIVER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/cidtoken.h b/drivers/freetype/freetype/src/cid/cidtoken.h deleted file mode 100644 index 904cb09cf4..0000000000 --- a/drivers/freetype/freetype/src/cid/cidtoken.h +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidtoken.h */ -/* */ -/* CID token definitions (specification only). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 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. */ -/* */ -/***************************************************************************/ - - -#undef FT_STRUCTURE -#define FT_STRUCTURE CID_FaceInfoRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_CID_INFO - - T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 ) - T1_FIELD_FIXED ( "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 -#define FT_STRUCTURE PS_FontInfoRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_INFO - - 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 -#define FT_STRUCTURE PS_FontExtraRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA - - T1_FIELD_NUM ( "FSType", fs_type, 0 ) - - -#undef FT_STRUCTURE -#define FT_STRUCTURE CID_FaceDictRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_DICT - - 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( "StrokeWidth", stroke_width, 0 ) - - -#undef FT_STRUCTURE -#define FT_STRUCTURE PS_PrivateRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_PRIVATE - - 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, 0 ) - T1_FIELD_NUM ( "BlueShift", blue_shift, 0 ) - T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, 0 ) - - 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, 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, 0 ) - T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 ) - - T1_FIELD_BOOL ( "ForceBold", force_bold, 0 ) - - -#undef FT_STRUCTURE -#define FT_STRUCTURE FT_BBox -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_BBOX - - T1_FIELD_BBOX( "FontBBox", xMin, 0 ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/cid/module.mk b/drivers/freetype/freetype/src/cid/module.mk deleted file mode 100644 index ce30bfd7ae..0000000000 --- a/drivers/freetype/freetype/src/cid/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 CID module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += TYPE1CID_DRIVER - -define TYPE1CID_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, t1cid_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/cid/rules.mk b/drivers/freetype/freetype/src/cid/rules.mk deleted file mode 100644 index f362744612..0000000000 --- a/drivers/freetype/freetype/src/cid/rules.mk +++ /dev/null @@ -1,70 +0,0 @@ -# -# FreeType 2 CID driver configuration rules -# - - -# Copyright 1996-2000, 2001, 2003 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. - - -# CID driver directory -# -CID_DIR := $(SRC_DIR)/cid - - -CID_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CID_DIR)) - - -# CID driver sources (i.e., C files) -# -CID_DRV_SRC := $(CID_DIR)/cidparse.c \ - $(CID_DIR)/cidload.c \ - $(CID_DIR)/cidriver.c \ - $(CID_DIR)/cidgload.c \ - $(CID_DIR)/cidobjs.c - -# CID driver headers -# -CID_DRV_H := $(CID_DRV_SRC:%.c=%.h) \ - $(CID_DIR)/cidtoken.h \ - $(CID_DIR)/ciderrs.h - - -# CID driver object(s) -# -# CID_DRV_OBJ_M is used during `multi' builds -# CID_DRV_OBJ_S is used during `single' builds -# -CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR)/%.c=$(OBJ_DIR)/%.$O) -CID_DRV_OBJ_S := $(OBJ_DIR)/type1cid.$O - -# CID driver source file for single build -# -CID_DRV_SRC_S := $(CID_DIR)/type1cid.c - - -# CID driver - single object -# -$(CID_DRV_OBJ_S): $(CID_DRV_SRC_S) $(CID_DRV_SRC) $(FREETYPE_H) $(CID_DRV_H) - $(CID_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CID_DRV_SRC_S)) - - -# CID driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(CID_DIR)/%.c $(FREETYPE_H) $(CID_DRV_H) - $(CID_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(CID_DRV_OBJ_S) -DRV_OBJS_M += $(CID_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/cid/type1cid.c b/drivers/freetype/freetype/src/cid/type1cid.c deleted file mode 100644 index 0b866e97c4..0000000000 --- a/drivers/freetype/freetype/src/cid/type1cid.c +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* type1cid.c */ -/* */ -/* FreeType OpenType driver component (body only). */ -/* */ -/* Copyright 1996-2001 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "cidparse.c" -#include "cidload.c" -#include "cidobjs.c" -#include "cidriver.c" -#include "cidgload.c" - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/Jamfile b/drivers/freetype/freetype/src/gxvalid/Jamfile deleted file mode 100644 index 88049a625d..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/Jamfile +++ /dev/null @@ -1,33 +0,0 @@ -# FreeType 2 src/gxvalid Jamfile -# -# Copyright 2005 by -# suzuki toshiya, Masatake YAMATO and Red Hat K.K. -# -# 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) gxvalid ; - - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = gxvcommn gxvfeat gxvbsln gxvtrak gxvopbd gxvprop - gxvmort gxvmort0 gxvmort1 gxvmort2 gxvmort4 gxvmort5 - gxvmorx gxvmorx0 gxvmorx1 gxvmorx2 gxvmorx4 gxvmorx5 - gxvlcar gxvkern gxvmod gxvjust ; - } - else - { - _sources = gxvalid ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/gxvalid Jamfile diff --git a/drivers/freetype/freetype/src/gxvalid/README b/drivers/freetype/freetype/src/gxvalid/README deleted file mode 100644 index 28e535b0bc..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/README +++ /dev/null @@ -1,532 +0,0 @@ -gxvalid: TrueType GX validator -============================== - - -1. What is this ---------------- - - `gxvalid' is a module to validate TrueType GX tables: a collection of - additional tables in TrueType font which are used by `QuickDraw GX - Text', Apple Advanced Typography (AAT). In addition, gxvalid can - validates `kern' tables which have been extended for AAT. Like the - otvalid module, gxvalid uses Freetype 2's validator framework - (ftvalid). - - You can link gxvalid with your program; before running your own layout - engine, gxvalid validates a font file. As the result, you can remove - error-checking code from the layout engine. It is also possible to - use gxvalid as a stand-alone font validator; the `ftvalid' test - program included in the ft2demo bundle calls gxvalid internally. - A stand-alone font validator may be useful for font developers. - - This documents documents the following issues. - - - supported TrueType GX tables - - fundamental validation limitations - - permissive error handling of broken GX tables - - `kern' table issue. - - -2. Supported tables -------------------- - - The following GX tables are currently supported. - - bsln - feat - just - kern(*) - lcar - mort - morx - opbd - prop - trak - - The following GX tables are currently unsupported. - - cvar - fdsc - fmtx - fvar - gvar - Zapf - - The following GX tables won't be supported. - - acnt(**) - hsty(***) - - The following undocumented tables in TrueType fonts designed for Apple - platform aren't handled either. - - addg - CVTM - TPNM - umif - - - *) The `kern' validator handles both the classic and the new kern - formats; the former is supported on both Microsoft and Apple - platforms, while the latter is supported on Apple platforms. - - **) `acnt' tables are not supported by currently available Apple font - tools. - - ***) There is one more Apple extension, `hsty', but it is for - Newton-OS, not GX (Newton-OS is a platform by Apple, but it can - use sfnt- housed bitmap fonts only). Therefore, it should be - excluded from `Apple platform' in the context of TrueType. - gxvalid ignores it as Apple font tools do so. - - - We have checked 183 fonts bundled with MacOS 9.1, MacOS 9.2, MacOS - 10.0, MacOS X 10.1, MSIE for MacOS, and AppleWorks 6.0. In addition, - we have checked 67 Dynalab fonts (designed for MacOS) and 189 Ricoh - fonts (designed for Windows and MacOS dual platforms). The number of - fonts including TrueType GX tables are as follows. - - bsln: 76 - feat: 191 - just: 84 - kern: 59 - lcar: 4 - mort: 326 - morx: 19 - opbd: 4 - prop: 114 - trak: 16 - - Dynalab and Ricoh fonts don't have GX tables except of `feat' and - `mort'. - - -3. Fundamental validation limitations -------------------------------------- - - TrueType GX provides layout information to libraries for font - rasterizers and text layout. gxvalid can check whether the layout - data in a font is conformant to the TrueType GX format specified by - Apple. But gxvalid cannot check a how QuickDraw GX/AAT renderer uses - the stored information. - - 3-1. Validation of State Machine activity - ----------------------------------------- - - QuickDraw GX/AAT uses a `State Machine' to provide `stateful' layout - features, and TrueType GX stores the state transition diagram of - this `State Machine' in a `StateTable' data structure. While the - State Machine receives a series of glyph IDs, the State Machine - starts with `start of text' state, walks around various states and - generates various layout information to the renderer, and finally - reaches the `end of text' state. - - gxvalid can check essential errors like: - - - possibility of state transitions to undefined states - - existence of glyph IDs that the State Machine doesn't know how - to handle - - the State Machine cannot compute the layout information from - given diagram - - These errors can be checked within finite steps, and without the - State Machine itself, because these are `expression' errors of state - transition diagram. - - There is no limitation about how long the State Machine walks - around, so validation of the algorithm in the state transition - diagram requires infinite steps, even if we had a State Machine in - gxvalid. Therefore, the following errors and problems cannot be - checked. - - - existence of states which the State Machine never transits to - - the possibility that the State Machine never reaches `end of - text' - - the possibility of stack underflow/overflow in the State Machine - (in ligature and contextual glyph substitutions, the State - Machine can store 16 glyphs onto its stack) - - In addition, gxvalid doesn't check `temporary glyph IDs' used in the - chained State Machines (in `mort' and `morx' tables). If a layout - feature is implemented by a single State Machine, a glyph ID - converted by the State Machine is passed to the glyph renderer, thus - it should not point to an undefined glyph ID. But if a layout - feature is implemented by chained State Machines, a component State - Machine (if it is not the final one) is permitted to generate - undefined glyph IDs for temporary use, because it is handled by next - component State Machine and not by the glyph renderer. To validate - such temporary glyph IDs, gxvalid must stack all undefined glyph IDs - which can occur in the output of the previous State Machine and - search them in the `ClassTable' structure of the current State - Machine. It is too complex to list all possible glyph IDs from the - StateTable, especially from a ligature substitution table. - - 3-2. Validation of relationship between multiple layout features - ---------------------------------------------------------------- - - gxvalid does not validate the relationship between multiple layout - features at all. - - If multiple layout features are defined in TrueType GX tables, - possible interactions, overrides, and conflicts between layout - features are implicitly given in the font too. For example, there - are several predefined spacing control features: - - - Text Spacing (Proportional/Monospace/Half-width/Normal) - - Number Spacing (Monospaced-numbers/Proportional-numbers) - - Kana Spacing (Full-width/Proportional) - - Ideographic Spacing (Full-width/Proportional) - - CJK Roman Spacing (Half-width/Proportional/Default-roman - /Full-width-roman/Proportional) - - If all layout features are independently managed, we can activate - inconsistent typographic rules like `Text Spacing=Monospace' and - `Ideographic Spacing=Proportional' at the same time. - - The combinations of layout features is managed by a 32bit integer - (one bit each for selector setting), so we can define relationships - between up to 32 features, theoretically. But if one feature - setting affects another feature setting, we need typographic - priority rules to validate the relationship. Unfortunately, the - TrueType GX format specification does not give such information even - for predefined features. - - -4. Permissive error handling of broken GX tables ------------------------------------------------- - - When Apple's font rendering system finds an inconsistency, like a - specification violation or an unspecified value in a TrueType GX - table, it does not always return error. In most cases, the rendering - engine silently ignores such wrong values or even whole tables. In - fact, MacOS is shipped with fonts including broken GX/AAT tables, but - no harmful effects due to `officially broken' fonts are observed by - end-users. - - gxvalid is designed to continue the validation process as long as - possible. When gxvalid find wrong values, gxvalid warns it at least, - and takes a fallback procedure if possible. The fallback procedure - depends on the debug level. - - We used the following three tools to investigate Apple's error handling. - - - FontValidator (for MacOS 8.5 - 9.2) resource fork font - - ftxvalidator (for MacOS X 10.1 -) dfont or naked-sfnt - - ftxdumperfuser (for MacOS X 10.1 -) dfont or naked-sfnt - - However, all tests were done on a PowerPC based Macintosh; at present, - we have not checked those tools on a m68k-based Macintosh. - - In total, we checked 183 fonts bundled to MacOS 9.1, MacOS 9.2, MacOS - 10.0, MacOS X 10.1, MSIE for MacOS, and AppleWorks 6.0. These fonts - are distributed officially, but many broken GX/AAT tables were found - by Apple's font tools. In the following, we list typical violation of - the GX specification, in fonts officially distributed with those Apple - systems. - - 4-1. broken BinSrchHeader (19/183) - ---------------------------------- - - `BinSrchHeader' is a header of a data array for m68k platforms to - access memory efficiently. Although there are only two independent - parameters for real (`unitSize' and `nUnits'), BinSrchHeader has - three additional parameters which can be calculated from `unitSize' - and `nUnits', for fast setup. Apple font tools ignore them - silently, so gxvalid warns if it finds and inconsistency, and always - continues validation. The additional parameters are ignored - regardless of the consistency. - - 19 fonts include such inconsistencies; all breaks are in the - BinSrchHeader structure of the `kern' table. - - 4-2. too-short LookupTable (5/183) - ---------------------------------- - - LookupTable format 0 is a simple array to get a value from a given - GID (glyph ID); the index of this array is a GID too. Therefore, - the length of the array is expected to be same as the maximum GID - value defined in the `maxp' table, but there are some fonts whose - LookupTable format 0 is too short to cover all GIDs. FontValidator - ignores this error silently, ftxvalidator and ftxdumperfuser both - warn and continue. Similar problems are found in format 3 subtables - of `kern'. gxvalid warns always and abort if the validation level - is set to FT_VALIDATE_PARANOID. - - 5 fonts include too-short kern format 0 subtables. - 1 font includes too-short kern format 3 subtable. - - 4-3. broken LookupTable format 2 (1/183) - ---------------------------------------- - - LookupTable format 2, subformat 4 covers the GID space by a - collection of segments which are specified by `firstGlyph' and - `lastGlyph'. Some fonts store `firstGlyph' and `lastGlyph' in - reverse order, so the segment specification is broken. Apple font - tools ignore this error silently; a broken segment is ignored as if - it did not exist. gxvalid warns and normalize the segment at - FT_VALIDATE_DEFAULT, or ignore the segment at FT_VALIDATE_TIGHT, or - abort at FT_VALIDATE_PARANOID. - - 1 font includes broken LookupTable format 2, in the `just' table. - - *) It seems that all fonts manufactured by ITC for AppleWorks have - this error. - - 4-4. bad bracketing in glyph property (14/183) - ---------------------------------------------- - - GX/AAT defines a `bracketing' property of the glyphs in the `prop' - table, to control layout features of strings enclosed inside and - outside of brackets. Some fonts give inappropriate bracket - properties to glyphs. Apple font tools warn about this error; - gxvalid warns too and aborts at FT_VALIDATE_PARANOID. - - 14 fonts include wrong bracket properties. - - - 4-5. invalid feature number (117/183) - ------------------------------------- - - The GX/AAT extension can include 255 different layout features, but - popular layout features are predefined (see - http://developer.apple.com/fonts/Registry/index.html). Some fonts - include feature numbers which are incompatible with the predefined - feature registry. - - In our survey, there are 140 fonts including `feat' table. - - a) 67 fonts use a feature number which should not be used. - b) 117 fonts set the wrong feature range (nSetting). This is mostly - found in the `mort' and `morx' tables. - - Apple font tools give no warning, although they cannot recognize - what the feature is. At FT_VALIDATE_DEFAULT, gxvalid warns but - continues in both cases (a, b). At FT_VALIDATE_TIGHT, gxvalid warns - and aborts for (a), but continues for (b). At FT_VALIDATE_PARANOID, - gxvalid warns and aborts in both cases (a, b). - - 4-6. invalid prop version (10/183) - ---------------------------------- - - As most TrueType GX tables, the `prop' table must start with a 32bit - version identifier: 0x00010000, 0x00020000 or 0x00030000. But some - fonts store nonsense binary data instead. When Apple font tools - find them, they abort the processing immediately, and the data which - follows is unhandled. gxvalid does the same. - - 10 fonts include broken `prop' version. - - All of these fonts are classic TrueType fonts for the Japanese - script, manufactured by Apple. - - 4-7. unknown resource name (2/183) - ------------------------------------ - - NOTE: THIS IS NOT A TRUETYPE GX ERROR. - - If a TrueType font is stored in the resource fork or in dfont - format, the data must be tagged as `sfnt' in the resource fork index - to invoke TrueType font handler for the data. But the TrueType font - data in `Keyboard.dfont' is tagged as `kbd', and that in - `LastResort.dfont' is tagged as `lst'. Apple font tools can detect - that the data is in TrueType format and successfully validate them. - Maybe this is possible because they are known to be dfont. The - current implementation of the resource fork driver of FreeType - cannot do that, thus gxvalid cannot validate them. - - 2 fonts use an unknown tag for the TrueType font resource. - -5. `kern' table issues ----------------------- - - In common terminology of TrueType, `kern' is classified as a basic and - platform-independent table. But there are Apple extensions of `kern', - and there is an extension which requires a GX state machine for - contextual kerning. Therefore, gxvalid includes a special validator - for `kern' tables. Unfortunately, there is no exact algorithm to - check Apple's extension, so gxvalid includes a heuristic algorithm to - find the proper validation routines for all possible data formats, - including the data format for Microsoft. By calling - classic_kern_validate() instead of gxv_validate(), you can specify the - `kern' format explicitly. However, current FreeType2 uses Microsoft - `kern' format only, others are ignored (and should be handled in a - library one level higher than FreeType). - - 5-1. History - ------------ - - The original 16bit version of `kern' was designed by Apple in the - pre-GX era, and it was also approved by Microsoft. Afterwards, - Apple designed a new 32bit version of the `kern' table. According - to the documentation, the difference between the 16bit and 32bit - version is only the size of variables in the `kern' header. In the - following, we call the original 16bit version as `classic', and - 32bit version as `new'. - - 5-2. Versions and dialects which should be differentiated - --------------------------------------------------------- - - The `kern' table consists of a table header and several subtables. - The version number which identifies a `classic' or a `new' version - is explicitly written in the table header, but there are - undocumented differences between Microsoft's and Apple's formats. - It is called a `dialect' in the following. There are three cases - which should be handled: the new Apple-dialect, the classic - Apple-dialect, and the classic Microsoft-dialect. An analysis of - the formats and the auto detection algorithm of gxvalid is described - in the following. - - 5-2-1. Version detection: classic and new kern - ---------------------------------------------- - - According to Apple TrueType specification, there are only two - differences between the classic and the new: - - - The `kern' table header starts with the version number. - The classic version starts with 0x0000 (16bit), - the new version starts with 0x00010000 (32bit). - - - In the `kern' table header, the number of subtables follows - the version number. - In the classic version, it is stored as a 16bit value. - In the new version, it is stored as a 32bit value. - - From Apple font tool's output (DumpKERN is also tested in addition - to the three Apple font tools in above), there is another - undocumented difference. In the new version, the subtable header - includes a 16bit variable named `tupleIndex' which does not exist - in the classic version. - - The new version can store all subtable formats (0, 1, 2, and 3), - but the Apple TrueType specification does not mention the subtable - formats available in the classic version. - - 5-2-2. Available subtable formats in classic version - ---------------------------------------------------- - - Although the Apple TrueType specification recommends to use the - classic version in the case if the font is designed for both the - Apple and Microsoft platforms, it does not document the available - subtable formats in the classic version. - - According to the Microsoft TrueType specification, the subtable - format assured for Windows and OS/2 support is only subtable - format 0. The Microsoft TrueType specification also describes - subtable format 2, but does not mention which platforms support - it. Aubtable formats 1, 3, and higher are documented as reserved - for future use. Therefore, the classic version can store subtable - formats 0 and 2, at least. `ttfdump.exe', a font tool provided by - Microsoft, ignores the subtable format written in the subtable - header, and parses the table as if all subtables are in format 0. - - `kern' subtable format 1 uses a StateTable, so it cannot be - utilized without a GX State Machine. Therefore, it is reasonable - to assume that format 1 (and 3) were introduced after Apple had - introduced GX and moved to the new 32bit version. - - 5-2-3. Apple and Microsoft dialects - ----------------------------------- - - The `kern' subtable has a 16bit `coverage' field to describe - kerning attributes, but bit interpretations by Apple and Microsoft - are different: For example, Apple uses bits 0-7 to identify the - subtable, while Microsoft uses bits 8-15. - - In addition, due to the output of DumpKERN and FontValidator, - Apple's bit interpretations of coverage in classic and new version - are incompatible also. In summary, there are three dialects: - classic Apple dialect, classic Microsoft dialect, and new Apple - dialect. The classic Microsoft dialect and the new Apple dialect - are documented by each vendors' TrueType font specification, but - the documentation for classic Apple dialect is not available. - - For example, in the new Apple dialect, bit 15 is documented as - `set to 1 if the kerning is vertical'. On the other hand, in - classic Microsoft dialect, bit 1 is documented as `set to 1 if the - kerning is horizontal'. From the outputs of DumpKERN and - FontValidator, classic Apple dialect recognizes 15 as `set to 1 - when the kerning is horizontal'. From the results of similar - experiments, classic Apple dialect seems to be the Endian reverse - of the classic Microsoft dialect. - - As a conclusion it must be noted that no font tool can identify - classic Apple dialect or classic Microsoft dialect automatically. - - 5-2-4. gxvalid auto dialect detection algorithm - ----------------------------------------------- - - The first 16 bits of the `kern' table are enough to identify the - version: - - - if the first 16 bits are 0x0000, the `kern' table is in - classic Apple dialect or classic Microsoft dialect - - if the first 16 bits are 0x0001, and next 16 bits are 0x0000, - the kern table is in new Apple dialect. - - If the `kern' table is a classic one, the 16bit `coverage' field - is checked next. Firstly, the coverage bits are decoded for the - classic Apple dialect using the following bit masks (this is based - on DumpKERN output): - - 0x8000: 1=horizontal, 0=vertical - 0x4000: not used - 0x2000: 1=cross-stream, 0=normal - 0x1FF0: reserved - 0x000F: subtable format - - If any of reserved bits are set or the subtable bits is - interpreted as format 1 or 3, we take it as `impossible in classic - Apple dialect' and retry, using the classic Microsoft dialect. - - The most popular coverage in new Apple-dialect: 0x8000, - The most popular coverage in classic Apple-dialect: 0x0000, - The most popular coverage in classic Microsoft dialect: 0x0001. - - 5-3. Tested fonts - ----------------- - - We checked 59 fonts bundled with MacOS and 38 fonts bundled with - Windows, where all font include a `kern' table. - - - fonts bundled with MacOS - * new Apple dialect - format 0: 18 - format 2: 1 - format 3: 1 - * classic Apple dialect - format 0: 14 - * classic Microsoft dialect - format 0: 15 - - - fonts bundled with Windows - * classic Microsoft dialect - format 0: 38 - - It looks strange that classic Microsoft-dialect fonts are bundled to - MacOS: they come from MSIE for MacOS, except of MarkerFelt.dfont. - - - ACKNOWLEDGEMENT - --------------- - - Some parts of gxvalid are derived from both the `gxlayout' module and - the `otvalid' module. Development of gxlayout was supported by the - Information-technology Promotion Agency(IPA), Japan. - - The detailed analysis of undefined glyph ID utilization in `mort' and - `morx' tables is provided by George Williams. - ------------------------------------------------------------------------- - -Copyright 2004, 2005, 2007 by -suzuki toshiya, Masatake YAMATO, Red hat K.K., -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. - - ---- end of README --- diff --git a/drivers/freetype/freetype/src/gxvalid/gxvalid.c b/drivers/freetype/freetype/src/gxvalid/gxvalid.c deleted file mode 100644 index bc36e675d1..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvalid.c +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvalid.c */ -/* */ -/* FreeType validator for TrueTypeGX/AAT tables (body only). */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> - -#include "gxvfeat.c" -#include "gxvcommn.c" -#include "gxvbsln.c" -#include "gxvtrak.c" -#include "gxvjust.c" -#include "gxvmort.c" -#include "gxvmort0.c" -#include "gxvmort1.c" -#include "gxvmort2.c" -#include "gxvmort4.c" -#include "gxvmort5.c" -#include "gxvmorx.c" -#include "gxvmorx0.c" -#include "gxvmorx1.c" -#include "gxvmorx2.c" -#include "gxvmorx4.c" -#include "gxvmorx5.c" -#include "gxvkern.c" -#include "gxvopbd.c" -#include "gxvprop.c" -#include "gxvlcar.c" -#include "gxvmod.c" - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvalid.h b/drivers/freetype/freetype/src/gxvalid/gxvalid.h deleted file mode 100644 index 27be9ecca8..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvalid.h +++ /dev/null @@ -1,107 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvalid.h */ -/* */ -/* TrueTyeeGX/AAT table validation (specification only). */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#ifndef __GXVALID_H__ -#define __GXVALID_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#include "gxverror.h" /* must come before FT_INTERNAL_VALIDATE_H */ - -#include FT_INTERNAL_VALIDATE_H -#include FT_INTERNAL_STREAM_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( void ) - gxv_feat_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - - FT_LOCAL( void ) - gxv_bsln_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - - FT_LOCAL( void ) - gxv_trak_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - FT_LOCAL( void ) - gxv_just_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - FT_LOCAL( void ) - gxv_mort_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - FT_LOCAL( void ) - gxv_morx_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - FT_LOCAL( void ) - gxv_kern_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - FT_LOCAL( void ) - gxv_kern_validate_classic( FT_Bytes table, - FT_Face face, - FT_Int dialect_flags, - FT_Validator valid ); - - FT_LOCAL( void ) - gxv_opbd_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - FT_LOCAL( void ) - gxv_prop_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - FT_LOCAL( void ) - gxv_lcar_validate( FT_Bytes table, - FT_Face face, - FT_Validator valid ); - - -FT_END_HEADER - - -#endif /* __GXVALID_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvbsln.c b/drivers/freetype/freetype/src/gxvalid/gxvbsln.c deleted file mode 100644 index 3d10031563..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvbsln.c +++ /dev/null @@ -1,333 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvbsln.c */ -/* */ -/* TrueTypeGX/AAT bsln table validation (body). */ -/* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvalid.h" -#include "gxvcommn.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_gxvbsln - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Data and Types *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define GXV_BSLN_VALUE_COUNT 32 -#define GXV_BSLN_VALUE_EMPTY 0xFFFFU - - - typedef struct GXV_bsln_DataRec_ - { - FT_Bytes ctlPoints_p; - FT_UShort defaultBaseline; - - } GXV_bsln_DataRec, *GXV_bsln_Data; - - -#define GXV_BSLN_DATA( field ) GXV_TABLE_DATA( bsln, field ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - gxv_bsln_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - FT_UShort v = value_p->u; - FT_UShort* ctlPoints; - - FT_UNUSED( glyph ); - - - GXV_NAME_ENTER( "lookup value" ); - - if ( v >= GXV_BSLN_VALUE_COUNT ) - FT_INVALID_DATA; - - ctlPoints = (FT_UShort*)GXV_BSLN_DATA( ctlPoints_p ); - if ( ctlPoints && ctlPoints[v] == GXV_BSLN_VALUE_EMPTY ) - FT_INVALID_DATA; - - GXV_EXIT; - } - - - /* - +===============+ --------+ - | lookup header | | - +===============+ | - | BinSrchHeader | | - +===============+ | - | lastGlyph[0] | | - +---------------+ | - | firstGlyph[0] | | head of lookup table - +---------------+ | + - | offset[0] | -> | offset [byte] - +===============+ | + - | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] - +---------------+ | - | firstGlyph[1] | | - +---------------+ | - | offset[1] | | - +===============+ | - | - ... | - | - 16bit value array | - +===============+ | - | value | <-------+ - ... - */ - - static GXV_LookupValueDesc - gxv_bsln_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueCPtr base_value_p, - FT_Bytes lookuptbl_limit, - GXV_Validator valid ) - { - FT_Bytes p; - FT_Bytes limit; - FT_UShort offset; - GXV_LookupValueDesc value; - - /* XXX: check range ? */ - offset = (FT_UShort)( base_value_p->u + - ( relative_gindex * sizeof ( FT_UShort ) ) ); - - p = valid->lookuptbl_head + offset; - limit = lookuptbl_limit; - GXV_LIMIT_CHECK( 2 ); - - value.u = FT_NEXT_USHORT( p ); - - return value; - } - - - static void - gxv_bsln_parts_fmt0_validate( FT_Bytes tables, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = tables; - - - GXV_NAME_ENTER( "parts format 0" ); - - /* deltas */ - GXV_LIMIT_CHECK( 2 * GXV_BSLN_VALUE_COUNT ); - - valid->table_data = NULL; /* No ctlPoints here. */ - - GXV_EXIT; - } - - - static void - gxv_bsln_parts_fmt1_validate( FT_Bytes tables, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = tables; - - - GXV_NAME_ENTER( "parts format 1" ); - - /* deltas */ - gxv_bsln_parts_fmt0_validate( p, limit, valid ); - - /* mappingData */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_bsln_LookupValue_validate; - valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; - gxv_LookupTable_validate( p + 2 * GXV_BSLN_VALUE_COUNT, - limit, - valid ); - - GXV_EXIT; - } - - - static void - gxv_bsln_parts_fmt2_validate( FT_Bytes tables, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = tables; - - FT_UShort stdGlyph; - FT_UShort ctlPoint; - FT_Int i; - - FT_UShort defaultBaseline = GXV_BSLN_DATA( defaultBaseline ); - - - GXV_NAME_ENTER( "parts format 2" ); - - GXV_LIMIT_CHECK( 2 + ( 2 * GXV_BSLN_VALUE_COUNT ) ); - - /* stdGlyph */ - stdGlyph = FT_NEXT_USHORT( p ); - GXV_TRACE(( " (stdGlyph = %u)\n", stdGlyph )); - - gxv_glyphid_validate( stdGlyph, valid ); - - /* Record the position of ctlPoints */ - GXV_BSLN_DATA( ctlPoints_p ) = p; - - /* ctlPoints */ - for ( i = 0; i < GXV_BSLN_VALUE_COUNT; i++ ) - { - ctlPoint = FT_NEXT_USHORT( p ); - if ( ctlPoint == GXV_BSLN_VALUE_EMPTY ) - { - if ( i == defaultBaseline ) - FT_INVALID_DATA; - } - else - gxv_ctlPoint_validate( stdGlyph, (FT_Short)ctlPoint, valid ); - } - - GXV_EXIT; - } - - - static void - gxv_bsln_parts_fmt3_validate( FT_Bytes tables, - FT_Bytes limit, - GXV_Validator valid) - { - FT_Bytes p = tables; - - - GXV_NAME_ENTER( "parts format 3" ); - - /* stdGlyph + ctlPoints */ - gxv_bsln_parts_fmt2_validate( p, limit, valid ); - - /* mappingData */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_bsln_LookupValue_validate; - valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; - gxv_LookupTable_validate( p + ( 2 + 2 * GXV_BSLN_VALUE_COUNT ), - limit, - valid ); - - GXV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** bsln TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - gxv_bsln_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - - GXV_bsln_DataRec bslnrec; - GXV_bsln_Data bsln = &bslnrec; - - FT_Bytes p = table; - FT_Bytes limit = 0; - - FT_ULong version; - FT_UShort format; - FT_UShort defaultBaseline; - - GXV_Validate_Func fmt_funcs_table [] = - { - gxv_bsln_parts_fmt0_validate, - gxv_bsln_parts_fmt1_validate, - gxv_bsln_parts_fmt2_validate, - gxv_bsln_parts_fmt3_validate, - }; - - - valid->root = ftvalid; - valid->table_data = bsln; - valid->face = face; - - FT_TRACE3(( "validating `bsln' table\n" )); - GXV_INIT; - - - GXV_LIMIT_CHECK( 4 + 2 + 2 ); - version = FT_NEXT_ULONG( p ); - format = FT_NEXT_USHORT( p ); - defaultBaseline = FT_NEXT_USHORT( p ); - - /* only version 1.0 is defined (1996) */ - if ( version != 0x00010000UL ) - FT_INVALID_FORMAT; - - /* only format 1, 2, 3 are defined (1996) */ - GXV_TRACE(( " (format = %d)\n", format )); - if ( format > 3 ) - FT_INVALID_FORMAT; - - if ( defaultBaseline > 31 ) - FT_INVALID_FORMAT; - - bsln->defaultBaseline = defaultBaseline; - - fmt_funcs_table[format]( p, limit, valid ); - - FT_TRACE4(( "\n" )); - } - - -/* arch-tag: ebe81143-fdaa-4c68-a4d1-b57227daa3bc - (do not change this comment) */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvcommn.c b/drivers/freetype/freetype/src/gxvalid/gxvcommn.c deleted file mode 100644 index 2ac80be8c7..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvcommn.c +++ /dev/null @@ -1,1744 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvcommn.c */ -/* */ -/* TrueTypeGX/AAT common tables validation (body). */ -/* */ -/* Copyright 2004, 2005, 2009, 2010, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvcommn.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_gxvcommon - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** 16bit offset sorter *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static int - gxv_compare_ushort_offset( FT_UShort* a, - FT_UShort* b ) - { - if ( *a < *b ) - return -1; - else if ( *a > *b ) - return 1; - else - return 0; - } - - - FT_LOCAL_DEF( void ) - gxv_set_length_by_ushort_offset( FT_UShort* offset, - FT_UShort** length, - FT_UShort* buff, - FT_UInt nmemb, - FT_UShort limit, - GXV_Validator valid ) - { - FT_UInt i; - - - for ( i = 0; i < nmemb; i++ ) - *(length[i]) = 0; - - for ( i = 0; i < nmemb; i++ ) - buff[i] = offset[i]; - buff[nmemb] = limit; - - ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_UShort ), - ( int(*)(const void*, const void*) )gxv_compare_ushort_offset ); - - if ( buff[nmemb] > limit ) - FT_INVALID_OFFSET; - - for ( i = 0; i < nmemb; i++ ) - { - FT_UInt j; - - - for ( j = 0; j < nmemb; j++ ) - if ( buff[j] == offset[i] ) - break; - - if ( j == nmemb ) - FT_INVALID_OFFSET; - - *(length[i]) = (FT_UShort)( buff[j + 1] - buff[j] ); - - if ( 0 != offset[i] && 0 == *(length[i]) ) - FT_INVALID_OFFSET; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** 32bit offset sorter *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static int - gxv_compare_ulong_offset( FT_ULong* a, - FT_ULong* b ) - { - if ( *a < *b ) - return -1; - else if ( *a > *b ) - return 1; - else - return 0; - } - - - FT_LOCAL_DEF( void ) - gxv_set_length_by_ulong_offset( FT_ULong* offset, - FT_ULong** length, - FT_ULong* buff, - FT_UInt nmemb, - FT_ULong limit, - GXV_Validator valid) - { - FT_UInt i; - - - for ( i = 0; i < nmemb; i++ ) - *(length[i]) = 0; - - for ( i = 0; i < nmemb; i++ ) - buff[i] = offset[i]; - buff[nmemb] = limit; - - ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_ULong ), - ( int(*)(const void*, const void*) )gxv_compare_ulong_offset ); - - if ( buff[nmemb] > limit ) - FT_INVALID_OFFSET; - - for ( i = 0; i < nmemb; i++ ) - { - FT_UInt j; - - - for ( j = 0; j < nmemb; j++ ) - if ( buff[j] == offset[i] ) - break; - - if ( j == nmemb ) - FT_INVALID_OFFSET; - - *(length[i]) = buff[j + 1] - buff[j]; - - if ( 0 != offset[i] && 0 == *(length[i]) ) - FT_INVALID_OFFSET; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** scan value array and get min & max *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL_DEF( void ) - gxv_array_getlimits_byte( FT_Bytes table, - FT_Bytes limit, - FT_Byte* min, - FT_Byte* max, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - *min = 0xFF; - *max = 0x00; - - while ( p < limit ) - { - FT_Byte val; - - - GXV_LIMIT_CHECK( 1 ); - val = FT_NEXT_BYTE( p ); - - *min = (FT_Byte)FT_MIN( *min, val ); - *max = (FT_Byte)FT_MAX( *max, val ); - } - - valid->subtable_length = p - table; - } - - - FT_LOCAL_DEF( void ) - gxv_array_getlimits_ushort( FT_Bytes table, - FT_Bytes limit, - FT_UShort* min, - FT_UShort* max, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - *min = 0xFFFFU; - *max = 0x0000; - - while ( p < limit ) - { - FT_UShort val; - - - GXV_LIMIT_CHECK( 2 ); - val = FT_NEXT_USHORT( p ); - - *min = (FT_Byte)FT_MIN( *min, val ); - *max = (FT_Byte)FT_MAX( *max, val ); - } - - valid->subtable_length = p - table; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** BINSEARCHHEADER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct GXV_BinSrchHeader_ - { - FT_UShort unitSize; - FT_UShort nUnits; - FT_UShort searchRange; - FT_UShort entrySelector; - FT_UShort rangeShift; - - } GXV_BinSrchHeader; - - - static void - gxv_BinSrchHeader_check_consistency( GXV_BinSrchHeader* binSrchHeader, - GXV_Validator valid ) - { - FT_UShort searchRange; - FT_UShort entrySelector; - FT_UShort rangeShift; - - - if ( binSrchHeader->unitSize == 0 ) - FT_INVALID_DATA; - - if ( binSrchHeader->nUnits == 0 ) - { - if ( binSrchHeader->searchRange == 0 && - binSrchHeader->entrySelector == 0 && - binSrchHeader->rangeShift == 0 ) - return; - else - FT_INVALID_DATA; - } - - for ( searchRange = 1, entrySelector = 1; - ( searchRange * 2 ) <= binSrchHeader->nUnits && - searchRange < 0x8000U; - searchRange *= 2, entrySelector++ ) - ; - - entrySelector--; - searchRange = (FT_UShort)( searchRange * binSrchHeader->unitSize ); - rangeShift = (FT_UShort)( binSrchHeader->nUnits * binSrchHeader->unitSize - - searchRange ); - - if ( searchRange != binSrchHeader->searchRange || - entrySelector != binSrchHeader->entrySelector || - rangeShift != binSrchHeader->rangeShift ) - { - GXV_TRACE(( "Inconsistency found in BinSrchHeader\n" )); - GXV_TRACE(( "originally: unitSize=%d, nUnits=%d, " - "searchRange=%d, entrySelector=%d, " - "rangeShift=%d\n", - binSrchHeader->unitSize, binSrchHeader->nUnits, - binSrchHeader->searchRange, binSrchHeader->entrySelector, - binSrchHeader->rangeShift )); - GXV_TRACE(( "calculated: unitSize=%d, nUnits=%d, " - "searchRange=%d, entrySelector=%d, " - "rangeShift=%d\n", - binSrchHeader->unitSize, binSrchHeader->nUnits, - searchRange, entrySelector, rangeShift )); - - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - } - - - /* - * parser & validator of BinSrchHeader - * which is used in LookupTable format 2, 4, 6. - * - * Essential parameters (unitSize, nUnits) are returned by - * given pointer, others (searchRange, entrySelector, rangeShift) - * can be calculated by essential parameters, so they are just - * validated and discarded. - * - * However, wrong values in searchRange, entrySelector, rangeShift - * won't cause fatal errors, because these parameters might be - * only used in old m68k font driver in MacOS. - * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp> - */ - - FT_LOCAL_DEF( void ) - gxv_BinSrchHeader_validate( FT_Bytes table, - FT_Bytes limit, - FT_UShort* unitSize_p, - FT_UShort* nUnits_p, - GXV_Validator valid ) - { - FT_Bytes p = table; - GXV_BinSrchHeader binSrchHeader; - - - GXV_NAME_ENTER( "BinSrchHeader validate" ); - - if ( *unitSize_p == 0 ) - { - GXV_LIMIT_CHECK( 2 ); - binSrchHeader.unitSize = FT_NEXT_USHORT( p ); - } - else - binSrchHeader.unitSize = *unitSize_p; - - if ( *nUnits_p == 0 ) - { - GXV_LIMIT_CHECK( 2 ); - binSrchHeader.nUnits = FT_NEXT_USHORT( p ); - } - else - binSrchHeader.nUnits = *nUnits_p; - - GXV_LIMIT_CHECK( 2 + 2 + 2 ); - binSrchHeader.searchRange = FT_NEXT_USHORT( p ); - binSrchHeader.entrySelector = FT_NEXT_USHORT( p ); - binSrchHeader.rangeShift = FT_NEXT_USHORT( p ); - GXV_TRACE(( "nUnits %d\n", binSrchHeader.nUnits )); - - gxv_BinSrchHeader_check_consistency( &binSrchHeader, valid ); - - if ( *unitSize_p == 0 ) - *unitSize_p = binSrchHeader.unitSize; - - if ( *nUnits_p == 0 ) - *nUnits_p = binSrchHeader.nUnits; - - valid->subtable_length = p - table; - GXV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** LOOKUP TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define GXV_LOOKUP_VALUE_LOAD( P, SIGNSPEC ) \ - ( P += 2, gxv_lookup_value_load( P - 2, SIGNSPEC ) ) - - static GXV_LookupValueDesc - gxv_lookup_value_load( FT_Bytes p, - int signspec ) - { - GXV_LookupValueDesc v; - - - if ( signspec == GXV_LOOKUPVALUE_UNSIGNED ) - v.u = FT_NEXT_USHORT( p ); - else - v.s = FT_NEXT_SHORT( p ); - - return v; - } - - -#define GXV_UNITSIZE_VALIDATE( FORMAT, UNITSIZE, NUNITS, CORRECTSIZE ) \ - FT_BEGIN_STMNT \ - if ( UNITSIZE != CORRECTSIZE ) \ - { \ - FT_ERROR(( "unitSize=%d differs from" \ - " expected unitSize=%d" \ - " in LookupTable %s\n", \ - UNITSIZE, CORRECTSIZE, FORMAT )); \ - if ( UNITSIZE != 0 && NUNITS != 0 ) \ - { \ - FT_ERROR(( " cannot validate anymore\n" )); \ - FT_INVALID_FORMAT; \ - } \ - else \ - FT_ERROR(( " forcibly continues\n" )); \ - } \ - FT_END_STMNT - - - /* ================= Simple Array Format 0 Lookup Table ================ */ - static void - gxv_LookupTable_fmt0_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort i; - - GXV_LookupValueDesc value; - - - GXV_NAME_ENTER( "LookupTable format 0" ); - - GXV_LIMIT_CHECK( 2 * valid->face->num_glyphs ); - - for ( i = 0; i < valid->face->num_glyphs; i++ ) - { - GXV_LIMIT_CHECK( 2 ); - if ( p + 2 >= limit ) /* some fonts have too-short fmt0 array */ - { - GXV_TRACE(( "too short, glyphs %d - %d are missing\n", - i, valid->face->num_glyphs )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - break; - } - - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( i, &value, valid ); - } - - valid->subtable_length = p - table; - GXV_EXIT; - } - - - /* ================= Segment Single Format 2 Loolup Table ============== */ - /* - * Apple spec says: - * - * To guarantee that a binary search terminates, you must include one or - * more special `end of search table' values at the end of the data to - * be searched. The number of termination values that need to be - * included is table-specific. The value that indicates binary search - * termination is 0xFFFF. - * - * The problem is that nUnits does not include this end-marker. It's - * quite difficult to discriminate whether the following 0xFFFF comes from - * the end-marker or some next data. - * - * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp> - */ - static void - gxv_LookupTable_fmt2_skip_endmarkers( FT_Bytes table, - FT_UShort unitSize, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - while ( ( p + 4 ) < valid->root->limit ) - { - if ( p[0] != 0xFF || p[1] != 0xFF || /* lastGlyph */ - p[2] != 0xFF || p[3] != 0xFF ) /* firstGlyph */ - break; - p += unitSize; - } - - valid->subtable_length = p - table; - } - - - static void - gxv_LookupTable_fmt2_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort gid; - - FT_UShort unitSize; - FT_UShort nUnits; - FT_UShort unit; - FT_UShort lastGlyph; - FT_UShort firstGlyph; - GXV_LookupValueDesc value; - - - GXV_NAME_ENTER( "LookupTable format 2" ); - - unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; - - GXV_UNITSIZE_VALIDATE( "format2", unitSize, nUnits, 6 ); - - for ( unit = 0, gid = 0; unit < nUnits; unit++ ) - { - GXV_LIMIT_CHECK( 2 + 2 + 2 ); - lastGlyph = FT_NEXT_USHORT( p ); - firstGlyph = FT_NEXT_USHORT( p ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( lastGlyph, valid ); - - if ( lastGlyph < gid ) - { - GXV_TRACE(( "reverse ordered segment specification:" - " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n", - unit, lastGlyph, unit - 1 , gid )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - - if ( lastGlyph < firstGlyph ) - { - GXV_TRACE(( "reverse ordered range specification at unit %d:", - " lastGlyph %d < firstGlyph %d ", - unit, lastGlyph, firstGlyph )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - - if ( valid->root->level == FT_VALIDATE_TIGHT ) - continue; /* ftxvalidator silently skips such an entry */ - - FT_TRACE4(( "continuing with exchanged values\n" )); - gid = firstGlyph; - firstGlyph = lastGlyph; - lastGlyph = gid; - } - - for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) - valid->lookupval_func( gid, &value, valid ); - } - - gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; - - valid->subtable_length = p - table; - GXV_EXIT; - } - - - /* ================= Segment Array Format 4 Lookup Table =============== */ - static void - gxv_LookupTable_fmt4_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort unit; - FT_UShort gid; - - FT_UShort unitSize; - FT_UShort nUnits; - FT_UShort lastGlyph; - FT_UShort firstGlyph; - GXV_LookupValueDesc base_value; - GXV_LookupValueDesc value; - - - GXV_NAME_ENTER( "LookupTable format 4" ); - - unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; - - GXV_UNITSIZE_VALIDATE( "format4", unitSize, nUnits, 6 ); - - for ( unit = 0, gid = 0; unit < nUnits; unit++ ) - { - GXV_LIMIT_CHECK( 2 + 2 ); - lastGlyph = FT_NEXT_USHORT( p ); - firstGlyph = FT_NEXT_USHORT( p ); - - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( lastGlyph, valid ); - - if ( lastGlyph < gid ) - { - GXV_TRACE(( "reverse ordered segment specification:" - " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n", - unit, lastGlyph, unit - 1 , gid )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - - if ( lastGlyph < firstGlyph ) - { - GXV_TRACE(( "reverse ordered range specification at unit %d:", - " lastGlyph %d < firstGlyph %d ", - unit, lastGlyph, firstGlyph )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - - if ( valid->root->level == FT_VALIDATE_TIGHT ) - continue; /* ftxvalidator silently skips such an entry */ - - FT_TRACE4(( "continuing with exchanged values\n" )); - gid = firstGlyph; - firstGlyph = lastGlyph; - lastGlyph = gid; - } - - GXV_LIMIT_CHECK( 2 ); - base_value = GXV_LOOKUP_VALUE_LOAD( p, GXV_LOOKUPVALUE_UNSIGNED ); - - for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) - { - value = valid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), - &base_value, - limit, - valid ); - - valid->lookupval_func( gid, &value, valid ); - } - } - - gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; - - valid->subtable_length = p - table; - GXV_EXIT; - } - - - /* ================= Segment Table Format 6 Lookup Table =============== */ - static void - gxv_LookupTable_fmt6_skip_endmarkers( FT_Bytes table, - FT_UShort unitSize, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - while ( p < valid->root->limit ) - { - if ( p[0] != 0xFF || p[1] != 0xFF ) - break; - p += unitSize; - } - - valid->subtable_length = p - table; - } - - - static void - gxv_LookupTable_fmt6_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort unit; - FT_UShort prev_glyph; - - FT_UShort unitSize; - FT_UShort nUnits; - FT_UShort glyph; - GXV_LookupValueDesc value; - - - GXV_NAME_ENTER( "LookupTable format 6" ); - - unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; - - GXV_UNITSIZE_VALIDATE( "format6", unitSize, nUnits, 4 ); - - for ( unit = 0, prev_glyph = 0; unit < nUnits; unit++ ) - { - GXV_LIMIT_CHECK( 2 + 2 ); - glyph = FT_NEXT_USHORT( p ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - - if ( gxv_glyphid_validate( glyph, valid ) ) - GXV_TRACE(( " endmarker found within defined range" - " (entry %d < nUnits=%d)\n", - unit, nUnits )); - - if ( prev_glyph > glyph ) - { - GXV_TRACE(( "current gid 0x%04x < previous gid 0x%04x\n", - glyph, prev_glyph )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - prev_glyph = glyph; - - valid->lookupval_func( glyph, &value, valid ); - } - - gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; - - valid->subtable_length = p - table; - GXV_EXIT; - } - - - /* ================= Trimmed Array Format 8 Lookup Table =============== */ - static void - gxv_LookupTable_fmt8_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort i; - - GXV_LookupValueDesc value; - FT_UShort firstGlyph; - FT_UShort glyphCount; - - - GXV_NAME_ENTER( "LookupTable format 8" ); - - /* firstGlyph + glyphCount */ - GXV_LIMIT_CHECK( 2 + 2 ); - firstGlyph = FT_NEXT_USHORT( p ); - glyphCount = FT_NEXT_USHORT( p ); - - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), valid ); - - /* valueArray */ - for ( i = 0; i < glyphCount; i++ ) - { - GXV_LIMIT_CHECK( 2 ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, valid ); - } - - valid->subtable_length = p - table; - GXV_EXIT; - } - - - FT_LOCAL_DEF( void ) - gxv_LookupTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort format; - - GXV_Validate_Func fmt_funcs_table[] = - { - gxv_LookupTable_fmt0_validate, /* 0 */ - NULL, /* 1 */ - gxv_LookupTable_fmt2_validate, /* 2 */ - NULL, /* 3 */ - gxv_LookupTable_fmt4_validate, /* 4 */ - NULL, /* 5 */ - gxv_LookupTable_fmt6_validate, /* 6 */ - NULL, /* 7 */ - gxv_LookupTable_fmt8_validate, /* 8 */ - }; - - GXV_Validate_Func func; - - - GXV_NAME_ENTER( "LookupTable" ); - - /* lookuptbl_head may be used in fmt4 transit function. */ - valid->lookuptbl_head = table; - - /* format */ - GXV_LIMIT_CHECK( 2 ); - format = FT_NEXT_USHORT( p ); - GXV_TRACE(( " (format %d)\n", format )); - - if ( format > 8 ) - FT_INVALID_FORMAT; - - func = fmt_funcs_table[format]; - if ( func == NULL ) - FT_INVALID_FORMAT; - - func( p, limit, valid ); - p += valid->subtable_length; - - valid->subtable_length = p - table; - - GXV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Glyph ID *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( FT_Int ) - gxv_glyphid_validate( FT_UShort gid, - GXV_Validator valid ) - { - FT_Face face; - - - if ( gid == 0xFFFFU ) - { - GXV_EXIT; - return 1; - } - - face = valid->face; - if ( face->num_glyphs < gid ) - { - GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n", - face->num_glyphs, gid )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - - return 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CONTROL POINT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - gxv_ctlPoint_validate( FT_UShort gid, - FT_Short ctl_point, - GXV_Validator valid ) - { - FT_Face face; - FT_Error error; - - FT_GlyphSlot glyph; - FT_Outline outline; - short n_points; - - - face = valid->face; - - error = FT_Load_Glyph( face, - gid, - FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM ); - if ( error ) - FT_INVALID_GLYPH_ID; - - glyph = face->glyph; - outline = glyph->outline; - n_points = outline.n_points; - - - if ( !( ctl_point < n_points ) ) - FT_INVALID_DATA; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SFNT NAME *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - gxv_sfntName_validate( FT_UShort name_index, - FT_UShort min_index, - FT_UShort max_index, - GXV_Validator valid ) - { - FT_SfntName name; - FT_UInt i; - FT_UInt nnames; - - - GXV_NAME_ENTER( "sfntName" ); - - if ( name_index < min_index || max_index < name_index ) - FT_INVALID_FORMAT; - - nnames = FT_Get_Sfnt_Name_Count( valid->face ); - for ( i = 0; i < nnames; i++ ) - { - if ( FT_Get_Sfnt_Name( valid->face, i, &name ) != FT_Err_Ok ) - continue ; - - if ( name.name_id == name_index ) - goto Out; - } - - GXV_TRACE(( " nameIndex = %d (UNTITLED)\n", name_index )); - FT_INVALID_DATA; - goto Exit; /* make compiler happy */ - - Out: - FT_TRACE1(( " nameIndex = %d (", name_index )); - GXV_TRACE_HEXDUMP_SFNTNAME( name ); - FT_TRACE1(( ")\n" )); - - Exit: - GXV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** STATE TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* -------------------------- Class Table --------------------------- */ - - /* - * highestClass specifies how many classes are defined in this - * Class Subtable. Apple spec does not mention whether undefined - * holes in the class (e.g.: 0-3 are predefined, 4 is unused, 5 is used) - * are permitted. At present, holes in a defined class are not checked. - * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp> - */ - - static void - gxv_ClassTable_validate( FT_Bytes table, - FT_UShort* length_p, - FT_UShort stateSize, - FT_Byte* maxClassID_p, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_Bytes limit = table + *length_p; - FT_UShort firstGlyph; - FT_UShort nGlyphs; - - - GXV_NAME_ENTER( "ClassTable" ); - - *maxClassID_p = 3; /* Classes 0, 2, and 3 are predefined */ - - GXV_LIMIT_CHECK( 2 + 2 ); - firstGlyph = FT_NEXT_USHORT( p ); - nGlyphs = FT_NEXT_USHORT( p ); - - GXV_TRACE(( " (firstGlyph = %d, nGlyphs = %d)\n", firstGlyph, nGlyphs )); - - if ( !nGlyphs ) - goto Out; - - gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs ), valid ); - - { - FT_Byte nGlyphInClass[256]; - FT_Byte classID; - FT_UShort i; - - - ft_memset( nGlyphInClass, 0, 256 ); - - - for ( i = 0; i < nGlyphs; i++ ) - { - GXV_LIMIT_CHECK( 1 ); - classID = FT_NEXT_BYTE( p ); - switch ( classID ) - { - /* following classes should not appear in class array */ - case 0: /* end of text */ - case 2: /* out of bounds */ - case 3: /* end of line */ - FT_INVALID_DATA; - break; - - case 1: /* out of bounds */ - default: /* user-defined: 4 - ( stateSize - 1 ) */ - if ( classID >= stateSize ) - FT_INVALID_DATA; /* assign glyph to undefined state */ - - nGlyphInClass[classID]++; - break; - } - } - *length_p = (FT_UShort)( p - table ); - - /* scan max ClassID in use */ - for ( i = 0; i < stateSize; i++ ) - if ( ( 3 < i ) && ( nGlyphInClass[i] > 0 ) ) - *maxClassID_p = (FT_Byte)i; /* XXX: Check Range? */ - } - - Out: - GXV_TRACE(( "Declared stateSize=0x%02x, Used maxClassID=0x%02x\n", - stateSize, *maxClassID_p )); - GXV_EXIT; - } - - - /* --------------------------- State Array ----------------------------- */ - - static void - gxv_StateArray_validate( FT_Bytes table, - FT_UShort* length_p, - FT_Byte maxClassID, - FT_UShort stateSize, - FT_Byte* maxState_p, - FT_Byte* maxEntry_p, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_Bytes limit = table + *length_p; - FT_Byte clazz; - FT_Byte entry; - - FT_UNUSED( stateSize ); /* for the non-debugging case */ - - - GXV_NAME_ENTER( "StateArray" ); - - GXV_TRACE(( "parse %d bytes by stateSize=%d maxClassID=%d\n", - (int)(*length_p), stateSize, (int)(maxClassID) )); - - /* - * 2 states are predefined and must be described in StateArray: - * state 0 (start of text), 1 (start of line) - */ - GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 ); - - *maxState_p = 0; - *maxEntry_p = 0; - - /* read if enough to read another state */ - while ( p + ( 1 + maxClassID ) <= limit ) - { - (*maxState_p)++; - for ( clazz = 0; clazz <= maxClassID; clazz++ ) - { - entry = FT_NEXT_BYTE( p ); - *maxEntry_p = (FT_Byte)FT_MAX( *maxEntry_p, entry ); - } - } - GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n", - *maxState_p, *maxEntry_p )); - - *length_p = (FT_UShort)( p - table ); - - GXV_EXIT; - } - - - /* --------------------------- Entry Table ----------------------------- */ - - static void - gxv_EntryTable_validate( FT_Bytes table, - FT_UShort* length_p, - FT_Byte maxEntry, - FT_UShort stateArray, - FT_UShort stateArray_length, - FT_Byte maxClassID, - FT_Bytes statetable_table, - FT_Bytes statetable_limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_Bytes limit = table + *length_p; - FT_Byte entry; - FT_Byte state; - FT_Int entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( statetable ); - - GXV_XStateTable_GlyphOffsetDesc glyphOffset; - - - GXV_NAME_ENTER( "EntryTable" ); - - GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize )); - - if ( ( maxEntry + 1 ) * entrySize > *length_p ) - { - GXV_SET_ERR_IF_PARANOID( FT_INVALID_TOO_SHORT ); - - /* ftxvalidator and FontValidator both warn and continue */ - maxEntry = (FT_Byte)( *length_p / entrySize - 1 ); - GXV_TRACE(( "too large maxEntry, shrinking to %d fit EntryTable length\n", - maxEntry )); - } - - for ( entry = 0; entry <= maxEntry; entry++ ) - { - FT_UShort newState; - FT_UShort flags; - - - GXV_LIMIT_CHECK( 2 + 2 ); - newState = FT_NEXT_USHORT( p ); - flags = FT_NEXT_USHORT( p ); - - - if ( newState < stateArray || - stateArray + stateArray_length < newState ) - { - GXV_TRACE(( " newState offset 0x%04x is out of stateArray\n", - newState )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - continue; - } - - if ( 0 != ( ( newState - stateArray ) % ( 1 + maxClassID ) ) ) - { - GXV_TRACE(( " newState offset 0x%04x is not aligned to %d-classes\n", - newState, 1 + maxClassID )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - continue; - } - - state = (FT_Byte)( ( newState - stateArray ) / ( 1 + maxClassID ) ); - - switch ( GXV_GLYPHOFFSET_FMT( statetable ) ) - { - case GXV_GLYPHOFFSET_NONE: - glyphOffset.uc = 0; /* make compiler happy */ - break; - - case GXV_GLYPHOFFSET_UCHAR: - glyphOffset.uc = FT_NEXT_BYTE( p ); - break; - - case GXV_GLYPHOFFSET_CHAR: - glyphOffset.c = FT_NEXT_CHAR( p ); - break; - - case GXV_GLYPHOFFSET_USHORT: - glyphOffset.u = FT_NEXT_USHORT( p ); - break; - - case GXV_GLYPHOFFSET_SHORT: - glyphOffset.s = FT_NEXT_SHORT( p ); - break; - - case GXV_GLYPHOFFSET_ULONG: - glyphOffset.ul = FT_NEXT_ULONG( p ); - break; - - case GXV_GLYPHOFFSET_LONG: - glyphOffset.l = FT_NEXT_LONG( p ); - break; - - default: - GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); - goto Exit; - } - - if ( NULL != valid->statetable.entry_validate_func ) - valid->statetable.entry_validate_func( state, - flags, - &glyphOffset, - statetable_table, - statetable_limit, - valid ); - } - - Exit: - *length_p = (FT_UShort)( p - table ); - - GXV_EXIT; - } - - - /* =========================== State Table ============================= */ - - FT_LOCAL_DEF( void ) - gxv_StateTable_subtable_setup( FT_UShort table_size, - FT_UShort classTable, - FT_UShort stateArray, - FT_UShort entryTable, - FT_UShort* classTable_length_p, - FT_UShort* stateArray_length_p, - FT_UShort* entryTable_length_p, - GXV_Validator valid ) - { - FT_UShort o[3]; - FT_UShort* l[3]; - FT_UShort buff[4]; - - - o[0] = classTable; - o[1] = stateArray; - o[2] = entryTable; - l[0] = classTable_length_p; - l[1] = stateArray_length_p; - l[2] = entryTable_length_p; - - gxv_set_length_by_ushort_offset( o, l, buff, 3, table_size, valid ); - } - - - FT_LOCAL_DEF( void ) - gxv_StateTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_UShort stateSize; - FT_UShort classTable; /* offset to Class(Sub)Table */ - FT_UShort stateArray; /* offset to StateArray */ - FT_UShort entryTable; /* offset to EntryTable */ - - FT_UShort classTable_length; - FT_UShort stateArray_length; - FT_UShort entryTable_length; - FT_Byte maxClassID; - FT_Byte maxState; - FT_Byte maxEntry; - - GXV_StateTable_Subtable_Setup_Func setup_func; - - FT_Bytes p = table; - - - GXV_NAME_ENTER( "StateTable" ); - - GXV_TRACE(( "StateTable header\n" )); - - GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); - stateSize = FT_NEXT_USHORT( p ); - classTable = FT_NEXT_USHORT( p ); - stateArray = FT_NEXT_USHORT( p ); - entryTable = FT_NEXT_USHORT( p ); - - GXV_TRACE(( "stateSize=0x%04x\n", stateSize )); - GXV_TRACE(( "offset to classTable=0x%04x\n", classTable )); - GXV_TRACE(( "offset to stateArray=0x%04x\n", stateArray )); - GXV_TRACE(( "offset to entryTable=0x%04x\n", entryTable )); - - if ( stateSize > 0xFF ) - FT_INVALID_DATA; - - if ( valid->statetable.optdata_load_func != NULL ) - valid->statetable.optdata_load_func( p, limit, valid ); - - if ( valid->statetable.subtable_setup_func != NULL) - setup_func = valid->statetable.subtable_setup_func; - else - setup_func = gxv_StateTable_subtable_setup; - - setup_func( (FT_UShort)( limit - table ), - classTable, - stateArray, - entryTable, - &classTable_length, - &stateArray_length, - &entryTable_length, - valid ); - - GXV_TRACE(( "StateTable Subtables\n" )); - - if ( classTable != 0 ) - gxv_ClassTable_validate( table + classTable, - &classTable_length, - stateSize, - &maxClassID, - valid ); - else - maxClassID = (FT_Byte)( stateSize - 1 ); - - if ( stateArray != 0 ) - gxv_StateArray_validate( table + stateArray, - &stateArray_length, - maxClassID, - stateSize, - &maxState, - &maxEntry, - valid ); - else - { - maxState = 1; /* 0:start of text, 1:start of line are predefined */ - maxEntry = 0; - } - - if ( maxEntry > 0 && entryTable == 0 ) - FT_INVALID_OFFSET; - - if ( entryTable != 0 ) - gxv_EntryTable_validate( table + entryTable, - &entryTable_length, - maxEntry, - stateArray, - stateArray_length, - maxClassID, - table, - limit, - valid ); - - GXV_EXIT; - } - - - /* ================= eXtended State Table (for morx) =================== */ - - FT_LOCAL_DEF( void ) - gxv_XStateTable_subtable_setup( FT_ULong table_size, - FT_ULong classTable, - FT_ULong stateArray, - FT_ULong entryTable, - FT_ULong* classTable_length_p, - FT_ULong* stateArray_length_p, - FT_ULong* entryTable_length_p, - GXV_Validator valid ) - { - FT_ULong o[3]; - FT_ULong* l[3]; - FT_ULong buff[4]; - - - o[0] = classTable; - o[1] = stateArray; - o[2] = entryTable; - l[0] = classTable_length_p; - l[1] = stateArray_length_p; - l[2] = entryTable_length_p; - - gxv_set_length_by_ulong_offset( o, l, buff, 3, table_size, valid ); - } - - - static void - gxv_XClassTable_lookupval_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - FT_UNUSED( glyph ); - - if ( value_p->u >= valid->xstatetable.nClasses ) - FT_INVALID_DATA; - if ( value_p->u > valid->xstatetable.maxClassID ) - valid->xstatetable.maxClassID = value_p->u; - } - - - /* - +===============+ --------+ - | lookup header | | - +===============+ | - | BinSrchHeader | | - +===============+ | - | lastGlyph[0] | | - +---------------+ | - | firstGlyph[0] | | head of lookup table - +---------------+ | + - | offset[0] | -> | offset [byte] - +===============+ | + - | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] - +---------------+ | - | firstGlyph[1] | | - +---------------+ | - | offset[1] | | - +===============+ | - | - .... | - | - 16bit value array | - +===============+ | - | value | <-------+ - .... - */ - static GXV_LookupValueDesc - gxv_XClassTable_lookupfmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueCPtr base_value_p, - FT_Bytes lookuptbl_limit, - GXV_Validator valid ) - { - FT_Bytes p; - FT_Bytes limit; - FT_UShort offset; - GXV_LookupValueDesc value; - - /* XXX: check range? */ - offset = (FT_UShort)( base_value_p->u + - relative_gindex * sizeof ( FT_UShort ) ); - - p = valid->lookuptbl_head + offset; - limit = lookuptbl_limit; - - GXV_LIMIT_CHECK ( 2 ); - value.u = FT_NEXT_USHORT( p ); - - return value; - } - - - static void - gxv_XStateArray_validate( FT_Bytes table, - FT_ULong* length_p, - FT_UShort maxClassID, - FT_ULong stateSize, - FT_UShort* maxState_p, - FT_UShort* maxEntry_p, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_Bytes limit = table + *length_p; - FT_UShort clazz; - FT_UShort entry; - - FT_UNUSED( stateSize ); /* for the non-debugging case */ - - - GXV_NAME_ENTER( "XStateArray" ); - - GXV_TRACE(( "parse % 3d bytes by stateSize=% 3d maxClassID=% 3d\n", - (int)(*length_p), stateSize, (int)(maxClassID) )); - - /* - * 2 states are predefined and must be described: - * state 0 (start of text), 1 (start of line) - */ - GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 * 2 ); - - *maxState_p = 0; - *maxEntry_p = 0; - - /* read if enough to read another state */ - while ( p + ( ( 1 + maxClassID ) * 2 ) <= limit ) - { - (*maxState_p)++; - for ( clazz = 0; clazz <= maxClassID; clazz++ ) - { - entry = FT_NEXT_USHORT( p ); - *maxEntry_p = (FT_UShort)FT_MAX( *maxEntry_p, entry ); - } - } - GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n", - *maxState_p, *maxEntry_p )); - - *length_p = p - table; - - GXV_EXIT; - } - - - static void - gxv_XEntryTable_validate( FT_Bytes table, - FT_ULong* length_p, - FT_UShort maxEntry, - FT_ULong stateArray_length, - FT_UShort maxClassID, - FT_Bytes xstatetable_table, - FT_Bytes xstatetable_limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_Bytes limit = table + *length_p; - FT_UShort entry; - FT_UShort state; - FT_Int entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( xstatetable ); - - - GXV_NAME_ENTER( "XEntryTable" ); - GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize )); - - if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit ) - FT_INVALID_TOO_SHORT; - - for (entry = 0; entry <= maxEntry ; entry++ ) - { - FT_UShort newState_idx; - FT_UShort flags; - GXV_XStateTable_GlyphOffsetDesc glyphOffset; - - - GXV_LIMIT_CHECK( 2 + 2 ); - newState_idx = FT_NEXT_USHORT( p ); - flags = FT_NEXT_USHORT( p ); - - if ( stateArray_length < (FT_ULong)( newState_idx * 2 ) ) - { - GXV_TRACE(( " newState index 0x%04x points out of stateArray\n", - newState_idx )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } - - state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) ); - if ( 0 != ( newState_idx % ( 1 + maxClassID ) ) ) - { - FT_TRACE4(( "-> new state = %d (supposed)\n" - "but newState index 0x%04x is not aligned to %d-classes\n", - state, newState_idx, 1 + maxClassID )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } - - switch ( GXV_GLYPHOFFSET_FMT( xstatetable ) ) - { - case GXV_GLYPHOFFSET_NONE: - glyphOffset.uc = 0; /* make compiler happy */ - break; - - case GXV_GLYPHOFFSET_UCHAR: - glyphOffset.uc = FT_NEXT_BYTE( p ); - break; - - case GXV_GLYPHOFFSET_CHAR: - glyphOffset.c = FT_NEXT_CHAR( p ); - break; - - case GXV_GLYPHOFFSET_USHORT: - glyphOffset.u = FT_NEXT_USHORT( p ); - break; - - case GXV_GLYPHOFFSET_SHORT: - glyphOffset.s = FT_NEXT_SHORT( p ); - break; - - case GXV_GLYPHOFFSET_ULONG: - glyphOffset.ul = FT_NEXT_ULONG( p ); - break; - - case GXV_GLYPHOFFSET_LONG: - glyphOffset.l = FT_NEXT_LONG( p ); - break; - - default: - GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); - goto Exit; - } - - if ( NULL != valid->xstatetable.entry_validate_func ) - valid->xstatetable.entry_validate_func( state, - flags, - &glyphOffset, - xstatetable_table, - xstatetable_limit, - valid ); - } - - Exit: - *length_p = p - table; - - GXV_EXIT; - } - - - FT_LOCAL_DEF( void ) - gxv_XStateTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - /* StateHeader members */ - FT_ULong classTable; /* offset to Class(Sub)Table */ - FT_ULong stateArray; /* offset to StateArray */ - FT_ULong entryTable; /* offset to EntryTable */ - - FT_ULong classTable_length; - FT_ULong stateArray_length; - FT_ULong entryTable_length; - FT_UShort maxState; - FT_UShort maxEntry; - - GXV_XStateTable_Subtable_Setup_Func setup_func; - - FT_Bytes p = table; - - - GXV_NAME_ENTER( "XStateTable" ); - - GXV_TRACE(( "XStateTable header\n" )); - - GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); - valid->xstatetable.nClasses = FT_NEXT_ULONG( p ); - classTable = FT_NEXT_ULONG( p ); - stateArray = FT_NEXT_ULONG( p ); - entryTable = FT_NEXT_ULONG( p ); - - GXV_TRACE(( "nClasses =0x%08x\n", valid->xstatetable.nClasses )); - GXV_TRACE(( "offset to classTable=0x%08x\n", classTable )); - GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray )); - GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable )); - - if ( valid->xstatetable.nClasses > 0xFFFFU ) - FT_INVALID_DATA; - - GXV_TRACE(( "StateTable Subtables\n" )); - - if ( valid->xstatetable.optdata_load_func != NULL ) - valid->xstatetable.optdata_load_func( p, limit, valid ); - - if ( valid->xstatetable.subtable_setup_func != NULL ) - setup_func = valid->xstatetable.subtable_setup_func; - else - setup_func = gxv_XStateTable_subtable_setup; - - setup_func( limit - table, - classTable, - stateArray, - entryTable, - &classTable_length, - &stateArray_length, - &entryTable_length, - valid ); - - if ( classTable != 0 ) - { - valid->xstatetable.maxClassID = 0; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_XClassTable_lookupval_validate; - valid->lookupfmt4_trans = gxv_XClassTable_lookupfmt4_transit; - gxv_LookupTable_validate( table + classTable, - table + classTable + classTable_length, - valid ); - if ( valid->subtable_length < classTable_length ) - classTable_length = valid->subtable_length; - } - else - { - /* XXX: check range? */ - valid->xstatetable.maxClassID = - (FT_UShort)( valid->xstatetable.nClasses - 1 ); - } - - if ( stateArray != 0 ) - gxv_XStateArray_validate( table + stateArray, - &stateArray_length, - valid->xstatetable.maxClassID, - valid->xstatetable.nClasses, - &maxState, - &maxEntry, - valid ); - else - { - maxState = 1; /* 0:start of text, 1:start of line are predefined */ - maxEntry = 0; - } - - if ( maxEntry > 0 && entryTable == 0 ) - FT_INVALID_OFFSET; - - if ( entryTable != 0 ) - gxv_XEntryTable_validate( table + entryTable, - &entryTable_length, - maxEntry, - stateArray_length, - valid->xstatetable.maxClassID, - table, - limit, - valid ); - - GXV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Table overlapping *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static int - gxv_compare_ranges( FT_Bytes table1_start, - FT_ULong table1_length, - FT_Bytes table2_start, - FT_ULong table2_length ) - { - if ( table1_start == table2_start ) - { - if ( ( table1_length == 0 || table2_length == 0 ) ) - goto Out; - } - else if ( table1_start < table2_start ) - { - if ( ( table1_start + table1_length ) <= table2_start ) - goto Out; - } - else if ( table1_start > table2_start ) - { - if ( ( table1_start >= table2_start + table2_length ) ) - goto Out; - } - return 1; - - Out: - return 0; - } - - - FT_LOCAL_DEF( void ) - gxv_odtect_add_range( FT_Bytes start, - FT_ULong length, - const FT_String* name, - GXV_odtect_Range odtect ) - { - odtect->range[odtect->nRanges].start = start; - odtect->range[odtect->nRanges].length = length; - odtect->range[odtect->nRanges].name = (FT_String*)name; - odtect->nRanges++; - } - - - FT_LOCAL_DEF( void ) - gxv_odtect_validate( GXV_odtect_Range odtect, - GXV_Validator valid ) - { - FT_UInt i, j; - - - GXV_NAME_ENTER( "check overlap among multi ranges" ); - - for ( i = 0; i < odtect->nRanges; i++ ) - for ( j = 0; j < i; j++ ) - if ( 0 != gxv_compare_ranges( odtect->range[i].start, - odtect->range[i].length, - odtect->range[j].start, - odtect->range[j].length ) ) - { - if ( odtect->range[i].name || odtect->range[j].name ) - GXV_TRACE(( "found overlap between range %d and range %d\n", - i, j )); - else - GXV_TRACE(( "found overlap between `%s' and `%s\'\n", - odtect->range[i].name, - odtect->range[j].name )); - FT_INVALID_OFFSET; - } - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvcommn.h b/drivers/freetype/freetype/src/gxvalid/gxvcommn.h deleted file mode 100644 index 1ff87e4423..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvcommn.h +++ /dev/null @@ -1,582 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvcommn.h */ -/* */ -/* TrueTypeGX/AAT common tables validation (specification). */ -/* */ -/* Copyright 2004, 2005, 2012 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - - /* - * keywords in variable naming - * --------------------------- - * table: Of type FT_Bytes, pointing to the start of this table/subtable. - * limit: Of type FT_Bytes, pointing to the end of this table/subtable, - * including padding for alignment. - * offset: Of type FT_UInt, the number of octets from the start to target. - * length: Of type FT_UInt, the number of octets from the start to the - * end in this table/subtable, including padding for alignment. - * - * _MIN, _MAX: Should be added to the tail of macros, as INT_MIN, etc. - */ - - -#ifndef __GXVCOMMN_H__ -#define __GXVCOMMN_H__ - - -#include <ft2build.h> -#include "gxvalid.h" -#include FT_INTERNAL_DEBUG_H -#include FT_SFNT_NAMES_H - - -FT_BEGIN_HEADER - - - /* some variables are not evaluated or only used in trace */ - -#ifdef FT_DEBUG_LEVEL_TRACE -#define GXV_LOAD_TRACE_VARS -#else -#undef GXV_LOAD_TRACE_VARS -#endif - -#undef GXV_LOAD_UNUSED_VARS /* debug purpose */ - -#define IS_PARANOID_VALIDATION ( valid->root->level >= FT_VALIDATE_PARANOID ) -#define GXV_SET_ERR_IF_PARANOID( err ) { if ( IS_PARANOID_VALIDATION ) ( err ); } - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** VALIDATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct GXV_ValidatorRec_* GXV_Validator; - - -#define DUMMY_LIMIT 0 - - typedef void - (*GXV_Validate_Func)( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - - /* ====================== LookupTable Validator ======================== */ - - typedef union GXV_LookupValueDesc_ - { - FT_UShort u; - FT_Short s; - - } GXV_LookupValueDesc; - - typedef const GXV_LookupValueDesc* GXV_LookupValueCPtr; - - typedef enum GXV_LookupValue_SignSpec_ - { - GXV_LOOKUPVALUE_UNSIGNED = 0, - GXV_LOOKUPVALUE_SIGNED - - } GXV_LookupValue_SignSpec; - - - typedef void - (*GXV_Lookup_Value_Validate_Func)( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ); - - typedef GXV_LookupValueDesc - (*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort relative_gindex, - GXV_LookupValueCPtr base_value_p, - FT_Bytes lookuptbl_limit, - GXV_Validator valid ); - - - /* ====================== StateTable Validator ========================= */ - - typedef enum GXV_GlyphOffset_Format_ - { - GXV_GLYPHOFFSET_NONE = -1, - GXV_GLYPHOFFSET_UCHAR = 2, - GXV_GLYPHOFFSET_CHAR, - GXV_GLYPHOFFSET_USHORT = 4, - GXV_GLYPHOFFSET_SHORT, - GXV_GLYPHOFFSET_ULONG = 8, - GXV_GLYPHOFFSET_LONG - - } GXV_GlyphOffset_Format; - - -#define GXV_GLYPHOFFSET_FMT( table ) \ - ( valid->table.entry_glyphoffset_fmt ) - -#define GXV_GLYPHOFFSET_SIZE( table ) \ - ( valid->table.entry_glyphoffset_fmt / 2 ) - - - /* ----------------------- 16bit StateTable ---------------------------- */ - - typedef union GXV_StateTable_GlyphOffsetDesc_ - { - FT_Byte uc; - FT_UShort u; /* same as GXV_LookupValueDesc */ - FT_ULong ul; - FT_Char c; - FT_Short s; /* same as GXV_LookupValueDesc */ - FT_Long l; - - } GXV_StateTable_GlyphOffsetDesc; - - typedef const GXV_StateTable_GlyphOffsetDesc* GXV_StateTable_GlyphOffsetCPtr; - - typedef void - (*GXV_StateTable_Subtable_Setup_Func)( FT_UShort table_size, - FT_UShort classTable, - FT_UShort stateArray, - FT_UShort entryTable, - FT_UShort* classTable_length_p, - FT_UShort* stateArray_length_p, - FT_UShort* entryTable_length_p, - GXV_Validator valid ); - - typedef void - (*GXV_StateTable_Entry_Validate_Func)( - FT_Byte state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes statetable_table, - FT_Bytes statetable_limit, - GXV_Validator valid ); - - typedef void - (*GXV_StateTable_OptData_Load_Func)( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - typedef struct GXV_StateTable_ValidatorRec_ - { - GXV_GlyphOffset_Format entry_glyphoffset_fmt; - void* optdata; - - GXV_StateTable_Subtable_Setup_Func subtable_setup_func; - GXV_StateTable_Entry_Validate_Func entry_validate_func; - GXV_StateTable_OptData_Load_Func optdata_load_func; - - } GXV_StateTable_ValidatorRec, *GXV_StateTable_ValidatorRecData; - - - /* ---------------------- 32bit XStateTable ---------------------------- */ - - typedef GXV_StateTable_GlyphOffsetDesc GXV_XStateTable_GlyphOffsetDesc; - - typedef const GXV_XStateTable_GlyphOffsetDesc* GXV_XStateTable_GlyphOffsetCPtr; - - typedef void - (*GXV_XStateTable_Subtable_Setup_Func)( FT_ULong table_size, - FT_ULong classTable, - FT_ULong stateArray, - FT_ULong entryTable, - FT_ULong* classTable_length_p, - FT_ULong* stateArray_length_p, - FT_ULong* entryTable_length_p, - GXV_Validator valid ); - - typedef void - (*GXV_XStateTable_Entry_Validate_Func)( - FT_UShort state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes xstatetable_table, - FT_Bytes xstatetable_limit, - GXV_Validator valid ); - - - typedef GXV_StateTable_OptData_Load_Func GXV_XStateTable_OptData_Load_Func; - - - typedef struct GXV_XStateTable_ValidatorRec_ - { - int entry_glyphoffset_fmt; - void* optdata; - - GXV_XStateTable_Subtable_Setup_Func subtable_setup_func; - GXV_XStateTable_Entry_Validate_Func entry_validate_func; - GXV_XStateTable_OptData_Load_Func optdata_load_func; - - FT_ULong nClasses; - FT_UShort maxClassID; - - } GXV_XStateTable_ValidatorRec, *GXV_XStateTable_ValidatorRecData; - - - /* ===================================================================== */ - - typedef struct GXV_ValidatorRec_ - { - FT_Validator root; - - FT_Face face; - void* table_data; - - FT_ULong subtable_length; - - GXV_LookupValue_SignSpec lookupval_sign; - GXV_Lookup_Value_Validate_Func lookupval_func; - GXV_Lookup_Fmt4_Transit_Func lookupfmt4_trans; - FT_Bytes lookuptbl_head; - - FT_UShort min_gid; - FT_UShort max_gid; - - GXV_StateTable_ValidatorRec statetable; - GXV_XStateTable_ValidatorRec xstatetable; - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_UInt debug_indent; - const FT_String* debug_function_name[3]; -#endif - - } GXV_ValidatorRec; - - -#define GXV_TABLE_DATA( tag, field ) \ - ( ( (GXV_ ## tag ## _Data)valid->table_data )->field ) - -#undef FT_INVALID_ -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid->root, _prefix ## _error ) - -#define GXV_LIMIT_CHECK( _count ) \ - FT_BEGIN_STMNT \ - if ( p + _count > ( limit? limit : valid->root->limit ) ) \ - FT_INVALID_TOO_SHORT; \ - FT_END_STMNT - - -#ifdef FT_DEBUG_LEVEL_TRACE - -#define GXV_INIT valid->debug_indent = 0 - -#define GXV_NAME_ENTER( name ) \ - FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", name )); \ - FT_END_STMNT - -#define GXV_EXIT valid->debug_indent -= 2 - -#define GXV_TRACE( s ) \ - FT_BEGIN_STMNT \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4( s ); \ - FT_END_STMNT - -#else /* !FT_DEBUG_LEVEL_TRACE */ - -#define GXV_INIT do { } while ( 0 ) -#define GXV_NAME_ENTER( name ) do { } while ( 0 ) -#define GXV_EXIT do { } while ( 0 ) - -#define GXV_TRACE( s ) do { } while ( 0 ) - -#endif /* !FT_DEBUG_LEVEL_TRACE */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** 32bit alignment checking *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define GXV_32BIT_ALIGNMENT_VALIDATE( a ) \ - FT_BEGIN_STMNT \ - { \ - if ( (a) & 3 ) \ - FT_INVALID_OFFSET ; \ - } \ - FT_END_STMNT - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Dumping Binary Data *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define GXV_TRACE_HEXDUMP( p, len ) \ - FT_BEGIN_STMNT \ - { \ - FT_Bytes b; \ - \ - \ - for ( b = p; b < (FT_Bytes)p + len; b++ ) \ - FT_TRACE1(("\\x%02x", *b)) ; \ - } \ - FT_END_STMNT - -#define GXV_TRACE_HEXDUMP_C( p, len ) \ - FT_BEGIN_STMNT \ - { \ - FT_Bytes b; \ - \ - \ - for ( b = p; b < (FT_Bytes)p + len; b++ ) \ - if ( 0x40 < *b && *b < 0x7e ) \ - FT_TRACE1(("%c", *b)) ; \ - else \ - FT_TRACE1(("\\x%02x", *b)) ; \ - } \ - FT_END_STMNT - -#define GXV_TRACE_HEXDUMP_SFNTNAME( n ) \ - GXV_TRACE_HEXDUMP( n.string, n.string_len ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** LOOKUP TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - gxv_BinSrchHeader_validate( FT_Bytes p, - FT_Bytes limit, - FT_UShort* unitSize_p, - FT_UShort* nUnits_p, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_LookupTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Glyph ID *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( FT_Int ) - gxv_glyphid_validate( FT_UShort gid, - GXV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CONTROL POINT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - gxv_ctlPoint_validate( FT_UShort gid, - FT_Short ctl_point, - GXV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SFNT NAME *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - gxv_sfntName_validate( FT_UShort name_index, - FT_UShort min_index, - FT_UShort max_index, - GXV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** STATE TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - gxv_StateTable_subtable_setup( FT_UShort table_size, - FT_UShort classTable, - FT_UShort stateArray, - FT_UShort entryTable, - FT_UShort* classTable_length_p, - FT_UShort* stateArray_length_p, - FT_UShort* entryTable_length_p, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_XStateTable_subtable_setup( FT_ULong table_size, - FT_ULong classTable, - FT_ULong stateArray, - FT_ULong entryTable, - FT_ULong* classTable_length_p, - FT_ULong* stateArray_length_p, - FT_ULong* entryTable_length_p, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_StateTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_XStateTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY MACROS AND FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - gxv_array_getlimits_byte( FT_Bytes table, - FT_Bytes limit, - FT_Byte* min, - FT_Byte* max, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_array_getlimits_ushort( FT_Bytes table, - FT_Bytes limit, - FT_UShort* min, - FT_UShort* max, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_set_length_by_ushort_offset( FT_UShort* offset, - FT_UShort** length, - FT_UShort* buff, - FT_UInt nmemb, - FT_UShort limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_set_length_by_ulong_offset( FT_ULong* offset, - FT_ULong** length, - FT_ULong* buff, - FT_UInt nmemb, - FT_ULong limit, - GXV_Validator valid); - - -#define GXV_SUBTABLE_OFFSET_CHECK( _offset ) \ - FT_BEGIN_STMNT \ - if ( (_offset) > valid->subtable_length ) \ - FT_INVALID_OFFSET; \ - FT_END_STMNT - -#define GXV_SUBTABLE_LIMIT_CHECK( _count ) \ - FT_BEGIN_STMNT \ - if ( ( p + (_count) - valid->subtable_start ) > \ - valid->subtable_length ) \ - FT_INVALID_TOO_SHORT; \ - FT_END_STMNT - -#define GXV_USHORT_TO_SHORT( _us ) \ - ( ( 0x8000U < ( _us ) ) ? ( ( _us ) - 0x8000U ) : ( _us ) ) - -#define GXV_STATETABLE_HEADER_SIZE ( 2 + 2 + 2 + 2 ) -#define GXV_STATEHEADER_SIZE GXV_STATETABLE_HEADER_SIZE - -#define GXV_XSTATETABLE_HEADER_SIZE ( 4 + 4 + 4 + 4 ) -#define GXV_XSTATEHEADER_SIZE GXV_XSTATETABLE_HEADER_SIZE - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Table overlapping *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct GXV_odtect_DataRec_ - { - FT_Bytes start; - FT_ULong length; - FT_String* name; - - } GXV_odtect_DataRec, *GXV_odtect_Data; - - typedef struct GXV_odtect_RangeRec_ - { - FT_UInt nRanges; - GXV_odtect_Data range; - - } GXV_odtect_RangeRec, *GXV_odtect_Range; - - - FT_LOCAL( void ) - gxv_odtect_add_range( FT_Bytes start, - FT_ULong length, - const FT_String* name, - GXV_odtect_Range odtect ); - - FT_LOCAL( void ) - gxv_odtect_validate( GXV_odtect_Range odtect, - GXV_Validator valid ); - - -#define GXV_ODTECT( n, odtect ) \ - GXV_odtect_DataRec odtect ## _range[n]; \ - GXV_odtect_RangeRec odtect ## _rec = { 0, NULL }; \ - GXV_odtect_Range odtect = NULL - -#define GXV_ODTECT_INIT( odtect ) \ - FT_BEGIN_STMNT \ - odtect ## _rec.nRanges = 0; \ - odtect ## _rec.range = odtect ## _range; \ - odtect = & odtect ## _rec; \ - FT_END_STMNT - - - /* */ - -FT_END_HEADER - -#endif /* __GXVCOMMN_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxverror.h b/drivers/freetype/freetype/src/gxvalid/gxverror.h deleted file mode 100644 index c573b72de7..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxverror.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxverror.h */ -/* */ -/* TrueTypeGX/AAT validation module error codes (specification only). */ -/* */ -/* Copyright 2004, 2005, 2012-2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the OpenType validation module error */ - /* enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __GXVERROR_H__ -#define __GXVERROR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX GXV_Err_ -#define FT_ERR_BASE FT_Mod_Err_GXvalid - -#include FT_ERRORS_H - -#endif /* __GXVERROR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvfeat.c b/drivers/freetype/freetype/src/gxvalid/gxvfeat.c deleted file mode 100644 index 6f75650991..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvfeat.c +++ /dev/null @@ -1,339 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvfeat.c */ -/* */ -/* TrueTypeGX/AAT feat table validation (body). */ -/* */ -/* Copyright 2004, 2005, 2008, 2012 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvalid.h" -#include "gxvcommn.h" -#include "gxvfeat.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_gxvfeat - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Data and Types *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct GXV_feat_DataRec_ - { - FT_UInt reserved_size; - FT_UShort feature; - FT_UShort setting; - - } GXV_feat_DataRec, *GXV_feat_Data; - - -#define GXV_FEAT_DATA( field ) GXV_TABLE_DATA( feat, field ) - - - typedef enum GXV_FeatureFlagsMask_ - { - GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000U, - GXV_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000, - GXV_FEAT_MASK_UNUSED = 0x3F00, - GXV_FEAT_MASK_DEFAULT_SETTING = 0x00FF - - } GXV_FeatureFlagsMask; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - gxv_feat_registry_validate( FT_UShort feature, - FT_UShort nSettings, - FT_Bool exclusive, - GXV_Validator valid ) - { - GXV_NAME_ENTER( "feature in registry" ); - - GXV_TRACE(( " (feature = %u)\n", feature )); - - if ( feature >= gxv_feat_registry_length ) - { - GXV_TRACE(( "feature number %d is out of range %d\n", - feature, gxv_feat_registry_length )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - goto Exit; - } - - if ( gxv_feat_registry[feature].existence == 0 ) - { - GXV_TRACE(( "feature number %d is in defined range but doesn't exist\n", - feature )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - goto Exit; - } - - if ( gxv_feat_registry[feature].apple_reserved ) - { - /* Don't use here. Apple is reserved. */ - GXV_TRACE(( "feature number %d is reserved by Apple\n", feature )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) - FT_INVALID_DATA; - } - - if ( nSettings != gxv_feat_registry[feature].nSettings ) - { - GXV_TRACE(( "feature %d: nSettings %d != defined nSettings %d\n", - feature, nSettings, - gxv_feat_registry[feature].nSettings )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) - FT_INVALID_DATA; - } - - if ( exclusive != gxv_feat_registry[feature].exclusive ) - { - GXV_TRACE(( "exclusive flag %d differs from predefined value\n", - exclusive )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) - FT_INVALID_DATA; - } - - Exit: - GXV_EXIT; - } - - - static void - gxv_feat_name_index_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - FT_Short nameIndex; - - - GXV_NAME_ENTER( "nameIndex" ); - - GXV_LIMIT_CHECK( 2 ); - nameIndex = FT_NEXT_SHORT ( p ); - GXV_TRACE(( " (nameIndex = %d)\n", nameIndex )); - - gxv_sfntName_validate( (FT_UShort)nameIndex, - 255, - 32768U, - valid ); - - GXV_EXIT; - } - - - static void - gxv_feat_setting_validate( FT_Bytes table, - FT_Bytes limit, - FT_Bool exclusive, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort setting; - - - GXV_NAME_ENTER( "setting" ); - - GXV_LIMIT_CHECK( 2 ); - - setting = FT_NEXT_USHORT( p ); - - /* If we have exclusive setting, the setting should be odd. */ - if ( exclusive && ( setting & 1 ) == 0 ) - FT_INVALID_DATA; - - gxv_feat_name_index_validate( p, limit, valid ); - - GXV_FEAT_DATA( setting ) = setting; - - GXV_EXIT; - } - - - static void - gxv_feat_name_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt reserved_size = GXV_FEAT_DATA( reserved_size ); - - FT_UShort feature; - FT_UShort nSettings; - FT_ULong settingTable; - FT_UShort featureFlags; - - FT_Bool exclusive; - FT_Int last_setting; - FT_UInt i; - - - GXV_NAME_ENTER( "name" ); - - /* feature + nSettings + settingTable + featureFlags */ - GXV_LIMIT_CHECK( 2 + 2 + 4 + 2 ); - - feature = FT_NEXT_USHORT( p ); - GXV_FEAT_DATA( feature ) = feature; - - nSettings = FT_NEXT_USHORT( p ); - settingTable = FT_NEXT_ULONG ( p ); - featureFlags = FT_NEXT_USHORT( p ); - - if ( settingTable < reserved_size ) - FT_INVALID_OFFSET; - - if ( ( featureFlags & GXV_FEAT_MASK_UNUSED ) == 0 ) - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - - exclusive = FT_BOOL( featureFlags & GXV_FEAT_MASK_EXCLUSIVE_SETTINGS ); - if ( exclusive ) - { - FT_Byte dynamic_default; - - - if ( featureFlags & GXV_FEAT_MASK_DYNAMIC_DEFAULT ) - dynamic_default = (FT_Byte)( featureFlags & - GXV_FEAT_MASK_DEFAULT_SETTING ); - else - dynamic_default = 0; - - /* If exclusive, check whether default setting is in the range. */ - if ( !( dynamic_default < nSettings ) ) - FT_INVALID_FORMAT; - } - - gxv_feat_registry_validate( feature, nSettings, exclusive, valid ); - - gxv_feat_name_index_validate( p, limit, valid ); - - p = valid->root->base + settingTable; - for ( last_setting = -1, i = 0; i < nSettings; i++ ) - { - gxv_feat_setting_validate( p, limit, exclusive, valid ); - - if ( (FT_Int)GXV_FEAT_DATA( setting ) <= last_setting ) - GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); - - last_setting = (FT_Int)GXV_FEAT_DATA( setting ); - /* setting + nameIndex */ - p += ( 2 + 2 ); - } - - GXV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** feat TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - gxv_feat_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - - GXV_feat_DataRec featrec; - GXV_feat_Data feat = &featrec; - - FT_Bytes p = table; - FT_Bytes limit = 0; - - FT_UInt featureNameCount; - - FT_UInt i; - FT_Int last_feature; - - - valid->root = ftvalid; - valid->table_data = feat; - valid->face = face; - - FT_TRACE3(( "validating `feat' table\n" )); - GXV_INIT; - - feat->reserved_size = 0; - - /* version + featureNameCount + none_0 + none_1 */ - GXV_LIMIT_CHECK( 4 + 2 + 2 + 4 ); - feat->reserved_size += 4 + 2 + 2 + 4; - - if ( FT_NEXT_ULONG( p ) != 0x00010000UL ) /* Version */ - FT_INVALID_FORMAT; - - featureNameCount = FT_NEXT_USHORT( p ); - GXV_TRACE(( " (featureNameCount = %d)\n", featureNameCount )); - - if ( !( IS_PARANOID_VALIDATION ) ) - p += 6; /* skip (none) and (none) */ - else - { - if ( FT_NEXT_USHORT( p ) != 0 ) - FT_INVALID_DATA; - - if ( FT_NEXT_ULONG( p ) != 0 ) - FT_INVALID_DATA; - } - - feat->reserved_size += featureNameCount * ( 2 + 2 + 4 + 2 + 2 ); - - for ( last_feature = -1, i = 0; i < featureNameCount; i++ ) - { - gxv_feat_name_validate( p, limit, valid ); - - if ( (FT_Int)GXV_FEAT_DATA( feature ) <= last_feature ) - GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); - - last_feature = GXV_FEAT_DATA( feature ); - p += 2 + 2 + 4 + 2 + 2; - } - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvfeat.h b/drivers/freetype/freetype/src/gxvalid/gxvfeat.h deleted file mode 100644 index 049d23a0b9..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvfeat.h +++ /dev/null @@ -1,172 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvfeat.h */ -/* */ -/* TrueTypeGX/AAT feat table validation (specification). */ -/* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#ifndef __GXVFEAT_H__ -#define __GXVFEAT_H__ - - -#include "gxvalid.h" -#include "gxvcommn.h" - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Registry predefined by Apple *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* TODO: More compact format */ - typedef struct GXV_Feature_RegistryRec_ - { - FT_Bool existence; - FT_Bool apple_reserved; - FT_Bool exclusive; - FT_Byte nSettings; - - } GX_Feature_RegistryRec; - - -#define gxv_feat_registry_length \ - ( sizeof ( gxv_feat_registry ) / \ - sizeof ( GX_Feature_RegistryRec ) ) - - - static GX_Feature_RegistryRec gxv_feat_registry[] = - { - /* Generated from gxvfgen.c */ - {1, 0, 0, 1}, /* All Typographic Features */ - {1, 0, 0, 8}, /* Ligatures */ - {1, 0, 1, 3}, /* Cursive Connection */ - {1, 0, 1, 6}, /* Letter Case */ - {1, 0, 0, 1}, /* Vertical Substitution */ - {1, 0, 0, 1}, /* Linguistic Rearrangement */ - {1, 0, 1, 2}, /* Number Spacing */ - {1, 1, 0, 0}, /* Apple Reserved 1 */ - {1, 0, 0, 5}, /* Smart Swashes */ - {1, 0, 1, 3}, /* Diacritics */ - {1, 0, 1, 4}, /* Vertical Position */ - {1, 0, 1, 3}, /* Fractions */ - {1, 1, 0, 0}, /* Apple Reserved 2 */ - {1, 0, 0, 1}, /* Overlapping Characters */ - {1, 0, 0, 6}, /* Typographic Extras */ - {1, 0, 0, 5}, /* Mathematical Extras */ - {1, 0, 1, 7}, /* Ornament Sets */ - {1, 0, 1, 1}, /* Character Alternatives */ - {1, 0, 1, 5}, /* Design Complexity */ - {1, 0, 1, 6}, /* Style Options */ - {1, 0, 1, 11}, /* Character Shape */ - {1, 0, 1, 2}, /* Number Case */ - {1, 0, 1, 4}, /* Text Spacing */ - {1, 0, 1, 10}, /* Transliteration */ - {1, 0, 1, 9}, /* Annotation */ - {1, 0, 1, 2}, /* Kana Spacing */ - {1, 0, 1, 2}, /* Ideographic Spacing */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {0, 0, 0, 0}, /* __EMPTY__ */ - {1, 0, 1, 4}, /* Text Spacing */ - {1, 0, 1, 2}, /* Kana Spacing */ - {1, 0, 1, 2}, /* Ideographic Spacing */ - {1, 0, 1, 4}, /* CJK Roman Spacing */ - }; - - -#endif /* __GXVFEAT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvfgen.c b/drivers/freetype/freetype/src/gxvalid/gxvfgen.c deleted file mode 100644 index e48778a2a1..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvfgen.c +++ /dev/null @@ -1,482 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxfgen.c */ -/* */ -/* Generate feature registry data for gxv `feat' validator. */ -/* This program is derived from gxfeatreg.c in gxlayout. */ -/* */ -/* Copyright 2004, 2005, 2006 by Masatake YAMATO and Redhat K.K. */ -/* */ -/* This file 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxfeatreg.c */ -/* */ -/* Database of font features pre-defined by Apple Computer, Inc. */ -/* http://developer.apple.com/fonts/Registry/ */ -/* (body). */ -/* */ -/* Copyright 2003 by */ -/* Masatake YAMATO and Redhat K.K. */ -/* */ -/* This file 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* Development of gxfeatreg.c is supported by */ -/* Information-technology Promotion Agency, Japan. */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* This file is compiled as a stand-alone executable. */ -/* This file is never compiled into `libfreetype2'. */ -/* The output of this file is used in `gxvfeat.c'. */ -/* ----------------------------------------------------------------------- */ -/* Compile: gcc `pkg-config --cflags freetype2` gxvfgen.c -o gxvfgen */ -/* Run: ./gxvfgen > tmp.c */ -/* */ -/***************************************************************************/ - - /*******************************************************************/ - /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ - /*******************************************************************/ - - /* - * If you add a new setting to a feature, check the number of settings - * in the feature. If the number is greater than the value defined as - * FEATREG_MAX_SETTING, update the value. - */ -#define FEATREG_MAX_SETTING 12 - - /*******************************************************************/ - /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ - /*******************************************************************/ - - -#include <stdio.h> -#include <string.h> - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Data and Types *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define APPLE_RESERVED "Apple Reserved" -#define APPLE_RESERVED_LENGTH 14 - - typedef struct GX_Feature_RegistryRec_ - { - const char* feat_name; - char exclusive; - char* setting_name[FEATREG_MAX_SETTING]; - - } GX_Feature_RegistryRec; - - -#define EMPTYFEAT {0, 0, {NULL}} - - - static GX_Feature_RegistryRec featreg_table[] = { - { /* 0 */ - "All Typographic Features", - 0, - { - "All Type Features", - NULL - } - }, { /* 1 */ - "Ligatures", - 0, - { - "Required Ligatures", - "Common Ligatures", - "Rare Ligatures", - "Logos", - "Rebus Pictures", - "Diphthong Ligatures", - "Squared Ligatures", - "Squared Ligatures, Abbreviated", - NULL - } - }, { /* 2 */ - "Cursive Connection", - 1, - { - "Unconnected", - "Partially Connected", - "Cursive", - NULL - } - }, { /* 3 */ - "Letter Case", - 1, - { - "Upper & Lower Case", - "All Caps", - "All Lower Case", - "Small Caps", - "Initial Caps", - "Initial Caps & Small Caps", - NULL - } - }, { /* 4 */ - "Vertical Substitution", - 0, - { - /* "Substitute Vertical Forms", */ - "Turns on the feature", - NULL - } - }, { /* 5 */ - "Linguistic Rearrangement", - 0, - { - /* "Linguistic Rearrangement", */ - "Turns on the feature", - NULL - } - }, { /* 6 */ - "Number Spacing", - 1, - { - "Monospaced Numbers", - "Proportional Numbers", - NULL - } - }, { /* 7 */ - APPLE_RESERVED " 1", - 0, - {NULL} - }, { /* 8 */ - "Smart Swashes", - 0, - { - "Word Initial Swashes", - "Word Final Swashes", - "Line Initial Swashes", - "Line Final Swashes", - "Non-Final Swashes", - NULL - } - }, { /* 9 */ - "Diacritics", - 1, - { - "Show Diacritics", - "Hide Diacritics", - "Decompose Diacritics", - NULL - } - }, { /* 10 */ - "Vertical Position", - 1, - { - /* "Normal Position", */ - "No Vertical Position", - "Superiors", - "Inferiors", - "Ordinals", - NULL - } - }, { /* 11 */ - "Fractions", - 1, - { - "No Fractions", - "Vertical Fractions", - "Diagonal Fractions", - NULL - } - }, { /* 12 */ - APPLE_RESERVED " 2", - 0, - {NULL} - }, { /* 13 */ - "Overlapping Characters", - 0, - { - /* "Prevent Overlap", */ - "Turns on the feature", - NULL - } - }, { /* 14 */ - "Typographic Extras", - 0, - { - "Hyphens to Em Dash", - "Hyphens to En Dash", - "Unslashed Zero", - "Form Interrobang", - "Smart Quotes", - "Periods to Ellipsis", - NULL - } - }, { /* 15 */ - "Mathematical Extras", - 0, - { - "Hyphens to Minus", - "Asterisk to Multiply", - "Slash to Divide", - "Inequality Ligatures", - "Exponents", - NULL - } - }, { /* 16 */ - "Ornament Sets", - 1, - { - "No Ornaments", - "Dingbats", - "Pi Characters", - "Fleurons", - "Decorative Borders", - "International Symbols", - "Math Symbols", - NULL - } - }, { /* 17 */ - "Character Alternatives", - 1, - { - "No Alternates", - /* TODO */ - NULL - } - }, { /* 18 */ - "Design Complexity", - 1, - { - "Design Level 1", - "Design Level 2", - "Design Level 3", - "Design Level 4", - "Design Level 5", - /* TODO */ - NULL - } - }, { /* 19 */ - "Style Options", - 1, - { - "No Style Options", - "Display Text", - "Engraved Text", - "Illuminated Caps", - "Tilling Caps", - "Tall Caps", - NULL - } - }, { /* 20 */ - "Character Shape", - 1, - { - "Traditional Characters", - "Simplified Characters", - "JIS 1978 Characters", - "JIS 1983 Characters", - "JIS 1990 Characters", - "Traditional Characters, Alternative Set 1", - "Traditional Characters, Alternative Set 2", - "Traditional Characters, Alternative Set 3", - "Traditional Characters, Alternative Set 4", - "Traditional Characters, Alternative Set 5", - "Expert Characters", - NULL /* count => 12 */ - } - }, { /* 21 */ - "Number Case", - 1, - { - "Lower Case Numbers", - "Upper Case Numbers", - NULL - } - }, { /* 22 */ - "Text Spacing", - 1, - { - "Proportional", - "Monospaced", - "Half-width", - "Normal", - NULL - } - }, /* Here after Newer */ { /* 23 */ - "Transliteration", - 1, - { - "No Transliteration", - "Hanja To Hangul", - "Hiragana to Katakana", - "Katakana to Hiragana", - "Kana to Romanization", - "Romanization to Hiragana", - "Romanization to Katakana", - "Hanja to Hangul, Alternative Set 1", - "Hanja to Hangul, Alternative Set 2", - "Hanja to Hangul, Alternative Set 3", - NULL - } - }, { /* 24 */ - "Annotation", - 1, - { - "No Annotation", - "Box Annotation", - "Rounded Box Annotation", - "Circle Annotation", - "Inverted Circle Annotation", - "Parenthesis Annotation", - "Period Annotation", - "Roman Numeral Annotation", - "Diamond Annotation", - NULL - } - }, { /* 25 */ - "Kana Spacing", - 1, - { - "Full Width", - "Proportional", - NULL - } - }, { /* 26 */ - "Ideographic Spacing", - 1, - { - "Full Width", - "Proportional", - NULL - } - }, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 27-30 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 31-35 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 36-40 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 40-45 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 46-50 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 51-55 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 56-60 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 61-65 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 66-70 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 71-75 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 76-80 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 81-85 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 86-90 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 91-95 */ - EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 96-98 */ - EMPTYFEAT, /* 99 */ { /* 100 => 22 */ - "Text Spacing", - 1, - { - "Proportional", - "Monospaced", - "Half-width", - "Normal", - NULL - } - }, { /* 101 => 25 */ - "Kana Spacing", - 1, - { - "Full Width", - "Proportional", - NULL - } - }, { /* 102 => 26 */ - "Ideographic Spacing", - 1, - { - "Full Width", - "Proportional", - NULL - } - }, { /* 103 */ - "CJK Roman Spacing", - 1, - { - "Half-width", - "Proportional", - "Default Roman", - "Full-width Roman", - NULL - } - }, { /* 104 => 1 */ - "All Typographic Features", - 0, - { - "All Type Features", - NULL - } - } - }; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Generator *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - int - main( void ) - { - int i; - - - printf( " {\n" ); - printf( " /* Generated from %s */\n", __FILE__ ); - - for ( i = 0; - i < sizeof ( featreg_table ) / sizeof ( GX_Feature_RegistryRec ); - i++ ) - { - const char* feat_name; - int nSettings; - - - feat_name = featreg_table[i].feat_name; - for ( nSettings = 0; - featreg_table[i].setting_name[nSettings]; - nSettings++) - ; /* Do nothing */ - - printf( " {%1d, %1d, %1d, %2d}, /* %s */\n", - feat_name ? 1 : 0, - ( feat_name && - ( ft_strncmp( feat_name, - APPLE_RESERVED, APPLE_RESERVED_LENGTH ) == 0 ) - ) ? 1 : 0, - featreg_table[i].exclusive ? 1 : 0, - nSettings, - feat_name ? feat_name : "__EMPTY__" ); - } - - printf( " };\n" ); - - return 0; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvjust.c b/drivers/freetype/freetype/src/gxvalid/gxvjust.c deleted file mode 100644 index 7816e0b7fb..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvjust.c +++ /dev/null @@ -1,717 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvjust.c */ -/* */ -/* TrueTypeGX/AAT just table validation (body). */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvalid.h" -#include "gxvcommn.h" - -#include FT_SFNT_NAMES_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_gxvjust - - /* - * referred `just' table format specification: - * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6just.html - * last updated 2000. - * ---------------------------------------------- - * [JUST HEADER]: GXV_JUST_HEADER_SIZE - * version (fixed: 32bit) = 0x00010000 - * format (uint16: 16bit) = 0 is only defined (2000) - * horizOffset (uint16: 16bit) - * vertOffset (uint16: 16bit) - * ---------------------------------------------- - */ - - typedef struct GXV_just_DataRec_ - { - FT_UShort wdc_offset_max; - FT_UShort wdc_offset_min; - FT_UShort pc_offset_max; - FT_UShort pc_offset_min; - - } GXV_just_DataRec, *GXV_just_Data; - - -#define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a ) - - - /* GX just table does not define their subset of GID */ - static void - gxv_just_check_max_gid( FT_UShort gid, - const FT_String* msg_tag, - GXV_Validator valid ) - { - if ( gid < valid->face->num_glyphs ) - return; - - GXV_TRACE(( "just table includes too large %s" - " GID=%d > %d (in maxp)\n", - msg_tag, gid, valid->face->num_glyphs )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - - - static void - gxv_just_wdp_entry_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_ULong justClass; -#ifdef GXV_LOAD_UNUSED_VARS - FT_Fixed beforeGrowLimit; - FT_Fixed beforeShrinkGrowLimit; - FT_Fixed afterGrowLimit; - FT_Fixed afterShrinkGrowLimit; - FT_UShort growFlags; - FT_UShort shrinkFlags; -#endif - - - GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 ); - justClass = FT_NEXT_ULONG( p ); -#ifndef GXV_LOAD_UNUSED_VARS - p += 4 + 4 + 4 + 4 + 2 + 2; -#else - beforeGrowLimit = FT_NEXT_ULONG( p ); - beforeShrinkGrowLimit = FT_NEXT_ULONG( p ); - afterGrowLimit = FT_NEXT_ULONG( p ); - afterShrinkGrowLimit = FT_NEXT_ULONG( p ); - growFlags = FT_NEXT_USHORT( p ); - shrinkFlags = FT_NEXT_USHORT( p ); -#endif - - /* According to Apple spec, only 7bits in justClass is used */ - if ( ( justClass & 0xFFFFFF80 ) != 0 ) - { - GXV_TRACE(( "just table includes non-zero value" - " in unused justClass higher bits" - " of WidthDeltaPair" )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - - valid->subtable_length = p - table; - } - - - static void - gxv_just_wdc_entry_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_ULong count, i; - - - GXV_LIMIT_CHECK( 4 ); - count = FT_NEXT_ULONG( p ); - for ( i = 0; i < count; i++ ) - { - GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count )); - gxv_just_wdp_entry_validate( p, limit, valid ); - p += valid->subtable_length; - } - - valid->subtable_length = p - table; - } - - - static void - gxv_just_widthDeltaClusters_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table ; - FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max ); - FT_UInt i; - - - GXV_NAME_ENTER( "just justDeltaClusters" ); - - if ( limit <= wdc_end ) - FT_INVALID_OFFSET; - - for ( i = 0; p <= wdc_end; i++ ) - { - gxv_just_wdc_entry_validate( p, limit, valid ); - p += valid->subtable_length; - } - - valid->subtable_length = p - table; - - GXV_EXIT; - } - - - static void - gxv_just_actSubrecord_type0_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - FT_Fixed lowerLimit; - FT_Fixed upperLimit; -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort order; -#endif - FT_UShort decomposedCount; - - FT_UInt i; - - - GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); - lowerLimit = FT_NEXT_ULONG( p ); - upperLimit = FT_NEXT_ULONG( p ); -#ifdef GXV_LOAD_UNUSED_VARS - order = FT_NEXT_USHORT( p ); -#else - p += 2; -#endif - decomposedCount = FT_NEXT_USHORT( p ); - - if ( lowerLimit >= upperLimit ) - { - GXV_TRACE(( "just table includes invalid range spec:" - " lowerLimit(%d) > upperLimit(%d)\n" )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - - for ( i = 0; i < decomposedCount; i++ ) - { - FT_UShort glyphs; - - - GXV_LIMIT_CHECK( 2 ); - glyphs = FT_NEXT_USHORT( p ); - gxv_just_check_max_gid( glyphs, "type0:glyphs", valid ); - } - - valid->subtable_length = p - table; - } - - - static void - gxv_just_actSubrecord_type1_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort addGlyph; - - - GXV_LIMIT_CHECK( 2 ); - addGlyph = FT_NEXT_USHORT( p ); - - gxv_just_check_max_gid( addGlyph, "type1:addGlyph", valid ); - - valid->subtable_length = p - table; - } - - - static void - gxv_just_actSubrecord_type2_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; -#ifdef GXV_LOAD_UNUSED_VARS - FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ -#endif - FT_UShort addGlyph; - FT_UShort substGlyph; - - - GXV_LIMIT_CHECK( 4 + 2 + 2 ); -#ifdef GXV_LOAD_UNUSED_VARS - substThreshhold = FT_NEXT_ULONG( p ); -#else - p += 4; -#endif - addGlyph = FT_NEXT_USHORT( p ); - substGlyph = FT_NEXT_USHORT( p ); - - if ( addGlyph != 0xFFFF ) - gxv_just_check_max_gid( addGlyph, "type2:addGlyph", valid ); - - gxv_just_check_max_gid( substGlyph, "type2:substGlyph", valid ); - - valid->subtable_length = p - table; - } - - - static void - gxv_just_actSubrecord_type4_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_ULong variantsAxis; - FT_Fixed minimumLimit; - FT_Fixed noStretchValue; - FT_Fixed maximumLimit; - - - GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); - variantsAxis = FT_NEXT_ULONG( p ); - minimumLimit = FT_NEXT_ULONG( p ); - noStretchValue = FT_NEXT_ULONG( p ); - maximumLimit = FT_NEXT_ULONG( p ); - - valid->subtable_length = p - table; - - if ( variantsAxis != 0x64756374 ) /* 'duct' */ - GXV_TRACE(( "variantsAxis 0x%08x is non default value", - variantsAxis )); - - if ( minimumLimit > noStretchValue ) - GXV_TRACE(( "type4:minimumLimit 0x%08x > noStretchValue 0x%08x\n", - minimumLimit, noStretchValue )); - else if ( noStretchValue > maximumLimit ) - GXV_TRACE(( "type4:noStretchValue 0x%08x > maximumLimit 0x%08x\n", - noStretchValue, maximumLimit )); - else if ( !IS_PARANOID_VALIDATION ) - return; - - FT_INVALID_DATA; - } - - - static void - gxv_just_actSubrecord_type5_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort flags; - FT_UShort glyph; - - - GXV_LIMIT_CHECK( 2 + 2 ); - flags = FT_NEXT_USHORT( p ); - glyph = FT_NEXT_USHORT( p ); - - if ( flags ) - GXV_TRACE(( "type5: nonzero value 0x%04x in unused flags\n", - flags )); - gxv_just_check_max_gid( glyph, "type5:glyph", valid ); - - valid->subtable_length = p - table; - } - - - /* parse single actSubrecord */ - static void - gxv_just_actSubrecord_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort actionClass; - FT_UShort actionType; - FT_ULong actionLength; - - - GXV_NAME_ENTER( "just actSubrecord" ); - - GXV_LIMIT_CHECK( 2 + 2 + 4 ); - actionClass = FT_NEXT_USHORT( p ); - actionType = FT_NEXT_USHORT( p ); - actionLength = FT_NEXT_ULONG( p ); - - /* actionClass is related with justClass using 7bit only */ - if ( ( actionClass & 0xFF80 ) != 0 ) - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - - if ( actionType == 0 ) - gxv_just_actSubrecord_type0_validate( p, limit, valid ); - else if ( actionType == 1 ) - gxv_just_actSubrecord_type1_validate( p, limit, valid ); - else if ( actionType == 2 ) - gxv_just_actSubrecord_type2_validate( p, limit, valid ); - else if ( actionType == 3 ) - ; /* Stretch glyph action: no actionData */ - else if ( actionType == 4 ) - gxv_just_actSubrecord_type4_validate( p, limit, valid ); - else if ( actionType == 5 ) - gxv_just_actSubrecord_type5_validate( p, limit, valid ); - else - FT_INVALID_DATA; - - valid->subtable_length = actionLength; - - GXV_EXIT; - } - - - static void - gxv_just_pcActionRecord_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_ULong actionCount; - FT_ULong i; - - - GXV_LIMIT_CHECK( 4 ); - actionCount = FT_NEXT_ULONG( p ); - GXV_TRACE(( "actionCount = %d\n", actionCount )); - - for ( i = 0; i < actionCount; i++ ) - { - gxv_just_actSubrecord_validate( p, limit, valid ); - p += valid->subtable_length; - } - - valid->subtable_length = p - table; - - GXV_EXIT; - } - - - static void - gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - FT_UNUSED( glyph ); - - if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) ) - GXV_JUST_DATA( pc_offset_max ) = value_p->u; - if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) ) - GXV_JUST_DATA( pc_offset_min ) = value_p->u; - } - - - static void - gxv_just_pcLookupTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - GXV_NAME_ENTER( "just pcLookupTable" ); - GXV_JUST_DATA( pc_offset_max ) = 0x0000; - GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU; - - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; - - gxv_LookupTable_validate( p, limit, valid ); - - /* subtable_length is set by gxv_LookupTable_validate() */ - - GXV_EXIT; - } - - - static void - gxv_just_postcompTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - GXV_NAME_ENTER( "just postcompTable" ); - - gxv_just_pcLookupTable_validate( p, limit, valid ); - p += valid->subtable_length; - - gxv_just_pcActionRecord_validate( p, limit, valid ); - p += valid->subtable_length; - - valid->subtable_length = p - table; - - GXV_EXIT; - } - - - static void - gxv_just_classTable_entry_validate( - FT_Byte state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_UNUSED_VARS - /* TODO: validate markClass & currentClass */ - FT_UShort setMark; - FT_UShort dontAdvance; - FT_UShort markClass; - FT_UShort currentClass; -#endif - - FT_UNUSED( state ); - FT_UNUSED( glyphOffset_p ); - FT_UNUSED( table ); - FT_UNUSED( limit ); - FT_UNUSED( valid ); - -#ifndef GXV_LOAD_UNUSED_VARS - FT_UNUSED( flags ); -#else - setMark = (FT_UShort)( ( flags >> 15 ) & 1 ); - dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); - markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F ); - currentClass = (FT_UShort)( flags & 0x7F ); -#endif - } - - - static void - gxv_just_justClassTable_validate ( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort length; - FT_UShort coverage; - FT_ULong subFeatureFlags; - - - GXV_NAME_ENTER( "just justClassTable" ); - - GXV_LIMIT_CHECK( 2 + 2 + 4 ); - length = FT_NEXT_USHORT( p ); - coverage = FT_NEXT_USHORT( p ); - subFeatureFlags = FT_NEXT_ULONG( p ); - - GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s) ", coverage )); - if ( ( coverage & 0x4000 ) == 0 ) - GXV_TRACE(( "ascending\n" )); - else - GXV_TRACE(( "descending\n" )); - - if ( subFeatureFlags ) - GXV_TRACE(( " justClassTable: nonzero value (0x%08x)" - " in unused subFeatureFlags\n", subFeatureFlags )); - - valid->statetable.optdata = NULL; - valid->statetable.optdata_load_func = NULL; - valid->statetable.subtable_setup_func = NULL; - valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = - gxv_just_classTable_entry_validate; - - gxv_StateTable_validate( p, table + length, valid ); - - /* subtable_length is set by gxv_LookupTable_validate() */ - - GXV_EXIT; - } - - - static void - gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - FT_UNUSED( glyph ); - - if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) ) - GXV_JUST_DATA( wdc_offset_max ) = value_p->u; - if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) ) - GXV_JUST_DATA( wdc_offset_min ) = value_p->u; - } - - - static void - gxv_just_justData_lookuptable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - GXV_JUST_DATA( wdc_offset_max ) = 0x0000; - GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU; - - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; - - gxv_LookupTable_validate( p, limit, valid ); - - /* subtable_length is set by gxv_LookupTable_validate() */ - - GXV_EXIT; - } - - - /* - * gxv_just_justData_validate() parses and validates horizData, vertData. - */ - static void - gxv_just_justData_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - /* - * following 3 offsets are measured from the start of `just' - * (which table points to), not justData - */ - FT_UShort justClassTableOffset; - FT_UShort wdcTableOffset; - FT_UShort pcTableOffset; - FT_Bytes p = table; - - GXV_ODTECT( 4, odtect ); - - - GXV_NAME_ENTER( "just justData" ); - - GXV_ODTECT_INIT( odtect ); - GXV_LIMIT_CHECK( 2 + 2 + 2 ); - justClassTableOffset = FT_NEXT_USHORT( p ); - wdcTableOffset = FT_NEXT_USHORT( p ); - pcTableOffset = FT_NEXT_USHORT( p ); - - GXV_TRACE(( " (justClassTableOffset = 0x%04x)\n", justClassTableOffset )); - GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset )); - GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset )); - - gxv_just_justData_lookuptable_validate( p, limit, valid ); - gxv_odtect_add_range( p, valid->subtable_length, - "just_LookupTable", odtect ); - - if ( wdcTableOffset ) - { - gxv_just_widthDeltaClusters_validate( - valid->root->base + wdcTableOffset, limit, valid ); - gxv_odtect_add_range( valid->root->base + wdcTableOffset, - valid->subtable_length, "just_wdcTable", odtect ); - } - - if ( pcTableOffset ) - { - gxv_just_postcompTable_validate( valid->root->base + pcTableOffset, - limit, valid ); - gxv_odtect_add_range( valid->root->base + pcTableOffset, - valid->subtable_length, "just_pcTable", odtect ); - } - - if ( justClassTableOffset ) - { - gxv_just_justClassTable_validate( - valid->root->base + justClassTableOffset, limit, valid ); - gxv_odtect_add_range( valid->root->base + justClassTableOffset, - valid->subtable_length, "just_justClassTable", - odtect ); - } - - gxv_odtect_validate( odtect, valid ); - - GXV_EXIT; - } - - - FT_LOCAL_DEF( void ) - gxv_just_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - FT_Bytes p = table; - FT_Bytes limit = 0; - - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - GXV_just_DataRec justrec; - GXV_just_Data just = &justrec; - - FT_ULong version; - FT_UShort format; - FT_UShort horizOffset; - FT_UShort vertOffset; - - GXV_ODTECT( 3, odtect ); - - - GXV_ODTECT_INIT( odtect ); - - valid->root = ftvalid; - valid->table_data = just; - valid->face = face; - - FT_TRACE3(( "validating `just' table\n" )); - GXV_INIT; - - limit = valid->root->limit; - - GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 ); - version = FT_NEXT_ULONG( p ); - format = FT_NEXT_USHORT( p ); - horizOffset = FT_NEXT_USHORT( p ); - vertOffset = FT_NEXT_USHORT( p ); - gxv_odtect_add_range( table, p - table, "just header", odtect ); - - - /* Version 1.0 (always:2000) */ - GXV_TRACE(( " (version = 0x%08x)\n", version )); - if ( version != 0x00010000UL ) - FT_INVALID_FORMAT; - - /* format 0 (always:2000) */ - GXV_TRACE(( " (format = 0x%04x)\n", format )); - if ( format != 0x0000 ) - FT_INVALID_FORMAT; - - GXV_TRACE(( " (horizOffset = %d)\n", horizOffset )); - GXV_TRACE(( " (vertOffset = %d)\n", vertOffset )); - - - /* validate justData */ - if ( 0 < horizOffset ) - { - gxv_just_justData_validate( table + horizOffset, limit, valid ); - gxv_odtect_add_range( table + horizOffset, valid->subtable_length, - "horizJustData", odtect ); - } - - if ( 0 < vertOffset ) - { - gxv_just_justData_validate( table + vertOffset, limit, valid ); - gxv_odtect_add_range( table + vertOffset, valid->subtable_length, - "vertJustData", odtect ); - } - - gxv_odtect_validate( odtect, valid ); - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvkern.c b/drivers/freetype/freetype/src/gxvalid/gxvkern.c deleted file mode 100644 index 557c5f1fe4..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvkern.c +++ /dev/null @@ -1,920 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvkern.c */ -/* */ -/* TrueTypeGX/AAT kern table validation (body). */ -/* */ -/* Copyright 2004-2007, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvalid.h" -#include "gxvcommn.h" - -#include FT_SFNT_NAMES_H -#include FT_SERVICE_GX_VALIDATE_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_gxvkern - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Data and Types *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef enum GXV_kern_Version_ - { - KERN_VERSION_CLASSIC = 0x0000, - KERN_VERSION_NEW = 0x0001 - - } GXV_kern_Version; - - - typedef enum GXV_kern_Dialect_ - { - KERN_DIALECT_UNKNOWN = 0, - KERN_DIALECT_MS = FT_VALIDATE_MS, - KERN_DIALECT_APPLE = FT_VALIDATE_APPLE, - KERN_DIALECT_ANY = FT_VALIDATE_CKERN - - } GXV_kern_Dialect; - - - typedef struct GXV_kern_DataRec_ - { - GXV_kern_Version version; - void *subtable_data; - GXV_kern_Dialect dialect_request; - - } GXV_kern_DataRec, *GXV_kern_Data; - - -#define GXV_KERN_DATA( field ) GXV_TABLE_DATA( kern, field ) - -#define KERN_IS_CLASSIC( valid ) \ - ( KERN_VERSION_CLASSIC == GXV_KERN_DATA( version ) ) -#define KERN_IS_NEW( valid ) \ - ( KERN_VERSION_NEW == GXV_KERN_DATA( version ) ) - -#define KERN_DIALECT( valid ) \ - GXV_KERN_DATA( dialect_request ) -#define KERN_ALLOWS_MS( valid ) \ - ( KERN_DIALECT( valid ) & KERN_DIALECT_MS ) -#define KERN_ALLOWS_APPLE( valid ) \ - ( KERN_DIALECT( valid ) & KERN_DIALECT_APPLE ) - -#define GXV_KERN_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 4 ) -#define GXV_KERN_SUBTABLE_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 6 ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SUBTABLE VALIDATORS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* ============================= format 0 ============================== */ - - static void - gxv_kern_subtable_fmt0_pairs_validate( FT_Bytes table, - FT_Bytes limit, - FT_UShort nPairs, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort i; - - FT_UShort last_gid_left = 0; - FT_UShort last_gid_right = 0; - - FT_UNUSED( limit ); - - - GXV_NAME_ENTER( "kern format 0 pairs" ); - - for ( i = 0; i < nPairs; i++ ) - { - FT_UShort gid_left; - FT_UShort gid_right; -#ifdef GXV_LOAD_UNUSED_VARS - FT_Short kernValue; -#endif - - - /* left */ - gid_left = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( gid_left, valid ); - - /* right */ - gid_right = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( gid_right, valid ); - - /* Pairs of left and right GIDs must be unique and sorted. */ - GXV_TRACE(( "left gid = %u, right gid = %u\n", gid_left, gid_right )); - if ( gid_left == last_gid_left ) - { - if ( last_gid_right < gid_right ) - last_gid_right = gid_right; - else - FT_INVALID_DATA; - } - else if ( last_gid_left < gid_left ) - { - last_gid_left = gid_left; - last_gid_right = gid_right; - } - else - FT_INVALID_DATA; - - /* skip the kern value */ -#ifdef GXV_LOAD_UNUSED_VARS - kernValue = FT_NEXT_SHORT( p ); -#else - p += 2; -#endif - } - - GXV_EXIT; - } - - static void - gxv_kern_subtable_fmt0_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; - - FT_UShort nPairs; - FT_UShort unitSize; - - - GXV_NAME_ENTER( "kern subtable format 0" ); - - unitSize = 2 + 2 + 2; - nPairs = 0; - - /* nPairs, searchRange, entrySelector, rangeShift */ - GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid ); - p += 2 + 2 + 2 + 2; - - gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, valid ); - - GXV_EXIT; - } - - - /* ============================= format 1 ============================== */ - - - typedef struct GXV_kern_fmt1_StateOptRec_ - { - FT_UShort valueTable; - FT_UShort valueTable_length; - - } GXV_kern_fmt1_StateOptRec, *GXV_kern_fmt1_StateOptRecData; - - - static void - gxv_kern_subtable_fmt1_valueTable_load( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - GXV_kern_fmt1_StateOptRecData optdata = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; - - - GXV_LIMIT_CHECK( 2 ); - optdata->valueTable = FT_NEXT_USHORT( p ); - } - - - /* - * passed tables_size covers whole StateTable, including kern fmt1 header - */ - static void - gxv_kern_subtable_fmt1_subtable_setup( FT_UShort table_size, - FT_UShort classTable, - FT_UShort stateArray, - FT_UShort entryTable, - FT_UShort* classTable_length_p, - FT_UShort* stateArray_length_p, - FT_UShort* entryTable_length_p, - GXV_Validator valid ) - { - FT_UShort o[4]; - FT_UShort *l[4]; - FT_UShort buff[5]; - - GXV_kern_fmt1_StateOptRecData optdata = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; - - - o[0] = classTable; - o[1] = stateArray; - o[2] = entryTable; - o[3] = optdata->valueTable; - l[0] = classTable_length_p; - l[1] = stateArray_length_p; - l[2] = entryTable_length_p; - l[3] = &(optdata->valueTable_length); - - gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid ); - } - - - /* - * passed table & limit are of whole StateTable, not including subtables - */ - static void - gxv_kern_subtable_fmt1_entry_validate( - FT_Byte state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort push; - FT_UShort dontAdvance; -#endif - FT_UShort valueOffset; -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort kernAction; - FT_UShort kernValue; -#endif - - FT_UNUSED( state ); - FT_UNUSED( glyphOffset_p ); - - -#ifdef GXV_LOAD_UNUSED_VARS - push = (FT_UShort)( ( flags >> 15 ) & 1 ); - dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); -#endif - valueOffset = (FT_UShort)( flags & 0x3FFF ); - - { - GXV_kern_fmt1_StateOptRecData vt_rec = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; - FT_Bytes p; - - - if ( valueOffset < vt_rec->valueTable ) - FT_INVALID_OFFSET; - - p = table + valueOffset; - limit = table + vt_rec->valueTable + vt_rec->valueTable_length; - - GXV_LIMIT_CHECK( 2 + 2 ); -#ifdef GXV_LOAD_UNUSED_VARS - kernAction = FT_NEXT_USHORT( p ); - kernValue = FT_NEXT_USHORT( p ); -#endif - } - } - - - static void - gxv_kern_subtable_fmt1_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - GXV_kern_fmt1_StateOptRec vt_rec; - - - GXV_NAME_ENTER( "kern subtable format 1" ); - - valid->statetable.optdata = - &vt_rec; - valid->statetable.optdata_load_func = - gxv_kern_subtable_fmt1_valueTable_load; - valid->statetable.subtable_setup_func = - gxv_kern_subtable_fmt1_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = - GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = - gxv_kern_subtable_fmt1_entry_validate; - - gxv_StateTable_validate( p, limit, valid ); - - GXV_EXIT; - } - - - /* ================ Data for Class-Based Subtables 2, 3 ================ */ - - typedef enum GXV_kern_ClassSpec_ - { - GXV_KERN_CLS_L = 0, - GXV_KERN_CLS_R - - } GXV_kern_ClassSpec; - - - /* ============================= format 2 ============================== */ - - /* ---------------------- format 2 specific data ----------------------- */ - - typedef struct GXV_kern_subtable_fmt2_DataRec_ - { - FT_UShort rowWidth; - FT_UShort array; - FT_UShort offset_min[2]; - FT_UShort offset_max[2]; - const FT_String* class_tag[2]; - GXV_odtect_Range odtect; - - } GXV_kern_subtable_fmt2_DataRec, *GXV_kern_subtable_fmt2_Data; - - -#define GXV_KERN_FMT2_DATA( field ) \ - ( ( (GXV_kern_subtable_fmt2_DataRec *) \ - ( GXV_KERN_DATA( subtable_data ) ) )->field ) - - - /* -------------------------- utility functions ----------------------- */ - - static void - gxv_kern_subtable_fmt2_clstbl_validate( FT_Bytes table, - FT_Bytes limit, - GXV_kern_ClassSpec spec, - GXV_Validator valid ) - { - const FT_String* tag = GXV_KERN_FMT2_DATA( class_tag[spec] ); - GXV_odtect_Range odtect = GXV_KERN_FMT2_DATA( odtect ); - - FT_Bytes p = table; - FT_UShort firstGlyph; - FT_UShort nGlyphs; - - - GXV_NAME_ENTER( "kern format 2 classTable" ); - - GXV_LIMIT_CHECK( 2 + 2 ); - firstGlyph = FT_NEXT_USHORT( p ); - nGlyphs = FT_NEXT_USHORT( p ); - GXV_TRACE(( " %s firstGlyph=%d, nGlyphs=%d\n", - tag, firstGlyph, nGlyphs )); - - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs - 1 ), valid ); - - gxv_array_getlimits_ushort( p, p + ( 2 * nGlyphs ), - &( GXV_KERN_FMT2_DATA( offset_min[spec] ) ), - &( GXV_KERN_FMT2_DATA( offset_max[spec] ) ), - valid ); - - gxv_odtect_add_range( table, 2 * nGlyphs, tag, odtect ); - - GXV_EXIT; - } - - - static void - gxv_kern_subtable_fmt2_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - GXV_ODTECT( 3, odtect ); - GXV_kern_subtable_fmt2_DataRec fmt2_rec = - { 0, 0, { 0, 0 }, { 0, 0 }, { "leftClass", "rightClass" }, NULL }; - - FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; - FT_UShort leftOffsetTable; - FT_UShort rightOffsetTable; - - - GXV_NAME_ENTER( "kern subtable format 2" ); - - GXV_ODTECT_INIT( odtect ); - fmt2_rec.odtect = odtect; - GXV_KERN_DATA( subtable_data ) = &fmt2_rec; - - GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); - GXV_KERN_FMT2_DATA( rowWidth ) = FT_NEXT_USHORT( p ); - leftOffsetTable = FT_NEXT_USHORT( p ); - rightOffsetTable = FT_NEXT_USHORT( p ); - GXV_KERN_FMT2_DATA( array ) = FT_NEXT_USHORT( p ); - - GXV_TRACE(( "rowWidth = %d\n", GXV_KERN_FMT2_DATA( rowWidth ) )); - - - GXV_LIMIT_CHECK( leftOffsetTable ); - GXV_LIMIT_CHECK( rightOffsetTable ); - GXV_LIMIT_CHECK( GXV_KERN_FMT2_DATA( array ) ); - - gxv_kern_subtable_fmt2_clstbl_validate( table + leftOffsetTable, limit, - GXV_KERN_CLS_L, valid ); - - gxv_kern_subtable_fmt2_clstbl_validate( table + rightOffsetTable, limit, - GXV_KERN_CLS_R, valid ); - - if ( GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_L] ) + - GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_R] ) - < GXV_KERN_FMT2_DATA( array ) ) - FT_INVALID_OFFSET; - - gxv_odtect_add_range( table + GXV_KERN_FMT2_DATA( array ), - GXV_KERN_FMT2_DATA( offset_max[GXV_KERN_CLS_L] ) - + GXV_KERN_FMT2_DATA( offset_max[GXV_KERN_CLS_R] ) - - GXV_KERN_FMT2_DATA( array ), - "array", odtect ); - - gxv_odtect_validate( odtect, valid ); - - GXV_EXIT; - } - - - /* ============================= format 3 ============================== */ - - static void - gxv_kern_subtable_fmt3_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; - FT_UShort glyphCount; - FT_Byte kernValueCount; - FT_Byte leftClassCount; - FT_Byte rightClassCount; - FT_Byte flags; - - - GXV_NAME_ENTER( "kern subtable format 3" ); - - GXV_LIMIT_CHECK( 2 + 1 + 1 + 1 + 1 ); - glyphCount = FT_NEXT_USHORT( p ); - kernValueCount = FT_NEXT_BYTE( p ); - leftClassCount = FT_NEXT_BYTE( p ); - rightClassCount = FT_NEXT_BYTE( p ); - flags = FT_NEXT_BYTE( p ); - - if ( valid->face->num_glyphs != glyphCount ) - { - GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n", - valid->face->num_glyphs, glyphCount )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - - if ( flags != 0 ) - GXV_TRACE(( "kern subtable fmt3 has nonzero value" - " (%d) in unused flag\n", flags )); - /* - * just skip kernValue[kernValueCount] - */ - GXV_LIMIT_CHECK( 2 * kernValueCount ); - p += 2 * kernValueCount; - - /* - * check leftClass[gid] < leftClassCount - */ - { - FT_Byte min, max; - - - GXV_LIMIT_CHECK( glyphCount ); - gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid ); - p += valid->subtable_length; - - if ( leftClassCount < max ) - FT_INVALID_DATA; - } - - /* - * check rightClass[gid] < rightClassCount - */ - { - FT_Byte min, max; - - - GXV_LIMIT_CHECK( glyphCount ); - gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid ); - p += valid->subtable_length; - - if ( rightClassCount < max ) - FT_INVALID_DATA; - } - - /* - * check kernIndex[i, j] < kernValueCount - */ - { - FT_UShort i, j; - - - for ( i = 0; i < leftClassCount; i++ ) - { - for ( j = 0; j < rightClassCount; j++ ) - { - GXV_LIMIT_CHECK( 1 ); - if ( kernValueCount < FT_NEXT_BYTE( p ) ) - FT_INVALID_OFFSET; - } - } - } - - valid->subtable_length = p - table; - - GXV_EXIT; - } - - - static FT_Bool - gxv_kern_coverage_new_apple_validate( FT_UShort coverage, - FT_UShort* format, - GXV_Validator valid ) - { - /* new Apple-dialect */ -#ifdef GXV_LOAD_TRACE_VARS - FT_Bool kernVertical; - FT_Bool kernCrossStream; - FT_Bool kernVariation; -#endif - - FT_UNUSED( valid ); - - - /* reserved bits = 0 */ - if ( coverage & 0x1FFC ) - return FALSE; - -#ifdef GXV_LOAD_TRACE_VARS - kernVertical = FT_BOOL( ( coverage >> 15 ) & 1 ); - kernCrossStream = FT_BOOL( ( coverage >> 14 ) & 1 ); - kernVariation = FT_BOOL( ( coverage >> 13 ) & 1 ); -#endif - - *format = (FT_UShort)( coverage & 0x0003 ); - - GXV_TRACE(( "new Apple-dialect: " - "horizontal=%d, cross-stream=%d, variation=%d, format=%d\n", - !kernVertical, kernCrossStream, kernVariation, *format )); - - GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" )); - - return TRUE; - } - - - static FT_Bool - gxv_kern_coverage_classic_apple_validate( FT_UShort coverage, - FT_UShort* format, - GXV_Validator valid ) - { - /* classic Apple-dialect */ -#ifdef GXV_LOAD_TRACE_VARS - FT_Bool horizontal; - FT_Bool cross_stream; -#endif - - - /* check expected flags, but don't check if MS-dialect is impossible */ - if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( valid ) ) - return FALSE; - - /* reserved bits = 0 */ - if ( coverage & 0x02FC ) - return FALSE; - -#ifdef GXV_LOAD_TRACE_VARS - horizontal = FT_BOOL( ( coverage >> 15 ) & 1 ); - cross_stream = FT_BOOL( ( coverage >> 13 ) & 1 ); -#endif - - *format = (FT_UShort)( coverage & 0x0003 ); - - GXV_TRACE(( "classic Apple-dialect: " - "horizontal=%d, cross-stream=%d, format=%d\n", - horizontal, cross_stream, *format )); - - /* format 1 requires GX State Machine, too new for classic */ - if ( *format == 1 ) - return FALSE; - - GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" )); - - return TRUE; - } - - - static FT_Bool - gxv_kern_coverage_classic_microsoft_validate( FT_UShort coverage, - FT_UShort* format, - GXV_Validator valid ) - { - /* classic Microsoft-dialect */ -#ifdef GXV_LOAD_TRACE_VARS - FT_Bool horizontal; - FT_Bool minimum; - FT_Bool cross_stream; - FT_Bool override; -#endif - - FT_UNUSED( valid ); - - - /* reserved bits = 0 */ - if ( coverage & 0xFDF0 ) - return FALSE; - -#ifdef GXV_LOAD_TRACE_VARS - horizontal = FT_BOOL( coverage & 1 ); - minimum = FT_BOOL( ( coverage >> 1 ) & 1 ); - cross_stream = FT_BOOL( ( coverage >> 2 ) & 1 ); - override = FT_BOOL( ( coverage >> 3 ) & 1 ); -#endif - - *format = (FT_UShort)( ( coverage >> 8 ) & 0x0003 ); - - GXV_TRACE(( "classic Microsoft-dialect: " - "horizontal=%d, minimum=%d, cross-stream=%d, " - "override=%d, format=%d\n", - horizontal, minimum, cross_stream, override, *format )); - - if ( *format == 2 ) - GXV_TRACE(( - "kerning values in Microsoft format 2 subtable are ignored\n" )); - - return TRUE; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MAIN *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static GXV_kern_Dialect - gxv_kern_coverage_validate( FT_UShort coverage, - FT_UShort* format, - GXV_Validator valid ) - { - GXV_kern_Dialect result = KERN_DIALECT_UNKNOWN; - - - GXV_NAME_ENTER( "validating coverage" ); - - GXV_TRACE(( "interprete coverage 0x%04x by Apple style\n", coverage )); - - if ( KERN_IS_NEW( valid ) ) - { - if ( gxv_kern_coverage_new_apple_validate( coverage, - format, - valid ) ) - { - result = KERN_DIALECT_APPLE; - goto Exit; - } - } - - if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_APPLE( valid ) ) - { - if ( gxv_kern_coverage_classic_apple_validate( coverage, - format, - valid ) ) - { - result = KERN_DIALECT_APPLE; - goto Exit; - } - } - - if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_MS( valid ) ) - { - if ( gxv_kern_coverage_classic_microsoft_validate( coverage, - format, - valid ) ) - { - result = KERN_DIALECT_MS; - goto Exit; - } - } - - GXV_TRACE(( "cannot interprete coverage, broken kern subtable\n" )); - - Exit: - GXV_EXIT; - return result; - } - - - static void - gxv_kern_subtable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; -#ifdef GXV_LOAD_TRACE_VARS - FT_UShort version = 0; /* MS only: subtable version, unused */ -#endif - FT_ULong length; /* MS: 16bit, Apple: 32bit*/ - FT_UShort coverage; -#ifdef GXV_LOAD_TRACE_VARS - FT_UShort tupleIndex = 0; /* Apple only */ -#endif - FT_UShort u16[2]; - FT_UShort format = 255; /* subtable format */ - - - GXV_NAME_ENTER( "kern subtable" ); - - GXV_LIMIT_CHECK( 2 + 2 + 2 ); - u16[0] = FT_NEXT_USHORT( p ); /* Apple: length_hi MS: version */ - u16[1] = FT_NEXT_USHORT( p ); /* Apple: length_lo MS: length */ - coverage = FT_NEXT_USHORT( p ); - - switch ( gxv_kern_coverage_validate( coverage, &format, valid ) ) - { - case KERN_DIALECT_MS: -#ifdef GXV_LOAD_TRACE_VARS - version = u16[0]; -#endif - length = u16[1]; -#ifdef GXV_LOAD_TRACE_VARS - tupleIndex = 0; -#endif - GXV_TRACE(( "Subtable version = %d\n", version )); - GXV_TRACE(( "Subtable length = %d\n", length )); - break; - - case KERN_DIALECT_APPLE: -#ifdef GXV_LOAD_TRACE_VARS - version = 0; -#endif - length = ( u16[0] << 16 ) + u16[1]; -#ifdef GXV_LOAD_TRACE_VARS - tupleIndex = 0; -#endif - GXV_TRACE(( "Subtable length = %d\n", length )); - - if ( KERN_IS_NEW( valid ) ) - { - GXV_LIMIT_CHECK( 2 ); -#ifdef GXV_LOAD_TRACE_VARS - tupleIndex = FT_NEXT_USHORT( p ); -#else - p += 2; -#endif - GXV_TRACE(( "Subtable tupleIndex = %d\n", tupleIndex )); - } - break; - - default: - length = u16[1]; - GXV_TRACE(( "cannot detect subtable dialect, " - "just skip %d byte\n", length )); - goto Exit; - } - - /* formats 1, 2, 3 require the position of the start of this subtable */ - if ( format == 0 ) - gxv_kern_subtable_fmt0_validate( table, table + length, valid ); - else if ( format == 1 ) - gxv_kern_subtable_fmt1_validate( table, table + length, valid ); - else if ( format == 2 ) - gxv_kern_subtable_fmt2_validate( table, table + length, valid ); - else if ( format == 3 ) - gxv_kern_subtable_fmt3_validate( table, table + length, valid ); - else - FT_INVALID_DATA; - - Exit: - valid->subtable_length = length; - GXV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** kern TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - gxv_kern_validate_generic( FT_Bytes table, - FT_Face face, - FT_Bool classic_only, - GXV_kern_Dialect dialect_request, - FT_Validator ftvalid ) - { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - - GXV_kern_DataRec kernrec; - GXV_kern_Data kern = &kernrec; - - FT_Bytes p = table; - FT_Bytes limit = 0; - - FT_ULong nTables = 0; - FT_UInt i; - - - valid->root = ftvalid; - valid->table_data = kern; - valid->face = face; - - FT_TRACE3(( "validating `kern' table\n" )); - GXV_INIT; - KERN_DIALECT( valid ) = dialect_request; - - GXV_LIMIT_CHECK( 2 ); - GXV_KERN_DATA( version ) = (GXV_kern_Version)FT_NEXT_USHORT( p ); - GXV_TRACE(( "version 0x%04x (higher 16bit)\n", - GXV_KERN_DATA( version ) )); - - if ( 0x0001 < GXV_KERN_DATA( version ) ) - FT_INVALID_FORMAT; - else if ( KERN_IS_CLASSIC( valid ) ) - { - GXV_LIMIT_CHECK( 2 ); - nTables = FT_NEXT_USHORT( p ); - } - else if ( KERN_IS_NEW( valid ) ) - { - if ( classic_only ) - FT_INVALID_FORMAT; - - if ( 0x0000 != FT_NEXT_USHORT( p ) ) - FT_INVALID_FORMAT; - - GXV_LIMIT_CHECK( 4 ); - nTables = FT_NEXT_ULONG( p ); - } - - for ( i = 0; i < nTables; i++ ) - { - GXV_TRACE(( "validating subtable %d/%d\n", i, nTables )); - /* p should be 32bit-aligned? */ - gxv_kern_subtable_validate( p, 0, valid ); - p += valid->subtable_length; - } - - FT_TRACE4(( "\n" )); - } - - - FT_LOCAL_DEF( void ) - gxv_kern_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - gxv_kern_validate_generic( table, face, 0, KERN_DIALECT_ANY, ftvalid ); - } - - - FT_LOCAL_DEF( void ) - gxv_kern_validate_classic( FT_Bytes table, - FT_Face face, - FT_Int dialect_flags, - FT_Validator ftvalid ) - { - GXV_kern_Dialect dialect_request; - - - dialect_request = (GXV_kern_Dialect)dialect_flags; - gxv_kern_validate_generic( table, face, 1, dialect_request, ftvalid ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvlcar.c b/drivers/freetype/freetype/src/gxvalid/gxvlcar.c deleted file mode 100644 index f14fa5b131..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvlcar.c +++ /dev/null @@ -1,223 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvlcar.c */ -/* */ -/* TrueTypeGX/AAT lcar table validation (body). */ -/* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvalid.h" -#include "gxvcommn.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_gxvlcar - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Data and Types *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct GXV_lcar_DataRec_ - { - FT_UShort format; - - } GXV_lcar_DataRec, *GXV_lcar_Data; - - -#define GXV_LCAR_DATA( FIELD ) GXV_TABLE_DATA( lcar, FIELD ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - gxv_lcar_partial_validate( FT_UShort partial, - FT_UShort glyph, - GXV_Validator valid ) - { - GXV_NAME_ENTER( "partial" ); - - if ( GXV_LCAR_DATA( format ) != 1 ) - goto Exit; - - gxv_ctlPoint_validate( glyph, partial, valid ); - - Exit: - GXV_EXIT; - } - - - static void - gxv_lcar_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - FT_Bytes p = valid->root->base + value_p->u; - FT_Bytes limit = valid->root->limit; - FT_UShort count; - FT_Short partial; - FT_UShort i; - - - GXV_NAME_ENTER( "element in lookupTable" ); - - GXV_LIMIT_CHECK( 2 ); - count = FT_NEXT_USHORT( p ); - - GXV_LIMIT_CHECK( 2 * count ); - for ( i = 0; i < count; i++ ) - { - partial = FT_NEXT_SHORT( p ); - gxv_lcar_partial_validate( partial, glyph, valid ); - } - - GXV_EXIT; - } - - - /* - +------ lcar --------------------+ - | | - | +===============+ | - | | looup header | | - | +===============+ | - | | BinSrchHeader | | - | +===============+ | - | | lastGlyph[0] | | - | +---------------+ | - | | firstGlyph[0] | | head of lcar sfnt table - | +---------------+ | + - | | offset[0] | -> | offset [byte] - | +===============+ | + - | | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] - | +---------------+ | - | | firstGlyph[1] | | - | +---------------+ | - | | offset[1] | | - | +===============+ | - | | - | .... | - | | - | 16bit value array | - | +===============+ | - +------| value | <-------+ - | .... - | - | - | - | - | - +----> lcar values...handled by lcar callback function - */ - - static GXV_LookupValueDesc - gxv_lcar_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueCPtr base_value_p, - FT_Bytes lookuptbl_limit, - GXV_Validator valid ) - { - FT_Bytes p; - FT_Bytes limit; - FT_UShort offset; - GXV_LookupValueDesc value; - - FT_UNUSED( lookuptbl_limit ); - - /* XXX: check range? */ - offset = (FT_UShort)( base_value_p->u + - relative_gindex * sizeof ( FT_UShort ) ); - p = valid->root->base + offset; - limit = valid->root->limit; - - GXV_LIMIT_CHECK ( 2 ); - value.u = FT_NEXT_USHORT( p ); - - return value; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** lcar TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - gxv_lcar_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - FT_Bytes p = table; - FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - - GXV_lcar_DataRec lcarrec; - GXV_lcar_Data lcar = &lcarrec; - - FT_Fixed version; - - - valid->root = ftvalid; - valid->table_data = lcar; - valid->face = face; - - FT_TRACE3(( "validating `lcar' table\n" )); - GXV_INIT; - - GXV_LIMIT_CHECK( 4 + 2 ); - version = FT_NEXT_ULONG( p ); - GXV_LCAR_DATA( format ) = FT_NEXT_USHORT( p ); - - if ( version != 0x00010000UL) - FT_INVALID_FORMAT; - - if ( GXV_LCAR_DATA( format ) > 1 ) - FT_INVALID_FORMAT; - - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_lcar_LookupValue_validate; - valid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmod.c b/drivers/freetype/freetype/src/gxvalid/gxvmod.c deleted file mode 100644 index 278d47688a..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmod.c +++ /dev/null @@ -1,285 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmod.c */ -/* */ -/* FreeType's TrueTypeGX/AAT validation module implementation (body). */ -/* */ -/* Copyright 2004-2006, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_TRUETYPE_TABLES_H -#include FT_TRUETYPE_TAGS_H -#include FT_GX_VALIDATE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_GX_VALIDATE_H - -#include "gxvmod.h" -#include "gxvalid.h" -#include "gxvcommn.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_gxvmodule - - - static FT_Error - gxv_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 ); - - - error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); - if ( FT_ERR_EQ( error, Table_Missing ) ) - return FT_Err_Ok; - if ( error ) - goto Exit; - - if ( FT_ALLOC( *table, *table_len ) ) - goto Exit; - - error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); - - Exit: - return error; - } - - -#define GXV_TABLE_DECL( _sfnt ) \ - FT_Byte* volatile _sfnt = NULL; \ - FT_ULong len_ ## _sfnt = 0 - -#define GXV_TABLE_LOAD( _sfnt ) \ - if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \ - ( gx_flags & FT_VALIDATE_ ## _sfnt ) ) \ - { \ - error = gxv_load_table( face, TTAG_ ## _sfnt, \ - &_sfnt, &len_ ## _sfnt ); \ - if ( error ) \ - goto Exit; \ - } - -#define GXV_TABLE_VALIDATE( _sfnt ) \ - if ( _sfnt ) \ - { \ - ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \ - FT_VALIDATE_DEFAULT ); \ - if ( ft_setjmp( valid.jump_buffer ) == 0 ) \ - gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \ - error = valid.error; \ - if ( error ) \ - goto Exit; \ - } - -#define GXV_TABLE_SET( _sfnt ) \ - if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) \ - tables[FT_VALIDATE_ ## _sfnt ## _INDEX] = (FT_Bytes)_sfnt - - - static FT_Error - gxv_validate( FT_Face face, - FT_UInt gx_flags, - FT_Bytes tables[FT_VALIDATE_GX_LENGTH], - FT_UInt table_count ) - { - FT_Memory volatile memory = FT_FACE_MEMORY( face ); - - FT_Error error = FT_Err_Ok; - FT_ValidatorRec volatile valid; - - FT_UInt i; - - - GXV_TABLE_DECL( feat ); - GXV_TABLE_DECL( bsln ); - GXV_TABLE_DECL( trak ); - GXV_TABLE_DECL( just ); - GXV_TABLE_DECL( mort ); - GXV_TABLE_DECL( morx ); - GXV_TABLE_DECL( kern ); - GXV_TABLE_DECL( opbd ); - GXV_TABLE_DECL( prop ); - GXV_TABLE_DECL( lcar ); - - for ( i = 0; i < table_count; i++ ) - tables[i] = 0; - - /* load tables */ - GXV_TABLE_LOAD( feat ); - GXV_TABLE_LOAD( bsln ); - GXV_TABLE_LOAD( trak ); - GXV_TABLE_LOAD( just ); - GXV_TABLE_LOAD( mort ); - GXV_TABLE_LOAD( morx ); - GXV_TABLE_LOAD( kern ); - GXV_TABLE_LOAD( opbd ); - GXV_TABLE_LOAD( prop ); - GXV_TABLE_LOAD( lcar ); - - /* validate tables */ - GXV_TABLE_VALIDATE( feat ); - GXV_TABLE_VALIDATE( bsln ); - GXV_TABLE_VALIDATE( trak ); - GXV_TABLE_VALIDATE( just ); - GXV_TABLE_VALIDATE( mort ); - GXV_TABLE_VALIDATE( morx ); - GXV_TABLE_VALIDATE( kern ); - GXV_TABLE_VALIDATE( opbd ); - GXV_TABLE_VALIDATE( prop ); - GXV_TABLE_VALIDATE( lcar ); - - /* Set results */ - GXV_TABLE_SET( feat ); - GXV_TABLE_SET( mort ); - GXV_TABLE_SET( morx ); - GXV_TABLE_SET( bsln ); - GXV_TABLE_SET( just ); - GXV_TABLE_SET( kern ); - GXV_TABLE_SET( opbd ); - GXV_TABLE_SET( trak ); - GXV_TABLE_SET( prop ); - GXV_TABLE_SET( lcar ); - - Exit: - if ( error ) - { - FT_FREE( feat ); - FT_FREE( bsln ); - FT_FREE( trak ); - FT_FREE( just ); - FT_FREE( mort ); - FT_FREE( morx ); - FT_FREE( kern ); - FT_FREE( opbd ); - FT_FREE( prop ); - FT_FREE( lcar ); - } - - return error; - } - - - static FT_Error - classic_kern_validate( FT_Face face, - FT_UInt ckern_flags, - FT_Bytes* ckern_table ) - { - FT_Memory volatile memory = FT_FACE_MEMORY( face ); - - FT_Byte* volatile ckern = NULL; - FT_ULong len_ckern = 0; - - /* without volatile on `error' GCC 4.1.1. emits: */ - /* warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */ - /* this warning seems spurious but --- */ - FT_Error volatile error; - FT_ValidatorRec volatile valid; - - - *ckern_table = NULL; - - error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern ); - if ( error ) - goto Exit; - - if ( ckern ) - { - ft_validator_init( &valid, ckern, ckern + len_ckern, - FT_VALIDATE_DEFAULT ); - if ( ft_setjmp( valid.jump_buffer ) == 0 ) - gxv_kern_validate_classic( ckern, face, - ckern_flags & FT_VALIDATE_CKERN, &valid ); - error = valid.error; - if ( error ) - goto Exit; - } - - *ckern_table = ckern; - - Exit: - if ( error ) - FT_FREE( ckern ); - - return error; - } - - - static - const FT_Service_GXvalidateRec gxvalid_interface = - { - gxv_validate - }; - - - static - const FT_Service_CKERNvalidateRec ckernvalid_interface = - { - classic_kern_validate - }; - - - static - const FT_ServiceDescRec gxvalid_services[] = - { - { FT_SERVICE_ID_GX_VALIDATE, &gxvalid_interface }, - { FT_SERVICE_ID_CLASSICKERN_VALIDATE, &ckernvalid_interface }, - { NULL, NULL } - }; - - - static FT_Pointer - gxvalid_get_service( FT_Module module, - const char* service_id ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( gxvalid_services, service_id ); - } - - - FT_CALLBACK_TABLE_DEF - const FT_Module_Class gxv_module_class = - { - 0, - sizeof ( FT_ModuleRec ), - "gxvalid", - 0x10000L, - 0x20000L, - - 0, /* module-specific interface */ - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) gxvalid_get_service - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmod.h b/drivers/freetype/freetype/src/gxvalid/gxvmod.h deleted file mode 100644 index 22732ba992..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmod.h +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmod.h */ -/* */ -/* FreeType's TrueTypeGX/AAT validation module implementation */ -/* (specification). */ -/* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#ifndef __GXVMOD_H__ -#define __GXVMOD_H__ - -#include <ft2build.h> -#include FT_MODULE_H - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - - FT_EXPORT_VAR( const FT_Module_Class ) gxv_module_class; - - -FT_END_HEADER - -#endif /* __GXVMOD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort.c b/drivers/freetype/freetype/src/gxvalid/gxvmort.c deleted file mode 100644 index 5356e67ca7..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort.c +++ /dev/null @@ -1,297 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmort.c */ -/* */ -/* TrueTypeGX/AAT mort table validation (body). */ -/* */ -/* Copyright 2005, 2013 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmort.h" -#include "gxvfeat.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_gxvmort - - - static void - gxv_mort_feature_validate( GXV_mort_feature f, - GXV_Validator valid ) - { - if ( f->featureType >= gxv_feat_registry_length ) - { - GXV_TRACE(( "featureType %d is out of registered range, " - "setting %d is unchecked\n", - f->featureType, f->featureSetting )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - else if ( !gxv_feat_registry[f->featureType].existence ) - { - GXV_TRACE(( "featureType %d is within registered area " - "but undefined, setting %d is unchecked\n", - f->featureType, f->featureSetting )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - else - { - FT_Byte nSettings_max; - - - /* nSettings in gxvfeat.c is halved for exclusive on/off settings */ - nSettings_max = gxv_feat_registry[f->featureType].nSettings; - if ( gxv_feat_registry[f->featureType].exclusive ) - nSettings_max = (FT_Byte)( 2 * nSettings_max ); - - GXV_TRACE(( "featureType %d is registered", f->featureType )); - GXV_TRACE(( "setting %d", f->featureSetting )); - - if ( f->featureSetting > nSettings_max ) - { - GXV_TRACE(( "out of defined range %d", nSettings_max )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - GXV_TRACE(( "\n" )); - } - - /* TODO: enableFlags must be unique value in specified chain? */ - } - - - /* - * nFeatureFlags is typed to FT_ULong to accept that in - * mort (typed FT_UShort) and morx (typed FT_ULong). - */ - FT_LOCAL_DEF( void ) - gxv_mort_featurearray_validate( FT_Bytes table, - FT_Bytes limit, - FT_ULong nFeatureFlags, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_ULong i; - - GXV_mort_featureRec f = GXV_MORT_FEATURE_OFF; - - - GXV_NAME_ENTER( "mort feature list" ); - for ( i = 0; i < nFeatureFlags; i++ ) - { - GXV_LIMIT_CHECK( 2 + 2 + 4 + 4 ); - f.featureType = FT_NEXT_USHORT( p ); - f.featureSetting = FT_NEXT_USHORT( p ); - f.enableFlags = FT_NEXT_ULONG( p ); - f.disableFlags = FT_NEXT_ULONG( p ); - - gxv_mort_feature_validate( &f, valid ); - } - - if ( !IS_GXV_MORT_FEATURE_OFF( f ) ) - FT_INVALID_DATA; - - valid->subtable_length = p - table; - GXV_EXIT; - } - - - FT_LOCAL_DEF( void ) - gxv_mort_coverage_validate( FT_UShort coverage, - GXV_Validator valid ) - { - FT_UNUSED( valid ); - - if ( coverage & 0x8000U ) - GXV_TRACE(( " this subtable is for vertical text only\n" )); - else - GXV_TRACE(( " this subtable is for horizontal text only\n" )); - - if ( coverage & 0x4000 ) - GXV_TRACE(( " this subtable is applied to glyph array " - "in descending order\n" )); - else - GXV_TRACE(( " this subtable is applied to glyph array " - "in ascending order\n" )); - - if ( coverage & 0x2000 ) - GXV_TRACE(( " this subtable is forcibly applied to " - "vertical/horizontal text\n" )); - - if ( coverage & 0x1FF8 ) - GXV_TRACE(( " coverage has non-zero bits in reserved area\n" )); - } - - - static void - gxv_mort_subtables_validate( FT_Bytes table, - FT_Bytes limit, - FT_UShort nSubtables, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_Validate_Func fmt_funcs_table[] = - { - gxv_mort_subtable_type0_validate, /* 0 */ - gxv_mort_subtable_type1_validate, /* 1 */ - gxv_mort_subtable_type2_validate, /* 2 */ - NULL, /* 3 */ - gxv_mort_subtable_type4_validate, /* 4 */ - gxv_mort_subtable_type5_validate, /* 5 */ - - }; - - FT_UShort i; - - - GXV_NAME_ENTER( "subtables in a chain" ); - - for ( i = 0; i < nSubtables; i++ ) - { - GXV_Validate_Func func; - - FT_UShort length; - FT_UShort coverage; -#ifdef GXV_LOAD_UNUSED_VARS - FT_ULong subFeatureFlags; -#endif - FT_UInt type; - FT_UInt rest; - - - GXV_LIMIT_CHECK( 2 + 2 + 4 ); - length = FT_NEXT_USHORT( p ); - coverage = FT_NEXT_USHORT( p ); -#ifdef GXV_LOAD_UNUSED_VARS - subFeatureFlags = FT_NEXT_ULONG( p ); -#else - p += 4; -#endif - - GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", - i + 1, nSubtables, length )); - type = coverage & 0x0007; - rest = length - ( 2 + 2 + 4 ); - - GXV_LIMIT_CHECK( rest ); - gxv_mort_coverage_validate( coverage, valid ); - - if ( type > 5 ) - FT_INVALID_FORMAT; - - func = fmt_funcs_table[type]; - if ( func == NULL ) - GXV_TRACE(( "morx type %d is reserved\n", type )); - - func( p, p + rest, valid ); - - p += rest; - /* TODO: validate subFeatureFlags */ - } - - valid->subtable_length = p - table; - - GXV_EXIT; - } - - - static void - gxv_mort_chain_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; -#ifdef GXV_LOAD_UNUSED_VARS - FT_ULong defaultFlags; -#endif - FT_ULong chainLength; - FT_UShort nFeatureFlags; - FT_UShort nSubtables; - - - GXV_NAME_ENTER( "mort chain header" ); - - GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); -#ifdef GXV_LOAD_UNUSED_VARS - defaultFlags = FT_NEXT_ULONG( p ); -#else - p += 4; -#endif - chainLength = FT_NEXT_ULONG( p ); - nFeatureFlags = FT_NEXT_USHORT( p ); - nSubtables = FT_NEXT_USHORT( p ); - - gxv_mort_featurearray_validate( p, table + chainLength, - nFeatureFlags, valid ); - p += valid->subtable_length; - gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid ); - valid->subtable_length = chainLength; - - /* TODO: validate defaultFlags */ - GXV_EXIT; - } - - - FT_LOCAL_DEF( void ) - gxv_mort_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - FT_Bytes p = table; - FT_Bytes limit = 0; - FT_ULong version; - FT_ULong nChains; - FT_ULong i; - - - valid->root = ftvalid; - valid->face = face; - limit = valid->root->limit; - - FT_TRACE3(( "validating `mort' table\n" )); - GXV_INIT; - - GXV_LIMIT_CHECK( 4 + 4 ); - version = FT_NEXT_ULONG( p ); - nChains = FT_NEXT_ULONG( p ); - - if (version != 0x00010000UL) - FT_INVALID_FORMAT; - - for ( i = 0; i < nChains; i++ ) - { - GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); - GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); - gxv_mort_chain_validate( p, limit, valid ); - p += valid->subtable_length; - } - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort.h b/drivers/freetype/freetype/src/gxvalid/gxvmort.h deleted file mode 100644 index 1e5a1f5ab6..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort.h +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmort.h */ -/* */ -/* TrueTypeGX/AAT common definition for mort table (specification). */ -/* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#ifndef __GXVMORT_H__ -#define __GXVMORT_H__ - -#include "gxvalid.h" -#include "gxvcommn.h" - -#include FT_SFNT_NAMES_H - - - typedef struct GXV_mort_featureRec_ - { - FT_UShort featureType; - FT_UShort featureSetting; - FT_ULong enableFlags; - FT_ULong disableFlags; - - } GXV_mort_featureRec, *GXV_mort_feature; - -#define GXV_MORT_FEATURE_OFF {0, 1, 0x00000000UL, 0x00000000UL} - -#define IS_GXV_MORT_FEATURE_OFF( f ) \ - ( (f).featureType == 0 || \ - (f).featureSetting == 1 || \ - (f).enableFlags == 0x00000000UL || \ - (f).disableFlags == 0x00000000UL ) - - - FT_LOCAL( void ) - gxv_mort_featurearray_validate( FT_Bytes table, - FT_Bytes limit, - FT_ULong nFeatureFlags, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_mort_coverage_validate( FT_UShort coverage, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_mort_subtable_type0_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_mort_subtable_type1_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_mort_subtable_type2_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_mort_subtable_type4_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_mort_subtable_type5_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - -#endif /* __GXVMORT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort0.c b/drivers/freetype/freetype/src/gxvalid/gxvmort0.c deleted file mode 100644 index b136ceda27..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort0.c +++ /dev/null @@ -1,151 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmort0.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type0 (Indic Script Rearrangement) subtable. */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmort.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_gxvmort - - - static const char* GXV_Mort_IndicScript_Msg[] = - { - "no change", - "Ax => xA", - "xD => Dx", - "AxD => DxA", - "ABx => xAB", - "ABx => xBA", - "xCD => CDx", - "xCD => DCx", - "AxCD => CDxA", - "AxCD => DCxA", - "ABxD => DxAB", - "ABxD => DxBA", - "ABxCD => CDxAB", - "ABxCD => CDxBA", - "ABxCD => DCxAB", - "ABxCD => DCxBA", - - }; - - - static void - gxv_mort_subtable_type0_entry_validate( - FT_Byte state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_UShort markFirst; - FT_UShort dontAdvance; - FT_UShort markLast; - FT_UShort reserved; - FT_UShort verb = 0; - - FT_UNUSED( state ); - FT_UNUSED( table ); - FT_UNUSED( limit ); - - FT_UNUSED( GXV_Mort_IndicScript_Msg[verb] ); /* for the non-debugging */ - FT_UNUSED( glyphOffset_p ); /* case */ - - - markFirst = (FT_UShort)( ( flags >> 15 ) & 1 ); - dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); - markLast = (FT_UShort)( ( flags >> 13 ) & 1 ); - - reserved = (FT_UShort)( flags & 0x1FF0 ); - verb = (FT_UShort)( flags & 0x000F ); - - GXV_TRACE(( " IndicScript MorphRule for glyphOffset 0x%04x", - glyphOffset_p->u )); - GXV_TRACE(( " markFirst=%01d", markFirst )); - GXV_TRACE(( " dontAdvance=%01d", dontAdvance )); - GXV_TRACE(( " markLast=%01d", markLast )); - GXV_TRACE(( " %02d", verb )); - GXV_TRACE(( " %s\n", GXV_Mort_IndicScript_Msg[verb] )); - - if ( markFirst > 0 && markLast > 0 ) - { - GXV_TRACE(( " [odd] a glyph is marked as the first and last" - " in Indic rearrangement\n" )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - - if ( markFirst > 0 && dontAdvance > 0 ) - { - GXV_TRACE(( " [odd] the first glyph is marked as dontAdvance" - " in Indic rearrangement\n" )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - - if ( 0 < reserved ) - { - GXV_TRACE(( " non-zero bits found in reserved range\n" )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - else - GXV_TRACE(( "\n" )); - } - - - FT_LOCAL_DEF( void ) - gxv_mort_subtable_type0_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - GXV_NAME_ENTER( - "mort chain subtable type0 (Indic-Script Rearrangement)" ); - - GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); - - valid->statetable.optdata = NULL; - valid->statetable.optdata_load_func = NULL; - valid->statetable.subtable_setup_func = NULL; - valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = - gxv_mort_subtable_type0_entry_validate; - - gxv_StateTable_validate( p, limit, valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort1.c b/drivers/freetype/freetype/src/gxvalid/gxvmort1.c deleted file mode 100644 index 1c17a5d92a..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort1.c +++ /dev/null @@ -1,259 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmort1.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type1 (Contextual Substitution) subtable. */ -/* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmort.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_gxvmort - - - typedef struct GXV_mort_subtable_type1_StateOptRec_ - { - FT_UShort substitutionTable; - FT_UShort substitutionTable_length; - - } GXV_mort_subtable_type1_StateOptRec, - *GXV_mort_subtable_type1_StateOptRecData; - -#define GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE \ - ( GXV_STATETABLE_HEADER_SIZE + 2 ) - - - static void - gxv_mort_subtable_type1_substitutionTable_load( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_mort_subtable_type1_StateOptRecData optdata = - (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata; - - - GXV_LIMIT_CHECK( 2 ); - optdata->substitutionTable = FT_NEXT_USHORT( p ); - } - - - static void - gxv_mort_subtable_type1_subtable_setup( FT_UShort table_size, - FT_UShort classTable, - FT_UShort stateArray, - FT_UShort entryTable, - FT_UShort* classTable_length_p, - FT_UShort* stateArray_length_p, - FT_UShort* entryTable_length_p, - GXV_Validator valid ) - { - FT_UShort o[4]; - FT_UShort *l[4]; - FT_UShort buff[5]; - - GXV_mort_subtable_type1_StateOptRecData optdata = - (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata; - - - o[0] = classTable; - o[1] = stateArray; - o[2] = entryTable; - o[3] = optdata->substitutionTable; - l[0] = classTable_length_p; - l[1] = stateArray_length_p; - l[2] = entryTable_length_p; - l[3] = &( optdata->substitutionTable_length ); - - gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid ); - } - - - static void - gxv_mort_subtable_type1_offset_to_subst_validate( - FT_Short wordOffset, - const FT_String* tag, - FT_Byte state, - GXV_Validator valid ) - { - FT_UShort substTable; - FT_UShort substTable_limit; - - FT_UNUSED( tag ); - FT_UNUSED( state ); - - - substTable = - ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable; - substTable_limit = - (FT_UShort)( substTable + - ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable_length ); - - valid->min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 ); - valid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 ); - valid->max_gid = (FT_UShort)( FT_MAX( valid->max_gid, - valid->face->num_glyphs ) ); - - /* XXX: check range? */ - - /* TODO: min_gid & max_gid comparison with ClassTable contents */ - } - - - static void - gxv_mort_subtable_type1_entry_validate( - FT_Byte state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort setMark; - FT_UShort dontAdvance; -#endif - FT_UShort reserved; - FT_Short markOffset; - FT_Short currentOffset; - - FT_UNUSED( table ); - FT_UNUSED( limit ); - - -#ifdef GXV_LOAD_UNUSED_VARS - setMark = (FT_UShort)( flags >> 15 ); - dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); -#endif - reserved = (FT_Short)( flags & 0x3FFF ); - - markOffset = (FT_Short)( glyphOffset_p->ul >> 16 ); - currentOffset = (FT_Short)( glyphOffset_p->ul ); - - if ( 0 < reserved ) - { - GXV_TRACE(( " non-zero bits found in reserved range\n" )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - - gxv_mort_subtable_type1_offset_to_subst_validate( markOffset, - "markOffset", - state, - valid ); - - gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset, - "currentOffset", - state, - valid ); - } - - - static void - gxv_mort_subtable_type1_substTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort num_gids = (FT_UShort)( - ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable_length / 2 ); - FT_UShort i; - - - GXV_NAME_ENTER( "validating contents of substitutionTable" ); - for ( i = 0; i < num_gids ; i ++ ) - { - FT_UShort dst_gid; - - - GXV_LIMIT_CHECK( 2 ); - dst_gid = FT_NEXT_USHORT( p ); - - if ( dst_gid >= 0xFFFFU ) - continue; - - if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid ) - { - GXV_TRACE(( "substTable include a strange gid[%d]=%d >" - " out of define range (%d..%d)\n", - i, dst_gid, valid->min_gid, valid->max_gid )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - } - - GXV_EXIT; - } - - - /* - * subtable for Contextual glyph substitution is a modified StateTable. - * In addition to classTable, stateArray, and entryTable, the field - * `substitutionTable' is added. - */ - FT_LOCAL_DEF( void ) - gxv_mort_subtable_type1_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_mort_subtable_type1_StateOptRec st_rec; - - - GXV_NAME_ENTER( "mort chain subtable type1 (Contextual Glyph Subst)" ); - - GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE ); - - valid->statetable.optdata = - &st_rec; - valid->statetable.optdata_load_func = - gxv_mort_subtable_type1_substitutionTable_load; - valid->statetable.subtable_setup_func = - gxv_mort_subtable_type1_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = - GXV_GLYPHOFFSET_ULONG; - valid->statetable.entry_validate_func = - - gxv_mort_subtable_type1_entry_validate; - gxv_StateTable_validate( p, limit, valid ); - - gxv_mort_subtable_type1_substTable_validate( - table + st_rec.substitutionTable, - table + st_rec.substitutionTable + st_rec.substitutionTable_length, - valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort2.c b/drivers/freetype/freetype/src/gxvalid/gxvmort2.c deleted file mode 100644 index 9e08fb792a..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort2.c +++ /dev/null @@ -1,311 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmort2.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type2 (Ligature Substitution) subtable. */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmort.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_gxvmort - - - typedef struct GXV_mort_subtable_type2_StateOptRec_ - { - FT_UShort ligActionTable; - FT_UShort componentTable; - FT_UShort ligatureTable; - FT_UShort ligActionTable_length; - FT_UShort componentTable_length; - FT_UShort ligatureTable_length; - - } GXV_mort_subtable_type2_StateOptRec, - *GXV_mort_subtable_type2_StateOptRecData; - -#define GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE \ - ( GXV_STATETABLE_HEADER_SIZE + 2 + 2 + 2 ) - - - static void - gxv_mort_subtable_type2_opttable_load( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; - - - GXV_LIMIT_CHECK( 2 + 2 + 2 ); - optdata->ligActionTable = FT_NEXT_USHORT( p ); - optdata->componentTable = FT_NEXT_USHORT( p ); - optdata->ligatureTable = FT_NEXT_USHORT( p ); - - GXV_TRACE(( "offset to ligActionTable=0x%04x\n", - optdata->ligActionTable )); - GXV_TRACE(( "offset to componentTable=0x%04x\n", - optdata->componentTable )); - GXV_TRACE(( "offset to ligatureTable=0x%04x\n", - optdata->ligatureTable )); - } - - - static void - gxv_mort_subtable_type2_subtable_setup( FT_UShort table_size, - FT_UShort classTable, - FT_UShort stateArray, - FT_UShort entryTable, - FT_UShort *classTable_length_p, - FT_UShort *stateArray_length_p, - FT_UShort *entryTable_length_p, - GXV_Validator valid ) - { - FT_UShort o[6]; - FT_UShort *l[6]; - FT_UShort buff[7]; - - GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; - - - GXV_NAME_ENTER( "subtable boundaries setup" ); - - o[0] = classTable; - o[1] = stateArray; - o[2] = entryTable; - o[3] = optdata->ligActionTable; - o[4] = optdata->componentTable; - o[5] = optdata->ligatureTable; - l[0] = classTable_length_p; - l[1] = stateArray_length_p; - l[2] = entryTable_length_p; - l[3] = &(optdata->ligActionTable_length); - l[4] = &(optdata->componentTable_length); - l[5] = &(optdata->ligatureTable_length); - - gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, valid ); - - GXV_TRACE(( "classTable: offset=0x%04x length=0x%04x\n", - classTable, *classTable_length_p )); - GXV_TRACE(( "stateArray: offset=0x%04x length=0x%04x\n", - stateArray, *stateArray_length_p )); - GXV_TRACE(( "entryTable: offset=0x%04x length=0x%04x\n", - entryTable, *entryTable_length_p )); - GXV_TRACE(( "ligActionTable: offset=0x%04x length=0x%04x\n", - optdata->ligActionTable, - optdata->ligActionTable_length )); - GXV_TRACE(( "componentTable: offset=0x%04x length=0x%04x\n", - optdata->componentTable, - optdata->componentTable_length )); - GXV_TRACE(( "ligatureTable: offset=0x%04x length=0x%04x\n", - optdata->ligatureTable, - optdata->ligatureTable_length )); - - GXV_EXIT; - } - - - static void - gxv_mort_subtable_type2_ligActionOffset_validate( - FT_Bytes table, - FT_UShort ligActionOffset, - GXV_Validator valid ) - { - /* access ligActionTable */ - GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; - - FT_Bytes lat_base = table + optdata->ligActionTable; - FT_Bytes p = table + ligActionOffset; - FT_Bytes lat_limit = lat_base + optdata->ligActionTable; - - - GXV_32BIT_ALIGNMENT_VALIDATE( ligActionOffset ); - if ( p < lat_base ) - { - GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%d byte rewind)\n", - ligActionOffset, lat_base - p )); - - /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } - else if ( lat_limit < p ) - { - GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%d byte overrun)\n", - ligActionOffset, p - lat_limit )); - - /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } - else - { - /* validate entry in ligActionTable */ - FT_ULong lig_action; -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort last; - FT_UShort store; -#endif - FT_ULong offset; - - - lig_action = FT_NEXT_ULONG( p ); -#ifdef GXV_LOAD_UNUSED_VARS - last = (FT_UShort)( ( lig_action >> 31 ) & 1 ); - store = (FT_UShort)( ( lig_action >> 30 ) & 1 ); -#endif - - /* Apple spec defines this offset as a word offset */ - offset = lig_action & 0x3FFFFFFFUL; - if ( offset * 2 < optdata->ligatureTable ) - { - GXV_TRACE(( "too short offset 0x%08x:" - " 2 x offset < ligatureTable (%d byte rewind)\n", - offset, optdata->ligatureTable - offset * 2 )); - - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } else if ( offset * 2 > - optdata->ligatureTable + optdata->ligatureTable_length ) - { - GXV_TRACE(( "too long offset 0x%08x:" - " 2 x offset > ligatureTable + ligatureTable_length" - " (%d byte overrun)\n", - offset, - optdata->ligatureTable + optdata->ligatureTable_length - - offset * 2 )); - - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } - } - } - - - static void - gxv_mort_subtable_type2_entry_validate( - FT_Byte state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort setComponent; - FT_UShort dontAdvance; -#endif - FT_UShort offset; - - FT_UNUSED( state ); - FT_UNUSED( glyphOffset_p ); - FT_UNUSED( limit ); - - -#ifdef GXV_LOAD_UNUSED_VARS - setComponent = (FT_UShort)( ( flags >> 15 ) & 1 ); - dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); -#endif - - offset = (FT_UShort)( flags & 0x3FFFU ); - - if ( 0 < offset ) - gxv_mort_subtable_type2_ligActionOffset_validate( table, offset, - valid ); - } - - - static void - gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes table, - GXV_Validator valid ) - { - GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; - - FT_Bytes p = table + optdata->ligatureTable; - FT_Bytes limit = table + optdata->ligatureTable - + optdata->ligatureTable_length; - - - GXV_NAME_ENTER( "mort chain subtable type2 - substitutionTable" ); - if ( 0 != optdata->ligatureTable ) - { - /* Apple does not give specification of ligatureTable format */ - while ( p < limit ) - { - FT_UShort lig_gid; - - - GXV_LIMIT_CHECK( 2 ); - lig_gid = FT_NEXT_USHORT( p ); - - if ( valid->face->num_glyphs < lig_gid ) - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - } - GXV_EXIT; - } - - - FT_LOCAL_DEF( void ) - gxv_mort_subtable_type2_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_mort_subtable_type2_StateOptRec lig_rec; - - - GXV_NAME_ENTER( "mort chain subtable type2 (Ligature Substitution)" ); - - GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ); - - valid->statetable.optdata = - &lig_rec; - valid->statetable.optdata_load_func = - gxv_mort_subtable_type2_opttable_load; - valid->statetable.subtable_setup_func = - gxv_mort_subtable_type2_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = - GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = - gxv_mort_subtable_type2_entry_validate; - - gxv_StateTable_validate( p, limit, valid ); - - p += valid->subtable_length; - gxv_mort_subtable_type2_ligatureTable_validate( table, valid ); - - valid->subtable_length = p - table; - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort4.c b/drivers/freetype/freetype/src/gxvalid/gxvmort4.c deleted file mode 100644 index 83470988c0..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort4.c +++ /dev/null @@ -1,125 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmort4.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type4 (Non-Contextual Glyph Substitution) subtable. */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmort.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_gxvmort - - - static void - gxv_mort_subtable_type4_lookupval_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - FT_UNUSED( glyph ); - - gxv_glyphid_validate( value_p->u, valid ); - } - - /* - +===============+ --------+ - | lookup header | | - +===============+ | - | BinSrchHeader | | - +===============+ | - | lastGlyph[0] | | - +---------------+ | - | firstGlyph[0] | | head of lookup table - +---------------+ | + - | offset[0] | -> | offset [byte] - +===============+ | + - | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] - +---------------+ | - | firstGlyph[1] | | - +---------------+ | - | offset[1] | | - +===============+ | - | - .... | - | - 16bit value array | - +===============+ | - | value | <-------+ - .... - */ - - static GXV_LookupValueDesc - gxv_mort_subtable_type4_lookupfmt4_transit( - FT_UShort relative_gindex, - GXV_LookupValueCPtr base_value_p, - FT_Bytes lookuptbl_limit, - GXV_Validator valid ) - { - FT_Bytes p; - FT_Bytes limit; - FT_UShort offset; - GXV_LookupValueDesc value; - - /* XXX: check range? */ - offset = (FT_UShort)( base_value_p->u + - relative_gindex * sizeof ( FT_UShort ) ); - - p = valid->lookuptbl_head + offset; - limit = lookuptbl_limit; - - GXV_LIMIT_CHECK( 2 ); - value.u = FT_NEXT_USHORT( p ); - - return value; - } - - - FT_LOCAL_DEF( void ) - gxv_mort_subtable_type4_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - GXV_NAME_ENTER( "mort chain subtable type4 " - "(Non-Contextual Glyph Substitution)" ); - - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_mort_subtable_type4_lookupval_validate; - valid->lookupfmt4_trans = gxv_mort_subtable_type4_lookupfmt4_transit; - - gxv_LookupTable_validate( p, limit, valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort5.c b/drivers/freetype/freetype/src/gxvalid/gxvmort5.c deleted file mode 100644 index 32cfb03639..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort5.c +++ /dev/null @@ -1,233 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmort5.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type5 (Contextual Glyph Insertion) subtable. */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmort.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_gxvmort - - - /* - * mort subtable type5 (Contextual Glyph Insertion) - * has the format of StateTable with insertion-glyph-list, - * but without name. The offset is given by glyphOffset in - * entryTable. There is no table location declaration - * like xxxTable. - */ - - typedef struct GXV_mort_subtable_type5_StateOptRec_ - { - FT_UShort classTable; - FT_UShort stateArray; - FT_UShort entryTable; - -#define GXV_MORT_SUBTABLE_TYPE5_HEADER_SIZE GXV_STATETABLE_HEADER_SIZE - - FT_UShort* classTable_length_p; - FT_UShort* stateArray_length_p; - FT_UShort* entryTable_length_p; - - } GXV_mort_subtable_type5_StateOptRec, - *GXV_mort_subtable_type5_StateOptRecData; - - - FT_LOCAL_DEF( void ) - gxv_mort_subtable_type5_subtable_setup( FT_UShort table_size, - FT_UShort classTable, - FT_UShort stateArray, - FT_UShort entryTable, - FT_UShort* classTable_length_p, - FT_UShort* stateArray_length_p, - FT_UShort* entryTable_length_p, - GXV_Validator valid ) - { - GXV_mort_subtable_type5_StateOptRecData optdata = - (GXV_mort_subtable_type5_StateOptRecData)valid->statetable.optdata; - - - gxv_StateTable_subtable_setup( table_size, - classTable, - stateArray, - entryTable, - classTable_length_p, - stateArray_length_p, - entryTable_length_p, - valid ); - - optdata->classTable = classTable; - optdata->stateArray = stateArray; - optdata->entryTable = entryTable; - - optdata->classTable_length_p = classTable_length_p; - optdata->stateArray_length_p = stateArray_length_p; - optdata->entryTable_length_p = entryTable_length_p; - } - - - static void - gxv_mort_subtable_type5_InsertList_validate( FT_UShort offset, - FT_UShort count, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - /* - * We don't know the range of insertion-glyph-list. - * Set range by whole of state table. - */ - FT_Bytes p = table + offset; - - GXV_mort_subtable_type5_StateOptRecData optdata = - (GXV_mort_subtable_type5_StateOptRecData)valid->statetable.optdata; - - if ( optdata->classTable < offset && - offset < optdata->classTable + *(optdata->classTable_length_p) ) - GXV_TRACE(( " offset runs into ClassTable" )); - if ( optdata->stateArray < offset && - offset < optdata->stateArray + *(optdata->stateArray_length_p) ) - GXV_TRACE(( " offset runs into StateArray" )); - if ( optdata->entryTable < offset && - offset < optdata->entryTable + *(optdata->entryTable_length_p) ) - GXV_TRACE(( " offset runs into EntryTable" )); - -#ifndef GXV_LOAD_TRACE_VARS - GXV_LIMIT_CHECK( count * 2 ); -#else - while ( p < table + offset + ( count * 2 ) ) - { - FT_UShort insert_glyphID; - - - GXV_LIMIT_CHECK( 2 ); - insert_glyphID = FT_NEXT_USHORT( p ); - GXV_TRACE(( " 0x%04x", insert_glyphID )); - } - GXV_TRACE(( "\n" )); -#endif - } - - - static void - gxv_mort_subtable_type5_entry_validate( - FT_Byte state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_UNUSED_VARS - FT_Bool setMark; - FT_Bool dontAdvance; - FT_Bool currentIsKashidaLike; - FT_Bool markedIsKashidaLike; - FT_Bool currentInsertBefore; - FT_Bool markedInsertBefore; -#endif - FT_Byte currentInsertCount; - FT_Byte markedInsertCount; - FT_UShort currentInsertList; - FT_UShort markedInsertList; - - FT_UNUSED( state ); - - -#ifdef GXV_LOAD_UNUSED_VARS - setMark = FT_BOOL( ( flags >> 15 ) & 1 ); - dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 ); - currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 ); - markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 ); - currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 ); - markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 ); -#endif - - currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); - markedInsertCount = (FT_Byte)( flags & 0x001F ); - - currentInsertList = (FT_UShort)( glyphOffset->ul >> 16 ); - markedInsertList = (FT_UShort)( glyphOffset->ul ); - - if ( 0 != currentInsertList && 0 != currentInsertCount ) - { - gxv_mort_subtable_type5_InsertList_validate( currentInsertList, - currentInsertCount, - table, - limit, - valid ); - } - - if ( 0 != markedInsertList && 0 != markedInsertCount ) - { - gxv_mort_subtable_type5_InsertList_validate( markedInsertList, - markedInsertCount, - table, - limit, - valid ); - } - } - - - FT_LOCAL_DEF( void ) - gxv_mort_subtable_type5_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_mort_subtable_type5_StateOptRec et_rec; - GXV_mort_subtable_type5_StateOptRecData et = &et_rec; - - - GXV_NAME_ENTER( "mort chain subtable type5 (Glyph Insertion)" ); - - GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE5_HEADER_SIZE ); - - valid->statetable.optdata = - et; - valid->statetable.optdata_load_func = - NULL; - valid->statetable.subtable_setup_func = - gxv_mort_subtable_type5_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = - GXV_GLYPHOFFSET_ULONG; - valid->statetable.entry_validate_func = - gxv_mort_subtable_type5_entry_validate; - - gxv_StateTable_validate( p, limit, valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx.c b/drivers/freetype/freetype/src/gxvalid/gxvmorx.c deleted file mode 100644 index 5ae04d3212..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx.c +++ /dev/null @@ -1,199 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmorx.c */ -/* */ -/* TrueTypeGX/AAT morx table validation (body). */ -/* */ -/* Copyright 2005, 2008, 2013 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmorx.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_gxvmorx - - - static void - gxv_morx_subtables_validate( FT_Bytes table, - FT_Bytes limit, - FT_UShort nSubtables, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_Validate_Func fmt_funcs_table[] = - { - gxv_morx_subtable_type0_validate, /* 0 */ - gxv_morx_subtable_type1_validate, /* 1 */ - gxv_morx_subtable_type2_validate, /* 2 */ - NULL, /* 3 */ - gxv_morx_subtable_type4_validate, /* 4 */ - gxv_morx_subtable_type5_validate, /* 5 */ - - }; - - FT_UShort i; - - - GXV_NAME_ENTER( "subtables in a chain" ); - - for ( i = 0; i < nSubtables; i++ ) - { - GXV_Validate_Func func; - - FT_ULong length; - FT_ULong coverage; -#ifdef GXV_LOAD_UNUSED_VARS - FT_ULong subFeatureFlags; -#endif - FT_ULong type; - FT_ULong rest; - - - GXV_LIMIT_CHECK( 4 + 4 + 4 ); - length = FT_NEXT_ULONG( p ); - coverage = FT_NEXT_ULONG( p ); -#ifdef GXV_LOAD_UNUSED_VARS - subFeatureFlags = FT_NEXT_ULONG( p ); -#else - p += 4; -#endif - - GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", - i + 1, nSubtables, length )); - - type = coverage & 0x0007; - rest = length - ( 4 + 4 + 4 ); - GXV_LIMIT_CHECK( rest ); - - /* morx coverage consists of mort_coverage & 16bit padding */ - gxv_mort_coverage_validate( (FT_UShort)( ( coverage >> 16 ) | coverage ), - valid ); - if ( type > 5 ) - FT_INVALID_FORMAT; - - func = fmt_funcs_table[type]; - if ( func == NULL ) - GXV_TRACE(( "morx type %d is reserved\n", type )); - - func( p, p + rest, valid ); - - /* TODO: subFeatureFlags should be unique in a table? */ - p += rest; - } - - valid->subtable_length = p - table; - - GXV_EXIT; - } - - - static void - gxv_morx_chain_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; -#ifdef GXV_LOAD_UNUSED_VARS - FT_ULong defaultFlags; -#endif - FT_ULong chainLength; - FT_ULong nFeatureFlags; - FT_ULong nSubtables; - - - GXV_NAME_ENTER( "morx chain header" ); - - GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); -#ifdef GXV_LOAD_UNUSED_VARS - defaultFlags = FT_NEXT_ULONG( p ); -#else - p += 4; -#endif - chainLength = FT_NEXT_ULONG( p ); - nFeatureFlags = FT_NEXT_ULONG( p ); - nSubtables = FT_NEXT_ULONG( p ); - - /* feature-array of morx is same with that of mort */ - gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid ); - p += valid->subtable_length; - - if ( nSubtables >= 0x10000L ) - FT_INVALID_DATA; - - gxv_morx_subtables_validate( p, table + chainLength, - (FT_UShort)nSubtables, valid ); - - valid->subtable_length = chainLength; - - /* TODO: defaultFlags should be compared with the flags in tables */ - - GXV_EXIT; - } - - - FT_LOCAL_DEF( void ) - gxv_morx_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - FT_Bytes p = table; - FT_Bytes limit = 0; - FT_ULong version; - FT_ULong nChains; - FT_ULong i; - - - valid->root = ftvalid; - valid->face = face; - - FT_TRACE3(( "validating `morx' table\n" )); - GXV_INIT; - - GXV_LIMIT_CHECK( 4 + 4 ); - version = FT_NEXT_ULONG( p ); - nChains = FT_NEXT_ULONG( p ); - - if ( version != 0x00020000UL ) - FT_INVALID_FORMAT; - - for ( i = 0; i < nChains; i++ ) - { - GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); - GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); - gxv_morx_chain_validate( p, limit, valid ); - p += valid->subtable_length; - } - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx.h b/drivers/freetype/freetype/src/gxvalid/gxvmorx.h deleted file mode 100644 index 28c1a44f6f..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx.h +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmorx.h */ -/* */ -/* TrueTypeGX/AAT common definition for morx table (specification). */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#ifndef __GXVMORX_H__ -#define __GXVMORX_H__ - - -#include "gxvalid.h" -#include "gxvcommn.h" -#include "gxvmort.h" - -#include FT_SFNT_NAMES_H - - - FT_LOCAL( void ) - gxv_morx_subtable_type0_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_morx_subtable_type1_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_morx_subtable_type2_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_morx_subtable_type4_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - FT_LOCAL( void ) - gxv_morx_subtable_type5_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ); - - -#endif /* __GXVMORX_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx0.c b/drivers/freetype/freetype/src/gxvalid/gxvmorx0.c deleted file mode 100644 index 6a736c1775..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx0.c +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmorx0.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for type0 (Indic Script Rearrangement) subtable. */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmorx.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_gxvmorx - - - static void - gxv_morx_subtable_type0_entry_validate( - FT_UShort state, - FT_UShort flags, - GXV_XStateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort markFirst; - FT_UShort dontAdvance; - FT_UShort markLast; -#endif - FT_UShort reserved; -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort verb; -#endif - - FT_UNUSED( state ); - FT_UNUSED( glyphOffset_p ); - FT_UNUSED( table ); - FT_UNUSED( limit ); - - -#ifdef GXV_LOAD_UNUSED_VARS - markFirst = (FT_UShort)( ( flags >> 15 ) & 1 ); - dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); - markLast = (FT_UShort)( ( flags >> 13 ) & 1 ); -#endif - - reserved = (FT_UShort)( flags & 0x1FF0 ); -#ifdef GXV_LOAD_UNUSED_VARS - verb = (FT_UShort)( flags & 0x000F ); -#endif - - if ( 0 < reserved ) - { - GXV_TRACE(( " non-zero bits found in reserved range\n" )); - FT_INVALID_DATA; - } - } - - - FT_LOCAL_DEF( void ) - gxv_morx_subtable_type0_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - - GXV_NAME_ENTER( - "morx chain subtable type0 (Indic-Script Rearrangement)" ); - - GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); - - valid->xstatetable.optdata = NULL; - valid->xstatetable.optdata_load_func = NULL; - valid->xstatetable.subtable_setup_func = NULL; - valid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->xstatetable.entry_validate_func = - gxv_morx_subtable_type0_entry_validate; - - gxv_XStateTable_validate( p, limit, valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx1.c b/drivers/freetype/freetype/src/gxvalid/gxvmorx1.c deleted file mode 100644 index ce0009a16f..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx1.c +++ /dev/null @@ -1,277 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmorx1.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for type1 (Contextual Substitution) subtable. */ -/* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmorx.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_gxvmorx - - - typedef struct GXV_morx_subtable_type1_StateOptRec_ - { - FT_ULong substitutionTable; - FT_ULong substitutionTable_length; - FT_UShort substitutionTable_num_lookupTables; - - } GXV_morx_subtable_type1_StateOptRec, - *GXV_morx_subtable_type1_StateOptRecData; - - -#define GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE \ - ( GXV_STATETABLE_HEADER_SIZE + 2 ) - - - static void - gxv_morx_subtable_type1_substitutionTable_load( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; - - - GXV_LIMIT_CHECK( 2 ); - optdata->substitutionTable = FT_NEXT_USHORT( p ); - } - - - static void - gxv_morx_subtable_type1_subtable_setup( FT_ULong table_size, - FT_ULong classTable, - FT_ULong stateArray, - FT_ULong entryTable, - FT_ULong* classTable_length_p, - FT_ULong* stateArray_length_p, - FT_ULong* entryTable_length_p, - GXV_Validator valid ) - { - FT_ULong o[4]; - FT_ULong *l[4]; - FT_ULong buff[5]; - - GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; - - - o[0] = classTable; - o[1] = stateArray; - o[2] = entryTable; - o[3] = optdata->substitutionTable; - l[0] = classTable_length_p; - l[1] = stateArray_length_p; - l[2] = entryTable_length_p; - l[3] = &(optdata->substitutionTable_length); - - gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid ); - } - - - static void - gxv_morx_subtable_type1_entry_validate( - FT_UShort state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_TRACE_VARS - FT_UShort setMark; - FT_UShort dontAdvance; -#endif - FT_UShort reserved; - FT_Short markIndex; - FT_Short currentIndex; - - GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; - - FT_UNUSED( state ); - FT_UNUSED( table ); - FT_UNUSED( limit ); - - -#ifdef GXV_LOAD_TRACE_VARS - setMark = (FT_UShort)( ( flags >> 15 ) & 1 ); - dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); -#endif - - reserved = (FT_UShort)( flags & 0x3FFF ); - - markIndex = (FT_Short)( glyphOffset_p->ul >> 16 ); - currentIndex = (FT_Short)( glyphOffset_p->ul ); - - GXV_TRACE(( " setMark=%01d dontAdvance=%01d\n", - setMark, dontAdvance )); - - if ( 0 < reserved ) - { - GXV_TRACE(( " non-zero bits found in reserved range\n" )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); - } - - GXV_TRACE(( "markIndex = %d, currentIndex = %d\n", - markIndex, currentIndex )); - - if ( optdata->substitutionTable_num_lookupTables < markIndex + 1 ) - optdata->substitutionTable_num_lookupTables = - (FT_Short)( markIndex + 1 ); - - if ( optdata->substitutionTable_num_lookupTables < currentIndex + 1 ) - optdata->substitutionTable_num_lookupTables = - (FT_Short)( currentIndex + 1 ); - } - - - static void - gxv_morx_subtable_type1_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - FT_UNUSED( glyph ); /* for the non-debugging case */ - - GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u )); - - if ( value_p->u > valid->face->num_glyphs ) - FT_INVALID_GLYPH_ID; - } - - - static GXV_LookupValueDesc - gxv_morx_subtable_type1_LookupFmt4_transit( - FT_UShort relative_gindex, - GXV_LookupValueCPtr base_value_p, - FT_Bytes lookuptbl_limit, - GXV_Validator valid ) - { - FT_Bytes p; - FT_Bytes limit; - FT_UShort offset; - GXV_LookupValueDesc value; - - /* XXX: check range? */ - offset = (FT_UShort)( base_value_p->u + - relative_gindex * sizeof ( FT_UShort ) ); - - p = valid->lookuptbl_head + offset; - limit = lookuptbl_limit; - - GXV_LIMIT_CHECK ( 2 ); - value.u = FT_NEXT_USHORT( p ); - - return value; - } - - - /* - * TODO: length should be limit? - **/ - static void - gxv_morx_subtable_type1_substitutionTable_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort i; - - GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; - - - /* TODO: calculate offset/length for each lookupTables */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_morx_subtable_type1_LookupValue_validate; - valid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit; - - for ( i = 0; i < optdata->substitutionTable_num_lookupTables; i++ ) - { - FT_ULong offset; - - - GXV_LIMIT_CHECK( 4 ); - offset = FT_NEXT_ULONG( p ); - - gxv_LookupTable_validate( table + offset, limit, valid ); - } - - /* TODO: overlapping of lookupTables in substitutionTable */ - } - - - /* - * subtable for Contextual glyph substitution is a modified StateTable. - * In addition to classTable, stateArray, entryTable, the field - * `substitutionTable' is added. - */ - FT_LOCAL_DEF( void ) - gxv_morx_subtable_type1_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_morx_subtable_type1_StateOptRec st_rec; - - - GXV_NAME_ENTER( "morx chain subtable type1 (Contextual Glyph Subst)" ); - - GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE ); - - st_rec.substitutionTable_num_lookupTables = 0; - - valid->xstatetable.optdata = - &st_rec; - valid->xstatetable.optdata_load_func = - gxv_morx_subtable_type1_substitutionTable_load; - valid->xstatetable.subtable_setup_func = - gxv_morx_subtable_type1_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = - GXV_GLYPHOFFSET_ULONG; - valid->xstatetable.entry_validate_func = - gxv_morx_subtable_type1_entry_validate; - - gxv_XStateTable_validate( p, limit, valid ); - - gxv_morx_subtable_type1_substitutionTable_validate( - table + st_rec.substitutionTable, - table + st_rec.substitutionTable + st_rec.substitutionTable_length, - valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx2.c b/drivers/freetype/freetype/src/gxvalid/gxvmorx2.c deleted file mode 100644 index 9d2b0bc4af..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx2.c +++ /dev/null @@ -1,327 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmorx2.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for type2 (Ligature Substitution) subtable. */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmorx.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_gxvmorx - - - typedef struct GXV_morx_subtable_type2_StateOptRec_ - { - FT_ULong ligActionTable; - FT_ULong componentTable; - FT_ULong ligatureTable; - FT_ULong ligActionTable_length; - FT_ULong componentTable_length; - FT_ULong ligatureTable_length; - - } GXV_morx_subtable_type2_StateOptRec, - *GXV_morx_subtable_type2_StateOptRecData; - - -#define GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE \ - ( GXV_XSTATETABLE_HEADER_SIZE + 4 + 4 + 4 ) - - - static void - gxv_morx_subtable_type2_opttable_load( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; - - - GXV_LIMIT_CHECK( 4 + 4 + 4 ); - optdata->ligActionTable = FT_NEXT_ULONG( p ); - optdata->componentTable = FT_NEXT_ULONG( p ); - optdata->ligatureTable = FT_NEXT_ULONG( p ); - - GXV_TRACE(( "offset to ligActionTable=0x%08x\n", - optdata->ligActionTable )); - GXV_TRACE(( "offset to componentTable=0x%08x\n", - optdata->componentTable )); - GXV_TRACE(( "offset to ligatureTable=0x%08x\n", - optdata->ligatureTable )); - } - - - static void - gxv_morx_subtable_type2_subtable_setup( FT_ULong table_size, - FT_ULong classTable, - FT_ULong stateArray, - FT_ULong entryTable, - FT_ULong* classTable_length_p, - FT_ULong* stateArray_length_p, - FT_ULong* entryTable_length_p, - GXV_Validator valid ) - { - FT_ULong o[6]; - FT_ULong* l[6]; - FT_ULong buff[7]; - - GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; - - - GXV_NAME_ENTER( "subtable boundaries setup" ); - - o[0] = classTable; - o[1] = stateArray; - o[2] = entryTable; - o[3] = optdata->ligActionTable; - o[4] = optdata->componentTable; - o[5] = optdata->ligatureTable; - l[0] = classTable_length_p; - l[1] = stateArray_length_p; - l[2] = entryTable_length_p; - l[3] = &(optdata->ligActionTable_length); - l[4] = &(optdata->componentTable_length); - l[5] = &(optdata->ligatureTable_length); - - gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, valid ); - - GXV_TRACE(( "classTable: offset=0x%08x length=0x%08x\n", - classTable, *classTable_length_p )); - GXV_TRACE(( "stateArray: offset=0x%08x length=0x%08x\n", - stateArray, *stateArray_length_p )); - GXV_TRACE(( "entryTable: offset=0x%08x length=0x%08x\n", - entryTable, *entryTable_length_p )); - GXV_TRACE(( "ligActionTable: offset=0x%08x length=0x%08x\n", - optdata->ligActionTable, - optdata->ligActionTable_length )); - GXV_TRACE(( "componentTable: offset=0x%08x length=0x%08x\n", - optdata->componentTable, - optdata->componentTable_length )); - GXV_TRACE(( "ligatureTable: offset=0x%08x length=0x%08x\n", - optdata->ligatureTable, - optdata->ligatureTable_length )); - - GXV_EXIT; - } - - -#define GXV_MORX_LIGACTION_ENTRY_SIZE 4 - - - static void - gxv_morx_subtable_type2_ligActionIndex_validate( - FT_Bytes table, - FT_UShort ligActionIndex, - GXV_Validator valid ) - { - /* access ligActionTable */ - GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; - - FT_Bytes lat_base = table + optdata->ligActionTable; - FT_Bytes p = lat_base + - ligActionIndex * GXV_MORX_LIGACTION_ENTRY_SIZE; - FT_Bytes lat_limit = lat_base + optdata->ligActionTable; - - - if ( p < lat_base ) - { - GXV_TRACE(( "p < lat_base (%d byte rewind)\n", lat_base - p )); - FT_INVALID_OFFSET; - } - else if ( lat_limit < p ) - { - GXV_TRACE(( "lat_limit < p (%d byte overrun)\n", p - lat_limit )); - FT_INVALID_OFFSET; - } - - { - /* validate entry in ligActionTable */ - FT_ULong lig_action; -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort last; - FT_UShort store; -#endif - FT_ULong offset; - FT_Long gid_limit; - - - lig_action = FT_NEXT_ULONG( p ); -#ifdef GXV_LOAD_UNUSED_VARS - last = (FT_UShort)( ( lig_action >> 31 ) & 1 ); - store = (FT_UShort)( ( lig_action >> 30 ) & 1 ); -#endif - - offset = lig_action & 0x3FFFFFFFUL; - - /* this offset is 30-bit signed value to add to GID */ - /* it is different from the location offset in mort */ - if ( ( offset & 0x3FFF0000UL ) == 0x3FFF0000UL ) - { /* negative offset */ - gid_limit = valid->face->num_glyphs - ( offset & 0x0000FFFFUL ); - if ( gid_limit > 0 ) - return; - - GXV_TRACE(( "ligature action table includes" - " too negative offset moving all GID" - " below defined range: 0x%04x\n", - offset & 0xFFFFU )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } - else if ( ( offset & 0x3FFF0000UL ) == 0x0000000UL ) - { /* positive offset */ - if ( (FT_Long)offset < valid->face->num_glyphs ) - return; - - GXV_TRACE(( "ligature action table includes" - " too large offset moving all GID" - " over defined range: 0x%04x\n", - offset & 0xFFFFU )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } - - GXV_TRACE(( "ligature action table includes" - " invalid offset to add to 16-bit GID:" - " 0x%08x\n", offset )); - GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); - } - } - - - static void - gxv_morx_subtable_type2_entry_validate( - FT_UShort state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_UNUSED_VARS - FT_UShort setComponent; - FT_UShort dontAdvance; - FT_UShort performAction; -#endif - FT_UShort reserved; - FT_UShort ligActionIndex; - - FT_UNUSED( state ); - FT_UNUSED( limit ); - - -#ifdef GXV_LOAD_UNUSED_VARS - setComponent = (FT_UShort)( ( flags >> 15 ) & 1 ); - dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); - performAction = (FT_UShort)( ( flags >> 13 ) & 1 ); -#endif - - reserved = (FT_UShort)( flags & 0x1FFF ); - ligActionIndex = glyphOffset_p->u; - - if ( reserved > 0 ) - GXV_TRACE(( " reserved 14bit is non-zero\n" )); - - if ( 0 < ligActionIndex ) - gxv_morx_subtable_type2_ligActionIndex_validate( - table, ligActionIndex, valid ); - } - - - static void - gxv_morx_subtable_type2_ligatureTable_validate( FT_Bytes table, - GXV_Validator valid ) - { - GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; - - FT_Bytes p = table + optdata->ligatureTable; - FT_Bytes limit = table + optdata->ligatureTable - + optdata->ligatureTable_length; - - - GXV_NAME_ENTER( "morx chain subtable type2 - substitutionTable" ); - - if ( 0 != optdata->ligatureTable ) - { - /* Apple does not give specification of ligatureTable format */ - while ( p < limit ) - { - FT_UShort lig_gid; - - - GXV_LIMIT_CHECK( 2 ); - lig_gid = FT_NEXT_USHORT( p ); - if ( lig_gid < valid->face->num_glyphs ) - GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - } - } - - GXV_EXIT; - } - - - FT_LOCAL_DEF( void ) - gxv_morx_subtable_type2_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_morx_subtable_type2_StateOptRec lig_rec; - - - GXV_NAME_ENTER( "morx chain subtable type2 (Ligature Substitution)" ); - - GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE ); - - valid->xstatetable.optdata = - &lig_rec; - valid->xstatetable.optdata_load_func = - gxv_morx_subtable_type2_opttable_load; - valid->xstatetable.subtable_setup_func = - gxv_morx_subtable_type2_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = - GXV_GLYPHOFFSET_USHORT; - valid->xstatetable.entry_validate_func = - gxv_morx_subtable_type2_entry_validate; - - gxv_XStateTable_validate( p, limit, valid ); - - p += valid->subtable_length; - gxv_morx_subtable_type2_ligatureTable_validate( table, valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx4.c b/drivers/freetype/freetype/src/gxvalid/gxvmorx4.c deleted file mode 100644 index c0d2f78e39..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx4.c +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmorx4.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for "morx" type4 (Non-Contextual Glyph Substitution) subtable. */ -/* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmorx.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_gxvmorx - - - FT_LOCAL_DEF( void ) - gxv_morx_subtable_type4_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - GXV_NAME_ENTER( "morx chain subtable type4 " - "(Non-Contextual Glyph Substitution)" ); - - gxv_mort_subtable_type4_validate( table, limit, valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx5.c b/drivers/freetype/freetype/src/gxvalid/gxvmorx5.c deleted file mode 100644 index d8cf700797..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx5.c +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvmorx5.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for type5 (Contextual Glyph Insertion) subtable. */ -/* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvmorx.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_gxvmorx - - - /* - * `morx' subtable type5 (Contextual Glyph Insertion) - * has format of a StateTable with insertion-glyph-list - * without name. However, the 32bit offset from the head - * of subtable to the i-g-l is given after `entryTable', - * without variable name specification (the existence of - * this offset to the table is different from mort type5). - */ - - - typedef struct GXV_morx_subtable_type5_StateOptRec_ - { - FT_ULong insertionGlyphList; - FT_ULong insertionGlyphList_length; - - } GXV_morx_subtable_type5_StateOptRec, - *GXV_morx_subtable_type5_StateOptRecData; - - -#define GXV_MORX_SUBTABLE_TYPE5_HEADER_SIZE \ - ( GXV_STATETABLE_HEADER_SIZE + 4 ) - - - static void - gxv_morx_subtable_type5_insertionGlyphList_load( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_morx_subtable_type5_StateOptRecData optdata = - (GXV_morx_subtable_type5_StateOptRecData)valid->xstatetable.optdata; - - - GXV_LIMIT_CHECK( 4 ); - optdata->insertionGlyphList = FT_NEXT_ULONG( p ); - } - - - static void - gxv_morx_subtable_type5_subtable_setup( FT_ULong table_size, - FT_ULong classTable, - FT_ULong stateArray, - FT_ULong entryTable, - FT_ULong* classTable_length_p, - FT_ULong* stateArray_length_p, - FT_ULong* entryTable_length_p, - GXV_Validator valid ) - { - FT_ULong o[4]; - FT_ULong* l[4]; - FT_ULong buff[5]; - - GXV_morx_subtable_type5_StateOptRecData optdata = - (GXV_morx_subtable_type5_StateOptRecData)valid->xstatetable.optdata; - - - o[0] = classTable; - o[1] = stateArray; - o[2] = entryTable; - o[3] = optdata->insertionGlyphList; - l[0] = classTable_length_p; - l[1] = stateArray_length_p; - l[2] = entryTable_length_p; - l[3] = &(optdata->insertionGlyphList_length); - - gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid ); - } - - - static void - gxv_morx_subtable_type5_InsertList_validate( FT_UShort table_index, - FT_UShort count, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table + table_index * 2; - - -#ifndef GXV_LOAD_TRACE_VARS - GXV_LIMIT_CHECK( count * 2 ); -#else - while ( p < table + count * 2 + table_index * 2 ) - { - FT_UShort insert_glyphID; - - - GXV_LIMIT_CHECK( 2 ); - insert_glyphID = FT_NEXT_USHORT( p ); - GXV_TRACE(( " 0x%04x", insert_glyphID )); - } - - GXV_TRACE(( "\n" )); -#endif - } - - - static void - gxv_morx_subtable_type5_entry_validate( - FT_UShort state, - FT_UShort flags, - GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, - FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { -#ifdef GXV_LOAD_UNUSED_VARS - FT_Bool setMark; - FT_Bool dontAdvance; - FT_Bool currentIsKashidaLike; - FT_Bool markedIsKashidaLike; - FT_Bool currentInsertBefore; - FT_Bool markedInsertBefore; -#endif - FT_Byte currentInsertCount; - FT_Byte markedInsertCount; - FT_Byte currentInsertList; - FT_UShort markedInsertList; - - FT_UNUSED( state ); - - -#ifdef GXV_LOAD_UNUSED_VARS - setMark = FT_BOOL( ( flags >> 15 ) & 1 ); - dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 ); - currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 ); - markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 ); - currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 ); - markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 ); -#endif - - currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); - markedInsertCount = (FT_Byte)( flags & 0x001F ); - - currentInsertList = (FT_Byte) ( glyphOffset_p->ul >> 16 ); - markedInsertList = (FT_UShort)( glyphOffset_p->ul ); - - if ( currentInsertList && 0 != currentInsertCount ) - gxv_morx_subtable_type5_InsertList_validate( currentInsertList, - currentInsertCount, - table, limit, - valid ); - - if ( markedInsertList && 0 != markedInsertCount ) - gxv_morx_subtable_type5_InsertList_validate( markedInsertList, - markedInsertCount, - table, limit, - valid ); - } - - - FT_LOCAL_DEF( void ) - gxv_morx_subtable_type5_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - - GXV_morx_subtable_type5_StateOptRec et_rec; - GXV_morx_subtable_type5_StateOptRecData et = &et_rec; - - - GXV_NAME_ENTER( "morx chain subtable type5 (Glyph Insertion)" ); - - GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE5_HEADER_SIZE ); - - valid->xstatetable.optdata = - et; - valid->xstatetable.optdata_load_func = - gxv_morx_subtable_type5_insertionGlyphList_load; - valid->xstatetable.subtable_setup_func = - gxv_morx_subtable_type5_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = - GXV_GLYPHOFFSET_ULONG; - valid->xstatetable.entry_validate_func = - gxv_morx_subtable_type5_entry_validate; - - gxv_XStateTable_validate( p, limit, valid ); - - GXV_EXIT; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvopbd.c b/drivers/freetype/freetype/src/gxvalid/gxvopbd.c deleted file mode 100644 index e125060946..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvopbd.c +++ /dev/null @@ -1,217 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvopbd.c */ -/* */ -/* TrueTypeGX/AAT opbd table validation (body). */ -/* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvalid.h" -#include "gxvcommn.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_gxvopbd - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Data and Types *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct GXV_opbd_DataRec_ - { - FT_UShort format; - FT_UShort valueOffset_min; - - } GXV_opbd_DataRec, *GXV_opbd_Data; - - -#define GXV_OPBD_DATA( FIELD ) GXV_TABLE_DATA( opbd, FIELD ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - gxv_opbd_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - /* offset in LookupTable is measured from the head of opbd table */ - FT_Bytes p = valid->root->base + value_p->u; - FT_Bytes limit = valid->root->limit; - FT_Short delta_value; - int i; - - - if ( value_p->u < GXV_OPBD_DATA( valueOffset_min ) ) - GXV_OPBD_DATA( valueOffset_min ) = value_p->u; - - for ( i = 0; i < 4; i++ ) - { - GXV_LIMIT_CHECK( 2 ); - delta_value = FT_NEXT_SHORT( p ); - - if ( GXV_OPBD_DATA( format ) ) /* format 1, value is ctrl pt. */ - { - if ( delta_value == -1 ) - continue; - - gxv_ctlPoint_validate( glyph, delta_value, valid ); - } - else /* format 0, value is distance */ - continue; - } - } - - - /* - opbd ---------------------+ - | - +===============+ | - | lookup header | | - +===============+ | - | BinSrchHeader | | - +===============+ | - | lastGlyph[0] | | - +---------------+ | - | firstGlyph[0] | | head of opbd sfnt table - +---------------+ | + - | offset[0] | -> | offset [byte] - +===============+ | + - | lastGlyph[1] | | (glyphID - firstGlyph) * 4 * sizeof(FT_Short) [byte] - +---------------+ | - | firstGlyph[1] | | - +---------------+ | - | offset[1] | | - +===============+ | - | - .... | - | - 48bit value array | - +===============+ | - | value | <-------+ - | | - | | - | | - +---------------+ - .... */ - - static GXV_LookupValueDesc - gxv_opbd_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueCPtr base_value_p, - FT_Bytes lookuptbl_limit, - GXV_Validator valid ) - { - GXV_LookupValueDesc value; - - FT_UNUSED( lookuptbl_limit ); - FT_UNUSED( valid ); - - /* XXX: check range? */ - value.u = (FT_UShort)( base_value_p->u + - relative_gindex * 4 * sizeof ( FT_Short ) ); - - return value; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** opbd TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - gxv_opbd_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - GXV_opbd_DataRec opbdrec; - GXV_opbd_Data opbd = &opbdrec; - FT_Bytes p = table; - FT_Bytes limit = 0; - - FT_ULong version; - - - valid->root = ftvalid; - valid->table_data = opbd; - valid->face = face; - - FT_TRACE3(( "validating `opbd' table\n" )); - GXV_INIT; - GXV_OPBD_DATA( valueOffset_min ) = 0xFFFFU; - - - GXV_LIMIT_CHECK( 4 + 2 ); - version = FT_NEXT_ULONG( p ); - GXV_OPBD_DATA( format ) = FT_NEXT_USHORT( p ); - - - /* only 0x00010000 is defined (1996) */ - GXV_TRACE(( "(version=0x%08x)\n", version )); - if ( 0x00010000UL != version ) - FT_INVALID_FORMAT; - - /* only values 0 and 1 are defined (1996) */ - GXV_TRACE(( "(format=0x%04x)\n", GXV_OPBD_DATA( format ) )); - if ( 0x0001 < GXV_OPBD_DATA( format ) ) - FT_INVALID_FORMAT; - - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_opbd_LookupValue_validate; - valid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; - - gxv_LookupTable_validate( p, limit, valid ); - p += valid->subtable_length; - - if ( p > table + GXV_OPBD_DATA( valueOffset_min ) ) - { - GXV_TRACE(( - "found overlap between LookupTable and opbd_value array\n" )); - FT_INVALID_OFFSET; - } - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvprop.c b/drivers/freetype/freetype/src/gxvalid/gxvprop.c deleted file mode 100644 index 0be21336f8..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvprop.c +++ /dev/null @@ -1,329 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvprop.c */ -/* */ -/* TrueTypeGX/AAT prop table validation (body). */ -/* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvalid.h" -#include "gxvcommn.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_gxvprop - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Data and Types *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define GXV_PROP_HEADER_SIZE ( 4 + 2 + 2 ) -#define GXV_PROP_SIZE_MIN GXV_PROP_HEADER_SIZE - - typedef struct GXV_prop_DataRec_ - { - FT_Fixed version; - - } GXV_prop_DataRec, *GXV_prop_Data; - -#define GXV_PROP_DATA( field ) GXV_TABLE_DATA( prop, field ) - -#define GXV_PROP_FLOATER 0x8000U -#define GXV_PROP_USE_COMPLEMENTARY_BRACKET 0x1000U -#define GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET 0x0F00U -#define GXV_PROP_ATTACHING_TO_RIGHT 0x0080U -#define GXV_PROP_RESERVED 0x0060U -#define GXV_PROP_DIRECTIONALITY_CLASS 0x001FU - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - gxv_prop_zero_advance_validate( FT_UShort gid, - GXV_Validator valid ) - { - FT_Face face; - FT_Error error; - FT_GlyphSlot glyph; - - - GXV_NAME_ENTER( "zero advance" ); - - face = valid->face; - - error = FT_Load_Glyph( face, - gid, - FT_LOAD_IGNORE_TRANSFORM ); - if ( error ) - FT_INVALID_GLYPH_ID; - - glyph = face->glyph; - - if ( glyph->advance.x != (FT_Pos)0 || - glyph->advance.y != (FT_Pos)0 ) - { - GXV_TRACE(( " found non-zero advance in zero-advance glyph\n" )); - FT_INVALID_DATA; - } - - GXV_EXIT; - } - - - /* Pass 0 as GLYPH to check the default property */ - static void - gxv_prop_property_validate( FT_UShort property, - FT_UShort glyph, - GXV_Validator valid ) - { - if ( glyph != 0 && ( property & GXV_PROP_FLOATER ) ) - gxv_prop_zero_advance_validate( glyph, valid ); - - if ( property & GXV_PROP_USE_COMPLEMENTARY_BRACKET ) - { - FT_UShort offset; - char complement; - - - offset = (FT_UShort)( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET ); - if ( offset == 0 ) - { - GXV_TRACE(( " found zero offset to property\n" )); - FT_INVALID_OFFSET; - } - - complement = (char)( offset >> 8 ); - if ( complement & 0x08 ) - { - /* Top bit is set: negative */ - - /* Calculate the absolute offset */ - complement = (char)( ( complement & 0x07 ) + 1 ); - - /* The gid for complement must be greater than 0 */ - if ( glyph <= complement ) - { - GXV_TRACE(( " found non-positive glyph complement\n" )); - FT_INVALID_DATA; - } - } - else - { - /* The gid for complement must be the face. */ - gxv_glyphid_validate( (FT_UShort)( glyph + complement ), valid ); - } - } - else - { - if ( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET ) - GXV_TRACE(( "glyph %d cannot have complementary bracketing\n", - glyph )); - } - - /* this is introduced in version 2.0 */ - if ( property & GXV_PROP_ATTACHING_TO_RIGHT ) - { - if ( GXV_PROP_DATA( version ) == 0x00010000UL ) - { - GXV_TRACE(( " found older version (1.0) in new version table\n" )); - FT_INVALID_DATA; - } - } - - if ( property & GXV_PROP_RESERVED ) - { - GXV_TRACE(( " found non-zero bits in reserved bits\n" )); - FT_INVALID_DATA; - } - - if ( ( property & GXV_PROP_DIRECTIONALITY_CLASS ) > 11 ) - { - /* TODO: Too restricted. Use the validation level. */ - if ( GXV_PROP_DATA( version ) == 0x00010000UL || - GXV_PROP_DATA( version ) == 0x00020000UL ) - { - GXV_TRACE(( " found too old version in directionality class\n" )); - FT_INVALID_DATA; - } - } - } - - - static void - gxv_prop_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueCPtr value_p, - GXV_Validator valid ) - { - gxv_prop_property_validate( value_p->u, glyph, valid ); - } - - - /* - +===============+ --------+ - | lookup header | | - +===============+ | - | BinSrchHeader | | - +===============+ | - | lastGlyph[0] | | - +---------------+ | - | firstGlyph[0] | | head of lookup table - +---------------+ | + - | offset[0] | -> | offset [byte] - +===============+ | + - | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] - +---------------+ | - | firstGlyph[1] | | - +---------------+ | - | offset[1] | | - +===============+ | - | - ... | - | - 16bit value array | - +===============+ | - | value | <-------+ - ... - */ - - static GXV_LookupValueDesc - gxv_prop_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueCPtr base_value_p, - FT_Bytes lookuptbl_limit, - GXV_Validator valid ) - { - FT_Bytes p; - FT_Bytes limit; - FT_UShort offset; - GXV_LookupValueDesc value; - - /* XXX: check range? */ - offset = (FT_UShort)( base_value_p->u + - relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; - limit = lookuptbl_limit; - - GXV_LIMIT_CHECK ( 2 ); - value.u = FT_NEXT_USHORT( p ); - - return value; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** prop TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - gxv_prop_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - FT_Bytes p = table; - FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - - GXV_prop_DataRec proprec; - GXV_prop_Data prop = &proprec; - - FT_Fixed version; - FT_UShort format; - FT_UShort defaultProp; - - - valid->root = ftvalid; - valid->table_data = prop; - valid->face = face; - - FT_TRACE3(( "validating `prop' table\n" )); - GXV_INIT; - - GXV_LIMIT_CHECK( 4 + 2 + 2 ); - version = FT_NEXT_ULONG( p ); - format = FT_NEXT_USHORT( p ); - defaultProp = FT_NEXT_USHORT( p ); - - GXV_TRACE(( " version 0x%08x\n", version )); - GXV_TRACE(( " format 0x%04x\n", format )); - GXV_TRACE(( " defaultProp 0x%04x\n", defaultProp )); - - /* only versions 1.0, 2.0, 3.0 are defined (1996) */ - if ( version != 0x00010000UL && - version != 0x00020000UL && - version != 0x00030000UL ) - { - GXV_TRACE(( " found unknown version\n" )); - FT_INVALID_FORMAT; - } - - - /* only formats 0x0000, 0x0001 are defined (1996) */ - if ( format > 1 ) - { - GXV_TRACE(( " found unknown format\n" )); - FT_INVALID_FORMAT; - } - - gxv_prop_property_validate( defaultProp, 0, valid ); - - if ( format == 0 ) - { - FT_TRACE3(( "(format 0, no per-glyph properties, " - "remaining %d bytes are skipped)", limit - p )); - goto Exit; - } - - /* format == 1 */ - GXV_PROP_DATA( version ) = version; - - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_prop_LookupValue_validate; - valid->lookupfmt4_trans = gxv_prop_LookupFmt4_transit; - - gxv_LookupTable_validate( p, limit, valid ); - - Exit: - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvtrak.c b/drivers/freetype/freetype/src/gxvalid/gxvtrak.c deleted file mode 100644 index 11fbd7ccfb..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/gxvtrak.c +++ /dev/null @@ -1,286 +0,0 @@ -/***************************************************************************/ -/* */ -/* gxvtrak.c */ -/* */ -/* TrueTypeGX/AAT trak table validation (body). */ -/* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* 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. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - -#include "gxvalid.h" -#include "gxvcommn.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_gxvtrak - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Data and Types *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * referred track table format specification: - * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6trak.html - * last update was 1996. - * ---------------------------------------------- - * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN - * version (fixed: 32bit) = 0x00010000 - * format (uint16: 16bit) = 0 is only defined (1996) - * horizOffset (uint16: 16bit) - * vertOffset (uint16: 16bit) - * reserved (uint16: 16bit) = 0 - * ---------------------------------------------- - * [VARIABLE BODY]: - * horizData - * header ( 2 + 2 + 4 - * trackTable + nTracks * ( 4 + 2 + 2 ) - * sizeTable + nSizes * 4 ) - * ---------------------------------------------- - * vertData - * header ( 2 + 2 + 4 - * trackTable + nTracks * ( 4 + 2 + 2 ) - * sizeTable + nSizes * 4 ) - * ---------------------------------------------- - */ - typedef struct GXV_trak_DataRec_ - { - FT_UShort trackValueOffset_min; - FT_UShort trackValueOffset_max; - - } GXV_trak_DataRec, *GXV_trak_Data; - - -#define GXV_TRAK_DATA( FIELD ) GXV_TABLE_DATA( trak, FIELD ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - gxv_trak_trackTable_validate( FT_Bytes table, - FT_Bytes limit, - FT_UShort nTracks, - GXV_Validator valid ) - { - FT_Bytes p = table; - - FT_Fixed track, t; - FT_UShort nameIndex; - FT_UShort offset; - FT_UShort i, j; - - - GXV_NAME_ENTER( "trackTable" ); - - GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU; - GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000; - - GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) ); - - for ( i = 0; i < nTracks; i ++ ) - { - p = table + i * ( 4 + 2 + 2 ); - track = FT_NEXT_LONG( p ); - nameIndex = FT_NEXT_USHORT( p ); - offset = FT_NEXT_USHORT( p ); - - if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) ) - GXV_TRAK_DATA( trackValueOffset_min ) = offset; - if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) ) - GXV_TRAK_DATA( trackValueOffset_max ) = offset; - - gxv_sfntName_validate( nameIndex, 256, 32767, valid ); - - for ( j = i; j < nTracks; j ++ ) - { - p = table + j * ( 4 + 2 + 2 ); - t = FT_NEXT_LONG( p ); - if ( t == track ) - GXV_TRACE(( "duplicated entries found for track value 0x%x\n", - track )); - } - } - - valid->subtable_length = p - table; - GXV_EXIT; - } - - - static void - gxv_trak_trackData_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) - { - FT_Bytes p = table; - FT_UShort nTracks; - FT_UShort nSizes; - FT_ULong sizeTableOffset; - - GXV_ODTECT( 4, odtect ); - - - GXV_ODTECT_INIT( odtect ); - GXV_NAME_ENTER( "trackData" ); - - /* read the header of trackData */ - GXV_LIMIT_CHECK( 2 + 2 + 4 ); - nTracks = FT_NEXT_USHORT( p ); - nSizes = FT_NEXT_USHORT( p ); - sizeTableOffset = FT_NEXT_ULONG( p ); - - gxv_odtect_add_range( table, p - table, "trackData header", odtect ); - - /* validate trackTable */ - gxv_trak_trackTable_validate( p, limit, nTracks, valid ); - gxv_odtect_add_range( p, valid->subtable_length, - "trackTable", odtect ); - - /* sizeTable is array of FT_Fixed, don't check contents */ - p = valid->root->base + sizeTableOffset; - GXV_LIMIT_CHECK( nSizes * 4 ); - gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect ); - - /* validate trackValueOffet */ - p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min ); - if ( limit - p < nTracks * nSizes * 2 ) - GXV_TRACE(( "too short trackValue array\n" )); - - p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max ); - GXV_LIMIT_CHECK( nSizes * 2 ); - - gxv_odtect_add_range( valid->root->base - + GXV_TRAK_DATA( trackValueOffset_min ), - GXV_TRAK_DATA( trackValueOffset_max ) - - GXV_TRAK_DATA( trackValueOffset_min ) - + nSizes * 2, - "trackValue array", odtect ); - - gxv_odtect_validate( odtect, valid ); - - GXV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** trak TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - gxv_trak_validate( FT_Bytes table, - FT_Face face, - FT_Validator ftvalid ) - { - FT_Bytes p = table; - FT_Bytes limit = 0; - - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; - GXV_trak_DataRec trakrec; - GXV_trak_Data trak = &trakrec; - - FT_ULong version; - FT_UShort format; - FT_UShort horizOffset; - FT_UShort vertOffset; - FT_UShort reserved; - - - GXV_ODTECT( 3, odtect ); - - GXV_ODTECT_INIT( odtect ); - valid->root = ftvalid; - valid->table_data = trak; - valid->face = face; - - limit = valid->root->limit; - - FT_TRACE3(( "validating `trak' table\n" )); - GXV_INIT; - - GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 ); - version = FT_NEXT_ULONG( p ); - format = FT_NEXT_USHORT( p ); - horizOffset = FT_NEXT_USHORT( p ); - vertOffset = FT_NEXT_USHORT( p ); - reserved = FT_NEXT_USHORT( p ); - - GXV_TRACE(( " (version = 0x%08x)\n", version )); - GXV_TRACE(( " (format = 0x%04x)\n", format )); - GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset )); - GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset )); - GXV_TRACE(( " (reserved = 0x%04x)\n", reserved )); - - /* Version 1.0 (always:1996) */ - if ( version != 0x00010000UL ) - FT_INVALID_FORMAT; - - /* format 0 (always:1996) */ - if ( format != 0x0000 ) - FT_INVALID_FORMAT; - - GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset ); - GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset ); - - /* Reserved Fixed Value (always) */ - if ( reserved != 0x0000 ) - FT_INVALID_DATA; - - /* validate trackData */ - if ( 0 < horizOffset ) - { - gxv_trak_trackData_validate( table + horizOffset, limit, valid ); - gxv_odtect_add_range( table + horizOffset, valid->subtable_length, - "horizJustData", odtect ); - } - - if ( 0 < vertOffset ) - { - gxv_trak_trackData_validate( table + vertOffset, limit, valid ); - gxv_odtect_add_range( table + vertOffset, valid->subtable_length, - "vertJustData", odtect ); - } - - gxv_odtect_validate( odtect, valid ); - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/module.mk b/drivers/freetype/freetype/src/gxvalid/module.mk deleted file mode 100644 index 9fd098e2c5..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 gxvalid module definition -# - -# Copyright 2004, 2005, 2006 -# by suzuki toshiya, Masatake YAMATO, Red Hat K.K., -# 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. - - -FTMODULE_H_COMMANDS += GXVALID_MODULE - -define GXVALID_MODULE -$(OPEN_DRIVER) FT_Module_Class, gxv_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)gxvalid $(ECHO_DRIVER_DESC)TrueTypeGX/AAT validation module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/gxvalid/rules.mk b/drivers/freetype/freetype/src/gxvalid/rules.mk deleted file mode 100644 index 57bc0823db..0000000000 --- a/drivers/freetype/freetype/src/gxvalid/rules.mk +++ /dev/null @@ -1,94 +0,0 @@ -# -# FreeType 2 TrueTypeGX/AAT validation driver configuration rules -# - - -# Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., -# 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. - - -# GXV driver directory -# -GXV_DIR := $(SRC_DIR)/gxvalid - - -# compilation flags for the driver -# -GXV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(GXV_DIR)) - - -# GXV driver sources (i.e., C files) -# -GXV_DRV_SRC := $(GXV_DIR)/gxvcommn.c \ - $(GXV_DIR)/gxvfeat.c \ - $(GXV_DIR)/gxvbsln.c \ - $(GXV_DIR)/gxvtrak.c \ - $(GXV_DIR)/gxvopbd.c \ - $(GXV_DIR)/gxvprop.c \ - $(GXV_DIR)/gxvjust.c \ - $(GXV_DIR)/gxvmort.c \ - $(GXV_DIR)/gxvmort0.c \ - $(GXV_DIR)/gxvmort1.c \ - $(GXV_DIR)/gxvmort2.c \ - $(GXV_DIR)/gxvmort4.c \ - $(GXV_DIR)/gxvmort5.c \ - $(GXV_DIR)/gxvmorx.c \ - $(GXV_DIR)/gxvmorx0.c \ - $(GXV_DIR)/gxvmorx1.c \ - $(GXV_DIR)/gxvmorx2.c \ - $(GXV_DIR)/gxvmorx4.c \ - $(GXV_DIR)/gxvmorx5.c \ - $(GXV_DIR)/gxvlcar.c \ - $(GXV_DIR)/gxvkern.c \ - $(GXV_DIR)/gxvmod.c - -# GXV driver headers -# -GXV_DRV_H := $(GXV_DIR)/gxvalid.h \ - $(GXV_DIR)/gxverror.h \ - $(GXV_DIR)/gxvcommn.h \ - $(GXV_DIR)/gxvfeat.h \ - $(GXV_DIR)/gxvmod.h \ - $(GXV_DIR)/gxvmort.h \ - $(GXV_DIR)/gxvmorx.h - - -# GXV driver object(s) -# -# GXV_DRV_OBJ_M is used during `multi' builds. -# GXV_DRV_OBJ_S is used during `single' builds. -# -GXV_DRV_OBJ_M := $(GXV_DRV_SRC:$(GXV_DIR)/%.c=$(OBJ_DIR)/%.$O) -GXV_DRV_OBJ_S := $(OBJ_DIR)/gxvalid.$O - -# GXV driver source file for single build -# -GXV_DRV_SRC_S := $(GXV_DIR)/gxvalid.c - - -# GXV driver - single object -# -$(GXV_DRV_OBJ_S): $(GXV_DRV_SRC_S) $(GXV_DRV_SRC) \ - $(FREETYPE_H) $(GXV_DRV_H) - $(GXV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(GXV_DRV_SRC_S)) - - -# GXV driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(GXV_DIR)/%.c $(FREETYPE_H) $(GXV_DRV_H) - $(GXV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(GXV_DRV_OBJ_S) -DRV_OBJS_M += $(GXV_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/otvalid/Jamfile b/drivers/freetype/freetype/src/otvalid/Jamfile deleted file mode 100644 index b457143de4..0000000000 --- a/drivers/freetype/freetype/src/otvalid/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/otvalid Jamfile -# -# Copyright 2004 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) otvalid ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod otvmath ; - } - else - { - _sources = otvalid ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/otvalid Jamfile diff --git a/drivers/freetype/freetype/src/otvalid/module.mk b/drivers/freetype/freetype/src/otvalid/module.mk deleted file mode 100644 index 9cadde55e4..0000000000 --- a/drivers/freetype/freetype/src/otvalid/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 otvalid module definition -# - - -# Copyright 2004, 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. - - -FTMODULE_H_COMMANDS += OTVALID_MODULE - -define OTVALID_MODULE -$(OPEN_DRIVER) FT_Module_Class, otv_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)otvalid $(ECHO_DRIVER_DESC)OpenType validation module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/otvalid/otvalid.c b/drivers/freetype/freetype/src/otvalid/otvalid.c deleted file mode 100644 index d5c2b75abb..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvalid.c +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvalid.c */ -/* */ -/* FreeType validator for OpenType tables (body only). */ -/* */ -/* Copyright 2004, 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. */ -/* */ -/***************************************************************************/ - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> - -#include "otvbase.c" -#include "otvcommn.c" -#include "otvgdef.c" -#include "otvgpos.c" -#include "otvgsub.c" -#include "otvjstf.c" -#include "otvmath.c" -#include "otvmod.c" - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvalid.h b/drivers/freetype/freetype/src/otvalid/otvalid.h deleted file mode 100644 index eb99b9cc48..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvalid.h +++ /dev/null @@ -1,78 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvalid.h */ -/* */ -/* OpenType table validation (specification only). */ -/* */ -/* Copyright 2004, 2008 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 __OTVALID_H__ -#define __OTVALID_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - -#include "otverror.h" /* must come before FT_INTERNAL_VALIDATE_H */ - -#include FT_INTERNAL_VALIDATE_H -#include FT_INTERNAL_STREAM_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( void ) - otv_BASE_validate( FT_Bytes table, - FT_Validator valid ); - - /* GSUB and GPOS tables should already be validated; */ - /* if missing, set corresponding argument to 0 */ - FT_LOCAL( void ) - otv_GDEF_validate( FT_Bytes table, - FT_Bytes gsub, - FT_Bytes gpos, - FT_UInt glyph_count, - FT_Validator valid ); - - FT_LOCAL( void ) - otv_GPOS_validate( FT_Bytes table, - FT_UInt glyph_count, - FT_Validator valid ); - - FT_LOCAL( void ) - otv_GSUB_validate( FT_Bytes table, - FT_UInt glyph_count, - FT_Validator valid ); - - /* GSUB and GPOS tables should already be validated; */ - /* if missing, set corresponding argument to 0 */ - FT_LOCAL( void ) - otv_JSTF_validate( FT_Bytes table, - FT_Bytes gsub, - FT_Bytes gpos, - FT_UInt glyph_count, - FT_Validator valid ); - - FT_LOCAL( void ) - otv_MATH_validate( FT_Bytes table, - FT_UInt glyph_count, - FT_Validator ftvalid ); - - -FT_END_HEADER - -#endif /* __OTVALID_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvbase.c b/drivers/freetype/freetype/src/otvalid/otvbase.c deleted file mode 100644 index d742d2dc95..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvbase.c +++ /dev/null @@ -1,318 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvbase.c */ -/* */ -/* OpenType BASE table validation (body). */ -/* */ -/* Copyright 2004, 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 "otvalid.h" -#include "otvcommn.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_otvbase - - - static void - otv_BaseCoord_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt BaseCoordFormat; - - - OTV_NAME_ENTER( "BaseCoord" ); - - OTV_LIMIT_CHECK( 4 ); - BaseCoordFormat = FT_NEXT_USHORT( p ); - p += 2; /* skip Coordinate */ - - OTV_TRACE(( " (format %d)\n", BaseCoordFormat )); - - switch ( BaseCoordFormat ) - { - case 1: /* BaseCoordFormat1 */ - break; - - case 2: /* BaseCoordFormat2 */ - OTV_LIMIT_CHECK( 4 ); /* ReferenceGlyph, BaseCoordPoint */ - break; - - case 3: /* BaseCoordFormat3 */ - OTV_LIMIT_CHECK( 2 ); - /* DeviceTable */ - otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - static void - otv_BaseTagList_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt BaseTagCount; - - - OTV_NAME_ENTER( "BaseTagList" ); - - OTV_LIMIT_CHECK( 2 ); - - BaseTagCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (BaseTagCount = %d)\n", BaseTagCount )); - - OTV_LIMIT_CHECK( BaseTagCount * 4 ); /* BaselineTag */ - - OTV_EXIT; - } - - - static void - otv_BaseValues_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt BaseCoordCount; - - - OTV_NAME_ENTER( "BaseValues" ); - - OTV_LIMIT_CHECK( 4 ); - - p += 2; /* skip DefaultIndex */ - BaseCoordCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (BaseCoordCount = %d)\n", BaseCoordCount )); - - OTV_LIMIT_CHECK( BaseCoordCount * 2 ); - - /* BaseCoord */ - for ( ; BaseCoordCount > 0; BaseCoordCount-- ) - otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), valid ); - - OTV_EXIT; - } - - - static void - otv_MinMax_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt table_size; - FT_UInt FeatMinMaxCount; - - OTV_OPTIONAL_TABLE( MinCoord ); - OTV_OPTIONAL_TABLE( MaxCoord ); - - - OTV_NAME_ENTER( "MinMax" ); - - OTV_LIMIT_CHECK( 6 ); - - OTV_OPTIONAL_OFFSET( MinCoord ); - OTV_OPTIONAL_OFFSET( MaxCoord ); - FeatMinMaxCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (FeatMinMaxCount = %d)\n", FeatMinMaxCount )); - - table_size = FeatMinMaxCount * 8 + 6; - - OTV_SIZE_CHECK( MinCoord ); - if ( MinCoord ) - otv_BaseCoord_validate( table + MinCoord, valid ); - - OTV_SIZE_CHECK( MaxCoord ); - if ( MaxCoord ) - otv_BaseCoord_validate( table + MaxCoord, valid ); - - OTV_LIMIT_CHECK( FeatMinMaxCount * 8 ); - - /* FeatMinMaxRecord */ - for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- ) - { - p += 4; /* skip FeatureTableTag */ - - OTV_OPTIONAL_OFFSET( MinCoord ); - OTV_OPTIONAL_OFFSET( MaxCoord ); - - OTV_SIZE_CHECK( MinCoord ); - if ( MinCoord ) - otv_BaseCoord_validate( table + MinCoord, valid ); - - OTV_SIZE_CHECK( MaxCoord ); - if ( MaxCoord ) - otv_BaseCoord_validate( table + MaxCoord, valid ); - } - - OTV_EXIT; - } - - - static void - otv_BaseScript_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt table_size; - FT_UInt BaseLangSysCount; - - OTV_OPTIONAL_TABLE( BaseValues ); - OTV_OPTIONAL_TABLE( DefaultMinMax ); - - - OTV_NAME_ENTER( "BaseScript" ); - - OTV_LIMIT_CHECK( 6 ); - OTV_OPTIONAL_OFFSET( BaseValues ); - OTV_OPTIONAL_OFFSET( DefaultMinMax ); - BaseLangSysCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (BaseLangSysCount = %d)\n", BaseLangSysCount )); - - table_size = BaseLangSysCount * 6 + 6; - - OTV_SIZE_CHECK( BaseValues ); - if ( BaseValues ) - otv_BaseValues_validate( table + BaseValues, valid ); - - OTV_SIZE_CHECK( DefaultMinMax ); - if ( DefaultMinMax ) - otv_MinMax_validate( table + DefaultMinMax, valid ); - - OTV_LIMIT_CHECK( BaseLangSysCount * 6 ); - - /* BaseLangSysRecord */ - for ( ; BaseLangSysCount > 0; BaseLangSysCount-- ) - { - p += 4; /* skip BaseLangSysTag */ - - otv_MinMax_validate( table + FT_NEXT_USHORT( p ), valid ); - } - - OTV_EXIT; - } - - - static void - otv_BaseScriptList_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt BaseScriptCount; - - - OTV_NAME_ENTER( "BaseScriptList" ); - - OTV_LIMIT_CHECK( 2 ); - BaseScriptCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (BaseScriptCount = %d)\n", BaseScriptCount )); - - OTV_LIMIT_CHECK( BaseScriptCount * 6 ); - - /* BaseScriptRecord */ - for ( ; BaseScriptCount > 0; BaseScriptCount-- ) - { - p += 4; /* skip BaseScriptTag */ - - /* BaseScript */ - otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), valid ); - } - - OTV_EXIT; - } - - - static void - otv_Axis_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt table_size; - - OTV_OPTIONAL_TABLE( BaseTagList ); - - - OTV_NAME_ENTER( "Axis" ); - - OTV_LIMIT_CHECK( 4 ); - OTV_OPTIONAL_OFFSET( BaseTagList ); - - table_size = 4; - - OTV_SIZE_CHECK( BaseTagList ); - if ( BaseTagList ) - otv_BaseTagList_validate( table + BaseTagList, valid ); - - /* BaseScriptList */ - otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), valid ); - - OTV_EXIT; - } - - - FT_LOCAL_DEF( void ) - otv_BASE_validate( FT_Bytes table, - FT_Validator ftvalid ) - { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; - FT_UInt table_size; - - OTV_OPTIONAL_TABLE( HorizAxis ); - OTV_OPTIONAL_TABLE( VertAxis ); - - - valid->root = ftvalid; - - FT_TRACE3(( "validating BASE table\n" )); - OTV_INIT; - - OTV_LIMIT_CHECK( 6 ); - - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_FORMAT; - - table_size = 6; - - OTV_OPTIONAL_OFFSET( HorizAxis ); - OTV_SIZE_CHECK( HorizAxis ); - if ( HorizAxis ) - otv_Axis_validate( table + HorizAxis, valid ); - - OTV_OPTIONAL_OFFSET( VertAxis ); - OTV_SIZE_CHECK( VertAxis ); - if ( VertAxis ) - otv_Axis_validate( table + VertAxis, valid ); - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvcommn.c b/drivers/freetype/freetype/src/otvalid/otvcommn.c deleted file mode 100644 index a4f885b51f..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvcommn.c +++ /dev/null @@ -1,1086 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvcommn.c */ -/* */ -/* OpenType common tables validation (body). */ -/* */ -/* 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, */ -/* 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 "otvcommn.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_otvcommon - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** COVERAGE TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid, - FT_Int expected_count ) - { - FT_Bytes p = table; - FT_UInt CoverageFormat; - FT_UInt total = 0; - - - OTV_NAME_ENTER( "Coverage" ); - - OTV_LIMIT_CHECK( 4 ); - CoverageFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", CoverageFormat )); - - switch ( CoverageFormat ) - { - case 1: /* CoverageFormat1 */ - { - FT_UInt GlyphCount; - FT_UInt i; - - - GlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - - OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ - - for ( i = 0; i < GlyphCount; ++i ) - { - FT_UInt gid; - - - gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) - FT_INVALID_GLYPH_ID; - } - - total = GlyphCount; - } - break; - - case 2: /* CoverageFormat2 */ - { - FT_UInt n, RangeCount; - FT_UInt Start, End, StartCoverageIndex, last = 0; - - - RangeCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (RangeCount = %d)\n", RangeCount )); - - OTV_LIMIT_CHECK( RangeCount * 6 ); - - /* RangeRecord */ - for ( n = 0; n < RangeCount; n++ ) - { - Start = FT_NEXT_USHORT( p ); - End = FT_NEXT_USHORT( p ); - StartCoverageIndex = FT_NEXT_USHORT( p ); - - if ( Start > End || StartCoverageIndex != total ) - FT_INVALID_DATA; - - if ( End >= valid->glyph_count ) - FT_INVALID_GLYPH_ID; - - if ( n > 0 && Start <= last ) - FT_INVALID_DATA; - - total += End - Start + 1; - last = End; - } - } - break; - - default: - FT_INVALID_FORMAT; - } - - /* Generally, a coverage table offset has an associated count field. */ - /* The number of glyphs in the table should match this field. If */ - /* there is no associated count, a value of -1 tells us not to check. */ - if ( expected_count != -1 && (FT_UInt)expected_count != total ) - FT_INVALID_DATA; - - OTV_EXIT; - } - - - FT_LOCAL_DEF( FT_UInt ) - otv_Coverage_get_first( FT_Bytes table ) - { - FT_Bytes p = table; - - - p += 4; /* skip CoverageFormat and Glyph/RangeCount */ - - return FT_NEXT_USHORT( p ); - } - - - FT_LOCAL_DEF( FT_UInt ) - otv_Coverage_get_last( FT_Bytes table ) - { - FT_Bytes p = table; - FT_UInt CoverageFormat = FT_NEXT_USHORT( p ); - FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */ - FT_UInt result = 0; - - - switch ( CoverageFormat ) - { - case 1: - p += ( count - 1 ) * 2; - result = FT_NEXT_USHORT( p ); - break; - - case 2: - p += ( count - 1 ) * 6 + 2; - result = FT_NEXT_USHORT( p ); - break; - - default: - ; - } - - return result; - } - - - FT_LOCAL_DEF( FT_UInt ) - otv_Coverage_get_count( FT_Bytes table ) - { - FT_Bytes p = table; - FT_UInt CoverageFormat = FT_NEXT_USHORT( p ); - FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */ - FT_UInt result = 0; - - - switch ( CoverageFormat ) - { - case 1: - return count; - - case 2: - { - FT_UInt Start, End; - - - for ( ; count > 0; count-- ) - { - Start = FT_NEXT_USHORT( p ); - End = FT_NEXT_USHORT( p ); - p += 2; /* skip StartCoverageIndex */ - - result += End - Start + 1; - } - } - break; - - default: - ; - } - - return result; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CLASS DEFINITION TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - otv_ClassDef_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt ClassFormat; - - - OTV_NAME_ENTER( "ClassDef" ); - - OTV_LIMIT_CHECK( 4 ); - ClassFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", ClassFormat )); - - switch ( ClassFormat ) - { - case 1: /* ClassDefFormat1 */ - { - FT_UInt StartGlyph; - FT_UInt GlyphCount; - - - OTV_LIMIT_CHECK( 4 ); - - StartGlyph = FT_NEXT_USHORT( p ); - GlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - - OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ - - if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count ) - FT_INVALID_GLYPH_ID; - } - break; - - case 2: /* ClassDefFormat2 */ - { - FT_UInt n, ClassRangeCount; - FT_UInt Start, End, last = 0; - - - ClassRangeCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount )); - - OTV_LIMIT_CHECK( ClassRangeCount * 6 ); - - /* ClassRangeRecord */ - for ( n = 0; n < ClassRangeCount; n++ ) - { - Start = FT_NEXT_USHORT( p ); - End = FT_NEXT_USHORT( p ); - p += 2; /* skip Class */ - - if ( Start > End || ( n > 0 && Start <= last ) ) - FT_INVALID_DATA; - - if ( End >= valid->glyph_count ) - FT_INVALID_GLYPH_ID; - - last = End; - } - } - break; - - default: - FT_INVALID_FORMAT; - } - - /* no need to check glyph indices used as input to class definition */ - /* tables since even invalid glyph indices return a meaningful result */ - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** DEVICE TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - otv_Device_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt StartSize, EndSize, DeltaFormat, count; - - - OTV_NAME_ENTER( "Device" ); - - OTV_LIMIT_CHECK( 8 ); - StartSize = FT_NEXT_USHORT( p ); - EndSize = FT_NEXT_USHORT( p ); - DeltaFormat = FT_NEXT_USHORT( p ); - - if ( DeltaFormat < 1 || DeltaFormat > 3 ) - FT_INVALID_FORMAT; - - if ( EndSize < StartSize ) - FT_INVALID_DATA; - - count = EndSize - StartSize + 1; - OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */ - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** LOOKUPS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* uses valid->type_count */ - /* uses valid->type_funcs */ - - FT_LOCAL_DEF( void ) - otv_Lookup_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt LookupType, SubTableCount; - OTV_Validate_Func validate; - - - OTV_NAME_ENTER( "Lookup" ); - - OTV_LIMIT_CHECK( 6 ); - LookupType = FT_NEXT_USHORT( p ); - p += 2; /* skip LookupFlag */ - SubTableCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (type %d)\n", LookupType )); - - if ( LookupType == 0 || LookupType > valid->type_count ) - FT_INVALID_DATA; - - validate = valid->type_funcs[LookupType - 1]; - - OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount )); - - OTV_LIMIT_CHECK( SubTableCount * 2 ); - - /* SubTable */ - for ( ; SubTableCount > 0; SubTableCount-- ) - validate( table + FT_NEXT_USHORT( p ), valid ); - - OTV_EXIT; - } - - - /* uses valid->lookup_count */ - - FT_LOCAL_DEF( void ) - otv_LookupList_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt LookupCount; - - - OTV_NAME_ENTER( "LookupList" ); - - OTV_LIMIT_CHECK( 2 ); - LookupCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (LookupCount = %d)\n", LookupCount )); - - OTV_LIMIT_CHECK( LookupCount * 2 ); - - valid->lookup_count = LookupCount; - - /* Lookup */ - for ( ; LookupCount > 0; LookupCount-- ) - otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid ); - - OTV_EXIT; - } - - - static FT_UInt - otv_LookupList_get_count( FT_Bytes table ) - { - return FT_NEXT_USHORT( table ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FEATURES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* uses valid->lookup_count */ - - FT_LOCAL_DEF( void ) - otv_Feature_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt LookupCount; - - - OTV_NAME_ENTER( "Feature" ); - - OTV_LIMIT_CHECK( 4 ); - p += 2; /* skip FeatureParams (unused) */ - LookupCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (LookupCount = %d)\n", LookupCount )); - - OTV_LIMIT_CHECK( LookupCount * 2 ); - - /* LookupListIndex */ - for ( ; LookupCount > 0; LookupCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) - FT_INVALID_DATA; - - OTV_EXIT; - } - - - static FT_UInt - otv_Feature_get_count( FT_Bytes table ) - { - return FT_NEXT_USHORT( table ); - } - - - /* sets valid->lookup_count */ - - FT_LOCAL_DEF( void ) - otv_FeatureList_validate( FT_Bytes table, - FT_Bytes lookups, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt FeatureCount; - - - OTV_NAME_ENTER( "FeatureList" ); - - OTV_LIMIT_CHECK( 2 ); - FeatureCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); - - OTV_LIMIT_CHECK( FeatureCount * 2 ); - - valid->lookup_count = otv_LookupList_get_count( lookups ); - - /* FeatureRecord */ - for ( ; FeatureCount > 0; FeatureCount-- ) - { - p += 4; /* skip FeatureTag */ - - /* Feature */ - otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid ); - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** LANGUAGE SYSTEM *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* uses valid->extra1 (number of features) */ - - FT_LOCAL_DEF( void ) - otv_LangSys_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt ReqFeatureIndex; - FT_UInt FeatureCount; - - - OTV_NAME_ENTER( "LangSys" ); - - OTV_LIMIT_CHECK( 6 ); - p += 2; /* skip LookupOrder (unused) */ - ReqFeatureIndex = FT_NEXT_USHORT( p ); - FeatureCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex )); - OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); - - if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 ) - FT_INVALID_DATA; - - OTV_LIMIT_CHECK( FeatureCount * 2 ); - - /* FeatureIndex */ - for ( ; FeatureCount > 0; FeatureCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) - FT_INVALID_DATA; - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SCRIPTS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - otv_Script_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_UInt DefaultLangSys, LangSysCount; - FT_Bytes p = table; - - - OTV_NAME_ENTER( "Script" ); - - OTV_LIMIT_CHECK( 4 ); - DefaultLangSys = FT_NEXT_USHORT( p ); - LangSysCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount )); - - if ( DefaultLangSys != 0 ) - otv_LangSys_validate( table + DefaultLangSys, valid ); - - OTV_LIMIT_CHECK( LangSysCount * 6 ); - - /* LangSysRecord */ - for ( ; LangSysCount > 0; LangSysCount-- ) - { - p += 4; /* skip LangSysTag */ - - /* LangSys */ - otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid ); - } - - OTV_EXIT; - } - - - /* sets valid->extra1 (number of features) */ - - FT_LOCAL_DEF( void ) - otv_ScriptList_validate( FT_Bytes table, - FT_Bytes features, - OTV_Validator valid ) - { - FT_UInt ScriptCount; - FT_Bytes p = table; - - - OTV_NAME_ENTER( "ScriptList" ); - - OTV_LIMIT_CHECK( 2 ); - ScriptCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount )); - - OTV_LIMIT_CHECK( ScriptCount * 6 ); - - valid->extra1 = otv_Feature_get_count( features ); - - /* ScriptRecord */ - for ( ; ScriptCount > 0; ScriptCount-- ) - { - p += 4; /* skip ScriptTag */ - - otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */ - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - u: uint16 - ux: unit16 [x] - - s: struct - sx: struct [x] - sxy: struct [x], using external y count - - x: uint16 x - - C: Coverage - - O: Offset - On: Offset (NULL) - Ox: Offset [x] - Onx: Offset (NULL) [x] - */ - - FT_LOCAL_DEF( void ) - otv_x_Ox( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt Count; - OTV_Validate_Func func; - - - OTV_ENTER; - - OTV_LIMIT_CHECK( 2 ); - Count = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (Count = %d)\n", Count )); - - OTV_LIMIT_CHECK( Count * 2 ); - - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - - for ( ; Count > 0; Count-- ) - func( table + FT_NEXT_USHORT( p ), valid ); - - valid->nesting_level--; - - OTV_EXIT; - } - - - FT_LOCAL_DEF( void ) - otv_u_C_x_Ox( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt Count, Coverage; - OTV_Validate_Func func; - - - OTV_ENTER; - - p += 2; /* skip Format */ - - OTV_LIMIT_CHECK( 4 ); - Coverage = FT_NEXT_USHORT( p ); - Count = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (Count = %d)\n", Count )); - - otv_Coverage_validate( table + Coverage, valid, Count ); - - OTV_LIMIT_CHECK( Count * 2 ); - - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - - for ( ; Count > 0; Count-- ) - func( table + FT_NEXT_USHORT( p ), valid ); - - valid->nesting_level--; - - OTV_EXIT; - } - - - /* uses valid->extra1 (if > 0: array value limit) */ - - FT_LOCAL_DEF( void ) - otv_x_ux( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt Count; - - - OTV_ENTER; - - OTV_LIMIT_CHECK( 2 ); - Count = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (Count = %d)\n", Count )); - - OTV_LIMIT_CHECK( Count * 2 ); - - if ( valid->extra1 ) - { - for ( ; Count > 0; Count-- ) - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) - FT_INVALID_DATA; - } - - OTV_EXIT; - } - - - /* `ux' in the function's name is not really correct since only x-1 */ - /* elements are tested */ - - /* uses valid->extra1 (array value limit) */ - - FT_LOCAL_DEF( void ) - otv_x_y_ux_sy( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt Count1, Count2; - - - OTV_ENTER; - - OTV_LIMIT_CHECK( 4 ); - Count1 = FT_NEXT_USHORT( p ); - Count2 = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (Count1 = %d)\n", Count1 )); - OTV_TRACE(( " (Count2 = %d)\n", Count2 )); - - if ( Count1 == 0 ) - FT_INVALID_DATA; - - OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 ); - p += ( Count1 - 1 ) * 2; - - for ( ; Count2 > 0; Count2-- ) - { - if ( FT_NEXT_USHORT( p ) >= Count1 ) - FT_INVALID_DATA; - - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) - FT_INVALID_DATA; - } - - OTV_EXIT; - } - - - /* `uy' in the function's name is not really correct since only y-1 */ - /* elements are tested */ - - /* uses valid->extra1 (array value limit) */ - - FT_LOCAL_DEF( void ) - otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt BacktrackCount, InputCount, LookaheadCount; - FT_UInt Count; - - - OTV_ENTER; - - OTV_LIMIT_CHECK( 2 ); - BacktrackCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount )); - - OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 ); - p += BacktrackCount * 2; - - InputCount = FT_NEXT_USHORT( p ); - if ( InputCount == 0 ) - FT_INVALID_DATA; - - OTV_TRACE(( " (InputCount = %d)\n", InputCount )); - - OTV_LIMIT_CHECK( InputCount * 2 ); - p += ( InputCount - 1 ) * 2; - - LookaheadCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount )); - - OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 ); - p += LookaheadCount * 2; - - Count = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (Count = %d)\n", Count )); - - OTV_LIMIT_CHECK( Count * 4 ); - - for ( ; Count > 0; Count-- ) - { - if ( FT_NEXT_USHORT( p ) >= InputCount ) - FT_INVALID_DATA; - - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) - FT_INVALID_DATA; - } - - OTV_EXIT; - } - - - /* sets valid->extra1 (valid->lookup_count) */ - - FT_LOCAL_DEF( void ) - otv_u_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt Coverage, ClassDef, ClassSetCount; - OTV_Validate_Func func; - - - OTV_ENTER; - - p += 2; /* skip Format */ - - OTV_LIMIT_CHECK( 6 ); - Coverage = FT_NEXT_USHORT( p ); - ClassDef = FT_NEXT_USHORT( p ); - ClassSetCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); - - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ClassDef_validate( table + ClassDef, valid ); - - OTV_LIMIT_CHECK( ClassSetCount * 2 ); - - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = valid->lookup_count; - - for ( ; ClassSetCount > 0; ClassSetCount-- ) - { - FT_UInt offset = FT_NEXT_USHORT( p ); - - - if ( offset ) - func( table + offset, valid ); - } - - valid->nesting_level--; - - OTV_EXIT; - } - - - /* uses valid->lookup_count */ - - FT_LOCAL_DEF( void ) - otv_u_x_y_Ox_sy( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt GlyphCount, Count, count1; - - - OTV_ENTER; - - p += 2; /* skip Format */ - - OTV_LIMIT_CHECK( 4 ); - GlyphCount = FT_NEXT_USHORT( p ); - Count = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - OTV_TRACE(( " (Count = %d)\n", Count )); - - OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); - - for ( count1 = GlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); - - for ( ; Count > 0; Count-- ) - { - if ( FT_NEXT_USHORT( p ) >= GlyphCount ) - FT_INVALID_DATA; - - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) - FT_INVALID_DATA; - } - - OTV_EXIT; - } - - - /* sets valid->extra1 (valid->lookup_count) */ - - FT_LOCAL_DEF( void ) - otv_u_O_O_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt Coverage; - FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef; - FT_UInt ChainClassSetCount; - OTV_Validate_Func func; - - - OTV_ENTER; - - p += 2; /* skip Format */ - - OTV_LIMIT_CHECK( 10 ); - Coverage = FT_NEXT_USHORT( p ); - BacktrackClassDef = FT_NEXT_USHORT( p ); - InputClassDef = FT_NEXT_USHORT( p ); - LookaheadClassDef = FT_NEXT_USHORT( p ); - ChainClassSetCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); - - otv_Coverage_validate( table + Coverage, valid, -1 ); - - otv_ClassDef_validate( table + BacktrackClassDef, valid ); - otv_ClassDef_validate( table + InputClassDef, valid ); - otv_ClassDef_validate( table + LookaheadClassDef, valid ); - - OTV_LIMIT_CHECK( ChainClassSetCount * 2 ); - - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = valid->lookup_count; - - for ( ; ChainClassSetCount > 0; ChainClassSetCount-- ) - { - FT_UInt offset = FT_NEXT_USHORT( p ); - - - if ( offset ) - func( table + offset, valid ); - } - - valid->nesting_level--; - - OTV_EXIT; - } - - - /* uses valid->lookup_count */ - - FT_LOCAL_DEF( void ) - otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount; - FT_UInt count1, count2; - - - OTV_ENTER; - - p += 2; /* skip Format */ - - OTV_LIMIT_CHECK( 2 ); - BacktrackGlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); - - OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); - - for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); - - InputGlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount )); - - OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); - - for ( count1 = InputGlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); - - LookaheadGlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); - - OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); - - for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); - - count2 = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (Count = %d)\n", count2 )); - - OTV_LIMIT_CHECK( count2 * 4 ); - - for ( ; count2 > 0; count2-- ) - { - if ( FT_NEXT_USHORT( p ) >= InputGlyphCount ) - FT_INVALID_DATA; - - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) - FT_INVALID_DATA; - } - - OTV_EXIT; - } - - - FT_LOCAL_DEF( FT_UInt ) - otv_GSUBGPOS_get_Lookup_count( FT_Bytes table ) - { - FT_Bytes p = table + 8; - - - return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) ); - } - - - FT_LOCAL_DEF( FT_UInt ) - otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table ) - { - FT_Bytes p, lookup; - FT_UInt count; - - - if ( !table ) - return 0; - - /* LookupList */ - p = table + 8; - table += FT_NEXT_USHORT( p ); - - /* LookupCount */ - p = table; - count = FT_NEXT_USHORT( p ); - - for ( ; count > 0; count-- ) - { - FT_Bytes oldp; - - - /* Lookup */ - lookup = table + FT_NEXT_USHORT( p ); - - oldp = p; - - /* LookupFlag */ - p = lookup + 2; - if ( FT_NEXT_USHORT( p ) & 0xFF00U ) - return 1; - - p = oldp; - } - - return 0; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvcommn.h b/drivers/freetype/freetype/src/otvalid/otvcommn.h deleted file mode 100644 index 898887fc95..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvcommn.h +++ /dev/null @@ -1,437 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvcommn.h */ -/* */ -/* OpenType common tables validation (specification). */ -/* */ -/* Copyright 2004, 2005, 2007, 2009 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 __OTVCOMMN_H__ -#define __OTVCOMMN_H__ - - -#include <ft2build.h> -#include "otvalid.h" -#include FT_INTERNAL_DEBUG_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** VALIDATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct OTV_ValidatorRec_* OTV_Validator; - - typedef void (*OTV_Validate_Func)( FT_Bytes table, - OTV_Validator valid ); - - typedef struct OTV_ValidatorRec_ - { - FT_Validator root; - FT_UInt type_count; - OTV_Validate_Func* type_funcs; - - FT_UInt lookup_count; - FT_UInt glyph_count; - - FT_UInt nesting_level; - - OTV_Validate_Func func[3]; - - FT_UInt extra1; /* for passing parameters */ - FT_UInt extra2; - FT_Bytes extra3; - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_UInt debug_indent; - const FT_String* debug_function_name[3]; -#endif - - } OTV_ValidatorRec; - - -#undef FT_INVALID_ -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid->root, _prefix ## _error ) - -#define OTV_OPTIONAL_TABLE( _table ) FT_UShort _table; \ - FT_Bytes _table ## _p - -#define OTV_OPTIONAL_OFFSET( _offset ) \ - FT_BEGIN_STMNT \ - _offset ## _p = p; \ - _offset = FT_NEXT_USHORT( p ); \ - FT_END_STMNT - -#define OTV_LIMIT_CHECK( _count ) \ - FT_BEGIN_STMNT \ - if ( p + (_count) > valid->root->limit ) \ - FT_INVALID_TOO_SHORT; \ - FT_END_STMNT - -#define OTV_SIZE_CHECK( _size ) \ - FT_BEGIN_STMNT \ - if ( _size > 0 && _size < table_size ) \ - { \ - if ( valid->root->level == FT_VALIDATE_PARANOID ) \ - FT_INVALID_OFFSET; \ - else \ - { \ - /* strip off `const' */ \ - FT_Byte* pp = (FT_Byte*)_size ## _p; \ - \ - \ - FT_TRACE3(( "\n" \ - "Invalid offset to optional table `%s'" \ - " set to zero.\n" \ - "\n", #_size )); \ - \ - /* always assume 16bit entities */ \ - _size = pp[0] = pp[1] = 0; \ - } \ - } \ - FT_END_STMNT - - -#define OTV_NAME_(x) #x -#define OTV_NAME(x) OTV_NAME_(x) - -#define OTV_FUNC_(x) x##Func -#define OTV_FUNC(x) OTV_FUNC_(x) - -#ifdef FT_DEBUG_LEVEL_TRACE - -#define OTV_NEST1( x ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ - FT_END_STMNT - -#define OTV_NEST2( x, y ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ - valid->debug_function_name[1] = OTV_NAME( y ); \ - FT_END_STMNT - -#define OTV_NEST3( x, y, z ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->func[2] = OTV_FUNC( z ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ - valid->debug_function_name[1] = OTV_NAME( y ); \ - valid->debug_function_name[2] = OTV_NAME( z ); \ - FT_END_STMNT - -#define OTV_INIT valid->debug_indent = 0 - -#define OTV_ENTER \ - FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", \ - valid->debug_function_name[valid->nesting_level] )); \ - FT_END_STMNT - -#define OTV_NAME_ENTER( name ) \ - FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", name )); \ - FT_END_STMNT - -#define OTV_EXIT valid->debug_indent -= 2 - -#define OTV_TRACE( s ) \ - FT_BEGIN_STMNT \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4( s ); \ - FT_END_STMNT - -#else /* !FT_DEBUG_LEVEL_TRACE */ - -#define OTV_NEST1( x ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - FT_END_STMNT - -#define OTV_NEST2( x, y ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - FT_END_STMNT - -#define OTV_NEST3( x, y, z ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->func[2] = OTV_FUNC( z ); \ - FT_END_STMNT - -#define OTV_INIT do { } while ( 0 ) -#define OTV_ENTER do { } while ( 0 ) -#define OTV_NAME_ENTER( name ) do { } while ( 0 ) -#define OTV_EXIT do { } while ( 0 ) - -#define OTV_TRACE( s ) do { } while ( 0 ) - -#endif /* !FT_DEBUG_LEVEL_TRACE */ - - -#define OTV_RUN valid->func[0] - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** COVERAGE TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid, - FT_Int expected_count ); - - /* return first covered glyph */ - FT_LOCAL( FT_UInt ) - otv_Coverage_get_first( FT_Bytes table ); - - /* return last covered glyph */ - FT_LOCAL( FT_UInt ) - otv_Coverage_get_last( FT_Bytes table ); - - /* return number of covered glyphs */ - FT_LOCAL( FT_UInt ) - otv_Coverage_get_count( FT_Bytes table ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CLASS DEFINITION TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - otv_ClassDef_validate( FT_Bytes table, - OTV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** DEVICE TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - otv_Device_validate( FT_Bytes table, - OTV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** LOOKUPS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - otv_Lookup_validate( FT_Bytes table, - OTV_Validator valid ); - - FT_LOCAL( void ) - otv_LookupList_validate( FT_Bytes table, - OTV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FEATURES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - otv_Feature_validate( FT_Bytes table, - OTV_Validator valid ); - - /* lookups must already be validated */ - FT_LOCAL( void ) - otv_FeatureList_validate( FT_Bytes table, - FT_Bytes lookups, - OTV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** LANGUAGE SYSTEM *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - otv_LangSys_validate( FT_Bytes table, - OTV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SCRIPTS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - otv_Script_validate( FT_Bytes table, - OTV_Validator valid ); - - /* features must already be validated */ - FT_LOCAL( void ) - otv_ScriptList_validate( FT_Bytes table, - FT_Bytes features, - OTV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define ChainPosClassSetFunc otv_x_Ox -#define ChainPosRuleSetFunc otv_x_Ox -#define ChainSubClassSetFunc otv_x_Ox -#define ChainSubRuleSetFunc otv_x_Ox -#define JstfLangSysFunc otv_x_Ox -#define JstfMaxFunc otv_x_Ox -#define LigGlyphFunc otv_x_Ox -#define LigatureArrayFunc otv_x_Ox -#define LigatureSetFunc otv_x_Ox -#define PosClassSetFunc otv_x_Ox -#define PosRuleSetFunc otv_x_Ox -#define SubClassSetFunc otv_x_Ox -#define SubRuleSetFunc otv_x_Ox - - FT_LOCAL( void ) - otv_x_Ox ( FT_Bytes table, - OTV_Validator valid ); - -#define AlternateSubstFormat1Func otv_u_C_x_Ox -#define ChainContextPosFormat1Func otv_u_C_x_Ox -#define ChainContextSubstFormat1Func otv_u_C_x_Ox -#define ContextPosFormat1Func otv_u_C_x_Ox -#define ContextSubstFormat1Func otv_u_C_x_Ox -#define LigatureSubstFormat1Func otv_u_C_x_Ox -#define MultipleSubstFormat1Func otv_u_C_x_Ox - - FT_LOCAL( void ) - otv_u_C_x_Ox( FT_Bytes table, - OTV_Validator valid ); - -#define AlternateSetFunc otv_x_ux -#define AttachPointFunc otv_x_ux -#define ExtenderGlyphFunc otv_x_ux -#define JstfGPOSModListFunc otv_x_ux -#define JstfGSUBModListFunc otv_x_ux -#define SequenceFunc otv_x_ux - - FT_LOCAL( void ) - otv_x_ux( FT_Bytes table, - OTV_Validator valid ); - -#define PosClassRuleFunc otv_x_y_ux_sy -#define PosRuleFunc otv_x_y_ux_sy -#define SubClassRuleFunc otv_x_y_ux_sy -#define SubRuleFunc otv_x_y_ux_sy - - FT_LOCAL( void ) - otv_x_y_ux_sy( FT_Bytes table, - OTV_Validator valid ); - -#define ChainPosClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp -#define ChainPosRuleFunc otv_x_ux_y_uy_z_uz_p_sp -#define ChainSubClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp -#define ChainSubRuleFunc otv_x_ux_y_uy_z_uz_p_sp - - FT_LOCAL( void ) - otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, - OTV_Validator valid ); - -#define ContextPosFormat2Func otv_u_O_O_x_Onx -#define ContextSubstFormat2Func otv_u_O_O_x_Onx - - FT_LOCAL( void ) - otv_u_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ); - -#define ContextPosFormat3Func otv_u_x_y_Ox_sy -#define ContextSubstFormat3Func otv_u_x_y_Ox_sy - - FT_LOCAL( void ) - otv_u_x_y_Ox_sy( FT_Bytes table, - OTV_Validator valid ); - -#define ChainContextPosFormat2Func otv_u_O_O_O_O_x_Onx -#define ChainContextSubstFormat2Func otv_u_O_O_O_O_x_Onx - - FT_LOCAL( void ) - otv_u_O_O_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ); - -#define ChainContextPosFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp -#define ChainContextSubstFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp - - FT_LOCAL( void ) - otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, - OTV_Validator valid ); - - - FT_LOCAL( FT_UInt ) - otv_GSUBGPOS_get_Lookup_count( FT_Bytes table ); - - FT_LOCAL( FT_UInt ) - otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table ); - - /* */ - -FT_END_HEADER - -#endif /* __OTVCOMMN_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otverror.h b/drivers/freetype/freetype/src/otvalid/otverror.h deleted file mode 100644 index b6f00c9dba..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otverror.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* otverror.h */ -/* */ -/* OpenType validation module error codes (specification only). */ -/* */ -/* Copyright 2004, 2005, 2012, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the OpenType validation module error */ - /* enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __OTVERROR_H__ -#define __OTVERROR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX OTV_Err_ -#define FT_ERR_BASE FT_Mod_Err_OTvalid - -#include FT_ERRORS_H - -#endif /* __OTVERROR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvgdef.c b/drivers/freetype/freetype/src/otvalid/otvgdef.c deleted file mode 100644 index 3633ad0de1..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvgdef.c +++ /dev/null @@ -1,224 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvgdef.c */ -/* */ -/* OpenType GDEF table validation (body). */ -/* */ -/* Copyright 2004, 2005, 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 "otvalid.h" -#include "otvcommn.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_otvgdef - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define AttachListFunc otv_O_x_Ox -#define LigCaretListFunc otv_O_x_Ox - - /* sets valid->extra1 (0) */ - - static void - otv_O_x_Ox( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_Bytes Coverage; - FT_UInt GlyphCount; - OTV_Validate_Func func; - - - OTV_ENTER; - - OTV_LIMIT_CHECK( 4 ); - Coverage = table + FT_NEXT_USHORT( p ); - GlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - - otv_Coverage_validate( Coverage, valid, GlyphCount ); - if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) - FT_INVALID_DATA; - - OTV_LIMIT_CHECK( GlyphCount * 2 ); - - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = 0; - - for ( ; GlyphCount > 0; GlyphCount-- ) - func( table + FT_NEXT_USHORT( p ), valid ); - - valid->nesting_level--; - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** LIGATURE CARETS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define CaretValueFunc otv_CaretValue_validate - - static void - otv_CaretValue_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt CaretValueFormat; - - - OTV_ENTER; - - OTV_LIMIT_CHECK( 4 ); - - CaretValueFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format = %d)\n", CaretValueFormat )); - - switch ( CaretValueFormat ) - { - case 1: /* CaretValueFormat1 */ - /* skip Coordinate, no test */ - break; - - case 2: /* CaretValueFormat2 */ - /* skip CaretValuePoint, no test */ - break; - - case 3: /* CaretValueFormat3 */ - p += 2; /* skip Coordinate */ - - OTV_LIMIT_CHECK( 2 ); - - /* DeviceTable */ - otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GDEF TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->glyph_count */ - - FT_LOCAL_DEF( void ) - otv_GDEF_validate( FT_Bytes table, - FT_Bytes gsub, - FT_Bytes gpos, - FT_UInt glyph_count, - FT_Validator ftvalid ) - { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; - FT_UInt table_size; - FT_Bool need_MarkAttachClassDef; - - OTV_OPTIONAL_TABLE( GlyphClassDef ); - OTV_OPTIONAL_TABLE( AttachListOffset ); - OTV_OPTIONAL_TABLE( LigCaretListOffset ); - OTV_OPTIONAL_TABLE( MarkAttachClassDef ); - - - valid->root = ftvalid; - - FT_TRACE3(( "validating GDEF table\n" )); - OTV_INIT; - - OTV_LIMIT_CHECK( 12 ); - - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_FORMAT; - - /* MarkAttachClassDef has been added to the OpenType */ - /* specification without increasing GDEF's version, */ - /* so we use this ugly hack to find out whether the */ - /* table is needed actually. */ - - need_MarkAttachClassDef = FT_BOOL( - otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) || - otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) ); - - if ( need_MarkAttachClassDef ) - table_size = 12; /* OpenType >= 1.2 */ - else - table_size = 10; /* OpenType < 1.2 */ - - valid->glyph_count = glyph_count; - - OTV_OPTIONAL_OFFSET( GlyphClassDef ); - OTV_SIZE_CHECK( GlyphClassDef ); - if ( GlyphClassDef ) - otv_ClassDef_validate( table + GlyphClassDef, valid ); - - OTV_OPTIONAL_OFFSET( AttachListOffset ); - OTV_SIZE_CHECK( AttachListOffset ); - if ( AttachListOffset ) - { - OTV_NEST2( AttachList, AttachPoint ); - OTV_RUN( table + AttachListOffset, valid ); - } - - OTV_OPTIONAL_OFFSET( LigCaretListOffset ); - OTV_SIZE_CHECK( LigCaretListOffset ); - if ( LigCaretListOffset ) - { - OTV_NEST3( LigCaretList, LigGlyph, CaretValue ); - OTV_RUN( table + LigCaretListOffset, valid ); - } - - if ( need_MarkAttachClassDef ) - { - OTV_OPTIONAL_OFFSET( MarkAttachClassDef ); - OTV_SIZE_CHECK( MarkAttachClassDef ); - if ( MarkAttachClassDef ) - otv_ClassDef_validate( table + MarkAttachClassDef, valid ); - } - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvgpos.c b/drivers/freetype/freetype/src/otvalid/otvgpos.c deleted file mode 100644 index 49b46183a3..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvgpos.c +++ /dev/null @@ -1,1017 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvgpos.c */ -/* */ -/* OpenType GPOS table validation (body). */ -/* */ -/* Copyright 2002, 2004, 2005, 2006, 2007, 2008 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 "otvalid.h" -#include "otvcommn.h" -#include "otvgpos.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_otvgpos - - - static void - otv_Anchor_validate( FT_Bytes table, - OTV_Validator valid ); - - static void - otv_MarkArray_validate( FT_Bytes table, - OTV_Validator valid ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** UTILITY FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define BaseArrayFunc otv_x_sxy -#define LigatureAttachFunc otv_x_sxy -#define Mark2ArrayFunc otv_x_sxy - - /* uses valid->extra1 (counter) */ - /* uses valid->extra2 (boolean to handle NULL anchor field) */ - - static void - otv_x_sxy( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt Count, count1, table_size; - - - OTV_ENTER; - - OTV_LIMIT_CHECK( 2 ); - - Count = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (Count = %d)\n", Count )); - - OTV_LIMIT_CHECK( Count * valid->extra1 * 2 ); - - table_size = Count * valid->extra1 * 2 + 2; - - for ( ; Count > 0; Count-- ) - for ( count1 = valid->extra1; count1 > 0; count1-- ) - { - OTV_OPTIONAL_TABLE( anchor_offset ); - - - OTV_OPTIONAL_OFFSET( anchor_offset ); - - if ( valid->extra2 ) - { - OTV_SIZE_CHECK( anchor_offset ); - if ( anchor_offset ) - otv_Anchor_validate( table + anchor_offset, valid ); - } - else - otv_Anchor_validate( table + anchor_offset, valid ); - } - - OTV_EXIT; - } - - -#define MarkBasePosFormat1Func otv_u_O_O_u_O_O -#define MarkLigPosFormat1Func otv_u_O_O_u_O_O -#define MarkMarkPosFormat1Func otv_u_O_O_u_O_O - - /* sets valid->extra1 (class count) */ - - static void - otv_u_O_O_u_O_O( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt Coverage1, Coverage2, ClassCount; - FT_UInt Array1, Array2; - OTV_Validate_Func func; - - - OTV_ENTER; - - p += 2; /* skip PosFormat */ - - OTV_LIMIT_CHECK( 10 ); - Coverage1 = FT_NEXT_USHORT( p ); - Coverage2 = FT_NEXT_USHORT( p ); - ClassCount = FT_NEXT_USHORT( p ); - Array1 = FT_NEXT_USHORT( p ); - Array2 = FT_NEXT_USHORT( p ); - - otv_Coverage_validate( table + Coverage1, valid, -1 ); - otv_Coverage_validate( table + Coverage2, valid, -1 ); - - otv_MarkArray_validate( table + Array1, valid ); - - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = ClassCount; - - func( table + Array2, valid ); - - valid->nesting_level--; - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** VALUE RECORDS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_UInt - otv_value_length( FT_UInt format ) - { - FT_UInt count; - - - count = ( ( format & 0xAA ) >> 1 ) + ( format & 0x55 ); - count = ( ( count & 0xCC ) >> 2 ) + ( count & 0x33 ); - count = ( ( count & 0xF0 ) >> 4 ) + ( count & 0x0F ); - - return count * 2; - } - - - /* uses valid->extra3 (pointer to base table) */ - - static void - otv_ValueRecord_validate( FT_Bytes table, - FT_UInt format, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt count; - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_Int loop; - FT_ULong res = 0; - - - OTV_NAME_ENTER( "ValueRecord" ); - - /* display `format' in dual representation */ - for ( loop = 7; loop >= 0; loop-- ) - { - res <<= 4; - res += ( format >> loop ) & 1; - } - - OTV_TRACE(( " (format 0b%08lx)\n", res )); -#endif - - if ( format >= 0x100 ) - FT_INVALID_FORMAT; - - for ( count = 4; count > 0; count-- ) - { - if ( format & 1 ) - { - /* XPlacement, YPlacement, XAdvance, YAdvance */ - OTV_LIMIT_CHECK( 2 ); - p += 2; - } - - format >>= 1; - } - - for ( count = 4; count > 0; count-- ) - { - if ( format & 1 ) - { - FT_PtrDist table_size; - - OTV_OPTIONAL_TABLE( device ); - - - /* XPlaDevice, YPlaDevice, XAdvDevice, YAdvDevice */ - OTV_LIMIT_CHECK( 2 ); - OTV_OPTIONAL_OFFSET( device ); - - /* XXX: this value is usually too small, especially if the current */ - /* ValueRecord is part of an array -- getting the correct table */ - /* size is probably not worth the trouble */ - - table_size = p - valid->extra3; - - OTV_SIZE_CHECK( device ); - if ( device ) - otv_Device_validate( valid->extra3 + device, valid ); - } - format >>= 1; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** ANCHORS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_Anchor_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt AnchorFormat; - - - OTV_NAME_ENTER( "Anchor"); - - OTV_LIMIT_CHECK( 6 ); - AnchorFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", AnchorFormat )); - - p += 4; /* skip XCoordinate and YCoordinate */ - - switch ( AnchorFormat ) - { - case 1: - break; - - case 2: - OTV_LIMIT_CHECK( 2 ); /* AnchorPoint */ - break; - - case 3: - { - FT_UInt table_size; - - OTV_OPTIONAL_TABLE( XDeviceTable ); - OTV_OPTIONAL_TABLE( YDeviceTable ); - - - OTV_LIMIT_CHECK( 4 ); - OTV_OPTIONAL_OFFSET( XDeviceTable ); - OTV_OPTIONAL_OFFSET( YDeviceTable ); - - table_size = 6 + 4; - - OTV_SIZE_CHECK( XDeviceTable ); - if ( XDeviceTable ) - otv_Device_validate( table + XDeviceTable, valid ); - - OTV_SIZE_CHECK( YDeviceTable ); - if ( YDeviceTable ) - otv_Device_validate( table + YDeviceTable, valid ); - } - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MARK ARRAYS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_MarkArray_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt MarkCount; - - - OTV_NAME_ENTER( "MarkArray" ); - - OTV_LIMIT_CHECK( 2 ); - MarkCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (MarkCount = %d)\n", MarkCount )); - - OTV_LIMIT_CHECK( MarkCount * 4 ); - - /* MarkRecord */ - for ( ; MarkCount > 0; MarkCount-- ) - { - p += 2; /* skip Class */ - /* MarkAnchor */ - otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid ); - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 1 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra3 (pointer to base table) */ - - static void - otv_SinglePos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "SinglePos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - valid->extra3 = table; - - switch ( PosFormat ) - { - case 1: /* SinglePosFormat1 */ - { - FT_UInt Coverage, ValueFormat; - - - OTV_LIMIT_CHECK( 4 ); - Coverage = FT_NEXT_USHORT( p ); - ValueFormat = FT_NEXT_USHORT( p ); - - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ - } - break; - - case 2: /* SinglePosFormat2 */ - { - FT_UInt Coverage, ValueFormat, ValueCount, len_value; - - - OTV_LIMIT_CHECK( 6 ); - Coverage = FT_NEXT_USHORT( p ); - ValueFormat = FT_NEXT_USHORT( p ); - ValueCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (ValueCount = %d)\n", ValueCount )); - - len_value = otv_value_length( ValueFormat ); - - otv_Coverage_validate( table + Coverage, valid, ValueCount ); - - OTV_LIMIT_CHECK( ValueCount * len_value ); - - /* Value */ - for ( ; ValueCount > 0; ValueCount-- ) - { - otv_ValueRecord_validate( p, ValueFormat, valid ); - p += len_value; - } - } - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 2 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_PairSet_validate( FT_Bytes table, - FT_UInt format1, - FT_UInt format2, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt value_len1, value_len2, PairValueCount; - - - OTV_NAME_ENTER( "PairSet" ); - - OTV_LIMIT_CHECK( 2 ); - PairValueCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (PairValueCount = %d)\n", PairValueCount )); - - value_len1 = otv_value_length( format1 ); - value_len2 = otv_value_length( format2 ); - - OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) ); - - /* PairValueRecord */ - for ( ; PairValueCount > 0; PairValueCount-- ) - { - p += 2; /* skip SecondGlyph */ - - if ( format1 ) - otv_ValueRecord_validate( p, format1, valid ); /* Value1 */ - p += value_len1; - - if ( format2 ) - otv_ValueRecord_validate( p, format2, valid ); /* Value2 */ - p += value_len2; - } - - OTV_EXIT; - } - - - /* sets valid->extra3 (pointer to base table) */ - - static void - otv_PairPos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "PairPos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - valid->extra3 = table; - - switch ( PosFormat ) - { - case 1: /* PairPosFormat1 */ - { - FT_UInt Coverage, ValueFormat1, ValueFormat2, PairSetCount; - - - OTV_LIMIT_CHECK( 8 ); - Coverage = FT_NEXT_USHORT( p ); - ValueFormat1 = FT_NEXT_USHORT( p ); - ValueFormat2 = FT_NEXT_USHORT( p ); - PairSetCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); - - otv_Coverage_validate( table + Coverage, valid, -1 ); - - OTV_LIMIT_CHECK( PairSetCount * 2 ); - - /* PairSetOffset */ - for ( ; PairSetCount > 0; PairSetCount-- ) - otv_PairSet_validate( table + FT_NEXT_USHORT( p ), - ValueFormat1, ValueFormat2, valid ); - } - break; - - case 2: /* PairPosFormat2 */ - { - FT_UInt Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2; - FT_UInt ClassCount1, ClassCount2, len_value1, len_value2, count; - - - OTV_LIMIT_CHECK( 14 ); - Coverage = FT_NEXT_USHORT( p ); - ValueFormat1 = FT_NEXT_USHORT( p ); - ValueFormat2 = FT_NEXT_USHORT( p ); - ClassDef1 = FT_NEXT_USHORT( p ); - ClassDef2 = FT_NEXT_USHORT( p ); - ClassCount1 = FT_NEXT_USHORT( p ); - ClassCount2 = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (ClassCount1 = %d)\n", ClassCount1 )); - OTV_TRACE(( " (ClassCount2 = %d)\n", ClassCount2 )); - - len_value1 = otv_value_length( ValueFormat1 ); - len_value2 = otv_value_length( ValueFormat2 ); - - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ClassDef_validate( table + ClassDef1, valid ); - otv_ClassDef_validate( table + ClassDef2, valid ); - - OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 * - ( len_value1 + len_value2 ) ); - - /* Class1Record */ - for ( ; ClassCount1 > 0; ClassCount1-- ) - { - /* Class2Record */ - for ( count = ClassCount2; count > 0; count-- ) - { - if ( ValueFormat1 ) - /* Value1 */ - otv_ValueRecord_validate( p, ValueFormat1, valid ); - p += len_value1; - - if ( ValueFormat2 ) - /* Value2 */ - otv_ValueRecord_validate( p, ValueFormat2, valid ); - p += len_value2; - } - } - } - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 3 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_CursivePos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "CursivePos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - switch ( PosFormat ) - { - case 1: /* CursivePosFormat1 */ - { - FT_UInt table_size; - FT_UInt Coverage, EntryExitCount; - - OTV_OPTIONAL_TABLE( EntryAnchor ); - OTV_OPTIONAL_TABLE( ExitAnchor ); - - - OTV_LIMIT_CHECK( 4 ); - Coverage = FT_NEXT_USHORT( p ); - EntryExitCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); - - otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); - - OTV_LIMIT_CHECK( EntryExitCount * 4 ); - - table_size = EntryExitCount * 4 + 4; - - /* EntryExitRecord */ - for ( ; EntryExitCount > 0; EntryExitCount-- ) - { - OTV_OPTIONAL_OFFSET( EntryAnchor ); - OTV_OPTIONAL_OFFSET( ExitAnchor ); - - OTV_SIZE_CHECK( EntryAnchor ); - if ( EntryAnchor ) - otv_Anchor_validate( table + EntryAnchor, valid ); - - OTV_SIZE_CHECK( ExitAnchor ); - if ( ExitAnchor ) - otv_Anchor_validate( table + ExitAnchor, valid ); - } - } - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 4 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* UNDOCUMENTED (in OpenType 1.5): */ - /* BaseRecord tables can contain NULL pointers. */ - - /* sets valid->extra2 (1) */ - - static void - otv_MarkBasePos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "MarkBasePos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - switch ( PosFormat ) - { - case 1: - valid->extra2 = 1; - OTV_NEST2( MarkBasePosFormat1, BaseArray ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 5 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra2 (1) */ - - static void - otv_MarkLigPos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "MarkLigPos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - switch ( PosFormat ) - { - case 1: - valid->extra2 = 1; - OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 6 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra2 (0) */ - - static void - otv_MarkMarkPos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "MarkMarkPos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - switch ( PosFormat ) - { - case 1: - valid->extra2 = 0; - OTV_NEST2( MarkMarkPosFormat1, Mark2Array ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 7 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra1 (lookup count) */ - - static void - otv_ContextPos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "ContextPos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - switch ( PosFormat ) - { - case 1: - /* no need to check glyph indices/classes used as input for these */ - /* context rules since even invalid glyph indices/classes return */ - /* meaningful results */ - - valid->extra1 = valid->lookup_count; - OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule ); - OTV_RUN( table, valid ); - break; - - case 2: - /* no need to check glyph indices/classes used as input for these */ - /* context rules since even invalid glyph indices/classes return */ - /* meaningful results */ - - OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule ); - OTV_RUN( table, valid ); - break; - - case 3: - OTV_NEST1( ContextPosFormat3 ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 8 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra1 (lookup count) */ - - static void - otv_ChainContextPos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "ChainContextPos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - switch ( PosFormat ) - { - case 1: - /* no need to check glyph indices/classes used as input for these */ - /* context rules since even invalid glyph indices/classes return */ - /* meaningful results */ - - valid->extra1 = valid->lookup_count; - OTV_NEST3( ChainContextPosFormat1, - ChainPosRuleSet, ChainPosRule ); - OTV_RUN( table, valid ); - break; - - case 2: - /* no need to check glyph indices/classes used as input for these */ - /* context rules since even invalid glyph indices/classes return */ - /* meaningful results */ - - OTV_NEST3( ChainContextPosFormat2, - ChainPosClassSet, ChainPosClassRule ); - OTV_RUN( table, valid ); - break; - - case 3: - OTV_NEST1( ChainContextPosFormat3 ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS LOOKUP TYPE 9 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* uses valid->type_funcs */ - - static void - otv_ExtensionPos_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt PosFormat; - - - OTV_NAME_ENTER( "ExtensionPos" ); - - OTV_LIMIT_CHECK( 2 ); - PosFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", PosFormat )); - - switch ( PosFormat ) - { - case 1: /* ExtensionPosFormat1 */ - { - FT_UInt ExtensionLookupType; - FT_ULong ExtensionOffset; - OTV_Validate_Func validate; - - - OTV_LIMIT_CHECK( 6 ); - ExtensionLookupType = FT_NEXT_USHORT( p ); - ExtensionOffset = FT_NEXT_ULONG( p ); - - if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 ) - FT_INVALID_DATA; - - validate = valid->type_funcs[ExtensionLookupType - 1]; - validate( table + ExtensionOffset, valid ); - } - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - static const OTV_Validate_Func otv_gpos_validate_funcs[9] = - { - otv_SinglePos_validate, - otv_PairPos_validate, - otv_CursivePos_validate, - otv_MarkBasePos_validate, - otv_MarkLigPos_validate, - otv_MarkMarkPos_validate, - otv_ContextPos_validate, - otv_ChainContextPos_validate, - otv_ExtensionPos_validate - }; - - - /* sets valid->type_count */ - /* sets valid->type_funcs */ - - FT_LOCAL_DEF( void ) - otv_GPOS_subtable_validate( FT_Bytes table, - OTV_Validator valid ) - { - valid->type_count = 9; - valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; - - otv_Lookup_validate( table, valid ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GPOS TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->glyph_count */ - - FT_LOCAL_DEF( void ) - otv_GPOS_validate( FT_Bytes table, - FT_UInt glyph_count, - FT_Validator ftvalid ) - { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; - FT_UInt ScriptList, FeatureList, LookupList; - - - valid->root = ftvalid; - - FT_TRACE3(( "validating GPOS table\n" )); - OTV_INIT; - - OTV_LIMIT_CHECK( 10 ); - - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_FORMAT; - - ScriptList = FT_NEXT_USHORT( p ); - FeatureList = FT_NEXT_USHORT( p ); - LookupList = FT_NEXT_USHORT( p ); - - valid->type_count = 9; - valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; - valid->glyph_count = glyph_count; - - otv_LookupList_validate( table + LookupList, - valid ); - otv_FeatureList_validate( table + FeatureList, table + LookupList, - valid ); - otv_ScriptList_validate( table + ScriptList, table + FeatureList, - valid ); - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvgpos.h b/drivers/freetype/freetype/src/otvalid/otvgpos.h deleted file mode 100644 index 14ca408261..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvgpos.h +++ /dev/null @@ -1,36 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvgpos.h */ -/* */ -/* OpenType GPOS table validator (specification). */ -/* */ -/* Copyright 2004 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 __OTVGPOS_H__ -#define __OTVGPOS_H__ - - -FT_BEGIN_HEADER - - - FT_LOCAL( void ) - otv_GPOS_subtable_validate( FT_Bytes table, - OTV_Validator valid ); - - -FT_END_HEADER - -#endif /* __OTVGPOS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvgsub.c b/drivers/freetype/freetype/src/otvalid/otvgsub.c deleted file mode 100644 index ed499d1e92..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvgsub.c +++ /dev/null @@ -1,585 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvgsub.c */ -/* */ -/* OpenType GSUB table validation (body). */ -/* */ -/* Copyright 2004, 2005, 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 "otvalid.h" -#include "otvcommn.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_otvgsub - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB LOOKUP TYPE 1 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* uses valid->glyph_count */ - - static void - otv_SingleSubst_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt SubstFormat; - - - OTV_NAME_ENTER( "SingleSubst" ); - - OTV_LIMIT_CHECK( 2 ); - SubstFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", SubstFormat )); - - switch ( SubstFormat ) - { - case 1: /* SingleSubstFormat1 */ - { - FT_Bytes Coverage; - FT_Int DeltaGlyphID; - FT_Long idx; - - - OTV_LIMIT_CHECK( 4 ); - Coverage = table + FT_NEXT_USHORT( p ); - DeltaGlyphID = FT_NEXT_SHORT( p ); - - otv_Coverage_validate( Coverage, valid, -1 ); - - idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; - if ( idx < 0 ) - FT_INVALID_DATA; - - idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID; - if ( (FT_UInt)idx >= valid->glyph_count ) - FT_INVALID_DATA; - } - break; - - case 2: /* SingleSubstFormat2 */ - { - FT_UInt Coverage, GlyphCount; - - - OTV_LIMIT_CHECK( 4 ); - Coverage = FT_NEXT_USHORT( p ); - GlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - - otv_Coverage_validate( table + Coverage, valid, GlyphCount ); - - OTV_LIMIT_CHECK( GlyphCount * 2 ); - - /* Substitute */ - for ( ; GlyphCount > 0; GlyphCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) - FT_INVALID_GLYPH_ID; - } - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB LOOKUP TYPE 2 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra1 (glyph count) */ - - static void - otv_MultipleSubst_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt SubstFormat; - - - OTV_NAME_ENTER( "MultipleSubst" ); - - OTV_LIMIT_CHECK( 2 ); - SubstFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", SubstFormat )); - - switch ( SubstFormat ) - { - case 1: - valid->extra1 = valid->glyph_count; - OTV_NEST2( MultipleSubstFormat1, Sequence ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB LOOKUP TYPE 3 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra1 (glyph count) */ - - static void - otv_AlternateSubst_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt SubstFormat; - - - OTV_NAME_ENTER( "AlternateSubst" ); - - OTV_LIMIT_CHECK( 2 ); - SubstFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", SubstFormat )); - - switch ( SubstFormat ) - { - case 1: - valid->extra1 = valid->glyph_count; - OTV_NEST2( AlternateSubstFormat1, AlternateSet ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB LOOKUP TYPE 4 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define LigatureFunc otv_Ligature_validate - - /* uses valid->glyph_count */ - - static void - otv_Ligature_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt LigatureGlyph, CompCount; - - - OTV_ENTER; - - OTV_LIMIT_CHECK( 4 ); - LigatureGlyph = FT_NEXT_USHORT( p ); - if ( LigatureGlyph >= valid->glyph_count ) - FT_INVALID_DATA; - - CompCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (CompCount = %d)\n", CompCount )); - - if ( CompCount == 0 ) - FT_INVALID_DATA; - - CompCount--; - - OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */ - - /* no need to check the Component glyph indices */ - - OTV_EXIT; - } - - - static void - otv_LigatureSubst_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt SubstFormat; - - - OTV_NAME_ENTER( "LigatureSubst" ); - - OTV_LIMIT_CHECK( 2 ); - SubstFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", SubstFormat )); - - switch ( SubstFormat ) - { - case 1: - OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB LOOKUP TYPE 5 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra1 (lookup count) */ - - static void - otv_ContextSubst_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt SubstFormat; - - - OTV_NAME_ENTER( "ContextSubst" ); - - OTV_LIMIT_CHECK( 2 ); - SubstFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", SubstFormat )); - - switch ( SubstFormat ) - { - case 1: - /* no need to check glyph indices/classes used as input for these */ - /* context rules since even invalid glyph indices/classes return */ - /* meaningful results */ - - valid->extra1 = valid->lookup_count; - OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule ); - OTV_RUN( table, valid ); - break; - - case 2: - /* no need to check glyph indices/classes used as input for these */ - /* context rules since even invalid glyph indices/classes return */ - /* meaningful results */ - - OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule ); - OTV_RUN( table, valid ); - break; - - case 3: - OTV_NEST1( ContextSubstFormat3 ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB LOOKUP TYPE 6 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->extra1 (lookup count) */ - - static void - otv_ChainContextSubst_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt SubstFormat; - - - OTV_NAME_ENTER( "ChainContextSubst" ); - - OTV_LIMIT_CHECK( 2 ); - SubstFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", SubstFormat )); - - switch ( SubstFormat ) - { - case 1: - /* no need to check glyph indices/classes used as input for these */ - /* context rules since even invalid glyph indices/classes return */ - /* meaningful results */ - - valid->extra1 = valid->lookup_count; - OTV_NEST3( ChainContextSubstFormat1, - ChainSubRuleSet, ChainSubRule ); - OTV_RUN( table, valid ); - break; - - case 2: - /* no need to check glyph indices/classes used as input for these */ - /* context rules since even invalid glyph indices/classes return */ - /* meaningful results */ - - OTV_NEST3( ChainContextSubstFormat2, - ChainSubClassSet, ChainSubClassRule ); - OTV_RUN( table, valid ); - break; - - case 3: - OTV_NEST1( ChainContextSubstFormat3 ); - OTV_RUN( table, valid ); - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB LOOKUP TYPE 7 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* uses valid->type_funcs */ - - static void - otv_ExtensionSubst_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt SubstFormat; - - - OTV_NAME_ENTER( "ExtensionSubst" ); - - OTV_LIMIT_CHECK( 2 ); - SubstFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", SubstFormat )); - - switch ( SubstFormat ) - { - case 1: /* ExtensionSubstFormat1 */ - { - FT_UInt ExtensionLookupType; - FT_ULong ExtensionOffset; - OTV_Validate_Func validate; - - - OTV_LIMIT_CHECK( 6 ); - ExtensionLookupType = FT_NEXT_USHORT( p ); - ExtensionOffset = FT_NEXT_ULONG( p ); - - if ( ExtensionLookupType == 0 || - ExtensionLookupType == 7 || - ExtensionLookupType > 8 ) - FT_INVALID_DATA; - - validate = valid->type_funcs[ExtensionLookupType - 1]; - validate( table + ExtensionOffset, valid ); - } - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB LOOKUP TYPE 8 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* uses valid->glyph_count */ - - static void - otv_ReverseChainSingleSubst_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table, Coverage; - FT_UInt SubstFormat; - FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount; - - - OTV_NAME_ENTER( "ReverseChainSingleSubst" ); - - OTV_LIMIT_CHECK( 2 ); - SubstFormat = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (format %d)\n", SubstFormat )); - - switch ( SubstFormat ) - { - case 1: /* ReverseChainSingleSubstFormat1 */ - OTV_LIMIT_CHECK( 4 ); - Coverage = table + FT_NEXT_USHORT( p ); - BacktrackGlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); - - otv_Coverage_validate( Coverage, valid, -1 ); - - OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); - - for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); - - LookaheadGlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); - - OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); - - for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); - - GlyphCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - - if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) - FT_INVALID_DATA; - - OTV_LIMIT_CHECK( GlyphCount * 2 ); - - /* Substitute */ - for ( ; GlyphCount > 0; GlyphCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) - FT_INVALID_DATA; - - break; - - default: - FT_INVALID_FORMAT; - } - - OTV_EXIT; - } - - - static const OTV_Validate_Func otv_gsub_validate_funcs[8] = - { - otv_SingleSubst_validate, - otv_MultipleSubst_validate, - otv_AlternateSubst_validate, - otv_LigatureSubst_validate, - otv_ContextSubst_validate, - otv_ChainContextSubst_validate, - otv_ExtensionSubst_validate, - otv_ReverseChainSingleSubst_validate - }; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GSUB TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->type_count */ - /* sets valid->type_funcs */ - /* sets valid->glyph_count */ - - FT_LOCAL_DEF( void ) - otv_GSUB_validate( FT_Bytes table, - FT_UInt glyph_count, - FT_Validator ftvalid ) - { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; - FT_UInt ScriptList, FeatureList, LookupList; - - - valid->root = ftvalid; - - FT_TRACE3(( "validating GSUB table\n" )); - OTV_INIT; - - OTV_LIMIT_CHECK( 10 ); - - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_FORMAT; - - ScriptList = FT_NEXT_USHORT( p ); - FeatureList = FT_NEXT_USHORT( p ); - LookupList = FT_NEXT_USHORT( p ); - - valid->type_count = 8; - valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; - valid->glyph_count = glyph_count; - - otv_LookupList_validate( table + LookupList, - valid ); - otv_FeatureList_validate( table + FeatureList, table + LookupList, - valid ); - otv_ScriptList_validate( table + ScriptList, table + FeatureList, - valid ); - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvjstf.c b/drivers/freetype/freetype/src/otvalid/otvjstf.c deleted file mode 100644 index a616a23432..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvjstf.c +++ /dev/null @@ -1,258 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvjstf.c */ -/* */ -/* OpenType JSTF table validation (body). */ -/* */ -/* Copyright 2004, 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 "otvalid.h" -#include "otvcommn.h" -#include "otvgpos.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_otvjstf - - -#define JstfPriorityFunc otv_JstfPriority_validate -#define JstfLookupFunc otv_GPOS_subtable_validate - - /* uses valid->extra1 (GSUB lookup count) */ - /* uses valid->extra2 (GPOS lookup count) */ - /* sets valid->extra1 (counter) */ - - static void - otv_JstfPriority_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt table_size; - FT_UInt gsub_lookup_count, gpos_lookup_count; - - OTV_OPTIONAL_TABLE( ShrinkageEnableGSUB ); - OTV_OPTIONAL_TABLE( ShrinkageDisableGSUB ); - OTV_OPTIONAL_TABLE( ShrinkageEnableGPOS ); - OTV_OPTIONAL_TABLE( ShrinkageDisableGPOS ); - OTV_OPTIONAL_TABLE( ExtensionEnableGSUB ); - OTV_OPTIONAL_TABLE( ExtensionDisableGSUB ); - OTV_OPTIONAL_TABLE( ExtensionEnableGPOS ); - OTV_OPTIONAL_TABLE( ExtensionDisableGPOS ); - OTV_OPTIONAL_TABLE( ShrinkageJstfMax ); - OTV_OPTIONAL_TABLE( ExtensionJstfMax ); - - - OTV_ENTER; - OTV_TRACE(( "JstfPriority table\n" )); - - OTV_LIMIT_CHECK( 20 ); - - gsub_lookup_count = valid->extra1; - gpos_lookup_count = valid->extra2; - - table_size = 20; - - valid->extra1 = gsub_lookup_count; - - OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB ); - OTV_SIZE_CHECK( ShrinkageEnableGSUB ); - if ( ShrinkageEnableGSUB ) - otv_x_ux( table + ShrinkageEnableGSUB, valid ); - - OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB ); - OTV_SIZE_CHECK( ShrinkageDisableGSUB ); - if ( ShrinkageDisableGSUB ) - otv_x_ux( table + ShrinkageDisableGSUB, valid ); - - valid->extra1 = gpos_lookup_count; - - OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS ); - OTV_SIZE_CHECK( ShrinkageEnableGPOS ); - if ( ShrinkageEnableGPOS ) - otv_x_ux( table + ShrinkageEnableGPOS, valid ); - - OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS ); - OTV_SIZE_CHECK( ShrinkageDisableGPOS ); - if ( ShrinkageDisableGPOS ) - otv_x_ux( table + ShrinkageDisableGPOS, valid ); - - OTV_OPTIONAL_OFFSET( ShrinkageJstfMax ); - OTV_SIZE_CHECK( ShrinkageJstfMax ); - if ( ShrinkageJstfMax ) - { - /* XXX: check lookup types? */ - OTV_NEST2( JstfMax, JstfLookup ); - OTV_RUN( table + ShrinkageJstfMax, valid ); - } - - valid->extra1 = gsub_lookup_count; - - OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB ); - OTV_SIZE_CHECK( ExtensionEnableGSUB ); - if ( ExtensionEnableGSUB ) - otv_x_ux( table + ExtensionEnableGSUB, valid ); - - OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB ); - OTV_SIZE_CHECK( ExtensionDisableGSUB ); - if ( ExtensionDisableGSUB ) - otv_x_ux( table + ExtensionDisableGSUB, valid ); - - valid->extra1 = gpos_lookup_count; - - OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS ); - OTV_SIZE_CHECK( ExtensionEnableGPOS ); - if ( ExtensionEnableGPOS ) - otv_x_ux( table + ExtensionEnableGPOS, valid ); - - OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS ); - OTV_SIZE_CHECK( ExtensionDisableGPOS ); - if ( ExtensionDisableGPOS ) - otv_x_ux( table + ExtensionDisableGPOS, valid ); - - OTV_OPTIONAL_OFFSET( ExtensionJstfMax ); - OTV_SIZE_CHECK( ExtensionJstfMax ); - if ( ExtensionJstfMax ) - { - /* XXX: check lookup types? */ - OTV_NEST2( JstfMax, JstfLookup ); - OTV_RUN( table + ExtensionJstfMax, valid ); - } - - valid->extra1 = gsub_lookup_count; - valid->extra2 = gpos_lookup_count; - - OTV_EXIT; - } - - - /* sets valid->extra (glyph count) */ - /* sets valid->func1 (otv_JstfPriority_validate) */ - - static void - otv_JstfScript_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt table_size; - FT_UInt JstfLangSysCount; - - OTV_OPTIONAL_TABLE( ExtGlyph ); - OTV_OPTIONAL_TABLE( DefJstfLangSys ); - - - OTV_NAME_ENTER( "JstfScript" ); - - OTV_LIMIT_CHECK( 6 ); - OTV_OPTIONAL_OFFSET( ExtGlyph ); - OTV_OPTIONAL_OFFSET( DefJstfLangSys ); - JstfLangSysCount = FT_NEXT_USHORT( p ); - - OTV_TRACE(( " (JstfLangSysCount = %d)\n", JstfLangSysCount )); - - table_size = JstfLangSysCount * 6 + 6; - - OTV_SIZE_CHECK( ExtGlyph ); - if ( ExtGlyph ) - { - valid->extra1 = valid->glyph_count; - OTV_NEST1( ExtenderGlyph ); - OTV_RUN( table + ExtGlyph, valid ); - } - - OTV_SIZE_CHECK( DefJstfLangSys ); - if ( DefJstfLangSys ) - { - OTV_NEST2( JstfLangSys, JstfPriority ); - OTV_RUN( table + DefJstfLangSys, valid ); - } - - OTV_LIMIT_CHECK( 6 * JstfLangSysCount ); - - /* JstfLangSysRecord */ - OTV_NEST2( JstfLangSys, JstfPriority ); - for ( ; JstfLangSysCount > 0; JstfLangSysCount-- ) - { - p += 4; /* skip JstfLangSysTag */ - - OTV_RUN( table + FT_NEXT_USHORT( p ), valid ); - } - - OTV_EXIT; - } - - - /* sets valid->extra1 (GSUB lookup count) */ - /* sets valid->extra2 (GPOS lookup count) */ - /* sets valid->glyph_count */ - - FT_LOCAL_DEF( void ) - otv_JSTF_validate( FT_Bytes table, - FT_Bytes gsub, - FT_Bytes gpos, - FT_UInt glyph_count, - FT_Validator ftvalid ) - { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; - FT_UInt JstfScriptCount; - - - valid->root = ftvalid; - - FT_TRACE3(( "validating JSTF table\n" )); - OTV_INIT; - - OTV_LIMIT_CHECK( 6 ); - - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_FORMAT; - - JstfScriptCount = FT_NEXT_USHORT( p ); - - FT_TRACE3(( " (JstfScriptCount = %d)\n", JstfScriptCount )); - - OTV_LIMIT_CHECK( JstfScriptCount * 6 ); - - if ( gsub ) - valid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); - else - valid->extra1 = 0; - - if ( gpos ) - valid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); - else - valid->extra2 = 0; - - valid->glyph_count = glyph_count; - - /* JstfScriptRecord */ - for ( ; JstfScriptCount > 0; JstfScriptCount-- ) - { - p += 4; /* skip JstfScriptTag */ - - /* JstfScript */ - otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), valid ); - } - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvmath.c b/drivers/freetype/freetype/src/otvalid/otvmath.c deleted file mode 100644 index 96f841f2a9..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvmath.c +++ /dev/null @@ -1,453 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvmath.c */ -/* */ -/* OpenType MATH table validation (body). */ -/* */ -/* Copyright 2007, 2008 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* Written by George Williams. */ -/* */ -/* 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 "otvalid.h" -#include "otvcommn.h" -#include "otvgpos.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_otvmath - - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MATH TYPOGRAPHIC CONSTANTS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_MathConstants_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt i; - FT_UInt table_size; - - OTV_OPTIONAL_TABLE( DeviceTableOffset ); - - - OTV_NAME_ENTER( "MathConstants" ); - - /* 56 constants, 51 have device tables */ - OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) ); - table_size = 2 * ( 56 + 51 ); - - p += 4 * 2; /* First 4 constants have no device tables */ - for ( i = 0; i < 51; ++i ) - { - p += 2; /* skip the value */ - OTV_OPTIONAL_OFFSET( DeviceTableOffset ); - OTV_SIZE_CHECK( DeviceTableOffset ); - if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MATH ITALICS CORRECTION *****/ - /***** MATH TOP ACCENT ATTACHMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, - OTV_Validator valid, - FT_Int isItalic ) - { - FT_Bytes p = table; - FT_UInt i, cnt, table_size ; - - OTV_OPTIONAL_TABLE( Coverage ); - OTV_OPTIONAL_TABLE( DeviceTableOffset ); - - FT_UNUSED( isItalic ); /* only used if tracing is active */ - - - OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo" - : "MathTopAccentAttachment" ); - - OTV_LIMIT_CHECK( 4 ); - - OTV_OPTIONAL_OFFSET( Coverage ); - cnt = FT_NEXT_USHORT( p ); - - OTV_LIMIT_CHECK( 4 * cnt ); - table_size = 4 + 4 * cnt; - - OTV_SIZE_CHECK( Coverage ); - otv_Coverage_validate( table + Coverage, valid, cnt ); - - for ( i = 0; i < cnt; ++i ) - { - p += 2; /* Skip the value */ - OTV_OPTIONAL_OFFSET( DeviceTableOffset ); - OTV_SIZE_CHECK( DeviceTableOffset ); - if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MATH KERNING *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_MathKern_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt i, cnt, table_size; - - OTV_OPTIONAL_TABLE( DeviceTableOffset ); - - - /* OTV_NAME_ENTER( "MathKern" );*/ - - OTV_LIMIT_CHECK( 2 ); - - cnt = FT_NEXT_USHORT( p ); - - OTV_LIMIT_CHECK( 4 * cnt + 2 ); - table_size = 4 + 4 * cnt; - - /* Heights */ - for ( i = 0; i < cnt; ++i ) - { - p += 2; /* Skip the value */ - OTV_OPTIONAL_OFFSET( DeviceTableOffset ); - OTV_SIZE_CHECK( DeviceTableOffset ); - if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); - } - - /* One more Kerning value */ - for ( i = 0; i < cnt + 1; ++i ) - { - p += 2; /* Skip the value */ - OTV_OPTIONAL_OFFSET( DeviceTableOffset ); - OTV_SIZE_CHECK( DeviceTableOffset ); - if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); - } - - OTV_EXIT; - } - - - static void - otv_MathKernInfo_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt i, j, cnt, table_size; - - OTV_OPTIONAL_TABLE( Coverage ); - OTV_OPTIONAL_TABLE( MKRecordOffset ); - - - OTV_NAME_ENTER( "MathKernInfo" ); - - OTV_LIMIT_CHECK( 4 ); - - OTV_OPTIONAL_OFFSET( Coverage ); - cnt = FT_NEXT_USHORT( p ); - - OTV_LIMIT_CHECK( 8 * cnt ); - table_size = 4 + 8 * cnt; - - OTV_SIZE_CHECK( Coverage ); - otv_Coverage_validate( table + Coverage, valid, cnt ); - - for ( i = 0; i < cnt; ++i ) - { - for ( j = 0; j < 4; ++j ) - { - OTV_OPTIONAL_OFFSET( MKRecordOffset ); - OTV_SIZE_CHECK( MKRecordOffset ); - if ( MKRecordOffset ) - otv_MathKern_validate( table + MKRecordOffset, valid ); - } - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MATH GLYPH INFO *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_MathGlyphInfo_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; - FT_UInt ExtendedShapeCoverage, MathKernInfo; - - - OTV_NAME_ENTER( "MathGlyphInfo" ); - - OTV_LIMIT_CHECK( 8 ); - - MathItalicsCorrectionInfo = FT_NEXT_USHORT( p ); - MathTopAccentAttachment = FT_NEXT_USHORT( p ); - ExtendedShapeCoverage = FT_NEXT_USHORT( p ); - MathKernInfo = FT_NEXT_USHORT( p ); - - if ( MathItalicsCorrectionInfo ) - otv_MathItalicsCorrectionInfo_validate( - table + MathItalicsCorrectionInfo, valid, TRUE ); - - /* Italic correction and Top Accent Attachment have the same format */ - if ( MathTopAccentAttachment ) - otv_MathItalicsCorrectionInfo_validate( - table + MathTopAccentAttachment, valid, FALSE ); - - if ( ExtendedShapeCoverage ) - { - OTV_NAME_ENTER( "ExtendedShapeCoverage" ); - otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 ); - OTV_EXIT; - } - - if ( MathKernInfo ) - otv_MathKernInfo_validate( table + MathKernInfo, valid ); - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MATH GLYPH CONSTRUCTION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - otv_GlyphAssembly_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt pcnt, table_size; - FT_UInt i; - - OTV_OPTIONAL_TABLE( DeviceTableOffset ); - - - /* OTV_NAME_ENTER( "GlyphAssembly" ); */ - - OTV_LIMIT_CHECK( 6 ); - - p += 2; /* Skip the Italics Correction value */ - OTV_OPTIONAL_OFFSET( DeviceTableOffset ); - pcnt = FT_NEXT_USHORT( p ); - - OTV_LIMIT_CHECK( 8 * pcnt ); - table_size = 6 + 8 * pcnt; - - OTV_SIZE_CHECK( DeviceTableOffset ); - if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); - - for ( i = 0; i < pcnt; ++i ) - { - FT_UInt gid; - - - gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) - FT_INVALID_GLYPH_ID; - p += 2*4; /* skip the Start, End, Full, and Flags fields */ - } - - /* OTV_EXIT; */ - } - - - static void - otv_MathGlyphConstruction_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt vcnt, table_size; - FT_UInt i; - - OTV_OPTIONAL_TABLE( GlyphAssembly ); - - - /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */ - - OTV_LIMIT_CHECK( 4 ); - - OTV_OPTIONAL_OFFSET( GlyphAssembly ); - vcnt = FT_NEXT_USHORT( p ); - - OTV_LIMIT_CHECK( 4 * vcnt ); - table_size = 4 + 4 * vcnt; - - for ( i = 0; i < vcnt; ++i ) - { - FT_UInt gid; - - - gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) - FT_INVALID_GLYPH_ID; - p += 2; /* skip the size */ - } - - OTV_SIZE_CHECK( GlyphAssembly ); - if ( GlyphAssembly ) - otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); - - /* OTV_EXIT; */ - } - - - static void - otv_MathVariants_validate( FT_Bytes table, - OTV_Validator valid ) - { - FT_Bytes p = table; - FT_UInt vcnt, hcnt, i, table_size; - - OTV_OPTIONAL_TABLE( VCoverage ); - OTV_OPTIONAL_TABLE( HCoverage ); - OTV_OPTIONAL_TABLE( Offset ); - - - OTV_NAME_ENTER( "MathVariants" ); - - OTV_LIMIT_CHECK( 10 ); - - p += 2; /* Skip the MinConnectorOverlap constant */ - OTV_OPTIONAL_OFFSET( VCoverage ); - OTV_OPTIONAL_OFFSET( HCoverage ); - vcnt = FT_NEXT_USHORT( p ); - hcnt = FT_NEXT_USHORT( p ); - - OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt ); - table_size = 10 + 2 * vcnt + 2 * hcnt; - - OTV_SIZE_CHECK( VCoverage ); - if ( VCoverage ) - otv_Coverage_validate( table + VCoverage, valid, vcnt ); - - OTV_SIZE_CHECK( HCoverage ); - if ( HCoverage ) - otv_Coverage_validate( table + HCoverage, valid, hcnt ); - - for ( i = 0; i < vcnt; ++i ) - { - OTV_OPTIONAL_OFFSET( Offset ); - OTV_SIZE_CHECK( Offset ); - otv_MathGlyphConstruction_validate( table + Offset, valid ); - } - - for ( i = 0; i < hcnt; ++i ) - { - OTV_OPTIONAL_OFFSET( Offset ); - OTV_SIZE_CHECK( Offset ); - otv_MathGlyphConstruction_validate( table + Offset, valid ); - } - - OTV_EXIT; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MATH TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* sets valid->glyph_count */ - - FT_LOCAL_DEF( void ) - otv_MATH_validate( FT_Bytes table, - FT_UInt glyph_count, - FT_Validator ftvalid ) - { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; - FT_UInt MathConstants, MathGlyphInfo, MathVariants; - - - valid->root = ftvalid; - - FT_TRACE3(( "validating MATH table\n" )); - OTV_INIT; - - OTV_LIMIT_CHECK( 10 ); - - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_FORMAT; - - MathConstants = FT_NEXT_USHORT( p ); - MathGlyphInfo = FT_NEXT_USHORT( p ); - MathVariants = FT_NEXT_USHORT( p ); - - valid->glyph_count = glyph_count; - - otv_MathConstants_validate( table + MathConstants, - valid ); - otv_MathGlyphInfo_validate( table + MathGlyphInfo, - valid ); - otv_MathVariants_validate ( table + MathVariants, - valid ); - - FT_TRACE4(( "\n" )); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvmod.c b/drivers/freetype/freetype/src/otvalid/otvmod.c deleted file mode 100644 index 37c6e869dd..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvmod.c +++ /dev/null @@ -1,282 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvmod.c */ -/* */ -/* FreeType's OpenType validation module implementation (body). */ -/* */ -/* Copyright 2004-2008, 2013 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_TRUETYPE_TABLES_H -#include FT_TRUETYPE_TAGS_H -#include FT_OPENTYPE_VALIDATE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_OPENTYPE_VALIDATE_H - -#include "otvmod.h" -#include "otvalid.h" -#include "otvcommn.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_otvmodule - - - static FT_Error - 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 ); - - - error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); - if ( FT_ERR_EQ( error, Table_Missing ) ) - return FT_Err_Ok; - if ( error ) - goto Exit; - - if ( FT_ALLOC( *table, *table_len ) ) - goto Exit; - - error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); - - Exit: - return error; - } - - - static FT_Error - 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 = FT_Err_Ok; - FT_Byte* volatile base; - FT_Byte* volatile gdef; - FT_Byte* volatile gpos; - FT_Byte* volatile gsub; - FT_Byte* volatile jstf; - FT_Byte* volatile math; - FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; - FT_ULong len_math; - FT_UInt num_glyphs = (FT_UInt)face->num_glyphs; - FT_ValidatorRec volatile valid; - - - base = gdef = gpos = gsub = jstf = math = NULL; - len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; - - /* - * XXX: OpenType tables cannot handle 32-bit glyph index, - * although broken TrueType can have 32-bit glyph index. - */ - if ( face->num_glyphs > 0xFFFFL ) - { - FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ", - face->num_glyphs )); - FT_TRACE1(( "are not handled by OpenType tables\n" )); - num_glyphs = 0xFFFF; - } - - /* load tables */ - - if ( ot_flags & FT_VALIDATE_BASE ) - { - error = otv_load_table( face, TTAG_BASE, &base, &len_base ); - if ( error ) - goto Exit; - } - - if ( ot_flags & FT_VALIDATE_GDEF ) - { - error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef ); - if ( error ) - goto Exit; - } - - if ( ot_flags & FT_VALIDATE_GPOS ) - { - error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos ); - if ( error ) - goto Exit; - } - - if ( ot_flags & FT_VALIDATE_GSUB ) - { - error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub ); - if ( error ) - goto Exit; - } - - if ( ot_flags & FT_VALIDATE_JSTF ) - { - error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf ); - if ( error ) - goto Exit; - } - - if ( ot_flags & FT_VALIDATE_MATH ) - { - error = otv_load_table( face, TTAG_MATH, &math, &len_math ); - if ( error ) - goto Exit; - } - - /* validate tables */ - - if ( base ) - { - ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT ); - if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_BASE_validate( base, &valid ); - error = valid.error; - if ( error ) - goto Exit; - } - - if ( gpos ) - { - ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); - if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GPOS_validate( gpos, num_glyphs, &valid ); - error = valid.error; - if ( error ) - goto Exit; - } - - if ( gsub ) - { - ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); - if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GSUB_validate( gsub, num_glyphs, &valid ); - error = valid.error; - if ( error ) - goto Exit; - } - - if ( gdef ) - { - ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); - if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid ); - error = valid.error; - if ( error ) - goto Exit; - } - - if ( jstf ) - { - ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); - if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid ); - error = valid.error; - if ( error ) - goto Exit; - } - - if ( math ) - { - ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); - if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_MATH_validate( math, num_glyphs, &valid ); - error = valid.error; - if ( error ) - goto Exit; - } - - *ot_base = (FT_Bytes)base; - *ot_gdef = (FT_Bytes)gdef; - *ot_gpos = (FT_Bytes)gpos; - *ot_gsub = (FT_Bytes)gsub; - *ot_jstf = (FT_Bytes)jstf; - - Exit: - if ( error ) - { - FT_Memory memory = FT_FACE_MEMORY( face ); - - - FT_FREE( base ); - FT_FREE( gdef ); - FT_FREE( gpos ); - FT_FREE( gsub ); - FT_FREE( jstf ); - } - - { - FT_Memory memory = FT_FACE_MEMORY( face ); - - - FT_FREE( math ); /* Can't return this as API is frozen */ - } - - return error; - } - - - static - const FT_Service_OTvalidateRec otvalid_interface = - { - otv_validate - }; - - - static - const FT_ServiceDescRec otvalid_services[] = - { - { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface }, - { NULL, NULL } - }; - - - static FT_Pointer - otvalid_get_service( FT_Module module, - const char* service_id ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( otvalid_services, service_id ); - } - - - FT_CALLBACK_TABLE_DEF - const FT_Module_Class otv_module_class = - { - 0, - sizeof ( FT_ModuleRec ), - "otvalid", - 0x10000L, - 0x20000L, - - 0, /* module-specific interface */ - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) otvalid_get_service - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvmod.h b/drivers/freetype/freetype/src/otvalid/otvmod.h deleted file mode 100644 index f7e1550787..0000000000 --- a/drivers/freetype/freetype/src/otvalid/otvmod.h +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************/ -/* */ -/* otvmod.h */ -/* */ -/* FreeType's OpenType validation module implementation */ -/* (specification). */ -/* */ -/* Copyright 2004 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 __OTVMOD_H__ -#define __OTVMOD_H__ - - -#include <ft2build.h> -#include FT_MODULE_H - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - - FT_EXPORT_VAR( const FT_Module_Class ) otv_module_class; - - -FT_END_HEADER - -#endif /* __OTVMOD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/otvalid/rules.mk b/drivers/freetype/freetype/src/otvalid/rules.mk deleted file mode 100644 index 53bd41e5e7..0000000000 --- a/drivers/freetype/freetype/src/otvalid/rules.mk +++ /dev/null @@ -1,78 +0,0 @@ -# -# FreeType 2 OpenType validation driver configuration rules -# - - -# Copyright 2004, 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. - - -# OTV driver directory -# -OTV_DIR := $(SRC_DIR)/otvalid - - -# compilation flags for the driver -# -OTV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(OTV_DIR)) - - -# OTV driver sources (i.e., C files) -# -OTV_DRV_SRC := $(OTV_DIR)/otvbase.c \ - $(OTV_DIR)/otvcommn.c \ - $(OTV_DIR)/otvgdef.c \ - $(OTV_DIR)/otvgpos.c \ - $(OTV_DIR)/otvgsub.c \ - $(OTV_DIR)/otvjstf.c \ - $(OTV_DIR)/otvmath.c \ - $(OTV_DIR)/otvmod.c - -# OTV driver headers -# -OTV_DRV_H := $(OTV_DIR)/otvalid.h \ - $(OTV_DIR)/otvcommn.h \ - $(OTV_DIR)/otverror.h \ - $(OTV_DIR)/otvgpos.h \ - $(OTV_DIR)/otvmod.h - - -# OTV driver object(s) -# -# OTV_DRV_OBJ_M is used during `multi' builds. -# OTV_DRV_OBJ_S is used during `single' builds. -# -OTV_DRV_OBJ_M := $(OTV_DRV_SRC:$(OTV_DIR)/%.c=$(OBJ_DIR)/%.$O) -OTV_DRV_OBJ_S := $(OBJ_DIR)/otvalid.$O - -# OTV driver source file for single build -# -OTV_DRV_SRC_S := $(OTV_DIR)/otvalid.c - - -# OTV driver - single object -# -$(OTV_DRV_OBJ_S): $(OTV_DRV_SRC_S) $(OTV_DRV_SRC) \ - $(FREETYPE_H) $(OTV_DRV_H) - $(OTV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(OTV_DRV_SRC_S)) - - -# OTV driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(OTV_DIR)/%.c $(FREETYPE_H) $(OTV_DRV_H) - $(OTV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(OTV_DRV_OBJ_S) -DRV_OBJS_M += $(OTV_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/pcf/Jamfile b/drivers/freetype/freetype/src/pcf/Jamfile deleted file mode 100644 index 752fcac2a1..0000000000 --- a/drivers/freetype/freetype/src/pcf/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/pcf Jamfile -# -# Copyright 2001, 2003 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) pcf ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = pcfdrivr pcfread pcfutil ; - } - else - { - _sources = pcf ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/pcf Jamfile diff --git a/drivers/freetype/freetype/src/pcf/README b/drivers/freetype/freetype/src/pcf/README deleted file mode 100644 index 10eff15fbe..0000000000 --- a/drivers/freetype/freetype/src/pcf/README +++ /dev/null @@ -1,96 +0,0 @@ - FreeType font driver for PCF fonts - - Francesco Zappa Nardelli - <francesco.zappa.nardelli@ens.fr> - - -Introduction -************ - -PCF (Portable Compiled Format) is a binary bitmap font format, largely used -in X world. This code implements a PCF driver for the FreeType library. -Glyph images are loaded into memory only on demand, thus leading to a small -memory footprint. - -Information on the PCF font format can only be worked out from -`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. - - -Supported hardware -****************** - -The driver has been tested on linux/x86 and sunos5.5/sparc. In both -cases the compiler was gcc. When back in Paris, I will test it also -on linux/alpha. - - -Encodings -********* - -Use `FT_Get_BDF_Charset_ID' to access the encoding and registry. - -The driver always exports `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. - - -Known problems -************** - -- dealing explicitly with encodings breaks the uniformity of freetype2 - api. - -- except for encodings properties, client applications have no - visibility of the PCF_Face object. This means that applications - cannot directly access font tables and are obliged to trust - FreeType. - -- currently, glyph names and ink_metrics are ignored. - -I plan to give full visibility of the PCF_Face object in the next -release of the driver, thus implementing also glyph names and -ink_metrics. - -- height is defined as (ascent - descent). Is this correct? - -- if unable to read size information from the font, PCF_Init_Face - sets available_size->width and available_size->height to 12. - -- too many english grammar errors in the readme file :-( - - -License -******* - -Copyright (C) 2000 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 to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -Credits -******* - -Keith Packard wrote the pcf driver found in XFree86. His work is at -the same time the specification and the sample implementation of the -PCF format. Undoubtedly, this driver is inspired from his work. diff --git a/drivers/freetype/freetype/src/pcf/module.mk b/drivers/freetype/freetype/src/pcf/module.mk deleted file mode 100644 index df383ff0fb..0000000000 --- a/drivers/freetype/freetype/src/pcf/module.mk +++ /dev/null @@ -1,34 +0,0 @@ -# -# FreeType 2 PCF module definition -# - -# 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 -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - -FTMODULE_H_COMMANDS += PCF_DRIVER - -define PCF_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, pcf_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)pcf $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/pcf/pcf.c b/drivers/freetype/freetype/src/pcf/pcf.c deleted file mode 100644 index 11d5b7b2a0..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcf.c +++ /dev/null @@ -1,36 +0,0 @@ -/* pcf.c - - FreeType font driver for pcf fonts - - Copyright 2000-2001, 2003 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#include <ft2build.h> -#include "pcfutil.c" -#include "pcfread.c" -#include "pcfdrivr.c" - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcf.h b/drivers/freetype/freetype/src/pcf/pcf.h deleted file mode 100644 index af0ffc3378..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcf.h +++ /dev/null @@ -1,237 +0,0 @@ -/* pcf.h - - FreeType font driver for pcf fonts - - Copyright (C) 2000, 2001, 2002, 2003, 2006, 2010 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - - -#ifndef __PCF_H__ -#define __PCF_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H -#include FT_INTERNAL_STREAM_H - - -FT_BEGIN_HEADER - - typedef struct PCF_TableRec_ - { - FT_ULong type; - FT_ULong format; - FT_ULong size; - FT_ULong offset; - - } PCF_TableRec, *PCF_Table; - - - typedef struct PCF_TocRec_ - { - FT_ULong version; - FT_ULong count; - PCF_Table tables; - - } PCF_TocRec, *PCF_Toc; - - - typedef struct PCF_ParsePropertyRec_ - { - FT_Long name; - FT_Byte isString; - FT_Long value; - - } PCF_ParsePropertyRec, *PCF_ParseProperty; - - - typedef struct PCF_PropertyRec_ - { - FT_String* name; - FT_Byte isString; - - union - { - FT_String* atom; - FT_Long l; - FT_ULong ul; - - } value; - - } PCF_PropertyRec, *PCF_Property; - - - typedef struct PCF_Compressed_MetricRec_ - { - FT_Byte leftSideBearing; - FT_Byte rightSideBearing; - FT_Byte characterWidth; - FT_Byte ascent; - FT_Byte descent; - - } PCF_Compressed_MetricRec, *PCF_Compressed_Metric; - - - typedef struct PCF_MetricRec_ - { - FT_Short leftSideBearing; - FT_Short rightSideBearing; - FT_Short characterWidth; - FT_Short ascent; - FT_Short descent; - FT_Short attributes; - FT_ULong bits; - - } PCF_MetricRec, *PCF_Metric; - - - typedef struct PCF_AccelRec_ - { - FT_Byte noOverlap; - FT_Byte constantMetrics; - FT_Byte terminalFont; - FT_Byte constantWidth; - FT_Byte inkInside; - FT_Byte inkMetrics; - FT_Byte drawDirection; - FT_Long fontAscent; - FT_Long fontDescent; - FT_Long maxOverlap; - PCF_MetricRec minbounds; - PCF_MetricRec maxbounds; - PCF_MetricRec ink_minbounds; - PCF_MetricRec ink_maxbounds; - - } PCF_AccelRec, *PCF_Accel; - - - typedef struct PCF_EncodingRec_ - { - FT_Long enc; - FT_UShort glyph; - - } PCF_EncodingRec, *PCF_Encoding; - - - typedef struct PCF_FaceRec_ - { - FT_FaceRec root; - - FT_StreamRec comp_stream; - FT_Stream comp_source; - - char* charset_encoding; - char* charset_registry; - - PCF_TocRec toc; - PCF_AccelRec accel; - - int nprops; - PCF_Property properties; - - FT_Long nmetrics; - PCF_Metric metrics; - FT_Long nencodings; - PCF_Encoding encodings; - - FT_Short defaultChar; - - FT_ULong bitmapsFormat; - - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ - - } PCF_FaceRec, *PCF_Face; - - - /* macros for pcf font format */ - -#define LSBFirst 0 -#define MSBFirst 1 - -#define PCF_FILE_VERSION ( ( 'p' << 24 ) | \ - ( 'c' << 16 ) | \ - ( 'f' << 8 ) | 1 ) -#define PCF_FORMAT_MASK 0xFFFFFF00UL - -#define PCF_DEFAULT_FORMAT 0x00000000UL -#define PCF_INKBOUNDS 0x00000200UL -#define PCF_ACCEL_W_INKBOUNDS 0x00000100UL -#define PCF_COMPRESSED_METRICS 0x00000100UL - -#define PCF_FORMAT_MATCH( a, b ) \ - ( ( (a) & PCF_FORMAT_MASK ) == ( (b) & PCF_FORMAT_MASK ) ) - -#define PCF_GLYPH_PAD_MASK ( 3 << 0 ) -#define PCF_BYTE_MASK ( 1 << 2 ) -#define PCF_BIT_MASK ( 1 << 3 ) -#define PCF_SCAN_UNIT_MASK ( 3 << 4 ) - -#define PCF_BYTE_ORDER( f ) \ - ( ( (f) & PCF_BYTE_MASK ) ? MSBFirst : LSBFirst ) -#define PCF_BIT_ORDER( f ) \ - ( ( (f) & PCF_BIT_MASK ) ? MSBFirst : LSBFirst ) -#define PCF_GLYPH_PAD_INDEX( f ) \ - ( (f) & PCF_GLYPH_PAD_MASK ) -#define PCF_GLYPH_PAD( f ) \ - ( 1 << PCF_GLYPH_PAD_INDEX( f ) ) -#define PCF_SCAN_UNIT_INDEX( f ) \ - ( ( (f) & PCF_SCAN_UNIT_MASK ) >> 4 ) -#define PCF_SCAN_UNIT( f ) \ - ( 1 << PCF_SCAN_UNIT_INDEX( f ) ) -#define PCF_FORMAT_BITS( f ) \ - ( (f) & ( PCF_GLYPH_PAD_MASK | \ - PCF_BYTE_MASK | \ - PCF_BIT_MASK | \ - PCF_SCAN_UNIT_MASK ) ) - -#define PCF_SIZE_TO_INDEX( s ) ( (s) == 4 ? 2 : (s) == 2 ? 1 : 0 ) -#define PCF_INDEX_TO_SIZE( b ) ( 1 << b ) - -#define PCF_FORMAT( bit, byte, glyph, scan ) \ - ( ( PCF_SIZE_TO_INDEX( scan ) << 4 ) | \ - ( ( (bit) == MSBFirst ? 1 : 0 ) << 3 ) | \ - ( ( (byte) == MSBFirst ? 1 : 0 ) << 2 ) | \ - ( PCF_SIZE_TO_INDEX( glyph ) << 0 ) ) - -#define PCF_PROPERTIES ( 1 << 0 ) -#define PCF_ACCELERATORS ( 1 << 1 ) -#define PCF_METRICS ( 1 << 2 ) -#define PCF_BITMAPS ( 1 << 3 ) -#define PCF_INK_METRICS ( 1 << 4 ) -#define PCF_BDF_ENCODINGS ( 1 << 5 ) -#define PCF_SWIDTHS ( 1 << 6 ) -#define PCF_GLYPH_NAMES ( 1 << 7 ) -#define PCF_BDF_ACCELERATORS ( 1 << 8 ) - -#define GLYPHPADOPTIONS 4 /* I'm not sure about this */ - - FT_LOCAL( FT_Error ) - pcf_load_font( FT_Stream, - PCF_Face ); - -FT_END_HEADER - -#endif /* __PCF_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfdrivr.c b/drivers/freetype/freetype/src/pcf/pcfdrivr.c deleted file mode 100644 index df25a645a0..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcfdrivr.c +++ /dev/null @@ -1,713 +0,0 @@ -/* pcfdrivr.c - - FreeType font driver for pcf files - - Copyright (C) 2000-2004, 2006-2011, 2013 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - - -#include <ft2build.h> - -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_OBJECTS_H -#include FT_GZIP_H -#include FT_LZW_H -#include FT_BZIP2_H -#include FT_ERRORS_H -#include FT_BDF_H -#include FT_TRUETYPE_IDS_H - -#include "pcf.h" -#include "pcfdrivr.h" -#include "pcfread.h" - -#include "pcferror.h" -#include "pcfutil.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pcfread - -#include FT_SERVICE_BDF_H -#include FT_SERVICE_XFREE86_NAME_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_pcfdriver - - - typedef struct PCF_CMapRec_ - { - FT_CMapRec root; - FT_UInt num_encodings; - PCF_Encoding encodings; - - } PCF_CMapRec, *PCF_CMap; - - - FT_CALLBACK_DEF( FT_Error ) - pcf_cmap_init( FT_CMap pcfcmap, /* PCF_CMap */ - FT_Pointer init_data ) - { - PCF_CMap cmap = (PCF_CMap)pcfcmap; - PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap ); - - FT_UNUSED( init_data ); - - - cmap->num_encodings = (FT_UInt)face->nencodings; - cmap->encodings = face->encodings; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( void ) - pcf_cmap_done( FT_CMap pcfcmap ) /* PCF_CMap */ - { - PCF_CMap cmap = (PCF_CMap)pcfcmap; - - - cmap->encodings = NULL; - cmap->num_encodings = 0; - } - - - FT_CALLBACK_DEF( FT_UInt ) - pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */ - FT_UInt32 charcode ) - { - PCF_CMap cmap = (PCF_CMap)pcfcmap; - PCF_Encoding encodings = cmap->encodings; - FT_UInt min, max, mid; - FT_UInt result = 0; - - - min = 0; - max = cmap->num_encodings; - - while ( min < max ) - { - FT_ULong code; - - - mid = ( min + max ) >> 1; - code = encodings[mid].enc; - - if ( charcode == code ) - { - result = encodings[mid].glyph + 1; - break; - } - - if ( charcode < code ) - max = mid; - else - min = mid + 1; - } - - return result; - } - - - FT_CALLBACK_DEF( FT_UInt ) - pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */ - FT_UInt32 *acharcode ) - { - PCF_CMap cmap = (PCF_CMap)pcfcmap; - PCF_Encoding encodings = cmap->encodings; - FT_UInt min, max, mid; - FT_ULong charcode = *acharcode + 1; - FT_UInt result = 0; - - - min = 0; - max = cmap->num_encodings; - - while ( min < max ) - { - FT_ULong code; - - - mid = ( min + max ) >> 1; - code = encodings[mid].enc; - - if ( charcode == code ) - { - result = encodings[mid].glyph + 1; - goto Exit; - } - - if ( charcode < code ) - max = mid; - else - min = mid + 1; - } - - charcode = 0; - if ( min < cmap->num_encodings ) - { - charcode = encodings[min].enc; - result = encodings[min].glyph + 1; - } - - Exit: - if ( charcode > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" )); - *acharcode = 0; - /* XXX: result should be changed to indicate an overflow error */ - } - else - *acharcode = (FT_UInt32)charcode; - return result; - } - - - FT_CALLBACK_TABLE_DEF - const FT_CMap_ClassRec pcf_cmap_class = - { - sizeof ( PCF_CMapRec ), - pcf_cmap_init, - pcf_cmap_done, - pcf_cmap_char_index, - pcf_cmap_char_next, - - NULL, NULL, NULL, NULL, NULL - }; - - - FT_CALLBACK_DEF( void ) - PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */ - { - PCF_Face face = (PCF_Face)pcfface; - FT_Memory memory; - - - if ( !face ) - return; - - memory = FT_FACE_MEMORY( face ); - - FT_FREE( face->encodings ); - FT_FREE( face->metrics ); - - /* free properties */ - { - PCF_Property prop; - FT_Int i; - - - if ( face->properties ) - { - for ( i = 0; i < face->nprops; i++ ) - { - prop = &face->properties[i]; - - if ( prop ) - { - FT_FREE( prop->name ); - if ( prop->isString ) - FT_FREE( prop->value.atom ); - } - } - } - FT_FREE( face->properties ); - } - - FT_FREE( face->toc.tables ); - FT_FREE( pcfface->family_name ); - FT_FREE( pcfface->style_name ); - FT_FREE( pcfface->available_sizes ); - FT_FREE( face->charset_encoding ); - FT_FREE( face->charset_registry ); - - /* close compressed stream if any */ - if ( pcfface->stream == &face->comp_stream ) - { - FT_Stream_Close( &face->comp_stream ); - pcfface->stream = face->comp_source; - } - } - - - FT_CALLBACK_DEF( FT_Error ) - PCF_Face_Init( FT_Stream stream, - FT_Face pcfface, /* PCF_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - PCF_Face face = (PCF_Face)pcfface; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - - - FT_TRACE2(( "PCF driver\n" )); - - error = pcf_load_font( stream, face ); - if ( error ) - { - PCF_Face_Done( pcfface ); - -#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ - defined( FT_CONFIG_OPTION_USE_LZW ) || \ - defined( FT_CONFIG_OPTION_USE_BZIP2 ) - -#ifdef FT_CONFIG_OPTION_USE_ZLIB - { - FT_Error error2; - - - /* this didn't work, try gzip support! */ - error2 = FT_Stream_OpenGzip( &face->comp_stream, stream ); - if ( FT_ERR_EQ( error2, Unimplemented_Feature ) ) - goto Fail; - - error = error2; - } -#endif /* FT_CONFIG_OPTION_USE_ZLIB */ - -#ifdef FT_CONFIG_OPTION_USE_LZW - if ( error ) - { - FT_Error error3; - - - /* this didn't work, try LZW support! */ - error3 = FT_Stream_OpenLZW( &face->comp_stream, stream ); - if ( FT_ERR_EQ( error3, Unimplemented_Feature ) ) - goto Fail; - - error = error3; - } -#endif /* FT_CONFIG_OPTION_USE_LZW */ - -#ifdef FT_CONFIG_OPTION_USE_BZIP2 - if ( error ) - { - FT_Error error4; - - - /* this didn't work, try Bzip2 support! */ - error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream ); - if ( FT_ERR_EQ( error4, Unimplemented_Feature ) ) - goto Fail; - - error = error4; - } -#endif /* FT_CONFIG_OPTION_USE_BZIP2 */ - - if ( error ) - goto Fail; - - face->comp_source = stream; - pcfface->stream = &face->comp_stream; - - stream = pcfface->stream; - - error = pcf_load_font( stream, face ); - if ( error ) - goto Fail; - -#else /* !(FT_CONFIG_OPTION_USE_ZLIB || - FT_CONFIG_OPTION_USE_LZW || - FT_CONFIG_OPTION_USE_BZIP2) */ - - goto Fail; - -#endif - } - - /* set up charmap */ - { - FT_String *charset_registry = face->charset_registry; - FT_String *charset_encoding = face->charset_encoding; - FT_Bool unicode_charmap = 0; - - - if ( charset_registry && charset_encoding ) - { - char* s = charset_registry; - - - /* Uh, oh, compare first letters manually to avoid dependency - on locales. */ - if ( ( s[0] == 'i' || s[0] == 'I' ) && - ( s[1] == 's' || s[1] == 'S' ) && - ( s[2] == 'o' || s[2] == 'O' ) ) - { - s += 3; - if ( !ft_strcmp( s, "10646" ) || - ( !ft_strcmp( s, "8859" ) && - !ft_strcmp( face->charset_encoding, "1" ) ) ) - unicode_charmap = 1; - } - } - - { - FT_CharMapRec charmap; - - - charmap.face = FT_FACE( face ); - charmap.encoding = FT_ENCODING_NONE; - /* initial platform/encoding should indicate unset status? */ - charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; - charmap.encoding_id = TT_APPLE_ID_DEFAULT; - - if ( unicode_charmap ) - { - charmap.encoding = FT_ENCODING_UNICODE; - charmap.platform_id = TT_PLATFORM_MICROSOFT; - charmap.encoding_id = TT_MS_ID_UNICODE_CS; - } - - error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( pcfface->num_charmaps ) - pcfface->charmap = pcfface->charmaps[0]; -#endif - } - } - - Exit: - return error; - - Fail: - FT_TRACE2(( " not a PCF file\n" )); - PCF_Face_Done( pcfface ); - error = FT_THROW( Unknown_File_Format ); /* error */ - goto Exit; - } - - - FT_CALLBACK_DEF( FT_Error ) - PCF_Size_Select( FT_Size size, - FT_ULong strike_index ) - { - PCF_Accel accel = &( (PCF_Face)size->face )->accel; - - - FT_Select_Metrics( size->face, strike_index ); - - size->metrics.ascender = accel->fontAscent << 6; - size->metrics.descender = -accel->fontDescent << 6; - size->metrics.max_advance = accel->maxbounds.characterWidth << 6; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_Error ) - PCF_Size_Request( FT_Size size, - FT_Size_Request req ) - { - PCF_Face face = (PCF_Face)size->face; - FT_Bitmap_Size* bsize = size->face->available_sizes; - FT_Error error = FT_ERR( Invalid_Pixel_Size ); - FT_Long height; - - - height = FT_REQUEST_HEIGHT( req ); - height = ( height + 32 ) >> 6; - - switch ( req->type ) - { - case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) - error = FT_Err_Ok; - break; - - case FT_SIZE_REQUEST_TYPE_REAL_DIM: - if ( height == ( face->accel.fontAscent + - face->accel.fontDescent ) ) - error = FT_Err_Ok; - break; - - default: - error = FT_THROW( Unimplemented_Feature ); - break; - } - - if ( error ) - return error; - else - return PCF_Size_Select( size, 0 ); - } - - - FT_CALLBACK_DEF( FT_Error ) - PCF_Glyph_Load( FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); - FT_Stream stream; - FT_Error error = FT_Err_Ok; - FT_Bitmap* bitmap = &slot->bitmap; - PCF_Metric metric; - FT_Offset bytes; - - FT_UNUSED( load_flags ); - - - FT_TRACE4(( "load_glyph %d ---", glyph_index )); - - if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - stream = face->root.stream; - - if ( glyph_index > 0 ) - glyph_index--; - - metric = face->metrics + glyph_index; - - bitmap->rows = metric->ascent + metric->descent; - bitmap->width = metric->rightSideBearing - metric->leftSideBearing; - bitmap->num_grays = 1; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - - FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n", - PCF_BIT_ORDER( face->bitmapsFormat ), - PCF_BYTE_ORDER( face->bitmapsFormat ), - PCF_GLYPH_PAD( face->bitmapsFormat ) )); - - switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) - { - case 1: - bitmap->pitch = ( bitmap->width + 7 ) >> 3; - break; - - case 2: - bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; - break; - - case 4: - bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; - break; - - case 8: - bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; - break; - - default: - return FT_THROW( Invalid_File_Format ); - } - - /* XXX: to do: are there cases that need repadding the bitmap? */ - bytes = bitmap->pitch * bitmap->rows; - - error = ft_glyphslot_alloc_bitmap( slot, (FT_ULong)bytes ); - if ( error ) - goto Exit; - - if ( FT_STREAM_SEEK( metric->bits ) || - FT_STREAM_READ( bitmap->buffer, bytes ) ) - goto Exit; - - if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst ) - BitOrderInvert( bitmap->buffer, bytes ); - - if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) != - PCF_BIT_ORDER( face->bitmapsFormat ) ) ) - { - switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) ) - { - case 1: - break; - - case 2: - TwoByteSwap( bitmap->buffer, bytes ); - break; - - case 4: - FourByteSwap( bitmap->buffer, bytes ); - break; - } - } - - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = metric->leftSideBearing; - slot->bitmap_top = metric->ascent; - - slot->metrics.horiAdvance = metric->characterWidth << 6; - slot->metrics.horiBearingX = metric->leftSideBearing << 6; - slot->metrics.horiBearingY = metric->ascent << 6; - slot->metrics.width = ( metric->rightSideBearing - - metric->leftSideBearing ) << 6; - slot->metrics.height = bitmap->rows << 6; - - ft_synthesize_vertical_metrics( &slot->metrics, - ( face->accel.fontAscent + - face->accel.fontDescent ) << 6 ); - - FT_TRACE4(( " --- ok\n" )); - - Exit: - return error; - } - - - /* - * - * BDF SERVICE - * - */ - - static FT_Error - pcf_get_bdf_property( PCF_Face face, - const char* prop_name, - BDF_PropertyRec *aproperty ) - { - PCF_Property prop; - - - prop = pcf_find_property( face, prop_name ); - if ( prop != NULL ) - { - if ( prop->isString ) - { - aproperty->type = BDF_PROPERTY_TYPE_ATOM; - aproperty->u.atom = prop->value.atom; - } - else - { - if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) - { - FT_TRACE1(( "pcf_get_bdf_property: " )); - FT_TRACE1(( "too large integer 0x%x is truncated\n" )); - } - /* Apparently, the PCF driver loads all properties as signed integers! - * This really doesn't seem to be a problem, because this is - * sufficient for any meaningful values. - */ - aproperty->type = BDF_PROPERTY_TYPE_INTEGER; - aproperty->u.integer = (FT_Int32)prop->value.l; - } - return 0; - } - - return FT_THROW( Invalid_Argument ); - } - - - static FT_Error - pcf_get_charset_id( PCF_Face face, - const char* *acharset_encoding, - const char* *acharset_registry ) - { - *acharset_encoding = face->charset_encoding; - *acharset_registry = face->charset_registry; - - return 0; - } - - - static const FT_Service_BDFRec pcf_service_bdf = - { - (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, - (FT_BDF_GetPropertyFunc) pcf_get_bdf_property - }; - - - /* - * - * SERVICE LIST - * - */ - - static const FT_ServiceDescRec pcf_services[] = - { - { FT_SERVICE_ID_BDF, &pcf_service_bdf }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, - { NULL, NULL } - }; - - - FT_CALLBACK_DEF( FT_Module_Interface ) - pcf_driver_requester( FT_Module module, - const char* name ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( pcf_services, name ); - } - - - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec pcf_driver_class = - { - { - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_NO_OUTLINES, - sizeof ( FT_DriverRec ), - - "pcf", - 0x10000L, - 0x20000L, - - 0, - - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - pcf_driver_requester - }, - - sizeof ( PCF_FaceRec ), - sizeof ( FT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - - PCF_Face_Init, - PCF_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ - - PCF_Glyph_Load, - - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ - - PCF_Size_Request, - PCF_Size_Select - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfdrivr.h b/drivers/freetype/freetype/src/pcf/pcfdrivr.h deleted file mode 100644 index 54614951b5..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcfdrivr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* pcfdrivr.h - - FreeType font driver for pcf fonts - - Copyright 2000-2001, 2002 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - - -#ifndef __PCFDRIVR_H__ -#define __PCFDRIVR_H__ - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) pcf_driver_class; - -FT_END_HEADER - - -#endif /* __PCFDRIVR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcferror.h b/drivers/freetype/freetype/src/pcf/pcferror.h deleted file mode 100644 index e51fff8ea6..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcferror.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* pcferror.h */ -/* */ -/* PCF error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PCF error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __PCFERROR_H__ -#define __PCFERROR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PCF_Err_ -#define FT_ERR_BASE FT_Mod_Err_PCF - -#include FT_ERRORS_H - -#endif /* __PCFERROR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfread.c b/drivers/freetype/freetype/src/pcf/pcfread.c deleted file mode 100644 index 3c1bb7dfa2..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcfread.c +++ /dev/null @@ -1,1269 +0,0 @@ -/* pcfread.c - - FreeType font driver for pcf fonts - - Copyright 2000-2010, 2012, 2013 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - - -#include <ft2build.h> - -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_OBJECTS_H - -#include "pcf.h" -#include "pcfread.h" - -#include "pcferror.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_pcfread - - -#ifdef FT_DEBUG_LEVEL_TRACE - static const char* const tableNames[] = - { - "prop", "accl", "mtrcs", "bmps", "imtrcs", - "enc", "swidth", "names", "accel" - }; -#endif - - - static - const FT_Frame_Field pcf_toc_header[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PCF_TocRec - - FT_FRAME_START( 8 ), - FT_FRAME_ULONG_LE( version ), - FT_FRAME_ULONG_LE( count ), - FT_FRAME_END - }; - - - static - const FT_Frame_Field pcf_table_header[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PCF_TableRec - - FT_FRAME_START( 16 ), - FT_FRAME_ULONG_LE( type ), - FT_FRAME_ULONG_LE( format ), - FT_FRAME_ULONG_LE( size ), - FT_FRAME_ULONG_LE( offset ), - FT_FRAME_END - }; - - - static FT_Error - pcf_read_TOC( FT_Stream stream, - PCF_Face face ) - { - FT_Error error; - PCF_Toc toc = &face->toc; - PCF_Table tables; - - FT_Memory memory = FT_FACE( face )->memory; - FT_UInt n; - - - if ( FT_STREAM_SEEK ( 0 ) || - FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) - return FT_THROW( Cannot_Open_Resource ); - - if ( toc->version != PCF_FILE_VERSION || - toc->count > FT_ARRAY_MAX( face->toc.tables ) || - toc->count == 0 ) - return FT_THROW( Invalid_File_Format ); - - if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) - return FT_THROW( Out_Of_Memory ); - - tables = face->toc.tables; - for ( n = 0; n < toc->count; n++ ) - { - if ( FT_STREAM_READ_FIELDS( pcf_table_header, tables ) ) - goto Exit; - 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 FT_THROW( Invalid_Offset ); - } - - if ( !have_change ) - break; - } - -#ifdef FT_DEBUG_LEVEL_TRACE - - { - FT_UInt i, j; - const char* name = "?"; - - - FT_TRACE4(( "pcf_read_TOC:\n" )); - - FT_TRACE4(( " number of tables: %ld\n", face->toc.count )); - - tables = face->toc.tables; - for ( i = 0; i < toc->count; i++ ) - { - for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); - j++ ) - if ( tables[i].type == (FT_UInt)( 1 << j ) ) - name = tableNames[j]; - - FT_TRACE4(( " %d: type=%s, format=0x%X, " - "size=%ld (0x%lX), offset=%ld (0x%lX)\n", - i, name, - tables[i].format, - tables[i].size, tables[i].size, - tables[i].offset, tables[i].offset )); - } - } - -#endif - - return FT_Err_Ok; - - Exit: - FT_FREE( face->toc.tables ); - return error; - } - - -#define PCF_METRIC_SIZE 12 - - static - const FT_Frame_Field pcf_metric_header[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PCF_MetricRec - - FT_FRAME_START( PCF_METRIC_SIZE ), - FT_FRAME_SHORT_LE( leftSideBearing ), - FT_FRAME_SHORT_LE( rightSideBearing ), - FT_FRAME_SHORT_LE( characterWidth ), - FT_FRAME_SHORT_LE( ascent ), - FT_FRAME_SHORT_LE( descent ), - FT_FRAME_SHORT_LE( attributes ), - FT_FRAME_END - }; - - - static - const FT_Frame_Field pcf_metric_msb_header[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PCF_MetricRec - - FT_FRAME_START( PCF_METRIC_SIZE ), - FT_FRAME_SHORT( leftSideBearing ), - FT_FRAME_SHORT( rightSideBearing ), - FT_FRAME_SHORT( characterWidth ), - FT_FRAME_SHORT( ascent ), - FT_FRAME_SHORT( descent ), - FT_FRAME_SHORT( attributes ), - FT_FRAME_END - }; - - -#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( PCF_COMPRESSED_METRIC_SIZE ), - FT_FRAME_BYTE( leftSideBearing ), - FT_FRAME_BYTE( rightSideBearing ), - FT_FRAME_BYTE( characterWidth ), - FT_FRAME_BYTE( ascent ), - FT_FRAME_BYTE( descent ), - FT_FRAME_END - }; - - - static FT_Error - pcf_get_metric( FT_Stream stream, - FT_ULong format, - PCF_Metric metric ) - { - FT_Error error = FT_Err_Ok; - - - if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) - { - const FT_Frame_Field* fields; - - - /* parsing normal metrics */ - fields = PCF_BYTE_ORDER( format ) == MSBFirst - ? pcf_metric_msb_header - : pcf_metric_header; - - /* the following sets `error' but doesn't return in case of failure */ - (void)FT_STREAM_READ_FIELDS( fields, metric ); - } - else - { - PCF_Compressed_MetricRec compr; - - - /* parsing compressed metrics */ - if ( FT_STREAM_READ_FIELDS( pcf_compressed_metric_header, &compr ) ) - goto Exit; - - metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 ); - metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 ); - metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 ); - metric->ascent = (FT_Short)( compr.ascent - 0x80 ); - metric->descent = (FT_Short)( compr.descent - 0x80 ); - metric->attributes = 0; - } - - Exit: - return error; - } - - - static FT_Error - pcf_seek_to_table_type( FT_Stream stream, - PCF_Table tables, - FT_ULong ntables, /* same as PCF_Toc->count */ - FT_ULong type, - FT_ULong *aformat, - FT_ULong *asize ) - { - FT_Error error = FT_ERR( Invalid_File_Format ); - FT_ULong i; - - - for ( i = 0; i < ntables; i++ ) - if ( tables[i].type == type ) - { - if ( stream->pos > tables[i].offset ) - { - error = FT_THROW( Invalid_Stream_Skip ); - goto Fail; - } - - if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) - { - error = FT_THROW( Invalid_Stream_Skip ); - goto Fail; - } - - *asize = tables[i].size; - *aformat = tables[i].format; - - return FT_Err_Ok; - } - - Fail: - *asize = 0; - return error; - } - - - static FT_Bool - pcf_has_table_type( PCF_Table tables, - FT_ULong ntables, /* same as PCF_Toc->count */ - FT_ULong type ) - { - FT_ULong i; - - - for ( i = 0; i < ntables; i++ ) - if ( tables[i].type == type ) - return TRUE; - - return FALSE; - } - - -#define PCF_PROPERTY_SIZE 9 - - static - const FT_Frame_Field pcf_property_header[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PCF_ParsePropertyRec - - FT_FRAME_START( PCF_PROPERTY_SIZE ), - FT_FRAME_LONG_LE( name ), - FT_FRAME_BYTE ( isString ), - FT_FRAME_LONG_LE( value ), - FT_FRAME_END - }; - - - static - const FT_Frame_Field pcf_property_msb_header[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PCF_ParsePropertyRec - - FT_FRAME_START( PCF_PROPERTY_SIZE ), - FT_FRAME_LONG( name ), - FT_FRAME_BYTE( isString ), - FT_FRAME_LONG( value ), - FT_FRAME_END - }; - - - FT_LOCAL_DEF( PCF_Property ) - pcf_find_property( PCF_Face face, - const FT_String* prop ) - { - PCF_Property properties = face->properties; - FT_Bool found = 0; - int i; - - - for ( i = 0 ; i < face->nprops && !found; i++ ) - { - if ( !ft_strcmp( properties[i].name, prop ) ) - found = 1; - } - - if ( found ) - return properties + i - 1; - else - return NULL; - } - - - static FT_Error - pcf_get_properties( FT_Stream stream, - PCF_Face face ) - { - PCF_ParseProperty props = 0; - PCF_Property properties = NULL; - FT_ULong nprops, i; - FT_ULong format, size; - FT_Error error; - FT_Memory memory = FT_FACE( face )->memory; - FT_ULong string_size; - FT_String* strings = 0; - - - error = pcf_seek_to_table_type( stream, - face->toc.tables, - face->toc.count, - PCF_PROPERTIES, - &format, - &size ); - if ( error ) - goto Bail; - - if ( FT_READ_ULONG_LE( format ) ) - goto Bail; - - FT_TRACE4(( "pcf_get_properties:\n" )); - - FT_TRACE4(( " format = %ld\n", format )); - - if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) - goto Bail; - - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_ULONG( nprops ); - else - (void)FT_READ_ULONG_LE( nprops ); - if ( error ) - goto Bail; - - FT_TRACE4(( " nprop = %d (truncate %d props)\n", - (int)nprops, nprops - (int)nprops )); - - nprops = (int)nprops; - - /* rough estimate */ - if ( nprops > size / PCF_PROPERTY_SIZE ) - { - error = FT_THROW( Invalid_Table ); - goto Bail; - } - - face->nprops = (int)nprops; - - if ( FT_NEW_ARRAY( props, nprops ) ) - goto Bail; - - for ( i = 0; i < nprops; i++ ) - { - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - { - if ( FT_STREAM_READ_FIELDS( pcf_property_msb_header, props + i ) ) - goto Bail; - } - else - { - if ( FT_STREAM_READ_FIELDS( pcf_property_header, props + i ) ) - goto Bail; - } - } - - /* pad the property array */ - /* */ - /* clever here - nprops is the same as the number of odd-units read, */ - /* as only isStringProp are odd length (Keith Packard) */ - /* */ - if ( nprops & 3 ) - { - i = 4 - ( nprops & 3 ); - if ( FT_STREAM_SKIP( i ) ) - { - error = FT_THROW( Invalid_Stream_Skip ); - goto Bail; - } - } - - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_ULONG( string_size ); - else - (void)FT_READ_ULONG_LE( string_size ); - if ( error ) - goto Bail; - - FT_TRACE4(( " string_size = %ld\n", string_size )); - - /* rough estimate */ - if ( string_size > size - nprops * PCF_PROPERTY_SIZE ) - { - error = FT_THROW( Invalid_Table ); - goto Bail; - } - - /* allocate one more byte so that we have a final null byte */ - if ( FT_NEW_ARRAY( strings, string_size + 1 ) ) - goto Bail; - - error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size ); - if ( error ) - goto Bail; - - if ( FT_NEW_ARRAY( properties, nprops ) ) - goto Bail; - - face->properties = properties; - - for ( i = 0; i < nprops; i++ ) - { - FT_Long name_offset = props[i].name; - - - if ( ( name_offset < 0 ) || - ( (FT_ULong)name_offset > string_size ) ) - { - error = FT_THROW( Invalid_Offset ); - goto Bail; - } - - if ( FT_STRDUP( properties[i].name, strings + name_offset ) ) - goto Bail; - - FT_TRACE4(( " %s:", properties[i].name )); - - properties[i].isString = props[i].isString; - - if ( props[i].isString ) - { - FT_Long value_offset = props[i].value; - - - if ( ( value_offset < 0 ) || - ( (FT_ULong)value_offset > string_size ) ) - { - error = FT_THROW( Invalid_Offset ); - goto Bail; - } - - if ( FT_STRDUP( properties[i].value.atom, strings + value_offset ) ) - goto Bail; - - FT_TRACE4(( " `%s'\n", properties[i].value.atom )); - } - else - { - properties[i].value.l = props[i].value; - - FT_TRACE4(( " %d\n", properties[i].value.l )); - } - } - - error = FT_Err_Ok; - - Bail: - FT_FREE( props ); - FT_FREE( strings ); - - return error; - } - - - static FT_Error - pcf_get_metrics( FT_Stream stream, - PCF_Face face ) - { - FT_Error error; - FT_Memory memory = FT_FACE( face )->memory; - FT_ULong format, size; - PCF_Metric metrics = 0; - FT_ULong nmetrics, i; - - - error = pcf_seek_to_table_type( stream, - face->toc.tables, - face->toc.count, - PCF_METRICS, - &format, - &size ); - if ( error ) - return error; - - if ( FT_READ_ULONG_LE( format ) ) - goto Bail; - - if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && - !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ) - return FT_THROW( Invalid_File_Format ); - - if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) - { - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_ULONG( nmetrics ); - else - (void)FT_READ_ULONG_LE( nmetrics ); - } - else - { - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_USHORT( nmetrics ); - else - (void)FT_READ_USHORT_LE( nmetrics ); - } - if ( error ) - return FT_THROW( Invalid_File_Format ); - - face->nmetrics = nmetrics; - - if ( !nmetrics ) - return FT_THROW( Invalid_Table ); - - 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 FT_THROW( Invalid_Table ); - } - else - { - if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE ) - return FT_THROW( Invalid_Table ); - } - - if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) - return FT_THROW( Out_Of_Memory ); - - metrics = face->metrics; - for ( i = 0; i < nmetrics; i++ ) - { - error = pcf_get_metric( stream, format, metrics + i ); - - metrics[i].bits = 0; - - FT_TRACE5(( " idx %d: width=%d, " - "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", - i, - ( metrics + i )->characterWidth, - ( metrics + i )->leftSideBearing, - ( metrics + i )->rightSideBearing, - ( metrics + i )->ascent, - ( metrics + i )->descent, - ( metrics + i )->attributes )); - - if ( error ) - break; - } - - if ( error ) - FT_FREE( face->metrics ); - - Bail: - return error; - } - - - static FT_Error - pcf_get_bitmaps( FT_Stream stream, - PCF_Face face ) - { - FT_Error error; - FT_Memory memory = FT_FACE( face )->memory; - FT_Long* offsets = NULL; - FT_Long bitmapSizes[GLYPHPADOPTIONS]; - FT_ULong format, size; - FT_ULong nbitmaps, i, sizebitmaps = 0; - - - error = pcf_seek_to_table_type( stream, - face->toc.tables, - face->toc.count, - PCF_BITMAPS, - &format, - &size ); - if ( error ) - return error; - - error = FT_Stream_EnterFrame( stream, 8 ); - if ( error ) - return error; - - format = FT_GET_ULONG_LE(); - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - nbitmaps = FT_GET_ULONG(); - else - nbitmaps = FT_GET_ULONG_LE(); - - FT_Stream_ExitFrame( stream ); - - if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) - return FT_THROW( Invalid_File_Format ); - - FT_TRACE4(( "pcf_get_bitmaps:\n" )); - - FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); - - /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ - if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) - return FT_THROW( Invalid_File_Format ); - - if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) - return error; - - for ( i = 0; i < nbitmaps; i++ ) - { - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_LONG( offsets[i] ); - else - (void)FT_READ_LONG_LE( offsets[i] ); - - FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n", - i, offsets[i], offsets[i] )); - } - if ( error ) - goto Bail; - - for ( i = 0; i < GLYPHPADOPTIONS; i++ ) - { - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_LONG( bitmapSizes[i] ); - else - (void)FT_READ_LONG_LE( bitmapSizes[i] ); - if ( error ) - goto Bail; - - sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; - - FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] )); - } - - FT_TRACE4(( " %d bitmaps, padding index %ld\n", - nbitmaps, - PCF_GLYPH_PAD_INDEX( format ) )); - FT_TRACE4(( " bitmap size = %d\n", sizebitmaps )); - - FT_UNUSED( sizebitmaps ); /* only used for debugging */ - - for ( i = 0; i < nbitmaps; i++ ) - { - /* rough estimate */ - if ( ( offsets[i] < 0 ) || - ( (FT_ULong)offsets[i] > size ) ) - { - FT_TRACE0(( "pcf_get_bitmaps:" - " invalid offset to bitmap data of glyph %d\n", i )); - } - else - face->metrics[i].bits = stream->pos + offsets[i]; - } - - face->bitmapsFormat = format; - - Bail: - FT_FREE( offsets ); - return error; - } - - - static FT_Error - pcf_get_encodings( FT_Stream stream, - PCF_Face face ) - { - FT_Error error; - FT_Memory memory = FT_FACE( face )->memory; - FT_ULong format, size; - int firstCol, lastCol; - int firstRow, lastRow; - int nencoding, encodingOffset; - int i, j, k; - PCF_Encoding encoding = NULL; - - - error = pcf_seek_to_table_type( stream, - face->toc.tables, - face->toc.count, - PCF_BDF_ENCODINGS, - &format, - &size ); - if ( error ) - return error; - - error = FT_Stream_EnterFrame( stream, 14 ); - if ( error ) - return error; - - format = FT_GET_ULONG_LE(); - - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - { - firstCol = FT_GET_SHORT(); - lastCol = FT_GET_SHORT(); - firstRow = FT_GET_SHORT(); - lastRow = FT_GET_SHORT(); - face->defaultChar = FT_GET_SHORT(); - } - else - { - firstCol = FT_GET_SHORT_LE(); - lastCol = FT_GET_SHORT_LE(); - firstRow = FT_GET_SHORT_LE(); - lastRow = FT_GET_SHORT_LE(); - face->defaultChar = FT_GET_SHORT_LE(); - } - - FT_Stream_ExitFrame( stream ); - - if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) - return FT_THROW( Invalid_File_Format ); - - FT_TRACE4(( "pdf_get_encodings:\n" )); - - FT_TRACE4(( " firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", - firstCol, lastCol, firstRow, lastRow )); - - nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 ); - - if ( FT_NEW_ARRAY( encoding, nencoding ) ) - return FT_THROW( Out_Of_Memory ); - - error = FT_Stream_EnterFrame( stream, 2 * nencoding ); - if ( error ) - goto Bail; - - k = 0; - for ( i = firstRow; i <= lastRow; i++ ) - { - for ( j = firstCol; j <= lastCol; j++ ) - { - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - encodingOffset = FT_GET_SHORT(); - else - encodingOffset = FT_GET_SHORT_LE(); - - if ( encodingOffset != -1 ) - { - encoding[k].enc = i * 256 + j; - encoding[k].glyph = (FT_Short)encodingOffset; - - FT_TRACE5(( " code %d (0x%04X): idx %d\n", - encoding[k].enc, encoding[k].enc, encoding[k].glyph )); - - k++; - } - } - } - FT_Stream_ExitFrame( stream ); - - if ( FT_RENEW_ARRAY( encoding, nencoding, k ) ) - goto Bail; - - face->nencodings = k; - face->encodings = encoding; - - return error; - - Bail: - FT_FREE( encoding ); - return error; - } - - - static - const FT_Frame_Field pcf_accel_header[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PCF_AccelRec - - FT_FRAME_START( 20 ), - FT_FRAME_BYTE ( noOverlap ), - FT_FRAME_BYTE ( constantMetrics ), - FT_FRAME_BYTE ( terminalFont ), - FT_FRAME_BYTE ( constantWidth ), - FT_FRAME_BYTE ( inkInside ), - FT_FRAME_BYTE ( inkMetrics ), - FT_FRAME_BYTE ( drawDirection ), - FT_FRAME_SKIP_BYTES( 1 ), - FT_FRAME_LONG_LE ( fontAscent ), - FT_FRAME_LONG_LE ( fontDescent ), - FT_FRAME_LONG_LE ( maxOverlap ), - FT_FRAME_END - }; - - - static - const FT_Frame_Field pcf_accel_msb_header[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PCF_AccelRec - - FT_FRAME_START( 20 ), - FT_FRAME_BYTE ( noOverlap ), - FT_FRAME_BYTE ( constantMetrics ), - FT_FRAME_BYTE ( terminalFont ), - FT_FRAME_BYTE ( constantWidth ), - FT_FRAME_BYTE ( inkInside ), - FT_FRAME_BYTE ( inkMetrics ), - FT_FRAME_BYTE ( drawDirection ), - FT_FRAME_SKIP_BYTES( 1 ), - FT_FRAME_LONG ( fontAscent ), - FT_FRAME_LONG ( fontDescent ), - FT_FRAME_LONG ( maxOverlap ), - FT_FRAME_END - }; - - - static FT_Error - pcf_get_accel( FT_Stream stream, - PCF_Face face, - FT_ULong type ) - { - FT_ULong format, size; - FT_Error error; - PCF_Accel accel = &face->accel; - - - error = pcf_seek_to_table_type( stream, - face->toc.tables, - face->toc.count, - type, - &format, - &size ); - if ( error ) - goto Bail; - - if ( FT_READ_ULONG_LE( format ) ) - goto Bail; - - if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && - !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) - goto Bail; - - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - { - if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) ) - goto Bail; - } - else - { - if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) ) - goto Bail; - } - - error = pcf_get_metric( stream, - format & ( ~PCF_FORMAT_MASK ), - &(accel->minbounds) ); - if ( error ) - goto Bail; - - error = pcf_get_metric( stream, - format & ( ~PCF_FORMAT_MASK ), - &(accel->maxbounds) ); - if ( error ) - goto Bail; - - if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) - { - error = pcf_get_metric( stream, - format & ( ~PCF_FORMAT_MASK ), - &(accel->ink_minbounds) ); - if ( error ) - goto Bail; - - error = pcf_get_metric( stream, - format & ( ~PCF_FORMAT_MASK ), - &(accel->ink_maxbounds) ); - if ( error ) - goto Bail; - } - else - { - accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */ - accel->ink_maxbounds = accel->maxbounds; - } - - Bail: - return error; - } - - - static FT_Error - pcf_interpret_style( PCF_Face pcf ) - { - FT_Error error = FT_Err_Ok; - FT_Face face = FT_FACE( pcf ); - FT_Memory memory = face->memory; - - PCF_Property prop; - - size_t nn, len; - char* strings[4] = { NULL, NULL, NULL, NULL }; - size_t lengths[4]; - - - face->style_flags = 0; - - prop = pcf_find_property( pcf, "SLANT" ); - if ( prop && prop->isString && - ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || - *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) - { - face->style_flags |= FT_STYLE_FLAG_ITALIC; - strings[2] = ( *(prop->value.atom) == 'O' || - *(prop->value.atom) == 'o' ) ? (char *)"Oblique" - : (char *)"Italic"; - } - - prop = pcf_find_property( pcf, "WEIGHT_NAME" ); - if ( prop && prop->isString && - ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) - { - face->style_flags |= FT_STYLE_FLAG_BOLD; - strings[1] = (char*)"Bold"; - } - - prop = pcf_find_property( pcf, "SETWIDTH_NAME" ); - if ( prop && prop->isString && - *(prop->value.atom) && - !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) - strings[3] = (char*)( prop->value.atom ); - - prop = pcf_find_property( pcf, "ADD_STYLE_NAME" ); - if ( prop && prop->isString && - *(prop->value.atom) && - !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) - strings[0] = (char*)( prop->value.atom ); - - for ( len = 0, nn = 0; nn < 4; nn++ ) - { - lengths[nn] = 0; - if ( strings[nn] ) - { - lengths[nn] = ft_strlen( strings[nn] ); - len += lengths[nn] + 1; - } - } - - if ( len == 0 ) - { - strings[0] = (char*)"Regular"; - lengths[0] = ft_strlen( strings[0] ); - len = lengths[0] + 1; - } - - { - char* s; - - - if ( FT_ALLOC( face->style_name, len ) ) - return error; - - s = face->style_name; - - for ( nn = 0; nn < 4; nn++ ) - { - char* src = strings[nn]; - - - len = lengths[nn]; - - if ( src == NULL ) - continue; - - /* separate elements with a space */ - if ( s != face->style_name ) - *s++ = ' '; - - ft_memcpy( s, src, len ); - - /* need to convert spaces to dashes for */ - /* add_style_name and setwidth_name */ - if ( nn == 0 || nn == 3 ) - { - size_t mm; - - - for ( mm = 0; mm < len; mm++ ) - if ( s[mm] == ' ' ) - s[mm] = '-'; - } - - s += len; - } - *s = 0; - } - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - pcf_load_font( FT_Stream stream, - PCF_Face face ) - { - FT_Error error = FT_Err_Ok; - FT_Memory memory = FT_FACE( face )->memory; - FT_Bool hasBDFAccelerators; - - - error = pcf_read_TOC( stream, face ); - if ( error ) - goto Exit; - - error = pcf_get_properties( stream, face ); - if ( error ) - goto Exit; - - /* Use the old accelerators if no BDF accelerators are in the file. */ - hasBDFAccelerators = pcf_has_table_type( face->toc.tables, - face->toc.count, - PCF_BDF_ACCELERATORS ); - if ( !hasBDFAccelerators ) - { - error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); - if ( error ) - goto Exit; - } - - /* metrics */ - error = pcf_get_metrics( stream, face ); - if ( error ) - goto Exit; - - /* bitmaps */ - error = pcf_get_bitmaps( stream, face ); - if ( error ) - goto Exit; - - /* encodings */ - error = pcf_get_encodings( stream, face ); - if ( error ) - goto Exit; - - /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ - if ( hasBDFAccelerators ) - { - error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); - if ( error ) - goto Exit; - } - - /* XXX: TO DO: inkmetrics and glyph_names are missing */ - - /* now construct the face object */ - { - FT_Face root = FT_FACE( face ); - PCF_Property prop; - - - root->num_faces = 1; - root->face_index = 0; - root->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_FAST_GLYPHS; - - if ( face->accel.constantWidth ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - if ( ( error = pcf_interpret_style( face ) ) != 0 ) - goto Exit; - - prop = pcf_find_property( face, "FAMILY_NAME" ); - if ( prop && prop->isString ) - { - if ( FT_STRDUP( root->family_name, prop->value.atom ) ) - goto Exit; - } - else - root->family_name = NULL; - - /* - * Note: We shift all glyph indices by +1 since we must - * respect the convention that glyph 0 always corresponds - * to the `missing glyph'. - * - * This implies bumping the number of `available' glyphs by 1. - */ - root->num_glyphs = face->nmetrics + 1; - - root->num_fixed_sizes = 1; - if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) - goto Exit; - - { - FT_Bitmap_Size* bsize = root->available_sizes; - FT_Short resolution_x = 0, resolution_y = 0; - - - FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); - -#if 0 - bsize->height = face->accel.maxbounds.ascent << 6; -#endif - bsize->height = (FT_Short)( face->accel.fontAscent + - face->accel.fontDescent ); - - prop = pcf_find_property( face, "AVERAGE_WIDTH" ); - if ( prop ) - bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); - else - bsize->width = (FT_Short)( bsize->height * 2/3 ); - - prop = pcf_find_property( face, "POINT_SIZE" ); - if ( prop ) - /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = - (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); - - prop = pcf_find_property( face, "PIXEL_SIZE" ); - if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.l << 6; - - prop = pcf_find_property( face, "RESOLUTION_X" ); - if ( prop ) - resolution_x = (FT_Short)prop->value.l; - - prop = pcf_find_property( face, "RESOLUTION_Y" ); - if ( prop ) - resolution_y = (FT_Short)prop->value.l; - - if ( bsize->y_ppem == 0 ) - { - bsize->y_ppem = bsize->size; - if ( resolution_y ) - bsize->y_ppem = bsize->y_ppem * resolution_y / 72; - } - if ( resolution_x && resolution_y ) - bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; - else - bsize->x_ppem = bsize->y_ppem; - } - - /* set up charset */ - { - PCF_Property charset_registry = 0, charset_encoding = 0; - - - charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); - charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); - - if ( charset_registry && charset_registry->isString && - charset_encoding && charset_encoding->isString ) - { - if ( FT_STRDUP( face->charset_encoding, - charset_encoding->value.atom ) || - FT_STRDUP( face->charset_registry, - charset_registry->value.atom ) ) - goto Exit; - } - } - } - - Exit: - if ( error ) - { - /* This is done to respect the behaviour of the original */ - /* PCF font driver. */ - error = FT_THROW( Invalid_File_Format ); - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfread.h b/drivers/freetype/freetype/src/pcf/pcfread.h deleted file mode 100644 index c9524f1346..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcfread.h +++ /dev/null @@ -1,45 +0,0 @@ -/* pcfread.h - - FreeType font driver for pcf fonts - - Copyright 2003 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - - -#ifndef __PCFREAD_H__ -#define __PCFREAD_H__ - - -#include <ft2build.h> - -FT_BEGIN_HEADER - - FT_LOCAL( PCF_Property ) - pcf_find_property( PCF_Face face, - const FT_String* prop ); - -FT_END_HEADER - -#endif /* __PCFREAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfutil.c b/drivers/freetype/freetype/src/pcf/pcfutil.c deleted file mode 100644 index b91274f935..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcfutil.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - -Copyright 1990, 1994, 1998 The Open Group - -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. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -*/ -/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.3 1999/08/22 08:58:58 dawes Exp $ */ - -/* - * Author: Keith Packard, MIT X Consortium - */ - -/* Modified for use with FreeType */ - - -#include <ft2build.h> -#include "pcfutil.h" - - - /* - * Invert bit order within each BYTE of an array. - */ - - FT_LOCAL_DEF( void ) - BitOrderInvert( unsigned char* buf, - size_t nbytes ) - { - for ( ; nbytes > 0; nbytes--, 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; - } - } - - - /* - * Invert byte order within each 16-bits of an array. - */ - - FT_LOCAL_DEF( void ) - TwoByteSwap( unsigned char* buf, - size_t nbytes ) - { - unsigned char c; - - - for ( ; nbytes >= 2; nbytes -= 2, buf += 2 ) - { - c = buf[0]; - buf[0] = buf[1]; - buf[1] = c; - } - } - - /* - * Invert byte order within each 32-bits of an array. - */ - - FT_LOCAL_DEF( void ) - FourByteSwap( unsigned char* buf, - size_t nbytes ) - { - unsigned char c; - - - for ( ; nbytes >= 4; nbytes -= 4, buf += 4 ) - { - c = buf[0]; - buf[0] = buf[3]; - buf[3] = c; - - c = buf[1]; - buf[1] = buf[2]; - buf[2] = c; - } - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfutil.h b/drivers/freetype/freetype/src/pcf/pcfutil.h deleted file mode 100644 index ce10fb541d..0000000000 --- a/drivers/freetype/freetype/src/pcf/pcfutil.h +++ /dev/null @@ -1,55 +0,0 @@ -/* pcfutil.h - - FreeType font driver for pcf fonts - - Copyright 2000, 2001, 2004 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 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - - -#ifndef __PCFUTIL_H__ -#define __PCFUTIL_H__ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H - - -FT_BEGIN_HEADER - - FT_LOCAL( void ) - BitOrderInvert( unsigned char* buf, - size_t nbytes ); - - FT_LOCAL( void ) - TwoByteSwap( unsigned char* buf, - size_t nbytes ); - - FT_LOCAL( void ) - FourByteSwap( unsigned char* buf, - size_t nbytes ); - -FT_END_HEADER - -#endif /* __PCFUTIL_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pcf/rules.mk b/drivers/freetype/freetype/src/pcf/rules.mk deleted file mode 100644 index 78641528fa..0000000000 --- a/drivers/freetype/freetype/src/pcf/rules.mk +++ /dev/null @@ -1,79 +0,0 @@ -# -# FreeType 2 pcf driver configuration rules -# - - -# Copyright (C) 2000, 2001, 2003, 2008 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 -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - -# pcf driver directory -# -PCF_DIR := $(SRC_DIR)/pcf - - -PCF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) - - -# pcf driver sources (i.e., C files) -# -PCF_DRV_SRC := $(PCF_DIR)/pcfdrivr.c \ - $(PCF_DIR)/pcfread.c \ - $(PCF_DIR)/pcfutil.c - -# pcf driver headers -# -PCF_DRV_H := $(PCF_DRV_SRC:%.c=%.h) \ - $(PCF_DIR)/pcf.h \ - $(PCF_DIR)/pcferror.h - -# pcf driver object(s) -# -# PCF_DRV_OBJ_M is used during `multi' builds -# PCF_DRV_OBJ_S is used during `single' builds -# -PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR)/%.c=$(OBJ_DIR)/%.$O) -PCF_DRV_OBJ_S := $(OBJ_DIR)/pcf.$O - -# pcf driver source file for single build -# -PCF_DRV_SRC_S := $(PCF_DIR)/pcf.c - - -# pcf driver - single object -# -$(PCF_DRV_OBJ_S): $(PCF_DRV_SRC_S) $(PCF_DRV_SRC) $(FREETYPE_H) $(PCF_DRV_H) - $(PCF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PCF_DRV_SRC_S)) - - -# pcf driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PCF_DIR)/%.c $(FREETYPE_H) $(PCF_DRV_H) - $(PCF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PCF_DRV_OBJ_S) -DRV_OBJS_M += $(PCF_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/pfr/Jamfile b/drivers/freetype/freetype/src/pfr/Jamfile deleted file mode 100644 index 9e2f2b8d05..0000000000 --- a/drivers/freetype/freetype/src/pfr/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/pfr Jamfile -# -# Copyright 2002 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) pfr ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ; - } - else - { - _sources = pfr ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/pfr Jamfile diff --git a/drivers/freetype/freetype/src/pfr/module.mk b/drivers/freetype/freetype/src/pfr/module.mk deleted file mode 100644 index 8d1d28a9d2..0000000000 --- a/drivers/freetype/freetype/src/pfr/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 PFR module definition -# - - -# Copyright 2002, 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. - - -FTMODULE_H_COMMANDS += PFR_DRIVER - -define PFR_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, pfr_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)pfr $(ECHO_DRIVER_DESC)PFR/TrueDoc font files with extension *.pfr$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/pfr/pfr.c b/drivers/freetype/freetype/src/pfr/pfr.c deleted file mode 100644 index eb2c4edb7e..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfr.c +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfr.c */ -/* */ -/* FreeType PFR driver component. */ -/* */ -/* Copyright 2002 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. */ -/* */ -/***************************************************************************/ - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> - -#include "pfrload.c" -#include "pfrgload.c" -#include "pfrcmap.c" -#include "pfrobjs.c" -#include "pfrdrivr.c" -#include "pfrsbit.c" - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrcmap.c b/drivers/freetype/freetype/src/pfr/pfrcmap.c deleted file mode 100644 index 740c433d66..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrcmap.c +++ /dev/null @@ -1,168 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrcmap.c */ -/* */ -/* FreeType PFR cmap handling (body). */ -/* */ -/* Copyright 2002, 2007, 2009, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include "pfrcmap.h" -#include "pfrobjs.h" - -#include "pfrerror.h" - - - FT_CALLBACK_DEF( FT_Error ) - pfr_cmap_init( PFR_CMap cmap ) - { - FT_Error error = FT_Err_Ok; - PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); - - - 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++ ) - { - if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code ) - { - error = FT_THROW( Invalid_Table ); - goto Exit; - } - } - } - - Exit: - return error; - } - - - FT_CALLBACK_DEF( void ) - pfr_cmap_done( PFR_CMap cmap ) - { - cmap->chars = NULL; - cmap->num_chars = 0; - } - - - FT_CALLBACK_DEF( FT_UInt ) - pfr_cmap_char_index( PFR_CMap cmap, - FT_UInt32 char_code ) - { - FT_UInt min = 0; - FT_UInt max = cmap->num_chars; - FT_UInt mid; - PFR_Char gchar; - - - while ( min < max ) - { - mid = min + ( max - min ) / 2; - gchar = cmap->chars + mid; - - if ( gchar->char_code == char_code ) - return mid + 1; - - if ( gchar->char_code < char_code ) - min = mid + 1; - else - max = mid; - } - return 0; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - pfr_cmap_char_next( PFR_CMap cmap, - FT_UInt32 *pchar_code ) - { - FT_UInt result = 0; - FT_UInt32 char_code = *pchar_code + 1; - - - Restart: - { - FT_UInt min = 0; - FT_UInt max = cmap->num_chars; - FT_UInt mid; - PFR_Char gchar; - - - while ( min < max ) - { - mid = min + ( ( max - min ) >> 1 ); - gchar = cmap->chars + mid; - - if ( gchar->char_code == char_code ) - { - result = mid; - if ( result != 0 ) - { - result++; - goto Exit; - } - - char_code++; - goto Restart; - } - - if ( gchar->char_code < char_code ) - min = mid+1; - else - max = mid; - } - - /* we didn't find it, but we have a pair just above it */ - char_code = 0; - - if ( min < cmap->num_chars ) - { - gchar = cmap->chars + min; - result = min; - if ( result != 0 ) - { - result++; - char_code = gchar->char_code; - } - } - } - - Exit: - *pchar_code = char_code; - return result; - } - - - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - pfr_cmap_class_rec = - { - sizeof ( PFR_CMapRec ), - - (FT_CMap_InitFunc) pfr_cmap_init, - (FT_CMap_DoneFunc) pfr_cmap_done, - (FT_CMap_CharIndexFunc)pfr_cmap_char_index, - (FT_CMap_CharNextFunc) pfr_cmap_char_next, - - NULL, NULL, NULL, NULL, NULL - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrcmap.h b/drivers/freetype/freetype/src/pfr/pfrcmap.h deleted file mode 100644 index a626953054..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrcmap.h +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrcmap.h */ -/* */ -/* FreeType PFR cmap handling (specification). */ -/* */ -/* Copyright 2002 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 __PFRCMAP_H__ -#define __PFRCMAP_H__ - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include "pfrtypes.h" - - -FT_BEGIN_HEADER - - typedef struct PFR_CMapRec_ - { - FT_CMapRec cmap; - FT_UInt num_chars; - PFR_Char chars; - - } PFR_CMapRec, *PFR_CMap; - - - FT_CALLBACK_TABLE const FT_CMap_ClassRec pfr_cmap_class_rec; - -FT_END_HEADER - - -#endif /* __PFRCMAP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrdrivr.c b/drivers/freetype/freetype/src/pfr/pfrdrivr.c deleted file mode 100644 index 4c43947bf4..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrdrivr.c +++ /dev/null @@ -1,210 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrdrivr.c */ -/* */ -/* FreeType PFR driver interface (body). */ -/* */ -/* Copyright 2002-2004, 2006, 2008, 2010, 2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_SERVICE_PFR_H -#include FT_SERVICE_XFREE86_NAME_H -#include "pfrdrivr.h" -#include "pfrobjs.h" - -#include "pfrerror.h" - - - FT_CALLBACK_DEF( FT_Error ) - pfr_get_kerning( FT_Face pfrface, /* PFR_Face */ - FT_UInt left, - FT_UInt right, - FT_Vector *avector ) - { - PFR_Face face = (PFR_Face)pfrface; - PFR_PhyFont phys = &face->phy_font; - - - pfr_face_get_kerning( pfrface, left, right, avector ); - - /* convert from metrics to outline units when necessary */ - if ( phys->outline_resolution != phys->metrics_resolution ) - { - if ( avector->x != 0 ) - avector->x = FT_MulDiv( avector->x, phys->outline_resolution, - phys->metrics_resolution ); - - if ( avector->y != 0 ) - avector->y = FT_MulDiv( avector->x, phys->outline_resolution, - phys->metrics_resolution ); - } - - return FT_Err_Ok; - } - - - /* - * PFR METRICS SERVICE - * - */ - - FT_CALLBACK_DEF( FT_Error ) - pfr_get_advance( FT_Face pfrface, /* PFR_Face */ - FT_UInt gindex, - FT_Pos *anadvance ) - { - PFR_Face face = (PFR_Face)pfrface; - FT_Error error = FT_ERR( Invalid_Argument ); - - - *anadvance = 0; - - if ( !gindex ) - goto Exit; - - gindex--; - - if ( face ) - { - PFR_PhyFont phys = &face->phy_font; - - - if ( gindex < phys->num_chars ) - { - *anadvance = phys->chars[gindex].advance; - error = FT_Err_Ok; - } - } - - Exit: - return error; - } - - - FT_CALLBACK_DEF( FT_Error ) - pfr_get_metrics( FT_Face pfrface, /* PFR_Face */ - FT_UInt *anoutline_resolution, - FT_UInt *ametrics_resolution, - FT_Fixed *ametrics_x_scale, - FT_Fixed *ametrics_y_scale ) - { - PFR_Face face = (PFR_Face)pfrface; - PFR_PhyFont phys = &face->phy_font; - FT_Fixed x_scale, y_scale; - FT_Size size = face->root.size; - - - if ( anoutline_resolution ) - *anoutline_resolution = phys->outline_resolution; - - if ( ametrics_resolution ) - *ametrics_resolution = phys->metrics_resolution; - - x_scale = 0x10000L; - y_scale = 0x10000L; - - if ( size ) - { - x_scale = FT_DivFix( size->metrics.x_ppem << 6, - phys->metrics_resolution ); - - y_scale = FT_DivFix( size->metrics.y_ppem << 6, - phys->metrics_resolution ); - } - - if ( ametrics_x_scale ) - *ametrics_x_scale = x_scale; - - if ( ametrics_y_scale ) - *ametrics_y_scale = y_scale; - - return FT_Err_Ok; - } - - - FT_CALLBACK_TABLE_DEF - const FT_Service_PfrMetricsRec pfr_metrics_service_rec = - { - pfr_get_metrics, - pfr_face_get_kerning, - pfr_get_advance - }; - - - /* - * SERVICE LIST - * - */ - - static const FT_ServiceDescRec pfr_services[] = - { - { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, - { NULL, NULL } - }; - - - FT_CALLBACK_DEF( FT_Module_Interface ) - pfr_get_service( FT_Module module, - const FT_String* service_id ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( pfr_services, service_id ); - } - - - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec pfr_driver_class = - { - { - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE, - - sizeof ( FT_DriverRec ), - - "pfr", - 0x10000L, - 0x20000L, - - NULL, - - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - pfr_get_service - }, - - sizeof ( PFR_FaceRec ), - sizeof ( PFR_SizeRec ), - sizeof ( PFR_SlotRec ), - - pfr_face_init, - pfr_face_done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - pfr_slot_init, - pfr_slot_done, - - pfr_slot_load, - - pfr_get_kerning, - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ - 0, /* FT_Size_RequestFunc */ - 0, /* FT_Size_SelectFunc */ - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrdrivr.h b/drivers/freetype/freetype/src/pfr/pfrdrivr.h deleted file mode 100644 index 75f86c5cdd..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrdrivr.h +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrdrivr.h */ -/* */ -/* High-level Type PFR driver interface (specification). */ -/* */ -/* Copyright 2002 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 __PFRDRIVR_H__ -#define __PFRDRIVR_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; - - -FT_END_HEADER - - -#endif /* __PFRDRIVR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrerror.h b/drivers/freetype/freetype/src/pfr/pfrerror.h deleted file mode 100644 index 94dc8c5e1c..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrerror.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrerror.h */ -/* */ -/* PFR error codes (specification only). */ -/* */ -/* Copyright 2002, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PFR error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __PFRERROR_H__ -#define __PFRERROR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PFR_Err_ -#define FT_ERR_BASE FT_Mod_Err_PFR - -#include FT_ERRORS_H - -#endif /* __PFRERROR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrgload.c b/drivers/freetype/freetype/src/pfr/pfrgload.c deleted file mode 100644 index 88b4d66a13..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrgload.c +++ /dev/null @@ -1,844 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrgload.c */ -/* */ -/* FreeType PFR glyph loader (body). */ -/* */ -/* Copyright 2002, 2003, 2005, 2007, 2010, 2013 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 "pfrgload.h" -#include "pfrsbit.h" -#include "pfrload.h" /* for macro definitions */ -#include FT_INTERNAL_DEBUG_H - -#include "pfrerror.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pfr - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PFR GLYPH BUILDER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL_DEF( void ) - pfr_glyph_init( PFR_Glyph glyph, - FT_GlyphLoader loader ) - { - FT_ZERO( glyph ); - - glyph->loader = loader; - glyph->path_begun = 0; - - FT_GlyphLoader_Rewind( loader ); - } - - - FT_LOCAL_DEF( void ) - pfr_glyph_done( PFR_Glyph glyph ) - { - FT_Memory memory = glyph->loader->memory; - - - FT_FREE( glyph->x_control ); - glyph->y_control = NULL; - - glyph->max_xy_control = 0; -#if 0 - glyph->num_x_control = 0; - glyph->num_y_control = 0; -#endif - - FT_FREE( glyph->subs ); - - glyph->max_subs = 0; - glyph->num_subs = 0; - - glyph->loader = NULL; - glyph->path_begun = 0; - } - - - /* close current contour, if any */ - static void - pfr_glyph_close_contour( PFR_Glyph glyph ) - { - FT_GlyphLoader loader = glyph->loader; - FT_Outline* outline = &loader->current.outline; - FT_Int last, first; - - - if ( !glyph->path_begun ) - return; - - /* compute first and last point indices in current glyph outline */ - last = outline->n_points - 1; - first = 0; - if ( outline->n_contours > 0 ) - first = outline->contours[outline->n_contours - 1]; - - /* if the last point falls on the same location than the first one */ - /* we need to delete it */ - if ( last > first ) - { - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + last; - - - if ( p1->x == p2->x && p1->y == p2->y ) - { - outline->n_points--; - last--; - } - } - - /* don't add empty contours */ - if ( last >= first ) - outline->contours[outline->n_contours++] = (short)last; - - glyph->path_begun = 0; - } - - - /* reset glyph to start the loading of a new glyph */ - static void - pfr_glyph_start( PFR_Glyph glyph ) - { - glyph->path_begun = 0; - } - - - static FT_Error - pfr_glyph_line_to( PFR_Glyph glyph, - FT_Vector* to ) - { - FT_GlyphLoader loader = glyph->loader; - FT_Outline* outline = &loader->current.outline; - FT_Error error; - - - /* check that we have begun a new path */ - if ( !glyph->path_begun ) - { - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" )); - goto Exit; - } - - error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 ); - if ( !error ) - { - FT_UInt n = outline->n_points; - - - outline->points[n] = *to; - outline->tags [n] = FT_CURVE_TAG_ON; - - outline->n_points++; - } - - Exit: - return error; - } - - - static FT_Error - pfr_glyph_curve_to( PFR_Glyph glyph, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) - { - FT_GlyphLoader loader = glyph->loader; - FT_Outline* outline = &loader->current.outline; - FT_Error error; - - - /* check that we have begun a new path */ - if ( !glyph->path_begun ) - { - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" )); - goto Exit; - } - - error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 ); - if ( !error ) - { - FT_Vector* vec = outline->points + outline->n_points; - FT_Byte* tag = (FT_Byte*)outline->tags + outline->n_points; - - - vec[0] = *control1; - vec[1] = *control2; - vec[2] = *to; - tag[0] = FT_CURVE_TAG_CUBIC; - tag[1] = FT_CURVE_TAG_CUBIC; - tag[2] = FT_CURVE_TAG_ON; - - outline->n_points = (FT_Short)( outline->n_points + 3 ); - } - - Exit: - return error; - } - - - static FT_Error - pfr_glyph_move_to( PFR_Glyph glyph, - FT_Vector* to ) - { - FT_GlyphLoader loader = glyph->loader; - FT_Error error; - - - /* close current contour if any */ - pfr_glyph_close_contour( glyph ); - - /* indicate that a new contour has started */ - glyph->path_begun = 1; - - /* check that there is space for a new contour and a new point */ - error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 ); - if ( !error ) - /* add new start point */ - error = pfr_glyph_line_to( glyph, to ); - - return error; - } - - - static void - pfr_glyph_end( PFR_Glyph glyph ) - { - /* close current contour if any */ - pfr_glyph_close_contour( glyph ); - - /* merge the current glyph into the stack */ - FT_GlyphLoader_Add( glyph->loader ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PFR GLYPH LOADER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* load a simple glyph */ - static FT_Error - pfr_glyph_load_simple( PFR_Glyph glyph, - FT_Byte* p, - FT_Byte* limit ) - { - FT_Error error = FT_Err_Ok; - FT_Memory memory = glyph->loader->memory; - FT_UInt flags, x_count, y_count, i, count, mask; - FT_Int x; - - - PFR_CHECK( 1 ); - flags = PFR_NEXT_BYTE( p ); - - /* test for composite glyphs */ - if ( flags & PFR_GLYPH_IS_COMPOUND ) - goto Failure; - - x_count = 0; - y_count = 0; - - if ( flags & PFR_GLYPH_1BYTE_XYCOUNT ) - { - PFR_CHECK( 1 ); - count = PFR_NEXT_BYTE( p ); - x_count = count & 15; - y_count = count >> 4; - } - else - { - if ( flags & PFR_GLYPH_XCOUNT ) - { - PFR_CHECK( 1 ); - x_count = PFR_NEXT_BYTE( p ); - } - - if ( flags & PFR_GLYPH_YCOUNT ) - { - PFR_CHECK( 1 ); - y_count = PFR_NEXT_BYTE( p ); - } - } - - count = x_count + y_count; - - /* re-allocate array when necessary */ - if ( count > glyph->max_xy_control ) - { - FT_UInt new_max = FT_PAD_CEIL( count, 8 ); - - - if ( FT_RENEW_ARRAY( glyph->x_control, - glyph->max_xy_control, - new_max ) ) - goto Exit; - - glyph->max_xy_control = new_max; - } - - glyph->y_control = glyph->x_control + x_count; - - mask = 0; - x = 0; - - for ( i = 0; i < count; i++ ) - { - if ( ( i & 7 ) == 0 ) - { - PFR_CHECK( 1 ); - mask = PFR_NEXT_BYTE( p ); - } - - if ( mask & 1 ) - { - PFR_CHECK( 2 ); - x = PFR_NEXT_SHORT( p ); - } - else - { - PFR_CHECK( 1 ); - x += PFR_NEXT_BYTE( p ); - } - - glyph->x_control[i] = x; - - mask >>= 1; - } - - /* XXX: for now we ignore the secondary stroke and edge definitions */ - /* since we don't want to support native PFR hinting */ - /* */ - if ( flags & PFR_GLYPH_EXTRA_ITEMS ) - { - error = pfr_extra_items_skip( &p, limit ); - if ( error ) - goto Exit; - } - - pfr_glyph_start( glyph ); - - /* now load a simple glyph */ - { - FT_Vector pos[4]; - FT_Vector* cur; - - - pos[0].x = pos[0].y = 0; - pos[3] = pos[0]; - - for (;;) - { - FT_UInt format, format_low, args_format = 0, args_count, n; - - - /***************************************************************/ - /* read instruction */ - /* */ - PFR_CHECK( 1 ); - format = PFR_NEXT_BYTE( p ); - format_low = format & 15; - - switch ( format >> 4 ) - { - case 0: /* end glyph */ - FT_TRACE6(( "- end glyph" )); - args_count = 0; - break; - - case 1: /* general line operation */ - FT_TRACE6(( "- general line" )); - goto Line1; - - case 4: /* move to inside contour */ - FT_TRACE6(( "- move to inside" )); - goto Line1; - - case 5: /* move to outside contour */ - FT_TRACE6(( "- move to outside" )); - Line1: - args_format = format_low; - args_count = 1; - break; - - case 2: /* horizontal line to */ - FT_TRACE6(( "- horizontal line to cx.%d", format_low )); - if ( format_low >= x_count ) - goto Failure; - pos[0].x = glyph->x_control[format_low]; - pos[0].y = pos[3].y; - pos[3] = pos[0]; - args_count = 0; - break; - - case 3: /* vertical line to */ - FT_TRACE6(( "- vertical line to cy.%d", format_low )); - if ( format_low >= y_count ) - goto Failure; - pos[0].x = pos[3].x; - pos[0].y = glyph->y_control[format_low]; - pos[3] = pos[0]; - args_count = 0; - break; - - case 6: /* horizontal to vertical curve */ - FT_TRACE6(( "- hv curve " )); - args_format = 0xB8E; - args_count = 3; - break; - - case 7: /* vertical to horizontal curve */ - FT_TRACE6(( "- vh curve" )); - args_format = 0xE2B; - args_count = 3; - break; - - default: /* general curve to */ - FT_TRACE6(( "- general curve" )); - args_count = 4; - args_format = format_low; - } - - /***********************************************************/ - /* now read arguments */ - /* */ - cur = pos; - for ( n = 0; n < args_count; n++ ) - { - FT_UInt idx; - FT_Int delta; - - - /* read the X argument */ - switch ( args_format & 3 ) - { - case 0: /* 8-bit index */ - PFR_CHECK( 1 ); - idx = PFR_NEXT_BYTE( p ); - if ( idx >= x_count ) - goto Failure; - cur->x = glyph->x_control[idx]; - FT_TRACE7(( " cx#%d", idx )); - break; - - case 1: /* 16-bit value */ - PFR_CHECK( 2 ); - cur->x = PFR_NEXT_SHORT( p ); - FT_TRACE7(( " x.%d", cur->x )); - break; - - case 2: /* 8-bit delta */ - PFR_CHECK( 1 ); - delta = PFR_NEXT_INT8( p ); - cur->x = pos[3].x + delta; - FT_TRACE7(( " dx.%d", delta )); - break; - - default: - FT_TRACE7(( " |" )); - cur->x = pos[3].x; - } - - /* read the Y argument */ - switch ( ( args_format >> 2 ) & 3 ) - { - case 0: /* 8-bit index */ - PFR_CHECK( 1 ); - idx = PFR_NEXT_BYTE( p ); - if ( idx >= y_count ) - goto Failure; - cur->y = glyph->y_control[idx]; - FT_TRACE7(( " cy#%d", idx )); - break; - - case 1: /* 16-bit absolute value */ - PFR_CHECK( 2 ); - cur->y = PFR_NEXT_SHORT( p ); - FT_TRACE7(( " y.%d", cur->y )); - break; - - case 2: /* 8-bit delta */ - PFR_CHECK( 1 ); - delta = PFR_NEXT_INT8( p ); - cur->y = pos[3].y + delta; - FT_TRACE7(( " dy.%d", delta )); - break; - - default: - FT_TRACE7(( " -" )); - cur->y = pos[3].y; - } - - /* read the additional format flag for the general curve */ - if ( n == 0 && args_count == 4 ) - { - PFR_CHECK( 1 ); - args_format = PFR_NEXT_BYTE( p ); - args_count--; - } - else - args_format >>= 4; - - /* save the previous point */ - pos[3] = cur[0]; - cur++; - } - - FT_TRACE7(( "\n" )); - - /***********************************************************/ - /* finally, execute instruction */ - /* */ - switch ( format >> 4 ) - { - case 0: /* end glyph => EXIT */ - pfr_glyph_end( glyph ); - goto Exit; - - case 1: /* line operations */ - case 2: - case 3: - error = pfr_glyph_line_to( glyph, pos ); - goto Test_Error; - - case 4: /* move to inside contour */ - case 5: /* move to outside contour */ - error = pfr_glyph_move_to( glyph, pos ); - goto Test_Error; - - default: /* curve operations */ - error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); - - Test_Error: /* test error condition */ - if ( error ) - goto Exit; - } - } /* for (;;) */ - } - - Exit: - return error; - - Failure: - Too_Short: - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" )); - goto Exit; - } - - - /* load a composite/compound glyph */ - static FT_Error - pfr_glyph_load_compound( PFR_Glyph glyph, - FT_Byte* p, - FT_Byte* limit ) - { - FT_Error error = FT_Err_Ok; - FT_GlyphLoader loader = glyph->loader; - FT_Memory memory = loader->memory; - PFR_SubGlyph subglyph; - FT_UInt flags, i, count, org_count; - FT_Int x_pos, y_pos; - - - PFR_CHECK( 1 ); - flags = PFR_NEXT_BYTE( p ); - - /* test for composite glyphs */ - if ( !( flags & PFR_GLYPH_IS_COMPOUND ) ) - goto Failure; - - count = flags & 0x3F; - - /* ignore extra items when present */ - /* */ - if ( flags & PFR_GLYPH_EXTRA_ITEMS ) - { - error = pfr_extra_items_skip( &p, limit ); - if (error) goto Exit; - } - - /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ - /* the PFR format is dumb, using direct file offsets to point to the */ - /* sub-glyphs (instead of glyph indices). Sigh. */ - /* */ - /* For now, we load the list of sub-glyphs into a different array */ - /* but this will prevent us from using the auto-hinter at its best */ - /* quality. */ - /* */ - org_count = glyph->num_subs; - - if ( org_count + count > glyph->max_subs ) - { - FT_UInt new_max = ( org_count + count + 3 ) & (FT_UInt)-4; - - - /* we arbitrarily limit the number of subglyphs */ - /* to avoid endless recursion */ - if ( new_max > 64 ) - { - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_glyph_load_compound:" - " too many compound glyphs components\n" )); - goto Exit; - } - - if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) - goto Exit; - - glyph->max_subs = new_max; - } - - subglyph = glyph->subs + org_count; - - for ( i = 0; i < count; i++, subglyph++ ) - { - FT_UInt format; - - - x_pos = 0; - y_pos = 0; - - PFR_CHECK( 1 ); - format = PFR_NEXT_BYTE( p ); - - /* read scale when available */ - subglyph->x_scale = 0x10000L; - if ( format & PFR_SUBGLYPH_XSCALE ) - { - PFR_CHECK( 2 ); - subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; - } - - subglyph->y_scale = 0x10000L; - if ( format & PFR_SUBGLYPH_YSCALE ) - { - PFR_CHECK( 2 ); - subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; - } - - /* read offset */ - switch ( format & 3 ) - { - case 1: - PFR_CHECK( 2 ); - x_pos = PFR_NEXT_SHORT( p ); - break; - - case 2: - PFR_CHECK( 1 ); - x_pos += PFR_NEXT_INT8( p ); - break; - - default: - ; - } - - switch ( ( format >> 2 ) & 3 ) - { - case 1: - PFR_CHECK( 2 ); - y_pos = PFR_NEXT_SHORT( p ); - break; - - case 2: - PFR_CHECK( 1 ); - y_pos += PFR_NEXT_INT8( p ); - break; - - default: - ; - } - - subglyph->x_delta = x_pos; - subglyph->y_delta = y_pos; - - /* read glyph position and size now */ - if ( format & PFR_SUBGLYPH_2BYTE_SIZE ) - { - PFR_CHECK( 2 ); - subglyph->gps_size = PFR_NEXT_USHORT( p ); - } - else - { - PFR_CHECK( 1 ); - subglyph->gps_size = PFR_NEXT_BYTE( p ); - } - - if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) - { - PFR_CHECK( 3 ); - subglyph->gps_offset = PFR_NEXT_LONG( p ); - } - else - { - PFR_CHECK( 2 ); - subglyph->gps_offset = PFR_NEXT_USHORT( p ); - } - - glyph->num_subs++; - } - - Exit: - return error; - - Failure: - Too_Short: - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" )); - goto Exit; - } - - - static FT_Error - pfr_glyph_load_rec( PFR_Glyph glyph, - FT_Stream stream, - FT_ULong gps_offset, - FT_ULong offset, - FT_ULong size ) - { - FT_Error error; - FT_Byte* p; - FT_Byte* limit; - - - if ( FT_STREAM_SEEK( gps_offset + offset ) || - FT_FRAME_ENTER( size ) ) - goto Exit; - - p = (FT_Byte*)stream->cursor; - limit = p + size; - - if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) - { - FT_Int n, old_count, count; - FT_GlyphLoader loader = glyph->loader; - FT_Outline* base = &loader->base.outline; - - - old_count = glyph->num_subs; - - /* this is a compound glyph - load it */ - error = pfr_glyph_load_compound( glyph, p, limit ); - - FT_FRAME_EXIT(); - - if ( error ) - goto Exit; - - count = glyph->num_subs - old_count; - - FT_TRACE4(( "compound glyph with %d elements (offset %lu):\n", - count, offset )); - - /* now, load each individual glyph */ - for ( n = 0; n < count; n++ ) - { - FT_Int i, old_points, num_points; - PFR_SubGlyph subglyph; - - - FT_TRACE4(( "subglyph %d:\n", n )); - - subglyph = glyph->subs + old_count + n; - old_points = base->n_points; - - error = pfr_glyph_load_rec( glyph, stream, gps_offset, - subglyph->gps_offset, - subglyph->gps_size ); - if ( error ) - break; - - /* note that `glyph->subs' might have been re-allocated */ - subglyph = glyph->subs + old_count + n; - num_points = base->n_points - old_points; - - /* translate and eventually scale the new glyph points */ - if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L ) - { - FT_Vector* vec = base->points + old_points; - - - for ( i = 0; i < num_points; i++, vec++ ) - { - vec->x = FT_MulFix( vec->x, subglyph->x_scale ) + - subglyph->x_delta; - vec->y = FT_MulFix( vec->y, subglyph->y_scale ) + - subglyph->y_delta; - } - } - else - { - FT_Vector* vec = loader->base.outline.points + old_points; - - - for ( i = 0; i < num_points; i++, vec++ ) - { - vec->x += subglyph->x_delta; - vec->y += subglyph->y_delta; - } - } - - /* proceed to next sub-glyph */ - } - - FT_TRACE4(( "end compound glyph with %d elements\n", count )); - } - else - { - FT_TRACE4(( "simple glyph (offset %lu)\n", offset )); - - /* load a simple glyph */ - error = pfr_glyph_load_simple( glyph, p, limit ); - - FT_FRAME_EXIT(); - } - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - pfr_glyph_load( PFR_Glyph glyph, - FT_Stream stream, - FT_ULong gps_offset, - FT_ULong offset, - FT_ULong size ) - { - /* initialize glyph loader */ - FT_GlyphLoader_Rewind( glyph->loader ); - - glyph->num_subs = 0; - - /* load the glyph, recursively when needed */ - return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrgload.h b/drivers/freetype/freetype/src/pfr/pfrgload.h deleted file mode 100644 index 7cc7a8702a..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrgload.h +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrgload.h */ -/* */ -/* FreeType PFR glyph loader (specification). */ -/* */ -/* Copyright 2002 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 __PFRGLOAD_H__ -#define __PFRGLOAD_H__ - -#include "pfrtypes.h" - -FT_BEGIN_HEADER - - - FT_LOCAL( void ) - pfr_glyph_init( PFR_Glyph glyph, - FT_GlyphLoader loader ); - - FT_LOCAL( void ) - pfr_glyph_done( PFR_Glyph glyph ); - - - FT_LOCAL( FT_Error ) - pfr_glyph_load( PFR_Glyph glyph, - FT_Stream stream, - FT_ULong gps_offset, - FT_ULong offset, - FT_ULong size ); - - -FT_END_HEADER - - -#endif /* __PFRGLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrload.c b/drivers/freetype/freetype/src/pfr/pfrload.c deleted file mode 100644 index c19fceb1ee..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrload.c +++ /dev/null @@ -1,941 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrload.c */ -/* */ -/* FreeType PFR loader (body). */ -/* */ -/* Copyright 2002-2005, 2007, 2009, 2010, 2013 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 "pfrload.h" -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H - -#include "pfrerror.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pfr - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** EXTRA ITEMS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL_DEF( FT_Error ) - pfr_extra_items_skip( FT_Byte* *pp, - FT_Byte* limit ) - { - return pfr_extra_items_parse( pp, limit, NULL, NULL ); - } - - - FT_LOCAL_DEF( FT_Error ) - pfr_extra_items_parse( FT_Byte* *pp, - FT_Byte* limit, - PFR_ExtraItem item_list, - FT_Pointer item_data ) - { - FT_Error error = FT_Err_Ok; - FT_Byte* p = *pp; - FT_UInt num_items, item_type, item_size; - - - PFR_CHECK( 1 ); - num_items = PFR_NEXT_BYTE( p ); - - for ( ; num_items > 0; num_items-- ) - { - PFR_CHECK( 2 ); - item_size = PFR_NEXT_BYTE( p ); - item_type = PFR_NEXT_BYTE( p ); - - PFR_CHECK( item_size ); - - if ( item_list ) - { - PFR_ExtraItem extra = item_list; - - - for ( extra = item_list; extra->parser != NULL; extra++ ) - { - if ( extra->type == item_type ) - { - error = extra->parser( p, p + item_size, item_data ); - if ( error ) goto Exit; - - break; - } - } - } - - p += item_size; - } - - Exit: - *pp = p; - return error; - - Too_Short: - FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PFR HEADER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static const FT_Frame_Field pfr_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE PFR_HeaderRec - - FT_FRAME_START( 58 ), - FT_FRAME_ULONG ( signature ), - FT_FRAME_USHORT( version ), - FT_FRAME_USHORT( signature2 ), - FT_FRAME_USHORT( header_size ), - - FT_FRAME_USHORT( log_dir_size ), - FT_FRAME_USHORT( log_dir_offset ), - - FT_FRAME_USHORT( log_font_max_size ), - FT_FRAME_UOFF3 ( log_font_section_size ), - FT_FRAME_UOFF3 ( log_font_section_offset ), - - FT_FRAME_USHORT( phy_font_max_size ), - FT_FRAME_UOFF3 ( phy_font_section_size ), - FT_FRAME_UOFF3 ( phy_font_section_offset ), - - FT_FRAME_USHORT( gps_max_size ), - FT_FRAME_UOFF3 ( gps_section_size ), - FT_FRAME_UOFF3 ( gps_section_offset ), - - FT_FRAME_BYTE ( max_blue_values ), - FT_FRAME_BYTE ( max_x_orus ), - FT_FRAME_BYTE ( max_y_orus ), - - FT_FRAME_BYTE ( phy_font_max_size_high ), - FT_FRAME_BYTE ( color_flags ), - - FT_FRAME_UOFF3 ( bct_max_size ), - FT_FRAME_UOFF3 ( bct_set_max_size ), - FT_FRAME_UOFF3 ( phy_bct_set_max_size ), - - FT_FRAME_USHORT( num_phy_fonts ), - FT_FRAME_BYTE ( max_vert_stem_snap ), - FT_FRAME_BYTE ( max_horz_stem_snap ), - FT_FRAME_USHORT( max_chars ), - FT_FRAME_END - }; - - - FT_LOCAL_DEF( FT_Error ) - pfr_header_load( PFR_Header header, - FT_Stream stream ) - { - FT_Error error; - - - /* read header directly */ - if ( !FT_STREAM_SEEK( 0 ) && - !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) ) - { - /* make a few adjustments to the header */ - header->phy_font_max_size += - (FT_UInt32)header->phy_font_max_size_high << 16; - } - - return error; - } - - - FT_LOCAL_DEF( FT_Bool ) - pfr_header_check( PFR_Header header ) - { - FT_Bool result = 1; - - - /* check signature and header size */ - if ( header->signature != 0x50465230L || /* "PFR0" */ - header->version > 4 || - header->header_size < 58 || - header->signature2 != 0x0d0a ) /* CR/LF */ - { - result = 0; - } - return result; - } - - - /***********************************************************************/ - /***********************************************************************/ - /***** *****/ - /***** PFR LOGICAL FONTS *****/ - /***** *****/ - /***********************************************************************/ - /***********************************************************************/ - - - FT_LOCAL_DEF( FT_Error ) - pfr_log_font_count( FT_Stream stream, - FT_UInt32 section_offset, - FT_UInt *acount ) - { - FT_Error error; - FT_UInt count; - FT_UInt result = 0; - - - if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) - goto Exit; - - result = count; - - Exit: - *acount = result; - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - pfr_log_font_load( PFR_LogFont log_font, - FT_Stream stream, - FT_UInt idx, - FT_UInt32 section_offset, - FT_Bool size_increment ) - { - FT_UInt num_log_fonts; - FT_UInt flags; - FT_UInt32 offset; - FT_UInt32 size; - FT_Error error; - - - if ( FT_STREAM_SEEK( section_offset ) || - FT_READ_USHORT( num_log_fonts ) ) - goto Exit; - - if ( idx >= num_log_fonts ) - return FT_THROW( Invalid_Argument ); - - if ( FT_STREAM_SKIP( idx * 5 ) || - FT_READ_USHORT( size ) || - FT_READ_UOFF3 ( offset ) ) - goto Exit; - - /* save logical font size and offset */ - log_font->size = size; - log_font->offset = offset; - - /* now, check the rest of the table before loading it */ - { - FT_Byte* p; - FT_Byte* limit; - FT_UInt local; - - - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) - goto Exit; - - p = stream->cursor; - limit = p + size; - - PFR_CHECK(13); - - log_font->matrix[0] = PFR_NEXT_LONG( p ); - log_font->matrix[1] = PFR_NEXT_LONG( p ); - log_font->matrix[2] = PFR_NEXT_LONG( p ); - log_font->matrix[3] = PFR_NEXT_LONG( p ); - - flags = PFR_NEXT_BYTE( p ); - - local = 0; - if ( flags & PFR_LOG_STROKE ) - { - local++; - if ( flags & PFR_LOG_2BYTE_STROKE ) - local++; - - if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) - local += 3; - } - if ( flags & PFR_LOG_BOLD ) - { - local++; - if ( flags & PFR_LOG_2BYTE_BOLD ) - local++; - } - - PFR_CHECK( local ); - - if ( flags & PFR_LOG_STROKE ) - { - log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE ) - ? PFR_NEXT_SHORT( p ) - : PFR_NEXT_BYTE( p ); - - if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) - log_font->miter_limit = PFR_NEXT_LONG( p ); - } - - if ( flags & PFR_LOG_BOLD ) - { - log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD ) - ? PFR_NEXT_SHORT( p ) - : PFR_NEXT_BYTE( p ); - } - - if ( flags & PFR_LOG_EXTRA_ITEMS ) - { - error = pfr_extra_items_skip( &p, limit ); - if (error) goto Fail; - } - - PFR_CHECK(5); - log_font->phys_size = PFR_NEXT_USHORT( p ); - log_font->phys_offset = PFR_NEXT_ULONG( p ); - if ( size_increment ) - { - PFR_CHECK( 1 ); - log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16; - } - } - - Fail: - FT_FRAME_EXIT(); - - Exit: - return error; - - Too_Short: - FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" )); - error = FT_THROW( Invalid_Table ); - goto Fail; - } - - - /***********************************************************************/ - /***********************************************************************/ - /***** *****/ - /***** PFR PHYSICAL FONTS *****/ - /***** *****/ - /***********************************************************************/ - /***********************************************************************/ - - - /* load bitmap strikes lists */ - FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_bitmap_info( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) - { - FT_Memory memory = phy_font->memory; - PFR_Strike strike; - FT_UInt flags0; - FT_UInt n, count, size1; - FT_Error error = FT_Err_Ok; - - - PFR_CHECK( 5 ); - - p += 3; /* skip bctSize */ - flags0 = PFR_NEXT_BYTE( p ); - count = PFR_NEXT_BYTE( p ); - - /* re-allocate when needed */ - if ( phy_font->num_strikes + count > phy_font->max_strikes ) - { - FT_UInt new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 ); - - - if ( FT_RENEW_ARRAY( phy_font->strikes, - phy_font->num_strikes, - new_max ) ) - goto Exit; - - phy_font->max_strikes = new_max; - } - - size1 = 1 + 1 + 1 + 2 + 2 + 1; - if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) - size1++; - - if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) - size1++; - - if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) - size1++; - - if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) - size1++; - - if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) - size1++; - - strike = phy_font->strikes + phy_font->num_strikes; - - PFR_CHECK( count * size1 ); - - for ( n = 0; n < count; n++, strike++ ) - { - strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) - ? PFR_NEXT_USHORT( p ) - : PFR_NEXT_BYTE( p ); - - strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) - ? PFR_NEXT_USHORT( p ) - : PFR_NEXT_BYTE( p ); - - strike->flags = PFR_NEXT_BYTE( p ); - - strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) - ? PFR_NEXT_ULONG( p ) - : PFR_NEXT_USHORT( p ); - - strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) - ? PFR_NEXT_ULONG( p ) - : PFR_NEXT_USHORT( p ); - - strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) - ? PFR_NEXT_USHORT( p ) - : PFR_NEXT_BYTE( p ); - } - - phy_font->num_strikes += count; - - Exit: - return error; - - Too_Short: - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_extra_item_load_bitmap_info:" - " invalid bitmap info table\n" )); - goto Exit; - } - - - /* Load font ID. This is a so-called "unique" name that is rather - * long and descriptive (like "Tiresias ScreenFont v7.51"). - * - * Note that a PFR font's family name is contained in an *undocumented* - * string of the "auxiliary data" portion of a physical font record. This - * may also contain the "real" style name! - * - * If no family name is present, the font ID is used instead for the - * family. - */ - FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_font_id( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) - { - FT_Error error = FT_Err_Ok; - FT_Memory memory = phy_font->memory; - FT_PtrDist len = limit - p; - - - if ( phy_font->font_id != NULL ) - goto Exit; - - if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) - goto Exit; - - /* copy font ID name, and terminate it for safety */ - FT_MEM_COPY( phy_font->font_id, p, len ); - phy_font->font_id[len] = 0; - - Exit: - return error; - } - - - /* load stem snap tables */ - FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_stem_snaps( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) - { - FT_UInt count, num_vert, num_horz; - FT_Int* snaps = NULL; - FT_Error error = FT_Err_Ok; - FT_Memory memory = phy_font->memory; - - - if ( phy_font->vertical.stem_snaps != NULL ) - goto Exit; - - PFR_CHECK( 1 ); - count = PFR_NEXT_BYTE( p ); - - num_vert = count & 15; - num_horz = count >> 4; - count = num_vert + num_horz; - - PFR_CHECK( count * 2 ); - - if ( FT_NEW_ARRAY( snaps, count ) ) - goto Exit; - - phy_font->vertical.stem_snaps = snaps; - phy_font->horizontal.stem_snaps = snaps + num_vert; - - for ( ; count > 0; count--, snaps++ ) - *snaps = FT_NEXT_SHORT( p ); - - Exit: - return error; - - Too_Short: - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_exta_item_load_stem_snaps:" - " invalid stem snaps table\n" )); - goto Exit; - } - - - - /* load kerning pair data */ - FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_kerning_pairs( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) - { - PFR_KernItem item = NULL; - FT_Error error = FT_Err_Ok; - FT_Memory memory = phy_font->memory; - - - FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); - - if ( FT_NEW( item ) ) - goto Exit; - - PFR_CHECK( 4 ); - - item->pair_count = PFR_NEXT_BYTE( p ); - item->base_adj = PFR_NEXT_SHORT( p ); - item->flags = PFR_NEXT_BYTE( p ); - item->offset = phy_font->offset + ( p - phy_font->cursor ); - -#ifndef PFR_CONFIG_NO_CHECKS - item->pair_size = 3; - - if ( item->flags & PFR_KERN_2BYTE_CHAR ) - item->pair_size += 2; - - if ( item->flags & PFR_KERN_2BYTE_ADJ ) - item->pair_size += 1; - - PFR_CHECK( item->pair_count * item->pair_size ); -#endif - - /* load first and last pairs into the item to speed up */ - /* lookup later... */ - if ( item->pair_count > 0 ) - { - FT_UInt char1, char2; - FT_Byte* q; - - - if ( item->flags & PFR_KERN_2BYTE_CHAR ) - { - q = p; - char1 = PFR_NEXT_USHORT( q ); - char2 = PFR_NEXT_USHORT( q ); - - item->pair1 = PFR_KERN_INDEX( char1, char2 ); - - q = p + item->pair_size * ( item->pair_count - 1 ); - char1 = PFR_NEXT_USHORT( q ); - char2 = PFR_NEXT_USHORT( q ); - - item->pair2 = PFR_KERN_INDEX( char1, char2 ); - } - else - { - q = p; - char1 = PFR_NEXT_BYTE( q ); - char2 = PFR_NEXT_BYTE( q ); - - item->pair1 = PFR_KERN_INDEX( char1, char2 ); - - q = p + item->pair_size * ( item->pair_count - 1 ); - char1 = PFR_NEXT_BYTE( q ); - char2 = PFR_NEXT_BYTE( q ); - - item->pair2 = PFR_KERN_INDEX( char1, char2 ); - } - - /* add new item to the current list */ - item->next = NULL; - *phy_font->kern_items_tail = item; - phy_font->kern_items_tail = &item->next; - phy_font->num_kern_pairs += item->pair_count; - } - else - { - /* empty item! */ - FT_FREE( item ); - } - - Exit: - return error; - - Too_Short: - FT_FREE( item ); - - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_extra_item_load_kerning_pairs:" - " invalid kerning pairs table\n" )); - goto Exit; - } - - - - static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = - { - { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, - { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id }, - { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps }, - { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs }, - { 0, NULL } - }; - - - /* Loads a name from the auxiliary data. Since this extracts undocumented - * strings from the font file, we need to be careful here. - */ - static FT_Error - pfr_aux_name_load( FT_Byte* p, - FT_UInt len, - FT_Memory memory, - FT_String* *astring ) - { - FT_Error error = FT_Err_Ok; - FT_String* result = NULL; - FT_UInt n, ok; - - - if ( len > 0 && p[len - 1] == 0 ) - len--; - - /* check that each character is ASCII for making sure not to - load garbage - */ - ok = ( len > 0 ); - for ( n = 0; n < len; n++ ) - if ( p[n] < 32 || p[n] > 127 ) - { - ok = 0; - break; - } - - if ( ok ) - { - if ( FT_ALLOC( result, len + 1 ) ) - goto Exit; - - FT_MEM_COPY( result, p, len ); - result[len] = 0; - } - Exit: - *astring = result; - return error; - } - - - FT_LOCAL_DEF( void ) - pfr_phy_font_done( PFR_PhyFont phy_font, - FT_Memory memory ) - { - FT_FREE( phy_font->font_id ); - FT_FREE( phy_font->family_name ); - FT_FREE( phy_font->style_name ); - - FT_FREE( phy_font->vertical.stem_snaps ); - phy_font->vertical.num_stem_snaps = 0; - - phy_font->horizontal.stem_snaps = NULL; - phy_font->horizontal.num_stem_snaps = 0; - - FT_FREE( phy_font->strikes ); - phy_font->num_strikes = 0; - phy_font->max_strikes = 0; - - FT_FREE( phy_font->chars ); - phy_font->num_chars = 0; - phy_font->chars_offset = 0; - - FT_FREE( phy_font->blue_values ); - phy_font->num_blue_values = 0; - - { - PFR_KernItem item, next; - - - item = phy_font->kern_items; - while ( item ) - { - next = item->next; - FT_FREE( item ); - item = next; - } - phy_font->kern_items = NULL; - phy_font->kern_items_tail = NULL; - } - - phy_font->num_kern_pairs = 0; - } - - - FT_LOCAL_DEF( FT_Error ) - pfr_phy_font_load( PFR_PhyFont phy_font, - FT_Stream stream, - FT_UInt32 offset, - FT_UInt32 size ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_UInt flags; - FT_ULong num_aux; - FT_Byte* p; - FT_Byte* limit; - - - phy_font->memory = memory; - phy_font->offset = offset; - - phy_font->kern_items = NULL; - phy_font->kern_items_tail = &phy_font->kern_items; - - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) - goto Exit; - - phy_font->cursor = stream->cursor; - - p = stream->cursor; - limit = p + size; - - PFR_CHECK( 15 ); - phy_font->font_ref_number = PFR_NEXT_USHORT( p ); - phy_font->outline_resolution = PFR_NEXT_USHORT( p ); - phy_font->metrics_resolution = PFR_NEXT_USHORT( p ); - phy_font->bbox.xMin = PFR_NEXT_SHORT( p ); - phy_font->bbox.yMin = PFR_NEXT_SHORT( p ); - phy_font->bbox.xMax = PFR_NEXT_SHORT( p ); - phy_font->bbox.yMax = PFR_NEXT_SHORT( p ); - phy_font->flags = flags = PFR_NEXT_BYTE( p ); - - /* get the standard advance for non-proportional fonts */ - if ( !(flags & PFR_PHY_PROPORTIONAL) ) - { - PFR_CHECK( 2 ); - phy_font->standard_advance = PFR_NEXT_SHORT( p ); - } - - /* load the extra items when present */ - if ( flags & PFR_PHY_EXTRA_ITEMS ) - { - error = pfr_extra_items_parse( &p, limit, - pfr_phy_font_extra_items, phy_font ); - - if ( error ) - goto Fail; - } - - /* In certain fonts, the auxiliary bytes contain interesting */ - /* information. These are not in the specification but can be */ - /* guessed by looking at the content of a few PFR0 fonts. */ - PFR_CHECK( 3 ); - num_aux = PFR_NEXT_ULONG( p ); - - if ( num_aux > 0 ) - { - FT_Byte* q = p; - FT_Byte* q2; - - - PFR_CHECK( num_aux ); - p += num_aux; - - while ( num_aux > 0 ) - { - FT_UInt length, type; - - - if ( q + 4 > p ) - break; - - length = PFR_NEXT_USHORT( q ); - if ( length < 4 || length > num_aux ) - break; - - q2 = q + length - 2; - type = PFR_NEXT_USHORT( q ); - - switch ( type ) - { - case 1: - /* this seems to correspond to the font's family name, - * padded to 16-bits with one zero when necessary - */ - error = pfr_aux_name_load( q, length - 4U, memory, - &phy_font->family_name ); - if ( error ) - goto Exit; - break; - - case 2: - if ( q + 32 > q2 ) - break; - - q += 10; - phy_font->ascent = PFR_NEXT_SHORT( q ); - phy_font->descent = PFR_NEXT_SHORT( q ); - phy_font->leading = PFR_NEXT_SHORT( q ); - q += 16; - break; - - case 3: - /* this seems to correspond to the font's style name, - * padded to 16-bits with one zero when necessary - */ - error = pfr_aux_name_load( q, length - 4U, memory, - &phy_font->style_name ); - if ( error ) - goto Exit; - break; - - default: - ; - } - - q = q2; - num_aux -= length; - } - } - - /* read the blue values */ - { - FT_UInt n, count; - - - PFR_CHECK( 1 ); - phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); - - PFR_CHECK( count * 2 ); - - if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) - goto Fail; - - for ( n = 0; n < count; n++ ) - phy_font->blue_values[n] = PFR_NEXT_SHORT( p ); - } - - PFR_CHECK( 8 ); - phy_font->blue_fuzz = PFR_NEXT_BYTE( p ); - phy_font->blue_scale = PFR_NEXT_BYTE( p ); - - phy_font->vertical.standard = PFR_NEXT_USHORT( p ); - phy_font->horizontal.standard = PFR_NEXT_USHORT( p ); - - /* read the character descriptors */ - { - FT_UInt n, count, Size; - - - phy_font->num_chars = count = PFR_NEXT_USHORT( p ); - phy_font->chars_offset = offset + ( p - stream->cursor ); - - if ( FT_NEW_ARRAY( phy_font->chars, count ) ) - goto Fail; - - Size = 1 + 1 + 2; - if ( flags & PFR_PHY_2BYTE_CHARCODE ) - Size += 1; - - if ( flags & PFR_PHY_PROPORTIONAL ) - Size += 2; - - if ( flags & PFR_PHY_ASCII_CODE ) - Size += 1; - - if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) - Size += 1; - - if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) - Size += 1; - - PFR_CHECK( count * Size ); - - for ( n = 0; n < count; n++ ) - { - PFR_Char cur = &phy_font->chars[n]; - - - cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) - ? PFR_NEXT_USHORT( p ) - : PFR_NEXT_BYTE( p ); - - cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) - ? PFR_NEXT_SHORT( p ) - : (FT_Int) phy_font->standard_advance; - -#if 0 - cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) - ? PFR_NEXT_BYTE( p ) - : 0; -#else - if ( flags & PFR_PHY_ASCII_CODE ) - p += 1; -#endif - cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) - ? PFR_NEXT_USHORT( p ) - : PFR_NEXT_BYTE( p ); - - cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) - ? PFR_NEXT_ULONG( p ) - : PFR_NEXT_USHORT( p ); - } - } - - /* that's it! */ - - Fail: - FT_FRAME_EXIT(); - - /* save position of bitmap info */ - phy_font->bct_offset = FT_STREAM_POS(); - phy_font->cursor = NULL; - - Exit: - return error; - - Too_Short: - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); - goto Fail; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrload.h b/drivers/freetype/freetype/src/pfr/pfrload.h deleted file mode 100644 index ed010715d1..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrload.h +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrload.h */ -/* */ -/* FreeType PFR loader (specification). */ -/* */ -/* Copyright 2002 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 __PFRLOAD_H__ -#define __PFRLOAD_H__ - -#include "pfrobjs.h" -#include FT_INTERNAL_STREAM_H - - -FT_BEGIN_HEADER - -#ifdef PFR_CONFIG_NO_CHECKS -#define PFR_CHECK( x ) do { } while ( 0 ) -#else -#define PFR_CHECK( x ) do \ - { \ - if ( p + (x) > limit ) \ - goto Too_Short; \ - } while ( 0 ) -#endif - -#define PFR_NEXT_BYTE( p ) FT_NEXT_BYTE( p ) -#define PFR_NEXT_INT8( p ) FT_NEXT_CHAR( p ) -#define PFR_NEXT_SHORT( p ) FT_NEXT_SHORT( p ) -#define PFR_NEXT_USHORT( p ) FT_NEXT_USHORT( p ) -#define PFR_NEXT_LONG( p ) FT_NEXT_OFF3( p ) -#define PFR_NEXT_ULONG( p ) FT_NEXT_UOFF3( p ) - - - /* handling extra items */ - - typedef FT_Error - (*PFR_ExtraItem_ParseFunc)( FT_Byte* p, - FT_Byte* limit, - FT_Pointer data ); - - typedef struct PFR_ExtraItemRec_ - { - 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, - FT_Byte* limit ); - - FT_LOCAL( FT_Error ) - pfr_extra_items_parse( FT_Byte* *pp, - FT_Byte* limit, - PFR_ExtraItem item_list, - FT_Pointer item_data ); - - - /* load a PFR header */ - FT_LOCAL( FT_Error ) - pfr_header_load( PFR_Header header, - FT_Stream stream ); - - /* check a PFR header */ - FT_LOCAL( FT_Bool ) - pfr_header_check( PFR_Header header ); - - - /* return number of logical fonts in this file */ - FT_LOCAL( FT_Error ) - pfr_log_font_count( FT_Stream stream, - FT_UInt32 log_section_offset, - FT_UInt *acount ); - - /* load a pfr logical font entry */ - FT_LOCAL( FT_Error ) - pfr_log_font_load( PFR_LogFont log_font, - FT_Stream stream, - FT_UInt face_index, - FT_UInt32 section_offset, - FT_Bool size_increment ); - - - /* load a physical font entry */ - FT_LOCAL( FT_Error ) - pfr_phy_font_load( PFR_PhyFont phy_font, - FT_Stream stream, - FT_UInt32 offset, - FT_UInt32 size ); - - /* finalize a physical font */ - FT_LOCAL( void ) - pfr_phy_font_done( PFR_PhyFont phy_font, - FT_Memory memory ); - - /* */ - -FT_END_HEADER - -#endif /* __PFRLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrobjs.c b/drivers/freetype/freetype/src/pfr/pfrobjs.c deleted file mode 100644 index 75fc4c3f1f..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrobjs.c +++ /dev/null @@ -1,593 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrobjs.c */ -/* */ -/* FreeType PFR object methods (body). */ -/* */ -/* Copyright 2002-2008, 2010-2011, 2013 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 "pfrobjs.h" -#include "pfrload.h" -#include "pfrgload.h" -#include "pfrcmap.h" -#include "pfrsbit.h" -#include FT_OUTLINE_H -#include FT_INTERNAL_DEBUG_H -#include FT_TRUETYPE_IDS_H - -#include "pfrerror.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pfr - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FACE OBJECT METHODS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - pfr_face_done( FT_Face pfrface ) /* PFR_Face */ - { - PFR_Face face = (PFR_Face)pfrface; - FT_Memory memory; - - - if ( !face ) - return; - - memory = pfrface->driver->root.memory; - - /* we don't want dangling pointers */ - pfrface->family_name = NULL; - pfrface->style_name = NULL; - - /* finalize the physical font record */ - pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); - - /* no need to finalize the logical font or the header */ - FT_FREE( pfrface->available_sizes ); - } - - - FT_LOCAL_DEF( FT_Error ) - pfr_face_init( FT_Stream stream, - FT_Face pfrface, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - PFR_Face face = (PFR_Face)pfrface; - FT_Error error; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - - - FT_TRACE2(( "PFR driver\n" )); - - /* load the header and check it */ - error = pfr_header_load( &face->header, stream ); - if ( error ) - goto Exit; - - if ( !pfr_header_check( &face->header ) ) - { - FT_TRACE2(( " not a PFR font\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - /* check face index */ - { - FT_UInt num_faces; - - - error = pfr_log_font_count( stream, - face->header.log_dir_offset, - &num_faces ); - if ( error ) - goto Exit; - - pfrface->num_faces = num_faces; - } - - if ( face_index < 0 ) - goto Exit; - - if ( face_index >= pfrface->num_faces ) - { - FT_ERROR(( "pfr_face_init: invalid face index\n" )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* load the face */ - error = pfr_log_font_load( - &face->log_font, stream, face_index, - face->header.log_dir_offset, - FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); - if ( error ) - goto Exit; - - /* now load the physical font descriptor */ - error = pfr_phy_font_load( &face->phy_font, stream, - face->log_font.phys_offset, - face->log_font.phys_size ); - if ( error ) - goto Exit; - - /* 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 + 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 ) - { - if ( phy_font->num_strikes > 0 ) - pfrface->face_flags = 0; /* not scalable */ - else - { - FT_ERROR(( "pfr_face_init: font doesn't contain glyphs\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - } - } - - if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) - pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - if ( phy_font->flags & PFR_PHY_VERTICAL ) - pfrface->face_flags |= FT_FACE_FLAG_VERTICAL; - else - pfrface->face_flags |= FT_FACE_FLAG_HORIZONTAL; - - if ( phy_font->num_strikes > 0 ) - pfrface->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - - if ( phy_font->num_kern_pairs > 0 ) - pfrface->face_flags |= FT_FACE_FLAG_KERNING; - - /* If no family name was found in the "undocumented" auxiliary - * data, use the font ID instead. This sucks but is better than - * nothing. - */ - pfrface->family_name = phy_font->family_name; - if ( pfrface->family_name == NULL ) - pfrface->family_name = phy_font->font_id; - - /* note that the style name can be NULL in certain PFR fonts, - * probably meaning "Regular" - */ - pfrface->style_name = phy_font->style_name; - - pfrface->num_fixed_sizes = 0; - pfrface->available_sizes = 0; - - pfrface->bbox = phy_font->bbox; - pfrface->units_per_EM = (FT_UShort)phy_font->outline_resolution; - pfrface->ascender = (FT_Short) phy_font->bbox.yMax; - pfrface->descender = (FT_Short) phy_font->bbox.yMin; - - pfrface->height = (FT_Short)( ( pfrface->units_per_EM * 12 ) / 10 ); - if ( pfrface->height < pfrface->ascender - pfrface->descender ) - pfrface->height = (FT_Short)(pfrface->ascender - pfrface->descender); - - if ( phy_font->num_strikes > 0 ) - { - FT_UInt n, count = phy_font->num_strikes; - FT_Bitmap_Size* size; - PFR_Strike strike; - FT_Memory memory = pfrface->stream->memory; - - - if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) ) - goto Exit; - - size = pfrface->available_sizes; - strike = phy_font->strikes; - for ( n = 0; n < count; n++, size++, strike++ ) - { - size->height = (FT_UShort)strike->y_ppm; - size->width = (FT_UShort)strike->x_ppm; - size->size = strike->y_ppm << 6; - size->x_ppem = strike->x_ppm << 6; - size->y_ppem = strike->y_ppm << 6; - } - pfrface->num_fixed_sizes = count; - } - - /* now compute maximum advance width */ - if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) - pfrface->max_advance_width = (FT_Short)phy_font->standard_advance; - else - { - FT_Int max = 0; - FT_UInt count = phy_font->num_chars; - PFR_Char gchar = phy_font->chars; - - - for ( ; count > 0; count--, gchar++ ) - { - if ( max < gchar->advance ) - max = gchar->advance; - } - - pfrface->max_advance_width = (FT_Short)max; - } - - pfrface->max_advance_height = pfrface->height; - - pfrface->underline_position = (FT_Short)( -pfrface->units_per_EM / 10 ); - pfrface->underline_thickness = (FT_Short)( pfrface->units_per_EM / 30 ); - - /* create charmap */ - { - FT_CharMapRec charmap; - - - charmap.face = pfrface; - charmap.platform_id = TT_PLATFORM_MICROSOFT; - charmap.encoding_id = TT_MS_ID_UNICODE_CS; - charmap.encoding = FT_ENCODING_UNICODE; - - error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( pfrface->num_charmaps ) - pfrface->charmap = pfrface->charmaps[0]; -#endif - } - - /* check whether we've loaded any kerning pairs */ - if ( phy_font->num_kern_pairs ) - pfrface->face_flags |= FT_FACE_FLAG_KERNING; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SLOT OBJECT METHOD *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( FT_Error ) - pfr_slot_init( FT_GlyphSlot pfrslot ) /* PFR_Slot */ - { - PFR_Slot slot = (PFR_Slot)pfrslot; - FT_GlyphLoader loader = pfrslot->internal->loader; - - - pfr_glyph_init( &slot->glyph, loader ); - - return 0; - } - - - FT_LOCAL_DEF( void ) - pfr_slot_done( FT_GlyphSlot pfrslot ) /* PFR_Slot */ - { - PFR_Slot slot = (PFR_Slot)pfrslot; - - - pfr_glyph_done( &slot->glyph ); - } - - - FT_LOCAL_DEF( FT_Error ) - pfr_slot_load( FT_GlyphSlot pfrslot, /* PFR_Slot */ - FT_Size pfrsize, /* PFR_Size */ - FT_UInt gindex, - FT_Int32 load_flags ) - { - PFR_Slot slot = (PFR_Slot)pfrslot; - PFR_Size size = (PFR_Size)pfrsize; - FT_Error error; - PFR_Face face = (PFR_Face)pfrslot->face; - PFR_Char gchar; - FT_Outline* outline = &pfrslot->outline; - FT_ULong gps_offset; - - - if ( gindex > 0 ) - gindex--; - - if ( !face || gindex >= face->phy_font.num_chars ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* try to load an embedded bitmap */ - if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) - { - error = pfr_slot_load_bitmap( slot, size, gindex ); - if ( error == 0 ) - goto Exit; - } - - if ( load_flags & FT_LOAD_SBITS_ONLY ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - gchar = face->phy_font.chars + gindex; - pfrslot->format = FT_GLYPH_FORMAT_OUTLINE; - outline->n_points = 0; - outline->n_contours = 0; - gps_offset = face->header.gps_section_offset; - - /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */ - error = pfr_glyph_load( &slot->glyph, face->root.stream, - gps_offset, gchar->gps_offset, gchar->gps_size ); - - if ( !error ) - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &pfrslot->metrics; - FT_Pos advance; - FT_Int em_metrics, em_outline; - FT_Bool scaling; - - - scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); - - /* copy outline data */ - *outline = slot->glyph.loader->base.outline; - - outline->flags &= ~FT_OUTLINE_OWNER; - outline->flags |= FT_OUTLINE_REVERSE_FILL; - - if ( size && pfrsize->metrics.y_ppem < 24 ) - outline->flags |= FT_OUTLINE_HIGH_PRECISION; - - /* compute the advance vector */ - metrics->horiAdvance = 0; - metrics->vertAdvance = 0; - - advance = gchar->advance; - em_metrics = face->phy_font.metrics_resolution; - em_outline = face->phy_font.outline_resolution; - - if ( em_metrics != em_outline ) - advance = FT_MulDiv( advance, em_outline, em_metrics ); - - if ( face->phy_font.flags & PFR_PHY_VERTICAL ) - metrics->vertAdvance = advance; - else - metrics->horiAdvance = advance; - - pfrslot->linearHoriAdvance = metrics->horiAdvance; - pfrslot->linearVertAdvance = metrics->vertAdvance; - - /* make-up vertical metrics(?) */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - -#if 0 /* some fonts seem to be broken here! */ - - /* Apply the font matrix, if any. */ - /* TODO: Test existing fonts with unusual matrix */ - /* whether we have to adjust Units per EM. */ - { - FT_Matrix font_matrix; - - - font_matrix.xx = face->log_font.matrix[0] << 8; - font_matrix.yx = face->log_font.matrix[1] << 8; - font_matrix.xy = face->log_font.matrix[2] << 8; - font_matrix.yy = face->log_font.matrix[3] << 8; - - FT_Outline_Transform( outline, &font_matrix ); - } -#endif - - /* scale when needed */ - if ( scaling ) - { - FT_Int n; - FT_Fixed x_scale = pfrsize->metrics.x_scale; - FT_Fixed y_scale = pfrsize->metrics.y_scale; - FT_Vector* vec = outline->points; - - - /* scale outline points */ - for ( n = 0; n < outline->n_points; n++, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - /* scale the advance */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - } - - /* compute the rest of the metrics */ - FT_Outline_Get_CBox( outline, &cbox ); - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax - metrics->height; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** KERNING METHOD *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( FT_Error ) - pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - PFR_Face face = (PFR_Face)pfrface; - FT_Error error = FT_Err_Ok; - PFR_PhyFont phy_font = &face->phy_font; - FT_UInt32 code1, code2, pair; - - - kerning->x = 0; - kerning->y = 0; - - if ( glyph1 > 0 ) - glyph1--; - - if ( glyph2 > 0 ) - glyph2--; - - /* convert glyph indices to character codes */ - if ( glyph1 > phy_font->num_chars || - glyph2 > phy_font->num_chars ) - goto Exit; - - code1 = phy_font->chars[glyph1].char_code; - code2 = phy_font->chars[glyph2].char_code; - pair = PFR_KERN_INDEX( code1, code2 ); - - /* now search the list of kerning items */ - { - PFR_KernItem item = phy_font->kern_items; - FT_Stream stream = pfrface->stream; - - - for ( ; item; item = item->next ) - { - if ( pair >= item->pair1 && pair <= item->pair2 ) - goto FoundPair; - } - goto Exit; - - FoundPair: /* we found an item, now parse it and find the value if any */ - if ( FT_STREAM_SEEK( item->offset ) || - FT_FRAME_ENTER( item->pair_count * item->pair_size ) ) - 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_Bool twobyte_adj = FT_BOOL( item->flags & 2 ); - FT_Byte* p; - FT_UInt32 cpair; - - - if ( extra > 0 ) - { - p = base + extra * size; - - if ( twobytes ) - cpair = FT_NEXT_ULONG( p ); - else - cpair = PFR_NEXT_KPAIR( p ); - - if ( cpair == pair ) - goto Found; - - if ( cpair < pair ) - { - if ( twobyte_adj ) - p += 2; - else - p++; - base = p; - } - } - - while ( probe > size ) - { - probe >>= 1; - p = base + probe; - - if ( twobytes ) - cpair = FT_NEXT_ULONG( p ); - else - cpair = PFR_NEXT_KPAIR( p ); - - if ( cpair == pair ) - goto Found; - - if ( cpair < pair ) - base += probe; - } - - p = base; - - if ( twobytes ) - cpair = FT_NEXT_ULONG( p ); - else - cpair = PFR_NEXT_KPAIR( p ); - - if ( cpair == pair ) - { - FT_Int value; - - - Found: - if ( twobyte_adj ) - value = FT_PEEK_SHORT( p ); - else - value = p[0]; - - kerning->x = item->base_adj + value; - } - } - - FT_FRAME_EXIT(); - } - - Exit: - return error; - } - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrobjs.h b/drivers/freetype/freetype/src/pfr/pfrobjs.h deleted file mode 100644 index f6aa8b44cc..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrobjs.h +++ /dev/null @@ -1,96 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrobjs.h */ -/* */ -/* FreeType PFR object methods (specification). */ -/* */ -/* Copyright 2002, 2003, 2004 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 __PFROBJS_H__ -#define __PFROBJS_H__ - -#include "pfrtypes.h" - - -FT_BEGIN_HEADER - - typedef struct PFR_FaceRec_* PFR_Face; - - typedef struct PFR_SizeRec_* PFR_Size; - - typedef struct PFR_SlotRec_* PFR_Slot; - - - typedef struct PFR_FaceRec_ - { - FT_FaceRec root; - PFR_HeaderRec header; - PFR_LogFontRec log_font; - PFR_PhyFontRec phy_font; - - } PFR_FaceRec; - - - typedef struct PFR_SizeRec_ - { - FT_SizeRec root; - - } PFR_SizeRec; - - - typedef struct PFR_SlotRec_ - { - FT_GlyphSlotRec root; - PFR_GlyphRec glyph; - - } PFR_SlotRec; - - - FT_LOCAL( FT_Error ) - pfr_face_init( FT_Stream stream, - FT_Face face, /* PFR_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - FT_LOCAL( void ) - pfr_face_done( FT_Face face ); /* PFR_Face */ - - - FT_LOCAL( FT_Error ) - pfr_face_get_kerning( FT_Face face, /* PFR_Face */ - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); - - - FT_LOCAL( FT_Error ) - pfr_slot_init( FT_GlyphSlot slot ); /* PFR_Slot */ - - FT_LOCAL( void ) - pfr_slot_done( FT_GlyphSlot slot ); /* PFR_Slot */ - - - FT_LOCAL( FT_Error ) - pfr_slot_load( FT_GlyphSlot slot, /* PFR_Slot */ - FT_Size size, /* PFR_Size */ - FT_UInt gindex, - FT_Int32 load_flags ); - - -FT_END_HEADER - -#endif /* __PFROBJS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrsbit.c b/drivers/freetype/freetype/src/pfr/pfrsbit.c deleted file mode 100644 index 2da1500707..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrsbit.c +++ /dev/null @@ -1,698 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrsbit.c */ -/* */ -/* FreeType PFR bitmap loader (body). */ -/* */ -/* Copyright 2002, 2003, 2006, 2009, 2010, 2013 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 "pfrsbit.h" -#include "pfrload.h" -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H - -#include "pfrerror.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pfr - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PFR BIT WRITER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct PFR_BitWriter_ - { - FT_Byte* line; /* current line start */ - FT_Int pitch; /* line size in bytes */ - FT_Int width; /* width in pixels/bits */ - FT_Int rows; /* number of remaining rows to scan */ - FT_Int total; /* total number of bits to draw */ - - } PFR_BitWriterRec, *PFR_BitWriter; - - - static void - pfr_bitwriter_init( PFR_BitWriter writer, - FT_Bitmap* target, - FT_Bool decreasing ) - { - writer->line = target->buffer; - writer->pitch = target->pitch; - writer->width = target->width; - writer->rows = target->rows; - writer->total = writer->width * writer->rows; - - if ( !decreasing ) - { - writer->line += writer->pitch * ( target->rows-1 ); - writer->pitch = -writer->pitch; - } - } - - - static void - pfr_bitwriter_decode_bytes( PFR_BitWriter writer, - FT_Byte* p, - FT_Byte* limit ) - { - FT_Int n, reload; - FT_Int left = writer->width; - FT_Byte* cur = writer->line; - FT_UInt mask = 0x80; - FT_UInt val = 0; - FT_UInt c = 0; - - - n = (FT_Int)( limit - p ) * 8; - if ( n > writer->total ) - n = writer->total; - - reload = n & 7; - - for ( ; n > 0; n-- ) - { - if ( ( n & 7 ) == reload ) - val = *p++; - - if ( val & 0x80 ) - c |= mask; - - val <<= 1; - mask >>= 1; - - if ( --left <= 0 ) - { - cur[0] = (FT_Byte)c; - left = writer->width; - mask = 0x80; - - writer->line += writer->pitch; - cur = writer->line; - c = 0; - } - else if ( mask == 0 ) - { - cur[0] = (FT_Byte)c; - mask = 0x80; - c = 0; - cur ++; - } - } - - if ( mask != 0x80 ) - cur[0] = (FT_Byte)c; - } - - - static void - pfr_bitwriter_decode_rle1( PFR_BitWriter writer, - FT_Byte* p, - FT_Byte* limit ) - { - FT_Int n, phase, count, counts[2], reload; - FT_Int left = writer->width; - FT_Byte* cur = writer->line; - FT_UInt mask = 0x80; - FT_UInt c = 0; - - - n = writer->total; - - phase = 1; - counts[0] = 0; - counts[1] = 0; - count = 0; - reload = 1; - - for ( ; n > 0; n-- ) - { - if ( reload ) - { - do - { - if ( phase ) - { - FT_Int v; - - - if ( p >= limit ) - break; - - v = *p++; - counts[0] = v >> 4; - counts[1] = v & 15; - phase = 0; - count = counts[0]; - } - else - { - phase = 1; - count = counts[1]; - } - - } while ( count == 0 ); - } - - if ( phase ) - c |= mask; - - mask >>= 1; - - if ( --left <= 0 ) - { - cur[0] = (FT_Byte) c; - left = writer->width; - mask = 0x80; - - writer->line += writer->pitch; - cur = writer->line; - c = 0; - } - else if ( mask == 0 ) - { - cur[0] = (FT_Byte)c; - mask = 0x80; - c = 0; - cur ++; - } - - reload = ( --count <= 0 ); - } - - if ( mask != 0x80 ) - cur[0] = (FT_Byte) c; - } - - - static void - pfr_bitwriter_decode_rle2( PFR_BitWriter writer, - FT_Byte* p, - FT_Byte* limit ) - { - FT_Int n, phase, count, reload; - FT_Int left = writer->width; - FT_Byte* cur = writer->line; - FT_UInt mask = 0x80; - FT_UInt c = 0; - - - n = writer->total; - - phase = 1; - count = 0; - reload = 1; - - for ( ; n > 0; n-- ) - { - if ( reload ) - { - do - { - if ( p >= limit ) - break; - - count = *p++; - phase = phase ^ 1; - - } while ( count == 0 ); - } - - if ( phase ) - c |= mask; - - mask >>= 1; - - if ( --left <= 0 ) - { - cur[0] = (FT_Byte) c; - c = 0; - mask = 0x80; - left = writer->width; - - writer->line += writer->pitch; - cur = writer->line; - } - else if ( mask == 0 ) - { - cur[0] = (FT_Byte)c; - c = 0; - mask = 0x80; - cur ++; - } - - reload = ( --count <= 0 ); - } - - if ( mask != 0x80 ) - cur[0] = (FT_Byte) c; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** BITMAP DATA DECODING *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - pfr_lookup_bitmap_data( FT_Byte* base, - FT_Byte* limit, - FT_UInt count, - FT_UInt flags, - FT_UInt char_code, - FT_ULong* found_offset, - FT_ULong* found_size ) - { - FT_UInt left, right, char_len; - FT_Bool two = FT_BOOL( flags & 1 ); - FT_Byte* buff; - - - char_len = 4; - if ( two ) char_len += 1; - if ( flags & 2 ) char_len += 1; - if ( flags & 4 ) char_len += 1; - - left = 0; - right = count; - - while ( left < right ) - { - FT_UInt middle, code; - - - middle = ( left + right ) >> 1; - buff = base + middle * char_len; - - /* check that we are not outside of the table -- */ - /* this is possible with broken fonts... */ - if ( buff + char_len > limit ) - goto Fail; - - if ( two ) - code = PFR_NEXT_USHORT( buff ); - else - code = PFR_NEXT_BYTE( buff ); - - if ( code == char_code ) - goto Found_It; - - if ( code < char_code ) - left = middle; - else - right = middle; - } - - Fail: - /* Not found */ - *found_size = 0; - *found_offset = 0; - return; - - Found_It: - if ( flags & 2 ) - *found_size = PFR_NEXT_USHORT( buff ); - else - *found_size = PFR_NEXT_BYTE( buff ); - - if ( flags & 4 ) - *found_offset = PFR_NEXT_ULONG( buff ); - else - *found_offset = PFR_NEXT_USHORT( buff ); - } - - - /* load bitmap metrics. "*padvance" must be set to the default value */ - /* before calling this function... */ - /* */ - static FT_Error - pfr_load_bitmap_metrics( FT_Byte** pdata, - FT_Byte* limit, - FT_Long scaled_advance, - FT_Long *axpos, - FT_Long *aypos, - FT_UInt *axsize, - FT_UInt *aysize, - FT_Long *aadvance, - FT_UInt *aformat ) - { - FT_Error error = FT_Err_Ok; - FT_Byte flags; - FT_Char b; - FT_Byte* p = *pdata; - FT_Long xpos, ypos, advance; - FT_UInt xsize, ysize; - - - PFR_CHECK( 1 ); - flags = PFR_NEXT_BYTE( p ); - - xpos = 0; - ypos = 0; - xsize = 0; - ysize = 0; - advance = 0; - - switch ( flags & 3 ) - { - case 0: - PFR_CHECK( 1 ); - b = PFR_NEXT_INT8( p ); - xpos = b >> 4; - ypos = ( (FT_Char)( b << 4 ) ) >> 4; - break; - - case 1: - PFR_CHECK( 2 ); - xpos = PFR_NEXT_INT8( p ); - ypos = PFR_NEXT_INT8( p ); - break; - - case 2: - PFR_CHECK( 4 ); - xpos = PFR_NEXT_SHORT( p ); - ypos = PFR_NEXT_SHORT( p ); - break; - - case 3: - PFR_CHECK( 6 ); - xpos = PFR_NEXT_LONG( p ); - ypos = PFR_NEXT_LONG( p ); - break; - - default: - ; - } - - flags >>= 2; - switch ( flags & 3 ) - { - case 0: - /* blank image */ - xsize = 0; - ysize = 0; - break; - - case 1: - PFR_CHECK( 1 ); - b = PFR_NEXT_BYTE( p ); - xsize = ( b >> 4 ) & 0xF; - ysize = b & 0xF; - break; - - case 2: - PFR_CHECK( 2 ); - xsize = PFR_NEXT_BYTE( p ); - ysize = PFR_NEXT_BYTE( p ); - break; - - case 3: - PFR_CHECK( 4 ); - xsize = PFR_NEXT_USHORT( p ); - ysize = PFR_NEXT_USHORT( p ); - break; - - default: - ; - } - - flags >>= 2; - switch ( flags & 3 ) - { - case 0: - advance = scaled_advance; - break; - - case 1: - PFR_CHECK( 1 ); - advance = PFR_NEXT_INT8( p ) << 8; - break; - - case 2: - PFR_CHECK( 2 ); - advance = PFR_NEXT_SHORT( p ); - break; - - case 3: - PFR_CHECK( 3 ); - advance = PFR_NEXT_LONG( p ); - break; - - default: - ; - } - - *axpos = xpos; - *aypos = ypos; - *axsize = xsize; - *aysize = ysize; - *aadvance = advance; - *aformat = flags >> 2; - *pdata = p; - - Exit: - return error; - - Too_Short: - error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" )); - goto Exit; - } - - - static FT_Error - pfr_load_bitmap_bits( FT_Byte* p, - FT_Byte* limit, - FT_UInt format, - FT_Bool decreasing, - FT_Bitmap* target ) - { - FT_Error error = FT_Err_Ok; - PFR_BitWriterRec writer; - - - if ( target->rows > 0 && target->width > 0 ) - { - pfr_bitwriter_init( &writer, target, decreasing ); - - switch ( format ) - { - case 0: /* packed bits */ - pfr_bitwriter_decode_bytes( &writer, p, limit ); - break; - - case 1: /* RLE1 */ - pfr_bitwriter_decode_rle1( &writer, p, limit ); - break; - - case 2: /* RLE2 */ - pfr_bitwriter_decode_rle2( &writer, p, limit ); - break; - - default: - FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); - error = FT_THROW( Invalid_File_Format ); - } - } - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** BITMAP LOADING *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( FT_Error ) - pfr_slot_load_bitmap( PFR_Slot glyph, - PFR_Size size, - FT_UInt glyph_index ) - { - FT_Error error; - PFR_Face face = (PFR_Face) glyph->root.face; - FT_Stream stream = face->root.stream; - PFR_PhyFont phys = &face->phy_font; - FT_ULong gps_offset; - FT_ULong gps_size; - PFR_Char character; - PFR_Strike strike; - - - character = &phys->chars[glyph_index]; - - /* Look-up a bitmap strike corresponding to the current */ - /* character dimensions */ - { - FT_UInt n; - - - strike = phys->strikes; - for ( n = 0; n < phys->num_strikes; n++ ) - { - if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && - strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) - { - goto Found_Strike; - } - - strike++; - } - - /* couldn't find it */ - return FT_THROW( Invalid_Argument ); - } - - Found_Strike: - - /* Now lookup the glyph's position within the file */ - { - FT_UInt char_len; - - - char_len = 4; - if ( strike->flags & 1 ) char_len += 1; - if ( strike->flags & 2 ) char_len += 1; - if ( strike->flags & 4 ) char_len += 1; - - /* Access data directly in the frame to speed lookups */ - if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || - FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) - goto Exit; - - pfr_lookup_bitmap_data( stream->cursor, - stream->limit, - strike->num_bitmaps, - strike->flags, - character->char_code, - &gps_offset, - &gps_size ); - - FT_FRAME_EXIT(); - - if ( gps_size == 0 ) - { - /* Could not find a bitmap program string for this glyph */ - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - } - - /* get the bitmap metrics */ - { - FT_Long xpos = 0, ypos = 0, advance = 0; - FT_UInt xsize = 0, ysize = 0, format = 0; - FT_Byte* p; - - - /* compute linear advance */ - advance = character->advance; - if ( phys->metrics_resolution != phys->outline_resolution ) - advance = FT_MulDiv( advance, - phys->outline_resolution, - phys->metrics_resolution ); - - glyph->root.linearHoriAdvance = advance; - - /* compute default advance, i.e., scaled advance. This can be */ - /* overridden in the bitmap header of certain glyphs. */ - advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8, - character->advance, - phys->metrics_resolution ); - - if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) || - FT_FRAME_ENTER( gps_size ) ) - goto Exit; - - p = stream->cursor; - error = pfr_load_bitmap_metrics( &p, stream->limit, - advance, - &xpos, &ypos, - &xsize, &ysize, - &advance, &format ); - - /* - * XXX: on 16bit system, we return an error for huge bitmap - * which causes a size truncation, because truncated - * size properties makes bitmap glyph broken. - */ - if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX ) - { - FT_TRACE1(( "pfr_slot_load_bitmap:" )); - FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n", - xpos, ypos )); - error = FT_THROW( Invalid_Pixel_Size ); - } - - if ( !error ) - { - glyph->root.format = FT_GLYPH_FORMAT_BITMAP; - - /* Set up glyph bitmap and metrics */ - - /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */ - glyph->root.bitmap.width = (FT_Int)xsize; - glyph->root.bitmap.rows = (FT_Int)ysize; - glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3; - glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; - - /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ - glyph->root.metrics.width = (FT_Pos)xsize << 6; - glyph->root.metrics.height = (FT_Pos)ysize << 6; - glyph->root.metrics.horiBearingX = xpos << 6; - glyph->root.metrics.horiBearingY = ypos << 6; - glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); - glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; - glyph->root.metrics.vertBearingY = 0; - glyph->root.metrics.vertAdvance = size->root.metrics.height; - - /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */ - glyph->root.bitmap_left = (FT_Int)xpos; - glyph->root.bitmap_top = (FT_Int)(ypos + ysize); - - /* Allocate and read bitmap data */ - { - FT_ULong len = glyph->root.bitmap.pitch * ysize; - - - error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); - if ( !error ) - { - error = pfr_load_bitmap_bits( - p, - stream->limit, - format, - FT_BOOL(face->header.color_flags & 2), - &glyph->root.bitmap ); - } - } - } - - FT_FRAME_EXIT(); - } - - Exit: - return error; - } - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrsbit.h b/drivers/freetype/freetype/src/pfr/pfrsbit.h deleted file mode 100644 index 015e9e6dad..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrsbit.h +++ /dev/null @@ -1,36 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrsbit.h */ -/* */ -/* FreeType PFR bitmap loader (specification). */ -/* */ -/* Copyright 2002 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 __PFRSBIT_H__ -#define __PFRSBIT_H__ - -#include "pfrobjs.h" - -FT_BEGIN_HEADER - - FT_LOCAL( FT_Error ) - pfr_slot_load_bitmap( PFR_Slot glyph, - PFR_Size size, - FT_UInt glyph_index ); - -FT_END_HEADER - -#endif /* __PFR_SBIT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrtypes.h b/drivers/freetype/freetype/src/pfr/pfrtypes.h deleted file mode 100644 index 918310814c..0000000000 --- a/drivers/freetype/freetype/src/pfr/pfrtypes.h +++ /dev/null @@ -1,362 +0,0 @@ -/***************************************************************************/ -/* */ -/* pfrtypes.h */ -/* */ -/* FreeType PFR data structures (specification only). */ -/* */ -/* Copyright 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, */ -/* 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 __PFRTYPES_H__ -#define __PFRTYPES_H__ - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H - -FT_BEGIN_HEADER - - /************************************************************************/ - - /* the PFR Header structure */ - typedef struct PFR_HeaderRec_ - { - FT_UInt32 signature; - FT_UInt version; - FT_UInt signature2; - FT_UInt header_size; - - FT_UInt log_dir_size; - FT_UInt log_dir_offset; - - FT_UInt log_font_max_size; - FT_UInt32 log_font_section_size; - FT_UInt32 log_font_section_offset; - - FT_UInt32 phy_font_max_size; - FT_UInt32 phy_font_section_size; - FT_UInt32 phy_font_section_offset; - - FT_UInt gps_max_size; - FT_UInt32 gps_section_size; - FT_UInt32 gps_section_offset; - - FT_UInt max_blue_values; - FT_UInt max_x_orus; - FT_UInt max_y_orus; - - FT_UInt phy_font_max_size_high; - FT_UInt color_flags; - - FT_UInt32 bct_max_size; - FT_UInt32 bct_set_max_size; - FT_UInt32 phy_bct_set_max_size; - - FT_UInt num_phy_fonts; - FT_UInt max_vert_stem_snap; - FT_UInt max_horz_stem_snap; - FT_UInt max_chars; - - } PFR_HeaderRec, *PFR_Header; - - - /* used in `color_flags' field of the PFR_Header */ - typedef enum PFR_HeaderFlags_ - { - PFR_FLAG_BLACK_PIXEL = 1, - PFR_FLAG_INVERT_BITMAP = 2 - - } PFR_HeaderFlags; - - - /************************************************************************/ - - typedef struct PFR_LogFontRec_ - { - FT_UInt32 size; - FT_UInt32 offset; - - FT_Int32 matrix[4]; - FT_UInt stroke_flags; - FT_Int stroke_thickness; - FT_Int bold_thickness; - FT_Int32 miter_limit; - - FT_UInt32 phys_size; - FT_UInt32 phys_offset; - - } PFR_LogFontRec, *PFR_LogFont; - - - typedef enum PFR_LogFlags_ - { - PFR_LOG_EXTRA_ITEMS = 0x40, - PFR_LOG_2BYTE_BOLD = 0x20, - PFR_LOG_BOLD = 0x10, - PFR_LOG_2BYTE_STROKE = 8, - PFR_LOG_STROKE = 4, - PFR_LINE_JOIN_MASK = 3 - - } PFR_LogFlags; - - - typedef enum PFR_LineJoinFlags_ - { - PFR_LINE_JOIN_MITER = 0, - PFR_LINE_JOIN_ROUND = 1, - PFR_LINE_JOIN_BEVEL = 2 - - } PFR_LineJoinFlags; - - - /************************************************************************/ - - typedef enum PFR_BitmapFlags_ - { - PFR_BITMAP_3BYTE_OFFSET = 4, - PFR_BITMAP_2BYTE_SIZE = 2, - PFR_BITMAP_2BYTE_CHARCODE = 1 - - } PFR_BitmapFlags; - - - typedef struct PFR_BitmapCharRec_ - { - FT_UInt char_code; - FT_UInt gps_size; - FT_UInt32 gps_offset; - - } PFR_BitmapCharRec, *PFR_BitmapChar; - - - typedef enum PFR_StrikeFlags_ - { - PFR_STRIKE_2BYTE_COUNT = 0x10, - PFR_STRIKE_3BYTE_OFFSET = 0x08, - PFR_STRIKE_3BYTE_SIZE = 0x04, - PFR_STRIKE_2BYTE_YPPM = 0x02, - PFR_STRIKE_2BYTE_XPPM = 0x01 - - } PFR_StrikeFlags; - - - typedef struct PFR_StrikeRec_ - { - FT_UInt x_ppm; - FT_UInt y_ppm; - FT_UInt flags; - - FT_UInt32 gps_size; - FT_UInt32 gps_offset; - - FT_UInt32 bct_size; - FT_UInt32 bct_offset; - - /* optional */ - FT_UInt num_bitmaps; - PFR_BitmapChar bitmaps; - - } PFR_StrikeRec, *PFR_Strike; - - - /************************************************************************/ - - typedef struct PFR_CharRec_ - { - FT_UInt char_code; - FT_Int advance; - FT_UInt gps_size; - FT_UInt32 gps_offset; - - } PFR_CharRec, *PFR_Char; - - - /************************************************************************/ - - typedef struct PFR_DimensionRec_ - { - FT_UInt standard; - FT_UInt num_stem_snaps; - FT_Int* stem_snaps; - - } PFR_DimensionRec, *PFR_Dimension; - - /************************************************************************/ - - typedef struct PFR_KernItemRec_* PFR_KernItem; - - typedef struct PFR_KernItemRec_ - { - PFR_KernItem next; - FT_Byte pair_count; - FT_Byte flags; - FT_Short base_adj; - FT_UInt pair_size; - FT_Offset offset; - FT_UInt32 pair1; - FT_UInt32 pair2; - - } PFR_KernItemRec; - - -#define PFR_KERN_INDEX( g1, g2 ) \ - ( ( (FT_UInt32)(g1) << 16 ) | (FT_UInt16)(g2) ) - -#define PFR_KERN_PAIR_INDEX( pair ) \ - PFR_KERN_INDEX( (pair)->glyph1, (pair)->glyph2 ) - -#define PFR_NEXT_KPAIR( p ) ( p += 2, \ - ( (FT_UInt32)p[-2] << 16 ) | p[-1] ) - - - /************************************************************************/ - - typedef struct PFR_PhyFontRec_ - { - FT_Memory memory; - FT_UInt32 offset; - - FT_UInt font_ref_number; - FT_UInt outline_resolution; - FT_UInt metrics_resolution; - FT_BBox bbox; - FT_UInt flags; - FT_UInt standard_advance; - - FT_Int ascent; /* optional, bbox.yMax if not present */ - FT_Int descent; /* optional, bbox.yMin if not present */ - FT_Int leading; /* optional, 0 if not present */ - - PFR_DimensionRec horizontal; - PFR_DimensionRec vertical; - - FT_String* font_id; - FT_String* family_name; - FT_String* style_name; - - FT_UInt num_strikes; - FT_UInt max_strikes; - PFR_StrikeRec* strikes; - - FT_UInt num_blue_values; - FT_Int *blue_values; - FT_UInt blue_fuzz; - FT_UInt blue_scale; - - FT_UInt num_chars; - FT_Offset chars_offset; - PFR_Char chars; - - FT_UInt num_kern_pairs; - PFR_KernItem kern_items; - PFR_KernItem* kern_items_tail; - - /* not part of the spec, but used during load */ - FT_Long bct_offset; - FT_Byte* cursor; - - } PFR_PhyFontRec, *PFR_PhyFont; - - - typedef enum PFR_PhyFlags_ - { - PFR_PHY_EXTRA_ITEMS = 0x80, - PFR_PHY_3BYTE_GPS_OFFSET = 0x20, - PFR_PHY_2BYTE_GPS_SIZE = 0x10, - PFR_PHY_ASCII_CODE = 0x08, - PFR_PHY_PROPORTIONAL = 0x04, - PFR_PHY_2BYTE_CHARCODE = 0x02, - PFR_PHY_VERTICAL = 0x01 - - } PFR_PhyFlags; - - - typedef enum PFR_KernFlags_ - { - PFR_KERN_2BYTE_CHAR = 0x01, - PFR_KERN_2BYTE_ADJ = 0x02 - - } PFR_KernFlags; - - - /************************************************************************/ - - typedef enum PFR_GlyphFlags_ - { - PFR_GLYPH_IS_COMPOUND = 0x80, - PFR_GLYPH_EXTRA_ITEMS = 0x08, - PFR_GLYPH_1BYTE_XYCOUNT = 0x04, - PFR_GLYPH_XCOUNT = 0x02, - PFR_GLYPH_YCOUNT = 0x01 - - } PFR_GlyphFlags; - - - /* controlled coordinate */ - typedef struct PFR_CoordRec_ - { - FT_UInt org; - FT_UInt cur; - - } PFR_CoordRec, *PFR_Coord; - - - typedef struct PFR_SubGlyphRec_ - { - FT_Fixed x_scale; - FT_Fixed y_scale; - FT_Int x_delta; - FT_Int y_delta; - FT_UInt32 gps_offset; - FT_UInt gps_size; - - } PFR_SubGlyphRec, *PFR_SubGlyph; - - - typedef enum PFR_SubgGlyphFlags_ - { - PFR_SUBGLYPH_3BYTE_OFFSET = 0x80, - PFR_SUBGLYPH_2BYTE_SIZE = 0x40, - PFR_SUBGLYPH_YSCALE = 0x20, - PFR_SUBGLYPH_XSCALE = 0x10 - - } PFR_SubGlyphFlags; - - - typedef struct PFR_GlyphRec_ - { - FT_Byte format; - -#if 0 - FT_UInt num_x_control; - FT_UInt num_y_control; -#endif - FT_UInt max_xy_control; - FT_Pos* x_control; - FT_Pos* y_control; - - - FT_UInt num_subs; - FT_UInt max_subs; - PFR_SubGlyphRec* subs; - - FT_GlyphLoader loader; - FT_Bool path_begun; - - } PFR_GlyphRec, *PFR_Glyph; - - -FT_END_HEADER - -#endif /* __PFRTYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pfr/rules.mk b/drivers/freetype/freetype/src/pfr/rules.mk deleted file mode 100644 index 60b96c7415..0000000000 --- a/drivers/freetype/freetype/src/pfr/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 PFR driver configuration rules -# - - -# Copyright 2002, 2003 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. - - -# pfr driver directory -# -PFR_DIR := $(SRC_DIR)/pfr - - -# compilation flags for the driver -# -PFR_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PFR_DIR)) - - -# pfr driver sources (i.e., C files) -# -PFR_DRV_SRC := $(PFR_DIR)/pfrload.c \ - $(PFR_DIR)/pfrgload.c \ - $(PFR_DIR)/pfrcmap.c \ - $(PFR_DIR)/pfrdrivr.c \ - $(PFR_DIR)/pfrsbit.c \ - $(PFR_DIR)/pfrobjs.c - -# pfr driver headers -# -PFR_DRV_H := $(PFR_DRV_SRC:%.c=%.h) \ - $(PFR_DIR)/pfrerror.h \ - $(PFR_DIR)/pfrtypes.h - - -# Pfr driver object(s) -# -# PFR_DRV_OBJ_M is used during `multi' builds -# PFR_DRV_OBJ_S is used during `single' builds -# -PFR_DRV_OBJ_M := $(PFR_DRV_SRC:$(PFR_DIR)/%.c=$(OBJ_DIR)/%.$O) -PFR_DRV_OBJ_S := $(OBJ_DIR)/pfr.$O - -# pfr driver source file for single build -# -PFR_DRV_SRC_S := $(PFR_DIR)/pfr.c - - -# pfr driver - single object -# -$(PFR_DRV_OBJ_S): $(PFR_DRV_SRC_S) $(PFR_DRV_SRC) $(FREETYPE_H) $(PFR_DRV_H) - $(PFR_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PFR_DRV_SRC_S)) - - -# pfr driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PFR_DIR)/%.c $(FREETYPE_H) $(PFR_DRV_H) - $(PFR_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PFR_DRV_OBJ_S) -DRV_OBJS_M += $(PFR_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/psaux/Jamfile b/drivers/freetype/freetype/src/psaux/Jamfile deleted file mode 100644 index faeded9044..0000000000 --- a/drivers/freetype/freetype/src/psaux/Jamfile +++ /dev/null @@ -1,31 +0,0 @@ -# FreeType 2 src/psaux Jamfile -# -# Copyright 2001, 2002 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) psaux ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = psauxmod psobjs t1decode t1cmap - psconv afmparse - ; - } - else - { - _sources = psaux ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/psaux Jamfile diff --git a/drivers/freetype/freetype/src/psaux/afmparse.c b/drivers/freetype/freetype/src/psaux/afmparse.c deleted file mode 100644 index 6a40e110dc..0000000000 --- a/drivers/freetype/freetype/src/psaux/afmparse.c +++ /dev/null @@ -1,964 +0,0 @@ -/***************************************************************************/ -/* */ -/* afmparse.c */ -/* */ -/* AFM parser (body). */ -/* */ -/* Copyright 2006-2010, 2012, 2013 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_FREETYPE_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H - -#include "afmparse.h" -#include "psconv.h" - -#include "psauxerr.h" - - -/***************************************************************************/ -/* */ -/* AFM_Stream */ -/* */ -/* The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib. */ -/* */ -/* */ - - enum - { - AFM_STREAM_STATUS_NORMAL, - AFM_STREAM_STATUS_EOC, - AFM_STREAM_STATUS_EOL, - AFM_STREAM_STATUS_EOF - }; - - - typedef struct AFM_StreamRec_ - { - FT_Byte* cursor; - FT_Byte* base; - FT_Byte* limit; - - FT_Int status; - - } AFM_StreamRec; - - -#ifndef EOF -#define EOF -1 -#endif - - - /* this works because empty lines are ignored */ -#define AFM_IS_NEWLINE( ch ) ( (ch) == '\r' || (ch) == '\n' ) - -#define AFM_IS_EOF( ch ) ( (ch) == EOF || (ch) == '\x1a' ) -#define AFM_IS_SPACE( ch ) ( (ch) == ' ' || (ch) == '\t' ) - - /* column separator; there is no `column' in the spec actually */ -#define AFM_IS_SEP( ch ) ( (ch) == ';' ) - -#define AFM_GETC() \ - ( ( (stream)->cursor < (stream)->limit ) ? *(stream)->cursor++ \ - : EOF ) - -#define AFM_STREAM_KEY_BEGIN( stream ) \ - (char*)( (stream)->cursor - 1 ) - -#define AFM_STREAM_KEY_LEN( stream, key ) \ - ( (char*)(stream)->cursor - key - 1 ) - -#define AFM_STATUS_EOC( stream ) \ - ( (stream)->status >= AFM_STREAM_STATUS_EOC ) - -#define AFM_STATUS_EOL( stream ) \ - ( (stream)->status >= AFM_STREAM_STATUS_EOL ) - -#define AFM_STATUS_EOF( stream ) \ - ( (stream)->status >= AFM_STREAM_STATUS_EOF ) - - - static int - afm_stream_skip_spaces( AFM_Stream stream ) - { - int ch = 0; /* make stupid compiler happy */ - - - if ( AFM_STATUS_EOC( stream ) ) - return ';'; - - while ( 1 ) - { - ch = AFM_GETC(); - if ( !AFM_IS_SPACE( ch ) ) - break; - } - - if ( AFM_IS_NEWLINE( ch ) ) - stream->status = AFM_STREAM_STATUS_EOL; - else if ( AFM_IS_SEP( ch ) ) - stream->status = AFM_STREAM_STATUS_EOC; - else if ( AFM_IS_EOF( ch ) ) - stream->status = AFM_STREAM_STATUS_EOF; - - return ch; - } - - - /* read a key or value in current column */ - static char* - afm_stream_read_one( AFM_Stream stream ) - { - char* str; - - - afm_stream_skip_spaces( stream ); - if ( AFM_STATUS_EOC( stream ) ) - return NULL; - - str = AFM_STREAM_KEY_BEGIN( stream ); - - while ( 1 ) - { - int ch = AFM_GETC(); - - - if ( AFM_IS_SPACE( ch ) ) - break; - else if ( AFM_IS_NEWLINE( ch ) ) - { - stream->status = AFM_STREAM_STATUS_EOL; - break; - } - else if ( AFM_IS_SEP( ch ) ) - { - stream->status = AFM_STREAM_STATUS_EOC; - break; - } - else if ( AFM_IS_EOF( ch ) ) - { - stream->status = AFM_STREAM_STATUS_EOF; - break; - } - } - - return str; - } - - - /* read a string (i.e., read to EOL) */ - static char* - afm_stream_read_string( AFM_Stream stream ) - { - char* str; - - - afm_stream_skip_spaces( stream ); - if ( AFM_STATUS_EOL( stream ) ) - return NULL; - - str = AFM_STREAM_KEY_BEGIN( stream ); - - /* scan to eol */ - while ( 1 ) - { - int ch = AFM_GETC(); - - - if ( AFM_IS_NEWLINE( ch ) ) - { - stream->status = AFM_STREAM_STATUS_EOL; - break; - } - else if ( AFM_IS_EOF( ch ) ) - { - stream->status = AFM_STREAM_STATUS_EOF; - break; - } - } - - return str; - } - - - /*************************************************************************/ - /* */ - /* AFM_Parser */ - /* */ - /* */ - - /* all keys defined in Ch. 7-10 of 5004.AFM_Spec.pdf */ - typedef enum AFM_Token_ - { - AFM_TOKEN_ASCENDER, - AFM_TOKEN_AXISLABEL, - AFM_TOKEN_AXISTYPE, - AFM_TOKEN_B, - AFM_TOKEN_BLENDAXISTYPES, - AFM_TOKEN_BLENDDESIGNMAP, - AFM_TOKEN_BLENDDESIGNPOSITIONS, - AFM_TOKEN_C, - AFM_TOKEN_CC, - AFM_TOKEN_CH, - AFM_TOKEN_CAPHEIGHT, - AFM_TOKEN_CHARWIDTH, - AFM_TOKEN_CHARACTERSET, - AFM_TOKEN_CHARACTERS, - AFM_TOKEN_DESCENDER, - AFM_TOKEN_ENCODINGSCHEME, - AFM_TOKEN_ENDAXIS, - AFM_TOKEN_ENDCHARMETRICS, - AFM_TOKEN_ENDCOMPOSITES, - AFM_TOKEN_ENDDIRECTION, - AFM_TOKEN_ENDFONTMETRICS, - AFM_TOKEN_ENDKERNDATA, - AFM_TOKEN_ENDKERNPAIRS, - AFM_TOKEN_ENDTRACKKERN, - AFM_TOKEN_ESCCHAR, - AFM_TOKEN_FAMILYNAME, - AFM_TOKEN_FONTBBOX, - AFM_TOKEN_FONTNAME, - AFM_TOKEN_FULLNAME, - AFM_TOKEN_ISBASEFONT, - AFM_TOKEN_ISCIDFONT, - AFM_TOKEN_ISFIXEDPITCH, - AFM_TOKEN_ISFIXEDV, - AFM_TOKEN_ITALICANGLE, - AFM_TOKEN_KP, - AFM_TOKEN_KPH, - AFM_TOKEN_KPX, - AFM_TOKEN_KPY, - AFM_TOKEN_L, - AFM_TOKEN_MAPPINGSCHEME, - AFM_TOKEN_METRICSSETS, - AFM_TOKEN_N, - AFM_TOKEN_NOTICE, - AFM_TOKEN_PCC, - AFM_TOKEN_STARTAXIS, - AFM_TOKEN_STARTCHARMETRICS, - AFM_TOKEN_STARTCOMPOSITES, - AFM_TOKEN_STARTDIRECTION, - AFM_TOKEN_STARTFONTMETRICS, - AFM_TOKEN_STARTKERNDATA, - AFM_TOKEN_STARTKERNPAIRS, - AFM_TOKEN_STARTKERNPAIRS0, - AFM_TOKEN_STARTKERNPAIRS1, - AFM_TOKEN_STARTTRACKKERN, - AFM_TOKEN_STDHW, - AFM_TOKEN_STDVW, - AFM_TOKEN_TRACKKERN, - AFM_TOKEN_UNDERLINEPOSITION, - AFM_TOKEN_UNDERLINETHICKNESS, - AFM_TOKEN_VV, - AFM_TOKEN_VVECTOR, - AFM_TOKEN_VERSION, - AFM_TOKEN_W, - AFM_TOKEN_W0, - AFM_TOKEN_W0X, - AFM_TOKEN_W0Y, - AFM_TOKEN_W1, - AFM_TOKEN_W1X, - AFM_TOKEN_W1Y, - AFM_TOKEN_WX, - AFM_TOKEN_WY, - AFM_TOKEN_WEIGHT, - AFM_TOKEN_WEIGHTVECTOR, - AFM_TOKEN_XHEIGHT, - N_AFM_TOKENS, - AFM_TOKEN_UNKNOWN - - } AFM_Token; - - - static const char* const afm_key_table[N_AFM_TOKENS] = - { - "Ascender", - "AxisLabel", - "AxisType", - "B", - "BlendAxisTypes", - "BlendDesignMap", - "BlendDesignPositions", - "C", - "CC", - "CH", - "CapHeight", - "CharWidth", - "CharacterSet", - "Characters", - "Descender", - "EncodingScheme", - "EndAxis", - "EndCharMetrics", - "EndComposites", - "EndDirection", - "EndFontMetrics", - "EndKernData", - "EndKernPairs", - "EndTrackKern", - "EscChar", - "FamilyName", - "FontBBox", - "FontName", - "FullName", - "IsBaseFont", - "IsCIDFont", - "IsFixedPitch", - "IsFixedV", - "ItalicAngle", - "KP", - "KPH", - "KPX", - "KPY", - "L", - "MappingScheme", - "MetricsSets", - "N", - "Notice", - "PCC", - "StartAxis", - "StartCharMetrics", - "StartComposites", - "StartDirection", - "StartFontMetrics", - "StartKernData", - "StartKernPairs", - "StartKernPairs0", - "StartKernPairs1", - "StartTrackKern", - "StdHW", - "StdVW", - "TrackKern", - "UnderlinePosition", - "UnderlineThickness", - "VV", - "VVector", - "Version", - "W", - "W0", - "W0X", - "W0Y", - "W1", - "W1X", - "W1Y", - "WX", - "WY", - "Weight", - "WeightVector", - "XHeight" - }; - - - /* - * `afm_parser_read_vals' and `afm_parser_next_key' provide - * high-level operations to an AFM_Stream. The rest of the - * parser functions should use them without accessing the - * AFM_Stream directly. - */ - - FT_LOCAL_DEF( FT_Int ) - afm_parser_read_vals( AFM_Parser parser, - AFM_Value vals, - FT_UInt n ) - { - AFM_Stream stream = parser->stream; - char* str; - FT_UInt i; - - - if ( n > AFM_MAX_ARGUMENTS ) - return 0; - - for ( i = 0; i < n; i++ ) - { - FT_Offset len; - AFM_Value val = vals + i; - - - if ( val->type == AFM_VALUE_TYPE_STRING ) - str = afm_stream_read_string( stream ); - else - str = afm_stream_read_one( stream ); - - if ( !str ) - break; - - len = AFM_STREAM_KEY_LEN( stream, str ); - - switch ( val->type ) - { - case AFM_VALUE_TYPE_STRING: - case AFM_VALUE_TYPE_NAME: - { - FT_Memory memory = parser->memory; - FT_Error error; - - - if ( !FT_QALLOC( val->u.s, len + 1 ) ) - { - ft_memcpy( val->u.s, str, len ); - val->u.s[len] = '\0'; - } - } - break; - - case AFM_VALUE_TYPE_FIXED: - val->u.f = PS_Conv_ToFixed( (FT_Byte**)(void*)&str, - (FT_Byte*)str + len, 0 ); - break; - - case AFM_VALUE_TYPE_INTEGER: - val->u.i = PS_Conv_ToInt( (FT_Byte**)(void*)&str, - (FT_Byte*)str + len ); - break; - - case AFM_VALUE_TYPE_BOOL: - val->u.b = FT_BOOL( len == 4 && - !ft_strncmp( str, "true", 4 ) ); - break; - - case AFM_VALUE_TYPE_INDEX: - if ( parser->get_index ) - val->u.i = parser->get_index( str, len, parser->user_data ); - else - val->u.i = 0; - break; - } - } - - return i; - } - - - FT_LOCAL_DEF( char* ) - afm_parser_next_key( AFM_Parser parser, - FT_Bool line, - FT_Offset* len ) - { - AFM_Stream stream = parser->stream; - char* key = 0; /* make stupid compiler happy */ - - - if ( line ) - { - while ( 1 ) - { - /* skip current line */ - if ( !AFM_STATUS_EOL( stream ) ) - afm_stream_read_string( stream ); - - stream->status = AFM_STREAM_STATUS_NORMAL; - key = afm_stream_read_one( stream ); - - /* skip empty line */ - if ( !key && - !AFM_STATUS_EOF( stream ) && - AFM_STATUS_EOL( stream ) ) - continue; - - break; - } - } - else - { - while ( 1 ) - { - /* skip current column */ - while ( !AFM_STATUS_EOC( stream ) ) - afm_stream_read_one( stream ); - - stream->status = AFM_STREAM_STATUS_NORMAL; - key = afm_stream_read_one( stream ); - - /* skip empty column */ - if ( !key && - !AFM_STATUS_EOF( stream ) && - AFM_STATUS_EOC( stream ) ) - continue; - - break; - } - } - - if ( len ) - *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key ) - : 0; - - return key; - } - - - static AFM_Token - afm_tokenize( const char* key, - FT_Offset len ) - { - int n; - - - for ( n = 0; n < N_AFM_TOKENS; n++ ) - { - if ( *( afm_key_table[n] ) == *key ) - { - for ( ; n < N_AFM_TOKENS; n++ ) - { - if ( *( afm_key_table[n] ) != *key ) - return AFM_TOKEN_UNKNOWN; - - if ( ft_strncmp( afm_key_table[n], key, len ) == 0 ) - return (AFM_Token) n; - } - } - } - - return AFM_TOKEN_UNKNOWN; - } - - - FT_LOCAL_DEF( FT_Error ) - afm_parser_init( AFM_Parser parser, - FT_Memory memory, - FT_Byte* base, - FT_Byte* limit ) - { - AFM_Stream stream = NULL; - FT_Error error; - - - if ( FT_NEW( stream ) ) - return error; - - stream->cursor = stream->base = base; - stream->limit = limit; - - /* don't skip the first line during the first call */ - stream->status = AFM_STREAM_STATUS_EOL; - - parser->memory = memory; - parser->stream = stream; - parser->FontInfo = NULL; - parser->get_index = NULL; - - return FT_Err_Ok; - } - - - FT_LOCAL( void ) - afm_parser_done( AFM_Parser parser ) - { - FT_Memory memory = parser->memory; - - - FT_FREE( parser->stream ); - } - - - FT_LOCAL_DEF( FT_Error ) - afm_parser_read_int( AFM_Parser parser, - FT_Int* aint ) - { - AFM_ValueRec val; - - - val.type = AFM_VALUE_TYPE_INTEGER; - - if ( afm_parser_read_vals( parser, &val, 1 ) == 1 ) - { - *aint = val.u.i; - - return FT_Err_Ok; - } - else - return FT_THROW( Syntax_Error ); - } - - - static FT_Error - afm_parse_track_kern( AFM_Parser parser ) - { - AFM_FontInfo fi = parser->FontInfo; - AFM_TrackKern tk; - char* key; - FT_Offset len; - int n = -1; - - - if ( afm_parser_read_int( parser, &fi->NumTrackKern ) ) - goto Fail; - - if ( fi->NumTrackKern ) - { - FT_Memory memory = parser->memory; - FT_Error error; - - - if ( FT_QNEW_ARRAY( fi->TrackKerns, fi->NumTrackKern ) ) - return error; - } - - while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) - { - AFM_ValueRec shared_vals[5]; - - - switch ( afm_tokenize( key, len ) ) - { - case AFM_TOKEN_TRACKKERN: - n++; - - if ( n >= fi->NumTrackKern ) - goto Fail; - - tk = fi->TrackKerns + n; - - shared_vals[0].type = AFM_VALUE_TYPE_INTEGER; - shared_vals[1].type = AFM_VALUE_TYPE_FIXED; - shared_vals[2].type = AFM_VALUE_TYPE_FIXED; - shared_vals[3].type = AFM_VALUE_TYPE_FIXED; - shared_vals[4].type = AFM_VALUE_TYPE_FIXED; - if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 ) - goto Fail; - - tk->degree = shared_vals[0].u.i; - tk->min_ptsize = shared_vals[1].u.f; - tk->min_kern = shared_vals[2].u.f; - tk->max_ptsize = shared_vals[3].u.f; - tk->max_kern = shared_vals[4].u.f; - - break; - - case AFM_TOKEN_ENDTRACKKERN: - case AFM_TOKEN_ENDKERNDATA: - case AFM_TOKEN_ENDFONTMETRICS: - fi->NumTrackKern = n + 1; - return FT_Err_Ok; - - case AFM_TOKEN_UNKNOWN: - break; - - default: - goto Fail; - } - } - - Fail: - return FT_THROW( Syntax_Error ); - } - - -#undef KERN_INDEX -#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) - - - /* compare two kerning pairs */ - FT_CALLBACK_DEF( int ) - afm_compare_kern_pairs( const void* a, - const void* b ) - { - AFM_KernPair kp1 = (AFM_KernPair)a; - AFM_KernPair kp2 = (AFM_KernPair)b; - - FT_ULong index1 = KERN_INDEX( kp1->index1, kp1->index2 ); - FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 ); - - - if ( index1 > index2 ) - return 1; - else if ( index1 < index2 ) - return -1; - else - return 0; - } - - - static FT_Error - afm_parse_kern_pairs( AFM_Parser parser ) - { - AFM_FontInfo fi = parser->FontInfo; - AFM_KernPair kp; - char* key; - FT_Offset len; - int n = -1; - - - if ( afm_parser_read_int( parser, &fi->NumKernPair ) ) - goto Fail; - - if ( fi->NumKernPair ) - { - FT_Memory memory = parser->memory; - FT_Error error; - - - if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) ) - return error; - } - - while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) - { - AFM_Token token = afm_tokenize( key, len ); - - - switch ( token ) - { - case AFM_TOKEN_KP: - case AFM_TOKEN_KPX: - case AFM_TOKEN_KPY: - { - FT_Int r; - AFM_ValueRec shared_vals[4]; - - - n++; - - if ( n >= fi->NumKernPair ) - goto Fail; - - kp = fi->KernPairs + n; - - shared_vals[0].type = AFM_VALUE_TYPE_INDEX; - shared_vals[1].type = AFM_VALUE_TYPE_INDEX; - shared_vals[2].type = AFM_VALUE_TYPE_INTEGER; - shared_vals[3].type = AFM_VALUE_TYPE_INTEGER; - r = afm_parser_read_vals( parser, shared_vals, 4 ); - if ( r < 3 ) - goto Fail; - - kp->index1 = shared_vals[0].u.i; - kp->index2 = shared_vals[1].u.i; - if ( token == AFM_TOKEN_KPY ) - { - kp->x = 0; - kp->y = shared_vals[2].u.i; - } - else - { - kp->x = shared_vals[2].u.i; - kp->y = ( token == AFM_TOKEN_KP && r == 4 ) - ? shared_vals[3].u.i : 0; - } - } - break; - - case AFM_TOKEN_ENDKERNPAIRS: - case AFM_TOKEN_ENDKERNDATA: - case AFM_TOKEN_ENDFONTMETRICS: - fi->NumKernPair = n + 1; - ft_qsort( fi->KernPairs, fi->NumKernPair, - sizeof ( AFM_KernPairRec ), - afm_compare_kern_pairs ); - return FT_Err_Ok; - - case AFM_TOKEN_UNKNOWN: - break; - - default: - goto Fail; - } - } - - Fail: - return FT_THROW( Syntax_Error ); - } - - - static FT_Error - afm_parse_kern_data( AFM_Parser parser ) - { - FT_Error error; - char* key; - FT_Offset len; - - - while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) - { - switch ( afm_tokenize( key, len ) ) - { - case AFM_TOKEN_STARTTRACKKERN: - error = afm_parse_track_kern( parser ); - if ( error ) - return error; - break; - - case AFM_TOKEN_STARTKERNPAIRS: - case AFM_TOKEN_STARTKERNPAIRS0: - error = afm_parse_kern_pairs( parser ); - if ( error ) - return error; - break; - - case AFM_TOKEN_ENDKERNDATA: - case AFM_TOKEN_ENDFONTMETRICS: - return FT_Err_Ok; - - case AFM_TOKEN_UNKNOWN: - break; - - default: - goto Fail; - } - } - - Fail: - return FT_THROW( Syntax_Error ); - } - - - static FT_Error - afm_parser_skip_section( AFM_Parser parser, - FT_UInt n, - AFM_Token end_section ) - { - char* key; - FT_Offset len; - - - while ( n-- > 0 ) - { - key = afm_parser_next_key( parser, 1, NULL ); - if ( !key ) - goto Fail; - } - - while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) - { - AFM_Token token = afm_tokenize( key, len ); - - - if ( token == end_section || token == AFM_TOKEN_ENDFONTMETRICS ) - return FT_Err_Ok; - } - - Fail: - return FT_THROW( Syntax_Error ); - } - - - FT_LOCAL_DEF( FT_Error ) - afm_parser_parse( AFM_Parser parser ) - { - FT_Memory memory = parser->memory; - AFM_FontInfo fi = parser->FontInfo; - FT_Error error = FT_ERR( Syntax_Error ); - char* key; - FT_Offset len; - FT_Int metrics_sets = 0; - - - if ( !fi ) - return FT_THROW( Invalid_Argument ); - - key = afm_parser_next_key( parser, 1, &len ); - if ( !key || len != 16 || - ft_strncmp( key, "StartFontMetrics", 16 ) != 0 ) - return FT_THROW( Unknown_File_Format ); - - while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) - { - AFM_ValueRec shared_vals[4]; - - - switch ( afm_tokenize( key, len ) ) - { - case AFM_TOKEN_METRICSSETS: - if ( afm_parser_read_int( parser, &metrics_sets ) ) - goto Fail; - - if ( metrics_sets != 0 && metrics_sets != 2 ) - { - error = FT_THROW( Unimplemented_Feature ); - - goto Fail; - } - break; - - case AFM_TOKEN_ISCIDFONT: - shared_vals[0].type = AFM_VALUE_TYPE_BOOL; - if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) - goto Fail; - - fi->IsCIDFont = shared_vals[0].u.b; - break; - - case AFM_TOKEN_FONTBBOX: - shared_vals[0].type = AFM_VALUE_TYPE_FIXED; - shared_vals[1].type = AFM_VALUE_TYPE_FIXED; - shared_vals[2].type = AFM_VALUE_TYPE_FIXED; - shared_vals[3].type = AFM_VALUE_TYPE_FIXED; - if ( afm_parser_read_vals( parser, shared_vals, 4 ) != 4 ) - goto Fail; - - fi->FontBBox.xMin = shared_vals[0].u.f; - fi->FontBBox.yMin = shared_vals[1].u.f; - fi->FontBBox.xMax = shared_vals[2].u.f; - fi->FontBBox.yMax = shared_vals[3].u.f; - break; - - case AFM_TOKEN_ASCENDER: - shared_vals[0].type = AFM_VALUE_TYPE_FIXED; - if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) - goto Fail; - - fi->Ascender = shared_vals[0].u.f; - break; - - case AFM_TOKEN_DESCENDER: - shared_vals[0].type = AFM_VALUE_TYPE_FIXED; - if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) - goto Fail; - - fi->Descender = shared_vals[0].u.f; - break; - - case AFM_TOKEN_STARTCHARMETRICS: - { - FT_Int n = 0; - - - if ( afm_parser_read_int( parser, &n ) ) - goto Fail; - - error = afm_parser_skip_section( parser, n, - AFM_TOKEN_ENDCHARMETRICS ); - if ( error ) - return error; - } - break; - - case AFM_TOKEN_STARTKERNDATA: - error = afm_parse_kern_data( parser ); - if ( error ) - goto Fail; - /* fall through since we only support kern data */ - - case AFM_TOKEN_ENDFONTMETRICS: - return FT_Err_Ok; - - default: - break; - } - } - - Fail: - FT_FREE( fi->TrackKerns ); - fi->NumTrackKern = 0; - - FT_FREE( fi->KernPairs ); - fi->NumKernPair = 0; - - fi->IsCIDFont = 0; - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/afmparse.h b/drivers/freetype/freetype/src/psaux/afmparse.h deleted file mode 100644 index 35d96046c5..0000000000 --- a/drivers/freetype/freetype/src/psaux/afmparse.h +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************/ -/* */ -/* afmparse.h */ -/* */ -/* AFM parser (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __AFMPARSE_H__ -#define __AFMPARSE_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_POSTSCRIPT_AUX_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - afm_parser_init( AFM_Parser parser, - FT_Memory memory, - FT_Byte* base, - FT_Byte* limit ); - - - FT_LOCAL( void ) - afm_parser_done( AFM_Parser parser ); - - - FT_LOCAL( FT_Error ) - afm_parser_parse( AFM_Parser parser ); - - - enum AFM_ValueType_ - { - AFM_VALUE_TYPE_STRING, - AFM_VALUE_TYPE_NAME, - AFM_VALUE_TYPE_FIXED, /* real number */ - AFM_VALUE_TYPE_INTEGER, - AFM_VALUE_TYPE_BOOL, - AFM_VALUE_TYPE_INDEX /* glyph index */ - }; - - - typedef struct AFM_ValueRec_ - { - enum AFM_ValueType_ type; - union - { - char* s; - FT_Fixed f; - FT_Int i; - FT_Bool b; - - } u; - - } AFM_ValueRec, *AFM_Value; - -#define AFM_MAX_ARGUMENTS 5 - - FT_LOCAL( FT_Int ) - afm_parser_read_vals( AFM_Parser parser, - AFM_Value vals, - FT_UInt n ); - - /* read the next key from the next line or column */ - FT_LOCAL( char* ) - afm_parser_next_key( AFM_Parser parser, - FT_Bool line, - FT_Offset* len ); - -FT_END_HEADER - -#endif /* __AFMPARSE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/module.mk b/drivers/freetype/freetype/src/psaux/module.mk deleted file mode 100644 index 42bf6f5199..0000000000 --- a/drivers/freetype/freetype/src/psaux/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 PSaux module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += PSAUX_MODULE - -define PSAUX_MODULE -$(OPEN_DRIVER) FT_Module_Class, psaux_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)psaux $(ECHO_DRIVER_DESC)Postscript Type 1 & Type 2 helper module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/psaux/psaux.c b/drivers/freetype/freetype/src/psaux/psaux.c deleted file mode 100644 index a4b9c5c6e4..0000000000 --- a/drivers/freetype/freetype/src/psaux/psaux.c +++ /dev/null @@ -1,34 +0,0 @@ -/***************************************************************************/ -/* */ -/* psaux.c */ -/* */ -/* FreeType auxiliary PostScript driver component (body only). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "psobjs.c" -#include "psauxmod.c" -#include "t1decode.c" -#include "t1cmap.c" - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include "afmparse.c" -#endif - -#include "psconv.c" - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/psauxerr.h b/drivers/freetype/freetype/src/psaux/psauxerr.h deleted file mode 100644 index d52375f8cb..0000000000 --- a/drivers/freetype/freetype/src/psaux/psauxerr.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* psauxerr.h */ -/* */ -/* PS auxiliary module error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PS auxiliary module error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ - -#ifndef __PSAUXERR_H__ -#define __PSAUXERR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PSaux_Err_ -#define FT_ERR_BASE FT_Mod_Err_PSaux - -#include FT_ERRORS_H - -#endif /* __PSAUXERR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/psauxmod.c b/drivers/freetype/freetype/src/psaux/psauxmod.c deleted file mode 100644 index 4b1249d49b..0000000000 --- a/drivers/freetype/freetype/src/psaux/psauxmod.c +++ /dev/null @@ -1,139 +0,0 @@ -/***************************************************************************/ -/* */ -/* psauxmod.c */ -/* */ -/* FreeType auxiliary PostScript module implementation (body). */ -/* */ -/* Copyright 2000-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, */ -/* 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 "psauxmod.h" -#include "psobjs.h" -#include "t1decode.h" -#include "t1cmap.h" - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include "afmparse.h" -#endif - - - FT_CALLBACK_TABLE_DEF - const PS_Table_FuncsRec ps_table_funcs = - { - ps_table_new, - ps_table_done, - ps_table_add, - ps_table_release - }; - - - FT_CALLBACK_TABLE_DEF - const PS_Parser_FuncsRec ps_parser_funcs = - { - ps_parser_init, - ps_parser_done, - ps_parser_skip_spaces, - ps_parser_skip_PS_token, - ps_parser_to_int, - ps_parser_to_fixed, - ps_parser_to_bytes, - ps_parser_to_coord_array, - ps_parser_to_fixed_array, - ps_parser_to_token, - ps_parser_to_token_array, - ps_parser_load_field, - ps_parser_load_field_table - }; - - - FT_CALLBACK_TABLE_DEF - const T1_Builder_FuncsRec t1_builder_funcs = - { - t1_builder_init, - t1_builder_done, - t1_builder_check_points, - t1_builder_add_point, - t1_builder_add_point1, - t1_builder_add_contour, - t1_builder_start_point, - t1_builder_close_contour - }; - - - FT_CALLBACK_TABLE_DEF - const T1_Decoder_FuncsRec t1_decoder_funcs = - { - t1_decoder_init, - t1_decoder_done, - t1_decoder_parse_charstrings - }; - - -#ifndef T1_CONFIG_OPTION_NO_AFM - FT_CALLBACK_TABLE_DEF - const AFM_Parser_FuncsRec afm_parser_funcs = - { - afm_parser_init, - afm_parser_done, - afm_parser_parse - }; -#endif - - - FT_CALLBACK_TABLE_DEF - const T1_CMap_ClassesRec t1_cmap_classes = - { - &t1_cmap_standard_class_rec, - &t1_cmap_expert_class_rec, - &t1_cmap_custom_class_rec, - &t1_cmap_unicode_class_rec - }; - - - static - const PSAux_Interface psaux_interface = - { - &ps_table_funcs, - &ps_parser_funcs, - &t1_builder_funcs, - &t1_decoder_funcs, - t1_decrypt, - - (const T1_CMap_ClassesRec*) &t1_cmap_classes, - -#ifndef T1_CONFIG_OPTION_NO_AFM - &afm_parser_funcs, -#else - 0, -#endif - }; - - - FT_CALLBACK_TABLE_DEF - const FT_Module_Class psaux_module_class = - { - 0, - sizeof ( FT_ModuleRec ), - "psaux", - 0x20000L, - 0x20000L, - - &psaux_interface, /* module-specific interface */ - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/psauxmod.h b/drivers/freetype/freetype/src/psaux/psauxmod.h deleted file mode 100644 index 1217236924..0000000000 --- a/drivers/freetype/freetype/src/psaux/psauxmod.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* psauxmod.h */ -/* */ -/* FreeType auxiliary PostScript module implementation (specification). */ -/* */ -/* Copyright 2000-2001 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 __PSAUXMOD_H__ -#define __PSAUXMOD_H__ - - -#include <ft2build.h> -#include FT_MODULE_H - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - - FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; - - -FT_END_HEADER - -#endif /* __PSAUXMOD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/psconv.c b/drivers/freetype/freetype/src/psaux/psconv.c deleted file mode 100644 index d0d8861c22..0000000000 --- a/drivers/freetype/freetype/src/psaux/psconv.c +++ /dev/null @@ -1,602 +0,0 @@ -/***************************************************************************/ -/* */ -/* psconv.c */ -/* */ -/* Some convenience conversions (body). */ -/* */ -/* Copyright 2006, 2008, 2009, 2012-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H - -#include "psconv.h" -#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_psconv - - - /* The following array is used by various functions to quickly convert */ - /* digits (both decimal and non-decimal) into numbers. */ - -#if 'A' == 65 - /* ASCII */ - - static const FT_Char ft_char_table[128] = - { - /* 0x00 */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, - }; - - /* no character >= 0x80 can represent a valid number */ -#define OP >= - -#endif /* 'A' == 65 */ - -#if 'A' == 193 - /* EBCDIC */ - - static const FT_Char ft_char_table[128] = - { - /* 0x80 */ - -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, - -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, - -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - }; - - /* no character < 0x80 can represent a valid number */ -#define OP < - -#endif /* 'A' == 193 */ - - - FT_LOCAL_DEF( FT_Long ) - PS_Conv_Strtol( FT_Byte** cursor, - FT_Byte* limit, - FT_Long base ) - { - FT_Byte* p = *cursor; - - FT_Long num = 0; - FT_Bool sign = 0; - FT_Bool have_overflow = 0; - - FT_Long num_limit; - FT_Char c_limit; - - - if ( p >= limit ) - goto Bad; - - if ( base < 2 || base > 36 ) - { - FT_TRACE4(( "!!!INVALID BASE:!!!" )); - return 0; - } - - if ( *p == '-' || *p == '+' ) - { - sign = FT_BOOL( *p == '-' ); - - p++; - if ( p == limit ) - goto Bad; - } - - num_limit = 0x7FFFFFFFL / base; - c_limit = (FT_Char)( 0x7FFFFFFFL % base ); - - for ( ; p < limit; p++ ) - { - FT_Char c; - - - if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) - break; - - c = ft_char_table[*p & 0x7f]; - - if ( c < 0 || c >= base ) - break; - - if ( num > num_limit || ( num == num_limit && c > c_limit ) ) - have_overflow = 1; - else - num = num * base + c; - } - - *cursor = p; - - if ( have_overflow ) - { - num = 0x7FFFFFFFL; - FT_TRACE4(( "!!!OVERFLOW:!!!" )); - } - - if ( sign ) - num = -num; - - return num; - - Bad: - FT_TRACE4(( "!!!END OF DATA:!!!" )); - return 0; - } - - - FT_LOCAL_DEF( FT_Long ) - PS_Conv_ToInt( FT_Byte** cursor, - FT_Byte* limit ) - - { - FT_Byte* p = *cursor; - FT_Byte* curp; - - FT_Long num; - - - curp = p; - num = PS_Conv_Strtol( &p, limit, 10 ); - - if ( p == curp ) - return 0; - - if ( p < limit && *p == '#' ) - { - p++; - - curp = p; - num = PS_Conv_Strtol( &p, limit, num ); - - if ( p == curp ) - return 0; - } - - *cursor = p; - - return num; - } - - - FT_LOCAL_DEF( FT_Fixed ) - PS_Conv_ToFixed( FT_Byte** cursor, - FT_Byte* limit, - FT_Long power_ten ) - { - FT_Byte* p = *cursor; - FT_Byte* curp; - - FT_Fixed integral = 0; - FT_Long decimal = 0; - FT_Long divider = 1; - - FT_Bool sign = 0; - FT_Bool have_overflow = 0; - FT_Bool have_underflow = 0; - - - if ( p >= limit ) - goto Bad; - - if ( *p == '-' || *p == '+' ) - { - sign = FT_BOOL( *p == '-' ); - - p++; - if ( p == limit ) - goto Bad; - } - - /* read the integer part */ - if ( *p != '.' ) - { - curp = p; - integral = PS_Conv_ToInt( &p, limit ); - - if ( p == curp ) - return 0; - - if ( integral > 0x7FFF ) - have_overflow = 1; - else - integral = (FT_Fixed)( (FT_UInt32)integral << 16 ); - } - - /* read the decimal part */ - if ( p < limit && *p == '.' ) - { - p++; - - for ( ; p < limit; p++ ) - { - FT_Char c; - - - if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) - break; - - c = ft_char_table[*p & 0x7f]; - - if ( c < 0 || c >= 10 ) - break; - - if ( decimal < 0xCCCCCCCL ) - { - decimal = decimal * 10 + c; - - if ( !integral && power_ten > 0 ) - power_ten--; - else - divider *= 10; - } - } - } - - /* read exponent, if any */ - if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) ) - { - FT_Long exponent; - - - p++; - - curp = p; - exponent = PS_Conv_ToInt( &p, limit ); - - if ( curp == p ) - return 0; - - /* arbitrarily limit exponent */ - if ( exponent > 1000 ) - have_overflow = 1; - else if ( exponent < -1000 ) - have_underflow = 1; - else - power_ten += exponent; - } - - *cursor = p; - - if ( !integral && !decimal ) - return 0; - - if ( have_overflow ) - goto Overflow; - if ( have_underflow ) - goto Underflow; - - while ( power_ten > 0 ) - { - if ( integral >= 0xCCCCCCCL ) - goto Overflow; - integral *= 10; - - if ( decimal >= 0xCCCCCCCL ) - { - if ( divider == 1 ) - goto Overflow; - divider /= 10; - } - else - decimal *= 10; - - power_ten--; - } - - while ( power_ten < 0 ) - { - integral /= 10; - if ( divider < 0xCCCCCCCL ) - divider *= 10; - else - decimal /= 10; - - if ( !integral && !decimal ) - goto Underflow; - - power_ten++; - } - - if ( decimal ) - { - decimal = FT_DivFix( decimal, divider ); - /* it's not necessary to check this addition for overflow */ - /* due to the structure of the real number representation */ - integral += decimal; - } - - Exit: - if ( sign ) - integral = -integral; - - return integral; - - Bad: - FT_TRACE4(( "!!!END OF DATA:!!!" )); - return 0; - - Overflow: - integral = 0x7FFFFFFFL; - FT_TRACE4(( "!!!OVERFLOW:!!!" )); - goto Exit; - - Underflow: - FT_TRACE4(( "!!!UNDERFLOW:!!!" )); - return 0; - } - - -#if 0 - FT_LOCAL_DEF( FT_UInt ) - PS_Conv_StringDecode( FT_Byte** cursor, - FT_Byte* limit, - FT_Byte* buffer, - FT_Offset n ) - { - FT_Byte* p; - FT_UInt r = 0; - - - for ( p = *cursor; r < n && p < limit; p++ ) - { - FT_Byte b; - - - if ( *p != '\\' ) - { - buffer[r++] = *p; - - continue; - } - - p++; - - switch ( *p ) - { - case 'n': - b = '\n'; - break; - case 'r': - b = '\r'; - break; - case 't': - b = '\t'; - break; - case 'b': - b = '\b'; - break; - case 'f': - b = '\f'; - break; - case '\r': - p++; - if ( *p != '\n' ) - { - b = *p; - - break; - } - /* no break */ - case '\n': - continue; - break; - default: - if ( IS_PS_DIGIT( *p ) ) - { - b = *p - '0'; - - p++; - - if ( IS_PS_DIGIT( *p ) ) - { - b = b * 8 + *p - '0'; - - p++; - - if ( IS_PS_DIGIT( *p ) ) - b = b * 8 + *p - '0'; - else - { - buffer[r++] = b; - b = *p; - } - } - else - { - buffer[r++] = b; - b = *p; - } - } - else - b = *p; - break; - } - - buffer[r++] = b; - } - - *cursor = p; - - return r; - } -#endif /* 0 */ - - - FT_LOCAL_DEF( FT_UInt ) - PS_Conv_ASCIIHexDecode( FT_Byte** cursor, - FT_Byte* limit, - FT_Byte* buffer, - FT_Offset n ) - { - FT_Byte* p; - FT_UInt r = 0; - FT_UInt w = 0; - FT_UInt pad = 0x01; - - - n *= 2; - -#if 1 - - p = *cursor; - - if ( p >= limit ) - return 0; - - 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; - - - if ( IS_PS_SPACE( *p ) ) - continue; - - if ( *p OP 0x80 ) - break; - - c = ft_char_table[*p & 0x7f]; - - if ( (unsigned)c >= 16 ) - break; - - if ( r & 1 ) - { - *buffer = (FT_Byte)(*buffer + c); - buffer++; - } - else - *buffer = (FT_Byte)(c << 4); - - r++; - } - - *cursor = p; - - return ( r + 1 ) / 2; - -#endif /* 0 */ - - } - - - FT_LOCAL_DEF( FT_UInt ) - PS_Conv_EexecDecode( FT_Byte** cursor, - FT_Byte* limit, - FT_Byte* buffer, - FT_Offset n, - FT_UShort* seed ) - { - FT_Byte* p; - FT_UInt r; - FT_UInt s = *seed; - - -#if 1 - - p = *cursor; - - if ( p >= limit ) - return 0; - - 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 ) ); - - - s = (FT_UShort)( ( *p + s ) * 52845U + 22719 ); - *buffer++ = b; - } - *cursor = p; - *seed = s; - -#endif /* 0 */ - - return r; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/psconv.h b/drivers/freetype/freetype/src/psaux/psconv.h deleted file mode 100644 index d91c762210..0000000000 --- a/drivers/freetype/freetype/src/psaux/psconv.h +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************/ -/* */ -/* psconv.h */ -/* */ -/* Some convenience conversions (specification). */ -/* */ -/* Copyright 2006, 2012 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 __PSCONV_H__ -#define __PSCONV_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_POSTSCRIPT_AUX_H - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Long ) - PS_Conv_Strtol( FT_Byte** cursor, - FT_Byte* limit, - FT_Long base ); - - - FT_LOCAL( FT_Long ) - PS_Conv_ToInt( FT_Byte** cursor, - FT_Byte* limit ); - - FT_LOCAL( FT_Fixed ) - PS_Conv_ToFixed( FT_Byte** cursor, - FT_Byte* limit, - FT_Long power_ten ); - -#if 0 - FT_LOCAL( FT_UInt ) - PS_Conv_StringDecode( FT_Byte** cursor, - FT_Byte* limit, - FT_Byte* buffer, - FT_Offset n ); -#endif - - FT_LOCAL( FT_UInt ) - PS_Conv_ASCIIHexDecode( FT_Byte** cursor, - FT_Byte* limit, - FT_Byte* buffer, - FT_Offset n ); - - FT_LOCAL( FT_UInt ) - PS_Conv_EexecDecode( FT_Byte** cursor, - FT_Byte* limit, - FT_Byte* buffer, - FT_Offset n, - FT_UShort* seed ); - - -FT_END_HEADER - -#endif /* __PSCONV_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/psobjs.c b/drivers/freetype/freetype/src/psaux/psobjs.c deleted file mode 100644 index dd976d3a96..0000000000 --- a/drivers/freetype/freetype/src/psaux/psobjs.c +++ /dev/null @@ -1,1765 +0,0 @@ -/***************************************************************************/ -/* */ -/* psobjs.c */ -/* */ -/* Auxiliary functions for PostScript fonts (body). */ -/* */ -/* Copyright 1996-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H - -#include "psobjs.h" -#include "psconv.h" - -#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 - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PS_TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_table_new */ - /* */ - /* <Description> */ - /* Initializes a PS_Table. */ - /* */ - /* <InOut> */ - /* table :: The address of the target table. */ - /* */ - /* <Input> */ - /* count :: The table size = the maximum number of elements. */ - /* */ - /* memory :: The memory object to use for all subsequent */ - /* reallocations. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - ps_table_new( PS_Table table, - FT_Int count, - FT_Memory memory ) - { - FT_Error error; - - - table->memory = memory; - if ( FT_NEW_ARRAY( table->elements, count ) || - FT_NEW_ARRAY( table->lengths, count ) ) - goto Exit; - - table->max_elems = count; - table->init = 0xDEADBEEFUL; - table->num_elems = 0; - table->block = 0; - table->capacity = 0; - table->cursor = 0; - - *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs; - - Exit: - if ( error ) - FT_FREE( table->elements ); - - return error; - } - - - static void - shift_elements( PS_Table table, - FT_Byte* old_base ) - { - FT_PtrDist delta = table->block - old_base; - FT_Byte** offset = table->elements; - FT_Byte** limit = offset + table->max_elems; - - - for ( ; offset < limit; offset++ ) - { - if ( offset[0] ) - offset[0] += delta; - } - } - - - static FT_Error - reallocate_t1_table( PS_Table table, - FT_Offset new_size ) - { - FT_Memory memory = table->memory; - FT_Byte* old_base = table->block; - FT_Error error; - - - /* allocate new base block */ - if ( FT_ALLOC( table->block, new_size ) ) - { - table->block = old_base; - return error; - } - - /* copy elements and shift offsets */ - if ( old_base ) - { - FT_MEM_COPY( table->block, old_base, table->capacity ); - shift_elements( table, old_base ); - FT_FREE( old_base ); - } - - table->capacity = new_size; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_table_add */ - /* */ - /* <Description> */ - /* Adds an object to a PS_Table, possibly growing its memory block. */ - /* */ - /* <InOut> */ - /* table :: The target table. */ - /* */ - /* <Input> */ - /* idx :: The index of the object in the table. */ - /* */ - /* object :: The address of the object to copy in memory. */ - /* */ - /* length :: The length in bytes of the source object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. An error is returned if a */ - /* reallocation fails. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ) - { - if ( idx < 0 || idx >= table->max_elems ) - { - FT_ERROR(( "ps_table_add: invalid index\n" )); - return FT_THROW( Invalid_Argument ); - } - - if ( length < 0 ) - { - FT_ERROR(( "ps_table_add: invalid length\n" )); - return FT_THROW( Invalid_Argument ); - } - - /* grow the base block if needed */ - if ( table->cursor + length > table->capacity ) - { - FT_Error error; - FT_Offset new_size = table->capacity; - FT_PtrDist in_offset; - - - in_offset = (FT_Byte*)object - table->block; - if ( in_offset < 0 || (FT_Offset)in_offset >= table->capacity ) - in_offset = -1; - - while ( new_size < table->cursor + length ) - { - /* increase size by 25% and round up to the nearest multiple - of 1024 */ - new_size += ( new_size >> 2 ) + 1; - new_size = FT_PAD_CEIL( new_size, 1024 ); - } - - error = reallocate_t1_table( table, new_size ); - if ( error ) - return error; - - if ( in_offset >= 0 ) - object = table->block + in_offset; - } - - /* add the object to the base block and adjust offset */ - table->elements[idx] = table->block + table->cursor; - table->lengths [idx] = length; - FT_MEM_COPY( table->block + table->cursor, object, length ); - - table->cursor += length; - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_table_done */ - /* */ - /* <Description> */ - /* Finalizes a PS_TableRec (i.e., reallocate it to its current */ - /* cursor). */ - /* */ - /* <InOut> */ - /* table :: The target table. */ - /* */ - /* <Note> */ - /* This function does NOT release the heap's memory block. It is up */ - /* to the caller to clean it, or reference it in its own structures. */ - /* */ - FT_LOCAL_DEF( void ) - ps_table_done( PS_Table table ) - { - FT_Memory memory = table->memory; - FT_Error error; - FT_Byte* old_base = table->block; - - - /* should never fail, because rec.cursor <= rec.size */ - if ( !old_base ) - return; - - if ( FT_ALLOC( table->block, table->cursor ) ) - return; - FT_MEM_COPY( table->block, old_base, table->cursor ); - shift_elements( table, old_base ); - - table->capacity = table->cursor; - FT_FREE( old_base ); - - FT_UNUSED( error ); - } - - - FT_LOCAL_DEF( void ) - ps_table_release( PS_Table table ) - { - FT_Memory memory = table->memory; - - - if ( (FT_ULong)table->init == 0xDEADBEEFUL ) - { - FT_FREE( table->block ); - FT_FREE( table->elements ); - FT_FREE( table->lengths ); - table->init = 0; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1 PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* first character must be already part of the comment */ - - static void - skip_comment( FT_Byte* *acur, - FT_Byte* limit ) - { - FT_Byte* cur = *acur; - - - while ( cur < limit ) - { - if ( IS_PS_NEWLINE( *cur ) ) - break; - cur++; - } - - *acur = cur; - } - - - static void - skip_spaces( FT_Byte* *acur, - FT_Byte* limit ) - { - FT_Byte* cur = *acur; - - - while ( cur < limit ) - { - if ( !IS_PS_SPACE( *cur ) ) - { - if ( *cur == '%' ) - /* According to the PLRM, a comment is equal to a space. */ - skip_comment( &cur, limit ); - else - break; - } - cur++; - } - - *acur = cur; - } - - -#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' ) - - - /* 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_Error error = FT_ERR( Invalid_File_Format ); - unsigned int i; - - - while ( cur < limit ) - { - 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 ( c == ')' ) - { - embed--; - if ( embed == 0 ) - { - error = FT_Err_Ok; - break; - } - } - } - - *acur = cur; - - return error; - } - - - /* first character must be `<' */ - - static FT_Error - skip_string( FT_Byte* *acur, - FT_Byte* limit ) - { - FT_Byte* cur = *acur; - FT_Error err = FT_Err_Ok; - - - while ( ++cur < limit ) - { - /* All whitespace characters are ignored. */ - skip_spaces( &cur, limit ); - if ( cur >= limit ) - break; - - if ( !IS_PS_XDIGIT( *cur ) ) - break; - } - - if ( cur < limit && *cur != '>' ) - { - FT_ERROR(( "skip_string: missing closing delimiter `>'\n" )); - err = FT_THROW( Invalid_File_Format ); - } - else - 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 = FT_Err_Ok; - - - FT_ASSERT( **acur == '{' ); - - for ( cur = *acur; cur < limit && error == FT_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 = FT_THROW( Invalid_File_Format ); - - *acur = cur; - - return error; - } - - - /***********************************************************************/ - /* */ - /* All exported parsing routines handle leading whitespace and stop at */ - /* the first character which isn't part of the just handled token. */ - /* */ - /***********************************************************************/ - - - FT_LOCAL_DEF( void ) - ps_parser_skip_PS_token( PS_Parser parser ) - { - /* Note: PostScript allows any non-delimiting, non-whitespace */ - /* character in a name (PS Ref Manual, 3rd ed, p31). */ - /* PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */ - - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - FT_Error error = FT_Err_Ok; - - - skip_spaces( &cur, limit ); /* this also skips comments */ - if ( cur >= limit ) - goto Exit; - - /* self-delimiting, single-character tokens */ - if ( *cur == '[' || *cur == ']' ) - { - cur++; - goto Exit; - } - - /* skip balanced expressions (procedures and strings) */ - - if ( *cur == '{' ) /* {...} */ - { - error = skip_procedure( &cur, limit ); - goto Exit; - } - - if ( *cur == '(' ) /* (...) */ - { - error = skip_literal_string( &cur, limit ); - goto Exit; - } - - if ( *cur == '<' ) /* <...> */ - { - if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */ - { - cur++; - cur++; - } - else - error = skip_string( &cur, limit ); - - goto Exit; - } - - if ( *cur == '>' ) - { - cur++; - if ( cur >= limit || *cur != '>' ) /* >> */ - { - FT_ERROR(( "ps_parser_skip_PS_token:" - " unexpected closing delimiter `>'\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - cur++; - goto Exit; - } - - if ( *cur == '/' ) - cur++; - - /* anything else */ - while ( cur < limit ) - { - /* *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 < limit && cur == parser->cursor ) - { - FT_ERROR(( "ps_parser_skip_PS_token:" - " current token is `%c' which is self-delimiting\n" - " " - " but invalid at this point\n", - *cur )); - - error = FT_THROW( Invalid_File_Format ); - } - - parser->error = error; - parser->cursor = cur; - } - - - FT_LOCAL_DEF( void ) - ps_parser_skip_spaces( PS_Parser parser ) - { - skip_spaces( &parser->cursor, parser->limit ); - } - - - /* `token' here means either something between balanced delimiters */ - /* or the next token; the delimiters are not removed. */ - - FT_LOCAL_DEF( void ) - ps_parser_to_token( PS_Parser parser, - T1_Token token ) - { - FT_Byte* cur; - FT_Byte* limit; - FT_Int embed; - - - token->type = T1_TOKEN_TYPE_NONE; - token->start = 0; - token->limit = 0; - - /* first of all, skip leading whitespace */ - ps_parser_skip_spaces( parser ); - - cur = parser->cursor; - limit = parser->limit; - - if ( cur >= limit ) - return; - - switch ( *cur ) - { - /************* check for literal string *****************/ - case '(': - token->type = T1_TOKEN_TYPE_STRING; - token->start = cur; - - if ( skip_literal_string( &cur, limit ) == FT_Err_Ok ) - token->limit = cur; - break; - - /************* check for programs/array *****************/ - case '{': - token->type = T1_TOKEN_TYPE_ARRAY; - token->start = cur; - - if ( skip_procedure( &cur, limit ) == FT_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; - embed = 1; - token->start = cur++; - - /* we need this to catch `[ ]' */ - parser->cursor = cur; - ps_parser_skip_spaces( parser ); - cur = parser->cursor; - - while ( cur < limit && !parser->error ) - { - /* XXX: this is wrong because it does not */ - /* skip comments, procedures, and strings */ - if ( *cur == '[' ) - embed++; - else if ( *cur == ']' ) - { - embed--; - if ( embed <= 0 ) - { - token->limit = ++cur; - break; - } - } - - parser->cursor = cur; - ps_parser_skip_PS_token( parser ); - /* we need this to catch `[XXX ]' */ - ps_parser_skip_spaces ( parser ); - cur = parser->cursor; - } - break; - - /* ************ otherwise, it is any token **************/ - default: - token->start = cur; - token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY ); - ps_parser_skip_PS_token( parser ); - cur = parser->cursor; - if ( !parser->error ) - token->limit = cur; - } - - if ( !token->limit ) - { - token->start = 0; - token->type = T1_TOKEN_TYPE_NONE; - } - - parser->cursor = cur; - } - - - /* 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, - FT_UInt max_tokens, - FT_Int* pnum_tokens ) - { - T1_TokenRec master; - - - *pnum_tokens = -1; - - /* this also handles leading whitespace */ - ps_parser_to_token( parser, &master ); - - if ( master.type == T1_TOKEN_TYPE_ARRAY ) - { - FT_Byte* old_cursor = parser->cursor; - FT_Byte* old_limit = parser->limit; - T1_Token cur = tokens; - T1_Token limit = cur + max_tokens; - - - /* don't include outermost delimiters */ - parser->cursor = master.start + 1; - parser->limit = master.limit - 1; - - while ( parser->cursor < parser->limit ) - { - T1_TokenRec token; - - - ps_parser_to_token( parser, &token ); - if ( !token.type ) - break; - - if ( tokens != NULL && cur < limit ) - *cur = token; - - cur++; - } - - *pnum_tokens = (FT_Int)( cur - tokens ); - - parser->cursor = old_cursor; - parser->limit = old_limit; - } - } - - - /* 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, - FT_Byte* limit, - FT_Int max_coords, - FT_Short* coords ) - { - FT_Byte* cur = *acur; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) - goto Exit; - - /* check for the beginning of an array; otherwise, only one number */ - /* will be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - else if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the coordinates */ - while ( cur < limit ) - { - FT_Short dummy; - FT_Byte* old_cur; - - - /* skip whitespace in front of data */ - skip_spaces( &cur, limit ); - if ( cur >= limit ) - goto Exit; - - if ( *cur == ender ) - { - cur++; - break; - } - - old_cur = cur; - - if ( coords != NULL && count >= max_coords ) - break; - - /* 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 ); - - if ( old_cur == cur ) - { - count = -1; - goto Exit; - } - else - count++; - - if ( !ender ) - break; - } - - Exit: - *acur = cur; - return count; - } - - - /* 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, - FT_Byte* limit, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - FT_Byte* cur = *acur; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) - goto Exit; - - /* Check for the beginning of an array. Otherwise, only one number */ - /* will be read. */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - else if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the values */ - while ( cur < limit ) - { - FT_Fixed dummy; - FT_Byte* old_cur; - - - /* skip whitespace in front of data */ - skip_spaces( &cur, limit ); - if ( cur >= limit ) - goto Exit; - - if ( *cur == ender ) - { - cur++; - break; - } - - old_cur = cur; - - if ( values != NULL && count >= max_values ) - break; - - /* 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 ); - - if ( old_cur == cur ) - { - count = -1; - goto Exit; - } - else - count++; - - if ( !ender ) - break; - } - - Exit: - *acur = cur; - return count; - } - - -#if 0 - - static FT_String* - ps_tostring( FT_Byte** cursor, - FT_Byte* limit, - FT_Memory memory ) - { - FT_Byte* cur = *cursor; - FT_PtrDist len = 0; - FT_Int count; - FT_String* result; - FT_Error error; - - - /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ - /* that simply doesn't begin with an opening parenthesis, even */ - /* though they have a closing one! E.g. "amuncial.pfb" */ - /* */ - /* We must deal with these ill-fated cases there. Note that */ - /* these fonts didn't work with the old Type 1 driver as the */ - /* notice/copyright was not recognized as a valid string token */ - /* and made the old token parser commit errors. */ - - while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) - cur++; - if ( cur + 1 >= limit ) - return 0; - - if ( *cur == '(' ) - cur++; /* skip the opening parenthesis, if there is one */ - - *cursor = cur; - count = 0; - - /* then, count its length */ - for ( ; cur < limit; cur++ ) - { - if ( *cur == '(' ) - count++; - - else if ( *cur == ')' ) - { - count--; - if ( count < 0 ) - break; - } - } - - len = cur - *cursor; - if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) - return 0; - - /* now copy the string */ - FT_MEM_COPY( result, *cursor, len ); - result[len] = '\0'; - *cursor = cur; - return result; - } - -#endif /* 0 */ - - - static int - ps_tobool( FT_Byte* *acur, - FT_Byte* limit ) - { - FT_Byte* cur = *acur; - FT_Bool result = 0; - - - /* return 1 if we find `true', 0 otherwise */ - if ( cur + 3 < limit && - cur[0] == 't' && - cur[1] == 'r' && - cur[2] == 'u' && - cur[3] == 'e' ) - { - result = 1; - cur += 5; - } - else if ( cur + 4 < limit && - cur[0] == 'f' && - cur[1] == 'a' && - cur[2] == 'l' && - cur[3] == 's' && - cur[4] == 'e' ) - { - result = 0; - cur += 6; - } - - *acur = cur; - return result; - } - - - /* load a simple field (i.e. non-table) into the current list of objects */ - - FT_LOCAL_DEF( FT_Error ) - ps_parser_load_field( PS_Parser parser, - const T1_Field field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ) - { - T1_TokenRec token; - FT_Byte* cur; - FT_Byte* limit; - FT_UInt count; - FT_UInt idx; - FT_Error error; - T1_FieldType type; - - - /* this also skips leading whitespace */ - ps_parser_to_token( parser, &token ); - if ( !token.type ) - goto Fail; - - count = 1; - idx = 0; - cur = token.start; - limit = token.limit; - - type = field->type; - - /* we must detect arrays in /FontBBox */ - if ( type == T1_FIELD_TYPE_BBOX ) - { - T1_TokenRec token2; - FT_Byte* old_cur = parser->cursor; - FT_Byte* old_limit = parser->limit; - - - /* don't include delimiters */ - parser->cursor = token.start + 1; - parser->limit = token.limit - 1; - - ps_parser_to_token( parser, &token2 ); - parser->cursor = old_cur; - parser->limit = old_limit; - - if ( token2.type == T1_TOKEN_TYPE_ARRAY ) - { - type = T1_FIELD_TYPE_MM_BBOX; - goto FieldArray; - } - } - else if ( token.type == T1_TOKEN_TYPE_ARRAY ) - { - count = max_objects; - - FieldArray: - /* if this is an array and we have no blend, an error occurs */ - if ( max_objects == 0 ) - goto Fail; - - idx = 1; - - /* don't include delimiters */ - cur++; - limit--; - } - - for ( ; count > 0; count--, idx++ ) - { - FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; - FT_Long val; - FT_String* string; - - - skip_spaces( &cur, limit ); - - switch ( type ) - { - case T1_FIELD_TYPE_BOOL: - val = ps_tobool( &cur, limit ); - goto Store_Integer; - - case T1_FIELD_TYPE_FIXED: - val = PS_Conv_ToFixed( &cur, limit, 0 ); - goto Store_Integer; - - case T1_FIELD_TYPE_FIXED_1000: - val = PS_Conv_ToFixed( &cur, limit, 3 ); - goto Store_Integer; - - case T1_FIELD_TYPE_INTEGER: - val = PS_Conv_ToInt( &cur, limit ); - /* fall through */ - - Store_Integer: - switch ( field->size ) - { - case (8 / FT_CHAR_BIT): - *(FT_Byte*)q = (FT_Byte)val; - break; - - case (16 / FT_CHAR_BIT): - *(FT_UShort*)q = (FT_UShort)val; - break; - - case (32 / FT_CHAR_BIT): - *(FT_UInt32*)q = (FT_UInt32)val; - break; - - default: /* for 64-bit systems */ - *(FT_Long*)q = val; - } - break; - - case T1_FIELD_TYPE_STRING: - case T1_FIELD_TYPE_KEY: - { - FT_Memory memory = parser->memory; - FT_UInt len = (FT_UInt)( limit - cur ); - - - if ( cur >= limit ) - break; - - /* 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 if ( token.type == T1_TOKEN_TYPE_STRING ) - { - /* 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\n" - " " - " but found token of type %d instead\n", - token.type )); - error = FT_THROW( 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; - - FT_MEM_COPY( string, cur, len ); - string[len] = 0; - - *(FT_String**)q = string; - } - break; - - case T1_FIELD_TYPE_BBOX: - { - FT_Fixed temp[4]; - FT_BBox* bbox = (FT_BBox*)q; - FT_Int result; - - - result = ps_tofixedarray( &cur, limit, 4, temp, 0 ); - - if ( result < 0 ) - { - FT_ERROR(( "ps_parser_load_field:" - " expected four integers in bounding box\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - bbox->xMin = FT_RoundFix( temp[0] ); - bbox->yMin = FT_RoundFix( temp[1] ); - bbox->xMax = FT_RoundFix( temp[2] ); - bbox->yMax = FT_RoundFix( temp[3] ); - } - break; - - case T1_FIELD_TYPE_MM_BBOX: - { - FT_Memory memory = parser->memory; - FT_Fixed* temp; - FT_Int result; - FT_UInt i; - - - if ( FT_NEW_ARRAY( temp, max_objects * 4 ) ) - goto Exit; - - for ( i = 0; i < 4; i++ ) - { - result = ps_tofixedarray( &cur, limit, max_objects, - temp + i * max_objects, 0 ); - if ( result < 0 ) - { - FT_ERROR(( "ps_parser_load_field:" - " expected %d integers in the %s subarray\n" - " " - " of /FontBBox in the /Blend dictionary\n", - max_objects, - i == 0 ? "first" - : ( i == 1 ? "second" - : ( i == 2 ? "third" - : "fourth" ) ) )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - skip_spaces( &cur, limit ); - } - - for ( i = 0; i < max_objects; i++ ) - { - FT_BBox* bbox = (FT_BBox*)objects[i]; - - - bbox->xMin = FT_RoundFix( temp[i ] ); - bbox->yMin = FT_RoundFix( temp[i + max_objects] ); - bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] ); - bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] ); - } - - FT_FREE( temp ); - } - break; - - default: - /* an error occurred */ - goto Fail; - } - } - -#if 0 /* obsolete -- keep for reference */ - if ( pflags ) - *pflags |= 1L << field->flag_bit; -#else - FT_UNUSED( pflags ); -#endif - - error = FT_Err_Ok; - - Exit: - return error; - - Fail: - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - -#define T1_MAX_TABLE_ELEMENTS 32 - - - FT_LOCAL_DEF( FT_Error ) - ps_parser_load_field_table( PS_Parser parser, - const T1_Field field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ) - { - T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; - T1_Token token; - FT_Int num_elements; - FT_Error error = FT_Err_Ok; - FT_Byte* old_cursor; - FT_Byte* old_limit; - T1_FieldRec fieldrec = *(T1_Field)field; - - - fieldrec.type = T1_FIELD_TYPE_INTEGER; - if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY || - field->type == T1_FIELD_TYPE_BBOX ) - fieldrec.type = T1_FIELD_TYPE_FIXED; - - ps_parser_to_token_array( parser, elements, - T1_MAX_TABLE_ELEMENTS, &num_elements ); - if ( num_elements < 0 ) - { - error = FT_ERR( Ignore ); - goto Exit; - } - if ( (FT_UInt)num_elements > field->array_max ) - num_elements = field->array_max; - - old_cursor = parser->cursor; - old_limit = parser->limit; - - /* we store the elements count if necessary; */ - /* we further assume that `count_offset' can't be zero */ - if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 ) - *(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; - for ( ; num_elements > 0; num_elements--, token++ ) - { - parser->cursor = token->start; - parser->limit = token->limit; - ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 ); - fieldrec.offset += fieldrec.size; - } - -#if 0 /* obsolete -- keep for reference */ - if ( pflags ) - *pflags |= 1L << field->flag_bit; -#else - FT_UNUSED( pflags ); -#endif - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Long ) - ps_parser_to_int( PS_Parser parser ) - { - ps_parser_skip_spaces( parser ); - return PS_Conv_ToInt( &parser->cursor, parser->limit ); - } - - - /* first character must be `<' if `delimiters' is non-zero */ - - FT_LOCAL_DEF( FT_Error ) - ps_parser_to_bytes( PS_Parser parser, - FT_Byte* bytes, - FT_Offset max_bytes, - FT_Long* pnum_bytes, - FT_Bool delimiters ) - { - FT_Error error = FT_Err_Ok; - FT_Byte* cur; - - - ps_parser_skip_spaces( parser ); - cur = parser->cursor; - - if ( cur >= parser->limit ) - goto Exit; - - if ( delimiters ) - { - if ( *cur != '<' ) - { - FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - cur++; - } - - *pnum_bytes = PS_Conv_ASCIIHexDecode( &cur, - parser->limit, - bytes, - max_bytes ); - - if ( delimiters ) - { - if ( cur < parser->limit && *cur != '>' ) - { - FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - cur++; - } - - parser->cursor = cur; - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Fixed ) - ps_parser_to_fixed( PS_Parser parser, - FT_Int power_ten ) - { - ps_parser_skip_spaces( parser ); - return PS_Conv_ToFixed( &parser->cursor, parser->limit, power_ten ); - } - - - FT_LOCAL_DEF( FT_Int ) - ps_parser_to_coord_array( PS_Parser parser, - FT_Int max_coords, - FT_Short* coords ) - { - ps_parser_skip_spaces( parser ); - return ps_tocoordarray( &parser->cursor, parser->limit, - max_coords, coords ); - } - - - FT_LOCAL_DEF( FT_Int ) - ps_parser_to_fixed_array( PS_Parser parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - ps_parser_skip_spaces( parser ); - return ps_tofixedarray( &parser->cursor, parser->limit, - max_values, values, power_ten ); - } - - -#if 0 - - FT_LOCAL_DEF( FT_String* ) - T1_ToString( PS_Parser parser ) - { - return ps_tostring( &parser->cursor, parser->limit, parser->memory ); - } - - - FT_LOCAL_DEF( FT_Bool ) - T1_ToBool( PS_Parser parser ) - { - return ps_tobool( &parser->cursor, parser->limit ); - } - -#endif /* 0 */ - - - FT_LOCAL_DEF( void ) - ps_parser_init( PS_Parser parser, - FT_Byte* base, - FT_Byte* limit, - FT_Memory memory ) - { - parser->error = FT_Err_Ok; - parser->base = base; - parser->limit = limit; - parser->cursor = base; - parser->memory = memory; - parser->funcs = ps_parser_funcs; - } - - - FT_LOCAL_DEF( void ) - ps_parser_done( PS_Parser parser ) - { - FT_UNUSED( parser ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1 BUILDER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_builder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph builder. */ - /* */ - /* <InOut> */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting should be applied. */ - /* */ - FT_LOCAL_DEF( void ) - t1_builder_init( T1_Builder builder, - FT_Face face, - FT_Size size, - FT_GlyphSlot glyph, - FT_Bool hinting ) - { - builder->parse_state = T1_Parse_Start; - builder->load_points = 1; - - builder->face = face; - builder->glyph = glyph; - builder->memory = face->memory; - - if ( glyph ) - { - FT_GlyphLoader loader = glyph->internal->loader; - - - builder->loader = loader; - builder->base = &loader->base.outline; - builder->current = &loader->current.outline; - FT_GlyphLoader_Rewind( loader ); - - builder->hints_globals = size->internal; - builder->hints_funcs = 0; - - if ( hinting ) - builder->hints_funcs = glyph->internal->glyph_hints; - } - - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - - builder->funcs = t1_builder_funcs; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_builder_done */ - /* */ - /* <Description> */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* <Input> */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - FT_LOCAL_DEF( void ) - t1_builder_done( T1_Builder builder ) - { - FT_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->outline = *builder->base; - } - - - /* check that there is enough space for `count' more points */ - FT_LOCAL_DEF( FT_Error ) - t1_builder_check_points( T1_Builder builder, - FT_Int count ) - { - return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); - } - - - /* add a new point, do not check space */ - FT_LOCAL_DEF( void ) - t1_builder_add_point( T1_Builder builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) - { - FT_Outline* outline = builder->current; - - - if ( builder->load_points ) - { - FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - - - point->x = FIXED_TO_INT( x ); - point->y = FIXED_TO_INT( y ); - *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - } - outline->n_points++; - } - - - /* check space for a new on-curve point, then add it */ - FT_LOCAL_DEF( FT_Error ) - t1_builder_add_point1( T1_Builder builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - - - error = t1_builder_check_points( builder, 1 ); - if ( !error ) - t1_builder_add_point( builder, x, y, 1 ); - - return error; - } - - - /* check space for a new contour, then add it */ - FT_LOCAL_DEF( FT_Error ) - t1_builder_add_contour( T1_Builder builder ) - { - FT_Outline* outline = builder->current; - FT_Error error; - - - /* this might happen in invalid fonts */ - if ( !outline ) - { - FT_ERROR(( "t1_builder_add_contour: no outline to add points to\n" )); - return FT_THROW( Invalid_File_Format ); - } - - if ( !builder->load_points ) - { - outline->n_contours++; - return FT_Err_Ok; - } - - error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); - if ( !error ) - { - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); - - outline->n_contours++; - } - - return error; - } - - - /* if a path was begun, add its first on-curve point */ - FT_LOCAL_DEF( FT_Error ) - t1_builder_start_point( T1_Builder builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error = FT_ERR( Invalid_File_Format ); - - - /* test whether we are building a new contour */ - - if ( builder->parse_state == T1_Parse_Have_Path ) - error = FT_Err_Ok; - else - { - builder->parse_state = T1_Parse_Have_Path; - error = t1_builder_add_contour( builder ); - if ( !error ) - error = t1_builder_add_point1( builder, x, y ); - } - - return error; - } - - - /* close the current contour */ - FT_LOCAL_DEF( void ) - t1_builder_close_contour( T1_Builder builder ) - { - FT_Outline* outline = builder->current; - FT_Int first; - - - if ( !outline ) - return; - - first = outline->n_contours <= 1 - ? 0 : outline->contours[outline->n_contours - 2] + 1; - - /* We must not include the last point in the path if it */ - /* is located on the first point. */ - if ( outline->n_points > 1 ) - { - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - - - /* `delete' last point only if it coincides with the first */ - /* point and it is not a control point (which can happen). */ - if ( p1->x == p2->x && p1->y == p2->y ) - if ( *control == FT_CURVE_TAG_ON ) - outline->n_points--; - } - - if ( outline->n_contours > 0 ) - { - /* Don't add contours only consisting of one point, i.e., */ - /* check whether the first and the last point is the same. */ - if ( first == outline->n_points - 1 ) - { - outline->n_contours--; - outline->n_points--; - } - else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** OTHER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - t1_decrypt( FT_Byte* buffer, - FT_Offset length, - FT_UShort seed ) - { - PS_Conv_EexecDecode( &buffer, - buffer + length, - buffer, - length, - &seed ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/psobjs.h b/drivers/freetype/freetype/src/psaux/psobjs.h deleted file mode 100644 index e380c60dab..0000000000 --- a/drivers/freetype/freetype/src/psaux/psobjs.h +++ /dev/null @@ -1,212 +0,0 @@ -/***************************************************************************/ -/* */ -/* psobjs.h */ -/* */ -/* Auxiliary functions for PostScript fonts (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003 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 __PSOBJS_H__ -#define __PSOBJS_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_POSTSCRIPT_AUX_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1_TABLE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_TABLE - const PS_Table_FuncsRec ps_table_funcs; - - FT_CALLBACK_TABLE - const PS_Parser_FuncsRec ps_parser_funcs; - - FT_CALLBACK_TABLE - const T1_Builder_FuncsRec t1_builder_funcs; - - - FT_LOCAL( FT_Error ) - ps_table_new( PS_Table table, - FT_Int count, - FT_Memory memory ); - - FT_LOCAL( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ); - - FT_LOCAL( void ) - ps_table_done( PS_Table table ); - - - FT_LOCAL( void ) - ps_table_release( PS_Table table ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1 PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL( void ) - ps_parser_skip_spaces( PS_Parser parser ); - - FT_LOCAL( void ) - ps_parser_skip_PS_token( PS_Parser parser ); - - FT_LOCAL( void ) - ps_parser_to_token( PS_Parser parser, - T1_Token token ); - - FT_LOCAL( void ) - ps_parser_to_token_array( PS_Parser parser, - T1_Token tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ); - - FT_LOCAL( FT_Error ) - ps_parser_load_field( PS_Parser parser, - const T1_Field field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ); - - FT_LOCAL( FT_Error ) - ps_parser_load_field_table( PS_Parser parser, - const T1_Field field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ); - - FT_LOCAL( FT_Long ) - ps_parser_to_int( PS_Parser parser ); - - - FT_LOCAL( FT_Error ) - ps_parser_to_bytes( PS_Parser parser, - FT_Byte* bytes, - FT_Offset max_bytes, - FT_Long* pnum_bytes, - FT_Bool delimiters ); - - - FT_LOCAL( FT_Fixed ) - ps_parser_to_fixed( PS_Parser parser, - FT_Int power_ten ); - - - FT_LOCAL( FT_Int ) - ps_parser_to_coord_array( PS_Parser parser, - FT_Int max_coords, - FT_Short* coords ); - - FT_LOCAL( FT_Int ) - ps_parser_to_fixed_array( PS_Parser parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ); - - - FT_LOCAL( void ) - ps_parser_init( PS_Parser parser, - FT_Byte* base, - FT_Byte* limit, - FT_Memory memory ); - - FT_LOCAL( void ) - ps_parser_done( PS_Parser parser ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** T1 BUILDER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - t1_builder_init( T1_Builder builder, - FT_Face face, - FT_Size size, - FT_GlyphSlot glyph, - FT_Bool hinting ); - - FT_LOCAL( void ) - t1_builder_done( T1_Builder builder ); - - FT_LOCAL( FT_Error ) - t1_builder_check_points( T1_Builder builder, - FT_Int count ); - - FT_LOCAL( void ) - t1_builder_add_point( T1_Builder builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ); - - FT_LOCAL( FT_Error ) - t1_builder_add_point1( T1_Builder builder, - FT_Pos x, - FT_Pos y ); - - FT_LOCAL( FT_Error ) - t1_builder_add_contour( T1_Builder builder ); - - - FT_LOCAL( FT_Error ) - t1_builder_start_point( T1_Builder builder, - FT_Pos x, - FT_Pos y ); - - - FT_LOCAL( void ) - t1_builder_close_contour( T1_Builder builder ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** OTHER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL( void ) - t1_decrypt( FT_Byte* buffer, - FT_Offset length, - FT_UShort seed ); - - -FT_END_HEADER - -#endif /* __PSOBJS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/rules.mk b/drivers/freetype/freetype/src/psaux/rules.mk deleted file mode 100644 index 7a1be37b69..0000000000 --- a/drivers/freetype/freetype/src/psaux/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 PSaux driver configuration rules -# - - -# Copyright 1996-2000, 2002, 2003, 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. - - -# PSAUX driver directory -# -PSAUX_DIR := $(SRC_DIR)/psaux - - -# compilation flags for the driver -# -PSAUX_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) - - -# PSAUX driver sources (i.e., C files) -# -PSAUX_DRV_SRC := $(PSAUX_DIR)/psobjs.c \ - $(PSAUX_DIR)/t1decode.c \ - $(PSAUX_DIR)/t1cmap.c \ - $(PSAUX_DIR)/afmparse.c \ - $(PSAUX_DIR)/psconv.c \ - $(PSAUX_DIR)/psauxmod.c - -# PSAUX driver headers -# -PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \ - $(PSAUX_DIR)/psauxerr.h - - -# PSAUX driver object(s) -# -# PSAUX_DRV_OBJ_M is used during `multi' builds. -# PSAUX_DRV_OBJ_S is used during `single' builds. -# -PSAUX_DRV_OBJ_M := $(PSAUX_DRV_SRC:$(PSAUX_DIR)/%.c=$(OBJ_DIR)/%.$O) -PSAUX_DRV_OBJ_S := $(OBJ_DIR)/psaux.$O - -# PSAUX driver source file for single build -# -PSAUX_DRV_SRC_S := $(PSAUX_DIR)/psaux.c - - -# PSAUX driver - single object -# -$(PSAUX_DRV_OBJ_S): $(PSAUX_DRV_SRC_S) $(PSAUX_DRV_SRC) \ - $(FREETYPE_H) $(PSAUX_DRV_H) - $(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSAUX_DRV_SRC_S)) - - -# PSAUX driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PSAUX_DIR)/%.c $(FREETYPE_H) $(PSAUX_DRV_H) - $(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PSAUX_DRV_OBJ_S) -DRV_OBJS_M += $(PSAUX_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/psaux/t1cmap.c b/drivers/freetype/freetype/src/psaux/t1cmap.c deleted file mode 100644 index 9e5bd34ffe..0000000000 --- a/drivers/freetype/freetype/src/psaux/t1cmap.c +++ /dev/null @@ -1,341 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1cmap.c */ -/* */ -/* Type 1 character map support (body). */ -/* */ -/* Copyright 2002, 2003, 2006, 2007, 2012 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 "t1cmap.h" - -#include FT_INTERNAL_DEBUG_H - -#include "psauxerr.h" - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - t1_cmap_std_init( T1_CMapStd cmap, - FT_Int is_expert ) - { - T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - - - cmap->num_glyphs = face->type1.num_glyphs; - cmap->glyph_names = (const char* const*)face->type1.glyph_names; - cmap->sid_to_string = psnames->adobe_std_strings; - cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding - : psnames->adobe_std_encoding; - - FT_ASSERT( cmap->code_to_sid != NULL ); - } - - - FT_CALLBACK_DEF( void ) - t1_cmap_std_done( T1_CMapStd cmap ) - { - cmap->num_glyphs = 0; - cmap->glyph_names = NULL; - cmap->sid_to_string = NULL; - cmap->code_to_sid = NULL; - } - - - FT_CALLBACK_DEF( FT_UInt ) - t1_cmap_std_char_index( T1_CMapStd cmap, - FT_UInt32 char_code ) - { - FT_UInt result = 0; - - - if ( char_code < 256 ) - { - FT_UInt code, n; - const char* glyph_name; - - - /* convert character code to Adobe SID string */ - code = cmap->code_to_sid[char_code]; - glyph_name = cmap->sid_to_string( code ); - - /* look for the corresponding glyph name */ - for ( n = 0; n < cmap->num_glyphs; n++ ) - { - const char* gname = cmap->glyph_names[n]; - - - if ( gname && gname[0] == glyph_name[0] && - ft_strcmp( gname, glyph_name ) == 0 ) - { - result = n; - break; - } - } - } - - return result; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - t1_cmap_std_char_next( T1_CMapStd cmap, - FT_UInt32 *pchar_code ) - { - FT_UInt result = 0; - FT_UInt32 char_code = *pchar_code + 1; - - - while ( char_code < 256 ) - { - result = t1_cmap_std_char_index( cmap, char_code ); - if ( result != 0 ) - goto Exit; - - char_code++; - } - char_code = 0; - - Exit: - *pchar_code = char_code; - return result; - } - - - FT_CALLBACK_DEF( FT_Error ) - t1_cmap_standard_init( T1_CMapStd cmap ) - { - t1_cmap_std_init( cmap, 0 ); - return 0; - } - - - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - t1_cmap_standard_class_rec = - { - sizeof ( T1_CMapStdRec ), - - (FT_CMap_InitFunc) t1_cmap_standard_init, - (FT_CMap_DoneFunc) t1_cmap_std_done, - (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next, - - NULL, NULL, NULL, NULL, NULL - }; - - - FT_CALLBACK_DEF( FT_Error ) - t1_cmap_expert_init( T1_CMapStd cmap ) - { - t1_cmap_std_init( cmap, 1 ); - return 0; - } - - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - t1_cmap_expert_class_rec = - { - sizeof ( T1_CMapStdRec ), - - (FT_CMap_InitFunc) t1_cmap_expert_init, - (FT_CMap_DoneFunc) t1_cmap_std_done, - (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next, - - NULL, NULL, NULL, NULL, NULL - }; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE1 CUSTOM ENCODING CMAP *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - t1_cmap_custom_init( T1_CMapCustom cmap ) - { - T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); - T1_Encoding encoding = &face->type1.encoding; - - - cmap->first = encoding->code_first; - cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); - cmap->indices = encoding->char_index; - - FT_ASSERT( cmap->indices != NULL ); - FT_ASSERT( encoding->code_first <= encoding->code_last ); - - return 0; - } - - - FT_CALLBACK_DEF( void ) - t1_cmap_custom_done( T1_CMapCustom cmap ) - { - cmap->indices = NULL; - cmap->first = 0; - cmap->count = 0; - } - - - FT_CALLBACK_DEF( FT_UInt ) - t1_cmap_custom_char_index( T1_CMapCustom cmap, - FT_UInt32 char_code ) - { - FT_UInt result = 0; - - - if ( ( char_code >= cmap->first ) && - ( char_code < ( cmap->first + cmap->count ) ) ) - result = cmap->indices[char_code]; - - return result; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - t1_cmap_custom_char_next( T1_CMapCustom cmap, - FT_UInt32 *pchar_code ) - { - FT_UInt result = 0; - FT_UInt32 char_code = *pchar_code; - - - ++char_code; - - if ( char_code < cmap->first ) - char_code = cmap->first; - - for ( ; char_code < ( cmap->first + cmap->count ); char_code++ ) - { - result = cmap->indices[char_code]; - if ( result != 0 ) - goto Exit; - } - - char_code = 0; - - Exit: - *pchar_code = char_code; - return result; - } - - - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - t1_cmap_custom_class_rec = - { - sizeof ( T1_CMapCustomRec ), - - (FT_CMap_InitFunc) t1_cmap_custom_init, - (FT_CMap_DoneFunc) t1_cmap_custom_done, - (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, - (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, - - NULL, NULL, NULL, NULL, NULL - }; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_CALLBACK_DEF( const char * ) - psaux_get_glyph_name( T1_Face face, - FT_UInt idx ) - { - return face->type1.glyph_names[idx]; - } - - - FT_CALLBACK_DEF( FT_Error ) - t1_cmap_unicode_init( PS_Unicodes unicodes ) - { - T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - - - return psnames->unicodes_init( memory, - unicodes, - face->type1.num_glyphs, - (PS_GetGlyphNameFunc)&psaux_get_glyph_name, - (PS_FreeGlyphNameFunc)NULL, - (FT_Pointer)face ); - } - - - FT_CALLBACK_DEF( void ) - t1_cmap_unicode_done( PS_Unicodes unicodes ) - { - FT_Face face = FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); - - - FT_FREE( unicodes->maps ); - unicodes->num_maps = 0; - } - - - FT_CALLBACK_DEF( FT_UInt ) - t1_cmap_unicode_char_index( PS_Unicodes unicodes, - FT_UInt32 char_code ) - { - T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - - - return psnames->unicodes_char_index( unicodes, char_code ); - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - t1_cmap_unicode_char_next( PS_Unicodes unicodes, - FT_UInt32 *pchar_code ) - { - T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - - - return psnames->unicodes_char_next( unicodes, pchar_code ); - } - - - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - t1_cmap_unicode_class_rec = - { - sizeof ( PS_UnicodesRec ), - - (FT_CMap_InitFunc) t1_cmap_unicode_init, - (FT_CMap_DoneFunc) t1_cmap_unicode_done, - (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, - - NULL, NULL, NULL, NULL, NULL - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/t1cmap.h b/drivers/freetype/freetype/src/psaux/t1cmap.h deleted file mode 100644 index 7ae65d2fa1..0000000000 --- a/drivers/freetype/freetype/src/psaux/t1cmap.h +++ /dev/null @@ -1,105 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1cmap.h */ -/* */ -/* Type 1 character map support (specification). */ -/* */ -/* Copyright 2002, 2003, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __T1CMAP_H__ -#define __T1CMAP_H__ - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_TYPE1_TYPES_H - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* standard (and expert) encoding cmaps */ - typedef struct T1_CMapStdRec_* T1_CMapStd; - - typedef struct T1_CMapStdRec_ - { - FT_CMapRec cmap; - - const FT_UShort* code_to_sid; - PS_Adobe_Std_StringsFunc sid_to_string; - - FT_UInt num_glyphs; - const char* const* glyph_names; - - } T1_CMapStdRec; - - - FT_CALLBACK_TABLE const FT_CMap_ClassRec - t1_cmap_standard_class_rec; - - FT_CALLBACK_TABLE const FT_CMap_ClassRec - t1_cmap_expert_class_rec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE1 CUSTOM ENCODING CMAP *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct T1_CMapCustomRec_* T1_CMapCustom; - - typedef struct T1_CMapCustomRec_ - { - FT_CMapRec cmap; - FT_UInt first; - FT_UInt count; - FT_UShort* indices; - - } T1_CMapCustomRec; - - - FT_CALLBACK_TABLE const FT_CMap_ClassRec - t1_cmap_custom_class_rec; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* unicode (synthetic) cmaps */ - - FT_CALLBACK_TABLE const FT_CMap_ClassRec - t1_cmap_unicode_class_rec; - - /* */ - - -FT_END_HEADER - -#endif /* __T1CMAP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/t1decode.c b/drivers/freetype/freetype/src/psaux/t1decode.c deleted file mode 100644 index 6ce370bfaa..0000000000 --- a/drivers/freetype/freetype/src/psaux/t1decode.c +++ /dev/null @@ -1,1620 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1decode.c */ -/* */ -/* PostScript Type 1 decoding routines (body). */ -/* */ -/* Copyright 2000-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H -#include FT_OUTLINE_H - -#include "t1decode.h" -#include "psobjs.h" - -#include "psauxerr.h" - -/* ensure proper sign extension */ -#define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) ) - - /*************************************************************************/ - /* */ - /* 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_t1decode - - - typedef enum T1_Operator_ - { - op_none = 0, - op_endchar, - op_hsbw, - op_seac, - op_sbw, - op_closepath, - op_hlineto, - op_hmoveto, - op_hvcurveto, - op_rlineto, - op_rmoveto, - op_rrcurveto, - op_vhcurveto, - op_vlineto, - op_vmoveto, - op_dotsection, - op_hstem, - op_hstem3, - op_vstem, - op_vstem3, - op_div, - op_callothersubr, - op_callsubr, - op_pop, - op_return, - op_setcurrentpoint, - op_unknown15, - - op_max /* never remove this one */ - - } T1_Operator; - - - static - const FT_Int t1_args_count[op_max] = - { - 0, /* none */ - 0, /* endchar */ - 2, /* hsbw */ - 5, /* seac */ - 4, /* sbw */ - 0, /* closepath */ - 1, /* hlineto */ - 1, /* hmoveto */ - 4, /* hvcurveto */ - 2, /* rlineto */ - 2, /* rmoveto */ - 6, /* rrcurveto */ - 4, /* vhcurveto */ - 1, /* vlineto */ - 1, /* vmoveto */ - 0, /* dotsection */ - 2, /* hstem */ - 6, /* hstem3 */ - 2, /* vstem */ - 6, /* vstem3 */ - 2, /* div */ - -1, /* callothersubr */ - 1, /* callsubr */ - 0, /* pop */ - 0, /* return */ - 2, /* setcurrentpoint */ - 2 /* opcode 15 (undocumented and obsolete) */ - }; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_lookup_glyph_by_stdcharcode */ - /* */ - /* <Description> */ - /* Looks up a given glyph by its StandardEncoding charcode. Used to */ - /* implement the SEAC Type 1 operator. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* <Return> */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ - static FT_Int - t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, - FT_Int charcode ) - { - FT_UInt n; - const FT_String* glyph_name; - FT_Service_PsCMaps psnames = decoder->psnames; - - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - glyph_name = psnames->adobe_std_strings( - psnames->adobe_std_encoding[charcode]); - - for ( n = 0; n < decoder->num_glyphs; n++ ) - { - FT_String* name = (FT_String*)decoder->glyph_names[n]; - - - if ( name && - name[0] == glyph_name[0] && - ft_strcmp( name, glyph_name ) == 0 ) - return n; - } - - return -1; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1operator_seac */ - /* */ - /* <Description> */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* <Input> */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error - t1operator_seac( T1_Decoder decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - FT_Int bchar_index, achar_index; -#if 0 - FT_Int n_base_points; - FT_Outline* base = decoder->builder.base; -#endif - FT_Vector left_bearing, advance; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - T1_Face face = (T1_Face)decoder->builder.face; -#endif - - - if ( decoder->seac ) - { - FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); - return FT_THROW( Syntax_Error ); - } - - if ( decoder->builder.metrics_only ) - { - FT_ERROR(( "t1operator_seac: unexpected seac\n" )); - return FT_THROW( Syntax_Error ); - } - - /* seac weirdness */ - adx += decoder->builder.left_bearing.x; - - /* `glyph_names' is set to 0 for CID fonts which do not */ - /* include an encoding. How can we deal with these? */ -#ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( decoder->glyph_names == 0 && - !face->root.internal->incremental_interface ) -#else - if ( decoder->glyph_names == 0 ) -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - { - FT_ERROR(( "t1operator_seac:" - " glyph names table not available in this font\n" )); - return FT_THROW( Syntax_Error ); - } - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( face->root.internal->incremental_interface ) - { - /* the caller must handle the font encoding also */ - bchar_index = bchar; - achar_index = achar; - } - else -#endif - { - bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); - achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); - } - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "t1operator_seac:" - " invalid seac character code arguments\n" )); - return FT_THROW( Syntax_Error ); - } - - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_GlyphLoader loader = glyph->internal->loader; - FT_SubGlyph subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); - subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->base.subglyphs; - glyph->format = FT_GLYPH_FORMAT_COMPOSITE; - - loader->current.num_subglyphs = 2; - goto Exit; - } - - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - - FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ - - /* the seac operator must not be nested */ - decoder->seac = TRUE; - error = t1_decoder_parse_glyph( decoder, bchar_index ); - decoder->seac = FALSE; - if ( error ) - goto Exit; - - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ - - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; - - decoder->builder.pos_x = adx - asb; - decoder->builder.pos_y = ady; - - /* Now load `achar' on top of */ - /* the base outline */ - - /* the seac operator must not be nested */ - decoder->seac = TRUE; - error = t1_decoder_parse_glyph( decoder, achar_index ); - decoder->seac = FALSE; - if ( error ) - goto Exit; - - /* restore the left side bearing and */ - /* advance width of the base character */ - - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - decoder->builder.pos_x = 0; - decoder->builder.pos_y = 0; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_decoder_parse_charstrings */ - /* */ - /* <Description> */ - /* Parses a given Type 1 charstrings program. */ - /* */ - /* <Input> */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* charstring_base :: The base address of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - t1_decoder_parse_charstrings( T1_Decoder decoder, - FT_Byte* charstring_base, - FT_UInt charstring_len ) - { - FT_Error error; - T1_Decoder_Zone zone; - FT_Byte* ip; - 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; - FT_Bool large_int; - FT_Fixed seed; - - T1_Hints_Funcs hinter; - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_Bool bol = TRUE; -#endif - - - /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ - (FT_PtrDist)(char*)&decoder ^ - (FT_PtrDist)(char*)&charstring_base ) & - FT_ULONG_MAX ) ; - seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; - if ( seed == 0 ) - seed = 0x7384; - - /* First of all, initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - - builder->parse_state = T1_Parse_Start; - - 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->buildchar && decoder->len_buildchar > 0 ) - ft_memset( &decoder->buildchar[0], - 0, - sizeof ( decoder->buildchar[0] ) * decoder->len_buildchar ); - - FT_TRACE4(( "\n" - "Start charstring\n" )); - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = FT_Err_Ok; - - x = orig_x = builder->pos_x; - y = orig_y = builder->pos_y; - - /* begin hints recording session, if any */ - if ( hinter ) - hinter->open( hinter->hints ); - - large_int = FALSE; - - /* now, execute loop */ - while ( ip < limit ) - { - FT_Long* top = decoder->top; - T1_Operator op = op_none; - FT_Int32 value = 0; - - - FT_ASSERT( known_othersubr_result_cnt == 0 || - unknown_othersubr_result_cnt == 0 ); - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( bol ) - { - FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); - bol = FALSE; - } -#endif - - /*********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - /* */ - - /* first of all, decompress operator or value */ - switch ( *ip++ ) - { - case 1: - op = op_hstem; - break; - - case 3: - op = op_vstem; - break; - case 4: - op = op_vmoveto; - break; - case 5: - op = op_rlineto; - break; - case 6: - op = op_hlineto; - break; - case 7: - op = op_vlineto; - break; - case 8: - op = op_rrcurveto; - break; - case 9: - op = op_closepath; - break; - case 10: - op = op_callsubr; - break; - case 11: - op = op_return; - break; - - case 13: - op = op_hsbw; - break; - case 14: - op = op_endchar; - break; - - case 15: /* undocumented, obsolete operator */ - op = op_unknown15; - break; - - case 21: - op = op_rmoveto; - break; - case 22: - op = op_hmoveto; - break; - - case 30: - op = op_vhcurveto; - break; - case 31: - op = op_hvcurveto; - break; - - case 12: - if ( ip > limit ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " invalid escape (12+EOF)\n" )); - goto Syntax_Error; - } - - switch ( *ip++ ) - { - case 0: - op = op_dotsection; - break; - case 1: - op = op_vstem3; - break; - case 2: - op = op_hstem3; - break; - case 6: - op = op_seac; - break; - case 7: - op = op_sbw; - break; - case 12: - op = op_div; - break; - case 16: - op = op_callothersubr; - break; - case 17: - op = op_pop; - break; - case 33: - op = op_setcurrentpoint; - break; - - default: - FT_ERROR(( "t1_decoder_parse_charstrings:" - " invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - break; - - case 255: /* four bytes integer */ - if ( ip + 4 > limit ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | - ( (FT_UInt32)ip[1] << 16 ) | - ( (FT_UInt32)ip[2] << 8 ) | - (FT_UInt32)ip[3] ); - ip += 4; - - /* According to the specification, values > 32000 or < -32000 must */ - /* be followed by a `div' operator to make the result be in the */ - /* range [-32000;32000]. We expect that the second argument of */ - /* `div' is not a large number. Additionally, we don't handle */ - /* stuff like `<large1> <large2> <num> div <num> div' or */ - /* <large1> <large2> <num> div div'. This is probably not allowed */ - /* anyway. */ - if ( value > 32000 || value < -32000 ) - { - if ( large_int ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " no `div' after large integer\n" )); - } - else - large_int = TRUE; - } - else - { - if ( !large_int ) - value = (FT_Int32)( (FT_UInt32)value << 16 ); - } - - break; - - default: - if ( ip[-1] >= 32 ) - { - if ( ip[-1] < 247 ) - value = (FT_Int32)ip[-1] - 139; - else - { - if ( ++ip > limit ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - if ( ip[-2] < 251 ) - value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108; - else - value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 ); - } - - if ( !large_int ) - value = (FT_Int32)( (FT_UInt32)value << 16 ); - } - else - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " invalid byte (%d)\n", ip[-1] )); - goto Syntax_Error; - } - } - - 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; - } - } - - if ( large_int && !( op == op_none || op == op_div ) ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " no `div' after large integer\n" )); - - large_int = FALSE; - } - - /*********************************************************************/ - /* */ - /* Push value on stack, or process operator */ - /* */ - /* */ - if ( op == op_none ) - { - if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) - { - FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); - goto Syntax_Error; - } - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( large_int ) - FT_TRACE4(( " %ld", value )); - else - FT_TRACE4(( " %ld", Fix2Int( value ) )); -#endif - - *top++ = value; - decoder->top = top; - } - else if ( op == op_callothersubr ) /* callothersubr */ - { - FT_Int subr_no; - FT_Int arg_cnt; - - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE4(( " callothersubr\n" )); - bol = TRUE; -#endif - - if ( top - decoder->stack < 2 ) - goto Stack_Underflow; - - top -= 2; - - subr_no = Fix2Int( top[1] ); - arg_cnt = Fix2Int( 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 0: /* end flex feature */ - if ( arg_cnt != 3 ) - goto Unexpected_OtherSubr; - - if ( decoder->flex_state == 0 || - decoder->num_flex_vectors != 7 ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " unexpected flex end\n" )); - goto Syntax_Error; - } - - /* the two `results' are popped by the following setcurrentpoint */ - top[0] = x; - top[1] = y; - known_othersubr_result_cnt = 2; - break; - - case 1: /* start flex feature */ - if ( arg_cnt != 0 ) - goto Unexpected_OtherSubr; - - decoder->flex_state = 1; - decoder->num_flex_vectors = 0; - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 6 ) ) - != FT_Err_Ok ) - goto Fail; - break; - - case 2: /* add flex vectors */ - { - FT_Int idx; - - - if ( arg_cnt != 0 ) - goto Unexpected_OtherSubr; - - if ( decoder->flex_state == 0 ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " missing flex start\n" )); - goto Syntax_Error; - } - - /* note that we should not add a point for index 0; */ - /* this will move our current position to the flex */ - /* point without adding any point to the outline */ - idx = decoder->num_flex_vectors++; - if ( idx > 0 && idx < 7 ) - t1_builder_add_point( builder, - x, - y, - (FT_Byte)( idx == 3 || idx == 6 ) ); - } - break; - - case 3: /* change hints */ - if ( arg_cnt != 1 ) - goto Unexpected_OtherSubr; - - known_othersubr_result_cnt = 1; - - if ( hinter ) - hinter->reset( hinter->hints, builder->current->n_points ); - break; - - case 12: - case 13: - /* counter control hints, clear stack */ - top = decoder->stack; - break; - - case 14: - case 15: - case 16: - case 17: - case 18: /* multiple masters */ - { - PS_Blend blend = decoder->blend; - FT_UInt num_points, nn, mm; - FT_Long* delta; - FT_Long* values; - - - if ( !blend ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " unexpected multiple masters operator\n" )); - goto Syntax_Error; - } - - 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:" - " incorrect number of multiple masters arguments\n" )); - goto Syntax_Error; - } - - /* We want to compute */ - /* */ - /* a0*w0 + a1*w1 + ... + ak*wk */ - /* */ - /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */ - /* */ - /* However, given that w0 + w1 + ... + wk == 1, we can */ - /* rewrite it easily as */ - /* */ - /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */ - /* */ - /* where k == num_designs-1. */ - /* */ - /* I guess that's why it's written in this `compact' */ - /* form. */ - /* */ - delta = top + num_points; - values = top; - for ( nn = 0; nn < num_points; nn++ ) - { - FT_Long tmp = values[0]; - - - for ( mm = 1; mm < blend->num_designs; mm++ ) - tmp += FT_MulFix( *delta++, blend->weight_vector[mm] ); - - *values++ = tmp; - } - - known_othersubr_result_cnt = num_points; - break; - } - - 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 = Fix2Int( top[0] ); - - if ( idx < 0 || - idx + blend->num_designs > decoder->len_buildchar ) - goto Unexpected_OtherSubr; - - ft_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] = FT_MulFix( top[0], top[1] ); - - 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] = FT_DivFix( top[0], top[1] ); - - known_othersubr_result_cnt = 1; - break; - - 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 = Fix2Int( 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 = Fix2Int( 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 which routine has left its 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; - - case 28: - /* 0 28 callothersubr pop */ - /* => push random value from interval [0, 1) onto stack */ - if ( arg_cnt != 0 ) - goto Unexpected_OtherSubr; - - { - FT_Fixed Rand; - - - Rand = seed; - if ( Rand >= 0x8000L ) - Rand++; - - top[0] = Rand; - - seed = FT_MulFix( seed, 0x10000L - seed ); - if ( seed == 0 ) - seed += 0x2873; - } - - known_othersubr_result_cnt = 1; - break; - - default: - if ( arg_cnt >= 0 && subr_no >= 0 ) - { - 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; - } - /* fall through */ - - Unexpected_OtherSubr: - FT_ERROR(( "t1_decoder_parse_charstrings:" - " invalid othersubr [%d %d]\n", arg_cnt, subr_no )); - goto Syntax_Error; - } - - top += known_othersubr_result_cnt; - - decoder->top = top; - } - else /* general operator */ - { - 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(( "t1_decoder_parse_charstrings:" - " too much operands on the stack" - " (seen %d, expected %d)\n", - top - decoder->stack, num_args )); - break; - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - top -= num_args; - - switch ( op ) - { - case op_endchar: - FT_TRACE4(( " endchar\n" )); - - t1_builder_close_contour( builder ); - - /* close hints recording session */ - if ( hinter ) - { - if ( hinter->close( hinter->hints, builder->current->n_points ) ) - goto Syntax_Error; - - /* apply hints to the loaded glyph outline now */ - hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_mode ); - } - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - - /* 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! */ - return FT_Err_Ok; - - case op_hsbw: - FT_TRACE4(( " hsbw" )); - - builder->parse_state = T1_Parse_Have_Width; - - builder->left_bearing.x += top[0]; - builder->advance.x = top[1]; - builder->advance.y = 0; - - orig_x = x = builder->pos_x + top[0]; - orig_y = y = builder->pos_y; - - FT_UNUSED( orig_y ); - - /* the `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it; so exit immediately */ - if ( builder->metrics_only ) - return FT_Err_Ok; - - break; - - case op_seac: - return t1operator_seac( decoder, - top[0], - top[1], - top[2], - Fix2Int( top[3] ), - Fix2Int( top[4] ) ); - - case op_sbw: - FT_TRACE4(( " sbw" )); - - builder->parse_state = T1_Parse_Have_Width; - - builder->left_bearing.x += top[0]; - builder->left_bearing.y += top[1]; - builder->advance.x = top[2]; - builder->advance.y = top[3]; - - x = builder->pos_x + top[0]; - y = builder->pos_y + top[1]; - - /* the `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it; so exit immediately */ - if ( builder->metrics_only ) - return FT_Err_Ok; - - break; - - case op_closepath: - FT_TRACE4(( " closepath" )); - - /* if there is no path, `closepath' is a no-op */ - if ( builder->parse_state == T1_Parse_Have_Path || - builder->parse_state == T1_Parse_Have_Moveto ) - t1_builder_close_contour( builder ); - - builder->parse_state = T1_Parse_Have_Width; - break; - - case op_hlineto: - FT_TRACE4(( " hlineto" )); - - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) - goto Fail; - - x += top[0]; - goto Add_Line; - - case op_hmoveto: - FT_TRACE4(( " hmoveto" )); - - x += top[0]; - if ( !decoder->flex_state ) - { - if ( builder->parse_state == T1_Parse_Start ) - goto Syntax_Error; - builder->parse_state = T1_Parse_Have_Moveto; - } - break; - - case op_hvcurveto: - FT_TRACE4(( " hvcurveto" )); - - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) - goto Fail; - - x += top[0]; - t1_builder_add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; - t1_builder_add_point( builder, x, y, 0 ); - y += top[3]; - t1_builder_add_point( builder, x, y, 1 ); - break; - - case op_rlineto: - FT_TRACE4(( " rlineto" )); - - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) - goto Fail; - - x += top[0]; - y += top[1]; - - Add_Line: - if ( ( error = t1_builder_add_point1( builder, x, y ) ) - != FT_Err_Ok ) - goto Fail; - break; - - case op_rmoveto: - FT_TRACE4(( " rmoveto" )); - - x += top[0]; - y += top[1]; - if ( !decoder->flex_state ) - { - if ( builder->parse_state == T1_Parse_Start ) - goto Syntax_Error; - builder->parse_state = T1_Parse_Have_Moveto; - } - break; - - case op_rrcurveto: - FT_TRACE4(( " rrcurveto" )); - - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) - goto Fail; - - x += top[0]; - y += top[1]; - t1_builder_add_point( builder, x, y, 0 ); - - x += top[2]; - y += top[3]; - t1_builder_add_point( builder, x, y, 0 ); - - x += top[4]; - y += top[5]; - t1_builder_add_point( builder, x, y, 1 ); - break; - - case op_vhcurveto: - FT_TRACE4(( " vhcurveto" )); - - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) - goto Fail; - - y += top[0]; - t1_builder_add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; - t1_builder_add_point( builder, x, y, 0 ); - x += top[3]; - t1_builder_add_point( builder, x, y, 1 ); - break; - - case op_vlineto: - FT_TRACE4(( " vlineto" )); - - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) - goto Fail; - - y += top[0]; - goto Add_Line; - - case op_vmoveto: - FT_TRACE4(( " vmoveto" )); - - y += top[0]; - if ( !decoder->flex_state ) - { - if ( builder->parse_state == T1_Parse_Start ) - goto Syntax_Error; - builder->parse_state = T1_Parse_Have_Moveto; - } - break; - - case op_div: - FT_TRACE4(( " div" )); - - /* if `large_int' is set, we divide unscaled numbers; */ - /* otherwise, we divide numbers in 16.16 format -- */ - /* in both cases, it is the same operation */ - *top = FT_DivFix( top[0], top[1] ); - ++top; - - large_int = FALSE; - break; - - case op_callsubr: - { - FT_Int idx; - - - FT_TRACE4(( " callsubr" )); - - idx = Fix2Int( top[0] ); - if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " invalid subrs index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - - /* The Type 1 driver stores subroutines without the seed bytes. */ - /* The CID driver stores subroutines with seed bytes. This */ - /* case is taken care of when decoder->subrs_len == 0. */ - zone->base = decoder->subrs[idx]; - - if ( decoder->subrs_len ) - zone->limit = zone->base + decoder->subrs_len[idx]; - else - { - /* We are using subroutines from a CID font. We must adjust */ - /* for the seed bytes. */ - zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); - zone->limit = decoder->subrs[idx + 1]; - } - - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " invoking empty subrs\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - break; - } - - case op_pop: - FT_TRACE4(( " pop" )); - - 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: - FT_TRACE4(( " return" )); - - if ( zone <= decoder->zones ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " unexpected return\n" )); - goto Syntax_Error; - } - - zone--; - ip = zone->cursor; - limit = zone->limit; - decoder->zone = zone; - break; - - case op_dotsection: - FT_TRACE4(( " dotsection" )); - - break; - - case op_hstem: - FT_TRACE4(( " hstem" )); - - /* record horizontal hint */ - if ( hinter ) - { - /* top[0] += builder->left_bearing.y; */ - hinter->stem( hinter->hints, 1, top ); - } - break; - - case op_hstem3: - FT_TRACE4(( " hstem3" )); - - /* record horizontal counter-controlled hints */ - if ( hinter ) - hinter->stem3( hinter->hints, 1, top ); - break; - - case op_vstem: - FT_TRACE4(( " vstem" )); - - /* record vertical hint */ - if ( hinter ) - { - top[0] += orig_x; - hinter->stem( hinter->hints, 0, top ); - } - break; - - case op_vstem3: - FT_TRACE4(( " vstem3" )); - - /* record vertical counter-controlled hints */ - if ( hinter ) - { - FT_Pos dx = orig_x; - - - top[0] += dx; - top[2] += dx; - top[4] += dx; - hinter->stem3( hinter->hints, 0, top ); - } - break; - - case op_setcurrentpoint: - FT_TRACE4(( " setcurrentpoint" )); - - /* From the T1 specification, 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. */ - - /* Note, however, that both Ghostscript and Adobe */ - /* Distiller handle this situation by silently ignoring */ - /* the inappropriate `setcurrentpoint' instruction. So */ - /* we do the same. */ -#if 0 - - if ( decoder->flex_state != 1 ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; - } - else - ... -#endif - - x = top[0]; - y = top[1]; - 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:" - " unhandled opcode %d\n", op )); - 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; - -#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE4(( "\n" )); - bol = TRUE; -#endif - - } /* general operator processing */ - - } /* while ip < limit */ - - FT_TRACE4(( "..end..\n\n" )); - - Fail: - return error; - - Syntax_Error: - return FT_THROW( Syntax_Error ); - - Stack_Underflow: - return FT_THROW( Stack_Underflow ); - } - - - /* parse a single Type 1 glyph */ - FT_LOCAL_DEF( FT_Error ) - t1_decoder_parse_glyph( T1_Decoder decoder, - FT_UInt glyph ) - { - return decoder->parse_callback( decoder, glyph ); - } - - - /* initialize T1 decoder */ - FT_LOCAL_DEF( FT_Error ) - t1_decoder_init( T1_Decoder decoder, - FT_Face face, - FT_Size size, - FT_GlyphSlot slot, - FT_Byte** glyph_names, - PS_Blend blend, - FT_Bool hinting, - FT_Render_Mode hint_mode, - T1_Decoder_Callback parse_callback ) - { - FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); - - /* retrieve PSNames interface from list of current modules */ - { - FT_Service_PsCMaps psnames = 0; - - - FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); - if ( !psnames ) - { - FT_ERROR(( "t1_decoder_init:" - " the `psnames' module is not available\n" )); - return FT_THROW( Unimplemented_Feature ); - } - - decoder->psnames = psnames; - } - - 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; - decoder->blend = blend; - decoder->parse_callback = parse_callback; - - decoder->funcs = t1_decoder_funcs; - - return FT_Err_Ok; - } - - - /* finalize T1 decoder */ - FT_LOCAL_DEF( void ) - t1_decoder_done( T1_Decoder decoder ) - { - t1_builder_done( &decoder->builder ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/psaux/t1decode.h b/drivers/freetype/freetype/src/psaux/t1decode.h deleted file mode 100644 index 00728db501..0000000000 --- a/drivers/freetype/freetype/src/psaux/t1decode.h +++ /dev/null @@ -1,64 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1decode.h */ -/* */ -/* PostScript Type 1 decoding routines (specification). */ -/* */ -/* Copyright 2000-2001, 2002, 2003 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 __T1DECODE_H__ -#define __T1DECODE_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_TYPE1_TYPES_H - - -FT_BEGIN_HEADER - - - FT_CALLBACK_TABLE - const T1_Decoder_FuncsRec t1_decoder_funcs; - - - FT_LOCAL( FT_Error ) - t1_decoder_parse_glyph( T1_Decoder decoder, - FT_UInt glyph_index ); - - FT_LOCAL( FT_Error ) - t1_decoder_parse_charstrings( T1_Decoder decoder, - FT_Byte* base, - FT_UInt len ); - - FT_LOCAL( FT_Error ) - t1_decoder_init( T1_Decoder decoder, - FT_Face face, - FT_Size size, - FT_GlyphSlot slot, - FT_Byte** glyph_names, - PS_Blend blend, - FT_Bool hinting, - FT_Render_Mode hint_mode, - T1_Decoder_Callback parse_glyph ); - - FT_LOCAL( void ) - t1_decoder_done( T1_Decoder decoder ); - - -FT_END_HEADER - -#endif /* __T1DECODE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/Jamfile b/drivers/freetype/freetype/src/pshinter/Jamfile deleted file mode 100644 index 779f1b0b82..0000000000 --- a/drivers/freetype/freetype/src/pshinter/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/pshinter Jamfile -# -# Copyright 2001, 2003 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = pshrec pshglob pshalgo pshmod pshpic ; - } - else - { - _sources = pshinter ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/pshinter Jamfile diff --git a/drivers/freetype/freetype/src/pshinter/module.mk b/drivers/freetype/freetype/src/pshinter/module.mk deleted file mode 100644 index ed24eb7fa8..0000000000 --- a/drivers/freetype/freetype/src/pshinter/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 PSHinter module definition -# - - -# Copyright 1996-2001, 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. - - -FTMODULE_H_COMMANDS += PSHINTER_MODULE - -define PSHINTER_MODULE -$(OPEN_DRIVER) FT_Module_Class, pshinter_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)pshinter $(ECHO_DRIVER_DESC)Postscript hinter module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/pshinter/pshalgo.c b/drivers/freetype/freetype/src/pshinter/pshalgo.c deleted file mode 100644 index 343472ddb3..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshalgo.c +++ /dev/null @@ -1,2305 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshalgo.c */ -/* */ -/* PostScript hinting algorithm (body). */ -/* */ -/* Copyright 2001-2010, 2012, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used */ -/* modified and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H -#include "pshalgo.h" - -#include "pshnterr.h" - - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pshalgo2 - - -#ifdef DEBUG_HINTER - PSH_Hint_Table ps_debug_hint_table = 0; - PSH_HintFunc ps_debug_hint_func = 0; - PSH_Glyph ps_debug_glyph = 0; -#endif - - -#define COMPUTE_INFLEXS /* compute inflection points to optimize `S' */ - /* and similar glyphs */ -#define STRONGER /* slightly increase the contrast of smooth */ - /* hinting */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** BASIC HINTS RECORDINGS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* return true if two stem hints overlap */ - static FT_Int - psh_hint_overlap( PSH_Hint hint1, - PSH_Hint hint2 ) - { - return hint1->org_pos + hint1->org_len >= hint2->org_pos && - hint2->org_pos + hint2->org_len >= hint1->org_pos; - } - - - /* destroy hints table */ - static void - psh_hint_table_done( PSH_Hint_Table table, - FT_Memory memory ) - { - FT_FREE( table->zones ); - table->num_zones = 0; - table->zone = 0; - - FT_FREE( table->sort ); - FT_FREE( table->hints ); - table->num_hints = 0; - table->max_hints = 0; - table->sort_global = 0; - } - - - /* deactivate all hints in a table */ - static void - psh_hint_table_deactivate( PSH_Hint_Table table ) - { - FT_UInt count = table->max_hints; - PSH_Hint hint = table->hints; - - - for ( ; count > 0; count--, hint++ ) - { - psh_hint_deactivate( hint ); - hint->order = -1; - } - } - - - /* internal function to record a new hint */ - static void - psh_hint_table_record( PSH_Hint_Table table, - FT_UInt idx ) - { - PSH_Hint hint = table->hints + idx; - - - if ( idx >= table->max_hints ) - { - FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx )); - return; - } - - /* ignore active hints */ - if ( psh_hint_is_active( hint ) ) - return; - - psh_hint_activate( hint ); - - /* now scan the current active hint set to check */ - /* whether `hint' overlaps with another hint */ - { - PSH_Hint* sorted = table->sort_global; - FT_UInt count = table->num_hints; - PSH_Hint hint2; - - - hint->parent = 0; - for ( ; count > 0; count--, sorted++ ) - { - hint2 = sorted[0]; - - if ( psh_hint_overlap( hint, hint2 ) ) - { - hint->parent = hint2; - break; - } - } - } - - if ( table->num_hints < table->max_hints ) - table->sort_global[table->num_hints++] = hint; - else - FT_TRACE0(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); - } - - - static void - psh_hint_table_record_mask( PSH_Hint_Table table, - PS_Mask hint_mask ) - { - FT_Int mask = 0, val = 0; - FT_Byte* cursor = hint_mask->bytes; - FT_UInt idx, limit; - - - limit = hint_mask->num_bits; - - for ( idx = 0; idx < limit; idx++ ) - { - if ( mask == 0 ) - { - val = *cursor++; - mask = 0x80; - } - - if ( val & mask ) - psh_hint_table_record( table, idx ); - - mask >>= 1; - } - } - - - /* create hints table */ - static FT_Error - psh_hint_table_init( PSH_Hint_Table table, - PS_Hint_Table hints, - PS_Mask_Table hint_masks, - PS_Mask_Table counter_masks, - FT_Memory memory ) - { - FT_UInt count; - FT_Error error; - - FT_UNUSED( counter_masks ); - - - count = hints->num_hints; - - /* allocate our tables */ - if ( FT_NEW_ARRAY( table->sort, 2 * count ) || - FT_NEW_ARRAY( table->hints, count ) || - FT_NEW_ARRAY( table->zones, 2 * count + 1 ) ) - goto Exit; - - table->max_hints = count; - table->sort_global = table->sort + count; - table->num_hints = 0; - table->num_zones = 0; - table->zone = 0; - - /* initialize the `table->hints' array */ - { - PSH_Hint write = table->hints; - PS_Hint read = hints->hints; - - - for ( ; count > 0; count--, write++, read++ ) - { - write->org_pos = read->pos; - write->org_len = read->len; - write->flags = read->flags; - } - } - - /* we now need to determine the initial `parent' stems; first */ - /* activate the hints that are given by the initial hint masks */ - if ( hint_masks ) - { - PS_Mask mask = hint_masks->masks; - - - count = hint_masks->num_masks; - table->hint_masks = hint_masks; - - for ( ; count > 0; count--, mask++ ) - psh_hint_table_record_mask( table, mask ); - } - - /* finally, do a linear parse in case some hints were left alone */ - if ( table->num_hints != table->max_hints ) - { - FT_UInt idx; - - - FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" )); - - count = table->max_hints; - for ( idx = 0; idx < count; idx++ ) - psh_hint_table_record( table, idx ); - } - - Exit: - return error; - } - - - static void - psh_hint_table_activate_mask( PSH_Hint_Table table, - PS_Mask hint_mask ) - { - FT_Int mask = 0, val = 0; - FT_Byte* cursor = hint_mask->bytes; - FT_UInt idx, limit, count; - - - limit = hint_mask->num_bits; - count = 0; - - psh_hint_table_deactivate( table ); - - for ( idx = 0; idx < limit; idx++ ) - { - if ( mask == 0 ) - { - val = *cursor++; - mask = 0x80; - } - - if ( val & mask ) - { - PSH_Hint hint = &table->hints[idx]; - - - if ( !psh_hint_is_active( hint ) ) - { - FT_UInt count2; - -#if 0 - PSH_Hint* sort = table->sort; - PSH_Hint hint2; - - - for ( count2 = count; count2 > 0; count2--, sort++ ) - { - hint2 = sort[0]; - if ( psh_hint_overlap( hint, hint2 ) ) - FT_TRACE0(( "psh_hint_table_activate_mask:" - " found overlapping hints\n" )) - } -#else - count2 = 0; -#endif - - if ( count2 == 0 ) - { - psh_hint_activate( hint ); - if ( count < table->max_hints ) - table->sort[count++] = hint; - else - FT_TRACE0(( "psh_hint_tableactivate_mask:" - " too many active hints\n" )); - } - } - } - - mask >>= 1; - } - table->num_hints = count; - - /* now, sort the hints; they are guaranteed to not overlap */ - /* so we can compare their "org_pos" field directly */ - { - FT_Int i1, i2; - PSH_Hint hint1, hint2; - PSH_Hint* sort = table->sort; - - - /* a simple bubble sort will do, since in 99% of cases, the hints */ - /* will be already sorted -- and the sort will be linear */ - for ( i1 = 1; i1 < (FT_Int)count; i1++ ) - { - hint1 = sort[i1]; - for ( i2 = i1 - 1; i2 >= 0; i2-- ) - { - hint2 = sort[i2]; - - if ( hint2->org_pos < hint1->org_pos ) - break; - - sort[i2 + 1] = hint2; - sort[i2] = hint1; - } - } - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#if 1 - static FT_Pos - psh_dimension_quantize_len( PSH_Dimension dim, - FT_Pos len, - FT_Bool do_snapping ) - { - if ( len <= 64 ) - len = 64; - else - { - FT_Pos delta = len - dim->stdw.widths[0].cur; - - - if ( delta < 0 ) - delta = -delta; - - if ( delta < 40 ) - { - len = dim->stdw.widths[0].cur; - if ( len < 48 ) - len = 48; - } - - if ( len < 3 * 64 ) - { - delta = ( len & 63 ); - len &= -64; - - if ( delta < 10 ) - len += delta; - - else if ( delta < 32 ) - len += 10; - - else if ( delta < 54 ) - len += 54; - - else - len += delta; - } - else - len = FT_PIX_ROUND( len ); - } - - if ( do_snapping ) - len = FT_PIX_ROUND( len ); - - return len; - } -#endif /* 0 */ - - -#ifdef DEBUG_HINTER - - static void - ps_simple_scale( PSH_Hint_Table table, - FT_Fixed scale, - FT_Fixed delta, - FT_Int dimension ) - { - FT_UInt count; - - - for ( count = 0; count < table->max_hints; count++ ) - { - PSH_Hint hint = table->hints + count; - - - hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; - hint->cur_len = FT_MulFix( hint->org_len, scale ); - - if ( ps_debug_hint_func ) - ps_debug_hint_func( hint, dimension ); - } - } - -#endif /* DEBUG_HINTER */ - - - static FT_Fixed - psh_hint_snap_stem_side_delta( FT_Fixed pos, - FT_Fixed len ) - { - FT_Fixed delta1 = FT_PIX_ROUND( pos ) - pos; - FT_Fixed delta2 = FT_PIX_ROUND( pos + len ) - pos - len; - - - if ( FT_ABS( delta1 ) <= FT_ABS( delta2 ) ) - return delta1; - else - return delta2; - } - - - static void - psh_hint_align( PSH_Hint hint, - PSH_Globals globals, - FT_Int dimension, - PSH_Glyph glyph ) - { - PSH_Dimension dim = &globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - - - if ( !psh_hint_is_fitted( hint ) ) - { - FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; - FT_Pos len = FT_MulFix( hint->org_len, scale ); - - FT_Int do_snapping; - FT_Pos fit_len; - PSH_AlignmentRec align; - - - /* ignore stem alignments when requested through the hint flags */ - if ( ( dimension == 0 && !glyph->do_horz_hints ) || - ( dimension == 1 && !glyph->do_vert_hints ) ) - { - hint->cur_pos = pos; - hint->cur_len = len; - - psh_hint_set_fitted( hint ); - return; - } - - /* perform stem snapping when requested - this is necessary - * for monochrome and LCD hinting modes only - */ - do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) || - ( dimension == 1 && glyph->do_vert_snapping ); - - hint->cur_len = fit_len = len; - - /* check blue zones for horizontal stems */ - align.align = PSH_BLUE_ALIGN_NONE; - align.align_bot = align.align_top = 0; - - if ( dimension == 1 ) - psh_blues_snap_stem( &globals->blues, - hint->org_pos + hint->org_len, - hint->org_pos, - &align ); - - switch ( align.align ) - { - case PSH_BLUE_ALIGN_TOP: - /* the top of the stem is aligned against a blue zone */ - hint->cur_pos = align.align_top - fit_len; - break; - - case PSH_BLUE_ALIGN_BOT: - /* the bottom of the stem is aligned against a blue zone */ - hint->cur_pos = align.align_bot; - break; - - case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: - /* both edges of the stem are aligned against blue zones */ - hint->cur_pos = align.align_bot; - hint->cur_len = align.align_top - align.align_bot; - break; - - default: - { - PSH_Hint parent = hint->parent; - - - if ( parent ) - { - FT_Pos par_org_center, par_cur_center; - FT_Pos cur_org_center, cur_delta; - - - /* ensure that parent is already fitted */ - if ( !psh_hint_is_fitted( parent ) ) - psh_hint_align( parent, globals, dimension, glyph ); - - /* keep original relation between hints, this is, use the */ - /* scaled distance between the centers of the hints to */ - /* compute the new position */ - par_org_center = parent->org_pos + ( parent->org_len >> 1 ); - par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 ); - cur_org_center = hint->org_pos + ( hint->org_len >> 1 ); - - cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); - pos = par_cur_center + cur_delta - ( len >> 1 ); - } - - hint->cur_pos = pos; - hint->cur_len = fit_len; - - /* Stem adjustment tries to snap stem widths to standard - * ones. This is important to prevent unpleasant rounding - * artefacts. - */ - if ( glyph->do_stem_adjust ) - { - if ( len <= 64 ) - { - /* the stem is less than one pixel; we will center it - * around the nearest pixel center - */ - if ( len >= 32 ) - { - /* This is a special case where we also widen the stem - * and align it to the pixel grid. - * - * stem_center = pos + (len/2) - * nearest_pixel_center = FT_ROUND(stem_center-32)+32 - * new_pos = nearest_pixel_center-32 - * = FT_ROUND(stem_center-32) - * = FT_FLOOR(stem_center-32+32) - * = FT_FLOOR(stem_center) - * new_len = 64 - */ - pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ); - len = 64; - } - else if ( len > 0 ) - { - /* This is a very small stem; we simply align it to the - * pixel grid, trying to find the minimum displacement. - * - * left = pos - * right = pos + len - * left_nearest_edge = ROUND(pos) - * right_nearest_edge = ROUND(right) - * - * if ( ABS(left_nearest_edge - left) <= - * ABS(right_nearest_edge - right) ) - * new_pos = left - * else - * new_pos = right - */ - FT_Pos left_nearest = FT_PIX_ROUND( pos ); - FT_Pos right_nearest = FT_PIX_ROUND( pos + len ); - FT_Pos left_disp = left_nearest - pos; - FT_Pos right_disp = right_nearest - ( pos + len ); - - - if ( left_disp < 0 ) - left_disp = -left_disp; - if ( right_disp < 0 ) - right_disp = -right_disp; - if ( left_disp <= right_disp ) - pos = left_nearest; - else - pos = right_nearest; - } - else - { - /* this is a ghost stem; we simply round it */ - pos = FT_PIX_ROUND( pos ); - } - } - else - { - len = psh_dimension_quantize_len( dim, len, 0 ); - } - } - - /* now that we have a good hinted stem width, try to position */ - /* the stem along a pixel grid integer coordinate */ - hint->cur_pos = pos + psh_hint_snap_stem_side_delta( pos, len ); - hint->cur_len = len; - } - } - - if ( do_snapping ) - { - pos = hint->cur_pos; - len = hint->cur_len; - - if ( len < 64 ) - len = 64; - else - len = FT_PIX_ROUND( len ); - - switch ( align.align ) - { - case PSH_BLUE_ALIGN_TOP: - hint->cur_pos = align.align_top - len; - hint->cur_len = len; - break; - - case PSH_BLUE_ALIGN_BOT: - hint->cur_len = len; - break; - - case PSH_BLUE_ALIGN_BOT | PSH_BLUE_ALIGN_TOP: - /* don't touch */ - break; - - - default: - hint->cur_len = len; - if ( len & 64 ) - pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ) + 32; - else - pos = FT_PIX_ROUND( pos + ( len >> 1 ) ); - - hint->cur_pos = pos - ( len >> 1 ); - hint->cur_len = len; - } - } - - psh_hint_set_fitted( hint ); - -#ifdef DEBUG_HINTER - if ( ps_debug_hint_func ) - ps_debug_hint_func( hint, dimension ); -#endif - } - } - - -#if 0 /* not used for now, experimental */ - - /* - * A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT) - * of stems - */ - static void - psh_hint_align_light( PSH_Hint hint, - PSH_Globals globals, - FT_Int dimension, - PSH_Glyph glyph ) - { - PSH_Dimension dim = &globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - - - if ( !psh_hint_is_fitted( hint ) ) - { - FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; - FT_Pos len = FT_MulFix( hint->org_len, scale ); - - FT_Pos fit_len; - - PSH_AlignmentRec align; - - - /* ignore stem alignments when requested through the hint flags */ - if ( ( dimension == 0 && !glyph->do_horz_hints ) || - ( dimension == 1 && !glyph->do_vert_hints ) ) - { - hint->cur_pos = pos; - hint->cur_len = len; - - psh_hint_set_fitted( hint ); - return; - } - - fit_len = len; - - hint->cur_len = fit_len; - - /* check blue zones for horizontal stems */ - align.align = PSH_BLUE_ALIGN_NONE; - align.align_bot = align.align_top = 0; - - if ( dimension == 1 ) - psh_blues_snap_stem( &globals->blues, - hint->org_pos + hint->org_len, - hint->org_pos, - &align ); - - switch ( align.align ) - { - case PSH_BLUE_ALIGN_TOP: - /* the top of the stem is aligned against a blue zone */ - hint->cur_pos = align.align_top - fit_len; - break; - - case PSH_BLUE_ALIGN_BOT: - /* the bottom of the stem is aligned against a blue zone */ - hint->cur_pos = align.align_bot; - break; - - case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: - /* both edges of the stem are aligned against blue zones */ - hint->cur_pos = align.align_bot; - hint->cur_len = align.align_top - align.align_bot; - break; - - default: - { - PSH_Hint parent = hint->parent; - - - if ( parent ) - { - FT_Pos par_org_center, par_cur_center; - FT_Pos cur_org_center, cur_delta; - - - /* ensure that parent is already fitted */ - if ( !psh_hint_is_fitted( parent ) ) - psh_hint_align_light( parent, globals, dimension, glyph ); - - par_org_center = parent->org_pos + ( parent->org_len / 2 ); - par_cur_center = parent->cur_pos + ( parent->cur_len / 2 ); - cur_org_center = hint->org_pos + ( hint->org_len / 2 ); - - cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); - pos = par_cur_center + cur_delta - ( len >> 1 ); - } - - /* Stems less than one pixel wide are easy -- we want to - * make them as dark as possible, so they must fall within - * one pixel. If the stem is split between two pixels - * then snap the edge that is nearer to the pixel boundary - * to the pixel boundary. - */ - if ( len <= 64 ) - { - if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 ) - pos += psh_hint_snap_stem_side_delta ( pos, len ); - } - - /* Position stems other to minimize the amount of mid-grays. - * There are, in general, two positions that do this, - * illustrated as A) and B) below. - * - * + + + + - * - * A) |--------------------------------| - * B) |--------------------------------| - * C) |--------------------------------| - * - * Position A) (split the excess stem equally) should be better - * for stems of width N + f where f < 0.5. - * - * Position B) (split the deficiency equally) should be better - * for stems of width N + f where f > 0.5. - * - * It turns out though that minimizing the total number of lit - * pixels is also important, so position C), with one edge - * aligned with a pixel boundary is actually preferable - * to A). There are also more possibile positions for C) than - * for A) or B), so it involves less distortion of the overall - * character shape. - */ - else /* len > 64 */ - { - FT_Fixed frac_len = len & 63; - FT_Fixed center = pos + ( len >> 1 ); - FT_Fixed delta_a, delta_b; - - - if ( ( len / 64 ) & 1 ) - { - delta_a = FT_PIX_FLOOR( center ) + 32 - center; - delta_b = FT_PIX_ROUND( center ) - center; - } - else - { - delta_a = FT_PIX_ROUND( center ) - center; - delta_b = FT_PIX_FLOOR( center ) + 32 - center; - } - - /* We choose between B) and C) above based on the amount - * of fractinal stem width; for small amounts, choose - * C) always, for large amounts, B) always, and inbetween, - * pick whichever one involves less stem movement. - */ - if ( frac_len < 32 ) - { - pos += psh_hint_snap_stem_side_delta ( pos, len ); - } - else if ( frac_len < 48 ) - { - FT_Fixed side_delta = psh_hint_snap_stem_side_delta ( pos, - len ); - - if ( FT_ABS( side_delta ) < FT_ABS( delta_b ) ) - pos += side_delta; - else - pos += delta_b; - } - else - { - pos += delta_b; - } - } - - hint->cur_pos = pos; - } - } /* switch */ - - psh_hint_set_fitted( hint ); - -#ifdef DEBUG_HINTER - if ( ps_debug_hint_func ) - ps_debug_hint_func( hint, dimension ); -#endif - } - } - -#endif /* 0 */ - - - static void - psh_hint_table_align_hints( PSH_Hint_Table table, - PSH_Globals globals, - FT_Int dimension, - PSH_Glyph glyph ) - { - PSH_Hint hint; - FT_UInt count; - -#ifdef DEBUG_HINTER - - PSH_Dimension dim = &globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - - - if ( ps_debug_no_vert_hints && dimension == 0 ) - { - ps_simple_scale( table, scale, delta, dimension ); - return; - } - - if ( ps_debug_no_horz_hints && dimension == 1 ) - { - ps_simple_scale( table, scale, delta, dimension ); - return; - } - -#endif /* DEBUG_HINTER*/ - - hint = table->hints; - count = table->max_hints; - - for ( ; count > 0; count--, hint++ ) - psh_hint_align( hint, globals, dimension, glyph ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** POINTS INTERPOLATION ROUTINES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define PSH_ZONE_MIN -3200000L -#define PSH_ZONE_MAX +3200000L - -#define xxDEBUG_ZONES - - -#ifdef DEBUG_ZONES - -#include FT_CONFIG_STANDARD_LIBRARY_H - - static void - psh_print_zone( PSH_Zone zone ) - { - printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", - zone->scale / 65536.0, - zone->delta / 64.0, - zone->min, - zone->max ); - } - -#else - -#define psh_print_zone( x ) do { } while ( 0 ) - -#endif /* DEBUG_ZONES */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** HINTER GLYPH MANAGEMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#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 */ - static void - psh_glyph_compute_inflections( PSH_Glyph glyph ) - { - FT_UInt n; - - - for ( n = 0; n < glyph->num_contours; n++ ) - { - PSH_Point first, start, end, before, after; - FT_Pos in_x, in_y, out_x, out_y; - FT_Int orient_prev, orient_cur; - FT_Int finished = 0; - - - /* we need at least 4 points to create an inflection point */ - if ( glyph->contours[n].count < 4 ) - continue; - - /* compute first segment in contour */ - first = glyph->contours[n].start; - - start = end = first; - do - { - end = end->next; - if ( end == first ) - goto Skip; - - in_x = end->org_u - start->org_u; - in_y = end->org_v - start->org_v; - - } 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->org_u - before->org_u; - out_y = start->org_v - before->org_v; - - } while ( out_x == 0 && out_y == 0 ); - - orient_prev = psh_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->org_u - end->org_u; - out_y = after->org_v - end->org_v; - - } while ( out_x == 0 && out_y == 0 ); - - orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y ); - - } while ( orient_cur == 0 ); - - if ( ( orient_cur ^ orient_prev ) < 0 ) - { - do - { - psh_point_set_inflex( start ); - start = start->next; - } - while ( start != end ); - - psh_point_set_inflex( start ); - } - - start = end; - end = after; - orient_prev = orient_cur; - in_x = out_x; - in_y = out_y; - - } while ( !finished ); - - Skip: - ; - } - } - -#endif /* COMPUTE_INFLEXS */ - - - static void - psh_glyph_done( PSH_Glyph glyph ) - { - FT_Memory memory = glyph->memory; - - - psh_hint_table_done( &glyph->hint_tables[1], memory ); - psh_hint_table_done( &glyph->hint_tables[0], memory ); - - FT_FREE( glyph->points ); - FT_FREE( glyph->contours ); - - glyph->num_points = 0; - glyph->num_contours = 0; - - glyph->memory = 0; - } - - - static int - psh_compute_dir( FT_Pos dx, - FT_Pos dy ) - { - FT_Pos ax, ay; - int result = PSH_DIR_NONE; - - - ax = FT_ABS( dx ); - ay = FT_ABS( dy ); - - if ( ay * 12 < ax ) - { - /* |dy| <<< |dx| means a near-horizontal segment */ - result = ( dx >= 0 ) ? PSH_DIR_RIGHT : PSH_DIR_LEFT; - } - else if ( ax * 12 < ay ) - { - /* |dx| <<< |dy| means a near-vertical segment */ - result = ( dy >= 0 ) ? PSH_DIR_UP : PSH_DIR_DOWN; - } - - return result; - } - - - /* load outline point coordinates into hinter glyph */ - static void - psh_glyph_load_points( PSH_Glyph glyph, - FT_Int dimension ) - { - FT_Vector* vec = glyph->outline->points; - PSH_Point point = glyph->points; - FT_UInt count = glyph->num_points; - - - for ( ; count > 0; count--, point++, vec++ ) - { - point->flags2 = 0; - point->hint = NULL; - if ( dimension == 0 ) - { - point->org_u = vec->x; - point->org_v = vec->y; - } - else - { - point->org_u = vec->y; - point->org_v = vec->x; - } - -#ifdef DEBUG_HINTER - point->org_x = vec->x; - point->org_y = vec->y; -#endif - - } - } - - - /* save hinted point coordinates back to outline */ - static void - psh_glyph_save_points( PSH_Glyph glyph, - FT_Int dimension ) - { - FT_UInt n; - PSH_Point point = glyph->points; - FT_Vector* vec = glyph->outline->points; - char* tags = glyph->outline->tags; - - - for ( n = 0; n < glyph->num_points; n++ ) - { - if ( dimension == 0 ) - vec[n].x = point->cur_u; - else - vec[n].y = point->cur_u; - - if ( psh_point_is_strong( point ) ) - tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 ); - -#ifdef DEBUG_HINTER - - if ( dimension == 0 ) - { - point->cur_x = point->cur_u; - point->flags_x = point->flags2 | point->flags; - } - else - { - point->cur_y = point->cur_u; - point->flags_y = point->flags2 | point->flags; - } - -#endif - - point++; - } - } - - - static FT_Error - psh_glyph_init( PSH_Glyph glyph, - FT_Outline* outline, - PS_Hints ps_hints, - PSH_Globals globals ) - { - FT_Error error; - FT_Memory memory; - - - /* clear all fields */ - FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); - - memory = glyph->memory = globals->memory; - - /* allocate and setup points + contours arrays */ - if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) || - FT_NEW_ARRAY( glyph->contours, outline->n_contours ) ) - goto Exit; - - glyph->num_points = outline->n_points; - glyph->num_contours = outline->n_contours; - - { - FT_UInt first = 0, next, n; - PSH_Point points = glyph->points; - PSH_Contour contour = glyph->contours; - - - for ( n = 0; n < glyph->num_contours; n++ ) - { - FT_Int count; - PSH_Point point; - - - next = outline->contours[n] + 1; - count = next - first; - - contour->start = points + first; - contour->count = (FT_UInt)count; - - if ( count > 0 ) - { - point = points + first; - - point->prev = points + next - 1; - point->contour = contour; - - for ( ; count > 1; count-- ) - { - point[0].next = point + 1; - point[1].prev = point; - point++; - point->contour = contour; - } - point->next = points + first; - } - - contour++; - first = next; - } - } - - { - PSH_Point points = glyph->points; - PSH_Point point = points; - FT_Vector* vec = outline->points; - FT_UInt n; - - - for ( n = 0; n < glyph->num_points; n++, point++ ) - { - FT_Int n_prev = (FT_Int)( point->prev - points ); - FT_Int n_next = (FT_Int)( point->next - points ); - FT_Pos dxi, dyi, dxo, dyo; - - - if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) ) - point->flags = PSH_POINT_OFF; - - dxi = vec[n].x - vec[n_prev].x; - dyi = vec[n].y - vec[n_prev].y; - - point->dir_in = (FT_Char)psh_compute_dir( dxi, dyi ); - - dxo = vec[n_next].x - vec[n].x; - dyo = vec[n_next].y - vec[n].y; - - point->dir_out = (FT_Char)psh_compute_dir( dxo, dyo ); - - /* detect smooth points */ - if ( point->flags & PSH_POINT_OFF ) - point->flags |= PSH_POINT_SMOOTH; - - else if ( point->dir_in == point->dir_out ) - { - if ( point->dir_out != PSH_DIR_NONE || - psh_corner_is_flat( dxi, dyi, dxo, dyo ) ) - point->flags |= PSH_POINT_SMOOTH; - } - } - } - - glyph->outline = outline; - glyph->globals = globals; - -#ifdef COMPUTE_INFLEXS - psh_glyph_load_points( glyph, 0 ); - psh_glyph_compute_inflections( glyph ); -#endif /* COMPUTE_INFLEXS */ - - /* now deal with hints tables */ - error = psh_hint_table_init( &glyph->hint_tables [0], - &ps_hints->dimension[0].hints, - &ps_hints->dimension[0].masks, - &ps_hints->dimension[0].counters, - memory ); - if ( error ) - goto Exit; - - error = psh_hint_table_init( &glyph->hint_tables [1], - &ps_hints->dimension[1].hints, - &ps_hints->dimension[1].masks, - &ps_hints->dimension[1].counters, - memory ); - if ( error ) - goto Exit; - - Exit: - return error; - } - - - /* compute all extrema in a glyph for a given dimension */ - static void - psh_glyph_compute_extrema( PSH_Glyph glyph ) - { - FT_UInt n; - - - /* first of all, compute all local extrema */ - for ( n = 0; n < glyph->num_contours; n++ ) - { - PSH_Point first = glyph->contours[n].start; - PSH_Point point, before, after; - - - if ( glyph->contours[n].count == 0 ) - continue; - - point = first; - before = point; - after = point; - - do - { - before = before->prev; - if ( before == first ) - goto Skip; - - } while ( before->org_u == point->org_u ); - - first = point = before->next; - - for (;;) - { - after = point; - do - { - after = after->next; - if ( after == first ) - goto Next; - - } while ( after->org_u == point->org_u ); - - if ( before->org_u < point->org_u ) - { - if ( after->org_u < point->org_u ) - { - /* local maximum */ - goto Extremum; - } - } - else /* before->org_u > point->org_u */ - { - if ( after->org_u > point->org_u ) - { - /* local minimum */ - Extremum: - do - { - psh_point_set_extremum( point ); - point = point->next; - - } while ( point != after ); - } - } - - before = after->prev; - point = after; - - } /* for */ - - Next: - ; - } - - /* for each extremum, determine its direction along the */ - /* orthogonal axis */ - for ( n = 0; n < glyph->num_points; n++ ) - { - PSH_Point point, before, after; - - - point = &glyph->points[n]; - before = point; - after = point; - - if ( psh_point_is_extremum( point ) ) - { - do - { - before = before->prev; - if ( before == point ) - goto Skip; - - } while ( before->org_v == point->org_v ); - - do - { - after = after->next; - if ( after == point ) - goto Skip; - - } while ( after->org_v == point->org_v ); - } - - if ( before->org_v < point->org_v && - after->org_v > point->org_v ) - { - psh_point_set_positive( point ); - } - else if ( before->org_v > point->org_v && - after->org_v < point->org_v ) - { - psh_point_set_negative( point ); - } - - Skip: - ; - } - } - - - /* major_dir is the direction for points on the bottom/left of the stem; */ - /* Points on the top/right of the stem will have a direction of */ - /* -major_dir. */ - - static void - 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; - - - for ( ; count > 0; count--, point++ ) - { - FT_Int point_dir = 0; - FT_Pos org_u = point->org_u; - - - 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 ) - { - if ( point_dir == major_dir ) - { - FT_UInt nn; - - - for ( nn = 0; nn < num_hints; nn++ ) - { - 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 ) - { - FT_UInt nn; - - - 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 nn, min_flag, max_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 ) - { - for ( nn = 0; nn < num_hints; nn++ ) - { - 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 ) - { - 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 ) - { - point->flags2 |= PSH_POINT_EDGE_MAX; - point->hint = hint; - psh_point_set_strong( point ); - break; - } - } - } - - if ( point->hint == NULL ) - { - 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 */ - } - } - - - /* the accepted shift for strong points in fractional pixels */ -#define PSH_STRONG_THRESHOLD 32 - - /* the maximum shift value in font units */ -#define PSH_STRONG_THRESHOLD_MAXIMUM 30 - - - /* find strong points in a glyph */ - static void - psh_glyph_find_strong_points( PSH_Glyph glyph, - FT_Int dimension ) - { - /* a point is `strong' if it is located on a stem edge and */ - /* has an `in' or `out' tangent parallel to the hint's direction */ - - PSH_Hint_Table table = &glyph->hint_tables[dimension]; - PS_Mask mask = table->hint_masks->masks; - FT_UInt num_masks = table->hint_masks->num_masks; - FT_UInt first = 0; - FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL - : PSH_DIR_HORIZONTAL; - PSH_Dimension dim = &glyph->globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Int threshold; - - - threshold = (FT_Int)FT_DivFix( PSH_STRONG_THRESHOLD, scale ); - if ( threshold > PSH_STRONG_THRESHOLD_MAXIMUM ) - threshold = PSH_STRONG_THRESHOLD_MAXIMUM; - - /* process secondary hints to `selected' points */ - if ( num_masks > 1 && glyph->num_points > 0 ) - { - /* the `endchar' op can reduce the number of points */ - first = mask->end_point > glyph->num_points - ? glyph->num_points - : mask->end_point; - mask++; - for ( ; num_masks > 1; num_masks--, mask++ ) - { - FT_UInt next; - FT_Int count; - - - next = mask->end_point > glyph->num_points - ? glyph->num_points - : mask->end_point; - count = next - first; - if ( count > 0 ) - { - PSH_Point point = glyph->points + first; - - - psh_hint_table_activate_mask( table, mask ); - - psh_hint_table_find_strong_points( table, point, count, - threshold, major_dir ); - } - first = next; - } - } - - /* process primary hints for all points */ - if ( num_masks == 1 ) - { - FT_UInt count = glyph->num_points; - PSH_Point point = glyph->points; - - - psh_hint_table_activate_mask( table, table->hint_masks->masks ); - - psh_hint_table_find_strong_points( table, point, count, - threshold, major_dir ); - } - - /* now, certain points may have been attached to a hint and */ - /* not marked as strong; update their flags then */ - { - FT_UInt count = glyph->num_points; - PSH_Point point = glyph->points; - - - for ( ; count > 0; count--, point++ ) - if ( point->hint && !psh_point_is_strong( point ) ) - psh_point_set_strong( point ); - } - } - - - /* find points in a glyph which are in a blue zone and have `in' or */ - /* `out' tangents parallel to the horizontal axis */ - static void - psh_glyph_find_blue_points( PSH_Blues blues, - PSH_Glyph glyph ) - { - PSH_Blue_Table table; - PSH_Blue_Zone zone; - FT_UInt glyph_count = glyph->num_points; - FT_UInt blue_count; - PSH_Point point = glyph->points; - - - for ( ; glyph_count > 0; glyph_count--, point++ ) - { - FT_Pos y; - - - /* check tangents */ - if ( !PSH_DIR_COMPARE( point->dir_in, PSH_DIR_HORIZONTAL ) && - !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) ) - continue; - - /* skip strong points */ - if ( psh_point_is_strong( point ) ) - continue; - - y = point->org_u; - - /* look up top zones */ - table = &blues->normal_top; - blue_count = table->count; - zone = table->zones; - - for ( ; blue_count > 0; blue_count--, zone++ ) - { - FT_Pos delta = y - zone->org_bottom; - - - if ( delta < -blues->blue_fuzz ) - break; - - if ( y <= zone->org_top + blues->blue_fuzz ) - if ( blues->no_overshoots || delta <= blues->blue_threshold ) - { - point->cur_u = zone->cur_bottom; - psh_point_set_strong( point ); - psh_point_set_fitted( point ); - } - } - - /* look up bottom zones */ - table = &blues->normal_bottom; - blue_count = table->count; - zone = table->zones + blue_count - 1; - - for ( ; blue_count > 0; blue_count--, zone-- ) - { - FT_Pos delta = zone->org_top - y; - - - if ( delta < -blues->blue_fuzz ) - break; - - if ( y >= zone->org_bottom - blues->blue_fuzz ) - if ( blues->no_overshoots || delta < blues->blue_threshold ) - { - point->cur_u = zone->cur_top; - psh_point_set_strong( point ); - psh_point_set_fitted( point ); - } - } - } - } - - - /* interpolate strong points with the help of hinted coordinates */ - static void - psh_glyph_interpolate_strong_points( PSH_Glyph glyph, - FT_Int dimension ) - { - PSH_Dimension dim = &glyph->globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - - FT_UInt count = glyph->num_points; - PSH_Point point = glyph->points; - - - for ( ; count > 0; count--, point++ ) - { - PSH_Hint hint = point->hint; - - - if ( hint ) - { - FT_Pos delta; - - - if ( psh_point_is_edge_min( point ) ) - point->cur_u = hint->cur_pos; - - else if ( psh_point_is_edge_max( point ) ) - point->cur_u = hint->cur_pos + hint->cur_len; - - else - { - delta = point->org_u - hint->org_pos; - - if ( delta <= 0 ) - point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); - - else if ( delta >= hint->org_len ) - point->cur_u = hint->cur_pos + hint->cur_len + - FT_MulFix( delta - hint->org_len, scale ); - - else /* hint->org_len > 0 */ - point->cur_u = hint->cur_pos + - FT_MulDiv( delta, hint->cur_len, - hint->org_len ); - } - psh_point_set_fitted( point ); - } - } - } - - -#define PSH_MAX_STRONG_INTERNAL 16 - - static void - psh_glyph_interpolate_normal_points( PSH_Glyph glyph, - FT_Int dimension ) - { - -#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; - FT_Memory memory = glyph->memory; - - 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; - - - /* 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; - - /* sometimes, some local extrema are smooth points */ - if ( psh_point_is_smooth( point ) ) - { - if ( point->dir_in == PSH_DIR_NONE || - point->dir_in != point->dir_out ) - continue; - - if ( !psh_point_is_extremum( point ) && - !psh_point_is_inflex( point ) ) - continue; - - point->flags &= ~PSH_POINT_SMOOTH; - } - - /* find best enclosing point coordinates then interpolate */ - { - PSH_Point before, after; - FT_UInt nn; - - - 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 */ - { - after = strongs[0]; - - point->cur_u = after->cur_u + - FT_MulFix( point->org_u - after->org_u, - scale ); - } - else - { - before = strongs[nn - 1]; - - 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]; - - point->cur_u = before->cur_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 */ - - } - - - /* interpolate other points */ - static void - psh_glyph_interpolate_other_points( PSH_Glyph glyph, - FT_Int dimension ) - { - PSH_Dimension dim = &glyph->globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - PSH_Contour contour = glyph->contours; - FT_UInt num_contours = glyph->num_contours; - - - for ( ; num_contours > 0; num_contours--, contour++ ) - { - PSH_Point start = contour->start; - PSH_Point first, next, point; - FT_UInt fit_count; - - - /* count the number of strong points in this contour */ - next = start + contour->count; - fit_count = 0; - first = 0; - - for ( point = start; point < next; point++ ) - if ( psh_point_is_fitted( point ) ) - { - if ( !first ) - first = point; - - fit_count++; - } - - /* if there are less than 2 fitted points in the contour, we */ - /* simply scale and eventually translate the contour points */ - if ( fit_count < 2 ) - { - if ( fit_count == 1 ) - delta = first->cur_u - FT_MulFix( first->org_u, scale ); - - for ( point = start; point < next; point++ ) - if ( point != first ) - point->cur_u = FT_MulFix( point->org_u, scale ) + delta; - - goto Next_Contour; - } - - /* there are more than 2 strong points in this contour; we */ - /* need to interpolate weak points between them */ - start = first; - do - { - point = first; - - /* skip consecutive fitted points */ - for (;;) - { - next = first->next; - if ( next == start ) - goto Next_Contour; - - if ( !psh_point_is_fitted( next ) ) - break; - - first = next; - } - - /* find next fitted point after unfitted one */ - for (;;) - { - next = next->next; - if ( psh_point_is_fitted( next ) ) - break; - } - - /* now interpolate between them */ - { - FT_Pos org_a, org_ab, cur_a, cur_ab; - FT_Pos org_c, org_ac, cur_c; - FT_Fixed scale_ab; - - - if ( first->org_u <= next->org_u ) - { - org_a = first->org_u; - cur_a = first->cur_u; - org_ab = next->org_u - org_a; - cur_ab = next->cur_u - cur_a; - } - else - { - org_a = next->org_u; - cur_a = next->cur_u; - org_ab = first->org_u - org_a; - cur_ab = first->cur_u - cur_a; - } - - scale_ab = 0x10000L; - if ( org_ab > 0 ) - scale_ab = FT_DivFix( cur_ab, org_ab ); - - point = first->next; - do - { - org_c = point->org_u; - org_ac = org_c - org_a; - - if ( org_ac <= 0 ) - { - /* on the left of the interpolation zone */ - cur_c = cur_a + FT_MulFix( org_ac, scale ); - } - else if ( org_ac >= org_ab ) - { - /* on the right on the interpolation zone */ - cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale ); - } - else - { - /* within the interpolation zone */ - cur_c = cur_a + FT_MulFix( org_ac, scale_ab ); - } - - point->cur_u = cur_c; - - point = point->next; - - } while ( point != next ); - } - - /* keep going until all points in the contours have been processed */ - first = next; - - } while ( first != start ); - - Next_Contour: - ; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** HIGH-LEVEL INTERFACE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_Error - ps_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ) - { - PSH_GlyphRec glyphrec; - PSH_Glyph glyph = &glyphrec; - FT_Error error; -#ifdef DEBUG_HINTER - FT_Memory memory; -#endif - FT_Int dimension; - - - /* something to do? */ - if ( outline->n_points == 0 || outline->n_contours == 0 ) - return FT_Err_Ok; - -#ifdef DEBUG_HINTER - - memory = globals->memory; - - if ( ps_debug_glyph ) - { - psh_glyph_done( ps_debug_glyph ); - FT_FREE( ps_debug_glyph ); - } - - if ( FT_NEW( glyph ) ) - return error; - - ps_debug_glyph = glyph; - -#endif /* DEBUG_HINTER */ - - error = psh_glyph_init( glyph, outline, ps_hints, globals ); - if ( error ) - goto Exit; - - /* try to optimize the y_scale so that the top of non-capital letters - * is aligned on a pixel boundary whenever possible - */ - { - PSH_Dimension dim_x = &glyph->globals->dimension[0]; - PSH_Dimension dim_y = &glyph->globals->dimension[1]; - - FT_Fixed x_scale = dim_x->scale_mult; - FT_Fixed y_scale = dim_y->scale_mult; - - FT_Fixed old_x_scale = x_scale; - FT_Fixed old_y_scale = y_scale; - - FT_Fixed scaled; - FT_Fixed fitted; - - FT_Bool rescale = FALSE; - - - scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale ); - fitted = FT_PIX_ROUND( scaled ); - - if ( fitted != 0 && scaled != fitted ) - { - rescale = TRUE; - - y_scale = FT_MulDiv( y_scale, fitted, scaled ); - - if ( fitted < scaled ) - x_scale -= x_scale / 50; - - psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 ); - } - - glyph->do_horz_hints = 1; - glyph->do_vert_hints = 1; - - glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || - hint_mode == FT_RENDER_MODE_LCD ); - - glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || - hint_mode == FT_RENDER_MODE_LCD_V ); - - glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); - - for ( dimension = 0; dimension < 2; dimension++ ) - { - /* load outline coordinates into glyph */ - psh_glyph_load_points( glyph, dimension ); - - /* compute local extrema */ - psh_glyph_compute_extrema( glyph ); - - /* compute aligned stem/hints positions */ - psh_hint_table_align_hints( &glyph->hint_tables[dimension], - glyph->globals, - dimension, - glyph ); - - /* find strong points, align them, then interpolate others */ - psh_glyph_find_strong_points( glyph, dimension ); - if ( dimension == 1 ) - psh_glyph_find_blue_points( &globals->blues, glyph ); - psh_glyph_interpolate_strong_points( glyph, dimension ); - psh_glyph_interpolate_normal_points( glyph, dimension ); - psh_glyph_interpolate_other_points( glyph, dimension ); - - /* save hinted coordinates back to outline */ - psh_glyph_save_points( glyph, dimension ); - - if ( rescale ) - psh_globals_set_scale( glyph->globals, - old_x_scale, old_y_scale, 0, 0 ); - } - } - - Exit: - -#ifndef DEBUG_HINTER - psh_glyph_done( glyph ); -#endif - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshalgo.h b/drivers/freetype/freetype/src/pshinter/pshalgo.h deleted file mode 100644 index c70f31ea94..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshalgo.h +++ /dev/null @@ -1,246 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshalgo.h */ -/* */ -/* PostScript hinting algorithm (specification). */ -/* */ -/* Copyright 2001-2003, 2008, 2013 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 __PSHALGO_H__ -#define __PSHALGO_H__ - - -#include "pshrec.h" -#include "pshglob.h" - - -FT_BEGIN_HEADER - - - /* handle to Hint structure */ - typedef struct PSH_HintRec_* PSH_Hint; - - /* hint bit-flags */ - typedef enum PSH_Hint_Flags_ - { - PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, - PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, - PSH_HINT_ACTIVE = 4, - PSH_HINT_FITTED = 8 - - } PSH_Hint_Flags; - - -#define psh_hint_is_active( x ) ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 ) -#define psh_hint_is_ghost( x ) ( ( (x)->flags & PSH_HINT_GHOST ) != 0 ) -#define psh_hint_is_fitted( x ) ( ( (x)->flags & PSH_HINT_FITTED ) != 0 ) - -#define psh_hint_activate( x ) (x)->flags |= PSH_HINT_ACTIVE -#define psh_hint_deactivate( x ) (x)->flags &= ~PSH_HINT_ACTIVE -#define psh_hint_set_fitted( x ) (x)->flags |= PSH_HINT_FITTED - - /* hint structure */ - typedef struct PSH_HintRec_ - { - FT_Int org_pos; - FT_Int org_len; - FT_Pos cur_pos; - FT_Pos cur_len; - FT_UInt flags; - PSH_Hint parent; - FT_Int order; - - } PSH_HintRec; - - - /* this is an interpolation zone used for strong points; */ - /* weak points are interpolated according to their strong */ - /* neighbours */ - typedef struct PSH_ZoneRec_ - { - FT_Fixed scale; - FT_Fixed delta; - FT_Pos min; - FT_Pos max; - - } PSH_ZoneRec, *PSH_Zone; - - - typedef struct PSH_Hint_TableRec_ - { - FT_UInt max_hints; - FT_UInt num_hints; - PSH_Hint hints; - PSH_Hint* sort; - PSH_Hint* sort_global; - FT_UInt num_zones; - PSH_ZoneRec* zones; - PSH_Zone zone; - PS_Mask_Table hint_masks; - PS_Mask_Table counter_masks; - - } PSH_Hint_TableRec, *PSH_Hint_Table; - - - typedef struct PSH_PointRec_* PSH_Point; - typedef struct PSH_ContourRec_* PSH_Contour; - - enum - { - PSH_DIR_NONE = 4, - PSH_DIR_UP = -1, - PSH_DIR_DOWN = 1, - PSH_DIR_LEFT = -2, - PSH_DIR_RIGHT = 2 - }; - -#define PSH_DIR_HORIZONTAL 2 -#define PSH_DIR_VERTICAL 1 - -#define PSH_DIR_COMPARE( d1, d2 ) ( (d1) == (d2) || (d1) == -(d2) ) -#define PSH_DIR_IS_HORIZONTAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_HORIZONTAL ) -#define PSH_DIR_IS_VERTICAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL ) - - - /* the following bit-flags are computed once by the glyph */ - /* analyzer, for both dimensions */ - enum - { - PSH_POINT_OFF = 1, /* point is off the curve */ - PSH_POINT_SMOOTH = 2, /* point is smooth */ - PSH_POINT_INFLEX = 4 /* point is inflection */ - }; - -#define psh_point_is_smooth( p ) ( (p)->flags & PSH_POINT_SMOOTH ) -#define psh_point_is_off( p ) ( (p)->flags & PSH_POINT_OFF ) -#define psh_point_is_inflex( p ) ( (p)->flags & PSH_POINT_INFLEX ) - -#define psh_point_set_smooth( p ) (p)->flags |= PSH_POINT_SMOOTH -#define psh_point_set_off( p ) (p)->flags |= PSH_POINT_OFF -#define psh_point_set_inflex( p ) (p)->flags |= PSH_POINT_INFLEX - - /* the following bit-flags are re-computed for each dimension */ - enum - { - PSH_POINT_STRONG = 16, /* point is strong */ - PSH_POINT_FITTED = 32, /* point is already fitted */ - PSH_POINT_EXTREMUM = 64, /* point is local extremum */ - PSH_POINT_POSITIVE = 128, /* extremum has positive contour flow */ - PSH_POINT_NEGATIVE = 256, /* extremum has negative contour flow */ - PSH_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */ - PSH_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */ - }; - -#define psh_point_is_strong( p ) ( (p)->flags2 & PSH_POINT_STRONG ) -#define psh_point_is_fitted( p ) ( (p)->flags2 & PSH_POINT_FITTED ) -#define psh_point_is_extremum( p ) ( (p)->flags2 & PSH_POINT_EXTREMUM ) -#define psh_point_is_positive( p ) ( (p)->flags2 & PSH_POINT_POSITIVE ) -#define psh_point_is_negative( p ) ( (p)->flags2 & PSH_POINT_NEGATIVE ) -#define psh_point_is_edge_min( p ) ( (p)->flags2 & PSH_POINT_EDGE_MIN ) -#define psh_point_is_edge_max( p ) ( (p)->flags2 & PSH_POINT_EDGE_MAX ) - -#define psh_point_set_strong( p ) (p)->flags2 |= PSH_POINT_STRONG -#define psh_point_set_fitted( p ) (p)->flags2 |= PSH_POINT_FITTED -#define psh_point_set_extremum( p ) (p)->flags2 |= PSH_POINT_EXTREMUM -#define psh_point_set_positive( p ) (p)->flags2 |= PSH_POINT_POSITIVE -#define psh_point_set_negative( p ) (p)->flags2 |= PSH_POINT_NEGATIVE -#define psh_point_set_edge_min( p ) (p)->flags2 |= PSH_POINT_EDGE_MIN -#define psh_point_set_edge_max( p ) (p)->flags2 |= PSH_POINT_EDGE_MAX - - - typedef struct PSH_PointRec_ - { - PSH_Point prev; - PSH_Point next; - PSH_Contour contour; - FT_UInt flags; - FT_UInt flags2; - FT_Char dir_in; - FT_Char dir_out; - PSH_Hint hint; - FT_Pos org_u; - FT_Pos org_v; - FT_Pos cur_u; -#ifdef DEBUG_HINTER - FT_Pos org_x; - FT_Pos cur_x; - FT_Pos org_y; - FT_Pos cur_y; - FT_UInt flags_x; - FT_UInt flags_y; -#endif - - } PSH_PointRec; - - - typedef struct PSH_ContourRec_ - { - PSH_Point start; - FT_UInt count; - - } PSH_ContourRec; - - - typedef struct PSH_GlyphRec_ - { - FT_UInt num_points; - FT_UInt num_contours; - - PSH_Point points; - PSH_Contour contours; - - FT_Memory memory; - FT_Outline* outline; - PSH_Globals globals; - PSH_Hint_TableRec hint_tables[2]; - - FT_Bool vertical; - FT_Int major_dir; - FT_Int minor_dir; - - FT_Bool do_horz_hints; - FT_Bool do_vert_hints; - FT_Bool do_horz_snapping; - FT_Bool do_vert_snapping; - FT_Bool do_stem_adjust; - - } PSH_GlyphRec, *PSH_Glyph; - - -#ifdef DEBUG_HINTER - extern PSH_Hint_Table ps_debug_hint_table; - - typedef void - (*PSH_HintFunc)( PSH_Hint hint, - FT_Bool vertical ); - - extern PSH_HintFunc ps_debug_hint_func; - - extern PSH_Glyph ps_debug_glyph; -#endif - - - extern FT_Error - ps_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ); - - -FT_END_HEADER - - -#endif /* __PSHALGO_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshglob.c b/drivers/freetype/freetype/src/pshinter/pshglob.c deleted file mode 100644 index 9285efc9e1..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshglob.c +++ /dev/null @@ -1,797 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshglob.c */ -/* */ -/* PostScript hinter global hinting management (body). */ -/* Inspired by the new auto-hinter module. */ -/* */ -/* Copyright 2001-2004, 2006, 2010, 2012 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "pshglob.h" - -#ifdef DEBUG_HINTER - PSH_Globals ps_debug_globals = 0; -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** STANDARD WIDTHS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* scale the widths/heights table */ - static void - psh_globals_scale_widths( PSH_Globals globals, - FT_UInt direction ) - { - PSH_Dimension dim = &globals->dimension[direction]; - PSH_Widths stdw = &dim->stdw; - FT_UInt count = stdw->count; - PSH_Width width = stdw->widths; - PSH_Width stand = width; /* standard width/height */ - FT_Fixed scale = dim->scale_mult; - - - if ( count > 0 ) - { - width->cur = FT_MulFix( width->org, scale ); - width->fit = FT_PIX_ROUND( width->cur ); - - width++; - count--; - - for ( ; count > 0; count--, width++ ) - { - FT_Pos w, dist; - - - w = FT_MulFix( width->org, scale ); - dist = w - stand->cur; - - if ( dist < 0 ) - dist = -dist; - - if ( dist < 128 ) - w = stand->cur; - - width->cur = w; - width->fit = FT_PIX_ROUND( w ); - } - } - } - - -#if 0 - - /* org_width is is font units, result in device pixels, 26.6 format */ - FT_LOCAL_DEF( FT_Pos ) - psh_dimension_snap_width( PSH_Dimension dimension, - FT_Int org_width ) - { - FT_UInt n; - FT_Pos width = FT_MulFix( org_width, dimension->scale_mult ); - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - - - for ( n = 0; n < dimension->stdw.count; n++ ) - { - FT_Pos w; - FT_Pos dist; - - - w = dimension->stdw.widths[n].cur; - dist = width - w; - if ( dist < 0 ) - dist = -dist; - if ( dist < best ) - { - best = dist; - reference = w; - } - } - - if ( width >= reference ) - { - width -= 0x21; - if ( width < reference ) - width = reference; - } - else - { - width += 0x21; - if ( width > reference ) - width = reference; - } - - return width; - } - -#endif /* 0 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** BLUE ZONES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - psh_blues_set_zones_0( PSH_Blues target, - FT_Bool is_others, - FT_UInt read_count, - FT_Short* read, - PSH_Blue_Table top_table, - PSH_Blue_Table bot_table ) - { - FT_UInt count_top = top_table->count; - FT_UInt count_bot = bot_table->count; - FT_Bool first = 1; - - FT_UNUSED( target ); - - - for ( ; read_count > 1; read_count -= 2 ) - { - FT_Int reference, delta; - FT_UInt count; - PSH_Blue_Zone zones, zone; - FT_Bool top; - - - /* read blue zone entry, and select target top/bottom zone */ - top = 0; - if ( first || is_others ) - { - reference = read[1]; - delta = read[0] - reference; - - zones = bot_table->zones; - count = count_bot; - first = 0; - } - else - { - reference = read[0]; - delta = read[1] - reference; - - zones = top_table->zones; - count = count_top; - top = 1; - } - - /* insert into sorted table */ - zone = zones; - for ( ; count > 0; count--, zone++ ) - { - if ( reference < zone->org_ref ) - break; - - if ( reference == zone->org_ref ) - { - FT_Int delta0 = zone->org_delta; - - - /* we have two zones on the same reference position -- */ - /* only keep the largest one */ - if ( delta < 0 ) - { - if ( delta < delta0 ) - zone->org_delta = delta; - } - else - { - if ( delta > delta0 ) - zone->org_delta = delta; - } - goto Skip; - } - } - - for ( ; count > 0; count-- ) - zone[count] = zone[count-1]; - - zone->org_ref = reference; - zone->org_delta = delta; - - if ( top ) - count_top++; - else - count_bot++; - - Skip: - read += 2; - } - - top_table->count = count_top; - bot_table->count = count_bot; - } - - - /* Re-read blue zones from the original fonts and store them into out */ - /* private structure. This function re-orders, sanitizes and */ - /* fuzz-expands the zones as well. */ - static void - psh_blues_set_zones( PSH_Blues target, - FT_UInt count, - FT_Short* blues, - FT_UInt count_others, - FT_Short* other_blues, - FT_Int fuzz, - FT_Int family ) - { - PSH_Blue_Table top_table, bot_table; - FT_Int count_top, count_bot; - - - if ( family ) - { - top_table = &target->family_top; - bot_table = &target->family_bottom; - } - else - { - top_table = &target->normal_top; - bot_table = &target->normal_bottom; - } - - /* read the input blue zones, and build two sorted tables */ - /* (one for the top zones, the other for the bottom zones) */ - top_table->count = 0; - bot_table->count = 0; - - /* first, the blues */ - psh_blues_set_zones_0( target, 0, - count, blues, top_table, bot_table ); - psh_blues_set_zones_0( target, 1, - count_others, other_blues, top_table, bot_table ); - - count_top = top_table->count; - count_bot = bot_table->count; - - /* sanitize top table */ - if ( count_top > 0 ) - { - PSH_Blue_Zone zone = top_table->zones; - - - for ( count = count_top; count > 0; count--, zone++ ) - { - FT_Int delta; - - - if ( count > 1 ) - { - delta = zone[1].org_ref - zone[0].org_ref; - if ( zone->org_delta > delta ) - zone->org_delta = delta; - } - - zone->org_bottom = zone->org_ref; - zone->org_top = zone->org_delta + zone->org_ref; - } - } - - /* sanitize bottom table */ - if ( count_bot > 0 ) - { - PSH_Blue_Zone zone = bot_table->zones; - - - for ( count = count_bot; count > 0; count--, zone++ ) - { - FT_Int delta; - - - if ( count > 1 ) - { - delta = zone[0].org_ref - zone[1].org_ref; - if ( zone->org_delta < delta ) - zone->org_delta = delta; - } - - zone->org_top = zone->org_ref; - zone->org_bottom = zone->org_delta + zone->org_ref; - } - } - - /* expand top and bottom tables with blue fuzz */ - { - FT_Int dim, top, bot, delta; - PSH_Blue_Zone zone; - - - zone = top_table->zones; - count = count_top; - - for ( dim = 1; dim >= 0; dim-- ) - { - if ( count > 0 ) - { - /* expand the bottom of the lowest zone normally */ - zone->org_bottom -= fuzz; - - /* expand the top and bottom of intermediate zones; */ - /* checking that the interval is smaller than the fuzz */ - top = zone->org_top; - - for ( count--; count > 0; count-- ) - { - bot = zone[1].org_bottom; - delta = bot - top; - - if ( delta < 2 * fuzz ) - zone[0].org_top = zone[1].org_bottom = top + delta / 2; - else - { - zone[0].org_top = top + fuzz; - zone[1].org_bottom = bot - fuzz; - } - - zone++; - top = zone->org_top; - } - - /* expand the top of the highest zone normally */ - zone->org_top = top + fuzz; - } - zone = bot_table->zones; - count = count_bot; - } - } - } - - - /* reset the blues table when the device transform changes */ - static void - psh_blues_scale_zones( PSH_Blues blues, - FT_Fixed scale, - FT_Pos delta ) - { - FT_UInt count; - FT_UInt num; - PSH_Blue_Table table = 0; - - /* */ - /* Determine whether we need to suppress overshoots or */ - /* not. We simply need to compare the vertical scale */ - /* parameter to the raw bluescale value. Here is why: */ - /* */ - /* We need to suppress overshoots for all pointsizes. */ - /* At 300dpi that satisfies: */ - /* */ - /* pointsize < 240*bluescale + 0.49 */ - /* */ - /* This corresponds to: */ - /* */ - /* pixelsize < 1000*bluescale + 49/24 */ - /* */ - /* scale*EM_Size < 1000*bluescale + 49/24 */ - /* */ - /* However, for normal Type 1 fonts, EM_Size is 1000! */ - /* We thus only check: */ - /* */ - /* scale < bluescale + 49/24000 */ - /* */ - /* which we shorten to */ - /* */ - /* "scale < bluescale" */ - /* */ - /* Note that `blue_scale' is stored 1000 times its real */ - /* value, and that `scale' converts from font units to */ - /* fractional pixels. */ - /* */ - - /* 1000 / 64 = 125 / 8 */ - if ( scale >= 0x20C49BAL ) - blues->no_overshoots = FT_BOOL( scale < blues->blue_scale * 8 / 125 ); - else - blues->no_overshoots = FT_BOOL( scale * 125 < blues->blue_scale * 8 ); - - /* */ - /* The blue threshold is the font units distance under */ - /* which overshoots are suppressed due to the BlueShift */ - /* even if the scale is greater than BlueScale. */ - /* */ - /* It is the smallest distance such that */ - /* */ - /* dist <= BlueShift && dist*scale <= 0.5 pixels */ - /* */ - { - FT_Int threshold = blues->blue_shift; - - - while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 ) - threshold--; - - blues->blue_threshold = threshold; - } - - for ( num = 0; num < 4; num++ ) - { - PSH_Blue_Zone zone; - - - switch ( num ) - { - case 0: - table = &blues->normal_top; - break; - case 1: - table = &blues->normal_bottom; - break; - case 2: - table = &blues->family_top; - break; - default: - table = &blues->family_bottom; - break; - } - - zone = table->zones; - count = table->count; - for ( ; count > 0; count--, zone++ ) - { - zone->cur_top = FT_MulFix( zone->org_top, scale ) + delta; - zone->cur_bottom = FT_MulFix( zone->org_bottom, scale ) + delta; - zone->cur_ref = FT_MulFix( zone->org_ref, scale ) + delta; - zone->cur_delta = FT_MulFix( zone->org_delta, scale ); - - /* round scaled reference position */ - zone->cur_ref = FT_PIX_ROUND( zone->cur_ref ); - -#if 0 - if ( zone->cur_ref > zone->cur_top ) - zone->cur_ref -= 64; - else if ( zone->cur_ref < zone->cur_bottom ) - zone->cur_ref += 64; -#endif - } - } - - /* process the families now */ - - for ( num = 0; num < 2; num++ ) - { - PSH_Blue_Zone zone1, zone2; - FT_UInt count1, count2; - PSH_Blue_Table normal, family; - - - switch ( num ) - { - case 0: - normal = &blues->normal_top; - family = &blues->family_top; - break; - - default: - normal = &blues->normal_bottom; - family = &blues->family_bottom; - } - - zone1 = normal->zones; - count1 = normal->count; - - for ( ; count1 > 0; count1--, zone1++ ) - { - /* try to find a family zone whose reference position is less */ - /* than 1 pixel far from the current zone */ - zone2 = family->zones; - count2 = family->count; - - for ( ; count2 > 0; count2--, zone2++ ) - { - FT_Pos Delta; - - - Delta = zone1->org_ref - zone2->org_ref; - if ( Delta < 0 ) - Delta = -Delta; - - if ( FT_MulFix( Delta, scale ) < 64 ) - { - zone1->cur_top = zone2->cur_top; - zone1->cur_bottom = zone2->cur_bottom; - zone1->cur_ref = zone2->cur_ref; - zone1->cur_delta = zone2->cur_delta; - break; - } - } - } - } - } - - - /* calculate the maximum height of given blue zones */ - static FT_Short - psh_calc_max_height( FT_UInt num, - const FT_Short* values, - FT_Short cur_max ) - { - FT_UInt count; - - - for ( count = 0; count < num; count += 2 ) - { - FT_Short cur_height = values[count + 1] - values[count]; - - - if ( cur_height > cur_max ) - cur_max = cur_height; - } - - return cur_max; - } - - - FT_LOCAL_DEF( void ) - psh_blues_snap_stem( PSH_Blues blues, - FT_Int stem_top, - FT_Int stem_bot, - PSH_Alignment alignment ) - { - PSH_Blue_Table table; - FT_UInt count; - FT_Pos delta; - PSH_Blue_Zone zone; - FT_Int no_shoots; - - - alignment->align = PSH_BLUE_ALIGN_NONE; - - no_shoots = blues->no_overshoots; - - /* look up stem top in top zones table */ - table = &blues->normal_top; - count = table->count; - zone = table->zones; - - for ( ; count > 0; count--, zone++ ) - { - delta = stem_top - zone->org_bottom; - if ( delta < -blues->blue_fuzz ) - break; - - if ( stem_top <= zone->org_top + blues->blue_fuzz ) - { - if ( no_shoots || delta <= blues->blue_threshold ) - { - alignment->align |= PSH_BLUE_ALIGN_TOP; - alignment->align_top = zone->cur_ref; - } - break; - } - } - - /* look up stem bottom in bottom zones table */ - table = &blues->normal_bottom; - count = table->count; - zone = table->zones + count-1; - - for ( ; count > 0; count--, zone-- ) - { - delta = zone->org_top - stem_bot; - if ( delta < -blues->blue_fuzz ) - break; - - if ( stem_bot >= zone->org_bottom - blues->blue_fuzz ) - { - if ( no_shoots || delta < blues->blue_threshold ) - { - alignment->align |= PSH_BLUE_ALIGN_BOT; - alignment->align_bot = zone->cur_ref; - } - break; - } - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLOBAL HINTS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - psh_globals_destroy( PSH_Globals globals ) - { - if ( globals ) - { - FT_Memory memory; - - - memory = globals->memory; - globals->dimension[0].stdw.count = 0; - globals->dimension[1].stdw.count = 0; - - globals->blues.normal_top.count = 0; - globals->blues.normal_bottom.count = 0; - globals->blues.family_top.count = 0; - globals->blues.family_bottom.count = 0; - - FT_FREE( globals ); - -#ifdef DEBUG_HINTER - ps_debug_globals = 0; -#endif - } - } - - - static FT_Error - psh_globals_new( FT_Memory memory, - T1_Private* priv, - PSH_Globals *aglobals ) - { - PSH_Globals globals = NULL; - FT_Error error; - - - if ( !FT_NEW( globals ) ) - { - FT_UInt count; - FT_Short* read; - - - globals->memory = memory; - - /* copy standard widths */ - { - PSH_Dimension dim = &globals->dimension[1]; - PSH_Width write = dim->stdw.widths; - - - write->org = priv->standard_width[0]; - write++; - - read = priv->snap_widths; - for ( count = priv->num_snap_widths; count > 0; count-- ) - { - write->org = *read; - write++; - read++; - } - - dim->stdw.count = priv->num_snap_widths + 1; - } - - /* copy standard heights */ - { - PSH_Dimension dim = &globals->dimension[0]; - PSH_Width write = dim->stdw.widths; - - - write->org = priv->standard_height[0]; - write++; - read = priv->snap_heights; - for ( count = priv->num_snap_heights; count > 0; count-- ) - { - write->org = *read; - write++; - read++; - } - - dim->stdw.count = priv->num_snap_heights + 1; - } - - /* copy blue zones */ - psh_blues_set_zones( &globals->blues, priv->num_blue_values, - priv->blue_values, priv->num_other_blues, - priv->other_blues, priv->blue_fuzz, 0 ); - - psh_blues_set_zones( &globals->blues, priv->num_family_blues, - priv->family_blues, priv->num_family_other_blues, - priv->family_other_blues, priv->blue_fuzz, 1 ); - - /* limit the BlueScale value to `1 / max_of_blue_zone_heights' */ - { - FT_Fixed max_scale; - FT_Short max_height = 1; - - - max_height = psh_calc_max_height( priv->num_blue_values, - priv->blue_values, - max_height ); - max_height = psh_calc_max_height( priv->num_other_blues, - priv->other_blues, - max_height ); - max_height = psh_calc_max_height( priv->num_family_blues, - priv->family_blues, - max_height ); - max_height = psh_calc_max_height( priv->num_family_other_blues, - priv->family_other_blues, - max_height ); - - /* BlueScale is scaled 1000 times */ - max_scale = FT_DivFix( 1000, max_height ); - globals->blues.blue_scale = priv->blue_scale < max_scale - ? priv->blue_scale - : max_scale; - } - - globals->blues.blue_shift = priv->blue_shift; - globals->blues.blue_fuzz = priv->blue_fuzz; - - globals->dimension[0].scale_mult = 0; - globals->dimension[0].scale_delta = 0; - globals->dimension[1].scale_mult = 0; - globals->dimension[1].scale_delta = 0; - -#ifdef DEBUG_HINTER - ps_debug_globals = globals; -#endif - } - - *aglobals = globals; - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - psh_globals_set_scale( PSH_Globals globals, - FT_Fixed x_scale, - FT_Fixed y_scale, - FT_Fixed x_delta, - FT_Fixed y_delta ) - { - PSH_Dimension dim = &globals->dimension[0]; - - - dim = &globals->dimension[0]; - if ( x_scale != dim->scale_mult || - x_delta != dim->scale_delta ) - { - dim->scale_mult = x_scale; - dim->scale_delta = x_delta; - - psh_globals_scale_widths( globals, 0 ); - } - - dim = &globals->dimension[1]; - if ( y_scale != dim->scale_mult || - y_delta != dim->scale_delta ) - { - dim->scale_mult = y_scale; - dim->scale_delta = y_delta; - - psh_globals_scale_widths( globals, 1 ); - psh_blues_scale_zones( &globals->blues, y_scale, y_delta ); - } - - return 0; - } - - - FT_LOCAL_DEF( void ) - psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ) - { - funcs->create = psh_globals_new; - funcs->set_scale = psh_globals_set_scale; - funcs->destroy = psh_globals_destroy; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshglob.h b/drivers/freetype/freetype/src/pshinter/pshglob.h deleted file mode 100644 index c511626157..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshglob.h +++ /dev/null @@ -1,196 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshglob.h */ -/* */ -/* PostScript hinter global hinting management. */ -/* */ -/* Copyright 2001, 2002, 2003 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 __PSHGLOB_H__ -#define __PSHGLOB_H__ - - -#include FT_FREETYPE_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLOBAL HINTS INTERNALS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* @constant: */ - /* PS_GLOBALS_MAX_BLUE_ZONES */ - /* */ - /* @description: */ - /* The maximum number of blue zones in a font global hints structure. */ - /* See @PS_Globals_BluesRec. */ - /* */ -#define PS_GLOBALS_MAX_BLUE_ZONES 16 - - - /*************************************************************************/ - /* */ - /* @constant: */ - /* PS_GLOBALS_MAX_STD_WIDTHS */ - /* */ - /* @description: */ - /* The maximum number of standard and snap widths in either the */ - /* horizontal or vertical direction. See @PS_Globals_WidthsRec. */ - /* */ -#define PS_GLOBALS_MAX_STD_WIDTHS 16 - - - /* standard and snap width */ - typedef struct PSH_WidthRec_ - { - FT_Int org; - FT_Pos cur; - FT_Pos fit; - - } PSH_WidthRec, *PSH_Width; - - - /* standard and snap widths table */ - typedef struct PSH_WidthsRec_ - { - FT_UInt count; - PSH_WidthRec widths[PS_GLOBALS_MAX_STD_WIDTHS]; - - } PSH_WidthsRec, *PSH_Widths; - - - typedef struct PSH_DimensionRec_ - { - PSH_WidthsRec stdw; - FT_Fixed scale_mult; - FT_Fixed scale_delta; - - } PSH_DimensionRec, *PSH_Dimension; - - - /* blue zone descriptor */ - typedef struct PSH_Blue_ZoneRec_ - { - FT_Int org_ref; - FT_Int org_delta; - FT_Int org_top; - FT_Int org_bottom; - - FT_Pos cur_ref; - FT_Pos cur_delta; - FT_Pos cur_bottom; - FT_Pos cur_top; - - } PSH_Blue_ZoneRec, *PSH_Blue_Zone; - - - typedef struct PSH_Blue_TableRec_ - { - FT_UInt count; - PSH_Blue_ZoneRec zones[PS_GLOBALS_MAX_BLUE_ZONES]; - - } PSH_Blue_TableRec, *PSH_Blue_Table; - - - /* blue zones table */ - typedef struct PSH_BluesRec_ - { - PSH_Blue_TableRec normal_top; - PSH_Blue_TableRec normal_bottom; - PSH_Blue_TableRec family_top; - PSH_Blue_TableRec family_bottom; - - FT_Fixed blue_scale; - FT_Int blue_shift; - FT_Int blue_threshold; - FT_Int blue_fuzz; - FT_Bool no_overshoots; - - } PSH_BluesRec, *PSH_Blues; - - - /* font globals. */ - /* dimension 0 => X coordinates + vertical hints/stems */ - /* dimension 1 => Y coordinates + horizontal hints/stems */ - typedef struct PSH_GlobalsRec_ - { - FT_Memory memory; - PSH_DimensionRec dimension[2]; - PSH_BluesRec blues; - - } PSH_GlobalsRec; - - -#define PSH_BLUE_ALIGN_NONE 0 -#define PSH_BLUE_ALIGN_TOP 1 -#define PSH_BLUE_ALIGN_BOT 2 - - - typedef struct PSH_AlignmentRec_ - { - int align; - FT_Pos align_top; - FT_Pos align_bot; - - } PSH_AlignmentRec, *PSH_Alignment; - - - FT_LOCAL( void ) - psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ); - - -#if 0 - /* snap a stem width to fitter coordinates. `org_width' is in font */ - /* units. The result is in device pixels (26.6 format). */ - FT_LOCAL( FT_Pos ) - psh_dimension_snap_width( PSH_Dimension dimension, - FT_Int org_width ); -#endif - - FT_LOCAL( FT_Error ) - psh_globals_set_scale( PSH_Globals globals, - FT_Fixed x_scale, - FT_Fixed y_scale, - FT_Fixed x_delta, - FT_Fixed y_delta ); - - /* snap a stem to one or two blue zones */ - FT_LOCAL( void ) - psh_blues_snap_stem( PSH_Blues blues, - FT_Int stem_top, - FT_Int stem_bot, - PSH_Alignment alignment ); - /* */ - -#ifdef DEBUG_HINTER - extern PSH_Globals ps_debug_globals; -#endif - - -FT_END_HEADER - - -#endif /* __PSHGLOB_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshinter.c b/drivers/freetype/freetype/src/pshinter/pshinter.c deleted file mode 100644 index b35a2a91c5..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshinter.c +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshinter.c */ -/* */ -/* FreeType PostScript Hinting module */ -/* */ -/* Copyright 2001, 2003 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "pshpic.c" -#include "pshrec.c" -#include "pshglob.c" -#include "pshalgo.c" -#include "pshmod.c" - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshmod.c b/drivers/freetype/freetype/src/pshinter/pshmod.c deleted file mode 100644 index cdeaca18c9..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshmod.c +++ /dev/null @@ -1,119 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshmod.c */ -/* */ -/* FreeType PostScript hinter module implementation (body). */ -/* */ -/* Copyright 2001, 2002, 2007, 2009, 2012 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include "pshrec.h" -#include "pshalgo.h" -#include "pshpic.h" - - - /* the Postscript Hinter module structure */ - typedef struct PS_Hinter_Module_Rec_ - { - FT_ModuleRec root; - PS_HintsRec ps_hints; - - PSH_Globals_FuncsRec globals_funcs; - T1_Hints_FuncsRec t1_funcs; - T2_Hints_FuncsRec t2_funcs; - - } PS_Hinter_ModuleRec, *PS_Hinter_Module; - - - /* finalize module */ - FT_CALLBACK_DEF( void ) - ps_hinter_done( PS_Hinter_Module module ) - { - module->t1_funcs.hints = NULL; - module->t2_funcs.hints = NULL; - - ps_hints_done( &module->ps_hints ); - } - - - /* initialize module, create hints recorder and the interface */ - FT_CALLBACK_DEF( FT_Error ) - ps_hinter_init( PS_Hinter_Module module ) - { - FT_Memory memory = module->root.memory; - void* ph = &module->ps_hints; - - - ps_hints_init( &module->ps_hints, memory ); - - psh_globals_funcs_init( &module->globals_funcs ); - - t1_hints_funcs_init( &module->t1_funcs ); - module->t1_funcs.hints = (T1_Hints)ph; - - t2_hints_funcs_init( &module->t2_funcs ); - module->t2_funcs.hints = (T2_Hints)ph; - - return 0; - } - - - /* returns global hints interface */ - FT_CALLBACK_DEF( PSH_Globals_Funcs ) - pshinter_get_globals_funcs( FT_Module module ) - { - return &((PS_Hinter_Module)module)->globals_funcs; - } - - - /* return Type 1 hints interface */ - FT_CALLBACK_DEF( T1_Hints_Funcs ) - pshinter_get_t1_funcs( FT_Module module ) - { - return &((PS_Hinter_Module)module)->t1_funcs; - } - - - /* return Type 2 hints interface */ - FT_CALLBACK_DEF( T2_Hints_Funcs ) - pshinter_get_t2_funcs( FT_Module module ) - { - return &((PS_Hinter_Module)module)->t2_funcs; - } - - - FT_DEFINE_PSHINTER_INTERFACE( - pshinter_interface, - pshinter_get_globals_funcs, - pshinter_get_t1_funcs, - pshinter_get_t2_funcs ) - - - FT_DEFINE_MODULE( - pshinter_module_class, - - 0, - sizeof ( PS_Hinter_ModuleRec ), - "pshinter", - 0x10000L, - 0x20000L, - - &PSHINTER_INTERFACE_GET, /* module-specific interface */ - - (FT_Module_Constructor)ps_hinter_init, - (FT_Module_Destructor) ps_hinter_done, - (FT_Module_Requester) NULL ) /* no additional interface for now */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshmod.h b/drivers/freetype/freetype/src/pshinter/pshmod.h deleted file mode 100644 index 0ae7e96f54..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshmod.h +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshmod.h */ -/* */ -/* PostScript hinter module interface (specification). */ -/* */ -/* Copyright 2001 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 __PSHMOD_H__ -#define __PSHMOD_H__ - - -#include <ft2build.h> -#include FT_MODULE_H - - -FT_BEGIN_HEADER - - - FT_DECLARE_MODULE( pshinter_module_class ) - - -FT_END_HEADER - - -#endif /* __PSHMOD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshnterr.h b/drivers/freetype/freetype/src/pshinter/pshnterr.h deleted file mode 100644 index 7cc180f0ca..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshnterr.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshnterr.h */ -/* */ -/* PS Hinter error codes (specification only). */ -/* */ -/* Copyright 2003, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PSHinter error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __PSHNTERR_H__ -#define __PSHNTERR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PSH_Err_ -#define FT_ERR_BASE FT_Mod_Err_PShinter - -#include FT_ERRORS_H - -#endif /* __PSHNTERR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshpic.c b/drivers/freetype/freetype/src/pshinter/pshpic.c deleted file mode 100644 index 568f4ac4b0..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshpic.c +++ /dev/null @@ -1,76 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshpic.c */ -/* */ -/* The FreeType position independent code services for pshinter module. */ -/* */ -/* Copyright 2009, 2010, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "pshpic.h" -#include "pshnterr.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from pshmod.c */ - void - FT_Init_Class_pshinter_interface( FT_Library library, - PSHinter_Interface* clazz ); - - void - pshinter_module_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->pshinter ) - { - FT_FREE( pic_container->pshinter ); - pic_container->pshinter = NULL; - } - } - - - FT_Error - pshinter_module_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - PSHinterPIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->pshinter = container; - - /* add call to initialization function when you add new scripts */ - FT_Init_Class_pshinter_interface( - library, &container->pshinter_interface ); - - if ( error ) - pshinter_module_class_pic_free( library ); - - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshpic.h b/drivers/freetype/freetype/src/pshinter/pshpic.h deleted file mode 100644 index b46f853113..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshpic.h +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshpic.h */ -/* */ -/* The FreeType position independent code services for pshinter module. */ -/* */ -/* Copyright 2009, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __PSHPIC_H__ -#define __PSHPIC_H__ - - -FT_BEGIN_HEADER - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define PSHINTER_INTERFACE_GET pshinter_interface - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_INTERNAL_POSTSCRIPT_HINTS_H - - typedef struct PSHinterPIC_ - { - PSHinter_Interface pshinter_interface; - - } PSHinterPIC; - - -#define GET_PIC( lib ) ( (PSHinterPIC*)( (lib)->pic_container.pshinter ) ) - -#define PSHINTER_INTERFACE_GET ( GET_PIC( library )->pshinter_interface ) - - /* see pshpic.c for the implementation */ - void - pshinter_module_class_pic_free( FT_Library library ); - - FT_Error - pshinter_module_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __PSHPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshrec.c b/drivers/freetype/freetype/src/pshinter/pshrec.c deleted file mode 100644 index cd66ea869a..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshrec.c +++ /dev/null @@ -1,1225 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshrec.c */ -/* */ -/* FreeType PostScript hints recorder (body). */ -/* */ -/* Copyright 2001-2004, 2007, 2009, 2013 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H - -#include "pshrec.h" -#include "pshalgo.h" - -#include "pshnterr.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pshrec - -#ifdef DEBUG_HINTER - PS_Hints ps_debug_hints = 0; - int ps_debug_no_horz_hints = 0; - int ps_debug_no_vert_hints = 0; -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PS_HINT MANAGEMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* destroy hints table */ - static void - ps_hint_table_done( PS_Hint_Table table, - FT_Memory memory ) - { - FT_FREE( table->hints ); - table->num_hints = 0; - table->max_hints = 0; - } - - - /* ensure that a table can contain "count" elements */ - static FT_Error - ps_hint_table_ensure( PS_Hint_Table table, - FT_UInt count, - FT_Memory memory ) - { - FT_UInt old_max = table->max_hints; - FT_UInt new_max = count; - FT_Error error = FT_Err_Ok; - - - if ( new_max > old_max ) - { - /* try to grow the table */ - new_max = FT_PAD_CEIL( new_max, 8 ); - if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) ) - table->max_hints = new_max; - } - return error; - } - - - static FT_Error - ps_hint_table_alloc( PS_Hint_Table table, - FT_Memory memory, - PS_Hint *ahint ) - { - FT_Error error = FT_Err_Ok; - FT_UInt count; - PS_Hint hint = 0; - - - count = table->num_hints; - count++; - - if ( count >= table->max_hints ) - { - error = ps_hint_table_ensure( table, count, memory ); - if ( error ) - goto Exit; - } - - hint = table->hints + count - 1; - hint->pos = 0; - hint->len = 0; - hint->flags = 0; - - table->num_hints = count; - - Exit: - *ahint = hint; - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PS_MASK MANAGEMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* destroy mask */ - static void - ps_mask_done( PS_Mask mask, - FT_Memory memory ) - { - FT_FREE( mask->bytes ); - mask->num_bits = 0; - mask->max_bits = 0; - mask->end_point = 0; - } - - - /* ensure that a mask can contain "count" bits */ - static FT_Error - ps_mask_ensure( PS_Mask mask, - FT_UInt count, - FT_Memory memory ) - { - FT_UInt old_max = ( mask->max_bits + 7 ) >> 3; - FT_UInt new_max = ( count + 7 ) >> 3; - FT_Error error = FT_Err_Ok; - - - if ( new_max > old_max ) - { - new_max = FT_PAD_CEIL( new_max, 8 ); - if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) ) - mask->max_bits = new_max * 8; - } - return error; - } - - - /* test a bit value in a given mask */ - static FT_Int - ps_mask_test_bit( PS_Mask mask, - FT_Int idx ) - { - if ( (FT_UInt)idx >= mask->num_bits ) - return 0; - - return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) ); - } - - - /* clear a given bit */ - static void - ps_mask_clear_bit( PS_Mask mask, - FT_Int idx ) - { - FT_Byte* p; - - - if ( (FT_UInt)idx >= mask->num_bits ) - return; - - p = mask->bytes + ( idx >> 3 ); - p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) ); - } - - - /* set a given bit, possibly grow the mask */ - static FT_Error - ps_mask_set_bit( PS_Mask mask, - FT_Int idx, - FT_Memory memory ) - { - FT_Error error = FT_Err_Ok; - FT_Byte* p; - - - if ( idx < 0 ) - goto Exit; - - if ( (FT_UInt)idx >= mask->num_bits ) - { - error = ps_mask_ensure( mask, idx + 1, memory ); - if ( error ) - goto Exit; - - mask->num_bits = idx + 1; - } - - p = mask->bytes + ( idx >> 3 ); - p[0] = (FT_Byte)( p[0] | ( 0x80 >> ( idx & 7 ) ) ); - - Exit: - return error; - } - - - /* destroy mask table */ - static void - ps_mask_table_done( PS_Mask_Table table, - FT_Memory memory ) - { - FT_UInt count = table->max_masks; - PS_Mask mask = table->masks; - - - for ( ; count > 0; count--, mask++ ) - ps_mask_done( mask, memory ); - - FT_FREE( table->masks ); - table->num_masks = 0; - table->max_masks = 0; - } - - - /* ensure that a mask table can contain "count" masks */ - static FT_Error - ps_mask_table_ensure( PS_Mask_Table table, - FT_UInt count, - FT_Memory memory ) - { - FT_UInt old_max = table->max_masks; - FT_UInt new_max = count; - FT_Error error = FT_Err_Ok; - - - if ( new_max > old_max ) - { - new_max = FT_PAD_CEIL( new_max, 8 ); - if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) ) - table->max_masks = new_max; - } - return error; - } - - - /* allocate a new mask in a table */ - static FT_Error - ps_mask_table_alloc( PS_Mask_Table table, - FT_Memory memory, - PS_Mask *amask ) - { - FT_UInt count; - FT_Error error = FT_Err_Ok; - PS_Mask mask = 0; - - - count = table->num_masks; - count++; - - if ( count > table->max_masks ) - { - error = ps_mask_table_ensure( table, count, memory ); - if ( error ) - goto Exit; - } - - mask = table->masks + count - 1; - mask->num_bits = 0; - mask->end_point = 0; - table->num_masks = count; - - Exit: - *amask = mask; - return error; - } - - - /* return last hint mask in a table, create one if the table is empty */ - static FT_Error - ps_mask_table_last( PS_Mask_Table table, - FT_Memory memory, - PS_Mask *amask ) - { - FT_Error error = FT_Err_Ok; - FT_UInt count; - PS_Mask mask; - - - count = table->num_masks; - if ( count == 0 ) - { - error = ps_mask_table_alloc( table, memory, &mask ); - if ( error ) - goto Exit; - } - else - mask = table->masks + count - 1; - - Exit: - *amask = mask; - return error; - } - - - /* set a new mask to a given bit range */ - static FT_Error - ps_mask_table_set_bits( PS_Mask_Table table, - const FT_Byte* source, - FT_UInt bit_pos, - FT_UInt bit_count, - FT_Memory memory ) - { - FT_Error error; - PS_Mask mask; - - - error = ps_mask_table_last( table, memory, &mask ); - if ( error ) - goto Exit; - - error = ps_mask_ensure( mask, bit_count, memory ); - if ( error ) - goto Exit; - - mask->num_bits = bit_count; - - /* now, copy bits */ - { - FT_Byte* read = (FT_Byte*)source + ( bit_pos >> 3 ); - FT_Int rmask = 0x80 >> ( bit_pos & 7 ); - FT_Byte* write = mask->bytes; - FT_Int wmask = 0x80; - FT_Int val; - - - for ( ; bit_count > 0; bit_count-- ) - { - val = write[0] & ~wmask; - - if ( read[0] & rmask ) - val |= wmask; - - write[0] = (FT_Byte)val; - - rmask >>= 1; - if ( rmask == 0 ) - { - read++; - rmask = 0x80; - } - - wmask >>= 1; - if ( wmask == 0 ) - { - write++; - wmask = 0x80; - } - } - } - - Exit: - return error; - } - - - /* test whether two masks in a table intersect */ - static FT_Int - ps_mask_table_test_intersect( PS_Mask_Table table, - FT_Int index1, - FT_Int index2 ) - { - PS_Mask mask1 = table->masks + index1; - PS_Mask mask2 = table->masks + index2; - FT_Byte* p1 = mask1->bytes; - FT_Byte* p2 = mask2->bytes; - FT_UInt count1 = mask1->num_bits; - FT_UInt count2 = mask2->num_bits; - FT_UInt count; - - - count = FT_MIN( count1, count2 ); - for ( ; count >= 8; count -= 8 ) - { - if ( p1[0] & p2[0] ) - return 1; - - p1++; - p2++; - } - - if ( count == 0 ) - return 0; - - return ( p1[0] & p2[0] ) & ~( 0xFF >> count ); - } - - - /* merge two masks, used by ps_mask_table_merge_all */ - static FT_Error - ps_mask_table_merge( PS_Mask_Table table, - FT_Int index1, - FT_Int index2, - FT_Memory memory ) - { - FT_UInt temp; - FT_Error error = FT_Err_Ok; - - - /* swap index1 and index2 so that index1 < index2 */ - if ( index1 > index2 ) - { - temp = index1; - index1 = index2; - index2 = temp; - } - - if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks ) - { - /* we need to merge the bitsets of index1 and index2 with a */ - /* simple union */ - PS_Mask mask1 = table->masks + index1; - PS_Mask mask2 = table->masks + index2; - FT_UInt count1 = mask1->num_bits; - FT_UInt count2 = mask2->num_bits; - FT_Int delta; - - - if ( count2 > 0 ) - { - FT_UInt pos; - FT_Byte* read; - FT_Byte* write; - - - /* if "count2" is greater than "count1", we need to grow the */ - /* first bitset, and clear the highest bits */ - if ( count2 > count1 ) - { - error = ps_mask_ensure( mask1, count2, memory ); - if ( error ) - goto Exit; - - for ( pos = count1; pos < count2; pos++ ) - ps_mask_clear_bit( mask1, pos ); - } - - /* merge (unite) the bitsets */ - read = mask2->bytes; - write = mask1->bytes; - pos = (FT_UInt)( ( count2 + 7 ) >> 3 ); - - for ( ; pos > 0; pos-- ) - { - write[0] = (FT_Byte)( write[0] | read[0] ); - write++; - read++; - } - } - - /* Now, remove "mask2" from the list. We need to keep the masks */ - /* sorted in order of importance, so move table elements. */ - mask2->num_bits = 0; - mask2->end_point = 0; - - delta = table->num_masks - 1 - index2; /* number of masks to move */ - if ( delta > 0 ) - { - /* move to end of table for reuse */ - PS_MaskRec dummy = *mask2; - - - ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) ); - - mask2[delta] = dummy; - } - - table->num_masks--; - } - else - FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", - index1, index2 )); - - Exit: - return error; - } - - - /* Try to merge all masks in a given table. This is used to merge */ - /* all counter masks into independent counter "paths". */ - /* */ - static FT_Error - ps_mask_table_merge_all( PS_Mask_Table table, - FT_Memory memory ) - { - FT_Int index1, index2; - FT_Error error = FT_Err_Ok; - - - for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) - { - for ( index2 = index1 - 1; index2 >= 0; index2-- ) - { - if ( ps_mask_table_test_intersect( table, index1, index2 ) ) - { - error = ps_mask_table_merge( table, index2, index1, memory ); - if ( error ) - goto Exit; - - break; - } - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PS_DIMENSION MANAGEMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* finalize a given dimension */ - static void - ps_dimension_done( PS_Dimension dimension, - FT_Memory memory ) - { - ps_mask_table_done( &dimension->counters, memory ); - ps_mask_table_done( &dimension->masks, memory ); - ps_hint_table_done( &dimension->hints, memory ); - } - - - /* initialize a given dimension */ - static void - ps_dimension_init( PS_Dimension dimension ) - { - dimension->hints.num_hints = 0; - dimension->masks.num_masks = 0; - dimension->counters.num_masks = 0; - } - - -#if 0 - - /* set a bit at a given index in the current hint mask */ - static FT_Error - ps_dimension_set_mask_bit( PS_Dimension dim, - FT_UInt idx, - FT_Memory memory ) - { - PS_Mask mask; - FT_Error error = FT_Err_Ok; - - - /* get last hint mask */ - error = ps_mask_table_last( &dim->masks, memory, &mask ); - if ( error ) - goto Exit; - - error = ps_mask_set_bit( mask, idx, memory ); - - Exit: - return error; - } - -#endif - - /* set the end point in a mask, called from "End" & "Reset" methods */ - static void - ps_dimension_end_mask( PS_Dimension dim, - FT_UInt end_point ) - { - FT_UInt count = dim->masks.num_masks; - - - if ( count > 0 ) - { - PS_Mask mask = dim->masks.masks + count - 1; - - - mask->end_point = end_point; - } - } - - - /* set the end point in the current mask, then create a new empty one */ - /* (called by "Reset" method) */ - static FT_Error - ps_dimension_reset_mask( PS_Dimension dim, - FT_UInt end_point, - FT_Memory memory ) - { - PS_Mask mask; - - - /* end current mask */ - ps_dimension_end_mask( dim, end_point ); - - /* allocate new one */ - return ps_mask_table_alloc( &dim->masks, memory, &mask ); - } - - - /* set a new mask, called from the "T2Stem" method */ - static FT_Error - ps_dimension_set_mask_bits( PS_Dimension dim, - const FT_Byte* source, - FT_UInt source_pos, - FT_UInt source_bits, - FT_UInt end_point, - FT_Memory memory ) - { - FT_Error error; - - - /* reset current mask, if any */ - error = ps_dimension_reset_mask( dim, end_point, memory ); - if ( error ) - goto Exit; - - /* set bits in new mask */ - error = ps_mask_table_set_bits( &dim->masks, source, - source_pos, source_bits, memory ); - - Exit: - return error; - } - - - /* add a new single stem (called from "T1Stem" method) */ - static FT_Error - ps_dimension_add_t1stem( PS_Dimension dim, - FT_Int pos, - FT_Int len, - FT_Memory memory, - FT_Int *aindex ) - { - FT_Error error = FT_Err_Ok; - FT_UInt flags = 0; - - - /* detect ghost stem */ - if ( len < 0 ) - { - flags |= PS_HINT_FLAG_GHOST; - if ( len == -21 ) - { - flags |= PS_HINT_FLAG_BOTTOM; - pos += len; - } - len = 0; - } - - if ( aindex ) - *aindex = -1; - - /* now, lookup stem in the current hints table */ - { - PS_Mask mask; - FT_UInt idx; - FT_UInt max = dim->hints.num_hints; - PS_Hint hint = dim->hints.hints; - - - for ( idx = 0; idx < max; idx++, hint++ ) - { - if ( hint->pos == pos && hint->len == len ) - break; - } - - /* we need to create a new hint in the table */ - if ( idx >= max ) - { - error = ps_hint_table_alloc( &dim->hints, memory, &hint ); - if ( error ) - goto Exit; - - hint->pos = pos; - hint->len = len; - hint->flags = flags; - } - - /* now, store the hint in the current mask */ - error = ps_mask_table_last( &dim->masks, memory, &mask ); - if ( error ) - goto Exit; - - error = ps_mask_set_bit( mask, idx, memory ); - if ( error ) - goto Exit; - - if ( aindex ) - *aindex = (FT_Int)idx; - } - - Exit: - return error; - } - - - /* add a "hstem3/vstem3" counter to our dimension table */ - static FT_Error - ps_dimension_add_counter( PS_Dimension dim, - FT_Int hint1, - FT_Int hint2, - FT_Int hint3, - FT_Memory memory ) - { - FT_Error error = FT_Err_Ok; - FT_UInt count = dim->counters.num_masks; - PS_Mask counter = dim->counters.masks; - - - /* try to find an existing counter mask that already uses */ - /* one of these stems here */ - for ( ; count > 0; count--, counter++ ) - { - if ( ps_mask_test_bit( counter, hint1 ) || - ps_mask_test_bit( counter, hint2 ) || - ps_mask_test_bit( counter, hint3 ) ) - break; - } - - /* create a new counter when needed */ - if ( count == 0 ) - { - error = ps_mask_table_alloc( &dim->counters, memory, &counter ); - if ( error ) - goto Exit; - } - - /* now, set the bits for our hints in the counter mask */ - error = ps_mask_set_bit( counter, hint1, memory ); - if ( error ) - goto Exit; - - error = ps_mask_set_bit( counter, hint2, memory ); - if ( error ) - goto Exit; - - error = ps_mask_set_bit( counter, hint3, memory ); - if ( error ) - goto Exit; - - Exit: - return error; - } - - - /* end of recording session for a given dimension */ - static FT_Error - ps_dimension_end( PS_Dimension dim, - FT_UInt end_point, - FT_Memory memory ) - { - /* end hint mask table */ - ps_dimension_end_mask( dim, end_point ); - - /* merge all counter masks into independent "paths" */ - return ps_mask_table_merge_all( &dim->counters, memory ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** PS_RECORDER MANAGEMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* destroy hints */ - FT_LOCAL( void ) - ps_hints_done( PS_Hints hints ) - { - FT_Memory memory = hints->memory; - - - ps_dimension_done( &hints->dimension[0], memory ); - ps_dimension_done( &hints->dimension[1], memory ); - - hints->error = FT_Err_Ok; - hints->memory = 0; - } - - - FT_LOCAL( FT_Error ) - ps_hints_init( PS_Hints hints, - FT_Memory memory ) - { - FT_MEM_ZERO( hints, sizeof ( *hints ) ); - hints->memory = memory; - return FT_Err_Ok; - } - - - /* initialize a hints for a new session */ - static void - ps_hints_open( PS_Hints hints, - PS_Hint_Type hint_type ) - { - switch ( hint_type ) - { - case PS_HINT_TYPE_1: - case PS_HINT_TYPE_2: - hints->error = FT_Err_Ok; - hints->hint_type = hint_type; - - ps_dimension_init( &hints->dimension[0] ); - ps_dimension_init( &hints->dimension[1] ); - break; - - default: - hints->error = FT_THROW( Invalid_Argument ); - hints->hint_type = hint_type; - - FT_TRACE0(( "ps_hints_open: invalid charstring type\n" )); - break; - } - } - - - /* add one or more stems to the current hints table */ - static void - ps_hints_stem( PS_Hints hints, - FT_Int dimension, - FT_UInt count, - FT_Long* stems ) - { - if ( !hints->error ) - { - /* limit "dimension" to 0..1 */ - if ( dimension < 0 || dimension > 1 ) - { - FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", - dimension )); - dimension = ( dimension != 0 ); - } - - /* record the stems in the current hints/masks table */ - switch ( hints->hint_type ) - { - case PS_HINT_TYPE_1: /* Type 1 "hstem" or "vstem" operator */ - case PS_HINT_TYPE_2: /* Type 2 "hstem" or "vstem" operator */ - { - PS_Dimension dim = &hints->dimension[dimension]; - - - for ( ; count > 0; count--, stems += 2 ) - { - FT_Error error; - FT_Memory memory = hints->memory; - - - error = ps_dimension_add_t1stem( - dim, (FT_Int)stems[0], (FT_Int)stems[1], - memory, NULL ); - if ( error ) - { - FT_ERROR(( "ps_hints_stem: could not add stem" - " (%d,%d) to hints table\n", stems[0], stems[1] )); - - hints->error = error; - return; - } - } - break; - } - - default: - FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n", - hints->hint_type )); - break; - } - } - } - - - /* add one Type1 counter stem to the current hints table */ - static void - ps_hints_t1stem3( PS_Hints hints, - FT_Int dimension, - FT_Fixed* stems ) - { - FT_Error error = FT_Err_Ok; - - - if ( !hints->error ) - { - PS_Dimension dim; - FT_Memory memory = hints->memory; - FT_Int count; - FT_Int idx[3]; - - - /* limit "dimension" to 0..1 */ - if ( dimension < 0 || dimension > 1 ) - { - FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n", - dimension )); - dimension = ( dimension != 0 ); - } - - dim = &hints->dimension[dimension]; - - /* there must be 6 elements in the 'stem' array */ - if ( hints->hint_type == PS_HINT_TYPE_1 ) - { - /* add the three stems to our hints/masks table */ - for ( count = 0; count < 3; count++, stems += 2 ) - { - error = ps_dimension_add_t1stem( dim, - (FT_Int)FIXED_TO_INT( stems[0] ), - (FT_Int)FIXED_TO_INT( stems[1] ), - memory, &idx[count] ); - if ( error ) - goto Fail; - } - - /* now, add the hints to the counters table */ - error = ps_dimension_add_counter( dim, idx[0], idx[1], idx[2], - memory ); - if ( error ) - goto Fail; - } - else - { - FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" )); - error = FT_THROW( Invalid_Argument ); - goto Fail; - } - } - - return; - - Fail: - FT_ERROR(( "ps_hints_t1stem3: could not add counter stems to table\n" )); - hints->error = error; - } - - - /* reset hints (only with Type 1 hints) */ - static void - ps_hints_t1reset( PS_Hints hints, - FT_UInt end_point ) - { - FT_Error error = FT_Err_Ok; - - - if ( !hints->error ) - { - FT_Memory memory = hints->memory; - - - if ( hints->hint_type == PS_HINT_TYPE_1 ) - { - error = ps_dimension_reset_mask( &hints->dimension[0], - end_point, memory ); - if ( error ) - goto Fail; - - error = ps_dimension_reset_mask( &hints->dimension[1], - end_point, memory ); - if ( error ) - goto Fail; - } - else - { - /* invalid hint type */ - error = FT_THROW( Invalid_Argument ); - goto Fail; - } - } - return; - - Fail: - hints->error = error; - } - - - /* Type2 "hintmask" operator, add a new hintmask to each direction */ - static void - ps_hints_t2mask( PS_Hints hints, - FT_UInt end_point, - FT_UInt bit_count, - const FT_Byte* bytes ) - { - FT_Error error; - - - if ( !hints->error ) - { - PS_Dimension dim = hints->dimension; - FT_Memory memory = hints->memory; - FT_UInt count1 = dim[0].hints.num_hints; - FT_UInt count2 = dim[1].hints.num_hints; - - - /* check bit count; must be equal to current total hint count */ - if ( bit_count != count1 + count2 ) - { - FT_TRACE0(( "ps_hints_t2mask:" - " called with invalid bitcount %d (instead of %d)\n", - bit_count, count1 + count2 )); - - /* simply ignore the operator */ - return; - } - - /* set-up new horizontal and vertical hint mask now */ - error = ps_dimension_set_mask_bits( &dim[0], bytes, count2, count1, - end_point, memory ); - if ( error ) - goto Fail; - - error = ps_dimension_set_mask_bits( &dim[1], bytes, 0, count2, - end_point, memory ); - if ( error ) - goto Fail; - } - return; - - Fail: - hints->error = error; - } - - - static void - ps_hints_t2counter( PS_Hints hints, - FT_UInt bit_count, - const FT_Byte* bytes ) - { - FT_Error error; - - - if ( !hints->error ) - { - PS_Dimension dim = hints->dimension; - FT_Memory memory = hints->memory; - FT_UInt count1 = dim[0].hints.num_hints; - FT_UInt count2 = dim[1].hints.num_hints; - - - /* check bit count, must be equal to current total hint count */ - if ( bit_count != count1 + count2 ) - { - FT_TRACE0(( "ps_hints_t2counter:" - " called with invalid bitcount %d (instead of %d)\n", - bit_count, count1 + count2 )); - - /* simply ignore the operator */ - return; - } - - /* set-up new horizontal and vertical hint mask now */ - error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1, - 0, memory ); - if ( error ) - goto Fail; - - error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2, - 0, memory ); - if ( error ) - goto Fail; - } - return; - - Fail: - hints->error = error; - } - - - /* end recording session */ - static FT_Error - ps_hints_close( PS_Hints hints, - FT_UInt end_point ) - { - FT_Error error; - - - error = hints->error; - if ( !error ) - { - FT_Memory memory = hints->memory; - PS_Dimension dim = hints->dimension; - - - error = ps_dimension_end( &dim[0], end_point, memory ); - if ( !error ) - { - error = ps_dimension_end( &dim[1], end_point, memory ); - } - } - -#ifdef DEBUG_HINTER - if ( !error ) - ps_debug_hints = hints; -#endif - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE 1 HINTS RECORDING INTERFACE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - t1_hints_open( T1_Hints hints ) - { - ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 ); - } - - static void - t1_hints_stem( T1_Hints hints, - FT_Int dimension, - FT_Fixed* coords ) - { - FT_Pos stems[2]; - - - stems[0] = FIXED_TO_INT( coords[0] ); - stems[1] = FIXED_TO_INT( coords[1] ); - - ps_hints_stem( (PS_Hints)hints, dimension, 1, stems ); - } - - - FT_LOCAL_DEF( void ) - t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ) - { - FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) ); - - funcs->open = (T1_Hints_OpenFunc) t1_hints_open; - funcs->close = (T1_Hints_CloseFunc) ps_hints_close; - funcs->stem = (T1_Hints_SetStemFunc) t1_hints_stem; - funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3; - funcs->reset = (T1_Hints_ResetFunc) ps_hints_t1reset; - funcs->apply = (T1_Hints_ApplyFunc) ps_hints_apply; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE 2 HINTS RECORDING INTERFACE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - t2_hints_open( T2_Hints hints ) - { - ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_2 ); - } - - - static void - t2_hints_stems( T2_Hints hints, - FT_Int dimension, - FT_Int count, - FT_Fixed* coords ) - { - FT_Pos stems[32], y, n; - FT_Int total = count; - - - y = 0; - while ( total > 0 ) - { - /* determine number of stems to write */ - count = total; - if ( count > 16 ) - count = 16; - - /* compute integer stem positions in font units */ - for ( n = 0; n < count * 2; n++ ) - { - y += coords[n]; - stems[n] = FIXED_TO_INT( y ); - } - - /* compute lengths */ - for ( n = 0; n < count * 2; n += 2 ) - stems[n + 1] = stems[n + 1] - stems[n]; - - /* add them to the current dimension */ - ps_hints_stem( (PS_Hints)hints, dimension, count, stems ); - - total -= count; - } - } - - - FT_LOCAL_DEF( void ) - t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ) - { - FT_MEM_ZERO( funcs, sizeof ( *funcs ) ); - - funcs->open = (T2_Hints_OpenFunc) t2_hints_open; - funcs->close = (T2_Hints_CloseFunc) ps_hints_close; - funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; - funcs->hintmask= (T2_Hints_MaskFunc) ps_hints_t2mask; - funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter; - funcs->apply = (T2_Hints_ApplyFunc) ps_hints_apply; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshrec.h b/drivers/freetype/freetype/src/pshinter/pshrec.h deleted file mode 100644 index dcb3197f94..0000000000 --- a/drivers/freetype/freetype/src/pshinter/pshrec.h +++ /dev/null @@ -1,176 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshrec.h */ -/* */ -/* Postscript (Type1/Type2) hints recorder (specification). */ -/* */ -/* Copyright 2001, 2002, 2003, 2006, 2008 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. */ -/* */ -/***************************************************************************/ - - - /**************************************************************************/ - /* */ - /* The functions defined here are called from the Type 1, CID and CFF */ - /* font drivers to record the hints of a given character/glyph. */ - /* */ - /* The hints are recorded in a unified format, and are later processed */ - /* by the `optimizer' and `fitter' to adjust the outlines to the pixel */ - /* grid. */ - /* */ - /**************************************************************************/ - - -#ifndef __PSHREC_H__ -#define __PSHREC_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_POSTSCRIPT_HINTS_H -#include "pshglob.h" - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH HINTS RECORDER INTERNALS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* handle to hint record */ - typedef struct PS_HintRec_* PS_Hint; - - /* hint types */ - typedef enum PS_Hint_Type_ - { - PS_HINT_TYPE_1 = 1, - PS_HINT_TYPE_2 = 2 - - } PS_Hint_Type; - - - /* hint flags */ - typedef enum PS_Hint_Flags_ - { - PS_HINT_FLAG_GHOST = 1, - PS_HINT_FLAG_BOTTOM = 2 - - } PS_Hint_Flags; - - - /* hint descriptor */ - typedef struct PS_HintRec_ - { - FT_Int pos; - FT_Int len; - FT_UInt flags; - - } PS_HintRec; - - -#define ps_hint_is_active( x ) ( (x)->flags & PS_HINT_FLAG_ACTIVE ) -#define ps_hint_is_ghost( x ) ( (x)->flags & PS_HINT_FLAG_GHOST ) -#define ps_hint_is_bottom( x ) ( (x)->flags & PS_HINT_FLAG_BOTTOM ) - - - /* hints table descriptor */ - typedef struct PS_Hint_TableRec_ - { - FT_UInt num_hints; - FT_UInt max_hints; - PS_Hint hints; - - } PS_Hint_TableRec, *PS_Hint_Table; - - - /* hint and counter mask descriptor */ - typedef struct PS_MaskRec_ - { - FT_UInt num_bits; - FT_UInt max_bits; - FT_Byte* bytes; - FT_UInt end_point; - - } PS_MaskRec, *PS_Mask; - - - /* masks and counters table descriptor */ - typedef struct PS_Mask_TableRec_ - { - FT_UInt num_masks; - FT_UInt max_masks; - PS_Mask masks; - - } PS_Mask_TableRec, *PS_Mask_Table; - - - /* dimension-specific hints descriptor */ - typedef struct PS_DimensionRec_ - { - PS_Hint_TableRec hints; - PS_Mask_TableRec masks; - PS_Mask_TableRec counters; - - } PS_DimensionRec, *PS_Dimension; - - - /* glyph hints descriptor */ - /* dimension 0 => X coordinates + vertical hints/stems */ - /* dimension 1 => Y coordinates + horizontal hints/stems */ - typedef struct PS_HintsRec_ - { - FT_Memory memory; - FT_Error error; - FT_UInt32 magic; - PS_Hint_Type hint_type; - PS_DimensionRec dimension[2]; - - } PS_HintsRec, *PS_Hints; - - /* */ - - /* initialize hints recorder */ - FT_LOCAL( FT_Error ) - ps_hints_init( PS_Hints hints, - FT_Memory memory ); - - /* finalize hints recorder */ - FT_LOCAL( void ) - ps_hints_done( PS_Hints hints ); - - /* initialize Type1 hints recorder interface */ - FT_LOCAL( void ) - t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ); - - /* initialize Type2 hints recorder interface */ - FT_LOCAL( void ) - t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ); - - -#ifdef DEBUG_HINTER - extern PS_Hints ps_debug_hints; - extern int ps_debug_no_horz_hints; - extern int ps_debug_no_vert_hints; -#endif - - /* */ - - -FT_END_HEADER - - -#endif /* __PS_HINTER_RECORD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/pshinter/rules.mk b/drivers/freetype/freetype/src/pshinter/rules.mk deleted file mode 100644 index 888ece1058..0000000000 --- a/drivers/freetype/freetype/src/pshinter/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 PSHinter driver configuration rules -# - - -# Copyright 2001, 2003, 2011 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. - - -# PSHINTER driver directory -# -PSHINTER_DIR := $(SRC_DIR)/pshinter - - -# compilation flags for the driver -# -PSHINTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) - - -# PSHINTER driver sources (i.e., C files) -# -PSHINTER_DRV_SRC := $(PSHINTER_DIR)/pshalgo.c \ - $(PSHINTER_DIR)/pshglob.c \ - $(PSHINTER_DIR)/pshmod.c \ - $(PSHINTER_DIR)/pshpic.c \ - $(PSHINTER_DIR)/pshrec.c - - -# PSHINTER driver headers -# -PSHINTER_DRV_H := $(PSHINTER_DRV_SRC:%c=%h) \ - $(PSHINTER_DIR)/pshnterr.h - - -# PSHINTER driver object(s) -# -# PSHINTER_DRV_OBJ_M is used during `multi' builds. -# PSHINTER_DRV_OBJ_S is used during `single' builds. -# -PSHINTER_DRV_OBJ_M := $(PSHINTER_DRV_SRC:$(PSHINTER_DIR)/%.c=$(OBJ_DIR)/%.$O) -PSHINTER_DRV_OBJ_S := $(OBJ_DIR)/pshinter.$O - -# PSHINTER driver source file for single build -# -PSHINTER_DRV_SRC_S := $(PSHINTER_DIR)/pshinter.c - - -# PSHINTER driver - single object -# -$(PSHINTER_DRV_OBJ_S): $(PSHINTER_DRV_SRC_S) $(PSHINTER_DRV_SRC) \ - $(FREETYPE_H) $(PSHINTER_DRV_H) - $(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSHINTER_DRV_SRC_S)) - - -# PSHINTER driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PSHINTER_DIR)/%.c $(FREETYPE_H) $(PSHINTER_DRV_H) - $(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PSHINTER_DRV_OBJ_S) -DRV_OBJS_M += $(PSHINTER_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/psnames/Jamfile b/drivers/freetype/freetype/src/psnames/Jamfile deleted file mode 100644 index 06c0dda66f..0000000000 --- a/drivers/freetype/freetype/src/psnames/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/psnames Jamfile -# -# Copyright 2001 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) psnames ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = psmodule pspic ; - } - else - { - _sources = psnames ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/psnames Jamfile diff --git a/drivers/freetype/freetype/src/psnames/module.mk b/drivers/freetype/freetype/src/psnames/module.mk deleted file mode 100644 index a6e908257c..0000000000 --- a/drivers/freetype/freetype/src/psnames/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 PSnames module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += PSNAMES_MODULE - -define PSNAMES_MODULE -$(OPEN_DRIVER) FT_Module_Class, psnames_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/psnames/psmodule.c b/drivers/freetype/freetype/src/psnames/psmodule.c deleted file mode 100644 index 0a5bcb7d2a..0000000000 --- a/drivers/freetype/freetype/src/psnames/psmodule.c +++ /dev/null @@ -1,609 +0,0 @@ -/***************************************************************************/ -/* */ -/* psmodule.c */ -/* */ -/* PSNames module implementation (body). */ -/* */ -/* Copyright 1996-2003, 2005-2008, 2012, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H - -#include "psmodule.h" -#include "pstables.h" - -#include "psnamerr.h" -#include "pspic.h" - - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - -#define VARIANT_BIT 0x80000000UL -#define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) ) - - - /* Return the Unicode value corresponding to a given glyph. Note that */ - /* we do deal with glyph variants by detecting a non-initial dot in */ - /* the name, as in `A.swash' or `e.final'; in this case, the */ - /* VARIANT_BIT is set in the return value. */ - /* */ - static FT_UInt32 - ps_unicode_value( const char* glyph_name ) - { - /* If the name begins with `uni', then the glyph name may be a */ - /* hard-coded unicode character code. */ - if ( glyph_name[0] == 'u' && - glyph_name[1] == 'n' && - glyph_name[2] == 'i' ) - { - /* determine whether the next four characters following are */ - /* hexadecimal. */ - - /* XXX: Add code to deal with ligatures, i.e. glyph names like */ - /* `uniXXXXYYYYZZZZ'... */ - - FT_Int count; - FT_UInt32 value = 0; - const char* p = glyph_name + 3; - - - for ( count = 4; count > 0; count--, p++ ) - { - char c = *p; - unsigned int d; - - - d = (unsigned char)c - '0'; - if ( d >= 10 ) - { - d = (unsigned char)c - 'A'; - if ( d >= 6 ) - d = 16; - else - d += 10; - } - - /* Exit if a non-uppercase hexadecimal character was found */ - /* -- this also catches character codes below `0' since such */ - /* negative numbers cast to `unsigned int' are far too big. */ - if ( d >= 16 ) - break; - - value = ( value << 4 ) + d; - } - - /* there must be exactly four hex digits */ - if ( count == 0 ) - { - if ( *p == '\0' ) - return value; - if ( *p == '.' ) - return (FT_UInt32)( value | VARIANT_BIT ); - } - } - - /* If the name begins with `u', followed by four to six uppercase */ - /* hexadecimal digits, it is a hard-coded unicode character code. */ - if ( glyph_name[0] == 'u' ) - { - FT_Int count; - FT_UInt32 value = 0; - const char* p = glyph_name + 1; - - - for ( count = 6; count > 0; count--, p++ ) - { - char c = *p; - unsigned int d; - - - d = (unsigned char)c - '0'; - if ( d >= 10 ) - { - d = (unsigned char)c - 'A'; - if ( d >= 6 ) - d = 16; - else - d += 10; - } - - if ( d >= 16 ) - break; - - value = ( value << 4 ) + d; - } - - if ( count <= 2 ) - { - if ( *p == '\0' ) - return value; - if ( *p == '.' ) - return (FT_UInt32)( value | VARIANT_BIT ); - } - } - - /* Look for a non-initial dot in the glyph name in order to */ - /* find variants like `A.swash', `e.final', etc. */ - { - const char* p = glyph_name; - const char* dot = NULL; - - - for ( ; *p; p++ ) - { - if ( *p == '.' && p > glyph_name ) - { - dot = p; - break; - } - } - - /* now look up the glyph in the Adobe Glyph List */ - if ( !dot ) - return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); - else - return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | - VARIANT_BIT ); - } - } - - - /* ft_qsort callback to sort the unicode map */ - FT_CALLBACK_DEF( int ) - compare_uni_maps( const void* a, - const void* b ) - { - PS_UniMap* map1 = (PS_UniMap*)a; - PS_UniMap* map2 = (PS_UniMap*)b; - FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode ); - FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode ); - - - /* sort base glyphs before glyph variants */ - if ( unicode1 == unicode2 ) - { - if ( map1->unicode > map2->unicode ) - return 1; - else if ( map1->unicode < map2->unicode ) - return -1; - else - return 0; - } - else - { - if ( unicode1 > unicode2 ) - return 1; - else if ( unicode1 < unicode2 ) - return -1; - else - return 0; - } - } - - - /* support for extra glyphs not handled (well) in AGL; */ - /* we add extra mappings for them if necessary */ - -#define EXTRA_GLYPH_LIST_SIZE 10 - - static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] = - { - /* WGL 4 */ - 0x0394, - 0x03A9, - 0x2215, - 0x00AD, - 0x02C9, - 0x03BC, - 0x2219, - 0x00A0, - /* Romanian */ - 0x021A, - 0x021B - }; - - static const char ft_extra_glyph_names[] = - { - 'D','e','l','t','a',0, - 'O','m','e','g','a',0, - 'f','r','a','c','t','i','o','n',0, - 'h','y','p','h','e','n',0, - 'm','a','c','r','o','n',0, - 'm','u',0, - 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0, - 's','p','a','c','e',0, - 'T','c','o','m','m','a','a','c','c','e','n','t',0, - 't','c','o','m','m','a','a','c','c','e','n','t',0 - }; - - static const FT_Int - ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] = - { - 0, - 6, - 12, - 21, - 28, - 35, - 38, - 53, - 59, - 72 - }; - - - static void - ps_check_extra_glyph_name( const char* gname, - FT_UInt glyph, - FT_UInt* extra_glyphs, - FT_UInt *states ) - { - FT_UInt n; - - - for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) - { - if ( ft_strcmp( ft_extra_glyph_names + - ft_extra_glyph_name_offsets[n], gname ) == 0 ) - { - if ( states[n] == 0 ) - { - /* mark this extra glyph as a candidate for the cmap */ - states[n] = 1; - extra_glyphs[n] = glyph; - } - - return; - } - } - } - - - static void - ps_check_extra_glyph_unicode( FT_UInt32 uni_char, - FT_UInt *states ) - { - FT_UInt n; - - - for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) - { - if ( uni_char == ft_extra_glyph_unicodes[n] ) - { - /* disable this extra glyph from being added to the cmap */ - states[n] = 2; - - return; - } - } - } - - - /* 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_GetGlyphNameFunc get_glyph_name, - PS_FreeGlyphNameFunc free_glyph_name, - FT_Pointer glyph_data ) - { - FT_Error error; - - FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE]; - - - /* we first allocate the table */ - table->num_maps = 0; - table->maps = 0; - - if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) - { - FT_UInt n; - FT_UInt count; - PS_UniMap* map; - FT_UInt32 uni_char; - - - map = table->maps; - - for ( n = 0; n < num_glyphs; n++ ) - { - const char* gname = get_glyph_name( glyph_data, n ); - - - if ( gname ) - { - ps_check_extra_glyph_name( gname, n, - extra_glyphs, extra_glyph_list_states ); - uni_char = ps_unicode_value( gname ); - - if ( BASE_GLYPH( uni_char ) != 0 ) - { - ps_check_extra_glyph_unicode( uni_char, - extra_glyph_list_states ); - map->unicode = uni_char; - map->glyph_index = n; - map++; - } - - if ( free_glyph_name ) - free_glyph_name( glyph_data, gname ); - } - } - - for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) - { - if ( extra_glyph_list_states[n] == 1 ) - { - /* This glyph name has an additional representation. */ - /* Add it to the cmap. */ - - map->unicode = ft_extra_glyph_unicodes[n]; - map->glyph_index = extra_glyphs[n]; - map++; - } - } - - /* now compress the table a bit */ - count = (FT_UInt)( map - table->maps ); - - if ( count == 0 ) - { - /* No unicode chars here! */ - FT_FREE( table->maps ); - if ( !error ) - error = FT_THROW( No_Unicode_Glyph_Name ); - } - else - { - /* Reallocate if the number of used entries is much smaller. */ - if ( count < num_glyphs / 2 ) - { - (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count ); - error = FT_Err_Ok; - } - - /* Sort the table in increasing order of unicode values, */ - /* taking care of glyph variants. */ - ft_qsort( table->maps, count, sizeof ( PS_UniMap ), - compare_uni_maps ); - } - - table->num_maps = count; - } - - return error; - } - - - static FT_UInt - ps_unicodes_char_index( PS_Unicodes table, - FT_UInt32 unicode ) - { - PS_UniMap *min, *max, *mid, *result = NULL; - - - /* Perform a binary search on the table. */ - - min = table->maps; - max = min + table->num_maps - 1; - - while ( min <= max ) - { - FT_UInt32 base_glyph; - - - mid = min + ( ( max - min ) >> 1 ); - - if ( mid->unicode == unicode ) - { - result = mid; - break; - } - - base_glyph = BASE_GLYPH( mid->unicode ); - - if ( base_glyph == unicode ) - result = mid; /* remember match but continue search for base glyph */ - - if ( min == max ) - break; - - if ( base_glyph < unicode ) - min = mid + 1; - else - max = mid - 1; - } - - if ( result ) - return result->glyph_index; - else - return 0; - } - - - static FT_UInt32 - ps_unicodes_char_next( PS_Unicodes table, - FT_UInt32 *unicode ) - { - FT_UInt result = 0; - FT_UInt32 char_code = *unicode + 1; - - - { - FT_UInt min = 0; - FT_UInt max = table->num_maps; - FT_UInt mid; - PS_UniMap* map; - FT_UInt32 base_glyph; - - - while ( min < max ) - { - mid = min + ( ( max - min ) >> 1 ); - map = table->maps + mid; - - if ( map->unicode == char_code ) - { - result = map->glyph_index; - goto Exit; - } - - base_glyph = BASE_GLYPH( map->unicode ); - - if ( base_glyph == char_code ) - result = map->glyph_index; - - if ( base_glyph < char_code ) - min = mid + 1; - else - max = mid; - } - - if ( result ) - goto Exit; /* we have a variant glyph */ - - /* we didn't find it; check whether we have a map just above it */ - char_code = 0; - - if ( min < table->num_maps ) - { - map = table->maps + min; - result = map->glyph_index; - char_code = BASE_GLYPH( map->unicode ); - } - } - - Exit: - *unicode = char_code; - return result; - } - - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - - static const char* - ps_get_macintosh_name( FT_UInt name_index ) - { - if ( name_index >= FT_NUM_MAC_NAMES ) - name_index = 0; - - return ft_standard_glyph_names + ft_mac_names[name_index]; - } - - - static const char* - ps_get_standard_strings( FT_UInt sid ) - { - if ( sid >= FT_NUM_SID_NAMES ) - return 0; - - return ft_standard_glyph_names + ft_sid_names[sid]; - } - - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - FT_DEFINE_SERVICE_PSCMAPSREC( - pscmaps_interface, - (PS_Unicode_ValueFunc) ps_unicode_value, - (PS_Unicodes_InitFunc) ps_unicodes_init, - (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, - (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, - - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, - - t1_standard_encoding, - t1_expert_encoding ) - -#else - - FT_DEFINE_SERVICE_PSCMAPSREC( - pscmaps_interface, - NULL, - NULL, - NULL, - NULL, - - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, - - t1_standard_encoding, - t1_expert_encoding ) - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - - FT_DEFINE_SERVICEDESCREC1( - pscmaps_services, - FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET ) - - - static FT_Pointer - psnames_get_service( FT_Module module, - const char* service_id ) - { - /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - FT_Library library; - - - if ( !module ) - return NULL; - library = module->library; - if ( !library ) - return NULL; -#else - FT_UNUSED( module ); -#endif - - return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id ); - } - -#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - -#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES -#define PUT_PS_NAMES_SERVICE( a ) NULL -#else -#define PUT_PS_NAMES_SERVICE( a ) a -#endif - - FT_DEFINE_MODULE( - psnames_module_class, - - 0, /* this is not a font driver, nor a renderer */ - sizeof ( FT_ModuleRec ), - - "psnames", /* driver name */ - 0x10000L, /* driver version */ - 0x20000L, /* driver requires FreeType 2 or above */ - - PUT_PS_NAMES_SERVICE( - (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */ - (FT_Module_Constructor)NULL, - (FT_Module_Destructor) NULL, - (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/psnames/psmodule.h b/drivers/freetype/freetype/src/psnames/psmodule.h deleted file mode 100644 index 28fa14807c..0000000000 --- a/drivers/freetype/freetype/src/psnames/psmodule.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************/ -/* */ -/* psmodule.h */ -/* */ -/* High-level PSNames module interface (specification). */ -/* */ -/* Copyright 1996-2001 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 __PSMODULE_H__ -#define __PSMODULE_H__ - - -#include <ft2build.h> -#include FT_MODULE_H - - -FT_BEGIN_HEADER - - - FT_DECLARE_MODULE( psnames_module_class ) - - -FT_END_HEADER - -#endif /* __PSMODULE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psnames/psnamerr.h b/drivers/freetype/freetype/src/psnames/psnamerr.h deleted file mode 100644 index acda7f967e..0000000000 --- a/drivers/freetype/freetype/src/psnames/psnamerr.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* psnamerr.h */ -/* */ -/* PS names module error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PS names module error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ - -#ifndef __PSNAMERR_H__ -#define __PSNAMERR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PSnames_Err_ -#define FT_ERR_BASE FT_Mod_Err_PSnames - -#include FT_ERRORS_H - -#endif /* __PSNAMERR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psnames/psnames.c b/drivers/freetype/freetype/src/psnames/psnames.c deleted file mode 100644 index 1ede225dc9..0000000000 --- a/drivers/freetype/freetype/src/psnames/psnames.c +++ /dev/null @@ -1,26 +0,0 @@ -/***************************************************************************/ -/* */ -/* psnames.c */ -/* */ -/* FreeType PSNames module component (body only). */ -/* */ -/* Copyright 1996-2001 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "pspic.c" -#include "psmodule.c" - - -/* END */ diff --git a/drivers/freetype/freetype/src/psnames/pspic.c b/drivers/freetype/freetype/src/psnames/pspic.c deleted file mode 100644 index 3820f65a74..0000000000 --- a/drivers/freetype/freetype/src/psnames/pspic.c +++ /dev/null @@ -1,97 +0,0 @@ -/***************************************************************************/ -/* */ -/* pspic.c */ -/* */ -/* The FreeType position independent code services for psnames module. */ -/* */ -/* Copyright 2009, 2010, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "pspic.h" -#include "psnamerr.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from psmodule.c */ - FT_Error - FT_Create_Class_pscmaps_services( FT_Library library, - FT_ServiceDescRec** output_class ); - void - FT_Destroy_Class_pscmaps_services( FT_Library library, - FT_ServiceDescRec* clazz ); - - void - FT_Init_Class_pscmaps_interface( FT_Library library, - FT_Service_PsCMapsRec* clazz ); - - - void - psnames_module_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->psnames ) - { - PSModulePIC* container = (PSModulePIC*)pic_container->psnames; - - - if ( container->pscmaps_services ) - FT_Destroy_Class_pscmaps_services( library, - container->pscmaps_services ); - container->pscmaps_services = NULL; - FT_FREE( container ); - pic_container->psnames = NULL; - } - } - - - FT_Error - psnames_module_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - PSModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->psnames = container; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - error = FT_Create_Class_pscmaps_services( - library, &container->pscmaps_services ); - if ( error ) - goto Exit; - FT_Init_Class_pscmaps_interface( library, - &container->pscmaps_interface ); - - Exit: - if ( error ) - psnames_module_class_pic_free( library ); - return error; - } - - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psnames/pspic.h b/drivers/freetype/freetype/src/psnames/pspic.h deleted file mode 100644 index 6ff002c603..0000000000 --- a/drivers/freetype/freetype/src/psnames/pspic.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************/ -/* */ -/* pspic.h */ -/* */ -/* The FreeType position independent code services for psnames module. */ -/* */ -/* Copyright 2009, 2012 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __PSPIC_H__ -#define __PSPIC_H__ - - -FT_BEGIN_HEADER - -#include FT_INTERNAL_PIC_H - -#ifndef FT_CONFIG_OPTION_PIC - -#define PSCMAPS_SERVICES_GET pscmaps_services -#define PSCMAPS_INTERFACE_GET pscmaps_interface - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_SERVICE_POSTSCRIPT_CMAPS_H - - typedef struct PSModulePIC_ - { - FT_ServiceDescRec* pscmaps_services; - FT_Service_PsCMapsRec pscmaps_interface; - - } PSModulePIC; - - -#define GET_PIC( lib ) \ - ( (PSModulePIC*)((lib)->pic_container.psnames) ) -#define PSCMAPS_SERVICES_GET ( GET_PIC( library )->pscmaps_services ) -#define PSCMAPS_INTERFACE_GET ( GET_PIC( library )->pscmaps_interface ) - - - /* see pspic.c for the implementation */ - void - psnames_module_class_pic_free( FT_Library library ); - - FT_Error - psnames_module_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __PSPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psnames/pstables.h b/drivers/freetype/freetype/src/psnames/pstables.h deleted file mode 100644 index 0a6637f985..0000000000 --- a/drivers/freetype/freetype/src/psnames/pstables.h +++ /dev/null @@ -1,4170 +0,0 @@ -/***************************************************************************/ -/* */ -/* pstables.h */ -/* */ -/* PostScript glyph names. */ -/* */ -/* Copyright 2005, 2008, 2011 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. */ -/* */ -/***************************************************************************/ - - - /* This file has been generated automatically -- do not edit! */ - - - static const char ft_standard_glyph_names[3696] = - { - '.','n','u','l','l', 0, - 'n','o','n','m','a','r','k','i','n','g','r','e','t','u','r','n', 0, - 'n','o','t','e','q','u','a','l', 0, - 'i','n','f','i','n','i','t','y', 0, - 'l','e','s','s','e','q','u','a','l', 0, - 'g','r','e','a','t','e','r','e','q','u','a','l', 0, - 'p','a','r','t','i','a','l','d','i','f','f', 0, - 's','u','m','m','a','t','i','o','n', 0, - 'p','r','o','d','u','c','t', 0, - 'p','i', 0, - 'i','n','t','e','g','r','a','l', 0, - 'O','m','e','g','a', 0, - 'r','a','d','i','c','a','l', 0, - 'a','p','p','r','o','x','e','q','u','a','l', 0, - 'D','e','l','t','a', 0, - 'n','o','n','b','r','e','a','k','i','n','g','s','p','a','c','e', 0, - 'l','o','z','e','n','g','e', 0, - 'a','p','p','l','e', 0, - 'f','r','a','n','c', 0, - 'G','b','r','e','v','e', 0, - 'g','b','r','e','v','e', 0, - 'I','d','o','t','a','c','c','e','n','t', 0, - 'S','c','e','d','i','l','l','a', 0, - 's','c','e','d','i','l','l','a', 0, - 'C','a','c','u','t','e', 0, - 'c','a','c','u','t','e', 0, - 'C','c','a','r','o','n', 0, - 'c','c','a','r','o','n', 0, - 'd','c','r','o','a','t', 0, - '.','n','o','t','d','e','f', 0, - 's','p','a','c','e', 0, - 'e','x','c','l','a','m', 0, - 'q','u','o','t','e','d','b','l', 0, - 'n','u','m','b','e','r','s','i','g','n', 0, - 'd','o','l','l','a','r', 0, - 'p','e','r','c','e','n','t', 0, - 'a','m','p','e','r','s','a','n','d', 0, - 'q','u','o','t','e','r','i','g','h','t', 0, - 'p','a','r','e','n','l','e','f','t', 0, - 'p','a','r','e','n','r','i','g','h','t', 0, - 'a','s','t','e','r','i','s','k', 0, - 'p','l','u','s', 0, - 'c','o','m','m','a', 0, - 'h','y','p','h','e','n', 0, - 'p','e','r','i','o','d', 0, - 's','l','a','s','h', 0, - 'z','e','r','o', 0, - 'o','n','e', 0, - 't','w','o', 0, - 't','h','r','e','e', 0, - 'f','o','u','r', 0, - 'f','i','v','e', 0, - 's','i','x', 0, - 's','e','v','e','n', 0, - 'e','i','g','h','t', 0, - 'n','i','n','e', 0, - 'c','o','l','o','n', 0, - 's','e','m','i','c','o','l','o','n', 0, - 'l','e','s','s', 0, - 'e','q','u','a','l', 0, - 'g','r','e','a','t','e','r', 0, - 'q','u','e','s','t','i','o','n', 0, - 'a','t', 0, - 'A', 0, - 'B', 0, - 'C', 0, - 'D', 0, - 'E', 0, - 'F', 0, - 'G', 0, - 'H', 0, - 'I', 0, - 'J', 0, - 'K', 0, - 'L', 0, - 'M', 0, - 'N', 0, - 'O', 0, - 'P', 0, - 'Q', 0, - 'R', 0, - 'S', 0, - 'T', 0, - 'U', 0, - 'V', 0, - 'W', 0, - 'X', 0, - 'Y', 0, - 'Z', 0, - 'b','r','a','c','k','e','t','l','e','f','t', 0, - 'b','a','c','k','s','l','a','s','h', 0, - 'b','r','a','c','k','e','t','r','i','g','h','t', 0, - 'a','s','c','i','i','c','i','r','c','u','m', 0, - 'u','n','d','e','r','s','c','o','r','e', 0, - 'q','u','o','t','e','l','e','f','t', 0, - 'a', 0, - 'b', 0, - 'c', 0, - 'd', 0, - 'e', 0, - 'f', 0, - 'g', 0, - 'h', 0, - 'i', 0, - 'j', 0, - 'k', 0, - 'l', 0, - 'm', 0, - 'n', 0, - 'o', 0, - 'p', 0, - 'q', 0, - 'r', 0, - 's', 0, - 't', 0, - 'u', 0, - 'v', 0, - 'w', 0, - 'x', 0, - 'y', 0, - 'z', 0, - 'b','r','a','c','e','l','e','f','t', 0, - 'b','a','r', 0, - 'b','r','a','c','e','r','i','g','h','t', 0, - 'a','s','c','i','i','t','i','l','d','e', 0, - 'e','x','c','l','a','m','d','o','w','n', 0, - 'c','e','n','t', 0, - 's','t','e','r','l','i','n','g', 0, - 'f','r','a','c','t','i','o','n', 0, - 'y','e','n', 0, - 'f','l','o','r','i','n', 0, - 's','e','c','t','i','o','n', 0, - 'c','u','r','r','e','n','c','y', 0, - 'q','u','o','t','e','s','i','n','g','l','e', 0, - 'q','u','o','t','e','d','b','l','l','e','f','t', 0, - 'g','u','i','l','l','e','m','o','t','l','e','f','t', 0, - 'g','u','i','l','s','i','n','g','l','l','e','f','t', 0, - 'g','u','i','l','s','i','n','g','l','r','i','g','h','t', 0, - 'f','i', 0, - 'f','l', 0, - 'e','n','d','a','s','h', 0, - 'd','a','g','g','e','r', 0, - 'd','a','g','g','e','r','d','b','l', 0, - 'p','e','r','i','o','d','c','e','n','t','e','r','e','d', 0, - 'p','a','r','a','g','r','a','p','h', 0, - 'b','u','l','l','e','t', 0, - 'q','u','o','t','e','s','i','n','g','l','b','a','s','e', 0, - 'q','u','o','t','e','d','b','l','b','a','s','e', 0, - 'q','u','o','t','e','d','b','l','r','i','g','h','t', 0, - 'g','u','i','l','l','e','m','o','t','r','i','g','h','t', 0, - 'e','l','l','i','p','s','i','s', 0, - 'p','e','r','t','h','o','u','s','a','n','d', 0, - 'q','u','e','s','t','i','o','n','d','o','w','n', 0, - 'g','r','a','v','e', 0, - 'a','c','u','t','e', 0, - 'c','i','r','c','u','m','f','l','e','x', 0, - 't','i','l','d','e', 0, - 'm','a','c','r','o','n', 0, - 'b','r','e','v','e', 0, - 'd','o','t','a','c','c','e','n','t', 0, - 'd','i','e','r','e','s','i','s', 0, - 'r','i','n','g', 0, - 'c','e','d','i','l','l','a', 0, - 'h','u','n','g','a','r','u','m','l','a','u','t', 0, - 'o','g','o','n','e','k', 0, - 'c','a','r','o','n', 0, - 'e','m','d','a','s','h', 0, - 'A','E', 0, - 'o','r','d','f','e','m','i','n','i','n','e', 0, - 'L','s','l','a','s','h', 0, - 'O','s','l','a','s','h', 0, - 'O','E', 0, - 'o','r','d','m','a','s','c','u','l','i','n','e', 0, - 'a','e', 0, - 'd','o','t','l','e','s','s','i', 0, - 'l','s','l','a','s','h', 0, - 'o','s','l','a','s','h', 0, - 'o','e', 0, - 'g','e','r','m','a','n','d','b','l','s', 0, - 'o','n','e','s','u','p','e','r','i','o','r', 0, - 'l','o','g','i','c','a','l','n','o','t', 0, - 'm','u', 0, - 't','r','a','d','e','m','a','r','k', 0, - 'E','t','h', 0, - 'o','n','e','h','a','l','f', 0, - 'p','l','u','s','m','i','n','u','s', 0, - 'T','h','o','r','n', 0, - 'o','n','e','q','u','a','r','t','e','r', 0, - 'd','i','v','i','d','e', 0, - 'b','r','o','k','e','n','b','a','r', 0, - 'd','e','g','r','e','e', 0, - 't','h','o','r','n', 0, - 't','h','r','e','e','q','u','a','r','t','e','r','s', 0, - 't','w','o','s','u','p','e','r','i','o','r', 0, - 'r','e','g','i','s','t','e','r','e','d', 0, - 'm','i','n','u','s', 0, - 'e','t','h', 0, - 'm','u','l','t','i','p','l','y', 0, - 't','h','r','e','e','s','u','p','e','r','i','o','r', 0, - 'c','o','p','y','r','i','g','h','t', 0, - 'A','a','c','u','t','e', 0, - 'A','c','i','r','c','u','m','f','l','e','x', 0, - 'A','d','i','e','r','e','s','i','s', 0, - 'A','g','r','a','v','e', 0, - 'A','r','i','n','g', 0, - 'A','t','i','l','d','e', 0, - 'C','c','e','d','i','l','l','a', 0, - 'E','a','c','u','t','e', 0, - 'E','c','i','r','c','u','m','f','l','e','x', 0, - 'E','d','i','e','r','e','s','i','s', 0, - 'E','g','r','a','v','e', 0, - 'I','a','c','u','t','e', 0, - 'I','c','i','r','c','u','m','f','l','e','x', 0, - 'I','d','i','e','r','e','s','i','s', 0, - 'I','g','r','a','v','e', 0, - 'N','t','i','l','d','e', 0, - 'O','a','c','u','t','e', 0, - 'O','c','i','r','c','u','m','f','l','e','x', 0, - 'O','d','i','e','r','e','s','i','s', 0, - 'O','g','r','a','v','e', 0, - 'O','t','i','l','d','e', 0, - 'S','c','a','r','o','n', 0, - 'U','a','c','u','t','e', 0, - 'U','c','i','r','c','u','m','f','l','e','x', 0, - 'U','d','i','e','r','e','s','i','s', 0, - 'U','g','r','a','v','e', 0, - 'Y','a','c','u','t','e', 0, - 'Y','d','i','e','r','e','s','i','s', 0, - 'Z','c','a','r','o','n', 0, - 'a','a','c','u','t','e', 0, - 'a','c','i','r','c','u','m','f','l','e','x', 0, - 'a','d','i','e','r','e','s','i','s', 0, - 'a','g','r','a','v','e', 0, - 'a','r','i','n','g', 0, - 'a','t','i','l','d','e', 0, - 'c','c','e','d','i','l','l','a', 0, - 'e','a','c','u','t','e', 0, - 'e','c','i','r','c','u','m','f','l','e','x', 0, - 'e','d','i','e','r','e','s','i','s', 0, - 'e','g','r','a','v','e', 0, - 'i','a','c','u','t','e', 0, - 'i','c','i','r','c','u','m','f','l','e','x', 0, - 'i','d','i','e','r','e','s','i','s', 0, - 'i','g','r','a','v','e', 0, - 'n','t','i','l','d','e', 0, - 'o','a','c','u','t','e', 0, - 'o','c','i','r','c','u','m','f','l','e','x', 0, - 'o','d','i','e','r','e','s','i','s', 0, - 'o','g','r','a','v','e', 0, - 'o','t','i','l','d','e', 0, - 's','c','a','r','o','n', 0, - 'u','a','c','u','t','e', 0, - 'u','c','i','r','c','u','m','f','l','e','x', 0, - 'u','d','i','e','r','e','s','i','s', 0, - 'u','g','r','a','v','e', 0, - 'y','a','c','u','t','e', 0, - 'y','d','i','e','r','e','s','i','s', 0, - 'z','c','a','r','o','n', 0, - 'e','x','c','l','a','m','s','m','a','l','l', 0, - 'H','u','n','g','a','r','u','m','l','a','u','t','s','m','a','l','l', 0, - 'd','o','l','l','a','r','o','l','d','s','t','y','l','e', 0, - 'd','o','l','l','a','r','s','u','p','e','r','i','o','r', 0, - 'a','m','p','e','r','s','a','n','d','s','m','a','l','l', 0, - 'A','c','u','t','e','s','m','a','l','l', 0, - 'p','a','r','e','n','l','e','f','t','s','u','p','e','r','i','o','r', 0, - 'p','a','r','e','n','r','i','g','h','t','s','u','p','e','r','i','o','r', 0, - 't','w','o','d','o','t','e','n','l','e','a','d','e','r', 0, - 'o','n','e','d','o','t','e','n','l','e','a','d','e','r', 0, - 'z','e','r','o','o','l','d','s','t','y','l','e', 0, - 'o','n','e','o','l','d','s','t','y','l','e', 0, - 't','w','o','o','l','d','s','t','y','l','e', 0, - 't','h','r','e','e','o','l','d','s','t','y','l','e', 0, - 'f','o','u','r','o','l','d','s','t','y','l','e', 0, - 'f','i','v','e','o','l','d','s','t','y','l','e', 0, - 's','i','x','o','l','d','s','t','y','l','e', 0, - 's','e','v','e','n','o','l','d','s','t','y','l','e', 0, - 'e','i','g','h','t','o','l','d','s','t','y','l','e', 0, - 'n','i','n','e','o','l','d','s','t','y','l','e', 0, - 'c','o','m','m','a','s','u','p','e','r','i','o','r', 0, - 't','h','r','e','e','q','u','a','r','t','e','r','s','e','m','d','a','s','h', 0, - 'p','e','r','i','o','d','s','u','p','e','r','i','o','r', 0, - 'q','u','e','s','t','i','o','n','s','m','a','l','l', 0, - 'a','s','u','p','e','r','i','o','r', 0, - 'b','s','u','p','e','r','i','o','r', 0, - 'c','e','n','t','s','u','p','e','r','i','o','r', 0, - 'd','s','u','p','e','r','i','o','r', 0, - 'e','s','u','p','e','r','i','o','r', 0, - 'i','s','u','p','e','r','i','o','r', 0, - 'l','s','u','p','e','r','i','o','r', 0, - 'm','s','u','p','e','r','i','o','r', 0, - 'n','s','u','p','e','r','i','o','r', 0, - 'o','s','u','p','e','r','i','o','r', 0, - 'r','s','u','p','e','r','i','o','r', 0, - 's','s','u','p','e','r','i','o','r', 0, - 't','s','u','p','e','r','i','o','r', 0, - 'f','f', 0, - 'f','f','i', 0, - 'f','f','l', 0, - 'p','a','r','e','n','l','e','f','t','i','n','f','e','r','i','o','r', 0, - 'p','a','r','e','n','r','i','g','h','t','i','n','f','e','r','i','o','r', 0, - 'C','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, - 'h','y','p','h','e','n','s','u','p','e','r','i','o','r', 0, - 'G','r','a','v','e','s','m','a','l','l', 0, - 'A','s','m','a','l','l', 0, - 'B','s','m','a','l','l', 0, - 'C','s','m','a','l','l', 0, - 'D','s','m','a','l','l', 0, - 'E','s','m','a','l','l', 0, - 'F','s','m','a','l','l', 0, - 'G','s','m','a','l','l', 0, - 'H','s','m','a','l','l', 0, - 'I','s','m','a','l','l', 0, - 'J','s','m','a','l','l', 0, - 'K','s','m','a','l','l', 0, - 'L','s','m','a','l','l', 0, - 'M','s','m','a','l','l', 0, - 'N','s','m','a','l','l', 0, - 'O','s','m','a','l','l', 0, - 'P','s','m','a','l','l', 0, - 'Q','s','m','a','l','l', 0, - 'R','s','m','a','l','l', 0, - 'S','s','m','a','l','l', 0, - 'T','s','m','a','l','l', 0, - 'U','s','m','a','l','l', 0, - 'V','s','m','a','l','l', 0, - 'W','s','m','a','l','l', 0, - 'X','s','m','a','l','l', 0, - 'Y','s','m','a','l','l', 0, - 'Z','s','m','a','l','l', 0, - 'c','o','l','o','n','m','o','n','e','t','a','r','y', 0, - 'o','n','e','f','i','t','t','e','d', 0, - 'r','u','p','i','a','h', 0, - 'T','i','l','d','e','s','m','a','l','l', 0, - 'e','x','c','l','a','m','d','o','w','n','s','m','a','l','l', 0, - 'c','e','n','t','o','l','d','s','t','y','l','e', 0, - 'L','s','l','a','s','h','s','m','a','l','l', 0, - 'S','c','a','r','o','n','s','m','a','l','l', 0, - 'Z','c','a','r','o','n','s','m','a','l','l', 0, - 'D','i','e','r','e','s','i','s','s','m','a','l','l', 0, - 'B','r','e','v','e','s','m','a','l','l', 0, - 'C','a','r','o','n','s','m','a','l','l', 0, - 'D','o','t','a','c','c','e','n','t','s','m','a','l','l', 0, - 'M','a','c','r','o','n','s','m','a','l','l', 0, - 'f','i','g','u','r','e','d','a','s','h', 0, - 'h','y','p','h','e','n','i','n','f','e','r','i','o','r', 0, - 'O','g','o','n','e','k','s','m','a','l','l', 0, - 'R','i','n','g','s','m','a','l','l', 0, - 'C','e','d','i','l','l','a','s','m','a','l','l', 0, - 'q','u','e','s','t','i','o','n','d','o','w','n','s','m','a','l','l', 0, - 'o','n','e','e','i','g','h','t','h', 0, - 't','h','r','e','e','e','i','g','h','t','h','s', 0, - 'f','i','v','e','e','i','g','h','t','h','s', 0, - 's','e','v','e','n','e','i','g','h','t','h','s', 0, - 'o','n','e','t','h','i','r','d', 0, - 't','w','o','t','h','i','r','d','s', 0, - 'z','e','r','o','s','u','p','e','r','i','o','r', 0, - 'f','o','u','r','s','u','p','e','r','i','o','r', 0, - 'f','i','v','e','s','u','p','e','r','i','o','r', 0, - 's','i','x','s','u','p','e','r','i','o','r', 0, - 's','e','v','e','n','s','u','p','e','r','i','o','r', 0, - 'e','i','g','h','t','s','u','p','e','r','i','o','r', 0, - 'n','i','n','e','s','u','p','e','r','i','o','r', 0, - 'z','e','r','o','i','n','f','e','r','i','o','r', 0, - 'o','n','e','i','n','f','e','r','i','o','r', 0, - 't','w','o','i','n','f','e','r','i','o','r', 0, - 't','h','r','e','e','i','n','f','e','r','i','o','r', 0, - 'f','o','u','r','i','n','f','e','r','i','o','r', 0, - 'f','i','v','e','i','n','f','e','r','i','o','r', 0, - 's','i','x','i','n','f','e','r','i','o','r', 0, - 's','e','v','e','n','i','n','f','e','r','i','o','r', 0, - 'e','i','g','h','t','i','n','f','e','r','i','o','r', 0, - 'n','i','n','e','i','n','f','e','r','i','o','r', 0, - 'c','e','n','t','i','n','f','e','r','i','o','r', 0, - 'd','o','l','l','a','r','i','n','f','e','r','i','o','r', 0, - 'p','e','r','i','o','d','i','n','f','e','r','i','o','r', 0, - 'c','o','m','m','a','i','n','f','e','r','i','o','r', 0, - 'A','g','r','a','v','e','s','m','a','l','l', 0, - 'A','a','c','u','t','e','s','m','a','l','l', 0, - 'A','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, - 'A','t','i','l','d','e','s','m','a','l','l', 0, - 'A','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, - 'A','r','i','n','g','s','m','a','l','l', 0, - 'A','E','s','m','a','l','l', 0, - 'C','c','e','d','i','l','l','a','s','m','a','l','l', 0, - 'E','g','r','a','v','e','s','m','a','l','l', 0, - 'E','a','c','u','t','e','s','m','a','l','l', 0, - 'E','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, - 'E','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, - 'I','g','r','a','v','e','s','m','a','l','l', 0, - 'I','a','c','u','t','e','s','m','a','l','l', 0, - 'I','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, - 'I','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, - 'E','t','h','s','m','a','l','l', 0, - 'N','t','i','l','d','e','s','m','a','l','l', 0, - 'O','g','r','a','v','e','s','m','a','l','l', 0, - 'O','a','c','u','t','e','s','m','a','l','l', 0, - 'O','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, - 'O','t','i','l','d','e','s','m','a','l','l', 0, - 'O','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, - 'O','E','s','m','a','l','l', 0, - 'O','s','l','a','s','h','s','m','a','l','l', 0, - 'U','g','r','a','v','e','s','m','a','l','l', 0, - 'U','a','c','u','t','e','s','m','a','l','l', 0, - 'U','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, - 'U','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, - 'Y','a','c','u','t','e','s','m','a','l','l', 0, - 'T','h','o','r','n','s','m','a','l','l', 0, - 'Y','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, - '0','0','1','.','0','0','0', 0, - '0','0','1','.','0','0','1', 0, - '0','0','1','.','0','0','2', 0, - '0','0','1','.','0','0','3', 0, - 'B','l','a','c','k', 0, - 'B','o','l','d', 0, - 'B','o','o','k', 0, - 'L','i','g','h','t', 0, - 'M','e','d','i','u','m', 0, - 'R','e','g','u','l','a','r', 0, - 'R','o','m','a','n', 0, - 'S','e','m','i','b','o','l','d', 0, - }; - - -#define FT_NUM_MAC_NAMES 258 - - /* Values are offsets into the `ft_standard_glyph_names' table */ - - static const short ft_mac_names[FT_NUM_MAC_NAMES] = - { - 253, 0, 6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351, - 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, - 436, 441, 447, 457, 462, 468, 476, 485, 488, 490, 492, 494, 496, 498, - 500, 502, 504, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, - 528, 530, 532, 534, 536, 538, 540, 552, 562, 575, 587, 979, 608, 610, - 612, 614, 616, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, - 640, 642, 644, 646, 648, 650, 652, 654, 656, 658, 660, 670, 674, 685, - 1375,1392,1405,1414,1486,1512,1562,1603,1632,1610,1622,1645,1639,1652, - 1661,1690,1668,1680,1697,1726,1704,1716,1733,1740,1769,1747,1759,1776, - 1790,1819,1797,1809, 839,1263, 707, 712, 741, 881, 871,1160,1302,1346, - 1197, 985,1031, 23,1086,1108, 32,1219, 41, 51, 730,1194, 64, 76, - 86, 94, 97,1089,1118, 106,1131,1150, 966, 696,1183, 112, 734, 120, - 132, 783, 930, 945, 138,1385,1398,1529,1115,1157, 832,1079, 770, 916, - 598, 319,1246, 155,1833,1586, 721, 749, 797, 811, 826, 829, 846, 856, - 888, 903, 954,1363,1421,1356,1433,1443,1450,1457,1469,1479,1493,1500, - 163,1522,1543,1550,1572,1134, 991,1002,1008,1015,1021,1040,1045,1053, - 1066,1073,1101,1143,1536,1783,1596,1843,1253,1207,1319,1579,1826,1229, - 1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200, - 209, 218, 225, 232, 239, 246 - }; - - -#define FT_NUM_SID_NAMES 391 - - /* Values are offsets into the `ft_standard_glyph_names' table */ - - static const short ft_sid_names[FT_NUM_SID_NAMES] = - { - 253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365, - 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, 436, 441, - 447, 457, 462, 468, 476, 485, 488, 490, 492, 494, 496, 498, 500, 502, - 504, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530, - 532, 534, 536, 538, 540, 552, 562, 575, 587, 598, 608, 610, 612, 614, - 616, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, 640, 642, - 644, 646, 648, 650, 652, 654, 656, 658, 660, 670, 674, 685, 696, 707, - 712, 721, 730, 734, 741, 749, 758, 770, 783, 797, 811, 826, 829, 832, - 839, 846, 856, 871, 881, 888, 903, 916, 930, 945, 954, 966, 979, 985, - 991,1002,1008,1015,1021,1031,1040,1045,1053,1066,1073,1079,1086,1089, - 1101,1108,1115,1118,1131,1134,1143,1150,1157,1160,1171,1183,1194,1197, - 1207,1211,1219,1229,1235,1246,1253,1263,1270,1276,1290,1302,1313,1319, - 1323,1332,1346,1356,1363,1375,1385,1392,1398,1405,1414,1421,1433,1443, - 1450,1457,1469,1479,1486,1493,1500,1512,1522,1529,1536,1543,1550,1562, - 1572,1579,1586,1596,1603,1610,1622,1632,1639,1645,1652,1661,1668,1680, - 1690,1697,1704,1716,1726,1733,1740,1747,1759,1769,1776,1783,1790,1797, - 1809,1819,1826,1833,1843,1850,1862,1880,1895,1910,1925,1936,1954,1973, - 1988,2003,2016,2028,2040,2054,2067,2080,2092,2106,2120,2133,2147,2167, - 2182,2196,2206,2216,2229,2239,2249,2259,2269,2279,2289,2299,2309,2319, - 2329,2332,2336,2340,2358,2377,2393,2408,2419,2426,2433,2440,2447,2454, - 2461,2468,2475,2482,2489,2496,2503,2510,2517,2524,2531,2538,2545,2552, - 2559,2566,2573,2580,2587,2594,2601,2615,2625,2632,2643,2659,2672,2684, - 2696,2708,2722,2733,2744,2759,2771,2782,2797,2809,2819,2832,2850,2860, - 2873,2885,2898,2907,2917,2930,2943,2956,2968,2982,2996,3009,3022,3034, - 3046,3060,3073,3086,3098,3112,3126,3139,3152,3167,3182,3196,3208,3220, - 3237,3249,3264,3275,3283,3297,3309,3321,3338,3353,3365,3377,3394,3409, - 3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586, - 3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687 - }; - - - /* the following are indices into the SID name table */ - static const unsigned short t1_standard_encoding[256] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110, - 0,111,112,113,114, 0,115,116,117,118,119,120,121,122, 0,123, - 0,124,125,126,127,128,129,130,131, 0,132,133, 0,134,135,136, - 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,138, 0,139, 0, 0, 0, 0,140,141,142,143, 0, 0, 0, 0, - 0,144, 0, 0, 0,145, 0, 0,146,147,148,149, 0, 0, 0, 0 - }; - - - /* the following are indices into the SID name table */ - static const unsigned short t1_expert_encoding[256] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1,229,230, 0,231,232,233,234,235,236,237,238, 13, 14, 15, 99, - 239,240,241,242,243,244,245,246,247,248, 27, 28,249,250,251,252, - 0,253,254,255,256,257, 0, 0, 0,258, 0, 0,259,260,261,262, - 0, 0,263,264,265, 0,266,109,110,267,268,269, 0,270,271,272, - 273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288, - 289,290,291,292,293,294,295,296,297,298,299,300,301,302,303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,304,305,306, 0, 0,307,308,309,310,311, 0,312, 0, 0,313, - 0, 0,314,315, 0, 0,316,317,318, 0, 0, 0,158,155,163,319, - 320,321,322,323,324,325, 0, 0,326,150,164,169,327,328,329,330, - 331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346, - 347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362, - 363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378 - }; - - - /* - * This table is a compressed version of the Adobe Glyph List (AGL), - * optimized for efficient searching. It has been generated by the - * `glnames.py' python script located in the `src/tools' directory. - * - * The lookup function to get the Unicode value for a given string - * is defined below the table. - */ - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - static const unsigned char ft_adobe_glyph_list[55997L] = - { - 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, - 11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88, - 22,110, 23, 32, 23, 71, 24, 77, 27,156, 29, 73, 31,247, 32,107, - 32,222, 33, 55, 34,154, 35,218, 58, 10, 64,122, 72,188, 80,109, - 88,104, 93, 61, 98,168,106, 91,114,111,115,237,122,180,127,255, - 135,164,143,132,149,213,158,108,161,115,168,175,183,147,197,199, - 202, 25,204,166,208,209,209, 81,215, 26, 65,143, 0, 65, 0,140, - 0,175, 0,193, 1, 15, 1,147, 1,233, 1,251, 2, 7, 2, 40, - 2, 57, 2, 82, 2, 91, 2,128, 2,136, 2,154, 69,131, 0,198, - 0,150, 0,158, 0,167,225,227,245,244,101,128, 1,252,237,225, - 227,242,239,110,128, 1,226,243,237,225,236,108,128,247,230,225, - 227,245,244,101,129, 0,193, 0,185,243,237,225,236,108,128,247, - 225,226,242,229,246,101,134, 1, 2, 0,213, 0,221, 0,232, 0, - 243, 0,251, 1, 7,225,227,245,244,101,128, 30,174,227,249,242, - 233,236,236,233, 99,128, 4,208,228,239,244,226,229,236,239,119, - 128, 30,182,231,242,225,246,101,128, 30,176,232,239,239,235,225, - 226,239,246,101,128, 30,178,244,233,236,228,101,128, 30,180, 99, - 4, 1, 25, 1, 32, 1,121, 1,137,225,242,239,110,128, 1,205, - 233,242, 99, 2, 1, 40, 1, 45,236,101,128, 36,182,245,237,230, - 236,229,120,134, 0,194, 1, 66, 1, 74, 1, 85, 1, 93, 1,105, - 1,113,225,227,245,244,101,128, 30,164,228,239,244,226,229,236, - 239,119,128, 30,172,231,242,225,246,101,128, 30,166,232,239,239, - 235,225,226,239,246,101,128, 30,168,243,237,225,236,108,128,247, - 226,244,233,236,228,101,128, 30,170,245,244,101,129,246,201, 1, - 129,243,237,225,236,108,128,247,180,249,242,233,236,236,233, 99, - 128, 4, 16,100, 3, 1,155, 1,165, 1,209,226,236,231,242,225, - 246,101,128, 2, 0,233,229,242,229,243,233,115,131, 0,196, 1, - 181, 1,192, 1,201,227,249,242,233,236,236,233, 99,128, 4,210, - 237,225,227,242,239,110,128, 1,222,243,237,225,236,108,128,247, - 228,239,116, 2, 1,216, 1,224,226,229,236,239,119,128, 30,160, - 237,225,227,242,239,110,128, 1,224,231,242,225,246,101,129, 0, - 192, 1,243,243,237,225,236,108,128,247,224,232,239,239,235,225, - 226,239,246,101,128, 30,162,105, 2, 2, 13, 2, 25,229,227,249, - 242,233,236,236,233, 99,128, 4,212,238,246,229,242,244,229,228, - 226,242,229,246,101,128, 2, 2,236,240,232, 97,129, 3,145, 2, - 49,244,239,238,239,115,128, 3,134,109, 2, 2, 63, 2, 71,225, - 227,242,239,110,128, 1, 0,239,238,239,243,240,225,227,101,128, - 255, 33,239,231,239,238,229,107,128, 1, 4,242,233,238,103,131, - 0,197, 2,104, 2,112, 2,120,225,227,245,244,101,128, 1,250, - 226,229,236,239,119,128, 30, 0,243,237,225,236,108,128,247,229, - 243,237,225,236,108,128,247, 97,244,233,236,228,101,129, 0,195, - 2,146,243,237,225,236,108,128,247,227,249,226,225,242,237,229, - 238,233,225,110,128, 5, 49, 66,137, 0, 66, 2,189, 2,198, 2, - 223, 3, 3, 3, 10, 3, 22, 3, 34, 3, 46, 3, 54,227,233,242, - 227,236,101,128, 36,183,228,239,116, 2, 2,206, 2,215,225,227, - 227,229,238,116,128, 30, 2,226,229,236,239,119,128, 30, 4,101, - 3, 2,231, 2,242, 2,254,227,249,242,233,236,236,233, 99,128, - 4, 17,238,225,242,237,229,238,233,225,110,128, 5, 50,244, 97, - 128, 3,146,232,239,239,107,128, 1,129,236,233,238,229,226,229, - 236,239,119,128, 30, 6,237,239,238,239,243,240,225,227,101,128, - 255, 34,242,229,246,229,243,237,225,236,108,128,246,244,243,237, - 225,236,108,128,247, 98,244,239,240,226,225,114,128, 1,130, 67, - 137, 0, 67, 3, 85, 3,127, 3,193, 3,210, 3,224, 4,171, 4, - 188, 4,200, 4,212, 97, 3, 3, 93, 3,104, 3,111,225,242,237, - 229,238,233,225,110,128, 5, 62,227,245,244,101,128, 1, 6,242, - 239,110,129,246,202, 3,119,243,237,225,236,108,128,246,245, 99, - 3, 3,135, 3,142, 3,171,225,242,239,110,128, 1, 12,229,228, - 233,236,236, 97,130, 0,199, 3,155, 3,163,225,227,245,244,101, - 128, 30, 8,243,237,225,236,108,128,247,231,233,242, 99, 2, 3, - 179, 3,184,236,101,128, 36,184,245,237,230,236,229,120,128, 1, - 8,228,239,116,129, 1, 10, 3,201,225,227,227,229,238,116,128, - 1, 10,229,228,233,236,236,225,243,237,225,236,108,128,247,184, - 104, 4, 3,234, 3,246, 4,161, 4,165,225,225,242,237,229,238, - 233,225,110,128, 5, 73,101, 6, 4, 4, 4, 24, 4, 35, 4,103, - 4,115, 4,136,225,226,235,232,225,243,233,225,238,227,249,242, - 233,236,236,233, 99,128, 4,188,227,249,242,233,236,236,233, 99, - 128, 4, 39,100, 2, 4, 41, 4, 85,229,243,227,229,238,228,229, - 114, 2, 4, 54, 4, 74,225,226,235,232,225,243,233,225,238,227, - 249,242,233,236,236,233, 99,128, 4,190,227,249,242,233,236,236, - 233, 99,128, 4,182,233,229,242,229,243,233,243,227,249,242,233, - 236,236,233, 99,128, 4,244,232,225,242,237,229,238,233,225,110, - 128, 5, 67,235,232,225,235,225,243,243,233,225,238,227,249,242, - 233,236,236,233, 99,128, 4,203,246,229,242,244,233,227,225,236, - 243,244,242,239,235,229,227,249,242,233,236,236,233, 99,128, 4, - 184,105,128, 3,167,239,239,107,128, 1,135,233,242,227,245,237, - 230,236,229,248,243,237,225,236,108,128,246,246,237,239,238,239, - 243,240,225,227,101,128,255, 35,239,225,242,237,229,238,233,225, - 110,128, 5, 81,243,237,225,236,108,128,247, 99, 68,142, 0, 68, - 4,252, 5, 10, 5, 36, 5, 96, 5,121, 5,166, 5,173, 5,231, - 5,244, 6, 0, 6, 12, 6, 28, 6, 48, 6, 57, 90,129, 1,241, - 5, 2,227,225,242,239,110,128, 1,196, 97, 2, 5, 16, 5, 27, - 225,242,237,229,238,233,225,110,128, 5, 52,230,242,233,227,225, - 110,128, 1,137, 99, 4, 5, 46, 5, 53, 5, 62, 5, 89,225,242, - 239,110,128, 1, 14,229,228,233,236,236, 97,128, 30, 16,233,242, - 99, 2, 5, 70, 5, 75,236,101,128, 36,185,245,237,230,236,229, - 248,226,229,236,239,119,128, 30, 18,242,239,225,116,128, 1, 16, - 228,239,116, 2, 5,104, 5,113,225,227,227,229,238,116,128, 30, - 10,226,229,236,239,119,128, 30, 12,101, 3, 5,129, 5,140, 5, - 150,227,249,242,233,236,236,233, 99,128, 4, 20,233,227,239,240, - 244,233, 99,128, 3,238,236,244, 97,129, 34, 6, 5,158,231,242, - 229,229,107,128, 3,148,232,239,239,107,128, 1,138,105, 2, 5, - 179, 5,218,229,242,229,243,233,115,131,246,203, 5,194, 5,202, - 5,210,193,227,245,244,101,128,246,204,199,242,225,246,101,128, - 246,205,243,237,225,236,108,128,247,168,231,225,237,237,225,231, - 242,229,229,107,128, 3,220,234,229,227,249,242,233,236,236,233, - 99,128, 4, 2,236,233,238,229,226,229,236,239,119,128, 30, 14, - 237,239,238,239,243,240,225,227,101,128,255, 36,239,244,225,227, - 227,229,238,244,243,237,225,236,108,128,246,247,115, 2, 6, 34, - 6, 41,236,225,243,104,128, 1, 16,237,225,236,108,128,247,100, - 244,239,240,226,225,114,128, 1,139,122,131, 1,242, 6, 67, 6, - 75, 6,112,227,225,242,239,110,128, 1,197,101, 2, 6, 81, 6, - 101,225,226,235,232,225,243,233,225,238,227,249,242,233,236,236, - 233, 99,128, 4,224,227,249,242,233,236,236,233, 99,128, 4, 5, - 232,229,227,249,242,233,236,236,233, 99,128, 4, 15, 69,146, 0, - 69, 6,165, 6,183, 6,191, 7, 89, 7,153, 7,165, 7,183, 7, - 211, 8, 7, 8, 36, 8, 94, 8,169, 8,189, 8,208, 8,248, 9, - 44, 9,109, 9,115,225,227,245,244,101,129, 0,201, 6,175,243, - 237,225,236,108,128,247,233,226,242,229,246,101,128, 1, 20, 99, - 5, 6,203, 6,210, 6,224, 6,236, 7, 79,225,242,239,110,128, - 1, 26,229,228,233,236,236,225,226,242,229,246,101,128, 30, 28, - 232,225,242,237,229,238,233,225,110,128, 5, 53,233,242, 99, 2, - 6,244, 6,249,236,101,128, 36,186,245,237,230,236,229,120,135, - 0,202, 7, 16, 7, 24, 7, 32, 7, 43, 7, 51, 7, 63, 7, 71, - 225,227,245,244,101,128, 30,190,226,229,236,239,119,128, 30, 24, - 228,239,244,226,229,236,239,119,128, 30,198,231,242,225,246,101, - 128, 30,192,232,239,239,235,225,226,239,246,101,128, 30,194,243, - 237,225,236,108,128,247,234,244,233,236,228,101,128, 30,196,249, - 242,233,236,236,233, 99,128, 4, 4,100, 3, 7, 97, 7,107, 7, - 127,226,236,231,242,225,246,101,128, 2, 4,233,229,242,229,243, - 233,115,129, 0,203, 7,119,243,237,225,236,108,128,247,235,239, - 116,130, 1, 22, 7,136, 7,145,225,227,227,229,238,116,128, 1, - 22,226,229,236,239,119,128, 30,184,230,227,249,242,233,236,236, - 233, 99,128, 4, 36,231,242,225,246,101,129, 0,200, 7,175,243, - 237,225,236,108,128,247,232,104, 2, 7,189, 7,200,225,242,237, - 229,238,233,225,110,128, 5, 55,239,239,235,225,226,239,246,101, - 128, 30,186,105, 3, 7,219, 7,230, 7,245,231,232,244,242,239, - 237,225,110,128, 33,103,238,246,229,242,244,229,228,226,242,229, - 246,101,128, 2, 6,239,244,233,230,233,229,228,227,249,242,233, - 236,236,233, 99,128, 4,100,108, 2, 8, 13, 8, 24,227,249,242, - 233,236,236,233, 99,128, 4, 27,229,246,229,238,242,239,237,225, - 110,128, 33,106,109, 3, 8, 44, 8, 72, 8, 83,225,227,242,239, - 110,130, 1, 18, 8, 56, 8, 64,225,227,245,244,101,128, 30, 22, - 231,242,225,246,101,128, 30, 20,227,249,242,233,236,236,233, 99, - 128, 4, 28,239,238,239,243,240,225,227,101,128,255, 37,110, 4, - 8,104, 8,115, 8,135, 8,154,227,249,242,233,236,236,233, 99, - 128, 4, 29,228,229,243,227,229,238,228,229,242,227,249,242,233, - 236,236,233, 99,128, 4,162,103,129, 1, 74, 8,141,232,229,227, - 249,242,233,236,236,233, 99,128, 4,164,232,239,239,235,227,249, - 242,233,236,236,233, 99,128, 4,199,111, 2, 8,175, 8,183,231, - 239,238,229,107,128, 1, 24,240,229,110,128, 1,144,240,243,233, - 236,239,110,129, 3,149, 8,200,244,239,238,239,115,128, 3,136, - 114, 2, 8,214, 8,225,227,249,242,233,236,236,233, 99,128, 4, - 32,229,246,229,242,243,229,100,129, 1,142, 8,237,227,249,242, - 233,236,236,233, 99,128, 4, 45,115, 4, 9, 2, 9, 13, 9, 33, - 9, 37,227,249,242,233,236,236,233, 99,128, 4, 33,228,229,243, - 227,229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4, - 170,104,128, 1,169,237,225,236,108,128,247,101,116, 3, 9, 52, - 9, 78, 9, 92, 97,130, 3,151, 9, 60, 9, 70,242,237,229,238, - 233,225,110,128, 5, 56,244,239,238,239,115,128, 3,137,104,129, - 0,208, 9, 84,243,237,225,236,108,128,247,240,233,236,228,101, - 129, 30,188, 9,101,226,229,236,239,119,128, 30, 26,245,242,111, - 128, 32,172,250,104,130, 1,183, 9,124, 9,132,227,225,242,239, - 110,128, 1,238,242,229,246,229,242,243,229,100,128, 1,184, 70, - 136, 0, 70, 9,163, 9,172, 9,184, 9,212, 9,219, 9,248, 10, - 4, 10, 15,227,233,242,227,236,101,128, 36,187,228,239,244,225, - 227,227,229,238,116,128, 30, 30,101, 2, 9,190, 9,202,232,225, - 242,237,229,238,233,225,110,128, 5, 86,233,227,239,240,244,233, - 99,128, 3,228,232,239,239,107,128, 1,145,105, 2, 9,225, 9, - 238,244,225,227,249,242,233,236,236,233, 99,128, 4,114,246,229, - 242,239,237,225,110,128, 33,100,237,239,238,239,243,240,225,227, - 101,128,255, 38,239,245,242,242,239,237,225,110,128, 33, 99,243, - 237,225,236,108,128,247,102, 71,140, 0, 71, 10, 51, 10, 61, 10, - 107, 10,115, 10,176, 10,193, 10,205, 11, 39, 11, 52, 11, 65, 11, - 90, 11,107,194,243,241,245,225,242,101,128, 51,135, 97, 3, 10, - 69, 10, 76, 10, 94,227,245,244,101,128, 1,244,237,237, 97,129, - 3,147, 10, 84,225,230,242,233,227,225,110,128, 1,148,238,231, - 233,225,227,239,240,244,233, 99,128, 3,234,226,242,229,246,101, - 128, 1, 30, 99, 4, 10,125, 10,132, 10,141, 10,163,225,242,239, - 110,128, 1,230,229,228,233,236,236, 97,128, 1, 34,233,242, 99, - 2, 10,149, 10,154,236,101,128, 36,188,245,237,230,236,229,120, - 128, 1, 28,239,237,237,225,225,227,227,229,238,116,128, 1, 34, - 228,239,116,129, 1, 32, 10,184,225,227,227,229,238,116,128, 1, - 32,229,227,249,242,233,236,236,233, 99,128, 4, 19,104, 3, 10, - 213, 10,226, 11, 33,225,228,225,242,237,229,238,233,225,110,128, - 5, 66,101, 3, 10,234, 10,255, 11, 16,237,233,228,228,236,229, - 232,239,239,235,227,249,242,233,236,236,233, 99,128, 4,148,243, - 244,242,239,235,229,227,249,242,233,236,236,233, 99,128, 4,146, - 245,240,244,245,242,238,227,249,242,233,236,236,233, 99,128, 4, - 144,239,239,107,128, 1,147,233,237,225,242,237,229,238,233,225, - 110,128, 5, 51,234,229,227,249,242,233,236,236,233, 99,128, 4, - 3,109, 2, 11, 71, 11, 79,225,227,242,239,110,128, 30, 32,239, - 238,239,243,240,225,227,101,128,255, 39,242,225,246,101,129,246, - 206, 11, 99,243,237,225,236,108,128,247, 96,115, 2, 11,113, 11, - 129,237,225,236,108,129,247,103, 11,122,232,239,239,107,128, 2, - 155,244,242,239,235,101,128, 1,228, 72,140, 0, 72, 11,165, 11, - 190, 11,198, 11,208, 12, 17, 12, 40, 12, 77, 12,117, 12,129, 12, - 157, 12,165, 12,189,177,184, 53, 3, 11,175, 11,180, 11,185,179, - 51,128, 37,207,180, 51,128, 37,170,181, 49,128, 37,171,178,178, - 176,183, 51,128, 37,161,208,243,241,245,225,242,101,128, 51,203, - 97, 3, 11,216, 11,236, 12, 0,225,226,235,232,225,243,233,225, - 238,227,249,242,233,236,236,233, 99,128, 4,168,228,229,243,227, - 229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,178, - 242,228,243,233,231,238,227,249,242,233,236,236,233, 99,128, 4, - 42, 98, 2, 12, 23, 12, 28,225,114,128, 1, 38,242,229,246,229, - 226,229,236,239,119,128, 30, 42, 99, 2, 12, 46, 12, 55,229,228, - 233,236,236, 97,128, 30, 40,233,242, 99, 2, 12, 63, 12, 68,236, - 101,128, 36,189,245,237,230,236,229,120,128, 1, 36,100, 2, 12, - 83, 12, 93,233,229,242,229,243,233,115,128, 30, 38,239,116, 2, - 12,100, 12,109,225,227,227,229,238,116,128, 30, 34,226,229,236, - 239,119,128, 30, 36,237,239,238,239,243,240,225,227,101,128,255, - 40,111, 2, 12,135, 12,146,225,242,237,229,238,233,225,110,128, - 5, 64,242,233,227,239,240,244,233, 99,128, 3,232,243,237,225, - 236,108,128,247,104,245,238,231,225,242,245,237,236,225,245,116, - 129,246,207, 12,181,243,237,225,236,108,128,246,248,250,243,241, - 245,225,242,101,128, 51,144, 73,146, 0, 73, 12,239, 12,251, 12, - 255, 13, 11, 13, 29, 13, 37, 13, 94, 13,181, 13,214, 13,224, 13, - 242, 13,254, 14, 48, 14, 86, 14, 99, 14,166, 14,187, 14,205,193, - 227,249,242,233,236,236,233, 99,128, 4, 47, 74,128, 1, 50,213, - 227,249,242,233,236,236,233, 99,128, 4, 46,225,227,245,244,101, - 129, 0,205, 13, 21,243,237,225,236,108,128,247,237,226,242,229, - 246,101,128, 1, 44, 99, 3, 13, 45, 13, 52, 13, 84,225,242,239, - 110,128, 1,207,233,242, 99, 2, 13, 60, 13, 65,236,101,128, 36, - 190,245,237,230,236,229,120,129, 0,206, 13, 76,243,237,225,236, - 108,128,247,238,249,242,233,236,236,233, 99,128, 4, 6,100, 3, - 13,102, 13,112, 13,155,226,236,231,242,225,246,101,128, 2, 8, - 233,229,242,229,243,233,115,131, 0,207, 13,128, 13,136, 13,147, - 225,227,245,244,101,128, 30, 46,227,249,242,233,236,236,233, 99, - 128, 4,228,243,237,225,236,108,128,247,239,239,116,130, 1, 48, - 13,164, 13,173,225,227,227,229,238,116,128, 1, 48,226,229,236, - 239,119,128, 30,202,101, 2, 13,187, 13,203,226,242,229,246,229, - 227,249,242,233,236,236,233, 99,128, 4,214,227,249,242,233,236, - 236,233, 99,128, 4, 21,230,242,225,235,244,245,114,128, 33, 17, - 231,242,225,246,101,129, 0,204, 13,234,243,237,225,236,108,128, - 247,236,232,239,239,235,225,226,239,246,101,128, 30,200,105, 3, - 14, 6, 14, 17, 14, 32,227,249,242,233,236,236,233, 99,128, 4, - 24,238,246,229,242,244,229,228,226,242,229,246,101,128, 2, 10, - 243,232,239,242,244,227,249,242,233,236,236,233, 99,128, 4, 25, - 109, 2, 14, 54, 14, 75,225,227,242,239,110,129, 1, 42, 14, 64, - 227,249,242,233,236,236,233, 99,128, 4,226,239,238,239,243,240, - 225,227,101,128,255, 41,238,233,225,242,237,229,238,233,225,110, - 128, 5, 59,111, 3, 14,107, 14,118, 14,126,227,249,242,233,236, - 236,233, 99,128, 4, 1,231,239,238,229,107,128, 1, 46,244, 97, - 131, 3,153, 14,137, 14,147, 14,158,225,230,242,233,227,225,110, - 128, 1,150,228,233,229,242,229,243,233,115,128, 3,170,244,239, - 238,239,115,128, 3,138,115, 2, 14,172, 14,179,237,225,236,108, - 128,247,105,244,242,239,235,101,128, 1,151,244,233,236,228,101, - 129, 1, 40, 14,197,226,229,236,239,119,128, 30, 44,250,232,233, - 244,243, 97, 2, 14,216, 14,227,227,249,242,233,236,236,233, 99, - 128, 4,116,228,226,236,231,242,225,246,229,227,249,242,233,236, - 236,233, 99,128, 4,118, 74,134, 0, 74, 15, 6, 15, 18, 15, 41, - 15, 53, 15, 67, 15, 79,225,225,242,237,229,238,233,225,110,128, - 5, 65,227,233,242, 99, 2, 15, 27, 15, 32,236,101,128, 36,191, - 245,237,230,236,229,120,128, 1, 52,229,227,249,242,233,236,236, - 233, 99,128, 4, 8,232,229,232,225,242,237,229,238,233,225,110, - 128, 5, 75,237,239,238,239,243,240,225,227,101,128,255, 42,243, - 237,225,236,108,128,247,106, 75,140, 0, 75, 15,115, 15,125, 15, - 135, 16, 18, 16, 65, 16, 76, 16,106, 16,143, 16,156, 16,168, 16, - 180, 16,208,194,243,241,245,225,242,101,128, 51,133,203,243,241, - 245,225,242,101,128, 51,205, 97, 7, 15,151, 15,169, 15,191, 15, - 211, 15,226, 15,232, 15,249,226,225,243,232,235,233,242,227,249, - 242,233,236,236,233, 99,128, 4,160, 99, 2, 15,175, 15,181,245, - 244,101,128, 30, 48,249,242,233,236,236,233, 99,128, 4, 26,228, - 229,243,227,229,238,228,229,242,227,249,242,233,236,236,233, 99, - 128, 4,154,232,239,239,235,227,249,242,233,236,236,233, 99,128, - 4,195,240,240, 97,128, 3,154,243,244,242,239,235,229,227,249, - 242,233,236,236,233, 99,128, 4,158,246,229,242,244,233,227,225, - 236,243,244,242,239,235,229,227,249,242,233,236,236,233, 99,128, - 4,156, 99, 4, 16, 28, 16, 35, 16, 44, 16, 52,225,242,239,110, - 128, 1,232,229,228,233,236,236, 97,128, 1, 54,233,242,227,236, - 101,128, 36,192,239,237,237,225,225,227,227,229,238,116,128, 1, - 54,228,239,244,226,229,236,239,119,128, 30, 50,101, 2, 16, 82, - 16, 94,232,225,242,237,229,238,233,225,110,128, 5, 84,238,225, - 242,237,229,238,233,225,110,128, 5, 63,104, 3, 16,114, 16,126, - 16,137,225,227,249,242,233,236,236,233, 99,128, 4, 37,229,233, - 227,239,240,244,233, 99,128, 3,230,239,239,107,128, 1,152,234, - 229,227,249,242,233,236,236,233, 99,128, 4, 12,236,233,238,229, - 226,229,236,239,119,128, 30, 52,237,239,238,239,243,240,225,227, - 101,128,255, 43,239,240,240, 97, 2, 16,189, 16,200,227,249,242, - 233,236,236,233, 99,128, 4,128,231,242,229,229,107,128, 3,222, - 115, 2, 16,214, 16,226,233,227,249,242,233,236,236,233, 99,128, - 4,110,237,225,236,108,128,247,107, 76,138, 0, 76, 17, 1, 17, - 5, 17, 9, 17, 29, 17, 95, 17,133, 17,147, 17,165, 17,177, 17, - 189, 74,128, 1,199, 76,128,246,191, 97, 2, 17, 15, 17, 22,227, - 245,244,101,128, 1, 57,237,226,228, 97,128, 3,155, 99, 4, 17, - 39, 17, 46, 17, 55, 17, 82,225,242,239,110,128, 1, 61,229,228, - 233,236,236, 97,128, 1, 59,233,242, 99, 2, 17, 63, 17, 68,236, - 101,128, 36,193,245,237,230,236,229,248,226,229,236,239,119,128, - 30, 60,239,237,237,225,225,227,227,229,238,116,128, 1, 59,228, - 239,116,130, 1, 63, 17,105, 17,114,225,227,227,229,238,116,128, - 1, 63,226,229,236,239,119,129, 30, 54, 17,124,237,225,227,242, - 239,110,128, 30, 56,233,247,238,225,242,237,229,238,233,225,110, - 128, 5, 60,106,129, 1,200, 17,153,229,227,249,242,233,236,236, - 233, 99,128, 4, 9,236,233,238,229,226,229,236,239,119,128, 30, - 58,237,239,238,239,243,240,225,227,101,128,255, 44,115, 2, 17, - 195, 17,212,236,225,243,104,129, 1, 65, 17,204,243,237,225,236, - 108,128,246,249,237,225,236,108,128,247,108, 77,137, 0, 77, 17, - 241, 17,251, 18, 24, 18, 33, 18, 58, 18, 71, 18, 83, 18, 91, 18, - 100,194,243,241,245,225,242,101,128, 51,134,225, 99, 2, 18, 2, - 18, 18,242,239,110,129,246,208, 18, 10,243,237,225,236,108,128, - 247,175,245,244,101,128, 30, 62,227,233,242,227,236,101,128, 36, - 194,228,239,116, 2, 18, 41, 18, 50,225,227,227,229,238,116,128, - 30, 64,226,229,236,239,119,128, 30, 66,229,238,225,242,237,229, - 238,233,225,110,128, 5, 68,237,239,238,239,243,240,225,227,101, - 128,255, 45,243,237,225,236,108,128,247,109,244,245,242,238,229, - 100,128, 1,156,117,128, 3,156, 78,141, 0, 78, 18,134, 18,138, - 18,146, 18,212, 18,237, 18,248, 19, 3, 19, 21, 19, 33, 19, 45, - 19, 58, 19, 66, 19, 84, 74,128, 1,202,225,227,245,244,101,128, - 1, 67, 99, 4, 18,156, 18,163, 18,172, 18,199,225,242,239,110, - 128, 1, 71,229,228,233,236,236, 97,128, 1, 69,233,242, 99, 2, - 18,180, 18,185,236,101,128, 36,195,245,237,230,236,229,248,226, - 229,236,239,119,128, 30, 74,239,237,237,225,225,227,227,229,238, - 116,128, 1, 69,228,239,116, 2, 18,220, 18,229,225,227,227,229, - 238,116,128, 30, 68,226,229,236,239,119,128, 30, 70,232,239,239, - 235,236,229,230,116,128, 1,157,233,238,229,242,239,237,225,110, - 128, 33,104,106,129, 1,203, 19, 9,229,227,249,242,233,236,236, - 233, 99,128, 4, 10,236,233,238,229,226,229,236,239,119,128, 30, - 72,237,239,238,239,243,240,225,227,101,128,255, 46,239,247,225, - 242,237,229,238,233,225,110,128, 5, 70,243,237,225,236,108,128, - 247,110,244,233,236,228,101,129, 0,209, 19, 76,243,237,225,236, - 108,128,247,241,117,128, 3,157, 79,141, 0, 79, 19,118, 19,132, - 19,150, 19,203, 20, 78, 20,152, 20,187, 21, 48, 21, 69, 21,213, - 21,223, 21,254, 22, 53, 69,129, 1, 82, 19,124,243,237,225,236, - 108,128,246,250,225,227,245,244,101,129, 0,211, 19,142,243,237, - 225,236,108,128,247,243, 98, 2, 19,156, 19,196,225,242,242,229, - 100, 2, 19,166, 19,177,227,249,242,233,236,236,233, 99,128, 4, - 232,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, - 99,128, 4,234,242,229,246,101,128, 1, 78, 99, 4, 19,213, 19, - 220, 19,235, 20, 68,225,242,239,110,128, 1,209,229,238,244,229, - 242,229,228,244,233,236,228,101,128, 1,159,233,242, 99, 2, 19, - 243, 19,248,236,101,128, 36,196,245,237,230,236,229,120,134, 0, - 212, 20, 13, 20, 21, 20, 32, 20, 40, 20, 52, 20, 60,225,227,245, - 244,101,128, 30,208,228,239,244,226,229,236,239,119,128, 30,216, - 231,242,225,246,101,128, 30,210,232,239,239,235,225,226,239,246, - 101,128, 30,212,243,237,225,236,108,128,247,244,244,233,236,228, - 101,128, 30,214,249,242,233,236,236,233, 99,128, 4, 30,100, 3, - 20, 86, 20,109, 20,142,226,108, 2, 20, 93, 20,101,225,227,245, - 244,101,128, 1, 80,231,242,225,246,101,128, 2, 12,233,229,242, - 229,243,233,115,130, 0,214, 20,123, 20,134,227,249,242,233,236, - 236,233, 99,128, 4,230,243,237,225,236,108,128,247,246,239,244, - 226,229,236,239,119,128, 30,204,103, 2, 20,158, 20,170,239,238, - 229,235,243,237,225,236,108,128,246,251,242,225,246,101,129, 0, - 210, 20,179,243,237,225,236,108,128,247,242,104, 4, 20,197, 20, - 208, 20,212, 21, 34,225,242,237,229,238,233,225,110,128, 5, 85, - 109,128, 33, 38,111, 2, 20,218, 20,228,239,235,225,226,239,246, - 101,128, 30,206,242,110,133, 1,160, 20,243, 20,251, 21, 6, 21, - 14, 21, 26,225,227,245,244,101,128, 30,218,228,239,244,226,229, - 236,239,119,128, 30,226,231,242,225,246,101,128, 30,220,232,239, - 239,235,225,226,239,246,101,128, 30,222,244,233,236,228,101,128, - 30,224,245,238,231,225,242,245,237,236,225,245,116,128, 1, 80, - 105,129, 1,162, 21, 54,238,246,229,242,244,229,228,226,242,229, - 246,101,128, 2, 14,109, 4, 21, 79, 21,107, 21,184, 21,202,225, - 227,242,239,110,130, 1, 76, 21, 91, 21, 99,225,227,245,244,101, - 128, 30, 82,231,242,225,246,101,128, 30, 80,229,231, 97,132, 33, - 38, 21,121, 21,132, 21,140, 21,156,227,249,242,233,236,236,233, - 99,128, 4, 96,231,242,229,229,107,128, 3,169,242,239,245,238, - 228,227,249,242,233,236,236,233, 99,128, 4,122,116, 2, 21,162, - 21,177,233,244,236,239,227,249,242,233,236,236,233, 99,128, 4, - 124,239,238,239,115,128, 3,143,233,227,242,239,110,129, 3,159, - 21,194,244,239,238,239,115,128, 3,140,239,238,239,243,240,225, - 227,101,128,255, 47,238,229,242,239,237,225,110,128, 33, 96,111, - 2, 21,229, 21,248,231,239,238,229,107,129, 1,234, 21,239,237, - 225,227,242,239,110,128, 1,236,240,229,110,128, 1,134,115, 3, - 22, 6, 22, 33, 22, 40,236,225,243,104,130, 0,216, 22, 17, 22, - 25,225,227,245,244,101,128, 1,254,243,237,225,236,108,128,247, - 248,237,225,236,108,128,247,111,244,242,239,235,229,225,227,245, - 244,101,128, 1,254,116, 2, 22, 59, 22, 70,227,249,242,233,236, - 236,233, 99,128, 4,126,233,236,228,101,131, 0,213, 22, 83, 22, - 91, 22,102,225,227,245,244,101,128, 30, 76,228,233,229,242,229, - 243,233,115,128, 30, 78,243,237,225,236,108,128,247,245, 80,136, - 0, 80, 22,130, 22,138, 22,147, 22,159, 22,211, 22,227, 22,246, - 23, 2,225,227,245,244,101,128, 30, 84,227,233,242,227,236,101, - 128, 36,197,228,239,244,225,227,227,229,238,116,128, 30, 86,101, - 3, 22,167, 22,178, 22,190,227,249,242,233,236,236,233, 99,128, - 4, 31,232,225,242,237,229,238,233,225,110,128, 5, 74,237,233, - 228,228,236,229,232,239,239,235,227,249,242,233,236,236,233, 99, - 128, 4,166,104, 2, 22,217, 22,221,105,128, 3,166,239,239,107, - 128, 1,164,105,129, 3,160, 22,233,247,242,225,242,237,229,238, - 233,225,110,128, 5, 83,237,239,238,239,243,240,225,227,101,128, - 255, 48,115, 2, 23, 8, 23, 25,105,129, 3,168, 23, 14,227,249, - 242,233,236,236,233, 99,128, 4,112,237,225,236,108,128,247,112, - 81,131, 0, 81, 23, 42, 23, 51, 23, 63,227,233,242,227,236,101, - 128, 36,198,237,239,238,239,243,240,225,227,101,128,255, 49,243, - 237,225,236,108,128,247,113, 82,138, 0, 82, 23, 95, 23,119, 23, - 166, 23,217, 23,230, 23,240, 23,245, 24, 19, 24, 31, 24, 43, 97, - 2, 23,101, 23,112,225,242,237,229,238,233,225,110,128, 5, 76, - 227,245,244,101,128, 1, 84, 99, 4, 23,129, 23,136, 23,145, 23, - 153,225,242,239,110,128, 1, 88,229,228,233,236,236, 97,128, 1, - 86,233,242,227,236,101,128, 36,199,239,237,237,225,225,227,227, - 229,238,116,128, 1, 86,100, 2, 23,172, 23,182,226,236,231,242, - 225,246,101,128, 2, 16,239,116, 2, 23,189, 23,198,225,227,227, - 229,238,116,128, 30, 88,226,229,236,239,119,129, 30, 90, 23,208, - 237,225,227,242,239,110,128, 30, 92,229,232,225,242,237,229,238, - 233,225,110,128, 5, 80,230,242,225,235,244,245,114,128, 33, 28, - 232,111,128, 3,161,233,110, 2, 23,252, 24, 5,231,243,237,225, - 236,108,128,246,252,246,229,242,244,229,228,226,242,229,246,101, - 128, 2, 18,236,233,238,229,226,229,236,239,119,128, 30, 94,237, - 239,238,239,243,240,225,227,101,128,255, 50,243,237,225,236,108, - 129,247,114, 24, 53,233,238,246,229,242,244,229,100,129, 2,129, - 24, 66,243,245,240,229,242,233,239,114,128, 2,182, 83,139, 0, - 83, 24,103, 26, 17, 26, 55, 26,182, 26,221, 26,250, 27, 84, 27, - 105, 27,117, 27,135, 27,143, 70, 6, 24,117, 24,209, 24,241, 25, - 77, 25,119, 25,221, 48, 9, 24,137, 24,145, 24,153, 24,161, 24, - 169, 24,177, 24,185, 24,193, 24,201,177,176,176,176, 48,128, 37, - 12,178,176,176,176, 48,128, 37, 20,179,176,176,176, 48,128, 37, - 16,180,176,176,176, 48,128, 37, 24,181,176,176,176, 48,128, 37, - 60,182,176,176,176, 48,128, 37, 44,183,176,176,176, 48,128, 37, - 52,184,176,176,176, 48,128, 37, 28,185,176,176,176, 48,128, 37, - 36, 49, 3, 24,217, 24,225, 24,233,176,176,176,176, 48,128, 37, - 0,177,176,176,176, 48,128, 37, 2,185,176,176,176, 48,128, 37, - 97, 50, 9, 25, 5, 25, 13, 25, 21, 25, 29, 25, 37, 25, 45, 25, - 53, 25, 61, 25, 69,176,176,176,176, 48,128, 37, 98,177,176,176, - 176, 48,128, 37, 86,178,176,176,176, 48,128, 37, 85,179,176,176, - 176, 48,128, 37, 99,180,176,176,176, 48,128, 37, 81,181,176,176, - 176, 48,128, 37, 87,182,176,176,176, 48,128, 37, 93,183,176,176, - 176, 48,128, 37, 92,184,176,176,176, 48,128, 37, 91, 51, 4, 25, - 87, 25, 95, 25,103, 25,111,182,176,176,176, 48,128, 37, 94,183, - 176,176,176, 48,128, 37, 95,184,176,176,176, 48,128, 37, 90,185, - 176,176,176, 48,128, 37, 84, 52, 10, 25,141, 25,149, 25,157, 25, - 165, 25,173, 25,181, 25,189, 25,197, 25,205, 25,213,176,176,176, - 176, 48,128, 37,105,177,176,176,176, 48,128, 37,102,178,176,176, - 176, 48,128, 37, 96,179,176,176,176, 48,128, 37, 80,180,176,176, - 176, 48,128, 37,108,181,176,176,176, 48,128, 37,103,182,176,176, - 176, 48,128, 37,104,183,176,176,176, 48,128, 37,100,184,176,176, - 176, 48,128, 37,101,185,176,176,176, 48,128, 37, 89, 53, 5, 25, - 233, 25,241, 25,249, 26, 1, 26, 9,176,176,176,176, 48,128, 37, - 88,177,176,176,176, 48,128, 37, 82,178,176,176,176, 48,128, 37, - 83,179,176,176,176, 48,128, 37,107,180,176,176,176, 48,128, 37, - 106, 97, 2, 26, 23, 26, 44,227,245,244,101,129, 1, 90, 26, 32, - 228,239,244,225,227,227,229,238,116,128, 30,100,237,240,233,231, - 242,229,229,107,128, 3,224, 99, 5, 26, 67, 26, 98, 26,107, 26, - 147, 26,169,225,242,239,110,130, 1, 96, 26, 78, 26, 90,228,239, - 244,225,227,227,229,238,116,128, 30,102,243,237,225,236,108,128, - 246,253,229,228,233,236,236, 97,128, 1, 94,232,247, 97,130, 1, - 143, 26,117, 26,128,227,249,242,233,236,236,233, 99,128, 4,216, - 228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99, - 128, 4,218,233,242, 99, 2, 26,155, 26,160,236,101,128, 36,200, - 245,237,230,236,229,120,128, 1, 92,239,237,237,225,225,227,227, - 229,238,116,128, 2, 24,228,239,116, 2, 26,190, 26,199,225,227, - 227,229,238,116,128, 30, 96,226,229,236,239,119,129, 30, 98, 26, - 209,228,239,244,225,227,227,229,238,116,128, 30,104,101, 2, 26, - 227, 26,239,232,225,242,237,229,238,233,225,110,128, 5, 77,246, - 229,238,242,239,237,225,110,128, 33,102,104, 5, 27, 6, 27, 34, - 27, 48, 27, 59, 27, 72, 97, 2, 27, 12, 27, 23,225,242,237,229, - 238,233,225,110,128, 5, 71,227,249,242,233,236,236,233, 99,128, - 4, 40,227,232,225,227,249,242,233,236,236,233, 99,128, 4, 41, - 229,233,227,239,240,244,233, 99,128, 3,226,232,225,227,249,242, - 233,236,236,233, 99,128, 4,186,233,237,225,227,239,240,244,233, - 99,128, 3,236,105, 2, 27, 90, 27, 96,231,237, 97,128, 3,163, - 248,242,239,237,225,110,128, 33,101,237,239,238,239,243,240,225, - 227,101,128,255, 51,239,230,244,243,233,231,238,227,249,242,233, - 236,236,233, 99,128, 4, 44,243,237,225,236,108,128,247,115,244, - 233,231,237,225,231,242,229,229,107,128, 3,218, 84,141, 0, 84, - 27,186, 27,191, 27,197, 28, 7, 28, 32, 28, 96, 28,147, 28,177, - 28,189, 28,201, 28,246, 29, 6, 29, 46,225,117,128, 3,164,226, - 225,114,128, 1,102, 99, 4, 27,207, 27,214, 27,223, 27,250,225, - 242,239,110,128, 1,100,229,228,233,236,236, 97,128, 1, 98,233, - 242, 99, 2, 27,231, 27,236,236,101,128, 36,201,245,237,230,236, - 229,248,226,229,236,239,119,128, 30,112,239,237,237,225,225,227, - 227,229,238,116,128, 1, 98,228,239,116, 2, 28, 15, 28, 24,225, - 227,227,229,238,116,128, 30,106,226,229,236,239,119,128, 30,108, - 101, 4, 28, 42, 28, 53, 28, 73, 28, 82,227,249,242,233,236,236, - 233, 99,128, 4, 34,228,229,243,227,229,238,228,229,242,227,249, - 242,233,236,236,233, 99,128, 4,172,238,242,239,237,225,110,128, - 33,105,244,243,229,227,249,242,233,236,236,233, 99,128, 4,180, - 104, 3, 28,104, 28,110, 28,136,229,244, 97,128, 3,152,111, 2, - 28,116, 28,121,239,107,128, 1,172,242,110,129, 0,222, 28,128, - 243,237,225,236,108,128,247,254,242,229,229,242,239,237,225,110, - 128, 33, 98,105, 2, 28,153, 28,164,236,228,229,243,237,225,236, - 108,128,246,254,247,238,225,242,237,229,238,233,225,110,128, 5, - 79,236,233,238,229,226,229,236,239,119,128, 30,110,237,239,238, - 239,243,240,225,227,101,128,255, 52,111, 2, 28,207, 28,218,225, - 242,237,229,238,233,225,110,128, 5, 57,238,101, 3, 28,227, 28, - 234, 28,240,230,233,246,101,128, 1,188,243,233,120,128, 1,132, - 244,247,111,128, 1,167,242,229,244,242,239,230,236,229,248,232, - 239,239,107,128, 1,174,115, 3, 29, 14, 29, 26, 29, 39,229,227, - 249,242,233,236,236,233, 99,128, 4, 38,232,229,227,249,242,233, - 236,236,233, 99,128, 4, 11,237,225,236,108,128,247,116,119, 2, - 29, 52, 29, 64,229,236,246,229,242,239,237,225,110,128, 33,107, - 239,242,239,237,225,110,128, 33, 97, 85,142, 0, 85, 29,105, 29, - 123, 29,131, 29,198, 30, 69, 30, 87, 30,198, 30,214, 30,226, 31, - 21, 31, 30, 31,142, 31,149, 31,219,225,227,245,244,101,129, 0, - 218, 29,115,243,237,225,236,108,128,247,250,226,242,229,246,101, - 128, 1,108, 99, 3, 29,139, 29,146, 29,188,225,242,239,110,128, - 1,211,233,242, 99, 2, 29,154, 29,159,236,101,128, 36,202,245, - 237,230,236,229,120,130, 0,219, 29,172, 29,180,226,229,236,239, - 119,128, 30,118,243,237,225,236,108,128,247,251,249,242,233,236, - 236,233, 99,128, 4, 35,100, 3, 29,206, 29,229, 30, 59,226,108, - 2, 29,213, 29,221,225,227,245,244,101,128, 1,112,231,242,225, - 246,101,128, 2, 20,233,229,242,229,243,233,115,134, 0,220, 29, - 251, 30, 3, 30, 11, 30, 34, 30, 42, 30, 51,225,227,245,244,101, - 128, 1,215,226,229,236,239,119,128, 30,114, 99, 2, 30, 17, 30, - 24,225,242,239,110,128, 1,217,249,242,233,236,236,233, 99,128, - 4,240,231,242,225,246,101,128, 1,219,237,225,227,242,239,110, - 128, 1,213,243,237,225,236,108,128,247,252,239,244,226,229,236, - 239,119,128, 30,228,231,242,225,246,101,129, 0,217, 30, 79,243, - 237,225,236,108,128,247,249,104, 2, 30, 93, 30,171,111, 2, 30, - 99, 30,109,239,235,225,226,239,246,101,128, 30,230,242,110,133, - 1,175, 30,124, 30,132, 30,143, 30,151, 30,163,225,227,245,244, - 101,128, 30,232,228,239,244,226,229,236,239,119,128, 30,240,231, - 242,225,246,101,128, 30,234,232,239,239,235,225,226,239,246,101, - 128, 30,236,244,233,236,228,101,128, 30,238,245,238,231,225,242, - 245,237,236,225,245,116,129, 1,112, 30,187,227,249,242,233,236, - 236,233, 99,128, 4,242,233,238,246,229,242,244,229,228,226,242, - 229,246,101,128, 2, 22,235,227,249,242,233,236,236,233, 99,128, - 4,120,109, 2, 30,232, 31, 10,225,227,242,239,110,130, 1,106, - 30,244, 30,255,227,249,242,233,236,236,233, 99,128, 4,238,228, - 233,229,242,229,243,233,115,128, 30,122,239,238,239,243,240,225, - 227,101,128,255, 53,239,231,239,238,229,107,128, 1,114,240,243, - 233,236,239,110,133, 3,165, 31, 49, 31, 53, 31, 90, 31,121, 31, - 134, 49,128, 3,210, 97, 2, 31, 59, 31, 81,227,245,244,229,232, - 239,239,235,243,249,237,226,239,236,231,242,229,229,107,128, 3, - 211,230,242,233,227,225,110,128, 1,177,228,233,229,242,229,243, - 233,115,129, 3,171, 31,103,232,239,239,235,243,249,237,226,239, - 236,231,242,229,229,107,128, 3,212,232,239,239,235,243,249,237, - 226,239,108,128, 3,210,244,239,238,239,115,128, 3,142,242,233, - 238,103,128, 1,110,115, 3, 31,157, 31,172, 31,179,232,239,242, - 244,227,249,242,233,236,236,233, 99,128, 4, 14,237,225,236,108, - 128,247,117,244,242,225,233,231,232,116, 2, 31,191, 31,202,227, - 249,242,233,236,236,233, 99,128, 4,174,243,244,242,239,235,229, - 227,249,242,233,236,236,233, 99,128, 4,176,244,233,236,228,101, - 130, 1,104, 31,231, 31,239,225,227,245,244,101,128, 30,120,226, - 229,236,239,119,128, 30,116, 86,136, 0, 86, 32, 11, 32, 20, 32, - 31, 32, 60, 32, 67, 32, 79, 32, 91, 32, 99,227,233,242,227,236, - 101,128, 36,203,228,239,244,226,229,236,239,119,128, 30,126,101, - 2, 32, 37, 32, 48,227,249,242,233,236,236,233, 99,128, 4, 18, - 247,225,242,237,229,238,233,225,110,128, 5, 78,232,239,239,107, - 128, 1,178,237,239,238,239,243,240,225,227,101,128,255, 54,239, - 225,242,237,229,238,233,225,110,128, 5, 72,243,237,225,236,108, - 128,247,118,244,233,236,228,101,128, 30,124, 87,134, 0, 87, 32, - 123, 32,131, 32,154, 32,194, 32,202, 32,214,225,227,245,244,101, - 128, 30,130,227,233,242, 99, 2, 32,140, 32,145,236,101,128, 36, - 204,245,237,230,236,229,120,128, 1,116,100, 2, 32,160, 32,170, - 233,229,242,229,243,233,115,128, 30,132,239,116, 2, 32,177, 32, - 186,225,227,227,229,238,116,128, 30,134,226,229,236,239,119,128, - 30,136,231,242,225,246,101,128, 30,128,237,239,238,239,243,240, - 225,227,101,128,255, 55,243,237,225,236,108,128,247,119, 88,134, - 0, 88, 32,238, 32,247, 33, 18, 33, 31, 33, 35, 33, 47,227,233, - 242,227,236,101,128, 36,205,100, 2, 32,253, 33, 7,233,229,242, - 229,243,233,115,128, 30,140,239,244,225,227,227,229,238,116,128, - 30,138,229,232,225,242,237,229,238,233,225,110,128, 5, 61,105, - 128, 3,158,237,239,238,239,243,240,225,227,101,128,255, 56,243, - 237,225,236,108,128,247,120, 89,139, 0, 89, 33, 81, 33,116, 33, - 139, 33,189, 33,228, 33,236, 33,253, 34, 40, 34, 52, 34, 60, 34, - 68, 97, 2, 33, 87, 33,104,227,245,244,101,129, 0,221, 33, 96, - 243,237,225,236,108,128,247,253,244,227,249,242,233,236,236,233, - 99,128, 4, 98,227,233,242, 99, 2, 33,125, 33,130,236,101,128, - 36,206,245,237,230,236,229,120,128, 1,118,100, 2, 33,145, 33, - 165,233,229,242,229,243,233,115,129, 1,120, 33,157,243,237,225, - 236,108,128,247,255,239,116, 2, 33,172, 33,181,225,227,227,229, - 238,116,128, 30,142,226,229,236,239,119,128, 30,244,229,114, 2, - 33,196, 33,208,233,227,249,242,233,236,236,233, 99,128, 4, 43, - 245,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, - 99,128, 4,248,231,242,225,246,101,128, 30,242,232,239,239,107, - 129, 1,179, 33,245,225,226,239,246,101,128, 30,246,105, 3, 34, - 5, 34, 16, 34, 27,225,242,237,229,238,233,225,110,128, 5, 69, - 227,249,242,233,236,236,233, 99,128, 4, 7,247,238,225,242,237, - 229,238,233,225,110,128, 5, 82,237,239,238,239,243,240,225,227, - 101,128,255, 57,243,237,225,236,108,128,247,121,244,233,236,228, - 101,128, 30,248,245,115, 2, 34, 75, 34,113,226,233,103, 2, 34, - 83, 34, 94,227,249,242,233,236,236,233, 99,128, 4,106,233,239, - 244,233,230,233,229,228,227,249,242,233,236,236,233, 99,128, 4, - 108,236,233,244,244,236,101, 2, 34,124, 34,135,227,249,242,233, - 236,236,233, 99,128, 4,102,233,239,244,233,230,233,229,228,227, - 249,242,233,236,236,233, 99,128, 4,104, 90,136, 0, 90, 34,174, - 34,198, 34,243, 35, 14, 35, 81, 35,173, 35,185, 35,197, 97, 2, - 34,180, 34,191,225,242,237,229,238,233,225,110,128, 5, 54,227, - 245,244,101,128, 1,121, 99, 2, 34,204, 34,221,225,242,239,110, - 129, 1,125, 34,213,243,237,225,236,108,128,246,255,233,242, 99, - 2, 34,229, 34,234,236,101,128, 36,207,245,237,230,236,229,120, - 128, 30,144,228,239,116,130, 1,123, 34,253, 35, 6,225,227,227, - 229,238,116,128, 1,123,226,229,236,239,119,128, 30,146,101, 3, - 35, 22, 35, 33, 35, 76,227,249,242,233,236,236,233, 99,128, 4, - 23,100, 2, 35, 39, 35, 58,229,243,227,229,238,228,229,242,227, - 249,242,233,236,236,233, 99,128, 4,152,233,229,242,229,243,233, - 243,227,249,242,233,236,236,233, 99,128, 4,222,244, 97,128, 3, - 150,232,101, 4, 35, 92, 35,103, 35,119, 35,130,225,242,237,229, - 238,233,225,110,128, 5, 58,226,242,229,246,229,227,249,242,233, - 236,236,233, 99,128, 4,193,227,249,242,233,236,236,233, 99,128, - 4, 22,100, 2, 35,136, 35,155,229,243,227,229,238,228,229,242, - 227,249,242,233,236,236,233, 99,128, 4,150,233,229,242,229,243, - 233,243,227,249,242,233,236,236,233, 99,128, 4,220,236,233,238, - 229,226,229,236,239,119,128, 30,148,237,239,238,239,243,240,225, - 227,101,128,255, 58,115, 2, 35,203, 35,210,237,225,236,108,128, - 247,122,244,242,239,235,101,128, 1,181, 97,158, 0, 97, 36, 26, - 38,154, 39, 4, 39, 68, 39,132, 39,196, 40, 4, 40, 68, 40,126, - 40,190, 41, 70, 41,217, 42,137, 42,237, 43, 17, 49,192, 49,229, - 50, 0, 50,225, 51, 7, 52, 96, 52,168, 53,123, 53,132, 54, 5, - 56, 13, 57, 3, 57, 50, 57,201, 57,215, 49,138, 39, 1, 36, 50, - 36,114, 36,154, 36,218, 37, 26, 37, 90, 37,154, 37,218, 38, 26, - 38, 90, 48,138, 39, 33, 36, 74, 36, 78, 36, 82, 36, 86, 36, 90, - 36, 94, 36, 98, 36,102, 36,106, 36,110, 48,128, 39, 94, 49,128, - 39, 97, 50,128, 39, 98, 51,128, 39, 99, 52,128, 39,100, 53,128, - 39, 16, 54,128, 39,101, 55,128, 39,102, 56,128, 39,103, 57,128, - 38, 96, 49,134, 38, 27, 36,130, 36,134, 36,138, 36,142, 36,146, - 36,150, 48,128, 38,101, 49,128, 38,102, 50,128, 38, 99, 55,128, - 39, 9, 56,128, 39, 8, 57,128, 39, 7, 50,138, 38, 30, 36,178, - 36,182, 36,186, 36,190, 36,194, 36,198, 36,202, 36,206, 36,210, - 36,214, 48,128, 36, 96, 49,128, 36, 97, 50,128, 36, 98, 51,128, - 36, 99, 52,128, 36,100, 53,128, 36,101, 54,128, 36,102, 55,128, - 36,103, 56,128, 36,104, 57,128, 36,105, 51,138, 39, 12, 36,242, - 36,246, 36,250, 36,254, 37, 2, 37, 6, 37, 10, 37, 14, 37, 18, - 37, 22, 48,128, 39,118, 49,128, 39,119, 50,128, 39,120, 51,128, - 39,121, 52,128, 39,122, 53,128, 39,123, 54,128, 39,124, 55,128, - 39,125, 56,128, 39,126, 57,128, 39,127, 52,138, 39, 13, 37, 50, - 37, 54, 37, 58, 37, 62, 37, 66, 37, 70, 37, 74, 37, 78, 37, 82, - 37, 86, 48,128, 39,128, 49,128, 39,129, 50,128, 39,130, 51,128, - 39,131, 52,128, 39,132, 53,128, 39,133, 54,128, 39,134, 55,128, - 39,135, 56,128, 39,136, 57,128, 39,137, 53,138, 39, 14, 37,114, - 37,118, 37,122, 37,126, 37,130, 37,134, 37,138, 37,142, 37,146, - 37,150, 48,128, 39,138, 49,128, 39,139, 50,128, 39,140, 51,128, - 39,141, 52,128, 39,142, 53,128, 39,143, 54,128, 39,144, 55,128, - 39,145, 56,128, 39,146, 57,128, 39,147, 54,138, 39, 15, 37,178, - 37,182, 37,186, 37,190, 37,194, 37,198, 37,202, 37,206, 37,210, - 37,214, 48,128, 39,148, 49,128, 33,146, 50,128, 39,163, 51,128, - 33,148, 52,128, 33,149, 53,128, 39,153, 54,128, 39,155, 55,128, - 39,156, 56,128, 39,157, 57,128, 39,158, 55,138, 39, 17, 37,242, - 37,246, 37,250, 37,254, 38, 2, 38, 6, 38, 10, 38, 14, 38, 18, - 38, 22, 48,128, 39,159, 49,128, 39,160, 50,128, 39,161, 51,128, - 39,162, 52,128, 39,164, 53,128, 39,165, 54,128, 39,166, 55,128, - 39,167, 56,128, 39,168, 57,128, 39,169, 56,138, 39, 18, 38, 50, - 38, 54, 38, 58, 38, 62, 38, 66, 38, 70, 38, 74, 38, 78, 38, 82, - 38, 86, 48,128, 39,171, 49,128, 39,173, 50,128, 39,175, 51,128, - 39,178, 52,128, 39,179, 53,128, 39,181, 54,128, 39,184, 55,128, - 39,186, 56,128, 39,187, 57,128, 39,188, 57,138, 39, 19, 38,114, - 38,118, 38,122, 38,126, 38,130, 38,134, 38,138, 38,142, 38,146, - 38,150, 48,128, 39,189, 49,128, 39,190, 50,128, 39,154, 51,128, - 39,170, 52,128, 39,182, 53,128, 39,185, 54,128, 39,152, 55,128, - 39,180, 56,128, 39,183, 57,128, 39,172, 50,138, 39, 2, 38,178, - 38,224, 38,228, 38,232, 38,236, 38,240, 38,244, 38,248, 38,252, - 39, 0, 48,135, 39, 20, 38,196, 38,200, 38,204, 38,208, 38,212, - 38,216, 38,220, 48,128, 39,174, 49,128, 39,177, 50,128, 39, 3, - 51,128, 39, 80, 52,128, 39, 82, 53,128, 39,110, 54,128, 39,112, - 49,128, 39, 21, 50,128, 39, 22, 51,128, 39, 23, 52,128, 39, 24, - 53,128, 39, 25, 54,128, 39, 26, 55,128, 39, 27, 56,128, 39, 28, - 57,128, 39, 34, 51,138, 39, 4, 39, 28, 39, 32, 39, 36, 39, 40, - 39, 44, 39, 48, 39, 52, 39, 56, 39, 60, 39, 64, 48,128, 39, 35, - 49,128, 39, 36, 50,128, 39, 37, 51,128, 39, 38, 52,128, 39, 39, - 53,128, 38, 5, 54,128, 39, 41, 55,128, 39, 42, 56,128, 39, 43, - 57,128, 39, 44, 52,138, 38, 14, 39, 92, 39, 96, 39,100, 39,104, - 39,108, 39,112, 39,116, 39,120, 39,124, 39,128, 48,128, 39, 45, - 49,128, 39, 46, 50,128, 39, 47, 51,128, 39, 48, 52,128, 39, 49, - 53,128, 39, 50, 54,128, 39, 51, 55,128, 39, 52, 56,128, 39, 53, - 57,128, 39, 54, 53,138, 39, 6, 39,156, 39,160, 39,164, 39,168, - 39,172, 39,176, 39,180, 39,184, 39,188, 39,192, 48,128, 39, 55, - 49,128, 39, 56, 50,128, 39, 57, 51,128, 39, 58, 52,128, 39, 59, - 53,128, 39, 60, 54,128, 39, 61, 55,128, 39, 62, 56,128, 39, 63, - 57,128, 39, 64, 54,138, 39, 29, 39,220, 39,224, 39,228, 39,232, - 39,236, 39,240, 39,244, 39,248, 39,252, 40, 0, 48,128, 39, 65, - 49,128, 39, 66, 50,128, 39, 67, 51,128, 39, 68, 52,128, 39, 69, - 53,128, 39, 70, 54,128, 39, 71, 55,128, 39, 72, 56,128, 39, 73, - 57,128, 39, 74, 55,138, 39, 30, 40, 28, 40, 32, 40, 36, 40, 40, - 40, 44, 40, 48, 40, 52, 40, 56, 40, 60, 40, 64, 48,128, 39, 75, - 49,128, 37,207, 50,128, 39, 77, 51,128, 37,160, 52,128, 39, 79, - 53,128, 39, 81, 54,128, 37,178, 55,128, 37,188, 56,128, 37,198, - 57,128, 39, 86, 56,137, 39, 31, 40, 90, 40, 94, 40, 98, 40,102, - 40,106, 40,110, 40,114, 40,118, 40,122, 49,128, 37,215, 50,128, - 39, 88, 51,128, 39, 89, 52,128, 39, 90, 53,128, 39,111, 54,128, - 39,113, 55,128, 39,114, 56,128, 39,115, 57,128, 39,104, 57,138, - 39, 32, 40,150, 40,154, 40,158, 40,162, 40,166, 40,170, 40,174, - 40,178, 40,182, 40,186, 48,128, 39,105, 49,128, 39,108, 50,128, - 39,109, 51,128, 39,106, 52,128, 39,107, 53,128, 39,116, 54,128, - 39,117, 55,128, 39, 91, 56,128, 39, 92, 57,128, 39, 93, 97, 7, - 40,206, 40,216, 40,223, 40,230, 40,255, 41, 15, 41, 26,226,229, - 238,231,225,236,105,128, 9,134,227,245,244,101,128, 0,225,228, - 229,246, 97,128, 9, 6,231,117, 2, 40,237, 40,246,234,225,242, - 225,244,105,128, 10,134,242,237,245,235,232,105,128, 10, 6,237, - 225,244,242,225,231,245,242,237,245,235,232,105,128, 10, 62,242, - 245,243,241,245,225,242,101,128, 51, 3,246,239,247,229,236,243, - 233,231,110, 3, 41, 42, 41, 52, 41, 59,226,229,238,231,225,236, - 105,128, 9,190,228,229,246, 97,128, 9, 62,231,245,234,225,242, - 225,244,105,128, 10,190, 98, 4, 41, 80, 41,121, 41,130, 41,140, - 226,242,229,246,233,225,244,233,239,110, 2, 41, 95, 41,110,237, - 225,242,235,225,242,237,229,238,233,225,110,128, 5, 95,243,233, - 231,238,228,229,246, 97,128, 9,112,229,238,231,225,236,105,128, - 9,133,239,240,239,237,239,230,111,128, 49, 26,242,229,246,101, - 134, 1, 3, 41,159, 41,167, 41,178, 41,189, 41,197, 41,209,225, - 227,245,244,101,128, 30,175,227,249,242,233,236,236,233, 99,128, - 4,209,228,239,244,226,229,236,239,119,128, 30,183,231,242,225, - 246,101,128, 30,177,232,239,239,235,225,226,239,246,101,128, 30, - 179,244,233,236,228,101,128, 30,181, 99, 4, 41,227, 41,234, 42, - 57, 42,127,225,242,239,110,128, 1,206,233,242, 99, 2, 41,242, - 41,247,236,101,128, 36,208,245,237,230,236,229,120,133, 0,226, - 42, 10, 42, 18, 42, 29, 42, 37, 42, 49,225,227,245,244,101,128, - 30,165,228,239,244,226,229,236,239,119,128, 30,173,231,242,225, - 246,101,128, 30,167,232,239,239,235,225,226,239,246,101,128, 30, - 169,244,233,236,228,101,128, 30,171,245,244,101,133, 0,180, 42, - 73, 42, 84, 42,101, 42,108, 42,117,226,229,236,239,247,227,237, - 98,128, 3, 23, 99, 2, 42, 90, 42, 95,237, 98,128, 3, 1,239, - 237, 98,128, 3, 1,228,229,246, 97,128, 9, 84,236,239,247,237, - 239,100,128, 2,207,244,239,238,229,227,237, 98,128, 3, 65,249, - 242,233,236,236,233, 99,128, 4, 48,100, 5, 42,149, 42,159, 42, - 173, 42,179, 42,213,226,236,231,242,225,246,101,128, 2, 1,228, - 225,235,231,245,242,237,245,235,232,105,128, 10,113,229,246, 97, - 128, 9, 5,233,229,242,229,243,233,115,130, 0,228, 42,193, 42, - 204,227,249,242,233,236,236,233, 99,128, 4,211,237,225,227,242, - 239,110,128, 1,223,239,116, 2, 42,220, 42,228,226,229,236,239, - 119,128, 30,161,237,225,227,242,239,110,128, 1,225,101,131, 0, - 230, 42,247, 42,255, 43, 8,225,227,245,244,101,128, 1,253,235, - 239,242,229,225,110,128, 49, 80,237,225,227,242,239,110,128, 1, - 227,230,233,105, 6, 43, 33, 43, 53, 45,246, 45,252, 46, 11, 49, - 111, 48, 2, 43, 39, 43, 46,176,178,176, 56,128, 32, 21,184,185, - 180, 49,128, 32,164,177, 48, 3, 43, 62, 45, 86, 45,221, 48, 9, - 43, 82, 43,102, 43,164, 43,226, 44, 32, 44, 94, 44,156, 44,218, - 45, 24, 49, 3, 43, 90, 43, 94, 43, 98, 55,128, 4, 16, 56,128, - 4, 17, 57,128, 4, 18, 50, 10, 43,124, 43,128, 43,132, 43,136, - 43,140, 43,144, 43,148, 43,152, 43,156, 43,160, 48,128, 4, 19, - 49,128, 4, 20, 50,128, 4, 21, 51,128, 4, 1, 52,128, 4, 22, - 53,128, 4, 23, 54,128, 4, 24, 55,128, 4, 25, 56,128, 4, 26, - 57,128, 4, 27, 51, 10, 43,186, 43,190, 43,194, 43,198, 43,202, - 43,206, 43,210, 43,214, 43,218, 43,222, 48,128, 4, 28, 49,128, - 4, 29, 50,128, 4, 30, 51,128, 4, 31, 52,128, 4, 32, 53,128, - 4, 33, 54,128, 4, 34, 55,128, 4, 35, 56,128, 4, 36, 57,128, - 4, 37, 52, 10, 43,248, 43,252, 44, 0, 44, 4, 44, 8, 44, 12, - 44, 16, 44, 20, 44, 24, 44, 28, 48,128, 4, 38, 49,128, 4, 39, - 50,128, 4, 40, 51,128, 4, 41, 52,128, 4, 42, 53,128, 4, 43, - 54,128, 4, 44, 55,128, 4, 45, 56,128, 4, 46, 57,128, 4, 47, - 53, 10, 44, 54, 44, 58, 44, 62, 44, 66, 44, 70, 44, 74, 44, 78, - 44, 82, 44, 86, 44, 90, 48,128, 4,144, 49,128, 4, 2, 50,128, - 4, 3, 51,128, 4, 4, 52,128, 4, 5, 53,128, 4, 6, 54,128, - 4, 7, 55,128, 4, 8, 56,128, 4, 9, 57,128, 4, 10, 54, 10, - 44,116, 44,120, 44,124, 44,128, 44,132, 44,136, 44,140, 44,144, - 44,148, 44,152, 48,128, 4, 11, 49,128, 4, 12, 50,128, 4, 14, - 51,128,246,196, 52,128,246,197, 53,128, 4, 48, 54,128, 4, 49, - 55,128, 4, 50, 56,128, 4, 51, 57,128, 4, 52, 55, 10, 44,178, - 44,182, 44,186, 44,190, 44,194, 44,198, 44,202, 44,206, 44,210, - 44,214, 48,128, 4, 53, 49,128, 4, 81, 50,128, 4, 54, 51,128, - 4, 55, 52,128, 4, 56, 53,128, 4, 57, 54,128, 4, 58, 55,128, - 4, 59, 56,128, 4, 60, 57,128, 4, 61, 56, 10, 44,240, 44,244, - 44,248, 44,252, 45, 0, 45, 4, 45, 8, 45, 12, 45, 16, 45, 20, - 48,128, 4, 62, 49,128, 4, 63, 50,128, 4, 64, 51,128, 4, 65, - 52,128, 4, 66, 53,128, 4, 67, 54,128, 4, 68, 55,128, 4, 69, - 56,128, 4, 70, 57,128, 4, 71, 57, 10, 45, 46, 45, 50, 45, 54, - 45, 58, 45, 62, 45, 66, 45, 70, 45, 74, 45, 78, 45, 82, 48,128, - 4, 72, 49,128, 4, 73, 50,128, 4, 74, 51,128, 4, 75, 52,128, - 4, 76, 53,128, 4, 77, 54,128, 4, 78, 55,128, 4, 79, 56,128, - 4,145, 57,128, 4, 82, 49, 4, 45, 96, 45,158, 45,163, 45,189, - 48, 10, 45,118, 45,122, 45,126, 45,130, 45,134, 45,138, 45,142, - 45,146, 45,150, 45,154, 48,128, 4, 83, 49,128, 4, 84, 50,128, - 4, 85, 51,128, 4, 86, 52,128, 4, 87, 53,128, 4, 88, 54,128, - 4, 89, 55,128, 4, 90, 56,128, 4, 91, 57,128, 4, 92,177, 48, - 128, 4, 94, 52, 4, 45,173, 45,177, 45,181, 45,185, 53,128, 4, - 15, 54,128, 4, 98, 55,128, 4,114, 56,128, 4,116, 57, 5, 45, - 201, 45,205, 45,209, 45,213, 45,217, 50,128,246,198, 51,128, 4, - 95, 52,128, 4, 99, 53,128, 4,115, 54,128, 4,117, 56, 2, 45, - 227, 45,241, 51, 2, 45,233, 45,237, 49,128,246,199, 50,128,246, - 200,180, 54,128, 4,217,178,185, 57,128, 32, 14,179, 48, 2, 46, - 3, 46, 7, 48,128, 32, 15, 49,128, 32, 13,181, 55, 7, 46, 28, - 46, 98, 47,163, 47,240, 48,197, 49, 34, 49,105, 51, 2, 46, 34, - 46, 48, 56, 2, 46, 40, 46, 44, 49,128, 6,106, 56,128, 6, 12, - 57, 8, 46, 66, 46, 70, 46, 74, 46, 78, 46, 82, 46, 86, 46, 90, - 46, 94, 50,128, 6, 96, 51,128, 6, 97, 52,128, 6, 98, 53,128, - 6, 99, 54,128, 6,100, 55,128, 6,101, 56,128, 6,102, 57,128, - 6,103, 52, 7, 46,114, 46,146, 46,208, 47, 14, 47, 46, 47,102, - 47,158, 48, 5, 46,126, 46,130, 46,134, 46,138, 46,142, 48,128, - 6,104, 49,128, 6,105, 51,128, 6, 27, 55,128, 6, 31, 57,128, - 6, 33, 49, 10, 46,168, 46,172, 46,176, 46,180, 46,184, 46,188, - 46,192, 46,196, 46,200, 46,204, 48,128, 6, 34, 49,128, 6, 35, - 50,128, 6, 36, 51,128, 6, 37, 52,128, 6, 38, 53,128, 6, 39, - 54,128, 6, 40, 55,128, 6, 41, 56,128, 6, 42, 57,128, 6, 43, - 50, 10, 46,230, 46,234, 46,238, 46,242, 46,246, 46,250, 46,254, - 47, 2, 47, 6, 47, 10, 48,128, 6, 44, 49,128, 6, 45, 50,128, - 6, 46, 51,128, 6, 47, 52,128, 6, 48, 53,128, 6, 49, 54,128, - 6, 50, 55,128, 6, 51, 56,128, 6, 52, 57,128, 6, 53, 51, 5, - 47, 26, 47, 30, 47, 34, 47, 38, 47, 42, 48,128, 6, 54, 49,128, - 6, 55, 50,128, 6, 56, 51,128, 6, 57, 52,128, 6, 58, 52, 9, - 47, 66, 47, 70, 47, 74, 47, 78, 47, 82, 47, 86, 47, 90, 47, 94, - 47, 98, 48,128, 6, 64, 49,128, 6, 65, 50,128, 6, 66, 51,128, - 6, 67, 52,128, 6, 68, 53,128, 6, 69, 54,128, 6, 70, 56,128, - 6, 72, 57,128, 6, 73, 53, 9, 47,122, 47,126, 47,130, 47,134, - 47,138, 47,142, 47,146, 47,150, 47,154, 48,128, 6, 74, 49,128, - 6, 75, 50,128, 6, 76, 51,128, 6, 77, 52,128, 6, 78, 53,128, - 6, 79, 54,128, 6, 80, 55,128, 6, 81, 56,128, 6, 82,183, 48, - 128, 6, 71, 53, 3, 47,171, 47,203, 47,235, 48, 5, 47,183, 47, - 187, 47,191, 47,195, 47,199, 53,128, 6,164, 54,128, 6,126, 55, - 128, 6,134, 56,128, 6,152, 57,128, 6,175, 49, 5, 47,215, 47, - 219, 47,223, 47,227, 47,231, 49,128, 6,121, 50,128, 6,136, 51, - 128, 6,145, 52,128, 6,186, 57,128, 6,210,179, 52,128, 6,213, - 54, 7, 48, 0, 48, 5, 48, 10, 48, 15, 48, 53, 48,115, 48,177, - 179, 54,128, 32,170,180, 53,128, 5,190,181, 56,128, 5,195, 54, - 6, 48, 29, 48, 33, 48, 37, 48, 41, 48, 45, 48, 49, 52,128, 5, - 208, 53,128, 5,209, 54,128, 5,210, 55,128, 5,211, 56,128, 5, - 212, 57,128, 5,213, 55, 10, 48, 75, 48, 79, 48, 83, 48, 87, 48, - 91, 48, 95, 48, 99, 48,103, 48,107, 48,111, 48,128, 5,214, 49, - 128, 5,215, 50,128, 5,216, 51,128, 5,217, 52,128, 5,218, 53, - 128, 5,219, 54,128, 5,220, 55,128, 5,221, 56,128, 5,222, 57, - 128, 5,223, 56, 10, 48,137, 48,141, 48,145, 48,149, 48,153, 48, - 157, 48,161, 48,165, 48,169, 48,173, 48,128, 5,224, 49,128, 5, - 225, 50,128, 5,226, 51,128, 5,227, 52,128, 5,228, 53,128, 5, - 229, 54,128, 5,230, 55,128, 5,231, 56,128, 5,232, 57,128, 5, - 233, 57, 3, 48,185, 48,189, 48,193, 48,128, 5,234, 52,128,251, - 42, 53,128,251, 43, 55, 4, 48,207, 48,221, 48,241, 48,246, 48, - 2, 48,213, 48,217, 48,128,251, 75, 53,128,251, 31, 49, 3, 48, - 229, 48,233, 48,237, 54,128, 5,240, 55,128, 5,241, 56,128, 5, - 242,178, 51,128,251, 53, 57, 7, 49, 6, 49, 10, 49, 14, 49, 18, - 49, 22, 49, 26, 49, 30, 51,128, 5,180, 52,128, 5,181, 53,128, - 5,182, 54,128, 5,187, 55,128, 5,184, 56,128, 5,183, 57,128, - 5,176, 56, 3, 49, 42, 49, 86, 49, 91, 48, 7, 49, 58, 49, 62, - 49, 66, 49, 70, 49, 74, 49, 78, 49, 82, 48,128, 5,178, 49,128, - 5,177, 50,128, 5,179, 51,128, 5,194, 52,128, 5,193, 54,128, - 5,185, 55,128, 5,188,179, 57,128, 5,189, 52, 2, 49, 97, 49, - 101, 49,128, 5,191, 50,128, 5,192,185,178, 57,128, 2,188, 54, - 3, 49,119, 49,178, 49,185, 49, 4, 49,129, 49,145, 49,151, 49, - 172, 50, 2, 49,135, 49,140,180, 56,128, 33, 5,184, 57,128, 33, - 19,179,181, 50,128, 33, 22,181, 55, 3, 49,160, 49,164, 49,168, - 51,128, 32, 44, 52,128, 32, 45, 53,128, 32, 46,182,182, 52,128, - 32, 12,179,177,182, 55,128, 6,109,180,185,179, 55,128, 2,189, - 103, 2, 49,198, 49,205,242,225,246,101,128, 0,224,117, 2, 49, - 211, 49,220,234,225,242,225,244,105,128, 10,133,242,237,245,235, - 232,105,128, 10, 5,104, 2, 49,235, 49,245,233,242,225,231,225, - 238, 97,128, 48, 66,239,239,235,225,226,239,246,101,128, 30,163, - 105, 7, 50, 16, 50, 41, 50, 48, 50, 60, 50, 85, 50,101, 50,181, - 98, 2, 50, 22, 50, 31,229,238,231,225,236,105,128, 9,144,239, - 240,239,237,239,230,111,128, 49, 30,228,229,246, 97,128, 9, 16, - 229,227,249,242,233,236,236,233, 99,128, 4,213,231,117, 2, 50, - 67, 50, 76,234,225,242,225,244,105,128, 10,144,242,237,245,235, - 232,105,128, 10, 16,237,225,244,242,225,231,245,242,237,245,235, - 232,105,128, 10, 72,110, 5, 50,113, 50,122, 50,136, 50,152, 50, - 167,225,242,225,226,233, 99,128, 6, 57,230,233,238,225,236,225, - 242,225,226,233, 99,128,254,202,233,238,233,244,233,225,236,225, - 242,225,226,233, 99,128,254,203,237,229,228,233,225,236,225,242, - 225,226,233, 99,128,254,204,246,229,242,244,229,228,226,242,229, - 246,101,128, 2, 3,246,239,247,229,236,243,233,231,110, 3, 50, - 197, 50,207, 50,214,226,229,238,231,225,236,105,128, 9,200,228, - 229,246, 97,128, 9, 72,231,245,234,225,242,225,244,105,128, 10, - 200,107, 2, 50,231, 50,255,225,244,225,235,225,238, 97,129, 48, - 162, 50,243,232,225,236,230,247,233,228,244,104,128,255,113,239, - 242,229,225,110,128, 49, 79,108, 3, 51, 15, 52, 71, 52, 80,101, - 2, 51, 21, 52, 66,102,136, 5,208, 51, 41, 51, 50, 51, 65, 51, - 79, 51,168, 51,182, 52, 37, 52, 51,225,242,225,226,233, 99,128, - 6, 39,228,225,231,229,243,232,232,229,226,242,229,119,128,251, - 48,230,233,238,225,236,225,242,225,226,233, 99,128,254,142,104, - 2, 51, 85, 51,160,225,237,250, 97, 2, 51, 94, 51,127,225,226, - 239,246,101, 2, 51,104, 51,113,225,242,225,226,233, 99,128, 6, - 35,230,233,238,225,236,225,242,225,226,233, 99,128,254,132,226, - 229,236,239,119, 2, 51,137, 51,146,225,242,225,226,233, 99,128, - 6, 37,230,233,238,225,236,225,242,225,226,233, 99,128,254,136, - 229,226,242,229,119,128, 5,208,236,225,237,229,228,232,229,226, - 242,229,119,128,251, 79,237, 97, 2, 51,189, 51,225,228,228,225, - 225,226,239,246,101, 2, 51,202, 51,211,225,242,225,226,233, 99, - 128, 6, 34,230,233,238,225,236,225,242,225,226,233, 99,128,254, - 130,235,243,245,242, 97, 4, 51,239, 51,248, 52, 6, 52, 22,225, - 242,225,226,233, 99,128, 6, 73,230,233,238,225,236,225,242,225, - 226,233, 99,128,254,240,233,238,233,244,233,225,236,225,242,225, - 226,233, 99,128,254,243,237,229,228,233,225,236,225,242,225,226, - 233, 99,128,254,244,240,225,244,225,232,232,229,226,242,229,119, - 128,251, 46,241,225,237,225,244,243,232,229,226,242,229,119,128, - 251, 47,240,104,128, 33, 53,236,229,241,245,225,108,128, 34, 76, - 240,232, 97,129, 3,177, 52, 88,244,239,238,239,115,128, 3,172, - 109, 4, 52,106, 52,114, 52,125, 52,159,225,227,242,239,110,128, - 1, 1,239,238,239,243,240,225,227,101,128,255, 65,240,229,242, - 243,225,238,100,130, 0, 38, 52,139, 52,151,237,239,238,239,243, - 240,225,227,101,128,255, 6,243,237,225,236,108,128,247, 38,243, - 241,245,225,242,101,128, 51,194,110, 4, 52,178, 52,189, 53, 55, - 53, 65,226,239,240,239,237,239,230,111,128, 49, 34,103, 4, 52, - 199, 52,210, 52,224, 53, 47,226,239,240,239,237,239,230,111,128, - 49, 36,235,232,225,238,235,232,245,244,232,225,105,128, 14, 90, - 236,101,131, 34, 32, 52,235, 53, 32, 53, 39,226,242,225,227,235, - 229,116, 2, 52,247, 53, 11,236,229,230,116,129, 48, 8, 53, 0, - 246,229,242,244,233,227,225,108,128,254, 63,242,233,231,232,116, - 129, 48, 9, 53, 21,246,229,242,244,233,227,225,108,128,254, 64, - 236,229,230,116,128, 35, 41,242,233,231,232,116,128, 35, 42,243, - 244,242,239,109,128, 33, 43,239,244,229,236,229,233, 97,128, 3, - 135,117, 2, 53, 71, 53, 83,228,225,244,244,225,228,229,246, 97, - 128, 9, 82,243,246,225,242, 97, 3, 53, 95, 53,105, 53,112,226, - 229,238,231,225,236,105,128, 9,130,228,229,246, 97,128, 9, 2, - 231,245,234,225,242,225,244,105,128, 10,130,239,231,239,238,229, - 107,128, 1, 5,112, 3, 53,140, 53,164, 53,194, 97, 2, 53,146, - 53,158,225,244,239,243,241,245,225,242,101,128, 51, 0,242,229, - 110,128, 36,156,239,243,244,242,239,240,232,101, 2, 53,177, 53, - 188,225,242,237,229,238,233,225,110,128, 5, 90,237,239,100,128, - 2,188,112, 2, 53,200, 53,205,236,101,128,248,255,242,111, 2, - 53,212, 53,220,225,227,232,229,115,128, 34, 80,120, 2, 53,226, - 53,246,229,241,245,225,108,129, 34, 72, 53,236,239,242,233,237, - 225,231,101,128, 34, 82,233,237,225,244,229,236,249,229,241,245, - 225,108,128, 34, 69,114, 4, 54, 15, 54, 42, 54, 46, 54, 91,225, - 229, 97, 2, 54, 23, 54, 33,229,235,239,242,229,225,110,128, 49, - 142,235,239,242,229,225,110,128, 49,141, 99,128, 35, 18,105, 2, - 54, 52, 54, 66,231,232,244,232,225,236,230,242,233,238,103,128, - 30,154,238,103,130, 0,229, 54, 75, 54, 83,225,227,245,244,101, - 128, 1,251,226,229,236,239,119,128, 30, 1,242,239,119, 8, 54, - 111, 54,118, 54,247, 55, 57, 55,107, 55,162, 55,185, 56, 4,226, - 239,244,104,128, 33,148,100, 3, 54,126, 54,165, 54,212,225,243, - 104, 4, 54,138, 54,145, 54,152, 54,160,228,239,247,110,128, 33, - 227,236,229,230,116,128, 33,224,242,233,231,232,116,128, 33,226, - 245,112,128, 33,225,226,108, 5, 54,178, 54,185, 54,192, 54,199, - 54,207,226,239,244,104,128, 33,212,228,239,247,110,128, 33,211, - 236,229,230,116,128, 33,208,242,233,231,232,116,128, 33,210,245, - 112,128, 33,209,239,247,110,131, 33,147, 54,224, 54,231, 54,239, - 236,229,230,116,128, 33,153,242,233,231,232,116,128, 33,152,247, - 232,233,244,101,128, 33,233,104, 2, 54,253, 55, 48,229,225,100, - 4, 55, 9, 55, 19, 55, 29, 55, 40,228,239,247,238,237,239,100, - 128, 2,197,236,229,230,244,237,239,100,128, 2,194,242,233,231, - 232,244,237,239,100,128, 2,195,245,240,237,239,100,128, 2,196, - 239,242,233,250,229,120,128,248,231,236,229,230,116,131, 33,144, - 55, 70, 55, 87, 55, 99,228,226,108,129, 33,208, 55, 78,243,244, - 242,239,235,101,128, 33,205,239,246,229,242,242,233,231,232,116, - 128, 33,198,247,232,233,244,101,128, 33,230,242,233,231,232,116, - 132, 33,146, 55,123, 55,135, 55,143, 55,154,228,226,236,243,244, - 242,239,235,101,128, 33,207,232,229,225,246,121,128, 39,158,239, - 246,229,242,236,229,230,116,128, 33,196,247,232,233,244,101,128, - 33,232,244,225, 98, 2, 55,170, 55,177,236,229,230,116,128, 33, - 228,242,233,231,232,116,128, 33,229,245,112,132, 33,145, 55,198, - 55,226, 55,244, 55,252,100, 2, 55,204, 55,216,110,129, 33,149, - 55,210,226,243,101,128, 33,168,239,247,238,226,225,243,101,128, - 33,168,236,229,230,116,129, 33,150, 55,235,239,230,228,239,247, - 110,128, 33,197,242,233,231,232,116,128, 33,151,247,232,233,244, - 101,128, 33,231,246,229,242,244,229,120,128,248,230,115, 5, 56, - 25, 56,101, 56,146, 56,229, 56,239, 99, 2, 56, 31, 56, 83,233, - 105, 2, 56, 38, 56, 61,227,233,242,227,245,109,129, 0, 94, 56, - 49,237,239,238,239,243,240,225,227,101,128,255, 62,244,233,236, - 228,101,129, 0,126, 56, 71,237,239,238,239,243,240,225,227,101, - 128,255, 94,242,233,240,116,129, 2, 81, 56, 92,244,245,242,238, - 229,100,128, 2, 82,237,225,236,108, 2, 56,110, 56,121,232,233, - 242,225,231,225,238, 97,128, 48, 65,235,225,244,225,235,225,238, - 97,129, 48,161, 56,134,232,225,236,230,247,233,228,244,104,128, - 255,103,244,229,242,233,115, 2, 56,156, 56,225,107,131, 0, 42, - 56,166, 56,194, 56,217, 97, 2, 56,172, 56,186,236,244,239,238, - 229,225,242,225,226,233, 99,128, 6,109,242,225,226,233, 99,128, - 6,109,109, 2, 56,200, 56,206,225,244,104,128, 34, 23,239,238, - 239,243,240,225,227,101,128,255, 10,243,237,225,236,108,128,254, - 97,109,128, 32, 66,245,240,229,242,233,239,114,128,246,233,249, - 237,240,244,239,244,233,227,225,236,236,249,229,241,245,225,108, - 128, 34, 67,116,132, 0, 64, 57, 15, 57, 22, 57, 34, 57, 42,233, - 236,228,101,128, 0,227,237,239,238,239,243,240,225,227,101,128, - 255, 32,243,237,225,236,108,128,254,107,245,242,238,229,100,128, - 2, 80,117, 6, 57, 64, 57, 89, 57, 96, 57,121, 57,141, 57,157, - 98, 2, 57, 70, 57, 79,229,238,231,225,236,105,128, 9,148,239, - 240,239,237,239,230,111,128, 49, 32,228,229,246, 97,128, 9, 20, - 231,117, 2, 57,103, 57,112,234,225,242,225,244,105,128, 10,148, - 242,237,245,235,232,105,128, 10, 20,236,229,238,231,244,232,237, - 225,242,235,226,229,238,231,225,236,105,128, 9,215,237,225,244, - 242,225,231,245,242,237,245,235,232,105,128, 10, 76,246,239,247, - 229,236,243,233,231,110, 3, 57,173, 57,183, 57,190,226,229,238, - 231,225,236,105,128, 9,204,228,229,246, 97,128, 9, 76,231,245, - 234,225,242,225,244,105,128, 10,204,246,225,231,242,225,232,225, - 228,229,246, 97,128, 9, 61,121, 2, 57,221, 57,233,226,225,242, - 237,229,238,233,225,110,128, 5, 97,233,110,130, 5,226, 57,242, - 58, 1,225,236,244,239,238,229,232,229,226,242,229,119,128,251, - 32,232,229,226,242,229,119,128, 5,226, 98,144, 0, 98, 58, 46, - 58,181, 58,192, 58,201, 58,226, 60, 11, 60, 73, 60,146, 62, 72, - 62, 84, 62,127, 62,135, 62,145, 64, 15, 64, 39, 64, 48, 97, 7, - 58, 62, 58, 72, 58, 96, 58,103, 58,128, 58,152, 58,163,226,229, - 238,231,225,236,105,128, 9,172,227,235,243,236,225,243,104,129, - 0, 92, 58, 84,237,239,238,239,243,240,225,227,101,128,255, 60, - 228,229,246, 97,128, 9, 44,231,117, 2, 58,110, 58,119,234,225, - 242,225,244,105,128, 10,172,242,237,245,235,232,105,128, 10, 44, - 104, 2, 58,134, 58,144,233,242,225,231,225,238, 97,128, 48,112, - 244,244,232,225,105,128, 14, 63,235,225,244,225,235,225,238, 97, - 128, 48,208,114,129, 0,124, 58,169,237,239,238,239,243,240,225, - 227,101,128,255, 92,226,239,240,239,237,239,230,111,128, 49, 5, - 227,233,242,227,236,101,128, 36,209,228,239,116, 2, 58,209, 58, - 218,225,227,227,229,238,116,128, 30, 3,226,229,236,239,119,128, - 30, 5,101, 6, 58,240, 59, 5, 59, 28, 59,170, 59,181, 59,193, - 225,237,229,228,243,233,248,244,229,229,238,244,232,238,239,244, - 229,115,128, 38,108, 99, 2, 59, 11, 59, 18,225,245,243,101,128, - 34, 53,249,242,233,236,236,233, 99,128, 4, 49,104, 5, 59, 40, - 59, 49, 59, 63, 59, 93, 59,152,225,242,225,226,233, 99,128, 6, - 40,230,233,238,225,236,225,242,225,226,233, 99,128,254,144,105, - 2, 59, 69, 59, 84,238,233,244,233,225,236,225,242,225,226,233, - 99,128,254,145,242,225,231,225,238, 97,128, 48,121,237,101, 2, - 59,100, 59,113,228,233,225,236,225,242,225,226,233, 99,128,254, - 146,229,237,105, 2, 59,121, 59,136,238,233,244,233,225,236,225, - 242,225,226,233, 99,128,252,159,243,239,236,225,244,229,228,225, - 242,225,226,233, 99,128,252, 8,238,239,239,238,230,233,238,225, - 236,225,242,225,226,233, 99,128,252,109,235,225,244,225,235,225, - 238, 97,128, 48,217,238,225,242,237,229,238,233,225,110,128, 5, - 98,116,132, 5,209, 59,205, 59,225, 59,245, 59,254, 97,129, 3, - 178, 59,211,243,249,237,226,239,236,231,242,229,229,107,128, 3, - 208,228,225,231,229,243,104,129,251, 49, 59,236,232,229,226,242, - 229,119,128,251, 49,232,229,226,242,229,119,128, 5,209,242,225, - 230,229,232,229,226,242,229,119,128,251, 76,104, 2, 60, 17, 60, - 67, 97, 3, 60, 25, 60, 35, 60, 42,226,229,238,231,225,236,105, - 128, 9,173,228,229,246, 97,128, 9, 45,231,117, 2, 60, 49, 60, - 58,234,225,242,225,244,105,128, 10,173,242,237,245,235,232,105, - 128, 10, 45,239,239,107,128, 2, 83,105, 5, 60, 85, 60, 96, 60, - 107, 60,121, 60,135,232,233,242,225,231,225,238, 97,128, 48,115, - 235,225,244,225,235,225,238, 97,128, 48,211,236,225,226,233,225, - 236,227,236,233,227,107,128, 2,152,238,228,233,231,245,242,237, - 245,235,232,105,128, 10, 2,242,245,243,241,245,225,242,101,128, - 51, 49,108, 3, 60,154, 62, 55, 62, 66, 97, 2, 60,160, 62, 50, - 227,107, 6, 60,175, 60,184, 60,221, 61,114, 61,169, 61,221,227, - 233,242,227,236,101,128, 37,207,100, 2, 60,190, 60,199,233,225, - 237,239,238,100,128, 37,198,239,247,238,240,239,233,238,244,233, - 238,231,244,242,233,225,238,231,236,101,128, 37,188,108, 2, 60, - 227, 61, 74,101, 2, 60,233, 61, 13,230,244,240,239,233,238,244, - 233,238,103, 2, 60,248, 61, 2,240,239,233,238,244,229,114,128, - 37,196,244,242,233,225,238,231,236,101,128, 37,192,238,244,233, - 227,245,236,225,242,226,242,225,227,235,229,116, 2, 61, 33, 61, - 53,236,229,230,116,129, 48, 16, 61, 42,246,229,242,244,233,227, - 225,108,128,254, 59,242,233,231,232,116,129, 48, 17, 61, 63,246, - 229,242,244,233,227,225,108,128,254, 60,239,247,229,114, 2, 61, - 83, 61, 98,236,229,230,244,244,242,233,225,238,231,236,101,128, - 37,227,242,233,231,232,244,244,242,233,225,238,231,236,101,128, - 37,226,114, 2, 61,120, 61,131,229,227,244,225,238,231,236,101, - 128, 37,172,233,231,232,244,240,239,233,238,244,233,238,103, 2, - 61,148, 61,158,240,239,233,238,244,229,114,128, 37,186,244,242, - 233,225,238,231,236,101,128, 37,182,115, 3, 61,177, 61,207, 61, - 215,109, 2, 61,183, 61,195,225,236,236,243,241,245,225,242,101, - 128, 37,170,233,236,233,238,231,230,225,227,101,128, 38, 59,241, - 245,225,242,101,128, 37,160,244,225,114,128, 38, 5,245,240,112, - 2, 61,229, 62, 11,229,114, 2, 61,236, 61,251,236,229,230,244, - 244,242,233,225,238,231,236,101,128, 37,228,242,233,231,232,244, - 244,242,233,225,238,231,236,101,128, 37,229,239,233,238,244,233, - 238,103, 2, 62, 23, 62, 39,243,237,225,236,236,244,242,233,225, - 238,231,236,101,128, 37,180,244,242,233,225,238,231,236,101,128, - 37,178,238,107,128, 36, 35,233,238,229,226,229,236,239,119,128, - 30, 7,239,227,107,128, 37,136,237,239,238,239,243,240,225,227, - 101,128,255, 66,111, 3, 62, 92, 62,105, 62,116,226,225,233,237, - 225,233,244,232,225,105,128, 14, 26,232,233,242,225,231,225,238, - 97,128, 48,124,235,225,244,225,235,225,238, 97,128, 48,220,240, - 225,242,229,110,128, 36,157,241,243,241,245,225,242,101,128, 51, - 195,114, 4, 62,155, 63,149, 63,222, 64, 5,225, 99, 2, 62,162, - 63, 56,101, 3, 62,170, 62,175, 62,243,229,120,128,248,244,236, - 229,230,116,133, 0,123, 62,192, 62,197, 62,219, 62,227, 62,232, - 226,116,128,248,243,109, 2, 62,203, 62,208,233,100,128,248,242, - 239,238,239,243,240,225,227,101,128,255, 91,243,237,225,236,108, - 128,254, 91,244,112,128,248,241,246,229,242,244,233,227,225,108, - 128,254, 55,242,233,231,232,116,133, 0,125, 63, 5, 63, 10, 63, - 32, 63, 40, 63, 45,226,116,128,248,254,109, 2, 63, 16, 63, 21, - 233,100,128,248,253,239,238,239,243,240,225,227,101,128,255, 93, - 243,237,225,236,108,128,254, 92,244,112,128,248,252,246,229,242, - 244,233,227,225,108,128,254, 56,235,229,116, 2, 63, 64, 63,106, - 236,229,230,116,132, 0, 91, 63, 79, 63, 84, 63, 89, 63,101,226, - 116,128,248,240,229,120,128,248,239,237,239,238,239,243,240,225, - 227,101,128,255, 59,244,112,128,248,238,242,233,231,232,116,132, - 0, 93, 63,122, 63,127, 63,132, 63,144,226,116,128,248,251,229, - 120,128,248,250,237,239,238,239,243,240,225,227,101,128,255, 61, - 244,112,128,248,249,229,246,101,131, 2,216, 63,161, 63,172, 63, - 178,226,229,236,239,247,227,237, 98,128, 3, 46,227,237, 98,128, - 3, 6,233,238,246,229,242,244,229,100, 3, 63,193, 63,204, 63, - 210,226,229,236,239,247,227,237, 98,128, 3, 47,227,237, 98,128, - 3, 17,228,239,245,226,236,229,227,237, 98,128, 3, 97,233,228, - 231,101, 2, 63,231, 63,242,226,229,236,239,247,227,237, 98,128, - 3, 42,233,238,246,229,242,244,229,228,226,229,236,239,247,227, - 237, 98,128, 3, 58,239,235,229,238,226,225,114,128, 0,166,115, - 2, 64, 21, 64, 29,244,242,239,235,101,128, 1,128,245,240,229, - 242,233,239,114,128,246,234,244,239,240,226,225,114,128, 1,131, - 117, 3, 64, 56, 64, 67, 64, 78,232,233,242,225,231,225,238, 97, - 128, 48,118,235,225,244,225,235,225,238, 97,128, 48,214,236,108, - 2, 64, 85, 64,115,229,116,130, 32, 34, 64, 94, 64,104,233,238, - 246,229,242,243,101,128, 37,216,239,240,229,242,225,244,239,114, - 128, 34, 25,243,229,249,101,128, 37,206, 99,143, 0, 99, 64,156, - 65,105, 65,116, 65,180, 65,211, 66, 48, 67,215, 68,199, 69, 43, - 69, 92, 72, 84, 72, 92, 72,102, 72,114, 72,147, 97, 9, 64,176, - 64,187, 64,197, 64,204, 64,211, 64,236, 64,246, 65, 42, 65, 51, - 225,242,237,229,238,233,225,110,128, 5,110,226,229,238,231,225, - 236,105,128, 9,154,227,245,244,101,128, 1, 7,228,229,246, 97, - 128, 9, 26,231,117, 2, 64,218, 64,227,234,225,242,225,244,105, - 128, 10,154,242,237,245,235,232,105,128, 10, 26,236,243,241,245, - 225,242,101,128, 51,136,238,228,242,225,226,233,238,228,117, 4, - 65, 8, 65, 18, 65, 24, 65, 31,226,229,238,231,225,236,105,128, - 9,129,227,237, 98,128, 3, 16,228,229,246, 97,128, 9, 1,231, - 245,234,225,242,225,244,105,128, 10,129,240,243,236,239,227,107, - 128, 33,234,114, 3, 65, 59, 65, 65, 65, 91,229,239,102,128, 33, - 5,239,110,130, 2,199, 65, 74, 65, 85,226,229,236,239,247,227, - 237, 98,128, 3, 44,227,237, 98,128, 3, 12,242,233,225,231,229, - 242,229,244,245,242,110,128, 33,181,226,239,240,239,237,239,230, - 111,128, 49, 24, 99, 4, 65,126, 65,133, 65,152, 65,174,225,242, - 239,110,128, 1, 13,229,228,233,236,236, 97,129, 0,231, 65,144, - 225,227,245,244,101,128, 30, 9,233,242, 99, 2, 65,160, 65,165, - 236,101,128, 36,210,245,237,230,236,229,120,128, 1, 9,245,242, - 108,128, 2, 85,100, 2, 65,186, 65,202,239,116,129, 1, 11, 65, - 193,225,227,227,229,238,116,128, 1, 11,243,241,245,225,242,101, - 128, 51,197,101, 2, 65,217, 65,233,228,233,236,236, 97,129, 0, - 184, 65,227,227,237, 98,128, 3, 39,238,116,132, 0,162, 65,246, - 66, 14, 66, 26, 66, 37,105, 2, 65,252, 66, 4,231,242,225,228, - 101,128, 33, 3,238,230,229,242,233,239,114,128,246,223,237,239, - 238,239,243,240,225,227,101,128,255,224,239,236,228,243,244,249, - 236,101,128,247,162,243,245,240,229,242,233,239,114,128,246,224, - 104, 5, 66, 60, 66,123, 66,134, 67, 62, 67,154, 97, 4, 66, 70, - 66, 81, 66, 91, 66, 98,225,242,237,229,238,233,225,110,128, 5, - 121,226,229,238,231,225,236,105,128, 9,155,228,229,246, 97,128, - 9, 27,231,117, 2, 66,105, 66,114,234,225,242,225,244,105,128, - 10,155,242,237,245,235,232,105,128, 10, 27,226,239,240,239,237, - 239,230,111,128, 49, 20,101, 6, 66,148, 66,168, 66,192, 67, 4, - 67, 16, 67, 37,225,226,235,232,225,243,233,225,238,227,249,242, - 233,236,236,233, 99,128, 4,189, 99, 2, 66,174, 66,182,235,237, - 225,242,107,128, 39, 19,249,242,233,236,236,233, 99,128, 4, 71, - 100, 2, 66,198, 66,242,229,243,227,229,238,228,229,114, 2, 66, - 211, 66,231,225,226,235,232,225,243,233,225,238,227,249,242,233, - 236,236,233, 99,128, 4,191,227,249,242,233,236,236,233, 99,128, - 4,183,233,229,242,229,243,233,243,227,249,242,233,236,236,233, - 99,128, 4,245,232,225,242,237,229,238,233,225,110,128, 5,115, - 235,232,225,235,225,243,243,233,225,238,227,249,242,233,236,236, - 233, 99,128, 4,204,246,229,242,244,233,227,225,236,243,244,242, - 239,235,229,227,249,242,233,236,236,233, 99,128, 4,185,105,129, - 3,199, 67, 68,229,245,227,104, 4, 67, 81, 67,116, 67,131, 67, - 140, 97, 2, 67, 87, 67,102,227,233,242,227,236,229,235,239,242, - 229,225,110,128, 50,119,240,225,242,229,238,235,239,242,229,225, - 110,128, 50, 23,227,233,242,227,236,229,235,239,242,229,225,110, - 128, 50,105,235,239,242,229,225,110,128, 49, 74,240,225,242,229, - 238,235,239,242,229,225,110,128, 50, 9,111, 2, 67,160, 67,210, - 227,104, 3, 67,169, 67,191, 67,201,225,110, 2, 67,176, 67,184, - 231,244,232,225,105,128, 14, 10,244,232,225,105,128, 14, 8,233, - 238,231,244,232,225,105,128, 14, 9,239,229,244,232,225,105,128, - 14, 12,239,107,128, 1,136,105, 2, 67,221, 68, 67,229,245, 99, - 5, 67,235, 68, 14, 68, 29, 68, 38, 68, 52, 97, 2, 67,241, 68, - 0,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,118, - 240,225,242,229,238,235,239,242,229,225,110,128, 50, 22,227,233, - 242,227,236,229,235,239,242,229,225,110,128, 50,104,235,239,242, - 229,225,110,128, 49, 72,240,225,242,229,238,235,239,242,229,225, - 110,128, 50, 8,245,240,225,242,229,238,235,239,242,229,225,110, - 128, 50, 28,242, 99, 2, 68, 74, 68,169,236,101,132, 37,203, 68, - 87, 68, 98, 68,103, 68,127,237,245,236,244,233,240,236,121,128, - 34,151,239,116,128, 34,153,112, 2, 68,109, 68,115,236,245,115, - 128, 34,149,239,243,244,225,236,237,225,242,107,128, 48, 54,247, - 233,244,104, 2, 68,136, 68,152,236,229,230,244,232,225,236,230, - 226,236,225,227,107,128, 37,208,242,233,231,232,244,232,225,236, - 230,226,236,225,227,107,128, 37,209,245,237,230,236,229,120,130, - 2,198, 68,182, 68,193,226,229,236,239,247,227,237, 98,128, 3, - 45,227,237, 98,128, 3, 2,108, 3, 68,207, 68,213, 69, 11,229, - 225,114,128, 35, 39,233,227,107, 4, 68,225, 68,236, 68,245, 68, - 255,225,236,246,229,239,236,225,114,128, 1,194,228,229,238,244, - 225,108,128, 1,192,236,225,244,229,242,225,108,128, 1,193,242, - 229,244,242,239,230,236,229,120,128, 1,195,245, 98,129, 38, 99, - 69, 18,243,245,233,116, 2, 69, 27, 69, 35,226,236,225,227,107, - 128, 38, 99,247,232,233,244,101,128, 38,103,109, 3, 69, 51, 69, - 65, 69, 76,227,245,226,229,228,243,241,245,225,242,101,128, 51, - 164,239,238,239,243,240,225,227,101,128,255, 67,243,241,245,225, - 242,229,228,243,241,245,225,242,101,128, 51,160,111, 8, 69,110, - 69,121, 69,208, 70,150, 71,179, 71,210, 72, 61, 72, 70,225,242, - 237,229,238,233,225,110,128, 5,129,236,239,110,131, 0, 58, 69, - 133, 69,158, 69,177,237,239,110, 2, 69,141, 69,149,229,244,225, - 242,121,128, 32,161,239,243,240,225,227,101,128,255, 26,115, 2, - 69,164, 69,170,233,231,110,128, 32,161,237,225,236,108,128,254, - 85,244,242,233,225,238,231,245,236,225,114, 2, 69,192, 69,202, - 232,225,236,230,237,239,100,128, 2,209,237,239,100,128, 2,208, - 109, 2, 69,214, 70,143,237, 97,134, 0, 44, 69,231, 70, 39, 70, - 50, 70, 62, 70, 92, 70,115, 97, 3, 69,239, 70, 9, 70, 17,226, - 239,246,101, 2, 69,248, 69,254,227,237, 98,128, 3, 19,242,233, - 231,232,244,227,237, 98,128, 3, 21,227,227,229,238,116,128,246, - 195,114, 2, 70, 23, 70, 30,225,226,233, 99,128, 6, 12,237,229, - 238,233,225,110,128, 5, 93,233,238,230,229,242,233,239,114,128, - 246,225,237,239,238,239,243,240,225,227,101,128,255, 12,242,229, - 246,229,242,243,229,100, 2, 70, 75, 70, 86,225,226,239,246,229, - 227,237, 98,128, 3, 20,237,239,100,128, 2,189,115, 2, 70, 98, - 70,105,237,225,236,108,128,254, 80,245,240,229,242,233,239,114, - 128,246,226,244,245,242,238,229,100, 2, 70,126, 70,137,225,226, - 239,246,229,227,237, 98,128, 3, 18,237,239,100,128, 2,187,240, - 225,243,115,128, 38, 60,110, 2, 70,156, 70,165,231,242,245,229, - 238,116,128, 34, 69,116, 2, 70,171, 70,185,239,245,242,233,238, - 244,229,231,242,225,108,128, 34, 46,242,239,108,142, 35, 3, 70, - 219, 70,225, 70,240, 70,255, 71, 43, 71, 88, 71,102, 71,107, 71, - 112, 71,117, 71,123, 71,128, 71,169, 71,174,193,195, 75,128, 0, - 6, 66, 2, 70,231, 70,236,197, 76,128, 0, 7, 83,128, 0, 8, - 67, 2, 70,246, 70,251,193, 78,128, 0, 24, 82,128, 0, 13, 68, - 3, 71, 7, 71, 33, 71, 38, 67, 4, 71, 17, 71, 21, 71, 25, 71, - 29, 49,128, 0, 17, 50,128, 0, 18, 51,128, 0, 19, 52,128, 0, - 20,197, 76,128, 0,127,204, 69,128, 0, 16, 69, 5, 71, 55, 71, - 59, 71, 64, 71, 69, 71, 74, 77,128, 0, 25,206, 81,128, 0, 5, - 207, 84,128, 0, 4,211, 67,128, 0, 27, 84, 2, 71, 80, 71, 84, - 66,128, 0, 23, 88,128, 0, 3, 70, 2, 71, 94, 71, 98, 70,128, - 0, 12, 83,128, 0, 28,199, 83,128, 0, 29,200, 84,128, 0, 9, - 204, 70,128, 0, 10,206,193, 75,128, 0, 21,210, 83,128, 0, 30, - 83, 5, 71,140, 71,144, 71,154, 71,159, 71,164, 73,128, 0, 15, - 79,129, 0, 14, 71,150, 84,128, 0, 2,212, 88,128, 0, 1,213, - 66,128, 0, 26,217, 78,128, 0, 22,213, 83,128, 0, 31,214, 84, - 128, 0, 11,240,249,242,233,231,232,116,129, 0,169, 71,191,115, - 2, 71,197, 71,203,225,238,115,128,248,233,229,242,233,102,128, - 246,217,114, 2, 71,216, 72, 44,238,229,242,226,242,225,227,235, - 229,116, 2, 71,231, 72, 9,236,229,230,116,130, 48, 12, 71,242, - 71,254,232,225,236,230,247,233,228,244,104,128,255, 98,246,229, - 242,244,233,227,225,108,128,254, 65,242,233,231,232,116,130, 48, - 13, 72, 21, 72, 33,232,225,236,230,247,233,228,244,104,128,255, - 99,246,229,242,244,233,227,225,108,128,254, 66,240,239,242,225, - 244,233,239,238,243,241,245,225,242,101,128, 51,127,243,241,245, - 225,242,101,128, 51,199,246,229,242,235,231,243,241,245,225,242, - 101,128, 51,198,240,225,242,229,110,128, 36,158,242,245,250,229, - 233,242,111,128, 32,162,243,244,242,229,244,227,232,229,100,128, - 2,151,245,114, 2, 72,121, 72,139,236,121, 2, 72,128, 72,134, - 225,238,100,128, 34,207,239,114,128, 34,206,242,229,238,227,121, - 128, 0,164,249,114, 4, 72,158, 72,166, 72,173, 72,181,194,242, - 229,246,101,128,246,209,198,236,229,120,128,246,210,226,242,229, - 246,101,128,246,212,230,236,229,120,128,246,213,100,146, 0,100, - 72,228, 74,110, 75,134, 75,194, 76,114, 77, 68, 77,130, 78, 59, - 78, 72, 78, 81, 78,107, 78,132, 78,141, 79,208, 79,216, 79,227, - 79,247, 80, 19, 97, 11, 72,252, 73, 7, 73, 17, 73, 89, 73,152, - 73,163, 73,174, 73,243, 74, 49, 74, 55, 74, 85,225,242,237,229, - 238,233,225,110,128, 5,100,226,229,238,231,225,236,105,128, 9, - 166,100, 5, 73, 29, 73, 38, 73, 44, 73, 58, 73, 74,225,242,225, - 226,233, 99,128, 6, 54,229,246, 97,128, 9, 38,230,233,238,225, - 236,225,242,225,226,233, 99,128,254,190,233,238,233,244,233,225, - 236,225,242,225,226,233, 99,128,254,191,237,229,228,233,225,236, - 225,242,225,226,233, 99,128,254,192,103, 3, 73, 97, 73,114, 73, - 128,229,243,104,129, 5,188, 73,105,232,229,226,242,229,119,128, - 5,188,231,229,114,129, 32, 32, 73,122,228,226,108,128, 32, 33, - 117, 2, 73,134, 73,143,234,225,242,225,244,105,128, 10,166,242, - 237,245,235,232,105,128, 10, 38,232,233,242,225,231,225,238, 97, - 128, 48, 96,235,225,244,225,235,225,238, 97,128, 48,192,108, 3, - 73,182, 73,191, 73,229,225,242,225,226,233, 99,128, 6, 47,229, - 116,130, 5,211, 73,200, 73,220,228,225,231,229,243,104,129,251, - 51, 73,211,232,229,226,242,229,119,128,251, 51,232,229,226,242, - 229,119,128, 5,211,230,233,238,225,236,225,242,225,226,233, 99, - 128,254,170,237,237, 97, 3, 73,253, 74, 6, 74, 18,225,242,225, - 226,233, 99,128, 6, 79,236,239,247,225,242,225,226,233, 99,128, - 6, 79,244,225,238, 97, 2, 74, 27, 74, 41,236,244,239,238,229, - 225,242,225,226,233, 99,128, 6, 76,242,225,226,233, 99,128, 6, - 76,238,228, 97,128, 9,100,242,231, 97, 2, 74, 63, 74, 72,232, - 229,226,242,229,119,128, 5,167,236,229,230,244,232,229,226,242, - 229,119,128, 5,167,243,233,225,240,238,229,245,237,225,244,225, - 227,249,242,233,236,236,233,227,227,237, 98,128, 4,133, 98, 3, - 74,118, 75,115, 75,125,108, 9, 74,138, 74,146, 75, 3, 75, 11, - 75, 27, 75, 38, 75, 56, 75, 70, 75, 81,199,242,225,246,101,128, - 246,211, 97, 2, 74,152, 74,209,238,231,236,229,226,242,225,227, - 235,229,116, 2, 74,168, 74,188,236,229,230,116,129, 48, 10, 74, - 177,246,229,242,244,233,227,225,108,128,254, 61,242,233,231,232, - 116,129, 48, 11, 74,198,246,229,242,244,233,227,225,108,128,254, - 62,114, 2, 74,215, 74,236,227,232,233,238,246,229,242,244,229, - 228,226,229,236,239,247,227,237, 98,128, 3, 43,242,239,119, 2, - 74,244, 74,251,236,229,230,116,128, 33,212,242,233,231,232,116, - 128, 33,210,228,225,238,228, 97,128, 9,101,231,242,225,246,101, - 129,246,214, 75, 21,227,237, 98,128, 3, 15,233,238,244,229,231, - 242,225,108,128, 34, 44,236,239,247,236,233,238,101,129, 32, 23, - 75, 50,227,237, 98,128, 3, 51,239,246,229,242,236,233,238,229, - 227,237, 98,128, 3, 63,240,242,233,237,229,237,239,100,128, 2, - 186,246,229,242,244,233,227,225,108, 2, 75, 94, 75,100,226,225, - 114,128, 32, 22,236,233,238,229,225,226,239,246,229,227,237, 98, - 128, 3, 14,239,240,239,237,239,230,111,128, 49, 9,243,241,245, - 225,242,101,128, 51,200, 99, 4, 75,144, 75,151, 75,160, 75,187, - 225,242,239,110,128, 1, 15,229,228,233,236,236, 97,128, 30, 17, - 233,242, 99, 2, 75,168, 75,173,236,101,128, 36,211,245,237,230, - 236,229,248,226,229,236,239,119,128, 30, 19,242,239,225,116,128, - 1, 17,100, 4, 75,204, 76, 29, 76, 39, 76, 90, 97, 4, 75,214, - 75,224, 75,231, 76, 0,226,229,238,231,225,236,105,128, 9,161, - 228,229,246, 97,128, 9, 33,231,117, 2, 75,238, 75,247,234,225, - 242,225,244,105,128, 10,161,242,237,245,235,232,105,128, 10, 33, - 108, 2, 76, 6, 76, 15,225,242,225,226,233, 99,128, 6,136,230, - 233,238,225,236,225,242,225,226,233, 99,128,251,137,228,232,225, - 228,229,246, 97,128, 9, 92,232, 97, 3, 76, 48, 76, 58, 76, 65, - 226,229,238,231,225,236,105,128, 9,162,228,229,246, 97,128, 9, - 34,231,117, 2, 76, 72, 76, 81,234,225,242,225,244,105,128, 10, - 162,242,237,245,235,232,105,128, 10, 34,239,116, 2, 76, 97, 76, - 106,225,227,227,229,238,116,128, 30, 11,226,229,236,239,119,128, - 30, 13,101, 8, 76,132, 76,185, 76,192, 76,217, 76,227, 76,238, - 77, 27, 77, 63, 99, 2, 76,138, 76,175,233,237,225,236,243,229, - 240,225,242,225,244,239,114, 2, 76,156, 76,165,225,242,225,226, - 233, 99,128, 6,107,240,229,242,243,233,225,110,128, 6,107,249, - 242,233,236,236,233, 99,128, 4, 52,231,242,229,101,128, 0,176, - 232,105, 2, 76,199, 76,208,232,229,226,242,229,119,128, 5,173, - 242,225,231,225,238, 97,128, 48,103,233,227,239,240,244,233, 99, - 128, 3,239,235,225,244,225,235,225,238, 97,128, 48,199,108, 2, - 76,244, 77, 11,229,244,101, 2, 76,252, 77, 3,236,229,230,116, - 128, 35, 43,242,233,231,232,116,128, 35, 38,244, 97,129, 3,180, - 77, 18,244,245,242,238,229,100,128, 1,141,238,239,237,233,238, - 225,244,239,242,237,233,238,245,243,239,238,229,238,245,237,229, - 242,225,244,239,242,226,229,238,231,225,236,105,128, 9,248,250, - 104,128, 2,164,104, 2, 77, 74, 77,124, 97, 3, 77, 82, 77, 92, - 77, 99,226,229,238,231,225,236,105,128, 9,167,228,229,246, 97, - 128, 9, 39,231,117, 2, 77,106, 77,115,234,225,242,225,244,105, - 128, 10,167,242,237,245,235,232,105,128, 10, 39,239,239,107,128, - 2, 87,105, 6, 77,144, 77,193, 77,253, 78, 8, 78, 19, 78, 29, - 97, 2, 77,150, 77,172,236,249,244,233,235,225,244,239,238,239, - 115,129, 3,133, 77,166,227,237, 98,128, 3, 68,237,239,238,100, - 129, 38,102, 77,181,243,245,233,244,247,232,233,244,101,128, 38, - 98,229,242,229,243,233,115,133, 0,168, 77,212, 77,220, 77,231, - 77,237, 77,245,225,227,245,244,101,128,246,215,226,229,236,239, - 247,227,237, 98,128, 3, 36,227,237, 98,128, 3, 8,231,242,225, - 246,101,128,246,216,244,239,238,239,115,128, 3,133,232,233,242, - 225,231,225,238, 97,128, 48, 98,235,225,244,225,235,225,238, 97, - 128, 48,194,244,244,239,237,225,242,107,128, 48, 3,246,105, 2, - 78, 36, 78, 47,228,101,129, 0,247, 78, 43,115,128, 34, 35,243, - 233,239,238,243,236,225,243,104,128, 34, 21,234,229,227,249,242, - 233,236,236,233, 99,128, 4, 82,235,243,232,225,228,101,128, 37, - 147,108, 2, 78, 87, 78, 98,233,238,229,226,229,236,239,119,128, - 30, 15,243,241,245,225,242,101,128, 51,151,109, 2, 78,113, 78, - 121,225,227,242,239,110,128, 1, 17,239,238,239,243,240,225,227, - 101,128,255, 68,238,226,236,239,227,107,128, 37,132,111, 10, 78, - 163, 78,175, 78,185, 78,196, 78,207, 79, 23, 79, 28, 79, 39, 79, - 154, 79,180,227,232,225,228,225,244,232,225,105,128, 14, 14,228, - 229,235,244,232,225,105,128, 14, 20,232,233,242,225,231,225,238, - 97,128, 48,105,235,225,244,225,235,225,238, 97,128, 48,201,236, - 236,225,114,132, 0, 36, 78,222, 78,233, 78,245, 79, 0,233,238, - 230,229,242,233,239,114,128,246,227,237,239,238,239,243,240,225, - 227,101,128,255, 4,239,236,228,243,244,249,236,101,128,247, 36, - 115, 2, 79, 6, 79, 13,237,225,236,108,128,254,105,245,240,229, - 242,233,239,114,128,246,228,238,103,128, 32,171,242,245,243,241, - 245,225,242,101,128, 51, 38,116, 6, 79, 53, 79, 70, 79, 92, 79, - 103, 79,135, 79,142,225,227,227,229,238,116,129, 2,217, 79, 64, - 227,237, 98,128, 3, 7,226,229,236,239,247, 99, 2, 79, 81, 79, - 86,237, 98,128, 3, 35,239,237, 98,128, 3, 35,235,225,244,225, - 235,225,238, 97,128, 48,251,236,229,243,115, 2, 79,112, 79,116, - 105,128, 1, 49,106,129,246,190, 79,122,243,244,242,239,235,229, - 232,239,239,107,128, 2,132,237,225,244,104,128, 34,197,244,229, - 228,227,233,242,227,236,101,128, 37,204,245,226,236,229,249,239, - 228,240,225,244,225,104,129,251, 31, 79,171,232,229,226,242,229, - 119,128,251, 31,247,238,244,225,227,107, 2, 79,191, 79,202,226, - 229,236,239,247,227,237, 98,128, 3, 30,237,239,100,128, 2,213, - 240,225,242,229,110,128, 36,159,243,245,240,229,242,233,239,114, - 128,246,235,116, 2, 79,233, 79,239,225,233,108,128, 2, 86,239, - 240,226,225,114,128, 1,140,117, 2, 79,253, 80, 8,232,233,242, - 225,231,225,238, 97,128, 48,101,235,225,244,225,235,225,238, 97, - 128, 48,197,122,132, 1,243, 80, 31, 80, 40, 80, 59, 80, 96,225, - 236,244,239,238,101,128, 2,163, 99, 2, 80, 46, 80, 53,225,242, - 239,110,128, 1,198,245,242,108,128, 2,165,101, 2, 80, 65, 80, - 85,225,226,235,232,225,243,233,225,238,227,249,242,233,236,236, - 233, 99,128, 4,225,227,249,242,233,236,236,233, 99,128, 4, 85, - 232,229,227,249,242,233,236,236,233, 99,128, 4, 95,101,151, 0, - 101, 80,159, 80,178, 80,212, 81,186, 81,248, 82, 25, 82, 37, 82, - 60, 82,113, 83,225, 84, 27, 84,129, 84,245, 85,124, 85,199, 85, - 230, 86, 36, 86, 89, 87, 24, 87,157, 87,177, 87,221, 88, 56, 97, - 2, 80,165, 80,172,227,245,244,101,128, 0,233,242,244,104,128, - 38, 65, 98, 3, 80,186, 80,195, 80,205,229,238,231,225,236,105, - 128, 9,143,239,240,239,237,239,230,111,128, 49, 28,242,229,246, - 101,128, 1, 21, 99, 5, 80,224, 81, 41, 81, 55, 81, 87, 81,176, - 97, 2, 80,230, 81, 35,238,228,242, 97, 3, 80,241, 80,248, 81, - 3,228,229,246, 97,128, 9, 13,231,245,234,225,242,225,244,105, - 128, 10,141,246,239,247,229,236,243,233,231,110, 2, 81, 17, 81, - 24,228,229,246, 97,128, 9, 69,231,245,234,225,242,225,244,105, - 128, 10,197,242,239,110,128, 1, 27,229,228,233,236,236,225,226, - 242,229,246,101,128, 30, 29,104, 2, 81, 61, 81, 72,225,242,237, - 229,238,233,225,110,128, 5,101,249,233,247,238,225,242,237,229, - 238,233,225,110,128, 5,135,233,242, 99, 2, 81, 95, 81,100,236, - 101,128, 36,212,245,237,230,236,229,120,134, 0,234, 81,121, 81, - 129, 81,137, 81,148, 81,156, 81,168,225,227,245,244,101,128, 30, - 191,226,229,236,239,119,128, 30, 25,228,239,244,226,229,236,239, - 119,128, 30,199,231,242,225,246,101,128, 30,193,232,239,239,235, - 225,226,239,246,101,128, 30,195,244,233,236,228,101,128, 30,197, - 249,242,233,236,236,233, 99,128, 4, 84,100, 4, 81,196, 81,206, - 81,212, 81,222,226,236,231,242,225,246,101,128, 2, 5,229,246, - 97,128, 9, 15,233,229,242,229,243,233,115,128, 0,235,239,116, - 130, 1, 23, 81,231, 81,240,225,227,227,229,238,116,128, 1, 23, - 226,229,236,239,119,128, 30,185,101, 2, 81,254, 82, 9,231,245, - 242,237,245,235,232,105,128, 10, 15,237,225,244,242,225,231,245, - 242,237,245,235,232,105,128, 10, 71,230,227,249,242,233,236,236, - 233, 99,128, 4, 68,103, 2, 82, 43, 82, 50,242,225,246,101,128, - 0,232,245,234,225,242,225,244,105,128, 10,143,104, 4, 82, 70, - 82, 81, 82, 92, 82,102,225,242,237,229,238,233,225,110,128, 5, - 103,226,239,240,239,237,239,230,111,128, 49, 29,233,242,225,231, - 225,238, 97,128, 48, 72,239,239,235,225,226,239,246,101,128, 30, - 187,105, 4, 82,123, 82,134, 83,192, 83,207,226,239,240,239,237, - 239,230,111,128, 49, 31,231,232,116,142, 0, 56, 82,168, 82,177, - 82,187, 82,217, 82,224, 83, 6, 83, 31, 83, 76, 83,110, 83,122, - 83,133, 83,166, 83,174, 83,185,225,242,225,226,233, 99,128, 6, - 104,226,229,238,231,225,236,105,128, 9,238,227,233,242,227,236, - 101,129, 36,103, 82,198,233,238,246,229,242,243,229,243,225,238, - 243,243,229,242,233,102,128, 39,145,228,229,246, 97,128, 9,110, - 229,229,110, 2, 82,232, 82,241,227,233,242,227,236,101,128, 36, - 113,112, 2, 82,247, 82,254,225,242,229,110,128, 36,133,229,242, - 233,239,100,128, 36,153,231,117, 2, 83, 13, 83, 22,234,225,242, - 225,244,105,128, 10,238,242,237,245,235,232,105,128, 10,110,104, - 2, 83, 37, 83, 63, 97, 2, 83, 43, 83, 54,227,235,225,242,225, - 226,233, 99,128, 6,104,238,231,250,232,239,117,128, 48, 40,238, - 239,244,229,226,229,225,237,229,100,128, 38,107,105, 2, 83, 82, - 83,100,228,229,239,231,242,225,240,232,233,227,240,225,242,229, - 110,128, 50, 39,238,230,229,242,233,239,114,128, 32,136,237,239, - 238,239,243,240,225,227,101,128,255, 24,239,236,228,243,244,249, - 236,101,128,247, 56,112, 2, 83,139, 83,146,225,242,229,110,128, - 36,123,229,114, 2, 83,153, 83,159,233,239,100,128, 36,143,243, - 233,225,110,128, 6,248,242,239,237,225,110,128, 33,119,243,245, - 240,229,242,233,239,114,128, 32,120,244,232,225,105,128, 14, 88, - 238,246,229,242,244,229,228,226,242,229,246,101,128, 2, 7,239, - 244,233,230,233,229,228,227,249,242,233,236,236,233, 99,128, 4, - 101,107, 2, 83,231, 83,255,225,244,225,235,225,238, 97,129, 48, - 168, 83,243,232,225,236,230,247,233,228,244,104,128,255,116,111, - 2, 84, 5, 84, 20,238,235,225,242,231,245,242,237,245,235,232, - 105,128, 10,116,242,229,225,110,128, 49, 84,108, 3, 84, 35, 84, - 46, 84,107,227,249,242,233,236,236,233, 99,128, 4, 59,101, 2, - 84, 52, 84, 59,237,229,238,116,128, 34, 8,246,229,110, 3, 84, - 69, 84, 78, 84, 99,227,233,242,227,236,101,128, 36,106,112, 2, - 84, 84, 84, 91,225,242,229,110,128, 36,126,229,242,233,239,100, - 128, 36,146,242,239,237,225,110,128, 33,122,236,233,240,243,233, - 115,129, 32, 38, 84,118,246,229,242,244,233,227,225,108,128, 34, - 238,109, 5, 84,141, 84,169, 84,180, 84,200, 84,211,225,227,242, - 239,110,130, 1, 19, 84,153, 84,161,225,227,245,244,101,128, 30, - 23,231,242,225,246,101,128, 30, 21,227,249,242,233,236,236,233, - 99,128, 4, 60,228,225,243,104,129, 32, 20, 84,189,246,229,242, - 244,233,227,225,108,128,254, 49,239,238,239,243,240,225,227,101, - 128,255, 69,112, 2, 84,217, 84,237,232,225,243,233,243,237,225, - 242,235,225,242,237,229,238,233,225,110,128, 5, 91,244,249,243, - 229,116,128, 34, 5,110, 6, 85, 3, 85, 14, 85, 25, 85, 69, 85, - 101, 85,116,226,239,240,239,237,239,230,111,128, 49, 35,227,249, - 242,233,236,236,233, 99,128, 4, 61,100, 2, 85, 31, 85, 50,225, - 243,104,129, 32, 19, 85, 39,246,229,242,244,233,227,225,108,128, - 254, 50,229,243,227,229,238,228,229,242,227,249,242,233,236,236, - 233, 99,128, 4,163,103,130, 1, 75, 85, 77, 85, 88,226,239,240, - 239,237,239,230,111,128, 49, 37,232,229,227,249,242,233,236,236, - 233, 99,128, 4,165,232,239,239,235,227,249,242,233,236,236,233, - 99,128, 4,200,243,240,225,227,101,128, 32, 2,111, 3, 85,132, - 85,140, 85,149,231,239,238,229,107,128, 1, 25,235,239,242,229, - 225,110,128, 49, 83,240,229,110,130, 2, 91, 85,159, 85,168,227, - 236,239,243,229,100,128, 2,154,242,229,246,229,242,243,229,100, - 130, 2, 92, 85,183, 85,192,227,236,239,243,229,100,128, 2, 94, - 232,239,239,107,128, 2, 93,112, 2, 85,205, 85,212,225,242,229, - 110,128, 36,160,243,233,236,239,110,129, 3,181, 85,222,244,239, - 238,239,115,128, 3,173,241,117, 2, 85,237, 86, 25,225,108,130, - 0, 61, 85,246, 86, 2,237,239,238,239,243,240,225,227,101,128, - 255, 29,115, 2, 86, 8, 86, 15,237,225,236,108,128,254,102,245, - 240,229,242,233,239,114,128, 32,124,233,246,225,236,229,238,227, - 101,128, 34, 97,114, 3, 86, 44, 86, 55, 86, 66,226,239,240,239, - 237,239,230,111,128, 49, 38,227,249,242,233,236,236,233, 99,128, - 4, 64,229,246,229,242,243,229,100,129, 2, 88, 86, 78,227,249, - 242,233,236,236,233, 99,128, 4, 77,115, 6, 86,103, 86,114, 86, - 134, 86,215, 87, 4, 87, 14,227,249,242,233,236,236,233, 99,128, - 4, 65,228,229,243,227,229,238,228,229,242,227,249,242,233,236, - 236,233, 99,128, 4,171,104,132, 2,131, 86,146, 86,153, 86,184, - 86,199,227,245,242,108,128, 2,134,239,242,116, 2, 86,161, 86, - 168,228,229,246, 97,128, 9, 14,246,239,247,229,236,243,233,231, - 238,228,229,246, 97,128, 9, 70,242,229,246,229,242,243,229,228, - 236,239,239,112,128, 1,170,243,241,245,225,244,242,229,246,229, - 242,243,229,100,128, 2,133,237,225,236,108, 2, 86,224, 86,235, - 232,233,242,225,231,225,238, 97,128, 48, 71,235,225,244,225,235, - 225,238, 97,129, 48,167, 86,248,232,225,236,230,247,233,228,244, - 104,128,255,106,244,233,237,225,244,229,100,128, 33, 46,245,240, - 229,242,233,239,114,128,246,236,116, 5, 87, 36, 87, 62, 87, 66, - 87, 83, 87,149, 97,130, 3,183, 87, 44, 87, 54,242,237,229,238, - 233,225,110,128, 5,104,244,239,238,239,115,128, 3,174,104,128, - 0,240,233,236,228,101,129, 30,189, 87, 75,226,229,236,239,119, - 128, 30, 27,238,225,232,244, 97, 3, 87, 95, 87,127, 87,136,230, - 239,245,235,104, 2, 87,105, 87,114,232,229,226,242,229,119,128, - 5,145,236,229,230,244,232,229,226,242,229,119,128, 5,145,232, - 229,226,242,229,119,128, 5,145,236,229,230,244,232,229,226,242, - 229,119,128, 5,145,245,242,238,229,100,128, 1,221,117, 2, 87, - 163, 87,172,235,239,242,229,225,110,128, 49, 97,242,111,128, 32, - 172,246,239,247,229,236,243,233,231,110, 3, 87,193, 87,203, 87, - 210,226,229,238,231,225,236,105,128, 9,199,228,229,246, 97,128, - 9, 71,231,245,234,225,242,225,244,105,128, 10,199,120, 2, 87, - 227, 88, 44,227,236,225,109,132, 0, 33, 87,242, 87,253, 88, 24, - 88, 36,225,242,237,229,238,233,225,110,128, 5, 92,100, 2, 88, - 3, 88, 8,226,108,128, 32, 60,239,247,110,129, 0,161, 88, 16, - 243,237,225,236,108,128,247,161,237,239,238,239,243,240,225,227, - 101,128,255, 1,243,237,225,236,108,128,247, 33,233,243,244,229, - 238,244,233,225,108,128, 34, 3,250,104,131, 2,146, 88, 67, 88, - 86, 88, 97, 99, 2, 88, 73, 88, 80,225,242,239,110,128, 1,239, - 245,242,108,128, 2,147,242,229,246,229,242,243,229,100,128, 1, - 185,244,225,233,108,128, 1,186,102,140, 0,102, 88,132, 88,214, - 88,225, 88,234, 88,246, 89, 93, 89,109, 91,117, 91,130, 91,156, - 93, 33, 93, 41, 97, 4, 88,142, 88,149, 88,160, 88,171,228,229, - 246, 97,128, 9, 94,231,245,242,237,245,235,232,105,128, 10, 94, - 232,242,229,238,232,229,233,116,128, 33, 9,244,232, 97, 3, 88, - 181, 88,190, 88,202,225,242,225,226,233, 99,128, 6, 78,236,239, - 247,225,242,225,226,233, 99,128, 6, 78,244,225,238,225,242,225, - 226,233, 99,128, 6, 75,226,239,240,239,237,239,230,111,128, 49, - 8,227,233,242,227,236,101,128, 36,213,228,239,244,225,227,227, - 229,238,116,128, 30, 31,101, 3, 88,254, 89, 76, 89, 86,104, 4, - 89, 8, 89, 31, 89, 45, 89, 61,225,114, 2, 89, 15, 89, 22,225, - 226,233, 99,128, 6, 65,237,229,238,233,225,110,128, 5,134,230, - 233,238,225,236,225,242,225,226,233, 99,128,254,210,233,238,233, - 244,233,225,236,225,242,225,226,233, 99,128,254,211,237,229,228, - 233,225,236,225,242,225,226,233, 99,128,254,212,233,227,239,240, - 244,233, 99,128, 3,229,237,225,236,101,128, 38, 64,102,130,251, - 0, 89,101, 89,105,105,128,251, 3,108,128,251, 4,105,136,251, - 1, 89,129, 89,169, 89,180, 89,202, 90, 68, 90, 85, 90, 93, 90, - 106,230,244,229,229,110, 2, 89,139, 89,148,227,233,242,227,236, - 101,128, 36,110,112, 2, 89,154, 89,161,225,242,229,110,128, 36, - 130,229,242,233,239,100,128, 36,150,231,245,242,229,228,225,243, - 104,128, 32, 18,236,236,229,100, 2, 89,189, 89,195,226,239,120, - 128, 37,160,242,229,227,116,128, 37,172,238,225,108, 5, 89,216, - 89,255, 90, 16, 90, 33, 90, 49,235,225,102,130, 5,218, 89,226, - 89,246,228,225,231,229,243,104,129,251, 58, 89,237,232,229,226, - 242,229,119,128,251, 58,232,229,226,242,229,119,128, 5,218,237, - 229,109,129, 5,221, 90, 7,232,229,226,242,229,119,128, 5,221, - 238,245,110,129, 5,223, 90, 24,232,229,226,242,229,119,128, 5, - 223,240,101,129, 5,227, 90, 40,232,229,226,242,229,119,128, 5, - 227,244,243,225,228,105,129, 5,229, 90, 59,232,229,226,242,229, - 119,128, 5,229,242,243,244,244,239,238,229,227,232,233,238,229, - 243,101,128, 2,201,243,232,229,249,101,128, 37,201,244,225,227, - 249,242,233,236,236,233, 99,128, 4,115,246,101,142, 0, 53, 90, - 139, 90,148, 90,158, 90,188, 90,195, 90,205, 90,230, 91, 1, 91, - 35, 91, 47, 91, 58, 91, 91, 91, 99, 91,110,225,242,225,226,233, - 99,128, 6,101,226,229,238,231,225,236,105,128, 9,235,227,233, - 242,227,236,101,129, 36,100, 90,169,233,238,246,229,242,243,229, - 243,225,238,243,243,229,242,233,102,128, 39,142,228,229,246, 97, - 128, 9,107,229,233,231,232,244,232,115,128, 33, 93,231,117, 2, - 90,212, 90,221,234,225,242,225,244,105,128, 10,235,242,237,245, - 235,232,105,128, 10,107,232, 97, 2, 90,237, 90,248,227,235,225, - 242,225,226,233, 99,128, 6,101,238,231,250,232,239,117,128, 48, - 37,105, 2, 91, 7, 91, 25,228,229,239,231,242,225,240,232,233, - 227,240,225,242,229,110,128, 50, 36,238,230,229,242,233,239,114, - 128, 32,133,237,239,238,239,243,240,225,227,101,128,255, 21,239, - 236,228,243,244,249,236,101,128,247, 53,112, 2, 91, 64, 91, 71, - 225,242,229,110,128, 36,120,229,114, 2, 91, 78, 91, 84,233,239, - 100,128, 36,140,243,233,225,110,128, 6,245,242,239,237,225,110, - 128, 33,116,243,245,240,229,242,233,239,114,128, 32,117,244,232, - 225,105,128, 14, 85,108,129,251, 2, 91,123,239,242,233,110,128, - 1,146,109, 2, 91,136, 91,147,239,238,239,243,240,225,227,101, - 128,255, 70,243,241,245,225,242,101,128, 51,153,111, 4, 91,166, - 91,188, 91,200, 91,207,230, 97, 2, 91,173, 91,181,238,244,232, - 225,105,128, 14, 31,244,232,225,105,128, 14, 29,238,231,237,225, - 238,244,232,225,105,128, 14, 79,242,225,236,108,128, 34, 0,245, - 114,142, 0, 52, 91,240, 91,249, 92, 3, 92, 33, 92, 40, 92, 65, - 92, 92, 92,126, 92,138, 92,157, 92,168, 92,201, 92,209, 92,220, - 225,242,225,226,233, 99,128, 6,100,226,229,238,231,225,236,105, - 128, 9,234,227,233,242,227,236,101,129, 36, 99, 92, 14,233,238, - 246,229,242,243,229,243,225,238,243,243,229,242,233,102,128, 39, - 141,228,229,246, 97,128, 9,106,231,117, 2, 92, 47, 92, 56,234, - 225,242,225,244,105,128, 10,234,242,237,245,235,232,105,128, 10, - 106,232, 97, 2, 92, 72, 92, 83,227,235,225,242,225,226,233, 99, - 128, 6,100,238,231,250,232,239,117,128, 48, 36,105, 2, 92, 98, - 92,116,228,229,239,231,242,225,240,232,233,227,240,225,242,229, - 110,128, 50, 35,238,230,229,242,233,239,114,128, 32,132,237,239, - 238,239,243,240,225,227,101,128,255, 20,238,245,237,229,242,225, - 244,239,242,226,229,238,231,225,236,105,128, 9,247,239,236,228, - 243,244,249,236,101,128,247, 52,112, 2, 92,174, 92,181,225,242, - 229,110,128, 36,119,229,114, 2, 92,188, 92,194,233,239,100,128, - 36,139,243,233,225,110,128, 6,244,242,239,237,225,110,128, 33, - 115,243,245,240,229,242,233,239,114,128, 32,116,116, 2, 92,226, - 93, 8,229,229,110, 2, 92,234, 92,243,227,233,242,227,236,101, - 128, 36,109,112, 2, 92,249, 93, 0,225,242,229,110,128, 36,129, - 229,242,233,239,100,128, 36,149,104, 2, 93, 14, 93, 19,225,105, - 128, 14, 84,244,239,238,229,227,232,233,238,229,243,101,128, 2, - 203,240,225,242,229,110,128, 36,161,242, 97, 2, 93, 48, 93, 56, - 227,244,233,239,110,128, 32, 68,238, 99,128, 32,163,103,144, 0, - 103, 93, 97, 94, 43, 94, 66, 94,127, 94,144, 95, 65, 96, 58, 96, - 143, 96,156, 97, 14, 97, 39, 97, 67, 97, 89, 98, 34, 98, 56, 98, - 158, 97, 9, 93,117, 93,127, 93,134, 93,141, 93,205, 93,230, 93, - 241, 93,252, 94, 30,226,229,238,231,225,236,105,128, 9,151,227, - 245,244,101,128, 1,245,228,229,246, 97,128, 9, 23,102, 4, 93, - 151, 93,160, 93,174, 93,190,225,242,225,226,233, 99,128, 6,175, - 230,233,238,225,236,225,242,225,226,233, 99,128,251,147,233,238, - 233,244,233,225,236,225,242,225,226,233, 99,128,251,148,237,229, - 228,233,225,236,225,242,225,226,233, 99,128,251,149,231,117, 2, - 93,212, 93,221,234,225,242,225,244,105,128, 10,151,242,237,245, - 235,232,105,128, 10, 23,232,233,242,225,231,225,238, 97,128, 48, - 76,235,225,244,225,235,225,238, 97,128, 48,172,237,237, 97,130, - 3,179, 94, 6, 94, 19,236,225,244,233,238,243,237,225,236,108, - 128, 2, 99,243,245,240,229,242,233,239,114,128, 2,224,238,231, - 233,225,227,239,240,244,233, 99,128, 3,235, 98, 2, 94, 49, 94, - 59,239,240,239,237,239,230,111,128, 49, 13,242,229,246,101,128, - 1, 31, 99, 4, 94, 76, 94, 83, 94, 92, 94,114,225,242,239,110, - 128, 1,231,229,228,233,236,236, 97,128, 1, 35,233,242, 99, 2, - 94,100, 94,105,236,101,128, 36,214,245,237,230,236,229,120,128, - 1, 29,239,237,237,225,225,227,227,229,238,116,128, 1, 35,228, - 239,116,129, 1, 33, 94,135,225,227,227,229,238,116,128, 1, 33, - 101, 6, 94,158, 94,169, 94,180, 94,191, 94,210, 95, 56,227,249, - 242,233,236,236,233, 99,128, 4, 51,232,233,242,225,231,225,238, - 97,128, 48, 82,235,225,244,225,235,225,238, 97,128, 48,178,239, - 237,229,244,242,233,227,225,236,236,249,229,241,245,225,108,128, - 34, 81,114, 3, 94,218, 95, 11, 95, 21,229,243,104, 3, 94,228, - 94,243, 94,252,225,227,227,229,238,244,232,229,226,242,229,119, - 128, 5,156,232,229,226,242,229,119,128, 5,243,237,245,241,228, - 225,237,232,229,226,242,229,119,128, 5,157,237,225,238,228,226, - 236,115,128, 0,223,243,232,225,249,233,109, 2, 95, 32, 95, 47, - 225,227,227,229,238,244,232,229,226,242,229,119,128, 5,158,232, - 229,226,242,229,119,128, 5,244,244,225,237,225,242,107,128, 48, - 19,104, 5, 95, 77, 95,210, 96, 17, 96, 42, 96, 48, 97, 4, 95, - 87, 95, 97, 95,120, 95,145,226,229,238,231,225,236,105,128, 9, - 152,100, 2, 95,103, 95,114,225,242,237,229,238,233,225,110,128, - 5,114,229,246, 97,128, 9, 24,231,117, 2, 95,127, 95,136,234, - 225,242,225,244,105,128, 10,152,242,237,245,235,232,105,128, 10, - 24,233,110, 4, 95,156, 95,165, 95,179, 95,195,225,242,225,226, - 233, 99,128, 6, 58,230,233,238,225,236,225,242,225,226,233, 99, - 128,254,206,233,238,233,244,233,225,236,225,242,225,226,233, 99, - 128,254,207,237,229,228,233,225,236,225,242,225,226,233, 99,128, - 254,208,101, 3, 95,218, 95,239, 96, 0,237,233,228,228,236,229, - 232,239,239,235,227,249,242,233,236,236,233, 99,128, 4,149,243, - 244,242,239,235,229,227,249,242,233,236,236,233, 99,128, 4,147, - 245,240,244,245,242,238,227,249,242,233,236,236,233, 99,128, 4, - 145,232, 97, 2, 96, 24, 96, 31,228,229,246, 97,128, 9, 90,231, - 245,242,237,245,235,232,105,128, 10, 90,239,239,107,128, 2, 96, - 250,243,241,245,225,242,101,128, 51,147,105, 3, 96, 66, 96, 77, - 96, 88,232,233,242,225,231,225,238, 97,128, 48, 78,235,225,244, - 225,235,225,238, 97,128, 48,174,109, 2, 96, 94, 96,105,225,242, - 237,229,238,233,225,110,128, 5, 99,229,108,130, 5,210, 96,114, - 96,134,228,225,231,229,243,104,129,251, 50, 96,125,232,229,226, - 242,229,119,128,251, 50,232,229,226,242,229,119,128, 5,210,234, - 229,227,249,242,233,236,236,233, 99,128, 4, 83,236,239,244,244, - 225,108, 2, 96,167, 96,184,233,238,246,229,242,244,229,228,243, - 244,242,239,235,101,128, 1,190,243,244,239,112,132, 2,148, 96, - 199, 96,210, 96,216, 96,248,233,238,246,229,242,244,229,100,128, - 2,150,237,239,100,128, 2,192,242,229,246,229,242,243,229,100, - 130, 2,149, 96,231, 96,237,237,239,100,128, 2,193,243,245,240, - 229,242,233,239,114,128, 2,228,243,244,242,239,235,101,129, 2, - 161, 97, 3,242,229,246,229,242,243,229,100,128, 2,162,109, 2, - 97, 20, 97, 28,225,227,242,239,110,128, 30, 33,239,238,239,243, - 240,225,227,101,128,255, 71,111, 2, 97, 45, 97, 56,232,233,242, - 225,231,225,238, 97,128, 48, 84,235,225,244,225,235,225,238, 97, - 128, 48,180,240, 97, 2, 97, 74, 97, 80,242,229,110,128, 36,162, - 243,241,245,225,242,101,128, 51,172,114, 2, 97, 95, 97,192, 97, - 2, 97,101, 97,109,228,233,229,238,116,128, 34, 7,246,101,134, - 0, 96, 97,126, 97,137, 97,154, 97,161, 97,170, 97,182,226,229, - 236,239,247,227,237, 98,128, 3, 22, 99, 2, 97,143, 97,148,237, - 98,128, 3, 0,239,237, 98,128, 3, 0,228,229,246, 97,128, 9, - 83,236,239,247,237,239,100,128, 2,206,237,239,238,239,243,240, - 225,227,101,128,255, 64,244,239,238,229,227,237, 98,128, 3, 64, - 229,225,244,229,114,132, 0, 62, 97,208, 97,227, 97,239, 98, 26, - 229,241,245,225,108,129, 34,101, 97,218,239,242,236,229,243,115, - 128, 34,219,237,239,238,239,243,240,225,227,101,128,255, 30,111, - 2, 97,245, 98, 15,114, 2, 97,251, 98, 8,229,241,245,233,246, - 225,236,229,238,116,128, 34,115,236,229,243,115,128, 34,119,246, - 229,242,229,241,245,225,108,128, 34,103,243,237,225,236,108,128, - 254,101,115, 2, 98, 40, 98, 48,227,242,233,240,116,128, 2, 97, - 244,242,239,235,101,128, 1,229,117, 4, 98, 66, 98, 77, 98,134, - 98,145,232,233,242,225,231,225,238, 97,128, 48, 80,233,108, 2, - 98, 84, 98,109,236,229,237,239,116, 2, 98, 94, 98,101,236,229, - 230,116,128, 0,171,242,233,231,232,116,128, 0,187,243,233,238, - 231,108, 2, 98,119, 98,126,236,229,230,116,128, 32, 57,242,233, - 231,232,116,128, 32, 58,235,225,244,225,235,225,238, 97,128, 48, - 176,242,225,237,245,243,241,245,225,242,101,128, 51, 24,249,243, - 241,245,225,242,101,128, 51,201,104,144, 0,104, 98,204,101, 90, - 101,125,101,162,101,202,103, 90,103,110,104, 75,104, 87,104, 99, - 105,167,105,175,105,186,105,195,106, 19,106, 23, 97, 13, 98,232, - 99, 15, 99, 25, 99, 55, 99, 80, 99,158, 99,170, 99,195, 99,210, - 99,239, 99,252,100, 54,100, 63, 97, 2, 98,238, 99, 1,226,235, - 232,225,243,233,225,238,227,249,242,233,236,236,233, 99,128, 4, - 169,236,244,239,238,229,225,242,225,226,233, 99,128, 6,193,226, - 229,238,231,225,236,105,128, 9,185,228,101, 2, 99, 32, 99, 50, - 243,227,229,238,228,229,242,227,249,242,233,236,236,233, 99,128, - 4,179,246, 97,128, 9, 57,231,117, 2, 99, 62, 99, 71,234,225, - 242,225,244,105,128, 10,185,242,237,245,235,232,105,128, 10, 57, - 104, 4, 99, 90, 99, 99, 99,113, 99,143,225,242,225,226,233, 99, - 128, 6, 45,230,233,238,225,236,225,242,225,226,233, 99,128,254, - 162,105, 2, 99,119, 99,134,238,233,244,233,225,236,225,242,225, - 226,233, 99,128,254,163,242,225,231,225,238, 97,128, 48,111,237, - 229,228,233,225,236,225,242,225,226,233, 99,128,254,164,233,244, - 245,243,241,245,225,242,101,128, 51, 42,235,225,244,225,235,225, - 238, 97,129, 48,207, 99,183,232,225,236,230,247,233,228,244,104, - 128,255,138,236,225,238,244,231,245,242,237,245,235,232,105,128, - 10, 77,237,250, 97, 2, 99,218, 99,227,225,242,225,226,233, 99, - 128, 6, 33,236,239,247,225,242,225,226,233, 99,128, 6, 33,238, - 231,245,236,230,233,236,236,229,114,128, 49,100,114, 2,100, 2, - 100, 18,228,243,233,231,238,227,249,242,233,236,236,233, 99,128, - 4, 74,240,239,239,110, 2,100, 27,100, 40,236,229,230,244,226, - 225,242,226,245,112,128, 33,188,242,233,231,232,244,226,225,242, - 226,245,112,128, 33,192,243,241,245,225,242,101,128, 51,202,244, - 225,102, 3,100, 73,100,165,101, 0,240,225,244,225,104,134, 5, - 178,100, 93,100, 98,100,112,100,121,100,136,100,152,177, 54,128, - 5,178, 50, 2,100,104,100,108, 51,128, 5,178,102,128, 5,178, - 232,229,226,242,229,119,128, 5,178,238,225,242,242,239,247,232, - 229,226,242,229,119,128, 5,178,241,245,225,242,244,229,242,232, - 229,226,242,229,119,128, 5,178,247,233,228,229,232,229,226,242, - 229,119,128, 5,178,241,225,237,225,244,115,135, 5,179,100,188, - 100,193,100,198,100,203,100,212,100,227,100,243,177, 98,128, 5, - 179,178, 56,128, 5,179,179, 52,128, 5,179,232,229,226,242,229, - 119,128, 5,179,238,225,242,242,239,247,232,229,226,242,229,119, - 128, 5,179,241,245,225,242,244,229,242,232,229,226,242,229,119, - 128, 5,179,247,233,228,229,232,229,226,242,229,119,128, 5,179, - 243,229,231,239,108,135, 5,177,101, 22,101, 27,101, 32,101, 37, - 101, 46,101, 61,101, 77,177, 55,128, 5,177,178, 52,128, 5,177, - 179, 48,128, 5,177,232,229,226,242,229,119,128, 5,177,238,225, - 242,242,239,247,232,229,226,242,229,119,128, 5,177,241,245,225, - 242,244,229,242,232,229,226,242,229,119,128, 5,177,247,233,228, - 229,232,229,226,242,229,119,128, 5,177, 98, 3,101, 98,101,103, - 101,113,225,114,128, 1, 39,239,240,239,237,239,230,111,128, 49, - 15,242,229,246,229,226,229,236,239,119,128, 30, 43, 99, 2,101, - 131,101,140,229,228,233,236,236, 97,128, 30, 41,233,242, 99, 2, - 101,148,101,153,236,101,128, 36,215,245,237,230,236,229,120,128, - 1, 37,100, 2,101,168,101,178,233,229,242,229,243,233,115,128, - 30, 39,239,116, 2,101,185,101,194,225,227,227,229,238,116,128, - 30, 35,226,229,236,239,119,128, 30, 37,101,136, 5,212,101,222, - 101,255,102, 19,102,248,103, 8,103, 53,103, 62,103, 75,225,242, - 116,129, 38,101,101,230,243,245,233,116, 2,101,239,101,247,226, - 236,225,227,107,128, 38,101,247,232,233,244,101,128, 38, 97,228, - 225,231,229,243,104,129,251, 52,102, 10,232,229,226,242,229,119, - 128,251, 52,104, 6,102, 33,102, 61,102, 69,102,119,102,165,102, - 214, 97, 2,102, 39,102, 53,236,244,239,238,229,225,242,225,226, - 233, 99,128, 6,193,242,225,226,233, 99,128, 6, 71,229,226,242, - 229,119,128, 5,212,230,233,238,225,236, 97, 2,102, 80,102,111, - 236,116, 2,102, 87,102, 99,239,238,229,225,242,225,226,233, 99, - 128,251,167,244,247,239,225,242,225,226,233, 99,128,254,234,242, - 225,226,233, 99,128,254,234,232,225,237,250,225,225,226,239,246, - 101, 2,102,134,102,148,230,233,238,225,236,225,242,225,226,233, - 99,128,251,165,233,243,239,236,225,244,229,228,225,242,225,226, - 233, 99,128,251,164,105, 2,102,171,102,205,238,233,244,233,225, - 236, 97, 2,102,183,102,197,236,244,239,238,229,225,242,225,226, - 233, 99,128,251,168,242,225,226,233, 99,128,254,235,242,225,231, - 225,238, 97,128, 48,120,237,229,228,233,225,236, 97, 2,102,226, - 102,240,236,244,239,238,229,225,242,225,226,233, 99,128,251,169, - 242,225,226,233, 99,128,254,236,233,243,229,233,229,242,225,243, - 241,245,225,242,101,128, 51,123,107, 2,103, 14,103, 38,225,244, - 225,235,225,238, 97,129, 48,216,103, 26,232,225,236,230,247,233, - 228,244,104,128,255,141,245,244,225,225,242,245,243,241,245,225, - 242,101,128, 51, 54,238,231,232,239,239,107,128, 2,103,242,245, - 244,245,243,241,245,225,242,101,128, 51, 57,116,129, 5,215,103, - 81,232,229,226,242,229,119,128, 5,215,232,239,239,107,129, 2, - 102,103, 99,243,245,240,229,242,233,239,114,128, 2,177,105, 4, - 103,120,103,205,103,216,103,241,229,245,104, 4,103,132,103,167, - 103,182,103,191, 97, 2,103,138,103,153,227,233,242,227,236,229, - 235,239,242,229,225,110,128, 50,123,240,225,242,229,238,235,239, - 242,229,225,110,128, 50, 27,227,233,242,227,236,229,235,239,242, - 229,225,110,128, 50,109,235,239,242,229,225,110,128, 49, 78,240, - 225,242,229,238,235,239,242,229,225,110,128, 50, 13,232,233,242, - 225,231,225,238, 97,128, 48,114,235,225,244,225,235,225,238, 97, - 129, 48,210,103,229,232,225,236,230,247,233,228,244,104,128,255, - 139,242,233,113,134, 5,180,104, 3,104, 8,104, 22,104, 31,104, - 46,104, 62,177, 52,128, 5,180, 50, 2,104, 14,104, 18, 49,128, - 5,180,100,128, 5,180,232,229,226,242,229,119,128, 5,180,238, - 225,242,242,239,247,232,229,226,242,229,119,128, 5,180,241,245, - 225,242,244,229,242,232,229,226,242,229,119,128, 5,180,247,233, - 228,229,232,229,226,242,229,119,128, 5,180,236,233,238,229,226, - 229,236,239,119,128, 30,150,237,239,238,239,243,240,225,227,101, - 128,255, 72,111, 9,104,119,104,130,104,154,104,179,105, 11,105, - 24,105,110,105,150,105,161,225,242,237,229,238,233,225,110,128, - 5,112,232,105, 2,104,137,104,145,240,244,232,225,105,128, 14, - 43,242,225,231,225,238, 97,128, 48,123,235,225,244,225,235,225, - 238, 97,129, 48,219,104,167,232,225,236,230,247,233,228,244,104, - 128,255,142,236,225,109,135, 5,185,104,199,104,204,104,209,104, - 214,104,223,104,238,104,254,177, 57,128, 5,185,178, 54,128, 5, - 185,179, 50,128, 5,185,232,229,226,242,229,119,128, 5,185,238, - 225,242,242,239,247,232,229,226,242,229,119,128, 5,185,241,245, - 225,242,244,229,242,232,229,226,242,229,119,128, 5,185,247,233, - 228,229,232,229,226,242,229,119,128, 5,185,238,239,235,232,245, - 235,244,232,225,105,128, 14, 46,111, 2,105, 30,105,100,107, 4, - 105, 40,105, 52,105, 58,105, 80,225,226,239,246,229,227,239,237, - 98,128, 3, 9,227,237, 98,128, 3, 9,240,225,236,225,244,225, - 236,233,250,229,228,226,229,236,239,247,227,237, 98,128, 3, 33, - 242,229,244,242,239,230,236,229,248,226,229,236,239,247,227,237, - 98,128, 3, 34,238,243,241,245,225,242,101,128, 51, 66,114, 2, - 105,116,105,143,105, 2,105,122,105,131,227,239,240,244,233, 99, - 128, 3,233,250,239,238,244,225,236,226,225,114,128, 32, 21,238, - 227,237, 98,128, 3, 27,244,243,240,242,233,238,231,115,128, 38, - 104,245,243,101,128, 35, 2,240,225,242,229,110,128, 36,163,243, - 245,240,229,242,233,239,114,128, 2,176,244,245,242,238,229,100, - 128, 2,101,117, 4,105,205,105,216,105,229,105,254,232,233,242, - 225,231,225,238, 97,128, 48,117,233,233,244,239,243,241,245,225, - 242,101,128, 51, 51,235,225,244,225,235,225,238, 97,129, 48,213, - 105,242,232,225,236,230,247,233,228,244,104,128,255,140,238,231, - 225,242,245,237,236,225,245,116,129, 2,221,106, 13,227,237, 98, - 128, 3, 11,118,128, 1,149,249,240,232,229,110,132, 0, 45,106, - 39,106, 50,106, 62,106, 85,233,238,230,229,242,233,239,114,128, - 246,229,237,239,238,239,243,240,225,227,101,128,255, 13,115, 2, - 106, 68,106, 75,237,225,236,108,128,254, 99,245,240,229,242,233, - 239,114,128,246,230,244,247,111,128, 32, 16,105,149, 0,105,106, - 137,106,160,106,194,106,241,110,123,110,243,111, 24,111, 51,111, - 213,111,217,111,255,112, 21,112,105,113, 14,113, 89,113, 97,113, - 110,113,197,113,254,114, 26,114, 70,225, 99, 2,106,144,106,150, - 245,244,101,128, 0,237,249,242,233,236,236,233, 99,128, 4, 79, - 98, 3,106,168,106,177,106,187,229,238,231,225,236,105,128, 9, - 135,239,240,239,237,239,230,111,128, 49, 39,242,229,246,101,128, - 1, 45, 99, 3,106,202,106,209,106,231,225,242,239,110,128, 1, - 208,233,242, 99, 2,106,217,106,222,236,101,128, 36,216,245,237, - 230,236,229,120,128, 0,238,249,242,233,236,236,233, 99,128, 4, - 86,100, 4,106,251,107, 5,110, 80,110,113,226,236,231,242,225, - 246,101,128, 2, 9,101, 2,107, 11,110, 75,239,231,242,225,240, - 104, 7,107, 32,107, 46,107, 59,109,244,110, 19,110, 32,110, 44, - 229,225,242,244,232,227,233,242,227,236,101,128, 50,143,230,233, - 242,229,227,233,242,227,236,101,128, 50,139,233, 99, 14,107, 90, - 107,106,107,205,108, 3,108, 69,108, 98,108,114,108,171,108,220, - 108,232,109, 3,109, 70,109,208,109,237,225,236,236,233,225,238, - 227,229,240,225,242,229,110,128, 50, 63, 99, 4,107,116,107,127, - 107,141,107,148,225,236,236,240,225,242,229,110,128, 50, 58,229, - 238,244,242,229,227,233,242,227,236,101,128, 50,165,236,239,243, - 101,128, 48, 6,111, 3,107,156,107,171,107,191,237,237, 97,129, - 48, 1,107,164,236,229,230,116,128,255,100,238,231,242,225,244, - 245,236,225,244,233,239,238,240,225,242,229,110,128, 50, 55,242, - 242,229,227,244,227,233,242,227,236,101,128, 50,163,101, 3,107, - 213,107,225,107,242,225,242,244,232,240,225,242,229,110,128, 50, - 47,238,244,229,242,240,242,233,243,229,240,225,242,229,110,128, - 50, 61,248,227,229,236,236,229,238,244,227,233,242,227,236,101, - 128, 50,157,102, 2,108, 9,108, 24,229,243,244,233,246,225,236, - 240,225,242,229,110,128, 50, 64,105, 2,108, 30,108, 59,238,225, - 238,227,233,225,108, 2,108, 42,108, 51,227,233,242,227,236,101, - 128, 50,150,240,225,242,229,110,128, 50, 54,242,229,240,225,242, - 229,110,128, 50, 43,104, 2,108, 75,108, 86,225,246,229,240,225, - 242,229,110,128, 50, 50,233,231,232,227,233,242,227,236,101,128, - 50,164,233,244,229,242,225,244,233,239,238,237,225,242,107,128, - 48, 5,108, 3,108,122,108,148,108,160,225,226,239,114, 2,108, - 131,108,140,227,233,242,227,236,101,128, 50,152,240,225,242,229, - 110,128, 50, 56,229,230,244,227,233,242,227,236,101,128, 50,167, - 239,247,227,233,242,227,236,101,128, 50,166,109, 2,108,177,108, - 209,101, 2,108,183,108,198,228,233,227,233,238,229,227,233,242, - 227,236,101,128, 50,169,244,225,236,240,225,242,229,110,128, 50, - 46,239,239,238,240,225,242,229,110,128, 50, 42,238,225,237,229, - 240,225,242,229,110,128, 50, 52,112, 2,108,238,108,246,229,242, - 233,239,100,128, 48, 2,242,233,238,244,227,233,242,227,236,101, - 128, 50,158,114, 2,109, 9,109, 57,101, 3,109, 17,109, 28,109, - 43,225,227,232,240,225,242,229,110,128, 50, 67,240,242,229,243, - 229,238,244,240,225,242,229,110,128, 50, 57,243,239,245,242,227, - 229,240,225,242,229,110,128, 50, 62,233,231,232,244,227,233,242, - 227,236,101,128, 50,168,115, 5,109, 82,109,111,109,125,109,150, - 109,178,101, 2,109, 88,109,101,227,242,229,244,227,233,242,227, - 236,101,128, 50,153,236,230,240,225,242,229,110,128, 50, 66,239, - 227,233,229,244,249,240,225,242,229,110,128, 50, 51,112, 2,109, - 131,109,137,225,227,101,128, 48, 0,229,227,233,225,236,240,225, - 242,229,110,128, 50, 53,116, 2,109,156,109,167,239,227,235,240, - 225,242,229,110,128, 50, 49,245,228,249,240,225,242,229,110,128, - 50, 59,117, 2,109,184,109,193,238,240,225,242,229,110,128, 50, - 48,240,229,242,246,233,243,229,240,225,242,229,110,128, 50, 60, - 119, 2,109,214,109,226,225,244,229,242,240,225,242,229,110,128, - 50, 44,239,239,228,240,225,242,229,110,128, 50, 45,250,229,242, - 111,128, 48, 7,109, 2,109,250,110, 7,229,244,225,236,227,233, - 242,227,236,101,128, 50,142,239,239,238,227,233,242,227,236,101, - 128, 50,138,238,225,237,229,227,233,242,227,236,101,128, 50,148, - 243,245,238,227,233,242,227,236,101,128, 50,144,119, 2,110, 50, - 110, 63,225,244,229,242,227,233,242,227,236,101,128, 50,140,239, - 239,228,227,233,242,227,236,101,128, 50,141,246, 97,128, 9, 7, - 233,229,242,229,243,233,115,130, 0,239,110, 94,110,102,225,227, - 245,244,101,128, 30, 47,227,249,242,233,236,236,233, 99,128, 4, - 229,239,244,226,229,236,239,119,128, 30,203,101, 3,110,131,110, - 147,110,158,226,242,229,246,229,227,249,242,233,236,236,233, 99, - 128, 4,215,227,249,242,233,236,236,233, 99,128, 4, 53,245,238, - 103, 4,110,170,110,205,110,220,110,229, 97, 2,110,176,110,191, - 227,233,242,227,236,229,235,239,242,229,225,110,128, 50,117,240, - 225,242,229,238,235,239,242,229,225,110,128, 50, 21,227,233,242, - 227,236,229,235,239,242,229,225,110,128, 50,103,235,239,242,229, - 225,110,128, 49, 71,240,225,242,229,238,235,239,242,229,225,110, - 128, 50, 7,103, 2,110,249,111, 0,242,225,246,101,128, 0,236, - 117, 2,111, 6,111, 15,234,225,242,225,244,105,128, 10,135,242, - 237,245,235,232,105,128, 10, 7,104, 2,111, 30,111, 40,233,242, - 225,231,225,238, 97,128, 48, 68,239,239,235,225,226,239,246,101, - 128, 30,201,105, 8,111, 69,111, 79,111, 90,111, 97,111,122,111, - 138,111,153,111,169,226,229,238,231,225,236,105,128, 9,136,227, - 249,242,233,236,236,233, 99,128, 4, 56,228,229,246, 97,128, 9, - 8,231,117, 2,111,104,111,113,234,225,242,225,244,105,128, 10, - 136,242,237,245,235,232,105,128, 10, 8,237,225,244,242,225,231, - 245,242,237,245,235,232,105,128, 10, 64,238,246,229,242,244,229, - 228,226,242,229,246,101,128, 2, 11,243,232,239,242,244,227,249, - 242,233,236,236,233, 99,128, 4, 57,246,239,247,229,236,243,233, - 231,110, 3,111,185,111,195,111,202,226,229,238,231,225,236,105, - 128, 9,192,228,229,246, 97,128, 9, 64,231,245,234,225,242,225, - 244,105,128, 10,192,106,128, 1, 51,107, 2,111,223,111,247,225, - 244,225,235,225,238, 97,129, 48,164,111,235,232,225,236,230,247, - 233,228,244,104,128,255,114,239,242,229,225,110,128, 49, 99,108, - 2,112, 5,112, 10,228,101,128, 2,220,245,249,232,229,226,242, - 229,119,128, 5,172,109, 2,112, 27,112, 94, 97, 3,112, 35,112, - 55,112, 80,227,242,239,110,129, 1, 43,112, 44,227,249,242,233, - 236,236,233, 99,128, 4,227,231,229,239,242,225,240,240,242,239, - 248,233,237,225,244,229,236,249,229,241,245,225,108,128, 34, 83, - 244,242,225,231,245,242,237,245,235,232,105,128, 10, 63,239,238, - 239,243,240,225,227,101,128,255, 73,110, 5,112,117,112,127,112, - 136,112,148,112,232,227,242,229,237,229,238,116,128, 34, 6,230, - 233,238,233,244,121,128, 34, 30,233,225,242,237,229,238,233,225, - 110,128, 5,107,116, 2,112,154,112,222,101, 2,112,160,112,211, - 231,242,225,108,131, 34, 43,112,173,112,191,112,196, 98, 2,112, - 179,112,187,239,244,244,239,109,128, 35, 33,116,128, 35, 33,229, - 120,128,248,245,116, 2,112,202,112,207,239,112,128, 35, 32,112, - 128, 35, 32,242,243,229,227,244,233,239,110,128, 34, 41,233,243, - 241,245,225,242,101,128, 51, 5,118, 3,112,240,112,249,113, 2, - 226,245,236,236,229,116,128, 37,216,227,233,242,227,236,101,128, - 37,217,243,237,233,236,229,230,225,227,101,128, 38, 59,111, 3, - 113, 22,113, 33,113, 41,227,249,242,233,236,236,233, 99,128, 4, - 81,231,239,238,229,107,128, 1, 47,244, 97,131, 3,185,113, 52, - 113, 73,113, 81,228,233,229,242,229,243,233,115,129, 3,202,113, - 65,244,239,238,239,115,128, 3,144,236,225,244,233,110,128, 2, - 105,244,239,238,239,115,128, 3,175,240,225,242,229,110,128, 36, - 164,242,233,231,245,242,237,245,235,232,105,128, 10,114,115, 4, - 113,120,113,165,113,179,113,187,237,225,236,108, 2,113,129,113, - 140,232,233,242,225,231,225,238, 97,128, 48, 67,235,225,244,225, - 235,225,238, 97,129, 48,163,113,153,232,225,236,230,247,233,228, - 244,104,128,255,104,243,232,225,242,226,229,238,231,225,236,105, - 128, 9,250,244,242,239,235,101,128, 2,104,245,240,229,242,233, - 239,114,128,246,237,116, 2,113,203,113,237,229,242,225,244,233, - 239,110, 2,113,215,113,226,232,233,242,225,231,225,238, 97,128, - 48,157,235,225,244,225,235,225,238, 97,128, 48,253,233,236,228, - 101,129, 1, 41,113,246,226,229,236,239,119,128, 30, 45,117, 2, - 114, 4,114, 15,226,239,240,239,237,239,230,111,128, 49, 41,227, - 249,242,233,236,236,233, 99,128, 4, 78,246,239,247,229,236,243, - 233,231,110, 3,114, 42,114, 52,114, 59,226,229,238,231,225,236, - 105,128, 9,191,228,229,246, 97,128, 9, 63,231,245,234,225,242, - 225,244,105,128, 10,191,250,232,233,244,243, 97, 2,114, 81,114, - 92,227,249,242,233,236,236,233, 99,128, 4,117,228,226,236,231, - 242,225,246,229,227,249,242,233,236,236,233, 99,128, 4,119,106, - 138, 0,106,114,135,114,198,114,209,115, 3,115, 19,115,132,115, - 201,115,206,115,218,115,226, 97, 4,114,145,114,156,114,166,114, - 173,225,242,237,229,238,233,225,110,128, 5,113,226,229,238,231, - 225,236,105,128, 9,156,228,229,246, 97,128, 9, 28,231,117, 2, - 114,180,114,189,234,225,242,225,244,105,128, 10,156,242,237,245, - 235,232,105,128, 10, 28,226,239,240,239,237,239,230,111,128, 49, - 16, 99, 3,114,217,114,224,114,246,225,242,239,110,128, 1,240, - 233,242, 99, 2,114,232,114,237,236,101,128, 36,217,245,237,230, - 236,229,120,128, 1, 53,242,239,243,243,229,228,244,225,233,108, - 128, 2,157,228,239,244,236,229,243,243,243,244,242,239,235,101, - 128, 2, 95,101, 3,115, 27,115, 38,115,103,227,249,242,233,236, - 236,233, 99,128, 4, 88,229,109, 4,115, 49,115, 58,115, 72,115, - 88,225,242,225,226,233, 99,128, 6, 44,230,233,238,225,236,225, - 242,225,226,233, 99,128,254,158,233,238,233,244,233,225,236,225, - 242,225,226,233, 99,128,254,159,237,229,228,233,225,236,225,242, - 225,226,233, 99,128,254,160,104, 2,115,109,115,118,225,242,225, - 226,233, 99,128, 6,152,230,233,238,225,236,225,242,225,226,233, - 99,128,251,139,104, 2,115,138,115,188, 97, 3,115,146,115,156, - 115,163,226,229,238,231,225,236,105,128, 9,157,228,229,246, 97, - 128, 9, 29,231,117, 2,115,170,115,179,234,225,242,225,244,105, - 128, 10,157,242,237,245,235,232,105,128, 10, 29,229,232,225,242, - 237,229,238,233,225,110,128, 5,123,233,115,128, 48, 4,237,239, - 238,239,243,240,225,227,101,128,255, 74,240,225,242,229,110,128, - 36,165,243,245,240,229,242,233,239,114,128, 2,178,107,146, 0, - 107,116, 21,118,110,118,121,118,183,118,194,119, 28,119, 42,120, - 150,121, 90,121,103,121,129,121,178,122, 60,122, 82,122, 95,122, - 118,122,160,122,170, 97, 12,116, 47,116, 79,116,101,116,131,116, - 245,117, 14,117, 44,117, 69,117,175,117,189,118, 56,118, 85, 98, - 2,116, 53,116, 70,225,243,232,235,233,242,227,249,242,233,236, - 236,233, 99,128, 4,161,229,238,231,225,236,105,128, 9,149, 99, - 2,116, 85,116, 91,245,244,101,128, 30, 49,249,242,233,236,236, - 233, 99,128, 4, 58,228,101, 2,116,108,116,126,243,227,229,238, - 228,229,242,227,249,242,233,236,236,233, 99,128, 4,155,246, 97, - 128, 9, 21,102,135, 5,219,116,149,116,158,116,178,116,192,116, - 201,116,217,116,232,225,242,225,226,233, 99,128, 6, 67,228,225, - 231,229,243,104,129,251, 59,116,169,232,229,226,242,229,119,128, - 251, 59,230,233,238,225,236,225,242,225,226,233, 99,128,254,218, - 232,229,226,242,229,119,128, 5,219,233,238,233,244,233,225,236, - 225,242,225,226,233, 99,128,254,219,237,229,228,233,225,236,225, - 242,225,226,233, 99,128,254,220,242,225,230,229,232,229,226,242, - 229,119,128,251, 77,231,117, 2,116,252,117, 5,234,225,242,225, - 244,105,128, 10,149,242,237,245,235,232,105,128, 10, 21,104, 2, - 117, 20,117, 30,233,242,225,231,225,238, 97,128, 48, 75,239,239, - 235,227,249,242,233,236,236,233, 99,128, 4,196,235,225,244,225, - 235,225,238, 97,129, 48,171,117, 57,232,225,236,230,247,233,228, - 244,104,128,255,118,112, 2,117, 75,117, 96,240, 97,129, 3,186, - 117, 82,243,249,237,226,239,236,231,242,229,229,107,128, 3,240, - 249,229,239,245,110, 3,117,108,117,122,117,156,237,233,229,245, - 237,235,239,242,229,225,110,128, 49,113,112, 2,117,128,117,143, - 232,233,229,245,240,232,235,239,242,229,225,110,128, 49,132,233, - 229,245,240,235,239,242,229,225,110,128, 49,120,243,243,225,238, - 231,240,233,229,245,240,235,239,242,229,225,110,128, 49,121,242, - 239,242,233,233,243,241,245,225,242,101,128, 51, 13,115, 5,117, - 201,117,245,118, 4,118, 12,118, 40,232,233,228,225,225,245,244, - 111, 2,117,214,117,223,225,242,225,226,233, 99,128, 6, 64,238, - 239,243,233,228,229,226,229,225,242,233,238,231,225,242,225,226, - 233, 99,128, 6, 64,237,225,236,236,235,225,244,225,235,225,238, - 97,128, 48,245,241,245,225,242,101,128, 51,132,242, 97, 2,118, - 19,118, 28,225,242,225,226,233, 99,128, 6, 80,244,225,238,225, - 242,225,226,233, 99,128, 6, 77,244,242,239,235,229,227,249,242, - 233,236,236,233, 99,128, 4,159,244,225,232,233,242,225,240,242, - 239,236,239,238,231,237,225,242,235,232,225,236,230,247,233,228, - 244,104,128,255,112,246,229,242,244,233,227,225,236,243,244,242, - 239,235,229,227,249,242,233,236,236,233, 99,128, 4,157,226,239, - 240,239,237,239,230,111,128, 49, 14, 99, 4,118,131,118,153,118, - 162,118,170, 97, 2,118,137,118,147,236,243,241,245,225,242,101, - 128, 51,137,242,239,110,128, 1,233,229,228,233,236,236, 97,128, - 1, 55,233,242,227,236,101,128, 36,218,239,237,237,225,225,227, - 227,229,238,116,128, 1, 55,228,239,244,226,229,236,239,119,128, - 30, 51,101, 4,118,204,118,231,119, 0,119, 12,104, 2,118,210, - 118,221,225,242,237,229,238,233,225,110,128, 5,132,233,242,225, - 231,225,238, 97,128, 48, 81,235,225,244,225,235,225,238, 97,129, - 48,177,118,244,232,225,236,230,247,233,228,244,104,128,255,121, - 238,225,242,237,229,238,233,225,110,128, 5,111,243,237,225,236, - 236,235,225,244,225,235,225,238, 97,128, 48,246,231,242,229,229, - 238,236,225,238,228,233, 99,128, 1, 56,104, 6,119, 56,119,185, - 119,196,119,221,120, 52,120,140, 97, 5,119, 68,119, 78,119, 89, - 119, 96,119,121,226,229,238,231,225,236,105,128, 9,150,227,249, - 242,233,236,236,233, 99,128, 4, 69,228,229,246, 97,128, 9, 22, - 231,117, 2,119,103,119,112,234,225,242,225,244,105,128, 10,150, - 242,237,245,235,232,105,128, 10, 22,104, 4,119,131,119,140,119, - 154,119,170,225,242,225,226,233, 99,128, 6, 46,230,233,238,225, - 236,225,242,225,226,233, 99,128,254,166,233,238,233,244,233,225, - 236,225,242,225,226,233, 99,128,254,167,237,229,228,233,225,236, - 225,242,225,226,233, 99,128,254,168,229,233,227,239,240,244,233, - 99,128, 3,231,232, 97, 2,119,203,119,210,228,229,246, 97,128, - 9, 89,231,245,242,237,245,235,232,105,128, 10, 89,233,229,245, - 235,104, 4,119,235,120, 14,120, 29,120, 38, 97, 2,119,241,120, - 0,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,120, - 240,225,242,229,238,235,239,242,229,225,110,128, 50, 24,227,233, - 242,227,236,229,235,239,242,229,225,110,128, 50,106,235,239,242, - 229,225,110,128, 49, 75,240,225,242,229,238,235,239,242,229,225, - 110,128, 50, 10,111, 4,120, 62,120,111,120,121,120,126,235,104, - 4,120, 73,120, 82,120, 91,120,101,225,233,244,232,225,105,128, - 14, 2,239,238,244,232,225,105,128, 14, 5,245,225,244,244,232, - 225,105,128, 14, 3,247,225,233,244,232,225,105,128, 14, 4,237, - 245,244,244,232,225,105,128, 14, 91,239,107,128, 1,153,242,225, - 235,232,225,238,231,244,232,225,105,128, 14, 6,250,243,241,245, - 225,242,101,128, 51,145,105, 4,120,160,120,171,120,196,120,245, - 232,233,242,225,231,225,238, 97,128, 48, 77,235,225,244,225,235, - 225,238, 97,129, 48,173,120,184,232,225,236,230,247,233,228,244, - 104,128,255,119,242,111, 3,120,205,120,220,120,236,231,245,242, - 225,237,245,243,241,245,225,242,101,128, 51, 21,237,229,229,244, - 239,242,245,243,241,245,225,242,101,128, 51, 22,243,241,245,225, - 242,101,128, 51, 20,249,229,239,107, 5,121, 4,121, 39,121, 54, - 121, 63,121, 77, 97, 2,121, 10,121, 25,227,233,242,227,236,229, - 235,239,242,229,225,110,128, 50,110,240,225,242,229,238,235,239, - 242,229,225,110,128, 50, 14,227,233,242,227,236,229,235,239,242, - 229,225,110,128, 50, 96,235,239,242,229,225,110,128, 49, 49,240, - 225,242,229,238,235,239,242,229,225,110,128, 50, 0,243,233,239, - 243,235,239,242,229,225,110,128, 49, 51,234,229,227,249,242,233, - 236,236,233, 99,128, 4, 92,108, 2,121,109,121,120,233,238,229, - 226,229,236,239,119,128, 30, 53,243,241,245,225,242,101,128, 51, - 152,109, 3,121,137,121,151,121,162,227,245,226,229,228,243,241, - 245,225,242,101,128, 51,166,239,238,239,243,240,225,227,101,128, - 255, 75,243,241,245,225,242,229,228,243,241,245,225,242,101,128, - 51,162,111, 5,121,190,121,216,121,254,122, 10,122, 24,104, 2, - 121,196,121,206,233,242,225,231,225,238, 97,128, 48, 83,237,243, - 241,245,225,242,101,128, 51,192,235, 97, 2,121,223,121,231,233, - 244,232,225,105,128, 14, 1,244,225,235,225,238, 97,129, 48,179, - 121,242,232,225,236,230,247,233,228,244,104,128,255,122,239,240, - 239,243,241,245,225,242,101,128, 51, 30,240,240,225,227,249,242, - 233,236,236,233, 99,128, 4,129,114, 2,122, 30,122, 50,229,225, - 238,243,244,225,238,228,225,242,228,243,249,237,226,239,108,128, - 50,127,239,238,233,243,227,237, 98,128, 3, 67,240, 97, 2,122, - 67,122, 73,242,229,110,128, 36,166,243,241,245,225,242,101,128, - 51,170,243,233,227,249,242,233,236,236,233, 99,128, 4,111,116, - 2,122,101,122,110,243,241,245,225,242,101,128, 51,207,245,242, - 238,229,100,128, 2,158,117, 2,122,124,122,135,232,233,242,225, - 231,225,238, 97,128, 48, 79,235,225,244,225,235,225,238, 97,129, - 48,175,122,148,232,225,236,230,247,233,228,244,104,128,255,120, - 246,243,241,245,225,242,101,128, 51,184,247,243,241,245,225,242, - 101,128, 51,190,108,146, 0,108,122,220,124,247,125, 20,125, 86, - 125,124,126, 20,126, 29,126, 45,126, 69,126, 87,126,205,126,246, - 127,125,127,133,127,166,127,175,127,183,127,245, 97, 7,122,236, - 122,246,122,253,123, 4,123, 29,123, 45,124,235,226,229,238,231, - 225,236,105,128, 9,178,227,245,244,101,128, 1, 58,228,229,246, - 97,128, 9, 50,231,117, 2,123, 11,123, 20,234,225,242,225,244, - 105,128, 10,178,242,237,245,235,232,105,128, 10, 50,235,235,232, - 225,238,231,249,225,239,244,232,225,105,128, 14, 69,109, 10,123, - 67,124, 6,124, 23,124, 61,124, 75,124, 94,124,110,124,130,124, - 150,124,173, 97, 2,123, 73,123,254,236,229,102, 4,123, 85,123, - 99,123,191,123,208,230,233,238,225,236,225,242,225,226,233, 99, - 128,254,252,232,225,237,250, 97, 2,123,109,123,150,225,226,239, - 246,101, 2,123,119,123,133,230,233,238,225,236,225,242,225,226, - 233, 99,128,254,248,233,243,239,236,225,244,229,228,225,242,225, - 226,233, 99,128,254,247,226,229,236,239,119, 2,123,160,123,174, - 230,233,238,225,236,225,242,225,226,233, 99,128,254,250,233,243, - 239,236,225,244,229,228,225,242,225,226,233, 99,128,254,249,233, - 243,239,236,225,244,229,228,225,242,225,226,233, 99,128,254,251, - 237,225,228,228,225,225,226,239,246,101, 2,123,223,123,237,230, - 233,238,225,236,225,242,225,226,233, 99,128,254,246,233,243,239, - 236,225,244,229,228,225,242,225,226,233, 99,128,254,245,242,225, - 226,233, 99,128, 6, 68,226,228, 97,129, 3,187,124, 14,243,244, - 242,239,235,101,128, 1,155,229,100,130, 5,220,124, 32,124, 52, - 228,225,231,229,243,104,129,251, 60,124, 43,232,229,226,242,229, - 119,128,251, 60,232,229,226,242,229,119,128, 5,220,230,233,238, - 225,236,225,242,225,226,233, 99,128,254,222,232,225,232,233,238, - 233,244,233,225,236,225,242,225,226,233, 99,128,252,202,233,238, - 233,244,233,225,236,225,242,225,226,233, 99,128,254,223,234,229, - 229,237,233,238,233,244,233,225,236,225,242,225,226,233, 99,128, - 252,201,235,232,225,232,233,238,233,244,233,225,236,225,242,225, - 226,233, 99,128,252,203,236,225,237,232,229,232,233,243,239,236, - 225,244,229,228,225,242,225,226,233, 99,128,253,242,237,101, 2, - 124,180,124,193,228,233,225,236,225,242,225,226,233, 99,128,254, - 224,229,109, 2,124,200,124,219,232,225,232,233,238,233,244,233, - 225,236,225,242,225,226,233, 99,128,253,136,233,238,233,244,233, - 225,236,225,242,225,226,233, 99,128,252,204,242,231,229,227,233, - 242,227,236,101,128, 37,239, 98, 3,124,255,125, 4,125, 10,225, - 114,128, 1,154,229,236,116,128, 2,108,239,240,239,237,239,230, - 111,128, 49, 12, 99, 4,125, 30,125, 37,125, 46,125, 73,225,242, - 239,110,128, 1, 62,229,228,233,236,236, 97,128, 1, 60,233,242, - 99, 2,125, 54,125, 59,236,101,128, 36,219,245,237,230,236,229, - 248,226,229,236,239,119,128, 30, 61,239,237,237,225,225,227,227, - 229,238,116,128, 1, 60,228,239,116,130, 1, 64,125, 96,125,105, - 225,227,227,229,238,116,128, 1, 64,226,229,236,239,119,129, 30, - 55,125,115,237,225,227,242,239,110,128, 30, 57,101, 3,125,132, - 125,170,126, 15,230,116, 2,125,139,125,155,225,238,231,236,229, - 225,226,239,246,229,227,237, 98,128, 3, 26,244,225,227,235,226, - 229,236,239,247,227,237, 98,128, 3, 24,243,115,132, 0, 60,125, - 183,125,205,125,217,126, 7,229,241,245,225,108,129, 34,100,125, - 193,239,242,231,242,229,225,244,229,114,128, 34,218,237,239,238, - 239,243,240,225,227,101,128,255, 28,111, 2,125,223,125,252,114, - 2,125,229,125,242,229,241,245,233,246,225,236,229,238,116,128, - 34,114,231,242,229,225,244,229,114,128, 34,118,246,229,242,229, - 241,245,225,108,128, 34,102,243,237,225,236,108,128,254,100,250, - 104,128, 2,110,230,226,236,239,227,107,128, 37,140,232,239,239, - 235,242,229,244,242,239,230,236,229,120,128, 2,109,105, 2,126, - 51,126, 56,242, 97,128, 32,164,247,238,225,242,237,229,238,233, - 225,110,128, 5,108,106,129, 1,201,126, 75,229,227,249,242,233, - 236,236,233, 99,128, 4, 89,108,132,246,192,126, 99,126,123,126, - 134,126,143, 97, 2,126,105,126,112,228,229,246, 97,128, 9, 51, - 231,245,234,225,242,225,244,105,128, 10,179,233,238,229,226,229, - 236,239,119,128, 30, 59,236,225,228,229,246, 97,128, 9, 52,246, - 239,227,225,236,233, 99, 3,126,157,126,167,126,174,226,229,238, - 231,225,236,105,128, 9,225,228,229,246, 97,128, 9, 97,246,239, - 247,229,236,243,233,231,110, 2,126,188,126,198,226,229,238,231, - 225,236,105,128, 9,227,228,229,246, 97,128, 9, 99,109, 3,126, - 213,126,226,126,237,233,228,228,236,229,244,233,236,228,101,128, - 2,107,239,238,239,243,240,225,227,101,128,255, 76,243,241,245, - 225,242,101,128, 51,208,111, 6,127, 4,127, 16,127, 58,127, 69, - 127, 75,127,117,227,232,245,236,225,244,232,225,105,128, 14, 44, - 231,233,227,225,108, 3,127, 28,127, 34,127, 53,225,238,100,128, - 34, 39,238,239,116,129, 0,172,127, 42,242,229,246,229,242,243, - 229,100,128, 35, 16,239,114,128, 34, 40,236,233,238,231,244,232, - 225,105,128, 14, 37,238,231,115,128, 1,127,247,236,233,238,101, - 2,127, 85,127,108, 99, 2,127, 91,127,103,229,238,244,229,242, - 236,233,238,101,128,254, 78,237, 98,128, 3, 50,228,225,243,232, - 229,100,128,254, 77,250,229,238,231,101,128, 37,202,240,225,242, - 229,110,128, 36,167,115, 3,127,141,127,148,127,156,236,225,243, - 104,128, 1, 66,241,245,225,242,101,128, 33, 19,245,240,229,242, - 233,239,114,128,246,238,244,243,232,225,228,101,128, 37,145,245, - 244,232,225,105,128, 14, 38,246,239,227,225,236,233, 99, 3,127, - 197,127,207,127,214,226,229,238,231,225,236,105,128, 9,140,228, - 229,246, 97,128, 9, 12,246,239,247,229,236,243,233,231,110, 2, - 127,228,127,238,226,229,238,231,225,236,105,128, 9,226,228,229, - 246, 97,128, 9, 98,248,243,241,245,225,242,101,128, 51,211,109, - 144, 0,109,128, 35,130,144,130,169,130,196,130,221,132, 18,132, - 40,133, 95,133,125,133,174,134, 25,134, 47,134, 72,134, 81,135, - 108,135,136, 97, 12,128, 61,128, 71,128,135,128,142,128,167,128, - 215,130, 51,130, 76,130, 81,130, 95,130,107,130,112,226,229,238, - 231,225,236,105,128, 9,174, 99, 2,128, 77,128,129,242,239,110, - 132, 0,175,128, 91,128,102,128,108,128,117,226,229,236,239,247, - 227,237, 98,128, 3, 49,227,237, 98,128, 3, 4,236,239,247,237, - 239,100,128, 2,205,237,239,238,239,243,240,225,227,101,128,255, - 227,245,244,101,128, 30, 63,228,229,246, 97,128, 9, 46,231,117, - 2,128,149,128,158,234,225,242,225,244,105,128, 10,174,242,237, - 245,235,232,105,128, 10, 46,104, 2,128,173,128,205,225,240,225, - 235,104, 2,128,183,128,192,232,229,226,242,229,119,128, 5,164, - 236,229,230,244,232,229,226,242,229,119,128, 5,164,233,242,225, - 231,225,238, 97,128, 48,126,105, 5,128,227,129, 40,129,103,129, - 133,130, 39,227,232,225,244,244,225,247, 97, 3,128,242,129, 17, - 129, 24,236,239,119, 2,128,250,129, 5,236,229,230,244,244,232, - 225,105,128,248,149,242,233,231,232,244,244,232,225,105,128,248, - 148,244,232,225,105,128, 14, 75,245,240,240,229,242,236,229,230, - 244,244,232,225,105,128,248,147,229,107, 3,129, 49,129, 80,129, - 87,236,239,119, 2,129, 57,129, 68,236,229,230,244,244,232,225, - 105,128,248,140,242,233,231,232,244,244,232,225,105,128,248,139, - 244,232,225,105,128, 14, 72,245,240,240,229,242,236,229,230,244, - 244,232,225,105,128,248,138,232,225,238,225,235,225,116, 2,129, - 115,129,126,236,229,230,244,244,232,225,105,128,248,132,244,232, - 225,105,128, 14, 49,116, 3,129,141,129,169,129,232,225,233,235, - 232,117, 2,129,151,129,162,236,229,230,244,244,232,225,105,128, - 248,137,244,232,225,105,128, 14, 71,232,111, 3,129,178,129,209, - 129,216,236,239,119, 2,129,186,129,197,236,229,230,244,244,232, - 225,105,128,248,143,242,233,231,232,244,244,232,225,105,128,248, - 142,244,232,225,105,128, 14, 73,245,240,240,229,242,236,229,230, - 244,244,232,225,105,128,248,141,242,105, 3,129,241,130, 16,130, - 23,236,239,119, 2,129,249,130, 4,236,229,230,244,244,232,225, - 105,128,248,146,242,233,231,232,244,244,232,225,105,128,248,145, - 244,232,225,105,128, 14, 74,245,240,240,229,242,236,229,230,244, - 244,232,225,105,128,248,144,249,225,237,239,235,244,232,225,105, - 128, 14, 70,235,225,244,225,235,225,238, 97,129, 48,222,130, 64, - 232,225,236,230,247,233,228,244,104,128,255,143,236,101,128, 38, - 66,238,243,249,239,238,243,241,245,225,242,101,128, 51, 71,241, - 225,230,232,229,226,242,229,119,128, 5,190,242,115,128, 38, 66, - 115, 2,130,118,130,136,239,242,225,227,233,242,227,236,229,232, - 229,226,242,229,119,128, 5,175,241,245,225,242,101,128, 51,131, - 98, 2,130,150,130,160,239,240,239,237,239,230,111,128, 49, 7, - 243,241,245,225,242,101,128, 51,212, 99, 2,130,175,130,183,233, - 242,227,236,101,128, 36,220,245,226,229,228,243,241,245,225,242, - 101,128, 51,165,228,239,116, 2,130,204,130,213,225,227,227,229, - 238,116,128, 30, 65,226,229,236,239,119,128, 30, 67,101, 7,130, - 237,131,108,131,119,131,134,131,159,131,196,131,208,101, 2,130, - 243,131, 95,109, 4,130,253,131, 6,131, 20,131, 36,225,242,225, - 226,233, 99,128, 6, 69,230,233,238,225,236,225,242,225,226,233, - 99,128,254,226,233,238,233,244,233,225,236,225,242,225,226,233, - 99,128,254,227,237,101, 2,131, 43,131, 56,228,233,225,236,225, - 242,225,226,233, 99,128,254,228,229,237,105, 2,131, 64,131, 79, - 238,233,244,233,225,236,225,242,225,226,233, 99,128,252,209,243, - 239,236,225,244,229,228,225,242,225,226,233, 99,128,252, 72,244, - 239,242,245,243,241,245,225,242,101,128, 51, 77,232,233,242,225, - 231,225,238, 97,128, 48,129,233,250,233,229,242,225,243,241,245, - 225,242,101,128, 51,126,235,225,244,225,235,225,238, 97,129, 48, - 225,131,147,232,225,236,230,247,233,228,244,104,128,255,146,109, - 130, 5,222,131,167,131,187,228,225,231,229,243,104,129,251, 62, - 131,178,232,229,226,242,229,119,128,251, 62,232,229,226,242,229, - 119,128, 5,222,238,225,242,237,229,238,233,225,110,128, 5,116, - 242,235,232, 97, 3,131,219,131,228,132, 5,232,229,226,242,229, - 119,128, 5,165,235,229,230,245,236, 97, 2,131,239,131,248,232, - 229,226,242,229,119,128, 5,166,236,229,230,244,232,229,226,242, - 229,119,128, 5,166,236,229,230,244,232,229,226,242,229,119,128, - 5,165,104, 2,132, 24,132, 30,239,239,107,128, 2,113,250,243, - 241,245,225,242,101,128, 51,146,105, 6,132, 54,132, 91,132,228, - 132,239,133, 8,133, 65,228,100, 2,132, 61,132, 86,236,229,228, - 239,244,235,225,244,225,235,225,238,225,232,225,236,230,247,233, - 228,244,104,128,255,101,239,116,128, 0,183,229,245,109, 5,132, - 105,132,140,132,155,132,164,132,215, 97, 2,132,111,132,126,227, - 233,242,227,236,229,235,239,242,229,225,110,128, 50,114,240,225, - 242,229,238,235,239,242,229,225,110,128, 50, 18,227,233,242,227, - 236,229,235,239,242,229,225,110,128, 50,100,235,239,242,229,225, - 110,128, 49, 65,112, 2,132,170,132,202, 97, 2,132,176,132,190, - 238,243,233,239,243,235,239,242,229,225,110,128, 49,112,242,229, - 238,235,239,242,229,225,110,128, 50, 4,233,229,245,240,235,239, - 242,229,225,110,128, 49,110,243,233,239,243,235,239,242,229,225, - 110,128, 49,111,232,233,242,225,231,225,238, 97,128, 48,127,235, - 225,244,225,235,225,238, 97,129, 48,223,132,252,232,225,236,230, - 247,233,228,244,104,128,255,144,238,117, 2,133, 15,133, 60,115, - 132, 34, 18,133, 27,133, 38,133, 47,133, 53,226,229,236,239,247, - 227,237, 98,128, 3, 32,227,233,242,227,236,101,128, 34,150,237, - 239,100,128, 2,215,240,236,245,115,128, 34, 19,244,101,128, 32, - 50,242,105, 2,133, 72,133, 86,226,225,225,242,245,243,241,245, - 225,242,101,128, 51, 74,243,241,245,225,242,101,128, 51, 73,108, - 2,133,101,133,116,239,238,231,236,229,231,244,245,242,238,229, - 100,128, 2,112,243,241,245,225,242,101,128, 51,150,109, 3,133, - 133,133,147,133,158,227,245,226,229,228,243,241,245,225,242,101, - 128, 51,163,239,238,239,243,240,225,227,101,128,255, 77,243,241, - 245,225,242,229,228,243,241,245,225,242,101,128, 51,159,111, 5, - 133,186,133,212,133,237,133,247,134, 0,104, 2,133,192,133,202, - 233,242,225,231,225,238, 97,128, 48,130,237,243,241,245,225,242, - 101,128, 51,193,235,225,244,225,235,225,238, 97,129, 48,226,133, - 225,232,225,236,230,247,233,228,244,104,128,255,147,236,243,241, - 245,225,242,101,128, 51,214,237,225,244,232,225,105,128, 14, 33, - 246,229,242,243,243,241,245,225,242,101,129, 51,167,134, 15,228, - 243,241,245,225,242,101,128, 51,168,240, 97, 2,134, 32,134, 38, - 242,229,110,128, 36,168,243,241,245,225,242,101,128, 51,171,115, - 2,134, 53,134, 62,243,241,245,225,242,101,128, 51,179,245,240, - 229,242,233,239,114,128,246,239,244,245,242,238,229,100,128, 2, - 111,117,141, 0,181,134,111,134,115,134,125,134,149,134,159,134, - 181,134,192,134,217,134,240,134,250,135, 24,135, 88,135, 98, 49, - 128, 0,181,225,243,241,245,225,242,101,128, 51,130,227,104, 2, - 134,132,134,142,231,242,229,225,244,229,114,128, 34,107,236,229, - 243,115,128, 34,106,230,243,241,245,225,242,101,128, 51,140,103, - 2,134,165,134,172,242,229,229,107,128, 3,188,243,241,245,225, - 242,101,128, 51,141,232,233,242,225,231,225,238, 97,128, 48,128, - 235,225,244,225,235,225,238, 97,129, 48,224,134,205,232,225,236, - 230,247,233,228,244,104,128,255,145,108, 2,134,223,134,232,243, - 241,245,225,242,101,128, 51,149,244,233,240,236,121,128, 0,215, - 237,243,241,245,225,242,101,128, 51,155,238,225,104, 2,135, 2, - 135, 11,232,229,226,242,229,119,128, 5,163,236,229,230,244,232, - 229,226,242,229,119,128, 5,163,115, 2,135, 30,135, 79,233, 99, - 3,135, 39,135, 56,135, 67,225,236,238,239,244,101,129, 38,106, - 135, 50,228,226,108,128, 38,107,230,236,225,244,243,233,231,110, - 128, 38,109,243,232,225,242,240,243,233,231,110,128, 38,111,243, - 241,245,225,242,101,128, 51,178,246,243,241,245,225,242,101,128, - 51,182,247,243,241,245,225,242,101,128, 51,188,118, 2,135,114, - 135,127,237,229,231,225,243,241,245,225,242,101,128, 51,185,243, - 241,245,225,242,101,128, 51,183,119, 2,135,142,135,155,237,229, - 231,225,243,241,245,225,242,101,128, 51,191,243,241,245,225,242, - 101,128, 51,189,110,150, 0,110,135,212,136, 90,136,114,136,180, - 136,205,137, 7,137, 17,137, 84,137,127,139,161,139,179,139,204, - 139,235,140, 5,140, 70,142, 52,142, 60,142, 85,142, 93,143, 61, - 143, 71,143, 81, 97, 8,135,230,135,250,136, 1,136, 8,136, 33, - 136, 44,136, 69,136, 81, 98, 2,135,236,135,245,229,238,231,225, - 236,105,128, 9,168,236, 97,128, 34, 7,227,245,244,101,128, 1, - 68,228,229,246, 97,128, 9, 40,231,117, 2,136, 15,136, 24,234, - 225,242,225,244,105,128, 10,168,242,237,245,235,232,105,128, 10, - 40,232,233,242,225,231,225,238, 97,128, 48,106,235,225,244,225, - 235,225,238, 97,129, 48,202,136, 57,232,225,236,230,247,233,228, - 244,104,128,255,133,240,239,243,244,242,239,240,232,101,128, 1, - 73,243,241,245,225,242,101,128, 51,129, 98, 2,136, 96,136,106, - 239,240,239,237,239,230,111,128, 49, 11,243,240,225,227,101,128, - 0,160, 99, 4,136,124,136,131,136,140,136,167,225,242,239,110, - 128, 1, 72,229,228,233,236,236, 97,128, 1, 70,233,242, 99, 2, - 136,148,136,153,236,101,128, 36,221,245,237,230,236,229,248,226, - 229,236,239,119,128, 30, 75,239,237,237,225,225,227,227,229,238, - 116,128, 1, 70,228,239,116, 2,136,188,136,197,225,227,227,229, - 238,116,128, 30, 69,226,229,236,239,119,128, 30, 71,101, 3,136, - 213,136,224,136,249,232,233,242,225,231,225,238, 97,128, 48,109, - 235,225,244,225,235,225,238, 97,129, 48,205,136,237,232,225,236, - 230,247,233,228,244,104,128,255,136,247,243,232,229,241,229,236, - 243,233,231,110,128, 32,170,230,243,241,245,225,242,101,128, 51, - 139,103, 2,137, 23,137, 73, 97, 3,137, 31,137, 41,137, 48,226, - 229,238,231,225,236,105,128, 9,153,228,229,246, 97,128, 9, 25, - 231,117, 2,137, 55,137, 64,234,225,242,225,244,105,128, 10,153, - 242,237,245,235,232,105,128, 10, 25,239,238,231,245,244,232,225, - 105,128, 14, 7,104, 2,137, 90,137,100,233,242,225,231,225,238, - 97,128, 48,147,239,239,107, 2,137,108,137,115,236,229,230,116, - 128, 2,114,242,229,244,242,239,230,236,229,120,128, 2,115,105, - 4,137,137,138, 50,138, 61,138,119,229,245,110, 7,137,155,137, - 190,137,222,137,236,137,245,138, 22,138, 35, 97, 2,137,161,137, - 176,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,111, - 240,225,242,229,238,235,239,242,229,225,110,128, 50, 15,227,105, - 2,137,197,137,209,229,245,227,235,239,242,229,225,110,128, 49, - 53,242,227,236,229,235,239,242,229,225,110,128, 50, 97,232,233, - 229,245,232,235,239,242,229,225,110,128, 49, 54,235,239,242,229, - 225,110,128, 49, 52,240, 97, 2,137,252,138, 10,238,243,233,239, - 243,235,239,242,229,225,110,128, 49,104,242,229,238,235,239,242, - 229,225,110,128, 50, 1,243,233,239,243,235,239,242,229,225,110, - 128, 49,103,244,233,235,229,245,244,235,239,242,229,225,110,128, - 49,102,232,233,242,225,231,225,238, 97,128, 48,107,107, 2,138, - 67,138, 91,225,244,225,235,225,238, 97,129, 48,203,138, 79,232, - 225,236,230,247,233,228,244,104,128,255,134,232,225,232,233,116, - 2,138,101,138,112,236,229,230,244,244,232,225,105,128,248,153, - 244,232,225,105,128, 14, 77,238,101,141, 0, 57,138,150,138,159, - 138,169,138,199,138,206,138,231,139, 2,139, 36,139, 48,139, 59, - 139, 92,139,100,139,111,225,242,225,226,233, 99,128, 6,105,226, - 229,238,231,225,236,105,128, 9,239,227,233,242,227,236,101,129, - 36,104,138,180,233,238,246,229,242,243,229,243,225,238,243,243, - 229,242,233,102,128, 39,146,228,229,246, 97,128, 9,111,231,117, - 2,138,213,138,222,234,225,242,225,244,105,128, 10,239,242,237, - 245,235,232,105,128, 10,111,232, 97, 2,138,238,138,249,227,235, - 225,242,225,226,233, 99,128, 6,105,238,231,250,232,239,117,128, - 48, 41,105, 2,139, 8,139, 26,228,229,239,231,242,225,240,232, - 233,227,240,225,242,229,110,128, 50, 40,238,230,229,242,233,239, - 114,128, 32,137,237,239,238,239,243,240,225,227,101,128,255, 25, - 239,236,228,243,244,249,236,101,128,247, 57,112, 2,139, 65,139, - 72,225,242,229,110,128, 36,124,229,114, 2,139, 79,139, 85,233, - 239,100,128, 36,144,243,233,225,110,128, 6,249,242,239,237,225, - 110,128, 33,120,243,245,240,229,242,233,239,114,128, 32,121,116, - 2,139,117,139,155,229,229,110, 2,139,125,139,134,227,233,242, - 227,236,101,128, 36,114,112, 2,139,140,139,147,225,242,229,110, - 128, 36,134,229,242,233,239,100,128, 36,154,232,225,105,128, 14, - 89,106,129, 1,204,139,167,229,227,249,242,233,236,236,233, 99, - 128, 4, 90,235,225,244,225,235,225,238, 97,129, 48,243,139,192, - 232,225,236,230,247,233,228,244,104,128,255,157,108, 2,139,210, - 139,224,229,231,242,233,231,232,244,236,239,238,103,128, 1,158, - 233,238,229,226,229,236,239,119,128, 30, 73,109, 2,139,241,139, - 252,239,238,239,243,240,225,227,101,128,255, 78,243,241,245,225, - 242,101,128, 51,154,110, 2,140, 11,140, 61, 97, 3,140, 19,140, - 29,140, 36,226,229,238,231,225,236,105,128, 9,163,228,229,246, - 97,128, 9, 35,231,117, 2,140, 43,140, 52,234,225,242,225,244, - 105,128, 10,163,242,237,245,235,232,105,128, 10, 35,238,225,228, - 229,246, 97,128, 9, 41,111, 6,140, 84,140, 95,140,120,140,161, - 141,113,142, 40,232,233,242,225,231,225,238, 97,128, 48,110,235, - 225,244,225,235,225,238, 97,129, 48,206,140,108,232,225,236,230, - 247,233,228,244,104,128,255,137,110, 3,140,128,140,144,140,153, - 226,242,229,225,235,233,238,231,243,240,225,227,101,128, 0,160, - 229,238,244,232,225,105,128, 14, 19,245,244,232,225,105,128, 14, - 25,239,110, 7,140,178,140,187,140,201,140,235,140,251,141, 36, - 141, 95,225,242,225,226,233, 99,128, 6, 70,230,233,238,225,236, - 225,242,225,226,233, 99,128,254,230,231,232,245,238,238, 97, 2, - 140,212,140,221,225,242,225,226,233, 99,128, 6,186,230,233,238, - 225,236,225,242,225,226,233, 99,128,251,159,233,238,233,244,233, - 225,236,225,242,225,226,233, 99,128,254,231,234,229,229,237,105, - 2,141, 5,141, 20,238,233,244,233,225,236,225,242,225,226,233, - 99,128,252,210,243,239,236,225,244,229,228,225,242,225,226,233, - 99,128,252, 75,237,101, 2,141, 43,141, 56,228,233,225,236,225, - 242,225,226,233, 99,128,254,232,229,237,105, 2,141, 64,141, 79, - 238,233,244,233,225,236,225,242,225,226,233, 99,128,252,213,243, - 239,236,225,244,229,228,225,242,225,226,233, 99,128,252, 78,238, - 239,239,238,230,233,238,225,236,225,242,225,226,233, 99,128,252, - 141,116, 7,141,129,141,140,141,169,141,204,141,216,141,236,142, - 6,227,239,238,244,225,233,238,115,128, 34, 12,101, 2,141,146, - 141,162,236,229,237,229,238,116,129, 34, 9,141,157,239,102,128, - 34, 9,241,245,225,108,128, 34, 96,231,242,229,225,244,229,114, - 129, 34,111,141,181,238,239,114, 2,141,189,141,197,229,241,245, - 225,108,128, 34,113,236,229,243,115,128, 34,121,233,228,229,238, - 244,233,227,225,108,128, 34, 98,236,229,243,115,129, 34,110,141, - 225,238,239,242,229,241,245,225,108,128, 34,112,112, 2,141,242, - 141,252,225,242,225,236,236,229,108,128, 34, 38,242,229,227,229, - 228,229,115,128, 34,128,243,117, 3,142, 15,142, 22,142, 31,226, - 243,229,116,128, 34,132,227,227,229,229,228,115,128, 34,129,240, - 229,242,243,229,116,128, 34,133,247,225,242,237,229,238,233,225, - 110,128, 5,118,240,225,242,229,110,128, 36,169,115, 2,142, 66, - 142, 75,243,241,245,225,242,101,128, 51,177,245,240,229,242,233, - 239,114,128, 32,127,244,233,236,228,101,128, 0,241,117,132, 3, - 189,142,105,142,116,142,197,143, 24,232,233,242,225,231,225,238, - 97,128, 48,108,107, 2,142,122,142,146,225,244,225,235,225,238, - 97,129, 48,204,142,134,232,225,236,230,247,233,228,244,104,128, - 255,135,244, 97, 3,142,155,142,165,142,172,226,229,238,231,225, - 236,105,128, 9,188,228,229,246, 97,128, 9, 60,231,117, 2,142, - 179,142,188,234,225,242,225,244,105,128, 10,188,242,237,245,235, - 232,105,128, 10, 60,109, 2,142,203,142,237,226,229,242,243,233, - 231,110,130, 0, 35,142,217,142,229,237,239,238,239,243,240,225, - 227,101,128,255, 3,243,237,225,236,108,128,254, 95,229,114, 2, - 142,244,143, 20,225,236,243,233,231,110, 2,142,255,143, 7,231, - 242,229,229,107,128, 3,116,236,239,247,229,242,231,242,229,229, - 107,128, 3,117,111,128, 33, 22,110,130, 5,224,143, 32,143, 52, - 228,225,231,229,243,104,129,251, 64,143, 43,232,229,226,242,229, - 119,128,251, 64,232,229,226,242,229,119,128, 5,224,246,243,241, - 245,225,242,101,128, 51,181,247,243,241,245,225,242,101,128, 51, - 187,249, 97, 3,143, 90,143,100,143,107,226,229,238,231,225,236, - 105,128, 9,158,228,229,246, 97,128, 9, 30,231,117, 2,143,114, - 143,123,234,225,242,225,244,105,128, 10,158,242,237,245,235,232, - 105,128, 10, 30,111,147, 0,111,143,174,143,196,144, 18,144,188, - 145, 4,145, 19,145, 59,145,182,145,203,145,241,145,252,146,174, - 148, 8,148, 72,148,105,148,151,149, 24,149, 71,149, 83, 97, 2, - 143,180,143,187,227,245,244,101,128, 0,243,238,231,244,232,225, - 105,128, 14, 45, 98, 4,143,206,143,248,144, 1,144, 11,225,242, - 242,229,100,130, 2,117,143,218,143,229,227,249,242,233,236,236, - 233, 99,128, 4,233,228,233,229,242,229,243,233,243,227,249,242, - 233,236,236,233, 99,128, 4,235,229,238,231,225,236,105,128, 9, - 147,239,240,239,237,239,230,111,128, 49, 27,242,229,246,101,128, - 1, 79, 99, 3,144, 26,144, 99,144,178, 97, 2,144, 32,144, 93, - 238,228,242, 97, 3,144, 43,144, 50,144, 61,228,229,246, 97,128, - 9, 17,231,245,234,225,242,225,244,105,128, 10,145,246,239,247, - 229,236,243,233,231,110, 2,144, 75,144, 82,228,229,246, 97,128, - 9, 73,231,245,234,225,242,225,244,105,128, 10,201,242,239,110, - 128, 1,210,233,242, 99, 2,144,107,144,112,236,101,128, 36,222, - 245,237,230,236,229,120,133, 0,244,144,131,144,139,144,150,144, - 158,144,170,225,227,245,244,101,128, 30,209,228,239,244,226,229, - 236,239,119,128, 30,217,231,242,225,246,101,128, 30,211,232,239, - 239,235,225,226,239,246,101,128, 30,213,244,233,236,228,101,128, - 30,215,249,242,233,236,236,233, 99,128, 4, 62,100, 4,144,198, - 144,221,144,227,144,250,226,108, 2,144,205,144,213,225,227,245, - 244,101,128, 1, 81,231,242,225,246,101,128, 2, 13,229,246, 97, - 128, 9, 19,233,229,242,229,243,233,115,129, 0,246,144,239,227, - 249,242,233,236,236,233, 99,128, 4,231,239,244,226,229,236,239, - 119,128, 30,205,101,129, 1, 83,145, 10,235,239,242,229,225,110, - 128, 49, 90,103, 3,145, 27,145, 42,145, 49,239,238,229,107,129, - 2,219,145, 36,227,237, 98,128, 3, 40,242,225,246,101,128, 0, - 242,245,234,225,242,225,244,105,128, 10,147,104, 4,145, 69,145, - 80,145, 90,145,168,225,242,237,229,238,233,225,110,128, 5,133, - 233,242,225,231,225,238, 97,128, 48, 74,111, 2,145, 96,145,106, - 239,235,225,226,239,246,101,128, 30,207,242,110,133, 1,161,145, - 121,145,129,145,140,145,148,145,160,225,227,245,244,101,128, 30, - 219,228,239,244,226,229,236,239,119,128, 30,227,231,242,225,246, - 101,128, 30,221,232,239,239,235,225,226,239,246,101,128, 30,223, - 244,233,236,228,101,128, 30,225,245,238,231,225,242,245,237,236, - 225,245,116,128, 1, 81,105,129, 1,163,145,188,238,246,229,242, - 244,229,228,226,242,229,246,101,128, 2, 15,107, 2,145,209,145, - 233,225,244,225,235,225,238, 97,129, 48,170,145,221,232,225,236, - 230,247,233,228,244,104,128,255,117,239,242,229,225,110,128, 49, - 87,236,229,232,229,226,242,229,119,128, 5,171,109, 6,146, 10, - 146, 38,146, 45,146,134,146,145,146,163,225,227,242,239,110,130, - 1, 77,146, 22,146, 30,225,227,245,244,101,128, 30, 83,231,242, - 225,246,101,128, 30, 81,228,229,246, 97,128, 9, 80,229,231, 97, - 133, 3,201,146, 61,146, 65,146, 76,146, 90,146,106, 49,128, 3, - 214,227,249,242,233,236,236,233, 99,128, 4, 97,236,225,244,233, - 238,227,236,239,243,229,100,128, 2,119,242,239,245,238,228,227, - 249,242,233,236,236,233, 99,128, 4,123,116, 2,146,112,146,127, - 233,244,236,239,227,249,242,233,236,236,233, 99,128, 4,125,239, - 238,239,115,128, 3,206,231,245,234,225,242,225,244,105,128, 10, - 208,233,227,242,239,110,129, 3,191,146,155,244,239,238,239,115, - 128, 3,204,239,238,239,243,240,225,227,101,128,255, 79,238,101, - 145, 0, 49,146,213,146,222,146,232,147, 6,147, 31,147, 40,147, - 49,147, 74,147,108,147,142,147,154,147,173,147,184,147,217,147, - 227,147,235,147,246,225,242,225,226,233, 99,128, 6, 97,226,229, - 238,231,225,236,105,128, 9,231,227,233,242,227,236,101,129, 36, - 96,146,243,233,238,246,229,242,243,229,243,225,238,243,243,229, - 242,233,102,128, 39,138,100, 2,147, 12,147, 18,229,246, 97,128, - 9,103,239,244,229,238,236,229,225,228,229,114,128, 32, 36,229, - 233,231,232,244,104,128, 33, 91,230,233,244,244,229,100,128,246, - 220,231,117, 2,147, 56,147, 65,234,225,242,225,244,105,128, 10, - 231,242,237,245,235,232,105,128, 10,103,232, 97, 3,147, 83,147, - 94,147, 99,227,235,225,242,225,226,233, 99,128, 6, 97,236,102, - 128, 0,189,238,231,250,232,239,117,128, 48, 33,105, 2,147,114, - 147,132,228,229,239,231,242,225,240,232,233,227,240,225,242,229, - 110,128, 50, 32,238,230,229,242,233,239,114,128, 32,129,237,239, - 238,239,243,240,225,227,101,128,255, 17,238,245,237,229,242,225, - 244,239,242,226,229,238,231,225,236,105,128, 9,244,239,236,228, - 243,244,249,236,101,128,247, 49,112, 2,147,190,147,197,225,242, - 229,110,128, 36,116,229,114, 2,147,204,147,210,233,239,100,128, - 36,136,243,233,225,110,128, 6,241,241,245,225,242,244,229,114, - 128, 0,188,242,239,237,225,110,128, 33,112,243,245,240,229,242, - 233,239,114,128, 0,185,244,104, 2,147,253,148, 2,225,105,128, - 14, 81,233,242,100,128, 33, 83,111, 3,148, 16,148, 50,148, 66, - 103, 2,148, 22,148, 40,239,238,229,107,129, 1,235,148, 31,237, - 225,227,242,239,110,128, 1,237,245,242,237,245,235,232,105,128, - 10, 19,237,225,244,242,225,231,245,242,237,245,235,232,105,128, - 10, 75,240,229,110,128, 2, 84,112, 3,148, 80,148, 87,148, 98, - 225,242,229,110,128, 36,170,229,238,226,245,236,236,229,116,128, - 37,230,244,233,239,110,128, 35, 37,114, 2,148,111,148,140,100, - 2,148,117,148,128,230,229,237,233,238,233,238,101,128, 0,170, - 237,225,243,227,245,236,233,238,101,128, 0,186,244,232,239,231, - 239,238,225,108,128, 34, 31,115, 5,148,163,148,195,148,212,149, - 1,149, 14,232,239,242,116, 2,148,172,148,179,228,229,246, 97, - 128, 9, 18,246,239,247,229,236,243,233,231,238,228,229,246, 97, - 128, 9, 74,236,225,243,104,129, 0,248,148,204,225,227,245,244, - 101,128, 1,255,237,225,236,108, 2,148,221,148,232,232,233,242, - 225,231,225,238, 97,128, 48, 73,235,225,244,225,235,225,238, 97, - 129, 48,169,148,245,232,225,236,230,247,233,228,244,104,128,255, - 107,244,242,239,235,229,225,227,245,244,101,128, 1,255,245,240, - 229,242,233,239,114,128,246,240,116, 2,149, 30,149, 41,227,249, - 242,233,236,236,233, 99,128, 4,127,233,236,228,101,130, 0,245, - 149, 52,149, 60,225,227,245,244,101,128, 30, 77,228,233,229,242, - 229,243,233,115,128, 30, 79,245,226,239,240,239,237,239,230,111, - 128, 49, 33,118, 2,149, 89,149,170,229,114, 2,149, 96,149,162, - 236,233,238,101,131, 32, 62,149,109,149,132,149,155, 99, 2,149, - 115,149,127,229,238,244,229,242,236,233,238,101,128,254, 74,237, - 98,128, 3, 5,100, 2,149,138,149,146,225,243,232,229,100,128, - 254, 73,226,236,247,225,246,121,128,254, 76,247,225,246,121,128, - 254, 75,243,227,239,242,101,128, 0,175,239,247,229,236,243,233, - 231,110, 3,149,185,149,195,149,202,226,229,238,231,225,236,105, - 128, 9,203,228,229,246, 97,128, 9, 75,231,245,234,225,242,225, - 244,105,128, 10,203,112,145, 0,112,149,251,152,123,152,134,152, - 143,152,155,154, 80,154, 90,155, 82,156,101,156,191,156,217,157, - 92,157,100,158, 2,158, 60,158, 88,158, 98, 97, 14,150, 25,150, - 57,150, 67,150, 74,150, 81,150,129,150,140,150,154,150,165,150, - 212,150,226,151,238,152, 21,152,111, 97, 2,150, 31,150, 43,237, - 240,243,243,241,245,225,242,101,128, 51,128,243,229,238,244,239, - 243,241,245,225,242,101,128, 51, 43,226,229,238,231,225,236,105, - 128, 9,170,227,245,244,101,128, 30, 85,228,229,246, 97,128, 9, - 42,103, 2,150, 87,150,105,101, 2,150, 93,150,100,228,239,247, - 110,128, 33,223,245,112,128, 33,222,117, 2,150,111,150,120,234, - 225,242,225,244,105,128, 10,170,242,237,245,235,232,105,128, 10, - 42,232,233,242,225,231,225,238, 97,128, 48,113,233,249,225,238, - 238,239,233,244,232,225,105,128, 14, 47,235,225,244,225,235,225, - 238, 97,128, 48,209,108, 2,150,171,150,196,225,244,225,236,233, - 250,225,244,233,239,238,227,249,242,233,236,236,233,227,227,237, - 98,128, 4,132,239,227,232,235,225,227,249,242,233,236,236,233, - 99,128, 4,192,238,243,233,239,243,235,239,242,229,225,110,128, - 49,127,114, 3,150,234,150,255,151,227, 97, 2,150,240,150,248, - 231,242,225,240,104,128, 0,182,236,236,229,108,128, 34, 37,229, - 110, 2,151, 6,151,116,236,229,230,116,136, 0, 40,151, 29,151, - 44,151, 49,151, 54,151, 65,151, 77,151,100,151,105,225,236,244, - 239,238,229,225,242,225,226,233, 99,128,253, 62,226,116,128,248, - 237,229,120,128,248,236,233,238,230,229,242,233,239,114,128, 32, - 141,237,239,238,239,243,240,225,227,101,128,255, 8,115, 2,151, - 83,151, 90,237,225,236,108,128,254, 89,245,240,229,242,233,239, - 114,128, 32,125,244,112,128,248,235,246,229,242,244,233,227,225, - 108,128,254, 53,242,233,231,232,116,136, 0, 41,151,140,151,155, - 151,160,151,165,151,176,151,188,151,211,151,216,225,236,244,239, - 238,229,225,242,225,226,233, 99,128,253, 63,226,116,128,248,248, - 229,120,128,248,247,233,238,230,229,242,233,239,114,128, 32,142, - 237,239,238,239,243,240,225,227,101,128,255, 9,115, 2,151,194, - 151,201,237,225,236,108,128,254, 90,245,240,229,242,233,239,114, - 128, 32,126,244,112,128,248,246,246,229,242,244,233,227,225,108, - 128,254, 54,244,233,225,236,228,233,230,102,128, 34, 2,115, 3, - 151,246,152, 1,152, 13,229,241,232,229,226,242,229,119,128, 5, - 192,232,244,225,232,229,226,242,229,119,128, 5,153,241,245,225, - 242,101,128, 51,169,244,225,104,134, 5,183,152, 39,152, 53,152, - 58,152, 67,152, 82,152, 98, 49, 2,152, 45,152, 49, 49,128, 5, - 183,100,128, 5,183,178, 97,128, 5,183,232,229,226,242,229,119, - 128, 5,183,238,225,242,242,239,247,232,229,226,242,229,119,128, - 5,183,241,245,225,242,244,229,242,232,229,226,242,229,119,128, - 5,183,247,233,228,229,232,229,226,242,229,119,128, 5,183,250, - 229,242,232,229,226,242,229,119,128, 5,161,226,239,240,239,237, - 239,230,111,128, 49, 6,227,233,242,227,236,101,128, 36,223,228, - 239,244,225,227,227,229,238,116,128, 30, 87,101,137, 5,228,152, - 177,152,188,152,208,152,220,152,240,153, 86,153, 97,153,118,154, - 73,227,249,242,233,236,236,233, 99,128, 4, 63,228,225,231,229, - 243,104,129,251, 68,152,199,232,229,226,242,229,119,128,251, 68, - 229,250,233,243,241,245,225,242,101,128, 51, 59,230,233,238,225, - 236,228,225,231,229,243,232,232,229,226,242,229,119,128,251, 67, - 104, 5,152,252,153, 19,153, 27,153, 41,153, 71,225,114, 2,153, - 3,153, 10,225,226,233, 99,128, 6,126,237,229,238,233,225,110, - 128, 5,122,229,226,242,229,119,128, 5,228,230,233,238,225,236, - 225,242,225,226,233, 99,128,251, 87,105, 2,153, 47,153, 62,238, - 233,244,233,225,236,225,242,225,226,233, 99,128,251, 88,242,225, - 231,225,238, 97,128, 48,122,237,229,228,233,225,236,225,242,225, - 226,233, 99,128,251, 89,235,225,244,225,235,225,238, 97,128, 48, - 218,237,233,228,228,236,229,232,239,239,235,227,249,242,233,236, - 236,233, 99,128, 4,167,114, 5,153,130,153,142,153,184,154, 49, - 154, 62,225,230,229,232,229,226,242,229,119,128,251, 78,227,229, - 238,116,131, 0, 37,153,155,153,164,153,176,225,242,225,226,233, - 99,128, 6,106,237,239,238,239,243,240,225,227,101,128,255, 5, - 243,237,225,236,108,128,254,106,105, 2,153,190,154, 31,239,100, - 134, 0, 46,153,207,153,218,153,229,153,241,153,252,154, 8,225, - 242,237,229,238,233,225,110,128, 5,137,227,229,238,244,229,242, - 229,100,128, 0,183,232,225,236,230,247,233,228,244,104,128,255, - 97,233,238,230,229,242,233,239,114,128,246,231,237,239,238,239, - 243,240,225,227,101,128,255, 14,115, 2,154, 14,154, 21,237,225, - 236,108,128,254, 82,245,240,229,242,233,239,114,128,246,232,243, - 240,239,237,229,238,233,231,242,229,229,235,227,237, 98,128, 3, - 66,240,229,238,228,233,227,245,236,225,114,128, 34,165,244,232, - 239,245,243,225,238,100,128, 32, 48,243,229,244, 97,128, 32,167, - 230,243,241,245,225,242,101,128, 51,138,104, 3,154, 98,154,148, - 155, 29, 97, 3,154,106,154,116,154,123,226,229,238,231,225,236, - 105,128, 9,171,228,229,246, 97,128, 9, 43,231,117, 2,154,130, - 154,139,234,225,242,225,244,105,128, 10,171,242,237,245,235,232, - 105,128, 10, 43,105,133, 3,198,154,162,154,166,154,252,155, 4, - 155, 15, 49,128, 3,213,229,245,240,104, 4,154,179,154,214,154, - 229,154,238, 97, 2,154,185,154,200,227,233,242,227,236,229,235, - 239,242,229,225,110,128, 50,122,240,225,242,229,238,235,239,242, - 229,225,110,128, 50, 26,227,233,242,227,236,229,235,239,242,229, - 225,110,128, 50,108,235,239,242,229,225,110,128, 49, 77,240,225, - 242,229,238,235,239,242,229,225,110,128, 50, 12,236,225,244,233, - 110,128, 2,120,238,244,232,245,244,232,225,105,128, 14, 58,243, - 249,237,226,239,236,231,242,229,229,107,128, 3,213,111, 3,155, - 37,155, 42,155, 68,239,107,128, 1,165,240,104, 2,155, 49,155, - 58,225,238,244,232,225,105,128, 14, 30,245,238,231,244,232,225, - 105,128, 14, 28,243,225,237,240,232,225,239,244,232,225,105,128, - 14, 32,105,133, 3,192,155, 96,156, 52,156, 63,156, 74,156, 88, - 229,245,112, 6,155,112,155,147,155,179,155,207,155,221,156, 17, - 97, 2,155,118,155,133,227,233,242,227,236,229,235,239,242,229, - 225,110,128, 50,115,240,225,242,229,238,235,239,242,229,225,110, - 128, 50, 19,227,105, 2,155,154,155,166,229,245,227,235,239,242, - 229,225,110,128, 49,118,242,227,236,229,235,239,242,229,225,110, - 128, 50,101,107, 2,155,185,155,199,233,249,229,239,235,235,239, - 242,229,225,110,128, 49,114,239,242,229,225,110,128, 49, 66,240, - 225,242,229,238,235,239,242,229,225,110,128, 50, 5,243,233,239, - 115, 2,155,230,156, 2,107, 2,155,236,155,250,233,249,229,239, - 235,235,239,242,229,225,110,128, 49,116,239,242,229,225,110,128, - 49, 68,244,233,235,229,245,244,235,239,242,229,225,110,128, 49, - 117,116, 2,156, 23,156, 38,232,233,229,245,244,232,235,239,242, - 229,225,110,128, 49,119,233,235,229,245,244,235,239,242,229,225, - 110,128, 49,115,232,233,242,225,231,225,238, 97,128, 48,116,235, - 225,244,225,235,225,238, 97,128, 48,212,243,249,237,226,239,236, - 231,242,229,229,107,128, 3,214,247,242,225,242,237,229,238,233, - 225,110,128, 5,131,236,245,115,132, 0, 43,156,115,156,126,156, - 135,156,168,226,229,236,239,247,227,237, 98,128, 3, 31,227,233, - 242,227,236,101,128, 34,149,109, 2,156,141,156,148,233,238,245, - 115,128, 0,177,111, 2,156,154,156,158,100,128, 2,214,238,239, - 243,240,225,227,101,128,255, 11,115, 2,156,174,156,181,237,225, - 236,108,128,254, 98,245,240,229,242,233,239,114,128, 32,122,109, - 2,156,197,156,208,239,238,239,243,240,225,227,101,128,255, 80, - 243,241,245,225,242,101,128, 51,216,111, 5,156,229,156,240,157, - 51,157, 62,157, 72,232,233,242,225,231,225,238, 97,128, 48,125, - 233,238,244,233,238,231,233,238,228,229,120, 4,157, 4,157, 16, - 157, 28,157, 41,228,239,247,238,247,232,233,244,101,128, 38, 31, - 236,229,230,244,247,232,233,244,101,128, 38, 28,242,233,231,232, - 244,247,232,233,244,101,128, 38, 30,245,240,247,232,233,244,101, - 128, 38, 29,235,225,244,225,235,225,238, 97,128, 48,221,240,236, - 225,244,232,225,105,128, 14, 27,243,244,225,236,237,225,242,107, - 129, 48, 18,157, 85,230,225,227,101,128, 48, 32,240,225,242,229, - 110,128, 36,171,114, 3,157,108,157,134,157,159,101, 2,157,114, - 157,122,227,229,228,229,115,128, 34,122,243,227,242,233,240,244, - 233,239,110,128, 33, 30,233,237,101, 2,157,142,157,148,237,239, - 100,128, 2,185,242,229,246,229,242,243,229,100,128, 32, 53,111, - 4,157,169,157,176,157,186,157,199,228,245,227,116,128, 34, 15, - 234,229,227,244,233,246,101,128, 35, 5,236,239,238,231,229,228, - 235,225,238, 97,128, 48,252,112, 2,157,205,157,242,101, 2,157, - 211,157,218,236,236,239,114,128, 35, 24,242,243,117, 2,157,226, - 157,233,226,243,229,116,128, 34,130,240,229,242,243,229,116,128, - 34,131,239,242,244,233,239,110,129, 34, 55,157,253,225,108,128, - 34, 29,115, 2,158, 8,158, 51,105,130, 3,200,158, 16,158, 27, - 227,249,242,233,236,236,233, 99,128, 4,113,236,233,240,238,229, - 245,237,225,244,225,227,249,242,233,236,236,233,227,227,237, 98, - 128, 4,134,243,241,245,225,242,101,128, 51,176,117, 2,158, 66, - 158, 77,232,233,242,225,231,225,238, 97,128, 48,119,235,225,244, - 225,235,225,238, 97,128, 48,215,246,243,241,245,225,242,101,128, - 51,180,247,243,241,245,225,242,101,128, 51,186,113,136, 0,113, - 158,128,159,177,159,188,159,197,159,204,159,216,159,254,160, 6, - 97, 4,158,138,158,161,158,225,159,160,100, 2,158,144,158,150, - 229,246, 97,128, 9, 88,237,225,232,229,226,242,229,119,128, 5, - 168,102, 4,158,171,158,180,158,194,158,210,225,242,225,226,233, - 99,128, 6, 66,230,233,238,225,236,225,242,225,226,233, 99,128, - 254,214,233,238,233,244,233,225,236,225,242,225,226,233, 99,128, - 254,215,237,229,228,233,225,236,225,242,225,226,233, 99,128,254, - 216,237,225,244,115,136, 5,184,158,248,159, 12,159, 26,159, 31, - 159, 36,159, 45,159, 60,159,147, 49, 3,159, 0,159, 4,159, 8, - 48,128, 5,184, 97,128, 5,184, 99,128, 5,184, 50, 2,159, 18, - 159, 22, 55,128, 5,184, 57,128, 5,184,179, 51,128, 5,184,228, - 101,128, 5,184,232,229,226,242,229,119,128, 5,184,238,225,242, - 242,239,247,232,229,226,242,229,119,128, 5,184,113, 2,159, 66, - 159,132,225,244,225,110, 4,159, 79,159, 88,159,103,159,119,232, - 229,226,242,229,119,128, 5,184,238,225,242,242,239,247,232,229, - 226,242,229,119,128, 5,184,241,245,225,242,244,229,242,232,229, - 226,242,229,119,128, 5,184,247,233,228,229,232,229,226,242,229, - 119,128, 5,184,245,225,242,244,229,242,232,229,226,242,229,119, - 128, 5,184,247,233,228,229,232,229,226,242,229,119,128, 5,184, - 242,238,229,249,240,225,242,225,232,229,226,242,229,119,128, 5, - 159,226,239,240,239,237,239,230,111,128, 49, 17,227,233,242,227, - 236,101,128, 36,224,232,239,239,107,128, 2,160,237,239,238,239, - 243,240,225,227,101,128,255, 81,239,102,130, 5,231,159,225,159, - 245,228,225,231,229,243,104,129,251, 71,159,236,232,229,226,242, - 229,119,128,251, 71,232,229,226,242,229,119,128, 5,231,240,225, - 242,229,110,128, 36,172,117, 4,160, 16,160, 28,160,117,160,204, - 225,242,244,229,242,238,239,244,101,128, 38,105,226,245,244,115, - 135, 5,187,160, 49,160, 54,160, 59,160, 64,160, 73,160, 88,160, - 104,177, 56,128, 5,187,178, 53,128, 5,187,179, 49,128, 5,187, - 232,229,226,242,229,119,128, 5,187,238,225,242,242,239,247,232, - 229,226,242,229,119,128, 5,187,241,245,225,242,244,229,242,232, - 229,226,242,229,119,128, 5,187,247,233,228,229,232,229,226,242, - 229,119,128, 5,187,229,243,244,233,239,110,133, 0, 63,160,136, - 160,159,160,176,160,184,160,196,225,114, 2,160,143,160,150,225, - 226,233, 99,128, 6, 31,237,229,238,233,225,110,128, 5, 94,228, - 239,247,110,129, 0,191,160,168,243,237,225,236,108,128,247,191, - 231,242,229,229,107,128, 3,126,237,239,238,239,243,240,225,227, - 101,128,255, 31,243,237,225,236,108,128,247, 63,239,244,101, 4, - 160,216,161, 31,161, 51,161, 80,228,226,108,133, 0, 34,160,232, - 160,239,160,246,161, 2,161, 23,226,225,243,101,128, 32, 30,236, - 229,230,116,128, 32, 28,237,239,238,239,243,240,225,227,101,128, - 255, 2,240,242,233,237,101,129, 48, 30,161, 12,242,229,246,229, - 242,243,229,100,128, 48, 29,242,233,231,232,116,128, 32, 29,236, - 229,230,116,129, 32, 24,161, 40,242,229,246,229,242,243,229,100, - 128, 32, 27,114, 2,161, 57,161, 67,229,246,229,242,243,229,100, - 128, 32, 27,233,231,232,116,129, 32, 25,161, 76,110,128, 1, 73, - 243,233,238,231,108, 2,161, 90,161, 97,226,225,243,101,128, 32, - 26,101,129, 0, 39,161,103,237,239,238,239,243,240,225,227,101, - 128,255, 7,114,145, 0,114,161,153,162,157,162,168,162,215,163, - 10,164, 27,164, 51,164,146,166,180,166,217,166,229,167, 27,167, - 35,167,197,167,208,167,243,168, 87, 97, 11,161,177,161,188,161, - 198,161,205,162, 14,162, 30,162, 55,162, 66,162, 91,162,114,162, - 151,225,242,237,229,238,233,225,110,128, 5,124,226,229,238,231, - 225,236,105,128, 9,176,227,245,244,101,128, 1, 85,100, 4,161, - 215,161,221,161,235,162, 5,229,246, 97,128, 9, 48,233,227,225, - 108,129, 34, 26,161,230,229,120,128,248,229,239,246,229,242,243, - 243,241,245,225,242,101,129, 51,174,161,251,228,243,241,245,225, - 242,101,128, 51,175,243,241,245,225,242,101,128, 51,173,230,101, - 129, 5,191,162, 21,232,229,226,242,229,119,128, 5,191,231,117, - 2,162, 37,162, 46,234,225,242,225,244,105,128, 10,176,242,237, - 245,235,232,105,128, 10, 48,232,233,242,225,231,225,238, 97,128, - 48,137,235,225,244,225,235,225,238, 97,129, 48,233,162, 79,232, - 225,236,230,247,233,228,244,104,128,255,151,236,239,247,229,242, - 228,233,225,231,239,238,225,236,226,229,238,231,225,236,105,128, - 9,241,109, 2,162,120,162,143,233,228,228,236,229,228,233,225, - 231,239,238,225,236,226,229,238,231,225,236,105,128, 9,240,243, - 232,239,242,110,128, 2,100,244,233,111,128, 34, 54,226,239,240, - 239,237,239,230,111,128, 49, 22, 99, 4,162,178,162,185,162,194, - 162,202,225,242,239,110,128, 1, 89,229,228,233,236,236, 97,128, - 1, 87,233,242,227,236,101,128, 36,225,239,237,237,225,225,227, - 227,229,238,116,128, 1, 87,100, 2,162,221,162,231,226,236,231, - 242,225,246,101,128, 2, 17,239,116, 2,162,238,162,247,225,227, - 227,229,238,116,128, 30, 89,226,229,236,239,119,129, 30, 91,163, - 1,237,225,227,242,239,110,128, 30, 93,101, 6,163, 24,163, 69, - 163,104,163,159,163,184,163,217,102, 2,163, 30,163, 43,229,242, - 229,238,227,229,237,225,242,107,128, 32, 59,236,229,248,243,117, - 2,163, 53,163, 60,226,243,229,116,128, 34,134,240,229,242,243, - 229,116,128, 34,135,231,233,243,244,229,114, 2,163, 80,163, 85, - 229,100,128, 0,174,115, 2,163, 91,163, 97,225,238,115,128,248, - 232,229,242,233,102,128,246,218,104, 3,163,112,163,135,163,149, - 225,114, 2,163,119,163,126,225,226,233, 99,128, 6, 49,237,229, - 238,233,225,110,128, 5,128,230,233,238,225,236,225,242,225,226, - 233, 99,128,254,174,233,242,225,231,225,238, 97,128, 48,140,235, - 225,244,225,235,225,238, 97,129, 48,236,163,172,232,225,236,230, - 247,233,228,244,104,128,255,154,243,104,130, 5,232,163,193,163, - 208,228,225,231,229,243,232,232,229,226,242,229,119,128,251, 72, - 232,229,226,242,229,119,128, 5,232,118, 3,163,225,163,238,164, - 14,229,242,243,229,228,244,233,236,228,101,128, 34, 61,233, 97, - 2,163,245,163,254,232,229,226,242,229,119,128, 5,151,237,245, - 231,242,225,243,232,232,229,226,242,229,119,128, 5,151,236,239, - 231,233,227,225,236,238,239,116,128, 35, 16,230,233,243,232,232, - 239,239,107,129, 2,126,164, 40,242,229,246,229,242,243,229,100, - 128, 2,127,104, 2,164, 57,164, 80, 97, 2,164, 63,164, 73,226, - 229,238,231,225,236,105,128, 9,221,228,229,246, 97,128, 9, 93, - 111,131, 3,193,164, 90,164,119,164,133,239,107,129, 2,125,164, - 97,244,245,242,238,229,100,129, 2,123,164,108,243,245,240,229, - 242,233,239,114,128, 2,181,243,249,237,226,239,236,231,242,229, - 229,107,128, 3,241,244,233,227,232,239,239,235,237,239,100,128, - 2,222,105, 6,164,160,165,204,165,250,166, 5,166, 30,166,166, - 229,245,108, 9,164,182,164,217,164,232,164,246,165, 36,165, 50, - 165,136,165,149,165,184, 97, 2,164,188,164,203,227,233,242,227, - 236,229,235,239,242,229,225,110,128, 50,113,240,225,242,229,238, - 235,239,242,229,225,110,128, 50, 17,227,233,242,227,236,229,235, - 239,242,229,225,110,128, 50, 99,232,233,229,245,232,235,239,242, - 229,225,110,128, 49, 64,107, 2,164,252,165, 28,233,249,229,239, - 107, 2,165, 6,165, 15,235,239,242,229,225,110,128, 49, 58,243, - 233,239,243,235,239,242,229,225,110,128, 49,105,239,242,229,225, - 110,128, 49, 57,237,233,229,245,237,235,239,242,229,225,110,128, - 49, 59,112, 3,165, 58,165, 90,165,105, 97, 2,165, 64,165, 78, - 238,243,233,239,243,235,239,242,229,225,110,128, 49,108,242,229, - 238,235,239,242,229,225,110,128, 50, 3,232,233,229,245,240,232, - 235,239,242,229,225,110,128, 49, 63,233,229,245,112, 2,165,114, - 165,123,235,239,242,229,225,110,128, 49, 60,243,233,239,243,235, - 239,242,229,225,110,128, 49,107,243,233,239,243,235,239,242,229, - 225,110,128, 49, 61,116, 2,165,155,165,170,232,233,229,245,244, - 232,235,239,242,229,225,110,128, 49, 62,233,235,229,245,244,235, - 239,242,229,225,110,128, 49,106,249,229,239,242,233,238,232,233, - 229,245,232,235,239,242,229,225,110,128, 49,109,231,232,116, 2, - 165,212,165,220,225,238,231,236,101,128, 34, 31,116, 2,165,226, - 165,240,225,227,235,226,229,236,239,247,227,237, 98,128, 3, 25, - 242,233,225,238,231,236,101,128, 34,191,232,233,242,225,231,225, - 238, 97,128, 48,138,235,225,244,225,235,225,238, 97,129, 48,234, - 166, 18,232,225,236,230,247,233,228,244,104,128,255,152,110, 2, - 166, 36,166,152,103,131, 2,218,166, 46,166, 57,166, 63,226,229, - 236,239,247,227,237, 98,128, 3, 37,227,237, 98,128, 3, 10,232, - 225,236,102, 2,166, 72,166,118,236,229,230,116,131, 2,191,166, - 85,166, 96,166,107,225,242,237,229,238,233,225,110,128, 5, 89, - 226,229,236,239,247,227,237, 98,128, 3, 28,227,229,238,244,229, - 242,229,100,128, 2,211,242,233,231,232,116,130, 2,190,166,130, - 166,141,226,229,236,239,247,227,237, 98,128, 3, 57,227,229,238, - 244,229,242,229,100,128, 2,210,246,229,242,244,229,228,226,242, - 229,246,101,128, 2, 19,244,244,239,242,245,243,241,245,225,242, - 101,128, 51, 81,108, 2,166,186,166,197,233,238,229,226,229,236, - 239,119,128, 30, 95,239,238,231,236,229,103,129, 2,124,166,208, - 244,245,242,238,229,100,128, 2,122,237,239,238,239,243,240,225, - 227,101,128,255, 82,111, 3,166,237,166,248,167, 17,232,233,242, - 225,231,225,238, 97,128, 48,141,235,225,244,225,235,225,238, 97, - 129, 48,237,167, 5,232,225,236,230,247,233,228,244,104,128,255, - 155,242,245,225,244,232,225,105,128, 14, 35,240,225,242,229,110, - 128, 36,173,114, 3,167, 43,167, 79,167,109, 97, 3,167, 51,167, - 61,167, 68,226,229,238,231,225,236,105,128, 9,220,228,229,246, - 97,128, 9, 49,231,245,242,237,245,235,232,105,128, 10, 92,229, - 104, 2,167, 86,167, 95,225,242,225,226,233, 99,128, 6,145,230, - 233,238,225,236,225,242,225,226,233, 99,128,251,141,246,239,227, - 225,236,233, 99, 4,167,125,167,135,167,142,167,153,226,229,238, - 231,225,236,105,128, 9,224,228,229,246, 97,128, 9, 96,231,245, - 234,225,242,225,244,105,128, 10,224,246,239,247,229,236,243,233, - 231,110, 3,167,169,167,179,167,186,226,229,238,231,225,236,105, - 128, 9,196,228,229,246, 97,128, 9, 68,231,245,234,225,242,225, - 244,105,128, 10,196,243,245,240,229,242,233,239,114,128,246,241, - 116, 2,167,214,167,222,226,236,239,227,107,128, 37,144,245,242, - 238,229,100,129, 2,121,167,232,243,245,240,229,242,233,239,114, - 128, 2,180,117, 4,167,253,168, 8,168, 33,168, 80,232,233,242, - 225,231,225,238, 97,128, 48,139,235,225,244,225,235,225,238, 97, - 129, 48,235,168, 21,232,225,236,230,247,233,228,244,104,128,255, - 153,112, 2,168, 39,168, 74,229,101, 2,168, 46,168, 60,237,225, - 242,235,226,229,238,231,225,236,105,128, 9,242,243,233,231,238, - 226,229,238,231,225,236,105,128, 9,243,233,225,104,128,246,221, - 244,232,225,105,128, 14, 36,246,239,227,225,236,233, 99, 4,168, - 103,168,113,168,120,168,131,226,229,238,231,225,236,105,128, 9, - 139,228,229,246, 97,128, 9, 11,231,245,234,225,242,225,244,105, - 128, 10,139,246,239,247,229,236,243,233,231,110, 3,168,147,168, - 157,168,164,226,229,238,231,225,236,105,128, 9,195,228,229,246, - 97,128, 9, 67,231,245,234,225,242,225,244,105,128, 10,195,115, - 147, 0,115,168,217,170,187,170,198,171, 68,171,107,174, 49,174, - 60,176,203,179, 85,179,131,179,158,180, 93,180,160,181,193,181, - 203,182,133,182,206,183,120,183,130, 97, 9,168,237,168,247,169, - 12,169, 84,169,109,169,120,169,145,169,177,169,217,226,229,238, - 231,225,236,105,128, 9,184,227,245,244,101,129, 1, 91,169, 0, - 228,239,244,225,227,227,229,238,116,128, 30,101,100, 5,169, 24, - 169, 33,169, 39,169, 53,169, 69,225,242,225,226,233, 99,128, 6, - 53,229,246, 97,128, 9, 56,230,233,238,225,236,225,242,225,226, - 233, 99,128,254,186,233,238,233,244,233,225,236,225,242,225,226, - 233, 99,128,254,187,237,229,228,233,225,236,225,242,225,226,233, - 99,128,254,188,231,117, 2,169, 91,169,100,234,225,242,225,244, - 105,128, 10,184,242,237,245,235,232,105,128, 10, 56,232,233,242, - 225,231,225,238, 97,128, 48, 85,235,225,244,225,235,225,238, 97, - 129, 48,181,169,133,232,225,236,230,247,233,228,244,104,128,255, - 123,236,236,225,236,236,225,232,239,245,225,236,225,249,232,229, - 247,225,243,225,236,236,225,237,225,242,225,226,233, 99,128,253, - 250,237,229,235,104,130, 5,225,169,188,169,208,228,225,231,229, - 243,104,129,251, 65,169,199,232,229,226,242,229,119,128,251, 65, - 232,229,226,242,229,119,128, 5,225,242, 97, 5,169,230,170, 48, - 170, 56,170,106,170,114, 97, 5,169,242,169,250,170, 2,170, 33, - 170, 41,225,244,232,225,105,128, 14, 50,229,244,232,225,105,128, - 14, 65,233,237,225,233,109, 2,170, 12,170, 23,225,236,225,233, - 244,232,225,105,128, 14, 68,245,225,238,244,232,225,105,128, 14, - 67,237,244,232,225,105,128, 14, 51,244,232,225,105,128, 14, 48, - 229,244,232,225,105,128, 14, 64,105, 3,170, 64,170, 88,170, 99, - 105, 2,170, 70,170, 81,236,229,230,244,244,232,225,105,128,248, - 134,244,232,225,105,128, 14, 53,236,229,230,244,244,232,225,105, - 128,248,133,244,232,225,105,128, 14, 52,239,244,232,225,105,128, - 14, 66,117, 3,170,122,170,172,170,179,101, 3,170,130,170,154, - 170,165,101, 2,170,136,170,147,236,229,230,244,244,232,225,105, - 128,248,136,244,232,225,105,128, 14, 55,236,229,230,244,244,232, - 225,105,128,248,135,244,232,225,105,128, 14, 54,244,232,225,105, - 128, 14, 56,245,244,232,225,105,128, 14, 57,226,239,240,239,237, - 239,230,111,128, 49, 25, 99, 5,170,210,170,231,170,240,171, 33, - 171, 55,225,242,239,110,129, 1, 97,170,219,228,239,244,225,227, - 227,229,238,116,128, 30,103,229,228,233,236,236, 97,128, 1, 95, - 232,247, 97,131, 2, 89,170,252,171, 7,171, 26,227,249,242,233, - 236,236,233, 99,128, 4,217,228,233,229,242,229,243,233,243,227, - 249,242,233,236,236,233, 99,128, 4,219,232,239,239,107,128, 2, - 90,233,242, 99, 2,171, 41,171, 46,236,101,128, 36,226,245,237, - 230,236,229,120,128, 1, 93,239,237,237,225,225,227,227,229,238, - 116,128, 2, 25,228,239,116, 2,171, 76,171, 85,225,227,227,229, - 238,116,128, 30, 97,226,229,236,239,119,129, 30, 99,171, 95,228, - 239,244,225,227,227,229,238,116,128, 30,105,101, 9,171,127,171, - 143,171,178,171,243,172, 90,172,117,172,142,172,223,172,250,225, - 231,245,236,236,226,229,236,239,247,227,237, 98,128, 3, 60, 99, - 2,171,149,171,171,239,238,100,129, 32, 51,171,157,244,239,238, - 229,227,232,233,238,229,243,101,128, 2,202,244,233,239,110,128, - 0,167,229,110, 4,171,189,171,198,171,212,171,228,225,242,225, - 226,233, 99,128, 6, 51,230,233,238,225,236,225,242,225,226,233, - 99,128,254,178,233,238,233,244,233,225,236,225,242,225,226,233, - 99,128,254,179,237,229,228,233,225,236,225,242,225,226,233, 99, - 128,254,180,231,239,108,135, 5,182,172, 7,172, 21,172, 26,172, - 35,172, 50,172, 66,172, 77, 49, 2,172, 13,172, 17, 51,128, 5, - 182,102,128, 5,182,178, 99,128, 5,182,232,229,226,242,229,119, - 128, 5,182,238,225,242,242,239,247,232,229,226,242,229,119,128, - 5,182,241,245,225,242,244,229,242,232,229,226,242,229,119,128, - 5,182,244,225,232,229,226,242,229,119,128, 5,146,247,233,228, - 229,232,229,226,242,229,119,128, 5,182,104, 2,172, 96,172,107, - 225,242,237,229,238,233,225,110,128, 5,125,233,242,225,231,225, - 238, 97,128, 48, 91,235,225,244,225,235,225,238, 97,129, 48,187, - 172,130,232,225,236,230,247,233,228,244,104,128,255,126,237,105, - 2,172,149,172,192,227,239,236,239,110,131, 0, 59,172,163,172, - 172,172,184,225,242,225,226,233, 99,128, 6, 27,237,239,238,239, - 243,240,225,227,101,128,255, 27,243,237,225,236,108,128,254, 84, - 246,239,233,227,229,228,237,225,242,235,235,225,238, 97,129, 48, - 156,172,211,232,225,236,230,247,233,228,244,104,128,255,159,238, - 116, 2,172,230,172,240,233,243,241,245,225,242,101,128, 51, 34, - 239,243,241,245,225,242,101,128, 51, 35,246,229,110,142, 0, 55, - 173, 28,173, 37,173, 47,173, 77,173, 84,173, 94,173,119,173,146, - 173,180,173,192,173,203,173,236,173,244,173,255,225,242,225,226, - 233, 99,128, 6,103,226,229,238,231,225,236,105,128, 9,237,227, - 233,242,227,236,101,129, 36,102,173, 58,233,238,246,229,242,243, - 229,243,225,238,243,243,229,242,233,102,128, 39,144,228,229,246, - 97,128, 9,109,229,233,231,232,244,232,115,128, 33, 94,231,117, - 2,173,101,173,110,234,225,242,225,244,105,128, 10,237,242,237, - 245,235,232,105,128, 10,109,232, 97, 2,173,126,173,137,227,235, - 225,242,225,226,233, 99,128, 6,103,238,231,250,232,239,117,128, - 48, 39,105, 2,173,152,173,170,228,229,239,231,242,225,240,232, - 233,227,240,225,242,229,110,128, 50, 38,238,230,229,242,233,239, - 114,128, 32,135,237,239,238,239,243,240,225,227,101,128,255, 23, - 239,236,228,243,244,249,236,101,128,247, 55,112, 2,173,209,173, - 216,225,242,229,110,128, 36,122,229,114, 2,173,223,173,229,233, - 239,100,128, 36,142,243,233,225,110,128, 6,247,242,239,237,225, - 110,128, 33,118,243,245,240,229,242,233,239,114,128, 32,119,116, - 2,174, 5,174, 43,229,229,110, 2,174, 13,174, 22,227,233,242, - 227,236,101,128, 36,112,112, 2,174, 28,174, 35,225,242,229,110, - 128, 36,132,229,242,233,239,100,128, 36,152,232,225,105,128, 14, - 87,230,244,232,249,240,232,229,110,128, 0,173,104, 7,174, 76, - 175, 50,175, 61,175, 75,176, 20,176, 33,176,197, 97, 6,174, 90, - 174,101,174,111,174,122,175, 9,175, 34,225,242,237,229,238,233, - 225,110,128, 5,119,226,229,238,231,225,236,105,128, 9,182,227, - 249,242,233,236,236,233, 99,128, 4, 72,100, 2,174,128,174,224, - 228, 97, 4,174,139,174,148,174,179,174,193,225,242,225,226,233, - 99,128, 6, 81,228,225,237,237, 97, 2,174,158,174,167,225,242, - 225,226,233, 99,128,252, 97,244,225,238,225,242,225,226,233, 99, - 128,252, 94,230,225,244,232,225,225,242,225,226,233, 99,128,252, - 96,235,225,243,242, 97, 2,174,203,174,212,225,242,225,226,233, - 99,128,252, 98,244,225,238,225,242,225,226,233, 99,128,252, 95, - 101,132, 37,146,174,236,174,243,174,251,175, 4,228,225,242,107, - 128, 37,147,236,233,231,232,116,128, 37,145,237,229,228,233,245, - 109,128, 37,146,246, 97,128, 9, 54,231,117, 2,175, 16,175, 25, - 234,225,242,225,244,105,128, 10,182,242,237,245,235,232,105,128, - 10, 54,236,243,232,229,236,229,244,232,229,226,242,229,119,128, - 5,147,226,239,240,239,237,239,230,111,128, 49, 21,227,232,225, - 227,249,242,233,236,236,233, 99,128, 4, 73,101, 4,175, 85,175, - 150,175,160,175,177,229,110, 4,175, 96,175,105,175,119,175,135, - 225,242,225,226,233, 99,128, 6, 52,230,233,238,225,236,225,242, - 225,226,233, 99,128,254,182,233,238,233,244,233,225,236,225,242, - 225,226,233, 99,128,254,183,237,229,228,233,225,236,225,242,225, - 226,233, 99,128,254,184,233,227,239,240,244,233, 99,128, 3,227, - 241,229,108,129, 32,170,175,168,232,229,226,242,229,119,128, 32, - 170,246, 97,134, 5,176,175,194,175,209,175,223,175,232,175,247, - 176, 7, 49, 2,175,200,175,205,177, 53,128, 5,176, 53,128, 5, - 176, 50, 2,175,215,175,219, 50,128, 5,176,101,128, 5,176,232, - 229,226,242,229,119,128, 5,176,238,225,242,242,239,247,232,229, - 226,242,229,119,128, 5,176,241,245,225,242,244,229,242,232,229, - 226,242,229,119,128, 5,176,247,233,228,229,232,229,226,242,229, - 119,128, 5,176,232,225,227,249,242,233,236,236,233, 99,128, 4, - 187,105, 2,176, 39,176, 50,237,225,227,239,240,244,233, 99,128, - 3,237,110,131, 5,233,176, 60,176,143,176,152,100, 2,176, 66, - 176,132,225,231,229,243,104,130,251, 73,176, 78,176, 87,232,229, - 226,242,229,119,128,251, 73,115, 2,176, 93,176,113,232,233,238, - 228,239,116,129,251, 44,176,104,232,229,226,242,229,119,128,251, - 44,233,238,228,239,116,129,251, 45,176,123,232,229,226,242,229, - 119,128,251, 45,239,244,232,229,226,242,229,119,128, 5,193,232, - 229,226,242,229,119,128, 5,233,115, 2,176,158,176,178,232,233, - 238,228,239,116,129,251, 42,176,169,232,229,226,242,229,119,128, - 251, 42,233,238,228,239,116,129,251, 43,176,188,232,229,226,242, - 229,119,128,251, 43,239,239,107,128, 2,130,105, 8,176,221,177, - 9,177, 20,177, 45,177, 75,177, 83,177, 96,178, 11,231,237, 97, - 131, 3,195,176,233,176,237,176,245, 49,128, 3,194,230,233,238, - 225,108,128, 3,194,236,245,238,225,244,229,243,249,237,226,239, - 236,231,242,229,229,107,128, 3,242,232,233,242,225,231,225,238, - 97,128, 48, 87,235,225,244,225,235,225,238, 97,129, 48,183,177, - 33,232,225,236,230,247,233,228,244,104,128,255,124,236,245,113, - 2,177, 53,177, 62,232,229,226,242,229,119,128, 5,189,236,229, - 230,244,232,229,226,242,229,119,128, 5,189,237,233,236,225,114, - 128, 34, 60,238,228,239,244,232,229,226,242,229,119,128, 5,194, - 239,115, 6,177,111,177,146,177,178,177,206,177,220,177,252, 97, - 2,177,117,177,132,227,233,242,227,236,229,235,239,242,229,225, - 110,128, 50,116,240,225,242,229,238,235,239,242,229,225,110,128, - 50, 20,227,105, 2,177,153,177,165,229,245,227,235,239,242,229, - 225,110,128, 49,126,242,227,236,229,235,239,242,229,225,110,128, - 50,102,107, 2,177,184,177,198,233,249,229,239,235,235,239,242, - 229,225,110,128, 49,122,239,242,229,225,110,128, 49, 69,238,233, - 229,245,238,235,239,242,229,225,110,128, 49,123,112, 2,177,226, - 177,239,225,242,229,238,235,239,242,229,225,110,128, 50, 6,233, - 229,245,240,235,239,242,229,225,110,128, 49,125,244,233,235,229, - 245,244,235,239,242,229,225,110,128, 49,124,120,141, 0, 54,178, - 41,178, 50,178, 60,178, 90,178, 97,178,122,178,149,178,183,178, - 195,178,206,178,239,178,247,179, 2,225,242,225,226,233, 99,128, - 6,102,226,229,238,231,225,236,105,128, 9,236,227,233,242,227, - 236,101,129, 36,101,178, 71,233,238,246,229,242,243,229,243,225, - 238,243,243,229,242,233,102,128, 39,143,228,229,246, 97,128, 9, - 108,231,117, 2,178,104,178,113,234,225,242,225,244,105,128, 10, - 236,242,237,245,235,232,105,128, 10,108,232, 97, 2,178,129,178, - 140,227,235,225,242,225,226,233, 99,128, 6,102,238,231,250,232, - 239,117,128, 48, 38,105, 2,178,155,178,173,228,229,239,231,242, - 225,240,232,233,227,240,225,242,229,110,128, 50, 37,238,230,229, - 242,233,239,114,128, 32,134,237,239,238,239,243,240,225,227,101, - 128,255, 22,239,236,228,243,244,249,236,101,128,247, 54,112, 2, - 178,212,178,219,225,242,229,110,128, 36,121,229,114, 2,178,226, - 178,232,233,239,100,128, 36,141,243,233,225,110,128, 6,246,242, - 239,237,225,110,128, 33,117,243,245,240,229,242,233,239,114,128, - 32,118,116, 2,179, 8,179, 79,229,229,110, 2,179, 16,179, 58, - 99, 2,179, 22,179, 30,233,242,227,236,101,128, 36,111,245,242, - 242,229,238,227,249,228,229,238,239,237,233,238,225,244,239,242, - 226,229,238,231,225,236,105,128, 9,249,112, 2,179, 64,179, 71, - 225,242,229,110,128, 36,131,229,242,233,239,100,128, 36,151,232, - 225,105,128, 14, 86,108, 2,179, 91,179,111,225,243,104,129, 0, - 47,179, 99,237,239,238,239,243,240,225,227,101,128,255, 15,239, - 238,103,129, 1,127,179,119,228,239,244,225,227,227,229,238,116, - 128, 30,155,109, 2,179,137,179,147,233,236,229,230,225,227,101, - 128, 38, 58,239,238,239,243,240,225,227,101,128,255, 83,111, 6, - 179,172,179,222,179,233,180, 2,180, 47,180, 58,102, 2,179,178, - 179,192,240,225,243,245,241,232,229,226,242,229,119,128, 5,195, - 116, 2,179,198,179,207,232,249,240,232,229,110,128, 0,173,243, - 233,231,238,227,249,242,233,236,236,233, 99,128, 4, 76,232,233, - 242,225,231,225,238, 97,128, 48, 93,235,225,244,225,235,225,238, - 97,129, 48,189,179,246,232,225,236,230,247,233,228,244,104,128, - 255,127,236,233,228,245,115, 2,180, 12,180, 29,236,239,238,231, - 239,246,229,242,236,225,249,227,237, 98,128, 3, 56,243,232,239, - 242,244,239,246,229,242,236,225,249,227,237, 98,128, 3, 55,242, - 245,243,233,244,232,225,105,128, 14, 41,115, 3,180, 66,180, 76, - 180, 84,225,236,225,244,232,225,105,128, 14, 40,239,244,232,225, - 105,128, 14, 11,245,225,244,232,225,105,128, 14, 42,240, 97, 3, - 180,102,180,122,180,154,227,101,129, 0, 32,180,109,232,225,227, - 235,225,242,225,226,233, 99,128, 0, 32,228,101,129, 38, 96,180, - 129,243,245,233,116, 2,180,138,180,146,226,236,225,227,107,128, - 38, 96,247,232,233,244,101,128, 38,100,242,229,110,128, 36,174, - 241,245,225,242,101, 11,180,188,180,199,180,213,180,238,180,255, - 181, 25,181, 40,181, 73,181,100,181,156,181,171,226,229,236,239, - 247,227,237, 98,128, 3, 59, 99, 2,180,205,180,209, 99,128, 51, - 196,109,128, 51,157,228,233,225,231,239,238,225,236,227,242,239, - 243,243,232,225,244,227,232,230,233,236,108,128, 37,169,232,239, - 242,233,250,239,238,244,225,236,230,233,236,108,128, 37,164,107, - 2,181, 5,181, 9,103,128, 51,143,109,129, 51,158,181, 15,227, - 225,240,233,244,225,108,128, 51,206,108, 2,181, 31,181, 35,110, - 128, 51,209,239,103,128, 51,210,109, 4,181, 50,181, 54,181, 59, - 181, 63,103,128, 51,142,233,108,128, 51,213,109,128, 51,156,243, - 241,245,225,242,229,100,128, 51,161,239,242,244,232,239,231,239, - 238,225,236,227,242,239,243,243,232,225,244,227,232,230,233,236, - 108,128, 37,166,245,240,240,229,114, 2,181,110,181,133,236,229, - 230,244,244,239,236,239,247,229,242,242,233,231,232,244,230,233, - 236,108,128, 37,167,242,233,231,232,244,244,239,236,239,247,229, - 242,236,229,230,244,230,233,236,108,128, 37,168,246,229,242,244, - 233,227,225,236,230,233,236,108,128, 37,165,247,232,233,244,229, - 247,233,244,232,243,237,225,236,236,226,236,225,227,107,128, 37, - 163,242,243,241,245,225,242,101,128, 51,219,115, 2,181,209,182, - 123, 97, 4,181,219,181,229,181,236,181,247,226,229,238,231,225, - 236,105,128, 9,183,228,229,246, 97,128, 9, 55,231,245,234,225, - 242,225,244,105,128, 10,183,238,103, 8,182, 10,182, 24,182, 38, - 182, 52,182, 67,182, 81,182, 95,182,108,227,233,229,245,227,235, - 239,242,229,225,110,128, 49, 73,232,233,229,245,232,235,239,242, - 229,225,110,128, 49,133,233,229,245,238,231,235,239,242,229,225, - 110,128, 49,128,235,233,249,229,239,235,235,239,242,229,225,110, - 128, 49, 50,238,233,229,245,238,235,239,242,229,225,110,128, 49, - 101,240,233,229,245,240,235,239,242,229,225,110,128, 49, 67,243, - 233,239,243,235,239,242,229,225,110,128, 49, 70,244,233,235,229, - 245,244,235,239,242,229,225,110,128, 49, 56,245,240,229,242,233, - 239,114,128,246,242,116, 2,182,139,182,162,229,242,236,233,238, - 103,129, 0,163,182,150,237,239,238,239,243,240,225,227,101,128, - 255,225,242,239,235,101, 2,182,171,182,188,236,239,238,231,239, - 246,229,242,236,225,249,227,237, 98,128, 3, 54,243,232,239,242, - 244,239,246,229,242,236,225,249,227,237, 98,128, 3, 53,117, 7, - 182,222,182,254,183, 20,183, 31,183, 72,183, 82,183, 86,226,243, - 229,116,130, 34,130,182,233,182,244,238,239,244,229,241,245,225, - 108,128, 34,138,239,242,229,241,245,225,108,128, 34,134, 99, 2, - 183, 4,183, 12,227,229,229,228,115,128, 34,123,232,244,232,225, - 116,128, 34, 11,232,233,242,225,231,225,238, 97,128, 48, 89,107, - 2,183, 37,183, 61,225,244,225,235,225,238, 97,129, 48,185,183, - 49,232,225,236,230,247,233,228,244,104,128,255,125,245,238,225, - 242,225,226,233, 99,128, 6, 82,237,237,225,244,233,239,110,128, - 34, 17,110,128, 38, 60,240,229,242,243,229,116,130, 34,131,183, - 99,183,110,238,239,244,229,241,245,225,108,128, 34,139,239,242, - 229,241,245,225,108,128, 34,135,246,243,241,245,225,242,101,128, - 51,220,249,239,245,247,225,229,242,225,243,241,245,225,242,101, - 128, 51,124,116,144, 0,116,183,183,184,192,184,213,185,100,185, - 140,187,188,191, 70,192,145,192,157,192,169,193,202,193,227,194, - 57,194,237,195,165,195,255, 97, 10,183,205,183,215,183,236,183, - 243,184, 12,184, 90,184,107,184,132,184,146,184,150,226,229,238, - 231,225,236,105,128, 9,164,227,107, 2,183,222,183,229,228,239, - 247,110,128, 34,164,236,229,230,116,128, 34,163,228,229,246, 97, - 128, 9, 36,231,117, 2,183,250,184, 3,234,225,242,225,244,105, - 128, 10,164,242,237,245,235,232,105,128, 10, 36,104, 4,184, 22, - 184, 31,184, 45,184, 75,225,242,225,226,233, 99,128, 6, 55,230, - 233,238,225,236,225,242,225,226,233, 99,128,254,194,105, 2,184, - 51,184, 66,238,233,244,233,225,236,225,242,225,226,233, 99,128, - 254,195,242,225,231,225,238, 97,128, 48, 95,237,229,228,233,225, - 236,225,242,225,226,233, 99,128,254,196,233,243,249,239,245,229, - 242,225,243,241,245,225,242,101,128, 51,125,235,225,244,225,235, - 225,238, 97,129, 48,191,184,120,232,225,236,230,247,233,228,244, - 104,128,255,128,244,247,229,229,236,225,242,225,226,233, 99,128, - 6, 64,117,128, 3,196,118,130, 5,234,184,158,184,183,228,225, - 231,229,115,129,251, 74,184,168,104,129,251, 74,184,174,232,229, - 226,242,229,119,128,251, 74,232,229,226,242,229,119,128, 5,234, - 98, 2,184,198,184,203,225,114,128, 1,103,239,240,239,237,239, - 230,111,128, 49, 10, 99, 6,184,227,184,234,184,241,184,250,185, - 60,185, 87,225,242,239,110,128, 1,101,227,245,242,108,128, 2, - 168,229,228,233,236,236, 97,128, 1, 99,232,229,104, 4,185, 6, - 185, 15,185, 29,185, 45,225,242,225,226,233, 99,128, 6,134,230, - 233,238,225,236,225,242,225,226,233, 99,128,251,123,233,238,233, - 244,233,225,236,225,242,225,226,233, 99,128,251,124,237,229,228, - 233,225,236,225,242,225,226,233, 99,128,251,125,233,242, 99, 2, - 185, 68,185, 73,236,101,128, 36,227,245,237,230,236,229,248,226, - 229,236,239,119,128, 30,113,239,237,237,225,225,227,227,229,238, - 116,128, 1, 99,100, 2,185,106,185,116,233,229,242,229,243,233, - 115,128, 30,151,239,116, 2,185,123,185,132,225,227,227,229,238, - 116,128, 30,107,226,229,236,239,119,128, 30,109,101, 9,185,160, - 185,171,185,191,186,201,186,226,187, 34,187,101,187,106,187,158, - 227,249,242,233,236,236,233, 99,128, 4, 66,228,229,243,227,229, - 238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,173,104, - 7,185,207,185,216,185,230,186, 14,186, 44,186, 85,186,183,225, - 242,225,226,233, 99,128, 6, 42,230,233,238,225,236,225,242,225, - 226,233, 99,128,254,150,232,225,232,105, 2,185,239,185,254,238, - 233,244,233,225,236,225,242,225,226,233, 99,128,252,162,243,239, - 236,225,244,229,228,225,242,225,226,233, 99,128,252, 12,105, 2, - 186, 20,186, 35,238,233,244,233,225,236,225,242,225,226,233, 99, - 128,254,151,242,225,231,225,238, 97,128, 48,102,234,229,229,237, - 105, 2,186, 54,186, 69,238,233,244,233,225,236,225,242,225,226, - 233, 99,128,252,161,243,239,236,225,244,229,228,225,242,225,226, - 233, 99,128,252, 11,109, 2,186, 91,186,125,225,242,226,245,244, - 97, 2,186,102,186,111,225,242,225,226,233, 99,128, 6, 41,230, - 233,238,225,236,225,242,225,226,233, 99,128,254,148,101, 2,186, - 131,186,144,228,233,225,236,225,242,225,226,233, 99,128,254,152, - 229,237,105, 2,186,152,186,167,238,233,244,233,225,236,225,242, - 225,226,233, 99,128,252,164,243,239,236,225,244,229,228,225,242, - 225,226,233, 99,128,252, 14,238,239,239,238,230,233,238,225,236, - 225,242,225,226,233, 99,128,252,115,235,225,244,225,235,225,238, - 97,129, 48,198,186,214,232,225,236,230,247,233,228,244,104,128, - 255,131,108, 2,186,232,186,251,229,240,232,239,238,101,129, 33, - 33,186,243,226,236,225,227,107,128, 38, 14,233,243,232, 97, 2, - 187, 4,187, 19,231,229,228,239,236,225,232,229,226,242,229,119, - 128, 5,160,241,229,244,225,238,225,232,229,226,242,229,119,128, - 5,169,110, 4,187, 44,187, 53,187, 72,187, 93,227,233,242,227, - 236,101,128, 36,105,233,228,229,239,231,242,225,240,232,233,227, - 240,225,242,229,110,128, 50, 41,112, 2,187, 78,187, 85,225,242, - 229,110,128, 36,125,229,242,233,239,100,128, 36,145,242,239,237, - 225,110,128, 33,121,243,104,128, 2,167,116,131, 5,216,187,116, - 187,136,187,145,228,225,231,229,243,104,129,251, 56,187,127,232, - 229,226,242,229,119,128,251, 56,232,229,226,242,229,119,128, 5, - 216,243,229,227,249,242,233,236,236,233, 99,128, 4,181,246,233, - 114, 2,187,166,187,175,232,229,226,242,229,119,128, 5,155,236, - 229,230,244,232,229,226,242,229,119,128, 5,155,104, 6,187,202, - 188, 98,188,220,189, 96,190, 3,191, 60, 97, 5,187,214,187,224, - 187,231,188, 0,188, 29,226,229,238,231,225,236,105,128, 9,165, - 228,229,246, 97,128, 9, 37,231,117, 2,187,238,187,247,234,225, - 242,225,244,105,128, 10,165,242,237,245,235,232,105,128, 10, 37, - 108, 2,188, 6,188, 15,225,242,225,226,233, 99,128, 6, 48,230, - 233,238,225,236,225,242,225,226,233, 99,128,254,172,238,244,232, - 225,235,232,225,116, 3,188, 44,188, 75,188, 82,236,239,119, 2, - 188, 52,188, 63,236,229,230,244,244,232,225,105,128,248,152,242, - 233,231,232,244,244,232,225,105,128,248,151,244,232,225,105,128, - 14, 76,245,240,240,229,242,236,229,230,244,244,232,225,105,128, - 248,150,101, 3,188,106,188,170,188,193,104, 4,188,116,188,125, - 188,139,188,155,225,242,225,226,233, 99,128, 6, 43,230,233,238, - 225,236,225,242,225,226,233, 99,128,254,154,233,238,233,244,233, - 225,236,225,242,225,226,233, 99,128,254,155,237,229,228,233,225, - 236,225,242,225,226,233, 99,128,254,156,242,101, 2,188,177,188, - 186,229,248,233,243,244,115,128, 34, 3,230,239,242,101,128, 34, - 52,244, 97,130, 3,184,188,202,188,206, 49,128, 3,209,243,249, - 237,226,239,236,231,242,229,229,107,128, 3,209,105, 2,188,226, - 189, 56,229,245,244,104, 4,188,239,189, 18,189, 33,189, 42, 97, - 2,188,245,189, 4,227,233,242,227,236,229,235,239,242,229,225, - 110,128, 50,121,240,225,242,229,238,235,239,242,229,225,110,128, - 50, 25,227,233,242,227,236,229,235,239,242,229,225,110,128, 50, - 107,235,239,242,229,225,110,128, 49, 76,240,225,242,229,238,235, - 239,242,229,225,110,128, 50, 11,242,244,229,229,110, 2,189, 66, - 189, 75,227,233,242,227,236,101,128, 36,108,112, 2,189, 81,189, - 88,225,242,229,110,128, 36,128,229,242,233,239,100,128, 36,148, - 111, 6,189,110,189,127,189,132,189,146,189,151,189,204,238,225, - 238,231,237,239,238,244,232,239,244,232,225,105,128, 14, 17,239, - 107,128, 1,173,240,232,245,244,232,225,239,244,232,225,105,128, - 14, 18,242,110,128, 0,254,244,104, 3,189,160,189,184,189,194, - 97, 2,189,166,189,176,232,225,238,244,232,225,105,128, 14, 23, - 238,244,232,225,105,128, 14, 16,239,238,231,244,232,225,105,128, - 14, 24,245,238,231,244,232,225,105,128, 14, 22,245,243,225,238, - 100, 2,189,214,189,225,227,249,242,233,236,236,233, 99,128, 4, - 130,243,243,229,240,225,242,225,244,239,114, 2,189,240,189,249, - 225,242,225,226,233, 99,128, 6,108,240,229,242,243,233,225,110, - 128, 6,108,242,229,101,144, 0, 51,190, 41,190, 50,190, 60,190, - 90,190, 97,190,107,190,132,190,159,190,193,190,205,190,224,190, - 235,191, 12,191, 34,191, 42,191, 53,225,242,225,226,233, 99,128, - 6, 99,226,229,238,231,225,236,105,128, 9,233,227,233,242,227, - 236,101,129, 36, 98,190, 71,233,238,246,229,242,243,229,243,225, - 238,243,243,229,242,233,102,128, 39,140,228,229,246, 97,128, 9, - 105,229,233,231,232,244,232,115,128, 33, 92,231,117, 2,190,114, - 190,123,234,225,242,225,244,105,128, 10,233,242,237,245,235,232, - 105,128, 10,105,232, 97, 2,190,139,190,150,227,235,225,242,225, - 226,233, 99,128, 6, 99,238,231,250,232,239,117,128, 48, 35,105, - 2,190,165,190,183,228,229,239,231,242,225,240,232,233,227,240, - 225,242,229,110,128, 50, 34,238,230,229,242,233,239,114,128, 32, - 131,237,239,238,239,243,240,225,227,101,128,255, 19,238,245,237, - 229,242,225,244,239,242,226,229,238,231,225,236,105,128, 9,246, - 239,236,228,243,244,249,236,101,128,247, 51,112, 2,190,241,190, - 248,225,242,229,110,128, 36,118,229,114, 2,190,255,191, 5,233, - 239,100,128, 36,138,243,233,225,110,128, 6,243,241,245,225,242, - 244,229,242,115,129, 0,190,191, 25,229,237,228,225,243,104,128, - 246,222,242,239,237,225,110,128, 33,114,243,245,240,229,242,233, - 239,114,128, 0,179,244,232,225,105,128, 14, 83,250,243,241,245, - 225,242,101,128, 51,148,105, 7,191, 86,191, 97,191,212,192, 54, - 192, 66,192,115,192,132,232,233,242,225,231,225,238, 97,128, 48, - 97,107, 2,191,103,191,127,225,244,225,235,225,238, 97,129, 48, - 193,191,115,232,225,236,230,247,233,228,244,104,128,255,129,229, - 245,116, 4,191,139,191,174,191,189,191,198, 97, 2,191,145,191, - 160,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,112, - 240,225,242,229,238,235,239,242,229,225,110,128, 50, 16,227,233, - 242,227,236,229,235,239,242,229,225,110,128, 50, 98,235,239,242, - 229,225,110,128, 49, 55,240,225,242,229,238,235,239,242,229,225, - 110,128, 50, 2,236,228,101,133, 2,220,191,228,191,239,192, 0, - 192, 12,192, 40,226,229,236,239,247,227,237, 98,128, 3, 48, 99, - 2,191,245,191,250,237, 98,128, 3, 3,239,237, 98,128, 3, 3, - 228,239,245,226,236,229,227,237, 98,128, 3, 96,111, 2,192, 18, - 192, 28,240,229,242,225,244,239,114,128, 34, 60,246,229,242,236, - 225,249,227,237, 98,128, 3, 52,246,229,242,244,233,227,225,236, - 227,237, 98,128, 3, 62,237,229,243,227,233,242,227,236,101,128, - 34,151,112, 2,192, 72,192,102,229,232, 97, 2,192, 80,192, 89, - 232,229,226,242,229,119,128, 5,150,236,229,230,244,232,229,226, - 242,229,119,128, 5,150,240,233,231,245,242,237,245,235,232,105, - 128, 10,112,244,236,239,227,249,242,233,236,236,233,227,227,237, - 98,128, 4,131,247,238,225,242,237,229,238,233,225,110,128, 5, - 127,236,233,238,229,226,229,236,239,119,128, 30,111,237,239,238, - 239,243,240,225,227,101,128,255, 84,111, 7,192,185,192,196,192, - 207,192,232,193, 96,193,108,193,192,225,242,237,229,238,233,225, - 110,128, 5,105,232,233,242,225,231,225,238, 97,128, 48,104,235, - 225,244,225,235,225,238, 97,129, 48,200,192,220,232,225,236,230, - 247,233,228,244,104,128,255,132,110, 3,192,240,193, 82,193, 87, - 101, 4,192,250,193, 63,193, 70,193, 76,226,225,114, 4,193, 6, - 193, 35,193, 45,193, 54,229,248,244,242, 97, 2,193, 16,193, 26, - 232,233,231,232,237,239,100,128, 2,229,236,239,247,237,239,100, - 128, 2,233,232,233,231,232,237,239,100,128, 2,230,236,239,247, - 237,239,100,128, 2,232,237,233,228,237,239,100,128, 2,231,230, - 233,246,101,128, 1,189,243,233,120,128, 1,133,244,247,111,128, - 1,168,239,115,128, 3,132,243,241,245,225,242,101,128, 51, 39, - 240,225,244,225,235,244,232,225,105,128, 14, 15,242,244,239,233, - 243,229,243,232,229,236,236,226,242,225,227,235,229,116, 2,193, - 131,193,161,236,229,230,116,130, 48, 20,193,142,193,150,243,237, - 225,236,108,128,254, 93,246,229,242,244,233,227,225,108,128,254, - 57,242,233,231,232,116,130, 48, 21,193,173,193,181,243,237,225, - 236,108,128,254, 94,246,229,242,244,233,227,225,108,128,254, 58, - 244,225,239,244,232,225,105,128, 14, 21,240, 97, 2,193,209,193, - 221,236,225,244,225,236,232,239,239,107,128, 1,171,242,229,110, - 128, 36,175,114, 3,193,235,194, 10,194, 25,225,228,229,237,225, - 242,107,129, 33, 34,193,247,115, 2,193,253,194, 3,225,238,115, - 128,248,234,229,242,233,102,128,246,219,229,244,242,239,230,236, - 229,248,232,239,239,107,128, 2,136,233,225,103, 4,194, 37,194, - 42,194, 47,194, 52,228,110,128, 37,188,236,102,128, 37,196,242, - 116,128, 37,186,245,112,128, 37,178,115,132, 2,166,194, 69,194, - 108,194,214,194,227,225,228,105,130, 5,230,194, 79,194, 99,228, - 225,231,229,243,104,129,251, 70,194, 90,232,229,226,242,229,119, - 128,251, 70,232,229,226,242,229,119,128, 5,230,101, 2,194,114, - 194,125,227,249,242,233,236,236,233, 99,128, 4, 70,242,101,134, - 5,181,194,142,194,156,194,161,194,170,194,185,194,201, 49, 2, - 194,148,194,152, 50,128, 5,181,101,128, 5,181,178, 98,128, 5, - 181,232,229,226,242,229,119,128, 5,181,238,225,242,242,239,247, - 232,229,226,242,229,119,128, 5,181,241,245,225,242,244,229,242, - 232,229,226,242,229,119,128, 5,181,247,233,228,229,232,229,226, - 242,229,119,128, 5,181,232,229,227,249,242,233,236,236,233, 99, - 128, 4, 91,245,240,229,242,233,239,114,128,246,243,116, 4,194, - 247,195, 41,195,106,195,157, 97, 3,194,255,195, 9,195, 16,226, - 229,238,231,225,236,105,128, 9,159,228,229,246, 97,128, 9, 31, - 231,117, 2,195, 23,195, 32,234,225,242,225,244,105,128, 10,159, - 242,237,245,235,232,105,128, 10, 31,229,104, 4,195, 52,195, 61, - 195, 75,195, 91,225,242,225,226,233, 99,128, 6,121,230,233,238, - 225,236,225,242,225,226,233, 99,128,251,103,233,238,233,244,233, - 225,236,225,242,225,226,233, 99,128,251,104,237,229,228,233,225, - 236,225,242,225,226,233, 99,128,251,105,232, 97, 3,195,115,195, - 125,195,132,226,229,238,231,225,236,105,128, 9,160,228,229,246, - 97,128, 9, 32,231,117, 2,195,139,195,148,234,225,242,225,244, - 105,128, 10,160,242,237,245,235,232,105,128, 10, 32,245,242,238, - 229,100,128, 2,135,117, 3,195,173,195,184,195,209,232,233,242, - 225,231,225,238, 97,128, 48,100,235,225,244,225,235,225,238, 97, - 129, 48,196,195,197,232,225,236,230,247,233,228,244,104,128,255, - 130,243,237,225,236,108, 2,195,219,195,230,232,233,242,225,231, - 225,238, 97,128, 48, 99,235,225,244,225,235,225,238, 97,129, 48, - 195,195,243,232,225,236,230,247,233,228,244,104,128,255,111,119, - 2,196, 5,196,110,101, 2,196, 11,196, 59,236,246,101, 3,196, - 21,196, 30,196, 51,227,233,242,227,236,101,128, 36,107,112, 2, - 196, 36,196, 43,225,242,229,110,128, 36,127,229,242,233,239,100, - 128, 36,147,242,239,237,225,110,128, 33,123,238,244,121, 3,196, - 69,196, 78,196, 89,227,233,242,227,236,101,128, 36,115,232,225, - 238,231,250,232,239,117,128, 83, 68,112, 2,196, 95,196,102,225, - 242,229,110,128, 36,135,229,242,233,239,100,128, 36,155,111,142, - 0, 50,196,142,196,151,196,161,196,191,196,243,197, 12,197, 39, - 197, 73,197, 85,197,104,197,115,197,148,197,156,197,180,225,242, - 225,226,233, 99,128, 6, 98,226,229,238,231,225,236,105,128, 9, - 232,227,233,242,227,236,101,129, 36, 97,196,172,233,238,246,229, - 242,243,229,243,225,238,243,243,229,242,233,102,128, 39,139,100, - 2,196,197,196,203,229,246, 97,128, 9,104,239,116, 2,196,210, - 196,221,229,238,236,229,225,228,229,114,128, 32, 37,236,229,225, - 228,229,114,129, 32, 37,196,232,246,229,242,244,233,227,225,108, - 128,254, 48,231,117, 2,196,250,197, 3,234,225,242,225,244,105, - 128, 10,232,242,237,245,235,232,105,128, 10,104,232, 97, 2,197, - 19,197, 30,227,235,225,242,225,226,233, 99,128, 6, 98,238,231, - 250,232,239,117,128, 48, 34,105, 2,197, 45,197, 63,228,229,239, - 231,242,225,240,232,233,227,240,225,242,229,110,128, 50, 33,238, - 230,229,242,233,239,114,128, 32,130,237,239,238,239,243,240,225, - 227,101,128,255, 18,238,245,237,229,242,225,244,239,242,226,229, - 238,231,225,236,105,128, 9,245,239,236,228,243,244,249,236,101, - 128,247, 50,112, 2,197,121,197,128,225,242,229,110,128, 36,117, - 229,114, 2,197,135,197,141,233,239,100,128, 36,137,243,233,225, - 110,128, 6,242,242,239,237,225,110,128, 33,113,115, 2,197,162, - 197,170,244,242,239,235,101,128, 1,187,245,240,229,242,233,239, - 114,128, 0,178,244,104, 2,197,187,197,192,225,105,128, 14, 82, - 233,242,228,115,128, 33, 84,117,145, 0,117,197,237,197,245,198, - 30,198, 87,198,225,199, 6,199,129,199,145,199,196,200, 10,200, - 91,200,100,200,219,200,243,201, 95,201,123,201,237,225,227,245, - 244,101,128, 0,250, 98, 4,197,255,198, 4,198, 13,198, 23,225, - 114,128, 2,137,229,238,231,225,236,105,128, 9,137,239,240,239, - 237,239,230,111,128, 49, 40,242,229,246,101,128, 1,109, 99, 3, - 198, 38,198, 45,198, 77,225,242,239,110,128, 1,212,233,242, 99, - 2,198, 53,198, 58,236,101,128, 36,228,245,237,230,236,229,120, - 129, 0,251,198, 69,226,229,236,239,119,128, 30,119,249,242,233, - 236,236,233, 99,128, 4, 67,100, 5,198, 99,198,110,198,133,198, - 139,198,215,225,244,244,225,228,229,246, 97,128, 9, 81,226,108, - 2,198,117,198,125,225,227,245,244,101,128, 1,113,231,242,225, - 246,101,128, 2, 21,229,246, 97,128, 9, 9,233,229,242,229,243, - 233,115,133, 0,252,198,159,198,167,198,175,198,198,198,206,225, - 227,245,244,101,128, 1,216,226,229,236,239,119,128, 30,115, 99, - 2,198,181,198,188,225,242,239,110,128, 1,218,249,242,233,236, - 236,233, 99,128, 4,241,231,242,225,246,101,128, 1,220,237,225, - 227,242,239,110,128, 1,214,239,244,226,229,236,239,119,128, 30, - 229,103, 2,198,231,198,238,242,225,246,101,128, 0,249,117, 2, - 198,244,198,253,234,225,242,225,244,105,128, 10,137,242,237,245, - 235,232,105,128, 10, 9,104, 3,199, 14,199, 24,199,102,233,242, - 225,231,225,238, 97,128, 48, 70,111, 2,199, 30,199, 40,239,235, - 225,226,239,246,101,128, 30,231,242,110,133, 1,176,199, 55,199, - 63,199, 74,199, 82,199, 94,225,227,245,244,101,128, 30,233,228, - 239,244,226,229,236,239,119,128, 30,241,231,242,225,246,101,128, - 30,235,232,239,239,235,225,226,239,246,101,128, 30,237,244,233, - 236,228,101,128, 30,239,245,238,231,225,242,245,237,236,225,245, - 116,129, 1,113,199,118,227,249,242,233,236,236,233, 99,128, 4, - 243,233,238,246,229,242,244,229,228,226,242,229,246,101,128, 2, - 23,107, 3,199,153,199,177,199,188,225,244,225,235,225,238, 97, - 129, 48,166,199,165,232,225,236,230,247,233,228,244,104,128,255, - 115,227,249,242,233,236,236,233, 99,128, 4,121,239,242,229,225, - 110,128, 49, 92,109, 2,199,202,199,255, 97, 2,199,208,199,241, - 227,242,239,110,130, 1,107,199,219,199,230,227,249,242,233,236, - 236,233, 99,128, 4,239,228,233,229,242,229,243,233,115,128, 30, - 123,244,242,225,231,245,242,237,245,235,232,105,128, 10, 65,239, - 238,239,243,240,225,227,101,128,255, 85,110, 2,200, 16,200, 71, - 228,229,242,243,227,239,242,101,132, 0, 95,200, 35,200, 41,200, - 53,200, 64,228,226,108,128, 32, 23,237,239,238,239,243,240,225, - 227,101,128,255, 63,246,229,242,244,233,227,225,108,128,254, 51, - 247,225,246,121,128,254, 79,105, 2,200, 77,200, 82,239,110,128, - 34, 42,246,229,242,243,225,108,128, 34, 0,239,231,239,238,229, - 107,128, 1,115,112, 5,200,112,200,119,200,127,200,142,200,193, - 225,242,229,110,128, 36,176,226,236,239,227,107,128, 37,128,240, - 229,242,228,239,244,232,229,226,242,229,119,128, 5,196,243,233, - 236,239,110,131, 3,197,200,156,200,177,200,185,228,233,229,242, - 229,243,233,115,129, 3,203,200,169,244,239,238,239,115,128, 3, - 176,236,225,244,233,110,128, 2,138,244,239,238,239,115,128, 3, - 205,244,225,227,107, 2,200,202,200,213,226,229,236,239,247,227, - 237, 98,128, 3, 29,237,239,100,128, 2,212,114, 2,200,225,200, - 237,225,231,245,242,237,245,235,232,105,128, 10,115,233,238,103, - 128, 1,111,115, 3,200,251,201, 10,201, 55,232,239,242,244,227, - 249,242,233,236,236,233, 99,128, 4, 94,237,225,236,108, 2,201, - 19,201, 30,232,233,242,225,231,225,238, 97,128, 48, 69,235,225, - 244,225,235,225,238, 97,129, 48,165,201, 43,232,225,236,230,247, - 233,228,244,104,128,255,105,244,242,225,233,231,232,116, 2,201, - 67,201, 78,227,249,242,233,236,236,233, 99,128, 4,175,243,244, - 242,239,235,229,227,249,242,233,236,236,233, 99,128, 4,177,244, - 233,236,228,101,130, 1,105,201,107,201,115,225,227,245,244,101, - 128, 30,121,226,229,236,239,119,128, 30,117,117, 5,201,135,201, - 145,201,152,201,177,201,193,226,229,238,231,225,236,105,128, 9, - 138,228,229,246, 97,128, 9, 10,231,117, 2,201,159,201,168,234, - 225,242,225,244,105,128, 10,138,242,237,245,235,232,105,128, 10, - 10,237,225,244,242,225,231,245,242,237,245,235,232,105,128, 10, - 66,246,239,247,229,236,243,233,231,110, 3,201,209,201,219,201, - 226,226,229,238,231,225,236,105,128, 9,194,228,229,246, 97,128, - 9, 66,231,245,234,225,242,225,244,105,128, 10,194,246,239,247, - 229,236,243,233,231,110, 3,201,253,202, 7,202, 14,226,229,238, - 231,225,236,105,128, 9,193,228,229,246, 97,128, 9, 65,231,245, - 234,225,242,225,244,105,128, 10,193,118,139, 0,118,202, 51,202, - 199,202,208,202,219,203,148,203,155,203,253,204, 9,204,109,204, - 117,204,138, 97, 4,202, 61,202, 68,202, 93,202,104,228,229,246, - 97,128, 9, 53,231,117, 2,202, 75,202, 84,234,225,242,225,244, - 105,128, 10,181,242,237,245,235,232,105,128, 10, 53,235,225,244, - 225,235,225,238, 97,128, 48,247,118,132, 5,213,202,116,202,143, - 202,175,202,187,228,225,231,229,243,104,130,251, 53,202,129,202, - 134,182, 53,128,251, 53,232,229,226,242,229,119,128,251, 53,104, - 2,202,149,202,157,229,226,242,229,119,128, 5,213,239,236,225, - 109,129,251, 75,202,166,232,229,226,242,229,119,128,251, 75,246, - 225,246,232,229,226,242,229,119,128, 5,240,249,239,228,232,229, - 226,242,229,119,128, 5,241,227,233,242,227,236,101,128, 36,229, - 228,239,244,226,229,236,239,119,128, 30,127,101, 6,202,233,202, - 244,203, 52,203, 63,203, 69,203,136,227,249,242,233,236,236,233, - 99,128, 4, 50,104, 4,202,254,203, 7,203, 21,203, 37,225,242, - 225,226,233, 99,128, 6,164,230,233,238,225,236,225,242,225,226, - 233, 99,128,251,107,233,238,233,244,233,225,236,225,242,225,226, - 233, 99,128,251,108,237,229,228,233,225,236,225,242,225,226,233, - 99,128,251,109,235,225,244,225,235,225,238, 97,128, 48,249,238, - 245,115,128, 38, 64,242,244,233,227,225,108, 2,203, 80,203, 86, - 226,225,114,128, 0,124,236,233,238,101, 4,203, 99,203,110,203, - 121,203,130,225,226,239,246,229,227,237, 98,128, 3, 13,226,229, - 236,239,247,227,237, 98,128, 3, 41,236,239,247,237,239,100,128, - 2,204,237,239,100,128, 2,200,247,225,242,237,229,238,233,225, - 110,128, 5,126,232,239,239,107,128, 2,139,105, 3,203,163,203, - 174,203,213,235,225,244,225,235,225,238, 97,128, 48,248,242,225, - 237, 97, 3,203,185,203,195,203,202,226,229,238,231,225,236,105, - 128, 9,205,228,229,246, 97,128, 9, 77,231,245,234,225,242,225, - 244,105,128, 10,205,243,225,242,231, 97, 3,203,225,203,235,203, - 242,226,229,238,231,225,236,105,128, 9,131,228,229,246, 97,128, - 9, 3,231,245,234,225,242,225,244,105,128, 10,131,237,239,238, - 239,243,240,225,227,101,128,255, 86,111, 3,204, 17,204, 28,204, - 98,225,242,237,229,238,233,225,110,128, 5,120,233,227,229,100, - 2,204, 37,204, 73,233,244,229,242,225,244,233,239,110, 2,204, - 51,204, 62,232,233,242,225,231,225,238, 97,128, 48,158,235,225, - 244,225,235,225,238, 97,128, 48,254,237,225,242,235,235,225,238, - 97,129, 48,155,204, 86,232,225,236,230,247,233,228,244,104,128, - 255,158,235,225,244,225,235,225,238, 97,128, 48,250,240,225,242, - 229,110,128, 36,177,116, 2,204,123,204,130,233,236,228,101,128, - 30,125,245,242,238,229,100,128, 2,140,117, 2,204,144,204,155, - 232,233,242,225,231,225,238, 97,128, 48,148,235,225,244,225,235, - 225,238, 97,128, 48,244,119,143, 0,119,204,200,205,177,205,187, - 205,210,205,250,206, 61,206, 69,208, 40,208, 81,208, 93,208,168, - 208,176,208,183,208,194,208,203, 97, 8,204,218,204,225,204,235, - 204,246,205, 28,205, 60,205, 72,205,108,227,245,244,101,128, 30, - 131,229,235,239,242,229,225,110,128, 49, 89,232,233,242,225,231, - 225,238, 97,128, 48,143,107, 2,204,252,205, 20,225,244,225,235, - 225,238, 97,129, 48,239,205, 8,232,225,236,230,247,233,228,244, - 104,128,255,156,239,242,229,225,110,128, 49, 88,243,237,225,236, - 108, 2,205, 38,205, 49,232,233,242,225,231,225,238, 97,128, 48, - 142,235,225,244,225,235,225,238, 97,128, 48,238,244,244,239,243, - 241,245,225,242,101,128, 51, 87,118, 2,205, 78,205, 86,229,228, - 225,243,104,128, 48, 28,249,245,238,228,229,242,243,227,239,242, - 229,246,229,242,244,233,227,225,108,128,254, 52,119, 3,205,116, - 205,125,205,139,225,242,225,226,233, 99,128, 6, 72,230,233,238, - 225,236,225,242,225,226,233, 99,128,254,238,232,225,237,250,225, - 225,226,239,246,101, 2,205,154,205,163,225,242,225,226,233, 99, - 128, 6, 36,230,233,238,225,236,225,242,225,226,233, 99,128,254, - 134,226,243,241,245,225,242,101,128, 51,221,227,233,242, 99, 2, - 205,196,205,201,236,101,128, 36,230,245,237,230,236,229,120,128, - 1,117,100, 2,205,216,205,226,233,229,242,229,243,233,115,128, - 30,133,239,116, 2,205,233,205,242,225,227,227,229,238,116,128, - 30,135,226,229,236,239,119,128, 30,137,101, 4,206, 4,206, 15, - 206, 27,206, 51,232,233,242,225,231,225,238, 97,128, 48,145,233, - 229,242,243,244,242,225,243,115,128, 33, 24,107, 2,206, 33,206, - 43,225,244,225,235,225,238, 97,128, 48,241,239,242,229,225,110, - 128, 49, 94,239,235,239,242,229,225,110,128, 49, 93,231,242,225, - 246,101,128, 30,129,232,233,244,101, 8,206, 90,206, 99,206,183, - 207, 17,207,101,207,146,207,198,207,254,226,245,236,236,229,116, - 128, 37,230, 99, 2,206,105,206,125,233,242,227,236,101,129, 37, - 203,206,115,233,238,246,229,242,243,101,128, 37,217,239,242,238, - 229,242,226,242,225,227,235,229,116, 2,206,142,206,162,236,229, - 230,116,129, 48, 14,206,151,246,229,242,244,233,227,225,108,128, - 254, 67,242,233,231,232,116,129, 48, 15,206,172,246,229,242,244, - 233,227,225,108,128,254, 68,100, 2,206,189,206,230,233,225,237, - 239,238,100,129, 37,199,206,200,227,239,238,244,225,233,238,233, - 238,231,226,236,225,227,235,243,237,225,236,236,228,233,225,237, - 239,238,100,128, 37,200,239,247,238,240,239,233,238,244,233,238, - 103, 2,206,246,207, 6,243,237,225,236,236,244,242,233,225,238, - 231,236,101,128, 37,191,244,242,233,225,238,231,236,101,128, 37, - 189,236,101, 2,207, 24,207, 66,230,244,240,239,233,238,244,233, - 238,103, 2,207, 39,207, 55,243,237,225,236,236,244,242,233,225, - 238,231,236,101,128, 37,195,244,242,233,225,238,231,236,101,128, - 37,193,238,244,233,227,245,236,225,242,226,242,225,227,235,229, - 116, 2,207, 86,207, 93,236,229,230,116,128, 48, 22,242,233,231, - 232,116,128, 48, 23,242,233,231,232,244,240,239,233,238,244,233, - 238,103, 2,207,119,207,135,243,237,225,236,236,244,242,233,225, - 238,231,236,101,128, 37,185,244,242,233,225,238,231,236,101,128, - 37,183,115, 3,207,154,207,184,207,192,109, 2,207,160,207,172, - 225,236,236,243,241,245,225,242,101,128, 37,171,233,236,233,238, - 231,230,225,227,101,128, 38, 58,241,245,225,242,101,128, 37,161, - 244,225,114,128, 38, 6,116, 2,207,204,207,215,229,236,229,240, - 232,239,238,101,128, 38, 15,239,242,244,239,233,243,229,243,232, - 229,236,236,226,242,225,227,235,229,116, 2,207,239,207,246,236, - 229,230,116,128, 48, 24,242,233,231,232,116,128, 48, 25,245,240, - 240,239,233,238,244,233,238,103, 2,208, 13,208, 29,243,237,225, - 236,236,244,242,233,225,238,231,236,101,128, 37,181,244,242,233, - 225,238,231,236,101,128, 37,179,105, 2,208, 46,208, 57,232,233, - 242,225,231,225,238, 97,128, 48,144,107, 2,208, 63,208, 73,225, - 244,225,235,225,238, 97,128, 48,240,239,242,229,225,110,128, 49, - 95,237,239,238,239,243,240,225,227,101,128,255, 87,111, 4,208, - 103,208,114,208,139,208,157,232,233,242,225,231,225,238, 97,128, - 48,146,235,225,244,225,235,225,238, 97,129, 48,242,208,127,232, - 225,236,230,247,233,228,244,104,128,255,102,110,129, 32,169,208, - 145,237,239,238,239,243,240,225,227,101,128,255,230,247,225,229, - 238,244,232,225,105,128, 14, 39,240,225,242,229,110,128, 36,178, - 242,233,238,103,128, 30,152,243,245,240,229,242,233,239,114,128, - 2,183,244,245,242,238,229,100,128, 2,141,249,238,110,128, 1, - 191,120,137, 0,120,208,231,208,242,208,253,209, 6,209, 33,209, - 46,209, 50,209, 62,209, 70,225,226,239,246,229,227,237, 98,128, - 3, 61,226,239,240,239,237,239,230,111,128, 49, 18,227,233,242, - 227,236,101,128, 36,231,100, 2,209, 12,209, 22,233,229,242,229, - 243,233,115,128, 30,141,239,244,225,227,227,229,238,116,128, 30, - 139,229,232,225,242,237,229,238,233,225,110,128, 5,109,105,128, - 3,190,237,239,238,239,243,240,225,227,101,128,255, 88,240,225, - 242,229,110,128, 36,179,243,245,240,229,242,233,239,114,128, 2, - 227,121,143, 0,121,209,115,210, 74,210, 97,210,137,212,103,212, - 111,212,128,212,192,212,204,213,201,213,241,213,253,214, 8,214, - 29,215, 2, 97, 11,209,139,209,151,209,161,209,168,209,175,209, - 185,209,210,209,221,210, 3,210, 16,210, 62,225,228,239,243,241, - 245,225,242,101,128, 51, 78,226,229,238,231,225,236,105,128, 9, - 175,227,245,244,101,128, 0,253,228,229,246, 97,128, 9, 47,229, - 235,239,242,229,225,110,128, 49, 82,231,117, 2,209,192,209,201, - 234,225,242,225,244,105,128, 10,175,242,237,245,235,232,105,128, - 10, 47,232,233,242,225,231,225,238, 97,128, 48,132,107, 2,209, - 227,209,251,225,244,225,235,225,238, 97,129, 48,228,209,239,232, - 225,236,230,247,233,228,244,104,128,255,148,239,242,229,225,110, - 128, 49, 81,237,225,235,235,225,238,244,232,225,105,128, 14, 78, - 243,237,225,236,108, 2,210, 26,210, 37,232,233,242,225,231,225, - 238, 97,128, 48,131,235,225,244,225,235,225,238, 97,129, 48,227, - 210, 50,232,225,236,230,247,233,228,244,104,128,255,108,244,227, - 249,242,233,236,236,233, 99,128, 4, 99,227,233,242, 99, 2,210, - 83,210, 88,236,101,128, 36,232,245,237,230,236,229,120,128, 1, - 119,100, 2,210,103,210,113,233,229,242,229,243,233,115,128, 0, - 255,239,116, 2,210,120,210,129,225,227,227,229,238,116,128, 30, - 143,226,229,236,239,119,128, 30,245,101, 7,210,153,211,161,211, - 170,211,188,211,220,212, 40,212, 91,104, 8,210,171,210,180,210, - 214,210,228,211, 45,211, 61,211,120,211,138,225,242,225,226,233, - 99,128, 6, 74,226,225,242,242,229,101, 2,210,191,210,200,225, - 242,225,226,233, 99,128, 6,210,230,233,238,225,236,225,242,225, - 226,233, 99,128,251,175,230,233,238,225,236,225,242,225,226,233, - 99,128,254,242,232,225,237,250,225,225,226,239,246,101, 4,210, - 247,211, 0,211, 14,211, 30,225,242,225,226,233, 99,128, 6, 38, - 230,233,238,225,236,225,242,225,226,233, 99,128,254,138,233,238, - 233,244,233,225,236,225,242,225,226,233, 99,128,254,139,237,229, - 228,233,225,236,225,242,225,226,233, 99,128,254,140,233,238,233, - 244,233,225,236,225,242,225,226,233, 99,128,254,243,237,101, 2, - 211, 68,211, 81,228,233,225,236,225,242,225,226,233, 99,128,254, - 244,229,237,105, 2,211, 89,211,104,238,233,244,233,225,236,225, - 242,225,226,233, 99,128,252,221,243,239,236,225,244,229,228,225, - 242,225,226,233, 99,128,252, 88,238,239,239,238,230,233,238,225, - 236,225,242,225,226,233, 99,128,252,148,244,232,242,229,229,228, - 239,244,243,226,229,236,239,247,225,242,225,226,233, 99,128, 6, - 209,235,239,242,229,225,110,128, 49, 86,110,129, 0,165,211,176, - 237,239,238,239,243,240,225,227,101,128,255,229,111, 2,211,194, - 211,203,235,239,242,229,225,110,128, 49, 85,242,233,238,232,233, - 229,245,232,235,239,242,229,225,110,128, 49,134,114, 3,211,228, - 212, 8,212, 20,225,232,226,229,238,249,239,237,111, 2,211,242, - 211,251,232,229,226,242,229,119,128, 5,170,236,229,230,244,232, - 229,226,242,229,119,128, 5,170,233,227,249,242,233,236,236,233, - 99,128, 4, 75,245,228,233,229,242,229,243,233,243,227,249,242, - 233,236,236,233, 99,128, 4,249,243,233,229,245,238,103, 3,212, - 53,212, 62,212, 78,235,239,242,229,225,110,128, 49,129,240,225, - 238,243,233,239,243,235,239,242,229,225,110,128, 49,131,243,233, - 239,243,235,239,242,229,225,110,128, 49,130,244,233,246,232,229, - 226,242,229,119,128, 5,154,231,242,225,246,101,128, 30,243,232, - 239,239,107,129, 1,180,212,120,225,226,239,246,101,128, 30,247, - 105, 5,212,140,212,151,212,162,212,171,212,179,225,242,237,229, - 238,233,225,110,128, 5,117,227,249,242,233,236,236,233, 99,128, - 4, 87,235,239,242,229,225,110,128, 49, 98,238,249,225,238,103, - 128, 38, 47,247,238,225,242,237,229,238,233,225,110,128, 5,130, - 237,239,238,239,243,240,225,227,101,128,255, 89,111, 7,212,220, - 213, 34,213, 45,213, 55,213, 93,213,139,213,148,100,131, 5,217, - 212,230,212,250,213, 3,228,225,231,229,243,104,129,251, 57,212, - 241,232,229,226,242,229,119,128,251, 57,232,229,226,242,229,119, - 128, 5,217,249,239,100, 2,213, 11,213, 20,232,229,226,242,229, - 119,128, 5,242,240,225,244,225,232,232,229,226,242,229,119,128, - 251, 31,232,233,242,225,231,225,238, 97,128, 48,136,233,235,239, - 242,229,225,110,128, 49,137,107, 2,213, 61,213, 85,225,244,225, - 235,225,238, 97,129, 48,232,213, 73,232,225,236,230,247,233,228, - 244,104,128,255,150,239,242,229,225,110,128, 49, 91,243,237,225, - 236,108, 2,213,103,213,114,232,233,242,225,231,225,238, 97,128, - 48,135,235,225,244,225,235,225,238, 97,129, 48,231,213,127,232, - 225,236,230,247,233,228,244,104,128,255,110,244,231,242,229,229, - 107,128, 3,243,121, 2,213,154,213,191, 97, 2,213,160,213,170, - 229,235,239,242,229,225,110,128, 49,136,107, 2,213,176,213,184, - 239,242,229,225,110,128, 49,135,244,232,225,105,128, 14, 34,233, - 238,231,244,232,225,105,128, 14, 13,112, 2,213,207,213,214,225, - 242,229,110,128, 36,180,239,231,229,231,242,225,237,237,229,238, - 105,129, 3,122,213,230,231,242,229,229,235,227,237, 98,128, 3, - 69,114,129, 1,166,213,247,233,238,103,128, 30,153,243,245,240, - 229,242,233,239,114,128, 2,184,116, 2,214, 14,214, 21,233,236, - 228,101,128, 30,249,245,242,238,229,100,128, 2,142,117, 5,214, - 41,214, 52,214, 62,214,100,214,232,232,233,242,225,231,225,238, - 97,128, 48,134,233,235,239,242,229,225,110,128, 49,140,107, 2, - 214, 68,214, 92,225,244,225,235,225,238, 97,129, 48,230,214, 80, - 232,225,236,230,247,233,228,244,104,128,255,149,239,242,229,225, - 110,128, 49, 96,115, 3,214,108,214,146,214,187,226,233,103, 2, - 214,116,214,127,227,249,242,233,236,236,233, 99,128, 4,107,233, - 239,244,233,230,233,229,228,227,249,242,233,236,236,233, 99,128, - 4,109,236,233,244,244,236,101, 2,214,157,214,168,227,249,242, - 233,236,236,233, 99,128, 4,103,233,239,244,233,230,233,229,228, - 227,249,242,233,236,236,233, 99,128, 4,105,237,225,236,108, 2, - 214,196,214,207,232,233,242,225,231,225,238, 97,128, 48,133,235, - 225,244,225,235,225,238, 97,129, 48,229,214,220,232,225,236,230, - 247,233,228,244,104,128,255,109,249,101, 2,214,239,214,248,235, - 239,242,229,225,110,128, 49,139,239,235,239,242,229,225,110,128, - 49,138,249, 97, 2,215, 9,215, 19,226,229,238,231,225,236,105, - 128, 9,223,228,229,246, 97,128, 9, 95,122,142, 0,122,215, 58, - 216, 66,216, 77,216,120,216,147,217,182,218, 34,218, 76,218, 88, - 218,100,218,128,218,136,218,152,218,161, 97, 10,215, 80,215, 91, - 215, 98,215,105,215,116,215,194,215,224,215,235,216, 15,216, 27, - 225,242,237,229,238,233,225,110,128, 5,102,227,245,244,101,128, - 1,122,228,229,246, 97,128, 9, 91,231,245,242,237,245,235,232, - 105,128, 10, 91,104, 4,215,126,215,135,215,149,215,179,225,242, - 225,226,233, 99,128, 6, 56,230,233,238,225,236,225,242,225,226, - 233, 99,128,254,198,105, 2,215,155,215,170,238,233,244,233,225, - 236,225,242,225,226,233, 99,128,254,199,242,225,231,225,238, 97, - 128, 48, 86,237,229,228,233,225,236,225,242,225,226,233, 99,128, - 254,200,233,110, 2,215,201,215,210,225,242,225,226,233, 99,128, - 6, 50,230,233,238,225,236,225,242,225,226,233, 99,128,254,176, - 235,225,244,225,235,225,238, 97,128, 48,182,241,229,102, 2,215, - 243,216, 1,231,225,228,239,236,232,229,226,242,229,119,128, 5, - 149,241,225,244,225,238,232,229,226,242,229,119,128, 5,148,242, - 241,225,232,229,226,242,229,119,128, 5,152,249,233,110,130, 5, - 214,216, 37,216, 57,228,225,231,229,243,104,129,251, 54,216, 48, - 232,229,226,242,229,119,128,251, 54,232,229,226,242,229,119,128, - 5,214,226,239,240,239,237,239,230,111,128, 49, 23, 99, 3,216, - 85,216, 92,216,114,225,242,239,110,128, 1,126,233,242, 99, 2, - 216,100,216,105,236,101,128, 36,233,245,237,230,236,229,120,128, - 30,145,245,242,108,128, 2,145,228,239,116,130, 1,124,216,130, - 216,139,225,227,227,229,238,116,128, 1,124,226,229,236,239,119, - 128, 30,147,101, 6,216,161,216,172,216,215,216,226,216,237,217, - 177,227,249,242,233,236,236,233, 99,128, 4, 55,100, 2,216,178, - 216,197,229,243,227,229,238,228,229,242,227,249,242,233,236,236, - 233, 99,128, 4,153,233,229,242,229,243,233,243,227,249,242,233, - 236,236,233, 99,128, 4,223,232,233,242,225,231,225,238, 97,128, - 48, 92,235,225,244,225,235,225,238, 97,128, 48,188,242,111,140, - 0, 48,217, 10,217, 19,217, 29,217, 36,217, 61,217, 74,217, 85, - 217, 97,217,108,217,118,217,129,217,136,225,242,225,226,233, 99, - 128, 6, 96,226,229,238,231,225,236,105,128, 9,230,228,229,246, - 97,128, 9,102,231,117, 2,217, 43,217, 52,234,225,242,225,244, - 105,128, 10,230,242,237,245,235,232,105,128, 10,102,232,225,227, - 235,225,242,225,226,233, 99,128, 6, 96,233,238,230,229,242,233, - 239,114,128, 32,128,237,239,238,239,243,240,225,227,101,128,255, - 16,239,236,228,243,244,249,236,101,128,247, 48,240,229,242,243, - 233,225,110,128, 6,240,243,245,240,229,242,233,239,114,128, 32, - 112,244,232,225,105,128, 14, 80,247,233,228,244,104, 3,217,148, - 217,157,217,169,234,239,233,238,229,114,128,254,255,238,239,238, - 234,239,233,238,229,114,128, 32, 12,243,240,225,227,101,128, 32, - 11,244, 97,128, 3,182,104, 2,217,188,217,199,226,239,240,239, - 237,239,230,111,128, 49, 19,101, 4,217,209,217,220,217,236,217, - 247,225,242,237,229,238,233,225,110,128, 5,106,226,242,229,246, - 229,227,249,242,233,236,236,233, 99,128, 4,194,227,249,242,233, - 236,236,233, 99,128, 4, 54,100, 2,217,253,218, 16,229,243,227, - 229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,151, - 233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99,128, - 4,221,105, 3,218, 42,218, 53,218, 64,232,233,242,225,231,225, - 238, 97,128, 48, 88,235,225,244,225,235,225,238, 97,128, 48,184, - 238,239,242,232,229,226,242,229,119,128, 5,174,236,233,238,229, - 226,229,236,239,119,128, 30,149,237,239,238,239,243,240,225,227, - 101,128,255, 90,111, 2,218,106,218,117,232,233,242,225,231,225, - 238, 97,128, 48, 94,235,225,244,225,235,225,238, 97,128, 48,190, - 240,225,242,229,110,128, 36,181,242,229,244,242,239,230,236,229, - 248,232,239,239,107,128, 2,144,243,244,242,239,235,101,128, 1, - 182,117, 2,218,167,218,178,232,233,242,225,231,225,238, 97,128, - 48, 90,235,225,244,225,235,225,238, 97,128, 48,186 - }; - - - /* - * This function searches the compressed table efficiently. - */ - static unsigned long - ft_get_adobe_glyph_index( const char* name, - const char* limit ) - { - int c = 0; - int count, min, max; - const unsigned char* p = ft_adobe_glyph_list; - - - if ( name == 0 || name >= limit ) - goto NotFound; - - c = *name++; - count = p[1]; - p += 2; - - min = 0; - max = count; - - while ( min < max ) - { - int mid = ( min + max ) >> 1; - const unsigned char* q = p + mid * 2; - int c2; - - - q = ft_adobe_glyph_list + ( ( (int)q[0] << 8 ) | q[1] ); - - c2 = q[0] & 127; - if ( c2 == c ) - { - p = q; - goto Found; - } - if ( c2 < c ) - min = mid + 1; - else - max = mid; - } - goto NotFound; - - Found: - for (;;) - { - /* assert (*p & 127) == c */ - - if ( name >= limit ) - { - if ( (p[0] & 128) == 0 && - (p[1] & 128) != 0 ) - return (unsigned long)( ( (int)p[2] << 8 ) | p[3] ); - - goto NotFound; - } - c = *name++; - if ( p[0] & 128 ) - { - p++; - if ( c != (p[0] & 127) ) - goto NotFound; - - continue; - } - - p++; - count = p[0] & 127; - if ( p[0] & 128 ) - p += 2; - - p++; - - for ( ; count > 0; count--, p += 2 ) - { - int offset = ( (int)p[0] << 8 ) | p[1]; - const unsigned char* q = ft_adobe_glyph_list + offset; - - if ( c == ( q[0] & 127 ) ) - { - p = q; - goto NextIter; - } - } - goto NotFound; - - NextIter: - ; - } - - NotFound: - return 0; - } - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/psnames/rules.mk b/drivers/freetype/freetype/src/psnames/rules.mk deleted file mode 100644 index 4cd39a8ccf..0000000000 --- a/drivers/freetype/freetype/src/psnames/rules.mk +++ /dev/null @@ -1,71 +0,0 @@ -# -# FreeType 2 PSNames driver configuration rules -# - - -# Copyright 1996-2000, 2001, 2003, 2011 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. - - -# PSNames driver directory -# -PSNAMES_DIR := $(SRC_DIR)/psnames - - -# compilation flags for the driver -# -PSNAMES_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR)) - - -# PSNames driver sources (i.e., C files) -# -PSNAMES_DRV_SRC := $(PSNAMES_DIR)/psmodule.c \ - $(PSNAMES_DIR)/pspic.c - - -# PSNames driver headers -# -PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ - $(PSNAMES_DIR)/psnamerr.h \ - $(PSNAMES_DIR)/pstables.h - - -# PSNames driver object(s) -# -# PSNAMES_DRV_OBJ_M is used during `multi' builds -# PSNAMES_DRV_OBJ_S is used during `single' builds -# -PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR)/%.c=$(OBJ_DIR)/%.$O) -PSNAMES_DRV_OBJ_S := $(OBJ_DIR)/psnames.$O - -# PSNames driver source file for single build -# -PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psmodule.c - - -# PSNames driver - single object -# -$(PSNAMES_DRV_OBJ_S): $(PSNAMES_DRV_SRC_S) $(PSNAMES_DRV_SRC) \ - $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSNAMES_DRV_SRC_S)) - - -# PSNames driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PSNAMES_DIR)/%.c $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PSNAMES_DRV_OBJ_S) -DRV_OBJS_M += $(PSNAMES_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/raster/Jamfile b/drivers/freetype/freetype/src/raster/Jamfile deleted file mode 100644 index 4f60e87c78..0000000000 --- a/drivers/freetype/freetype/src/raster/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/raster Jamfile -# -# Copyright 2001 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) raster ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = ftraster ftrend1 rastpic ; - } - else - { - _sources = raster ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/raster Jamfile diff --git a/drivers/freetype/freetype/src/raster/ftmisc.h b/drivers/freetype/freetype/src/raster/ftmisc.h deleted file mode 100644 index 703155a429..0000000000 --- a/drivers/freetype/freetype/src/raster/ftmisc.h +++ /dev/null @@ -1,142 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmisc.h */ -/* */ -/* Miscellaneous macros for stand-alone rasterizer (specification */ -/* only). */ -/* */ -/* Copyright 2005, 2009, 2010 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. */ -/* */ -/***************************************************************************/ - - - /***************************************************/ - /* */ - /* This file is *not* portable! You have to adapt */ - /* its definitions to your platform. */ - /* */ - /***************************************************/ - -#ifndef __FTMISC_H__ -#define __FTMISC_H__ - - - /* memset */ -#include FT_CONFIG_STANDARD_LIBRARY_H - -#define FT_BEGIN_HEADER -#define FT_END_HEADER - -#define FT_LOCAL_DEF( x ) static x - - - /* from include/freetype2/fttypes.h */ - - typedef unsigned char FT_Byte; - typedef signed int FT_Int; - typedef unsigned int FT_UInt; - typedef signed long FT_Long; - typedef unsigned long FT_ULong; - typedef signed long FT_F26Dot6; - typedef int FT_Error; - -#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ - ( ( (FT_ULong)_x1 << 24 ) | \ - ( (FT_ULong)_x2 << 16 ) | \ - ( (FT_ULong)_x3 << 8 ) | \ - (FT_ULong)_x4 ) - - - /* from include/freetype2/ftsystem.h */ - - typedef struct FT_MemoryRec_* FT_Memory; - - typedef void* (*FT_Alloc_Func)( FT_Memory memory, - long size ); - - typedef void (*FT_Free_Func)( FT_Memory memory, - void* block ); - - typedef void* (*FT_Realloc_Func)( FT_Memory memory, - long cur_size, - long new_size, - void* block ); - - typedef struct FT_MemoryRec_ - { - void* user; - - FT_Alloc_Func alloc; - FT_Free_Func free; - FT_Realloc_Func realloc; - - } FT_MemoryRec; - - - /* from src/ftcalc.c */ - -#if ( defined _WIN32 || defined _WIN64 ) - - typedef __int64 FT_Int64; - -#else - -#include "inttypes.h" - - typedef int64_t FT_Int64; - -#endif - - - static FT_Long - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - - - static FT_Long - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - -#endif /* __FTMISC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/ftraster.c b/drivers/freetype/freetype/src/raster/ftraster.c deleted file mode 100644 index bbd503d97d..0000000000 --- a/drivers/freetype/freetype/src/raster/ftraster.c +++ /dev/null @@ -1,3640 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftraster.c */ -/* */ -/* The FreeType glyph rasterizer (body). */ -/* */ -/* Copyright 1996-2003, 2005, 2007-2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ - /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ - /* directory. Typically, you should do something like */ - /* */ - /* - copy `src/raster/ftraster.c' (this file) to your current directory */ - /* */ - /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' */ - /* to your current directory */ - /* */ - /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ - /* */ - /* cc -c -D_STANDALONE_ ftraster.c */ - /* */ - /* The renderer can be initialized with a call to */ - /* `ft_standard_raster.raster_new'; a bitmap can be generated */ - /* with a call to `ft_standard_raster.raster_render'. */ - /* */ - /* See the comments and documentation in the file `ftimage.h' for more */ - /* details on how the raster works. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This is a rewrite of the FreeType 1.x scan-line converter */ - /* */ - /*************************************************************************/ - -#ifdef _STANDALONE_ - -#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> - -#include <string.h> /* for memset */ - -#include "ftmisc.h" -#include "ftimage.h" - -#else /* !_STANDALONE_ */ - -#include <ft2build.h> -#include "ftraster.h" -#include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */ - -#include "rastpic.h" - -#endif /* !_STANDALONE_ */ - - - /*************************************************************************/ - /* */ - /* A simple technical note on how the raster works */ - /* ----------------------------------------------- */ - /* */ - /* Converting an outline into a bitmap is achieved in several steps: */ - /* */ - /* 1 - Decomposing the outline into successive `profiles'. Each */ - /* profile is simply an array of scanline intersections on a given */ - /* dimension. A profile's main attributes are */ - /* */ - /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ - /* */ - /* o an array of intersection coordinates for each scanline */ - /* between `Ymin' and `Ymax' */ - /* */ - /* o a direction, indicating whether it was built going `up' or */ - /* `down', as this is very important for filling rules */ - /* */ - /* o its drop-out mode */ - /* */ - /* 2 - Sweeping the target map's scanlines in order to compute segment */ - /* `spans' which are then filled. Additionally, this pass */ - /* performs drop-out control. */ - /* */ - /* The outline data is parsed during step 1 only. The profiles are */ - /* built from the bottom of the render pool, used as a stack. The */ - /* following graphics shows the profile list under construction: */ - /* */ - /* __________________________________________________________ _ _ */ - /* | | | | | */ - /* | profile | coordinates for | profile | coordinates for |--> */ - /* | 1 | profile 1 | 2 | profile 2 |--> */ - /* |_________|_________________|_________|_________________|__ _ _ */ - /* */ - /* ^ ^ */ - /* | | */ - /* start of render pool top */ - /* */ - /* The top of the profile stack is kept in the `top' variable. */ - /* */ - /* As you can see, a profile record is pushed on top of the render */ - /* pool, which is then followed by its coordinates/intersections. If */ - /* a change of direction is detected in the outline, a new profile is */ - /* generated until the end of the outline. */ - /* */ - /* Note that when all profiles have been generated, the function */ - /* Finalize_Profile_Table() is used to record, for each profile, its */ - /* bottom-most scanline as well as the scanline above its upmost */ - /* boundary. These positions are called `y-turns' because they (sort */ - /* of) correspond to local extrema. They are stored in a sorted list */ - /* built from the top of the render pool as a downwards stack: */ - /* */ - /* _ _ _______________________________________ */ - /* | | */ - /* <--| sorted list of | */ - /* <--| extrema scanlines | */ - /* _ _ __________________|____________________| */ - /* */ - /* ^ ^ */ - /* | | */ - /* maxBuff sizeBuff = end of pool */ - /* */ - /* This list is later used during the sweep phase in order to */ - /* optimize performance (see technical note on the sweep below). */ - /* */ - /* Of course, the raster detects whether the two stacks collide and */ - /* handles the situation properly. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** CONFIGURATION MACROS **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - /* define DEBUG_RASTER if you want to compile a debugging version */ -/* #define DEBUG_RASTER */ - - /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ - /* 5-levels anti-aliasing */ -/* #define FT_RASTER_OPTION_ANTI_ALIASING */ - - /* The size of the two-lines intermediate bitmap used */ - /* for anti-aliasing, in bytes. */ -#define RASTER_GRAY_LINES 2048 - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** OTHER MACROS (do not change) **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* 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_raster - - -#ifdef _STANDALONE_ - - /* Auxiliary macros for token concatenation. */ -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) - - /* This macro is used to indicate that a function parameter is unused. */ - /* Its purpose is simply to reduce compiler warnings. Note also that */ - /* simply defining it as `(void)x' doesn't avoid warnings with certain */ - /* ANSI compilers (e.g. LCC). */ -#define FT_UNUSED( x ) (x) = (x) - - /* Disable the tracing mechanism for simplicity -- developers can */ - /* activate it easily by redefining these macros. */ -#ifndef FT_ERROR -#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ -#endif - -#ifndef FT_TRACE -#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ -#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ -#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ -#endif - -#ifndef FT_THROW -#define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e ) -#endif - -#define Raster_Err_None 0 -#define Raster_Err_Not_Ini -1 -#define Raster_Err_Overflow -2 -#define Raster_Err_Neg_Height -3 -#define Raster_Err_Invalid -4 -#define Raster_Err_Unsupported -5 - -#define ft_memset memset - -#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \ - raster_reset_, raster_set_mode_, \ - raster_render_, raster_done_ ) \ - const FT_Raster_Funcs class_ = \ - { \ - glyph_format_, \ - raster_new_, \ - raster_reset_, \ - raster_set_mode_, \ - raster_render_, \ - raster_done_ \ - }; - -#else /* !_STANDALONE_ */ - - -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H /* for FT_TRACE, FT_ERROR, and FT_THROW */ - -#include "rasterrs.h" - -#define Raster_Err_None FT_Err_Ok -#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized -#define Raster_Err_Overflow Raster_Err_Raster_Overflow -#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height -#define Raster_Err_Invalid Raster_Err_Invalid_Outline -#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph - - -#endif /* !_STANDALONE_ */ - - -#ifndef FT_MEM_SET -#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) -#endif - -#ifndef FT_MEM_ZERO -#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) -#endif - - /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ - /* typically a small value and the result of a*b is known to fit into */ - /* 32 bits. */ -#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) - - /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ - /* for clipping computations. It simply uses the FT_MulDiv() function */ - /* defined in `ftcalc.h'. */ -#define SMulDiv FT_MulDiv -#define SMulDiv_No_Round FT_MulDiv_No_Round - - /* The rasterizer is a very general purpose component; please leave */ - /* the following redefinitions there (you never know your target */ - /* environment). */ - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL (void*)0 -#endif - -#ifndef SUCCESS -#define SUCCESS 0 -#endif - -#ifndef FAILURE -#define FAILURE 1 -#endif - - -#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ - /* Setting this constant to more than 32 is a */ - /* pure waste of space. */ - -#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** SIMPLE TYPE DECLARATIONS **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - typedef int Int; - typedef unsigned int UInt; - typedef short Short; - typedef unsigned short UShort, *PUShort; - typedef long Long, *PLong; - typedef unsigned long ULong; - - typedef unsigned char Byte, *PByte; - typedef char Bool; - - - typedef union Alignment_ - { - long l; - void* p; - void (*f)(void); - - } Alignment, *PAlignment; - - - typedef struct TPoint_ - { - Long x; - Long y; - - } TPoint; - - - /* values for the `flags' bit field */ -#define Flow_Up 0x8 -#define Overshoot_Top 0x10 -#define Overshoot_Bottom 0x20 - - - /* States of each line, arc, and profile */ - typedef enum TStates_ - { - Unknown_State, - Ascending_State, - Descending_State, - Flat_State - - } TStates; - - - typedef struct TProfile_ TProfile; - typedef TProfile* PProfile; - - struct TProfile_ - { - FT_F26Dot6 X; /* current coordinate during sweep */ - PProfile link; /* link to next profile (various purposes) */ - PLong offset; /* start of profile's data in render pool */ - unsigned flags; /* Bit 0-2: drop-out mode */ - /* Bit 3: profile orientation (up/down) */ - /* Bit 4: is top profile? */ - /* Bit 5: is bottom profile? */ - long height; /* profile's height in scanlines */ - long start; /* profile's starting scanline */ - - unsigned countL; /* number of lines to step before this */ - /* profile becomes drawable */ - - PProfile next; /* next profile in same contour, used */ - /* during drop-out control */ - }; - - typedef PProfile TProfileList; - typedef PProfile* PProfileList; - - - /* Simple record used to implement a stack of bands, required */ - /* by the sub-banding mechanism */ - typedef struct black_TBand_ - { - Short y_min; /* band's minimum */ - Short y_max; /* band's maximum */ - - } black_TBand; - - -#define AlignProfileSize \ - ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) - - -#undef RAS_ARG -#undef RAS_ARGS -#undef RAS_VAR -#undef RAS_VARS - -#ifdef FT_STATIC_RASTER - - -#define RAS_ARGS /* void */ -#define RAS_ARG /* void */ - -#define RAS_VARS /* void */ -#define RAS_VAR /* void */ - -#define FT_UNUSED_RASTER do { } while ( 0 ) - - -#else /* !FT_STATIC_RASTER */ - - -#define RAS_ARGS black_PWorker worker, -#define RAS_ARG black_PWorker worker - -#define RAS_VARS worker, -#define RAS_VAR worker - -#define FT_UNUSED_RASTER FT_UNUSED( worker ) - - -#endif /* !FT_STATIC_RASTER */ - - - typedef struct black_TWorker_ black_TWorker, *black_PWorker; - - - /* prototypes used for sweep function dispatch */ - typedef void - Function_Sweep_Init( RAS_ARGS Short* min, - Short* max ); - - typedef void - Function_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ); - - typedef void - Function_Sweep_Step( RAS_ARG ); - - - /* NOTE: These operations are only valid on 2's complement processors */ -#undef FLOOR -#undef CEILING -#undef TRUNC -#undef SCALED - -#define FLOOR( x ) ( (x) & -ras.precision ) -#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) -#define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) -#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) -#define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half ) - -#define IS_BOTTOM_OVERSHOOT( x ) \ - (Bool)( CEILING( x ) - x >= ras.precision_half ) -#define IS_TOP_OVERSHOOT( x ) \ - (Bool)( x - FLOOR( x ) >= ras.precision_half ) - - /* The most used variables are positioned at the top of the structure. */ - /* Thus, their offset can be coded with less opcodes, resulting in a */ - /* smaller executable. */ - - struct black_TWorker_ - { - Int precision_bits; /* precision related variables */ - Int precision; - Int precision_half; - Int precision_shift; - Int precision_step; - Int precision_jitter; - - Int scale_shift; /* == precision_shift for bitmaps */ - /* == precision_shift+1 for pixmaps */ - - PLong buff; /* The profiles buffer */ - PLong sizeBuff; /* Render pool size */ - PLong maxBuff; /* Profiles buffer size */ - PLong top; /* Current cursor in buffer */ - - FT_Error error; - - Int numTurns; /* number of Y-turns in outline */ - - TPoint* arc; /* current Bezier arc pointer */ - - UShort bWidth; /* target bitmap width */ - PByte bTarget; /* target bitmap buffer */ - PByte gTarget; /* target pixmap buffer */ - - Long lastX, lastY; - Long minY, maxY; - - UShort num_Profs; /* current number of profiles */ - - Bool fresh; /* signals a fresh new profile which */ - /* `start' field must be completed */ - Bool joint; /* signals that the last arc ended */ - /* exactly on a scanline. Allows */ - /* removal of doublets */ - PProfile cProfile; /* current profile */ - PProfile fProfile; /* head of linked list of profiles */ - PProfile gProfile; /* contour's first profile in case */ - /* of impact */ - - TStates state; /* rendering state */ - - FT_Bitmap target; /* description of target bit/pixmap */ - FT_Outline outline; - - Long traceOfs; /* current offset in target bitmap */ - Long traceG; /* current offset in target pixmap */ - - Short traceIncr; /* sweep's increment in target bitmap */ - - Short gray_min_x; /* current min x during gray rendering */ - Short gray_max_x; /* current max x during gray rendering */ - - /* dispatch variables */ - - Function_Sweep_Init* Proc_Sweep_Init; - Function_Sweep_Span* Proc_Sweep_Span; - Function_Sweep_Span* Proc_Sweep_Drop; - Function_Sweep_Step* Proc_Sweep_Step; - - Byte dropOutControl; /* current drop_out control method */ - - Bool second_pass; /* indicates whether a horizontal pass */ - /* should be performed to control */ - /* drop-out accurately when calling */ - /* Render_Glyph. Note that there is */ - /* no horizontal pass during gray */ - /* rendering. */ - - TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ - - black_TBand band_stack[16]; /* band stack used for sub-banding */ - Int band_top; /* band stack top */ - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - Byte* grays; - - Byte gray_lines[RASTER_GRAY_LINES]; - /* Intermediate table used to render the */ - /* graylevels pixmaps. */ - /* gray_lines is a buffer holding two */ - /* monochrome scanlines */ - - Short gray_width; /* width in bytes of one monochrome */ - /* intermediate scanline of gray_lines. */ - /* Each gray pixel takes 2 bits long there */ - - /* The gray_lines must hold 2 lines, thus with size */ - /* in bytes of at least `gray_width*2'. */ - -#endif /* FT_RASTER_ANTI_ALIASING */ - - }; - - - typedef struct black_TRaster_ - { - char* buffer; - long buffer_size; - void* memory; - black_PWorker worker; - Byte grays[5]; - Short gray_width; - - } black_TRaster, *black_PRaster; - -#ifdef FT_STATIC_RASTER - - static black_TWorker cur_ras; -#define ras cur_ras - -#else /* !FT_STATIC_RASTER */ - -#define ras (*worker) - -#endif /* !FT_STATIC_RASTER */ - - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - /* A lookup table used to quickly count set bits in four gray 2x2 */ - /* cells. The values of the table have been produced with the */ - /* following code: */ - /* */ - /* for ( i = 0; i < 256; i++ ) */ - /* { */ - /* l = 0; */ - /* j = i; */ - /* */ - /* for ( c = 0; c < 4; c++ ) */ - /* { */ - /* l <<= 4; */ - /* */ - /* if ( j & 0x80 ) l++; */ - /* if ( j & 0x40 ) l++; */ - /* */ - /* j = ( j << 2 ) & 0xFF; */ - /* } */ - /* printf( "0x%04X", l ); */ - /* } */ - /* */ - - static const short count_table[256] = - { - 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, - 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, - 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, - 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, - 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, - 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, - 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, - 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, - 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, - 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, - 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, - 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, - 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, - 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, - 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, - 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, - 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, - 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, - 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, - 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, - 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, - 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 - }; - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** PROFILES COMPUTATION **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Set_High_Precision */ - /* */ - /* <Description> */ - /* Set precision variables according to param flag. */ - /* */ - /* <Input> */ - /* High :: Set to True for high precision (typically for ppem < 24), */ - /* false otherwise. */ - /* */ - static void - Set_High_Precision( RAS_ARGS Int High ) - { - /* - * `precision_step' is used in `Bezier_Up' to decide when to split a - * given y-monotonous Bezier arc that crosses a scanline before - * approximating it as a straight segment. The default value of 32 (for - * low accuracy) corresponds to - * - * 32 / 64 == 0.5 pixels , - * - * while for the high accuracy case we have - * - * 256/ (1 << 12) = 0.0625 pixels . - * - * `precision_jitter' is an epsilon threshold used in - * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier - * decomposition (after all, we are working with approximations only); - * it avoids switching on additional pixels which would cause artifacts - * otherwise. - * - * The value of `precision_jitter' has been determined heuristically. - * - */ - - if ( High ) - { - ras.precision_bits = 12; - ras.precision_step = 256; - ras.precision_jitter = 30; - } - else - { - ras.precision_bits = 6; - ras.precision_step = 32; - ras.precision_jitter = 2; - } - - FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); - - ras.precision = 1 << ras.precision_bits; - ras.precision_half = ras.precision / 2; - ras.precision_shift = ras.precision_bits - Pixel_Bits; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* New_Profile */ - /* */ - /* <Description> */ - /* Create a new profile in the render pool. */ - /* */ - /* <Input> */ - /* aState :: The state/orientation of the new profile. */ - /* */ - /* overshoot :: Whether the profile's unrounded start position */ - /* differs by at least a half pixel. */ - /* */ - /* <Return> */ - /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ - /* profile. */ - /* */ - static Bool - New_Profile( RAS_ARGS TStates aState, - Bool overshoot ) - { - if ( !ras.fProfile ) - { - ras.cProfile = (PProfile)ras.top; - ras.fProfile = ras.cProfile; - ras.top += AlignProfileSize; - } - - if ( ras.top >= ras.maxBuff ) - { - ras.error = FT_THROW( Overflow ); - return FAILURE; - } - - ras.cProfile->flags = 0; - ras.cProfile->start = 0; - ras.cProfile->height = 0; - ras.cProfile->offset = ras.top; - ras.cProfile->link = (PProfile)0; - ras.cProfile->next = (PProfile)0; - ras.cProfile->flags = ras.dropOutControl; - - switch ( aState ) - { - case Ascending_State: - ras.cProfile->flags |= Flow_Up; - if ( overshoot ) - ras.cProfile->flags |= Overshoot_Bottom; - - FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile )); - break; - - case Descending_State: - if ( overshoot ) - ras.cProfile->flags |= Overshoot_Top; - FT_TRACE6(( "New descending profile = %p\n", ras.cProfile )); - break; - - default: - FT_ERROR(( "New_Profile: invalid profile direction\n" )); - ras.error = FT_THROW( Invalid ); - return FAILURE; - } - - if ( !ras.gProfile ) - ras.gProfile = ras.cProfile; - - ras.state = aState; - ras.fresh = TRUE; - ras.joint = FALSE; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* End_Profile */ - /* */ - /* <Description> */ - /* Finalize the current profile. */ - /* */ - /* <Input> */ - /* overshoot :: Whether the profile's unrounded end position differs */ - /* by at least a half pixel. */ - /* */ - /* <Return> */ - /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ - /* */ - static Bool - End_Profile( RAS_ARGS Bool overshoot ) - { - Long h; - - - h = (Long)( ras.top - ras.cProfile->offset ); - - if ( h < 0 ) - { - FT_ERROR(( "End_Profile: negative height encountered\n" )); - ras.error = FT_THROW( Neg_Height ); - return FAILURE; - } - - if ( h > 0 ) - { - PProfile oldProfile; - - - FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n", - ras.cProfile, ras.cProfile->start, h )); - - ras.cProfile->height = h; - if ( overshoot ) - { - if ( ras.cProfile->flags & Flow_Up ) - ras.cProfile->flags |= Overshoot_Top; - else - ras.cProfile->flags |= Overshoot_Bottom; - } - - oldProfile = ras.cProfile; - ras.cProfile = (PProfile)ras.top; - - ras.top += AlignProfileSize; - - ras.cProfile->height = 0; - ras.cProfile->offset = ras.top; - - oldProfile->next = ras.cProfile; - ras.num_Profs++; - } - - if ( ras.top >= ras.maxBuff ) - { - FT_TRACE1(( "overflow in End_Profile\n" )); - ras.error = FT_THROW( Overflow ); - return FAILURE; - } - - ras.joint = FALSE; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Insert_Y_Turn */ - /* */ - /* <Description> */ - /* Insert a salient into the sorted list placed on top of the render */ - /* pool. */ - /* */ - /* <Input> */ - /* New y scanline position. */ - /* */ - /* <Return> */ - /* SUCCESS on success. FAILURE in case of overflow. */ - /* */ - static Bool - Insert_Y_Turn( RAS_ARGS Int y ) - { - PLong y_turns; - Int n; - - - n = ras.numTurns - 1; - y_turns = ras.sizeBuff - ras.numTurns; - - /* look for first y value that is <= */ - while ( n >= 0 && y < y_turns[n] ) - n--; - - /* if it is <, simply insert it, ignore if == */ - if ( n >= 0 && y > y_turns[n] ) - while ( n >= 0 ) - { - Int y2 = (Int)y_turns[n]; - - - y_turns[n] = y; - y = y2; - n--; - } - - if ( n < 0 ) - { - ras.maxBuff--; - if ( ras.maxBuff <= ras.top ) - { - ras.error = FT_THROW( Overflow ); - return FAILURE; - } - ras.numTurns++; - ras.sizeBuff[-ras.numTurns] = y; - } - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Finalize_Profile_Table */ - /* */ - /* <Description> */ - /* Adjust all links in the profiles list. */ - /* */ - /* <Return> */ - /* SUCCESS on success. FAILURE in case of overflow. */ - /* */ - static Bool - Finalize_Profile_Table( RAS_ARG ) - { - UShort n; - PProfile p; - - - n = ras.num_Profs; - p = ras.fProfile; - - if ( n > 1 && p ) - { - while ( n > 0 ) - { - Int bottom, top; - - - if ( n > 1 ) - p->link = (PProfile)( p->offset + p->height ); - else - p->link = NULL; - - if ( p->flags & Flow_Up ) - { - bottom = (Int)p->start; - top = (Int)( p->start + p->height - 1 ); - } - else - { - bottom = (Int)( p->start - p->height + 1 ); - top = (Int)p->start; - p->start = bottom; - p->offset += p->height - 1; - } - - if ( Insert_Y_Turn( RAS_VARS bottom ) || - Insert_Y_Turn( RAS_VARS top + 1 ) ) - return FAILURE; - - p = p->link; - n--; - } - } - else - ras.fProfile = NULL; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Split_Conic */ - /* */ - /* <Description> */ - /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ - /* stack. */ - /* */ - /* <Input> */ - /* None (subdivided Bezier is taken from the top of the stack). */ - /* */ - /* <Note> */ - /* This routine is the `beef' of this component. It is _the_ inner */ - /* loop that should be optimized to hell to get the best performance. */ - /* */ - static void - Split_Conic( TPoint* base ) - { - Long a, b; - - - base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; - - base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; - - /* hand optimized. gcc doesn't seem to be too good at common */ - /* expression substitution and instruction scheduling ;-) */ - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Split_Cubic */ - /* */ - /* <Description> */ - /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ - /* Bezier stack. */ - /* */ - /* <Note> */ - /* This routine is the `beef' of the component. It is one of _the_ */ - /* inner loops that should be optimized like hell to get the best */ - /* performance. */ - /* */ - static void - Split_Cubic( TPoint* base ) - { - Long a, b, c, d; - - - base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c + 1 ) >> 1; - base[5].x = b = ( base[3].x + d + 1 ) >> 1; - c = ( c + d + 1 ) >> 1; - base[2].x = a = ( a + c + 1 ) >> 1; - base[4].x = b = ( b + c + 1 ) >> 1; - base[3].x = ( a + b + 1 ) >> 1; - - base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c + 1 ) >> 1; - base[5].y = b = ( base[3].y + d + 1 ) >> 1; - c = ( c + d + 1 ) >> 1; - base[2].y = a = ( a + c + 1 ) >> 1; - base[4].y = b = ( b + c + 1 ) >> 1; - base[3].y = ( a + b + 1 ) >> 1; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Line_Up */ - /* */ - /* <Description> */ - /* Compute the x-coordinates of an ascending line segment and store */ - /* them in the render pool. */ - /* */ - /* <Input> */ - /* x1 :: The x-coordinate of the segment's start point. */ - /* */ - /* y1 :: The y-coordinate of the segment's start point. */ - /* */ - /* x2 :: The x-coordinate of the segment's end point. */ - /* */ - /* y2 :: The y-coordinate of the segment's end point. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static Bool - Line_Up( RAS_ARGS Long x1, - Long y1, - Long x2, - Long y2, - Long miny, - Long maxy ) - { - Long Dx, Dy; - Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ - Long Ix, Rx, Ax; - - PLong top; - - - Dx = x2 - x1; - Dy = y2 - y1; - - if ( Dy <= 0 || y2 < miny || y1 > maxy ) - return SUCCESS; - - if ( y1 < miny ) - { - /* Take care: miny-y1 can be a very large value; we use */ - /* a slow MulDiv function to avoid clipping bugs */ - x1 += SMulDiv( Dx, miny - y1, Dy ); - e1 = (Int)TRUNC( miny ); - f1 = 0; - } - else - { - e1 = (Int)TRUNC( y1 ); - f1 = (Int)FRAC( y1 ); - } - - if ( y2 > maxy ) - { - /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ - e2 = (Int)TRUNC( maxy ); - f2 = 0; - } - else - { - e2 = (Int)TRUNC( y2 ); - f2 = (Int)FRAC( y2 ); - } - - if ( f1 > 0 ) - { - if ( e1 == e2 ) - return SUCCESS; - else - { - x1 += SMulDiv( Dx, ras.precision - f1, Dy ); - e1 += 1; - } - } - else - if ( ras.joint ) - { - ras.top--; - ras.joint = FALSE; - } - - ras.joint = (char)( f2 == 0 ); - - if ( ras.fresh ) - { - ras.cProfile->start = e1; - ras.fresh = FALSE; - } - - size = e2 - e1 + 1; - if ( ras.top + size >= ras.maxBuff ) - { - ras.error = FT_THROW( Overflow ); - return FAILURE; - } - - if ( Dx > 0 ) - { - Ix = SMulDiv_No_Round( ras.precision, Dx, Dy ); - Rx = ( ras.precision * Dx ) % Dy; - Dx = 1; - } - else - { - Ix = -SMulDiv_No_Round( ras.precision, -Dx, Dy ); - Rx = ( ras.precision * -Dx ) % Dy; - Dx = -1; - } - - Ax = -Dy; - top = ras.top; - - while ( size > 0 ) - { - *top++ = x1; - - x1 += Ix; - Ax += Rx; - if ( Ax >= 0 ) - { - Ax -= Dy; - x1 += Dx; - } - size--; - } - - ras.top = top; - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Line_Down */ - /* */ - /* <Description> */ - /* Compute the x-coordinates of an descending line segment and store */ - /* them in the render pool. */ - /* */ - /* <Input> */ - /* x1 :: The x-coordinate of the segment's start point. */ - /* */ - /* y1 :: The y-coordinate of the segment's start point. */ - /* */ - /* x2 :: The x-coordinate of the segment's end point. */ - /* */ - /* y2 :: The y-coordinate of the segment's end point. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static Bool - Line_Down( RAS_ARGS Long x1, - Long y1, - Long x2, - Long y2, - Long miny, - Long maxy ) - { - Bool result, fresh; - - - fresh = ras.fresh; - - result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); - - if ( fresh && !ras.fresh ) - ras.cProfile->start = -ras.cProfile->start; - - return result; - } - - - /* A function type describing the functions used to split Bezier arcs */ - typedef void (*TSplitter)( TPoint* base ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Bezier_Up */ - /* */ - /* <Description> */ - /* Compute the x-coordinates of an ascending Bezier arc and store */ - /* them in the render pool. */ - /* */ - /* <Input> */ - /* degree :: The degree of the Bezier arc (either 2 or 3). */ - /* */ - /* splitter :: The function to split Bezier arcs. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static Bool - Bezier_Up( RAS_ARGS Int degree, - TSplitter splitter, - Long miny, - Long maxy ) - { - Long y1, y2, e, e2, e0; - Short f1; - - TPoint* arc; - TPoint* start_arc; - - PLong top; - - - arc = ras.arc; - y1 = arc[degree].y; - y2 = arc[0].y; - top = ras.top; - - if ( y2 < miny || y1 > maxy ) - goto Fin; - - e2 = FLOOR( y2 ); - - if ( e2 > maxy ) - e2 = maxy; - - e0 = miny; - - if ( y1 < miny ) - e = miny; - else - { - e = CEILING( y1 ); - f1 = (Short)( FRAC( y1 ) ); - e0 = e; - - if ( f1 == 0 ) - { - if ( ras.joint ) - { - top--; - ras.joint = FALSE; - } - - *top++ = arc[degree].x; - - e += ras.precision; - } - } - - if ( ras.fresh ) - { - ras.cProfile->start = TRUNC( e0 ); - ras.fresh = FALSE; - } - - if ( e2 < e ) - goto Fin; - - if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) - { - ras.top = top; - ras.error = FT_THROW( Overflow ); - return FAILURE; - } - - start_arc = arc; - - while ( arc >= start_arc && e <= e2 ) - { - ras.joint = FALSE; - - y2 = arc[0].y; - - if ( y2 > e ) - { - y1 = arc[degree].y; - if ( y2 - y1 >= ras.precision_step ) - { - splitter( arc ); - arc += degree; - } - else - { - *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, - e - y1, y2 - y1 ); - arc -= degree; - e += ras.precision; - } - } - else - { - if ( y2 == e ) - { - ras.joint = TRUE; - *top++ = arc[0].x; - - e += ras.precision; - } - arc -= degree; - } - } - - Fin: - ras.top = top; - ras.arc -= degree; - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Bezier_Down */ - /* */ - /* <Description> */ - /* Compute the x-coordinates of an descending Bezier arc and store */ - /* them in the render pool. */ - /* */ - /* <Input> */ - /* degree :: The degree of the Bezier arc (either 2 or 3). */ - /* */ - /* splitter :: The function to split Bezier arcs. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static Bool - Bezier_Down( RAS_ARGS Int degree, - TSplitter splitter, - Long miny, - Long maxy ) - { - TPoint* arc = ras.arc; - Bool result, fresh; - - - arc[0].y = -arc[0].y; - arc[1].y = -arc[1].y; - arc[2].y = -arc[2].y; - if ( degree > 2 ) - arc[3].y = -arc[3].y; - - fresh = ras.fresh; - - result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); - - if ( fresh && !ras.fresh ) - ras.cProfile->start = -ras.cProfile->start; - - arc[0].y = -arc[0].y; - return result; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Line_To */ - /* */ - /* <Description> */ - /* Inject a new line segment and adjust the Profiles list. */ - /* */ - /* <Input> */ - /* x :: The x-coordinate of the segment's end point (its start point */ - /* is stored in `lastX'). */ - /* */ - /* y :: The y-coordinate of the segment's end point (its start point */ - /* is stored in `lastY'). */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ - static Bool - Line_To( RAS_ARGS Long x, - Long y ) - { - /* First, detect a change of direction */ - - switch ( ras.state ) - { - case Unknown_State: - if ( y > ras.lastY ) - { - if ( New_Profile( RAS_VARS Ascending_State, - IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) - return FAILURE; - } - else - { - if ( y < ras.lastY ) - if ( New_Profile( RAS_VARS Descending_State, - IS_TOP_OVERSHOOT( ras.lastY ) ) ) - return FAILURE; - } - break; - - case Ascending_State: - if ( y < ras.lastY ) - { - if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || - New_Profile( RAS_VARS Descending_State, - IS_TOP_OVERSHOOT( ras.lastY ) ) ) - return FAILURE; - } - break; - - case Descending_State: - if ( y > ras.lastY ) - { - if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || - New_Profile( RAS_VARS Ascending_State, - IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) - return FAILURE; - } - break; - - default: - ; - } - - /* Then compute the lines */ - - switch ( ras.state ) - { - case Ascending_State: - if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) - return FAILURE; - break; - - case Descending_State: - if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) - return FAILURE; - break; - - default: - ; - } - - ras.lastX = x; - ras.lastY = y; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Conic_To */ - /* */ - /* <Description> */ - /* Inject a new conic arc and adjust the profile list. */ - /* */ - /* <Input> */ - /* cx :: The x-coordinate of the arc's new control point. */ - /* */ - /* cy :: The y-coordinate of the arc's new control point. */ - /* */ - /* x :: The x-coordinate of the arc's end point (its start point is */ - /* stored in `lastX'). */ - /* */ - /* y :: The y-coordinate of the arc's end point (its start point is */ - /* stored in `lastY'). */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ - static Bool - Conic_To( RAS_ARGS Long cx, - Long cy, - Long x, - Long y ) - { - Long y1, y2, y3, x3, ymin, ymax; - TStates state_bez; - - - ras.arc = ras.arcs; - ras.arc[2].x = ras.lastX; - ras.arc[2].y = ras.lastY; - ras.arc[1].x = cx; - ras.arc[1].y = cy; - ras.arc[0].x = x; - ras.arc[0].y = y; - - do - { - y1 = ras.arc[2].y; - y2 = ras.arc[1].y; - y3 = ras.arc[0].y; - x3 = ras.arc[0].x; - - /* first, categorize the Bezier arc */ - - if ( y1 <= y3 ) - { - ymin = y1; - ymax = y3; - } - else - { - ymin = y3; - ymax = y1; - } - - if ( y2 < ymin || y2 > ymax ) - { - /* this arc has no given direction, split it! */ - Split_Conic( ras.arc ); - ras.arc += 2; - } - else if ( y1 == y3 ) - { - /* this arc is flat, ignore it and pop it from the Bezier stack */ - ras.arc -= 2; - } - else - { - /* the arc is y-monotonous, either ascending or descending */ - /* detect a change of direction */ - state_bez = y1 < y3 ? Ascending_State : Descending_State; - if ( ras.state != state_bez ) - { - Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); - - - /* finalize current profile if any */ - if ( ras.state != Unknown_State && - End_Profile( RAS_VARS o ) ) - goto Fail; - - /* create a new profile */ - if ( New_Profile( RAS_VARS state_bez, o ) ) - goto Fail; - } - - /* now call the appropriate routine */ - if ( state_bez == Ascending_State ) - { - if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) - goto Fail; - } - else - if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) - goto Fail; - } - - } while ( ras.arc >= ras.arcs ); - - ras.lastX = x3; - ras.lastY = y3; - - return SUCCESS; - - Fail: - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Cubic_To */ - /* */ - /* <Description> */ - /* Inject a new cubic arc and adjust the profile list. */ - /* */ - /* <Input> */ - /* cx1 :: The x-coordinate of the arc's first new control point. */ - /* */ - /* cy1 :: The y-coordinate of the arc's first new control point. */ - /* */ - /* cx2 :: The x-coordinate of the arc's second new control point. */ - /* */ - /* cy2 :: The y-coordinate of the arc's second new control point. */ - /* */ - /* x :: The x-coordinate of the arc's end point (its start point is */ - /* stored in `lastX'). */ - /* */ - /* y :: The y-coordinate of the arc's end point (its start point is */ - /* stored in `lastY'). */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ - static Bool - Cubic_To( RAS_ARGS Long cx1, - Long cy1, - Long cx2, - Long cy2, - Long x, - Long y ) - { - Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; - TStates state_bez; - - - ras.arc = ras.arcs; - ras.arc[3].x = ras.lastX; - ras.arc[3].y = ras.lastY; - ras.arc[2].x = cx1; - ras.arc[2].y = cy1; - ras.arc[1].x = cx2; - ras.arc[1].y = cy2; - ras.arc[0].x = x; - ras.arc[0].y = y; - - do - { - y1 = ras.arc[3].y; - y2 = ras.arc[2].y; - y3 = ras.arc[1].y; - y4 = ras.arc[0].y; - x4 = ras.arc[0].x; - - /* first, categorize the Bezier arc */ - - if ( y1 <= y4 ) - { - ymin1 = y1; - ymax1 = y4; - } - else - { - ymin1 = y4; - ymax1 = y1; - } - - if ( y2 <= y3 ) - { - ymin2 = y2; - ymax2 = y3; - } - else - { - ymin2 = y3; - ymax2 = y2; - } - - if ( ymin2 < ymin1 || ymax2 > ymax1 ) - { - /* this arc has no given direction, split it! */ - Split_Cubic( ras.arc ); - ras.arc += 3; - } - else if ( y1 == y4 ) - { - /* this arc is flat, ignore it and pop it from the Bezier stack */ - ras.arc -= 3; - } - else - { - state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; - - /* detect a change of direction */ - if ( ras.state != state_bez ) - { - Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); - - - /* finalize current profile if any */ - if ( ras.state != Unknown_State && - End_Profile( RAS_VARS o ) ) - goto Fail; - - if ( New_Profile( RAS_VARS state_bez, o ) ) - goto Fail; - } - - /* compute intersections */ - if ( state_bez == Ascending_State ) - { - if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) - goto Fail; - } - else - if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) - goto Fail; - } - - } while ( ras.arc >= ras.arcs ); - - ras.lastX = x4; - ras.lastY = y4; - - return SUCCESS; - - Fail: - return FAILURE; - } - - -#undef SWAP_ -#define SWAP_( x, y ) do \ - { \ - Long swap = x; \ - \ - \ - x = y; \ - y = swap; \ - } while ( 0 ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Decompose_Curve */ - /* */ - /* <Description> */ - /* Scan the outline arrays in order to emit individual segments and */ - /* Beziers by calling Line_To() and Bezier_To(). It handles all */ - /* weird cases, like when the first point is off the curve, or when */ - /* there are simply no `on' points in the contour! */ - /* */ - /* <Input> */ - /* first :: The index of the first point in the contour. */ - /* */ - /* last :: The index of the last point in the contour. */ - /* */ - /* flipped :: If set, flip the direction of the curve. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on error. */ - /* */ - static Bool - Decompose_Curve( RAS_ARGS UShort first, - UShort last, - int flipped ) - { - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* points; - FT_Vector* point; - FT_Vector* limit; - char* tags; - - unsigned tag; /* current point's state */ - - - points = ras.outline.points; - limit = points + last; - - v_start.x = SCALED( points[first].x ); - v_start.y = SCALED( points[first].y ); - v_last.x = SCALED( points[last].x ); - v_last.y = SCALED( points[last].y ); - - if ( flipped ) - { - SWAP_( v_start.x, v_start.y ); - SWAP_( v_last.x, v_last.y ); - } - - v_control = v_start; - - point = points + first; - tags = ras.outline.tags + first; - - /* set scan mode if necessary */ - if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) - ras.dropOutControl = (Byte)tags[0] >> 5; - - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_CURVE_TAG_CONIC ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - ras.lastX = v_start.x; - ras.lastY = v_start.y; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - - switch ( tag ) - { - case FT_CURVE_TAG_ON: /* emit a single line_to */ - { - Long x, y; - - - x = SCALED( point->x ); - y = SCALED( point->y ); - if ( flipped ) - SWAP_( x, y ); - - if ( Line_To( RAS_VARS x, y ) ) - goto Fail; - continue; - } - - case FT_CURVE_TAG_CONIC: /* consume conic arcs */ - v_control.x = SCALED( point[0].x ); - v_control.y = SCALED( point[0].y ); - - if ( flipped ) - SWAP_( v_control.x, v_control.y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector v_middle; - Long x, y; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - x = SCALED( point[0].x ); - y = SCALED( point[0].y ); - - if ( flipped ) - SWAP_( x, y ); - - if ( tag == FT_CURVE_TAG_ON ) - { - if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) - goto Fail; - continue; - } - - if ( tag != FT_CURVE_TAG_CONIC ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + x ) / 2; - v_middle.y = ( v_control.y + y ) / 2; - - if ( Conic_To( RAS_VARS v_control.x, v_control.y, - v_middle.x, v_middle.y ) ) - goto Fail; - - v_control.x = x; - v_control.y = y; - - goto Do_Conic; - } - - if ( Conic_To( RAS_VARS v_control.x, v_control.y, - v_start.x, v_start.y ) ) - goto Fail; - - goto Close; - - default: /* FT_CURVE_TAG_CUBIC */ - { - Long x1, y1, x2, y2, x3, y3; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - x1 = SCALED( point[-2].x ); - y1 = SCALED( point[-2].y ); - x2 = SCALED( point[-1].x ); - y2 = SCALED( point[-1].y ); - - if ( flipped ) - { - SWAP_( x1, y1 ); - SWAP_( x2, y2 ); - } - - if ( point <= limit ) - { - x3 = SCALED( point[0].x ); - y3 = SCALED( point[0].y ); - - if ( flipped ) - SWAP_( x3, y3 ); - - if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) - goto Fail; - continue; - } - - if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) - goto Fail; - goto Close; - } - } - } - - /* close the contour with a line segment */ - if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) - goto Fail; - - Close: - return SUCCESS; - - Invalid_Outline: - ras.error = FT_THROW( Invalid ); - - Fail: - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Convert_Glyph */ - /* */ - /* <Description> */ - /* Convert a glyph into a series of segments and arcs and make a */ - /* profiles list with them. */ - /* */ - /* <Input> */ - /* flipped :: If set, flip the direction of curve. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE if any error was encountered during */ - /* rendering. */ - /* */ - static Bool - Convert_Glyph( RAS_ARGS int flipped ) - { - int i; - unsigned start; - - - ras.fProfile = NULL; - ras.joint = FALSE; - ras.fresh = FALSE; - - ras.maxBuff = ras.sizeBuff - AlignProfileSize; - - ras.numTurns = 0; - - ras.cProfile = (PProfile)ras.top; - ras.cProfile->offset = ras.top; - ras.num_Profs = 0; - - start = 0; - - for ( i = 0; i < ras.outline.n_contours; i++ ) - { - PProfile lastProfile; - Bool o; - - - ras.state = Unknown_State; - ras.gProfile = NULL; - - if ( Decompose_Curve( RAS_VARS (unsigned short)start, - ras.outline.contours[i], - flipped ) ) - return FAILURE; - - start = ras.outline.contours[i] + 1; - - /* we must now check whether the extreme arcs join or not */ - if ( FRAC( ras.lastY ) == 0 && - ras.lastY >= ras.minY && - ras.lastY <= ras.maxY ) - if ( ras.gProfile && - ( ras.gProfile->flags & Flow_Up ) == - ( ras.cProfile->flags & Flow_Up ) ) - ras.top--; - /* Note that ras.gProfile can be nil if the contour was too small */ - /* to be drawn. */ - - lastProfile = ras.cProfile; - if ( ras.cProfile->flags & Flow_Up ) - o = IS_TOP_OVERSHOOT( ras.lastY ); - else - o = IS_BOTTOM_OVERSHOOT( ras.lastY ); - if ( End_Profile( RAS_VARS o ) ) - return FAILURE; - - /* close the `next profile in contour' linked list */ - if ( ras.gProfile ) - lastProfile->next = ras.gProfile; - } - - if ( Finalize_Profile_Table( RAS_VAR ) ) - return FAILURE; - - return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** SCAN-LINE SWEEPS AND DRAWING **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Init_Linked */ - /* */ - /* Initializes an empty linked list. */ - /* */ - static void - Init_Linked( TProfileList* l ) - { - *l = NULL; - } - - - /*************************************************************************/ - /* */ - /* InsNew */ - /* */ - /* Inserts a new profile in a linked list. */ - /* */ - static void - InsNew( PProfileList list, - PProfile profile ) - { - PProfile *old, current; - Long x; - - - old = list; - current = *old; - x = profile->X; - - while ( current ) - { - if ( x < current->X ) - break; - old = ¤t->link; - current = *old; - } - - profile->link = current; - *old = profile; - } - - - /*************************************************************************/ - /* */ - /* DelOld */ - /* */ - /* Removes an old profile from a linked list. */ - /* */ - static void - DelOld( PProfileList list, - PProfile profile ) - { - PProfile *old, current; - - - old = list; - current = *old; - - while ( current ) - { - if ( current == profile ) - { - *old = current->link; - return; - } - - old = ¤t->link; - current = *old; - } - - /* we should never get there, unless the profile was not part of */ - /* the list. */ - } - - - /*************************************************************************/ - /* */ - /* Sort */ - /* */ - /* Sorts a trace list. In 95%, the list is already sorted. We need */ - /* an algorithm which is fast in this case. Bubble sort is enough */ - /* and simple. */ - /* */ - static void - Sort( PProfileList list ) - { - PProfile *old, current, next; - - - /* First, set the new X coordinate of each profile */ - current = *list; - while ( current ) - { - current->X = *current->offset; - current->offset += current->flags & Flow_Up ? 1 : -1; - current->height--; - current = current->link; - } - - /* Then sort them */ - old = list; - current = *old; - - if ( !current ) - return; - - next = current->link; - - while ( next ) - { - if ( current->X <= next->X ) - { - old = ¤t->link; - current = *old; - - if ( !current ) - return; - } - else - { - *old = next; - current->link = next->link; - next->link = current; - - old = list; - current = *old; - } - - next = current->link; - } - } - - - /*************************************************************************/ - /* */ - /* Vertical Sweep Procedure Set */ - /* */ - /* These four routines are used during the vertical black/white sweep */ - /* phase by the generic Draw_Sweep() function. */ - /* */ - /*************************************************************************/ - - static void - Vertical_Sweep_Init( RAS_ARGS Short* min, - Short* max ) - { - Long pitch = ras.target.pitch; - - FT_UNUSED( max ); - - - ras.traceIncr = (Short)-pitch; - ras.traceOfs = -*min * pitch; - if ( pitch > 0 ) - ras.traceOfs += ( ras.target.rows - 1 ) * pitch; - - ras.gray_min_x = 0; - ras.gray_max_x = 0; - } - - - static void - Vertical_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - Byte* target; - - FT_UNUSED( y ); - FT_UNUSED( left ); - FT_UNUSED( right ); - - - /* Drop-out control */ - - e1 = TRUNC( CEILING( x1 ) ); - - if ( x2 - x1 - ras.precision <= ras.precision_jitter ) - e2 = e1; - else - e2 = TRUNC( FLOOR( x2 ) ); - - if ( e2 >= 0 && e1 < ras.bWidth ) - { - int c1, c2; - Byte f1, f2; - - - if ( e1 < 0 ) - e1 = 0; - if ( e2 >= ras.bWidth ) - e2 = ras.bWidth - 1; - - c1 = (Short)( e1 >> 3 ); - c2 = (Short)( e2 >> 3 ); - - f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); - f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); - - if ( ras.gray_min_x > c1 ) - ras.gray_min_x = (short)c1; - if ( ras.gray_max_x < c2 ) - ras.gray_max_x = (short)c2; - - target = ras.bTarget + ras.traceOfs + c1; - c2 -= c1; - - if ( c2 > 0 ) - { - target[0] |= f1; - - /* memset() is slower than the following code on many platforms. */ - /* This is due to the fact that, in the vast majority of cases, */ - /* the span length in bytes is relatively small. */ - c2--; - while ( c2 > 0 ) - { - *(++target) = 0xFF; - c2--; - } - target[1] |= f2; - } - else - *target |= ( f1 & f2 ); - } - } - - - static void - Vertical_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2, pxl; - Short c1, f1; - - - /* Drop-out control */ - - /* e2 x2 x1 e1 */ - /* */ - /* ^ | */ - /* | | */ - /* +-------------+---------------------+------------+ */ - /* | | */ - /* | v */ - /* */ - /* pixel contour contour pixel */ - /* center center */ - - /* drop-out mode scan conversion rules (as defined in OpenType) */ - /* --------------------------------------------------------------- */ - /* 0 1, 2, 3 */ - /* 1 1, 2, 4 */ - /* 2 1, 2 */ - /* 3 same as mode 2 */ - /* 4 1, 2, 5 */ - /* 5 1, 2, 6 */ - /* 6, 7 same as mode 2 */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - pxl = e1; - - if ( e1 > e2 ) - { - Int dropOutControl = left->flags & 7; - - - if ( e1 == e2 + ras.precision ) - { - switch ( dropOutControl ) - { - case 0: /* simple drop-outs including stubs */ - pxl = e2; - break; - - case 4: /* smart drop-outs including stubs */ - pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; - - case 1: /* simple drop-outs excluding stubs */ - case 5: /* smart drop-outs excluding stubs */ - - /* Drop-out Control Rules #4 and #6 */ - - /* The specification neither provides an exact definition */ - /* of a `stub' nor gives exact rules to exclude them. */ - /* */ - /* Here the constraints we use to recognize a stub. */ - /* */ - /* upper stub: */ - /* */ - /* - P_Left and P_Right are in the same contour */ - /* - P_Right is the successor of P_Left in that contour */ - /* - y is the top of P_Left and P_Right */ - /* */ - /* lower stub: */ - /* */ - /* - P_Left and P_Right are in the same contour */ - /* - P_Left is the successor of P_Right in that contour */ - /* - y is the bottom of P_Left */ - /* */ - /* We draw a stub if the following constraints are met. */ - /* */ - /* - for an upper or lower stub, there is top or bottom */ - /* overshoot, respectively */ - /* - the covered interval is greater or equal to a half */ - /* pixel */ - - /* upper stub test */ - if ( left->next == right && - left->height <= 0 && - !( left->flags & Overshoot_Top && - x2 - x1 >= ras.precision_half ) ) - return; - - /* lower stub test */ - if ( right->next == left && - left->start == y && - !( left->flags & Overshoot_Bottom && - x2 - x1 >= ras.precision_half ) ) - return; - - if ( dropOutControl == 1 ) - pxl = e2; - else - pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; - - default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ - } - - /* undocumented but confirmed: If the drop-out would result in a */ - /* pixel outside of the bounding box, use the pixel inside of the */ - /* bounding box instead */ - if ( pxl < 0 ) - pxl = e1; - else if ( TRUNC( pxl ) >= ras.bWidth ) - pxl = e2; - - /* check that the other pixel isn't set */ - e1 = pxl == e1 ? e2 : e1; - - e1 = TRUNC( e1 ); - - c1 = (Short)( e1 >> 3 ); - f1 = (Short)( e1 & 7 ); - - if ( e1 >= 0 && e1 < ras.bWidth && - ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) - return; - } - else - return; - } - - e1 = TRUNC( pxl ); - - if ( e1 >= 0 && e1 < ras.bWidth ) - { - c1 = (Short)( e1 >> 3 ); - f1 = (Short)( e1 & 7 ); - - if ( ras.gray_min_x > c1 ) - ras.gray_min_x = c1; - if ( ras.gray_max_x < c1 ) - ras.gray_max_x = c1; - - ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); - } - } - - - static void - Vertical_Sweep_Step( RAS_ARG ) - { - ras.traceOfs += ras.traceIncr; - } - - - /***********************************************************************/ - /* */ - /* Horizontal Sweep Procedure Set */ - /* */ - /* These four routines are used during the horizontal black/white */ - /* sweep phase by the generic Draw_Sweep() function. */ - /* */ - /***********************************************************************/ - - static void - Horizontal_Sweep_Init( RAS_ARGS Short* min, - Short* max ) - { - /* nothing, really */ - FT_UNUSED_RASTER; - FT_UNUSED( min ); - FT_UNUSED( max ); - } - - - static void - Horizontal_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - FT_UNUSED( left ); - FT_UNUSED( right ); - - - if ( x2 - x1 < ras.precision ) - { - Long e1, e2; - - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - - if ( e1 == e2 ) - { - Byte f1; - PByte bits; - - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - - e1 = TRUNC( e1 ); - - if ( e1 >= 0 && e1 < ras.target.rows ) - { - PByte p; - - - p = bits - e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - p += ( ras.target.rows - 1 ) * ras.target.pitch; - - p[0] |= f1; - } - } - } - } - - - static void - Horizontal_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2, pxl; - PByte bits; - Byte f1; - - - /* During the horizontal sweep, we only take care of drop-outs */ - - /* e1 + <-- pixel center */ - /* | */ - /* x1 ---+--> <-- contour */ - /* | */ - /* | */ - /* x2 <--+--- <-- contour */ - /* | */ - /* | */ - /* e2 + <-- pixel center */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - pxl = e1; - - if ( e1 > e2 ) - { - Int dropOutControl = left->flags & 7; - - - if ( e1 == e2 + ras.precision ) - { - switch ( dropOutControl ) - { - case 0: /* simple drop-outs including stubs */ - pxl = e2; - break; - - case 4: /* smart drop-outs including stubs */ - pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; - - case 1: /* simple drop-outs excluding stubs */ - case 5: /* smart drop-outs excluding stubs */ - /* see Vertical_Sweep_Drop for details */ - - /* rightmost stub test */ - if ( left->next == right && - left->height <= 0 && - !( left->flags & Overshoot_Top && - x2 - x1 >= ras.precision_half ) ) - return; - - /* leftmost stub test */ - if ( right->next == left && - left->start == y && - !( left->flags & Overshoot_Bottom && - x2 - x1 >= ras.precision_half ) ) - return; - - if ( dropOutControl == 1 ) - pxl = e2; - else - pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; - - default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ - } - - /* undocumented but confirmed: If the drop-out would result in a */ - /* pixel outside of the bounding box, use the pixel inside of the */ - /* bounding box instead */ - if ( pxl < 0 ) - pxl = e1; - else if ( TRUNC( pxl ) >= ras.target.rows ) - pxl = e2; - - /* check that the other pixel isn't set */ - e1 = pxl == e1 ? e2 : e1; - - e1 = TRUNC( e1 ); - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( e1 >= 0 && - e1 < ras.target.rows && - *bits & f1 ) - return; - } - else - return; - } - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - - e1 = TRUNC( pxl ); - - if ( e1 >= 0 && e1 < ras.target.rows ) - { - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; - - bits[0] |= f1; - } - } - - - static void - Horizontal_Sweep_Step( RAS_ARG ) - { - /* Nothing, really */ - FT_UNUSED_RASTER; - } - - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - - /*************************************************************************/ - /* */ - /* Vertical Gray Sweep Procedure Set */ - /* */ - /* These two routines are used during the vertical gray-levels sweep */ - /* phase by the generic Draw_Sweep() function. */ - /* */ - /* NOTES */ - /* */ - /* - The target pixmap's width *must* be a multiple of 4. */ - /* */ - /* - You have to use the function Vertical_Sweep_Span() for the gray */ - /* span call. */ - /* */ - /*************************************************************************/ - - static void - Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, - Short* max ) - { - Long pitch, byte_len; - - - *min = *min & -2; - *max = ( *max + 3 ) & -2; - - ras.traceOfs = 0; - pitch = ras.target.pitch; - byte_len = -pitch; - ras.traceIncr = (Short)byte_len; - ras.traceG = ( *min / 2 ) * byte_len; - - if ( pitch > 0 ) - { - ras.traceG += ( ras.target.rows - 1 ) * pitch; - byte_len = -byte_len; - } - - ras.gray_min_x = (Short)byte_len; - ras.gray_max_x = -(Short)byte_len; - } - - - static void - Vertical_Gray_Sweep_Step( RAS_ARG ) - { - short* count = (short*)count_table; - Byte* grays; - - - ras.traceOfs += ras.gray_width; - - if ( ras.traceOfs > ras.gray_width ) - { - PByte pix; - - - pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; - grays = ras.grays; - - if ( ras.gray_max_x >= 0 ) - { - Long last_pixel = ras.target.width - 1; - Int last_cell = last_pixel >> 2; - Int last_bit = last_pixel & 3; - Bool over = 0; - - Int c1, c2; - PByte bit, bit2; - - - if ( ras.gray_max_x >= last_cell && last_bit != 3 ) - { - ras.gray_max_x = last_cell - 1; - over = 1; - } - - if ( ras.gray_min_x < 0 ) - ras.gray_min_x = 0; - - bit = ras.bTarget + ras.gray_min_x; - bit2 = bit + ras.gray_width; - - c1 = ras.gray_max_x - ras.gray_min_x; - - while ( c1 >= 0 ) - { - c2 = count[*bit] + count[*bit2]; - - if ( c2 ) - { - pix[0] = grays[(c2 >> 12) & 0x000F]; - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - pix[3] = grays[ c2 & 0x000F]; - - *bit = 0; - *bit2 = 0; - } - - bit++; - bit2++; - pix += 4; - c1--; - } - - if ( over ) - { - c2 = count[*bit] + count[*bit2]; - if ( c2 ) - { - switch ( last_bit ) - { - case 2: - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - case 1: - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - default: - pix[0] = grays[(c2 >> 12) & 0x000F]; - } - - *bit = 0; - *bit2 = 0; - } - } - } - - ras.traceOfs = 0; - ras.traceG += ras.traceIncr; - - ras.gray_min_x = 32000; - ras.gray_max_x = -32000; - } - } - - - static void - Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - /* nothing, really */ - FT_UNUSED_RASTER; - FT_UNUSED( y ); - FT_UNUSED( x1 ); - FT_UNUSED( x2 ); - FT_UNUSED( left ); - FT_UNUSED( right ); - } - - - static void - Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - PByte pixel; - - - /* During the horizontal sweep, we only take care of drop-outs */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - - if ( e1 > e2 ) - { - Int dropOutControl = left->flags & 7; - - - if ( e1 == e2 + ras.precision ) - { - switch ( dropOutControl ) - { - case 0: /* simple drop-outs including stubs */ - e1 = e2; - break; - - case 4: /* smart drop-outs including stubs */ - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; - - case 1: /* simple drop-outs excluding stubs */ - case 5: /* smart drop-outs excluding stubs */ - /* see Vertical_Sweep_Drop for details */ - - /* rightmost stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* leftmost stub test */ - if ( right->next == left && left->start == y ) - return; - - if ( dropOutControl == 1 ) - e1 = e2; - else - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - - break; - - default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ - } - } - else - return; - } - - if ( e1 >= 0 ) - { - Byte color; - - - if ( x2 - x1 >= ras.precision_half ) - color = ras.grays[2]; - else - color = ras.grays[1]; - - e1 = TRUNC( e1 ) / 2; - if ( e1 < ras.target.rows ) - { - pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; - if ( ras.target.pitch > 0 ) - pixel += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( pixel[0] == ras.grays[0] ) - pixel[0] = color; - } - } - } - - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - - /*************************************************************************/ - /* */ - /* Generic Sweep Drawing routine */ - /* */ - /*************************************************************************/ - - static Bool - Draw_Sweep( RAS_ARG ) - { - Short y, y_change, y_height; - - PProfile P, Q, P_Left, P_Right; - - Short min_Y, max_Y, top, bottom, dropouts; - - Long x1, x2, xs, e1, e2; - - TProfileList waiting; - TProfileList draw_left, draw_right; - - - /* initialize empty linked lists */ - - Init_Linked( &waiting ); - - Init_Linked( &draw_left ); - Init_Linked( &draw_right ); - - /* first, compute min and max Y */ - - P = ras.fProfile; - max_Y = (Short)TRUNC( ras.minY ); - min_Y = (Short)TRUNC( ras.maxY ); - - while ( P ) - { - Q = P->link; - - bottom = (Short)P->start; - top = (Short)( P->start + P->height - 1 ); - - if ( min_Y > bottom ) - min_Y = bottom; - if ( max_Y < top ) - max_Y = top; - - P->X = 0; - InsNew( &waiting, P ); - - P = Q; - } - - /* check the Y-turns */ - if ( ras.numTurns == 0 ) - { - ras.error = FT_THROW( Invalid ); - return FAILURE; - } - - /* now initialize the sweep */ - - ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); - - /* then compute the distance of each profile from min_Y */ - - P = waiting; - - while ( P ) - { - P->countL = (UShort)( P->start - min_Y ); - P = P->link; - } - - /* let's go */ - - y = min_Y; - y_height = 0; - - if ( ras.numTurns > 0 && - ras.sizeBuff[-ras.numTurns] == min_Y ) - ras.numTurns--; - - while ( ras.numTurns > 0 ) - { - /* check waiting list for new activations */ - - P = waiting; - - while ( P ) - { - Q = P->link; - P->countL -= y_height; - if ( P->countL == 0 ) - { - DelOld( &waiting, P ); - - if ( P->flags & Flow_Up ) - InsNew( &draw_left, P ); - else - InsNew( &draw_right, P ); - } - - P = Q; - } - - /* sort the drawing lists */ - - Sort( &draw_left ); - Sort( &draw_right ); - - y_change = (Short)ras.sizeBuff[-ras.numTurns--]; - y_height = (Short)( y_change - y ); - - while ( y < y_change ) - { - /* let's trace */ - - dropouts = 0; - - P_Left = draw_left; - P_Right = draw_right; - - while ( P_Left ) - { - x1 = P_Left ->X; - x2 = P_Right->X; - - if ( x1 > x2 ) - { - xs = x1; - x1 = x2; - x2 = xs; - } - - e1 = FLOOR( x1 ); - e2 = CEILING( x2 ); - - if ( x2 - x1 <= ras.precision && - e1 != x1 && e2 != x2 ) - { - if ( e1 > e2 || e2 == e1 + ras.precision ) - { - Int dropOutControl = P_Left->flags & 7; - - - if ( dropOutControl != 2 ) - { - /* a drop-out was detected */ - - P_Left ->X = x1; - P_Right->X = x2; - - /* mark profile for drop-out processing */ - P_Left->countL = 1; - dropouts++; - } - - goto Skip_To_Next; - } - } - - ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); - - Skip_To_Next: - - P_Left = P_Left->link; - P_Right = P_Right->link; - } - - /* handle drop-outs _after_ the span drawing -- */ - /* drop-out processing has been moved out of the loop */ - /* for performance tuning */ - if ( dropouts > 0 ) - goto Scan_DropOuts; - - Next_Line: - - ras.Proc_Sweep_Step( RAS_VAR ); - - y++; - - if ( y < y_change ) - { - Sort( &draw_left ); - Sort( &draw_right ); - } - } - - /* now finalize the profiles that need it */ - - P = draw_left; - while ( P ) - { - Q = P->link; - if ( P->height == 0 ) - DelOld( &draw_left, P ); - P = Q; - } - - P = draw_right; - while ( P ) - { - Q = P->link; - if ( P->height == 0 ) - DelOld( &draw_right, P ); - P = Q; - } - } - - /* for gray-scaling, flush the bitmap scanline cache */ - while ( y <= max_Y ) - { - ras.Proc_Sweep_Step( RAS_VAR ); - y++; - } - - return SUCCESS; - - Scan_DropOuts: - - P_Left = draw_left; - P_Right = draw_right; - - while ( P_Left ) - { - if ( P_Left->countL ) - { - P_Left->countL = 0; -#if 0 - dropouts--; /* -- this is useful when debugging only */ -#endif - ras.Proc_Sweep_Drop( RAS_VARS y, - P_Left->X, - P_Right->X, - P_Left, - P_Right ); - } - - P_Left = P_Left->link; - P_Right = P_Right->link; - } - - goto Next_Line; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Render_Single_Pass */ - /* */ - /* <Description> */ - /* Perform one sweep with sub-banding. */ - /* */ - /* <Input> */ - /* flipped :: If set, flip the direction of the outline. */ - /* */ - /* <Return> */ - /* Renderer error code. */ - /* */ - static int - Render_Single_Pass( RAS_ARGS Bool flipped ) - { - Short i, j, k; - - - while ( ras.band_top >= 0 ) - { - ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; - ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; - - ras.top = ras.buff; - - ras.error = Raster_Err_None; - - if ( Convert_Glyph( RAS_VARS flipped ) ) - { - if ( ras.error != Raster_Err_Overflow ) - return FAILURE; - - ras.error = Raster_Err_None; - - /* sub-banding */ - -#ifdef DEBUG_RASTER - ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); -#endif - - i = ras.band_stack[ras.band_top].y_min; - j = ras.band_stack[ras.band_top].y_max; - - k = (Short)( ( i + j ) / 2 ); - - if ( ras.band_top >= 7 || k < i ) - { - ras.band_top = 0; - ras.error = FT_THROW( Invalid ); - - return ras.error; - } - - ras.band_stack[ras.band_top + 1].y_min = k; - ras.band_stack[ras.band_top + 1].y_max = j; - - ras.band_stack[ras.band_top].y_max = (Short)( k - 1 ); - - ras.band_top++; - } - else - { - if ( ras.fProfile ) - if ( Draw_Sweep( RAS_VAR ) ) - return ras.error; - ras.band_top--; - } - } - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Render_Glyph */ - /* */ - /* <Description> */ - /* Render a glyph in a bitmap. Sub-banding if needed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - Render_Glyph( RAS_ARG ) - { - FT_Error error; - - - Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift; - - if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) - ras.dropOutControl = 2; - else - { - if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) - ras.dropOutControl = 4; - else - ras.dropOutControl = 0; - - if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) - ras.dropOutControl += 1; - } - - ras.second_pass = (FT_Byte)( !( ras.outline.flags & - FT_OUTLINE_SINGLE_PASS ) ); - - /* Vertical Sweep */ - ras.Proc_Sweep_Init = Vertical_Sweep_Init; - ras.Proc_Sweep_Span = Vertical_Sweep_Span; - ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; - ras.Proc_Sweep_Step = Vertical_Sweep_Step; - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); - - ras.bWidth = (unsigned short)ras.target.width; - ras.bTarget = (Byte*)ras.target.buffer; - - if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) - return error; - - /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 2 ) - { - ras.Proc_Sweep_Init = Horizontal_Sweep_Init; - ras.Proc_Sweep_Span = Horizontal_Sweep_Span; - ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; - ras.Proc_Sweep_Step = Horizontal_Sweep_Step; - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); - - if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) - return error; - } - - return Raster_Err_None; - } - - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Render_Gray_Glyph */ - /* */ - /* <Description> */ - /* Render a glyph with grayscaling. Sub-banding if needed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - Render_Gray_Glyph( RAS_ARG ) - { - Long pixel_width; - FT_Error error; - - - Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift + 1; - - if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) - ras.dropOutControl = 2; - else - { - if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) - ras.dropOutControl = 4; - else - ras.dropOutControl = 0; - - if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) - ras.dropOutControl += 1; - } - - ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); - - /* Vertical Sweep */ - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = 2 * ras.target.rows - 1; - - ras.bWidth = ras.gray_width; - pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); - - if ( ras.bWidth > pixel_width ) - ras.bWidth = pixel_width; - - ras.bWidth = ras.bWidth * 8; - ras.bTarget = (Byte*)ras.gray_lines; - ras.gTarget = (Byte*)ras.target.buffer; - - ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; - ras.Proc_Sweep_Span = Vertical_Sweep_Span; - ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; - ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; - - error = Render_Single_Pass( RAS_VARS 0 ); - if ( error ) - return error; - - /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 2 ) - { - ras.Proc_Sweep_Init = Horizontal_Sweep_Init; - ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; - ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; - ras.Proc_Sweep_Step = Horizontal_Sweep_Step; - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = ras.target.width * 2 - 1; - - error = Render_Single_Pass( RAS_VARS 1 ); - if ( error ) - return error; - } - - return Raster_Err_None; - } - -#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ - - FT_LOCAL_DEF( FT_Error ) - Render_Gray_Glyph( RAS_ARG ) - { - FT_UNUSED_RASTER; - - return FT_THROW( Unsupported ); - } - -#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ - - - static void - ft_black_init( black_PRaster 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; - - raster->gray_width = RASTER_GRAY_LINES / 2; -#else - FT_UNUSED( raster ); -#endif - } - - - /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ - /**** a static object. *****/ - - -#ifdef _STANDALONE_ - - - static int - ft_black_new( void* memory, - FT_Raster *araster ) - { - static black_TRaster the_raster; - FT_UNUSED( memory ); - - - *araster = (FT_Raster)&the_raster; - FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); - ft_black_init( &the_raster ); - - return 0; - } - - - static void - ft_black_done( FT_Raster raster ) - { - /* nothing */ - FT_UNUSED( raster ); - } - - -#else /* !_STANDALONE_ */ - - - static int - ft_black_new( FT_Memory memory, - black_PRaster *araster ) - { - FT_Error error; - black_PRaster raster = NULL; - - - *araster = 0; - if ( !FT_NEW( raster ) ) - { - raster->memory = memory; - ft_black_init( raster ); - - *araster = raster; - } - - return error; - } - - - static void - ft_black_done( black_PRaster raster ) - { - FT_Memory memory = (FT_Memory)raster->memory; - - - FT_FREE( raster ); - } - - -#endif /* !_STANDALONE_ */ - - - static void - ft_black_reset( black_PRaster raster, - char* pool_base, - long pool_size ) - { - if ( raster ) - { - if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 ) - { - black_PWorker worker = (black_PWorker)pool_base; - - - raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 ); - raster->buffer_size = (long)( pool_base + pool_size - - (char*)raster->buffer ); - raster->worker = worker; - } - else - { - raster->buffer = NULL; - raster->buffer_size = 0; - raster->worker = NULL; - } - } - } - - - static void - ft_black_set_mode( black_PRaster raster, - unsigned long mode, - const char* palette ) - { -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) - { - /* set 5-levels gray palette */ - 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 - - FT_UNUSED( raster ); - FT_UNUSED( mode ); - FT_UNUSED( palette ); - -#endif - } - - - static int - ft_black_render( black_PRaster raster, - const FT_Raster_Params* params ) - { - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; - black_PWorker worker; - - - if ( !raster || !raster->buffer || !raster->buffer_size ) - return FT_THROW( Not_Ini ); - - if ( !outline ) - return FT_THROW( Invalid ); - - /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return Raster_Err_None; - - if ( !outline->contours || !outline->points ) - return FT_THROW( Invalid ); - - if ( outline->n_points != - outline->contours[outline->n_contours - 1] + 1 ) - return FT_THROW( Invalid ); - - worker = raster->worker; - - /* this version of the raster does not support direct rendering, sorry */ - if ( params->flags & FT_RASTER_FLAG_DIRECT ) - return FT_THROW( Unsupported ); - - if ( !target_map ) - return FT_THROW( Invalid ); - - /* nothing to do */ - if ( !target_map->width || !target_map->rows ) - return Raster_Err_None; - - if ( !target_map->buffer ) - return FT_THROW( Invalid ); - - 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; - - FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); -#endif - - return ( params->flags & FT_RASTER_FLAG_AA ) - ? Render_Gray_Glyph( RAS_VAR ) - : Render_Glyph( RAS_VAR ); - } - - - FT_DEFINE_RASTER_FUNCS( ft_standard_raster, - FT_GLYPH_FORMAT_OUTLINE, - (FT_Raster_New_Func) ft_black_new, - (FT_Raster_Reset_Func) ft_black_reset, - (FT_Raster_Set_Mode_Func)ft_black_set_mode, - (FT_Raster_Render_Func) ft_black_render, - (FT_Raster_Done_Func) ft_black_done - ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/ftraster.h b/drivers/freetype/freetype/src/raster/ftraster.h deleted file mode 100644 index 80fe46deba..0000000000 --- a/drivers/freetype/freetype/src/raster/ftraster.h +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftraster.h */ -/* */ -/* The FreeType glyph rasterizer (specification). */ -/* */ -/* Copyright 1996-2001 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 __FTRASTER_H__ -#define __FTRASTER_H__ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_IMAGE_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* Uncomment the following line if you are using ftraster.c as a */ - /* standalone module, fully independent of FreeType. */ - /* */ -/* #define _STANDALONE_ */ - - FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; - - -FT_END_HEADER - -#endif /* __FTRASTER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/ftrend1.c b/drivers/freetype/freetype/src/raster/ftrend1.c deleted file mode 100644 index aa7f6d5664..0000000000 --- a/drivers/freetype/freetype/src/raster/ftrend1.c +++ /dev/null @@ -1,306 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrend1.c */ -/* */ -/* The FreeType glyph rasterizer interface (body). */ -/* */ -/* Copyright 1996-2003, 2005, 2006, 2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_OUTLINE_H -#include "ftrend1.h" -#include "ftraster.h" -#include "rastpic.h" - -#include "rasterrs.h" - - - /* initialize renderer -- init its raster */ - static FT_Error - ft_raster1_init( FT_Renderer render ) - { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); - - return FT_Err_Ok; - } - - - /* set render-specific mode */ - static FT_Error - ft_raster1_set_mode( FT_Renderer render, - FT_ULong mode_tag, - FT_Pointer data ) - { - /* we simply pass it to the raster */ - return render->clazz->raster_class->raster_set_mode( render->raster, - mode_tag, - data ); - } - - - /* transform a given glyph image */ - static FT_Error - ft_raster1_transform( FT_Renderer render, - FT_GlyphSlot slot, - const FT_Matrix* matrix, - const FT_Vector* delta ) - { - FT_Error error = FT_Err_Ok; - - - if ( slot->format != render->glyph_format ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( matrix ) - FT_Outline_Transform( &slot->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &slot->outline, delta->x, delta->y ); - - Exit: - return error; - } - - - /* return the glyph's control box */ - static void - ft_raster1_get_cbox( FT_Renderer render, - FT_GlyphSlot slot, - FT_BBox* cbox ) - { - FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); - - if ( slot->format == render->glyph_format ) - FT_Outline_Get_CBox( &slot->outline, cbox ); - } - - - /* convert a slot's glyph image into a bitmap */ - static FT_Error - ft_raster1_render( FT_Renderer render, - FT_GlyphSlot slot, - FT_Render_Mode mode, - const FT_Vector* origin ) - { - FT_Error error; - FT_Outline* outline; - FT_BBox cbox; - FT_UInt width, height, pitch; - FT_Bitmap* bitmap; - FT_Memory memory; - - FT_Raster_Params params; - - - /* check glyph image format */ - if ( slot->format != render->glyph_format ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* check rendering mode */ -#ifndef FT_CONFIG_OPTION_PIC - if ( mode != FT_RENDER_MODE_MONO ) - { - /* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz == &ft_raster1_renderer_class ) - return FT_THROW( Cannot_Render_Glyph ); - } - else - { - /* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz == &ft_raster5_renderer_class ) - return FT_THROW( Cannot_Render_Glyph ); - } -#else /* FT_CONFIG_OPTION_PIC */ - /* When PIC is enabled, we cannot get to the class object */ - /* so instead we check the final character in the class name */ - /* ("raster5" or "raster1"). Yes this is a hack. */ - /* The "correct" thing to do is have different render function */ - /* for each of the classes. */ - if ( mode != FT_RENDER_MODE_MONO ) - { - /* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz->root.module_name[6] == '1' ) - return FT_THROW( Cannot_Render_Glyph ); - } - else - { - /* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz->root.module_name[6] == '5' ) - return FT_THROW( Cannot_Render_Glyph ); - } -#endif /* FT_CONFIG_OPTION_PIC */ - - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ - if ( origin ) - FT_Outline_Translate( outline, origin->x, origin->y ); - - /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); - - /* undocumented but confirmed: bbox values get rounded */ -#if 1 - cbox.xMin = FT_PIX_ROUND( cbox.xMin ); - cbox.yMin = FT_PIX_ROUND( cbox.yMin ); - cbox.xMax = FT_PIX_ROUND( cbox.xMax ); - cbox.yMax = FT_PIX_ROUND( cbox.yMax ); -#else - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL( cbox.yMax ); -#endif - - width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); - height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); - - if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - bitmap = &slot->bitmap; - memory = render->root.memory; - - /* release old bitmap buffer */ - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { - FT_FREE( bitmap->buffer ); - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - - /* allocate new one, depends on pixel format */ - if ( !( mode & FT_RENDER_MODE_MONO ) ) - { - /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ - pitch = FT_PAD_CEIL( width, 4 ); - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->num_grays = 256; - } - else - { - pitch = ( ( width + 15 ) >> 4 ) << 1; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - } - - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = pitch; - - if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) - goto Exit; - - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); - - /* set up parameters */ - params.target = bitmap; - params.source = outline; - params.flags = 0; - - if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) - params.flags |= FT_RASTER_FLAG_AA; - - /* render outline into the bitmap */ - error = render->raster_render( render->raster, ¶ms ); - - FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); - - if ( error ) - goto Exit; - - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); - slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); - - Exit: - return error; - } - - - FT_DEFINE_RENDERER( ft_raster1_renderer_class, - - FT_MODULE_RENDERER, - sizeof ( FT_RendererRec ), - - "raster1", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , - - FT_GLYPH_FORMAT_OUTLINE, - - (FT_Renderer_RenderFunc) ft_raster1_render, - (FT_Renderer_TransformFunc)ft_raster1_transform, - (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, - (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - - (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET - ) - - - /* This renderer is _NOT_ part of the default modules; you will need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - /* */ - FT_DEFINE_RENDERER( ft_raster5_renderer_class, - - FT_MODULE_RENDERER, - sizeof ( FT_RendererRec ), - - "raster5", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , - - FT_GLYPH_FORMAT_OUTLINE, - - (FT_Renderer_RenderFunc) ft_raster1_render, - (FT_Renderer_TransformFunc)ft_raster1_transform, - (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, - (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - - (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET - ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/ftrend1.h b/drivers/freetype/freetype/src/raster/ftrend1.h deleted file mode 100644 index 4cf128622a..0000000000 --- a/drivers/freetype/freetype/src/raster/ftrend1.h +++ /dev/null @@ -1,44 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrend1.h */ -/* */ -/* The FreeType glyph rasterizer interface (specification). */ -/* */ -/* Copyright 1996-2001 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 __FTREND1_H__ -#define __FTREND1_H__ - - -#include <ft2build.h> -#include FT_RENDER_H - - -FT_BEGIN_HEADER - - - FT_DECLARE_RENDERER( ft_raster1_renderer_class ) - - /* this renderer is _NOT_ part of the default modules, you'll need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - /* */ - FT_DECLARE_RENDERER( ft_raster5_renderer_class ) - - -FT_END_HEADER - -#endif /* __FTREND1_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/module.mk b/drivers/freetype/freetype/src/raster/module.mk deleted file mode 100644 index cbff5df96e..0000000000 --- a/drivers/freetype/freetype/src/raster/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 renderer module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += RASTER_MODULE - -define RASTER_MODULE -$(OPEN_DRIVER) FT_Renderer_Class, ft_raster1_renderer_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)raster $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/raster/raster.c b/drivers/freetype/freetype/src/raster/raster.c deleted file mode 100644 index 1202a116cd..0000000000 --- a/drivers/freetype/freetype/src/raster/raster.c +++ /dev/null @@ -1,27 +0,0 @@ -/***************************************************************************/ -/* */ -/* raster.c */ -/* */ -/* FreeType monochrome rasterer module component (body only). */ -/* */ -/* Copyright 1996-2001 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "rastpic.c" -#include "ftraster.c" -#include "ftrend1.c" - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/rasterrs.h b/drivers/freetype/freetype/src/raster/rasterrs.h deleted file mode 100644 index ab85c002a3..0000000000 --- a/drivers/freetype/freetype/src/raster/rasterrs.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* rasterrs.h */ -/* */ -/* monochrome renderer error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the monochrome renderer error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ - -#ifndef __RASTERRS_H__ -#define __RASTERRS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX Raster_Err_ -#define FT_ERR_BASE FT_Mod_Err_Raster - -#include FT_ERRORS_H - -#endif /* __RASTERRS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/rastpic.c b/drivers/freetype/freetype/src/raster/rastpic.c deleted file mode 100644 index 5e9f7cc9c4..0000000000 --- a/drivers/freetype/freetype/src/raster/rastpic.c +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************/ -/* */ -/* rastpic.c */ -/* */ -/* The FreeType position independent code services for raster module. */ -/* */ -/* Copyright 2009, 2010, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "rastpic.h" -#include "rasterrs.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from ftraster.c */ - void - FT_Init_Class_ft_standard_raster( FT_Raster_Funcs* funcs ); - - - void - ft_raster1_renderer_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->raster ) - { - RasterPIC* container = (RasterPIC*)pic_container->raster; - - - if ( --container->ref_count ) - return; - FT_FREE( container ); - pic_container->raster = NULL; - } - } - - - FT_Error - ft_raster1_renderer_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - RasterPIC* container = NULL; - FT_Memory memory = library->memory; - - - /* since this function also serves raster5 renderer, */ - /* it implements reference counting */ - if ( pic_container->raster ) - { - ((RasterPIC*)pic_container->raster)->ref_count++; - return error; - } - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->raster = container; - - container->ref_count = 1; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - FT_Init_Class_ft_standard_raster( &container->ft_standard_raster ); - - return error; - } - - - /* re-route these init and free functions to the above functions */ - FT_Error - ft_raster5_renderer_class_pic_init( FT_Library library ) - { - return ft_raster1_renderer_class_pic_init( library ); - } - - - void - ft_raster5_renderer_class_pic_free( FT_Library library ) - { - ft_raster1_renderer_class_pic_free( library ); - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/rastpic.h b/drivers/freetype/freetype/src/raster/rastpic.h deleted file mode 100644 index e0ddba624e..0000000000 --- a/drivers/freetype/freetype/src/raster/rastpic.h +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************/ -/* */ -/* rastpic.h */ -/* */ -/* The FreeType position independent code services for raster module. */ -/* */ -/* Copyright 2009 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __RASTPIC_H__ -#define __RASTPIC_H__ - - -FT_BEGIN_HEADER - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_STANDARD_RASTER_GET ft_standard_raster - -#else /* FT_CONFIG_OPTION_PIC */ - - typedef struct RasterPIC_ - { - int ref_count; - FT_Raster_Funcs ft_standard_raster; - - } RasterPIC; - - -#define GET_PIC( lib ) \ - ( (RasterPIC*)( (lib)->pic_container.raster ) ) -#define FT_STANDARD_RASTER_GET ( GET_PIC( library )->ft_standard_raster ) - - - /* see rastpic.c for the implementation */ - void - ft_raster1_renderer_class_pic_free( FT_Library library ); - - void - ft_raster5_renderer_class_pic_free( FT_Library library ); - - FT_Error - ft_raster1_renderer_class_pic_init( FT_Library library ); - - FT_Error - ft_raster5_renderer_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __RASTPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/raster/rules.mk b/drivers/freetype/freetype/src/raster/rules.mk deleted file mode 100644 index 0e0b5e4ebd..0000000000 --- a/drivers/freetype/freetype/src/raster/rules.mk +++ /dev/null @@ -1,70 +0,0 @@ -# -# FreeType 2 renderer module build rules -# - - -# Copyright 1996-2000, 2001, 2003, 2008, 2009, 2011 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. - - -# raster driver directory -# -RASTER_DIR := $(SRC_DIR)/raster - -# compilation flags for the driver -# -RASTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR)) - - -# raster driver sources (i.e., C files) -# -RASTER_DRV_SRC := $(RASTER_DIR)/ftraster.c \ - $(RASTER_DIR)/ftrend1.c \ - $(RASTER_DIR)/rastpic.c - - -# raster driver headers -# -RASTER_DRV_H := $(RASTER_DRV_SRC:%.c=%.h) \ - $(RASTER_DIR)/rasterrs.h - - -# raster driver object(s) -# -# RASTER_DRV_OBJ_M is used during `multi' builds. -# RASTER_DRV_OBJ_S is used during `single' builds. -# -RASTER_DRV_OBJ_M := $(RASTER_DRV_SRC:$(RASTER_DIR)/%.c=$(OBJ_DIR)/%.$O) -RASTER_DRV_OBJ_S := $(OBJ_DIR)/raster.$O - -# raster driver source file for single build -# -RASTER_DRV_SRC_S := $(RASTER_DIR)/raster.c - - -# raster driver - single object -# -$(RASTER_DRV_OBJ_S): $(RASTER_DRV_SRC_S) $(RASTER_DRV_SRC) \ - $(FREETYPE_H) $(RASTER_DRV_H) - $(RASTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(RASTER_DRV_SRC_S)) - - -# raster driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(RASTER_DIR)/%.c $(FREETYPE_H) $(RASTER_DRV_H) - $(RASTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(RASTER_DRV_OBJ_S) -DRV_OBJS_M += $(RASTER_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/sfnt/Jamfile b/drivers/freetype/freetype/src/sfnt/Jamfile deleted file mode 100644 index cb20b1b04b..0000000000 --- a/drivers/freetype/freetype/src/sfnt/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/sfnt Jamfile -# -# Copyright 2001, 2002, 2004, 2005 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - -SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = sfobjs sfdriver ttcmap ttmtx ttpost ttload ttsbit ttkern ttbdf sfntpic ; - } - else - { - _sources = sfnt ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/sfnt Jamfile diff --git a/drivers/freetype/freetype/src/sfnt/module.mk b/drivers/freetype/freetype/src/sfnt/module.mk deleted file mode 100644 index 95fd6a3143..0000000000 --- a/drivers/freetype/freetype/src/sfnt/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 SFNT module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += SFNT_MODULE - -define SFNT_MODULE -$(OPEN_DRIVER) FT_Module_Class, sfnt_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/sfnt/pngshim.c b/drivers/freetype/freetype/src/sfnt/pngshim.c deleted file mode 100644 index 408f879c34..0000000000 --- a/drivers/freetype/freetype/src/sfnt/pngshim.c +++ /dev/null @@ -1,336 +0,0 @@ -/***************************************************************************/ -/* */ -/* pngshim.c */ -/* */ -/* PNG Bitmap glyph support. */ -/* */ -/* Copyright 2013 by Google, Inc. */ -/* Written by Stuart Gill and Behdad Esfahbod. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include FT_CONFIG_STANDARD_LIBRARY_H - - -#ifdef FT_CONFIG_OPTION_USE_PNG - - /* We always include <stjmp.h>, so make libpng shut up! */ -#define PNG_SKIP_SETJMP_CHECK 1 -#include <png.h> -#include "pngshim.h" - -#include "sferrors.h" - - - /* This code is freely based on cairo-png.c. There's so many ways */ - /* to call libpng, and the way cairo does it is defacto standard. */ - - static int - multiply_alpha( int alpha, - int color ) - { - int temp = ( alpha * color ) + 0x80; - - - return ( temp + ( temp >> 8 ) ) >> 8; - } - - - /* Premultiplies data and converts RGBA bytes => native endian. */ - static void - premultiply_data( png_structp png, - png_row_infop row_info, - png_bytep data ) - { - unsigned int i; - - FT_UNUSED( png ); - - - for ( i = 0; i < row_info->rowbytes; i += 4 ) - { - unsigned char* base = &data[i]; - unsigned int alpha = base[3]; - - - if ( alpha == 0 ) - base[0] = base[1] = base[2] = base[3] = 0; - - else - { - unsigned int red = base[0]; - unsigned int green = base[1]; - unsigned int blue = base[2]; - - - if ( alpha != 0xFF ) - { - red = multiply_alpha( alpha, red ); - green = multiply_alpha( alpha, green ); - blue = multiply_alpha( alpha, blue ); - } - - base[0] = blue; - base[1] = green; - base[2] = red; - base[3] = alpha; - } - } - } - - - /* Converts RGBx bytes to BGRA. */ - static void - convert_bytes_to_data( png_structp png, - png_row_infop row_info, - png_bytep data ) - { - unsigned int i; - - FT_UNUSED( png ); - - - for ( i = 0; i < row_info->rowbytes; i += 4 ) - { - unsigned char* base = &data[i]; - unsigned int red = base[0]; - unsigned int green = base[1]; - unsigned int blue = base[2]; - - - base[0] = blue; - base[1] = green; - base[2] = red; - base[3] = 0xFF; - } - } - - - /* Use error callback to avoid png writing to stderr. */ - static void - error_callback( png_structp png, - png_const_charp error_msg ) - { - FT_Error* error = png_get_error_ptr( png ); - - FT_UNUSED( error_msg ); - - - *error = FT_THROW( Out_Of_Memory ); -#ifdef PNG_SETJMP_SUPPORTED - longjmp( png_jmpbuf( png ), 1 ); -#endif - /* if we get here, then we have no choice but to abort ... */ - } - - - /* Use warning callback to avoid png writing to stderr. */ - static void - warning_callback( png_structp png, - png_const_charp error_msg ) - { - FT_UNUSED( png ); - FT_UNUSED( error_msg ); - - /* Just ignore warnings. */ - } - - - static void - read_data_from_FT_Stream( png_structp png, - png_bytep data, - png_size_t length ) - { - FT_Error error; - png_voidp p = png_get_io_ptr( png ); - FT_Stream stream = (FT_Stream)p; - - - if ( FT_FRAME_ENTER( length ) ) - { - FT_Error* e = png_get_error_ptr( png ); - - - *e = FT_THROW( Invalid_Stream_Read ); - png_error( png, NULL ); - - return; - } - - memcpy( data, stream->cursor, length ); - - FT_FRAME_EXIT(); - } - - - static FT_Error - Load_SBit_Png( FT_Bitmap* map, - FT_Int x_offset, - FT_Int y_offset, - FT_Int pix_bits, - TT_SBit_Metrics metrics, - FT_Memory memory, - FT_Byte* data, - FT_UInt png_len ) - { - FT_Error error = FT_Err_Ok; - FT_StreamRec stream; - - png_structp png; - png_infop info; - png_uint_32 imgWidth, imgHeight; - - int bitdepth, color_type, interlace; - FT_Int i; - png_byte* *rows; - - - if ( x_offset < 0 || x_offset + metrics->width > map->width || - y_offset < 0 || y_offset + metrics->height > map->rows || - pix_bits != 32 || map->pixel_mode != FT_PIXEL_MODE_BGRA ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - FT_Stream_OpenMemory( &stream, data, png_len ); - - png = png_create_read_struct( PNG_LIBPNG_VER_STRING, - &error, - error_callback, - warning_callback ); - if ( !png ) - { - error = FT_THROW( Out_Of_Memory ); - goto Exit; - } - - info = png_create_info_struct( png ); - if ( !info ) - { - error = FT_THROW( Out_Of_Memory ); - png_destroy_read_struct( &png, NULL, NULL ); - goto Exit; - } - - if ( ft_setjmp( png_jmpbuf( png ) ) ) - { - error = FT_THROW( Invalid_File_Format ); - goto DestroyExit; - } - - png_set_read_fn( png, &stream, read_data_from_FT_Stream ); - - png_read_info( png, info ); - png_get_IHDR( png, info, - &imgWidth, &imgHeight, - &bitdepth, &color_type, &interlace, - NULL, NULL ); - - if ( error != FT_Err_Ok || - (FT_Int)imgWidth != metrics->width || - (FT_Int)imgHeight != metrics->height ) - goto DestroyExit; - - /* convert palette/gray image to rgb */ - if ( color_type == PNG_COLOR_TYPE_PALETTE ) - png_set_palette_to_rgb( png ); - - /* expand gray bit depth if needed */ - if ( color_type == PNG_COLOR_TYPE_GRAY ) - { -#if PNG_LIBPNG_VER >= 10209 - png_set_expand_gray_1_2_4_to_8( png ); -#else - png_set_gray_1_2_4_to_8( png ); -#endif - } - - /* transform transparency to alpha */ - if ( png_get_valid(png, info, PNG_INFO_tRNS ) ) - png_set_tRNS_to_alpha( png ); - - if ( bitdepth == 16 ) - png_set_strip_16( png ); - - if ( bitdepth < 8 ) - png_set_packing( png ); - - /* convert grayscale to RGB */ - if ( color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) - png_set_gray_to_rgb( png ); - - if ( interlace != PNG_INTERLACE_NONE ) - png_set_interlace_handling( png ); - - png_set_filler( png, 0xFF, PNG_FILLER_AFTER ); - - /* recheck header after setting EXPAND options */ - png_read_update_info(png, info ); - png_get_IHDR( png, info, - &imgWidth, &imgHeight, - &bitdepth, &color_type, &interlace, - NULL, NULL ); - - if ( bitdepth != 8 || - !( color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA ) ) - { - error = FT_THROW( Invalid_File_Format ); - goto DestroyExit; - } - - switch ( color_type ) - { - default: - /* Shouldn't happen, but fall through. */ - - case PNG_COLOR_TYPE_RGB_ALPHA: - png_set_read_user_transform_fn( png, premultiply_data ); - break; - - case PNG_COLOR_TYPE_RGB: - /* Humm, this smells. Carry on though. */ - png_set_read_user_transform_fn( png, convert_bytes_to_data ); - break; - } - - if ( FT_NEW_ARRAY( rows, imgHeight ) ) - { - error = FT_THROW( Out_Of_Memory ); - goto DestroyExit; - } - - for ( i = 0; i < (FT_Int)imgHeight; i++ ) - rows[i] = map->buffer + ( y_offset + i ) * map->pitch + x_offset * 4; - - png_read_image( png, rows ); - - FT_FREE( rows ); - - png_read_end( png, info ); - - DestroyExit: - png_destroy_read_struct( &png, &info, NULL ); - FT_Stream_Close( &stream ); - - Exit: - return error; - } - -#endif /* FT_CONFIG_OPTION_USE_PNG */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/pngshim.h b/drivers/freetype/freetype/src/sfnt/pngshim.h deleted file mode 100644 index 8a2e69ccf9..0000000000 --- a/drivers/freetype/freetype/src/sfnt/pngshim.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************/ -/* */ -/* pngshim.h */ -/* */ -/* PNG Bitmap glyph support. */ -/* */ -/* Copyright 2013 by Google, Inc. */ -/* Written by Stuart Gill and Behdad Esfahbod. */ -/* */ -/* 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 __PNGSHIM_H__ -#define __PNGSHIM_H__ - - -#include <ft2build.h> -#include "ttload.h" - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_USE_PNG - - FT_LOCAL( FT_Error ) - Load_SBit_Png( FT_Bitmap* map, - FT_Int x_offset, - FT_Int y_offset, - FT_Int pix_bits, - TT_SBit_Metrics metrics, - FT_Memory memory, - FT_Byte* data, - FT_UInt png_len ); - -#endif - -FT_END_HEADER - -#endif /* __PNGSHIM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/rules.mk b/drivers/freetype/freetype/src/sfnt/rules.mk deleted file mode 100644 index a6c956ab65..0000000000 --- a/drivers/freetype/freetype/src/sfnt/rules.mk +++ /dev/null @@ -1,78 +0,0 @@ -# -# FreeType 2 SFNT driver configuration rules -# - - -# Copyright 1996-2000, 2002-2007, 2009, 2011, 2013 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. - - -# SFNT driver directory -# -SFNT_DIR := $(SRC_DIR)/sfnt - - -# compilation flags for the driver -# -SFNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) - - -# SFNT driver sources (i.e., C files) -# -SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \ - $(SFNT_DIR)/ttmtx.c \ - $(SFNT_DIR)/ttcmap.c \ - $(SFNT_DIR)/ttsbit.c \ - $(SFNT_DIR)/ttpost.c \ - $(SFNT_DIR)/ttkern.c \ - $(SFNT_DIR)/ttbdf.c \ - $(SFNT_DIR)/sfobjs.c \ - $(SFNT_DIR)/sfdriver.c \ - $(SFNT_DIR)/sfntpic.c \ - $(SFNT_DIR)/pngshim.c - -# SFNT driver headers -# -SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ - $(SFNT_DIR)/sferrors.h - - -# SFNT driver object(s) -# -# SFNT_DRV_OBJ_M is used during `multi' builds. -# SFNT_DRV_OBJ_S is used during `single' builds. -# -SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR)/%.c=$(OBJ_DIR)/%.$O) -SFNT_DRV_OBJ_S := $(OBJ_DIR)/sfnt.$O - -# SFNT driver source file for single build -# -SFNT_DRV_SRC_S := $(SFNT_DIR)/sfnt.c - - -# SFNT driver - single object -# -$(SFNT_DRV_OBJ_S): $(SFNT_DRV_SRC_S) $(SFNT_DRV_SRC) \ - $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SFNT_DRV_SRC_S)) - - -# SFNT driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(SFNT_DIR)/%.c $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(SFNT_DRV_OBJ_S) -DRV_OBJS_M += $(SFNT_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/sfnt/sfdriver.c b/drivers/freetype/freetype/src/sfnt/sfdriver.c deleted file mode 100644 index a368b8caea..0000000000 --- a/drivers/freetype/freetype/src/sfnt/sfdriver.c +++ /dev/null @@ -1,529 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfdriver.c */ -/* */ -/* High-level SFNT driver interface (body). */ -/* */ -/* Copyright 1996-2007, 2009-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_SFNT_H -#include FT_INTERNAL_OBJECTS_H - -#include "sfdriver.h" -#include "ttload.h" -#include "sfobjs.h" -#include "sfntpic.h" - -#include "sferrors.h" - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#include "ttsbit.h" -#endif - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES -#include "ttpost.h" -#endif - -#ifdef TT_CONFIG_OPTION_BDF -#include "ttbdf.h" -#include FT_SERVICE_BDF_H -#endif - -#include "ttcmap.h" -#include "ttkern.h" -#include "ttmtx.h" - -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_TT_CMAP_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_sfdriver - - - /* - * SFNT TABLE SERVICE - * - */ - - static void* - get_sfnt_table( TT_Face face, - FT_Sfnt_Tag tag ) - { - void* table; - - - switch ( tag ) - { - case ft_sfnt_head: - table = &face->header; - break; - - case ft_sfnt_hhea: - table = &face->horizontal; - break; - - case ft_sfnt_vhea: - table = face->vertical_info ? &face->vertical : 0; - break; - - case ft_sfnt_os2: - table = face->os2.version == 0xFFFFU ? 0 : &face->os2; - break; - - case ft_sfnt_post: - table = &face->postscript; - break; - - case ft_sfnt_maxp: - table = &face->max_profile; - break; - - case ft_sfnt_pclt: - table = face->pclt.Version ? &face->pclt : 0; - break; - - default: - table = 0; - } - - return table; - } - - - static FT_Error - sfnt_table_info( TT_Face face, - FT_UInt idx, - FT_ULong *tag, - FT_ULong *offset, - FT_ULong *length ) - { - if ( !offset || !length ) - return FT_THROW( Invalid_Argument ); - - if ( !tag ) - *length = face->num_tables; - else - { - if ( idx >= face->num_tables ) - return FT_THROW( Table_Missing ); - - *tag = face->dir_tables[idx].Tag; - *offset = face->dir_tables[idx].Offset; - *length = face->dir_tables[idx].Length; - } - - return FT_Err_Ok; - } - - - FT_DEFINE_SERVICE_SFNT_TABLEREC( - sfnt_service_sfnt_table, - (FT_SFNT_TableLoadFunc)tt_face_load_any, - (FT_SFNT_TableGetFunc) get_sfnt_table, - (FT_SFNT_TableInfoFunc)sfnt_table_info ) - - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - /* - * GLYPH DICT SERVICE - * - */ - - static FT_Error - sfnt_get_glyph_name( TT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_String* gname; - FT_Error error; - - - error = tt_face_get_ps_name( face, glyph_index, &gname ); - if ( !error ) - FT_STRCPYN( buffer, gname, buffer_max ); - - return error; - } - - - static FT_UInt - sfnt_get_name_index( TT_Face face, - FT_String* glyph_name ) - { - FT_Face root = &face->root; - - FT_UInt i, max_gid = FT_UINT_MAX; - - - if ( root->num_glyphs < 0 ) - return 0; - else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX ) - max_gid = (FT_UInt)root->num_glyphs; - else - FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", - FT_UINT_MAX, root->num_glyphs )); - - for ( i = 0; i < max_gid; i++ ) - { - FT_String* gname; - FT_Error error = tt_face_get_ps_name( face, i, &gname ); - - - if ( error ) - continue; - - if ( !ft_strcmp( glyph_name, gname ) ) - return i; - } - - return 0; - } - - - FT_DEFINE_SERVICE_GLYPHDICTREC( - sfnt_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) - - -#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - /* - * POSTSCRIPT NAME SERVICE - * - */ - - static const char* - sfnt_get_ps_name( TT_Face face ) - { - FT_Int n, found_win, found_apple; - const char* result = NULL; - - - /* shouldn't happen, but just in case to avoid memory leaks */ - if ( face->postscript_name ) - return face->postscript_name; - - /* scan the name table to see whether we have a Postscript name here, */ - /* either in Macintosh or Windows platform encodings */ - found_win = -1; - found_apple = -1; - - for ( n = 0; n < face->num_names; n++ ) - { - TT_NameEntryRec* name = face->name_table.names + n; - - - if ( name->nameID == 6 && name->stringLength > 0 ) - { - if ( name->platformID == 3 && - name->encodingID == 1 && - name->languageID == 0x409 ) - found_win = n; - - if ( name->platformID == 1 && - name->encodingID == 0 && - name->languageID == 0 ) - found_apple = n; - } - } - - if ( found_win != -1 ) - { - FT_Memory memory = face->root.memory; - TT_NameEntryRec* name = face->name_table.names + found_win; - FT_UInt len = name->stringLength / 2; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - if ( !FT_ALLOC( result, name->stringLength + 1 ) ) - { - FT_Stream stream = face->name_table.stream; - FT_String* r = (FT_String*)result; - FT_Byte* p = (FT_Byte*)name->string; - - - if ( FT_STREAM_SEEK( name->stringOffset ) || - FT_FRAME_ENTER( name->stringLength ) ) - { - FT_FREE( result ); - name->stringLength = 0; - name->stringOffset = 0; - FT_FREE( name->string ); - - goto Exit; - } - - p = (FT_Byte*)stream->cursor; - - for ( ; len > 0; len--, p += 2 ) - { - if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 ) - *r++ = p[1]; - } - *r = '\0'; - - FT_FRAME_EXIT(); - } - goto Exit; - } - - if ( found_apple != -1 ) - { - FT_Memory memory = face->root.memory; - TT_NameEntryRec* name = face->name_table.names + found_apple; - FT_UInt len = name->stringLength; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - if ( !FT_ALLOC( result, len + 1 ) ) - { - FT_Stream stream = face->name_table.stream; - - - if ( FT_STREAM_SEEK( name->stringOffset ) || - FT_STREAM_READ( result, len ) ) - { - name->stringOffset = 0; - name->stringLength = 0; - FT_FREE( name->string ); - FT_FREE( result ); - goto Exit; - } - ((char*)result)[len] = '\0'; - } - } - - Exit: - face->postscript_name = result; - return result; - } - - - FT_DEFINE_SERVICE_PSFONTNAMEREC( - sfnt_service_ps_name, - (FT_PsName_GetFunc)sfnt_get_ps_name ) - - - /* - * TT CMAP INFO - */ - FT_DEFINE_SERVICE_TTCMAPSREC( - tt_service_get_cmap_info, - (TT_CMap_Info_GetFunc)tt_get_cmap_info ) - - -#ifdef TT_CONFIG_OPTION_BDF - - static FT_Error - sfnt_get_charset_id( TT_Face face, - const char* *acharset_encoding, - const char* *acharset_registry ) - { - BDF_PropertyRec encoding, registry; - FT_Error error; - - - /* XXX: I don't know whether this is correct, since - * tt_face_find_bdf_prop only returns something correct if we have - * previously selected a size that is listed in the BDF table. - * Should we change the BDF table format to include single offsets - * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'? - */ - error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", ®istry ); - if ( !error ) - { - error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding ); - if ( !error ) - { - if ( registry.type == BDF_PROPERTY_TYPE_ATOM && - encoding.type == BDF_PROPERTY_TYPE_ATOM ) - { - *acharset_encoding = encoding.u.atom; - *acharset_registry = registry.u.atom; - } - else - error = FT_THROW( Invalid_Argument ); - } - } - - return error; - } - - - FT_DEFINE_SERVICE_BDFRec( - sfnt_service_bdf, - (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) - - -#endif /* TT_CONFIG_OPTION_BDF */ - - - /* - * SERVICE LIST - */ - -#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF - FT_DEFINE_SERVICEDESCREC5( - sfnt_services, - FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, - FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, - FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) -#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES - FT_DEFINE_SERVICEDESCREC4( - sfnt_services, - FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, - FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) -#elif defined TT_CONFIG_OPTION_BDF - FT_DEFINE_SERVICEDESCREC4( - sfnt_services, - FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, - FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) -#else - FT_DEFINE_SERVICEDESCREC3( - sfnt_services, - FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) -#endif - - - FT_CALLBACK_DEF( FT_Module_Interface ) - sfnt_get_interface( FT_Module module, - const char* module_interface ) - { - /* SFNT_SERVICES_GET derefers `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - FT_Library library; - - - if ( !module ) - return NULL; - library = module->library; - if ( !library ) - return NULL; -#else - FT_UNUSED( module ); -#endif - - return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface ); - } - - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#define PUT_EMBEDDED_BITMAPS( a ) a -#else -#define PUT_EMBEDDED_BITMAPS( a ) NULL -#endif - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES -#define PUT_PS_NAMES( a ) a -#else -#define PUT_PS_NAMES( a ) NULL -#endif - - FT_DEFINE_SFNT_INTERFACE( - sfnt_interface, - tt_face_goto_table, - - sfnt_init_face, - sfnt_load_face, - sfnt_done_face, - sfnt_get_interface, - - tt_face_load_any, - - tt_face_load_head, - tt_face_load_hhea, - tt_face_load_cmap, - tt_face_load_maxp, - tt_face_load_os2, - tt_face_load_post, - - tt_face_load_name, - tt_face_free_name, - - tt_face_load_kern, - tt_face_load_gasp, - tt_face_load_pclt, - - /* see `ttload.h' */ - PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ), - - PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ), - - /* see `ttpost.h' */ - PUT_PS_NAMES( tt_face_get_ps_name ), - PUT_PS_NAMES( tt_face_free_ps_names ), - - /* since version 2.1.8 */ - tt_face_get_kerning, - - /* since version 2.2 */ - tt_face_load_font_dir, - tt_face_load_hmtx, - - /* see `ttsbit.h' and `sfnt.h' */ - PUT_EMBEDDED_BITMAPS( tt_face_load_eblc ), - PUT_EMBEDDED_BITMAPS( tt_face_free_eblc ), - - PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), - PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), - - tt_face_get_metrics - ) - - - FT_DEFINE_MODULE( - sfnt_module_class, - - 0, /* not a font driver or renderer */ - sizeof ( FT_ModuleRec ), - - "sfnt", /* driver name */ - 0x10000L, /* driver version 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or higher */ - - (const void*)&SFNT_INTERFACE_GET, /* module specific interface */ - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) sfnt_get_interface ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sfdriver.h b/drivers/freetype/freetype/src/sfnt/sfdriver.h deleted file mode 100644 index 5de25d51ca..0000000000 --- a/drivers/freetype/freetype/src/sfnt/sfdriver.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfdriver.h */ -/* */ -/* High-level SFNT driver interface (specification). */ -/* */ -/* Copyright 1996-2001 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 __SFDRIVER_H__ -#define __SFDRIVER_H__ - - -#include <ft2build.h> -#include FT_MODULE_H - - -FT_BEGIN_HEADER - - - FT_DECLARE_MODULE( sfnt_module_class ) - - -FT_END_HEADER - -#endif /* __SFDRIVER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sferrors.h b/drivers/freetype/freetype/src/sfnt/sferrors.h deleted file mode 100644 index e981e1d26f..0000000000 --- a/drivers/freetype/freetype/src/sfnt/sferrors.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* sferrors.h */ -/* */ -/* SFNT error codes (specification only). */ -/* */ -/* Copyright 2001, 2004, 2012, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the SFNT error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __SFERRORS_H__ -#define __SFERRORS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX SFNT_Err_ -#define FT_ERR_BASE FT_Mod_Err_SFNT - -#include FT_ERRORS_H - -#endif /* __SFERRORS_H__ */ - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sfnt.c b/drivers/freetype/freetype/src/sfnt/sfnt.c deleted file mode 100644 index d62ed4e0b5..0000000000 --- a/drivers/freetype/freetype/src/sfnt/sfnt.c +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfnt.c */ -/* */ -/* Single object library component. */ -/* */ -/* Copyright 1996-2006, 2013 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "sfntpic.c" -#include "ttload.c" -#include "ttmtx.c" -#include "ttcmap.c" -#include "ttkern.c" -#include "sfobjs.c" -#include "sfdriver.c" - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#include "pngshim.c" -#include "ttsbit.c" -#endif - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES -#include "ttpost.c" -#endif - -#ifdef TT_CONFIG_OPTION_BDF -#include "ttbdf.c" -#endif - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sfntpic.c b/drivers/freetype/freetype/src/sfnt/sfntpic.c deleted file mode 100644 index b3fb24b3f0..0000000000 --- a/drivers/freetype/freetype/src/sfnt/sfntpic.c +++ /dev/null @@ -1,143 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfntpic.c */ -/* */ -/* The FreeType position independent code services for sfnt module. */ -/* */ -/* Copyright 2009, 2010, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "sfntpic.h" -#include "sferrors.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from sfdriver.c */ - FT_Error - FT_Create_Class_sfnt_services( FT_Library library, - FT_ServiceDescRec** output_class ); - void - FT_Destroy_Class_sfnt_services( FT_Library library, - FT_ServiceDescRec* clazz ); - void - FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec* clazz ); - void - FT_Init_Class_sfnt_interface( FT_Library library, - SFNT_Interface* clazz ); - void - FT_Init_Class_sfnt_service_glyph_dict( - FT_Library library, - FT_Service_GlyphDictRec* clazz ); - void - FT_Init_Class_sfnt_service_ps_name( - FT_Library library, - FT_Service_PsFontNameRec* clazz ); - void - FT_Init_Class_tt_service_get_cmap_info( - FT_Library library, - FT_Service_TTCMapsRec* clazz ); - void - FT_Init_Class_sfnt_service_sfnt_table( - FT_Service_SFNT_TableRec* clazz ); - - - /* forward declaration of PIC init functions from ttcmap.c */ - FT_Error - FT_Create_Class_tt_cmap_classes( FT_Library library, - TT_CMap_Class** output_class ); - void - FT_Destroy_Class_tt_cmap_classes( FT_Library library, - TT_CMap_Class* clazz ); - - - void - sfnt_module_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->sfnt ) - { - sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt; - - - if ( container->sfnt_services ) - FT_Destroy_Class_sfnt_services( library, - container->sfnt_services ); - container->sfnt_services = NULL; - - if ( container->tt_cmap_classes ) - FT_Destroy_Class_tt_cmap_classes( library, - container->tt_cmap_classes ); - container->tt_cmap_classes = NULL; - - FT_FREE( container ); - pic_container->sfnt = NULL; - } - } - - - FT_Error - sfnt_module_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - sfntModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->sfnt = container; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - error = FT_Create_Class_sfnt_services( library, - &container->sfnt_services ); - if ( error ) - goto Exit; - - error = FT_Create_Class_tt_cmap_classes( library, - &container->tt_cmap_classes ); - if ( error ) - goto Exit; - - FT_Init_Class_sfnt_service_glyph_dict( - library, &container->sfnt_service_glyph_dict ); - FT_Init_Class_sfnt_service_ps_name( - library, &container->sfnt_service_ps_name ); - FT_Init_Class_tt_service_get_cmap_info( - library, &container->tt_service_get_cmap_info ); - FT_Init_Class_sfnt_service_sfnt_table( - &container->sfnt_service_sfnt_table ); -#ifdef TT_CONFIG_OPTION_BDF - FT_Init_Class_sfnt_service_bdf( &container->sfnt_service_bdf ); -#endif - FT_Init_Class_sfnt_interface( library, &container->sfnt_interface ); - - Exit: - if ( error ) - sfnt_module_class_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sfntpic.h b/drivers/freetype/freetype/src/sfnt/sfntpic.h deleted file mode 100644 index b09a9141e0..0000000000 --- a/drivers/freetype/freetype/src/sfnt/sfntpic.h +++ /dev/null @@ -1,114 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfntpic.h */ -/* */ -/* The FreeType position independent code services for sfnt module. */ -/* */ -/* Copyright 2009, 2012 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __SFNTPIC_H__ -#define __SFNTPIC_H__ - - -FT_BEGIN_HEADER - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define SFNT_SERVICES_GET sfnt_services -#define SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict -#define SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name -#define TT_SERVICE_CMAP_INFO_GET tt_service_get_cmap_info -#define SFNT_SERVICES_GET sfnt_services -#define TT_CMAP_CLASSES_GET tt_cmap_classes -#define SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table -#define SFNT_SERVICE_BDF_GET sfnt_service_bdf -#define SFNT_INTERFACE_GET sfnt_interface - -#else /* FT_CONFIG_OPTION_PIC */ - - /* some include files required for members of sfntModulePIC */ -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_TT_CMAP_H - -#ifdef TT_CONFIG_OPTION_BDF -#include "ttbdf.h" -#include FT_SERVICE_BDF_H -#endif - -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include "ttcmap.h" - - - typedef struct sfntModulePIC_ - { - FT_ServiceDescRec* sfnt_services; - FT_Service_GlyphDictRec sfnt_service_glyph_dict; - FT_Service_PsFontNameRec sfnt_service_ps_name; - FT_Service_TTCMapsRec tt_service_get_cmap_info; - TT_CMap_Class* tt_cmap_classes; - FT_Service_SFNT_TableRec sfnt_service_sfnt_table; -#ifdef TT_CONFIG_OPTION_BDF - FT_Service_BDFRec sfnt_service_bdf; -#endif - SFNT_Interface sfnt_interface; - - } sfntModulePIC; - - -#define GET_PIC( lib ) \ - ( (sfntModulePIC*)( (lib)->pic_container.sfnt ) ) - -#define SFNT_SERVICES_GET \ - ( GET_PIC( library )->sfnt_services ) -#define SFNT_SERVICE_GLYPH_DICT_GET \ - ( GET_PIC( library )->sfnt_service_glyph_dict ) -#define SFNT_SERVICE_PS_NAME_GET \ - ( GET_PIC( library )->sfnt_service_ps_name ) -#define TT_SERVICE_CMAP_INFO_GET \ - ( GET_PIC( library )->tt_service_get_cmap_info ) -#define SFNT_SERVICES_GET \ - ( GET_PIC( library )->sfnt_services ) -#define TT_CMAP_CLASSES_GET \ - ( GET_PIC( library )->tt_cmap_classes ) -#define SFNT_SERVICE_SFNT_TABLE_GET \ - ( GET_PIC( library )->sfnt_service_sfnt_table ) -#define SFNT_SERVICE_BDF_GET \ - ( GET_PIC( library )->sfnt_service_bdf ) -#define SFNT_INTERFACE_GET \ - ( GET_PIC( library )->sfnt_interface ) - - - /* see sfntpic.c for the implementation */ - void - sfnt_module_class_pic_free( FT_Library library ); - - FT_Error - sfnt_module_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __SFNTPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sfobjs.c b/drivers/freetype/freetype/src/sfnt/sfobjs.c deleted file mode 100644 index f975e71c3b..0000000000 --- a/drivers/freetype/freetype/src/sfnt/sfobjs.c +++ /dev/null @@ -1,1163 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfobjs.c */ -/* */ -/* SFNT object management (base). */ -/* */ -/* Copyright 1996-2008, 2010-2013 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 "sfobjs.h" -#include "ttload.h" -#include "ttcmap.h" -#include "ttkern.h" -#include FT_INTERNAL_SFNT_H -#include FT_INTERNAL_DEBUG_H -#include FT_TRUETYPE_IDS_H -#include FT_TRUETYPE_TAGS_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H -#include FT_SFNT_NAMES_H -#include "sferrors.h" - -#ifdef TT_CONFIG_OPTION_BDF -#include "ttbdf.h" -#endif - - - /*************************************************************************/ - /* */ - /* 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_sfobjs - - - - /* convert a UTF-16 name entry to ASCII */ - static FT_String* - tt_name_entry_ascii_from_utf16( TT_NameEntry entry, - FT_Memory memory ) - { - FT_String* string = NULL; - FT_UInt len, code, n; - FT_Byte* read = (FT_Byte*)entry->string; - FT_Error error; - - - len = (FT_UInt)entry->stringLength / 2; - - if ( FT_NEW_ARRAY( string, len + 1 ) ) - return NULL; - - for ( n = 0; n < len; n++ ) - { - code = FT_NEXT_USHORT( read ); - - if ( code == 0 ) - break; - - if ( code < 32 || code > 127 ) - code = '?'; - - string[n] = (char)code; - } - - string[n] = 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, - FT_Memory memory ) - { - FT_String* string = NULL; - FT_UInt len, code, n; - FT_Byte* read = (FT_Byte*)entry->string; - FT_Error error; - - - len = (FT_UInt)entry->stringLength; - - if ( FT_NEW_ARRAY( string, len + 1 ) ) - return NULL; - - for ( n = 0; n < len; n++ ) - { - code = *read++; - - if ( code == 0 ) - break; - - if ( code < 32 || code > 127 ) - code = '?'; - - string[n] = (char)code; - } - - string[n] = 0; - - return string; - } - - - typedef FT_String* (*TT_NameEntry_ConvertFunc)( TT_NameEntry entry, - FT_Memory memory ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_get_name */ - /* */ - /* <Description> */ - /* Returns a given ENGLISH name record in ASCII. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* nameid :: The name id of the name record to return. */ - /* */ - /* <InOut> */ - /* name :: The address of a string pointer. NULL if no name is */ - /* present. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error - tt_face_get_name( TT_Face face, - FT_UShort nameid, - FT_String** name ) - { - FT_Memory memory = face->root.memory; - FT_Error error = FT_Err_Ok; - FT_String* result = NULL; - FT_UShort n; - TT_NameEntryRec* rec; - 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; - - TT_NameEntry_ConvertFunc convert; - - - FT_ASSERT( name ); - - rec = face->name_table.names; - for ( n = 0; n < face->num_names; n++, rec++ ) - { - /* According to the OpenType 1.3 specification, only Microsoft or */ - /* Apple platform IDs might be used in the `name' table. The */ - /* `Unicode' platform is reserved for the `cmap' table, and the */ - /* `ISO' one is deprecated. */ - /* */ - /* However, the Apple TrueType specification doesn't say the same */ - /* thing and goes to suggest that all Unicode `name' table entries */ - /* should be coded in UTF-16 (in big-endian format I suppose). */ - /* */ - if ( rec->nameID == nameid && rec->stringLength > 0 ) - { - switch ( rec->platformID ) - { - case TT_PLATFORM_APPLE_UNICODE: - case TT_PLATFORM_ISO: - /* there is `languageID' to check there. We should use this */ - /* field only as a last solution when nothing else is */ - /* available. */ - /* */ - found_unicode = n; - 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_english = n; - else if ( rec->encodingID == TT_MAC_ID_ROMAN ) - found_apple_roman = n; - break; - - case TT_PLATFORM_MICROSOFT: - /* we only take a non-English name when there is nothing */ - /* else available in the font */ - /* */ - if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 ) - { - switch ( rec->encodingID ) - { - case TT_MS_ID_SYMBOL_CS: - case TT_MS_ID_UNICODE_CS: - case TT_MS_ID_UCS_4: - is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 ); - found_win = n; - break; - - default: - ; - } - } - break; - - default: - ; - } - } - } - - 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) */ - /* */ - convert = NULL; - if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) ) - { - 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: - /* 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: - ; - } - } - else if ( found_apple >= 0 ) - { - rec = face->name_table.names + found_apple; - convert = tt_name_entry_ascii_from_other; - } - else if ( found_unicode >= 0 ) - { - rec = face->name_table.names + found_unicode; - convert = tt_name_entry_ascii_from_utf16; - } - - if ( rec && convert ) - { - if ( rec->string == NULL ) - { - FT_Stream stream = face->name_table.stream; - - - if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || - FT_STREAM_SEEK( rec->stringOffset ) || - FT_STREAM_READ( rec->string, rec->stringLength ) ) - { - FT_FREE( rec->string ); - rec->stringLength = 0; - result = NULL; - goto Exit; - } - } - - result = convert( rec, memory ); - } - - Exit: - *name = result; - return error; - } - - - static FT_Encoding - sfnt_find_encoding( int platform_id, - int encoding_id ) - { - typedef struct TEncoding_ - { - int platform_id; - int encoding_id; - FT_Encoding encoding; - - } TEncoding; - - static - const TEncoding tt_encodings[] = - { - { TT_PLATFORM_ISO, -1, FT_ENCODING_UNICODE }, - - { TT_PLATFORM_APPLE_UNICODE, -1, FT_ENCODING_UNICODE }, - - { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, FT_ENCODING_APPLE_ROMAN }, - - { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_SJIS }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_GB2312 }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_BIG5 }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_WANSUNG }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_JOHAB } - }; - - const TEncoding *cur, *limit; - - - cur = tt_encodings; - limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] ); - - for ( ; cur < limit; cur++ ) - { - if ( cur->platform_id == platform_id ) - { - if ( cur->encoding_id == encoding_id || - cur->encoding_id == -1 ) - return cur->encoding; - } - } - - return FT_ENCODING_NONE; - } - - - /* Fill in face->ttc_header. If the font is not a TTC, it is */ - /* synthesized into a TTC with one offset table. */ - static FT_Error - sfnt_open_font( FT_Stream stream, - TT_Face face ) - { - FT_Memory memory = stream->memory; - FT_Error error; - FT_ULong tag, offset; - - static const FT_Frame_Field ttc_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TTC_HeaderRec - - FT_FRAME_START( 8 ), - FT_FRAME_LONG( version ), - FT_FRAME_LONG( count ), /* this is ULong in the specs */ - FT_FRAME_END - }; - - - face->ttc_header.tag = 0; - face->ttc_header.version = 0; - face->ttc_header.count = 0; - - offset = FT_STREAM_POS(); - - if ( FT_READ_ULONG( tag ) ) - return error; - - if ( tag != 0x00010000UL && - tag != TTAG_ttcf && - tag != TTAG_OTTO && - tag != TTAG_true && - tag != TTAG_typ1 && - tag != 0x00020000UL ) - { - FT_TRACE2(( " not a font using the SFNT container format\n" )); - return FT_THROW( Unknown_File_Format ); - } - - face->ttc_header.tag = TTAG_ttcf; - - if ( tag == TTAG_ttcf ) - { - FT_Int n; - - - FT_TRACE3(( "sfnt_open_font: file is a collection\n" )); - - if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) - return error; - - if ( face->ttc_header.count == 0 ) - return FT_THROW( Invalid_Table ); - - /* a rough size estimate: let's conservatively assume that there */ - /* is just a single table info in each subfont header (12 + 16*1 = */ - /* 28 bytes), thus we have (at least) `12 + 4*count' bytes for the */ - /* size of the TTC header plus `28*count' bytes for all subfont */ - /* headers */ - if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) ) - return FT_THROW( Array_Too_Large ); - - /* now read the offsets of each font in the file */ - if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) ) - return error; - - if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) ) - return error; - - for ( n = 0; n < face->ttc_header.count; n++ ) - face->ttc_header.offsets[n] = FT_GET_ULONG(); - - FT_FRAME_EXIT(); - } - else - { - FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" )); - - face->ttc_header.version = 1 << 16; - face->ttc_header.count = 1; - - if ( FT_NEW( face->ttc_header.offsets ) ) - return error; - - face->ttc_header.offsets[0] = offset; - } - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - sfnt_init_face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - FT_Library library = face->root.driver->root.library; - SFNT_Service sfnt; - - - /* for now, parameters are unused */ - FT_UNUSED( num_params ); - FT_UNUSED( params ); - - - sfnt = (SFNT_Service)face->sfnt; - if ( !sfnt ) - { - sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); - if ( !sfnt ) - { - FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" )); - return FT_THROW( Missing_Module ); - } - - face->sfnt = sfnt; - face->goto_table = sfnt->goto_table; - } - - FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS ); - - FT_TRACE2(( "SFNT driver\n" )); - - error = sfnt_open_font( stream, face ); - if ( error ) - return error; - - FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index )); - - if ( face_index < 0 ) - face_index = 0; - - if ( face_index >= face->ttc_header.count ) - return FT_THROW( Invalid_Argument ); - - if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) - return error; - - /* check that we have a valid TrueType file */ - error = sfnt->load_font_dir( face, stream ); - if ( error ) - return error; - - face->root.num_faces = face->ttc_header.count; - face->root.face_index = face_index; - - return error; - } - - -#define LOAD_( x ) \ - do { \ - FT_TRACE2(( "`" #x "' " )); \ - FT_TRACE3(( "-->\n" )); \ - \ - error = sfnt->load_ ## x( face, stream ); \ - \ - FT_TRACE2(( "%s\n", ( !error ) \ - ? "loaded" \ - : FT_ERR_EQ( error, Table_Missing ) \ - ? "missing" \ - : "failed to load" )); \ - FT_TRACE3(( "\n" )); \ - } while ( 0 ) - -#define LOADM_( x, vertical ) \ - do { \ - FT_TRACE2(( "`%s" #x "' ", \ - vertical ? "vertical " : "" )); \ - FT_TRACE3(( "-->\n" )); \ - \ - error = sfnt->load_ ## x( face, stream, vertical ); \ - \ - FT_TRACE2(( "%s\n", ( !error ) \ - ? "loaded" \ - : FT_ERR_EQ( error, Table_Missing ) \ - ? "missing" \ - : "failed to load" )); \ - FT_TRACE3(( "\n" )); \ - } while ( 0 ) - -#define GET_NAME( id, field ) \ - do { \ - error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \ - if ( error ) \ - goto Exit; \ - } while ( 0 ) - - - FT_LOCAL_DEF( FT_Error ) - sfnt_load_face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - FT_Error psnames_error; -#endif - FT_Bool has_outline; - FT_Bool is_apple_sbit; - FT_Bool ignore_preferred_family = FALSE; - FT_Bool ignore_preferred_subfamily = FALSE; - - SFNT_Service sfnt = (SFNT_Service)face->sfnt; - - FT_UNUSED( face_index ); - - - /* Check parameters */ - - { - FT_Int i; - - - for ( i = 0; i < num_params; i++ ) - { - if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY ) - ignore_preferred_family = TRUE; - else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY ) - ignore_preferred_subfamily = TRUE; - } - } - - /* Load tables */ - - /* We now support two SFNT-based bitmapped font formats. They */ - /* are recognized easily as they do not include a `glyf' */ - /* table. */ - /* */ - /* The first format comes from Apple, and uses a table named */ - /* `bhed' instead of `head' to store the font header (using */ - /* the same format). It also doesn't include horizontal and */ - /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */ - /* missing). */ - /* */ - /* The other format comes from Microsoft, and is used with */ - /* WinCE/PocketPC. It looks like a standard TTF, except that */ - /* it doesn't contain outlines. */ - /* */ - - FT_TRACE2(( "sfnt_load_face: %08p\n\n", face )); - - /* do we have outlines in there? */ -#ifdef FT_CONFIG_OPTION_INCREMENTAL - has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || - tt_face_lookup_table( face, TTAG_glyf ) != 0 || - tt_face_lookup_table( face, TTAG_CFF ) != 0 ); -#else - has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || - tt_face_lookup_table( face, TTAG_CFF ) != 0 ); -#endif - - is_apple_sbit = 0; - - /* if this font doesn't contain outlines, we try to load */ - /* a `bhed' table */ - if ( !has_outline && sfnt->load_bhed ) - { - LOAD_( bhed ); - is_apple_sbit = FT_BOOL( !error ); - } - - /* load the font header (`head' table) if this isn't an Apple */ - /* sbit font file */ - if ( !is_apple_sbit ) - { - LOAD_( head ); - if ( error ) - goto Exit; - } - - if ( face->header.Units_Per_EM == 0 ) - { - error = FT_THROW( Invalid_Table ); - - goto Exit; - } - - /* the following tables are often not present in embedded TrueType */ - /* fonts within PDF documents, so don't check for them. */ - LOAD_( maxp ); - LOAD_( cmap ); - - /* the following tables are optional in PCL fonts -- */ - /* don't check for errors */ - LOAD_( name ); - LOAD_( post ); - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - psnames_error = error; -#endif - - /* do not load the metrics headers and tables if this is an Apple */ - /* sbit font file */ - if ( !is_apple_sbit ) - { - /* load the `hhea' and `hmtx' tables */ - LOADM_( hhea, 0 ); - if ( !error ) - { - LOADM_( hmtx, 0 ); - if ( FT_ERR_EQ( error, Table_Missing ) ) - { - error = FT_THROW( Hmtx_Table_Missing ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - /* If this is an incrementally loaded font and there are */ - /* overriding metrics, tolerate a missing `hmtx' table. */ - if ( face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs-> - get_glyph_metrics ) - { - face->horizontal.number_Of_HMetrics = 0; - error = FT_Err_Ok; - } -#endif - } - } - else if ( FT_ERR_EQ( error, Table_Missing ) ) - { - /* No `hhea' table necessary for SFNT Mac fonts. */ - if ( face->format_tag == TTAG_true ) - { - FT_TRACE2(( "This is an SFNT Mac font.\n" )); - - has_outline = 0; - error = FT_Err_Ok; - } - else - { - error = FT_THROW( Horiz_Header_Missing ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - /* If this is an incrementally loaded font and there are */ - /* overriding metrics, tolerate a missing `hhea' table. */ - if ( face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs-> - get_glyph_metrics ) - { - face->horizontal.number_Of_HMetrics = 0; - error = FT_Err_Ok; - } -#endif - - } - } - - if ( error ) - goto Exit; - - /* try to load the `vhea' and `vmtx' tables */ - LOADM_( hhea, 1 ); - if ( !error ) - { - LOADM_( hmtx, 1 ); - if ( !error ) - face->vertical_info = 1; - } - - if ( error && FT_ERR_NEQ( error, Table_Missing ) ) - goto Exit; - - LOAD_( os2 ); - if ( error ) - { - /* we treat the table as missing if there are any errors */ - face->os2.version = 0xFFFFU; - } - } - - /* the optional tables */ - - /* embedded bitmap support */ - if ( sfnt->load_eblc ) - { - LOAD_( eblc ); - if ( error ) - { - /* a font which contains neither bitmaps nor outlines is */ - /* still valid (although rather useless in most cases); */ - /* however, you can find such stripped fonts in PDFs */ - if ( FT_ERR_EQ( error, Table_Missing ) ) - error = FT_Err_Ok; - else - goto Exit; - } - } - - LOAD_( pclt ); - if ( error ) - { - if ( FT_ERR_NEQ( error, Table_Missing ) ) - goto Exit; - - face->pclt.Version = 0; - } - - /* consider the kerning and gasp tables as optional */ - LOAD_( gasp ); - LOAD_( kern ); - - face->root.num_glyphs = face->max_profile.numGlyphs; - - /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ - /* a WWS-only font face. `WWS' stands for `weight', width', and */ - /* `slope', a term used by Microsoft's Windows Presentation */ - /* Foundation (WPF). This flag has been introduced in version */ - /* 1.5 of the OpenType specification (May 2008). */ - - face->root.family_name = NULL; - face->root.style_name = NULL; - if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) - { - if ( !ignore_preferred_family ) - GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); - if ( !face->root.family_name ) - GET_NAME( FONT_FAMILY, &face->root.family_name ); - - if ( !ignore_preferred_subfamily ) - GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); - if ( !face->root.style_name ) - GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); - } - else - { - GET_NAME( WWS_FAMILY, &face->root.family_name ); - if ( !face->root.family_name && !ignore_preferred_family ) - GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); - if ( !face->root.family_name ) - GET_NAME( FONT_FAMILY, &face->root.family_name ); - - GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); - if ( !face->root.style_name && !ignore_preferred_subfamily ) - GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); - if ( !face->root.style_name ) - GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); - } - - /* now set up root fields */ - { - FT_Face root = &face->root; - FT_Long flags = root->face_flags; - - - /*********************************************************************/ - /* */ - /* Compute face flags. */ - /* */ - if ( has_outline == TRUE ) - flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */ - - /* The sfnt driver only supports bitmap fonts natively, thus we */ - /* don't set FT_FACE_FLAG_HINTER. */ - flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */ - FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - if ( !psnames_error && - face->postscript.FormatType != 0x00030000L ) - flags |= FT_FACE_FLAG_GLYPH_NAMES; -#endif - - /* fixed width font? */ - if ( face->postscript.isFixedPitch ) - flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* vertical information? */ - if ( face->vertical_info ) - flags |= FT_FACE_FLAG_VERTICAL; - - /* kerning available ? */ - if ( TT_FACE_HAS_KERNING( face ) ) - flags |= FT_FACE_FLAG_KERNING; - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - /* Don't bother to load the tables unless somebody asks for them. */ - /* No need to do work which will (probably) not be used. */ - if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && - tt_face_lookup_table( face, TTAG_fvar ) != 0 && - tt_face_lookup_table( face, TTAG_gvar ) != 0 ) - flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; -#endif - - root->face_flags = flags; - - /*********************************************************************/ - /* */ - /* Compute style flags. */ - /* */ - - flags = 0; - if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) - { - /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ - /* indicates an oblique font face. This flag has been */ - /* introduced in version 1.5 of the OpenType specification. */ - - if ( face->os2.fsSelection & 512 ) /* bit 9 */ - flags |= FT_STYLE_FLAG_ITALIC; - else if ( face->os2.fsSelection & 1 ) /* bit 0 */ - flags |= FT_STYLE_FLAG_ITALIC; - - if ( face->os2.fsSelection & 32 ) /* bit 5 */ - flags |= FT_STYLE_FLAG_BOLD; - } - else - { - /* this is an old Mac font, use the header field */ - - if ( face->header.Mac_Style & 1 ) - flags |= FT_STYLE_FLAG_BOLD; - - if ( face->header.Mac_Style & 2 ) - flags |= FT_STYLE_FLAG_ITALIC; - } - - root->style_flags = flags; - - /*********************************************************************/ - /* */ - /* Polish the charmaps. */ - /* */ - /* Try to set the charmap encoding according to the platform & */ - /* encoding ID of each charmap. */ - /* */ - - tt_face_build_cmaps( face ); /* ignore errors */ - - - /* set the encoding fields */ - { - FT_Int m; - - - for ( m = 0; m < root->num_charmaps; m++ ) - { - FT_CharMap charmap = root->charmaps[m]; - - - charmap->encoding = sfnt_find_encoding( charmap->platform_id, - charmap->encoding_id ); - -#if 0 - if ( root->charmap == NULL && - charmap->encoding == FT_ENCODING_UNICODE ) - { - /* set 'root->charmap' to the first Unicode encoding we find */ - root->charmap = charmap; - } -#endif - } - } - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* - * Now allocate the root array of FT_Bitmap_Size records and - * populate them. Unfortunately, it isn't possible to indicate bit - * depths in the FT_Bitmap_Size record. This is a design error. - */ - { - FT_UInt i, count; - - - count = face->sbit_num_strikes; - - if ( count > 0 ) - { - FT_Memory memory = face->root.stream->memory; - FT_UShort em_size = face->header.Units_Per_EM; - FT_Short avgwidth = face->os2.xAvgCharWidth; - FT_Size_Metrics metrics; - - - if ( em_size == 0 || face->os2.version == 0xFFFFU ) - { - avgwidth = 0; - em_size = 1; - } - - if ( FT_NEW_ARRAY( root->available_sizes, count ) ) - goto Exit; - - for ( i = 0; i < count; i++ ) - { - FT_Bitmap_Size* bsize = root->available_sizes + i; - - - error = sfnt->load_strike_metrics( face, i, &metrics ); - if ( error ) - goto Exit; - - bsize->height = (FT_Short)( metrics.height >> 6 ); - bsize->width = (FT_Short)( - ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); - - bsize->x_ppem = metrics.x_ppem << 6; - bsize->y_ppem = metrics.y_ppem << 6; - - /* assume 72dpi */ - bsize->size = metrics.y_ppem << 6; - } - - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - root->num_fixed_sizes = (FT_Int)count; - } - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - /* a font with no bitmaps and no outlines is scalable; */ - /* it has only empty glyphs then */ - if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) ) - root->face_flags |= FT_FACE_FLAG_SCALABLE; - - - /*********************************************************************/ - /* */ - /* Set up metrics. */ - /* */ - if ( FT_IS_SCALABLE( root ) ) - { - /* XXX What about if outline header is missing */ - /* (e.g. sfnt wrapped bitmap)? */ - root->bbox.xMin = face->header.xMin; - root->bbox.yMin = face->header.yMin; - root->bbox.xMax = face->header.xMax; - root->bbox.yMax = face->header.yMax; - root->units_per_EM = face->header.Units_Per_EM; - - - /* XXX: Computing the ascender/descender/height is very different */ - /* from what the specification tells you. Apparently, we */ - /* must be careful because */ - /* */ - /* - not all fonts have an OS/2 table; in this case, we take */ - /* the values in the horizontal header. However, these */ - /* values very often are not reliable. */ - /* */ - /* - otherwise, the correct typographic values are in the */ - /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */ - /* */ - /* However, certain fonts have these fields set to 0. */ - /* Rather, they have usWinAscent & usWinDescent correctly */ - /* set (but with different values). */ - /* */ - /* As an example, Arial Narrow is implemented through four */ - /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */ - /* */ - /* Strangely, all fonts have the same values in their */ - /* sTypoXXX fields, except ARIALNB which sets them to 0. */ - /* */ - /* On the other hand, they all have different */ - /* usWinAscent/Descent values -- as a conclusion, the OS/2 */ - /* table cannot be used to compute the text height reliably! */ - /* */ - - /* The ascender and descender are taken from the `hhea' table. */ - /* If zero, they are taken from the `OS/2' table. */ - - root->ascender = face->horizontal.Ascender; - root->descender = face->horizontal.Descender; - - root->height = (FT_Short)( root->ascender - root->descender + - face->horizontal.Line_Gap ); - - if ( !( root->ascender || root->descender ) ) - { - if ( face->os2.version != 0xFFFFU ) - { - if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) - { - root->ascender = face->os2.sTypoAscender; - root->descender = face->os2.sTypoDescender; - - root->height = (FT_Short)( root->ascender - root->descender + - face->os2.sTypoLineGap ); - } - else - { - root->ascender = (FT_Short)face->os2.usWinAscent; - root->descender = -(FT_Short)face->os2.usWinDescent; - - root->height = (FT_UShort)( root->ascender - root->descender ); - } - } - } - - root->max_advance_width = face->horizontal.advance_Width_Max; - root->max_advance_height = (FT_Short)( face->vertical_info - ? face->vertical.advance_Height_Max - : root->height ); - - /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ - /* Adjust underline position from top edge to centre of */ - /* stroke to convert TrueType meaning to FreeType meaning. */ - root->underline_position = face->postscript.underlinePosition - - face->postscript.underlineThickness / 2; - root->underline_thickness = face->postscript.underlineThickness; - } - - } - - Exit: - FT_TRACE2(( "sfnt_load_face: done\n" )); - - return error; - } - - -#undef LOAD_ -#undef LOADM_ -#undef GET_NAME - - - FT_LOCAL_DEF( void ) - sfnt_done_face( TT_Face face ) - { - FT_Memory memory; - SFNT_Service sfnt; - - - if ( !face ) - return; - - memory = face->root.memory; - sfnt = (SFNT_Service)face->sfnt; - - if ( sfnt ) - { - /* destroy the postscript names table if it is loaded */ - if ( sfnt->free_psnames ) - sfnt->free_psnames( face ); - - /* destroy the embedded bitmaps table if it is loaded */ - if ( sfnt->free_eblc ) - sfnt->free_eblc( face ); - } - -#ifdef TT_CONFIG_OPTION_BDF - /* freeing the embedded BDF properties */ - tt_face_free_bdf_props( face ); -#endif - - /* freeing the kerning table */ - tt_face_done_kern( face ); - - /* freeing the collection table */ - FT_FREE( face->ttc_header.offsets ); - face->ttc_header.count = 0; - - /* freeing table directory */ - FT_FREE( face->dir_tables ); - face->num_tables = 0; - - { - FT_Stream stream = FT_FACE_STREAM( face ); - - - /* simply release the 'cmap' table frame */ - FT_FRAME_RELEASE( face->cmap_table ); - face->cmap_size = 0; - } - - /* freeing the horizontal metrics */ - { - FT_Stream stream = FT_FACE_STREAM( face ); - - - FT_FRAME_RELEASE( face->horz_metrics ); - FT_FRAME_RELEASE( face->vert_metrics ); - face->horz_metrics_size = 0; - face->vert_metrics_size = 0; - } - - /* freeing the vertical ones, if any */ - if ( face->vertical_info ) - { - FT_FREE( face->vertical.long_metrics ); - FT_FREE( face->vertical.short_metrics ); - face->vertical_info = 0; - } - - /* freeing the gasp table */ - FT_FREE( face->gasp.gaspRanges ); - face->gasp.numRanges = 0; - - /* freeing the name table */ - if ( sfnt ) - sfnt->free_name( face ); - - /* freeing family and style name */ - FT_FREE( face->root.family_name ); - FT_FREE( face->root.style_name ); - - /* freeing sbit size table */ - FT_FREE( face->root.available_sizes ); - face->root.num_fixed_sizes = 0; - - FT_FREE( face->postscript_name ); - - face->sfnt = 0; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sfobjs.h b/drivers/freetype/freetype/src/sfnt/sfobjs.h deleted file mode 100644 index 6241c93b39..0000000000 --- a/drivers/freetype/freetype/src/sfnt/sfobjs.h +++ /dev/null @@ -1,54 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfobjs.h */ -/* */ -/* SFNT object management (specification). */ -/* */ -/* Copyright 1996-2001, 2002 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 __SFOBJS_H__ -#define __SFOBJS_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_SFNT_H -#include FT_INTERNAL_OBJECTS_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - sfnt_init_face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - FT_LOCAL( FT_Error ) - sfnt_load_face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - FT_LOCAL( void ) - sfnt_done_face( TT_Face face ); - - -FT_END_HEADER - -#endif /* __SFDRIVER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttbdf.c b/drivers/freetype/freetype/src/sfnt/ttbdf.c deleted file mode 100644 index 9401dae5f8..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttbdf.c +++ /dev/null @@ -1,250 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttbdf.c */ -/* */ -/* TrueType and OpenType embedded BDF properties (body). */ -/* */ -/* Copyright 2005, 2006, 2010, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include "ttbdf.h" - -#include "sferrors.h" - - -#ifdef TT_CONFIG_OPTION_BDF - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttbdf - - - FT_LOCAL_DEF( void ) - tt_face_free_bdf_props( TT_Face face ) - { - TT_BDF bdf = &face->bdf; - - - if ( bdf->loaded ) - { - FT_Stream stream = FT_FACE(face)->stream; - - - if ( bdf->table != NULL ) - FT_FRAME_RELEASE( bdf->table ); - - bdf->table_end = NULL; - bdf->strings = NULL; - bdf->strings_size = 0; - } - } - - - static FT_Error - tt_face_load_bdf_props( TT_Face face, - FT_Stream stream ) - { - TT_BDF bdf = &face->bdf; - FT_ULong length; - FT_Error error; - - - FT_ZERO( bdf ); - - error = tt_face_goto_table( face, TTAG_BDF, stream, &length ); - if ( error || - length < 8 || - FT_FRAME_EXTRACT( length, bdf->table ) ) - { - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - bdf->table_end = bdf->table + length; - - { - FT_Byte* p = bdf->table; - FT_UInt version = FT_NEXT_USHORT( p ); - FT_UInt num_strikes = FT_NEXT_USHORT( p ); - FT_ULong strings = FT_NEXT_ULONG ( p ); - FT_UInt count; - FT_Byte* strike; - - - if ( version != 0x0001 || - strings < 8 || - ( strings - 8 ) / 4 < num_strikes || - strings + 1 > length ) - { - goto BadTable; - } - - bdf->num_strikes = num_strikes; - bdf->strings = bdf->table + strings; - bdf->strings_size = length - strings; - - count = bdf->num_strikes; - p = bdf->table + 8; - strike = p + count * 4; - - - for ( ; count > 0; count-- ) - { - FT_UInt num_items = FT_PEEK_USHORT( p + 2 ); - - /* - * We don't need to check the value sets themselves, since this - * is done later. - */ - strike += 10 * num_items; - - p += 4; - } - - if ( strike > bdf->strings ) - goto BadTable; - } - - bdf->loaded = 1; - - Exit: - return error; - - BadTable: - FT_FRAME_RELEASE( bdf->table ); - FT_ZERO( bdf ); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - - FT_LOCAL_DEF( FT_Error ) - tt_face_find_bdf_prop( TT_Face face, - const char* property_name, - BDF_PropertyRec *aprop ) - { - TT_BDF bdf = &face->bdf; - FT_Size size = FT_FACE(face)->size; - FT_Error error = FT_Err_Ok; - FT_Byte* p; - FT_UInt count; - FT_Byte* strike; - FT_Offset property_len; - - - aprop->type = BDF_PROPERTY_TYPE_NONE; - - if ( bdf->loaded == 0 ) - { - error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); - if ( error ) - goto Exit; - } - - count = bdf->num_strikes; - p = bdf->table + 8; - strike = p + 4 * count; - - error = FT_ERR( Invalid_Argument ); - - if ( size == NULL || property_name == NULL ) - goto Exit; - - property_len = ft_strlen( property_name ); - if ( property_len == 0 ) - goto Exit; - - for ( ; count > 0; count-- ) - { - FT_UInt _ppem = FT_NEXT_USHORT( p ); - FT_UInt _count = FT_NEXT_USHORT( p ); - - if ( _ppem == size->metrics.y_ppem ) - { - count = _count; - goto FoundStrike; - } - - strike += 10 * _count; - } - goto Exit; - - FoundStrike: - p = strike; - for ( ; count > 0; count-- ) - { - FT_UInt type = FT_PEEK_USHORT( p + 4 ); - - if ( ( type & 0x10 ) != 0 ) - { - FT_UInt32 name_offset = FT_PEEK_ULONG( p ); - FT_UInt32 value = FT_PEEK_ULONG( p + 6 ); - - /* be a bit paranoid for invalid entries here */ - if ( name_offset < bdf->strings_size && - property_len < bdf->strings_size - name_offset && - ft_strncmp( property_name, - (const char*)bdf->strings + name_offset, - bdf->strings_size - name_offset ) == 0 ) - { - switch ( type & 0x0F ) - { - case 0x00: /* string */ - case 0x01: /* atoms */ - /* check that the content is really 0-terminated */ - if ( value < bdf->strings_size && - ft_memchr( bdf->strings + value, 0, bdf->strings_size ) ) - { - aprop->type = BDF_PROPERTY_TYPE_ATOM; - aprop->u.atom = (const char*)bdf->strings + value; - error = FT_Err_Ok; - goto Exit; - } - break; - - case 0x02: - aprop->type = BDF_PROPERTY_TYPE_INTEGER; - aprop->u.integer = (FT_Int32)value; - error = FT_Err_Ok; - goto Exit; - - case 0x03: - aprop->type = BDF_PROPERTY_TYPE_CARDINAL; - aprop->u.cardinal = value; - error = FT_Err_Ok; - goto Exit; - - default: - ; - } - } - } - p += 10; - } - - Exit: - return error; - } - -#endif /* TT_CONFIG_OPTION_BDF */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttbdf.h b/drivers/freetype/freetype/src/sfnt/ttbdf.h deleted file mode 100644 index 48a10d6e9b..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttbdf.h +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttbdf.h */ -/* */ -/* TrueType and OpenType embedded BDF properties (specification). */ -/* */ -/* Copyright 2005 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __TTBDF_H__ -#define __TTBDF_H__ - - -#include <ft2build.h> -#include "ttload.h" -#include FT_BDF_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( void ) - tt_face_free_bdf_props( TT_Face face ); - - - FT_LOCAL( FT_Error ) - tt_face_find_bdf_prop( TT_Face face, - const char* property_name, - BDF_PropertyRec *aprop ); - - -FT_END_HEADER - -#endif /* __TTBDF_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttcmap.c b/drivers/freetype/freetype/src/sfnt/ttcmap.c deleted file mode 100644 index 1507202ea8..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttcmap.c +++ /dev/null @@ -1,3557 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.c */ -/* */ -/* TrueType character mapping table (cmap) support (body). */ -/* */ -/* Copyright 2002-2010, 2012, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H - -#include "sferrors.h" /* must come before FT_INTERNAL_VALIDATE_H */ - -#include FT_INTERNAL_VALIDATE_H -#include FT_INTERNAL_STREAM_H -#include "ttload.h" -#include "ttcmap.h" -#include "sfntpic.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_ttcmap - - -#define TT_PEEK_SHORT FT_PEEK_SHORT -#define TT_PEEK_USHORT FT_PEEK_USHORT -#define TT_PEEK_UINT24 FT_PEEK_UOFF3 -#define TT_PEEK_LONG FT_PEEK_LONG -#define TT_PEEK_ULONG FT_PEEK_ULONG - -#define TT_NEXT_SHORT FT_NEXT_SHORT -#define TT_NEXT_USHORT FT_NEXT_USHORT -#define TT_NEXT_UINT24 FT_NEXT_UOFF3 -#define TT_NEXT_LONG FT_NEXT_LONG -#define TT_NEXT_ULONG FT_NEXT_ULONG - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap_init( TT_CMap cmap, - FT_Byte* table ) - { - cmap->data = table; - return FT_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 0 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 0 */ - /* length 2 USHORT table length in bytes */ - /* language 4 USHORT Mac language code */ - /* glyph_ids 6 BYTE[256] array of glyph indices */ - /* 262 */ - /* */ - -#ifdef TT_CONFIG_CMAP_FORMAT_0 - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap0_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p = table + 2; - FT_UInt length = TT_NEXT_USHORT( p ); - - - if ( table + length > valid->limit || length < 262 ) - FT_INVALID_TOO_SHORT; - - /* check glyph indices whenever necessary */ - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - FT_UInt n, idx; - - - p = table + 6; - for ( n = 0; n < 256; n++ ) - { - idx = *p++; - if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - } - } - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap0_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - FT_Byte* table = cmap->data; - - - return char_code < 256 ? table[6 + char_code] : 0; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap0_char_next( TT_CMap cmap, - FT_UInt32 *pchar_code ) - { - FT_Byte* table = cmap->data; - FT_UInt32 charcode = *pchar_code; - FT_UInt32 result = 0; - FT_UInt gindex = 0; - - - table += 6; /* go to glyph IDs */ - while ( ++charcode < 256 ) - { - gindex = table[charcode]; - if ( gindex != 0 ) - { - result = charcode; - break; - } - } - - *pchar_code = result; - return gindex; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap0_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_Byte* p = cmap->data + 4; - - - cmap_info->format = 0; - cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); - - return FT_Err_Ok; - } - - - FT_DEFINE_TT_CMAP( - tt_cmap0_class_rec, - sizeof ( TT_CMapRec ), - - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap0_char_index, - (FT_CMap_CharNextFunc) tt_cmap0_char_next, - - NULL, - NULL, - NULL, - NULL, - NULL, - - 0, - (TT_CMap_ValidateFunc)tt_cmap0_validate, - (TT_CMap_Info_GetFunc)tt_cmap0_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_0 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 2 *****/ - /***** *****/ - /***** This is used for certain CJK encodings that encode text in a *****/ - /***** mixed 8/16 bits encoding along the following lines: *****/ - /***** *****/ - /***** * Certain byte values correspond to an 8-bit character code *****/ - /***** (typically in the range 0..127 for ASCII compatibility). *****/ - /***** *****/ - /***** * Certain byte values signal the first byte of a 2-byte *****/ - /***** character code (but these values are also valid as the *****/ - /***** second byte of a 2-byte character). *****/ - /***** *****/ - /***** The following charmap lookup and iteration functions all *****/ - /***** assume that the value "charcode" correspond to following: *****/ - /***** *****/ - /***** - For one byte characters, "charcode" is simply the *****/ - /***** character code. *****/ - /***** *****/ - /***** - For two byte characters, "charcode" is the 2-byte *****/ - /***** character code in big endian format. More exactly: *****/ - /***** *****/ - /***** (charcode >> 8) is the first byte value *****/ - /***** (charcode & 0xFF) is the second byte value *****/ - /***** *****/ - /***** Note that not all values of "charcode" are valid according *****/ - /***** to these rules, and the function moderately check the *****/ - /***** arguments. *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 2 */ - /* length 2 USHORT table length in bytes */ - /* language 4 USHORT Mac language code */ - /* keys 6 USHORT[256] sub-header keys */ - /* subs 518 SUBHEAD[NSUBS] sub-headers array */ - /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ - /* */ - /* The `keys' table is used to map charcode high-bytes to sub-headers. */ - /* The value of `NSUBS' is the number of sub-headers defined in the */ - /* table and is computed by finding the maximum of the `keys' table. */ - /* */ - /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ - /* table, i.e., it is the corresponding sub-header index multiplied */ - /* by 8. */ - /* */ - /* Each sub-header has the following format: */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* first 0 USHORT first valid low-byte */ - /* count 2 USHORT number of valid low-bytes */ - /* delta 4 SHORT see below */ - /* offset 6 USHORT see below */ - /* */ - /* A sub-header defines, for each high-byte, the range of valid */ - /* low-bytes within the charmap. Note that the range defined by `first' */ - /* and `count' must be completely included in the interval [0..255] */ - /* according to the specification. */ - /* */ - /* If a character code is contained within a given sub-header, then */ - /* mapping it to a glyph index is done as follows: */ - /* */ - /* * The value of `offset' is read. This is a _byte_ distance from the */ - /* location of the `offset' field itself into a slice of the */ - /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ - /* */ - /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ - /* no glyph for the charcode. Otherwise, the value of `delta' is */ - /* added to it (modulo 65536) to form a new glyph index. */ - /* */ - /* It is up to the validation routine to check that all offsets fall */ - /* within the glyph IDs table (and not within the `subs' table itself or */ - /* outside of the CMap). */ - /* */ - -#ifdef TT_CONFIG_CMAP_FORMAT_2 - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap2_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p = table + 2; /* skip format */ - FT_UInt length = TT_PEEK_USHORT( p ); - FT_UInt n, max_subs; - FT_Byte* keys; /* keys table */ - FT_Byte* subs; /* sub-headers */ - FT_Byte* glyph_ids; /* glyph ID array */ - - - if ( table + length > valid->limit || length < 6 + 512 ) - FT_INVALID_TOO_SHORT; - - keys = table + 6; - - /* parse keys to compute sub-headers count */ - p = keys; - max_subs = 0; - for ( n = 0; n < 256; n++ ) - { - FT_UInt idx = TT_NEXT_USHORT( p ); - - - /* value must be multiple of 8 */ - if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 ) - FT_INVALID_DATA; - - idx >>= 3; - - if ( idx > max_subs ) - max_subs = idx; - } - - FT_ASSERT( p == table + 518 ); - - subs = p; - glyph_ids = subs + (max_subs + 1) * 8; - if ( glyph_ids > valid->limit ) - FT_INVALID_TOO_SHORT; - - /* parse sub-headers */ - for ( n = 0; n <= max_subs; n++ ) - { - FT_UInt first_code, code_count, offset; - FT_Int delta; - FT_Byte* ids; - - - first_code = TT_NEXT_USHORT( p ); - code_count = TT_NEXT_USHORT( p ); - delta = TT_NEXT_SHORT( p ); - offset = TT_NEXT_USHORT( p ); - - /* many Dynalab fonts have empty sub-headers */ - if ( code_count == 0 ) - continue; - - /* check range within 0..255 */ - if ( valid->level >= FT_VALIDATE_PARANOID ) - { - if ( first_code >= 256 || first_code + code_count > 256 ) - FT_INVALID_DATA; - } - - /* check offset */ - if ( offset != 0 ) - { - ids = p - 2 + offset; - if ( ids < glyph_ids || ids + code_count*2 > table + length ) - FT_INVALID_OFFSET; - - /* check glyph IDs */ - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - FT_Byte* limit = p + code_count * 2; - FT_UInt idx; - - - for ( ; p < limit; ) - { - idx = TT_NEXT_USHORT( p ); - if ( idx != 0 ) - { - idx = ( idx + delta ) & 0xFFFFU; - if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - } - } - } - } - } - - return FT_Err_Ok; - } - - - /* return sub header corresponding to a given character code */ - /* NULL on invalid charcode */ - static FT_Byte* - tt_cmap2_get_subheader( FT_Byte* table, - FT_UInt32 char_code ) - { - FT_Byte* result = NULL; - - - if ( char_code < 0x10000UL ) - { - FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); - FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); - FT_Byte* p = table + 6; /* keys table */ - FT_Byte* subs = table + 518; /* subheaders table */ - FT_Byte* sub; - - - if ( char_hi == 0 ) - { - /* an 8-bit character code -- we use subHeader 0 in this case */ - /* to test whether the character code is in the charmap */ - /* */ - sub = subs; /* jump to first sub-header */ - - /* check that the sub-header for this byte is 0, which */ - /* indicates that it is really a valid one-byte value */ - /* Otherwise, return 0 */ - /* */ - p += char_lo * 2; - if ( TT_PEEK_USHORT( p ) != 0 ) - goto Exit; - } - else - { - /* a 16-bit character code */ - - /* jump to key entry */ - p += char_hi * 2; - /* jump to sub-header */ - sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); - - /* check that the high byte isn't a valid one-byte value */ - if ( sub == subs ) - goto Exit; - } - result = sub; - } - Exit: - return result; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap2_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - FT_Byte* table = cmap->data; - FT_UInt result = 0; - FT_Byte* subheader; - - - subheader = tt_cmap2_get_subheader( table, char_code ); - if ( subheader ) - { - FT_Byte* p = subheader; - FT_UInt idx = (FT_UInt)(char_code & 0xFF); - FT_UInt start, count; - FT_Int delta; - FT_UInt offset; - - - start = TT_NEXT_USHORT( p ); - count = TT_NEXT_USHORT( p ); - delta = TT_NEXT_SHORT ( p ); - offset = TT_PEEK_USHORT( p ); - - idx -= start; - if ( idx < count && offset != 0 ) - { - p += offset + 2 * idx; - idx = TT_PEEK_USHORT( p ); - - if ( idx != 0 ) - result = (FT_UInt)( idx + delta ) & 0xFFFFU; - } - } - return result; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap2_char_next( TT_CMap cmap, - FT_UInt32 *pcharcode ) - { - FT_Byte* table = cmap->data; - FT_UInt gindex = 0; - FT_UInt32 result = 0; - FT_UInt32 charcode = *pcharcode + 1; - FT_Byte* subheader; - - - while ( charcode < 0x10000UL ) - { - subheader = tt_cmap2_get_subheader( table, charcode ); - if ( subheader ) - { - FT_Byte* p = subheader; - FT_UInt start = TT_NEXT_USHORT( p ); - FT_UInt count = TT_NEXT_USHORT( p ); - FT_Int delta = TT_NEXT_SHORT ( p ); - FT_UInt offset = TT_PEEK_USHORT( p ); - FT_UInt char_lo = (FT_UInt)( charcode & 0xFF ); - FT_UInt pos, idx; - - - if ( offset == 0 ) - goto Next_SubHeader; - - if ( char_lo < start ) - { - char_lo = start; - pos = 0; - } - else - pos = (FT_UInt)( char_lo - start ); - - p += offset + pos * 2; - charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; - - for ( ; pos < count; pos++, charcode++ ) - { - idx = TT_NEXT_USHORT( p ); - - if ( idx != 0 ) - { - gindex = ( idx + delta ) & 0xFFFFU; - if ( gindex != 0 ) - { - result = charcode; - goto Exit; - } - } - } - } - - /* jump to next sub-header, i.e. higher byte value */ - Next_SubHeader: - charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; - } - - Exit: - *pcharcode = result; - - return gindex; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap2_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_Byte* p = cmap->data + 4; - - - cmap_info->format = 2; - cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); - - return FT_Err_Ok; - } - - - FT_DEFINE_TT_CMAP( - tt_cmap2_class_rec, - sizeof ( TT_CMapRec ), - - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap2_char_index, - (FT_CMap_CharNextFunc) tt_cmap2_char_next, - - NULL, - NULL, - NULL, - NULL, - NULL, - - 2, - (TT_CMap_ValidateFunc)tt_cmap2_validate, - (TT_CMap_Info_GetFunc)tt_cmap2_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_2 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 4 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 4 */ - /* length 2 USHORT table length */ - /* in bytes */ - /* language 4 USHORT Mac language code */ - /* */ - /* segCountX2 6 USHORT 2*NUM_SEGS */ - /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */ - /* entrySelector 10 USHORT LOG_SEGS */ - /* rangeShift 12 USHORT segCountX2 - */ - /* searchRange */ - /* */ - /* endCount 14 USHORT[NUM_SEGS] end charcode for */ - /* each segment; last */ - /* is 0xFFFF */ - /* */ - /* pad 14+NUM_SEGS*2 USHORT padding */ - /* */ - /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */ - /* each segment */ - /* */ - /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */ - /* segment */ - /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */ - /* each segment; can be */ - /* zero */ - /* */ - /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ - /* ranges */ - /* */ - /* Character codes are modelled by a series of ordered (increasing) */ - /* intervals called segments. Each segment has start and end codes, */ - /* provided by the `startCount' and `endCount' arrays. Segments must */ - /* not overlap, and the last segment should always contain the value */ - /* 0xFFFF for `endCount'. */ - /* */ - /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ - /* ignored (they are traces of over-engineering in the TrueType */ - /* specification). */ - /* */ - /* Each segment also has a signed `delta', as well as an optional offset */ - /* within the `glyphIds' table. */ - /* */ - /* If a segment's idOffset is 0, the glyph index corresponding to any */ - /* charcode within the segment is obtained by adding the value of */ - /* `idDelta' directly to the charcode, modulo 65536. */ - /* */ - /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ - /* the segment, and the value of `idDelta' is added to it. */ - /* */ - /* */ - /* Finally, note that a lot of fonts contain an invalid last segment, */ - /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ - /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ - /* OpenOffice.org). We need special code to deal with them correctly. */ - /* */ - -#ifdef TT_CONFIG_CMAP_FORMAT_4 - - typedef struct TT_CMap4Rec_ - { - TT_CMapRec cmap; - FT_UInt32 cur_charcode; /* current charcode */ - FT_UInt cur_gindex; /* current glyph index */ - - FT_UInt num_ranges; - FT_UInt cur_range; - FT_UInt cur_start; - FT_UInt cur_end; - FT_Int cur_delta; - FT_Byte* cur_values; - - } TT_CMap4Rec, *TT_CMap4; - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap4_init( TT_CMap4 cmap, - FT_Byte* table ) - { - FT_Byte* p; - - - cmap->cmap.data = table; - - p = table + 6; - cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; - cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; - cmap->cur_gindex = 0; - - return FT_Err_Ok; - } - - - static FT_Int - tt_cmap4_set_range( TT_CMap4 cmap, - FT_UInt range_index ) - { - FT_Byte* table = cmap->cmap.data; - FT_Byte* p; - FT_UInt num_ranges = cmap->num_ranges; - - - while ( range_index < num_ranges ) - { - FT_UInt offset; - - - p = table + 14 + range_index * 2; - cmap->cur_end = FT_PEEK_USHORT( p ); - - p += 2 + num_ranges * 2; - cmap->cur_start = FT_PEEK_USHORT( p ); - - p += num_ranges * 2; - cmap->cur_delta = FT_PEEK_SHORT( p ); - - p += num_ranges * 2; - offset = FT_PEEK_USHORT( p ); - - /* some fonts have an incorrect last segment; */ - /* we have to catch it */ - if ( range_index >= num_ranges - 1 && - cmap->cur_start == 0xFFFFU && - cmap->cur_end == 0xFFFFU ) - { - TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; - FT_Byte* limit = face->cmap_table + face->cmap_size; - - - if ( offset && p + offset + 2 > limit ) - { - cmap->cur_delta = 1; - offset = 0; - } - } - - if ( offset != 0xFFFFU ) - { - cmap->cur_values = offset ? p + offset : NULL; - cmap->cur_range = range_index; - return 0; - } - - /* we skip empty segments */ - range_index++; - } - - return -1; - } - - - /* search the index of the charcode next to cmap->cur_charcode; */ - /* caller should call tt_cmap4_set_range with proper range */ - /* before calling this function */ - /* */ - static void - tt_cmap4_next( TT_CMap4 cmap ) - { - FT_UInt charcode; - - - if ( cmap->cur_charcode >= 0xFFFFUL ) - goto Fail; - - charcode = (FT_UInt)cmap->cur_charcode + 1; - - if ( charcode < cmap->cur_start ) - charcode = cmap->cur_start; - - for ( ;; ) - { - FT_Byte* values = cmap->cur_values; - FT_UInt end = cmap->cur_end; - FT_Int delta = cmap->cur_delta; - - - if ( charcode <= end ) - { - if ( values ) - { - FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); - - - do - { - FT_UInt gindex = FT_NEXT_USHORT( p ); - - - if ( gindex != 0 ) - { - gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); - if ( gindex != 0 ) - { - cmap->cur_charcode = charcode; - cmap->cur_gindex = gindex; - return; - } - } - } while ( ++charcode <= end ); - } - else - { - do - { - FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); - - - if ( gindex != 0 ) - { - cmap->cur_charcode = charcode; - cmap->cur_gindex = gindex; - return; - } - } while ( ++charcode <= end ); - } - } - - /* we need to find another range */ - if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) - break; - - if ( charcode < cmap->cur_start ) - charcode = cmap->cur_start; - } - - Fail: - cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; - cmap->cur_gindex = 0; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap4_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p = table + 2; /* skip format */ - FT_UInt length = TT_NEXT_USHORT( p ); - FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; - FT_UInt num_segs; - FT_Error error = FT_Err_Ok; - - - if ( length < 16 ) - FT_INVALID_TOO_SHORT; - - /* in certain fonts, the `length' field is invalid and goes */ - /* out of bound. We try to correct this here... */ - if ( table + length > valid->limit ) - { - if ( valid->level >= FT_VALIDATE_TIGHT ) - FT_INVALID_TOO_SHORT; - - length = (FT_UInt)( valid->limit - table ); - } - - p = table + 6; - num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ - - if ( valid->level >= FT_VALIDATE_PARANOID ) - { - /* check that we have an even value here */ - if ( num_segs & 1 ) - FT_INVALID_DATA; - } - - num_segs /= 2; - - if ( length < 16 + num_segs * 2 * 4 ) - FT_INVALID_TOO_SHORT; - - /* check the search parameters - even though we never use them */ - /* */ - if ( valid->level >= FT_VALIDATE_PARANOID ) - { - /* check the values of `searchRange', `entrySelector', `rangeShift' */ - FT_UInt search_range = TT_NEXT_USHORT( p ); - FT_UInt entry_selector = TT_NEXT_USHORT( p ); - FT_UInt range_shift = TT_NEXT_USHORT( p ); - - - if ( ( search_range | range_shift ) & 1 ) /* must be even values */ - FT_INVALID_DATA; - - search_range /= 2; - range_shift /= 2; - - /* `search range' is the greatest power of 2 that is <= num_segs */ - - if ( search_range > num_segs || - search_range * 2 < num_segs || - search_range + range_shift != num_segs || - search_range != ( 1U << entry_selector ) ) - FT_INVALID_DATA; - } - - ends = table + 14; - starts = table + 16 + num_segs * 2; - deltas = starts + num_segs * 2; - offsets = deltas + num_segs * 2; - glyph_ids = offsets + num_segs * 2; - - /* check last segment; its end count value must be 0xFFFF */ - if ( valid->level >= FT_VALIDATE_PARANOID ) - { - p = ends + ( num_segs - 1 ) * 2; - if ( TT_PEEK_USHORT( p ) != 0xFFFFU ) - FT_INVALID_DATA; - } - - { - FT_UInt start, end, offset, n; - FT_UInt last_start = 0, last_end = 0; - FT_Int delta; - FT_Byte* p_start = starts; - FT_Byte* p_end = ends; - FT_Byte* p_delta = deltas; - FT_Byte* p_offset = offsets; - - - for ( n = 0; n < num_segs; n++ ) - { - p = p_offset; - start = TT_NEXT_USHORT( p_start ); - end = TT_NEXT_USHORT( p_end ); - delta = TT_NEXT_SHORT( p_delta ); - offset = TT_NEXT_USHORT( p_offset ); - - if ( start > end ) - FT_INVALID_DATA; - - /* this test should be performed at default validation level; */ - /* unfortunately, some popular Asian fonts have overlapping */ - /* ranges in their charmaps */ - /* */ - if ( start <= last_end && n > 0 ) - { - if ( valid->level >= FT_VALIDATE_TIGHT ) - FT_INVALID_DATA; - else - { - /* allow overlapping segments, provided their start points */ - /* and end points, respectively, are in ascending order */ - /* */ - if ( last_start > start || last_end > end ) - error |= TT_CMAP_FLAG_UNSORTED; - else - error |= TT_CMAP_FLAG_OVERLAPPING; - } - } - - if ( offset && offset != 0xFFFFU ) - { - p += offset; /* start of glyph ID array */ - - /* check that we point within the glyph IDs table only */ - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - if ( p < glyph_ids || - p + ( end - start + 1 ) * 2 > table + length ) - FT_INVALID_DATA; - } - /* Some fonts handle the last segment incorrectly. In */ - /* theory, 0xFFFF might point to an ordinary glyph -- */ - /* a cmap 4 is versatile and could be used for any */ - /* encoding, not only Unicode. However, reality shows */ - /* that far too many fonts are sloppy and incorrectly */ - /* set all fields but `start' and `end' for the last */ - /* segment if it contains only a single character. */ - /* */ - /* We thus omit the test here, delaying it to the */ - /* routines which actually access the cmap. */ - else if ( n != num_segs - 1 || - !( start == 0xFFFFU && end == 0xFFFFU ) ) - { - if ( p < glyph_ids || - p + ( end - start + 1 ) * 2 > valid->limit ) - FT_INVALID_DATA; - } - - /* check glyph indices within the segment range */ - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - FT_UInt i, idx; - - - for ( i = start; i < end; i++ ) - { - idx = FT_NEXT_USHORT( p ); - if ( idx != 0 ) - { - idx = (FT_UInt)( idx + delta ) & 0xFFFFU; - - if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - } - } - } - } - else if ( offset == 0xFFFFU ) - { - /* some fonts (erroneously?) use a range offset of 0xFFFF */ - /* to mean missing glyph in cmap table */ - /* */ - if ( valid->level >= FT_VALIDATE_PARANOID || - n != num_segs - 1 || - !( start == 0xFFFFU && end == 0xFFFFU ) ) - FT_INVALID_DATA; - } - - last_start = start; - last_end = end; - } - } - - return error; - } - - - static FT_UInt - tt_cmap4_char_map_linear( TT_CMap cmap, - FT_UInt32* pcharcode, - FT_Bool next ) - { - FT_UInt num_segs2, start, end, offset; - FT_Int delta; - FT_UInt i, num_segs; - FT_UInt32 charcode = *pcharcode; - FT_UInt gindex = 0; - FT_Byte* p; - - - p = cmap->data + 6; - num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); - - num_segs = num_segs2 >> 1; - - if ( !num_segs ) - return 0; - - if ( next ) - charcode++; - - /* linear search */ - for ( ; charcode <= 0xFFFFU; charcode++ ) - { - FT_Byte* q; - - - p = cmap->data + 14; /* ends table */ - q = cmap->data + 16 + num_segs2; /* starts table */ - - for ( i = 0; i < num_segs; i++ ) - { - end = TT_NEXT_USHORT( p ); - start = TT_NEXT_USHORT( q ); - - if ( charcode >= start && charcode <= end ) - { - p = q - 2 + num_segs2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - - /* some fonts have an incorrect last segment; */ - /* we have to catch it */ - if ( i >= num_segs - 1 && - start == 0xFFFFU && end == 0xFFFFU ) - { - TT_Face face = (TT_Face)cmap->cmap.charmap.face; - FT_Byte* limit = face->cmap_table + face->cmap_size; - - - if ( offset && p + offset + 2 > limit ) - { - delta = 1; - offset = 0; - } - } - - if ( offset == 0xFFFFU ) - continue; - - if ( offset ) - { - p += offset + ( charcode - start ) * 2; - gindex = TT_PEEK_USHORT( p ); - if ( gindex != 0 ) - gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; - } - else - gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; - - break; - } - } - - if ( !next || gindex ) - break; - } - - if ( next && gindex ) - *pcharcode = charcode; - - return gindex; - } - - - static FT_UInt - tt_cmap4_char_map_binary( TT_CMap cmap, - FT_UInt32* pcharcode, - FT_Bool next ) - { - FT_UInt num_segs2, start, end, offset; - FT_Int delta; - FT_UInt max, min, mid, num_segs; - FT_UInt charcode = (FT_UInt)*pcharcode; - FT_UInt gindex = 0; - FT_Byte* p; - - - p = cmap->data + 6; - num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); - - if ( !num_segs2 ) - return 0; - - num_segs = num_segs2 >> 1; - - /* make compiler happy */ - mid = num_segs; - end = 0xFFFFU; - - if ( next ) - charcode++; - - min = 0; - max = num_segs; - - /* binary search */ - while ( min < max ) - { - mid = ( min + max ) >> 1; - p = cmap->data + 14 + mid * 2; - end = TT_PEEK_USHORT( p ); - p += 2 + num_segs2; - start = TT_PEEK_USHORT( p ); - - if ( charcode < start ) - max = mid; - else if ( charcode > end ) - min = mid + 1; - else - { - p += num_segs2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - - /* some fonts have an incorrect last segment; */ - /* we have to catch it */ - if ( mid >= num_segs - 1 && - start == 0xFFFFU && end == 0xFFFFU ) - { - TT_Face face = (TT_Face)cmap->cmap.charmap.face; - FT_Byte* limit = face->cmap_table + face->cmap_size; - - - if ( offset && p + offset + 2 > limit ) - { - delta = 1; - offset = 0; - } - } - - /* search the first segment containing `charcode' */ - if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) - { - FT_UInt i; - - - /* call the current segment `max' */ - max = mid; - - if ( offset == 0xFFFFU ) - mid = max + 1; - - /* search in segments before the current segment */ - for ( i = max ; i > 0; i-- ) - { - FT_UInt prev_end; - FT_Byte* old_p; - - - old_p = p; - p = cmap->data + 14 + ( i - 1 ) * 2; - prev_end = TT_PEEK_USHORT( p ); - - if ( charcode > prev_end ) - { - p = old_p; - break; - } - - end = prev_end; - p += 2 + num_segs2; - start = TT_PEEK_USHORT( p ); - p += num_segs2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - - if ( offset != 0xFFFFU ) - mid = i - 1; - } - - /* no luck */ - if ( mid == max + 1 ) - { - if ( i != max ) - { - p = cmap->data + 14 + max * 2; - end = TT_PEEK_USHORT( p ); - p += 2 + num_segs2; - start = TT_PEEK_USHORT( p ); - p += num_segs2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - } - - mid = max; - - /* search in segments after the current segment */ - for ( i = max + 1; i < num_segs; i++ ) - { - FT_UInt next_end, next_start; - - - p = cmap->data + 14 + i * 2; - next_end = TT_PEEK_USHORT( p ); - p += 2 + num_segs2; - next_start = TT_PEEK_USHORT( p ); - - if ( charcode < next_start ) - break; - - end = next_end; - start = next_start; - p += num_segs2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - - if ( offset != 0xFFFFU ) - mid = i; - } - i--; - - /* still no luck */ - if ( mid == max ) - { - mid = i; - - break; - } - } - - /* end, start, delta, and offset are for the i'th segment */ - if ( mid != i ) - { - p = cmap->data + 14 + mid * 2; - end = TT_PEEK_USHORT( p ); - p += 2 + num_segs2; - start = TT_PEEK_USHORT( p ); - p += num_segs2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - } - } - else - { - if ( offset == 0xFFFFU ) - break; - } - - if ( offset ) - { - p += offset + ( charcode - start ) * 2; - gindex = TT_PEEK_USHORT( p ); - if ( gindex != 0 ) - gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; - } - else - gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; - - break; - } - } - - if ( next ) - { - TT_CMap4 cmap4 = (TT_CMap4)cmap; - - - /* if `charcode' is not in any segment, then `mid' is */ - /* the segment nearest to `charcode' */ - /* */ - - if ( charcode > end ) - { - mid++; - if ( mid == num_segs ) - return 0; - } - - if ( tt_cmap4_set_range( cmap4, mid ) ) - { - if ( gindex ) - *pcharcode = charcode; - } - else - { - cmap4->cur_charcode = charcode; - - if ( gindex ) - cmap4->cur_gindex = gindex; - else - { - cmap4->cur_charcode = charcode; - tt_cmap4_next( cmap4 ); - gindex = cmap4->cur_gindex; - } - - if ( gindex ) - *pcharcode = cmap4->cur_charcode; - } - } - - return gindex; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap4_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - if ( char_code >= 0x10000UL ) - return 0; - - if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) - return tt_cmap4_char_map_linear( cmap, &char_code, 0 ); - else - return tt_cmap4_char_map_binary( cmap, &char_code, 0 ); - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap4_char_next( TT_CMap cmap, - FT_UInt32 *pchar_code ) - { - FT_UInt gindex; - - - if ( *pchar_code >= 0xFFFFU ) - return 0; - - if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) - gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 ); - else - { - TT_CMap4 cmap4 = (TT_CMap4)cmap; - - - /* no need to search */ - if ( *pchar_code == cmap4->cur_charcode ) - { - tt_cmap4_next( cmap4 ); - gindex = cmap4->cur_gindex; - if ( gindex ) - *pchar_code = cmap4->cur_charcode; - } - else - gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 ); - } - - return gindex; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap4_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_Byte* p = cmap->data + 4; - - - cmap_info->format = 4; - cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); - - return FT_Err_Ok; - } - - - FT_DEFINE_TT_CMAP( - tt_cmap4_class_rec, - sizeof ( TT_CMap4Rec ), - (FT_CMap_InitFunc) tt_cmap4_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap4_char_index, - (FT_CMap_CharNextFunc) tt_cmap4_char_next, - - NULL, - NULL, - NULL, - NULL, - NULL, - - 4, - (TT_CMap_ValidateFunc)tt_cmap4_validate, - (TT_CMap_Info_GetFunc)tt_cmap4_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_4 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 6 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 4 */ - /* length 2 USHORT table length in bytes */ - /* language 4 USHORT Mac language code */ - /* */ - /* first 6 USHORT first segment code */ - /* count 8 USHORT segment size in chars */ - /* glyphIds 10 USHORT[count] glyph IDs */ - /* */ - /* A very simplified segment mapping. */ - /* */ - -#ifdef TT_CONFIG_CMAP_FORMAT_6 - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap6_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p; - FT_UInt length, count; - - - if ( table + 10 > valid->limit ) - FT_INVALID_TOO_SHORT; - - p = table + 2; - length = TT_NEXT_USHORT( p ); - - p = table + 8; /* skip language and start index */ - count = TT_NEXT_USHORT( p ); - - if ( table + length > valid->limit || length < 10 + count * 2 ) - FT_INVALID_TOO_SHORT; - - /* check glyph indices */ - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - FT_UInt gindex; - - - for ( ; count > 0; count-- ) - { - gindex = TT_NEXT_USHORT( p ); - if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - } - } - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap6_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - FT_Byte* table = cmap->data; - FT_UInt result = 0; - FT_Byte* p = table + 6; - FT_UInt start = TT_NEXT_USHORT( p ); - FT_UInt count = TT_NEXT_USHORT( p ); - FT_UInt idx = (FT_UInt)( char_code - start ); - - - if ( idx < count ) - { - p += 2 * idx; - result = TT_PEEK_USHORT( p ); - } - return result; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap6_char_next( TT_CMap cmap, - FT_UInt32 *pchar_code ) - { - FT_Byte* table = cmap->data; - FT_UInt32 result = 0; - FT_UInt32 char_code = *pchar_code + 1; - FT_UInt gindex = 0; - - FT_Byte* p = table + 6; - FT_UInt start = TT_NEXT_USHORT( p ); - FT_UInt count = TT_NEXT_USHORT( p ); - FT_UInt idx; - - - if ( char_code >= 0x10000UL ) - goto Exit; - - if ( char_code < start ) - char_code = start; - - idx = (FT_UInt)( char_code - start ); - p += 2 * idx; - - for ( ; idx < count; idx++ ) - { - gindex = TT_NEXT_USHORT( p ); - if ( gindex != 0 ) - { - result = char_code; - break; - } - char_code++; - } - - Exit: - *pchar_code = result; - return gindex; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap6_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_Byte* p = cmap->data + 4; - - - cmap_info->format = 6; - cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); - - return FT_Err_Ok; - } - - - FT_DEFINE_TT_CMAP( - tt_cmap6_class_rec, - sizeof ( TT_CMapRec ), - - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap6_char_index, - (FT_CMap_CharNextFunc) tt_cmap6_char_next, - - NULL, - NULL, - NULL, - NULL, - NULL, - - 6, - (TT_CMap_ValidateFunc)tt_cmap6_validate, - (TT_CMap_Info_GetFunc)tt_cmap6_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_6 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 8 *****/ - /***** *****/ - /***** It is hard to completely understand what the OpenType spec *****/ - /***** says about this format, but here is my conclusion. *****/ - /***** *****/ - /***** The purpose of this format is to easily map UTF-16 text to *****/ - /***** glyph indices. Basically, the `char_code' must be in one of *****/ - /***** the following formats: *****/ - /***** *****/ - /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ - /***** Area (i.e. U+D800-U+DFFF). *****/ - /***** *****/ - /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ - /***** `char_code = (char_hi << 16) | char_lo', then both *****/ - /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ - /***** Area. *****/ - /***** *****/ - /***** The `is32' table embedded in the charmap indicates whether a *****/ - /***** given 16-bit value is in the surrogates area or not. *****/ - /***** *****/ - /***** So, for any given `char_code', we can assert the following: *****/ - /***** *****/ - /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ - /***** *****/ - /***** If `char_hi != 0' then we must have both *****/ - /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 8 */ - /* reserved 2 USHORT reserved */ - /* length 4 ULONG length in bytes */ - /* language 8 ULONG Mac language code */ - /* is32 12 BYTE[8192] 32-bitness bitmap */ - /* count 8204 ULONG number of groups */ - /* */ - /* This header is followed by `count' groups of the following format: */ - /* */ - /* start 0 ULONG first charcode */ - /* end 4 ULONG last charcode */ - /* startId 8 ULONG start glyph ID for the group */ - /* */ - -#ifdef TT_CONFIG_CMAP_FORMAT_8 - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap8_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p = table + 4; - FT_Byte* is32; - FT_UInt32 length; - FT_UInt32 num_groups; - - - if ( table + 16 + 8192 > valid->limit ) - FT_INVALID_TOO_SHORT; - - length = TT_NEXT_ULONG( p ); - if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) - FT_INVALID_TOO_SHORT; - - is32 = table + 12; - p = is32 + 8192; /* skip `is32' array */ - num_groups = TT_NEXT_ULONG( p ); - - if ( p + num_groups * 12 > valid->limit ) - FT_INVALID_TOO_SHORT; - - /* check groups, they must be in increasing order */ - { - FT_UInt32 n, start, end, start_id, count, last = 0; - - - for ( n = 0; n < num_groups; n++ ) - { - FT_UInt hi, lo; - - - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - start_id = TT_NEXT_ULONG( p ); - - if ( start > end ) - FT_INVALID_DATA; - - if ( n > 0 && start <= last ) - FT_INVALID_DATA; - - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - - count = (FT_UInt32)( end - start + 1 ); - - if ( start & ~0xFFFFU ) - { - /* start_hi != 0; check that is32[i] is 1 for each i in */ - /* the `hi' and `lo' of the range [start..end] */ - for ( ; count > 0; count--, start++ ) - { - hi = (FT_UInt)( start >> 16 ); - lo = (FT_UInt)( start & 0xFFFFU ); - - if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 ) - FT_INVALID_DATA; - - if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 ) - FT_INVALID_DATA; - } - } - else - { - /* start_hi == 0; check that is32[i] is 0 for each i in */ - /* the range [start..end] */ - - /* end_hi cannot be != 0! */ - if ( end & ~0xFFFFU ) - FT_INVALID_DATA; - - for ( ; count > 0; count--, start++ ) - { - lo = (FT_UInt)( start & 0xFFFFU ); - - if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 ) - FT_INVALID_DATA; - } - } - } - - last = end; - } - } - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap8_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - FT_Byte* table = cmap->data; - FT_UInt result = 0; - FT_Byte* p = table + 8204; - FT_UInt32 num_groups = TT_NEXT_ULONG( p ); - FT_UInt32 start, end, start_id; - - - for ( ; num_groups > 0; num_groups-- ) - { - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - start_id = TT_NEXT_ULONG( p ); - - if ( char_code < start ) - break; - - if ( char_code <= end ) - { - result = (FT_UInt)( start_id + char_code - start ); - break; - } - } - return result; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap8_char_next( TT_CMap cmap, - FT_UInt32 *pchar_code ) - { - FT_UInt32 result = 0; - FT_UInt32 char_code = *pchar_code + 1; - FT_UInt gindex = 0; - FT_Byte* table = cmap->data; - FT_Byte* p = table + 8204; - FT_UInt32 num_groups = TT_NEXT_ULONG( p ); - FT_UInt32 start, end, start_id; - - - p = table + 8208; - - for ( ; num_groups > 0; num_groups-- ) - { - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - start_id = TT_NEXT_ULONG( p ); - - if ( char_code < start ) - char_code = start; - - if ( char_code <= end ) - { - gindex = (FT_UInt)( char_code - start + start_id ); - if ( gindex != 0 ) - { - result = char_code; - goto Exit; - } - } - } - - Exit: - *pchar_code = result; - return gindex; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap8_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_Byte* p = cmap->data + 8; - - - cmap_info->format = 8; - cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); - - return FT_Err_Ok; - } - - - FT_DEFINE_TT_CMAP( - tt_cmap8_class_rec, - sizeof ( TT_CMapRec ), - - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap8_char_index, - (FT_CMap_CharNextFunc) tt_cmap8_char_next, - - NULL, - NULL, - NULL, - NULL, - NULL, - - 8, - (TT_CMap_ValidateFunc)tt_cmap8_validate, - (TT_CMap_Info_GetFunc)tt_cmap8_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_8 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 10 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 10 */ - /* reserved 2 USHORT reserved */ - /* length 4 ULONG length in bytes */ - /* language 8 ULONG Mac language code */ - /* */ - /* start 12 ULONG first char in range */ - /* count 16 ULONG number of chars in range */ - /* glyphIds 20 USHORT[count] glyph indices covered */ - /* */ - -#ifdef TT_CONFIG_CMAP_FORMAT_10 - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap10_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p = table + 4; - FT_ULong length, count; - - - if ( table + 20 > valid->limit ) - FT_INVALID_TOO_SHORT; - - length = TT_NEXT_ULONG( p ); - p = table + 16; - count = TT_NEXT_ULONG( p ); - - if ( length > (FT_ULong)( valid->limit - table ) || - length < 20 + count * 2 ) - FT_INVALID_TOO_SHORT; - - /* check glyph indices */ - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - FT_UInt gindex; - - - for ( ; count > 0; count-- ) - { - gindex = TT_NEXT_USHORT( p ); - if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - } - } - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap10_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - FT_Byte* table = cmap->data; - FT_UInt result = 0; - FT_Byte* p = table + 12; - FT_UInt32 start = TT_NEXT_ULONG( p ); - FT_UInt32 count = TT_NEXT_ULONG( p ); - FT_UInt32 idx = (FT_ULong)( char_code - start ); - - - if ( idx < count ) - { - p += 2 * idx; - result = TT_PEEK_USHORT( p ); - } - return result; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap10_char_next( TT_CMap cmap, - FT_UInt32 *pchar_code ) - { - FT_Byte* table = cmap->data; - FT_UInt32 char_code = *pchar_code + 1; - FT_UInt gindex = 0; - FT_Byte* p = table + 12; - FT_UInt32 start = TT_NEXT_ULONG( p ); - FT_UInt32 count = TT_NEXT_ULONG( p ); - FT_UInt32 idx; - - - if ( char_code < start ) - char_code = start; - - idx = (FT_UInt32)( char_code - start ); - p += 2 * idx; - - for ( ; idx < count; idx++ ) - { - gindex = TT_NEXT_USHORT( p ); - if ( gindex != 0 ) - break; - char_code++; - } - - *pchar_code = char_code; - return gindex; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap10_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_Byte* p = cmap->data + 8; - - - cmap_info->format = 10; - cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); - - return FT_Err_Ok; - } - - - FT_DEFINE_TT_CMAP( - tt_cmap10_class_rec, - sizeof ( TT_CMapRec ), - - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap10_char_index, - (FT_CMap_CharNextFunc) tt_cmap10_char_next, - - NULL, - NULL, - NULL, - NULL, - NULL, - - 10, - (TT_CMap_ValidateFunc)tt_cmap10_validate, - (TT_CMap_Info_GetFunc)tt_cmap10_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_10 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 12 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 12 */ - /* reserved 2 USHORT reserved */ - /* length 4 ULONG length in bytes */ - /* language 8 ULONG Mac language code */ - /* count 12 ULONG number of groups */ - /* 16 */ - /* */ - /* This header is followed by `count' groups of the following format: */ - /* */ - /* start 0 ULONG first charcode */ - /* end 4 ULONG last charcode */ - /* startId 8 ULONG start glyph ID for the group */ - /* */ - -#ifdef TT_CONFIG_CMAP_FORMAT_12 - - typedef struct TT_CMap12Rec_ - { - TT_CMapRec cmap; - FT_Bool valid; - FT_ULong cur_charcode; - FT_UInt cur_gindex; - FT_ULong cur_group; - FT_ULong num_groups; - - } TT_CMap12Rec, *TT_CMap12; - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap12_init( TT_CMap12 cmap, - FT_Byte* table ) - { - cmap->cmap.data = table; - - table += 12; - cmap->num_groups = FT_PEEK_ULONG( table ); - - cmap->valid = 0; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap12_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p; - FT_ULong length; - FT_ULong num_groups; - - - if ( table + 16 > valid->limit ) - FT_INVALID_TOO_SHORT; - - p = table + 4; - length = TT_NEXT_ULONG( p ); - - p = table + 12; - num_groups = TT_NEXT_ULONG( p ); - - if ( length > (FT_ULong)( valid->limit - table ) || - length < 16 + 12 * num_groups ) - FT_INVALID_TOO_SHORT; - - /* check groups, they must be in increasing order */ - { - FT_ULong n, start, end, start_id, last = 0; - - - for ( n = 0; n < num_groups; n++ ) - { - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - start_id = TT_NEXT_ULONG( p ); - - if ( start > end ) - FT_INVALID_DATA; - - if ( n > 0 && start <= last ) - FT_INVALID_DATA; - - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - } - - last = end; - } - } - - return FT_Err_Ok; - } - - - /* search the index of the charcode next to cmap->cur_charcode */ - /* cmap->cur_group should be set up properly by caller */ - /* */ - static void - tt_cmap12_next( TT_CMap12 cmap ) - { - FT_Byte* p; - FT_ULong start, end, start_id, char_code; - FT_ULong n; - FT_UInt gindex; - - - if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) - goto Fail; - - char_code = cmap->cur_charcode + 1; - - n = cmap->cur_group; - - for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) - { - p = cmap->cmap.data + 16 + 12 * n; - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - start_id = TT_PEEK_ULONG( p ); - - if ( char_code < start ) - char_code = start; - - for ( ; char_code <= end; char_code++ ) - { - gindex = (FT_UInt)( start_id + char_code - start ); - - if ( gindex ) - { - cmap->cur_charcode = char_code;; - cmap->cur_gindex = gindex; - cmap->cur_group = n; - - return; - } - } - } - - Fail: - cmap->valid = 0; - } - - - static FT_UInt - tt_cmap12_char_map_binary( TT_CMap cmap, - FT_UInt32* pchar_code, - FT_Bool next ) - { - FT_UInt gindex = 0; - FT_Byte* p = cmap->data + 12; - FT_UInt32 num_groups = TT_PEEK_ULONG( p ); - FT_UInt32 char_code = *pchar_code; - FT_UInt32 start, end, start_id; - FT_UInt32 max, min, mid; - - - if ( !num_groups ) - return 0; - - /* make compiler happy */ - mid = num_groups; - end = 0xFFFFFFFFUL; - - if ( next ) - char_code++; - - min = 0; - max = num_groups; - - /* binary search */ - while ( min < max ) - { - mid = ( min + max ) >> 1; - p = cmap->data + 16 + 12 * mid; - - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - - if ( char_code < start ) - max = mid; - else if ( char_code > end ) - min = mid + 1; - else - { - start_id = TT_PEEK_ULONG( p ); - gindex = (FT_UInt)( start_id + char_code - start ); - - break; - } - } - - if ( next ) - { - TT_CMap12 cmap12 = (TT_CMap12)cmap; - - - /* if `char_code' is not in any group, then `mid' is */ - /* the group nearest to `char_code' */ - /* */ - - if ( char_code > end ) - { - mid++; - if ( mid == num_groups ) - return 0; - } - - cmap12->valid = 1; - cmap12->cur_charcode = char_code; - cmap12->cur_group = mid; - - if ( !gindex ) - { - tt_cmap12_next( cmap12 ); - - if ( cmap12->valid ) - gindex = cmap12->cur_gindex; - } - else - cmap12->cur_gindex = gindex; - - if ( gindex ) - *pchar_code = cmap12->cur_charcode; - } - - return gindex; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap12_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap12_char_next( TT_CMap cmap, - FT_UInt32 *pchar_code ) - { - TT_CMap12 cmap12 = (TT_CMap12)cmap; - FT_ULong gindex; - - - if ( cmap12->cur_charcode >= 0xFFFFFFFFUL ) - return 0; - - /* no need to search */ - if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) - { - tt_cmap12_next( cmap12 ); - if ( cmap12->valid ) - { - gindex = cmap12->cur_gindex; - - /* XXX: check cur_charcode overflow is expected */ - if ( gindex ) - *pchar_code = (FT_UInt32)cmap12->cur_charcode; - } - else - gindex = 0; - } - else - gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); - - /* XXX: check gindex overflow is expected */ - return (FT_UInt32)gindex; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap12_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_Byte* p = cmap->data + 8; - - - cmap_info->format = 12; - cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); - - return FT_Err_Ok; - } - - - FT_DEFINE_TT_CMAP( - tt_cmap12_class_rec, - sizeof ( TT_CMap12Rec ), - - (FT_CMap_InitFunc) tt_cmap12_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap12_char_index, - (FT_CMap_CharNextFunc) tt_cmap12_char_next, - - NULL, - NULL, - NULL, - NULL, - NULL, - - 12, - (TT_CMap_ValidateFunc)tt_cmap12_validate, - (TT_CMap_Info_GetFunc)tt_cmap12_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_12 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 13 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 13 */ - /* reserved 2 USHORT reserved */ - /* length 4 ULONG length in bytes */ - /* language 8 ULONG Mac language code */ - /* count 12 ULONG number of groups */ - /* 16 */ - /* */ - /* This header is followed by `count' groups of the following format: */ - /* */ - /* start 0 ULONG first charcode */ - /* end 4 ULONG last charcode */ - /* glyphId 8 ULONG glyph ID for the whole group */ - /* */ - -#ifdef TT_CONFIG_CMAP_FORMAT_13 - - typedef struct TT_CMap13Rec_ - { - TT_CMapRec cmap; - FT_Bool valid; - FT_ULong cur_charcode; - FT_UInt cur_gindex; - FT_ULong cur_group; - FT_ULong num_groups; - - } TT_CMap13Rec, *TT_CMap13; - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap13_init( TT_CMap13 cmap, - FT_Byte* table ) - { - cmap->cmap.data = table; - - table += 12; - cmap->num_groups = FT_PEEK_ULONG( table ); - - cmap->valid = 0; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap13_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p; - FT_ULong length; - FT_ULong num_groups; - - - if ( table + 16 > valid->limit ) - FT_INVALID_TOO_SHORT; - - p = table + 4; - length = TT_NEXT_ULONG( p ); - - p = table + 12; - num_groups = TT_NEXT_ULONG( p ); - - if ( length > (FT_ULong)( valid->limit - table ) || - length < 16 + 12 * num_groups ) - FT_INVALID_TOO_SHORT; - - /* check groups, they must be in increasing order */ - { - FT_ULong n, start, end, glyph_id, last = 0; - - - for ( n = 0; n < num_groups; n++ ) - { - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - glyph_id = TT_NEXT_ULONG( p ); - - if ( start > end ) - FT_INVALID_DATA; - - if ( n > 0 && start <= last ) - FT_INVALID_DATA; - - if ( valid->level >= FT_VALIDATE_TIGHT ) - { - if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - } - - last = end; - } - } - - return FT_Err_Ok; - } - - - /* search the index of the charcode next to cmap->cur_charcode */ - /* cmap->cur_group should be set up properly by caller */ - /* */ - static void - tt_cmap13_next( TT_CMap13 cmap ) - { - FT_Byte* p; - FT_ULong start, end, glyph_id, char_code; - FT_ULong n; - FT_UInt gindex; - - - if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) - goto Fail; - - char_code = cmap->cur_charcode + 1; - - n = cmap->cur_group; - - for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) - { - p = cmap->cmap.data + 16 + 12 * n; - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - glyph_id = TT_PEEK_ULONG( p ); - - if ( char_code < start ) - char_code = start; - - if ( char_code <= end ) - { - gindex = (FT_UInt)glyph_id; - - if ( gindex ) - { - cmap->cur_charcode = char_code;; - cmap->cur_gindex = gindex; - cmap->cur_group = n; - - return; - } - } - } - - Fail: - cmap->valid = 0; - } - - - static FT_UInt - tt_cmap13_char_map_binary( TT_CMap cmap, - FT_UInt32* pchar_code, - FT_Bool next ) - { - FT_UInt gindex = 0; - FT_Byte* p = cmap->data + 12; - FT_UInt32 num_groups = TT_PEEK_ULONG( p ); - FT_UInt32 char_code = *pchar_code; - FT_UInt32 start, end; - FT_UInt32 max, min, mid; - - - if ( !num_groups ) - return 0; - - /* make compiler happy */ - mid = num_groups; - end = 0xFFFFFFFFUL; - - if ( next ) - char_code++; - - min = 0; - max = num_groups; - - /* binary search */ - while ( min < max ) - { - mid = ( min + max ) >> 1; - p = cmap->data + 16 + 12 * mid; - - start = TT_NEXT_ULONG( p ); - end = TT_NEXT_ULONG( p ); - - if ( char_code < start ) - max = mid; - else if ( char_code > end ) - min = mid + 1; - else - { - gindex = (FT_UInt)TT_PEEK_ULONG( p ); - - break; - } - } - - if ( next ) - { - TT_CMap13 cmap13 = (TT_CMap13)cmap; - - - /* if `char_code' is not in any group, then `mid' is */ - /* the group nearest to `char_code' */ - - if ( char_code > end ) - { - mid++; - if ( mid == num_groups ) - return 0; - } - - cmap13->valid = 1; - cmap13->cur_charcode = char_code; - cmap13->cur_group = mid; - - if ( !gindex ) - { - tt_cmap13_next( cmap13 ); - - if ( cmap13->valid ) - gindex = cmap13->cur_gindex; - } - else - cmap13->cur_gindex = gindex; - - if ( gindex ) - *pchar_code = cmap13->cur_charcode; - } - - return gindex; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap13_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap13_char_next( TT_CMap cmap, - FT_UInt32 *pchar_code ) - { - TT_CMap13 cmap13 = (TT_CMap13)cmap; - FT_UInt gindex; - - - if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) - return 0; - - /* no need to search */ - if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) - { - tt_cmap13_next( cmap13 ); - if ( cmap13->valid ) - { - gindex = cmap13->cur_gindex; - if ( gindex ) - *pchar_code = cmap13->cur_charcode; - } - else - gindex = 0; - } - else - gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); - - return gindex; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap13_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_Byte* p = cmap->data + 8; - - - cmap_info->format = 13; - cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); - - return FT_Err_Ok; - } - - - FT_DEFINE_TT_CMAP( - tt_cmap13_class_rec, - sizeof ( TT_CMap13Rec ), - - (FT_CMap_InitFunc) tt_cmap13_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap13_char_index, - (FT_CMap_CharNextFunc) tt_cmap13_char_next, - - NULL, - NULL, - NULL, - NULL, - NULL, - - 13, - (TT_CMap_ValidateFunc)tt_cmap13_validate, - (TT_CMap_Info_GetFunc)tt_cmap13_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_13 */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FORMAT 14 *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 14 */ - /* length 2 ULONG table length in bytes */ - /* numSelector 6 ULONG number of variation sel. records */ - /* */ - /* Followed by numSelector records, each of which looks like */ - /* */ - /* varSelector 0 UINT24 Unicode codepoint of sel. */ - /* defaultOff 3 ULONG offset to a default UVS table */ - /* describing any variants to be found in */ - /* the normal Unicode subtable. */ - /* nonDefOff 7 ULONG offset to a non-default UVS table */ - /* describing any variants not in the */ - /* standard cmap, with GIDs here */ - /* (either offset may be 0 NULL) */ - /* */ - /* Selectors are sorted by code point. */ - /* */ - /* A default Unicode Variation Selector (UVS) subtable is just a list of */ - /* ranges of code points which are to be found in the standard cmap. No */ - /* glyph IDs (GIDs) here. */ - /* */ - /* numRanges 0 ULONG number of ranges following */ - /* */ - /* A range looks like */ - /* */ - /* uniStart 0 UINT24 code point of the first character in */ - /* this range */ - /* additionalCnt 3 UBYTE count of additional characters in this */ - /* range (zero means a range of a single */ - /* character) */ - /* */ - /* Ranges are sorted by `uniStart'. */ - /* */ - /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ - /* mappings from codepoint to GID. */ - /* */ - /* numMappings 0 ULONG number of mappings */ - /* */ - /* A range looks like */ - /* */ - /* uniStart 0 UINT24 code point of the first character in */ - /* this range */ - /* GID 3 USHORT and its GID */ - /* */ - /* Ranges are sorted by `uniStart'. */ - -#ifdef TT_CONFIG_CMAP_FORMAT_14 - - typedef struct TT_CMap14Rec_ - { - TT_CMapRec cmap; - FT_ULong num_selectors; - - /* This array is used to store the results of various - * cmap 14 query functions. The data is overwritten - * on each call to these functions. - */ - FT_UInt32 max_results; - FT_UInt32* results; - FT_Memory memory; - - } TT_CMap14Rec, *TT_CMap14; - - - FT_CALLBACK_DEF( void ) - tt_cmap14_done( TT_CMap14 cmap ) - { - FT_Memory memory = cmap->memory; - - - cmap->max_results = 0; - if ( memory != NULL && cmap->results != NULL ) - FT_FREE( cmap->results ); - } - - - static FT_Error - tt_cmap14_ensure( TT_CMap14 cmap, - FT_UInt32 num_results, - FT_Memory memory ) - { - FT_UInt32 old_max = cmap->max_results; - FT_Error error = FT_Err_Ok; - - - if ( num_results > cmap->max_results ) - { - cmap->memory = memory; - - if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) - return error; - - cmap->max_results = num_results; - } - - return error; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap14_init( TT_CMap14 cmap, - FT_Byte* table ) - { - cmap->cmap.data = table; - - table += 6; - cmap->num_selectors = FT_PEEK_ULONG( table ); - cmap->max_results = 0; - cmap->results = NULL; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap14_validate( FT_Byte* table, - FT_Validator valid ) - { - FT_Byte* p = table + 2; - FT_ULong length = TT_NEXT_ULONG( p ); - FT_ULong num_selectors = TT_NEXT_ULONG( p ); - - - if ( length > (FT_ULong)( valid->limit - table ) || - length < 10 + 11 * num_selectors ) - FT_INVALID_TOO_SHORT; - - /* check selectors, they must be in increasing order */ - { - /* we start lastVarSel at 1 because a variant selector value of 0 - * isn't valid. - */ - FT_ULong n, lastVarSel = 1; - - - for ( n = 0; n < num_selectors; n++ ) - { - FT_ULong varSel = TT_NEXT_UINT24( p ); - FT_ULong defOff = TT_NEXT_ULONG( p ); - FT_ULong nondefOff = TT_NEXT_ULONG( p ); - - - if ( defOff >= length || nondefOff >= length ) - FT_INVALID_TOO_SHORT; - - if ( varSel < lastVarSel ) - FT_INVALID_DATA; - - lastVarSel = varSel + 1; - - /* check the default table (these glyphs should be reached */ - /* through the normal Unicode cmap, no GIDs, just check order) */ - if ( defOff != 0 ) - { - FT_Byte* defp = table + defOff; - FT_ULong numRanges = TT_NEXT_ULONG( defp ); - FT_ULong i; - FT_ULong lastBase = 0; - - - if ( defp + numRanges * 4 > valid->limit ) - FT_INVALID_TOO_SHORT; - - for ( i = 0; i < numRanges; ++i ) - { - FT_ULong base = TT_NEXT_UINT24( defp ); - FT_ULong cnt = FT_NEXT_BYTE( defp ); - - - if ( base + cnt >= 0x110000UL ) /* end of Unicode */ - FT_INVALID_DATA; - - if ( base < lastBase ) - FT_INVALID_DATA; - - lastBase = base + cnt + 1U; - } - } - - /* and the non-default table (these glyphs are specified here) */ - if ( nondefOff != 0 ) - { - FT_Byte* ndp = table + nondefOff; - FT_ULong numMappings = TT_NEXT_ULONG( ndp ); - FT_ULong i, lastUni = 0; - - - if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) - FT_INVALID_TOO_SHORT; - - for ( i = 0; i < numMappings; ++i ) - { - FT_ULong uni = TT_NEXT_UINT24( ndp ); - FT_ULong gid = TT_NEXT_USHORT( ndp ); - - - if ( uni >= 0x110000UL ) /* end of Unicode */ - FT_INVALID_DATA; - - if ( uni < lastUni ) - FT_INVALID_DATA; - - lastUni = uni + 1U; - - if ( valid->level >= FT_VALIDATE_TIGHT && - gid >= TT_VALID_GLYPH_COUNT( valid ) ) - FT_INVALID_GLYPH_ID; - } - } - } - } - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap14_char_index( TT_CMap cmap, - FT_UInt32 char_code ) - { - FT_UNUSED( cmap ); - FT_UNUSED( char_code ); - - /* This can't happen */ - return 0; - } - - - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap14_char_next( TT_CMap cmap, - FT_UInt32 *pchar_code ) - { - FT_UNUSED( cmap ); - - /* This can't happen */ - *pchar_code = 0; - return 0; - } - - - FT_CALLBACK_DEF( FT_Error ) - tt_cmap14_get_info( TT_CMap cmap, - TT_CMapInfo *cmap_info ) - { - FT_UNUSED( cmap ); - - cmap_info->format = 14; - /* subtable 14 does not define a language field */ - cmap_info->language = 0xFFFFFFFFUL; - - return FT_Err_Ok; - } - - - static FT_UInt - tt_cmap14_char_map_def_binary( FT_Byte *base, - FT_UInt32 char_code ) - { - FT_UInt32 numRanges = TT_PEEK_ULONG( base ); - FT_UInt32 max, min; - - - min = 0; - max = numRanges; - - base += 4; - - /* binary search */ - while ( min < max ) - { - FT_UInt32 mid = ( min + max ) >> 1; - FT_Byte* p = base + 4 * mid; - FT_ULong start = TT_NEXT_UINT24( p ); - FT_UInt cnt = FT_NEXT_BYTE( p ); - - - if ( char_code < start ) - max = mid; - else if ( char_code > start+cnt ) - min = mid + 1; - else - return TRUE; - } - - return FALSE; - } - - - static FT_UInt - tt_cmap14_char_map_nondef_binary( FT_Byte *base, - FT_UInt32 char_code ) - { - FT_UInt32 numMappings = TT_PEEK_ULONG( base ); - FT_UInt32 max, min; - - - min = 0; - max = numMappings; - - base += 4; - - /* binary search */ - while ( min < max ) - { - FT_UInt32 mid = ( min + max ) >> 1; - FT_Byte* p = base + 5 * mid; - FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); - - - if ( char_code < uni ) - max = mid; - else if ( char_code > uni ) - min = mid + 1; - else - return TT_PEEK_USHORT( p ); - } - - return 0; - } - - - static FT_Byte* - tt_cmap14_find_variant( FT_Byte *base, - FT_UInt32 variantCode ) - { - FT_UInt32 numVar = TT_PEEK_ULONG( base ); - FT_UInt32 max, min; - - - min = 0; - max = numVar; - - base += 4; - - /* binary search */ - while ( min < max ) - { - FT_UInt32 mid = ( min + max ) >> 1; - FT_Byte* p = base + 11 * mid; - FT_ULong varSel = TT_NEXT_UINT24( p ); - - - if ( variantCode < varSel ) - max = mid; - else if ( variantCode > varSel ) - min = mid + 1; - else - return p; - } - - return NULL; - } - - - FT_CALLBACK_DEF( FT_UInt ) - tt_cmap14_char_var_index( TT_CMap cmap, - TT_CMap ucmap, - FT_UInt32 charcode, - FT_UInt32 variantSelector ) - { - FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); - FT_ULong defOff; - FT_ULong nondefOff; - - - if ( !p ) - return 0; - - defOff = TT_NEXT_ULONG( p ); - nondefOff = TT_PEEK_ULONG( p ); - - if ( defOff != 0 && - tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) - { - /* This is the default variant of this charcode. GID not stored */ - /* here; stored in the normal Unicode charmap instead. */ - return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); - } - - if ( nondefOff != 0 ) - return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, - charcode ); - - return 0; - } - - - FT_CALLBACK_DEF( FT_Int ) - tt_cmap14_char_var_isdefault( TT_CMap cmap, - FT_UInt32 charcode, - FT_UInt32 variantSelector ) - { - FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); - FT_ULong defOff; - FT_ULong nondefOff; - - - if ( !p ) - return -1; - - defOff = TT_NEXT_ULONG( p ); - nondefOff = TT_NEXT_ULONG( p ); - - if ( defOff != 0 && - tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) - return 1; - - if ( nondefOff != 0 && - tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, - charcode ) != 0 ) - return 0; - - return -1; - } - - - FT_CALLBACK_DEF( FT_UInt32* ) - tt_cmap14_variants( TT_CMap cmap, - FT_Memory memory ) - { - TT_CMap14 cmap14 = (TT_CMap14)cmap; - FT_UInt32 count = cmap14->num_selectors; - FT_Byte* p = cmap->data + 10; - FT_UInt32* result; - FT_UInt32 i; - - - if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) - return NULL; - - result = cmap14->results; - for ( i = 0; i < count; ++i ) - { - result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); - p += 8; - } - result[i] = 0; - - return result; - } - - - FT_CALLBACK_DEF( FT_UInt32 * ) - tt_cmap14_char_variants( TT_CMap cmap, - FT_Memory memory, - FT_UInt32 charCode ) - { - TT_CMap14 cmap14 = (TT_CMap14) cmap; - FT_UInt32 count = cmap14->num_selectors; - FT_Byte* p = cmap->data + 10; - FT_UInt32* q; - - - if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) - return NULL; - - for ( q = cmap14->results; count > 0; --count ) - { - FT_UInt32 varSel = TT_NEXT_UINT24( p ); - FT_ULong defOff = TT_NEXT_ULONG( p ); - FT_ULong nondefOff = TT_NEXT_ULONG( p ); - - - if ( ( defOff != 0 && - tt_cmap14_char_map_def_binary( cmap->data + defOff, - charCode ) ) || - ( nondefOff != 0 && - tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, - charCode ) != 0 ) ) - { - q[0] = varSel; - q++; - } - } - q[0] = 0; - - return cmap14->results; - } - - - static FT_UInt - tt_cmap14_def_char_count( FT_Byte *p ) - { - FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); - FT_UInt tot = 0; - - - p += 3; /* point to the first `cnt' field */ - for ( ; numRanges > 0; numRanges-- ) - { - tot += 1 + p[0]; - p += 4; - } - - return tot; - } - - - static FT_UInt32* - tt_cmap14_get_def_chars( TT_CMap cmap, - FT_Byte* p, - FT_Memory memory ) - { - TT_CMap14 cmap14 = (TT_CMap14) cmap; - FT_UInt32 numRanges; - FT_UInt cnt; - FT_UInt32* q; - - - cnt = tt_cmap14_def_char_count( p ); - numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); - - if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) - return NULL; - - for ( q = cmap14->results; numRanges > 0; --numRanges ) - { - FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); - - - cnt = FT_NEXT_BYTE( p ) + 1; - do - { - q[0] = uni; - uni += 1; - q += 1; - - } while ( --cnt != 0 ); - } - q[0] = 0; - - return cmap14->results; - } - - - static FT_UInt32* - tt_cmap14_get_nondef_chars( TT_CMap cmap, - FT_Byte *p, - FT_Memory memory ) - { - TT_CMap14 cmap14 = (TT_CMap14) cmap; - FT_UInt32 numMappings; - FT_UInt i; - FT_UInt32 *ret; - - - numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); - - if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) - return NULL; - - ret = cmap14->results; - for ( i = 0; i < numMappings; ++i ) - { - ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); - p += 2; - } - ret[i] = 0; - - return ret; - } - - - FT_CALLBACK_DEF( FT_UInt32 * ) - tt_cmap14_variant_chars( TT_CMap cmap, - FT_Memory memory, - FT_UInt32 variantSelector ) - { - FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, - variantSelector ); - FT_UInt32 *ret; - FT_Int i; - FT_ULong defOff; - FT_ULong nondefOff; - - - if ( !p ) - return NULL; - - defOff = TT_NEXT_ULONG( p ); - nondefOff = TT_NEXT_ULONG( p ); - - if ( defOff == 0 && nondefOff == 0 ) - return NULL; - - if ( defOff == 0 ) - return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, - memory ); - else if ( nondefOff == 0 ) - return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, - memory ); - else - { - /* Both a default and a non-default glyph set? That's probably not */ - /* good font design, but the spec allows for it... */ - TT_CMap14 cmap14 = (TT_CMap14) cmap; - FT_UInt32 numRanges; - FT_UInt32 numMappings; - FT_UInt32 duni; - FT_UInt32 dcnt; - FT_UInt32 nuni; - FT_Byte* dp; - FT_UInt di, ni, k; - - - p = cmap->data + nondefOff; - dp = cmap->data + defOff; - - numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); - dcnt = tt_cmap14_def_char_count( dp ); - numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); - - if ( numMappings == 0 ) - return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, - memory ); - if ( dcnt == 0 ) - return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, - memory ); - - if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) - return NULL; - - ret = cmap14->results; - duni = (FT_UInt32)TT_NEXT_UINT24( dp ); - dcnt = FT_NEXT_BYTE( dp ); - di = 1; - nuni = (FT_UInt32)TT_NEXT_UINT24( p ); - p += 2; - ni = 1; - i = 0; - - for ( ;; ) - { - if ( nuni > duni + dcnt ) - { - for ( k = 0; k <= dcnt; ++k ) - ret[i++] = duni + k; - - ++di; - - if ( di > numRanges ) - break; - - duni = (FT_UInt32)TT_NEXT_UINT24( dp ); - dcnt = FT_NEXT_BYTE( dp ); - } - else - { - if ( nuni < duni ) - ret[i++] = nuni; - /* If it is within the default range then ignore it -- */ - /* that should not have happened */ - ++ni; - if ( ni > numMappings ) - break; - - nuni = (FT_UInt32)TT_NEXT_UINT24( p ); - p += 2; - } - } - - if ( ni <= numMappings ) - { - /* If we get here then we have run out of all default ranges. */ - /* We have read one non-default mapping which we haven't stored */ - /* and there may be others that need to be read. */ - ret[i++] = nuni; - while ( ni < numMappings ) - { - ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); - p += 2; - ++ni; - } - } - else if ( di <= numRanges ) - { - /* If we get here then we have run out of all non-default */ - /* mappings. We have read one default range which we haven't */ - /* stored and there may be others that need to be read. */ - for ( k = 0; k <= dcnt; ++k ) - ret[i++] = duni + k; - - while ( di < numRanges ) - { - duni = (FT_UInt32)TT_NEXT_UINT24( dp ); - dcnt = FT_NEXT_BYTE( dp ); - - for ( k = 0; k <= dcnt; ++k ) - ret[i++] = duni + k; - ++di; - } - } - - ret[i] = 0; - - return ret; - } - } - - - FT_DEFINE_TT_CMAP( - tt_cmap14_class_rec, - sizeof ( TT_CMap14Rec ), - - (FT_CMap_InitFunc) tt_cmap14_init, - (FT_CMap_DoneFunc) tt_cmap14_done, - (FT_CMap_CharIndexFunc)tt_cmap14_char_index, - (FT_CMap_CharNextFunc) tt_cmap14_char_next, - - /* Format 14 extension functions */ - (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, - (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, - (FT_CMap_VariantListFunc) tt_cmap14_variants, - (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, - (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, - - 14, - (TT_CMap_ValidateFunc)tt_cmap14_validate, - (TT_CMap_Info_GetFunc)tt_cmap14_get_info ) - -#endif /* TT_CONFIG_CMAP_FORMAT_14 */ - - -#ifndef FT_CONFIG_OPTION_PIC - - static const TT_CMap_Class tt_cmap_classes[] = - { -#define TTCMAPCITEM( a ) &a, -#include "ttcmapc.h" - NULL, - }; - -#else /*FT_CONFIG_OPTION_PIC*/ - - void - FT_Destroy_Class_tt_cmap_classes( FT_Library library, - TT_CMap_Class* clazz ) - { - FT_Memory memory = library->memory; - - - if ( clazz ) - FT_FREE( clazz ); - } - - - FT_Error - FT_Create_Class_tt_cmap_classes( FT_Library library, - TT_CMap_Class** output_class ) - { - TT_CMap_Class* clazz = NULL; - TT_CMap_ClassRec* recs; - FT_Error error; - FT_Memory memory = library->memory; - - int i = 0; - - -#define TTCMAPCITEM( a ) i++; -#include "ttcmapc.h" - - /* allocate enough space for both the pointers */ - /* plus terminator and the class instances */ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * ( i + 1 ) + - sizeof ( TT_CMap_ClassRec ) * i ) ) - return error; - - /* the location of the class instances follows the array of pointers */ - recs = (TT_CMap_ClassRec*)( (char*)clazz + - sizeof ( *clazz ) * ( i + 1 ) ); - i = 0; - -#undef TTCMAPCITEM -#define TTCMAPCITEM( a ) \ - FT_Init_Class_ ## a( &recs[i] ); \ - clazz[i] = &recs[i]; \ - i++; -#include "ttcmapc.h" - - clazz[i] = NULL; - - *output_class = clazz; - return FT_Err_Ok; - } - -#endif /*FT_CONFIG_OPTION_PIC*/ - - - /* parse the `cmap' table and build the corresponding TT_CMap objects */ - /* in the current face */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_build_cmaps( TT_Face face ) - { - FT_Byte* table = face->cmap_table; - FT_Byte* limit = table + face->cmap_size; - FT_UInt volatile num_cmaps; - FT_Byte* volatile p = table; - FT_Library library = FT_FACE_LIBRARY( face ); - - FT_UNUSED( library ); - - - if ( !p || p + 4 > limit ) - return FT_THROW( Invalid_Table ); - - /* only recognize format 0 */ - if ( TT_NEXT_USHORT( p ) != 0 ) - { - p -= 2; - FT_ERROR(( "tt_face_build_cmaps:" - " unsupported `cmap' table format = %d\n", - TT_PEEK_USHORT( p ) )); - return FT_THROW( Invalid_Table ); - } - - num_cmaps = TT_NEXT_USHORT( p ); - -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE ) - FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n" - " subtable #%d and higher are loaded" - " but cannot be searched\n", - num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 )); -#endif - - for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) - { - FT_CharMapRec charmap; - FT_UInt32 offset; - - - charmap.platform_id = TT_NEXT_USHORT( p ); - charmap.encoding_id = TT_NEXT_USHORT( p ); - charmap.face = FT_FACE( face ); - charmap.encoding = FT_ENCODING_NONE; /* will be filled later */ - offset = TT_NEXT_ULONG( p ); - - if ( offset && offset <= face->cmap_size - 2 ) - { - FT_Byte* volatile cmap = table + offset; - volatile FT_UInt format = TT_PEEK_USHORT( cmap ); - const TT_CMap_Class* volatile pclazz = TT_CMAP_CLASSES_GET; - TT_CMap_Class volatile clazz; - - - for ( ; *pclazz; pclazz++ ) - { - clazz = *pclazz; - if ( clazz->format == format ) - { - volatile TT_ValidatorRec valid; - volatile FT_Error error = FT_Err_Ok; - - - ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, - FT_VALIDATE_DEFAULT ); - - valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs; - - if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 ) - { - /* validate this cmap sub-table */ - error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); - } - - if ( valid.validator.error == 0 ) - { - FT_CMap ttcmap; - - - /* It might make sense to store the single variation */ - /* selector cmap somewhere special. But it would have to be */ - /* in the public FT_FaceRec, and we can't change that. */ - - if ( !FT_CMap_New( (FT_CMap_Class)clazz, - cmap, &charmap, &ttcmap ) ) - { - /* it is simpler to directly set `flags' than adding */ - /* a parameter to FT_CMap_New */ - ((TT_CMap)ttcmap)->flags = (FT_Int)error; - } - } - else - { - FT_TRACE0(( "tt_face_build_cmaps:" - " broken cmap sub-table ignored\n" )); - } - break; - } - } - - if ( *pclazz == NULL ) - { - FT_TRACE0(( "tt_face_build_cmaps:" - " unsupported cmap sub-table ignored\n" )); - } - } - } - - return FT_Err_Ok; - } - - - FT_LOCAL( FT_Error ) - tt_get_cmap_info( FT_CharMap charmap, - TT_CMapInfo *cmap_info ) - { - FT_CMap cmap = (FT_CMap)charmap; - TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; - - - return clazz->get_cmap_info( charmap, cmap_info ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttcmap.h b/drivers/freetype/freetype/src/sfnt/ttcmap.h deleted file mode 100644 index 0fde1676bf..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttcmap.h +++ /dev/null @@ -1,158 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.h */ -/* */ -/* TrueType character mapping table (cmap) support (specification). */ -/* */ -/* Copyright 2002-2005, 2009, 2012 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 __TTCMAP_H__ -#define __TTCMAP_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_TRUETYPE_TYPES_H -#include FT_INTERNAL_VALIDATE_H -#include FT_SERVICE_TT_CMAP_H - -FT_BEGIN_HEADER - - -#define TT_CMAP_FLAG_UNSORTED 1 -#define TT_CMAP_FLAG_OVERLAPPING 2 - - typedef struct TT_CMapRec_ - { - FT_CMapRec cmap; - FT_Byte* data; /* pointer to in-memory cmap table */ - FT_Int flags; /* for format 4 only */ - - } TT_CMapRec, *TT_CMap; - - typedef const struct TT_CMap_ClassRec_* TT_CMap_Class; - - - typedef FT_Error - (*TT_CMap_ValidateFunc)( FT_Byte* data, - FT_Validator valid ); - - typedef struct TT_CMap_ClassRec_ - { - FT_CMap_ClassRec clazz; - FT_UInt format; - TT_CMap_ValidateFunc validate; - TT_CMap_Info_GetFunc get_cmap_info; - - } TT_CMap_ClassRec; - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_TT_CMAP( class_, \ - size_, \ - init_, \ - done_, \ - char_index_, \ - char_next_, \ - char_var_index_, \ - char_var_default_, \ - variant_list_, \ - charvariant_list_, \ - variantchar_list_, \ - format_, \ - validate_, \ - get_cmap_info_ ) \ - FT_CALLBACK_TABLE_DEF \ - const TT_CMap_ClassRec class_ = \ - { \ - { size_, \ - init_, \ - done_, \ - char_index_, \ - char_next_, \ - char_var_index_, \ - char_var_default_, \ - variant_list_, \ - charvariant_list_, \ - variantchar_list_ \ - }, \ - \ - format_, \ - validate_, \ - get_cmap_info_ \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_TT_CMAP( class_, \ - size_, \ - init_, \ - done_, \ - char_index_, \ - char_next_, \ - char_var_index_, \ - char_var_default_, \ - variant_list_, \ - charvariant_list_, \ - variantchar_list_, \ - format_, \ - validate_, \ - get_cmap_info_ ) \ - void \ - FT_Init_Class_ ## class_( TT_CMap_ClassRec* clazz ) \ - { \ - clazz->clazz.size = size_; \ - clazz->clazz.init = init_; \ - clazz->clazz.done = done_; \ - clazz->clazz.char_index = char_index_; \ - clazz->clazz.char_next = char_next_; \ - clazz->clazz.char_var_index = char_var_index_; \ - clazz->clazz.char_var_default = char_var_default_; \ - clazz->clazz.variant_list = variant_list_; \ - clazz->clazz.charvariant_list = charvariant_list_; \ - clazz->clazz.variantchar_list = variantchar_list_; \ - clazz->format = format_; \ - clazz->validate = validate_; \ - clazz->get_cmap_info = get_cmap_info_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - typedef struct TT_ValidatorRec_ - { - FT_ValidatorRec validator; - FT_UInt num_glyphs; - - } TT_ValidatorRec, *TT_Validator; - - -#define TT_VALIDATOR( x ) ( (TT_Validator)( x ) ) -#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs - - - FT_LOCAL( FT_Error ) - tt_face_build_cmaps( TT_Face face ); - - /* used in tt-cmaps service */ - FT_LOCAL( FT_Error ) - tt_get_cmap_info( FT_CharMap charmap, - TT_CMapInfo *cmap_info ); - - -FT_END_HEADER - -#endif /* __TTCMAP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttcmapc.h b/drivers/freetype/freetype/src/sfnt/ttcmapc.h deleted file mode 100644 index 2ea204309c..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttcmapc.h +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmapc.h */ -/* */ -/* TT CMAP classes definitions (specification only). */ -/* */ -/* Copyright 2009 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef TT_CONFIG_CMAP_FORMAT_0 - TTCMAPCITEM( tt_cmap0_class_rec ) -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_2 - TTCMAPCITEM( tt_cmap2_class_rec ) -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_4 - TTCMAPCITEM( tt_cmap4_class_rec ) -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_6 - TTCMAPCITEM( tt_cmap6_class_rec ) -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_8 - TTCMAPCITEM( tt_cmap8_class_rec ) -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_10 - TTCMAPCITEM( tt_cmap10_class_rec ) -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_12 - TTCMAPCITEM( tt_cmap12_class_rec ) -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_13 - TTCMAPCITEM( tt_cmap13_class_rec ) -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_14 - TTCMAPCITEM( tt_cmap14_class_rec ) -#endif - - - /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttkern.c b/drivers/freetype/freetype/src/sfnt/ttkern.c deleted file mode 100644 index 60ee546d79..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttkern.c +++ /dev/null @@ -1,306 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttkern.c */ -/* */ -/* Load the basic TrueType kerning table. This doesn't handle */ -/* kerning data within the GPOS table at the moment. */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include "ttkern.h" - -#include "sferrors.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_ttkern - - -#undef TT_KERN_INDEX -#define TT_KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) - - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_kern( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_ULong table_size; - FT_Byte* p; - FT_Byte* p_limit; - FT_UInt nn, num_tables; - FT_UInt32 avail = 0, ordered = 0; - - - /* the kern table is optional; exit silently if it is missing */ - error = face->goto_table( face, TTAG_kern, stream, &table_size ); - if ( error ) - goto Exit; - - if ( table_size < 4 ) /* the case of a malformed table */ - { - FT_ERROR(( "tt_face_load_kern:" - " kerning table is too small - ignored\n" )); - error = FT_THROW( Table_Missing ); - goto Exit; - } - - if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) ) - { - FT_ERROR(( "tt_face_load_kern:" - " could not extract kerning table\n" )); - goto Exit; - } - - face->kern_table_size = table_size; - - p = face->kern_table; - p_limit = p + table_size; - - p += 2; /* skip version */ - num_tables = FT_NEXT_USHORT( p ); - - if ( num_tables > 32 ) /* we only support up to 32 sub-tables */ - num_tables = 32; - - for ( nn = 0; nn < num_tables; nn++ ) - { - FT_UInt num_pairs, length, coverage; - FT_Byte* p_next; - FT_UInt32 mask = (FT_UInt32)1UL << nn; - - - if ( p + 6 > p_limit ) - break; - - p_next = p; - - p += 2; /* skip version */ - length = FT_NEXT_USHORT( p ); - coverage = FT_NEXT_USHORT( p ); - - if ( length <= 6 ) - break; - - p_next += length; - - if ( p_next > p_limit ) /* handle broken table */ - p_next = p_limit; - - /* only use horizontal kerning tables */ - if ( ( coverage & ~8 ) != 0x0001 || - p + 8 > p_limit ) - goto NextTable; - - num_pairs = FT_NEXT_USHORT( p ); - p += 6; - - if ( ( p_next - p ) < 6 * (int)num_pairs ) /* handle broken count */ - num_pairs = (FT_UInt)( ( p_next - p ) / 6 ); - - avail |= mask; - - /* - * Now check whether the pairs in this table are ordered. - * We then can use binary search. - */ - if ( num_pairs > 0 ) - { - FT_ULong count; - FT_ULong old_pair; - - - old_pair = FT_NEXT_ULONG( p ); - p += 2; - - for ( count = num_pairs - 1; count > 0; count-- ) - { - FT_UInt32 cur_pair; - - - cur_pair = FT_NEXT_ULONG( p ); - if ( cur_pair <= old_pair ) - break; - - p += 2; - old_pair = cur_pair; - } - - if ( count == 0 ) - ordered |= mask; - } - - NextTable: - p = p_next; - } - - face->num_kern_tables = nn; - face->kern_avail_bits = avail; - face->kern_order_bits = ordered; - - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - tt_face_done_kern( TT_Face face ) - { - FT_Stream stream = face->root.stream; - - - FT_FRAME_RELEASE( face->kern_table ); - face->kern_table_size = 0; - face->num_kern_tables = 0; - face->kern_avail_bits = 0; - face->kern_order_bits = 0; - } - - - FT_LOCAL_DEF( FT_Int ) - tt_face_get_kerning( TT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph ) - { - FT_Int result = 0; - FT_UInt count, mask = 1; - FT_Byte* p = face->kern_table; - FT_Byte* p_limit = p + face->kern_table_size; - - - p += 4; - mask = 0x0001; - - for ( count = face->num_kern_tables; - count > 0 && p + 6 <= p_limit; - count--, mask <<= 1 ) - { - FT_Byte* base = p; - FT_Byte* next = base; - FT_UInt version = FT_NEXT_USHORT( p ); - FT_UInt length = FT_NEXT_USHORT( p ); - FT_UInt coverage = FT_NEXT_USHORT( p ); - FT_UInt num_pairs; - FT_Int value = 0; - - FT_UNUSED( version ); - - - next = base + length; - - if ( next > p_limit ) /* handle broken table */ - next = p_limit; - - if ( ( face->kern_avail_bits & mask ) == 0 ) - goto NextTable; - - if ( p + 8 > next ) - goto NextTable; - - num_pairs = FT_NEXT_USHORT( p ); - p += 6; - - if ( ( next - p ) < 6 * (int)num_pairs ) /* handle broken count */ - num_pairs = (FT_UInt)( ( next - p ) / 6 ); - - switch ( coverage >> 8 ) - { - case 0: - { - FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); - - - if ( face->kern_order_bits & mask ) /* binary search */ - { - FT_UInt min = 0; - FT_UInt max = num_pairs; - - - while ( min < max ) - { - FT_UInt mid = ( min + max ) >> 1; - FT_Byte* q = p + 6 * mid; - FT_ULong key; - - - key = FT_NEXT_ULONG( q ); - - if ( key == key0 ) - { - value = FT_PEEK_SHORT( q ); - goto Found; - } - if ( key < key0 ) - min = mid + 1; - else - max = mid; - } - } - else /* linear search */ - { - FT_UInt count2; - - - for ( count2 = num_pairs; count2 > 0; count2-- ) - { - FT_ULong key = FT_NEXT_ULONG( p ); - - - if ( key == key0 ) - { - value = FT_PEEK_SHORT( p ); - goto Found; - } - p += 2; - } - } - } - break; - - /* - * We don't support format 2 because we haven't seen a single font - * using it in real life... - */ - - default: - ; - } - - goto NextTable; - - Found: - if ( coverage & 8 ) /* override or add */ - result = value; - else - result += value; - - NextTable: - p = next; - } - - return result; - } - -#undef TT_KERN_INDEX - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttkern.h b/drivers/freetype/freetype/src/sfnt/ttkern.h deleted file mode 100644 index df1da9b273..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttkern.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttkern.h */ -/* */ -/* Load the basic TrueType kerning table. This doesn't handle */ -/* kerning data within the GPOS table at the moment. */ -/* */ -/* Copyright 1996-2001, 2002, 2005, 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 __TTKERN_H__ -#define __TTKERN_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_TRUETYPE_TYPES_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - tt_face_load_kern( TT_Face face, - FT_Stream stream ); - - FT_LOCAL( void ) - tt_face_done_kern( TT_Face face ); - - FT_LOCAL( FT_Int ) - tt_face_get_kerning( TT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph ); - -#define TT_FACE_HAS_KERNING( face ) ( (face)->kern_avail_bits != 0 ) - - -FT_END_HEADER - -#endif /* __TTKERN_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttload.c b/drivers/freetype/freetype/src/sfnt/ttload.c deleted file mode 100644 index fbe70f7974..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttload.c +++ /dev/null @@ -1,1269 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttload.c */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (body). */ -/* */ -/* Copyright 1996-2010, 2012, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include "ttload.h" - -#include "sferrors.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_ttload - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_lookup_table */ - /* */ - /* <Description> */ - /* Looks for a TrueType table by name. */ - /* */ - /* <Input> */ - /* face :: A face object handle. */ - /* */ - /* tag :: The searched tag. */ - /* */ - /* <Return> */ - /* A pointer to the table directory entry. 0 if not found. */ - /* */ - FT_LOCAL_DEF( TT_Table ) - tt_face_lookup_table( TT_Face face, - FT_ULong tag ) - { - TT_Table entry; - TT_Table limit; -#ifdef FT_DEBUG_LEVEL_TRACE - FT_Bool zero_length = FALSE; -#endif - - - FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ", - face, - (FT_Char)( tag >> 24 ), - (FT_Char)( tag >> 16 ), - (FT_Char)( tag >> 8 ), - (FT_Char)( tag ) )); - - entry = face->dir_tables; - limit = entry + face->num_tables; - - for ( ; entry < limit; entry++ ) - { - /* For compatibility with Windows, we consider */ - /* zero-length tables the same as missing tables. */ - if ( entry->Tag == tag ) - { - if ( entry->Length != 0 ) - { - FT_TRACE4(( "found table.\n" )); - return entry; - } -#ifdef FT_DEBUG_LEVEL_TRACE - zero_length = TRUE; -#endif - } - } - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( zero_length ) - FT_TRACE4(( "ignoring empty table\n" )); - else - FT_TRACE4(( "could not find table\n" )); -#endif - - return NULL; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_goto_table */ - /* */ - /* <Description> */ - /* Looks for a TrueType table by name, then seek a stream to it. */ - /* */ - /* <Input> */ - /* face :: A face object handle. */ - /* */ - /* tag :: The searched tag. */ - /* */ - /* stream :: The stream to seek when the table is found. */ - /* */ - /* <Output> */ - /* length :: The length of the table if found, undefined otherwise. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_goto_table( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ) - { - TT_Table table; - FT_Error error; - - - table = tt_face_lookup_table( face, tag ); - if ( table ) - { - if ( length ) - *length = table->Length; - - if ( FT_STREAM_SEEK( table->Offset ) ) - goto Exit; - } - else - error = FT_THROW( Table_Missing ); - - Exit: - return error; - } - - - /* Here, we */ - /* */ - /* - check that `num_tables' is valid (and adjust it if necessary) */ - /* */ - /* - look for a `head' table, check its size, and parse it to check */ - /* whether its `magic' field is correctly set */ - /* */ - /* - errors (except errors returned by stream handling) */ - /* */ - /* SFNT_Err_Unknown_File_Format: */ - /* no table is defined in directory, it is not sfnt-wrapped */ - /* data */ - /* SFNT_Err_Table_Missing: */ - /* table directory is valid, but essential tables */ - /* (head/bhed/SING) are missing */ - /* */ - static FT_Error - check_table_dir( SFNT_Header sfnt, - FT_Stream stream ) - { - FT_Error error; - FT_UShort nn, valid_entries = 0; - FT_UInt has_head = 0, has_sing = 0, has_meta = 0; - FT_ULong offset = sfnt->offset + 12; - - static const FT_Frame_Field table_dir_entry_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_TableRec - - FT_FRAME_START( 16 ), - FT_FRAME_ULONG( Tag ), - FT_FRAME_ULONG( CheckSum ), - FT_FRAME_ULONG( Offset ), - FT_FRAME_ULONG( Length ), - FT_FRAME_END - }; - - - if ( FT_STREAM_SEEK( offset ) ) - goto Exit; - - for ( nn = 0; nn < sfnt->num_tables; nn++ ) - { - TT_TableRec table; - - - if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) ) - { - nn--; - FT_TRACE2(( "check_table_dir:" - " can read only %d table%s in font (instead of %d)\n", - nn, nn == 1 ? "" : "s", sfnt->num_tables )); - sfnt->num_tables = nn; - break; - } - - /* we ignore invalid tables */ - if ( table.Offset + table.Length > stream->size ) - { - FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); - continue; - } - else - valid_entries++; - - if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) - { - FT_UInt32 magic; - - -#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - if ( table.Tag == TTAG_head ) -#endif - has_head = 1; - - /* - * The table length should be 0x36, but certain font tools make it - * 0x38, so we will just check that it is greater. - * - * Note that according to the specification, the table must be - * padded to 32-bit lengths, but this doesn't apply to the value of - * its `Length' field! - * - */ - if ( table.Length < 0x36 ) - { - FT_TRACE2(( "check_table_dir: `head' table too small\n" )); - error = FT_THROW( Table_Missing ); - goto Exit; - } - - if ( FT_STREAM_SEEK( table.Offset + 12 ) || - FT_READ_ULONG( magic ) ) - goto Exit; - - if ( magic != 0x5F0F3CF5UL ) - { - FT_TRACE2(( "check_table_dir:" - " no magic number found in `head' table\n")); - error = FT_THROW( Table_Missing ); - goto Exit; - } - - if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) - goto Exit; - } - else if ( table.Tag == TTAG_SING ) - has_sing = 1; - else if ( table.Tag == TTAG_META ) - has_meta = 1; - } - - sfnt->num_tables = valid_entries; - - if ( sfnt->num_tables == 0 ) - { - FT_TRACE2(( "check_table_dir: no tables found\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - /* if `sing' and `meta' tables are present, there is no `head' table */ - if ( has_head || ( has_sing && has_meta ) ) - { - error = FT_Err_Ok; - goto Exit; - } - else - { - FT_TRACE2(( "check_table_dir:" )); -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" )); -#else - FT_TRACE2(( " neither `head' nor `sing' table found\n" )); -#endif - error = FT_THROW( Table_Missing ); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_font_dir */ - /* */ - /* <Description> */ - /* Loads the header of a SFNT font file. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Output> */ - /* sfnt :: The SFNT header. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The stream cursor must be at the beginning of the font directory. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_font_dir( TT_Face face, - FT_Stream stream ) - { - SFNT_HeaderRec sfnt; - FT_Error error; - FT_Memory memory = stream->memory; - TT_TableRec* entry; - FT_Int nn; - - static const FT_Frame_Field offset_table_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE SFNT_HeaderRec - - FT_FRAME_START( 8 ), - FT_FRAME_USHORT( num_tables ), - FT_FRAME_USHORT( search_range ), - FT_FRAME_USHORT( entry_selector ), - FT_FRAME_USHORT( range_shift ), - FT_FRAME_END - }; - - - FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face )); - - /* read the offset table */ - - sfnt.offset = FT_STREAM_POS(); - - if ( FT_READ_ULONG( sfnt.format_tag ) || - FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) ) - goto Exit; - - /* many fonts don't have these fields set correctly */ -#if 0 - if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) || - sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 ) - return FT_THROW( Unknown_File_Format ); -#endif - - /* load the table directory */ - - FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables )); - FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag )); - - if ( sfnt.format_tag != TTAG_OTTO ) - { - /* check first */ - error = check_table_dir( &sfnt, stream ); - if ( error ) - { - FT_TRACE2(( "tt_face_load_font_dir:" - " invalid table directory for TrueType\n" )); - - goto Exit; - } - } - - face->num_tables = sfnt.num_tables; - face->format_tag = sfnt.format_tag; - - if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) - goto Exit; - - if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || - FT_FRAME_ENTER( face->num_tables * 16L ) ) - goto Exit; - - entry = face->dir_tables; - - FT_TRACE2(( "\n" - " tag offset length checksum\n" - " ----------------------------------\n" )); - - for ( nn = 0; nn < sfnt.num_tables; nn++ ) - { - entry->Tag = FT_GET_TAG4(); - entry->CheckSum = FT_GET_ULONG(); - entry->Offset = FT_GET_LONG(); - entry->Length = FT_GET_LONG(); - - /* ignore invalid tables */ - if ( entry->Offset + entry->Length > stream->size ) - continue; - else - { - FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n", - (FT_Char)( entry->Tag >> 24 ), - (FT_Char)( entry->Tag >> 16 ), - (FT_Char)( entry->Tag >> 8 ), - (FT_Char)( entry->Tag ), - entry->Offset, - entry->Length, - entry->CheckSum )); - entry++; - } - } - - FT_FRAME_EXIT(); - - FT_TRACE2(( "table directory loaded\n\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_any */ - /* */ - /* <Description> */ - /* Loads any font table into client memory. */ - /* */ - /* <Input> */ - /* face :: The face object to look for. */ - /* */ - /* tag :: The tag of table to load. Use the value 0 if you want */ - /* to access the whole font file, else set this parameter */ - /* to a valid TrueType table tag that you can forge with */ - /* the MAKE_TT_TAG macro. */ - /* */ - /* offset :: The starting offset in the table (or the file if */ - /* tag == 0). */ - /* */ - /* length :: The address of the decision variable: */ - /* */ - /* If length == NULL: */ - /* Loads the whole table. Returns an error if */ - /* `offset' == 0! */ - /* */ - /* If *length == 0: */ - /* Exits immediately; returning the length of the given */ - /* table or of the font file, depending on the value of */ - /* `tag'. */ - /* */ - /* If *length != 0: */ - /* Loads the next `length' bytes of table or font, */ - /* starting at offset `offset' (in table or font too). */ - /* */ - /* <Output> */ - /* buffer :: The address of target buffer. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_any( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ) - { - FT_Error error; - FT_Stream stream; - TT_Table table; - FT_ULong size; - - - if ( tag != 0 ) - { - /* look for tag in font directory */ - table = tt_face_lookup_table( face, tag ); - if ( !table ) - { - error = FT_THROW( Table_Missing ); - goto Exit; - } - - offset += table->Offset; - size = table->Length; - } - else - /* tag == 0 -- the user wants to access the font file directly */ - size = face->root.stream->size; - - if ( length && *length == 0 ) - { - *length = size; - - return FT_Err_Ok; - } - - if ( length ) - size = *length; - - stream = face->root.stream; - /* the `if' is syntactic sugar for picky compilers */ - if ( FT_STREAM_READ_AT( offset, buffer, size ) ) - goto Exit; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_generic_header */ - /* */ - /* <Description> */ - /* Loads the TrueType table `head' or `bhed'. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error - tt_face_load_generic_header( TT_Face face, - FT_Stream stream, - FT_ULong tag ) - { - FT_Error error; - TT_Header* header; - - static const FT_Frame_Field header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_Header - - FT_FRAME_START( 54 ), - FT_FRAME_ULONG ( Table_Version ), - FT_FRAME_ULONG ( Font_Revision ), - FT_FRAME_LONG ( CheckSum_Adjust ), - FT_FRAME_LONG ( Magic_Number ), - FT_FRAME_USHORT( Flags ), - FT_FRAME_USHORT( Units_Per_EM ), - FT_FRAME_LONG ( Created[0] ), - FT_FRAME_LONG ( Created[1] ), - FT_FRAME_LONG ( Modified[0] ), - FT_FRAME_LONG ( Modified[1] ), - FT_FRAME_SHORT ( xMin ), - FT_FRAME_SHORT ( yMin ), - FT_FRAME_SHORT ( xMax ), - FT_FRAME_SHORT ( yMax ), - FT_FRAME_USHORT( Mac_Style ), - FT_FRAME_USHORT( Lowest_Rec_PPEM ), - FT_FRAME_SHORT ( Font_Direction ), - FT_FRAME_SHORT ( Index_To_Loc_Format ), - FT_FRAME_SHORT ( Glyph_Data_Format ), - FT_FRAME_END - }; - - - error = face->goto_table( face, tag, stream, 0 ); - if ( error ) - goto Exit; - - header = &face->header; - - if ( FT_STREAM_READ_FIELDS( header_fields, header ) ) - goto Exit; - - FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM )); - FT_TRACE3(( "IndexToLoc: %4d\n", header->Index_To_Loc_Format )); - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_head( TT_Face face, - FT_Stream stream ) - { - return tt_face_load_generic_header( face, stream, TTAG_head ); - } - - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_bhed( TT_Face face, - FT_Stream stream ) - { - return tt_face_load_generic_header( face, stream, TTAG_bhed ); - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_max_profile */ - /* */ - /* <Description> */ - /* Loads the maximum profile into a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_maxp( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_MaxProfile* maxProfile = &face->max_profile; - - static const FT_Frame_Field maxp_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_MaxProfile - - FT_FRAME_START( 6 ), - FT_FRAME_LONG ( version ), - FT_FRAME_USHORT( numGlyphs ), - FT_FRAME_END - }; - - static const FT_Frame_Field maxp_fields_extra[] = - { - FT_FRAME_START( 26 ), - FT_FRAME_USHORT( maxPoints ), - FT_FRAME_USHORT( maxContours ), - FT_FRAME_USHORT( maxCompositePoints ), - FT_FRAME_USHORT( maxCompositeContours ), - FT_FRAME_USHORT( maxZones ), - FT_FRAME_USHORT( maxTwilightPoints ), - FT_FRAME_USHORT( maxStorage ), - FT_FRAME_USHORT( maxFunctionDefs ), - FT_FRAME_USHORT( maxInstructionDefs ), - FT_FRAME_USHORT( maxStackElements ), - FT_FRAME_USHORT( maxSizeOfInstructions ), - FT_FRAME_USHORT( maxComponentElements ), - FT_FRAME_USHORT( maxComponentDepth ), - FT_FRAME_END - }; - - - error = face->goto_table( face, TTAG_maxp, stream, 0 ); - if ( error ) - goto Exit; - - if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) ) - goto Exit; - - maxProfile->maxPoints = 0; - maxProfile->maxContours = 0; - maxProfile->maxCompositePoints = 0; - maxProfile->maxCompositeContours = 0; - maxProfile->maxZones = 0; - maxProfile->maxTwilightPoints = 0; - maxProfile->maxStorage = 0; - maxProfile->maxFunctionDefs = 0; - maxProfile->maxInstructionDefs = 0; - maxProfile->maxStackElements = 0; - maxProfile->maxSizeOfInstructions = 0; - maxProfile->maxComponentElements = 0; - maxProfile->maxComponentDepth = 0; - - if ( maxProfile->version >= 0x10000L ) - { - if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) ) - goto Exit; - - /* XXX: an adjustment that is necessary to load certain */ - /* broken fonts like `Keystrokes MT' :-( */ - /* */ - /* We allocate 64 function entries by default when */ - /* the maxFunctionDefs value is smaller. */ - - if ( maxProfile->maxFunctionDefs < 64 ) - maxProfile->maxFunctionDefs = 64; - - /* we add 4 phantom points later */ - if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) - { - FT_TRACE0(( "tt_face_load_maxp:" - " too much twilight points in `maxp' table;\n" - " " - " some glyphs might be rendered incorrectly\n" )); - - maxProfile->maxTwilightPoints = 0xFFFFU - 4; - } - - /* we arbitrarily limit recursion to avoid stack exhaustion */ - if ( maxProfile->maxComponentDepth > 100 ) - { - FT_TRACE0(( "tt_face_load_maxp:" - " abnormally large component depth (%d) set to 100\n", - maxProfile->maxComponentDepth )); - maxProfile->maxComponentDepth = 100; - } - } - - FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_name */ - /* */ - /* <Description> */ - /* Loads the name records. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_name( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong table_pos, table_len; - FT_ULong storage_start, storage_limit; - FT_UInt count; - TT_NameTable table; - - static const FT_Frame_Field name_table_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_NameTableRec - - FT_FRAME_START( 6 ), - FT_FRAME_USHORT( format ), - FT_FRAME_USHORT( numNameRecords ), - FT_FRAME_USHORT( storageOffset ), - FT_FRAME_END - }; - - static const FT_Frame_Field name_record_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_NameEntryRec - - /* no FT_FRAME_START */ - FT_FRAME_USHORT( platformID ), - FT_FRAME_USHORT( encodingID ), - FT_FRAME_USHORT( languageID ), - FT_FRAME_USHORT( nameID ), - FT_FRAME_USHORT( stringLength ), - FT_FRAME_USHORT( stringOffset ), - FT_FRAME_END - }; - - - table = &face->name_table; - table->stream = stream; - - error = face->goto_table( face, TTAG_name, stream, &table_len ); - if ( error ) - goto Exit; - - table_pos = FT_STREAM_POS(); - - - if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) ) - goto Exit; - - /* Some popular Asian fonts have an invalid `storageOffset' value */ - /* (it should be at least "6 + 12*num_names"). However, the string */ - /* offsets, computed as "storageOffset + entry->stringOffset", are */ - /* valid pointers within the name table... */ - /* */ - /* We thus can't check `storageOffset' right now. */ - /* */ - storage_start = table_pos + 6 + 12*table->numNameRecords; - storage_limit = table_pos + table_len; - - if ( storage_start > storage_limit ) - { - FT_ERROR(( "tt_face_load_name: invalid `name' table\n" )); - error = FT_THROW( Name_Table_Missing ); - goto Exit; - } - - /* Allocate the array of name records. */ - count = table->numNameRecords; - table->numNameRecords = 0; - - if ( FT_NEW_ARRAY( table->names, count ) || - FT_FRAME_ENTER( count * 12 ) ) - goto Exit; - - /* Load the name records and determine how much storage is needed */ - /* to hold the strings themselves. */ - { - TT_NameEntryRec* entry = table->names; - - - for ( ; count > 0; count-- ) - { - if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) ) - continue; - - /* check that the name is not empty */ - if ( entry->stringLength == 0 ) - continue; - - /* check that the name string is within the table */ - entry->stringOffset += table_pos + table->storageOffset; - if ( entry->stringOffset < storage_start || - entry->stringOffset + entry->stringLength > storage_limit ) - { - /* invalid entry - ignore it */ - entry->stringOffset = 0; - entry->stringLength = 0; - continue; - } - - entry++; - } - - table->numNameRecords = (FT_UInt)( entry - table->names ); - } - - FT_FRAME_EXIT(); - - /* everything went well, update face->num_names */ - face->num_names = (FT_UShort) table->numNameRecords; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_free_names */ - /* */ - /* <Description> */ - /* Frees the name records. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - FT_LOCAL_DEF( void ) - tt_face_free_name( TT_Face face ) - { - FT_Memory memory = face->root.driver->root.memory; - TT_NameTable table = &face->name_table; - TT_NameEntry entry = table->names; - FT_UInt count = table->numNameRecords; - - - if ( table->names ) - { - for ( ; count > 0; count--, entry++ ) - { - FT_FREE( entry->string ); - entry->stringLength = 0; - } - - /* free strings table */ - FT_FREE( table->names ); - } - - table->numNameRecords = 0; - table->format = 0; - table->storageOffset = 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_cmap */ - /* */ - /* <Description> */ - /* Loads the cmap directory in a face object. The cmaps themselves */ - /* are loaded on demand in the `ttcmap.c' module. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_cmap( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - - - error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size ); - if ( error ) - goto Exit; - - if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) ) - face->cmap_size = 0; - - Exit: - return error; - } - - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_os2 */ - /* */ - /* <Description> */ - /* Loads the OS2 table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_os2( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_OS2* os2; - - static const FT_Frame_Field os2_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_OS2 - - FT_FRAME_START( 78 ), - FT_FRAME_USHORT( version ), - FT_FRAME_SHORT ( xAvgCharWidth ), - FT_FRAME_USHORT( usWeightClass ), - FT_FRAME_USHORT( usWidthClass ), - FT_FRAME_SHORT ( fsType ), - FT_FRAME_SHORT ( ySubscriptXSize ), - FT_FRAME_SHORT ( ySubscriptYSize ), - FT_FRAME_SHORT ( ySubscriptXOffset ), - FT_FRAME_SHORT ( ySubscriptYOffset ), - FT_FRAME_SHORT ( ySuperscriptXSize ), - FT_FRAME_SHORT ( ySuperscriptYSize ), - FT_FRAME_SHORT ( ySuperscriptXOffset ), - FT_FRAME_SHORT ( ySuperscriptYOffset ), - FT_FRAME_SHORT ( yStrikeoutSize ), - FT_FRAME_SHORT ( yStrikeoutPosition ), - FT_FRAME_SHORT ( sFamilyClass ), - FT_FRAME_BYTE ( panose[0] ), - FT_FRAME_BYTE ( panose[1] ), - FT_FRAME_BYTE ( panose[2] ), - FT_FRAME_BYTE ( panose[3] ), - FT_FRAME_BYTE ( panose[4] ), - FT_FRAME_BYTE ( panose[5] ), - FT_FRAME_BYTE ( panose[6] ), - FT_FRAME_BYTE ( panose[7] ), - FT_FRAME_BYTE ( panose[8] ), - FT_FRAME_BYTE ( panose[9] ), - FT_FRAME_ULONG ( ulUnicodeRange1 ), - FT_FRAME_ULONG ( ulUnicodeRange2 ), - FT_FRAME_ULONG ( ulUnicodeRange3 ), - FT_FRAME_ULONG ( ulUnicodeRange4 ), - FT_FRAME_BYTE ( achVendID[0] ), - FT_FRAME_BYTE ( achVendID[1] ), - FT_FRAME_BYTE ( achVendID[2] ), - FT_FRAME_BYTE ( achVendID[3] ), - - FT_FRAME_USHORT( fsSelection ), - FT_FRAME_USHORT( usFirstCharIndex ), - FT_FRAME_USHORT( usLastCharIndex ), - FT_FRAME_SHORT ( sTypoAscender ), - FT_FRAME_SHORT ( sTypoDescender ), - FT_FRAME_SHORT ( sTypoLineGap ), - FT_FRAME_USHORT( usWinAscent ), - FT_FRAME_USHORT( usWinDescent ), - FT_FRAME_END - }; - - static const FT_Frame_Field os2_fields_extra[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_ULONG( ulCodePageRange1 ), - FT_FRAME_ULONG( ulCodePageRange2 ), - FT_FRAME_END - }; - - static const FT_Frame_Field os2_fields_extra2[] = - { - FT_FRAME_START( 10 ), - FT_FRAME_SHORT ( sxHeight ), - FT_FRAME_SHORT ( sCapHeight ), - FT_FRAME_USHORT( usDefaultChar ), - FT_FRAME_USHORT( usBreakChar ), - FT_FRAME_USHORT( usMaxContext ), - FT_FRAME_END - }; - - - /* We now support old Mac fonts where the OS/2 table doesn't */ - /* exist. Simply put, we set the `version' field to 0xFFFF */ - /* and test this value each time we need to access the table. */ - error = face->goto_table( face, TTAG_OS2, stream, 0 ); - if ( error ) - goto Exit; - - os2 = &face->os2; - - if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) ) - goto Exit; - - os2->ulCodePageRange1 = 0; - os2->ulCodePageRange2 = 0; - os2->sxHeight = 0; - os2->sCapHeight = 0; - os2->usDefaultChar = 0; - os2->usBreakChar = 0; - os2->usMaxContext = 0; - - if ( os2->version >= 0x0001 ) - { - /* only version 1 tables */ - if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) ) - goto Exit; - - if ( os2->version >= 0x0002 ) - { - /* only version 2 tables */ - if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) ) - goto Exit; - } - } - - FT_TRACE3(( "sTypoAscender: %4d\n", os2->sTypoAscender )); - FT_TRACE3(( "sTypoDescender: %4d\n", os2->sTypoDescender )); - FT_TRACE3(( "usWinAscent: %4u\n", os2->usWinAscent )); - FT_TRACE3(( "usWinDescent: %4u\n", os2->usWinDescent )); - FT_TRACE3(( "fsSelection: 0x%2x\n", os2->fsSelection )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_postscript */ - /* */ - /* <Description> */ - /* Loads the Postscript table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_post( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_Postscript* post = &face->postscript; - - static const FT_Frame_Field post_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_Postscript - - FT_FRAME_START( 32 ), - FT_FRAME_ULONG( FormatType ), - FT_FRAME_ULONG( italicAngle ), - FT_FRAME_SHORT( underlinePosition ), - FT_FRAME_SHORT( underlineThickness ), - FT_FRAME_ULONG( isFixedPitch ), - FT_FRAME_ULONG( minMemType42 ), - FT_FRAME_ULONG( maxMemType42 ), - FT_FRAME_ULONG( minMemType1 ), - FT_FRAME_ULONG( maxMemType1 ), - FT_FRAME_END - }; - - - error = face->goto_table( face, TTAG_post, stream, 0 ); - if ( error ) - return error; - - if ( FT_STREAM_READ_FIELDS( post_fields, post ) ) - return error; - - /* we don't load the glyph names, we do that in another */ - /* module (ttpost). */ - - FT_TRACE3(( "FormatType: 0x%x\n", post->FormatType )); - FT_TRACE3(( "isFixedPitch: %s\n", post->isFixedPitch - ? " yes" : " no" )); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_pclt */ - /* */ - /* <Description> */ - /* Loads the PCL 5 Table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_pclt( TT_Face face, - FT_Stream stream ) - { - static const FT_Frame_Field pclt_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_PCLT - - FT_FRAME_START( 54 ), - FT_FRAME_ULONG ( Version ), - FT_FRAME_ULONG ( FontNumber ), - FT_FRAME_USHORT( Pitch ), - FT_FRAME_USHORT( xHeight ), - FT_FRAME_USHORT( Style ), - FT_FRAME_USHORT( TypeFamily ), - FT_FRAME_USHORT( CapHeight ), - FT_FRAME_BYTES ( TypeFace, 16 ), - FT_FRAME_BYTES ( CharacterComplement, 8 ), - FT_FRAME_BYTES ( FileName, 6 ), - FT_FRAME_CHAR ( StrokeWeight ), - FT_FRAME_CHAR ( WidthType ), - FT_FRAME_BYTE ( SerifStyle ), - FT_FRAME_BYTE ( Reserved ), - FT_FRAME_END - }; - - FT_Error error; - TT_PCLT* pclt = &face->pclt; - - - /* optional table */ - error = face->goto_table( face, TTAG_PCLT, stream, 0 ); - if ( error ) - goto Exit; - - if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) ) - goto Exit; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_gasp */ - /* */ - /* <Description> */ - /* Loads the `gasp' table into a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_gasp( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_UInt j,num_ranges; - TT_GaspRange gaspranges = NULL; - - - /* the gasp table is optional */ - error = face->goto_table( face, TTAG_gasp, stream, 0 ); - if ( error ) - goto Exit; - - if ( FT_FRAME_ENTER( 4L ) ) - goto Exit; - - face->gasp.version = FT_GET_USHORT(); - face->gasp.numRanges = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - /* only support versions 0 and 1 of the table */ - if ( face->gasp.version >= 2 ) - { - face->gasp.numRanges = 0; - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - num_ranges = face->gasp.numRanges; - FT_TRACE3(( "numRanges: %u\n", num_ranges )); - - if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) || - FT_FRAME_ENTER( num_ranges * 4L ) ) - goto Exit; - - gaspranges = face->gasp.gaspRanges; - - for ( j = 0; j < num_ranges; j++ ) - { - gaspranges[j].maxPPEM = FT_GET_USHORT(); - gaspranges[j].gaspFlag = FT_GET_USHORT(); - - FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n", - j, - gaspranges[j].maxPPEM, - gaspranges[j].gaspFlag )); - } - - FT_FRAME_EXIT(); - - Exit: - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttload.h b/drivers/freetype/freetype/src/sfnt/ttload.h deleted file mode 100644 index 49a1aee163..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttload.h +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttload.h */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2005, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __TTLOAD_H__ -#define __TTLOAD_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_TRUETYPE_TYPES_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( TT_Table ) - tt_face_lookup_table( TT_Face face, - FT_ULong tag ); - - FT_LOCAL( FT_Error ) - tt_face_goto_table( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ); - - - FT_LOCAL( FT_Error ) - tt_face_load_font_dir( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_any( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); - - - FT_LOCAL( FT_Error ) - tt_face_load_head( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_cmap( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_maxp( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_name( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_os2( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_post( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_pclt( TT_Face face, - FT_Stream stream ); - - FT_LOCAL( void ) - tt_face_free_name( TT_Face face ); - - - FT_LOCAL( FT_Error ) - tt_face_load_gasp( TT_Face face, - FT_Stream stream ); - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - FT_LOCAL( FT_Error ) - tt_face_load_bhed( TT_Face face, - FT_Stream stream ); - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - -FT_END_HEADER - -#endif /* __TTLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttmtx.c b/drivers/freetype/freetype/src/sfnt/ttmtx.c deleted file mode 100644 index 371a9edabe..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttmtx.c +++ /dev/null @@ -1,279 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttmtx.c */ -/* */ -/* Load the metrics tables common to TTF and OTF fonts (body). */ -/* */ -/* Copyright 2006-2009, 2011-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include "ttmtx.h" - -#include "sferrors.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_ttmtx - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_hmtx */ - /* */ - /* <Description> */ - /* Load the `hmtx' or `vmtx' table into a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load `vmtx'. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_hmtx( TT_Face face, - FT_Stream stream, - FT_Bool vertical ) - { - FT_Error error; - FT_ULong tag, table_size; - FT_ULong* ptable_offset; - FT_ULong* ptable_size; - - - if ( vertical ) - { - tag = TTAG_vmtx; - ptable_offset = &face->vert_metrics_offset; - ptable_size = &face->vert_metrics_size; - } - else - { - tag = TTAG_hmtx; - ptable_offset = &face->horz_metrics_offset; - ptable_size = &face->horz_metrics_size; - } - - error = face->goto_table( face, tag, stream, &table_size ); - if ( error ) - goto Fail; - - *ptable_size = table_size; - *ptable_offset = FT_STREAM_POS(); - - Fail: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_hhea */ - /* */ - /* <Description> */ - /* Load the `hhea' or 'vhea' table into a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load `vhea'. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_hhea( TT_Face face, - FT_Stream stream, - FT_Bool vertical ) - { - FT_Error error; - TT_HoriHeader* header; - - static const FT_Frame_Field metrics_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_HoriHeader - - FT_FRAME_START( 36 ), - FT_FRAME_ULONG ( Version ), - FT_FRAME_SHORT ( Ascender ), - FT_FRAME_SHORT ( Descender ), - FT_FRAME_SHORT ( Line_Gap ), - FT_FRAME_USHORT( advance_Width_Max ), - FT_FRAME_SHORT ( min_Left_Side_Bearing ), - FT_FRAME_SHORT ( min_Right_Side_Bearing ), - FT_FRAME_SHORT ( xMax_Extent ), - FT_FRAME_SHORT ( caret_Slope_Rise ), - FT_FRAME_SHORT ( caret_Slope_Run ), - FT_FRAME_SHORT ( caret_Offset ), - FT_FRAME_SHORT ( Reserved[0] ), - FT_FRAME_SHORT ( Reserved[1] ), - FT_FRAME_SHORT ( Reserved[2] ), - FT_FRAME_SHORT ( Reserved[3] ), - FT_FRAME_SHORT ( metric_Data_Format ), - FT_FRAME_USHORT( number_Of_HMetrics ), - FT_FRAME_END - }; - - - if ( vertical ) - { - void *v = &face->vertical; - - - error = face->goto_table( face, TTAG_vhea, stream, 0 ); - if ( error ) - goto Fail; - - header = (TT_HoriHeader*)v; - } - else - { - error = face->goto_table( face, TTAG_hhea, stream, 0 ); - if ( error ) - goto Fail; - - header = &face->horizontal; - } - - if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) ) - goto Fail; - - FT_TRACE3(( "Ascender: %5d\n", header->Ascender )); - FT_TRACE3(( "Descender: %5d\n", header->Descender )); - FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics )); - - header->long_metrics = NULL; - header->short_metrics = NULL; - - Fail: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_get_metrics */ - /* */ - /* <Description> */ - /* Returns the horizontal or vertical metrics in font units for a */ - /* given glyph. The metrics are the left side bearing (resp. top */ - /* side bearing) and advance width (resp. advance height). */ - /* */ - /* <Input> */ - /* header :: A pointer to either the horizontal or vertical metrics */ - /* structure. */ - /* */ - /* idx :: The glyph index. */ - /* */ - /* <Output> */ - /* bearing :: The bearing, either left side or top side. */ - /* */ - /* advance :: The advance width resp. advance height. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_get_metrics( TT_Face face, - FT_Bool vertical, - FT_UInt gindex, - FT_Short *abearing, - FT_UShort *aadvance ) - { - FT_Error error; - FT_Stream stream = face->root.stream; - TT_HoriHeader* header; - FT_ULong table_pos, table_size, table_end; - FT_UShort k; - - - if ( vertical ) - { - void* v = &face->vertical; - - - header = (TT_HoriHeader*)v; - table_pos = face->vert_metrics_offset; - table_size = face->vert_metrics_size; - } - else - { - header = &face->horizontal; - table_pos = face->horz_metrics_offset; - table_size = face->horz_metrics_size; - } - - table_end = table_pos + table_size; - - k = header->number_Of_HMetrics; - - if ( k > 0 ) - { - if ( gindex < (FT_UInt)k ) - { - table_pos += 4 * gindex; - if ( table_pos + 4 > table_end ) - goto NoData; - - if ( FT_STREAM_SEEK( table_pos ) || - FT_READ_USHORT( *aadvance ) || - FT_READ_SHORT( *abearing ) ) - goto NoData; - } - else - { - table_pos += 4 * ( k - 1 ); - if ( table_pos + 4 > table_end ) - goto NoData; - - if ( FT_STREAM_SEEK( table_pos ) || - FT_READ_USHORT( *aadvance ) ) - goto NoData; - - table_pos += 4 + 2 * ( gindex - k ); - if ( table_pos + 2 > table_end ) - *abearing = 0; - else - { - if ( !FT_STREAM_SEEK( table_pos ) ) - (void)FT_READ_SHORT( *abearing ); - } - } - } - else - { - NoData: - *abearing = 0; - *aadvance = 0; - } - - return FT_Err_Ok; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttmtx.h b/drivers/freetype/freetype/src/sfnt/ttmtx.h deleted file mode 100644 index 8b91a113d8..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttmtx.h +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttmtx.h */ -/* */ -/* Load the metrics tables common to TTF and OTF fonts (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __TTMTX_H__ -#define __TTMTX_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_TRUETYPE_TYPES_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - tt_face_load_hhea( TT_Face face, - FT_Stream stream, - FT_Bool vertical ); - - - FT_LOCAL( FT_Error ) - tt_face_load_hmtx( TT_Face face, - FT_Stream stream, - FT_Bool vertical ); - - - FT_LOCAL( FT_Error ) - tt_face_get_metrics( TT_Face face, - FT_Bool vertical, - FT_UInt gindex, - FT_Short* abearing, - FT_UShort* aadvance ); - -FT_END_HEADER - -#endif /* __TTMTX_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttpost.c b/drivers/freetype/freetype/src/sfnt/ttpost.c deleted file mode 100644 index 47a85c0c9f..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttpost.c +++ /dev/null @@ -1,563 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpost.c */ -/* */ -/* Postcript name table processing for TrueType and OpenType fonts */ -/* (body). */ -/* */ -/* Copyright 1996-2003, 2006-2010, 2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* The post table is not completely loaded by the core engine. This */ - /* file loads the missing PS glyph names and implements an API to access */ - /* them. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include "ttpost.h" - -#include "sferrors.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_ttpost - - - /* If this configuration macro is defined, we rely on the `PSNames' */ - /* module to grab the glyph names. */ - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - -#include FT_SERVICE_POSTSCRIPT_CMAPS_H - -#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) - - -#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - /* Otherwise, we ignore the `PSNames' module, and provide our own */ - /* table of Mac names. Thus, it is possible to build a version of */ - /* FreeType without the Type 1 driver & PSNames module. */ - -#define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) - - /* the 258 default Mac PS glyph names */ - - static const FT_String* const tt_post_default_names[258] = - { - /* 0 */ - ".notdef", ".null", "CR", "space", "exclam", - "quotedbl", "numbersign", "dollar", "percent", "ampersand", - /* 10 */ - "quotesingle", "parenleft", "parenright", "asterisk", "plus", - "comma", "hyphen", "period", "slash", "zero", - /* 20 */ - "one", "two", "three", "four", "five", - "six", "seven", "eight", "nine", "colon", - /* 30 */ - "semicolon", "less", "equal", "greater", "question", - "at", "A", "B", "C", "D", - /* 40 */ - "E", "F", "G", "H", "I", - "J", "K", "L", "M", "N", - /* 50 */ - "O", "P", "Q", "R", "S", - "T", "U", "V", "W", "X", - /* 60 */ - "Y", "Z", "bracketleft", "backslash", "bracketright", - "asciicircum", "underscore", "grave", "a", "b", - /* 70 */ - "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", - /* 80 */ - "m", "n", "o", "p", "q", - "r", "s", "t", "u", "v", - /* 90 */ - "w", "x", "y", "z", "braceleft", - "bar", "braceright", "asciitilde", "Adieresis", "Aring", - /* 100 */ - "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", - "aacute", "agrave", "acircumflex", "adieresis", "atilde", - /* 110 */ - "aring", "ccedilla", "eacute", "egrave", "ecircumflex", - "edieresis", "iacute", "igrave", "icircumflex", "idieresis", - /* 120 */ - "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", - "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", - /* 130 */ - "dagger", "degree", "cent", "sterling", "section", - "bullet", "paragraph", "germandbls", "registered", "copyright", - /* 140 */ - "trademark", "acute", "dieresis", "notequal", "AE", - "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", - /* 150 */ - "yen", "mu", "partialdiff", "summation", "product", - "pi", "integral", "ordfeminine", "ordmasculine", "Omega", - /* 160 */ - "ae", "oslash", "questiondown", "exclamdown", "logicalnot", - "radical", "florin", "approxequal", "Delta", "guillemotleft", - /* 170 */ - "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", - "Otilde", "OE", "oe", "endash", "emdash", - /* 180 */ - "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", - "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", - /* 190 */ - "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", - "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", - /* 200 */ - "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", - "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", - /* 210 */ - "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", - "dotlessi", "circumflex", "tilde", "macron", "breve", - /* 220 */ - "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", - "caron", "Lslash", "lslash", "Scaron", "scaron", - /* 230 */ - "Zcaron", "zcaron", "brokenbar", "Eth", "eth", - "Yacute", "yacute", "Thorn", "thorn", "minus", - /* 240 */ - "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", - "onequarter", "threequarters", "franc", "Gbreve", "gbreve", - /* 250 */ - "Idot", "Scedilla", "scedilla", "Cacute", "cacute", - "Ccaron", "ccaron", "dmacron", - }; - - -#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - static FT_Error - load_format_20( TT_Face face, - FT_Stream stream, - FT_Long post_limit ) - { - FT_Memory memory = stream->memory; - FT_Error error; - - FT_Int num_glyphs; - FT_UShort num_names; - - FT_UShort* glyph_indices = 0; - FT_Char** name_strings = 0; - - - if ( FT_READ_USHORT( num_glyphs ) ) - goto Exit; - - /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ - /* than the value in the maxp table (cf. cyberbit.ttf). */ - - /* There already exist fonts which have more than 32768 glyph names */ - /* in this table, so the test for this threshold has been dropped. */ - - if ( num_glyphs > face->max_profile.numGlyphs ) - { - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* load the indices */ - { - FT_Int n; - - - if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) || - FT_FRAME_ENTER( num_glyphs * 2L ) ) - goto Fail; - - for ( n = 0; n < num_glyphs; n++ ) - glyph_indices[n] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - } - - /* compute number of names stored in table */ - { - FT_Int n; - - - num_names = 0; - - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Int idx; - - - idx = glyph_indices[n]; - if ( idx >= 258 ) - { - idx -= 257; - if ( idx > num_names ) - num_names = (FT_UShort)idx; - } - } - } - - /* now load the name strings */ - { - FT_UShort n; - - - if ( FT_NEW_ARRAY( name_strings, num_names ) ) - goto Fail; - - for ( n = 0; n < num_names; n++ ) - { - FT_UInt len; - - - if ( FT_STREAM_POS() >= post_limit ) - break; - else - { - FT_TRACE6(( "load_format_20: %d byte left in post table\n", - post_limit - FT_STREAM_POS() )); - - if ( FT_READ_BYTE( len ) ) - goto Fail1; - } - - if ( (FT_Int)len > post_limit || - FT_STREAM_POS() > post_limit - (FT_Int)len ) - { - FT_ERROR(( "load_format_20:" - " exceeding string length (%d)," - " truncating at end of post table (%d byte left)\n", - len, post_limit - FT_STREAM_POS() )); - len = FT_MAX( 0, post_limit - FT_STREAM_POS() ); - } - - if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) || - FT_STREAM_READ( name_strings[n], len ) ) - goto Fail1; - - name_strings[n][len] = '\0'; - } - - if ( n < num_names ) - { - FT_ERROR(( "load_format_20:" - " all entries in post table are already parsed," - " using NULL names for gid %d - %d\n", - n, num_names - 1 )); - for ( ; n < num_names; n++ ) - if ( FT_NEW_ARRAY( name_strings[n], 1 ) ) - goto Fail1; - else - name_strings[n][0] = '\0'; - } - } - - /* all right, set table fields and exit successfully */ - { - TT_Post_20 table = &face->postscript_names.names.format_20; - - - table->num_glyphs = (FT_UShort)num_glyphs; - table->num_names = (FT_UShort)num_names; - table->glyph_indices = glyph_indices; - table->glyph_names = name_strings; - } - return FT_Err_Ok; - - Fail1: - { - FT_UShort n; - - - for ( n = 0; n < num_names; n++ ) - FT_FREE( name_strings[n] ); - } - - Fail: - FT_FREE( name_strings ); - FT_FREE( glyph_indices ); - - Exit: - return error; - } - - - static FT_Error - load_format_25( TT_Face face, - FT_Stream stream, - FT_Long post_limit ) - { - FT_Memory memory = stream->memory; - FT_Error error; - - FT_Int num_glyphs; - FT_Char* offset_table = 0; - - FT_UNUSED( post_limit ); - - - /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ - if ( FT_READ_USHORT( num_glyphs ) ) - goto Exit; - - /* check the number of glyphs */ - if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 ) - { - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( FT_NEW_ARRAY( offset_table, num_glyphs ) || - FT_STREAM_READ( offset_table, num_glyphs ) ) - goto Fail; - - /* now check the offset table */ - { - FT_Int n; - - - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Long idx = (FT_Long)n + offset_table[n]; - - - if ( idx < 0 || idx > num_glyphs ) - { - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - } - } - - /* OK, set table fields and exit successfully */ - { - TT_Post_25 table = &face->postscript_names.names.format_25; - - - table->num_glyphs = (FT_UShort)num_glyphs; - table->offsets = offset_table; - } - - return FT_Err_Ok; - - Fail: - FT_FREE( offset_table ); - - Exit: - return error; - } - - - static FT_Error - load_post_names( TT_Face face ) - { - FT_Stream stream; - FT_Error error; - FT_Fixed format; - FT_ULong post_len; - FT_Long post_limit; - - - /* get a stream for the face's resource */ - stream = face->root.stream; - - /* seek to the beginning of the PS names table */ - error = face->goto_table( face, TTAG_post, stream, &post_len ); - if ( error ) - goto Exit; - - post_limit = FT_STREAM_POS() + post_len; - - format = face->postscript.FormatType; - - /* go to beginning of subtable */ - if ( FT_STREAM_SKIP( 32 ) ) - goto Exit; - - /* now read postscript table */ - if ( format == 0x00020000L ) - error = load_format_20( face, stream, post_limit ); - else if ( format == 0x00028000L ) - error = load_format_25( face, stream, post_limit ); - else - error = FT_THROW( Invalid_File_Format ); - - face->postscript_names.loaded = 1; - - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - tt_face_free_ps_names( TT_Face face ) - { - FT_Memory memory = face->root.memory; - TT_Post_Names names = &face->postscript_names; - FT_Fixed format; - - - if ( names->loaded ) - { - format = face->postscript.FormatType; - - if ( format == 0x00020000L ) - { - TT_Post_20 table = &names->names.format_20; - FT_UShort n; - - - FT_FREE( table->glyph_indices ); - table->num_glyphs = 0; - - for ( n = 0; n < table->num_names; n++ ) - FT_FREE( table->glyph_names[n] ); - - FT_FREE( table->glyph_names ); - table->num_names = 0; - } - else if ( format == 0x00028000L ) - { - TT_Post_25 table = &names->names.format_25; - - - FT_FREE( table->offsets ); - table->num_glyphs = 0; - } - } - names->loaded = 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_get_ps_name */ - /* */ - /* <Description> */ - /* Get the PostScript glyph name of a glyph. */ - /* */ - /* <Input> */ - /* face :: A handle to the parent face. */ - /* */ - /* idx :: The glyph index. */ - /* */ - /* <InOut> */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ - /* */ - /* You must not modify the returned string! */ - /* */ - /* <Output> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_get_ps_name( TT_Face face, - FT_UInt idx, - FT_String** PSname ) - { - FT_Error error; - TT_Post_Names names; - FT_Fixed format; - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - FT_Service_PsCMaps psnames; -#endif - - - if ( !face ) - return FT_THROW( Invalid_Face_Handle ); - - if ( idx >= (FT_UInt)face->max_profile.numGlyphs ) - return FT_THROW( Invalid_Glyph_Index ); - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - psnames = (FT_Service_PsCMaps)face->psnames; - if ( !psnames ) - return FT_THROW( Unimplemented_Feature ); -#endif - - names = &face->postscript_names; - - /* `.notdef' by default */ - *PSname = MAC_NAME( 0 ); - - format = face->postscript.FormatType; - - if ( format == 0x00010000L ) - { - if ( idx < 258 ) /* paranoid checking */ - *PSname = MAC_NAME( idx ); - } - else if ( format == 0x00020000L ) - { - TT_Post_20 table = &names->names.format_20; - - - if ( !names->loaded ) - { - error = load_post_names( face ); - if ( error ) - goto End; - } - - if ( idx < (FT_UInt)table->num_glyphs ) - { - FT_UShort name_index = table->glyph_indices[idx]; - - - if ( name_index < 258 ) - *PSname = MAC_NAME( name_index ); - else - *PSname = (FT_String*)table->glyph_names[name_index - 258]; - } - } - else if ( format == 0x00028000L ) - { - TT_Post_25 table = &names->names.format_25; - - - if ( !names->loaded ) - { - error = load_post_names( face ); - if ( error ) - goto End; - } - - if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */ - { - idx += table->offsets[idx]; - *PSname = MAC_NAME( idx ); - } - } - - /* nothing to do for format == 0x00030000L */ - - End: - return FT_Err_Ok; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttpost.h b/drivers/freetype/freetype/src/sfnt/ttpost.h deleted file mode 100644 index 6f06d75a71..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttpost.h +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpost.h */ -/* */ -/* Postcript name table processing for TrueType and OpenType fonts */ -/* (specification). */ -/* */ -/* Copyright 1996-2001, 2002 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 __TTPOST_H__ -#define __TTPOST_H__ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_TRUETYPE_TYPES_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - tt_face_get_ps_name( TT_Face face, - FT_UInt idx, - FT_String** PSname ); - - FT_LOCAL( void ) - tt_face_free_ps_names( TT_Face face ); - - -FT_END_HEADER - -#endif /* __TTPOST_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttsbit.c b/drivers/freetype/freetype/src/sfnt/ttsbit.c deleted file mode 100644 index cd3e5a4a00..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttsbit.c +++ /dev/null @@ -1,1177 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsbit.c */ -/* */ -/* TrueType and OpenType embedded bitmap support (body). */ -/* */ -/* Copyright 2005-2009, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* Copyright 2013 by Google, Inc. */ -/* Google Author(s): Behdad Esfahbod. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include FT_BITMAP_H -#include "ttsbit.h" - -#include "sferrors.h" - -#include "pngshim.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_ttsbit - - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_eblc( TT_Face face, - FT_Stream stream ) - { - FT_Error error = FT_Err_Ok; - FT_Fixed version; - FT_ULong num_strikes, table_size; - FT_Byte* p; - FT_Byte* p_limit; - FT_UInt count; - - - face->sbit_num_strikes = 0; - - /* this table is optional */ - error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); - if ( error ) - error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); - if ( error ) - error = face->goto_table( face, TTAG_bloc, stream, &table_size ); - if ( error ) - goto Exit; - - if ( table_size < 8 ) - { - FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) - goto Exit; - - face->sbit_table_size = table_size; - - p = face->sbit_table; - p_limit = p + table_size; - - version = FT_NEXT_ULONG( p ); - num_strikes = FT_NEXT_ULONG( p ); - - if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) - { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* - * Count the number of strikes available in the table. We are a bit - * paranoid there and don't trust the data. - */ - count = (FT_UInt)num_strikes; - if ( 8 + 48UL * count > table_size ) - count = (FT_UInt)( ( p_limit - p ) / 48 ); - - face->sbit_num_strikes = count; - - FT_TRACE3(( "sbit_num_strikes: %u\n", count )); - Exit: - return error; - - Fail: - FT_FRAME_RELEASE( face->sbit_table ); - face->sbit_table_size = 0; - goto Exit; - } - - - FT_LOCAL_DEF( void ) - tt_face_free_eblc( TT_Face face ) - { - FT_Stream stream = face->root.stream; - - - FT_FRAME_RELEASE( face->sbit_table ); - face->sbit_table_size = 0; - face->sbit_num_strikes = 0; - } - - - FT_LOCAL_DEF( FT_Error ) - tt_face_set_sbit_strike( TT_Face face, - FT_Size_Request req, - FT_ULong* astrike_index ) - { - return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); - } - - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_strike_metrics( TT_Face face, - FT_ULong strike_index, - FT_Size_Metrics* metrics ) - { - FT_Byte* strike; - - - if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) - return FT_THROW( Invalid_Argument ); - - strike = face->sbit_table + 8 + strike_index * 48; - - metrics->x_ppem = (FT_UShort)strike[44]; - metrics->y_ppem = (FT_UShort)strike[45]; - - metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ - metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ - metrics->height = metrics->ascender - metrics->descender; - - /* XXX: Is this correct? */ - metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ - strike[18] + /* max_width */ - (FT_Char)strike[23] /* min_advance_SB */ - ) << 6; - - return FT_Err_Ok; - } - - - typedef struct TT_SBitDecoderRec_ - { - TT_Face face; - FT_Stream stream; - FT_Bitmap* bitmap; - TT_SBit_Metrics metrics; - FT_Bool metrics_loaded; - FT_Bool bitmap_allocated; - FT_Byte bit_depth; - - FT_ULong ebdt_start; - FT_ULong ebdt_size; - - FT_ULong strike_index_array; - FT_ULong strike_index_count; - FT_Byte* eblc_base; - FT_Byte* eblc_limit; - - } TT_SBitDecoderRec, *TT_SBitDecoder; - - - static FT_Error - tt_sbit_decoder_init( TT_SBitDecoder decoder, - TT_Face face, - FT_ULong strike_index, - TT_SBit_MetricsRec* metrics ) - { - FT_Error error; - FT_Stream stream = face->root.stream; - FT_ULong ebdt_size; - - - error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size ); - if ( error ) - error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); - if ( error ) - error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); - if ( error ) - goto Exit; - - decoder->face = face; - decoder->stream = stream; - decoder->bitmap = &face->root.glyph->bitmap; - decoder->metrics = metrics; - - decoder->metrics_loaded = 0; - decoder->bitmap_allocated = 0; - - decoder->ebdt_start = FT_STREAM_POS(); - decoder->ebdt_size = ebdt_size; - - decoder->eblc_base = face->sbit_table; - decoder->eblc_limit = face->sbit_table + face->sbit_table_size; - - /* now find the strike corresponding to the index */ - { - FT_Byte* p; - - - if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size ) - { - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - p = decoder->eblc_base + 8 + 48 * strike_index; - - decoder->strike_index_array = FT_NEXT_ULONG( p ); - p += 4; - decoder->strike_index_count = FT_NEXT_ULONG( p ); - p += 34; - decoder->bit_depth = *p; - - if ( decoder->strike_index_array > face->sbit_table_size || - decoder->strike_index_array + 8 * decoder->strike_index_count > - face->sbit_table_size ) - error = FT_THROW( Invalid_File_Format ); - } - - Exit: - return error; - } - - - static void - tt_sbit_decoder_done( TT_SBitDecoder decoder ) - { - FT_UNUSED( decoder ); - } - - - static FT_Error - tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, - FT_UInt load_flags ) - { - FT_Error error = FT_Err_Ok; - FT_UInt width, height; - FT_Bitmap* map = decoder->bitmap; - FT_Long size; - - - if ( !decoder->metrics_loaded ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - width = decoder->metrics->width; - height = decoder->metrics->height; - - map->width = (int)width; - map->rows = (int)height; - - switch ( decoder->bit_depth ) - { - case 1: - map->pixel_mode = FT_PIXEL_MODE_MONO; - map->pitch = ( map->width + 7 ) >> 3; - map->num_grays = 2; - break; - - case 2: - map->pixel_mode = FT_PIXEL_MODE_GRAY2; - map->pitch = ( map->width + 3 ) >> 2; - map->num_grays = 4; - break; - - case 4: - map->pixel_mode = FT_PIXEL_MODE_GRAY4; - map->pitch = ( map->width + 1 ) >> 1; - map->num_grays = 16; - break; - - case 8: - map->pixel_mode = FT_PIXEL_MODE_GRAY; - map->pitch = map->width; - map->num_grays = 256; - break; - - case 32: - if ( load_flags & FT_LOAD_COLOR ) - { - map->pixel_mode = FT_PIXEL_MODE_BGRA; - map->pitch = map->width * 4; - map->num_grays = 256; - } - else - { - map->pixel_mode = FT_PIXEL_MODE_GRAY; - map->pitch = map->width; - map->num_grays = 256; - } - break; - - default: - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - size = map->rows * map->pitch; - - /* check that there is no empty image */ - if ( size == 0 ) - goto Exit; /* exit successfully! */ - - error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); - if ( error ) - goto Exit; - - decoder->bitmap_allocated = 1; - - Exit: - return error; - } - - - static FT_Error - tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder, - FT_Byte* *pp, - FT_Byte* limit, - FT_Bool big ) - { - FT_Byte* p = *pp; - TT_SBit_Metrics metrics = decoder->metrics; - - - if ( p + 5 > limit ) - goto Fail; - - metrics->height = p[0]; - metrics->width = p[1]; - metrics->horiBearingX = (FT_Char)p[2]; - metrics->horiBearingY = (FT_Char)p[3]; - metrics->horiAdvance = p[4]; - - p += 5; - if ( big ) - { - if ( p + 3 > limit ) - goto Fail; - - metrics->vertBearingX = (FT_Char)p[0]; - metrics->vertBearingY = (FT_Char)p[1]; - metrics->vertAdvance = p[2]; - - p += 3; - } - - decoder->metrics_loaded = 1; - *pp = p; - return FT_Err_Ok; - - Fail: - FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" )); - return FT_THROW( Invalid_Argument ); - } - - - /* forward declaration */ - static FT_Error - tt_sbit_decoder_load_image( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_UInt glyph_index, - FT_Int x_pos, - FT_Int y_pos ); - - typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_Byte* p, - FT_Byte* plimit, - FT_Int x_pos, - FT_Int y_pos ); - - - static FT_Error - tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_Byte* p, - FT_Byte* limit, - FT_Int x_pos, - FT_Int y_pos ) - { - FT_Error error = FT_Err_Ok; - FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; - FT_Bitmap* bitmap; - - FT_UNUSED( load_flags ); - - - /* check that we can write the glyph into the bitmap */ - bitmap = decoder->bitmap; - bit_width = bitmap->width; - bit_height = bitmap->rows; - pitch = bitmap->pitch; - line = bitmap->buffer; - - width = decoder->metrics->width; - height = decoder->metrics->height; - - line_bits = width * decoder->bit_depth; - - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) - { - FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:" - " invalid bitmap dimensions\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit ) - { - FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* now do the blit */ - line += y_pos * pitch + ( x_pos >> 3 ); - x_pos &= 7; - - if ( x_pos == 0 ) /* the easy one */ - { - for ( h = height; h > 0; h--, line += pitch ) - { - FT_Byte* pwrite = line; - FT_Int w; - - - for ( w = line_bits; w >= 8; w -= 8 ) - { - pwrite[0] = (FT_Byte)( pwrite[0] | *p++ ); - pwrite += 1; - } - - if ( w > 0 ) - pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) ); - } - } - else /* x_pos > 0 */ - { - for ( h = height; h > 0; h--, line += pitch ) - { - FT_Byte* pwrite = line; - FT_Int w; - FT_UInt wval = 0; - - - for ( w = line_bits; w >= 8; w -= 8 ) - { - wval = (FT_UInt)( wval | *p++ ); - pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); - pwrite += 1; - wval <<= 8; - } - - if ( w > 0 ) - wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); - - /* all bits read and there are `x_pos + w' bits to be written */ - - pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); - - if ( x_pos + w > 8 ) - { - pwrite++; - wval <<= 8; - pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); - } - } - } - - Exit: - if ( !error ) - FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" )); - return error; - } - - - /* - * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap - * (with pointer `pwrite'). In the example below, the width is 3 pixel, - * and `x_pos' is 1 pixel. - * - * p p+1 - * | | | - * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... - * | | | - * +-------+ +-------+ +-------+ ... - * . . . - * . . . - * v . . - * +-------+ . . - * | | . - * | 7 6 5 4 3 2 1 0 | . - * | | . - * pwrite . . - * . . - * v . - * +-------+ . - * | | - * | 7 6 5 4 3 2 1 0 | - * | | - * pwrite+1 . - * . - * v - * +-------+ - * | | - * | 7 6 5 4 3 2 1 0 | - * | | - * pwrite+2 - * - */ - - static FT_Error - tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_Byte* p, - FT_Byte* limit, - FT_Int x_pos, - FT_Int y_pos ) - { - FT_Error error = FT_Err_Ok; - FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits; - FT_Bitmap* bitmap; - FT_UShort rval; - - FT_UNUSED( load_flags ); - - - /* check that we can write the glyph into the bitmap */ - bitmap = decoder->bitmap; - bit_width = bitmap->width; - bit_height = bitmap->rows; - pitch = bitmap->pitch; - line = bitmap->buffer; - - width = decoder->metrics->width; - height = decoder->metrics->height; - - line_bits = width * decoder->bit_depth; - - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) - { - FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:" - " invalid bitmap dimensions\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit ) - { - FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* now do the blit */ - - /* adjust `line' to point to the first byte of the bitmap */ - line += y_pos * pitch + ( x_pos >> 3 ); - x_pos &= 7; - - /* the higher byte of `rval' is used as a buffer */ - rval = 0; - nbits = 0; - - for ( h = height; h > 0; h--, line += pitch ) - { - FT_Byte* pwrite = line; - FT_Int w = line_bits; - - - /* handle initial byte (in target bitmap) specially if necessary */ - if ( x_pos ) - { - w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos; - - if ( h == height ) - { - rval = *p++; - nbits = x_pos; - } - else if ( nbits < w ) - { - if ( p < limit ) - rval |= *p++; - nbits += 8 - w; - } - else - { - rval >>= 8; - nbits -= w; - } - - *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) & - ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); - rval <<= 8; - - w = line_bits - w; - } - - /* handle medial bytes */ - for ( ; w >= 8; w -= 8 ) - { - rval |= *p++; - *pwrite++ |= ( rval >> nbits ) & 0xFF; - - rval <<= 8; - } - - /* handle final byte if necessary */ - if ( w > 0 ) - { - if ( nbits < w ) - { - if ( p < limit ) - rval |= *p++; - *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); - nbits += 8 - w; - - rval <<= 8; - } - else - { - *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); - nbits -= w; - } - } - } - - Exit: - if ( !error ) - FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" )); - return error; - } - - - static FT_Error - tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_Byte* p, - FT_Byte* limit, - FT_Int x_pos, - FT_Int y_pos ) - { - FT_Error error = FT_Err_Ok; - FT_UInt num_components, nn; - - FT_Char horiBearingX = decoder->metrics->horiBearingX; - FT_Char horiBearingY = decoder->metrics->horiBearingY; - FT_Byte horiAdvance = decoder->metrics->horiAdvance; - FT_Char vertBearingX = decoder->metrics->vertBearingX; - FT_Char vertBearingY = decoder->metrics->vertBearingY; - FT_Byte vertAdvance = decoder->metrics->vertAdvance; - - - if ( p + 2 > limit ) - goto Fail; - - num_components = FT_NEXT_USHORT( p ); - if ( p + 4 * num_components > limit ) - { - FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" )); - goto Fail; - } - - FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n", - num_components )); - - for ( nn = 0; nn < num_components; nn++ ) - { - FT_UInt gindex = FT_NEXT_USHORT( p ); - FT_Byte dx = FT_NEXT_BYTE( p ); - FT_Byte dy = FT_NEXT_BYTE( p ); - - - /* NB: a recursive call */ - error = tt_sbit_decoder_load_image( decoder, load_flags, gindex, - x_pos + dx, y_pos + dy ); - if ( error ) - break; - } - - FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" )); - - decoder->metrics->horiBearingX = horiBearingX; - decoder->metrics->horiBearingY = horiBearingY; - decoder->metrics->horiAdvance = horiAdvance; - decoder->metrics->vertBearingX = vertBearingX; - decoder->metrics->vertBearingY = vertBearingY; - decoder->metrics->vertAdvance = vertAdvance; - decoder->metrics->width = (FT_Byte)decoder->bitmap->width; - decoder->metrics->height = (FT_Byte)decoder->bitmap->rows; - - Exit: - return error; - - Fail: - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - -#ifdef FT_CONFIG_OPTION_USE_PNG - - static FT_Error - tt_sbit_decoder_load_png( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_Byte* p, - FT_Byte* limit, - FT_Int x_pos, - FT_Int y_pos ) - { - FT_Error error = FT_Err_Ok; - FT_ULong png_len; - - FT_UNUSED( load_flags ); - - - if ( limit - p < 4 ) - { - FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - png_len = FT_NEXT_ULONG( p ); - if ( (FT_ULong)( limit - p ) < png_len ) - { - FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - error = Load_SBit_Png( decoder->bitmap, - x_pos, - y_pos, - decoder->bit_depth, - decoder->metrics, - decoder->stream->memory, - p, - png_len ); - - Exit: - if ( !error ) - FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" )); - return error; - } - -#endif /* FT_CONFIG_OPTION_USE_PNG */ - - - static FT_Error - tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_UInt glyph_format, - FT_ULong glyph_start, - FT_ULong glyph_size, - FT_Int x_pos, - FT_Int y_pos ) - { - FT_Error error; - FT_Stream stream = decoder->stream; - FT_Byte* p; - FT_Byte* p_limit; - FT_Byte* data; - - - /* seek into the EBDT table now */ - if ( glyph_start + glyph_size > decoder->ebdt_size ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || - FT_FRAME_EXTRACT( glyph_size, data ) ) - goto Exit; - - p = data; - p_limit = p + glyph_size; - - /* read the data, depending on the glyph format */ - switch ( glyph_format ) - { - case 1: - case 2: - case 8: - case 17: - error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); - break; - - case 6: - case 7: - case 9: - case 18: - error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); - break; - - default: - error = FT_Err_Ok; - } - - if ( error ) - goto Fail; - - { - TT_SBitDecoder_LoadFunc loader; - - - switch ( glyph_format ) - { - case 1: - case 6: - loader = tt_sbit_decoder_load_byte_aligned; - break; - - case 2: - case 5: - case 7: - loader = tt_sbit_decoder_load_bit_aligned; - break; - - case 8: - if ( p + 1 > p_limit ) - goto Fail; - - p += 1; /* skip padding */ - /* fall-through */ - - case 9: - loader = tt_sbit_decoder_load_compound; - break; - -#ifdef FT_CONFIG_OPTION_USE_PNG - case 17: /* small metrics, PNG image data */ - case 18: /* big metrics, PNG image data */ - case 19: /* metrics in EBLC, PNG image data */ - loader = tt_sbit_decoder_load_png; - break; -#endif /* FT_CONFIG_OPTION_USE_PNG */ - - default: - error = FT_THROW( Invalid_Table ); - goto Fail; - } - - if ( !decoder->bitmap_allocated ) - { - error = tt_sbit_decoder_alloc_bitmap( decoder, load_flags ); - if ( error ) - goto Fail; - } - - if ( decoder->bit_depth == 32 && - decoder->bitmap->pixel_mode != FT_PIXEL_MODE_BGRA ) - { - /* Flatten color bitmaps if color was not requested. */ - - FT_Library library = decoder->face->root.glyph->library; - FT_Memory memory = decoder->stream->memory; - - FT_Bitmap color, *orig; - - - if ( decoder->bitmap->pixel_mode != FT_PIXEL_MODE_GRAY || - x_pos != 0 || y_pos != 0 ) - { - /* Shouldn't happen. */ - error = FT_THROW( Invalid_Table ); - goto Fail; - } - - FT_Bitmap_New( &color ); - - color.rows = decoder->bitmap->rows; - color.width = decoder->bitmap->width; - color.pitch = color.width * 4; - color.pixel_mode = FT_PIXEL_MODE_BGRA; - - if ( FT_ALLOC( color.buffer, color.rows * color.pitch ) ) - goto Fail; - - orig = decoder->bitmap; - decoder->bitmap = &color; - - error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); - - decoder->bitmap = orig; - - /* explicitly test against FT_Err_Ok to avoid compiler warnings */ - /* (we do an assignment within a conditional) */ - if ( error || - ( error = FT_Bitmap_Convert( library, - &color, - decoder->bitmap, - 1 ) ) != FT_Err_Ok ) - { - FT_Bitmap_Done( library, &color ); - goto Fail; - } - - FT_Bitmap_Done( library, &color ); - } - - else - error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); - } - - Fail: - FT_FRAME_RELEASE( data ); - - Exit: - return error; - } - - - static FT_Error - tt_sbit_decoder_load_image( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_UInt glyph_index, - FT_Int x_pos, - FT_Int y_pos ) - { - /* - * First, we find the correct strike range that applies to this - * glyph index. - */ - - FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; - FT_Byte* p_limit = decoder->eblc_limit; - FT_ULong num_ranges = decoder->strike_index_count; - FT_UInt start, end, index_format, image_format; - FT_ULong image_start = 0, image_end = 0, image_offset; - - - for ( ; num_ranges > 0; num_ranges-- ) - { - start = FT_NEXT_USHORT( p ); - end = FT_NEXT_USHORT( p ); - - if ( glyph_index >= start && glyph_index <= end ) - goto FoundRange; - - p += 4; /* ignore index offset */ - } - goto NoBitmap; - - FoundRange: - image_offset = FT_NEXT_ULONG( p ); - - /* overflow check */ - p = decoder->eblc_base + decoder->strike_index_array; - if ( image_offset > (FT_ULong)( p_limit - p ) ) - goto Failure; - - p += image_offset; - if ( p + 8 > p_limit ) - goto NoBitmap; - - /* now find the glyph's location and extend within the ebdt table */ - index_format = FT_NEXT_USHORT( p ); - image_format = FT_NEXT_USHORT( p ); - image_offset = FT_NEXT_ULONG ( p ); - - switch ( index_format ) - { - case 1: /* 4-byte offsets relative to `image_offset' */ - { - p += 4 * ( glyph_index - start ); - if ( p + 8 > p_limit ) - goto NoBitmap; - - image_start = FT_NEXT_ULONG( p ); - image_end = FT_NEXT_ULONG( p ); - - if ( image_start == image_end ) /* missing glyph */ - goto NoBitmap; - } - break; - - case 2: /* big metrics, constant image size */ - { - FT_ULong image_size; - - - if ( p + 12 > p_limit ) - goto NoBitmap; - - image_size = FT_NEXT_ULONG( p ); - - if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) - goto NoBitmap; - - image_start = image_size * ( glyph_index - start ); - image_end = image_start + image_size; - } - break; - - case 3: /* 2-byte offsets relative to 'image_offset' */ - { - p += 2 * ( glyph_index - start ); - if ( p + 4 > p_limit ) - goto NoBitmap; - - image_start = FT_NEXT_USHORT( p ); - image_end = FT_NEXT_USHORT( p ); - - if ( image_start == image_end ) /* missing glyph */ - goto NoBitmap; - } - break; - - case 4: /* sparse glyph array with (glyph,offset) pairs */ - { - FT_ULong mm, num_glyphs; - - - if ( p + 4 > p_limit ) - goto NoBitmap; - - num_glyphs = FT_NEXT_ULONG( p ); - - /* overflow check for p + ( num_glyphs + 1 ) * 4 */ - if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) - goto NoBitmap; - - for ( mm = 0; mm < num_glyphs; mm++ ) - { - FT_UInt gindex = FT_NEXT_USHORT( p ); - - - if ( gindex == glyph_index ) - { - image_start = FT_NEXT_USHORT( p ); - p += 2; - image_end = FT_PEEK_USHORT( p ); - break; - } - p += 2; - } - - if ( mm >= num_glyphs ) - goto NoBitmap; - } - break; - - case 5: /* constant metrics with sparse glyph codes */ - case 19: - { - FT_ULong image_size, mm, num_glyphs; - - - if ( p + 16 > p_limit ) - goto NoBitmap; - - image_size = FT_NEXT_ULONG( p ); - - if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) - goto NoBitmap; - - num_glyphs = FT_NEXT_ULONG( p ); - - /* overflow check for p + 2 * num_glyphs */ - if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) ) - goto NoBitmap; - - for ( mm = 0; mm < num_glyphs; mm++ ) - { - FT_UInt gindex = FT_NEXT_USHORT( p ); - - - if ( gindex == glyph_index ) - break; - } - - if ( mm >= num_glyphs ) - goto NoBitmap; - - image_start = image_size * mm; - image_end = image_start + image_size; - } - break; - - default: - goto NoBitmap; - } - - if ( image_start > image_end ) - goto NoBitmap; - - image_end -= image_start; - image_start = image_offset + image_start; - - FT_TRACE3(( "tt_sbit_decoder_load_image:" - " found sbit (format %d) for glyph index %d\n", - image_format, glyph_index )); - - return tt_sbit_decoder_load_bitmap( decoder, - load_flags, - image_format, - image_start, - image_end, - x_pos, - y_pos ); - - Failure: - return FT_THROW( Invalid_Table ); - - NoBitmap: - FT_TRACE4(( "tt_sbit_decoder_load_image:" - " no sbit found for glyph index %d\n", glyph_index )); - - return FT_THROW( Invalid_Argument ); - } - - - FT_LOCAL( FT_Error ) - tt_face_load_sbit_image( TT_Face face, - FT_ULong strike_index, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap *map, - TT_SBit_MetricsRec *metrics ) - { - TT_SBitDecoderRec decoder[1]; - FT_Error error; - - FT_UNUSED( load_flags ); - FT_UNUSED( stream ); - FT_UNUSED( map ); - - - error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); - if ( !error ) - { - error = tt_sbit_decoder_load_image( decoder, - load_flags, - glyph_index, - 0, - 0 ); - tt_sbit_decoder_done( decoder ); - } - - return error; - } - - -/* EOF */ diff --git a/drivers/freetype/freetype/src/sfnt/ttsbit.h b/drivers/freetype/freetype/src/sfnt/ttsbit.h deleted file mode 100644 index ea0b5f8ada..0000000000 --- a/drivers/freetype/freetype/src/sfnt/ttsbit.h +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsbit.h */ -/* */ -/* TrueType and OpenType embedded bitmap support (specification). */ -/* */ -/* Copyright 1996-2008, 2013 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 __TTSBIT_H__ -#define __TTSBIT_H__ - - -#include <ft2build.h> -#include "ttload.h" - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - tt_face_load_eblc( TT_Face face, - FT_Stream stream ); - - FT_LOCAL( void ) - tt_face_free_eblc( TT_Face face ); - - - FT_LOCAL( FT_Error ) - tt_face_set_sbit_strike( TT_Face face, - FT_Size_Request req, - FT_ULong* astrike_index ); - - FT_LOCAL( FT_Error ) - tt_face_load_strike_metrics( TT_Face face, - FT_ULong strike_index, - FT_Size_Metrics* metrics ); - - FT_LOCAL( FT_Error ) - tt_face_load_sbit_image( TT_Face face, - FT_ULong strike_index, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap *map, - TT_SBit_MetricsRec *metrics ); - - -FT_END_HEADER - -#endif /* __TTSBIT_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/smooth/Jamfile b/drivers/freetype/freetype/src/smooth/Jamfile deleted file mode 100644 index a8496aa2c2..0000000000 --- a/drivers/freetype/freetype/src/smooth/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/smooth Jamfile -# -# Copyright 2001 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) smooth ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = ftgrays ftsmooth ftspic ; - } - else - { - _sources = smooth ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/smooth Jamfile diff --git a/drivers/freetype/freetype/src/smooth/ftgrays.c b/drivers/freetype/freetype/src/smooth/ftgrays.c deleted file mode 100644 index 7532a35829..0000000000 --- a/drivers/freetype/freetype/src/smooth/ftgrays.c +++ /dev/null @@ -1,2132 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgrays.c */ -/* */ -/* A new `perfect' anti-aliasing renderer (body). */ -/* */ -/* Copyright 2000-2003, 2005-2013 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ - /* put the files `ftgrays.h' and `ftimage.h' into the current */ - /* compilation directory. Typically, you could do something like */ - /* */ - /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */ - /* */ - /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ - /* same directory */ - /* */ - /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ - /* */ - /* cc -c -D_STANDALONE_ ftgrays.c */ - /* */ - /* The renderer can be initialized with a call to */ - /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ - /* with a call to `ft_gray_raster.raster_render'. */ - /* */ - /* See the comments and documentation in the file `ftimage.h' for more */ - /* details on how the raster works. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* This is a new anti-aliasing scan-converter for FreeType 2. The */ - /* algorithm used here is _very_ different from the one in the standard */ - /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ - /* coverage of the outline on each pixel cell. */ - /* */ - /* It is based on ideas that I initially found in Raph Levien's */ - /* excellent LibArt graphics library (see http://www.levien.com/libart */ - /* for more information, though the web pages do not tell anything */ - /* about the renderer; you'll have to dive into the source code to */ - /* understand how it works). */ - /* */ - /* Note, however, that this is a _very_ different implementation */ - /* compared to Raph's. Coverage information is stored in a very */ - /* different way, and I don't use sorted vector paths. Also, it doesn't */ - /* use floating point values. */ - /* */ - /* This renderer has the following advantages: */ - /* */ - /* - It doesn't need an intermediate bitmap. Instead, one can supply a */ - /* callback function that will be called by the renderer to draw gray */ - /* spans on any target surface. You can thus do direct composition on */ - /* any kind of bitmap, provided that you give the renderer the right */ - /* callback. */ - /* */ - /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ - /* each pixel cell. */ - /* */ - /* - It performs a single pass on the outline (the `standard' FT2 */ - /* renderer makes two passes). */ - /* */ - /* - It can easily be modified to render to _any_ number of gray levels */ - /* cheaply. */ - /* */ - /* - For small (< 20) pixel sizes, it is faster than the standard */ - /* renderer. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* 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_smooth - - -#ifdef _STANDALONE_ - - - /* Auxiliary macros for token concatenation. */ -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) - - - /* define this to dump debugging information */ -/* #define FT_DEBUG_LEVEL_TRACE */ - - -#ifdef FT_DEBUG_LEVEL_TRACE -#include <stdio.h> -#include <stdarg.h> -#endif - -#include <stddef.h> -#include <string.h> -#include <setjmp.h> -#include <limits.h> -#define FT_UINT_MAX UINT_MAX -#define FT_INT_MAX INT_MAX - -#define ft_memset memset - -#define ft_setjmp setjmp -#define ft_longjmp longjmp -#define ft_jmp_buf jmp_buf - -typedef ptrdiff_t FT_PtrDist; - - -#define ErrRaster_Invalid_Mode -2 -#define ErrRaster_Invalid_Outline -1 -#define ErrRaster_Invalid_Argument -3 -#define ErrRaster_Memory_Overflow -4 - -#define FT_BEGIN_HEADER -#define FT_END_HEADER - -#include "ftimage.h" -#include "ftgrays.h" - - - /* This macro is used to indicate that a function parameter is unused. */ - /* Its purpose is simply to reduce compiler warnings. Note also that */ - /* simply defining it as `(void)x' doesn't avoid warnings with certain */ - /* ANSI compilers (e.g. LCC). */ -#define FT_UNUSED( x ) (x) = (x) - - - /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */ - -#ifdef FT_DEBUG_LEVEL_TRACE - - void - FT_Message( const char* fmt, - ... ) - { - va_list ap; - - - va_start( ap, fmt ); - vfprintf( stderr, fmt, ap ); - va_end( ap ); - } - - - /* empty function useful for setting a breakpoint to catch errors */ - int - FT_Throw( int error, - int line, - const char* file ) - { - FT_UNUSED( error ); - FT_UNUSED( line ); - FT_UNUSED( file ); - - return 0; - } - - - /* we don't handle tracing levels in stand-alone mode; */ -#ifndef FT_TRACE5 -#define FT_TRACE5( varformat ) FT_Message varformat -#endif -#ifndef FT_TRACE7 -#define FT_TRACE7( varformat ) FT_Message varformat -#endif -#ifndef FT_ERROR -#define FT_ERROR( varformat ) FT_Message varformat -#endif - -#define FT_THROW( e ) \ - ( FT_Throw( FT_ERR_CAT( ErrRaster, e ), \ - __LINE__, \ - __FILE__ ) | \ - FT_ERR_CAT( ErrRaster, e ) ) - -#else /* !FT_DEBUG_LEVEL_TRACE */ - -#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */ -#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ -#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ -#define FT_THROW( e ) FT_ERR_CAT( ErrRaster_, e ) - - -#endif /* !FT_DEBUG_LEVEL_TRACE */ - - -#define FT_DEFINE_OUTLINE_FUNCS( class_, \ - move_to_, line_to_, \ - conic_to_, cubic_to_, \ - shift_, delta_ ) \ - static const FT_Outline_Funcs class_ = \ - { \ - move_to_, \ - line_to_, \ - conic_to_, \ - cubic_to_, \ - shift_, \ - delta_ \ - }; - -#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \ - raster_new_, raster_reset_, \ - raster_set_mode_, raster_render_, \ - raster_done_ ) \ - const FT_Raster_Funcs class_ = \ - { \ - glyph_format_, \ - raster_new_, \ - raster_reset_, \ - raster_set_mode_, \ - raster_render_, \ - raster_done_ \ - }; - - -#else /* !_STANDALONE_ */ - - -#include <ft2build.h> -#include "ftgrays.h" -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_OUTLINE_H - -#include "ftsmerrs.h" - -#include "ftspic.h" - -#define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph -#define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory -#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory - - -#endif /* !_STANDALONE_ */ - - -#ifndef FT_MEM_SET -#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) -#endif - -#ifndef FT_MEM_ZERO -#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) -#endif - - /* as usual, for the speed hungry :-) */ - -#undef RAS_ARG -#undef RAS_ARG_ -#undef RAS_VAR -#undef RAS_VAR_ - -#ifndef FT_STATIC_RASTER - -#define RAS_ARG gray_PWorker worker -#define RAS_ARG_ gray_PWorker worker, - -#define RAS_VAR worker -#define RAS_VAR_ worker, - -#else /* FT_STATIC_RASTER */ - -#define RAS_ARG /* empty */ -#define RAS_ARG_ /* empty */ -#define RAS_VAR /* empty */ -#define RAS_VAR_ /* empty */ - -#endif /* FT_STATIC_RASTER */ - - - /* must be at least 6 bits! */ -#define PIXEL_BITS 8 - -#undef FLOOR -#undef CEILING -#undef TRUNC -#undef SCALED - -#define ONE_PIXEL ( 1L << PIXEL_BITS ) -#define PIXEL_MASK ( -1L << PIXEL_BITS ) -#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) -#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) -#define FLOOR( x ) ( (x) & -ONE_PIXEL ) -#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) -#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) - -#if PIXEL_BITS >= 6 -#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) -#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) -#else -#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) -#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) -#endif - - - /*************************************************************************/ - /* */ - /* TYPE DEFINITIONS */ - /* */ - - /* don't change the following types to FT_Int or FT_Pos, since we might */ - /* need to define them to "float" or "double" when experimenting with */ - /* new algorithms */ - - typedef long TCoord; /* integer scanline/pixel coordinate */ - typedef long TPos; /* sub-pixel coordinate */ - - /* determine the type used to store cell areas. This normally takes at */ - /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ - /* `long' instead of `int', otherwise bad things happen */ - -#if PIXEL_BITS <= 7 - - typedef int TArea; - -#else /* PIXEL_BITS >= 8 */ - - /* approximately determine the size of integers using an ANSI-C header */ -#if FT_UINT_MAX == 0xFFFFU - typedef long TArea; -#else - typedef int TArea; -#endif - -#endif /* PIXEL_BITS >= 8 */ - - - /* maximum number of gray spans in a call to the span callback */ -#define FT_MAX_GRAY_SPANS 32 - - - typedef struct TCell_* PCell; - - typedef struct TCell_ - { - TPos x; /* same with gray_TWorker.ex */ - TCoord cover; /* same with gray_TWorker.cover */ - TArea area; - PCell next; - - } TCell; - - -#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ - /* We disable the warning `structure was padded due to */ - /* __declspec(align())' in order to compile cleanly with */ - /* the maximum level of warnings. */ -#pragma warning( push ) -#pragma warning( disable : 4324 ) -#endif /* _MSC_VER */ - - typedef struct gray_TWorker_ - { - TCoord ex, ey; - TPos min_ex, max_ex; - TPos min_ey, max_ey; - TPos count_ex, count_ey; - - TArea area; - TCoord cover; - int invalid; - - PCell cells; - FT_PtrDist max_cells; - FT_PtrDist num_cells; - - TCoord cx, cy; - TPos x, y; - - TPos last_ey; - - FT_Vector bez_stack[32 * 3 + 1]; - int lev_stack[32]; - - FT_Outline outline; - FT_Bitmap target; - FT_BBox clip_box; - - FT_Span gray_spans[FT_MAX_GRAY_SPANS]; - int num_gray_spans; - - FT_Raster_Span_Func render_span; - void* render_span_data; - int span_y; - - int band_size; - int band_shoot; - - ft_jmp_buf jump_buffer; - - void* buffer; - long buffer_size; - - PCell* ycells; - TPos ycount; - - } gray_TWorker, *gray_PWorker; - -#if defined( _MSC_VER ) -#pragma warning( pop ) -#endif - - -#ifndef FT_STATIC_RASTER -#define ras (*worker) -#else - static gray_TWorker ras; -#endif - - - typedef struct gray_TRaster_ - { - void* buffer; - long buffer_size; - int band_size; - void* memory; - gray_PWorker worker; - - } gray_TRaster, *gray_PRaster; - - - - /*************************************************************************/ - /* */ - /* Initialize the cells table. */ - /* */ - static void - gray_init_cells( RAS_ARG_ void* buffer, - long byte_size ) - { - ras.buffer = buffer; - ras.buffer_size = byte_size; - - ras.ycells = (PCell*) buffer; - ras.cells = NULL; - ras.max_cells = 0; - ras.num_cells = 0; - ras.area = 0; - ras.cover = 0; - ras.invalid = 1; - } - - - /*************************************************************************/ - /* */ - /* Compute the outline bounding box. */ - /* */ - static void - gray_compute_cbox( RAS_ARG ) - { - FT_Outline* outline = &ras.outline; - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - if ( outline->n_points <= 0 ) - { - ras.min_ex = ras.max_ex = 0; - ras.min_ey = ras.max_ey = 0; - return; - } - - ras.min_ex = ras.max_ex = vec->x; - ras.min_ey = ras.max_ey = vec->y; - - vec++; - - for ( ; vec < limit; vec++ ) - { - TPos x = vec->x; - TPos y = vec->y; - - - if ( x < ras.min_ex ) ras.min_ex = x; - if ( x > ras.max_ex ) ras.max_ex = x; - if ( y < ras.min_ey ) ras.min_ey = y; - if ( y > ras.max_ey ) ras.max_ey = y; - } - - /* truncate the bounding box to integer pixels */ - ras.min_ex = ras.min_ex >> 6; - ras.min_ey = ras.min_ey >> 6; - ras.max_ex = ( ras.max_ex + 63 ) >> 6; - ras.max_ey = ( ras.max_ey + 63 ) >> 6; - } - - - /*************************************************************************/ - /* */ - /* Record the current cell in the table. */ - /* */ - static PCell - gray_find_cell( RAS_ARG ) - { - PCell *pcell, cell; - TPos x = ras.ex; - - - if ( x > ras.count_ex ) - x = ras.count_ex; - - pcell = &ras.ycells[ras.ey]; - for (;;) - { - cell = *pcell; - if ( cell == NULL || cell->x > x ) - break; - - if ( cell->x == x ) - goto Exit; - - pcell = &cell->next; - } - - if ( ras.num_cells >= ras.max_cells ) - ft_longjmp( ras.jump_buffer, 1 ); - - cell = ras.cells + ras.num_cells++; - cell->x = x; - cell->area = 0; - cell->cover = 0; - - cell->next = *pcell; - *pcell = cell; - - Exit: - return cell; - } - - - static void - gray_record_cell( RAS_ARG ) - { - if ( !ras.invalid && ( ras.area | ras.cover ) ) - { - PCell cell = gray_find_cell( RAS_VAR ); - - - cell->area += ras.area; - cell->cover += ras.cover; - } - } - - - /*************************************************************************/ - /* */ - /* Set the current cell to a new position. */ - /* */ - static void - gray_set_cell( RAS_ARG_ TCoord ex, - TCoord ey ) - { - /* Move the cell pointer to a new position. We set the `invalid' */ - /* flag to indicate that the cell isn't part of those we're interested */ - /* in during the render phase. This means that: */ - /* */ - /* . the new vertical position must be within min_ey..max_ey-1. */ - /* . the new horizontal position must be strictly less than max_ex */ - /* */ - /* Note that if a cell is to the left of the clipping region, it is */ - /* actually set to the (min_ex-1) horizontal position. */ - - /* All cells that are on the left of the clipping region go to the */ - /* min_ex - 1 horizontal position. */ - ey -= ras.min_ey; - - if ( ex > ras.max_ex ) - ex = ras.max_ex; - - ex -= ras.min_ex; - if ( ex < 0 ) - ex = -1; - - /* are we moving to a different cell ? */ - if ( ex != ras.ex || ey != ras.ey ) - { - /* record the current one if it is valid */ - if ( !ras.invalid ) - gray_record_cell( RAS_VAR ); - - ras.area = 0; - ras.cover = 0; - } - - ras.ex = ex; - ras.ey = ey; - ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey || - ex >= ras.count_ex ); - } - - - /*************************************************************************/ - /* */ - /* Start a new contour at a given cell. */ - /* */ - static void - gray_start_cell( RAS_ARG_ TCoord ex, - TCoord ey ) - { - if ( ex > ras.max_ex ) - ex = (TCoord)( ras.max_ex ); - - if ( ex < ras.min_ex ) - ex = (TCoord)( ras.min_ex - 1 ); - - ras.area = 0; - ras.cover = 0; - ras.ex = ex - ras.min_ex; - ras.ey = ey - ras.min_ey; - ras.last_ey = SUBPIXELS( ey ); - ras.invalid = 0; - - gray_set_cell( RAS_VAR_ ex, ey ); - } - - - /*************************************************************************/ - /* */ - /* Render a scanline as one or more cells. */ - /* */ - static void - gray_render_scanline( RAS_ARG_ TCoord ey, - TPos x1, - TCoord y1, - TPos x2, - TCoord y2 ) - { - TCoord ex1, ex2, fx1, fx2, delta, mod; - long p, first, dx; - int incr; - - - dx = x2 - x1; - - ex1 = TRUNC( x1 ); - ex2 = TRUNC( x2 ); - fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); - fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); - - /* trivial case. Happens often */ - if ( y1 == y2 ) - { - gray_set_cell( RAS_VAR_ ex2, ey ); - return; - } - - /* everything is located in a single cell. That is easy! */ - /* */ - if ( ex1 == ex2 ) - { - delta = y2 - y1; - ras.area += (TArea)(( fx1 + fx2 ) * delta); - ras.cover += delta; - return; - } - - /* ok, we'll have to render a run of adjacent cells on the same */ - /* scanline... */ - /* */ - p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); - first = ONE_PIXEL; - incr = 1; - - if ( dx < 0 ) - { - p = fx1 * ( y2 - y1 ); - first = 0; - incr = -1; - dx = -dx; - } - - delta = (TCoord)( p / dx ); - mod = (TCoord)( p % dx ); - if ( mod < 0 ) - { - delta--; - mod += (TCoord)dx; - } - - ras.area += (TArea)(( fx1 + first ) * delta); - ras.cover += delta; - - ex1 += incr; - gray_set_cell( RAS_VAR_ ex1, ey ); - y1 += delta; - - if ( ex1 != ex2 ) - { - TCoord lift, rem; - - - p = ONE_PIXEL * ( y2 - y1 + delta ); - lift = (TCoord)( p / dx ); - rem = (TCoord)( p % dx ); - if ( rem < 0 ) - { - lift--; - rem += (TCoord)dx; - } - - mod -= (int)dx; - - while ( ex1 != ex2 ) - { - delta = lift; - mod += rem; - if ( mod >= 0 ) - { - mod -= (TCoord)dx; - delta++; - } - - ras.area += (TArea)(ONE_PIXEL * delta); - ras.cover += delta; - y1 += delta; - ex1 += incr; - gray_set_cell( RAS_VAR_ ex1, ey ); - } - } - - delta = y2 - y1; - ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); - ras.cover += delta; - } - - - /*************************************************************************/ - /* */ - /* Render a given line as a series of scanlines. */ - /* */ - static void - gray_render_line( RAS_ARG_ TPos to_x, - TPos to_y ) - { - TCoord ey1, ey2, fy1, fy2, mod; - TPos dx, dy, x, x2; - long p, first; - int delta, rem, lift, incr; - - - ey1 = TRUNC( ras.last_ey ); - ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ - fy1 = (TCoord)( ras.y - ras.last_ey ); - fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); - - dx = to_x - ras.x; - dy = to_y - ras.y; - - /* XXX: we should do something about the trivial case where dx == 0, */ - /* as it happens very often! */ - - /* perform vertical clipping */ - { - TCoord min, max; - - - min = ey1; - max = ey2; - if ( ey1 > ey2 ) - { - min = ey2; - max = ey1; - } - if ( min >= ras.max_ey || max < ras.min_ey ) - goto End; - } - - /* everything is on a single scanline */ - if ( ey1 == ey2 ) - { - gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ); - goto End; - } - - /* vertical line - avoid calling gray_render_scanline */ - incr = 1; - - if ( dx == 0 ) - { - TCoord ex = TRUNC( ras.x ); - TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); - TArea area; - - - first = ONE_PIXEL; - if ( dy < 0 ) - { - first = 0; - incr = -1; - } - - delta = (int)( first - fy1 ); - ras.area += (TArea)two_fx * delta; - ras.cover += delta; - ey1 += incr; - - gray_set_cell( RAS_VAR_ ex, ey1 ); - - delta = (int)( first + first - ONE_PIXEL ); - area = (TArea)two_fx * delta; - while ( ey1 != ey2 ) - { - ras.area += area; - ras.cover += delta; - ey1 += incr; - - gray_set_cell( RAS_VAR_ ex, ey1 ); - } - - delta = (int)( fy2 - ONE_PIXEL + first ); - ras.area += (TArea)two_fx * delta; - ras.cover += delta; - - goto End; - } - - /* ok, we have to render several scanlines */ - p = ( ONE_PIXEL - fy1 ) * dx; - first = ONE_PIXEL; - incr = 1; - - if ( dy < 0 ) - { - p = fy1 * dx; - first = 0; - incr = -1; - dy = -dy; - } - - delta = (int)( p / dy ); - mod = (int)( p % dy ); - if ( mod < 0 ) - { - delta--; - mod += (TCoord)dy; - } - - x = ras.x + delta; - gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); - - ey1 += incr; - gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); - - if ( ey1 != ey2 ) - { - p = ONE_PIXEL * dx; - lift = (int)( p / dy ); - rem = (int)( p % dy ); - if ( rem < 0 ) - { - lift--; - rem += (int)dy; - } - mod -= (int)dy; - - while ( ey1 != ey2 ) - { - delta = lift; - mod += rem; - if ( mod >= 0 ) - { - mod -= (int)dy; - delta++; - } - - x2 = x + delta; - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), x2, - (TCoord)first ); - x = x2; - - ey1 += incr; - gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); - } - } - - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), to_x, - fy2 ); - - End: - ras.x = to_x; - ras.y = to_y; - ras.last_ey = SUBPIXELS( ey2 ); - } - - - static void - gray_split_conic( FT_Vector* base ) - { - TPos a, b; - - - base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; - - base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; - } - - - static void - gray_render_conic( RAS_ARG_ const FT_Vector* control, - const FT_Vector* to ) - { - TPos dx, dy; - TPos min, max, y; - int top, level; - int* levels; - FT_Vector* arc; - - - levels = ras.lev_stack; - - arc = ras.bez_stack; - arc[0].x = UPSCALE( to->x ); - arc[0].y = UPSCALE( to->y ); - arc[1].x = UPSCALE( control->x ); - arc[1].y = UPSCALE( control->y ); - arc[2].x = ras.x; - arc[2].y = ras.y; - top = 0; - - dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x ); - dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y ); - if ( dx < dy ) - dx = dy; - - if ( dx < ONE_PIXEL / 4 ) - goto Draw; - - /* short-cut the arc that crosses the current band */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; - - level = 0; - do - { - dx >>= 2; - level++; - } while ( dx > ONE_PIXEL / 4 ); - - levels[0] = level; - - do - { - level = levels[top]; - if ( level > 0 ) - { - gray_split_conic( arc ); - arc += 2; - top++; - levels[top] = levels[top - 1] = level - 1; - continue; - } - - Draw: - gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - top--; - arc -= 2; - - } while ( top >= 0 ); - } - - - static void - gray_split_cubic( FT_Vector* base ) - { - TPos a, b, c, d; - - - base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c ) / 2; - base[5].x = b = ( base[3].x + d ) / 2; - c = ( c + d ) / 2; - base[2].x = a = ( a + c ) / 2; - base[4].x = b = ( b + c ) / 2; - base[3].x = ( a + b ) / 2; - - base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c ) / 2; - base[5].y = b = ( base[3].y + d ) / 2; - c = ( c + d ) / 2; - base[2].y = a = ( a + c ) / 2; - base[4].y = b = ( b + c ) / 2; - base[3].y = ( a + b ) / 2; - } - - - static void - gray_render_cubic( RAS_ARG_ const FT_Vector* control1, - const FT_Vector* control2, - const FT_Vector* to ) - { - FT_Vector* arc; - TPos min, max, y; - - - arc = ras.bez_stack; - arc[0].x = UPSCALE( to->x ); - arc[0].y = UPSCALE( to->y ); - arc[1].x = UPSCALE( control2->x ); - arc[1].y = UPSCALE( control2->y ); - arc[2].x = UPSCALE( control1->x ); - arc[2].y = UPSCALE( control1->y ); - arc[3].x = ras.x; - arc[3].y = ras.y; - - /* Short-cut the arc that crosses the current band. */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[2].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[3].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; - - for (;;) - { - /* Decide whether to split or draw. See `Rapid Termination */ - /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */ - /* F. Hain, at */ - /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ - - { - TPos dx, dy, dx_, dy_; - TPos dx1, dy1, dx2, dy2; - TPos L, s, s_limit; - - - /* dx and dy are x and y components of the P0-P3 chord vector. */ - dx = arc[3].x - arc[0].x; - dy = arc[3].y - arc[0].y; - - /* L is an (under)estimate of the Euclidean distance P0-P3. */ - /* */ - /* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated */ - /* with least maximum error by */ - /* */ - /* r_upperbound = dx + (sqrt(2) - 1) * dy , */ - /* */ - /* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */ - /* error of no more than 8.4%. */ - /* */ - /* Similarly, some elementary calculus shows that r can be */ - /* underestimated with least maximum error by */ - /* */ - /* r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx */ - /* + sqrt(2 - sqrt(2)) / 2 * dy . */ - /* */ - /* 236/256 and 97/256 are (under)estimates of the two algebraic */ - /* numbers, giving an error of no more than 8.1%. */ - - dx_ = FT_ABS( dx ); - dy_ = FT_ABS( dy ); - - /* This is the same as */ - /* */ - /* L = ( 236 * FT_MAX( dx_, dy_ ) */ - /* + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */ - L = ( dx_ > dy_ ? 236 * dx_ + 97 * dy_ - : 97 * dx_ + 236 * dy_ ) >> 8; - - /* Avoid possible arithmetic overflow below by splitting. */ - if ( L > 32767 ) - goto Split; - - /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ - s_limit = L * (TPos)( ONE_PIXEL / 6 ); - - /* s is L * the perpendicular distance from P1 to the line P0-P3. */ - dx1 = arc[1].x - arc[0].x; - dy1 = arc[1].y - arc[0].y; - s = FT_ABS( dy * dx1 - dx * dy1 ); - - if ( s > s_limit ) - goto Split; - - /* s is L * the perpendicular distance from P2 to the line P0-P3. */ - dx2 = arc[2].x - arc[0].x; - dy2 = arc[2].y - arc[0].y; - s = FT_ABS( dy * dx2 - dx * dy2 ); - - if ( s > s_limit ) - goto Split; - - /* Split super curvy segments where the off points are so far - from the chord that the angles P0-P1-P3 or P0-P2-P3 become - acute as detected by appropriate dot products. */ - if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || - dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) - goto Split; - - /* No reason to split. */ - goto Draw; - } - - Split: - gray_split_cubic( arc ); - arc += 3; - continue; - - Draw: - gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - - if ( arc == ras.bez_stack ) - return; - - arc -= 3; - } - } - - - static int - gray_move_to( const FT_Vector* to, - gray_PWorker worker ) - { - TPos x, y; - - - /* record current cell, if any */ - gray_record_cell( RAS_VAR ); - - /* start to a new position */ - x = UPSCALE( to->x ); - y = UPSCALE( to->y ); - - gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); - - worker->x = x; - worker->y = y; - return 0; - } - - - static int - gray_line_to( const FT_Vector* to, - gray_PWorker worker ) - { - gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) ); - return 0; - } - - - static int - gray_conic_to( const FT_Vector* control, - const FT_Vector* to, - gray_PWorker worker ) - { - gray_render_conic( RAS_VAR_ control, to ); - return 0; - } - - - static int - gray_cubic_to( const FT_Vector* control1, - const FT_Vector* control2, - const FT_Vector* to, - gray_PWorker worker ) - { - gray_render_cubic( RAS_VAR_ control1, control2, to ); - return 0; - } - - - static void - gray_render_span( int y, - int count, - const FT_Span* spans, - gray_PWorker worker ) - { - unsigned char* p; - FT_Bitmap* map = &worker->target; - - - /* first of all, compute the scanline offset */ - p = (unsigned char*)map->buffer - y * map->pitch; - if ( map->pitch >= 0 ) - p += (unsigned)( ( map->rows - 1 ) * map->pitch ); - - for ( ; count > 0; count--, spans++ ) - { - unsigned char coverage = spans->coverage; - - - if ( coverage ) - { - /* For small-spans it is faster to do it by ourselves than - * calling `memset'. This is mainly due to the cost of the - * function call. - */ - if ( spans->len >= 8 ) - FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); - else - { - unsigned char* q = p + spans->x; - - - switch ( spans->len ) - { - case 7: *q++ = (unsigned char)coverage; - case 6: *q++ = (unsigned char)coverage; - case 5: *q++ = (unsigned char)coverage; - case 4: *q++ = (unsigned char)coverage; - case 3: *q++ = (unsigned char)coverage; - case 2: *q++ = (unsigned char)coverage; - case 1: *q = (unsigned char)coverage; - default: - ; - } - } - } - } - } - - - static void - gray_hline( RAS_ARG_ TCoord x, - TCoord y, - TPos area, - TCoord acount ) - { - int coverage; - - - /* compute the coverage line's coverage, depending on the */ - /* outline fill rule */ - /* */ - /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ - /* */ - coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); - /* use range 0..256 */ - if ( coverage < 0 ) - coverage = -coverage; - - if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) - { - coverage &= 511; - - if ( coverage > 256 ) - coverage = 512 - coverage; - else if ( coverage == 256 ) - coverage = 255; - } - else - { - /* normal non-zero winding rule */ - if ( coverage >= 256 ) - coverage = 255; - } - - y += (TCoord)ras.min_ey; - x += (TCoord)ras.min_ex; - - /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ - if ( x >= 32767 ) - x = 32767; - - /* FT_Span.y is an integer, so limit our coordinates appropriately */ - if ( y >= FT_INT_MAX ) - y = FT_INT_MAX; - - if ( coverage ) - { - FT_Span* span; - int count; - - - /* see whether we can add this span to the current list */ - count = ras.num_gray_spans; - span = ras.gray_spans + count - 1; - if ( count > 0 && - ras.span_y == y && - (int)span->x + span->len == (int)x && - span->coverage == coverage ) - { - span->len = (unsigned short)( span->len + acount ); - return; - } - - if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) - { - if ( ras.render_span && count > 0 ) - ras.render_span( ras.span_y, count, ras.gray_spans, - ras.render_span_data ); - -#ifdef FT_DEBUG_LEVEL_TRACE - - if ( count > 0 ) - { - int n; - - - FT_TRACE7(( "y = %3d ", ras.span_y )); - span = ras.gray_spans; - for ( n = 0; n < count; n++, span++ ) - FT_TRACE7(( "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage )); - FT_TRACE7(( "\n" )); - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - ras.num_gray_spans = 0; - ras.span_y = (int)y; - - count = 0; - span = ras.gray_spans; - } - else - span++; - - /* add a gray span to the current list */ - span->x = (short)x; - span->len = (unsigned short)acount; - span->coverage = (unsigned char)coverage; - - ras.num_gray_spans++; - } - } - - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* to be called while in the debugger -- */ - /* this function causes a compiler warning since it is unused otherwise */ - static void - gray_dump_cells( RAS_ARG ) - { - int yindex; - - - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - { - PCell cell; - - - printf( "%3d:", yindex ); - - for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) - printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); - printf( "\n" ); - } - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - - static void - gray_sweep( RAS_ARG_ const FT_Bitmap* target ) - { - int yindex; - - FT_UNUSED( target ); - - - if ( ras.num_cells == 0 ) - return; - - ras.num_gray_spans = 0; - - FT_TRACE7(( "gray_sweep: start\n" )); - - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - { - PCell cell = ras.ycells[yindex]; - TCoord cover = 0; - TCoord x = 0; - - - for ( ; cell != NULL; cell = cell->next ) - { - TPos area; - - - if ( cell->x > x && cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), - cell->x - x ); - - cover += cell->cover; - area = cover * ( ONE_PIXEL * 2 ) - cell->area; - - if ( area != 0 && cell->x >= 0 ) - gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); - - x = cell->x + 1; - } - - if ( cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), - ras.count_ex - x ); - } - - if ( ras.render_span && ras.num_gray_spans > 0 ) - ras.render_span( ras.span_y, ras.num_gray_spans, - ras.gray_spans, ras.render_span_data ); - -#ifdef FT_DEBUG_LEVEL_TRACE - - if ( ras.num_gray_spans > 0 ) - { - FT_Span* span; - int n; - - - FT_TRACE7(( "y = %3d ", ras.span_y )); - span = ras.gray_spans; - for ( n = 0; n < ras.num_gray_spans; n++, span++ ) - FT_TRACE7(( "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage )); - FT_TRACE7(( "\n" )); - } - - FT_TRACE7(( "gray_sweep: end\n" )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - } - - -#ifdef _STANDALONE_ - - /*************************************************************************/ - /* */ - /* The following function should only compile in stand-alone mode, */ - /* i.e., when building this component without the rest of FreeType. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Decompose */ - /* */ - /* <Description> */ - /* Walk over an outline's structure to decompose it into individual */ - /* segments and Bézier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source target. */ - /* */ - /* func_interface :: A table of `emitters', i.e., function pointers */ - /* called during decomposition to indicate path */ - /* operations. */ - /* */ - /* <InOut> */ - /* user :: A typeless pointer which is passed to each */ - /* emitter during the decomposition. It can be */ - /* used to store the state during the */ - /* decomposition. */ - /* */ - /* <Return> */ - /* Error code. 0 means success. */ - /* */ - static int - FT_Outline_Decompose( const FT_Outline* outline, - const FT_Outline_Funcs* func_interface, - void* user ) - { -#undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) - - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - int error; - - int n; /* index of contour in outline */ - int first; /* index of first point in contour */ - char tag; /* current point's state */ - - int shift; - TPos delta; - - - if ( !outline || !func_interface ) - return FT_THROW( Invalid_Argument ); - - shift = func_interface->shift; - delta = func_interface->delta; - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - int last; /* index of last point in contour */ - - - FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); - - last = outline->contours[n]; - if ( last < 0 ) - goto Invalid_Outline; - limit = outline->points + last; - - v_start = outline->points[first]; - v_start.x = SCALED( v_start.x ); - v_start.y = SCALED( v_start.y ); - - v_last = outline->points[last]; - v_last.x = SCALED( v_last.x ); - v_last.y = SCALED( v_last.y ); - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_CURVE_TAG_CONIC ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - FT_TRACE5(( " move to (%.2f, %.2f)\n", - v_start.x / 64.0, v_start.y / 64.0 )); - error = func_interface->move_to( &v_start, user ); - if ( error ) - goto Exit; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - switch ( tag ) - { - case FT_CURVE_TAG_ON: /* emit a single line_to */ - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - FT_TRACE5(( " line to (%.2f, %.2f)\n", - vec.x / 64.0, vec.y / 64.0 )); - error = func_interface->line_to( &vec, user ); - if ( error ) - goto Exit; - continue; - } - - case FT_CURVE_TAG_CONIC: /* consume conic arcs */ - v_control.x = SCALED( point->x ); - v_control.y = SCALED( point->y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - if ( tag == FT_CURVE_TAG_ON ) - { - FT_TRACE5(( " conic to (%.2f, %.2f)" - " with control (%.2f, %.2f)\n", - vec.x / 64.0, vec.y / 64.0, - v_control.x / 64.0, v_control.y / 64.0 )); - error = func_interface->conic_to( &v_control, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_CURVE_TAG_CONIC ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - FT_TRACE5(( " conic to (%.2f, %.2f)" - " with control (%.2f, %.2f)\n", - v_middle.x / 64.0, v_middle.y / 64.0, - v_control.x / 64.0, v_control.y / 64.0 )); - error = func_interface->conic_to( &v_control, &v_middle, user ); - if ( error ) - goto Exit; - - v_control = vec; - goto Do_Conic; - } - - FT_TRACE5(( " conic to (%.2f, %.2f)" - " with control (%.2f, %.2f)\n", - v_start.x / 64.0, v_start.y / 64.0, - v_control.x / 64.0, v_control.y / 64.0 )); - error = func_interface->conic_to( &v_control, &v_start, user ); - goto Close; - - default: /* FT_CURVE_TAG_CUBIC */ - { - FT_Vector vec1, vec2; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1.x = SCALED( point[-2].x ); - vec1.y = SCALED( point[-2].y ); - - vec2.x = SCALED( point[-1].x ); - vec2.y = SCALED( point[-1].y ); - - if ( point <= limit ) - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - FT_TRACE5(( " cubic to (%.2f, %.2f)" - " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", - vec.x / 64.0, vec.y / 64.0, - vec1.x / 64.0, vec1.y / 64.0, - vec2.x / 64.0, vec2.y / 64.0 )); - error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - FT_TRACE5(( " cubic to (%.2f, %.2f)" - " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", - v_start.x / 64.0, v_start.y / 64.0, - vec1.x / 64.0, vec1.y / 64.0, - vec2.x / 64.0, vec2.y / 64.0 )); - error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); - goto Close; - } - } - } - - /* close the contour with a line segment */ - FT_TRACE5(( " line to (%.2f, %.2f)\n", - v_start.x / 64.0, v_start.y / 64.0 )); - error = func_interface->line_to( &v_start, user ); - - Close: - if ( error ) - goto Exit; - - first = last + 1; - } - - FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); - return 0; - - Exit: - FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); - return error; - - Invalid_Outline: - return FT_THROW( Invalid_Outline ); - } - -#endif /* _STANDALONE_ */ - - - typedef struct gray_TBand_ - { - TPos min, max; - - } gray_TBand; - - FT_DEFINE_OUTLINE_FUNCS(func_interface, - (FT_Outline_MoveTo_Func) gray_move_to, - (FT_Outline_LineTo_Func) gray_line_to, - (FT_Outline_ConicTo_Func)gray_conic_to, - (FT_Outline_CubicTo_Func)gray_cubic_to, - 0, - 0 - ) - - static int - gray_convert_glyph_inner( RAS_ARG ) - { - - volatile int error = 0; - -#ifdef FT_CONFIG_OPTION_PIC - FT_Outline_Funcs func_interface; - Init_Class_func_interface(&func_interface); -#endif - - if ( ft_setjmp( ras.jump_buffer ) == 0 ) - { - error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); - gray_record_cell( RAS_VAR ); - } - else - error = FT_THROW( Memory_Overflow ); - - return error; - } - - - static int - gray_convert_glyph( RAS_ARG ) - { - gray_TBand bands[40]; - gray_TBand* volatile band; - int volatile n, num_bands; - TPos volatile min, max, max_y; - FT_BBox* clip; - - - /* Set up state in the raster object */ - gray_compute_cbox( RAS_VAR ); - - /* clip to target bitmap, exit if nothing to do */ - clip = &ras.clip_box; - - if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || - ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) - return 0; - - if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; - if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; - - if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; - if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; - - ras.count_ex = ras.max_ex - ras.min_ex; - ras.count_ey = ras.max_ey - ras.min_ey; - - /* set up vertical bands */ - num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); - if ( num_bands == 0 ) - num_bands = 1; - if ( num_bands >= 39 ) - num_bands = 39; - - ras.band_shoot = 0; - - min = ras.min_ey; - max_y = ras.max_ey; - - for ( n = 0; n < num_bands; n++, min = max ) - { - max = min + ras.band_size; - if ( n == num_bands - 1 || max > max_y ) - max = max_y; - - bands[0].min = min; - bands[0].max = max; - band = bands; - - while ( band >= bands ) - { - TPos bottom, top, middle; - int error; - - { - PCell cells_max; - int yindex; - long cell_start, cell_end, cell_mod; - - - ras.ycells = (PCell*)ras.buffer; - ras.ycount = band->max - band->min; - - cell_start = sizeof ( PCell ) * ras.ycount; - cell_mod = cell_start % sizeof ( TCell ); - if ( cell_mod > 0 ) - cell_start += sizeof ( TCell ) - cell_mod; - - cell_end = ras.buffer_size; - cell_end -= cell_end % sizeof ( TCell ); - - cells_max = (PCell)( (char*)ras.buffer + cell_end ); - ras.cells = (PCell)( (char*)ras.buffer + cell_start ); - if ( ras.cells >= cells_max ) - goto ReduceBands; - - ras.max_cells = cells_max - ras.cells; - if ( ras.max_cells < 2 ) - goto ReduceBands; - - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - ras.ycells[yindex] = NULL; - } - - ras.num_cells = 0; - ras.invalid = 1; - ras.min_ey = band->min; - ras.max_ey = band->max; - ras.count_ey = band->max - band->min; - - error = gray_convert_glyph_inner( RAS_VAR ); - - if ( !error ) - { - gray_sweep( RAS_VAR_ &ras.target ); - band--; - continue; - } - else if ( error != ErrRaster_Memory_Overflow ) - return 1; - - ReduceBands: - /* render pool overflow; we will reduce the render band by half */ - bottom = band->min; - top = band->max; - middle = bottom + ( ( top - bottom ) >> 1 ); - - /* This is too complex for a single scanline; there must */ - /* be some problems. */ - if ( middle == bottom ) - { -#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); -#endif - return 1; - } - - if ( bottom-top >= ras.band_size ) - ras.band_shoot++; - - band[1].min = bottom; - band[1].max = middle; - band[0].min = middle; - band[0].max = top; - band++; - } - } - - if ( ras.band_shoot > 8 && ras.band_size > 16 ) - ras.band_size = ras.band_size / 2; - - return 0; - } - - - static int - gray_raster_render( gray_PRaster raster, - const FT_Raster_Params* params ) - { - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; - gray_PWorker worker; - - - if ( !raster || !raster->buffer || !raster->buffer_size ) - return FT_THROW( Invalid_Argument ); - - if ( !outline ) - return FT_THROW( Invalid_Outline ); - - /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return 0; - - if ( !outline->contours || !outline->points ) - return FT_THROW( Invalid_Outline ); - - if ( outline->n_points != - outline->contours[outline->n_contours - 1] + 1 ) - return FT_THROW( Invalid_Outline ); - - worker = raster->worker; - - /* if direct mode is not set, we must have a target bitmap */ - if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) - { - if ( !target_map ) - return FT_THROW( Invalid_Argument ); - - /* nothing to do */ - if ( !target_map->width || !target_map->rows ) - return 0; - - if ( !target_map->buffer ) - return FT_THROW( Invalid_Argument ); - } - - /* this version does not support monochrome rendering */ - if ( !( params->flags & FT_RASTER_FLAG_AA ) ) - return FT_THROW( Invalid_Mode ); - - /* compute clipping box */ - if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) - { - /* compute clip box from target pixmap */ - ras.clip_box.xMin = 0; - ras.clip_box.yMin = 0; - ras.clip_box.xMax = target_map->width; - ras.clip_box.yMax = target_map->rows; - } - else if ( params->flags & FT_RASTER_FLAG_CLIP ) - ras.clip_box = params->clip_box; - else - { - ras.clip_box.xMin = -32768L; - ras.clip_box.yMin = -32768L; - ras.clip_box.xMax = 32767L; - ras.clip_box.yMax = 32767L; - } - - gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); - - ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = raster->band_size; - ras.num_gray_spans = 0; - - if ( params->flags & FT_RASTER_FLAG_DIRECT ) - { - ras.render_span = (FT_Raster_Span_Func)params->gray_spans; - ras.render_span_data = params->user; - } - else - { - ras.target = *target_map; - ras.render_span = (FT_Raster_Span_Func)gray_render_span; - ras.render_span_data = &ras; - } - - return gray_convert_glyph( RAS_VAR ); - } - - - /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ - /**** a static object. *****/ - -#ifdef _STANDALONE_ - - static int - gray_raster_new( void* memory, - FT_Raster* araster ) - { - static gray_TRaster the_raster; - - FT_UNUSED( memory ); - - - *araster = (FT_Raster)&the_raster; - FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); - - return 0; - } - - - static void - gray_raster_done( FT_Raster raster ) - { - /* nothing */ - FT_UNUSED( raster ); - } - -#else /* !_STANDALONE_ */ - - static int - gray_raster_new( FT_Memory memory, - FT_Raster* araster ) - { - FT_Error error; - gray_PRaster raster = NULL; - - - *araster = 0; - if ( !FT_ALLOC( raster, sizeof ( gray_TRaster ) ) ) - { - raster->memory = memory; - *araster = (FT_Raster)raster; - } - - return error; - } - - - static void - gray_raster_done( FT_Raster raster ) - { - FT_Memory memory = (FT_Memory)((gray_PRaster)raster)->memory; - - - FT_FREE( raster ); - } - -#endif /* !_STANDALONE_ */ - - - static void - gray_raster_reset( FT_Raster raster, - char* pool_base, - long pool_size ) - { - gray_PRaster rast = (gray_PRaster)raster; - - - if ( raster ) - { - if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 ) - { - gray_PWorker worker = (gray_PWorker)pool_base; - - - rast->worker = worker; - rast->buffer = pool_base + - ( ( sizeof ( gray_TWorker ) + - sizeof ( TCell ) - 1 ) & - ~( sizeof ( TCell ) - 1 ) ); - rast->buffer_size = (long)( ( pool_base + pool_size ) - - (char*)rast->buffer ) & - ~( sizeof ( TCell ) - 1 ); - rast->band_size = (int)( rast->buffer_size / - ( sizeof ( TCell ) * 8 ) ); - } - else - { - rast->buffer = NULL; - rast->buffer_size = 0; - rast->worker = NULL; - } - } - } - - - FT_DEFINE_RASTER_FUNCS(ft_grays_raster, - FT_GLYPH_FORMAT_OUTLINE, - - (FT_Raster_New_Func) gray_raster_new, - (FT_Raster_Reset_Func) gray_raster_reset, - (FT_Raster_Set_Mode_Func)0, - (FT_Raster_Render_Func) gray_raster_render, - (FT_Raster_Done_Func) gray_raster_done - ) - - -/* END */ - - -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ diff --git a/drivers/freetype/freetype/src/smooth/ftgrays.h b/drivers/freetype/freetype/src/smooth/ftgrays.h deleted file mode 100644 index f20f55f14b..0000000000 --- a/drivers/freetype/freetype/src/smooth/ftgrays.h +++ /dev/null @@ -1,58 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgrays.h */ -/* */ -/* FreeType smooth renderer declaration */ -/* */ -/* Copyright 1996-2001 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 __FTGRAYS_H__ -#define __FTGRAYS_H__ - -#ifdef __cplusplus - extern "C" { -#endif - - -#ifdef _STANDALONE_ -#include "ftimage.h" -#else -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */ -#include FT_IMAGE_H -#endif - - - /*************************************************************************/ - /* */ - /* To make ftgrays.h independent from configuration files we check */ - /* whether FT_EXPORT_VAR has been defined already. */ - /* */ - /* On some systems and compilers (Win32 mostly), an extra keyword is */ - /* necessary to compile the library as a DLL. */ - /* */ -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - - FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_grays_raster; - - -#ifdef __cplusplus - } -#endif - -#endif /* __FTGRAYS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftsmerrs.h b/drivers/freetype/freetype/src/smooth/ftsmerrs.h deleted file mode 100644 index 413d2f1f70..0000000000 --- a/drivers/freetype/freetype/src/smooth/ftsmerrs.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsmerrs.h */ -/* */ -/* smooth renderer error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the smooth renderer error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ - -#ifndef __FTSMERRS_H__ -#define __FTSMERRS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX Smooth_Err_ -#define FT_ERR_BASE FT_Mod_Err_Smooth - -#include FT_ERRORS_H - -#endif /* __FTSMERRS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftsmooth.c b/drivers/freetype/freetype/src/smooth/ftsmooth.c deleted file mode 100644 index 89088cd091..0000000000 --- a/drivers/freetype/freetype/src/smooth/ftsmooth.c +++ /dev/null @@ -1,534 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsmooth.c */ -/* */ -/* Anti-aliasing renderer interface (body). */ -/* */ -/* Copyright 2000-2006, 2009-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_OUTLINE_H -#include "ftsmooth.h" -#include "ftgrays.h" -#include "ftspic.h" - -#include "ftsmerrs.h" - - - /* initialize renderer -- init its raster */ - static FT_Error - ft_smooth_init( FT_Renderer render ) - { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); - - return 0; - } - - - /* sets render-specific mode */ - static FT_Error - ft_smooth_set_mode( FT_Renderer render, - FT_ULong mode_tag, - FT_Pointer data ) - { - /* we simply pass it to the raster */ - return render->clazz->raster_class->raster_set_mode( render->raster, - mode_tag, - data ); - } - - /* transform a given glyph image */ - static FT_Error - ft_smooth_transform( FT_Renderer render, - FT_GlyphSlot slot, - const FT_Matrix* matrix, - const FT_Vector* delta ) - { - FT_Error error = FT_Err_Ok; - - - if ( slot->format != render->glyph_format ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( matrix ) - FT_Outline_Transform( &slot->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &slot->outline, delta->x, delta->y ); - - Exit: - return error; - } - - - /* return the glyph's control box */ - static void - ft_smooth_get_cbox( FT_Renderer render, - FT_GlyphSlot slot, - FT_BBox* cbox ) - { - FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); - - if ( slot->format == render->glyph_format ) - FT_Outline_Get_CBox( &slot->outline, cbox ); - } - - - /* convert a slot's glyph image into a bitmap */ - static FT_Error - ft_smooth_render_generic( FT_Renderer render, - FT_GlyphSlot slot, - FT_Render_Mode mode, - const FT_Vector* origin, - FT_Render_Mode required_mode ) - { - FT_Error error; - FT_Outline* outline = NULL; - FT_BBox cbox; - FT_Pos width, height, pitch; -#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - FT_Pos height_org, width_org; -#endif - FT_Bitmap* bitmap = &slot->bitmap; - FT_Memory memory = render->root.memory; - FT_Int hmul = mode == FT_RENDER_MODE_LCD; - FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; - FT_Pos x_shift = 0; - FT_Pos y_shift = 0; - FT_Pos x_left, y_top; - - FT_Raster_Params params; - - FT_Bool have_translated_origin = FALSE; - FT_Bool have_outline_shifted = FALSE; - FT_Bool have_buffer = FALSE; - - - /* check glyph image format */ - if ( slot->format != render->glyph_format ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* check mode */ - if ( mode != required_mode ) - { - error = FT_THROW( Cannot_Render_Glyph ); - goto Exit; - } - - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ - if ( origin ) - { - FT_Outline_Translate( outline, origin->x, origin->y ); - have_translated_origin = TRUE; - } - - /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); - - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL( cbox.yMax ); - - if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large:" - " xMin = %d, xMax = %d\n", - cbox.xMin >> 6, cbox.xMax >> 6 )); - error = FT_THROW( Raster_Overflow ); - goto Exit; - } - else - width = ( cbox.xMax - cbox.xMin ) >> 6; - - if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large:" - " yMin = %d, yMax = %d\n", - cbox.yMin >> 6, cbox.yMax >> 6 )); - error = FT_THROW( Raster_Overflow ); - goto Exit; - } - else - height = ( cbox.yMax - cbox.yMin ) >> 6; - -#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - width_org = width; - height_org = height; -#endif - - /* release old bitmap buffer */ - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { - FT_FREE( bitmap->buffer ); - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - - /* allocate new one */ - pitch = width; - if ( hmul ) - { - width = width * 3; - pitch = FT_PAD_CEIL( width, 4 ); - } - - if ( vmul ) - height *= 3; - - x_shift = (FT_Int) cbox.xMin; - y_shift = (FT_Int) cbox.yMin; - x_left = (FT_Int)( cbox.xMin >> 6 ); - y_top = (FT_Int)( cbox.yMax >> 6 ); - -#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - - if ( slot->library->lcd_filter_func ) - { - FT_Int extra = slot->library->lcd_extra; - - - if ( hmul ) - { - x_shift -= 64 * ( extra >> 1 ); - width += 3 * extra; - pitch = FT_PAD_CEIL( width, 4 ); - x_left -= extra >> 1; - } - - if ( vmul ) - { - y_shift -= 64 * ( extra >> 1 ); - height += 3 * extra; - y_top += extra >> 1; - } - } - -#endif - -#if FT_UINT_MAX > 0xFFFFU - - /* Required check is (pitch * height < FT_ULONG_MAX), */ - /* but we care realistic cases only. Always pitch <= width. */ - if ( width > 0x7FFF || height > 0x7FFF ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", - width, height )); - error = FT_THROW( Raster_Overflow ); - goto Exit; - } - -#endif - - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->num_grays = 256; - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = pitch; - - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -x_shift, -y_shift ); - have_outline_shifted = TRUE; - - if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) - goto Exit; - else - have_buffer = TRUE; - - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - - /* set up parameters */ - params.target = bitmap; - params.source = outline; - params.flags = FT_RASTER_FLAG_AA; - -#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - - /* implode outline if needed */ - { - FT_Vector* points = outline->points; - FT_Vector* points_end = points + outline->n_points; - FT_Vector* vec; - - - if ( hmul ) - for ( vec = points; vec < points_end; vec++ ) - vec->x *= 3; - - if ( vmul ) - for ( vec = points; vec < points_end; vec++ ) - vec->y *= 3; - } - - /* render outline into the bitmap */ - error = render->raster_render( render->raster, ¶ms ); - - /* deflate outline if needed */ - { - FT_Vector* points = outline->points; - FT_Vector* points_end = points + outline->n_points; - FT_Vector* vec; - - - if ( hmul ) - for ( vec = points; vec < points_end; vec++ ) - vec->x /= 3; - - if ( vmul ) - for ( vec = points; vec < points_end; vec++ ) - vec->y /= 3; - } - - if ( error ) - goto Exit; - - if ( slot->library->lcd_filter_func ) - slot->library->lcd_filter_func( bitmap, mode, slot->library ); - -#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - /* render outline into bitmap */ - error = render->raster_render( render->raster, ¶ms ); - if ( error ) - goto Exit; - - /* expand it horizontally */ - if ( hmul ) - { - FT_Byte* line = bitmap->buffer; - FT_UInt hh; - - - for ( hh = height_org; hh > 0; hh--, line += pitch ) - { - FT_UInt xx; - FT_Byte* end = line + width; - - - for ( xx = width_org; xx > 0; xx-- ) - { - FT_UInt pixel = line[xx-1]; - - - end[-3] = (FT_Byte)pixel; - end[-2] = (FT_Byte)pixel; - end[-1] = (FT_Byte)pixel; - end -= 3; - } - } - } - - /* expand it vertically */ - if ( vmul ) - { - FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; - FT_Byte* write = bitmap->buffer; - FT_UInt hh; - - - for ( hh = height_org; hh > 0; hh-- ) - { - ft_memcpy( write, read, pitch ); - write += pitch; - - ft_memcpy( write, read, pitch ); - write += pitch; - - ft_memcpy( write, read, pitch ); - write += pitch; - read += pitch; - } - } - -#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - /* - * XXX: on 16bit system, we return an error for huge bitmap - * to prevent an overflow. - */ - if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) - { - error = FT_THROW( Invalid_Pixel_Size ); - goto Exit; - } - - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = (FT_Int)x_left; - slot->bitmap_top = (FT_Int)y_top; - - /* everything is fine; don't deallocate buffer */ - have_buffer = FALSE; - - error = FT_Err_Ok; - - Exit: - if ( have_outline_shifted ) - FT_Outline_Translate( outline, x_shift, y_shift ); - if ( have_translated_origin ) - FT_Outline_Translate( outline, -origin->x, -origin->y ); - if ( have_buffer ) - { - FT_FREE( bitmap->buffer ); - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - - return error; - } - - - /* convert a slot's glyph image into a bitmap */ - static FT_Error - ft_smooth_render( FT_Renderer render, - FT_GlyphSlot slot, - FT_Render_Mode mode, - const FT_Vector* origin ) - { - if ( mode == FT_RENDER_MODE_LIGHT ) - mode = FT_RENDER_MODE_NORMAL; - - return ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_NORMAL ); - } - - - /* convert a slot's glyph image into a horizontal LCD bitmap */ - static FT_Error - ft_smooth_render_lcd( FT_Renderer render, - FT_GlyphSlot slot, - FT_Render_Mode mode, - const FT_Vector* origin ) - { - FT_Error error; - - error = ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_LCD ); - if ( !error ) - slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; - - return error; - } - - - /* convert a slot's glyph image into a vertical LCD bitmap */ - static FT_Error - ft_smooth_render_lcd_v( FT_Renderer render, - FT_GlyphSlot slot, - FT_Render_Mode mode, - const FT_Vector* origin ) - { - FT_Error error; - - error = ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_LCD_V ); - if ( !error ) - slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V; - - return error; - } - - - FT_DEFINE_RENDERER( ft_smooth_renderer_class, - - FT_MODULE_RENDERER, - sizeof ( FT_RendererRec ), - - "smooth", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , - - FT_GLYPH_FORMAT_OUTLINE, - - (FT_Renderer_RenderFunc) ft_smooth_render, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET - ) - - - FT_DEFINE_RENDERER( ft_smooth_lcd_renderer_class, - - FT_MODULE_RENDERER, - sizeof ( FT_RendererRec ), - - "smooth-lcd", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , - - FT_GLYPH_FORMAT_OUTLINE, - - (FT_Renderer_RenderFunc) ft_smooth_render_lcd, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET - ) - - FT_DEFINE_RENDERER( ft_smooth_lcdv_renderer_class, - - FT_MODULE_RENDERER, - sizeof ( FT_RendererRec ), - - "smooth-lcdv", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , - - FT_GLYPH_FORMAT_OUTLINE, - - (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET - ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftsmooth.h b/drivers/freetype/freetype/src/smooth/ftsmooth.h deleted file mode 100644 index 3708790df1..0000000000 --- a/drivers/freetype/freetype/src/smooth/ftsmooth.h +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsmooth.h */ -/* */ -/* Anti-aliasing renderer interface (specification). */ -/* */ -/* Copyright 1996-2001 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 __FTSMOOTH_H__ -#define __FTSMOOTH_H__ - - -#include <ft2build.h> -#include FT_RENDER_H - - -FT_BEGIN_HEADER - - -#ifndef FT_CONFIG_OPTION_NO_STD_RASTER - FT_DECLARE_RENDERER( ft_std_renderer_class ) -#endif - -#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER - FT_DECLARE_RENDERER( ft_smooth_renderer_class ) - - FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class ) - - FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class ) -#endif - - - -FT_END_HEADER - -#endif /* __FTSMOOTH_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftspic.c b/drivers/freetype/freetype/src/smooth/ftspic.c deleted file mode 100644 index 67a2b8310c..0000000000 --- a/drivers/freetype/freetype/src/smooth/ftspic.c +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftspic.c */ -/* */ -/* The FreeType position independent code services for smooth module. */ -/* */ -/* Copyright 2009, 2010, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "ftspic.h" -#include "ftsmerrs.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from ftgrays.c */ - void - FT_Init_Class_ft_grays_raster( FT_Raster_Funcs* funcs ); - - - void - ft_smooth_renderer_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->smooth ) - { - SmoothPIC* container = (SmoothPIC*)pic_container->smooth; - - - if ( --container->ref_count ) - return; - - FT_FREE( container ); - pic_container->smooth = NULL; - } - } - - - FT_Error - ft_smooth_renderer_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - SmoothPIC* container = NULL; - FT_Memory memory = library->memory; - - - /* since this function also serve smooth_lcd and smooth_lcdv renderers, - it implements reference counting */ - if ( pic_container->smooth ) - { - ((SmoothPIC*)pic_container->smooth)->ref_count++; - return error; - } - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->smooth = container; - - container->ref_count = 1; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - FT_Init_Class_ft_grays_raster( &container->ft_grays_raster ); - - return error; - } - - - /* re-route these init and free functions to the above functions */ - FT_Error - ft_smooth_lcd_renderer_class_pic_init( FT_Library library ) - { - return ft_smooth_renderer_class_pic_init( library ); - } - - - void - ft_smooth_lcd_renderer_class_pic_free( FT_Library library ) - { - ft_smooth_renderer_class_pic_free( library ); - } - - - FT_Error - ft_smooth_lcdv_renderer_class_pic_init( FT_Library library ) - { - return ft_smooth_renderer_class_pic_init( library ); - } - - - void - ft_smooth_lcdv_renderer_class_pic_free( FT_Library library ) - { - ft_smooth_renderer_class_pic_free( library ); - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftspic.h b/drivers/freetype/freetype/src/smooth/ftspic.h deleted file mode 100644 index 334b51c3f1..0000000000 --- a/drivers/freetype/freetype/src/smooth/ftspic.h +++ /dev/null @@ -1,74 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftspic.h */ -/* */ -/* The FreeType position independent code services for smooth module. */ -/* */ -/* Copyright 2009 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __FTSPIC_H__ -#define __FTSPIC_H__ - - -FT_BEGIN_HEADER - -#include FT_INTERNAL_PIC_H - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_GRAYS_RASTER_GET ft_grays_raster - -#else /* FT_CONFIG_OPTION_PIC */ - - typedef struct SmoothPIC_ - { - int ref_count; - FT_Raster_Funcs ft_grays_raster; - - } SmoothPIC; - - -#define GET_PIC( lib ) \ - ( (SmoothPIC*)( (lib)->pic_container.smooth ) ) -#define FT_GRAYS_RASTER_GET ( GET_PIC( library )->ft_grays_raster ) - - - /* see ftspic.c for the implementation */ - void - ft_smooth_renderer_class_pic_free( FT_Library library ); - - void - ft_smooth_lcd_renderer_class_pic_free( FT_Library library ); - - void - ft_smooth_lcdv_renderer_class_pic_free( FT_Library library ); - - FT_Error - ft_smooth_renderer_class_pic_init( FT_Library library ); - - FT_Error - ft_smooth_lcd_renderer_class_pic_init( FT_Library library ); - - FT_Error - ft_smooth_lcdv_renderer_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* __FTSPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/smooth/module.mk b/drivers/freetype/freetype/src/smooth/module.mk deleted file mode 100644 index 47f6c04076..0000000000 --- a/drivers/freetype/freetype/src/smooth/module.mk +++ /dev/null @@ -1,27 +0,0 @@ -# -# FreeType 2 smooth renderer module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += SMOOTH_RENDERER - -define SMOOTH_RENDERER -$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_renderer_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) -$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcd_renderer_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for LCDs$(ECHO_DRIVER_DONE) -$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcdv_renderer_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for vertical LCDs$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/smooth/rules.mk b/drivers/freetype/freetype/src/smooth/rules.mk deleted file mode 100644 index 88d0aa53ac..0000000000 --- a/drivers/freetype/freetype/src/smooth/rules.mk +++ /dev/null @@ -1,70 +0,0 @@ -# -# FreeType 2 smooth renderer module build rules -# - - -# Copyright 1996-2000, 2001, 2003, 2011 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. - - -# smooth driver directory -# -SMOOTH_DIR := $(SRC_DIR)/smooth - -# compilation flags for the driver -# -SMOOTH_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SMOOTH_DIR)) - - -# smooth driver sources (i.e., C files) -# -SMOOTH_DRV_SRC := $(SMOOTH_DIR)/ftgrays.c \ - $(SMOOTH_DIR)/ftsmooth.c \ - $(SMOOTH_DIR)/ftspic.c - - -# smooth driver headers -# -SMOOTH_DRV_H := $(SMOOTH_DRV_SRC:%c=%h) \ - $(SMOOTH_DIR)/ftsmerrs.h - - -# smooth driver object(s) -# -# SMOOTH_DRV_OBJ_M is used during `multi' builds. -# SMOOTH_DRV_OBJ_S is used during `single' builds. -# -SMOOTH_DRV_OBJ_M := $(SMOOTH_DRV_SRC:$(SMOOTH_DIR)/%.c=$(OBJ_DIR)/%.$O) -SMOOTH_DRV_OBJ_S := $(OBJ_DIR)/smooth.$O - -# smooth driver source file for single build -# -SMOOTH_DRV_SRC_S := $(SMOOTH_DIR)/smooth.c - - -# smooth driver - single object -# -$(SMOOTH_DRV_OBJ_S): $(SMOOTH_DRV_SRC_S) $(SMOOTH_DRV_SRC) \ - $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SMOOTH_DRV_SRC_S)) - - -# smooth driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(SMOOTH_DIR)/%.c $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(SMOOTH_DRV_OBJ_S) -DRV_OBJS_M += $(SMOOTH_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/smooth/smooth.c b/drivers/freetype/freetype/src/smooth/smooth.c deleted file mode 100644 index a8ac51f9f8..0000000000 --- a/drivers/freetype/freetype/src/smooth/smooth.c +++ /dev/null @@ -1,27 +0,0 @@ -/***************************************************************************/ -/* */ -/* smooth.c */ -/* */ -/* FreeType anti-aliasing rasterer module component (body only). */ -/* */ -/* Copyright 1996-2001 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "ftspic.c" -#include "ftgrays.c" -#include "ftsmooth.c" - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/Jamfile b/drivers/freetype/freetype/src/truetype/Jamfile deleted file mode 100644 index a8cccfe137..0000000000 --- a/drivers/freetype/freetype/src/truetype/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/truetype Jamfile -# -# Copyright 2001, 2004 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) truetype ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ttpic ; - } - else - { - _sources = truetype ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/truetype Jamfile diff --git a/drivers/freetype/freetype/src/truetype/module.mk b/drivers/freetype/freetype/src/truetype/module.mk deleted file mode 100644 index baee81a773..0000000000 --- a/drivers/freetype/freetype/src/truetype/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 TrueType module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += TRUETYPE_DRIVER - -define TRUETYPE_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, tt_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/truetype/rules.mk b/drivers/freetype/freetype/src/truetype/rules.mk deleted file mode 100644 index d4b69f578b..0000000000 --- a/drivers/freetype/freetype/src/truetype/rules.mk +++ /dev/null @@ -1,74 +0,0 @@ -# -# FreeType 2 TrueType driver configuration rules -# - - -# Copyright 1996-2001, 2003-2004, 2011-2012 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. - - -# TrueType driver directory -# -TT_DIR := $(SRC_DIR)/truetype - - -# compilation flags for the driver -# -TT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) - - -# TrueType driver sources (i.e., C files) -# -TT_DRV_SRC := $(TT_DIR)/ttdriver.c \ - $(TT_DIR)/ttgload.c \ - $(TT_DIR)/ttgxvar.c \ - $(TT_DIR)/ttinterp.c \ - $(TT_DIR)/ttobjs.c \ - $(TT_DIR)/ttpic.c \ - $(TT_DIR)/ttpload.c \ - $(TT_DIR)/ttsubpix.c - -# TrueType driver headers -# -TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) \ - $(TT_DIR)/tterrors.h - - -# TrueType driver object(s) -# -# TT_DRV_OBJ_M is used during `multi' builds -# TT_DRV_OBJ_S is used during `single' builds -# -TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR)/%.c=$(OBJ_DIR)/%.$O) -TT_DRV_OBJ_S := $(OBJ_DIR)/truetype.$O - -# TrueType driver source file for single build -# -TT_DRV_SRC_S := $(TT_DIR)/truetype.c - - -# TrueType driver - single object -# -$(TT_DRV_OBJ_S): $(TT_DRV_SRC_S) $(TT_DRV_SRC) $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(TT_DRV_SRC_S)) - - -# driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(TT_DIR)/%.c $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(TT_DRV_OBJ_S) -DRV_OBJS_M += $(TT_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/truetype/truetype.c b/drivers/freetype/freetype/src/truetype/truetype.c deleted file mode 100644 index 576912b219..0000000000 --- a/drivers/freetype/freetype/src/truetype/truetype.c +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************/ -/* */ -/* truetype.c */ -/* */ -/* FreeType TrueType driver component (body only). */ -/* */ -/* Copyright 1996-2001, 2004, 2006, 2012 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "ttpic.c" -#include "ttdriver.c" /* driver interface */ -#include "ttpload.c" /* tables loader */ -#include "ttgload.c" /* glyph loader */ -#include "ttobjs.c" /* object manager */ - -#ifdef TT_USE_BYTECODE_INTERPRETER -#include "ttinterp.c" -#include "ttsubpix.c" -#endif - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#include "ttgxvar.c" /* gx distortable font */ -#endif - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttdriver.c b/drivers/freetype/freetype/src/truetype/ttdriver.c deleted file mode 100644 index fb25706ab8..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttdriver.c +++ /dev/null @@ -1,572 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttdriver.c */ -/* */ -/* TrueType font driver implementation (body). */ -/* */ -/* Copyright 1996-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_SERVICE_XFREE86_NAME_H - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#include FT_MULTIPLE_MASTERS_H -#include FT_SERVICE_MULTIPLE_MASTERS_H -#endif - -#include FT_SERVICE_TRUETYPE_ENGINE_H -#include FT_SERVICE_TRUETYPE_GLYF_H -#include FT_SERVICE_PROPERTIES_H -#include FT_TRUETYPE_DRIVER_H - -#include "ttdriver.h" -#include "ttgload.h" -#include "ttpload.h" - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#include "ttgxvar.h" -#endif - -#include "tterrors.h" - -#include "ttpic.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_ttdriver - - - /* - * PROPERTY SERVICE - * - */ - static FT_Error - tt_property_set( FT_Module module, /* TT_Driver */ - const char* property_name, - const void* value ) - { - FT_Error error = FT_Err_Ok; - TT_Driver driver = (TT_Driver)module; - - - if ( !ft_strcmp( property_name, "interpreter-version" ) ) - { - FT_UInt* interpreter_version = (FT_UInt*)value; - - -#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) - error = FT_ERR( Unimplemented_Feature ); - else -#endif - driver->interpreter_version = *interpreter_version; - - return error; - } - - FT_TRACE0(( "tt_property_set: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - static FT_Error - tt_property_get( FT_Module module, /* TT_Driver */ - const char* property_name, - const void* value ) - { - FT_Error error = FT_Err_Ok; - TT_Driver driver = (TT_Driver)module; - - FT_UInt interpreter_version = driver->interpreter_version; - - - if ( !ft_strcmp( property_name, "interpreter-version" ) ) - { - FT_UInt* val = (FT_UInt*)value; - - - *val = interpreter_version; - - return error; - } - - FT_TRACE0(( "tt_property_get: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - FT_DEFINE_SERVICE_PROPERTIESREC( - tt_service_properties, - (FT_Properties_SetFunc)tt_property_set, - (FT_Properties_GetFunc)tt_property_get ) - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F A C E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_get_kerning */ - /* */ - /* <Description> */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* <Output> */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings, are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static FT_Error - tt_get_kerning( FT_Face ttface, /* TT_Face */ - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - TT_Face face = (TT_Face)ttface; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; - - - kerning->x = 0; - kerning->y = 0; - - if ( sfnt ) - kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); - - return 0; - } - - -#undef PAIR_TAG - - - static FT_Error - tt_get_advances( FT_Face ttface, - FT_UInt start, - FT_UInt count, - FT_Int32 flags, - FT_Fixed *advances ) - { - FT_UInt nn; - TT_Face face = (TT_Face) ttface; - - - /* XXX: TODO: check for sbits */ - - if ( flags & FT_LOAD_VERTICAL_LAYOUT ) - { - for ( nn = 0; nn < count; nn++ ) - { - FT_Short tsb; - FT_UShort ah; - - - TT_Get_VMetrics( face, start + nn, &tsb, &ah ); - advances[nn] = ah; - } - } - else - { - for ( nn = 0; nn < count; nn++ ) - { - FT_Short lsb; - FT_UShort aw; - - - TT_Get_HMetrics( face, start + nn, &lsb, &aw ); - advances[nn] = aw; - } - } - - return FT_Err_Ok; - } - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** S I Z E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - static FT_Error - tt_size_select( FT_Size size, - FT_ULong strike_index ) - { - TT_Face ttface = (TT_Face)size->face; - TT_Size ttsize = (TT_Size)size; - FT_Error error = FT_Err_Ok; - - - ttsize->strike_index = strike_index; - - if ( FT_IS_SCALABLE( size->face ) ) - { - /* use the scaled metrics, even when tt_size_reset fails */ - FT_Select_Metrics( size->face, strike_index ); - - tt_size_reset( ttsize ); - } - else - { - SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; - FT_Size_Metrics* metrics = &size->metrics; - - - error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); - if ( error ) - ttsize->strike_index = 0xFFFFFFFFUL; - } - - return error; - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - - static FT_Error - tt_size_request( FT_Size size, - FT_Size_Request req ) - { - TT_Size ttsize = (TT_Size)size; - FT_Error error = FT_Err_Ok; - - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - if ( FT_HAS_FIXED_SIZES( size->face ) ) - { - TT_Face ttface = (TT_Face)size->face; - SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; - FT_ULong strike_index; - - - error = sfnt->set_sbit_strike( ttface, req, &strike_index ); - - if ( error ) - ttsize->strike_index = 0xFFFFFFFFUL; - else - return tt_size_select( size, strike_index ); - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - FT_Request_Metrics( size->face, req ); - - if ( FT_IS_SCALABLE( size->face ) ) - { - error = tt_size_reset( ttsize ); - ttsize->root.metrics = ttsize->metrics; - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_glyph_load */ - /* */ - /* <Description> */ - /* A driver method used to load a glyph within a given glyph slot. */ - /* */ - /* <Input> */ - /* slot :: A handle to the target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled, loaded, etc. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error - tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ - FT_Size ttsize, /* TT_Size */ - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; - TT_Size size = (TT_Size)ttsize; - FT_Face face = ttslot->face; - FT_Error error; - - - if ( !slot ) - return FT_THROW( Invalid_Slot_Handle ); - - if ( !size ) - return FT_THROW( Invalid_Size_Handle ); - - if ( !face ) - return FT_THROW( Invalid_Argument ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( glyph_index >= (FT_UInt)face->num_glyphs && - !face->internal->incremental_interface ) -#else - if ( glyph_index >= (FT_UInt)face->num_glyphs ) -#endif - return FT_THROW( Invalid_Argument ); - - if ( load_flags & FT_LOAD_NO_HINTING ) - { - /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ - /* are necessary to disable hinting for tricky fonts */ - - if ( FT_IS_TRICKY( face ) ) - load_flags &= ~FT_LOAD_NO_HINTING; - - if ( load_flags & FT_LOAD_NO_AUTOHINT ) - load_flags |= FT_LOAD_NO_HINTING; - } - - if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) - { - load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; - - if ( !FT_IS_TRICKY( face ) ) - load_flags |= FT_LOAD_NO_HINTING; - } - - /* now load the glyph outline if necessary */ - error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); - - /* force drop-out mode to 2 - irrelevant now */ - /* slot->outline.dropout_mode = 2; */ - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** D R I V E R I N T E R F A C E ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_DEFINE_SERVICE_MULTIMASTERSREC( - tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, - (FT_Set_MM_Design_Func) NULL, - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, - (FT_Get_MM_Var_Func) TT_Get_MM_Var, - (FT_Set_Var_Design_Func)TT_Set_Var_Design ) -#endif - - static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = - { -#ifdef TT_USE_BYTECODE_INTERPRETER - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_TRUETYPE_ENGINE_TYPE_UNPATENTED -#else - FT_TRUETYPE_ENGINE_TYPE_PATENTED -#endif - -#else /* !TT_USE_BYTECODE_INTERPRETER */ - - FT_TRUETYPE_ENGINE_TYPE_NONE - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - }; - - FT_DEFINE_SERVICE_TTGLYFREC( - tt_service_truetype_glyf, - (TT_Glyf_GetLocationFunc)tt_face_get_location ) - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_DEFINE_SERVICEDESCREC5( - tt_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, - FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, - FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, - FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, - FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) -#else - FT_DEFINE_SERVICEDESCREC4( - tt_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, - FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, - FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, - FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) -#endif - - - FT_CALLBACK_DEF( FT_Module_Interface ) - tt_get_interface( FT_Module driver, /* TT_Driver */ - const char* tt_interface ) - { - FT_Library library; - FT_Module_Interface result; - FT_Module sfntd; - SFNT_Service sfnt; - - - /* TT_SERVICES_GET derefers `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - if ( !driver ) - return NULL; - library = driver->library; - if ( !library ) - return NULL; -#endif - - result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); - if ( result != NULL ) - return result; - -#ifndef FT_CONFIG_OPTION_PIC - if ( !driver ) - return NULL; - library = driver->library; - if ( !library ) - return NULL; -#endif - - /* only return the default interface from the SFNT module */ - sfntd = FT_Get_Module( library, "sfnt" ); - if ( sfntd ) - { - sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); - if ( sfnt ) - return sfnt->get_interface( driver, tt_interface ); - } - - return 0; - } - - - /* The FT_DriverInterface structure is defined in ftdriver.h. */ - -#ifdef TT_USE_BYTECODE_INTERPRETER -#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER -#else -#define TT_HINTER_FLAG 0 -#endif - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#define TT_SIZE_SELECT tt_size_select -#else -#define TT_SIZE_SELECT 0 -#endif - - FT_DEFINE_DRIVER( - tt_driver_class, - - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - TT_HINTER_FLAG, - - sizeof ( TT_DriverRec ), - - "truetype", /* driver name */ - 0x10000L, /* driver version == 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or above */ - - (void*)0, /* driver specific interface */ - - tt_driver_init, - tt_driver_done, - tt_get_interface, - - sizeof ( TT_FaceRec ), - sizeof ( TT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - - tt_face_init, - tt_face_done, - tt_size_init, - tt_size_done, - tt_slot_init, - 0, /* FT_Slot_DoneFunc */ - - tt_glyph_load, - - tt_get_kerning, - 0, /* FT_Face_AttachFunc */ - tt_get_advances, - - tt_size_request, - TT_SIZE_SELECT - ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttdriver.h b/drivers/freetype/freetype/src/truetype/ttdriver.h deleted file mode 100644 index aae00f2617..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttdriver.h +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttdriver.h */ -/* */ -/* High-level TrueType driver interface (specification). */ -/* */ -/* Copyright 1996-2001, 2002 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 __TTDRIVER_H__ -#define __TTDRIVER_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H - - -FT_BEGIN_HEADER - - - FT_DECLARE_DRIVER( tt_driver_class ) - - -FT_END_HEADER - -#endif /* __TTDRIVER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/tterrors.h b/drivers/freetype/freetype/src/truetype/tterrors.h deleted file mode 100644 index 78d138fab2..0000000000 --- a/drivers/freetype/freetype/src/truetype/tterrors.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* tterrors.h */ -/* */ -/* TrueType error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the TrueType error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ - -#ifndef __TTERRORS_H__ -#define __TTERRORS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX TT_Err_ -#define FT_ERR_BASE FT_Mod_Err_TrueType - -#include FT_ERRORS_H - -#endif /* __TTERRORS_H__ */ - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttgload.c b/drivers/freetype/freetype/src/truetype/ttgload.c deleted file mode 100644 index f640a6c78e..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttgload.c +++ /dev/null @@ -1,2328 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgload.c */ -/* */ -/* TrueType Glyph Loader (body). */ -/* */ -/* Copyright 1996-2013 */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_TAGS_H -#include FT_OUTLINE_H -#include FT_TRUETYPE_DRIVER_H - -#include "ttgload.h" -#include "ttpload.h" - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#include "ttgxvar.h" -#endif - -#include "tterrors.h" -#include "ttsubpix.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_ttgload - - - /*************************************************************************/ - /* */ - /* Composite glyph flags. */ - /* */ -#define ARGS_ARE_WORDS 0x0001 -#define ARGS_ARE_XY_VALUES 0x0002 -#define ROUND_XY_TO_GRID 0x0004 -#define WE_HAVE_A_SCALE 0x0008 -/* reserved 0x0010 */ -#define MORE_COMPONENTS 0x0020 -#define WE_HAVE_AN_XY_SCALE 0x0040 -#define WE_HAVE_A_2X2 0x0080 -#define WE_HAVE_INSTR 0x0100 -#define USE_MY_METRICS 0x0200 -#define OVERLAP_COMPOUND 0x0400 -#define SCALED_COMPONENT_OFFSET 0x0800 -#define UNSCALED_COMPONENT_OFFSET 0x1000 - - - /*************************************************************************/ - /* */ - /* Return the horizontal metrics in font units for a given glyph. */ - /* */ - FT_LOCAL_DEF( void ) - TT_Get_HMetrics( TT_Face face, - FT_UInt idx, - FT_Short* lsb, - FT_UShort* aw ) - { - ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw ); - - FT_TRACE5(( " advance width (font units): %d\n", *aw )); - FT_TRACE5(( " left side bearing (font units): %d\n", *lsb )); - } - - - /*************************************************************************/ - /* */ - /* Return the vertical metrics in font units for a given glyph. */ - /* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */ - /* table, typoAscender/Descender from the `OS/2' table would be used */ - /* instead, and if there were no `OS/2' table, use ascender/descender */ - /* from the `hhea' table. But that is not what Microsoft's rasterizer */ - /* apparently does: It uses the ppem value as the advance height, and */ - /* sets the top side bearing to be zero. */ - /* */ - FT_LOCAL_DEF( void ) - TT_Get_VMetrics( TT_Face face, - FT_UInt idx, - FT_Short* tsb, - FT_UShort* ah ) - { - if ( face->vertical_info ) - ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah ); - -#if 1 /* Empirically determined, at variance with what MS said */ - - else - { - *tsb = 0; - *ah = face->root.units_per_EM; - } - -#else /* This is what MS said to do. It isn't what they do, however. */ - - else if ( face->os2.version != 0xFFFFU ) - { - *tsb = face->os2.sTypoAscender; - *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; - } - else - { - *tsb = face->horizontal.Ascender; - *ah = face->horizontal.Ascender - face->horizontal.Descender; - } - -#endif - - FT_TRACE5(( " advance height (font units): %d\n", *ah )); - FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); - } - - - static void - tt_get_metrics( TT_Loader loader, - FT_UInt glyph_index ) - { - TT_Face face = (TT_Face)loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); -#endif - - FT_Short left_bearing = 0, top_bearing = 0; - FT_UShort advance_width = 0, advance_height = 0; - - - TT_Get_HMetrics( face, glyph_index, - &left_bearing, - &advance_width ); - TT_Get_VMetrics( face, glyph_index, - &top_bearing, - &advance_height ); - - loader->left_bearing = left_bearing; - loader->advance = advance_width; - loader->top_bearing = top_bearing; - loader->vadvance = advance_height; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - if ( loader->exec ) - loader->exec->sph_tweak_flags = 0; - - /* this may not be the right place for this, but it works */ - if ( loader->exec && loader->exec->ignore_x_mode ) - sph_set_tweaks( loader, glyph_index ); - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - if ( !loader->linear_def ) - { - loader->linear_def = 1; - loader->linear = advance_width; - } - } - - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - static void - tt_get_metrics_incr_overrides( TT_Loader loader, - FT_UInt glyph_index ) - { - TT_Face face = (TT_Face)loader->face; - - FT_Short left_bearing = 0, top_bearing = 0; - FT_UShort advance_width = 0, advance_height = 0; - - - /* If this is an incrementally loaded font check whether there are */ - /* overriding metrics for this glyph. */ - if ( face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) - { - FT_Incremental_MetricsRec metrics; - FT_Error error; - - - metrics.bearing_x = loader->left_bearing; - metrics.bearing_y = 0; - metrics.advance = loader->advance; - metrics.advance_v = 0; - - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - if ( error ) - goto Exit; - - left_bearing = (FT_Short)metrics.bearing_x; - advance_width = (FT_UShort)metrics.advance; - -#if 0 - - /* GWW: Do I do the same for vertical metrics? */ - metrics.bearing_x = 0; - metrics.bearing_y = loader->top_bearing; - metrics.advance = loader->vadvance; - - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, TRUE, &metrics ); - if ( error ) - goto Exit; - - top_bearing = (FT_Short)metrics.bearing_y; - advance_height = (FT_UShort)metrics.advance; - -#endif /* 0 */ - - loader->left_bearing = left_bearing; - loader->advance = advance_width; - loader->top_bearing = top_bearing; - loader->vadvance = advance_height; - - if ( !loader->linear_def ) - { - loader->linear_def = 1; - loader->linear = advance_width; - } - } - - Exit: - return; - } - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - - /*************************************************************************/ - /* */ - /* Translates an array of coordinates. */ - /* */ - static void - translate_array( FT_UInt n, - FT_Vector* coords, - FT_Pos delta_x, - FT_Pos delta_y ) - { - FT_UInt k; - - - if ( delta_x ) - for ( k = 0; k < n; k++ ) - coords[k].x += delta_x; - - if ( delta_y ) - for ( k = 0; k < n; k++ ) - coords[k].y += delta_y; - } - - - /*************************************************************************/ - /* */ - /* The following functions are used by default with TrueType fonts. */ - /* However, they can be replaced by alternatives if we need to support */ - /* TrueType-compressed formats (like MicroType) in the future. */ - /* */ - /*************************************************************************/ - - FT_CALLBACK_DEF( FT_Error ) - TT_Access_Glyph_Frame( TT_Loader loader, - FT_UInt glyph_index, - FT_ULong offset, - FT_UInt byte_count ) - { - FT_Error error; - FT_Stream stream = loader->stream; - - /* for non-debug mode */ - FT_UNUSED( glyph_index ); - - - FT_TRACE4(( "Glyph %ld\n", glyph_index )); - - /* the following line sets the `error' variable through macros! */ - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) - return error; - - loader->cursor = stream->cursor; - loader->limit = stream->limit; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( void ) - TT_Forget_Glyph_Frame( TT_Loader loader ) - { - FT_Stream stream = loader->stream; - - - FT_FRAME_EXIT(); - } - - - FT_CALLBACK_DEF( FT_Error ) - TT_Load_Glyph_Header( TT_Loader loader ) - { - FT_Byte* p = loader->cursor; - FT_Byte* limit = loader->limit; - - - if ( p + 10 > limit ) - return FT_THROW( Invalid_Outline ); - - loader->n_contours = FT_NEXT_SHORT( p ); - - loader->bbox.xMin = FT_NEXT_SHORT( p ); - loader->bbox.yMin = FT_NEXT_SHORT( p ); - loader->bbox.xMax = FT_NEXT_SHORT( p ); - loader->bbox.yMax = FT_NEXT_SHORT( p ); - - FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); - FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, - loader->bbox.xMax )); - FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, - loader->bbox.yMax )); - loader->cursor = p; - - return FT_Err_Ok; - } - - - FT_CALLBACK_DEF( FT_Error ) - TT_Load_Simple_Glyph( TT_Loader load ) - { - FT_Error error; - FT_Byte* p = load->cursor; - FT_Byte* limit = load->limit; - FT_GlyphLoader gloader = load->gloader; - FT_Int n_contours = load->n_contours; - FT_Outline* outline; - TT_Face face = (TT_Face)load->face; - FT_UShort n_ins; - FT_Int n_points; - - FT_Byte *flag, *flag_limit; - FT_Byte c, count; - FT_Vector *vec, *vec_limit; - FT_Pos x; - FT_Short *cont, *cont_limit, prev_cont; - FT_Int xy_size = 0; - - - /* check that we can add the contours to the glyph */ - error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours ); - if ( error ) - goto Fail; - - /* reading the contours' endpoints & number of points */ - cont = gloader->current.outline.contours; - cont_limit = cont + n_contours; - - /* check space for contours array + instructions count */ - if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) - goto Invalid_Outline; - - prev_cont = FT_NEXT_SHORT( p ); - - if ( n_contours > 0 ) - cont[0] = prev_cont; - - if ( prev_cont < 0 ) - goto Invalid_Outline; - - for ( cont++; cont < cont_limit; cont++ ) - { - cont[0] = FT_NEXT_SHORT( p ); - if ( cont[0] <= prev_cont ) - { - /* unordered contours: this is invalid */ - goto Invalid_Outline; - } - prev_cont = cont[0]; - } - - n_points = 0; - if ( n_contours > 0 ) - { - n_points = cont[-1] + 1; - if ( n_points < 0 ) - goto Invalid_Outline; - } - - /* note that we will add four phantom points later */ - error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 ); - if ( error ) - goto Fail; - - /* reading the bytecode instructions */ - load->glyph->control_len = 0; - load->glyph->control_data = 0; - - if ( p + 2 > limit ) - goto Invalid_Outline; - - n_ins = FT_NEXT_USHORT( p ); - - FT_TRACE5(( " Instructions size: %u\n", n_ins )); - - if ( n_ins > face->max_profile.maxSizeOfInstructions ) - { - FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", - n_ins )); - error = FT_THROW( Too_Many_Hints ); - goto Fail; - } - - if ( ( limit - p ) < n_ins ) - { - FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); - error = FT_THROW( Too_Many_Hints ); - goto Fail; - } - -#ifdef TT_USE_BYTECODE_INTERPRETER - - if ( IS_HINTED( load->load_flags ) ) - { - load->glyph->control_len = n_ins; - load->glyph->control_data = load->exec->glyphIns; - - FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); - } - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - p += n_ins; - - outline = &gloader->current.outline; - - /* reading the point tags */ - flag = (FT_Byte*)outline->tags; - flag_limit = flag + n_points; - - FT_ASSERT( flag != NULL ); - - while ( flag < flag_limit ) - { - if ( p + 1 > limit ) - goto Invalid_Outline; - - *flag++ = c = FT_NEXT_BYTE( p ); - if ( c & 8 ) - { - if ( p + 1 > limit ) - goto Invalid_Outline; - - count = FT_NEXT_BYTE( p ); - if ( flag + (FT_Int)count > flag_limit ) - goto Invalid_Outline; - - for ( ; count > 0; count-- ) - *flag++ = c; - } - } - - /* reading the X coordinates */ - - vec = outline->points; - vec_limit = vec + n_points; - flag = (FT_Byte*)outline->tags; - x = 0; - - if ( p + xy_size > limit ) - goto Invalid_Outline; - - for ( ; vec < vec_limit; vec++, flag++ ) - { - FT_Pos y = 0; - FT_Byte f = *flag; - - - if ( f & 2 ) - { - if ( p + 1 > limit ) - goto Invalid_Outline; - - y = (FT_Pos)FT_NEXT_BYTE( p ); - if ( ( f & 16 ) == 0 ) - y = -y; - } - else if ( ( f & 16 ) == 0 ) - { - if ( p + 2 > limit ) - goto Invalid_Outline; - - y = (FT_Pos)FT_NEXT_SHORT( p ); - } - - x += y; - vec->x = x; - /* the cast is for stupid compilers */ - *flag = (FT_Byte)( f & ~( 2 | 16 ) ); - } - - /* reading the Y coordinates */ - - vec = gloader->current.outline.points; - vec_limit = vec + n_points; - flag = (FT_Byte*)outline->tags; - x = 0; - - for ( ; vec < vec_limit; vec++, flag++ ) - { - FT_Pos y = 0; - FT_Byte f = *flag; - - - if ( f & 4 ) - { - if ( p + 1 > limit ) - goto Invalid_Outline; - - y = (FT_Pos)FT_NEXT_BYTE( p ); - if ( ( f & 32 ) == 0 ) - y = -y; - } - else if ( ( f & 32 ) == 0 ) - { - if ( p + 2 > limit ) - goto Invalid_Outline; - - y = (FT_Pos)FT_NEXT_SHORT( p ); - } - - x += y; - vec->y = x; - /* the cast is for stupid compilers */ - *flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); - } - - outline->n_points = (FT_UShort)n_points; - outline->n_contours = (FT_Short) n_contours; - - load->cursor = p; - - Fail: - return error; - - Invalid_Outline: - error = FT_THROW( Invalid_Outline ); - goto Fail; - } - - - FT_CALLBACK_DEF( FT_Error ) - TT_Load_Composite_Glyph( TT_Loader loader ) - { - FT_Error error; - FT_Byte* p = loader->cursor; - FT_Byte* limit = loader->limit; - FT_GlyphLoader gloader = loader->gloader; - FT_SubGlyph subglyph; - FT_UInt num_subglyphs; - - - num_subglyphs = 0; - - do - { - FT_Fixed xx, xy, yy, yx; - FT_UInt count; - - - /* check that we can load a new subglyph */ - error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 ); - if ( error ) - goto Fail; - - /* check space */ - if ( p + 4 > limit ) - goto Invalid_Composite; - - subglyph = gloader->current.subglyphs + num_subglyphs; - - subglyph->arg1 = subglyph->arg2 = 0; - - subglyph->flags = FT_NEXT_USHORT( p ); - subglyph->index = FT_NEXT_USHORT( p ); - - /* check space */ - count = 2; - if ( subglyph->flags & ARGS_ARE_WORDS ) - count += 2; - if ( subglyph->flags & WE_HAVE_A_SCALE ) - count += 2; - else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) - count += 4; - else if ( subglyph->flags & WE_HAVE_A_2X2 ) - count += 8; - - if ( p + count > limit ) - goto Invalid_Composite; - - /* read arguments */ - if ( subglyph->flags & ARGS_ARE_WORDS ) - { - subglyph->arg1 = FT_NEXT_SHORT( p ); - subglyph->arg2 = FT_NEXT_SHORT( p ); - } - else - { - subglyph->arg1 = FT_NEXT_CHAR( p ); - subglyph->arg2 = FT_NEXT_CHAR( p ); - } - - /* read transform */ - xx = yy = 0x10000L; - xy = yx = 0; - - if ( subglyph->flags & WE_HAVE_A_SCALE ) - { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = xx; - } - else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) - { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - } - else if ( subglyph->flags & WE_HAVE_A_2X2 ) - { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - } - - subglyph->transform.xx = xx; - subglyph->transform.xy = xy; - subglyph->transform.yx = yx; - subglyph->transform.yy = yy; - - num_subglyphs++; - - } while ( subglyph->flags & MORE_COMPONENTS ); - - gloader->current.num_subglyphs = num_subglyphs; - -#ifdef TT_USE_BYTECODE_INTERPRETER - - { - FT_Stream stream = loader->stream; - - - /* we must undo the FT_FRAME_ENTER in order to point */ - /* to the composite instructions, if we find some. */ - /* We will process them later. */ - /* */ - loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + - p - limit ); - } - -#endif - - loader->cursor = p; - - Fail: - return error; - - Invalid_Composite: - error = FT_THROW( Invalid_Composite ); - goto Fail; - } - - - FT_LOCAL_DEF( void ) - TT_Init_Glyph_Loading( TT_Face face ) - { - face->access_glyph_frame = TT_Access_Glyph_Frame; - face->read_glyph_header = TT_Load_Glyph_Header; - face->read_simple_glyph = TT_Load_Simple_Glyph; - face->read_composite_glyph = TT_Load_Composite_Glyph; - face->forget_glyph_frame = TT_Forget_Glyph_Frame; - } - - - static void - tt_prepare_zone( TT_GlyphZone zone, - FT_GlyphLoad load, - FT_UInt start_point, - FT_UInt start_contour ) - { - zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); - zone->n_contours = (FT_Short) ( load->outline.n_contours - - start_contour ); - zone->org = load->extra_points + start_point; - zone->cur = load->outline.points + start_point; - zone->orus = load->extra_points2 + start_point; - zone->tags = (FT_Byte*)load->outline.tags + start_point; - zone->contours = (FT_UShort*)load->outline.contours + start_contour; - zone->first_point = (FT_UShort)start_point; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Hint_Glyph */ - /* */ - /* <Description> */ - /* Hint the glyph using the zone prepared by the caller. Note that */ - /* the zone is supposed to include four phantom points. */ - /* */ - static FT_Error - TT_Hint_Glyph( TT_Loader loader, - FT_Bool is_composite ) - { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Face face = (TT_Face)loader->face; - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); -#endif - - TT_GlyphZone zone = &loader->zone; - FT_Pos origin; - -#ifdef TT_USE_BYTECODE_INTERPRETER - FT_UInt n_ins; -#else - FT_UNUSED( is_composite ); -#endif - - -#ifdef TT_USE_BYTECODE_INTERPRETER - if ( loader->glyph->control_len > 0xFFFFL ) - { - FT_TRACE1(( "TT_Hint_Glyph: too long instructions " )); - FT_TRACE1(( "(0x%lx byte) is truncated\n", - loader->glyph->control_len )); - } - n_ins = (FT_UInt)( loader->glyph->control_len ); -#endif - - origin = zone->cur[zone->n_points - 4].x; - origin = FT_PIX_ROUND( origin ) - origin; - if ( origin ) - translate_array( zone->n_points, zone->cur, origin, 0 ); - -#ifdef TT_USE_BYTECODE_INTERPRETER - /* save original point position in org */ - if ( n_ins > 0 ) - FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); - - /* Reset graphics state. */ - loader->exec->GS = ((TT_Size)loader->size)->GS; - - /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ - /* completely refer to the (already) hinted subglyphs. */ - if ( is_composite ) - { - loader->exec->metrics.x_scale = 1 << 16; - loader->exec->metrics.y_scale = 1 << 16; - - FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); - } - else - { - loader->exec->metrics.x_scale = - ((TT_Size)loader->size)->metrics.x_scale; - loader->exec->metrics.y_scale = - ((TT_Size)loader->size)->metrics.y_scale; - } -#endif - - /* round pp2 and pp4 */ - zone->cur[zone->n_points - 3].x = - FT_PIX_ROUND( zone->cur[zone->n_points - 3].x ); - zone->cur[zone->n_points - 1].y = - FT_PIX_ROUND( zone->cur[zone->n_points - 1].y ); - -#ifdef TT_USE_BYTECODE_INTERPRETER - - if ( n_ins > 0 ) - { - FT_Bool debug; - FT_Error error; - - FT_GlyphLoader gloader = loader->gloader; - FT_Outline current_outline = gloader->current.outline; - - - error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, - loader->exec->glyphIns, n_ins ); - if ( error ) - return error; - - loader->exec->is_composite = is_composite; - loader->exec->pts = *zone; - - debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && - ((TT_Size)loader->size)->debug ); - - error = TT_Run_Context( loader->exec, debug ); - if ( error && loader->exec->pedantic_hinting ) - return error; - - /* store drop-out mode in bits 5-7; set bit 2 also as a marker */ - current_outline.tags[0] |= - ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; - } - -#endif - - /* save glyph phantom points */ - if ( !loader->preserve_pps ) - { - loader->pp1 = zone->cur[zone->n_points - 4]; - loader->pp2 = zone->cur[zone->n_points - 3]; - loader->pp3 = zone->cur[zone->n_points - 2]; - loader->pp4 = zone->cur[zone->n_points - 1]; - } - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) - FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 ); - - else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) - FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Process_Simple_Glyph */ - /* */ - /* <Description> */ - /* Once a simple glyph has been loaded, it needs to be processed. */ - /* Usually, this means scaling and hinting through bytecode */ - /* interpretation. */ - /* */ - static FT_Error - TT_Process_Simple_Glyph( TT_Loader loader ) - { - FT_GlyphLoader gloader = loader->gloader; - FT_Error error = FT_Err_Ok; - FT_Outline* outline; - FT_Int n_points; - - - outline = &gloader->current.outline; - n_points = outline->n_points; - - /* set phantom points */ - - outline->points[n_points ] = loader->pp1; - outline->points[n_points + 1] = loader->pp2; - outline->points[n_points + 2] = loader->pp3; - outline->points[n_points + 3] = loader->pp4; - - outline->tags[n_points ] = 0; - outline->tags[n_points + 1] = 0; - outline->tags[n_points + 2] = 0; - outline->tags[n_points + 3] = 0; - - n_points += 4; - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - - if ( ((TT_Face)loader->face)->doblend ) - { - /* Deltas apply to the unscaled data. */ - FT_Vector* deltas; - FT_Memory memory = loader->face->memory; - FT_Int i; - - - error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), - loader->glyph_index, - &deltas, - n_points ); - if ( error ) - return error; - - for ( i = 0; i < n_points; ++i ) - { - outline->points[i].x += deltas[i].x; - outline->points[i].y += deltas[i].y; - } - - FT_FREE( deltas ); - } - -#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ - - if ( IS_HINTED( loader->load_flags ) ) - { - tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); - - FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, - loader->zone.n_points + 4 ); - } - - { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Face face = (TT_Face)loader->face; - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); - - FT_String* family = face->root.family_name; - FT_Int ppem = loader->size->metrics.x_ppem; - FT_String* style = face->root.style_name; - FT_Int x_scale_factor = 1000; -#endif - - FT_Vector* vec = outline->points; - FT_Vector* limit = outline->points + n_points; - - FT_Fixed x_scale = 0; /* pacify compiler */ - FT_Fixed y_scale = 0; - - FT_Bool do_scale = FALSE; - - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - /* scale, but only if enabled and only if TT hinting is being used */ - if ( IS_HINTED( loader->load_flags ) ) - x_scale_factor = sph_test_tweak_x_scaling( face, - family, - ppem, - style, - loader->glyph_index ); - /* scale the glyph */ - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || - x_scale_factor != 1000 ) - { - x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale, - x_scale_factor, 1000 ); - y_scale = ((TT_Size)loader->size)->metrics.y_scale; - - /* compensate for any scaling by de/emboldening; */ - /* the amount was determined via experimentation */ - if ( x_scale_factor != 1000 && ppem > 11 ) - FT_Outline_EmboldenXY( outline, - FT_MulFix( 1280 * ppem, - 1000 - x_scale_factor ), - 0 ); - do_scale = TRUE; - } - } - else - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - { - /* scale the glyph */ - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - x_scale = ((TT_Size)loader->size)->metrics.x_scale; - y_scale = ((TT_Size)loader->size)->metrics.y_scale; - - do_scale = TRUE; - } - } - - if ( do_scale ) - { - for ( ; vec < limit; vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - loader->pp1 = outline->points[n_points - 4]; - loader->pp2 = outline->points[n_points - 3]; - loader->pp3 = outline->points[n_points - 2]; - loader->pp4 = outline->points[n_points - 1]; - } - } - - if ( IS_HINTED( loader->load_flags ) ) - { - loader->zone.n_points += 4; - - error = TT_Hint_Glyph( loader, 0 ); - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Process_Composite_Component */ - /* */ - /* <Description> */ - /* Once a composite component has been loaded, it needs to be */ - /* processed. Usually, this means transforming and translating. */ - /* */ - static FT_Error - TT_Process_Composite_Component( TT_Loader loader, - FT_SubGlyph subglyph, - FT_UInt start_point, - FT_UInt num_base_points ) - { - FT_GlyphLoader gloader = loader->gloader; - FT_Vector* base_vec = gloader->base.outline.points; - FT_UInt num_points = gloader->base.outline.n_points; - FT_Bool have_scale; - FT_Pos x, y; - - - have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE | - WE_HAVE_AN_XY_SCALE | - WE_HAVE_A_2X2 ) ); - - /* perform the transform required for this subglyph */ - if ( have_scale ) - { - FT_UInt i; - - - for ( i = num_base_points; i < num_points; i++ ) - FT_Vector_Transform( base_vec + i, &subglyph->transform ); - } - - /* get offset */ - if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) - { - FT_UInt k = subglyph->arg1; - FT_UInt l = subglyph->arg2; - FT_Vector* p1; - FT_Vector* p2; - - - /* match l-th point of the newly loaded component to the k-th point */ - /* of the previously loaded components. */ - - /* change to the point numbers used by our outline */ - k += start_point; - l += num_base_points; - if ( k >= num_base_points || - l >= num_points ) - return FT_THROW( Invalid_Composite ); - - p1 = gloader->base.outline.points + k; - p2 = gloader->base.outline.points + l; - - x = p1->x - p2->x; - y = p1->y - p2->y; - } - else - { - x = subglyph->arg1; - y = subglyph->arg2; - - if ( !x && !y ) - return FT_Err_Ok; - - /* Use a default value dependent on */ - /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */ - /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */ - - if ( have_scale && -#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) ) -#else - ( subglyph->flags & SCALED_COMPONENT_OFFSET ) ) -#endif - { - -#if 0 - - /*************************************************************************/ - /* */ - /* This algorithm is what Apple documents. But it doesn't work. */ - /* */ - int a = subglyph->transform.xx > 0 ? subglyph->transform.xx - : -subglyph->transform.xx; - int b = subglyph->transform.yx > 0 ? subglyph->transform.yx - : -subglyph->transform.yx; - int c = subglyph->transform.xy > 0 ? subglyph->transform.xy - : -subglyph->transform.xy; - int d = subglyph->transform.yy > 0 ? subglyph->transform.yy - : -subglyph->transform.yy; - int m = a > b ? a : b; - int n = c > d ? c : d; - - - if ( a - b <= 33 && a - b >= -33 ) - m *= 2; - if ( c - d <= 33 && c - d >= -33 ) - n *= 2; - x = FT_MulFix( x, m ); - y = FT_MulFix( y, n ); - -#else /* 0 */ - - /*************************************************************************/ - /* */ - /* This algorithm is a guess and works much better than the above. */ - /* */ - FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx, - subglyph->transform.xy ); - FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy, - subglyph->transform.yx ); - - - x = FT_MulFix( x, mac_xscale ); - y = FT_MulFix( y, mac_yscale ); - -#endif /* 0 */ - - } - - if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) - { - FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; - FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; - - - x = FT_MulFix( x, x_scale ); - y = FT_MulFix( y, y_scale ); - - if ( subglyph->flags & ROUND_XY_TO_GRID ) - { - x = FT_PIX_ROUND( x ); - y = FT_PIX_ROUND( y ); - } - } - } - - if ( x || y ) - translate_array( num_points - num_base_points, - base_vec + num_base_points, - x, y ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Process_Composite_Glyph */ - /* */ - /* <Description> */ - /* This is slightly different from TT_Process_Simple_Glyph, in that */ - /* its sole purpose is to hint the glyph. Thus this function is */ - /* only available when bytecode interpreter is enabled. */ - /* */ - static FT_Error - TT_Process_Composite_Glyph( TT_Loader loader, - FT_UInt start_point, - FT_UInt start_contour ) - { - FT_Error error; - FT_Outline* outline; - FT_UInt i; - - - outline = &loader->gloader->base.outline; - - /* make room for phantom points */ - error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader, - outline->n_points + 4, - 0 ); - if ( error ) - return error; - - outline->points[outline->n_points ] = loader->pp1; - outline->points[outline->n_points + 1] = loader->pp2; - outline->points[outline->n_points + 2] = loader->pp3; - outline->points[outline->n_points + 3] = loader->pp4; - - outline->tags[outline->n_points ] = 0; - outline->tags[outline->n_points + 1] = 0; - outline->tags[outline->n_points + 2] = 0; - outline->tags[outline->n_points + 3] = 0; - -#ifdef TT_USE_BYTECODE_INTERPRETER - - { - FT_Stream stream = loader->stream; - FT_UShort n_ins, max_ins; - FT_ULong tmp; - - - /* TT_Load_Composite_Glyph only gives us the offset of instructions */ - /* so we read them here */ - if ( FT_STREAM_SEEK( loader->ins_pos ) || - FT_READ_USHORT( n_ins ) ) - return error; - - FT_TRACE5(( " Instructions size = %d\n", n_ins )); - - /* check it */ - max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions; - if ( n_ins > max_ins ) - { - /* acroread ignores this field, so we only do a rough safety check */ - if ( (FT_Int)n_ins > loader->byte_len ) - { - FT_TRACE1(( "TT_Process_Composite_Glyph: " - "too many instructions (%d) for glyph with length %d\n", - n_ins, loader->byte_len )); - return FT_THROW( Too_Many_Hints ); - } - - tmp = loader->exec->glyphSize; - error = Update_Max( loader->exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void*)&loader->exec->glyphIns, - n_ins ); - loader->exec->glyphSize = (FT_UShort)tmp; - if ( error ) - return error; - } - else if ( n_ins == 0 ) - return FT_Err_Ok; - - if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) ) - return error; - - loader->glyph->control_data = loader->exec->glyphIns; - loader->glyph->control_len = n_ins; - } - -#endif - - tt_prepare_zone( &loader->zone, &loader->gloader->base, - start_point, start_contour ); - - /* Some points are likely touched during execution of */ - /* instructions on components. So let's untouch them. */ - for ( i = start_point; i < loader->zone.n_points; i++ ) - loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; - - loader->zone.n_points += 4; - - return TT_Hint_Glyph( loader, 1 ); - } - - - /* Calculate the four phantom points. */ - /* The first two stand for horizontal origin and advance. */ - /* The last two stand for vertical origin and advance. */ -#define TT_LOADER_SET_PP( loader ) \ - do { \ - (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ - (loader)->pp1.y = 0; \ - (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ - (loader)->pp2.y = 0; \ - (loader)->pp3.x = 0; \ - (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax; \ - (loader)->pp4.x = 0; \ - (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ - } while ( 0 ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* load_truetype_glyph */ - /* */ - /* <Description> */ - /* Loads a given truetype glyph. Handles composites and uses a */ - /* TT_Loader object. */ - /* */ - static FT_Error - load_truetype_glyph( TT_Loader loader, - FT_UInt glyph_index, - FT_UInt recurse_count, - FT_Bool header_only ) - { - FT_Error error = FT_Err_Ok; - FT_Fixed x_scale, y_scale; - FT_ULong offset; - TT_Face face = (TT_Face)loader->face; - FT_GlyphLoader gloader = loader->gloader; - FT_Bool opened_frame = 0; - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Vector* deltas = NULL; -#endif - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - FT_StreamRec inc_stream; - FT_Data glyph_data; - FT_Bool glyph_data_loaded = 0; -#endif - - - /* some fonts have an incorrect value of `maxComponentDepth', */ - /* thus we allow depth 1 to catch the majority of them */ - if ( recurse_count > 1 && - recurse_count > face->max_profile.maxComponentDepth ) - { - error = FT_THROW( Invalid_Composite ); - goto Exit; - } - - /* check glyph index */ - if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) - { - error = FT_THROW( Invalid_Glyph_Index ); - goto Exit; - } - - loader->glyph_index = glyph_index; - - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - x_scale = ((TT_Size)loader->size)->metrics.x_scale; - y_scale = ((TT_Size)loader->size)->metrics.y_scale; - } - else - { - x_scale = 0x10000L; - y_scale = 0x10000L; - } - - tt_get_metrics( loader, glyph_index ); - - /* Set `offset' to the start of the glyph relative to the start of */ - /* the `glyf' table, and `byte_len' to the length of the glyph in */ - /* bytes. */ - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* If we are loading glyph data via the incremental interface, set */ - /* the loader stream to a memory stream reading the data returned */ - /* by the interface. */ - if ( face->root.internal->incremental_interface ) - { - error = face->root.internal->incremental_interface->funcs->get_glyph_data( - face->root.internal->incremental_interface->object, - glyph_index, &glyph_data ); - if ( error ) - goto Exit; - - glyph_data_loaded = 1; - offset = 0; - loader->byte_len = glyph_data.length; - - FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); - FT_Stream_OpenMemory( &inc_stream, - glyph_data.pointer, glyph_data.length ); - - loader->stream = &inc_stream; - } - else - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - offset = tt_face_get_location( face, glyph_index, - (FT_UInt*)&loader->byte_len ); - - if ( loader->byte_len > 0 ) - { -#ifdef FT_CONFIG_OPTION_INCREMENTAL - /* for the incremental interface, `glyf_offset' is always zero */ - if ( !loader->glyf_offset && - !face->root.internal->incremental_interface ) -#else - if ( !loader->glyf_offset ) -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - { - FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - error = face->access_glyph_frame( loader, glyph_index, - loader->glyf_offset + offset, - loader->byte_len ); - if ( error ) - goto Exit; - - opened_frame = 1; - - /* read glyph header first */ - error = face->read_glyph_header( loader ); - if ( error || header_only ) - goto Exit; - } - - if ( loader->byte_len == 0 || loader->n_contours == 0 ) - { - loader->bbox.xMin = 0; - loader->bbox.xMax = 0; - loader->bbox.yMin = 0; - loader->bbox.yMax = 0; - - if ( header_only ) - goto Exit; - - /* must initialize points before (possibly) overriding */ - /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - tt_get_metrics_incr_overrides( loader, glyph_index ); -#endif - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - - if ( ((TT_Face)(loader->face))->doblend ) - { - /* this must be done before scaling */ - FT_Memory memory = loader->face->memory; - - - error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), - glyph_index, &deltas, 4 ); - if ( error ) - goto Exit; - - loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y; - loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y; - loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y; - loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y; - - FT_FREE( deltas ); - } - -#endif - - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); - loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); - loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); - loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); - } - - error = FT_Err_Ok; - goto Exit; - } - - /* must initialize points before (possibly) overriding */ - /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - tt_get_metrics_incr_overrides( loader, glyph_index ); -#endif - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - /* if it is a simple glyph, load it */ - - if ( loader->n_contours > 0 ) - { - error = face->read_simple_glyph( loader ); - if ( error ) - goto Exit; - - /* all data have been read */ - face->forget_glyph_frame( loader ); - opened_frame = 0; - - error = TT_Process_Simple_Glyph( loader ); - if ( error ) - goto Exit; - - FT_GlyphLoader_Add( gloader ); - } - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - /* otherwise, load a composite! */ - else if ( loader->n_contours == -1 ) - { - FT_UInt start_point; - FT_UInt start_contour; - FT_ULong ins_pos; /* position of composite instructions, if any */ - - - start_point = gloader->base.outline.n_points; - start_contour = gloader->base.outline.n_contours; - - /* for each subglyph, read composite header */ - error = face->read_composite_glyph( loader ); - if ( error ) - goto Exit; - - /* store the offset of instructions */ - ins_pos = loader->ins_pos; - - /* all data we need are read */ - face->forget_glyph_frame( loader ); - opened_frame = 0; - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - - if ( face->doblend ) - { - FT_Int i, limit; - FT_SubGlyph subglyph; - FT_Memory memory = face->root.memory; - - - /* this provides additional offsets */ - /* for each component's translation */ - - if ( ( error = TT_Vary_Get_Glyph_Deltas( - face, - glyph_index, - &deltas, - gloader->current.num_subglyphs + 4 )) != 0 ) - goto Exit; - - subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; - limit = gloader->current.num_subglyphs; - - for ( i = 0; i < limit; ++i, ++subglyph ) - { - if ( subglyph->flags & ARGS_ARE_XY_VALUES ) - { - /* XXX: overflow check for subglyph->{arg1,arg2}. */ - /* deltas[i].{x,y} must be within signed 16-bit, */ - /* but the restriction of summed delta is not clear */ - subglyph->arg1 += (FT_Int16)deltas[i].x; - subglyph->arg2 += (FT_Int16)deltas[i].y; - } - } - - loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y; - loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y; - loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y; - loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y; - - FT_FREE( deltas ); - } - -#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ - - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); - loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); - loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); - loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); - } - - /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ - /* `as is' in the glyph slot (the client application will be */ - /* responsible for interpreting these data)... */ - if ( loader->load_flags & FT_LOAD_NO_RECURSE ) - { - FT_GlyphLoader_Add( gloader ); - loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE; - - goto Exit; - } - - /*********************************************************************/ - /*********************************************************************/ - /*********************************************************************/ - - { - FT_UInt n, num_base_points; - FT_SubGlyph subglyph = 0; - - FT_UInt num_points = start_point; - FT_UInt num_subglyphs = gloader->current.num_subglyphs; - FT_UInt num_base_subgs = gloader->base.num_subglyphs; - - FT_Stream old_stream = loader->stream; - FT_Int old_byte_len = loader->byte_len; - - - FT_GlyphLoader_Add( gloader ); - - /* read each subglyph independently */ - for ( n = 0; n < num_subglyphs; n++ ) - { - FT_Vector pp[4]; - - - /* Each time we call load_truetype_glyph in this loop, the */ - /* value of `gloader.base.subglyphs' can change due to table */ - /* reallocations. We thus need to recompute the subglyph */ - /* pointer on each iteration. */ - subglyph = gloader->base.subglyphs + num_base_subgs + n; - - pp[0] = loader->pp1; - pp[1] = loader->pp2; - pp[2] = loader->pp3; - pp[3] = loader->pp4; - - num_base_points = gloader->base.outline.n_points; - - error = load_truetype_glyph( loader, subglyph->index, - recurse_count + 1, FALSE ); - if ( error ) - goto Exit; - - /* restore subglyph pointer */ - subglyph = gloader->base.subglyphs + num_base_subgs + n; - - if ( !( subglyph->flags & USE_MY_METRICS ) ) - { - loader->pp1 = pp[0]; - loader->pp2 = pp[1]; - loader->pp3 = pp[2]; - loader->pp4 = pp[3]; - } - - num_points = gloader->base.outline.n_points; - - if ( num_points == num_base_points ) - continue; - - /* gloader->base.outline consists of three parts: */ - /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */ - /* */ - /* (1): exists from the beginning */ - /* (2): components that have been loaded so far */ - /* (3): the newly loaded component */ - TT_Process_Composite_Component( loader, subglyph, start_point, - num_base_points ); - } - - loader->stream = old_stream; - loader->byte_len = old_byte_len; - - /* process the glyph */ - loader->ins_pos = ins_pos; - if ( IS_HINTED( loader->load_flags ) && - -#ifdef TT_USE_BYTECODE_INTERPRETER - - subglyph->flags & WE_HAVE_INSTR && - -#endif - - num_points > start_point ) - TT_Process_Composite_Glyph( loader, start_point, start_contour ); - - } - } - else - { - /* invalid composite count (negative but not -1) */ - error = FT_THROW( Invalid_Outline ); - goto Exit; - } - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - Exit: - - if ( opened_frame ) - face->forget_glyph_frame( loader ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - if ( glyph_data_loaded ) - face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object, - &glyph_data ); - -#endif - - return error; - } - - - static FT_Error - compute_glyph_metrics( TT_Loader loader, - FT_UInt glyph_index ) - { - TT_Face face = (TT_Face)loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); -#endif - - FT_BBox bbox; - FT_Fixed y_scale; - TT_GlyphSlot glyph = loader->glyph; - TT_Size size = (TT_Size)loader->size; - - - y_scale = 0x10000L; - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - y_scale = size->root.metrics.y_scale; - - if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) - FT_Outline_Get_CBox( &glyph->outline, &bbox ); - else - bbox = loader->bbox; - - /* get the device-independent horizontal advance; it is scaled later */ - /* by the base layer. */ - glyph->linearHoriAdvance = loader->linear; - - glyph->metrics.horiBearingX = bbox.xMin; - glyph->metrics.horiBearingY = bbox.yMax; - glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - - /* adjust advance width to the value contained in the hdmx table */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) ) - { - FT_Byte* widthp; - - - widthp = tt_face_get_device_metrics( face, - size->root.metrics.x_ppem, - glyph_index ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - FT_Bool ignore_x_mode; - - - ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) != - FT_RENDER_MODE_MONO ); - - if ( widthp && - ( ( ignore_x_mode && loader->exec->compatible_widths ) || - !ignore_x_mode || - SPH_OPTION_BITMAP_WIDTHS ) ) - glyph->metrics.horiAdvance = *widthp << 6; - } - else - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - { - if ( widthp ) - glyph->metrics.horiAdvance = *widthp << 6; - } - } - - /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; - - /* Now take care of vertical metrics. In the case where there is */ - /* no vertical information within the font (relatively common), */ - /* create some metrics manually */ - { - FT_Pos top; /* scaled vertical top side bearing */ - FT_Pos advance; /* scaled vertical advance height */ - - - /* Get the unscaled top bearing and advance height. */ - if ( face->vertical_info && - face->vertical.number_Of_VMetrics > 0 ) - { - top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax, - y_scale ); - - if ( loader->pp3.y <= loader->pp4.y ) - advance = 0; - else - advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y, - y_scale ); - } - else - { - FT_Pos height; - - - /* XXX Compute top side bearing and advance height in */ - /* Get_VMetrics instead of here. */ - - /* NOTE: The OS/2 values are the only `portable' ones, */ - /* which is why we use them, if there is an OS/2 */ - /* table in the font. Otherwise, we use the */ - /* values defined in the horizontal header. */ - - height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin, - y_scale ); - if ( face->os2.version != 0xFFFFU ) - advance = (FT_Pos)( face->os2.sTypoAscender - - face->os2.sTypoDescender ); - else - advance = (FT_Pos)( face->horizontal.Ascender - - face->horizontal.Descender ); - - top = ( advance - height ) / 2; - } - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - { - FT_Incremental_InterfaceRec* incr; - FT_Incremental_MetricsRec metrics; - FT_Error error; - - - incr = face->root.internal->incremental_interface; - - /* If this is an incrementally loaded font see if there are */ - /* overriding metrics for this glyph. */ - if ( incr && incr->funcs->get_glyph_metrics ) - { - metrics.bearing_x = 0; - metrics.bearing_y = top; - metrics.advance = advance; - - error = incr->funcs->get_glyph_metrics( incr->object, - glyph_index, - TRUE, - &metrics ); - if ( error ) - return error; - - top = metrics.bearing_y; - advance = metrics.advance; - } - } - - /* GWW: Do vertical metrics get loaded incrementally too? */ - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - glyph->linearVertAdvance = advance; - - /* scale the metrics */ - if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) - { - top = FT_MulFix( top, y_scale ); - advance = FT_MulFix( advance, y_scale ); - } - - /* XXX: for now, we have no better algorithm for the lsb, but it */ - /* should work fine. */ - /* */ - glyph->metrics.vertBearingX = glyph->metrics.horiBearingX - - glyph->metrics.horiAdvance / 2; - glyph->metrics.vertBearingY = top; - glyph->metrics.vertAdvance = advance; - } - - return 0; - } - - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - static FT_Error - load_sbit_image( TT_Size size, - TT_GlyphSlot glyph, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - TT_Face face; - SFNT_Service sfnt; - FT_Stream stream; - FT_Error error; - TT_SBit_MetricsRec metrics; - - - face = (TT_Face)glyph->face; - sfnt = (SFNT_Service)face->sfnt; - stream = face->root.stream; - - error = sfnt->load_sbit_image( face, - size->strike_index, - glyph_index, - (FT_Int)load_flags, - stream, - &glyph->bitmap, - &metrics ); - if ( !error ) - { - glyph->outline.n_points = 0; - glyph->outline.n_contours = 0; - - glyph->metrics.width = (FT_Pos)metrics.width << 6; - glyph->metrics.height = (FT_Pos)metrics.height << 6; - - glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; - glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; - glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; - - glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; - glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; - glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; - - glyph->format = FT_GLYPH_FORMAT_BITMAP; - - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - glyph->bitmap_left = metrics.vertBearingX; - glyph->bitmap_top = metrics.vertBearingY; - } - else - { - glyph->bitmap_left = metrics.horiBearingX; - glyph->bitmap_top = metrics.horiBearingY; - } - } - - return error; - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - - static FT_Error - tt_loader_init( TT_Loader loader, - TT_Size size, - TT_GlyphSlot glyph, - FT_Int32 load_flags, - FT_Bool glyf_table_only ) - { - TT_Face face; - FT_Stream stream; -#ifdef TT_USE_BYTECODE_INTERPRETER - FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); -#endif - - - face = (TT_Face)glyph->face; - stream = face->root.stream; - - FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); - -#ifdef TT_USE_BYTECODE_INTERPRETER - - /* load execution context */ - if ( IS_HINTED( load_flags ) && !glyf_table_only ) - { - TT_ExecContext exec; - FT_Bool grayscale; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); - - FT_Bool subpixel_hinting = FALSE; - FT_Bool grayscale_hinting = TRUE; - -#if 0 - /* not used yet */ - FT_Bool compatible_widths; - FT_Bool symmetrical_smoothing; - FT_Bool bgr; - FT_Bool subpixel_positioned; -#endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - FT_Bool reexecute = FALSE; - - - if ( !size->cvt_ready ) - { - FT_Error error = tt_size_ready_bytecode( size, pedantic ); - - - if ( error ) - return error; - } - - /* query new execution context */ - exec = size->debug ? size->context - : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; - if ( !exec ) - return FT_THROW( Could_Not_Find_Context ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) - != FT_RENDER_MODE_MONO ) && - SPH_OPTION_SET_SUBPIXEL ); - - if ( subpixel_hinting ) - grayscale = grayscale_hinting = FALSE; - else if ( SPH_OPTION_SET_GRAYSCALE ) - { - grayscale = grayscale_hinting = TRUE; - subpixel_hinting = FALSE; - } - else - grayscale = grayscale_hinting = FALSE; - - if ( FT_IS_TRICKY( glyph->face ) ) - subpixel_hinting = grayscale_hinting = FALSE; - - exec->ignore_x_mode = subpixel_hinting || grayscale_hinting; - exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) - exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - -#if 1 - exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; - exec->symmetrical_smoothing = FALSE; - exec->bgr = FALSE; - exec->subpixel_positioned = TRUE; -#else /* 0 */ - exec->compatible_widths = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_COMPATIBLE_WIDTHS ); - exec->symmetrical_smoothing = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_SYMMETRICAL_SMOOTHING ); - exec->bgr = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_BGR ); - exec->subpixel_positioned = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_SUBPIXEL_POSITIONED ); -#endif /* 0 */ - - } - else - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - { - grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - FT_RENDER_MODE_MONO ); - } - - TT_Load_Context( exec, face, size ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - /* a change from mono to subpixel rendering (and vice versa) */ - /* requires a re-execution of the CVT program */ - if ( subpixel_hinting != exec->subpixel_hinting ) - { - FT_TRACE4(( "tt_loader_init: subpixel hinting change," - " re-executing `prep' table\n" )); - - exec->subpixel_hinting = subpixel_hinting; - reexecute = TRUE; - } - - /* a change from mono to grayscale rendering (and vice versa) */ - /* requires a re-execution of the CVT program */ - if ( grayscale != exec->grayscale_hinting ) - { - FT_TRACE4(( "tt_loader_init: grayscale hinting change," - " re-executing `prep' table\n" )); - - exec->grayscale_hinting = grayscale_hinting; - reexecute = TRUE; - } - } - else - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - { - /* a change from mono to grayscale rendering (and vice versa) */ - /* requires a re-execution of the CVT program */ - if ( grayscale != exec->grayscale ) - { - FT_TRACE4(( "tt_loader_init: grayscale change," - " re-executing `prep' table\n" )); - - exec->grayscale = grayscale; - reexecute = TRUE; - } - } - - if ( reexecute ) - { - FT_UInt i; - - - for ( i = 0; i < size->cvt_size; i++ ) - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - tt_size_run_prep( size, pedantic ); - } - - /* see whether the cvt program has disabled hinting */ - if ( exec->GS.instruct_control & 1 ) - load_flags |= FT_LOAD_NO_HINTING; - - /* load default graphics state -- if needed */ - if ( exec->GS.instruct_control & 2 ) - exec->GS = tt_default_graphics_state; - - exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); - loader->exec = exec; - loader->instructions = exec->glyphIns; - } - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - /* seek to the beginning of the glyph table -- for Type 42 fonts */ - /* the table might be accessed from a Postscript stream or something */ - /* else... */ - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - if ( face->root.internal->incremental_interface ) - loader->glyf_offset = 0; - else - -#endif - - { - FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); - - - if ( FT_ERR_EQ( error, Table_Missing ) ) - loader->glyf_offset = 0; - else if ( error ) - { - FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); - return error; - } - else - loader->glyf_offset = FT_STREAM_POS(); - } - - /* get face's glyph loader */ - if ( !glyf_table_only ) - { - FT_GlyphLoader gloader = glyph->internal->loader; - - - FT_GlyphLoader_Rewind( gloader ); - loader->gloader = gloader; - } - - loader->load_flags = load_flags; - - loader->face = (FT_Face)face; - loader->size = (FT_Size)size; - loader->glyph = (FT_GlyphSlot)glyph; - loader->stream = stream; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Load_Glyph */ - /* */ - /* <Description> */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size. */ - /* */ - /* <Input> */ - /* glyph :: A handle to a target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled/loaded. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Load_Glyph( TT_Size size, - TT_GlyphSlot glyph, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - FT_Error error; - TT_LoaderRec loader; - - - error = FT_Err_Ok; - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* try to load embedded bitmap if any */ - /* */ - /* XXX: The convention should be emphasized in */ - /* the documents because it can be confusing. */ - if ( size->strike_index != 0xFFFFFFFFUL && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) - { - error = load_sbit_image( size, glyph, glyph_index, load_flags ); - if ( !error ) - { - if ( FT_IS_SCALABLE( glyph->face ) ) - { - /* for the bbox we need the header only */ - (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); - (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); - glyph->linearHoriAdvance = loader.linear; - glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - - loader.vadvance; - - /* sanity check: if `horiAdvance' in the sbit metric */ - /* structure isn't set, use `linearHoriAdvance' */ - if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance ) - glyph->metrics.horiAdvance = - FT_MulFix( glyph->linearHoriAdvance, - size->root.metrics.x_scale ); - } - - return FT_Err_Ok; - } - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */ - if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid ) - return FT_THROW( Invalid_Size_Handle ); - - if ( load_flags & FT_LOAD_SBITS_ONLY ) - return FT_THROW( Invalid_Argument ); - - error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); - if ( error ) - return error; - - glyph->format = FT_GLYPH_FORMAT_OUTLINE; - glyph->num_subglyphs = 0; - glyph->outline.flags = 0; - - /* main loading loop */ - error = load_truetype_glyph( &loader, glyph_index, 0, FALSE ); - if ( !error ) - { - if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE ) - { - glyph->num_subglyphs = loader.gloader->base.num_subglyphs; - glyph->subglyphs = loader.gloader->base.subglyphs; - } - else - { - glyph->outline = loader.gloader->base.outline; - glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS; - - /* Translate array so that (0,0) is the glyph's origin. Note */ - /* that this behaviour is independent on the value of bit 1 of */ - /* the `flags' field in the `head' table -- at least major */ - /* applications like Acroread indicate that. */ - if ( loader.pp1.x ) - FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 ); - } - -#ifdef TT_USE_BYTECODE_INTERPRETER - - if ( IS_HINTED( load_flags ) ) - { - if ( loader.exec->GS.scan_control ) - { - /* convert scan conversion mode to FT_OUTLINE_XXX flags */ - switch ( loader.exec->GS.scan_type ) - { - case 0: /* simple drop-outs including stubs */ - glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS; - break; - case 1: /* simple drop-outs excluding stubs */ - /* nothing; it's the default rendering mode */ - break; - case 4: /* smart drop-outs including stubs */ - glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS | - FT_OUTLINE_INCLUDE_STUBS; - break; - case 5: /* smart drop-outs excluding stubs */ - glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS; - break; - - default: /* no drop-out control */ - glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; - break; - } - } - else - glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; - } - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - compute_glyph_metrics( &loader, glyph_index ); - } - - /* Set the `high precision' bit flag. */ - /* This is _critical_ to get correct output for monochrome */ - /* TrueType glyphs at all sizes using the bytecode interpreter. */ - /* */ - if ( !( load_flags & FT_LOAD_NO_SCALE ) && - size->root.metrics.y_ppem < 24 ) - glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttgload.h b/drivers/freetype/freetype/src/truetype/ttgload.h deleted file mode 100644 index 05f75882dc..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttgload.h +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgload.h */ -/* */ -/* TrueType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2006, 2008, 2011 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 __TTGLOAD_H__ -#define __TTGLOAD_H__ - - -#include <ft2build.h> -#include "ttobjs.h" - -#ifdef TT_USE_BYTECODE_INTERPRETER -#include "ttinterp.h" -#endif - - -FT_BEGIN_HEADER - - - FT_LOCAL( void ) - TT_Init_Glyph_Loading( TT_Face face ); - - FT_LOCAL( void ) - TT_Get_HMetrics( TT_Face face, - FT_UInt idx, - FT_Short* lsb, - FT_UShort* aw ); - - FT_LOCAL( void ) - TT_Get_VMetrics( TT_Face face, - FT_UInt idx, - FT_Short* tsb, - FT_UShort* ah ); - - FT_LOCAL( FT_Error ) - TT_Load_Glyph( TT_Size size, - TT_GlyphSlot glyph, - FT_UInt glyph_index, - FT_Int32 load_flags ); - - -FT_END_HEADER - -#endif /* __TTGLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttgxvar.c b/drivers/freetype/freetype/src/truetype/ttgxvar.c deleted file mode 100644 index 7899d3671d..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttgxvar.c +++ /dev/null @@ -1,1532 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgxvar.c */ -/* */ -/* TrueType GX Font Variation loader */ -/* */ -/* Copyright 2004-2013 by */ -/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ - /* */ - /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ - /* */ - /* The documentation for `fvar' is inconsistent. At one point it says */ - /* that `countSizePairs' should be 3, at another point 2. It should */ - /* be 2. */ - /* */ - /* The documentation for `gvar' is not intelligible; `cvar' refers you */ - /* to `gvar' and is thus also incomprehensible. */ - /* */ - /* The documentation for `avar' appears correct, but Apple has no fonts */ - /* with an `avar' table, so it is hard to test. */ - /* */ - /* Many thanks to John Jenkins (at Apple) in figuring this out. */ - /* */ - /* */ - /* Apple's `kern' table has some references to tuple indices, but as */ - /* there is no indication where these indices are defined, nor how to */ - /* interpolate the kerning values (different tuples have different */ - /* classes) this issue is ignored. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_TAGS_H -#include FT_MULTIPLE_MASTERS_H - -#include "ttpload.h" -#include "ttgxvar.h" - -#include "tterrors.h" - - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - - -#define FT_Stream_FTell( stream ) \ - (FT_ULong)( (stream)->cursor - (stream)->base ) -#define FT_Stream_SeekSet( stream, off ) \ - ( (stream)->cursor = (stream)->base + (off) ) - - - /*************************************************************************/ - /* */ - /* 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_ttgxvar - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** Internal Routines *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It */ - /* indicates that there is a delta for every point without needing to */ - /* enumerate all of them. */ - /* */ - - /* ensure that value `0' has the same width as a pointer */ -#define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0 - - -#define GX_PT_POINTS_ARE_WORDS 0x80 -#define GX_PT_POINT_RUN_COUNT_MASK 0x7F - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_var_readpackedpoints */ - /* */ - /* <Description> */ - /* Read a set of points to which the following deltas will apply. */ - /* Points are packed with a run length encoding. */ - /* */ - /* <Input> */ - /* stream :: The data stream. */ - /* */ - /* <Output> */ - /* point_cnt :: The number of points read. A zero value means that */ - /* all points in the glyph will be affected, without */ - /* enumerating them individually. */ - /* */ - /* <Return> */ - /* An array of FT_UShort containing the affected points or the */ - /* special value ALL_POINTS. */ - /* */ - static FT_UShort* - ft_var_readpackedpoints( FT_Stream stream, - FT_UInt *point_cnt ) - { - FT_UShort *points = NULL; - FT_Int n; - FT_Int runcnt; - FT_Int i; - FT_Int j; - FT_Int first; - FT_Memory memory = stream->memory; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - *point_cnt = n = FT_GET_BYTE(); - if ( n == 0 ) - return ALL_POINTS; - - if ( n & GX_PT_POINTS_ARE_WORDS ) - n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 ); - - if ( FT_NEW_ARRAY( points, n ) ) - return NULL; - - i = 0; - while ( i < n ) - { - runcnt = FT_GET_BYTE(); - if ( runcnt & GX_PT_POINTS_ARE_WORDS ) - { - runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; - first = points[i++] = FT_GET_USHORT(); - - if ( runcnt < 1 || i + runcnt >= n ) - goto Exit; - - /* first point not included in runcount */ - for ( j = 0; j < runcnt; ++j ) - points[i++] = (FT_UShort)( first += FT_GET_USHORT() ); - } - else - { - first = points[i++] = FT_GET_BYTE(); - - if ( runcnt < 1 || i + runcnt >= n ) - goto Exit; - - for ( j = 0; j < runcnt; ++j ) - points[i++] = (FT_UShort)( first += FT_GET_BYTE() ); - } - } - - Exit: - return points; - } - - - enum - { - GX_DT_DELTAS_ARE_ZERO = 0x80, - GX_DT_DELTAS_ARE_WORDS = 0x40, - GX_DT_DELTA_RUN_COUNT_MASK = 0x3F - }; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_var_readpackeddeltas */ - /* */ - /* <Description> */ - /* Read a set of deltas. These are packed slightly differently than */ - /* points. In particular there is no overall count. */ - /* */ - /* <Input> */ - /* stream :: The data stream. */ - /* */ - /* delta_cnt :: The number of to be read. */ - /* */ - /* <Return> */ - /* An array of FT_Short containing the deltas for the affected */ - /* points. (This only gets the deltas for one dimension. It will */ - /* generally be called twice, once for x, once for y. When used in */ - /* cvt table, it will only be called once.) */ - /* */ - static FT_Short* - ft_var_readpackeddeltas( FT_Stream stream, - FT_Offset delta_cnt ) - { - FT_Short *deltas = NULL; - FT_UInt runcnt; - FT_Offset i; - FT_UInt j; - FT_Memory memory = stream->memory; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) - return NULL; - - i = 0; - while ( i < delta_cnt ) - { - runcnt = FT_GET_BYTE(); - if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) - { - /* runcnt zeroes get added */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) - deltas[i++] = 0; - } - else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) - { - /* runcnt shorts from the stack */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) - deltas[i++] = FT_GET_SHORT(); - } - else - { - /* runcnt signed bytes from the stack */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) - deltas[i++] = FT_GET_CHAR(); - } - - if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) ) - { - /* Bad format */ - FT_FREE( deltas ); - return NULL; - } - } - - return deltas; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_var_load_avar */ - /* */ - /* <Description> */ - /* Parse the `avar' table if present. It need not be, so we return */ - /* nothing. */ - /* */ - /* <InOut> */ - /* face :: The font face. */ - /* */ - static void - ft_var_load_avar( TT_Face face ) - { - FT_Stream stream = FT_FACE_STREAM(face); - FT_Memory memory = stream->memory; - GX_Blend blend = face->blend; - GX_AVarSegment segment; - FT_Error error = FT_Err_Ok; - FT_ULong version; - FT_Long axisCount; - FT_Int i, j; - FT_ULong table_len; - - FT_UNUSED( error ); - - - blend->avar_checked = TRUE; - if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0 ) - return; - - if ( FT_FRAME_ENTER( table_len ) ) - return; - - version = FT_GET_LONG(); - axisCount = FT_GET_LONG(); - - if ( version != 0x00010000L || - axisCount != (FT_Long)blend->mmvar->num_axis ) - goto Exit; - - if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) ) - goto Exit; - - segment = &blend->avar_segment[0]; - for ( i = 0; i < axisCount; ++i, ++segment ) - { - segment->pairCount = FT_GET_USHORT(); - if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) - { - /* Failure. Free everything we have done so far. We must do */ - /* it right now since loading the `avar' table is optional. */ - - for ( j = i - 1; j >= 0; --j ) - FT_FREE( blend->avar_segment[j].correspondence ); - - FT_FREE( blend->avar_segment ); - blend->avar_segment = NULL; - goto Exit; - } - - for ( j = 0; j < segment->pairCount; ++j ) - { - segment->correspondence[j].fromCoord = - FT_GET_SHORT() << 2; /* convert to Fixed */ - segment->correspondence[j].toCoord = - FT_GET_SHORT()<<2; /* convert to Fixed */ - } - } - - Exit: - FT_FRAME_EXIT(); - } - - - typedef struct GX_GVar_Head_ - { - FT_Long version; - FT_UShort axisCount; - FT_UShort globalCoordCount; - FT_ULong offsetToCoord; - FT_UShort glyphCount; - FT_UShort flags; - FT_ULong offsetToData; - - } GX_GVar_Head; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_var_load_gvar */ - /* */ - /* <Description> */ - /* Parses the `gvar' table if present. If `fvar' is there, `gvar' */ - /* had better be there too. */ - /* */ - /* <InOut> */ - /* face :: The font face. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error - ft_var_load_gvar( TT_Face face ) - { - FT_Stream stream = FT_FACE_STREAM(face); - FT_Memory memory = stream->memory; - GX_Blend blend = face->blend; - FT_Error error; - FT_UInt i, j; - FT_ULong table_len; - FT_ULong gvar_start; - FT_ULong offsetToData; - GX_GVar_Head gvar_head; - - static const FT_Frame_Field gvar_fields[] = - { - -#undef FT_STRUCTURE -#define FT_STRUCTURE GX_GVar_Head - - FT_FRAME_START( 20 ), - FT_FRAME_LONG ( version ), - FT_FRAME_USHORT( axisCount ), - FT_FRAME_USHORT( globalCoordCount ), - FT_FRAME_ULONG ( offsetToCoord ), - FT_FRAME_USHORT( glyphCount ), - FT_FRAME_USHORT( flags ), - FT_FRAME_ULONG ( offsetToData ), - FT_FRAME_END - }; - - if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 ) - goto Exit; - - gvar_start = FT_STREAM_POS( ); - if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) - goto Exit; - - blend->tuplecount = gvar_head.globalCoordCount; - blend->gv_glyphcnt = gvar_head.glyphCount; - offsetToData = gvar_start + gvar_head.offsetToData; - - if ( gvar_head.version != (FT_Long)0x00010000L || - gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) - { - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) - goto Exit; - - if ( gvar_head.flags & 1 ) - { - /* long offsets (one more offset than glyphs, to mark size of last) */ - if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) - goto Exit; - - for ( i = 0; i <= blend->gv_glyphcnt; ++i ) - blend->glyphoffsets[i] = offsetToData + FT_GET_LONG(); - - FT_FRAME_EXIT(); - } - else - { - /* short offsets (one more offset than glyphs, to mark size of last) */ - if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) - goto Exit; - - for ( i = 0; i <= blend->gv_glyphcnt; ++i ) - blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; - /* XXX: Undocumented: `*2'! */ - - FT_FRAME_EXIT(); - } - - if ( blend->tuplecount != 0 ) - { - if ( FT_NEW_ARRAY( blend->tuplecoords, - gvar_head.axisCount * blend->tuplecount ) ) - goto Exit; - - if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || - FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) - goto Exit; - - for ( i = 0; i < blend->tuplecount; ++i ) - for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j ) - blend->tuplecoords[i * gvar_head.axisCount + j] = - FT_GET_SHORT() << 2; /* convert to FT_Fixed */ - - FT_FRAME_EXIT(); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_var_apply_tuple */ - /* */ - /* <Description> */ - /* Figure out whether a given tuple (design) applies to the current */ - /* blend, and if so, what is the scaling factor. */ - /* */ - /* <Input> */ - /* blend :: The current blend of the font. */ - /* */ - /* tupleIndex :: A flag saying whether this is an intermediate */ - /* tuple or not. */ - /* */ - /* tuple_coords :: The coordinates of the tuple in normalized axis */ - /* units. */ - /* */ - /* im_start_coords :: The initial coordinates where this tuple starts */ - /* to apply (for intermediate coordinates). */ - /* */ - /* im_end_coords :: The final coordinates after which this tuple no */ - /* longer applies (for intermediate coordinates). */ - /* */ - /* <Return> */ - /* An FT_Fixed value containing the scaling factor. */ - /* */ - static FT_Fixed - ft_var_apply_tuple( GX_Blend blend, - FT_UShort tupleIndex, - FT_Fixed* tuple_coords, - FT_Fixed* im_start_coords, - FT_Fixed* im_end_coords ) - { - FT_UInt i; - FT_Fixed apply = 0x10000L; - - - for ( i = 0; i < blend->num_axis; ++i ) - { - if ( tuple_coords[i] == 0 ) - /* It's not clear why (for intermediate tuples) we don't need */ - /* to check against start/end -- the documentation says we don't. */ - /* Similarly, it's unclear why we don't need to scale along the */ - /* axis. */ - continue; - - else if ( blend->normalizedcoords[i] == 0 || - ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || - ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) - { - apply = 0; - break; - } - - else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) - /* not an intermediate tuple */ - apply = FT_MulFix( apply, - blend->normalizedcoords[i] > 0 - ? blend->normalizedcoords[i] - : -blend->normalizedcoords[i] ); - - else if ( blend->normalizedcoords[i] <= im_start_coords[i] || - blend->normalizedcoords[i] >= im_end_coords[i] ) - { - apply = 0; - break; - } - - else if ( blend->normalizedcoords[i] < tuple_coords[i] ) - apply = FT_MulDiv( apply, - blend->normalizedcoords[i] - im_start_coords[i], - tuple_coords[i] - im_start_coords[i] ); - - else - apply = FT_MulDiv( apply, - im_end_coords[i] - blend->normalizedcoords[i], - im_end_coords[i] - tuple_coords[i] ); - } - - return apply; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MULTIPLE MASTERS SERVICE FUNCTIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - typedef struct GX_FVar_Head_ - { - FT_Long version; - FT_UShort offsetToData; - FT_UShort countSizePairs; - FT_UShort axisCount; - FT_UShort axisSize; - FT_UShort instanceCount; - FT_UShort instanceSize; - - } GX_FVar_Head; - - - typedef struct fvar_axis_ - { - FT_ULong axisTag; - FT_ULong minValue; - FT_ULong defaultValue; - FT_ULong maxValue; - FT_UShort flags; - FT_UShort nameID; - - } GX_FVar_Axis; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Get_MM_Var */ - /* */ - /* <Description> */ - /* Check that the font's `fvar' table is valid, parse it, and return */ - /* those data. */ - /* */ - /* <InOut> */ - /* face :: The font face. */ - /* TT_Get_MM_Var initializes the blend structure. */ - /* */ - /* <Output> */ - /* master :: The `fvar' data (must be freed by caller). */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Get_MM_Var( TT_Face face, - FT_MM_Var* *master ) - { - FT_Stream stream = face->root.stream; - FT_Memory memory = face->root.memory; - FT_ULong table_len; - FT_Error error = FT_Err_Ok; - FT_ULong fvar_start; - FT_Int i, j; - FT_MM_Var* mmvar = NULL; - FT_Fixed* next_coords; - FT_String* next_name; - FT_Var_Axis* a; - FT_Var_Named_Style* ns; - GX_FVar_Head fvar_head; - - static const FT_Frame_Field fvar_fields[] = - { - -#undef FT_STRUCTURE -#define FT_STRUCTURE GX_FVar_Head - - FT_FRAME_START( 16 ), - FT_FRAME_LONG ( version ), - FT_FRAME_USHORT( offsetToData ), - FT_FRAME_USHORT( countSizePairs ), - FT_FRAME_USHORT( axisCount ), - FT_FRAME_USHORT( axisSize ), - FT_FRAME_USHORT( instanceCount ), - FT_FRAME_USHORT( instanceSize ), - FT_FRAME_END - }; - - static const FT_Frame_Field fvaraxis_fields[] = - { - -#undef FT_STRUCTURE -#define FT_STRUCTURE GX_FVar_Axis - - FT_FRAME_START( 20 ), - FT_FRAME_ULONG ( axisTag ), - FT_FRAME_ULONG ( minValue ), - FT_FRAME_ULONG ( defaultValue ), - FT_FRAME_ULONG ( maxValue ), - FT_FRAME_USHORT( flags ), - FT_FRAME_USHORT( nameID ), - FT_FRAME_END - }; - - - if ( face->blend == NULL ) - { - /* both `fvar' and `gvar' must be present */ - if ( (error = face->goto_table( face, TTAG_gvar, - stream, &table_len )) != 0 ) - goto Exit; - - if ( (error = face->goto_table( face, TTAG_fvar, - stream, &table_len )) != 0 ) - goto Exit; - - fvar_start = FT_STREAM_POS( ); - - if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) ) - goto Exit; - - if ( fvar_head.version != (FT_Long)0x00010000L || - fvar_head.countSizePairs != 2 || - fvar_head.axisSize != 20 || - /* axisCount limit implied by 16-bit instanceSize */ - fvar_head.axisCount > 0x3FFE || - fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount || - /* instanceCount limit implied by limited range of name IDs */ - fvar_head.instanceCount > 0x7EFF || - fvar_head.offsetToData + fvar_head.axisCount * 20U + - fvar_head.instanceCount * fvar_head.instanceSize > table_len ) - { - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - if ( FT_NEW( face->blend ) ) - goto Exit; - - /* cannot overflow 32-bit arithmetic because of limits above */ - face->blend->mmvar_len = - sizeof ( FT_MM_Var ) + - fvar_head.axisCount * sizeof ( FT_Var_Axis ) + - fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) + - fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) + - 5 * fvar_head.axisCount; - - if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) - goto Exit; - face->blend->mmvar = mmvar; - - mmvar->num_axis = - fvar_head.axisCount; - mmvar->num_designs = - ~0U; /* meaningless in this context; each glyph */ - /* may have a different number of designs */ - /* (or tuples, as called by Apple) */ - mmvar->num_namedstyles = - fvar_head.instanceCount; - mmvar->axis = - (FT_Var_Axis*)&(mmvar[1]); - mmvar->namedstyle = - (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]); - - next_coords = - (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]); - for ( i = 0; i < fvar_head.instanceCount; ++i ) - { - mmvar->namedstyle[i].coords = next_coords; - next_coords += fvar_head.axisCount; - } - - next_name = (FT_String*)next_coords; - for ( i = 0; i < fvar_head.axisCount; ++i ) - { - mmvar->axis[i].name = next_name; - next_name += 5; - } - - if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) ) - goto Exit; - - a = mmvar->axis; - for ( i = 0; i < fvar_head.axisCount; ++i ) - { - GX_FVar_Axis axis_rec; - - - if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) - goto Exit; - a->tag = axis_rec.axisTag; - a->minimum = axis_rec.minValue; /* A Fixed */ - a->def = axis_rec.defaultValue; /* A Fixed */ - a->maximum = axis_rec.maxValue; /* A Fixed */ - a->strid = axis_rec.nameID; - - a->name[0] = (FT_String)( a->tag >> 24 ); - a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF ); - a->name[2] = (FT_String)( ( a->tag >> 8 ) & 0xFF ); - a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); - a->name[4] = 0; - - ++a; - } - - ns = mmvar->namedstyle; - for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns ) - { - if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) - goto Exit; - - ns->strid = FT_GET_USHORT(); - (void) /* flags = */ FT_GET_USHORT(); - - for ( j = 0; j < fvar_head.axisCount; ++j ) - ns->coords[j] = FT_GET_ULONG(); /* A Fixed */ - - FT_FRAME_EXIT(); - } - } - - if ( master != NULL ) - { - FT_UInt n; - - - if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) - goto Exit; - FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); - - mmvar->axis = - (FT_Var_Axis*)&(mmvar[1]); - mmvar->namedstyle = - (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]); - next_coords = - (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]); - - for ( n = 0; n < mmvar->num_namedstyles; ++n ) - { - mmvar->namedstyle[n].coords = next_coords; - next_coords += mmvar->num_axis; - } - - a = mmvar->axis; - next_name = (FT_String*)next_coords; - for ( n = 0; n < mmvar->num_axis; ++n ) - { - a->name = next_name; - - /* standard PostScript names for some standard apple tags */ - if ( a->tag == TTAG_wght ) - a->name = (char *)"Weight"; - else if ( a->tag == TTAG_wdth ) - a->name = (char *)"Width"; - else if ( a->tag == TTAG_opsz ) - a->name = (char *)"OpticalSize"; - else if ( a->tag == TTAG_slnt ) - a->name = (char *)"Slant"; - - next_name += 5; - ++a; - } - - *master = mmvar; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Set_MM_Blend */ - /* */ - /* <Description> */ - /* Set the blend (normalized) coordinates for this instance of the */ - /* font. Check that the `gvar' table is reasonable and does some */ - /* initial preparation. */ - /* */ - /* <InOut> */ - /* face :: The font. */ - /* Initialize the blend structure with `gvar' data. */ - /* */ - /* <Input> */ - /* num_coords :: Must be the axis count of the font. */ - /* */ - /* coords :: An array of num_coords, each between [-1,1]. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Set_MM_Blend( TT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error = FT_Err_Ok; - GX_Blend blend; - FT_MM_Var* mmvar; - FT_UInt i; - FT_Memory memory = face->root.memory; - - enum - { - mcvt_retain, - mcvt_modify, - mcvt_load - - } manageCvt; - - - face->doblend = FALSE; - - if ( face->blend == NULL ) - { - if ( (error = TT_Get_MM_Var( face, NULL)) != 0 ) - goto Exit; - } - - blend = face->blend; - mmvar = blend->mmvar; - - if ( num_coords != mmvar->num_axis ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - for ( i = 0; i < num_coords; ++i ) - if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( blend->glyphoffsets == NULL ) - if ( (error = ft_var_load_gvar( face )) != 0 ) - goto Exit; - - if ( blend->normalizedcoords == NULL ) - { - if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) ) - goto Exit; - - manageCvt = mcvt_modify; - - /* If we have not set the blend coordinates before this, then the */ - /* cvt table will still be what we read from the `cvt ' table and */ - /* we don't need to reload it. We may need to change it though... */ - } - else - { - manageCvt = mcvt_retain; - for ( i = 0; i < num_coords; ++i ) - { - if ( blend->normalizedcoords[i] != coords[i] ) - { - manageCvt = mcvt_load; - break; - } - } - - /* If we don't change the blend coords then we don't need to do */ - /* anything to the cvt table. It will be correct. Otherwise we */ - /* no longer have the original cvt (it was modified when we set */ - /* the blend last time), so we must reload and then modify it. */ - } - - blend->num_axis = num_coords; - FT_MEM_COPY( blend->normalizedcoords, - coords, - num_coords * sizeof ( FT_Fixed ) ); - - face->doblend = TRUE; - - if ( face->cvt != NULL ) - { - switch ( manageCvt ) - { - case mcvt_load: - /* The cvt table has been loaded already; every time we change the */ - /* blend we may need to reload and remodify the cvt table. */ - FT_FREE( face->cvt ); - face->cvt = NULL; - - tt_face_load_cvt( face, face->root.stream ); - break; - - case mcvt_modify: - /* The original cvt table is in memory. All we need to do is */ - /* apply the `cvar' table (if any). */ - tt_face_vary_cvt( face, face->root.stream ); - break; - - case mcvt_retain: - /* The cvt table is correct for this set of coordinates. */ - break; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Set_Var_Design */ - /* */ - /* <Description> */ - /* Set the coordinates for the instance, measured in the user */ - /* coordinate system. Parse the `avar' table (if present) to convert */ - /* from user to normalized coordinates. */ - /* */ - /* <InOut> */ - /* face :: The font face. */ - /* Initialize the blend struct with `gvar' data. */ - /* */ - /* <Input> */ - /* num_coords :: This must be the axis count of the font. */ - /* */ - /* coords :: A coordinate array with `num_coords' elements. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Set_Var_Design( TT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error = FT_Err_Ok; - FT_Fixed* normalized = NULL; - GX_Blend blend; - FT_MM_Var* mmvar; - FT_UInt i, j; - FT_Var_Axis* a; - GX_AVarSegment av; - FT_Memory memory = face->root.memory; - - - if ( face->blend == NULL ) - { - if ( (error = TT_Get_MM_Var( face, NULL )) != 0 ) - goto Exit; - } - - blend = face->blend; - mmvar = blend->mmvar; - - if ( num_coords != mmvar->num_axis ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* Axis normalization is a two stage process. First we normalize */ - /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ - /* Then, if there's an `avar' table, we renormalize this range. */ - - if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) - goto Exit; - - a = mmvar->axis; - for ( i = 0; i < mmvar->num_axis; ++i, ++a ) - { - if ( coords[i] > a->maximum || coords[i] < a->minimum ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( coords[i] < a->def ) - normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def ); - else if ( a->maximum == a->def ) - normalized[i] = 0; - else - normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def ); - } - - if ( !blend->avar_checked ) - ft_var_load_avar( face ); - - if ( blend->avar_segment != NULL ) - { - av = blend->avar_segment; - for ( i = 0; i < mmvar->num_axis; ++i, ++av ) - { - for ( j = 1; j < (FT_UInt)av->pairCount; ++j ) - if ( normalized[i] < av->correspondence[j].fromCoord ) - { - normalized[i] = - FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, - av->correspondence[j].toCoord - - av->correspondence[j - 1].toCoord, - av->correspondence[j].fromCoord - - av->correspondence[j - 1].fromCoord ) + - av->correspondence[j - 1].toCoord; - break; - } - } - } - - error = TT_Set_MM_Blend( face, num_coords, normalized ); - - Exit: - FT_FREE( normalized ); - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GX VAR PARSING ROUTINES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_vary_cvt */ - /* */ - /* <Description> */ - /* Modify the loaded cvt table according to the `cvar' table and the */ - /* font's blend. */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Input> */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* Most errors are ignored. It is perfectly valid not to have a */ - /* `cvar' table even if there is a `gvar' and `fvar' table. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_vary_cvt( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong table_start; - FT_ULong table_len; - FT_UInt tupleCount; - FT_ULong offsetToData; - FT_ULong here; - FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; - GX_Blend blend = face->blend; - FT_UInt point_count; - FT_UShort* localpoints; - FT_Short* deltas; - - - FT_TRACE2(( "CVAR " )); - - if ( blend == NULL ) - { - FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); - - error = FT_Err_Ok; - goto Exit; - } - - if ( face->cvt == NULL ) - { - FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); - - error = FT_Err_Ok; - goto Exit; - } - - error = face->goto_table( face, TTAG_cvar, stream, &table_len ); - if ( error ) - { - FT_TRACE2(( "is missing\n" )); - - error = FT_Err_Ok; - goto Exit; - } - - if ( FT_FRAME_ENTER( table_len ) ) - { - error = FT_Err_Ok; - goto Exit; - } - - table_start = FT_Stream_FTell( stream ); - if ( FT_GET_LONG() != 0x00010000L ) - { - FT_TRACE2(( "bad table version\n" )); - - error = FT_Err_Ok; - goto FExit; - } - - if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) - goto FExit; - - tupleCount = FT_GET_USHORT(); - offsetToData = table_start + FT_GET_USHORT(); - - /* The documentation implies there are flags packed into the */ - /* tuplecount, but John Jenkins says that shared points don't apply */ - /* to `cvar', and no other flags are defined. */ - - for ( i = 0; i < ( tupleCount & 0xFFF ); ++i ) - { - FT_UInt tupleDataSize; - FT_UInt tupleIndex; - FT_Fixed apply; - - - tupleDataSize = FT_GET_USHORT(); - tupleIndex = FT_GET_USHORT(); - - /* There is no provision here for a global tuple coordinate section, */ - /* so John says. There are no tuple indices, just embedded tuples. */ - - if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) - { - for ( j = 0; j < blend->num_axis; ++j ) - tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ - /* short frac to fixed */ - } - else - { - /* skip this tuple; it makes no sense */ - - if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - for ( j = 0; j < 2 * blend->num_axis; ++j ) - (void)FT_GET_SHORT(); - - offsetToData += tupleDataSize; - continue; - } - - if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - { - for ( j = 0; j < blend->num_axis; ++j ) - im_start_coords[j] = FT_GET_SHORT() << 2; - for ( j = 0; j < blend->num_axis; ++j ) - im_end_coords[j] = FT_GET_SHORT() << 2; - } - - apply = ft_var_apply_tuple( blend, - (FT_UShort)tupleIndex, - tuple_coords, - im_start_coords, - im_end_coords ); - if ( /* tuple isn't active for our blend */ - apply == 0 || - /* global points not allowed, */ - /* if they aren't local, makes no sense */ - !( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) ) - { - offsetToData += tupleDataSize; - continue; - } - - here = FT_Stream_FTell( stream ); - - FT_Stream_SeekSet( stream, offsetToData ); - - localpoints = ft_var_readpackedpoints( stream, &point_count ); - deltas = ft_var_readpackeddeltas( stream, - point_count == 0 ? face->cvt_size - : point_count ); - if ( localpoints == NULL || deltas == NULL ) - /* failure, ignore it */; - - else if ( localpoints == ALL_POINTS ) - { - /* this means that there are deltas for every entry in cvt */ - for ( j = 0; j < face->cvt_size; ++j ) - face->cvt[j] = (FT_Short)( face->cvt[j] + - FT_MulFix( deltas[j], apply ) ); - } - - else - { - for ( j = 0; j < point_count; ++j ) - { - int pindex = localpoints[j]; - - face->cvt[pindex] = (FT_Short)( face->cvt[pindex] + - FT_MulFix( deltas[j], apply ) ); - } - } - - if ( localpoints != ALL_POINTS ) - FT_FREE( localpoints ); - FT_FREE( deltas ); - - offsetToData += tupleDataSize; - - FT_Stream_SeekSet( stream, here ); - } - - FExit: - FT_FRAME_EXIT(); - - Exit: - FT_FREE( tuple_coords ); - FT_FREE( im_start_coords ); - FT_FREE( im_end_coords ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Vary_Get_Glyph_Deltas */ - /* */ - /* <Description> */ - /* Load the appropriate deltas for the current glyph. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* glyph_index :: The index of the glyph being modified. */ - /* */ - /* n_points :: The number of the points in the glyph, including */ - /* phantom points. */ - /* */ - /* <Output> */ - /* deltas :: The array of points to change. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Vary_Get_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, - FT_Vector* *deltas, - FT_UInt n_points ) - { - FT_Stream stream = face->root.stream; - FT_Memory memory = stream->memory; - GX_Blend blend = face->blend; - FT_Vector* delta_xy = NULL; - - FT_Error error; - FT_ULong glyph_start; - FT_UInt tupleCount; - FT_ULong offsetToData; - FT_ULong here; - FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; - FT_UInt point_count, spoint_count = 0; - FT_UShort* sharedpoints = NULL; - FT_UShort* localpoints = NULL; - FT_UShort* points; - FT_Short *deltas_x, *deltas_y; - - - if ( !face->doblend || blend == NULL ) - return FT_THROW( Invalid_Argument ); - - /* to be freed by the caller */ - if ( FT_NEW_ARRAY( delta_xy, n_points ) ) - goto Exit; - *deltas = delta_xy; - - if ( glyph_index >= blend->gv_glyphcnt || - blend->glyphoffsets[glyph_index] == - blend->glyphoffsets[glyph_index + 1] ) - return FT_Err_Ok; /* no variation data for this glyph */ - - if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || - FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - - blend->glyphoffsets[glyph_index] ) ) - goto Fail1; - - glyph_start = FT_Stream_FTell( stream ); - - /* each set of glyph variation data is formatted similarly to `cvar' */ - /* (except we get shared points and global tuples) */ - - if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) - goto Fail2; - - tupleCount = FT_GET_USHORT(); - offsetToData = glyph_start + FT_GET_USHORT(); - - if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) - { - here = FT_Stream_FTell( stream ); - - FT_Stream_SeekSet( stream, offsetToData ); - - sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); - offsetToData = FT_Stream_FTell( stream ); - - FT_Stream_SeekSet( stream, here ); - } - - for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i ) - { - FT_UInt tupleDataSize; - FT_UInt tupleIndex; - FT_Fixed apply; - - - tupleDataSize = FT_GET_USHORT(); - tupleIndex = FT_GET_USHORT(); - - if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) - { - for ( j = 0; j < blend->num_axis; ++j ) - tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ - /* short frac to fixed */ - } - else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) - { - error = FT_THROW( Invalid_Table ); - goto Fail3; - } - else - { - FT_MEM_COPY( - tuple_coords, - &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis], - blend->num_axis * sizeof ( FT_Fixed ) ); - } - - if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - { - for ( j = 0; j < blend->num_axis; ++j ) - im_start_coords[j] = FT_GET_SHORT() << 2; - for ( j = 0; j < blend->num_axis; ++j ) - im_end_coords[j] = FT_GET_SHORT() << 2; - } - - apply = ft_var_apply_tuple( blend, - (FT_UShort)tupleIndex, - tuple_coords, - im_start_coords, - im_end_coords ); - - if ( apply == 0 ) /* tuple isn't active for our blend */ - { - offsetToData += tupleDataSize; - continue; - } - - here = FT_Stream_FTell( stream ); - - if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) - { - FT_Stream_SeekSet( stream, offsetToData ); - - localpoints = ft_var_readpackedpoints( stream, &point_count ); - points = localpoints; - } - else - { - points = sharedpoints; - point_count = spoint_count; - } - - deltas_x = ft_var_readpackeddeltas( stream, - point_count == 0 ? n_points - : point_count ); - deltas_y = ft_var_readpackeddeltas( stream, - point_count == 0 ? n_points - : point_count ); - - if ( points == NULL || deltas_y == NULL || deltas_x == NULL ) - ; /* failure, ignore it */ - - else if ( points == ALL_POINTS ) - { - /* this means that there are deltas for every point in the glyph */ - for ( j = 0; j < n_points; ++j ) - { - delta_xy[j].x += FT_MulFix( deltas_x[j], apply ); - delta_xy[j].y += FT_MulFix( deltas_y[j], apply ); - } - } - - else - { - for ( j = 0; j < point_count; ++j ) - { - if ( localpoints[j] >= n_points ) - continue; - - delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply ); - delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply ); - } - } - - if ( localpoints != ALL_POINTS ) - FT_FREE( localpoints ); - FT_FREE( deltas_x ); - FT_FREE( deltas_y ); - - offsetToData += tupleDataSize; - - FT_Stream_SeekSet( stream, here ); - } - - Fail3: - FT_FREE( tuple_coords ); - FT_FREE( im_start_coords ); - FT_FREE( im_end_coords ); - - Fail2: - FT_FRAME_EXIT(); - - Fail1: - if ( error ) - { - FT_FREE( delta_xy ); - *deltas = NULL; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_done_blend */ - /* */ - /* <Description> */ - /* Frees the blend internal data structure. */ - /* */ - FT_LOCAL_DEF( void ) - tt_done_blend( FT_Memory memory, - GX_Blend blend ) - { - if ( blend != NULL ) - { - FT_UInt i; - - - FT_FREE( blend->normalizedcoords ); - FT_FREE( blend->mmvar ); - - if ( blend->avar_segment != NULL ) - { - for ( i = 0; i < blend->num_axis; ++i ) - FT_FREE( blend->avar_segment[i].correspondence ); - FT_FREE( blend->avar_segment ); - } - - FT_FREE( blend->tuplecoords ); - FT_FREE( blend->glyphoffsets ); - FT_FREE( blend ); - } - } - -#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttgxvar.h b/drivers/freetype/freetype/src/truetype/ttgxvar.h deleted file mode 100644 index 82dfc4431f..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttgxvar.h +++ /dev/null @@ -1,182 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgxvar.h */ -/* */ -/* TrueType GX Font Variation loader (specification) */ -/* */ -/* Copyright 2004 by */ -/* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */ -/* */ -/* 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 __TTGXVAR_H__ -#define __TTGXVAR_H__ - - -#include <ft2build.h> -#include "ttobjs.h" - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* GX_AVarCorrespondenceRec */ - /* */ - /* <Description> */ - /* A data structure representing `shortFracCorrespondence' in `avar' */ - /* table according to the specifications from Apple. */ - /* */ - typedef struct GX_AVarCorrespondenceRec_ - { - FT_Fixed fromCoord; - FT_Fixed toCoord; - - } GX_AVarCorrespondenceRec_, *GX_AVarCorrespondence; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* GX_AVarRec */ - /* */ - /* <Description> */ - /* Data from the segment field of `avar' table. */ - /* There is one of these for each axis. */ - /* */ - typedef struct GX_AVarSegmentRec_ - { - FT_UShort pairCount; - GX_AVarCorrespondence correspondence; /* array with pairCount entries */ - - } GX_AVarSegmentRec, *GX_AVarSegment; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* GX_BlendRec */ - /* */ - /* <Description> */ - /* Data for interpolating a font from a distortable font specified */ - /* by the GX *var tables ([fgca]var). */ - /* */ - /* <Fields> */ - /* num_axis :: The number of axes along which interpolation */ - /* may happen */ - /* */ - /* normalizedcoords :: A normalized value (between [-1,1]) indicating */ - /* the contribution along each axis to the final */ - /* interpolated font. */ - /* */ - typedef struct GX_BlendRec_ - { - FT_UInt num_axis; - FT_Fixed* normalizedcoords; - - FT_MM_Var* mmvar; - FT_Offset mmvar_len; - - FT_Bool avar_checked; - GX_AVarSegment avar_segment; - - FT_UInt tuplecount; /* shared tuples in `gvar' */ - FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */ - - FT_UInt gv_glyphcnt; - FT_ULong* glyphoffsets; - - } GX_BlendRec; - - - /*************************************************************************/ - /* */ - /* <enum> */ - /* GX_TupleCountFlags */ - /* */ - /* <Description> */ - /* Flags used within the `TupleCount' field of the `gvar' table. */ - /* */ - typedef enum GX_TupleCountFlags_ - { - GX_TC_TUPLES_SHARE_POINT_NUMBERS = 0x8000, - GX_TC_RESERVED_TUPLE_FLAGS = 0x7000, - GX_TC_TUPLE_COUNT_MASK = 0x0FFF - - } GX_TupleCountFlags; - - - /*************************************************************************/ - /* */ - /* <enum> */ - /* GX_TupleIndexFlags */ - /* */ - /* <Description> */ - /* Flags used within the `TupleIndex' field of the `gvar' and `cvar' */ - /* tables. */ - /* */ - typedef enum GX_TupleIndexFlags_ - { - GX_TI_EMBEDDED_TUPLE_COORD = 0x8000, - GX_TI_INTERMEDIATE_TUPLE = 0x4000, - GX_TI_PRIVATE_POINT_NUMBERS = 0x2000, - GX_TI_RESERVED_TUPLE_FLAG = 0x1000, - GX_TI_TUPLE_INDEX_MASK = 0x0FFF - - } GX_TupleIndexFlags; - - -#define TTAG_wght FT_MAKE_TAG( 'w', 'g', 'h', 't' ) -#define TTAG_wdth FT_MAKE_TAG( 'w', 'd', 't', 'h' ) -#define TTAG_opsz FT_MAKE_TAG( 'o', 'p', 's', 'z' ) -#define TTAG_slnt FT_MAKE_TAG( 's', 'l', 'n', 't' ) - - - FT_LOCAL( FT_Error ) - TT_Set_MM_Blend( TT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - FT_LOCAL( FT_Error ) - TT_Set_Var_Design( TT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - FT_LOCAL( FT_Error ) - TT_Get_MM_Var( TT_Face face, - FT_MM_Var* *master ); - - - FT_LOCAL( FT_Error ) - tt_face_vary_cvt( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - TT_Vary_Get_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, - FT_Vector* *deltas, - FT_UInt n_points ); - - - FT_LOCAL( void ) - tt_done_blend( FT_Memory memory, - GX_Blend blend ); - - -FT_END_HEADER - - -#endif /* __TTGXVAR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttinterp.c b/drivers/freetype/freetype/src/truetype/ttinterp.c deleted file mode 100644 index e7ffb987ce..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttinterp.c +++ /dev/null @@ -1,8948 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttinterp.c */ -/* */ -/* TrueType bytecode interpreter (body). */ -/* */ -/* Copyright 1996-2013 */ -/* 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. */ -/* */ -/***************************************************************************/ - - -/* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ -/* issues; many thanks! */ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H -#include FT_TRIGONOMETRY_H -#include FT_SYSTEM_H -#include FT_TRUETYPE_DRIVER_H - -#include "ttinterp.h" -#include "tterrors.h" -#include "ttsubpix.h" - - -#ifdef TT_USE_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* 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_ttinterp - - /*************************************************************************/ - /* */ - /* In order to detect infinite loops in the code, we set up a counter */ - /* within the run loop. A single stroke of interpretation is now */ - /* limited to a maximum number of opcodes defined below. */ - /* */ -#define MAX_RUNNABLE_OPCODES 1000000L - - - /*************************************************************************/ - /* */ - /* There are two kinds of implementations: */ - /* */ - /* a. static implementation */ - /* */ - /* The current execution context is a static variable, which fields */ - /* are accessed directly by the interpreter during execution. The */ - /* context is named `cur'. */ - /* */ - /* This version is non-reentrant, of course. */ - /* */ - /* b. indirect implementation */ - /* */ - /* The current execution context is passed to _each_ function as its */ - /* first argument, and each field is thus accessed indirectly. */ - /* */ - /* This version is fully re-entrant. */ - /* */ - /* The idea is that an indirect implementation may be slower to execute */ - /* on low-end processors that are used in some systems (like 386s or */ - /* even 486s). */ - /* */ - /* As a consequence, the indirect implementation is now the default, as */ - /* its performance costs can be considered negligible in our context. */ - /* Note, however, that we kept the same source with macros because: */ - /* */ - /* - The code is kept very close in design to the Pascal code used for */ - /* development. */ - /* */ - /* - It's much more readable that way! */ - /* */ - /* - It's still open to experimentation and tuning. */ - /* */ - /*************************************************************************/ - - -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ - -#define CUR (*exc) /* see ttobjs.h */ - - /*************************************************************************/ - /* */ - /* This macro is used whenever `exec' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_EXEC FT_UNUSED( exc ) - -#else /* static implementation */ - -#define CUR cur - -#define FT_UNUSED_EXEC int __dummy = __dummy - - static - TT_ExecContextRec cur; /* static exec. context variable */ - - /* apparently, we have a _lot_ of direct indexing when accessing */ - /* the static `cur', which makes the code bigger (due to all the */ - /* four bytes addresses). */ - -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* The instruction argument stack. */ - /* */ -#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ - - - /*************************************************************************/ - /* */ - /* This macro is used whenever `args' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) - - -#define SUBPIXEL_HINTING \ - ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \ - TT_INTERPRETER_VERSION_38 ) - - - /*************************************************************************/ - /* */ - /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ - /* increase readability of the code. */ - /* */ - /*************************************************************************/ - - -#define SKIP_Code() \ - SkipCode( EXEC_ARG ) - -#define GET_ShortIns() \ - GetShortIns( EXEC_ARG ) - -#define NORMalize( x, y, v ) \ - Normalize( EXEC_ARG_ x, y, v ) - -#define SET_SuperRound( scale, flags ) \ - SetSuperRound( EXEC_ARG_ scale, flags ) - -#define ROUND_None( d, c ) \ - Round_None( EXEC_ARG_ d, c ) - -#define INS_Goto_CodeRange( range, ip ) \ - Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) - -#define CUR_Func_move( z, p, d ) \ - CUR.func_move( EXEC_ARG_ z, p, d ) - -#define CUR_Func_move_orig( z, p, d ) \ - CUR.func_move_orig( EXEC_ARG_ z, p, d ) - -#define CUR_Func_round( d, c ) \ - CUR.func_round( EXEC_ARG_ d, c ) - -#define CUR_Func_read_cvt( index ) \ - CUR.func_read_cvt( EXEC_ARG_ index ) - -#define CUR_Func_write_cvt( index, val ) \ - CUR.func_write_cvt( EXEC_ARG_ index, val ) - -#define CUR_Func_move_cvt( index, val ) \ - CUR.func_move_cvt( EXEC_ARG_ index, val ) - -#define CURRENT_Ratio() \ - Current_Ratio( EXEC_ARG ) - -#define CURRENT_Ppem() \ - Current_Ppem( EXEC_ARG ) - -#define CUR_Ppem() \ - Cur_PPEM( EXEC_ARG ) - -#define INS_SxVTL( a, b, c, d ) \ - Ins_SxVTL( EXEC_ARG_ a, b, c, d ) - -#define COMPUTE_Funcs() \ - Compute_Funcs( EXEC_ARG ) - -#define COMPUTE_Round( a ) \ - Compute_Round( EXEC_ARG_ a ) - -#define COMPUTE_Point_Displacement( a, b, c, d ) \ - Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) - -#define MOVE_Zp2_Point( a, b, c, t ) \ - Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) - - -#define CUR_Func_project( v1, v2 ) \ - CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) - -#define CUR_Func_dualproj( v1, v2 ) \ - CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) - -#define CUR_fast_project( v ) \ - CUR.func_project( EXEC_ARG_ (v)->x, (v)->y ) - -#define CUR_fast_dualproj( v ) \ - CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y ) - - - /*************************************************************************/ - /* */ - /* Instruction dispatch function, as used by the interpreter. */ - /* */ - typedef void (*TInstruction_Function)( INS_ARG ); - - - /*************************************************************************/ - /* */ - /* Two simple bounds-checking macros. */ - /* */ -#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) -#define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) - - /*************************************************************************/ - /* */ - /* This macro computes (a*2^14)/b and complements TT_MulFix14. */ - /* */ -#define TT_DivFix14( a, b ) \ - FT_DivFix( a, (b) << 2 ) - - -#undef SUCCESS -#define SUCCESS 0 - -#undef FAILURE -#define FAILURE 1 - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define GUESS_VECTOR( V ) \ - if ( CUR.face->unpatented_hinting ) \ - { \ - CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \ - CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \ - } -#else -#define GUESS_VECTOR( V ) -#endif - - /*************************************************************************/ - /* */ - /* CODERANGE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Goto_CodeRange */ - /* */ - /* <Description> */ - /* Switches to a new code range (updates the code related elements in */ - /* `exec', and `IP'). */ - /* */ - /* <Input> */ - /* range :: The new execution code range. */ - /* */ - /* IP :: The new IP in the new code range. */ - /* */ - /* <InOut> */ - /* exec :: The target execution context. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Goto_CodeRange( TT_ExecContext exec, - FT_Int range, - FT_Long IP ) - { - TT_CodeRange* coderange; - - - FT_ASSERT( range >= 1 && range <= 3 ); - - coderange = &exec->codeRangeTable[range - 1]; - - FT_ASSERT( coderange->base != NULL ); - - /* NOTE: Because the last instruction of a program may be a CALL */ - /* which will return to the first byte *after* the code */ - /* range, we test for IP <= Size instead of IP < Size. */ - /* */ - FT_ASSERT( (FT_ULong)IP <= coderange->size ); - - exec->code = coderange->base; - exec->codeSize = coderange->size; - exec->IP = IP; - exec->curRange = range; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Set_CodeRange */ - /* */ - /* <Description> */ - /* Sets a code range. */ - /* */ - /* <Input> */ - /* range :: The code range index. */ - /* */ - /* base :: The new code base. */ - /* */ - /* length :: The range size in bytes. */ - /* */ - /* <InOut> */ - /* exec :: The target execution context. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Set_CodeRange( TT_ExecContext exec, - FT_Int range, - void* base, - FT_Long length ) - { - FT_ASSERT( range >= 1 && range <= 3 ); - - exec->codeRangeTable[range - 1].base = (FT_Byte*)base; - exec->codeRangeTable[range - 1].size = length; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Clear_CodeRange */ - /* */ - /* <Description> */ - /* Clears a code range. */ - /* */ - /* <Input> */ - /* range :: The code range index. */ - /* */ - /* <InOut> */ - /* exec :: The target execution context. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Does not set the Error variable. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Clear_CodeRange( TT_ExecContext exec, - FT_Int range ) - { - FT_ASSERT( range >= 1 && range <= 3 ); - - exec->codeRangeTable[range - 1].base = NULL; - exec->codeRangeTable[range - 1].size = 0; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* EXECUTION CONTEXT ROUTINES */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Done_Context */ - /* */ - /* <Description> */ - /* Destroys a given context. */ - /* */ - /* <Input> */ - /* exec :: A handle to the target execution context. */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Done_Context( TT_ExecContext exec ) - { - FT_Memory memory = exec->memory; - - - /* points zone */ - exec->maxPoints = 0; - exec->maxContours = 0; - - /* free stack */ - FT_FREE( exec->stack ); - exec->stackSize = 0; - - /* free call stack */ - FT_FREE( exec->callStack ); - exec->callSize = 0; - exec->callTop = 0; - - /* free glyph code range */ - FT_FREE( exec->glyphIns ); - exec->glyphSize = 0; - - exec->size = NULL; - exec->face = NULL; - - FT_FREE( exec ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Init_Context */ - /* */ - /* <Description> */ - /* Initializes a context object. */ - /* */ - /* <Input> */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* <InOut> */ - /* exec :: A handle to the target execution context. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error - Init_Context( TT_ExecContext exec, - FT_Memory memory ) - { - FT_Error error; - - - FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec )); - - exec->memory = memory; - exec->callSize = 32; - - if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) ) - goto Fail_Memory; - - /* all values in the context are set to 0 already, but this is */ - /* here as a remainder */ - exec->maxPoints = 0; - exec->maxContours = 0; - - exec->stackSize = 0; - exec->glyphSize = 0; - - exec->stack = NULL; - exec->glyphIns = NULL; - - exec->face = NULL; - exec->size = NULL; - - return FT_Err_Ok; - - Fail_Memory: - FT_ERROR(( "Init_Context: not enough memory for %p\n", exec )); - TT_Done_Context( exec ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Update_Max */ - /* */ - /* <Description> */ - /* Checks the size of a buffer and reallocates it if necessary. */ - /* */ - /* <Input> */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* multiplier :: The size in bytes of each element in the buffer. */ - /* */ - /* new_max :: The new capacity (size) of the buffer. */ - /* */ - /* <InOut> */ - /* size :: The address of the buffer's current size expressed */ - /* in elements. */ - /* */ - /* buff :: The address of the buffer base pointer. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - Update_Max( FT_Memory memory, - FT_ULong* size, - FT_Long multiplier, - void* _pbuff, - FT_ULong new_max ) - { - FT_Error error; - void** pbuff = (void**)_pbuff; - - - if ( *size < new_max ) - { - if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) - return error; - *size = new_max; - } - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Load_Context */ - /* */ - /* <Description> */ - /* Prepare an execution context for glyph hinting. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* size :: A handle to the source size object. */ - /* */ - /* <InOut> */ - /* exec :: A handle to the target execution context. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Load_Context( TT_ExecContext exec, - TT_Face face, - TT_Size size ) - { - FT_Int i; - FT_ULong tmp; - TT_MaxProfile* maxp; - FT_Error error; - - - exec->face = face; - maxp = &face->max_profile; - exec->size = size; - - if ( size ) - { - exec->numFDefs = size->num_function_defs; - exec->maxFDefs = size->max_function_defs; - exec->numIDefs = size->num_instruction_defs; - exec->maxIDefs = size->max_instruction_defs; - exec->FDefs = size->function_defs; - exec->IDefs = size->instruction_defs; - exec->tt_metrics = size->ttmetrics; - exec->metrics = size->metrics; - - exec->maxFunc = size->max_func; - exec->maxIns = size->max_ins; - - for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) - exec->codeRangeTable[i] = size->codeRangeTable[i]; - - /* set graphics state */ - exec->GS = size->GS; - - exec->cvtSize = size->cvt_size; - exec->cvt = size->cvt; - - exec->storeSize = size->storage_size; - exec->storage = size->storage; - - exec->twilight = size->twilight; - - /* In case of multi-threading it can happen that the old size object */ - /* no longer exists, thus we must clear all glyph zone references. */ - ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) ); - exec->zp1 = exec->zp0; - exec->zp2 = exec->zp0; - } - - /* XXX: We reserve a little more elements on the stack to deal safely */ - /* with broken fonts like arialbs, courbs, timesbs, etc. */ - tmp = exec->stackSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_F26Dot6 ), - (void*)&exec->stack, - maxp->maxStackElements + 32 ); - exec->stackSize = (FT_UInt)tmp; - if ( error ) - return error; - - tmp = exec->glyphSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void*)&exec->glyphIns, - maxp->maxSizeOfInstructions ); - exec->glyphSize = (FT_UShort)tmp; - if ( error ) - return error; - - exec->pts.n_points = 0; - exec->pts.n_contours = 0; - - exec->zp1 = exec->pts; - exec->zp2 = exec->pts; - exec->zp0 = exec->pts; - - exec->instruction_trap = FALSE; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Save_Context */ - /* */ - /* <Description> */ - /* Saves the code ranges in a `size' object. */ - /* */ - /* <Input> */ - /* exec :: A handle to the source execution context. */ - /* */ - /* <InOut> */ - /* size :: A handle to the target size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Save_Context( TT_ExecContext exec, - TT_Size size ) - { - FT_Int i; - - - /* XXX: Will probably disappear soon with all the code range */ - /* management, which is now rather obsolete. */ - /* */ - size->num_function_defs = exec->numFDefs; - size->num_instruction_defs = exec->numIDefs; - - size->max_func = exec->maxFunc; - size->max_ins = exec->maxIns; - - for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) - size->codeRangeTable[i] = exec->codeRangeTable[i]; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_Run_Context */ - /* */ - /* <Description> */ - /* Executes one or more instructions in the execution context. */ - /* */ - /* <Input> */ - /* debug :: A Boolean flag. If set, the function sets some internal */ - /* variables and returns immediately, otherwise TT_RunIns() */ - /* is called. */ - /* */ - /* This is commented out currently. */ - /* */ - /* <Input> */ - /* exec :: A handle to the target execution context. */ - /* */ - /* <Return> */ - /* TrueType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ) - { - FT_Error error; - - - if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) - != FT_Err_Ok ) - return error; - - exec->zp0 = exec->pts; - exec->zp1 = exec->pts; - exec->zp2 = exec->pts; - - exec->GS.gep0 = 1; - exec->GS.gep1 = 1; - exec->GS.gep2 = 1; - - exec->GS.projVector.x = 0x4000; - exec->GS.projVector.y = 0x0000; - - exec->GS.freeVector = exec->GS.projVector; - exec->GS.dualVector = exec->GS.projVector; - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - exec->GS.both_x_axis = TRUE; -#endif - - exec->GS.round_state = 1; - exec->GS.loop = 1; - - /* some glyphs leave something on the stack. so we clean it */ - /* before a new execution. */ - exec->top = 0; - exec->callTop = 0; - -#if 1 - FT_UNUSED( debug ); - - return exec->face->interpreter( exec ); -#else - if ( !debug ) - return TT_RunIns( exec ); - else - return FT_Err_Ok; -#endif - } - - - /* The default value for `scan_control' is documented as FALSE in the */ - /* TrueType specification. This is confusing since it implies a */ - /* Boolean value. However, this is not the case, thus both the */ - /* default values of our `scan_type' and `scan_control' fields (which */ - /* the documentation's `scan_control' variable is split into) are */ - /* zero. */ - - const TT_GraphicsState tt_default_graphics_state = - { - 0, 0, 0, - { 0x4000, 0 }, - { 0x4000, 0 }, - { 0x4000, 0 }, - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - TRUE, -#endif - - 1, 64, 1, - TRUE, 68, 0, 0, 9, 3, - 0, FALSE, 0, 1, 1, 1 - }; - - - /* documentation is in ttinterp.h */ - - FT_EXPORT_DEF( TT_ExecContext ) - TT_New_Context( TT_Driver driver ) - { - TT_ExecContext exec; - FT_Memory memory; - - - memory = driver->root.root.memory; - exec = driver->context; - - if ( !driver->context ) - { - FT_Error error; - - - /* allocate object */ - if ( FT_NEW( exec ) ) - goto Fail; - - /* initialize it; in case of error this deallocates `exec' too */ - error = Init_Context( exec, memory ); - if ( error ) - goto Fail; - - /* store it into the driver */ - driver->context = exec; - } - - return driver->context; - - Fail: - return NULL; - } - - - /*************************************************************************/ - /* */ - /* Before an opcode is executed, the interpreter verifies that there are */ - /* enough arguments on the stack, with the help of the `Pop_Push_Count' */ - /* table. */ - /* */ - /* For each opcode, the first column gives the number of arguments that */ - /* are popped from the stack; the second one gives the number of those */ - /* that are pushed in result. */ - /* */ - /* Opcodes which have a varying number of parameters in the data stream */ - /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */ - /* the `opcode_length' table, and the value in `Pop_Push_Count' is set */ - /* to zero. */ - /* */ - /*************************************************************************/ - - -#undef PACK -#define PACK( x, y ) ( ( x << 4 ) | y ) - - - static - const FT_Byte Pop_Push_Count[256] = - { - /* opcodes are gathered in groups of 16 */ - /* please keep the spaces as they are */ - - /* SVTCA y */ PACK( 0, 0 ), - /* SVTCA x */ PACK( 0, 0 ), - /* SPvTCA y */ PACK( 0, 0 ), - /* SPvTCA x */ PACK( 0, 0 ), - /* SFvTCA y */ PACK( 0, 0 ), - /* SFvTCA x */ PACK( 0, 0 ), - /* SPvTL // */ PACK( 2, 0 ), - /* SPvTL + */ PACK( 2, 0 ), - /* SFvTL // */ PACK( 2, 0 ), - /* SFvTL + */ PACK( 2, 0 ), - /* SPvFS */ PACK( 2, 0 ), - /* SFvFS */ PACK( 2, 0 ), - /* GPV */ PACK( 0, 2 ), - /* GFV */ PACK( 0, 2 ), - /* SFvTPv */ PACK( 0, 0 ), - /* ISECT */ PACK( 5, 0 ), - - /* SRP0 */ PACK( 1, 0 ), - /* SRP1 */ PACK( 1, 0 ), - /* SRP2 */ PACK( 1, 0 ), - /* SZP0 */ PACK( 1, 0 ), - /* SZP1 */ PACK( 1, 0 ), - /* SZP2 */ PACK( 1, 0 ), - /* SZPS */ PACK( 1, 0 ), - /* SLOOP */ PACK( 1, 0 ), - /* RTG */ PACK( 0, 0 ), - /* RTHG */ PACK( 0, 0 ), - /* SMD */ PACK( 1, 0 ), - /* ELSE */ PACK( 0, 0 ), - /* JMPR */ PACK( 1, 0 ), - /* SCvTCi */ PACK( 1, 0 ), - /* SSwCi */ PACK( 1, 0 ), - /* SSW */ PACK( 1, 0 ), - - /* DUP */ PACK( 1, 2 ), - /* POP */ PACK( 1, 0 ), - /* CLEAR */ PACK( 0, 0 ), - /* SWAP */ PACK( 2, 2 ), - /* DEPTH */ PACK( 0, 1 ), - /* CINDEX */ PACK( 1, 1 ), - /* MINDEX */ PACK( 1, 0 ), - /* AlignPTS */ PACK( 2, 0 ), - /* INS_$28 */ PACK( 0, 0 ), - /* UTP */ PACK( 1, 0 ), - /* LOOPCALL */ PACK( 2, 0 ), - /* CALL */ PACK( 1, 0 ), - /* FDEF */ PACK( 1, 0 ), - /* ENDF */ PACK( 0, 0 ), - /* MDAP[0] */ PACK( 1, 0 ), - /* MDAP[1] */ PACK( 1, 0 ), - - /* IUP[0] */ PACK( 0, 0 ), - /* IUP[1] */ PACK( 0, 0 ), - /* SHP[0] */ PACK( 0, 0 ), - /* SHP[1] */ PACK( 0, 0 ), - /* SHC[0] */ PACK( 1, 0 ), - /* SHC[1] */ PACK( 1, 0 ), - /* SHZ[0] */ PACK( 1, 0 ), - /* SHZ[1] */ PACK( 1, 0 ), - /* SHPIX */ PACK( 1, 0 ), - /* IP */ PACK( 0, 0 ), - /* MSIRP[0] */ PACK( 2, 0 ), - /* MSIRP[1] */ PACK( 2, 0 ), - /* AlignRP */ PACK( 0, 0 ), - /* RTDG */ PACK( 0, 0 ), - /* MIAP[0] */ PACK( 2, 0 ), - /* MIAP[1] */ PACK( 2, 0 ), - - /* NPushB */ PACK( 0, 0 ), - /* NPushW */ PACK( 0, 0 ), - /* WS */ PACK( 2, 0 ), - /* RS */ PACK( 1, 1 ), - /* WCvtP */ PACK( 2, 0 ), - /* RCvt */ PACK( 1, 1 ), - /* GC[0] */ PACK( 1, 1 ), - /* GC[1] */ PACK( 1, 1 ), - /* SCFS */ PACK( 2, 0 ), - /* MD[0] */ PACK( 2, 1 ), - /* MD[1] */ PACK( 2, 1 ), - /* MPPEM */ PACK( 0, 1 ), - /* MPS */ PACK( 0, 1 ), - /* FlipON */ PACK( 0, 0 ), - /* FlipOFF */ PACK( 0, 0 ), - /* DEBUG */ PACK( 1, 0 ), - - /* LT */ PACK( 2, 1 ), - /* LTEQ */ PACK( 2, 1 ), - /* GT */ PACK( 2, 1 ), - /* GTEQ */ PACK( 2, 1 ), - /* EQ */ PACK( 2, 1 ), - /* NEQ */ PACK( 2, 1 ), - /* ODD */ PACK( 1, 1 ), - /* EVEN */ PACK( 1, 1 ), - /* IF */ PACK( 1, 0 ), - /* EIF */ PACK( 0, 0 ), - /* AND */ PACK( 2, 1 ), - /* OR */ PACK( 2, 1 ), - /* NOT */ PACK( 1, 1 ), - /* DeltaP1 */ PACK( 1, 0 ), - /* SDB */ PACK( 1, 0 ), - /* SDS */ PACK( 1, 0 ), - - /* ADD */ PACK( 2, 1 ), - /* SUB */ PACK( 2, 1 ), - /* DIV */ PACK( 2, 1 ), - /* MUL */ PACK( 2, 1 ), - /* ABS */ PACK( 1, 1 ), - /* NEG */ PACK( 1, 1 ), - /* FLOOR */ PACK( 1, 1 ), - /* CEILING */ PACK( 1, 1 ), - /* ROUND[0] */ PACK( 1, 1 ), - /* ROUND[1] */ PACK( 1, 1 ), - /* ROUND[2] */ PACK( 1, 1 ), - /* ROUND[3] */ PACK( 1, 1 ), - /* NROUND[0] */ PACK( 1, 1 ), - /* NROUND[1] */ PACK( 1, 1 ), - /* NROUND[2] */ PACK( 1, 1 ), - /* NROUND[3] */ PACK( 1, 1 ), - - /* WCvtF */ PACK( 2, 0 ), - /* DeltaP2 */ PACK( 1, 0 ), - /* DeltaP3 */ PACK( 1, 0 ), - /* DeltaCn[0] */ PACK( 1, 0 ), - /* DeltaCn[1] */ PACK( 1, 0 ), - /* DeltaCn[2] */ PACK( 1, 0 ), - /* SROUND */ PACK( 1, 0 ), - /* S45Round */ PACK( 1, 0 ), - /* JROT */ PACK( 2, 0 ), - /* JROF */ PACK( 2, 0 ), - /* ROFF */ PACK( 0, 0 ), - /* INS_$7B */ PACK( 0, 0 ), - /* RUTG */ PACK( 0, 0 ), - /* RDTG */ PACK( 0, 0 ), - /* SANGW */ PACK( 1, 0 ), - /* AA */ PACK( 1, 0 ), - - /* FlipPT */ PACK( 0, 0 ), - /* FlipRgON */ PACK( 2, 0 ), - /* FlipRgOFF */ PACK( 2, 0 ), - /* INS_$83 */ PACK( 0, 0 ), - /* INS_$84 */ PACK( 0, 0 ), - /* ScanCTRL */ PACK( 1, 0 ), - /* SDPVTL[0] */ PACK( 2, 0 ), - /* SDPVTL[1] */ PACK( 2, 0 ), - /* GetINFO */ PACK( 1, 1 ), - /* IDEF */ PACK( 1, 0 ), - /* ROLL */ PACK( 3, 3 ), - /* MAX */ PACK( 2, 1 ), - /* MIN */ PACK( 2, 1 ), - /* ScanTYPE */ PACK( 1, 0 ), - /* InstCTRL */ PACK( 2, 0 ), - /* INS_$8F */ PACK( 0, 0 ), - - /* INS_$90 */ PACK( 0, 0 ), - /* INS_$91 */ PACK( 0, 0 ), - /* INS_$92 */ PACK( 0, 0 ), - /* INS_$93 */ PACK( 0, 0 ), - /* INS_$94 */ PACK( 0, 0 ), - /* INS_$95 */ PACK( 0, 0 ), - /* INS_$96 */ PACK( 0, 0 ), - /* INS_$97 */ PACK( 0, 0 ), - /* INS_$98 */ PACK( 0, 0 ), - /* INS_$99 */ PACK( 0, 0 ), - /* INS_$9A */ PACK( 0, 0 ), - /* INS_$9B */ PACK( 0, 0 ), - /* INS_$9C */ PACK( 0, 0 ), - /* INS_$9D */ PACK( 0, 0 ), - /* INS_$9E */ PACK( 0, 0 ), - /* INS_$9F */ PACK( 0, 0 ), - - /* INS_$A0 */ PACK( 0, 0 ), - /* INS_$A1 */ PACK( 0, 0 ), - /* INS_$A2 */ PACK( 0, 0 ), - /* INS_$A3 */ PACK( 0, 0 ), - /* INS_$A4 */ PACK( 0, 0 ), - /* INS_$A5 */ PACK( 0, 0 ), - /* INS_$A6 */ PACK( 0, 0 ), - /* INS_$A7 */ PACK( 0, 0 ), - /* INS_$A8 */ PACK( 0, 0 ), - /* INS_$A9 */ PACK( 0, 0 ), - /* INS_$AA */ PACK( 0, 0 ), - /* INS_$AB */ PACK( 0, 0 ), - /* INS_$AC */ PACK( 0, 0 ), - /* INS_$AD */ PACK( 0, 0 ), - /* INS_$AE */ PACK( 0, 0 ), - /* INS_$AF */ PACK( 0, 0 ), - - /* PushB[0] */ PACK( 0, 1 ), - /* PushB[1] */ PACK( 0, 2 ), - /* PushB[2] */ PACK( 0, 3 ), - /* PushB[3] */ PACK( 0, 4 ), - /* PushB[4] */ PACK( 0, 5 ), - /* PushB[5] */ PACK( 0, 6 ), - /* PushB[6] */ PACK( 0, 7 ), - /* PushB[7] */ PACK( 0, 8 ), - /* PushW[0] */ PACK( 0, 1 ), - /* PushW[1] */ PACK( 0, 2 ), - /* PushW[2] */ PACK( 0, 3 ), - /* PushW[3] */ PACK( 0, 4 ), - /* PushW[4] */ PACK( 0, 5 ), - /* PushW[5] */ PACK( 0, 6 ), - /* PushW[6] */ PACK( 0, 7 ), - /* PushW[7] */ PACK( 0, 8 ), - - /* MDRP[00] */ PACK( 1, 0 ), - /* MDRP[01] */ PACK( 1, 0 ), - /* MDRP[02] */ PACK( 1, 0 ), - /* MDRP[03] */ PACK( 1, 0 ), - /* MDRP[04] */ PACK( 1, 0 ), - /* MDRP[05] */ PACK( 1, 0 ), - /* MDRP[06] */ PACK( 1, 0 ), - /* MDRP[07] */ PACK( 1, 0 ), - /* MDRP[08] */ PACK( 1, 0 ), - /* MDRP[09] */ PACK( 1, 0 ), - /* MDRP[10] */ PACK( 1, 0 ), - /* MDRP[11] */ PACK( 1, 0 ), - /* MDRP[12] */ PACK( 1, 0 ), - /* MDRP[13] */ PACK( 1, 0 ), - /* MDRP[14] */ PACK( 1, 0 ), - /* MDRP[15] */ PACK( 1, 0 ), - - /* MDRP[16] */ PACK( 1, 0 ), - /* MDRP[17] */ PACK( 1, 0 ), - /* MDRP[18] */ PACK( 1, 0 ), - /* MDRP[19] */ PACK( 1, 0 ), - /* MDRP[20] */ PACK( 1, 0 ), - /* MDRP[21] */ PACK( 1, 0 ), - /* MDRP[22] */ PACK( 1, 0 ), - /* MDRP[23] */ PACK( 1, 0 ), - /* MDRP[24] */ PACK( 1, 0 ), - /* MDRP[25] */ PACK( 1, 0 ), - /* MDRP[26] */ PACK( 1, 0 ), - /* MDRP[27] */ PACK( 1, 0 ), - /* MDRP[28] */ PACK( 1, 0 ), - /* MDRP[29] */ PACK( 1, 0 ), - /* MDRP[30] */ PACK( 1, 0 ), - /* MDRP[31] */ PACK( 1, 0 ), - - /* MIRP[00] */ PACK( 2, 0 ), - /* MIRP[01] */ PACK( 2, 0 ), - /* MIRP[02] */ PACK( 2, 0 ), - /* MIRP[03] */ PACK( 2, 0 ), - /* MIRP[04] */ PACK( 2, 0 ), - /* MIRP[05] */ PACK( 2, 0 ), - /* MIRP[06] */ PACK( 2, 0 ), - /* MIRP[07] */ PACK( 2, 0 ), - /* MIRP[08] */ PACK( 2, 0 ), - /* MIRP[09] */ PACK( 2, 0 ), - /* MIRP[10] */ PACK( 2, 0 ), - /* MIRP[11] */ PACK( 2, 0 ), - /* MIRP[12] */ PACK( 2, 0 ), - /* MIRP[13] */ PACK( 2, 0 ), - /* MIRP[14] */ PACK( 2, 0 ), - /* MIRP[15] */ PACK( 2, 0 ), - - /* MIRP[16] */ PACK( 2, 0 ), - /* MIRP[17] */ PACK( 2, 0 ), - /* MIRP[18] */ PACK( 2, 0 ), - /* MIRP[19] */ PACK( 2, 0 ), - /* MIRP[20] */ PACK( 2, 0 ), - /* MIRP[21] */ PACK( 2, 0 ), - /* MIRP[22] */ PACK( 2, 0 ), - /* MIRP[23] */ PACK( 2, 0 ), - /* MIRP[24] */ PACK( 2, 0 ), - /* MIRP[25] */ PACK( 2, 0 ), - /* MIRP[26] */ PACK( 2, 0 ), - /* MIRP[27] */ PACK( 2, 0 ), - /* MIRP[28] */ PACK( 2, 0 ), - /* MIRP[29] */ PACK( 2, 0 ), - /* MIRP[30] */ PACK( 2, 0 ), - /* MIRP[31] */ PACK( 2, 0 ) - }; - - -#ifdef FT_DEBUG_LEVEL_TRACE - - static - const char* const opcode_name[256] = - { - "SVTCA y", - "SVTCA x", - "SPvTCA y", - "SPvTCA x", - "SFvTCA y", - "SFvTCA x", - "SPvTL ||", - "SPvTL +", - "SFvTL ||", - "SFvTL +", - "SPvFS", - "SFvFS", - "GPV", - "GFV", - "SFvTPv", - "ISECT", - - "SRP0", - "SRP1", - "SRP2", - "SZP0", - "SZP1", - "SZP2", - "SZPS", - "SLOOP", - "RTG", - "RTHG", - "SMD", - "ELSE", - "JMPR", - "SCvTCi", - "SSwCi", - "SSW", - - "DUP", - "POP", - "CLEAR", - "SWAP", - "DEPTH", - "CINDEX", - "MINDEX", - "AlignPTS", - "INS_$28", - "UTP", - "LOOPCALL", - "CALL", - "FDEF", - "ENDF", - "MDAP[0]", - "MDAP[1]", - - "IUP[0]", - "IUP[1]", - "SHP[0]", - "SHP[1]", - "SHC[0]", - "SHC[1]", - "SHZ[0]", - "SHZ[1]", - "SHPIX", - "IP", - "MSIRP[0]", - "MSIRP[1]", - "AlignRP", - "RTDG", - "MIAP[0]", - "MIAP[1]", - - "NPushB", - "NPushW", - "WS", - "RS", - "WCvtP", - "RCvt", - "GC[0]", - "GC[1]", - "SCFS", - "MD[0]", - "MD[1]", - "MPPEM", - "MPS", - "FlipON", - "FlipOFF", - "DEBUG", - - "LT", - "LTEQ", - "GT", - "GTEQ", - "EQ", - "NEQ", - "ODD", - "EVEN", - "IF", - "EIF", - "AND", - "OR", - "NOT", - "DeltaP1", - "SDB", - "SDS", - - "ADD", - "SUB", - "DIV", - "MUL", - "ABS", - "NEG", - "FLOOR", - "CEILING", - "ROUND[0]", - "ROUND[1]", - "ROUND[2]", - "ROUND[3]", - "NROUND[0]", - "NROUND[1]", - "NROUND[2]", - "NROUND[3]", - - "WCvtF", - "DeltaP2", - "DeltaP3", - "DeltaCn[0]", - "DeltaCn[1]", - "DeltaCn[2]", - "SROUND", - "S45Round", - "JROT", - "JROF", - "ROFF", - "INS_$7B", - "RUTG", - "RDTG", - "SANGW", - "AA", - - "FlipPT", - "FlipRgON", - "FlipRgOFF", - "INS_$83", - "INS_$84", - "ScanCTRL", - "SDVPTL[0]", - "SDVPTL[1]", - "GetINFO", - "IDEF", - "ROLL", - "MAX", - "MIN", - "ScanTYPE", - "InstCTRL", - "INS_$8F", - - "INS_$90", - "INS_$91", - "INS_$92", - "INS_$93", - "INS_$94", - "INS_$95", - "INS_$96", - "INS_$97", - "INS_$98", - "INS_$99", - "INS_$9A", - "INS_$9B", - "INS_$9C", - "INS_$9D", - "INS_$9E", - "INS_$9F", - - "INS_$A0", - "INS_$A1", - "INS_$A2", - "INS_$A3", - "INS_$A4", - "INS_$A5", - "INS_$A6", - "INS_$A7", - "INS_$A8", - "INS_$A9", - "INS_$AA", - "INS_$AB", - "INS_$AC", - "INS_$AD", - "INS_$AE", - "INS_$AF", - - "PushB[0]", - "PushB[1]", - "PushB[2]", - "PushB[3]", - "PushB[4]", - "PushB[5]", - "PushB[6]", - "PushB[7]", - "PushW[0]", - "PushW[1]", - "PushW[2]", - "PushW[3]", - "PushW[4]", - "PushW[5]", - "PushW[6]", - "PushW[7]", - - "MDRP[00]", - "MDRP[01]", - "MDRP[02]", - "MDRP[03]", - "MDRP[04]", - "MDRP[05]", - "MDRP[06]", - "MDRP[07]", - "MDRP[08]", - "MDRP[09]", - "MDRP[10]", - "MDRP[11]", - "MDRP[12]", - "MDRP[13]", - "MDRP[14]", - "MDRP[15]", - - "MDRP[16]", - "MDRP[17]", - "MDRP[18]", - "MDRP[19]", - "MDRP[20]", - "MDRP[21]", - "MDRP[22]", - "MDRP[23]", - "MDRP[24]", - "MDRP[25]", - "MDRP[26]", - "MDRP[27]", - "MDRP[28]", - "MDRP[29]", - "MDRP[30]", - "MDRP[31]", - - "MIRP[00]", - "MIRP[01]", - "MIRP[02]", - "MIRP[03]", - "MIRP[04]", - "MIRP[05]", - "MIRP[06]", - "MIRP[07]", - "MIRP[08]", - "MIRP[09]", - "MIRP[10]", - "MIRP[11]", - "MIRP[12]", - "MIRP[13]", - "MIRP[14]", - "MIRP[15]", - - "MIRP[16]", - "MIRP[17]", - "MIRP[18]", - "MIRP[19]", - "MIRP[20]", - "MIRP[21]", - "MIRP[22]", - "MIRP[23]", - "MIRP[24]", - "MIRP[25]", - "MIRP[26]", - "MIRP[27]", - "MIRP[28]", - "MIRP[29]", - "MIRP[30]", - "MIRP[31]" - }; - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - - static - const FT_Char opcode_length[256] = - { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - -1,-2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - }; - -#undef PACK - -#if 1 - - static FT_Int32 - TT_MulFix14( FT_Int32 a, - FT_Int b ) - { - FT_Int32 sign; - FT_UInt32 ah, al, mid, lo, hi; - - - sign = a ^ b; - - if ( a < 0 ) - a = -a; - if ( b < 0 ) - b = -b; - - ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU ); - al = (FT_UInt32)( a & 0xFFFFU ); - - lo = al * b; - mid = ah * b; - hi = mid >> 16; - mid = ( mid << 16 ) + ( 1 << 13 ); /* rounding */ - lo += mid; - if ( lo < mid ) - hi += 1; - - mid = ( lo >> 14 ) | ( hi << 18 ); - - return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid; - } - -#else - - /* compute (a*b)/2^14 with maximum accuracy and rounding */ - static FT_Int32 - TT_MulFix14( FT_Int32 a, - FT_Int b ) - { - FT_Int32 m, s, hi; - FT_UInt32 l, lo; - - - /* compute ax*bx as 64-bit value */ - l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); - m = ( a >> 16 ) * b; - - lo = l + ( (FT_UInt32)m << 16 ); - hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); - - /* divide the result by 2^14 with rounding */ - s = hi >> 31; - l = lo + (FT_UInt32)s; - hi += s + ( l < lo ); - lo = l; - - l = lo + 0x2000U; - hi += l < lo; - - return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); - } -#endif - - - /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */ - static FT_Int32 - TT_DotFix14( FT_Int32 ax, - FT_Int32 ay, - FT_Int bx, - FT_Int by ) - { - FT_Int32 m, s, hi1, hi2, hi; - FT_UInt32 l, lo1, lo2, lo; - - - /* compute ax*bx as 64-bit value */ - l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx ); - m = ( ax >> 16 ) * bx; - - lo1 = l + ( (FT_UInt32)m << 16 ); - hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l ); - - /* compute ay*by as 64-bit value */ - l = (FT_UInt32)( ( ay & 0xFFFFU ) * by ); - m = ( ay >> 16 ) * by; - - lo2 = l + ( (FT_UInt32)m << 16 ); - hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l ); - - /* add them */ - lo = lo1 + lo2; - hi = hi1 + hi2 + ( lo < lo1 ); - - /* divide the result by 2^14 with rounding */ - s = hi >> 31; - l = lo + (FT_UInt32)s; - hi += s + ( l < lo ); - lo = l; - - l = lo + 0x2000U; - hi += ( l < lo ); - - return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Current_Ratio */ - /* */ - /* <Description> */ - /* Returns the current aspect ratio scaling factor depending on the */ - /* projection vector's state and device resolutions. */ - /* */ - /* <Return> */ - /* The aspect ratio in 16.16 format, always <= 1.0 . */ - /* */ - static FT_Long - Current_Ratio( EXEC_OP ) - { - if ( !CUR.tt_metrics.ratio ) - { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; - else - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; - } - else -#endif - { - if ( CUR.GS.projVector.y == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; - - else if ( CUR.GS.projVector.x == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; - - else - { - FT_F26Dot6 x, y; - - - x = TT_MulFix14( CUR.tt_metrics.x_ratio, - CUR.GS.projVector.x ); - y = TT_MulFix14( CUR.tt_metrics.y_ratio, - CUR.GS.projVector.y ); - CUR.tt_metrics.ratio = FT_Hypot( x, y ); - } - } - } - return CUR.tt_metrics.ratio; - } - - - static FT_Long - Current_Ppem( EXEC_OP ) - { - return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() ); - } - - - /*************************************************************************/ - /* */ - /* Functions related to the control value table (CVT). */ - /* */ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_F26Dot6 ) - Read_CVT( EXEC_OP_ FT_ULong idx ) - { - return CUR.cvt[idx]; - } - - - FT_CALLBACK_DEF( FT_F26Dot6 ) - Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) - { - return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() ); - } - - - FT_CALLBACK_DEF( void ) - Write_CVT( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) - { - CUR.cvt[idx] = value; - } - - - FT_CALLBACK_DEF( void ) - Write_CVT_Stretched( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) - { - CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() ); - } - - - FT_CALLBACK_DEF( void ) - Move_CVT( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) - { - CUR.cvt[idx] += value; - } - - - FT_CALLBACK_DEF( void ) - Move_CVT_Stretched( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) - { - CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* GetShortIns */ - /* */ - /* <Description> */ - /* Returns a short integer taken from the instruction stream at */ - /* address IP. */ - /* */ - /* <Return> */ - /* Short read at code[IP]. */ - /* */ - /* <Note> */ - /* This one could become a macro. */ - /* */ - static FT_Short - GetShortIns( EXEC_OP ) - { - /* Reading a byte stream so there is no endianess (DaveP) */ - CUR.IP += 2; - return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + - CUR.code[CUR.IP - 1] ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Ins_Goto_CodeRange */ - /* */ - /* <Description> */ - /* Goes to a certain code range in the instruction stream. */ - /* */ - /* <Input> */ - /* aRange :: The index of the code range. */ - /* */ - /* aIP :: The new IP address in the code range. */ - /* */ - /* <Return> */ - /* SUCCESS or FAILURE. */ - /* */ - static FT_Bool - Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, - FT_ULong aIP ) - { - TT_CodeRange* range; - - - if ( aRange < 1 || aRange > 3 ) - { - CUR.error = FT_THROW( Bad_Argument ); - return FAILURE; - } - - range = &CUR.codeRangeTable[aRange - 1]; - - if ( range->base == NULL ) /* invalid coderange */ - { - CUR.error = FT_THROW( Invalid_CodeRange ); - return FAILURE; - } - - /* NOTE: Because the last instruction of a program may be a CALL */ - /* which will return to the first byte *after* the code */ - /* range, we test for aIP <= Size, instead of aIP < Size. */ - - if ( aIP > range->size ) - { - CUR.error = FT_THROW( Code_Overflow ); - return FAILURE; - } - - CUR.code = range->base; - CUR.codeSize = range->size; - CUR.IP = aIP; - CUR.curRange = aRange; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Direct_Move */ - /* */ - /* <Description> */ - /* Moves a point by a given distance along the freedom vector. The */ - /* point will be `touched'. */ - /* */ - /* <Input> */ - /* point :: The index of the point to move. */ - /* */ - /* distance :: The distance to apply. */ - /* */ - /* <InOut> */ - /* zone :: The affected glyph zone. */ - /* */ - static void - Direct_Move( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_F26Dot6 v; - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - v = CUR.GS.freeVector.x; - - if ( v != 0 ) - { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); - - zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; - } - - v = CUR.GS.freeVector.y; - - if ( v != 0 ) - { - zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); - - zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; - } - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Direct_Move_Orig */ - /* */ - /* <Description> */ - /* Moves the *original* position of a point by a given distance along */ - /* the freedom vector. Obviously, the point will not be `touched'. */ - /* */ - /* <Input> */ - /* point :: The index of the point to move. */ - /* */ - /* distance :: The distance to apply. */ - /* */ - /* <InOut> */ - /* zone :: The affected glyph zone. */ - /* */ - static void - Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_F26Dot6 v; - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - v = CUR.GS.freeVector.x; - - if ( v != 0 ) - zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); - - v = CUR.GS.freeVector.y; - - if ( v != 0 ) - zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); - } - - - /*************************************************************************/ - /* */ - /* Special versions of Direct_Move() */ - /* */ - /* The following versions are used whenever both vectors are both */ - /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ - /* */ - /*************************************************************************/ - - - static void - Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_UNUSED_EXEC; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - !CUR.ignore_x_mode ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - zone->cur[point].x += distance; - - zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; - } - - - static void - Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_UNUSED_EXEC; - - zone->cur[point].y += distance; - zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; - } - - - /*************************************************************************/ - /* */ - /* Special versions of Direct_Move_Orig() */ - /* */ - /* The following versions are used whenever both vectors are both */ - /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ - /* */ - /*************************************************************************/ - - - static void - Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_UNUSED_EXEC; - - zone->org[point].x += distance; - } - - - static void - Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_UNUSED_EXEC; - - zone->org[point].y += distance; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Round_None */ - /* */ - /* <Description> */ - /* Does not round, but adds engine compensation. */ - /* */ - /* <Input> */ - /* distance :: The distance (not) to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* <Return> */ - /* The compensated distance. */ - /* */ - /* <Note> */ - /* The TrueType specification says very few about the relationship */ - /* between rounding and engine compensation. However, it seems from */ - /* the description of super round that we should add the compensation */ - /* before rounding. */ - /* */ - static FT_F26Dot6 - Round_None( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation; - if ( distance && val < 0 ) - val = 0; - } - else - { - val = distance - compensation; - if ( val > 0 ) - val = 0; - } - return val; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Round_To_Grid */ - /* */ - /* <Description> */ - /* Rounds value to grid after adding engine compensation. */ - /* */ - /* <Input> */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation + 32; - if ( distance && val > 0 ) - val &= ~63; - else - val = 0; - } - else - { - val = -FT_PIX_ROUND( compensation - distance ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Round_To_Half_Grid */ - /* */ - /* <Description> */ - /* Rounds value to half grid after adding engine compensation. */ - /* */ - /* <Input> */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = FT_PIX_FLOOR( distance + compensation ) + 32; - if ( distance && val < 0 ) - val = 0; - } - else - { - val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Round_Down_To_Grid */ - /* */ - /* <Description> */ - /* Rounds value down to grid after adding engine compensation. */ - /* */ - /* <Input> */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation; - if ( distance && val > 0 ) - val &= ~63; - else - val = 0; - } - else - { - val = -( ( compensation - distance ) & -64 ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Round_Up_To_Grid */ - /* */ - /* <Description> */ - /* Rounds value up to grid after adding engine compensation. */ - /* */ - /* <Input> */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation + 63; - if ( distance && val > 0 ) - val &= ~63; - else - val = 0; - } - else - { - val = -FT_PIX_CEIL( compensation - distance ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Round_To_Double_Grid */ - /* */ - /* <Description> */ - /* Rounds value to double grid after adding engine compensation. */ - /* */ - /* <Input> */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation + 16; - if ( distance && val > 0 ) - val &= ~31; - else - val = 0; - } - else - { - val = -FT_PAD_ROUND( compensation - distance, 32 ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Round_Super */ - /* */ - /* <Description> */ - /* Super-rounds value to grid after adding engine compensation. */ - /* */ - /* <Input> */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - /* <Note> */ - /* The TrueType specification says very few about the relationship */ - /* between rounding and engine compensation. However, it seems from */ - /* the description of super round that we should add the compensation */ - /* before rounding. */ - /* */ - static FT_F26Dot6 - Round_Super( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - - if ( distance >= 0 ) - { - val = ( distance - CUR.phase + CUR.threshold + compensation ) & - -CUR.period; - if ( distance && val < 0 ) - val = 0; - val += CUR.phase; - } - else - { - val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & - -CUR.period ); - if ( val > 0 ) - val = 0; - val -= CUR.phase; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Round_Super_45 */ - /* */ - /* <Description> */ - /* Super-rounds value to grid after adding engine compensation. */ - /* */ - /* <Input> */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - /* <Note> */ - /* There is a separate function for Round_Super_45() as we may need */ - /* greater precision. */ - /* */ - static FT_F26Dot6 - Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - - if ( distance >= 0 ) - { - val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / - CUR.period ) * CUR.period; - if ( distance && val < 0 ) - val = 0; - val += CUR.phase; - } - else - { - val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / - CUR.period ) * CUR.period ); - if ( val > 0 ) - val = 0; - val -= CUR.phase; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Compute_Round */ - /* */ - /* <Description> */ - /* Sets the rounding mode. */ - /* */ - /* <Input> */ - /* round_mode :: The rounding mode to be used. */ - /* */ - static void - Compute_Round( EXEC_OP_ FT_Byte round_mode ) - { - switch ( round_mode ) - { - case TT_Round_Off: - CUR.func_round = (TT_Round_Func)Round_None; - break; - - case TT_Round_To_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Grid; - break; - - case TT_Round_Up_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; - break; - - case TT_Round_Down_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; - break; - - case TT_Round_To_Half_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; - break; - - case TT_Round_To_Double_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; - break; - - case TT_Round_Super: - CUR.func_round = (TT_Round_Func)Round_Super; - break; - - case TT_Round_Super_45: - CUR.func_round = (TT_Round_Func)Round_Super_45; - break; - } - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* SetSuperRound */ - /* */ - /* <Description> */ - /* Sets Super Round parameters. */ - /* */ - /* <Input> */ - /* GridPeriod :: The grid period. */ - /* */ - /* selector :: The SROUND opcode. */ - /* */ - static void - SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, - FT_Long selector ) - { - switch ( (FT_Int)( selector & 0xC0 ) ) - { - case 0: - CUR.period = GridPeriod / 2; - break; - - case 0x40: - CUR.period = GridPeriod; - break; - - case 0x80: - CUR.period = GridPeriod * 2; - break; - - /* This opcode is reserved, but... */ - - case 0xC0: - CUR.period = GridPeriod; - break; - } - - switch ( (FT_Int)( selector & 0x30 ) ) - { - case 0: - CUR.phase = 0; - break; - - case 0x10: - CUR.phase = CUR.period / 4; - break; - - case 0x20: - CUR.phase = CUR.period / 2; - break; - - case 0x30: - CUR.phase = CUR.period * 3 / 4; - break; - } - - if ( ( selector & 0x0F ) == 0 ) - CUR.threshold = CUR.period - 1; - else - CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; - - CUR.period /= 256; - CUR.phase /= 256; - CUR.threshold /= 256; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Project */ - /* */ - /* <Description> */ - /* Computes the projection of vector given by (v2-v1) along the */ - /* current projection vector. */ - /* */ - /* <Input> */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* <Return> */ - /* The distance in F26dot6 format. */ - /* */ - static FT_F26Dot6 - Project( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) - { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, - CUR.GS.projVector.x, - CUR.GS.projVector.y ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Dual_Project */ - /* */ - /* <Description> */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* current dual vector. */ - /* */ - /* <Input> */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* <Return> */ - /* The distance in F26dot6 format. */ - /* */ - static FT_F26Dot6 - Dual_Project( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) - { - return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, - CUR.GS.dualVector.x, - CUR.GS.dualVector.y ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Project_x */ - /* */ - /* <Description> */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* horizontal axis. */ - /* */ - /* <Input> */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* <Return> */ - /* The distance in F26dot6 format. */ - /* */ - static FT_F26Dot6 - Project_x( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) - { - FT_UNUSED_EXEC; - FT_UNUSED( dy ); - - return dx; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Project_y */ - /* */ - /* <Description> */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* vertical axis. */ - /* */ - /* <Input> */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* <Return> */ - /* The distance in F26dot6 format. */ - /* */ - static FT_F26Dot6 - Project_y( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) - { - FT_UNUSED_EXEC; - FT_UNUSED( dx ); - - return dy; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Compute_Funcs */ - /* */ - /* <Description> */ - /* Computes the projection and movement function pointers according */ - /* to the current graphics state. */ - /* */ - static void - Compute_Funcs( EXEC_OP ) - { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - /* If both vectors point rightwards along the x axis, set */ - /* `both-x-axis' true, otherwise set it false. The x values only */ - /* need be tested because the vector has been normalised to a unit */ - /* vector of length 0x4000 = unity. */ - CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 && - CUR.GS.freeVector.x == 0x4000 ); - - /* Throw away projection and freedom vector information */ - /* because the patents don't allow them to be stored. */ - /* The relevant US Patents are 5155805 and 5325479. */ - CUR.GS.projVector.x = 0; - CUR.GS.projVector.y = 0; - CUR.GS.freeVector.x = 0; - CUR.GS.freeVector.y = 0; - - if ( CUR.GS.both_x_axis ) - { - CUR.func_project = Project_x; - CUR.func_move = Direct_Move_X; - CUR.func_move_orig = Direct_Move_Orig_X; - } - else - { - CUR.func_project = Project_y; - CUR.func_move = Direct_Move_Y; - CUR.func_move_orig = Direct_Move_Orig_Y; - } - - if ( CUR.GS.dualVector.x == 0x4000 ) - CUR.func_dualproj = Project_x; - else if ( CUR.GS.dualVector.y == 0x4000 ) - CUR.func_dualproj = Project_y; - else - CUR.func_dualproj = Dual_Project; - - /* Force recalculation of cached aspect ratio */ - CUR.tt_metrics.ratio = 0; - - return; - } -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - if ( CUR.GS.freeVector.x == 0x4000 ) - CUR.F_dot_P = CUR.GS.projVector.x; - else if ( CUR.GS.freeVector.y == 0x4000 ) - CUR.F_dot_P = CUR.GS.projVector.y; - else - CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x + - (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >> - 14; - - if ( CUR.GS.projVector.x == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_x; - else if ( CUR.GS.projVector.y == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_y; - else - CUR.func_project = (TT_Project_Func)Project; - - if ( CUR.GS.dualVector.x == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_x; - else if ( CUR.GS.dualVector.y == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_y; - else - CUR.func_dualproj = (TT_Project_Func)Dual_Project; - - CUR.func_move = (TT_Move_Func)Direct_Move; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; - - if ( CUR.F_dot_P == 0x4000L ) - { - if ( CUR.GS.freeVector.x == 0x4000 ) - { - CUR.func_move = (TT_Move_Func)Direct_Move_X; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; - } - else if ( CUR.GS.freeVector.y == 0x4000 ) - { - CUR.func_move = (TT_Move_Func)Direct_Move_Y; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; - } - } - - /* at small sizes, F_dot_P can become too small, resulting */ - /* in overflows and `spikes' in a number of glyphs like `w'. */ - - if ( FT_ABS( CUR.F_dot_P ) < 0x400L ) - CUR.F_dot_P = 0x4000L; - - /* Disable cached aspect ratio */ - CUR.tt_metrics.ratio = 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Normalize */ - /* */ - /* <Description> */ - /* Norms a vector. */ - /* */ - /* <Input> */ - /* Vx :: The horizontal input vector coordinate. */ - /* Vy :: The vertical input vector coordinate. */ - /* */ - /* <Output> */ - /* R :: The normed unit vector. */ - /* */ - /* <Return> */ - /* Returns FAILURE if a vector parameter is zero. */ - /* */ - /* <Note> */ - /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ - /* R is undefined. */ - /* */ - static FT_Bool - Normalize( EXEC_OP_ FT_F26Dot6 Vx, - FT_F26Dot6 Vy, - FT_UnitVector* R ) - { - FT_F26Dot6 W; - - FT_UNUSED_EXEC; - - - if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L ) - { - if ( Vx == 0 && Vy == 0 ) - { - /* XXX: UNDOCUMENTED! It seems that it is possible to try */ - /* to normalize the vector (0,0). Return immediately. */ - return SUCCESS; - } - - Vx *= 0x4000; - Vy *= 0x4000; - } - - W = FT_Hypot( Vx, Vy ); - - R->x = (FT_F2Dot14)TT_DivFix14( Vx, W ); - R->y = (FT_F2Dot14)TT_DivFix14( Vy, W ); - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* Here we start with the implementation of the various opcodes. */ - /* */ - /*************************************************************************/ - - - static FT_Bool - Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, - FT_UShort aIdx2, - FT_Int aOpc, - FT_UnitVector* Vec ) - { - FT_Long A, B, C; - FT_Vector* p1; - FT_Vector* p2; - - - if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || - BOUNDS( aIdx2, CUR.zp1.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return FAILURE; - } - - p1 = CUR.zp1.cur + aIdx2; - p2 = CUR.zp2.cur + aIdx1; - - A = p1->x - p2->x; - B = p1->y - p2->y; - - /* If p1 == p2, SPVTL and SFVTL behave the same as */ - /* SPVTCA[X] and SFVTCA[X], respectively. */ - /* */ - /* Confirmed by Greg Hitchcock. */ - - if ( A == 0 && B == 0 ) - { - A = 0x4000; - aOpc = 0; - } - - if ( ( aOpc & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, Vec ); - - return SUCCESS; - } - - - /* When not using the big switch statements, the interpreter uses a */ - /* call table defined later below in this source. Each opcode must */ - /* thus have a corresponding function, even trivial ones. */ - /* */ - /* They are all defined there. */ - -#define DO_SVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.projVector.x = A; \ - CUR.GS.dualVector.x = A; \ - \ - CUR.GS.freeVector.y = B; \ - CUR.GS.projVector.y = B; \ - CUR.GS.dualVector.y = B; \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.projVector.x = A; \ - CUR.GS.dualVector.x = A; \ - \ - CUR.GS.projVector.y = B; \ - CUR.GS.dualVector.y = B; \ - \ - GUESS_VECTOR( freeVector ); \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.freeVector.y = B; \ - \ - GUESS_VECTOR( projVector ); \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.projVector ) == SUCCESS ) \ - { \ - CUR.GS.dualVector = CUR.GS.projVector; \ - GUESS_VECTOR( freeVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.freeVector ) == SUCCESS ) \ - { \ - GUESS_VECTOR( projVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTPV \ - GUESS_VECTOR( projVector ); \ - CUR.GS.freeVector = CUR.GS.projVector; \ - COMPUTE_Funcs(); - - -#define DO_SPVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = (FT_Long)S; \ - \ - NORMalize( X, Y, &CUR.GS.projVector ); \ - \ - CUR.GS.dualVector = CUR.GS.projVector; \ - GUESS_VECTOR( freeVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = S; \ - \ - NORMalize( X, Y, &CUR.GS.freeVector ); \ - GUESS_VECTOR( projVector ); \ - COMPUTE_Funcs(); \ - } - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define DO_GPV \ - if ( CUR.face->unpatented_hinting ) \ - { \ - args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ - args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ - } \ - else \ - { \ - args[0] = CUR.GS.projVector.x; \ - args[1] = CUR.GS.projVector.y; \ - } -#else -#define DO_GPV \ - args[0] = CUR.GS.projVector.x; \ - args[1] = CUR.GS.projVector.y; -#endif - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define DO_GFV \ - if ( CUR.face->unpatented_hinting ) \ - { \ - args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ - args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ - } \ - else \ - { \ - args[0] = CUR.GS.freeVector.x; \ - args[1] = CUR.GS.freeVector.y; \ - } -#else -#define DO_GFV \ - args[0] = CUR.GS.freeVector.x; \ - args[1] = CUR.GS.freeVector.y; -#endif - - -#define DO_SRP0 \ - CUR.GS.rp0 = (FT_UShort)args[0]; - - -#define DO_SRP1 \ - CUR.GS.rp1 = (FT_UShort)args[0]; - - -#define DO_SRP2 \ - CUR.GS.rp2 = (FT_UShort)args[0]; - - -#define DO_RTHG \ - CUR.GS.round_state = TT_Round_To_Half_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; - - -#define DO_RTG \ - CUR.GS.round_state = TT_Round_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Grid; - - -#define DO_RTDG \ - CUR.GS.round_state = TT_Round_To_Double_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; - - -#define DO_RUTG \ - CUR.GS.round_state = TT_Round_Up_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; - - -#define DO_RDTG \ - CUR.GS.round_state = TT_Round_Down_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; - - -#define DO_ROFF \ - CUR.GS.round_state = TT_Round_Off; \ - CUR.func_round = (TT_Round_Func)Round_None; - - -#define DO_SROUND \ - SET_SuperRound( 0x4000, args[0] ); \ - CUR.GS.round_state = TT_Round_Super; \ - CUR.func_round = (TT_Round_Func)Round_Super; - - -#define DO_S45ROUND \ - SET_SuperRound( 0x2D41, args[0] ); \ - CUR.GS.round_state = TT_Round_Super_45; \ - CUR.func_round = (TT_Round_Func)Round_Super_45; - - -#define DO_SLOOP \ - if ( args[0] < 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - else \ - CUR.GS.loop = args[0]; - - -#define DO_SMD \ - CUR.GS.minimum_distance = args[0]; - - -#define DO_SCVTCI \ - CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; - - -#define DO_SSWCI \ - CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; - - -#define DO_SSW \ - CUR.GS.single_width_value = FT_MulFix( args[0], \ - CUR.tt_metrics.scale ); - - -#define DO_FLIPON \ - CUR.GS.auto_flip = TRUE; - - -#define DO_FLIPOFF \ - CUR.GS.auto_flip = FALSE; - - -#define DO_SDB \ - CUR.GS.delta_base = (FT_Short)args[0]; - - -#define DO_SDS \ - CUR.GS.delta_shift = (FT_Short)args[0]; - - -#define DO_MD /* nothing */ - - -#define DO_MPPEM \ - args[0] = CURRENT_Ppem(); - - - /* Note: The pointSize should be irrelevant in a given font program; */ - /* we thus decide to return only the ppem. */ -#if 0 - -#define DO_MPS \ - args[0] = CUR.metrics.pointSize; - -#else - -#define DO_MPS \ - args[0] = CURRENT_Ppem(); - -#endif /* 0 */ - - -#define DO_DUP \ - args[1] = args[0]; - - -#define DO_CLEAR \ - CUR.new_top = 0; - - -#define DO_SWAP \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - args[0] = args[1]; \ - args[1] = L; \ - } - - -#define DO_DEPTH \ - args[0] = CUR.top; - - -#define DO_CINDEX \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - \ - if ( L <= 0 || L > CUR.args ) \ - { \ - if ( CUR.pedantic_hinting ) \ - CUR.error = FT_THROW( Invalid_Reference ); \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR.stack[CUR.args - L]; \ - } - - -#define DO_JROT \ - if ( args[1] != 0 ) \ - { \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; \ - } - - -#define DO_JMPR \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; - - -#define DO_JROF \ - if ( args[1] == 0 ) \ - { \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; \ - } - - -#define DO_LT \ - args[0] = ( args[0] < args[1] ); - - -#define DO_LTEQ \ - args[0] = ( args[0] <= args[1] ); - - -#define DO_GT \ - args[0] = ( args[0] > args[1] ); - - -#define DO_GTEQ \ - args[0] = ( args[0] >= args[1] ); - - -#define DO_EQ \ - args[0] = ( args[0] == args[1] ); - - -#define DO_NEQ \ - args[0] = ( args[0] != args[1] ); - - -#define DO_ODD \ - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); - - -#define DO_EVEN \ - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); - - -#define DO_AND \ - args[0] = ( args[0] && args[1] ); - - -#define DO_OR \ - args[0] = ( args[0] || args[1] ); - - -#define DO_NOT \ - args[0] = !args[0]; - - -#define DO_ADD \ - args[0] += args[1]; - - -#define DO_SUB \ - args[0] -= args[1]; - - -#define DO_DIV \ - if ( args[1] == 0 ) \ - CUR.error = FT_THROW( Divide_By_Zero ); \ - else \ - args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); - - -#define DO_MUL \ - args[0] = FT_MulDiv( args[0], args[1], 64L ); - - -#define DO_ABS \ - args[0] = FT_ABS( args[0] ); - - -#define DO_NEG \ - args[0] = -args[0]; - - -#define DO_FLOOR \ - args[0] = FT_PIX_FLOOR( args[0] ); - - -#define DO_CEILING \ - args[0] = FT_PIX_CEIL( args[0] ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - -#define DO_RS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - ARRAY_BOUND_ERROR; \ - else \ - args[0] = 0; \ - } \ - else \ - { \ - /* subpixel hinting - avoid Typeman Dstroke and */ \ - /* IStroke and Vacuform rounds */ \ - \ - if ( SUBPIXEL_HINTING && \ - CUR.ignore_x_mode && \ - ( ( I == 24 && \ - ( CUR.face->sph_found_func_flags & \ - ( SPH_FDEF_SPACING_1 | \ - SPH_FDEF_SPACING_2 ) ) ) || \ - ( I == 22 && \ - ( CUR.sph_in_func_flags & \ - SPH_FDEF_TYPEMAN_STROKES ) ) || \ - ( I == 8 && \ - ( CUR.face->sph_found_func_flags & \ - SPH_FDEF_VACUFORM_ROUND_1 ) && \ - CUR.iup_called ) ) ) \ - args[0] = 0; \ - else \ - args[0] = CUR.storage[I]; \ - } \ - } - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - -#define DO_RS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - else \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR.storage[I]; \ - } - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#define DO_WS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.storage[I] = args[1]; \ - } - - -#define DO_RCVT \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - else \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR_Func_read_cvt( I ); \ - } - - -#define DO_WCVTP \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR_Func_write_cvt( I, args[1] ); \ - } - - -#define DO_WCVTF \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \ - } - - -#define DO_DEBUG \ - CUR.error = FT_THROW( Debug_OpCode ); - - -#define DO_ROUND \ - args[0] = CUR_Func_round( \ - args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); - - -#define DO_NROUND \ - args[0] = ROUND_None( args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); - - -#define DO_MAX \ - if ( args[1] > args[0] ) \ - args[0] = args[1]; - - -#define DO_MIN \ - if ( args[1] < args[0] ) \ - args[0] = args[1]; - - -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - -#undef ARRAY_BOUND_ERROR -#define ARRAY_BOUND_ERROR \ - { \ - CUR.error = FT_THROW( Invalid_Reference ); \ - return; \ - } - - - /*************************************************************************/ - /* */ - /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ - /* Opcode range: 0x00-0x01 */ - /* Stack: --> */ - /* */ - static void - Ins_SVTCA( INS_ARG ) - { - DO_SVTCA - } - - - /*************************************************************************/ - /* */ - /* SPVTCA[a]: Set PVector to Coordinate Axis */ - /* Opcode range: 0x02-0x03 */ - /* Stack: --> */ - /* */ - static void - Ins_SPVTCA( INS_ARG ) - { - DO_SPVTCA - } - - - /*************************************************************************/ - /* */ - /* SFVTCA[a]: Set FVector to Coordinate Axis */ - /* Opcode range: 0x04-0x05 */ - /* Stack: --> */ - /* */ - static void - Ins_SFVTCA( INS_ARG ) - { - DO_SFVTCA - } - - - /*************************************************************************/ - /* */ - /* SPVTL[a]: Set PVector To Line */ - /* Opcode range: 0x06-0x07 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_SPVTL( INS_ARG ) - { - DO_SPVTL - } - - - /*************************************************************************/ - /* */ - /* SFVTL[a]: Set FVector To Line */ - /* Opcode range: 0x08-0x09 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_SFVTL( INS_ARG ) - { - DO_SFVTL - } - - - /*************************************************************************/ - /* */ - /* SFVTPV[]: Set FVector To PVector */ - /* Opcode range: 0x0E */ - /* Stack: --> */ - /* */ - static void - Ins_SFVTPV( INS_ARG ) - { - DO_SFVTPV - } - - - /*************************************************************************/ - /* */ - /* SPVFS[]: Set PVector From Stack */ - /* Opcode range: 0x0A */ - /* Stack: f2.14 f2.14 --> */ - /* */ - static void - Ins_SPVFS( INS_ARG ) - { - DO_SPVFS - } - - - /*************************************************************************/ - /* */ - /* SFVFS[]: Set FVector From Stack */ - /* Opcode range: 0x0B */ - /* Stack: f2.14 f2.14 --> */ - /* */ - static void - Ins_SFVFS( INS_ARG ) - { - DO_SFVFS - } - - - /*************************************************************************/ - /* */ - /* GPV[]: Get Projection Vector */ - /* Opcode range: 0x0C */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ - static void - Ins_GPV( INS_ARG ) - { - DO_GPV - } - - - /*************************************************************************/ - /* GFV[]: Get Freedom Vector */ - /* Opcode range: 0x0D */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ - static void - Ins_GFV( INS_ARG ) - { - DO_GFV - } - - - /*************************************************************************/ - /* */ - /* SRP0[]: Set Reference Point 0 */ - /* Opcode range: 0x10 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SRP0( INS_ARG ) - { - DO_SRP0 - } - - - /*************************************************************************/ - /* */ - /* SRP1[]: Set Reference Point 1 */ - /* Opcode range: 0x11 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SRP1( INS_ARG ) - { - DO_SRP1 - } - - - /*************************************************************************/ - /* */ - /* SRP2[]: Set Reference Point 2 */ - /* Opcode range: 0x12 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SRP2( INS_ARG ) - { - DO_SRP2 - } - - - /*************************************************************************/ - /* */ - /* RTHG[]: Round To Half Grid */ - /* Opcode range: 0x19 */ - /* Stack: --> */ - /* */ - static void - Ins_RTHG( INS_ARG ) - { - DO_RTHG - } - - - /*************************************************************************/ - /* */ - /* RTG[]: Round To Grid */ - /* Opcode range: 0x18 */ - /* Stack: --> */ - /* */ - static void - Ins_RTG( INS_ARG ) - { - DO_RTG - } - - - /*************************************************************************/ - /* RTDG[]: Round To Double Grid */ - /* Opcode range: 0x3D */ - /* Stack: --> */ - /* */ - static void - Ins_RTDG( INS_ARG ) - { - DO_RTDG - } - - - /*************************************************************************/ - /* RUTG[]: Round Up To Grid */ - /* Opcode range: 0x7C */ - /* Stack: --> */ - /* */ - static void - Ins_RUTG( INS_ARG ) - { - DO_RUTG - } - - - /*************************************************************************/ - /* */ - /* RDTG[]: Round Down To Grid */ - /* Opcode range: 0x7D */ - /* Stack: --> */ - /* */ - static void - Ins_RDTG( INS_ARG ) - { - DO_RDTG - } - - - /*************************************************************************/ - /* */ - /* ROFF[]: Round OFF */ - /* Opcode range: 0x7A */ - /* Stack: --> */ - /* */ - static void - Ins_ROFF( INS_ARG ) - { - DO_ROFF - } - - - /*************************************************************************/ - /* */ - /* SROUND[]: Super ROUND */ - /* Opcode range: 0x76 */ - /* Stack: Eint8 --> */ - /* */ - static void - Ins_SROUND( INS_ARG ) - { - DO_SROUND - } - - - /*************************************************************************/ - /* */ - /* S45ROUND[]: Super ROUND 45 degrees */ - /* Opcode range: 0x77 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_S45ROUND( INS_ARG ) - { - DO_S45ROUND - } - - - /*************************************************************************/ - /* */ - /* SLOOP[]: Set LOOP variable */ - /* Opcode range: 0x17 */ - /* Stack: int32? --> */ - /* */ - static void - Ins_SLOOP( INS_ARG ) - { - DO_SLOOP - } - - - /*************************************************************************/ - /* */ - /* SMD[]: Set Minimum Distance */ - /* Opcode range: 0x1A */ - /* Stack: f26.6 --> */ - /* */ - static void - Ins_SMD( INS_ARG ) - { - DO_SMD - } - - - /*************************************************************************/ - /* */ - /* SCVTCI[]: Set Control Value Table Cut In */ - /* Opcode range: 0x1D */ - /* Stack: f26.6 --> */ - /* */ - static void - Ins_SCVTCI( INS_ARG ) - { - DO_SCVTCI - } - - - /*************************************************************************/ - /* */ - /* SSWCI[]: Set Single Width Cut In */ - /* Opcode range: 0x1E */ - /* Stack: f26.6 --> */ - /* */ - static void - Ins_SSWCI( INS_ARG ) - { - DO_SSWCI - } - - - /*************************************************************************/ - /* */ - /* SSW[]: Set Single Width */ - /* Opcode range: 0x1F */ - /* Stack: int32? --> */ - /* */ - static void - Ins_SSW( INS_ARG ) - { - DO_SSW - } - - - /*************************************************************************/ - /* */ - /* FLIPON[]: Set auto-FLIP to ON */ - /* Opcode range: 0x4D */ - /* Stack: --> */ - /* */ - static void - Ins_FLIPON( INS_ARG ) - { - DO_FLIPON - } - - - /*************************************************************************/ - /* */ - /* FLIPOFF[]: Set auto-FLIP to OFF */ - /* Opcode range: 0x4E */ - /* Stack: --> */ - /* */ - static void - Ins_FLIPOFF( INS_ARG ) - { - DO_FLIPOFF - } - - - /*************************************************************************/ - /* */ - /* SANGW[]: Set ANGle Weight */ - /* Opcode range: 0x7E */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SANGW( INS_ARG ) - { - /* instruction not supported anymore */ - } - - - /*************************************************************************/ - /* */ - /* SDB[]: Set Delta Base */ - /* Opcode range: 0x5E */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SDB( INS_ARG ) - { - DO_SDB - } - - - /*************************************************************************/ - /* */ - /* SDS[]: Set Delta Shift */ - /* Opcode range: 0x5F */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SDS( INS_ARG ) - { - DO_SDS - } - - - /*************************************************************************/ - /* */ - /* MPPEM[]: Measure Pixel Per EM */ - /* Opcode range: 0x4B */ - /* Stack: --> Euint16 */ - /* */ - static void - Ins_MPPEM( INS_ARG ) - { - DO_MPPEM - } - - - /*************************************************************************/ - /* */ - /* MPS[]: Measure Point Size */ - /* Opcode range: 0x4C */ - /* Stack: --> Euint16 */ - /* */ - static void - Ins_MPS( INS_ARG ) - { - DO_MPS - } - - - /*************************************************************************/ - /* */ - /* DUP[]: DUPlicate the top stack's element */ - /* Opcode range: 0x20 */ - /* Stack: StkElt --> StkElt StkElt */ - /* */ - static void - Ins_DUP( INS_ARG ) - { - DO_DUP - } - - - /*************************************************************************/ - /* */ - /* POP[]: POP the stack's top element */ - /* Opcode range: 0x21 */ - /* Stack: StkElt --> */ - /* */ - static void - Ins_POP( INS_ARG ) - { - /* nothing to do */ - } - - - /*************************************************************************/ - /* */ - /* CLEAR[]: CLEAR the entire stack */ - /* Opcode range: 0x22 */ - /* Stack: StkElt... --> */ - /* */ - static void - Ins_CLEAR( INS_ARG ) - { - DO_CLEAR - } - - - /*************************************************************************/ - /* */ - /* SWAP[]: SWAP the stack's top two elements */ - /* Opcode range: 0x23 */ - /* Stack: 2 * StkElt --> 2 * StkElt */ - /* */ - static void - Ins_SWAP( INS_ARG ) - { - DO_SWAP - } - - - /*************************************************************************/ - /* */ - /* DEPTH[]: return the stack DEPTH */ - /* Opcode range: 0x24 */ - /* Stack: --> uint32 */ - /* */ - static void - Ins_DEPTH( INS_ARG ) - { - DO_DEPTH - } - - - /*************************************************************************/ - /* */ - /* CINDEX[]: Copy INDEXed element */ - /* Opcode range: 0x25 */ - /* Stack: int32 --> StkElt */ - /* */ - static void - Ins_CINDEX( INS_ARG ) - { - DO_CINDEX - } - - - /*************************************************************************/ - /* */ - /* EIF[]: End IF */ - /* Opcode range: 0x59 */ - /* Stack: --> */ - /* */ - static void - Ins_EIF( INS_ARG ) - { - /* nothing to do */ - } - - - /*************************************************************************/ - /* */ - /* JROT[]: Jump Relative On True */ - /* Opcode range: 0x78 */ - /* Stack: StkElt int32 --> */ - /* */ - static void - Ins_JROT( INS_ARG ) - { - DO_JROT - } - - - /*************************************************************************/ - /* */ - /* JMPR[]: JuMP Relative */ - /* Opcode range: 0x1C */ - /* Stack: int32 --> */ - /* */ - static void - Ins_JMPR( INS_ARG ) - { - DO_JMPR - } - - - /*************************************************************************/ - /* */ - /* JROF[]: Jump Relative On False */ - /* Opcode range: 0x79 */ - /* Stack: StkElt int32 --> */ - /* */ - static void - Ins_JROF( INS_ARG ) - { - DO_JROF - } - - - /*************************************************************************/ - /* */ - /* LT[]: Less Than */ - /* Opcode range: 0x50 */ - /* Stack: int32? int32? --> bool */ - /* */ - static void - Ins_LT( INS_ARG ) - { - DO_LT - } - - - /*************************************************************************/ - /* */ - /* LTEQ[]: Less Than or EQual */ - /* Opcode range: 0x51 */ - /* Stack: int32? int32? --> bool */ - /* */ - static void - Ins_LTEQ( INS_ARG ) - { - DO_LTEQ - } - - - /*************************************************************************/ - /* */ - /* GT[]: Greater Than */ - /* Opcode range: 0x52 */ - /* Stack: int32? int32? --> bool */ - /* */ - static void - Ins_GT( INS_ARG ) - { - DO_GT - } - - - /*************************************************************************/ - /* */ - /* GTEQ[]: Greater Than or EQual */ - /* Opcode range: 0x53 */ - /* Stack: int32? int32? --> bool */ - /* */ - static void - Ins_GTEQ( INS_ARG ) - { - DO_GTEQ - } - - - /*************************************************************************/ - /* */ - /* EQ[]: EQual */ - /* Opcode range: 0x54 */ - /* Stack: StkElt StkElt --> bool */ - /* */ - static void - Ins_EQ( INS_ARG ) - { - DO_EQ - } - - - /*************************************************************************/ - /* */ - /* NEQ[]: Not EQual */ - /* Opcode range: 0x55 */ - /* Stack: StkElt StkElt --> bool */ - /* */ - static void - Ins_NEQ( INS_ARG ) - { - DO_NEQ - } - - - /*************************************************************************/ - /* */ - /* ODD[]: Is ODD */ - /* Opcode range: 0x56 */ - /* Stack: f26.6 --> bool */ - /* */ - static void - Ins_ODD( INS_ARG ) - { - DO_ODD - } - - - /*************************************************************************/ - /* */ - /* EVEN[]: Is EVEN */ - /* Opcode range: 0x57 */ - /* Stack: f26.6 --> bool */ - /* */ - static void - Ins_EVEN( INS_ARG ) - { - DO_EVEN - } - - - /*************************************************************************/ - /* */ - /* AND[]: logical AND */ - /* Opcode range: 0x5A */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ - static void - Ins_AND( INS_ARG ) - { - DO_AND - } - - - /*************************************************************************/ - /* */ - /* OR[]: logical OR */ - /* Opcode range: 0x5B */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ - static void - Ins_OR( INS_ARG ) - { - DO_OR - } - - - /*************************************************************************/ - /* */ - /* NOT[]: logical NOT */ - /* Opcode range: 0x5C */ - /* Stack: StkElt --> uint32 */ - /* */ - static void - Ins_NOT( INS_ARG ) - { - DO_NOT - } - - - /*************************************************************************/ - /* */ - /* ADD[]: ADD */ - /* Opcode range: 0x60 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static void - Ins_ADD( INS_ARG ) - { - DO_ADD - } - - - /*************************************************************************/ - /* */ - /* SUB[]: SUBtract */ - /* Opcode range: 0x61 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static void - Ins_SUB( INS_ARG ) - { - DO_SUB - } - - - /*************************************************************************/ - /* */ - /* DIV[]: DIVide */ - /* Opcode range: 0x62 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static void - Ins_DIV( INS_ARG ) - { - DO_DIV - } - - - /*************************************************************************/ - /* */ - /* MUL[]: MULtiply */ - /* Opcode range: 0x63 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static void - Ins_MUL( INS_ARG ) - { - DO_MUL - } - - - /*************************************************************************/ - /* */ - /* ABS[]: ABSolute value */ - /* Opcode range: 0x64 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static void - Ins_ABS( INS_ARG ) - { - DO_ABS - } - - - /*************************************************************************/ - /* */ - /* NEG[]: NEGate */ - /* Opcode range: 0x65 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static void - Ins_NEG( INS_ARG ) - { - DO_NEG - } - - - /*************************************************************************/ - /* */ - /* FLOOR[]: FLOOR */ - /* Opcode range: 0x66 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static void - Ins_FLOOR( INS_ARG ) - { - DO_FLOOR - } - - - /*************************************************************************/ - /* */ - /* CEILING[]: CEILING */ - /* Opcode range: 0x67 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static void - Ins_CEILING( INS_ARG ) - { - DO_CEILING - } - - - /*************************************************************************/ - /* */ - /* RS[]: Read Store */ - /* Opcode range: 0x43 */ - /* Stack: uint32 --> uint32 */ - /* */ - static void - Ins_RS( INS_ARG ) - { - DO_RS - } - - - /*************************************************************************/ - /* */ - /* WS[]: Write Store */ - /* Opcode range: 0x42 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_WS( INS_ARG ) - { - DO_WS - } - - - /*************************************************************************/ - /* */ - /* WCVTP[]: Write CVT in Pixel units */ - /* Opcode range: 0x44 */ - /* Stack: f26.6 uint32 --> */ - /* */ - static void - Ins_WCVTP( INS_ARG ) - { - DO_WCVTP - } - - - /*************************************************************************/ - /* */ - /* WCVTF[]: Write CVT in Funits */ - /* Opcode range: 0x70 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_WCVTF( INS_ARG ) - { - DO_WCVTF - } - - - /*************************************************************************/ - /* */ - /* RCVT[]: Read CVT */ - /* Opcode range: 0x45 */ - /* Stack: uint32 --> f26.6 */ - /* */ - static void - Ins_RCVT( INS_ARG ) - { - DO_RCVT - } - - - /*************************************************************************/ - /* */ - /* AA[]: Adjust Angle */ - /* Opcode range: 0x7F */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_AA( INS_ARG ) - { - /* intentionally no longer supported */ - } - - - /*************************************************************************/ - /* */ - /* DEBUG[]: DEBUG. Unsupported. */ - /* Opcode range: 0x4F */ - /* Stack: uint32 --> */ - /* */ - /* Note: The original instruction pops a value from the stack. */ - /* */ - static void - Ins_DEBUG( INS_ARG ) - { - DO_DEBUG - } - - - /*************************************************************************/ - /* */ - /* ROUND[ab]: ROUND value */ - /* Opcode range: 0x68-0x6B */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static void - Ins_ROUND( INS_ARG ) - { - DO_ROUND - } - - - /*************************************************************************/ - /* */ - /* NROUND[ab]: No ROUNDing of value */ - /* Opcode range: 0x6C-0x6F */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static void - Ins_NROUND( INS_ARG ) - { - DO_NROUND - } - - - /*************************************************************************/ - /* */ - /* MAX[]: MAXimum */ - /* Opcode range: 0x68 */ - /* Stack: int32? int32? --> int32 */ - /* */ - static void - Ins_MAX( INS_ARG ) - { - DO_MAX - } - - - /*************************************************************************/ - /* */ - /* MIN[]: MINimum */ - /* Opcode range: 0x69 */ - /* Stack: int32? int32? --> int32 */ - /* */ - static void - Ins_MIN( INS_ARG ) - { - DO_MIN - } - - -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - - /*************************************************************************/ - /* */ - /* The following functions are called as is within the switch statement. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* MINDEX[]: Move INDEXed element */ - /* Opcode range: 0x26 */ - /* Stack: int32? --> StkElt */ - /* */ - static void - Ins_MINDEX( INS_ARG ) - { - FT_Long L, K; - - - L = args[0]; - - if ( L <= 0 || L > CUR.args ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - } - else - { - K = CUR.stack[CUR.args - L]; - - FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], - &CUR.stack[CUR.args - L + 1], - ( L - 1 ) ); - - CUR.stack[CUR.args - 1] = K; - } - } - - - /*************************************************************************/ - /* */ - /* ROLL[]: ROLL top three elements */ - /* Opcode range: 0x8A */ - /* Stack: 3 * StkElt --> 3 * StkElt */ - /* */ - static void - Ins_ROLL( INS_ARG ) - { - FT_Long A, B, C; - - FT_UNUSED_EXEC; - - - A = args[2]; - B = args[1]; - C = args[0]; - - args[2] = C; - args[1] = A; - args[0] = B; - } - - - /*************************************************************************/ - /* */ - /* MANAGING THE FLOW OF CONTROL */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - static FT_Bool - SkipCode( EXEC_OP ) - { - CUR.IP += CUR.length; - - if ( CUR.IP < CUR.codeSize ) - { - CUR.opcode = CUR.code[CUR.IP]; - - CUR.length = opcode_length[CUR.opcode]; - if ( CUR.length < 0 ) - { - if ( CUR.IP + 1 >= CUR.codeSize ) - goto Fail_Overflow; - CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; - } - - if ( CUR.IP + CUR.length <= CUR.codeSize ) - return SUCCESS; - } - - Fail_Overflow: - CUR.error = FT_THROW( Code_Overflow ); - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* IF[]: IF test */ - /* Opcode range: 0x58 */ - /* Stack: StkElt --> */ - /* */ - static void - Ins_IF( INS_ARG ) - { - FT_Int nIfs; - FT_Bool Out; - - - if ( args[0] != 0 ) - return; - - nIfs = 1; - Out = 0; - - do - { - if ( SKIP_Code() == FAILURE ) - return; - - switch ( CUR.opcode ) - { - case 0x58: /* IF */ - nIfs++; - break; - - case 0x1B: /* ELSE */ - Out = FT_BOOL( nIfs == 1 ); - break; - - case 0x59: /* EIF */ - nIfs--; - Out = FT_BOOL( nIfs == 0 ); - break; - } - } while ( Out == 0 ); - } - - - /*************************************************************************/ - /* */ - /* ELSE[]: ELSE */ - /* Opcode range: 0x1B */ - /* Stack: --> */ - /* */ - static void - Ins_ELSE( INS_ARG ) - { - FT_Int nIfs; - - FT_UNUSED_ARG; - - - nIfs = 1; - - do - { - if ( SKIP_Code() == FAILURE ) - return; - - switch ( CUR.opcode ) - { - case 0x58: /* IF */ - nIfs++; - break; - - case 0x59: /* EIF */ - nIfs--; - break; - } - } while ( nIfs != 0 ); - } - - - /*************************************************************************/ - /* */ - /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* FDEF[]: Function DEFinition */ - /* Opcode range: 0x2C */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_FDEF( INS_ARG ) - { - FT_ULong n; - TT_DefRecord* rec; - TT_DefRecord* limit; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* arguments to opcodes are skipped by `SKIP_Code' */ - FT_Byte opcode_pattern[9][12] = { - /* #0 inline delta function 1 */ - { - 0x4B, /* PPEM */ - 0x53, /* GTEQ */ - 0x23, /* SWAP */ - 0x4B, /* PPEM */ - 0x51, /* LTEQ */ - 0x5A, /* AND */ - 0x58, /* IF */ - 0x38, /* SHPIX */ - 0x1B, /* ELSE */ - 0x21, /* POP */ - 0x21, /* POP */ - 0x59 /* EIF */ - }, - /* #1 inline delta function 2 */ - { - 0x4B, /* PPEM */ - 0x54, /* EQ */ - 0x58, /* IF */ - 0x38, /* SHPIX */ - 0x1B, /* ELSE */ - 0x21, /* POP */ - 0x21, /* POP */ - 0x59 /* EIF */ - }, - /* #2 diagonal stroke function */ - { - 0x20, /* DUP */ - 0x20, /* DUP */ - 0xB0, /* PUSHB_1 */ - /* 1 */ - 0x60, /* ADD */ - 0x46, /* GC_cur */ - 0xB0, /* PUSHB_1 */ - /* 64 */ - 0x23, /* SWAP */ - 0x42 /* WS */ - }, - /* #3 VacuFormRound function */ - { - 0x45, /* RCVT */ - 0x23, /* SWAP */ - 0x46, /* GC_cur */ - 0x60, /* ADD */ - 0x20, /* DUP */ - 0xB0 /* PUSHB_1 */ - /* 38 */ - }, - /* #4 TTFautohint bytecode (old) */ - { - 0x20, /* DUP */ - 0x64, /* ABS */ - 0xB0, /* PUSHB_1 */ - /* 32 */ - 0x60, /* ADD */ - 0x66, /* FLOOR */ - 0x23, /* SWAP */ - 0xB0 /* PUSHB_1 */ - }, - /* #5 spacing function 1 */ - { - 0x01, /* SVTCA_x */ - 0xB0, /* PUSHB_1 */ - /* 24 */ - 0x43, /* RS */ - 0x58 /* IF */ - }, - /* #6 spacing function 2 */ - { - 0x01, /* SVTCA_x */ - 0x18, /* RTG */ - 0xB0, /* PUSHB_1 */ - /* 24 */ - 0x43, /* RS */ - 0x58 /* IF */ - }, - /* #7 TypeMan Talk DiagEndCtrl function */ - { - 0x01, /* SVTCA_x */ - 0x20, /* DUP */ - 0xB0, /* PUSHB_1 */ - /* 3 */ - 0x25, /* CINDEX */ - }, - /* #8 TypeMan Talk Align */ - { - 0x06, /* SPVTL */ - 0x7D, /* RDTG */ - }, - }; - FT_UShort opcode_patterns = 9; - FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; - FT_UShort i; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /* some font programs are broken enough to redefine functions! */ - /* We will then parse the current table. */ - - rec = CUR.FDefs; - limit = rec + CUR.numFDefs; - n = args[0]; - - for ( ; rec < limit; rec++ ) - { - if ( rec->opc == n ) - break; - } - - if ( rec == limit ) - { - /* check that there is enough room for new functions */ - if ( CUR.numFDefs >= CUR.maxFDefs ) - { - CUR.error = FT_THROW( Too_Many_Function_Defs ); - return; - } - CUR.numFDefs++; - } - - /* Although FDEF takes unsigned 32-bit integer, */ - /* func # must be within unsigned 16-bit integer */ - if ( n > 0xFFFFU ) - { - CUR.error = FT_THROW( Too_Many_Function_Defs ); - return; - } - - rec->range = CUR.curRange; - rec->opc = (FT_UInt16)n; - rec->start = CUR.IP + 1; - rec->active = TRUE; - rec->inline_delta = FALSE; - rec->sph_fdef_flags = 0x0000; - - if ( n > CUR.maxFunc ) - CUR.maxFunc = (FT_UInt16)n; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* We don't know for sure these are typeman functions, */ - /* however they are only active when RS 22 is called */ - if ( n >= 64 && n <= 66 ) - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES; -#endif - - /* Now skip the whole function definition. */ - /* We don't allow nested IDEFS & FDEFs. */ - - while ( SKIP_Code() == SUCCESS ) - { - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( SUBPIXEL_HINTING ) - { - for ( i = 0; i < opcode_patterns; i++ ) - { - if ( opcode_pointer[i] < opcode_size[i] && - CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) - { - opcode_pointer[i] += 1; - - if ( opcode_pointer[i] == opcode_size[i] ) - { - FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n", - i, n, - CUR.face->root.family_name, - CUR.face->root.style_name )); - - switch ( i ) - { - case 0: - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; - break; - - case 1: - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; - CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; - break; - - case 2: - switch ( n ) - { - /* needs to be implemented still */ - case 58: - rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; - CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; - } - break; - - case 3: - switch ( n ) - { - case 0: - rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; - } - break; - - case 4: - /* probably not necessary to detect anymore */ - rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; - break; - - case 5: - switch ( n ) - { - case 0: - case 1: - case 2: - case 4: - case 7: - case 8: - rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1; - } - break; - - case 6: - switch ( n ) - { - case 0: - case 1: - case 2: - case 4: - case 7: - case 8: - rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; - CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2; - } - break; - - case 7: - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - break; - - case 8: -#if 0 - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; -#endif - break; - } - opcode_pointer[i] = 0; - } - } - - else - opcode_pointer[i] = 0; - } - - /* Set sph_compatibility_mode only when deltas are detected */ - CUR.face->sph_compatibility_mode = - ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | - ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); - } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - switch ( CUR.opcode ) - { - case 0x89: /* IDEF */ - case 0x2C: /* FDEF */ - CUR.error = FT_THROW( Nested_DEFS ); - return; - - case 0x2D: /* ENDF */ - rec->end = CUR.IP; - return; - } - } - } - - - /*************************************************************************/ - /* */ - /* ENDF[]: END Function definition */ - /* Opcode range: 0x2D */ - /* Stack: --> */ - /* */ - static void - Ins_ENDF( INS_ARG ) - { - TT_CallRec* pRec; - - FT_UNUSED_ARG; - - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - CUR.sph_in_func_flags = 0x0000; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ - { - CUR.error = FT_THROW( ENDF_In_Exec_Stream ); - return; - } - - CUR.callTop--; - - pRec = &CUR.callStack[CUR.callTop]; - - pRec->Cur_Count--; - - CUR.step_ins = FALSE; - - if ( pRec->Cur_Count > 0 ) - { - CUR.callTop++; - CUR.IP = pRec->Cur_Restart; - } - else - /* Loop through the current function */ - INS_Goto_CodeRange( pRec->Caller_Range, - pRec->Caller_IP ); - - /* Exit the current call frame. */ - - /* NOTE: If the last instruction of a program is a */ - /* CALL or LOOPCALL, the return address is */ - /* always out of the code range. This is a */ - /* valid address, and it is why we do not test */ - /* the result of Ins_Goto_CodeRange() here! */ - } - - - /*************************************************************************/ - /* */ - /* CALL[]: CALL function */ - /* Opcode range: 0x2B */ - /* Stack: uint32? --> */ - /* */ - static void - Ins_CALL( INS_ARG ) - { - FT_ULong F; - TT_CallRec* pCrec; - TT_DefRecord* def; - - - /* first of all, check the index */ - - F = args[0]; - if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) - goto Fail; - - /* Except for some old Apple fonts, all functions in a TrueType */ - /* font are defined in increasing order, starting from 0. This */ - /* means that we normally have */ - /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ - /* */ - /* If this isn't true, we need to look up the function table. */ - - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) - { - /* look up the FDefs table */ - TT_DefRecord* limit; - - - def = CUR.FDefs; - limit = def + CUR.numFDefs; - - while ( def < limit && def->opc != F ) - def++; - - if ( def == limit ) - goto Fail; - } - - /* check that the function is active */ - if ( !def->active ) - goto Fail; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - ( ( CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) - goto Fail; - else - CUR.sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - /* check the call stack */ - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - - pCrec = CUR.callStack + CUR.callTop; - - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; - pCrec->Cur_Count = 1; - pCrec->Cur_Restart = def->start; - pCrec->Cur_End = def->end; - - CUR.callTop++; - - INS_Goto_CodeRange( def->range, - def->start ); - - CUR.step_ins = FALSE; - - return; - - Fail: - CUR.error = FT_THROW( Invalid_Reference ); - } - - - /*************************************************************************/ - /* */ - /* LOOPCALL[]: LOOP and CALL function */ - /* Opcode range: 0x2A */ - /* Stack: uint32? Eint16? --> */ - /* */ - static void - Ins_LOOPCALL( INS_ARG ) - { - FT_ULong F; - TT_CallRec* pCrec; - TT_DefRecord* def; - - - /* first of all, check the index */ - F = args[1]; - if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) - goto Fail; - - /* Except for some old Apple fonts, all functions in a TrueType */ - /* font are defined in increasing order, starting from 0. This */ - /* means that we normally have */ - /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ - /* */ - /* If this isn't true, we need to look up the function table. */ - - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) - { - /* look up the FDefs table */ - TT_DefRecord* limit; - - - def = CUR.FDefs; - limit = def + CUR.numFDefs; - - while ( def < limit && def->opc != F ) - def++; - - if ( def == limit ) - goto Fail; - } - - /* check that the function is active */ - if ( !def->active ) - goto Fail; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) - goto Fail; - else - CUR.sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - /* check stack */ - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - - if ( args[0] > 0 ) - { - pCrec = CUR.callStack + CUR.callTop; - - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; - pCrec->Cur_Count = (FT_Int)args[0]; - pCrec->Cur_Restart = def->start; - pCrec->Cur_End = def->end; - - CUR.callTop++; - - INS_Goto_CodeRange( def->range, def->start ); - - CUR.step_ins = FALSE; - } - - return; - - Fail: - CUR.error = FT_THROW( Invalid_Reference ); - } - - - /*************************************************************************/ - /* */ - /* IDEF[]: Instruction DEFinition */ - /* Opcode range: 0x89 */ - /* Stack: Eint8 --> */ - /* */ - static void - Ins_IDEF( INS_ARG ) - { - TT_DefRecord* def; - TT_DefRecord* limit; - - - /* First of all, look for the same function in our table */ - - def = CUR.IDefs; - limit = def + CUR.numIDefs; - - for ( ; def < limit; def++ ) - if ( def->opc == (FT_ULong)args[0] ) - break; - - if ( def == limit ) - { - /* check that there is enough room for a new instruction */ - if ( CUR.numIDefs >= CUR.maxIDefs ) - { - CUR.error = FT_THROW( Too_Many_Instruction_Defs ); - return; - } - CUR.numIDefs++; - } - - /* opcode must be unsigned 8-bit integer */ - if ( 0 > args[0] || args[0] > 0x00FF ) - { - CUR.error = FT_THROW( Too_Many_Instruction_Defs ); - return; - } - - def->opc = (FT_Byte)args[0]; - def->start = CUR.IP + 1; - def->range = CUR.curRange; - def->active = TRUE; - - if ( (FT_ULong)args[0] > CUR.maxIns ) - CUR.maxIns = (FT_Byte)args[0]; - - /* Now skip the whole function definition. */ - /* We don't allow nested IDEFs & FDEFs. */ - - while ( SKIP_Code() == SUCCESS ) - { - switch ( CUR.opcode ) - { - case 0x89: /* IDEF */ - case 0x2C: /* FDEF */ - CUR.error = FT_THROW( Nested_DEFS ); - return; - case 0x2D: /* ENDF */ - return; - } - } - } - - - /*************************************************************************/ - /* */ - /* PUSHING DATA ONTO THE INTERPRETER STACK */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* NPUSHB[]: PUSH N Bytes */ - /* Opcode range: 0x40 */ - /* Stack: --> uint32... */ - /* */ - static void - Ins_NPUSHB( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_UShort)CUR.code[CUR.IP + 1]; - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - - for ( K = 1; K <= L; K++ ) - args[K - 1] = CUR.code[CUR.IP + K + 1]; - - CUR.new_top += L; - } - - - /*************************************************************************/ - /* */ - /* NPUSHW[]: PUSH N Words */ - /* Opcode range: 0x41 */ - /* Stack: --> int32... */ - /* */ - static void - Ins_NPUSHW( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_UShort)CUR.code[CUR.IP + 1]; - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - - CUR.IP += 2; - - for ( K = 0; K < L; K++ ) - args[K] = GET_ShortIns(); - - CUR.step_ins = FALSE; - CUR.new_top += L; - } - - - /*************************************************************************/ - /* */ - /* PUSHB[abc]: PUSH Bytes */ - /* Opcode range: 0xB0-0xB7 */ - /* Stack: --> uint32... */ - /* */ - static void - Ins_PUSHB( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_UShort)( CUR.opcode - 0xB0 + 1 ); - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - - for ( K = 1; K <= L; K++ ) - args[K - 1] = CUR.code[CUR.IP + K]; - } - - - /*************************************************************************/ - /* */ - /* PUSHW[abc]: PUSH Words */ - /* Opcode range: 0xB8-0xBF */ - /* Stack: --> int32... */ - /* */ - static void - Ins_PUSHW( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_UShort)( CUR.opcode - 0xB8 + 1 ); - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - - CUR.IP++; - - for ( K = 0; K < L; K++ ) - args[K] = GET_ShortIns(); - - CUR.step_ins = FALSE; - } - - - /*************************************************************************/ - /* */ - /* MANAGING THE GRAPHICS STATE */ - /* */ - /* Instructions appear in the specs' order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* GC[a]: Get Coordinate projected onto */ - /* Opcode range: 0x46-0x47 */ - /* Stack: uint32 --> f26.6 */ - /* */ - /* XXX: UNDOCUMENTED: Measures from the original glyph must be taken */ - /* along the dual projection vector! */ - /* */ - static void - Ins_GC( INS_ARG ) - { - FT_ULong L; - FT_F26Dot6 R; - - - L = (FT_ULong)args[0]; - - if ( BOUNDSL( L, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - R = 0; - } - else - { - if ( CUR.opcode & 1 ) - R = CUR_fast_dualproj( &CUR.zp2.org[L] ); - else - R = CUR_fast_project( &CUR.zp2.cur[L] ); - } - - args[0] = R; - } - - - /*************************************************************************/ - /* */ - /* SCFS[]: Set Coordinate From Stack */ - /* Opcode range: 0x48 */ - /* Stack: f26.6 uint32 --> */ - /* */ - /* Formula: */ - /* */ - /* OA := OA + ( value - OA.p )/( f.p ) * f */ - /* */ - static void - Ins_SCFS( INS_ARG ) - { - FT_Long K; - FT_UShort L; - - - L = (FT_UShort)args[0]; - - if ( BOUNDS( L, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - K = CUR_fast_project( &CUR.zp2.cur[L] ); - - CUR_Func_move( &CUR.zp2, L, args[1] - K ); - - /* UNDOCUMENTED! The MS rasterizer does that with */ - /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep2 == 0 ) - CUR.zp2.org[L] = CUR.zp2.cur[L]; - } - - - /*************************************************************************/ - /* */ - /* MD[a]: Measure Distance */ - /* Opcode range: 0x49-0x4A */ - /* Stack: uint32 uint32 --> f26.6 */ - /* */ - /* XXX: UNDOCUMENTED: Measure taken in the original glyph must be along */ - /* the dual projection vector. */ - /* */ - /* XXX: UNDOCUMENTED: Flag attributes are inverted! */ - /* 0 => measure distance in original outline */ - /* 1 => measure distance in grid-fitted outline */ - /* */ - /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */ - /* */ - static void - Ins_MD( INS_ARG ) - { - FT_UShort K, L; - FT_F26Dot6 D; - - - K = (FT_UShort)args[1]; - L = (FT_UShort)args[0]; - - if ( BOUNDS( L, CUR.zp0.n_points ) || - BOUNDS( K, CUR.zp1.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - D = 0; - } - else - { - if ( CUR.opcode & 1 ) - D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); - else - { - /* XXX: UNDOCUMENTED: twilight zone special case */ - - if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) - { - FT_Vector* vec1 = CUR.zp0.org + L; - FT_Vector* vec2 = CUR.zp1.org + K; - - - D = CUR_Func_dualproj( vec1, vec2 ); - } - else - { - FT_Vector* vec1 = CUR.zp0.orus + L; - FT_Vector* vec2 = CUR.zp1.orus + K; - - - if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) - { - /* this should be faster */ - D = CUR_Func_dualproj( vec1, vec2 ); - D = FT_MulFix( D, CUR.metrics.x_scale ); - } - else - { - FT_Vector vec; - - - vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); - vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); - - D = CUR_fast_dualproj( &vec ); - } - } - } - } - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && FT_ABS( D ) == 64 ) - D += 1; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - args[0] = D; - } - - - /*************************************************************************/ - /* */ - /* SDPVTL[a]: Set Dual PVector to Line */ - /* Opcode range: 0x86-0x87 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_SDPVTL( INS_ARG ) - { - FT_Long A, B, C; - FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ - FT_Int aOpc = CUR.opcode; - - - p1 = (FT_UShort)args[1]; - p2 = (FT_UShort)args[0]; - - if ( BOUNDS( p2, CUR.zp1.n_points ) || - BOUNDS( p1, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - { - FT_Vector* v1 = CUR.zp1.org + p2; - FT_Vector* v2 = CUR.zp2.org + p1; - - - A = v1->x - v2->x; - B = v1->y - v2->y; - - /* If v1 == v2, SDPVTL behaves the same as */ - /* SVTCA[X], respectively. */ - /* */ - /* Confirmed by Greg Hitchcock. */ - - if ( A == 0 && B == 0 ) - { - A = 0x4000; - aOpc = 0; - } - } - - if ( ( aOpc & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, &CUR.GS.dualVector ); - - { - FT_Vector* v1 = CUR.zp1.cur + p2; - FT_Vector* v2 = CUR.zp2.cur + p1; - - - A = v1->x - v2->x; - B = v1->y - v2->y; - - if ( A == 0 && B == 0 ) - { - A = 0x4000; - aOpc = 0; - } - } - - if ( ( aOpc & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, &CUR.GS.projVector ); - - GUESS_VECTOR( freeVector ); - - COMPUTE_Funcs(); - } - - - /*************************************************************************/ - /* */ - /* SZP0[]: Set Zone Pointer 0 */ - /* Opcode range: 0x13 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SZP0( INS_ARG ) - { - switch ( (FT_Int)args[0] ) - { - case 0: - CUR.zp0 = CUR.twilight; - break; - - case 1: - CUR.zp0 = CUR.pts; - break; - - default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - CUR.GS.gep0 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZP1[]: Set Zone Pointer 1 */ - /* Opcode range: 0x14 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SZP1( INS_ARG ) - { - switch ( (FT_Int)args[0] ) - { - case 0: - CUR.zp1 = CUR.twilight; - break; - - case 1: - CUR.zp1 = CUR.pts; - break; - - default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - CUR.GS.gep1 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZP2[]: Set Zone Pointer 2 */ - /* Opcode range: 0x15 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SZP2( INS_ARG ) - { - switch ( (FT_Int)args[0] ) - { - case 0: - CUR.zp2 = CUR.twilight; - break; - - case 1: - CUR.zp2 = CUR.pts; - break; - - default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - CUR.GS.gep2 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZPS[]: Set Zone PointerS */ - /* Opcode range: 0x16 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SZPS( INS_ARG ) - { - switch ( (FT_Int)args[0] ) - { - case 0: - CUR.zp0 = CUR.twilight; - break; - - case 1: - CUR.zp0 = CUR.pts; - break; - - default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - CUR.zp1 = CUR.zp0; - CUR.zp2 = CUR.zp0; - - CUR.GS.gep0 = (FT_UShort)args[0]; - CUR.GS.gep1 = (FT_UShort)args[0]; - CUR.GS.gep2 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* INSTCTRL[]: INSTruction ConTRoL */ - /* Opcode range: 0x8e */ - /* Stack: int32 int32 --> */ - /* */ - static void - Ins_INSTCTRL( INS_ARG ) - { - FT_Long K, L; - - - K = args[1]; - L = args[0]; - - if ( K < 1 || K > 2 ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - if ( L != 0 ) - L = K; - - CUR.GS.instruct_control = FT_BOOL( - ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); - } - - - /*************************************************************************/ - /* */ - /* SCANCTRL[]: SCAN ConTRoL */ - /* Opcode range: 0x85 */ - /* Stack: uint32? --> */ - /* */ - static void - Ins_SCANCTRL( INS_ARG ) - { - FT_Int A; - - - /* Get Threshold */ - A = (FT_Int)( args[0] & 0xFF ); - - if ( A == 0xFF ) - { - CUR.GS.scan_control = TRUE; - return; - } - else if ( A == 0 ) - { - CUR.GS.scan_control = FALSE; - return; - } - - if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A ) - CUR.GS.scan_control = TRUE; - - if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = TRUE; - - if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = TRUE; - - if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A ) - CUR.GS.scan_control = FALSE; - - if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = FALSE; - - if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = FALSE; - } - - - /*************************************************************************/ - /* */ - /* SCANTYPE[]: SCAN TYPE */ - /* Opcode range: 0x8D */ - /* Stack: uint32? --> */ - /* */ - static void - Ins_SCANTYPE( INS_ARG ) - { - if ( args[0] >= 0 ) - CUR.GS.scan_type = (FT_Int)args[0]; - } - - - /*************************************************************************/ - /* */ - /* MANAGING OUTLINES */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* FLIPPT[]: FLIP PoinT */ - /* Opcode range: 0x80 */ - /* Stack: uint32... --> */ - /* */ - static void - Ins_FLIPPT( INS_ARG ) - { - FT_UShort point; - - FT_UNUSED_ARG; - - - if ( CUR.top < CUR.GS.loop ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - goto Fail; - } - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.pts.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - } - else - CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; - - CUR.GS.loop--; - } - - Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* FLIPRGON[]: FLIP RanGe ON */ - /* Opcode range: 0x81 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_FLIPRGON( INS_ARG ) - { - FT_UShort I, K, L; - - - K = (FT_UShort)args[1]; - L = (FT_UShort)args[0]; - - if ( BOUNDS( K, CUR.pts.n_points ) || - BOUNDS( L, CUR.pts.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - for ( I = L; I <= K; I++ ) - CUR.pts.tags[I] |= FT_CURVE_TAG_ON; - } - - - /*************************************************************************/ - /* */ - /* FLIPRGOFF: FLIP RanGe OFF */ - /* Opcode range: 0x82 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_FLIPRGOFF( INS_ARG ) - { - FT_UShort I, K, L; - - - K = (FT_UShort)args[1]; - L = (FT_UShort)args[0]; - - if ( BOUNDS( K, CUR.pts.n_points ) || - BOUNDS( L, CUR.pts.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - for ( I = L; I <= K; I++ ) - CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; - } - - - static FT_Bool - Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, - FT_F26Dot6* y, - TT_GlyphZone zone, - FT_UShort* refp ) - { - TT_GlyphZoneRec zp; - FT_UShort p; - FT_F26Dot6 d; - - - if ( CUR.opcode & 1 ) - { - zp = CUR.zp0; - p = CUR.GS.rp1; - } - else - { - zp = CUR.zp1; - p = CUR.GS.rp2; - } - - if ( BOUNDS( p, zp.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - *refp = 0; - return FAILURE; - } - - *zone = zp; - *refp = p; - - d = CUR_Func_project( zp.cur + p, zp.org + p ); - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - { - *x = d; - *y = 0; - } - else - { - *x = 0; - *y = d; - } - } - else -#endif - { - *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P ); - *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P ); - } - - return SUCCESS; - } - - - static void - Move_Zp2_Point( EXEC_OP_ FT_UShort point, - FT_F26Dot6 dx, - FT_F26Dot6 dy, - FT_Bool touch ) - { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - { - CUR.zp2.cur[point].x += dx; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; - } - else - { - CUR.zp2.cur[point].y += dy; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; - } - return; - } -#endif - - if ( CUR.GS.freeVector.x != 0 ) - { - CUR.zp2.cur[point].x += dx; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; - } - - if ( CUR.GS.freeVector.y != 0 ) - { - CUR.zp2.cur[point].y += dy; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; - } - } - - - /*************************************************************************/ - /* */ - /* SHP[a]: SHift Point by the last point */ - /* Opcode range: 0x32-0x33 */ - /* Stack: uint32... --> */ - /* */ - static void - Ins_SHP( INS_ARG ) - { - TT_GlyphZoneRec zp; - FT_UShort refp; - - FT_F26Dot6 dx, - dy; - FT_UShort point; - - FT_UNUSED_ARG; - - - if ( CUR.top < CUR.GS.loop ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } - - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) - return; - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - point = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - } - else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* doesn't follow Cleartype spec but produces better result */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) - MOVE_Zp2_Point( point, 0, dy, TRUE ); - else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - MOVE_Zp2_Point( point, dx, dy, TRUE ); - - CUR.GS.loop--; - } - - Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* SHC[a]: SHift Contour */ - /* Opcode range: 0x34-35 */ - /* Stack: uint32 --> */ - /* */ - /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */ - /* contour in the twilight zone, namely contour number */ - /* zero which includes all points of it. */ - /* */ - static void - Ins_SHC( INS_ARG ) - { - TT_GlyphZoneRec zp; - FT_UShort refp; - FT_F26Dot6 dx, dy; - - FT_Short contour, bounds; - FT_UShort start, limit, i; - - - contour = (FT_UShort)args[0]; - bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours; - - if ( BOUNDS( contour, bounds ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) - return; - - if ( contour == 0 ) - start = 0; - else - start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 - - CUR.zp2.first_point ); - - /* we use the number of points if in the twilight zone */ - if ( CUR.GS.gep2 == 0 ) - limit = CUR.zp2.n_points; - else - limit = (FT_UShort)( CUR.zp2.contours[contour] - - CUR.zp2.first_point + 1 ); - - for ( i = start; i < limit; i++ ) - { - if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, TRUE ); - } - } - - - /*************************************************************************/ - /* */ - /* SHZ[a]: SHift Zone */ - /* Opcode range: 0x36-37 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SHZ( INS_ARG ) - { - TT_GlyphZoneRec zp; - FT_UShort refp; - FT_F26Dot6 dx, - dy; - - FT_UShort limit, i; - - - if ( BOUNDS( args[0], 2 ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) - return; - - /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ - /* Twilight zone has no real contours, so use `n_points'. */ - /* Normal zone's `n_points' includes phantoms, so must */ - /* use end of last contour. */ - if ( CUR.GS.gep2 == 0 ) - limit = (FT_UShort)CUR.zp2.n_points; - else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) - limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 ); - else - limit = 0; - - /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ - for ( i = 0; i < limit; i++ ) - { - if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, FALSE ); - } - } - - - /*************************************************************************/ - /* */ - /* SHPIX[]: SHift points by a PIXel amount */ - /* Opcode range: 0x38 */ - /* Stack: f26.6 uint32... --> */ - /* */ - static void - Ins_SHPIX( INS_ARG ) - { - FT_F26Dot6 dx, dy; - FT_UShort point; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Int B1, B2; -#endif - - - if ( CUR.top < CUR.GS.loop + 1 ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - { - dx = (FT_UInt32)args[0]; - dy = 0; - } - else - { - dx = 0; - dy = (FT_UInt32)args[0]; - } - } - else -#endif - { - dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); - dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); - } - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - } - else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - { - /* If not using ignore_x_mode rendering, allow ZP2 move. */ - /* If inline deltas aren't allowed, skip ZP2 move. */ - /* If using ignore_x_mode rendering, allow ZP2 point move if: */ - /* - freedom vector is y and sph_compatibility_mode is off */ - /* - the glyph is composite and the move is in the Y direction */ - /* - the glyph is specifically set to allow SHPIX moves */ - /* - the move is on a previously Y-touched point */ - - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) - { - /* save point for later comparison */ - if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp2.cur[point].y; - else - B1 = CUR.zp2.cur[point].x; - - if ( !CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 ) - { - MOVE_Zp2_Point( point, dx, dy, TRUE ); - - /* save new point */ - if ( CUR.GS.freeVector.y != 0 ) - { - B2 = CUR.zp2.cur[point].y; - - /* reverse any disallowed moves */ - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - ( B1 & 63 ) != 0 && - ( B2 & 63 ) != 0 && - B1 != B2 ) - MOVE_Zp2_Point( point, -dx, -dy, TRUE ); - } - } - else if ( CUR.face->sph_compatibility_mode ) - { - if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) - { - dx = FT_PIX_ROUND( B1 + dx ) - B1; - dy = FT_PIX_ROUND( B1 + dy ) - B1; - } - - /* skip post-iup deltas */ - if ( CUR.iup_called && - ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || - ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) - goto Skip; - - if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && - ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || - ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || - ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) - MOVE_Zp2_Point( point, 0, dy, TRUE ); - - /* save new point */ - if ( CUR.GS.freeVector.y != 0 ) - { - B2 = CUR.zp2.cur[point].y; - - /* reverse any disallowed moves */ - if ( ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 && - B1 != B2 ) - MOVE_Zp2_Point( point, 0, -dy, TRUE ); - } - } - else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) - MOVE_Zp2_Point( point, dx, dy, TRUE ); - } - else - MOVE_Zp2_Point( point, dx, dy, TRUE ); - } - - Skip: - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - MOVE_Zp2_Point( point, dx, dy, TRUE ); - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - CUR.GS.loop--; - } - - Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* MSIRP[a]: Move Stack Indirect Relative Position */ - /* Opcode range: 0x3A-0x3B */ - /* Stack: f26.6 uint32 --> */ - /* */ - static void - Ins_MSIRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 distance; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */ - - - if ( SUBPIXEL_HINTING ) - { - control_value_cutin = CUR.GS.control_value_cutin; - - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - control_value_cutin = 0; - } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - /* UNDOCUMENTED! The MS rasterizer does that with */ - /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep1 == 0 ) - { - CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; - CUR_Func_move_orig( &CUR.zp1, point, args[1] ); - CUR.zp1.cur[point] = CUR.zp1.org[point]; - } - - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - FT_ABS( distance - args[1] ) >= control_value_cutin ) - distance = args[1]; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - CUR_Func_move( &CUR.zp1, point, args[1] - distance ); - - CUR.GS.rp1 = CUR.GS.rp0; - CUR.GS.rp2 = point; - - if ( ( CUR.opcode & 1 ) != 0 ) - CUR.GS.rp0 = point; - } - - - /*************************************************************************/ - /* */ - /* MDAP[a]: Move Direct Absolute Point */ - /* Opcode range: 0x2E-0x2F */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_MDAP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 cur_dist; - FT_F26Dot6 distance; - - - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - if ( ( CUR.opcode & 1 ) != 0 ) - { - cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( - cur_dist, - CUR.tt_metrics.compensations[0] ) - cur_dist; - else -#endif - distance = CUR_Func_round( - cur_dist, - CUR.tt_metrics.compensations[0] ) - cur_dist; - } - else - distance = 0; - - CUR_Func_move( &CUR.zp0, point, distance ); - - CUR.GS.rp0 = point; - CUR.GS.rp1 = point; - } - - - /*************************************************************************/ - /* */ - /* MIAP[a]: Move Indirect Absolute Point */ - /* Opcode range: 0x3E-0x3F */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_MIAP( INS_ARG ) - { - FT_ULong cvtEntry; - FT_UShort point; - FT_F26Dot6 distance; - FT_F26Dot6 org_dist; - FT_F26Dot6 control_value_cutin; - - - control_value_cutin = CUR.GS.control_value_cutin; - cvtEntry = (FT_ULong)args[1]; - point = (FT_UShort)args[0]; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - CUR.GS.freeVector.y == 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - control_value_cutin = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - if ( BOUNDS( point, CUR.zp0.n_points ) || - BOUNDSL( cvtEntry, CUR.cvtSize ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } - - /* UNDOCUMENTED! */ - /* */ - /* The behaviour of an MIAP instruction is quite different when used */ - /* in the twilight zone. */ - /* */ - /* First, no control value cut-in test is performed as it would fail */ - /* anyway. Second, the original point, i.e. (org_x,org_y) of */ - /* zp0.point, is set to the absolute, unrounded distance found in the */ - /* CVT. */ - /* */ - /* This is used in the CVT programs of the Microsoft fonts Arial, */ - /* Times, etc., in order to re-adjust some key font heights. It */ - /* allows the use of the IP instruction in the twilight zone, which */ - /* otherwise would be invalid according to the specification. */ - /* */ - /* We implement it with a special sequence for the twilight zone. */ - /* This is a bad hack, but it seems to work. */ - /* */ - /* Confirmed by Greg Hitchcock. */ - - distance = CUR_Func_read_cvt( cvtEntry ); - - if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ - { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ - /* Determined via experimentation and may be incorrect... */ - if ( !SUBPIXEL_HINTING || - ( !CUR.ignore_x_mode || - !CUR.face->sph_compatibility_mode ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, - CUR.GS.freeVector.x ); - CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, - CUR.GS.freeVector.y ), - CUR.zp0.cur[point] = CUR.zp0.org[point]; - } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && - distance > 0 && - CUR.GS.freeVector.y != 0 ) - distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); - - if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ - { - if ( FT_ABS( distance - org_dist ) > control_value_cutin ) - distance = org_dist; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( distance, - CUR.tt_metrics.compensations[0] ); - else -#endif - distance = CUR_Func_round( distance, - CUR.tt_metrics.compensations[0] ); - } - - CUR_Func_move( &CUR.zp0, point, distance - org_dist ); - - Fail: - CUR.GS.rp0 = point; - CUR.GS.rp1 = point; - } - - - /*************************************************************************/ - /* */ - /* MDRP[abcde]: Move Direct Relative Point */ - /* Opcode range: 0xC0-0xDF */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_MDRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 org_dist, distance, minimum_distance; - - - minimum_distance = CUR.GS.minimum_distance; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } - - /* XXX: Is there some undocumented feature while in the */ - /* twilight zone? */ - - /* XXX: UNDOCUMENTED: twilight zone special case */ - - if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) - { - FT_Vector* vec1 = &CUR.zp1.org[point]; - FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0]; - - - org_dist = CUR_Func_dualproj( vec1, vec2 ); - } - else - { - FT_Vector* vec1 = &CUR.zp1.orus[point]; - FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0]; - - - if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) - { - /* this should be faster */ - org_dist = CUR_Func_dualproj( vec1, vec2 ); - org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale ); - } - else - { - FT_Vector vec; - - - vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); - vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); - - org_dist = CUR_fast_dualproj( &vec ); - } - } - - /* single width cut-in test */ - - if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < - CUR.GS.single_width_cutin ) - { - if ( org_dist >= 0 ) - org_dist = CUR.GS.single_width_value; - else - org_dist = -CUR.GS.single_width_value; - } - - /* round flag */ - - if ( ( CUR.opcode & 4 ) != 0 ) - { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( - org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - else -#endif - distance = CUR_Func_round( - org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - } - else - distance = ROUND_None( - org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - - /* minimum distance flag */ - - if ( ( CUR.opcode & 8 ) != 0 ) - { - if ( org_dist >= 0 ) - { - if ( distance < minimum_distance ) - distance = minimum_distance; - } - else - { - if ( distance > -minimum_distance ) - distance = -minimum_distance; - } - } - - /* now move the point */ - - org_dist = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); - - CUR_Func_move( &CUR.zp1, point, distance - org_dist ); - - Fail: - CUR.GS.rp1 = CUR.GS.rp0; - CUR.GS.rp2 = point; - - if ( ( CUR.opcode & 16 ) != 0 ) - CUR.GS.rp0 = point; - } - - - /*************************************************************************/ - /* */ - /* MIRP[abcde]: Move Indirect Relative Point */ - /* Opcode range: 0xE0-0xFF */ - /* Stack: int32? uint32 --> */ - /* */ - static void - Ins_MIRP( INS_ARG ) - { - FT_UShort point; - FT_ULong cvtEntry; - - FT_F26Dot6 cvt_dist, - distance, - cur_dist, - org_dist, - control_value_cutin, - minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Int B1 = 0; /* pacify compiler */ - FT_Int B2 = 0; - FT_Bool reverse_move = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - minimum_distance = CUR.GS.minimum_distance; - control_value_cutin = CUR.GS.control_value_cutin; - point = (FT_UShort)args[0]; - cvtEntry = (FT_ULong)( args[1] + 1 ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - control_value_cutin = minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ - - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } - - if ( !cvtEntry ) - cvt_dist = 0; - else - cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); - - /* single width test */ - - if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) < - CUR.GS.single_width_cutin ) - { - if ( cvt_dist >= 0 ) - cvt_dist = CUR.GS.single_width_value; - else - cvt_dist = -CUR.GS.single_width_value; - } - - /* UNDOCUMENTED! The MS rasterizer does that with */ - /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep1 == 0 ) - { - CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + - TT_MulFix14( (FT_UInt32)cvt_dist, - CUR.GS.freeVector.x ); - CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + - TT_MulFix14( (FT_UInt32)cvt_dist, - CUR.GS.freeVector.y ); - CUR.zp1.cur[point] = CUR.zp1.org[point]; - } - - org_dist = CUR_Func_dualproj( &CUR.zp1.org[point], - &CUR.zp0.org[CUR.GS.rp0] ); - cur_dist = CUR_Func_project ( &CUR.zp1.cur[point], - &CUR.zp0.cur[CUR.GS.rp0] ); - - /* auto-flip test */ - - if ( CUR.GS.auto_flip ) - { - if ( ( org_dist ^ cvt_dist ) < 0 ) - cvt_dist = -cvt_dist; - } - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) - { - if ( cur_dist < -64 ) - cvt_dist -= 16; - else if ( cur_dist > 64 && cur_dist < 84 ) - cvt_dist += 32; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - /* control value cut-in and round */ - - if ( ( CUR.opcode & 4 ) != 0 ) - { - /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ - /* refer to the same zone. */ - - if ( CUR.GS.gep0 == CUR.GS.gep1 ) - { - /* XXX: According to Greg Hitchcock, the following wording is */ - /* the right one: */ - /* */ - /* When the absolute difference between the value in */ - /* the table [CVT] and the measurement directly from */ - /* the outline is _greater_ than the cut_in value, the */ - /* outline measurement is used. */ - /* */ - /* This is from `instgly.doc'. The description in */ - /* `ttinst2.doc', version 1.66, is thus incorrect since */ - /* it implies `>=' instead of `>'. */ - - if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) - cvt_dist = org_dist; - } - - distance = CUR_Func_round( - cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - } - else - { - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* do cvt cut-in always in MIRP for sph */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.gep0 == CUR.GS.gep1 ) - { - if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) - cvt_dist = org_dist; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - distance = ROUND_None( - cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - } - - /* minimum distance test */ - - if ( ( CUR.opcode & 8 ) != 0 ) - { - if ( org_dist >= 0 ) - { - if ( distance < minimum_distance ) - distance = minimum_distance; - } - else - { - if ( distance > -minimum_distance ) - distance = -minimum_distance; - } - } - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) - { - B1 = CUR.zp1.cur[point].y; - - /* Round moves if necessary */ - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) - distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; - - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.opcode & 16 ) == 0 && - ( CUR.opcode & 8 ) == 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) - distance += 64; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) - { - B2 = CUR.zp1.cur[point].y; - - /* Reverse move if necessary */ - if ( CUR.ignore_x_mode ) - { - if ( CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 && - ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 ) - reverse_move = TRUE; - - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - CUR.GS.freeVector.y != 0 && - ( B2 & 63 ) != 0 && - ( B1 & 63 ) != 0 ) - reverse_move = TRUE; - } - - if ( reverse_move ) - CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) ); - } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - Fail: - CUR.GS.rp1 = CUR.GS.rp0; - - if ( ( CUR.opcode & 16 ) != 0 ) - CUR.GS.rp0 = point; - - CUR.GS.rp2 = point; - } - - - /*************************************************************************/ - /* */ - /* ALIGNRP[]: ALIGN Relative Point */ - /* Opcode range: 0x3C */ - /* Stack: uint32 uint32... --> */ - /* */ - static void - Ins_ALIGNRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 distance; - - FT_UNUSED_ARG; - - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) - { - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - if ( CUR.top < CUR.GS.loop || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.zp1.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - } - else - { - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); - - CUR_Func_move( &CUR.zp1, point, -distance ); - } - - CUR.GS.loop--; - } - - Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* ISECT[]: moves point to InterSECTion */ - /* Opcode range: 0x0F */ - /* Stack: 5 * uint32 --> */ - /* */ - static void - Ins_ISECT( INS_ARG ) - { - FT_UShort point, - a0, a1, - b0, b1; - - FT_F26Dot6 discriminant, dotproduct; - - FT_F26Dot6 dx, dy, - dax, day, - dbx, dby; - - FT_F26Dot6 val; - - FT_Vector R; - - - point = (FT_UShort)args[0]; - - a0 = (FT_UShort)args[1]; - a1 = (FT_UShort)args[2]; - b0 = (FT_UShort)args[3]; - b1 = (FT_UShort)args[4]; - - if ( BOUNDS( b0, CUR.zp0.n_points ) || - BOUNDS( b1, CUR.zp0.n_points ) || - BOUNDS( a0, CUR.zp1.n_points ) || - BOUNDS( a1, CUR.zp1.n_points ) || - BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - /* Cramer's rule */ - - dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; - dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; - - dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; - day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; - - dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; - dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; - - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; - - discriminant = FT_MulDiv( dax, -dby, 0x40 ) + - FT_MulDiv( day, dbx, 0x40 ); - dotproduct = FT_MulDiv( dax, dbx, 0x40 ) + - FT_MulDiv( day, dby, 0x40 ); - - /* The discriminant above is actually a cross product of vectors */ - /* da and db. Together with the dot product, they can be used as */ - /* surrogates for sine and cosine of the angle between the vectors. */ - /* Indeed, */ - /* dotproduct = |da||db|cos(angle) */ - /* discriminant = |da||db|sin(angle) . */ - /* We use these equations to reject grazing intersections by */ - /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */ - if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) ) - { - val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 ); - - R.x = FT_MulDiv( val, dax, discriminant ); - R.y = FT_MulDiv( val, day, discriminant ); - - CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; - CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; - } - else - { - /* else, take the middle of the middles of A and B */ - - CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + - CUR.zp1.cur[a1].x + - CUR.zp0.cur[b0].x + - CUR.zp0.cur[b1].x ) / 4; - CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + - CUR.zp1.cur[a1].y + - CUR.zp0.cur[b0].y + - CUR.zp0.cur[b1].y ) / 4; - } - } - - - /*************************************************************************/ - /* */ - /* ALIGNPTS[]: ALIGN PoinTS */ - /* Opcode range: 0x27 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_ALIGNPTS( INS_ARG ) - { - FT_UShort p1, p2; - FT_F26Dot6 distance; - - - p1 = (FT_UShort)args[0]; - p2 = (FT_UShort)args[1]; - - if ( BOUNDS( p1, CUR.zp1.n_points ) || - BOUNDS( p2, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - distance = CUR_Func_project( CUR.zp0.cur + p2, - CUR.zp1.cur + p1 ) / 2; - - CUR_Func_move( &CUR.zp1, p1, distance ); - CUR_Func_move( &CUR.zp0, p2, -distance ); - } - - - /*************************************************************************/ - /* */ - /* IP[]: Interpolate Point */ - /* Opcode range: 0x39 */ - /* Stack: uint32... --> */ - /* */ - - /* SOMETIMES, DUMBER CODE IS BETTER CODE */ - - static void - Ins_IP( INS_ARG ) - { - FT_F26Dot6 old_range, cur_range; - FT_Vector* orus_base; - FT_Vector* cur_base; - FT_Int twilight; - - FT_UNUSED_ARG; - - - if ( CUR.top < CUR.GS.loop ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } - - /* - * We need to deal in a special way with the twilight zone. - * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0), - * for every n. - */ - twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; - - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - goto Fail; - } - - if ( twilight ) - orus_base = &CUR.zp0.org[CUR.GS.rp1]; - else - orus_base = &CUR.zp0.orus[CUR.GS.rp1]; - - cur_base = &CUR.zp0.cur[CUR.GS.rp1]; - - /* XXX: There are some glyphs in some braindead but popular */ - /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ - /* calling IP[] with bad values of rp[12]. */ - /* Do something sane when this odd thing happens. */ - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || - BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) - { - old_range = 0; - cur_range = 0; - } - else - { - if ( twilight ) - old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], - orus_base ); - else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) - old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2], - orus_base ); - else - { - FT_Vector vec; - - - vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x, - CUR.metrics.x_scale ); - vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y, - CUR.metrics.y_scale ); - - old_range = CUR_fast_dualproj( &vec ); - } - - cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); - } - - for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) - { - FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; - FT_F26Dot6 org_dist, cur_dist, new_dist; - - - /* check point bounds */ - if ( BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - continue; - } - - if ( twilight ) - org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); - else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) - org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); - else - { - FT_Vector vec; - - - vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x, - CUR.metrics.x_scale ); - vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y, - CUR.metrics.y_scale ); - - org_dist = CUR_fast_dualproj( &vec ); - } - - cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); - - if ( org_dist ) - { - if ( old_range ) - new_dist = FT_MulDiv( org_dist, cur_range, old_range ); - else - { - /* This is the same as what MS does for the invalid case: */ - /* */ - /* delta = (Original_Pt - Original_RP1) - */ - /* (Current_Pt - Current_RP1) */ - /* */ - /* In FreeType speak: */ - /* */ - /* new_dist = cur_dist - */ - /* org_dist - cur_dist; */ - - new_dist = -org_dist; - } - } - else - new_dist = 0; - - CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); - } - - Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* UTP[a]: UnTouch Point */ - /* Opcode range: 0x29 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_UTP( INS_ARG ) - { - FT_UShort point; - FT_Byte mask; - - - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - - mask = 0xFF; - - if ( CUR.GS.freeVector.x != 0 ) - mask &= ~FT_CURVE_TAG_TOUCH_X; - - if ( CUR.GS.freeVector.y != 0 ) - mask &= ~FT_CURVE_TAG_TOUCH_Y; - - CUR.zp0.tags[point] &= mask; - } - - - /* Local variables for Ins_IUP: */ - typedef struct IUP_WorkerRec_ - { - FT_Vector* orgs; /* original and current coordinate */ - FT_Vector* curs; /* arrays */ - FT_Vector* orus; - FT_UInt max_points; - - } IUP_WorkerRec, *IUP_Worker; - - - static void - _iup_worker_shift( IUP_Worker worker, - FT_UInt p1, - FT_UInt p2, - FT_UInt p ) - { - FT_UInt i; - FT_F26Dot6 dx; - - - dx = worker->curs[p].x - worker->orgs[p].x; - if ( dx != 0 ) - { - for ( i = p1; i < p; i++ ) - worker->curs[i].x += dx; - - for ( i = p + 1; i <= p2; i++ ) - worker->curs[i].x += dx; - } - } - - - static void - _iup_worker_interpolate( IUP_Worker worker, - FT_UInt p1, - FT_UInt p2, - FT_UInt ref1, - FT_UInt ref2 ) - { - FT_UInt i; - FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2; - - - if ( p1 > p2 ) - return; - - if ( BOUNDS( ref1, worker->max_points ) || - BOUNDS( ref2, worker->max_points ) ) - return; - - orus1 = worker->orus[ref1].x; - orus2 = worker->orus[ref2].x; - - if ( orus1 > orus2 ) - { - FT_F26Dot6 tmp_o; - FT_UInt tmp_r; - - - tmp_o = orus1; - orus1 = orus2; - orus2 = tmp_o; - - tmp_r = ref1; - ref1 = ref2; - ref2 = tmp_r; - } - - org1 = worker->orgs[ref1].x; - org2 = worker->orgs[ref2].x; - delta1 = worker->curs[ref1].x - org1; - delta2 = worker->curs[ref2].x - org2; - - if ( orus1 == orus2 ) - { - /* simple shift of untouched points */ - for ( i = p1; i <= p2; i++ ) - { - FT_F26Dot6 x = worker->orgs[i].x; - - - if ( x <= org1 ) - x += delta1; - else - x += delta2; - - worker->curs[i].x = x; - } - } - else - { - FT_Fixed scale = 0; - FT_Bool scale_valid = 0; - - - /* interpolation */ - for ( i = p1; i <= p2; i++ ) - { - FT_F26Dot6 x = worker->orgs[i].x; - - - if ( x <= org1 ) - x += delta1; - - else if ( x >= org2 ) - x += delta2; - - else - { - if ( !scale_valid ) - { - scale_valid = 1; - scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ), - orus2 - orus1 ); - } - - x = ( org1 + delta1 ) + - FT_MulFix( worker->orus[i].x - orus1, scale ); - } - worker->curs[i].x = x; - } - } - } - - - /*************************************************************************/ - /* */ - /* IUP[a]: Interpolate Untouched Points */ - /* Opcode range: 0x30-0x31 */ - /* Stack: --> */ - /* */ - static void - Ins_IUP( INS_ARG ) - { - IUP_WorkerRec V; - FT_Byte mask; - - FT_UInt first_point; /* first point of contour */ - FT_UInt end_point; /* end point (last+1) of contour */ - - FT_UInt first_touched; /* first touched point in contour */ - FT_UInt cur_touched; /* current touched point in contour */ - - FT_UInt point; /* current point */ - FT_Short contour; /* current contour */ - - FT_UNUSED_ARG; - - - /* ignore empty outlines */ - if ( CUR.pts.n_contours == 0 ) - return; - - if ( CUR.opcode & 1 ) - { - mask = FT_CURVE_TAG_TOUCH_X; - V.orgs = CUR.pts.org; - V.curs = CUR.pts.cur; - V.orus = CUR.pts.orus; - } - else - { - mask = FT_CURVE_TAG_TOUCH_Y; - V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); - V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); - V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); - } - V.max_points = CUR.pts.n_points; - - contour = 0; - point = 0; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) - { - CUR.iup_called = TRUE; - if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) - return; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - do - { - end_point = CUR.pts.contours[contour] - CUR.pts.first_point; - first_point = point; - - if ( BOUNDS ( end_point, CUR.pts.n_points ) ) - end_point = CUR.pts.n_points - 1; - - while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) - point++; - - if ( point <= end_point ) - { - first_touched = point; - cur_touched = point; - - point++; - - while ( point <= end_point ) - { - if ( ( CUR.pts.tags[point] & mask ) != 0 ) - { - _iup_worker_interpolate( &V, - cur_touched + 1, - point - 1, - cur_touched, - point ); - cur_touched = point; - } - - point++; - } - - if ( cur_touched == first_touched ) - _iup_worker_shift( &V, first_point, end_point, cur_touched ); - else - { - _iup_worker_interpolate( &V, - (FT_UShort)( cur_touched + 1 ), - end_point, - cur_touched, - first_touched ); - - if ( first_touched > 0 ) - _iup_worker_interpolate( &V, - first_point, - first_touched - 1, - cur_touched, - first_touched ); - } - } - contour++; - } while ( contour < CUR.pts.n_contours ); - } - - - /*************************************************************************/ - /* */ - /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ - /* Opcode range: 0x5D,0x71,0x72 */ - /* Stack: uint32 (2 * uint32)... --> */ - /* */ - static void - Ins_DELTAP( INS_ARG ) - { - FT_ULong k, nump; - FT_UShort A; - FT_ULong C; - FT_Long B; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_UShort B1, B2; - - - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) - goto Fail; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( CUR.face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( CUR.args < n ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - n = CUR.args; - } - - CUR.args -= n; - CUR.new_top = CUR.args; - return; - } -#endif - - nump = (FT_ULong)args[0]; /* some points theoretically may occur more - than once, thus UShort isn't enough */ - - for ( k = 1; k <= nump; k++ ) - { - if ( CUR.args < 2 ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - CUR.args = 0; - goto Fail; - } - - CUR.args -= 2; - - A = (FT_UShort)CUR.stack[CUR.args + 1]; - B = CUR.stack[CUR.args]; - - /* XXX: Because some popular fonts contain some invalid DeltaP */ - /* instructions, we simply ignore them when the stacked */ - /* point reference is off limit, rather than returning an */ - /* error. As a delta instruction doesn't change a glyph */ - /* in great ways, this shouldn't be a problem. */ - - if ( !BOUNDS( A, CUR.zp0.n_points ) ) - { - C = ( (FT_ULong)B & 0xF0 ) >> 4; - - switch ( CUR.opcode ) - { - case 0x5D: - break; - - case 0x71: - C += 16; - break; - - case 0x72: - C += 32; - break; - } - - C += CUR.GS.delta_base; - - if ( CURRENT_Ppem() == (FT_Long)C ) - { - B = ( (FT_ULong)B & 0xF ) - 8; - if ( B >= 0 ) - B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( SUBPIXEL_HINTING ) - { - /* - * Allow delta move if - * - * - not using ignore_x_mode rendering - * - glyph is specifically set to allow it - * - glyph is composite and freedom vector is not subpixel - * vector - */ - if ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || - ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ) - CUR_Func_move( &CUR.zp0, A, B ); - - /* Otherwise apply subpixel hinting and */ - /* compatibility mode rules */ - else if ( CUR.ignore_x_mode ) - { - if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp0.cur[A].y; - else - B1 = CUR.zp0.cur[A].x; - -#if 0 - /* Standard Subpixel Hinting: Allow y move. */ - /* This messes up dejavu and may not be needed... */ - if ( !CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 ) - CUR_Func_move( &CUR.zp0, A, B ); - else -#endif /* 0 */ - - /* Compatibility Mode: Allow x or y move if point touched in */ - /* Y direction. */ - if ( CUR.face->sph_compatibility_mode && - !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) - { - /* save the y value of the point now; compare after move */ - B1 = CUR.zp0.cur[A].y; - - if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) - B = FT_PIX_ROUND( B1 + B ) - B1; - - /* Allow delta move if using sph_compatibility_mode, */ - /* IUP has not been called, and point is touched on Y. */ - if ( !CUR.iup_called && - ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) - CUR_Func_move( &CUR.zp0, A, B ); - } - - B2 = CUR.zp0.cur[A].y; - - /* Reverse this move if it results in a disallowed move */ - if ( CUR.GS.freeVector.y != 0 && - ( ( CUR.face->sph_compatibility_mode && - ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 ) || - ( ( CUR.sph_tweak_flags & - SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && - ( B1 & 63 ) != 0 && - ( B2 & 63 ) != 0 ) ) ) - CUR_Func_move( &CUR.zp0, A, -B ); - } - } - else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - CUR_Func_move( &CUR.zp0, A, B ); - } - } - else - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - } - - Fail: - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* DELTACn[]: DELTA exceptions C1, C2, C3 */ - /* Opcode range: 0x73,0x74,0x75 */ - /* Stack: uint32 (2 * uint32)... --> */ - /* */ - static void - Ins_DELTAC( INS_ARG ) - { - FT_ULong nump, k; - FT_ULong A, C; - FT_Long B; - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( CUR.face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( CUR.args < n ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - n = CUR.args; - } - - CUR.args -= n; - CUR.new_top = CUR.args; - return; - } -#endif - - nump = (FT_ULong)args[0]; - - for ( k = 1; k <= nump; k++ ) - { - if ( CUR.args < 2 ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - CUR.args = 0; - goto Fail; - } - - CUR.args -= 2; - - A = (FT_ULong)CUR.stack[CUR.args + 1]; - B = CUR.stack[CUR.args]; - - if ( BOUNDSL( A, CUR.cvtSize ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = FT_THROW( Invalid_Reference ); - return; - } - } - else - { - C = ( (FT_ULong)B & 0xF0 ) >> 4; - - switch ( CUR.opcode ) - { - case 0x73: - break; - - case 0x74: - C += 16; - break; - - case 0x75: - C += 32; - break; - } - - C += CUR.GS.delta_base; - - if ( CURRENT_Ppem() == (FT_Long)C ) - { - B = ( (FT_ULong)B & 0xF ) - 8; - if ( B >= 0 ) - B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); - - CUR_Func_move_cvt( A, B ); - } - } - } - - Fail: - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* MISC. INSTRUCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* GETINFO[]: GET INFOrmation */ - /* Opcode range: 0x88 */ - /* Stack: uint32 --> uint32 */ - /* */ - static void - Ins_GETINFO( INS_ARG ) - { - FT_Long K; - - - K = 0; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /********************************/ - /* RASTERIZER VERSION */ - /* Selector Bit: 0 */ - /* Return Bit(s): 0-7 */ - /* */ - if ( SUBPIXEL_HINTING && - ( args[0] & 1 ) != 0 && - CUR.ignore_x_mode ) - { - K = CUR.rasterizer_version; - FT_TRACE7(( "Setting rasterizer version %d\n", - CUR.rasterizer_version )); - } - else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - if ( ( args[0] & 1 ) != 0 ) - K = TT_INTERPRETER_VERSION_35; - - /********************************/ - /* GLYPH ROTATED */ - /* Selector Bit: 1 */ - /* Return Bit(s): 8 */ - /* */ - if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) - K |= 0x80; - - /********************************/ - /* GLYPH STRETCHED */ - /* Selector Bit: 2 */ - /* Return Bit(s): 9 */ - /* */ - if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) - K |= 1 << 8; - - /********************************/ - /* HINTING FOR GRAYSCALE */ - /* Selector Bit: 5 */ - /* Return Bit(s): 12 */ - /* */ - if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) - K |= 1 << 12; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 ) - { - /********************************/ - /* HINTING FOR GRAYSCALE */ - /* Selector Bit: 5 */ - /* Return Bit(s): 12 */ - /* */ - if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting ) - K |= 1 << 12; - - /********************************/ - /* HINTING FOR SUBPIXEL */ - /* Selector Bit: 6 */ - /* Return Bit(s): 13 */ - /* */ - if ( ( args[0] & 64 ) != 0 && - CUR.subpixel_hinting && - CUR.rasterizer_version >= 37 ) - { - K |= 1 << 13; - - /* the stuff below is irrelevant if subpixel_hinting is not set */ - - /********************************/ - /* COMPATIBLE WIDTHS ENABLED */ - /* Selector Bit: 7 */ - /* Return Bit(s): 14 */ - /* */ - /* Functionality still needs to be added */ - if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) - K |= 1 << 14; - - /********************************/ - /* SYMMETRICAL SMOOTHING */ - /* Selector Bit: 8 */ - /* Return Bit(s): 15 */ - /* */ - /* Functionality still needs to be added */ - if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing ) - K |= 1 << 15; - - /********************************/ - /* HINTING FOR BGR? */ - /* Selector Bit: 9 */ - /* Return Bit(s): 16 */ - /* */ - /* Functionality still needs to be added */ - if ( ( args[0] & 512 ) != 0 && CUR.bgr ) - K |= 1 << 16; - - if ( CUR.rasterizer_version >= 38 ) - { - /********************************/ - /* SUBPIXEL POSITIONED? */ - /* Selector Bit: 10 */ - /* Return Bit(s): 17 */ - /* */ - /* Functionality still needs to be added */ - if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned ) - K |= 1 << 17; - } - } - } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - args[0] = K; - } - - - static void - Ins_UNKNOWN( INS_ARG ) - { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; - - FT_UNUSED_ARG; - - - for ( ; def < limit; def++ ) - { - if ( (FT_Byte)def->opc == CUR.opcode && def->active ) - { - TT_CallRec* call; - - - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - - call = CUR.callStack + CUR.callTop++; - - call->Caller_Range = CUR.curRange; - call->Caller_IP = CUR.IP + 1; - call->Cur_Count = 1; - call->Cur_Restart = def->start; - call->Cur_End = def->end; - - INS_Goto_CodeRange( def->range, def->start ); - - CUR.step_ins = FALSE; - return; - } - } - - CUR.error = FT_THROW( Invalid_Opcode ); - } - - -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - static - TInstruction_Function Instruct_Dispatch[256] = - { - /* Opcodes are gathered in groups of 16. */ - /* Please keep the spaces as they are. */ - - /* SVTCA y */ Ins_SVTCA, - /* SVTCA x */ Ins_SVTCA, - /* SPvTCA y */ Ins_SPVTCA, - /* SPvTCA x */ Ins_SPVTCA, - /* SFvTCA y */ Ins_SFVTCA, - /* SFvTCA x */ Ins_SFVTCA, - /* SPvTL // */ Ins_SPVTL, - /* SPvTL + */ Ins_SPVTL, - /* SFvTL // */ Ins_SFVTL, - /* SFvTL + */ Ins_SFVTL, - /* SPvFS */ Ins_SPVFS, - /* SFvFS */ Ins_SFVFS, - /* GPV */ Ins_GPV, - /* GFV */ Ins_GFV, - /* SFvTPv */ Ins_SFVTPV, - /* ISECT */ Ins_ISECT, - - /* SRP0 */ Ins_SRP0, - /* SRP1 */ Ins_SRP1, - /* SRP2 */ Ins_SRP2, - /* SZP0 */ Ins_SZP0, - /* SZP1 */ Ins_SZP1, - /* SZP2 */ Ins_SZP2, - /* SZPS */ Ins_SZPS, - /* SLOOP */ Ins_SLOOP, - /* RTG */ Ins_RTG, - /* RTHG */ Ins_RTHG, - /* SMD */ Ins_SMD, - /* ELSE */ Ins_ELSE, - /* JMPR */ Ins_JMPR, - /* SCvTCi */ Ins_SCVTCI, - /* SSwCi */ Ins_SSWCI, - /* SSW */ Ins_SSW, - - /* DUP */ Ins_DUP, - /* POP */ Ins_POP, - /* CLEAR */ Ins_CLEAR, - /* SWAP */ Ins_SWAP, - /* DEPTH */ Ins_DEPTH, - /* CINDEX */ Ins_CINDEX, - /* MINDEX */ Ins_MINDEX, - /* AlignPTS */ Ins_ALIGNPTS, - /* INS_0x28 */ Ins_UNKNOWN, - /* UTP */ Ins_UTP, - /* LOOPCALL */ Ins_LOOPCALL, - /* CALL */ Ins_CALL, - /* FDEF */ Ins_FDEF, - /* ENDF */ Ins_ENDF, - /* MDAP[0] */ Ins_MDAP, - /* MDAP[1] */ Ins_MDAP, - - /* IUP[0] */ Ins_IUP, - /* IUP[1] */ Ins_IUP, - /* SHP[0] */ Ins_SHP, - /* SHP[1] */ Ins_SHP, - /* SHC[0] */ Ins_SHC, - /* SHC[1] */ Ins_SHC, - /* SHZ[0] */ Ins_SHZ, - /* SHZ[1] */ Ins_SHZ, - /* SHPIX */ Ins_SHPIX, - /* IP */ Ins_IP, - /* MSIRP[0] */ Ins_MSIRP, - /* MSIRP[1] */ Ins_MSIRP, - /* AlignRP */ Ins_ALIGNRP, - /* RTDG */ Ins_RTDG, - /* MIAP[0] */ Ins_MIAP, - /* MIAP[1] */ Ins_MIAP, - - /* NPushB */ Ins_NPUSHB, - /* NPushW */ Ins_NPUSHW, - /* WS */ Ins_WS, - /* RS */ Ins_RS, - /* WCvtP */ Ins_WCVTP, - /* RCvt */ Ins_RCVT, - /* GC[0] */ Ins_GC, - /* GC[1] */ Ins_GC, - /* SCFS */ Ins_SCFS, - /* MD[0] */ Ins_MD, - /* MD[1] */ Ins_MD, - /* MPPEM */ Ins_MPPEM, - /* MPS */ Ins_MPS, - /* FlipON */ Ins_FLIPON, - /* FlipOFF */ Ins_FLIPOFF, - /* DEBUG */ Ins_DEBUG, - - /* LT */ Ins_LT, - /* LTEQ */ Ins_LTEQ, - /* GT */ Ins_GT, - /* GTEQ */ Ins_GTEQ, - /* EQ */ Ins_EQ, - /* NEQ */ Ins_NEQ, - /* ODD */ Ins_ODD, - /* EVEN */ Ins_EVEN, - /* IF */ Ins_IF, - /* EIF */ Ins_EIF, - /* AND */ Ins_AND, - /* OR */ Ins_OR, - /* NOT */ Ins_NOT, - /* DeltaP1 */ Ins_DELTAP, - /* SDB */ Ins_SDB, - /* SDS */ Ins_SDS, - - /* ADD */ Ins_ADD, - /* SUB */ Ins_SUB, - /* DIV */ Ins_DIV, - /* MUL */ Ins_MUL, - /* ABS */ Ins_ABS, - /* NEG */ Ins_NEG, - /* FLOOR */ Ins_FLOOR, - /* CEILING */ Ins_CEILING, - /* ROUND[0] */ Ins_ROUND, - /* ROUND[1] */ Ins_ROUND, - /* ROUND[2] */ Ins_ROUND, - /* ROUND[3] */ Ins_ROUND, - /* NROUND[0] */ Ins_NROUND, - /* NROUND[1] */ Ins_NROUND, - /* NROUND[2] */ Ins_NROUND, - /* NROUND[3] */ Ins_NROUND, - - /* WCvtF */ Ins_WCVTF, - /* DeltaP2 */ Ins_DELTAP, - /* DeltaP3 */ Ins_DELTAP, - /* DeltaCn[0] */ Ins_DELTAC, - /* DeltaCn[1] */ Ins_DELTAC, - /* DeltaCn[2] */ Ins_DELTAC, - /* SROUND */ Ins_SROUND, - /* S45Round */ Ins_S45ROUND, - /* JROT */ Ins_JROT, - /* JROF */ Ins_JROF, - /* ROFF */ Ins_ROFF, - /* INS_0x7B */ Ins_UNKNOWN, - /* RUTG */ Ins_RUTG, - /* RDTG */ Ins_RDTG, - /* SANGW */ Ins_SANGW, - /* AA */ Ins_AA, - - /* FlipPT */ Ins_FLIPPT, - /* FlipRgON */ Ins_FLIPRGON, - /* FlipRgOFF */ Ins_FLIPRGOFF, - /* INS_0x83 */ Ins_UNKNOWN, - /* INS_0x84 */ Ins_UNKNOWN, - /* ScanCTRL */ Ins_SCANCTRL, - /* SDPVTL[0] */ Ins_SDPVTL, - /* SDPVTL[1] */ Ins_SDPVTL, - /* GetINFO */ Ins_GETINFO, - /* IDEF */ Ins_IDEF, - /* ROLL */ Ins_ROLL, - /* MAX */ Ins_MAX, - /* MIN */ Ins_MIN, - /* ScanTYPE */ Ins_SCANTYPE, - /* InstCTRL */ Ins_INSTCTRL, - /* INS_0x8F */ Ins_UNKNOWN, - - /* INS_0x90 */ Ins_UNKNOWN, - /* INS_0x91 */ Ins_UNKNOWN, - /* INS_0x92 */ Ins_UNKNOWN, - /* INS_0x93 */ Ins_UNKNOWN, - /* INS_0x94 */ Ins_UNKNOWN, - /* INS_0x95 */ Ins_UNKNOWN, - /* INS_0x96 */ Ins_UNKNOWN, - /* INS_0x97 */ Ins_UNKNOWN, - /* INS_0x98 */ Ins_UNKNOWN, - /* INS_0x99 */ Ins_UNKNOWN, - /* INS_0x9A */ Ins_UNKNOWN, - /* INS_0x9B */ Ins_UNKNOWN, - /* INS_0x9C */ Ins_UNKNOWN, - /* INS_0x9D */ Ins_UNKNOWN, - /* INS_0x9E */ Ins_UNKNOWN, - /* INS_0x9F */ Ins_UNKNOWN, - - /* INS_0xA0 */ Ins_UNKNOWN, - /* INS_0xA1 */ Ins_UNKNOWN, - /* INS_0xA2 */ Ins_UNKNOWN, - /* INS_0xA3 */ Ins_UNKNOWN, - /* INS_0xA4 */ Ins_UNKNOWN, - /* INS_0xA5 */ Ins_UNKNOWN, - /* INS_0xA6 */ Ins_UNKNOWN, - /* INS_0xA7 */ Ins_UNKNOWN, - /* INS_0xA8 */ Ins_UNKNOWN, - /* INS_0xA9 */ Ins_UNKNOWN, - /* INS_0xAA */ Ins_UNKNOWN, - /* INS_0xAB */ Ins_UNKNOWN, - /* INS_0xAC */ Ins_UNKNOWN, - /* INS_0xAD */ Ins_UNKNOWN, - /* INS_0xAE */ Ins_UNKNOWN, - /* INS_0xAF */ Ins_UNKNOWN, - - /* PushB[0] */ Ins_PUSHB, - /* PushB[1] */ Ins_PUSHB, - /* PushB[2] */ Ins_PUSHB, - /* PushB[3] */ Ins_PUSHB, - /* PushB[4] */ Ins_PUSHB, - /* PushB[5] */ Ins_PUSHB, - /* PushB[6] */ Ins_PUSHB, - /* PushB[7] */ Ins_PUSHB, - /* PushW[0] */ Ins_PUSHW, - /* PushW[1] */ Ins_PUSHW, - /* PushW[2] */ Ins_PUSHW, - /* PushW[3] */ Ins_PUSHW, - /* PushW[4] */ Ins_PUSHW, - /* PushW[5] */ Ins_PUSHW, - /* PushW[6] */ Ins_PUSHW, - /* PushW[7] */ Ins_PUSHW, - - /* MDRP[00] */ Ins_MDRP, - /* MDRP[01] */ Ins_MDRP, - /* MDRP[02] */ Ins_MDRP, - /* MDRP[03] */ Ins_MDRP, - /* MDRP[04] */ Ins_MDRP, - /* MDRP[05] */ Ins_MDRP, - /* MDRP[06] */ Ins_MDRP, - /* MDRP[07] */ Ins_MDRP, - /* MDRP[08] */ Ins_MDRP, - /* MDRP[09] */ Ins_MDRP, - /* MDRP[10] */ Ins_MDRP, - /* MDRP[11] */ Ins_MDRP, - /* MDRP[12] */ Ins_MDRP, - /* MDRP[13] */ Ins_MDRP, - /* MDRP[14] */ Ins_MDRP, - /* MDRP[15] */ Ins_MDRP, - - /* MDRP[16] */ Ins_MDRP, - /* MDRP[17] */ Ins_MDRP, - /* MDRP[18] */ Ins_MDRP, - /* MDRP[19] */ Ins_MDRP, - /* MDRP[20] */ Ins_MDRP, - /* MDRP[21] */ Ins_MDRP, - /* MDRP[22] */ Ins_MDRP, - /* MDRP[23] */ Ins_MDRP, - /* MDRP[24] */ Ins_MDRP, - /* MDRP[25] */ Ins_MDRP, - /* MDRP[26] */ Ins_MDRP, - /* MDRP[27] */ Ins_MDRP, - /* MDRP[28] */ Ins_MDRP, - /* MDRP[29] */ Ins_MDRP, - /* MDRP[30] */ Ins_MDRP, - /* MDRP[31] */ Ins_MDRP, - - /* MIRP[00] */ Ins_MIRP, - /* MIRP[01] */ Ins_MIRP, - /* MIRP[02] */ Ins_MIRP, - /* MIRP[03] */ Ins_MIRP, - /* MIRP[04] */ Ins_MIRP, - /* MIRP[05] */ Ins_MIRP, - /* MIRP[06] */ Ins_MIRP, - /* MIRP[07] */ Ins_MIRP, - /* MIRP[08] */ Ins_MIRP, - /* MIRP[09] */ Ins_MIRP, - /* MIRP[10] */ Ins_MIRP, - /* MIRP[11] */ Ins_MIRP, - /* MIRP[12] */ Ins_MIRP, - /* MIRP[13] */ Ins_MIRP, - /* MIRP[14] */ Ins_MIRP, - /* MIRP[15] */ Ins_MIRP, - - /* MIRP[16] */ Ins_MIRP, - /* MIRP[17] */ Ins_MIRP, - /* MIRP[18] */ Ins_MIRP, - /* MIRP[19] */ Ins_MIRP, - /* MIRP[20] */ Ins_MIRP, - /* MIRP[21] */ Ins_MIRP, - /* MIRP[22] */ Ins_MIRP, - /* MIRP[23] */ Ins_MIRP, - /* MIRP[24] */ Ins_MIRP, - /* MIRP[25] */ Ins_MIRP, - /* MIRP[26] */ Ins_MIRP, - /* MIRP[27] */ Ins_MIRP, - /* MIRP[28] */ Ins_MIRP, - /* MIRP[29] */ Ins_MIRP, - /* MIRP[30] */ Ins_MIRP, - /* MIRP[31] */ Ins_MIRP - }; - - -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - - /*************************************************************************/ - /* */ - /* RUN */ - /* */ - /* This function executes a run of opcodes. It will exit in the */ - /* following cases: */ - /* */ - /* - Errors (in which case it returns FALSE). */ - /* */ - /* - Reaching the end of the main code range (returns TRUE). */ - /* Reaching the end of a code range within a function call is an */ - /* error. */ - /* */ - /* - After executing one single opcode, if the flag `Instruction_Trap' */ - /* is set to TRUE (returns TRUE). */ - /* */ - /* On exit with TRUE, test IP < CodeSize to know whether it comes from */ - /* an instruction trap or a normal termination. */ - /* */ - /* */ - /* Note: The documented DEBUG opcode pops a value from the stack. This */ - /* behaviour is unsupported; here a DEBUG opcode is always an */ - /* error. */ - /* */ - /* */ - /* THIS IS THE INTERPRETER'S MAIN LOOP. */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /* documentation is in ttinterp.h */ - - FT_EXPORT_DEF( FT_Error ) - TT_RunIns( TT_ExecContext exc ) - { - FT_Long ins_counter = 0; /* executed instructions counter */ - FT_UShort i; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Byte opcode_pattern[1][2] = { - /* #8 TypeMan Talk Align */ - { - 0x06, /* SPVTL */ - 0x7D, /* RDTG */ - }, - }; - FT_UShort opcode_patterns = 1; - FT_UShort opcode_pointer[1] = { 0 }; - FT_UShort opcode_size[1] = { 1 }; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - cur = *exc; -#endif - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - CUR.iup_called = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - /* set CVT functions */ - CUR.tt_metrics.ratio = 0; - if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) - { - /* non-square pixels, use the stretched routines */ - CUR.func_read_cvt = Read_CVT_Stretched; - CUR.func_write_cvt = Write_CVT_Stretched; - CUR.func_move_cvt = Move_CVT_Stretched; - } - else - { - /* square pixels, use normal routines */ - CUR.func_read_cvt = Read_CVT; - CUR.func_write_cvt = Write_CVT; - CUR.func_move_cvt = Move_CVT; - } - - COMPUTE_Funcs(); - COMPUTE_Round( (FT_Byte)exc->GS.round_state ); - - do - { - CUR.opcode = CUR.code[CUR.IP]; - - FT_TRACE7(( " " )); - FT_TRACE7(( opcode_name[CUR.opcode] )); - FT_TRACE7(( "\n" )); - - if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) - { - if ( CUR.IP + 1 >= CUR.codeSize ) - goto LErrorCodeOverflow_; - - CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; - } - - if ( CUR.IP + CUR.length > CUR.codeSize ) - goto LErrorCodeOverflow_; - - /* First, let's check for empty stack and overflow */ - CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); - - /* `args' is the top of the stack once arguments have been popped. */ - /* One can also interpret it as the index of the last argument. */ - if ( CUR.args < 0 ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = FT_THROW( Too_Few_Arguments ); - goto LErrorLabel_; - } - - /* push zeroes onto the stack */ - for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ ) - CUR.stack[i] = 0; - CUR.args = 0; - } - - CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); - - /* `new_top' is the new top of the stack, after the instruction's */ - /* execution. `top' will be set to `new_top' after the `switch' */ - /* statement. */ - if ( CUR.new_top > CUR.stackSize ) - { - CUR.error = FT_THROW( Stack_Overflow ); - goto LErrorLabel_; - } - - CUR.step_ins = TRUE; - CUR.error = FT_Err_Ok; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( SUBPIXEL_HINTING ) - { - for ( i = 0; i < opcode_patterns; i++ ) - { - if ( opcode_pointer[i] < opcode_size[i] && - CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) - { - opcode_pointer[i] += 1; - - if ( opcode_pointer[i] == opcode_size[i] ) - { - FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n", - i, - CUR.face->root.family_name, - CUR.face->root.style_name )); - - switch ( i ) - { - case 0: - break; - } - opcode_pointer[i] = 0; - } - } - else - opcode_pointer[i] = 0; - } - } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - -#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - { - FT_Long* args = CUR.stack + CUR.args; - FT_Byte opcode = CUR.opcode; - - -#undef ARRAY_BOUND_ERROR -#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref - - - switch ( opcode ) - { - case 0x00: /* SVTCA y */ - case 0x01: /* SVTCA x */ - case 0x02: /* SPvTCA y */ - case 0x03: /* SPvTCA x */ - case 0x04: /* SFvTCA y */ - case 0x05: /* SFvTCA x */ - { - FT_Short AA, BB; - - - AA = (FT_Short)( ( opcode & 1 ) << 14 ); - BB = (FT_Short)( AA ^ 0x4000 ); - - if ( opcode < 4 ) - { - CUR.GS.projVector.x = AA; - CUR.GS.projVector.y = BB; - - CUR.GS.dualVector.x = AA; - CUR.GS.dualVector.y = BB; - } - else - { - GUESS_VECTOR( projVector ); - } - - if ( ( opcode & 2 ) == 0 ) - { - CUR.GS.freeVector.x = AA; - CUR.GS.freeVector.y = BB; - } - else - { - GUESS_VECTOR( freeVector ); - } - - COMPUTE_Funcs(); - } - break; - - case 0x06: /* SPvTL // */ - case 0x07: /* SPvTL + */ - DO_SPVTL - break; - - case 0x08: /* SFvTL // */ - case 0x09: /* SFvTL + */ - DO_SFVTL - break; - - case 0x0A: /* SPvFS */ - DO_SPVFS - break; - - case 0x0B: /* SFvFS */ - DO_SFVFS - break; - - case 0x0C: /* GPV */ - DO_GPV - break; - - case 0x0D: /* GFV */ - DO_GFV - break; - - case 0x0E: /* SFvTPv */ - DO_SFVTPV - break; - - case 0x0F: /* ISECT */ - Ins_ISECT( EXEC_ARG_ args ); - break; - - case 0x10: /* SRP0 */ - DO_SRP0 - break; - - case 0x11: /* SRP1 */ - DO_SRP1 - break; - - case 0x12: /* SRP2 */ - DO_SRP2 - break; - - case 0x13: /* SZP0 */ - Ins_SZP0( EXEC_ARG_ args ); - break; - - case 0x14: /* SZP1 */ - Ins_SZP1( EXEC_ARG_ args ); - break; - - case 0x15: /* SZP2 */ - Ins_SZP2( EXEC_ARG_ args ); - break; - - case 0x16: /* SZPS */ - Ins_SZPS( EXEC_ARG_ args ); - break; - - case 0x17: /* SLOOP */ - DO_SLOOP - break; - - case 0x18: /* RTG */ - DO_RTG - break; - - case 0x19: /* RTHG */ - DO_RTHG - break; - - case 0x1A: /* SMD */ - DO_SMD - break; - - case 0x1B: /* ELSE */ - Ins_ELSE( EXEC_ARG_ args ); - break; - - case 0x1C: /* JMPR */ - DO_JMPR - break; - - case 0x1D: /* SCVTCI */ - DO_SCVTCI - break; - - case 0x1E: /* SSWCI */ - DO_SSWCI - break; - - case 0x1F: /* SSW */ - DO_SSW - break; - - case 0x20: /* DUP */ - DO_DUP - break; - - case 0x21: /* POP */ - /* nothing :-) */ - break; - - case 0x22: /* CLEAR */ - DO_CLEAR - break; - - case 0x23: /* SWAP */ - DO_SWAP - break; - - case 0x24: /* DEPTH */ - DO_DEPTH - break; - - case 0x25: /* CINDEX */ - DO_CINDEX - break; - - case 0x26: /* MINDEX */ - Ins_MINDEX( EXEC_ARG_ args ); - break; - - case 0x27: /* ALIGNPTS */ - Ins_ALIGNPTS( EXEC_ARG_ args ); - break; - - case 0x28: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - case 0x29: /* UTP */ - Ins_UTP( EXEC_ARG_ args ); - break; - - case 0x2A: /* LOOPCALL */ - Ins_LOOPCALL( EXEC_ARG_ args ); - break; - - case 0x2B: /* CALL */ - Ins_CALL( EXEC_ARG_ args ); - break; - - case 0x2C: /* FDEF */ - Ins_FDEF( EXEC_ARG_ args ); - break; - - case 0x2D: /* ENDF */ - Ins_ENDF( EXEC_ARG_ args ); - break; - - case 0x2E: /* MDAP */ - case 0x2F: /* MDAP */ - Ins_MDAP( EXEC_ARG_ args ); - break; - - case 0x30: /* IUP */ - case 0x31: /* IUP */ - Ins_IUP( EXEC_ARG_ args ); - break; - - case 0x32: /* SHP */ - case 0x33: /* SHP */ - Ins_SHP( EXEC_ARG_ args ); - break; - - case 0x34: /* SHC */ - case 0x35: /* SHC */ - Ins_SHC( EXEC_ARG_ args ); - break; - - case 0x36: /* SHZ */ - case 0x37: /* SHZ */ - Ins_SHZ( EXEC_ARG_ args ); - break; - - case 0x38: /* SHPIX */ - Ins_SHPIX( EXEC_ARG_ args ); - break; - - case 0x39: /* IP */ - Ins_IP( EXEC_ARG_ args ); - break; - - case 0x3A: /* MSIRP */ - case 0x3B: /* MSIRP */ - Ins_MSIRP( EXEC_ARG_ args ); - break; - - case 0x3C: /* AlignRP */ - Ins_ALIGNRP( EXEC_ARG_ args ); - break; - - case 0x3D: /* RTDG */ - DO_RTDG - break; - - case 0x3E: /* MIAP */ - case 0x3F: /* MIAP */ - Ins_MIAP( EXEC_ARG_ args ); - break; - - case 0x40: /* NPUSHB */ - Ins_NPUSHB( EXEC_ARG_ args ); - break; - - case 0x41: /* NPUSHW */ - Ins_NPUSHW( EXEC_ARG_ args ); - break; - - case 0x42: /* WS */ - DO_WS - break; - - Set_Invalid_Ref: - CUR.error = FT_THROW( Invalid_Reference ); - break; - - case 0x43: /* RS */ - DO_RS - break; - - case 0x44: /* WCVTP */ - DO_WCVTP - break; - - case 0x45: /* RCVT */ - DO_RCVT - break; - - case 0x46: /* GC */ - case 0x47: /* GC */ - Ins_GC( EXEC_ARG_ args ); - break; - - case 0x48: /* SCFS */ - Ins_SCFS( EXEC_ARG_ args ); - break; - - case 0x49: /* MD */ - case 0x4A: /* MD */ - Ins_MD( EXEC_ARG_ args ); - break; - - case 0x4B: /* MPPEM */ - DO_MPPEM - break; - - case 0x4C: /* MPS */ - DO_MPS - break; - - case 0x4D: /* FLIPON */ - DO_FLIPON - break; - - case 0x4E: /* FLIPOFF */ - DO_FLIPOFF - break; - - case 0x4F: /* DEBUG */ - DO_DEBUG - break; - - case 0x50: /* LT */ - DO_LT - break; - - case 0x51: /* LTEQ */ - DO_LTEQ - break; - - case 0x52: /* GT */ - DO_GT - break; - - case 0x53: /* GTEQ */ - DO_GTEQ - break; - - case 0x54: /* EQ */ - DO_EQ - break; - - case 0x55: /* NEQ */ - DO_NEQ - break; - - case 0x56: /* ODD */ - DO_ODD - break; - - case 0x57: /* EVEN */ - DO_EVEN - break; - - case 0x58: /* IF */ - Ins_IF( EXEC_ARG_ args ); - break; - - case 0x59: /* EIF */ - /* do nothing */ - break; - - case 0x5A: /* AND */ - DO_AND - break; - - case 0x5B: /* OR */ - DO_OR - break; - - case 0x5C: /* NOT */ - DO_NOT - break; - - case 0x5D: /* DELTAP1 */ - Ins_DELTAP( EXEC_ARG_ args ); - break; - - case 0x5E: /* SDB */ - DO_SDB - break; - - case 0x5F: /* SDS */ - DO_SDS - break; - - case 0x60: /* ADD */ - DO_ADD - break; - - case 0x61: /* SUB */ - DO_SUB - break; - - case 0x62: /* DIV */ - DO_DIV - break; - - case 0x63: /* MUL */ - DO_MUL - break; - - case 0x64: /* ABS */ - DO_ABS - break; - - case 0x65: /* NEG */ - DO_NEG - break; - - case 0x66: /* FLOOR */ - DO_FLOOR - break; - - case 0x67: /* CEILING */ - DO_CEILING - break; - - case 0x68: /* ROUND */ - case 0x69: /* ROUND */ - case 0x6A: /* ROUND */ - case 0x6B: /* ROUND */ - DO_ROUND - break; - - case 0x6C: /* NROUND */ - case 0x6D: /* NROUND */ - case 0x6E: /* NRRUND */ - case 0x6F: /* NROUND */ - DO_NROUND - break; - - case 0x70: /* WCVTF */ - DO_WCVTF - break; - - case 0x71: /* DELTAP2 */ - case 0x72: /* DELTAP3 */ - Ins_DELTAP( EXEC_ARG_ args ); - break; - - case 0x73: /* DELTAC0 */ - case 0x74: /* DELTAC1 */ - case 0x75: /* DELTAC2 */ - Ins_DELTAC( EXEC_ARG_ args ); - break; - - case 0x76: /* SROUND */ - DO_SROUND - break; - - case 0x77: /* S45Round */ - DO_S45ROUND - break; - - case 0x78: /* JROT */ - DO_JROT - break; - - case 0x79: /* JROF */ - DO_JROF - break; - - case 0x7A: /* ROFF */ - DO_ROFF - break; - - case 0x7B: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - case 0x7C: /* RUTG */ - DO_RUTG - break; - - case 0x7D: /* RDTG */ - DO_RDTG - break; - - case 0x7E: /* SANGW */ - case 0x7F: /* AA */ - /* nothing - obsolete */ - break; - - case 0x80: /* FLIPPT */ - Ins_FLIPPT( EXEC_ARG_ args ); - break; - - case 0x81: /* FLIPRGON */ - Ins_FLIPRGON( EXEC_ARG_ args ); - break; - - case 0x82: /* FLIPRGOFF */ - Ins_FLIPRGOFF( EXEC_ARG_ args ); - break; - - case 0x83: /* UNKNOWN */ - case 0x84: /* UNKNOWN */ - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - case 0x85: /* SCANCTRL */ - Ins_SCANCTRL( EXEC_ARG_ args ); - break; - - case 0x86: /* SDPVTL */ - case 0x87: /* SDPVTL */ - Ins_SDPVTL( EXEC_ARG_ args ); - break; - - case 0x88: /* GETINFO */ - Ins_GETINFO( EXEC_ARG_ args ); - break; - - case 0x89: /* IDEF */ - Ins_IDEF( EXEC_ARG_ args ); - break; - - case 0x8A: /* ROLL */ - Ins_ROLL( EXEC_ARG_ args ); - break; - - case 0x8B: /* MAX */ - DO_MAX - break; - - case 0x8C: /* MIN */ - DO_MIN - break; - - case 0x8D: /* SCANTYPE */ - Ins_SCANTYPE( EXEC_ARG_ args ); - break; - - case 0x8E: /* INSTCTRL */ - Ins_INSTCTRL( EXEC_ARG_ args ); - break; - - case 0x8F: - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - default: - if ( opcode >= 0xE0 ) - Ins_MIRP( EXEC_ARG_ args ); - else if ( opcode >= 0xC0 ) - Ins_MDRP( EXEC_ARG_ args ); - else if ( opcode >= 0xB8 ) - Ins_PUSHW( EXEC_ARG_ args ); - else if ( opcode >= 0xB0 ) - Ins_PUSHB( EXEC_ARG_ args ); - else - Ins_UNKNOWN( EXEC_ARG_ args ); - } - - } - -#else - - Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); - -#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - if ( CUR.error ) - { - switch ( CUR.error ) - { - /* looking for redefined instructions */ - case FT_ERR( Invalid_Opcode ): - { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; - - - for ( ; def < limit; def++ ) - { - if ( def->active && CUR.opcode == (FT_Byte)def->opc ) - { - TT_CallRec* callrec; - - - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = FT_THROW( Invalid_Reference ); - goto LErrorLabel_; - } - - callrec = &CUR.callStack[CUR.callTop]; - - callrec->Caller_Range = CUR.curRange; - callrec->Caller_IP = CUR.IP + 1; - callrec->Cur_Count = 1; - callrec->Cur_Restart = def->start; - callrec->Cur_End = def->end; - - if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) - goto LErrorLabel_; - - goto LSuiteLabel_; - } - } - } - - CUR.error = FT_THROW( Invalid_Opcode ); - goto LErrorLabel_; - -#if 0 - break; /* Unreachable code warning suppression. */ - /* Leave to remind in case a later change the editor */ - /* to consider break; */ -#endif - - default: - goto LErrorLabel_; - -#if 0 - break; -#endif - } - } - - CUR.top = CUR.new_top; - - if ( CUR.step_ins ) - CUR.IP += CUR.length; - - /* increment instruction counter and check if we didn't */ - /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) - return FT_THROW( Execution_Too_Long ); - - LSuiteLabel_: - if ( CUR.IP >= CUR.codeSize ) - { - if ( CUR.callTop > 0 ) - { - CUR.error = FT_THROW( Code_Overflow ); - goto LErrorLabel_; - } - else - goto LNo_Error_; - } - } while ( !CUR.instruction_trap ); - - LNo_Error_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - - return FT_Err_Ok; - - LErrorCodeOverflow_: - CUR.error = FT_THROW( Code_Overflow ); - - LErrorLabel_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - - /* If any errors have occurred, function tables may be broken. */ - /* Force a re-execution of `prep' and `fpgm' tables if no */ - /* bytecode debugger is run. */ - if ( CUR.error && !CUR.instruction_trap ) - { - FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); - exc->size->cvt_ready = FALSE; - } - - return CUR.error; - } - - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttinterp.h b/drivers/freetype/freetype/src/truetype/ttinterp.h deleted file mode 100644 index 69f5011ed4..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttinterp.h +++ /dev/null @@ -1,397 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttinterp.h */ -/* */ -/* TrueType bytecode interpreter (specification). */ -/* */ -/* Copyright 1996-2007, 2010, 2012-2013 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 __TTINTERP_H__ -#define __TTINTERP_H__ - -#include <ft2build.h> -#include "ttobjs.h" - - -FT_BEGIN_HEADER - - -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ - -#define EXEC_OP_ TT_ExecContext exc, -#define EXEC_OP TT_ExecContext exc -#define EXEC_ARG_ exc, -#define EXEC_ARG exc - -#else /* static implementation */ - -#define EXEC_OP_ /* void */ -#define EXEC_OP /* void */ -#define EXEC_ARG_ /* void */ -#define EXEC_ARG /* void */ - -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* Rounding mode constants. */ - /* */ -#define TT_Round_Off 5 -#define TT_Round_To_Half_Grid 0 -#define TT_Round_To_Grid 1 -#define TT_Round_To_Double_Grid 2 -#define TT_Round_Up_To_Grid 4 -#define TT_Round_Down_To_Grid 3 -#define TT_Round_Super 6 -#define TT_Round_Super_45 7 - - - /*************************************************************************/ - /* */ - /* Function types used by the interpreter, depending on various modes */ - /* (e.g. the rounding mode, whether to render a vertical or horizontal */ - /* line etc). */ - /* */ - /*************************************************************************/ - - /* Rounding function */ - typedef FT_F26Dot6 - (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ); - - /* Point displacement along the freedom vector routine */ - typedef void - (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ); - - /* Distance projection along one of the projection vectors */ - typedef FT_F26Dot6 - (*TT_Project_Func)( EXEC_OP_ FT_Pos dx, - FT_Pos dy ); - - /* reading a cvt value. Take care of non-square pixels if necessary */ - typedef FT_F26Dot6 - (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx ); - - /* setting or moving a cvt value. Take care of non-square pixels */ - /* if necessary */ - typedef void - (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ); - - - /*************************************************************************/ - /* */ - /* This structure defines a call record, used to manage function calls. */ - /* */ - typedef struct TT_CallRec_ - { - FT_Int Caller_Range; - FT_Long Caller_IP; - FT_Long Cur_Count; - FT_Long Cur_Restart; - FT_Long Cur_End; - - } TT_CallRec, *TT_CallStack; - - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - /*************************************************************************/ - /* */ - /* These structures define rules used to tweak subpixel hinting for */ - /* various fonts. "", 0, "", NULL value indicates to match any value. */ - /* */ - -#define SPH_MAX_NAME_SIZE 32 -#define SPH_MAX_CLASS_MEMBERS 100 - - typedef struct SPH_TweakRule_ - { - const char family[SPH_MAX_NAME_SIZE]; - const FT_UInt ppem; - const char style[SPH_MAX_NAME_SIZE]; - const FT_ULong glyph; - - } SPH_TweakRule; - - - typedef struct SPH_ScaleRule_ - { - const char family[SPH_MAX_NAME_SIZE]; - const FT_UInt ppem; - const char style[SPH_MAX_NAME_SIZE]; - const FT_ULong glyph; - const FT_ULong scale; - - } SPH_ScaleRule; - - - typedef struct SPH_Font_Class_ - { - const char name[SPH_MAX_NAME_SIZE]; - const char member[SPH_MAX_CLASS_MEMBERS][SPH_MAX_NAME_SIZE]; - - } SPH_Font_Class; - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /*************************************************************************/ - /* */ - /* The main structure for the interpreter which collects all necessary */ - /* variables and states. */ - /* */ - typedef struct TT_ExecContextRec_ - { - TT_Face face; - TT_Size size; - FT_Memory memory; - - /* instructions state */ - - FT_Error error; /* last execution error */ - - FT_Long top; /* top of exec. stack */ - - FT_UInt stackSize; /* size of exec. stack */ - FT_Long* stack; /* current exec. stack */ - - FT_Long args; - FT_UInt new_top; /* new top after exec. */ - - TT_GlyphZoneRec zp0, /* zone records */ - zp1, - zp2, - pts, - twilight; - - FT_Size_Metrics metrics; - TT_Size_Metrics tt_metrics; /* size metrics */ - - TT_GraphicsState GS; /* current graphics state */ - - FT_Int curRange; /* current code range number */ - FT_Byte* code; /* current code range */ - FT_Long IP; /* current instruction pointer */ - FT_Long codeSize; /* size of current range */ - - FT_Byte opcode; /* current opcode */ - FT_Int length; /* length of current opcode */ - - FT_Bool step_ins; /* true if the interpreter must */ - /* increment IP after ins. exec */ - FT_ULong cvtSize; - FT_Long* cvt; - - FT_UInt glyphSize; /* glyph instructions buffer size */ - FT_Byte* glyphIns; /* glyph instructions buffer */ - - FT_UInt numFDefs; /* number of function defs */ - FT_UInt maxFDefs; /* maximum number of function defs */ - TT_DefArray FDefs; /* table of FDefs entries */ - - FT_UInt numIDefs; /* number of instruction defs */ - FT_UInt maxIDefs; /* maximum number of ins defs */ - TT_DefArray IDefs; /* table of IDefs entries */ - - FT_UInt maxFunc; /* maximum function index */ - FT_UInt maxIns; /* maximum instruction index */ - - FT_Int callTop, /* top of call stack during execution */ - callSize; /* size of call stack */ - TT_CallStack callStack; /* call stack */ - - FT_UShort maxPoints; /* capacity of this context's `pts' */ - FT_Short maxContours; /* record, expressed in points and */ - /* contours. */ - - TT_CodeRangeTable codeRangeTable; /* table of valid code ranges */ - /* useful for the debugger */ - - FT_UShort storeSize; /* size of current storage */ - FT_Long* storage; /* storage area */ - - FT_F26Dot6 period; /* values used for the */ - FT_F26Dot6 phase; /* `SuperRounding' */ - FT_F26Dot6 threshold; - -#if 0 - /* this seems to be unused */ - FT_Int cur_ppem; /* ppem along the current proj vector */ -#endif - - FT_Bool instruction_trap; /* If `True', the interpreter will */ - /* exit after each instruction */ - - TT_GraphicsState default_GS; /* graphics state resulting from */ - /* the prep program */ - FT_Bool is_composite; /* true if the glyph is composite */ - FT_Bool pedantic_hinting; /* true if pedantic interpretation */ - - /* latest interpreter additions */ - - FT_Long F_dot_P; /* dot product of freedom and projection */ - /* vectors */ - TT_Round_Func func_round; /* current rounding function */ - - TT_Project_Func func_project, /* current projection function */ - func_dualproj, /* current dual proj. function */ - func_freeProj; /* current freedom proj. func */ - - TT_Move_Func func_move; /* current point move function */ - TT_Move_Func func_move_orig; /* move original position function */ - - TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ - TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ - TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ - - FT_Bool grayscale; /* are we hinting for grayscale? */ - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Round_Func func_round_sphn; /* subpixel rounding function */ - - FT_Bool grayscale_hinting; /* Using grayscale hinting? */ - FT_Bool subpixel_hinting; /* Using subpixel hinting? */ - FT_Bool native_hinting; /* Using native hinting? */ - FT_Bool ignore_x_mode; /* Standard rendering mode for */ - /* subpixel hinting. On if gray */ - /* or subpixel hinting is on ) */ - - /* The following 4 aren't fully implemented but here for MS rasterizer */ - /* compatibility. */ - FT_Bool compatible_widths; /* compatible widths? */ - FT_Bool symmetrical_smoothing; /* symmetrical_smoothing? */ - FT_Bool bgr; /* bgr instead of rgb? */ - FT_Bool subpixel_positioned; /* subpixel positioned */ - /* (DirectWrite ClearType)? */ - - FT_Int rasterizer_version; /* MS rasterizer version */ - - FT_Bool iup_called; /* IUP called for glyph? */ - - FT_ULong sph_tweak_flags; /* flags to control */ - /* hint tweaks */ - - FT_ULong sph_in_func_flags; /* flags to indicate if in */ - /* special functions */ - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - } TT_ExecContextRec; - - - extern const TT_GraphicsState tt_default_graphics_state; - - -#ifdef TT_USE_BYTECODE_INTERPRETER - FT_LOCAL( FT_Error ) - TT_Goto_CodeRange( TT_ExecContext exec, - FT_Int range, - FT_Long IP ); - - FT_LOCAL( FT_Error ) - TT_Set_CodeRange( TT_ExecContext exec, - FT_Int range, - void* base, - FT_Long length ); - - FT_LOCAL( FT_Error ) - TT_Clear_CodeRange( TT_ExecContext exec, - FT_Int range ); - - - FT_LOCAL( FT_Error ) - Update_Max( FT_Memory memory, - FT_ULong* size, - FT_Long multiplier, - void* _pbuff, - FT_ULong new_max ); -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_New_Context */ - /* */ - /* <Description> */ - /* Queries the face context for a given font. Note that there is */ - /* now a _single_ execution context in the TrueType driver which is */ - /* shared among faces. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Return> */ - /* A handle to the execution context. Initialized for `face'. */ - /* */ - /* <Note> */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - FT_EXPORT( TT_ExecContext ) - TT_New_Context( TT_Driver driver ); - - -#ifdef TT_USE_BYTECODE_INTERPRETER - FT_LOCAL( FT_Error ) - TT_Done_Context( TT_ExecContext exec ); - - FT_LOCAL( FT_Error ) - TT_Load_Context( TT_ExecContext exec, - TT_Face face, - TT_Size size ); - - FT_LOCAL( FT_Error ) - TT_Save_Context( TT_ExecContext exec, - TT_Size ins ); - - FT_LOCAL( FT_Error ) - TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ); -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* TT_RunIns */ - /* */ - /* <Description> */ - /* Executes one or more instruction in the execution context. This */ - /* is the main function of the TrueType opcode interpreter. */ - /* */ - /* <Input> */ - /* exec :: A handle to the target execution context. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only the object manager and debugger should call this function. */ - /* */ - /* This function is publicly exported because it is directly */ - /* invoked by the TrueType debugger. */ - /* */ - FT_EXPORT( FT_Error ) - TT_RunIns( TT_ExecContext exec ); - - -FT_END_HEADER - -#endif /* __TTINTERP_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttobjs.c b/drivers/freetype/freetype/src/truetype/ttobjs.c deleted file mode 100644 index 7897efa77a..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttobjs.c +++ /dev/null @@ -1,1331 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttobjs.c */ -/* */ -/* Objects manager (body). */ -/* */ -/* Copyright 1996-2013 */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H -#include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_DRIVER_H - -#include "ttgload.h" -#include "ttpload.h" - -#include "tterrors.h" - -#ifdef TT_USE_BYTECODE_INTERPRETER -#include "ttinterp.h" -#endif - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#include FT_TRUETYPE_UNPATENTED_H -#endif - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#include "ttgxvar.h" -#endif - - /*************************************************************************/ - /* */ - /* 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_ttobjs - - -#ifdef TT_USE_BYTECODE_INTERPRETER - - /*************************************************************************/ - /* */ - /* GLYPH ZONE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_glyphzone_done */ - /* */ - /* <Description> */ - /* Deallocate a glyph zone. */ - /* */ - /* <Input> */ - /* zone :: A pointer to the target glyph zone. */ - /* */ - FT_LOCAL_DEF( void ) - tt_glyphzone_done( TT_GlyphZone zone ) - { - FT_Memory memory = zone->memory; - - - if ( memory ) - { - FT_FREE( zone->contours ); - FT_FREE( zone->tags ); - FT_FREE( zone->cur ); - FT_FREE( zone->org ); - FT_FREE( zone->orus ); - - zone->max_points = zone->n_points = 0; - zone->max_contours = zone->n_contours = 0; - zone->memory = NULL; - } - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_glyphzone_new */ - /* */ - /* <Description> */ - /* Allocate a new glyph zone. */ - /* */ - /* <Input> */ - /* memory :: A handle to the current memory object. */ - /* */ - /* maxPoints :: The capacity of glyph zone in points. */ - /* */ - /* maxContours :: The capacity of glyph zone in contours. */ - /* */ - /* <Output> */ - /* zone :: A pointer to the target glyph zone record. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_glyphzone_new( FT_Memory memory, - FT_UShort maxPoints, - FT_Short maxContours, - TT_GlyphZone zone ) - { - FT_Error error; - - - FT_MEM_ZERO( zone, sizeof ( *zone ) ); - zone->memory = memory; - - if ( FT_NEW_ARRAY( zone->org, maxPoints ) || - FT_NEW_ARRAY( zone->cur, maxPoints ) || - FT_NEW_ARRAY( zone->orus, maxPoints ) || - FT_NEW_ARRAY( zone->tags, maxPoints ) || - FT_NEW_ARRAY( zone->contours, maxContours ) ) - { - tt_glyphzone_done( zone ); - } - else - { - zone->max_points = maxPoints; - zone->max_contours = maxContours; - } - - return error; - } -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - - /* Compare the face with a list of well-known `tricky' fonts. */ - /* This list shall be expanded as we find more of them. */ - - static FT_Bool - tt_check_trickyness_family( FT_String* name ) - { - -#define TRICK_NAMES_MAX_CHARACTERS 16 -#define TRICK_NAMES_COUNT 8 - - static const char trick_names[TRICK_NAMES_COUNT] - [TRICK_NAMES_MAX_CHARACTERS + 1] = - { - "DFKaiSho-SB", /* dfkaisb.ttf */ - "DFKaiShu", - "DFKai-SB", /* kaiu.ttf */ - "HuaTianKaiTi?", /* htkt2.ttf */ - "HuaTianSongTi?", /* htst3.ttf */ - "MingLiU", /* mingliu.ttf & mingliu.ttc */ - "PMingLiU", /* mingliu.ttc */ - "MingLi43", /* mingli.ttf */ - }; - - int nn; - - - for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) - if ( ft_strstr( name, trick_names[nn] ) ) - return TRUE; - - return FALSE; - } - - - /* XXX: This function should be in the `sfnt' module. */ - - /* Some PDF generators clear the checksums in the TrueType header table. */ - /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */ - /* Printer clears the entries for subsetted subtables. We thus have to */ - /* recalculate the checksums where necessary. */ - - static FT_UInt32 - tt_synth_sfnt_checksum( FT_Stream stream, - FT_ULong length ) - { - FT_Error error; - FT_UInt32 checksum = 0; - int i; - - - if ( FT_FRAME_ENTER( length ) ) - return 0; - - for ( ; length > 3; length -= 4 ) - checksum += (FT_UInt32)FT_GET_ULONG(); - - for ( i = 3; length > 0; length --, i-- ) - checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) ); - - FT_FRAME_EXIT(); - - return checksum; - } - - - /* XXX: This function should be in the `sfnt' module. */ - - static FT_ULong - tt_get_sfnt_checksum( TT_Face face, - FT_UShort i ) - { -#if 0 /* if we believe the written value, use following part. */ - if ( face->dir_tables[i].CheckSum ) - return face->dir_tables[i].CheckSum; -#endif - - if ( !face->goto_table ) - return 0; - - if ( face->goto_table( face, - face->dir_tables[i].Tag, - face->root.stream, - NULL ) ) - return 0; - - return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream, - face->dir_tables[i].Length ); - } - - - typedef struct tt_sfnt_id_rec_ - { - FT_ULong CheckSum; - FT_ULong Length; - - } tt_sfnt_id_rec; - - - static FT_Bool - tt_check_trickyness_sfnt_ids( TT_Face face ) - { -#define TRICK_SFNT_IDS_PER_FACE 3 -#define TRICK_SFNT_IDS_NUM_FACES 17 - - static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] - [TRICK_SFNT_IDS_PER_FACE] = { - -#define TRICK_SFNT_ID_cvt 0 -#define TRICK_SFNT_ID_fpgm 1 -#define TRICK_SFNT_ID_prep 2 - - { /* MingLiU 1995 */ - { 0x05bcf058, 0x000002e4 }, /* cvt */ - { 0x28233bf1, 0x000087c4 }, /* fpgm */ - { 0xa344a1ea, 0x000001e1 } /* prep */ - }, - { /* MingLiU 1996- */ - { 0x05bcf058, 0x000002e4 }, /* cvt */ - { 0x28233bf1, 0x000087c4 }, /* fpgm */ - { 0xa344a1eb, 0x000001e1 } /* prep */ - }, - { /* DFKaiShu */ - { 0x11e5ead4, 0x00000350 }, /* cvt */ - { 0x5a30ca3b, 0x00009063 }, /* fpgm */ - { 0x13a42602, 0x0000007e } /* prep */ - }, - { /* HuaTianKaiTi */ - { 0xfffbfffc, 0x00000008 }, /* cvt */ - { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */ - { 0x70020112, 0x00000008 } /* prep */ - }, - { /* HuaTianSongTi */ - { 0xfffbfffc, 0x00000008 }, /* cvt */ - { 0x0a5a0483, 0x00017c39 }, /* fpgm */ - { 0x70020112, 0x00000008 } /* prep */ - }, - { /* NEC fadpop7.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40c92555, 0x000000e5 }, /* fpgm */ - { 0xa39b58e3, 0x0000117c } /* prep */ - }, - { /* NEC fadrei5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x33c41652, 0x000000e5 }, /* fpgm */ - { 0x26d6c52a, 0x00000f6a } /* prep */ - }, - { /* NEC fangot7.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x6db1651d, 0x0000019d }, /* fpgm */ - { 0x6c6e4b03, 0x00002492 } /* prep */ - }, - { /* NEC fangyo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40c92555, 0x000000e5 }, /* fpgm */ - { 0xde51fad0, 0x0000117c } /* prep */ - }, - { /* NEC fankyo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x85e47664, 0x000000e5 }, /* fpgm */ - { 0xa6c62831, 0x00001caa } /* prep */ - }, - { /* NEC fanrgo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x2d891cfd, 0x0000019d }, /* fpgm */ - { 0xa0604633, 0x00001de8 } /* prep */ - }, - { /* NEC fangot5.ttc */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40aa774c, 0x000001cb }, /* fpgm */ - { 0x9b5caa96, 0x00001f9a } /* prep */ - }, - { /* NEC fanmin3.ttc */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x0d3de9cb, 0x00000141 }, /* fpgm */ - { 0xd4127766, 0x00002280 } /* prep */ - }, - { /* NEC FA-Gothic, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x4a692698, 0x000001f0 }, /* fpgm */ - { 0x340d4346, 0x00001fca } /* prep */ - }, - { /* NEC FA-Minchou, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0xcd34c604, 0x00000166 }, /* fpgm */ - { 0x6cf31046, 0x000022b0 } /* prep */ - }, - { /* NEC FA-RoundGothicB, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x5da75315, 0x0000019d }, /* fpgm */ - { 0x40745a5f, 0x000022e0 } /* prep */ - }, - { /* NEC FA-RoundGothicM, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0xf055fc48, 0x000001c2 }, /* fpgm */ - { 0x3900ded3, 0x00001e18 } /* prep */ - } - }; - - FT_ULong checksum; - int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES]; - FT_Bool has_cvt, has_fpgm, has_prep; - FT_UShort i; - int j, k; - - - FT_MEM_SET( num_matched_ids, 0, - sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES ); - has_cvt = FALSE; - has_fpgm = FALSE; - has_prep = FALSE; - - for ( i = 0; i < face->num_tables; i++ ) - { - checksum = 0; - - switch( face->dir_tables[i].Tag ) - { - case TTAG_cvt: - k = TRICK_SFNT_ID_cvt; - has_cvt = TRUE; - break; - - case TTAG_fpgm: - k = TRICK_SFNT_ID_fpgm; - has_fpgm = TRUE; - break; - - case TTAG_prep: - k = TRICK_SFNT_ID_prep; - has_prep = TRUE; - break; - - default: - continue; - } - - for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) - if ( face->dir_tables[i].Length == sfnt_id[j][k].Length ) - { - if ( !checksum ) - checksum = tt_get_sfnt_checksum( face, i ); - - if ( sfnt_id[j][k].CheckSum == checksum ) - num_matched_ids[j]++; - - if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) - return TRUE; - } - } - - for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) - { - if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) - num_matched_ids[j] ++; - if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) - num_matched_ids[j] ++; - if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) - num_matched_ids[j] ++; - if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) - return TRUE; - } - - return FALSE; - } - - - static FT_Bool - tt_check_trickyness( FT_Face face ) - { - if ( !face ) - return FALSE; - - /* For first, check the face name for quick check. */ - if ( face->family_name && - tt_check_trickyness_family( face->family_name ) ) - return TRUE; - - /* Type42 fonts may lack `name' tables, we thus try to identify */ - /* tricky fonts by checking the checksums of Type42-persistent */ - /* sfnt tables (`cvt', `fpgm', and `prep'). */ - if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) ) - return TRUE; - - return FALSE; - } - - - /* Check whether `.notdef' is the only glyph in the `loca' table. */ - static FT_Bool - tt_check_single_notdef( FT_Face ttface ) - { - FT_Bool result = FALSE; - - TT_Face face = (TT_Face)ttface; - FT_UInt asize; - FT_ULong i; - FT_ULong glyph_index = 0; - FT_UInt count = 0; - - - for( i = 0; i < face->num_locations; i++ ) - { - tt_face_get_location( face, i, &asize ); - if ( asize > 0 ) - { - count += 1; - if ( count > 1 ) - break; - glyph_index = i; - } - } - - /* Only have a single outline. */ - if ( count == 1 ) - { - if ( glyph_index == 0 ) - result = TRUE; - else - { - /* FIXME: Need to test glyphname == .notdef ? */ - FT_Error error; - char buf[8]; - - - error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 ); - if ( !error && - buf[0] == '.' && !ft_strncmp( buf, ".notdef", 8 ) ) - result = TRUE; - } - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_init */ - /* */ - /* <Description> */ - /* Initialize a given TrueType face object. */ - /* */ - /* <Input> */ - /* stream :: The source font stream. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* <InOut> */ - /* face :: The newly built face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_init( FT_Stream stream, - FT_Face ttface, /* TT_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - FT_Library library; - SFNT_Service sfnt; - TT_Face face = (TT_Face)ttface; - - - FT_TRACE2(( "TTF driver\n" )); - - library = ttface->driver->root.library; - - sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); - if ( !sfnt ) - { - FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" )); - error = FT_THROW( Missing_Module ); - goto Exit; - } - - /* create input stream from resource */ - if ( FT_STREAM_SEEK( 0 ) ) - goto Exit; - - /* check that we have a valid TrueType file */ - error = sfnt->init_face( stream, face, face_index, num_params, params ); - if ( error ) - goto Exit; - - /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ - /* The 0x00020000 tag is completely undocumented; some fonts from */ - /* Arphic made for Chinese Windows 3.1 have this. */ - if ( face->format_tag != 0x00010000L && /* MS fonts */ - face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ - face->format_tag != TTAG_true ) /* Mac fonts */ - { - FT_TRACE2(( " not a TTF font\n" )); - goto Bad_Format; - } - -#ifdef TT_USE_BYTECODE_INTERPRETER - ttface->face_flags |= FT_FACE_FLAG_HINTER; -#endif - - /* If we are performing a simple font format check, exit immediately. */ - if ( face_index < 0 ) - return FT_Err_Ok; - - /* Load font directory */ - error = sfnt->load_face( stream, face, face_index, num_params, params ); - if ( error ) - goto Exit; - - if ( tt_check_trickyness( ttface ) ) - ttface->face_flags |= FT_FACE_FLAG_TRICKY; - - error = tt_face_load_hdmx( face, stream ); - if ( error ) - goto Exit; - - if ( FT_IS_SCALABLE( ttface ) ) - { - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - if ( !ttface->internal->incremental_interface ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); - - /* Check the scalable flag based on `loca'. */ - if ( !ttface->internal->incremental_interface && - ttface->num_fixed_sizes && - face->glyph_locations && - tt_check_single_notdef( ttface ) ) - { - FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " - " Resetting scalable flag to FALSE.\n" )); - - ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; - } - -#else - - if ( !error ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); - - /* Check the scalable flag based on `loca'. */ - if ( ttface->num_fixed_sizes && - face->glyph_locations && - tt_check_single_notdef( ttface ) ) - { - FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " - " Resetting scalable flag to FALSE.\n" )); - - ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; - } - -#endif - - } - -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) - - { - FT_Bool unpatented_hinting; - int i; - - - /* Determine whether unpatented hinting is to be used for this face. */ - unpatented_hinting = FT_BOOL - ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); - - for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) - if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) - unpatented_hinting = TRUE; - - if ( !unpatented_hinting ) - ttface->internal->ignore_unpatented_hinter = TRUE; - } - -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && - !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - /* initialize standard glyph loading routines */ - TT_Init_Glyph_Loading( face ); - - Exit: - return error; - - Bad_Format: - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_done */ - /* */ - /* <Description> */ - /* Finalize a given face object. */ - /* */ - /* <Input> */ - /* face :: A pointer to the face object to destroy. */ - /* */ - FT_LOCAL_DEF( void ) - tt_face_done( FT_Face ttface ) /* TT_Face */ - { - TT_Face face = (TT_Face)ttface; - FT_Memory memory; - FT_Stream stream; - SFNT_Service sfnt; - - - if ( !face ) - return; - - memory = ttface->memory; - stream = ttface->stream; - sfnt = (SFNT_Service)face->sfnt; - - /* for `extended TrueType formats' (i.e. compressed versions) */ - if ( face->extra.finalizer ) - face->extra.finalizer( face->extra.data ); - - if ( sfnt ) - sfnt->done_face( face ); - - /* freeing the locations table */ - tt_face_done_loca( face ); - - tt_face_free_hdmx( face ); - - /* freeing the CVT */ - FT_FREE( face->cvt ); - face->cvt_size = 0; - - /* freeing the programs */ - FT_FRAME_RELEASE( face->font_program ); - FT_FRAME_RELEASE( face->cvt_program ); - face->font_program_size = 0; - face->cvt_program_size = 0; - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - tt_done_blend( memory, face->blend ); - face->blend = NULL; -#endif - } - - - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ - -#ifdef TT_USE_BYTECODE_INTERPRETER - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_size_run_fpgm */ - /* */ - /* <Description> */ - /* Run the font program. */ - /* */ - /* <Input> */ - /* size :: A handle to the size object. */ - /* */ - /* pedantic :: Set if bytecode execution should be pedantic. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_size_run_fpgm( TT_Size size, - FT_Bool pedantic ) - { - TT_Face face = (TT_Face)size->root.face; - TT_ExecContext exec; - FT_Error error; - - - /* debugging instances have their own context */ - if ( size->debug ) - exec = size->context; - else - exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; - - if ( !exec ) - return FT_THROW( Could_Not_Find_Context ); - - TT_Load_Context( exec, face, size ); - - exec->callTop = 0; - exec->top = 0; - - exec->period = 64; - exec->phase = 0; - exec->threshold = 0; - - exec->instruction_trap = FALSE; - exec->F_dot_P = 0x4000L; - - exec->pedantic_hinting = pedantic; - - { - FT_Size_Metrics* metrics = &exec->metrics; - TT_Size_Metrics* tt_metrics = &exec->tt_metrics; - - - metrics->x_ppem = 0; - metrics->y_ppem = 0; - metrics->x_scale = 0; - metrics->y_scale = 0; - - tt_metrics->ppem = 0; - tt_metrics->scale = 0; - tt_metrics->ratio = 0x10000L; - } - - /* allow font program execution */ - TT_Set_CodeRange( exec, - tt_coderange_font, - face->font_program, - face->font_program_size ); - - /* disable CVT and glyph programs coderange */ - TT_Clear_CodeRange( exec, tt_coderange_cvt ); - TT_Clear_CodeRange( exec, tt_coderange_glyph ); - - if ( face->font_program_size > 0 ) - { - error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); - - if ( !error ) - { - FT_TRACE4(( "Executing `fpgm' table.\n" )); - - error = face->interpreter( exec ); - } - } - else - error = FT_Err_Ok; - - if ( !error ) - TT_Save_Context( exec, size ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_size_run_prep */ - /* */ - /* <Description> */ - /* Run the control value program. */ - /* */ - /* <Input> */ - /* size :: A handle to the size object. */ - /* */ - /* pedantic :: Set if bytecode execution should be pedantic. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_size_run_prep( TT_Size size, - FT_Bool pedantic ) - { - TT_Face face = (TT_Face)size->root.face; - TT_ExecContext exec; - FT_Error error; - - - /* debugging instances have their own context */ - if ( size->debug ) - exec = size->context; - else - exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; - - if ( !exec ) - return FT_THROW( Could_Not_Find_Context ); - - TT_Load_Context( exec, face, size ); - - exec->callTop = 0; - exec->top = 0; - - exec->instruction_trap = FALSE; - - exec->pedantic_hinting = pedantic; - - TT_Set_CodeRange( exec, - tt_coderange_cvt, - face->cvt_program, - face->cvt_program_size ); - - TT_Clear_CodeRange( exec, tt_coderange_glyph ); - - if ( face->cvt_program_size > 0 ) - { - error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); - - if ( !error && !size->debug ) - { - FT_TRACE4(( "Executing `prep' table.\n" )); - - error = face->interpreter( exec ); - } - } - else - error = FT_Err_Ok; - - /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */ - /* graphics state variables to be modified by the CVT program. */ - - exec->GS.dualVector.x = 0x4000; - exec->GS.dualVector.y = 0; - exec->GS.projVector.x = 0x4000; - exec->GS.projVector.y = 0x0; - exec->GS.freeVector.x = 0x4000; - exec->GS.freeVector.y = 0x0; - - exec->GS.rp0 = 0; - exec->GS.rp1 = 0; - exec->GS.rp2 = 0; - - exec->GS.gep0 = 1; - exec->GS.gep1 = 1; - exec->GS.gep2 = 1; - - exec->GS.loop = 1; - - /* save as default graphics state */ - size->GS = exec->GS; - - TT_Save_Context( exec, size ); - - return error; - } - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - -#ifdef TT_USE_BYTECODE_INTERPRETER - - static void - tt_size_done_bytecode( FT_Size ftsize ) - { - TT_Size size = (TT_Size)ftsize; - TT_Face face = (TT_Face)ftsize->face; - FT_Memory memory = face->root.memory; - - - if ( size->debug ) - { - /* the debug context must be deleted by the debugger itself */ - size->context = NULL; - size->debug = FALSE; - } - - FT_FREE( size->cvt ); - size->cvt_size = 0; - - /* free storage area */ - FT_FREE( size->storage ); - size->storage_size = 0; - - /* twilight zone */ - tt_glyphzone_done( &size->twilight ); - - FT_FREE( size->function_defs ); - FT_FREE( size->instruction_defs ); - - size->num_function_defs = 0; - size->max_function_defs = 0; - size->num_instruction_defs = 0; - size->max_instruction_defs = 0; - - size->max_func = 0; - size->max_ins = 0; - - size->bytecode_ready = 0; - size->cvt_ready = 0; - } - - - /* Initialize bytecode-related fields in the size object. */ - /* We do this only if bytecode interpretation is really needed. */ - static FT_Error - tt_size_init_bytecode( FT_Size ftsize, - FT_Bool pedantic ) - { - FT_Error error; - TT_Size size = (TT_Size)ftsize; - TT_Face face = (TT_Face)ftsize->face; - FT_Memory memory = face->root.memory; - FT_Int i; - - FT_UShort n_twilight; - TT_MaxProfile* maxp = &face->max_profile; - - - size->bytecode_ready = 1; - size->cvt_ready = 0; - - size->max_function_defs = maxp->maxFunctionDefs; - size->max_instruction_defs = maxp->maxInstructionDefs; - - size->num_function_defs = 0; - size->num_instruction_defs = 0; - - size->max_func = 0; - size->max_ins = 0; - - size->cvt_size = face->cvt_size; - size->storage_size = maxp->maxStorage; - - /* Set default metrics */ - { - TT_Size_Metrics* metrics = &size->ttmetrics; - - - metrics->rotated = FALSE; - metrics->stretched = FALSE; - - /* set default compensation (all 0) */ - for ( i = 0; i < 4; i++ ) - metrics->compensations[i] = 0; - } - - /* allocate function defs, instruction defs, cvt, and storage area */ - if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || - FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || - FT_NEW_ARRAY( size->cvt, size->cvt_size ) || - FT_NEW_ARRAY( size->storage, size->storage_size ) ) - goto Exit; - - /* reserve twilight zone */ - n_twilight = maxp->maxTwilightPoints; - - /* there are 4 phantom points (do we need this?) */ - n_twilight += 4; - - error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); - if ( error ) - goto Exit; - - size->twilight.n_points = n_twilight; - - size->GS = tt_default_graphics_state; - - /* set `face->interpreter' according to the debug hook present */ - { - FT_Library library = face->root.driver->root.library; - - - face->interpreter = (TT_Interpreter) - library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; - if ( !face->interpreter ) - face->interpreter = (TT_Interpreter)TT_RunIns; - } - - /* Fine, now run the font program! */ - error = tt_size_run_fpgm( size, pedantic ); - - Exit: - if ( error ) - tt_size_done_bytecode( ftsize ); - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - tt_size_ready_bytecode( TT_Size size, - FT_Bool pedantic ) - { - FT_Error error = FT_Err_Ok; - - - if ( !size->bytecode_ready ) - { - error = tt_size_init_bytecode( (FT_Size)size, pedantic ); - if ( error ) - goto Exit; - } - - /* rescale CVT when needed */ - if ( !size->cvt_ready ) - { - FT_UInt i; - TT_Face face = (TT_Face)size->root.face; - - - /* Scale the cvt values to the new ppem. */ - /* We use by default the y ppem to scale the CVT. */ - for ( i = 0; i < size->cvt_size; i++ ) - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - - /* all twilight points are originally zero */ - for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) - { - size->twilight.org[i].x = 0; - size->twilight.org[i].y = 0; - size->twilight.cur[i].x = 0; - size->twilight.cur[i].y = 0; - } - - /* clear storage area */ - for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) - size->storage[i] = 0; - - size->GS = tt_default_graphics_state; - - error = tt_size_run_prep( size, pedantic ); - if ( !error ) - size->cvt_ready = 1; - } - - Exit: - return error; - } - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_size_init */ - /* */ - /* <Description> */ - /* Initialize a new TrueType size object. */ - /* */ - /* <InOut> */ - /* size :: A handle to the size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_size_init( FT_Size ttsize ) /* TT_Size */ - { - TT_Size size = (TT_Size)ttsize; - FT_Error error = FT_Err_Ok; - -#ifdef TT_USE_BYTECODE_INTERPRETER - size->bytecode_ready = 0; - size->cvt_ready = 0; -#endif - - size->ttmetrics.valid = FALSE; - size->strike_index = 0xFFFFFFFFUL; - - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_size_done */ - /* */ - /* <Description> */ - /* The TrueType size object finalizer. */ - /* */ - /* <Input> */ - /* size :: A handle to the target size object. */ - /* */ - FT_LOCAL_DEF( void ) - tt_size_done( FT_Size ttsize ) /* TT_Size */ - { - TT_Size size = (TT_Size)ttsize; - - -#ifdef TT_USE_BYTECODE_INTERPRETER - if ( size->bytecode_ready ) - tt_size_done_bytecode( ttsize ); -#endif - - size->ttmetrics.valid = FALSE; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_size_reset */ - /* */ - /* <Description> */ - /* Reset a TrueType size when resolutions and character dimensions */ - /* have been changed. */ - /* */ - /* <Input> */ - /* size :: A handle to the target size object. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_size_reset( TT_Size size ) - { - TT_Face face; - FT_Error error = FT_Err_Ok; - FT_Size_Metrics* metrics; - - - size->ttmetrics.valid = FALSE; - - face = (TT_Face)size->root.face; - - metrics = &size->metrics; - - /* copy the result from base layer */ - *metrics = size->root.metrics; - - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) - return FT_THROW( Invalid_PPem ); - - /* This bit flag, if set, indicates that the ppems must be */ - /* rounded to integers. Nearly all TrueType fonts have this bit */ - /* set, as hinting won't work really well otherwise. */ - /* */ - if ( face->header.Flags & 8 ) - { - metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, - face->root.units_per_EM ); - metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, - face->root.units_per_EM ); - - metrics->ascender = - FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); - metrics->descender = - FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); - metrics->height = - FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); - metrics->max_advance = - FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, - metrics->x_scale ) ); - } - - /* compute new transformation */ - if ( metrics->x_ppem >= metrics->y_ppem ) - { - size->ttmetrics.scale = metrics->x_scale; - size->ttmetrics.ppem = metrics->x_ppem; - size->ttmetrics.x_ratio = 0x10000L; - size->ttmetrics.y_ratio = FT_DivFix( metrics->y_ppem, - metrics->x_ppem ); - } - else - { - size->ttmetrics.scale = metrics->y_scale; - size->ttmetrics.ppem = metrics->y_ppem; - size->ttmetrics.x_ratio = FT_DivFix( metrics->x_ppem, - metrics->y_ppem ); - size->ttmetrics.y_ratio = 0x10000L; - } - -#ifdef TT_USE_BYTECODE_INTERPRETER - size->cvt_ready = 0; -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - if ( !error ) - size->ttmetrics.valid = TRUE; - - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_driver_init */ - /* */ - /* <Description> */ - /* Initialize a given TrueType driver object. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target driver object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ - { - -#ifdef TT_USE_BYTECODE_INTERPRETER - - TT_Driver driver = (TT_Driver)ttdriver; - - - if ( !TT_New_Context( driver ) ) - return FT_THROW( Could_Not_Find_Context ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - driver->interpreter_version = TT_INTERPRETER_VERSION_38; -#else - driver->interpreter_version = TT_INTERPRETER_VERSION_35; -#endif - -#else /* !TT_USE_BYTECODE_INTERPRETER */ - - FT_UNUSED( ttdriver ); - -#endif /* !TT_USE_BYTECODE_INTERPRETER */ - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_driver_done */ - /* */ - /* <Description> */ - /* Finalize a given TrueType driver. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target TrueType driver. */ - /* */ - FT_LOCAL_DEF( void ) - tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ - { -#ifdef TT_USE_BYTECODE_INTERPRETER - TT_Driver driver = (TT_Driver)ttdriver; - - - /* destroy the execution context */ - if ( driver->context ) - { - TT_Done_Context( driver->context ); - driver->context = NULL; - } -#else - FT_UNUSED( ttdriver ); -#endif - - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_slot_init */ - /* */ - /* <Description> */ - /* Initialize a new slot object. */ - /* */ - /* <InOut> */ - /* slot :: A handle to the slot object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_slot_init( FT_GlyphSlot slot ) - { - return FT_GlyphLoader_CreateExtra( slot->internal->loader ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttobjs.h b/drivers/freetype/freetype/src/truetype/ttobjs.h deleted file mode 100644 index a11dd3752a..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttobjs.h +++ /dev/null @@ -1,442 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttobjs.h */ -/* */ -/* Objects manager (specification). */ -/* */ -/* Copyright 1996-2009, 2011-2013 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 __TTOBJS_H__ -#define __TTOBJS_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_TRUETYPE_TYPES_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_Driver */ - /* */ - /* <Description> */ - /* A handle to a TrueType driver object. */ - /* */ - typedef struct TT_DriverRec_* TT_Driver; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_Instance */ - /* */ - /* <Description> */ - /* A handle to a TrueType size object. */ - /* */ - typedef struct TT_SizeRec_* TT_Size; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to a TrueType glyph slot object. */ - /* */ - /* <Note> */ - /* This is a direct typedef of FT_GlyphSlot, as there is nothing */ - /* specific about the TrueType glyph slot. */ - /* */ - typedef FT_GlyphSlot TT_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_GraphicsState */ - /* */ - /* <Description> */ - /* The TrueType graphics state used during bytecode interpretation. */ - /* */ - typedef struct TT_GraphicsState_ - { - FT_UShort rp0; - FT_UShort rp1; - FT_UShort rp2; - - FT_UnitVector dualVector; - FT_UnitVector projVector; - FT_UnitVector freeVector; - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_Bool both_x_axis; -#endif - - FT_Long loop; - FT_F26Dot6 minimum_distance; - FT_Int round_state; - - FT_Bool auto_flip; - FT_F26Dot6 control_value_cutin; - FT_F26Dot6 single_width_cutin; - FT_F26Dot6 single_width_value; - FT_Short delta_base; - FT_Short delta_shift; - - FT_Byte instruct_control; - /* According to Greg Hitchcock from Microsoft, the `scan_control' */ - /* variable as documented in the TrueType specification is a 32-bit */ - /* integer; the high-word part holds the SCANTYPE value, the low-word */ - /* part the SCANCTRL value. We separate it into two fields. */ - FT_Bool scan_control; - FT_Int scan_type; - - FT_UShort gep0; - FT_UShort gep1; - FT_UShort gep2; - - } TT_GraphicsState; - - -#ifdef TT_USE_BYTECODE_INTERPRETER - - FT_LOCAL( void ) - tt_glyphzone_done( TT_GlyphZone zone ); - - FT_LOCAL( FT_Error ) - tt_glyphzone_new( FT_Memory memory, - FT_UShort maxPoints, - FT_Short maxContours, - TT_GlyphZone zone ); - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - - - /*************************************************************************/ - /* */ - /* EXECUTION SUBTABLES */ - /* */ - /* These sub-tables relate to instruction execution. */ - /* */ - /*************************************************************************/ - - -#define TT_MAX_CODE_RANGES 3 - - - /*************************************************************************/ - /* */ - /* There can only be 3 active code ranges at once: */ - /* - the Font Program */ - /* - the CVT Program */ - /* - a glyph's instructions set */ - /* */ - typedef enum TT_CodeRange_Tag_ - { - tt_coderange_none = 0, - tt_coderange_font, - tt_coderange_cvt, - tt_coderange_glyph - - } TT_CodeRange_Tag; - - - typedef struct TT_CodeRange_ - { - FT_Byte* base; - FT_ULong size; - - } TT_CodeRange; - - typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES]; - - - /*************************************************************************/ - /* */ - /* Defines a function/instruction definition record. */ - /* */ - typedef struct TT_DefRecord_ - { - FT_Int range; /* in which code range is it located? */ - FT_Long start; /* where does it start? */ - FT_Long end; /* where does it end? */ - FT_UInt opc; /* function #, or instruction code */ - FT_Bool active; /* is it active? */ - FT_Bool inline_delta; /* is function that defines inline delta? */ - FT_ULong sph_fdef_flags; /* flags to identify special functions */ - - } TT_DefRecord, *TT_DefArray; - - - /*************************************************************************/ - /* */ - /* Subglyph transformation record. */ - /* */ - typedef struct TT_Transform_ - { - FT_Fixed xx, xy; /* transformation matrix coefficients */ - FT_Fixed yx, yy; - FT_F26Dot6 ox, oy; /* offsets */ - - } TT_Transform; - - - /*************************************************************************/ - /* */ - /* A note regarding non-squared pixels: */ - /* */ - /* (This text will probably go into some docs at some time; for now, it */ - /* is kept here to explain some definitions in the TT_Size_Metrics */ - /* record). */ - /* */ - /* The CVT is a one-dimensional array containing values that control */ - /* certain important characteristics in a font, like the height of all */ - /* capitals, all lowercase letter, default spacing or stem width/height. */ - /* */ - /* These values are found in FUnits in the font file, and must be scaled */ - /* to pixel coordinates before being used by the CVT and glyph programs. */ - /* Unfortunately, when using distinct x and y resolutions (or distinct x */ - /* and y pointsizes), there are two possible scalings. */ - /* */ - /* A first try was to implement a `lazy' scheme where all values were */ - /* scaled when first used. However, while some values are always used */ - /* in the same direction, some others are used under many different */ - /* circumstances and orientations. */ - /* */ - /* I have found a simpler way to do the same, and it even seems to work */ - /* in most of the cases: */ - /* */ - /* - All CVT values are scaled to the maximum ppem size. */ - /* */ - /* - When performing a read or write in the CVT, a ratio factor is used */ - /* to perform adequate scaling. Example: */ - /* */ - /* x_ppem = 14 */ - /* y_ppem = 10 */ - /* */ - /* We choose ppem = x_ppem = 14 as the CVT scaling size. All cvt */ - /* entries are scaled to it. */ - /* */ - /* x_ratio = 1.0 */ - /* y_ratio = y_ppem/ppem (< 1.0) */ - /* */ - /* We compute the current ratio like: */ - /* */ - /* - If projVector is horizontal, */ - /* ratio = x_ratio = 1.0 */ - /* */ - /* - if projVector is vertical, */ - /* ratio = y_ratio */ - /* */ - /* - else, */ - /* ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) */ - /* */ - /* Reading a cvt value returns */ - /* ratio * cvt[index] */ - /* */ - /* Writing a cvt value in pixels: */ - /* cvt[index] / ratio */ - /* */ - /* The current ppem is simply */ - /* ratio * ppem */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Metrics used by the TrueType size and context objects. */ - /* */ - typedef struct TT_Size_Metrics_ - { - /* for non-square pixels */ - FT_Long x_ratio; - FT_Long y_ratio; - - FT_UShort ppem; /* maximum ppem size */ - FT_Long ratio; /* current ratio */ - FT_Fixed scale; - - FT_F26Dot6 compensations[4]; /* device-specific compensations */ - - FT_Bool valid; - - FT_Bool rotated; /* `is the glyph rotated?'-flag */ - FT_Bool stretched; /* `is the glyph stretched?'-flag */ - - } TT_Size_Metrics; - - - /*************************************************************************/ - /* */ - /* TrueType size class. */ - /* */ - typedef struct TT_SizeRec_ - { - FT_SizeRec root; - - /* we have our own copy of metrics so that we can modify */ - /* it without affecting auto-hinting (when used) */ - FT_Size_Metrics metrics; - - TT_Size_Metrics ttmetrics; - - FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ - -#ifdef TT_USE_BYTECODE_INTERPRETER - - FT_UInt num_function_defs; /* number of function definitions */ - FT_UInt max_function_defs; - TT_DefArray function_defs; /* table of function definitions */ - - FT_UInt num_instruction_defs; /* number of ins. definitions */ - FT_UInt max_instruction_defs; - TT_DefArray instruction_defs; /* table of ins. definitions */ - - FT_UInt max_func; - FT_UInt max_ins; - - TT_CodeRangeTable codeRangeTable; - - TT_GraphicsState GS; - - FT_ULong cvt_size; /* the scaled control value table */ - FT_Long* cvt; - - FT_UShort storage_size; /* The storage area is now part of */ - FT_Long* storage; /* the instance */ - - TT_GlyphZoneRec twilight; /* The instance's twilight zone */ - - /* debugging variables */ - - /* When using the debugger, we must keep the */ - /* execution context tied to the instance */ - /* object rather than asking it on demand. */ - - FT_Bool debug; - TT_ExecContext context; - - FT_Bool bytecode_ready; - FT_Bool cvt_ready; - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - } TT_SizeRec; - - - /*************************************************************************/ - /* */ - /* TrueType driver class. */ - /* */ - typedef struct TT_DriverRec_ - { - FT_DriverRec root; - - TT_ExecContext context; /* execution context */ - TT_GlyphZoneRec zone; /* glyph loader points zone */ - - FT_UInt interpreter_version; - - } TT_DriverRec; - - - /* Note: All of the functions below (except tt_size_reset()) are used */ - /* as function pointers in a FT_Driver_ClassRec. Therefore their */ - /* parameters are of types FT_Face, FT_Size, etc., rather than TT_Face, */ - /* TT_Size, etc., so that the compiler can confirm that the types and */ - /* number of parameters are correct. In all cases the FT_xxx types are */ - /* cast to their TT_xxx counterparts inside the functions since FreeType */ - /* will always use the TT driver to create them. */ - - - /*************************************************************************/ - /* */ - /* Face functions */ - /* */ - FT_LOCAL( FT_Error ) - tt_face_init( FT_Stream stream, - FT_Face ttface, /* TT_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - FT_LOCAL( void ) - tt_face_done( FT_Face ttface ); /* TT_Face */ - - - /*************************************************************************/ - /* */ - /* Size functions */ - /* */ - FT_LOCAL( FT_Error ) - tt_size_init( FT_Size ttsize ); /* TT_Size */ - - FT_LOCAL( void ) - tt_size_done( FT_Size ttsize ); /* TT_Size */ - -#ifdef TT_USE_BYTECODE_INTERPRETER - - FT_LOCAL( FT_Error ) - tt_size_run_fpgm( TT_Size size, - FT_Bool pedantic ); - - FT_LOCAL( FT_Error ) - tt_size_run_prep( TT_Size size, - FT_Bool pedantic ); - - FT_LOCAL( FT_Error ) - tt_size_ready_bytecode( TT_Size size, - FT_Bool pedantic ); - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - FT_LOCAL( FT_Error ) - tt_size_reset( TT_Size size ); - - - /*************************************************************************/ - /* */ - /* Driver functions */ - /* */ - FT_LOCAL( FT_Error ) - tt_driver_init( FT_Module ttdriver ); /* TT_Driver */ - - FT_LOCAL( void ) - tt_driver_done( FT_Module ttdriver ); /* TT_Driver */ - - - /*************************************************************************/ - /* */ - /* Slot functions */ - /* */ - FT_LOCAL( FT_Error ) - tt_slot_init( FT_GlyphSlot slot ); - - - /* auxiliary */ -#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) - - -FT_END_HEADER - -#endif /* __TTOBJS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttpic.c b/drivers/freetype/freetype/src/truetype/ttpic.c deleted file mode 100644 index edefae72c5..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttpic.c +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpic.c */ -/* */ -/* The FreeType position independent code services for truetype module. */ -/* */ -/* Copyright 2009, 2010, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "ttpic.h" -#include "tterrors.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from ttdriver.c */ - FT_Error - FT_Create_Class_tt_services( FT_Library library, - FT_ServiceDescRec** output_class ); - void - FT_Destroy_Class_tt_services( FT_Library library, - FT_ServiceDescRec* clazz ); - void - FT_Init_Class_tt_service_gx_multi_masters( - FT_Service_MultiMastersRec* sv_mm ); - void - FT_Init_Class_tt_service_truetype_glyf( - FT_Service_TTGlyfRec* sv_ttglyf ); - - - void - tt_driver_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->truetype ) - { - TTModulePIC* container = (TTModulePIC*)pic_container->truetype; - - - if ( container->tt_services ) - FT_Destroy_Class_tt_services( library, container->tt_services ); - container->tt_services = NULL; - FT_FREE( container ); - pic_container->truetype = NULL; - } - } - - - FT_Error - tt_driver_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - TTModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->truetype = container; - - /* initialize pointer table - this is how the module usually */ - /* expects this data */ - error = FT_Create_Class_tt_services( library, - &container->tt_services ); - if ( error ) - goto Exit; -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Init_Class_tt_service_gx_multi_masters( - &container->tt_service_gx_multi_masters ); -#endif - FT_Init_Class_tt_service_truetype_glyf( - &container->tt_service_truetype_glyf ); - - Exit: - if ( error ) - tt_driver_class_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttpic.h b/drivers/freetype/freetype/src/truetype/ttpic.h deleted file mode 100644 index cfb4ee6281..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttpic.h +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpic.h */ -/* */ -/* The FreeType position independent code services for truetype module. */ -/* */ -/* Copyright 2009, 2012, 2013 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* 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 __TTPIC_H__ -#define __TTPIC_H__ - - -FT_BEGIN_HEADER - -#ifndef FT_CONFIG_OPTION_PIC - -#define TT_SERVICES_GET tt_services -#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters -#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf -#define TT_SERVICE_PROPERTIES_GET tt_service_properties - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_MULTIPLE_MASTERS_H -#include FT_SERVICE_MULTIPLE_MASTERS_H -#include FT_SERVICE_TRUETYPE_GLYF_H -#include FT_SERVICE_PROPERTIES_H - - - typedef struct TTModulePIC_ - { - FT_ServiceDescRec* tt_services; -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Service_MultiMastersRec tt_service_gx_multi_masters; -#endif - FT_Service_TTGlyfRec tt_service_truetype_glyf; - FT_Service_PropertiesRec tt_service_properties; - - } TTModulePIC; - - -#define GET_PIC( lib ) \ - ( (TTModulePIC*)((lib)->pic_container.truetype) ) -#define TT_SERVICES_GET \ - ( GET_PIC( library )->tt_services ) -#define TT_SERVICE_GX_MULTI_MASTERS_GET \ - ( GET_PIC( library )->tt_service_gx_multi_masters ) -#define TT_SERVICE_TRUETYPE_GLYF_GET \ - ( GET_PIC( library )->tt_service_truetype_glyf ) -#define TT_SERVICE_PROPERTIES_GET \ - ( GET_PIC( library )->tt_service_properties ) - - - /* see ttpic.c for the implementation */ - void - tt_driver_class_pic_free( FT_Library library ); - - FT_Error - tt_driver_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - - -FT_END_HEADER - -#endif /* __TTPIC_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttpload.c b/drivers/freetype/freetype/src/truetype/ttpload.c deleted file mode 100644 index 9723a515b9..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttpload.c +++ /dev/null @@ -1,599 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpload.c */ -/* */ -/* TrueType-specific tables loader (body). */ -/* */ -/* Copyright 1996-2002, 2004-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TAGS_H - -#include "ttpload.h" - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#include "ttgxvar.h" -#endif - -#include "tterrors.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_ttpload - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_loca */ - /* */ - /* <Description> */ - /* Load the locations table. */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Input> */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_loca( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_ULong table_len; - FT_Int shift; - - - /* we need the size of the `glyf' table for malformed `loca' tables */ - error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len ); - - /* it is possible that a font doesn't have a glyf table at all */ - /* or its size is zero */ - if ( FT_ERR_EQ( error, Table_Missing ) ) - face->glyf_len = 0; - else if ( error ) - goto Exit; - - FT_TRACE2(( "Locations " )); - error = face->goto_table( face, TTAG_loca, stream, &table_len ); - if ( error ) - { - error = FT_THROW( Locations_Missing ); - goto Exit; - } - - if ( face->header.Index_To_Loc_Format != 0 ) - { - shift = 2; - - if ( table_len >= 0x40000L ) - { - FT_TRACE2(( "table too large\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - face->num_locations = table_len >> shift; - } - else - { - shift = 1; - - if ( table_len >= 0x20000L ) - { - FT_TRACE2(( "table too large\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - face->num_locations = table_len >> shift; - } - - if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 ) - { - FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", - face->num_locations - 1, face->root.num_glyphs )); - - /* we only handle the case where `maxp' gives a larger value */ - if ( face->num_locations <= (FT_ULong)face->root.num_glyphs ) - { - FT_Long new_loca_len = - ( (FT_Long)( face->root.num_glyphs ) + 1 ) << shift; - - TT_Table entry = face->dir_tables; - TT_Table limit = entry + face->num_tables; - - FT_Long pos = FT_Stream_Pos( stream ); - FT_Long dist = 0x7FFFFFFFL; - - - /* compute the distance to next table in font file */ - for ( ; entry < limit; entry++ ) - { - FT_Long diff = entry->Offset - pos; - - - if ( diff > 0 && diff < dist ) - dist = diff; - } - - if ( entry == limit ) - { - /* `loca' is the last table */ - dist = stream->size - pos; - } - - if ( new_loca_len <= dist ) - { - face->num_locations = face->root.num_glyphs + 1; - table_len = new_loca_len; - - FT_TRACE2(( "adjusting num_locations to %d\n", - face->num_locations )); - } - } - } - - /* - * Extract the frame. We don't need to decompress it since - * we are able to parse it directly. - */ - if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) ) - goto Exit; - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_ULong ) - tt_face_get_location( TT_Face face, - FT_UInt gindex, - FT_UInt *asize ) - { - FT_ULong pos1, pos2; - FT_Byte* p; - FT_Byte* p_limit; - - - pos1 = pos2 = 0; - - if ( gindex < face->num_locations ) - { - if ( face->header.Index_To_Loc_Format != 0 ) - { - p = face->glyph_locations + gindex * 4; - p_limit = face->glyph_locations + face->num_locations * 4; - - pos1 = FT_NEXT_ULONG( p ); - pos2 = pos1; - - if ( p + 4 <= p_limit ) - pos2 = FT_NEXT_ULONG( p ); - } - else - { - p = face->glyph_locations + gindex * 2; - p_limit = face->glyph_locations + face->num_locations * 2; - - pos1 = FT_NEXT_USHORT( p ); - pos2 = pos1; - - if ( p + 2 <= p_limit ) - pos2 = FT_NEXT_USHORT( p ); - - pos1 <<= 1; - pos2 <<= 1; - } - } - - /* Check broken location data */ - if ( pos1 > face->glyf_len ) - { - FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," - " exceeding the end of glyf table (0x%08lx)\n", - pos1, gindex, face->glyf_len )); - *asize = 0; - return 0; - } - - if ( pos2 > face->glyf_len ) - { - FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," - " truncate at the end of glyf table (0x%08lx)\n", - pos2, gindex + 1, face->glyf_len )); - pos2 = face->glyf_len; - } - - /* The `loca' table must be ordered; it refers to the length of */ - /* an entry as the difference between the current and the next */ - /* position. However, there do exist (malformed) fonts which */ - /* don't obey this rule, so we are only able to provide an */ - /* upper bound for the size. */ - /* */ - /* We get (intentionally) a wrong, non-zero result in case the */ - /* `glyf' table is missing. */ - if ( pos2 >= pos1 ) - *asize = (FT_UInt)( pos2 - pos1 ); - else - *asize = (FT_UInt)( face->glyf_len - pos1 ); - - return pos1; - } - - - FT_LOCAL_DEF( void ) - tt_face_done_loca( TT_Face face ) - { - FT_Stream stream = face->root.stream; - - - FT_FRAME_RELEASE( face->glyph_locations ); - face->num_locations = 0; - } - - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_cvt */ - /* */ - /* <Description> */ - /* Load the control value table into a face object. */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Input> */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_cvt( TT_Face face, - FT_Stream stream ) - { -#ifdef TT_USE_BYTECODE_INTERPRETER - - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong table_len; - - - FT_TRACE2(( "CVT " )); - - error = face->goto_table( face, TTAG_cvt, stream, &table_len ); - if ( error ) - { - FT_TRACE2(( "is missing\n" )); - - face->cvt_size = 0; - face->cvt = NULL; - error = FT_Err_Ok; - - goto Exit; - } - - face->cvt_size = table_len / 2; - - if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) - goto Exit; - - if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) - goto Exit; - - { - FT_Short* cur = face->cvt; - FT_Short* limit = cur + face->cvt_size; - - - for ( ; cur < limit; cur++ ) - *cur = FT_GET_SHORT(); - } - - FT_FRAME_EXIT(); - FT_TRACE2(( "loaded\n" )); - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( face->doblend ) - error = tt_face_vary_cvt( face, stream ); -#endif - - Exit: - return error; - -#else /* !TT_USE_BYTECODE_INTERPRETER */ - - FT_UNUSED( face ); - FT_UNUSED( stream ); - - return FT_Err_Ok; - -#endif - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_fpgm */ - /* */ - /* <Description> */ - /* Load the font program. */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Input> */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_fpgm( TT_Face face, - FT_Stream stream ) - { -#ifdef TT_USE_BYTECODE_INTERPRETER - - FT_Error error; - FT_ULong table_len; - - - FT_TRACE2(( "Font program " )); - - /* The font program is optional */ - error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); - if ( error ) - { - face->font_program = NULL; - face->font_program_size = 0; - error = FT_Err_Ok; - - FT_TRACE2(( "is missing\n" )); - } - else - { - face->font_program_size = table_len; - if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) - goto Exit; - - FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); - } - - Exit: - return error; - -#else /* !TT_USE_BYTECODE_INTERPRETER */ - - FT_UNUSED( face ); - FT_UNUSED( stream ); - - return FT_Err_Ok; - -#endif - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_prep */ - /* */ - /* <Description> */ - /* Load the cvt program. */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Input> */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_prep( TT_Face face, - FT_Stream stream ) - { -#ifdef TT_USE_BYTECODE_INTERPRETER - - FT_Error error; - FT_ULong table_len; - - - FT_TRACE2(( "Prep program " )); - - error = face->goto_table( face, TTAG_prep, stream, &table_len ); - if ( error ) - { - face->cvt_program = NULL; - face->cvt_program_size = 0; - error = FT_Err_Ok; - - FT_TRACE2(( "is missing\n" )); - } - else - { - face->cvt_program_size = table_len; - if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) - goto Exit; - - FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); - } - - Exit: - return error; - -#else /* !TT_USE_BYTECODE_INTERPRETER */ - - FT_UNUSED( face ); - FT_UNUSED( stream ); - - return FT_Err_Ok; - -#endif - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_hdmx */ - /* */ - /* <Description> */ - /* Load the `hdmx' table into the face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - - FT_LOCAL_DEF( FT_Error ) - tt_face_load_hdmx( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_UInt version, nn, num_records; - FT_ULong table_size, record_size; - FT_Byte* p; - FT_Byte* limit; - - - /* this table is optional */ - error = face->goto_table( face, TTAG_hdmx, stream, &table_size ); - if ( error || table_size < 8 ) - return FT_Err_Ok; - - if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) ) - goto Exit; - - p = face->hdmx_table; - limit = p + table_size; - - version = FT_NEXT_USHORT( p ); - num_records = FT_NEXT_USHORT( p ); - record_size = FT_NEXT_ULONG( p ); - - /* The maximum number of bytes in an hdmx device record is the */ - /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ - /* the reason why `record_size' is a long (which we read as */ - /* unsigned long for convenience). In practice, two bytes */ - /* sufficient to hold the size value. */ - /* */ - /* There are at least two fonts, HANNOM-A and HANNOM-B version */ - /* 2.0 (2005), which get this wrong: The upper two bytes of */ - /* the size value are set to 0xFF instead of 0x00. We catch */ - /* and fix this. */ - - if ( record_size >= 0xFFFF0000UL ) - record_size &= 0xFFFFU; - - /* The limit for `num_records' is a heuristic value. */ - - if ( version != 0 || num_records > 255 || record_size > 0x10001L ) - { - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) ) - goto Fail; - - for ( nn = 0; nn < num_records; nn++ ) - { - if ( p + record_size > limit ) - break; - - face->hdmx_record_sizes[nn] = p[0]; - p += record_size; - } - - face->hdmx_record_count = nn; - face->hdmx_table_size = table_size; - face->hdmx_record_size = record_size; - - Exit: - return error; - - Fail: - FT_FRAME_RELEASE( face->hdmx_table ); - face->hdmx_table_size = 0; - goto Exit; - } - - - FT_LOCAL_DEF( void ) - tt_face_free_hdmx( TT_Face face ) - { - FT_Stream stream = face->root.stream; - FT_Memory memory = stream->memory; - - - FT_FREE( face->hdmx_record_sizes ); - FT_FRAME_RELEASE( face->hdmx_table ); - } - - - /*************************************************************************/ - /* */ - /* Return the advance width table for a given pixel size if it is found */ - /* in the font's `hdmx' table (if any). */ - /* */ - FT_LOCAL_DEF( FT_Byte* ) - tt_face_get_device_metrics( TT_Face face, - FT_UInt ppem, - FT_UInt gindex ) - { - FT_UInt nn; - FT_Byte* result = NULL; - FT_ULong record_size = face->hdmx_record_size; - FT_Byte* record = face->hdmx_table + 8; - - - for ( nn = 0; nn < face->hdmx_record_count; nn++ ) - if ( face->hdmx_record_sizes[nn] == ppem ) - { - gindex += 2; - if ( gindex < record_size ) - result = record + nn * record_size + gindex; - break; - } - - return result; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttpload.h b/drivers/freetype/freetype/src/truetype/ttpload.h deleted file mode 100644 index f61ac079ce..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttpload.h +++ /dev/null @@ -1,75 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpload.h */ -/* */ -/* TrueType-specific tables loader (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2005, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __TTPLOAD_H__ -#define __TTPLOAD_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_TRUETYPE_TYPES_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - tt_face_load_loca( TT_Face face, - FT_Stream stream ); - - FT_LOCAL( FT_ULong ) - tt_face_get_location( TT_Face face, - FT_UInt gindex, - FT_UInt *asize ); - - FT_LOCAL( void ) - tt_face_done_loca( TT_Face face ); - - FT_LOCAL( FT_Error ) - tt_face_load_cvt( TT_Face face, - FT_Stream stream ); - - FT_LOCAL( FT_Error ) - tt_face_load_fpgm( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_prep( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( FT_Error ) - tt_face_load_hdmx( TT_Face face, - FT_Stream stream ); - - - FT_LOCAL( void ) - tt_face_free_hdmx( TT_Face face ); - - - FT_LOCAL( FT_Byte* ) - tt_face_get_device_metrics( TT_Face face, - FT_UInt ppem, - FT_UInt gindex ); - -FT_END_HEADER - -#endif /* __TTPLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttsubpix.c b/drivers/freetype/freetype/src/truetype/ttsubpix.c deleted file mode 100644 index 28470ad655..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttsubpix.c +++ /dev/null @@ -1,1011 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsubpix.c */ -/* */ -/* TrueType Subpixel Hinting. */ -/* */ -/* Copyright 2010-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_TAGS_H -#include FT_OUTLINE_H -#include FT_TRUETYPE_DRIVER_H - -#include "ttsubpix.h" - - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - /*************************************************************************/ - /* */ - /* These rules affect how the TT Interpreter does hinting, with the */ - /* goal of doing subpixel hinting by (in general) ignoring x moves. */ - /* Some of these rules are fixes that go above and beyond the */ - /* stated techniques in the MS whitepaper on Cleartype, due to */ - /* artifacts in many glyphs. So, these rules make some glyphs render */ - /* better than they do in the MS rasterizer. */ - /* */ - /* "" string or 0 int/char indicates to apply to all glyphs. */ - /* "-" used as dummy placeholders, but any non-matching string works. */ - /* */ - /* Some of this could arguably be implemented in fontconfig, however: */ - /* */ - /* - Fontconfig can't set things on a glyph-by-glyph basis. */ - /* - The tweaks that happen here are very low-level, from an average */ - /* user's point of view and are best implemented in the hinter. */ - /* */ - /* The goal is to make the subpixel hinting techniques as generalized */ - /* as possible across all fonts to prevent the need for extra rules such */ - /* as these. */ - /* */ - /* The rule structure is designed so that entirely new rules can easily */ - /* be added when a new compatibility feature is discovered. */ - /* */ - /* The rule structures could also use some enhancement to handle ranges. */ - /* */ - /* ****************** WORK IN PROGRESS ******************* */ - /* */ - - /* These are `classes' of fonts that can be grouped together and used in */ - /* rules below. A blank entry "" is required at the end of these! */ -#define FAMILY_CLASS_RULES_SIZE 7 - - static const SPH_Font_Class FAMILY_CLASS_Rules - [FAMILY_CLASS_RULES_SIZE] = - { - { "MS Legacy Fonts", - { "Aharoni", - "Andale Mono", - "Andalus", - "Angsana New", - "AngsanaUPC", - "Arabic Transparent", - "Arial Black", - "Arial Narrow", - "Arial Unicode MS", - "Arial", - "Batang", - "Browallia New", - "BrowalliaUPC", - "Comic Sans MS", - "Cordia New", - "CordiaUPC", - "Courier New", - "DFKai-SB", - "David Transparent", - "David", - "DilleniaUPC", - "Estrangelo Edessa", - "EucrosiaUPC", - "FangSong_GB2312", - "Fixed Miriam Transparent", - "FrankRuehl", - "Franklin Gothic Medium", - "FreesiaUPC", - "Garamond", - "Gautami", - "Georgia", - "Gulim", - "Impact", - "IrisUPC", - "JasmineUPC", - "KaiTi_GB2312", - "KodchiangUPC", - "Latha", - "Levenim MT", - "LilyUPC", - "Lucida Console", - "Lucida Sans Unicode", - "MS Gothic", - "MS Mincho", - "MV Boli", - "Mangal", - "Marlett", - "Microsoft Sans Serif", - "Mingliu", - "Miriam Fixed", - "Miriam Transparent", - "Miriam", - "Narkisim", - "Palatino Linotype", - "Raavi", - "Rod Transparent", - "Rod", - "Shruti", - "SimHei", - "Simplified Arabic Fixed", - "Simplified Arabic", - "Simsun", - "Sylfaen", - "Symbol", - "Tahoma", - "Times New Roman", - "Traditional Arabic", - "Trebuchet MS", - "Tunga", - "Verdana", - "Webdings", - "Wingdings", - "", - }, - }, - { "Core MS Legacy Fonts", - { "Arial Black", - "Arial Narrow", - "Arial Unicode MS", - "Arial", - "Comic Sans MS", - "Courier New", - "Garamond", - "Georgia", - "Impact", - "Lucida Console", - "Lucida Sans Unicode", - "Microsoft Sans Serif", - "Palatino Linotype", - "Tahoma", - "Times New Roman", - "Trebuchet MS", - "Verdana", - "", - }, - }, - { "Apple Legacy Fonts", - { "Geneva", - "Times", - "Monaco", - "Century", - "Chalkboard", - "Lobster", - "Century Gothic", - "Optima", - "Lucida Grande", - "Gill Sans", - "Baskerville", - "Helvetica", - "Helvetica Neue", - "", - }, - }, - { "Legacy Sans Fonts", - { "Andale Mono", - "Arial Unicode MS", - "Arial", - "Century Gothic", - "Comic Sans MS", - "Franklin Gothic Medium", - "Geneva", - "Lucida Console", - "Lucida Grande", - "Lucida Sans Unicode", - "Lucida Sans Typewriter", - "Microsoft Sans Serif", - "Monaco", - "Tahoma", - "Trebuchet MS", - "Verdana", - "", - }, - }, - - { "Misc Legacy Fonts", - { "Dark Courier", "", }, }, - { "Verdana Clones", - { "DejaVu Sans", - "Bitstream Vera Sans", "", }, }, - { "Verdana and Clones", - { "DejaVu Sans", - "Bitstream Vera Sans", - "Verdana", "", }, }, - }; - - - /* Define this to force natural (i.e. not bitmap-compatible) widths. */ - /* The default leans strongly towards natural widths except for a few */ - /* legacy fonts where a selective combination produces nicer results. */ -/* #define FORCE_NATURAL_WIDTHS */ - - - /* Define `classes' of styles that can be grouped together and used in */ - /* rules below. A blank entry "" is required at the end of these! */ -#define STYLE_CLASS_RULES_SIZE 5 - - const SPH_Font_Class STYLE_CLASS_Rules - [STYLE_CLASS_RULES_SIZE] = - { - { "Regular Class", - { "Regular", - "Book", - "Medium", - "Roman", - "Normal", - "", - }, - }, - { "Regular/Italic Class", - { "Regular", - "Book", - "Medium", - "Italic", - "Oblique", - "Roman", - "Normal", - "", - }, - }, - { "Bold/BoldItalic Class", - { "Bold", - "Bold Italic", - "Black", - "", - }, - }, - { "Bold/Italic/BoldItalic Class", - { "Bold", - "Bold Italic", - "Black", - "Italic", - "Oblique", - "", - }, - }, - { "Regular/Bold Class", - { "Regular", - "Book", - "Medium", - "Normal", - "Roman", - "Bold", - "Black", - "", - }, - }, - }; - - - /* Force special legacy fixes for fonts. */ -#define COMPATIBILITY_MODE_RULES_SIZE 1 - - const SPH_TweakRule COMPATIBILITY_MODE_Rules - [COMPATIBILITY_MODE_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting. */ -#define PIXEL_HINTING_RULES_SIZE 2 - - const SPH_TweakRule PIXEL_HINTING_Rules - [PIXEL_HINTING_RULES_SIZE] = - { - /* these characters are almost always safe */ - { "Courier New", 12, "Italic", 'z' }, - { "Courier New", 11, "Italic", 'z' }, - }; - - - /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */ -#define DO_SHPIX_RULES_SIZE 1 - - const SPH_TweakRule DO_SHPIX_Rules - [DO_SHPIX_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Skip Y moves that start with a point that is not on a Y pixel */ - /* boundary and don't move that point to a Y pixel boundary. */ -#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 4 - - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules - [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = - { - /* fix vwxyz thinness*/ - { "Consolas", 0, "", 0 }, - /* Fix thin middle stems */ - { "Core MS Legacy Fonts", 0, "Regular", 0 }, - /* Cyrillic small letter I */ - { "Legacy Sans Fonts", 0, "", 0 }, - /* Fix artifacts with some Regular & Bold */ - { "Verdana Clones", 0, "", 0 }, - }; - - -#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - /* Fixes < and > */ - { "Courier New", 0, "Regular", 0 }, - }; - - - /* Skip Y moves that start with a point that is not on a Y pixel */ - /* boundary and don't move that point to a Y pixel boundary. */ -#define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE 2 - - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules - [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] = - { - /* Maintain thickness of diagonal in 'N' */ - { "Times New Roman", 0, "Regular/Bold Class", 'N' }, - { "Georgia", 0, "Regular/Bold Class", 'N' }, - }; - - - /* Skip Y moves that move a point off a Y pixel boundary. */ -#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 1 - - const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules - [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - -#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - - const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Round moves that don't move a point to a Y pixel boundary. */ -#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 2 - - const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules - [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = - { - /* Droid font instructions don't snap Y to pixels */ - { "Droid Sans", 0, "Regular/Italic Class", 0 }, - { "Droid Sans Mono", 0, "", 0 }, - }; - - -#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - - const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions - [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Allow a Direct_Move along X freedom vector if matched. */ -#define ALLOW_X_DMOVE_RULES_SIZE 1 - - const SPH_TweakRule ALLOW_X_DMOVE_Rules - [ALLOW_X_DMOVE_RULES_SIZE] = - { - /* Fixes vanishing diagonal in 4 */ - { "Verdana", 0, "Regular", '4' }, - }; - - - /* Return MS rasterizer version 35 if matched. */ -#define RASTERIZER_35_RULES_SIZE 8 - - const SPH_TweakRule RASTERIZER_35_Rules - [RASTERIZER_35_RULES_SIZE] = - { - /* This seems to be the only way to make these look good */ - { "Times New Roman", 0, "Regular", 'i' }, - { "Times New Roman", 0, "Regular", 'j' }, - { "Times New Roman", 0, "Regular", 'm' }, - { "Times New Roman", 0, "Regular", 'r' }, - { "Times New Roman", 0, "Regular", 'a' }, - { "Times New Roman", 0, "Regular", 'n' }, - { "Times New Roman", 0, "Regular", 'p' }, - { "Times", 0, "", 0 }, - }; - - - /* Don't round to the subpixel grid. Round to pixel grid. */ -#define NORMAL_ROUND_RULES_SIZE 1 - - const SPH_TweakRule NORMAL_ROUND_Rules - [NORMAL_ROUND_RULES_SIZE] = - { - /* Fix serif thickness for certain ppems */ - /* Can probably be generalized somehow */ - { "Courier New", 0, "", 0 }, - }; - - - /* Skip IUP instructions if matched. */ -#define SKIP_IUP_RULES_SIZE 1 - - const SPH_TweakRule SKIP_IUP_Rules - [SKIP_IUP_RULES_SIZE] = - { - { "Arial", 13, "Regular", 'a' }, - }; - - - /* Skip MIAP Twilight hack if matched. */ -#define MIAP_HACK_RULES_SIZE 1 - - const SPH_TweakRule MIAP_HACK_Rules - [MIAP_HACK_RULES_SIZE] = - { - { "Geneva", 12, "", 0 }, - }; - - - /* Skip DELTAP instructions if matched. */ -#define ALWAYS_SKIP_DELTAP_RULES_SIZE 23 - - const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules - [ALWAYS_SKIP_DELTAP_RULES_SIZE] = - { - { "Georgia", 0, "Regular", 'k' }, - /* fix various problems with e in different versions */ - { "Trebuchet MS", 14, "Regular", 'e' }, - { "Trebuchet MS", 13, "Regular", 'e' }, - { "Trebuchet MS", 15, "Regular", 'e' }, - { "Trebuchet MS", 0, "Italic", 'v' }, - { "Trebuchet MS", 0, "Italic", 'w' }, - { "Trebuchet MS", 0, "Regular", 'Y' }, - { "Arial", 11, "Regular", 's' }, - /* prevent problems with '3' and others */ - { "Verdana", 10, "Regular", 0 }, - { "Verdana", 9, "Regular", 0 }, - /* Cyrillic small letter short I */ - { "Legacy Sans Fonts", 0, "", 0x438 }, - { "Legacy Sans Fonts", 0, "", 0x439 }, - { "Arial", 10, "Regular", '6' }, - { "Arial", 0, "Bold/BoldItalic Class", 'a' }, - /* Make horizontal stems consistent with the rest */ - { "Arial", 24, "Bold", 'a' }, - { "Arial", 25, "Bold", 'a' }, - { "Arial", 24, "Bold", 's' }, - { "Arial", 25, "Bold", 's' }, - { "Arial", 34, "Bold", 's' }, - { "Arial", 35, "Bold", 's' }, - { "Arial", 36, "Bold", 's' }, - { "Arial", 25, "Regular", 's' }, - { "Arial", 26, "Regular", 's' }, - }; - - - /* Always do DELTAP instructions if matched. */ -#define ALWAYS_DO_DELTAP_RULES_SIZE 1 - - const SPH_TweakRule ALWAYS_DO_DELTAP_Rules - [ALWAYS_DO_DELTAP_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Don't allow ALIGNRP after IUP. */ -#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE 1 - - static const SPH_TweakRule NO_ALIGNRP_AFTER_IUP_Rules - [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] = - { - /* Prevent creation of dents in outline */ - { "-", 0, "", 0 }, - }; - - - /* Don't allow DELTAP after IUP. */ -#define NO_DELTAP_AFTER_IUP_RULES_SIZE 1 - - static const SPH_TweakRule NO_DELTAP_AFTER_IUP_Rules - [NO_DELTAP_AFTER_IUP_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Don't allow CALL after IUP. */ -#define NO_CALL_AFTER_IUP_RULES_SIZE 1 - - static const SPH_TweakRule NO_CALL_AFTER_IUP_Rules - [NO_CALL_AFTER_IUP_RULES_SIZE] = - { - /* Prevent creation of dents in outline */ - { "-", 0, "", 0 }, - }; - - - /* De-embolden these glyphs slightly. */ -#define DEEMBOLDEN_RULES_SIZE 9 - - static const SPH_TweakRule DEEMBOLDEN_Rules - [DEEMBOLDEN_RULES_SIZE] = - { - { "Courier New", 0, "Bold", 'A' }, - { "Courier New", 0, "Bold", 'W' }, - { "Courier New", 0, "Bold", 'w' }, - { "Courier New", 0, "Bold", 'M' }, - { "Courier New", 0, "Bold", 'X' }, - { "Courier New", 0, "Bold", 'K' }, - { "Courier New", 0, "Bold", 'x' }, - { "Courier New", 0, "Bold", 'z' }, - { "Courier New", 0, "Bold", 'v' }, - }; - - - /* Embolden these glyphs slightly. */ -#define EMBOLDEN_RULES_SIZE 2 - - static const SPH_TweakRule EMBOLDEN_Rules - [EMBOLDEN_RULES_SIZE] = - { - { "Courier New", 0, "Regular", 0 }, - { "Courier New", 0, "Italic", 0 }, - }; - - - /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7 */ - /* similar to Windows XP. */ -#define TIMES_NEW_ROMAN_HACK_RULES_SIZE 12 - - static const SPH_TweakRule TIMES_NEW_ROMAN_HACK_Rules - [TIMES_NEW_ROMAN_HACK_RULES_SIZE] = - { - { "Times New Roman", 16, "Italic", '2' }, - { "Times New Roman", 16, "Italic", '5' }, - { "Times New Roman", 16, "Italic", '7' }, - { "Times New Roman", 16, "Regular", '2' }, - { "Times New Roman", 16, "Regular", '5' }, - { "Times New Roman", 16, "Regular", '7' }, - { "Times New Roman", 17, "Italic", '2' }, - { "Times New Roman", 17, "Italic", '5' }, - { "Times New Roman", 17, "Italic", '7' }, - { "Times New Roman", 17, "Regular", '2' }, - { "Times New Roman", 17, "Regular", '5' }, - { "Times New Roman", 17, "Regular", '7' }, - }; - - - /* This fudges distance on 2 to get rid of the vanishing stem issue. */ - /* A real solution to this is certainly welcome. */ -#define COURIER_NEW_2_HACK_RULES_SIZE 15 - - static const SPH_TweakRule COURIER_NEW_2_HACK_Rules - [COURIER_NEW_2_HACK_RULES_SIZE] = - { - { "Courier New", 10, "Regular", '2' }, - { "Courier New", 11, "Regular", '2' }, - { "Courier New", 12, "Regular", '2' }, - { "Courier New", 13, "Regular", '2' }, - { "Courier New", 14, "Regular", '2' }, - { "Courier New", 15, "Regular", '2' }, - { "Courier New", 16, "Regular", '2' }, - { "Courier New", 17, "Regular", '2' }, - { "Courier New", 18, "Regular", '2' }, - { "Courier New", 19, "Regular", '2' }, - { "Courier New", 20, "Regular", '2' }, - { "Courier New", 21, "Regular", '2' }, - { "Courier New", 22, "Regular", '2' }, - { "Courier New", 23, "Regular", '2' }, - { "Courier New", 24, "Regular", '2' }, - }; - - -#ifndef FORCE_NATURAL_WIDTHS - - /* Use compatible widths with these glyphs. Compatible widths is always */ - /* on when doing B/W TrueType instructing, but is used selectively here, */ - /* typically on glyphs with 3 or more vertical stems. */ -#define COMPATIBLE_WIDTHS_RULES_SIZE 38 - - static const SPH_TweakRule COMPATIBLE_WIDTHS_Rules - [COMPATIBLE_WIDTHS_RULES_SIZE] = - { - { "Arial Unicode MS", 12, "Regular Class", 'm' }, - { "Arial Unicode MS", 14, "Regular Class", 'm' }, - /* Cyrillic small letter sha */ - { "Arial", 10, "Regular Class", 0x448 }, - { "Arial", 11, "Regular Class", 'm' }, - { "Arial", 12, "Regular Class", 'm' }, - /* Cyrillic small letter sha */ - { "Arial", 12, "Regular Class", 0x448 }, - { "Arial", 13, "Regular Class", 0x448 }, - { "Arial", 14, "Regular Class", 'm' }, - /* Cyrillic small letter sha */ - { "Arial", 14, "Regular Class", 0x448 }, - { "Arial", 15, "Regular Class", 0x448 }, - { "Arial", 17, "Regular Class", 'm' }, - { "DejaVu Sans", 15, "Regular Class", 0 }, - { "Microsoft Sans Serif", 11, "Regular Class", 0 }, - { "Microsoft Sans Serif", 12, "Regular Class", 0 }, - { "Segoe UI", 11, "Regular Class", 0 }, - { "Monaco", 0, "Regular Class", 0 }, - { "Segoe UI", 12, "Regular Class", 'm' }, - { "Segoe UI", 14, "Regular Class", 'm' }, - { "Tahoma", 11, "Regular Class", 0 }, - { "Times New Roman", 16, "Regular Class", 'c' }, - { "Times New Roman", 16, "Regular Class", 'm' }, - { "Times New Roman", 16, "Regular Class", 'o' }, - { "Times New Roman", 16, "Regular Class", 'w' }, - { "Trebuchet MS", 11, "Regular Class", 0 }, - { "Trebuchet MS", 12, "Regular Class", 0 }, - { "Trebuchet MS", 14, "Regular Class", 0 }, - { "Trebuchet MS", 15, "Regular Class", 0 }, - { "Ubuntu", 12, "Regular Class", 'm' }, - /* Cyrillic small letter sha */ - { "Verdana", 10, "Regular Class", 0x448 }, - { "Verdana", 11, "Regular Class", 0x448 }, - { "Verdana and Clones", 12, "Regular Class", 'i' }, - { "Verdana and Clones", 12, "Regular Class", 'j' }, - { "Verdana and Clones", 12, "Regular Class", 'l' }, - { "Verdana and Clones", 12, "Regular Class", 'm' }, - { "Verdana and Clones", 13, "Regular Class", 'i' }, - { "Verdana and Clones", 13, "Regular Class", 'j' }, - { "Verdana and Clones", 13, "Regular Class", 'l' }, - { "Verdana and Clones", 14, "Regular Class", 'm' }, - }; - - - /* Scaling slightly in the x-direction prior to hinting results in */ - /* more visually pleasing glyphs in certain cases. */ - /* This sometimes needs to be coordinated with compatible width rules. */ - /* A value of 1000 corresponds to a scaled value of 1.0. */ - -#define X_SCALING_RULES_SIZE 50 - - static const SPH_ScaleRule X_SCALING_Rules[X_SCALING_RULES_SIZE] = - { - { "DejaVu Sans", 12, "Regular Class", 'm', 950 }, - { "Verdana and Clones", 12, "Regular Class", 'a', 1100 }, - { "Verdana and Clones", 13, "Regular Class", 'a', 1050 }, - { "Arial", 11, "Regular Class", 'm', 975 }, - { "Arial", 12, "Regular Class", 'm', 1050 }, - /* Cyrillic small letter el */ - { "Arial", 13, "Regular Class", 0x43B, 950 }, - { "Arial", 13, "Regular Class", 'o', 950 }, - { "Arial", 13, "Regular Class", 'e', 950 }, - { "Arial", 14, "Regular Class", 'm', 950 }, - /* Cyrillic small letter el */ - { "Arial", 15, "Regular Class", 0x43B, 925 }, - { "Bitstream Vera Sans", 10, "Regular/Italic Class", 0, 1100 }, - { "Bitstream Vera Sans", 12, "Regular/Italic Class", 0, 1050 }, - { "Bitstream Vera Sans", 16, "Regular Class", 0, 1050 }, - { "Bitstream Vera Sans", 9, "Regular/Italic Class", 0, 1050 }, - { "DejaVu Sans", 12, "Regular Class", 'l', 975 }, - { "DejaVu Sans", 12, "Regular Class", 'i', 975 }, - { "DejaVu Sans", 12, "Regular Class", 'j', 975 }, - { "DejaVu Sans", 13, "Regular Class", 'l', 950 }, - { "DejaVu Sans", 13, "Regular Class", 'i', 950 }, - { "DejaVu Sans", 13, "Regular Class", 'j', 950 }, - { "DejaVu Sans", 10, "Regular/Italic Class", 0, 1100 }, - { "DejaVu Sans", 12, "Regular/Italic Class", 0, 1050 }, - { "Georgia", 10, "", 0, 1050 }, - { "Georgia", 11, "", 0, 1100 }, - { "Georgia", 12, "", 0, 1025 }, - { "Georgia", 13, "", 0, 1050 }, - { "Georgia", 16, "", 0, 1050 }, - { "Georgia", 17, "", 0, 1030 }, - { "Liberation Sans", 12, "Regular Class", 'm', 1100 }, - { "Lucida Grande", 11, "Regular Class", 'm', 1100 }, - { "Microsoft Sans Serif", 11, "Regular Class", 'm', 950 }, - { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1050 }, - { "Segoe UI", 12, "Regular Class", 'H', 1050 }, - { "Segoe UI", 12, "Regular Class", 'm', 1050 }, - { "Segoe UI", 14, "Regular Class", 'm', 1050 }, - { "Tahoma", 11, "Regular Class", 'i', 975 }, - { "Tahoma", 11, "Regular Class", 'l', 975 }, - { "Tahoma", 11, "Regular Class", 'j', 900 }, - { "Tahoma", 11, "Regular Class", 'm', 918 }, - { "Verdana", 10, "Regular/Italic Class", 0, 1100 }, - { "Verdana", 12, "Regular Class", 'm', 975 }, - { "Verdana", 12, "Regular/Italic Class", 0, 1050 }, - { "Verdana", 13, "Regular/Italic Class", 'i', 950 }, - { "Verdana", 13, "Regular/Italic Class", 'j', 950 }, - { "Verdana", 13, "Regular/Italic Class", 'l', 950 }, - { "Verdana", 16, "Regular Class", 0, 1050 }, - { "Verdana", 9, "Regular/Italic Class", 0, 1050 }, - { "Times New Roman", 16, "Regular Class", 'm', 918 }, - { "Trebuchet MS", 11, "Regular Class", 'm', 800 }, - { "Trebuchet MS", 12, "Regular Class", 'm', 800 }, - }; - -#else - -#define COMPATIBLE_WIDTHS_RULES_SIZE 1 - - static const SPH_TweakRule COMPATIBLE_WIDTHS_Rules - [COMPATIBLE_WIDTHS_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - -#define X_SCALING_RULES_SIZE 1 - - static const SPH_ScaleRule X_SCALING_Rules - [X_SCALING_RULES_SIZE] = - { - { "-", 0, "", 0, 1000 }, - }; - -#endif /* FORCE_NATURAL_WIDTHS */ - - - FT_LOCAL_DEF( FT_Bool ) - is_member_of_family_class( const FT_String* detected_font_name, - const FT_String* rule_font_name ) - { - FT_UInt i, j; - - - /* Does font name match rule family? */ - if ( strcmp( detected_font_name, rule_font_name ) == 0 ) - return TRUE; - - /* Is font name a wildcard ""? */ - if ( strcmp( rule_font_name, "" ) == 0 ) - return TRUE; - - /* Is font name contained in a class list? */ - for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ ) - { - if ( strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 ) - { - for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ ) - { - if ( strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 ) - continue; - if ( strcmp( FAMILY_CLASS_Rules[i].member[j], - detected_font_name ) == 0 ) - return TRUE; - } - } - } - - return FALSE; - } - - - FT_LOCAL_DEF( FT_Bool ) - is_member_of_style_class( const FT_String* detected_font_style, - const FT_String* rule_font_style ) - { - FT_UInt i, j; - - - /* Does font style match rule style? */ - if ( strcmp( detected_font_style, rule_font_style ) == 0 ) - return TRUE; - - /* Is font style a wildcard ""? */ - if ( strcmp( rule_font_style, "" ) == 0 ) - return TRUE; - - /* Is font style contained in a class list? */ - for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ ) - { - if ( strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 ) - { - for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ ) - { - if ( strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 ) - continue; - if ( strcmp( STYLE_CLASS_Rules[i].member[j], - detected_font_style ) == 0 ) - return TRUE; - } - } - } - - return FALSE; - } - - - FT_LOCAL_DEF( FT_Bool ) - sph_test_tweak( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index, - const SPH_TweakRule* rule, - FT_UInt num_rules ) - { - FT_UInt i; - - - /* rule checks may be able to be optimized further */ - for ( i = 0; i < num_rules; i++ ) - { - if ( family && - ( is_member_of_family_class ( family, rule[i].family ) ) ) - if ( rule[i].ppem == 0 || - rule[i].ppem == ppem ) - if ( style && - is_member_of_style_class ( style, rule[i].style ) ) - if ( rule[i].glyph == 0 || - FT_Get_Char_Index( (FT_Face)face, - rule[i].glyph ) == glyph_index ) - return TRUE; - } - - return FALSE; - } - - - static FT_UInt - scale_test_tweak( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index, - const SPH_ScaleRule* rule, - FT_UInt num_rules ) - { - FT_UInt i; - - - /* rule checks may be able to be optimized further */ - for ( i = 0; i < num_rules; i++ ) - { - if ( family && - ( is_member_of_family_class ( family, rule[i].family ) ) ) - if ( rule[i].ppem == 0 || - rule[i].ppem == ppem ) - if ( style && - is_member_of_style_class( style, rule[i].style ) ) - if ( rule[i].glyph == 0 || - FT_Get_Char_Index( (FT_Face)face, - rule[i].glyph ) == glyph_index ) - return rule[i].scale; - } - - return 1000; - } - - - FT_LOCAL_DEF( FT_UInt ) - sph_test_tweak_x_scaling( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index ) - { - return scale_test_tweak( face, family, ppem, style, glyph_index, - X_SCALING_Rules, X_SCALING_RULES_SIZE ); - } - - -#define TWEAK_RULES( x ) \ - if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ - x##_Rules, x##_RULES_SIZE ) ) \ - loader->exec->sph_tweak_flags |= SPH_TWEAK_##x; - -#define TWEAK_RULES_EXCEPTIONS( x ) \ - if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ - x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \ - loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x; - - - FT_LOCAL_DEF( void ) - sph_set_tweaks( TT_Loader loader, - FT_UInt glyph_index ) - { - TT_Face face = (TT_Face)loader->face; - FT_String* family = face->root.family_name; - int ppem = loader->size->metrics.x_ppem; - FT_String* style = face->root.style_name; - - - /* don't apply rules if style isn't set */ - if ( !face->root.style_name ) - return; - -#ifdef SPH_DEBUG_MORE_VERBOSE - printf( "%s,%d,%s,%c=%d ", - family, ppem, style, glyph_index, glyph_index ); -#endif - - TWEAK_RULES( PIXEL_HINTING ); - - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING ) - { - loader->exec->ignore_x_mode = FALSE; - return; - } - - TWEAK_RULES( ALLOW_X_DMOVE ); - TWEAK_RULES( ALWAYS_DO_DELTAP ); - TWEAK_RULES( ALWAYS_SKIP_DELTAP ); - TWEAK_RULES( DEEMBOLDEN ); - TWEAK_RULES( DO_SHPIX ); - TWEAK_RULES( EMBOLDEN ); - TWEAK_RULES( MIAP_HACK ); - TWEAK_RULES( NORMAL_ROUND ); - TWEAK_RULES( NO_ALIGNRP_AFTER_IUP ); - TWEAK_RULES( NO_CALL_AFTER_IUP ); - TWEAK_RULES( NO_DELTAP_AFTER_IUP ); - TWEAK_RULES( RASTERIZER_35 ); - TWEAK_RULES( SKIP_IUP ); - - TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES ); - - TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES_DELTAP ); - - TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES ); - - TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES ); - - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) - { - if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 ) - { - loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - loader->exec->size->cvt_ready = FALSE; - - tt_size_ready_bytecode( - loader->exec->size, - FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); - } - else - loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - } - else - { - if ( loader->exec->rasterizer_version != - SPH_OPTION_SET_RASTERIZER_VERSION ) - { - loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - loader->exec->size->cvt_ready = FALSE; - - tt_size_ready_bytecode( - loader->exec->size, - FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); - } - else - loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - } - - if ( IS_HINTED( loader->load_flags ) ) - { - TWEAK_RULES( TIMES_NEW_ROMAN_HACK ); - TWEAK_RULES( COURIER_NEW_2_HACK ); - } - - if ( sph_test_tweak( face, family, ppem, style, glyph_index, - COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) ) - loader->exec->face->sph_compatibility_mode = TRUE; - - - if ( IS_HINTED( loader->load_flags ) ) - { - if ( sph_test_tweak( face, family, ppem, style, glyph_index, - COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) ) - loader->exec->compatible_widths |= TRUE; - } - } - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - /* ANSI C doesn't like empty source files */ - typedef int _tt_subpix_dummy; - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttsubpix.h b/drivers/freetype/freetype/src/truetype/ttsubpix.h deleted file mode 100644 index 8a54fc7cc7..0000000000 --- a/drivers/freetype/freetype/src/truetype/ttsubpix.h +++ /dev/null @@ -1,110 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsubpix.h */ -/* */ -/* TrueType Subpixel Hinting. */ -/* */ -/* Copyright 2010-2013 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 __TTSUBPIX_H__ -#define __TTSUBPIX_H__ - -#include <ft2build.h> -#include "ttobjs.h" -#include "ttinterp.h" - - -FT_BEGIN_HEADER - - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - /*************************************************************************/ - /* */ - /* ID flags to identify special functions at FDEF and runtime. */ - /* */ - /* */ -#define SPH_FDEF_INLINE_DELTA_1 0x0000001 -#define SPH_FDEF_INLINE_DELTA_2 0x0000002 -#define SPH_FDEF_DIAGONAL_STROKE 0x0000004 -#define SPH_FDEF_VACUFORM_ROUND_1 0x0000008 -#define SPH_FDEF_TTFAUTOHINT_1 0x0000010 -#define SPH_FDEF_SPACING_1 0x0000020 -#define SPH_FDEF_SPACING_2 0x0000040 -#define SPH_FDEF_TYPEMAN_STROKES 0x0000080 -#define SPH_FDEF_TYPEMAN_DIAGENDCTRL 0x0000100 - - - /*************************************************************************/ - /* */ - /* Tweak flags that are set for each glyph by the below rules. */ - /* */ - /* */ -#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001 -#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002 -#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004 -#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008 -#define SPH_TWEAK_DEEMBOLDEN 0x0000010 -#define SPH_TWEAK_DO_SHPIX 0x0000020 -#define SPH_TWEAK_EMBOLDEN 0x0000040 -#define SPH_TWEAK_MIAP_HACK 0x0000080 -#define SPH_TWEAK_NORMAL_ROUND 0x0000100 -#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200 -#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400 -#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800 -#define SPH_TWEAK_PIXEL_HINTING 0x0001000 -#define SPH_TWEAK_RASTERIZER_35 0x0002000 -#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000 -#define SPH_TWEAK_SKIP_IUP 0x0008000 -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000 -#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000 -#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000 -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000 - - - FT_LOCAL( FT_Bool ) - sph_test_tweak( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index, - const SPH_TweakRule* rule, - FT_UInt num_rules ); - - FT_LOCAL( FT_UInt ) - sph_test_tweak_x_scaling( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index ); - - FT_LOCAL( void ) - sph_set_tweaks( TT_Loader loader, - FT_UInt glyph_index ); - - - /* These macros are defined absent a method for setting them */ -#define SPH_OPTION_BITMAP_WIDTHS FALSE -#define SPH_OPTION_SET_SUBPIXEL TRUE -#define SPH_OPTION_SET_GRAYSCALE FALSE -#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE -#define SPH_OPTION_SET_RASTERIZER_VERSION 38 - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -FT_END_HEADER - -#endif /* __TTSUBPIX_H__ */ - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/Jamfile b/drivers/freetype/freetype/src/type1/Jamfile deleted file mode 100644 index 8e366baae5..0000000000 --- a/drivers/freetype/freetype/src/type1/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/type1 Jamfile -# -# Copyright 2001 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) type1 ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = t1afm t1driver t1objs t1load t1gload t1parse ; - } - else - { - _sources = type1 ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/type1 Jamfile diff --git a/drivers/freetype/freetype/src/type1/module.mk b/drivers/freetype/freetype/src/type1/module.mk deleted file mode 100644 index ade0210d76..0000000000 --- a/drivers/freetype/freetype/src/type1/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 Type1 module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += TYPE1_DRIVER - -define TYPE1_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, t1_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/type1/rules.mk b/drivers/freetype/freetype/src/type1/rules.mk deleted file mode 100644 index 15087b0304..0000000000 --- a/drivers/freetype/freetype/src/type1/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 Type1 driver configuration rules -# - - -# Copyright 1996-2000, 2001, 2003 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. - - -# Type1 driver directory -# -T1_DIR := $(SRC_DIR)/type1 - - -# compilation flags for the driver -# -T1_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T1_DIR)) - - -# Type1 driver sources (i.e., C files) -# -T1_DRV_SRC := $(T1_DIR)/t1parse.c \ - $(T1_DIR)/t1load.c \ - $(T1_DIR)/t1driver.c \ - $(T1_DIR)/t1afm.c \ - $(T1_DIR)/t1gload.c \ - $(T1_DIR)/t1objs.c - -# Type1 driver headers -# -T1_DRV_H := $(T1_DRV_SRC:%.c=%.h) \ - $(T1_DIR)/t1tokens.h \ - $(T1_DIR)/t1errors.h - - -# Type1 driver object(s) -# -# T1_DRV_OBJ_M is used during `multi' builds -# T1_DRV_OBJ_S is used during `single' builds -# -T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR)/%.c=$(OBJ_DIR)/%.$O) -T1_DRV_OBJ_S := $(OBJ_DIR)/type1.$O - -# Type1 driver source file for single build -# -T1_DRV_SRC_S := $(T1_DIR)/type1.c - - -# Type1 driver - single object -# -$(T1_DRV_OBJ_S): $(T1_DRV_SRC_S) $(T1_DRV_SRC) $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(T1_DRV_SRC_S)) - - -# Type1 driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(T1_DIR)/%.c $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(T1_DRV_OBJ_S) -DRV_OBJS_M += $(T1_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/type1/t1afm.c b/drivers/freetype/freetype/src/type1/t1afm.c deleted file mode 100644 index de9c1997c4..0000000000 --- a/drivers/freetype/freetype/src/type1/t1afm.c +++ /dev/null @@ -1,396 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1afm.c */ -/* */ -/* AFM support for Type 1 fonts (body). */ -/* */ -/* Copyright 1996-2011, 2013 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 "t1afm.h" -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H -#include "t1errors.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_t1afm - - - FT_LOCAL_DEF( void ) - T1_Done_Metrics( FT_Memory memory, - AFM_FontInfo fi ) - { - FT_FREE( fi->KernPairs ); - fi->NumKernPair = 0; - - FT_FREE( fi->TrackKerns ); - fi->NumTrackKern = 0; - - FT_FREE( fi ); - } - - - /* read a glyph name and return the equivalent glyph index */ - static FT_Int - t1_get_index( const char* name, - FT_Offset len, - void* user_data ) - { - T1_Font type1 = (T1_Font)user_data; - FT_Int n; - - - /* PS string/name length must be < 16-bit */ - if ( len > 0xFFFFU ) - return 0; - - for ( n = 0; n < type1->num_glyphs; n++ ) - { - char* gname = (char*)type1->glyph_names[n]; - - - if ( gname && gname[0] == name[0] && - ft_strlen( gname ) == len && - ft_strncmp( gname, name, len ) == 0 ) - return n; - } - - return 0; - } - - -#undef KERN_INDEX -#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) - - - /* compare two kerning pairs */ - FT_CALLBACK_DEF( int ) - compare_kern_pairs( const void* a, - const void* b ) - { - AFM_KernPair pair1 = (AFM_KernPair)a; - AFM_KernPair pair2 = (AFM_KernPair)b; - - FT_ULong index1 = KERN_INDEX( pair1->index1, pair1->index2 ); - FT_ULong index2 = KERN_INDEX( pair2->index1, pair2->index2 ); - - - if ( index1 > index2 ) - return 1; - else if ( index1 < index2 ) - return -1; - else - return 0; - } - - - /* parse a PFM file -- for now, only read the kerning pairs */ - static FT_Error - T1_Read_PFM( FT_Face t1_face, - FT_Stream stream, - AFM_FontInfo fi ) - { - FT_Error error = FT_Err_Ok; - FT_Memory memory = stream->memory; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* p; - AFM_KernPair kp; - FT_Int width_table_length; - FT_CharMap oldcharmap; - FT_CharMap charmap; - FT_Int n; - - - start = (FT_Byte*)stream->cursor; - limit = (FT_Byte*)stream->limit; - - /* Figure out how long the width table is. */ - /* This info is a little-endian short at offset 99. */ - p = start + 99; - if ( p + 2 > limit ) - { - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - width_table_length = FT_PEEK_USHORT_LE( p ); - - p += 18 + width_table_length; - if ( p + 0x12 > limit || FT_PEEK_USHORT_LE( p ) < 0x12 ) - /* extension table is probably optional */ - goto Exit; - - /* Kerning offset is 14 bytes from start of extensions table. */ - p += 14; - p = start + FT_PEEK_ULONG_LE( p ); - - if ( p == start ) - /* zero offset means no table */ - goto Exit; - - if ( p + 2 > limit ) - { - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - fi->NumKernPair = FT_PEEK_USHORT_LE( p ); - p += 2; - if ( p + 4 * fi->NumKernPair > limit ) - { - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - /* Actually, kerning pairs are simply optional! */ - if ( fi->NumKernPair == 0 ) - goto Exit; - - /* allocate the pairs */ - if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) ) - goto Exit; - - /* now, read each kern pair */ - kp = fi->KernPairs; - limit = p + 4 * fi->NumKernPair; - - /* PFM kerning data are stored by encoding rather than glyph index, */ - /* so find the PostScript charmap of this font and install it */ - /* temporarily. If we find no PostScript charmap, then just use */ - /* the default and hope it is the right one. */ - oldcharmap = t1_face->charmap; - charmap = NULL; - - for ( n = 0; n < t1_face->num_charmaps; n++ ) - { - charmap = t1_face->charmaps[n]; - /* check against PostScript pseudo platform */ - if ( charmap->platform_id == 7 ) - { - error = FT_Set_Charmap( t1_face, charmap ); - if ( error ) - goto Exit; - break; - } - } - - /* Kerning info is stored as: */ - /* */ - /* encoding of first glyph (1 byte) */ - /* encoding of second glyph (1 byte) */ - /* offset (little-endian short) */ - for ( ; p < limit ; p += 4 ) - { - kp->index1 = FT_Get_Char_Index( t1_face, p[0] ); - kp->index2 = FT_Get_Char_Index( t1_face, p[1] ); - - kp->x = (FT_Int)FT_PEEK_SHORT_LE(p + 2); - kp->y = 0; - - kp++; - } - - if ( oldcharmap != NULL ) - error = FT_Set_Charmap( t1_face, oldcharmap ); - if ( error ) - goto Exit; - - /* now, sort the kern pairs according to their glyph indices */ - ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ), - compare_kern_pairs ); - - Exit: - if ( error ) - { - FT_FREE( fi->KernPairs ); - fi->NumKernPair = 0; - } - - return error; - } - - - /* parse a metrics file -- either AFM or PFM depending on what */ - /* it turns out to be */ - FT_LOCAL_DEF( FT_Error ) - T1_Read_Metrics( FT_Face t1_face, - FT_Stream stream ) - { - PSAux_Service psaux; - FT_Memory memory = stream->memory; - AFM_ParserRec parser; - AFM_FontInfo fi = NULL; - FT_Error error = FT_ERR( Unknown_File_Format ); - T1_Font t1_font = &( (T1_Face)t1_face )->type1; - - - if ( FT_NEW( fi ) || - FT_FRAME_ENTER( stream->size ) ) - goto Exit; - - fi->FontBBox = t1_font->font_bbox; - fi->Ascender = t1_font->font_bbox.yMax; - fi->Descender = t1_font->font_bbox.yMin; - - psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; - if ( psaux->afm_parser_funcs ) - { - error = psaux->afm_parser_funcs->init( &parser, - stream->memory, - stream->cursor, - stream->limit ); - - if ( !error ) - { - parser.FontInfo = fi; - parser.get_index = t1_get_index; - parser.user_data = t1_font; - - error = psaux->afm_parser_funcs->parse( &parser ); - psaux->afm_parser_funcs->done( &parser ); - } - } - - if ( FT_ERR_EQ( error, Unknown_File_Format ) ) - { - FT_Byte* start = stream->cursor; - - - /* MS Windows allows versions up to 0x3FF without complaining */ - if ( stream->size > 6 && - start[1] < 4 && - FT_PEEK_ULONG_LE( start + 2 ) == stream->size ) - error = T1_Read_PFM( t1_face, stream, fi ); - } - - if ( !error ) - { - t1_font->font_bbox = fi->FontBBox; - - t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; - t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; - /* no `U' suffix here to 0xFFFF! */ - t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16; - t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16; - - /* no `U' suffix here to 0x8000! */ - t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000 ) >> 16 ); - t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 ); - - if ( fi->NumKernPair ) - { - t1_face->face_flags |= FT_FACE_FLAG_KERNING; - ( (T1_Face)t1_face )->afm_data = fi; - fi = NULL; - } - } - - FT_FRAME_EXIT(); - - Exit: - if ( fi != NULL ) - T1_Done_Metrics( memory, fi ); - - return error; - } - - - /* find the kerning for a given glyph pair */ - FT_LOCAL_DEF( void ) - T1_Get_Kerning( AFM_FontInfo fi, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - AFM_KernPair min, mid, max; - FT_ULong idx = KERN_INDEX( glyph1, glyph2 ); - - - /* simple binary search */ - min = fi->KernPairs; - max = min + fi->NumKernPair - 1; - - while ( min <= max ) - { - FT_ULong midi; - - - mid = min + ( max - min ) / 2; - midi = KERN_INDEX( mid->index1, mid->index2 ); - - if ( midi == idx ) - { - kerning->x = mid->x; - kerning->y = mid->y; - - return; - } - - if ( midi < idx ) - min = mid + 1; - else - max = mid - 1; - } - - kerning->x = 0; - kerning->y = 0; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Get_Track_Kerning( FT_Face face, - FT_Fixed ptsize, - FT_Int degree, - FT_Fixed* kerning ) - { - AFM_FontInfo fi = (AFM_FontInfo)( (T1_Face)face )->afm_data; - FT_Int i; - - - if ( !fi ) - return FT_THROW( Invalid_Argument ); - - for ( i = 0; i < fi->NumTrackKern; i++ ) - { - AFM_TrackKern tk = fi->TrackKerns + i; - - - if ( tk->degree != degree ) - continue; - - if ( ptsize < tk->min_ptsize ) - *kerning = tk->min_kern; - else if ( ptsize > tk->max_ptsize ) - *kerning = tk->max_kern; - else - { - *kerning = FT_MulDiv( ptsize - tk->min_ptsize, - tk->max_kern - tk->min_kern, - tk->max_ptsize - tk->min_ptsize ) + - tk->min_kern; - } - } - - return FT_Err_Ok; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1afm.h b/drivers/freetype/freetype/src/type1/t1afm.h deleted file mode 100644 index 8eb1764de7..0000000000 --- a/drivers/freetype/freetype/src/type1/t1afm.h +++ /dev/null @@ -1,54 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1afm.h */ -/* */ -/* AFM support for Type 1 fonts (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __T1AFM_H__ -#define __T1AFM_H__ - -#include <ft2build.h> -#include "t1objs.h" -#include FT_INTERNAL_TYPE1_TYPES_H - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - T1_Read_Metrics( FT_Face face, - FT_Stream stream ); - - FT_LOCAL( void ) - T1_Done_Metrics( FT_Memory memory, - AFM_FontInfo fi ); - - FT_LOCAL( void ) - T1_Get_Kerning( AFM_FontInfo fi, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); - - FT_LOCAL( FT_Error ) - T1_Get_Track_Kerning( FT_Face face, - FT_Fixed ptsize, - FT_Int degree, - FT_Fixed* kerning ); - -FT_END_HEADER - -#endif /* __T1AFM_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1driver.c b/drivers/freetype/freetype/src/type1/t1driver.c deleted file mode 100644 index 697288d66d..0000000000 --- a/drivers/freetype/freetype/src/type1/t1driver.c +++ /dev/null @@ -1,726 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1driver.c */ -/* */ -/* Type 1 driver interface (body). */ -/* */ -/* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013 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 "t1driver.h" -#include "t1gload.h" -#include "t1load.h" - -#include "t1errors.h" - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include "t1afm.h" -#endif - -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H - -#include FT_SERVICE_MULTIPLE_MASTERS_H -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_XFREE86_NAME_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H -#include FT_SERVICE_POSTSCRIPT_INFO_H -#include FT_SERVICE_KERNING_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_t1driver - - /* - * GLYPH DICT SERVICE - * - */ - - static FT_Error - t1_get_glyph_name( T1_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); - - return FT_Err_Ok; - } - - - static FT_UInt - t1_get_name_index( T1_Face face, - FT_String* glyph_name ) - { - FT_Int i; - - - for ( i = 0; i < face->type1.num_glyphs; i++ ) - { - FT_String* gname = face->type1.glyph_names[i]; - - - if ( !ft_strcmp( glyph_name, gname ) ) - return (FT_UInt)i; - } - - return 0; - } - - - static const FT_Service_GlyphDictRec t1_service_glyph_dict = - { - (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t1_get_name_index - }; - - - /* - * POSTSCRIPT NAME SERVICE - * - */ - - static const char* - t1_get_ps_name( T1_Face face ) - { - return (const char*) face->type1.font_name; - } - - - static const FT_Service_PsFontNameRec t1_service_ps_name = - { - (FT_PsName_GetFunc)t1_get_ps_name - }; - - - /* - * MULTIPLE MASTERS SERVICE - * - */ - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - static const FT_Service_MultiMastersRec t1_service_multi_masters = - { - (FT_Get_MM_Func) T1_Get_Multi_Master, - (FT_Set_MM_Design_Func) T1_Set_MM_Design, - (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, - (FT_Get_MM_Var_Func) T1_Get_MM_Var, - (FT_Set_Var_Design_Func)T1_Set_Var_Design - }; -#endif - - - /* - * POSTSCRIPT INFO SERVICE - * - */ - - static FT_Error - t1_ps_get_font_info( FT_Face face, - PS_FontInfoRec* afont_info ) - { - *afont_info = ((T1_Face)face)->type1.font_info; - - return FT_Err_Ok; - } - - - static FT_Error - t1_ps_get_font_extra( FT_Face face, - PS_FontExtraRec* afont_extra ) - { - *afont_extra = ((T1_Face)face)->type1.font_extra; - - return FT_Err_Ok; - } - - - static FT_Int - t1_ps_has_glyph_names( FT_Face face ) - { - FT_UNUSED( face ); - - return 1; - } - - - static FT_Error - t1_ps_get_font_private( FT_Face face, - PS_PrivateRec* afont_private ) - { - *afont_private = ((T1_Face)face)->type1.private_dict; - - return FT_Err_Ok; - } - - - static FT_Long - t1_ps_get_font_value( FT_Face face, - PS_Dict_Keys key, - FT_UInt idx, - void *value, - FT_Long value_len ) - { - FT_Long retval = -1; - T1_Face t1face = (T1_Face)face; - T1_Font type1 = &t1face->type1; - - - switch ( key ) - { - case PS_DICT_FONT_TYPE: - retval = sizeof ( type1->font_type ); - if ( value && value_len >= retval ) - *((FT_Byte *)value) = type1->font_type; - break; - - case PS_DICT_FONT_MATRIX: - if ( idx < sizeof ( type1->font_matrix ) / - sizeof ( type1->font_matrix.xx ) ) - { - FT_Fixed val = 0; - - - retval = sizeof ( val ); - if ( value && value_len >= retval ) - { - switch ( idx ) - { - case 0: - val = type1->font_matrix.xx; - break; - case 1: - val = type1->font_matrix.xy; - break; - case 2: - val = type1->font_matrix.yx; - break; - case 3: - val = type1->font_matrix.yy; - break; - } - *((FT_Fixed *)value) = val; - } - } - break; - - case PS_DICT_FONT_BBOX: - if ( idx < sizeof ( type1->font_bbox ) / - sizeof ( type1->font_bbox.xMin ) ) - { - FT_Fixed val = 0; - - - retval = sizeof ( val ); - if ( value && value_len >= retval ) - { - switch ( idx ) - { - case 0: - val = type1->font_bbox.xMin; - break; - case 1: - val = type1->font_bbox.yMin; - break; - case 2: - val = type1->font_bbox.xMax; - break; - case 3: - val = type1->font_bbox.yMax; - break; - } - *((FT_Fixed *)value) = val; - } - } - break; - - case PS_DICT_PAINT_TYPE: - retval = sizeof ( type1->paint_type ); - if ( value && value_len >= retval ) - *((FT_Byte *)value) = type1->paint_type; - break; - - case PS_DICT_FONT_NAME: - retval = (FT_Long)( ft_strlen( type1->font_name ) + 1 ); - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_name ), retval ); - break; - - case PS_DICT_UNIQUE_ID: - retval = sizeof ( type1->private_dict.unique_id ); - if ( value && value_len >= retval ) - *((FT_Int *)value) = type1->private_dict.unique_id; - break; - - case PS_DICT_NUM_CHAR_STRINGS: - retval = sizeof ( type1->num_glyphs ); - if ( value && value_len >= retval ) - *((FT_Int *)value) = type1->num_glyphs; - break; - - case PS_DICT_CHAR_STRING_KEY: - if ( idx < (FT_UInt)type1->num_glyphs ) - { - retval = (FT_Long)( ft_strlen( type1->glyph_names[idx] ) + 1 ); - if ( value && value_len >= retval ) - { - ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; - } - } - break; - - case PS_DICT_CHAR_STRING: - if ( idx < (FT_UInt)type1->num_glyphs ) - { - retval = (FT_Long)( type1->charstrings_len[idx] + 1 ); - if ( value && value_len >= retval ) - { - ft_memcpy( value, (void *)( type1->charstrings[idx] ), - retval - 1 ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; - } - } - break; - - case PS_DICT_ENCODING_TYPE: - retval = sizeof ( type1->encoding_type ); - if ( value && value_len >= retval ) - *((T1_EncodingType *)value) = type1->encoding_type; - break; - - case PS_DICT_ENCODING_ENTRY: - if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY && - idx < (FT_UInt)type1->encoding.num_chars ) - { - retval = (FT_Long)( ft_strlen( type1->encoding.char_name[idx] ) + 1 ); - if ( value && value_len >= retval ) - { - ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ), - retval - 1 ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; - } - } - break; - - case PS_DICT_NUM_SUBRS: - retval = sizeof ( type1->num_subrs ); - if ( value && value_len >= retval ) - *((FT_Int *)value) = type1->num_subrs; - break; - - case PS_DICT_SUBR: - if ( idx < (FT_UInt)type1->num_subrs ) - { - retval = (FT_Long)( type1->subrs_len[idx] + 1 ); - if ( value && value_len >= retval ) - { - ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; - } - } - break; - - case PS_DICT_STD_HW: - retval = sizeof ( type1->private_dict.standard_width[0] ); - if ( value && value_len >= retval ) - *((FT_UShort *)value) = type1->private_dict.standard_width[0]; - break; - - case PS_DICT_STD_VW: - retval = sizeof ( type1->private_dict.standard_height[0] ); - if ( value && value_len >= retval ) - *((FT_UShort *)value) = type1->private_dict.standard_height[0]; - break; - - case PS_DICT_NUM_BLUE_VALUES: - retval = sizeof ( type1->private_dict.num_blue_values ); - if ( value && value_len >= retval ) - *((FT_Byte *)value) = type1->private_dict.num_blue_values; - break; - - case PS_DICT_BLUE_VALUE: - if ( idx < type1->private_dict.num_blue_values ) - { - retval = sizeof ( type1->private_dict.blue_values[idx] ); - if ( value && value_len >= retval ) - *((FT_Short *)value) = type1->private_dict.blue_values[idx]; - } - break; - - case PS_DICT_BLUE_SCALE: - retval = sizeof ( type1->private_dict.blue_scale ); - if ( value && value_len >= retval ) - *((FT_Fixed *)value) = type1->private_dict.blue_scale; - break; - - case PS_DICT_BLUE_FUZZ: - retval = sizeof ( type1->private_dict.blue_fuzz ); - if ( value && value_len >= retval ) - *((FT_Int *)value) = type1->private_dict.blue_fuzz; - break; - - case PS_DICT_BLUE_SHIFT: - retval = sizeof ( type1->private_dict.blue_shift ); - if ( value && value_len >= retval ) - *((FT_Int *)value) = type1->private_dict.blue_shift; - break; - - case PS_DICT_NUM_OTHER_BLUES: - retval = sizeof ( type1->private_dict.num_other_blues ); - if ( value && value_len >= retval ) - *((FT_Byte *)value) = type1->private_dict.num_other_blues; - break; - - case PS_DICT_OTHER_BLUE: - if ( idx < type1->private_dict.num_other_blues ) - { - retval = sizeof ( type1->private_dict.other_blues[idx] ); - if ( value && value_len >= retval ) - *((FT_Short *)value) = type1->private_dict.other_blues[idx]; - } - break; - - case PS_DICT_NUM_FAMILY_BLUES: - retval = sizeof ( type1->private_dict.num_family_blues ); - if ( value && value_len >= retval ) - *((FT_Byte *)value) = type1->private_dict.num_family_blues; - break; - - case PS_DICT_FAMILY_BLUE: - if ( idx < type1->private_dict.num_family_blues ) - { - retval = sizeof ( type1->private_dict.family_blues[idx] ); - if ( value && value_len >= retval ) - *((FT_Short *)value) = type1->private_dict.family_blues[idx]; - } - break; - - case PS_DICT_NUM_FAMILY_OTHER_BLUES: - retval = sizeof ( type1->private_dict.num_family_other_blues ); - if ( value && value_len >= retval ) - *((FT_Byte *)value) = type1->private_dict.num_family_other_blues; - break; - - case PS_DICT_FAMILY_OTHER_BLUE: - if ( idx < type1->private_dict.num_family_other_blues ) - { - retval = sizeof ( type1->private_dict.family_other_blues[idx] ); - if ( value && value_len >= retval ) - *((FT_Short *)value) = type1->private_dict.family_other_blues[idx]; - } - break; - - case PS_DICT_NUM_STEM_SNAP_H: - retval = sizeof ( type1->private_dict.num_snap_widths ); - if ( value && value_len >= retval ) - *((FT_Byte *)value) = type1->private_dict.num_snap_widths; - break; - - case PS_DICT_STEM_SNAP_H: - if ( idx < type1->private_dict.num_snap_widths ) - { - retval = sizeof ( type1->private_dict.snap_widths[idx] ); - if ( value && value_len >= retval ) - *((FT_Short *)value) = type1->private_dict.snap_widths[idx]; - } - break; - - case PS_DICT_NUM_STEM_SNAP_V: - retval = sizeof ( type1->private_dict.num_snap_heights ); - if ( value && value_len >= retval ) - *((FT_Byte *)value) = type1->private_dict.num_snap_heights; - break; - - case PS_DICT_STEM_SNAP_V: - if ( idx < type1->private_dict.num_snap_heights ) - { - retval = sizeof ( type1->private_dict.snap_heights[idx] ); - if ( value && value_len >= retval ) - *((FT_Short *)value) = type1->private_dict.snap_heights[idx]; - } - break; - - case PS_DICT_RND_STEM_UP: - retval = sizeof ( type1->private_dict.round_stem_up ); - if ( value && value_len >= retval ) - *((FT_Bool *)value) = type1->private_dict.round_stem_up; - break; - - case PS_DICT_FORCE_BOLD: - retval = sizeof ( type1->private_dict.force_bold ); - if ( value && value_len >= retval ) - *((FT_Bool *)value) = type1->private_dict.force_bold; - break; - - case PS_DICT_MIN_FEATURE: - if ( idx < sizeof ( type1->private_dict.min_feature ) / - sizeof ( type1->private_dict.min_feature[0] ) ) - { - retval = sizeof ( type1->private_dict.min_feature[idx] ); - if ( value && value_len >= retval ) - *((FT_Short *)value) = type1->private_dict.min_feature[idx]; - } - break; - - case PS_DICT_LEN_IV: - retval = sizeof ( type1->private_dict.lenIV ); - if ( value && value_len >= retval ) - *((FT_Int *)value) = type1->private_dict.lenIV; - break; - - case PS_DICT_PASSWORD: - retval = sizeof ( type1->private_dict.password ); - if ( value && value_len >= retval ) - *((FT_Long *)value) = type1->private_dict.password; - break; - - case PS_DICT_LANGUAGE_GROUP: - retval = sizeof ( type1->private_dict.language_group ); - if ( value && value_len >= retval ) - *((FT_Long *)value) = type1->private_dict.language_group; - break; - - case PS_DICT_IS_FIXED_PITCH: - retval = sizeof ( type1->font_info.is_fixed_pitch ); - if ( value && value_len >= retval ) - *((FT_Bool *)value) = type1->font_info.is_fixed_pitch; - break; - - case PS_DICT_UNDERLINE_POSITION: - retval = sizeof ( type1->font_info.underline_position ); - if ( value && value_len >= retval ) - *((FT_Short *)value) = type1->font_info.underline_position; - break; - - case PS_DICT_UNDERLINE_THICKNESS: - retval = sizeof ( type1->font_info.underline_thickness ); - if ( value && value_len >= retval ) - *((FT_UShort *)value) = type1->font_info.underline_thickness; - break; - - case PS_DICT_FS_TYPE: - retval = sizeof ( type1->font_extra.fs_type ); - if ( value && value_len >= retval ) - *((FT_UShort *)value) = type1->font_extra.fs_type; - break; - - case PS_DICT_VERSION: - retval = (FT_Long)( ft_strlen( type1->font_info.version ) + 1 ); - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.version ), retval ); - break; - - case PS_DICT_NOTICE: - retval = (FT_Long)( ft_strlen( type1->font_info.notice ) + 1 ); - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.notice ), retval ); - break; - - case PS_DICT_FULL_NAME: - retval = (FT_Long)( ft_strlen( type1->font_info.full_name ) + 1 ); - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.full_name ), retval ); - break; - - case PS_DICT_FAMILY_NAME: - retval = (FT_Long)( ft_strlen( type1->font_info.family_name ) + 1 ); - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.family_name ), retval ); - break; - - case PS_DICT_WEIGHT: - retval = (FT_Long)( ft_strlen( type1->font_info.weight ) + 1 ); - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.weight ), retval ); - break; - - case PS_DICT_ITALIC_ANGLE: - retval = sizeof ( type1->font_info.italic_angle ); - if ( value && value_len >= retval ) - *((FT_Long *)value) = type1->font_info.italic_angle; - break; - - default: - break; - } - - return retval; - } - - - static const FT_Service_PsInfoRec t1_service_ps_info = - { - (PS_GetFontInfoFunc) t1_ps_get_font_info, - (PS_GetFontExtraFunc) t1_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t1_ps_get_font_private, - (PS_GetFontValueFunc) t1_ps_get_font_value, - }; - - -#ifndef T1_CONFIG_OPTION_NO_AFM - static const FT_Service_KerningRec t1_service_kerning = - { - T1_Get_Track_Kerning, - }; -#endif - - - /* - * SERVICE LIST - * - */ - - static const FT_ServiceDescRec t1_services[] = - { - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name }, - { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_1 }, - { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, - -#ifndef T1_CONFIG_OPTION_NO_AFM - { FT_SERVICE_ID_KERNING, &t1_service_kerning }, -#endif - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - { FT_SERVICE_ID_MULTI_MASTERS, &t1_service_multi_masters }, -#endif - { NULL, NULL } - }; - - - FT_CALLBACK_DEF( FT_Module_Interface ) - Get_Interface( FT_Module module, - const FT_String* t1_interface ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( t1_services, t1_interface ); - } - - -#ifndef T1_CONFIG_OPTION_NO_AFM - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Get_Kerning */ - /* */ - /* <Description> */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* <Output> */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static FT_Error - Get_Kerning( FT_Face t1face, /* T1_Face */ - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - T1_Face face = (T1_Face)t1face; - - - kerning->x = 0; - kerning->y = 0; - - if ( face->afm_data ) - T1_Get_Kerning( (AFM_FontInfo)face->afm_data, - left_glyph, - right_glyph, - kerning ); - - return FT_Err_Ok; - } - - -#endif /* T1_CONFIG_OPTION_NO_AFM */ - - - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec t1_driver_class = - { - { - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - FT_MODULE_DRIVER_HAS_HINTER, - - sizeof ( FT_DriverRec ), - - "type1", - 0x10000L, - 0x20000L, - - 0, /* format interface */ - - T1_Driver_Init, - T1_Driver_Done, - Get_Interface, - }, - - sizeof ( T1_FaceRec ), - sizeof ( T1_SizeRec ), - sizeof ( T1_GlyphSlotRec ), - - T1_Face_Init, - T1_Face_Done, - T1_Size_Init, - T1_Size_Done, - T1_GlyphSlot_Init, - T1_GlyphSlot_Done, - - T1_Load_Glyph, - -#ifdef T1_CONFIG_OPTION_NO_AFM - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ -#else - Get_Kerning, - T1_Read_Metrics, -#endif - T1_Get_Advances, - T1_Size_Request, - 0 /* FT_Size_SelectFunc */ - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1driver.h b/drivers/freetype/freetype/src/type1/t1driver.h deleted file mode 100644 index 639cd4a7ad..0000000000 --- a/drivers/freetype/freetype/src/type1/t1driver.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1driver.h */ -/* */ -/* High-level Type 1 driver interface (specification). */ -/* */ -/* Copyright 1996-2001, 2002 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 __T1DRIVER_H__ -#define __T1DRIVER_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; - - -FT_END_HEADER - -#endif /* __T1DRIVER_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1errors.h b/drivers/freetype/freetype/src/type1/t1errors.h deleted file mode 100644 index 8740530eef..0000000000 --- a/drivers/freetype/freetype/src/type1/t1errors.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1errors.h */ -/* */ -/* Type 1 error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the Type 1 error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __T1ERRORS_H__ -#define __T1ERRORS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX T1_Err_ -#define FT_ERR_BASE FT_Mod_Err_Type1 - -#include FT_ERRORS_H - -#endif /* __T1ERRORS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1gload.c b/drivers/freetype/freetype/src/type1/t1gload.c deleted file mode 100644 index 23478d1288..0000000000 --- a/drivers/freetype/freetype/src/type1/t1gload.c +++ /dev/null @@ -1,517 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1gload.c */ -/* */ -/* Type 1 Glyph Loader (body). */ -/* */ -/* Copyright 1996-2006, 2008-2010, 2013 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 "t1gload.h" -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_OUTLINE_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H - -#include "t1errors.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_t1gload - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_LOCAL_DEF( FT_Error ) - T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, - FT_UInt glyph_index, - FT_Data* char_string ) - { - T1_Face face = (T1_Face)decoder->builder.face; - T1_Font type1 = &face->type1; - FT_Error error = FT_Err_Ok; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - FT_Incremental_InterfaceRec *inc = - face->root.internal->incremental_interface; -#endif - - - decoder->font_matrix = type1->font_matrix; - decoder->font_offset = type1->font_offset; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* For incremental fonts get the character data using the */ - /* callback function. */ - if ( inc ) - error = inc->funcs->get_glyph_data( inc->object, - glyph_index, char_string ); - else - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - /* For ordinary fonts get the character data stored in the face record. */ - { - char_string->pointer = type1->charstrings[glyph_index]; - char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; - } - - if ( !error ) - error = decoder->funcs.parse_charstrings( - decoder, (FT_Byte*)char_string->pointer, - char_string->length ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* Incremental fonts can optionally override the metrics. */ - if ( !error && inc && inc->funcs->get_glyph_metrics ) - { - FT_Incremental_MetricsRec metrics; - - - metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); - metrics.bearing_y = 0; - metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); - metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); - - error = inc->funcs->get_glyph_metrics( inc->object, - glyph_index, FALSE, &metrics ); - - decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); - decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); - decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); - } - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - return error; - } - - - FT_CALLBACK_DEF( FT_Error ) - T1_Parse_Glyph( T1_Decoder decoder, - FT_UInt glyph_index ) - { - FT_Data glyph_data; - FT_Error error = T1_Parse_Glyph_And_Get_Char_String( - decoder, glyph_index, &glyph_data ); - - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - if ( !error ) - { - T1_Face face = (T1_Face)decoder->builder.face; - - - if ( face->root.internal->incremental_interface ) - face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object, - &glyph_data ); - } - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Compute_Max_Advance( T1_Face face, - FT_Pos* max_advance ) - { - FT_Error error; - T1_DecoderRec decoder; - FT_Int glyph_index; - T1_Font type1 = &face->type1; - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); - - *max_advance = 0; - - /* initialize load decoder */ - error = psaux->t1_decoder_funcs->init( &decoder, - (FT_Face)face, - 0, /* size */ - 0, /* glyph slot */ - (FT_Byte**)type1->glyph_names, - face->blend, - 0, - FT_RENDER_MODE_NORMAL, - T1_Parse_Glyph ); - if ( error ) - return error; - - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; - - decoder.num_subrs = type1->num_subrs; - decoder.subrs = type1->subrs; - decoder.subrs_len = type1->subrs_len; - - decoder.buildchar = face->buildchar; - decoder.len_buildchar = face->len_buildchar; - - *max_advance = 0; - - /* for each glyph, parse the glyph charstring and extract */ - /* the advance width */ - for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) - { - /* now get load the unscaled outline */ - error = T1_Parse_Glyph( &decoder, glyph_index ); - if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) - *max_advance = decoder.builder.advance.x; - - /* ignore the error if one occurred - skip to next glyph */ - } - - psaux->t1_decoder_funcs->done( &decoder ); - - return FT_Err_Ok; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Get_Advances( FT_Face t1face, /* T1_Face */ - FT_UInt first, - FT_UInt count, - FT_Int32 load_flags, - FT_Fixed* advances ) - { - T1_Face face = (T1_Face)t1face; - T1_DecoderRec decoder; - T1_Font type1 = &face->type1; - PSAux_Service psaux = (PSAux_Service)face->psaux; - FT_UInt nn; - FT_Error error; - - - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - for ( nn = 0; nn < count; nn++ ) - advances[nn] = 0; - - return FT_Err_Ok; - } - - error = psaux->t1_decoder_funcs->init( &decoder, - (FT_Face)face, - 0, /* size */ - 0, /* glyph slot */ - (FT_Byte**)type1->glyph_names, - face->blend, - 0, - FT_RENDER_MODE_NORMAL, - T1_Parse_Glyph ); - if ( error ) - return error; - - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; - - decoder.num_subrs = type1->num_subrs; - decoder.subrs = type1->subrs; - decoder.subrs_len = type1->subrs_len; - - decoder.buildchar = face->buildchar; - decoder.len_buildchar = face->len_buildchar; - - for ( nn = 0; nn < count; nn++ ) - { - error = T1_Parse_Glyph( &decoder, first + nn ); - if ( !error ) - advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); - else - advances[nn] = 0; - } - - return FT_Err_Ok; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Load_Glyph( FT_GlyphSlot t1glyph, /* T1_GlyphSlot */ - FT_Size t1size, /* T1_Size */ - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - T1_GlyphSlot glyph = (T1_GlyphSlot)t1glyph; - FT_Error error; - T1_DecoderRec decoder; - T1_Face face = (T1_Face)t1glyph->face; - FT_Bool hinting; - T1_Font type1 = &face->type1; - PSAux_Service psaux = (PSAux_Service)face->psaux; - const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; - - FT_Matrix font_matrix; - FT_Vector font_offset; - FT_Data glyph_data; - FT_Bool must_finish_decoder = FALSE; -#ifdef FT_CONFIG_OPTION_INCREMENTAL - FT_Bool glyph_data_loaded = 0; -#endif - - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( glyph_index >= (FT_UInt)face->root.num_glyphs && - !face->root.internal->incremental_interface ) -#else - if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - if ( t1size ) - { - glyph->x_scale = t1size->metrics.x_scale; - glyph->y_scale = t1size->metrics.y_scale; - } - else - { - glyph->x_scale = 0x10000L; - glyph->y_scale = 0x10000L; - } - - t1glyph->outline.n_points = 0; - t1glyph->outline.n_contours = 0; - - hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && - ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); - - t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; - - error = decoder_funcs->init( &decoder, - t1glyph->face, - t1size, - t1glyph, - (FT_Byte**)type1->glyph_names, - face->blend, - FT_BOOL( hinting ), - FT_LOAD_TARGET_MODE( load_flags ), - T1_Parse_Glyph ); - if ( error ) - goto Exit; - - must_finish_decoder = TRUE; - - decoder.builder.no_recurse = FT_BOOL( - ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); - - decoder.num_subrs = type1->num_subrs; - decoder.subrs = type1->subrs; - decoder.subrs_len = type1->subrs_len; - - decoder.buildchar = face->buildchar; - decoder.len_buildchar = face->len_buildchar; - - /* now load the unscaled outline */ - error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, - &glyph_data ); - if ( error ) - goto Exit; -#ifdef FT_CONFIG_OPTION_INCREMENTAL - glyph_data_loaded = 1; -#endif - - font_matrix = decoder.font_matrix; - font_offset = decoder.font_offset; - - /* save new glyph tables */ - decoder_funcs->done( &decoder ); - - must_finish_decoder = FALSE; - - /* 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 ) - { - t1glyph->outline.flags &= FT_OUTLINE_OWNER; - t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; - - /* for composite glyphs, return only left side bearing and */ - /* advance width */ - if ( load_flags & FT_LOAD_NO_RECURSE ) - { - FT_Slot_Internal internal = t1glyph->internal; - - - t1glyph->metrics.horiBearingX = - FIXED_TO_INT( decoder.builder.left_bearing.x ); - t1glyph->metrics.horiAdvance = - FIXED_TO_INT( 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 = &t1glyph->metrics; - FT_Vector advance; - - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = - FIXED_TO_INT( decoder.builder.advance.x ); - t1glyph->linearHoriAdvance = - FIXED_TO_INT( decoder.builder.advance.x ); - t1glyph->internal->glyph_transformed = 0; - - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - /* make up vertical ones */ - metrics->vertAdvance = ( face->type1.font_bbox.yMax - - face->type1.font_bbox.yMin ) >> 16; - t1glyph->linearVertAdvance = metrics->vertAdvance; - } - else - { - metrics->vertAdvance = - FIXED_TO_INT( decoder.builder.advance.y ); - t1glyph->linearVertAdvance = - FIXED_TO_INT( decoder.builder.advance.y ); - } - - t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; - - if ( t1size && t1size->metrics.y_ppem < 24 ) - t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; - -#if 1 - /* apply the font matrix, if any */ - if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx || - font_matrix.xy != 0 || font_matrix.yx != 0 ) - FT_Outline_Transform( &t1glyph->outline, &font_matrix ); - - if ( font_offset.x || font_offset.y ) - FT_Outline_Translate( &t1glyph->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; -#endif - - 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 we are not hinting */ - 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( &t1glyph->outline, &cbox ); - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - /* make up vertical ones */ - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); - } - } - - /* Set control data to the glyph charstrings. Note that this is */ - /* _not_ zero-terminated. */ - t1glyph->control_data = (FT_Byte*)glyph_data.pointer; - t1glyph->control_len = glyph_data.length; - } - - - Exit: - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( glyph_data_loaded && face->root.internal->incremental_interface ) - { - face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object, - &glyph_data ); - - /* Set the control data to null - it is no longer available if */ - /* loaded incrementally. */ - t1glyph->control_data = 0; - t1glyph->control_len = 0; - } -#endif - - if ( must_finish_decoder ) - decoder_funcs->done( &decoder ); - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1gload.h b/drivers/freetype/freetype/src/type1/t1gload.h deleted file mode 100644 index 0bdea3a8d5..0000000000 --- a/drivers/freetype/freetype/src/type1/t1gload.h +++ /dev/null @@ -1,53 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1gload.h */ -/* */ -/* Type 1 Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2008, 2011 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 __T1GLOAD_H__ -#define __T1GLOAD_H__ - - -#include <ft2build.h> -#include "t1objs.h" - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - T1_Compute_Max_Advance( T1_Face face, - FT_Pos* max_advance ); - - FT_LOCAL( FT_Error ) - T1_Get_Advances( FT_Face face, - FT_UInt first, - FT_UInt count, - FT_Int32 load_flags, - FT_Fixed* advances ); - - FT_LOCAL( FT_Error ) - T1_Load_Glyph( FT_GlyphSlot glyph, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ); - - -FT_END_HEADER - -#endif /* __T1GLOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1load.c b/drivers/freetype/freetype/src/type1/t1load.c deleted file mode 100644 index 1c834a17bb..0000000000 --- a/drivers/freetype/freetype/src/type1/t1load.c +++ /dev/null @@ -1,2267 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1load.c */ -/* */ -/* Type 1 font loader (body). */ -/* */ -/* Copyright 1996-2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This is the new and improved Type 1 data loader for FreeType 2. The */ - /* old loader has several problems: it is slow, complex, difficult to */ - /* maintain, and contains incredible hacks to make it accept some */ - /* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of */ - /* the Type 1 fonts on my machine still aren't loaded correctly by it. */ - /* */ - /* This version is much simpler, much faster and also easier to read and */ - /* maintain by a great order of magnitude. The idea behind it is to */ - /* _not_ try to read the Type 1 token stream with a state machine (i.e. */ - /* a Postscript-like interpreter) but rather to perform simple pattern */ - /* matching. */ - /* */ - /* Indeed, nearly all data definitions follow a simple pattern like */ - /* */ - /* ... /Field <data> ... */ - /* */ - /* where <data> can be a number, a boolean, a string, or an array of */ - /* numbers. There are a few exceptions, namely the encoding, font name, */ - /* charstrings, and subrs; they are handled with a special pattern */ - /* matching routine. */ - /* */ - /* All other common cases are handled very simply. The matching rules */ - /* are defined in the file `t1tokens.h' through the use of several */ - /* macros calls PARSE_XXX. This file is included twice here; the first */ - /* time to generate parsing callback functions, the second time to */ - /* generate a table of keywords (with pointers to the associated */ - /* callback functions). */ - /* */ - /* The function `parse_dict' simply scans *linearly* a given dictionary */ - /* (either the top-level or private one) and calls the appropriate */ - /* callback when it encounters an immediate keyword. */ - /* */ - /* This is by far the fastest way one can find to parse and read all */ - /* data. */ - /* */ - /* This led to tremendous code size reduction. Note that later, the */ - /* glyph loader will also be _greatly_ simplified, and the automatic */ - /* hinter will replace the clumsy `t1hinter'. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_CONFIG_CONFIG_H -#include FT_MULTIPLE_MASTERS_H -#include FT_INTERNAL_TYPE1_TYPES_H -#include FT_INTERNAL_CALC_H - -#include "t1load.h" -#include "t1errors.h" - - -#ifdef FT_CONFIG_OPTION_INCREMENTAL -#define IS_INCREMENTAL (FT_Bool)( face->root.internal->incremental_interface != 0 ) -#else -#define IS_INCREMENTAL 0 -#endif - - - /*************************************************************************/ - /* */ - /* 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_t1load - - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MULTIPLE MASTERS SUPPORT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_Error - t1_allocate_blend( T1_Face face, - FT_UInt num_designs, - FT_UInt num_axis ) - { - PS_Blend blend; - FT_Memory memory = face->root.memory; - FT_Error error = FT_Err_Ok; - - - blend = face->blend; - if ( !blend ) - { - if ( FT_NEW( blend ) ) - goto Exit; - - blend->num_default_design_vector = 0; - - face->blend = blend; - } - - /* allocate design data if needed */ - if ( num_designs > 0 ) - { - if ( blend->num_designs == 0 ) - { - FT_UInt nn; - - - /* allocate the blend `private' and `font_info' dictionaries */ - if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) || - FT_NEW_ARRAY( blend->privates [1], num_designs ) || - FT_NEW_ARRAY( blend->bboxes [1], num_designs ) || - FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) ) - goto Exit; - - blend->default_weight_vector = blend->weight_vector + num_designs; - - blend->font_infos[0] = &face->type1.font_info; - blend->privates [0] = &face->type1.private_dict; - blend->bboxes [0] = &face->type1.font_bbox; - - for ( nn = 2; nn <= num_designs; nn++ ) - { - blend->font_infos[nn] = blend->font_infos[nn - 1] + 1; - blend->privates [nn] = blend->privates [nn - 1] + 1; - blend->bboxes [nn] = blend->bboxes [nn - 1] + 1; - } - - blend->num_designs = num_designs; - } - else if ( blend->num_designs != num_designs ) - goto Fail; - } - - /* allocate axis data if needed */ - if ( num_axis > 0 ) - { - if ( blend->num_axis != 0 && blend->num_axis != num_axis ) - goto Fail; - - blend->num_axis = num_axis; - } - - /* allocate the blend design pos table if needed */ - num_designs = blend->num_designs; - num_axis = blend->num_axis; - if ( num_designs && num_axis && blend->design_pos[0] == 0 ) - { - FT_UInt n; - - - if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) ) - goto Exit; - - for ( n = 1; n < num_designs; n++ ) - blend->design_pos[n] = blend->design_pos[0] + num_axis * n; - } - - Exit: - return error; - - Fail: - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Get_Multi_Master( T1_Face face, - FT_Multi_Master* master ) - { - PS_Blend blend = face->blend; - FT_UInt n; - FT_Error error; - - - error = FT_THROW( Invalid_Argument ); - - if ( blend ) - { - master->num_axis = blend->num_axis; - master->num_designs = blend->num_designs; - - for ( n = 0; n < blend->num_axis; n++ ) - { - FT_MM_Axis* axis = master->axis + n; - PS_DesignMap map = blend->design_map + n; - - - axis->name = blend->axis_names[n]; - axis->minimum = map->design_points[0]; - axis->maximum = map->design_points[map->num_points - 1]; - } - - error = FT_Err_Ok; - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* Given a normalized (blend) coordinate, figure out the design */ - /* coordinate appropriate for that value. */ - /* */ - FT_LOCAL_DEF( FT_Fixed ) - mm_axis_unmap( PS_DesignMap axismap, - FT_Fixed ncv ) - { - int j; - - - if ( ncv <= axismap->blend_points[0] ) - return INT_TO_FIXED( axismap->design_points[0] ); - - for ( j = 1; j < axismap->num_points; ++j ) - { - if ( ncv <= axismap->blend_points[j] ) - return INT_TO_FIXED( axismap->design_points[j - 1] ) + - ( axismap->design_points[j] - axismap->design_points[j - 1] ) * - FT_DivFix( ncv - axismap->blend_points[j - 1], - axismap->blend_points[j] - - axismap->blend_points[j - 1] ); - } - - return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] ); - } - - - /*************************************************************************/ - /* */ - /* Given a vector of weights, one for each design, figure out the */ - /* normalized axis coordinates which gave rise to those weights. */ - /* */ - FT_LOCAL_DEF( void ) - mm_weights_unmap( FT_Fixed* weights, - FT_Fixed* axiscoords, - FT_UInt axis_count ) - { - FT_ASSERT( axis_count <= T1_MAX_MM_AXIS ); - - if ( axis_count == 1 ) - axiscoords[0] = weights[1]; - - else if ( axis_count == 2 ) - { - axiscoords[0] = weights[3] + weights[1]; - axiscoords[1] = weights[3] + weights[2]; - } - - else if ( axis_count == 3 ) - { - axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1]; - axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2]; - axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4]; - } - - else - { - axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] + - weights[7] + weights[5] + weights[3] + weights[1]; - axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] + - weights[7] + weights[6] + weights[3] + weights[2]; - axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] + - weights[7] + weights[6] + weights[5] + weights[4]; - axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] + - weights[11] + weights[10] + weights[9] + weights[8]; - } - } - - - /*************************************************************************/ - /* */ - /* Just a wrapper around T1_Get_Multi_Master to support the different */ - /* arguments needed by the GX var distortable fonts. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - T1_Get_MM_Var( T1_Face face, - FT_MM_Var* *master ) - { - FT_Memory memory = face->root.memory; - FT_MM_Var *mmvar = NULL; - FT_Multi_Master mmaster; - FT_Error error; - FT_UInt i; - FT_Fixed axiscoords[T1_MAX_MM_AXIS]; - PS_Blend blend = face->blend; - - - error = T1_Get_Multi_Master( face, &mmaster ); - if ( error ) - goto Exit; - if ( FT_ALLOC( mmvar, - sizeof ( FT_MM_Var ) + - mmaster.num_axis * sizeof ( FT_Var_Axis ) ) ) - goto Exit; - - mmvar->num_axis = mmaster.num_axis; - mmvar->num_designs = mmaster.num_designs; - mmvar->num_namedstyles = ~0U; /* Does not apply */ - mmvar->axis = (FT_Var_Axis*)&mmvar[1]; - /* Point to axes after MM_Var struct */ - mmvar->namedstyle = NULL; - - for ( i = 0 ; i < mmaster.num_axis; ++i ) - { - mmvar->axis[i].name = mmaster.axis[i].name; - mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); - mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum); - mmvar->axis[i].def = ( mmvar->axis[i].minimum + - mmvar->axis[i].maximum ) / 2; - /* Does not apply. But this value is in range */ - mmvar->axis[i].strid = ~0U; /* Does not apply */ - mmvar->axis[i].tag = ~0U; /* Does not apply */ - - if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) - mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); - else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 ) - mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' ); - else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 ) - mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' ); - } - - if ( blend->num_designs == ( 1U << blend->num_axis ) ) - { - mm_weights_unmap( blend->default_weight_vector, - axiscoords, - blend->num_axis ); - - for ( i = 0; i < mmaster.num_axis; ++i ) - mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], - axiscoords[i] ); - } - - *master = mmvar; - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Set_MM_Blend( T1_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - PS_Blend blend = face->blend; - FT_Error error; - FT_UInt n, m; - - - error = FT_ERR( Invalid_Argument ); - - if ( blend && blend->num_axis == num_coords ) - { - /* recompute the weight vector from the blend coordinates */ - error = FT_Err_Ok; - - for ( n = 0; n < blend->num_designs; n++ ) - { - FT_Fixed result = 0x10000L; /* 1.0 fixed */ - - - for ( m = 0; m < blend->num_axis; m++ ) - { - FT_Fixed factor; - - - /* get current blend axis position */ - factor = coords[m]; - if ( factor < 0 ) - factor = 0; - if ( factor > 0x10000L ) - factor = 0x10000L; - - if ( ( n & ( 1 << m ) ) == 0 ) - factor = 0x10000L - factor; - - result = FT_MulFix( result, factor ); - } - blend->weight_vector[n] = result; - } - - error = FT_Err_Ok; - } - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Set_MM_Design( T1_Face face, - FT_UInt num_coords, - FT_Long* coords ) - { - PS_Blend blend = face->blend; - FT_Error error; - FT_UInt n, p; - - - error = FT_ERR( Invalid_Argument ); - if ( blend && blend->num_axis == num_coords ) - { - /* compute the blend coordinates through the blend design map */ - FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; - - - for ( n = 0; n < blend->num_axis; n++ ) - { - FT_Long design = coords[n]; - FT_Fixed the_blend; - PS_DesignMap map = blend->design_map + n; - FT_Long* designs = map->design_points; - FT_Fixed* blends = map->blend_points; - FT_Int before = -1, after = -1; - - - for ( p = 0; p < (FT_UInt)map->num_points; p++ ) - { - FT_Long p_design = designs[p]; - - - /* exact match? */ - if ( design == p_design ) - { - the_blend = blends[p]; - goto Found; - } - - if ( design < p_design ) - { - after = p; - break; - } - - before = p; - } - - /* now interpolate if necessary */ - if ( before < 0 ) - the_blend = blends[0]; - - else if ( after < 0 ) - the_blend = blends[map->num_points - 1]; - - else - the_blend = FT_MulDiv( design - designs[before], - blends [after] - blends [before], - designs[after] - designs[before] ); - - Found: - final_blends[n] = the_blend; - } - - error = T1_Set_MM_Blend( face, num_coords, final_blends ); - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* Just a wrapper around T1_Set_MM_Design to support the different */ - /* arguments needed by the GX var distortable fonts. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - T1_Set_Var_Design( T1_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Long lcoords[4]; /* maximum axis count is 4 */ - FT_UInt i; - FT_Error error; - - - error = FT_ERR( Invalid_Argument ); - if ( num_coords <= 4 && num_coords > 0 ) - { - for ( i = 0; i < num_coords; ++i ) - lcoords[i] = FIXED_TO_INT( coords[i] ); - error = T1_Set_MM_Design( face, num_coords, lcoords ); - } - - return error; - } - - - FT_LOCAL_DEF( void ) - T1_Done_Blend( T1_Face face ) - { - FT_Memory memory = face->root.memory; - PS_Blend blend = face->blend; - - - if ( blend ) - { - FT_UInt num_designs = blend->num_designs; - FT_UInt num_axis = blend->num_axis; - FT_UInt n; - - - /* release design pos table */ - FT_FREE( blend->design_pos[0] ); - for ( n = 1; n < num_designs; n++ ) - blend->design_pos[n] = NULL; - - /* release blend `private' and `font info' dictionaries */ - FT_FREE( blend->privates[1] ); - FT_FREE( blend->font_infos[1] ); - FT_FREE( blend->bboxes[1] ); - - for ( n = 0; n < num_designs; n++ ) - { - blend->privates [n] = NULL; - blend->font_infos[n] = NULL; - blend->bboxes [n] = NULL; - } - - /* release weight vectors */ - FT_FREE( blend->weight_vector ); - blend->default_weight_vector = NULL; - - /* release axis names */ - for ( n = 0; n < num_axis; n++ ) - FT_FREE( blend->axis_names[n] ); - - /* release design map */ - for ( n = 0; n < num_axis; n++ ) - { - PS_DesignMap dmap = blend->design_map + n; - - - FT_FREE( dmap->design_points ); - dmap->num_points = 0; - } - - FT_FREE( face->blend ); - } - } - - - static void - parse_blend_axis_types( T1_Face face, - T1_Loader loader ) - { - T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; - FT_Int n, num_axis; - FT_Error error = FT_Err_Ok; - PS_Blend blend; - FT_Memory memory; - - - /* take an array of objects */ - T1_ToTokenArray( &loader->parser, axis_tokens, - T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis < 0 ) - { - error = FT_ERR( Ignore ); - goto Exit; - } - if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) - { - FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", - num_axis )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* allocate blend if necessary */ - error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); - if ( error ) - goto Exit; - - blend = face->blend; - memory = face->root.memory; - - /* each token is an immediate containing the name of the axis */ - for ( n = 0; n < num_axis; n++ ) - { - T1_Token token = axis_tokens + n; - FT_Byte* name; - FT_PtrDist len; - - - /* skip first slash, if any */ - if ( token->start[0] == '/' ) - token->start++; - - len = token->limit - token->start; - if ( len == 0 ) - { - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( FT_ALLOC( blend->axis_names[n], (FT_Long)( len + 1 ) ) ) - goto Exit; - - name = (FT_Byte*)blend->axis_names[n]; - FT_MEM_COPY( name, token->start, len ); - name[len] = '\0'; - } - - Exit: - loader->parser.root.error = error; - } - - - static void - parse_blend_design_positions( T1_Face face, - T1_Loader loader ) - { - T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; - FT_Int num_designs; - FT_Int num_axis; - T1_Parser parser = &loader->parser; - - FT_Error error = FT_Err_Ok; - PS_Blend blend; - - - /* get the array of design tokens -- compute number of designs */ - T1_ToTokenArray( parser, design_tokens, - T1_MAX_MM_DESIGNS, &num_designs ); - if ( num_designs < 0 ) - { - error = FT_ERR( Ignore ); - goto Exit; - } - if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) - { - FT_ERROR(( "parse_blend_design_positions:" - " incorrect number of designs: %d\n", - num_designs )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - { - FT_Byte* old_cursor = parser->root.cursor; - FT_Byte* old_limit = parser->root.limit; - FT_Int n; - - - blend = face->blend; - num_axis = 0; /* make compiler happy */ - - for ( n = 0; n < num_designs; n++ ) - { - T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; - T1_Token token; - FT_Int axis, n_axis; - - - /* read axis/coordinates tokens */ - token = design_tokens + n; - parser->root.cursor = token->start; - parser->root.limit = token->limit; - T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis ); - - if ( n == 0 ) - { - if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS ) - { - FT_ERROR(( "parse_blend_design_positions:" - " invalid number of axes: %d\n", - n_axis )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - num_axis = n_axis; - error = t1_allocate_blend( face, num_designs, num_axis ); - if ( error ) - goto Exit; - blend = face->blend; - } - else if ( n_axis != num_axis ) - { - FT_ERROR(( "parse_blend_design_positions: incorrect table\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* now read each axis token into the design position */ - for ( axis = 0; axis < n_axis; axis++ ) - { - T1_Token token2 = axis_tokens + axis; - - - parser->root.cursor = token2->start; - parser->root.limit = token2->limit; - blend->design_pos[n][axis] = T1_ToFixed( parser, 0 ); - } - } - - loader->parser.root.cursor = old_cursor; - loader->parser.root.limit = old_limit; - } - - Exit: - loader->parser.root.error = error; - } - - - static void - parse_blend_design_map( T1_Face face, - T1_Loader loader ) - { - FT_Error error = FT_Err_Ok; - T1_Parser parser = &loader->parser; - PS_Blend blend; - T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; - FT_Int n, num_axis; - FT_Byte* old_cursor; - FT_Byte* old_limit; - FT_Memory memory = face->root.memory; - - - T1_ToTokenArray( parser, axis_tokens, - T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis < 0 ) - { - error = FT_ERR( Ignore ); - goto Exit; - } - if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) - { - FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", - num_axis )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - old_cursor = parser->root.cursor; - old_limit = parser->root.limit; - - error = t1_allocate_blend( face, 0, num_axis ); - if ( error ) - goto Exit; - blend = face->blend; - - /* now read each axis design map */ - for ( n = 0; n < num_axis; n++ ) - { - PS_DesignMap map = blend->design_map + n; - T1_Token axis_token; - T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS]; - FT_Int p, num_points; - - - axis_token = axis_tokens + n; - - parser->root.cursor = axis_token->start; - parser->root.limit = axis_token->limit; - T1_ToTokenArray( parser, point_tokens, - T1_MAX_MM_MAP_POINTS, &num_points ); - - if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) - { - FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* allocate design map data */ - if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) ) - goto Exit; - map->blend_points = map->design_points + num_points; - map->num_points = (FT_Byte)num_points; - - for ( p = 0; p < num_points; p++ ) - { - T1_Token point_token; - - - point_token = point_tokens + p; - - /* don't include delimiting brackets */ - parser->root.cursor = point_token->start + 1; - parser->root.limit = point_token->limit - 1; - - map->design_points[p] = T1_ToInt( parser ); - map->blend_points [p] = T1_ToFixed( parser, 0 ); - } - } - - parser->root.cursor = old_cursor; - parser->root.limit = old_limit; - - Exit: - parser->root.error = error; - } - - - static void - parse_weight_vector( T1_Face face, - T1_Loader loader ) - { - T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; - FT_Int num_designs; - FT_Error error = FT_Err_Ok; - T1_Parser parser = &loader->parser; - PS_Blend blend = face->blend; - T1_Token token; - FT_Int n; - FT_Byte* old_cursor; - FT_Byte* old_limit; - - - T1_ToTokenArray( parser, design_tokens, - T1_MAX_MM_DESIGNS, &num_designs ); - if ( num_designs < 0 ) - { - error = FT_ERR( Ignore ); - goto Exit; - } - if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) - { - FT_ERROR(( "parse_weight_vector:" - " incorrect number of designs: %d\n", - num_designs )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( !blend || !blend->num_designs ) - { - error = t1_allocate_blend( face, num_designs, 0 ); - if ( error ) - goto Exit; - blend = face->blend; - } - else if ( blend->num_designs != (FT_UInt)num_designs ) - { - FT_ERROR(( "parse_weight_vector:" - " /BlendDesignPosition and /WeightVector have\n" - " " - " different number of elements\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - old_cursor = parser->root.cursor; - old_limit = parser->root.limit; - - for ( n = 0; n < num_designs; n++ ) - { - token = design_tokens + n; - parser->root.cursor = token->start; - parser->root.limit = token->limit; - - blend->default_weight_vector[n] = - blend->weight_vector[n] = T1_ToFixed( parser, 0 ); - } - - parser->root.cursor = old_cursor; - parser->root.limit = old_limit; - - Exit: - parser->root.error = error; - } - - - /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def */ - /* we're only interested in the number of array elements */ - static void - parse_buildchar( T1_Face face, - T1_Loader loader ) - { - face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 ); - - return; - } - - -#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ - - - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE 1 SYMBOL PARSING *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_Error - t1_load_keyword( T1_Face face, - T1_Loader loader, - const T1_Field field ) - { - FT_Error error; - void* dummy_object; - void** objects; - FT_UInt max_objects; - PS_Blend blend = face->blend; - - - if ( blend && blend->num_designs == 0 ) - blend = NULL; - - /* if the keyword has a dedicated callback, call it */ - if ( field->type == T1_FIELD_TYPE_CALLBACK ) - { - field->reader( (FT_Face)face, loader ); - error = loader->parser.root.error; - goto Exit; - } - - /* now, the keyword is either a simple field, or a table of fields; */ - /* we are now going to take care of it */ - switch ( field->location ) - { - case T1_FIELD_LOCATION_FONT_INFO: - dummy_object = &face->type1.font_info; - objects = &dummy_object; - max_objects = 0; - - if ( blend ) - { - objects = (void**)blend->font_infos; - max_objects = blend->num_designs; - } - break; - - case T1_FIELD_LOCATION_FONT_EXTRA: - dummy_object = &face->type1.font_extra; - objects = &dummy_object; - max_objects = 0; - break; - - case T1_FIELD_LOCATION_PRIVATE: - dummy_object = &face->type1.private_dict; - objects = &dummy_object; - max_objects = 0; - - if ( blend ) - { - objects = (void**)blend->privates; - max_objects = blend->num_designs; - } - break; - - case T1_FIELD_LOCATION_BBOX: - dummy_object = &face->type1.font_bbox; - objects = &dummy_object; - max_objects = 0; - - if ( blend ) - { - objects = (void**)blend->bboxes; - max_objects = blend->num_designs; - } - break; - - case T1_FIELD_LOCATION_LOADER: - dummy_object = loader; - objects = &dummy_object; - max_objects = 0; - break; - - case T1_FIELD_LOCATION_FACE: - dummy_object = face; - objects = &dummy_object; - max_objects = 0; - break; - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - case T1_FIELD_LOCATION_BLEND: - dummy_object = face->blend; - objects = &dummy_object; - max_objects = 0; - break; -#endif - - default: - dummy_object = &face->type1; - objects = &dummy_object; - max_objects = 0; - } - - if ( *objects ) - { - if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || - field->type == T1_FIELD_TYPE_FIXED_ARRAY ) - error = T1_Load_Field_Table( &loader->parser, field, - objects, max_objects, 0 ); - else - error = T1_Load_Field( &loader->parser, field, - objects, max_objects, 0 ); - } - else - { - FT_TRACE1(( "t1_load_keyword: ignoring keyword `%s'" - " which is not valid at this point\n" - " (probably due to missing keywords)\n", - field->ident )); - error = FT_Err_Ok; - } - - Exit: - return error; - } - - - static void - parse_private( T1_Face face, - T1_Loader loader ) - { - FT_UNUSED( face ); - - loader->keywords_encountered |= T1_PRIVATE; - } - - - static int - read_binary_data( T1_Parser parser, - FT_Long* size, - FT_Byte** base, - FT_Bool incremental ) - { - FT_Byte* cur; - FT_Byte* limit = parser->root.limit; - - - /* the binary data has one of the following formats */ - /* */ - /* `size' [white*] RD white ....... ND */ - /* `size' [white*] -| white ....... |- */ - /* */ - - T1_Skip_Spaces( parser ); - - cur = parser->root.cursor; - - if ( cur < limit && ft_isdigit( *cur ) ) - { - FT_Long s = T1_ToInt( parser ); - - - T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */ - - /* there is only one whitespace char after the */ - /* `RD' or `-|' token */ - *base = parser->root.cursor + 1; - - if ( s >= 0 && s < limit - *base ) - { - parser->root.cursor += s + 1; - *size = s; - return !parser->root.error; - } - } - - if( !incremental ) - { - FT_ERROR(( "read_binary_data: invalid size field\n" )); - parser->root.error = FT_THROW( Invalid_File_Format ); - } - - return 0; - } - - - /* We now define the routines to handle the `/Encoding', `/Subrs', */ - /* and `/CharStrings' dictionaries. */ - - static void - t1_parse_font_matrix( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - FT_Matrix* matrix = &face->type1.font_matrix; - FT_Vector* offset = &face->type1.font_offset; - FT_Face root = (FT_Face)&face->root; - FT_Fixed temp[6]; - FT_Fixed temp_scale; - FT_Int result; - - - result = T1_ToFixedArray( parser, 6, temp, 3 ); - - if ( result < 0 ) - { - parser->root.error = FT_THROW( Invalid_File_Format ); - return; - } - - temp_scale = FT_ABS( temp[3] ); - - if ( temp_scale == 0 ) - { - FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" )); - parser->root.error = FT_THROW( Invalid_File_Format ); - return; - } - - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ - - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); - - /* we need to scale the values by 1.0/temp_scale */ - if ( temp_scale != 0x10000L ) - { - temp[0] = FT_DivFix( temp[0], temp_scale ); - temp[1] = FT_DivFix( temp[1], temp_scale ); - temp[2] = FT_DivFix( temp[2], temp_scale ); - temp[4] = FT_DivFix( temp[4], temp_scale ); - temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; - } - - matrix->xx = temp[0]; - matrix->yx = temp[1]; - matrix->xy = temp[2]; - matrix->yy = temp[3]; - - /* note that the offsets must be expressed in integer font units */ - offset->x = temp[4] >> 16; - offset->y = temp[5] >> 16; - } - - - static void - parse_encoding( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - FT_Byte* cur; - FT_Byte* limit = parser->root.limit; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - T1_Skip_Spaces( parser ); - cur = parser->root.cursor; - if ( cur >= limit ) - { - FT_ERROR(( "parse_encoding: out of bounds\n" )); - parser->root.error = FT_THROW( Invalid_File_Format ); - return; - } - - /* if we have a number or `[', the encoding is an array, */ - /* and we must load it now */ - if ( ft_isdigit( *cur ) || *cur == '[' ) - { - T1_Encoding encode = &face->type1.encoding; - FT_Int count, n; - PS_Table char_table = &loader->encoding_table; - FT_Memory memory = parser->root.memory; - FT_Error error; - FT_Bool only_immediates = 0; - - - /* read the number of entries in the encoding; should be 256 */ - if ( *cur == '[' ) - { - count = 256; - only_immediates = 1; - parser->root.cursor++; - } - else - count = (FT_Int)T1_ToInt( parser ); - - T1_Skip_Spaces( parser ); - if ( parser->root.cursor >= limit ) - return; - - /* we use a T1_Table to store our charnames */ - loader->num_chars = encode->num_chars = count; - if ( FT_NEW_ARRAY( encode->char_index, count ) || - FT_NEW_ARRAY( encode->char_name, count ) || - FT_SET_ERROR( psaux->ps_table_funcs->init( - char_table, count, memory ) ) ) - { - parser->root.error = error; - return; - } - - /* We need to `zero' out encoding_table.elements */ - for ( n = 0; n < count; n++ ) - { - char* notdef = (char *)".notdef"; - - - T1_Add_Table( char_table, n, notdef, 8 ); - } - - /* Now we need to read records of the form */ - /* */ - /* ... charcode /charname ... */ - /* */ - /* for each entry in our table. */ - /* */ - /* We simply look for a number followed by an immediate */ - /* name. Note that this ignores correctly the sequence */ - /* that is often seen in type1 fonts: */ - /* */ - /* 0 1 255 { 1 index exch /.notdef put } for dup */ - /* */ - /* used to clean the encoding array before anything else. */ - /* */ - /* Alternatively, if the array is directly given as */ - /* */ - /* /Encoding [ ... ] */ - /* */ - /* we only read immediates. */ - - n = 0; - T1_Skip_Spaces( parser ); - - while ( parser->root.cursor < limit ) - { - cur = parser->root.cursor; - - /* we stop when we encounter a `def' or `]' */ - if ( *cur == 'd' && cur + 3 < limit ) - { - if ( cur[1] == 'e' && - cur[2] == 'f' && - IS_PS_DELIM( cur[3] ) ) - { - FT_TRACE6(( "encoding end\n" )); - cur += 3; - break; - } - } - if ( *cur == ']' ) - { - FT_TRACE6(( "encoding end\n" )); - cur++; - break; - } - - /* check whether we've found an entry */ - if ( ft_isdigit( *cur ) || only_immediates ) - { - FT_Int charcode; - - - if ( only_immediates ) - charcode = n; - else - { - charcode = (FT_Int)T1_ToInt( parser ); - T1_Skip_Spaces( parser ); - } - - cur = parser->root.cursor; - - if ( cur + 2 < limit && *cur == '/' && n < count ) - { - FT_PtrDist len; - - - cur++; - - parser->root.cursor = cur; - T1_Skip_PS_Token( parser ); - if ( parser->root.cursor >= limit ) - return; - if ( parser->root.error ) - return; - - len = parser->root.cursor - cur; - - parser->root.error = T1_Add_Table( char_table, charcode, - cur, len + 1 ); - if ( parser->root.error ) - return; - char_table->elements[charcode][len] = '\0'; - - n++; - } - else if ( only_immediates ) - { - /* Since the current position is not updated for */ - /* immediates-only mode we would get an infinite loop if */ - /* we don't do anything here. */ - /* */ - /* This encoding array is not valid according to the type1 */ - /* specification (it might be an encoding for a CID type1 */ - /* font, however), so we conclude that this font is NOT a */ - /* type1 font. */ - parser->root.error = FT_THROW( Unknown_File_Format ); - return; - } - } - else - { - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - return; - } - - T1_Skip_Spaces( parser ); - } - - face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; - parser->root.cursor = cur; - } - - /* Otherwise, we should have either `StandardEncoding', */ - /* `ExpertEncoding', or `ISOLatin1Encoding' */ - else - { - if ( cur + 17 < limit && - ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; - - else if ( cur + 15 < limit && - ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; - - else if ( cur + 18 < limit && - ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; - - else - parser->root.error = FT_ERR( Ignore ); - } - } - - - static void - parse_subrs( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - PS_Table table = &loader->subrs; - FT_Memory memory = parser->root.memory; - FT_Error error; - FT_Int num_subrs; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - T1_Skip_Spaces( parser ); - - /* test for empty array */ - if ( parser->root.cursor < parser->root.limit && - *parser->root.cursor == '[' ) - { - T1_Skip_PS_Token( parser ); - T1_Skip_Spaces ( parser ); - if ( parser->root.cursor >= parser->root.limit || - *parser->root.cursor != ']' ) - parser->root.error = FT_THROW( Invalid_File_Format ); - return; - } - - num_subrs = (FT_Int)T1_ToInt( parser ); - - /* position the parser right before the `dup' of the first subr */ - T1_Skip_PS_Token( parser ); /* `array' */ - if ( parser->root.error ) - return; - T1_Skip_Spaces( parser ); - - /* initialize subrs array -- with synthetic fonts it is possible */ - /* we get here twice */ - if ( !loader->num_subrs ) - { - error = psaux->ps_table_funcs->init( table, num_subrs, memory ); - if ( error ) - goto Fail; - } - - /* the format is simple: */ - /* */ - /* `index' + binary data */ - /* */ - for (;;) - { - FT_Long idx, size; - FT_Byte* base; - - - /* If we are out of data, or if the next token isn't `dup', */ - /* we are done. */ - if ( parser->root.cursor + 4 >= parser->root.limit || - ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) - break; - - T1_Skip_PS_Token( parser ); /* `dup' */ - - idx = T1_ToInt( parser ); - - if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) - return; - - /* The binary string is followed by one token, e.g. `NP' */ - /* (bound to `noaccess put') or by two separate tokens: */ - /* `noaccess' & `put'. We position the parser right */ - /* before the next `dup', if any. */ - T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */ - if ( parser->root.error ) - return; - T1_Skip_Spaces ( parser ); - - if ( parser->root.cursor + 4 < parser->root.limit && - ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) - { - T1_Skip_PS_Token( parser ); /* skip `put' */ - T1_Skip_Spaces ( parser ); - } - - /* with synthetic fonts it is possible we get here twice */ - if ( loader->num_subrs ) - continue; - - /* some fonts use a value of -1 for lenIV to indicate that */ - /* the charstrings are unencoded */ - /* */ - /* thanks to Tom Kacvinsky for pointing this out */ - /* */ - if ( face->type1.private_dict.lenIV >= 0 ) - { - FT_Byte* temp; - - - /* some fonts define empty subr records -- this is not totally */ - /* compliant to the specification (which says they should at */ - /* least contain a `return'), but we support them anyway */ - if ( size < face->type1.private_dict.lenIV ) - { - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* t1_decrypt() shouldn't write to base -- make temporary copy */ - if ( FT_ALLOC( temp, size ) ) - goto Fail; - FT_MEM_COPY( temp, base, size ); - psaux->t1_decrypt( temp, size, 4330 ); - size -= face->type1.private_dict.lenIV; - error = T1_Add_Table( table, (FT_Int)idx, - temp + face->type1.private_dict.lenIV, size ); - FT_FREE( temp ); - } - else - error = T1_Add_Table( table, (FT_Int)idx, base, size ); - if ( error ) - goto Fail; - } - - if ( !loader->num_subrs ) - loader->num_subrs = num_subrs; - - return; - - Fail: - parser->root.error = error; - } - - -#define TABLE_EXTEND 5 - - - static void - parse_charstrings( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - PS_Table code_table = &loader->charstrings; - PS_Table name_table = &loader->glyph_names; - PS_Table swap_table = &loader->swap_table; - FT_Memory memory = parser->root.memory; - FT_Error error; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - FT_Byte* cur; - FT_Byte* limit = parser->root.limit; - FT_Int n, num_glyphs; - FT_UInt notdef_index = 0; - FT_Byte notdef_found = 0; - - - num_glyphs = (FT_Int)T1_ToInt( parser ); - if ( num_glyphs < 0 ) - { - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* some fonts like Optima-Oblique not only define the /CharStrings */ - /* array but access it also */ - if ( num_glyphs == 0 || parser->root.error ) - return; - - /* initialize tables, leaving space for addition of .notdef, */ - /* if necessary, and a few other glyphs to handle buggy */ - /* fonts which have more glyphs than specified. */ - - /* for some non-standard fonts like `Optima' which provides */ - /* different outlines depending on the resolution it is */ - /* possible to get here twice */ - if ( !loader->num_glyphs ) - { - error = psaux->ps_table_funcs->init( - code_table, num_glyphs + 1 + TABLE_EXTEND, memory ); - if ( error ) - goto Fail; - - error = psaux->ps_table_funcs->init( - name_table, num_glyphs + 1 + TABLE_EXTEND, memory ); - if ( error ) - goto Fail; - - /* Initialize table for swapping index notdef_index and */ - /* index 0 names and codes (if necessary). */ - - error = psaux->ps_table_funcs->init( swap_table, 4, memory ); - if ( error ) - goto Fail; - } - - n = 0; - - for (;;) - { - FT_Long size; - FT_Byte* base; - - - /* the format is simple: */ - /* `/glyphname' + binary data */ - - T1_Skip_Spaces( parser ); - - cur = parser->root.cursor; - if ( cur >= limit ) - break; - - /* we stop when we find a `def' or `end' keyword */ - if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) ) - { - if ( cur[0] == 'd' && - cur[1] == 'e' && - cur[2] == 'f' ) - { - /* There are fonts which have this: */ - /* */ - /* /CharStrings 118 dict def */ - /* Private begin */ - /* CharStrings begin */ - /* ... */ - /* */ - /* To catch this we ignore `def' if */ - /* no charstring has actually been */ - /* seen. */ - if ( n ) - break; - } - - if ( cur[0] == 'e' && - cur[1] == 'n' && - cur[2] == 'd' ) - break; - } - - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - return; - - if ( *cur == '/' ) - { - FT_PtrDist len; - - - if ( cur + 1 >= limit ) - { - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - cur++; /* skip `/' */ - len = parser->root.cursor - cur; - - if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) - return; - - /* for some non-standard fonts like `Optima' which provides */ - /* different outlines depending on the resolution it is */ - /* possible to get here twice */ - if ( loader->num_glyphs ) - continue; - - error = T1_Add_Table( name_table, n, cur, len + 1 ); - if ( error ) - goto Fail; - - /* add a trailing zero to the name table */ - name_table->elements[n][len] = '\0'; - - /* record index of /.notdef */ - if ( *cur == '.' && - ft_strcmp( ".notdef", - (const char*)(name_table->elements[n]) ) == 0 ) - { - notdef_index = n; - notdef_found = 1; - } - - if ( face->type1.private_dict.lenIV >= 0 && - n < num_glyphs + TABLE_EXTEND ) - { - FT_Byte* temp; - - - if ( size <= face->type1.private_dict.lenIV ) - { - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* t1_decrypt() shouldn't write to base -- make temporary copy */ - if ( FT_ALLOC( temp, size ) ) - goto Fail; - FT_MEM_COPY( temp, base, size ); - psaux->t1_decrypt( temp, size, 4330 ); - size -= face->type1.private_dict.lenIV; - error = T1_Add_Table( code_table, n, - temp + face->type1.private_dict.lenIV, size ); - FT_FREE( temp ); - } - else - error = T1_Add_Table( code_table, n, base, size ); - if ( error ) - goto Fail; - - n++; - } - } - - loader->num_glyphs = n; - - /* if /.notdef is found but does not occupy index 0, do our magic. */ - if ( notdef_found && - ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) ) - { - /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ - /* name and code entries to swap_table. Then place notdef_index */ - /* name and code entries into swap_table. Then swap name and code */ - /* entries at indices notdef_index and 0 using values stored in */ - /* swap_table. */ - - /* Index 0 name */ - error = T1_Add_Table( swap_table, 0, - name_table->elements[0], - name_table->lengths [0] ); - if ( error ) - goto Fail; - - /* Index 0 code */ - error = T1_Add_Table( swap_table, 1, - code_table->elements[0], - code_table->lengths [0] ); - if ( error ) - goto Fail; - - /* Index notdef_index name */ - error = T1_Add_Table( swap_table, 2, - name_table->elements[notdef_index], - name_table->lengths [notdef_index] ); - if ( error ) - goto Fail; - - /* Index notdef_index code */ - error = T1_Add_Table( swap_table, 3, - code_table->elements[notdef_index], - code_table->lengths [notdef_index] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( name_table, notdef_index, - swap_table->elements[0], - swap_table->lengths [0] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( code_table, notdef_index, - swap_table->elements[1], - swap_table->lengths [1] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( name_table, 0, - swap_table->elements[2], - swap_table->lengths [2] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( code_table, 0, - swap_table->elements[3], - swap_table->lengths [3] ); - if ( error ) - goto Fail; - - } - else if ( !notdef_found ) - { - /* notdef_index is already 0, or /.notdef is undefined in */ - /* charstrings dictionary. Worry about /.notdef undefined. */ - /* We take index 0 and add it to the end of the table(s) */ - /* and add our own /.notdef glyph to index 0. */ - - /* 0 333 hsbw endchar */ - FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E }; - char* notdef_name = (char *)".notdef"; - - - error = T1_Add_Table( swap_table, 0, - name_table->elements[0], - name_table->lengths [0] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( swap_table, 1, - code_table->elements[0], - code_table->lengths [0] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( name_table, 0, notdef_name, 8 ); - if ( error ) - goto Fail; - - error = T1_Add_Table( code_table, 0, notdef_glyph, 5 ); - - if ( error ) - goto Fail; - - error = T1_Add_Table( name_table, n, - swap_table->elements[0], - swap_table->lengths [0] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( code_table, n, - swap_table->elements[1], - swap_table->lengths [1] ); - if ( error ) - goto Fail; - - /* we added a glyph. */ - loader->num_glyphs += 1; - } - - return; - - Fail: - parser->root.error = error; - } - - - /*************************************************************************/ - /* */ - /* Define the token field static variables. This is a set of */ - /* T1_FieldRec variables. */ - /* */ - /*************************************************************************/ - - - static - const T1_FieldRec t1_keywords[] = - { - -#include "t1tokens.h" - - /* now add the special functions... */ - T1_FIELD_CALLBACK( "FontMatrix", t1_parse_font_matrix, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_CALLBACK( "Encoding", parse_encoding, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_CALLBACK( "Subrs", parse_subrs, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_CALLBACK( "CharStrings", parse_charstrings, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_CALLBACK( "Private", parse_private, - T1_FIELD_DICT_FONTDICT ) - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar, - T1_FIELD_DICT_PRIVATE ) -#endif - - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } - }; - - -#define T1_FIELD_COUNT \ - ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) ) - - - static FT_Error - parse_dict( T1_Face face, - T1_Loader loader, - FT_Byte* base, - FT_Long size ) - { - T1_Parser parser = &loader->parser; - FT_Byte *limit, *start_binary = NULL; - FT_Bool have_integer = 0; - - - parser->root.cursor = base; - parser->root.limit = base + size; - parser->root.error = FT_Err_Ok; - - limit = parser->root.limit; - - T1_Skip_Spaces( parser ); - - while ( parser->root.cursor < limit ) - { - FT_Byte* cur; - - - cur = parser->root.cursor; - - /* look for `eexec' */ - if ( IS_PS_TOKEN( cur, limit, "eexec" ) ) - break; - - /* look for `closefile' which ends the eexec section */ - else if ( IS_PS_TOKEN( cur, limit, "closefile" ) ) - break; - - /* in a synthetic font the base font starts after a */ - /* `FontDictionary' token that is placed after a Private dict */ - else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) ) - { - if ( loader->keywords_encountered & T1_PRIVATE ) - loader->keywords_encountered |= - T1_FONTDIR_AFTER_PRIVATE; - parser->root.cursor += 13; - } - - /* check whether we have an integer */ - else if ( ft_isdigit( *cur ) ) - { - start_binary = cur; - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - goto Exit; - have_integer = 1; - } - - /* in valid Type 1 fonts we don't see `RD' or `-|' directly */ - /* since those tokens are handled by parse_subrs and */ - /* parse_charstrings */ - else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' && - have_integer ) - { - FT_Long s; - FT_Byte* b; - - - parser->root.cursor = start_binary; - if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) ) - return FT_THROW( Invalid_File_Format ); - have_integer = 0; - } - - else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' && - have_integer ) - { - FT_Long s; - FT_Byte* b; - - - parser->root.cursor = start_binary; - if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) ) - return FT_THROW( Invalid_File_Format ); - have_integer = 0; - } - - /* look for immediates */ - else if ( *cur == '/' && cur + 2 < limit ) - { - FT_PtrDist len; - - - cur++; - - parser->root.cursor = cur; - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - goto Exit; - - len = parser->root.cursor - cur; - - if ( len > 0 && len < 22 && parser->root.cursor < limit ) - { - /* now compare the immediate name to the keyword table */ - T1_Field keyword = (T1_Field)t1_keywords; - - - for (;;) - { - FT_Byte* name; - - - name = (FT_Byte*)keyword->ident; - if ( !name ) - break; - - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char *)name ) && - ft_memcmp( cur, name, len ) == 0 ) - { - /* We found it -- run the parsing callback! */ - /* We record every instance of every field */ - /* (until we reach the base font of a */ - /* synthetic font) to deal adequately with */ - /* multiple master fonts; this is also */ - /* necessary because later PostScript */ - /* definitions override earlier ones. */ - - /* Once we encounter `FontDirectory' after */ - /* `/Private', we know that this is a synthetic */ - /* font; except for `/CharStrings' we are not */ - /* interested in anything that follows this */ - /* `FontDirectory'. */ - - /* MM fonts have more than one /Private token at */ - /* the top level; let's hope that all the junk */ - /* that follows the first /Private token is not */ - /* interesting to us. */ - - /* According to Adobe Tech Note #5175 (CID-Keyed */ - /* Font Installation for ATM Software) a `begin' */ - /* must be followed by exactly one `end', and */ - /* `begin' -- `end' pairs must be accurately */ - /* paired. We could use this to distinguish */ - /* between the global Private and the Private */ - /* dict that is a member of the Blend dict. */ - - const FT_UInt dict = - ( loader->keywords_encountered & T1_PRIVATE ) - ? T1_FIELD_DICT_PRIVATE - : T1_FIELD_DICT_FONTDICT; - - if ( !( dict & keyword->dict ) ) - { - FT_TRACE1(( "parse_dict: found `%s' but ignoring it" - " since it is in the wrong dictionary\n", - keyword->ident )); - break; - } - - if ( !( loader->keywords_encountered & - T1_FONTDIR_AFTER_PRIVATE ) || - ft_strcmp( (const char*)name, "CharStrings" ) == 0 ) - { - parser->root.error = t1_load_keyword( face, - loader, - keyword ); - if ( parser->root.error != FT_Err_Ok ) - { - if ( FT_ERR_EQ( parser->root.error, Ignore ) ) - parser->root.error = FT_Err_Ok; - else - return parser->root.error; - } - } - break; - } - - keyword++; - } - } - - have_integer = 0; - } - else - { - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - goto Exit; - have_integer = 0; - } - - T1_Skip_Spaces( parser ); - } - - Exit: - return parser->root.error; - } - - - static void - t1_init_loader( T1_Loader loader, - T1_Face face ) - { - FT_UNUSED( face ); - - FT_MEM_ZERO( loader, sizeof ( *loader ) ); - loader->num_glyphs = 0; - loader->num_chars = 0; - - /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - loader->subrs.init = 0; - loader->swap_table.init = 0; - loader->fontdata = 0; - loader->keywords_encountered = 0; - } - - - static void - t1_done_loader( T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - - - /* finalize tables */ - T1_Release_Table( &loader->encoding_table ); - T1_Release_Table( &loader->charstrings ); - T1_Release_Table( &loader->glyph_names ); - T1_Release_Table( &loader->swap_table ); - T1_Release_Table( &loader->subrs ); - - /* finalize parser */ - T1_Finalize_Parser( parser ); - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Open_Face( T1_Face face ) - { - T1_LoaderRec loader; - T1_Parser parser; - T1_Font type1 = &face->type1; - PS_Private priv = &type1->private_dict; - FT_Error error; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - t1_init_loader( &loader, face ); - - /* default values */ - face->ndv_idx = -1; - face->cdv_idx = -1; - face->len_buildchar = 0; - - priv->blue_shift = 7; - priv->blue_fuzz = 1; - priv->lenIV = 4; - priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); - priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - - parser = &loader.parser; - error = T1_New_Parser( parser, - face->root.stream, - face->root.memory, - psaux ); - if ( error ) - goto Exit; - - error = parse_dict( face, &loader, - parser->base_dict, parser->base_len ); - if ( error ) - goto Exit; - - error = T1_Get_Private_Dict( parser, psaux ); - if ( error ) - goto Exit; - - error = parse_dict( face, &loader, - parser->private_dict, parser->private_len ); - if ( error ) - goto Exit; - - /* ensure even-ness of `num_blue_values' */ - priv->num_blue_values &= ~1; - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - - if ( face->blend && - face->blend->num_default_design_vector != 0 && - face->blend->num_default_design_vector != face->blend->num_axis ) - { - /* we don't use it currently so just warn, reset, and ignore */ - FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries " - "while there are %u axes.\n", - face->blend->num_default_design_vector, - face->blend->num_axis )); - - face->blend->num_default_design_vector = 0; - } - - /* the following can happen for MM instances; we then treat the */ - /* font as a normal PS font */ - if ( face->blend && - ( !face->blend->num_designs || !face->blend->num_axis ) ) - T1_Done_Blend( face ); - - /* another safety check */ - if ( face->blend ) - { - FT_UInt i; - - - for ( i = 0; i < face->blend->num_axis; i++ ) - if ( !face->blend->design_map[i].num_points ) - { - T1_Done_Blend( face ); - break; - } - } - - if ( face->blend ) - { - if ( face->len_buildchar > 0 ) - { - FT_Memory memory = face->root.memory; - - - if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) ) - { - FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" )); - face->len_buildchar = 0; - goto Exit; - } - } - } - else - face->len_buildchar = 0; - -#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ - - /* now, propagate the subrs, charstrings, and glyphnames tables */ - /* to the Type1 data */ - type1->num_glyphs = loader.num_glyphs; - - if ( loader.subrs.init ) - { - loader.subrs.init = 0; - type1->num_subrs = loader.num_subrs; - type1->subrs_block = loader.subrs.block; - type1->subrs = loader.subrs.elements; - type1->subrs_len = loader.subrs.lengths; - } - - if ( !IS_INCREMENTAL ) - if ( !loader.charstrings.init ) - { - FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" )); - error = FT_THROW( Invalid_File_Format ); - } - - loader.charstrings.init = 0; - type1->charstrings_block = loader.charstrings.block; - type1->charstrings = loader.charstrings.elements; - type1->charstrings_len = loader.charstrings.lengths; - - /* we copy the glyph names `block' and `elements' fields; */ - /* the `lengths' field must be released later */ - type1->glyph_names_block = loader.glyph_names.block; - type1->glyph_names = (FT_String**)loader.glyph_names.elements; - loader.glyph_names.block = 0; - loader.glyph_names.elements = 0; - - /* we must now build type1.encoding when we have a custom array */ - if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) - { - FT_Int charcode, idx, min_char, max_char; - FT_Byte* char_name; - FT_Byte* glyph_name; - - - /* OK, we do the following: for each element in the encoding */ - /* table, look up the index of the glyph having the same name */ - /* the index is then stored in type1.encoding.char_index, and */ - /* the name to type1.encoding.char_name */ - - min_char = 0; - max_char = 0; - - charcode = 0; - for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) - { - type1->encoding.char_index[charcode] = 0; - type1->encoding.char_name [charcode] = (char *)".notdef"; - - char_name = loader.encoding_table.elements[charcode]; - if ( char_name ) - for ( idx = 0; idx < type1->num_glyphs; idx++ ) - { - glyph_name = (FT_Byte*)type1->glyph_names[idx]; - if ( ft_strcmp( (const char*)char_name, - (const char*)glyph_name ) == 0 ) - { - type1->encoding.char_index[charcode] = (FT_UShort)idx; - type1->encoding.char_name [charcode] = (char*)glyph_name; - - /* Change min/max encoded char only if glyph name is */ - /* not /.notdef */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)glyph_name ) != 0 ) - { - if ( charcode < min_char ) - min_char = charcode; - if ( charcode >= max_char ) - max_char = charcode + 1; - } - break; - } - } - } - - type1->encoding.code_first = min_char; - type1->encoding.code_last = max_char; - type1->encoding.num_chars = loader.num_chars; - } - - Exit: - t1_done_loader( &loader ); - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1load.h b/drivers/freetype/freetype/src/type1/t1load.h deleted file mode 100644 index 546fc33530..0000000000 --- a/drivers/freetype/freetype/src/type1/t1load.h +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1load.h */ -/* */ -/* Type 1 font loader (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2004, 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 __T1LOAD_H__ -#define __T1LOAD_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_MULTIPLE_MASTERS_H - -#include "t1parse.h" - - -FT_BEGIN_HEADER - - - typedef struct T1_Loader_ - { - T1_ParserRec parser; /* parser used to read the stream */ - - FT_Int num_chars; /* number of characters in encoding */ - PS_TableRec encoding_table; /* PS_Table used to store the */ - /* encoding character names */ - - FT_Int num_glyphs; - PS_TableRec glyph_names; - PS_TableRec charstrings; - PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ - - FT_Int num_subrs; - PS_TableRec subrs; - FT_Bool fontdata; - - FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */ - - } T1_LoaderRec, *T1_Loader; - - - /* treatment of some keywords differs depending on whether */ - /* they precede or follow certain other keywords */ - -#define T1_PRIVATE ( 1 << 0 ) -#define T1_FONTDIR_AFTER_PRIVATE ( 1 << 1 ) - - - FT_LOCAL( FT_Error ) - T1_Open_Face( T1_Face face ); - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - - FT_LOCAL( FT_Error ) - T1_Get_Multi_Master( T1_Face face, - FT_Multi_Master* master ); - - FT_LOCAL_DEF( FT_Error ) - T1_Get_MM_Var( T1_Face face, - FT_MM_Var* *master ); - - FT_LOCAL( FT_Error ) - T1_Set_MM_Blend( T1_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - FT_LOCAL( FT_Error ) - T1_Set_MM_Design( T1_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - FT_LOCAL_DEF( FT_Error ) - T1_Set_Var_Design( T1_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - FT_LOCAL( void ) - T1_Done_Blend( T1_Face face ); - -#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ - - -FT_END_HEADER - -#endif /* __T1LOAD_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1objs.c b/drivers/freetype/freetype/src/type1/t1objs.c deleted file mode 100644 index 837b7911d4..0000000000 --- a/drivers/freetype/freetype/src/type1/t1objs.c +++ /dev/null @@ -1,616 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1objs.c */ -/* */ -/* Type 1 objects manager (body). */ -/* */ -/* Copyright 1996-2009, 2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_IDS_H - -#include "t1gload.h" -#include "t1load.h" - -#include "t1errors.h" - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include "t1afm.h" -#endif - -#include FT_SERVICE_POSTSCRIPT_CMAPS_H -#include FT_INTERNAL_POSTSCRIPT_AUX_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_t1objs - - - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /* note that we store the global hints in the size's "internal" root */ - /* field */ - /* */ - /*************************************************************************/ - - - static PSH_Globals_Funcs - T1_Size_Get_Globals_Funcs( T1_Size size ) - { - T1_Face face = (T1_Face)size->root.face; - PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; - FT_Module module; - - - module = FT_Get_Module( size->root.face->driver->root.library, - "pshinter" ); - return ( module && pshinter && pshinter->get_globals_funcs ) - ? pshinter->get_globals_funcs( module ) - : 0 ; - } - - - FT_LOCAL_DEF( void ) - T1_Size_Done( FT_Size t1size ) /* T1_Size */ - { - T1_Size size = (T1_Size)t1size; - - - if ( size->root.internal ) - { - PSH_Globals_Funcs funcs; - - - funcs = T1_Size_Get_Globals_Funcs( size ); - if ( funcs ) - funcs->destroy( (PSH_Globals)size->root.internal ); - - size->root.internal = 0; - } - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Size_Init( FT_Size t1size ) /* T1_Size */ - { - T1_Size size = (T1_Size)t1size; - FT_Error error = FT_Err_Ok; - PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); - - - if ( funcs ) - { - PSH_Globals globals; - T1_Face face = (T1_Face)size->root.face; - - - error = funcs->create( size->root.face->memory, - &face->type1.private_dict, &globals ); - if ( !error ) - size->root.internal = (FT_Size_Internal)(void*)globals; - } - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Size_Request( FT_Size t1size, /* T1_Size */ - FT_Size_Request req ) - { - T1_Size size = (T1_Size)t1size; - PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); - - - FT_Request_Metrics( size->root.face, req ); - - if ( funcs ) - funcs->set_scale( (PSH_Globals)size->root.internal, - size->root.metrics.x_scale, - size->root.metrics.y_scale, - 0, 0 ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* SLOT FUNCTIONS */ - /* */ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - T1_GlyphSlot_Done( FT_GlyphSlot slot ) - { - slot->internal->glyph_hints = 0; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_GlyphSlot_Init( FT_GlyphSlot slot ) - { - T1_Face face; - PSHinter_Service pshinter; - - - face = (T1_Face)slot->face; - pshinter = (PSHinter_Service)face->pshinter; - - if ( pshinter ) - { - FT_Module module; - - - module = FT_Get_Module( slot->face->driver->root.library, - "pshinter" ); - if ( module ) - { - T1_Hints_Funcs funcs; - - - funcs = pshinter->get_t1_funcs( module ); - slot->internal->glyph_hints = (void*)funcs; - } - } - - return 0; - } - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* T1_Face_Done */ - /* */ - /* <Description> */ - /* The face object destructor. */ - /* */ - /* <Input> */ - /* face :: A typeless pointer to the face object to destroy. */ - /* */ - FT_LOCAL_DEF( void ) - T1_Face_Done( FT_Face t1face ) /* T1_Face */ - { - T1_Face face = (T1_Face)t1face; - FT_Memory memory; - T1_Font type1; - - - if ( !face ) - return; - - memory = face->root.memory; - type1 = &face->type1; - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - /* release multiple masters information */ - FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); - - if ( face->buildchar ) - { - FT_FREE( face->buildchar ); - - face->buildchar = NULL; - face->len_buildchar = 0; - } - - T1_Done_Blend( face ); - face->blend = 0; -#endif - - /* release font info strings */ - { - PS_FontInfo info = &type1->font_info; - - - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); - } - - /* release top dictionary */ - FT_FREE( type1->charstrings_len ); - FT_FREE( type1->charstrings ); - FT_FREE( type1->glyph_names ); - - FT_FREE( type1->subrs ); - FT_FREE( type1->subrs_len ); - - FT_FREE( type1->subrs_block ); - FT_FREE( type1->charstrings_block ); - FT_FREE( type1->glyph_names_block ); - - FT_FREE( type1->encoding.char_index ); - FT_FREE( type1->encoding.char_name ); - FT_FREE( type1->font_name ); - -#ifndef T1_CONFIG_OPTION_NO_AFM - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); -#endif - - /* release unicode map, if any */ -#if 0 - FT_FREE( face->unicode_map_rec.maps ); - face->unicode_map_rec.num_maps = 0; - face->unicode_map = NULL; -#endif - - face->root.family_name = NULL; - face->root.style_name = NULL; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* T1_Face_Init */ - /* */ - /* <Description> */ - /* The face object constructor. */ - /* */ - /* <Input> */ - /* stream :: input stream where to load font data. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* <InOut> */ - /* face :: The face record to build. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - T1_Face_Init( FT_Stream stream, - FT_Face t1face, /* T1_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - T1_Face face = (T1_Face)t1face; - FT_Error error; - FT_Service_PsCMaps psnames; - PSAux_Service psaux; - T1_Font type1 = &face->type1; - PS_FontInfo info = &type1->font_info; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( stream ); - - - face->root.num_faces = 1; - - FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); - face->psnames = psnames; - - face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), - "psaux" ); - psaux = (PSAux_Service)face->psaux; - if ( !psaux ) - { - FT_ERROR(( "T1_Face_Init: cannot access `psaux' module\n" )); - error = FT_THROW( Missing_Module ); - goto Exit; - } - - face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), - "pshinter" ); - - FT_TRACE2(( "Type 1 driver\n" )); - - /* open the tokenizer; this will also check the font format */ - error = T1_Open_Face( face ); - if ( error ) - goto Exit; - - /* if we just wanted to check the format, leave successfully now */ - if ( face_index < 0 ) - goto Exit; - - /* check the face index */ - if ( face_index > 0 ) - { - FT_ERROR(( "T1_Face_Init: invalid face index\n" )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* now load the font program into the face object */ - - /* initialize the face object fields */ - - /* set up root face fields */ - { - FT_Face root = (FT_Face)&face->root; - - - root->num_glyphs = type1->num_glyphs; - root->face_index = 0; - - root->face_flags = FT_FACE_FLAG_SCALABLE | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_GLYPH_NAMES | - FT_FACE_FLAG_HINTER; - - if ( info->is_fixed_pitch ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - if ( face->blend ) - root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; - - /* XXX: TODO -- add kerning with .afm support */ - - - /* The following code to extract the family and the style is very */ - /* simplistic and might get some things wrong. For a full-featured */ - /* algorithm you might have a look at the whitepaper given at */ - /* */ - /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ - - /* get style name -- be careful, some broken fonts only */ - /* have a `/FontName' dictionary entry! */ - root->family_name = info->family_name; - root->style_name = NULL; - - if ( root->family_name ) - { - char* full = info->full_name; - char* family = root->family_name; - - - if ( full ) - { - FT_Bool the_same = TRUE; - - - while ( *full ) - { - if ( *full == *family ) - { - family++; - full++; - } - else - { - if ( *full == ' ' || *full == '-' ) - full++; - else if ( *family == ' ' || *family == '-' ) - family++; - else - { - the_same = FALSE; - - if ( !*family ) - root->style_name = full; - break; - } - } - } - - if ( the_same ) - root->style_name = (char *)"Regular"; - } - } - else - { - /* do we have a `/FontName'? */ - if ( type1->font_name ) - root->family_name = type1->font_name; - } - - if ( !root->style_name ) - { - if ( info->weight ) - root->style_name = info->weight; - else - /* assume `Regular' style because we don't know better */ - root->style_name = (char *)"Regular"; - } - - /* compute style flags */ - root->style_flags = 0; - if ( info->italic_angle ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - if ( info->weight ) - { - if ( !ft_strcmp( info->weight, "Bold" ) || - !ft_strcmp( info->weight, "Black" ) ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - } - - /* no embedded bitmap support */ - root->num_fixed_sizes = 0; - root->available_sizes = 0; - - root->bbox.xMin = type1->font_bbox.xMin >> 16; - root->bbox.yMin = type1->font_bbox.yMin >> 16; - /* no `U' suffix here to 0xFFFF! */ - root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16; - root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16; - - /* Set units_per_EM if we didn't set it in t1_parse_font_matrix. */ - if ( !root->units_per_EM ) - root->units_per_EM = 1000; - - root->ascender = (FT_Short)( root->bbox.yMax ); - root->descender = (FT_Short)( root->bbox.yMin ); - - root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 ); - if ( root->height < root->ascender - root->descender ) - root->height = (FT_Short)( root->ascender - root->descender ); - - /* now compute the maximum advance width */ - root->max_advance_width = - (FT_Short)( root->bbox.xMax ); - { - FT_Pos max_advance; - - - error = T1_Compute_Max_Advance( face, &max_advance ); - - /* in case of error, keep the standard width */ - if ( !error ) - root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); - else - error = FT_Err_Ok; /* clear error */ - } - - root->max_advance_height = root->height; - - root->underline_position = (FT_Short)info->underline_position; - root->underline_thickness = (FT_Short)info->underline_thickness; - } - - { - FT_Face root = &face->root; - - - if ( psnames ) - { - FT_CharMapRec charmap; - T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; - FT_CMap_Class clazz; - - - charmap.face = root; - - /* first of all, try to synthesize a Unicode charmap */ - charmap.platform_id = TT_PLATFORM_MICROSOFT; - charmap.encoding_id = TT_MS_ID_UNICODE_CS; - charmap.encoding = FT_ENCODING_UNICODE; - - error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); - if ( error && - FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) - goto Exit; - error = FT_Err_Ok; - - /* now, generate an Adobe Standard encoding when appropriate */ - charmap.platform_id = TT_PLATFORM_ADOBE; - clazz = NULL; - - switch ( type1->encoding_type ) - { - case T1_ENCODING_TYPE_STANDARD: - charmap.encoding = FT_ENCODING_ADOBE_STANDARD; - charmap.encoding_id = TT_ADOBE_ID_STANDARD; - clazz = cmap_classes->standard; - break; - - case T1_ENCODING_TYPE_EXPERT: - charmap.encoding = FT_ENCODING_ADOBE_EXPERT; - charmap.encoding_id = TT_ADOBE_ID_EXPERT; - clazz = cmap_classes->expert; - break; - - case T1_ENCODING_TYPE_ARRAY: - charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; - charmap.encoding_id = TT_ADOBE_ID_CUSTOM; - clazz = cmap_classes->custom; - break; - - case T1_ENCODING_TYPE_ISOLATIN1: - charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; - charmap.encoding_id = TT_ADOBE_ID_LATIN_1; - clazz = cmap_classes->unicode; - break; - - default: - ; - } - - if ( clazz ) - error = FT_CMap_New( clazz, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if (root->num_charmaps) - root->charmap = root->charmaps[0]; -#endif - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* T1_Driver_Init */ - /* */ - /* <Description> */ - /* Initializes a given Type 1 driver object. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target driver object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - T1_Driver_Init( FT_Module driver ) - { - FT_UNUSED( driver ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* T1_Driver_Done */ - /* */ - /* <Description> */ - /* Finalizes a given Type 1 driver. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target Type 1 driver. */ - /* */ - FT_LOCAL_DEF( void ) - T1_Driver_Done( FT_Module driver ) - { - FT_UNUSED( driver ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1objs.h b/drivers/freetype/freetype/src/type1/t1objs.h deleted file mode 100644 index 54ccbb996a..0000000000 --- a/drivers/freetype/freetype/src/type1/t1objs.h +++ /dev/null @@ -1,160 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1objs.h */ -/* */ -/* Type 1 objects manager (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2006, 2011 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 __T1OBJS_H__ -#define __T1OBJS_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_TYPE1_TYPES_H - - -FT_BEGIN_HEADER - - - /* The following structures must be defined by the hinter */ - typedef struct T1_Size_Hints_ T1_Size_Hints; - typedef struct T1_Glyph_Hints_ T1_Glyph_Hints; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* T1_Size */ - /* */ - /* <Description> */ - /* A handle to a Type 1 size object. */ - /* */ - typedef struct T1_SizeRec_* T1_Size; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* T1_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to a Type 1 glyph slot object. */ - /* */ - typedef struct T1_GlyphSlotRec_* T1_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* T1_CharMap */ - /* */ - /* <Description> */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* <Note> */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ - typedef struct T1_CharMapRec_* T1_CharMap; - - - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* T1_SizeRec */ - /* */ - /* <Description> */ - /* Type 1 size record. */ - /* */ - typedef struct T1_SizeRec_ - { - FT_SizeRec root; - - } T1_SizeRec; - - - FT_LOCAL( void ) - T1_Size_Done( FT_Size size ); - - FT_LOCAL( FT_Error ) - T1_Size_Request( FT_Size size, - FT_Size_Request req ); - - FT_LOCAL( FT_Error ) - T1_Size_Init( FT_Size size ); - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* T1_GlyphSlotRec */ - /* */ - /* <Description> */ - /* Type 1 glyph slot record. */ - /* */ - typedef struct T1_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Int max_points; - FT_Int max_contours; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - } T1_GlyphSlotRec; - - - FT_LOCAL( FT_Error ) - T1_Face_Init( FT_Stream stream, - FT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - FT_LOCAL( void ) - T1_Face_Done( FT_Face face ); - - FT_LOCAL( FT_Error ) - T1_GlyphSlot_Init( FT_GlyphSlot slot ); - - FT_LOCAL( void ) - T1_GlyphSlot_Done( FT_GlyphSlot slot ); - - FT_LOCAL( FT_Error ) - T1_Driver_Init( FT_Module driver ); - - FT_LOCAL( void ) - T1_Driver_Done( FT_Module driver ); - - -FT_END_HEADER - -#endif /* __T1OBJS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1parse.c b/drivers/freetype/freetype/src/type1/t1parse.c deleted file mode 100644 index 106e4e7ecd..0000000000 --- a/drivers/freetype/freetype/src/type1/t1parse.c +++ /dev/null @@ -1,497 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1parse.c */ -/* */ -/* Type 1 parser (body). */ -/* */ -/* Copyright 1996-2005, 2008, 2009, 2012, 2013 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The Type 1 parser is in charge of the following: */ - /* */ - /* - provide an implementation of a growing sequence of objects called */ - /* a `T1_Table' (used to build various tables needed by the loader). */ - /* */ - /* - opening .pfb and .pfa files to extract their top-level and private */ - /* dictionaries. */ - /* */ - /* - read numbers, arrays & strings from any dictionary. */ - /* */ - /* See `t1load.c' to see how data is loaded from the font file. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H - -#include "t1parse.h" - -#include "t1errors.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_t1parse - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** INPUT STREAM PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* see Adobe Technical Note 5040.Download_Fonts.pdf */ - - static FT_Error - read_pfb_tag( FT_Stream stream, - FT_UShort *atag, - FT_ULong *asize ) - { - FT_Error error; - FT_UShort tag; - FT_ULong size; - - - *atag = 0; - *asize = 0; - - if ( !FT_READ_USHORT( tag ) ) - { - if ( tag == 0x8001U || tag == 0x8002U ) - { - if ( !FT_READ_ULONG_LE( size ) ) - *asize = size; - } - - *atag = tag; - } - - return error; - } - - - static FT_Error - check_type1_format( FT_Stream stream, - const char* header_string, - size_t header_length ) - { - FT_Error error; - FT_UShort tag; - FT_ULong dummy; - - - if ( FT_STREAM_SEEK( 0 ) ) - goto Exit; - - error = read_pfb_tag( stream, &tag, &dummy ); - if ( error ) - goto Exit; - - /* We assume that the first segment in a PFB is always encoded as */ - /* text. This might be wrong (and the specification doesn't insist */ - /* on that), but we have never seen a counterexample. */ - if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) - goto Exit; - - if ( !FT_FRAME_ENTER( header_length ) ) - { - error = FT_Err_Ok; - - if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) - error = FT_THROW( Unknown_File_Format ); - - FT_FRAME_EXIT(); - } - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - T1_New_Parser( T1_Parser parser, - FT_Stream stream, - FT_Memory memory, - PSAux_Service psaux ) - { - FT_Error error; - FT_UShort tag; - FT_ULong size; - - - psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); - - parser->stream = stream; - parser->base_len = 0; - parser->base_dict = 0; - parser->private_len = 0; - parser->private_dict = 0; - parser->in_pfb = 0; - parser->in_memory = 0; - parser->single_block = 0; - - /* check the header format */ - error = check_type1_format( stream, "%!PS-AdobeFont", 14 ); - if ( error ) - { - if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) - goto Exit; - - error = check_type1_format( stream, "%!FontType", 10 ); - if ( error ) - { - FT_TRACE2(( " not a Type 1 font\n" )); - goto Exit; - } - } - - /******************************************************************/ - /* */ - /* Here a short summary of what is going on: */ - /* */ - /* When creating a new Type 1 parser, we try to locate and load */ - /* the base dictionary if this is possible (i.e., for PFB */ - /* files). Otherwise, we load the whole font into memory. */ - /* */ - /* When `loading' the base dictionary, we only setup pointers */ - /* in the case of a memory-based stream. Otherwise, we */ - /* allocate and load the base dictionary in it. */ - /* */ - /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ - /* parser->in_memory is set if we have a memory stream. */ - /* */ - - /* try to compute the size of the base dictionary; */ - /* look for a Postscript binary file tag, i.e., 0x8001 */ - if ( FT_STREAM_SEEK( 0L ) ) - goto Exit; - - error = read_pfb_tag( stream, &tag, &size ); - if ( error ) - goto Exit; - - if ( tag != 0x8001U ) - { - /* assume that this is a PFA file for now; an error will */ - /* be produced later when more things are checked */ - if ( FT_STREAM_SEEK( 0L ) ) - goto Exit; - size = stream->size; - } - else - parser->in_pfb = 1; - - /* now, try to load `size' bytes of the `base' dictionary we */ - /* found previously */ - - /* if it is a memory-based resource, set up pointers */ - if ( !stream->read ) - { - parser->base_dict = (FT_Byte*)stream->base + stream->pos; - parser->base_len = size; - parser->in_memory = 1; - - /* check that the `size' field is valid */ - if ( FT_STREAM_SKIP( size ) ) - goto Exit; - } - else - { - /* read segment in memory -- this is clumsy, but so does the format */ - if ( FT_ALLOC( parser->base_dict, size ) || - FT_STREAM_READ( parser->base_dict, size ) ) - goto Exit; - parser->base_len = size; - } - - parser->root.base = parser->base_dict; - parser->root.cursor = parser->base_dict; - parser->root.limit = parser->root.cursor + parser->base_len; - - Exit: - if ( error && !parser->in_memory ) - FT_FREE( parser->base_dict ); - - return error; - } - - - FT_LOCAL_DEF( void ) - T1_Finalize_Parser( T1_Parser parser ) - { - FT_Memory memory = parser->root.memory; - - - /* always free the private dictionary */ - FT_FREE( parser->private_dict ); - - /* free the base dictionary only when we have a disk stream */ - if ( !parser->in_memory ) - FT_FREE( parser->base_dict ); - - parser->root.funcs.done( &parser->root ); - } - - - FT_LOCAL_DEF( FT_Error ) - T1_Get_Private_Dict( T1_Parser parser, - PSAux_Service psaux ) - { - FT_Stream stream = parser->stream; - FT_Memory memory = parser->root.memory; - FT_Error error = FT_Err_Ok; - FT_ULong size; - - - if ( parser->in_pfb ) - { - /* in the case of the PFB format, the private dictionary can be */ - /* made of several segments. We thus first read the number of */ - /* segments to compute the total size of the private dictionary */ - /* then re-read them into memory. */ - FT_Long start_pos = FT_STREAM_POS(); - FT_UShort tag; - - - parser->private_len = 0; - for (;;) - { - error = read_pfb_tag( stream, &tag, &size ); - if ( error ) - goto Fail; - - if ( tag != 0x8002U ) - break; - - parser->private_len += size; - - if ( FT_STREAM_SKIP( size ) ) - goto Fail; - } - - /* Check that we have a private dictionary there */ - /* and allocate private dictionary buffer */ - if ( parser->private_len == 0 ) - { - FT_ERROR(( "T1_Get_Private_Dict:" - " invalid private dictionary section\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - if ( FT_STREAM_SEEK( start_pos ) || - FT_ALLOC( parser->private_dict, parser->private_len ) ) - goto Fail; - - parser->private_len = 0; - for (;;) - { - error = read_pfb_tag( stream, &tag, &size ); - if ( error || tag != 0x8002U ) - { - error = FT_Err_Ok; - break; - } - - if ( FT_STREAM_READ( parser->private_dict + parser->private_len, - size ) ) - goto Fail; - - parser->private_len += size; - } - } - else - { - /* We have already `loaded' the whole PFA font file into memory; */ - /* if this is a memory resource, allocate a new block to hold */ - /* the private dict. Otherwise, simply overwrite into the base */ - /* dictionary block in the heap. */ - - /* first of all, look at the `eexec' keyword */ - FT_Byte* cur = parser->base_dict; - FT_Byte* limit = cur + parser->base_len; - FT_Byte c; - - - Again: - for (;;) - { - c = cur[0]; - if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ - /* whitespace + 4 chars */ - { - if ( cur[1] == 'e' && - cur[2] == 'x' && - cur[3] == 'e' && - cur[4] == 'c' ) - break; - } - cur++; - if ( cur >= limit ) - { - FT_ERROR(( "T1_Get_Private_Dict:" - " could not find `eexec' keyword\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - } - - /* check whether `eexec' was real -- it could be in a comment */ - /* or string (as e.g. in u003043t.gsf from ghostscript) */ - - parser->root.cursor = parser->base_dict; - /* set limit to `eexec' + whitespace + 4 characters */ - parser->root.limit = cur + 10; - - cur = parser->root.cursor; - limit = parser->root.limit; - - while ( cur < limit ) - { - if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) - goto Found; - - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - break; - T1_Skip_Spaces ( parser ); - cur = parser->root.cursor; - } - - /* we haven't found the correct `eexec'; go back and continue */ - /* searching */ - - cur = limit; - limit = parser->base_dict + parser->base_len; - goto Again; - - /* now determine where to write the _encrypted_ binary private */ - /* dictionary. We overwrite the base dictionary for disk-based */ - /* resources and allocate a new block otherwise */ - - Found: - parser->root.limit = parser->base_dict + parser->base_len; - - T1_Skip_PS_Token( parser ); - cur = parser->root.cursor; - limit = parser->root.limit; - - /* according to the Type1 spec, the first cipher byte must not be */ - /* an ASCII whitespace character code (blank, tab, carriage return */ - /* or line feed). We have seen Type 1 fonts with two line feed */ - /* characters... So skip now all whitespace character codes. */ - while ( cur < limit && - ( *cur == ' ' || - *cur == '\t' || - *cur == '\r' || - *cur == '\n' ) ) - ++cur; - if ( cur >= limit ) - { - FT_ERROR(( "T1_Get_Private_Dict:" - " `eexec' not properly terminated\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - size = (FT_ULong)( parser->base_len - ( cur - parser->base_dict ) ); - - if ( parser->in_memory ) - { - /* note that we allocate one more byte to put a terminating `0' */ - if ( FT_ALLOC( parser->private_dict, size + 1 ) ) - goto Fail; - parser->private_len = size; - } - else - { - parser->single_block = 1; - parser->private_dict = parser->base_dict; - parser->private_len = size; - parser->base_dict = 0; - parser->base_len = 0; - } - - /* now determine whether the private dictionary is encoded in binary */ - /* or hexadecimal ASCII format -- decode it accordingly */ - - /* we need to access the next 4 bytes (after the final whitespace */ - /* following the `eexec' keyword); if they all are hexadecimal */ - /* digits, then we have a case of ASCII storage */ - - if ( cur + 3 < limit && - ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && - ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) - { - /* ASCII hexadecimal encoding */ - FT_Long len; - - - parser->root.cursor = cur; - (void)psaux->ps_parser_funcs->to_bytes( &parser->root, - parser->private_dict, - parser->private_len, - &len, - 0 ); - parser->private_len = len; - - /* put a safeguard */ - parser->private_dict[len] = '\0'; - } - else - /* binary encoding -- copy the private dict */ - FT_MEM_MOVE( parser->private_dict, cur, size ); - } - - /* we now decrypt the encoded binary private dictionary */ - psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U ); - - if ( parser->private_len < 4 ) - { - FT_ERROR(( "T1_Get_Private_Dict:" - " invalid private dictionary section\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* replace the four random bytes at the beginning with whitespace */ - parser->private_dict[0] = ' '; - parser->private_dict[1] = ' '; - parser->private_dict[2] = ' '; - parser->private_dict[3] = ' '; - - parser->root.base = parser->private_dict; - parser->root.cursor = parser->private_dict; - parser->root.limit = parser->root.cursor + parser->private_len; - - Fail: - Exit: - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1parse.h b/drivers/freetype/freetype/src/type1/t1parse.h deleted file mode 100644 index fb1c8a8830..0000000000 --- a/drivers/freetype/freetype/src/type1/t1parse.h +++ /dev/null @@ -1,135 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1parse.h */ -/* */ -/* Type 1 parser (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2008 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 __T1PARSE_H__ -#define __T1PARSE_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_TYPE1_TYPES_H -#include FT_INTERNAL_STREAM_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* T1_ParserRec */ - /* */ - /* <Description> */ - /* A PS_ParserRec is an object used to parse a Type 1 fonts very */ - /* quickly. */ - /* */ - /* <Fields> */ - /* root :: The root parser. */ - /* */ - /* stream :: The current input stream. */ - /* */ - /* base_dict :: A pointer to the top-level dictionary. */ - /* */ - /* base_len :: The length in bytes of the top dictionary. */ - /* */ - /* private_dict :: A pointer to the private dictionary. */ - /* */ - /* private_len :: The length in bytes of the private dictionary. */ - /* */ - /* in_pfb :: A boolean. Indicates that we are handling a PFB */ - /* file. */ - /* */ - /* in_memory :: A boolean. Indicates a memory-based stream. */ - /* */ - /* single_block :: A boolean. Indicates that the private dictionary */ - /* is stored in lieu of the base dictionary. */ - /* */ - typedef struct T1_ParserRec_ - { - PS_ParserRec root; - FT_Stream stream; - - FT_Byte* base_dict; - FT_ULong base_len; - - FT_Byte* private_dict; - FT_ULong private_len; - - FT_Bool in_pfb; - FT_Bool in_memory; - FT_Bool single_block; - - } T1_ParserRec, *T1_Parser; - - -#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) -#define T1_Done_Table( p ) \ - do \ - { \ - if ( (p)->funcs.done ) \ - (p)->funcs.done( p ); \ - } while ( 0 ) -#define T1_Release_Table( p ) \ - do \ - { \ - if ( (p)->funcs.release ) \ - (p)->funcs.release( p ); \ - } while ( 0 ) - - -#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) -#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root ) - -#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root ) -#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) - -#define T1_ToCoordArray( p, m, c ) \ - (p)->root.funcs.to_coord_array( &(p)->root, m, c ) -#define T1_ToFixedArray( p, m, f, t ) \ - (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) -#define T1_ToToken( p, t ) \ - (p)->root.funcs.to_token( &(p)->root, t ) -#define T1_ToTokenArray( p, t, m, c ) \ - (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) - -#define T1_Load_Field( p, f, o, m, pf ) \ - (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) - -#define T1_Load_Field_Table( p, f, o, m, pf ) \ - (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) - - - FT_LOCAL( FT_Error ) - T1_New_Parser( T1_Parser parser, - FT_Stream stream, - FT_Memory memory, - PSAux_Service psaux ); - - FT_LOCAL( FT_Error ) - T1_Get_Private_Dict( T1_Parser parser, - PSAux_Service psaux ); - - FT_LOCAL( void ) - T1_Finalize_Parser( T1_Parser parser ); - - -FT_END_HEADER - -#endif /* __T1PARSE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/t1tokens.h b/drivers/freetype/freetype/src/type1/t1tokens.h deleted file mode 100644 index e37276b908..0000000000 --- a/drivers/freetype/freetype/src/type1/t1tokens.h +++ /dev/null @@ -1,143 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1tokens.h */ -/* */ -/* Type 1 tokenizer (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 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. */ -/* */ -/***************************************************************************/ - - -#undef FT_STRUCTURE -#define FT_STRUCTURE PS_FontInfoRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_INFO - - T1_FIELD_STRING( "version", version, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_STRING( "Notice", notice, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_STRING( "FullName", full_name, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_STRING( "FamilyName", family_name, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_STRING( "Weight", weight, - T1_FIELD_DICT_FONTDICT ) - - /* we use pointers to detect modifications made by synthetic fonts */ - T1_FIELD_NUM ( "ItalicAngle", italic_angle, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_NUM ( "UnderlinePosition", underline_position, - T1_FIELD_DICT_FONTDICT ) - T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, - T1_FIELD_DICT_FONTDICT ) - -#undef FT_STRUCTURE -#define FT_STRUCTURE PS_FontExtraRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA - - T1_FIELD_NUM ( "FSType", fs_type, - T1_FIELD_DICT_FONTDICT ) - -#undef FT_STRUCTURE -#define FT_STRUCTURE PS_PrivateRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_PRIVATE - - T1_FIELD_NUM ( "UniqueID", unique_id, - T1_FIELD_DICT_FONTDICT | T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM ( "lenIV", lenIV, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM ( "LanguageGroup", language_group, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM ( "password", password, - T1_FIELD_DICT_PRIVATE ) - - T1_FIELD_FIXED_1000( "BlueScale", blue_scale, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM ( "BlueShift", blue_shift, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, - T1_FIELD_DICT_PRIVATE ) - - T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, - T1_FIELD_DICT_PRIVATE ) - - T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, - T1_FIELD_DICT_PRIVATE ) - - T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, - T1_FIELD_DICT_PRIVATE ) - - T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor, - T1_FIELD_DICT_PRIVATE ) - T1_FIELD_BOOL ( "ForceBold", force_bold, - T1_FIELD_DICT_PRIVATE ) - - -#undef FT_STRUCTURE -#define FT_STRUCTURE T1_FontRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_DICT - - T1_FIELD_KEY ( "FontName", font_name, T1_FIELD_DICT_FONTDICT ) - T1_FIELD_NUM ( "PaintType", paint_type, T1_FIELD_DICT_FONTDICT ) - T1_FIELD_NUM ( "FontType", font_type, T1_FIELD_DICT_FONTDICT ) - T1_FIELD_FIXED( "StrokeWidth", stroke_width, T1_FIELD_DICT_FONTDICT ) - - -#undef FT_STRUCTURE -#define FT_STRUCTURE FT_BBox -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_BBOX - - T1_FIELD_BBOX( "FontBBox", xMin, T1_FIELD_DICT_FONTDICT ) - - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - -#undef FT_STRUCTURE -#define FT_STRUCTURE T1_FaceRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FACE - - T1_FIELD_NUM( "NDV", ndv_idx, T1_FIELD_DICT_PRIVATE ) - T1_FIELD_NUM( "CDV", cdv_idx, T1_FIELD_DICT_PRIVATE ) - - -#undef FT_STRUCTURE -#define FT_STRUCTURE PS_BlendRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_BLEND - - T1_FIELD_NUM_TABLE( "DesignVector", default_design_vector, - T1_MAX_MM_DESIGNS, T1_FIELD_DICT_FONTDICT ) - - -#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type1/type1.c b/drivers/freetype/freetype/src/type1/type1.c deleted file mode 100644 index ccc12be103..0000000000 --- a/drivers/freetype/freetype/src/type1/type1.c +++ /dev/null @@ -1,33 +0,0 @@ -/***************************************************************************/ -/* */ -/* type1.c */ -/* */ -/* FreeType Type 1 driver component (body only). */ -/* */ -/* Copyright 1996-2001 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "t1parse.c" -#include "t1load.c" -#include "t1objs.c" -#include "t1driver.c" -#include "t1gload.c" - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include "t1afm.c" -#endif - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/Jamfile b/drivers/freetype/freetype/src/type42/Jamfile deleted file mode 100644 index 00371d54f3..0000000000 --- a/drivers/freetype/freetype/src/type42/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/type42 Jamfile -# -# Copyright 2002 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) type42 ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = t42objs t42parse t42drivr ; - } - else - { - _sources = type42 ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/type42 Jamfile diff --git a/drivers/freetype/freetype/src/type42/module.mk b/drivers/freetype/freetype/src/type42/module.mk deleted file mode 100644 index b3f10a8d3c..0000000000 --- a/drivers/freetype/freetype/src/type42/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 Type42 module definition -# - - -# Copyright 2002, 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. - - -FTMODULE_H_COMMANDS += TYPE42_DRIVER - -define TYPE42_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, t42_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)type42 $(ECHO_DRIVER_DESC)Type 42 font files with no known extension$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/type42/rules.mk b/drivers/freetype/freetype/src/type42/rules.mk deleted file mode 100644 index eac1081eb1..0000000000 --- a/drivers/freetype/freetype/src/type42/rules.mk +++ /dev/null @@ -1,70 +0,0 @@ -# -# FreeType 2 Type42 driver configuration rules -# - - -# Copyright 2002, 2003, 2008 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. - - -# Type42 driver directory -# -T42_DIR := $(SRC_DIR)/type42 - - -# compilation flags for the driver -# -T42_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T42_DIR)) - - -# Type42 driver source -# -T42_DRV_SRC := $(T42_DIR)/t42objs.c \ - $(T42_DIR)/t42parse.c \ - $(T42_DIR)/t42drivr.c - -# Type42 driver headers -# -T42_DRV_H := $(T42_DRV_SRC:%.c=%.h) \ - $(T42_DIR)/t42error.h \ - $(T42_DIR)/t42types.h - - -# Type42 driver object(s) -# -# T42_DRV_OBJ_M is used during `multi' builds -# T42_DRV_OBJ_S is used during `single' builds -# -T42_DRV_OBJ_M := $(T42_DRV_SRC:$(T42_DIR)/%.c=$(OBJ_DIR)/%.$O) -T42_DRV_OBJ_S := $(OBJ_DIR)/type42.$O - -# Type42 driver source file for single build -# -T42_DRV_SRC_S := $(T42_DIR)/type42.c - - -# Type42 driver - single object -# -$(T42_DRV_OBJ_S): $(T42_DRV_SRC_S) $(T42_DRV_SRC) $(FREETYPE_H) $(T42_DRV_H) - $(T42_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(T42_DRV_SRC_S)) - - -# Type42 driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(T42_DIR)/%.c $(FREETYPE_H) $(T42_DRV_H) - $(T42_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(T42_DRV_OBJ_S) -DRV_OBJS_M += $(T42_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/type42/t42drivr.c b/drivers/freetype/freetype/src/type42/t42drivr.c deleted file mode 100644 index 3ad1bde79f..0000000000 --- a/drivers/freetype/freetype/src/type42/t42drivr.c +++ /dev/null @@ -1,244 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42drivr.c */ -/* */ -/* High-level Type 42 driver interface (body). */ -/* */ -/* Copyright 2002-2004, 2006, 2007, 2009, 2011, 2013 by */ -/* Roberto Alameda. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This driver implements Type42 fonts as described in the */ - /* Technical Note #5012 from Adobe, with these limitations: */ - /* */ - /* 1) CID Fonts are not currently supported. */ - /* 2) Incremental fonts making use of the GlyphDirectory keyword */ - /* will be loaded, but the rendering will be using the TrueType */ - /* tables. */ - /* 3) As for Type1 fonts, CDevProc is not supported. */ - /* 4) The Metrics dictionary is not supported. */ - /* 5) AFM metrics are not supported. */ - /* */ - /* In other words, this driver supports Type42 fonts derived from */ - /* TrueType fonts in a non-CID manner, as done by usual conversion */ - /* programs. */ - /* */ - /*************************************************************************/ - - -#include "t42drivr.h" -#include "t42objs.h" -#include "t42error.h" -#include FT_INTERNAL_DEBUG_H - -#include FT_SERVICE_XFREE86_NAME_H -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_POSTSCRIPT_INFO_H - -#undef FT_COMPONENT -#define FT_COMPONENT trace_t42 - - - /* - * - * GLYPH DICT SERVICE - * - */ - - static FT_Error - t42_get_glyph_name( T42_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); - - return FT_Err_Ok; - } - - - static FT_UInt - t42_get_name_index( T42_Face face, - FT_String* glyph_name ) - { - FT_Int i; - - - for ( i = 0; i < face->type1.num_glyphs; i++ ) - { - FT_String* gname = face->type1.glyph_names[i]; - - - if ( glyph_name[0] == gname[0] && !ft_strcmp( glyph_name, gname ) ) - return (FT_UInt)ft_atol( (const char *)face->type1.charstrings[i] ); - } - - return 0; - } - - - static const FT_Service_GlyphDictRec t42_service_glyph_dict = - { - (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t42_get_name_index - }; - - - /* - * - * POSTSCRIPT NAME SERVICE - * - */ - - static const char* - t42_get_ps_font_name( T42_Face face ) - { - return (const char*)face->type1.font_name; - } - - - static const FT_Service_PsFontNameRec t42_service_ps_font_name = - { - (FT_PsName_GetFunc)t42_get_ps_font_name - }; - - - /* - * - * POSTSCRIPT INFO SERVICE - * - */ - - static FT_Error - t42_ps_get_font_info( FT_Face face, - PS_FontInfoRec* afont_info ) - { - *afont_info = ((T42_Face)face)->type1.font_info; - - return FT_Err_Ok; - } - - - static FT_Error - t42_ps_get_font_extra( FT_Face face, - PS_FontExtraRec* afont_extra ) - { - *afont_extra = ((T42_Face)face)->type1.font_extra; - - return FT_Err_Ok; - } - - - static FT_Int - t42_ps_has_glyph_names( FT_Face face ) - { - FT_UNUSED( face ); - - return 1; - } - - - static FT_Error - t42_ps_get_font_private( FT_Face face, - PS_PrivateRec* afont_private ) - { - *afont_private = ((T42_Face)face)->type1.private_dict; - - return FT_Err_Ok; - } - - - static const FT_Service_PsInfoRec t42_service_ps_info = - { - (PS_GetFontInfoFunc) t42_ps_get_font_info, - (PS_GetFontExtraFunc) t42_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t42_ps_get_font_private, - (PS_GetFontValueFunc) NULL /* not implemented */ - }; - - - /* - * - * SERVICE LIST - * - */ - - static const FT_ServiceDescRec t42_services[] = - { - { FT_SERVICE_ID_GLYPH_DICT, &t42_service_glyph_dict }, - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t42_service_ps_font_name }, - { FT_SERVICE_ID_POSTSCRIPT_INFO, &t42_service_ps_info }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_42 }, - { NULL, NULL } - }; - - - FT_CALLBACK_DEF( FT_Module_Interface ) - T42_Get_Interface( FT_Module module, - const FT_String* t42_interface ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( t42_services, t42_interface ); - } - - - const FT_Driver_ClassRec t42_driver_class = - { - { - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | -#ifdef TT_USE_BYTECODE_INTERPRETER - FT_MODULE_DRIVER_HAS_HINTER, -#else - 0, -#endif - - sizeof ( T42_DriverRec ), - - "type42", - 0x10000L, - 0x20000L, - - 0, /* format interface */ - - T42_Driver_Init, - T42_Driver_Done, - T42_Get_Interface, - }, - - sizeof ( T42_FaceRec ), - sizeof ( T42_SizeRec ), - sizeof ( T42_GlyphSlotRec ), - - T42_Face_Init, - T42_Face_Done, - T42_Size_Init, - T42_Size_Done, - T42_GlyphSlot_Init, - T42_GlyphSlot_Done, - - T42_GlyphSlot_Load, - - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - - 0, /* FT_Face_GetAdvancesFunc */ - T42_Size_Request, - T42_Size_Select - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/t42drivr.h b/drivers/freetype/freetype/src/type42/t42drivr.h deleted file mode 100644 index 9a1e97e30e..0000000000 --- a/drivers/freetype/freetype/src/type42/t42drivr.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42drivr.h */ -/* */ -/* High-level Type 42 driver interface (specification). */ -/* */ -/* Copyright 2002 by Roberto Alameda. */ -/* */ -/* 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 __T42DRIVR_H__ -#define __T42DRIVR_H__ - - -#include <ft2build.h> -#include FT_INTERNAL_DRIVER_H - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) t42_driver_class; - - -FT_END_HEADER - - -#endif /* __T42DRIVR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/t42error.h b/drivers/freetype/freetype/src/type42/t42error.h deleted file mode 100644 index 217ae8bd52..0000000000 --- a/drivers/freetype/freetype/src/type42/t42error.h +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42error.h */ -/* */ -/* Type 42 error codes (specification only). */ -/* */ -/* Copyright 2002, 2003, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the Type 42 error enumeration constants. */ - /* */ - /*************************************************************************/ - -#ifndef __T42ERROR_H__ -#define __T42ERROR_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX T42_Err_ -#define FT_ERR_BASE FT_Mod_Err_Type42 - -#include FT_ERRORS_H - -#endif /* __T42ERROR_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/t42objs.c b/drivers/freetype/freetype/src/type42/t42objs.c deleted file mode 100644 index 18e2c0b625..0000000000 --- a/drivers/freetype/freetype/src/type42/t42objs.c +++ /dev/null @@ -1,682 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42objs.c */ -/* */ -/* Type 42 objects manager (body). */ -/* */ -/* Copyright 2002-2009, 2011, 2013 */ -/* by Roberto Alameda. */ -/* */ -/* 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 "t42objs.h" -#include "t42parse.h" -#include "t42error.h" -#include FT_INTERNAL_DEBUG_H -#include FT_LIST_H -#include FT_TRUETYPE_IDS_H - - -#undef FT_COMPONENT -#define FT_COMPONENT trace_t42 - - - static FT_Error - T42_Open_Face( T42_Face face ) - { - T42_LoaderRec loader; - T42_Parser parser; - T1_Font type1 = &face->type1; - FT_Memory memory = face->root.memory; - FT_Error error; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - t42_loader_init( &loader, face ); - - parser = &loader.parser; - - if ( FT_ALLOC( face->ttf_data, 12 ) ) - goto Exit; - - error = t42_parser_init( parser, - face->root.stream, - memory, - psaux); - if ( error ) - goto Exit; - - error = t42_parse_dict( face, &loader, - parser->base_dict, parser->base_len ); - if ( error ) - goto Exit; - - if ( type1->font_type != 42 ) - { - FT_ERROR(( "T42_Open_Face: cannot handle FontType %d\n", - type1->font_type )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - /* now, propagate the charstrings and glyphnames tables */ - /* to the Type1 data */ - type1->num_glyphs = loader.num_glyphs; - - if ( !loader.charstrings.init ) - { - FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" )); - error = FT_THROW( Invalid_File_Format ); - } - - loader.charstrings.init = 0; - type1->charstrings_block = loader.charstrings.block; - type1->charstrings = loader.charstrings.elements; - type1->charstrings_len = loader.charstrings.lengths; - - /* we copy the glyph names `block' and `elements' fields; */ - /* the `lengths' field must be released later */ - type1->glyph_names_block = loader.glyph_names.block; - type1->glyph_names = (FT_String**)loader.glyph_names.elements; - loader.glyph_names.block = 0; - loader.glyph_names.elements = 0; - - /* we must now build type1.encoding when we have a custom array */ - if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) - { - FT_Int charcode, idx, min_char, max_char; - FT_Byte* glyph_name; - - - /* OK, we do the following: for each element in the encoding */ - /* table, look up the index of the glyph having the same name */ - /* as defined in the CharStrings array. */ - /* The index is then stored in type1.encoding.char_index, and */ - /* the name in type1.encoding.char_name */ - - min_char = 0; - max_char = 0; - - charcode = 0; - for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) - { - FT_Byte* char_name; - - - type1->encoding.char_index[charcode] = 0; - type1->encoding.char_name [charcode] = (char *)".notdef"; - - char_name = loader.encoding_table.elements[charcode]; - if ( char_name ) - for ( idx = 0; idx < type1->num_glyphs; idx++ ) - { - glyph_name = (FT_Byte*)type1->glyph_names[idx]; - if ( ft_strcmp( (const char*)char_name, - (const char*)glyph_name ) == 0 ) - { - type1->encoding.char_index[charcode] = (FT_UShort)idx; - type1->encoding.char_name [charcode] = (char*)glyph_name; - - /* Change min/max encoded char only if glyph name is */ - /* not /.notdef */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)glyph_name ) != 0 ) - { - if ( charcode < min_char ) - min_char = charcode; - if ( charcode >= max_char ) - max_char = charcode + 1; - } - break; - } - } - } - - type1->encoding.code_first = min_char; - type1->encoding.code_last = max_char; - type1->encoding.num_chars = loader.num_chars; - } - - Exit: - t42_loader_done( &loader ); - return error; - } - - - /***************** Driver Functions *************/ - - - FT_LOCAL_DEF( FT_Error ) - T42_Face_Init( FT_Stream stream, - FT_Face t42face, /* T42_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - T42_Face face = (T42_Face)t42face; - FT_Error error; - FT_Service_PsCMaps psnames; - PSAux_Service psaux; - FT_Face root = (FT_Face)&face->root; - T1_Font type1 = &face->type1; - PS_FontInfo info = &type1->font_info; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - FT_UNUSED( stream ); - - - face->ttf_face = NULL; - face->root.num_faces = 1; - - FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); - face->psnames = psnames; - - face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), - "psaux" ); - psaux = (PSAux_Service)face->psaux; - if ( !psaux ) - { - FT_ERROR(( "T42_Face_Init: cannot access `psaux' module\n" )); - error = FT_THROW( Missing_Module ); - goto Exit; - } - - FT_TRACE2(( "Type 42 driver\n" )); - - /* open the tokenizer, this will also check the font format */ - error = T42_Open_Face( face ); - if ( error ) - goto Exit; - - /* if we just wanted to check the format, leave successfully now */ - if ( face_index < 0 ) - goto Exit; - - /* check the face index */ - if ( face_index > 0 ) - { - FT_ERROR(( "T42_Face_Init: invalid face index\n" )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - /* Now load the font program into the face object */ - - /* Init the face object fields */ - /* Now set up root face fields */ - - root->num_glyphs = type1->num_glyphs; - root->num_charmaps = 0; - root->face_index = 0; - - root->face_flags = FT_FACE_FLAG_SCALABLE | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_GLYPH_NAMES; - - if ( info->is_fixed_pitch ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* We only set this flag if we have the patented bytecode interpreter. */ - /* There are no known `tricky' Type42 fonts that could be loaded with */ - /* the unpatented interpreter. */ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - root->face_flags |= FT_FACE_FLAG_HINTER; -#endif - - /* XXX: TODO -- add kerning with .afm support */ - - /* get style name -- be careful, some broken fonts only */ - /* have a `/FontName' dictionary entry! */ - root->family_name = info->family_name; - /* assume "Regular" style if we don't know better */ - root->style_name = (char *)"Regular"; - if ( root->family_name ) - { - char* full = info->full_name; - char* family = root->family_name; - - - if ( full ) - { - while ( *full ) - { - if ( *full == *family ) - { - family++; - full++; - } - else - { - if ( *full == ' ' || *full == '-' ) - full++; - else if ( *family == ' ' || *family == '-' ) - family++; - else - { - if ( !*family ) - root->style_name = full; - break; - } - } - } - } - } - else - { - /* do we have a `/FontName'? */ - if ( type1->font_name ) - root->family_name = type1->font_name; - } - - /* no embedded bitmap support */ - root->num_fixed_sizes = 0; - root->available_sizes = 0; - - /* Load the TTF font embedded in the T42 font */ - { - FT_Open_Args args; - - - args.flags = FT_OPEN_MEMORY; - args.memory_base = face->ttf_data; - args.memory_size = face->ttf_size; - - if ( num_params ) - { - args.flags |= FT_OPEN_PARAMS; - args.num_params = num_params; - args.params = params; - } - - error = FT_Open_Face( FT_FACE_LIBRARY( face ), - &args, 0, &face->ttf_face ); - } - - if ( error ) - goto Exit; - - FT_Done_Size( face->ttf_face->size ); - - /* Ignore info in FontInfo dictionary and use the info from the */ - /* loaded TTF font. The PostScript interpreter also ignores it. */ - root->bbox = face->ttf_face->bbox; - root->units_per_EM = face->ttf_face->units_per_EM; - - root->ascender = face->ttf_face->ascender; - root->descender = face->ttf_face->descender; - root->height = face->ttf_face->height; - - root->max_advance_width = face->ttf_face->max_advance_width; - root->max_advance_height = face->ttf_face->max_advance_height; - - root->underline_position = (FT_Short)info->underline_position; - root->underline_thickness = (FT_Short)info->underline_thickness; - - /* compute style flags */ - root->style_flags = 0; - if ( info->italic_angle ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - - if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - - if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) - root->face_flags |= FT_FACE_FLAG_VERTICAL; - - { - if ( psnames ) - { - FT_CharMapRec charmap; - T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; - FT_CMap_Class clazz; - - - charmap.face = root; - - /* first of all, try to synthesize a Unicode charmap */ - charmap.platform_id = TT_PLATFORM_MICROSOFT; - charmap.encoding_id = TT_MS_ID_UNICODE_CS; - charmap.encoding = FT_ENCODING_UNICODE; - - error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); - if ( error && - FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) - goto Exit; - error = FT_Err_Ok; - - /* now, generate an Adobe Standard encoding when appropriate */ - charmap.platform_id = TT_PLATFORM_ADOBE; - clazz = NULL; - - switch ( type1->encoding_type ) - { - case T1_ENCODING_TYPE_STANDARD: - charmap.encoding = FT_ENCODING_ADOBE_STANDARD; - charmap.encoding_id = TT_ADOBE_ID_STANDARD; - clazz = cmap_classes->standard; - break; - - case T1_ENCODING_TYPE_EXPERT: - charmap.encoding = FT_ENCODING_ADOBE_EXPERT; - charmap.encoding_id = TT_ADOBE_ID_EXPERT; - clazz = cmap_classes->expert; - break; - - case T1_ENCODING_TYPE_ARRAY: - charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; - charmap.encoding_id = TT_ADOBE_ID_CUSTOM; - clazz = cmap_classes->custom; - break; - - case T1_ENCODING_TYPE_ISOLATIN1: - charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; - charmap.encoding_id = TT_ADOBE_ID_LATIN_1; - clazz = cmap_classes->unicode; - break; - - default: - ; - } - - if ( clazz ) - error = FT_CMap_New( clazz, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( root->num_charmaps ) - root->charmap = root->charmaps[0]; -#endif - } - } - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - T42_Face_Done( FT_Face t42face ) - { - T42_Face face = (T42_Face)t42face; - T1_Font type1; - PS_FontInfo info; - FT_Memory memory; - - - if ( !face ) - return; - - type1 = &face->type1; - info = &type1->font_info; - memory = face->root.memory; - - /* delete internal ttf face prior to freeing face->ttf_data */ - if ( face->ttf_face ) - FT_Done_Face( face->ttf_face ); - - /* release font info strings */ - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); - - /* release top dictionary */ - FT_FREE( type1->charstrings_len ); - FT_FREE( type1->charstrings ); - FT_FREE( type1->glyph_names ); - - FT_FREE( type1->charstrings_block ); - FT_FREE( type1->glyph_names_block ); - - FT_FREE( type1->encoding.char_index ); - FT_FREE( type1->encoding.char_name ); - FT_FREE( type1->font_name ); - - FT_FREE( face->ttf_data ); - -#if 0 - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); -#endif - - /* release unicode map, if any */ - FT_FREE( face->unicode_map.maps ); - face->unicode_map.num_maps = 0; - - face->root.family_name = 0; - face->root.style_name = 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* T42_Driver_Init */ - /* */ - /* <Description> */ - /* Initializes a given Type 42 driver object. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target driver object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - T42_Driver_Init( FT_Module module ) /* T42_Driver */ - { - T42_Driver driver = (T42_Driver)module; - FT_Module ttmodule; - - - ttmodule = FT_Get_Module( module->library, "truetype" ); - if ( !ttmodule ) - { - FT_ERROR(( "T42_Driver_Init: cannot access `truetype' module\n" )); - return FT_THROW( Missing_Module ); - } - - driver->ttclazz = (FT_Driver_Class)ttmodule->clazz; - - return FT_Err_Ok; - } - - - FT_LOCAL_DEF( void ) - T42_Driver_Done( FT_Module module ) - { - FT_UNUSED( module ); - } - - - FT_LOCAL_DEF( FT_Error ) - T42_Size_Init( FT_Size size ) /* T42_Size */ - { - T42_Size t42size = (T42_Size)size; - FT_Face face = size->face; - T42_Face t42face = (T42_Face)face; - FT_Size ttsize; - FT_Error error = FT_Err_Ok; - - - error = FT_New_Size( t42face->ttf_face, &ttsize ); - t42size->ttsize = ttsize; - - FT_Activate_Size( ttsize ); - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - T42_Size_Request( FT_Size t42size, /* T42_Size */ - FT_Size_Request req ) - { - T42_Size size = (T42_Size)t42size; - T42_Face face = (T42_Face)t42size->face; - FT_Error error; - - - FT_Activate_Size( size->ttsize ); - - error = FT_Request_Size( face->ttf_face, req ); - if ( !error ) - t42size->metrics = face->ttf_face->size->metrics; - - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - T42_Size_Select( FT_Size t42size, /* T42_Size */ - FT_ULong strike_index ) - { - T42_Size size = (T42_Size)t42size; - T42_Face face = (T42_Face)t42size->face; - FT_Error error; - - - FT_Activate_Size( size->ttsize ); - - error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index ); - if ( !error ) - t42size->metrics = face->ttf_face->size->metrics; - - return error; - - } - - - FT_LOCAL_DEF( void ) - T42_Size_Done( FT_Size t42size ) /* T42_Size */ - { - T42_Size size = (T42_Size)t42size; - FT_Face face = t42size->face; - T42_Face t42face = (T42_Face)face; - FT_ListNode node; - - - node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize ); - if ( node ) - { - FT_Done_Size( size->ttsize ); - size->ttsize = NULL; - } - } - - - FT_LOCAL_DEF( FT_Error ) - T42_GlyphSlot_Init( FT_GlyphSlot t42slot ) /* T42_GlyphSlot */ - { - T42_GlyphSlot slot = (T42_GlyphSlot)t42slot; - FT_Face face = t42slot->face; - T42_Face t42face = (T42_Face)face; - FT_GlyphSlot ttslot; - FT_Error error = FT_Err_Ok; - - - if ( face->glyph == NULL ) - { - /* First glyph slot for this face */ - slot->ttslot = t42face->ttf_face->glyph; - } - else - { - error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot ); - slot->ttslot = ttslot; - } - - return error; - } - - - FT_LOCAL_DEF( void ) - T42_GlyphSlot_Done( FT_GlyphSlot t42slot ) /* T42_GlyphSlot */ - { - T42_GlyphSlot slot = (T42_GlyphSlot)t42slot; - - - FT_Done_GlyphSlot( slot->ttslot ); - } - - - static void - t42_glyphslot_clear( FT_GlyphSlot slot ) - { - /* free bitmap if needed */ - ft_glyphslot_free_bitmap( slot ); - - /* clear all public fields in the glyph slot */ - FT_ZERO( &slot->metrics ); - FT_ZERO( &slot->outline ); - FT_ZERO( &slot->bitmap ); - - slot->bitmap_left = 0; - slot->bitmap_top = 0; - slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; - slot->control_len = 0; - slot->other = 0; - slot->format = FT_GLYPH_FORMAT_NONE; - - slot->linearHoriAdvance = 0; - slot->linearVertAdvance = 0; - } - - - FT_LOCAL_DEF( FT_Error ) - T42_GlyphSlot_Load( FT_GlyphSlot glyph, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - FT_Error error; - T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph; - T42_Size t42size = (T42_Size)size; - FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; - - - t42_glyphslot_clear( t42slot->ttslot ); - error = ttclazz->load_glyph( t42slot->ttslot, - t42size->ttsize, - glyph_index, - load_flags | FT_LOAD_NO_BITMAP ); - - if ( !error ) - { - glyph->metrics = t42slot->ttslot->metrics; - - glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance; - glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance; - - glyph->format = t42slot->ttslot->format; - glyph->outline = t42slot->ttslot->outline; - - glyph->bitmap = t42slot->ttslot->bitmap; - glyph->bitmap_left = t42slot->ttslot->bitmap_left; - glyph->bitmap_top = t42slot->ttslot->bitmap_top; - - glyph->num_subglyphs = t42slot->ttslot->num_subglyphs; - glyph->subglyphs = t42slot->ttslot->subglyphs; - - glyph->control_data = t42slot->ttslot->control_data; - glyph->control_len = t42slot->ttslot->control_len; - } - - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/t42objs.h b/drivers/freetype/freetype/src/type42/t42objs.h deleted file mode 100644 index 02d13259be..0000000000 --- a/drivers/freetype/freetype/src/type42/t42objs.h +++ /dev/null @@ -1,124 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42objs.h */ -/* */ -/* Type 42 objects manager (specification). */ -/* */ -/* Copyright 2002, 2003, 2006, 2007, 2011 by Roberto Alameda. */ -/* */ -/* 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 __T42OBJS_H__ -#define __T42OBJS_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_TYPE1_TABLES_H -#include FT_INTERNAL_TYPE1_TYPES_H -#include "t42types.h" -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DRIVER_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H - - -FT_BEGIN_HEADER - - - /* Type42 size */ - typedef struct T42_SizeRec_ - { - FT_SizeRec root; - FT_Size ttsize; - - } T42_SizeRec, *T42_Size; - - - /* Type42 slot */ - typedef struct T42_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - FT_GlyphSlot ttslot; - - } T42_GlyphSlotRec, *T42_GlyphSlot; - - - /* Type 42 driver */ - typedef struct T42_DriverRec_ - { - FT_DriverRec root; - FT_Driver_Class ttclazz; - void* extension_component; - - } T42_DriverRec, *T42_Driver; - - - /* */ - - - FT_LOCAL( FT_Error ) - T42_Face_Init( FT_Stream stream, - FT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - - FT_LOCAL( void ) - T42_Face_Done( FT_Face face ); - - - FT_LOCAL( FT_Error ) - T42_Size_Init( FT_Size size ); - - - FT_LOCAL( FT_Error ) - T42_Size_Request( FT_Size size, - FT_Size_Request req ); - - - FT_LOCAL( FT_Error ) - T42_Size_Select( FT_Size size, - FT_ULong strike_index ); - - - FT_LOCAL( void ) - T42_Size_Done( FT_Size size ); - - - FT_LOCAL( FT_Error ) - T42_GlyphSlot_Init( FT_GlyphSlot slot ); - - - FT_LOCAL( FT_Error ) - T42_GlyphSlot_Load( FT_GlyphSlot glyph, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ); - - FT_LOCAL( void ) - T42_GlyphSlot_Done( FT_GlyphSlot slot ); - - - FT_LOCAL( FT_Error ) - T42_Driver_Init( FT_Module module ); - - FT_LOCAL( void ) - T42_Driver_Done( FT_Module module ); - - /* */ - -FT_END_HEADER - - -#endif /* __T42OBJS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/t42parse.c b/drivers/freetype/freetype/src/type42/t42parse.c deleted file mode 100644 index 3cdd8a1acf..0000000000 --- a/drivers/freetype/freetype/src/type42/t42parse.c +++ /dev/null @@ -1,1187 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42parse.c */ -/* */ -/* Type 42 font parser (body). */ -/* */ -/* Copyright 2002-2013 by */ -/* Roberto Alameda. */ -/* */ -/* 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 "t42parse.h" -#include "t42error.h" -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_AUX_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_t42 - - - static void - t42_parse_font_matrix( T42_Face face, - T42_Loader loader ); - static void - t42_parse_encoding( T42_Face face, - T42_Loader loader ); - - static void - t42_parse_charstrings( T42_Face face, - T42_Loader loader ); - - static void - t42_parse_sfnts( T42_Face face, - T42_Loader loader ); - - - /* as Type42 fonts have no Private dict, */ - /* we set the last argument of T1_FIELD_XXX to 0 */ - static const - T1_FieldRec t42_keywords[] = - { - -#undef FT_STRUCTURE -#define FT_STRUCTURE T1_FontInfo -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_INFO - - 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 -#define FT_STRUCTURE PS_FontExtraRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA - - T1_FIELD_NUM ( "FSType", fs_type, 0 ) - -#undef FT_STRUCTURE -#define FT_STRUCTURE T1_FontRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_DICT - - T1_FIELD_KEY ( "FontName", font_name, 0 ) - T1_FIELD_NUM ( "PaintType", paint_type, 0 ) - T1_FIELD_NUM ( "FontType", font_type, 0 ) - T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 ) - -#undef FT_STRUCTURE -#define FT_STRUCTURE FT_BBox -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_BBOX - - T1_FIELD_BBOX("FontBBox", xMin, 0 ) - - T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix, 0 ) - T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding, 0 ) - T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings, 0 ) - T1_FIELD_CALLBACK( "sfnts", t42_parse_sfnts, 0 ) - - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } - }; - - -#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) -#define T1_Done_Table( p ) \ - do \ - { \ - if ( (p)->funcs.done ) \ - (p)->funcs.done( p ); \ - } while ( 0 ) -#define T1_Release_Table( p ) \ - do \ - { \ - if ( (p)->funcs.release ) \ - (p)->funcs.release( p ); \ - } while ( 0 ) - -#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) -#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root ) - -#define T1_ToInt( p ) \ - (p)->root.funcs.to_int( &(p)->root ) -#define T1_ToBytes( p, b, m, n, d ) \ - (p)->root.funcs.to_bytes( &(p)->root, b, m, n, d ) - -#define T1_ToFixedArray( p, m, f, t ) \ - (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) -#define T1_ToToken( p, t ) \ - (p)->root.funcs.to_token( &(p)->root, t ) - -#define T1_Load_Field( p, f, o, m, pf ) \ - (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) -#define T1_Load_Field_Table( p, f, o, m, pf ) \ - (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) - - - /********************* Parsing Functions ******************/ - - FT_LOCAL_DEF( FT_Error ) - t42_parser_init( T42_Parser parser, - FT_Stream stream, - FT_Memory memory, - PSAux_Service psaux ) - { - FT_Error error = FT_Err_Ok; - FT_Long size; - - - psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); - - parser->stream = stream; - parser->base_len = 0; - parser->base_dict = 0; - parser->in_memory = 0; - - /*******************************************************************/ - /* */ - /* Here a short summary of what is going on: */ - /* */ - /* When creating a new Type 42 parser, we try to locate and load */ - /* the base dictionary, loading the whole font into memory. */ - /* */ - /* When `loading' the base dictionary, we only set up pointers */ - /* in the case of a memory-based stream. Otherwise, we allocate */ - /* and load the base dictionary in it. */ - /* */ - /* parser->in_memory is set if we have a memory stream. */ - /* */ - - if ( FT_STREAM_SEEK( 0L ) || - FT_FRAME_ENTER( 17 ) ) - goto Exit; - - if ( ft_memcmp( stream->cursor, "%!PS-TrueTypeFont", 17 ) != 0 ) - { - FT_TRACE2(( " not a Type42 font\n" )); - error = FT_THROW( Unknown_File_Format ); - } - - FT_FRAME_EXIT(); - - if ( error || FT_STREAM_SEEK( 0 ) ) - goto Exit; - - size = stream->size; - - /* now, try to load `size' bytes of the `base' dictionary we */ - /* found previously */ - - /* if it is a memory-based resource, set up pointers */ - if ( !stream->read ) - { - parser->base_dict = (FT_Byte*)stream->base + stream->pos; - parser->base_len = size; - parser->in_memory = 1; - - /* check that the `size' field is valid */ - if ( FT_STREAM_SKIP( size ) ) - goto Exit; - } - else - { - /* read segment in memory */ - if ( FT_ALLOC( parser->base_dict, size ) || - FT_STREAM_READ( parser->base_dict, size ) ) - goto Exit; - - parser->base_len = size; - } - - parser->root.base = parser->base_dict; - parser->root.cursor = parser->base_dict; - parser->root.limit = parser->root.cursor + parser->base_len; - - Exit: - if ( error && !parser->in_memory ) - FT_FREE( parser->base_dict ); - - return error; - } - - - FT_LOCAL_DEF( void ) - t42_parser_done( T42_Parser parser ) - { - FT_Memory memory = parser->root.memory; - - - /* free the base dictionary only when we have a disk stream */ - if ( !parser->in_memory ) - FT_FREE( parser->base_dict ); - - parser->root.funcs.done( &parser->root ); - } - - - static int - t42_is_space( FT_Byte c ) - { - return ( c == ' ' || c == '\t' || - c == '\r' || c == '\n' || c == '\f' || - c == '\0' ); - } - - - static void - t42_parse_font_matrix( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_Matrix* matrix = &face->type1.font_matrix; - FT_Vector* offset = &face->type1.font_offset; - FT_Face root = (FT_Face)&face->root; - FT_Fixed temp[6]; - FT_Fixed temp_scale; - - - (void)T1_ToFixedArray( parser, 6, temp, 3 ); - - temp_scale = FT_ABS( temp[3] ); - - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ - - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); - - /* we need to scale the values by 1.0/temp_scale */ - if ( temp_scale != 0x10000L ) - { - temp[0] = FT_DivFix( temp[0], temp_scale ); - temp[1] = FT_DivFix( temp[1], temp_scale ); - temp[2] = FT_DivFix( temp[2], temp_scale ); - temp[4] = FT_DivFix( temp[4], temp_scale ); - temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; - } - - matrix->xx = temp[0]; - matrix->yx = temp[1]; - matrix->xy = temp[2]; - matrix->yy = temp[3]; - - /* note that the offsets must be expressed in integer font units */ - offset->x = temp[4] >> 16; - offset->y = temp[5] >> 16; - } - - - static void - t42_parse_encoding( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_Byte* cur; - FT_Byte* limit = parser->root.limit; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - T1_Skip_Spaces( parser ); - cur = parser->root.cursor; - if ( cur >= limit ) - { - FT_ERROR(( "t42_parse_encoding: out of bounds\n" )); - parser->root.error = FT_THROW( Invalid_File_Format ); - return; - } - - /* if we have a number or `[', the encoding is an array, */ - /* and we must load it now */ - if ( ft_isdigit( *cur ) || *cur == '[' ) - { - T1_Encoding encode = &face->type1.encoding; - FT_UInt count, n; - PS_Table char_table = &loader->encoding_table; - FT_Memory memory = parser->root.memory; - FT_Error error; - FT_Bool only_immediates = 0; - - - /* read the number of entries in the encoding; should be 256 */ - if ( *cur == '[' ) - { - count = 256; - only_immediates = 1; - parser->root.cursor++; - } - else - count = (FT_UInt)T1_ToInt( parser ); - - T1_Skip_Spaces( parser ); - if ( parser->root.cursor >= limit ) - return; - - /* we use a T1_Table to store our charnames */ - loader->num_chars = encode->num_chars = count; - if ( FT_NEW_ARRAY( encode->char_index, count ) || - FT_NEW_ARRAY( encode->char_name, count ) || - FT_SET_ERROR( psaux->ps_table_funcs->init( - char_table, count, memory ) ) ) - { - parser->root.error = error; - return; - } - - /* We need to `zero' out encoding_table.elements */ - for ( n = 0; n < count; n++ ) - { - char* notdef = (char *)".notdef"; - - - T1_Add_Table( char_table, n, notdef, 8 ); - } - - /* Now we need to read records of the form */ - /* */ - /* ... charcode /charname ... */ - /* */ - /* for each entry in our table. */ - /* */ - /* We simply look for a number followed by an immediate */ - /* name. Note that this ignores correctly the sequence */ - /* that is often seen in type42 fonts: */ - /* */ - /* 0 1 255 { 1 index exch /.notdef put } for dup */ - /* */ - /* used to clean the encoding array before anything else. */ - /* */ - /* Alternatively, if the array is directly given as */ - /* */ - /* /Encoding [ ... ] */ - /* */ - /* we only read immediates. */ - - n = 0; - T1_Skip_Spaces( parser ); - - while ( parser->root.cursor < limit ) - { - cur = parser->root.cursor; - - /* we stop when we encounter `def' or `]' */ - if ( *cur == 'd' && cur + 3 < limit ) - { - if ( cur[1] == 'e' && - cur[2] == 'f' && - t42_is_space( cur[3] ) ) - { - FT_TRACE6(( "encoding end\n" )); - cur += 3; - break; - } - } - if ( *cur == ']' ) - { - FT_TRACE6(( "encoding end\n" )); - cur++; - break; - } - - /* check whether we have found an entry */ - if ( ft_isdigit( *cur ) || only_immediates ) - { - FT_Int charcode; - - - if ( only_immediates ) - charcode = n; - else - { - charcode = (FT_Int)T1_ToInt( parser ); - T1_Skip_Spaces( parser ); - } - - cur = parser->root.cursor; - - if ( *cur == '/' && cur + 2 < limit && n < count ) - { - FT_PtrDist len; - - - cur++; - - parser->root.cursor = cur; - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - return; - - len = parser->root.cursor - cur; - - parser->root.error = T1_Add_Table( char_table, charcode, - cur, len + 1 ); - if ( parser->root.error ) - return; - char_table->elements[charcode][len] = '\0'; - - n++; - } - } - else - { - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - return; - } - - T1_Skip_Spaces( parser ); - } - - face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; - parser->root.cursor = cur; - } - - /* Otherwise, we should have either `StandardEncoding', */ - /* `ExpertEncoding', or `ISOLatin1Encoding' */ - else - { - if ( cur + 17 < limit && - ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; - - else if ( cur + 15 < limit && - ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; - - else if ( cur + 18 < limit && - ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; - - else - { - FT_ERROR(( "t42_parse_encoding: invalid token\n" )); - parser->root.error = FT_THROW( Invalid_File_Format ); - } - } - } - - - typedef enum T42_Load_Status_ - { - BEFORE_START, - BEFORE_TABLE_DIR, - OTHER_TABLES - - } T42_Load_Status; - - - static void - t42_parse_sfnts( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_Memory memory = parser->root.memory; - FT_Byte* cur; - FT_Byte* limit = parser->root.limit; - FT_Error error; - FT_Int num_tables = 0; - FT_ULong count, ttf_size = 0; - - FT_Long n, string_size, old_string_size, real_size; - FT_Byte* string_buf = NULL; - FT_Bool allocated = 0; - - T42_Load_Status status; - - - /* The format is */ - /* */ - /* /sfnts [ <hexstring> <hexstring> ... ] def */ - /* */ - /* or */ - /* */ - /* /sfnts [ */ - /* <num_bin_bytes> RD <binary data> */ - /* <num_bin_bytes> RD <binary data> */ - /* ... */ - /* ] def */ - /* */ - /* with exactly one space after the `RD' token. */ - - T1_Skip_Spaces( parser ); - - if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' ) - { - FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - T1_Skip_Spaces( parser ); - status = BEFORE_START; - string_size = 0; - old_string_size = 0; - count = 0; - - while ( parser->root.cursor < limit ) - { - cur = parser->root.cursor; - - if ( *cur == ']' ) - { - parser->root.cursor++; - goto Exit; - } - - else if ( *cur == '<' ) - { - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - goto Exit; - - /* don't include delimiters */ - string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); - if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) - goto Fail; - - allocated = 1; - - parser->root.cursor = cur; - (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 ); - old_string_size = string_size; - string_size = real_size; - } - - else if ( ft_isdigit( *cur ) ) - { - if ( allocated ) - { - FT_ERROR(( "t42_parse_sfnts: " - "can't handle mixed binary and hex strings\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - string_size = T1_ToInt( parser ); - if ( string_size < 0 ) - { - FT_ERROR(( "t42_parse_sfnts: invalid string size\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - T1_Skip_PS_Token( parser ); /* `RD' */ - if ( parser->root.error ) - return; - - string_buf = parser->root.cursor + 1; /* one space after `RD' */ - - if ( limit - parser->root.cursor < string_size ) - { - FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - else - parser->root.cursor += string_size + 1; - } - - if ( !string_buf ) - { - FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* A string can have a trailing zero (odd) byte for padding. */ - /* Ignore it. */ - if ( ( string_size & 1 ) && string_buf[string_size - 1] == 0 ) - string_size--; - - if ( !string_size ) - { - FT_ERROR(( "t42_parse_sfnts: invalid string\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - for ( n = 0; n < string_size; n++ ) - { - switch ( status ) - { - case BEFORE_START: - /* load offset table, 12 bytes */ - if ( count < 12 ) - { - face->ttf_data[count++] = string_buf[n]; - continue; - } - else - { - num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; - status = BEFORE_TABLE_DIR; - ttf_size = 12 + 16 * num_tables; - - if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) - goto Fail; - } - /* fall through */ - - case BEFORE_TABLE_DIR: - /* the offset table is read; read the table directory */ - if ( count < ttf_size ) - { - face->ttf_data[count++] = string_buf[n]; - continue; - } - else - { - int i; - FT_ULong len; - - - for ( i = 0; i < num_tables; i++ ) - { - FT_Byte* p = face->ttf_data + 12 + 16 * i + 12; - - - len = FT_PEEK_ULONG( p ); - - /* Pad to a 4-byte boundary length */ - ttf_size += ( len + 3 ) & ~3; - } - - status = OTHER_TABLES; - face->ttf_size = ttf_size; - - /* there are no more than 256 tables, so no size check here */ - if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, - ttf_size + 1 ) ) - goto Fail; - } - /* fall through */ - - case OTHER_TABLES: - /* all other tables are just copied */ - if ( count >= ttf_size ) - { - FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - face->ttf_data[count++] = string_buf[n]; - } - } - - T1_Skip_Spaces( parser ); - } - - /* if control reaches this point, the format was not valid */ - error = FT_THROW( Invalid_File_Format ); - - Fail: - parser->root.error = error; - - Exit: - if ( allocated ) - FT_FREE( string_buf ); - } - - - static void - t42_parse_charstrings( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - PS_Table code_table = &loader->charstrings; - PS_Table name_table = &loader->glyph_names; - PS_Table swap_table = &loader->swap_table; - FT_Memory memory = parser->root.memory; - FT_Error error; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - FT_Byte* cur; - FT_Byte* limit = parser->root.limit; - FT_UInt n; - FT_UInt notdef_index = 0; - FT_Byte notdef_found = 0; - - - T1_Skip_Spaces( parser ); - - if ( parser->root.cursor >= limit ) - { - FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - if ( ft_isdigit( *parser->root.cursor ) ) - { - loader->num_glyphs = (FT_UInt)T1_ToInt( parser ); - if ( parser->root.error ) - return; - } - else if ( *parser->root.cursor == '<' ) - { - /* We have `<< ... >>'. Count the number of `/' in the dictionary */ - /* to get its size. */ - FT_UInt count = 0; - - - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - return; - T1_Skip_Spaces( parser ); - cur = parser->root.cursor; - - while ( parser->root.cursor < limit ) - { - if ( *parser->root.cursor == '/' ) - count++; - else if ( *parser->root.cursor == '>' ) - { - loader->num_glyphs = count; - parser->root.cursor = cur; /* rewind */ - break; - } - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - return; - T1_Skip_Spaces( parser ); - } - } - else - { - FT_ERROR(( "t42_parse_charstrings: invalid token\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - if ( parser->root.cursor >= limit ) - { - FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* initialize tables */ - - error = psaux->ps_table_funcs->init( code_table, - loader->num_glyphs, - memory ); - if ( error ) - goto Fail; - - error = psaux->ps_table_funcs->init( name_table, - loader->num_glyphs, - memory ); - if ( error ) - goto Fail; - - /* Initialize table for swapping index notdef_index and */ - /* index 0 names and codes (if necessary). */ - - error = psaux->ps_table_funcs->init( swap_table, 4, memory ); - if ( error ) - goto Fail; - - n = 0; - - for (;;) - { - /* The format is simple: */ - /* `/glyphname' + index [+ def] */ - - T1_Skip_Spaces( parser ); - - cur = parser->root.cursor; - if ( cur >= limit ) - break; - - /* We stop when we find an `end' keyword or '>' */ - if ( *cur == 'e' && - cur + 3 < limit && - cur[1] == 'n' && - cur[2] == 'd' && - t42_is_space( cur[3] ) ) - break; - if ( *cur == '>' ) - break; - - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - return; - - if ( *cur == '/' ) - { - FT_PtrDist len; - - - if ( cur + 1 >= limit ) - { - FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - cur++; /* skip `/' */ - len = parser->root.cursor - cur; - - error = T1_Add_Table( name_table, n, cur, len + 1 ); - if ( error ) - goto Fail; - - /* add a trailing zero to the name table */ - name_table->elements[n][len] = '\0'; - - /* record index of /.notdef */ - if ( *cur == '.' && - ft_strcmp( ".notdef", - (const char*)(name_table->elements[n]) ) == 0 ) - { - notdef_index = n; - notdef_found = 1; - } - - T1_Skip_Spaces( parser ); - - cur = parser->root.cursor; - - (void)T1_ToInt( parser ); - if ( parser->root.cursor >= limit ) - { - FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - len = parser->root.cursor - cur; - - error = T1_Add_Table( code_table, n, cur, len + 1 ); - if ( error ) - goto Fail; - - code_table->elements[n][len] = '\0'; - - n++; - if ( n >= loader->num_glyphs ) - break; - } - } - - loader->num_glyphs = n; - - if ( !notdef_found ) - { - FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* if /.notdef does not occupy index 0, do our magic. */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)name_table->elements[0] ) ) - { - /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ - /* name and code entries to swap_table. Then place notdef_index */ - /* name and code entries into swap_table. Then swap name and code */ - /* entries at indices notdef_index and 0 using values stored in */ - /* swap_table. */ - - /* Index 0 name */ - error = T1_Add_Table( swap_table, 0, - name_table->elements[0], - name_table->lengths [0] ); - if ( error ) - goto Fail; - - /* Index 0 code */ - error = T1_Add_Table( swap_table, 1, - code_table->elements[0], - code_table->lengths [0] ); - if ( error ) - goto Fail; - - /* Index notdef_index name */ - error = T1_Add_Table( swap_table, 2, - name_table->elements[notdef_index], - name_table->lengths [notdef_index] ); - if ( error ) - goto Fail; - - /* Index notdef_index code */ - error = T1_Add_Table( swap_table, 3, - code_table->elements[notdef_index], - code_table->lengths [notdef_index] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( name_table, notdef_index, - swap_table->elements[0], - swap_table->lengths [0] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( code_table, notdef_index, - swap_table->elements[1], - swap_table->lengths [1] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( name_table, 0, - swap_table->elements[2], - swap_table->lengths [2] ); - if ( error ) - goto Fail; - - error = T1_Add_Table( code_table, 0, - swap_table->elements[3], - swap_table->lengths [3] ); - if ( error ) - goto Fail; - - } - - return; - - Fail: - parser->root.error = error; - } - - - static FT_Error - t42_load_keyword( T42_Face face, - T42_Loader loader, - T1_Field field ) - { - FT_Error error; - void* dummy_object; - void** objects; - FT_UInt max_objects = 0; - - - /* if the keyword has a dedicated callback, call it */ - if ( field->type == T1_FIELD_TYPE_CALLBACK ) - { - field->reader( (FT_Face)face, loader ); - error = loader->parser.root.error; - goto Exit; - } - - /* now the keyword is either a simple field or a table of fields; */ - /* we are now going to take care of it */ - - switch ( field->location ) - { - case T1_FIELD_LOCATION_FONT_INFO: - dummy_object = &face->type1.font_info; - break; - - case T1_FIELD_LOCATION_FONT_EXTRA: - dummy_object = &face->type1.font_extra; - break; - - case T1_FIELD_LOCATION_BBOX: - dummy_object = &face->type1.font_bbox; - break; - - default: - dummy_object = &face->type1; - } - - objects = &dummy_object; - - if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || - field->type == T1_FIELD_TYPE_FIXED_ARRAY ) - error = T1_Load_Field_Table( &loader->parser, field, - objects, max_objects, 0 ); - else - error = T1_Load_Field( &loader->parser, field, - objects, max_objects, 0 ); - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - t42_parse_dict( T42_Face face, - T42_Loader loader, - FT_Byte* base, - FT_Long size ) - { - T42_Parser parser = &loader->parser; - FT_Byte* limit; - FT_Int n_keywords = (FT_Int)( sizeof ( t42_keywords ) / - sizeof ( t42_keywords[0] ) ); - - - parser->root.cursor = base; - parser->root.limit = base + size; - parser->root.error = FT_Err_Ok; - - limit = parser->root.limit; - - T1_Skip_Spaces( parser ); - - while ( parser->root.cursor < limit ) - { - FT_Byte* cur; - - - cur = parser->root.cursor; - - /* look for `FontDirectory' which causes problems for some fonts */ - if ( *cur == 'F' && cur + 25 < limit && - ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) - { - FT_Byte* cur2; - - - /* skip the `FontDirectory' keyword */ - T1_Skip_PS_Token( parser ); - T1_Skip_Spaces ( parser ); - cur = cur2 = parser->root.cursor; - - /* look up the `known' keyword */ - while ( cur < limit ) - { - if ( *cur == 'k' && cur + 5 < limit && - ft_strncmp( (char*)cur, "known", 5 ) == 0 ) - break; - - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - goto Exit; - T1_Skip_Spaces ( parser ); - cur = parser->root.cursor; - } - - if ( cur < limit ) - { - T1_TokenRec token; - - - /* skip the `known' keyword and the token following it */ - T1_Skip_PS_Token( parser ); - T1_ToToken( parser, &token ); - - /* if the last token was an array, skip it! */ - if ( token.type == T1_TOKEN_TYPE_ARRAY ) - cur2 = parser->root.cursor; - } - parser->root.cursor = cur2; - } - - /* look for immediates */ - else if ( *cur == '/' && cur + 2 < limit ) - { - FT_PtrDist len; - - - cur++; - - parser->root.cursor = cur; - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - goto Exit; - - len = parser->root.cursor - cur; - - if ( len > 0 && len < 22 && parser->root.cursor < limit ) - { - int i; - - - /* now compare the immediate name to the keyword table */ - - /* loop through all known keywords */ - for ( i = 0; i < n_keywords; i++ ) - { - T1_Field keyword = (T1_Field)&t42_keywords[i]; - FT_Byte *name = (FT_Byte*)keyword->ident; - - - if ( !name ) - continue; - - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char *)name ) && - ft_memcmp( cur, name, len ) == 0 ) - { - /* we found it -- run the parsing callback! */ - parser->root.error = t42_load_keyword( face, - loader, - keyword ); - if ( parser->root.error ) - return parser->root.error; - break; - } - } - } - } - else - { - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - goto Exit; - } - - T1_Skip_Spaces( parser ); - } - - Exit: - return parser->root.error; - } - - - FT_LOCAL_DEF( void ) - t42_loader_init( T42_Loader loader, - T42_Face face ) - { - FT_UNUSED( face ); - - FT_MEM_ZERO( loader, sizeof ( *loader ) ); - loader->num_glyphs = 0; - loader->num_chars = 0; - - /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - } - - - FT_LOCAL_DEF( void ) - t42_loader_done( T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - - - /* finalize tables */ - T1_Release_Table( &loader->encoding_table ); - T1_Release_Table( &loader->charstrings ); - T1_Release_Table( &loader->glyph_names ); - T1_Release_Table( &loader->swap_table ); - - /* finalize parser */ - t42_parser_done( parser ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/t42parse.h b/drivers/freetype/freetype/src/type42/t42parse.h deleted file mode 100644 index f77ec4af4f..0000000000 --- a/drivers/freetype/freetype/src/type42/t42parse.h +++ /dev/null @@ -1,90 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42parse.h */ -/* */ -/* Type 42 font parser (specification). */ -/* */ -/* Copyright 2002, 2003 by Roberto Alameda. */ -/* */ -/* 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 __T42PARSE_H__ -#define __T42PARSE_H__ - - -#include "t42objs.h" -#include FT_INTERNAL_POSTSCRIPT_AUX_H - - -FT_BEGIN_HEADER - - typedef struct T42_ParserRec_ - { - PS_ParserRec root; - FT_Stream stream; - - FT_Byte* base_dict; - FT_Long base_len; - - FT_Bool in_memory; - - } T42_ParserRec, *T42_Parser; - - - typedef struct T42_Loader_ - { - T42_ParserRec parser; /* parser used to read the stream */ - - FT_UInt num_chars; /* number of characters in encoding */ - PS_TableRec encoding_table; /* PS_Table used to store the */ - /* encoding character names */ - - FT_UInt num_glyphs; - PS_TableRec glyph_names; - PS_TableRec charstrings; - PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ - - } T42_LoaderRec, *T42_Loader; - - - FT_LOCAL( FT_Error ) - t42_parser_init( T42_Parser parser, - FT_Stream stream, - FT_Memory memory, - PSAux_Service psaux ); - - FT_LOCAL( void ) - t42_parser_done( T42_Parser parser ); - - - FT_LOCAL( FT_Error ) - t42_parse_dict( T42_Face face, - T42_Loader loader, - FT_Byte* base, - FT_Long size ); - - - FT_LOCAL( void ) - t42_loader_init( T42_Loader loader, - T42_Face face ); - - FT_LOCAL( void ) - t42_loader_done( T42_Loader loader ); - - - /* */ - -FT_END_HEADER - - -#endif /* __T42PARSE_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/t42types.h b/drivers/freetype/freetype/src/type42/t42types.h deleted file mode 100644 index c7c2db490d..0000000000 --- a/drivers/freetype/freetype/src/type42/t42types.h +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42types.h */ -/* */ -/* Type 42 font data types (specification only). */ -/* */ -/* Copyright 2002, 2003, 2006, 2008 by Roberto Alameda. */ -/* */ -/* 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 __T42TYPES_H__ -#define __T42TYPES_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_TYPE1_TABLES_H -#include FT_INTERNAL_TYPE1_TYPES_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H - - -FT_BEGIN_HEADER - - - typedef struct T42_FaceRec_ - { - FT_FaceRec root; - T1_FontRec type1; - const void* psnames; - const void* psaux; -#if 0 - const void* afm_data; -#endif - FT_Byte* ttf_data; - FT_ULong ttf_size; - FT_Face ttf_face; - FT_CharMapRec charmaprecs[2]; - FT_CharMap charmaps[2]; - PS_UnicodesRec unicode_map; - - } T42_FaceRec, *T42_Face; - - -FT_END_HEADER - -#endif /* __T42TYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/type42/type42.c b/drivers/freetype/freetype/src/type42/type42.c deleted file mode 100644 index d13df56b10..0000000000 --- a/drivers/freetype/freetype/src/type42/type42.c +++ /dev/null @@ -1,25 +0,0 @@ -/***************************************************************************/ -/* */ -/* type42.c */ -/* */ -/* FreeType Type 42 driver component. */ -/* */ -/* Copyright 2002 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. */ -/* */ -/***************************************************************************/ - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include <ft2build.h> -#include "t42objs.c" -#include "t42parse.c" -#include "t42drivr.c" - -/* END */ diff --git a/drivers/freetype/freetype/src/winfonts/Jamfile b/drivers/freetype/freetype/src/winfonts/Jamfile deleted file mode 100644 index 71cf5678e8..0000000000 --- a/drivers/freetype/freetype/src/winfonts/Jamfile +++ /dev/null @@ -1,16 +0,0 @@ -# FreeType 2 src/winfonts Jamfile -# -# Copyright 2001 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. - -SubDir FT2_TOP $(FT2_SRC_DIR) winfonts ; - -Library $(FT2_LIB) : winfnt.c ; - -# end of src/winfonts Jamfile diff --git a/drivers/freetype/freetype/src/winfonts/fnterrs.h b/drivers/freetype/freetype/src/winfonts/fnterrs.h deleted file mode 100644 index 463ba77ee2..0000000000 --- a/drivers/freetype/freetype/src/winfonts/fnterrs.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* fnterrs.h */ -/* */ -/* Win FNT/FON error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the Windows FNT/FON error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ - -#ifndef __FNTERRS_H__ -#define __FNTERRS_H__ - -#include FT_MODULE_ERRORS_H - -#undef __FTERRORS_H__ - -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX FNT_Err_ -#define FT_ERR_BASE FT_Mod_Err_Winfonts - -#include FT_ERRORS_H - -#endif /* __FNTERRS_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/winfonts/module.mk b/drivers/freetype/freetype/src/winfonts/module.mk deleted file mode 100644 index b44d7f0570..0000000000 --- a/drivers/freetype/freetype/src/winfonts/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 Windows FNT/FON module definition -# - - -# Copyright 1996-2000, 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. - - -FTMODULE_H_COMMANDS += WINDOWS_DRIVER - -define WINDOWS_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, winfnt_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/drivers/freetype/freetype/src/winfonts/rules.mk b/drivers/freetype/freetype/src/winfonts/rules.mk deleted file mode 100644 index 71a7df2d8a..0000000000 --- a/drivers/freetype/freetype/src/winfonts/rules.mk +++ /dev/null @@ -1,65 +0,0 @@ -# -# FreeType 2 Windows FNT/FON driver configuration rules -# - - -# Copyright 1996-2000, 2001, 2003 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. - - -# Windows driver directory -# -FNT_DIR := $(SRC_DIR)/winfonts - - -FNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(FNT_DIR)) - - -# Windows driver sources (i.e., C files) -# -FNT_DRV_SRC := $(FNT_DIR)/winfnt.c - -# Windows driver headers -# -FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h) \ - $(FNT_DIR)/fnterrs.h - - -# Windows driver object(s) -# -# FNT_DRV_OBJ_M is used during `multi' builds -# FNT_DRV_OBJ_S is used during `single' builds -# -FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR)/%.c=$(OBJ_DIR)/%.$O) -FNT_DRV_OBJ_S := $(OBJ_DIR)/winfnt.$O - -# Windows driver source file for single build -# -FNT_DRV_SRC_S := $(FNT_DIR)/winfnt.c - - -# Windows driver - single object -# -$(FNT_DRV_OBJ_S): $(FNT_DRV_SRC_S) $(FNT_DRV_SRC) $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(FNT_DRV_SRC_S)) - - -# Windows driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(FNT_DIR)/%.c $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(FNT_DRV_OBJ_S) -DRV_OBJS_M += $(FNT_DRV_OBJ_M) - - -# EOF diff --git a/drivers/freetype/freetype/src/winfonts/winfnt.c b/drivers/freetype/freetype/src/winfonts/winfnt.c deleted file mode 100644 index e8055c0898..0000000000 --- a/drivers/freetype/freetype/src/winfonts/winfnt.c +++ /dev/null @@ -1,1155 +0,0 @@ -/***************************************************************************/ -/* */ -/* winfnt.c */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* Copyright 1996-2004, 2006-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* Copyright 2003 Huw D M Davies for Codeweavers */ -/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ -/* */ -/* 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_WINFONTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_OBJECTS_H -#include FT_TRUETYPE_IDS_H - -#include "winfnt.h" -#include "fnterrs.h" -#include FT_SERVICE_WINFNT_H -#include FT_SERVICE_XFREE86_NAME_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_winfnt - - - static const FT_Frame_Field winmz_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE WinMZ_HeaderRec - - FT_FRAME_START( 64 ), - FT_FRAME_USHORT_LE ( magic ), - FT_FRAME_SKIP_BYTES( 29 * 2 ), - FT_FRAME_ULONG_LE ( lfanew ), - FT_FRAME_END - }; - - static const FT_Frame_Field winne_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE WinNE_HeaderRec - - FT_FRAME_START( 40 ), - FT_FRAME_USHORT_LE ( magic ), - FT_FRAME_SKIP_BYTES( 34 ), - FT_FRAME_USHORT_LE ( resource_tab_offset ), - FT_FRAME_USHORT_LE ( rname_tab_offset ), - FT_FRAME_END - }; - - static const FT_Frame_Field winpe32_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE WinPE32_HeaderRec - - FT_FRAME_START( 248 ), - FT_FRAME_ULONG_LE ( magic ), /* PE00 */ - FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */ - FT_FRAME_USHORT_LE ( number_of_sections ), - FT_FRAME_SKIP_BYTES( 12 ), - FT_FRAME_USHORT_LE ( size_of_optional_header ), - FT_FRAME_SKIP_BYTES( 2 ), - FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */ - FT_FRAME_SKIP_BYTES( 110 ), - FT_FRAME_ULONG_LE ( rsrc_virtual_address ), - FT_FRAME_ULONG_LE ( rsrc_size ), - FT_FRAME_SKIP_BYTES( 104 ), - FT_FRAME_END - }; - - static const FT_Frame_Field winpe32_section_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE WinPE32_SectionRec - - FT_FRAME_START( 40 ), - FT_FRAME_BYTES ( name, 8 ), - FT_FRAME_SKIP_BYTES( 4 ), - FT_FRAME_ULONG_LE ( virtual_address ), - FT_FRAME_ULONG_LE ( size_of_raw_data ), - FT_FRAME_ULONG_LE ( pointer_to_raw_data ), - FT_FRAME_SKIP_BYTES( 16 ), - FT_FRAME_END - }; - - static const FT_Frame_Field winpe_rsrc_dir_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE WinPE_RsrcDirRec - - FT_FRAME_START( 16 ), - FT_FRAME_ULONG_LE ( characteristics ), - FT_FRAME_ULONG_LE ( time_date_stamp ), - FT_FRAME_USHORT_LE( major_version ), - FT_FRAME_USHORT_LE( minor_version ), - FT_FRAME_USHORT_LE( number_of_named_entries ), - FT_FRAME_USHORT_LE( number_of_id_entries ), - FT_FRAME_END - }; - - static const FT_Frame_Field winpe_rsrc_dir_entry_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE WinPE_RsrcDirEntryRec - - FT_FRAME_START( 8 ), - FT_FRAME_ULONG_LE( name ), - FT_FRAME_ULONG_LE( offset ), - FT_FRAME_END - }; - - static const FT_Frame_Field winpe_rsrc_data_entry_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE WinPE_RsrcDataEntryRec - - FT_FRAME_START( 16 ), - FT_FRAME_ULONG_LE( offset_to_data ), - FT_FRAME_ULONG_LE( size ), - FT_FRAME_ULONG_LE( code_page ), - FT_FRAME_ULONG_LE( reserved ), - FT_FRAME_END - }; - - static const FT_Frame_Field winfnt_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE FT_WinFNT_HeaderRec - - FT_FRAME_START( 148 ), - FT_FRAME_USHORT_LE( version ), - FT_FRAME_ULONG_LE ( file_size ), - FT_FRAME_BYTES ( copyright, 60 ), - FT_FRAME_USHORT_LE( file_type ), - FT_FRAME_USHORT_LE( nominal_point_size ), - FT_FRAME_USHORT_LE( vertical_resolution ), - FT_FRAME_USHORT_LE( horizontal_resolution ), - FT_FRAME_USHORT_LE( ascent ), - FT_FRAME_USHORT_LE( internal_leading ), - FT_FRAME_USHORT_LE( external_leading ), - FT_FRAME_BYTE ( italic ), - FT_FRAME_BYTE ( underline ), - FT_FRAME_BYTE ( strike_out ), - FT_FRAME_USHORT_LE( weight ), - FT_FRAME_BYTE ( charset ), - FT_FRAME_USHORT_LE( pixel_width ), - FT_FRAME_USHORT_LE( pixel_height ), - FT_FRAME_BYTE ( pitch_and_family ), - FT_FRAME_USHORT_LE( avg_width ), - FT_FRAME_USHORT_LE( max_width ), - FT_FRAME_BYTE ( first_char ), - FT_FRAME_BYTE ( last_char ), - FT_FRAME_BYTE ( default_char ), - FT_FRAME_BYTE ( break_char ), - FT_FRAME_USHORT_LE( bytes_per_row ), - FT_FRAME_ULONG_LE ( device_offset ), - FT_FRAME_ULONG_LE ( face_name_offset ), - FT_FRAME_ULONG_LE ( bits_pointer ), - FT_FRAME_ULONG_LE ( bits_offset ), - FT_FRAME_BYTE ( reserved ), - FT_FRAME_ULONG_LE ( flags ), - FT_FRAME_USHORT_LE( A_space ), - FT_FRAME_USHORT_LE( B_space ), - FT_FRAME_USHORT_LE( C_space ), - FT_FRAME_ULONG_LE ( color_table_offset ), - FT_FRAME_BYTES ( reserved1, 16 ), - FT_FRAME_END - }; - - - static void - fnt_font_done( FNT_Face face ) - { - FT_Memory memory = FT_FACE( face )->memory; - FT_Stream stream = FT_FACE( face )->stream; - FNT_Font font = face->font; - - - if ( !font ) - return; - - if ( font->fnt_frame ) - FT_FRAME_RELEASE( font->fnt_frame ); - FT_FREE( font->family_name ); - - FT_FREE( font ); - face->font = 0; - } - - - static FT_Error - fnt_font_load( FNT_Font font, - FT_Stream stream ) - { - FT_Error error; - FT_WinFNT_Header header = &font->header; - FT_Bool new_format; - FT_UInt size; - - - /* first of all, read the FNT header */ - if ( FT_STREAM_SEEK( font->offset ) || - FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) ) - goto Exit; - - /* check header */ - if ( header->version != 0x200 && - header->version != 0x300 ) - { - FT_TRACE2(( " not a Windows FNT file\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - new_format = FT_BOOL( font->header.version == 0x300 ); - size = new_format ? 148 : 118; - - if ( header->file_size < size ) - { - FT_TRACE2(( " not a Windows FNT file\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - /* Version 2 doesn't have these fields */ - if ( header->version == 0x200 ) - { - header->flags = 0; - header->A_space = 0; - header->B_space = 0; - header->C_space = 0; - - header->color_table_offset = 0; - } - - if ( header->file_type & 1 ) - { - FT_TRACE2(( "[can't handle vector FNT fonts]\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; - } - - /* this is a FNT file/table; extract its frame */ - if ( FT_STREAM_SEEK( font->offset ) || - FT_FRAME_EXTRACT( header->file_size, font->fnt_frame ) ) - goto Exit; - - Exit: - return error; - } - - - static FT_Error - fnt_face_get_dll_font( FNT_Face face, - FT_Int face_index ) - { - FT_Error error; - FT_Stream stream = FT_FACE( face )->stream; - FT_Memory memory = FT_FACE( face )->memory; - WinMZ_HeaderRec mz_header; - - - face->font = 0; - - /* does it begin with an MZ header? */ - if ( FT_STREAM_SEEK( 0 ) || - FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) ) - goto Exit; - - error = FT_ERR( Unknown_File_Format ); - if ( mz_header.magic == WINFNT_MZ_MAGIC ) - { - /* yes, now look for an NE header in the file */ - WinNE_HeaderRec ne_header; - - - FT_TRACE2(( "MZ signature found\n" )); - - if ( FT_STREAM_SEEK( mz_header.lfanew ) || - FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) ) - goto Exit; - - error = FT_ERR( Unknown_File_Format ); - if ( ne_header.magic == WINFNT_NE_MAGIC ) - { - /* good, now look into the resource table for each FNT resource */ - FT_ULong res_offset = mz_header.lfanew + - ne_header.resource_tab_offset; - FT_UShort size_shift; - FT_UShort font_count = 0; - FT_ULong font_offset = 0; - - - FT_TRACE2(( "NE signature found\n" )); - - if ( FT_STREAM_SEEK( res_offset ) || - FT_FRAME_ENTER( ne_header.rname_tab_offset - - ne_header.resource_tab_offset ) ) - goto Exit; - - size_shift = FT_GET_USHORT_LE(); - - for (;;) - { - FT_UShort type_id, count; - - - type_id = FT_GET_USHORT_LE(); - if ( !type_id ) - break; - - count = FT_GET_USHORT_LE(); - - if ( type_id == 0x8008U ) - { - font_count = count; - font_offset = (FT_ULong)( FT_STREAM_POS() + 4 + - ( stream->cursor - stream->limit ) ); - break; - } - - stream->cursor += 4 + count * 12; - } - - FT_FRAME_EXIT(); - - if ( !font_count || !font_offset ) - { - FT_TRACE2(( "this file doesn't contain any FNT resources\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* loading `winfnt_header_fields' needs at least 118 bytes; */ - /* use this as a rough measure to check the expected font size */ - if ( font_count * 118UL > stream->size ) - { - FT_TRACE2(( "invalid number of faces\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - face->root.num_faces = font_count; - - if ( face_index >= font_count ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - else if ( face_index < 0 ) - goto Exit; - - if ( FT_NEW( face->font ) ) - goto Exit; - - if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) || - FT_FRAME_ENTER( 12 ) ) - goto Fail; - - face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; - face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift; - - stream->cursor += 8; - - FT_FRAME_EXIT(); - - error = fnt_font_load( face->font, stream ); - } - else if ( ne_header.magic == WINFNT_PE_MAGIC ) - { - WinPE32_HeaderRec pe32_header; - WinPE32_SectionRec pe32_section; - WinPE_RsrcDirRec root_dir, name_dir, lang_dir; - WinPE_RsrcDirEntryRec dir_entry1, dir_entry2, dir_entry3; - WinPE_RsrcDataEntryRec data_entry; - - FT_Long root_dir_offset, name_dir_offset, lang_dir_offset; - FT_UShort i, j, k; - - - FT_TRACE2(( "PE signature found\n" )); - - if ( FT_STREAM_SEEK( mz_header.lfanew ) || - FT_STREAM_READ_FIELDS( winpe32_header_fields, &pe32_header ) ) - goto Exit; - - FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, " - "size_of_optional_header %02x\n" - "magic32 %02x, rsrc_virtual_address %04lx, " - "rsrc_size %04lx\n", - pe32_header.magic, pe32_header.machine, - pe32_header.number_of_sections, - pe32_header.size_of_optional_header, - pe32_header.magic32, pe32_header.rsrc_virtual_address, - pe32_header.rsrc_size )); - - if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ || - pe32_header.machine != 0x014c /* i386 */ || - pe32_header.size_of_optional_header != 0xe0 /* FIXME */ || - pe32_header.magic32 != 0x10b ) - { - FT_TRACE2(( "this file has an invalid PE header\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - face->root.num_faces = 0; - - for ( i = 0; i < pe32_header.number_of_sections; i++ ) - { - if ( FT_STREAM_READ_FIELDS( winpe32_section_fields, - &pe32_section ) ) - goto Exit; - - FT_TRACE2(( "name %.8s, va %04lx, size %04lx, offset %04lx\n", - pe32_section.name, pe32_section.virtual_address, - pe32_section.size_of_raw_data, - pe32_section.pointer_to_raw_data )); - - if ( pe32_header.rsrc_virtual_address == - pe32_section.virtual_address ) - goto Found_rsrc_section; - } - - FT_TRACE2(( "this file doesn't contain any resources\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - - Found_rsrc_section: - FT_TRACE2(( "found resources section %.8s\n", pe32_section.name )); - - if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data ) || - FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &root_dir ) ) - goto Exit; - - root_dir_offset = pe32_section.pointer_to_raw_data; - - for ( i = 0; i < root_dir.number_of_named_entries + - root_dir.number_of_id_entries; i++ ) - { - if ( FT_STREAM_SEEK( root_dir_offset + 16 + i * 8 ) || - FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, - &dir_entry1 ) ) - goto Exit; - - if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ ) - { - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - dir_entry1.offset &= ~0x80000000UL; - - name_dir_offset = pe32_section.pointer_to_raw_data + - dir_entry1.offset; - - if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data + - dir_entry1.offset ) || - FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &name_dir ) ) - goto Exit; - - for ( j = 0; j < name_dir.number_of_named_entries + - name_dir.number_of_id_entries; j++ ) - { - if ( FT_STREAM_SEEK( name_dir_offset + 16 + j * 8 ) || - FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, - &dir_entry2 ) ) - goto Exit; - - if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ ) - { - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - dir_entry2.offset &= ~0x80000000UL; - - lang_dir_offset = pe32_section.pointer_to_raw_data + - dir_entry2.offset; - - if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data + - dir_entry2.offset ) || - FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &lang_dir ) ) - goto Exit; - - for ( k = 0; k < lang_dir.number_of_named_entries + - lang_dir.number_of_id_entries; k++ ) - { - if ( FT_STREAM_SEEK( lang_dir_offset + 16 + k * 8 ) || - FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, - &dir_entry3 ) ) - goto Exit; - - if ( dir_entry2.offset & 0x80000000UL /* DataIsDirectory */ ) - { - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( dir_entry1.name == 8 /* RT_FONT */ ) - { - if ( FT_STREAM_SEEK( root_dir_offset + dir_entry3.offset ) || - FT_STREAM_READ_FIELDS( winpe_rsrc_data_entry_fields, - &data_entry ) ) - goto Exit; - - FT_TRACE2(( "found font #%lu, offset %04lx, " - "size %04lx, cp %lu\n", - dir_entry2.name, - pe32_section.pointer_to_raw_data + - data_entry.offset_to_data - - pe32_section.virtual_address, - data_entry.size, data_entry.code_page )); - - if ( face_index == face->root.num_faces ) - { - if ( FT_NEW( face->font ) ) - goto Exit; - - face->font->offset = pe32_section.pointer_to_raw_data + - data_entry.offset_to_data - - pe32_section.virtual_address; - face->font->fnt_size = data_entry.size; - - error = fnt_font_load( face->font, stream ); - if ( error ) - { - FT_TRACE2(( "font #%lu load error %d\n", - dir_entry2.name, error )); - goto Fail; - } - else - FT_TRACE2(( "font #%lu successfully loaded\n", - dir_entry2.name )); - } - - face->root.num_faces++; - } - } - } - } - } - - if ( !face->root.num_faces ) - { - FT_TRACE2(( "this file doesn't contain any RT_FONT resources\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( face_index >= face->root.num_faces ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - } - - Fail: - if ( error ) - fnt_font_done( face ); - - Exit: - return error; - } - - - typedef struct FNT_CMapRec_ - { - FT_CMapRec cmap; - FT_UInt32 first; - FT_UInt32 count; - - } FNT_CMapRec, *FNT_CMap; - - - static FT_Error - fnt_cmap_init( FNT_CMap cmap ) - { - FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); - FNT_Font font = face->font; - - - cmap->first = (FT_UInt32) font->header.first_char; - cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 ); - - return 0; - } - - - static FT_UInt - fnt_cmap_char_index( FNT_CMap cmap, - FT_UInt32 char_code ) - { - FT_UInt gindex = 0; - - - char_code -= cmap->first; - if ( char_code < cmap->count ) - /* we artificially increase the glyph index; */ - /* FNT_Load_Glyph reverts to the right one */ - gindex = (FT_UInt)( char_code + 1 ); - return gindex; - } - - - static FT_UInt32 - fnt_cmap_char_next( FNT_CMap cmap, - FT_UInt32 *pchar_code ) - { - FT_UInt gindex = 0; - FT_UInt32 result = 0; - FT_UInt32 char_code = *pchar_code + 1; - - - if ( char_code <= cmap->first ) - { - result = cmap->first; - gindex = 1; - } - else - { - char_code -= cmap->first; - if ( char_code < cmap->count ) - { - result = cmap->first + char_code; - gindex = (FT_UInt)( char_code + 1 ); - } - } - - *pchar_code = result; - return gindex; - } - - - static const FT_CMap_ClassRec fnt_cmap_class_rec = - { - sizeof ( FNT_CMapRec ), - - (FT_CMap_InitFunc) fnt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)fnt_cmap_char_index, - (FT_CMap_CharNextFunc) fnt_cmap_char_next, - - NULL, NULL, NULL, NULL, NULL - }; - - static FT_CMap_Class const fnt_cmap_class = &fnt_cmap_class_rec; - - - static void - FNT_Face_Done( FT_Face fntface ) /* FNT_Face */ - { - FNT_Face face = (FNT_Face)fntface; - FT_Memory memory; - - - if ( !face ) - return; - - memory = FT_FACE_MEMORY( face ); - - fnt_font_done( face ); - - FT_FREE( fntface->available_sizes ); - fntface->num_fixed_sizes = 0; - } - - - static FT_Error - FNT_Face_Init( FT_Stream stream, - FT_Face fntface, /* FNT_Face */ - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FNT_Face face = (FNT_Face)fntface; - FT_Error error; - FT_Memory memory = FT_FACE_MEMORY( face ); - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - - - FT_TRACE2(( "Windows FNT driver\n" )); - - /* try to load font from a DLL */ - error = fnt_face_get_dll_font( face, face_index ); - if ( !error && face_index < 0 ) - goto Exit; - - if ( FT_ERR_EQ( error, Unknown_File_Format ) ) - { - /* this didn't work; try to load a single FNT font */ - FNT_Font font; - - if ( FT_NEW( face->font ) ) - goto Exit; - - fntface->num_faces = 1; - - font = face->font; - font->offset = 0; - font->fnt_size = stream->size; - - error = fnt_font_load( font, stream ); - - if ( !error ) - { - if ( face_index > 0 ) - error = FT_THROW( Invalid_Argument ); - else if ( face_index < 0 ) - goto Exit; - } - } - - if ( error ) - goto Fail; - - /* we now need to fill the root FT_Face fields */ - /* with relevant information */ - { - FT_Face root = FT_FACE( face ); - FNT_Font font = face->font; - FT_PtrDist family_size; - - - root->face_index = face_index; - - root->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL; - - if ( font->header.avg_width == font->header.max_width ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - if ( font->header.italic ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - - if ( font->header.weight >= 800 ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - - /* set up the `fixed_sizes' array */ - if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) - goto Fail; - - root->num_fixed_sizes = 1; - - { - FT_Bitmap_Size* bsize = root->available_sizes; - FT_UShort x_res, y_res; - - - bsize->width = font->header.avg_width; - bsize->height = (FT_Short)( - font->header.pixel_height + font->header.external_leading ); - bsize->size = font->header.nominal_point_size << 6; - - x_res = font->header.horizontal_resolution; - if ( !x_res ) - x_res = 72; - - y_res = font->header.vertical_resolution; - if ( !y_res ) - y_res = 72; - - bsize->y_ppem = FT_MulDiv( bsize->size, y_res, 72 ); - bsize->y_ppem = FT_PIX_ROUND( bsize->y_ppem ); - - /* - * this reads: - * - * the nominal height is larger than the bbox's height - * - * => nominal_point_size contains incorrect value; - * use pixel_height as the nominal height - */ - if ( bsize->y_ppem > ( font->header.pixel_height << 6 ) ) - { - FT_TRACE2(( "use pixel_height as the nominal height\n" )); - - bsize->y_ppem = font->header.pixel_height << 6; - bsize->size = FT_MulDiv( bsize->y_ppem, 72, y_res ); - } - - bsize->x_ppem = FT_MulDiv( bsize->size, x_res, 72 ); - bsize->x_ppem = FT_PIX_ROUND( bsize->x_ppem ); - } - - { - FT_CharMapRec charmap; - - - charmap.encoding = FT_ENCODING_NONE; - /* initial platform/encoding should indicate unset status? */ - charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; - charmap.encoding_id = TT_APPLE_ID_DEFAULT; - charmap.face = root; - - if ( font->header.charset == FT_WinFNT_ID_MAC ) - { - charmap.encoding = FT_ENCODING_APPLE_ROMAN; - charmap.platform_id = TT_PLATFORM_MACINTOSH; -/* charmap.encoding_id = TT_MAC_ID_ROMAN; */ - } - - error = FT_CMap_New( fnt_cmap_class, - NULL, - &charmap, - NULL ); - if ( error ) - goto Fail; - - /* Select default charmap */ - if ( root->num_charmaps ) - root->charmap = root->charmaps[0]; - } - - /* set up remaining flags */ - - if ( font->header.last_char < font->header.first_char ) - { - FT_TRACE2(( "invalid number of glyphs\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - - /* reserve one slot for the .notdef glyph at index 0 */ - root->num_glyphs = font->header.last_char - - font->header.first_char + 1 + 1; - - if ( font->header.face_name_offset >= font->header.file_size ) - { - FT_TRACE2(( "invalid family name offset\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - family_size = font->header.file_size - font->header.face_name_offset; - /* Some broken fonts don't delimit the face name with a final */ - /* NULL byte -- the frame is erroneously one byte too small. */ - /* We thus allocate one more byte, setting it explicitly to */ - /* zero. */ - if ( FT_ALLOC( font->family_name, family_size + 1 ) ) - goto Fail; - - FT_MEM_COPY( font->family_name, - font->fnt_frame + font->header.face_name_offset, - family_size ); - - font->family_name[family_size] = '\0'; - - if ( FT_REALLOC( font->family_name, - family_size, - ft_strlen( font->family_name ) + 1 ) ) - goto Fail; - - root->family_name = font->family_name; - root->style_name = (char *)"Regular"; - - if ( root->style_flags & FT_STYLE_FLAG_BOLD ) - { - if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Bold Italic"; - else - root->style_name = (char *)"Bold"; - } - else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Italic"; - } - goto Exit; - - Fail: - FNT_Face_Done( fntface ); - - Exit: - return error; - } - - - static FT_Error - FNT_Size_Select( FT_Size size, - FT_ULong strike_index ) - { - FNT_Face face = (FNT_Face)size->face; - FT_WinFNT_Header header = &face->font->header; - - FT_UNUSED( strike_index ); - - - FT_Select_Metrics( size->face, 0 ); - - size->metrics.ascender = header->ascent * 64; - size->metrics.descender = -( header->pixel_height - - header->ascent ) * 64; - size->metrics.max_advance = header->max_width * 64; - - return FT_Err_Ok; - } - - - static FT_Error - FNT_Size_Request( FT_Size size, - FT_Size_Request req ) - { - FNT_Face face = (FNT_Face)size->face; - FT_WinFNT_Header header = &face->font->header; - FT_Bitmap_Size* bsize = size->face->available_sizes; - FT_Error error = FT_ERR( Invalid_Pixel_Size ); - FT_Long height; - - - height = FT_REQUEST_HEIGHT( req ); - height = ( height + 32 ) >> 6; - - switch ( req->type ) - { - case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) - error = FT_Err_Ok; - break; - - case FT_SIZE_REQUEST_TYPE_REAL_DIM: - if ( height == header->pixel_height ) - error = FT_Err_Ok; - break; - - default: - error = FT_THROW( Unimplemented_Feature ); - break; - } - - if ( error ) - return error; - else - return FNT_Size_Select( size, 0 ); - } - - - static FT_Error - FNT_Load_Glyph( FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); - FNT_Font font; - FT_Error error = FT_Err_Ok; - FT_Byte* p; - FT_Int len; - FT_Bitmap* bitmap = &slot->bitmap; - FT_ULong offset; - FT_Bool new_format; - - FT_UNUSED( load_flags ); - - - if ( !face ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - font = face->font; - - if ( !font || - glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - if ( glyph_index > 0 ) - glyph_index--; /* revert to real index */ - else - glyph_index = font->header.default_char; /* the .notdef glyph */ - - new_format = FT_BOOL( font->header.version == 0x300 ); - len = new_format ? 6 : 4; - - /* jump to glyph entry */ - p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index; - - bitmap->width = FT_NEXT_SHORT_LE( p ); - - if ( new_format ) - offset = FT_NEXT_ULONG_LE( p ); - else - offset = FT_NEXT_USHORT_LE( p ); - - if ( offset >= font->header.file_size ) - { - FT_TRACE2(( "invalid FNT offset\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* jump to glyph data */ - p = font->fnt_frame + /* font->header.bits_offset */ + offset; - - /* allocate and build bitmap */ - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - FT_Int pitch = ( bitmap->width + 7 ) >> 3; - FT_Byte* column; - FT_Byte* write; - - - bitmap->pitch = pitch; - bitmap->rows = font->header.pixel_height; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - - if ( offset + pitch * bitmap->rows >= font->header.file_size ) - { - FT_TRACE2(( "invalid bitmap width\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* note: since glyphs are stored in columns and not in rows we */ - /* can't use ft_glyphslot_set_bitmap */ - if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) ) - goto Exit; - - column = (FT_Byte*)bitmap->buffer; - - for ( ; pitch > 0; pitch--, column++ ) - { - FT_Byte* limit = p + bitmap->rows; - - - for ( write = column; p < limit; p++, write += bitmap->pitch ) - *write = *p; - } - } - - slot->internal->flags = FT_GLYPH_OWN_BITMAP; - slot->bitmap_left = 0; - slot->bitmap_top = font->header.ascent; - slot->format = FT_GLYPH_FORMAT_BITMAP; - - /* now set up metrics */ - slot->metrics.width = bitmap->width << 6; - slot->metrics.height = bitmap->rows << 6; - slot->metrics.horiAdvance = bitmap->width << 6; - slot->metrics.horiBearingX = 0; - slot->metrics.horiBearingY = slot->bitmap_top << 6; - - ft_synthesize_vertical_metrics( &slot->metrics, - bitmap->rows << 6 ); - - Exit: - return error; - } - - - static FT_Error - winfnt_get_header( FT_Face face, - FT_WinFNT_HeaderRec *aheader ) - { - FNT_Font font = ((FNT_Face)face)->font; - - - *aheader = font->header; - - return 0; - } - - - static const FT_Service_WinFntRec winfnt_service_rec = - { - winfnt_get_header - }; - - /* - * SERVICE LIST - * - */ - - static const FT_ServiceDescRec winfnt_services[] = - { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT }, - { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, - { NULL, NULL } - }; - - - static FT_Module_Interface - winfnt_get_service( FT_Module module, - const FT_String* service_id ) - { - FT_UNUSED( module ); - - return ft_service_list_lookup( winfnt_services, service_id ); - } - - - - - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec winfnt_driver_class = - { - { - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_NO_OUTLINES, - sizeof ( FT_DriverRec ), - - "winfonts", - 0x10000L, - 0x20000L, - - 0, - - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - winfnt_get_service - }, - - sizeof ( FNT_FaceRec ), - sizeof ( FT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - - FNT_Face_Init, - FNT_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ - - FNT_Load_Glyph, - - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ - - FNT_Size_Request, - FNT_Size_Select - }; - - -/* END */ diff --git a/drivers/freetype/freetype/src/winfonts/winfnt.h b/drivers/freetype/freetype/src/winfonts/winfnt.h deleted file mode 100644 index b7a80736d8..0000000000 --- a/drivers/freetype/freetype/src/winfonts/winfnt.h +++ /dev/null @@ -1,171 +0,0 @@ -/***************************************************************************/ -/* */ -/* winfnt.h */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ -/* */ -/* 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 __WINFNT_H__ -#define __WINFNT_H__ - - -#include <ft2build.h> -#include FT_WINFONTS_H -#include FT_INTERNAL_DRIVER_H - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - typedef struct WinMZ_HeaderRec_ - { - FT_UShort magic; - /* skipped content */ - FT_UShort lfanew; - - } WinMZ_HeaderRec; - - - typedef struct WinNE_HeaderRec_ - { - FT_UShort magic; - /* skipped content */ - FT_UShort resource_tab_offset; - FT_UShort rname_tab_offset; - - } WinNE_HeaderRec; - - - typedef struct WinPE32_HeaderRec_ - { - FT_ULong magic; - FT_UShort machine; - FT_UShort number_of_sections; - /* skipped content */ - FT_UShort size_of_optional_header; - /* skipped content */ - FT_UShort magic32; - /* skipped content */ - FT_ULong rsrc_virtual_address; - FT_ULong rsrc_size; - /* skipped content */ - - } WinPE32_HeaderRec; - - - typedef struct WinPE32_SectionRec_ - { - FT_Byte name[8]; - /* skipped content */ - FT_ULong virtual_address; - FT_ULong size_of_raw_data; - FT_ULong pointer_to_raw_data; - /* skipped content */ - - } WinPE32_SectionRec; - - - typedef struct WinPE_RsrcDirRec_ - { - FT_ULong characteristics; - FT_ULong time_date_stamp; - FT_UShort major_version; - FT_UShort minor_version; - FT_UShort number_of_named_entries; - FT_UShort number_of_id_entries; - - } WinPE_RsrcDirRec; - - - typedef struct WinPE_RsrcDirEntryRec_ - { - FT_ULong name; - FT_ULong offset; - - } WinPE_RsrcDirEntryRec; - - - typedef struct WinPE_RsrcDataEntryRec_ - { - FT_ULong offset_to_data; - FT_ULong size; - FT_ULong code_page; - FT_ULong reserved; - - } WinPE_RsrcDataEntryRec; - - - typedef struct WinNameInfoRec_ - { - FT_UShort offset; - FT_UShort length; - FT_UShort flags; - FT_UShort id; - FT_UShort handle; - FT_UShort usage; - - } WinNameInfoRec; - - - typedef struct WinResourceInfoRec_ - { - FT_UShort type_id; - FT_UShort count; - - } WinResourceInfoRec; - - -#define WINFNT_MZ_MAGIC 0x5A4D -#define WINFNT_NE_MAGIC 0x454E -#define WINFNT_PE_MAGIC 0x4550 - - - typedef struct FNT_FontRec_ - { - FT_ULong offset; - - FT_WinFNT_HeaderRec header; - - FT_Byte* fnt_frame; - FT_ULong fnt_size; - FT_String* family_name; - - } FNT_FontRec, *FNT_Font; - - - typedef struct FNT_FaceRec_ - { - FT_FaceRec root; - FNT_Font font; - - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ - - } FNT_FaceRec, *FNT_Face; - - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) winfnt_driver_class; - - -FT_END_HEADER - - -#endif /* __WINFNT_H__ */ - - -/* END */ diff --git a/drivers/freetype/include/freetype/config/ftconfig.h b/drivers/freetype/include/freetype/config/ftconfig.h new file mode 100644 index 0000000000..5dce30ef3e --- /dev/null +++ b/drivers/freetype/include/freetype/config/ftconfig.h @@ -0,0 +1,598 @@ +/***************************************************************************/ +/* */ +/* ftconfig.h */ +/* */ +/* ANSI-specific configuration file (specification only). */ +/* */ +/* Copyright 1996-2004, 2006-2008, 2010-2011, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This header file contains a number of macro definitions that are used */ + /* by the rest of the engine. Most of the macros here are automatically */ + /* determined at compile time, and you should not need to change it to */ + /* port FreeType, except to compile the library with a non-ANSI */ + /* compiler. */ + /* */ + /* Note however that if some specific modifications are needed, we */ + /* advise you to place a modified copy in your build directory. */ + /* */ + /* The build directory is usually `freetype/builds/<system>', and */ + /* contains system-specific files that are always included first when */ + /* building the library. */ + /* */ + /* This ANSI version should stay in `include/freetype/config'. */ + /* */ + /*************************************************************************/ + +#ifndef __FTCONFIG_H__ +#define __FTCONFIG_H__ + +#include <ft2build.h> +#include FT_CONFIG_OPTIONS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ + /* */ + /* These macros can be toggled to suit a specific system. The current */ + /* ones are defaults used to compile FreeType in an ANSI C environment */ + /* (16bit compilers are also supported). Copy this file to your own */ + /* `freetype/builds/<system>' directory, and edit it to port the engine. */ + /* */ + /*************************************************************************/ + + + /* There are systems (like the Texas Instruments 'C54x) where a `char' */ + /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ + /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ + /* is probably unexpected. */ + /* */ + /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ + /* `char' type. */ + +#ifndef FT_CHAR_BIT +#define FT_CHAR_BIT CHAR_BIT +#endif + + + /* The size of an `int' type. */ +#if FT_UINT_MAX == 0xFFFFUL +#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) +#elif FT_UINT_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) +#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `int' type!" +#endif + + /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ + /* DM642) is recognized but avoided. */ +#if FT_ULONG_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `long' type!" +#endif + + + /* FT_UNUSED is a macro used to indicate that a given parameter is not */ + /* used -- this is only used to get rid of unpleasant compiler warnings */ +#ifndef FT_UNUSED +#define FT_UNUSED( arg ) ( (arg) = (arg) ) +#endif + + + /*************************************************************************/ + /* */ + /* AUTOMATIC CONFIGURATION MACROS */ + /* */ + /* These macros are computed from the ones defined above. Don't touch */ + /* their definition, unless you know precisely what you are doing. No */ + /* porter should need to mess with them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Mac support */ + /* */ + /* This is the only necessary change, so it is defined here instead */ + /* providing a new configuration file. */ + /* */ +#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) + /* no Carbon frameworks for 64bit 10.4.x */ + /* AvailabilityMacros.h is available since Mac OS X 10.2, */ + /* so guess the system version by maximum errno before inclusion */ +#include <errno.h> +#ifdef ECANCELED /* defined since 10.2 */ +#include "AvailabilityMacros.h" +#endif +#if defined( __LP64__ ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) +#undef FT_MACINTOSH +#endif + +#elif defined( __SC__ ) || defined( __MRC__ ) + /* Classic MacOS compilers */ +#include "ConditionalMacros.h" +#if TARGET_OS_MAC +#define FT_MACINTOSH 1 +#endif + +#endif + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int16 */ + /* */ + /* <Description> */ + /* A typedef for a 16bit signed integer type. */ + /* */ + typedef signed short FT_Int16; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt16 */ + /* */ + /* <Description> */ + /* A typedef for a 16bit unsigned integer type. */ + /* */ + typedef unsigned short FT_UInt16; + + /* */ + + + /* this #if 0 ... #endif clause is for documentation purposes */ +#if 0 + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int32 */ + /* */ + /* <Description> */ + /* A typedef for a 32bit signed integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef signed XXX FT_Int32; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt32 */ + /* */ + /* A typedef for a 32bit unsigned integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef unsigned XXX FT_UInt32; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int64 */ + /* */ + /* A typedef for a 64bit signed integer type. The size depends on */ + /* the configuration. Only defined if there is real 64bit support; */ + /* otherwise, it gets emulated with a structure (if necessary). */ + /* */ + typedef signed XXX FT_Int64; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt64 */ + /* */ + /* A typedef for a 64bit unsigned integer type. The size depends on */ + /* the configuration. Only defined if there is real 64bit support; */ + /* otherwise, it gets emulated with a structure (if necessary). */ + /* */ + typedef unsigned XXX FT_UInt64; + + /* */ + +#endif + +#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) + + typedef signed int FT_Int32; + typedef unsigned int FT_UInt32; + +#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) + + typedef signed long FT_Int32; + typedef unsigned long FT_UInt32; + +#else +#error "no 32bit type found -- please check your configuration files" +#endif + + + /* look up an integer type that is at least 32 bits */ +#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) + + typedef int FT_Fast; + typedef unsigned int FT_UFast; + +#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) + + typedef long FT_Fast; + typedef unsigned long FT_UFast; + +#endif + + + /* determine whether we have a 64-bit int type for platforms without */ + /* Autoconf */ +#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) + + /* FT_LONG64 must be defined if a 64-bit type is available */ +#define FT_LONG64 +#define FT_INT64 long +#define FT_UINT64 unsigned long + +#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 +#define FT_UINT64 unsigned __int64 + +#elif defined( __BORLANDC__ ) /* Borland C++ */ + + /* XXXX: We should probably check the value of __BORLANDC__ in order */ + /* to test the compiler version. */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 +#define FT_UINT64 unsigned __int64 + +#elif defined( __WATCOMC__ ) /* Watcom C++ */ + + /* Watcom doesn't provide 64-bit data types */ + +#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ + +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#elif defined( __GNUC__ ) + + /* GCC provides the `long long' type */ +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ + + + /*************************************************************************/ + /* */ + /* A 64-bit data type will create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ + /* is defined. You can however ignore this rule by defining the */ + /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#ifdef __STDC__ + + /* undefine the 64-bit macros in strict ANSI compilation mode */ +#undef FT_LONG64 +#undef FT_INT64 + +#endif /* __STDC__ */ + +#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ + +#ifdef FT_LONG64 + typedef FT_INT64 FT_Int64; + typedef FT_UINT64 FT_UInt64; +#endif + + +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) +#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT + + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + /* Provide assembler fragments for performance-critical functions. */ + /* These must be defined `static __inline__' with GCC. */ + +#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x8000 /* a += 0x8000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #16 /* a = t2 >> 16 */ + orr a, a, t, lsl #16 /* a |= t << 16 */ + } + return a; + } + +#endif /* __CC_ARM || __ARMCC__ */ + + +#ifdef __GNUC__ + +#if defined( __arm__ ) && !defined( __thumb__ ) && \ + !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + __asm__ __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ + "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ + "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) + : "cc" ); + return a; + } + +#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */ + +#if defined( __i386__ ) +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 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" + : "=a"(result), "=d"(b) + : "a"(a), "d"(b) + : "%ecx", "cc" ); + return result; + } + +#endif /* i386 */ + +#endif /* __GNUC__ */ + + +#ifdef _MSC_VER /* Visual C++ */ + +#ifdef _M_IX86 + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 result; + + __asm + { + mov eax, a + mov edx, b + imul edx + mov ecx, edx + sar ecx, 31 + add ecx, 8000h + add eax, ecx + adc edx, 0 + shr eax, 16 + shl edx, 16 + add eax, edx + mov result, eax + } + return result; + } + +#endif /* _M_IX86 */ + +#endif /* _MSC_VER */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX +#ifdef FT_MULFIX_ASSEMBLER +#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER +#endif +#endif + + +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT + +#define FT_LOCAL( x ) static x +#define FT_LOCAL_DEF( x ) static x + +#else + +#ifdef __cplusplus +#define FT_LOCAL( x ) extern "C" x +#define FT_LOCAL_DEF( x ) extern "C" x +#else +#define FT_LOCAL( x ) extern x +#define FT_LOCAL_DEF( x ) x +#endif + +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ + + +#ifndef FT_BASE + +#ifdef __cplusplus +#define FT_BASE( x ) extern "C" x +#else +#define FT_BASE( x ) extern x +#endif + +#endif /* !FT_BASE */ + + +#ifndef FT_BASE_DEF + +#ifdef __cplusplus +#define FT_BASE_DEF( x ) x +#else +#define FT_BASE_DEF( x ) x +#endif + +#endif /* !FT_BASE_DEF */ + + +#ifndef FT_EXPORT + +#ifdef __cplusplus +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif /* !FT_EXPORT */ + + +#ifndef FT_EXPORT_DEF + +#ifdef __cplusplus +#define FT_EXPORT_DEF( x ) extern "C" x +#else +#define FT_EXPORT_DEF( x ) extern x +#endif + +#endif /* !FT_EXPORT_DEF */ + + +#ifndef FT_EXPORT_VAR + +#ifdef __cplusplus +#define FT_EXPORT_VAR( x ) extern "C" x +#else +#define FT_EXPORT_VAR( x ) extern x +#endif + +#endif /* !FT_EXPORT_VAR */ + + /* The following macros are needed to compile the library with a */ + /* C++ compiler and with 16bit compilers. */ + /* */ + + /* This is special. Within C++, you must specify `extern "C"' for */ + /* functions which are used via function pointers, and you also */ + /* must do that for structures which contain function pointers to */ + /* assure C linkage -- it's not possible to have (local) anonymous */ + /* functions which are accessed by (global) function pointers. */ + /* */ + /* */ + /* FT_CALLBACK_DEF is used to _define_ a callback function. */ + /* */ + /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ + /* contains pointers to callback functions. */ + /* */ + /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ + /* that contains pointers to callback functions. */ + /* */ + /* */ + /* Some 16bit compilers have to redefine these macros to insert */ + /* the infamous `_cdecl' or `__fastcall' declarations. */ + /* */ +#ifndef FT_CALLBACK_DEF +#ifdef __cplusplus +#define FT_CALLBACK_DEF( x ) extern "C" x +#else +#define FT_CALLBACK_DEF( x ) static x +#endif +#endif /* FT_CALLBACK_DEF */ + +#ifndef FT_CALLBACK_TABLE +#ifdef __cplusplus +#define FT_CALLBACK_TABLE extern "C" +#define FT_CALLBACK_TABLE_DEF extern "C" +#else +#define FT_CALLBACK_TABLE extern +#define FT_CALLBACK_TABLE_DEF /* nothing */ +#endif +#endif /* FT_CALLBACK_TABLE */ + + +FT_END_HEADER + + +#endif /* __FTCONFIG_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/config/ftheader.h b/drivers/freetype/include/freetype/config/ftheader.h new file mode 100644 index 0000000000..8371a31611 --- /dev/null +++ b/drivers/freetype/include/freetype/config/ftheader.h @@ -0,0 +1,832 @@ +/***************************************************************************/ +/* */ +/* ftheader.h */ +/* */ +/* Build macros of the FreeType 2 library. */ +/* */ +/* Copyright 1996-2008, 2010, 2012, 2013 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_HEADER_H__ +#define __FT_HEADER_H__ + + + /*@***********************************************************************/ + /* */ + /* <Macro> */ + /* FT_BEGIN_HEADER */ + /* */ + /* <Description> */ + /* This macro is used in association with @FT_END_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_BEGIN_HEADER extern "C" { +#else +#define FT_BEGIN_HEADER /* nothing */ +#endif + + + /*@***********************************************************************/ + /* */ + /* <Macro> */ + /* FT_END_HEADER */ + /* */ + /* <Description> */ + /* This macro is used in association with @FT_BEGIN_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_END_HEADER } +#else +#define FT_END_HEADER /* nothing */ +#endif + + + /*************************************************************************/ + /* */ + /* Aliases for the FreeType 2 public and configuration files. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Section> */ + /* header_file_macros */ + /* */ + /* <Title> */ + /* Header File Macros */ + /* */ + /* <Abstract> */ + /* Macro definitions used to #include specific header files. */ + /* */ + /* <Description> */ + /* The following macros are defined to the name of specific */ + /* FreeType~2 header files. They can be used directly in #include */ + /* statements as in: */ + /* */ + /* { */ + /* #include FT_FREETYPE_H */ + /* #include FT_MULTIPLE_MASTERS_H */ + /* #include FT_GLYPH_H */ + /* } */ + /* */ + /* There are several reasons why we are now using macros to name */ + /* public header files. The first one is that such macros are not */ + /* 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 it allows for more flexibility in the */ + /* way FreeType~2 is installed on a given system. */ + /* */ + /*************************************************************************/ + + + /* configuration files */ + + /************************************************************************* + * + * @macro: + * FT_CONFIG_CONFIG_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 configuration data. + * + */ +#ifndef FT_CONFIG_CONFIG_H +#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_STANDARD_LIBRARY_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 interface to the standard C library functions. + * + */ +#ifndef FT_CONFIG_STANDARD_LIBRARY_H +#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_OPTIONS_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 project-specific configuration options. + * + */ +#ifndef FT_CONFIG_OPTIONS_H +#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_MODULES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 modules that are statically linked to new library + * instances in @FT_Init_FreeType. + * + */ +#ifndef FT_CONFIG_MODULES_H +#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h> +#endif + + /* */ + + /* public headers */ + + /************************************************************************* + * + * @macro: + * FT_FREETYPE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * base FreeType~2 API. + * + */ +#define FT_FREETYPE_H <freetype/freetype.h> + + + /************************************************************************* + * + * @macro: + * FT_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 error codes (and messages). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_ERRORS_H <freetype/fterrors.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 module error offsets (and messages). + * + */ +#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> + + + /************************************************************************* + * + * @macro: + * FT_SYSTEM_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 interface to low-level operations (i.e., memory management + * and stream i/o). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_SYSTEM_H <freetype/ftsystem.h> + + + /************************************************************************* + * + * @macro: + * FT_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing type + * definitions related to glyph images (i.e., bitmaps, outlines, + * scan-converter parameters). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_IMAGE_H <freetype/ftimage.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * basic data types defined by FreeType~2. + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_TYPES_H <freetype/fttypes.h> + + + /************************************************************************* + * + * @macro: + * FT_LIST_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list management API of FreeType~2. + * + * (Most applications will never need to include this file.) + * + */ +#define FT_LIST_H <freetype/ftlist.h> + + + /************************************************************************* + * + * @macro: + * FT_OUTLINE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * scalable outline management API of FreeType~2. + * + */ +#define FT_OUTLINE_H <freetype/ftoutln.h> + + + /************************************************************************* + * + * @macro: + * FT_SIZES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API which manages multiple @FT_Size objects per face. + * + */ +#define FT_SIZES_H <freetype/ftsizes.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * module management API of FreeType~2. + * + */ +#define FT_MODULE_H <freetype/ftmodapi.h> + + + /************************************************************************* + * + * @macro: + * FT_RENDER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * renderer module management API of FreeType~2. + * + */ +#define FT_RENDER_H <freetype/ftrender.h> + + + /************************************************************************* + * + * @macro: + * FT_AUTOHINTER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the auto-hinting module. + * + */ +#define FT_AUTOHINTER_H <freetype/ftautoh.h> + + + /************************************************************************* + * + * @macro: + * FT_CFF_DRIVER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the CFF driver module. + * + */ +#define FT_CFF_DRIVER_H <freetype/ftcffdrv.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_DRIVER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the TrueType driver module. + * + */ +#define FT_TRUETYPE_DRIVER_H <freetype/ftttdrv.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPE1_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the Type~1 format. + * + */ +#define FT_TYPE1_TABLES_H <freetype/t1tables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_IDS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * 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> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the TrueType (as well as OpenType) format. + * + */ +#define FT_TRUETYPE_TABLES_H <freetype/tttables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TAGS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of TrueType four-byte `tags' which identify blocks in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_TRUETYPE_TAGS_H <freetype/tttags.h> + + + /************************************************************************* + * + * @macro: + * FT_BDF_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which accesses BDF-specific strings from a + * face. + * + */ +#define FT_BDF_H <freetype/ftbdf.h> + + + /************************************************************************* + * + * @macro: + * FT_CID_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which access CID font information from a + * face. + * + */ +#define FT_CID_H <freetype/ftcid.h> + + + /************************************************************************* + * + * @macro: + * FT_GZIP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports gzip-compressed files. + * + */ +#define FT_GZIP_H <freetype/ftgzip.h> + + + /************************************************************************* + * + * @macro: + * FT_LZW_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports LZW-compressed files. + * + */ +#define FT_LZW_H <freetype/ftlzw.h> + + + /************************************************************************* + * + * @macro: + * FT_BZIP2_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports bzip2-compressed files. + * + */ +#define FT_BZIP2_H <freetype/ftbzip2.h> + + + /************************************************************************* + * + * @macro: + * FT_WINFONTS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports Windows FNT files. + * + */ +#define FT_WINFONTS_H <freetype/ftwinfnt.h> + + + /************************************************************************* + * + * @macro: + * FT_GLYPH_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional glyph management component. + * + */ +#define FT_GLYPH_H <freetype/ftglyph.h> + + + /************************************************************************* + * + * @macro: + * FT_BITMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional bitmap conversion component. + * + */ +#define FT_BITMAP_H <freetype/ftbitmap.h> + + + /************************************************************************* + * + * @macro: + * FT_BBOX_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional exact bounding box computation routines. + * + */ +#define FT_BBOX_H <freetype/ftbbox.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional FreeType~2 cache sub-system. + * + */ +#define FT_CACHE_H <freetype/ftcache.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `glyph image' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for @FT_Glyph elements. You can also + * 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 + * glyph image-related cache declarations. + * + */ +#define FT_CACHE_IMAGE_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_SMALL_BITMAPS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `small bitmaps' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for small glyph bitmaps in a relatively + * memory-efficient way. You can also use the API defined in + * @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, + * including scalable outlines. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * small bitmaps-related cache declarations. + * + */ +#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_CHARMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `charmap' API of the FreeType~2 cache sub-system. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * charmap-based cache declarations. + * + */ +#define FT_CACHE_CHARMAP_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_MAC_H + * + * @description: + * A macro used in #include statements to name the file containing the + * Macintosh-specific FreeType~2 API. The latter is used to access + * fonts embedded in resource forks. + * + * This header file must be explicitly included by client applications + * compiled on the Mac (note that the base API still works though). + * + */ +#define FT_MAC_H <freetype/ftmac.h> + + + /************************************************************************* + * + * @macro: + * FT_MULTIPLE_MASTERS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional multiple-masters management API of FreeType~2. + * + */ +#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> + + + /************************************************************************* + * + * @macro: + * FT_SFNT_NAMES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which accesses embedded `name' strings in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_SFNT_NAMES_H <freetype/ftsnames.h> + + + /************************************************************************* + * + * @macro: + * FT_OPENTYPE_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, + * GPOS, GSUB, JSTF). + * + */ +#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h> + + + /************************************************************************* + * + * @macro: + * FT_GX_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, + * mort, morx, bsln, just, kern, opbd, trak, prop). + * + */ +#define FT_GX_VALIDATE_H <freetype/ftgxval.h> + + + /************************************************************************* + * + * @macro: + * FT_PFR_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which accesses PFR-specific data. + * + */ +#define FT_PFR_H <freetype/ftpfr.h> + + + /************************************************************************* + * + * @macro: + * FT_STROKER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions to stroke outline paths. + */ +#define FT_STROKER_H <freetype/ftstroke.h> + + + /************************************************************************* + * + * @macro: + * FT_SYNTHESIS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs artificial obliquing and emboldening. + */ +#define FT_SYNTHESIS_H <freetype/ftsynth.h> + + + /************************************************************************* + * + * @macro: + * FT_XFREE86_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions specific to the XFree86 and + * X.Org X11 servers. + */ +#define FT_XFREE86_H <freetype/ftxf86.h> + + + /************************************************************************* + * + * @macro: + * FT_TRIGONOMETRY_H + * + * @description: + * A macro used in #include statements to name the file containing the + * 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_UNPATENTED_HINTING_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_UNPATENTED_HINTING_H <freetype/ttunpat.h> + + + /************************************************************************* + * + * @macro: + * FT_INCREMENTAL_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_INCREMENTAL_H <freetype/ftincrem.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> + + + /************************************************************************* + * + * @macro: + * FT_ADVANCES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns individual and ranged glyph advances. + */ +#define FT_ADVANCES_H <freetype/ftadvanc.h> + + + /* */ + +#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h> + + + /* The internals of the cache sub-system are no longer exposed. We */ + /* default to FT_CACHE_H at the moment just in case, but we know of */ + /* no rogue client that uses them. */ + /* */ +#define FT_CACHE_MANAGER_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_MRU_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_MANAGER_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_CACHE_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_GLYPH_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_IMAGE_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_SBITS_H <freetype/ftcache.h> + + +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + +#define FT_TRUETYPE_UNPATENTED_H <freetype/ttunpat.h> + + + /* + * Include internal headers definitions from <freetype/internal/...> + * only when building the library. + */ +#ifdef FT2_BUILD_LIBRARY +#define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> +#include FT_INTERNAL_INTERNAL_H +#endif /* FT2_BUILD_LIBRARY */ + + +#endif /* __FT2_BUILD_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/config/ftmodule.h b/drivers/freetype/include/freetype/config/ftmodule.h new file mode 100644 index 0000000000..76d271a74b --- /dev/null +++ b/drivers/freetype/include/freetype/config/ftmodule.h @@ -0,0 +1,32 @@ +/* + * This file registers the FreeType modules compiled into the library. + * + * If you use GNU make, this file IS NOT USED! Instead, it is created in + * the objects directory (normally `<topdir>/objs/') based on information + * from `<topdir>/modules.cfg'. + * + * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile + * FreeType without GNU make. + * + */ + +FT_USE_MODULE( FT_Module_Class, autofit_module_class ) +FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) +FT_USE_MODULE( FT_Module_Class, psaux_module_class ) +FT_USE_MODULE( FT_Module_Class, psnames_module_class ) +FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) +FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) +FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) + +/* EOF */ diff --git a/drivers/freetype/include/freetype/config/ftoption.h b/drivers/freetype/include/freetype/config/ftoption.h new file mode 100644 index 0000000000..b9d840b41f --- /dev/null +++ b/drivers/freetype/include/freetype/config/ftoption.h @@ -0,0 +1,833 @@ +/***************************************************************************/ +/* */ +/* ftoption.h */ +/* */ +/* User-selectable configuration macros (specification only). */ +/* */ +/* Copyright 1996-2013 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 __FTOPTION_H__ +#define __FTOPTION_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* USER-SELECTABLE CONFIGURATION MACROS */ + /* */ + /* This file contains the default configuration macro definitions for */ + /* a standard build of the FreeType library. There are three ways to */ + /* use this file to build project-specific versions of the library: */ + /* */ + /* - You can modify this file by hand, but this is not recommended in */ + /* cases where you would like to build several versions of the */ + /* library from a single source directory. */ + /* */ + /* - You can put a copy of this file in your build directory, more */ + /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ + /* is the name of a directory that is included _before_ the FreeType */ + /* include path during compilation. */ + /* */ + /* The default FreeType Makefiles and Jamfiles use the build */ + /* directory `builds/<system>' by default, but you can easily change */ + /* that for your own projects. */ + /* */ + /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ + /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ + /* locate this file during the build. For example, */ + /* */ + /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ + /* #include <freetype/config/ftheader.h> */ + /* */ + /* will use `$BUILD/myftoptions.h' instead of this file for macro */ + /* definitions. */ + /* */ + /* Note also that you can similarly pre-define the macro */ + /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ + /* that are statically linked to the library at compile time. By */ + /* default, this file is <freetype/config/ftmodule.h>. */ + /* */ + /* We highly recommend using the third method whenever possible. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* 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 wider than */ + /* the original size in case this macro isn't defined; however, 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 */ + /* by FreeType to speed up some computations. However, this will create */ + /* some problems when compiling the library in strict ANSI mode. */ + /* */ + /* For this reason, the use of 64-bit integers is normally disabled when */ + /* the __STDC__ macro is defined. You can however disable this by */ + /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ + /* */ + /* For most compilers, this will only create compilation warnings when */ + /* building the library. */ + /* */ + /* ObNote: The compiler-specific 64-bit integers are detected in the */ + /* file `ftconfig.h' either statically or through the */ + /* `configure' script on supported platforms. */ + /* */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* If this macro is defined, do not try to use an assembler version of */ + /* performance-critical functions (e.g. FT_MulFix). You should only do */ + /* that to verify that the assembler function works properly, or to */ + /* execute benchmark tests of the various implementations. */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + + + /*************************************************************************/ + /* */ + /* If this macro is defined, try to use an inlined assembler version of */ + /* the `FT_MulFix' function, which is a `hotspot' when loading and */ + /* hinting glyphs, and which should be executed as fast as possible. */ + /* */ + /* Note that if your compiler or CPU is not supported, this will default */ + /* to the standard and portable implementation found in `ftcalc.c'. */ + /* */ +#define FT_CONFIG_OPTION_INLINE_MULFIX + + + /*************************************************************************/ + /* */ + /* LZW-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `compress' program. This is mostly used to parse many of the PCF */ + /* files that come with various X11 distributions. The implementation */ + /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ + /* (see src/lzw/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_LZW */ // -GODOT- + + + /*************************************************************************/ + /* */ + /* Gzip-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses `zlib' to */ + /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. See also */ + /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_ZLIB */ // -GODOT- + + + /*************************************************************************/ + /* */ + /* ZLib library selection */ + /* */ + /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ + /* It allows FreeType's `ftgzip' component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ + /* Unix or VMS where it generally is already available. */ + /* */ + /* If you let it undefined, the component will use its own copy */ + /* of the zlib sources instead. These have been modified to be */ + /* included directly within the component and *not* export external */ + /* function names. This allows you to link any program with FreeType */ + /* _and_ ZLib without linking conflicts. */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + + /*************************************************************************/ + /* */ + /* Bzip2-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `bzip2' program. This is mostly used to parse many of the PCF */ + /* files that come with XFree86. The implementation uses `libbz2' to */ + /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ + /* Contrary to gzip, bzip2 currently is not included and need to use */ + /* the system available bzip2 implementation. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_BZIP2 */ + + + /*************************************************************************/ + /* */ + /* Define to disable the use of file stream functions and types, FILE, */ + /* fopen() etc. Enables the use of smaller system libraries on embedded */ + /* systems that have multiple system libraries, some with or without */ + /* file stream support, in the cases where file stream support is not */ + /* necessary such as memory loading of font files. */ + /* */ +/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ + + + /*************************************************************************/ + /* */ + /* PNG bitmap support. */ + /* */ + /* FreeType now handles loading color bitmap glyphs in the PNG format. */ + /* This requires help from the external libpng library. Uncompressed */ + /* color bitmaps do not need any external libraries and will be */ + /* supported regardless of this configuration. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_PNG */ + + + /*************************************************************************/ + /* */ + /* DLL export compilation */ + /* */ + /* When compiling FreeType as a DLL, some systems/compilers need a */ + /* special keyword in front OR after the return type of function */ + /* declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ + /* will be later automatically defined as `extern return_type' to */ + /* allow normal compilation. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ + + + /*************************************************************************/ + /* */ + /* Glyph Postscript Names handling */ + /* */ + /* By default, FreeType 2 is compiled with the `psnames' module. This */ + /* module is in charge of converting a glyph name string into a */ + /* Unicode value, or return a Macintosh standard glyph name for the */ + /* use with the TrueType `post' table. */ + /* */ + /* Undefine this macro if you do not want `psnames' compiled in your */ + /* build of FreeType. This has the following effects: */ + /* */ + /* - The TrueType driver will provide its own set of glyph names, */ + /* if you build it to support postscript names in the TrueType */ + /* `post' table. */ + /* */ + /* - The Type 1 driver will not be able to synthesize a Unicode */ + /* charmap out of the glyphs found in the fonts. */ + /* */ + /* You would normally undefine this configuration macro when building */ + /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ + /* */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Postscript Names to Unicode Values support */ + /* */ + /* By default, FreeType 2 is built with the `PSNames' module compiled */ + /* in. Among other things, the module is used to convert a glyph name */ + /* into a Unicode value. This is especially useful in order to */ + /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* through a big table named the `Adobe Glyph List' (AGL). */ + /* */ + /* Undefine this macro if you do not want the Adobe Glyph List */ + /* compiled in your `PSNames' module. The Type 1 driver will not be */ + /* able to synthesize a Unicode charmap out of the glyphs found in the */ + /* fonts. */ + /* */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /*************************************************************************/ + /* */ + /* Support for Mac fonts */ + /* */ + /* Define this macro if you want support for outline fonts in Mac */ + /* format (mac dfont, mac resource, macbinary containing a mac */ + /* resource) on non-Mac platforms. */ + /* */ + /* Note that the `FOND' resource isn't checked. */ + /* */ +#define FT_CONFIG_OPTION_MAC_FONTS + + + /*************************************************************************/ + /* */ + /* Guessing methods to access embedded resource forks */ + /* */ + /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ + /* GNU/Linux). */ + /* */ + /* Resource forks which include fonts data are stored sometimes in */ + /* locations which users or developers don't expected. In some cases, */ + /* resource forks start with some offset from the head of a file. In */ + /* other cases, the actual resource fork is stored in file different */ + /* from what the user specifies. If this option is activated, */ + /* FreeType tries to guess whether such offsets or different file */ + /* names must be used. */ + /* */ + /* Note that normal, direct access of resource forks is controlled via */ + /* the FT_CONFIG_OPTION_MAC_FONTS option. */ + /* */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + + + /*************************************************************************/ + /* */ + /* Allow the use of FT_Incremental_Interface to load typefaces that */ + /* contain no glyph data, but supply it via a callback function. */ + /* This is required by clients supporting document formats which */ + /* supply font data incrementally as the document is parsed, such */ + /* as the Ghostscript interpreter for the PostScript language. */ + /* */ +#define FT_CONFIG_OPTION_INCREMENTAL + + + /*************************************************************************/ + /* */ + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ + /* */ + /* This must be greater than 4KByte if you use FreeType to rasterize */ + /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ + /* allocation of the render pool. */ + /* */ +#define FT_RENDER_POOL_SIZE 16384L + + + /*************************************************************************/ + /* */ + /* FT_MAX_MODULES */ + /* */ + /* The maximum number of modules that can be registered in a single */ + /* FreeType library object. 32 is the default. */ + /* */ +#define FT_MAX_MODULES 32 + + + /*************************************************************************/ + /* */ + /* Debug level */ + /* */ + /* FreeType can be compiled in debug or trace mode. In debug mode, */ + /* errors are reported through the `ftdebug' component. In trace */ + /* mode, additional messages are sent to the standard output during */ + /* execution. */ + /* */ + /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ + /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ + /* */ + /* Don't define any of these macros to compile in `release' mode! */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Autofitter debugging */ + /* */ + /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ + /* control the autofitter behaviour for debugging purposes with global */ + /* boolean variables (consequently, you should *never* enable this */ + /* while compiling in `release' mode): */ + /* */ + /* _af_debug_disable_horz_hints */ + /* _af_debug_disable_vert_hints */ + /* _af_debug_disable_blue_hints */ + /* */ + /* Additionally, the following functions provide dumps of various */ + /* internal autofit structures to stdout (using `printf'): */ + /* */ + /* af_glyph_hints_dump_points */ + /* af_glyph_hints_dump_segments */ + /* af_glyph_hints_dump_edges */ + /* */ + /* As an argument, they use another global variable: */ + /* */ + /* _af_debug_hints */ + /* */ + /* Please have a look at the `ftgrid' demo program to see how those */ + /* variables and macros should be used. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_AUTOFIT */ + + + /*************************************************************************/ + /* */ + /* Memory Debugging */ + /* */ + /* FreeType now comes with an integrated memory debugger that is */ + /* capable of detecting simple errors like memory leaks or double */ + /* deletes. To compile it within your build of the library, you */ + /* should define FT_DEBUG_MEMORY here. */ + /* */ + /* Note that the memory debugger is only activated at runtime when */ + /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_DEBUG_MEMORY */ + + + /*************************************************************************/ + /* */ + /* Module errors */ + /* */ + /* If this macro is set (which is _not_ the default), the higher byte */ + /* of an error code gives the module in which the error has occurred, */ + /* while the lower byte is the real error code. */ + /* */ + /* Setting this macro makes sense for debugging purposes only, since */ + /* it would break source compatibility of certain programs that use */ + /* FreeType 2. */ + /* */ + /* More details can be found in the files ftmoderr.h and fterrors.h. */ + /* */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + + + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ + /* embedded bitmaps in all formats using the SFNT module (namely */ + /* TrueType & OpenType). */ + /* */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ + /* load and enumerate the glyph Postscript names in a TrueType or */ + /* OpenType file. */ + /* */ + /* Note that when you do not compile the `PSNames' module by undefining */ + /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ + /* contain additional code used to read the PS Names table from a font. */ + /* */ + /* (By default, the module uses `PSNames' to extract glyph names.) */ + /* */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ + /* access the internal name table in a SFNT-based format like TrueType */ + /* or OpenType. The name table contains various strings used to */ + /* describe the font, like family name, copyright, version, etc. It */ + /* does not contain any glyph name though. */ + /* */ + /* Accessing SFNT names is done through the functions declared in */ + /* `freetype/ftsnames.h'. */ + /* */ +#define TT_CONFIG_OPTION_SFNT_NAMES + + + /*************************************************************************/ + /* */ + /* TrueType CMap support */ + /* */ + /* Here you can fine-tune which TrueType CMap table format shall be */ + /* supported. */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ + /* a bytecode interpreter in the TrueType driver. */ + /* */ + /* By undefining this, you will only compile the code necessary to load */ + /* TrueType glyphs without hinting. */ + /* */ + /* Do not #undef this macro here, since the build system might */ + /* define it for certain configurations only. */ + /* */ +#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ + /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ + /* replaces the native TrueType hinting mechanism when anything but */ + /* FT_RENDER_MODE_MONO is requested. */ + /* */ + /* Enabling this causes the TrueType driver to ignore instructions under */ + /* certain conditions. This is done in accordance with the guide here, */ + /* with some minor differences: */ + /* */ + /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ + /* */ + /* By undefining this, you only compile the code necessary to hint */ + /* TrueType glyphs with native TT hinting. */ + /* */ + /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ + /* defined. */ + /* */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + + /*************************************************************************/ + /* */ + /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ + /* of the TrueType bytecode interpreter is used that doesn't implement */ + /* any of the patented opcodes and algorithms. The patents related to */ + /* TrueType hinting have expired worldwide since May 2010; this option */ + /* is now deprecated. */ + /* */ + /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ + /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ + /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ + /* */ + /* This macro is only useful for a small number of font files (mostly */ + /* for Asian scripts) that require bytecode interpretation to properly */ + /* load glyphs. For all other fonts, this produces unpleasant results, */ + /* thus the unpatented interpreter is never used to load glyphs from */ + /* TrueType fonts unless one of the following two options is used. */ + /* */ + /* - The unpatented interpreter is explicitly activated by the user */ + /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ + /* when opening the FT_Face. */ + /* */ + /* - FreeType detects that the FT_Face corresponds to one of the */ + /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ + /* contains a hard-coded list of font names and other matching */ + /* parameters (see function `tt_face_init' in file */ + /* `src/truetype/ttobjs.c'). */ + /* */ + /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ + /* */ + /* { */ + /* FT_Parameter parameter; */ + /* FT_Open_Args open_args; */ + /* */ + /* */ + /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ + /* */ + /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ + /* open_args.pathname = my_font_pathname; */ + /* open_args.num_params = 1; */ + /* open_args.params = ¶meter; */ + /* */ + /* error = FT_Open_Face( library, &open_args, index, &face ); */ + /* ... */ + /* } */ + /* */ +/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ + /* bytecode interpreter with a huge switch statement, rather than a call */ + /* table. This results in smaller and faster code for a number of */ + /* architectures. */ + /* */ + /* Note however that on some compiler/processor combinations, undefining */ + /* this macro will generate faster, though larger, code. */ + /* */ +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ + /* TrueType glyph loader to use Apple's definition of how to handle */ + /* component offsets in composite glyphs. */ + /* */ + /* Apple and MS disagree on the default behavior of component offsets */ + /* in composites. Apple says that they should be scaled by the scaling */ + /* factors in the transformation matrix (roughly, it's more complex) */ + /* while MS says they should not. OpenType defines two bits in the */ + /* composite flags array which can be used to disambiguate, but old */ + /* fonts will not have them. */ + /* */ + /* http://www.microsoft.com/typography/otspec/glyf.htm */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ + /* support for Apple's distortable font technology (fvar, gvar, cvar, */ + /* and avar tables). This has many similarities to Type 1 Multiple */ + /* Masters support. */ + /* */ +#define TT_CONFIG_OPTION_GX_VAR_SUPPORT + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ + /* an embedded `BDF ' table within SFNT-based bitmap formats. */ + /* */ +#define TT_CONFIG_OPTION_BDF + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ + /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ + /* required. */ + /* */ +#define T1_MAX_DICT_DEPTH 5 + + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 16 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ + /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ + /* files into an existing face. Note that if set, the T1 driver will be */ + /* unable to produce kerning distances. */ + /* */ +#undef T1_CONFIG_OPTION_NO_AFM + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of the Multiple Masters font support in the Type 1 */ + /* driver. */ + /* */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** C F F D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ + /* engine gets compiled into FreeType. If defined, it is possible to */ + /* switch between the two engines using the `hinting-engine' property of */ + /* the cff driver module. */ + /* */ +/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ // -GODOT- + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ + /* */ +#define AF_CONFIG_OPTION_CJK + + /*************************************************************************/ + /* */ + /* Compile autofit module with Indic script support. */ + /* */ +#define AF_CONFIG_OPTION_INDIC + + /*************************************************************************/ + /* */ + /* Compile autofit module with warp hinting. The idea of the warping */ + /* code is to slightly scale and shift a glyph within a single dimension */ + /* so that as much of its segments are aligned (more or less) on the */ + /* grid. To find out the optimal scaling and shifting value, various */ + /* parameter combinations are tried and scored. */ + /* */ + /* This experimental option is only active if the render mode is */ + /* FT_RENDER_MODE_LIGHT. */ + /* */ +/* #define AF_CONFIG_OPTION_USE_WARPER */ + + /* */ + + + /* + * This macro is obsolete. Support has been removed in FreeType + * version 2.5. + */ +/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /* + * This macro 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 +#undef TT_CONFIG_OPTION_UNPATENTED_HINTING +#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING +#define TT_USE_BYTECODE_INTERPRETER +#endif + +FT_END_HEADER + + +#endif /* __FTOPTION_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/config/ftstdlib.h b/drivers/freetype/include/freetype/config/ftstdlib.h new file mode 100644 index 0000000000..b940efc427 --- /dev/null +++ b/drivers/freetype/include/freetype/config/ftstdlib.h @@ -0,0 +1,174 @@ +/***************************************************************************/ +/* */ +/* ftstdlib.h */ +/* */ +/* ANSI-specific library and header configuration file (specification */ +/* only). */ +/* */ +/* Copyright 2002-2007, 2009, 2011-2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to group all #includes to the ANSI C library that */ + /* FreeType normally requires. It also defines macros to rename the */ + /* standard functions within the FreeType source code. */ + /* */ + /* Load a file which defines __FTSTDLIB_H__ before this one to override */ + /* it. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSTDLIB_H__ +#define __FTSTDLIB_H__ + + +#include <stddef.h> + +#define ft_ptrdiff_t ptrdiff_t + + + /**********************************************************************/ + /* */ + /* integer limits */ + /* */ + /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ + /* of `int' and `long' in bytes at compile-time. So far, this works */ + /* for all platforms the library has been tested on. */ + /* */ + /* Note that on the extremely rare platforms that do not provide */ + /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ + /* old Crays where `int' is 36 bits), we do not make any guarantee */ + /* about the correct behaviour of FT2 with all fonts. */ + /* */ + /* In these case, `ftconfig.h' will refuse to compile anyway with a */ + /* message like `couldn't find 32-bit type' or something similar. */ + /* */ + /**********************************************************************/ + + +#include <limits.h> + +#define FT_CHAR_BIT CHAR_BIT +#define FT_USHORT_MAX USHRT_MAX +#define FT_INT_MAX INT_MAX +#define FT_INT_MIN INT_MIN +#define FT_UINT_MAX UINT_MAX +#define FT_ULONG_MAX ULONG_MAX + + + /**********************************************************************/ + /* */ + /* character and string processing */ + /* */ + /**********************************************************************/ + + +#include <string.h> + +#define ft_memchr memchr +#define ft_memcmp memcmp +#define ft_memcpy memcpy +#define ft_memmove memmove +#define ft_memset memset +#define ft_strcat strcat +#define ft_strcmp strcmp +#define ft_strcpy strcpy +#define ft_strlen strlen +#define ft_strncmp strncmp +#define ft_strncpy strncpy +#define ft_strrchr strrchr +#define ft_strstr strstr + + + /**********************************************************************/ + /* */ + /* file handling */ + /* */ + /**********************************************************************/ + + +#include <stdio.h> + +#define FT_FILE FILE +#define ft_fclose fclose +#define ft_fopen fopen +#define ft_fread fread +#define ft_fseek fseek +#define ft_ftell ftell +#define ft_sprintf sprintf + + + /**********************************************************************/ + /* */ + /* sorting */ + /* */ + /**********************************************************************/ + + +#include <stdlib.h> + +#define ft_qsort qsort + + + /**********************************************************************/ + /* */ + /* memory allocation */ + /* */ + /**********************************************************************/ + + +#define ft_scalloc calloc +#define ft_sfree free +#define ft_smalloc malloc +#define ft_srealloc realloc + + + /**********************************************************************/ + /* */ + /* miscellaneous */ + /* */ + /**********************************************************************/ + + +#define ft_atol atol +#define ft_labs labs + + + /**********************************************************************/ + /* */ + /* execution control */ + /* */ + /**********************************************************************/ + + +#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_longjmp longjmp +#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */ + + + /* the following is only used for debugging purposes, i.e., if */ + /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ + +#include <stdarg.h> + + +#endif /* __FTSTDLIB_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/freetype.h b/drivers/freetype/include/freetype/freetype.h new file mode 100644 index 0000000000..fe46d22978 --- /dev/null +++ b/drivers/freetype/include/freetype/freetype.h @@ -0,0 +1,4012 @@ +/***************************************************************************/ +/* */ +/* freetype.h */ +/* */ +/* FreeType high-level API and common types (specification only). */ +/* */ +/* Copyright 1996-2013 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 __FREETYPE_H__ +#define __FREETYPE_H__ + + +#ifndef FT_FREETYPE_H +#error "`ft2build.h' hasn't been included yet!" +#error "Please always use macros to include FreeType header files." +#error "Example:" +#error " #include <ft2build.h>" +#error " #include FT_FREETYPE_H" +#endif + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_TYPES_H +#include FT_ERRORS_H + + +FT_BEGIN_HEADER + + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* user_allocation */ + /* */ + /* <Title> */ + /* User allocation */ + /* */ + /* <Abstract> */ + /* How client applications should allocate FreeType data structures. */ + /* */ + /* <Description> */ + /* FreeType assumes that structures allocated by the user and passed */ + /* as arguments are zeroed out except for the actual data. In other */ + /* words, it is recommended to use `calloc' (or variants of it) */ + /* instead of `malloc' for allocation. */ + /* */ + /*************************************************************************/ + + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S I C T Y P E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /* <Title> */ + /* Base Interface */ + /* */ + /* <Abstract> */ + /* The FreeType~2 base font interface. */ + /* */ + /* <Description> */ + /* This section describes the public high-level API of FreeType~2. */ + /* */ + /* <Order> */ + /* FT_Library */ + /* FT_Face */ + /* FT_Size */ + /* FT_GlyphSlot */ + /* FT_CharMap */ + /* FT_Encoding */ + /* */ + /* FT_FaceRec */ + /* */ + /* FT_FACE_FLAG_SCALABLE */ + /* FT_FACE_FLAG_FIXED_SIZES */ + /* FT_FACE_FLAG_FIXED_WIDTH */ + /* FT_FACE_FLAG_HORIZONTAL */ + /* FT_FACE_FLAG_VERTICAL */ + /* FT_FACE_FLAG_SFNT */ + /* FT_FACE_FLAG_KERNING */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS */ + /* FT_FACE_FLAG_GLYPH_NAMES */ + /* FT_FACE_FLAG_EXTERNAL_STREAM */ + /* FT_FACE_FLAG_FAST_GLYPHS */ + /* FT_FACE_FLAG_HINTER */ + /* */ + /* FT_STYLE_FLAG_BOLD */ + /* FT_STYLE_FLAG_ITALIC */ + /* */ + /* FT_SizeRec */ + /* FT_Size_Metrics */ + /* */ + /* FT_GlyphSlotRec */ + /* FT_Glyph_Metrics */ + /* FT_SubGlyph */ + /* */ + /* FT_Bitmap_Size */ + /* */ + /* FT_Init_FreeType */ + /* FT_Done_FreeType */ + /* */ + /* FT_New_Face */ + /* FT_Done_Face */ + /* FT_New_Memory_Face */ + /* FT_Open_Face */ + /* FT_Open_Args */ + /* FT_Parameter */ + /* FT_Attach_File */ + /* FT_Attach_Stream */ + /* */ + /* FT_Set_Char_Size */ + /* FT_Set_Pixel_Sizes */ + /* FT_Request_Size */ + /* FT_Select_Size */ + /* FT_Size_Request_Type */ + /* FT_Size_Request */ + /* FT_Set_Transform */ + /* FT_Load_Glyph */ + /* FT_Get_Char_Index */ + /* FT_Get_Name_Index */ + /* FT_Load_Char */ + /* */ + /* FT_OPEN_MEMORY */ + /* FT_OPEN_STREAM */ + /* FT_OPEN_PATHNAME */ + /* FT_OPEN_DRIVER */ + /* FT_OPEN_PARAMS */ + /* */ + /* FT_LOAD_DEFAULT */ + /* FT_LOAD_RENDER */ + /* FT_LOAD_MONOCHROME */ + /* FT_LOAD_LINEAR_DESIGN */ + /* FT_LOAD_NO_SCALE */ + /* FT_LOAD_NO_HINTING */ + /* FT_LOAD_NO_BITMAP */ + /* FT_LOAD_CROP_BITMAP */ + /* */ + /* FT_LOAD_VERTICAL_LAYOUT */ + /* FT_LOAD_IGNORE_TRANSFORM */ + /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ + /* FT_LOAD_FORCE_AUTOHINT */ + /* FT_LOAD_NO_RECURSE */ + /* FT_LOAD_PEDANTIC */ + /* */ + /* FT_LOAD_TARGET_NORMAL */ + /* FT_LOAD_TARGET_LIGHT */ + /* FT_LOAD_TARGET_MONO */ + /* FT_LOAD_TARGET_LCD */ + /* FT_LOAD_TARGET_LCD_V */ + /* */ + /* FT_Render_Glyph */ + /* FT_Render_Mode */ + /* FT_Get_Kerning */ + /* FT_Kerning_Mode */ + /* FT_Get_Track_Kerning */ + /* FT_Get_Glyph_Name */ + /* FT_Get_Postscript_Name */ + /* */ + /* FT_CharMapRec */ + /* FT_Select_Charmap */ + /* FT_Set_Charmap */ + /* FT_Get_Charmap_Index */ + /* */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING */ + /* FT_FSTYPE_EDITABLE_EMBEDDING */ + /* FT_FSTYPE_NO_SUBSETTING */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY */ + /* */ + /* FT_Get_FSType_Flags */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Glyph_Metrics */ + /* */ + /* <Description> */ + /* A structure used to model the metrics of a single glyph. The */ + /* values are expressed in 26.6 fractional pixel format; if the flag */ + /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ + /* are expressed in font units instead. */ + /* */ + /* <Fields> */ + /* width :: */ + /* The glyph's width. */ + /* */ + /* height :: */ + /* The glyph's height. */ + /* */ + /* horiBearingX :: */ + /* Left side bearing for horizontal layout. */ + /* */ + /* horiBearingY :: */ + /* Top side bearing for horizontal layout. */ + /* */ + /* horiAdvance :: */ + /* Advance width for horizontal layout. */ + /* */ + /* vertBearingX :: */ + /* Left side bearing for vertical layout. */ + /* */ + /* vertBearingY :: */ + /* Top side bearing for vertical layout. Larger positive values */ + /* mean further below the vertical glyph origin. */ + /* */ + /* vertAdvance :: */ + /* Advance height for vertical layout. Positive values mean the */ + /* glyph has a positive advance downward. */ + /* */ + /* <Note> */ + /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ + /* dimensions of the hinted glyph (in case hinting is applicable). */ + /* */ + /* Stroking a glyph with an outside border does not increase */ + /* `horiAdvance' or `vertAdvance'; you have to manually adjust these */ + /* values to account for the added width and height. */ + /* */ + typedef struct FT_Glyph_Metrics_ + { + FT_Pos width; + FT_Pos height; + + FT_Pos horiBearingX; + FT_Pos horiBearingY; + FT_Pos horiAdvance; + + FT_Pos vertBearingX; + FT_Pos vertBearingY; + FT_Pos vertAdvance; + + } FT_Glyph_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap_Size */ + /* */ + /* <Description> */ + /* This structure models the metrics of a bitmap strike (i.e., a set */ + /* of glyphs for a given point size and resolution) in a bitmap font. */ + /* It is used for the `available_sizes' field of @FT_Face. */ + /* */ + /* <Fields> */ + /* height :: The vertical distance, in pixels, between two */ + /* consecutive baselines. It is always positive. */ + /* */ + /* width :: The average width, in pixels, of all glyphs in the */ + /* strike. */ + /* */ + /* size :: The nominal size of the strike in 26.6 fractional */ + /* points. This field is not very useful. */ + /* */ + /* x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional */ + /* pixels. */ + /* */ + /* y_ppem :: The vertical ppem (nominal height) in 26.6 fractional */ + /* pixels. */ + /* */ + /* <Note> */ + /* Windows FNT: */ + /* The nominal size given in a FNT font is not reliable. Thus when */ + /* the driver finds it incorrect, it sets `size' to some calculated */ + /* values and sets `x_ppem' and `y_ppem' to the pixel width and */ + /* height given in the font, respectively. */ + /* */ + /* TrueType embedded bitmaps: */ + /* `size', `width', and `height' values are not contained in the */ + /* bitmap strike itself. They are computed from the global font */ + /* parameters. */ + /* */ + typedef struct FT_Bitmap_Size_ + { + FT_Short height; + FT_Short width; + + FT_Pos size; + + FT_Pos x_ppem; + FT_Pos y_ppem; + + } FT_Bitmap_Size; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Library */ + /* */ + /* <Description> */ + /* A handle to a FreeType library instance. Each `library' is */ + /* completely independent from the others; it is the `root' of a set */ + /* of objects like fonts, faces, sizes, etc. */ + /* */ + /* It also embeds a memory manager (see @FT_Memory), as well as a */ + /* scan-line converter object (see @FT_Raster). */ + /* */ + /* In multi-threaded applications, make sure that the same FT_Library */ + /* object or any of its children doesn't get accessed in parallel. */ + /* */ + /* <Note> */ + /* Library objects are normally created by @FT_Init_FreeType, and */ + /* destroyed with @FT_Done_FreeType. If you need reference-counting */ + /* (cf. @FT_Reference_Library), use @FT_New_Library and */ + /* @FT_Done_Library. */ + /* */ + typedef struct FT_LibraryRec_ *FT_Library; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Module */ + /* */ + /* <Description> */ + /* A handle to a given FreeType module object. Each module can be a */ + /* font driver, a renderer, or anything else that provides services */ + /* to the formers. */ + /* */ + typedef struct FT_ModuleRec_* FT_Module; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Driver */ + /* */ + /* <Description> */ + /* A handle to a given FreeType font driver object. Each font driver */ + /* is a special module capable of creating faces from font files. */ + /* */ + typedef struct FT_DriverRec_* FT_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Renderer */ + /* */ + /* <Description> */ + /* A handle to a given FreeType renderer. A renderer is a special */ + /* module in charge of converting a glyph image to a bitmap, when */ + /* necessary. Each renderer supports a given glyph image format, and */ + /* one or more target surface depths. */ + /* */ + typedef struct FT_RendererRec_* FT_Renderer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face */ + /* */ + /* <Description> */ + /* A handle to a given typographic face object. A face object models */ + /* a given typeface, in a given style. */ + /* */ + /* <Note> */ + /* Each face object also owns a single @FT_GlyphSlot object, as well */ + /* as one or more @FT_Size objects. */ + /* */ + /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ + /* a given filepathname or a custom input stream. */ + /* */ + /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ + /* */ + /* <Also> */ + /* See @FT_FaceRec for the publicly accessible fields of a given face */ + /* object. */ + /* */ + typedef struct FT_FaceRec_* FT_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size */ + /* */ + /* <Description> */ + /* A handle to an object used to model a face scaled to a given */ + /* character size. */ + /* */ + /* <Note> */ + /* Each @FT_Face has an _active_ @FT_Size object that is used by */ + /* functions like @FT_Load_Glyph to determine the scaling */ + /* transformation which is used to load and hint glyphs and metrics. */ + /* */ + /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ + /* @FT_Request_Size or even @FT_Select_Size to change the content */ + /* (i.e., the scaling values) of the active @FT_Size. */ + /* */ + /* You can use @FT_New_Size to create additional size objects for a */ + /* given @FT_Face, but they won't be used by other functions until */ + /* you activate it through @FT_Activate_Size. Only one size can be */ + /* activated at any given time per face. */ + /* */ + /* <Also> */ + /* See @FT_SizeRec for the publicly accessible fields of a given size */ + /* object. */ + /* */ + typedef struct FT_SizeRec_* FT_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a given `glyph slot'. A slot is a container where it */ + /* is possible to load any of the glyphs contained in its parent */ + /* face. */ + /* */ + /* In other words, each time you call @FT_Load_Glyph or */ + /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ + /* i.e., the glyph's metrics, its image (bitmap or outline), and */ + /* other control information. */ + /* */ + /* <Also> */ + /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ + /* */ + typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_CharMap */ + /* */ + /* <Description> */ + /* A handle to a given character map. A charmap is used to translate */ + /* character codes in a given encoding into glyph indexes for its */ + /* parent's face. Some font formats may provide several charmaps per */ + /* font. */ + /* */ + /* Each face object owns zero or more charmaps, but only one of them */ + /* can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char. */ + /* */ + /* The list of available charmaps in a face is available through the */ + /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ + /* */ + /* The currently active charmap is available as `face->charmap'. */ + /* You should call @FT_Set_Charmap to change it. */ + /* */ + /* <Note> */ + /* When a new face is created (either through @FT_New_Face or */ + /* @FT_Open_Face), the library looks for a Unicode charmap within */ + /* the list and automatically activates it. */ + /* */ + /* <Also> */ + /* See @FT_CharMapRec for the publicly accessible fields of a given */ + /* character map. */ + /* */ + typedef struct FT_CharMapRec_* FT_CharMap; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_ENC_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags into an unsigned long. It is */ + /* used to define `encoding' identifiers (see @FT_Encoding). */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_ENC_TAG( value, a, b, c, d ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ + +#ifndef FT_ENC_TAG +#define FT_ENC_TAG( value, a, b, c, d ) \ + value = ( ( (FT_UInt32)(a) << 24 ) | \ + ( (FT_UInt32)(b) << 16 ) | \ + ( (FT_UInt32)(c) << 8 ) | \ + (FT_UInt32)(d) ) + +#endif /* FT_ENC_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Encoding */ + /* */ + /* <Description> */ + /* An enumeration used to specify character sets supported by */ + /* charmaps. Used in the @FT_Select_Charmap API function. */ + /* */ + /* <Note> */ + /* Despite the name, this enumeration lists specific character */ + /* repertories (i.e., charsets), and not text encoding methods (e.g., */ + /* UTF-8, UTF-16, etc.). */ + /* */ + /* Other encodings might be defined in the future. */ + /* */ + /* <Values> */ + /* FT_ENCODING_NONE :: */ + /* The encoding value~0 is reserved. */ + /* */ + /* FT_ENCODING_UNICODE :: */ + /* Corresponds to the Unicode character set. This value covers */ + /* all versions of the Unicode repertoire, including ASCII and */ + /* Latin-1. Most fonts include a Unicode charmap, but not all */ + /* of them. */ + /* */ + /* For example, if you want to access Unicode value U+1F028 (and */ + /* the font contains it), use value 0x1F028 as the input value for */ + /* @FT_Get_Char_Index. */ + /* */ + /* FT_ENCODING_MS_SYMBOL :: */ + /* Corresponds to the Microsoft Symbol encoding, used to encode */ + /* mathematical symbols in the 32..255 character code range. For */ + /* more information, see `http://www.ceviz.net/symbol.htm'. */ + /* */ + /* FT_ENCODING_SJIS :: */ + /* Corresponds to Japanese SJIS encoding. More info at */ + /* at `http://langsupport.japanreference.com/encoding.shtml'. */ + /* See note on multi-byte encodings below. */ + /* */ + /* FT_ENCODING_GB2312 :: */ + /* Corresponds to an encoding system for Simplified Chinese as used */ + /* used in mainland China. */ + /* */ + /* FT_ENCODING_BIG5 :: */ + /* Corresponds to an encoding system for Traditional Chinese as */ + /* used in Taiwan and Hong Kong. */ + /* */ + /* FT_ENCODING_WANSUNG :: */ + /* Corresponds to the Korean encoding system known as Wansung. */ + /* For more information see */ + /* `http://www.microsoft.com/typography/unicode/949.txt'. */ + /* */ + /* FT_ENCODING_JOHAB :: */ + /* The Korean standard character set (KS~C 5601-1992), which */ + /* corresponds to MS Windows code page 1361. This character set */ + /* includes all possible Hangeul character combinations. */ + /* */ + /* FT_ENCODING_ADOBE_LATIN_1 :: */ + /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ + /* PostScript font. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_ADOBE_STANDARD :: */ + /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_EXPERT :: */ + /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_CUSTOM :: */ + /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_APPLE_ROMAN :: */ + /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ + /* and OpenType fonts contain a charmap for this encoding, since */ + /* older versions of Mac OS are able to use it. */ + /* */ + /* FT_ENCODING_OLD_LATIN_2 :: */ + /* This value is deprecated and was never used nor reported by */ + /* FreeType. Don't use or test for it. */ + /* */ + /* FT_ENCODING_MS_SJIS :: */ + /* Same as FT_ENCODING_SJIS. Deprecated. */ + /* */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Same as FT_ENCODING_BIG5. Deprecated. */ + /* */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* Same as FT_ENCODING_JOHAB. Deprecated. */ + /* */ + /* <Note> */ + /* By default, FreeType automatically synthesizes a Unicode charmap */ + /* for PostScript fonts, using their glyph names dictionaries. */ + /* However, it also reports the encodings defined explicitly in the */ + /* font file, for the cases when they are needed, with the Adobe */ + /* values as well. */ + /* */ + /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ + /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ + /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ + /* which encoding is really present. If, for example, the */ + /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ + /* the font is encoded in KOI8-R. */ + /* */ + /* FT_ENCODING_NONE is always set (with a single exception) by the */ + /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ + /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ + /* which encoding is really present. For example, */ + /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ + /* Russian). */ + /* */ + /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ + /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ + /* FT_ENCODING_APPLE_ROMAN). */ + /* */ + /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID which may */ + /* be needed to be able to distinguish Apple encoding variants. See */ + /* */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ + /* */ + /* to get an idea how to do that. Basically, if the language ID */ + /* is~0, don't use it, otherwise subtract 1 from the language ID. */ + /* Then examine `encoding_id'. If, for example, `encoding_id' is */ + /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ + /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ + /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* variant the Arabic encoding. */ + /* */ + typedef enum FT_Encoding_ + { + FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), + + FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), + FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), + + FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), + FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ), + FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), + FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), + FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), + + /* for backwards compatibility */ + FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, + FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312, + FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, + FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, + FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, + + FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ), + + FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ), + + FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' ) + + } FT_Encoding; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_encoding_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated; use the corresponding @FT_Encoding */ + /* values instead. */ + /* */ +#define ft_encoding_none FT_ENCODING_NONE +#define ft_encoding_unicode FT_ENCODING_UNICODE +#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL +#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 +#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 +#define ft_encoding_sjis FT_ENCODING_SJIS +#define ft_encoding_gb2312 FT_ENCODING_GB2312 +#define ft_encoding_big5 FT_ENCODING_BIG5 +#define ft_encoding_wansung FT_ENCODING_WANSUNG +#define ft_encoding_johab FT_ENCODING_JOHAB + +#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD +#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT +#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM +#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_CharMapRec */ + /* */ + /* <Description> */ + /* The base charmap structure. */ + /* */ + /* <Fields> */ + /* face :: A handle to the parent face object. */ + /* */ + /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ + /* this with @FT_Select_Charmap. */ + /* */ + /* platform_id :: An ID number describing the platform for the */ + /* following encoding ID. This comes directly from */ + /* the TrueType specification and should be emulated */ + /* for other formats. */ + /* */ + /* encoding_id :: A platform specific encoding number. This also */ + /* comes from the TrueType specification and should be */ + /* emulated similarly. */ + /* */ + typedef struct FT_CharMapRec_ + { + FT_Face face; + FT_Encoding encoding; + FT_UShort platform_id; + FT_UShort encoding_id; + + } FT_CharMapRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S E O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ + /* model private data of a given @FT_Face object. */ + /* */ + /* This structure might change between releases of FreeType~2 and is */ + /* not generally available to client applications. */ + /* */ + typedef struct FT_Face_InternalRec_* FT_Face_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_FaceRec */ + /* */ + /* <Description> */ + /* FreeType root face class structure. A face object models a */ + /* typeface in a font file. */ + /* */ + /* <Fields> */ + /* num_faces :: The number of faces in the font file. Some */ + /* font formats can have multiple faces in */ + /* a font file. */ + /* */ + /* face_index :: The index of the face in the font file. It */ + /* is set to~0 if there is only one face in */ + /* the font file. */ + /* */ + /* face_flags :: A set of bit flags that give important */ + /* information about the face; see */ + /* @FT_FACE_FLAG_XXX for the details. */ + /* */ + /* style_flags :: A set of bit flags indicating the style of */ + /* the face; see @FT_STYLE_FLAG_XXX for the */ + /* details. */ + /* */ + /* num_glyphs :: The number of glyphs in the face. If the */ + /* face is scalable and has sbits (see */ + /* `num_fixed_sizes'), it is set to the number */ + /* of outline glyphs. */ + /* */ + /* For CID-keyed fonts, this value gives the */ + /* highest CID used in the font. */ + /* */ + /* family_name :: The face's family name. This is an ASCII */ + /* string, usually in English, which describes */ + /* the typeface's family (like `Times New */ + /* Roman', `Bodoni', `Garamond', etc). This */ + /* is a least common denominator used to list */ + /* fonts. Some formats (TrueType & OpenType) */ + /* provide localized and Unicode versions of */ + /* this string. Applications should use the */ + /* format specific interface to access them. */ + /* Can be NULL (e.g., in fonts embedded in a */ + /* PDF file). */ + /* */ + /* style_name :: The face's style name. This is an ASCII */ + /* string, usually in English, which describes */ + /* the typeface's style (like `Italic', */ + /* `Bold', `Condensed', etc). Not all font */ + /* formats provide a style name, so this field */ + /* is optional, and can be set to NULL. As */ + /* for `family_name', some formats provide */ + /* localized and Unicode versions of this */ + /* string. Applications should use the format */ + /* specific interface to access them. */ + /* */ + /* num_fixed_sizes :: The number of bitmap strikes in the face. */ + /* Even if the face is scalable, there might */ + /* still be bitmap strikes, which are called */ + /* `sbits' in that case. */ + /* */ + /* available_sizes :: An array of @FT_Bitmap_Size for all bitmap */ + /* strikes in the face. It is set to NULL if */ + /* there is no bitmap strike. */ + /* */ + /* num_charmaps :: The number of charmaps in the face. */ + /* */ + /* charmaps :: An array of the charmaps of the face. */ + /* */ + /* generic :: A field reserved for client uses. See the */ + /* @FT_Generic type description. */ + /* */ + /* bbox :: The font bounding box. Coordinates are */ + /* expressed in font units (see */ + /* `units_per_EM'). The box is large enough */ + /* to contain any glyph from the font. Thus, */ + /* `bbox.yMax' can be seen as the `maximum */ + /* ascender', and `bbox.yMin' as the `minimum */ + /* descender'. Only relevant for scalable */ + /* formats. */ + /* */ + /* Note that the bounding box might be off by */ + /* (at least) one pixel for hinted fonts. See */ + /* @FT_Size_Metrics for further discussion. */ + /* */ + /* units_per_EM :: The number of font units per EM square for */ + /* this face. This is typically 2048 for */ + /* TrueType fonts, and 1000 for Type~1 fonts. */ + /* Only relevant for scalable formats. */ + /* */ + /* ascender :: The typographic ascender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMax'. Only relevant for scalable */ + /* formats. */ + /* */ + /* descender :: The typographic descender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMin'. Note that this field is */ + /* usually negative. Only relevant for */ + /* scalable formats. */ + /* */ + /* height :: This value is the vertical distance */ + /* between two consecutive baselines, */ + /* expressed in font units. It is always */ + /* positive. Only relevant for scalable */ + /* formats. */ + /* */ + /* If you want the global glyph height, use */ + /* `ascender - descender'. */ + /* */ + /* max_advance_width :: The maximum advance width, in font units, */ + /* for all glyphs in this face. This can be */ + /* used to make word wrapping computations */ + /* faster. Only relevant for scalable */ + /* formats. */ + /* */ + /* max_advance_height :: The maximum advance height, in font units, */ + /* for all glyphs in this face. This is only */ + /* relevant for vertical layouts, and is set */ + /* to `height' for fonts that do not provide */ + /* vertical metrics. Only relevant for */ + /* scalable formats. */ + /* */ + /* underline_position :: The position, in font units, of the */ + /* underline line for this face. It is the */ + /* center of the underlining stem. Only */ + /* relevant for scalable formats. */ + /* */ + /* underline_thickness :: The thickness, in font units, of the */ + /* underline for this face. Only relevant for */ + /* scalable formats. */ + /* */ + /* glyph :: The face's associated glyph slot(s). */ + /* */ + /* size :: The current active size for this face. */ + /* */ + /* charmap :: The current active charmap for this face. */ + /* */ + /* <Note> */ + /* Fields may be changed after a call to @FT_Attach_File or */ + /* @FT_Attach_Stream. */ + /* */ + typedef struct FT_FaceRec_ + { + FT_Long num_faces; + FT_Long face_index; + + FT_Long face_flags; + FT_Long style_flags; + + FT_Long num_glyphs; + + FT_String* family_name; + FT_String* style_name; + + FT_Int num_fixed_sizes; + FT_Bitmap_Size* available_sizes; + + FT_Int num_charmaps; + FT_CharMap* charmaps; + + FT_Generic generic; + + /*# 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; + FT_Short ascender; + FT_Short descender; + FT_Short height; + + FT_Short max_advance_width; + FT_Short max_advance_height; + + FT_Short underline_position; + FT_Short underline_thickness; + + FT_GlyphSlot glyph; + FT_Size size; + FT_CharMap charmap; + + /*@private begin */ + + FT_Driver driver; + FT_Memory memory; + FT_Stream stream; + + FT_ListRec sizes_list; + + FT_Generic autohint; /* face-specific auto-hinter data */ + void* extensions; /* unused */ + + FT_Face_Internal internal; + + /*@private end */ + + } FT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FACE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `face_flags' field of the */ + /* @FT_FaceRec structure. They inform client applications of */ + /* properties of the corresponding face. */ + /* */ + /* <Values> */ + /* FT_FACE_FLAG_SCALABLE :: */ + /* Indicates that the face contains outline glyphs. This doesn't */ + /* prevent bitmap strikes, i.e., a face can have both this and */ + /* and @FT_FACE_FLAG_FIXED_SIZES set. */ + /* */ + /* FT_FACE_FLAG_FIXED_SIZES :: */ + /* Indicates that the face contains bitmap strikes. See also the */ + /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ + /* */ + /* FT_FACE_FLAG_FIXED_WIDTH :: */ + /* Indicates that the face contains fixed-width characters (like */ + /* Courier, Lucido, MonoType, etc.). */ + /* */ + /* FT_FACE_FLAG_SFNT :: */ + /* Indicates that the face uses the `sfnt' storage scheme. For */ + /* now, this means TrueType and OpenType. */ + /* */ + /* FT_FACE_FLAG_HORIZONTAL :: */ + /* Indicates that the face contains horizontal glyph metrics. This */ + /* should be set for all common formats. */ + /* */ + /* FT_FACE_FLAG_VERTICAL :: */ + /* Indicates that the face contains vertical glyph metrics. This */ + /* is only available in some formats, not all of them. */ + /* */ + /* FT_FACE_FLAG_KERNING :: */ + /* Indicates that the face contains kerning information. If set, */ + /* the kerning distance can be retrieved through the function */ + /* @FT_Get_Kerning. Otherwise the function always return the */ + /* vector (0,0). Note that FreeType doesn't handle kerning data */ + /* from the `GPOS' table (as present in some OpenType fonts). */ + /* */ + /* FT_FACE_FLAG_FAST_GLYPHS :: */ + /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ + /* */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ + /* Indicates that the font contains multiple masters and is capable */ + /* of interpolating between them. See the multiple-masters */ + /* specific API for details. */ + /* */ + /* FT_FACE_FLAG_GLYPH_NAMES :: */ + /* Indicates that the font contains glyph names that can be */ + /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ + /* fonts contain broken glyph name tables. Use the function */ + /* @FT_Has_PS_Glyph_Names when needed. */ + /* */ + /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ + /* Used internally by FreeType to indicate that a face's stream was */ + /* provided by the client application and should not be destroyed */ + /* when @FT_Done_Face is called. Don't read or test this flag. */ + /* */ + /* FT_FACE_FLAG_HINTER :: */ + /* Set if the font driver has a hinting machine of its own. For */ + /* example, with TrueType fonts, it makes sense to use data from */ + /* the SFNT `gasp' table only if the native TrueType hinting engine */ + /* (with the bytecode interpreter) is available and active. */ + /* */ + /* FT_FACE_FLAG_CID_KEYED :: */ + /* Set if the font is CID-keyed. In that case, the font is not */ + /* accessed by glyph indices but by CID values. For subsetted */ + /* CID-keyed fonts this has the consequence that not all index */ + /* values are a valid argument to FT_Load_Glyph. Only the CID */ + /* values for which corresponding glyphs in the subsetted font */ + /* exist make FT_Load_Glyph return successfully; in all other cases */ + /* you get an `FT_Err_Invalid_Argument' error. */ + /* */ + /* Note that CID-keyed fonts which are in an SFNT wrapper don't */ + /* have this flag set since the glyphs are accessed in the normal */ + /* way (using contiguous indices); the `CID-ness' isn't visible to */ + /* the application. */ + /* */ + /* FT_FACE_FLAG_TRICKY :: */ + /* Set if the font is `tricky', this is, it always needs the */ + /* font format's native hinting engine to get a reasonable result. */ + /* A typical example is the Chinese font `mingli.ttf' which uses */ + /* TrueType bytecode instructions to move and scale all of its */ + /* subglyphs. */ + /* */ + /* It is not possible to autohint such fonts using */ + /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ + /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */ + /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ + /* probably never want this except for demonstration purposes. */ + /* */ + /* Currently, there are about a dozen TrueType fonts in the list of */ + /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ + /* */ +#define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) +#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) +#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) +#define FT_FACE_FLAG_SFNT ( 1L << 3 ) +#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 ) +#define FT_FACE_FLAG_VERTICAL ( 1L << 5 ) +#define FT_FACE_FLAG_KERNING ( 1L << 6 ) +#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 ) +#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 ) +#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) +#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) +#define FT_FACE_FLAG_HINTER ( 1L << 11 ) +#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) +#define FT_FACE_FLAG_TRICKY ( 1L << 13 ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_HORIZONTAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * horizontal metrics (this is true for all font formats though). + * + * @also: + * @FT_HAS_VERTICAL can be used to check for vertical metrics. + * + */ +#define FT_HAS_HORIZONTAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_VERTICAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains real + * vertical metrics (and not only synthesized ones). + * + */ +#define FT_HAS_VERTICAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_KERNING( face ) + * + * @description: + * A macro that returns true whenever a face object contains kerning + * data that can be accessed with @FT_Get_Kerning. + * + */ +#define FT_HAS_KERNING( face ) \ + ( face->face_flags & FT_FACE_FLAG_KERNING ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SCALABLE( face ) + * + * @description: + * A macro that returns true whenever a face object contains a scalable + * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, + * and PFR font formats. + * + */ +#define FT_IS_SCALABLE( face ) \ + ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SFNT( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font + * whose format is based on the SFNT storage scheme. This usually + * means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded + * bitmap fonts. + * + * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and + * @FT_TRUETYPE_TABLES_H are available. + * + */ +#define FT_IS_SFNT( face ) \ + ( face->face_flags & FT_FACE_FLAG_SFNT ) + + + /************************************************************************* + * + * @macro: + * FT_IS_FIXED_WIDTH( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font face + * that contains fixed-width (or `monospace', `fixed-pitch', etc.) + * glyphs. + * + */ +#define FT_IS_FIXED_WIDTH( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FIXED_SIZES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * embedded bitmaps. See the `available_sizes' field of the + * @FT_FaceRec structure. + * + */ +#define FT_HAS_FIXED_SIZES( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FAST_GLYPHS( face ) + * + * @description: + * Deprecated. + * + */ +#define FT_HAS_FAST_GLYPHS( face ) 0 + + + /************************************************************************* + * + * @macro: + * FT_HAS_GLYPH_NAMES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some glyph + * names that can be accessed through @FT_Get_Glyph_Name. + * + */ +#define FT_HAS_GLYPH_NAMES( face ) \ + ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_MULTIPLE_MASTERS( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * multiple masters. The functions provided by @FT_MULTIPLE_MASTERS_H + * are then available to choose the exact design you want. + * + */ +#define FT_HAS_MULTIPLE_MASTERS( face ) \ + ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + + + /************************************************************************* + * + * @macro: + * FT_IS_CID_KEYED( face ) + * + * @description: + * A macro that returns true whenever a face object contains a CID-keyed + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more + * details. + * + * If this macro is true, all functions defined in @FT_CID_H are + * available. + * + */ +#define FT_IS_CID_KEYED( face ) \ + ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + + + /************************************************************************* + * + * @macro: + * FT_IS_TRICKY( face ) + * + * @description: + * A macro that returns true whenever a face represents a `tricky' font. + * See the discussion of @FT_FACE_FLAG_TRICKY for more details. + * + */ +#define FT_IS_TRICKY( face ) \ + ( face->face_flags & FT_FACE_FLAG_TRICKY ) + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_STYLE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit-flags used to indicate the style of a given face. */ + /* These are used in the `style_flags' field of @FT_FaceRec. */ + /* */ + /* <Values> */ + /* FT_STYLE_FLAG_ITALIC :: */ + /* Indicates that a given face style is italic or oblique. */ + /* */ + /* FT_STYLE_FLAG_BOLD :: */ + /* Indicates that a given face is bold. */ + /* */ + /* <Note> */ + /* The style information as provided by FreeType is very basic. More */ + /* details are beyond the scope and should be done on a higher level */ + /* (for example, by analyzing various fields of the `OS/2' table in */ + /* SFNT based fonts). */ + /* */ +#define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) +#define FT_STYLE_FLAG_BOLD ( 1 << 1 ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ + /* model private data of a given @FT_Size object. */ + /* */ + typedef struct FT_Size_InternalRec_* FT_Size_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Metrics */ + /* */ + /* <Description> */ + /* The size metrics structure gives the metrics of a size object. */ + /* */ + /* <Fields> */ + /* x_ppem :: The width of the scaled EM square in pixels, hence */ + /* the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal width'. */ + /* */ + /* y_ppem :: The height of the scaled EM square in pixels, */ + /* hence the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal height'. */ + /* */ + /* x_scale :: A 16.16 fractional scaling value used to convert */ + /* horizontal metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* y_scale :: A 16.16 fractional scaling value used to convert */ + /* vertical metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* ascender :: The ascender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* descender :: The descender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* height :: The height in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* max_advance :: The maximum advance width in 26.6 fractional */ + /* pixels. See @FT_FaceRec for the details. */ + /* */ + /* <Note> */ + /* The scaling values, if relevant, are determined first during a */ + /* size changing operation. The remaining fields are then set by the */ + /* driver. For scalable formats, they are usually set to scaled */ + /* values of the corresponding fields in @FT_FaceRec. */ + /* */ + /* Note that due to glyph hinting, these values might not be exact */ + /* for certain fonts. Thus they must be treated as unreliable */ + /* with an error margin of at least one pixel! */ + /* */ + /* Indeed, the only way to get the exact metrics is to render _all_ */ + /* 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 */ + FT_UShort y_ppem; /* vertical pixels per EM */ + + FT_Fixed x_scale; /* scaling values used to convert font */ + FT_Fixed y_scale; /* units to 26.6 fractional pixels */ + + FT_Pos ascender; /* ascender in 26.6 frac. pixels */ + FT_Pos descender; /* descender in 26.6 frac. pixels */ + FT_Pos height; /* text height in 26.6 frac. pixels */ + FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ + + } FT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SizeRec */ + /* */ + /* <Description> */ + /* FreeType root size class structure. A size object models a face */ + /* object at a given size. */ + /* */ + /* <Fields> */ + /* face :: Handle to the parent face object. */ + /* */ + /* generic :: A typeless pointer, which is unused by the FreeType */ + /* library or any of its drivers. It can be used by */ + /* client applications to link their own data to each size */ + /* object. */ + /* */ + /* metrics :: Metrics for this size object. This field is read-only. */ + /* */ + typedef struct FT_SizeRec_ + { + FT_Face face; /* parent face object */ + FT_Generic generic; /* generic pointer for client uses */ + FT_Size_Metrics metrics; /* size metrics */ + FT_Size_Internal internal; + + } FT_SizeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SubGlyph */ + /* */ + /* <Description> */ + /* The subglyph structure is an internal object used to describe */ + /* subglyphs (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The subglyph implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + /* You can however retrieve subglyph information with */ + /* @FT_Get_SubGlyph_Info. */ + /* */ + typedef struct FT_SubGlyphRec_* FT_SubGlyph; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Slot_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ + /* model private data of a given @FT_GlyphSlot object. */ + /* */ + typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphSlotRec */ + /* */ + /* <Description> */ + /* FreeType root glyph slot class structure. A glyph slot is a */ + /* container where individual glyphs can be loaded, be they in */ + /* outline or bitmap format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library instance */ + /* this slot belongs to. */ + /* */ + /* face :: A handle to the parent face object. */ + /* */ + /* next :: In some cases (like some font tools), several */ + /* glyph slots per face object can be a good */ + /* thing. As this is rare, the glyph slots are */ + /* listed through a direct, single-linked list */ + /* using its `next' field. */ + /* */ + /* generic :: A typeless pointer which is unused by the */ + /* FreeType library or any of its drivers. It */ + /* can be used by client applications to link */ + /* their own data to each glyph slot object. */ + /* */ + /* metrics :: The metrics of the last loaded glyph in the */ + /* slot. The returned values depend on the last */ + /* load flags (see the @FT_Load_Glyph API */ + /* function) and can be expressed either in 26.6 */ + /* fractional pixels or font units. */ + /* */ + /* Note that even when the glyph image is */ + /* transformed, the metrics are not. */ + /* */ + /* linearHoriAdvance :: The advance width of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* linearVertAdvance :: The advance height of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* advance :: This shorthand is, depending on */ + /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ + /* advance width for the glyph (in 26.6 */ + /* fractional pixel format). As specified with */ + /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ + /* `horiAdvance' or the `vertAdvance' value of */ + /* `metrics' field. */ + /* */ + /* format :: This field indicates the format of the image */ + /* contained in the glyph slot. Typically */ + /* @FT_GLYPH_FORMAT_BITMAP, */ + /* @FT_GLYPH_FORMAT_OUTLINE, or */ + /* @FT_GLYPH_FORMAT_COMPOSITE, but others are */ + /* possible. */ + /* */ + /* bitmap :: This field is used as a bitmap descriptor */ + /* when the slot format is */ + /* @FT_GLYPH_FORMAT_BITMAP. Note that the */ + /* address and content of the bitmap buffer can */ + /* change between calls of @FT_Load_Glyph and a */ + /* few other functions. */ + /* */ + /* bitmap_left :: This is the bitmap's left bearing expressed */ + /* in integer pixels. Of course, this is only */ + /* valid if the format is */ + /* @FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* bitmap_top :: This is the bitmap's top bearing expressed in */ + /* integer pixels. Remember that this is the */ + /* distance from the baseline to the top-most */ + /* glyph scanline, upwards y~coordinates being */ + /* *positive*. */ + /* */ + /* outline :: The outline descriptor for the current glyph */ + /* image if its format is */ + /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ + /* loaded, `outline' can be transformed, */ + /* distorted, embolded, etc. However, it must */ + /* not be freed. */ + /* */ + /* num_subglyphs :: The number of subglyphs in a composite glyph. */ + /* This field is only valid for the composite */ + /* glyph format that should normally only be */ + /* loaded with the @FT_LOAD_NO_RECURSE flag. */ + /* For now this is internal to FreeType. */ + /* */ + /* subglyphs :: An array of subglyph descriptors for */ + /* composite glyphs. There are `num_subglyphs' */ + /* elements in there. Currently internal to */ + /* FreeType. */ + /* */ + /* control_data :: Certain font drivers can also return the */ + /* control data for a given glyph image (e.g. */ + /* TrueType bytecode, Type~1 charstrings, etc.). */ + /* This field is a pointer to such data. */ + /* */ + /* control_len :: This is the length in bytes of the control */ + /* data. */ + /* */ + /* other :: Really wicked formats can use this pointer to */ + /* present their own glyph image to client */ + /* applications. Note that the application */ + /* needs to know about the image format. */ + /* */ + /* lsb_delta :: The difference between hinted and unhinted */ + /* left side bearing while autohinting is */ + /* active. Zero otherwise. */ + /* */ + /* rsb_delta :: The difference between hinted and unhinted */ + /* right side bearing while autohinting is */ + /* active. Zero otherwise. */ + /* */ + /* <Note> */ + /* If @FT_Load_Glyph is called with default flags (see */ + /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ + /* its native format (e.g., an outline glyph for TrueType and Type~1 */ + /* formats). */ + /* */ + /* This image can later be converted into a bitmap by calling */ + /* @FT_Render_Glyph. This function finds the current renderer for */ + /* the native image's format, then invokes it. */ + /* */ + /* The renderer is in charge of transforming the native image through */ + /* the slot's face transformation fields, then converting it into a */ + /* bitmap that is returned in `slot->bitmap'. */ + /* */ + /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ + /* to specify the position of the bitmap relative to the current pen */ + /* position (e.g., coordinates (0,0) on the baseline). Of course, */ + /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* <Note> */ + /* Here a small pseudo code fragment which shows how to use */ + /* `lsb_delta' and `rsb_delta': */ + /* */ + /* { */ + /* FT_Pos origin_x = 0; */ + /* FT_Pos prev_rsb_delta = 0; */ + /* */ + /* */ + /* for all glyphs do */ + /* <compute kern between current and previous glyph and add it to */ + /* `origin_x'> */ + /* */ + /* <load glyph with `FT_Load_Glyph'> */ + /* */ + /* if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 ) */ + /* origin_x -= 64; */ + /* else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 ) */ + /* origin_x += 64; */ + /* */ + /* prev_rsb_delta = face->glyph->rsb_delta; */ + /* */ + /* <save glyph image, or render glyph, or ...> */ + /* */ + /* origin_x += face->glyph->advance.x; */ + /* endfor */ + /* } */ + /* */ + typedef struct FT_GlyphSlotRec_ + { + FT_Library library; + FT_Face face; + FT_GlyphSlot next; + FT_UInt reserved; /* retained for binary compatibility */ + FT_Generic generic; + + FT_Glyph_Metrics metrics; + FT_Fixed linearHoriAdvance; + FT_Fixed linearVertAdvance; + FT_Vector advance; + + FT_Glyph_Format format; + + FT_Bitmap bitmap; + FT_Int bitmap_left; + FT_Int bitmap_top; + + FT_Outline outline; + + FT_UInt num_subglyphs; + FT_SubGlyph subglyphs; + + void* control_data; + long control_len; + + FT_Pos lsb_delta; + FT_Pos rsb_delta; + + void* other; + + FT_Slot_Internal internal; + + } FT_GlyphSlotRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* F U N C T I O N S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Init_FreeType */ + /* */ + /* <Description> */ + /* Initialize a new FreeType library object. The set of modules */ + /* that are registered by this function is determined at build time. */ + /* */ + /* <Output> */ + /* alibrary :: A handle to a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case you want to provide your own memory allocating routines, */ + /* use @FT_New_Library instead, followed by a call to */ + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ + /* */ + /* For multi-threading applications each thread should have its own */ + /* FT_Library object. */ + /* */ + /* If you need reference-counting (cf. @FT_Reference_Library), use */ + /* @FT_New_Library and @FT_Done_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_FreeType */ + /* */ + /* <Description> */ + /* Destroy a given FreeType library object and all of its children, */ + /* including resources, drivers, faces, sizes, etc. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_FreeType( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OPEN_XXX */ + /* */ + /* <Description> */ + /* A list of bit-field constants used within the `flags' field of the */ + /* @FT_Open_Args structure. */ + /* */ + /* <Values> */ + /* FT_OPEN_MEMORY :: This is a memory-based stream. */ + /* */ + /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ + /* */ + /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ + /* name. */ + /* */ + /* FT_OPEN_DRIVER :: Use the `driver' field. */ + /* */ + /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ + /* */ + /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ + /* */ + /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ + /* */ + /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ + /* */ + /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ + /* */ + /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ + /* */ + /* <Note> */ + /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ + /* flags are mutually exclusive. */ + /* */ +#define FT_OPEN_MEMORY 0x1 +#define FT_OPEN_STREAM 0x2 +#define FT_OPEN_PATHNAME 0x4 +#define FT_OPEN_DRIVER 0x8 +#define FT_OPEN_PARAMS 0x10 + +#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ +#define ft_open_stream FT_OPEN_STREAM /* deprecated */ +#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ +#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ +#define ft_open_params FT_OPEN_PARAMS /* deprecated */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Parameter */ + /* */ + /* <Description> */ + /* A simple structure used to pass more or less generic parameters to */ + /* @FT_Open_Face. */ + /* */ + /* <Fields> */ + /* tag :: A four-byte identification tag. */ + /* */ + /* data :: A pointer to the parameter data. */ + /* */ + /* <Note> */ + /* The ID and function of parameters are driver-specific. See the */ + /* various FT_PARAM_TAG_XXX flags for more information. */ + /* */ + typedef struct FT_Parameter_ + { + FT_ULong tag; + FT_Pointer data; + + } FT_Parameter; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Open_Args */ + /* */ + /* <Description> */ + /* A structure used to indicate how to open a new font file or */ + /* stream. A pointer to such a structure can be used as a parameter */ + /* for the functions @FT_Open_Face and @FT_Attach_Stream. */ + /* */ + /* <Fields> */ + /* flags :: A set of bit flags indicating how to use the */ + /* structure. */ + /* */ + /* memory_base :: The first byte of the file in memory. */ + /* */ + /* memory_size :: The size in bytes of the file in memory. */ + /* */ + /* pathname :: A pointer to an 8-bit file pathname. */ + /* */ + /* stream :: A handle to a source stream object. */ + /* */ + /* driver :: This field is exclusively used by @FT_Open_Face; */ + /* it simply specifies the font driver to use to open */ + /* the face. If set to~0, FreeType tries to load the */ + /* face with each one of the drivers in its list. */ + /* */ + /* num_params :: The number of extra parameters. */ + /* */ + /* params :: Extra parameters passed to the font driver when */ + /* opening a new face. */ + /* */ + /* <Note> */ + /* The stream type is determined by the contents of `flags' which */ + /* are tested in the following order by @FT_Open_Face: */ + /* */ + /* If the `FT_OPEN_MEMORY' bit is set, assume that this is a */ + /* memory file of `memory_size' bytes, located at `memory_address'. */ + /* The data are are not copied, and the client is responsible for */ + /* releasing and destroying them _after_ the corresponding call to */ + /* @FT_Done_Face. */ + /* */ + /* Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a */ + /* custom input stream `stream' is used. */ + /* */ + /* Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this */ + /* is a normal file and use `pathname' to open it. */ + /* */ + /* If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to */ + /* open the file with the driver whose handler is in `driver'. */ + /* */ + /* If the `FT_OPEN_PARAMS' bit is set, the parameters given by */ + /* `num_params' and `params' is used. They are ignored otherwise. */ + /* */ + /* Ideally, both the `pathname' and `params' fields should be tagged */ + /* as `const'; this is missing for API backwards compatibility. In */ + /* other words, applications should treat them as read-only. */ + /* */ + typedef struct FT_Open_Args_ + { + FT_UInt flags; + const FT_Byte* memory_base; + FT_Long memory_size; + FT_String* pathname; + FT_Stream stream; + FT_Module driver; + FT_Int num_params; + FT_Parameter* params; + + } FT_Open_Args; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font by its pathname. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* pathname :: A path to the font file. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See @FT_Open_Face for more details. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Use @FT_Done_Face to destroy the created @FT_Face object (along */ + /* with its slot and sizes). */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face( FT_Library library, + const char* filepathname, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font which has been */ + /* loaded into memory. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* file_base :: A pointer to the beginning of the font data. */ + /* */ + /* file_size :: The size of the memory chunk used by the font data. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See @FT_Open_Face for more details. */ + /* */ + /* <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, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Open_Face */ + /* */ + /* <Description> */ + /* Create a face object from a given resource described by */ + /* @FT_Open_Args. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* args :: A pointer to an `FT_Open_Args' structure which must */ + /* be filled by the caller. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See note below. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object which can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* FT_Open_Face can be used to quickly check whether the font */ + /* format of a given font resource is supported by FreeType. If the */ + /* `face_index' field is negative, the function's return value is~0 */ + /* if the font format is recognized, or non-zero otherwise; */ + /* the function returns a more or less empty face handle in `*aface' */ + /* (if `aface' isn't NULL). The only useful field in this special */ + /* case is `face->num_faces' which gives the number of faces within */ + /* the font file. After examination, the returned @FT_Face structure */ + /* should be deallocated with a call to @FT_Done_Face. */ + /* */ + /* Each new face object created with this function also owns a */ + /* default @FT_Size object, accessible as `face->size'. */ + /* */ + /* One @FT_Library instance can have multiple face objects, this is, */ + /* @FT_Open_Face and its siblings can be called multiple times using */ + /* the same `library' argument. */ + /* */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_File */ + /* */ + /* <Description> */ + /* This function calls @FT_Attach_Stream to attach a file. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* filepathname :: The pathname. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_Stream */ + /* */ + /* <Description> */ + /* `Attach' data to a face object. Normally, this is used to read */ + /* additional information for the face object. For example, you can */ + /* attach an AFM file that comes with a Type~1 font to get the */ + /* kerning values and other metrics. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* parameters :: A pointer to @FT_Open_Args which must be filled by */ + /* the caller. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The meaning of the `attach' (i.e., what really happens when the */ + /* new file is read) is not fixed by FreeType itself. It really */ + /* depends on the font format (and thus the font driver). */ + /* */ + /* Client applications are expected to know what they are doing */ + /* when invoking this function. Most drivers simply do not implement */ + /* file attachments. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Reference_Face */ + /* */ + /* <Description> */ + /* A counter gets initialized to~1 at the time an @FT_Face structure */ + /* is created. This function increments the counter. @FT_Done_Face */ + /* then only destroys a face if the counter is~1, otherwise it simply */ + /* decrements the counter. */ + /* */ + /* This function helps in managing life-cycles of structures which */ + /* reference @FT_Face objects. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.4.2 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Reference_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Face */ + /* */ + /* <Description> */ + /* Discard a given face object, as well as all of its child slots and */ + /* sizes. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Size */ + /* */ + /* <Description> */ + /* Select a bitmap strike. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* strike_index :: The index of the bitmap strike in the */ + /* `available_sizes' field of @FT_FaceRec structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Size( FT_Face face, + FT_Int strike_index ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Size_Request_Type */ + /* */ + /* <Description> */ + /* An enumeration type that lists the supported size request types. */ + /* */ + /* <Values> */ + /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ + /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ + /* used to determine both scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ + /* The real dimension. The sum of the the `ascender' and (minus */ + /* of) the `descender' fields of @FT_FaceRec are used to determine */ + /* both scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_BBOX :: */ + /* The font bounding box. The width and height of the `bbox' field */ + /* of @FT_FaceRec are used to determine the horizontal and vertical */ + /* scaling value, respectively. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_CELL :: */ + /* The `max_advance_width' field of @FT_FaceRec is used to */ + /* determine the horizontal scaling value; the vertical scaling */ + /* value is determined the same way as */ + /* @FT_SIZE_REQUEST_TYPE_REAL_DIM does. Finally, both scaling */ + /* values are set to the smaller one. This type is useful if you */ + /* want to specify the font size for, say, a window of a given */ + /* dimension and 80x24 cells. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_SCALES :: */ + /* Specify the scaling values directly. */ + /* */ + /* <Note> */ + /* The above descriptions only apply to scalable formats. For bitmap */ + /* formats, the behaviour is up to the driver. */ + /* */ + /* See the note section of @FT_Size_Metrics if you wonder how size */ + /* requesting relates to scaling values. */ + /* */ + typedef enum FT_Size_Request_Type_ + { + FT_SIZE_REQUEST_TYPE_NOMINAL, + FT_SIZE_REQUEST_TYPE_REAL_DIM, + FT_SIZE_REQUEST_TYPE_BBOX, + FT_SIZE_REQUEST_TYPE_CELL, + FT_SIZE_REQUEST_TYPE_SCALES, + + FT_SIZE_REQUEST_TYPE_MAX + + } FT_Size_Request_Type; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_RequestRec */ + /* */ + /* <Description> */ + /* A structure used to model a size request. */ + /* */ + /* <Fields> */ + /* type :: See @FT_Size_Request_Type. */ + /* */ + /* width :: The desired width. */ + /* */ + /* height :: The desired height. */ + /* */ + /* horiResolution :: The horizontal resolution. If set to zero, */ + /* `width' is treated as a 26.6 fractional pixel */ + /* value. */ + /* */ + /* vertResolution :: The vertical resolution. If set to zero, */ + /* `height' is treated as a 26.6 fractional pixel */ + /* value. */ + /* */ + /* <Note> */ + /* If `width' is zero, then the horizontal scaling value is set equal */ + /* to the vertical scaling value, and vice versa. */ + /* */ + typedef struct FT_Size_RequestRec_ + { + FT_Size_Request_Type type; + FT_Long width; + FT_Long height; + FT_UInt horiResolution; + FT_UInt vertResolution; + + } FT_Size_RequestRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Request */ + /* */ + /* <Description> */ + /* A handle to a size request structure. */ + /* */ + typedef struct FT_Size_RequestRec_ *FT_Size_Request; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Request_Size */ + /* */ + /* <Description> */ + /* Resize the scale of the active @FT_Size object in a face. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* req :: A pointer to a @FT_Size_RequestRec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Although drivers may select the bitmap strike matching the */ + /* request, you should not rely on this if you intend to select a */ + /* particular bitmap strike. Use @FT_Select_Size instead in that */ + /* case. */ + /* */ + /* The relation between the requested size and the resulting glyph */ + /* size is dependent entirely on how the size is defined in the */ + /* source face. The font designer chooses the final size of each */ + /* glyph relative to this size. For more information refer to */ + /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */ + /* */ + FT_EXPORT( FT_Error ) + FT_Request_Size( FT_Face face, + FT_Size_Request req ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Char_Size */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in points). */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* char_width :: The nominal width, in 26.6 fractional points. */ + /* */ + /* char_height :: The nominal height, in 26.6 fractional points. */ + /* */ + /* horz_resolution :: The horizontal resolution in dpi. */ + /* */ + /* vert_resolution :: The vertical resolution in dpi. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If either the character width or height is zero, it is set equal */ + /* to the other value. */ + /* */ + /* If either the horizontal or vertical resolution is zero, it is set */ + /* equal to the other value. */ + /* */ + /* A character width or height smaller than 1pt is set to 1pt; if */ + /* both resolution values are zero, they are set to 72dpi. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Pixel_Sizes */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in pixels). */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* pixel_width :: The nominal width, in pixels. */ + /* */ + /* pixel_height :: The nominal height, in pixels. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You should not rely on the resulting glyphs matching, or being */ + /* constrained, to this pixel size. Refer to @FT_Request_Size to */ + /* understand how requested sizes relate to actual sizes. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Glyph */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* glyph_index :: The index of the glyph in the font file. For */ + /* CID-keyed fonts (either in PS or in CFF format) */ + /* this argument specifies the CID value. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The loaded glyph may be transformed. See @FT_Set_Transform for */ + /* the details. */ + /* */ + /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ + /* returned for invalid CID values (this is, for CID values which */ + /* don't have a corresponding glyph in the font). See the discussion */ + /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Char */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object, according to its character code. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* char_code :: The glyph's character code, according to the */ + /* current charmap used in the face. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ); + + + /************************************************************************* + * + * @enum: + * FT_LOAD_XXX + * + * @description: + * A list of bit-field constants used with @FT_Load_Glyph to indicate + * what kind of operations to perform during glyph loading. + * + * @values: + * FT_LOAD_DEFAULT :: + * Corresponding to~0, this value is used as the default glyph load + * operation. In this case, the following happens: + * + * 1. FreeType looks for a bitmap for the glyph corresponding to the + * face's current size. If one is found, the function returns. + * The bitmap data can be accessed from the glyph slot (see note + * below). + * + * 2. If no embedded bitmap is searched or found, FreeType looks for a + * scalable outline. If one is found, it is loaded from the font + * file, scaled to device pixels, then `hinted' to the pixel grid + * in order to optimize it. The outline data can be accessed from + * the glyph slot (see note below). + * + * Note that by default, the glyph loader doesn't render outlines into + * bitmaps. The following flags are used to modify this default + * behaviour to more specific and useful cases. + * + * FT_LOAD_NO_SCALE :: + * Don't scale the loaded outline glyph but keep it in font units. + * + * This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and + * unsets @FT_LOAD_RENDER. + * + * If the font is `tricky' (see @FT_FACE_FLAG_TRICKY for more), using + * FT_LOAD_NO_SCALE usually yields meaningless outlines because the + * subglyphs must be scaled and positioned with hinting instructions. + * This can be solved by loading the font without FT_LOAD_NO_SCALE and + * setting the character size to `font->units_per_EM'. + * + * FT_LOAD_NO_HINTING :: + * Disable hinting. This generally generates `blurrier' bitmap glyphs + * when the glyph are rendered in any of the anti-aliased modes. See + * also the note below. + * + * This flag is implied by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_RENDER :: + * Call @FT_Render_Glyph after the glyph is loaded. By default, the + * glyph is rendered in @FT_RENDER_MODE_NORMAL mode. This can be + * overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME. + * + * This flag is unset by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_NO_BITMAP :: + * Ignore bitmap strikes when loading. Bitmap-only fonts ignore this + * flag. + * + * @FT_LOAD_NO_SCALE always sets this flag. + * + * FT_LOAD_VERTICAL_LAYOUT :: + * Load the glyph for vertical text layout. In particular, the + * `advance' value in the @FT_GlyphSlotRec structure is set to the + * `vertAdvance' value of the `metrics' field. + * + * In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use + * this flag currently. Reason is that in this case vertical metrics + * get synthesized, and those values are not always consistent across + * various font formats. + * + * FT_LOAD_FORCE_AUTOHINT :: + * Indicates that the auto-hinter is preferred over the font's native + * hinter. See also the note below. + * + * FT_LOAD_CROP_BITMAP :: + * Indicates that the font driver should crop the loaded bitmap glyph + * (i.e., remove all space around its black bits). Not all drivers + * implement this. + * + * FT_LOAD_PEDANTIC :: + * Indicates that the font driver should perform pedantic verifications + * during glyph loading. This is mostly used to detect broken glyphs + * in fonts. By default, FreeType tries to handle broken fonts also. + * + * In particular, errors from the TrueType bytecode engine are not + * passed to the application if this flag is not set; this might + * result in partially hinted or distorted glyphs in case a glyph's + * bytecode is buggy. + * + * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: + * Ignored. Deprecated. + * + * FT_LOAD_NO_RECURSE :: + * This flag is only used internally. It merely indicates that the + * font driver should not load composite glyphs recursively. Instead, + * it should set the `num_subglyph' and `subglyphs' values of the + * glyph slot accordingly, and set `glyph->format' to + * @FT_GLYPH_FORMAT_COMPOSITE. + * + * The description of sub-glyphs is not available to client + * applications for now. + * + * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. + * + * FT_LOAD_IGNORE_TRANSFORM :: + * Indicates that the transform matrix set by @FT_Set_Transform should + * be ignored. + * + * FT_LOAD_MONOCHROME :: + * This flag is used with @FT_LOAD_RENDER to indicate that you want to + * render an outline glyph to a 1-bit monochrome bitmap glyph, with + * 8~pixels packed into each byte of the bitmap data. + * + * Note that this has no effect on the hinting algorithm used. You + * should rather use @FT_LOAD_TARGET_MONO so that the + * monochrome-optimized hinting algorithm is used. + * + * FT_LOAD_LINEAR_DESIGN :: + * Indicates that the `linearHoriAdvance' and `linearVertAdvance' + * fields of @FT_GlyphSlotRec should be kept in font units. See + * @FT_GlyphSlotRec for details. + * + * FT_LOAD_NO_AUTOHINT :: + * Disable auto-hinter. See also the note below. + * + * FT_LOAD_COLOR :: + * This flag is used to request loading of color embedded-bitmap + * images. The resulting color bitmaps, if available, will have the + * @FT_PIXEL_MODE_BGRA format. When the flag is not used and color + * bitmaps are found, they will be converted to 256-level gray + * bitmaps transparently. Those bitmaps will be in the + * @FT_PIXEL_MODE_GRAY format. + * + * @note: + * By default, hinting is enabled and the font's native hinter (see + * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can + * disable hinting by setting @FT_LOAD_NO_HINTING or change the + * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set + * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be + * used at all. + * + * See the description of @FT_FACE_FLAG_TRICKY for a special exception + * (affecting only a handful of Asian fonts). + * + * Besides deciding which hinter to use, you can also decide which + * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. + * + * Note that the auto-hinter needs a valid Unicode cmap (either a native + * one or synthesized by FreeType) for producing correct results. If a + * font provides an incorrect mapping (for example, assigning the + * character code U+005A, LATIN CAPITAL LETTER Z, to a glyph depicting a + * mathematical integral sign), the auto-hinter might produce useless + * results. + * + */ +#define FT_LOAD_DEFAULT 0x0 +#define FT_LOAD_NO_SCALE ( 1L << 0 ) +#define FT_LOAD_NO_HINTING ( 1L << 1 ) +#define FT_LOAD_RENDER ( 1L << 2 ) +#define FT_LOAD_NO_BITMAP ( 1L << 3 ) +#define FT_LOAD_VERTICAL_LAYOUT ( 1L << 4 ) +#define FT_LOAD_FORCE_AUTOHINT ( 1L << 5 ) +#define FT_LOAD_CROP_BITMAP ( 1L << 6 ) +#define FT_LOAD_PEDANTIC ( 1L << 7 ) +#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ( 1L << 9 ) +#define FT_LOAD_NO_RECURSE ( 1L << 10 ) +#define FT_LOAD_IGNORE_TRANSFORM ( 1L << 11 ) +#define FT_LOAD_MONOCHROME ( 1L << 12 ) +#define FT_LOAD_LINEAR_DESIGN ( 1L << 13 ) +#define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) + /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ +#define FT_LOAD_COLOR ( 1L << 20 ) + + /* */ + + /* used internally only by certain font drivers! */ +#define FT_LOAD_ADVANCE_ONLY ( 1L << 8 ) +#define FT_LOAD_SBITS_ONLY ( 1L << 14 ) + + + /************************************************************************** + * + * @enum: + * FT_LOAD_TARGET_XXX + * + * @description: + * A list of values that are used to select a specific hinting algorithm + * to use by the hinter. You should OR one of these values to your + * `load_flags' when calling @FT_Load_Glyph. + * + * Note that font's native hinters may ignore the hinting algorithm you + * have specified (e.g., the TrueType bytecode interpreter). You can set + * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. + * + * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it + * always implies @FT_LOAD_FORCE_AUTOHINT. + * + * @values: + * FT_LOAD_TARGET_NORMAL :: + * This corresponds to the default hinting algorithm, optimized for + * standard gray-level rendering. For monochrome output, use + * @FT_LOAD_TARGET_MONO instead. + * + * FT_LOAD_TARGET_LIGHT :: + * A lighter hinting algorithm for non-monochrome modes. Many + * generated glyphs are more fuzzy but better resemble its original + * shape. A bit like rendering on Mac OS~X. + * + * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. + * + * FT_LOAD_TARGET_MONO :: + * Strong hinting algorithm that should only be used for monochrome + * output. The result is probably unpleasant if the glyph is rendered + * in non-monochrome modes. + * + * FT_LOAD_TARGET_LCD :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally + * decimated LCD displays. + * + * FT_LOAD_TARGET_LCD_V :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically + * decimated LCD displays. + * + * @note: + * You should use only _one_ of the FT_LOAD_TARGET_XXX values in your + * `load_flags'. They can't be ORed. + * + * If @FT_LOAD_RENDER is also set, the glyph is rendered in the + * corresponding mode (i.e., the mode which matches the used algorithm + * best). An exeption is FT_LOAD_TARGET_MONO since it implies + * @FT_LOAD_MONOCHROME. + * + * You can use a hinting algorithm that doesn't correspond to the same + * rendering mode. As an example, it is possible to use the `light' + * hinting algorithm and have the results rendered in horizontal LCD + * pixel mode, with code like + * + * { + * FT_Load_Glyph( face, glyph_index, + * load_flags | FT_LOAD_TARGET_LIGHT ); + * + * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); + * } + * + */ +#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) + +#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) +#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) +#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) +#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) +#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) + + + /************************************************************************** + * + * @macro: + * FT_LOAD_TARGET_MODE + * + * @description: + * Return the @FT_Render_Mode corresponding to a given + * @FT_LOAD_TARGET_XXX value. + * + */ +#define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Transform */ + /* */ + /* <Description> */ + /* A function used to set the transformation that is applied to glyph */ + /* images when they are loaded into a glyph slot through */ + /* @FT_Load_Glyph. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ + /* the identity matrix. */ + /* delta :: A pointer to the translation vector. Use~0 for the null */ + /* vector. */ + /* */ + /* <Note> */ + /* The transformation is only applied to scalable image formats after */ + /* the glyph has been loaded. It means that hinting is unaltered by */ + /* the transformation and is performed on the character size given in */ + /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ + /* */ + /* Note that this also transforms the `face.glyph.advance' field, but */ + /* *not* the values in `face.glyph.metrics'. */ + /* */ + FT_EXPORT( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Render_Mode */ + /* */ + /* <Description> */ + /* An enumeration type that lists the render modes supported by */ + /* FreeType~2. Each mode corresponds to a specific type of scanline */ + /* conversion performed on the outline. */ + /* */ + /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ + /* field in the @FT_GlyphSlotRec structure gives the format of the */ + /* returned bitmap. */ + /* */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ + /* */ + /* <Values> */ + /* FT_RENDER_MODE_NORMAL :: */ + /* This is the default render mode; it corresponds to 8-bit */ + /* anti-aliased bitmaps. */ + /* */ + /* FT_RENDER_MODE_LIGHT :: */ + /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ + /* defined as a separate value because render modes are also used */ + /* indirectly to define hinting algorithm selectors. See */ + /* @FT_LOAD_TARGET_XXX for details. */ + /* */ + /* FT_RENDER_MODE_MONO :: */ + /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ + /* opacity). */ + /* */ + /* FT_RENDER_MODE_LCD :: */ + /* This mode corresponds to horizontal RGB and BGR sub-pixel */ + /* displays like LCD screens. It produces 8-bit bitmaps that are */ + /* 3~times the width of the original glyph outline in pixels, and */ + /* which use the @FT_PIXEL_MODE_LCD mode. */ + /* */ + /* FT_RENDER_MODE_LCD_V :: */ + /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ + /* (like PDA screens, rotated LCD displays, etc.). It produces */ + /* 8-bit bitmaps that are 3~times the height of the original */ + /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ + /* */ + /* <Note> */ + /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ + /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ + /* (not active in the default builds). It is up to the caller to */ + /* either call @FT_Library_SetLcdFilter (if available) or do the */ + /* filtering itself. */ + /* */ + /* The selected render mode only affects vector glyphs of a font. */ + /* Embedded bitmaps often have a different pixel mode like */ + /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ + /* them into 8-bit pixmaps. */ + /* */ + typedef enum FT_Render_Mode_ + { + FT_RENDER_MODE_NORMAL = 0, + FT_RENDER_MODE_LIGHT, + FT_RENDER_MODE_MONO, + FT_RENDER_MODE_LCD, + FT_RENDER_MODE_LCD_V, + + FT_RENDER_MODE_MAX + + } FT_Render_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_render_mode_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated. Use the corresponding */ + /* @FT_Render_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ + /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ + /* */ +#define ft_render_mode_normal FT_RENDER_MODE_NORMAL +#define ft_render_mode_mono FT_RENDER_MODE_MONO + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Render_Glyph */ + /* */ + /* <Description> */ + /* Convert a given glyph image to a bitmap. It does so by inspecting */ + /* the glyph image format, finding the relevant renderer, and */ + /* invoking it. */ + /* */ + /* <InOut> */ + /* slot :: A handle to the glyph slot containing the image to */ + /* convert. */ + /* */ + /* <Input> */ + /* render_mode :: This is the render mode used to render the glyph */ + /* image into a bitmap. See @FT_Render_Mode for a */ + /* list of possible values. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Kerning_Mode */ + /* */ + /* <Description> */ + /* An enumeration used to specify which kerning values to return in */ + /* @FT_Get_Kerning. */ + /* */ + /* <Values> */ + /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ + /* distances (value is~0). */ + /* */ + /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ + /* distances. */ + /* */ + /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ + /* units. */ + /* */ + typedef enum FT_Kerning_Mode_ + { + FT_KERNING_DEFAULT = 0, + FT_KERNING_UNFITTED, + FT_KERNING_UNSCALED + + } FT_Kerning_Mode; + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_default */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_DEFAULT */ + /* instead. */ + /* */ +#define ft_kerning_default FT_KERNING_DEFAULT + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_unfitted */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_UNFITTED */ + /* instead. */ + /* */ +#define ft_kerning_unfitted FT_KERNING_UNFITTED + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_unscaled */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_UNSCALED */ + /* instead. */ + /* */ +#define ft_kerning_unscaled FT_KERNING_UNSCALED + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Kerning */ + /* */ + /* <Description> */ + /* Return the kerning vector between two glyphs of a same face. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* kern_mode :: See @FT_Kerning_Mode for more information. */ + /* Determines the scale and dimension of the returned */ + /* kerning vector. */ + /* */ + /* <Output> */ + /* akerning :: The kerning vector. This is either in font units */ + /* or in pixels (26.6 format) for scalable formats, */ + /* and in pixels for fixed-sizes formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this method. Other layouts, or more sophisticated */ + /* kernings, are out of the scope of this API function -- they can be */ + /* implemented through format-specific interfaces. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Track_Kerning */ + /* */ + /* <Description> */ + /* Return the track kerning for a given face object at a given size. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* point_size :: The point size in 16.16 fractional points. */ + /* */ + /* degree :: The degree of tightness. Increasingly negative */ + /* values represent tighter track kerning, while */ + /* increasingly positive values represent looser track */ + /* kerning. Value zero means no track kerning. */ + /* */ + /* <Output> */ + /* akerning :: The kerning in 16.16 fractional points, to be */ + /* uniformly applied between all glyphs. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Currently, only the Type~1 font driver supports track kerning, */ + /* using data from AFM files (if attached with @FT_Attach_File or */ + /* @FT_Attach_Stream). */ + /* */ + /* Only very few AFM files come with track kerning data; please refer */ + /* to the Adobe's AFM specification for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Track_Kerning( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII name of a given glyph in a face. This only */ + /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* buffer_max :: The maximum number of bytes available in the */ + /* buffer. */ + /* */ + /* <Output> */ + /* buffer :: A pointer to a target buffer where the name is */ + /* copied to. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error is returned if the face doesn't provide glyph names or if */ + /* the glyph index is invalid. In all cases of failure, the first */ + /* byte of `buffer' is set to~0 to indicate an empty name. */ + /* */ + /* The glyph name is truncated to fit within the buffer if it is too */ + /* long. The returned string is always zero-terminated. */ + /* */ + /* Be aware that FreeType reorders glyph indices internally so that */ + /* glyph index~0 always corresponds to the `missing glyph' (called */ + /* `.notdef'). */ + /* */ + /* This function is not compiled within the library if the config */ + /* macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in */ + /* `include/freetype/config/ftoptions.h'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Postscript_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII PostScript name of a given face, if available. */ + /* This only works with PostScript and TrueType fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to the face's PostScript name. NULL if unavailable. */ + /* */ + /* <Note> */ + /* The returned pointer is owned by the face and is destroyed with */ + /* it. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Postscript_Name( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap by its encoding tag (as listed in */ + /* `freetype.h'). */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* encoding :: A handle to the selected encoding. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if no charmap in the face */ + /* corresponds to the encoding queried here. */ + /* */ + /* Because many fonts contain more than a single cmap for Unicode */ + /* encoding, this function has some special code to select the one */ + /* which covers Unicode best (`best' in the sense that a UCS-4 cmap */ + /* is preferred to a UCS-2 cmap). It is thus preferable to */ + /* @FT_Set_Charmap in this case. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap for character code to glyph index mapping. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the selected charmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if the charmap is not part of */ + /* the face (i.e., if it is not listed in the `face->charmaps' */ + /* table). */ + /* */ + /* It also fails if a type~14 charmap is selected. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ); + + + /************************************************************************* + * + * @function: + * FT_Get_Charmap_Index + * + * @description: + * Retrieve index of a given charmap. + * + * @input: + * charmap :: + * A handle to a charmap. + * + * @return: + * The index into the array of character maps within the face to which + * `charmap' belongs. If an error occurs, -1 is returned. + * + */ + FT_EXPORT( FT_Int ) + FT_Get_Charmap_Index( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Char_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code. This function */ + /* uses a charmap object to do the mapping. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within the */ + /* file. This is done to ensure that value~0 always corresponds to */ + /* the `missing glyph'. If the first glyph is not named `.notdef', */ + /* then for Type~1 and Type~42 fonts, `.notdef' will be moved into */ + /* the glyph ID~0 position, and whatever was there will be moved to */ + /* the position `.notdef' had. For Type~1 fonts, if there is no */ + /* `.notdef' glyph at all, then one will be created at index~0 and */ + /* whatever was there will be moved to the last index -- Type~42 */ + /* fonts are considered invalid under this condition. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_First_Char */ + /* */ + /* <Description> */ + /* This function is used to return the first character code in the */ + /* current charmap of a given face. It also returns the */ + /* corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of first character code. 0~if charmap is */ + /* empty. */ + /* */ + /* <Return> */ + /* The charmap's first character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_Next_Char to be able to */ + /* parse all character codes available in a given charmap. The code */ + /* should look like this: */ + /* */ + /* { */ + /* FT_ULong charcode; */ + /* FT_UInt gindex; */ + /* */ + /* */ + /* charcode = FT_Get_First_Char( face, &gindex ); */ + /* while ( gindex != 0 ) */ + /* { */ + /* ... do something with (charcode,gindex) pair ... */ + /* */ + /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ + /* } */ + /* } */ + /* */ + /* Note that `*agindex' is set to~0 if the charmap is empty. The */ + /* result itself can be~0 in two cases: if the charmap is empty or */ + /* if the value~0 is the first valid character code. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Next_Char */ + /* */ + /* <Description> */ + /* This function is used to return the next character code in the */ + /* current charmap of a given face following the value `char_code', */ + /* as well as the corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* char_code :: The starting character code. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of next character code. 0~if charmap */ + /* is empty. */ + /* */ + /* <Return> */ + /* The charmap's next character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_First_Char to walk */ + /* over all character codes available in a given charmap. See the */ + /* note for this function for a simple code example. */ + /* */ + /* Note that `*agindex' is set to~0 when there are no more codes in */ + /* the charmap. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong char_code, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Name_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given glyph name. This function uses */ + /* driver specific objects to do the translation. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* glyph_name :: The glyph name. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ); + + + /************************************************************************* + * + * @macro: + * FT_SUBGLYPH_FLAG_XXX + * + * @description: + * A list of constants used to describe subglyphs. Please refer to the + * TrueType specification for the meaning of the various flags. + * + * @values: + * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: + * FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES :: + * FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID :: + * FT_SUBGLYPH_FLAG_SCALE :: + * FT_SUBGLYPH_FLAG_XY_SCALE :: + * FT_SUBGLYPH_FLAG_2X2 :: + * FT_SUBGLYPH_FLAG_USE_MY_METRICS :: + * + */ +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 + + + /************************************************************************* + * + * @func: + * FT_Get_SubGlyph_Info + * + * @description: + * Retrieve a description of a given subglyph. Only use it if + * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is + * returned otherwise. + * + * @input: + * glyph :: + * The source glyph slot. + * + * sub_index :: + * The index of the subglyph. Must be less than + * `glyph->num_subglyphs'. + * + * @output: + * p_index :: + * The glyph index of the subglyph. + * + * p_flags :: + * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. + * + * p_arg1 :: + * The subglyph's first argument (if any). + * + * p_arg2 :: + * The subglyph's second argument (if any). + * + * p_transform :: + * The subglyph transformation (if any). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be + * interpreted depending on the flags returned in `*p_flags'. See the + * TrueType specification for details. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, + FT_UInt sub_index, + FT_Int *p_index, + FT_UInt *p_flags, + FT_Int *p_arg1, + FT_Int *p_arg2, + FT_Matrix *p_transform ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FSTYPE_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `fsType' field of the OS/2 table */ + /* in a TrueType or OpenType font and the `FSType' entry in a */ + /* PostScript font. These bit flags are returned by */ + /* @FT_Get_FSType_Flags; they inform client applications of embedding */ + /* and subsetting restrictions associated with a font. */ + /* */ + /* See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for */ + /* more details. */ + /* */ + /* <Values> */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ + /* Fonts with no fsType bit set may be embedded and permanently */ + /* installed on the remote system by an application. */ + /* */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ + /* Fonts that have only this bit set must not be modified, embedded */ + /* or exchanged in any manner without first obtaining permission of */ + /* the font software copyright owner. */ + /* */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ + /* If this bit is set, the font may be embedded and temporarily */ + /* loaded on the remote system. Documents containing Preview & */ + /* Print fonts must be opened `read-only'; no edits can be applied */ + /* to the document. */ + /* */ + /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ + /* If this bit is set, the font may be embedded but must only be */ + /* installed temporarily on other systems. In contrast to Preview */ + /* & Print fonts, documents containing editable fonts may be opened */ + /* for reading, editing is permitted, and changes may be saved. */ + /* */ + /* FT_FSTYPE_NO_SUBSETTING :: */ + /* If this bit is set, the font may not be subsetted prior to */ + /* embedding. */ + /* */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ + /* If this bit is set, only bitmaps contained in the font may be */ + /* embedded; no outline data may be embedded. If there are no */ + /* bitmaps available in the font, then the font is unembeddable. */ + /* */ + /* <Note> */ + /* While the fsType flags can indicate that a font may be embedded, a */ + /* license with the font vendor may be separately required to use the */ + /* font in this way. */ + /* */ +#define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 +#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 +#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 +#define FT_FSTYPE_EDITABLE_EMBEDDING 0x0008 +#define FT_FSTYPE_NO_SUBSETTING 0x0100 +#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_FSType_Flags */ + /* */ + /* <Description> */ + /* Return the fsType flags for a font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* The fsType flags, @FT_FSTYPE_XXX. */ + /* */ + /* <Note> */ + /* Use this function rather than directly reading the `fs_type' field */ + /* in the @PS_FontInfoRec structure which is only guaranteed to */ + /* return the correct results for Type~1 fonts. */ + /* */ + /* <Since> */ + /* 2.3.8 */ + /* */ + FT_EXPORT( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_variants */ + /* */ + /* <Title> */ + /* Glyph Variants */ + /* */ + /* <Abstract> */ + /* The FreeType~2 interface to Unicode Ideographic Variation */ + /* Sequences (IVS), using the SFNT cmap format~14. */ + /* */ + /* <Description> */ + /* Many CJK characters have variant forms. They are a sort of grey */ + /* area somewhere between being totally irrelevant and semantically */ + /* distinct; for this reason, the Unicode consortium decided to */ + /* introduce Ideographic Variation Sequences (IVS), consisting of a */ + /* Unicode base character and one of 240 variant selectors */ + /* (U+E0100-U+E01EF), instead of further extending the already huge */ + /* code range for CJK characters. */ + /* */ + /* An IVS is registered and unique; for further details please refer */ + /* to Unicode Technical Standard #37, the Ideographic Variation */ + /* Database: */ + /* */ + /* http://www.unicode.org/reports/tr37/ */ + /* */ + /* To date (November 2012), the character with the most variants is */ + /* U+9089, having 31 such IVS. */ + /* */ + /* Adobe and MS decided to support IVS with a new cmap subtable */ + /* (format~14). It is an odd subtable because it is not a mapping of */ + /* input code points to glyphs, but contains lists of all variants */ + /* supported by the font. */ + /* */ + /* A variant may be either `default' or `non-default'. A default */ + /* variant is the one you will get for that code point if you look it */ + /* up in the standard Unicode cmap. A non-default variant is a */ + /* different glyph. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIndex */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code as modified by */ + /* the variation selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character code point in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode code point of the variation selector. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means either `undefined character code', or */ + /* `undefined selector code', or `no variation selector cmap */ + /* subtable', or `current CharMap is not Unicode'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + /* This function is only meaningful if */ + /* a) the font has a variation selector cmap sub table, */ + /* and */ + /* b) the current charmap has a Unicode encoding. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIsDefault */ + /* */ + /* <Description> */ + /* Check whether this variant of this Unicode character is the one to */ + /* be found in the `cmap'. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode codepoint of the variation selector. */ + /* */ + /* <Return> */ + /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ + /* variation selector cmap, or -1 if it is not a variant. */ + /* */ + /* <Note> */ + /* This function is only meaningful if the font has a variation */ + /* selector cmap subtable. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantSelectors */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* in the font. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to an array of selector code points, or NULL if there is */ + /* no valid variant selector cmap subtable. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantsOfChar */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* for the specified character code. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* <Return> */ + /* A pointer to an array of variant selector code points which are */ + /* active for the given character, or NULL if the corresponding list */ + /* is empty. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharsOfVariant */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode character codes found for */ + /* the specified variant selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* variantSelector :: */ + /* The variant selector code point in Unicode. */ + /* */ + /* <Return> */ + /* A list of all the code points which are specified by this selector */ + /* (both default and non-default codes are returned) or NULL if there */ + /* is no valid cmap or the variant selector is invalid. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /* <Title> */ + /* Computations */ + /* */ + /* <Abstract> */ + /* Crunching fixed numbers and vectors. */ + /* */ + /* <Description> */ + /* This section contains various functions used to perform */ + /* computations on 16.16 fixed-float numbers or 2d vectors. */ + /* */ + /* <Order> */ + /* FT_MulDiv */ + /* FT_MulFix */ + /* FT_DivFix */ + /* FT_RoundFix */ + /* FT_CeilFix */ + /* FT_FloorFix */ + /* FT_Vector_Transform */ + /* FT_Matrix_Multiply */ + /* FT_Matrix_Invert */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* with maximum accuracy (it uses a 64-bit intermediate integer */ + /* whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ); + + + /* */ + + /* The following #if 0 ... #endif is for the documentation formatter, */ + /* hiding the internal `FT_MULFIX_INLINED' macro. */ + +#if 0 + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */ + /* used to multiply a given value by a 16.16 fixed-point factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*b)/0x10000'. */ + /* */ + /* <Note> */ + /* This function has been optimized for the case where the absolute */ + /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ + /* As this happens mainly when scaling from notional units to */ + /* fractional pixels in FreeType, it resulted in noticeable speed */ + /* improvements between versions 2.x and 1.x. */ + /* */ + /* As a conclusion, always try to place a 16.16 factor as the */ + /* _second_ argument of this function; this can make a great */ + /* difference. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); + + /* */ +#endif + +#ifdef FT_MULFIX_INLINED +#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b ) +#else + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); +#endif + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_DivFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */ + /* used to divide a given value by a 16.16 fixed-point factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*0x10000)/b'. */ + /* */ + /* <Note> */ + /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ + /* 32~bits, then the division is computed directly. Otherwise, we */ + /* use a specialized version of @FT_MulDiv. */ + /* */ + FT_EXPORT( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_RoundFix */ + /* */ + /* <Description> */ + /* A very simple function used to round a 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number to be rounded. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x8000) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_RoundFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_CeilFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the ceiling function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the ceiling function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x10000 - 1) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_CeilFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FloorFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the floor function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the floor function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `a & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_FloorFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Vector_Transform */ + /* */ + /* <Description> */ + /* Transform a single vector through a 2x2 matrix. */ + /* */ + /* <InOut> */ + /* vector :: The target vector to transform. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the source 2x2 matrix. */ + /* */ + /* <Note> */ + /* The result is undefined if either `vector' or `matrix' is invalid. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Transform( FT_Vector* vec, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* version */ + /* */ + /* <Title> */ + /* FreeType Version */ + /* */ + /* <Abstract> */ + /* Functions and macros related to FreeType versions. */ + /* */ + /* <Description> */ + /* Note that those functions and macros are of limited use because */ + /* even a new release of FreeType with only documentation changes */ + /* increases the version number. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FREETYPE_XXX + * + * @description: + * These three macros identify the FreeType source code version. + * Use @FT_Library_Version to access them at runtime. + * + * @values: + * FREETYPE_MAJOR :: The major version number. + * FREETYPE_MINOR :: The minor version number. + * FREETYPE_PATCH :: The patch level. + * + * @note: + * The version number of FreeType if built as a dynamic link library + * with the `libtool' package is _not_ controlled by these three + * macros. + * + */ +#define FREETYPE_MAJOR 2 +#define FREETYPE_MINOR 5 +#define FREETYPE_PATCH 0 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Library_Version */ + /* */ + /* <Description> */ + /* Return the version of the FreeType library being used. This is */ + /* useful when dynamically linking to the library, since one cannot */ + /* use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and */ + /* @FREETYPE_PATCH. */ + /* */ + /* <Input> */ + /* library :: A source library handle. */ + /* */ + /* <Output> */ + /* amajor :: The major version number. */ + /* */ + /* aminor :: The minor version number. */ + /* */ + /* apatch :: The patch version number. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' argument is because */ + /* certain programs implement library initialization in a custom way */ + /* that doesn't use @FT_Init_FreeType. */ + /* */ + /* In such cases, the library version might not be available before */ + /* the library object has been created. */ + /* */ + FT_EXPORT( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_CheckTrueTypePatents */ + /* */ + /* <Description> */ + /* Parse all bytecode instructions of a TrueType font file to check */ + /* whether any of the patented opcodes are used. This is only useful */ + /* if you want to be able to use the unpatented hinter with */ + /* fonts that do *not* use these opcodes. */ + /* */ + /* Note that this function parses *all* glyph instructions in the */ + /* font file, which may be slow. */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* <Return> */ + /* 1~if this is a TrueType font that uses one of the patented */ + /* opcodes, 0~otherwise. */ + /* */ + /* <Note> */ + /* Since May 2010, TrueType hinting is no longer patented. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_CheckTrueTypePatents( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* <Description> */ + /* Enable or disable the unpatented hinter for a given face. */ + /* Only enable it if you have determined that the face doesn't */ + /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* value :: New boolean setting. */ + /* */ + /* <Return> */ + /* The old setting value. This will always be false if this is not */ + /* an SFNT font, or if the unpatented hinter is not compiled in this */ + /* instance of the library. */ + /* */ + /* <Note> */ + /* Since May 2010, TrueType hinting is no longer patented. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_SetUnpatentedHinting( FT_Face face, + FT_Bool value ); + + /* */ + + +FT_END_HEADER + +#endif /* __FREETYPE_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftadvanc.h b/drivers/freetype/include/freetype/ftadvanc.h new file mode 100644 index 0000000000..012b74b812 --- /dev/null +++ b/drivers/freetype/include/freetype/ftadvanc.h @@ -0,0 +1,182 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.h */ +/* */ +/* Quick computation of advance widths (specification only). */ +/* */ +/* Copyright 2008, 2013 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 __FTADVANC_H__ +#define __FTADVANC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * quick_advance + * + * @title: + * Quick retrieval of advance values + * + * @abstract: + * Retrieve horizontal and vertical advance values without processing + * glyph outlines, if possible. + * + * @description: + * This section contains functions to quickly extract advance values + * without handling glyph outlines, if possible. + */ + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_ADVANCE_FLAG_FAST_ONLY */ + /* */ + /* <Description> */ + /* A bit-flag to be OR-ed with the `flags' parameter of the */ + /* @FT_Get_Advance and @FT_Get_Advances functions. */ + /* */ + /* If set, it indicates that you want these functions to fail if the */ + /* corresponding hinting mode or font driver doesn't allow for very */ + /* quick advance computation. */ + /* */ + /* Typically, glyphs which are either unscaled, unhinted, bitmapped, */ + /* or light-hinted can have their advance width computed very */ + /* quickly. */ + /* */ + /* Normal and bytecode hinted modes, which require loading, scaling, */ + /* and hinting of the glyph outline, are extremely slow by */ + /* comparison. */ + /* */ +#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000UL + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advance */ + /* */ + /* <Description> */ + /* Retrieve the advance value of a given glyph outline in an */ + /* @FT_Face. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph, used to determine what kind */ + /* of advances you need. */ + /* <Output> */ + /* padvance :: The advance value. If scaling is performed (based on */ + /* the value of `load_flags'), the advance value is in */ + /* 16.16 format. Otherwise, it is in font units. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ + /* vertical advance corresponding to a vertical layout. */ + /* Otherwise, it is the horizontal advance in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* A scaled advance is returned in 16.16 format but isn't transformed */ + /* by the affine transformation specified by @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags, + FT_Fixed *padvance ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advances */ + /* */ + /* <Description> */ + /* Retrieve the advance values of several glyph outlines in an */ + /* @FT_Face. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* start :: The first glyph index. */ + /* */ + /* count :: The number of advance values you want to retrieve. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph. */ + /* */ + /* <Output> */ + /* padvance :: The advance values. This array, to be provided by the */ + /* caller, must contain at least `count' elements. */ + /* */ + /* If scaling is performed (based on the value of */ + /* `load_flags'), the advance values are in 16.16 format. */ + /* Otherwise, they are in font units. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ + /* vertical advances corresponding to a vertical layout. */ + /* Otherwise, they are the horizontal advances in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* Scaled advances are returned in 16.16 format but aren't */ + /* transformed by the affine transformation specified by */ + /* @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 load_flags, + FT_Fixed *padvances ); + +/* */ + + +FT_END_HEADER + +#endif /* __FTADVANC_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftautoh.h b/drivers/freetype/include/freetype/ftautoh.h new file mode 100644 index 0000000000..5e1153a1c1 --- /dev/null +++ b/drivers/freetype/include/freetype/ftautoh.h @@ -0,0 +1,357 @@ +/***************************************************************************/ +/* */ +/* ftautoh.h */ +/* */ +/* FreeType API for controlling the auto-hinter (specification only). */ +/* */ +/* Copyright 2012, 2013 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 __FTAUTOH_H__ +#define __FTAUTOH_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * auto_hinter + * + * @title: + * The auto-hinter + * + * @abstract: + * Controlling the auto-hinting module. + * + * @description: + * While FreeType's auto-hinter doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * Note that the auto-hinter's module name is `autofitter' for + * historical reasons. + * + */ + + + /************************************************************************** + * + * @property: + * glyph-to-script-map + * + * @description: + * *Experimental* *only* + * + * The auto-hinter provides various script modules to hint glyphs. + * Examples of supported scripts are Latin or CJK. Before a glyph is + * auto-hinted, the Unicode character map of the font gets examined, and + * the script is then determined based on Unicode character ranges, see + * below. + * + * OpenType fonts, however, often provide much more glyphs than + * character codes (small caps, superscripts, ligatures, swashes, etc.), + * to be controlled by so-called `features'. Handling OpenType features + * can be quite complicated and thus needs a separate library on top of + * FreeType. + * + * The mapping between glyph indices and scripts (in the auto-hinter + * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an + * array with `num_glyphs' elements, as found in the font's @FT_Face + * structure. The `glyph-to-script-map' property returns a pointer to + * this array which can be modified as needed. Note that the + * modification should happen before the first glyph gets processed by + * the auto-hinter so that the global analysis of the font shapes + * actually uses the modified mapping. + * + * The following example code demonstrates how to access it (omitting + * the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_GlyphToScriptMap prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * + * prop.face = face; + * + * FT_Property_Get( library, "autofitter", + * "glyph-to-script-map", &prop ); + * + * // adjust `prop.map' as needed right here + * + * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT ); + * } + * + */ + + + /************************************************************************** + * + * @enum: + * FT_AUTOHINTER_SCRIPT_XXX + * + * @description: + * *Experimental* *only* + * + * A list of constants used for the @glyph-to-script-map property to + * specify the script submodule the auto-hinter should use for hinting a + * particular glyph. + * + * @values: + * FT_AUTOHINTER_SCRIPT_NONE :: + * Don't auto-hint this glyph. + * + * FT_AUTOHINTER_SCRIPT_LATIN :: + * Apply the latin auto-hinter. For the auto-hinter, `latin' is a + * very broad term, including Cyrillic and Greek also since characters + * from those scripts share the same design constraints. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0020 - U+007F // Basic Latin (no control characters) + * U+00A0 - U+00FF // Latin-1 Supplement (no control characters) + * U+0100 - U+017F // Latin Extended-A + * U+0180 - U+024F // Latin Extended-B + * U+0250 - U+02AF // IPA Extensions + * U+02B0 - U+02FF // Spacing Modifier Letters + * U+0300 - U+036F // Combining Diacritical Marks + * U+0370 - U+03FF // Greek and Coptic + * U+0400 - U+04FF // Cyrillic + * U+0500 - U+052F // Cyrillic Supplement + * U+1D00 - U+1D7F // Phonetic Extensions + * U+1D80 - U+1DBF // Phonetic Extensions Supplement + * U+1DC0 - U+1DFF // Combining Diacritical Marks Supplement + * U+1E00 - U+1EFF // Latin Extended Additional + * U+1F00 - U+1FFF // Greek Extended + * U+2000 - U+206F // General Punctuation + * U+2070 - U+209F // Superscripts and Subscripts + * U+20A0 - U+20CF // Currency Symbols + * U+2150 - U+218F // Number Forms + * U+2460 - U+24FF // Enclosed Alphanumerics + * U+2C60 - U+2C7F // Latin Extended-C + * U+2DE0 - U+2DFF // Cyrillic Extended-A + * U+2E00 - U+2E7F // Supplemental Punctuation + * U+A640 - U+A69F // Cyrillic Extended-B + * U+A720 - U+A7FF // Latin Extended-D + * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligatures) + * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols + * U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_CJK :: + * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old + * Vietnamese, and some other scripts. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+1100 - U+11FF // Hangul Jamo + * U+2E80 - U+2EFF // CJK Radicals Supplement + * U+2F00 - U+2FDF // Kangxi Radicals + * U+2FF0 - U+2FFF // Ideographic Description Characters + * U+3000 - U+303F // CJK Symbols and Punctuation + * U+3040 - U+309F // Hiragana + * U+30A0 - U+30FF // Katakana + * U+3100 - U+312F // Bopomofo + * U+3130 - U+318F // Hangul Compatibility Jamo + * U+3190 - U+319F // Kanbun + * U+31A0 - U+31BF // Bopomofo Extended + * U+31C0 - U+31EF // CJK Strokes + * U+31F0 - U+31FF // Katakana Phonetic Extensions + * U+3200 - U+32FF // Enclosed CJK Letters and Months + * U+3300 - U+33FF // CJK Compatibility + * U+3400 - U+4DBF // CJK Unified Ideographs Extension A + * U+4DC0 - U+4DFF // Yijing Hexagram Symbols + * U+4E00 - U+9FFF // CJK Unified Ideographs + * U+A960 - U+A97F // Hangul Jamo Extended-A + * U+AC00 - U+D7AF // Hangul Syllables + * U+D7B0 - U+D7FF // Hangul Jamo Extended-B + * U+F900 - U+FAFF // CJK Compatibility Ideographs + * U+FE10 - U+FE1F // Vertical forms + * U+FE30 - U+FE4F // CJK Compatibility Forms + * U+FF00 - U+FFEF // Halfwidth and Fullwidth Forms + * U+1B000 - U+1B0FF // Kana Supplement + * U+1D300 - U+1D35F // Tai Xuan Hing Symbols + * U+1F200 - U+1F2FF // Enclosed Ideographic Supplement + * U+20000 - U+2A6DF // CJK Unified Ideographs Extension B + * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C + * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D + * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_INDIC :: + * Apply the indic auto-hinter, covering all major scripts from the + * Indian sub-continent and some other related scripts like Thai, Lao, + * or Tibetan. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0900 - U+0DFF // Indic Range + * U+0F00 - U+0FFF // Tibetan + * U+1900 - U+194F // Limbu + * U+1B80 - U+1BBF // Sundanese + * U+1C80 - U+1CDF // Meetei Mayak + * U+A800 - U+A82F // Syloti Nagri + * U+11800 - U+118DF // Sharada + * } + * + * Note that currently Indic support is rudimentary only, missing blue + * zone support. + * + */ +#define FT_AUTOHINTER_SCRIPT_NONE 0 +#define FT_AUTOHINTER_SCRIPT_LATIN 1 +#define FT_AUTOHINTER_SCRIPT_CJK 2 +#define FT_AUTOHINTER_SCRIPT_INDIC 3 + + + /************************************************************************** + * + * @struct: + * FT_Prop_GlyphToScriptMap + * + * @description: + * *Experimental* *only* + * + * The data exchange structure for the @glyph-to-script-map property. + * + */ + typedef struct FT_Prop_GlyphToScriptMap_ + { + FT_Face face; + FT_Byte* map; + + } FT_Prop_GlyphToScriptMap; + + + /************************************************************************** + * + * @property: + * fallback-script + * + * @description: + * *Experimental* *only* + * + * If no auto-hinter script module can be assigned to a glyph, a + * fallback script gets assigned to it (see also the + * @glyph-to-script-map property). By default, this is + * @FT_AUTOHINTER_SCRIPT_CJK. Using the `fallback-script' property, + * this fallback value can be changed. + * + * { + * FT_Library library; + * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "fallback-script", &fallback_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map which eventually uses the + * fallback script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the fallback glyph will affect this face. + * + */ + + + /************************************************************************** + * + * @property: + * increase-x-height + * + * @description: + * For ppem values in the range 6~<= ppem <= `increase-x-height', round + * up the font's x~height much more often than normally. If the value + * is set to~0, which is the default, this feature is switched off. Use + * this property to improve the legibility of small font sizes if + * necessary. + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_IncreaseXHeight prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * FT_Set_Char_Size( face, 10 * 64, 0, 72, 0 ); + * + * prop.face = face; + * prop.limit = 14; + * + * FT_Property_Set( library, "autofitter", + * "increase-x-height", &prop ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * Set this value right after calling @FT_Set_Char_Size, but before + * loading any glyph (using the auto-hinter). + * + */ + + + /************************************************************************** + * + * @struct: + * FT_Prop_IncreaseXHeight + * + * @description: + * The data exchange structure for the @increase-x-height property. + * + */ + typedef struct FT_Prop_IncreaseXHeight_ + { + FT_Face face; + FT_UInt limit; + + } FT_Prop_IncreaseXHeight; + + + /* */ + +FT_END_HEADER + +#endif /* __FTAUTOH_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftbbox.h b/drivers/freetype/include/freetype/ftbbox.h new file mode 100644 index 0000000000..976691956f --- /dev/null +++ b/drivers/freetype/include/freetype/ftbbox.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* ftbbox.h */ +/* */ +/* FreeType exact bbox computation (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2007, 2011 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This component has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /* It is separated from the rest of the engine for various technical */ + /* reasons. It may well be integrated in `ftoutln' later. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTBBOX_H__ +#define __FTBBOX_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_BBox */ + /* */ + /* <Description> */ + /* Compute the exact bounding box of an outline. This is slower */ + /* than computing the control box. However, it uses an advanced */ + /* algorithm which returns _very_ quickly when the two boxes */ + /* coincide. Otherwise, the outline Bézier arcs are traversed to */ + /* extract their extrema. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline. */ + /* */ + /* <Output> */ + /* abbox :: The outline's exact bounding box. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If the font is tricky and the glyph has been loaded with */ + /* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */ + /* reasonable values for the BBox it is necessary to load the glyph */ + /* at a large ppem value (so that the hinting instructions can */ + /* properly shift and scale the subglyphs), then extracting the BBox */ + /* which can be eventually converted back to font units. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBBOX_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/drivers/freetype/include/freetype/ftbdf.h b/drivers/freetype/include/freetype/ftbdf.h new file mode 100644 index 0000000000..4f8baf8401 --- /dev/null +++ b/drivers/freetype/include/freetype/ftbdf.h @@ -0,0 +1,209 @@ +/***************************************************************************/ +/* */ +/* ftbdf.h */ +/* */ +/* FreeType API for accessing BDF-specific strings (specification). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2009 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 __FTBDF_H__ +#define __FTBDF_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bdf_fonts */ + /* */ + /* <Title> */ + /* BDF and PCF Files */ + /* */ + /* <Abstract> */ + /* BDF and PCF specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions specific to BDF */ + /* and PCF fonts. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_PropertyType + * + * @description: + * A list of BDF property types. + * + * @values: + * BDF_PROPERTY_TYPE_NONE :: + * Value~0 is used to indicate a missing property. + * + * BDF_PROPERTY_TYPE_ATOM :: + * Property is a string atom. + * + * BDF_PROPERTY_TYPE_INTEGER :: + * Property is a 32-bit signed integer. + * + * BDF_PROPERTY_TYPE_CARDINAL :: + * Property is a 32-bit unsigned integer. + */ + typedef enum BDF_PropertyType_ + { + BDF_PROPERTY_TYPE_NONE = 0, + BDF_PROPERTY_TYPE_ATOM = 1, + BDF_PROPERTY_TYPE_INTEGER = 2, + BDF_PROPERTY_TYPE_CARDINAL = 3 + + } BDF_PropertyType; + + + /********************************************************************** + * + * @type: + * BDF_Property + * + * @description: + * A handle to a @BDF_PropertyRec structure to model a given + * BDF/PCF property. + */ + typedef struct BDF_PropertyRec_* BDF_Property; + + + /********************************************************************** + * + * @struct: + * BDF_PropertyRec + * + * @description: + * This structure models a given BDF/PCF property. + * + * @fields: + * type :: + * The property type. + * + * u.atom :: + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. + * + * u.integer :: + * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. + * + * u.cardinal :: + * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. + */ + typedef struct BDF_PropertyRec_ + { + BDF_PropertyType type; + union { + const char* atom; + FT_Int32 integer; + FT_UInt32 cardinal; + + } u; + + } BDF_PropertyRec; + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Charset_ID + * + * @description: + * Retrieve a BDF font character set identity, according to + * the BDF specification. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * acharset_encoding :: + * Charset encoding, as a C~string, owned by the face. + * + * acharset_registry :: + * Charset registry, as a C~string, owned by the face. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with BDF faces, returning an error otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Property + * + * @description: + * Retrieve a BDF property from a BDF or PCF font file. + * + * @input: + * face :: A handle to the input face. + * + * name :: The property name. + * + * @output: + * aproperty :: The property. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function works with BDF _and_ PCF fonts. It returns an error + * otherwise. It also returns an error if the property is not in the + * font. + * + * A `property' is a either key-value pair within the STARTPROPERTIES + * ... ENDPROPERTIES block of a BDF font or a key-value pair from the + * `info->props' array within a `FontRec' structure of a PCF font. + * + * Integer properties are always stored as `signed' within PCF fonts; + * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value + * for BDF fonts only. + * + * In case of error, `aproperty->type' is always set to + * @BDF_PROPERTY_TYPE_NONE. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + /* */ + +FT_END_HEADER + +#endif /* __FTBDF_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftbitmap.h b/drivers/freetype/include/freetype/ftbitmap.h new file mode 100644 index 0000000000..7dbf5ba3fe --- /dev/null +++ b/drivers/freetype/include/freetype/ftbitmap.h @@ -0,0 +1,227 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.h */ +/* */ +/* FreeType utility functions for bitmaps (specification). */ +/* */ +/* Copyright 2004-2006, 2008, 2013 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 __FTBITMAP_H__ +#define __FTBITMAP_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bitmap_handling */ + /* */ + /* <Title> */ + /* Bitmap Handling */ + /* */ + /* <Abstract> */ + /* Handling FT_Bitmap objects. */ + /* */ + /* <Description> */ + /* This section contains functions for converting FT_Bitmap objects. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_New */ + /* */ + /* <Description> */ + /* Initialize a pointer to an @FT_Bitmap structure. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the bitmap structure. */ + /* */ + FT_EXPORT( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Copy */ + /* */ + /* <Description> */ + /* Copy a bitmap into another one. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: A handle to the source bitmap. */ + /* */ + /* <Output> */ + /* target :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Copy( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Embolden */ + /* */ + /* <Description> */ + /* Embolden a bitmap. The new bitmap will be about `xStrength' */ + /* pixels wider and `yStrength' pixels higher. The left and bottom */ + /* borders are kept unchanged. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* xStrength :: How strong the glyph is emboldened horizontally. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* yStrength :: How strong the glyph is emboldened vertically. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* <InOut> */ + /* bitmap :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The current implementation restricts `xStrength' to be less than */ + /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ + /* */ + /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ + /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Embolden( FT_Library library, + FT_Bitmap* bitmap, + FT_Pos xStrength, + FT_Pos yStrength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Convert */ + /* */ + /* <Description> */ + /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp */ + /* to a bitmap object with depth 8bpp, making the number of used */ + /* bytes line (a.k.a. the `pitch') a multiple of `alignment'. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: The source bitmap. */ + /* */ + /* alignment :: The pitch of the bitmap is a multiple of this */ + /* parameter. Common values are 1, 2, or 4. */ + /* */ + /* <Output> */ + /* target :: The target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* It is possible to call @FT_Bitmap_Convert multiple times without */ + /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ + /* */ + /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ + /* */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GlyphSlot_Own_Bitmap */ + /* */ + /* <Description> */ + /* Make sure that a glyph slot owns `slot->bitmap'. */ + /* */ + /* <Input> */ + /* slot :: The glyph slot. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function is to be used in combination with */ + /* @FT_Bitmap_Embolden. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Done */ + /* */ + /* <Description> */ + /* Destroy a bitmap object created with @FT_Bitmap_New. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* bitmap :: The bitmap object to be freed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBITMAP_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftbzip2.h b/drivers/freetype/include/freetype/ftbzip2.h new file mode 100644 index 0000000000..1bf81b15e8 --- /dev/null +++ b/drivers/freetype/include/freetype/ftbzip2.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* ftbzip2.h */ +/* */ +/* Bzip2-compressed stream support. */ +/* */ +/* Copyright 2010 by */ +/* Joel Klinghed. */ +/* */ +/* 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 __FTBZIP2_H__ +#define __FTBZIP2_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bzip2 */ + /* */ + /* <Title> */ + /* BZIP2 Streams */ + /* */ + /* <Abstract> */ + /* Using bzip2-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Bzip2-specific functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************ + * + * @function: + * FT_Stream_OpenBzip2 + * + * @description: + * Open a new stream to parse bzip2-compressed font files. This is + * mainly used to support the compressed `*.pcf.bz2' fonts that come + * with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, bzip2 compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a bzip2 compressed stream + * from it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with bzip2 support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenBzip2( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTBZIP2_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftcache.h b/drivers/freetype/include/freetype/ftcache.h new file mode 100644 index 0000000000..4ec9587cf6 --- /dev/null +++ b/drivers/freetype/include/freetype/ftcache.h @@ -0,0 +1,1057 @@ +/***************************************************************************/ +/* */ +/* ftcache.h */ +/* */ +/* FreeType Cache subsystem (specification). */ +/* */ +/* Copyright 1996-2008, 2010, 2013 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 __FTCACHE_H__ +#define __FTCACHE_H__ + + +#include <ft2build.h> +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************* + * + * <Section> + * cache_subsystem + * + * <Title> + * Cache Sub-System + * + * <Abstract> + * How to cache face, size, and glyph data with FreeType~2. + * + * <Description> + * This section describes the FreeType~2 cache sub-system, which is used + * to limit the number of concurrently opened @FT_Face and @FT_Size + * objects, as well as caching information like character maps and glyph + * images while limiting their maximum memory usage. + * + * Note that all types and functions begin with the `FTC_' prefix. + * + * The cache is highly portable and thus doesn't know anything about the + * fonts installed on your system, or how to access them. This implies + * the following scheme: + * + * First, available or installed font faces are uniquely identified by + * @FTC_FaceID values, provided to the cache by the client. Note that + * the cache only stores and compares these values, and doesn't try to + * interpret them in any way. + * + * Second, the cache calls, only when needed, a client-provided function + * to convert an @FTC_FaceID into a new @FT_Face object. The latter is + * then completely managed by the cache, including its termination + * through @FT_Done_Face. To monitor termination of face objects, the + * finalizer callback in the `generic' field of the @FT_Face object can + * be used, which might also be used to store the @FTC_FaceID of the + * face. + * + * Clients are free to map face IDs to anything else. The most simple + * usage is to associate them to a (pathname,face_index) pair that is + * used to call @FT_New_Face. However, more complex schemes are also + * possible. + * + * Note that for the cache to work correctly, the face ID values must be + * *persistent*, which means that the contents they point to should not + * change at runtime, or that their value should not become invalid. + * + * If this is unavoidable (e.g., when a font is uninstalled at runtime), + * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let + * the cache get rid of any references to the old @FTC_FaceID it may + * keep internally. Failure to do so will lead to incorrect behaviour + * or even crashes. + * + * To use the cache, start with calling @FTC_Manager_New to create a new + * @FTC_Manager object, which models a single cache instance. You can + * then look up @FT_Face and @FT_Size objects with + * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively. + * + * If you want to use the charmap caching, call @FTC_CMapCache_New, then + * later use @FTC_CMapCache_Lookup to perform the equivalent of + * @FT_Get_Char_Index, only much faster. + * + * If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then + * later use @FTC_ImageCache_Lookup to retrieve the corresponding + * @FT_Glyph objects from the cache. + * + * If you need lots of small bitmaps, it is much more memory efficient + * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This + * returns @FTC_SBitRec structures, which are used to store small + * bitmaps directly. (A small bitmap is one whose metrics and + * dimensions all fit into 8-bit integers). + * + * We hope to also provide a kerning cache in the near future. + * + * + * <Order> + * FTC_Manager + * FTC_FaceID + * FTC_Face_Requester + * + * FTC_Manager_New + * FTC_Manager_Reset + * FTC_Manager_Done + * FTC_Manager_LookupFace + * FTC_Manager_LookupSize + * FTC_Manager_RemoveFaceID + * + * FTC_Node + * FTC_Node_Unref + * + * FTC_ImageCache + * FTC_ImageCache_New + * FTC_ImageCache_Lookup + * + * FTC_SBit + * FTC_SBitCache + * FTC_SBitCache_New + * FTC_SBitCache_Lookup + * + * FTC_CMapCache + * FTC_CMapCache_New + * FTC_CMapCache_Lookup + * + *************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC TYPE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: FTC_FaceID + * + * @description: + * An opaque pointer type that is used to identity face objects. The + * contents of such objects is application-dependent. + * + * These pointers are typically used to point to a user-defined + * structure containing a font file path, and face index. + * + * @note: + * Never use NULL as a valid @FTC_FaceID. + * + * Face IDs are passed by the client to the cache manager, which calls, + * when needed, the @FTC_Face_Requester to translate them into new + * @FT_Face objects. + * + * If the content of a given face ID changes at runtime, or if the value + * becomes invalid (e.g., when uninstalling a font), you should + * immediately call @FTC_Manager_RemoveFaceID before any other cache + * function. + * + * Failure to do so will result in incorrect behaviour or even + * memory leaks and crashes. + */ + typedef FT_Pointer FTC_FaceID; + + + /************************************************************************ + * + * @functype: + * FTC_Face_Requester + * + * @description: + * A callback function provided by client applications. It is used by + * the cache manager to translate a given @FTC_FaceID into a new valid + * @FT_Face object, on demand. + * + * <Input> + * face_id :: + * The face ID to resolve. + * + * library :: + * A handle to a FreeType library object. + * + * req_data :: + * Application-provided request data (see note below). + * + * <Output> + * aface :: + * A new @FT_Face handle. + * + * <Return> + * FreeType error code. 0~means success. + * + * <Note> + * The third parameter `req_data' is the same as the one passed by the + * client when @FTC_Manager_New is called. + * + * The face requester should not perform funny things on the returned + * face object, like creating a new @FT_Size for it, or setting a + * transformation through @FT_Set_Transform! + */ + typedef FT_Error + (*FTC_Face_Requester)( FTC_FaceID face_id, + FT_Library library, + FT_Pointer request_data, + FT_Face* aface ); + + /* */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Manager */ + /* */ + /* <Description> */ + /* This object corresponds to one instance of the cache-subsystem. */ + /* It is used to cache one or more @FT_Face objects, along with */ + /* corresponding @FT_Size objects. */ + /* */ + /* The manager intentionally limits the total number of opened */ + /* @FT_Face and @FT_Size objects to control memory usage. See the */ + /* `max_faces' and `max_sizes' parameters of @FTC_Manager_New. */ + /* */ + /* The manager is also used to cache `nodes' of various types while */ + /* limiting their total memory usage. */ + /* */ + /* All limitations are enforced by keeping lists of managed objects */ + /* in most-recently-used order, and flushing old nodes to make room */ + /* for new ones. */ + /* */ + typedef struct FTC_ManagerRec_* FTC_Manager; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Node */ + /* */ + /* <Description> */ + /* An opaque handle to a cache node object. Each cache node is */ + /* reference-counted. A node with a count of~0 might be flushed */ + /* out of a full cache whenever a lookup request is performed. */ + /* */ + /* If you look up nodes, you have the ability to `acquire' them, */ + /* i.e., to increment their reference count. This will prevent the */ + /* node from being flushed out of the cache until you explicitly */ + /* `release' it (see @FTC_Node_Unref). */ + /* */ + /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ + /* */ + typedef struct FTC_NodeRec_* FTC_Node; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_New */ + /* */ + /* <Description> */ + /* Create a new cache manager. */ + /* */ + /* <Input> */ + /* library :: The parent FreeType library handle to use. */ + /* */ + /* max_faces :: Maximum number of opened @FT_Face objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ + /* Use~0 for defaults. Note that this value does not */ + /* account for managed @FT_Face and @FT_Size objects. */ + /* */ + /* requester :: An application-provided callback used to translate */ + /* face IDs into real @FT_Face objects. */ + /* */ + /* req_data :: A generic pointer that is passed to the requester */ + /* each time it is called (see @FTC_Face_Requester). */ + /* */ + /* <Output> */ + /* amanager :: A handle to a new manager object. 0~in case of */ + /* failure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Reset */ + /* */ + /* <Description> */ + /* Empty a given cache manager. This simply gets rid of all the */ + /* currently cached @FT_Face and @FT_Size objects within the manager. */ + /* */ + /* <InOut> */ + /* manager :: A handle to the manager. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Reset( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Done */ + /* */ + /* <Description> */ + /* Destroy a given manager after emptying it. */ + /* */ + /* <Input> */ + /* manager :: A handle to the target cache manager object. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Done( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupFace */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Face object that corresponds to a given face ID */ + /* through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* face_id :: The ID of the face object. */ + /* */ + /* <Output> */ + /* aface :: A handle to the face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Face object is always owned by the manager. You */ + /* should never try to discard it yourself. */ + /* */ + /* The @FT_Face object doesn't necessarily have a current size object */ + /* (i.e., face->size can be~0). If you need a specific `font size', */ + /* use @FTC_Manager_LookupSize instead. */ + /* */ + /* Never change the face's transformation matrix (i.e., never call */ + /* the @FT_Set_Transform function) on a returned face! If you need */ + /* to transform glyphs, do it yourself after glyph loading. */ + /* */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory was available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_ScalerRec */ + /* */ + /* <Description> */ + /* A structure used to describe a given character size in either */ + /* pixels or points to the cache manager. See */ + /* @FTC_Manager_LookupSize. */ + /* */ + /* <Fields> */ + /* face_id :: The source face ID. */ + /* */ + /* width :: The character width. */ + /* */ + /* height :: The character height. */ + /* */ + /* pixel :: A Boolean. If 1, the `width' and `height' fields are */ + /* interpreted as integer pixel character sizes. */ + /* Otherwise, they are expressed as 1/64th of points. */ + /* */ + /* x_res :: Only used when `pixel' is value~0 to indicate the */ + /* horizontal resolution in dpi. */ + /* */ + /* y_res :: Only used when `pixel' is value~0 to indicate the */ + /* vertical resolution in dpi. */ + /* */ + /* <Note> */ + /* This type is mainly used to retrieve @FT_Size objects through the */ + /* cache manager. */ + /* */ + typedef struct FTC_ScalerRec_ + { + FTC_FaceID face_id; + FT_UInt width; + FT_UInt height; + FT_Int pixel; + FT_UInt x_res; + FT_UInt y_res; + + } FTC_ScalerRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_Scaler */ + /* */ + /* <Description> */ + /* A handle to an @FTC_ScalerRec structure. */ + /* */ + typedef struct FTC_ScalerRec_* FTC_Scaler; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupSize */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Size object that corresponds to a given */ + /* @FTC_ScalerRec pointer through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* scaler :: A scaler handle. */ + /* */ + /* <Output> */ + /* asize :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Size object is always owned by the manager. You */ + /* should never try to discard it by yourself. */ + /* */ + /* You can access the parent @FT_Face object simply as `size->face' */ + /* if you need it. Note that this object is also owned by the */ + /* manager. */ + /* */ + /* <Note> */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory is available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Node_Unref */ + /* */ + /* <Description> */ + /* Decrement a cache node's internal reference count. When the count */ + /* reaches 0, it is not destroyed but becomes eligible for subsequent */ + /* cache flushes. */ + /* */ + /* <Input> */ + /* node :: The cache node handle. */ + /* */ + /* manager :: The cache manager handle. */ + /* */ + FT_EXPORT( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); + + + /************************************************************************* + * + * @function: + * FTC_Manager_RemoveFaceID + * + * @description: + * A special function used to indicate to the cache manager that + * a given @FTC_FaceID is no longer valid, either because its + * content changed, or because it was deallocated or uninstalled. + * + * @input: + * manager :: + * The cache manager handle. + * + * face_id :: + * The @FTC_FaceID to be removed. + * + * @note: + * This function flushes all nodes from the cache corresponding to this + * `face_id', with the exception of nodes with a non-null reference + * count. + * + * Such nodes are however modified internally so as to never appear + * in later lookups with the same `face_id' value, and to be immediately + * destroyed when released by all their users. + * + */ + FT_EXPORT( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * FTC_CMapCache + * + * @description: + * An opaque handle used to model a charmap cache. This cache is to + * hold character codes -> glyph indices mappings. + * + */ + typedef struct FTC_CMapCacheRec_* FTC_CMapCache; + + + /************************************************************************* + * + * @function: + * FTC_CMapCache_New + * + * @description: + * Create a new charmap cache. + * + * @input: + * manager :: + * A handle to the cache manager. + * + * @output: + * acache :: + * A new cache handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Like all other caches, this one will be destroyed with the cache + * manager. + * + */ + FT_EXPORT( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ); + + + /************************************************************************ + * + * @function: + * FTC_CMapCache_Lookup + * + * @description: + * Translate a character code into a glyph index, using the charmap + * cache. + * + * @input: + * cache :: + * A charmap cache handle. + * + * face_id :: + * The source face ID. + * + * cmap_index :: + * The index of the charmap in the source face. Any negative value + * means to use the cache @FT_Face's default charmap. + * + * char_code :: + * The character code (in the corresponding charmap). + * + * @return: + * Glyph index. 0~means `no glyph'. + * + */ + FT_EXPORT( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cache, + FTC_FaceID face_id, + FT_Int cmap_index, + FT_UInt32 char_code ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @struct: + * FTC_ImageTypeRec + * + * @description: + * A structure used to model the type of images in a glyph cache. + * + * @fields: + * face_id :: + * The face ID. + * + * width :: + * The width in pixels. + * + * height :: + * The height in pixels. + * + * flags :: + * The load flags, as in @FT_Load_Glyph. + * + */ + typedef struct FTC_ImageTypeRec_ + { + FTC_FaceID face_id; + FT_Int width; + FT_Int height; + FT_Int32 flags; + + } FTC_ImageTypeRec; + + + /************************************************************************* + * + * @type: + * FTC_ImageType + * + * @description: + * A handle to an @FTC_ImageTypeRec structure. + * + */ + typedef struct FTC_ImageTypeRec_* FTC_ImageType; + + + /* */ + + +#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ + ( (d1)->face_id == (d2)->face_id && \ + (d1)->width == (d2)->width && \ + (d1)->flags == (d2)->flags ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_ImageCache */ + /* */ + /* <Description> */ + /* A handle to a glyph image cache object. They are designed to */ + /* hold many distinct glyph images while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_ImageCacheRec_* FTC_ImageCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_New */ + /* */ + /* <Description> */ + /* Create a new glyph image cache. */ + /* */ + /* <Input> */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_Lookup */ + /* */ + /* <Description> */ + /* Retrieve a given glyph image from a glyph image cache. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* type :: A pointer to a glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* scaler :: A pointer to a scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ + /* glyphs; you should always use the FreeType cache API instead. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_LookupScaler( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBit */ + /* */ + /* <Description> */ + /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ + /* structure for details. */ + /* */ + typedef struct FTC_SBitRec_* FTC_SBit; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_SBitRec */ + /* */ + /* <Description> */ + /* A very compact structure used to describe a small glyph bitmap. */ + /* */ + /* <Fields> */ + /* width :: The bitmap width in pixels. */ + /* */ + /* height :: The bitmap height in pixels. */ + /* */ + /* left :: The horizontal distance from the pen position to the */ + /* left bitmap border (a.k.a. `left side bearing', or */ + /* `lsb'). */ + /* */ + /* top :: The vertical distance from the pen position (on the */ + /* baseline) to the upper bitmap border (a.k.a. `top */ + /* side bearing'). The distance is positive for upwards */ + /* y~coordinates. */ + /* */ + /* format :: The format of the glyph bitmap (monochrome or gray). */ + /* */ + /* max_grays :: Maximum gray level value (in the range 1 to~255). */ + /* */ + /* pitch :: The number of bytes per bitmap line. May be positive */ + /* or negative. */ + /* */ + /* xadvance :: The horizontal advance width in pixels. */ + /* */ + /* yadvance :: The vertical advance height in pixels. */ + /* */ + /* buffer :: A pointer to the bitmap pixels. */ + /* */ + typedef struct FTC_SBitRec_ + { + FT_Byte width; + FT_Byte height; + FT_Char left; + FT_Char top; + + FT_Byte format; + FT_Byte max_grays; + FT_Short pitch; + FT_Char xadvance; + FT_Char yadvance; + + FT_Byte* buffer; + + } FTC_SBitRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBitCache */ + /* */ + /* <Description> */ + /* A handle to a small bitmap cache. These are special cache objects */ + /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ + /* much more efficient way than the traditional glyph image cache */ + /* implemented by @FTC_ImageCache. */ + /* */ + typedef struct FTC_SBitCacheRec_* FTC_SBitCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_New */ + /* */ + /* <Description> */ + /* Create a new cache to store small glyph bitmaps. */ + /* */ + /* <Input> */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_Lookup */ + /* */ + /* <Description> */ + /* Look up a given small glyph bitmap in a given sbit cache and */ + /* `lock' it to prevent its flushing from the cache until needed. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* type :: A pointer to the glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* scaler :: A pointer to the scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_LookupScaler( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /* */ + +FT_END_HEADER + +#endif /* __FTCACHE_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftcffdrv.h b/drivers/freetype/include/freetype/ftcffdrv.h new file mode 100644 index 0000000000..ccbcbccaa8 --- /dev/null +++ b/drivers/freetype/include/freetype/ftcffdrv.h @@ -0,0 +1,151 @@ +/***************************************************************************/ +/* */ +/* ftcffdrv.h */ +/* */ +/* FreeType API for controlling the CFF driver (specification only). */ +/* */ +/* Copyright 2013 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 __FTCFFDRV_H__ +#define __FTCFFDRV_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * cff_driver + * + * @title: + * The CFF driver + * + * @abstract: + * Controlling the CFF driver module. + * + * @description: + * While FreeType's CFF driver doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * The CFF driver's module name is `cff'. + * + */ + + + /************************************************************************** + * + * @property: + * hinting-engine + * + * @description: + * Thanks to Adobe, which contributed a new hinting (and parsing) + * engine, an application can select between `freetype' and `adobe' if + * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration + * macro isn't defined, `hinting-engine' does nothing. + * + * The default engine is `freetype' if CFF_CONFIG_OPTION_OLD_ENGINE is + * defined, and `adobe' otherwise. + * + * The following example code demonstrates how to select Adobe's hinting + * engine (omitting the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "hinting-engine", &hinting_engine ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_CFF_HINTING_XXX + * + * @description: + * A list of constants used for the @hinting-engine property to select + * the hinting engine for CFF fonts. + * + * @values: + * FT_CFF_HINTING_FREETYPE :: + * Use the old FreeType hinting engine. + * + * FT_CFF_HINTING_ADOBE :: + * Use the hinting engine contributed by Adobe. + * + */ +#define FT_CFF_HINTING_FREETYPE 0 +#define FT_CFF_HINTING_ADOBE 1 + + + /************************************************************************** + * + * @property: + * no-stem-darkening + * + * @description: + * By default, the Adobe CFF engine darkens stems at smaller sizes, + * regardless of hinting, to enhance contrast. Setting this property, + * stem darkening gets switched off. + * + * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. + * + * { + * FT_Library library; + * FT_Face face; + * FT_Bool no_stem_darkening = TRUE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "no-stem-darkening", &no_stem_darkening ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /* */ + +FT_END_HEADER + + +#endif /* __FTCFFDRV_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftchapters.h b/drivers/freetype/include/freetype/ftchapters.h new file mode 100644 index 0000000000..c55670d1d2 --- /dev/null +++ b/drivers/freetype/include/freetype/ftchapters.h @@ -0,0 +1,120 @@ +/***************************************************************************/ +/* */ +/* This file defines the structure of the FreeType reference. */ +/* It is used by the python script which generates the HTML files. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* general_remarks */ +/* */ +/* <Title> */ +/* General Remarks */ +/* */ +/* <Sections> */ +/* user_allocation */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* core_api */ +/* */ +/* <Title> */ +/* Core API */ +/* */ +/* <Sections> */ +/* version */ +/* basic_types */ +/* base_interface */ +/* glyph_variants */ +/* glyph_management */ +/* mac_specific */ +/* sizes_management */ +/* header_file_macros */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* format_specific */ +/* */ +/* <Title> */ +/* Format-Specific API */ +/* */ +/* <Sections> */ +/* multiple_masters */ +/* truetype_tables */ +/* type1_tables */ +/* sfnt_names */ +/* bdf_fonts */ +/* cid_fonts */ +/* pfr_fonts */ +/* winfnt_fonts */ +/* font_formats */ +/* gasp_table */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* module_specific */ +/* */ +/* <Title> */ +/* Controlling FreeType Modules */ +/* */ +/* <Sections> */ +/* auto_hinter */ +/* cff_driver */ +/* tt_driver */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* cache_subsystem */ +/* */ +/* <Title> */ +/* Cache Sub-System */ +/* */ +/* <Sections> */ +/* cache_subsystem */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* support_api */ +/* */ +/* <Title> */ +/* Support API */ +/* */ +/* <Sections> */ +/* computations */ +/* list_processing */ +/* outline_processing */ +/* quick_advance */ +/* bitmap_handling */ +/* raster */ +/* glyph_stroker */ +/* system_interface */ +/* module_management */ +/* gzip */ +/* lzw */ +/* bzip2 */ +/* lcd_filtering */ +/* */ +/***************************************************************************/ diff --git a/drivers/freetype/include/freetype/ftcid.h b/drivers/freetype/include/freetype/ftcid.h new file mode 100644 index 0000000000..203a30caf8 --- /dev/null +++ b/drivers/freetype/include/freetype/ftcid.h @@ -0,0 +1,166 @@ +/***************************************************************************/ +/* */ +/* ftcid.h */ +/* */ +/* FreeType API for accessing CID font information (specification). */ +/* */ +/* Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal. */ +/* */ +/* 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 __FTCID_H__ +#define __FTCID_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cid_fonts */ + /* */ + /* <Title> */ + /* CID Fonts */ + /* */ + /* <Abstract> */ + /* CID-keyed font specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of CID-keyed font specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Registry_Ordering_Supplement + * + * @description: + * Retrieve the Registry/Ordering/Supplement triple (also known as the + * "R/O/S") from a CID-keyed font. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * registry :: + * The registry, as a C~string, owned by the face. + * + * ordering :: + * The ordering, as a C~string, owned by the face. + * + * supplement :: + * The supplement. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces, returning an error + * otherwise. + * + * @since: + * 2.3.6 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Is_Internally_CID_Keyed + * + * @description: + * Retrieve the type of the input face, CID keyed or not. In + * constrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SNFT wrapper. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * is_cid :: + * The type of the face as an @FT_Bool. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_From_Glyph_Index + * + * @description: + * Retrieve the CID of the input glyph index. + * + * @input: + * face :: + * A handle to the input face. + * + * glyph_index :: + * The input glyph index. + * + * @output: + * cid :: + * The CID as an @FT_UInt. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + /* */ + +FT_END_HEADER + +#endif /* __FTCID_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/fterrdef.h b/drivers/freetype/include/freetype/fterrdef.h new file mode 100644 index 0000000000..76c7b9e36f --- /dev/null +++ b/drivers/freetype/include/freetype/fterrdef.h @@ -0,0 +1,249 @@ +/***************************************************************************/ +/* */ +/* fterrdef.h */ +/* */ +/* FreeType error codes (specification). */ +/* */ +/* Copyright 2002, 2004, 2006, 2007, 2010-2013 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. */ +/* */ +/***************************************************************************/ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST OF ERROR CODES/MESSAGES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + + /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */ + /* including this file. */ + + + /* generic errors */ + + FT_NOERRORDEF_( Ok, 0x00, \ + "no error" ) + + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ + "cannot open resource" ) + FT_ERRORDEF_( Unknown_File_Format, 0x02, \ + "unknown file format" ) + FT_ERRORDEF_( Invalid_File_Format, 0x03, \ + "broken file" ) + FT_ERRORDEF_( Invalid_Version, 0x04, \ + "invalid FreeType version" ) + FT_ERRORDEF_( Lower_Module_Version, 0x05, \ + "module version is too low" ) + FT_ERRORDEF_( Invalid_Argument, 0x06, \ + "invalid argument" ) + FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ + "unimplemented feature" ) + FT_ERRORDEF_( Invalid_Table, 0x08, \ + "broken table" ) + FT_ERRORDEF_( Invalid_Offset, 0x09, \ + "broken offset within table" ) + FT_ERRORDEF_( Array_Too_Large, 0x0A, \ + "array allocation size too large" ) + FT_ERRORDEF_( Missing_Module, 0x0B, \ + "missing module" ) + FT_ERRORDEF_( Missing_Property, 0x0C, \ + "missing property" ) + + /* glyph/character errors */ + + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ + "invalid glyph index" ) + FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ + "invalid character code" ) + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ + "unsupported glyph image format" ) + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ + "cannot render this glyph format" ) + FT_ERRORDEF_( Invalid_Outline, 0x14, \ + "invalid outline" ) + FT_ERRORDEF_( Invalid_Composite, 0x15, \ + "invalid composite glyph" ) + FT_ERRORDEF_( Too_Many_Hints, 0x16, \ + "too many hints" ) + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ + "invalid pixel size" ) + + /* handle errors */ + + FT_ERRORDEF_( Invalid_Handle, 0x20, \ + "invalid object handle" ) + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ + "invalid library handle" ) + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ + "invalid module handle" ) + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ + "invalid face handle" ) + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ + "invalid size handle" ) + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ + "invalid glyph slot handle" ) + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ + "invalid charmap handle" ) + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ + "invalid cache manager handle" ) + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ + "invalid stream handle" ) + + /* driver errors */ + + FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ + "too many modules" ) + FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ + "too many extensions" ) + + /* memory errors */ + + FT_ERRORDEF_( Out_Of_Memory, 0x40, \ + "out of memory" ) + FT_ERRORDEF_( Unlisted_Object, 0x41, \ + "unlisted object" ) + + /* stream errors */ + + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ + "cannot open stream" ) + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ + "invalid stream seek" ) + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ + "invalid stream skip" ) + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ + "invalid stream read" ) + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ + "invalid stream operation" ) + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ + "invalid frame operation" ) + FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ + "nested frame access" ) + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ + "invalid frame read" ) + + /* raster errors */ + + FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ + "raster uninitialized" ) + FT_ERRORDEF_( Raster_Corrupted, 0x61, \ + "raster corrupted" ) + FT_ERRORDEF_( Raster_Overflow, 0x62, \ + "raster overflow" ) + FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ + "negative height while rastering" ) + + /* cache errors */ + + FT_ERRORDEF_( Too_Many_Caches, 0x70, \ + "too many registered caches" ) + + /* TrueType and SFNT errors */ + + FT_ERRORDEF_( Invalid_Opcode, 0x80, \ + "invalid opcode" ) + FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ + "too few arguments" ) + FT_ERRORDEF_( Stack_Overflow, 0x82, \ + "stack overflow" ) + FT_ERRORDEF_( Code_Overflow, 0x83, \ + "code overflow" ) + FT_ERRORDEF_( Bad_Argument, 0x84, \ + "bad argument" ) + FT_ERRORDEF_( Divide_By_Zero, 0x85, \ + "division by zero" ) + FT_ERRORDEF_( Invalid_Reference, 0x86, \ + "invalid reference" ) + FT_ERRORDEF_( Debug_OpCode, 0x87, \ + "found debug opcode" ) + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ + "found ENDF opcode in execution stream" ) + FT_ERRORDEF_( Nested_DEFS, 0x89, \ + "nested DEFS" ) + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ + "invalid code range" ) + FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ + "execution context too long" ) + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ + "too many function definitions" ) + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ + "too many instruction definitions" ) + FT_ERRORDEF_( Table_Missing, 0x8E, \ + "SFNT font table missing" ) + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ + "horizontal header (hhea) table missing" ) + FT_ERRORDEF_( Locations_Missing, 0x90, \ + "locations (loca) table missing" ) + FT_ERRORDEF_( Name_Table_Missing, 0x91, \ + "name table missing" ) + FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ + "character map (cmap) table missing" ) + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ + "horizontal metrics (hmtx) table missing" ) + FT_ERRORDEF_( Post_Table_Missing, 0x94, \ + "PostScript (post) table missing" ) + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ + "invalid horizontal metrics" ) + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ + "invalid character map (cmap) format" ) + FT_ERRORDEF_( Invalid_PPem, 0x97, \ + "invalid ppem value" ) + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ + "invalid vertical metrics" ) + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ + "could not find context" ) + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ + "invalid PostScript (post) table format" ) + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ + "invalid PostScript (post) table" ) + + /* CFF, CID, and Type 1 errors */ + + FT_ERRORDEF_( Syntax_Error, 0xA0, \ + "opcode syntax error" ) + FT_ERRORDEF_( Stack_Underflow, 0xA1, \ + "argument stack underflow" ) + FT_ERRORDEF_( Ignore, 0xA2, \ + "ignore" ) + FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \ + "no Unicode glyph name found" ) + FT_ERRORDEF_( Glyph_Too_Big, 0xA4, \ + "glyph to big for hinting" ) + + /* BDF errors */ + + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ + "`STARTFONT' field missing" ) + FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ + "`FONT' field missing" ) + FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ + "`SIZE' field missing" ) + FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, \ + "`FONTBOUNDINGBOX' field missing" ) + FT_ERRORDEF_( Missing_Chars_Field, 0xB4, \ + "`CHARS' field missing" ) + FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, \ + "`STARTCHAR' field missing" ) + FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, \ + "`ENCODING' field missing" ) + FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, \ + "`BBX' field missing" ) + FT_ERRORDEF_( Bbx_Too_Big, 0xB8, \ + "`BBX' too big" ) + FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, \ + "Font header corrupted or missing fields" ) + FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, \ + "Font glyphs corrupted or missing fields" ) + + +/* END */ diff --git a/drivers/freetype/include/freetype/fterrors.h b/drivers/freetype/include/freetype/fterrors.h new file mode 100644 index 0000000000..0fa3e4dce1 --- /dev/null +++ b/drivers/freetype/include/freetype/fterrors.h @@ -0,0 +1,198 @@ +/***************************************************************************/ +/* */ +/* fterrors.h */ +/* */ +/* FreeType error code handling (specification). */ +/* */ +/* Copyright 1996-2002, 2004, 2007, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This special header file is used to define the handling of FT2 */ + /* enumeration constants. It can also be used to generate error message */ + /* strings with a small macro trick explained below. */ + /* */ + /* I - Error Formats */ + /* ----------------- */ + /* */ + /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ + /* defined in ftoption.h in order to make the higher byte indicate */ + /* the module where the error has happened (this is not compatible */ + /* with standard builds of FreeType 2). See the file `ftmoderr.h' for */ + /* more details. */ + /* */ + /* */ + /* II - Error Message strings */ + /* -------------------------- */ + /* */ + /* The error definitions below are made through special macros that */ + /* allow client applications to build a table of error message strings */ + /* if they need it. The strings are not included in a normal build of */ + /* FreeType 2 to save space (most client applications do not use */ + /* them). */ + /* */ + /* To do so, you have to define the following macros before including */ + /* this file: */ + /* */ + /* FT_ERROR_START_LIST :: */ + /* This macro is called before anything else to define the start of */ + /* the error list. It is followed by several FT_ERROR_DEF calls */ + /* (see below). */ + /* */ + /* FT_ERROR_DEF( e, v, s ) :: */ + /* This macro is called to define one single error. */ + /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ + /* `v' is the error numerical value. */ + /* `s' is the corresponding error string. */ + /* */ + /* FT_ERROR_END_LIST :: */ + /* This macro ends the list. */ + /* */ + /* Additionally, you have to undefine __FTERRORS_H__ before #including */ + /* this file. */ + /* */ + /* Here is a simple example: */ + /* */ + /* { */ + /* #undef __FTERRORS_H__ */ + /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ + /* #define FT_ERROR_START_LIST { */ + /* #define FT_ERROR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int err_code; */ + /* const char* err_msg; */ + /* } ft_errors[] = */ + /* */ + /* #include FT_ERRORS_H */ + /* } */ + /* */ + /*************************************************************************/ + + +#ifndef __FTERRORS_H__ +#define __FTERRORS_H__ + + + /* include module base error codes */ +#include FT_MODULE_ERRORS_H + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + + + /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ + /* By default, we use `FT_Err_'. */ + /* */ +#ifndef FT_ERR_PREFIX +#define FT_ERR_PREFIX FT_Err_ +#endif + + + /* FT_ERR_BASE is used as the base for module-specific errors. */ + /* */ +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS + +#ifndef FT_ERR_BASE +#define FT_ERR_BASE FT_Mod_Err_Base +#endif + +#else + +#undef FT_ERR_BASE +#define FT_ERR_BASE 0 + +#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ + + + /* If FT_ERRORDEF is not defined, we need to define a simple */ + /* enumeration type. */ + /* */ +#ifndef FT_ERRORDEF + +#define FT_ERRORDEF( e, v, s ) e = v, +#define FT_ERROR_START_LIST enum { +#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_ERRORDEF */ + + + /* this macro is used to define an error */ +#define FT_ERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) + + /* this is only used for <module>_Err_Ok, which must be 0! */ +#define FT_NOERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) + + +#ifdef FT_ERROR_START_LIST + FT_ERROR_START_LIST +#endif + + + /* now include the error codes */ +#include FT_ERROR_DEFINITIONS_H + + +#ifdef FT_ERROR_END_LIST + FT_ERROR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SIMPLE CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_ERROR_START_LIST +#undef FT_ERROR_END_LIST + +#undef FT_ERRORDEF +#undef FT_ERRORDEF_ +#undef FT_NOERRORDEF_ + +#undef FT_NEED_EXTERN_C +#undef FT_ERR_BASE + + /* FT_ERR_PREFIX is needed internally */ +#ifndef FT2_BUILD_LIBRARY +#undef FT_ERR_PREFIX +#endif + +#endif /* __FTERRORS_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftgasp.h b/drivers/freetype/include/freetype/ftgasp.h new file mode 100644 index 0000000000..453d4fa42c --- /dev/null +++ b/drivers/freetype/include/freetype/ftgasp.h @@ -0,0 +1,128 @@ +/***************************************************************************/ +/* */ +/* ftgasp.h */ +/* */ +/* Access of TrueType's `gasp' table (specification). */ +/* */ +/* Copyright 2007, 2008, 2011 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 + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + + /*************************************************************************** + * + * @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 its `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. If this bit + * is not set, no hinting gets applied. + * + * FT_GASP_DO_GRAY :: + * Anti-aliased rendering should be performed at the specified ppem. + * If not set, do monochrome rendering. + * + * FT_GASP_SYMMETRIC_SMOOTHING :: + * If set, smoothing along multiple axes must be used with ClearType. + * + * FT_GASP_SYMMETRIC_GRIDFIT :: + * Grid-fitting must be used with ClearType's symmetric smoothing. + * + * @note: + * The bit-flags `FT_GASP_DO_GRIDFIT' and `FT_GASP_DO_GRAY' are to be + * used for standard font rasterization only. Independently of that, + * `FT_GASP_SYMMETRIC_SMOOTHING' and `FT_GASP_SYMMETRIC_GRIDFIT' are to + * be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT' and + * `FT_GASP_DO_GRAY' are consequently ignored). + * + * `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 if 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 */ diff --git a/drivers/freetype/include/freetype/ftglyph.h b/drivers/freetype/include/freetype/ftglyph.h new file mode 100644 index 0000000000..31dc33187d --- /dev/null +++ b/drivers/freetype/include/freetype/ftglyph.h @@ -0,0 +1,620 @@ +/***************************************************************************/ +/* */ +/* ftglyph.h */ +/* */ +/* FreeType convenience functions to handle glyphs (specification). */ +/* */ +/* Copyright 1996-2003, 2006, 2008, 2009, 2011 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTGLYPH_H__ +#define __FTGLYPH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_management */ + /* */ + /* <Title> */ + /* Glyph Management */ + /* */ + /* <Abstract> */ + /* Generic interface to manage individual glyph data. */ + /* */ + /* <Description> */ + /* This section contains definitions used to manage glyph data */ + /* through generic FT_Glyph objects. Each of them can contain a */ + /* bitmap, a vector outline, or even images in other formats. */ + /* */ + /*************************************************************************/ + + + /* forward declaration to a private type */ + typedef struct FT_Glyph_Class_ FT_Glyph_Class; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Glyph */ + /* */ + /* <Description> */ + /* Handle to an object used to model generic glyph images. It is a */ + /* pointer to the @FT_GlyphRec structure and can contain a glyph */ + /* bitmap or pointer. */ + /* */ + /* <Note> */ + /* Glyph objects are not owned by the library. You must thus release */ + /* them manually (through @FT_Done_Glyph) _before_ calling */ + /* @FT_Done_FreeType. */ + /* */ + typedef struct FT_GlyphRec_* FT_Glyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphRec */ + /* */ + /* <Description> */ + /* The root glyph structure contains a given glyph image plus its */ + /* advance width in 16.16 fixed-point format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library object. */ + /* */ + /* clazz :: A pointer to the glyph's class. Private. */ + /* */ + /* format :: The format of the glyph's image. */ + /* */ + /* advance :: A 16.16 vector that gives the glyph's advance width. */ + /* */ + typedef struct FT_GlyphRec_ + { + FT_Library library; + const FT_Glyph_Class* clazz; + FT_Glyph_Format format; + FT_Vector advance; + + } FT_GlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_BitmapGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model a bitmap glyph image. This is */ + /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ + /* */ + typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BitmapGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for bitmap glyph images. This really is a */ + /* `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* left :: The left-side bearing, i.e., the horizontal distance */ + /* from the current pen position to the left border of the */ + /* glyph bitmap. */ + /* */ + /* top :: The top-side bearing, i.e., the vertical distance from */ + /* the current pen position to the top border of the glyph */ + /* bitmap. This distance is positive for upwards~y! */ + /* */ + /* bitmap :: A descriptor for the bitmap. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_BITMAP'. This lets you access */ + /* the bitmap's contents easily. */ + /* */ + /* The corresponding pixel buffer is always owned by @FT_BitmapGlyph */ + /* and is thus created and destroyed with it. */ + /* */ + typedef struct FT_BitmapGlyphRec_ + { + FT_GlyphRec root; + FT_Int left; + FT_Int top; + FT_Bitmap bitmap; + + } FT_BitmapGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_OutlineGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model an outline glyph image. This */ + /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ + /* */ + typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_OutlineGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for outline (vectorial) glyph images. This */ + /* really is a `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* outline :: A descriptor for the outline. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ + /* the outline's content easily. */ + /* */ + /* As the outline is extracted from a glyph slot, its coordinates are */ + /* expressed normally in 26.6 pixels, unless the flag */ + /* @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */ + /* */ + /* The outline's tables are always owned by the object and are */ + /* destroyed with it. */ + /* */ + typedef struct FT_OutlineGlyphRec_ + { + FT_GlyphRec root; + FT_Outline outline; + + } FT_OutlineGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph */ + /* */ + /* <Description> */ + /* A function used to extract a glyph image from a slot. Note that */ + /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* slot :: A handle to the source glyph slot. */ + /* */ + /* <Output> */ + /* aglyph :: A handle to the glyph object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Copy */ + /* */ + /* <Description> */ + /* A function used to copy a glyph image. Note that the created */ + /* @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* source :: A handle to the source glyph object. */ + /* */ + /* <Output> */ + /* target :: A handle to the target glyph object. 0~in case of */ + /* error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Transform */ + /* */ + /* <Description> */ + /* Transform a glyph image if its format is scalable. */ + /* */ + /* <InOut> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to a 2x2 matrix to apply. */ + /* */ + /* delta :: A pointer to a 2d vector to apply. Coordinates are */ + /* expressed in 1/64th of a pixel. */ + /* */ + /* <Return> */ + /* FreeType error code (if not 0, the glyph format is not scalable). */ + /* */ + /* <Note> */ + /* The 2x2 transformation matrix is also applied to the glyph's */ + /* advance vector. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_BBox_Mode */ + /* */ + /* <Description> */ + /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ + /* */ + /* <Values> */ + /* FT_GLYPH_BBOX_UNSCALED :: */ + /* Return unscaled font units. */ + /* */ + /* FT_GLYPH_BBOX_SUBPIXELS :: */ + /* Return unfitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_GRIDFIT :: */ + /* Return grid-fitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_TRUNCATE :: */ + /* Return coordinates in integer pixels. */ + /* */ + /* FT_GLYPH_BBOX_PIXELS :: */ + /* Return grid-fitted pixel coordinates. */ + /* */ + typedef enum FT_Glyph_BBox_Mode_ + { + FT_GLYPH_BBOX_UNSCALED = 0, + FT_GLYPH_BBOX_SUBPIXELS = 0, + FT_GLYPH_BBOX_GRIDFIT = 1, + FT_GLYPH_BBOX_TRUNCATE = 2, + FT_GLYPH_BBOX_PIXELS = 3 + + } FT_Glyph_BBox_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_glyph_bbox_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated. Use the corresponding */ + /* @FT_Glyph_BBox_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_glyph_bbox_unscaled :: See @FT_GLYPH_BBOX_UNSCALED. */ + /* ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS. */ + /* ft_glyph_bbox_gridfit :: See @FT_GLYPH_BBOX_GRIDFIT. */ + /* ft_glyph_bbox_truncate :: See @FT_GLYPH_BBOX_TRUNCATE. */ + /* ft_glyph_bbox_pixels :: See @FT_GLYPH_BBOX_PIXELS. */ + /* */ +#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED +#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS +#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT +#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE +#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Get_CBox */ + /* */ + /* <Description> */ + /* Return a glyph's `control box'. The control box encloses all the */ + /* outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* which contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the source glyph object. */ + /* */ + /* mode :: The mode which indicates how to interpret the returned */ + /* bounding box values. */ + /* */ + /* <Output> */ + /* acbox :: The glyph coordinate bounding box. Coordinates are */ + /* expressed in 1/64th of pixels if it is grid-fitted. */ + /* */ + /* <Note> */ + /* Coordinates are relative to the glyph origin, using the y~upwards */ + /* convention. */ + /* */ + /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ + /* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font */ + /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ + /* is another name for this constant. */ + /* */ + /* If the font is tricky and the glyph has been loaded with */ + /* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */ + /* reasonable values for the CBox it is necessary to load the glyph */ + /* at a large ppem value (so that the hinting instructions can */ + /* properly shift and scale the subglyphs), then extracting the CBox */ + /* which can be eventually converted back to font units. */ + /* */ + /* Note that the maximum coordinates are exclusive, which means that */ + /* one can compute the width and height of the glyph image (be it in */ + /* integer or 26.6 pixels) as: */ + /* */ + /* { */ + /* width = bbox.xMax - bbox.xMin; */ + /* height = bbox.yMax - bbox.yMin; */ + /* } */ + /* */ + /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ + /* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, */ + /* which corresponds to: */ + /* */ + /* { */ + /* bbox.xMin = FLOOR(bbox.xMin); */ + /* bbox.yMin = FLOOR(bbox.yMin); */ + /* bbox.xMax = CEILING(bbox.xMax); */ + /* bbox.yMax = CEILING(bbox.yMax); */ + /* } */ + /* */ + /* To get the bbox in pixel coordinates, set `bbox_mode' to */ + /* @FT_GLYPH_BBOX_TRUNCATE. */ + /* */ + /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ + /* to @FT_GLYPH_BBOX_PIXELS. */ + /* */ + FT_EXPORT( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_To_Bitmap */ + /* */ + /* <Description> */ + /* Convert a given glyph object to a bitmap glyph object. */ + /* */ + /* <InOut> */ + /* the_glyph :: A pointer to a handle to the target glyph. */ + /* */ + /* <Input> */ + /* render_mode :: An enumeration that describes how the data is */ + /* rendered. */ + /* */ + /* origin :: A pointer to a vector used to translate the glyph */ + /* image before rendering. Can be~0 (if no */ + /* translation). The origin is expressed in */ + /* 26.6 pixels. */ + /* */ + /* destroy :: A boolean that indicates that the original glyph */ + /* image should be destroyed by this function. It is */ + /* never destroyed in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does nothing if the glyph format isn't scalable. */ + /* */ + /* The glyph image is translated with the `origin' vector before */ + /* rendering. */ + /* */ + /* The first parameter is a pointer to an @FT_Glyph handle, that will */ + /* be _replaced_ by this function (with newly allocated data). */ + /* Typically, you would use (omitting error handling): */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyph; */ + /* FT_BitmapGlyph glyph_bitmap; */ + /* */ + /* */ + /* // load glyph */ + /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ + /* */ + /* // extract glyph image */ + /* error = FT_Get_Glyph( face->glyph, &glyph ); */ + /* */ + /* // convert to a bitmap (default render mode + destroying old) */ + /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ + /* { */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ + /* 0, 1 ); */ + /* if ( error ) // `glyph' unchanged */ + /* ... */ + /* } */ + /* */ + /* // access bitmap content by typecasting */ + /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ + /* */ + /* // do funny stuff with it, like blitting/drawing */ + /* ... */ + /* */ + /* // discard glyph image (bitmap or not) */ + /* FT_Done_Glyph( glyph ); */ + /* } */ + /* */ + /* */ + /* Here another example, again without error handling: */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyphs[MAX_GLYPHS] */ + /* */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ + /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* { */ + /* FT_Glyph bitmap = glyphs[idx]; */ + /* */ + /* */ + /* ... */ + /* */ + /* // after this call, `bitmap' no longer points into */ + /* // the `glyphs' array (and the old value isn't destroyed) */ + /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ + /* */ + /* ... */ + /* */ + /* FT_Done_Glyph( bitmap ); */ + /* } */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* FT_Done_Glyph( glyphs[idx] ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Glyph */ + /* */ + /* <Description> */ + /* Destroy a given glyph. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + FT_EXPORT( void ) + FT_Done_Glyph( FT_Glyph glyph ); + + /* */ + + + /* other helpful functions */ + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Multiply */ + /* */ + /* <Description> */ + /* Perform the matrix operation `b = a*b'. */ + /* */ + /* <Input> */ + /* a :: A pointer to matrix `a'. */ + /* */ + /* <InOut> */ + /* b :: A pointer to matrix `b'. */ + /* */ + /* <Note> */ + /* The result is undefined if either `a' or `b' is zero. */ + /* */ + FT_EXPORT( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix* b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Invert */ + /* */ + /* <Description> */ + /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ + /* */ + /* <InOut> */ + /* matrix :: A pointer to the target matrix. Remains untouched in */ + /* case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLYPH_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/drivers/freetype/include/freetype/ftgxval.h b/drivers/freetype/include/freetype/ftgxval.h new file mode 100644 index 0000000000..497015c101 --- /dev/null +++ b/drivers/freetype/include/freetype/ftgxval.h @@ -0,0 +1,358 @@ +/***************************************************************************/ +/* */ +/* ftgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004, 2005, 2006 by */ +/* Masatake YAMATO, Redhat K.K, */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGXVAL_H__ +#define __FTGXVAL_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gx_validation */ + /* */ + /* <Title> */ + /* TrueTypeGX/AAT Validation */ + /* */ + /* <Abstract> */ + /* An API to validate TrueTypeGX/AAT tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ + /* trak, prop, lcar). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* Warning: Use FT_VALIDATE_XXX to validate a table. */ + /* Following definitions are for gxvalid developers. */ + /* */ + /* */ + /*************************************************************************/ + +#define FT_VALIDATE_feat_INDEX 0 +#define FT_VALIDATE_mort_INDEX 1 +#define FT_VALIDATE_morx_INDEX 2 +#define FT_VALIDATE_bsln_INDEX 3 +#define FT_VALIDATE_just_INDEX 4 +#define FT_VALIDATE_kern_INDEX 5 +#define FT_VALIDATE_opbd_INDEX 6 +#define FT_VALIDATE_trak_INDEX 7 +#define FT_VALIDATE_prop_INDEX 8 +#define FT_VALIDATE_lcar_INDEX 9 +#define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX + + + /************************************************************************* + * + * @macro: + * FT_VALIDATE_GX_LENGTH + * + * @description: + * The number of tables checked in this module. Use it as a parameter + * for the `table-length' argument of function @FT_TrueTypeGX_Validate. + */ +#define FT_VALIDATE_GX_LENGTH (FT_VALIDATE_GX_LAST_INDEX + 1) + + /* */ + + /* Up to 0x1000 is used by otvalid. + Ox2xxx is reserved for feature OT extension. */ +#define FT_VALIDATE_GX_START 0x4000 +#define FT_VALIDATE_GX_BITFIELD( tag ) \ + ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_GXXXX + * + * @description: + * A list of bit-field constants used with @FT_TrueTypeGX_Validate to + * indicate which TrueTypeGX/AAT Type tables should be validated. + * + * @values: + * FT_VALIDATE_feat :: + * Validate `feat' table. + * + * FT_VALIDATE_mort :: + * Validate `mort' table. + * + * FT_VALIDATE_morx :: + * Validate `morx' table. + * + * FT_VALIDATE_bsln :: + * Validate `bsln' table. + * + * FT_VALIDATE_just :: + * Validate `just' table. + * + * FT_VALIDATE_kern :: + * Validate `kern' table. + * + * FT_VALIDATE_opbd :: + * Validate `opbd' table. + * + * FT_VALIDATE_trak :: + * Validate `trak' table. + * + * FT_VALIDATE_prop :: + * Validate `prop' table. + * + * FT_VALIDATE_lcar :: + * Validate `lcar' table. + * + * FT_VALIDATE_GX :: + * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, + * opbd, trak, prop and lcar). + * + */ + +#define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat ) +#define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort ) +#define FT_VALIDATE_morx FT_VALIDATE_GX_BITFIELD( morx ) +#define FT_VALIDATE_bsln FT_VALIDATE_GX_BITFIELD( bsln ) +#define FT_VALIDATE_just FT_VALIDATE_GX_BITFIELD( just ) +#define FT_VALIDATE_kern FT_VALIDATE_GX_BITFIELD( kern ) +#define FT_VALIDATE_opbd FT_VALIDATE_GX_BITFIELD( opbd ) +#define FT_VALIDATE_trak FT_VALIDATE_GX_BITFIELD( trak ) +#define FT_VALIDATE_prop FT_VALIDATE_GX_BITFIELD( prop ) +#define FT_VALIDATE_lcar FT_VALIDATE_GX_BITFIELD( lcar ) + +#define FT_VALIDATE_GX ( FT_VALIDATE_feat | \ + FT_VALIDATE_mort | \ + FT_VALIDATE_morx | \ + FT_VALIDATE_bsln | \ + FT_VALIDATE_just | \ + FT_VALIDATE_kern | \ + FT_VALIDATE_opbd | \ + FT_VALIDATE_trak | \ + FT_VALIDATE_prop | \ + FT_VALIDATE_lcar ) + + + /* */ + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Validate + * + * @description: + * Validate various TrueTypeGX tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the tables to be validated. See + * @FT_VALIDATE_GXXXX for possible values. + * + * table_length :: + * The size of the `tables' array. Normally, @FT_VALIDATE_GX_LENGTH + * should be passed. + * + * @output: + * tables :: + * The array where all validated sfnt tables are stored. + * The array itself must be allocated by a client. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with TrueTypeGX fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the buffers pointed to by + * each `tables' element, by calling @FT_TrueTypeGX_Free. A NULL value + * indicates that the table either doesn't exist in the font, the + * application hasn't asked for validation, or the validator doesn't have + * the ability to validate the sfnt table. + */ + FT_EXPORT( FT_Error ) + FT_TrueTypeGX_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + /* */ + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Free + * + * @description: + * Free the buffer allocated by TrueTypeGX validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer allocated by + * @FT_TrueTypeGX_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_TrueTypeGX_Validate only. + */ + FT_EXPORT( void ) + FT_TrueTypeGX_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_CKERNXXX + * + * @description: + * A list of bit-field constants used with @FT_ClassicKern_Validate + * to indicate the classic kern dialect or dialects. If the selected + * type doesn't fit, @FT_ClassicKern_Validate regards the table as + * invalid. + * + * @values: + * FT_VALIDATE_MS :: + * Handle the `kern' table as a classic Microsoft kern table. + * + * FT_VALIDATE_APPLE :: + * Handle the `kern' table as a classic Apple kern table. + * + * FT_VALIDATE_CKERN :: + * Handle the `kern' as either classic Apple or Microsoft kern table. + */ +#define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 ) +#define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 ) + +#define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) + + + /* */ + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Validate + * + * @description: + * Validate classic (16-bit format) kern table to assure that the offsets + * and indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without error + * checking (which can be quite time consuming). + * + * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both + * the new 32-bit format and the classic 16-bit format, while + * FT_ClassicKern_Validate only supports the classic 16-bit format. + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the dialect to be validated. See + * @FT_VALIDATE_CKERNXXX for possible values. + * + * @output: + * ckern_table :: + * A pointer to the kern table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * After use, the application should deallocate the buffers pointed to by + * `ckern_table', by calling @FT_ClassicKern_Free. A NULL value + * indicates that the table doesn't exist in the font. + */ + FT_EXPORT( FT_Error ) + FT_ClassicKern_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *ckern_table ); + + + /* */ + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Free + * + * @description: + * Free the buffer allocated by classic Kern validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_ClassicKern_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_ClassicKern_Validate only. + */ + FT_EXPORT( void ) + FT_ClassicKern_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTGXVAL_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftgzip.h b/drivers/freetype/include/freetype/ftgzip.h new file mode 100644 index 0000000000..acbc4f0327 --- /dev/null +++ b/drivers/freetype/include/freetype/ftgzip.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* ftgzip.h */ +/* */ +/* Gzip-compressed stream support. */ +/* */ +/* 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, */ +/* 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 __FTGZIP_H__ +#define __FTGZIP_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gzip */ + /* */ + /* <Title> */ + /* GZIP Streams */ + /* */ + /* <Abstract> */ + /* Using gzip-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Gzip-specific functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************ + * + * @function: + * FT_Stream_OpenGzip + * + * @description: + * Open a new stream to parse gzip-compressed font files. This is + * mainly used to support the compressed `*.pcf.gz' fonts that come + * with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, gzip compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a gzipped stream from + * it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGZIP_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftimage.h b/drivers/freetype/include/freetype/ftimage.h new file mode 100644 index 0000000000..3b826b1d32 --- /dev/null +++ b/drivers/freetype/include/freetype/ftimage.h @@ -0,0 +1,1322 @@ +/***************************************************************************/ +/* */ +/* ftimage.h */ +/* */ +/* FreeType glyph image formats and default raster interface */ +/* (specification). */ +/* */ +/* Copyright 1996-2010, 2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Note: A `raster' is simply a scan-line converter, used to render */ + /* FT_Outlines into FT_Bitmaps. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTIMAGE_H__ +#define __FTIMAGE_H__ + + + /* _STANDALONE_ is from ftgrays.c */ +#ifndef _STANDALONE_ +#include <ft2build.h> +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pos */ + /* */ + /* <Description> */ + /* The type FT_Pos is used to store vectorial coordinates. Depending */ + /* on the context, these can represent distances in integer font */ + /* units, or 16.16, or 26.6 fixed-point pixel coordinates. */ + /* */ + typedef signed long FT_Pos; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Vector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector; coordinates are of */ + /* the FT_Pos type. */ + /* */ + /* <Fields> */ + /* x :: The horizontal coordinate. */ + /* y :: The vertical coordinate. */ + /* */ + typedef struct FT_Vector_ + { + FT_Pos x; + FT_Pos y; + + } FT_Vector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BBox */ + /* */ + /* <Description> */ + /* A structure used to hold an outline's bounding box, i.e., the */ + /* coordinates of its extrema in the horizontal and vertical */ + /* directions. */ + /* */ + /* <Fields> */ + /* xMin :: The horizontal minimum (left-most). */ + /* */ + /* yMin :: The vertical minimum (bottom-most). */ + /* */ + /* xMax :: The horizontal maximum (right-most). */ + /* */ + /* yMax :: The vertical maximum (top-most). */ + /* */ + /* <Note> */ + /* The bounding box is specified with the coordinates of the lower */ + /* left and the upper right corner. In PostScript, those values are */ + /* often called (llx,lly) and (urx,ury), respectively. */ + /* */ + /* If `yMin' is negative, this value gives the glyph's descender. */ + /* Otherwise, the glyph doesn't descend below the baseline. */ + /* Similarly, if `ymax' is positive, this value gives the glyph's */ + /* ascender. */ + /* */ + /* `xMin' gives the horizontal distance from the glyph's origin to */ + /* the left edge of the glyph's bounding box. If `xMin' is negative, */ + /* the glyph extends to the left of the origin. */ + /* */ + typedef struct FT_BBox_ + { + FT_Pos xMin, yMin; + FT_Pos xMax, yMax; + + } FT_BBox; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Pixel_Mode */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of pixels in a */ + /* given bitmap. Note that additional formats may be added in the */ + /* future. */ + /* */ + /* <Values> */ + /* FT_PIXEL_MODE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_PIXEL_MODE_MONO :: */ + /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ + /* are stored in most-significant order (MSB), which means that */ + /* the left-most pixel in a byte has value 128. */ + /* */ + /* FT_PIXEL_MODE_GRAY :: */ + /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ + /* images. Each pixel is stored in one byte. Note that the number */ + /* of `gray' levels is stored in the `num_grays' field of the */ + /* @FT_Bitmap structure (it generally is 256). */ + /* */ + /* FT_PIXEL_MODE_GRAY2 :: */ + /* A 2-bit per pixel bitmap, used to represent embedded */ + /* anti-aliased bitmaps in font files according to the OpenType */ + /* specification. We haven't found a single font using this */ + /* format, however. */ + /* */ + /* FT_PIXEL_MODE_GRAY4 :: */ + /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ + /* bitmaps in font files according to the OpenType specification. */ + /* We haven't found a single font using this format, however. */ + /* */ + /* FT_PIXEL_MODE_LCD :: */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on LCD displays; the bitmap is three times */ + /* wider than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD. */ + /* */ + /* FT_PIXEL_MODE_LCD_V :: */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on rotated LCD displays; the bitmap is three */ + /* times taller than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD_V. */ + /* */ + /* FT_PIXEL_MODE_BGRA :: */ + /* An image with four 8-bit channels per pixel, representing a */ + /* color image (such as emoticons) with alpha channel. For each */ + /* pixel, the format is BGRA, which means, the blue channel comes */ + /* first in memory. The color channels are pre-multiplied and in */ + /* the sRGB colorspace. For example, full red at half-translucent */ + /* opacity will be represented as `00,00,80,80', not `00,00,FF,80'. */ + /* See also @FT_LOAD_COLOR. */ + /* */ + typedef enum FT_Pixel_Mode_ + { + FT_PIXEL_MODE_NONE = 0, + FT_PIXEL_MODE_MONO, + FT_PIXEL_MODE_GRAY, + FT_PIXEL_MODE_GRAY2, + FT_PIXEL_MODE_GRAY4, + FT_PIXEL_MODE_LCD, + FT_PIXEL_MODE_LCD_V, + FT_PIXEL_MODE_BGRA, + + FT_PIXEL_MODE_MAX /* do not remove */ + + } FT_Pixel_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_pixel_mode_xxx */ + /* */ + /* <Description> */ + /* A list of deprecated constants. Use the corresponding */ + /* @FT_Pixel_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_pixel_mode_none :: See @FT_PIXEL_MODE_NONE. */ + /* ft_pixel_mode_mono :: See @FT_PIXEL_MODE_MONO. */ + /* ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY. */ + /* ft_pixel_mode_pal2 :: See @FT_PIXEL_MODE_GRAY2. */ + /* ft_pixel_mode_pal4 :: See @FT_PIXEL_MODE_GRAY4. */ + /* */ +#define ft_pixel_mode_none FT_PIXEL_MODE_NONE +#define ft_pixel_mode_mono FT_PIXEL_MODE_MONO +#define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY +#define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 +#define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 + + /* */ + +#if 0 + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Palette_Mode */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT! */ + /* */ + /* An enumeration type to describe the format of a bitmap palette, */ + /* used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ + /* */ + /* <Values> */ + /* ft_palette_mode_rgb :: The palette is an array of 3-byte RGB */ + /* records. */ + /* */ + /* ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA */ + /* records. */ + /* */ + /* <Note> */ + /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ + /* FreeType, these types are not handled by the library itself. */ + /* */ + typedef enum FT_Palette_Mode_ + { + ft_palette_mode_rgb = 0, + ft_palette_mode_rgba, + + ft_palette_mode_max /* do not remove */ + + } FT_Palette_Mode; + + /* */ + +#endif + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap */ + /* */ + /* <Description> */ + /* A structure used to describe a bitmap or pixmap to the raster. */ + /* Note that we now manage pixmaps of various depths through the */ + /* `pixel_mode' field. */ + /* */ + /* <Fields> */ + /* rows :: The number of bitmap rows. */ + /* */ + /* width :: The number of pixels in bitmap row. */ + /* */ + /* pitch :: The pitch's absolute value is the number of bytes */ + /* taken by one bitmap row, including padding. */ + /* However, the pitch is positive when the bitmap has */ + /* a `down' flow, and negative when it has an `up' */ + /* flow. In all cases, the pitch is an offset to add */ + /* to a bitmap pointer in order to go down one row. */ + /* */ + /* Note that `padding' means the alignment of a */ + /* bitmap to a byte border, and FreeType functions */ + /* normally align to the smallest possible integer */ + /* value. */ + /* */ + /* For the B/W rasterizer, `pitch' is always an even */ + /* number. */ + /* */ + /* To change the pitch of a bitmap (say, to make it a */ + /* multiple of 4), use @FT_Bitmap_Convert. */ + /* Alternatively, you might use callback functions to */ + /* directly render to the application's surface; see */ + /* the file `example2.cpp' in the tutorial for a */ + /* demonstration. */ + /* */ + /* buffer :: A typeless pointer to the bitmap buffer. This */ + /* value should be aligned on 32-bit boundaries in */ + /* most cases. */ + /* */ + /* num_grays :: This field is only used with */ + /* @FT_PIXEL_MODE_GRAY; it gives the number of gray */ + /* levels used in the bitmap. */ + /* */ + /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ + /* See @FT_Pixel_Mode for possible values. */ + /* */ + /* palette_mode :: This field is intended for paletted pixel modes; */ + /* it indicates how the palette is stored. Not */ + /* used currently. */ + /* */ + /* palette :: A typeless pointer to the bitmap palette; this */ + /* field is intended for paletted pixel modes. Not */ + /* used currently. */ + /* */ + /* <Note> */ + /* For now, the only pixel modes supported by FreeType are mono and */ + /* grays. However, drivers might be added in the future to support */ + /* more `colorful' options. */ + /* */ + typedef struct FT_Bitmap_ + { + int rows; + int width; + int pitch; + unsigned char* buffer; + short num_grays; + char pixel_mode; + char palette_mode; + void* palette; + + } FT_Bitmap; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline */ + /* */ + /* <Description> */ + /* This structure is used to describe an outline to the scan-line */ + /* converter. */ + /* */ + /* <Fields> */ + /* n_contours :: The number of contours in the outline. */ + /* */ + /* n_points :: The number of points in the outline. */ + /* */ + /* points :: A pointer to an array of `n_points' @FT_Vector */ + /* elements, giving the outline's point coordinates. */ + /* */ + /* tags :: A pointer to an array of `n_points' chars, giving */ + /* each outline point's type. */ + /* */ + /* If bit~0 is unset, the point is `off' the curve, */ + /* i.e., a Bézier control point, while it is `on' if */ + /* set. */ + /* */ + /* Bit~1 is meaningful for `off' points only. If set, */ + /* it indicates a third-order Bézier arc control point; */ + /* and a second-order control point if unset. */ + /* */ + /* If bit~2 is set, bits 5-7 contain the drop-out mode */ + /* (as defined in the OpenType specification; the value */ + /* is the same as the argument to the SCANMODE */ + /* instruction). */ + /* */ + /* Bits 3 and~4 are reserved for internal purposes. */ + /* */ + /* contours :: An array of `n_contours' shorts, giving the end */ + /* point of each contour within the outline. For */ + /* example, the first contour is defined by the points */ + /* `0' to `contours[0]', the second one is defined by */ + /* the points `contours[0]+1' to `contours[1]', etc. */ + /* */ + /* flags :: A set of bit flags used to characterize the outline */ + /* and give hints to the scan-converter and hinter on */ + /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ + /* */ + /* <Note> */ + /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ + /* first point of each contour. The drop-out mode as given with */ + /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ + /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ + /* */ + typedef struct FT_Outline_ + { + short n_contours; /* number of contours in glyph */ + short n_points; /* number of points in the glyph */ + + FT_Vector* points; /* the outline's points */ + char* tags; /* the points flags */ + short* contours; /* the contour end points */ + + int flags; /* outline masks */ + + } FT_Outline; + + /* Following limits must be consistent with */ + /* FT_Outline.{n_contours,n_points} */ +#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX +#define FT_OUTLINE_POINTS_MAX SHRT_MAX + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OUTLINE_FLAGS */ + /* */ + /* <Description> */ + /* A list of bit-field constants use for the flags in an outline's */ + /* `flags' field. */ + /* */ + /* <Values> */ + /* FT_OUTLINE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_OUTLINE_OWNER :: */ + /* If set, this flag indicates that the outline's field arrays */ + /* (i.e., `points', `flags', and `contours') are `owned' by the */ + /* outline object, and should thus be freed when it is destroyed. */ + /* */ + /* FT_OUTLINE_EVEN_ODD_FILL :: */ + /* By default, outlines are filled using the non-zero winding rule. */ + /* If set to 1, the outline will be filled using the even-odd fill */ + /* rule (only works with the smooth rasterizer). */ + /* */ + /* FT_OUTLINE_REVERSE_FILL :: */ + /* By default, outside contours of an outline are oriented in */ + /* clock-wise direction, as defined in the TrueType specification. */ + /* This flag is set if the outline uses the opposite direction */ + /* (typically for Type~1 fonts). This flag is ignored by the scan */ + /* converter. */ + /* */ + /* FT_OUTLINE_IGNORE_DROPOUTS :: */ + /* By default, the scan converter will try to detect drop-outs in */ + /* an outline and correct the glyph bitmap to ensure consistent */ + /* shape continuity. If set, this flag hints the scan-line */ + /* converter to ignore such cases. See below for more information. */ + /* */ + /* FT_OUTLINE_SMART_DROPOUTS :: */ + /* Select smart dropout control. If unset, use simple dropout */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ + /* below for more information. */ + /* */ + /* FT_OUTLINE_INCLUDE_STUBS :: */ + /* If set, turn pixels on for `stubs', otherwise exclude them. */ + /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ + /* more information. */ + /* */ + /* FT_OUTLINE_HIGH_PRECISION :: */ + /* This flag indicates that the scan-line converter should try to */ + /* convert this outline to bitmaps with the highest possible */ + /* quality. It is typically set for small character sizes. Note */ + /* that this is only a hint that might be completely ignored by a */ + /* given scan-converter. */ + /* */ + /* FT_OUTLINE_SINGLE_PASS :: */ + /* This flag is set to force a given scan-converter to only use a */ + /* single pass over the outline to render a bitmap glyph image. */ + /* Normally, it is set for very large character sizes. It is only */ + /* a hint that might be completely ignored by a given */ + /* scan-converter. */ + /* */ + /* <Note> */ + /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ + /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ + /* rasterizer. */ + /* */ + /* There exists a second mechanism to pass the drop-out mode to the */ + /* B/W rasterizer; see the `tags' field in @FT_Outline. */ + /* */ + /* Please refer to the description of the `SCANTYPE' instruction in */ + /* the OpenType specification (in file `ttinst1.doc') how simple */ + /* drop-outs, smart drop-outs, and stubs are defined. */ + /* */ +#define FT_OUTLINE_NONE 0x0 +#define FT_OUTLINE_OWNER 0x1 +#define FT_OUTLINE_EVEN_ODD_FILL 0x2 +#define FT_OUTLINE_REVERSE_FILL 0x4 +#define FT_OUTLINE_IGNORE_DROPOUTS 0x8 +#define FT_OUTLINE_SMART_DROPOUTS 0x10 +#define FT_OUTLINE_INCLUDE_STUBS 0x20 + +#define FT_OUTLINE_HIGH_PRECISION 0x100 +#define FT_OUTLINE_SINGLE_PASS 0x200 + + + /************************************************************************* + * + * @enum: + * ft_outline_flags + * + * @description: + * These constants are deprecated. Please use the corresponding + * @FT_OUTLINE_FLAGS values. + * + * @values: + * ft_outline_none :: See @FT_OUTLINE_NONE. + * ft_outline_owner :: See @FT_OUTLINE_OWNER. + * ft_outline_even_odd_fill :: See @FT_OUTLINE_EVEN_ODD_FILL. + * ft_outline_reverse_fill :: See @FT_OUTLINE_REVERSE_FILL. + * ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS. + * ft_outline_high_precision :: See @FT_OUTLINE_HIGH_PRECISION. + * ft_outline_single_pass :: See @FT_OUTLINE_SINGLE_PASS. + */ +#define ft_outline_none FT_OUTLINE_NONE +#define ft_outline_owner FT_OUTLINE_OWNER +#define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL +#define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL +#define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS +#define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION +#define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS + + /* */ + +#define FT_CURVE_TAG( flag ) ( flag & 3 ) + +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 + +#define FT_CURVE_TAG_HAS_SCANMODE 4 + +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ + +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) + +#define FT_Curve_Tag_On FT_CURVE_TAG_ON +#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC +#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC +#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X +#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_MoveToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `move */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `move to' is emitted to start a new contour in an outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `move to'. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_MoveToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_LineToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `line */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `line to' is emitted to indicate a segment in the outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `line to'. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_LineToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_LineTo_Func FT_Outline_LineToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_ConicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `conic */ + /* to' function during outline walking or decomposition. */ + /* */ + /* A `conic to' is emitted to indicate a second-order Bézier arc in */ + /* the outline. */ + /* */ + /* <Input> */ + /* control :: An intermediate control point between the last position */ + /* and the new target in `to'. */ + /* */ + /* to :: A pointer to the target end point of the conic arc. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_ConicToFunc)( const FT_Vector* control, + const FT_Vector* to, + void* user ); + +#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_CubicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `cubic */ + /* to' function during outline walking or decomposition. */ + /* */ + /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first Bézier control point. */ + /* */ + /* control2 :: A pointer to the second Bézier control point. */ + /* */ + /* to :: A pointer to the target end point. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_CubicToFunc)( const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to, + void* user ); + +#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline_Funcs */ + /* */ + /* <Description> */ + /* A structure to hold various function pointers used during outline */ + /* decomposition in order to emit segments, conic, and cubic Béziers. */ + /* */ + /* <Fields> */ + /* move_to :: The `move to' emitter. */ + /* */ + /* line_to :: The segment emitter. */ + /* */ + /* conic_to :: The second-order Bézier arc emitter. */ + /* */ + /* cubic_to :: The third-order Bézier arc emitter. */ + /* */ + /* shift :: The shift that is applied to coordinates before they */ + /* are sent to the emitter. */ + /* */ + /* delta :: The delta that is applied to coordinates before they */ + /* are sent to the emitter, but after the shift. */ + /* */ + /* <Note> */ + /* The point coordinates sent to the emitters are the transformed */ + /* version of the original coordinates (this is important for high */ + /* accuracy during scan-conversion). The transformation is simple: */ + /* */ + /* { */ + /* x' = (x << shift) - delta */ + /* y' = (x << shift) - delta */ + /* } */ + /* */ + /* Set the values of `shift' and `delta' to~0 to get the original */ + /* point coordinates. */ + /* */ + typedef struct FT_Outline_Funcs_ + { + FT_Outline_MoveToFunc move_to; + FT_Outline_LineToFunc line_to; + FT_Outline_ConicToFunc conic_to; + FT_Outline_CubicToFunc cubic_to; + + int shift; + FT_Pos delta; + + } FT_Outline_Funcs; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_IMAGE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags to an unsigned long type. */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ +#ifndef FT_IMAGE_TAG +#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ + value = ( ( (unsigned long)_x1 << 24 ) | \ + ( (unsigned long)_x2 << 16 ) | \ + ( (unsigned long)_x3 << 8 ) | \ + (unsigned long)_x4 ) +#endif /* FT_IMAGE_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_Format */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of a given glyph */ + /* image. Note that this version of FreeType only supports two image */ + /* formats, even though future font drivers will be able to register */ + /* their own format. */ + /* */ + /* <Values> */ + /* FT_GLYPH_FORMAT_NONE :: */ + /* The value~0 is reserved. */ + /* */ + /* FT_GLYPH_FORMAT_COMPOSITE :: */ + /* The glyph image is a composite of several other images. This */ + /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ + /* report compound glyphs (like accented characters). */ + /* */ + /* FT_GLYPH_FORMAT_BITMAP :: */ + /* The glyph image is a bitmap, and can be described as an */ + /* @FT_Bitmap. You generally need to access the `bitmap' field of */ + /* the @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_OUTLINE :: */ + /* The glyph image is a vectorial outline made of line segments */ + /* and Bézier arcs; it can be described as an @FT_Outline; you */ + /* generally want to access the `outline' field of the */ + /* @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_PLOTTER :: */ + /* The glyph image is a vectorial path with no inside and outside */ + /* contours. Some Type~1 fonts, like those in the Hershey family, */ + /* contain glyphs in this format. These are described as */ + /* @FT_Outline, but FreeType isn't currently capable of rendering */ + /* them correctly. */ + /* */ + typedef enum FT_Glyph_Format_ + { + FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), + + FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ) + + } FT_Glyph_Format; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_glyph_format_xxx */ + /* */ + /* <Description> */ + /* A list of deprecated constants. Use the corresponding */ + /* @FT_Glyph_Format values instead. */ + /* */ + /* <Values> */ + /* ft_glyph_format_none :: See @FT_GLYPH_FORMAT_NONE. */ + /* ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE. */ + /* ft_glyph_format_bitmap :: See @FT_GLYPH_FORMAT_BITMAP. */ + /* ft_glyph_format_outline :: See @FT_GLYPH_FORMAT_OUTLINE. */ + /* ft_glyph_format_plotter :: See @FT_GLYPH_FORMAT_PLOTTER. */ + /* */ +#define ft_glyph_format_none FT_GLYPH_FORMAT_NONE +#define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE +#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP +#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE +#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** R A S T E R D E F I N I T I O N S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A raster is a scan converter, in charge of rendering an outline into */ + /* a a bitmap. This section contains the public API for rasters. */ + /* */ + /* Note that in FreeType 2, all rasters are now encapsulated within */ + /* specific modules called `renderers'. See `freetype/ftrender.h' for */ + /* more details on renderers. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* raster */ + /* */ + /* <Title> */ + /* Scanline Converter */ + /* */ + /* <Abstract> */ + /* How vectorial outlines are converted into bitmaps and pixmaps. */ + /* */ + /* <Description> */ + /* This section contains technical definitions. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Raster */ + /* */ + /* <Description> */ + /* A handle (pointer) to a raster object. Each object can be used */ + /* independently to convert an outline into a bitmap or pixmap. */ + /* */ + typedef struct FT_RasterRec_* FT_Raster; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Span */ + /* */ + /* <Description> */ + /* A structure used to model a single span of gray (or black) pixels */ + /* when rendering a monochrome or anti-aliased bitmap. */ + /* */ + /* <Fields> */ + /* x :: The span's horizontal start position. */ + /* */ + /* len :: The span's length in pixels. */ + /* */ + /* coverage :: The span color/coverage, ranging from 0 (background) */ + /* to 255 (foreground). Only used for anti-aliased */ + /* rendering. */ + /* */ + /* <Note> */ + /* This structure is used by the span drawing callback type named */ + /* @FT_SpanFunc which takes the y~coordinate of the span as a */ + /* a parameter. */ + /* */ + /* The coverage value is always between 0 and 255. If you want less */ + /* gray values, the callback function has to reduce them. */ + /* */ + typedef struct FT_Span_ + { + short x; + unsigned short len; + unsigned char coverage; + + } FT_Span; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_SpanFunc */ + /* */ + /* <Description> */ + /* A function used as a call-back by the anti-aliased renderer in */ + /* order to let client applications draw themselves the gray pixel */ + /* spans on each scan line. */ + /* */ + /* <Input> */ + /* y :: The scanline's y~coordinate. */ + /* */ + /* count :: The number of spans to draw on this scanline. */ + /* */ + /* spans :: A table of `count' spans to draw on the scanline. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Note> */ + /* This callback allows client applications to directly render the */ + /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ + /* */ + /* This can be used to write anti-aliased outlines directly to a */ + /* given background bitmap, and even perform translucency. */ + /* */ + /* Note that the `count' field cannot be greater than a fixed value */ + /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ + /* `ftoption.h'. By default, this value is set to~32, which means */ + /* that if there are more than 32~spans on a given scanline, the */ + /* callback is called several times with the same `y' parameter in */ + /* order to draw all callbacks. */ + /* */ + /* Otherwise, the callback is only called once per scan-line, and */ + /* only for those scanlines that do have `gray' pixels on them. */ + /* */ + typedef void + (*FT_SpanFunc)( int y, + int count, + const FT_Span* spans, + void* user ); + +#define FT_Raster_Span_Func FT_SpanFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitTest_Func */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ + /* */ + /* A function used as a call-back by the monochrome scan-converter */ + /* to test whether a given target pixel is already set to the drawing */ + /* `color'. These tests are crucial to implement drop-out control */ + /* per-se the TrueType spec. */ + /* */ + /* <Input> */ + /* y :: The pixel's y~coordinate. */ + /* */ + /* x :: The pixel's x~coordinate. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Return> */ + /* 1~if the pixel is `set', 0~otherwise. */ + /* */ + typedef int + (*FT_Raster_BitTest_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitSet_Func */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ + /* */ + /* A function used as a call-back by the monochrome scan-converter */ + /* to set an individual target pixel. This is crucial to implement */ + /* drop-out control according to the TrueType specification. */ + /* */ + /* <Input> */ + /* y :: The pixel's y~coordinate. */ + /* */ + /* x :: The pixel's x~coordinate. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Return> */ + /* 1~if the pixel is `set', 0~otherwise. */ + /* */ + typedef void + (*FT_Raster_BitSet_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flag constants as used in the `flags' field of a */ + /* @FT_Raster_Params structure. */ + /* */ + /* <Values> */ + /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ + /* */ + /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ + /* anti-aliased glyph image should be */ + /* generated. Otherwise, it will be */ + /* monochrome (1-bit). */ + /* */ + /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ + /* rendering. In this mode, client */ + /* applications must provide their own span */ + /* callback. This lets them directly */ + /* draw or compose over an existing bitmap. */ + /* If this bit is not set, the target */ + /* pixmap's buffer _must_ be zeroed before */ + /* rendering. */ + /* */ + /* Note that for now, direct rendering is */ + /* only possible with anti-aliased glyphs. */ + /* */ + /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ + /* rendering mode. If set, the output will */ + /* be clipped to a box specified in the */ + /* `clip_box' field of the */ + /* @FT_Raster_Params structure. */ + /* */ + /* Note that by default, the glyph bitmap */ + /* is clipped to the target pixmap, except */ + /* in direct rendering mode where all spans */ + /* are generated if no clipping box is set. */ + /* */ +#define FT_RASTER_FLAG_DEFAULT 0x0 +#define FT_RASTER_FLAG_AA 0x1 +#define FT_RASTER_FLAG_DIRECT 0x2 +#define FT_RASTER_FLAG_CLIP 0x4 + + /* deprecated */ +#define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT +#define ft_raster_flag_aa FT_RASTER_FLAG_AA +#define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT +#define ft_raster_flag_clip FT_RASTER_FLAG_CLIP + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Params */ + /* */ + /* <Description> */ + /* A structure to hold the arguments used by a raster's render */ + /* function. */ + /* */ + /* <Fields> */ + /* target :: The target bitmap. */ + /* */ + /* source :: A pointer to the source glyph image (e.g., an */ + /* @FT_Outline). */ + /* */ + /* flags :: The rendering flags. */ + /* */ + /* gray_spans :: The gray span drawing callback. */ + /* */ + /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ + /* */ + /* bit_test :: The bit test callback. UNIMPLEMENTED! */ + /* */ + /* bit_set :: The bit set callback. UNIMPLEMENTED! */ + /* */ + /* user :: User-supplied data that is passed to each drawing */ + /* callback. */ + /* */ + /* clip_box :: An optional clipping box. It is only used in */ + /* direct rendering mode. Note that coordinates here */ + /* should be expressed in _integer_ pixels (and not in */ + /* 26.6 fixed-point units). */ + /* */ + /* <Note> */ + /* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA */ + /* bit flag is set in the `flags' field, otherwise a monochrome */ + /* bitmap is generated. */ + /* */ + /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ + /* raster will call the `gray_spans' callback to draw gray pixel */ + /* spans, in the case of an aa glyph bitmap, it will call */ + /* `black_spans', and `bit_test' and `bit_set' in the case of a */ + /* monochrome bitmap. This allows direct composition over a */ + /* pre-existing bitmap through user-provided callbacks to perform the */ + /* span drawing/composition. */ + /* */ + /* Note that the `bit_test' and `bit_set' callbacks are required when */ + /* rendering a monochrome bitmap, as they are crucial to implement */ + /* correct drop-out control as defined in the TrueType specification. */ + /* */ + typedef struct FT_Raster_Params_ + { + const FT_Bitmap* target; + const void* source; + int flags; + FT_SpanFunc gray_spans; + FT_SpanFunc black_spans; /* doesn't work! */ + FT_Raster_BitTest_Func bit_test; /* doesn't work! */ + FT_Raster_BitSet_Func bit_set; /* doesn't work! */ + void* user; + FT_BBox clip_box; + + } FT_Raster_Params; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_NewFunc */ + /* */ + /* <Description> */ + /* A function used to create a new raster object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory allocator. */ + /* */ + /* <Output> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `memory' parameter is a typeless pointer in order to avoid */ + /* un-wanted dependencies on the rest of the FreeType code. In */ + /* practice, it is an @FT_Memory object, i.e., a handle to the */ + /* standard FreeType memory allocator. However, this field can be */ + /* completely ignored by a given raster implementation. */ + /* */ + typedef int + (*FT_Raster_NewFunc)( void* memory, + FT_Raster* raster ); + +#define FT_Raster_New_Func FT_Raster_NewFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_DoneFunc */ + /* */ + /* <Description> */ + /* A function used to destroy a given raster object. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + typedef void + (*FT_Raster_DoneFunc)( FT_Raster raster ); + +#define FT_Raster_Done_Func FT_Raster_DoneFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_ResetFunc */ + /* */ + /* <Description> */ + /* FreeType provides an area of memory called the `render pool', */ + /* available to all registered rasters. This pool can be freely used */ + /* during a given scan-conversion but is shared by all rasters. Its */ + /* content is thus transient. */ + /* */ + /* This function is called each time the render pool changes, or just */ + /* after a new raster object is created. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* pool_base :: The address in memory of the render pool. */ + /* */ + /* pool_size :: The size in bytes of the render pool. */ + /* */ + /* <Note> */ + /* Rasters can ignore the render pool and rely on dynamic memory */ + /* allocation if they want to (a handle to the memory allocator is */ + /* passed to the raster constructor). However, this is not */ + /* recommended for efficiency purposes. */ + /* */ + typedef void + (*FT_Raster_ResetFunc)( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ); + +#define FT_Raster_Reset_Func FT_Raster_ResetFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_SetModeFunc */ + /* */ + /* <Description> */ + /* This function is a generic facility to change modes or attributes */ + /* in a given raster. This can be used for debugging purposes, or */ + /* simply to allow implementation-specific `features' in a given */ + /* raster module. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* mode :: A 4-byte tag used to name the mode or property. */ + /* */ + /* args :: A pointer to the new mode/property to use. */ + /* */ + typedef int + (*FT_Raster_SetModeFunc)( FT_Raster raster, + unsigned long mode, + void* args ); + +#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_RenderFunc */ + /* */ + /* <Description> */ + /* Invoke a given raster to scan-convert a given glyph image into a */ + /* target bitmap. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* store the rendering parameters. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The exact format of the source image depends on the raster's glyph */ + /* format defined in its @FT_Raster_Funcs structure. It can be an */ + /* @FT_Outline or anything else in order to support a large array of */ + /* glyph formats. */ + /* */ + /* Note also that the render function can fail and return a */ + /* `FT_Err_Unimplemented_Feature' error code if the raster used does */ + /* not support direct composition. */ + /* */ + /* XXX: For now, the standard raster doesn't support direct */ + /* composition but this should change for the final release (see */ + /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ + /* for examples of distinct implementations which support direct */ + /* composition). */ + /* */ + typedef int + (*FT_Raster_RenderFunc)( FT_Raster raster, + const FT_Raster_Params* params ); + +#define FT_Raster_Render_Func FT_Raster_RenderFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Funcs */ + /* */ + /* <Description> */ + /* A structure used to describe a given raster class to the library. */ + /* */ + /* <Fields> */ + /* glyph_format :: The supported glyph format for this raster. */ + /* */ + /* raster_new :: The raster constructor. */ + /* */ + /* raster_reset :: Used to reset the render pool within the raster. */ + /* */ + /* raster_render :: A function to render a glyph into a given bitmap. */ + /* */ + /* raster_done :: The raster destructor. */ + /* */ + typedef struct FT_Raster_Funcs_ + { + FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; + FT_Raster_ResetFunc raster_reset; + FT_Raster_SetModeFunc raster_set_mode; + FT_Raster_RenderFunc raster_render; + FT_Raster_DoneFunc raster_done; + + } FT_Raster_Funcs; + + + /* */ + + +FT_END_HEADER + +#endif /* __FTIMAGE_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/drivers/freetype/include/freetype/ftincrem.h b/drivers/freetype/include/freetype/ftincrem.h new file mode 100644 index 0000000000..aaf689ff16 --- /dev/null +++ b/drivers/freetype/include/freetype/ftincrem.h @@ -0,0 +1,353 @@ +/***************************************************************************/ +/* */ +/* ftincrem.h */ +/* */ +/* FreeType incremental loading (specification). */ +/* */ +/* Copyright 2002, 2003, 2006, 2007, 2008, 2010 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 __FTINCREM_H__ +#define __FTINCREM_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * incremental + * + * @title: + * Incremental Loading + * + * @abstract: + * Custom Glyph Loading. + * + * @description: + * This section contains various functions used to perform so-called + * `incremental' glyph loading. This is a mode where all glyphs loaded + * from a given @FT_Face are provided by the client application, + * + * Apart from that, all other tables are loaded normally from the font + * file. This mode is useful when FreeType is used within another + * engine, e.g., a PostScript Imaging Processor. + * + * To enable this mode, you must use @FT_Open_Face, passing an + * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an + * @FT_Incremental_Interface value. See the comments for + * @FT_Incremental_InterfaceRec for an example. + * + */ + + + /*************************************************************************** + * + * @type: + * FT_Incremental + * + * @description: + * An opaque type describing a user-provided object used to implement + * `incremental' glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g., PostScript interpreters), + * where the glyph data isn't in the font file, or must be overridden by + * different values. + * + * @note: + * It is up to client applications to create and implement @FT_Incremental + * objects, as long as they provide implementations for the methods + * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc + * and @FT_Incremental_GetGlyphMetricsFunc. + * + * See the description of @FT_Incremental_InterfaceRec to understand how + * to use incremental objects with FreeType. + * + */ + typedef struct FT_IncrementalRec_* FT_Incremental; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_MetricsRec + * + * @description: + * A small structure used to contain the basic glyph metrics returned + * by the @FT_Incremental_GetGlyphMetricsFunc method. + * + * @fields: + * bearing_x :: + * Left bearing, in font units. + * + * bearing_y :: + * Top bearing, in font units. + * + * advance :: + * Horizontal component of glyph advance, in font units. + * + * advance_v :: + * Vertical component of glyph advance, in font units. + * + * @note: + * These correspond to horizontal or vertical metrics depending on the + * value of the `vertical' argument to the function + * @FT_Incremental_GetGlyphMetricsFunc. + * + */ + typedef struct FT_Incremental_MetricsRec_ + { + FT_Long bearing_x; + FT_Long bearing_y; + FT_Long advance; + FT_Long advance_v; /* since 2.3.12 */ + + } FT_Incremental_MetricsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_Metrics + * + * @description: + * A handle to an @FT_Incremental_MetricsRec structure. + * + */ + typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphDataFunc + * + * @description: + * A function called by FreeType to access a given glyph's data bytes + * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is + * enabled. + * + * Note that the format of the glyph's data bytes depends on the font + * file format. For TrueType, it must correspond to the raw bytes within + * the `glyf' table. For PostScript formats, it must correspond to the + * *unencrypted* charstring bytes, without any `lenIV' header. It is + * undefined for any other format. + * + * @input: + * incremental :: + * Handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * @output: + * adata :: + * A structure describing the returned glyph data bytes (which will be + * accessed as a read-only byte block). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If this function returns successfully the method + * @FT_Incremental_FreeGlyphDataFunc will be called later to release + * the data bytes. + * + * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for + * compound glyphs. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Data* adata ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_FreeGlyphDataFunc + * + * @description: + * A function used to release the glyph data bytes returned by a + * successful call to @FT_Incremental_GetGlyphDataFunc. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * data :: + * A structure describing the glyph data bytes (which will be accessed + * as a read-only byte block). + * + */ + typedef void + (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, + FT_Data* data ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphMetricsFunc + * + * @description: + * A function used to retrieve the basic metrics of a given glyph index + * before accessing its data. This is necessary because, in certain + * formats like TrueType, the metrics are stored in a different place from + * the glyph images proper. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * vertical :: + * If true, return vertical metrics. + * + * ametrics :: + * This parameter is used for both input and output. + * The original glyph metrics, if any, in font units. If metrics are + * not available all the values must be set to zero. + * + * @output: + * ametrics :: + * The replacement glyph metrics in font units. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphMetricsFunc) + ( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Bool vertical, + FT_Incremental_MetricsRec *ametrics ); + + + /************************************************************************** + * + * @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. + * + * free_glyph_data :: + * The function to release glyph data. Must not be null. + * + * get_glyph_metrics :: + * The function to get glyph metrics. May be null if the font does + * not provide overriding glyph metrics. + * + */ + typedef struct FT_Incremental_FuncsRec_ + { + FT_Incremental_GetGlyphDataFunc get_glyph_data; + FT_Incremental_FreeGlyphDataFunc free_glyph_data; + FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; + + } FT_Incremental_FuncsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_InterfaceRec + * + * @description: + * A structure to be used with @FT_Open_Face to indicate that the user + * wants to support incremental glyph loading. You should use it with + * @FT_PARAM_TAG_INCREMENTAL as in the following example: + * + * { + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; + * + * + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; + * + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; + * + * // set up FT_Open_Args structure + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument + * + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * } + * + */ + typedef struct FT_Incremental_InterfaceRec_ + { + const FT_Incremental_FuncsRec* funcs; + FT_Incremental object; + + } FT_Incremental_InterfaceRec; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_Interface + * + * @description: + * A pointer to an @FT_Incremental_InterfaceRec structure. + * + */ + typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * A constant used as the tag of @FT_Parameter structures to indicate + * an incremental loading object to be used by FreeType. + * + */ +#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) + + /* */ + +FT_END_HEADER + +#endif /* __FTINCREM_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftlcdfil.h b/drivers/freetype/include/freetype/ftlcdfil.h new file mode 100644 index 0000000000..8b253f118b --- /dev/null +++ b/drivers/freetype/include/freetype/ftlcdfil.h @@ -0,0 +1,251 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.h */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs */ +/* (specification). */ +/* */ +/* Copyright 2006, 2007, 2008, 2010 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 + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +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. + * + * FreeType generates alpha coverage maps, which are linear by nature. + * For instance, the value 0x80 in bitmap representation means that + * (within numerical precision) 0x80/0xff fraction of that pixel is + * covered by the glyph's outline. The blending function for placing + * text over a background is + * + * { + * dst = alpha * src + (1 - alpha) * dst , + * } + * + * which is known as OVER. However, when calculating the output of the + * OVER operator, the source colors should first be transformed to a + * linear color space, then alpha blended in that space, and transformed + * back to the output color space. + * + * When linear light blending is used, the default FIR5 filtering + * weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as + * they have been designed for black on white rendering while lacking + * gamma correction. To preserve color neutrality, weights for a FIR5 + * filter should be chosen according to two free parameters `a' and `c', + * and the FIR weights should be + * + * { + * [a - c, a + c, 2 * a, a + c, a - c] . + * } + * + * This formula generates equal weights for all the color primaries + * across the filter kernel, which makes it colorless. One suggested + * set of weights is + * + * { + * [0x10, 0x50, 0x60, 0x50, 0x10] , + * } + * + * where `a' has value 0x30 and `b' value 0x20. The weights in filter + * may have a sum larger than 0x100, which increases coloration slightly + * but also improves contrast. + */ + + + /**************************************************************************** + * + * @enum: + * 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_LcdFilter_ + { + 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 ); + + + /************************************************************************** + * + * @func: + * FT_Library_SetLcdFilterWeights + * + * @description: + * Use this function to override the filter weights selected by + * @FT_Library_SetLcdFilter. By default, FreeType uses the quintuple + * (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10, + * 0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and + * FT_LCD_FILTER_LEGACY. + * + * @input: + * library :: + * A handle to the target library instance. + * + * weights :: + * A pointer to an array; the function copies the first five bytes and + * uses them to specify the filter weights. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * 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. + * + * This function must be called after @FT_Library_SetLcdFilter to have + * any effect. + * + * @since: + * 2.4.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilterWeights( FT_Library library, + unsigned char *weights ); + + /* */ + + +FT_END_HEADER + +#endif /* __FT_LCD_FILTER_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftlist.h b/drivers/freetype/include/freetype/ftlist.h new file mode 100644 index 0000000000..bb6f7f119d --- /dev/null +++ b/drivers/freetype/include/freetype/ftlist.h @@ -0,0 +1,277 @@ +/***************************************************************************/ +/* */ +/* ftlist.h */ +/* */ +/* Generic list support for FreeType (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2007, 2010 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file implements functions relative to list processing. Its */ + /* data structures are defined in `freetype.h'. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTLIST_H__ +#define __FTLIST_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /* <Title> */ + /* List Processing */ + /* */ + /* <Abstract> */ + /* Simple management of lists. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to list */ + /* processing using doubly-linked nodes. */ + /* */ + /* <Order> */ + /* FT_List */ + /* FT_ListNode */ + /* FT_ListRec */ + /* FT_ListNodeRec */ + /* */ + /* FT_List_Add */ + /* FT_List_Insert */ + /* FT_List_Find */ + /* FT_List_Remove */ + /* FT_List_Up */ + /* FT_List_Iterate */ + /* FT_List_Iterator */ + /* FT_List_Finalize */ + /* FT_List_Destructor */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Find */ + /* */ + /* <Description> */ + /* Find the list node for a given listed object. */ + /* */ + /* <Input> */ + /* list :: A pointer to the parent list. */ + /* data :: The address of the listed object. */ + /* */ + /* <Return> */ + /* List node. NULL if it wasn't found. */ + /* */ + FT_EXPORT( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Add */ + /* */ + /* <Description> */ + /* Append an element to the end of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to append. */ + /* */ + FT_EXPORT( void ) + FT_List_Add( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Insert */ + /* */ + /* <Description> */ + /* Insert an element at the head of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to parent list. */ + /* node :: The node to insert. */ + /* */ + FT_EXPORT( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Remove */ + /* */ + /* <Description> */ + /* Remove a node from a list. This function doesn't check whether */ + /* the node is in the list! */ + /* */ + /* <Input> */ + /* node :: The node to remove. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* */ + FT_EXPORT( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Up */ + /* */ + /* <Description> */ + /* Move a node to the head/top of a list. Used to maintain LRU */ + /* lists. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to move. */ + /* */ + FT_EXPORT( void ) + FT_List_Up( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Iterator */ + /* */ + /* <Description> */ + /* An FT_List iterator function which is called during a list parse */ + /* by @FT_List_Iterate. */ + /* */ + /* <Input> */ + /* node :: The current iteration list node. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. */ + /* Can be used to point to the iteration's state. */ + /* */ + typedef FT_Error + (*FT_List_Iterator)( FT_ListNode node, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Iterate */ + /* */ + /* <Description> */ + /* Parse a list and calls a given iterator function on each element. */ + /* Note that parsing is stopped as soon as one of the iterator calls */ + /* returns a non-zero value. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* iterator :: An iterator function, called on each node of the list. */ + /* user :: A user-supplied field which is passed as the second */ + /* argument to the iterator. */ + /* */ + /* <Return> */ + /* The result (a FreeType error code) of the last iterator call. */ + /* */ + FT_EXPORT( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Destructor */ + /* */ + /* <Description> */ + /* An @FT_List iterator function which is called during a list */ + /* finalization by @FT_List_Finalize to destroy all elements in a */ + /* given list. */ + /* */ + /* <Input> */ + /* system :: The current system object. */ + /* */ + /* data :: The current object to destroy. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. It can */ + /* be used to point to the iteration's state. */ + /* */ + typedef void + (*FT_List_Destructor)( FT_Memory memory, + void* data, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Finalize */ + /* */ + /* <Description> */ + /* Destroy all elements in the list as well as the list itself. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* */ + /* destroy :: A list destructor that will be applied to each element */ + /* of the list. */ + /* */ + /* memory :: The current memory object which handles deallocation. */ + /* */ + /* user :: A user-supplied field which is passed as the last */ + /* argument to the destructor. */ + /* */ + /* <Note> */ + /* This function expects that all nodes added by @FT_List_Add or */ + /* @FT_List_Insert have been dynamically allocated. */ + /* */ + FT_EXPORT( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTLIST_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftlzw.h b/drivers/freetype/include/freetype/ftlzw.h new file mode 100644 index 0000000000..00d40169a7 --- /dev/null +++ b/drivers/freetype/include/freetype/ftlzw.h @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* ftlzw.h */ +/* */ +/* LZW-compressed stream support. */ +/* */ +/* Copyright 2004, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTLZW_H__ +#define __FTLZW_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* lzw */ + /* */ + /* <Title> */ + /* LZW Streams */ + /* */ + /* <Abstract> */ + /* Using LZW-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of LZW-specific functions. */ + /* */ + /*************************************************************************/ + + /************************************************************************ + * + * @function: + * FT_Stream_OpenLZW + * + * @description: + * Open a new stream to parse LZW-compressed font files. This is + * mainly used to support the compressed `*.pcf.Z' fonts that come + * with XFree86. + * + * @input: + * stream :: The target embedding stream. + * + * source :: The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream + * + * In certain builds of the library, LZW compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a LZW stream from it + * and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with LZW support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTLZW_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftmac.h b/drivers/freetype/include/freetype/ftmac.h new file mode 100644 index 0000000000..ab5bab5170 --- /dev/null +++ b/drivers/freetype/include/freetype/ftmac.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* ftmac.h */ +/* */ +/* Additional Mac-specific API. */ +/* */ +/* Copyright 1996-2001, 2004, 2006, 2007 by */ +/* Just van Rossum, 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. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* NOTE: Include this file after <freetype/freetype.h> and after any */ +/* Mac-specific headers (because this header uses Mac types such as */ +/* Handle, FSSpec, FSRef, etc.) */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMAC_H__ +#define __FTMAC_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + +/* gcc-3.4.1 and later can warn about functions tagged as deprecated */ +#ifndef FT_DEPRECATED_ATTRIBUTE +#if defined(__GNUC__) && \ + ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) +#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#else +#define FT_DEPRECATED_ATTRIBUTE +#endif +#endif + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* mac_specific */ + /* */ + /* <Title> */ + /* Mac Specific Interface */ + /* */ + /* <Abstract> */ + /* Only available on the Macintosh. */ + /* */ + /* <Description> */ + /* The following definitions are only available if FreeType is */ + /* compiled on a Macintosh. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FOND */ + /* */ + /* <Description> */ + /* Create a new face object from a FOND resource. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* fond :: A FOND resource. */ + /* */ + /* face_index :: Only supported for the -1 `sanity check' special */ + /* case. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Notes> */ + /* This function can be used to create @FT_Face objects from fonts */ + /* that are installed in the system as follows. */ + /* */ + /* { */ + /* fond = GetResource( 'FOND', fontName ); */ + /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font (e.g., Times New Roman */ + /* Bold). */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFilePath_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return a pathname of the disk file and face index for given font */ + /* name which is handled by ATS framework. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* path :: Buffer to store pathname of the file. For passing */ + /* to @FT_New_Face. The client must allocate this */ + /* buffer before calling this function. */ + /* */ + /* maxPathSize :: Lengths of the buffer `path' that client allocated. */ + /* */ + /* face_index :: Index of the face. For passing to @FT_New_Face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, + UInt8* path, + UInt32 maxPathSize, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSSpec to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSSpec to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ + /* it accepts an FSSpec instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSRef */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSRef to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSRef to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ + /* it accepts an FSRef instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSRef( FT_Library library, + const FSRef *ref, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + /* */ + + +FT_END_HEADER + + +#endif /* __FTMAC_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftmm.h b/drivers/freetype/include/freetype/ftmm.h new file mode 100644 index 0000000000..3aefb9e4f2 --- /dev/null +++ b/drivers/freetype/include/freetype/ftmm.h @@ -0,0 +1,378 @@ +/***************************************************************************/ +/* */ +/* ftmm.h */ +/* */ +/* FreeType Multiple Master font interface (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009 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 __FTMM_H__ +#define __FTMM_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* multiple_masters */ + /* */ + /* <Title> */ + /* Multiple Masters */ + /* */ + /* <Abstract> */ + /* How to manage Multiple Masters fonts. */ + /* */ + /* <Description> */ + /* The following types and functions are used to manage Multiple */ + /* Master fonts, i.e., the selection of specific design instances by */ + /* setting design axis coordinates. */ + /* */ + /* George Williams has extended this interface to make it work with */ + /* both Type~1 Multiple Masters fonts and GX distortable (var) */ + /* fonts. Some of these routines only work with MM fonts, others */ + /* will work with both types. They are similar enough that a */ + /* consistent interface makes sense. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters fonts. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + typedef struct FT_MM_Axis_ + { + FT_String* name; + FT_Long minimum; + FT_Long maximum; + + } FT_MM_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Multi_Master */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* font. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* num_axis :: Number of axes. Cannot exceed~4. */ + /* */ + /* num_designs :: Number of designs; should be normally 2^num_axis */ + /* even though the Type~1 specification strangely */ + /* allows for intermediate designs to be present. This */ + /* number cannot exceed~16. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* */ + typedef struct FT_Multi_Master_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_MM_Axis axis[T1_MAX_MM_AXIS]; + + } FT_Multi_Master; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters and GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* Not always meaningful for GX. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* def :: The axis's default design coordinate. */ + /* FreeType computes meaningful default values for MM; it */ + /* is then an integer value, not in 16.16 format. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + /* tag :: The axis's tag (the GX equivalent to `name'). */ + /* FreeType provides default values for MM if possible. */ + /* */ + /* strid :: The entry in `name' table (another GX version of */ + /* `name'). */ + /* Not meaningful for MM. */ + /* */ + typedef struct FT_Var_Axis_ + { + FT_String* name; + + FT_Fixed minimum; + FT_Fixed def; + FT_Fixed maximum; + + FT_ULong tag; + FT_UInt strid; + + } FT_Var_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Named_Style */ + /* */ + /* <Description> */ + /* A simple structure used to model a named style in a GX var font. */ + /* */ + /* This structure can't be used for MM fonts. */ + /* */ + /* <Fields> */ + /* coords :: The design coordinates for this style. */ + /* This is an array with one entry for each axis. */ + /* */ + /* strid :: The entry in `name' table identifying this style. */ + /* */ + typedef struct FT_Var_Named_Style_ + { + FT_Fixed* coords; + FT_UInt strid; + + } FT_Var_Named_Style; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Var */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* or GX var distortable font. */ + /* */ + /* Some fields are specific to one format and not to the other. */ + /* */ + /* <Fields> */ + /* num_axis :: The number of axes. The maximum value is~4 for */ + /* MM; no limit in GX. */ + /* */ + /* num_designs :: The number of designs; should be normally */ + /* 2^num_axis for MM fonts. Not meaningful for GX */ + /* (where every glyph could have a different */ + /* number of designs). */ + /* */ + /* num_namedstyles :: The number of named styles; only meaningful for */ + /* GX which allows certain design coordinates to */ + /* have a string ID (in the `name' table) */ + /* associated with them. The font can tell the */ + /* user that, for example, Weight=1.5 is `Bold'. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* GX fonts contain slightly more data than MM. */ + /* */ + /* namedstyles :: A table of named styles. */ + /* Only meaningful with GX. */ + /* */ + typedef struct FT_MM_Var_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_UInt num_namedstyles; + FT_Var_Axis* axis; + FT_Var_Named_Style* namedstyle; + + } FT_MM_Var; + + + /* */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Multi_Master */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master descriptor of a given font. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_MM_Var */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master/GX var descriptor of a given font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters/GX var descriptor. */ + /* Allocates a data structure, which the user must free */ + /* (a single call to FT_FREE will do it). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Var( FT_Face face, + FT_MM_Var* *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters fonts, choose an interpolated font design */ + /* through design coordinates. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Master or GX Var fonts, choose an interpolated font */ + /* design through design coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Blend_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters and GX var fonts, choose an interpolated font */ + /* design through normalized blend coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: The design coordinates array (each element must be */ + /* between 0 and 1.0). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Blend_Coordinates */ + /* */ + /* <Description> */ + /* This is another name of @FT_Set_MM_Blend_Coordinates. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTMM_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftmodapi.h b/drivers/freetype/include/freetype/ftmodapi.h new file mode 100644 index 0000000000..8abffb558f --- /dev/null +++ b/drivers/freetype/include/freetype/ftmodapi.h @@ -0,0 +1,641 @@ +/***************************************************************************/ +/* */ +/* ftmodapi.h */ +/* */ +/* FreeType modules public interface (specification). */ +/* */ +/* Copyright 1996-2003, 2006, 2008-2010, 2012, 2013 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 __FTMODAPI_H__ +#define __FTMODAPI_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /* <Title> */ + /* Module Management */ + /* */ + /* <Abstract> */ + /* How to add, upgrade, remove, and control modules from FreeType. */ + /* */ + /* <Description> */ + /* The definitions below are used to manage modules within FreeType. */ + /* Modules can be added, upgraded, and removed at runtime. */ + /* Additionally, some module properties can be controlled also. */ + /* */ + /* Here is a list of possible values of the `module_name' field in */ + /* the @FT_Module_Class structure. */ + /* */ + /* { */ + /* autofitter */ + /* bdf */ + /* cff */ + /* gxvalid */ + /* otvalid */ + /* pcf */ + /* pfr */ + /* psaux */ + /* pshinter */ + /* psnames */ + /* raster1, raster5 */ + /* sfnt */ + /* smooth, smooth-lcd, smooth-lcdv */ + /* truetype */ + /* type1 */ + /* type42 */ + /* t1cid */ + /* winfonts */ + /* } */ + /* */ + /* Note that the FreeType Cache sub-system is not a FreeType module. */ + /* */ + /*************************************************************************/ + + + /* module bit flags */ +#define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ +#define FT_MODULE_RENDERER 2 /* this module is a renderer */ +#define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ +#define FT_MODULE_STYLER 8 /* this module is a styler */ + +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ + /* scalable fonts */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ + /* support vector outlines */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ + /* own hinter */ + + + /* deprecated values */ +#define ft_module_font_driver FT_MODULE_FONT_DRIVER +#define ft_module_renderer FT_MODULE_RENDERER +#define ft_module_hinter FT_MODULE_HINTER +#define ft_module_styler FT_MODULE_STYLER + +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER + + + typedef FT_Pointer FT_Module_Interface; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Constructor */ + /* */ + /* <Description> */ + /* A function used to initialize (not create) a new module object. */ + /* */ + /* <Input> */ + /* module :: The module to initialize. */ + /* */ + typedef FT_Error + (*FT_Module_Constructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destructor */ + /* */ + /* <Description> */ + /* A function used to finalize (not destroy) a given module object. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + typedef void + (*FT_Module_Destructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Requester */ + /* */ + /* <Description> */ + /* A function used to query a given module for a specific interface. */ + /* */ + /* <Input> */ + /* module :: The module to be searched. */ + /* */ + /* name :: The name of the interface in the module. */ + /* */ + typedef FT_Module_Interface + (*FT_Module_Requester)( FT_Module module, + const char* name ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Module_Class */ + /* */ + /* <Description> */ + /* The module class descriptor. */ + /* */ + /* <Fields> */ + /* module_flags :: Bit flags describing the module. */ + /* */ + /* module_size :: The size of one module object/instance in */ + /* bytes. */ + /* */ + /* module_name :: The name of the module. */ + /* */ + /* module_version :: The version, as a 16.16 fixed number */ + /* (major.minor). */ + /* */ + /* module_requires :: The version of FreeType this module requires, */ + /* as a 16.16 fixed number (major.minor). Starts */ + /* at version 2.0, i.e., 0x20000. */ + /* */ + /* module_init :: The initializing function. */ + /* */ + /* module_done :: The finalizing function. */ + /* */ + /* get_interface :: The interface requesting function. */ + /* */ + typedef struct FT_Module_Class_ + { + FT_ULong module_flags; + FT_Long module_size; + const FT_String* module_name; + FT_Fixed module_version; + FT_Fixed module_requires; + + const void* module_interface; + + FT_Module_Constructor module_init; + FT_Module_Destructor module_done; + FT_Module_Requester get_interface; + + } FT_Module_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Module */ + /* */ + /* <Description> */ + /* Add a new module to a given library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* clazz :: A pointer to class descriptor for the module. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module */ + /* */ + /* <Description> */ + /* Find a module by its name. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module handle. 0~if none was found. */ + /* */ + /* <Note> */ + /* FreeType's internal modules aren't documented very well, and you */ + /* should look up the source code for details. */ + /* */ + FT_EXPORT( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Remove_Module */ + /* */ + /* <Description> */ + /* Remove a given module from a library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to a library object. */ + /* */ + /* <Input> */ + /* module :: A handle to a module object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The module object is destroyed by the function in case of success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ); + + + /********************************************************************** + * + * @function: + * FT_Property_Set + * + * @description: + * Set a property for a given module. + * + * @input: + * library :: + * A handle to the library the module is part of. + * + * module_name :: + * The module name. + * + * property_name :: + * The property name. Properties are described in the `Synopsis' + * subsection of the module's documentation. + * + * Note that only a few modules have properties. + * + * value :: + * A generic pointer to a variable or structure which gives the new + * value of the property. The exact definition of `value' is + * dependent on the property; see the `Synopsis' subsection of the + * module's documentation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `module_name' isn't a valid module name, or `property_name' + * doesn't specify a valid property, or if `value' doesn't represent a + * valid value for the given property, an error is returned. + * + * The following example sets property `bar' (a simple integer) in + * module `foo' to value~1. + * + * { + * FT_UInt bar; + * + * + * bar = 1; + * FT_Property_Set( library, "foo", "bar", &bar ); + * } + * + * Note that the FreeType Cache sub-system doesn't recognize module + * property changes. To avoid glyph lookup confusion within the cache + * you should call @FTC_Manager_Reset to completely flush the cache if + * a module property gets changed after @FTC_Manager_New has been + * called. + * + * It is not possible to set properties of the FreeType Cache + * sub-system itself with FT_Property_Set; use @FTC_Property_Set + * instead. + * + * @since: + * 2.4.11 + * + */ + FT_EXPORT( FT_Error ) + FT_Property_Set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + const void* value ); + + + /********************************************************************** + * + * @function: + * FT_Property_Get + * + * @description: + * Get a module's property value. + * + * @input: + * library :: + * A handle to the library the module is part of. + * + * module_name :: + * The module name. + * + * property_name :: + * The property name. Properties are described in the `Synopsis' + * subsection of the module's documentation. + * + * @inout: + * value :: + * A generic pointer to a variable or structure which gives the + * value of the property. The exact definition of `value' is + * dependent on the property; see the `Synopsis' subsection of the + * module's documentation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `module_name' isn't a valid module name, or `property_name' + * doesn't specify a valid property, or if `value' doesn't represent a + * valid value for the given property, an error is returned. + * + * The following example gets property `baz' (a range) in module `foo'. + * + * { + * typedef range_ + * { + * FT_Int32 min; + * FT_Int32 max; + * + * } range; + * + * range baz; + * + * + * FT_Property_Get( library, "foo", "baz", &baz ); + * } + * + * It is not possible to retrieve properties of the FreeType Cache + * sub-system with FT_Property_Get; use @FTC_Property_Get instead. + * + * @since: + * 2.4.11 + * + */ + FT_EXPORT( FT_Error ) + FT_Property_Get( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + void* value ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Reference_Library */ + /* */ + /* <Description> */ + /* A counter gets initialized to~1 at the time an @FT_Library */ + /* structure is created. This function increments the counter. */ + /* @FT_Done_Library then only destroys a library if the counter is~1, */ + /* otherwise it simply decrements the counter. */ + /* */ + /* This function helps in managing life-cycles of structures which */ + /* reference @FT_Library objects. */ + /* */ + /* <Input> */ + /* library :: A handle to a target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.4.2 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Reference_Library( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Library */ + /* */ + /* <Description> */ + /* This function is used to create a new FreeType library instance */ + /* from a given memory object. It is thus possible to use libraries */ + /* with distinct memory allocators within the same program. */ + /* */ + /* Normally, you would call this function (followed by a call to */ + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ + /* instead of @FT_Init_FreeType to initialize the FreeType library. */ + /* */ + /* Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a */ + /* library instance. */ + /* */ + /* <Input> */ + /* memory :: A handle to the original memory object. */ + /* */ + /* <Output> */ + /* alibrary :: A pointer to handle of a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Library */ + /* */ + /* <Description> */ + /* Discard a given library object. This closes all drivers and */ + /* discards all resource objects. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Library( FT_Library library ); + +/* */ + + typedef void + (*FT_DebugHook_Func)( void* arg ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Debug_Hook */ + /* */ + /* <Description> */ + /* Set a debug hook function for debugging the interpreter of a font */ + /* format. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* hook_index :: The index of the debug hook. You should use the */ + /* values defined in `ftobjs.h', e.g., */ + /* `FT_DEBUG_HOOK_TRUETYPE'. */ + /* */ + /* debug_hook :: The function used to debug the interpreter. */ + /* */ + /* <Note> */ + /* Currently, four debug hook slots are available, but only two (for */ + /* the TrueType and the Type~1 interpreter) are defined. */ + /* */ + /* Since the internal headers of FreeType are no longer installed, */ + /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ + /* This is a bug and will be fixed in a forthcoming release. */ + /* */ + FT_EXPORT( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Default_Modules */ + /* */ + /* <Description> */ + /* Add the set of default drivers to a given library object. */ + /* This is only useful when you create a library object with */ + /* @FT_New_Library (usually to plug a custom memory manager). */ + /* */ + /* <InOut> */ + /* library :: A handle to a new library object. */ + /* */ + FT_EXPORT( void ) + FT_Add_Default_Modules( FT_Library library ); + + + + /************************************************************************** + * + * @section: + * truetype_engine + * + * @title: + * The TrueType Engine + * + * @abstract: + * TrueType bytecode support. + * + * @description: + * This section contains a function used to query the level of TrueType + * bytecode support compiled in this version of the library. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_TrueTypeEngineType + * + * @description: + * A list of values describing which kind of TrueType bytecode + * engine is implemented in a given FT_Library instance. It is used + * by the @FT_Get_TrueType_Engine_Type function. + * + * @values: + * FT_TRUETYPE_ENGINE_TYPE_NONE :: + * The library doesn't implement any kind of bytecode interpreter. + * + * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: + * The library implements a bytecode interpreter that doesn't + * support the patented operations of the TrueType virtual machine. + * + * Its main use is to load certain Asian fonts which position and + * scale glyph components with bytecode instructions. It produces + * bad output for most other fonts. + * + * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: + * The library implements a bytecode interpreter that covers + * the full instruction set of the TrueType virtual machine (this + * was governed by patents until May 2010, hence the name). + * + * @since: + * 2.2 + * + */ + typedef enum FT_TrueTypeEngineType_ + { + FT_TRUETYPE_ENGINE_TYPE_NONE = 0, + FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, + FT_TRUETYPE_ENGINE_TYPE_PATENTED + + } FT_TrueTypeEngineType; + + + /************************************************************************** + * + * @func: + * FT_Get_TrueType_Engine_Type + * + * @description: + * Return an @FT_TrueTypeEngineType value to indicate which level of + * the TrueType virtual machine a given library instance supports. + * + * @input: + * library :: + * A library instance. + * + * @return: + * A value indicating which level is supported. + * + * @since: + * 2.2 + * + */ + FT_EXPORT( FT_TrueTypeEngineType ) + FT_Get_TrueType_Engine_Type( FT_Library library ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTMODAPI_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftmoderr.h b/drivers/freetype/include/freetype/ftmoderr.h new file mode 100644 index 0000000000..5a27db151a --- /dev/null +++ b/drivers/freetype/include/freetype/ftmoderr.h @@ -0,0 +1,194 @@ +/***************************************************************************/ +/* */ +/* ftmoderr.h */ +/* */ +/* FreeType module error offsets (specification). */ +/* */ +/* Copyright 2001-2005, 2010, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the FreeType module error codes. */ + /* */ + /* If the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in `ftoption.h' is */ + /* set, the lower byte of an error value identifies the error code as */ + /* usual. In addition, the higher byte identifies the module. For */ + /* example, the error `FT_Err_Invalid_File_Format' has value 0x0003, the */ + /* error `TT_Err_Invalid_File_Format' has value 0x1303, the error */ + /* `T1_Err_Invalid_File_Format' has value 0x1403, etc. */ + /* */ + /* Note that `FT_Err_Ok', `TT_Err_Ok', etc. are always equal to zero, */ + /* including the high byte. */ + /* */ + /* If FT_CONFIG_OPTION_USE_MODULE_ERRORS isn't set, the higher byte of */ + /* an error value is set to zero. */ + /* */ + /* To hide the various `XXX_Err_' prefixes in the source code, FreeType */ + /* provides some macros in `fttypes.h'. */ + /* */ + /* FT_ERR( err ) */ + /* Add current error module prefix (as defined with the */ + /* `FT_ERR_PREFIX' macro) to `err'. For example, in the BDF module */ + /* the line */ + /* */ + /* error = FT_ERR( Invalid_Outline ); */ + /* */ + /* expands to */ + /* */ + /* error = BDF_Err_Invalid_Outline; */ + /* */ + /* For simplicity, you can always use `FT_Err_Ok' directly instead */ + /* of `FT_ERR( Ok )'. */ + /* */ + /* FT_ERR_EQ( errcode, err ) */ + /* FT_ERR_NEQ( errcode, err ) */ + /* Compare error code `errcode' with the error `err' for equality */ + /* and inequality, respectively. Example: */ + /* */ + /* if ( FT_ERR_EQ( error, Invalid_Outline ) ) */ + /* ... */ + /* */ + /* Using this macro you don't have to think about error prefixes. */ + /* Of course, if module errors are not active, the above example is */ + /* the same as */ + /* */ + /* if ( error == FT_Err_Invalid_Outline ) */ + /* ... */ + /* */ + /* FT_ERROR_BASE( errcode ) */ + /* FT_ERROR_MODULE( errcode ) */ + /* Get base error and module error code, respectively. */ + /* */ + /* */ + /* It can also be used to create a module error message table easily */ + /* with something like */ + /* */ + /* { */ + /* #undef __FTMODERR_H__ */ + /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ + /* #define FT_MODERR_START_LIST { */ + /* #define FT_MODERR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int mod_err_offset; */ + /* const char* mod_err_msg */ + /* } ft_mod_errors[] = */ + /* */ + /* #include FT_MODULE_ERRORS_H */ + /* } */ + /* */ + /*************************************************************************/ + + +#ifndef __FTMODERR_H__ +#define __FTMODERR_H__ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#ifndef FT_MODERRDEF + +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = v, +#else +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, +#endif + +#define FT_MODERR_START_LIST enum { +#define FT_MODERR_END_LIST FT_Mod_Err_Max }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_MODERRDEF */ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST MODULE ERROR BASES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_MODERR_START_LIST + FT_MODERR_START_LIST +#endif + + + FT_MODERRDEF( Base, 0x000, "base module" ) + FT_MODERRDEF( Autofit, 0x100, "autofitter module" ) + FT_MODERRDEF( BDF, 0x200, "BDF module" ) + FT_MODERRDEF( Bzip2, 0x300, "Bzip2 module" ) + FT_MODERRDEF( Cache, 0x400, "cache module" ) + FT_MODERRDEF( CFF, 0x500, "CFF module" ) + FT_MODERRDEF( CID, 0x600, "CID module" ) + FT_MODERRDEF( Gzip, 0x700, "Gzip module" ) + FT_MODERRDEF( LZW, 0x800, "LZW module" ) + FT_MODERRDEF( OTvalid, 0x900, "OpenType validation module" ) + FT_MODERRDEF( PCF, 0xA00, "PCF module" ) + FT_MODERRDEF( PFR, 0xB00, "PFR module" ) + FT_MODERRDEF( PSaux, 0xC00, "PS auxiliary module" ) + FT_MODERRDEF( PShinter, 0xD00, "PS hinter module" ) + FT_MODERRDEF( PSnames, 0xE00, "PS names module" ) + FT_MODERRDEF( Raster, 0xF00, "raster module" ) + FT_MODERRDEF( SFNT, 0x1000, "SFNT module" ) + FT_MODERRDEF( Smooth, 0x1100, "smooth raster module" ) + FT_MODERRDEF( TrueType, 0x1200, "TrueType module" ) + FT_MODERRDEF( Type1, 0x1300, "Type 1 module" ) + FT_MODERRDEF( Type42, 0x1400, "Type 42 module" ) + FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" ) + FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" ) + + +#ifdef FT_MODERR_END_LIST + FT_MODERR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_MODERR_START_LIST +#undef FT_MODERR_END_LIST +#undef FT_MODERRDEF +#undef FT_NEED_EXTERN_C + + +#endif /* __FTMODERR_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftotval.h b/drivers/freetype/include/freetype/ftotval.h new file mode 100644 index 0000000000..027f2e8865 --- /dev/null +++ b/drivers/freetype/include/freetype/ftotval.h @@ -0,0 +1,203 @@ +/***************************************************************************/ +/* */ +/* ftotval.h */ +/* */ +/* FreeType API for validating OpenType tables (specification). */ +/* */ +/* 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, */ +/* 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. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* */ +/* Warning: This module might be moved to a different library in the */ +/* future to avoid a tight dependency between FreeType and the */ +/* OpenType specification. */ +/* */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOTVAL_H__ +#define __FTOTVAL_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* ot_validation */ + /* */ + /* <Title> */ + /* OpenType Validation */ + /* */ + /* <Abstract> */ + /* An API to validate OpenType tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_OTXXX + * + * @description: + * A list of bit-field constants used with @FT_OpenType_Validate to + * indicate which OpenType tables should be validated. + * + * @values: + * FT_VALIDATE_BASE :: + * Validate BASE table. + * + * FT_VALIDATE_GDEF :: + * Validate GDEF table. + * + * FT_VALIDATE_GPOS :: + * Validate GPOS table. + * + * FT_VALIDATE_GSUB :: + * Validate GSUB table. + * + * FT_VALIDATE_JSTF :: + * Validate JSTF table. + * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * + * FT_VALIDATE_OT :: + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). + * + */ +#define FT_VALIDATE_BASE 0x0100 +#define FT_VALIDATE_GDEF 0x0200 +#define FT_VALIDATE_GPOS 0x0400 +#define FT_VALIDATE_GSUB 0x0800 +#define FT_VALIDATE_JSTF 0x1000 +#define FT_VALIDATE_MATH 0x2000 + +#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH + + /* */ + + /********************************************************************** + * + * @function: + * FT_OpenType_Validate + * + * @description: + * Validate various OpenType tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the tables to be validated. See + * @FT_VALIDATE_OTXXX for possible values. + * + * @output: + * BASE_table :: + * A pointer to the BASE table. + * + * GDEF_table :: + * A pointer to the GDEF table. + * + * GPOS_table :: + * A pointer to the GPOS table. + * + * GSUB_table :: + * A pointer to the GSUB table. + * + * JSTF_table :: + * A pointer to the JSTF table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with OpenType fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the five tables with + * @FT_OpenType_Free. A NULL value indicates that the table either + * doesn't exist in the font, or the application hasn't asked for + * validation. + */ + 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 *JSTF_table ); + + /* */ + + /********************************************************************** + * + * @function: + * FT_OpenType_Free + * + * @description: + * Free the buffer allocated by OpenType validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_OpenType_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_OpenType_Validate only. + */ + FT_EXPORT( void ) + FT_OpenType_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTOTVAL_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftoutln.h b/drivers/freetype/include/freetype/ftoutln.h new file mode 100644 index 0000000000..fd69f28292 --- /dev/null +++ b/drivers/freetype/include/freetype/ftoutln.h @@ -0,0 +1,560 @@ +/***************************************************************************/ +/* */ +/* ftoutln.h */ +/* */ +/* Support for the FT_Outline type used to store glyph shapes of */ +/* most scalable font formats (specification). */ +/* */ +/* Copyright 1996-2003, 2005-2012 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 __FTOUTLN_H__ +#define __FTOUTLN_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /* <Title> */ + /* Outline Processing */ + /* */ + /* <Abstract> */ + /* Functions to create, transform, and render vectorial glyph images. */ + /* */ + /* <Description> */ + /* This section contains routines used to create and destroy scalable */ + /* glyph images known as `outlines'. These can also be measured, */ + /* transformed, and converted into bitmaps and pixmaps. */ + /* */ + /* <Order> */ + /* FT_Outline */ + /* FT_OUTLINE_FLAGS */ + /* FT_Outline_New */ + /* FT_Outline_Done */ + /* FT_Outline_Copy */ + /* FT_Outline_Translate */ + /* FT_Outline_Transform */ + /* FT_Outline_Embolden */ + /* FT_Outline_EmboldenXY */ + /* FT_Outline_Reverse */ + /* FT_Outline_Check */ + /* */ + /* FT_Outline_Get_CBox */ + /* FT_Outline_Get_BBox */ + /* */ + /* FT_Outline_Get_Bitmap */ + /* FT_Outline_Render */ + /* */ + /* FT_Outline_Decompose */ + /* FT_Outline_Funcs */ + /* FT_Outline_MoveTo_Func */ + /* FT_Outline_LineTo_Func */ + /* FT_Outline_ConicTo_Func */ + /* FT_Outline_CubicTo_Func */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and Bézier arcs. This function also emits `move to' */ + /* operations to indicate the start of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e., function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* <InOut> */ + /* user :: A typeless pointer which is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_New */ + /* */ + /* <Description> */ + /* Create a new outline of a given size. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object from where the */ + /* outline is allocated. Note however that the new */ + /* outline will *not* necessarily be *freed*, when */ + /* destroying the library, by @FT_Done_FreeType. */ + /* */ + /* numPoints :: The maximum number of points within the outline. */ + /* Must be smaller than or equal to 0xFFFF (65535). */ + /* */ + /* numContours :: The maximum number of contours within the outline. */ + /* This value must be in the range 0 to `numPoints'. */ + /* */ + /* <Output> */ + /* anoutline :: A handle to the new outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' parameter is simply */ + /* to use the library's memory allocator. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Done */ + /* */ + /* <Description> */ + /* Destroy an outline created with @FT_Outline_New. */ + /* */ + /* <Input> */ + /* library :: A handle of the library object used to allocate the */ + /* outline. */ + /* */ + /* outline :: A pointer to the outline object to be discarded. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If the outline's `owner' field is not set, only the outline */ + /* descriptor will be released. */ + /* */ + /* The reason why this function takes an `library' parameter is */ + /* simply to use ft_mem_free(). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Check */ + /* */ + /* <Description> */ + /* Check the contents of an outline descriptor. */ + /* */ + /* <Input> */ + /* outline :: A handle to a source outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Check( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* which contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + /* <Note> */ + /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Translate */ + /* */ + /* <Description> */ + /* Apply a simple translation to the points of an outline. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* xOffset :: The horizontal offset. */ + /* */ + /* yOffset :: The vertical offset. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Translate( const FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Copy */ + /* */ + /* <Description> */ + /* Copy an outline into another one. Both objects must have the */ + /* same sizes (number of points & number of contours) when this */ + /* function is called. */ + /* */ + /* <Input> */ + /* source :: A handle to the source outline. */ + /* */ + /* <Output> */ + /* target :: A handle to the target outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Copy( const FT_Outline* source, + FT_Outline *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Transform */ + /* */ + /* <Description> */ + /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ + /* for applying rotations, slanting, flipping, etc. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation matrix. */ + /* */ + /* <Note> */ + /* You can use @FT_Outline_Translate if you need to translate the */ + /* outline's points. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Transform( const FT_Outline* outline, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Embolden */ + /* */ + /* <Description> */ + /* Embolden an outline. The new outline will be at most 4~times */ + /* `strength' pixels wider and higher. You may think of the left and */ + /* bottom borders as unchanged. */ + /* */ + /* Negative `strength' values to reduce the outline thickness are */ + /* possible also. */ + /* */ + /* <InOut> */ + /* outline :: A handle to the target outline. */ + /* */ + /* <Input> */ + /* strength :: How strong the glyph is emboldened. Expressed in */ + /* 26.6 pixel format. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The used algorithm to increase or decrease the thickness of the */ + /* glyph doesn't change the number of points; this means that certain */ + /* situations like acute angles or intersections are sometimes */ + /* handled incorrectly. */ + /* */ + /* If you need `better' metrics values you should call */ + /* @FT_Outline_Get_CBox or @FT_Outline_Get_BBox. */ + /* */ + /* Example call: */ + /* */ + /* { */ + /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ + /* if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE ) */ + /* FT_Outline_Embolden( &face->slot->outline, strength ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Embolden( FT_Outline* outline, + FT_Pos strength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_EmboldenXY */ + /* */ + /* <Description> */ + /* Embolden an outline. The new outline will be `xstrength' pixels */ + /* wider and `ystrength' pixels higher. Otherwise, it is similar to */ + /* @FT_Outline_Embolden, which uses the same strength in both */ + /* directions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_EmboldenXY( FT_Outline* outline, + FT_Pos xstrength, + FT_Pos ystrength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Reverse */ + /* */ + /* <Description> */ + /* Reverse the drawing direction of an outline. This is used to */ + /* ensure consistent fill conventions for mirrored glyphs. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Note> */ + /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ + /* the outline's `flags' field. */ + /* */ + /* It shouldn't be used by a normal client application, unless it */ + /* knows what it is doing. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Reverse( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_Bitmap */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap. The outline's image is simply */ + /* OR-ed to the target bitmap. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the target bitmap descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does NOT CREATE the bitmap, it only renders an */ + /* outline image within the one you pass to it! Consequently, the */ + /* various fields in `abitmap' should be set accordingly. */ + /* */ + /* It will use the raster corresponding to the default glyph format. */ + /* */ + /* The value of the `num_grays' field in `abitmap' is ignored. If */ + /* you select the gray-level rasterizer, and you want less than 256 */ + /* gray levels, you have to use @FT_Outline_Render directly. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + const FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Render */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap using the current scan-convert. */ + /* This function uses an @FT_Raster_Params structure as an argument, */ + /* allowing advanced features like direct composition, translucency, */ + /* etc. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* describe the rendering operation. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You should know what you are doing and how @FT_Raster_Params works */ + /* to use this function. */ + /* */ + /* The field `params.source' will be set to `outline' before the scan */ + /* converter is called, which means that the value you give to it is */ + /* actually ignored. */ + /* */ + /* The gray-level rasterizer always uses 256 gray levels. If you */ + /* want less gray levels, you have to provide your own span callback. */ + /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ + /* @FT_Raster_Params structure for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ); + + + /************************************************************************** + * + * @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 + * be filled, and counter-clockwise ones must be unfilled. + * + * FT_ORIENTATION_POSTSCRIPT :: + * According to the PostScript specification, counter-clockwise contours + * must be filled, and clockwise ones must be unfilled. + * + * FT_ORIENTATION_FILL_RIGHT :: + * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to + * remember that in TrueType, everything that is to the right of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_FILL_LEFT :: + * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to + * remember that in PostScript, everything that is to the left of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_NONE :: + * The orientation cannot be determined. That is, different parts of + * the glyph have different orientation. + * + */ + typedef enum FT_Orientation_ + { + FT_ORIENTATION_TRUETYPE = 0, + FT_ORIENTATION_POSTSCRIPT = 1, + FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, + FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT, + FT_ORIENTATION_NONE + + } FT_Orientation; + + + /************************************************************************** + * + * @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 + * the direction of each global horizontal and/or vertical extrema + * within the outline. + * + * Note that this will return @FT_ORIENTATION_TRUETYPE for empty + * outlines. + * + * @input: + * outline :: + * A handle to the source outline. + * + * @return: + * The orientation. + * + */ + FT_EXPORT( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTOUTLN_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/drivers/freetype/include/freetype/ftpfr.h b/drivers/freetype/include/freetype/ftpfr.h new file mode 100644 index 0000000000..0b7b7d427c --- /dev/null +++ b/drivers/freetype/include/freetype/ftpfr.h @@ -0,0 +1,172 @@ +/***************************************************************************/ +/* */ +/* ftpfr.h */ +/* */ +/* FreeType API for accessing PFR-specific data (specification only). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2008, 2009 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 __FTPFR_H__ +#define __FTPFR_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* pfr_fonts */ + /* */ + /* <Title> */ + /* PFR Fonts */ + /* */ + /* <Abstract> */ + /* PFR/TrueDoc specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of PFR-specific functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Metrics + * + * @description: + * Return the outline and metrics resolutions of a given PFR face. + * + * @input: + * face :: Handle to the input face. It can be a non-PFR face. + * + * @output: + * aoutline_resolution :: + * Outline resolution. This is equivalent to `face->units_per_EM' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_resolution :: + * Metrics resolution. This is equivalent to `outline_resolution' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_x_scale :: + * A 16.16 fixed-point number used to scale distance expressed + * in metrics units to device sub-pixels. This is equivalent to + * `face->size->x_scale', but for metrics only. Optional (parameter + * can be NULL). + * + * ametrics_y_scale :: + * Same as `ametrics_x_scale' but for the vertical direction. + * optional (parameter can be NULL). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If the input face is not a PFR, this function will return an error. + * However, in all cases, it will return valid values. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Kerning + * + * @description: + * Return the kerning pair corresponding to two glyphs in a PFR face. + * The distance is expressed in metrics units, unlike the result of + * @FT_Get_Kerning. + * + * @input: + * face :: A handle to the input face. + * + * left :: Index of the left glyph. + * + * right :: Index of the right glyph. + * + * @output: + * avector :: A kerning vector. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function always return distances in original PFR metrics + * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED + * mode, which always returns distances converted to outline units. + * + * You can use the value of the `x_scale' and `y_scale' parameters + * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Advance + * + * @description: + * Return a given glyph advance, expressed in original metrics units, + * from a PFR font. + * + * @input: + * face :: A handle to the input face. + * + * gindex :: The glyph index. + * + * @output: + * aadvance :: The glyph advance in metrics units. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics + * to convert the advance to device sub-pixels (i.e., 1/64th of pixels). + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTPFR_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftrender.h b/drivers/freetype/include/freetype/ftrender.h new file mode 100644 index 0000000000..dd0229b815 --- /dev/null +++ b/drivers/freetype/include/freetype/ftrender.h @@ -0,0 +1,238 @@ +/***************************************************************************/ +/* */ +/* ftrender.h */ +/* */ +/* FreeType renderer modules public interface (specification). */ +/* */ +/* Copyright 1996-2001, 2005, 2006, 2010 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 __FTRENDER_H__ +#define __FTRENDER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + + /* create a new glyph object */ + typedef FT_Error + (*FT_Glyph_InitFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + + /* destroys a given glyph object */ + typedef void + (*FT_Glyph_DoneFunc)( FT_Glyph glyph ); + + typedef void + (*FT_Glyph_TransformFunc)( FT_Glyph glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + typedef void + (*FT_Glyph_GetBBoxFunc)( FT_Glyph glyph, + FT_BBox* abbox ); + + typedef FT_Error + (*FT_Glyph_CopyFunc)( FT_Glyph source, + FT_Glyph target ); + + typedef FT_Error + (*FT_Glyph_PrepareFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + +/* deprecated */ +#define FT_Glyph_Init_Func FT_Glyph_InitFunc +#define FT_Glyph_Done_Func FT_Glyph_DoneFunc +#define FT_Glyph_Transform_Func FT_Glyph_TransformFunc +#define FT_Glyph_BBox_Func FT_Glyph_GetBBoxFunc +#define FT_Glyph_Copy_Func FT_Glyph_CopyFunc +#define FT_Glyph_Prepare_Func FT_Glyph_PrepareFunc + + + struct FT_Glyph_Class_ + { + FT_Long glyph_size; + FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; + FT_Glyph_DoneFunc glyph_done; + FT_Glyph_CopyFunc glyph_copy; + FT_Glyph_TransformFunc glyph_transform; + FT_Glyph_GetBBoxFunc glyph_bbox; + FT_Glyph_PrepareFunc glyph_prepare; + }; + + + typedef FT_Error + (*FT_Renderer_RenderFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_UInt mode, + const FT_Vector* origin ); + + typedef FT_Error + (*FT_Renderer_TransformFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + + typedef void + (*FT_Renderer_GetCBoxFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_BBox* cbox ); + + + typedef FT_Error + (*FT_Renderer_SetModeFunc)( FT_Renderer renderer, + FT_ULong mode_tag, + FT_Pointer mode_ptr ); + +/* deprecated identifiers */ +#define FTRenderer_render FT_Renderer_RenderFunc +#define FTRenderer_transform FT_Renderer_TransformFunc +#define FTRenderer_getCBox FT_Renderer_GetCBoxFunc +#define FTRenderer_setMode FT_Renderer_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Renderer_Class */ + /* */ + /* <Description> */ + /* The renderer module class descriptor. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Module_Class fields. */ + /* */ + /* glyph_format :: The glyph image format this renderer handles. */ + /* */ + /* render_glyph :: A method used to render the image that is in a */ + /* given glyph slot into a bitmap. */ + /* */ + /* transform_glyph :: A method used to transform the image that is in */ + /* a given glyph slot. */ + /* */ + /* get_glyph_cbox :: A method used to access the glyph's cbox. */ + /* */ + /* set_mode :: A method used to pass additional parameters. */ + /* */ + /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to its raster's class. */ + /* */ + typedef struct FT_Renderer_Class_ + { + FT_Module_Class root; + + FT_Glyph_Format glyph_format; + + FT_Renderer_RenderFunc render_glyph; + FT_Renderer_TransformFunc transform_glyph; + FT_Renderer_GetCBoxFunc get_glyph_cbox; + FT_Renderer_SetModeFunc set_mode; + + FT_Raster_Funcs* raster_class; + + } FT_Renderer_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Renderer */ + /* */ + /* <Description> */ + /* Retrieve the current renderer for a given glyph format. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* format :: The glyph format. */ + /* */ + /* <Return> */ + /* A renderer handle. 0~if none found. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + /* To add a new renderer, simply use @FT_Add_Module. To retrieve a */ + /* renderer by its name, use @FT_Get_Module. */ + /* */ + FT_EXPORT( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Renderer */ + /* */ + /* <Description> */ + /* Set the current renderer to use, and set additional mode. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* renderer :: A handle to the renderer object. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* parameters :: Additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case of success, the renderer will be used to convert glyph */ + /* images in the renderer's known format into bitmaps. */ + /* */ + /* This doesn't change the current renderer for other formats. */ + /* */ + /* Currently, only the B/W renderer, if compiled with */ + /* FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels */ + /* anti-aliasing mode; this option must be set directly in */ + /* `ftraster.c' and is undefined by default) accepts a single tag */ + /* `pal5' to set its gray palette as a character string with */ + /* 5~elements. Consequently, the third and fourth argument are zero */ + /* normally. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTRENDER_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftsizes.h b/drivers/freetype/include/freetype/ftsizes.h new file mode 100644 index 0000000000..3e548cc39f --- /dev/null +++ b/drivers/freetype/include/freetype/ftsizes.h @@ -0,0 +1,159 @@ +/***************************************************************************/ +/* */ +/* ftsizes.h */ +/* */ +/* FreeType size objects management (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Typical application would normally not need to use these functions. */ + /* However, they have been placed in a public API for the rare cases */ + /* where they are needed. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSIZES_H__ +#define __FTSIZES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sizes_management */ + /* */ + /* <Title> */ + /* Size Management */ + /* */ + /* <Abstract> */ + /* Managing multiple sizes per face. */ + /* */ + /* <Description> */ + /* When creating a new face object (e.g., with @FT_New_Face), an */ + /* @FT_Size object is automatically created and used to store all */ + /* pixel-size dependent information, available in the `face->size' */ + /* field. */ + /* */ + /* It is however possible to create more sizes for a given face, */ + /* mostly in order to manage several character pixel sizes of the */ + /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ + /* */ + /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ + /* modify the contents of the current `active' size; you thus need */ + /* to use @FT_Activate_Size to change it. */ + /* */ + /* 99% of applications won't need the functions provided here, */ + /* especially if they use the caching sub-system, so be cautious */ + /* when using these. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Size */ + /* */ + /* <Description> */ + /* Create a new size object from a given face object. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* asize :: A handle to a new size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You need to call @FT_Activate_Size in order to select the new size */ + /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ + /* @FT_Load_Glyph, @FT_Load_Char, etc. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size* size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Size */ + /* */ + /* <Description> */ + /* Discard a given size object. Note that @FT_Done_Face */ + /* automatically discards all size objects allocated with */ + /* @FT_New_Size. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Size( FT_Size size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Activate_Size */ + /* */ + /* <Description> */ + /* Even though it is possible to create several size objects for a */ + /* given face (see @FT_New_Size for details), functions like */ + /* @FT_Load_Glyph or @FT_Load_Char only use the one which has been */ + /* activated last to determine the `current character pixel size'. */ + /* */ + /* This function can be used to `activate' a previously created size */ + /* object. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If `face' is the size's parent face object, this function changes */ + /* the value of `face->size' to the input size handle. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Activate_Size( FT_Size size ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTSIZES_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftsnames.h b/drivers/freetype/include/freetype/ftsnames.h new file mode 100644 index 0000000000..485e4e162e --- /dev/null +++ b/drivers/freetype/include/freetype/ftsnames.h @@ -0,0 +1,200 @@ +/***************************************************************************/ +/* */ +/* ftsnames.h */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (specification). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 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_SFNT_NAMES_H__ +#define __FT_SFNT_NAMES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sfnt_names */ + /* */ + /* <Title> */ + /* SFNT Names */ + /* */ + /* <Abstract> */ + /* Access the names embedded in TrueType and OpenType files. */ + /* */ + /* <Description> */ + /* The TrueType and OpenType specifications allow the inclusion of */ + /* a special `names table' in font files. This table contains */ + /* textual (and internationalized) information regarding the font, */ + /* like family name, copyright, version, etc. */ + /* */ + /* The definitions below are used to access them if available. */ + /* */ + /* Note that this has nothing to do with glyph names! */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SfntName */ + /* */ + /* <Description> */ + /* A structure used to model an SFNT `name' table entry. */ + /* */ + /* <Fields> */ + /* platform_id :: The platform ID for `string'. */ + /* */ + /* encoding_id :: The encoding ID for `string'. */ + /* */ + /* language_id :: The language ID for `string'. */ + /* */ + /* name_id :: An identifier for `string'. */ + /* */ + /* string :: The `name' string. Note that its format differs */ + /* depending on the (platform,encoding) pair. It can */ + /* be a Pascal String, a UTF-16 one, etc. */ + /* */ + /* Generally speaking, the string is not */ + /* zero-terminated. Please refer to the TrueType */ + /* specification for details. */ + /* */ + /* string_len :: The length of `string' in bytes. */ + /* */ + /* <Note> */ + /* Possible values for `platform_id', `encoding_id', `language_id', */ + /* and `name_id' are given in the file `ttnameid.h'. For details */ + /* please refer to the TrueType or OpenType specification. */ + /* */ + /* See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ + /* @TT_ISO_ID_XXX, and @TT_MS_ID_XXX. */ + /* */ + typedef struct FT_SfntName_ + { + FT_UShort platform_id; + FT_UShort encoding_id; + FT_UShort language_id; + FT_UShort name_id; + + FT_Byte* string; /* this string is *not* null-terminated! */ + FT_UInt string_len; /* in bytes */ + + } FT_SfntName; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name_Count */ + /* */ + /* <Description> */ + /* Retrieve the number of name strings in the SFNT `name' table. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Return> */ + /* The number of strings in the `name' table. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name */ + /* */ + /* <Description> */ + /* Retrieve a string of the SFNT `name' table for a given index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* idx :: The index of the `name' string. */ + /* */ + /* <Output> */ + /* aname :: The indexed @FT_SfntName structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `string' array returned in the `aname' structure is not */ + /* null-terminated. The application should deallocate it if it is no */ + /* longer in use. */ + /* */ + /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ + /* `name' table entries, then do a loop until you get the right */ + /* platform, encoding, and name ID. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ); + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred family subfamily names in `name' + * table since OpenType version 1.4. For backwards compatibility with + * legacy systems which has 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred subfamily names in `name' table since + * OpenType version 1.4. For backwards compatibility with legacy + * systems which has 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) + + /* */ + + +FT_END_HEADER + +#endif /* __FT_SFNT_NAMES_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftstroke.h b/drivers/freetype/include/freetype/ftstroke.h new file mode 100644 index 0000000000..a498e4a883 --- /dev/null +++ b/drivers/freetype/include/freetype/ftstroke.h @@ -0,0 +1,751 @@ +/***************************************************************************/ +/* */ +/* ftstroke.h */ +/* */ +/* FreeType path stroker (specification). */ +/* */ +/* Copyright 2002-2006, 2008, 2009, 2011-2012 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_STROKE_H__ +#define __FT_STROKE_H__ + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************ + * + * @section: + * glyph_stroker + * + * @title: + * Glyph Stroker + * + * @abstract: + * Generating bordered and stroked glyphs. + * + * @description: + * This component generates stroked outlines of a given vectorial + * glyph. It also allows you to retrieve the `outside' and/or the + * `inside' borders of the stroke. + * + * This can be useful to generate `bordered' glyph, i.e., glyphs + * displayed with a coloured (and anti-aliased) border around their + * shape. + */ + + + /************************************************************** + * + * @type: + * FT_Stroker + * + * @description: + * Opaque handler to a path stroker object. + */ + typedef struct FT_StrokerRec_* FT_Stroker; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineJoin + * + * @description: + * These values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * FT_STROKER_LINEJOIN_ROUND :: + * Used to render rounded line joins. Circular arcs are used + * to join two lines smoothly. + * + * FT_STROKER_LINEJOIN_BEVEL :: + * Used to render beveled line joins. The outer corner of + * the joined lines is filled by enclosing the triangular + * region of the corner with a straight line between the + * outer corners of each stroke. + * + * FT_STROKER_LINEJOIN_MITER_FIXED :: + * Used to render mitered line joins, with fixed bevels if the + * miter limit is exceeded. The outer edges of the strokes + * for the two segments are extended until they meet at an + * angle. If the segments meet at too sharp an angle (such + * that the miter would extend from the intersection of the + * segments a distance greater than the product of the miter + * limit value and the border radius), then a bevel join (see + * above) is used instead. This prevents long spikes being + * created. FT_STROKER_LINEJOIN_MITER_FIXED generates a miter + * line join as used in PostScript and PDF. + * + * FT_STROKER_LINEJOIN_MITER_VARIABLE :: + * FT_STROKER_LINEJOIN_MITER :: + * Used to render mitered line joins, with variable bevels if + * the miter limit is exceeded. The intersection of the + * strokes is clipped at a line perpendicular to the bisector + * of the angle between the strokes, at the distance from the + * intersection of the segments equal to the product of the + * miter limit value and the border radius. This prevents + * long spikes being created. + * FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line + * join as used in XPS. FT_STROKER_LINEJOIN_MITER is an alias + * for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for + * backwards compatibility. + */ + typedef enum FT_Stroker_LineJoin_ + { + FT_STROKER_LINEJOIN_ROUND = 0, + FT_STROKER_LINEJOIN_BEVEL = 1, + FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, + FT_STROKER_LINEJOIN_MITER = FT_STROKER_LINEJOIN_MITER_VARIABLE, + FT_STROKER_LINEJOIN_MITER_FIXED = 3 + + } FT_Stroker_LineJoin; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineCap + * + * @description: + * These values determine how the end of opened sub-paths are + * rendered in a stroke. + * + * @values: + * FT_STROKER_LINECAP_BUTT :: + * The end of lines is rendered as a full stop on the last + * point itself. + * + * FT_STROKER_LINECAP_ROUND :: + * The end of lines is rendered as a half-circle around the + * last point. + * + * FT_STROKER_LINECAP_SQUARE :: + * The end of lines is rendered as a square around the + * last point. + */ + typedef enum FT_Stroker_LineCap_ + { + FT_STROKER_LINECAP_BUTT = 0, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINECAP_SQUARE + + } FT_Stroker_LineCap; + + + /************************************************************** + * + * @enum: + * FT_StrokerBorder + * + * @description: + * These values are used to select a given stroke border + * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. + * + * @values: + * FT_STROKER_BORDER_LEFT :: + * Select the left border, relative to the drawing direction. + * + * FT_STROKER_BORDER_RIGHT :: + * Select the right border, relative to the drawing direction. + * + * @note: + * Applications are generally interested in the `inside' and `outside' + * borders. However, there is no direct mapping between these and the + * `left' and `right' ones, since this really depends on the glyph's + * drawing orientation, which varies between font formats. + * + * You can however use @FT_Outline_GetInsideBorder and + * @FT_Outline_GetOutsideBorder to get these. + */ + typedef enum FT_StrokerBorder_ + { + FT_STROKER_BORDER_LEFT = 0, + FT_STROKER_BORDER_RIGHT + + } FT_StrokerBorder; + + + /************************************************************** + * + * @function: + * FT_Outline_GetInsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `inside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Outline_GetOutsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `outside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_New + * + * @description: + * Create a new stroker object. + * + * @input: + * library :: + * FreeType library handle. + * + * @output: + * astroker :: + * A new stroker object handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_New( FT_Library library, + FT_Stroker *astroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Set + * + * @description: + * Reset a stroker object's attributes. + * + * @input: + * stroker :: + * The target stroker handle. + * + * radius :: + * The border radius. + * + * line_cap :: + * The line cap style. + * + * line_join :: + * The line join style. + * + * miter_limit :: + * The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and + * FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles, + * expressed as 16.16 fixed-point value. + * + * @note: + * The radius is expressed in the same units as the outline + * coordinates. + */ + FT_EXPORT( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Rewind + * + * @description: + * Reset a stroker object without changing its attributes. + * You should call this function before beginning a new + * series of calls to @FT_Stroker_BeginSubPath or + * @FT_Stroker_EndSubPath. + * + * @input: + * stroker :: + * The target stroker handle. + */ + FT_EXPORT( void ) + FT_Stroker_Rewind( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ParseOutline + * + * @description: + * A convenience function used to parse a whole outline with + * the stroker. The resulting outline(s) can be retrieved + * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The source outline. + * + * opened :: + * A boolean. If~1, the outline is treated as an open path instead + * of a closed one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `opened' is~0 (the default), the outline is treated as a closed + * path, and the stroker generates two distinct `border' outlines. + * + * If `opened' is~1, the outline is processed as an open path, and the + * stroker generates a single `stroke' outline. + * + * This function calls @FT_Stroker_Rewind automatically. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ); + + + /************************************************************** + * + * @function: + * FT_Stroker_BeginSubPath + * + * @description: + * Start a new sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the start vector. + * + * open :: + * A boolean. If~1, the sub-path is treated as an open one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function is useful when you need to stroke a path that is + * not stored as an @FT_Outline object. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ); + + + /************************************************************** + * + * @function: + * FT_Stroker_EndSubPath + * + * @description: + * Close the current sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function after @FT_Stroker_BeginSubPath. + * If the subpath was not `opened', this function `draws' a + * single line segment to the start position when needed. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_LineTo + * + * @description: + * `Draw' a single line segment in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ConicTo + * + * @description: + * `Draw' a single quadratic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control :: + * A pointer to a Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_CubicTo + * + * @description: + * `Draw' a single cubic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control1 :: + * A pointer to the first Bézier control point. + * + * control2 :: + * A pointer to second Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetBorderCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export one of the `border' or `stroke' + * outlines generated by the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_GetCounts instead if you want to + * retrieve the counts associated to both borders. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ExportBorder + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the corresponding border to your own @FT_Outline + * structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * outline :: + * The target outline handle. + * + * @note: + * Always call this function after @FT_Stroker_GetBorderCounts to + * get sure that there is enough room in your @FT_Outline object to + * receive all new data. + * + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right' + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_Export instead if you want to + * retrieve all borders at once. + */ + FT_EXPORT( void ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export all points/borders from the stroked + * outline/path. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Export + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export all borders to your own @FT_Outline structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The target outline handle. + */ + FT_EXPORT( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Done + * + * @description: + * Destroy a stroker object. + * + * @input: + * stroker :: + * A stroker handle. Can be NULL. + */ + FT_EXPORT( void ) + FT_Stroker_Done( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Glyph_Stroke + * + * @description: + * Stroke a given outline glyph object with a given stroker. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + * + * Adding stroke may yield a significantly wider and taller glyph + * depending on how large of a radius was used to stroke the glyph. You + * may need to manually adjust horizontal and vertical advance amounts + * to account for this added size. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ); + + + /************************************************************** + * + * @function: + * FT_Glyph_StrokeBorder + * + * @description: + * Stroke a given outline glyph object with a given stroker, but + * only return either its inside or outside border. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * inside :: + * A Boolean. If~1, return the inside border, otherwise + * the outside border. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + * + * Adding stroke may yield a significantly wider and taller glyph + * depending on how large of a radius was used to stroke the glyph. You + * may need to manually adjust horizontal and vertical advance amounts + * to account for this added size. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ); + + /* */ + +FT_END_HEADER + +#endif /* __FT_STROKE_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/drivers/freetype/include/freetype/ftsynth.h b/drivers/freetype/include/freetype/ftsynth.h new file mode 100644 index 0000000000..2074503cf6 --- /dev/null +++ b/drivers/freetype/include/freetype/ftsynth.h @@ -0,0 +1,81 @@ +/***************************************************************************/ +/* */ +/* ftsynth.h */ +/* */ +/* FreeType synthesizing code for emboldening and slanting */ +/* (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2006, 2008, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS ALPHA CODE! THIS API *********/ + /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ + /********* FREETYPE DEVELOPMENT TEAM *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* Main reason for not lifting the functions in this module to a */ + /* `standard' API is that the used parameters for emboldening and */ + /* slanting are not configurable. Consider the functions as a */ + /* code resource which should be copied into the application and */ + /* adapted to the particular needs. */ + + +#ifndef __FTSYNTH_H__ +#define __FTSYNTH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ + /* taste). This function is actually a convenience function, providing */ + /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ + /* */ + /* For emboldened outlines the height, width, and advance metrics are */ + /* increased by the strength of the emboldening. You can also call */ + /* @FT_Outline_Get_CBox to get precise values. */ + FT_EXPORT( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); + + /* Slant an outline glyph to the right by about 12 degrees. */ + FT_EXPORT( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); + + /* */ + +FT_END_HEADER + +#endif /* __FTSYNTH_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftsystem.h b/drivers/freetype/include/freetype/ftsystem.h new file mode 100644 index 0000000000..e07460c55d --- /dev/null +++ b/drivers/freetype/include/freetype/ftsystem.h @@ -0,0 +1,347 @@ +/***************************************************************************/ +/* */ +/* ftsystem.h */ +/* */ +/* FreeType low-level system interface definition (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 2010 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 __FTSYSTEM_H__ +#define __FTSYSTEM_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* system_interface */ + /* */ + /* <Title> */ + /* System Interface */ + /* */ + /* <Abstract> */ + /* How FreeType manages memory and i/o. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to memory */ + /* management and i/o access. You need to understand this */ + /* information if you want to use a custom memory manager or you own */ + /* i/o streams. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* M E M O R Y M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Memory + * + * @description: + * A handle to a given memory manager object, defined with an + * @FT_MemoryRec structure. + * + */ + typedef struct FT_MemoryRec_* FT_Memory; + + + /************************************************************************* + * + * @functype: + * FT_Alloc_Func + * + * @description: + * A function used to allocate `size' bytes from `memory'. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * size :: + * The size in bytes to allocate. + * + * @return: + * Address of new memory block. 0~in case of failure. + * + */ + typedef void* + (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + + /************************************************************************* + * + * @functype: + * FT_Free_Func + * + * @description: + * A function used to release a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * block :: + * The address of the target memory block. + * + */ + typedef void + (*FT_Free_Func)( FT_Memory memory, + void* block ); + + + /************************************************************************* + * + * @functype: + * FT_Realloc_Func + * + * @description: + * A function used to re-allocate a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * cur_size :: + * The block's current size in bytes. + * + * new_size :: + * The block's requested new size. + * + * block :: + * The block's current address. + * + * @return: + * New block address. 0~in case of memory shortage. + * + * @note: + * In case of error, the old block must still be available. + * + */ + typedef void* + (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + + /************************************************************************* + * + * @struct: + * FT_MemoryRec + * + * @description: + * A structure used to describe a given memory manager to FreeType~2. + * + * @fields: + * user :: + * A generic typeless pointer for user data. + * + * alloc :: + * A pointer type to an allocation function. + * + * free :: + * A pointer type to an memory freeing function. + * + * realloc :: + * A pointer type to a reallocation function. + * + */ + struct FT_MemoryRec_ + { + void* user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + }; + + + /*************************************************************************/ + /* */ + /* I / O M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Stream + * + * @description: + * A handle to an input stream. + * + */ + typedef struct FT_StreamRec_* FT_Stream; + + + /************************************************************************* + * + * @struct: + * FT_StreamDesc + * + * @description: + * A union type used to store either a long or a pointer. This is used + * to store a file descriptor or a `FILE*' in an input stream. + * + */ + typedef union FT_StreamDesc_ + { + long value; + void* pointer; + + } FT_StreamDesc; + + + /************************************************************************* + * + * @functype: + * FT_Stream_IoFunc + * + * @description: + * A function used to seek and read data from a given input stream. + * + * @input: + * stream :: + * A handle to the source stream. + * + * offset :: + * The offset of read in stream (always from start). + * + * buffer :: + * The address of the read buffer. + * + * count :: + * The number of bytes to read from the stream. + * + * @return: + * The number of bytes effectively read by the stream. + * + * @note: + * This function might be called to perform a seek or skip operation + * with a `count' of~0. A non-zero return value then indicates an + * error. + * + */ + typedef unsigned long + (*FT_Stream_IoFunc)( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ); + + + /************************************************************************* + * + * @functype: + * FT_Stream_CloseFunc + * + * @description: + * A function used to close a given input stream. + * + * @input: + * stream :: + * A handle to the target stream. + * + */ + typedef void + (*FT_Stream_CloseFunc)( FT_Stream stream ); + + + /************************************************************************* + * + * @struct: + * FT_StreamRec + * + * @description: + * A structure used to describe an input stream. + * + * @input: + * base :: + * For memory-based streams, this is the address of the first stream + * byte in memory. This field should always be set to NULL for + * disk-based streams. + * + * size :: + * The stream size in bytes. + * + * pos :: + * The current position within the stream. + * + * descriptor :: + * This field is a union that can hold an integer or a pointer. It is + * used by stream implementations to store file descriptors or `FILE*' + * pointers. + * + * pathname :: + * This field is completely ignored by FreeType. However, it is often + * useful during debugging to use it to store the stream's filename + * (where available). + * + * read :: + * The stream's input function. + * + * close :: + * The stream's close function. + * + * memory :: + * The memory manager to use to preload frames. This is set + * internally by FreeType and shouldn't be touched by stream + * implementations. + * + * cursor :: + * This field is set and used internally by FreeType when parsing + * frames. + * + * limit :: + * This field is set and used internally by FreeType when parsing + * frames. + * + */ + typedef struct FT_StreamRec_ + { + unsigned char* base; + unsigned long size; + unsigned long pos; + + FT_StreamDesc descriptor; + FT_StreamDesc pathname; + FT_Stream_IoFunc read; + FT_Stream_CloseFunc close; + + FT_Memory memory; + unsigned char* cursor; + unsigned char* limit; + + } FT_StreamRec; + + + /* */ + + +FT_END_HEADER + +#endif /* __FTSYSTEM_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/fttrigon.h b/drivers/freetype/include/freetype/fttrigon.h new file mode 100644 index 0000000000..65143cb8c8 --- /dev/null +++ b/drivers/freetype/include/freetype/fttrigon.h @@ -0,0 +1,350 @@ +/***************************************************************************/ +/* */ +/* fttrigon.h */ +/* */ +/* FreeType trigonometric functions (specification). */ +/* */ +/* Copyright 2001, 2003, 2005, 2007, 2013 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 __FTTRIGON_H__ +#define __FTTRIGON_H__ + +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Angle + * + * @description: + * This type is used to model angle values in FreeType. Note that the + * angle is a 16.16 fixed-point value expressed in degrees. + * + */ + typedef FT_Fixed FT_Angle; + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI + * + * @description: + * The angle pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI ( 180L << 16 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_2PI + * + * @description: + * The angle 2*pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI2 + * + * @description: + * The angle pi/2 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI4 + * + * @description: + * The angle pi/4 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) + + + /************************************************************************* + * + * @function: + * FT_Sin + * + * @description: + * Return the sinus of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The sinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Sin( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Cos + * + * @description: + * Return the cosinus of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The cosinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Cos( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Tan + * + * @description: + * Return the tangent of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The tangent value. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Tan( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Atan2 + * + * @description: + * Return the arc-tangent corresponding to a given vector (x,y) in + * the 2d plane. + * + * @input: + * x :: + * The horizontal vector coordinate. + * + * y :: + * The vertical vector coordinate. + * + * @return: + * The arc-tangent value (i.e. angle). + * + */ + FT_EXPORT( FT_Angle ) + FT_Atan2( FT_Fixed x, + FT_Fixed y ); + + + /************************************************************************* + * + * @function: + * FT_Angle_Diff + * + * @description: + * Return the difference between two angles. The result is always + * constrained to the ]-PI..PI] interval. + * + * @input: + * angle1 :: + * First angle. + * + * angle2 :: + * Second angle. + * + * @return: + * Constrained value of `value2-value1'. + * + */ + FT_EXPORT( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Unit + * + * @description: + * Return the unit vector corresponding to a given angle. After the + * call, the value of `vec.x' will be `sin(angle)', and the value of + * `vec.y' will be `cos(angle)'. + * + * This function is useful to retrieve both the sinus and cosinus of a + * given angle quickly. + * + * @output: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The address of angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Rotate + * + * @description: + * Rotate a vector by a given angle. + * + * @inout: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The address of angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Length + * + * @description: + * Return the length of a given vector. + * + * @input: + * vec :: + * The address of target vector. + * + * @return: + * The vector length, expressed in the same units that the original + * vector coordinates. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Polarize + * + * @description: + * Compute both the length and angle of a given vector. + * + * @input: + * vec :: + * The address of source vector. + * + * @output: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_From_Polar + * + * @description: + * Compute vector coordinates from a length and angle. + * + * @output: + * vec :: + * The address of source vector. + * + * @input: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTTRIGON_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftttdrv.h b/drivers/freetype/include/freetype/ftttdrv.h new file mode 100644 index 0000000000..d5d3f1ccc1 --- /dev/null +++ b/drivers/freetype/include/freetype/ftttdrv.h @@ -0,0 +1,150 @@ +/***************************************************************************/ +/* */ +/* ftttdrv.h */ +/* */ +/* FreeType API for controlling the TrueType driver */ +/* (specification only). */ +/* */ +/* Copyright 2013 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 __FTTTDRV_H__ +#define __FTTTDRV_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * tt_driver + * + * @title: + * The TrueType driver + * + * @abstract: + * Controlling the TrueType driver module. + * + * @description: + * While FreeType's TrueType driver doesn't expose API functions by + * itself, it is possible to control its behaviour with @FT_Property_Set + * and @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * The TrueType driver's module name is `truetype'. + * + */ + + + /************************************************************************** + * + * @property: + * interpreter-version + * + * @description: + * Currently, two versions are available which represent the bytecode + * interpreter with and without subpixel hinting support, + * respectively. The default is subpixel support if + * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel + * support otherwise (since it isn't available then). + * + * If subpixel hinting is on, many TrueType bytecode instructions + * behave differently compared to B/W or grayscale rendering. The + * main idea is to render at a much increased horizontal resolution, + * then sampling down the created output to subpixel precision. + * However, many older fonts are not suited to this and must be + * specially taken care of by applying (hardcoded) font-specific + * tweaks. + * + * Details on subpixel hinting and some of the necessary tweaks can be + * found in Greg Hitchcock's whitepaper at + * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * + * The following example code demonstrates how to activate subpixel + * hinting (omitting the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_38; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "truetype", + * "interpreter-version", + * &interpreter_version ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /************************************************************************** + * + * @enum: + * TT_INTERPRETER_VERSION_XXX + * + * @description: + * A list of constants used for the @interpreter-version property to + * select the hinting engine for Truetype fonts. + * + * The numeric value in the constant names represents the version + * number as returned by the `GETINFO' bytecode instruction. + * + * @values: + * TT_INTERPRETER_VERSION_35 :: + * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in + * Windows~98; only grayscale and B/W rasterizing is supported. + * + * TT_INTERPRETER_VERSION_38 :: + * Version~38 corresponds to MS rasterizer v.1.9; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as + * can be found, for example, in the Internet Explorer~9 running on + * Windows~7). + * + * @note: + * This property controls the behaviour of the bytecode interpreter + * and thus how outlines get hinted. It does *not* control how glyph + * get rasterized! In particular, it does not control subpixel color + * filtering. + * + * If FreeType has not been compiled with configuration option + * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an + * `FT_Err_Unimplemented_Feature' error. + * + */ +#define TT_INTERPRETER_VERSION_35 35 +#define TT_INTERPRETER_VERSION_38 38 + + + /* */ + +FT_END_HEADER + + +#endif /* __FTTTDRV_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/fttypes.h b/drivers/freetype/include/freetype/fttypes.h new file mode 100644 index 0000000000..027e59ce11 --- /dev/null +++ b/drivers/freetype/include/freetype/fttypes.h @@ -0,0 +1,598 @@ +/***************************************************************************/ +/* */ +/* fttypes.h */ +/* */ +/* FreeType simple types definitions (specification only). */ +/* */ +/* Copyright 1996-2002, 2004, 2006-2009, 2012, 2013 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 __FTTYPES_H__ +#define __FTTYPES_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_SYSTEM_H +#include FT_IMAGE_H + +#include <stddef.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /* <Title> */ + /* Basic Data Types */ + /* */ + /* <Abstract> */ + /* The basic data types defined by the library. */ + /* */ + /* <Description> */ + /* This section contains the basic data types defined by FreeType~2, */ + /* ranging from simple scalar types to bitmap descriptors. More */ + /* font-specific structures are defined in a different section. */ + /* */ + /* <Order> */ + /* FT_Byte */ + /* FT_Bytes */ + /* FT_Char */ + /* FT_Int */ + /* FT_UInt */ + /* FT_Int16 */ + /* FT_UInt16 */ + /* FT_Int32 */ + /* FT_UInt32 */ + /* FT_Short */ + /* FT_UShort */ + /* FT_Long */ + /* FT_ULong */ + /* FT_Bool */ + /* FT_Offset */ + /* FT_PtrDist */ + /* FT_String */ + /* FT_Tag */ + /* FT_Error */ + /* FT_Fixed */ + /* FT_Pointer */ + /* FT_Pos */ + /* FT_Vector */ + /* FT_BBox */ + /* FT_Matrix */ + /* FT_FWord */ + /* FT_UFWord */ + /* FT_F2Dot14 */ + /* FT_UnitVector */ + /* FT_F26Dot6 */ + /* */ + /* */ + /* FT_Generic */ + /* FT_Generic_Finalizer */ + /* */ + /* FT_Bitmap */ + /* FT_Pixel_Mode */ + /* FT_Palette_Mode */ + /* FT_Glyph_Format */ + /* FT_IMAGE_TAG */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bool */ + /* */ + /* <Description> */ + /* A typedef of unsigned char, used for simple booleans. As usual, */ + /* values 1 and~0 represent true and false, respectively. */ + /* */ + typedef unsigned char FT_Bool; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_FWord */ + /* */ + /* <Description> */ + /* A signed 16-bit integer used to store a distance in original font */ + /* units. */ + /* */ + typedef signed short FT_FWord; /* distance in FUnits */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UFWord */ + /* */ + /* <Description> */ + /* An unsigned 16-bit integer used to store a distance in original */ + /* font units. */ + /* */ + typedef unsigned short FT_UFWord; /* unsigned distance */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Char */ + /* */ + /* <Description> */ + /* A simple typedef for the _signed_ char type. */ + /* */ + typedef signed char FT_Char; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Byte */ + /* */ + /* <Description> */ + /* A simple typedef for the _unsigned_ char type. */ + /* */ + typedef unsigned char FT_Byte; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bytes */ + /* */ + /* <Description> */ + /* A typedef for constant memory areas. */ + /* */ + typedef const FT_Byte* FT_Bytes; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Tag */ + /* */ + /* <Description> */ + /* A typedef for 32-bit tags (as used in the SFNT format). */ + /* */ + typedef FT_UInt32 FT_Tag; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_String */ + /* */ + /* <Description> */ + /* A simple typedef for the char type, usually used for strings. */ + /* */ + typedef char FT_String; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Short */ + /* */ + /* <Description> */ + /* A typedef for signed short. */ + /* */ + typedef signed short FT_Short; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UShort */ + /* */ + /* <Description> */ + /* A typedef for unsigned short. */ + /* */ + typedef unsigned short FT_UShort; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int */ + /* */ + /* <Description> */ + /* A typedef for the int type. */ + /* */ + typedef signed int FT_Int; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt */ + /* */ + /* <Description> */ + /* A typedef for the unsigned int type. */ + /* */ + typedef unsigned int FT_UInt; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Long */ + /* */ + /* <Description> */ + /* A typedef for signed long. */ + /* */ + typedef signed long FT_Long; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ULong */ + /* */ + /* <Description> */ + /* A typedef for unsigned long. */ + /* */ + typedef unsigned long FT_ULong; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F2Dot14 */ + /* */ + /* <Description> */ + /* A signed 2.14 fixed-point type used for unit vectors. */ + /* */ + typedef signed short FT_F2Dot14; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F26Dot6 */ + /* */ + /* <Description> */ + /* A signed 26.6 fixed-point type used for vectorial pixel */ + /* coordinates. */ + /* */ + typedef signed long FT_F26Dot6; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Fixed */ + /* */ + /* <Description> */ + /* This type is used to store 16.16 fixed-point values, like scaling */ + /* values or matrix coefficients. */ + /* */ + typedef signed long FT_Fixed; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Error */ + /* */ + /* <Description> */ + /* The FreeType error code type. A value of~0 is always interpreted */ + /* as a successful operation. */ + /* */ + typedef int FT_Error; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pointer */ + /* */ + /* <Description> */ + /* A simple typedef for a typeless pointer. */ + /* */ + typedef void* FT_Pointer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Offset */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ + /* _unsigned_ integer type used to express a file size or position, */ + /* or a memory block size. */ + /* */ + typedef size_t FT_Offset; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_PtrDist */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ + /* largest _signed_ integer type used to express the distance */ + /* between two pointers. */ + /* */ + typedef ft_ptrdiff_t FT_PtrDist; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_UnitVector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector unit vector. Uses */ + /* FT_F2Dot14 types. */ + /* */ + /* <Fields> */ + /* x :: Horizontal coordinate. */ + /* */ + /* y :: Vertical coordinate. */ + /* */ + typedef struct FT_UnitVector_ + { + FT_F2Dot14 x; + FT_F2Dot14 y; + + } FT_UnitVector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Matrix */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2x2 matrix. Coefficients are */ + /* in 16.16 fixed-point format. The computation performed is: */ + /* */ + /* { */ + /* x' = x*xx + y*xy */ + /* y' = x*yx + y*yy */ + /* } */ + /* */ + /* <Fields> */ + /* xx :: Matrix coefficient. */ + /* */ + /* xy :: Matrix coefficient. */ + /* */ + /* yx :: Matrix coefficient. */ + /* */ + /* yy :: Matrix coefficient. */ + /* */ + typedef struct FT_Matrix_ + { + FT_Fixed xx, xy; + FT_Fixed yx, yy; + + } FT_Matrix; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Data */ + /* */ + /* <Description> */ + /* Read-only binary data represented as a pointer and a length. */ + /* */ + /* <Fields> */ + /* pointer :: The data. */ + /* */ + /* length :: The length of the data in bytes. */ + /* */ + typedef struct FT_Data_ + { + const FT_Byte* pointer; + FT_Int length; + + } FT_Data; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Generic_Finalizer */ + /* */ + /* <Description> */ + /* Describe a function used to destroy the `client' data of any */ + /* FreeType object. See the description of the @FT_Generic type for */ + /* details of usage. */ + /* */ + /* <Input> */ + /* The address of the FreeType object which is under finalization. */ + /* Its client data is accessed through its `generic' field. */ + /* */ + typedef void (*FT_Generic_Finalizer)(void* object); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Generic */ + /* */ + /* <Description> */ + /* Client applications often need to associate their own data to a */ + /* variety of FreeType core objects. For example, a text layout API */ + /* might want to associate a glyph cache to a given size object. */ + /* */ + /* Some FreeType object contains a `generic' field, of type */ + /* FT_Generic, which usage is left to client applications and font */ + /* servers. */ + /* */ + /* It can be used to store a pointer to client-specific data, as well */ + /* as the address of a `finalizer' function, which will be called by */ + /* FreeType when the object is destroyed (for example, the previous */ + /* client example would put the address of the glyph cache destructor */ + /* in the `finalizer' field). */ + /* */ + /* <Fields> */ + /* data :: A typeless pointer to any client-specified data. This */ + /* field is completely ignored by the FreeType library. */ + /* */ + /* finalizer :: A pointer to a `generic finalizer' function, which */ + /* will be called when the object is destroyed. If this */ + /* field is set to NULL, no code will be called. */ + /* */ + typedef struct FT_Generic_ + { + void* data; + FT_Generic_Finalizer finalizer; + + } FT_Generic; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_MAKE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags which are used to label */ + /* TrueType tables into an unsigned long to be used within FreeType. */ + /* */ + /* <Note> */ + /* The produced values *must* be 32-bit integers. Don't redefine */ + /* this macro. */ + /* */ +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + (FT_Tag) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* L I S T M A N A G E M E N T */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ListNode */ + /* */ + /* <Description> */ + /* Many elements and objects in FreeType are listed through an */ + /* @FT_List record (see @FT_ListRec). As its name suggests, an */ + /* FT_ListNode is a handle to a single list element. */ + /* */ + typedef struct FT_ListNodeRec_* FT_ListNode; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_List */ + /* */ + /* <Description> */ + /* A handle to a list record (see @FT_ListRec). */ + /* */ + typedef struct FT_ListRec_* FT_List; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListNodeRec */ + /* */ + /* <Description> */ + /* A structure used to hold a single list element. */ + /* */ + /* <Fields> */ + /* prev :: The previous element in the list. NULL if first. */ + /* */ + /* next :: The next element in the list. NULL if last. */ + /* */ + /* data :: A typeless pointer to the listed object. */ + /* */ + typedef struct FT_ListNodeRec_ + { + FT_ListNode prev; + FT_ListNode next; + void* data; + + } FT_ListNodeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListRec */ + /* */ + /* <Description> */ + /* A structure used to hold a simple doubly-linked list. These are */ + /* used in many parts of FreeType. */ + /* */ + /* <Fields> */ + /* head :: The head (first element) of doubly-linked list. */ + /* */ + /* tail :: The tail (last element) of doubly-linked list. */ + /* */ + typedef struct FT_ListRec_ + { + FT_ListNode head; + FT_ListNode tail; + + } FT_ListRec; + + + /* */ + +#define FT_IS_EMPTY( list ) ( (list).head == 0 ) +#define FT_BOOL( x ) ( (FT_Bool)( x ) ) + + /* concatenate C tokens */ +#define FT_ERR_XCAT( x, y ) x ## y +#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) + + /* see `ftmoderr.h' for descriptions of the following macros */ + +#define FT_ERR( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) + +#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) +#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) + +#define FT_ERR_EQ( x, e ) \ + ( FT_ERROR_BASE( x ) == FT_ERROR_BASE( FT_ERR( e ) ) ) +#define FT_ERR_NEQ( x, e ) \ + ( FT_ERROR_BASE( x ) != FT_ERROR_BASE( FT_ERR( e ) ) ) + + +FT_END_HEADER + +#endif /* __FTTYPES_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftwinfnt.h b/drivers/freetype/include/freetype/ftwinfnt.h new file mode 100644 index 0000000000..ea33353536 --- /dev/null +++ b/drivers/freetype/include/freetype/ftwinfnt.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.h */ +/* */ +/* FreeType API for accessing Windows fnt-specific data. */ +/* */ +/* Copyright 2003, 2004, 2008 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 __FTWINFNT_H__ +#define __FTWINFNT_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* winfnt_fonts */ + /* */ + /* <Title> */ + /* Window FNT Files */ + /* */ + /* <Abstract> */ + /* Windows FNT specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Windows FNT specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FT_WinFNT_ID_XXX + * + * @description: + * A list of valid values for the `charset' byte in + * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX + * encodings (except for cp1361) can be found at ftp://ftp.unicode.org + * in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory. cp1361 is + * roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * + * @values: + * FT_WinFNT_ID_DEFAULT :: + * 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 + * return value (of the related Windows API) simply denotes failure. + * + * FT_WinFNT_ID_SYMBOL :: + * There is no known mapping table available. + * + * FT_WinFNT_ID_MAC :: + * Mac Roman encoding. + * + * FT_WinFNT_ID_OEM :: + * From Michael Pöttgen <michael@poettgen.de>: + * + * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM + * is used for the charset of vector fonts, like `modern.fon', + * `roman.fon', and `script.fon' on Windows. + * + * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value + * specifies a character set that is operating-system dependent. + * + * The `IFIMETRICS' documentation from the `Windows Driver + * Development Kit' says: This font supports an OEM-specific + * character set. The OEM character set is system dependent. + * + * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the + * second default codepage that most international versions of + * 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. + * + * FT_WinFNT_ID_CP874 :: + * A superset of Thai TIS 620 and ISO 8859-11. + * + * FT_WinFNT_ID_CP932 :: + * A superset of Japanese Shift-JIS (with minor deviations). + * + * FT_WinFNT_ID_CP936 :: + * A superset of simplified Chinese GB 2312-1980 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP949 :: + * A superset of Korean Hangul KS~C 5601-1987 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP950 :: + * A superset of traditional Chinese Big~5 ETen (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP1250 :: + * A superset of East European ISO 8859-2 (with slightly different + * ordering). + * + * FT_WinFNT_ID_CP1251 :: + * A superset of Russian ISO 8859-5 (with different ordering). + * + * FT_WinFNT_ID_CP1252 :: + * ANSI encoding. A superset of ISO 8859-1. + * + * 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). + * + * FT_WinFNT_ID_CP1256 :: + * A superset of Arabic ISO 8859-6 (with different ordering). + * + * FT_WinFNT_ID_CP1257 :: + * A superset of Baltic ISO 8859-13 (with some deviations). + * + * FT_WinFNT_ID_CP1258 :: + * For Vietnamese. This encoding doesn't cover all necessary + * characters. + * + * FT_WinFNT_ID_CP1361 :: + * Korean (Johab). + */ + +#define FT_WinFNT_ID_CP1252 0 +#define FT_WinFNT_ID_DEFAULT 1 +#define FT_WinFNT_ID_SYMBOL 2 +#define FT_WinFNT_ID_MAC 77 +#define FT_WinFNT_ID_CP932 128 +#define FT_WinFNT_ID_CP949 129 +#define FT_WinFNT_ID_CP1361 130 +#define FT_WinFNT_ID_CP936 134 +#define FT_WinFNT_ID_CP950 136 +#define FT_WinFNT_ID_CP1253 161 +#define FT_WinFNT_ID_CP1254 162 +#define FT_WinFNT_ID_CP1258 163 +#define FT_WinFNT_ID_CP1255 177 +#define FT_WinFNT_ID_CP1256 178 +#define FT_WinFNT_ID_CP1257 186 +#define FT_WinFNT_ID_CP1251 204 +#define FT_WinFNT_ID_CP874 222 +#define FT_WinFNT_ID_CP1250 238 +#define FT_WinFNT_ID_OEM 255 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_HeaderRec */ + /* */ + /* <Description> */ + /* Windows FNT Header info. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_ + { + FT_UShort version; + FT_ULong file_size; + FT_Byte copyright[60]; + FT_UShort file_type; + FT_UShort nominal_point_size; + FT_UShort vertical_resolution; + FT_UShort horizontal_resolution; + FT_UShort ascent; + FT_UShort internal_leading; + FT_UShort external_leading; + FT_Byte italic; + FT_Byte underline; + FT_Byte strike_out; + FT_UShort weight; + FT_Byte charset; + FT_UShort pixel_width; + FT_UShort pixel_height; + FT_Byte pitch_and_family; + FT_UShort avg_width; + FT_UShort max_width; + FT_Byte first_char; + FT_Byte last_char; + FT_Byte default_char; + FT_Byte break_char; + FT_UShort bytes_per_row; + FT_ULong device_offset; + FT_ULong face_name_offset; + FT_ULong bits_pointer; + FT_ULong bits_offset; + FT_Byte reserved; + FT_ULong flags; + FT_UShort A_space; + FT_UShort B_space; + FT_UShort C_space; + FT_UShort color_table_offset; + FT_ULong reserved1[4]; + + } FT_WinFNT_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_Header */ + /* */ + /* <Description> */ + /* A handle to an @FT_WinFNT_HeaderRec structure. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieve a Windows FNT font info header. + * + * @input: + * face :: A handle to the input face. + * + * @output: + * aheader :: The WinFNT header. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with Windows FNT faces, returning an error + * otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + /* */ + +FT_END_HEADER + +#endif /* __FTWINFNT_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/drivers/freetype/include/freetype/ftxf86.h b/drivers/freetype/include/freetype/ftxf86.h new file mode 100644 index 0000000000..8c68afdcc5 --- /dev/null +++ b/drivers/freetype/include/freetype/ftxf86.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* ftxf86.h */ +/* */ +/* Support functions for X11. */ +/* */ +/* Copyright 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, */ +/* 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 __FTXF86_H__ +#define __FTXF86_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* font_formats */ + /* */ + /* <Title> */ + /* Font Formats */ + /* */ + /* <Abstract> */ + /* Getting the font format. */ + /* */ + /* <Description> */ + /* 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, in spite of FreeType's uniform API. */ + /* */ + /* This function is in the X11/xf86 namespace for historical reasons */ + /* and in no way depends on that windowing system. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <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. */ + /* */ + /* <Return> */ + /* Font format string. NULL in case of error. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_X11_Font_Format( FT_Face face ); + + /* */ + +FT_END_HEADER + +#endif /* __FTXF86_H__ */ diff --git a/drivers/freetype/include/freetype/internal/autohint.h b/drivers/freetype/include/freetype/internal/autohint.h new file mode 100644 index 0000000000..545de938c2 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/autohint.h @@ -0,0 +1,244 @@ +/***************************************************************************/ +/* */ +/* autohint.h */ +/* */ +/* High-level `autohint' module-specific interface (specification). */ +/* */ +/* Copyright 1996-2002, 2007, 2009, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The auto-hinter is used to load and automatically hint glyphs if a */ + /* format-specific hinter isn't available. */ + /* */ + /*************************************************************************/ + + +#ifndef __AUTOHINT_H__ +#define __AUTOHINT_H__ + + + /*************************************************************************/ + /* */ + /* A small technical note regarding automatic hinting in order to */ + /* clarify this module interface. */ + /* */ + /* An automatic hinter might compute two kinds of data for a given face: */ + /* */ + /* - global hints: Usually some metrics that describe global properties */ + /* of the face. It is computed by scanning more or less */ + /* aggressively the glyphs in the face, and thus can be */ + /* very slow to compute (even if the size of global */ + /* hints is really small). */ + /* */ + /* - glyph hints: These describe some important features of the glyph */ + /* outline, as well as how to align them. They are */ + /* generally much faster to compute than global hints. */ + /* */ + /* The current FreeType auto-hinter does a pretty good job while */ + /* performing fast computations for both global and glyph hints. */ + /* However, we might be interested in introducing more complex and */ + /* powerful algorithms in the future, like the one described in the John */ + /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ + /* */ + /* Because a sufficiently sophisticated font management system would */ + /* typically implement an LRU cache of opened face objects to reduce */ + /* memory usage, it is a good idea to be able to avoid recomputing */ + /* global hints every time the same face is re-opened. */ + /* */ + /* We thus provide the ability to cache global hints outside of the face */ + /* object, in order to speed up font re-opening time. Of course, this */ + /* feature is purely optional, so most client programs won't even notice */ + /* it. */ + /* */ + /* I initially thought that it would be a good idea to cache the glyph */ + /* hints too. However, my general idea now is that if you really need */ + /* to cache these too, you are simply in need of a new font format, */ + /* where all this information could be stored within the font file and */ + /* decoded on the fly. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef struct FT_AutoHinterRec_ *FT_AutoHinter; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalGetFunc */ + /* */ + /* <Description> */ + /* Retrieve the global hints computed for a given face object. The */ + /* resulting data is dissociated from the face and will survive a */ + /* call to FT_Done_Face(). It must be discarded through the API */ + /* FT_AutoHinter_GlobalDoneFunc(). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* global_hints :: A typeless pointer to the global hints. */ + /* */ + /* global_len :: The size in bytes of the global hints. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter hinter, + FT_Face face, + void** global_hints, + long* global_len ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalDoneFunc */ + /* */ + /* <Description> */ + /* Discard the global hints retrieved through */ + /* FT_AutoHinter_GlobalGetFunc(). This is the only way these hints */ + /* are freed from memory. */ + /* */ + /* <Input> */ + /* hinter :: A handle to the auto-hinter module. */ + /* */ + /* global :: A pointer to retrieved global hints to discard. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter hinter, + void* global ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalResetFunc */ + /* */ + /* <Description> */ + /* This function is used to recompute the global metrics in a given */ + /* font. This is useful when global font data changes (e.g. Multiple */ + /* Masters fonts where blend coordinates change). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the face. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter hinter, + FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlyphLoadFunc */ + /* */ + /* <Description> */ + /* This function is used to load, scale, and automatically hint a */ + /* glyph from a given face. */ + /* */ + /* <Input> */ + /* face :: A handle to the face. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* load_flags :: The load flags. */ + /* */ + /* <Note> */ + /* This function is capable of loading composite glyphs by hinting */ + /* each sub-glyph independently (which improves quality). */ + /* */ + /* It will call the font driver with @FT_Load_Glyph, with */ + /* @FT_LOAD_NO_SCALE set. */ + /* */ + typedef FT_Error + (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter hinter, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_AutoHinter_InterfaceRec */ + /* */ + /* <Description> */ + /* The auto-hinter module's interface. */ + /* */ + typedef struct FT_AutoHinter_InterfaceRec_ + { + FT_AutoHinter_GlobalResetFunc reset_face; + FT_AutoHinter_GlobalGetFunc get_global_hints; + FT_AutoHinter_GlobalDoneFunc done_global_hints; + FT_AutoHinter_GlyphLoadFunc load_glyph; + + } FT_AutoHinter_InterfaceRec, *FT_AutoHinter_Interface; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_AUTOHINTER_INTERFACE( \ + class_, \ + reset_face_, \ + get_global_hints_, \ + done_global_hints_, \ + load_glyph_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_AutoHinter_InterfaceRec class_ = \ + { \ + reset_face_, \ + get_global_hints_, \ + done_global_hints_, \ + load_glyph_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_AUTOHINTER_INTERFACE( \ + class_, \ + reset_face_, \ + get_global_hints_, \ + done_global_hints_, \ + load_glyph_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_AutoHinter_InterfaceRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->reset_face = reset_face_; \ + clazz->get_global_hints = get_global_hints_; \ + clazz->done_global_hints = done_global_hints_; \ + clazz->load_glyph = load_glyph_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* __AUTOHINT_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftcalc.h b/drivers/freetype/include/freetype/internal/ftcalc.h new file mode 100644 index 0000000000..faac3a3867 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftcalc.h @@ -0,0 +1,167 @@ +/***************************************************************************/ +/* */ +/* ftcalc.h */ +/* */ +/* Arithmetic computations (specification). */ +/* */ +/* Copyright 1996-2006, 2008, 2009, 2012-2013 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 __FTCALC_H__ +#define __FTCALC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FixedSqrt */ + /* */ + /* <Description> */ + /* Computes the square root of a 16.16 fixed-point value. */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + /* <Note> */ + /* This function is not very fast. */ + /* */ + FT_BASE( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ); + + + /*************************************************************************/ + /* */ + /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv_No_Round */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* (without rounding) with maximum accuracy (it uses a 64-bit */ + /* intermediate integer whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_BASE( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ); + + + /* + * A variant of FT_Matrix_Multiply which scales its result afterwards. + * The idea is that both `a' and `b' are scaled by factors of 10 so that + * the values are as precise as possible to get a correct result during + * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of + * `a' and `b', respectively, then the scaling factor of the result is + * `sa*sb'. + */ + FT_BASE( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ); + + + /* + * A variant of FT_Vector_Transform. See comments for + * FT_Matrix_Multiply_Scaled. + */ + FT_BASE( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ); + + + /* + * 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 ); + + + /* + * Return the most significant bit index. + */ + FT_BASE( FT_Int ) + FT_MSB( FT_UInt32 z ); + + + /* + * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses + * two fixed-point arguments instead. + */ + FT_BASE( FT_Fixed ) + FT_Hypot( FT_Fixed x, + FT_Fixed y ); + + +#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) +#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) +#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) +#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) +#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) +#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) + +#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ + : ( -( ( 32 - (x) ) & -64 ) ) ) + + +FT_END_HEADER + +#endif /* __FTCALC_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftdebug.h b/drivers/freetype/include/freetype/internal/ftdebug.h new file mode 100644 index 0000000000..58a3916d7e --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftdebug.h @@ -0,0 +1,255 @@ +/***************************************************************************/ +/* */ +/* ftdebug.h */ +/* */ +/* Debugging and logging component (specification). */ +/* */ +/* Copyright 1996-2002, 2004, 2006-2009, 2013 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. */ +/* */ +/* */ +/* IMPORTANT: A description of FreeType's debugging support can be */ +/* found in `docs/DEBUG.TXT'. Read it if you need to use or */ +/* understand this code. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTDEBUG_H__ +#define __FTDEBUG_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ + /* is already defined; this simplifies the following #ifdefs */ + /* */ +#ifdef FT_DEBUG_LEVEL_TRACE +#undef FT_DEBUG_LEVEL_ERROR +#define FT_DEBUG_LEVEL_ERROR +#endif + + + /*************************************************************************/ + /* */ + /* Define the trace enums as well as the trace levels array when they */ + /* are needed. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define FT_TRACE_DEF( x ) trace_ ## x , + + /* defining the enumeration */ + typedef enum FT_Trace_ + { +#include FT_INTERNAL_TRACE_H + trace_count + + } FT_Trace; + + + /* defining the array of trace levels, provided by `src/base/ftdebug.c' */ + extern int ft_trace_levels[trace_count]; + +#undef FT_TRACE_DEF + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Define the FT_TRACE macro */ + /* */ + /* IMPORTANT! */ + /* */ + /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ + /* value before using any TRACE macro. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define FT_TRACE( level, varformat ) \ + do \ + { \ + if ( ft_trace_levels[FT_COMPONENT] >= level ) \ + FT_Message varformat; \ + } while ( 0 ) + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Trace_Get_Count */ + /* */ + /* <Description> */ + /* Return the number of available trace components. */ + /* */ + /* <Return> */ + /* The number of trace components. 0 if FreeType 2 is not built with */ + /* FT_DEBUG_LEVEL_TRACE definition. */ + /* */ + /* <Note> */ + /* This function may be useful if you want to access elements of */ + /* the internal `ft_trace_levels' array by an index. */ + /* */ + FT_BASE( FT_Int ) + FT_Trace_Get_Count( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Trace_Get_Name */ + /* */ + /* <Description> */ + /* Return the name of a trace component. */ + /* */ + /* <Input> */ + /* The index of the trace component. */ + /* */ + /* <Return> */ + /* The name of the trace component. This is a statically allocated */ + /* C string, so do not free it after use. NULL if FreeType 2 is not */ + /* built with FT_DEBUG_LEVEL_TRACE definition. */ + /* */ + /* <Note> */ + /* Use @FT_Trace_Get_Count to get the number of available trace */ + /* components. */ + /* */ + /* This function may be useful if you want to control FreeType 2's */ + /* debug level in your application. */ + /* */ + FT_BASE( const char * ) + FT_Trace_Get_Name( FT_Int idx ); + + + /*************************************************************************/ + /* */ + /* You need two opening and closing parentheses! */ + /* */ + /* Example: FT_TRACE0(( "Value is %i", foo )) */ + /* */ + /* Output of the FT_TRACEX macros is sent to stderr. */ + /* */ + /*************************************************************************/ + +#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) +#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) +#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat ) +#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat ) +#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat ) +#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat ) +#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat ) +#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) + + + /*************************************************************************/ + /* */ + /* Define the FT_ERROR macro. */ + /* */ + /* Output of this macro is sent to stderr. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#define FT_ERROR( varformat ) FT_Message varformat + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_ERROR */ + + + /*************************************************************************/ + /* */ + /* Define the FT_ASSERT and FT_THROW macros. The call to `FT_Throw' */ + /* makes it possible to easily set a breakpoint at this function. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#define FT_ASSERT( condition ) \ + do \ + { \ + if ( !( condition ) ) \ + FT_Panic( "assertion failed on line %d of file %s\n", \ + __LINE__, __FILE__ ); \ + } while ( 0 ) + +#define FT_THROW( e ) \ + ( FT_Throw( FT_ERR_CAT( FT_ERR_PREFIX, e ), \ + __LINE__, \ + __FILE__ ) | \ + FT_ERR_CAT( FT_ERR_PREFIX, e ) ) + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ASSERT( condition ) do { } while ( 0 ) + +#define FT_THROW( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) + +#endif /* !FT_DEBUG_LEVEL_ERROR */ + + + /*************************************************************************/ + /* */ + /* Define `FT_Message' and `FT_Panic' when needed. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#include "stdio.h" /* for vfprintf() */ + + /* print a message */ + FT_BASE( void ) + FT_Message( const char* fmt, + ... ); + + /* print a message and exit */ + FT_BASE( void ) + FT_Panic( const char* fmt, + ... ); + + /* report file name and line number of an error */ + FT_BASE( int ) + FT_Throw( FT_Error error, + int line, + const char* file ); + +#endif /* FT_DEBUG_LEVEL_ERROR */ + + + FT_BASE( void ) + ft_debug_init( void ); + +FT_END_HEADER + +#endif /* __FTDEBUG_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftdriver.h b/drivers/freetype/include/freetype/internal/ftdriver.h new file mode 100644 index 0000000000..940218e62d --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftdriver.h @@ -0,0 +1,409 @@ +/***************************************************************************/ +/* */ +/* ftdriver.h */ +/* */ +/* FreeType font driver interface (specification). */ +/* */ +/* Copyright 1996-2003, 2006, 2008, 2011-2013 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 __FTDRIVER_H__ +#define __FTDRIVER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + typedef FT_Error + (*FT_Face_InitFunc)( FT_Stream stream, + FT_Face face, + FT_Int typeface_index, + FT_Int num_params, + FT_Parameter* parameters ); + + typedef void + (*FT_Face_DoneFunc)( FT_Face face ); + + + typedef FT_Error + (*FT_Size_InitFunc)( FT_Size size ); + + typedef void + (*FT_Size_DoneFunc)( FT_Size size ); + + + typedef FT_Error + (*FT_Slot_InitFunc)( FT_GlyphSlot slot ); + + typedef void + (*FT_Slot_DoneFunc)( FT_GlyphSlot slot ); + + + typedef FT_Error + (*FT_Size_RequestFunc)( FT_Size size, + FT_Size_Request req ); + + typedef FT_Error + (*FT_Size_SelectFunc)( FT_Size size, + FT_ULong size_index ); + + typedef FT_Error + (*FT_Slot_LoadFunc)( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + typedef FT_UInt + (*FT_CharMap_CharIndexFunc)( FT_CharMap charmap, + FT_Long charcode ); + + typedef FT_Long + (*FT_CharMap_CharNextFunc)( FT_CharMap charmap, + FT_Long charcode ); + + + typedef FT_Error + (*FT_Face_GetKerningFunc)( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ); + + + typedef FT_Error + (*FT_Face_AttachFunc)( FT_Face face, + FT_Stream stream ); + + + typedef FT_Error + (*FT_Face_GetAdvancesFunc)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Driver_ClassRec */ + /* */ + /* <Description> */ + /* The font driver class. This structure mostly contains pointers to */ + /* driver methods. */ + /* */ + /* <Fields> */ + /* root :: The parent module. */ + /* */ + /* face_object_size :: The size of a face object in bytes. */ + /* */ + /* size_object_size :: The size of a size object in bytes. */ + /* */ + /* slot_object_size :: The size of a glyph object in bytes. */ + /* */ + /* init_face :: The format-specific face constructor. */ + /* */ + /* done_face :: The format-specific face destructor. */ + /* */ + /* init_size :: The format-specific size constructor. */ + /* */ + /* done_size :: The format-specific size destructor. */ + /* */ + /* init_slot :: The format-specific slot constructor. */ + /* */ + /* done_slot :: The format-specific slot destructor. */ + /* */ + /* */ + /* load_glyph :: A function handle to load a glyph to a slot. */ + /* This field is mandatory! */ + /* */ + /* get_kerning :: A function handle to return the unscaled */ + /* kerning for a given pair of glyphs. Can be */ + /* set to 0 if the format doesn't support */ + /* kerning. */ + /* */ + /* attach_file :: This function handle is used to read */ + /* additional data for a face from another */ + /* file/stream. For example, this can be used to */ + /* add data from AFM or PFM files on a Type 1 */ + /* face, or a CIDMap on a CID-keyed face. */ + /* */ + /* get_advances :: A function handle used to return advance */ + /* widths of `count' glyphs (in font units), */ + /* starting at `first'. The `vertical' flag must */ + /* be set to get vertical advance heights. The */ + /* `advances' buffer is caller-allocated. */ + /* The idea of this function is to be able to */ + /* perform device-independent text layout without */ + /* loading a single glyph image. */ + /* */ + /* request_size :: A handle to a function used to request the new */ + /* character size. Can be set to 0 if the */ + /* scaling done in the base layer suffices. */ + /* */ + /* select_size :: A handle to a function used to select a new */ + /* fixed size. It is used only if */ + /* @FT_FACE_FLAG_FIXED_SIZES is set. Can be set */ + /* to 0 if the scaling done in the base layer */ + /* suffices. */ + /* <Note> */ + /* Most function pointers, with the exception of `load_glyph', can be */ + /* set to 0 to indicate a default behaviour. */ + /* */ + typedef struct FT_Driver_ClassRec_ + { + FT_Module_Class root; + + FT_Long face_object_size; + FT_Long size_object_size; + FT_Long slot_object_size; + + FT_Face_InitFunc init_face; + FT_Face_DoneFunc done_face; + + FT_Size_InitFunc init_size; + FT_Size_DoneFunc done_size; + + FT_Slot_InitFunc init_slot; + FT_Slot_DoneFunc done_slot; + + FT_Slot_LoadFunc load_glyph; + + FT_Face_GetKerningFunc get_kerning; + FT_Face_AttachFunc attach_file; + FT_Face_GetAdvancesFunc get_advances; + + /* since version 2.2 */ + FT_Size_RequestFunc request_size; + FT_Size_SelectFunc select_size; + + } FT_Driver_ClassRec, *FT_Driver_Class; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_DRIVER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of an FT_Driver_ClassRec */ + /* struct instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_DRIVER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Driver_ClassRec struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function has to be */ + /* called with a pointer where the allocated structure is returned. */ + /* And when it is no longer needed a `destroy' function needs to be */ + /* called to release that allocation. */ + /* */ + /* `fcinit.c' (ft_create_default_module_classes) already contains a */ + /* mechanism to call these functions for the default modules */ + /* described in `ftmodule.h'. */ + /* */ + /* Notice that the created `create' and `destroy' functions call */ + /* `pic_init' and `pic_free' to allow you to manually allocate and */ + /* initialize any additional global data, like a module specific */ + /* interface, and put them in the global pic container defined in */ + /* `ftpic.h'. If you don't need them just implement the functions as */ + /* empty to resolve the link error. Also the `pic_init' and */ + /* `pic_free' functions should be declared in `pic.h', to be referred */ + /* by driver definition calling `FT_DEFINE_DRIVER' in following. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro is */ + /* used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_DRIVER( class_ ) \ + FT_CALLBACK_TABLE \ + const FT_Driver_ClassRec class_; + +#define FT_DEFINE_DRIVER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + init_face_, \ + done_face_, \ + init_size_, \ + done_size_, \ + init_slot_, \ + done_slot_, \ + load_glyph_, \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + request_size_, \ + select_size_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Driver_ClassRec class_ = \ + { \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + \ + init_face_, \ + done_face_, \ + \ + init_size_, \ + done_size_, \ + \ + init_slot_, \ + done_slot_, \ + \ + load_glyph_, \ + \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + \ + request_size_, \ + select_size_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_DRIVER( class_ ) FT_DECLARE_MODULE( class_ ) + +#define FT_DEFINE_DRIVER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + init_face_, \ + done_face_, \ + init_size_, \ + done_size_, \ + init_slot_, \ + done_slot_, \ + load_glyph_, \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + request_size_, \ + select_size_ ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \ + \ + \ + class_ ## _pic_free( library ); \ + if ( dclazz ) \ + FT_FREE( dclazz ); \ + } \ + \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Driver_Class clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ + return error; \ + \ + error = class_ ## _pic_init( library ); \ + if ( error ) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + \ + clazz->face_object_size = face_object_size_; \ + clazz->size_object_size = size_object_size_; \ + clazz->slot_object_size = slot_object_size_; \ + \ + clazz->init_face = init_face_; \ + clazz->done_face = done_face_; \ + \ + clazz->init_size = init_size_; \ + clazz->done_size = done_size_; \ + \ + clazz->init_slot = init_slot_; \ + clazz->done_slot = done_slot_; \ + \ + clazz->load_glyph = load_glyph_; \ + \ + clazz->get_kerning = get_kerning_; \ + clazz->attach_file = attach_file_; \ + clazz->get_advances = get_advances_; \ + \ + clazz->request_size = request_size_; \ + clazz->select_size = select_size_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + \ + return FT_Err_Ok; \ + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* __FTDRIVER_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftgloadr.h b/drivers/freetype/include/freetype/internal/ftgloadr.h new file mode 100644 index 0000000000..ce4dc6c9cc --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftgloadr.h @@ -0,0 +1,168 @@ +/***************************************************************************/ +/* */ +/* ftgloadr.h */ +/* */ +/* The FreeType glyph loader (specification). */ +/* */ +/* Copyright 2002, 2003, 2005, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGLOADR_H__ +#define __FTGLOADR_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphLoader */ + /* */ + /* <Description> */ + /* The glyph loader is an internal object used to load several glyphs */ + /* together (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The glyph loader implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; + + +#if 0 /* moved to freetype.h in version 2.2 */ +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 +#endif + + + typedef struct FT_SubGlyphRec_ + { + FT_Int index; + FT_UShort flags; + FT_Int arg1; + FT_Int arg2; + FT_Matrix transform; + + } FT_SubGlyphRec; + + + typedef struct FT_GlyphLoadRec_ + { + 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 */ + + } FT_GlyphLoadRec, *FT_GlyphLoad; + + + typedef struct FT_GlyphLoaderRec_ + { + FT_Memory memory; + FT_UInt max_points; + FT_UInt max_contours; + FT_UInt max_subglyphs; + FT_Bool use_extra; + + FT_GlyphLoadRec base; + FT_GlyphLoadRec current; + + void* other; /* for possible future extension? */ + + } FT_GlyphLoaderRec; + + + /* create new empty glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader *aloader ); + + /* add an extra points table to a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ); + + /* destroy a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Done( FT_GlyphLoader loader ); + + /* reset a glyph loader (frees everything int it) */ + FT_BASE( void ) + FT_GlyphLoader_Reset( FT_GlyphLoader loader ); + + /* rewind a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Rewind( FT_GlyphLoader loader ); + + /* check that there is enough space to add `n_points' and `n_contours' */ + /* to the glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, + FT_UInt n_points, + FT_UInt n_contours ); + + +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_points + \ + (_loader)->current.outline.n_points + \ + (unsigned long)(_count)) <= (_loader)->max_points ) + +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ + (_loader)->current.outline.n_contours + \ + (unsigned long)(_count)) <= (_loader)->max_contours ) + +#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ + ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ + FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ + ? 0 \ + : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) ) + + + /* check that there is enough space to add `n_subs' sub-glyphs to */ + /* a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, + FT_UInt n_subs ); + + /* prepare a glyph loader, i.e. empty the current glyph */ + FT_BASE( void ) + FT_GlyphLoader_Prepare( FT_GlyphLoader loader ); + + /* add the current glyph to the base glyph */ + FT_BASE( void ) + FT_GlyphLoader_Add( FT_GlyphLoader loader ); + + /* copy points from one glyph loader to another */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, + FT_GlyphLoader source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLOADR_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftmemory.h b/drivers/freetype/include/freetype/internal/ftmemory.h new file mode 100644 index 0000000000..3d51aeec69 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftmemory.h @@ -0,0 +1,378 @@ +/***************************************************************************/ +/* */ +/* ftmemory.h */ +/* */ +/* The FreeType memory management macros (specification). */ +/* */ +/* Copyright 1996-2002, 2004-2007, 2010, 2013 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 __FTMEMORY_H__ +#define __FTMEMORY_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_SET_ERROR */ + /* */ + /* <Description> */ + /* This macro is used to set an implicit `error' variable to a given */ + /* expression's value (usually a function call), and convert it to a */ + /* boolean which is set whenever the value is != 0. */ + /* */ +#undef FT_SET_ERROR +#define FT_SET_ERROR( expression ) \ + ( ( error = (expression) ) != 0 ) + + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M E M O R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* + * C++ refuses to handle statements like p = (void*)anything, with `p' a + * typed pointer. Since we don't have a `typeof' operator in standard + * C++, we have to use a template to emulate it. + */ + +#ifdef __cplusplus + + extern "C++" + template <typename T> inline T* + cplusplus_typeof( T*, + void *v ) + { + return static_cast <T*> ( v ); + } + +#define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) ) + +#else + +#define FT_ASSIGNP( p, val ) (p) = (val) + +#endif + + + +#ifdef FT_DEBUG_MEMORY + + FT_BASE( const char* ) _ft_debug_file; + FT_BASE( long ) _ft_debug_lineno; + +#define FT_DEBUG_INNER( exp ) ( _ft_debug_file = __FILE__, \ + _ft_debug_lineno = __LINE__, \ + (exp) ) + +#define FT_ASSIGNP_INNER( p, exp ) ( _ft_debug_file = __FILE__, \ + _ft_debug_lineno = __LINE__, \ + FT_ASSIGNP( p, exp ) ) + +#else /* !FT_DEBUG_MEMORY */ + +#define FT_DEBUG_INNER( exp ) (exp) +#define FT_ASSIGNP_INNER( p, exp ) FT_ASSIGNP( p, exp ) + +#endif /* !FT_DEBUG_MEMORY */ + + + /* + * The allocation functions return a pointer, and the error code + * is written to through the `p_error' parameter. See below for + * for documentation. + */ + + FT_BASE( FT_Pointer ) + ft_mem_alloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_qalloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_realloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_qrealloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ); + + FT_BASE( void ) + ft_mem_free( FT_Memory memory, + const void* P ); + + +#define FT_MEM_ALLOC( ptr, size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, \ + (FT_Long)(size), \ + &error ) ) + +#define FT_MEM_FREE( ptr ) \ + FT_BEGIN_STMNT \ + ft_mem_free( memory, (ptr) ); \ + (ptr) = NULL; \ + FT_END_STMNT + +#define FT_MEM_NEW( ptr ) \ + FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) ) + +#define FT_MEM_REALLOC( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + 1, \ + (FT_Long)(cursz), \ + (FT_Long)(newsz), \ + (ptr), \ + &error ) ) + +#define FT_MEM_QALLOC( ptr, size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, \ + (FT_Long)(size), \ + &error ) ) + +#define FT_MEM_QNEW( ptr ) \ + FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) ) + +#define FT_MEM_QREALLOC( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + 1, \ + (FT_Long)(cursz), \ + (FT_Long)(newsz), \ + (ptr), \ + &error ) ) + +#define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + (FT_Long)(item_size), \ + 0, \ + (FT_Long)(count), \ + NULL, \ + &error ) ) + +#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + (FT_Long)(itmsz), \ + (FT_Long)(oldcnt), \ + (FT_Long)(newcnt), \ + (ptr), \ + &error ) ) + +#define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + (FT_Long)(item_size), \ + 0, \ + (FT_Long)(count), \ + NULL, \ + &error ) ) + +#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + (FT_Long)(itmsz), \ + (FT_Long)(oldcnt), \ + (FT_Long)(newcnt), \ + (ptr), \ + &error ) ) + + +#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) + + +#define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) + +#define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) + +#define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) + + +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) + +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) + + +#define FT_ARRAY_ZERO( dest, count ) \ + FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) ) + +#define FT_ARRAY_COPY( dest, source, count ) \ + FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) ) + +#define FT_ARRAY_MOVE( dest, source, count ) \ + FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) ) + + + /* + * Return the maximum number of addressable elements in an array. + * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid + * any problems. + */ +#define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) ) + +#define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) ) + + + /*************************************************************************/ + /* */ + /* The following functions macros expect that their pointer argument is */ + /* _typed_ in order to automatically compute array element sizes. */ + /* */ + +#define FT_MEM_NEW_ARRAY( ptr, count ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + sizeof ( *(ptr) ), \ + 0, \ + (FT_Long)(count), \ + NULL, \ + &error ) ) + +#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + sizeof ( *(ptr) ), \ + (FT_Long)(cursz), \ + (FT_Long)(newsz), \ + (ptr), \ + &error ) ) + +#define FT_MEM_QNEW_ARRAY( ptr, count ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + sizeof ( *(ptr) ), \ + 0, \ + (FT_Long)(count), \ + NULL, \ + &error ) ) + +#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + sizeof ( *(ptr) ), \ + (FT_Long)(cursz), \ + (FT_Long)(newsz), \ + (ptr), \ + &error ) ) + +#define FT_ALLOC( ptr, size ) \ + FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) ) + +#define FT_REALLOC( ptr, cursz, newsz ) \ + FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) ) + +#define FT_ALLOC_MULT( ptr, count, item_size ) \ + FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) ) + +#define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt, \ + newcnt, itmsz ) ) + +#define FT_QALLOC( ptr, size ) \ + FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) ) + +#define FT_QREALLOC( ptr, cursz, newsz ) \ + FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) ) + +#define FT_QALLOC_MULT( ptr, count, item_size ) \ + FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) ) + +#define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt, \ + newcnt, itmsz ) ) + +#define FT_FREE( ptr ) FT_MEM_FREE( ptr ) + +#define FT_NEW( ptr ) FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) ) + +#define FT_NEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) + +#define FT_RENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) + +#define FT_QNEW( ptr ) \ + FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) + +#define FT_QNEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) + +#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) + + + FT_BASE( FT_Pointer ) + ft_mem_strdup( FT_Memory memory, + const char* str, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_dup( FT_Memory memory, + const void* address, + FT_ULong size, + FT_Error *p_error ); + + +#define FT_MEM_STRDUP( dst, str ) \ + (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) + +#define FT_STRDUP( dst, str ) \ + FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) + +#define FT_MEM_DUP( dst, address, size ) \ + (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) + +#define FT_DUP( dst, address, size ) \ + FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) + + + /* Return >= 1 if a truncation occurs. */ + /* Return 0 if the source string fits the buffer. */ + /* This is *not* the same as strlcpy(). */ + FT_BASE( FT_Int ) + ft_mem_strcpyn( char* dst, + const char* src, + FT_ULong size ); + +#define FT_STRCPYN( dst, src, size ) \ + ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) ) + + /* */ + + +FT_END_HEADER + +#endif /* __FTMEMORY_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftobjs.h b/drivers/freetype/include/freetype/internal/ftobjs.h new file mode 100644 index 0000000000..701c850eb7 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftobjs.h @@ -0,0 +1,1569 @@ +/***************************************************************************/ +/* */ +/* ftobjs.h */ +/* */ +/* The FreeType private base classes (specification). */ +/* */ +/* Copyright 1996-2006, 2008, 2010, 2012-2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file contains the definition of all internal FreeType classes. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTOBJS_H__ +#define __FTOBJS_H__ + +#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 +#include FT_INTERNAL_AUTOHINT_H +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_PIC_H + +#ifdef FT_CONFIG_OPTION_INCREMENTAL +#include FT_INCREMENTAL_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Some generic definitions. */ + /* */ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + + + /*************************************************************************/ + /* */ + /* The min and max functions missing in C. As usual, be careful not to */ + /* write things like FT_MIN( a++, b++ ) to avoid side effects. */ + /* */ +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) + +#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) + + +#define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) ) +#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) +#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) + +#define FT_PIX_FLOOR( x ) ( (x) & ~63 ) +#define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) +#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) + + + /* + * Return the highest power of 2 that is <= value; this correspond to + * the highest bit in a given 32-bit value. + */ + FT_BASE( FT_UInt32 ) + ft_highpow2( FT_UInt32 value ); + + + /* + * character classification functions -- since these are used to parse + * font files, we must not use those in <ctypes.h> which are + * locale-dependent + */ +#define ft_isdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U ) + +#define ft_isxdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U || \ + ( (unsigned)(x) - 'a' ) < 6U || \ + ( (unsigned)(x) - 'A' ) < 6U ) + + /* the next two macros assume ASCII representation */ +#define ft_isupper( x ) ( ( (unsigned)(x) - 'A' ) < 26U ) +#define ft_islower( x ) ( ( (unsigned)(x) - 'a' ) < 26U ) + +#define ft_isalpha( x ) ( ft_isupper( x ) || ft_islower( x ) ) +#define ft_isalnum( x ) ( ft_isdigit( x ) || ft_isalpha( x ) ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C H A R M A P S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to internal charmap object */ + typedef struct FT_CMapRec_* FT_CMap; + + /* handle to charmap class structure */ + typedef const struct FT_CMap_ClassRec_* FT_CMap_Class; + + /* internal charmap object structure */ + typedef struct FT_CMapRec_ + { + FT_CharMapRec charmap; + FT_CMap_Class clazz; + + } FT_CMapRec; + + /* typecase any pointer to a charmap handle */ +#define FT_CMAP( x ) ((FT_CMap)( x )) + + /* obvious macros */ +#define FT_CMAP_PLATFORM_ID( x ) FT_CMAP( x )->charmap.platform_id +#define FT_CMAP_ENCODING_ID( x ) FT_CMAP( x )->charmap.encoding_id +#define FT_CMAP_ENCODING( x ) FT_CMAP( x )->charmap.encoding +#define FT_CMAP_FACE( x ) FT_CMAP( x )->charmap.face + + + /* class method definitions */ + typedef FT_Error + (*FT_CMap_InitFunc)( FT_CMap cmap, + FT_Pointer init_data ); + + typedef void + (*FT_CMap_DoneFunc)( FT_CMap cmap ); + + typedef FT_UInt + (*FT_CMap_CharIndexFunc)( FT_CMap cmap, + FT_UInt32 char_code ); + + typedef FT_UInt + (*FT_CMap_CharNextFunc)( FT_CMap cmap, + FT_UInt32 *achar_code ); + + typedef FT_UInt + (*FT_CMap_CharVarIndexFunc)( FT_CMap cmap, + FT_CMap unicode_cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_Bool + (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_UInt32 * + (*FT_CMap_VariantListFunc)( FT_CMap cmap, + FT_Memory mem ); + + typedef FT_UInt32 * + (*FT_CMap_CharVariantListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 char_code ); + + typedef FT_UInt32 * + (*FT_CMap_VariantCharListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 variant_selector ); + + + typedef struct FT_CMap_ClassRec_ + { + FT_ULong size; + FT_CMap_InitFunc init; + FT_CMap_DoneFunc done; + FT_CMap_CharIndexFunc char_index; + FT_CMap_CharNextFunc char_next; + + /* Subsequent entries are special ones for format 14 -- the variant */ + /* selector subtable which behaves like no other */ + + FT_CMap_CharVarIndexFunc char_var_index; + FT_CMap_CharVarIsDefaultFunc char_var_default; + FT_CMap_VariantListFunc variant_list; + FT_CMap_CharVariantListFunc charvariant_list; + FT_CMap_VariantCharListFunc variantchar_list; + + } FT_CMap_ClassRec; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_CMAP_CLASS( class_ ) \ + FT_CALLBACK_TABLE const FT_CMap_ClassRec class_; + +#define FT_DEFINE_CMAP_CLASS( \ + class_, \ + size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_CMap_ClassRec class_ = \ + { \ + size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_CMAP_CLASS( class_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_CMap_ClassRec* clazz ); + +#define FT_DEFINE_CMAP_CLASS( \ + class_, \ + size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_CMap_ClassRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->size = size_; \ + clazz->init = init_; \ + clazz->done = done_; \ + clazz->char_index = char_index_; \ + clazz->char_next = char_next_; \ + clazz->char_var_index = char_var_index_; \ + clazz->char_var_default = char_var_default_; \ + clazz->variant_list = variant_list_; \ + clazz->charvariant_list = charvariant_list_; \ + clazz->variantchar_list = variantchar_list_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* create a new charmap and add it to charmap->face */ + FT_BASE( FT_Error ) + FT_CMap_New( FT_CMap_Class clazz, + FT_Pointer init_data, + FT_CharMap charmap, + FT_CMap *acmap ); + + /* destroy a charmap and remove it from face's list */ + FT_BASE( void ) + FT_CMap_Done( FT_CMap cmap ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Face_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Face */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* max_points :: */ + /* The maximum number of points used to store the vectorial outline */ + /* of any glyph in this face. If this value cannot be known in */ + /* advance, or if the face isn't scalable, this should be set to 0. */ + /* Only relevant for scalable formats. */ + /* */ + /* max_contours :: */ + /* The maximum number of contours used to store the vectorial */ + /* outline of any glyph in this face. If this value cannot be */ + /* known in advance, or if the face isn't scalable, this should be */ + /* set to 0. Only relevant for scalable formats. */ + /* */ + /* transform_matrix :: */ + /* A 2x2 matrix of 16.16 coefficients used to transform glyph */ + /* outlines after they are loaded from the font. Only used by the */ + /* convenience functions. */ + /* */ + /* transform_delta :: */ + /* A translation vector used to transform glyph outlines after they */ + /* are loaded from the font. Only used by the convenience */ + /* functions. */ + /* */ + /* transform_flags :: */ + /* Some flags used to classify the transform. Only used by the */ + /* convenience functions. */ + /* */ + /* services :: */ + /* A cache for frequently used services. It should be only */ + /* accessed with the macro `FT_FACE_LOOKUP_SERVICE'. */ + /* */ + /* incremental_interface :: */ + /* If non-null, the interface through which glyph data and metrics */ + /* are loaded incrementally for faces that do not provide all of */ + /* 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. */ + /* */ + /* refcount :: */ + /* A counter initialized to~1 at the time an @FT_Face structure is */ + /* created. @FT_Reference_Face increments this counter, and */ + /* @FT_Done_Face only destroys a face if the counter is~1, */ + /* otherwise it simply decrements it. */ + /* */ + typedef struct FT_Face_InternalRec_ + { + FT_Matrix transform_matrix; + FT_Vector transform_delta; + FT_Int transform_flags; + + FT_ServiceCacheRec services; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec* incremental_interface; +#endif + + FT_Bool ignore_unpatented_hinter; + FT_Int refcount; + + } FT_Face_InternalRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Slot_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_GlyphSlot */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* loader :: The glyph loader object used to load outlines */ + /* into the glyph slot. */ + /* */ + /* flags :: Possible values are zero or */ + /* FT_GLYPH_OWN_BITMAP. The latter indicates */ + /* that the FT_GlyphSlot structure owns the */ + /* bitmap buffer. */ + /* */ + /* glyph_transformed :: Boolean. Set to TRUE when the loaded glyph */ + /* must be transformed through a specific */ + /* font transformation. This is _not_ the same */ + /* as the face transform set through */ + /* FT_Set_Transform(). */ + /* */ + /* glyph_matrix :: The 2x2 matrix corresponding to the glyph */ + /* transformation, if necessary. */ + /* */ + /* glyph_delta :: The 2d translation vector corresponding to */ + /* the glyph transformation, if necessary. */ + /* */ + /* glyph_hints :: Format-specific glyph hints management. */ + /* */ + +#define FT_GLYPH_OWN_BITMAP 0x1 + + typedef struct FT_Slot_InternalRec_ + { + FT_GlyphLoader loader; + FT_UInt flags; + FT_Bool glyph_transformed; + FT_Matrix glyph_matrix; + FT_Vector glyph_delta; + void* glyph_hints; + + } FT_GlyphSlot_InternalRec; + + +#if 0 + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Size */ + /* object. Currently, it's empty. */ + /* */ + /*************************************************************************/ + + typedef struct FT_Size_InternalRec_ + { + /* empty */ + + } FT_Size_InternalRec; + +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ModuleRec */ + /* */ + /* <Description> */ + /* A module object instance. */ + /* */ + /* <Fields> */ + /* clazz :: A pointer to the module's class. */ + /* */ + /* library :: A handle to the parent library object. */ + /* */ + /* memory :: A handle to the memory manager. */ + /* */ + typedef struct FT_ModuleRec_ + { + FT_Module_Class* clazz; + FT_Library library; + FT_Memory memory; + + } FT_ModuleRec; + + + /* typecast an object to an FT_Module */ +#define FT_MODULE( x ) ((FT_Module)( x )) +#define FT_MODULE_CLASS( x ) FT_MODULE( x )->clazz +#define FT_MODULE_LIBRARY( x ) FT_MODULE( x )->library +#define FT_MODULE_MEMORY( x ) FT_MODULE( x )->memory + + +#define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_FONT_DRIVER ) + +#define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_RENDERER ) + +#define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_HINTER ) + +#define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_STYLER ) + +#define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_SCALABLE ) + +#define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_NO_OUTLINES ) + +#define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HAS_HINTER ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module_Interface */ + /* */ + /* <Description> */ + /* Finds a module and returns its specific interface as a typeless */ + /* pointer. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module-specific interface if available, 0 otherwise. */ + /* */ + /* <Note> */ + /* You should better be familiar with FreeType internals to know */ + /* which module to look for, and what its interface is :-) */ + /* */ + FT_BASE( const void* ) + FT_Get_Module_Interface( FT_Library library, + const char* mod_name ); + + FT_BASE( FT_Pointer ) + ft_module_get_service( FT_Module module, + const char* service_id ); + + /* */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F A C E, S I Z E & G L Y P H S L O T O B J E C T S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* a few macros used to perform easy typecasts with minimal brain damage */ + +#define FT_FACE( x ) ((FT_Face)(x)) +#define FT_SIZE( x ) ((FT_Size)(x)) +#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) + +#define FT_FACE_DRIVER( x ) FT_FACE( x )->driver +#define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library +#define FT_FACE_MEMORY( x ) FT_FACE( x )->memory +#define FT_FACE_STREAM( x ) FT_FACE( x )->stream + +#define FT_SIZE_FACE( x ) FT_SIZE( x )->face +#define FT_SLOT_FACE( x ) FT_SLOT( x )->face + +#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph +#define FT_FACE_SIZE( x ) FT_FACE( x )->size + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_GlyphSlot */ + /* */ + /* <Description> */ + /* It is sometimes useful to have more than one glyph slot for a */ + /* given face object. This function is used to create additional */ + /* slots. All of them are automatically discarded when the face is */ + /* destroyed. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* aslot :: A handle to a new glyph slot object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_BASE( FT_Error ) + FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot *aslot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_GlyphSlot */ + /* */ + /* <Description> */ + /* Destroys a given glyph slot. Remember however that all slots are */ + /* automatically destroyed with its parent. Using this function is */ + /* not always mandatory. */ + /* */ + /* <Input> */ + /* slot :: A handle to a target glyph slot. */ + /* */ + FT_BASE( void ) + FT_Done_GlyphSlot( FT_GlyphSlot slot ); + + /* */ + +#define FT_REQUEST_WIDTH( req ) \ + ( (req)->horiResolution \ + ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \ + : (req)->width ) + +#define FT_REQUEST_HEIGHT( req ) \ + ( (req)->vertResolution \ + ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \ + : (req)->height ) + + + /* Set the metrics according to a bitmap strike. */ + FT_BASE( void ) + FT_Select_Metrics( FT_Face face, + FT_ULong strike_index ); + + + /* Set the metrics according to a size request. */ + FT_BASE( void ) + FT_Request_Metrics( FT_Face face, + FT_Size_Request req ); + + + /* Match a size request against `available_sizes'. */ + FT_BASE( FT_Error ) + FT_Match_Size( FT_Face face, + FT_Size_Request req, + FT_Bool ignore_width, + FT_ULong* size_index ); + + + /* Use the horizontal metrics to synthesize the vertical metrics. */ + /* If `advance' is zero, it is also synthesized. */ + FT_BASE( void ) + ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, + FT_Pos advance ); + + + /* Free the bitmap of a given glyphslot when needed (i.e., only when it */ + /* was allocated with ft_glyphslot_alloc_bitmap). */ + FT_BASE( void ) + ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); + + + /* Allocate a new bitmap buffer in a glyph slot. */ + FT_BASE( FT_Error ) + ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, + FT_ULong size ); + + + /* Set the bitmap buffer in a glyph slot to a given pointer. The buffer */ + /* will not be freed by a later call to ft_glyphslot_free_bitmap. */ + FT_BASE( void ) + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Byte* buffer ); + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FT_RENDERER( x ) ((FT_Renderer)( x )) +#define FT_GLYPH( x ) ((FT_Glyph)( x )) +#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) +#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) + + + typedef struct FT_RendererRec_ + { + FT_ModuleRec root; + FT_Renderer_Class* clazz; + FT_Glyph_Format glyph_format; + FT_Glyph_Class glyph_class; + + FT_Raster raster; + FT_Raster_Render_Func raster_render; + FT_Renderer_RenderFunc render; + + } FT_RendererRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F O N T D R I V E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* typecast a module into a driver easily */ +#define FT_DRIVER( x ) ((FT_Driver)(x)) + + /* typecast a module as a driver, and get its driver class */ +#define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_DriverRec */ + /* */ + /* <Description> */ + /* The root font driver class. A font driver is responsible for */ + /* managing and loading font files of a given format. */ + /* */ + /* <Fields> */ + /* root :: Contains the fields of the root module class. */ + /* */ + /* clazz :: A pointer to the font driver's class. Note that */ + /* this is NOT root.clazz. `class' wasn't used */ + /* as it is a reserved word in C++. */ + /* */ + /* faces_list :: The list of faces currently opened by this */ + /* driver. */ + /* */ + /* glyph_loader :: The glyph loader for all faces managed by this */ + /* driver. This object isn't defined for unscalable */ + /* formats. */ + /* */ + typedef struct FT_DriverRec_ + { + FT_ModuleRec root; + FT_Driver_Class clazz; + FT_ListRec faces_list; + FT_GlyphLoader glyph_loader; + + } FT_DriverRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R I E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* This hook is used by the TrueType debugger. It must be set to an */ + /* alternate truetype bytecode interpreter function. */ +#define FT_DEBUG_HOOK_TRUETYPE 0 + + + /* Set this debug hook to a non-null pointer to force unpatented hinting */ + /* 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> */ + /* FT_LibraryRec */ + /* */ + /* <Description> */ + /* The FreeType library class. This is the root of all FreeType */ + /* data. Use FT_New_Library() to create a library object, and */ + /* FT_Done_Library() to discard it and all child objects. */ + /* */ + /* <Fields> */ + /* memory :: The library's memory object. Manages memory */ + /* allocation. */ + /* */ + /* version_major :: The major version number of the library. */ + /* */ + /* version_minor :: The minor version number of the library. */ + /* */ + /* version_patch :: The current patch level of the library. */ + /* */ + /* num_modules :: The number of modules currently registered */ + /* within this library. This is set to 0 for new */ + /* libraries. New modules are added through the */ + /* FT_Add_Module() API function. */ + /* */ + /* modules :: A table used to store handles to the currently */ + /* registered modules. Note that each font driver */ + /* contains a list of its opened faces. */ + /* */ + /* renderers :: The list of renderers currently registered */ + /* within the library. */ + /* */ + /* cur_renderer :: The current outline renderer. This is a */ + /* shortcut used to avoid parsing the list on */ + /* each call to FT_Outline_Render(). It is a */ + /* handle to the current renderer for the */ + /* FT_GLYPH_FORMAT_OUTLINE format. */ + /* */ + /* auto_hinter :: XXX */ + /* */ + /* raster_pool :: The raster object's render pool. This can */ + /* ideally be changed dynamically at run-time. */ + /* */ + /* raster_pool_size :: The size of the render pool in bytes. */ + /* */ + /* debug_hooks :: XXX */ + /* */ + /* lcd_filter :: If subpixel rendering is activated, the */ + /* selected LCD filter mode. */ + /* */ + /* lcd_extra :: If subpixel rendering is activated, the number */ + /* of extra pixels needed for the LCD filter. */ + /* */ + /* lcd_weights :: If subpixel rendering is activated, the LCD */ + /* filter weights, if any. */ + /* */ + /* lcd_filter_func :: If subpixel rendering is activated, the LCD */ + /* filtering callback function. */ + /* */ + /* pic_container :: Contains global structs and tables, instead */ + /* of defining them globallly. */ + /* */ + /* refcount :: A counter initialized to~1 at the time an */ + /* @FT_Library structure is created. */ + /* @FT_Reference_Library increments this counter, */ + /* and @FT_Done_Library only destroys a library */ + /* if the counter is~1, otherwise it simply */ + /* decrements it. */ + /* */ + typedef struct FT_LibraryRec_ + { + FT_Memory memory; /* library's memory manager */ + + FT_Int version_major; + FT_Int version_minor; + FT_Int version_patch; + + FT_UInt num_modules; + FT_Module modules[FT_MAX_MODULES]; /* module objects */ + + FT_ListRec renderers; /* list of renderers */ + FT_Renderer cur_renderer; /* current outline renderer */ + FT_Module auto_hinter; + + FT_Byte* raster_pool; /* scan-line conversion */ + /* render pool */ + FT_ULong raster_pool_size; /* size of render pool in bytes */ + + 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 + +#ifdef FT_CONFIG_OPTION_PIC + FT_PIC_Container pic_container; +#endif + + FT_Int refcount; + + } FT_LibraryRec; + + + FT_BASE( FT_Renderer ) + FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode* node ); + + FT_BASE( FT_Error ) + FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + typedef const char* + (*FT_Face_GetPostscriptNameFunc)( FT_Face face ); + + typedef FT_Error + (*FT_Face_GetGlyphNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_Face_GetGlyphNameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory */ + /* */ + /* <Description> */ + /* Creates a new memory object. */ + /* */ + /* <Return> */ + /* A pointer to the new memory object. 0 in case of error. */ + /* */ + FT_BASE( FT_Memory ) + FT_New_Memory( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Memory */ + /* */ + /* <Description> */ + /* Discards memory manager. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* */ + FT_BASE( void ) + FT_Done_Memory( FT_Memory memory ); + +#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* Define default raster's interface. The default raster is located in */ + /* `src/base/ftraster.c'. */ + /* */ + /* Client applications can register new rasters through the */ + /* FT_Set_Raster() API. */ + +#ifndef FT_NO_DEFAULT_RASTER + FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** P I C S U P P O R T ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* PIC support macros for ftimage.h */ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_OUTLINE_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Outline_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_OUTLINE_FUNCS( \ + class_, \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ ) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_OUTLINE_FUNCS( \ + class_, \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ ) \ + static FT_Error \ + Init_Class_ ## class_( FT_Outline_Funcs* clazz ) \ + { \ + clazz->move_to = move_to_; \ + clazz->line_to = line_to_; \ + clazz->conic_to = conic_to_; \ + clazz->cubic_to = cubic_to_; \ + clazz->shift = shift_; \ + clazz->delta = delta_; \ + \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_RASTER_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Raster_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_RASTER_FUNCS( \ + class_, \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_RASTER_FUNCS( \ + class_, \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Raster_Funcs* clazz ) \ + { \ + clazz->glyph_format = glyph_format_; \ + clazz->raster_new = raster_new_; \ + clazz->raster_reset = raster_reset_; \ + clazz->raster_set_mode = raster_set_mode_; \ + clazz->raster_render = raster_render_; \ + clazz->raster_done = raster_done_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* PIC support macros for ftrender.h */ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_GLYPH */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Glyph_Class struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* be called with a pre-allocated stcture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_GLYPH( \ + class_, \ + size_, \ + format_, \ + init_, \ + done_, \ + copy_, \ + transform_, \ + bbox_, \ + prepare_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Glyph_Class class_ = \ + { \ + size_, \ + format_, \ + init_, \ + done_, \ + copy_, \ + transform_, \ + bbox_, \ + prepare_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_GLYPH( \ + class_, \ + size_, \ + format_, \ + init_, \ + done_, \ + copy_, \ + transform_, \ + bbox_, \ + prepare_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Glyph_Class* clazz ) \ + { \ + clazz->glyph_size = size_; \ + clazz->glyph_format = format_; \ + clazz->glyph_init = init_; \ + clazz->glyph_done = done_; \ + clazz->glyph_copy = copy_; \ + clazz->glyph_transform = transform_; \ + clazz->glyph_bbox = bbox_; \ + clazz->glyph_prepare = prepare_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_RENDERER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Renderer_Class struct instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_RENDERER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Renderer_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need */ + /* to be called with a pointer where the allocated structure is */ + /* returned. And when it is no longer needed a `destroy' function */ + /* needs to be called to release that allocation. */ + /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in `ftmodule.h'. */ + /* */ + /* Notice that the created `create' and `destroy' functions call */ + /* `pic_init' and `pic_free' to allow you to manually allocate and */ + /* initialize any additional global data, like a module specific */ + /* interface, and put them in the global pic container defined in */ + /* `ftpic.h'. If you don't need them just implement the functions as */ + /* empty to resolve the link error. Also the `pic_init' and */ + /* `pic_free' functions should be declared in `pic.h', to be referred */ + /* by the renderer definition calling `FT_DEFINE_RENDERER' in the */ + /* following. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_RENDERER( class_ ) \ + FT_EXPORT_VAR( const FT_Renderer_Class ) class_; + +#define FT_DEFINE_RENDERER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + glyph_format_, \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + raster_class_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Renderer_Class class_ = \ + { \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + glyph_format_, \ + \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + \ + raster_class_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_RENDERER( class_ ) FT_DECLARE_MODULE( class_ ) + +#define FT_DEFINE_RENDERER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + glyph_format_, \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + raster_class_ ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \ + FT_Memory memory = library->memory; \ + \ + \ + class_ ## _pic_free( library ); \ + if ( rclazz ) \ + FT_FREE( rclazz ); \ + } \ + \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Renderer_Class* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ + return error; \ + \ + error = class_ ## _pic_init( library ); \ + if ( error ) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + \ + clazz->glyph_format = glyph_format_; \ + \ + clazz->render_glyph = render_glyph_; \ + clazz->transform_glyph = transform_glyph_; \ + clazz->get_glyph_cbox = get_glyph_cbox_; \ + clazz->set_mode = set_mode_; \ + \ + clazz->raster_class = raster_class_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* PIC support macros for ftmodapi.h **/ + + +#ifdef FT_CONFIG_OPTION_PIC + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Creator */ + /* */ + /* <Description> */ + /* A function used to create (allocate) a new module class object. */ + /* The object's members are initialized, but the module itself is */ + /* not. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* output_class :: Initialized with the newly allocated class. */ + /* */ + typedef FT_Error + (*FT_Module_Creator)( FT_Memory memory, + FT_Module_Class** output_class ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destroyer */ + /* */ + /* <Description> */ + /* A function used to destroy (deallocate) a module class object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* clazz :: Module class to destroy. */ + /* */ + typedef void + (*FT_Module_Destroyer)( FT_Memory memory, + FT_Module_Class* clazz ); + +#endif + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_MODULE */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Module_Class struct instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of an FT_Module_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to */ + /* be called with a pointer where the allocated structure is */ + /* returned. And when it is no longer needed a `destroy' function */ + /* needs to be called to release that allocation. */ + /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in `ftmodule.h'. */ + /* */ + /* Notice that the created `create' and `destroy' functions call */ + /* `pic_init' and `pic_free' to allow you to manually allocate and */ + /* initialize any additional global data, like a module specific */ + /* interface, and put them in the global pic container defined in */ + /* `ftpic.h'. If you don't need them just implement the functions as */ + /* empty to resolve the link error. Also the `pic_init' and */ + /* `pic_free' functions should be declared in `pic.h', to be referred */ + /* by the module definition calling `FT_DEFINE_MODULE' in the */ + /* following. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ + /* <Macro> */ + /* FT_DEFINE_ROOT_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of an FT_Module_Class struct inside */ + /* another struct that contains it or in a function that initializes */ + /* that containing struct. */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_MODULE( class_ ) \ + FT_CALLBACK_TABLE \ + const FT_Module_Class class_; + +#define FT_DEFINE_ROOT_MODULE( \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }, + +#define FT_DEFINE_MODULE( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Module_Class class_ = \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }; + + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_MODULE( class_ ) \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ); \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ); + +#define FT_DEFINE_ROOT_MODULE( \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + clazz->root.module_flags = flags_; \ + clazz->root.module_size = size_; \ + clazz->root.module_name = name_; \ + clazz->root.module_version = version_; \ + clazz->root.module_requires = requires_; \ + \ + clazz->root.module_interface = interface_; \ + \ + clazz->root.module_init = init_; \ + clazz->root.module_done = done_; \ + clazz->root.get_interface = get_interface_; + +#define FT_DEFINE_MODULE( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + class_ ## _pic_free( library ); \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Module_Class* clazz = NULL; \ + FT_Error error; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ + return error; \ + error = class_ ## _pic_init( library ); \ + if ( error ) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + clazz->module_flags = flags_; \ + clazz->module_size = size_; \ + clazz->module_name = name_; \ + clazz->module_version = version_; \ + clazz->module_requires = requires_; \ + \ + clazz->module_interface = interface_; \ + \ + clazz->module_init = init_; \ + clazz->module_done = done_; \ + clazz->get_interface = get_interface_; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +FT_END_HEADER + +#endif /* __FTOBJS_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftpic.h b/drivers/freetype/include/freetype/internal/ftpic.h new file mode 100644 index 0000000000..485ce7a24e --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftpic.h @@ -0,0 +1,71 @@ +/***************************************************************************/ +/* */ +/* ftpic.h */ +/* */ +/* The FreeType position independent code services (declaration). */ +/* */ +/* Copyright 2009, 2012 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Modules that ordinarily have const global data that need address */ + /* can instead define pointers here. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTPIC_H__ +#define __FTPIC_H__ + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC + + typedef struct FT_PIC_Container_ + { + /* pic containers for base */ + void* base; + + /* pic containers for modules */ + void* autofit; + void* cff; + void* pshinter; + void* psnames; + void* raster; + void* sfnt; + void* smooth; + void* truetype; + + } FT_PIC_Container; + + + /* Initialize the various function tables, structs, etc. */ + /* stored in the container. */ + FT_BASE( FT_Error ) + ft_pic_container_init( FT_Library library ); + + + /* Destroy the contents of the container. */ + FT_BASE( void ) + ft_pic_container_destroy( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftrfork.h b/drivers/freetype/include/freetype/internal/ftrfork.h new file mode 100644 index 0000000000..6307f2d0c5 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftrfork.h @@ -0,0 +1,258 @@ +/***************************************************************************/ +/* */ +/* ftrfork.h */ +/* */ +/* Embedded resource forks accessor (specification). */ +/* */ +/* Copyright 2004, 2006, 2007, 2012 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#ifndef __FTRFORK_H__ +#define __FTRFORK_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Number of guessing rules supported in `FT_Raccess_Guess'. */ + /* Don't forget to increment the number if you add a new guessing rule. */ +#define FT_RACCESS_N_RULES 9 + + + /* A structure to describe a reference in a resource by its resource ID */ + /* and internal offset. The `POST' resource expects to be concatenated */ + /* by the order of resource IDs instead of its appearance in the file. */ + + typedef struct FT_RFork_Ref_ + { + FT_UShort res_id; + FT_ULong offset; + + } FT_RFork_Ref; + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK + typedef FT_Error + (*ft_raccess_guess_func)( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + typedef enum FT_RFork_Rule_ { + FT_RFork_Rule_invalid = -2, + FT_RFork_Rule_uknown, /* -1 */ + FT_RFork_Rule_apple_double, + FT_RFork_Rule_apple_single, + FT_RFork_Rule_darwin_ufs_export, + FT_RFork_Rule_darwin_newvfs, + FT_RFork_Rule_darwin_hfsplus, + FT_RFork_Rule_vfat, + FT_RFork_Rule_linux_cap, + FT_RFork_Rule_linux_double, + FT_RFork_Rule_linux_netatalk + } FT_RFork_Rule; + + /* For fast translation between rule index and rule type, + * the macros FT_RFORK_xxx should be kept consistent with + * the raccess_guess_funcs table + */ + typedef struct ft_raccess_guess_rec_ { + ft_raccess_guess_func func; + FT_RFork_Rule type; + } ft_raccess_guess_rec; + +#ifndef FT_CONFIG_OPTION_PIC + + /* this array is a storage in non-PIC mode, so ; is needed in END */ +#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ + const type name[] = { +#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ + { raccess_guess_ ## func_suffix, \ + FT_RFork_Rule_ ## type_suffix }, +#define CONST_FT_RFORK_RULE_ARRAY_END }; + +#else /* FT_CONFIG_OPTION_PIC */ + + /* this array is a function in PIC mode, so no ; is needed in END */ +#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ + void \ + FT_Init_ ## name( type* storage ) \ + { \ + type* local = storage; \ + \ + \ + int i = 0; +#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ + local[i].func = raccess_guess_ ## func_suffix; \ + local[i].type = FT_RFork_Rule_ ## type_suffix; \ + i++; +#define CONST_FT_RFORK_RULE_ARRAY_END } + +#endif /* FT_CONFIG_OPTION_PIC */ + +#endif /* FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Guess */ + /* */ + /* <Description> */ + /* Guess a file name and offset where the actual resource fork is */ + /* stored. The macro FT_RACCESS_N_RULES holds the number of */ + /* guessing rules; the guessed result for the Nth rule is */ + /* represented as a triplet: a new file name (new_names[N]), a file */ + /* offset (offsets[N]), and an error code (errors[N]). */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* base_name :: */ + /* The (base) file name of the resource fork used for some */ + /* guessing rules. */ + /* */ + /* <Output> */ + /* new_names :: */ + /* An array of guessed file names in which the resource forks may */ + /* exist. If `new_names[N]' is NULL, the guessed file name is */ + /* equal to `base_name'. */ + /* */ + /* offsets :: */ + /* An array of guessed file offsets. `offsets[N]' holds the file */ + /* offset of the possible start of the resource fork in file */ + /* `new_names[N]'. */ + /* */ + /* errors :: */ + /* An array of FreeType error codes. `errors[N]' is the error */ + /* code of Nth guessing rule function. If `errors[N]' is not */ + /* FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless. */ + /* */ + FT_BASE( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char** new_names, + FT_Long* offsets, + FT_Error* errors ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_HeaderInfo */ + /* */ + /* <Description> */ + /* Get the information from the header of resource fork. The */ + /* information includes the file offset where the resource map */ + /* starts, and the file offset where the resource data starts. */ + /* `FT_Raccess_Get_DataOffsets' requires these two data. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* rfork_offset :: */ + /* The file offset where the resource fork starts. */ + /* */ + /* <Output> */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_DataOffsets */ + /* */ + /* <Description> */ + /* Get the data offsets for a tag in a resource fork. Offsets are */ + /* stored in an array because, in some cases, resources in a resource */ + /* fork have the same tag. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* tag :: */ + /* The resource tag. */ + /* */ + /* <Output> */ + /* offsets :: */ + /* The stream offsets for the resource data specified by `tag'. */ + /* This array is allocated by the function, so you have to call */ + /* @ft_mem_free after use. */ + /* */ + /* count :: */ + /* The length of offsets array. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + /* <Note> */ + /* Normally you should use `FT_Raccess_Get_HeaderInfo' to get the */ + /* value for `map_offset' and `rdata_pos'. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Long **offsets, + FT_Long *count ); + + +FT_END_HEADER + +#endif /* __FTRFORK_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftserv.h b/drivers/freetype/include/freetype/internal/ftserv.h new file mode 100644 index 0000000000..cd5fbd0fac --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftserv.h @@ -0,0 +1,763 @@ +/***************************************************************************/ +/* */ +/* ftserv.h */ +/* */ +/* The FreeType services (specification only). */ +/* */ +/* Copyright 2003-2007, 2009, 2012, 2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each module can export one or more `services'. Each service is */ + /* identified by a constant string and modeled by a pointer; the latter */ + /* generally corresponds to a structure containing function pointers. */ + /* */ + /* Note that a service's data cannot be a mere function pointer because */ + /* in C it is possible that function pointers might be implemented */ + /* differently than data pointers (e.g. 48 bits instead of 32). */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSERV_H__ +#define __FTSERV_H__ + + +FT_BEGIN_HEADER + + /* + * @macro: + * FT_FACE_FIND_SERVICE + * + * @description: + * This macro is used to look up a service from a face's driver module. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#ifdef __cplusplus + +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_ = NULL; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + if ( module->clazz->get_interface ) \ + _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + *_pptr_ = _tmp_; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_ = NULL; \ + \ + if ( module->clazz->get_interface ) \ + _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + ptr = _tmp_; \ + FT_END_STMNT + +#endif /* !C++ */ + + + /* + * @macro: + * FT_FACE_FIND_GLOBAL_SERVICE + * + * @description: + * This macro is used to look up a service from all modules. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#ifdef __cplusplus + +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + *_pptr_ = _tmp_; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + ptr = _tmp_; \ + FT_END_STMNT + +#endif /* !C++ */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E D E S C R I P T O R S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The following structure is used to _describe_ a given service + * to the library. This is useful to build simple static service lists. + */ + typedef struct FT_ServiceDescRec_ + { + const char* serv_id; /* service name */ + const void* serv_data; /* service pointer/data */ + + } FT_ServiceDescRec; + + typedef const FT_ServiceDescRec* FT_ServiceDesc; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_SERVICEDESCREC1 */ + /* FT_DEFINE_SERVICEDESCREC2 */ + /* FT_DEFINE_SERVICEDESCREC3 */ + /* FT_DEFINE_SERVICEDESCREC4 */ + /* FT_DEFINE_SERVICEDESCREC5 */ + /* FT_DEFINE_SERVICEDESCREC6 */ + /* FT_DEFINE_SERVICEDESCREC7 */ + /* */ + /* <Description> */ + /* Used to initialize an array of FT_ServiceDescRec structures. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs to */ + /* be called with a pointer to return an allocated array. As soon as */ + /* it is no longer needed, a `destroy' function needs to be called to */ + /* release that allocation. */ + /* */ + /* These functions should be manually called from the `pic_init' and */ + /* `pic_free' functions of your module (see FT_DEFINE_MODULE). */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the array will be */ + /* allocated in the global scope (or the scope where the macro is */ + /* used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICEDESCREC1( class_, \ + serv_id_1, serv_data_1 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC2( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC3( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC4( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC5( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC6( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC7( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { serv_id_7, serv_data_7 }, \ + { NULL, NULL } \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICEDESCREC1( class_, \ + serv_id_1, serv_data_1 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = NULL; \ + clazz[1].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC2( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = NULL; \ + clazz[2].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC3( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = NULL; \ + clazz[3].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC4( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = NULL; \ + clazz[4].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC5( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = NULL; \ + clazz[5].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC6( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = NULL; \ + clazz[6].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC7( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = serv_id_7; \ + clazz[6].serv_data = serv_data_7; \ + clazz[7].serv_id = NULL; \ + clazz[7].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* + * Parse a list of FT_ServiceDescRec descriptors and look for + * a specific service by ID. Note that the last element in the + * array must be { NULL, NULL }, and that the function should + * return NULL if the service isn't available. + * + * This function can be used by modules to implement their + * `get_service' method. + */ + FT_BASE( FT_Pointer ) + ft_service_list_lookup( FT_ServiceDesc service_descriptors, + const char* service_id ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E S C A C H E *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * This structure is used to store a cache for several frequently used + * services. It is the type of `face->internal->services'. You + * should only use FT_FACE_LOOKUP_SERVICE to access it. + * + * All fields should have the type FT_Pointer to relax compilation + * dependencies. We assume the developer isn't completely stupid. + * + * Each field must be named `service_XXXX' where `XXX' corresponds to + * the correct FT_SERVICE_ID_XXXX macro. See the definition of + * FT_FACE_LOOKUP_SERVICE below how this is implemented. + * + */ + typedef struct FT_ServiceCacheRec_ + { + FT_Pointer service_POSTSCRIPT_FONT_NAME; + FT_Pointer service_MULTI_MASTERS; + FT_Pointer service_GLYPH_DICT; + FT_Pointer service_PFR_METRICS; + FT_Pointer service_WINFNT; + + } FT_ServiceCacheRec, *FT_ServiceCache; + + + /* + * A magic number used within the services cache. + */ + + /* ensure that value `1' has the same width as a pointer */ +#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~(FT_PtrDist)1) + + + /* + * @macro: + * FT_FACE_LOOKUP_SERVICE + * + * @description: + * This macro is used to lookup a service from a face's driver module + * using its cache. + * + * @input: + * face:: + * The source face handle containing the cache. + * + * field :: + * The field name in the cache. + * + * id :: + * The service ID. + * + * @output: + * ptr :: + * A variable receiving the service data. NULL if not available. + */ +#ifdef __cplusplus + +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Pointer svc; \ + FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \ + \ + \ + svc = FT_FACE( face )->internal->services. service_ ## id; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE( face )->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + *Pptr = svc; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Pointer svc; \ + \ + \ + svc = FT_FACE( face )->internal->services. service_ ## id; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE( face )->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + ptr = svc; \ + FT_END_STMNT + +#endif /* !C++ */ + + /* + * A macro used to define new service structure types. + */ + +#define FT_DEFINE_SERVICE( name ) \ + typedef struct FT_Service_ ## name ## Rec_ \ + FT_Service_ ## name ## Rec ; \ + typedef struct FT_Service_ ## name ## Rec_ \ + const * FT_Service_ ## name ; \ + struct FT_Service_ ## name ## Rec_ + + /* */ + + /* + * The header files containing the services. + */ + +#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> +#define FT_SERVICE_CID_H <freetype/internal/services/svcid.h> +#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> +#define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> +#define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> +#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> +#define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h> +#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> +#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h> +#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h> +#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h> +#define FT_SERVICE_PROPERTIES_H <freetype/internal/services/svprop.h> +#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> +#define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> +#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> +#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> +#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> +#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> + + /* */ + +FT_END_HEADER + +#endif /* __FTSERV_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftstream.h b/drivers/freetype/include/freetype/internal/ftstream.h new file mode 100644 index 0000000000..2661858320 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftstream.h @@ -0,0 +1,536 @@ +/***************************************************************************/ +/* */ +/* ftstream.h */ +/* */ +/* Stream handling (specification). */ +/* */ +/* Copyright 1996-2002, 2004-2006, 2011, 2013 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 __FTSTREAM_H__ +#define __FTSTREAM_H__ + + +#include <ft2build.h> +#include FT_SYSTEM_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* format of an 8-bit frame_op value: */ + /* */ + /* bit 76543210 */ + /* xxxxxxes */ + /* */ + /* s is set to 1 if the value is signed. */ + /* e is set to 1 if the value is little-endian. */ + /* xxx is a command. */ + +#define FT_FRAME_OP_SHIFT 2 +#define FT_FRAME_OP_SIGNED 1 +#define FT_FRAME_OP_LITTLE 2 +#define FT_FRAME_OP_COMMAND( x ) ( x >> FT_FRAME_OP_SHIFT ) + +#define FT_MAKE_FRAME_OP( command, little, sign ) \ + ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign ) + +#define FT_FRAME_OP_END 0 +#define FT_FRAME_OP_START 1 /* start a new frame */ +#define FT_FRAME_OP_BYTE 2 /* read 1-byte value */ +#define FT_FRAME_OP_SHORT 3 /* read 2-byte value */ +#define FT_FRAME_OP_LONG 4 /* read 4-byte value */ +#define FT_FRAME_OP_OFF3 5 /* read 3-byte value */ +#define FT_FRAME_OP_BYTES 6 /* read a bytes sequence */ + + + typedef enum FT_Frame_Op_ + { + ft_frame_end = 0, + ft_frame_start = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ), + + ft_frame_byte = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 0 ), + ft_frame_schar = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 1 ), + + ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ), + ft_frame_short_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ), + ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ), + ft_frame_short_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ), + + ft_frame_ulong_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ), + ft_frame_long_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ), + ft_frame_ulong_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ), + ft_frame_long_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ), + + ft_frame_uoff3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ), + ft_frame_off3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ), + ft_frame_uoff3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ), + ft_frame_off3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ), + + ft_frame_bytes = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ), + ft_frame_skip = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 ) + + } FT_Frame_Op; + + + typedef struct FT_Frame_Field_ + { + FT_Byte value; + FT_Byte size; + FT_UShort offset; + + } FT_Frame_Field; + + + /* Construct an FT_Frame_Field out of a structure type and a field name. */ + /* The structure type must be set in the FT_STRUCTURE macro before */ + /* calling the FT_FRAME_START() macro. */ + /* */ +#define FT_FIELD_SIZE( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f ) + +#define FT_FIELD_SIZE_DELTA( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] ) + +#define FT_FIELD_OFFSET( f ) \ + (FT_UShort)( offsetof( FT_STRUCTURE, f ) ) + +#define FT_FRAME_FIELD( frame_op, field ) \ + { \ + frame_op, \ + FT_FIELD_SIZE( field ), \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_MAKE_EMPTY_FIELD( frame_op ) { frame_op, 0, 0 } + +#define FT_FRAME_START( size ) { ft_frame_start, 0, size } +#define FT_FRAME_END { ft_frame_end, 0, 0 } + +#define FT_FRAME_LONG( f ) FT_FRAME_FIELD( ft_frame_long_be, f ) +#define FT_FRAME_ULONG( f ) FT_FRAME_FIELD( ft_frame_ulong_be, f ) +#define FT_FRAME_SHORT( f ) FT_FRAME_FIELD( ft_frame_short_be, f ) +#define FT_FRAME_USHORT( f ) FT_FRAME_FIELD( ft_frame_ushort_be, f ) +#define FT_FRAME_OFF3( f ) FT_FRAME_FIELD( ft_frame_off3_be, f ) +#define FT_FRAME_UOFF3( f ) FT_FRAME_FIELD( ft_frame_uoff3_be, f ) +#define FT_FRAME_BYTE( f ) FT_FRAME_FIELD( ft_frame_byte, f ) +#define FT_FRAME_CHAR( f ) FT_FRAME_FIELD( ft_frame_schar, f ) + +#define FT_FRAME_LONG_LE( f ) FT_FRAME_FIELD( ft_frame_long_le, f ) +#define FT_FRAME_ULONG_LE( f ) FT_FRAME_FIELD( ft_frame_ulong_le, f ) +#define FT_FRAME_SHORT_LE( f ) FT_FRAME_FIELD( ft_frame_short_le, f ) +#define FT_FRAME_USHORT_LE( f ) FT_FRAME_FIELD( ft_frame_ushort_le, f ) +#define FT_FRAME_OFF3_LE( f ) FT_FRAME_FIELD( ft_frame_off3_le, f ) +#define FT_FRAME_UOFF3_LE( f ) FT_FRAME_FIELD( ft_frame_uoff3_le, f ) + +#define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } +#define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } +#define FT_FRAME_SKIP_BYTE { ft_frame_byte, 0, 0 } + +#define FT_FRAME_BYTES( field, count ) \ + { \ + ft_frame_bytes, \ + count, \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } + + + /*************************************************************************/ + /* */ + /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */ + /* type `char*' or equivalent (1-byte elements). */ + /* */ + +#define FT_BYTE_( p, i ) ( ((const FT_Byte*)(p))[(i)] ) + +#define FT_INT16( x ) ( (FT_Int16)(x) ) +#define FT_UINT16( x ) ( (FT_UInt16)(x) ) +#define FT_INT32( x ) ( (FT_Int32)(x) ) +#define FT_UINT32( x ) ( (FT_UInt32)(x) ) + + +#define FT_BYTE_U16( p, i, s ) ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) + + +#define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8) | \ + FT_BYTE_U16( p, 1, 0) ) + +#define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \ + FT_BYTE_U16( p, 1, 0 ) ) + +#define FT_PEEK_LONG( p ) FT_INT32( FT_BYTE_U32( p, 0, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 2, 8 ) | \ + FT_BYTE_U32( p, 3, 0 ) ) + +#define FT_PEEK_ULONG( p ) FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 2, 8 ) | \ + FT_BYTE_U32( p, 3, 0 ) ) + +#define FT_PEEK_OFF3( p ) FT_INT32( FT_BYTE_U32( p, 0, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 2, 0 ) ) + +#define FT_PEEK_UOFF3( p ) FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 2, 0 ) ) + +#define FT_PEEK_SHORT_LE( p ) FT_INT16( FT_BYTE_U16( p, 1, 8 ) | \ + FT_BYTE_U16( p, 0, 0 ) ) + +#define FT_PEEK_USHORT_LE( p ) FT_UINT16( FT_BYTE_U16( p, 1, 8 ) | \ + FT_BYTE_U16( p, 0, 0 ) ) + +#define FT_PEEK_LONG_LE( p ) FT_INT32( FT_BYTE_U32( p, 3, 24 ) | \ + FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_ULONG_LE( p ) FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \ + FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_UOFF3_LE( p ) FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + + +#define FT_NEXT_CHAR( buffer ) \ + ( (signed char)*buffer++ ) + +#define FT_NEXT_BYTE( buffer ) \ + ( (unsigned char)*buffer++ ) + +#define FT_NEXT_SHORT( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) ) + +#define FT_NEXT_LONG( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) ) + + +#define FT_NEXT_SHORT_LE( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT_LE( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3_LE( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3_LE( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_LONG_LE( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG_LE( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) ) + + + /*************************************************************************/ + /* */ + /* Each GET_xxxx() macro uses an implicit `stream' variable. */ + /* */ +#if 0 +#define FT_GET_MACRO( type ) FT_NEXT_ ## type ( stream->cursor ) + +#define FT_GET_CHAR() FT_GET_MACRO( CHAR ) +#define FT_GET_BYTE() FT_GET_MACRO( BYTE ) +#define FT_GET_SHORT() FT_GET_MACRO( SHORT ) +#define FT_GET_USHORT() FT_GET_MACRO( USHORT ) +#define FT_GET_OFF3() FT_GET_MACRO( OFF3 ) +#define FT_GET_UOFF3() FT_GET_MACRO( UOFF3 ) +#define FT_GET_LONG() FT_GET_MACRO( LONG ) +#define FT_GET_ULONG() FT_GET_MACRO( ULONG ) +#define FT_GET_TAG4() FT_GET_MACRO( ULONG ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( SHORT_LE ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( USHORT_LE ) +#define FT_GET_LONG_LE() FT_GET_MACRO( LONG_LE ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( ULONG_LE ) + +#else +#define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) + +#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char ) +#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte ) +#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_Short ) +#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort ) +#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_Long ) +#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong ) +#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetULong, FT_Long ) +#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong ) +#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort ) +#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong ) +#endif + +#define FT_READ_MACRO( func, type, var ) \ + ( var = (type)func( stream, &error ), \ + error != FT_Err_Ok ) + +#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) +#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) +#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var ) +#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var ) +#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_Long, var ) +#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var ) +#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var ) +#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var ) + +#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Short, var ) +#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UShort, var ) +#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Long, var ) +#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_ULong, var ) + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /* initialize a stream for reading a regular system stream */ + FT_BASE( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ); + +#endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* create a new (input) stream from an FT_Open_Args structure */ + FT_BASE( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ); + + /* free a stream */ + FT_BASE( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ); + + /* initialize a stream for reading in-memory data */ + FT_BASE( void ) + FT_Stream_OpenMemory( FT_Stream stream, + const FT_Byte* base, + FT_ULong size ); + + /* close a stream (does not destroy the stream structure) */ + FT_BASE( void ) + FT_Stream_Close( FT_Stream stream ); + + + /* seek within a stream. position is relative to start of stream */ + FT_BASE( FT_Error ) + FT_Stream_Seek( FT_Stream stream, + FT_ULong pos ); + + /* skip bytes in a stream */ + FT_BASE( FT_Error ) + FT_Stream_Skip( FT_Stream stream, + FT_Long distance ); + + /* return current stream position */ + FT_BASE( FT_Long ) + FT_Stream_Pos( FT_Stream stream ); + + /* read bytes from a stream into a user-allocated buffer, returns an */ + /* error if not all bytes could be read. */ + FT_BASE( FT_Error ) + FT_Stream_Read( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* read bytes from a stream at a given position */ + FT_BASE( FT_Error ) + FT_Stream_ReadAt( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ); + + /* try to read bytes at the end of a stream; return number of bytes */ + /* really available */ + FT_BASE( FT_ULong ) + FT_Stream_TryRead( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* Enter a frame of `count' consecutive bytes in a stream. Returns an */ + /* error if the frame could not be read/accessed. The caller can use */ + /* the FT_Stream_Get_XXX functions to retrieve frame data without */ + /* error checks. */ + /* */ + /* You must _always_ call FT_Stream_ExitFrame() once you have entered */ + /* a stream frame! */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_EnterFrame( FT_Stream stream, + FT_ULong count ); + + /* exit a stream frame */ + FT_BASE( void ) + FT_Stream_ExitFrame( FT_Stream stream ); + + /* Extract a stream frame. If the stream is disk-based, a heap block */ + /* is allocated and the frame bytes are read into it. If the stream */ + /* is memory-based, this function simply set a pointer to the data. */ + /* */ + /* Useful to optimize access to memory-based streams transparently. */ + /* */ + /* All extracted frames must be `freed' with a call to the function */ + /* FT_Stream_ReleaseFrame(). */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_ExtractFrame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ); + + /* release an extract frame (see FT_Stream_ExtractFrame) */ + FT_BASE( void ) + FT_Stream_ReleaseFrame( FT_Stream stream, + FT_Byte** pbytes ); + + /* read a byte from an entered frame */ + FT_BASE( FT_Char ) + FT_Stream_GetChar( FT_Stream stream ); + + /* read a 16-bit big-endian unsigned integer from an entered frame */ + FT_BASE( FT_UShort ) + FT_Stream_GetUShort( FT_Stream stream ); + + /* read a 24-bit big-endian unsigned integer from an entered frame */ + FT_BASE( FT_ULong ) + FT_Stream_GetUOffset( FT_Stream stream ); + + /* read a 32-bit big-endian unsigned integer from an entered frame */ + FT_BASE( FT_ULong ) + FT_Stream_GetULong( FT_Stream stream ); + + /* read a 16-bit little-endian unsigned integer from an entered frame */ + FT_BASE( FT_UShort ) + FT_Stream_GetUShortLE( FT_Stream stream ); + + /* read a 32-bit little-endian unsigned integer from an entered frame */ + FT_BASE( FT_ULong ) + FT_Stream_GetULongLE( FT_Stream stream ); + + + /* read a byte from a stream */ + FT_BASE( FT_Char ) + FT_Stream_ReadChar( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit big-endian unsigned integer from a stream */ + FT_BASE( FT_UShort ) + FT_Stream_ReadUShort( FT_Stream stream, + FT_Error* error ); + + /* read a 24-bit big-endian unsigned integer from a stream */ + FT_BASE( FT_ULong ) + FT_Stream_ReadUOffset( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit big-endian integer from a stream */ + FT_BASE( FT_ULong ) + FT_Stream_ReadULong( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit little-endian unsigned integer from a stream */ + FT_BASE( FT_UShort ) + FT_Stream_ReadUShortLE( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit little-endian unsigned integer from a stream */ + FT_BASE( FT_ULong ) + FT_Stream_ReadULongLE( FT_Stream stream, + FT_Error* error ); + + /* Read a structure from a stream. The structure must be described */ + /* by an array of FT_Frame_Field records. */ + FT_BASE( FT_Error ) + FT_Stream_ReadFields( FT_Stream stream, + const FT_Frame_Field* fields, + void* structure ); + + +#define FT_STREAM_POS() \ + FT_Stream_Pos( stream ) + +#define FT_STREAM_SEEK( position ) \ + FT_SET_ERROR( FT_Stream_Seek( stream, \ + (FT_ULong)(position) ) ) + +#define FT_STREAM_SKIP( distance ) \ + FT_SET_ERROR( FT_Stream_Skip( stream, \ + (FT_Long)(distance) ) ) + +#define FT_STREAM_READ( buffer, count ) \ + FT_SET_ERROR( FT_Stream_Read( stream, \ + (FT_Byte*)(buffer), \ + (FT_ULong)(count) ) ) + +#define FT_STREAM_READ_AT( position, buffer, count ) \ + FT_SET_ERROR( FT_Stream_ReadAt( stream, \ + (FT_ULong)(position), \ + (FT_Byte*)buffer, \ + (FT_ULong)(count) ) ) + +#define FT_STREAM_READ_FIELDS( fields, object ) \ + FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) ) + + +#define FT_FRAME_ENTER( size ) \ + FT_SET_ERROR( \ + FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, \ + (FT_ULong)(size) ) ) ) + +#define FT_FRAME_EXIT() \ + FT_DEBUG_INNER( FT_Stream_ExitFrame( stream ) ) + +#define FT_FRAME_EXTRACT( size, bytes ) \ + FT_SET_ERROR( \ + FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, \ + (FT_ULong)(size), \ + (FT_Byte**)&(bytes) ) ) ) + +#define FT_FRAME_RELEASE( bytes ) \ + FT_DEBUG_INNER( FT_Stream_ReleaseFrame( stream, \ + (FT_Byte**)&(bytes) ) ) + + +FT_END_HEADER + +#endif /* __FTSTREAM_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/fttrace.h b/drivers/freetype/include/freetype/internal/fttrace.h new file mode 100644 index 0000000000..a9d98b60aa --- /dev/null +++ b/drivers/freetype/include/freetype/internal/fttrace.h @@ -0,0 +1,152 @@ +/***************************************************************************/ +/* */ +/* fttrace.h */ +/* */ +/* Tracing handling (specification only). */ +/* */ +/* Copyright 2002, 2004-2007, 2009, 2011-2013 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. */ +/* */ +/***************************************************************************/ + + + /* definitions of trace levels for FreeType 2 */ + + /* the first level must always be `trace_any' */ +FT_TRACE_DEF( any ) + + /* base components */ +FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ +FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ +FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ +FT_TRACE_DEF( io ) /* i/o interface (ftsystem.c) */ +FT_TRACE_DEF( list ) /* list management (ftlist.c) */ +FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ +FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ +FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ +FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ +FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ + +FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ +FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ +FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ +FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ +FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ +FT_TRACE_DEF( bitmap ) /* bitmap checksum (ftobjs.c) */ + + /* Cache sub-system */ +FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ + + /* SFNT driver components */ +FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ +FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ +FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ +FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ +FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ +FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ +FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ +FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ +FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ + + /* TrueType driver components */ +FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ +FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */ +FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */ +FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */ +FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ +FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ + + /* Type 1 driver components */ +FT_TRACE_DEF( t1afm ) +FT_TRACE_DEF( t1driver ) +FT_TRACE_DEF( t1gload ) +FT_TRACE_DEF( t1hint ) +FT_TRACE_DEF( t1load ) +FT_TRACE_DEF( t1objs ) +FT_TRACE_DEF( t1parse ) + + /* PostScript helper module `psaux' */ +FT_TRACE_DEF( t1decode ) +FT_TRACE_DEF( psobjs ) +FT_TRACE_DEF( psconv ) + + /* PostScript hinting module `pshinter' */ +FT_TRACE_DEF( pshrec ) +FT_TRACE_DEF( pshalgo1 ) +FT_TRACE_DEF( pshalgo2 ) + + /* Type 2 driver components */ +FT_TRACE_DEF( cffdriver ) +FT_TRACE_DEF( cffgload ) +FT_TRACE_DEF( cffload ) +FT_TRACE_DEF( cffobjs ) +FT_TRACE_DEF( cffparse ) + +FT_TRACE_DEF( cf2blues ) +FT_TRACE_DEF( cf2hints ) +FT_TRACE_DEF( cf2interp ) + + /* Type 42 driver component */ +FT_TRACE_DEF( t42 ) + + /* CID driver components */ +FT_TRACE_DEF( cidafm ) +FT_TRACE_DEF( ciddriver ) +FT_TRACE_DEF( cidgload ) +FT_TRACE_DEF( cidload ) +FT_TRACE_DEF( cidobjs ) +FT_TRACE_DEF( cidparse ) + + /* Windows font component */ +FT_TRACE_DEF( winfnt ) + + /* PCF font components */ +FT_TRACE_DEF( pcfdriver ) +FT_TRACE_DEF( pcfread ) + + /* BDF font components */ +FT_TRACE_DEF( bdfdriver ) +FT_TRACE_DEF( bdflib ) + + /* PFR font component */ +FT_TRACE_DEF( pfr ) + + /* OpenType validation components */ +FT_TRACE_DEF( otvmodule ) +FT_TRACE_DEF( otvcommon ) +FT_TRACE_DEF( otvbase ) +FT_TRACE_DEF( otvgdef ) +FT_TRACE_DEF( otvgpos ) +FT_TRACE_DEF( otvgsub ) +FT_TRACE_DEF( otvjstf ) +FT_TRACE_DEF( otvmath ) + + /* TrueTypeGX/AAT validation components */ +FT_TRACE_DEF( gxvmodule ) +FT_TRACE_DEF( gxvcommon ) +FT_TRACE_DEF( gxvfeat ) +FT_TRACE_DEF( gxvmort ) +FT_TRACE_DEF( gxvmorx ) +FT_TRACE_DEF( gxvbsln ) +FT_TRACE_DEF( gxvjust ) +FT_TRACE_DEF( gxvkern ) +FT_TRACE_DEF( gxvopbd ) +FT_TRACE_DEF( gxvtrak ) +FT_TRACE_DEF( gxvprop ) +FT_TRACE_DEF( gxvlcar ) + + /* autofit components */ +FT_TRACE_DEF( afmodule ) +FT_TRACE_DEF( afhints ) +FT_TRACE_DEF( afcjk ) +FT_TRACE_DEF( aflatin ) +FT_TRACE_DEF( aflatin2 ) +FT_TRACE_DEF( afwarp ) + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftvalid.h b/drivers/freetype/include/freetype/internal/ftvalid.h new file mode 100644 index 0000000000..12ad03685a --- /dev/null +++ b/drivers/freetype/include/freetype/internal/ftvalid.h @@ -0,0 +1,161 @@ +/***************************************************************************/ +/* */ +/* ftvalid.h */ +/* */ +/* FreeType validation support (specification). */ +/* */ +/* Copyright 2004, 2013 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 __FTVALID_H__ +#define __FTVALID_H__ + +#include <ft2build.h> +#include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** V A L I D A T I O N ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to a validation object */ + typedef struct FT_ValidatorRec_ volatile* FT_Validator; + + + /*************************************************************************/ + /* */ + /* There are three distinct validation levels defined here: */ + /* */ + /* FT_VALIDATE_DEFAULT :: */ + /* A table that passes this validation level can be used reliably by */ + /* FreeType. It generally means that all offsets have been checked to */ + /* prevent out-of-bound reads, that array counts are correct, etc. */ + /* */ + /* FT_VALIDATE_TIGHT :: */ + /* A table that passes this validation level can be used reliably and */ + /* doesn't contain invalid data. For example, a charmap table that */ + /* returns invalid glyph indices will not pass, even though it can */ + /* be used with FreeType in default mode (the library will simply */ + /* return an error later when trying to load the glyph). */ + /* */ + /* It also checks that fields which must be a multiple of 2, 4, or 8, */ + /* don't have incorrect values, etc. */ + /* */ + /* FT_VALIDATE_PARANOID :: */ + /* Only for font debugging. Checks that a table follows the */ + /* specification by 100%. Very few fonts will be able to pass this */ + /* level anyway but it can be useful for certain tools like font */ + /* editors/converters. */ + /* */ + typedef enum FT_ValidationLevel_ + { + FT_VALIDATE_DEFAULT = 0, + FT_VALIDATE_TIGHT, + FT_VALIDATE_PARANOID + + } FT_ValidationLevel; + + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + /* We disable the warning `structure was padded due to */ + /* __declspec(align())' in order to compile cleanly with */ + /* the maximum level of warnings. */ +#pragma warning( push ) +#pragma warning( disable : 4324 ) +#endif /* _MSC_VER */ + + /* validator structure */ + typedef struct FT_ValidatorRec_ + { + const FT_Byte* base; /* address of table in memory */ + const FT_Byte* limit; /* `base' + sizeof(table) in memory */ + FT_ValidationLevel level; /* validation level */ + FT_Error error; /* error returned. 0 means success */ + + ft_jmp_buf jump_buffer; /* used for exception handling */ + + } FT_ValidatorRec; + +#if defined( _MSC_VER ) +#pragma warning( pop ) +#endif + +#define FT_VALIDATOR( x ) ( (FT_Validator)( x ) ) + + + FT_BASE( void ) + ft_validator_init( FT_Validator valid, + const FT_Byte* base, + 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 ); + + /* Sets the error field in a validator, then calls `longjmp' to return */ + /* to high-level caller. Using `setjmp/longjmp' avoids many stupid */ + /* error checks within the validation routines. */ + /* */ + FT_BASE( void ) + ft_validator_error( FT_Validator valid, + FT_Error error ); + + + /* Calls ft_validate_error. Assumes that the `valid' local variable */ + /* holds a pointer to the current validator object. */ + /* */ + /* Use preprocessor prescan to pass FT_ERR_PREFIX. */ + /* */ +#define FT_INVALID( _prefix, _error ) FT_INVALID_( _prefix, _error ) +#define FT_INVALID_( _prefix, _error ) \ + ft_validator_error( valid, _prefix ## _error ) + + /* called when a broken table is detected */ +#define FT_INVALID_TOO_SHORT \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + /* called when an invalid offset is detected */ +#define FT_INVALID_OFFSET \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Offset ) + + /* called when an invalid format/value is detected */ +#define FT_INVALID_FORMAT \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + /* called when an invalid glyph index is detected */ +#define FT_INVALID_GLYPH_ID \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index ) + + /* called when an invalid field value is detected */ +#define FT_INVALID_DATA \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + +FT_END_HEADER + +#endif /* __FTVALID_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/internal.h b/drivers/freetype/include/freetype/internal/internal.h new file mode 100644 index 0000000000..262afcfa8a --- /dev/null +++ b/drivers/freetype/include/freetype/internal/internal.h @@ -0,0 +1,63 @@ +/***************************************************************************/ +/* */ +/* internal.h */ +/* */ +/* Internal header files (specification only). */ +/* */ +/* Copyright 1996-2004, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is automatically included by `ft2build.h'. */ + /* Do not include it manually! */ + /* */ + /*************************************************************************/ + + +#define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> +#define FT_INTERNAL_PIC_H <freetype/internal/ftpic.h> +#define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> +#define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> +#define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> +#define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> +#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> +#define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> +#define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> +#define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> +#define FT_INTERNAL_SERVICE_H <freetype/internal/ftserv.h> +#define FT_INTERNAL_RFORK_H <freetype/internal/ftrfork.h> +#define FT_INTERNAL_VALIDATE_H <freetype/internal/ftvalid.h> + +#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> +#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> + +#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> +#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> +#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> + +#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> + + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + + /* We disable the warning `conditional expression is constant' here */ + /* in order to compile cleanly with the maximum level of warnings. */ + /* In particular, the warning complains about stuff like `while(0)' */ + /* which is very useful in macro definitions. There is no benefit */ + /* in having it enabled. */ +#pragma warning( disable : 4127 ) + +#endif /* _MSC_VER */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/psaux.h b/drivers/freetype/include/freetype/internal/psaux.h new file mode 100644 index 0000000000..e903114f84 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/psaux.h @@ -0,0 +1,877 @@ +/***************************************************************************/ +/* */ +/* psaux.h */ +/* */ +/* Auxiliary functions and data structures related to PostScript fonts */ +/* (specification). */ +/* */ +/* Copyright 1996-2004, 2006, 2008, 2009, 2012 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 __PSAUX_H__ +#define __PSAUX_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct PS_TableRec_* PS_Table; + typedef const struct PS_Table_FuncsRec_* PS_Table_Funcs; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Table_FuncsRec */ + /* */ + /* <Description> */ + /* A set of function pointers to manage PS_Table objects. */ + /* */ + /* <Fields> */ + /* table_init :: Used to initialize a table. */ + /* */ + /* table_done :: Finalizes resp. destroy a given table. */ + /* */ + /* table_add :: Adds a new object to a table. */ + /* */ + /* table_release :: Releases table data, then finalizes it. */ + /* */ + typedef struct PS_Table_FuncsRec_ + { + FT_Error + (*init)( PS_Table table, + FT_Int count, + FT_Memory memory ); + + void + (*done)( PS_Table table ); + + FT_Error + (*add)( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ); + + void + (*release)( PS_Table table ); + + } PS_Table_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_TableRec */ + /* */ + /* <Description> */ + /* A PS_Table is a simple object used to store an array of objects in */ + /* a single memory block. */ + /* */ + /* <Fields> */ + /* block :: The address in memory of the growheap's block. This */ + /* can change between two object adds, due to */ + /* reallocation. */ + /* */ + /* cursor :: The current top of the grow heap within its block. */ + /* */ + /* capacity :: The current size of the heap block. Increments by */ + /* 1kByte chunks. */ + /* */ + /* init :: Set to 0xDEADBEEF if `elements' and `lengths' have */ + /* been allocated. */ + /* */ + /* max_elems :: The maximum number of elements in table. */ + /* */ + /* num_elems :: The current number of elements in table. */ + /* */ + /* elements :: A table of element addresses within the block. */ + /* */ + /* lengths :: A table of element sizes within the block. */ + /* */ + /* memory :: The object used for memory operations */ + /* (alloc/realloc). */ + /* */ + /* funcs :: A table of method pointers for this object. */ + /* */ + typedef struct PS_TableRec_ + { + FT_Byte* block; /* current memory block */ + FT_Offset cursor; /* current cursor in memory block */ + FT_Offset capacity; /* current size of memory block */ + FT_Long init; + + FT_Int max_elems; + FT_Int num_elems; + FT_Byte** elements; /* addresses of table elements */ + FT_PtrDist* lengths; /* lengths of table elements */ + + FT_Memory memory; + PS_Table_FuncsRec funcs; + + } PS_TableRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 FIELDS & TOKENS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PS_ParserRec_* PS_Parser; + + typedef struct T1_TokenRec_* T1_Token; + + typedef struct T1_FieldRec_* T1_Field; + + + /* simple enumeration type used to identify token types */ + typedef enum T1_TokenType_ + { + T1_TOKEN_TYPE_NONE = 0, + 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 + + } T1_TokenType; + + + /* a simple structure used to identify tokens */ + typedef struct T1_TokenRec_ + { + FT_Byte* start; /* first character of token in input stream */ + FT_Byte* limit; /* first character after the token */ + T1_TokenType type; /* type of token */ + + } T1_TokenRec; + + + /* enumeration type used to identify object fields */ + typedef enum T1_FieldType_ + { + T1_FIELD_TYPE_NONE = 0, + T1_FIELD_TYPE_BOOL, + T1_FIELD_TYPE_INTEGER, + T1_FIELD_TYPE_FIXED, + T1_FIELD_TYPE_FIXED_1000, + T1_FIELD_TYPE_STRING, + T1_FIELD_TYPE_KEY, + T1_FIELD_TYPE_BBOX, + T1_FIELD_TYPE_MM_BBOX, + T1_FIELD_TYPE_INTEGER_ARRAY, + T1_FIELD_TYPE_FIXED_ARRAY, + T1_FIELD_TYPE_CALLBACK, + + /* do not remove */ + T1_FIELD_TYPE_MAX + + } T1_FieldType; + + + typedef enum T1_FieldLocation_ + { + T1_FIELD_LOCATION_CID_INFO, + T1_FIELD_LOCATION_FONT_DICT, + T1_FIELD_LOCATION_FONT_EXTRA, + 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 + + } T1_FieldLocation; + + + typedef void + (*T1_Field_ParseFunc)( FT_Face face, + FT_Pointer parser ); + + + /* structure type used to model object fields */ + typedef struct T1_FieldRec_ + { + const char* ident; /* field identifier */ + T1_FieldLocation location; + T1_FieldType type; /* type of field */ + T1_Field_ParseFunc reader; + FT_UInt offset; /* offset of field in object */ + FT_Byte size; /* size of field in bytes */ + FT_UInt array_max; /* maximum number of elements for */ + /* array */ + FT_UInt count_offset; /* offset of element count for */ + /* arrays; must not be zero if in */ + /* use -- in other words, a */ + /* `num_FOO' element must not */ + /* start the used structure if we */ + /* parse a `FOO' array */ + 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, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE( _fname ), \ + 0, 0, \ + _dict \ + }, + +#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, _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, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, 0, \ + _dict \ + }, + + +#define T1_FIELD_BOOL( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict ) + +#define T1_FIELD_NUM( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict ) + +#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, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \ + _dict ) + +#define T1_FIELD_STRING( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict ) + +#define T1_FIELD_KEY( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict ) + +#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, _dict ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_CALLBACK( _ident, _name, _dict ) \ + T1_NEW_CALLBACK_FIELD( _ident, _name, _dict ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct PS_Parser_FuncsRec_* PS_Parser_Funcs; + + typedef struct PS_Parser_FuncsRec_ + { + void + (*init)( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + void + (*done)( PS_Parser parser ); + + void + (*skip_spaces)( PS_Parser parser ); + void + (*skip_PS_token)( PS_Parser parser ); + + FT_Long + (*to_int)( PS_Parser parser ); + FT_Fixed + (*to_fixed)( PS_Parser parser, + FT_Int power_ten ); + + FT_Error + (*to_bytes)( PS_Parser parser, + FT_Byte* bytes, + FT_Offset max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ); + + FT_Int + (*to_coord_array)( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ); + FT_Int + (*to_fixed_array)( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + void + (*to_token)( PS_Parser parser, + T1_Token token ); + void + (*to_token_array)( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + FT_Error + (*load_field)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_Error + (*load_field_table)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + } PS_Parser_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_ParserRec */ + /* */ + /* <Description> */ + /* A PS_Parser is an object used to parse a Type 1 font very quickly. */ + /* */ + /* <Fields> */ + /* cursor :: The current position in the text. */ + /* */ + /* base :: Start of the processed text. */ + /* */ + /* limit :: End of the processed text. */ + /* */ + /* error :: The last error returned. */ + /* */ + /* memory :: The object used for memory operations (alloc/realloc). */ + /* */ + /* funcs :: A table of functions for the parser. */ + /* */ + typedef struct PS_ParserRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + FT_Error error; + FT_Memory memory; + + PS_Parser_FuncsRec funcs; + + } PS_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_BuilderRec_* T1_Builder; + + + typedef FT_Error + (*T1_Builder_Check_Points_Func)( T1_Builder builder, + FT_Int count ); + + typedef void + (*T1_Builder_Add_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + typedef FT_Error + (*T1_Builder_Add_Point1_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef FT_Error + (*T1_Builder_Add_Contour_Func)( T1_Builder builder ); + + typedef FT_Error + (*T1_Builder_Start_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef void + (*T1_Builder_Close_Contour_Func)( T1_Builder builder ); + + + typedef const struct T1_Builder_FuncsRec_* T1_Builder_Funcs; + + typedef struct T1_Builder_FuncsRec_ + { + void + (*init)( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Bool hinting ); + + void + (*done)( T1_Builder builder ); + + T1_Builder_Check_Points_Func check_points; + T1_Builder_Add_Point_Func add_point; + T1_Builder_Add_Point1_Func add_point1; + T1_Builder_Add_Contour_Func add_contour; + T1_Builder_Start_Point_Func start_point; + T1_Builder_Close_Contour_Func close_contour; + + } T1_Builder_FuncsRec; + + + /* an enumeration type to handle charstring parsing states */ + typedef enum T1_ParseState_ + { + T1_Parse_Start, + T1_Parse_Have_Width, + T1_Parse_Have_Moveto, + T1_Parse_Have_Path + + } T1_ParseState; + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* T1_BuilderRec */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: XXX */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* max_points :: maximum points in builder outline */ + /* */ + /* max_contours :: Maximum number of contours in builder outline. */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* parse_state :: An enumeration which controls the charstring */ + /* parsing state. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* funcs :: An array of function pointers for the builder. */ + /* */ + typedef struct T1_BuilderRec_ + { + FT_Memory memory; + FT_Face face; + FT_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + T1_ParseState parse_state; + FT_Bool load_points; + FT_Bool no_recurse; + + FT_Bool metrics_only; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + T1_Builder_FuncsRec funcs; + + } T1_BuilderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 DECODER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 0 + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 8 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 32 + +#endif /* 0 */ + + + typedef struct T1_Decoder_ZoneRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + + } T1_Decoder_ZoneRec, *T1_Decoder_Zone; + + + typedef struct T1_DecoderRec_* T1_Decoder; + typedef const struct T1_Decoder_FuncsRec_* T1_Decoder_Funcs; + + + typedef FT_Error + (*T1_Decoder_Callback)( T1_Decoder decoder, + FT_UInt glyph_index ); + + + typedef struct T1_Decoder_FuncsRec_ + { + FT_Error + (*init)( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback callback ); + + void + (*done)( T1_Decoder decoder ); + + FT_Error + (*parse_charstrings)( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); + + } T1_Decoder_FuncsRec; + + + typedef struct T1_DecoderRec_ + { + T1_BuilderRec builder; + + FT_Long stack[T1_MAX_CHARSTRINGS_OPERANDS]; + FT_Long* top; + + T1_Decoder_ZoneRec zones[T1_MAX_SUBRS_CALLS + 1]; + T1_Decoder_Zone zone; + + FT_Service_PsCMaps psnames; /* for seac */ + FT_UInt num_glyphs; + FT_Byte** glyph_names; + + FT_Int lenIV; /* internal for sub routine calls */ + FT_UInt num_subrs; + FT_Byte** subrs; + FT_PtrDist* subrs_len; /* array of subrs length (optional) */ + + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + PS_Blend blend; /* for multiple master support */ + + FT_Render_Mode hint_mode; + + T1_Decoder_Callback parse_callback; + T1_Decoder_FuncsRec funcs; + + FT_Long* buildchar; + FT_UInt len_buildchar; + + FT_Bool seac; + + } T1_DecoderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** AFM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AFM_ParserRec_* AFM_Parser; + + typedef struct AFM_Parser_FuncsRec_ + { + FT_Error + (*init)( AFM_Parser parser, + FT_Memory memory, + FT_Byte* base, + FT_Byte* limit ); + + void + (*done)( AFM_Parser parser ); + + FT_Error + (*parse)( AFM_Parser parser ); + + } AFM_Parser_FuncsRec; + + + typedef struct AFM_StreamRec_* AFM_Stream; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AFM_ParserRec */ + /* */ + /* <Description> */ + /* An AFM_Parser is a parser for the AFM files. */ + /* */ + /* <Fields> */ + /* memory :: The object used for memory operations (alloc and */ + /* realloc). */ + /* */ + /* stream :: This is an opaque object. */ + /* */ + /* FontInfo :: The result will be stored here. */ + /* */ + /* get_index :: A user provided function to get a glyph index by its */ + /* name. */ + /* */ + typedef struct AFM_ParserRec_ + { + FT_Memory memory; + AFM_Stream stream; + + AFM_FontInfo FontInfo; + + FT_Int + (*get_index)( const char* name, + FT_Offset len, + void* user_data ); + + void* user_data; + + } AFM_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CHARMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct T1_CMap_ClassesRec_* T1_CMap_Classes; + + typedef struct T1_CMap_ClassesRec_ + { + FT_CMap_Class standard; + FT_CMap_Class expert; + FT_CMap_Class custom; + FT_CMap_Class unicode; + + } T1_CMap_ClassesRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PSAux Module Interface *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSAux_ServiceRec_ + { + /* don't use `PS_Table_Funcs' and friends to avoid compiler warnings */ + const PS_Table_FuncsRec* ps_table_funcs; + const PS_Parser_FuncsRec* ps_parser_funcs; + const T1_Builder_FuncsRec* t1_builder_funcs; + const T1_Decoder_FuncsRec* t1_decoder_funcs; + + void + (*t1_decrypt)( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + T1_CMap_Classes t1_cmap_classes; + + /* fields after this comment line were added after version 2.1.10 */ + const AFM_Parser_FuncsRec* afm_parser_funcs; + + } PSAux_ServiceRec, *PSAux_Service; + + /* 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__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/pshints.h b/drivers/freetype/include/freetype/internal/pshints.h new file mode 100644 index 0000000000..3fb18dc2d5 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/pshints.h @@ -0,0 +1,722 @@ +/***************************************************************************/ +/* */ +/* pshints.h */ +/* */ +/* Interface to Postscript-specific (Type 1 and Type 2) hints */ +/* recorders (specification only). These are used to support native */ +/* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ +/* */ +/* Copyright 2001-2003, 2005-2007, 2009, 2012 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 __PSHINTS_H__ +#define __PSHINTS_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INTERNAL REPRESENTATION OF GLOBALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSH_GlobalsRec_* PSH_Globals; + + typedef FT_Error + (*PSH_Globals_NewFunc)( FT_Memory memory, + T1_Private* private_dict, + PSH_Globals* aglobals ); + + typedef FT_Error + (*PSH_Globals_SetScaleFunc)( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ); + + typedef void + (*PSH_Globals_DestroyFunc)( PSH_Globals globals ); + + + typedef struct PSH_Globals_FuncsRec_ + { + PSH_Globals_NewFunc create; + PSH_Globals_SetScaleFunc set_scale; + PSH_Globals_DestroyFunc destroy; + + } PSH_Globals_FuncsRec, *PSH_Globals_Funcs; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 1 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * T1_Hints + * + * @description: + * This is a handle to an opaque structure used to record glyph hints + * from a Type 1 character glyph character string. + * + * The methods used to operate on this object are defined by the + * @T1_Hints_FuncsRec structure. Recording glyph hints is normally + * achieved through the following scheme: + * + * - Open a new hint recording session by calling the `open' method. + * This rewinds the recorder and prepare it for new input. + * + * - For each hint found in the glyph charstring, call the corresponding + * method (`stem', `stem3', or `reset'). Note that these functions do + * not return an error code. + * + * - Close the recording session by calling the `close' method. It + * returns an error code if the hints were invalid or something + * strange happened (e.g., memory shortage). + * + * The hints accumulated in the object can later be used by the + * PostScript hinter. + * + */ + typedef struct T1_HintsRec_* T1_Hints; + + + /************************************************************************* + * + * @type: + * T1_Hints_Funcs + * + * @description: + * A pointer to the @T1_Hints_FuncsRec structure that defines the API of + * a given @T1_Hints object. + * + */ + typedef const struct T1_Hints_FuncsRec_* T1_Hints_Funcs; + + + /************************************************************************* + * + * @functype: + * T1_Hints_OpenFunc + * + * @description: + * A method of the @T1_Hints class used to prepare it for a new Type 1 + * hints recording session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * @note: + * You should always call the @T1_Hints_CloseFunc method in order to + * close an opened recording session. + * + */ + typedef void + (*T1_Hints_OpenFunc)( T1_Hints hints ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_SetStemFunc + * + * @description: + * A method of the @T1_Hints class used to record a new horizontal or + * vertical stem. This corresponds to the Type 1 `hstem' and `vstem' + * operators. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * dimension :: + * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). + * + * coords :: + * Array of 2 coordinates in 16.16 format, used as (position,length) + * stem descriptor. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * `coords[0]' is the absolute stem position (lowest coordinate); + * `coords[1]' is the length. + * + * The length can be negative, in which case it must be either -20 or + * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * specification. + * + * If the length is -21 (corresponding to a bottom ghost stem), then + * the real stem position is `coords[0]+coords[1]'. + * + */ + typedef void + (*T1_Hints_SetStemFunc)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_SetStem3Func + * + * @description: + * A method of the @T1_Hints class used to record three + * counter-controlled horizontal or vertical stems at once. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * dimension :: + * 0 for horizontal stems, 1 for vertical ones. + * + * coords :: + * An array of 6 values in 16.16 format, holding 3 (position,length) + * pairs for the counter-controlled stems. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * The lengths cannot be negative (ghost stems are never + * counter-controlled). + * + */ + typedef void + (*T1_Hints_SetStem3Func)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_ResetFunc + * + * @description: + * A method of the @T1_Hints class used to reset the stems hints in a + * recording session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph in which the + * previously defined hints apply. + * + */ + typedef void + (*T1_Hints_ResetFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_CloseFunc + * + * @description: + * A method of the @T1_Hints class used to close a hint recording + * session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The error code is set to indicate that an error occurred during the + * recording session. + * + */ + typedef FT_Error + (*T1_Hints_CloseFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_ApplyFunc + * + * @description: + * A method of the @T1_Hints class used to apply hints to the + * corresponding glyph outline. Must be called once all hints have been + * recorded. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * outline :: + * A pointer to the target outline descriptor. + * + * globals :: + * The hinter globals for this font. + * + * hint_mode :: + * Hinting information. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * On input, all points within the outline are in font coordinates. On + * output, they are in 1/64th of pixels. + * + * The scaling transformation is taken from the `globals' object which + * must correspond to the same font as the glyph. + * + */ + typedef FT_Error + (*T1_Hints_ApplyFunc)( T1_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /************************************************************************* + * + * @struct: + * T1_Hints_FuncsRec + * + * @description: + * The structure used to provide the API to @T1_Hints objects. + * + * @fields: + * hints :: + * A handle to the T1 Hints recorder. + * + * open :: + * The function to open a recording session. + * + * close :: + * The function to close a recording session. + * + * stem :: + * The function to set a simple stem. + * + * stem3 :: + * The function to set counter-controlled stems. + * + * reset :: + * The function to reset stem hints. + * + * apply :: + * The function to apply the hints to the corresponding glyph outline. + * + */ + typedef struct T1_Hints_FuncsRec_ + { + T1_Hints hints; + T1_Hints_OpenFunc open; + T1_Hints_CloseFunc close; + T1_Hints_SetStemFunc stem; + T1_Hints_SetStem3Func stem3; + T1_Hints_ResetFunc reset; + T1_Hints_ApplyFunc apply; + + } T1_Hints_FuncsRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 2 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * T2_Hints + * + * @description: + * This is a handle to an opaque structure used to record glyph hints + * from a Type 2 character glyph character string. + * + * The methods used to operate on this object are defined by the + * @T2_Hints_FuncsRec structure. Recording glyph hints is normally + * achieved through the following scheme: + * + * - Open a new hint recording session by calling the `open' method. + * This rewinds the recorder and prepare it for new input. + * + * - For each hint found in the glyph charstring, call the corresponding + * method (`stems', `hintmask', `counters'). Note that these + * functions do not return an error code. + * + * - Close the recording session by calling the `close' method. It + * returns an error code if the hints were invalid or something + * strange happened (e.g., memory shortage). + * + * The hints accumulated in the object can later be used by the + * Postscript hinter. + * + */ + typedef struct T2_HintsRec_* T2_Hints; + + + /************************************************************************* + * + * @type: + * T2_Hints_Funcs + * + * @description: + * A pointer to the @T2_Hints_FuncsRec structure that defines the API of + * a given @T2_Hints object. + * + */ + typedef const struct T2_Hints_FuncsRec_* T2_Hints_Funcs; + + + /************************************************************************* + * + * @functype: + * T2_Hints_OpenFunc + * + * @description: + * A method of the @T2_Hints class used to prepare it for a new Type 2 + * hints recording session. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * @note: + * You should always call the @T2_Hints_CloseFunc method in order to + * close an opened recording session. + * + */ + typedef void + (*T2_Hints_OpenFunc)( T2_Hints hints ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_StemsFunc + * + * @description: + * A method of the @T2_Hints class used to set the table of stems in + * either the vertical or horizontal dimension. Equivalent to the + * `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * dimension :: + * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). + * + * count :: + * The number of stems. + * + * coords :: + * An array of `count' (position,length) pairs in 16.16 format. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * There are `2*count' elements in the `coords' array. Each even + * element is an absolute position in font units, each odd element is a + * length in font units. + * + * A length can be negative, in which case it must be either -20 or + * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * specification. + * + */ + typedef void + (*T2_Hints_StemsFunc)( T2_Hints hints, + FT_UInt dimension, + FT_UInt count, + FT_Fixed* coordinates ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_MaskFunc + * + * @description: + * A method of the @T2_Hints class used to set a given hintmask (this + * corresponds to the `hintmask' Type 2 operator). + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * The glyph index of the last point to which the previously defined + * or activated hints apply. + * + * bit_count :: + * The number of bits in the hint mask. + * + * bytes :: + * An array of bytes modelling the hint mask. + * + * @note: + * If the hintmask starts the charstring (before any glyph point + * definition), the value of `end_point' should be 0. + * + * `bit_count' is the number of meaningful bits in the `bytes' array; it + * must be equal to the total number of hints defined so far (i.e., + * horizontal+verticals). + * + * The `bytes' array can come directly from the Type 2 charstring and + * respects the same format. + * + */ + typedef void + (*T2_Hints_MaskFunc)( T2_Hints hints, + FT_UInt end_point, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_CounterFunc + * + * @description: + * A method of the @T2_Hints class used to set a given counter mask + * (this corresponds to the `hintmask' Type 2 operator). + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * A glyph index of the last point to which the previously defined or + * active hints apply. + * + * bit_count :: + * The number of bits in the hint mask. + * + * bytes :: + * An array of bytes modelling the hint mask. + * + * @note: + * If the hintmask starts the charstring (before any glyph point + * definition), the value of `end_point' should be 0. + * + * `bit_count' is the number of meaningful bits in the `bytes' array; it + * must be equal to the total number of hints defined so far (i.e., + * horizontal+verticals). + * + * The `bytes' array can come directly from the Type 2 charstring and + * respects the same format. + * + */ + typedef void + (*T2_Hints_CounterFunc)( T2_Hints hints, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_CloseFunc + * + * @description: + * A method of the @T2_Hints class used to close a hint recording + * session. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The error code is set to indicate that an error occurred during the + * recording session. + * + */ + typedef FT_Error + (*T2_Hints_CloseFunc)( T2_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_ApplyFunc + * + * @description: + * A method of the @T2_Hints class used to apply hints to the + * corresponding glyph outline. Must be called after the `close' + * method. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * outline :: + * A pointer to the target outline descriptor. + * + * globals :: + * The hinter globals for this font. + * + * hint_mode :: + * Hinting information. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * On input, all points within the outline are in font coordinates. On + * output, they are in 1/64th of pixels. + * + * The scaling transformation is taken from the `globals' object which + * must correspond to the same font than the glyph. + * + */ + typedef FT_Error + (*T2_Hints_ApplyFunc)( T2_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /************************************************************************* + * + * @struct: + * T2_Hints_FuncsRec + * + * @description: + * The structure used to provide the API to @T2_Hints objects. + * + * @fields: + * hints :: + * A handle to the T2 hints recorder object. + * + * open :: + * The function to open a recording session. + * + * close :: + * The function to close a recording session. + * + * stems :: + * The function to set the dimension's stems table. + * + * hintmask :: + * The function to set hint masks. + * + * counter :: + * The function to set counter masks. + * + * apply :: + * The function to apply the hints on the corresponding glyph outline. + * + */ + typedef struct T2_Hints_FuncsRec_ + { + T2_Hints hints; + T2_Hints_OpenFunc open; + T2_Hints_CloseFunc close; + T2_Hints_StemsFunc stems; + T2_Hints_MaskFunc hintmask; + T2_Hints_CounterFunc counter; + T2_Hints_ApplyFunc apply; + + } T2_Hints_FuncsRec; + + + /* */ + + + typedef struct PSHinter_Interface_ + { + PSH_Globals_Funcs (*get_globals_funcs)( FT_Module module ); + T1_Hints_Funcs (*get_t1_funcs) ( FT_Module module ); + T2_Hints_Funcs (*get_t2_funcs) ( FT_Module module ); + + } PSHinter_Interface; + + typedef PSHinter_Interface* PSHinter_Service; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_PSHINTER_INTERFACE( \ + class_, \ + get_globals_funcs_, \ + get_t1_funcs_, \ + get_t2_funcs_ ) \ + static const PSHinter_Interface class_ = \ + { \ + get_globals_funcs_, \ + get_t1_funcs_, \ + get_t2_funcs_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_PSHINTER_INTERFACE( \ + class_, \ + get_globals_funcs_, \ + get_t1_funcs_, \ + get_t2_funcs_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + PSHinter_Interface* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_globals_funcs = get_globals_funcs_; \ + clazz->get_t1_funcs = get_t1_funcs_; \ + clazz->get_t2_funcs = get_t2_funcs_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* __PSHINTS_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svbdf.h b/drivers/freetype/include/freetype/internal/services/svbdf.h new file mode 100644 index 0000000000..0974752a79 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svbdf.h @@ -0,0 +1,82 @@ +/***************************************************************************/ +/* */ +/* svbdf.h */ +/* */ +/* The FreeType BDF services (specification). */ +/* */ +/* Copyright 2003, 2009, 2012 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 __SVBDF_H__ +#define __SVBDF_H__ + +#include FT_BDF_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_BDF "bdf" + + typedef FT_Error + (*FT_BDF_GetCharsetIdFunc)( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + typedef FT_Error + (*FT_BDF_GetPropertyFunc)( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + + FT_DEFINE_SERVICE( BDF ) + { + FT_BDF_GetCharsetIdFunc get_charset_id; + FT_BDF_GetPropertyFunc get_property; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_BDFRec( class_, \ + get_charset_id_, \ + get_property_ ) \ + static const FT_Service_BDFRec class_ = \ + { \ + get_charset_id_, get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_BDFRec( class_, \ + get_charset_id_, \ + get_property_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_BDFRec* clazz ) \ + { \ + clazz->get_charset_id = get_charset_id_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVBDF_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svcid.h b/drivers/freetype/include/freetype/internal/services/svcid.h new file mode 100644 index 0000000000..6be3f9374d --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svcid.h @@ -0,0 +1,89 @@ +/***************************************************************************/ +/* */ +/* svcid.h */ +/* */ +/* The FreeType CID font services (specification). */ +/* */ +/* Copyright 2007, 2009, 2012 by Derek Clegg, Michael Toftdal. */ +/* */ +/* 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 __SVCID_H__ +#define __SVCID_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_CID "CID" + + typedef FT_Error + (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ); + typedef FT_Error + (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face face, + FT_Bool *is_cid ); + typedef FT_Error + (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + FT_DEFINE_SERVICE( CID ) + { + FT_CID_GetRegistryOrderingSupplementFunc get_ros; + FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid; + FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_CIDREC( class_, \ + get_ros_, \ + get_is_cid_, \ + get_cid_from_glyph_index_ ) \ + static const FT_Service_CIDRec class_ = \ + { \ + get_ros_, get_is_cid_, get_cid_from_glyph_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_CIDREC( class_, \ + get_ros_, \ + get_is_cid_, \ + get_cid_from_glyph_index_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_CIDRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_ros = get_ros_; \ + clazz->get_is_cid = get_is_cid_; \ + clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVCID_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svgldict.h b/drivers/freetype/include/freetype/internal/services/svgldict.h new file mode 100644 index 0000000000..1d12534725 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svgldict.h @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* svgldict.h */ +/* */ +/* The FreeType glyph dictionary services (specification). */ +/* */ +/* Copyright 2003, 2009, 2012 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 __SVGLDICT_H__ +#define __SVGLDICT_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to retrieve glyph names, as well as to find the + * index of a given glyph name in a font. + * + */ + +#define FT_SERVICE_ID_GLYPH_DICT "glyph-dict" + + + typedef FT_Error + (*FT_GlyphDict_GetNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_GlyphDict_NameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + + FT_DEFINE_SERVICE( GlyphDict ) + { + FT_GlyphDict_GetNameFunc get_name; + FT_GlyphDict_NameIndexFunc name_index; /* optional */ + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ + get_name_, \ + name_index_) \ + static const FT_Service_GlyphDictRec class_ = \ + { \ + get_name_, name_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ + get_name_, \ + name_index_) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_GlyphDictRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_name = get_name_; \ + clazz->name_index = name_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVGLDICT_H__ */ diff --git a/drivers/freetype/include/freetype/internal/services/svgxval.h b/drivers/freetype/include/freetype/internal/services/svgxval.h new file mode 100644 index 0000000000..2cdab50655 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svgxval.h @@ -0,0 +1,72 @@ +/***************************************************************************/ +/* */ +/* svgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004, 2005 by */ +/* Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVGXVAL_H__ +#define __SVGXVAL_H__ + +#include FT_GX_VALIDATE_H +#include FT_INTERNAL_VALIDATE_H + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_GX_VALIDATE "truetypegx-validate" +#define FT_SERVICE_ID_CLASSICKERN_VALIDATE "classickern-validate" + + typedef FT_Error + (*gxv_validate_func)( FT_Face face, + FT_UInt gx_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + typedef FT_Error + (*ckern_validate_func)( FT_Face face, + FT_UInt ckern_flags, + FT_Bytes *ckern_table ); + + + FT_DEFINE_SERVICE( GXvalidate ) + { + gxv_validate_func validate; + }; + + FT_DEFINE_SERVICE( CKERNvalidate ) + { + ckern_validate_func validate; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVGXVAL_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svkern.h b/drivers/freetype/include/freetype/internal/services/svkern.h new file mode 100644 index 0000000000..1488adf493 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svkern.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* svkern.h */ +/* */ +/* The FreeType Kerning service (specification). */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVKERN_H__ +#define __SVKERN_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + +#define FT_SERVICE_ID_KERNING "kerning" + + + typedef FT_Error + (*FT_Kerning_TrackGetFunc)( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + FT_DEFINE_SERVICE( Kerning ) + { + FT_Kerning_TrackGetFunc get_track; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVKERN_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svmm.h b/drivers/freetype/include/freetype/internal/services/svmm.h new file mode 100644 index 0000000000..b08a663d66 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svmm.h @@ -0,0 +1,113 @@ +/***************************************************************************/ +/* */ +/* svmm.h */ +/* */ +/* The FreeType Multiple Masters and GX var services (specification). */ +/* */ +/* Copyright 2003, 2004, 2009, 2012 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 __SVMM_H__ +#define __SVMM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to manage multiple-masters data in a given face. + * + * See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H). + * + */ + +#define FT_SERVICE_ID_MULTI_MASTERS "multi-masters" + + + typedef FT_Error + (*FT_Get_MM_Func)( FT_Face face, + FT_Multi_Master* master ); + + typedef FT_Error + (*FT_Get_MM_Var_Func)( FT_Face face, + FT_MM_Var* *master ); + + typedef FT_Error + (*FT_Set_MM_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Set_Var_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + typedef FT_Error + (*FT_Set_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + FT_DEFINE_SERVICE( MultiMasters ) + { + FT_Get_MM_Func get_mm; + FT_Set_MM_Design_Func set_mm_design; + FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Var_Func get_mm_var; + FT_Set_Var_Design_Func set_var_design; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_var_, \ + set_var_design_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_var_, \ + set_var_design_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* __SVMM_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svotval.h b/drivers/freetype/include/freetype/internal/services/svotval.h new file mode 100644 index 0000000000..970bbd5759 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svotval.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svotval.h */ +/* */ +/* The FreeType OpenType validation service (specification). */ +/* */ +/* Copyright 2004, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVOTVAL_H__ +#define __SVOTVAL_H__ + +#include FT_OPENTYPE_VALIDATE_H +#include FT_INTERNAL_VALIDATE_H + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_OPENTYPE_VALIDATE "opentype-validate" + + + typedef FT_Error + (*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 ) + { + otv_validate_func validate; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVOTVAL_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svpfr.h b/drivers/freetype/include/freetype/internal/services/svpfr.h new file mode 100644 index 0000000000..462786f9ce --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svpfr.h @@ -0,0 +1,66 @@ +/***************************************************************************/ +/* */ +/* svpfr.h */ +/* */ +/* Internal PFR service functions (specification). */ +/* */ +/* Copyright 2003, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPFR_H__ +#define __SVPFR_H__ + +#include FT_PFR_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_PFR_METRICS "pfr-metrics" + + + typedef FT_Error + (*FT_PFR_GetMetricsFunc)( FT_Face face, + FT_UInt *aoutline, + FT_UInt *ametrics, + FT_Fixed *ax_scale, + FT_Fixed *ay_scale ); + + typedef FT_Error + (*FT_PFR_GetKerningFunc)( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + typedef FT_Error + (*FT_PFR_GetAdvanceFunc)( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + + FT_DEFINE_SERVICE( PfrMetrics ) + { + FT_PFR_GetMetricsFunc get_metrics; + FT_PFR_GetKerningFunc get_kerning; + FT_PFR_GetAdvanceFunc get_advance; + + }; + + /* */ + +FT_END_HEADER + +#endif /* __SVPFR_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svpostnm.h b/drivers/freetype/include/freetype/internal/services/svpostnm.h new file mode 100644 index 0000000000..a76b4fe057 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svpostnm.h @@ -0,0 +1,81 @@ +/***************************************************************************/ +/* */ +/* svpostnm.h */ +/* */ +/* The FreeType PostScript name services (specification). */ +/* */ +/* Copyright 2003, 2007, 2009, 2012 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 __SVPOSTNM_H__ +#define __SVPOSTNM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + /* + * A trivial service used to retrieve the PostScript name of a given + * font when available. The `get_name' field should never be NULL. + * + * The corresponding function can return NULL to indicate that the + * PostScript name is not available. + * + * The name is owned by the face and will be destroyed with it. + */ + +#define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME "postscript-font-name" + + + typedef const char* + (*FT_PsName_GetFunc)( FT_Face face ); + + + FT_DEFINE_SERVICE( PsFontName ) + { + FT_PsName_GetFunc get_ps_font_name; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ + static const FT_Service_PsFontNameRec class_ = \ + { \ + get_ps_font_name_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_PsFontNameRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_ps_font_name = get_ps_font_name_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPOSTNM_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svprop.h b/drivers/freetype/include/freetype/internal/services/svprop.h new file mode 100644 index 0000000000..22da0bbc69 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svprop.h @@ -0,0 +1,81 @@ +/***************************************************************************/ +/* */ +/* svprop.h */ +/* */ +/* The FreeType property service (specification). */ +/* */ +/* Copyright 2012 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 __SVPROP_H__ +#define __SVPROP_H__ + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_PROPERTIES "properties" + + + typedef FT_Error + (*FT_Properties_SetFunc)( FT_Module module, + const char* property_name, + const void* value ); + + typedef FT_Error + (*FT_Properties_GetFunc)( FT_Module module, + const char* property_name, + void* value ); + + + FT_DEFINE_SERVICE( Properties ) + { + FT_Properties_SetFunc set_property; + FT_Properties_GetFunc get_property; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ + set_property_, \ + get_property_ ) \ + static const FT_Service_PropertiesRec class_ = \ + { \ + set_property_, \ + get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ + set_property_, \ + get_property_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_PropertiesRec* clazz ) \ + { \ + clazz->set_property = set_property_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPROP_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svpscmap.h b/drivers/freetype/include/freetype/internal/services/svpscmap.h new file mode 100644 index 0000000000..030948ea64 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svpscmap.h @@ -0,0 +1,177 @@ +/***************************************************************************/ +/* */ +/* svpscmap.h */ +/* */ +/* The FreeType PostScript charmap service (specification). */ +/* */ +/* Copyright 2003, 2006, 2009, 2012 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 __SVPSCMAP_H__ +#define __SVPSCMAP_H__ + +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_CMAPS "postscript-cmaps" + + + /* + * Adobe glyph name to unicode value. + */ + typedef FT_UInt32 + (*PS_Unicode_ValueFunc)( const char* glyph_name ); + + /* + * Macintosh name id to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Macintosh_NameFunc)( FT_UInt name_index ); + + /* + * Adobe standard string ID to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Adobe_Std_StringsFunc)( FT_UInt string_index ); + + + /* + * Simple unicode -> glyph index charmap built from font glyph names + * table. + */ + typedef struct PS_UniMap_ + { + FT_UInt32 unicode; /* bit 31 set: is glyph variant */ + FT_UInt glyph_index; + + } PS_UniMap; + + + typedef struct PS_UnicodesRec_* PS_Unicodes; + + typedef struct PS_UnicodesRec_ + { + FT_CMapRec cmap; + FT_UInt num_maps; + PS_UniMap* maps; + + } PS_UnicodesRec; + + + /* + * A function which returns a glyph name for a given index. Returns + * NULL if invalid index. + */ + typedef const char* + (*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_GetGlyphNameFunc get_glyph_name, + PS_FreeGlyphNameFunc free_glyph_name, + FT_Pointer glyph_data ); + + typedef FT_UInt + (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, + FT_UInt32 unicode ); + + typedef FT_UInt32 + (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, + FT_UInt32 *unicode ); + + + FT_DEFINE_SERVICE( PsCMaps ) + { + PS_Unicode_ValueFunc unicode_value; + + PS_Unicodes_InitFunc unicodes_init; + PS_Unicodes_CharIndexFunc unicodes_char_index; + PS_Unicodes_CharNextFunc unicodes_char_next; + + PS_Macintosh_NameFunc macintosh_name; + PS_Adobe_Std_StringsFunc adobe_std_strings; + const unsigned short* adobe_std_encoding; + const unsigned short* adobe_expert_encoding; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSCMAPSREC( class_, \ + unicode_value_, \ + unicodes_init_, \ + unicodes_char_index_, \ + unicodes_char_next_, \ + macintosh_name_, \ + adobe_std_strings_, \ + adobe_std_encoding_, \ + adobe_expert_encoding_ ) \ + static const FT_Service_PsCMapsRec class_ = \ + { \ + unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSCMAPSREC( class_, \ + unicode_value_, \ + unicodes_init_, \ + unicodes_char_index_, \ + unicodes_char_next_, \ + macintosh_name_, \ + adobe_std_strings_, \ + adobe_std_encoding_, \ + adobe_expert_encoding_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_PsCMapsRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->unicode_value = unicode_value_; \ + clazz->unicodes_init = unicodes_init_; \ + clazz->unicodes_char_index = unicodes_char_index_; \ + clazz->unicodes_char_next = unicodes_char_next_; \ + clazz->macintosh_name = macintosh_name_; \ + clazz->adobe_std_strings = adobe_std_strings_; \ + clazz->adobe_std_encoding = adobe_std_encoding_; \ + clazz->adobe_expert_encoding = adobe_expert_encoding_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPSCMAP_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svpsinfo.h b/drivers/freetype/include/freetype/internal/services/svpsinfo.h new file mode 100644 index 0000000000..4bfb506711 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svpsinfo.h @@ -0,0 +1,111 @@ +/***************************************************************************/ +/* */ +/* svpsinfo.h */ +/* */ +/* The FreeType PostScript info service (specification). */ +/* */ +/* Copyright 2003, 2004, 2009, 2011, 2012 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 __SVPSINFO_H__ +#define __SVPSINFO_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_INFO "postscript-info" + + + typedef FT_Error + (*PS_GetFontInfoFunc)( FT_Face face, + PS_FontInfoRec* afont_info ); + + typedef FT_Error + (*PS_GetFontExtraFunc)( FT_Face face, + PS_FontExtraRec* afont_extra ); + + typedef FT_Int + (*PS_HasGlyphNamesFunc)( FT_Face face ); + + typedef FT_Error + (*PS_GetFontPrivateFunc)( FT_Face face, + PS_PrivateRec* afont_private ); + + typedef FT_Long + (*PS_GetFontValueFunc)( FT_Face face, + PS_Dict_Keys key, + FT_UInt idx, + void *value, + FT_Long value_len ); + + + FT_DEFINE_SERVICE( PsInfo ) + { + PS_GetFontInfoFunc ps_get_font_info; + PS_GetFontExtraFunc ps_get_font_extra; + PS_HasGlyphNamesFunc ps_has_glyph_names; + PS_GetFontPrivateFunc ps_get_font_private; + PS_GetFontValueFunc ps_get_font_value; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSINFOREC( class_, \ + get_font_info_, \ + ps_get_font_extra_, \ + has_glyph_names_, \ + get_font_private_, \ + get_font_value_ ) \ + static const FT_Service_PsInfoRec class_ = \ + { \ + get_font_info_, ps_get_font_extra_, has_glyph_names_, \ + get_font_private_, get_font_value_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSINFOREC( class_, \ + get_font_info_, \ + ps_get_font_extra_, \ + has_glyph_names_, \ + get_font_private_, \ + get_font_value_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_PsInfoRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->ps_get_font_info = get_font_info_; \ + clazz->ps_get_font_extra = ps_get_font_extra_; \ + clazz->ps_has_glyph_names = has_glyph_names_; \ + clazz->ps_get_font_private = get_font_private_; \ + clazz->ps_get_font_value = get_font_value_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPSINFO_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svsfnt.h b/drivers/freetype/include/freetype/internal/services/svsfnt.h new file mode 100644 index 0000000000..d3835aa1c2 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svsfnt.h @@ -0,0 +1,103 @@ +/***************************************************************************/ +/* */ +/* svsfnt.h */ +/* */ +/* The FreeType SFNT table loading service (specification). */ +/* */ +/* Copyright 2003, 2004, 2009, 2012 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 __SVSFNT_H__ +#define __SVSFNT_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_SFNT_TABLE "sfnt-table" + + + /* + * Used to implement FT_Load_Sfnt_Table(). + */ + typedef FT_Error + (*FT_SFNT_TableLoadFunc)( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + /* + * Used to implement FT_Get_Sfnt_Table(). + */ + typedef void* + (*FT_SFNT_TableGetFunc)( FT_Face face, + FT_Sfnt_Tag tag ); + + + /* + * Used to implement FT_Sfnt_Table_Info(). + */ + typedef FT_Error + (*FT_SFNT_TableInfoFunc)( FT_Face face, + FT_UInt idx, + FT_ULong *tag, + FT_ULong *offset, + FT_ULong *length ); + + + FT_DEFINE_SERVICE( SFNT_Table ) + { + FT_SFNT_TableLoadFunc load_table; + FT_SFNT_TableGetFunc get_table; + FT_SFNT_TableInfoFunc table_info; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ + static const FT_Service_SFNT_TableRec class_ = \ + { \ + load_, get_, info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_SFNT_TableRec* clazz ) \ + { \ + clazz->load_table = load_; \ + clazz->get_table = get_; \ + clazz->table_info = info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVSFNT_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svttcmap.h b/drivers/freetype/include/freetype/internal/services/svttcmap.h new file mode 100644 index 0000000000..83994aaf8a --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svttcmap.h @@ -0,0 +1,107 @@ +/***************************************************************************/ +/* */ +/* svttcmap.h */ +/* */ +/* The FreeType TrueType/sfnt cmap extra information service. */ +/* */ +/* Copyright 2003 by */ +/* Masatake YAMATO, Redhat K.K. */ +/* */ +/* Copyright 2003, 2008, 2009, 2012 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. */ +/* */ +/***************************************************************************/ + +/* Development of this service is support of + Information-technology Promotion Agency, Japan. */ + +#ifndef __SVTTCMAP_H__ +#define __SVTTCMAP_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_CMAP "tt-cmaps" + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_CMapInfo */ + /* */ + /* <Description> */ + /* A structure used to store TrueType/sfnt specific cmap information */ + /* which is not covered by the generic @FT_CharMap structure. This */ + /* structure can be accessed with the @FT_Get_TT_CMap_Info function. */ + /* */ + /* <Fields> */ + /* language :: */ + /* The language ID used in Mac fonts. Definitions of values are in */ + /* freetype/ttnameid.h. */ + /* */ + /* format :: */ + /* The cmap format. OpenType 1.5 defines the formats 0 (byte */ + /* encoding table), 2~(high-byte mapping through table), 4~(segment */ + /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ + /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ + /* coverage), and 14 (Unicode Variation Sequences). */ + /* */ + typedef struct TT_CMapInfo_ + { + FT_ULong language; + FT_Long format; + + } TT_CMapInfo; + + + typedef FT_Error + (*TT_CMap_Info_GetFunc)( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + + + FT_DEFINE_SERVICE( TTCMaps ) + { + TT_CMap_Info_GetFunc get_cmap_info; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ + static const FT_Service_TTCMapsRec class_ = \ + { \ + get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_TTCMapsRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* __SVTTCMAP_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svtteng.h b/drivers/freetype/include/freetype/internal/services/svtteng.h new file mode 100644 index 0000000000..58e02a6f9d --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svtteng.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* svtteng.h */ +/* */ +/* The FreeType TrueType engine query service (specification). */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVTTENG_H__ +#define __SVTTENG_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_TRUETYPE_ENGINE "truetype-engine" + + /* + * Used to implement FT_Get_TrueType_Engine_Type + */ + + FT_DEFINE_SERVICE( TrueTypeEngine ) + { + FT_TrueTypeEngineType engine_type; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVTTENG_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svttglyf.h b/drivers/freetype/include/freetype/internal/services/svttglyf.h new file mode 100644 index 0000000000..369eb8421b --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svttglyf.h @@ -0,0 +1,68 @@ +/***************************************************************************/ +/* */ +/* svttglyf.h */ +/* */ +/* The FreeType TrueType glyph service. */ +/* */ +/* Copyright 2007, 2009, 2012 by David Turner. */ +/* */ +/* 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 __SVTTGLYF_H__ +#define __SVTTGLYF_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_GLYF "tt-glyf" + + + typedef FT_ULong + (*TT_Glyf_GetLocationFunc)( FT_Face face, + FT_UInt gindex, + FT_ULong *psize ); + + FT_DEFINE_SERVICE( TTGlyf ) + { + TT_Glyf_GetLocationFunc get_location; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ + static const FT_Service_TTGlyfRec class_ = \ + { \ + get_location_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_TTGlyfRec* clazz ) \ + { \ + clazz->get_location = get_location_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* __SVTTGLYF_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svwinfnt.h b/drivers/freetype/include/freetype/internal/services/svwinfnt.h new file mode 100644 index 0000000000..57f7765d92 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svwinfnt.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* svwinfnt.h */ +/* */ +/* The FreeType Windows FNT/FONT service (specification). */ +/* */ +/* Copyright 2003 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 __SVWINFNT_H__ +#define __SVWINFNT_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_WINFONTS_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_WINFNT "winfonts" + + typedef FT_Error + (*FT_WinFnt_GetHeaderFunc)( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + FT_DEFINE_SERVICE( WinFnt ) + { + FT_WinFnt_GetHeaderFunc get_header; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVWINFNT_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svxf86nm.h b/drivers/freetype/include/freetype/internal/services/svxf86nm.h new file mode 100644 index 0000000000..ca5d884a83 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svxf86nm.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svxf86nm.h */ +/* */ +/* The FreeType XFree86 services (specification only). */ +/* */ +/* Copyright 2003 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 __SVXF86NM_H__ +#define __SVXF86NM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A trivial service used to return the name of a face's font driver, + * according to the XFree86 nomenclature. Note that the service data + * is a simple constant string pointer. + */ + +#define FT_SERVICE_ID_XF86_NAME "xf86-driver-name" + +#define FT_XF86_FORMAT_TRUETYPE "TrueType" +#define FT_XF86_FORMAT_TYPE_1 "Type 1" +#define FT_XF86_FORMAT_BDF "BDF" +#define FT_XF86_FORMAT_PCF "PCF" +#define FT_XF86_FORMAT_TYPE_42 "Type 42" +#define FT_XF86_FORMAT_CID "CID Type 1" +#define FT_XF86_FORMAT_CFF "CFF" +#define FT_XF86_FORMAT_PFR "PFR" +#define FT_XF86_FORMAT_WINFNT "Windows FNT" + + /* */ + + +FT_END_HEADER + + +#endif /* __SVXF86NM_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/sfnt.h b/drivers/freetype/include/freetype/internal/sfnt.h new file mode 100644 index 0000000000..6b5e41f1ad --- /dev/null +++ b/drivers/freetype/include/freetype/internal/sfnt.h @@ -0,0 +1,707 @@ +/***************************************************************************/ +/* */ +/* sfnt.h */ +/* */ +/* High-level `sfnt' driver interface (specification). */ +/* */ +/* Copyright 1996-2006, 2009, 2012-2013 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 __SFNT_H__ +#define __SFNT_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Init_Face_Func */ + /* */ + /* <Description> */ + /* First part of the SFNT face object initialization. This finds */ + /* the face in a SFNT file or collection, and load its format tag in */ + /* face->format_tag. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType */ + /* collection'. */ + /* */ + /* Once the format tag has been validated by the font driver, it */ + /* should then call the TT_Load_Face_Func() callback to read the rest */ + /* of the SFNT tables in the object. */ + /* */ + typedef FT_Error + (*TT_Init_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Face_Func */ + /* */ + /* <Description> */ + /* Second part of the SFNT face object initialization. This loads */ + /* the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the */ + /* face object. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function must be called after TT_Init_Face_Func(). */ + /* */ + typedef FT_Error + (*TT_Load_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Done_Face_Func */ + /* */ + /* <Description> */ + /* A callback used to delete the common SFNT data from a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Note> */ + /* This function does NOT destroy the face object. */ + /* */ + typedef void + (*TT_Done_Face_Func)( TT_Face face ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Any_Func */ + /* */ + /* <Description> */ + /* Load any font table into client memory. */ + /* */ + /* <Input> */ + /* face :: The face object to look for. */ + /* */ + /* tag :: The tag of table to load. Use the value 0 if you want */ + /* to access the whole font file, else set this parameter */ + /* to a valid TrueType table tag that you can forge with */ + /* the MAKE_TT_TAG macro. */ + /* */ + /* offset :: The starting offset in the table (or the file if */ + /* tag == 0). */ + /* */ + /* length :: The address of the decision variable: */ + /* */ + /* If length == NULL: */ + /* Loads the whole table. Returns an error if */ + /* `offset' == 0! */ + /* */ + /* If *length == 0: */ + /* Exits immediately; returning the length of the given */ + /* table or of the font file, depending on the value of */ + /* `tag'. */ + /* */ + /* If *length != 0: */ + /* Loads the next `length' bytes of table or font, */ + /* starting at offset `offset' (in table or font too). */ + /* */ + /* <Output> */ + /* buffer :: The address of target buffer. */ + /* */ + /* <Return> */ + /* TrueType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Any_Func)( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte *buffer, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Find_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Check whether an embedded bitmap (an `sbit') exists for a given */ + /* glyph, at a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* <Output> */ + /* arange :: The SBit range containing the glyph index. */ + /* */ + /* astrike :: The SBit strike containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns */ + /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ + /* glyph. */ + /* */ + typedef FT_Error + (*TT_Find_SBit_Image_Func)( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Metrics_Func */ + /* */ + /* <Description> */ + /* Get the big metrics for a given embedded bitmap. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* range :: The SBit range containing the glyph. */ + /* */ + /* <Output> */ + /* big_metrics :: A big SBit metrics structure for the glyph. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be positioned at the glyph's offset within */ + /* the `EBDT' table before the call. */ + /* */ + /* If the image format uses variable metrics, the stream cursor is */ + /* positioned just after the metrics header in the `EBDT' table on */ + /* function exit. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Metrics_Func)( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Load a given glyph sbit image from the font resource. This also */ + /* returns its metrics. */ + /* */ + /* <Input> */ + /* face :: */ + /* The target face object. */ + /* */ + /* strike_index :: */ + /* The strike index. */ + /* */ + /* glyph_index :: */ + /* The current glyph index. */ + /* */ + /* load_flags :: */ + /* The current load flags. */ + /* */ + /* stream :: */ + /* The input stream. */ + /* */ + /* <Output> */ + /* amap :: */ + /* The target pixmap. */ + /* */ + /* ametrics :: */ + /* A big sbit metrics structure for the glyph image. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* glyph sbit exists for the index. */ + /* */ + /* <Note> */ + /* The `map.buffer' field is always freed before the glyph is loaded. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Image_Func)( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *amap, + TT_SBit_MetricsRec *ametrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Set_SBit_Strike_Func */ + /* */ + /* <Description> */ + /* Select an sbit strike for a given size request. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* req :: The size request. */ + /* */ + /* <Output> */ + /* astrike_index :: The index of the sbit strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* sbit strike exists for the selected ppem values. */ + /* */ + typedef FT_Error + (*TT_Set_SBit_Strike_Func)( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Strike_Metrics_Func */ + /* */ + /* <Description> */ + /* Load the metrics of a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* strike_index :: The strike index. */ + /* */ + /* <Output> */ + /* metrics :: the metrics of the strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* such sbit strike exists. */ + /* */ + typedef FT_Error + (*TT_Load_Strike_Metrics_Func)( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_PS_Name_Func */ + /* */ + /* <Description> */ + /* Get the PostScript glyph name of a glyph. */ + /* */ + /* <Input> */ + /* idx :: The glyph index. */ + /* */ + /* PSname :: The address of a string pointer. Will be NULL in case */ + /* of error, otherwise it is a pointer to the glyph name. */ + /* */ + /* You must not modify the returned string! */ + /* */ + /* <Output> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_PS_Name_Func)( TT_Face face, + FT_UInt idx, + FT_String** PSname ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Metrics_Func */ + /* */ + /* <Description> */ + /* Load a metrics table, which is a table with a horizontal and a */ + /* vertical version. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load the vertical one. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Metrics_Func)( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_Metrics_Func */ + /* */ + /* <Description> */ + /* Load the horizontal or vertical header in a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load vertical metrics. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_Metrics_Func)( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short* abearing, + FT_UShort* aadvance ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Table_Func */ + /* */ + /* <Description> */ + /* Load a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function uses `face->goto_table' to seek the stream to the */ + /* start of the table, except while loading the font directory. */ + /* */ + typedef FT_Error + (*TT_Load_Table_Func)( TT_Face face, + FT_Stream stream ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Free_Table_Func */ + /* */ + /* <Description> */ + /* Free a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + typedef void + (*TT_Free_Table_Func)( TT_Face face ); + + + /* + * @functype: + * TT_Face_GetKerningFunc + * + * @description: + * Return the horizontal kerning value between two glyphs. + * + * @input: + * face :: A handle to the source face object. + * left_glyph :: The left glyph index. + * right_glyph :: The right glyph index. + * + * @return: + * The kerning value in font units. + */ + typedef FT_Int + (*TT_Face_GetKerningFunc)( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_Interface */ + /* */ + /* <Description> */ + /* This structure holds pointers to the functions used to load and */ + /* free the basic tables that are required in a `sfnt' font file. */ + /* */ + /* <Fields> */ + /* Check the various xxx_Func() descriptions for details. */ + /* */ + typedef struct SFNT_Interface_ + { + TT_Loader_GotoTableFunc goto_table; + + TT_Init_Face_Func init_face; + TT_Load_Face_Func load_face; + TT_Done_Face_Func done_face; + FT_Module_Requester get_interface; + + TT_Load_Any_Func load_any; + + /* these functions are called by `load_face' but they can also */ + /* be called from external modules, if there is a need to do so */ + TT_Load_Table_Func load_head; + TT_Load_Metrics_Func load_hhea; + TT_Load_Table_Func load_cmap; + TT_Load_Table_Func load_maxp; + TT_Load_Table_Func load_os2; + TT_Load_Table_Func load_post; + + TT_Load_Table_Func load_name; + TT_Free_Table_Func free_name; + + /* this field was called `load_kerning' up to version 2.1.10 */ + TT_Load_Table_Func load_kern; + + TT_Load_Table_Func load_gasp; + TT_Load_Table_Func load_pclt; + + /* see `ttload.h'; this field was called `load_bitmap_header' up to */ + /* version 2.1.10 */ + TT_Load_Table_Func load_bhed; + + TT_Load_SBit_Image_Func load_sbit_image; + + /* see `ttpost.h' */ + TT_Get_PS_Name_Func get_psname; + TT_Free_Table_Func free_psnames; + + /* starting here, the structure differs from version 2.1.7 */ + + /* this field was introduced in version 2.1.8, named `get_psname' */ + TT_Face_GetKerningFunc get_kerning; + + /* new elements introduced after version 2.1.10 */ + + /* load the font directory, i.e., the offset table and */ + /* 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; + + + /* transitional */ + typedef SFNT_Interface* SFNT_Service; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SFNT_INTERFACE( \ + class_, \ + goto_table_, \ + init_face_, \ + load_face_, \ + done_face_, \ + get_interface_, \ + load_any_, \ + load_head_, \ + load_hhea_, \ + load_cmap_, \ + load_maxp_, \ + load_os2_, \ + load_post_, \ + load_name_, \ + free_name_, \ + load_kern_, \ + load_gasp_, \ + load_pclt_, \ + load_bhed_, \ + load_sbit_image_, \ + get_psname_, \ + free_psnames_, \ + get_kerning_, \ + load_font_dir_, \ + load_hmtx_, \ + load_eblc_, \ + free_eblc_, \ + set_sbit_strike_, \ + load_strike_metrics_, \ + get_metrics_ ) \ + static const SFNT_Interface class_ = \ + { \ + goto_table_, \ + init_face_, \ + load_face_, \ + done_face_, \ + get_interface_, \ + load_any_, \ + load_head_, \ + load_hhea_, \ + load_cmap_, \ + load_maxp_, \ + load_os2_, \ + load_post_, \ + load_name_, \ + free_name_, \ + load_kern_, \ + load_gasp_, \ + load_pclt_, \ + load_bhed_, \ + load_sbit_image_, \ + get_psname_, \ + free_psnames_, \ + get_kerning_, \ + load_font_dir_, \ + load_hmtx_, \ + load_eblc_, \ + free_eblc_, \ + set_sbit_strike_, \ + load_strike_metrics_, \ + get_metrics_, \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_INTERNAL( a, a_ ) \ + clazz->a = a_; + +#define FT_DEFINE_SFNT_INTERFACE( \ + class_, \ + goto_table_, \ + init_face_, \ + load_face_, \ + done_face_, \ + get_interface_, \ + load_any_, \ + load_head_, \ + load_hhea_, \ + load_cmap_, \ + load_maxp_, \ + load_os2_, \ + load_post_, \ + load_name_, \ + free_name_, \ + load_kern_, \ + load_gasp_, \ + load_pclt_, \ + load_bhed_, \ + load_sbit_image_, \ + get_psname_, \ + free_psnames_, \ + get_kerning_, \ + load_font_dir_, \ + load_hmtx_, \ + load_eblc_, \ + free_eblc_, \ + set_sbit_strike_, \ + load_strike_metrics_, \ + get_metrics_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + SFNT_Interface* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->goto_table = goto_table_; \ + clazz->init_face = init_face_; \ + clazz->load_face = load_face_; \ + clazz->done_face = done_face_; \ + clazz->get_interface = get_interface_; \ + clazz->load_any = load_any_; \ + clazz->load_head = load_head_; \ + clazz->load_hhea = load_hhea_; \ + clazz->load_cmap = load_cmap_; \ + clazz->load_maxp = load_maxp_; \ + clazz->load_os2 = load_os2_; \ + clazz->load_post = load_post_; \ + clazz->load_name = load_name_; \ + clazz->free_name = free_name_; \ + clazz->load_kern = load_kern_; \ + clazz->load_gasp = load_gasp_; \ + clazz->load_pclt = load_pclt_; \ + clazz->load_bhed = load_bhed_; \ + clazz->load_sbit_image = load_sbit_image_; \ + clazz->get_psname = get_psname_; \ + clazz->free_psnames = free_psnames_; \ + clazz->get_kerning = get_kerning_; \ + clazz->load_font_dir = load_font_dir_; \ + clazz->load_hmtx = load_hmtx_; \ + clazz->load_eblc = load_eblc_; \ + clazz->free_eblc = free_eblc_; \ + clazz->set_sbit_strike = set_sbit_strike_; \ + clazz->load_strike_metrics = load_strike_metrics_; \ + clazz->get_metrics = get_metrics_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* __SFNT_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/t1types.h b/drivers/freetype/include/freetype/internal/t1types.h new file mode 100644 index 0000000000..e20237c14d --- /dev/null +++ b/drivers/freetype/include/freetype/internal/t1types.h @@ -0,0 +1,255 @@ +/***************************************************************************/ +/* */ +/* t1types.h */ +/* */ +/* Basic Type1/Type2 type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 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 __T1TYPES_H__ +#define __T1TYPES_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_EncodingRec */ + /* */ + /* <Description> */ + /* A structure modeling a custom encoding. */ + /* */ + /* <Fields> */ + /* num_chars :: The number of character codes in the encoding. */ + /* Usually 256. */ + /* */ + /* code_first :: The lowest valid character code in the encoding. */ + /* */ + /* code_last :: The highest valid character code in the encoding */ + /* + 1. When equal to code_first there are no valid */ + /* character codes. */ + /* */ + /* char_index :: An array of corresponding glyph indices. */ + /* */ + /* char_name :: An array of corresponding glyph names. */ + /* */ + typedef struct T1_EncodingRecRec_ + { + FT_Int num_chars; + FT_Int code_first; + FT_Int code_last; + + FT_UShort* char_index; + FT_String** char_name; + + } T1_EncodingRec, *T1_Encoding; + + + /* used to hold extra data of PS_FontInfoRec that + * cannot be stored in the publicly defined structure. + * + * Note these can't be blended with multiple-masters. + */ + typedef struct PS_FontExtraRec_ + { + FT_UShort fs_type; + + } PS_FontExtraRec; + + + typedef struct T1_FontRec_ + { + PS_FontInfoRec font_info; /* font info dictionary */ + PS_FontExtraRec font_extra; /* font info extra fields */ + PS_PrivateRec private_dict; /* private dictionary */ + FT_String* font_name; /* top-level dictionary */ + + T1_EncodingType encoding_type; + T1_EncodingRec encoding; + + FT_Byte* subrs_block; + FT_Byte* charstrings_block; + FT_Byte* glyph_names_block; + + FT_Int num_subrs; + FT_Byte** subrs; + FT_PtrDist* subrs_len; + + FT_Int num_glyphs; + FT_String** glyph_names; /* array of glyph names */ + FT_Byte** charstrings; /* array of glyph charstrings */ + FT_PtrDist* charstrings_len; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + FT_BBox font_bbox; + FT_Long font_id; + + FT_Fixed stroke_width; + + } T1_FontRec, *T1_Font; + + + typedef struct CID_SubrsRec_ + { + FT_UInt num_subrs; + FT_Byte** code; + + } CID_SubrsRec, *CID_Subrs; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** AFM FONT INFORMATION STRUCTURES ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AFM_TrackKernRec_ + { + FT_Int degree; + FT_Fixed min_ptsize; + FT_Fixed min_kern; + FT_Fixed max_ptsize; + FT_Fixed max_kern; + + } AFM_TrackKernRec, *AFM_TrackKern; + + typedef struct AFM_KernPairRec_ + { + FT_Int index1; + FT_Int index2; + FT_Int x; + FT_Int y; + + } AFM_KernPairRec, *AFM_KernPair; + + typedef struct AFM_FontInfoRec_ + { + FT_Bool IsCIDFont; + FT_BBox FontBBox; + FT_Fixed Ascender; + FT_Fixed Descender; + AFM_TrackKern TrackKerns; /* free if non-NULL */ + FT_Int NumTrackKern; + AFM_KernPair KernPairs; /* free if non-NULL */ + FT_Int NumKernPair; + + } AFM_FontInfoRec, *AFM_FontInfo; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL T1_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_FaceRec_* T1_Face; + typedef struct CID_FaceRec_* CID_Face; + + + typedef struct T1_FaceRec_ + { + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; + const void* afm_data; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; + + /* 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_Long* buildchar; + + /* since version 2.1 - interface to PostScript hinter */ + const void* pshinter; + + } T1_FaceRec; + + + typedef struct CID_FaceRec_ + { + FT_FaceRec root; + void* psnames; + void* psaux; + CID_FaceInfoRec cid; + PS_FontExtraRec font_extra; +#if 0 + void* afm_data; +#endif + CID_Subrs subrs; + + /* since version 2.1 - interface to PostScript hinter */ + void* pshinter; + + /* since version 2.1.8, but was originally positioned after `afm_data' */ + FT_Byte* binary_data; /* used if hex data has been converted */ + FT_Stream cid_stream; + + } CID_FaceRec; + + +FT_END_HEADER + +#endif /* __T1TYPES_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/tttypes.h b/drivers/freetype/include/freetype/internal/tttypes.h new file mode 100644 index 0000000000..1bbfe499c5 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/tttypes.h @@ -0,0 +1,1440 @@ +/***************************************************************************/ +/* */ +/* tttypes.h */ +/* */ +/* Basic SFNT/TrueType type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2002, 2004-2008, 2012-2013 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 __TTTYPES_H__ +#define __TTTYPES_H__ + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_OBJECTS_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TTC_HeaderRec */ + /* */ + /* <Description> */ + /* TrueType collection header. This table contains the offsets of */ + /* the font headers of each distinct TrueType face in the file. */ + /* */ + /* <Fields> */ + /* tag :: Must be `ttc ' to indicate a TrueType collection. */ + /* */ + /* version :: The version number. */ + /* */ + /* count :: The number of faces in the collection. The */ + /* specification says this should be an unsigned long, but */ + /* we use a signed long since we need the value -1 for */ + /* specific purposes. */ + /* */ + /* offsets :: The offsets of the font headers, one per face. */ + /* */ + typedef struct TTC_HeaderRec_ + { + FT_ULong tag; + FT_Fixed version; + FT_Long count; + FT_ULong* offsets; + + } TTC_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_HeaderRec */ + /* */ + /* <Description> */ + /* SFNT file format header. */ + /* */ + /* <Fields> */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of tables in file. */ + /* */ + /* search_range :: Must be `16 * (max power of 2 <= num_tables)'. */ + /* */ + /* entry_selector :: Must be log2 of `search_range / 16'. */ + /* */ + /* range_shift :: Must be `num_tables * 16 - search_range'. */ + /* */ + typedef struct SFNT_HeaderRec_ + { + FT_ULong format_tag; + FT_UShort num_tables; + FT_UShort search_range; + FT_UShort entry_selector; + FT_UShort range_shift; + + FT_ULong offset; /* not in file */ + + } SFNT_HeaderRec, *SFNT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_TableRec */ + /* */ + /* <Description> */ + /* This structure describes a given table of a TrueType font. */ + /* */ + /* <Fields> */ + /* Tag :: A four-bytes tag describing the table. */ + /* */ + /* CheckSum :: The table checksum. This value can be ignored. */ + /* */ + /* Offset :: The offset of the table from the start of the TrueType */ + /* font in its resource. */ + /* */ + /* Length :: The table length (in bytes). */ + /* */ + typedef struct TT_TableRec_ + { + FT_ULong Tag; /* table type */ + FT_ULong CheckSum; /* table checksum */ + FT_ULong Offset; /* table file offset */ + FT_ULong Length; /* table length */ + + } TT_TableRec, *TT_Table; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_LongMetricsRec */ + /* */ + /* <Description> */ + /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ + /* TrueType tables. The values are expressed in font units. */ + /* */ + /* <Fields> */ + /* advance :: The advance width or height for the glyph. */ + /* */ + /* bearing :: The left-side or top-side bearing for the glyph. */ + /* */ + typedef struct TT_LongMetricsRec_ + { + FT_UShort advance; + FT_Short bearing; + + } TT_LongMetricsRec, *TT_LongMetrics; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_ShortMetrics */ + /* */ + /* <Description> */ + /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ + /* tables. */ + /* */ + typedef FT_Short TT_ShortMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameEntryRec */ + /* */ + /* <Description> */ + /* A structure modeling TrueType name records. Name records are used */ + /* to store important strings like family name, style name, */ + /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ + /* etc). */ + /* */ + /* <Fields> */ + /* platformID :: The ID of the name's encoding platform. */ + /* */ + /* encodingID :: The platform-specific ID for the name's encoding. */ + /* */ + /* languageID :: The platform-specific ID for the name's language. */ + /* */ + /* nameID :: The ID specifying what kind of name this is. */ + /* */ + /* stringLength :: The length of the string in bytes. */ + /* */ + /* stringOffset :: The offset to the string in the `name' table. */ + /* */ + /* string :: A pointer to the string's bytes. Note that these */ + /* are usually UTF-16 encoded characters. */ + /* */ + typedef struct TT_NameEntryRec_ + { + FT_UShort platformID; + FT_UShort encodingID; + FT_UShort languageID; + FT_UShort nameID; + FT_UShort stringLength; + FT_ULong stringOffset; + + /* this last field is not defined in the spec */ + /* but used by the FreeType engine */ + + FT_Byte* string; + + } TT_NameEntryRec, *TT_NameEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameTableRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType name table. */ + /* */ + /* <Fields> */ + /* format :: The format of the name table. */ + /* */ + /* numNameRecords :: The number of names in table. */ + /* */ + /* storageOffset :: The offset of the name table in the `name' */ + /* TrueType table. */ + /* */ + /* names :: An array of name records. */ + /* */ + /* stream :: the file's input stream. */ + /* */ + typedef struct TT_NameTableRec_ + { + FT_UShort format; + FT_UInt numNameRecords; + FT_UInt storageOffset; + TT_NameEntryRec* names; + FT_Stream stream; + + } TT_NameTableRec, *TT_NameTable; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRangeRec */ + /* */ + /* <Description> */ + /* A tiny structure used to model a gasp range according to the */ + /* TrueType specification. */ + /* */ + /* <Fields> */ + /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ + /* */ + /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ + /* modes to be used. */ + /* */ + typedef struct TT_GaspRangeRec_ + { + FT_UShort maxPPEM; + FT_UShort gaspFlag; + + } TT_GaspRangeRec, *TT_GaspRange; + + +#define TT_GASP_GRIDFIT 0x01 +#define TT_GASP_DOGRAY 0x02 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType `gasp' table used to specify */ + /* grid-fitting and anti-aliasing behaviour. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numRanges :: The number of gasp ranges in table. */ + /* */ + /* gaspRanges :: An array of gasp ranges. */ + /* */ + typedef struct TT_Gasp_ + { + FT_UShort version; + FT_UShort numRanges; + TT_GaspRange gaspRanges; + + } TT_GaspRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BITMAPS SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_MetricsRec */ + /* */ + /* <Description> */ + /* A structure used to hold the big metrics of a given glyph bitmap */ + /* in a TrueType or OpenType font. These are usually found in the */ + /* `EBDT' (Microsoft) or `bloc' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* horiBearingX :: The horizontal left bearing. */ + /* */ + /* horiBearingY :: The horizontal top bearing. */ + /* */ + /* horiAdvance :: The horizontal advance. */ + /* */ + /* vertBearingX :: The vertical left bearing. */ + /* */ + /* vertBearingY :: The vertical top bearing. */ + /* */ + /* vertAdvance :: The vertical advance. */ + /* */ + typedef struct TT_SBit_MetricsRec_ + { + FT_Byte height; + FT_Byte width; + + FT_Char horiBearingX; + FT_Char horiBearingY; + FT_Byte horiAdvance; + + FT_Char vertBearingX; + FT_Char vertBearingY; + FT_Byte vertAdvance; + + } TT_SBit_MetricsRec, *TT_SBit_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_SmallMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to hold the small metrics of a given glyph bitmap */ + /* in a TrueType or OpenType font. These are usually found in the */ + /* `EBDT' (Microsoft) or the `bdat' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* bearingX :: The left-side bearing. */ + /* */ + /* bearingY :: The top-side bearing. */ + /* */ + /* advance :: The advance width or height. */ + /* */ + typedef struct TT_SBit_Small_Metrics_ + { + FT_Byte height; + FT_Byte width; + + FT_Char bearingX; + FT_Char bearingY; + FT_Byte advance; + + } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_LineMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to describe the text line metrics of a given */ + /* bitmap strike, for either a horizontal or vertical layout. */ + /* */ + /* <Fields> */ + /* ascender :: The ascender in pixels. */ + /* */ + /* descender :: The descender in pixels. */ + /* */ + /* max_width :: The maximum glyph width in pixels. */ + /* */ + /* caret_slope_enumerator :: Rise of the caret slope, typically set */ + /* to 1 for non-italic fonts. */ + /* */ + /* caret_slope_denominator :: Rise of the caret slope, typically set */ + /* to 0 for non-italic fonts. */ + /* */ + /* caret_offset :: Offset in pixels to move the caret for */ + /* proper positioning. */ + /* */ + /* min_origin_SB :: Minimum of horiBearingX (resp. */ + /* vertBearingY). */ + /* min_advance_SB :: Minimum of */ + /* */ + /* horizontal advance - */ + /* ( horiBearingX + width ) */ + /* */ + /* resp. */ + /* */ + /* vertical advance - */ + /* ( vertBearingY + height ) */ + /* */ + /* max_before_BL :: Maximum of horiBearingY (resp. */ + /* vertBearingY). */ + /* */ + /* min_after_BL :: Minimum of */ + /* */ + /* horiBearingY - height */ + /* */ + /* resp. */ + /* */ + /* vertBearingX - width */ + /* */ + /* pads :: Unused (to make the size of the record */ + /* a multiple of 32 bits. */ + /* */ + typedef struct TT_SBit_LineMetricsRec_ + { + FT_Char ascender; + FT_Char descender; + FT_Byte max_width; + FT_Char caret_slope_numerator; + FT_Char caret_slope_denominator; + FT_Char caret_offset; + FT_Char min_origin_SB; + FT_Char min_advance_SB; + FT_Char max_before_BL; + FT_Char min_after_BL; + FT_Char pads[2]; + + } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_RangeRec */ + /* */ + /* <Description> */ + /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* first_glyph :: The first glyph index in the range. */ + /* */ + /* last_glyph :: The last glyph index in the range. */ + /* */ + /* index_format :: The format of index table. Valid values are 1 */ + /* to 5. */ + /* */ + /* image_format :: The format of `EBDT' image data. */ + /* */ + /* image_offset :: The offset to image data in `EBDT'. */ + /* */ + /* image_size :: For index formats 2 and 5. This is the size in */ + /* bytes of each glyph bitmap. */ + /* */ + /* big_metrics :: For index formats 2 and 5. This is the big */ + /* metrics for each glyph bitmap. */ + /* */ + /* num_glyphs :: For index formats 4 and 5. This is the number of */ + /* glyphs in the code array. */ + /* */ + /* glyph_offsets :: For index formats 1 and 3. */ + /* */ + /* glyph_codes :: For index formats 4 and 5. */ + /* */ + /* table_offset :: The offset of the index table in the `EBLC' */ + /* table. Only used during strike loading. */ + /* */ + typedef struct TT_SBit_RangeRec_ + { + FT_UShort first_glyph; + FT_UShort last_glyph; + + FT_UShort index_format; + FT_UShort image_format; + FT_ULong image_offset; + + FT_ULong image_size; + TT_SBit_MetricsRec metrics; + FT_ULong num_glyphs; + + FT_ULong* glyph_offsets; + FT_UShort* glyph_codes; + + FT_ULong table_offset; + + } TT_SBit_RangeRec, *TT_SBit_Range; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_StrikeRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap strike in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* num_index_ranges :: The number of index ranges. */ + /* */ + /* index_ranges :: An array of glyph index ranges. */ + /* */ + /* color_ref :: Unused. `color_ref' is put in for future */ + /* enhancements, but these fields are already */ + /* in use by other platforms (e.g. Newton). */ + /* For details, please see */ + /* */ + /* http://fonts.apple.com/ */ + /* TTRefMan/RM06/Chap6bloc.html */ + /* */ + /* hori :: The line metrics for horizontal layouts. */ + /* */ + /* vert :: The line metrics for vertical layouts. */ + /* */ + /* start_glyph :: The lowest glyph index for this strike. */ + /* */ + /* end_glyph :: The highest glyph index for this strike. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ + /* and 8. */ + /* */ + /* flags :: Is this a vertical or horizontal strike? For */ + /* details, please see */ + /* */ + /* http://fonts.apple.com/ */ + /* TTRefMan/RM06/Chap6bloc.html */ + /* */ + typedef struct TT_SBit_StrikeRec_ + { + FT_Int num_ranges; + TT_SBit_Range sbit_ranges; + FT_ULong ranges_offset; + + FT_ULong color_ref; + + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_UShort start_glyph; + FT_UShort end_glyph; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte bit_depth; + FT_Char flags; + + } TT_SBit_StrikeRec, *TT_SBit_Strike; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ComponentRec */ + /* */ + /* <Description> */ + /* A simple structure to describe a compound sbit element. */ + /* */ + /* <Fields> */ + /* glyph_code :: The element's glyph index. */ + /* */ + /* x_offset :: The element's left bearing. */ + /* */ + /* y_offset :: The element's top bearing. */ + /* */ + typedef struct TT_SBit_ComponentRec_ + { + FT_UShort glyph_code; + FT_Char x_offset; + FT_Char y_offset; + + } TT_SBit_ComponentRec, *TT_SBit_Component; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ScaleRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap scaling table, as defined */ + /* in the `EBSC' table. */ + /* */ + /* <Fields> */ + /* hori :: The horizontal line metrics. */ + /* */ + /* vert :: The vertical line metrics. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* x_ppem_substitute :: Substitution x_ppem value. */ + /* */ + /* y_ppem_substitute :: Substitution y_ppem value. */ + /* */ + typedef struct TT_SBit_ScaleRec_ + { + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte x_ppem_substitute; + FT_Byte y_ppem_substitute; + + } TT_SBit_ScaleRec, *TT_SBit_Scale; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_20Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.0. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of named glyphs in the table. */ + /* */ + /* num_names :: The number of PS names stored in the table. */ + /* */ + /* glyph_indices :: The indices of the glyphs in the names arrays. */ + /* */ + /* glyph_names :: The PS names not in Mac Encoding. */ + /* */ + typedef struct TT_Post_20Rec_ + { + FT_UShort num_glyphs; + FT_UShort num_names; + FT_UShort* glyph_indices; + FT_Char** glyph_names; + + } TT_Post_20Rec, *TT_Post_20; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_25Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.5. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of glyphs in the table. */ + /* */ + /* offsets :: An array of signed offsets in a normal Mac */ + /* Postscript name encoding. */ + /* */ + typedef struct TT_Post_25_ + { + FT_UShort num_glyphs; + FT_Char* offsets; + + } TT_Post_25Rec, *TT_Post_25; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_NamesRec */ + /* */ + /* <Description> */ + /* Postscript names table, either format 2.0 or 2.5. */ + /* */ + /* <Fields> */ + /* loaded :: A flag to indicate whether the PS names are loaded. */ + /* */ + /* format_20 :: The sub-table used for format 2.0. */ + /* */ + /* format_25 :: The sub-table used for format 2.5. */ + /* */ + typedef struct TT_Post_NamesRec_ + { + FT_Bool loaded; + + union + { + TT_Post_20Rec format_20; + TT_Post_25Rec format_25; + + } names; + + } TT_Post_NamesRec, *TT_Post_Names; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** GX VARIATION TABLE SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + typedef struct GX_BlendRec_ *GX_Blend; +#endif + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BDF PROPERTIES TABLE SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * These types are used to support a `BDF ' table that isn't part of the + * official TrueType specification. It is mainly used in SFNT-based + * bitmap fonts that were generated from a set of BDF fonts. + * + * The format of the table is as follows. + * + * USHORT version `BDF ' table version number, should be 0x0001. + * USHORT strikeCount Number of strikes (bitmap sizes) in this table. + * ULONG stringTable Offset (from start of BDF table) to string + * table. + * + * This is followed by an array of `strikeCount' descriptors, having the + * following format. + * + * USHORT ppem Vertical pixels per EM for this strike. + * USHORT numItems Number of items for this strike (properties and + * atoms). Maximum is 255. + * + * This array in turn is followed by `strikeCount' value sets. Each + * `value set' is an array of `numItems' items with the following format. + * + * ULONG item_name Offset in string table to item name. + * USHORT item_type The item type. Possible values are + * 0 => string (e.g., COMMENT) + * 1 => atom (e.g., FONT or even SIZE) + * 2 => int32 + * 3 => uint32 + * 0x10 => A flag to indicate a properties. This + * is ORed with the above values. + * ULONG item_value For strings => Offset into string table without + * the corresponding double quotes. + * For atoms => Offset into string table. + * For integers => Direct value. + * + * All strings in the string table consist of bytes and are + * zero-terminated. + * + */ + +#ifdef TT_CONFIG_OPTION_BDF + + typedef struct TT_BDFRec_ + { + FT_Byte* table; + FT_Byte* table_end; + FT_Byte* strings; + FT_ULong strings_size; + FT_UInt num_strikes; + FT_Bool loaded; + + } TT_BDFRec, *TT_BDF; + +#endif /* TT_CONFIG_OPTION_BDF */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL TT_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This structure/class is defined here because it is common to the */ + /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ + /* */ + /* Note, however, that the classes TT_Size and TT_GlyphSlot are not */ + /* shared between font drivers, and are thus defined in `ttobjs.h'. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* A handle to a TrueType face/font object. A TT_Face encapsulates */ + /* the resolution and scaling independent parts of a TrueType font */ + /* resource. */ + /* */ + /* <Note> */ + /* The TT_Face structure is also used as a `parent class' for the */ + /* OpenType-CFF class (T2_Face). */ + /* */ + typedef struct TT_FaceRec_* TT_Face; + + + /* a function type used for the truetype bytecode interpreter hooks */ + typedef FT_Error + (*TT_Interpreter)( void* exec_context ); + + /* forward declaration */ + typedef struct TT_LoaderRec_* TT_Loader; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_GotoTableFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* tag :: A 4-byte tag used to name the table. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* length :: The length of the table in bytes. Set to 0 if not */ + /* needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + typedef FT_Error + (*TT_Loader_GotoTableFunc)( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_StartGlyphFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given glyph element, and opens a */ + /* frame for it. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* glyph index :: The index of the glyph to access. */ + /* */ + /* offset :: The offset of the glyph according to the */ + /* `locations' table. */ + /* */ + /* byte_count :: The size of the frame in bytes. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function is normally equivalent to FT_STREAM_SEEK(offset) */ + /* followed by FT_FRAME_ENTER(byte_count) with the loader's stream, */ + /* but alternative formats (e.g. compressed ones) might use something */ + /* different. */ + /* */ + typedef FT_Error + (*TT_Loader_StartGlyphFunc)( TT_Loader loader, + FT_UInt glyph_index, + FT_ULong offset, + FT_UInt byte_count ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_ReadGlyphFunc */ + /* */ + /* <Description> */ + /* Reads one glyph element (its header, a simple glyph, or a */ + /* composite) from the loader's current stream frame. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Loader_ReadGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_EndGlyphFunc */ + /* */ + /* <Description> */ + /* Closes the current loader stream frame for the glyph. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + typedef void + (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* TrueType Face Type */ + /* */ + /* <Struct> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* The TrueType face class. These objects model the resolution and */ + /* point-size independent data found in a TrueType font file. */ + /* */ + /* <Fields> */ + /* root :: The base FT_Face structure, managed by the */ + /* base layer. */ + /* */ + /* ttc_header :: The TrueType collection header, used when */ + /* the file is a `ttc' rather than a `ttf'. */ + /* For ordinary font files, the field */ + /* `ttc_header.count' is set to 0. */ + /* */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of TrueType tables in this font */ + /* file. */ + /* */ + /* dir_tables :: The directory of TrueType tables for this */ + /* font file. */ + /* */ + /* header :: The font's font header (`head' table). */ + /* Read on font opening. */ + /* */ + /* horizontal :: The font's horizontal header (`hhea' */ + /* table). This field also contains the */ + /* associated horizontal metrics table */ + /* (`hmtx'). */ + /* */ + /* max_profile :: The font's maximum profile table. Read on */ + /* font opening. Note that some maximum */ + /* values cannot be taken directly from this */ + /* table. We thus define additional fields */ + /* below to hold the computed maxima. */ + /* */ + /* vertical_info :: A boolean which is set when the font file */ + /* contains vertical metrics. If not, the */ + /* value of the `vertical' field is */ + /* undefined. */ + /* */ + /* vertical :: The font's vertical header (`vhea' table). */ + /* This field also contains the associated */ + /* vertical metrics table (`vmtx'), if found. */ + /* IMPORTANT: The contents of this field is */ + /* undefined if the `verticalInfo' field is */ + /* unset. */ + /* */ + /* num_names :: The number of name records within this */ + /* TrueType font. */ + /* */ + /* name_table :: The table of name records (`name'). */ + /* */ + /* os2 :: The font's OS/2 table (`OS/2'). */ + /* */ + /* postscript :: The font's PostScript table (`post' */ + /* table). The PostScript glyph names are */ + /* not loaded by the driver on face opening. */ + /* See the `ttpost' module for more details. */ + /* */ + /* cmap_table :: Address of the face's `cmap' SFNT table */ + /* in memory (it's an extracted frame). */ + /* */ + /* cmap_size :: The size in bytes of the `cmap_table' */ + /* described above. */ + /* */ + /* goto_table :: A function called by each TrueType table */ + /* loader to position a stream's cursor to */ + /* the start of a given table according to */ + /* its tag. It defaults to TT_Goto_Face but */ + /* can be different for strange formats (e.g. */ + /* Type 42). */ + /* */ + /* access_glyph_frame :: A function used to access the frame of a */ + /* given glyph within the face's font file. */ + /* */ + /* forget_glyph_frame :: A function used to forget the frame of a */ + /* given glyph when all data has been loaded. */ + /* */ + /* read_glyph_header :: A function used to read a glyph header. */ + /* It must be called between an `access' and */ + /* `forget'. */ + /* */ + /* read_simple_glyph :: A function used to read a simple glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* read_composite_glyph :: A function used to read a composite glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* sfnt :: A pointer to the SFNT service. */ + /* */ + /* psnames :: A pointer to the PostScript names service. */ + /* */ + /* hdmx :: The face's horizontal device metrics */ + /* (`hdmx' table). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* gasp :: The grid-fitting and scaling properties */ + /* table (`gasp'). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* pclt :: The `pclt' SFNT table. */ + /* */ + /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ + /* sizes, embedded in this font. */ + /* */ + /* sbit_strikes :: An array of sbit strikes embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* num_sbit_scales :: The number of sbit scales for this font. */ + /* */ + /* sbit_scales :: Array of sbit scales embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* postscript_names :: A table used to store the Postscript names */ + /* of the glyphs for this font. See the */ + /* file `ttconfig.h' for comments on the */ + /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ + /* */ + /* num_locations :: The number of glyph locations in this */ + /* TrueType file. This should be */ + /* identical to the number of glyphs. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* glyph_locations :: An array of longs. These are offsets to */ + /* glyph data within the `glyf' table. */ + /* Ignored for Type 2 font faces. */ + /* */ + /* glyf_len :: The length of the `glyf' table. Needed */ + /* for malformed `loca' tables. */ + /* */ + /* font_program_size :: Size in bytecodes of the face's font */ + /* program. 0 if none defined. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* font_program :: The face's font program (bytecode stream) */ + /* executed at load time, also used during */ + /* glyph rendering. Comes from the `fpgm' */ + /* table. Ignored for Type 2 font fonts. */ + /* */ + /* cvt_program_size :: The size in bytecodes of the face's cvt */ + /* program. Ignored for Type 2 fonts. */ + /* */ + /* cvt_program :: The face's cvt program (bytecode stream) */ + /* executed each time an instance/size is */ + /* changed/reset. Comes from the `prep' */ + /* table. Ignored for Type 2 fonts. */ + /* */ + /* cvt_size :: Size of the control value table (in */ + /* entries). Ignored for Type 2 fonts. */ + /* */ + /* cvt :: The face's original control value table. */ + /* Coordinates are expressed in unscaled font */ + /* units. Comes from the `cvt ' table. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* num_kern_pairs :: The number of kerning pairs present in the */ + /* font file. The engine only loads the */ + /* first horizontal format 0 kern table it */ + /* finds in the font file. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* kern_table_index :: The index of the kerning table in the font */ + /* kerning directory. Ignored for Type 2 */ + /* fonts. */ + /* */ + /* interpreter :: A pointer to the TrueType bytecode */ + /* interpreters field is also used to hook */ + /* the debugger in `ttdebug'. */ + /* */ + /* unpatented_hinting :: If true, use only unpatented methods in */ + /* the bytecode interpreter. */ + /* */ + /* doblend :: A boolean which is set if the font should */ + /* be blended (this is for GX var). */ + /* */ + /* blend :: Contains the data needed to control GX */ + /* variation tables (rather like Multiple */ + /* Master data). */ + /* */ + /* extra :: Reserved for third-party font drivers. */ + /* */ + /* postscript_name :: The PS name of the font. Used by the */ + /* postscript name service. */ + /* */ + typedef struct TT_FaceRec_ + { + FT_FaceRec root; + + TTC_HeaderRec ttc_header; + + FT_ULong format_tag; + FT_UShort num_tables; + TT_Table dir_tables; + + TT_Header header; /* TrueType header table */ + TT_HoriHeader horizontal; /* TrueType horizontal header */ + + TT_MaxProfile max_profile; + + FT_Bool vertical_info; + TT_VertHeader vertical; /* TT Vertical header, if present */ + + FT_UShort num_names; /* number of name records */ + TT_NameTableRec name_table; /* name table */ + + TT_OS2 os2; /* TrueType OS/2 table */ + TT_Postscript postscript; /* TrueType Postscript table */ + + FT_Byte* cmap_table; /* extracted `cmap' table */ + FT_ULong cmap_size; + + TT_Loader_GotoTableFunc goto_table; + + TT_Loader_StartGlyphFunc access_glyph_frame; + TT_Loader_EndGlyphFunc forget_glyph_frame; + TT_Loader_ReadGlyphFunc read_glyph_header; + TT_Loader_ReadGlyphFunc read_simple_glyph; + TT_Loader_ReadGlyphFunc read_composite_glyph; + + /* a typeless pointer to the SFNT_Interface table used to load */ + /* the basic TrueType tables in the face object */ + void* sfnt; + + /* a typeless pointer to the FT_Service_PsCMapsRec table used to */ + /* handle glyph names <-> unicode & Mac values */ + void* psnames; + + + /***********************************************************************/ + /* */ + /* Optional TrueType/OpenType tables */ + /* */ + /***********************************************************************/ + + /* grid-fitting and scaling table */ + TT_GaspRec gasp; /* the `gasp' table */ + + /* PCL 5 table */ + TT_PCLT pclt; + + /* embedded bitmaps support */ + FT_ULong num_sbit_scales; + TT_SBit_Scale sbit_scales; + + /* postscript names table */ + TT_Post_NamesRec postscript_names; + + + /***********************************************************************/ + /* */ + /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ + /* */ + /***********************************************************************/ + + /* the font program, if any */ + FT_ULong font_program_size; + FT_Byte* font_program; + + /* the cvt program, if any */ + FT_ULong cvt_program_size; + FT_Byte* cvt_program; + + /* the original, unscaled, control value table */ + FT_ULong cvt_size; + FT_Short* cvt; + + /* A pointer to the bytecode interpreter to use. This is also */ + /* used to hook the debugger for the `ttdebug' utility. */ + TT_Interpreter interpreter; + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Use unpatented hinting only. */ + FT_Bool unpatented_hinting; +#endif + + /***********************************************************************/ + /* */ + /* Other tables or fields. This is used by derivative formats like */ + /* OpenType. */ + /* */ + /***********************************************************************/ + + FT_Generic extra; + + const char* postscript_name; + + FT_ULong glyf_len; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Bool doblend; + GX_Blend blend; +#endif + + /* since version 2.2 */ + + FT_Byte* horz_metrics; + FT_ULong horz_metrics_size; + + FT_Byte* vert_metrics; + FT_ULong vert_metrics_size; + + FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ + FT_Byte* glyph_locations; + + FT_Byte* hdmx_table; + FT_ULong hdmx_table_size; + FT_UInt hdmx_record_count; + FT_ULong hdmx_record_size; + FT_Byte* hdmx_record_sizes; + + FT_Byte* sbit_table; + FT_ULong sbit_table_size; + FT_UInt sbit_num_strikes; + + FT_Byte* kern_table; + FT_ULong kern_table_size; + FT_UInt num_kern_tables; + FT_UInt32 kern_avail_bits; + FT_UInt32 kern_order_bits; + +#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; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* since 2.4.12 */ + FT_ULong sph_found_func_flags; /* special functions found */ + /* for this face */ + FT_Bool sph_compatibility_mode; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + } TT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GlyphZoneRec */ + /* */ + /* <Description> */ + /* A glyph zone is used to load, scale and hint glyph outline */ + /* coordinates. */ + /* */ + /* <Fields> */ + /* memory :: A handle to the memory manager. */ + /* */ + /* max_points :: The maximum size in points of the zone. */ + /* */ + /* max_contours :: Max size in links contours of the zone. */ + /* */ + /* n_points :: The current number of points in the zone. */ + /* */ + /* n_contours :: The current number of contours in the zone. */ + /* */ + /* org :: The original glyph coordinates (font */ + /* units/scaled). */ + /* */ + /* cur :: The current glyph coordinates (scaled/hinted). */ + /* */ + /* tags :: The point control tags. */ + /* */ + /* 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_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_UShort first_point; /* offset of first (#0) point */ + + } TT_GlyphZoneRec, *TT_GlyphZone; + + + /* handle to execution context */ + typedef struct TT_ExecContextRec_* TT_ExecContext; + + /* glyph loader structure */ + typedef struct TT_LoaderRec_ + { + FT_Face face; + FT_Size size; + FT_GlyphSlot glyph; + FT_GlyphLoader gloader; + + FT_ULong load_flags; + FT_UInt glyph_index; + + FT_Stream stream; + FT_Int byte_len; + + FT_Short n_contours; + FT_BBox bbox; + FT_Int left_bearing; + FT_Int advance; + FT_Int linear; + FT_Bool linear_def; + FT_Bool preserve_pps; + FT_Vector pp1; + FT_Vector pp2; + + FT_ULong glyf_offset; + + /* the zone where we load our glyphs */ + TT_GlyphZoneRec base; + TT_GlyphZoneRec zone; + + TT_ExecContext exec; + FT_Byte* instructions; + FT_ULong ins_pos; + + /* for possible extensibility in other formats */ + void* other; + + /* since version 2.1.8 */ + FT_Int top_bearing; + FT_Int vadvance; + FT_Vector pp3; + FT_Vector pp4; + + /* since version 2.2.1 */ + FT_Byte* cursor; + FT_Byte* limit; + + } TT_LoaderRec; + + +FT_END_HEADER + +#endif /* __TTTYPES_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/t1tables.h b/drivers/freetype/include/freetype/t1tables.h new file mode 100644 index 0000000000..a14255e5f5 --- /dev/null +++ b/drivers/freetype/include/freetype/t1tables.h @@ -0,0 +1,662 @@ +/***************************************************************************/ +/* */ +/* t1tables.h */ +/* */ +/* Basic Type 1/Type 2 tables definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2004, 2006, 2008, 2009, 2011 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 __T1TABLES_H__ +#define __T1TABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* type1_tables */ + /* */ + /* <Title> */ + /* Type 1 Tables */ + /* */ + /* <Abstract> */ + /* Type~1 (PostScript) specific font tables. */ + /* */ + /* <Description> */ + /* This section contains the definition of Type 1-specific tables, */ + /* including structures related to other PostScript font formats. */ + /* */ + /*************************************************************************/ + + + /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ + /* structures in order to support Multiple Master fonts. */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfoRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* FontInfo dictionary. */ + /* */ + typedef struct PS_FontInfoRec_ + { + FT_String* version; + FT_String* notice; + FT_String* full_name; + FT_String* family_name; + FT_String* weight; + FT_Long italic_angle; + FT_Bool is_fixed_pitch; + FT_Short underline_position; + FT_UShort underline_thickness; + + } PS_FontInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfo */ + /* */ + /* <Description> */ + /* A handle to a @PS_FontInfoRec structure. */ + /* */ + typedef struct PS_FontInfoRec_* PS_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_FontInfo */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_FontInfoRec T1_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_PrivateRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 private dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* Private dictionary. */ + /* */ + typedef struct PS_PrivateRec_ + { + FT_Int unique_id; + FT_Int lenIV; + + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Short blue_values[14]; + FT_Short other_blues[10]; + + FT_Short family_blues [14]; + FT_Short family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_fuzz; + + FT_UShort standard_width[1]; + FT_UShort standard_height[1]; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Bool force_bold; + FT_Bool round_stem_up; + + FT_Short snap_widths [13]; /* including std width */ + FT_Short snap_heights[13]; /* including std height */ + + FT_Fixed expansion_factor; + + FT_Long language_group; + FT_Long password; + + FT_Short min_feature[2]; + + } PS_PrivateRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Private */ + /* */ + /* <Description> */ + /* A handle to a @PS_PrivateRec structure. */ + /* */ + typedef struct PS_PrivateRec_* PS_Private; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_Private */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_PrivateRec T1_Private; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_Blend_Flags */ + /* */ + /* <Description> */ + /* A set of flags used to indicate which fields are present in a */ + /* given blend dictionary (font info or private). Used to support */ + /* Multiple Masters fonts. */ + /* */ + typedef enum T1_Blend_Flags_ + { + /*# required fields in a FontInfo blend dictionary */ + T1_BLEND_UNDERLINE_POSITION = 0, + T1_BLEND_UNDERLINE_THICKNESS, + T1_BLEND_ITALIC_ANGLE, + + /*# required fields in a Private blend dictionary */ + T1_BLEND_BLUE_VALUES, + T1_BLEND_OTHER_BLUES, + T1_BLEND_STANDARD_WIDTH, + T1_BLEND_STANDARD_HEIGHT, + T1_BLEND_STEM_SNAP_WIDTHS, + T1_BLEND_STEM_SNAP_HEIGHTS, + T1_BLEND_BLUE_SCALE, + T1_BLEND_BLUE_SHIFT, + T1_BLEND_FAMILY_BLUES, + T1_BLEND_FAMILY_OTHER_BLUES, + T1_BLEND_FORCE_BOLD, + + /*# never remove */ + T1_BLEND_MAX + + } T1_Blend_Flags; + + /* */ + + + /*# backwards compatible definitions */ +#define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION +#define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS +#define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE +#define t1_blend_blue_values T1_BLEND_BLUE_VALUES +#define t1_blend_other_blues T1_BLEND_OTHER_BLUES +#define t1_blend_standard_widths T1_BLEND_STANDARD_WIDTH +#define t1_blend_standard_height T1_BLEND_STANDARD_HEIGHT +#define t1_blend_stem_snap_widths T1_BLEND_STEM_SNAP_WIDTHS +#define t1_blend_stem_snap_heights T1_BLEND_STEM_SNAP_HEIGHTS +#define t1_blend_blue_scale T1_BLEND_BLUE_SCALE +#define t1_blend_blue_shift T1_BLEND_BLUE_SHIFT +#define t1_blend_family_blues T1_BLEND_FAMILY_BLUES +#define t1_blend_family_other_blues T1_BLEND_FAMILY_OTHER_BLUES +#define t1_blend_force_bold T1_BLEND_FORCE_BOLD +#define t1_blend_max T1_BLEND_MAX + + + /* maximum number of Multiple Masters designs, as defined in the spec */ +#define T1_MAX_MM_DESIGNS 16 + + /* maximum number of Multiple Masters axes, as defined in the spec */ +#define T1_MAX_MM_AXIS 4 + + /* maximum number of elements in a design map */ +#define T1_MAX_MM_MAP_POINTS 20 + + + /* this structure is used to store the BlendDesignMap entry for an axis */ + typedef struct PS_DesignMap_ + { + FT_Byte num_points; + FT_Long* design_points; + FT_Fixed* blend_points; + + } PS_DesignMapRec, *PS_DesignMap; + + /* backwards-compatible definition */ + typedef PS_DesignMapRec T1_DesignMap; + + + typedef struct PS_BlendRec_ + { + FT_UInt num_designs; + FT_UInt num_axis; + + FT_String* axis_names[T1_MAX_MM_AXIS]; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; + PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; + + FT_Fixed* weight_vector; + FT_Fixed* default_weight_vector; + + PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; + PS_Private privates [T1_MAX_MM_DESIGNS + 1]; + + FT_ULong blend_bitflags; + + 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; + + + /* backwards-compatible definition */ + typedef PS_BlendRec T1_Blend; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDictRec */ + /* */ + /* <Description> */ + /* A structure used to represent data in a CID top-level dictionary. */ + /* */ + typedef struct CID_FaceDictRec_ + { + PS_PrivateRec private_dict; + + FT_UInt len_buildchar; + FT_Fixed forcebold_threshold; + FT_Pos stroke_width; + FT_Fixed expansion_factor; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_UInt num_subrs; + FT_ULong subrmap_offset; + FT_Int sd_bytes; + + } CID_FaceDictRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDict */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceDictRec structure. */ + /* */ + typedef struct CID_FaceDictRec_* CID_FaceDict; + + /* */ + + + /* backwards-compatible definition */ + typedef CID_FaceDictRec CID_FontDict; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfoRec */ + /* */ + /* <Description> */ + /* A structure used to represent CID Face information. */ + /* */ + typedef struct CID_FaceInfoRec_ + { + FT_String* cid_font_name; + FT_Fixed cid_version; + FT_Int cid_font_type; + + FT_String* registry; + FT_String* ordering; + FT_Int supplement; + + PS_FontInfoRec font_info; + FT_BBox font_bbox; + FT_ULong uid_base; + + FT_Int num_xuid; + FT_ULong xuid[16]; + + FT_ULong cidmap_offset; + FT_Int fd_bytes; + FT_Int gd_bytes; + FT_ULong cid_count; + + FT_Int num_dicts; + CID_FaceDict font_dicts; + + FT_ULong data_offset; + + } CID_FaceInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfo */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceInfoRec structure. */ + /* */ + typedef struct CID_FaceInfoRec_* CID_FaceInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Info */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef CID_FaceInfoRec CID_Info; + + + /************************************************************************ + * + * @function: + * FT_Has_PS_Glyph_Names + * + * @description: + * Return true if a given face provides reliable PostScript glyph + * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, + * except that certain fonts (mostly TrueType) contain incorrect + * glyph name tables. + * + * When this function returns true, the caller is sure that the glyph + * names returned by @FT_Get_Glyph_Name are reliable. + * + * @input: + * face :: + * face handle + * + * @return: + * Boolean. True if glyph names are reliable. + * + */ + FT_EXPORT( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Info + * + * @description: + * Retrieve the @PS_FontInfoRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_info :: + * Output font info structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the font info structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function will + * return the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfo afont_info ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Private + * + * @description: + * Retrieve the @PS_PrivateRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_private :: + * Output private dictionary structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the @PS_PrivateRec structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Private( FT_Face face, + PS_Private afont_private ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_EncodingType */ + /* */ + /* <Description> */ + /* An enumeration describing the `Encoding' entry in a Type 1 */ + /* dictionary. */ + /* */ + typedef enum T1_EncodingType_ + { + T1_ENCODING_TYPE_NONE = 0, + T1_ENCODING_TYPE_ARRAY, + T1_ENCODING_TYPE_STANDARD, + T1_ENCODING_TYPE_ISOLATIN1, + T1_ENCODING_TYPE_EXPERT + + } T1_EncodingType; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* PS_Dict_Keys */ + /* */ + /* <Description> */ + /* An enumeration used in calls to @FT_Get_PS_Font_Value to identify */ + /* the Type~1 dictionary entry to retrieve. */ + /* */ + typedef enum PS_Dict_Keys_ + { + /* conventionally in the font dictionary */ + PS_DICT_FONT_TYPE, /* FT_Byte */ + PS_DICT_FONT_MATRIX, /* FT_Fixed */ + PS_DICT_FONT_BBOX, /* FT_Fixed */ + PS_DICT_PAINT_TYPE, /* FT_Byte */ + PS_DICT_FONT_NAME, /* FT_String* */ + PS_DICT_UNIQUE_ID, /* FT_Int */ + PS_DICT_NUM_CHAR_STRINGS, /* FT_Int */ + PS_DICT_CHAR_STRING_KEY, /* FT_String* */ + PS_DICT_CHAR_STRING, /* FT_String* */ + PS_DICT_ENCODING_TYPE, /* T1_EncodingType */ + PS_DICT_ENCODING_ENTRY, /* FT_String* */ + + /* conventionally in the font Private dictionary */ + PS_DICT_NUM_SUBRS, /* FT_Int */ + PS_DICT_SUBR, /* FT_String* */ + PS_DICT_STD_HW, /* FT_UShort */ + PS_DICT_STD_VW, /* FT_UShort */ + PS_DICT_NUM_BLUE_VALUES, /* FT_Byte */ + PS_DICT_BLUE_VALUE, /* FT_Short */ + PS_DICT_BLUE_FUZZ, /* FT_Int */ + PS_DICT_NUM_OTHER_BLUES, /* FT_Byte */ + PS_DICT_OTHER_BLUE, /* FT_Short */ + PS_DICT_NUM_FAMILY_BLUES, /* FT_Byte */ + PS_DICT_FAMILY_BLUE, /* FT_Short */ + PS_DICT_NUM_FAMILY_OTHER_BLUES, /* FT_Byte */ + PS_DICT_FAMILY_OTHER_BLUE, /* FT_Short */ + PS_DICT_BLUE_SCALE, /* FT_Fixed */ + PS_DICT_BLUE_SHIFT, /* FT_Int */ + PS_DICT_NUM_STEM_SNAP_H, /* FT_Byte */ + PS_DICT_STEM_SNAP_H, /* FT_Short */ + PS_DICT_NUM_STEM_SNAP_V, /* FT_Byte */ + PS_DICT_STEM_SNAP_V, /* FT_Short */ + PS_DICT_FORCE_BOLD, /* FT_Bool */ + PS_DICT_RND_STEM_UP, /* FT_Bool */ + PS_DICT_MIN_FEATURE, /* FT_Short */ + PS_DICT_LEN_IV, /* FT_Int */ + PS_DICT_PASSWORD, /* FT_Long */ + PS_DICT_LANGUAGE_GROUP, /* FT_Long */ + + /* conventionally in the font FontInfo dictionary */ + PS_DICT_VERSION, /* FT_String* */ + PS_DICT_NOTICE, /* FT_String* */ + PS_DICT_FULL_NAME, /* FT_String* */ + PS_DICT_FAMILY_NAME, /* FT_String* */ + PS_DICT_WEIGHT, /* FT_String* */ + PS_DICT_IS_FIXED_PITCH, /* FT_Bool */ + PS_DICT_UNDERLINE_POSITION, /* FT_Short */ + PS_DICT_UNDERLINE_THICKNESS, /* FT_UShort */ + PS_DICT_FS_TYPE, /* FT_UShort */ + PS_DICT_ITALIC_ANGLE, /* FT_Long */ + + PS_DICT_MAX = PS_DICT_ITALIC_ANGLE + + } PS_Dict_Keys; + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Value + * + * @description: + * Retrieve the value for the supplied key from a PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * key :: + * An enumeration value representing the dictionary key to retrieve. + * + * idx :: + * For array values, this specifies the index to be returned. + * + * value :: + * A pointer to memory into which to write the value. + * + * valen_len :: + * The size, in bytes, of the memory supplied for the value. + * + * @output: + * value :: + * The value matching the above key, if it exists. + * + * @return: + * The amount of memory (in bytes) required to hold the requested + * value (if it exists, -1 otherwise). + * + * @note: + * The values returned are not pointers into the internal structures of + * the face, but are `fresh' copies, so that the memory containing them + * belongs to the calling application. This also enforces the + * `read-only' nature of these values, i.e., this function cannot be + * used to manipulate the face. + * + * `value' is a void pointer because the values returned can be of + * various types. + * + * If either `value' is NULL or `value_len' is too small, just the + * required memory size for the requested entry is returned. + * + * The `idx' parameter is used, not only to retrieve elements of, for + * example, the FontMatrix or FontBBox, but also to retrieve name keys + * from the CharStrings dictionary, and the charstrings themselves. It + * is ignored for atomic values. + * + * PS_DICT_BLUE_SCALE returns a value that is scaled up by 1000. To + * get the value as in the font stream, you need to divide by + * 65536000.0 (to remove the FT_Fixed scale, and the x1000 scale). + * + * IMPORTANT: Only key/value pairs read by the FreeType interpreter can + * be retrieved. So, for example, PostScript procedures such as NP, + * ND, and RD are not available. Arbitrary keys are, obviously, not be + * available either. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Long ) + FT_Get_PS_Font_Value( FT_Face face, + PS_Dict_Keys key, + FT_UInt idx, + void *value, + FT_Long value_len ); + + /* */ + +FT_END_HEADER + +#endif /* __T1TABLES_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ttnameid.h b/drivers/freetype/include/freetype/ttnameid.h new file mode 100644 index 0000000000..173f88c950 --- /dev/null +++ b/drivers/freetype/include/freetype/ttnameid.h @@ -0,0 +1,1237 @@ +/***************************************************************************/ +/* */ +/* ttnameid.h */ +/* */ +/* TrueType name ID definitions (specification only). */ +/* */ +/* Copyright 1996-2004, 2006-2008, 2012 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 __TTNAMEID_H__ +#define __TTNAMEID_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + + + /*************************************************************************/ + /* */ + /* Possible values for the `platform' identifier code in the name */ + /* records of the TTF `name' table. */ + /* */ + /*************************************************************************/ + + + /*********************************************************************** + * + * @enum: + * TT_PLATFORM_XXX + * + * @description: + * A list of valid values for the `platform_id' identifier code in + * @FT_CharMapRec and @FT_SfntName structures. + * + * @values: + * TT_PLATFORM_APPLE_UNICODE :: + * Used by Apple to indicate a Unicode character map and/or name entry. + * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note + * that name entries in this format are coded as big-endian UCS-2 + * character codes _only_. + * + * TT_PLATFORM_MACINTOSH :: + * Used by Apple to indicate a MacOS-specific charmap and/or name entry. + * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that + * most TrueType fonts contain an Apple roman charmap to be usable on + * MacOS systems (even if they contain a Microsoft charmap as well). + * + * TT_PLATFORM_ISO :: + * This value was used to specify ISO/IEC 10646 charmaps. It is however + * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding + * `encoding_id' values. + * + * TT_PLATFORM_MICROSOFT :: + * Used by Microsoft to indicate Windows-specific charmaps. See + * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. + * Note that most fonts contain a Unicode charmap using + * (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). + * + * TT_PLATFORM_CUSTOM :: + * Used to indicate application-specific charmaps. + * + * TT_PLATFORM_ADOBE :: + * This value isn't part of any font format specification, but is used + * by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec + * structure. See @TT_ADOBE_ID_XXX. + */ + +#define TT_PLATFORM_APPLE_UNICODE 0 +#define TT_PLATFORM_MACINTOSH 1 +#define TT_PLATFORM_ISO 2 /* deprecated */ +#define TT_PLATFORM_MICROSOFT 3 +#define TT_PLATFORM_CUSTOM 4 +#define TT_PLATFORM_ADOBE 7 /* artificial */ + + + /*********************************************************************** + * + * @enum: + * TT_APPLE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. + * + * @values: + * TT_APPLE_ID_DEFAULT :: + * Unicode version 1.0. + * + * TT_APPLE_ID_UNICODE_1_1 :: + * Unicode 1.1; specifies Hangul characters starting at U+34xx. + * + * TT_APPLE_ID_ISO_10646 :: + * Deprecated (identical to preceding). + * + * TT_APPLE_ID_UNICODE_2_0 :: + * Unicode 2.0 and beyond (UTF-16 BMP only). + * + * TT_APPLE_ID_UNICODE_32 :: + * Unicode 3.1 and beyond, using UTF-32. + * + * TT_APPLE_ID_VARIANT_SELECTOR :: + * From Adobe, not Apple. Not a normal cmap. Specifies variations + * on a real cmap. + */ + +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ + + + /*********************************************************************** + * + * @enum: + * TT_MAC_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MACINTOSH charmaps and name entries. + * + * @values: + * TT_MAC_ID_ROMAN :: + * TT_MAC_ID_JAPANESE :: + * TT_MAC_ID_TRADITIONAL_CHINESE :: + * TT_MAC_ID_KOREAN :: + * TT_MAC_ID_ARABIC :: + * TT_MAC_ID_HEBREW :: + * TT_MAC_ID_GREEK :: + * TT_MAC_ID_RUSSIAN :: + * TT_MAC_ID_RSYMBOL :: + * TT_MAC_ID_DEVANAGARI :: + * TT_MAC_ID_GURMUKHI :: + * TT_MAC_ID_GUJARATI :: + * TT_MAC_ID_ORIYA :: + * TT_MAC_ID_BENGALI :: + * TT_MAC_ID_TAMIL :: + * TT_MAC_ID_TELUGU :: + * TT_MAC_ID_KANNADA :: + * TT_MAC_ID_MALAYALAM :: + * TT_MAC_ID_SINHALESE :: + * TT_MAC_ID_BURMESE :: + * TT_MAC_ID_KHMER :: + * TT_MAC_ID_THAI :: + * TT_MAC_ID_LAOTIAN :: + * TT_MAC_ID_GEORGIAN :: + * TT_MAC_ID_ARMENIAN :: + * TT_MAC_ID_MALDIVIAN :: + * TT_MAC_ID_SIMPLIFIED_CHINESE :: + * TT_MAC_ID_TIBETAN :: + * TT_MAC_ID_MONGOLIAN :: + * TT_MAC_ID_GEEZ :: + * TT_MAC_ID_SLAVIC :: + * TT_MAC_ID_VIETNAMESE :: + * TT_MAC_ID_SINDHI :: + * TT_MAC_ID_UNINTERP :: + */ + +#define TT_MAC_ID_ROMAN 0 +#define TT_MAC_ID_JAPANESE 1 +#define TT_MAC_ID_TRADITIONAL_CHINESE 2 +#define TT_MAC_ID_KOREAN 3 +#define TT_MAC_ID_ARABIC 4 +#define TT_MAC_ID_HEBREW 5 +#define TT_MAC_ID_GREEK 6 +#define TT_MAC_ID_RUSSIAN 7 +#define TT_MAC_ID_RSYMBOL 8 +#define TT_MAC_ID_DEVANAGARI 9 +#define TT_MAC_ID_GURMUKHI 10 +#define TT_MAC_ID_GUJARATI 11 +#define TT_MAC_ID_ORIYA 12 +#define TT_MAC_ID_BENGALI 13 +#define TT_MAC_ID_TAMIL 14 +#define TT_MAC_ID_TELUGU 15 +#define TT_MAC_ID_KANNADA 16 +#define TT_MAC_ID_MALAYALAM 17 +#define TT_MAC_ID_SINHALESE 18 +#define TT_MAC_ID_BURMESE 19 +#define TT_MAC_ID_KHMER 20 +#define TT_MAC_ID_THAI 21 +#define TT_MAC_ID_LAOTIAN 22 +#define TT_MAC_ID_GEORGIAN 23 +#define TT_MAC_ID_ARMENIAN 24 +#define TT_MAC_ID_MALDIVIAN 25 +#define TT_MAC_ID_SIMPLIFIED_CHINESE 25 +#define TT_MAC_ID_TIBETAN 26 +#define TT_MAC_ID_MONGOLIAN 27 +#define TT_MAC_ID_GEEZ 28 +#define TT_MAC_ID_SLAVIC 29 +#define TT_MAC_ID_VIETNAMESE 30 +#define TT_MAC_ID_SINDHI 31 +#define TT_MAC_ID_UNINTERP 32 + + + /*********************************************************************** + * + * @enum: + * TT_ISO_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ISO charmaps and name entries. + * + * Their use is now deprecated. + * + * @values: + * TT_ISO_ID_7BIT_ASCII :: + * ASCII. + * TT_ISO_ID_10646 :: + * ISO/10646. + * TT_ISO_ID_8859_1 :: + * Also known as Latin-1. + */ + +#define TT_ISO_ID_7BIT_ASCII 0 +#define TT_ISO_ID_10646 1 +#define TT_ISO_ID_8859_1 2 + + + /*********************************************************************** + * + * @enum: + * TT_MS_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MICROSOFT charmaps and name entries. + * + * @values: + * TT_MS_ID_SYMBOL_CS :: + * Corresponds to Microsoft symbol encoding. See + * @FT_ENCODING_MS_SYMBOL. + * + * TT_MS_ID_UNICODE_CS :: + * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See + * @FT_ENCODING_UNICODE. + * + * TT_MS_ID_SJIS :: + * Corresponds to SJIS Japanese encoding. See @FT_ENCODING_SJIS. + * + * TT_MS_ID_GB2312 :: + * Corresponds to Simplified Chinese as used in Mainland China. See + * @FT_ENCODING_GB2312. + * + * TT_MS_ID_BIG_5 :: + * Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. + * See @FT_ENCODING_BIG5. + * + * TT_MS_ID_WANSUNG :: + * Corresponds to Korean Wansung encoding. See @FT_ENCODING_WANSUNG. + * + * TT_MS_ID_JOHAB :: + * Corresponds to Johab encoding. See @FT_ENCODING_JOHAB. + * + * TT_MS_ID_UCS_4 :: + * Corresponds to UCS-4 or UTF-32 charmaps. This has been added to + * the OpenType specification version 1.4 (mid-2001.) + */ + +#define TT_MS_ID_SYMBOL_CS 0 +#define TT_MS_ID_UNICODE_CS 1 +#define TT_MS_ID_SJIS 2 +#define TT_MS_ID_GB2312 3 +#define TT_MS_ID_BIG_5 4 +#define TT_MS_ID_WANSUNG 5 +#define TT_MS_ID_JOHAB 6 +#define TT_MS_ID_UCS_4 10 + + + /*********************************************************************** + * + * @enum: + * TT_ADOBE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! + * + * @values: + * TT_ADOBE_ID_STANDARD :: + * Adobe standard encoding. + * TT_ADOBE_ID_EXPERT :: + * Adobe expert encoding. + * TT_ADOBE_ID_CUSTOM :: + * Adobe custom encoding. + * TT_ADOBE_ID_LATIN_1 :: + * Adobe Latin~1 encoding. + */ + +#define TT_ADOBE_ID_STANDARD 0 +#define TT_ADOBE_ID_EXPERT 1 +#define TT_ADOBE_ID_CUSTOM 2 +#define TT_ADOBE_ID_LATIN_1 3 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MACINTOSH. These values are also used as return values */ + /* for function @FT_Get_CMap_Language_ID. */ + /* */ + /* The canonical source for the Apple assigned Language ID's is at */ + /* */ + /* https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html */ + /* */ +#define TT_MAC_LANGID_ENGLISH 0 +#define TT_MAC_LANGID_FRENCH 1 +#define TT_MAC_LANGID_GERMAN 2 +#define TT_MAC_LANGID_ITALIAN 3 +#define TT_MAC_LANGID_DUTCH 4 +#define TT_MAC_LANGID_SWEDISH 5 +#define TT_MAC_LANGID_SPANISH 6 +#define TT_MAC_LANGID_DANISH 7 +#define TT_MAC_LANGID_PORTUGUESE 8 +#define TT_MAC_LANGID_NORWEGIAN 9 +#define TT_MAC_LANGID_HEBREW 10 +#define TT_MAC_LANGID_JAPANESE 11 +#define TT_MAC_LANGID_ARABIC 12 +#define TT_MAC_LANGID_FINNISH 13 +#define TT_MAC_LANGID_GREEK 14 +#define TT_MAC_LANGID_ICELANDIC 15 +#define TT_MAC_LANGID_MALTESE 16 +#define TT_MAC_LANGID_TURKISH 17 +#define TT_MAC_LANGID_CROATIAN 18 +#define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 +#define TT_MAC_LANGID_URDU 20 +#define TT_MAC_LANGID_HINDI 21 +#define TT_MAC_LANGID_THAI 22 +#define TT_MAC_LANGID_KOREAN 23 +#define TT_MAC_LANGID_LITHUANIAN 24 +#define TT_MAC_LANGID_POLISH 25 +#define TT_MAC_LANGID_HUNGARIAN 26 +#define TT_MAC_LANGID_ESTONIAN 27 +#define TT_MAC_LANGID_LETTISH 28 +#define TT_MAC_LANGID_SAAMISK 29 +#define TT_MAC_LANGID_FAEROESE 30 +#define TT_MAC_LANGID_FARSI 31 +#define TT_MAC_LANGID_RUSSIAN 32 +#define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 +#define TT_MAC_LANGID_FLEMISH 34 +#define TT_MAC_LANGID_IRISH 35 +#define TT_MAC_LANGID_ALBANIAN 36 +#define TT_MAC_LANGID_ROMANIAN 37 +#define TT_MAC_LANGID_CZECH 38 +#define TT_MAC_LANGID_SLOVAK 39 +#define TT_MAC_LANGID_SLOVENIAN 40 +#define TT_MAC_LANGID_YIDDISH 41 +#define TT_MAC_LANGID_SERBIAN 42 +#define TT_MAC_LANGID_MACEDONIAN 43 +#define TT_MAC_LANGID_BULGARIAN 44 +#define TT_MAC_LANGID_UKRAINIAN 45 +#define TT_MAC_LANGID_BYELORUSSIAN 46 +#define TT_MAC_LANGID_UZBEK 47 +#define TT_MAC_LANGID_KAZAKH 48 +#define TT_MAC_LANGID_AZERBAIJANI 49 +#define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT 49 +#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 +#define TT_MAC_LANGID_ARMENIAN 51 +#define TT_MAC_LANGID_GEORGIAN 52 +#define TT_MAC_LANGID_MOLDAVIAN 53 +#define TT_MAC_LANGID_KIRGHIZ 54 +#define TT_MAC_LANGID_TAJIKI 55 +#define TT_MAC_LANGID_TURKMEN 56 +#define TT_MAC_LANGID_MONGOLIAN 57 +#define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT 57 +#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 +#define TT_MAC_LANGID_PASHTO 59 +#define TT_MAC_LANGID_KURDISH 60 +#define TT_MAC_LANGID_KASHMIRI 61 +#define TT_MAC_LANGID_SINDHI 62 +#define TT_MAC_LANGID_TIBETAN 63 +#define TT_MAC_LANGID_NEPALI 64 +#define TT_MAC_LANGID_SANSKRIT 65 +#define TT_MAC_LANGID_MARATHI 66 +#define TT_MAC_LANGID_BENGALI 67 +#define TT_MAC_LANGID_ASSAMESE 68 +#define TT_MAC_LANGID_GUJARATI 69 +#define TT_MAC_LANGID_PUNJABI 70 +#define TT_MAC_LANGID_ORIYA 71 +#define TT_MAC_LANGID_MALAYALAM 72 +#define TT_MAC_LANGID_KANNADA 73 +#define TT_MAC_LANGID_TAMIL 74 +#define TT_MAC_LANGID_TELUGU 75 +#define TT_MAC_LANGID_SINHALESE 76 +#define TT_MAC_LANGID_BURMESE 77 +#define TT_MAC_LANGID_KHMER 78 +#define TT_MAC_LANGID_LAO 79 +#define TT_MAC_LANGID_VIETNAMESE 80 +#define TT_MAC_LANGID_INDONESIAN 81 +#define TT_MAC_LANGID_TAGALOG 82 +#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 +#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 +#define TT_MAC_LANGID_AMHARIC 85 +#define TT_MAC_LANGID_TIGRINYA 86 +#define TT_MAC_LANGID_GALLA 87 +#define TT_MAC_LANGID_SOMALI 88 +#define TT_MAC_LANGID_SWAHILI 89 +#define TT_MAC_LANGID_RUANDA 90 +#define TT_MAC_LANGID_RUNDI 91 +#define TT_MAC_LANGID_CHEWA 92 +#define TT_MAC_LANGID_MALAGASY 93 +#define TT_MAC_LANGID_ESPERANTO 94 +#define TT_MAC_LANGID_WELSH 128 +#define TT_MAC_LANGID_BASQUE 129 +#define TT_MAC_LANGID_CATALAN 130 +#define TT_MAC_LANGID_LATIN 131 +#define TT_MAC_LANGID_QUECHUA 132 +#define TT_MAC_LANGID_GUARANI 133 +#define TT_MAC_LANGID_AYMARA 134 +#define TT_MAC_LANGID_TATAR 135 +#define TT_MAC_LANGID_UIGHUR 136 +#define TT_MAC_LANGID_DZONGKHA 137 +#define TT_MAC_LANGID_JAVANESE 138 +#define TT_MAC_LANGID_SUNDANESE 139 + + +#if 0 /* these seem to be errors that have been dropped */ + +#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 +#define TT_MAC_LANGID_IRISH_GAELIC 141 + +#endif + + + /* The following codes are new as of 2000-03-10 */ +#define TT_MAC_LANGID_GALICIAN 140 +#define TT_MAC_LANGID_AFRIKAANS 141 +#define TT_MAC_LANGID_BRETON 142 +#define TT_MAC_LANGID_INUKTITUT 143 +#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 +#define TT_MAC_LANGID_MANX_GAELIC 145 +#define TT_MAC_LANGID_IRISH_GAELIC 146 +#define TT_MAC_LANGID_TONGAN 147 +#define TT_MAC_LANGID_GREEK_POLYTONIC 148 +#define TT_MAC_LANGID_GREELANDIC 149 +#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MICROSOFT. */ + /* */ + /* The canonical source for the MS assigned LCIDs is */ + /* */ + /* http://www.microsoft.com/globaldev/reference/lcid-all.mspx */ + /* */ + +#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 +#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 +#define TT_MS_LANGID_ARABIC_IRAQ 0x0801 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0c01 +#define TT_MS_LANGID_ARABIC_LIBYA 0x1001 +#define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 +#define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1c01 +#define TT_MS_LANGID_ARABIC_OMAN 0x2001 +#define TT_MS_LANGID_ARABIC_YEMEN 0x2401 +#define TT_MS_LANGID_ARABIC_SYRIA 0x2801 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2c01 +#define TT_MS_LANGID_ARABIC_LEBANON 0x3001 +#define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 +#define TT_MS_LANGID_ARABIC_UAE 0x3801 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3c01 +#define TT_MS_LANGID_ARABIC_QATAR 0x4001 +#define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 +#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 +#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 +#define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 +#define TT_MS_LANGID_CHINESE_PRC 0x0804 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0c04 +#define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 + +#if 1 /* this looks like the correct value */ +#define TT_MS_LANGID_CHINESE_MACAU 0x1404 +#else /* but beware, Microsoft may change its mind... + the most recent Word reference has the following: */ +#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG +#endif + +#if 0 /* used only with .NET `cultures'; commented out */ +#define TT_MS_LANGID_CHINESE_TRADITIONAL 0x7C04 +#endif + +#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 +#define TT_MS_LANGID_DANISH_DENMARK 0x0406 +#define TT_MS_LANGID_GERMAN_GERMANY 0x0407 +#define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0c07 +#define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 +#define TT_MS_LANGID_GREEK_GREECE 0x0408 + + /* don't ask what this one means... It is commented out currently. */ +#if 0 +#define TT_MS_LANGID_GREEK_GREECE2 0x2008 +#endif + +#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 +#define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 +#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0c09 +#define TT_MS_LANGID_ENGLISH_CANADA 0x1009 +#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 +#define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1c09 +#define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 +#define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 +#define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2c09 +#define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 +#define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 +#define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3c09 +#define TT_MS_LANGID_ENGLISH_INDIA 0x4009 +#define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 +#define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040a +#define TT_MS_LANGID_SPANISH_MEXICO 0x080a +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0c0a +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100a +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140a +#define TT_MS_LANGID_SPANISH_PANAMA 0x180a +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1c0a +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200a +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240a +#define TT_MS_LANGID_SPANISH_PERU 0x280a +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2c0a +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300a +#define TT_MS_LANGID_SPANISH_CHILE 0x340a +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380a +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3c0a +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400a +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440a +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480a +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4c0a +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500a +#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540a + /* The following ID blatantly violate MS specs by using a */ + /* sublanguage > 0x1F. */ +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40aU +#define TT_MS_LANGID_FINNISH_FINLAND 0x040b +#define TT_MS_LANGID_FRENCH_FRANCE 0x040c +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080c +#define TT_MS_LANGID_FRENCH_CANADA 0x0c0c +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100c +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140c +#define TT_MS_LANGID_FRENCH_MONACO 0x180c +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1c0c +#define TT_MS_LANGID_FRENCH_REUNION 0x200c +#define TT_MS_LANGID_FRENCH_CONGO 0x240c + /* which was formerly: */ +#define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280c +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2c0c +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300c +#define TT_MS_LANGID_FRENCH_MALI 0x340c +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380c +#define TT_MS_LANGID_FRENCH_HAITI 0x3c0c + /* and another violation of the spec (see 0xE40aU) */ +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40cU +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040d +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040e +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040f +#define TT_MS_LANGID_ITALIAN_ITALY 0x0410 +#define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 +#define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 +#define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 +#define TT_MS_LANGID_POLISH_POLAND 0x0415 +#define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 +#define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 +#define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 +#define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041a +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081a +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0c1a + +#if 0 /* this used to be this value, but it looks like we were wrong */ +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101a +#else /* current sources say */ +#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101a +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141a + /* and XPsp2 Platform SDK added (2004-07-26) */ + /* Names are shortened to be significant within 40 chars. */ +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181a +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181a +#endif + +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041b +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041c +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041d +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081d +#define TT_MS_LANGID_THAI_THAILAND 0x041e +#define TT_MS_LANGID_TURKISH_TURKEY 0x041f +#define TT_MS_LANGID_URDU_PAKISTAN 0x0420 +#define TT_MS_LANGID_URDU_INDIA 0x0820 +#define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 +#define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 +#define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 +#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 +#define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 +#define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 +#define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 +#define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 +#define TT_MS_LANGID_FARSI_IRAN 0x0429 +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042a +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042b +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042c +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082c +#define TT_MS_LANGID_BASQUE_SPAIN 0x042d +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042e +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042f +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 +#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 +#define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 +#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 +#define TT_MS_LANGID_HINDI_INDIA 0x0439 +#define TT_MS_LANGID_MALTESE_MALTA 0x043a + /* Added by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043b +#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083b +#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3b +#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103b +#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143b +#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183b +#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3b +#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203b +#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243b + /* ... and we also keep our old identifier... */ +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043b + +#if 0 /* this seems to be a previous inversion */ +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#else +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#endif + +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043d +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043e +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083e +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043f +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ + TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN + +#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 +#define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 +#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 +#define TT_MS_LANGID_BENGALI_INDIA 0x0445 +#define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 +#define TT_MS_LANGID_PUNJABI_INDIA 0x0446 +#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 +#define TT_MS_LANGID_GUJARATI_INDIA 0x0447 +#define TT_MS_LANGID_ORIYA_INDIA 0x0448 +#define TT_MS_LANGID_TAMIL_INDIA 0x0449 +#define TT_MS_LANGID_TELUGU_INDIA 0x044a +#define TT_MS_LANGID_KANNADA_INDIA 0x044b +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044c +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044d +#define TT_MS_LANGID_MARATHI_INDIA 0x044e +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044f +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 +#define TT_MS_LANGID_TIBETAN_CHINA 0x0451 + /* Don't use the next constant! It has */ + /* (1) the wrong spelling (Dzonghka) */ + /* (2) Microsoft doesn't officially define it -- */ + /* at least it is not in the List of Local */ + /* ID Values. */ + /* (3) Dzongkha is not the same language as */ + /* Tibetan, so merging it is wrong anyway. */ + /* */ + /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW. */ +#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 + +#if 0 + /* the following used to be defined */ +#define TT_MS_LANGID_TIBETAN_BHUTAN 0x0451 + /* ... but it was changed; */ +#else + /* So we will continue to #define it, but with the correct value */ +#define TT_MS_LANGID_TIBETAN_BHUTAN TT_MS_LANGID_DZONGHKA_BHUTAN +#endif + +#define TT_MS_LANGID_WELSH_WALES 0x0452 +#define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 +#define TT_MS_LANGID_LAO_LAOS 0x0454 +#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 +#define TT_MS_LANGID_GALICIAN_SPAIN 0x0456 +#define TT_MS_LANGID_KONKANI_INDIA 0x0457 +#define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 +#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 +#define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 + /* Missing a LCID for Sindhi in Devanagari script */ +#define TT_MS_LANGID_SYRIAC_SYRIA 0x045a +#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045b +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045c +#define TT_MS_LANGID_INUKTITUT_CANADA 0x045d +#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045e +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045f +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085f + /* Missing a LCID for Tifinagh script */ +#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 + /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ + /* script is yet unclear... might be Arabic, Nagari or Sharada */ +#define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 + /* ... and aliased (by MS) for compatibility reasons. */ +#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA +#define TT_MS_LANGID_NEPALI_NEPAL 0x0461 +#define TT_MS_LANGID_NEPALI_INDIA 0x0861 +#define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 +#define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 +#define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 +#define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_DIVEHI_MALDIVES TT_MS_LANGID_DHIVEHI_MALDIVES +#define TT_MS_LANGID_EDO_NIGERIA 0x0466 +#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 +#define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 +#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 +#define TT_MS_LANGID_YORUBA_NIGERIA 0x046a +#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046b +#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086b +#define TT_MS_LANGID_QUECHUA_PERU 0x0c6b +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046c + /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ + TT_MS_LANGID_SEPEDI_SOUTH_AFRICA + /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */ +#define TT_MS_LANGID_IGBO_NIGERIA 0x0470 +#define TT_MS_LANGID_KANURI_NIGERIA 0x0471 +#define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 +#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 +#define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 + /* also spelled in the `Passport SDK' list as: */ +#define TT_MS_LANGID_TIGRIGNA_ERYTREA TT_MS_LANGID_TIGRIGNA_ERYTHREA +#define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 +#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 +#define TT_MS_LANGID_LATIN 0x0476 +#define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 + /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */ + /* not written (but OTOH the peculiar writing system is worth */ + /* studying). */ +#define TT_MS_LANGID_YI_CHINA 0x0478 +#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 + /* language codes from 0x047a to 0x047f are (still) unknown. */ +#define TT_MS_LANGID_UIGHUR_CHINA 0x0480 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 + +#if 0 /* not deemed useful for fonts */ +#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04ff +#endif + + + /*************************************************************************/ + /* */ + /* Possible values of the `name' identifier field in the name records of */ + /* the TTF `name' table. These values are platform independent. */ + /* */ +#define TT_NAME_ID_COPYRIGHT 0 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 +#define TT_NAME_ID_FULL_NAME 4 +#define TT_NAME_ID_VERSION_STRING 5 +#define TT_NAME_ID_PS_NAME 6 +#define TT_NAME_ID_TRADEMARK 7 + + /* the following values are from the OpenType spec */ +#define TT_NAME_ID_MANUFACTURER 8 +#define TT_NAME_ID_DESIGNER 9 +#define TT_NAME_ID_DESCRIPTION 10 +#define TT_NAME_ID_VENDOR_URL 11 +#define TT_NAME_ID_DESIGNER_URL 12 +#define TT_NAME_ID_LICENSE 13 +#define TT_NAME_ID_LICENSE_URL 14 + /* number 15 is reserved */ +#define TT_NAME_ID_PREFERRED_FAMILY 16 +#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 +#define TT_NAME_ID_MAC_FULL_NAME 18 + + /* The following code is new as of 2000-01-21 */ +#define TT_NAME_ID_SAMPLE_TEXT 19 + + /* This is new in OpenType 1.3 */ +#define TT_NAME_ID_CID_FINDFONT_NAME 20 + + /* This is new in OpenType 1.5 */ +#define TT_NAME_ID_WWS_FAMILY 21 +#define TT_NAME_ID_WWS_SUBFAMILY 22 + + + /*************************************************************************/ + /* */ + /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ + /* */ + /* Updated 08-Nov-2008. */ + /* */ + + /* Bit 0 Basic Latin */ +#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ + /* Bit 1 C1 Controls and Latin-1 Supplement */ +#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ + /* Bit 2 Latin Extended-A */ +#define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ + /* Bit 3 Latin Extended-B */ +#define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ + /* Bit 4 IPA Extensions */ + /* Phonetic Extensions */ + /* Phonetic Extensions Supplement */ +#define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ + /* U+1D00-U+1D7F */ + /* U+1D80-U+1DBF */ + /* Bit 5 Spacing Modifier Letters */ + /* Modifier Tone Letters */ +#define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ + /* U+A700-U+A71F */ + /* Bit 6 Combining Diacritical Marks */ + /* Combining Diacritical Marks Supplement */ +#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ + /* U+1DC0-U+1DFF */ + /* Bit 7 Greek and Coptic */ +#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ + /* Bit 8 Coptic */ +#define TT_UCR_COPTIC (1L << 8) /* U+2C80-U+2CFF */ + /* Bit 9 Cyrillic */ + /* Cyrillic Supplement */ + /* Cyrillic Extended-A */ + /* Cyrillic Extended-B */ +#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ + /* U+0500-U+052F */ + /* U+2DE0-U+2DFF */ + /* U+A640-U+A69F */ + /* Bit 10 Armenian */ +#define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ + /* Bit 11 Hebrew */ +#define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ + /* Bit 12 Vai */ +#define TT_UCR_VAI (1L << 12) /* U+A500-U+A63F */ + /* Bit 13 Arabic */ + /* Arabic Supplement */ +#define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ + /* U+0750-U+077F */ + /* Bit 14 NKo */ +#define TT_UCR_NKO (1L << 14) /* U+07C0-U+07FF */ + /* Bit 15 Devanagari */ +#define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ + /* Bit 16 Bengali */ +#define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ + /* Bit 17 Gurmukhi */ +#define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ + /* Bit 18 Gujarati */ +#define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ + /* Bit 19 Oriya */ +#define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ + /* Bit 20 Tamil */ +#define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ + /* Bit 21 Telugu */ +#define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ + /* Bit 22 Kannada */ +#define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ + /* Bit 23 Malayalam */ +#define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ + /* Bit 24 Thai */ +#define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ + /* Bit 25 Lao */ +#define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ + /* Bit 26 Georgian */ + /* Georgian Supplement */ +#define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ + /* U+2D00-U+2D2F */ + /* Bit 27 Balinese */ +#define TT_UCR_BALINESE (1L << 27) /* U+1B00-U+1B7F */ + /* Bit 28 Hangul Jamo */ +#define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ + /* Bit 29 Latin Extended Additional */ + /* Latin Extended-C */ + /* Latin Extended-D */ +#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ + /* U+2C60-U+2C7F */ + /* U+A720-U+A7FF */ + /* Bit 30 Greek Extended */ +#define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ + /* Bit 31 General Punctuation */ + /* Supplemental Punctuation */ +#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ + /* U+2E00-U+2E7F */ + /* Bit 32 Superscripts And Subscripts */ +#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ + /* Bit 33 Currency Symbols */ +#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ + /* Bit 34 Combining Diacritical Marks For Symbols */ +#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ + /* Bit 35 Letterlike Symbols */ +#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ + /* Bit 36 Number Forms */ +#define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ + /* Bit 37 Arrows */ + /* Supplemental Arrows-A */ + /* Supplemental Arrows-B */ + /* Miscellaneous Symbols and Arrows */ +#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ + /* U+27F0-U+27FF */ + /* U+2900-U+297F */ + /* U+2B00-U+2BFF */ + /* Bit 38 Mathematical Operators */ + /* Supplemental Mathematical Operators */ + /* Miscellaneous Mathematical Symbols-A */ + /* Miscellaneous Mathematical Symbols-B */ +#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ + /* U+2A00-U+2AFF */ + /* U+27C0-U+27EF */ + /* U+2980-U+29FF */ + /* Bit 39 Miscellaneous Technical */ +#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ + /* Bit 40 Control Pictures */ +#define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ + /* Bit 41 Optical Character Recognition */ +#define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ + /* Bit 42 Enclosed Alphanumerics */ +#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ + /* Bit 43 Box Drawing */ +#define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ + /* Bit 44 Block Elements */ +#define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ + /* Bit 45 Geometric Shapes */ +#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ + /* Bit 46 Miscellaneous Symbols */ +#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ + /* Bit 47 Dingbats */ +#define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ + /* Bit 48 CJK Symbols and Punctuation */ +#define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ + /* Bit 49 Hiragana */ +#define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ + /* Bit 50 Katakana */ + /* Katakana Phonetic Extensions */ +#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ + /* U+31F0-U+31FF */ + /* Bit 51 Bopomofo */ + /* Bopomofo Extended */ +#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ + /* U+31A0-U+31BF */ + /* Bit 52 Hangul Compatibility Jamo */ +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ + /* Bit 53 Phags-Pa */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+A840-U+A87F */ +#define TT_UCR_KANBUN TT_UCR_CJK_MISC /* deprecated */ +#define TT_UCR_PHAGSPA + /* Bit 54 Enclosed CJK Letters and Months */ +#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ + /* Bit 55 CJK Compatibility */ +#define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ + /* Bit 56 Hangul Syllables */ +#define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ + /* Bit 57 High Surrogates */ + /* High Private Use Surrogates */ + /* Low Surrogates */ + /* */ + /* According to OpenType specs v.1.3+, */ + /* setting bit 57 implies that there is */ + /* at least one codepoint beyond the */ + /* Basic Multilingual Plane that is */ + /* supported by this font. So it really */ + /* means >= U+10000 */ +#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ + /* U+DB80-U+DBFF */ + /* U+DC00-U+DFFF */ +#define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES + /* Bit 58 Phoenician */ +#define TT_UCR_PHOENICIAN (1L << 26) /*U+10900-U+1091F*/ + /* Bit 59 CJK Unified Ideographs */ + /* CJK Radicals Supplement */ + /* Kangxi Radicals */ + /* Ideographic Description Characters */ + /* CJK Unified Ideographs Extension A */ + /* CJK Unified Ideographs Extension B */ + /* Kanbun */ +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ + /* U+2E80-U+2EFF */ + /* U+2F00-U+2FDF */ + /* U+2FF0-U+2FFF */ + /* U+3400-U+4DB5 */ + /*U+20000-U+2A6DF*/ + /* U+3190-U+319F */ + /* Bit 60 Private Use */ +#define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ + /* Bit 61 CJK Strokes */ + /* CJK Compatibility Ideographs */ + /* CJK Compatibility Ideographs Supplement */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+31C0-U+31EF */ + /* U+F900-U+FAFF */ + /*U+2F800-U+2FA1F*/ + /* Bit 62 Alphabetic Presentation Forms */ +#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ + /* Bit 63 Arabic Presentation Forms-A */ +#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ + /* Bit 64 Combining Half Marks */ +#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ + /* Bit 65 Vertical forms */ + /* CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE10-U+FE1F */ + /* U+FE30-U+FE4F */ + /* Bit 66 Small Form Variants */ +#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ + /* Bit 67 Arabic Presentation Forms-B */ +#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFE */ + /* Bit 68 Halfwidth and Fullwidth Forms */ +#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ + /* Bit 69 Specials */ +#define TT_UCR_SPECIALS (1L << 5) /* U+FFF0-U+FFFD */ + /* Bit 70 Tibetan */ +#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FFF */ + /* Bit 71 Syriac */ +#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ + /* Bit 72 Thaana */ +#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ + /* Bit 73 Sinhala */ +#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ + /* Bit 74 Myanmar */ +#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ + /* Bit 75 Ethiopic */ + /* Ethiopic Supplement */ + /* Ethiopic Extended */ +#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ + /* U+1380-U+139F */ + /* U+2D80-U+2DDF */ + /* Bit 76 Cherokee */ +#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ + /* Bit 77 Unified Canadian Aboriginal Syllabics */ +#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+167F */ + /* Bit 78 Ogham */ +#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ + /* Bit 79 Runic */ +#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ + /* Bit 80 Khmer */ + /* Khmer Symbols */ +#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ + /* U+19E0-U+19FF */ + /* Bit 81 Mongolian */ +#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ + /* Bit 82 Braille Patterns */ +#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ + /* Bit 83 Yi Syllables */ + /* Yi Radicals */ +#define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ + /* U+A490-U+A4CF */ + /* Bit 84 Tagalog */ + /* Hanunoo */ + /* Buhid */ + /* Tagbanwa */ +#define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ + /* U+1720-U+173F */ + /* U+1740-U+175F */ + /* U+1760-U+177F */ + /* Bit 85 Old Italic */ +#define TT_UCR_OLD_ITALIC (1L << 21) /*U+10300-U+1032F*/ + /* Bit 86 Gothic */ +#define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ + /* Bit 87 Deseret */ +#define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ + /* Bit 88 Byzantine Musical Symbols */ + /* Musical Symbols */ + /* Ancient Greek Musical Notation */ +#define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ + /*U+1D100-U+1D1FF*/ + /*U+1D200-U+1D24F*/ + /* Bit 89 Mathematical Alphanumeric Symbols */ +#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ + /* Bit 90 Private Use (plane 15) */ + /* Private Use (plane 16) */ +#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ + /*U+100000-U+10FFFD*/ + /* Bit 91 Variation Selectors */ + /* Variation Selectors Supplement */ +#define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ + /*U+E0100-U+E01EF*/ + /* Bit 92 Tags */ +#define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ + /* Bit 93 Limbu */ +#define TT_UCR_LIMBU (1L << 29) /* U+1900-U+194F */ + /* Bit 94 Tai Le */ +#define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ + /* Bit 95 New Tai Lue */ +#define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ + /* Bit 96 Buginese */ +#define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ + /* Bit 97 Glagolitic */ +#define TT_UCR_GLAGOLITIC (1L << 1) /* U+2C00-U+2C5F */ + /* Bit 98 Tifinagh */ +#define TT_UCR_TIFINAGH (1L << 2) /* U+2D30-U+2D7F */ + /* Bit 99 Yijing Hexagram Symbols */ +#define TT_UCR_YIJING (1L << 3) /* U+4DC0-U+4DFF */ + /* Bit 100 Syloti Nagri */ +#define TT_UCR_SYLOTI_NAGRI (1L << 4) /* U+A800-U+A82F */ + /* Bit 101 Linear B Syllabary */ + /* Linear B Ideograms */ + /* Aegean Numbers */ +#define TT_UCR_LINEAR_B (1L << 5) /*U+10000-U+1007F*/ + /*U+10080-U+100FF*/ + /*U+10100-U+1013F*/ + /* Bit 102 Ancient Greek Numbers */ +#define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) /*U+10140-U+1018F*/ + /* Bit 103 Ugaritic */ +#define TT_UCR_UGARITIC (1L << 7) /*U+10380-U+1039F*/ + /* Bit 104 Old Persian */ +#define TT_UCR_OLD_PERSIAN (1L << 8) /*U+103A0-U+103DF*/ + /* Bit 105 Shavian */ +#define TT_UCR_SHAVIAN (1L << 9) /*U+10450-U+1047F*/ + /* Bit 106 Osmanya */ +#define TT_UCR_OSMANYA (1L << 10) /*U+10480-U+104AF*/ + /* Bit 107 Cypriot Syllabary */ +#define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) /*U+10800-U+1083F*/ + /* Bit 108 Kharoshthi */ +#define TT_UCR_KHAROSHTHI (1L << 12) /*U+10A00-U+10A5F*/ + /* Bit 109 Tai Xuan Jing Symbols */ +#define TT_UCR_TAI_XUAN_JING (1L << 13) /*U+1D300-U+1D35F*/ + /* Bit 110 Cuneiform */ + /* Cuneiform Numbers and Punctuation */ +#define TT_UCR_CUNEIFORM (1L << 14) /*U+12000-U+123FF*/ + /*U+12400-U+1247F*/ + /* Bit 111 Counting Rod Numerals */ +#define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) /*U+1D360-U+1D37F*/ + /* Bit 112 Sundanese */ +#define TT_UCR_SUNDANESE (1L << 16) /* U+1B80-U+1BBF */ + /* Bit 113 Lepcha */ +#define TT_UCR_LEPCHA (1L << 17) /* U+1C00-U+1C4F */ + /* Bit 114 Ol Chiki */ +#define TT_UCR_OL_CHIKI (1L << 18) /* U+1C50-U+1C7F */ + /* Bit 115 Saurashtra */ +#define TT_UCR_SAURASHTRA (1L << 19) /* U+A880-U+A8DF */ + /* Bit 116 Kayah Li */ +#define TT_UCR_KAYAH_LI (1L << 20) /* U+A900-U+A92F */ + /* Bit 117 Rejang */ +#define TT_UCR_REJANG (1L << 21) /* U+A930-U+A95F */ + /* Bit 118 Cham */ +#define TT_UCR_CHAM (1L << 22) /* U+AA00-U+AA5F */ + /* Bit 119 Ancient Symbols */ +#define TT_UCR_ANCIENT_SYMBOLS (1L << 23) /*U+10190-U+101CF*/ + /* Bit 120 Phaistos Disc */ +#define TT_UCR_PHAISTOS_DISC (1L << 24) /*U+101D0-U+101FF*/ + /* Bit 121 Carian */ + /* Lycian */ + /* Lydian */ +#define TT_UCR_OLD_ANATOLIAN (1L << 25) /*U+102A0-U+102DF*/ + /*U+10280-U+1029F*/ + /*U+10920-U+1093F*/ + /* Bit 122 Domino Tiles */ + /* Mahjong Tiles */ +#define TT_UCR_GAME_TILES (1L << 26) /*U+1F030-U+1F09F*/ + /*U+1F000-U+1F02F*/ + /* Bit 123-127 Reserved for process-internal usage */ + + + /*************************************************************************/ + /* */ + /* Some compilers have a very limited length of identifiers. */ + /* */ +#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) +#define HAVE_LIMIT_ON_IDENTS +#endif + + +#ifndef HAVE_LIMIT_ON_IDENTS + + + /*************************************************************************/ + /* */ + /* Here some alias #defines in order to be clearer. */ + /* */ + /* These are not always #defined to stay within the 31~character limit */ + /* which some compilers have. */ + /* */ + /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ + /* Borland compilers (read: from BC++ 3.1 on) can increase this limit. */ + /* If you get a warning with such a compiler, use the -i40 switch. */ + /* */ +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ + TT_UCR_ARABIC_PRESENTATIONS_A +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ + TT_UCR_ARABIC_PRESENTATIONS_B + +#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ + TT_UCR_COMBINING_DIACRITICS +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ + TT_UCR_COMBINING_DIACRITICS_SYMB + + +#endif /* !HAVE_LIMIT_ON_IDENTS */ + + +FT_END_HEADER + +#endif /* __TTNAMEID_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/tttables.h b/drivers/freetype/include/freetype/tttables.h new file mode 100644 index 0000000000..fe07117b0b --- /dev/null +++ b/drivers/freetype/include/freetype/tttables.h @@ -0,0 +1,777 @@ +/***************************************************************************/ +/* */ +/* tttables.h */ +/* */ +/* Basic SFNT/TrueType tables definitions and interface */ +/* (specification only). */ +/* */ +/* Copyright 1996-2005, 2008-2012 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 __TTTABLES_H__ +#define __TTTABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + /* <Title> */ + /* TrueType Tables */ + /* */ + /* <Abstract> */ + /* TrueType specific table types and functions. */ + /* */ + /* <Description> */ + /* This section contains the definition of TrueType-specific tables */ + /* as well as some routines used to access and process them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Header */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType font header table. All */ + /* fields follow the TrueType specification. */ + /* */ + typedef struct TT_Header_ + { + FT_Fixed Table_Version; + FT_Fixed Font_Revision; + + FT_Long CheckSum_Adjust; + FT_Long Magic_Number; + + FT_UShort Flags; + FT_UShort Units_Per_EM; + + FT_Long Created [2]; + FT_Long Modified[2]; + + FT_Short xMin; + FT_Short yMin; + FT_Short xMax; + FT_Short yMax; + + FT_UShort Mac_Style; + FT_UShort Lowest_Rec_PPEM; + + FT_Short Font_Direction; + FT_Short Index_To_Loc_Format; + FT_Short Glyph_Data_Format; + + } TT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HoriHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType horizontal header, the `hhea' */ + /* table, as well as the corresponding horizontal metrics table, */ + /* i.e., the `hmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of all */ + /* glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoAscender' field */ + /* of the OS/2 table instead if you want */ + /* the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the distance */ + /* from the baseline to the bottom-most of */ + /* all glyph points found in the font. It */ + /* is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Width_Max :: This field is the maximum of all advance */ + /* widths found in the font. It can be */ + /* used to compute the maximum width of an */ + /* arbitrary string of text. */ + /* */ + /* min_Left_Side_Bearing :: The minimum left side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Right_Side_Bearing :: The minimum right side bearing of all */ + /* glyphs within the font. */ + /* */ + /* xMax_Extent :: The maximum horizontal extent (i.e., the */ + /* `width' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ + /* table -- this value can be smaller than */ + /* the total number of glyphs in the font. */ + /* */ + /* long_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields which */ + /* are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_HoriHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Width_Max; /* advance width maximum */ + + FT_Short min_Left_Side_Bearing; /* minimum left-sb */ + FT_Short min_Right_Side_Bearing; /* minimum right-sb */ + FT_Short xMax_Extent; /* xmax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_HMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they are used to connect the metrics header to the relevant */ + /* `HMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_HoriHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_VertHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType vertical header, the `vhea' */ + /* table, as well as the corresponding vertical metrics table, i.e., */ + /* the `vmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of */ + /* all glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoAscender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the */ + /* distance from the baseline to the */ + /* bottom-most of all glyph points found */ + /* in the font. It is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Height_Max :: This field is the maximum of all */ + /* advance heights found in the font. It */ + /* can be used to compute the maximum */ + /* height of an arbitrary string of text. */ + /* */ + /* min_Top_Side_Bearing :: The minimum top side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ + /* glyphs within the font. */ + /* */ + /* yMax_Extent :: The maximum vertical extent (i.e., the */ + /* `height' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* caret_Offset :: The cursor's offset for slanted fonts. */ + /* This value is `reserved' in vmtx */ + /* version 1.0. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of VMetrics entries in the */ + /* `vmtx' table -- this value can be */ + /* smaller than the total number of glyphs */ + /* in the font. */ + /* */ + /* long_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields which */ + /* are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_VertHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Height_Max; /* advance height maximum */ + + FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ + FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ + FT_Short yMax_Extent; /* xmax or ymax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_VMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_VertHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_OS2 */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType OS/2 table. This is the long */ + /* table version. All fields comply to the TrueType specification. */ + /* */ + /* Note that we now support old Mac fonts which do not include an */ + /* OS/2 table. In this case, the `version' field is always set to */ + /* 0xFFFF. */ + /* */ + typedef struct TT_OS2_ + { + FT_UShort version; /* 0x0001 - more or 0xFFFF */ + FT_Short xAvgCharWidth; + FT_UShort usWeightClass; + FT_UShort usWidthClass; + FT_Short fsType; + FT_Short ySubscriptXSize; + FT_Short ySubscriptYSize; + FT_Short ySubscriptXOffset; + FT_Short ySubscriptYOffset; + FT_Short ySuperscriptXSize; + FT_Short ySuperscriptYSize; + FT_Short ySuperscriptXOffset; + FT_Short ySuperscriptYOffset; + FT_Short yStrikeoutSize; + FT_Short yStrikeoutPosition; + FT_Short sFamilyClass; + + FT_Byte panose[10]; + + FT_ULong ulUnicodeRange1; /* Bits 0-31 */ + FT_ULong ulUnicodeRange2; /* Bits 32-63 */ + FT_ULong ulUnicodeRange3; /* Bits 64-95 */ + FT_ULong ulUnicodeRange4; /* Bits 96-127 */ + + FT_Char achVendID[4]; + + FT_UShort fsSelection; + FT_UShort usFirstCharIndex; + FT_UShort usLastCharIndex; + FT_Short sTypoAscender; + FT_Short sTypoDescender; + FT_Short sTypoLineGap; + FT_UShort usWinAscent; + FT_UShort usWinDescent; + + /* only version 1 tables: */ + + FT_ULong ulCodePageRange1; /* Bits 0-31 */ + FT_ULong ulCodePageRange2; /* Bits 32-63 */ + + /* only version 2 tables: */ + + FT_Short sxHeight; + FT_Short sCapHeight; + FT_UShort usDefaultChar; + FT_UShort usBreakChar; + FT_UShort usMaxContext; + + } TT_OS2; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Postscript */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PostScript table. All fields */ + /* comply to the TrueType specification. This structure does not */ + /* reference the PostScript glyph names, which can be nevertheless */ + /* accessed with the `ttpost' module. */ + /* */ + typedef struct TT_Postscript_ + { + FT_Fixed FormatType; + FT_Fixed italicAngle; + FT_Short underlinePosition; + FT_Short underlineThickness; + FT_ULong isFixedPitch; + FT_ULong minMemType42; + FT_ULong maxMemType42; + FT_ULong minMemType1; + FT_ULong maxMemType1; + + /* Glyph names follow in the file, but we don't */ + /* load them by default. See the ttpost.c file. */ + + } TT_Postscript; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_PCLT */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PCLT table. All fields */ + /* comply to the TrueType specification. */ + /* */ + typedef struct TT_PCLT_ + { + FT_Fixed Version; + FT_ULong FontNumber; + FT_UShort Pitch; + FT_UShort xHeight; + FT_UShort Style; + FT_UShort TypeFamily; + FT_UShort CapHeight; + FT_UShort SymbolSet; + FT_Char TypeFace[16]; + FT_Char CharacterComplement[8]; + FT_Char FileName[6]; + FT_Char StrokeWeight; + FT_Char WidthType; + FT_Byte SerifStyle; + FT_Byte Reserved; + + } TT_PCLT; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_MaxProfile */ + /* */ + /* <Description> */ + /* The maximum profile is a table containing many max values which */ + /* can be used to pre-allocate arrays. This ensures that no memory */ + /* allocation occurs during a glyph load. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numGlyphs :: The number of glyphs in this TrueType */ + /* font. */ + /* */ + /* maxPoints :: The maximum number of points in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositePoints'. */ + /* */ + /* maxContours :: The maximum number of contours in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositeContours'. */ + /* */ + /* maxCompositePoints :: The maximum number of points in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxPoints'. */ + /* */ + /* maxCompositeContours :: The maximum number of contours in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxContours'. */ + /* */ + /* maxZones :: The maximum number of zones used for */ + /* glyph hinting. */ + /* */ + /* maxTwilightPoints :: The maximum number of points in the */ + /* twilight zone used for glyph hinting. */ + /* */ + /* maxStorage :: The maximum number of elements in the */ + /* storage area used for glyph hinting. */ + /* */ + /* maxFunctionDefs :: The maximum number of function */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxInstructionDefs :: The maximum number of instruction */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxStackElements :: The maximum number of stack elements used */ + /* during bytecode interpretation. */ + /* */ + /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ + /* used for glyph hinting. */ + /* */ + /* maxComponentElements :: The maximum number of simple (i.e., non- */ + /* composite) glyphs in a composite glyph. */ + /* */ + /* maxComponentDepth :: The maximum nesting depth of composite */ + /* glyphs. */ + /* */ + /* <Note> */ + /* This structure is only used during font loading. */ + /* */ + typedef struct TT_MaxProfile_ + { + FT_Fixed version; + FT_UShort numGlyphs; + FT_UShort maxPoints; + FT_UShort maxContours; + FT_UShort maxCompositePoints; + FT_UShort maxCompositeContours; + FT_UShort maxZones; + FT_UShort maxTwilightPoints; + FT_UShort maxStorage; + FT_UShort maxFunctionDefs; + FT_UShort maxInstructionDefs; + FT_UShort maxStackElements; + FT_UShort maxSizeOfInstructions; + FT_UShort maxComponentElements; + FT_UShort maxComponentDepth; + + } TT_MaxProfile; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Sfnt_Tag */ + /* */ + /* <Description> */ + /* An enumeration used to specify the index of an SFNT table. */ + /* Used in the @FT_Get_Sfnt_Table API function. */ + /* */ + typedef enum FT_Sfnt_Tag_ + { + ft_sfnt_head = 0, /* TT_Header */ + ft_sfnt_maxp = 1, /* TT_MaxProfile */ + ft_sfnt_os2 = 2, /* TT_OS2 */ + ft_sfnt_hhea = 3, /* TT_HoriHeader */ + ft_sfnt_vhea = 4, /* TT_VertHeader */ + ft_sfnt_post = 5, /* TT_Postscript */ + ft_sfnt_pclt = 6, /* TT_PCLT */ + + sfnt_max /* internal end mark */ + + } FT_Sfnt_Tag; + + /* */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Table */ + /* */ + /* <Description> */ + /* Return a pointer to a given SFNT table within a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source. */ + /* */ + /* tag :: The index of the SFNT table. */ + /* */ + /* <Return> */ + /* A type-less pointer to the table. This will be~0 in case of */ + /* error, or if the corresponding table was not found *OR* loaded */ + /* from the file. */ + /* */ + /* Use a typecast according to `tag' to access the structure */ + /* elements. */ + /* */ + /* <Note> */ + /* The table is owned by the face object and disappears with it. */ + /* */ + /* This function is only useful to access SFNT tables that are loaded */ + /* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */ + /* a list. */ + /* */ + /* Here an example how to access the `vhea' table: */ + /* */ + /* { */ + /* TT_VertHeader* vert_header; */ + /* */ + /* */ + /* vert_header = */ + /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, ft_sfnt_vhea ); */ + /* } */ + /* */ + FT_EXPORT( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ); + + + /************************************************************************** + * + * @function: + * FT_Load_Sfnt_Table + * + * @description: + * Load any font table into client memory. + * + * @input: + * face :: + * A handle to the source face. + * + * tag :: + * The four-byte tag of the table to load. Use the value~0 if you want + * 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). + * + * @output: + * buffer :: + * The target buffer address. The client must ensure that the memory + * array is big enough to hold the data. + * + * @inout: + * length :: + * 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 + * table's (or file) full size in it. + * + * Else the number of bytes to read from the table or file, from the + * starting offset. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If you need to determine the table's length you should first call this + * function with `*length' set to~0, as in the following example: + * + * { + * FT_ULong length = 0; + * + * + * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + * if ( error ) { ... table does not exist ... } + * + * buffer = malloc( length ); + * if ( buffer == NULL ) { ... not enough memory ... } + * + * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); + * if ( error ) { ... could not load table ... } + * } + */ + FT_EXPORT( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + /************************************************************************** + * + * @function: + * FT_Sfnt_Table_Info + * + * @description: + * Return information on an SFNT table. + * + * @input: + * face :: + * A handle to the source face. + * + * table_index :: + * The index of an SFNT table. The function returns + * FT_Err_Table_Missing for an invalid value. + * + * @inout: + * tag :: + * The name tag of the SFNT table. If the value is NULL, `table_index' + * is ignored, and `length' returns the number of SFNT tables in the + * font. + * + * @output: + * length :: + * The length of the SFNT table (or the number of SFNT tables, depending + * on `tag'). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * While parsing fonts, FreeType handles SFNT tables with length zero as + * missing. + * + */ + FT_EXPORT( FT_Error ) + FT_Sfnt_Table_Info( FT_Face face, + FT_UInt table_index, + FT_ULong *tag, + FT_ULong *length ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Language_ID */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap language ID. Definitions of */ + /* language ID values are in `freetype/ttnameid.h'. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The language ID of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, just return~0 as the default value. */ + /* */ + /* For a format~14 cmap (to access Unicode IVS), the return value is */ + /* 0xFFFFFFFF. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Format */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap format. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The format of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, return -1. */ + /* */ + FT_EXPORT( FT_Long ) + FT_Get_CMap_Format( FT_CharMap charmap ); + + /* */ + + +FT_END_HEADER + +#endif /* __TTTABLES_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/tttags.h b/drivers/freetype/include/freetype/tttags.h new file mode 100644 index 0000000000..be8c524edb --- /dev/null +++ b/drivers/freetype/include/freetype/tttags.h @@ -0,0 +1,109 @@ +/***************************************************************************/ +/* */ +/* tttags.h */ +/* */ +/* Tags for TrueType and OpenType tables (specification only). */ +/* */ +/* Copyright 1996-2001, 2004, 2005, 2007, 2008, 2013 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 __TTAGS_H__ +#define __TTAGS_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + +#define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' ) +#define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' ) +#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) +#define TTAG_BDF FT_MAKE_TAG( 'B', 'D', 'F', ' ' ) +#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) +#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) +#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) +#define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' ) +#define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' ) +#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) +#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) +#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) +#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) +#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) +#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) +#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) +#define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) +#define TTAG_FOND FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) +#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) +#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) +#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) +#define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' ) +#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) +#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) +#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) +#define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) +#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) +#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) +#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) +#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) +#define TTAG_JSTF FT_MAKE_TAG( 'J', 'S', 'T', 'F' ) +#define TTAG_just FT_MAKE_TAG( 'j', 'u', 's', 't' ) +#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) +#define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) +#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) +#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_LWFN FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) +#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) +#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) +#define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) +#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) +#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) +#define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) +#define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) +#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) +#define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) +#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) +#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) +#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_POST FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) +#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) +#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) +#define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) +#define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) +#define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) +#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) +#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) +#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) +#define TTAG_TYP1 FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) +#define TTAG_typ1 FT_MAKE_TAG( 't', 'y', 'p', '1' ) +#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) +#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) +#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) + + +FT_END_HEADER + +#endif /* __TTAGS_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ttunpat.h b/drivers/freetype/include/freetype/ttunpat.h new file mode 100644 index 0000000000..a0162759b7 --- /dev/null +++ b/drivers/freetype/include/freetype/ttunpat.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttunpat.h */ +/* */ +/* Definitions for the unpatented TrueType hinting system */ +/* */ +/* Copyright 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by Graham Asher <graham.asher@btinternet.com> */ +/* */ +/* 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 __TTUNPAT_H__ +#define __TTUNPAT_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_UNPATENTED_HINTING + * + * @description: + * A constant used as the tag of an @FT_Parameter structure to indicate + * that unpatented methods only should be used by the TrueType bytecode + * interpreter for a typeface opened by @FT_Open_Face. + * + */ +#define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) + + /* */ + +FT_END_HEADER + + +#endif /* __TTUNPAT_H__ */ + + +/* END */ diff --git a/drivers/freetype/include/ft2build.h b/drivers/freetype/include/ft2build.h new file mode 100644 index 0000000000..cb23b8e24b --- /dev/null +++ b/drivers/freetype/include/ft2build.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* (Generic version) */ +/* */ +/* Copyright 1996-2001, 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file corresponds to the default `ft2build.h' file for */ + /* FreeType 2. It uses the `freetype' include root. */ + /* */ + /* Note that specific platforms might use a different configuration. */ + /* See builds/unix/ft2unix.h for an example. */ + /* */ + /*************************************************************************/ + + +#ifndef __FT2_BUILD_GENERIC_H__ +#define __FT2_BUILD_GENERIC_H__ + +#define FT2_BUILD_LIBRARY +#include <freetype/config/ftheader.h> + +#endif /* __FT2_BUILD_GENERIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/Jamfile b/drivers/freetype/src/Jamfile new file mode 100644 index 0000000000..76ee0f46e6 --- /dev/null +++ b/drivers/freetype/src/Jamfile @@ -0,0 +1,25 @@ +# FreeType 2 src Jamfile +# +# Copyright 2001, 2002 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) ; + +# The file <freetype/internal/internal.h> is used to define macros that are +# later used in #include statements. It needs to be parsed in order to +# record these definitions. +# +HDRMACRO [ FT2_SubDir $(FT2_INCLUDE_DIR) internal internal.h ] ; + +for xx in $(FT2_COMPONENTS) +{ + SubInclude FT2_TOP $(FT2_SRC_DIR) $(xx) ; +} + +# end of src Jamfile diff --git a/drivers/freetype/src/autofit/Jamfile b/drivers/freetype/src/autofit/Jamfile new file mode 100644 index 0000000000..2714765b5b --- /dev/null +++ b/drivers/freetype/src/autofit/Jamfile @@ -0,0 +1,39 @@ +# FreeType 2 src/autofit Jamfile +# +# Copyright 2003, 2004, 2005, 2006, 2007, 2009 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. + +SubDir FT2_TOP src autofit ; + +{ + local _sources ; + + # define FT2_AUTOFIT2 to enable experimental latin hinter replacement + if $(FT2_AUTOFIT2) + { + DEFINES += FT_OPTION_AUTOFIT2 ; + } + if $(FT2_MULTI) + { + _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp afpic ; + + if $(FT2_AUTOFIT2) + { + _sources += aflatin2 ; + } + } + else + { + _sources = autofit ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/autofit Jamfile diff --git a/drivers/freetype/src/autofit/afangles.c b/drivers/freetype/src/autofit/afangles.c new file mode 100644 index 0000000000..b44a5ba2c6 --- /dev/null +++ b/drivers/freetype/src/autofit/afangles.c @@ -0,0 +1,345 @@ +/***************************************************************************/ +/* */ +/* afangles.c */ +/* */ +/* Routines used to compute vector angles with limited accuracy */ +/* and very high speed. It also contains sorting routines (body). */ +/* */ +/* Copyright 2003-2006, 2011-2012 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 "aftypes.h" + + +#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 /* 0 */ + + + /* + * 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 */ + +#define AF_ATAN_BITS 8 + + static const FT_Byte af_arctan[1L << AF_ATAN_BITS] = + { + 0, 0, 1, 1, 1, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 6, 6, 6, 7, 7, 7, + 8, 8, 8, 9, 9, 9, 10, 10, + 10, 10, 11, 11, 11, 12, 12, 12, + 13, 13, 13, 14, 14, 14, 14, 15, + 15, 15, 16, 16, 16, 17, 17, 17, + 18, 18, 18, 18, 19, 19, 19, 20, + 20, 20, 21, 21, 21, 21, 22, 22, + 22, 23, 23, 23, 24, 24, 24, 24, + 25, 25, 25, 26, 26, 26, 26, 27, + 27, 27, 28, 28, 28, 28, 29, 29, + 29, 30, 30, 30, 30, 31, 31, 31, + 31, 32, 32, 32, 33, 33, 33, 33, + 34, 34, 34, 34, 35, 35, 35, 35, + 36, 36, 36, 36, 37, 37, 37, 38, + 38, 38, 38, 39, 39, 39, 39, 40, + 40, 40, 40, 41, 41, 41, 41, 42, + 42, 42, 42, 42, 43, 43, 43, 43, + 44, 44, 44, 44, 45, 45, 45, 45, + 46, 46, 46, 46, 46, 47, 47, 47, + 47, 48, 48, 48, 48, 48, 49, 49, + 49, 49, 50, 50, 50, 50, 50, 51, + 51, 51, 51, 51, 52, 52, 52, 52, + 52, 53, 53, 53, 53, 53, 54, 54, + 54, 54, 54, 55, 55, 55, 55, 55, + 56, 56, 56, 56, 56, 57, 57, 57, + 57, 57, 57, 58, 58, 58, 58, 58, + 59, 59, 59, 59, 59, 59, 60, 60, + 60, 60, 60, 61, 61, 61, 61, 61, + 61, 62, 62, 62, 62, 62, 62, 63, + 63, 63, 63, 63, 63, 64, 64, 64 + }; + + + FT_LOCAL_DEF( AF_Angle ) + af_angle_atan( FT_Fixed dx, + FT_Fixed dy ) + { + AF_Angle angle; + + + /* check trivial cases */ + if ( dy == 0 ) + { + angle = 0; + if ( dx < 0 ) + angle = AF_ANGLE_PI; + return angle; + } + else if ( dx == 0 ) + { + angle = AF_ANGLE_PI2; + if ( dy < 0 ) + angle = -AF_ANGLE_PI2; + return angle; + } + + angle = 0; + if ( dx < 0 ) + { + dx = -dx; + dy = -dy; + angle = AF_ANGLE_PI; + } + + if ( dy < 0 ) + { + FT_Pos tmp; + + + tmp = dx; + dx = -dy; + dy = tmp; + angle -= AF_ANGLE_PI2; + } + + if ( dx == 0 && dy == 0 ) + return 0; + + if ( dx == dy ) + angle += AF_ANGLE_PI4; + else if ( dx > dy ) + angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )]; + else + angle += AF_ANGLE_PI2 - + af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )]; + + if ( angle > AF_ANGLE_PI ) + angle -= AF_ANGLE_2PI; + + return angle; + } + + +#endif /* 0 */ + + + FT_LOCAL_DEF( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ) + { + FT_UInt i, j; + FT_Pos swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j] >= table[j - 1] ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } + + + FT_LOCAL_DEF( void ) + af_sort_and_quantize_widths( FT_UInt* count, + AF_Width table, + FT_Pos threshold ) + { + FT_UInt i, j; + FT_UInt cur_idx; + FT_Pos cur_val; + FT_Pos sum; + AF_WidthRec swap; + + + if ( *count == 1 ) + return; + + /* sort */ + for ( i = 1; i < *count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j].org >= table[j - 1].org ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + + cur_idx = 0; + cur_val = table[cur_idx].org; + + /* compute and use mean values for clusters not larger than */ + /* `threshold'; this is very primitive and might not yield */ + /* the best result, but normally, using reference character */ + /* `o', `*count' is 2, so the code below is fully sufficient */ + for ( i = 1; i < *count; i++ ) + { + if ( table[i].org - cur_val > threshold || + i == *count - 1 ) + { + sum = 0; + + /* fix loop for end of array */ + if ( table[i].org - cur_val <= threshold && + i == *count - 1 ) + i++; + + for ( j = cur_idx; j < i; j++ ) + { + sum += table[j].org; + table[j].org = 0; + } + table[cur_idx].org = sum / j; + + if ( i < *count - 1 ) + { + cur_idx = i + 1; + cur_val = table[cur_idx].org; + } + } + } + + cur_idx = 1; + + /* compress array to remove zero values */ + for ( i = 1; i < *count; i++ ) + { + if ( table[i].org ) + table[cur_idx++] = table[i]; + } + + *count = cur_idx; + } + + +/* END */ diff --git a/drivers/freetype/src/autofit/afangles.h b/drivers/freetype/src/autofit/afangles.h new file mode 100644 index 0000000000..f33f9e108e --- /dev/null +++ b/drivers/freetype/src/autofit/afangles.h @@ -0,0 +1,7 @@ +/* + * afangles.h + * + * This is a dummy file, used to please the build system. It is never + * included by the auto-fitter sources. + * + */ diff --git a/drivers/freetype/src/autofit/afcjk.c b/drivers/freetype/src/autofit/afcjk.c new file mode 100644 index 0000000000..f69a528e3b --- /dev/null +++ b/drivers/freetype/src/autofit/afcjk.c @@ -0,0 +1,2275 @@ +/***************************************************************************/ +/* */ +/* afcjk.c */ +/* */ +/* Auto-fitter hinting routines for CJK script (body). */ +/* */ +/* Copyright 2006-2013 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. */ +/* */ +/***************************************************************************/ + + /* + * The algorithm is based on akito's autohint patch, available here: + * + * http://www.kde.gr.jp/~akito/patch/freetype2/ + * + */ + +#include <ft2build.h> +#include FT_ADVANCES_H +#include FT_INTERNAL_DEBUG_H + +#include "aftypes.h" +#include "aflatin.h" + + +#ifdef AF_CONFIG_OPTION_CJK + +#undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + +#include "afcjk.h" +#include "aferrors.h" + + +#ifdef AF_CONFIG_OPTION_USE_WARPER +#include "afwarp.h" +#endif + + + /*************************************************************************/ + /* */ + /* 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_afcjk + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* Basically the Latin version with AF_CJKMetrics */ + /* to replace AF_LatinMetrics. */ + + FT_LOCAL_DEF( void ) + af_cjk_metrics_init_widths( AF_CJKMetrics metrics, + FT_Face face ) + { + /* scan the array of segments in each direction */ + AF_GlyphHintsRec hints[1]; + + + af_glyph_hints_init( hints, face->memory ); + + metrics->axis[AF_DIMENSION_HORZ].width_count = 0; + metrics->axis[AF_DIMENSION_VERT].width_count = 0; + + { + FT_Error error; + FT_UInt glyph_index; + int dim; + AF_CJKMetricsRec dummy[1]; + AF_Scaler scaler = &dummy->root.scaler; + + + glyph_index = FT_Get_Char_Index( face, + metrics->root.clazz->standard_char ); + if ( glyph_index == 0 ) + goto Exit; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) + goto Exit; + + FT_ZERO( dummy ); + + dummy->units_per_em = metrics->units_per_em; + + scaler->x_scale = 0x10000L; + scaler->y_scale = 0x10000L; + scaler->x_delta = 0; + scaler->y_delta = 0; + + scaler->face = face; + scaler->render_mode = FT_RENDER_MODE_NORMAL; + scaler->flags = 0; + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + + error = af_glyph_hints_reload( hints, &face->glyph->outline ); + if ( error ) + goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_CJKAxis axis = &metrics->axis[dim]; + AF_AxisHints axhints = &hints->axis[dim]; + AF_Segment seg, limit, link; + FT_UInt num_widths = 0; + + + error = af_latin_hints_compute_segments( hints, (AF_Dimension)dim ); + if ( error ) + goto Exit; + + af_latin_hints_link_segments( hints, (AF_Dimension)dim ); + + seg = axhints->segments; + limit = seg + axhints->num_segments; + + for ( ; seg < limit; seg++ ) + { + link = seg->link; + + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { + FT_Pos dist; + + + dist = seg->pos - link->pos; + if ( dist < 0 ) + dist = -dist; + + if ( num_widths < AF_CJK_MAX_WIDTHS ) + axis->widths[num_widths++].org = dist; + } + } + + /* this also replaces multiple almost identical stem widths */ + /* with a single one (the value 100 is heuristic) */ + af_sort_and_quantize_widths( &num_widths, axis->widths, + dummy->units_per_em / 100 ); + axis->width_count = num_widths; + } + + Exit: + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_CJKAxis axis = &metrics->axis[dim]; + FT_Pos stdw; + + + stdw = ( axis->width_count > 0 ) ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); + + /* let's try 20% of the smallest width */ + axis->edge_distance_threshold = stdw / 5; + axis->standard_width = stdw; + axis->extra_light = 0; + } + } + + af_glyph_hints_done( hints ); + } + + +#define AF_CJK_MAX_TEST_CHARACTERS 32 + + + /* Each blue zone has two types of fill and unfill, this is, */ + /* filling the entire glyph square or not. */ + + enum + { + AF_CJK_BLUE_TYPE_FILL, + AF_CJK_BLUE_TYPE_UNFILL, + AF_CJK_BLUE_TYPE_MAX + }; + + + /* Put some common and representative Han Ideographs characters here. */ + static const FT_ULong af_cjk_hani_blue_chars[AF_CJK_BLUE_MAX] + [AF_CJK_BLUE_TYPE_MAX] + [AF_CJK_MAX_TEST_CHARACTERS] = + { + { + { + 0x4ED6, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730, + 0x5BF9, 0x5C0D, 0x5C31, 0x5E2D, 0x6211, 0x65F6, 0x6642, 0x6703, + 0x6765, 0x70BA, 0x80FD, 0x8230, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019, + 0x9F4A /* top fill */ + }, + { + 0x519B, 0x540C, 0x5DF2, 0x613F, 0x65E2, 0x661F, 0x662F, 0x666F, + 0x6C11, 0x7167, 0x73B0, 0x73FE, 0x7406, 0x7528, 0x7F6E, 0x8981, + 0x8ECD, 0x90A3, 0x914D, 0x91CC, 0x958B, 0x96F7, 0x9732, 0x9762, + 0x987E /* top unfill */ + } + }, + { + { + 0x4E2A, 0x4E3A, 0x4EBA, 0x4ED6, 0x4EE5, 0x4EEC, 0x4F60, 0x4F86, + 0x500B, 0x5011, 0x5230, 0x548C, 0x5927, 0x5BF9, 0x5C0D, 0x5C31, + 0x6211, 0x65F6, 0x6642, 0x6709, 0x6765, 0x70BA, 0x8981, 0x8AAA, + 0x8BF4 /* bottom fill */ + }, + { + 0x4E3B, 0x4E9B, 0x56E0, 0x5B83, 0x60F3, 0x610F, 0x7406, 0x751F, + 0x7576, 0x770B, 0x7740, 0x7F6E, 0x8005, 0x81EA, 0x8457, 0x88E1, + 0x8FC7, 0x8FD8, 0x8FDB, 0x9032, 0x904E, 0x9053, 0x9084, 0x91CC, + 0x9762 /* bottom unfill */ + } + }, +#ifndef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + { {0x0000}, {0x0000} }, + { {0x0000}, {0x0000} } +#else + { + { + 0x4E9B, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730, + 0x5979, 0x5C06, 0x5C07, 0x5C31, 0x5E74, 0x5F97, 0x60C5, 0x6700, + 0x6837, 0x6A23, 0x7406, 0x80FD, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019, + 0x901A /* left fill */ + }, + { + 0x5373, 0x5417, 0x5427, 0x542C, 0x5462, 0x54C1, 0x54CD, 0x55CE, + 0x5E08, 0x5E2B, 0x6536, 0x65AD, 0x65B7, 0x660E, 0x773C, 0x9593, + 0x95F4, 0x9645, 0x9648, 0x9650, 0x9664, 0x9673, 0x968F, 0x969B, + 0x96A8 /* left unfill */ + } + }, + { + { + 0x4E8B, 0x524D, 0x5B78, 0x5C06, 0x5C07, 0x60C5, 0x60F3, 0x6216, + 0x653F, 0x65AF, 0x65B0, 0x6837, 0x6A23, 0x6C11, 0x6C92, 0x6CA1, + 0x7136, 0x7279, 0x73B0, 0x73FE, 0x7403, 0x7B2C, 0x7D93, 0x8C01, + 0x8D77 /* right fill */ + }, + { + 0x4F8B, 0x5225, 0x522B, 0x5236, 0x52A8, 0x52D5, 0x5417, 0x55CE, + 0x589E, 0x6307, 0x660E, 0x671D, 0x671F, 0x6784, 0x7269, 0x786E, + 0x79CD, 0x8ABF, 0x8C03, 0x8CBB, 0x8D39, 0x90A3, 0x90FD, 0x9593, + 0x95F4 /* right unfill */ + } + } +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + }; + + + /* Calculate blue zones for all the CJK_BLUE_XXX's. */ + + static void + af_cjk_metrics_init_blues( AF_CJKMetrics metrics, + FT_Face face, + const FT_ULong blue_chars + [AF_CJK_BLUE_MAX] + [AF_CJK_BLUE_TYPE_MAX] + [AF_CJK_MAX_TEST_CHARACTERS] ) + { + FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS]; + FT_Pos flats[AF_CJK_MAX_TEST_CHARACTERS]; + + FT_Int num_fills; + FT_Int num_flats; + + FT_Int bb; + AF_CJKBlue blue; + FT_Error error; + AF_CJKAxis axis; + FT_GlyphSlot glyph = face->glyph; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_String* cjk_blue_name[AF_CJK_BLUE_MAX] = { + (FT_String*)"top", + (FT_String*)"bottom", + (FT_String*)"left", + (FT_String*)"right" + }; + FT_String* cjk_blue_type_name[AF_CJK_BLUE_TYPE_MAX] = { + (FT_String*)"filled", + (FT_String*)"unfilled" + }; +#endif + + + /* We compute the blues simply by loading each character from the */ + /* `blue_chars[blues]' string, then computing its extreme points */ + /* (depending blue zone type etc.). */ + + FT_TRACE5(( "cjk blue zones computation\n" )); + FT_TRACE5(( "------------------------------------------------\n" )); + + for ( bb = 0; bb < AF_CJK_BLUE_MAX; bb++ ) + { + FT_Int fill_type; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; + + + num_fills = 0; + num_flats = 0; + + for ( fill_type = 0; fill_type < AF_CJK_BLUE_TYPE_MAX; fill_type++ ) + { + const FT_ULong* p = blue_chars[bb][fill_type]; + const FT_ULong* limit = p + AF_CJK_MAX_TEST_CHARACTERS; + FT_Bool fill = FT_BOOL( + fill_type == AF_CJK_BLUE_TYPE_FILL ); + + + FT_TRACE5(( "cjk blue %s/%s\n", cjk_blue_name[bb], + cjk_blue_type_name[fill_type] )); + + + for ( ; p < limit && *p; p++ ) + { + FT_UInt glyph_index; + FT_Pos best_pos; /* same as points.y */ + FT_Int best_point; + FT_Vector* points; + + + FT_TRACE5(( " U+%lX...", *p )); + + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = FT_Get_Char_Index( face, *p ); + if ( glyph_index == 0 ) + { + FT_TRACE5(( "unavailable\n" )); + continue; + } + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || glyph->outline.n_points <= 0 ) + { + FT_TRACE5(( "no outline\n" )); + continue; + } + + /* now compute min or max point indices and coordinates */ + points = glyph->outline.points; + best_point = -1; + best_pos = 0; /* make compiler happy */ + + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; + + + for ( nn = 0; + nn < glyph->outline.n_contours; + first = last + 1, nn++ ) + { + FT_Int pp; + + + last = glyph->outline.contours[nn]; + + /* Avoid single-point contours since they are never */ + /* rasterized. In some fonts, they correspond to mark */ + /* attachment points which are way outside of the glyph's */ + /* real outline. */ + if ( last <= first ) + continue; + + switch ( bb ) + { + case AF_CJK_BLUE_TOP: + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y > best_pos ) + { + best_point = pp; + best_pos = points[pp].y; + } + break; + + case AF_CJK_BLUE_BOTTOM: + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y < best_pos ) + { + best_point = pp; + best_pos = points[pp].y; + } + break; + + case AF_CJK_BLUE_LEFT: + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].x < best_pos ) + { + best_point = pp; + best_pos = points[pp].x; + } + break; + + case AF_CJK_BLUE_RIGHT: + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].x > best_pos ) + { + best_point = pp; + best_pos = points[pp].x; + } + break; + + default: + ; + } + } + FT_TRACE5(( "best_pos=%5ld\n", best_pos )); + } + + if ( fill ) + fills[num_fills++] = best_pos; + else + flats[num_flats++] = best_pos; + } + } + + if ( num_flats == 0 && num_fills == 0 ) + { + /* + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then + */ + FT_TRACE5(( "empty\n" )); + continue; + } + + /* we have computed the contents of the `fill' and `flats' tables, */ + /* now determine the reference position of the blue -- */ + /* we simply take the median value after a simple sort */ + af_sort_pos( num_flats, flats ); + af_sort_pos( num_fills, fills ); + + if ( AF_CJK_BLUE_TOP == bb || AF_CJK_BLUE_BOTTOM == bb ) + axis = &metrics->axis[AF_DIMENSION_VERT]; + else + axis = &metrics->axis[AF_DIMENSION_HORZ]; + + blue = & axis->blues[axis->blue_count]; + blue_ref = & blue->ref.org; + blue_shoot = & blue->shoot.org; + + axis->blue_count++; + if ( num_flats == 0 ) + { + *blue_ref = fills[num_fills / 2]; + *blue_shoot = fills[num_fills / 2]; + } + else if ( num_fills == 0 ) + { + *blue_ref = flats[num_flats / 2]; + *blue_shoot = flats[num_flats / 2]; + } + else + { + *blue_ref = fills[num_fills / 2]; + *blue_shoot = flats[num_flats / 2]; + } + + /* make sure blue_ref >= blue_shoot for top/right or */ + /* vice versa for bottom/left */ + if ( *blue_shoot != *blue_ref ) + { + FT_Pos ref = *blue_ref; + FT_Pos shoot = *blue_shoot; + FT_Bool under_ref = FT_BOOL( shoot < ref ); + + + if ( ( AF_CJK_BLUE_TOP == bb || + AF_CJK_BLUE_RIGHT == bb ) ^ under_ref ) + *blue_shoot = *blue_ref = ( shoot + ref ) / 2; + } + + blue->flags = 0; + if ( AF_CJK_BLUE_TOP == bb ) + blue->flags |= AF_CJK_BLUE_IS_TOP; + else if ( AF_CJK_BLUE_RIGHT == bb ) + blue->flags |= AF_CJK_BLUE_IS_RIGHT; + + FT_TRACE5(( "-- cjk %s bluezone ref = %ld shoot = %ld\n", + cjk_blue_name[bb], *blue_ref, *blue_shoot )); + } + + return; + } + + + /* Basically the Latin version with type AF_CJKMetrics for metrics. */ + FT_LOCAL_DEF( void ) + af_cjk_metrics_check_digits( AF_CJKMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + + FT_LOCAL_DEF( FT_Error ) + af_cjk_metrics_init( AF_CJKMetrics metrics, + FT_Face face ) + { + FT_CharMap oldmap = face->charmap; + + + metrics->units_per_em = face->units_per_EM; + + if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) + face->charmap = NULL; + else + { + af_cjk_metrics_init_widths( metrics, face ); + af_cjk_metrics_init_blues( metrics, face, af_cjk_hani_blue_chars ); + af_cjk_metrics_check_digits( metrics, face ); + } + + FT_Set_Charmap( face, oldmap ); + + return FT_Err_Ok; + } + + + static void + af_cjk_metrics_scale_dim( AF_CJKMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) + { + FT_Fixed scale; + FT_Pos delta; + AF_CJKAxis axis; + FT_UInt nn; + + + axis = &metrics->axis[dim]; + + if ( dim == AF_DIMENSION_HORZ ) + { + scale = scaler->x_scale; + delta = scaler->x_delta; + } + else + { + scale = scaler->y_scale; + delta = scaler->y_delta; + } + + if ( axis->org_scale == scale && axis->org_delta == delta ) + return; + + axis->org_scale = scale; + axis->org_delta = delta; + + axis->scale = scale; + axis->delta = delta; + + /* scale the blue zones */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_CJKBlue blue = &axis->blues[nn]; + FT_Pos dist; + + + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; + blue->ref.fit = blue->ref.cur; + blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; + blue->shoot.fit = blue->shoot.cur; + blue->flags &= ~AF_CJK_BLUE_ACTIVE; + + /* a blue zone is only active if it is less than 3/4 pixels tall */ + dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); + if ( dist <= 48 && dist >= -48 ) + { + FT_Pos delta1, delta2; + + + blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); + + /* shoot is under shoot for cjk */ + delta1 = FT_DivFix( blue->ref.fit, scale ) - blue->shoot.org; + delta2 = delta1; + if ( delta1 < 0 ) + delta2 = -delta2; + + delta2 = FT_MulFix( delta2, scale ); + + FT_TRACE5(( "delta: %d", delta1 )); + if ( delta2 < 32 ) + delta2 = 0; +#if 0 + else if ( delta2 < 64 ) + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); +#endif + else + delta2 = FT_PIX_ROUND( delta2 ); + FT_TRACE5(( "/%d\n", delta2 )); + + if ( delta1 < 0 ) + delta2 = -delta2; + + blue->shoot.fit = blue->ref.fit - delta2; + + FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]: " + "ref: cur=%.2f fit=%.2f shoot: cur=%.2f fit=%.2f\n", + ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V', + nn, blue->ref.org, blue->shoot.org, + blue->ref.cur / 64.0, blue->ref.fit / 64.0, + blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); + + blue->flags |= AF_CJK_BLUE_ACTIVE; + } + } + } + + + FT_LOCAL_DEF( void ) + af_cjk_metrics_scale( AF_CJKMetrics metrics, + AF_Scaler scaler ) + { + metrics->root.scaler = *scaler; + + af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + af_cjk_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + FT_Error error; + AF_Segment seg; + + + error = af_latin_hints_compute_segments( hints, dim ); + if ( error ) + return error; + + /* a segment is round if it doesn't have successive */ + /* on-curve points. */ + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Point pt = seg->first; + AF_Point last = seg->last; + AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); + AF_Flags f1; + + + seg->flags &= ~AF_EDGE_ROUND; + + for ( ; pt != last; f0 = f1 ) + { + pt = pt->next; + f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); + + if ( !f0 && !f1 ) + break; + + if ( pt == last ) + seg->flags |= AF_EDGE_ROUND; + } + } + + return FT_Err_Ok; + } + + + static void + af_cjk_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Direction major_dir = axis->major_dir; + AF_Segment seg1, seg2; + FT_Pos len_threshold; + FT_Pos dist_threshold; + + + len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); + + dist_threshold = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + dist_threshold = FT_DivFix( 64 * 3, dist_threshold ); + + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + /* the fake segments are for metrics hinting only */ + if ( seg1->first == seg1->last ) + continue; + + if ( seg1->dir != major_dir ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + if ( seg2 != seg1 && seg1->dir + seg2->dir == 0 ) + { + FT_Pos dist = seg2->pos - seg1->pos; + + + if ( dist < 0 ) + continue; + + { + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + len = max - min; + if ( len >= len_threshold ) + { + if ( dist * 8 < seg1->score * 9 && + ( dist * 8 < seg1->score * 7 || seg1->len < len ) ) + { + seg1->score = dist; + seg1->len = len; + seg1->link = seg2; + } + + if ( dist * 8 < seg2->score * 9 && + ( dist * 8 < seg2->score * 7 || seg2->len < len ) ) + { + seg2->score = dist; + seg2->len = len; + seg2->link = seg1; + } + } + } + } + } + + /* + * now compute the `serif' segments + * + * In Hanzi, some strokes are wider on one or both of the ends. + * We either identify the stems on the ends as serifs or remove + * the linkage, depending on the length of the stems. + * + */ + + { + AF_Segment link1, link2; + + + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + link1 = seg1->link; + if ( !link1 || link1->link != seg1 || link1->pos <= seg1->pos ) + continue; + + if ( seg1->score >= dist_threshold ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + { + if ( seg2->pos > seg1->pos || seg1 == seg2 ) + continue; + + link2 = seg2->link; + if ( !link2 || link2->link != seg2 || link2->pos < link1->pos ) + continue; + + if ( seg1->pos == seg2->pos && link1->pos == link2->pos ) + continue; + + if ( seg2->score <= seg1->score || seg1->score * 4 <= seg2->score ) + continue; + + /* seg2 < seg1 < link1 < link2 */ + + if ( seg1->len >= seg2->len * 3 ) + { + AF_Segment seg; + + + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Segment link = seg->link; + + + if ( link == seg2 ) + { + seg->link = 0; + seg->serif = link1; + } + else if ( link == link2 ) + { + seg->link = 0; + seg->serif = seg1; + } + } + } + else + { + seg1->link = link1->link = 0; + + break; + } + } + } + } + + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; + + if ( seg2 ) + { + seg2->num_linked++; + if ( seg2->link != seg1 ) + { + seg1->link = 0; + + if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 ) + seg1->serif = seg2->link; + else + seg2->num_linked--; + } + } + } + } + + + static FT_Error + af_cjk_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Error error = FT_Err_Ok; + FT_Memory memory = hints->memory; + AF_CJKAxis laxis = &((AF_CJKMetrics)hints->metrics)->axis[dim]; + + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + + FT_Fixed scale; + FT_Pos edge_distance_threshold; + + + axis->num_edges = 0; + + scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + + /*********************************************************************/ + /* */ + /* We begin by generating a sorted table of edges for the current */ + /* direction. To do so, we simply scan each segment and try to find */ + /* an edge in our table that corresponds to its position. */ + /* */ + /* If no edge is found, we create and insert a new edge in the */ + /* sorted table. Otherwise, we simply add the segment to the edge's */ + /* list which is then processed in the second step to compute the */ + /* edge's properties. */ + /* */ + /* Note that the edges table is sorted along the segment/edge */ + /* position. */ + /* */ + /*********************************************************************/ + + edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, + scale ); + if ( edge_distance_threshold > 64 / 4 ) + edge_distance_threshold = FT_DivFix( 64 / 4, scale ); + else + edge_distance_threshold = laxis->edge_distance_threshold; + + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = 0; + FT_Pos best = 0xFFFFU; + FT_Int ee; + + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + if ( edge->dir != seg->dir ) + continue; + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold && dist < best ) + { + AF_Segment link = seg->link; + + + /* check whether all linked segments of the candidate edge */ + /* can make a single edge. */ + if ( link ) + { + AF_Segment seg1 = edge->first; + FT_Pos dist2 = 0; + + + do + { + AF_Segment link1 = seg1->link; + + + if ( link1 ) + { + dist2 = AF_SEGMENT_DIST( link, link1 ); + if ( dist2 >= edge_distance_threshold ) + break; + } + + } while ( ( seg1 = seg1->edge_next ) != edge->first ); + + if ( dist2 >= edge_distance_threshold ) + continue; + } + + best = dist; + found = edge; + } + } + + if ( !found ) + { + AF_Edge edge; + + + /* insert a new edge in the list and */ + /* sort according to the position */ + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); + if ( error ) + goto Exit; + + /* add the segment to the new edge's list */ + FT_ZERO( edge ); + + edge->first = seg; + edge->last = seg; + edge->fpos = seg->pos; + edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + seg->edge_next = seg; + edge->dir = seg->dir; + } + else + { + /* if an edge was found, simply add the segment to the edge's */ + /* list */ + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + + /*********************************************************************/ + /* */ + /* Good, we now compute each edge's properties according to segments */ + /* found on its position. Basically, these are as follows. */ + /* */ + /* - edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /*********************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + /* */ + /* Note that removing this loop and setting the `edge' field of each */ + /* segment directly in the code above slows down execution speed for */ + /* some reasons on platforms like the Sun. */ + + { + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + + + for ( edge = edges; edge < edge_limit; edge++ ) + { + seg = edge->first; + if ( seg ) + do + { + seg->edge = edge; + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + + /* now compute each edge properties */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ + + + seg = edge->first; + + do + { + FT_Bool is_serif; + + + /* check for roundness of segment */ + if ( seg->flags & AF_EDGE_ROUND ) + is_round++; + else + is_straight++; + + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge ); + + if ( seg->link || is_serif ) + { + AF_Edge edge2; + AF_Segment seg2; + + + edge2 = edge->link; + seg2 = seg->link; + + if ( is_serif ) + { + seg2 = seg->serif; + edge2 = edge->serif; + } + + if ( edge2 ) + { + FT_Pos edge_delta; + FT_Pos seg_delta; + + + edge_delta = edge->fpos - edge2->fpos; + if ( edge_delta < 0 ) + edge_delta = -edge_delta; + + seg_delta = AF_SEGMENT_DIST( seg, seg2 ); + + if ( seg_delta < edge_delta ) + edge2 = seg2->edge; + } + else + edge2 = seg2->edge; + + if ( is_serif ) + { + edge->serif = edge2; + edge2->flags |= AF_EDGE_SERIF; + } + else + edge->link = edge2; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + + /* set the round/straight flags */ + edge->flags = AF_EDGE_NORMAL; + + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AF_EDGE_ROUND; + + /* get rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ + + if ( edge->serif && edge->link ) + edge->serif = 0; + } + } + + Exit: + return error; + } + + + static FT_Error + af_cjk_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ) + { + FT_Error error; + + + error = af_cjk_hints_compute_segments( hints, dim ); + if ( !error ) + { + af_cjk_hints_link_segments( hints, dim ); + + error = af_cjk_hints_compute_edges( hints, dim ); + } + return error; + } + + + FT_LOCAL_DEF( void ) + af_cjk_hints_compute_blue_edges( AF_GlyphHints hints, + AF_CJKMetrics metrics, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edge = axis->edges; + AF_Edge edge_limit = edge + axis->num_edges; + AF_CJKAxis cjk = &metrics->axis[dim]; + FT_Fixed scale = cjk->scale; + FT_Pos best_dist0; /* initial threshold */ + + + /* compute the initial threshold as a fraction of the EM size */ + best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); + + if ( best_dist0 > 64 / 2 ) /* maximum 1/2 pixel */ + best_dist0 = 64 / 2; + + /* compute which blue zones are active, i.e. have their scaled */ + /* size < 3/4 pixels */ + + /* If the distant between an edge and a blue zone is shorter than */ + /* best_dist0, set the blue zone for the edge. Then search for */ + /* the blue zone with the smallest best_dist to the edge. */ + + for ( ; edge < edge_limit; edge++ ) + { + FT_UInt bb; + AF_Width best_blue = NULL; + FT_Pos best_dist = best_dist0; + + + for ( bb = 0; bb < cjk->blue_count; bb++ ) + { + AF_CJKBlue blue = cjk->blues + bb; + FT_Bool is_top_right_blue, is_major_dir; + + + /* skip inactive blue zones (i.e., those that are too small) */ + if ( !( blue->flags & AF_CJK_BLUE_ACTIVE ) ) + continue; + + /* if it is a top zone, check for right edges -- if it is a bottom */ + /* zone, check for left edges */ + /* */ + /* of course, that's for TrueType */ + is_top_right_blue = + FT_BOOL( ( ( blue->flags & AF_CJK_BLUE_IS_TOP ) != 0 ) || + ( ( blue->flags & AF_CJK_BLUE_IS_RIGHT ) != 0 ) ); + is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + + /* if it is a top zone, the edge must be against the major */ + /* direction; if it is a bottom zone, it must be in the major */ + /* direction */ + if ( is_top_right_blue ^ is_major_dir ) + { + FT_Pos dist; + AF_Width compare; + + + /* Compare the edge to the closest blue zone type */ + if ( FT_ABS( edge->fpos - blue->ref.org ) > + FT_ABS( edge->fpos - blue->shoot.org ) ) + compare = &blue->shoot; + else + compare = &blue->ref; + + dist = edge->fpos - compare->org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = compare; + } + } + } + + if ( best_blue ) + edge->blue_edge = best_blue; + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_cjk_hints_init( AF_GlyphHints hints, + AF_CJKMetrics metrics ) + { + FT_Render_Mode mode; + FT_UInt32 scaler_flags, other_flags; + + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + + /* + * correct x_scale and y_scale when needed, since they may have + * been modified af_cjk_scale_dim above + */ + hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; + hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; + hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; + hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; + + /* compute flags depending on render mode, etc. */ + mode = metrics->root.scaler.render_mode; + +#ifdef AF_CONFIG_OPTION_USE_WARPER + if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) + metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; +#endif + + scaler_flags = hints->scaler_flags; + other_flags = 0; + + /* + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) + other_flags |= AF_LATIN_HINTS_HORZ_SNAP; + + /* + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* + * We adjust stems to full pixels only if we don't use the `light' mode. + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + other_flags |= AF_LATIN_HINTS_STEM_ADJUST; + + if ( mode == FT_RENDER_MODE_MONO ) + other_flags |= AF_LATIN_HINTS_MONO; + + scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE; + + hints->scaler_flags = scaler_flags; + hints->other_flags = other_flags; + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* snap a given width in scaled coordinates to one of the */ + /* current standard widths */ + + static FT_Pos + af_cjk_snap_width( AF_Width widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = FT_PIX_ROUND( reference ); + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* compute the snapped width of a given stem */ + + static FT_Pos + af_cjk_compute_stem_width( AF_GlyphHints hints, + AF_Dimension dim, + FT_Pos width, + AF_Edge_Flags base_flags, + AF_Edge_Flags stem_flags ) + { + AF_CJKMetrics metrics = (AF_CJKMetrics) hints->metrics; + AF_CJKAxis axis = & metrics->axis[dim]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Bool vertical = FT_BOOL( dim == AF_DIMENSION_VERT ); + + FT_UNUSED( base_flags ); + FT_UNUSED( stem_flags ); + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + return width; + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) + { + /* smooth hinting process: very lightly quantize the stem width */ + + if ( axis->width_count > 0 ) + { + if ( FT_ABS( dist - axis->widths[0].cur ) < 40 ) + { + dist = axis->widths[0].cur; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + } + + if ( dist < 54 ) + dist += ( 54 - dist ) / 2 ; + else if ( dist < 3 * 64 ) + { + FT_Pos delta; + + + delta = dist & 63; + dist &= -64; + + if ( delta < 10 ) + dist += delta; + else if ( delta < 22 ) + dist += 10; + else if ( delta < 42 ) + dist += delta; + else if ( delta < 54 ) + dist += 54; + else + dist += delta; + } + } + else + { + /* strong hinting process: snap the stem width to integer pixels */ + + dist = af_cjk_snap_width( axis->widths, axis->width_count, dist ); + + if ( vertical ) + { + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + + if ( dist >= 64 ) + dist = ( dist + 16 ) & ~63; + else + dist = 64; + } + else + { + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & ~63; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + dist = ( dist + 22 ) & ~63; + else + /* round otherwise to prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & ~63; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } + + + /* align one stem edge relative to the previous stem edge */ + + static void + af_cjk_align_linked_edge( AF_GlyphHints hints, + AF_Dimension dim, + AF_Edge base_edge, + AF_Edge stem_edge ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + + FT_Pos fitted_width = af_cjk_compute_stem_width( + hints, dim, dist, + (AF_Edge_Flags)base_edge->flags, + (AF_Edge_Flags)stem_edge->flags ); + + + stem_edge->pos = base_edge->pos + fitted_width; + } + + + static void + af_cjk_align_serif_edge( AF_GlyphHints hints, + AF_Edge base, + AF_Edge serif ) + { + FT_UNUSED( hints ); + + serif->pos = base->pos + ( serif->opos - base->opos ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define AF_LIGHT_MODE_MAX_HORZ_GAP 9 +#define AF_LIGHT_MODE_MAX_VERT_GAP 15 +#define AF_LIGHT_MODE_MAX_DELTA_ABS 14 + + + static FT_Pos + af_hint_normal_stem( AF_GlyphHints hints, + AF_Edge edge, + AF_Edge edge2, + FT_Pos anchor, + AF_Dimension dim ) + { + FT_Pos org_len, cur_len, org_center; + FT_Pos cur_pos1, cur_pos2; + FT_Pos d_off1, u_off1, d_off2, u_off2, delta; + FT_Pos offset; + FT_Pos threshold = 64; + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + { + if ( ( edge->flags & AF_EDGE_ROUND ) && + ( edge2->flags & AF_EDGE_ROUND ) ) + { + if ( dim == AF_DIMENSION_VERT ) + threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP; + else + threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP; + } + else + { + if ( dim == AF_DIMENSION_VERT ) + threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP / 3; + else + threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP / 3; + } + } + + org_len = edge2->opos - edge->opos; + cur_len = af_cjk_compute_stem_width( hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + org_center = ( edge->opos + edge2->opos ) / 2 + anchor; + cur_pos1 = org_center - cur_len / 2; + cur_pos2 = cur_pos1 + cur_len; + d_off1 = cur_pos1 - FT_PIX_FLOOR( cur_pos1 ); + d_off2 = cur_pos2 - FT_PIX_FLOOR( cur_pos2 ); + u_off1 = 64 - d_off1; + u_off2 = 64 - d_off2; + delta = 0; + + + if ( d_off1 == 0 || d_off2 == 0 ) + goto Exit; + + if ( cur_len <= threshold ) + { + if ( d_off2 < cur_len ) + { + if ( u_off1 <= d_off2 ) + delta = u_off1; + else + delta = -d_off2; + } + + goto Exit; + } + + if ( threshold < 64 ) + { + if ( d_off1 >= threshold || u_off1 >= threshold || + d_off2 >= threshold || u_off2 >= threshold ) + goto Exit; + } + + offset = cur_len & 63; + + if ( offset < 32 ) + { + if ( u_off1 <= offset || d_off2 <= offset ) + goto Exit; + } + else + offset = 64 - threshold; + + d_off1 = threshold - u_off1; + u_off1 = u_off1 - offset; + u_off2 = threshold - d_off2; + d_off2 = d_off2 - offset; + + if ( d_off1 <= u_off1 ) + u_off1 = -d_off1; + + if ( d_off2 <= u_off2 ) + u_off2 = -d_off2; + + if ( FT_ABS( u_off1 ) <= FT_ABS( u_off2 ) ) + delta = u_off1; + else + delta = u_off2; + + Exit: + +#if 1 + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + { + if ( delta > AF_LIGHT_MODE_MAX_DELTA_ABS ) + delta = AF_LIGHT_MODE_MAX_DELTA_ABS; + else if ( delta < -AF_LIGHT_MODE_MAX_DELTA_ABS ) + delta = -AF_LIGHT_MODE_MAX_DELTA_ABS; + } +#endif + + cur_pos1 += delta; + + if ( edge->opos < edge2->opos ) + { + edge->pos = cur_pos1; + edge2->pos = cur_pos1 + cur_len; + } + else + { + edge->pos = cur_pos1 + cur_len; + edge2->pos = cur_pos1; + } + + return delta; + } + + + static void + af_cjk_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + FT_PtrDist n_edges; + AF_Edge edge; + AF_Edge anchor = 0; + FT_Pos delta = 0; + FT_Int skipped = 0; + FT_Bool has_last_stem = FALSE; + FT_Pos last_stem_pos = 0; + + + /* we begin by aligning all stems relative to the blue zone */ + FT_TRACE5(( "==== cjk hinting %s edges =====\n", + dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); + + if ( AF_HINTS_DO_BLUES( hints ) ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Width blue; + AF_Edge edge1, edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + blue = edge->blue_edge; + edge1 = NULL; + edge2 = edge->link; + + if ( blue ) + { + edge1 = edge; + } + else if ( edge2 && edge2->blue_edge ) + { + blue = edge2->blue_edge; + edge1 = edge2; + edge2 = edge; + } + + if ( !edge1 ) + continue; + + FT_TRACE5(( "CJKBLUE: edge %d @%d (opos=%.2f) snapped to (%.2f), " + "was (%.2f)\n", + edge1-edges, edge1->fpos, edge1->opos / 64.0, blue->fit / 64.0, + edge1->pos / 64.0 )); + + edge1->pos = blue->fit; + edge1->flags |= AF_EDGE_DONE; + + if ( edge2 && !edge2->blue_edge ) + { + af_cjk_align_linked_edge( hints, dim, edge1, edge2 ); + edge2->flags |= AF_EDGE_DONE; + } + + if ( !anchor ) + anchor = edge; + } + } + + /* now we align all stem edges. */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + skipped++; + continue; + } + + /* Some CJK characters have so many stems that + * the hinter is likely to merge two adjacent ones. + * To solve this problem, if either edge of a stem + * is too close to the previous one, we avoid + * aligning the two edges, but rather interpolate + * their locations at the end of this function in + * order to preserve the space between the stems. + */ + if ( has_last_stem && + ( edge->pos < last_stem_pos + 64 || + edge2->pos < last_stem_pos + 64 ) ) + { + skipped++; + continue; + } + + /* now align the stem */ + /* this should not happen, but it's better to be safe */ + if ( edge2->blue_edge ) + { + FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges )); + + af_cjk_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + continue; + } + + if ( edge2 < edge ) + { + af_cjk_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + /* We rarely reaches here it seems; + * usually the two edges belonging + * to one stem are marked as DONE together + */ + has_last_stem = TRUE; + last_stem_pos = edge->pos; + continue; + } + + if ( dim != AF_DIMENSION_VERT && !anchor ) + { + +#if 0 + if ( fixedpitch ) + { + AF_Edge left = edge; + AF_Edge right = edge_limit - 1; + AF_EdgeRec left1, left2, right1, right2; + FT_Pos target, center1, center2; + FT_Pos delta1, delta2, d1, d2; + + + while ( right > left && !right->link ) + right--; + + left1 = *left; + left2 = *left->link; + right1 = *right->link; + right2 = *right; + + delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2; + target = left->opos + ( right->opos - left->opos ) / 2 + delta - 16; + + delta1 = delta; + delta1 += af_hint_normal_stem( hints, left, left->link, + delta1, 0 ); + + if ( left->link != right ) + af_hint_normal_stem( hints, right->link, right, delta1, 0 ); + + center1 = left->pos + ( right->pos - left->pos ) / 2; + + if ( center1 >= target ) + delta2 = delta - 32; + else + delta2 = delta + 32; + + delta2 += af_hint_normal_stem( hints, &left1, &left2, delta2, 0 ); + + if ( delta1 != delta2 ) + { + if ( left->link != right ) + af_hint_normal_stem( hints, &right1, &right2, delta2, 0 ); + + center2 = left1.pos + ( right2.pos - left1.pos ) / 2; + + d1 = center1 - target; + d2 = center2 - target; + + if ( FT_ABS( d2 ) < FT_ABS( d1 ) ) + { + left->pos = left1.pos; + left->link->pos = left2.pos; + + if ( left->link != right ) + { + right->link->pos = right1.pos; + right->pos = right2.pos; + } + + delta1 = delta2; + } + } + + delta = delta1; + right->link->flags |= AF_EDGE_DONE; + right->flags |= AF_EDGE_DONE; + } + else + +#endif /* 0 */ + + delta = af_hint_normal_stem( hints, edge, edge2, 0, + AF_DIMENSION_HORZ ); + } + else + af_hint_normal_stem( hints, edge, edge2, delta, dim ); + +#if 0 + printf( "stem (%d,%d) adjusted (%.1f,%.1f)\n", + edge - edges, edge2 - edges, + ( edge->pos - edge->opos ) / 64.0, + ( edge2->pos - edge2->opos ) / 64.0 ); +#endif + + anchor = edge; + edge->flags |= AF_EDGE_DONE; + edge2->flags |= AF_EDGE_DONE; + has_last_stem = TRUE; + last_stem_pos = edge2->pos; + } + + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are with serifs. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + + n_edges = edge_limit - edges; + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) + { + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( edge1->link == edge1 + 1 && + edge2->link == edge2 + 1 && + edge3->link == edge3 + 1 && span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } + } + + if ( !skipped ) + return; + + /* + * now hint the remaining edges (serifs and single) in order + * to complete our processing + */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + if ( edge->flags & AF_EDGE_DONE ) + continue; + + if ( edge->serif ) + { + af_cjk_align_serif_edge( hints, edge->serif, edge ); + edge->flags |= AF_EDGE_DONE; + skipped--; + } + } + + if ( !skipped ) + return; + + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge before, after; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + before = after = edge; + + while ( --before >= edges ) + if ( before->flags & AF_EDGE_DONE ) + break; + + while ( ++after < edge_limit ) + if ( after->flags & AF_EDGE_DONE ) + break; + + if ( before >= edges || after < edge_limit ) + { + if ( before < edges ) + af_cjk_align_serif_edge( hints, after, edge ); + else if ( after >= edge_limit ) + af_cjk_align_serif_edge( hints, before, edge ); + else + { + if ( after->fpos == before->fpos ) + edge->pos = before->pos; + else + edge->pos = before->pos + + FT_MulDiv( edge->fpos - before->fpos, + after->pos - before->pos, + after->fpos - before->fpos ); + } + } + } + } + + + static void + af_cjk_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = & hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + FT_Bool snapping; + + + snapping = FT_BOOL( ( dim == AF_DIMENSION_HORZ && + AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) || + ( dim == AF_DIMENSION_VERT && + AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ); + + for ( edge = edges; edge < edge_limit; edge++ ) + { + /* move the points of each segment */ + /* in each edge to the edge's position */ + AF_Segment seg = edge->first; + + + if ( snapping ) + { + do + { + AF_Point point = seg->first; + + + for (;;) + { + if ( dim == AF_DIMENSION_HORZ ) + { + point->x = edge->pos; + point->flags |= AF_FLAG_TOUCH_X; + } + else + { + point->y = edge->pos; + point->flags |= AF_FLAG_TOUCH_Y; + } + + if ( point == seg->last ) + break; + + point = point->next; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + else + { + FT_Pos delta = edge->pos - edge->opos; + + + do + { + AF_Point point = seg->first; + + + for (;;) + { + if ( dim == AF_DIMENSION_HORZ ) + { + point->x += delta; + point->flags |= AF_FLAG_TOUCH_X; + } + else + { + point->y += delta; + point->flags |= AF_FLAG_TOUCH_Y; + } + + if ( point == seg->last ) + break; + + point = point->next; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_cjk_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_CJKMetrics metrics ) + { + FT_Error error; + int dim; + + FT_UNUSED( metrics ); + + + error = af_glyph_hints_reload( hints, outline ); + if ( error ) + goto Exit; + + /* analyze glyph outline */ + if ( AF_HINTS_DO_HORIZONTAL( hints ) ) + { + error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ ); + if ( error ) + goto Exit; + + af_cjk_hints_compute_blue_edges( hints, metrics, AF_DIMENSION_HORZ ); + } + + if ( AF_HINTS_DO_VERTICAL( hints ) ) + { + error = af_cjk_hints_detect_features( hints, AF_DIMENSION_VERT ); + if ( error ) + goto Exit; + + af_cjk_hints_compute_blue_edges( hints, metrics, AF_DIMENSION_VERT ); + } + + /* grid-fit the outline */ + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || + ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) + { + +#ifdef AF_CONFIG_OPTION_USE_WARPER + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL ) + { + AF_WarperRec warper; + FT_Fixed scale; + FT_Pos delta; + + + af_warper_compute( &warper, hints, (AF_Dimension)dim, + &scale, &delta ); + af_glyph_hints_scale_dim( hints, (AF_Dimension)dim, + scale, delta ); + continue; + } +#endif /* AF_CONFIG_OPTION_USE_WARPER */ + + af_cjk_hint_edges( hints, (AF_Dimension)dim ); + af_cjk_align_edge_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); + } + } + +#if 0 + af_glyph_hints_dump_points( hints ); + af_glyph_hints_dump_segments( hints ); + af_glyph_hints_dump_edges( hints ); +#endif + + af_glyph_hints_save( hints, outline ); + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* this corresponds to Unicode 6.0 */ + + static const AF_Script_UniRangeRec af_cjk_uniranges[] = + { + AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), /* Hangul Jamo */ + AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ + AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ + AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), /* Ideographic Description Characters */ + AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ + AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ + AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ + AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ + AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ + AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), /* Kanbun */ + AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ + AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ + AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ + AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */ + AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ + AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ + AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ + AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ + AF_UNIRANGE_REC( 0xA960UL, 0xA97FUL ), /* Hangul Jamo Extended-A */ + AF_UNIRANGE_REC( 0xAC00UL, 0xD7AFUL ), /* Hangul Syllables */ + AF_UNIRANGE_REC( 0xD7B0UL, 0xD7FFUL ), /* Hangul Jamo Extended-B */ + AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ + AF_UNIRANGE_REC( 0xFE10UL, 0xFE1FUL ), /* Vertical forms */ + AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ + AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ + AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ), /* Kana Supplement */ + AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ), /* Tai Xuan Hing Symbols */ + AF_UNIRANGE_REC( 0x1F200UL, 0x1F2FFUL ), /* Enclosed Ideographic Supplement */ + AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ + AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ), /* CJK Unified Ideographs Extension C */ + AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ), /* CJK Unified Ideographs Extension D */ + AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + + + AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class, + AF_SCRIPT_CJK, + af_cjk_uniranges, + 0x7530, /* 田 */ + + sizeof ( AF_CJKMetricsRec ), + + (AF_Script_InitMetricsFunc) af_cjk_metrics_init, + (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_cjk_hints_init, + (AF_Script_ApplyHintsFunc) af_cjk_hints_apply + ) + +#else /* !AF_CONFIG_OPTION_CJK */ + + static const AF_Script_UniRangeRec af_cjk_uniranges[] = + { + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + + + AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class, + AF_SCRIPT_CJK, + af_cjk_uniranges, + 0, + + sizeof ( AF_CJKMetricsRec ), + + (AF_Script_InitMetricsFunc) NULL, + (AF_Script_ScaleMetricsFunc)NULL, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) NULL, + (AF_Script_ApplyHintsFunc) NULL + ) + +#endif /* !AF_CONFIG_OPTION_CJK */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afcjk.h b/drivers/freetype/src/autofit/afcjk.h new file mode 100644 index 0000000000..ab816f20b1 --- /dev/null +++ b/drivers/freetype/src/autofit/afcjk.h @@ -0,0 +1,142 @@ +/***************************************************************************/ +/* */ +/* afcjk.h */ +/* */ +/* Auto-fitter hinting routines for CJK script (specification). */ +/* */ +/* Copyright 2006, 2007, 2011, 2012 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 __AFCJK_H__ +#define __AFCJK_H__ + +#include "afhints.h" +#include "aflatin.h" + + +FT_BEGIN_HEADER + + + /* the CJK-specific script class */ + + AF_DECLARE_SCRIPT_CLASS( af_cjk_script_class ) + + /* CJK (global) metrics management */ + + /* + * CJK glyphs tend to fill the square. So we have both vertical and + * horizontal blue zones. But some glyphs have flat bounding strokes that + * leave some space between neighbour glyphs. + */ + enum + { + AF_CJK_BLUE_TOP, + AF_CJK_BLUE_BOTTOM, + AF_CJK_BLUE_LEFT, + AF_CJK_BLUE_RIGHT, + + AF_CJK_BLUE_MAX + }; + + +#define AF_CJK_MAX_WIDTHS 16 +#define AF_CJK_MAX_BLUES AF_CJK_BLUE_MAX + + + enum + { + AF_CJK_BLUE_ACTIVE = 1 << 0, + AF_CJK_BLUE_IS_TOP = 1 << 1, + AF_CJK_BLUE_IS_RIGHT = 1 << 2, + AF_CJK_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment */ + /* optimization */ + AF_CJK_BLUE_FLAG_MAX + }; + + + typedef struct AF_CJKBlueRec_ + { + AF_WidthRec ref; + AF_WidthRec shoot; /* undershoot */ + FT_UInt flags; + + } AF_CJKBlueRec, *AF_CJKBlue; + + + typedef struct AF_CJKAxisRec_ + { + FT_Fixed scale; + FT_Pos delta; + + FT_UInt width_count; + AF_WidthRec widths[AF_CJK_MAX_WIDTHS]; + FT_Pos edge_distance_threshold; + FT_Pos standard_width; + FT_Bool extra_light; + + /* used for horizontal metrics too for CJK */ + FT_Bool control_overshoot; + FT_UInt blue_count; + AF_CJKBlueRec blues[AF_CJK_BLUE_MAX]; + + FT_Fixed org_scale; + FT_Pos org_delta; + + } AF_CJKAxisRec, *AF_CJKAxis; + + + typedef struct AF_CJKMetricsRec_ + { + AF_ScriptMetricsRec root; + FT_UInt units_per_em; + AF_CJKAxisRec axis[AF_DIMENSION_MAX]; + + } AF_CJKMetricsRec, *AF_CJKMetrics; + + +#ifdef AF_CONFIG_OPTION_CJK + FT_LOCAL( FT_Error ) + af_cjk_metrics_init( AF_CJKMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_cjk_metrics_scale( AF_CJKMetrics metrics, + AF_Scaler scaler ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_init( AF_GlyphHints hints, + AF_CJKMetrics metrics ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_CJKMetrics metrics ); + + /* shared; called from afindic.c */ + FT_LOCAL( void ) + af_cjk_metrics_check_digits( AF_CJKMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_cjk_metrics_init_widths( AF_CJKMetrics metrics, + FT_Face face ); +#endif /* AF_CONFIG_OPTION_CJK */ + + +/* */ + +FT_END_HEADER + +#endif /* __AFCJK_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afdummy.c b/drivers/freetype/src/autofit/afdummy.c new file mode 100644 index 0000000000..22944559da --- /dev/null +++ b/drivers/freetype/src/autofit/afdummy.c @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* afdummy.c */ +/* */ +/* Auto-fitter dummy routines to be used if no hinting should be */ +/* performed (body). */ +/* */ +/* Copyright 2003-2005, 2011, 2013 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 "afdummy.h" +#include "afhints.h" +#include "aferrors.h" + + + static FT_Error + af_dummy_hints_init( AF_GlyphHints hints, + AF_ScriptMetrics metrics ) + { + af_glyph_hints_rescale( hints, + metrics ); + return FT_Err_Ok; + } + + + static FT_Error + af_dummy_hints_apply( AF_GlyphHints hints, + FT_Outline* outline ) + { + FT_UNUSED( hints ); + FT_UNUSED( outline ); + + return FT_Err_Ok; + } + + + AF_DEFINE_SCRIPT_CLASS( af_dummy_script_class, + AF_SCRIPT_DUMMY, + NULL, + 0, + + sizeof ( AF_ScriptMetricsRec ), + + (AF_Script_InitMetricsFunc) NULL, + (AF_Script_ScaleMetricsFunc)NULL, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_dummy_hints_init, + (AF_Script_ApplyHintsFunc) af_dummy_hints_apply + ) + + +/* END */ diff --git a/drivers/freetype/src/autofit/afdummy.h b/drivers/freetype/src/autofit/afdummy.h new file mode 100644 index 0000000000..95d8f8cf19 --- /dev/null +++ b/drivers/freetype/src/autofit/afdummy.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* afdummy.h */ +/* */ +/* Auto-fitter dummy routines to be used if no hinting should be */ +/* performed (specification). */ +/* */ +/* Copyright 2003-2005, 2011 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 __AFDUMMY_H__ +#define __AFDUMMY_H__ + +#include "aftypes.h" + + +FT_BEGIN_HEADER + + /* A dummy script metrics class used when no hinting should + * be performed. This is the default for non-latin glyphs! + */ + + AF_DECLARE_SCRIPT_CLASS( af_dummy_script_class ) + +/* */ + +FT_END_HEADER + + +#endif /* __AFDUMMY_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/aferrors.h b/drivers/freetype/src/autofit/aferrors.h new file mode 100644 index 0000000000..50e1a22dd5 --- /dev/null +++ b/drivers/freetype/src/autofit/aferrors.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* aferrors.h */ +/* */ +/* Autofitter error codes (specification only). */ +/* */ +/* Copyright 2005, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the Autofitter error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __AFERRORS_H__ +#define __AFERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX AF_Err_ +#define FT_ERR_BASE FT_Mod_Err_Autofit + +#include FT_ERRORS_H + +#endif /* __AFERRORS_H__ */ + +/* END */ diff --git a/drivers/freetype/src/autofit/afglobal.c b/drivers/freetype/src/autofit/afglobal.c new file mode 100644 index 0000000000..3e41465756 --- /dev/null +++ b/drivers/freetype/src/autofit/afglobal.c @@ -0,0 +1,304 @@ +/***************************************************************************/ +/* */ +/* afglobal.c */ +/* */ +/* Auto-fitter routines to compute global hinting values (body). */ +/* */ +/* Copyright 2003-2013 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 "afglobal.h" +#include "afdummy.h" +#include "aflatin.h" +#include "afcjk.h" +#include "afindic.h" +#include "afpic.h" + +#include "aferrors.h" + +#ifdef FT_OPTION_AUTOFIT2 +#include "aflatin2.h" +#endif + +#ifndef FT_CONFIG_OPTION_PIC + + /* when updating this table, don't forget to update */ + /* AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ + + /* populate this list when you add new scripts */ + static AF_ScriptClass const af_script_classes[] = + { + &af_dummy_script_class, +#ifdef FT_OPTION_AUTOFIT2 + &af_latin2_script_class, +#endif + &af_latin_script_class, + &af_cjk_script_class, + &af_indic_script_class, + NULL /* do not remove */ + }; + +#endif /* !FT_CONFIG_OPTION_PIC */ + + + /* Compute the script index of each glyph within a given face. */ + + static FT_Error + af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) + { + FT_Error error; + FT_Face face = globals->face; + FT_CharMap old_charmap = face->charmap; + FT_Byte* gscripts = globals->glyph_scripts; + FT_UInt ss; + FT_UInt i; + + + /* the value AF_SCRIPT_NONE means `uncovered glyph' */ + FT_MEM_SET( globals->glyph_scripts, + AF_SCRIPT_NONE, + globals->glyph_count ); + + error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); + if ( error ) + { + /* + * Ignore this error; we simply use the fallback script. + * XXX: Shouldn't we rather disable hinting? + */ + error = FT_Err_Ok; + goto Exit; + } + + /* scan each script in a Unicode charmap */ + for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) + { + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; + AF_Script_UniRange range; + + + if ( clazz->script_uni_ranges == NULL ) + continue; + + /* + * Scan all Unicode points in the range and set the corresponding + * glyph script index. + */ + for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) + { + FT_ULong charcode = range->first; + FT_UInt gindex; + + + gindex = FT_Get_Char_Index( face, charcode ); + + if ( gindex != 0 && + gindex < (FT_ULong)globals->glyph_count && + gscripts[gindex] == AF_SCRIPT_NONE ) + gscripts[gindex] = (FT_Byte)ss; + + for (;;) + { + charcode = FT_Get_Next_Char( face, charcode, &gindex ); + + if ( gindex == 0 || charcode > range->last ) + break; + + if ( gindex < (FT_ULong)globals->glyph_count && + gscripts[gindex] == AF_SCRIPT_NONE ) + gscripts[gindex] = (FT_Byte)ss; + } + } + } + + /* mark ASCII digits */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt gindex = FT_Get_Char_Index( face, i ); + + + if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) + gscripts[gindex] |= AF_DIGIT; + } + + Exit: + /* + * By default, all uncovered glyphs are set to the fallback script. + * XXX: Shouldn't we disable hinting or do something similar? + */ + if ( globals->module->fallback_script != AF_SCRIPT_NONE ) + { + FT_Long nn; + + + for ( nn = 0; nn < globals->glyph_count; nn++ ) + { + if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_NONE ) + { + gscripts[nn] &= ~AF_SCRIPT_NONE; + gscripts[nn] |= globals->module->fallback_script; + } + } + } + + FT_Set_Charmap( face, old_charmap ); + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_face_globals_new( FT_Face face, + AF_FaceGlobals *aglobals, + AF_Module module ) + { + FT_Error error; + FT_Memory memory; + AF_FaceGlobals globals = NULL; + + + memory = face->memory; + + if ( FT_ALLOC( globals, sizeof ( *globals ) + + face->num_glyphs * sizeof ( FT_Byte ) ) ) + goto Exit; + + globals->face = face; + globals->glyph_count = face->num_glyphs; + globals->glyph_scripts = (FT_Byte*)( globals + 1 ); + globals->module = module; + + error = af_face_globals_compute_script_coverage( globals ); + if ( error ) + { + af_face_globals_free( globals ); + globals = NULL; + } + + globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; + + Exit: + *aglobals = globals; + return error; + } + + + FT_LOCAL_DEF( void ) + af_face_globals_free( AF_FaceGlobals globals ) + { + if ( globals ) + { + FT_Memory memory = globals->face->memory; + FT_UInt nn; + + + for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ ) + { + if ( globals->metrics[nn] ) + { + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[nn]; + + + FT_ASSERT( globals->metrics[nn]->clazz == clazz ); + + if ( clazz->script_metrics_done ) + clazz->script_metrics_done( globals->metrics[nn] ); + + FT_FREE( globals->metrics[nn] ); + } + } + + globals->glyph_count = 0; + globals->glyph_scripts = NULL; /* no need to free this one! */ + globals->face = NULL; + + FT_FREE( globals ); + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + FT_UInt options, + AF_ScriptMetrics *ametrics ) + { + AF_ScriptMetrics metrics = NULL; + FT_UInt gidx; + AF_ScriptClass clazz; + FT_UInt script = options & 15; + const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / + sizeof ( AF_SCRIPT_CLASSES_GET[0] ); + FT_Error error = FT_Err_Ok; + + + if ( gindex >= (FT_ULong)globals->glyph_count ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + gidx = script; + if ( gidx == 0 || gidx + 1 >= script_max ) + gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_NONE; + + clazz = AF_SCRIPT_CLASSES_GET[gidx]; + if ( script == 0 ) + script = clazz->script; + + metrics = globals->metrics[clazz->script]; + if ( metrics == NULL ) + { + /* create the global metrics object if necessary */ + FT_Memory memory = globals->face->memory; + + + if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) + goto Exit; + + metrics->clazz = clazz; + metrics->globals = globals; + + if ( clazz->script_metrics_init ) + { + error = clazz->script_metrics_init( metrics, globals->face ); + if ( error ) + { + if ( clazz->script_metrics_done ) + clazz->script_metrics_done( metrics ); + + FT_FREE( metrics ); + goto Exit; + } + } + + globals->metrics[clazz->script] = metrics; + } + + Exit: + *ametrics = metrics; + + return error; + } + + + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ) + { + if ( gindex < (FT_ULong)globals->glyph_count ) + return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); + + return (FT_Bool)0; + } + + +/* END */ diff --git a/drivers/freetype/src/autofit/afglobal.h b/drivers/freetype/src/autofit/afglobal.h new file mode 100644 index 0000000000..2e24900822 --- /dev/null +++ b/drivers/freetype/src/autofit/afglobal.h @@ -0,0 +1,109 @@ +/***************************************************************************/ +/* */ +/* afglobal.h */ +/* */ +/* Auto-fitter routines to compute global hinting values */ +/* (specification). */ +/* */ +/* Copyright 2003-2005, 2007, 2009, 2011-2012 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 __AFGLOBAL_H__ +#define __AFGLOBAL_H__ + + +#include "aftypes.h" +#include "afmodule.h" + + +FT_BEGIN_HEADER + + + /* + * Default values and flags for both autofitter globals (found in + * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec). + */ + + /* index of fallback script in `af_script_classes' */ +#define AF_SCRIPT_FALLBACK 2 + /* a bit mask indicating an uncovered glyph */ +#define AF_SCRIPT_NONE 0x7F + /* if this flag is set, we have an ASCII digit */ +#define AF_DIGIT 0x80 + + /* `increase-x-height' property */ +#define AF_PROP_INCREASE_X_HEIGHT_MIN 6 +#define AF_PROP_INCREASE_X_HEIGHT_MAX 0 + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** F A C E G L O B A L S *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + /* + * Note that glyph_scripts[] is used to map each glyph into + * an index into the `af_script_classes' array. + * + */ + typedef struct AF_FaceGlobalsRec_ + { + FT_Face face; + FT_Long glyph_count; /* same as face->num_glyphs */ + FT_Byte* glyph_scripts; + + /* per-face auto-hinter properties */ + FT_UInt increase_x_height; + + AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; + + AF_Module module; /* to access global properties */ + + } AF_FaceGlobalsRec; + + + /* + * model the global hints data for a given face, decomposed into + * script-specific items + */ + + FT_LOCAL( FT_Error ) + af_face_globals_new( FT_Face face, + AF_FaceGlobals *aglobals, + AF_Module module ); + + FT_LOCAL( FT_Error ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + FT_UInt options, + AF_ScriptMetrics *ametrics ); + + FT_LOCAL( void ) + af_face_globals_free( AF_FaceGlobals globals ); + + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ); + + /* */ + + +FT_END_HEADER + +#endif /* __AFGLOBAL_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afhints.c b/drivers/freetype/src/autofit/afhints.c new file mode 100644 index 0000000000..e8defaa88d --- /dev/null +++ b/drivers/freetype/src/autofit/afhints.c @@ -0,0 +1,1321 @@ +/***************************************************************************/ +/* */ +/* afhints.c */ +/* */ +/* Auto-fitter hinting routines (body). */ +/* */ +/* Copyright 2003-2007, 2009-2013 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 "afhints.h" +#include "aferrors.h" +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_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_afhints + + + /* Get new segment for given axis. */ + + FT_LOCAL_DEF( FT_Error ) + af_axis_hints_new_segment( AF_AxisHints axis, + FT_Memory memory, + AF_Segment *asegment ) + { + FT_Error error = FT_Err_Ok; + AF_Segment segment = NULL; + + + if ( axis->num_segments >= axis->max_segments ) + { + FT_Int old_max = axis->max_segments; + FT_Int new_max = old_max; + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) ); + + + if ( old_max >= big_max ) + { + error = FT_THROW( Out_Of_Memory ); + goto Exit; + } + + new_max += ( new_max >> 2 ) + 4; + if ( new_max < old_max || new_max > big_max ) + new_max = big_max; + + if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) + goto Exit; + + axis->max_segments = new_max; + } + + segment = axis->segments + axis->num_segments++; + + Exit: + *asegment = segment; + return error; + } + + + /* Get new edge for given axis, direction, and position. */ + + FT_LOCAL( FT_Error ) + af_axis_hints_new_edge( AF_AxisHints axis, + FT_Int fpos, + AF_Direction dir, + FT_Memory memory, + AF_Edge *anedge ) + { + FT_Error error = FT_Err_Ok; + AF_Edge edge = NULL; + AF_Edge edges; + + + if ( axis->num_edges >= axis->max_edges ) + { + FT_Int old_max = axis->max_edges; + FT_Int new_max = old_max; + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); + + + if ( old_max >= big_max ) + { + error = FT_THROW( Out_Of_Memory ); + goto Exit; + } + + new_max += ( new_max >> 2 ) + 4; + if ( new_max < old_max || new_max > big_max ) + new_max = big_max; + + if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) + goto Exit; + + axis->max_edges = new_max; + } + + edges = axis->edges; + edge = edges + axis->num_edges; + + while ( edge > edges ) + { + if ( edge[-1].fpos < fpos ) + break; + + /* we want the edge with same position and minor direction */ + /* to appear before those in the major one in the list */ + if ( edge[-1].fpos == fpos && dir == axis->major_dir ) + break; + + edge[0] = edge[-1]; + edge--; + } + + axis->num_edges++; + + FT_ZERO( edge ); + edge->fpos = (FT_Short)fpos; + edge->dir = (FT_Char)dir; + + Exit: + *anedge = edge; + return error; + } + + +#ifdef FT_DEBUG_AUTOFIT + +#include FT_CONFIG_STANDARD_LIBRARY_H + + static const char* + af_dir_str( AF_Direction dir ) + { + const char* result; + + + switch ( dir ) + { + case AF_DIR_UP: + result = "up"; + break; + case AF_DIR_DOWN: + result = "down"; + break; + case AF_DIR_LEFT: + result = "left"; + break; + case AF_DIR_RIGHT: + result = "right"; + break; + default: + result = "none"; + } + + return result; + } + + +#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 ) + + +#ifdef __cplusplus + extern "C" { +#endif + void + af_glyph_hints_dump_points( AF_GlyphHints hints ) + { + AF_Point points = hints->points; + AF_Point limit = points + hints->num_points; + AF_Point point; + + + FT_TRACE7(( "Table of points:\n" + " [ index | xorg | yorg | xscale | yscale" + " | xfit | yfit | flags ]\n" )); + + for ( point = points; point < limit; point++ ) + FT_TRACE7(( " [ %5d | %5d | %5d | %6.2f | %6.2f" + " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n", + point - points, + point->fx, + point->fy, + point->ox / 64.0, + point->oy / 64.0, + point->x / 64.0, + point->y / 64.0, + ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', + ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', + ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', + ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ', + ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ', + ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' ')); + FT_TRACE7(( "\n" )); + } +#ifdef __cplusplus + } +#endif + + + static const char* + af_edge_flags_to_string( AF_Edge_Flags flags ) + { + static char temp[32]; + int pos = 0; + + + if ( flags & AF_EDGE_ROUND ) + { + ft_memcpy( temp + pos, "round", 5 ); + pos += 5; + } + if ( flags & AF_EDGE_SERIF ) + { + if ( pos > 0 ) + temp[pos++] = ' '; + ft_memcpy( temp + pos, "serif", 5 ); + pos += 5; + } + if ( pos == 0 ) + return "normal"; + + temp[pos] = '\0'; + + return temp; + } + + + /* Dump the array of linked segments. */ + +#ifdef __cplusplus + extern "C" { +#endif + void + af_glyph_hints_dump_segments( AF_GlyphHints hints ) + { + FT_Int dimension; + + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Point points = hints->points; + AF_Edge edges = axis->edges; + AF_Segment segments = axis->segments; + AF_Segment limit = segments + axis->num_segments; + AF_Segment seg; + + + FT_TRACE7(( "Table of %s segments:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" + : "horizontal" )); + if ( axis->num_segments ) + FT_TRACE7(( " [ index | pos | dir | from" + " | to | link | serif | edge" + " | height | extra | flags ]\n" )); + else + FT_TRACE7(( " (none)\n" )); + + for ( seg = segments; seg < limit; seg++ ) + FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d" + " | %4d | %4d | %5d | %4d" + " | %6d | %5d | %11s ]\n", + seg - segments, + dimension == AF_DIMENSION_HORZ + ? (int)seg->first->ox / 64.0 + : (int)seg->first->oy / 64.0, + af_dir_str( (AF_Direction)seg->dir ), + AF_INDEX_NUM( seg->first, points ), + AF_INDEX_NUM( seg->last, points ), + AF_INDEX_NUM( seg->link, segments ), + AF_INDEX_NUM( seg->serif, segments ), + AF_INDEX_NUM( seg->edge, edges ), + seg->height, + seg->height - ( seg->max_coord - seg->min_coord ), + af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) )); + FT_TRACE7(( "\n" )); + } + } +#ifdef __cplusplus + } +#endif + + + /* Fetch number of segments. */ + +#ifdef __cplusplus + extern "C" { +#endif + FT_Error + af_glyph_hints_get_num_segments( AF_GlyphHints hints, + FT_Int dimension, + FT_Int* num_segments ) + { + AF_Dimension dim; + AF_AxisHints axis; + + + dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; + + axis = &hints->axis[dim]; + *num_segments = axis->num_segments; + + return FT_Err_Ok; + } +#ifdef __cplusplus + } +#endif + + + /* Fetch offset of segments into user supplied offset array. */ + +#ifdef __cplusplus + extern "C" { +#endif + FT_Error + af_glyph_hints_get_segment_offset( AF_GlyphHints hints, + FT_Int dimension, + FT_Int idx, + FT_Pos* offset ) + { + AF_Dimension dim; + AF_AxisHints axis; + AF_Segment seg; + + + if ( !offset ) + return FT_THROW( Invalid_Argument ); + + dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; + + axis = &hints->axis[dim]; + + if ( idx < 0 || idx >= axis->num_segments ) + return FT_THROW( Invalid_Argument ); + + seg = &axis->segments[idx]; + *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox + : seg->first->oy; + + return FT_Err_Ok; + } +#ifdef __cplusplus + } +#endif + + + /* Dump the array of linked edges. */ + +#ifdef __cplusplus + extern "C" { +#endif + void + af_glyph_hints_dump_edges( AF_GlyphHints hints ) + { + FT_Int dimension; + + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Edge edges = axis->edges; + AF_Edge limit = edges + axis->num_edges; + AF_Edge edge; + + + /* + * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges + * since they have a constant X coordinate. + */ + FT_TRACE7(( "Table of %s edges:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" + : "horizontal" )); + if ( axis->num_edges ) + FT_TRACE7(( " [ index | pos | dir | link" + " | serif | blue | opos | pos | flags ]\n" )); + else + FT_TRACE7(( " (none)\n" )); + + for ( edge = edges; edge < limit; edge++ ) + FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d" + " | %5d | %c | %5.2f | %5.2f | %11s ]\n", + edge - edges, + (int)edge->opos / 64.0, + af_dir_str( (AF_Direction)edge->dir ), + AF_INDEX_NUM( edge->link, edges ), + AF_INDEX_NUM( edge->serif, edges ), + edge->blue_edge ? 'y' : 'n', + edge->opos / 64.0, + edge->pos / 64.0, + af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) )); + FT_TRACE7(( "\n" )); + } + } +#ifdef __cplusplus + } +#endif + +#else /* !FT_DEBUG_AUTOFIT */ + + /* these empty stubs are only used to link the `ftgrid' test program */ + /* if debugging is disabled */ + +#ifdef __cplusplus + extern "C" { +#endif + + void + af_glyph_hints_dump_points( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + + + void + af_glyph_hints_dump_segments( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + + + FT_Error + af_glyph_hints_get_num_segments( AF_GlyphHints hints, + FT_Int dimension, + FT_Int* num_segments ) + { + FT_UNUSED( hints ); + FT_UNUSED( dimension ); + FT_UNUSED( num_segments ); + + return 0; + } + + + FT_Error + af_glyph_hints_get_segment_offset( AF_GlyphHints hints, + FT_Int dimension, + FT_Int idx, + FT_Pos* offset ) + { + FT_UNUSED( hints ); + FT_UNUSED( dimension ); + FT_UNUSED( idx ); + FT_UNUSED( offset ); + + return 0; + } + + + void + af_glyph_hints_dump_edges( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + +#ifdef __cplusplus + } +#endif + +#endif /* !FT_DEBUG_AUTOFIT */ + + + /* Compute the direction value of a given vector. */ + + FT_LOCAL_DEF( AF_Direction ) + af_direction_compute( FT_Pos dx, + FT_Pos dy ) + { + FT_Pos ll, ss; /* long and short arm lengths */ + AF_Direction dir; /* candidate direction */ + + + if ( dy >= dx ) + { + if ( dy >= -dx ) + { + dir = AF_DIR_UP; + ll = dy; + ss = dx; + } + else + { + dir = AF_DIR_LEFT; + ll = -dx; + ss = dy; + } + } + else /* dy < dx */ + { + if ( dy >= -dx ) + { + dir = AF_DIR_RIGHT; + ll = dx; + ss = dy; + } + else + { + dir = AF_DIR_DOWN; + ll = dy; + ss = dx; + } + } + + /* return no direction if arm lengths differ too much */ + /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */ + ss *= 14; + if ( FT_ABS( ll ) <= FT_ABS( ss ) ) + dir = AF_DIR_NONE; + + return dir; + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_init( AF_GlyphHints hints, + FT_Memory memory ) + { + FT_ZERO( hints ); + hints->memory = memory; + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_done( AF_GlyphHints hints ) + { + FT_Memory memory = hints->memory; + int dim; + + + if ( !( hints && hints->memory ) ) + return; + + /* + * note that we don't need to free the segment and edge + * buffers since they are really within the hints->points array + */ + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_AxisHints axis = &hints->axis[dim]; + + + axis->num_segments = 0; + axis->max_segments = 0; + FT_FREE( axis->segments ); + + axis->num_edges = 0; + axis->max_edges = 0; + FT_FREE( axis->edges ); + } + + FT_FREE( hints->contours ); + hints->max_contours = 0; + hints->num_contours = 0; + + FT_FREE( hints->points ); + hints->num_points = 0; + hints->max_points = 0; + + hints->memory = NULL; + } + + + /* Reset metrics. */ + + FT_LOCAL_DEF( void ) + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_ScriptMetrics metrics ) + { + hints->metrics = metrics; + hints->scaler_flags = metrics->scaler.flags; + } + + + /* Recompute all AF_Point in AF_GlyphHints from the definitions */ + /* in a source outline. */ + + FT_LOCAL_DEF( FT_Error ) + af_glyph_hints_reload( AF_GlyphHints hints, + FT_Outline* outline ) + { + FT_Error error = FT_Err_Ok; + AF_Point points; + FT_UInt old_max, new_max; + FT_Fixed x_scale = hints->x_scale; + FT_Fixed y_scale = hints->y_scale; + FT_Pos x_delta = hints->x_delta; + FT_Pos y_delta = hints->y_delta; + FT_Memory memory = hints->memory; + + + hints->num_points = 0; + hints->num_contours = 0; + + hints->axis[0].num_segments = 0; + hints->axis[0].num_edges = 0; + hints->axis[1].num_segments = 0; + hints->axis[1].num_edges = 0; + + /* first of all, reallocate the contours array if necessary */ + new_max = (FT_UInt)outline->n_contours; + old_max = hints->max_contours; + if ( new_max > old_max ) + { + new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */ + + if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) + goto Exit; + + hints->max_contours = new_max; + } + + /* + * then reallocate the points arrays if necessary -- + * note that we reserve two additional point positions, used to + * hint metrics appropriately + */ + new_max = (FT_UInt)( outline->n_points + 2 ); + old_max = hints->max_points; + if ( new_max > old_max ) + { + new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */ + + if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) + goto Exit; + + hints->max_points = new_max; + } + + hints->num_points = outline->n_points; + hints->num_contours = outline->n_contours; + + /* We can't rely on the value of `FT_Outline.flags' to know the fill */ + /* direction used for a glyph, given that some fonts are broken (e.g., */ + /* the Arphic ones). We thus recompute it each time we need to. */ + /* */ + hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP; + hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT; + + if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) + { + hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN; + hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT; + } + + hints->x_scale = x_scale; + hints->y_scale = y_scale; + hints->x_delta = x_delta; + hints->y_delta = y_delta; + + hints->xmin_delta = 0; + hints->xmax_delta = 0; + + points = hints->points; + if ( hints->num_points == 0 ) + goto Exit; + + { + AF_Point point; + AF_Point point_limit = points + hints->num_points; + + + /* compute coordinates & Bezier flags, next and prev */ + { + FT_Vector* vec = outline->points; + char* tag = outline->tags; + AF_Point end = points + outline->contours[0]; + AF_Point prev = end; + FT_Int contour_index = 0; + + + for ( point = points; point < point_limit; point++, vec++, tag++ ) + { + point->fx = (FT_Short)vec->x; + point->fy = (FT_Short)vec->y; + point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; + point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; + + switch ( FT_CURVE_TAG( *tag ) ) + { + case FT_CURVE_TAG_CONIC: + point->flags = AF_FLAG_CONIC; + break; + case FT_CURVE_TAG_CUBIC: + point->flags = AF_FLAG_CUBIC; + break; + default: + point->flags = AF_FLAG_NONE; + } + + point->prev = prev; + prev->next = point; + prev = point; + + if ( point == end ) + { + if ( ++contour_index < outline->n_contours ) + { + end = points + outline->contours[contour_index]; + prev = end; + } + } + } + } + + /* set up the contours array */ + { + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + short* end = outline->contours; + short idx = 0; + + + for ( ; contour < contour_limit; contour++, end++ ) + { + contour[0] = points + idx; + idx = (short)( end[0] + 1 ); + } + } + + /* compute directions of in & out vectors */ + { + AF_Point first = points; + AF_Point prev = NULL; + FT_Pos in_x = 0; + FT_Pos in_y = 0; + AF_Direction in_dir = AF_DIR_NONE; + + + for ( point = points; point < point_limit; point++ ) + { + AF_Point next; + FT_Pos out_x, out_y; + + + if ( point == first ) + { + prev = first->prev; + in_x = first->fx - prev->fx; + in_y = first->fy - prev->fy; + in_dir = af_direction_compute( in_x, in_y ); + first = prev + 1; + } + + point->in_dir = (FT_Char)in_dir; + + next = point->next; + out_x = next->fx - point->fx; + out_y = next->fy - point->fy; + + in_dir = af_direction_compute( out_x, out_y ); + point->out_dir = (FT_Char)in_dir; + + /* check for weak points */ + + if ( point->flags & AF_FLAG_CONTROL ) + { + Is_Weak_Point: + point->flags |= AF_FLAG_WEAK_INTERPOLATION; + } + else if ( point->out_dir == point->in_dir ) + { + 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 if ( point->in_dir == -point->out_dir ) + goto Is_Weak_Point; + + in_x = out_x; + in_y = out_y; + prev = point; + } + } + } + + Exit: + return error; + } + + + /* Store the hinted outline in an FT_Outline structure. */ + + FT_LOCAL_DEF( void ) + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + FT_Vector* vec = outline->points; + char* tag = outline->tags; + + + for ( ; point < limit; point++, vec++, tag++ ) + { + vec->x = point->x; + vec->y = point->y; + + if ( point->flags & AF_FLAG_CONIC ) + tag[0] = FT_CURVE_TAG_CONIC; + else if ( point->flags & AF_FLAG_CUBIC ) + tag[0] = FT_CURVE_TAG_CUBIC; + else + tag[0] = FT_CURVE_TAG_ON; + } + } + + + /**************************************************************** + * + * EDGE POINT GRID-FITTING + * + ****************************************************************/ + + + /* Align all points of an edge to the same coordinate value, */ + /* either horizontally or vertically. */ + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = & hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + + + if ( dim == AF_DIMENSION_HORZ ) + { + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge edge = seg->edge; + AF_Point point, first, last; + + + if ( edge == NULL ) + continue; + + first = seg->first; + last = seg->last; + point = first; + for (;;) + { + point->x = edge->pos; + point->flags |= AF_FLAG_TOUCH_X; + + if ( point == last ) + break; + + point = point->next; + } + } + } + else + { + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge edge = seg->edge; + AF_Point point, first, last; + + + if ( edge == NULL ) + continue; + + first = seg->first; + last = seg->last; + point = first; + for (;;) + { + point->y = edge->pos; + point->flags |= AF_FLAG_TOUCH_Y; + + if ( point == last ) + break; + + point = point->next; + } + } + } + } + + + /**************************************************************** + * + * STRONG POINT INTERPOLATION + * + ****************************************************************/ + + + /* Hint the strong points -- this is equivalent to the TrueType `IP' */ + /* hinting instruction. */ + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_strong_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_Point points = hints->points; + AF_Point point_limit = points + hints->num_points; + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Flags touch_flag; + + + if ( dim == AF_DIMENSION_HORZ ) + touch_flag = AF_FLAG_TOUCH_X; + else + touch_flag = AF_FLAG_TOUCH_Y; + + if ( edges < edge_limit ) + { + AF_Point point; + AF_Edge edge; + + + for ( point = points; point < point_limit; point++ ) + { + FT_Pos u, ou, fu; /* point position */ + FT_Pos delta; + + + if ( point->flags & touch_flag ) + continue; + + /* if this point is candidate to weak interpolation, we */ + /* interpolate it after all strong points have been processed */ + + if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && + !( point->flags & AF_FLAG_INFLECTION ) ) + continue; + + if ( dim == AF_DIMENSION_VERT ) + { + u = point->fy; + ou = point->oy; + } + else + { + u = point->fx; + ou = point->ox; + } + + fu = u; + + /* is the point before the first edge? */ + edge = edges; + delta = edge->fpos - u; + if ( delta >= 0 ) + { + u = edge->pos - ( edge->opos - ou ); + goto Store_Point; + } + + /* is the point after the last edge? */ + edge = edge_limit - 1; + delta = u - edge->fpos; + if ( delta >= 0 ) + { + u = edge->pos + ( ou - edge->opos ); + goto Store_Point; + } + + { + FT_PtrDist min, max, mid; + FT_Pos fpos; + + + /* find enclosing edges */ + min = 0; + max = edge_limit - edges; + +#if 1 + /* for a small number of edges, a linear search is better */ + if ( max <= 8 ) + { + FT_PtrDist nn; + + + for ( nn = 0; nn < max; nn++ ) + if ( edges[nn].fpos >= u ) + break; + + if ( edges[nn].fpos == u ) + { + u = edges[nn].pos; + goto Store_Point; + } + min = nn; + } + else +#endif + while ( min < max ) + { + mid = ( max + min ) >> 1; + edge = edges + mid; + fpos = edge->fpos; + + if ( u < fpos ) + max = mid; + else if ( u > fpos ) + min = mid + 1; + else + { + /* we are on the edge */ + u = edge->pos; + goto Store_Point; + } + } + + /* point is not on an edge */ + { + AF_Edge before = edges + min - 1; + AF_Edge after = edges + min + 0; + + + /* assert( before && after && before != after ) */ + if ( before->scale == 0 ) + before->scale = FT_DivFix( after->pos - before->pos, + after->fpos - before->fpos ); + + u = before->pos + FT_MulFix( fu - before->fpos, + before->scale ); + } + } + + Store_Point: + /* save the point position */ + if ( dim == AF_DIMENSION_HORZ ) + point->x = u; + else + point->y = u; + + point->flags |= touch_flag; + } + } + } + + + /**************************************************************** + * + * WEAK POINT INTERPOLATION + * + ****************************************************************/ + + + /* Shift the original coordinates of all points between `p1' and */ + /* `p2' to get hinted coordinates, using the same difference as */ + /* given by `ref'. */ + + static void + af_iup_shift( AF_Point p1, + AF_Point p2, + AF_Point ref ) + { + AF_Point p; + FT_Pos delta = ref->u - ref->v; + + + if ( delta == 0 ) + return; + + for ( p = p1; p < ref; p++ ) + p->u = p->v + delta; + + for ( p = ref + 1; p <= p2; p++ ) + p->u = p->v + delta; + } + + + /* Interpolate the original coordinates of all points between `p1' and */ + /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */ + /* reference points. The `u' and `v' members are the current and */ + /* original coordinate values, respectively. */ + /* */ + /* Details can be found in the TrueType bytecode specification. */ + + static void + af_iup_interp( AF_Point p1, + AF_Point p2, + AF_Point ref1, + AF_Point ref2 ) + { + AF_Point p; + FT_Pos u; + FT_Pos v1 = ref1->v; + FT_Pos v2 = ref2->v; + FT_Pos d1 = ref1->u - v1; + FT_Pos d2 = ref2->u - v2; + + + if ( p1 > p2 ) + return; + + if ( v1 == v2 ) + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v1 ) + u += d1; + else + u += d2; + + p->u = u; + } + return; + } + + if ( v1 < v2 ) + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v1 ) + u += d1; + else if ( u >= v2 ) + u += d2; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + else + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v2 ) + u += d2; + else if ( u >= v1 ) + u += d1; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + } + + + /* Hint the weak points -- this is equivalent to the TrueType `IUP' */ + /* hinting instruction. */ + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_weak_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_Point points = hints->points; + AF_Point point_limit = points + hints->num_points; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + AF_Flags touch_flag; + AF_Point point; + AF_Point end_point; + AF_Point first_point; + + + /* PASS 1: Move segment points to edge positions */ + + if ( dim == AF_DIMENSION_HORZ ) + { + touch_flag = AF_FLAG_TOUCH_X; + + for ( point = points; point < point_limit; point++ ) + { + point->u = point->x; + point->v = point->ox; + } + } + else + { + touch_flag = AF_FLAG_TOUCH_Y; + + for ( point = points; point < point_limit; point++ ) + { + point->u = point->y; + point->v = point->oy; + } + } + + point = points; + + for ( ; contour < contour_limit; contour++ ) + { + AF_Point first_touched, last_touched; + + + point = *contour; + end_point = point->prev; + first_point = point; + + /* find first touched point */ + for (;;) + { + if ( point > end_point ) /* no touched point in contour */ + goto NextContour; + + if ( point->flags & touch_flag ) + break; + + point++; + } + + first_touched = point; + last_touched = point; + + for (;;) + { + FT_ASSERT( point <= end_point && + ( point->flags & touch_flag ) != 0 ); + + /* skip any touched neighbours */ + while ( point < end_point && + ( point[1].flags & touch_flag ) != 0 ) + point++; + + last_touched = point; + + /* find the next touched point, if any */ + point++; + for (;;) + { + if ( point > end_point ) + goto EndContour; + + if ( ( point->flags & touch_flag ) != 0 ) + break; + + point++; + } + + /* interpolate between last_touched and point */ + af_iup_interp( last_touched + 1, point - 1, + last_touched, point ); + } + + EndContour: + /* special case: only one point was touched */ + if ( last_touched == first_touched ) + af_iup_shift( first_point, end_point, first_touched ); + + else /* interpolate the last part */ + { + if ( last_touched < end_point ) + af_iup_interp( last_touched + 1, end_point, + last_touched, first_touched ); + + if ( first_touched > points ) + af_iup_interp( first_point, first_touched - 1, + last_touched, first_touched ); + } + + NextContour: + ; + } + + /* now save the interpolated values back to x/y */ + if ( dim == AF_DIMENSION_HORZ ) + { + for ( point = points; point < point_limit; point++ ) + point->x = point->u; + } + else + { + for ( point = points; point < point_limit; point++ ) + point->y = point->u; + } + } + + +#ifdef AF_CONFIG_OPTION_USE_WARPER + + /* Apply (small) warp scale and warp delta for given dimension. */ + + FT_LOCAL_DEF( void ) + af_glyph_hints_scale_dim( AF_GlyphHints hints, + AF_Dimension dim, + FT_Fixed scale, + FT_Pos delta ) + { + AF_Point points = hints->points; + AF_Point points_limit = points + hints->num_points; + AF_Point point; + + + if ( dim == AF_DIMENSION_HORZ ) + { + for ( point = points; point < points_limit; point++ ) + point->x = FT_MulFix( point->fx, scale ) + delta; + } + else + { + for ( point = points; point < points_limit; point++ ) + point->y = FT_MulFix( point->fy, scale ) + delta; + } + } + +#endif /* AF_CONFIG_OPTION_USE_WARPER */ + +/* END */ diff --git a/drivers/freetype/src/autofit/afhints.h b/drivers/freetype/src/autofit/afhints.h new file mode 100644 index 0000000000..776b3c844e --- /dev/null +++ b/drivers/freetype/src/autofit/afhints.h @@ -0,0 +1,467 @@ +/***************************************************************************/ +/* */ +/* afhints.h */ +/* */ +/* Auto-fitter hinting routines (specification). */ +/* */ +/* Copyright 2003-2008, 2010-2012 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 __AFHINTS_H__ +#define __AFHINTS_H__ + +#include "aftypes.h" + +#define xxAF_SORT_SEGMENTS + +FT_BEGIN_HEADER + + /* + * The definition of outline glyph hints. These are shared by all + * script analysis routines (until now). + */ + + typedef enum AF_Dimension_ + { + AF_DIMENSION_HORZ = 0, /* x coordinates, */ + /* i.e., vertical segments & edges */ + AF_DIMENSION_VERT = 1, /* y coordinates, */ + /* i.e., horizontal segments & edges */ + + AF_DIMENSION_MAX /* do not remove */ + + } AF_Dimension; + + + /* hint directions -- the values are computed so that two vectors are */ + /* in opposite directions iff `dir1 + dir2 == 0' */ + typedef enum AF_Direction_ + { + AF_DIR_NONE = 4, + AF_DIR_RIGHT = 1, + AF_DIR_LEFT = -1, + AF_DIR_UP = 2, + AF_DIR_DOWN = -2 + + } AF_Direction; + + + /* + * The following explanations are mostly taken from the article + * + * Real-Time Grid Fitting of Typographic Outlines + * + * by David Turner and Werner Lemberg + * + * http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf + * + * + * Segments + * + * `af_{cjk,latin,...}_hints_compute_segments' are the functions to + * find segments in an outline. A segment is a series of consecutive + * points that are approximately aligned along a coordinate axis. The + * analysis to do so is specific to a script. + * + * A segment must have at least two points, except in the case of + * `fake' segments that are generated to hint metrics appropriately, + * and which consist of a single point. + * + * + * Edges + * + * As soon as segments are defined, the auto-hinter groups them into + * edges. An edge corresponds to a single position on the main + * dimension that collects one or more segments (allowing for a small + * threshold). + * + * The auto-hinter first tries to grid fit edges, then to align + * segments on the edges unless it detects that they form a serif. + * + * `af_{cjk,latin,...}_hints_compute_edges' are the functions to find + * edges; they are specific to a script. + * + * + * A H + * | | + * | | + * | | + * | | + * C | | F + * +------<-----+ +-----<------+ + * | B G | + * | | + * | | + * +--------------->------------------+ + * D E + * + * + * Stems + * + * Segments need to be `linked' to other ones in order to detect stems. + * A stem is made of two segments that face each other in opposite + * directions and that are sufficiently close to each other. Using + * vocabulary from the TrueType specification, stem segments form a + * `black distance'. + * + * In the above ASCII drawing, the horizontal segments are BC, DE, and + * FG; the vertical segments are AB, CD, EF, and GH. + * + * Each segment has at most one `best' candidate to form a black + * distance, or no candidate at all. Notice that two distinct segments + * can have the same candidate, which frequently means a serif. + * + * A stem is recognized by the following condition: + * + * best segment_1 = segment_2 && best segment_2 = segment_1 + * + * The best candidate is stored in field `link' in structure + * `AF_Segment'. + * + * Stems are detected by `af_{cjk,latin,...}_hint_edges'. + * + * In the above ASCII drawing, the best candidate for both AB and CD is + * GH, while the best candidate for GH is AB. Similarly, the best + * candidate for EF and GH is AB, while the best candidate for AB is + * GH. + * + * + * Serifs + * + * On the opposite, a serif has + * + * best segment_1 = segment_2 && best segment_2 != segment_1 + * + * where segment_1 corresponds to the serif segment (CD and EF in the + * above ASCII drawing). + * + * The best candidate is stored in field `serif' in structure + * `AF_Segment' (and `link' is set to NULL). + * + * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. + * + * + * Touched points + * + * A point is called `touched' if it has been processed somehow by the + * auto-hinter. It basically means that it shouldn't be moved again + * (or moved only under certain constraints to preserve the already + * applied processing). + * + * + * Flat and round segments + * + * Segments are `round' or `flat', depending on the series of points + * that define them. A segment is round if the next and previous point + * of an extremum (which can be either a single point or sequence of + * points) are both conic or cubic control points. Otherwise, a + * segment with an extremum is flat. + * + * + * Strong Points + * + * Experience has shown that points which are not part of an edge need + * to be interpolated linearly between their two closest edges, even if + * these are not part of the contour of those particular points. + * Typical candidates for this are + * + * - angle points (i.e., points where the `in' and `out' direction + * differ greatly) + * + * - inflection points (i.e., where the `in' and `out' angles are the + * same, but the curvature changes sign) + * + * `af_glyph_hints_align_strong_points' is the function which takes + * care of such situations; it is equivalent to the TrueType `IP' + * hinting instruction. + * + * + * Weak Points + * + * Other points in the outline must be interpolated using the + * coordinates of their previous and next unfitted contour neighbours. + * These are called `weak points' and are touched by the function + * `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP' + * hinting instruction. Typical candidates are control points and + * points on the contour without a major direction. + * + * The major effect is to reduce possible distortion caused by + * alignment of edges and strong points, thus weak points are processed + * after strong points. + */ + + + /* point hint flags */ + typedef enum AF_Flags_ + { + AF_FLAG_NONE = 0, + + /* point type flags */ + AF_FLAG_CONIC = 1 << 0, + AF_FLAG_CUBIC = 1 << 1, + AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, + + /* point extremum flags */ + AF_FLAG_EXTREMA_X = 1 << 2, + AF_FLAG_EXTREMA_Y = 1 << 3, + + /* point roundness flags */ + AF_FLAG_ROUND_X = 1 << 4, + AF_FLAG_ROUND_Y = 1 << 5, + + /* point touch flags */ + AF_FLAG_TOUCH_X = 1 << 6, + AF_FLAG_TOUCH_Y = 1 << 7, + + /* candidates for weak interpolation have this flag set */ + AF_FLAG_WEAK_INTERPOLATION = 1 << 8, + + /* all inflection points in the outline have this flag set */ + AF_FLAG_INFLECTION = 1 << 9 + + } AF_Flags; + + + /* edge hint flags */ + typedef enum AF_Edge_Flags_ + { + AF_EDGE_NORMAL = 0, + AF_EDGE_ROUND = 1 << 0, + AF_EDGE_SERIF = 1 << 1, + AF_EDGE_DONE = 1 << 2 + + } AF_Edge_Flags; + + + typedef struct AF_PointRec_* AF_Point; + typedef struct AF_SegmentRec_* AF_Segment; + typedef struct AF_EdgeRec_* AF_Edge; + + + typedef struct AF_PointRec_ + { + FT_UShort flags; /* point flags used by hinter */ + FT_Char in_dir; /* direction of inwards vector */ + FT_Char out_dir; /* direction of outwards vector */ + + FT_Pos ox, oy; /* original, scaled position */ + FT_Short fx, fy; /* original, unscaled position (in font units) */ + FT_Pos x, y; /* current position */ + FT_Pos u, v; /* current (x,y) or (y,x) depending on context */ + + AF_Point next; /* next point in contour */ + AF_Point prev; /* previous point in contour */ + + } AF_PointRec; + + + typedef struct AF_SegmentRec_ + { + FT_Byte flags; /* edge/segment flags for this segment */ + FT_Char dir; /* segment direction */ + 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 */ + + AF_Segment link; /* (stem) link segment */ + AF_Segment serif; /* primary segment for serifs */ + FT_Pos num_linked; /* number of linked segments */ + FT_Pos score; /* used during stem matching */ + FT_Pos len; /* used during stem matching */ + + AF_Point first; /* first point in edge segment */ + AF_Point last; /* last point in edge segment */ + + } AF_SegmentRec; + + + typedef struct AF_EdgeRec_ + { + FT_Short fpos; /* original, unscaled position (in font units) */ + FT_Pos opos; /* original, scaled position */ + FT_Pos pos; /* current position */ + + FT_Byte flags; /* edge flags */ + FT_Char dir; /* edge direction */ + FT_Fixed scale; /* used to speed up interpolation between edges */ + + AF_Width blue_edge; /* non-NULL if this is a blue edge */ + AF_Edge link; /* link edge */ + AF_Edge serif; /* primary edge for serifs */ + FT_Short num_linked; /* number of linked edges */ + FT_Int score; /* used during stem matching */ + + AF_Segment first; /* first segment in edge */ + AF_Segment last; /* last segment in edge */ + + } AF_EdgeRec; + + + typedef struct AF_AxisHintsRec_ + { + FT_Int num_segments; /* number of used segments */ + FT_Int max_segments; /* number of allocated segments */ + AF_Segment segments; /* segments array */ +#ifdef AF_SORT_SEGMENTS + FT_Int mid_segments; +#endif + + FT_Int num_edges; /* number of used edges */ + FT_Int max_edges; /* number of allocated edges */ + AF_Edge edges; /* edges array */ + + AF_Direction major_dir; /* either vertical or horizontal */ + + } AF_AxisHintsRec, *AF_AxisHints; + + + typedef struct AF_GlyphHintsRec_ + { + FT_Memory memory; + + FT_Fixed x_scale; + FT_Pos x_delta; + + FT_Fixed y_scale; + FT_Pos y_delta; + + FT_Int max_points; /* number of allocated points */ + FT_Int num_points; /* number of used points */ + AF_Point points; /* points array */ + + FT_Int max_contours; /* number of allocated contours */ + FT_Int num_contours; /* number of used contours */ + AF_Point* contours; /* contours array */ + + AF_AxisHintsRec axis[AF_DIMENSION_MAX]; + + FT_UInt32 scaler_flags; /* copy of scaler flags */ + FT_UInt32 other_flags; /* free for script-specific */ + /* implementations */ + AF_ScriptMetrics metrics; + + FT_Pos xmin_delta; /* used for warping */ + FT_Pos xmax_delta; + + } AF_GlyphHintsRec; + + +#define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) ) +#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) ) + + +#ifdef FT_DEBUG_AUTOFIT + +#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 /* !FT_DEBUG_AUTOFIT */ + +#define AF_HINTS_DO_HORIZONTAL( h ) \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) + +#define AF_HINTS_DO_VERTICAL( h ) \ + !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 ) 1 + +#endif /* !FT_DEBUG_AUTOFIT */ + + + FT_LOCAL( AF_Direction ) + af_direction_compute( FT_Pos dx, + FT_Pos dy ); + + + FT_LOCAL( FT_Error ) + af_axis_hints_new_segment( AF_AxisHints axis, + FT_Memory memory, + AF_Segment *asegment ); + + FT_LOCAL( FT_Error) + af_axis_hints_new_edge( AF_AxisHints axis, + FT_Int fpos, + AF_Direction dir, + FT_Memory memory, + AF_Edge *edge ); + + FT_LOCAL( void ) + af_glyph_hints_init( AF_GlyphHints hints, + FT_Memory memory ); + + FT_LOCAL( void ) + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_ScriptMetrics metrics ); + + FT_LOCAL( FT_Error ) + af_glyph_hints_reload( AF_GlyphHints hints, + FT_Outline* outline ); + + FT_LOCAL( void ) + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ); + + FT_LOCAL( void ) + af_glyph_hints_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_align_strong_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_align_weak_points( AF_GlyphHints hints, + AF_Dimension dim ); + +#ifdef AF_CONFIG_OPTION_USE_WARPER + FT_LOCAL( void ) + af_glyph_hints_scale_dim( AF_GlyphHints hints, + AF_Dimension dim, + FT_Fixed scale, + FT_Pos delta ); +#endif + + FT_LOCAL( void ) + af_glyph_hints_done( AF_GlyphHints hints ); + +/* */ + +#define AF_SEGMENT_LEN( seg ) ( (seg)->max_coord - (seg)->min_coord ) + +#define AF_SEGMENT_DIST( seg1, seg2 ) ( ( (seg1)->pos > (seg2)->pos ) \ + ? (seg1)->pos - (seg2)->pos \ + : (seg2)->pos - (seg1)->pos ) + + +FT_END_HEADER + +#endif /* __AFHINTS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afindic.c b/drivers/freetype/src/autofit/afindic.c new file mode 100644 index 0000000000..8c24972598 --- /dev/null +++ b/drivers/freetype/src/autofit/afindic.c @@ -0,0 +1,157 @@ +/***************************************************************************/ +/* */ +/* afindic.c */ +/* */ +/* Auto-fitter hinting routines for Indic scripts (body). */ +/* */ +/* Copyright 2007, 2011-2013 by */ +/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ +/* */ +/* 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 "aftypes.h" +#include "aflatin.h" + + +#ifdef AF_CONFIG_OPTION_INDIC + +#include "afindic.h" +#include "aferrors.h" +#include "afcjk.h" + + +#ifdef AF_CONFIG_OPTION_USE_WARPER +#include "afwarp.h" +#endif + + + static FT_Error + af_indic_metrics_init( AF_CJKMetrics metrics, + FT_Face face ) + { + /* skip blue zone init in CJK routines */ + FT_CharMap oldmap = face->charmap; + + + metrics->units_per_em = face->units_per_EM; + + if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) + face->charmap = NULL; + else + { + af_cjk_metrics_init_widths( metrics, face ); +#if 0 + /* either need indic specific blue_chars[] or just skip blue zones */ + af_cjk_metrics_init_blues( metrics, face, af_cjk_blue_chars ); +#endif + af_cjk_metrics_check_digits( metrics, face ); + } + + FT_Set_Charmap( face, oldmap ); + + return FT_Err_Ok; + } + + + static void + af_indic_metrics_scale( AF_CJKMetrics metrics, + AF_Scaler scaler ) + { + /* use CJK routines */ + af_cjk_metrics_scale( metrics, scaler ); + } + + + static FT_Error + af_indic_hints_init( AF_GlyphHints hints, + AF_CJKMetrics metrics ) + { + /* use CJK routines */ + return af_cjk_hints_init( hints, metrics ); + } + + + static FT_Error + af_indic_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_CJKMetrics metrics ) + { + /* use CJK routines */ + return af_cjk_hints_apply( hints, outline, metrics ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** I N D I C S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static const AF_Script_UniRangeRec af_indic_uniranges[] = + { +#if 0 + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ +#endif + AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ + AF_UNIRANGE_REC( 0x0F00UL, 0x0FFFUL), /* Tibetan */ + AF_UNIRANGE_REC( 0x1900UL, 0x194FUL), /* Limbu */ + AF_UNIRANGE_REC( 0x1B80UL, 0x1BBFUL), /* Sundanese */ + AF_UNIRANGE_REC( 0x1C80UL, 0x1CDFUL), /* Meetei Mayak */ + AF_UNIRANGE_REC( 0xA800UL, 0xA82FUL), /* Syloti Nagri */ + AF_UNIRANGE_REC( 0x11800UL, 0x118DFUL), /* Sharada */ + AF_UNIRANGE_REC( 0UL, 0UL) + }; + + + AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, + AF_SCRIPT_INDIC, + af_indic_uniranges, + 'o', /* XXX */ + + sizeof ( AF_CJKMetricsRec ), + + (AF_Script_InitMetricsFunc) af_indic_metrics_init, + (AF_Script_ScaleMetricsFunc)af_indic_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_indic_hints_init, + (AF_Script_ApplyHintsFunc) af_indic_hints_apply + ) + +#else /* !AF_CONFIG_OPTION_INDIC */ + + static const AF_Script_UniRangeRec af_indic_uniranges[] = + { + { 0, 0 } + }; + + + AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, + AF_SCRIPT_INDIC, + af_indic_uniranges, + 0, + + sizeof ( AF_CJKMetricsRec ), + + (AF_Script_InitMetricsFunc) NULL, + (AF_Script_ScaleMetricsFunc)NULL, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) NULL, + (AF_Script_ApplyHintsFunc) NULL + ) + +#endif /* !AF_CONFIG_OPTION_INDIC */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afindic.h b/drivers/freetype/src/autofit/afindic.h new file mode 100644 index 0000000000..c252cf20da --- /dev/null +++ b/drivers/freetype/src/autofit/afindic.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* afindic.h */ +/* */ +/* Auto-fitter hinting routines for Indic scripts (specification). */ +/* */ +/* Copyright 2007, 2012 by */ +/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ +/* */ +/* 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 __AFINDIC_H__ +#define __AFINDIC_H__ + +#include "afhints.h" + + +FT_BEGIN_HEADER + + + /* the Indic-specific script class */ + + AF_DECLARE_SCRIPT_CLASS( af_indic_script_class ) + + +/* */ + +FT_END_HEADER + +#endif /* __AFINDIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/aflatin.c b/drivers/freetype/src/autofit/aflatin.c new file mode 100644 index 0000000000..ef0157a13e --- /dev/null +++ b/drivers/freetype/src/autofit/aflatin.c @@ -0,0 +1,2486 @@ +/***************************************************************************/ +/* */ +/* aflatin.c */ +/* */ +/* Auto-fitter hinting routines for latin script (body). */ +/* */ +/* Copyright 2003-2013 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_ADVANCES_H +#include FT_INTERNAL_DEBUG_H + +#include "afglobal.h" +#include "aflatin.h" +#include "aferrors.h" + + +#ifdef AF_CONFIG_OPTION_USE_WARPER +#include "afwarp.h" +#endif + + + /*************************************************************************/ + /* */ + /* 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_aflatin + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* Find segments and links, compute all stem widths, and initialize */ + /* standard width and height for the glyph with given charcode. */ + + FT_LOCAL_DEF( void ) + af_latin_metrics_init_widths( AF_LatinMetrics metrics, + FT_Face face ) + { + /* scan the array of segments in each direction */ + AF_GlyphHintsRec hints[1]; + + + FT_TRACE5(( "standard widths computation\n" + "===========================\n\n" )); + + af_glyph_hints_init( hints, face->memory ); + + metrics->axis[AF_DIMENSION_HORZ].width_count = 0; + metrics->axis[AF_DIMENSION_VERT].width_count = 0; + + { + FT_Error error; + FT_UInt glyph_index; + int dim; + AF_LatinMetricsRec dummy[1]; + AF_Scaler scaler = &dummy->root.scaler; + + + glyph_index = FT_Get_Char_Index( face, + metrics->root.clazz->standard_char ); + if ( glyph_index == 0 ) + goto Exit; + + FT_TRACE5(( "standard character: 0x%X (glyph index %d)\n", + metrics->root.clazz->standard_char, glyph_index )); + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) + goto Exit; + + FT_ZERO( dummy ); + + dummy->units_per_em = metrics->units_per_em; + + scaler->x_scale = 0x10000L; + scaler->y_scale = 0x10000L; + scaler->x_delta = 0; + scaler->y_delta = 0; + + scaler->face = face; + scaler->render_mode = FT_RENDER_MODE_NORMAL; + scaler->flags = 0; + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + + error = af_glyph_hints_reload( hints, &face->glyph->outline ); + if ( error ) + goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = &metrics->axis[dim]; + AF_AxisHints axhints = &hints->axis[dim]; + AF_Segment seg, limit, link; + FT_UInt num_widths = 0; + + + error = af_latin_hints_compute_segments( hints, + (AF_Dimension)dim ); + if ( error ) + goto Exit; + + af_latin_hints_link_segments( hints, + (AF_Dimension)dim ); + + seg = axhints->segments; + limit = seg + axhints->num_segments; + + for ( ; seg < limit; seg++ ) + { + link = seg->link; + + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { + FT_Pos dist; + + + dist = seg->pos - link->pos; + if ( dist < 0 ) + dist = -dist; + + if ( num_widths < AF_LATIN_MAX_WIDTHS ) + axis->widths[num_widths++].org = dist; + } + } + + /* this also replaces multiple almost identical stem widths */ + /* with a single one (the value 100 is heuristic) */ + af_sort_and_quantize_widths( &num_widths, axis->widths, + dummy->units_per_em / 100 ); + axis->width_count = num_widths; + } + + Exit: + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = &metrics->axis[dim]; + FT_Pos stdw; + + + stdw = ( axis->width_count > 0 ) + ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); + + /* let's try 20% of the smallest width */ + axis->edge_distance_threshold = stdw / 5; + axis->standard_width = stdw; + axis->extra_light = 0; + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt i; + + + FT_TRACE5(( "%s widths:\n", + dim == AF_DIMENSION_VERT ? "horizontal" + : "vertical" )); + + FT_TRACE5(( " %d (standard)", axis->standard_width )); + for ( i = 1; i < axis->width_count; i++ ) + FT_TRACE5(( " %d", axis->widths[i].org )); + + FT_TRACE5(( "\n" )); + } +#endif + } + } + + FT_TRACE5(( "\n" )); + + af_glyph_hints_done( hints ); + } + + + +#define AF_LATIN_MAX_TEST_CHARACTERS 12 + + + static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] + [AF_LATIN_MAX_TEST_CHARACTERS + 1] = + { + "THEZOCQS", + "HEZLOCUS", + "fijkdbh", + "xzroesc", + "xzroesc", + "pqgjy" + }; + + + /* Find all blue zones. Flat segments give the reference points, */ + /* round segments the overshoot positions. */ + + static void + af_latin_metrics_init_blues( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Int num_flats; + FT_Int num_rounds; + FT_Int bb; + AF_LatinBlue blue; + FT_Error error; + AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; + FT_Outline outline; + + + /* we compute the blues simply by loading each character from the */ + /* `af_latin_blue_chars[blues]' string, then finding its top-most or */ + /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ + + FT_TRACE5(( "blue zones computation\n" + "======================\n\n" )); + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + const char* p = af_latin_blue_chars[bb]; + const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; + + + FT_TRACE5(( "blue zone %d:\n", bb )); + + num_flats = 0; + num_rounds = 0; + + for ( ; p < limit && *p; p++ ) + { + FT_UInt glyph_index; + FT_Pos best_y; /* same as points.y */ + FT_Int best_point, best_contour_first, best_contour_last; + FT_Vector* points; + FT_Bool round = 0; + + + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); + if ( glyph_index == 0 ) + continue; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + outline = face->glyph->outline; + if ( error || outline.n_points <= 0 ) + continue; + + /* now compute min or max point indices and coordinates */ + points = outline.points; + best_point = -1; + best_y = 0; /* make compiler happy */ + best_contour_first = 0; /* ditto */ + best_contour_last = 0; /* ditto */ + + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; + + + for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) + { + FT_Int old_best_point = best_point; + FT_Int pp; + + + last = outline.contours[nn]; + + /* Avoid single-point contours since they are never rasterized. */ + /* In some fonts, they correspond to mark attachment points */ + /* which are way outside of the glyph's real outline. */ + if ( last <= first ) + continue; + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + { + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y > best_y ) + { + best_point = pp; + best_y = points[pp].y; + } + } + else + { + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y < best_y ) + { + best_point = pp; + best_y = points[pp].y; + } + } + + if ( best_point != old_best_point ) + { + best_contour_first = first; + best_contour_last = last; + } + } + FT_TRACE5(( " %c %ld", *p, best_y )); + } + + /* now check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then inspect its previous and next points */ + if ( best_point >= 0 ) + { + FT_Pos best_x = points[best_point].x; + FT_Int prev, next; + FT_Int best_on_point_first, best_on_point_last; + FT_Pos dist; + + + if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) + { + best_on_point_first = best_point; + best_on_point_last = best_point; + } + else + { + best_on_point_first = -1; + best_on_point_last = -1; + } + + /* look for the previous and next points that are not on the */ + /* same Y coordinate, then threshold the `closeness'... */ + prev = best_point; + next = prev; + + do + { + if ( prev > best_contour_first ) + prev--; + else + prev = best_contour_last; + + dist = FT_ABS( points[prev].y - best_y ); + /* accept a small distance or a small angle (both values are */ + /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ + if ( dist > 5 ) + if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) + break; + + if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) + { + best_on_point_first = prev; + if ( best_on_point_last < 0 ) + best_on_point_last = prev; + } + + } while ( prev != best_point ); + + do + { + if ( next < best_contour_last ) + next++; + else + next = best_contour_first; + + dist = FT_ABS( points[next].y - best_y ); + if ( dist > 5 ) + if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) + break; + + if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) + { + best_on_point_last = next; + if ( best_on_point_first < 0 ) + best_on_point_first = next; + } + + } while ( next != best_point ); + + /* now set the `round' flag depending on the segment's kind */ + /* (value 8 is heuristic) */ + if ( best_on_point_first >= 0 && + best_on_point_last >= 0 && + (FT_UInt)( FT_ABS( points[best_on_point_last].x - + points[best_on_point_first].x ) ) > + metrics->units_per_em / 8 ) + round = 0; + else + round = FT_BOOL( + FT_CURVE_TAG( outline.tags[prev] ) != FT_CURVE_TAG_ON || + FT_CURVE_TAG( outline.tags[next] ) != FT_CURVE_TAG_ON ); + + FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); + } + + if ( round ) + rounds[num_rounds++] = best_y; + else + flats[num_flats++] = best_y; + } + + if ( num_flats == 0 && num_rounds == 0 ) + { + /* + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then + */ + FT_TRACE5(( " empty\n" )); + continue; + } + + /* we have computed the contents of the `rounds' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ + af_sort_pos( num_rounds, rounds ); + af_sort_pos( num_flats, flats ); + + blue = &axis->blues[axis->blue_count]; + blue_ref = &blue->ref.org; + blue_shoot = &blue->shoot.org; + + axis->blue_count++; + + if ( num_flats == 0 ) + { + *blue_ref = + *blue_shoot = rounds[num_rounds / 2]; + } + else if ( num_rounds == 0 ) + { + *blue_ref = + *blue_shoot = flats[num_flats / 2]; + } + else + { + *blue_ref = flats[num_flats / 2]; + *blue_shoot = rounds[num_rounds / 2]; + } + + /* there are sometimes problems: if the overshoot position of top */ + /* zones is under its reference position, or the opposite for bottom */ + /* zones. We must thus check everything there and correct the errors */ + if ( *blue_shoot != *blue_ref ) + { + FT_Pos ref = *blue_ref; + FT_Pos shoot = *blue_shoot; + FT_Bool over_ref = FT_BOOL( shoot > ref ); + + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) + { + *blue_ref = + *blue_shoot = ( shoot + ref ) / 2; + + FT_TRACE5(( " [overshoot smaller than reference," + " taking mean value]\n" )); + } + } + + blue->flags = 0; + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + blue->flags |= AF_LATIN_BLUE_TOP; + + /* + * The following flag is used later to adjust the y and x scales + * in order to optimize the pixel grid alignment of the top of small + * letters. + */ + if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; + + FT_TRACE5(( " -> reference = %ld\n" + " overshoot = %ld\n", + *blue_ref, *blue_shoot )); + } + + FT_TRACE5(( "\n" )); + + return; + } + + + /* Check whether all ASCII digits have the same advance width. */ + + FT_LOCAL_DEF( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; + + + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + + /* Initialize global metrics. */ + + FT_LOCAL_DEF( FT_Error ) + af_latin_metrics_init( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_CharMap oldmap = face->charmap; + + + metrics->units_per_em = face->units_per_EM; + + if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) + { + af_latin_metrics_init_widths( metrics, face ); + af_latin_metrics_init_blues( metrics, face ); + af_latin_metrics_check_digits( metrics, face ); + } + + FT_Set_Charmap( face, oldmap ); + return FT_Err_Ok; + } + + + /* Adjust scaling value, then scale and shift widths */ + /* and blue zones (if applicable) for given dimension. */ + + static void + af_latin_metrics_scale_dim( AF_LatinMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) + { + FT_Fixed scale; + FT_Pos delta; + AF_LatinAxis axis; + FT_UInt nn; + + + if ( dim == AF_DIMENSION_HORZ ) + { + scale = scaler->x_scale; + delta = scaler->x_delta; + } + else + { + scale = scaler->y_scale; + delta = scaler->y_delta; + } + + axis = &metrics->axis[dim]; + + if ( axis->org_scale == scale && axis->org_delta == delta ) + return; + + axis->org_scale = scale; + axis->org_delta = delta; + + /* + * correct X and Y scale to optimize the alignment of the top of small + * letters to the pixel grid + */ + { + AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT]; + AF_LatinBlue blue = NULL; + + + for ( nn = 0; nn < Axis->blue_count; nn++ ) + { + if ( Axis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) + { + blue = &Axis->blues[nn]; + break; + } + } + + if ( blue ) + { + FT_Pos scaled; + FT_Pos threshold; + FT_Pos fitted; + FT_UInt limit; + FT_UInt ppem; + + + scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); + ppem = metrics->root.scaler.face->size->metrics.x_ppem; + limit = metrics->root.globals->increase_x_height; + threshold = 40; + + /* if the `increase-x-height' property is active, */ + /* we round up much more often */ + if ( limit && + ppem <= limit && + ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN ) + threshold = 52; + + fitted = ( scaled + threshold ) & ~63; + + if ( scaled != fitted ) + { +#if 0 + if ( dim == AF_DIMENSION_HORZ ) + { + if ( fitted < scaled ) + scale -= scale / 50; /* scale *= 0.98 */ + } + else +#endif + if ( dim == AF_DIMENSION_VERT ) + scale = FT_MulDiv( scale, fitted, scaled ); + } + } + } + + axis->scale = scale; + axis->delta = delta; + + if ( dim == AF_DIMENSION_HORZ ) + { + metrics->root.scaler.x_scale = scale; + metrics->root.scaler.x_delta = delta; + } + else + { + metrics->root.scaler.y_scale = scale; + metrics->root.scaler.y_delta = delta; + } + + /* scale the widths */ + for ( nn = 0; nn < axis->width_count; nn++ ) + { + AF_Width width = axis->widths + nn; + + + width->cur = FT_MulFix( width->org, scale ); + width->fit = width->cur; + } + + /* an extra-light axis corresponds to a standard width that is */ + /* smaller than 5/8 pixels */ + axis->extra_light = + (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); + + if ( dim == AF_DIMENSION_VERT ) + { + /* scale the blue zones */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + FT_Pos dist; + + + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; + blue->ref.fit = blue->ref.cur; + blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; + blue->shoot.fit = blue->shoot.cur; + blue->flags &= ~AF_LATIN_BLUE_ACTIVE; + + /* a blue zone is only active if it is less than 3/4 pixels tall */ + dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); + if ( dist <= 48 && dist >= -48 ) + { +#if 0 + FT_Pos delta1; +#endif + FT_Pos delta2; + + + /* use discrete values for blue zone widths */ + +#if 0 + + /* generic, original code */ + delta1 = blue->shoot.org - blue->ref.org; + delta2 = delta1; + if ( delta1 < 0 ) + delta2 = -delta2; + + delta2 = FT_MulFix( delta2, scale ); + + if ( delta2 < 32 ) + delta2 = 0; + else if ( delta2 < 64 ) + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); + else + delta2 = FT_PIX_ROUND( delta2 ); + + if ( delta1 < 0 ) + delta2 = -delta2; + + blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); + blue->shoot.fit = blue->ref.fit + delta2; + +#else + + /* simplified version due to abs(dist) <= 48 */ + delta2 = dist; + if ( dist < 0 ) + delta2 = -delta2; + + if ( delta2 < 32 ) + delta2 = 0; + else if ( delta2 < 48 ) + delta2 = 32; + else + delta2 = 64; + + if ( dist < 0 ) + delta2 = -delta2; + + blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); + blue->shoot.fit = blue->ref.fit - delta2; + +#endif + + blue->flags |= AF_LATIN_BLUE_ACTIVE; + } + } + } + } + + + /* Scale global values in both directions. */ + + FT_LOCAL_DEF( void ) + af_latin_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ) + { + metrics->root.scaler.render_mode = scaler->render_mode; + metrics->root.scaler.face = scaler->face; + metrics->root.scaler.flags = scaler->flags; + + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* Walk over all contours and compute its segments. */ + + FT_LOCAL_DEF( FT_Error ) + af_latin_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Memory memory = hints->memory; + FT_Error error = FT_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; + + + FT_ZERO( &seg0 ); + seg0.score = 32000; + seg0.flags = AF_EDGE_NORMAL; + + major_dir = (AF_Direction)FT_ABS( axis->major_dir ); + segment_dir = major_dir; + + axis->num_segments = 0; + + /* set up (u,v) in each point */ + if ( dim == AF_DIMENSION_HORZ ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + + for ( ; point < limit; point++ ) + { + point->u = point->fx; + point->v = point->fy; + } + } + else + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + + for ( ; point < limit; point++ ) + { + point->u = point->fy; + point->v = point->fx; + } + } + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AF_Point point = contour[0]; + AF_Point last = point->prev; + int on_edge = 0; + FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */ + FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ + FT_Bool passed; + + + if ( point == last ) /* skip singletons -- just in case */ + continue; + + if ( FT_ABS( last->out_dir ) == major_dir && + FT_ABS( point->out_dir ) == major_dir ) + { + /* we are already on an edge, try to locate its start */ + last = point; + + for (;;) + { + point = point->prev; + if ( FT_ABS( point->out_dir ) != major_dir ) + { + point = point->next; + break; + } + if ( point == last ) + break; + } + } + + last = point; + passed = 0; + + for (;;) + { + FT_Pos u, v; + + + if ( on_edge ) + { + u = point->u; + if ( u < min_pos ) + min_pos = u; + if ( u > max_pos ) + max_pos = u; + + if ( point->out_dir != segment_dir || point == last ) + { + /* we are just leaving an edge; record a new segment! */ + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + + /* a segment is round if either its first or last point */ + /* is a control point */ + if ( ( segment->first->flags | point->flags ) & + AF_FLAG_CONTROL ) + segment->flags |= AF_EDGE_ROUND; + + /* compute segment size */ + min_pos = max_pos = point->v; + + v = segment->first->v; + if ( v < min_pos ) + min_pos = v; + if ( v > max_pos ) + max_pos = v; + + 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; + /* fall through */ + } + } + + /* now exit if we are at the start/end point */ + if ( point == last ) + { + if ( passed ) + break; + passed = 1; + } + + if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) + { + /* this is the start of a new segment! */ + segment_dir = (AF_Direction)point->out_dir; + + /* clear all segment fields */ + error = af_axis_hints_new_segment( axis, memory, &segment ); + if ( error ) + goto Exit; + + segment[0] = seg0; + segment->dir = (FT_Char)segment_dir; + min_pos = max_pos = point->u; + segment->first = point; + segment->last = point; + on_edge = 1; + } + + point = point->next; + } + + } /* contours */ + + + /* now slightly increase the height of segments if 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 ) ); + } + } + } + + Exit: + return error; + } + + + /* Link segments to form stems and serifs. */ + + FT_LOCAL_DEF( void ) + af_latin_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + FT_Pos len_threshold, len_score; + AF_Segment seg1, seg2; + + + len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); + if ( len_threshold == 0 ) + len_threshold = 1; + + len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); + + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + /* the fake segments are introduced to hint the metrics -- */ + /* we must never link them to anything */ + if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + continue; + + /* search for stems having opposite directions, */ + /* with seg1 to the `left' of seg2 */ + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + { + FT_Pos pos1 = seg1->pos; + FT_Pos pos2 = seg2->pos; + + + if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 ) + { + /* compute distance between the two segments */ + FT_Pos dist = pos2 - pos1; + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len, score; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + /* compute maximum coordinate difference of the two segments */ + len = max - min; + if ( len >= len_threshold ) + { + /* small coordinate differences cause a higher score, and */ + /* segments with a greater distance cause a higher score also */ + score = dist + len_score / len; + + /* and we search for the smallest score */ + /* of the sum of the two values */ + if ( score < seg1->score ) + { + seg1->score = score; + seg1->link = seg2; + } + + if ( score < seg2->score ) + { + seg2->score = score; + seg2->link = seg1; + } + } + } + } + } + + /* now compute the `serif' segments, cf. explanations in `afhints.h' */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; + + if ( seg2 ) + { + if ( seg2->link != seg1 ) + { + seg1->link = 0; + seg1->serif = seg2->link; + } + } + } + } + + + /* Link segments to edges, using feature analysis for selection. */ + + FT_LOCAL_DEF( FT_Error ) + af_latin_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Error error = FT_Err_Ok; + FT_Memory memory = hints->memory; + AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; + + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + +#if 0 + AF_Direction up_dir; +#endif + FT_Fixed scale; + FT_Pos edge_distance_threshold; + FT_Pos segment_length_threshold; + + + axis->num_edges = 0; + + scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + +#if 0 + up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP + : AF_DIR_RIGHT; +#endif + + /* + * We ignore all segments that are less than 1 pixel 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( 64, hints->y_scale ); + else + segment_length_threshold = 0; + + /*********************************************************************/ + /* */ + /* We begin by generating a sorted table of edges for the current */ + /* direction. To do so, we simply scan each segment and try to find */ + /* an edge in our table that corresponds to its position. */ + /* */ + /* If no edge is found, we create and insert a new edge in the */ + /* sorted table. Otherwise, we simply add the segment to the edge's */ + /* list which gets processed in the second step to compute the */ + /* edge's properties. */ + /* */ + /* Note that the table of edges is sorted along the segment/edge */ + /* position. */ + /* */ + /*********************************************************************/ + + /* assure that edge distance threshold is at most 0.25px */ + edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, + scale ); + if ( edge_distance_threshold > 64 / 4 ) + edge_distance_threshold = 64 / 4; + + edge_distance_threshold = FT_DivFix( edge_distance_threshold, + scale ); + + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = NULL; + FT_Int ee; + + + if ( seg->height < segment_length_threshold ) + continue; + + /* A special case for serif edges: If they are smaller than */ + /* 1.5 pixels we ignore them. */ + if ( seg->serif && + 2 * seg->height < 3 * segment_length_threshold ) + continue; + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold && edge->dir == seg->dir ) + { + found = edge; + break; + } + } + + if ( !found ) + { + AF_Edge edge; + + + /* insert a new edge in the list and */ + /* sort according to the position */ + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); + if ( error ) + goto Exit; + + /* add the segment to the new edge's list */ + FT_ZERO( edge ); + + edge->first = seg; + edge->last = seg; + edge->dir = seg->dir; + edge->fpos = seg->pos; + edge->opos = FT_MulFix( seg->pos, scale ); + edge->pos = edge->opos; + seg->edge_next = seg; + } + else + { + /* if an edge was found, simply add the segment to the edge's */ + /* list */ + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + + + /******************************************************************/ + /* */ + /* Good, we now compute each edge's properties according to the */ + /* segments found on its position. Basically, these are */ + /* */ + /* - the edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /******************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + + /* + * Note that removing this loop and setting the `edge' field of each + * segment directly in the code above slows down execution speed for + * some reasons on platforms like the Sun. + */ + { + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + + + for ( edge = edges; edge < edge_limit; edge++ ) + { + seg = edge->first; + if ( seg ) + do + { + seg->edge = edge; + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + + /* now compute each edge properties */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ +#if 0 + FT_Pos ups = 0; /* number of upwards segments */ + FT_Pos downs = 0; /* number of downwards segments */ +#endif + + + seg = edge->first; + + do + { + FT_Bool is_serif; + + + /* check for roundness of segment */ + if ( seg->flags & AF_EDGE_ROUND ) + is_round++; + else + is_straight++; + +#if 0 + /* check for segment direction */ + if ( seg->dir == up_dir ) + ups += seg->max_coord - seg->min_coord; + else + downs += seg->max_coord - seg->min_coord; +#endif + + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && + seg->serif->edge && + seg->serif->edge != edge ); + + if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) + { + AF_Edge edge2; + AF_Segment seg2; + + + edge2 = edge->link; + seg2 = seg->link; + + if ( is_serif ) + { + seg2 = seg->serif; + edge2 = edge->serif; + } + + if ( edge2 ) + { + FT_Pos edge_delta; + FT_Pos seg_delta; + + + edge_delta = edge->fpos - edge2->fpos; + if ( edge_delta < 0 ) + edge_delta = -edge_delta; + + seg_delta = seg->pos - seg2->pos; + if ( seg_delta < 0 ) + seg_delta = -seg_delta; + + if ( seg_delta < edge_delta ) + edge2 = seg2->edge; + } + else + edge2 = seg2->edge; + + if ( is_serif ) + { + edge->serif = edge2; + edge2->flags |= AF_EDGE_SERIF; + } + else + edge->link = edge2; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + + /* set the round/straight flags */ + edge->flags = AF_EDGE_NORMAL; + + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AF_EDGE_ROUND; + +#if 0 + /* set the edge's main direction */ + edge->dir = AF_DIR_NONE; + + if ( ups > downs ) + edge->dir = (FT_Char)up_dir; + + else if ( ups < downs ) + edge->dir = (FT_Char)-up_dir; + + else if ( ups == downs ) + edge->dir = 0; /* both up and down! */ +#endif + + /* get rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ + + if ( edge->serif && edge->link ) + edge->serif = 0; + } + } + + Exit: + return error; + } + + + /* Detect segments and edges for given dimension. */ + + FT_LOCAL_DEF( FT_Error ) + af_latin_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ) + { + FT_Error error; + + + error = af_latin_hints_compute_segments( hints, dim ); + if ( !error ) + { + af_latin_hints_link_segments( hints, dim ); + + error = af_latin_hints_compute_edges( hints, dim ); + } + + return error; + } + + + /* Compute all edges which lie within blue zones. */ + + FT_LOCAL_DEF( void ) + af_latin_hints_compute_blue_edges( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + AF_AxisHints axis = &hints->axis[AF_DIMENSION_VERT]; + AF_Edge edge = axis->edges; + AF_Edge edge_limit = edge + axis->num_edges; + AF_LatinAxis latin = &metrics->axis[AF_DIMENSION_VERT]; + FT_Fixed scale = latin->scale; + + + /* compute which blue zones are active, i.e. have their scaled */ + /* size < 3/4 pixels */ + + /* for each horizontal edge search the blue zone which is closest */ + for ( ; edge < edge_limit; edge++ ) + { + FT_UInt bb; + AF_Width best_blue = NULL; + FT_Pos best_dist; /* initial threshold */ + + + /* compute the initial threshold as a fraction of the EM size */ + /* (the value 40 is heuristic) */ + best_dist = FT_MulFix( metrics->units_per_em / 40, scale ); + + /* assure a minimum distance of 0.5px */ + if ( best_dist > 64 / 2 ) + best_dist = 64 / 2; + + for ( bb = 0; bb < latin->blue_count; bb++ ) + { + AF_LatinBlue blue = latin->blues + bb; + FT_Bool is_top_blue, is_major_dir; + + + /* skip inactive blue zones (i.e., those that are too large) */ + if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + /* if it is a top zone, check for right edges -- if it is a bottom */ + /* zone, check for left edges */ + /* */ + /* of course, that's for TrueType */ + is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); + is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + + /* if it is a top zone, the edge must be against the major */ + /* direction; if it is a bottom zone, it must be in the major */ + /* direction */ + if ( is_top_blue ^ is_major_dir ) + { + FT_Pos dist; + + + /* first of all, compare it to the reference position */ + dist = edge->fpos - blue->ref.org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = &blue->ref; + } + + /* now compare it to the overshoot position and check whether */ + /* the edge is rounded, and whether the edge is over the */ + /* reference position of a top zone, or under the reference */ + /* position of a bottom zone */ + if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) + { + FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); + + + if ( is_top_blue ^ is_under_ref ) + { + dist = edge->fpos - blue->shoot.org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = &blue->shoot; + } + } + } + } + } + + if ( best_blue ) + edge->blue_edge = best_blue; + } + } + + + /* Initalize hinting engine. */ + + static FT_Error + af_latin_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + FT_Render_Mode mode; + FT_UInt32 scaler_flags, other_flags; + FT_Face face = metrics->root.scaler.face; + + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + + /* + * correct x_scale and y_scale if needed, since they may have + * been modified by `af_latin_metrics_scale_dim' above + */ + hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; + hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; + hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; + hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; + + /* compute flags depending on render mode, etc. */ + mode = metrics->root.scaler.render_mode; + +#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ + if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) + metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; +#endif + + scaler_flags = hints->scaler_flags; + other_flags = 0; + + /* + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) + other_flags |= AF_LATIN_HINTS_HORZ_SNAP; + + /* + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* + * We adjust stems to full pixels only if we don't use the `light' mode. + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + other_flags |= AF_LATIN_HINTS_STEM_ADJUST; + + if ( mode == FT_RENDER_MODE_MONO ) + other_flags |= AF_LATIN_HINTS_MONO; + + /* + * In `light' hinting mode we disable horizontal hinting completely. + * We also do it if the face is italic. + */ + if ( mode == FT_RENDER_MODE_LIGHT || + ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) + scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; + + hints->scaler_flags = scaler_flags; + hints->other_flags = other_flags; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* Snap a given width in scaled coordinates to one of the */ + /* current standard widths. */ + + static FT_Pos + af_latin_snap_width( AF_Width widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = FT_PIX_ROUND( reference ); + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* Compute the snapped width of a given stem, ignoring very thin ones. */ + /* There is a lot of voodoo in this function; changing the hard-coded */ + /* parameters influence the whole hinting process. */ + + static FT_Pos + af_latin_compute_stem_width( AF_GlyphHints hints, + AF_Dimension dim, + FT_Pos width, + AF_Edge_Flags base_flags, + AF_Edge_Flags stem_flags ) + { + AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; + AF_LatinAxis axis = & metrics->axis[dim]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = ( dim == AF_DIMENSION_VERT ); + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || + axis->extra_light ) + return width; + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) + { + /* smooth hinting process: very lightly quantize the stem width */ + + /* leave the widths of serifs alone */ + if ( ( stem_flags & AF_EDGE_SERIF ) && + vertical && + ( dist < 3 * 64 ) ) + goto Done_Width; + + else if ( base_flags & AF_EDGE_ROUND ) + { + if ( dist < 80 ) + dist = 64; + } + else if ( dist < 56 ) + dist = 56; + + if ( axis->width_count > 0 ) + { + FT_Pos delta; + + + /* compare to standard width */ + delta = dist - axis->widths[0].cur; + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = axis->widths[0].cur; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + + if ( dist < 3 * 64 ) + { + delta = dist & 63; + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & ~63; + } + } + 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 ); + + if ( vertical ) + { + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + + if ( dist >= 64 ) + dist = ( dist + 16 ) & ~63; + else + dist = 64; + } + else + { + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & ~63; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + + if ( dist < 48 ) + 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_Pos 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; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } + + + /* Align one stem edge relative to the previous stem edge. */ + + static void + af_latin_align_linked_edge( AF_GlyphHints hints, + AF_Dimension dim, + AF_Edge base_edge, + AF_Edge stem_edge ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + + FT_Pos fitted_width = af_latin_compute_stem_width( + hints, dim, dist, + (AF_Edge_Flags)base_edge->flags, + (AF_Edge_Flags)stem_edge->flags ); + + + stem_edge->pos = base_edge->pos + fitted_width; + + FT_TRACE5(( " 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 )); + } + + + /* Shift the coordinates of the `serif' edge by the same amount */ + /* as the corresponding `base' edge has been moved already. */ + + static void + af_latin_align_serif_edge( AF_GlyphHints hints, + AF_Edge base, + AF_Edge serif ) + { + FT_UNUSED( hints ); + + serif->pos = base->pos + ( serif->opos - base->opos ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* The main grid-fitting routine. */ + + FT_LOCAL_DEF( void ) + af_latin_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + FT_PtrDist n_edges; + AF_Edge edge; + AF_Edge anchor = NULL; + FT_Int has_serifs = 0; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_UInt num_actions = 0; +#endif + + + FT_TRACE5(( "%s edge hinting\n", + dim == AF_DIMENSION_VERT ? "horizontal" : "vertical" )); + + /* we begin by aligning all stems relative to the blue zone */ + /* if needed -- that's only for horizontal edges */ + + if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Width blue; + AF_Edge edge1, edge2; /* these edges form the stem to check */ + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + blue = edge->blue_edge; + edge1 = NULL; + edge2 = edge->link; + + if ( blue ) + edge1 = edge; + + /* flip edges if the other stem is aligned to a blue zone */ + else if ( edge2 && edge2->blue_edge ) + { + blue = edge2->blue_edge; + edge1 = edge2; + edge2 = edge; + } + + if ( !edge1 ) + continue; + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !anchor ) + FT_TRACE5(( " BLUE_ANCHOR: edge %d (opos=%.2f) snapped to %.2f," + " was %.2f (anchor=edge %d)\n", + edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0, + edge1->pos / 64.0, edge - edges )); + else + FT_TRACE5(( " 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 )); + + num_actions++; +#endif + + edge1->pos = blue->fit; + edge1->flags |= AF_EDGE_DONE; + + if ( edge2 && !edge2->blue_edge ) + { + af_latin_align_linked_edge( hints, dim, edge1, edge2 ); + edge2->flags |= AF_EDGE_DONE; + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif + } + + if ( !anchor ) + anchor = edge; + } + } + + /* now we align all other stem edges, trying to maintain the */ + /* relative order of stems in the glyph */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + has_serifs++; + continue; + } + + /* now align the stem */ + + /* this should not happen, but it's better to be safe */ + if ( edge2->blue_edge ) + { + FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2-edges )); + + af_latin_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif + continue; + } + + if ( !anchor ) + { + /* if we reach this if clause, no stem has been aligned yet */ + + FT_Pos org_len, org_center, cur_len; + FT_Pos cur_pos1, error1, error2, u_off, d_off; + + + org_len = edge2->opos - edge->opos; + cur_len = af_latin_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + /* some voodoo to specially round edges for small stem widths; */ + /* the idea is to align the center of a stem, then shifting */ + /* the stem edges to suitable positions */ + if ( cur_len <= 64 ) + { + /* width <= 1px */ + u_off = 32; + d_off = 32; + } + else + { + /* 1px < width < 1.5px */ + u_off = 38; + d_off = 26; + } + + if ( cur_len < 96 ) + { + org_center = edge->opos + ( org_len >> 1 ); + cur_pos1 = FT_PIX_ROUND( org_center ); + + error1 = org_center - ( cur_pos1 - u_off ); + if ( error1 < 0 ) + error1 = -error1; + + error2 = org_center - ( cur_pos1 + d_off ); + if ( error2 < 0 ) + error2 = -error2; + + if ( error1 < error2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = edge->pos + cur_len; + } + else + edge->pos = FT_PIX_ROUND( edge->opos ); + + anchor = edge; + edge->flags |= AF_EDGE_DONE; + + FT_TRACE5(( " ANCHOR: edge %d (opos=%.2f) and %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 )); + + af_latin_align_linked_edge( hints, dim, edge, edge2 ); + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions += 2; +#endif + } + else + { + FT_Pos org_pos, org_len, org_center, cur_len; + FT_Pos cur_pos1, cur_pos2, delta1, delta2; + + + org_pos = anchor->pos + ( edge->opos - anchor->opos ); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + if ( edge2->flags & AF_EDGE_DONE ) + { + FT_TRACE5(( " ADJUST: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, edge->pos / 64.0, + ( edge2->pos - cur_len ) / 64.0 )); + + edge->pos = edge2->pos - cur_len; + } + + else if ( cur_len < 96 ) + { + FT_Pos u_off, d_off; + + + cur_pos1 = FT_PIX_ROUND( org_center ); + + if ( cur_len <= 64 ) + { + u_off = 32; + d_off = 32; + } + else + { + u_off = 38; + d_off = 26; + } + + delta1 = org_center - ( cur_pos1 - u_off ); + if ( delta1 < 0 ) + delta1 = -delta1; + + delta2 = org_center - ( cur_pos1 + d_off ); + if ( delta2 < 0 ) + delta2 = -delta2; + + if ( delta1 < delta2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = cur_pos1 + cur_len / 2; + + FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked 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 + { + org_pos = anchor->pos + ( edge->opos - anchor->opos ); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + cur_pos1 = FT_PIX_ROUND( org_pos ); + delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center; + if ( delta1 < 0 ) + delta1 = -delta1; + + cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; + delta2 = cur_pos2 + ( cur_len >> 1 ) - org_center; + if ( delta2 < 0 ) + delta2 = -delta2; + + edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; + edge2->pos = edge->pos + cur_len; + + FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked 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 )); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif + + edge->flags |= AF_EDGE_DONE; + edge2->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + + num_actions++; +#endif + + edge->pos = edge[-1].pos; + } + } + } + + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are with serifs. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + + n_edges = edge_limit - edges; + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) + { + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span, delta; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } + } + + if ( has_serifs || !anchor ) + { + /* + * now hint the remaining edges (serifs and single) in order + * to complete our processing + */ + 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 ); + FT_TRACE5(( " 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 ) + { + edge->pos = FT_PIX_ROUND( edge->opos ); + anchor = edge; + FT_TRACE5(( " SERIF_ANCHOR: edge %d (opos=%.2f)" + " snapped to %.2f\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); + } + else + { + 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 ) + { + if ( after->opos == before->opos ) + edge->pos = before->pos; + else + edge->pos = before->pos + + FT_MulDiv( edge->opos - before->opos, + after->pos - before->pos, + after->opos - before->opos ); + + FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to %.2f" + " from %d (opos=%.2f)\n", + edge - edges, edge->opos / 64.0, + edge->pos / 64.0, + before - edges, before->opos / 64.0 )); + } + else + { + edge->pos = anchor->pos + + ( ( edge->opos - anchor->opos + 16 ) & ~31 ); + FT_TRACE5(( " SERIF_LINK2: edge %d (opos=%.2f)" + " snapped to %.2f\n", + edge - edges, edge->opos / 64.0, edge->pos / 64.0 )); + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif + edge->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + + num_actions++; +#endif + edge->pos = edge[-1].pos; + } + + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + edge->pos > edge[1].pos ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 )); + + num_actions++; +#endif + + edge->pos = edge[1].pos; + } + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !num_actions ) + FT_TRACE5(( " (none)\n" )); + FT_TRACE5(( "\n" )); +#endif + } + + + /* Apply the complete hinting algorithm to a latin glyph. */ + + static FT_Error + af_latin_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + FT_Error error; + int dim; + + + error = af_glyph_hints_reload( hints, outline ); + if ( error ) + goto Exit; + + /* analyze glyph outline */ +#ifdef AF_CONFIG_OPTION_USE_WARPER + if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || + AF_HINTS_DO_HORIZONTAL( hints ) ) +#else + if ( AF_HINTS_DO_HORIZONTAL( hints ) ) +#endif + { + error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); + if ( error ) + goto Exit; + } + + if ( AF_HINTS_DO_VERTICAL( hints ) ) + { + error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + if ( error ) + goto Exit; + + af_latin_hints_compute_blue_edges( hints, metrics ); + } + + /* grid-fit the outline */ + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { +#ifdef AF_CONFIG_OPTION_USE_WARPER + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) + { + AF_WarperRec warper; + FT_Fixed scale; + FT_Pos delta; + + + af_warper_compute( &warper, hints, (AF_Dimension)dim, + &scale, &delta ); + af_glyph_hints_scale_dim( hints, (AF_Dimension)dim, + scale, delta ); + continue; + } +#endif + + if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || + ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) + { + af_latin_hint_edges( hints, (AF_Dimension)dim ); + af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); + } + } + af_glyph_hints_save( hints, outline ); + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* XXX: this should probably fine tuned to differentiate better between */ + /* scripts... */ + + static const AF_Script_UniRangeRec af_latin_uniranges[] = + { + AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ + AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ + AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ + AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ + AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ + AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ + AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ + AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ + AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ + AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ + AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */ + AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ + AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ + AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ + AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ + AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */ + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + + + AF_DEFINE_SCRIPT_CLASS( af_latin_script_class, + AF_SCRIPT_LATIN, + af_latin_uniranges, + 'o', + + sizeof ( AF_LatinMetricsRec ), + + (AF_Script_InitMetricsFunc) af_latin_metrics_init, + (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_latin_hints_init, + (AF_Script_ApplyHintsFunc) af_latin_hints_apply + ) + + +/* END */ diff --git a/drivers/freetype/src/autofit/aflatin.h b/drivers/freetype/src/autofit/aflatin.h new file mode 100644 index 0000000000..d9170b3dcc --- /dev/null +++ b/drivers/freetype/src/autofit/aflatin.h @@ -0,0 +1,202 @@ +/***************************************************************************/ +/* */ +/* aflatin.h */ +/* */ +/* Auto-fitter hinting routines for latin script (specification). */ +/* */ +/* Copyright 2003-2007, 2009, 2011-2012 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 __AFLATIN_H__ +#define __AFLATIN_H__ + +#include "afhints.h" + + +FT_BEGIN_HEADER + + + /* the latin-specific script class */ + + AF_DECLARE_SCRIPT_CLASS( af_latin_script_class ) + + + /* constants are given with units_per_em == 2048 in mind */ +#define AF_LATIN_CONSTANT( metrics, c ) \ + ( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* + * The following declarations could be embedded in the file `aflatin.c'; + * they have been made semi-public to allow alternate script hinters to + * re-use some of them. + */ + + + /* Latin (global) metrics management */ + + enum + { + AF_LATIN_BLUE_CAPITAL_TOP, + AF_LATIN_BLUE_CAPITAL_BOTTOM, + AF_LATIN_BLUE_SMALL_F_TOP, + AF_LATIN_BLUE_SMALL_TOP, + AF_LATIN_BLUE_SMALL_BOTTOM, + AF_LATIN_BLUE_SMALL_MINOR, + + AF_LATIN_BLUE_MAX + }; + + +#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \ + (b) == AF_LATIN_BLUE_SMALL_F_TOP || \ + (b) == AF_LATIN_BLUE_SMALL_TOP ) + +#define AF_LATIN_MAX_WIDTHS 16 +#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX + + + enum + { + AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */ + AF_LATIN_BLUE_TOP = 1 << 1, /* result of AF_LATIN_IS_TOP_BLUE */ + AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */ + /* optimization */ + AF_LATIN_BLUE_FLAG_MAX + }; + + + typedef struct AF_LatinBlueRec_ + { + AF_WidthRec ref; + AF_WidthRec shoot; + FT_UInt flags; + + } AF_LatinBlueRec, *AF_LatinBlue; + + + typedef struct AF_LatinAxisRec_ + { + FT_Fixed scale; + FT_Pos delta; + + FT_UInt width_count; /* number of used widths */ + AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]; /* widths array */ + FT_Pos edge_distance_threshold; /* used for creating edges */ + FT_Pos standard_width; /* the default stem thickness */ + FT_Bool extra_light; /* is standard width very light? */ + + /* ignored for horizontal metrics */ + FT_UInt blue_count; + AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX]; + + FT_Fixed org_scale; + FT_Pos org_delta; + + } AF_LatinAxisRec, *AF_LatinAxis; + + + typedef struct AF_LatinMetricsRec_ + { + AF_ScriptMetricsRec root; + FT_UInt units_per_em; + AF_LatinAxisRec axis[AF_DIMENSION_MAX]; + + } AF_LatinMetricsRec, *AF_LatinMetrics; + + + FT_LOCAL( FT_Error ) + af_latin_metrics_init( AF_LatinMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_latin_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ); + + FT_LOCAL( void ) + af_latin_metrics_init_widths( AF_LatinMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + enum + { + AF_LATIN_HINTS_HORZ_SNAP = 1 << 0, /* enable stem width snapping */ + AF_LATIN_HINTS_VERT_SNAP = 1 << 1, /* enable stem height snapping */ + AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, /* enable stem width/height */ + /* adjustment */ + AF_LATIN_HINTS_MONO = 1 << 3 /* indicate monochrome */ + /* rendering */ + }; + + +#define AF_LATIN_HINTS_DO_HORZ_SNAP( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP ) + +#define AF_LATIN_HINTS_DO_VERT_SNAP( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP ) + +#define AF_LATIN_HINTS_DO_STEM_ADJUST( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST ) + +#define AF_LATIN_HINTS_DO_MONO( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO ) + + + /* + * The next functions shouldn't normally be exported. However, other + * scripts might like to use these functions as-is. + */ + FT_LOCAL( FT_Error ) + af_latin_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_latin_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( FT_Error ) + af_latin_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( FT_Error ) + af_latin_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ); + +/* */ + +FT_END_HEADER + +#endif /* __AFLATIN_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/aflatin2.c b/drivers/freetype/src/autofit/aflatin2.c new file mode 100644 index 0000000000..b1e9658d5d --- /dev/null +++ b/drivers/freetype/src/autofit/aflatin2.c @@ -0,0 +1,2406 @@ +/***************************************************************************/ +/* */ +/* aflatin2.c */ +/* */ +/* Auto-fitter hinting routines for latin script (body). */ +/* */ +/* Copyright 2003-2013 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 FT_ADVANCES_H + +#include "afglobal.h" +#include "aflatin.h" +#include "aflatin2.h" +#include "aferrors.h" + + +#ifdef AF_CONFIG_OPTION_USE_WARPER +#include "afwarp.h" +#endif + + + /*************************************************************************/ + /* */ + /* 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_aflatin2 + + + FT_LOCAL_DEF( FT_Error ) + af_latin2_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL_DEF( void ) + af_latin2_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + af_latin2_metrics_init_widths( AF_LatinMetrics metrics, + FT_Face face ) + { + /* scan the array of segments in each direction */ + AF_GlyphHintsRec hints[1]; + + + af_glyph_hints_init( hints, face->memory ); + + metrics->axis[AF_DIMENSION_HORZ].width_count = 0; + metrics->axis[AF_DIMENSION_VERT].width_count = 0; + + { + FT_Error error; + FT_UInt glyph_index; + int dim; + AF_LatinMetricsRec dummy[1]; + AF_Scaler scaler = &dummy->root.scaler; + + + glyph_index = FT_Get_Char_Index( face, + metrics->root.clazz->standard_char ); + if ( glyph_index == 0 ) + goto Exit; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) + goto Exit; + + FT_ZERO( dummy ); + + dummy->units_per_em = metrics->units_per_em; + scaler->x_scale = scaler->y_scale = 0x10000L; + scaler->x_delta = scaler->y_delta = 0; + scaler->face = face; + scaler->render_mode = FT_RENDER_MODE_NORMAL; + scaler->flags = 0; + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + + error = af_glyph_hints_reload( hints, &face->glyph->outline ); + if ( error ) + goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = &metrics->axis[dim]; + AF_AxisHints axhints = &hints->axis[dim]; + AF_Segment seg, limit, link; + FT_UInt num_widths = 0; + + + error = af_latin2_hints_compute_segments( hints, + (AF_Dimension)dim ); + if ( error ) + goto Exit; + + af_latin2_hints_link_segments( hints, + (AF_Dimension)dim ); + + seg = axhints->segments; + limit = seg + axhints->num_segments; + + for ( ; seg < limit; seg++ ) + { + link = seg->link; + + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { + FT_Pos dist; + + + dist = seg->pos - link->pos; + if ( dist < 0 ) + dist = -dist; + + if ( num_widths < AF_LATIN_MAX_WIDTHS ) + axis->widths[num_widths++].org = dist; + } + } + + af_sort_widths( num_widths, axis->widths ); + axis->width_count = num_widths; + } + + Exit: + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = &metrics->axis[dim]; + FT_Pos stdw; + + + stdw = ( axis->width_count > 0 ) + ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); + + /* let's try 20% of the smallest width */ + axis->edge_distance_threshold = stdw / 5; + axis->standard_width = stdw; + axis->extra_light = 0; + } + } + + af_glyph_hints_done( hints ); + } + + + +#define AF_LATIN_MAX_TEST_CHARACTERS 12 + + + static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES] + [AF_LATIN_MAX_TEST_CHARACTERS+1] = + { + "THEZOCQS", + "HEZLOCUS", + "fijkdbh", + "xzroesc", + "xzroesc", + "pqgjy" + }; + + + static void + af_latin2_metrics_init_blues( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Int num_flats; + FT_Int num_rounds; + FT_Int bb; + AF_LatinBlue blue; + FT_Error error; + AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; + FT_GlyphSlot glyph = face->glyph; + + + /* we compute the blues simply by loading each character from the */ + /* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */ + /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ + + FT_TRACE5(( "blue zones computation\n" + "======================\n\n" )); + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + const char* p = af_latin2_blue_chars[bb]; + const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; + + + FT_TRACE5(( "blue zone %d:\n", bb )); + + num_flats = 0; + num_rounds = 0; + + for ( ; p < limit && *p; p++ ) + { + FT_UInt glyph_index; + FT_Int best_point, best_y, best_first, best_last; + FT_Vector* points; + FT_Bool round; + + + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); + if ( glyph_index == 0 ) + continue; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || glyph->outline.n_points <= 0 ) + continue; + + /* now compute min or max point indices and coordinates */ + points = glyph->outline.points; + best_point = -1; + best_y = 0; /* make compiler happy */ + best_first = 0; /* ditto */ + best_last = 0; /* ditto */ + + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; + + + for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ ) + { + FT_Int old_best_point = best_point; + FT_Int pp; + + + last = glyph->outline.contours[nn]; + + /* Avoid single-point contours since they are never rasterized. */ + /* In some fonts, they correspond to mark attachment points */ + /* which are way outside of the glyph's real outline. */ + if ( last == first ) + continue; + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + { + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y > best_y ) + { + best_point = pp; + best_y = points[pp].y; + } + } + else + { + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y < best_y ) + { + best_point = pp; + best_y = points[pp].y; + } + } + + if ( best_point != old_best_point ) + { + best_first = first; + best_last = last; + } + } + FT_TRACE5(( " %c %d", *p, best_y )); + } + + /* now check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then inspect its previous and next points */ + { + FT_Pos best_x = points[best_point].x; + FT_Int start, end, prev, next; + FT_Pos dist; + + + /* now look for the previous and next points that are not on the */ + /* same Y coordinate. Threshold the `closeness'... */ + start = end = best_point; + + do + { + prev = start - 1; + if ( prev < best_first ) + prev = best_last; + + dist = FT_ABS( points[prev].y - best_y ); + /* accept a small distance or a small angle (both values are */ + /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ + if ( dist > 5 ) + if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) + break; + + start = prev; + + } while ( start != best_point ); + + do + { + next = end + 1; + if ( next > best_last ) + next = best_first; + + dist = FT_ABS( points[next].y - best_y ); + if ( dist > 5 ) + if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) + break; + + end = next; + + } while ( end != best_point ); + + /* now, set the `round' flag depending on the segment's kind */ + round = FT_BOOL( + FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON || + FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON ); + + FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); + } + + if ( round ) + rounds[num_rounds++] = best_y; + else + flats[num_flats++] = best_y; + } + + if ( num_flats == 0 && num_rounds == 0 ) + { + /* + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then + */ + FT_TRACE5(( " empty\n" )); + continue; + } + + /* we have computed the contents of the `rounds' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ + af_sort_pos( num_rounds, rounds ); + af_sort_pos( num_flats, flats ); + + blue = & axis->blues[axis->blue_count]; + blue_ref = & blue->ref.org; + blue_shoot = & blue->shoot.org; + + axis->blue_count++; + + if ( num_flats == 0 ) + { + *blue_ref = + *blue_shoot = rounds[num_rounds / 2]; + } + else if ( num_rounds == 0 ) + { + *blue_ref = + *blue_shoot = flats[num_flats / 2]; + } + else + { + *blue_ref = flats[num_flats / 2]; + *blue_shoot = rounds[num_rounds / 2]; + } + + /* there are sometimes problems: if the overshoot position of top */ + /* zones is under its reference position, or the opposite for bottom */ + /* zones. We must thus check everything there and correct the errors */ + if ( *blue_shoot != *blue_ref ) + { + FT_Pos ref = *blue_ref; + FT_Pos shoot = *blue_shoot; + FT_Bool over_ref = FT_BOOL( shoot > ref ); + + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) + { + *blue_ref = + *blue_shoot = ( shoot + ref ) / 2; + + FT_TRACE5(( " [overshoot smaller than reference," + " taking mean value]\n" )); + } + } + + blue->flags = 0; + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + blue->flags |= AF_LATIN_BLUE_TOP; + + /* + * The following flags is used later to adjust the y and x scales + * in order to optimize the pixel grid alignment of the top of small + * letters. + */ + if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; + + FT_TRACE5(( " -> reference = %ld\n" + " overshoot = %ld\n", + *blue_ref, *blue_shoot )); + } + + return; + } + + + FT_LOCAL_DEF( void ) + af_latin2_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin2_metrics_init( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Error error = FT_Err_Ok; + FT_CharMap oldmap = face->charmap; + FT_UInt ee; + + static const FT_Encoding latin_encodings[] = + { + FT_ENCODING_UNICODE, + FT_ENCODING_APPLE_ROMAN, + FT_ENCODING_ADOBE_STANDARD, + FT_ENCODING_ADOBE_LATIN_1, + FT_ENCODING_NONE /* end of list */ + }; + + + metrics->units_per_em = face->units_per_EM; + + /* do we have a latin charmap in there? */ + for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ ) + { + error = FT_Select_Charmap( face, latin_encodings[ee] ); + if ( !error ) + break; + } + + if ( !error ) + { + af_latin2_metrics_init_widths( metrics, face ); + af_latin2_metrics_init_blues( metrics, face ); + af_latin2_metrics_check_digits( metrics, face ); + } + + FT_Set_Charmap( face, oldmap ); + return FT_Err_Ok; + } + + + static void + af_latin2_metrics_scale_dim( AF_LatinMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) + { + FT_Fixed scale; + FT_Pos delta; + AF_LatinAxis axis; + FT_UInt nn; + + + if ( dim == AF_DIMENSION_HORZ ) + { + scale = scaler->x_scale; + delta = scaler->x_delta; + } + else + { + scale = scaler->y_scale; + delta = scaler->y_delta; + } + + axis = &metrics->axis[dim]; + + if ( axis->org_scale == scale && axis->org_delta == delta ) + return; + + axis->org_scale = scale; + axis->org_delta = delta; + + /* + * correct Y scale to optimize the alignment of the top of small + * letters to the pixel grid + */ + if ( dim == AF_DIMENSION_VERT ) + { + AF_LatinAxis vaxis = &metrics->axis[AF_DIMENSION_VERT]; + AF_LatinBlue blue = NULL; + + + for ( nn = 0; nn < vaxis->blue_count; nn++ ) + { + if ( vaxis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) + { + blue = &vaxis->blues[nn]; + break; + } + } + + if ( blue ) + { + FT_Pos scaled; + FT_Pos threshold; + FT_Pos fitted; + FT_UInt limit; + FT_UInt ppem; + + + scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); + ppem = metrics->root.scaler.face->size->metrics.x_ppem; + limit = metrics->root.globals->increase_x_height; + threshold = 40; + + /* if the `increase-x-height' property is active, */ + /* we round up much more often */ + if ( limit && + ppem <= limit && + ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN ) + threshold = 52; + + fitted = ( scaled + threshold ) & ~63; + +#if 1 + if ( scaled != fitted ) + { + scale = FT_MulDiv( scale, fitted, scaled ); + FT_TRACE5(( "== scaled x-top = %.2g" + " fitted = %.2g, scaling = %.4g\n", + scaled / 64.0, fitted / 64.0, + ( fitted * 1.0 ) / scaled )); + } +#endif + } + } + + axis->scale = scale; + axis->delta = delta; + + if ( dim == AF_DIMENSION_HORZ ) + { + metrics->root.scaler.x_scale = scale; + metrics->root.scaler.x_delta = delta; + } + else + { + metrics->root.scaler.y_scale = scale; + metrics->root.scaler.y_delta = delta; + } + + /* scale the standard widths */ + for ( nn = 0; nn < axis->width_count; nn++ ) + { + AF_Width width = axis->widths + nn; + + + width->cur = FT_MulFix( width->org, scale ); + width->fit = width->cur; + } + + /* an extra-light axis corresponds to a standard width that is */ + /* smaller than 5/8 pixels */ + axis->extra_light = + (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); + + if ( dim == AF_DIMENSION_VERT ) + { + /* scale the blue zones */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + FT_Pos dist; + + + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; + blue->ref.fit = blue->ref.cur; + blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; + blue->shoot.fit = blue->shoot.cur; + blue->flags &= ~AF_LATIN_BLUE_ACTIVE; + + /* a blue zone is only active if it is less than 3/4 pixels tall */ + dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); + if ( dist <= 48 && dist >= -48 ) + { + FT_Pos delta1, delta2; + + delta1 = blue->shoot.org - blue->ref.org; + delta2 = delta1; + if ( delta1 < 0 ) + delta2 = -delta2; + + delta2 = FT_MulFix( delta2, scale ); + + if ( delta2 < 32 ) + delta2 = 0; + else if ( delta2 < 64 ) + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); + else + delta2 = FT_PIX_ROUND( delta2 ); + + if ( delta1 < 0 ) + delta2 = -delta2; + + blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); + blue->shoot.fit = blue->ref.fit + delta2; + + FT_TRACE5(( ">> activating blue zone %d:" + " ref.cur=%.2g ref.fit=%.2g" + " shoot.cur=%.2g shoot.fit=%.2g\n", + nn, blue->ref.cur / 64.0, blue->ref.fit / 64.0, + blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); + + blue->flags |= AF_LATIN_BLUE_ACTIVE; + } + } + } + } + + + FT_LOCAL_DEF( void ) + af_latin2_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ) + { + metrics->root.scaler.render_mode = scaler->render_mode; + metrics->root.scaler.face = scaler->face; + metrics->root.scaler.flags = scaler->flags; + + af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define SORT_SEGMENTS + + FT_LOCAL_DEF( FT_Error ) + af_latin2_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Memory memory = hints->memory; + FT_Error error = FT_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; + + + FT_ZERO( &seg0 ); + seg0.score = 32000; + seg0.flags = AF_EDGE_NORMAL; + + major_dir = (AF_Direction)FT_ABS( axis->major_dir ); + segment_dir = major_dir; + + axis->num_segments = 0; + + /* set up (u,v) in each point */ + if ( dim == AF_DIMENSION_HORZ ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + + for ( ; point < limit; point++ ) + { + point->u = point->fx; + point->v = point->fy; + } + } + else + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + + for ( ; point < limit; point++ ) + { + point->u = point->fy; + point->v = point->fx; + } + } + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AF_Point point = contour[0]; + AF_Point start = point; + AF_Point last = point->prev; + + + if ( point == last ) /* skip singletons -- just in case */ + continue; + + /* already on an edge ?, backtrack to find its start */ + if ( FT_ABS( point->in_dir ) == major_dir ) + { + point = point->prev; + + while ( point->in_dir == start->in_dir ) + point = point->prev; + } + else /* otherwise, find first segment start, if any */ + { + while ( FT_ABS( point->out_dir ) != major_dir ) + { + point = point->next; + + if ( point == start ) + goto NextContour; + } + } + + start = point; + + for (;;) + { + AF_Point first; + FT_Pos min_u, min_v, max_u, max_v; + + /* we're at the start of a new segment */ + FT_ASSERT( FT_ABS( point->out_dir ) == major_dir && + point->in_dir != point->out_dir ); + first = point; + + min_u = max_u = point->u; + min_v = max_v = point->v; + + point = point->next; + + while ( point->out_dir == first->out_dir ) + { + point = point->next; + + if ( point->u < min_u ) + min_u = point->u; + + if ( point->u > max_u ) + max_u = point->u; + } + + if ( point->v < min_v ) + min_v = point->v; + + if ( point->v > max_v ) + max_v = point->v; + + /* record new segment */ + error = af_axis_hints_new_segment( axis, memory, &segment ); + if ( error ) + goto Exit; + + segment[0] = seg0; + segment->dir = first->out_dir; + segment->first = first; + segment->last = point; + segment->pos = (FT_Short)( ( min_u + max_u ) >> 1 ); + segment->min_coord = (FT_Short) min_v; + segment->max_coord = (FT_Short) max_v; + segment->height = (FT_Short)( max_v - min_v ); + + /* a segment is round if it doesn't have successive */ + /* on-curve points. */ + { + AF_Point pt = first; + AF_Point last = point; + AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); + AF_Flags f1; + + + segment->flags &= ~AF_EDGE_ROUND; + + for ( ; pt != last; f0 = f1 ) + { + pt = pt->next; + f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); + + if ( !f0 && !f1 ) + break; + + if ( pt == last ) + segment->flags |= AF_EDGE_ROUND; + } + } + + /* this can happen in the case of a degenerate contour + * e.g. a 2-point vertical contour + */ + if ( point == start ) + break; + + /* jump to the start of the next segment, if any */ + while ( FT_ABS( point->out_dir ) != major_dir ) + { + point = point->next; + + if ( point == start ) + goto NextContour; + } + } + + NextContour: + ; + } /* 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; + AF_Point p; + FT_Pos first_v = first->v; + FT_Pos last_v = last->v; + + + if ( first == last ) + continue; + + if ( first_v < last_v ) + { + 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 + { + 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_SORT_SEGMENTS + /* place all segments with a negative direction to the start + * of the array, used to speed up segment linking later... + */ + { + AF_Segment segments = axis->segments; + FT_UInt count = axis->num_segments; + FT_UInt ii, jj; + + for ( ii = 0; ii < count; ii++ ) + { + if ( segments[ii].dir > 0 ) + { + for ( jj = ii + 1; jj < count; jj++ ) + { + if ( segments[jj].dir < 0 ) + { + AF_SegmentRec tmp; + + + tmp = segments[ii]; + segments[ii] = segments[jj]; + segments[jj] = tmp; + + break; + } + } + + if ( jj == count ) + break; + } + } + axis->mid_segments = ii; + } +#endif + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + af_latin2_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; +#ifdef AF_SORT_SEGMENTS + AF_Segment segment_mid = segments + axis->mid_segments; +#endif + FT_Pos len_threshold, len_score; + AF_Segment seg1, seg2; + + + len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); + if ( len_threshold == 0 ) + len_threshold = 1; + + len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); + +#ifdef AF_SORT_SEGMENTS + for ( seg1 = segments; seg1 < segment_mid; seg1++ ) + { + if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + continue; + + for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ ) +#else + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + /* the fake segments are introduced to hint the metrics -- */ + /* we must never link them to anything */ + if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos ) +#endif + { + FT_Pos pos1 = seg1->pos; + FT_Pos pos2 = seg2->pos; + FT_Pos dist = pos2 - pos1; + + + if ( dist < 0 ) + continue; + + { + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len, score; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + len = max - min; + if ( len >= len_threshold ) + { + score = dist + len_score / len; + if ( score < seg1->score ) + { + seg1->score = score; + seg1->link = seg2; + } + + if ( score < seg2->score ) + { + seg2->score = score; + seg2->link = seg1; + } + } + } + } + } +#if 0 + } +#endif + + /* now, compute the `serif' segments */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; + + if ( seg2 ) + { + if ( seg2->link != seg1 ) + { + seg1->link = 0; + seg1->serif = seg2->link; + } + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin2_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Error error = FT_Err_Ok; + FT_Memory memory = hints->memory; + AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; + + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + + AF_Direction up_dir; + FT_Fixed scale; + FT_Pos edge_distance_threshold; + FT_Pos segment_length_threshold; + + + axis->num_edges = 0; + + scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + + up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP + : AF_DIR_RIGHT; + + /* + * We want to ignore very small (mostly serif) segments, we do that + * by ignoring those that whose length is less than a given fraction + * of the standard width. If there is no standard width, we ignore + * those that are less than a given size in pixels + * + * also, unlink serif segments that are linked to segments farther + * than 50% of the standard width + */ + if ( dim == AF_DIMENSION_HORZ ) + { + if ( laxis->width_count > 0 ) + segment_length_threshold = ( laxis->standard_width * 10 ) >> 4; + else + segment_length_threshold = FT_DivFix( 64, hints->y_scale ); + } + else + segment_length_threshold = 0; + + /*********************************************************************/ + /* */ + /* We will begin by generating a sorted table of edges for the */ + /* current direction. To do so, we simply scan each segment and try */ + /* to find an edge in our table that corresponds to its position. */ + /* */ + /* If no edge is found, we create and insert a new edge in the */ + /* sorted table. Otherwise, we simply add the segment to the edge's */ + /* list which will be processed in the second step to compute the */ + /* edge's properties. */ + /* */ + /* Note that the edges table is sorted along the segment/edge */ + /* position. */ + /* */ + /*********************************************************************/ + + edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, + scale ); + if ( edge_distance_threshold > 64 / 4 ) + edge_distance_threshold = 64 / 4; + + edge_distance_threshold = FT_DivFix( edge_distance_threshold, + scale ); + + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = 0; + FT_Int ee; + + + if ( seg->height < segment_length_threshold ) + continue; + + /* A special case for serif edges: If they are smaller than */ + /* 1.5 pixels we ignore them. */ + if ( seg->serif ) + { + FT_Pos dist = seg->serif->pos - seg->pos; + + + if ( dist < 0 ) + dist = -dist; + + if ( dist >= laxis->standard_width >> 1 ) + { + /* unlink this serif, it is too distant from its reference stem */ + seg->serif = NULL; + } + else if ( 2*seg->height < 3 * segment_length_threshold ) + continue; + } + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold && edge->dir == seg->dir ) + { + found = edge; + break; + } + } + + if ( !found ) + { + AF_Edge edge; + + + /* insert a new edge in the list and */ + /* sort according to the position */ + error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, + memory, &edge ); + if ( error ) + goto Exit; + + /* add the segment to the new edge's list */ + FT_ZERO( edge ); + + edge->first = seg; + edge->last = seg; + edge->fpos = seg->pos; + edge->dir = seg->dir; + edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + seg->edge_next = seg; + } + else + { + /* if an edge was found, simply add the segment to the edge's */ + /* list */ + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + + + /*********************************************************************/ + /* */ + /* Good, we will now compute each edge's properties according to */ + /* segments found on its position. Basically, these are: */ + /* */ + /* - edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /*********************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + + /* + * Note that removing this loop and setting the `edge' field of each + * segment directly in the code above slows down execution speed for + * some reasons on platforms like the Sun. + */ + { + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + + + for ( edge = edges; edge < edge_limit; edge++ ) + { + seg = edge->first; + if ( seg ) + do + { + seg->edge = edge; + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + + /* now, compute each edge properties */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ +#if 0 + FT_Pos ups = 0; /* number of upwards segments */ + FT_Pos downs = 0; /* number of downwards segments */ +#endif + + + seg = edge->first; + + do + { + FT_Bool is_serif; + + + /* check for roundness of segment */ + if ( seg->flags & AF_EDGE_ROUND ) + is_round++; + else + is_straight++; + +#if 0 + /* check for segment direction */ + if ( seg->dir == up_dir ) + ups += seg->max_coord-seg->min_coord; + else + downs += seg->max_coord-seg->min_coord; +#endif + + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && + seg->serif->edge && + seg->serif->edge != edge ); + + if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) + { + AF_Edge edge2; + AF_Segment seg2; + + + edge2 = edge->link; + seg2 = seg->link; + + if ( is_serif ) + { + seg2 = seg->serif; + edge2 = edge->serif; + } + + if ( edge2 ) + { + FT_Pos edge_delta; + FT_Pos seg_delta; + + + edge_delta = edge->fpos - edge2->fpos; + if ( edge_delta < 0 ) + edge_delta = -edge_delta; + + seg_delta = seg->pos - seg2->pos; + if ( seg_delta < 0 ) + seg_delta = -seg_delta; + + if ( seg_delta < edge_delta ) + edge2 = seg2->edge; + } + else + edge2 = seg2->edge; + + if ( is_serif ) + { + edge->serif = edge2; + edge2->flags |= AF_EDGE_SERIF; + } + else + edge->link = edge2; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + + /* set the round/straight flags */ + edge->flags = AF_EDGE_NORMAL; + + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AF_EDGE_ROUND; + +#if 0 + /* set the edge's main direction */ + edge->dir = AF_DIR_NONE; + + if ( ups > downs ) + edge->dir = (FT_Char)up_dir; + + else if ( ups < downs ) + edge->dir = (FT_Char)-up_dir; + + else if ( ups == downs ) + edge->dir = 0; /* both up and down! */ +#endif + + /* gets rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ + + if ( edge->serif && edge->link ) + edge->serif = 0; + } + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin2_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ) + { + FT_Error error; + + + error = af_latin2_hints_compute_segments( hints, dim ); + if ( !error ) + { + af_latin2_hints_link_segments( hints, dim ); + + error = af_latin2_hints_compute_edges( hints, dim ); + } + return error; + } + + + FT_LOCAL_DEF( void ) + af_latin2_hints_compute_blue_edges( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + AF_AxisHints axis = &hints->axis[AF_DIMENSION_VERT]; + AF_Edge edge = axis->edges; + AF_Edge edge_limit = edge + axis->num_edges; + AF_LatinAxis latin = &metrics->axis[AF_DIMENSION_VERT]; + FT_Fixed scale = latin->scale; + FT_Pos best_dist0; /* initial threshold */ + + + /* compute the initial threshold as a fraction of the EM size */ + best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); + + if ( best_dist0 > 64 / 2 ) + best_dist0 = 64 / 2; + + /* compute which blue zones are active, i.e. have their scaled */ + /* size < 3/4 pixels */ + + /* for each horizontal edge search the blue zone which is closest */ + for ( ; edge < edge_limit; edge++ ) + { + FT_Int bb; + AF_Width best_blue = NULL; + FT_Pos best_dist = best_dist0; + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + AF_LatinBlue blue = latin->blues + bb; + FT_Bool is_top_blue, is_major_dir; + + + /* skip inactive blue zones (i.e., those that are too small) */ + if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + /* if it is a top zone, check for right edges -- if it is a bottom */ + /* zone, check for left edges */ + /* */ + /* of course, that's for TrueType */ + is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); + is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + + /* if it is a top zone, the edge must be against the major */ + /* direction; if it is a bottom zone, it must be in the major */ + /* direction */ + if ( is_top_blue ^ is_major_dir ) + { + FT_Pos dist; + AF_Width compare; + + + /* if it's a rounded edge, compare it to the overshoot position */ + /* if it's a flat edge, compare it to the reference position */ + if ( edge->flags & AF_EDGE_ROUND ) + compare = &blue->shoot; + else + compare = &blue->ref; + + dist = edge->fpos - compare->org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = compare; + } + +#if 0 + /* now, compare it to the overshoot position if the edge is */ + /* rounded, and if the edge is over the reference position of a */ + /* top zone, or under the reference position of a bottom zone */ + if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) + { + FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); + + + if ( is_top_blue ^ is_under_ref ) + { + blue = latin->blues + bb; + dist = edge->fpos - blue->shoot.org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = & blue->shoot; + } + } + } +#endif + } + } + + if ( best_blue ) + edge->blue_edge = best_blue; + } + } + + + static FT_Error + af_latin2_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + FT_Render_Mode mode; + FT_UInt32 scaler_flags, other_flags; + FT_Face face = metrics->root.scaler.face; + + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + + /* + * correct x_scale and y_scale if needed, since they may have + * been modified `af_latin2_metrics_scale_dim' above + */ + hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; + hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; + hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; + hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; + + /* compute flags depending on render mode, etc. */ + mode = metrics->root.scaler.render_mode; + +#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ + if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) + { + metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; + } +#endif + + scaler_flags = hints->scaler_flags; + other_flags = 0; + + /* + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) + other_flags |= AF_LATIN_HINTS_HORZ_SNAP; + + /* + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* + * We adjust stems to full pixels only if we don't use the `light' mode. + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + other_flags |= AF_LATIN_HINTS_STEM_ADJUST; + + if ( mode == FT_RENDER_MODE_MONO ) + other_flags |= AF_LATIN_HINTS_MONO; + + /* + * In `light' hinting mode we disable horizontal hinting completely. + * We also do it if the face is italic. + */ + if ( mode == FT_RENDER_MODE_LIGHT || + ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) + scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; + + hints->scaler_flags = scaler_flags; + hints->other_flags = other_flags; + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* snap a given width in scaled coordinates to one of the */ + /* current standard widths */ + + static FT_Pos + af_latin2_snap_width( AF_Width widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = FT_PIX_ROUND( reference ); + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* compute the snapped width of a given stem */ + + static FT_Pos + af_latin2_compute_stem_width( AF_GlyphHints hints, + AF_Dimension dim, + FT_Pos width, + AF_Edge_Flags base_flags, + AF_Edge_Flags stem_flags ) + { + AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; + AF_LatinAxis axis = & metrics->axis[dim]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = ( dim == AF_DIMENSION_VERT ); + + FT_UNUSED( base_flags ); + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || + axis->extra_light ) + return width; + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) + { + /* smooth hinting process: very lightly quantize the stem width */ + + /* leave the widths of serifs alone */ + + if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) + goto Done_Width; + +#if 0 + else if ( ( base_flags & AF_EDGE_ROUND ) ) + { + if ( dist < 80 ) + dist = 64; + } + else if ( dist < 56 ) + dist = 56; +#endif + if ( axis->width_count > 0 ) + { + FT_Pos delta; + + + /* compare to standard width */ + if ( axis->width_count > 0 ) + { + delta = dist - axis->widths[0].cur; + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = axis->widths[0].cur; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + } + + if ( dist < 3 * 64 ) + { + delta = dist & 63; + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & ~63; + } + } + else + { + /* strong hinting process: snap the stem width to integer pixels */ + FT_Pos org_dist = dist; + + + dist = af_latin2_snap_width( axis->widths, axis->width_count, dist ); + + if ( vertical ) + { + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + + if ( dist >= 64 ) + dist = ( dist + 16 ) & ~63; + else + dist = 64; + } + else + { + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & ~63; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + + if ( dist < 48 ) + 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; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } + + + /* align one stem edge relative to the previous stem edge */ + + static void + af_latin2_align_linked_edge( AF_GlyphHints hints, + AF_Dimension dim, + AF_Edge base_edge, + AF_Edge stem_edge ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + + FT_Pos fitted_width = af_latin2_compute_stem_width( + hints, dim, dist, + (AF_Edge_Flags)base_edge->flags, + (AF_Edge_Flags)stem_edge->flags ); + + + stem_edge->pos = base_edge->pos + fitted_width; + + FT_TRACE5(( "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 )); + } + + + static void + af_latin2_align_serif_edge( AF_GlyphHints hints, + AF_Edge base, + AF_Edge serif ) + { + FT_UNUSED( hints ); + + serif->pos = base->pos + ( serif->opos - base->opos ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( void ) + af_latin2_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + AF_Edge anchor = 0; + FT_Int has_serifs = 0; + FT_Pos anchor_drift = 0; + + + + FT_TRACE5(( "==== hinting %s edges =====\n", + dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); + + /* we begin by aligning all stems relative to the blue zone */ + /* if needed -- that's only for horizontal edges */ + + if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Width blue; + AF_Edge edge1, edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + blue = edge->blue_edge; + edge1 = NULL; + edge2 = edge->link; + + if ( blue ) + { + edge1 = edge; + } + else if ( edge2 && edge2->blue_edge ) + { + blue = edge2->blue_edge; + edge1 = edge2; + edge2 = edge; + } + + if ( !edge1 ) + continue; + + FT_TRACE5(( "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; + + if ( edge2 && !edge2->blue_edge ) + { + af_latin2_align_linked_edge( hints, dim, edge1, edge2 ); + edge2->flags |= AF_EDGE_DONE; + } + + if ( !anchor ) + { + anchor = edge; + + anchor_drift = ( anchor->pos - anchor->opos ); + if ( edge2 ) + anchor_drift = ( anchor_drift + + ( edge2->pos - edge2->opos ) ) >> 1; + } + } + } + + /* now we will align all stem edges, trying to maintain the */ + /* relative order of stems in the glyph */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + has_serifs++; + continue; + } + + /* now align the stem */ + + /* this should not happen, but it's better to be safe */ + if ( edge2->blue_edge ) + { + FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges )); + + af_latin2_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + continue; + } + + if ( !anchor ) + { + FT_Pos org_len, org_center, cur_len; + FT_Pos cur_pos1, error1, error2, u_off, d_off; + + + org_len = edge2->opos - edge->opos; + cur_len = af_latin2_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + if ( cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + if ( cur_len < 96 ) + { + org_center = edge->opos + ( org_len >> 1 ); + + cur_pos1 = FT_PIX_ROUND( org_center ); + + error1 = org_center - ( cur_pos1 - u_off ); + if ( error1 < 0 ) + error1 = -error1; + + error2 = org_center - ( cur_pos1 + d_off ); + if ( error2 < 0 ) + error2 = -error2; + + if ( error1 < error2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = edge->pos + cur_len; + } + else + edge->pos = FT_PIX_ROUND( edge->opos ); + + FT_TRACE5(( "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; + + af_latin2_align_linked_edge( hints, dim, edge, edge2 ); + + edge2->flags |= AF_EDGE_DONE; + + anchor_drift = ( ( anchor->pos - anchor->opos ) + + ( edge2->pos - edge2->opos ) ) >> 1; + + FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 )); + } + else + { + FT_Pos org_pos, org_len, org_center, cur_center, cur_len; + FT_Pos org_left, org_right; + + + org_pos = edge->opos + anchor_drift; + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin2_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + org_left = org_pos + ( ( org_len - cur_len ) >> 1 ); + org_right = org_pos + ( ( org_len + cur_len ) >> 1 ); + + FT_TRACE5(( "ALIGN: left=%.2f right=%.2f ", + org_left / 64.0, org_right / 64.0 )); + cur_center = org_center; + + if ( edge2->flags & AF_EDGE_DONE ) + { + FT_TRACE5(( "\n" )); + edge->pos = edge2->pos - cur_len; + } + else + { + /* we want to compare several displacement, and choose + * the one that increases fitness while minimizing + * distortion as well + */ + FT_Pos displacements[6], scores[6], org, fit, delta; + FT_UInt count = 0; + + /* note: don't even try to fit tiny stems */ + if ( cur_len < 32 ) + { + FT_TRACE5(( "tiny stem\n" )); + goto AlignStem; + } + + /* if the span is within a single pixel, don't touch it */ + if ( FT_PIX_FLOOR( org_left ) == FT_PIX_CEIL( org_right ) ) + { + FT_TRACE5(( "single pixel stem\n" )); + goto AlignStem; + } + + if ( cur_len <= 96 ) + { + /* we want to avoid the absolute worst case which is + * when the left and right edges of the span each represent + * about 50% of the gray. we'd better want to change this + * to 25/75%, since this is much more pleasant to the eye with + * very acceptable distortion + */ + FT_Pos frac_left = org_left & 63; + FT_Pos frac_right = org_right & 63; + + if ( frac_left >= 22 && frac_left <= 42 && + frac_right >= 22 && frac_right <= 42 ) + { + org = frac_left; + fit = ( org <= 32 ) ? 16 : 48; + delta = FT_ABS( fit - org ); + displacements[count] = fit - org; + scores[count++] = delta; + FT_TRACE5(( "dispA=%.2f (%d) ", ( fit - org ) / 64.0, delta )); + + org = frac_right; + fit = ( org <= 32 ) ? 16 : 48; + delta = FT_ABS( fit - org ); + displacements[count] = fit - org; + scores[count++] = delta; + FT_TRACE5(( "dispB=%.2f (%d) ", ( fit - org ) / 64.0, delta )); + } + } + + /* snapping the left edge to the grid */ + org = org_left; + fit = FT_PIX_ROUND( org ); + delta = FT_ABS( fit - org ); + displacements[count] = fit - org; + scores[count++] = delta; + FT_TRACE5(( "dispC=%.2f (%d) ", ( fit - org ) / 64.0, delta )); + + /* snapping the right edge to the grid */ + org = org_right; + fit = FT_PIX_ROUND( org ); + delta = FT_ABS( fit - org ); + displacements[count] = fit - org; + scores[count++] = delta; + FT_TRACE5(( "dispD=%.2f (%d) ", ( fit - org ) / 64.0, delta )); + + /* now find the best displacement */ + { + FT_Pos best_score = scores[0]; + FT_Pos best_disp = displacements[0]; + FT_UInt nn; + + for ( nn = 1; nn < count; nn++ ) + { + if ( scores[nn] < best_score ) + { + best_score = scores[nn]; + best_disp = displacements[nn]; + } + } + + cur_center = org_center + best_disp; + } + FT_TRACE5(( "\n" )); + } + + AlignStem: + edge->pos = cur_center - ( cur_len >> 1 ); + edge2->pos = edge->pos + cur_len; + + FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)" + " snapped to (%.2f) and (%.2f)," + " org_len=%.2f cur_len=%.2f\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0, + org_len / 64.0, cur_len / 64.0 )); + + edge->flags |= AF_EDGE_DONE; + edge2->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + { + FT_TRACE5(( "BOUND: %d (pos=%.2f) to (%.2f)\n", + edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + edge->pos = edge[-1].pos; + } + } + } + + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are with serifs. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + +#if 0 + { + FT_Int n_edges = edge_limit - edges; + + + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) + { + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span, delta; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } + } + } +#endif + + if ( has_serifs || !anchor ) + { + /* + * now hint the remaining edges (serifs and single) in order + * to complete our processing + */ + 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_latin2_align_serif_edge( hints, edge->serif, edge ); + FT_TRACE5(( "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 ) + { + FT_TRACE5(( "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 + { + 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 ) + { + if ( after->opos == before->opos ) + edge->pos = before->pos; + else + edge->pos = before->pos + + FT_MulDiv( edge->opos - before->opos, + after->pos - before->pos, + after->opos - before->opos ); + FT_TRACE5(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)" + " from %d (opos=%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0, + before - edges, before->opos / 64.0 )); + } + else + { + edge->pos = anchor->pos + + ( ( edge->opos - anchor->opos + 16 ) & ~31 ); + + FT_TRACE5(( "SERIF_LINK2: edge %d (opos=%.2f)" + " snapped to (%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); + } + } + + edge->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + edge->pos > edge[1].pos ) + edge->pos = edge[1].pos; + } + } + } + + + static FT_Error + af_latin2_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + FT_Error error; + int dim; + + + error = af_glyph_hints_reload( hints, outline ); + if ( error ) + goto Exit; + + /* analyze glyph outline */ +#ifdef AF_CONFIG_OPTION_USE_WARPER + if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || + AF_HINTS_DO_HORIZONTAL( hints ) ) +#else + if ( AF_HINTS_DO_HORIZONTAL( hints ) ) +#endif + { + error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ ); + if ( error ) + goto Exit; + } + + if ( AF_HINTS_DO_VERTICAL( hints ) ) + { + error = af_latin2_hints_detect_features( hints, AF_DIMENSION_VERT ); + if ( error ) + goto Exit; + + af_latin2_hints_compute_blue_edges( hints, metrics ); + } + + /* grid-fit the outline */ + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { +#ifdef AF_CONFIG_OPTION_USE_WARPER + if ( ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) ) + { + AF_WarperRec warper; + FT_Fixed scale; + FT_Pos delta; + + + af_warper_compute( &warper, hints, dim, &scale, &delta ); + af_glyph_hints_scale_dim( hints, dim, scale, delta ); + continue; + } +#endif + + if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || + ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) + { + af_latin2_hint_edges( hints, (AF_Dimension)dim ); + af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); + } + } + af_glyph_hints_save( hints, outline ); + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static const AF_Script_UniRangeRec af_latin2_uniranges[] = + { + AF_UNIRANGE_REC( 32UL, 127UL ), /* TODO: Add new Unicode ranges here! */ + AF_UNIRANGE_REC( 160UL, 255UL ), + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + + + AF_DEFINE_SCRIPT_CLASS( af_latin2_script_class, + AF_SCRIPT_LATIN2, + af_latin2_uniranges, + 'o', + + sizeof ( AF_LatinMetricsRec ), + + (AF_Script_InitMetricsFunc) af_latin2_metrics_init, + (AF_Script_ScaleMetricsFunc)af_latin2_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_latin2_hints_init, + (AF_Script_ApplyHintsFunc) af_latin2_hints_apply + ) + + +/* END */ diff --git a/drivers/freetype/src/autofit/aflatin2.h b/drivers/freetype/src/autofit/aflatin2.h new file mode 100644 index 0000000000..cbfa395522 --- /dev/null +++ b/drivers/freetype/src/autofit/aflatin2.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* aflatin2.h */ +/* */ +/* Auto-fitter hinting routines for latin script (specification). */ +/* */ +/* Copyright 2003-2007, 2012 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 __AFLATIN2_H__ +#define __AFLATIN2_H__ + +#include "afhints.h" + + +FT_BEGIN_HEADER + + + /* the latin-specific script class */ + + AF_DECLARE_SCRIPT_CLASS( af_latin2_script_class ) + +/* */ + +FT_END_HEADER + +#endif /* __AFLATIN_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afloader.c b/drivers/freetype/src/autofit/afloader.c new file mode 100644 index 0000000000..17a6fb7c3b --- /dev/null +++ b/drivers/freetype/src/autofit/afloader.c @@ -0,0 +1,561 @@ +/***************************************************************************/ +/* */ +/* afloader.c */ +/* */ +/* Auto-fitter glyph loading routines (body). */ +/* */ +/* Copyright 2003-2009, 2011-2013 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 "afglobal.h" +#include "afloader.h" +#include "afhints.h" +#include "aferrors.h" +#include "afmodule.h" + + + /* Initialize glyph loader. */ + + FT_LOCAL_DEF( FT_Error ) + af_loader_init( AF_Module module ) + { + AF_Loader loader = module->loader; + FT_Memory memory = module->root.library->memory; + + + FT_ZERO( loader ); + + af_glyph_hints_init( &loader->hints, memory ); +#ifdef FT_DEBUG_AUTOFIT + _af_debug_hints = &loader->hints; +#endif + return FT_GlyphLoader_New( memory, &loader->gloader ); + } + + + /* Reset glyph loader and compute globals if necessary. */ + + FT_LOCAL_DEF( FT_Error ) + af_loader_reset( AF_Module module, + FT_Face face ) + { + FT_Error error = FT_Err_Ok; + AF_Loader loader = module->loader; + + + loader->face = face; + loader->globals = (AF_FaceGlobals)face->autohint.data; + + FT_GlyphLoader_Rewind( loader->gloader ); + + if ( loader->globals == NULL ) + { + error = af_face_globals_new( face, &loader->globals, module ); + if ( !error ) + { + face->autohint.data = + (FT_Pointer)loader->globals; + face->autohint.finalizer = + (FT_Generic_Finalizer)af_face_globals_free; + } + } + + return error; + } + + + /* Finalize glyph loader. */ + + FT_LOCAL_DEF( void ) + af_loader_done( AF_Module module ) + { + AF_Loader loader = module->loader; + + + af_glyph_hints_done( &loader->hints ); + + loader->face = NULL; + loader->globals = NULL; + +#ifdef FT_DEBUG_AUTOFIT + _af_debug_hints = NULL; +#endif + FT_GlyphLoader_Done( loader->gloader ); + loader->gloader = NULL; + } + + + /* Load a single glyph component. This routine calls itself */ + /* recursively, if necessary, and does the main work of */ + /* `af_loader_load_glyph.' */ + + static FT_Error + af_loader_load_g( AF_Loader loader, + AF_Scaler scaler, + FT_UInt glyph_index, + FT_Int32 load_flags, + FT_UInt depth ) + { + FT_Error error; + FT_Face face = loader->face; + FT_GlyphLoader gloader = loader->gloader; + AF_ScriptMetrics metrics = loader->metrics; + AF_GlyphHints hints = &loader->hints; + FT_GlyphSlot slot = face->glyph; + FT_Slot_Internal internal = slot->internal; + FT_Int32 flags; + + + flags = load_flags | FT_LOAD_LINEAR_DESIGN; + error = FT_Load_Glyph( face, glyph_index, flags ); + if ( error ) + goto Exit; + + loader->transformed = internal->glyph_transformed; + if ( loader->transformed ) + { + FT_Matrix inverse; + + + loader->trans_matrix = internal->glyph_matrix; + loader->trans_delta = internal->glyph_delta; + + inverse = loader->trans_matrix; + FT_Matrix_Invert( &inverse ); + FT_Vector_Transform( &loader->trans_delta, &inverse ); + } + + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_OUTLINE: + /* translate the loaded glyph when an internal transform is needed */ + if ( loader->transformed ) + FT_Outline_Translate( &slot->outline, + loader->trans_delta.x, + loader->trans_delta.y ); + + /* copy the outline points in the loader's current */ + /* extra points which are used to keep original glyph coordinates */ + error = FT_GLYPHLOADER_CHECK_POINTS( gloader, + slot->outline.n_points + 4, + slot->outline.n_contours ); + if ( error ) + goto Exit; + + FT_ARRAY_COPY( gloader->current.outline.points, + slot->outline.points, + slot->outline.n_points ); + + FT_ARRAY_COPY( gloader->current.outline.contours, + slot->outline.contours, + slot->outline.n_contours ); + + FT_ARRAY_COPY( gloader->current.outline.tags, + slot->outline.tags, + slot->outline.n_points ); + + gloader->current.outline.n_points = slot->outline.n_points; + gloader->current.outline.n_contours = slot->outline.n_contours; + + /* compute original horizontal phantom points (and ignore */ + /* vertical ones) */ + loader->pp1.x = hints->x_delta; + loader->pp1.y = hints->y_delta; + loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, + hints->x_scale ) + hints->x_delta; + loader->pp2.y = hints->y_delta; + + /* be sure to check for spacing glyphs */ + if ( slot->outline.n_points == 0 ) + goto Hint_Metrics; + + /* now load the slot image into the auto-outline and run the */ + /* automatic hinting process */ + if ( metrics->clazz->script_hints_apply ) + metrics->clazz->script_hints_apply( hints, + &gloader->current.outline, + metrics ); + + /* we now need to adjust the metrics according to the change in */ + /* width/positioning that occurred during the hinting process */ + if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) + { + FT_Pos old_rsb, old_lsb, new_lsb; + FT_Pos pp1x_uh, pp2x_uh; + AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; + AF_Edge edge1 = axis->edges; /* leftmost edge */ + AF_Edge edge2 = edge1 + + axis->num_edges - 1; /* rightmost edge */ + + + if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) + { + old_rsb = loader->pp2.x - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; + + /* remember unhinted values to later account */ + /* for rounding errors */ + + pp1x_uh = new_lsb - old_lsb; + pp2x_uh = edge2->pos + old_rsb; + + /* prefer too much space over too little space */ + /* for very small sizes */ + + if ( old_lsb < 24 ) + pp1x_uh -= 8; + + if ( old_rsb < 24 ) + pp2x_uh += 8; + + loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); + loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); + + if ( loader->pp1.x >= new_lsb && old_lsb > 0 ) + loader->pp1.x -= 64; + + if ( loader->pp2.x <= edge2->pos && old_rsb > 0 ) + loader->pp2.x += 64; + + slot->lsb_delta = loader->pp1.x - pp1x_uh; + slot->rsb_delta = loader->pp2.x - pp2x_uh; + } + else + { + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + + + loader->pp1.x = FT_PIX_ROUND( pp1x ); + loader->pp2.x = FT_PIX_ROUND( pp2x ); + + slot->lsb_delta = loader->pp1.x - pp1x; + slot->rsb_delta = loader->pp2.x - pp2x; + } + } + else + { + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + + + loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); + loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); + + slot->lsb_delta = loader->pp1.x - pp1x; + slot->rsb_delta = loader->pp2.x - pp2x; + } + + /* good, we simply add the glyph to our loader's base */ + FT_GlyphLoader_Add( gloader ); + break; + + case FT_GLYPH_FORMAT_COMPOSITE: + { + FT_UInt nn, num_subglyphs = slot->num_subglyphs; + FT_UInt num_base_subgs, start_point; + FT_SubGlyph subglyph; + + + start_point = gloader->base.outline.n_points; + + /* first of all, copy the subglyph descriptors in the glyph loader */ + error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs ); + if ( error ) + goto Exit; + + FT_ARRAY_COPY( gloader->current.subglyphs, + slot->subglyphs, + num_subglyphs ); + + gloader->current.num_subglyphs = num_subglyphs; + num_base_subgs = gloader->base.num_subglyphs; + + /* now read each subglyph independently */ + for ( nn = 0; nn < num_subglyphs; nn++ ) + { + FT_Vector pp1, pp2; + FT_Pos x, y; + FT_UInt num_points, num_new_points, num_base_points; + + + /* gloader.current.subglyphs can change during glyph loading due */ + /* to re-allocation -- we must recompute the current subglyph on */ + /* each iteration */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + pp1 = loader->pp1; + pp2 = loader->pp2; + + num_base_points = gloader->base.outline.n_points; + + error = af_loader_load_g( loader, scaler, subglyph->index, + load_flags, depth + 1 ); + if ( error ) + goto Exit; + + /* recompute subglyph pointer */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) + { + pp1 = loader->pp1; + pp2 = loader->pp2; + } + else + { + loader->pp1 = pp1; + loader->pp2 = pp2; + } + + num_points = gloader->base.outline.n_points; + num_new_points = num_points - num_base_points; + + /* now perform the transformation required for this subglyph */ + + if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | + FT_SUBGLYPH_FLAG_XY_SCALE | + FT_SUBGLYPH_FLAG_2X2 ) ) + { + FT_Vector* cur = gloader->base.outline.points + + num_base_points; + FT_Vector* limit = cur + num_new_points; + + + for ( ; cur < limit; cur++ ) + FT_Vector_Transform( cur, &subglyph->transform ); + } + + /* apply offset */ + + if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) + { + FT_Int k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; + + + if ( start_point + k >= num_base_points || + l >= (FT_UInt)num_new_points ) + { + error = FT_THROW( Invalid_Composite ); + goto Exit; + } + + l += num_base_points; + + /* for now, only use the current point coordinates; */ + /* we eventually may consider another approach */ + p1 = gloader->base.outline.points + start_point + k; + p2 = gloader->base.outline.points + start_point + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; + } + else + { + x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; + y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; + + x = FT_PIX_ROUND( x ); + y = FT_PIX_ROUND( y ); + } + + { + FT_Outline dummy = gloader->base.outline; + + + dummy.points += num_base_points; + dummy.n_points = (short)num_new_points; + + FT_Outline_Translate( &dummy, x, y ); + } + } + } + break; + + default: + /* we don't support other formats (yet?) */ + error = FT_THROW( Unimplemented_Feature ); + } + + Hint_Metrics: + if ( depth == 0 ) + { + FT_BBox bbox; + FT_Vector vvector; + + + vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; + vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; + vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale ); + vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale ); + + /* transform the hinted outline if needed */ + if ( loader->transformed ) + { + FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); + FT_Vector_Transform( &vvector, &loader->trans_matrix ); + } +#if 1 + /* we must translate our final outline by -pp1.x and compute */ + /* the new metrics */ + if ( loader->pp1.x ) + FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); +#endif + FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); + + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); + + slot->metrics.width = bbox.xMax - bbox.xMin; + slot->metrics.height = bbox.yMax - bbox.yMin; + slot->metrics.horiBearingX = bbox.xMin; + slot->metrics.horiBearingY = bbox.yMax; + + slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x ); + slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); + + /* for mono-width fonts (like Andale, Courier, etc.) we need */ + /* to keep the original rounded advance width; ditto for */ + /* digits if all have the same advance width */ +#if 0 + if ( !FT_IS_FIXED_WIDTH( slot->face ) ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + else + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + x_scale ); +#else + if ( scaler->render_mode != FT_RENDER_MODE_LIGHT && + ( FT_IS_FIXED_WIDTH( slot->face ) || + ( af_face_globals_is_digit( loader->globals, glyph_index ) && + metrics->digits_have_same_width ) ) ) + { + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + metrics->scaler.x_scale ); + + /* Set delta values to 0. Otherwise code that uses them is */ + /* going to ruin the fixed advance width. */ + slot->lsb_delta = 0; + slot->rsb_delta = 0; + } + else + { + /* non-spacing glyphs must stay as-is */ + if ( slot->metrics.horiAdvance ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + } +#endif + + slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, + metrics->scaler.y_scale ); + + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); + slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); + + /* now copy outline into glyph slot */ + FT_GlyphLoader_Rewind( internal->loader ); + error = FT_GlyphLoader_CopyPoints( internal->loader, gloader ); + if ( error ) + goto Exit; + + /* reassign all outline fields except flags to protect them */ + slot->outline.n_contours = internal->loader->base.outline.n_contours; + slot->outline.n_points = internal->loader->base.outline.n_points; + slot->outline.points = internal->loader->base.outline.points; + slot->outline.tags = internal->loader->base.outline.tags; + slot->outline.contours = internal->loader->base.outline.contours; + + slot->format = FT_GLYPH_FORMAT_OUTLINE; + } + + Exit: + return error; + } + + + /* Load a glyph. */ + + FT_LOCAL_DEF( FT_Error ) + af_loader_load_glyph( AF_Module module, + FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags ) + { + FT_Error error; + FT_Size size = face->size; + AF_Loader loader = module->loader; + AF_ScalerRec scaler; + + + if ( !size ) + return FT_THROW( Invalid_Argument ); + + FT_ZERO( &scaler ); + + scaler.face = face; + scaler.x_scale = size->metrics.x_scale; + scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + scaler.y_scale = size->metrics.y_scale; + scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + + scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); + scaler.flags = 0; /* XXX: fix this */ + + error = af_loader_reset( module, face ); + if ( !error ) + { + AF_ScriptMetrics metrics; + FT_UInt options = 0; + + +#ifdef FT_OPTION_AUTOFIT2 + /* XXX: undocumented hook to activate the latin2 hinter */ + if ( load_flags & ( 1UL << 20 ) ) + options = 2; +#endif + + error = af_face_globals_get_metrics( loader->globals, gindex, + options, &metrics ); + if ( !error ) + { + loader->metrics = metrics; + + if ( metrics->clazz->script_metrics_scale ) + metrics->clazz->script_metrics_scale( metrics, &scaler ); + else + metrics->scaler = scaler; + + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; + load_flags &= ~FT_LOAD_RENDER; + + if ( metrics->clazz->script_hints_init ) + { + error = metrics->clazz->script_hints_init( &loader->hints, + metrics ); + if ( error ) + goto Exit; + } + + error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); + } + } + Exit: + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/autofit/afloader.h b/drivers/freetype/src/autofit/afloader.h new file mode 100644 index 0000000000..1f34d17cce --- /dev/null +++ b/drivers/freetype/src/autofit/afloader.h @@ -0,0 +1,85 @@ +/***************************************************************************/ +/* */ +/* afloader.h */ +/* */ +/* Auto-fitter glyph loading routines (specification). */ +/* */ +/* Copyright 2003-2005, 2011-2012 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 __AFLOADER_H__ +#define __AFLOADER_H__ + +#include "afhints.h" +#include "afglobal.h" + + +FT_BEGIN_HEADER + + typedef struct AF_ModuleRec_* AF_Module; + + /* + * The autofitter module's (global) data structure to communicate with + * actual fonts. If necessary, `local' data like the current face, the + * current face's auto-hint data, or the current glyph's parameters + * relevant to auto-hinting are `swapped in'. Cf. functions like + * `af_loader_reset' and `af_loader_load_g'. + */ + + typedef struct AF_LoaderRec_ + { + /* current face data */ + FT_Face face; + AF_FaceGlobals globals; + + /* current glyph data */ + FT_GlyphLoader gloader; + AF_GlyphHintsRec hints; + AF_ScriptMetrics metrics; + FT_Bool transformed; + FT_Matrix trans_matrix; + FT_Vector trans_delta; + FT_Vector pp1; + FT_Vector pp2; + /* we don't handle vertical phantom points */ + + } AF_LoaderRec, *AF_Loader; + + + FT_LOCAL( FT_Error ) + af_loader_init( AF_Module module ); + + + FT_LOCAL( FT_Error ) + af_loader_reset( AF_Module module, + FT_Face face ); + + + FT_LOCAL( void ) + af_loader_done( AF_Module module ); + + + FT_LOCAL( FT_Error ) + af_loader_load_glyph( AF_Module module, + FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags ); + +/* */ + + +FT_END_HEADER + +#endif /* __AFLOADER_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afmodule.c b/drivers/freetype/src/autofit/afmodule.c new file mode 100644 index 0000000000..b1bb5ee0ed --- /dev/null +++ b/drivers/freetype/src/autofit/afmodule.c @@ -0,0 +1,264 @@ +/***************************************************************************/ +/* */ +/* afmodule.c */ +/* */ +/* Auto-fitter module implementation (body). */ +/* */ +/* Copyright 2003-2006, 2009, 2011-2013 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 "afglobal.h" +#include "afmodule.h" +#include "afloader.h" +#include "aferrors.h" +#include "afpic.h" + +#ifdef FT_DEBUG_AUTOFIT + 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 +#include FT_INTERNAL_DEBUG_H +#include FT_AUTOHINTER_H +#include FT_SERVICE_PROPERTIES_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_afmodule + + + FT_Error + af_property_get_face_globals( FT_Face face, + AF_FaceGlobals* aglobals, + AF_Module module ) + { + FT_Error error = FT_Err_Ok; + AF_FaceGlobals globals; + + + if ( !face ) + return FT_THROW( Invalid_Argument ); + + globals = (AF_FaceGlobals)face->autohint.data; + if ( !globals ) + { + /* trigger computation of the global script data */ + /* in case it hasn't been done yet */ + error = af_face_globals_new( face, &globals, module ); + if ( !error ) + { + face->autohint.data = + (FT_Pointer)globals; + face->autohint.finalizer = + (FT_Generic_Finalizer)af_face_globals_free; + } + } + + if ( !error ) + *aglobals = globals; + + return error; + } + + + FT_Error + af_property_set( FT_Module ft_module, + const char* property_name, + const void* value ) + { + FT_Error error = FT_Err_Ok; + AF_Module module = (AF_Module)ft_module; + + + if ( !ft_strcmp( property_name, "fallback-script" ) ) + { + FT_UInt* fallback_script = (FT_UInt*)value; + + + module->fallback_script = *fallback_script; + + return error; + } + else if ( !ft_strcmp( property_name, "increase-x-height" ) ) + { + FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; + AF_FaceGlobals globals; + + + error = af_property_get_face_globals( prop->face, &globals, module ); + if ( !error ) + globals->increase_x_height = prop->limit; + + return error; + } + + FT_TRACE0(( "af_property_set: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + FT_Error + af_property_get( FT_Module ft_module, + const char* property_name, + void* value ) + { + FT_Error error = FT_Err_Ok; + AF_Module module = (AF_Module)ft_module; + FT_UInt fallback_script = module->fallback_script; + + + if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) + { + FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value; + AF_FaceGlobals globals; + + + error = af_property_get_face_globals( prop->face, &globals, module ); + if ( !error ) + prop->map = globals->glyph_scripts; + + return error; + } + else if ( !ft_strcmp( property_name, "fallback-script" ) ) + { + FT_UInt* val = (FT_UInt*)value; + + + *val = fallback_script; + + return error; + } + else if ( !ft_strcmp( property_name, "increase-x-height" ) ) + { + FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; + AF_FaceGlobals globals; + + + error = af_property_get_face_globals( prop->face, &globals, module ); + if ( !error ) + prop->limit = globals->increase_x_height; + + return error; + } + + + FT_TRACE0(( "af_property_get: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + FT_DEFINE_SERVICE_PROPERTIESREC( + af_service_properties, + (FT_Properties_SetFunc)af_property_set, + (FT_Properties_GetFunc)af_property_get ) + + + FT_DEFINE_SERVICEDESCREC1( + af_services, + FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) + + + FT_CALLBACK_DEF( FT_Module_Interface ) + af_get_interface( FT_Module module, + const char* module_interface ) + { + /* AF_SERVICES_GET derefers `library' in PIC mode */ +#ifdef FT_CONFIG_OPTION_PIC + FT_Library library; + + + if ( !module ) + return NULL; + library = module->library; + if ( !library ) + return NULL; +#else + FT_UNUSED( module ); +#endif + + return ft_service_list_lookup( AF_SERVICES_GET, module_interface ); + } + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_init( FT_Module ft_module ) /* AF_Module */ + { + AF_Module module = (AF_Module)ft_module; + + + module->fallback_script = AF_SCRIPT_FALLBACK; + + return af_loader_init( module ); + } + + + FT_CALLBACK_DEF( void ) + af_autofitter_done( FT_Module ft_module ) /* AF_Module */ + { + AF_Module module = (AF_Module)ft_module; + + + af_loader_done( module ); + } + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_load_glyph( AF_Module module, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_UNUSED( size ); + + return af_loader_load_glyph( module, slot->face, + glyph_index, load_flags ); + } + + + FT_DEFINE_AUTOHINTER_INTERFACE( + af_autofitter_interface, + NULL, /* reset_face */ + NULL, /* get_global_hints */ + NULL, /* done_global_hints */ + (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph ) /* load_glyph */ + + + FT_DEFINE_MODULE( + autofit_module_class, + + FT_MODULE_HINTER, + sizeof ( AF_ModuleRec ), + + "autofitter", + 0x10000L, /* version 1.0 of the autofitter */ + 0x20000L, /* requires FreeType 2.0 or above */ + + (const void*)&AF_INTERFACE_GET, + + (FT_Module_Constructor)af_autofitter_init, + (FT_Module_Destructor) af_autofitter_done, + (FT_Module_Requester) af_get_interface ) + + +/* END */ diff --git a/drivers/freetype/src/autofit/afmodule.h b/drivers/freetype/src/autofit/afmodule.h new file mode 100644 index 0000000000..c4e8f8f66a --- /dev/null +++ b/drivers/freetype/src/autofit/afmodule.h @@ -0,0 +1,58 @@ +/***************************************************************************/ +/* */ +/* afmodule.h */ +/* */ +/* Auto-fitter module implementation (specification). */ +/* */ +/* Copyright 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFMODULE_H__ +#define __AFMODULE_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_MODULE_H + +#include "afloader.h" + + +FT_BEGIN_HEADER + + + /* + * This is the `extended' FT_Module structure which holds the + * autofitter's global data. Right before hinting a glyph, the data + * specific to the glyph's face (blue zones, stem widths, etc.) are + * loaded into `loader' (see function `af_loader_reset'). + */ + + typedef struct AF_ModuleRec_ + { + FT_ModuleRec root; + + FT_UInt fallback_script; + + AF_LoaderRec loader[1]; + + } AF_ModuleRec; + + +FT_DECLARE_MODULE(autofit_module_class) + + +FT_END_HEADER + +#endif /* __AFMODULE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afpic.c b/drivers/freetype/src/autofit/afpic.c new file mode 100644 index 0000000000..45e1448c08 --- /dev/null +++ b/drivers/freetype/src/autofit/afpic.c @@ -0,0 +1,137 @@ +/***************************************************************************/ +/* */ +/* afpic.c */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009-2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "afpic.h" +#include "aferrors.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from afmodule.c */ + FT_Error + FT_Create_Class_af_services( FT_Library library, + FT_ServiceDescRec** output_class ); + + void + FT_Destroy_Class_af_services( FT_Library library, + FT_ServiceDescRec* clazz ); + + void + FT_Init_Class_af_service_properties( FT_Service_PropertiesRec* clazz ); + + void FT_Init_Class_af_autofitter_interface( + FT_Library library, + FT_AutoHinter_InterfaceRec* clazz ); + + + /* forward declaration of PIC init functions from script classes */ +#include "aflatin.h" +#ifdef FT_OPTION_AUTOFIT2 +#include "aflatin2.h" +#endif +#include "afcjk.h" +#include "afdummy.h" +#include "afindic.h" + + + void + autofit_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->autofit ) + { + AFModulePIC* container = (AFModulePIC*)pic_container->autofit; + + + if ( container->af_services ) + FT_Destroy_Class_af_services( library, + container->af_services ); + container->af_services = NULL; + + FT_FREE( container ); + pic_container->autofit = NULL; + } + } + + + FT_Error + autofit_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_UInt ss; + FT_Error error = FT_Err_Ok; + AFModulePIC* container = NULL; + FT_Memory memory = library->memory; + + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->autofit = container; + + /* initialize pointer table - */ + /* this is how the module usually expects this data */ + error = FT_Create_Class_af_services( library, + &container->af_services ); + if ( error ) + goto Exit; + + FT_Init_Class_af_service_properties( &container->af_service_properties ); + + for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) + { + container->af_script_classes[ss] = + &container->af_script_classes_rec[ss]; + } + container->af_script_classes[AF_SCRIPT_CLASSES_COUNT - 1] = NULL; + + /* add call to initialization function when you add new scripts */ + ss = 0; + FT_Init_Class_af_dummy_script_class( + &container->af_script_classes_rec[ss++] ); +#ifdef FT_OPTION_AUTOFIT2 + FT_Init_Class_af_latin2_script_class( + &container->af_script_classes_rec[ss++] ); +#endif + FT_Init_Class_af_latin_script_class( + &container->af_script_classes_rec[ss++] ); + FT_Init_Class_af_cjk_script_class( + &container->af_script_classes_rec[ss++] ); + FT_Init_Class_af_indic_script_class( + &container->af_script_classes_rec[ss++] ); + + FT_Init_Class_af_autofitter_interface( + library, &container->af_autofitter_interface ); + + Exit: + if ( error ) + autofit_module_class_pic_free( library ); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afpic.h b/drivers/freetype/src/autofit/afpic.h new file mode 100644 index 0000000000..0acf803894 --- /dev/null +++ b/drivers/freetype/src/autofit/afpic.h @@ -0,0 +1,96 @@ +/***************************************************************************/ +/* */ +/* afpic.h */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009, 2011-2012 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __AFPIC_H__ +#define __AFPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_SERVICES_GET af_services +#define AF_SERVICE_PROPERTIES_GET af_service_properties + +#define AF_SCRIPT_CLASSES_GET af_script_classes +#define AF_INTERFACE_GET af_autofitter_interface + +#else /* FT_CONFIG_OPTION_PIC */ + + /* some include files required for members of AFModulePIC */ +#include FT_SERVICE_PROPERTIES_H + +#include "aftypes.h" + + /* increase these when you add new scripts, */ + /* and update autofit_module_class_pic_init */ +#ifdef FT_OPTION_AUTOFIT2 +#define AF_SCRIPT_CLASSES_COUNT 6 +#else +#define AF_SCRIPT_CLASSES_COUNT 5 +#endif + +#define AF_SCRIPT_CLASSES_REC_COUNT ( AF_SCRIPT_CLASSES_COUNT - 1 ) + + + typedef struct AFModulePIC_ + { + FT_ServiceDescRec* af_services; + FT_Service_PropertiesRec af_service_properties; + + AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; + AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; + FT_AutoHinter_InterfaceRec af_autofitter_interface; + + } AFModulePIC; + + +#define GET_PIC( lib ) \ + ( (AFModulePIC*)((lib)->pic_container.autofit) ) + +#define AF_SERVICES_GET \ + ( GET_PIC( library )->af_services ) +#define AF_SERVICE_PROPERTIES_GET \ + ( GET_PIC( library )->af_service_properties ) + +#define AF_SCRIPT_CLASSES_GET \ + ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_script_classes ) +#define AF_INTERFACE_GET \ + ( GET_PIC( library )->af_autofitter_interface ) + + + /* see afpic.c for the implementation */ + void + autofit_module_class_pic_free( FT_Library library ); + + FT_Error + autofit_module_class_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __AFPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/aftypes.h b/drivers/freetype/src/autofit/aftypes.h new file mode 100644 index 0000000000..9acd7ad6d2 --- /dev/null +++ b/drivers/freetype/src/autofit/aftypes.h @@ -0,0 +1,378 @@ +/***************************************************************************/ +/* */ +/* aftypes.h */ +/* */ +/* Auto-fitter types (specification only). */ +/* */ +/* Copyright 2003-2009, 2011-2012 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. */ +/* */ +/***************************************************************************/ + + + /************************************************************************* + * + * The auto-fitter is a complete rewrite of the old auto-hinter. + * Its main feature is the ability to differentiate between different + * scripts in order to apply language-specific rules. + * + * The code has also been compartmentized into several entities that + * should make algorithmic experimentation easier than with the old + * code. + * + * Finally, we get rid of the Catharon license, since this code is + * released under the FreeType one. + * + *************************************************************************/ + + +#ifndef __AFTYPES_H__ +#define __AFTYPES_H__ + +#include <ft2build.h> + +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** D E B U G G I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#ifdef FT_DEBUG_AUTOFIT + +#include FT_CONFIG_STANDARD_LIBRARY_H + +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; + +#endif /* FT_DEBUG_AUTOFIT */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** U T I L I T Y S T U F F *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AF_WidthRec_ + { + FT_Pos org; /* original position/width in font units */ + FT_Pos cur; /* current/scaled position/width in device sub-pixels */ + FT_Pos fit; /* current/fitted position/width in device sub-pixels */ + + } AF_WidthRec, *AF_Width; + + + FT_LOCAL( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ); + + FT_LOCAL( void ) + af_sort_and_quantize_widths( FT_UInt* count, + AF_Width widths, + FT_Pos threshold ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** A N G L E T Y P E S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The auto-fitter doesn't need a very high angular accuracy; + * this allows us to speed up some computations considerably with a + * light Cordic algorithm (see afangles.c). + */ + + typedef FT_Int AF_Angle; + + +#define AF_ANGLE_PI 256 +#define AF_ANGLE_2PI ( AF_ANGLE_PI * 2 ) +#define AF_ANGLE_PI2 ( AF_ANGLE_PI / 2 ) +#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 ) + + +#if 0 + /* + * compute the angle of a given 2-D vector + */ + FT_LOCAL( AF_Angle ) + af_angle_atan( FT_Pos dx, + FT_Pos dy ); + + + /* + * compute `angle2 - angle1'; the result is always within + * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] + */ + FT_LOCAL( AF_Angle ) + af_angle_diff( AF_Angle angle1, + AF_Angle angle2 ); +#endif /* 0 */ + + +#define AF_ANGLE_DIFF( result, angle1, angle2 ) \ + FT_BEGIN_STMNT \ + 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; \ + \ + result = _delta; \ + FT_END_STMNT + + + /* opaque handle to glyph-specific hints -- see `afhints.h' for more + * details + */ + typedef struct AF_GlyphHintsRec_* AF_GlyphHints; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S C A L E R S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * A scaler models the target pixel device that will receive the + * auto-hinted glyph image. + */ + + typedef enum AF_ScalerFlags_ + { + AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ + AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ + AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */ + + } AF_ScalerFlags; + + + typedef struct AF_ScalerRec_ + { + FT_Face face; /* source font face */ + FT_Fixed x_scale; /* from font units to 1/64th device pixels */ + FT_Fixed y_scale; /* from font units to 1/64th device pixels */ + FT_Pos x_delta; /* in 1/64th device pixels */ + FT_Pos y_delta; /* in 1/64th device pixels */ + FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc. */ + FT_UInt32 flags; /* additional control flags, see above */ + + } AF_ScalerRec, *AF_Scaler; + + +#define AF_SCALER_EQUAL_SCALES( a, b ) \ + ( (a)->x_scale == (b)->x_scale && \ + (a)->y_scale == (b)->y_scale && \ + (a)->x_delta == (b)->x_delta && \ + (a)->y_delta == (b)->y_delta ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S C R I P T S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The list of known scripts. Each different script corresponds to the + * following information: + * + * - A set of Unicode ranges to test whether the face supports the + * script. + * + * - A specific global analyzer that will compute global metrics + * specific to the script. + * + * - A specific glyph analyzer that will compute segments and + * edges for each glyph covered by the script. + * + * - A specific grid-fitting algorithm that will distort the + * scaled glyph outline according to the results of the glyph + * analyzer. + * + * Note that a given analyzer and/or grid-fitting algorithm can be + * used by more than one script. + */ + + typedef enum AF_Script_ + { + AF_SCRIPT_DUMMY = 0, + AF_SCRIPT_LATIN = 1, + AF_SCRIPT_CJK = 2, + AF_SCRIPT_INDIC = 3, +#ifdef FT_OPTION_AUTOFIT2 + AF_SCRIPT_LATIN2 = 4, +#endif + + /* add new scripts here. Don't forget to update the list in */ + /* `afglobal.c'. */ + + AF_SCRIPT_MAX /* do not remove */ + + } AF_Script; + + + typedef struct AF_ScriptClassRec_ const* AF_ScriptClass; + typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; + + typedef struct AF_ScriptMetricsRec_ + { + AF_ScriptClass clazz; + AF_ScalerRec scaler; + FT_Bool digits_have_same_width; + + AF_FaceGlobals globals; /* to access properties */ + + } AF_ScriptMetricsRec, *AF_ScriptMetrics; + + + /* This function parses an FT_Face to compute global metrics for + * a specific script. + */ + typedef FT_Error + (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, + FT_Face face ); + + typedef void + (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics, + AF_Scaler scaler ); + + typedef void + (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics ); + + + typedef FT_Error + (*AF_Script_InitHintsFunc)( AF_GlyphHints hints, + AF_ScriptMetrics metrics ); + + typedef void + (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints, + FT_Outline* outline, + AF_ScriptMetrics metrics ); + + + typedef struct AF_Script_UniRangeRec_ + { + FT_UInt32 first; + FT_UInt32 last; + + } AF_Script_UniRangeRec; + +#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } + + typedef const AF_Script_UniRangeRec *AF_Script_UniRange; + + + typedef struct AF_ScriptClassRec_ + { + AF_Script script; + AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ + FT_UInt32 standard_char; /* for default width and height */ + + FT_Offset script_metrics_size; + AF_Script_InitMetricsFunc script_metrics_init; + AF_Script_ScaleMetricsFunc script_metrics_scale; + AF_Script_DoneMetricsFunc script_metrics_done; + + AF_Script_InitHintsFunc script_hints_init; + AF_Script_ApplyHintsFunc script_hints_apply; + + } AF_ScriptClassRec; + + + /* Declare and define vtables for classes */ +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ + FT_CALLBACK_TABLE const AF_ScriptClassRec \ + script_class; + +#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \ + m_size, \ + m_init, m_scale, m_done, h_init, h_apply ) \ + FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec script_class = \ + { \ + script_, \ + ranges, \ + def_char, \ + \ + m_size, \ + \ + m_init, \ + m_scale, \ + m_done, \ + \ + h_init, \ + h_apply \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ + FT_LOCAL( void ) \ + FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ); + +#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \ + m_size, \ + m_init, m_scale, m_done, h_init, h_apply ) \ + FT_LOCAL_DEF( void ) \ + FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \ + { \ + ac->script = script_; \ + ac->script_uni_ranges = ranges; \ + ac->default_char = def_char; \ + \ + ac->script_metrics_size = m_size; \ + \ + ac->script_metrics_init = m_init; \ + ac->script_metrics_scale = m_scale; \ + ac->script_metrics_done = m_done; \ + \ + ac->script_hints_init = h_init; \ + ac->script_hints_apply = h_apply; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* */ + +FT_END_HEADER + +#endif /* __AFTYPES_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afwarp.c b/drivers/freetype/src/autofit/afwarp.c new file mode 100644 index 0000000000..34a97ffc57 --- /dev/null +++ b/drivers/freetype/src/autofit/afwarp.c @@ -0,0 +1,374 @@ +/***************************************************************************/ +/* */ +/* afwarp.c */ +/* */ +/* Auto-fitter warping algorithm (body). */ +/* */ +/* Copyright 2006, 2007, 2011 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. */ +/* */ +/***************************************************************************/ + + + /* + * The idea of the warping code is to slightly scale and shift a glyph + * within a single dimension so that as much of its segments are aligned + * (more or less) on the grid. To find out the optimal scaling and + * shifting value, various parameter combinations are tried and scored. + */ + +#include "afwarp.h" + +#ifdef AF_CONFIG_OPTION_USE_WARPER + + /*************************************************************************/ + /* */ + /* 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_afwarp + + + /* The weights cover the range 0/64 - 63/64 of a pixel. Obviously, */ + /* values around a half pixel (which means exactly between two grid */ + /* lines) gets the worst weight. */ +#if 1 + static const AF_WarpScore + af_warper_weights[64] = + { + 35, 32, 30, 25, 20, 15, 12, 10, 5, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30, + + -30,-30,-20,-20,-10,-10, -8, -5, -2, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 5, 10, 12, 15, 20, 25, 30, 32, + }; +#else + static const AF_WarpScore + af_warper_weights[64] = + { + 30, 20, 10, 5, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, -2, -2, -5, -5,-10,-10,-15,-20, + + -20,-15,-15,-10,-10, -5, -5, -2, -2, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 5, 10, 20, + }; +#endif + + + /* Score segments for a given `scale' and `delta' in the range */ + /* `xx1' to `xx2', and store the best result in `warper'. If */ + /* the new best score is equal to the old one, prefer the */ + /* value with a smaller distortion (around `base_distort'). */ + + static void + af_warper_compute_line_best( AF_Warper warper, + FT_Fixed scale, + FT_Pos delta, + FT_Pos xx1, + FT_Pos xx2, + AF_WarpScore base_distort, + AF_Segment segments, + FT_UInt num_segments ) + { + FT_Int idx_min, idx_max, idx0; + FT_UInt nn; + AF_WarpScore scores[65]; + + + for ( nn = 0; nn < 65; nn++ ) + scores[nn] = 0; + + idx0 = xx1 - warper->t1; + + /* compute minimum and maximum indices */ + { + FT_Pos xx1min = warper->x1min; + FT_Pos xx1max = warper->x1max; + FT_Pos w = xx2 - xx1; + + + if ( xx1min + w < warper->x2min ) + xx1min = warper->x2min - w; + + xx1max = warper->x1max; + if ( xx1max + w > warper->x2max ) + xx1max = warper->x2max - w; + + idx_min = xx1min - warper->t1; + idx_max = xx1max - warper->t1; + + if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 ) + { + FT_TRACE5(( "invalid indices:\n" + " min=%d max=%d, xx1=%ld xx2=%ld,\n" + " x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n", + idx_min, idx_max, xx1, xx2, + warper->x1min, warper->x1max, + warper->x2min, warper->x2max )); + return; + } + } + + for ( nn = 0; nn < num_segments; nn++ ) + { + FT_Pos len = segments[nn].max_coord - segments[nn].min_coord; + FT_Pos y0 = FT_MulFix( segments[nn].pos, scale ) + delta; + FT_Pos y = y0 + ( idx_min - idx0 ); + FT_Int idx; + + + /* score the length of the segments for the given range */ + for ( idx = idx_min; idx <= idx_max; idx++, y++ ) + scores[idx] += af_warper_weights[y & 63] * len; + } + + /* find best score */ + { + FT_Int idx; + + + for ( idx = idx_min; idx <= idx_max; idx++ ) + { + AF_WarpScore score = scores[idx]; + AF_WarpScore distort = base_distort + ( idx - idx0 ); + + + if ( score > warper->best_score || + ( score == warper->best_score && + distort < warper->best_distort ) ) + { + warper->best_score = score; + warper->best_distort = distort; + warper->best_scale = scale; + warper->best_delta = delta + ( idx - idx0 ); + } + } + } + } + + + /* Compute optimal scaling and delta values for a given glyph and */ + /* dimension. */ + + FT_LOCAL_DEF( void ) + af_warper_compute( AF_Warper warper, + AF_GlyphHints hints, + AF_Dimension dim, + FT_Fixed *a_scale, + FT_Pos *a_delta ) + { + AF_AxisHints axis; + AF_Point points; + + FT_Fixed org_scale; + FT_Pos org_delta; + + FT_UInt nn, num_points, num_segments; + FT_Int X1, X2; + FT_Int w; + + AF_WarpScore base_distort; + AF_Segment segments; + + + /* get original scaling transformation */ + if ( dim == AF_DIMENSION_VERT ) + { + org_scale = hints->y_scale; + org_delta = hints->y_delta; + } + else + { + org_scale = hints->x_scale; + org_delta = hints->x_delta; + } + + warper->best_scale = org_scale; + warper->best_delta = org_delta; + warper->best_score = INT_MIN; + warper->best_distort = 0; + + axis = &hints->axis[dim]; + segments = axis->segments; + num_segments = axis->num_segments; + points = hints->points; + num_points = hints->num_points; + + *a_scale = org_scale; + *a_delta = org_delta; + + /* get X1 and X2, minimum and maximum in original coordinates */ + if ( num_segments < 1 ) + return; + +#if 1 + X1 = X2 = points[0].fx; + for ( nn = 1; nn < num_points; nn++ ) + { + FT_Int X = points[nn].fx; + + + if ( X < X1 ) + X1 = X; + if ( X > X2 ) + X2 = X; + } +#else + X1 = X2 = segments[0].pos; + for ( nn = 1; nn < num_segments; nn++ ) + { + FT_Int X = segments[nn].pos; + + + if ( X < X1 ) + X1 = X; + if ( X > X2 ) + X2 = X; + } +#endif + + if ( X1 >= X2 ) + return; + + warper->x1 = FT_MulFix( X1, org_scale ) + org_delta; + warper->x2 = FT_MulFix( X2, org_scale ) + org_delta; + + warper->t1 = AF_WARPER_FLOOR( warper->x1 ); + warper->t2 = AF_WARPER_CEIL( warper->x2 ); + + /* examine a half pixel wide range around the maximum coordinates */ + warper->x1min = warper->x1 & ~31; + warper->x1max = warper->x1min + 32; + warper->x2min = warper->x2 & ~31; + warper->x2max = warper->x2min + 32; + + if ( warper->x1max > warper->x2 ) + warper->x1max = warper->x2; + + if ( warper->x2min < warper->x1 ) + warper->x2min = warper->x1; + + warper->w0 = warper->x2 - warper->x1; + + if ( warper->w0 <= 64 ) + { + warper->x1max = warper->x1; + warper->x2min = warper->x2; + } + + /* examine (at most) a pixel wide range around the natural width */ + warper->wmin = warper->x2min - warper->x1max; + warper->wmax = warper->x2max - warper->x1min; + +#if 1 + /* some heuristics to reduce the number of widths to be examined */ + { + int margin = 16; + + + if ( warper->w0 <= 128 ) + { + margin = 8; + if ( warper->w0 <= 96 ) + margin = 4; + } + + if ( warper->wmin < warper->w0 - margin ) + warper->wmin = warper->w0 - margin; + + if ( warper->wmax > warper->w0 + margin ) + warper->wmax = warper->w0 + margin; + } + + if ( warper->wmin < warper->w0 * 3 / 4 ) + warper->wmin = warper->w0 * 3 / 4; + + if ( warper->wmax > warper->w0 * 5 / 4 ) + warper->wmax = warper->w0 * 5 / 4; +#else + /* no scaling, just translation */ + warper->wmin = warper->wmax = warper->w0; +#endif + + for ( w = warper->wmin; w <= warper->wmax; w++ ) + { + FT_Fixed new_scale; + FT_Pos new_delta; + FT_Pos xx1, xx2; + + + /* compute min and max positions for given width, */ + /* assuring that they stay within the coordinate ranges */ + xx1 = warper->x1; + xx2 = warper->x2; + if ( w >= warper->w0 ) + { + xx1 -= w - warper->w0; + if ( xx1 < warper->x1min ) + { + xx2 += warper->x1min - xx1; + xx1 = warper->x1min; + } + } + else + { + xx1 -= w - warper->w0; + if ( xx1 > warper->x1max ) + { + xx2 -= xx1 - warper->x1max; + xx1 = warper->x1max; + } + } + + if ( xx1 < warper->x1 ) + base_distort = warper->x1 - xx1; + else + base_distort = xx1 - warper->x1; + + if ( xx2 < warper->x2 ) + base_distort += warper->x2 - xx2; + else + base_distort += xx2 - warper->x2; + + /* give base distortion a greater weight while scoring */ + base_distort *= 10; + + new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 ); + new_delta = xx1 - FT_MulFix( X1, new_scale ); + + af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2, + base_distort, + segments, num_segments ); + } + + { + FT_Fixed best_scale = warper->best_scale; + FT_Pos best_delta = warper->best_delta; + + + hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale ) + + best_delta; + hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale ) + + best_delta; + + *a_scale = best_scale; + *a_delta = best_delta; + } + } + +#else /* !AF_CONFIG_OPTION_USE_WARPER */ + + /* ANSI C doesn't like empty source files */ + typedef int _af_warp_dummy; + +#endif /* !AF_CONFIG_OPTION_USE_WARPER */ + +/* END */ diff --git a/drivers/freetype/src/autofit/afwarp.h b/drivers/freetype/src/autofit/afwarp.h new file mode 100644 index 0000000000..7343fdd5ef --- /dev/null +++ b/drivers/freetype/src/autofit/afwarp.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* afwarp.h */ +/* */ +/* Auto-fitter warping algorithm (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 __AFWARP_H__ +#define __AFWARP_H__ + +#include "afhints.h" + +FT_BEGIN_HEADER + +#define AF_WARPER_SCALE + +#define AF_WARPER_FLOOR( x ) ( (x) & ~63 ) +#define AF_WARPER_CEIL( x ) AF_WARPER_FLOOR( (x) + 63 ) + + + typedef FT_Int32 AF_WarpScore; + + typedef struct AF_WarperRec_ + { + FT_Pos x1, x2; + FT_Pos t1, t2; + FT_Pos x1min, x1max; + FT_Pos x2min, x2max; + FT_Pos w0, wmin, wmax; + + FT_Fixed best_scale; + FT_Pos best_delta; + AF_WarpScore best_score; + AF_WarpScore best_distort; + + } AF_WarperRec, *AF_Warper; + + + FT_LOCAL( void ) + af_warper_compute( AF_Warper warper, + AF_GlyphHints hints, + AF_Dimension dim, + FT_Fixed *a_scale, + FT_Fixed *a_delta ); + + +FT_END_HEADER + + +#endif /* __AFWARP_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/autofit.c b/drivers/freetype/src/autofit/autofit.c new file mode 100644 index 0000000000..3883a0a706 --- /dev/null +++ b/drivers/freetype/src/autofit/autofit.c @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* autofit.c */ +/* */ +/* Auto-fitter module (body). */ +/* */ +/* Copyright 2003-2007, 2011 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT +#include <ft2build.h> +#include "afpic.c" +#include "afangles.c" +#include "afglobal.c" +#include "afhints.c" + +#include "afdummy.c" +#include "aflatin.c" +#ifdef FT_OPTION_AUTOFIT2 +#include "aflatin2.c" +#endif +#include "afcjk.c" +#include "afindic.c" + +#include "afloader.c" +#include "afmodule.c" + +#ifdef AF_CONFIG_OPTION_USE_WARPER +#include "afwarp.c" +#endif + +/* END */ diff --git a/drivers/freetype/src/autofit/module.mk b/drivers/freetype/src/autofit/module.mk new file mode 100644 index 0000000000..6ec60912ab --- /dev/null +++ b/drivers/freetype/src/autofit/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 auto-fitter module definition +# + + +# 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, 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. + + +FTMODULE_H_COMMANDS += AUTOFIT_MODULE + +define AUTOFIT_MODULE +$(OPEN_DRIVER) FT_Module_Class, autofit_module_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)autofit $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/autofit/rules.mk b/drivers/freetype/src/autofit/rules.mk new file mode 100644 index 0000000000..b76bb79ab4 --- /dev/null +++ b/drivers/freetype/src/autofit/rules.mk @@ -0,0 +1,79 @@ +# +# FreeType 2 auto-fitter module configuration rules +# + + +# Copyright 2003, 2004, 2005, 2006, 2007, 2011 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. + + +# AUTOF driver directory +# +AUTOF_DIR := $(SRC_DIR)/autofit + + +# compilation flags for the driver +# +AUTOF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR)) + + +# AUTOF driver sources (i.e., C files) +# +AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ + $(AUTOF_DIR)/afcjk.c \ + $(AUTOF_DIR)/afdummy.c \ + $(AUTOF_DIR)/afglobal.c \ + $(AUTOF_DIR)/afhints.c \ + $(AUTOF_DIR)/afindic.c \ + $(AUTOF_DIR)/aflatin.c \ + $(AUTOF_DIR)/afloader.c \ + $(AUTOF_DIR)/afmodule.c \ + $(AUTOF_DIR)/afpic.c \ + $(AUTOF_DIR)/afwarp.c + +# AUTOF driver headers +# +AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ + $(AUTOF_DIR)/aferrors.h \ + $(AUTOF_DIR)/aftypes.h + + +# AUTOF driver object(s) +# +# AUTOF_DRV_OBJ_M is used during `multi' builds. +# AUTOF_DRV_OBJ_S is used during `single' builds. +# +AUTOF_DRV_OBJ_M := $(AUTOF_DRV_SRC:$(AUTOF_DIR)/%.c=$(OBJ_DIR)/%.$O) +AUTOF_DRV_OBJ_S := $(OBJ_DIR)/autofit.$O + +# AUTOF driver source file for single build +# +AUTOF_DRV_SRC_S := $(AUTOF_DIR)/autofit.c + + +# AUTOF driver - single object +# +$(AUTOF_DRV_OBJ_S): $(AUTOF_DRV_SRC_S) $(AUTOF_DRV_SRC) \ + $(FREETYPE_H) $(AUTOF_DRV_H) + $(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(AUTOF_DRV_SRC_S)) + + +# AUTOF driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(AUTOF_DIR)/%.c $(FREETYPE_H) $(AUTOF_DRV_H) + $(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(AUTOF_DRV_OBJ_S) +DRV_OBJS_M += $(AUTOF_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/base/Jamfile b/drivers/freetype/src/base/Jamfile new file mode 100644 index 0000000000..832e8b8424 --- /dev/null +++ b/drivers/freetype/src/base/Jamfile @@ -0,0 +1,60 @@ +# FreeType 2 src/base Jamfile +# +# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) base ; + + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ftadvanc ftcalc ftdbgmem ftgloadr + ftobjs ftoutln ftrfork ftsnames + ftstream fttrigon ftutil + basepic ftpic + ; + } + else + { + _sources = ftbase ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# Add the optional/replaceable files. +# +{ + local _sources = bbox bdf bitmap debug gasp + glyph gxval init lcdfil mm + otval pfr stroke synth system + type1 winfnt xf86 patent + ; + + Library $(FT2_LIB) : ft$(_sources).c ; +} + +# Add Macintosh-specific file to the library when necessary. +# +if $(MAC) +{ + Library $(FT2_LIB) : ftmac.c ; +} +else if $(OS) = MACOSX +{ + if $(FT2_MULTI) + { + Library $(FT2_LIB) : ftmac.c ; + } +} + +# end of src/base Jamfile diff --git a/drivers/freetype/src/base/basepic.c b/drivers/freetype/src/base/basepic.c new file mode 100644 index 0000000000..0af770ebc2 --- /dev/null +++ b/drivers/freetype/src/base/basepic.c @@ -0,0 +1,108 @@ +/***************************************************************************/ +/* */ +/* basepic.c */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009, 2012 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftglyph.c */ + void + FT_Init_Class_ft_outline_glyph_class( FT_Glyph_Class* clazz ); + + void + FT_Init_Class_ft_bitmap_glyph_class( FT_Glyph_Class* clazz ); + +#ifdef FT_CONFIG_OPTION_MAC_FONTS + /* forward declaration of PIC init function from ftrfork.c */ + /* (not modularized) */ + void + FT_Init_Table_raccess_guess_table( ft_raccess_guess_rec* record ); +#endif + + /* forward declaration of PIC init functions from ftinit.c */ + FT_Error + ft_create_default_module_classes( FT_Library library ); + + void + ft_destroy_default_module_classes( FT_Library library ); + + + void + ft_base_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->base ) + { + /* destroy default module classes */ + /* (in case FT_Add_Default_Modules was used) */ + ft_destroy_default_module_classes( library ); + + FT_FREE( pic_container->base ); + pic_container->base = NULL; + } + } + + + FT_Error + ft_base_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + BasePIC* container = NULL; + FT_Memory memory = library->memory; + + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->base = container; + + /* initialize default modules list and pointers */ + error = ft_create_default_module_classes( library ); + if ( error ) + goto Exit; + + /* initialize pointer table - */ + /* this is how the module usually expects this data */ + FT_Init_Class_ft_outline_glyph_class( + &container->ft_outline_glyph_class ); + FT_Init_Class_ft_bitmap_glyph_class( + &container->ft_bitmap_glyph_class ); +#ifdef FT_CONFIG_OPTION_MAC_FONTS + FT_Init_Table_raccess_guess_table( + (ft_raccess_guess_rec*)&container->ft_raccess_guess_table ); +#endif + + Exit: + if ( error ) + ft_base_pic_free( library ); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/base/basepic.h b/drivers/freetype/src/base/basepic.h new file mode 100644 index 0000000000..329d7c8fd6 --- /dev/null +++ b/drivers/freetype/src/base/basepic.h @@ -0,0 +1,90 @@ +/***************************************************************************/ +/* */ +/* basepic.h */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __BASEPIC_H__ +#define __BASEPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class +#define FT_BITMAP_GLYPH_CLASS_GET &ft_bitmap_glyph_class +#define FT_DEFAULT_MODULES_GET ft_default_modules + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#define FT_RACCESS_GUESS_TABLE_GET ft_raccess_guess_table +#endif + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_GLYPH_H + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#include FT_INTERNAL_RFORK_H +#endif + + + typedef struct BasePIC_ + { + FT_Module_Class** default_module_classes; + FT_Glyph_Class ft_outline_glyph_class; + FT_Glyph_Class ft_bitmap_glyph_class; + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK + ft_raccess_guess_rec ft_raccess_guess_table[FT_RACCESS_N_RULES]; +#endif + + } BasePIC; + + +#define GET_PIC( lib ) ( (BasePIC*)( (lib)->pic_container.base ) ) + +#define FT_OUTLINE_GLYPH_CLASS_GET \ + ( &GET_PIC( library )->ft_outline_glyph_class ) +#define FT_BITMAP_GLYPH_CLASS_GET \ + ( &GET_PIC( library )->ft_bitmap_glyph_class ) +#define FT_DEFAULT_MODULES_GET \ + ( GET_PIC( library )->default_module_classes ) + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#define FT_RACCESS_GUESS_TABLE_GET \ + ( GET_PIC( library )->ft_raccess_guess_table ) +#endif + + + /* see basepic.c for the implementation */ + void + ft_base_pic_free( FT_Library library ); + + FT_Error + ft_base_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __BASEPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftadvanc.c b/drivers/freetype/src/base/ftadvanc.c new file mode 100644 index 0000000000..52078478df --- /dev/null +++ b/drivers/freetype/src/base/ftadvanc.c @@ -0,0 +1,162 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.c */ +/* */ +/* Quick computation of advance widths (body). */ +/* */ +/* Copyright 2008, 2009, 2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_ADVANCES_H +#include FT_INTERNAL_OBJECTS_H + + + static FT_Error + _ft_face_scale_advances( FT_Face face, + FT_Fixed* advances, + FT_UInt count, + FT_Int32 flags ) + { + FT_Fixed scale; + FT_UInt nn; + + + if ( flags & FT_LOAD_NO_SCALE ) + return FT_Err_Ok; + + if ( face->size == NULL ) + return FT_THROW( Invalid_Size_Handle ); + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + scale = face->size->metrics.y_scale; + else + scale = face->size->metrics.x_scale; + + /* this must be the same scaling as to get linear{Hori,Vert}Advance */ + /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */ + + for ( nn = 0; nn < count; nn++ ) + advances[nn] = FT_MulDiv( advances[nn], scale, 64 ); + + return FT_Err_Ok; + } + + + /* at the moment, we can perform fast advance retrieval only in */ + /* the following cases: */ + /* */ + /* - unscaled load */ + /* - unhinted load */ + /* - light-hinted load */ + +#define LOAD_ADVANCE_FAST_CHECK( flags ) \ + ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ + FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) + + + /* documentation is in ftadvanc.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 flags, + FT_Fixed *padvance ) + { + FT_Face_GetAdvancesFunc func; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( gindex >= (FT_UInt)face->num_glyphs ) + return FT_THROW( Invalid_Glyph_Index ); + + func = face->driver->clazz->get_advances; + if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + { + FT_Error error; + + + error = func( face, gindex, 1, flags, padvance ); + if ( !error ) + return _ft_face_scale_advances( face, padvance, 1, flags ); + + if ( FT_ERR_NEQ( error, Unimplemented_Feature ) ) + return error; + } + + return FT_Get_Advances( face, gindex, 1, flags, padvance ); + } + + + /* documentation is in ftadvanc.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed *padvances ) + { + FT_Face_GetAdvancesFunc func; + FT_UInt num, end, nn; + FT_Error error = FT_Err_Ok; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + num = (FT_UInt)face->num_glyphs; + end = start + count; + if ( start >= num || end < start || end > num ) + return FT_THROW( Invalid_Glyph_Index ); + + if ( count == 0 ) + return FT_Err_Ok; + + func = face->driver->clazz->get_advances; + if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + { + error = func( face, start, count, flags, padvances ); + if ( !error ) + return _ft_face_scale_advances( face, padvances, count, flags ); + + if ( FT_ERR_NEQ( error, Unimplemented_Feature ) ) + return error; + } + + error = FT_Err_Ok; + + if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) + return FT_THROW( Unimplemented_Feature ); + + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + for ( nn = 0; nn < count; nn++ ) + { + error = FT_Load_Glyph( face, start + nn, flags ); + if ( error ) + break; + + /* scale from 26.6 to 16.16 */ + padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) + ? face->glyph->advance.y << 10 + : face->glyph->advance.x << 10; + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftapi.c b/drivers/freetype/src/base/ftapi.c new file mode 100644 index 0000000000..8914d1f4e9 --- /dev/null +++ b/drivers/freetype/src/base/ftapi.c @@ -0,0 +1,121 @@ +/***************************************************************************/ +/* */ +/* ftapi.c */ +/* */ +/* The FreeType compatibility functions (body). */ +/* */ +/* Copyright 2002 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_LIST_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TABLES_H +#include FT_OUTLINE_H + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C O M P A T I B I L I T Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* backwards compatibility API */ + + FT_BASE_DEF( void ) + FT_New_Memory_Stream( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Stream stream ) + { + FT_UNUSED( library ); + + FT_Stream_OpenMemory( stream, base, size ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Seek_Stream( FT_Stream stream, + FT_ULong pos ) + { + return FT_Stream_Seek( stream, pos ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Skip_Stream( FT_Stream stream, + FT_Long distance ) + { + return FT_Stream_Skip( stream, distance ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Read_Stream( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_Read( stream, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Read_Stream_At( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_ReadAt( stream, pos, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Extract_Frame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ) + { + return FT_Stream_ExtractFrame( stream, count, pbytes ); + } + + + FT_BASE_DEF( void ) + FT_Release_Frame( FT_Stream stream, + 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 ) + FT_Forget_Frame( FT_Stream stream ) + { + FT_Stream_ExitFrame( stream ); + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftbase.c b/drivers/freetype/src/base/ftbase.c new file mode 100644 index 0000000000..5e5d70ec4b --- /dev/null +++ b/drivers/freetype/src/base/ftbase.c @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* ftbase.c */ +/* */ +/* Single object library component (body only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 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> + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include "ftpic.c" +#include "basepic.c" +#include "ftadvanc.c" +#include "ftcalc.c" +#include "ftdbgmem.c" +#include "ftgloadr.c" +#include "ftobjs.c" +#include "ftoutln.c" +#include "ftrfork.c" +#include "ftsnames.c" +#include "ftstream.c" +#include "fttrigon.c" +#include "ftutil.c" + +#ifdef FT_MACINTOSH +#include "ftmac.c" +#endif + +/* END */ diff --git a/drivers/freetype/src/base/ftbase.h b/drivers/freetype/src/base/ftbase.h new file mode 100644 index 0000000000..51a1db18b8 --- /dev/null +++ b/drivers/freetype/src/base/ftbase.h @@ -0,0 +1,69 @@ +/***************************************************************************/ +/* */ +/* ftbase.h */ +/* */ +/* The FreeType private functions used in base module (specification). */ +/* */ +/* Copyright 2008, 2010 by */ +/* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ +/* */ +/* 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 __FTBASE_H__ +#define __FTBASE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ + /* font, and try to load a face specified by the face_index. */ + FT_LOCAL( FT_Error ) + open_face_PS_from_sfnt_stream( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter *params, + FT_Face *aface ); + + + /* Create a new FT_Face given a buffer and a driver name. */ + /* From ftmac.c. */ + FT_LOCAL( FT_Error ) + open_face_from_buffer( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Long face_index, + const char* driver_name, + FT_Face *aface ); + + +#if defined( FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK ) && \ + !defined( FT_MACINTOSH ) + /* Mac OS X/Darwin kernel often changes recommended method to access */ + /* the resource fork and older methods makes the kernel issue the */ + /* warning of deprecated method. To calm it down, the methods based */ + /* on Darwin VFS should be grouped and skip the rest methods after */ + /* the case the resource is opened but found to lack a font in it. */ + FT_LOCAL( FT_Bool ) + ft_raccess_rule_by_darwin_vfs( FT_Library library, FT_UInt rule_index ); +#endif + + +FT_END_HEADER + +#endif /* __FTBASE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftbbox.c b/drivers/freetype/src/base/ftbbox.c new file mode 100644 index 0000000000..6d1c44cb2e --- /dev/null +++ b/drivers/freetype/src/base/ftbbox.c @@ -0,0 +1,649 @@ +/***************************************************************************/ +/* */ +/* ftbbox.c */ +/* */ +/* FreeType bbox computation (body). */ +/* */ +/* Copyright 1996-2002, 2004, 2006, 2010, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This component has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_BBOX_H +#include FT_IMAGE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_OBJECTS_H + + + typedef struct TBBox_Rec_ + { + FT_Vector last; + FT_BBox bbox; + + } TBBox_Rec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Move_To */ + /* */ + /* <Description> */ + /* This function is used as a `move_to' and `line_to' emitter during */ + /* FT_Outline_Decompose(). It simply records the destination point */ + /* in `user->last'; no further computations are necessary since we */ + /* use the cbox as the starting bbox which must be refined. */ + /* */ + /* <Input> */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: A pointer to the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + static int + BBox_Move_To( FT_Vector* to, + TBBox_Rec* user ) + { + user->last = *to; + + return 0; + } + + +#define CHECK_X( p, bbox ) \ + ( p->x < bbox.xMin || p->x > bbox.xMax ) + +#define CHECK_Y( p, bbox ) \ + ( p->y < bbox.yMin || p->y > bbox.yMax ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Conic_Check */ + /* */ + /* <Description> */ + /* Finds the extrema of a 1-dimensional conic Bezier curve and update */ + /* a bounding range. This version uses direct computation, as it */ + /* doesn't need square roots. */ + /* */ + /* <Input> */ + /* y1 :: The start coordinate. */ + /* */ + /* y2 :: The coordinate of the control point. */ + /* */ + /* y3 :: The end coordinate. */ + /* */ + /* <InOut> */ + /* min :: The address of the current minimum. */ + /* */ + /* max :: The address of the current maximum. */ + /* */ + static void + BBox_Conic_Check( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos* min, + FT_Pos* max ) + { + if ( y1 <= y3 && y2 == y1 ) /* flat arc */ + goto Suite; + + if ( y1 < y3 ) + { + if ( y2 >= y1 && y2 <= y3 ) /* ascending arc */ + goto Suite; + } + else + { + if ( y2 >= y3 && y2 <= y1 ) /* descending arc */ + { + y2 = y1; + y1 = y3; + y3 = y2; + goto Suite; + } + } + + y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 ); + + Suite: + if ( y1 < *min ) *min = y1; + if ( y3 > *max ) *max = y3; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Conic_To */ + /* */ + /* <Description> */ + /* This function is used as a `conic_to' emitter during */ + /* FT_Outline_Decompose(). It checks a conic Bezier curve with the */ + /* current bounding box, and computes its extrema if necessary to */ + /* update it. */ + /* */ + /* <Input> */ + /* control :: A pointer to a control point. */ + /* */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: The address of the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + /* <Note> */ + /* In the case of a non-monotonous arc, we compute directly the */ + /* extremum coordinates, as it is sufficiently fast. */ + /* */ + static int + BBox_Conic_To( FT_Vector* control, + FT_Vector* to, + TBBox_Rec* user ) + { + /* we don't need to check `to' since it is always an `on' point, thus */ + /* within the bbox */ + + if ( CHECK_X( control, user->bbox ) ) + BBox_Conic_Check( user->last.x, + control->x, + to->x, + &user->bbox.xMin, + &user->bbox.xMax ); + + if ( CHECK_Y( control, user->bbox ) ) + BBox_Conic_Check( user->last.y, + control->y, + to->y, + &user->bbox.yMin, + &user->bbox.yMax ); + + user->last = *to; + + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Cubic_Check */ + /* */ + /* <Description> */ + /* Finds the extrema of a 1-dimensional cubic Bezier curve and */ + /* updates a bounding range. This version uses splitting because we */ + /* don't want to use square roots and extra accuracy. */ + /* */ + /* <Input> */ + /* p1 :: The start coordinate. */ + /* */ + /* p2 :: The coordinate of the first control point. */ + /* */ + /* p3 :: The coordinate of the second control point. */ + /* */ + /* p4 :: The end coordinate. */ + /* */ + /* <InOut> */ + /* min :: The address of the current minimum. */ + /* */ + /* max :: The address of the current maximum. */ + /* */ + +#if 0 + + static void + BBox_Cubic_Check( FT_Pos p1, + FT_Pos p2, + FT_Pos p3, + FT_Pos p4, + FT_Pos* min, + FT_Pos* max ) + { + FT_Pos q1, q2, q3, q4; + + + q1 = p1; + q2 = p2; + q3 = p3; + q4 = p4; + + /* for a conic segment to possibly reach new maximum */ + /* one of its off-points must be above the current value */ + while ( q2 > *max || q3 > *max ) + { + /* determine which half contains the maximum and split */ + if ( q1 + q2 > q3 + q4 ) /* first half */ + { + q4 = q4 + q3; + q3 = q3 + q2; + q2 = q2 + q1; + q4 = q4 + q3; + q3 = q3 + q2; + q4 = ( q4 + q3 ) / 8; + q3 = q3 / 4; + q2 = q2 / 2; + } + else /* second half */ + { + q1 = q1 + q2; + q2 = q2 + q3; + q3 = q3 + q4; + q1 = q1 + q2; + q2 = q2 + q3; + q1 = ( q1 + q2 ) / 8; + q2 = q2 / 4; + q3 = q3 / 2; + } + + /* check if either end reached the maximum */ + if ( q1 == q2 && q1 >= q3 ) + { + *max = q1; + break; + } + if ( q3 == q4 && q2 <= q4 ) + { + *max = q4; + break; + } + } + + q1 = p1; + q2 = p2; + q3 = p3; + q4 = p4; + + /* for a conic segment to possibly reach new minimum */ + /* one of its off-points must be below the current value */ + while ( q2 < *min || q3 < *min ) + { + /* determine which half contains the minimum and split */ + if ( q1 + q2 < q3 + q4 ) /* first half */ + { + q4 = q4 + q3; + q3 = q3 + q2; + q2 = q2 + q1; + q4 = q4 + q3; + q3 = q3 + q2; + q4 = ( q4 + q3 ) / 8; + q3 = q3 / 4; + q2 = q2 / 2; + } + else /* second half */ + { + q1 = q1 + q2; + q2 = q2 + q3; + q3 = q3 + q4; + q1 = q1 + q2; + q2 = q2 + q3; + q1 = ( q1 + q2 ) / 8; + q2 = q2 / 4; + q3 = q3 / 2; + } + + /* check if either end reached the minimum */ + if ( q1 == q2 && q1 <= q3 ) + { + *min = q1; + break; + } + if ( q3 == q4 && q2 >= q4 ) + { + *min = q4; + break; + } + } + } + +#else + + static void + test_cubic_extrema( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos y4, + FT_Fixed u, + FT_Pos* min, + FT_Pos* max ) + { + /* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */ + FT_Pos b = y3 - 2*y2 + y1; + FT_Pos c = y2 - y1; + FT_Pos d = y1; + FT_Pos y; + FT_Fixed uu; + + FT_UNUSED ( y4 ); + + + /* The polynomial is */ + /* */ + /* P(x) = a*x^3 + 3b*x^2 + 3c*x + d , */ + /* */ + /* dP/dx = 3a*x^2 + 6b*x + 3c . */ + /* */ + /* However, we also have */ + /* */ + /* dP/dx(u) = 0 , */ + /* */ + /* which implies by subtraction that */ + /* */ + /* P(u) = b*u^2 + 2c*u + d . */ + + if ( u > 0 && u < 0x10000L ) + { + uu = FT_MulFix( u, u ); + y = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu ); + + if ( y < *min ) *min = y; + if ( y > *max ) *max = y; + } + } + + + static void + BBox_Cubic_Check( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos y4, + FT_Pos* min, + FT_Pos* max ) + { + /* always compare first and last points */ + if ( y1 < *min ) *min = y1; + else if ( y1 > *max ) *max = y1; + + if ( y4 < *min ) *min = y4; + else if ( y4 > *max ) *max = y4; + + /* now, try to see if there are split points here */ + if ( y1 <= y4 ) + { + /* flat or ascending arc test */ + if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) + return; + } + else /* y1 > y4 */ + { + /* descending arc test */ + if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) + return; + } + + /* There are some split points. Find them. */ + /* We already made sure that a, b, and c below cannot be all zero. */ + { + FT_Pos a = y4 - 3*y3 + 3*y2 - y1; + FT_Pos b = y3 - 2*y2 + y1; + FT_Pos c = y2 - y1; + FT_Pos d; + FT_Fixed t; + FT_Int shift; + + + /* We need to solve `ax^2+2bx+c' here, without floating points! */ + /* The trick is to normalize to a different representation in order */ + /* to use our 16.16 fixed-point routines. */ + /* */ + /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */ + /* These values must fit into a single 16.16 value. */ + /* */ + /* We normalize a, b, and c to `8.16' fixed-point values to ensure */ + /* that their product is held in a `16.16' value including the sign. */ + /* Necessarily, we need to shift `a', `b', and `c' so that the most */ + /* significant bit of their absolute values is at position 22. */ + /* */ + /* This also means that we are using 23 bits of precision to compute */ + /* the zeros, independently of the range of the original polynomial */ + /* coefficients. */ + /* */ + /* This algorithm should ensure reasonably accurate values for the */ + /* zeros. Note that they are only expressed with 16 bits when */ + /* computing the extrema (the zeros need to be in 0..1 exclusive */ + /* to be considered part of the arc). */ + + shift = FT_MSB( FT_ABS( a ) | FT_ABS( b ) | FT_ABS( c ) ); + + if ( shift > 22 ) + { + shift -= 22; + + /* this loses some bits of precision, but we use 23 of them */ + /* for the computation anyway */ + a >>= shift; + b >>= shift; + c >>= shift; + } + else + { + shift = 22 - shift; + + a <<= shift; + b <<= shift; + c <<= shift; + } + + /* handle a == 0 */ + if ( a == 0 ) + { + if ( b != 0 ) + { + t = - FT_DivFix( c, b ) / 2; + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + } + else + { + /* solve the equation now */ + d = FT_MulFix( b, b ) - FT_MulFix( a, c ); + if ( d < 0 ) + return; + + if ( d == 0 ) + { + /* there is a single split point at -b/a */ + t = - FT_DivFix( b, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + else + { + /* there are two solutions; we need to filter them */ + d = FT_SqrtFixed( (FT_Int32)d ); + t = - FT_DivFix( b - d, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + + t = - FT_DivFix( b + d, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + } + } + } + +#endif + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Cubic_To */ + /* */ + /* <Description> */ + /* This function is used as a `cubic_to' emitter during */ + /* FT_Outline_Decompose(). It checks a cubic Bezier curve with the */ + /* current bounding box, and computes its extrema if necessary to */ + /* update it. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first control point. */ + /* */ + /* control2 :: A pointer to the second control point. */ + /* */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: The address of the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + /* <Note> */ + /* In the case of a non-monotonous arc, we don't compute directly */ + /* extremum coordinates, we subdivide instead. */ + /* */ + static int + BBox_Cubic_To( FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to, + TBBox_Rec* user ) + { + /* we don't need to check `to' since it is always an `on' point, thus */ + /* within the bbox */ + + if ( CHECK_X( control1, user->bbox ) || + CHECK_X( control2, user->bbox ) ) + BBox_Cubic_Check( user->last.x, + control1->x, + control2->x, + to->x, + &user->bbox.xMin, + &user->bbox.xMax ); + + if ( CHECK_Y( control1, user->bbox ) || + CHECK_Y( control2, user->bbox ) ) + BBox_Cubic_Check( user->last.y, + control1->y, + control2->y, + to->y, + &user->bbox.yMin, + &user->bbox.yMax ); + + user->last = *to; + + return 0; + } + +FT_DEFINE_OUTLINE_FUNCS(bbox_interface, + (FT_Outline_MoveTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_ConicTo_Func)BBox_Conic_To, + (FT_Outline_CubicTo_Func)BBox_Cubic_To, + 0, 0 + ) + + /* documentation is in ftbbox.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ) + { + FT_BBox cbox; + FT_BBox bbox; + FT_Vector* vec; + FT_UShort n; + + + if ( !abbox ) + return FT_THROW( Invalid_Argument ); + + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + /* if outline is empty, return (0,0,0,0) */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + { + abbox->xMin = abbox->xMax = 0; + abbox->yMin = abbox->yMax = 0; + return 0; + } + + /* We compute the control box as well as the bounding box of */ + /* all `on' points in the outline. Then, if the two boxes */ + /* coincide, we exit immediately. */ + + vec = outline->points; + bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x; + bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y; + vec++; + + for ( n = 1; n < outline->n_points; n++ ) + { + FT_Pos x = vec->x; + FT_Pos y = vec->y; + + + /* update control box */ + if ( x < cbox.xMin ) cbox.xMin = x; + if ( x > cbox.xMax ) cbox.xMax = x; + + if ( y < cbox.yMin ) cbox.yMin = y; + if ( y > cbox.yMax ) cbox.yMax = y; + + if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) + { + /* update bbox for `on' points only */ + if ( x < bbox.xMin ) bbox.xMin = x; + if ( x > bbox.xMax ) bbox.xMax = x; + + if ( y < bbox.yMin ) bbox.yMin = y; + if ( y > bbox.yMax ) bbox.yMax = y; + } + + vec++; + } + + /* test two boxes for equality */ + if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax || + cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax ) + { + /* the two boxes are different, now walk over the outline to */ + /* get the Bezier arc extrema. */ + + FT_Error error; + TBBox_Rec user; + +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs bbox_interface; + Init_Class_bbox_interface(&bbox_interface); +#endif + + user.bbox = bbox; + + error = FT_Outline_Decompose( outline, &bbox_interface, &user ); + if ( error ) + return error; + + *abbox = user.bbox; + } + else + *abbox = bbox; + + return FT_Err_Ok; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftbdf.c b/drivers/freetype/src/base/ftbdf.c new file mode 100644 index 0000000000..5755f8558d --- /dev/null +++ b/drivers/freetype/src/base/ftbdf.c @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* ftbdf.c */ +/* */ +/* FreeType API for accessing BDF-specific strings (body). */ +/* */ +/* Copyright 2002-2004, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_BDF_H + + + /* documentation is in ftbdf.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + FT_Error error; + const char* encoding = NULL; + const char* registry = NULL; + + + error = FT_ERR( Invalid_Argument ); + + if ( face ) + { + FT_Service_BDF service; + + + FT_FACE_FIND_SERVICE( face, service, BDF ); + + if ( service && service->get_charset_id ) + error = service->get_charset_id( face, &encoding, ®istry ); + } + + if ( acharset_encoding ) + *acharset_encoding = encoding; + + if ( acharset_registry ) + *acharset_registry = registry; + + return error; + } + + + /* documentation is in ftbdf.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + FT_Error error; + + + error = FT_ERR( Invalid_Argument ); + + aproperty->type = BDF_PROPERTY_TYPE_NONE; + + if ( face ) + { + FT_Service_BDF service; + + + FT_FACE_FIND_SERVICE( face, service, BDF ); + + if ( service && service->get_property ) + error = service->get_property( face, prop_name, aproperty ); + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftbitmap.c b/drivers/freetype/src/base/ftbitmap.c new file mode 100644 index 0000000000..975818e14f --- /dev/null +++ b/drivers/freetype/src/base/ftbitmap.c @@ -0,0 +1,758 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.c */ +/* */ +/* FreeType utility functions for bitmaps (body). */ +/* */ +/* Copyright 2004-2009, 2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_BITMAP_H +#include FT_IMAGE_H +#include FT_INTERNAL_OBJECTS_H + + + static + const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ) + { + *abitmap = null_bitmap; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Copy( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target) + { + FT_Memory memory = library->memory; + FT_Error error = FT_Err_Ok; + FT_Int pitch = source->pitch; + FT_ULong size; + + + if ( source == target ) + return FT_Err_Ok; + + if ( source->buffer == NULL ) + { + *target = *source; + + return FT_Err_Ok; + } + + if ( pitch < 0 ) + pitch = -pitch; + size = (FT_ULong)( pitch * source->rows ); + + if ( target->buffer ) + { + FT_Int target_pitch = target->pitch; + FT_ULong target_size; + + + if ( target_pitch < 0 ) + target_pitch = -target_pitch; + target_size = (FT_ULong)( target_pitch * target->rows ); + + if ( target_size != size ) + (void)FT_QREALLOC( target->buffer, target_size, size ); + } + else + (void)FT_QALLOC( target->buffer, size ); + + if ( !error ) + { + unsigned char *p; + + + p = target->buffer; + *target = *source; + target->buffer = p; + + FT_MEM_COPY( target->buffer, source->buffer, size ); + } + + return error; + } + + + static FT_Error + ft_bitmap_assure_buffer( FT_Memory memory, + FT_Bitmap* bitmap, + FT_UInt xpixels, + FT_UInt ypixels ) + { + FT_Error error; + int pitch; + int new_pitch; + FT_UInt bpp; + FT_Int i, width, height; + unsigned char* buffer = NULL; + + + width = bitmap->width; + height = bitmap->rows; + pitch = bitmap->pitch; + if ( pitch < 0 ) + pitch = -pitch; + + switch ( bitmap->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + bpp = 1; + new_pitch = ( width + xpixels + 7 ) >> 3; + break; + case FT_PIXEL_MODE_GRAY2: + bpp = 2; + new_pitch = ( width + xpixels + 3 ) >> 2; + break; + case FT_PIXEL_MODE_GRAY4: + bpp = 4; + new_pitch = ( width + xpixels + 1 ) >> 1; + break; + case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: + bpp = 8; + new_pitch = ( width + xpixels ); + break; + default: + return FT_THROW( Invalid_Glyph_Format ); + } + + /* if no need to allocate memory */ + if ( ypixels == 0 && new_pitch <= pitch ) + { + /* zero the padding */ + FT_Int bit_width = pitch * 8; + FT_Int bit_last = ( width + xpixels ) * bpp; + + + if ( bit_last < bit_width ) + { + FT_Byte* line = bitmap->buffer + ( bit_last >> 3 ); + FT_Byte* end = bitmap->buffer + pitch; + FT_Int shift = bit_last & 7; + FT_UInt mask = 0xFF00U >> shift; + FT_Int count = height; + + + for ( ; count > 0; count--, line += pitch, end += pitch ) + { + FT_Byte* write = line; + + + if ( shift > 0 ) + { + write[0] = (FT_Byte)( write[0] & mask ); + write++; + } + if ( write < end ) + FT_MEM_ZERO( write, end-write ); + } + } + + return FT_Err_Ok; + } + + if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) + return error; + + if ( bitmap->pitch > 0 ) + { + FT_Int len = ( width * bpp + 7 ) >> 3; + + + for ( i = 0; i < bitmap->rows; i++ ) + FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ), + bitmap->buffer + pitch * i, len ); + } + else + { + FT_Int len = ( width * bpp + 7 ) >> 3; + + + for ( i = 0; i < bitmap->rows; i++ ) + FT_MEM_COPY( buffer + new_pitch * i, + bitmap->buffer + pitch * i, len ); + } + + FT_FREE( bitmap->buffer ); + bitmap->buffer = buffer; + + if ( bitmap->pitch < 0 ) + new_pitch = -new_pitch; + + /* set pitch only, width and height are left untouched */ + bitmap->pitch = new_pitch; + + return FT_Err_Ok; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Embolden( FT_Library library, + FT_Bitmap* bitmap, + FT_Pos xStrength, + FT_Pos yStrength ) + { + FT_Error error; + unsigned char* p; + FT_Int i, x, y, pitch; + FT_Int xstr, ystr; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !bitmap || !bitmap->buffer ) + return FT_THROW( Invalid_Argument ); + + if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || + ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) + return FT_THROW( Invalid_Argument ); + + xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6; + ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6; + + if ( xstr == 0 && ystr == 0 ) + return FT_Err_Ok; + else if ( xstr < 0 || ystr < 0 ) + return FT_THROW( Invalid_Argument ); + + switch ( bitmap->pixel_mode ) + { + case FT_PIXEL_MODE_GRAY2: + case FT_PIXEL_MODE_GRAY4: + { + FT_Bitmap tmp; + FT_Int align; + + + if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 ) + align = ( bitmap->width + xstr + 3 ) / 4; + else + align = ( bitmap->width + xstr + 1 ) / 2; + + FT_Bitmap_New( &tmp ); + + error = FT_Bitmap_Convert( library, bitmap, &tmp, align ); + if ( error ) + return error; + + FT_Bitmap_Done( library, bitmap ); + *bitmap = tmp; + } + break; + + case FT_PIXEL_MODE_MONO: + if ( xstr > 8 ) + xstr = 8; + break; + + case FT_PIXEL_MODE_LCD: + xstr *= 3; + break; + + case FT_PIXEL_MODE_LCD_V: + ystr *= 3; + break; + + case FT_PIXEL_MODE_BGRA: + /* We don't embolden color glyphs. */ + return FT_Err_Ok; + } + + error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); + if ( error ) + return error; + + pitch = bitmap->pitch; + if ( pitch > 0 ) + p = bitmap->buffer + pitch * ystr; + else + { + pitch = -pitch; + p = bitmap->buffer + pitch * ( bitmap->rows - 1 ); + } + + /* for each row */ + for ( y = 0; y < bitmap->rows ; y++ ) + { + /* + * Horizontally: + * + * From the last pixel on, make each pixel or'ed with the + * `xstr' pixels before it. + */ + for ( x = pitch - 1; x >= 0; x-- ) + { + unsigned char tmp; + + + tmp = p[x]; + for ( i = 1; i <= xstr; i++ ) + { + if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO ) + { + p[x] |= tmp >> i; + + /* the maximum value of 8 for `xstr' comes from here */ + if ( x > 0 ) + p[x] |= p[x - 1] << ( 8 - i ); + +#if 0 + if ( p[x] == 0xff ) + break; +#endif + } + else + { + if ( x - i >= 0 ) + { + if ( p[x] + p[x - i] > bitmap->num_grays - 1 ) + { + p[x] = (unsigned char)(bitmap->num_grays - 1); + break; + } + else + { + p[x] = (unsigned char)(p[x] + p[x-i]); + if ( p[x] == bitmap->num_grays - 1 ) + break; + } + } + else + break; + } + } + } + + /* + * Vertically: + * + * Make the above `ystr' rows or'ed with it. + */ + for ( x = 1; x <= ystr; x++ ) + { + unsigned char* q; + + + q = p - bitmap->pitch * x; + for ( i = 0; i < pitch; i++ ) + q[i] |= p[i]; + } + + p += bitmap->pitch; + } + + bitmap->width += xstr; + bitmap->rows += ystr; + + return FT_Err_Ok; + } + + + FT_Byte + ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra ) + { + FT_Long a = bgra[3]; + FT_Long b = bgra[0]; + FT_Long g = bgra[1]; + FT_Long r = bgra[2]; + FT_Long l; + + + /* + * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722 + * coefficients for RGB channels *on the linear colors*. + * A gamma of 2.2 is fair to assume. And then, we need to + * undo the premultiplication too. + * + * http://accessibility.kde.org/hsl-adjusted.php + * + * We do the computation with integers only. + */ + + /* Undo premultification, get the number in a 16.16 form. */ + b = FT_MulDiv( b, 65536, a ); + g = FT_MulDiv( g, 65536, a ); + r = FT_MulDiv( r, 65536, a ); + a = a * 256; + + /* Apply gamma of 2.0 instead of 2.2. */ + b = FT_MulFix( b, b ); + g = FT_MulFix( g, g ); + r = FT_MulFix( r, r ); + + /* Apply coefficients. */ + b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ ); + g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ ); + r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ ); + + l = r + g + b; + + /* + * Final transparency can be determined this way: + * + * - If alpha is zero, we want 0. + * - If alpha is zero and luminosity is zero, we want 255. + * - If alpha is zero and luminosity is one, we want 0. + * + * So the formula is a * (1 - l). + */ + + return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 ); + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + memory = library->memory; + + switch ( source->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_GRAY2: + case FT_PIXEL_MODE_GRAY4: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: + case FT_PIXEL_MODE_BGRA: + { + FT_Int pad; + FT_Long old_size; + + + old_size = target->rows * target->pitch; + if ( old_size < 0 ) + old_size = -old_size; + + target->pixel_mode = FT_PIXEL_MODE_GRAY; + target->rows = source->rows; + target->width = source->width; + + pad = 0; + if ( alignment > 0 ) + { + pad = source->width % alignment; + if ( pad != 0 ) + pad = alignment - pad; + } + + target->pitch = source->width + pad; + + if ( target->pitch > 0 && + (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch ) + return FT_THROW( Invalid_Argument ); + + if ( target->rows * target->pitch > old_size && + FT_QREALLOC( target->buffer, + old_size, target->rows * target->pitch ) ) + return error; + } + break; + + default: + error = FT_THROW( Invalid_Argument ); + } + + switch ( source->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + { + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int i; + + + target->num_grays = 2; + + for ( i = source->rows; i > 0; i-- ) + { + FT_Byte* ss = s; + FT_Byte* tt = t; + FT_Int j; + + + /* get the full bytes */ + for ( j = source->width >> 3; j > 0; j-- ) + { + FT_Int val = ss[0]; /* avoid a byte->int cast on each line */ + + + tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 ); + tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 ); + tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 ); + tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 ); + tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 ); + tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 ); + tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 ); + tt[7] = (FT_Byte)( val & 0x01 ); + + tt += 8; + ss += 1; + } + + /* get remaining pixels (if any) */ + j = source->width & 7; + if ( j > 0 ) + { + FT_Int val = *ss; + + + for ( ; j > 0; j-- ) + { + tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7); + val <<= 1; + tt += 1; + } + } + + s += source->pitch; + t += target->pitch; + } + } + break; + + + case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: + { + FT_Int width = source->width; + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int s_pitch = source->pitch; + FT_Int t_pitch = target->pitch; + FT_Int i; + + + target->num_grays = 256; + + for ( i = source->rows; i > 0; i-- ) + { + FT_ARRAY_COPY( t, s, width ); + + s += s_pitch; + t += t_pitch; + } + } + break; + + + case FT_PIXEL_MODE_GRAY2: + { + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int i; + + + target->num_grays = 4; + + for ( i = source->rows; i > 0; i-- ) + { + FT_Byte* ss = s; + FT_Byte* tt = t; + FT_Int j; + + + /* get the full bytes */ + for ( j = source->width >> 2; j > 0; j-- ) + { + FT_Int val = ss[0]; + + + tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 ); + tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 ); + tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 ); + tt[3] = (FT_Byte)( ( val & 0x03 ) ); + + ss += 1; + tt += 4; + } + + j = source->width & 3; + if ( j > 0 ) + { + FT_Int val = ss[0]; + + + for ( ; j > 0; j-- ) + { + tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 ); + val <<= 2; + tt += 1; + } + } + + s += source->pitch; + t += target->pitch; + } + } + break; + + + case FT_PIXEL_MODE_GRAY4: + { + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int i; + + + target->num_grays = 16; + + for ( i = source->rows; i > 0; i-- ) + { + FT_Byte* ss = s; + FT_Byte* tt = t; + FT_Int j; + + + /* get the full bytes */ + for ( j = source->width >> 1; j > 0; j-- ) + { + FT_Int val = ss[0]; + + + tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 ); + tt[1] = (FT_Byte)( ( val & 0x0F ) ); + + ss += 1; + tt += 2; + } + + if ( source->width & 1 ) + tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 ); + + s += source->pitch; + t += target->pitch; + } + } + break; + + case FT_PIXEL_MODE_BGRA: + { + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int s_pitch = source->pitch; + FT_Int t_pitch = target->pitch; + FT_Int i; + + + target->num_grays = 256; + + for ( i = source->rows; i > 0; i-- ) + { + FT_Byte* ss = s; + FT_Byte* tt = t; + FT_Int j; + + + for ( j = source->width; j > 0; j-- ) + { + tt[0] = ft_gray_for_premultiplied_srgb_bgra( ss ); + + ss += 4; + tt += 1; + } + + s += s_pitch; + t += t_pitch; + } + } + break; + + default: + ; + } + + return error; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ) + { + if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP && + !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + { + FT_Bitmap bitmap; + FT_Error error; + + + FT_Bitmap_New( &bitmap ); + error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); + if ( error ) + return error; + + slot->bitmap = bitmap; + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + } + + return FT_Err_Ok; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ) + { + FT_Memory memory; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !bitmap ) + return FT_THROW( Invalid_Argument ); + + memory = library->memory; + + FT_FREE( bitmap->buffer ); + *bitmap = null_bitmap; + + return FT_Err_Ok; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftcalc.c b/drivers/freetype/src/base/ftcalc.c new file mode 100644 index 0000000000..0ec0d78930 --- /dev/null +++ b/drivers/freetype/src/base/ftcalc.c @@ -0,0 +1,974 @@ +/***************************************************************************/ +/* */ +/* ftcalc.c */ +/* */ +/* Arithmetic computations (body). */ +/* */ +/* Copyright 1996-2006, 2008, 2012-2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Support for 1-complement arithmetic has been totally dropped in this */ + /* release. You can still write your own code if you need it. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Implementing basic computation routines. */ + /* */ + /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ + /* and FT_FloorFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_GLYPH_H +#include FT_TRIGONOMETRY_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + +#ifdef FT_MULFIX_INLINED +#undef FT_MulFix +#endif + +/* we need to emulate a 64-bit data type if a real one isn't available */ + +#ifndef FT_LONG64 + + typedef struct FT_Int64_ + { + FT_UInt32 lo; + FT_UInt32 hi; + + } FT_Int64; + +#endif /* !FT_LONG64 */ + + + /*************************************************************************/ + /* */ + /* 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_calc + + + /* The following three functions are available regardless of whether */ + /* FT_LONG64 is defined. */ + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_RoundFix( FT_Fixed a ) + { + return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL + : -((-a + 0x8000L ) & ~0xFFFFL ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_CeilFix( FT_Fixed a ) + { + return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL + : -((-a + 0xFFFFL ) & ~0xFFFFL ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_FloorFix( FT_Fixed a ) + { + return ( a >= 0 ) ? a & ~0xFFFFL + : -((-a) & ~0xFFFFL ); + } + + + FT_BASE_DEF ( FT_Int ) + FT_MSB( FT_UInt32 z ) + { + FT_Int shift = 0; + + /* determine msb bit index in `shift' */ + if ( z >= ( 1L << 16 ) ) + { + z >>= 16; + shift += 16; + } + if ( z >= ( 1L << 8 ) ) + { + z >>= 8; + shift += 8; + } + if ( z >= ( 1L << 4 ) ) + { + z >>= 4; + shift += 4; + } + if ( z >= ( 1L << 2 ) ) + { + z >>= 2; + shift += 2; + } + if ( z >= ( 1L << 1 ) ) + { + z >>= 1; + shift += 1; + } + + return shift; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Fixed ) + FT_Hypot( FT_Fixed x, + FT_Fixed y ) + { + FT_Vector v; + + + v.x = x; + v.y = y; + + return FT_Vector_Length( &v ); + } + + +#ifdef FT_LONG64 + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ) + { +#ifdef FT_MULFIX_ASSEMBLER + + return FT_MULFIX_ASSEMBLER( a, b ); + +#else + + FT_Int s = 1; + FT_Long c; + + + if ( a < 0 ) + { + a = -a; + s = -1; + } + + if ( b < 0 ) + { + b = -b; + s = -s; + } + + c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); + + return ( s > 0 ) ? c : -c; + +#endif /* FT_MULFIX_ASSEMBLER */ + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ) + { + FT_Int32 s; + FT_UInt32 q; + + + s = 1; + if ( a < 0 ) + { + a = -a; + s = -1; + } + if ( b < 0 ) + { + b = -b; + s = -s; + } + + if ( b == 0 ) + /* check for division by 0 */ + q = 0x7FFFFFFFL; + else + /* compute result directly */ + q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b ); + + return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); + } + + +#else /* !FT_LONG64 */ + + + static void + ft_multo64( FT_UInt32 x, + FT_UInt32 y, + FT_Int64 *z ) + { + FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + lo1 = x & 0x0000FFFFU; hi1 = x >> 16; + lo2 = y & 0x0000FFFFU; hi2 = y >> 16; + + lo = lo1 * lo2; + i1 = lo1 * hi2; + i2 = lo2 * hi1; + hi = hi1 * hi2; + + /* Check carry overflow of i1 + i2 */ + i1 += i2; + hi += (FT_UInt32)( i1 < i2 ) << 16; + + hi += i1 >> 16; + i1 = i1 << 16; + + /* Check carry overflow of i1 + lo */ + lo += i1; + hi += ( lo < i1 ); + + z->lo = lo; + z->hi = hi; + } + + + static FT_UInt32 + ft_div64by32( FT_UInt32 hi, + FT_UInt32 lo, + FT_UInt32 y ) + { + FT_UInt32 r, q; + FT_Int i; + + + q = 0; + r = hi; + + if ( r >= y ) + return (FT_UInt32)0x7FFFFFFFL; + + i = 32; + do + { + r <<= 1; + q <<= 1; + r |= lo >> 31; + + if ( r >= y ) + { + r -= y; + q |= 1; + } + lo <<= 1; + } while ( --i ); + + return q; + } + + + static void + FT_Add64( FT_Int64* x, + FT_Int64* y, + FT_Int64 *z ) + { + register FT_UInt32 lo, hi; + + + lo = x->lo + y->lo; + hi = x->hi + y->hi + ( lo < x->lo ); + + z->lo = lo; + z->hi = hi; + } + + + /* 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, + FT_Long c ) + { + long s; + + + /* XXX: this function does not allow 64-bit arguments */ + if ( a == 0 || b == c ) + return a; + + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + s ^= c; c = FT_ABS( c ); + + if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) + a = ( a * b + ( c >> 1 ) ) / c; + + else if ( (FT_Int32)c > 0 ) + { + FT_Int64 temp, temp2; + + + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + + temp2.hi = 0; + temp2.lo = (FT_UInt32)(c >> 1); + FT_Add64( &temp, &temp2, &temp ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + } + else + a = 0x7FFFFFFFL; + + return ( s < 0 ? -a : a ); + } + + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + long s; + + + if ( a == 0 || b == c ) + return a; + + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + s ^= c; c = FT_ABS( c ); + + if ( a <= 46340L && b <= 46340L && c > 0 ) + a = a * b / c; + + else if ( (FT_Int32)c > 0 ) + { + FT_Int64 temp; + + + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + } + else + a = 0x7FFFFFFFL; + + return ( s < 0 ? -a : a ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ) + { +#ifdef FT_MULFIX_ASSEMBLER + + return FT_MULFIX_ASSEMBLER( a, b ); + +#elif 0 + + /* + * This code is nonportable. See comment below. + * + * However, on a platform where right-shift of a signed quantity fills + * the leftmost bits by copying the sign bit, it might be faster. + */ + + FT_Long sa, sb; + FT_ULong ua, ub; + + + if ( a == 0 || b == 0x10000L ) + return a; + + /* + * This is a clever way of converting a signed number `a' into its + * absolute value (stored back into `a') and its sign. The sign is + * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' + * was negative. (Similarly for `b' and `sb'). + * + * Unfortunately, it doesn't work (at least not portably). + * + * It makes the assumption that right-shift on a negative signed value + * fills the leftmost bits by copying the sign bit. This is wrong. + * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, + * the result of right-shift of a negative signed value is + * implementation-defined. At least one implementation fills the + * leftmost bits with 0s (i.e., it is exactly the same as an unsigned + * right shift). This means that when `a' is negative, `sa' ends up + * with the value 1 rather than -1. After that, everything else goes + * wrong. + */ + sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); + a = ( a ^ sa ) - sa; + sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); + b = ( b ^ sb ) - sb; + + ua = (FT_ULong)a; + ub = (FT_ULong)b; + + if ( ua <= 2048 && ub <= 1048576L ) + ua = ( ua * ub + 0x8000U ) >> 16; + else + { + FT_ULong al = ua & 0xFFFFU; + + + ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + + ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); + } + + sa ^= sb, + ua = (FT_ULong)(( ua ^ sa ) - sa); + + return (FT_Long)ua; + +#else /* 0 */ + + FT_Long s; + FT_ULong ua, ub; + + + if ( a == 0 || b == 0x10000L ) + return a; + + 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 + 0x8000UL ) >> 16; + else + { + FT_ULong al = ua & 0xFFFFUL; + + + ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + + ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); + } + + return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); + +#endif /* 0 */ + + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ) + { + FT_Int32 s; + FT_UInt32 q; + + + /* XXX: this function does not allow 64-bit arguments */ + s = (FT_Int32)a; a = FT_ABS( a ); + s ^= (FT_Int32)b; b = FT_ABS( b ); + + if ( (FT_UInt32)b == 0 ) + { + /* check for division by 0 */ + q = (FT_UInt32)0x7FFFFFFFL; + } + else if ( ( a >> 16 ) == 0 ) + { + /* compute result directly */ + q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; + } + else + { + /* we need more bits; we have to do it by hand */ + FT_Int64 temp, temp2; + + + temp.hi = (FT_Int32)( a >> 16 ); + temp.lo = (FT_UInt32)a << 16; + temp2.hi = 0; + temp2.lo = (FT_UInt32)( b >> 1 ); + FT_Add64( &temp, &temp2, &temp ); + q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); + } + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + +#if 0 + + /* documentation is in ftcalc.h */ + + FT_EXPORT_DEF( void ) + FT_MulTo64( FT_Int32 x, + FT_Int32 y, + FT_Int64 *z ) + { + FT_Int32 s; + + + s = x; x = FT_ABS( x ); + s ^= y; y = FT_ABS( y ); + + ft_multo64( x, y, z ); + + if ( s < 0 ) + { + z->lo = (FT_UInt32)-(FT_Int32)z->lo; + z->hi = ~z->hi + !( z->lo ); + } + } + + + /* apparently, the second version of this code is not compiled correctly */ + /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ + +#if 1 + + FT_EXPORT_DEF( FT_Int32 ) + FT_Div64by32( FT_Int64* x, + FT_Int32 y ) + { + FT_Int32 s; + FT_UInt32 q, r, i, lo; + + + s = x->hi; + if ( s < 0 ) + { + x->lo = (FT_UInt32)-(FT_Int32)x->lo; + x->hi = ~x->hi + !x->lo; + } + s ^= y; y = FT_ABS( y ); + + /* Shortcut */ + if ( x->hi == 0 ) + { + if ( y > 0 ) + q = x->lo / y; + else + q = 0x7FFFFFFFL; + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + r = x->hi; + lo = x->lo; + + 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! */ + q = 0; + for ( i = 0; i < 32; i++ ) + { + r <<= 1; + q <<= 1; + r |= lo >> 31; + + if ( r >= (FT_UInt32)y ) + { + r -= y; + q |= 1; + } + lo <<= 1; + } + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + +#else /* 0 */ + + FT_EXPORT_DEF( FT_Int32 ) + FT_Div64by32( FT_Int64* x, + FT_Int32 y ) + { + FT_Int32 s; + FT_UInt32 q; + + + s = x->hi; + if ( s < 0 ) + { + x->lo = (FT_UInt32)-(FT_Int32)x->lo; + x->hi = ~x->hi + !x->lo; + } + s ^= y; y = FT_ABS( y ); + + /* Shortcut */ + if ( x->hi == 0 ) + { + if ( y > 0 ) + q = ( x->lo + ( y >> 1 ) ) / y; + else + q = 0x7FFFFFFFL; + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + q = ft_div64by32( x->hi, x->lo, y ); + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + +#endif /* 0 */ + +#endif /* 0 */ + + +#endif /* FT_LONG64 */ + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix *b ) + { + FT_Fixed xx, xy, yx, yy; + + + if ( !a || !b ) + return; + + xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); + xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); + yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); + yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ) + { + FT_Pos delta, xx, yy; + + + if ( !matrix ) + return FT_THROW( Invalid_Argument ); + + /* compute discriminant */ + delta = FT_MulFix( matrix->xx, matrix->yy ) - + FT_MulFix( matrix->xy, matrix->yx ); + + if ( !delta ) + return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */ + + matrix->xy = - FT_DivFix( matrix->xy, delta ); + matrix->yx = - FT_DivFix( matrix->yx, delta ); + + xx = matrix->xx; + yy = matrix->yy; + + matrix->xx = FT_DivFix( yy, delta ); + matrix->yy = FT_DivFix( xx, delta ); + + return FT_Err_Ok; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ) + { + FT_Fixed xx, xy, yx, yy; + + FT_Long val = 0x10000L * scaling; + + + if ( !a || !b ) + return; + + xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); + xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); + yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); + yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ) + { + FT_Pos xz, yz; + + FT_Long val = 0x10000L * scaling; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulDiv( vector->x, matrix->xx, val ) + + FT_MulDiv( vector->y, matrix->xy, val ); + + yz = FT_MulDiv( vector->x, matrix->yx, val ) + + FT_MulDiv( vector->y, matrix->yy, val ); + + vector->x = xz; + vector->y = yz; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ) + { + FT_UInt32 root, rem_hi, rem_lo, test_div; + FT_Int count; + + + root = 0; + + if ( x > 0 ) + { + rem_hi = 0; + rem_lo = x; + count = 24; + do + { + rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); + rem_lo <<= 2; + root <<= 1; + test_div = ( root << 1 ) + 1; + + if ( rem_hi >= test_div ) + { + rem_hi -= test_div; + root += 1; + } + } while ( --count ); + } + + return (FT_Int32)root; + } + + + /* 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_Long result; /* avoid overflow on 16-bit system */ + + + /* 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; + + + /* XXX: this function does not allow 64-bit arguments */ + ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); + ft_multo64( (FT_Int32)in_y, (FT_Int32)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 + } + + /* XXX: only the sign of return value, +1/0/-1 must be used */ + return (FT_Int)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 */ diff --git a/drivers/freetype/src/base/ftcid.c b/drivers/freetype/src/base/ftcid.c new file mode 100644 index 0000000000..741879d922 --- /dev/null +++ b/drivers/freetype/src/base/ftcid.c @@ -0,0 +1,117 @@ +/***************************************************************************/ +/* */ +/* ftcid.c */ +/* */ +/* FreeType API for accessing CID font information. */ +/* */ +/* Copyright 2007, 2009, 2013 by Derek Clegg, Michael Toftdal. */ +/* */ +/* 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_CID_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_CID_H + + + /* documentation is in ftcid.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement) + { + FT_Error error; + const char* r = NULL; + const char* o = NULL; + FT_Int s = 0; + + + error = FT_ERR( Invalid_Argument ); + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_ros ) + error = service->get_ros( face, &r, &o, &s ); + } + + if ( registry ) + *registry = r; + + if ( ordering ) + *ordering = o; + + if ( supplement ) + *supplement = s; + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Bool ic = 0; + + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_is_cid ) + error = service->get_is_cid( face, &ic); + } + + if ( is_cid ) + *is_cid = ic; + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + FT_UInt c = 0; + + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_cid_from_glyph_index ) + error = service->get_cid_from_glyph_index( face, glyph_index, &c); + } + + if ( cid ) + *cid = c; + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftdbgmem.c b/drivers/freetype/src/base/ftdbgmem.c new file mode 100644 index 0000000000..6fb86fe77d --- /dev/null +++ b/drivers/freetype/src/base/ftdbgmem.c @@ -0,0 +1,992 @@ +/***************************************************************************/ +/* */ +/* ftdbgmem.c */ +/* */ +/* Memory debugger (body). */ +/* */ +/* Copyright 2001-2006, 2009, 2013 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_CONFIG_CONFIG_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_MEMORY_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H + + +#ifdef FT_DEBUG_MEMORY + +#define KEEPALIVE /* `Keep alive' means that freed blocks aren't released + * to the heap. This is useful to detect double-frees + * or weird heap corruption, but it uses large amounts of + * memory, however. + */ + +#include FT_CONFIG_STANDARD_LIBRARY_H + + FT_BASE_DEF( const char* ) _ft_debug_file = 0; + FT_BASE_DEF( long ) _ft_debug_lineno = 0; + + extern void + FT_DumpMemory( FT_Memory memory ); + + + typedef struct FT_MemSourceRec_* FT_MemSource; + typedef struct FT_MemNodeRec_* FT_MemNode; + typedef struct FT_MemTableRec_* FT_MemTable; + + +#define FT_MEM_VAL( addr ) ((FT_PtrDist)(FT_Pointer)( addr )) + + /* + * This structure holds statistics for a single allocation/release + * site. This is useful to know where memory operations happen the + * most. + */ + typedef struct FT_MemSourceRec_ + { + const char* file_name; + long line_no; + + FT_Long cur_blocks; /* current number of allocated blocks */ + FT_Long max_blocks; /* max. number of allocated blocks */ + FT_Long all_blocks; /* total number of blocks allocated */ + + FT_Long cur_size; /* current cumulative allocated size */ + FT_Long max_size; /* maximum cumulative allocated size */ + FT_Long all_size; /* total cumulative allocated size */ + + FT_Long cur_max; /* current maximum allocated size */ + + FT_UInt32 hash; + FT_MemSource link; + + } FT_MemSourceRec; + + + /* + * We don't need a resizable array for the memory sources, because + * their number is pretty limited within FreeType. + */ +#define FT_MEM_SOURCE_BUCKETS 128 + + /* + * This structure holds information related to a single allocated + * memory block. If KEEPALIVE is defined, blocks that are freed by + * FreeType are never released to the system. Instead, their `size' + * field is set to -size. This is mainly useful to detect double frees, + * at the price of large memory footprint during execution. + */ + typedef struct FT_MemNodeRec_ + { + FT_Byte* address; + FT_Long size; /* < 0 if the block was freed */ + + FT_MemSource source; + +#ifdef KEEPALIVE + const char* free_file_name; + FT_Long free_line_no; +#endif + + FT_MemNode link; + + } FT_MemNodeRec; + + + /* + * The global structure, containing compound statistics and all hash + * tables. + */ + typedef struct FT_MemTableRec_ + { + FT_ULong size; + FT_ULong nodes; + FT_MemNode* buckets; + + FT_ULong alloc_total; + FT_ULong alloc_current; + FT_ULong alloc_max; + FT_ULong alloc_count; + + FT_Bool bound_total; + FT_ULong alloc_total_max; + + FT_Bool bound_count; + FT_ULong alloc_count_max; + + FT_MemSource sources[FT_MEM_SOURCE_BUCKETS]; + + FT_Bool keep_alive; + + FT_Memory memory; + FT_Pointer memory_user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + + } FT_MemTableRec; + + +#define FT_MEM_SIZE_MIN 7 +#define FT_MEM_SIZE_MAX 13845163 + +#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") + + + /* + * Prime numbers are ugly to handle. It would be better to implement + * L-Hashing, which is 10% faster and doesn't require divisions. + */ + static const FT_UInt ft_mem_primes[] = + { + 7, + 11, + 19, + 37, + 73, + 109, + 163, + 251, + 367, + 557, + 823, + 1237, + 1861, + 2777, + 4177, + 6247, + 9371, + 14057, + 21089, + 31627, + 47431, + 71143, + 106721, + 160073, + 240101, + 360163, + 540217, + 810343, + 1215497, + 1823231, + 2734867, + 4102283, + 6153409, + 9230113, + 13845163, + }; + + + static FT_ULong + ft_mem_closest_prime( FT_ULong num ) + { + FT_UInt i; + + + for ( i = 0; + i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ ) + if ( ft_mem_primes[i] > num ) + return ft_mem_primes[i]; + + return FT_MEM_SIZE_MAX; + } + + + extern void + ft_mem_debug_panic( const char* fmt, + ... ) + { + va_list ap; + + + printf( "FreeType.Debug: " ); + + va_start( ap, fmt ); + vprintf( fmt, ap ); + va_end( ap ); + + printf( "\n" ); + exit( EXIT_FAILURE ); + } + + + static FT_Pointer + ft_mem_table_alloc( FT_MemTable table, + FT_Long size ) + { + FT_Memory memory = table->memory; + FT_Pointer block; + + + memory->user = table->memory_user; + block = table->alloc( memory, size ); + memory->user = table; + + return block; + } + + + static void + ft_mem_table_free( FT_MemTable table, + FT_Pointer block ) + { + FT_Memory memory = table->memory; + + + memory->user = table->memory_user; + table->free( memory, block ); + memory->user = table; + } + + + static void + ft_mem_table_resize( FT_MemTable table ) + { + FT_ULong new_size; + + + new_size = ft_mem_closest_prime( table->nodes ); + if ( new_size != table->size ) + { + FT_MemNode* new_buckets; + FT_ULong i; + + + new_buckets = (FT_MemNode *) + ft_mem_table_alloc( table, + new_size * sizeof ( FT_MemNode ) ); + if ( new_buckets == NULL ) + return; + + FT_ARRAY_ZERO( new_buckets, new_size ); + + for ( i = 0; i < table->size; i++ ) + { + FT_MemNode node, next, *pnode; + FT_PtrDist hash; + + + node = table->buckets[i]; + while ( node ) + { + next = node->link; + hash = FT_MEM_VAL( node->address ) % new_size; + pnode = new_buckets + hash; + + node->link = pnode[0]; + pnode[0] = node; + + node = next; + } + } + + if ( table->buckets ) + ft_mem_table_free( table, table->buckets ); + + table->buckets = new_buckets; + table->size = new_size; + } + } + + + static FT_MemTable + ft_mem_table_new( FT_Memory memory ) + { + FT_MemTable table; + + + table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); + if ( table == NULL ) + goto Exit; + + FT_ZERO( table ); + + table->size = FT_MEM_SIZE_MIN; + table->nodes = 0; + + table->memory = memory; + + table->memory_user = memory->user; + + table->alloc = memory->alloc; + table->realloc = memory->realloc; + table->free = memory->free; + + table->buckets = (FT_MemNode *) + memory->alloc( memory, + table->size * sizeof ( FT_MemNode ) ); + if ( table->buckets ) + FT_ARRAY_ZERO( table->buckets, table->size ); + else + { + memory->free( memory, table ); + table = NULL; + } + + Exit: + return table; + } + + + static void + ft_mem_table_destroy( FT_MemTable table ) + { + FT_ULong i; + FT_Long leak_count = 0; + FT_ULong leaks = 0; + + + FT_DumpMemory( table->memory ); + + /* remove all blocks from the table, revealing leaked ones */ + for ( i = 0; i < table->size; i++ ) + { + FT_MemNode *pnode = table->buckets + i, next, node = *pnode; + + + while ( node ) + { + next = node->link; + node->link = 0; + + if ( node->size > 0 ) + { + printf( + "leaked memory block at address %p, size %8ld in (%s:%ld)\n", + node->address, node->size, + FT_FILENAME( node->source->file_name ), + node->source->line_no ); + + leak_count++; + leaks += node->size; + + ft_mem_table_free( table, node->address ); + } + + node->address = NULL; + node->size = 0; + + ft_mem_table_free( table, node ); + node = next; + } + table->buckets[i] = 0; + } + + ft_mem_table_free( table, table->buckets ); + table->buckets = NULL; + + table->size = 0; + table->nodes = 0; + + /* remove all sources */ + for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ ) + { + FT_MemSource source, next; + + + for ( source = table->sources[i]; source != NULL; source = next ) + { + next = source->link; + ft_mem_table_free( table, source ); + } + + table->sources[i] = NULL; + } + + printf( "FreeType: total memory allocations = %ld\n", + table->alloc_total ); + printf( "FreeType: maximum memory footprint = %ld\n", + table->alloc_max ); + + ft_mem_table_free( table, table ); + + if ( leak_count > 0 ) + ft_mem_debug_panic( + "FreeType: %ld bytes of memory leaked in %ld blocks\n", + leaks, leak_count ); + + printf( "FreeType: no memory leaks detected\n" ); + } + + + static FT_MemNode* + ft_mem_table_get_nodep( FT_MemTable table, + FT_Byte* address ) + { + FT_PtrDist hash; + FT_MemNode *pnode, node; + + + hash = FT_MEM_VAL( address ); + pnode = table->buckets + ( hash % table->size ); + + for (;;) + { + node = pnode[0]; + if ( !node ) + break; + + if ( node->address == address ) + break; + + pnode = &node->link; + } + return pnode; + } + + + static FT_MemSource + ft_mem_table_get_source( FT_MemTable table ) + { + FT_UInt32 hash; + FT_MemSource node, *pnode; + + + /* 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]; + + for ( ;; ) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->file_name == _ft_debug_file && + node->line_no == _ft_debug_lineno ) + goto Exit; + + pnode = &node->link; + } + + node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); + if ( node == NULL ) + ft_mem_debug_panic( + "not enough memory to perform memory debugging\n" ); + + node->file_name = _ft_debug_file; + node->line_no = _ft_debug_lineno; + + node->cur_blocks = 0; + node->max_blocks = 0; + node->all_blocks = 0; + + node->cur_size = 0; + node->max_size = 0; + node->all_size = 0; + + node->cur_max = 0; + + node->link = NULL; + node->hash = hash; + *pnode = node; + + Exit: + return node; + } + + + static void + ft_mem_table_set( FT_MemTable table, + FT_Byte* address, + FT_ULong size, + FT_Long delta ) + { + FT_MemNode *pnode, node; + + + if ( table ) + { + FT_MemSource source; + + + pnode = ft_mem_table_get_nodep( table, address ); + node = *pnode; + if ( node ) + { + if ( node->size < 0 ) + { + /* This block was already freed. Our memory is now completely */ + /* corrupted! */ + /* This can only happen in keep-alive mode. */ + ft_mem_debug_panic( + "memory heap corrupted (allocating freed block)" ); + } + else + { + /* This block was already allocated. This means that our memory */ + /* is also corrupted! */ + ft_mem_debug_panic( + "memory heap corrupted (re-allocating allocated block at" + " %p, of size %ld)\n" + "org=%s:%d new=%s:%d\n", + node->address, node->size, + FT_FILENAME( node->source->file_name ), node->source->line_no, + FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); + } + } + + /* we need to create a new node in this table */ + node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); + if ( node == NULL ) + ft_mem_debug_panic( "not enough memory to run memory tests" ); + + node->address = address; + node->size = size; + node->source = source = ft_mem_table_get_source( table ); + + if ( delta == 0 ) + { + /* this is an allocation */ + source->all_blocks++; + source->cur_blocks++; + if ( source->cur_blocks > source->max_blocks ) + source->max_blocks = source->cur_blocks; + } + + if ( size > (FT_ULong)source->cur_max ) + source->cur_max = size; + + if ( delta != 0 ) + { + /* we are growing or shrinking a reallocated block */ + source->cur_size += delta; + table->alloc_current += delta; + } + else + { + /* we are allocating a new block */ + source->cur_size += size; + table->alloc_current += size; + } + + source->all_size += size; + + if ( source->cur_size > source->max_size ) + source->max_size = source->cur_size; + + node->free_file_name = NULL; + node->free_line_no = 0; + + node->link = pnode[0]; + + pnode[0] = node; + table->nodes++; + + table->alloc_total += size; + + if ( table->alloc_current > table->alloc_max ) + table->alloc_max = table->alloc_current; + + if ( table->nodes * 3 < table->size || + table->size * 3 < table->nodes ) + ft_mem_table_resize( table ); + } + } + + + static void + ft_mem_table_remove( FT_MemTable table, + FT_Byte* address, + FT_Long delta ) + { + if ( table ) + { + FT_MemNode *pnode, node; + + + pnode = ft_mem_table_get_nodep( table, address ); + node = *pnode; + if ( node ) + { + FT_MemSource source; + + + if ( node->size < 0 ) + ft_mem_debug_panic( + "freeing memory block at %p more than once at (%s:%ld)\n" + "block allocated at (%s:%ld) and released at (%s:%ld)", + address, + FT_FILENAME( _ft_debug_file ), _ft_debug_lineno, + FT_FILENAME( node->source->file_name ), node->source->line_no, + FT_FILENAME( node->free_file_name ), node->free_line_no ); + + /* scramble the node's content for additional safety */ + FT_MEM_SET( address, 0xF3, node->size ); + + if ( delta == 0 ) + { + source = node->source; + + source->cur_blocks--; + source->cur_size -= node->size; + + table->alloc_current -= node->size; + } + + if ( table->keep_alive ) + { + /* we simply invert the node's size to indicate that the node */ + /* was freed. */ + node->size = -node->size; + node->free_file_name = _ft_debug_file; + node->free_line_no = _ft_debug_lineno; + } + else + { + table->nodes--; + + *pnode = node->link; + + node->size = 0; + node->source = NULL; + + ft_mem_table_free( table, node ); + + if ( table->nodes * 3 < table->size || + table->size * 3 < table->nodes ) + ft_mem_table_resize( table ); + } + } + else + ft_mem_debug_panic( + "trying to free unknown block at %p in (%s:%ld)\n", + address, + FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); + } + } + + + extern FT_Pointer + ft_mem_debug_alloc( FT_Memory memory, + FT_Long size ) + { + FT_MemTable table = (FT_MemTable)memory->user; + FT_Byte* block; + + + if ( size <= 0 ) + ft_mem_debug_panic( "negative block size allocation (%ld)", size ); + + /* return NULL if the maximum number of allocations was reached */ + if ( table->bound_count && + table->alloc_count >= table->alloc_count_max ) + return NULL; + + /* return NULL if this allocation would overflow the maximum heap size */ + if ( table->bound_total && + table->alloc_total_max - table->alloc_current > (FT_ULong)size ) + return NULL; + + block = (FT_Byte *)ft_mem_table_alloc( table, size ); + if ( block ) + { + ft_mem_table_set( table, block, (FT_ULong)size, 0 ); + + table->alloc_count++; + } + + _ft_debug_file = "<unknown>"; + _ft_debug_lineno = 0; + + return (FT_Pointer)block; + } + + + extern void + ft_mem_debug_free( FT_Memory memory, + FT_Pointer block ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( block == NULL ) + ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", + FT_FILENAME( _ft_debug_file ), + _ft_debug_lineno ); + + ft_mem_table_remove( table, (FT_Byte*)block, 0 ); + + if ( !table->keep_alive ) + ft_mem_table_free( table, block ); + + table->alloc_count--; + + _ft_debug_file = "<unknown>"; + _ft_debug_lineno = 0; + } + + + extern FT_Pointer + ft_mem_debug_realloc( FT_Memory memory, + FT_Long cur_size, + FT_Long new_size, + FT_Pointer block ) + { + FT_MemTable table = (FT_MemTable)memory->user; + FT_MemNode node, *pnode; + FT_Pointer new_block; + FT_Long delta; + + const char* file_name = FT_FILENAME( _ft_debug_file ); + FT_Long line_no = _ft_debug_lineno; + + + /* unlikely, but possible */ + if ( new_size == cur_size ) + return block; + + /* the following is valid according to ANSI C */ +#if 0 + if ( block == NULL || cur_size == 0 ) + ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", + file_name, line_no ); +#endif + + /* while the following is allowed in ANSI C also, we abort since */ + /* such case should be handled by FreeType. */ + if ( new_size <= 0 ) + ft_mem_debug_panic( + "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)", + block, cur_size, file_name, line_no ); + + /* check `cur_size' value */ + pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block ); + node = *pnode; + if ( !node ) + ft_mem_debug_panic( + "trying to reallocate unknown block at %p in (%s:%ld)", + block, file_name, line_no ); + + if ( node->size <= 0 ) + ft_mem_debug_panic( + "trying to reallocate freed block at %p in (%s:%ld)", + block, file_name, line_no ); + + if ( node->size != cur_size ) + ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is " + "%ld instead of %ld in (%s:%ld)", + block, cur_size, node->size, file_name, line_no ); + + /* return NULL if the maximum number of allocations was reached */ + if ( table->bound_count && + table->alloc_count >= table->alloc_count_max ) + return NULL; + + delta = (FT_Long)( new_size - cur_size ); + + /* return NULL if this allocation would overflow the maximum heap size */ + if ( delta > 0 && + table->bound_total && + table->alloc_current + (FT_ULong)delta > table->alloc_total_max ) + return NULL; + + new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size ); + if ( new_block == NULL ) + return NULL; + + ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); + + ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); + + ft_mem_table_remove( table, (FT_Byte*)block, delta ); + + _ft_debug_file = "<unknown>"; + _ft_debug_lineno = 0; + + if ( !table->keep_alive ) + ft_mem_table_free( table, block ); + + return new_block; + } + + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ) + { + FT_MemTable table; + FT_Int result = 0; + + + if ( getenv( "FT2_DEBUG_MEMORY" ) ) + { + table = ft_mem_table_new( memory ); + if ( table ) + { + const char* p; + + + memory->user = table; + memory->alloc = ft_mem_debug_alloc; + memory->realloc = ft_mem_debug_realloc; + memory->free = ft_mem_debug_free; + + p = getenv( "FT2_ALLOC_TOTAL_MAX" ); + if ( p != NULL ) + { + FT_Long total_max = ft_atol( p ); + + + if ( total_max > 0 ) + { + table->bound_total = 1; + table->alloc_total_max = (FT_ULong)total_max; + } + } + + p = getenv( "FT2_ALLOC_COUNT_MAX" ); + if ( p != NULL ) + { + FT_Long total_count = ft_atol( p ); + + + if ( total_count > 0 ) + { + table->bound_count = 1; + table->alloc_count_max = (FT_ULong)total_count; + } + } + + p = getenv( "FT2_KEEP_ALIVE" ); + if ( p != NULL ) + { + FT_Long keep_alive = ft_atol( p ); + + + if ( keep_alive > 0 ) + table->keep_alive = 1; + } + + result = 1; + } + } + return result; + } + + + extern void + ft_mem_debug_done( FT_Memory memory ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( table ) + { + memory->free = table->free; + memory->realloc = table->realloc; + memory->alloc = table->alloc; + + ft_mem_table_destroy( table ); + memory->user = NULL; + } + } + + + + static int + ft_mem_source_compare( const void* p1, + const void* p2 ) + { + FT_MemSource s1 = *(FT_MemSource*)p1; + FT_MemSource s2 = *(FT_MemSource*)p2; + + + if ( s2->max_size > s1->max_size ) + return 1; + else if ( s2->max_size < s1->max_size ) + return -1; + else + return 0; + } + + + extern void + FT_DumpMemory( FT_Memory memory ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( table ) + { + FT_MemSource* bucket = table->sources; + FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; + FT_MemSource* sources; + FT_UInt nn, count; + const char* fmt; + + + count = 0; + for ( ; bucket < limit; bucket++ ) + { + FT_MemSource source = *bucket; + + + for ( ; source; source = source->link ) + count++; + } + + sources = (FT_MemSource*)ft_mem_table_alloc( + table, sizeof ( *sources ) * count ); + + count = 0; + for ( bucket = table->sources; bucket < limit; bucket++ ) + { + FT_MemSource source = *bucket; + + + for ( ; source; source = source->link ) + sources[count++] = source; + } + + ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare ); + + printf( "FreeType Memory Dump: " + "current=%ld max=%ld total=%ld count=%ld\n", + table->alloc_current, table->alloc_max, + table->alloc_total, table->alloc_count ); + printf( " block block sizes sizes sizes source\n" ); + printf( " count high sum highsum max location\n" ); + printf( "-------------------------------------------------\n" ); + + fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n"; + + for ( nn = 0; nn < count; nn++ ) + { + FT_MemSource source = sources[nn]; + + + printf( fmt, + source->cur_blocks, source->max_blocks, + source->cur_size, source->max_size, source->cur_max, + FT_FILENAME( source->file_name ), + source->line_no ); + } + printf( "------------------------------------------------\n" ); + + ft_mem_table_free( table, sources ); + } + } + +#else /* !FT_DEBUG_MEMORY */ + + /* ANSI C doesn't like empty source files */ + typedef int _debug_mem_dummy; + +#endif /* !FT_DEBUG_MEMORY */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftdebug.c b/drivers/freetype/src/base/ftdebug.c new file mode 100644 index 0000000000..b9156d15ee --- /dev/null +++ b/drivers/freetype/src/base/ftdebug.c @@ -0,0 +1,266 @@ +/***************************************************************************/ +/* */ +/* ftdebug.c */ +/* */ +/* Debugging and logging component (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2008, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This component contains various macros and functions used to ease the */ + /* debugging of the FreeType engine. Its main purpose is in assertion */ + /* checking, tracing, and error detection. */ + /* */ + /* There are now three debugging modes: */ + /* */ + /* - trace mode */ + /* */ + /* Error and trace messages are sent to the log file (which can be the */ + /* standard error output). */ + /* */ + /* - error mode */ + /* */ + /* Only error messages are generated. */ + /* */ + /* - release mode: */ + /* */ + /* No error message is sent or generated. The code is free from any */ + /* debugging parts. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H + + +#ifdef FT_DEBUG_LEVEL_ERROR + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( void ) + FT_Message( const char* fmt, + ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + } + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( void ) + FT_Panic( const char* fmt, + ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + + exit( EXIT_FAILURE ); + } + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( int ) + FT_Throw( FT_Error error, + int line, + const char* file ) + { + FT_UNUSED( error ); + FT_UNUSED( line ); + FT_UNUSED( file ); + + return 0; + } + +#endif /* FT_DEBUG_LEVEL_ERROR */ + + + +#ifdef FT_DEBUG_LEVEL_TRACE + + /* array of trace levels, initialized to 0 */ + int ft_trace_levels[trace_count]; + + + /* define array of trace toggle names */ +#define FT_TRACE_DEF( x ) #x , + + static const char* ft_trace_toggles[trace_count + 1] = + { +#include FT_INTERNAL_TRACE_H + NULL + }; + +#undef FT_TRACE_DEF + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( FT_Int ) + FT_Trace_Get_Count( void ) + { + return trace_count; + } + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( const char * ) + FT_Trace_Get_Name( FT_Int idx ) + { + int max = FT_Trace_Get_Count(); + + + if ( idx < max ) + return ft_trace_toggles[idx]; + else + return NULL; + } + + + /*************************************************************************/ + /* */ + /* Initialize the tracing sub-system. This is done by retrieving the */ + /* value of the `FT2_DEBUG' environment variable. It must be a list of */ + /* toggles, separated by spaces, `;', or `,'. Example: */ + /* */ + /* export FT2_DEBUG="any:3 memory:7 stream:5" */ + /* */ + /* This requests that all levels be set to 3, except the trace level for */ + /* the memory and stream components which are set to 7 and 5, */ + /* respectively. */ + /* */ + /* See the file <include/freetype/internal/fttrace.h> for details of the */ + /* available toggle names. */ + /* */ + /* The level must be between 0 and 7; 0 means quiet (except for serious */ + /* runtime errors), and 7 means _very_ verbose. */ + /* */ + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + const char* ft2_debug = getenv( "FT2_DEBUG" ); + + + if ( ft2_debug ) + { + const char* p = ft2_debug; + const char* q; + + + for ( ; *p; p++ ) + { + /* skip leading whitespace and separators */ + if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) + continue; + + /* read toggle name, followed by ':' */ + q = p; + while ( *p && *p != ':' ) + p++; + + if ( !*p ) + break; + + if ( *p == ':' && p > q ) + { + FT_Int n, i, len = (FT_Int)( p - q ); + FT_Int level = -1, found = -1; + + + for ( n = 0; n < trace_count; n++ ) + { + const char* toggle = ft_trace_toggles[n]; + + + for ( i = 0; i < len; i++ ) + { + if ( toggle[i] != q[i] ) + break; + } + + if ( i == len && toggle[i] == 0 ) + { + found = n; + break; + } + } + + /* read level */ + p++; + if ( *p ) + { + level = *p - '0'; + if ( level < 0 || level > 7 ) + level = -1; + } + + if ( found >= 0 && level >= 0 ) + { + if ( found == trace_any ) + { + /* special case for `any' */ + for ( n = 0; n < trace_count; n++ ) + ft_trace_levels[n] = level; + } + else + ft_trace_levels[found] = level; + } + } + } + } + } + + +#else /* !FT_DEBUG_LEVEL_TRACE */ + + + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + /* nothing */ + } + + + FT_BASE_DEF( FT_Int ) + FT_Trace_Get_Count( void ) + { + return 0; + } + + + FT_BASE_DEF( const char * ) + FT_Trace_Get_Name( FT_Int idx ) + { + FT_UNUSED( idx ); + + return NULL; + } + + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftfstype.c b/drivers/freetype/src/base/ftfstype.c new file mode 100644 index 0000000000..d0ef7b7c1b --- /dev/null +++ b/drivers/freetype/src/base/ftfstype.c @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* ftfstype.c */ +/* */ +/* FreeType utility file to access FSType data (body). */ +/* */ +/* Copyright 2008, 2009 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_TYPE1_TABLES_H +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ) + { + TT_OS2* os2; + + + /* first, try to get the fs_type directly from the font */ + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_extra ) + { + PS_FontExtraRec extra; + + + if ( !service->ps_get_font_extra( face, &extra ) && + extra.fs_type != 0 ) + return extra.fs_type; + } + } + + /* look at FSType before fsType for Type42 */ + + if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL && + os2->version != 0xFFFFU ) + return os2->fsType; + + return 0; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftgasp.c b/drivers/freetype/src/base/ftgasp.c new file mode 100644 index 0000000000..8485d29259 --- /dev/null +++ b/drivers/freetype/src/base/ftgasp.c @@ -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 */ diff --git a/drivers/freetype/src/base/ftgloadr.c b/drivers/freetype/src/base/ftgloadr.c new file mode 100644 index 0000000000..3cc5c7a805 --- /dev/null +++ b/drivers/freetype/src/base/ftgloadr.c @@ -0,0 +1,405 @@ +/***************************************************************************/ +/* */ +/* ftgloadr.c */ +/* */ +/* The FreeType glyph loader (body). */ +/* */ +/* Copyright 2002-2006, 2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_GLYPH_LOADER_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H + +#undef FT_COMPONENT +#define FT_COMPONENT trace_gloader + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** G L Y P H L O A D E R *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* The glyph loader is a simple object which is used to load a set of */ + /* glyphs easily. It is critical for the correct loading of composites. */ + /* */ + /* Ideally, one can see it as a stack of abstract `glyph' objects. */ + /* */ + /* loader.base Is really the bottom of the stack. It describes a */ + /* single glyph image made of the juxtaposition of */ + /* several glyphs (those `in the stack'). */ + /* */ + /* loader.current Describes the top of the stack, on which a new */ + /* glyph can be loaded. */ + /* */ + /* Rewind Clears the stack. */ + /* Prepare Set up `loader.current' for addition of a new glyph */ + /* image. */ + /* Add Add the `current' glyph image to the `base' one, */ + /* and prepare for another one. */ + /* */ + /* The glyph loader is now a base object. Each driver used to */ + /* re-implement it in one way or the other, which wasted code and */ + /* energy. */ + /* */ + /*************************************************************************/ + + + /* create a new glyph loader */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader *aloader ) + { + FT_GlyphLoader loader = NULL; + FT_Error error; + + + if ( !FT_NEW( loader ) ) + { + loader->memory = memory; + *aloader = loader; + } + return error; + } + + + /* rewind the glyph loader - reset counters to 0 */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Rewind( FT_GlyphLoader loader ) + { + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + base->outline.n_points = 0; + base->outline.n_contours = 0; + base->num_subglyphs = 0; + + *current = *base; + } + + + /* reset the glyph loader, frees all allocated tables */ + /* and starts from zero */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Reset( FT_GlyphLoader loader ) + { + FT_Memory memory = loader->memory; + + + FT_FREE( loader->base.outline.points ); + FT_FREE( loader->base.outline.tags ); + FT_FREE( loader->base.outline.contours ); + 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; + + FT_GlyphLoader_Rewind( loader ); + } + + + /* delete a glyph loader */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Done( FT_GlyphLoader loader ) + { + if ( loader ) + { + FT_Memory memory = loader->memory; + + + FT_GlyphLoader_Reset( loader ); + FT_FREE( loader ); + } + } + + + /* re-adjust the `current' outline fields */ + static void + FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader ) + { + FT_Outline* base = &loader->base.outline; + FT_Outline* current = &loader->current.outline; + + + current->points = base->points + base->n_points; + current->tags = base->tags + base->n_points; + current->contours = base->contours + base->n_contours; + + /* handle extra points table - if any */ + if ( loader->use_extra ) + { + loader->current.extra_points = loader->base.extra_points + + base->n_points; + + loader->current.extra_points2 = loader->base.extra_points2 + + base->n_points; + } + } + + + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ) + { + FT_Error error; + FT_Memory memory = loader->memory; + + + if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) ) + { + loader->use_extra = 1; + loader->base.extra_points2 = loader->base.extra_points + + loader->max_points; + + FT_GlyphLoader_Adjust_Points( loader ); + } + return error; + } + + + /* re-adjust the `current' subglyphs field */ + static void + FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader ) + { + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + current->subglyphs = base->subglyphs + base->num_subglyphs; + } + + + /* Ensure that we can add `n_points' and `n_contours' to our glyph. */ + /* This function reallocates its outline tables if necessary. Note that */ + /* it DOESN'T change the number of points within the loader! */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, + FT_UInt n_points, + FT_UInt n_contours ) + { + FT_Memory memory = loader->memory; + FT_Error error = FT_Err_Ok; + FT_Outline* base = &loader->base.outline; + FT_Outline* current = &loader->current.outline; + FT_Bool adjust = 0; + + FT_UInt new_max, old_max; + + + /* check points & tags */ + new_max = base->n_points + current->n_points + n_points; + old_max = loader->max_points; + + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 8 ); + + if ( new_max > FT_OUTLINE_POINTS_MAX ) + return FT_THROW( Array_Too_Large ); + + if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || + FT_RENEW_ARRAY( base->tags, 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; + } + + /* check contours */ + old_max = loader->max_contours; + new_max = base->n_contours + current->n_contours + + n_contours; + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 4 ); + + if ( new_max > FT_OUTLINE_CONTOURS_MAX ) + return FT_THROW( Array_Too_Large ); + + if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) + goto Exit; + + adjust = 1; + loader->max_contours = new_max; + } + + if ( adjust ) + FT_GlyphLoader_Adjust_Points( loader ); + + Exit: + if ( error ) + FT_GlyphLoader_Reset( loader ); + + return error; + } + + + /* Ensure that we can add `n_subglyphs' to our glyph. this function */ + /* reallocates its subglyphs table if necessary. Note that it DOES */ + /* NOT change the number of subglyphs within the loader! */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, + FT_UInt n_subs ) + { + FT_Memory memory = loader->memory; + FT_Error error = FT_Err_Ok; + FT_UInt new_max, old_max; + + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + new_max = base->num_subglyphs + current->num_subglyphs + n_subs; + old_max = loader->max_subglyphs; + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 2 ); + if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) ) + goto Exit; + + loader->max_subglyphs = new_max; + + FT_GlyphLoader_Adjust_Subglyphs( loader ); + } + + Exit: + return error; + } + + + /* prepare loader for the addition of a new glyph on top of the base one */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Prepare( FT_GlyphLoader loader ) + { + FT_GlyphLoad current = &loader->current; + + + current->outline.n_points = 0; + current->outline.n_contours = 0; + current->num_subglyphs = 0; + + FT_GlyphLoader_Adjust_Points ( loader ); + FT_GlyphLoader_Adjust_Subglyphs( loader ); + } + + + /* add current glyph to the base image -- and prepare for another */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Add( FT_GlyphLoader loader ) + { + FT_GlyphLoad base; + FT_GlyphLoad current; + + FT_UInt n_curr_contours; + FT_UInt n_base_points; + FT_UInt n; + + + if ( !loader ) + return; + + base = &loader->base; + current = &loader->current; + + n_curr_contours = current->outline.n_contours; + n_base_points = base->outline.n_points; + + base->outline.n_points = + (short)( base->outline.n_points + current->outline.n_points ); + base->outline.n_contours = + (short)( base->outline.n_contours + current->outline.n_contours ); + + base->num_subglyphs += current->num_subglyphs; + + /* adjust contours count in newest outline */ + for ( n = 0; n < n_curr_contours; n++ ) + current->outline.contours[n] = + (short)( current->outline.contours[n] + n_base_points ); + + /* prepare for another new glyph image */ + FT_GlyphLoader_Prepare( loader ); + } + + + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, + FT_GlyphLoader source ) + { + FT_Error error; + FT_UInt num_points = source->base.outline.n_points; + FT_UInt num_contours = source->base.outline.n_contours; + + + error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); + if ( !error ) + { + FT_Outline* out = &target->base.outline; + FT_Outline* in = &source->base.outline; + + + FT_ARRAY_COPY( out->points, in->points, + num_points ); + FT_ARRAY_COPY( out->tags, in->tags, + num_points ); + FT_ARRAY_COPY( out->contours, in->contours, + num_contours ); + + /* 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; + + FT_GlyphLoader_Adjust_Points( target ); + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftglyph.c b/drivers/freetype/src/base/ftglyph.c new file mode 100644 index 0000000000..5dd28a8c52 --- /dev/null +++ b/drivers/freetype/src/base/ftglyph.c @@ -0,0 +1,629 @@ +/***************************************************************************/ +/* */ +/* ftglyph.c */ +/* */ +/* FreeType convenience functions to handle glyphs (body). */ +/* */ +/* Copyright 1996-2005, 2007, 2008, 2010, 2012, 2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This file contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_GLYPH_H +#include FT_OUTLINE_H +#include FT_BITMAP_H +#include FT_INTERNAL_OBJECTS_H + +#include "basepic.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_glyph + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_BitmapGlyph support ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Error ) + ft_bitmap_glyph_init( FT_Glyph bitmap_glyph, + FT_GlyphSlot slot ) + { + FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; + FT_Error error = FT_Err_Ok; + FT_Library library = FT_GLYPH( glyph )->library; + + + if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) + { + error = FT_THROW( Invalid_Glyph_Format ); + goto Exit; + } + + glyph->left = slot->bitmap_left; + glyph->top = slot->bitmap_top; + + /* do lazy copying whenever possible */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + glyph->bitmap = slot->bitmap; + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + else + { + FT_Bitmap_New( &glyph->bitmap ); + error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap ); + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + ft_bitmap_glyph_copy( FT_Glyph bitmap_source, + FT_Glyph bitmap_target ) + { + FT_Library library = bitmap_source->library; + FT_BitmapGlyph source = (FT_BitmapGlyph)bitmap_source; + FT_BitmapGlyph target = (FT_BitmapGlyph)bitmap_target; + + + target->left = source->left; + target->top = source->top; + + return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap ); + } + + + FT_CALLBACK_DEF( void ) + ft_bitmap_glyph_done( FT_Glyph bitmap_glyph ) + { + FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; + FT_Library library = FT_GLYPH( glyph )->library; + + + FT_Bitmap_Done( library, &glyph->bitmap ); + } + + + FT_CALLBACK_DEF( void ) + ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph, + FT_BBox* cbox ) + { + FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; + + + cbox->xMin = glyph->left << 6; + cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); + cbox->yMax = glyph->top << 6; + cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); + } + + + FT_DEFINE_GLYPH(ft_bitmap_glyph_class, + sizeof ( FT_BitmapGlyphRec ), + FT_GLYPH_FORMAT_BITMAP, + + ft_bitmap_glyph_init, + ft_bitmap_glyph_done, + ft_bitmap_glyph_copy, + 0, /* FT_Glyph_TransformFunc */ + ft_bitmap_glyph_bbox, + 0 /* FT_Glyph_PrepareFunc */ + ) + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_OutlineGlyph support ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_Error ) + ft_outline_glyph_init( FT_Glyph outline_glyph, + FT_GlyphSlot slot ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + FT_Error error = FT_Err_Ok; + FT_Library library = FT_GLYPH( glyph )->library; + FT_Outline* source = &slot->outline; + FT_Outline* target = &glyph->outline; + + + /* check format in glyph slot */ + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + { + error = FT_THROW( Invalid_Glyph_Format ); + goto Exit; + } + + /* allocate new outline */ + error = FT_Outline_New( library, source->n_points, source->n_contours, + &glyph->outline ); + if ( error ) + goto Exit; + + FT_Outline_Copy( source, target ); + + Exit: + return error; + } + + + FT_CALLBACK_DEF( void ) + ft_outline_glyph_done( FT_Glyph outline_glyph ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + + + FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ft_outline_glyph_copy( FT_Glyph outline_source, + FT_Glyph outline_target ) + { + FT_OutlineGlyph source = (FT_OutlineGlyph)outline_source; + FT_OutlineGlyph target = (FT_OutlineGlyph)outline_target; + FT_Error error; + FT_Library library = FT_GLYPH( source )->library; + + + error = FT_Outline_New( library, source->outline.n_points, + source->outline.n_contours, &target->outline ); + if ( !error ) + FT_Outline_Copy( &source->outline, &target->outline ); + + return error; + } + + + FT_CALLBACK_DEF( void ) + ft_outline_glyph_transform( FT_Glyph outline_glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + + + if ( matrix ) + FT_Outline_Transform( &glyph->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &glyph->outline, delta->x, delta->y ); + } + + + FT_CALLBACK_DEF( void ) + ft_outline_glyph_bbox( FT_Glyph outline_glyph, + FT_BBox* bbox ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + + + FT_Outline_Get_CBox( &glyph->outline, bbox ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ft_outline_glyph_prepare( FT_Glyph outline_glyph, + FT_GlyphSlot slot ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + + + slot->format = FT_GLYPH_FORMAT_OUTLINE; + slot->outline = glyph->outline; + slot->outline.flags &= ~FT_OUTLINE_OWNER; + + return FT_Err_Ok; + } + + + FT_DEFINE_GLYPH( ft_outline_glyph_class, + sizeof ( FT_OutlineGlyphRec ), + FT_GLYPH_FORMAT_OUTLINE, + + ft_outline_glyph_init, + ft_outline_glyph_done, + ft_outline_glyph_copy, + ft_outline_glyph_transform, + ft_outline_glyph_bbox, + ft_outline_glyph_prepare + ) + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_Glyph class and API ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + ft_new_glyph( FT_Library library, + const FT_Glyph_Class* clazz, + FT_Glyph* aglyph ) + { + FT_Memory memory = library->memory; + FT_Error error; + FT_Glyph glyph = NULL; + + + *aglyph = 0; + + if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) + { + glyph->library = library; + glyph->clazz = clazz; + glyph->format = clazz->glyph_format; + + *aglyph = glyph; + } + + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ) + { + FT_Glyph copy; + FT_Error error; + const FT_Glyph_Class* clazz; + + + /* check arguments */ + if ( !target ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + *target = 0; + + if ( !source || !source->clazz ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + clazz = source->clazz; + error = ft_new_glyph( source->library, clazz, © ); + if ( error ) + goto Exit; + + copy->advance = source->advance; + copy->format = source->format; + + if ( clazz->glyph_copy ) + error = clazz->glyph_copy( source, copy ); + + if ( error ) + FT_Done_Glyph( copy ); + else + *target = copy; + + Exit: + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ) + { + FT_Library library; + FT_Error error; + FT_Glyph glyph; + + const FT_Glyph_Class* clazz = 0; + + + if ( !slot ) + return FT_THROW( Invalid_Slot_Handle ); + + library = slot->library; + + if ( !aglyph ) + return FT_THROW( Invalid_Argument ); + + /* if it is a bitmap, that's easy :-) */ + if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) + clazz = FT_BITMAP_GLYPH_CLASS_GET; + + /* if it is an outline */ + else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + clazz = FT_OUTLINE_GLYPH_CLASS_GET; + + else + { + /* try to find a renderer that supports the glyph image format */ + FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); + + + if ( render ) + clazz = &render->glyph_class; + } + + if ( !clazz ) + { + error = FT_THROW( Invalid_Glyph_Format ); + goto Exit; + } + + /* create FT_Glyph object */ + error = ft_new_glyph( library, clazz, &glyph ); + if ( error ) + goto Exit; + + /* copy advance while converting it to 16.16 format */ + glyph->advance.x = slot->advance.x << 10; + glyph->advance.y = slot->advance.y << 10; + + /* now import the image from the glyph slot */ + error = clazz->glyph_init( glyph, slot ); + + /* if an error occurred, destroy the glyph */ + if ( error ) + FT_Done_Glyph( glyph ); + else + *aglyph = glyph; + + Exit: + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ) + { + const FT_Glyph_Class* clazz; + FT_Error error = FT_Err_Ok; + + + if ( !glyph || !glyph->clazz ) + error = FT_THROW( Invalid_Argument ); + else + { + clazz = glyph->clazz; + if ( clazz->glyph_transform ) + { + /* transform glyph image */ + clazz->glyph_transform( glyph, matrix, delta ); + + /* transform advance vector */ + if ( matrix ) + FT_Vector_Transform( &glyph->advance, matrix ); + } + else + error = FT_THROW( Invalid_Glyph_Format ); + } + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ) + { + const FT_Glyph_Class* clazz; + + + if ( !acbox ) + return; + + acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0; + + if ( !glyph || !glyph->clazz ) + return; + else + { + clazz = glyph->clazz; + if ( !clazz->glyph_bbox ) + return; + else + { + /* retrieve bbox in 26.6 coordinates */ + clazz->glyph_bbox( glyph, acbox ); + + /* perform grid fitting if needed */ + if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) + { + acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); + acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); + acbox->xMax = FT_PIX_CEIL( acbox->xMax ); + acbox->yMax = FT_PIX_CEIL( acbox->yMax ); + } + + /* convert to integer pixels if needed */ + if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) + { + acbox->xMin >>= 6; + acbox->yMin >>= 6; + acbox->xMax >>= 6; + acbox->yMax >>= 6; + } + } + } + return; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ) + { + FT_GlyphSlotRec dummy; + FT_GlyphSlot_InternalRec dummy_internal; + FT_Error error = FT_Err_Ok; + FT_Glyph b, glyph; + FT_BitmapGlyph bitmap = NULL; + const FT_Glyph_Class* clazz; + + /* FT_BITMAP_GLYPH_CLASS_GET derefers `library' in PIC mode */ + FT_Library library; + + + /* check argument */ + if ( !the_glyph ) + goto Bad; + glyph = *the_glyph; + if ( !glyph ) + goto Bad; + + clazz = glyph->clazz; + library = glyph->library; + if ( !library || !clazz ) + goto Bad; + + /* when called with a bitmap glyph, do nothing and return successfully */ + if ( clazz == FT_BITMAP_GLYPH_CLASS_GET ) + goto Exit; + + if ( !clazz->glyph_prepare ) + goto Bad; + + /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ + /* then calling FT_Render_Glyph_Internal() */ + + FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); + FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); + dummy.internal = &dummy_internal; + dummy.library = library; + dummy.format = clazz->glyph_format; + + /* create result bitmap glyph */ + error = ft_new_glyph( library, FT_BITMAP_GLYPH_CLASS_GET, &b ); + if ( error ) + goto Exit; + bitmap = (FT_BitmapGlyph)b; + +#if 1 + /* if `origin' is set, translate the glyph image */ + if ( origin ) + FT_Glyph_Transform( glyph, 0, origin ); +#else + FT_UNUSED( origin ); +#endif + + /* prepare dummy slot for rendering */ + error = clazz->glyph_prepare( glyph, &dummy ); + if ( !error ) + error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); + +#if 1 + if ( !destroy && origin ) + { + FT_Vector v; + + + v.x = -origin->x; + v.y = -origin->y; + FT_Glyph_Transform( glyph, 0, &v ); + } +#endif + + if ( error ) + goto Exit; + + /* in case of success, copy the bitmap to the glyph bitmap */ + error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy ); + if ( error ) + goto Exit; + + /* copy advance */ + bitmap->root.advance = glyph->advance; + + if ( destroy ) + FT_Done_Glyph( glyph ); + + *the_glyph = FT_GLYPH( bitmap ); + + Exit: + if ( error && bitmap ) + FT_Done_Glyph( FT_GLYPH( bitmap ) ); + + return error; + + Bad: + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Done_Glyph( FT_Glyph glyph ) + { + if ( glyph ) + { + FT_Memory memory = glyph->library->memory; + const FT_Glyph_Class* clazz = glyph->clazz; + + + if ( clazz->glyph_done ) + clazz->glyph_done( glyph ); + + FT_FREE( glyph ); + } + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftgxval.c b/drivers/freetype/src/base/ftgxval.c new file mode 100644 index 0000000000..a8ec44ac00 --- /dev/null +++ b/drivers/freetype/src/base/ftgxval.c @@ -0,0 +1,142 @@ +/***************************************************************************/ +/* */ +/* ftgxval.c */ +/* */ +/* FreeType API for validating TrueTyepGX/AAT tables (body). */ +/* */ +/* Copyright 2004-2006, 2010, 2013 by */ +/* Masatake YAMATO, Redhat K.K, */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_GX_VALIDATE_H + + + /* documentation is in ftgxval.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_TrueTypeGX_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ) + { + FT_Service_GXvalidate service; + FT_Error error; + + + if ( !face ) + { + error = FT_THROW( Invalid_Face_Handle ); + goto Exit; + } + + if ( tables == NULL ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, service, GX_VALIDATE ); + + if ( service ) + error = service->validate( face, + validation_flags, + tables, + table_length ); + else + error = FT_THROW( Unimplemented_Feature ); + + Exit: + return error; + } + + + FT_EXPORT_DEF( void ) + FT_TrueTypeGX_Free( FT_Face face, + FT_Bytes table ) + { + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + FT_FREE( table ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_ClassicKern_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *ckern_table ) + { + FT_Service_CKERNvalidate service; + FT_Error error; + + + if ( !face ) + { + error = FT_THROW( Invalid_Face_Handle ); + goto Exit; + } + + if ( ckern_table == NULL ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, service, CLASSICKERN_VALIDATE ); + + if ( service ) + error = service->validate( face, + validation_flags, + ckern_table ); + else + error = FT_THROW( Unimplemented_Feature ); + + Exit: + return error; + } + + + FT_EXPORT_DEF( void ) + FT_ClassicKern_Free( FT_Face face, + FT_Bytes table ) + { + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + + FT_FREE( table ); + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftinit.c b/drivers/freetype/src/base/ftinit.c new file mode 100644 index 0000000000..85f321fd2d --- /dev/null +++ b/drivers/freetype/src/base/ftinit.c @@ -0,0 +1,282 @@ +/***************************************************************************/ +/* */ +/* ftinit.c */ +/* */ +/* FreeType initialization layer (body). */ +/* */ +/* Copyright 1996-2002, 2005, 2007, 2009, 2012, 2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* The purpose of this file is to implement the following two */ + /* functions: */ + /* */ + /* FT_Add_Default_Modules(): */ + /* This function is used to add the set of default modules to a */ + /* fresh new library object. The set is taken from the header file */ + /* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */ + /* Build System' for more information. */ + /* */ + /* FT_Init_FreeType(): */ + /* This function creates a system object for the current platform, */ + /* builds a library out of it, then calls FT_Default_Drivers(). */ + /* */ + /* Note that even if FT_Init_FreeType() uses the implementation of the */ + /* system object defined at build time, client applications are still */ + /* able to provide their own `ftsystem.c'. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_MODULE_H +#include "basepic.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_init + + +#ifndef FT_CONFIG_OPTION_PIC + + +#undef FT_USE_MODULE +#ifdef __cplusplus +#define FT_USE_MODULE( type, x ) extern "C" const type x; +#else +#define FT_USE_MODULE( type, x ) extern const type x; +#endif + +#include FT_CONFIG_MODULES_H + +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) (const FT_Module_Class*)&(x), + + static + const FT_Module_Class* const ft_default_modules[] = + { +#include FT_CONFIG_MODULES_H + 0 + }; + + +#else /* FT_CONFIG_OPTION_PIC */ + + +#ifdef __cplusplus +#define FT_EXTERNC extern "C" +#else +#define FT_EXTERNC extern +#endif + + /* declare the module's class creation/destruction functions */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + FT_EXTERNC FT_Error \ + FT_Create_Class_ ## x( FT_Library library, \ + FT_Module_Class* *output_class ); \ + FT_EXTERNC void \ + FT_Destroy_Class_ ## x( FT_Library library, \ + FT_Module_Class* clazz ); + +#include FT_CONFIG_MODULES_H + + /* count all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) MODULE_CLASS_ ## x, + + enum + { +#include FT_CONFIG_MODULES_H + FT_NUM_MODULE_CLASSES + }; + + /* destroy all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + if ( classes[i] ) \ + { \ + FT_Destroy_Class_ ## x( library, classes[i] ); \ + } \ + i++; + + + FT_BASE_DEF( void ) + ft_destroy_default_module_classes( FT_Library library ) + { + FT_Module_Class* *classes; + FT_Memory memory; + FT_UInt i; + BasePIC* pic_container = (BasePIC*)library->pic_container.base; + + + if ( !pic_container->default_module_classes ) + return; + + memory = library->memory; + classes = pic_container->default_module_classes; + i = 0; + +#include FT_CONFIG_MODULES_H + + FT_FREE( classes ); + pic_container->default_module_classes = 0; + } + + + /* initialize all module classes and the pointer table */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + error = FT_Create_Class_ ## x( library, &clazz ); \ + if ( error ) \ + goto Exit; \ + classes[i++] = clazz; + + + FT_BASE_DEF( FT_Error ) + ft_create_default_module_classes( FT_Library library ) + { + FT_Error error; + FT_Memory memory; + FT_Module_Class* *classes = NULL; + FT_Module_Class* clazz; + FT_UInt i; + BasePIC* pic_container = (BasePIC*)library->pic_container.base; + + + memory = library->memory; + + pic_container->default_module_classes = 0; + + if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) * + ( FT_NUM_MODULE_CLASSES + 1 ) ) ) + return error; + + /* initialize all pointers to 0, especially the last one */ + for ( i = 0; i < FT_NUM_MODULE_CLASSES; i++ ) + classes[i] = 0; + classes[FT_NUM_MODULE_CLASSES] = 0; + + i = 0; + +#include FT_CONFIG_MODULES_H + + Exit: + if ( error ) + ft_destroy_default_module_classes( library ); + else + pic_container->default_module_classes = classes; + + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( void ) + FT_Add_Default_Modules( FT_Library library ) + { + FT_Error error; + const FT_Module_Class* const* cur; + + + /* FT_DEFAULT_MODULES_GET dereferences `library' in PIC mode */ +#ifdef FT_CONFIG_OPTION_PIC + if ( !library ) + return; +#endif + + /* GCC 4.6 warns the type difference: + * FT_Module_Class** != const FT_Module_Class* const* + */ + cur = (const FT_Module_Class* const*)FT_DEFAULT_MODULES_GET; + + /* test for valid `library' delayed to FT_Add_Module() */ + while ( *cur ) + { + error = FT_Add_Module( library, *cur ); + /* notify errors, but don't stop */ + if ( error ) + FT_TRACE0(( "FT_Add_Default_Module:" + " Cannot install `%s', error = 0x%x\n", + (*cur)->module_name, error )); + cur++; + } + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ) + { + FT_Error error; + FT_Memory memory; + + + /* First of all, allocate a new system object -- this function is part */ + /* of the system-specific component, i.e. `ftsystem.c'. */ + + memory = FT_New_Memory(); + if ( !memory ) + { + FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" )); + return FT_THROW( Unimplemented_Feature ); + } + + /* build a library out of it, then fill it with the set of */ + /* default drivers. */ + + error = FT_New_Library( memory, alibrary ); + if ( error ) + FT_Done_Memory( memory ); + else + FT_Add_Default_Modules( *alibrary ); + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_FreeType( FT_Library library ) + { + if ( library ) + { + FT_Memory memory = library->memory; + + + /* Discard the library object */ + FT_Done_Library( library ); + + /* discard memory manager */ + FT_Done_Memory( memory ); + } + + return FT_Err_Ok; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftlcdfil.c b/drivers/freetype/src/base/ftlcdfil.c new file mode 100644 index 0000000000..852fb32982 --- /dev/null +++ b/drivers/freetype/src/base/ftlcdfil.c @@ -0,0 +1,378 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.c */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs (body). */ +/* */ +/* Copyright 2006, 2008-2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_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 + + /* intra-pixel filter used by the legacy filter */ + 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 intra-pixel 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_DEF( FT_Error ) + FT_Library_SetLcdFilterWeights( FT_Library library, + unsigned char *weights ) + { + if ( !library || !weights ) + return FT_THROW( Invalid_Argument ); + + ft_memcpy( library->lcd_weights, weights, 5 ); + + return FT_Err_Ok; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ) + { + static const FT_Byte light_filter[5] = + { 0x00, 0x55, 0x56, 0x55, 0x00 }; + /* 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 ) + return FT_THROW( 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 ) + + ft_memcpy( library->lcd_weights, light_filter, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; + +#else + + ft_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: + ft_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_THROW( Invalid_Argument ); + } + + library->lcd_filter = filter; + + return FT_Err_Ok; + } + +#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + FT_EXPORT_DEF( FT_Error ) + FT_Library_SetLcdFilterWeights( FT_Library library, + unsigned char *weights ) + { + FT_UNUSED( library ); + FT_UNUSED( weights ); + + return FT_THROW( Unimplemented_Feature ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ) + { + FT_UNUSED( library ); + FT_UNUSED( filter ); + + return FT_THROW( Unimplemented_Feature ); + } + +#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftmac.c b/drivers/freetype/src/base/ftmac.c new file mode 100644 index 0000000000..5b5aae61cc --- /dev/null +++ b/drivers/freetype/src/base/ftmac.c @@ -0,0 +1,1061 @@ +/***************************************************************************/ +/* */ +/* ftmac.c */ +/* */ +/* Mac FOND support. Written by just@letterror.com. */ +/* 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-2009, 2013 by */ +/* Just van Rossum, 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. */ +/* */ +/***************************************************************************/ + + + /* + Notes + + Mac suitcase files can (and often do!) contain multiple fonts. To + support this I use the face_index argument of FT_(Open|New)_Face() + functions, and pretend the suitcase file is a collection. + + Warning: fbit and NFNT bitmap resources are not supported yet. In old + sfnt fonts, bitmap glyph data for each size is stored in each `NFNT' + resources instead of the `bdat' table in the sfnt resource. Therefore, + face->num_fixed_sizes is set to 0, because bitmap data in `NFNT' + resource is unavailable at present. + + The Mac FOND support works roughly like this: + + - Check whether the offered stream points to a Mac suitcase file. This + is done by checking the file type: it has to be 'FFIL' or 'tfil'. The + stream that gets passed to our init_face() routine is a stdio stream, + which isn't usable for us, since the FOND resources live in the + resource fork. So we just grab the stream->pathname field. + + - Read the FOND resource into memory, then check whether there is a + TrueType font and/or(!) a Type 1 font available. + + - If there is a Type 1 font available (as a separate `LWFN' file), read + its data into memory, massage it slightly so it becomes PFB data, wrap + it into a memory stream, load the Type 1 driver and delegate the rest + of the work to it by calling FT_Open_Face(). (XXX TODO: after this + has been done, the kerning data from the FOND resource should be + appended to the face: On the Mac there are usually no AFM files + available. However, this is tricky since we need to map Mac char + codes to ps glyph names to glyph ID's...) + + - 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. + */ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_STREAM_H +#include "ftbase.h" + + /* This is for Mac OS X. Without redefinition, OS_INLINE */ + /* expands to `static inline' which doesn't survive the */ + /* -ansi compilation flag of GCC. */ +#if !HAVE_ANSI_OS_INLINE +#undef OS_INLINE +#define OS_INLINE static __inline__ +#endif + + /* `configure' checks the availability of `ResourceIndex' strictly */ + /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always. If it is */ + /* not set (e.g., a build without `configure'), the availability */ + /* is guessed from the SDK version. */ +#ifndef HAVE_TYPE_RESOURCE_INDEX +#if !defined( MAC_OS_X_VERSION_10_5 ) || \ + ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 ) +#define HAVE_TYPE_RESOURCE_INDEX 0 +#else +#define HAVE_TYPE_RESOURCE_INDEX 1 +#endif +#endif /* !HAVE_TYPE_RESOURCE_INDEX */ + +#if ( HAVE_TYPE_RESOURCE_INDEX == 0 ) + typedef short ResourceIndex; +#endif + +#include <CoreServices/CoreServices.h> +#include <ApplicationServices/ApplicationServices.h> +#include <sys/syslimits.h> /* PATH_MAX */ + + /* Don't want warnings about our own use of deprecated functions. */ +#define FT_DEPRECATED_ATTRIBUTE + +#include FT_MAC_H + +#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */ +#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault +#endif + + + /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over + TrueType in case *both* are available (this is not common, + but it *is* possible). */ +#ifndef PREFER_LWFN +#define PREFER_LWFN 1 +#endif + + +#ifdef FT_MACINTOSH + + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { + FT_UNUSED( fontName ); + FT_UNUSED( pathSpec ); + FT_UNUSED( face_index ); + + return FT_THROW( Unimplemented_Feature ); + } + + + /* Private function. */ + /* The FSSpec type has been discouraged for a long time, */ + /* unfortunately an FSRef replacement API for */ + /* ATSFontGetFileSpecification() is only available in */ + /* Mac OS X 10.5 and later. */ + static OSStatus + FT_ATSFontGetFileReference( ATSFontRef ats_font_id, + FSRef* ats_font_ref ) + { +#if defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) + + OSStatus err; + + err = ATSFontGetFileReference( ats_font_id, ats_font_ref ); + + return err; +#elif __LP64__ /* No 64bit Carbon API on legacy platforms */ + FT_UNUSED( ats_font_id ); + FT_UNUSED( ats_font_ref ); + + + return fnfErr; +#else /* 32bit Carbon API on legacy platforms */ + OSStatus err; + FSSpec spec; + + + err = ATSFontGetFileSpecification( ats_font_id, &spec ); + if ( noErr == err ) + err = FSpMakeFSRef( &spec, ats_font_ref ); + + return err; +#endif + } + + + static FT_Error + FT_GetFileRef_From_Mac_ATS_Name( const char* fontName, + FSRef* ats_font_ref, + FT_Long* face_index ) + { + CFStringRef cf_fontName; + ATSFontRef ats_font_id; + + + *face_index = 0; + + cf_fontName = CFStringCreateWithCString( NULL, fontName, + kCFStringEncodingMacRoman ); + ats_font_id = ATSFontFindFromName( cf_fontName, + kATSOptionFlagsUnRestrictedScope ); + CFRelease( cf_fontName ); + + if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL ) + return FT_THROW( Unknown_File_Format ); + + if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) ) + return FT_THROW( Unknown_File_Format ); + + /* face_index calculation by searching preceding fontIDs */ + /* with same FSRef */ + { + ATSFontRef id2 = ats_font_id - 1; + FSRef ref2; + + + while ( id2 > 0 ) + { + if ( noErr != FT_ATSFontGetFileReference( id2, &ref2 ) ) + break; + if ( noErr != FSCompareFSRefs( ats_font_ref, &ref2 ) ) + break; + + id2 --; + } + *face_index = ats_font_id - ( id2 + 1 ); + } + + return FT_Err_Ok; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, + UInt8* path, + UInt32 maxPathSize, + FT_Long* face_index ) + { + FSRef ref; + FT_Error err; + + + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); + if ( err ) + return err; + + if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) ) + return FT_THROW( Unknown_File_Format ); + + return FT_Err_Ok; + } + + + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) + FT_UNUSED( fontName ); + FT_UNUSED( pathSpec ); + FT_UNUSED( face_index ); + + return FT_THROW( Unimplemented_Feature ); +#else + FSRef ref; + FT_Error err; + + + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); + if ( err ) + return err; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, + pathSpec, NULL ) ) + return FT_THROW( Unknown_File_Format ); + + return FT_Err_Ok; +#endif + } + + + static OSErr + FT_FSPathMakeRes( const UInt8* pathname, + ResFileRefNum* res ) + { + OSErr err; + FSRef ref; + + + if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) + return FT_THROW( Cannot_Open_Resource ); + + /* at present, no support for dfont format */ + err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res ); + if ( noErr == err ) + return err; + + /* fallback to original resource-fork font */ + *res = FSOpenResFile( &ref, fsRdPerm ); + err = ResError(); + + return err; + } + + + /* Return the file type for given pathname */ + static OSType + get_file_type_from_path( const UInt8* pathname ) + { + FSRef ref; + FSCatalogInfo info; + + + if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) + return ( OSType ) 0; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info, + NULL, NULL, NULL ) ) + return ( OSType ) 0; + + return ((FInfo *)(info.finderInfo))->fdType; + } + + + /* Given a PostScript font name, create the Macintosh LWFN file name. */ + static void + create_lwfn_name( char* ps_name, + Str255 lwfn_file_name ) + { + int max = 5, count = 0; + FT_Byte* p = lwfn_file_name; + FT_Byte* q = (FT_Byte*)ps_name; + + + lwfn_file_name[0] = 0; + + while ( *q ) + { + if ( ft_isupper( *q ) ) + { + if ( count ) + max = 3; + count = 0; + } + if ( count < max && ( ft_isalnum( *q ) || *q == '_' ) ) + { + *++p = *q; + lwfn_file_name[0]++; + count++; + } + q++; + } + } + + + static short + count_faces_sfnt( char* fond_data ) + { + /* The count is 1 greater than the value in the FOND. */ + /* Isn't that cute? :-) */ + + return EndianS16_BtoN( *( (short*)( fond_data + + sizeof ( FamRec ) ) ) ) + 1; + } + + + static short + count_faces_scalable( char* fond_data ) + { + AsscEntry* assoc; + short i, face, face_all; + + + 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 == EndianS16_BtoN( assoc[i].fontSize ) ) + face++; + } + return face; + } + + + /* Look inside the FOND data, answer whether there should be an SFNT + resource, and answer the name of a possible LWFN Type 1 file. + + Thanks to Paul Miller (paulm@profoundeffects.com) for the fix + to load a face OTHER than the first one in the FOND! + */ + + + static void + parse_fond( char* fond_data, + short* have_sfnt, + ResID* sfnt_id, + Str255 lwfn_file_name, + short face_index ) + { + AsscEntry* assoc; + AsscEntry* base_assoc; + FamRec* fond; + + + *sfnt_id = 0; + *have_sfnt = 0; + lwfn_file_name[0] = 0; + + fond = (FamRec*)fond_data; + assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); + base_assoc = assoc; + + /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */ + if ( 47 < face_index ) + return; + + /* Let's do a little range checking before we get too excited here */ + if ( face_index < count_faces_sfnt( fond_data ) ) + { + assoc += face_index; /* add on the face_index! */ + + /* if the face at this index is not scalable, + fall back to the first one (old behavior) */ + if ( EndianS16_BtoN( assoc->fontSize ) == 0 ) + { + *have_sfnt = 1; + *sfnt_id = EndianS16_BtoN( assoc->fontID ); + } + else if ( base_assoc->fontSize == 0 ) + { + *have_sfnt = 1; + *sfnt_id = EndianS16_BtoN( base_assoc->fontID ); + } + } + + if ( EndianS32_BtoN( fond->ffStylOff ) ) + { + unsigned char* p = (unsigned char*)fond_data; + StyleTable* style; + unsigned short string_count; + char ps_name[256]; + unsigned char* names[64]; + int i; + + + p += EndianS32_BtoN( fond->ffStylOff ); + style = (StyleTable*)p; + p += sizeof ( StyleTable ); + string_count = EndianS16_BtoN( *(short*)(p) ); + p += sizeof ( short ); + + for ( i = 0; i < string_count && i < 64; i++ ) + { + names[i] = p; + p += names[i][0]; + p++; + } + + { + size_t ps_name_len = (size_t)names[0][0]; + + + if ( ps_name_len != 0 ) + { + ft_memcpy(ps_name, names[0] + 1, ps_name_len); + ps_name[ps_name_len] = 0; + } + if ( style->indexes[face_index] > 1 && + style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) + { + unsigned char* suffixes = names[style->indexes[face_index] - 1]; + + + for ( i = 1; i <= suffixes[0]; i++ ) + { + unsigned char* s; + size_t j = suffixes[i] - 1; + + + if ( j < string_count && ( s = names[j] ) != NULL ) + { + size_t s_len = (size_t)s[0]; + + + if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) ) + { + ft_memcpy( ps_name + ps_name_len, s + 1, s_len ); + ps_name_len += s_len; + ps_name[ps_name_len] = 0; + } + } + } + } + } + + create_lwfn_name( ps_name, lwfn_file_name ); + } + } + + + static FT_Error + lookup_lwfn_by_fond( const UInt8* path_fond, + ConstStr255Param base_lwfn, + UInt8* path_lwfn, + size_t path_size ) + { + FSRef ref, par_ref; + size_t dirname_len; + + + /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */ + /* We should not extract parent directory by string manipulation. */ + + if ( noErr != FSPathMakeRef( path_fond, &ref, FALSE ) ) + return FT_THROW( Invalid_Argument ); + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, + NULL, NULL, NULL, &par_ref ) ) + return FT_THROW( Invalid_Argument ); + + if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) ) + return FT_THROW( Invalid_Argument ); + + if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size ) + return FT_THROW( Invalid_Argument ); + + /* now we have absolute dirname in path_lwfn */ + ft_strcat( (char *)path_lwfn, "/" ); + dirname_len = ft_strlen( (char *)path_lwfn ); + ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 ); + path_lwfn[dirname_len + base_lwfn[0]] = '\0'; + + if ( noErr != FSPathMakeRef( path_lwfn, &ref, FALSE ) ) + return FT_THROW( Cannot_Open_Resource ); + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, + NULL, NULL, NULL, NULL ) ) + return FT_THROW( Cannot_Open_Resource ); + + return FT_Err_Ok; + } + + + static short + count_faces( Handle fond, + const UInt8* pathname ) + { + ResID sfnt_id; + short have_sfnt, have_lwfn; + Str255 lwfn_file_name; + UInt8 buff[PATH_MAX]; + FT_Error err; + short num_faces; + + + have_sfnt = have_lwfn = 0; + + parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 ); + + if ( lwfn_file_name[0] ) + { + err = lookup_lwfn_by_fond( pathname, lwfn_file_name, + buff, sizeof ( buff ) ); + if ( !err ) + have_lwfn = 1; + } + + if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) + num_faces = 1; + else + num_faces = count_faces_scalable( *fond ); + + return num_faces; + } + + + /* Read Type 1 data from the POST resources inside the LWFN file, + return a PFB buffer. This is somewhat convoluted because the FT2 + PFB parser wants the ASCII header as one chunk, and the LWFN + chunks are often not organized that way, so we glue chunks + of the same type together. */ + static FT_Error + read_lwfn( FT_Memory memory, + ResFileRefNum res, + FT_Byte** pfb_data, + FT_ULong* size ) + { + FT_Error error = FT_Err_Ok; + ResID res_id; + unsigned char *buffer, *p, *size_p = NULL; + FT_ULong total_size = 0; + FT_ULong old_total_size = 0; + FT_ULong post_size, pfb_chunk_size; + Handle post_data; + char code, last_code; + + + UseResFile( res ); + + /* First pass: load all POST resources, and determine the size of */ + /* the output buffer. */ + res_id = 501; + last_code = -1; + + for (;;) + { + post_data = Get1Resource( TTAG_POST, res_id++ ); + if ( post_data == NULL ) + break; /* we are done */ + + code = (*post_data)[0]; + + if ( code != last_code ) + { + if ( code == 5 ) + total_size += 2; /* just the end code */ + else + total_size += 6; /* code + 4 bytes chunk length */ + } + + total_size += GetHandleSize( post_data ) - 2; + last_code = code; + + /* detect integer overflows */ + if ( total_size < old_total_size ) + { + error = FT_THROW( Array_Too_Large ); + goto Error; + } + + old_total_size = total_size; + } + + if ( FT_ALLOC( buffer, (FT_Long)total_size ) ) + goto Error; + + /* Second pass: append all POST data to the buffer, add PFB fields. */ + /* Glue all consecutive chunks of the same type together. */ + p = buffer; + res_id = 501; + last_code = -1; + pfb_chunk_size = 0; + + for (;;) + { + post_data = Get1Resource( TTAG_POST, res_id++ ); + if ( post_data == NULL ) + break; /* we are done */ + + post_size = (FT_ULong)GetHandleSize( post_data ) - 2; + code = (*post_data)[0]; + + if ( code != last_code ) + { + if ( last_code != -1 ) + { + /* we are done adding a chunk, fill in the size field */ + if ( size_p != NULL ) + { + *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF ); + } + pfb_chunk_size = 0; + } + + *p++ = 0x80; + if ( code == 5 ) + *p++ = 0x03; /* the end */ + else if ( code == 2 ) + *p++ = 0x02; /* binary segment */ + else + *p++ = 0x01; /* ASCII segment */ + + if ( code != 5 ) + { + size_p = p; /* save for later */ + p += 4; /* make space for size field */ + } + } + + ft_memcpy( p, *post_data + 2, post_size ); + pfb_chunk_size += post_size; + p += post_size; + last_code = code; + } + + *pfb_data = buffer; + *size = total_size; + + Error: + CloseResFile( res ); + return error; + } + + + /* Create a new FT_Face from a file path to an LWFN file. */ + static FT_Error + FT_New_Face_From_LWFN( FT_Library library, + const UInt8* pathname, + FT_Long face_index, + FT_Face* aface ) + { + FT_Byte* pfb_data; + FT_ULong pfb_size; + FT_Error error; + ResFileRefNum res; + + + if ( noErr != FT_FSPathMakeRes( pathname, &res ) ) + return FT_THROW( Cannot_Open_Resource ); + + pfb_data = NULL; + pfb_size = 0; + error = read_lwfn( library->memory, res, &pfb_data, &pfb_size ); + CloseResFile( res ); /* PFB is already loaded, useless anymore */ + if ( error ) + return error; + + return open_face_from_buffer( library, + pfb_data, + pfb_size, + face_index, + "type1", + aface ); + } + + + /* Create a new FT_Face from an SFNT resource, specified by res ID. */ + static FT_Error + FT_New_Face_From_SFNT( FT_Library library, + ResID sfnt_id, + FT_Long face_index, + FT_Face* aface ) + { + Handle sfnt = NULL; + FT_Byte* sfnt_data; + size_t sfnt_size; + FT_Error error = FT_Err_Ok; + FT_Memory memory = library->memory; + int is_cff, is_sfnt_ps; + + + sfnt = GetResource( TTAG_sfnt, sfnt_id ); + if ( sfnt == NULL ) + return FT_THROW( Invalid_Handle ); + + sfnt_size = (FT_ULong)GetHandleSize( sfnt ); + if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) + { + ReleaseResource( sfnt ); + return error; + } + + ft_memcpy( sfnt_data, *sfnt, sfnt_size ); + ReleaseResource( sfnt ); + + is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); + is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 ); + + if ( is_sfnt_ps ) + { + FT_Stream stream; + + + if ( FT_NEW( stream ) ) + goto Try_OpenType; + + FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size ); + if ( !open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ) ) + { + FT_Stream_Close( stream ); + FT_FREE( stream ); + FT_FREE( sfnt_data ); + goto Exit; + } + + FT_FREE( stream ); + } + Try_OpenType: + error = open_face_from_buffer( library, + sfnt_data, + sfnt_size, + face_index, + is_cff ? "cff" : "truetype", + aface ); + Exit: + return error; + } + + + /* Create a new FT_Face from a file path to a suitcase file. */ + static FT_Error + FT_New_Face_From_Suitcase( FT_Library library, + const UInt8* pathname, + FT_Long face_index, + FT_Face* aface ) + { + FT_Error error = FT_ERR( Cannot_Open_Resource ); + ResFileRefNum res_ref; + ResourceIndex res_index; + Handle fond; + short num_faces_in_res; + + + if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) + return FT_THROW( Cannot_Open_Resource ); + + UseResFile( res_ref ); + if ( ResError() ) + return FT_THROW( Cannot_Open_Resource ); + + num_faces_in_res = 0; + for ( res_index = 1; ; ++res_index ) + { + short num_faces_in_fond; + + + fond = Get1IndResource( TTAG_FOND, res_index ); + if ( ResError() ) + break; + + num_faces_in_fond = count_faces( fond, pathname ); + num_faces_in_res += num_faces_in_fond; + + if ( 0 <= face_index && face_index < num_faces_in_fond && error ) + error = FT_New_Face_From_FOND( library, fond, face_index, aface ); + + face_index -= num_faces_in_fond; + } + + CloseResFile( res_ref ); + if ( !error && aface && *aface ) + (*aface)->num_faces = num_faces_in_res; + return error; + } + + + /* documentation is in ftmac.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face* aface ) + { + short have_sfnt, have_lwfn = 0; + ResID sfnt_id, fond_id; + OSType fond_type; + Str255 fond_name; + Str255 lwfn_file_name; + UInt8 path_lwfn[PATH_MAX]; + OSErr err; + FT_Error error = FT_Err_Ok; + + + GetResInfo( fond, &fond_id, &fond_type, fond_name ); + if ( ResError() != noErr || fond_type != TTAG_FOND ) + return FT_THROW( Invalid_File_Format ); + + parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); + + if ( lwfn_file_name[0] ) + { + ResFileRefNum res; + + + res = HomeResFile( fond ); + if ( noErr != ResError() ) + goto found_no_lwfn_file; + + { + UInt8 path_fond[PATH_MAX]; + FSRef ref; + + + err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum, + NULL, NULL, NULL, &ref, NULL ); + if ( noErr != err ) + goto found_no_lwfn_file; + + err = FSRefMakePath( &ref, 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 ( !error ) + have_lwfn = 1; + } + } + + if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) + error = FT_New_Face_From_LWFN( library, + path_lwfn, + face_index, + aface ); + else + error = FT_THROW( Unknown_File_Format ); + + found_no_lwfn_file: + if ( have_sfnt && error ) + error = FT_New_Face_From_SFNT( library, + sfnt_id, + face_index, + aface ); + + return error; + } + + + /* Common function to load a new FT_Face from a resource file. */ + static FT_Error + FT_New_Face_From_Resource( FT_Library library, + const UInt8* pathname, + FT_Long face_index, + FT_Face* aface ) + { + OSType file_type; + FT_Error error; + + + /* LWFN is a (very) specific file format, check for it explicitly */ + file_type = get_file_type_from_path( pathname ); + if ( file_type == TTAG_LWFN ) + return FT_New_Face_From_LWFN( library, pathname, face_index, aface ); + + /* Otherwise the file type doesn't matter (there are more than */ + /* `FFIL' and `tfil'). Just try opening it as a font suitcase; */ + /* if it works, fine. */ + + error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface ); + if ( error == 0 ) + return error; + + /* let it fall through to normal loader (.ttf, .otf, etc.); */ + /* we signal this by returning no error and no FT_Face */ + *aface = NULL; + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* This is the Mac-specific implementation of FT_New_Face. In */ + /* addition to the standard FT_New_Face() functionality, it also */ + /* accepts pathnames to Mac suitcase files. For further */ + /* documentation see the original FT_New_Face() in freetype.h. */ + /* */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face( FT_Library library, + const char* pathname, + FT_Long face_index, + FT_Face* aface ) + { + FT_Open_Args args; + FT_Error error; + + + /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + if ( !pathname ) + return FT_THROW( Invalid_Argument ); + + error = FT_Err_Ok; + *aface = NULL; + + /* try resourcefork based font: LWFN, FFIL */ + error = FT_New_Face_From_Resource( library, (UInt8 *)pathname, + face_index, aface ); + if ( error != 0 || *aface != NULL ) + return error; + + /* let it fall through to normal loader (.ttf, .otf, etc.) */ + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSRef */ + /* */ + /* <Description> */ + /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ + /* accepts an FSRef instead of a path. */ + /* */ + /* This function is deprecated because Carbon data types (FSRef) */ + /* are not cross-platform, and thus not suitable for the freetype API. */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FSRef( FT_Library library, + const FSRef* ref, + FT_Long face_index, + FT_Face* aface ) + { + FT_Error error; + FT_Open_Args args; + OSErr err; + UInt8 pathname[PATH_MAX]; + + + if ( !ref ) + return FT_THROW( Invalid_Argument ); + + err = FSRefMakePath( ref, pathname, sizeof ( pathname ) ); + if ( err ) + error = FT_THROW( 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 ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ + /* accepts an FSSpec instead of a path. */ + /* */ + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec* spec, + FT_Long face_index, + FT_Face* aface ) + { +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) + FT_UNUSED( library ); + FT_UNUSED( spec ); + FT_UNUSED( face_index ); + FT_UNUSED( aface ); + + return FT_THROW( Unimplemented_Feature ); +#else + FSRef ref; + + + if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr ) + return FT_THROW( Invalid_Argument ); + else + return FT_New_Face_From_FSRef( library, &ref, face_index, aface ); +#endif + } + +#endif /* FT_MACINTOSH */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftmm.c b/drivers/freetype/src/base/ftmm.c new file mode 100644 index 0000000000..18ff879bfc --- /dev/null +++ b/drivers/freetype/src/base/ftmm.c @@ -0,0 +1,204 @@ +/***************************************************************************/ +/* */ +/* ftmm.c */ +/* */ +/* Multiple Master font support (body). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2009, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_MULTIPLE_MASTERS_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_mm + + + static FT_Error + ft_face_get_mm_service( FT_Face face, + FT_Service_MultiMasters *aservice ) + { + FT_Error error; + + + *aservice = NULL; + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + error = FT_ERR( Invalid_Argument ); + + if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + { + FT_FACE_LOOKUP_SERVICE( face, + *aservice, + MULTI_MASTERS ); + + if ( *aservice ) + error = FT_Err_Ok; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm ) + error = service->get_mm( face, amaster ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_Var( FT_Face face, + FT_MM_Var* *amaster ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm_var ) + error = service->get_mm_var( face, amaster ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->set_mm_design ) + error = service->set_mm_design( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->set_var_design ) + error = service->set_var_design( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->set_mm_blend ) + error = service->set_mm_blend( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + /* This is exactly the same as the previous function. It exists for */ + /* orthogonality. */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->set_mm_blend ) + error = service->set_mm_blend( face, num_coords, coords ); + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftobjs.c b/drivers/freetype/src/base/ftobjs.c new file mode 100644 index 0000000000..157bf45634 --- /dev/null +++ b/drivers/freetype/src/base/ftobjs.c @@ -0,0 +1,4870 @@ +/***************************************************************************/ +/* */ +/* ftobjs.c */ +/* */ +/* The FreeType private base classes (body). */ +/* */ +/* Copyright 1996-2013 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_LIST_H +#include FT_OUTLINE_H +#include FT_INTERNAL_VALIDATE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_RFORK_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ +#include FT_TRUETYPE_TABLES_H +#include FT_TRUETYPE_TAGS_H +#include FT_TRUETYPE_IDS_H + +#include FT_SERVICE_PROPERTIES_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_TT_CMAP_H +#include FT_SERVICE_KERNING_H +#include FT_SERVICE_TRUETYPE_ENGINE_H + +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#include "ftbase.h" +#endif + + +#ifdef FT_DEBUG_LEVEL_TRACE + +#include FT_BITMAP_H + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + /* We disable the warning `conversion from XXX to YYY, */ + /* possible loss of data' in order to compile cleanly with */ + /* the maximum level of warnings: `md5.c' is non-FreeType */ + /* code, and it gets used during development builds only. */ +#pragma warning( push ) +#pragma warning( disable : 4244 ) +#endif /* _MSC_VER */ + + /* it's easiest to include `md5.c' directly */ +#define free md5_free /* suppress a shadow warning */ +#include "md5.c" +#undef free + +#if defined( _MSC_VER ) +#pragma warning( pop ) +#endif + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + +#define GRID_FIT_METRICS + + + FT_BASE_DEF( FT_Pointer ) + ft_service_list_lookup( FT_ServiceDesc service_descriptors, + const char* service_id ) + { + FT_Pointer result = NULL; + FT_ServiceDesc desc = service_descriptors; + + + if ( desc && service_id ) + { + for ( ; desc->serv_id != NULL; desc++ ) + { + if ( ft_strcmp( desc->serv_id, service_id ) == 0 ) + { + result = (FT_Pointer)desc->serv_data; + break; + } + } + } + + return result; + } + + + FT_BASE_DEF( void ) + ft_validator_init( FT_Validator valid, + const FT_Byte* base, + const FT_Byte* limit, + FT_ValidationLevel level ) + { + valid->base = base; + valid->limit = limit; + valid->level = level; + valid->error = FT_Err_Ok; + } + + + FT_BASE_DEF( FT_Int ) + ft_validator_run( FT_Validator valid ) + { + /* This function doesn't work! None should call it. */ + FT_UNUSED( valid ); + + return -1; + } + + + FT_BASE_DEF( void ) + 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 ft_jmp_buf* jump_buffer = &valid->jump_buffer; + + + valid->error = error; + + /* throw away volatileness; use `jump_buffer' or the */ + /* compiler may warn about an unused local variable */ + ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** S T R E A M ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* create a new input stream from an FT_Open_Args structure */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ) + { + FT_Error error; + FT_Memory memory; + FT_Stream stream = NULL; + + + *astream = 0; + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !args ) + return FT_THROW( Invalid_Argument ); + + memory = library->memory; + + if ( FT_NEW( stream ) ) + goto Exit; + + stream->memory = memory; + + if ( args->flags & FT_OPEN_MEMORY ) + { + /* create a memory-based stream */ + FT_Stream_OpenMemory( stream, + (const FT_Byte*)args->memory_base, + args->memory_size ); + } + +#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT + + else if ( args->flags & FT_OPEN_PATHNAME ) + { + /* create a normal system stream */ + error = FT_Stream_Open( stream, args->pathname ); + stream->pathname.pointer = args->pathname; + } + else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) + { + /* use an existing, user-provided stream */ + + /* in this case, we do not need to allocate a new stream object */ + /* since the caller is responsible for closing it himself */ + FT_FREE( stream ); + stream = args->stream; + } + +#endif + + else + error = FT_THROW( Invalid_Argument ); + + if ( error ) + FT_FREE( stream ); + else + stream->memory = memory; /* just to be certain */ + + *astream = stream; + + Exit: + return error; + } + + + FT_BASE_DEF( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ) + { + if ( stream ) + { + FT_Memory memory = stream->memory; + + + FT_Stream_Close( stream ); + + if ( !external ) + FT_FREE( stream ); + } + } + + + /*************************************************************************/ + /* */ + /* 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_objs + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + ft_glyphslot_init( FT_GlyphSlot slot ) + { + FT_Driver driver = slot->face->driver; + FT_Driver_Class clazz = driver->clazz; + FT_Memory memory = driver->root.memory; + FT_Error error = FT_Err_Ok; + FT_Slot_Internal internal = NULL; + + + slot->library = driver->root.library; + + if ( FT_NEW( internal ) ) + goto Exit; + + slot->internal = internal; + + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + error = FT_GlyphLoader_New( memory, &internal->loader ); + + if ( !error && clazz->init_slot ) + error = clazz->init_slot( slot ); + + Exit: + return error; + } + + + FT_BASE_DEF( void ) + ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) + { + if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + + + FT_FREE( slot->bitmap.buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + else + { + /* assume that the bitmap buffer was stolen or not */ + /* allocated from the heap */ + slot->bitmap.buffer = NULL; + } + } + + + FT_BASE_DEF( void ) + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Byte* buffer ) + { + ft_glyphslot_free_bitmap( slot ); + + slot->bitmap.buffer = buffer; + + FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 ); + } + + + FT_BASE_DEF( FT_Error ) + ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, + FT_ULong size ) + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + FT_Error error; + + + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + FT_FREE( slot->bitmap.buffer ); + else + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + + (void)FT_ALLOC( slot->bitmap.buffer, size ); + return error; + } + + + static void + ft_glyphslot_clear( FT_GlyphSlot slot ) + { + /* free bitmap if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* clear all public fields in the glyph slot */ + FT_ZERO( &slot->metrics ); + FT_ZERO( &slot->outline ); + + slot->bitmap.width = 0; + slot->bitmap.rows = 0; + slot->bitmap.pitch = 0; + slot->bitmap.pixel_mode = 0; + /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */ + + slot->bitmap_left = 0; + slot->bitmap_top = 0; + slot->num_subglyphs = 0; + slot->subglyphs = 0; + slot->control_data = 0; + slot->control_len = 0; + slot->other = 0; + slot->format = FT_GLYPH_FORMAT_NONE; + + slot->linearHoriAdvance = 0; + slot->linearVertAdvance = 0; + slot->lsb_delta = 0; + slot->rsb_delta = 0; + } + + + static void + ft_glyphslot_done( FT_GlyphSlot slot ) + { + FT_Driver driver = slot->face->driver; + FT_Driver_Class clazz = driver->clazz; + FT_Memory memory = driver->root.memory; + + + if ( clazz->done_slot ) + clazz->done_slot( slot ); + + /* free bitmap buffer if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* slot->internal might be NULL in out-of-memory situations */ + if ( slot->internal ) + { + /* free glyph loader */ + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + { + FT_GlyphLoader_Done( slot->internal->loader ); + slot->internal->loader = 0; + } + + FT_FREE( slot->internal ); + } + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( FT_Error ) + FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot *aslot ) + { + FT_Error error; + FT_Driver driver; + FT_Driver_Class clazz; + FT_Memory memory; + FT_GlyphSlot slot = NULL; + + + if ( !face || !face->driver ) + return FT_THROW( Invalid_Argument ); + + driver = face->driver; + clazz = driver->clazz; + memory = driver->root.memory; + + FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); + if ( !FT_ALLOC( slot, clazz->slot_object_size ) ) + { + slot->face = face; + + error = ft_glyphslot_init( slot ); + if ( error ) + { + ft_glyphslot_done( slot ); + FT_FREE( slot ); + goto Exit; + } + + slot->next = face->glyph; + face->glyph = slot; + + if ( aslot ) + *aslot = slot; + } + else if ( aslot ) + *aslot = 0; + + + Exit: + FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( void ) + FT_Done_GlyphSlot( FT_GlyphSlot slot ) + { + if ( slot ) + { + FT_Driver driver = slot->face->driver; + FT_Memory memory = driver->root.memory; + FT_GlyphSlot prev; + FT_GlyphSlot cur; + + + /* Remove slot from its parent face's list */ + prev = NULL; + cur = slot->face->glyph; + + while ( cur ) + { + if ( cur == slot ) + { + if ( !prev ) + slot->face->glyph = cur->next; + else + prev->next = cur->next; + + /* finalize client-specific data */ + if ( slot->generic.finalizer ) + slot->generic.finalizer( slot ); + + ft_glyphslot_done( slot ); + FT_FREE( slot ); + break; + } + prev = cur; + cur = cur->next; + } + } + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ) + { + FT_Face_Internal internal; + + + if ( !face ) + return; + + internal = face->internal; + + internal->transform_flags = 0; + + if ( !matrix ) + { + internal->transform_matrix.xx = 0x10000L; + internal->transform_matrix.xy = 0; + internal->transform_matrix.yx = 0; + internal->transform_matrix.yy = 0x10000L; + matrix = &internal->transform_matrix; + } + else + internal->transform_matrix = *matrix; + + /* set transform_flags bit flag 0 if `matrix' isn't the identity */ + if ( ( matrix->xy | matrix->yx ) || + matrix->xx != 0x10000L || + matrix->yy != 0x10000L ) + internal->transform_flags |= 1; + + if ( !delta ) + { + internal->transform_delta.x = 0; + internal->transform_delta.y = 0; + delta = &internal->transform_delta; + } + else + internal->transform_delta = *delta; + + /* set transform_flags bit flag 1 if `delta' isn't the null vector */ + if ( delta->x | delta->y ) + internal->transform_flags |= 2; + } + + + static FT_Renderer + ft_lookup_glyph_renderer( FT_GlyphSlot slot ); + + +#ifdef GRID_FIT_METRICS + static void + ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot, + FT_Bool vertical ) + { + FT_Glyph_Metrics* metrics = &slot->metrics; + FT_Pos right, bottom; + + + if ( vertical ) + { + metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); + metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); + + right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width ); + bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); + + metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); + + metrics->width = right - metrics->vertBearingX; + metrics->height = bottom - metrics->vertBearingY; + } + else + { + metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); + + right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); + bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); + + metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); + metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); + + metrics->width = right - metrics->horiBearingX; + metrics->height = metrics->horiBearingY - bottom; + } + + metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); + } +#endif /* GRID_FIT_METRICS */ + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + FT_Driver driver; + FT_GlyphSlot slot; + FT_Library library; + FT_Bool autohint = FALSE; + FT_Module hinter; + TT_Face ttface = (TT_Face)face; + + + if ( !face || !face->size || !face->glyph ) + return FT_THROW( Invalid_Face_Handle ); + + /* The validity test for `glyph_index' is performed by the */ + /* font drivers. */ + + slot = face->glyph; + ft_glyphslot_clear( slot ); + + driver = face->driver; + library = driver->root.library; + hinter = library->auto_hinter; + + /* resolve load flags dependencies */ + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | + FT_LOAD_IGNORE_TRANSFORM; + + if ( load_flags & FT_LOAD_NO_SCALE ) + { + load_flags |= FT_LOAD_NO_HINTING | + FT_LOAD_NO_BITMAP; + + load_flags &= ~FT_LOAD_RENDER; + } + + /* + * 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 and/or rotations by integer multiples of 90 degrees. + * + * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't + * have a native font hinter. + * + * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't + * any hinting bytecode in the TrueType/OpenType font. + * + * - Exception: The font is `tricky' and requires the native hinter to + * load properly. + */ + + if ( hinter && + !( load_flags & FT_LOAD_NO_HINTING ) && + !( load_flags & FT_LOAD_NO_AUTOHINT ) && + FT_DRIVER_IS_SCALABLE( driver ) && + FT_DRIVER_USES_OUTLINES( driver ) && + !FT_IS_TRICKY( face ) && + ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) || + ( face->internal->transform_matrix.yx == 0 && + face->internal->transform_matrix.xx != 0 ) || + ( face->internal->transform_matrix.xx == 0 && + face->internal->transform_matrix.yx != 0 ) ) ) + { + if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) || + !FT_DRIVER_HAS_HINTER( driver ) ) + autohint = TRUE; + else + { + FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); + + + /* the check for `num_locations' assures that we actually */ + /* test for instructions in a TTF and not in a CFF-based OTF */ + if ( mode == FT_RENDER_MODE_LIGHT || + face->internal->ignore_unpatented_hinter || + ( FT_IS_SFNT( face ) && + ttface->num_locations && + ttface->max_profile.maxSizeOfInstructions == 0 ) ) + autohint = TRUE; + } + } + + if ( autohint ) + { + FT_AutoHinter_Interface hinting; + + + /* try to load embedded bitmaps first if available */ + /* */ + /* XXX: This is really a temporary hack that should disappear */ + /* promptly with FreeType 2.1! */ + /* */ + if ( FT_HAS_FIXED_SIZES( face ) && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + error = driver->clazz->load_glyph( slot, face->size, + glyph_index, + load_flags | FT_LOAD_SBITS_ONLY ); + + if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP ) + goto Load_Ok; + } + + { + FT_Face_Internal internal = face->internal; + FT_Int transform_flags = internal->transform_flags; + + + /* since the auto-hinter calls FT_Load_Glyph by itself, */ + /* make sure that glyphs aren't transformed */ + internal->transform_flags = 0; + + /* load auto-hinted outline */ + hinting = (FT_AutoHinter_Interface)hinter->clazz->module_interface; + + error = hinting->load_glyph( (FT_AutoHinter)hinter, + slot, face->size, + glyph_index, load_flags ); + + internal->transform_flags = transform_flags; + } + } + else + { + error = driver->clazz->load_glyph( slot, + face->size, + glyph_index, + load_flags ); + if ( error ) + goto Exit; + + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* check that the loaded outline is correct */ + error = FT_Outline_Check( &slot->outline ); + if ( error ) + goto Exit; + +#ifdef GRID_FIT_METRICS + if ( !( load_flags & FT_LOAD_NO_HINTING ) ) + ft_glyphslot_grid_fit_metrics( slot, + FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); +#endif + } + } + + Load_Ok: + /* compute the advance */ + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + slot->advance.x = 0; + slot->advance.y = slot->metrics.vertAdvance; + } + else + { + slot->advance.x = slot->metrics.horiAdvance; + slot->advance.y = 0; + } + + /* compute the linear advance in 16.16 pixels */ + if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && + ( FT_IS_SCALABLE( face ) ) ) + { + FT_Size_Metrics* metrics = &face->size->metrics; + + + /* it's tricky! */ + slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, + metrics->x_scale, 64 ); + + slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, + metrics->y_scale, 64 ); + } + + if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) + { + FT_Face_Internal internal = face->internal; + + + /* now, transform the glyph image if needed */ + if ( internal->transform_flags ) + { + /* get renderer */ + FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); + + + if ( renderer ) + error = renderer->clazz->transform_glyph( + renderer, slot, + &internal->transform_matrix, + &internal->transform_delta ); + else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* apply `standard' transformation if no renderer is available */ + if ( internal->transform_flags & 1 ) + FT_Outline_Transform( &slot->outline, + &internal->transform_matrix ); + + if ( internal->transform_flags & 2 ) + FT_Outline_Translate( &slot->outline, + internal->transform_delta.x, + internal->transform_delta.y ); + } + + /* transform advance */ + FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); + } + } + + FT_TRACE5(( " x advance: %d\n" , slot->advance.x )); + FT_TRACE5(( " y advance: %d\n" , slot->advance.y )); + + FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance )); + FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance )); + + /* do we need to render the image now? */ + if ( !error && + slot->format != FT_GLYPH_FORMAT_BITMAP && + slot->format != FT_GLYPH_FORMAT_COMPOSITE && + load_flags & FT_LOAD_RENDER ) + { + FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); + + + if ( mode == FT_RENDER_MODE_NORMAL && + (load_flags & FT_LOAD_MONOCHROME ) ) + mode = FT_RENDER_MODE_MONO; + + error = FT_Render_Glyph( slot, mode ); + } + + Exit: + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ) + { + FT_UInt glyph_index; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + glyph_index = (FT_UInt)char_code; + if ( face->charmap ) + glyph_index = FT_Get_Char_Index( face, char_code ); + + return FT_Load_Glyph( face, glyph_index, load_flags ); + } + + + /* destructor for sizes list */ + static void + destroy_size( FT_Memory memory, + FT_Size size, + FT_Driver driver ) + { + /* finalize client-specific data */ + if ( size->generic.finalizer ) + size->generic.finalizer( size ); + + /* finalize format-specific stuff */ + if ( driver->clazz->done_size ) + driver->clazz->done_size( size ); + + FT_FREE( size->internal ); + FT_FREE( size ); + } + + + static void + ft_cmap_done_internal( FT_CMap cmap ); + + + static void + destroy_charmaps( FT_Face face, + FT_Memory memory ) + { + FT_Int n; + + + if ( !face ) + return; + + for ( n = 0; n < face->num_charmaps; n++ ) + { + FT_CMap cmap = FT_CMAP( face->charmaps[n] ); + + + ft_cmap_done_internal( cmap ); + + face->charmaps[n] = NULL; + } + + FT_FREE( face->charmaps ); + face->num_charmaps = 0; + } + + + /* destructor for faces list */ + static void + destroy_face( FT_Memory memory, + FT_Face face, + FT_Driver driver ) + { + FT_Driver_Class clazz = driver->clazz; + + + /* discard auto-hinting data */ + if ( face->autohint.finalizer ) + face->autohint.finalizer( face->autohint.data ); + + /* Discard glyph slots for this face. */ + /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */ + while ( face->glyph ) + FT_Done_GlyphSlot( face->glyph ); + + /* discard all sizes for this face */ + FT_List_Finalize( &face->sizes_list, + (FT_List_Destructor)destroy_size, + memory, + driver ); + face->size = 0; + + /* now discard client data */ + if ( face->generic.finalizer ) + face->generic.finalizer( face ); + + /* discard charmaps */ + destroy_charmaps( face, memory ); + + /* finalize format-specific stuff */ + if ( clazz->done_face ) + clazz->done_face( face ); + + /* close the stream for this face if needed */ + FT_Stream_Free( + face->stream, + ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); + + face->stream = 0; + + /* get rid of it */ + if ( face->internal ) + { + FT_FREE( face->internal ); + } + FT_FREE( face ); + } + + + static void + Destroy_Driver( FT_Driver driver ) + { + FT_List_Finalize( &driver->faces_list, + (FT_List_Destructor)destroy_face, + driver->root.memory, + driver ); + + /* check whether we need to drop the driver's glyph loader */ + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + FT_GlyphLoader_Done( driver->glyph_loader ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_unicode_charmap */ + /* */ + /* <Description> */ + /* This function finds a Unicode charmap, if there is one. */ + /* And if there is more than one, it tries to favour the more */ + /* extensive one, i.e., one that supports UCS-4 against those which */ + /* are limited to the BMP (said UCS-2 encoding.) */ + /* */ + /* This function is called from open_face() (just below), and also */ + /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ + /* */ + static FT_Error + find_unicode_charmap( FT_Face face ) + { + FT_CharMap* first; + FT_CharMap* cur; + + + /* caller should have already checked that `face' is valid */ + FT_ASSERT( face ); + + first = face->charmaps; + + if ( !first ) + return FT_THROW( Invalid_CharMap_Handle ); + + /* + * The original TrueType specification(s) only specified charmap + * formats that are capable of mapping 8 or 16 bit character codes to + * glyph indices. + * + * However, recent updates to the Apple and OpenType specifications + * introduced new formats that are capable of mapping 32-bit character + * codes as well. And these are already used on some fonts, mainly to + * map non-BMP Asian ideographs as defined in Unicode. + * + * For compatibility purposes, these fonts generally come with + * *several* Unicode charmaps: + * + * - One of them in the "old" 16-bit format, that cannot access + * all glyphs in the font. + * + * - Another one in the "new" 32-bit format, that can access all + * the glyphs. + * + * This function has been written to always favor a 32-bit charmap + * when found. Otherwise, a 16-bit one is returned when found. + */ + + /* Since the `interesting' table, with IDs (3,10), is normally the */ + /* last one, we loop backwards. This loses with type1 fonts with */ + /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */ + /* chars (.01% ?), and this is the same about 99.99% of the time! */ + + cur = first + face->num_charmaps; /* points after the last one */ + + for ( ; --cur >= first; ) + { + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { + /* XXX If some new encodings to represent UCS-4 are added, */ + /* they should be added here. */ + if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && + cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || + ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) + { +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) + { + FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found " + "at too late position (%d)\n", cur - first )); + continue; + } +#endif + face->charmap = cur[0]; + return FT_Err_Ok; + } + } + } + + /* We do not have any UCS-4 charmap. */ + /* Do the loop again and search for UCS-2 charmaps. */ + cur = first + face->num_charmaps; + + for ( ; --cur >= first; ) + { + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) + { + FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found " + "at too late position (%d)\n", cur - first )); + continue; + } +#endif + face->charmap = cur[0]; + return FT_Err_Ok; + } + } + + return FT_THROW( Invalid_CharMap_Handle ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_variant_selector_charmap */ + /* */ + /* <Description> */ + /* This function finds the variant selector charmap, if there is one. */ + /* There can only be one (platform=0, specific=5, format=14). */ + /* */ + static FT_CharMap + find_variant_selector_charmap( FT_Face face ) + { + FT_CharMap* first; + FT_CharMap* end; + FT_CharMap* cur; + + + /* caller should have already checked that `face' is valid */ + FT_ASSERT( face ); + + first = face->charmaps; + + if ( !first ) + return NULL; + + end = first + face->num_charmaps; /* points after the last one */ + + for ( cur = first; cur < end; ++cur ) + { + if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && + FT_Get_CMap_Format( cur[0] ) == 14 ) + { +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) + { + FT_ERROR(( "find_unicode_charmap: UVS cmap is found " + "at too late position (%d)\n", cur - first )); + continue; + } +#endif + return cur[0]; + } + } + + return NULL; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* open_face */ + /* */ + /* <Description> */ + /* This function does some work for FT_Open_Face(). */ + /* */ + static FT_Error + open_face( FT_Driver driver, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter* params, + FT_Face *aface ) + { + FT_Memory memory; + FT_Driver_Class clazz; + FT_Face face = 0; + FT_Error error, error2; + FT_Face_Internal internal = NULL; + + + clazz = driver->clazz; + memory = driver->root.memory; + + /* allocate the face object and perform basic initialization */ + if ( FT_ALLOC( face, clazz->face_object_size ) ) + goto Fail; + + face->driver = driver; + face->memory = memory; + face->stream = stream; + + if ( FT_NEW( internal ) ) + goto Fail; + + face->internal = internal; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + { + int i; + + + face->internal->incremental_interface = 0; + for ( i = 0; i < num_params && !face->internal->incremental_interface; + i++ ) + if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) + face->internal->incremental_interface = + (FT_Incremental_Interface)params[i].data; + } +#endif + + if ( clazz->init_face ) + error = clazz->init_face( stream, + face, + (FT_Int)face_index, + num_params, + params ); + if ( error ) + goto Fail; + + /* select Unicode charmap by default */ + error2 = find_unicode_charmap( face ); + + /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */ + /* is returned. */ + + /* no error should happen, but we want to play safe */ + if ( error2 && FT_ERR_NEQ( error2, Invalid_CharMap_Handle ) ) + { + error = error2; + goto Fail; + } + + *aface = face; + + Fail: + if ( error ) + { + destroy_charmaps( face, memory ); + if ( clazz->done_face ) + clazz->done_face( face ); + FT_FREE( internal ); + FT_FREE( face ); + *aface = 0; + } + + return error; + } + + + /* there's a Mac-specific extended implementation of FT_New_Face() */ + /* in src/base/ftmac.c */ + +#ifndef FT_MACINTOSH + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Face( FT_Library library, + const char* pathname, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + + + /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + if ( !pathname ) + return FT_THROW( Invalid_Argument ); + + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + args.stream = NULL; + + return FT_Open_Face( library, &args, face_index, aface ); + } + +#endif + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Memory_Face( FT_Library library, + const FT_Byte* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + + + /* test for valid `library' and `face' delayed to FT_Open_Face() */ + if ( !file_base ) + return FT_THROW( Invalid_Argument ); + + args.flags = FT_OPEN_MEMORY; + args.memory_base = file_base; + args.memory_size = file_size; + args.stream = NULL; + + return FT_Open_Face( library, &args, face_index, aface ); + } + + +#ifdef FT_CONFIG_OPTION_MAC_FONTS + + /* The behavior here is very similar to that in base/ftmac.c, but it */ + /* is designed to work on non-mac systems, so no mac specific calls. */ + /* */ + /* We look at the file and determine if it is a mac dfont file or a mac */ + /* resource file, or a macbinary file containing a mac resource file. */ + /* */ + /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */ + /* the point, especially since there may be multiple `FOND' resources. */ + /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */ + /* they occur in the file. */ + /* */ + /* Note that multiple `POST' resources do not mean multiple postscript */ + /* fonts; they all get jammed together to make what is essentially a */ + /* pfb file. */ + /* */ + /* We aren't interested in `NFNT' or `FONT' bitmap resources. */ + /* */ + /* As soon as we get an `sfnt' load it into memory and pass it off to */ + /* FT_Open_Face. */ + /* */ + /* If we have a (set of) `POST' resources, massage them into a (memory) */ + /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */ + /* going to try to save the kerning info. After all that lives in the */ + /* `FOND' which isn't in the file containing the `POST' resources so */ + /* we don't really have access to it. */ + + + /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ + /* It frees the memory it uses. */ + /* From ftmac.c. */ + static void + memory_stream_close( FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( stream->base ); + + stream->size = 0; + stream->base = 0; + stream->close = 0; + } + + + /* Create a new memory stream from a buffer and a size. */ + /* From ftmac.c. */ + static FT_Error + new_memory_stream( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Stream_CloseFunc close, + FT_Stream *astream ) + { + FT_Error error; + FT_Memory memory; + FT_Stream stream = NULL; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !base ) + return FT_THROW( Invalid_Argument ); + + *astream = 0; + memory = library->memory; + if ( FT_NEW( stream ) ) + goto Exit; + + FT_Stream_OpenMemory( stream, base, size ); + + stream->close = close; + + *astream = stream; + + Exit: + return error; + } + + + /* Create a new FT_Face given a buffer and a driver name. */ + /* from ftmac.c */ + FT_LOCAL_DEF( FT_Error ) + open_face_from_buffer( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Long face_index, + const char* driver_name, + FT_Face *aface ) + { + FT_Open_Args args; + FT_Error error; + FT_Stream stream = NULL; + FT_Memory memory = library->memory; + + + error = new_memory_stream( library, + base, + size, + memory_stream_close, + &stream ); + if ( error ) + { + FT_FREE( base ); + return error; + } + + args.flags = FT_OPEN_STREAM; + args.stream = stream; + if ( driver_name ) + { + args.flags = args.flags | FT_OPEN_DRIVER; + args.driver = FT_Get_Module( library, driver_name ); + } + +#ifdef FT_MACINTOSH + /* At this point, face_index has served its purpose; */ + /* whoever calls this function has already used it to */ + /* locate the correct font data. We should not propagate */ + /* this index to FT_Open_Face() (unless it is negative). */ + + if ( face_index > 0 ) + face_index = 0; +#endif + + error = FT_Open_Face( library, &args, face_index, aface ); + + if ( error == FT_Err_Ok ) + (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + else +#ifdef FT_MACINTOSH + FT_Stream_Free( stream, 0 ); +#else + { + FT_Stream_Close( stream ); + FT_FREE( stream ); + } +#endif + + return error; + } + + + /* Look up `TYP1' or `CID ' table from sfnt table directory. */ + /* `offset' and `length' must exclude the binary header in tables. */ + + /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ + /* format too. Here, since we can't expect that the TrueType font */ + /* driver is loaded unconditially, we must parse the font by */ + /* ourselves. We are only interested in the name of the table and */ + /* the offset. */ + + static FT_Error + ft_lookup_PS_in_sfnt_stream( FT_Stream stream, + FT_Long face_index, + FT_ULong* offset, + FT_ULong* length, + FT_Bool* is_sfnt_cid ) + { + FT_Error error; + FT_UShort numTables; + FT_Long pstable_index; + FT_ULong tag; + int i; + + + *offset = 0; + *length = 0; + *is_sfnt_cid = FALSE; + + /* TODO: support for sfnt-wrapped PS/CID in TTC format */ + + /* version check for 'typ1' (should be ignored?) */ + if ( FT_READ_ULONG( tag ) ) + return error; + if ( tag != TTAG_typ1 ) + return FT_THROW( Unknown_File_Format ); + + if ( FT_READ_USHORT( numTables ) ) + return error; + if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */ + return error; + + pstable_index = -1; + *is_sfnt_cid = FALSE; + + for ( i = 0; i < numTables; i++ ) + { + if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) || + FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) ) + return error; + + if ( tag == TTAG_CID ) + { + pstable_index++; + *offset += 22; + *length -= 22; + *is_sfnt_cid = TRUE; + if ( face_index < 0 ) + return FT_Err_Ok; + } + else if ( tag == TTAG_TYP1 ) + { + pstable_index++; + *offset += 24; + *length -= 24; + *is_sfnt_cid = FALSE; + if ( face_index < 0 ) + return FT_Err_Ok; + } + if ( face_index >= 0 && pstable_index == face_index ) + return FT_Err_Ok; + } + return FT_THROW( Table_Missing ); + } + + + FT_LOCAL_DEF( FT_Error ) + open_face_PS_from_sfnt_stream( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter *params, + FT_Face *aface ) + { + FT_Error error; + FT_Memory memory = library->memory; + FT_ULong offset, length; + FT_Long pos; + FT_Bool is_sfnt_cid; + FT_Byte* sfnt_ps = NULL; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + pos = FT_Stream_Pos( stream ); + + error = ft_lookup_PS_in_sfnt_stream( stream, + face_index, + &offset, + &length, + &is_sfnt_cid ); + if ( error ) + goto Exit; + + if ( FT_Stream_Seek( stream, pos + offset ) ) + goto Exit; + + if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) + goto Exit; + + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); + if ( error ) + goto Exit; + + error = open_face_from_buffer( library, + sfnt_ps, + length, + FT_MIN( face_index, 0 ), + is_sfnt_cid ? "cid" : "type1", + aface ); + Exit: + { + FT_Error error1; + + + if ( FT_ERR_EQ( error, Unknown_File_Format ) ) + { + error1 = FT_Stream_Seek( stream, pos ); + if ( error1 ) + return error1; + } + + return error; + } + } + + +#ifndef FT_MACINTOSH + + /* The resource header says we've got resource_cnt `POST' (type1) */ + /* resources in this file. They all need to be coalesced into */ + /* one lump which gets passed on to the type1 driver. */ + /* Here can be only one PostScript font in a file so face_index */ + /* must be 0 (or -1). */ + /* */ + static FT_Error + Mac_Read_POST_Resource( FT_Library library, + FT_Stream stream, + FT_Long *offsets, + FT_Long resource_cnt, + FT_Long face_index, + FT_Face *aface ) + { + FT_Error error = FT_ERR( Cannot_Open_Resource ); + FT_Memory memory = library->memory; + FT_Byte* pfb_data = NULL; + int i, type, flags; + FT_Long len; + FT_Long pfb_len, pfb_pos, pfb_lenpos; + FT_Long rlen, temp; + + + if ( face_index == -1 ) + face_index = 0; + if ( face_index != 0 ) + return error; + + /* Find the length of all the POST resources, concatenated. Assume */ + /* worst case (each resource in its own section). */ + pfb_len = 0; + for ( i = 0; i < resource_cnt; ++i ) + { + error = FT_Stream_Seek( stream, offsets[i] ); + if ( error ) + goto Exit; + if ( FT_READ_LONG( temp ) ) + goto Exit; + pfb_len += temp + 6; + } + + if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) + goto Exit; + + pfb_data[0] = 0x80; + pfb_data[1] = 1; /* Ascii section */ + pfb_data[2] = 0; /* 4-byte length, fill in later */ + pfb_data[3] = 0; + pfb_data[4] = 0; + pfb_data[5] = 0; + pfb_pos = 6; + pfb_lenpos = 2; + + len = 0; + type = 1; + for ( i = 0; i < resource_cnt; ++i ) + { + error = FT_Stream_Seek( stream, offsets[i] ); + if ( error ) + goto Exit2; + if ( FT_READ_LONG( rlen ) ) + goto Exit; + if ( FT_READ_USHORT( flags ) ) + goto Exit; + FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", + i, offsets[i], rlen, flags )); + + /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ + if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ + continue; + + /* the flags are part of the resource, so rlen >= 2. */ + /* but some fonts declare rlen = 0 for empty fragment */ + if ( rlen > 2 ) + rlen -= 2; + else + rlen = 0; + + if ( ( flags >> 8 ) == type ) + len += rlen; + else + { + if ( pfb_lenpos + 3 > pfb_len + 2 ) + goto Exit2; + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); + pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); + pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); + pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); + + if ( ( flags >> 8 ) == 5 ) /* End of font mark */ + break; + + if ( pfb_pos + 6 > pfb_len + 2 ) + goto Exit2; + pfb_data[pfb_pos++] = 0x80; + + type = flags >> 8; + len = rlen; + + pfb_data[pfb_pos++] = (FT_Byte)type; + pfb_lenpos = pfb_pos; + pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */ + pfb_data[pfb_pos++] = 0; + pfb_data[pfb_pos++] = 0; + pfb_data[pfb_pos++] = 0; + } + + error = FT_ERR( Cannot_Open_Resource ); + if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len ) + goto Exit2; + + error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); + if ( error ) + goto Exit2; + pfb_pos += rlen; + } + + if ( pfb_pos + 2 > pfb_len + 2 ) + goto Exit2; + pfb_data[pfb_pos++] = 0x80; + pfb_data[pfb_pos++] = 3; + + if ( pfb_lenpos + 3 > pfb_len + 2 ) + goto Exit2; + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); + pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); + pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); + pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); + + return open_face_from_buffer( library, + pfb_data, + pfb_pos, + face_index, + "type1", + aface ); + + Exit2: + FT_FREE( pfb_data ); + + Exit: + return error; + } + + + /* The resource header says we've got resource_cnt `sfnt' */ + /* (TrueType/OpenType) resources in this file. Look through */ + /* them for the one indicated by face_index, load it into mem, */ + /* pass it on the the truetype driver and return it. */ + /* */ + static FT_Error + Mac_Read_sfnt_Resource( FT_Library library, + FT_Stream stream, + FT_Long *offsets, + FT_Long resource_cnt, + FT_Long face_index, + FT_Face *aface ) + { + FT_Memory memory = library->memory; + FT_Byte* sfnt_data = NULL; + FT_Error error; + FT_Long flag_offset; + FT_Long rlen; + int is_cff; + FT_Long face_index_in_resource = 0; + + + if ( face_index == -1 ) + face_index = 0; + if ( face_index >= resource_cnt ) + return FT_THROW( Cannot_Open_Resource ); + + flag_offset = offsets[face_index]; + error = FT_Stream_Seek( stream, flag_offset ); + if ( error ) + goto Exit; + + if ( FT_READ_LONG( rlen ) ) + goto Exit; + if ( rlen == -1 ) + return FT_THROW( Cannot_Open_Resource ); + + error = open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ); + if ( !error ) + goto Exit; + + /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ + if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + goto Exit; + + if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) + return error; + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); + if ( error ) + goto Exit; + + is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); + error = open_face_from_buffer( library, + sfnt_data, + rlen, + face_index_in_resource, + is_cff ? "cff" : "truetype", + aface ); + + Exit: + return error; + } + + + /* Check for a valid resource fork header, or a valid dfont */ + /* header. In a resource fork the first 16 bytes are repeated */ + /* at the location specified by bytes 4-7. In a dfont bytes */ + /* 4-7 point to 16 bytes of zeroes instead. */ + /* */ + static FT_Error + IsMacResource( FT_Library library, + FT_Stream stream, + FT_Long resource_offset, + FT_Long face_index, + FT_Face *aface ) + { + FT_Memory memory = library->memory; + FT_Error error; + FT_Long map_offset, rdara_pos; + FT_Long *data_offsets; + FT_Long count; + + + error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, + &map_offset, &rdara_pos ); + if ( error ) + return error; + + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + TTAG_POST, + &data_offsets, &count ); + if ( !error ) + { + 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; + } + + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + TTAG_sfnt, + &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_internal, aface ); + FT_FREE( data_offsets ); + if ( !error ) + (*aface)->num_faces = count; + } + + return error; + } + + + /* Check for a valid macbinary header, and if we find one */ + /* check that the (flattened) resource fork in it is valid. */ + /* */ + static FT_Error + IsMacBinary( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface ) + { + unsigned char header[128]; + FT_Error error; + FT_Long dlen, offset; + + + if ( NULL == stream ) + return FT_THROW( Invalid_Stream_Operation ); + + error = FT_Stream_Seek( stream, 0 ); + if ( error ) + goto Exit; + + error = FT_Stream_Read( stream, (FT_Byte*)header, 128 ); + if ( error ) + goto Exit; + + if ( header[ 0] != 0 || + header[74] != 0 || + header[82] != 0 || + header[ 1] == 0 || + header[ 1] > 33 || + header[63] != 0 || + header[2 + header[1]] != 0 ) + return FT_THROW( Unknown_File_Format ); + + dlen = ( header[0x53] << 24 ) | + ( header[0x54] << 16 ) | + ( header[0x55] << 8 ) | + header[0x56]; +#if 0 + rlen = ( header[0x57] << 24 ) | + ( header[0x58] << 16 ) | + ( header[0x59] << 8 ) | + header[0x5a]; +#endif /* 0 */ + offset = 128 + ( ( dlen + 127 ) & ~127 ); + + return IsMacResource( library, stream, offset, face_index, aface ); + + Exit: + return error; + } + + + static FT_Error + load_face_in_embedded_rfork( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface, + const FT_Open_Args *args ) + { + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + FT_Memory memory = library->memory; + FT_Error error = FT_ERR( Unknown_File_Format ); + int i; + + char * file_names[FT_RACCESS_N_RULES]; + FT_Long offsets[FT_RACCESS_N_RULES]; + FT_Error errors[FT_RACCESS_N_RULES]; + FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ + + FT_Open_Args args2; + FT_Stream stream2 = 0; + + + FT_Raccess_Guess( library, stream, + args->pathname, file_names, offsets, errors ); + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i ); + if ( is_darwin_vfs && vfs_rfork_has_no_font ) + { + FT_TRACE3(( "Skip rule %d: darwin vfs resource fork" + " is already checked and" + " no font is found\n", i )); + continue; + } + + if ( errors[i] ) + { + FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); + continue; + } + + args2.flags = FT_OPEN_PATHNAME; + args2.pathname = file_names[i] ? file_names[i] : args->pathname; + + FT_TRACE3(( "Try rule %d: %s (offset=%d) ...", + i, args2.pathname, offsets[i] )); + + error = FT_Stream_New( library, &args2, &stream2 ); + if ( is_darwin_vfs && FT_ERR_EQ( error, Cannot_Open_Stream ) ) + vfs_rfork_has_no_font = TRUE; + + if ( error ) + { + FT_TRACE3(( "failed\n" )); + continue; + } + + error = IsMacResource( library, stream2, offsets[i], + face_index, aface ); + FT_Stream_Free( stream2, 0 ); + + FT_TRACE3(( "%s\n", error ? "failed": "successful" )); + + if ( !error ) + break; + else if ( is_darwin_vfs ) + vfs_rfork_has_no_font = TRUE; + } + + for (i = 0; i < FT_RACCESS_N_RULES; i++) + { + if ( file_names[i] ) + FT_FREE( file_names[i] ); + } + + /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */ + if ( error ) + error = FT_ERR( Unknown_File_Format ); + + return error; + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + } + + + /* Check for some macintosh formats without Carbon framework. */ + /* Is this a macbinary file? If so look at the resource fork. */ + /* Is this a mac dfont file? */ + /* Is this an old style resource fork? (in data) */ + /* Else call load_face_in_embedded_rfork to try extra rules */ + /* (defined in `ftrfork.c'). */ + /* */ + static FT_Error + load_mac_face( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface, + const FT_Open_Args *args ) + { + FT_Error error; + FT_UNUSED( args ); + + + error = IsMacBinary( library, stream, face_index, aface ); + if ( FT_ERR_EQ( error, Unknown_File_Format ) ) + { + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); + + error = IsMacResource( library, stream, 0, face_index, aface ); + + FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + } + + if ( ( FT_ERR_EQ( error, Unknown_File_Format ) || + FT_ERR_EQ( error, Invalid_Stream_Operation ) ) && + ( args->flags & FT_OPEN_PATHNAME ) ) + error = load_face_in_embedded_rfork( library, stream, + face_index, aface, args ); + return error; + } +#endif + +#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ) + { + FT_Error error; + FT_Driver driver = NULL; + FT_Memory memory = NULL; + FT_Stream stream = NULL; + FT_Face face = NULL; + FT_ListNode node = NULL; + FT_Bool external_stream; + FT_Module* cur; + FT_Module* limit; + + + /* test for valid `library' delayed to */ + /* FT_Stream_New() */ + + if ( ( !aface && face_index >= 0 ) || !args ) + return FT_THROW( Invalid_Argument ); + + external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) && + args->stream ); + + /* create input stream */ + error = FT_Stream_New( library, args, &stream ); + if ( error ) + goto Fail3; + + memory = library->memory; + + /* If the font driver is specified in the `args' structure, use */ + /* it. Otherwise, we scan the list of registered drivers. */ + if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver ) + { + driver = FT_DRIVER( args->driver ); + + /* not all modules are drivers, so check... */ + if ( FT_MODULE_IS_DRIVER( driver ) ) + { + FT_Int num_params = 0; + FT_Parameter* params = 0; + + + if ( args->flags & FT_OPEN_PARAMS ) + { + num_params = args->num_params; + params = args->params; + } + + error = open_face( driver, stream, face_index, + num_params, params, &face ); + if ( !error ) + goto Success; + } + else + error = FT_THROW( Invalid_Handle ); + + FT_Stream_Free( stream, external_stream ); + goto Fail; + } + else + { + error = FT_ERR( Missing_Module ); + + /* check each font driver for an appropriate format */ + cur = library->modules; + limit = cur + library->num_modules; + + for ( ; cur < limit; cur++ ) + { + /* not all modules are font drivers, so check... */ + if ( FT_MODULE_IS_DRIVER( cur[0] ) ) + { + FT_Int num_params = 0; + FT_Parameter* params = 0; + + + driver = FT_DRIVER( cur[0] ); + + if ( args->flags & FT_OPEN_PARAMS ) + { + num_params = args->num_params; + params = args->params; + } + + error = open_face( driver, stream, face_index, + num_params, params, &face ); + if ( !error ) + goto Success; + +#ifdef FT_CONFIG_OPTION_MAC_FONTS + if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && + FT_ERR_EQ( error, Table_Missing ) ) + { + /* TrueType but essential tables are missing */ + if ( FT_Stream_Seek( stream, 0 ) ) + break; + + error = open_face_PS_from_sfnt_stream( library, + stream, + face_index, + num_params, + params, + aface ); + if ( !error ) + { + FT_Stream_Free( stream, external_stream ); + return error; + } + } +#endif + + if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) + goto Fail3; + } + } + + Fail3: + /* If we are on the mac, and we get an */ + /* FT_Err_Invalid_Stream_Operation it may be because we have an */ + /* empty data fork, so we need to check the resource fork. */ + if ( FT_ERR_NEQ( error, Cannot_Open_Stream ) && + FT_ERR_NEQ( error, Unknown_File_Format ) && + FT_ERR_NEQ( error, Invalid_Stream_Operation ) ) + goto Fail2; + +#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) + error = load_mac_face( library, stream, face_index, aface, args ); + if ( !error ) + { + /* We don't want to go to Success here. We've already done that. */ + /* On the other hand, if we succeeded we still need to close this */ + /* stream (we opened a different stream which extracted the */ + /* interesting information out of this stream here. That stream */ + /* will still be open and the face will point to it). */ + FT_Stream_Free( stream, external_stream ); + return error; + } + + if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) + goto Fail2; +#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ + + /* no driver is able to handle this format */ + error = FT_THROW( Unknown_File_Format ); + + Fail2: + FT_Stream_Free( stream, external_stream ); + goto Fail; + } + + Success: + FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); + + /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ + if ( external_stream ) + face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; + + /* add the face object to its driver's list */ + if ( FT_NEW( node ) ) + goto Fail; + + node->data = face; + /* don't assume driver is the same as face->driver, so use */ + /* face->driver instead. */ + FT_List_Add( &face->driver->faces_list, node ); + + /* now allocate a glyph slot object for the face */ + FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); + + if ( face_index >= 0 ) + { + error = FT_New_GlyphSlot( face, NULL ); + if ( error ) + goto Fail; + + /* finally, allocate a size object for the face */ + { + FT_Size size; + + + FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); + + error = FT_New_Size( face, &size ); + if ( error ) + goto Fail; + + face->size = size; + } + } + + /* some checks */ + + if ( FT_IS_SCALABLE( face ) ) + { + if ( face->height < 0 ) + face->height = (FT_Short)-face->height; + + if ( !FT_HAS_VERTICAL( face ) ) + face->max_advance_height = (FT_Short)face->height; + } + + if ( FT_HAS_FIXED_SIZES( face ) ) + { + FT_Int i; + + + for ( i = 0; i < face->num_fixed_sizes; i++ ) + { + FT_Bitmap_Size* bsize = face->available_sizes + i; + + + if ( bsize->height < 0 ) + bsize->height = (FT_Short)-bsize->height; + if ( bsize->x_ppem < 0 ) + bsize->x_ppem = (FT_Short)-bsize->x_ppem; + if ( bsize->y_ppem < 0 ) + bsize->y_ppem = -bsize->y_ppem; + } + } + + /* initialize internal face data */ + { + FT_Face_Internal internal = face->internal; + + + internal->transform_matrix.xx = 0x10000L; + internal->transform_matrix.xy = 0; + internal->transform_matrix.yx = 0; + internal->transform_matrix.yy = 0x10000L; + + internal->transform_delta.x = 0; + internal->transform_delta.y = 0; + + internal->refcount = 1; + } + + if ( aface ) + *aface = face; + else + FT_Done_Face( face ); + + goto Exit; + + Fail: + if ( node ) + FT_Done_Face( face ); /* face must be in the driver's list */ + else if ( face ) + destroy_face( memory, face, driver ); + + Exit: + FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ) + { + FT_Open_Args open; + + + /* test for valid `face' delayed to FT_Attach_Stream() */ + + if ( !filepathname ) + return FT_THROW( Invalid_Argument ); + + open.stream = NULL; + open.flags = FT_OPEN_PATHNAME; + open.pathname = (char*)filepathname; + + return FT_Attach_Stream( face, &open ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ) + { + FT_Stream stream; + FT_Error error; + FT_Driver driver; + + FT_Driver_Class clazz; + + + /* test for valid `parameters' delayed to FT_Stream_New() */ + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + driver = face->driver; + if ( !driver ) + return FT_THROW( Invalid_Driver_Handle ); + + error = FT_Stream_New( driver->root.library, parameters, &stream ); + if ( error ) + goto Exit; + + /* we implement FT_Attach_Stream in each driver through the */ + /* `attach_file' interface */ + + error = FT_ERR( Unimplemented_Feature ); + clazz = driver->clazz; + if ( clazz->attach_file ) + error = clazz->attach_file( face, stream ); + + /* close the attached stream */ + FT_Stream_Free( stream, + (FT_Bool)( parameters->stream && + ( parameters->flags & FT_OPEN_STREAM ) ) ); + + Exit: + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Reference_Face( FT_Face face ) + { + face->internal->refcount++; + + return FT_Err_Ok; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Face( FT_Face face ) + { + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_ListNode node; + + + error = FT_ERR( Invalid_Face_Handle ); + if ( face && face->driver ) + { + face->internal->refcount--; + if ( face->internal->refcount > 0 ) + error = FT_Err_Ok; + else + { + driver = face->driver; + memory = driver->root.memory; + + /* find face in driver's list */ + node = FT_List_Find( &driver->faces_list, face ); + if ( node ) + { + /* remove face object from the driver's list */ + FT_List_Remove( &driver->faces_list, node ); + FT_FREE( node ); + + /* now destroy the object proper */ + destroy_face( memory, face, driver ); + error = FT_Err_Ok; + } + } + } + + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size *asize ) + { + FT_Error error; + FT_Memory memory; + FT_Driver driver; + FT_Driver_Class clazz; + + FT_Size size = 0; + FT_ListNode node = 0; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !asize ) + return FT_THROW( Invalid_Size_Handle ); + + if ( !face->driver ) + return FT_THROW( Invalid_Driver_Handle ); + + *asize = 0; + + driver = face->driver; + clazz = driver->clazz; + memory = face->memory; + + /* Allocate new size object and perform basic initialisation */ + if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) + goto Exit; + + size->face = face; + + /* for now, do not use any internal fields in size objects */ + size->internal = 0; + + if ( clazz->init_size ) + error = clazz->init_size( size ); + + /* in case of success, add to the face's list */ + if ( !error ) + { + *asize = size; + node->data = size; + FT_List_Add( &face->sizes_list, node ); + } + + Exit: + if ( error ) + { + FT_FREE( node ); + FT_FREE( size ); + } + + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Size( FT_Size size ) + { + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_Face face; + FT_ListNode node; + + + if ( !size ) + return FT_THROW( Invalid_Size_Handle ); + + face = size->face; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + driver = face->driver; + if ( !driver ) + return FT_THROW( Invalid_Driver_Handle ); + + memory = driver->root.memory; + + error = FT_Err_Ok; + node = FT_List_Find( &face->sizes_list, size ); + if ( node ) + { + FT_List_Remove( &face->sizes_list, node ); + FT_FREE( node ); + + if ( face->size == size ) + { + face->size = 0; + if ( face->sizes_list.head ) + face->size = (FT_Size)(face->sizes_list.head->data); + } + + destroy_size( memory, size, driver ); + } + else + error = FT_THROW( Invalid_Size_Handle ); + + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( FT_Error ) + FT_Match_Size( FT_Face face, + FT_Size_Request req, + FT_Bool ignore_width, + FT_ULong* size_index ) + { + FT_Int i; + FT_Long w, h; + + + if ( !FT_HAS_FIXED_SIZES( face ) ) + return FT_THROW( Invalid_Face_Handle ); + + /* FT_Bitmap_Size doesn't provide enough info... */ + if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) + return FT_THROW( Unimplemented_Feature ); + + w = FT_REQUEST_WIDTH ( req ); + h = FT_REQUEST_HEIGHT( req ); + + if ( req->width && !req->height ) + h = w; + else if ( !req->width && req->height ) + w = h; + + w = FT_PIX_ROUND( w ); + h = FT_PIX_ROUND( h ); + + for ( i = 0; i < face->num_fixed_sizes; i++ ) + { + FT_Bitmap_Size* bsize = face->available_sizes + i; + + + if ( h != FT_PIX_ROUND( bsize->y_ppem ) ) + continue; + + if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width ) + { + FT_TRACE3(( "FT_Match_Size: bitmap strike %d matches\n", i )); + + if ( size_index ) + *size_index = (FT_ULong)i; + + return FT_Err_Ok; + } + } + + return FT_THROW( Invalid_Pixel_Size ); + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( void ) + ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, + FT_Pos advance ) + { + FT_Pos height = metrics->height; + + + /* compensate for glyph with bbox above/below the baseline */ + if ( metrics->horiBearingY < 0 ) + { + if ( height < metrics->horiBearingY ) + height = metrics->horiBearingY; + } + else if ( metrics->horiBearingY > 0 ) + height -= metrics->horiBearingY; + + /* the factor 1.2 is a heuristical value */ + if ( !advance ) + advance = height * 12 / 10; + + metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; + metrics->vertBearingY = ( advance - height ) / 2; + metrics->vertAdvance = advance; + } + + + static void + ft_recompute_scaled_metrics( FT_Face face, + FT_Size_Metrics* metrics ) + { + /* Compute root ascender, descender, test height, and max_advance */ + +#ifdef GRID_FIT_METRICS + metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender, + metrics->y_scale ) ); + + metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender, + metrics->y_scale ) ); + + metrics->height = FT_PIX_ROUND( FT_MulFix( face->height, + metrics->y_scale ) ); + + metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width, + metrics->x_scale ) ); +#else /* !GRID_FIT_METRICS */ + metrics->ascender = FT_MulFix( face->ascender, + metrics->y_scale ); + + metrics->descender = FT_MulFix( face->descender, + metrics->y_scale ); + + metrics->height = FT_MulFix( face->height, + metrics->y_scale ); + + metrics->max_advance = FT_MulFix( face->max_advance_width, + metrics->x_scale ); +#endif /* !GRID_FIT_METRICS */ + } + + + FT_BASE_DEF( void ) + FT_Select_Metrics( FT_Face face, + FT_ULong strike_index ) + { + FT_Size_Metrics* metrics; + FT_Bitmap_Size* bsize; + + + metrics = &face->size->metrics; + bsize = face->available_sizes + strike_index; + + metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 ); + metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 ); + + if ( FT_IS_SCALABLE( face ) ) + { + metrics->x_scale = FT_DivFix( bsize->x_ppem, + face->units_per_EM ); + metrics->y_scale = FT_DivFix( bsize->y_ppem, + face->units_per_EM ); + + ft_recompute_scaled_metrics( face, metrics ); + } + else + { + metrics->x_scale = 1L << 16; + metrics->y_scale = 1L << 16; + metrics->ascender = bsize->y_ppem; + metrics->descender = 0; + metrics->height = bsize->height << 6; + metrics->max_advance = bsize->x_ppem; + } + + FT_TRACE5(( "FT_Select_Metrics:\n" )); + FT_TRACE5(( " x scale: %d (%f)\n", + metrics->x_scale, metrics->x_scale / 65536.0 )); + FT_TRACE5(( " y scale: %d (%f)\n", + metrics->y_scale, metrics->y_scale / 65536.0 )); + FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); + FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); + FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); + FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); + FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); + FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); + } + + + FT_BASE_DEF( void ) + FT_Request_Metrics( FT_Face face, + FT_Size_Request req ) + { + FT_Size_Metrics* metrics; + + + metrics = &face->size->metrics; + + if ( FT_IS_SCALABLE( face ) ) + { + FT_Long w = 0, h = 0, scaled_w = 0, scaled_h = 0; + + + switch ( req->type ) + { + case FT_SIZE_REQUEST_TYPE_NOMINAL: + w = h = face->units_per_EM; + break; + + case FT_SIZE_REQUEST_TYPE_REAL_DIM: + w = h = face->ascender - face->descender; + break; + + case FT_SIZE_REQUEST_TYPE_BBOX: + w = face->bbox.xMax - face->bbox.xMin; + h = face->bbox.yMax - face->bbox.yMin; + break; + + case FT_SIZE_REQUEST_TYPE_CELL: + w = face->max_advance_width; + h = face->ascender - face->descender; + break; + + case FT_SIZE_REQUEST_TYPE_SCALES: + metrics->x_scale = (FT_Fixed)req->width; + metrics->y_scale = (FT_Fixed)req->height; + if ( !metrics->x_scale ) + metrics->x_scale = metrics->y_scale; + else if ( !metrics->y_scale ) + metrics->y_scale = metrics->x_scale; + goto Calculate_Ppem; + + case FT_SIZE_REQUEST_TYPE_MAX: + break; + } + + /* to be on the safe side */ + if ( w < 0 ) + w = -w; + + if ( h < 0 ) + h = -h; + + scaled_w = FT_REQUEST_WIDTH ( req ); + scaled_h = FT_REQUEST_HEIGHT( req ); + + /* determine scales */ + if ( req->width ) + { + metrics->x_scale = FT_DivFix( scaled_w, w ); + + if ( req->height ) + { + metrics->y_scale = FT_DivFix( scaled_h, h ); + + if ( req->type == FT_SIZE_REQUEST_TYPE_CELL ) + { + if ( metrics->y_scale > metrics->x_scale ) + metrics->y_scale = metrics->x_scale; + else + metrics->x_scale = metrics->y_scale; + } + } + else + { + metrics->y_scale = metrics->x_scale; + scaled_h = FT_MulDiv( scaled_w, h, w ); + } + } + else + { + metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h ); + scaled_w = FT_MulDiv( scaled_h, w, h ); + } + + Calculate_Ppem: + /* calculate the ppems */ + if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) + { + scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale ); + scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale ); + } + + metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 ); + metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 ); + + ft_recompute_scaled_metrics( face, metrics ); + } + else + { + FT_ZERO( metrics ); + metrics->x_scale = 1L << 16; + metrics->y_scale = 1L << 16; + } + + FT_TRACE5(( "FT_Request_Metrics:\n" )); + FT_TRACE5(( " x scale: %d (%f)\n", + metrics->x_scale, metrics->x_scale / 65536.0 )); + FT_TRACE5(( " y scale: %d (%f)\n", + metrics->y_scale, metrics->y_scale / 65536.0 )); + FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); + FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); + FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); + FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); + FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); + FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Select_Size( FT_Face face, + FT_Int strike_index ) + { + FT_Driver_Class clazz; + + + if ( !face || !FT_HAS_FIXED_SIZES( face ) ) + return FT_THROW( Invalid_Face_Handle ); + + if ( strike_index < 0 || strike_index >= face->num_fixed_sizes ) + return FT_THROW( Invalid_Argument ); + + clazz = face->driver->clazz; + + if ( clazz->select_size ) + { + FT_Error error; + + + error = clazz->select_size( face->size, (FT_ULong)strike_index ); + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Size_Metrics* metrics = &face->size->metrics; + + + FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" )); + FT_TRACE5(( " x scale: %d (%f)\n", + metrics->x_scale, metrics->x_scale / 65536.0 )); + FT_TRACE5(( " y scale: %d (%f)\n", + metrics->y_scale, metrics->y_scale / 65536.0 )); + FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); + FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); + FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); + FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); + FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); + FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); + } +#endif + + return error; + } + + FT_Select_Metrics( face, (FT_ULong)strike_index ); + + return FT_Err_Ok; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Request_Size( FT_Face face, + FT_Size_Request req ) + { + FT_Driver_Class clazz; + FT_ULong strike_index; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !req || req->width < 0 || req->height < 0 || + req->type >= FT_SIZE_REQUEST_TYPE_MAX ) + return FT_THROW( Invalid_Argument ); + + clazz = face->driver->clazz; + + if ( clazz->request_size ) + { + FT_Error error; + + + error = clazz->request_size( face->size, req ); + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Size_Metrics* metrics = &face->size->metrics; + + + FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" )); + FT_TRACE5(( " x scale: %d (%f)\n", + metrics->x_scale, metrics->x_scale / 65536.0 )); + FT_TRACE5(( " y scale: %d (%f)\n", + metrics->y_scale, metrics->y_scale / 65536.0 )); + FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); + FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); + FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); + FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); + FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); + FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); + } +#endif + + return error; + } + + /* + * The reason that a driver doesn't have `request_size' defined is + * either that the scaling here suffices or that the supported formats + * are bitmap-only and size matching is not implemented. + * + * In the latter case, a simple size matching is done. + */ + if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) ) + { + FT_Error error; + + + error = FT_Match_Size( face, req, 0, &strike_index ); + if ( error ) + return error; + + return FT_Select_Size( face, (FT_Int)strike_index ); + } + + FT_Request_Metrics( face, req ); + + return FT_Err_Ok; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ) + { + FT_Size_RequestRec req; + + + if ( !char_width ) + char_width = char_height; + else if ( !char_height ) + char_height = char_width; + + if ( !horz_resolution ) + horz_resolution = vert_resolution; + else if ( !vert_resolution ) + vert_resolution = horz_resolution; + + if ( char_width < 1 * 64 ) + char_width = 1 * 64; + if ( char_height < 1 * 64 ) + char_height = 1 * 64; + + if ( !horz_resolution ) + horz_resolution = vert_resolution = 72; + + req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + req.width = char_width; + req.height = char_height; + req.horiResolution = horz_resolution; + req.vertResolution = vert_resolution; + + return FT_Request_Size( face, &req ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ) + { + FT_Size_RequestRec req; + + + if ( pixel_width == 0 ) + pixel_width = pixel_height; + else if ( pixel_height == 0 ) + pixel_height = pixel_width; + + if ( pixel_width < 1 ) + pixel_width = 1; + if ( pixel_height < 1 ) + pixel_height = 1; + + /* use `>=' to avoid potential compiler warning on 16bit platforms */ + if ( pixel_width >= 0xFFFFU ) + pixel_width = 0xFFFFU; + if ( pixel_height >= 0xFFFFU ) + pixel_height = 0xFFFFU; + + req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + req.width = pixel_width << 6; + req.height = pixel_height << 6; + req.horiResolution = 0; + req.vertResolution = 0; + + return FT_Request_Size( face, &req ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ) + { + FT_Error error = FT_Err_Ok; + FT_Driver driver; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !akerning ) + return FT_THROW( Invalid_Argument ); + + driver = face->driver; + + akerning->x = 0; + akerning->y = 0; + + if ( driver->clazz->get_kerning ) + { + error = driver->clazz->get_kerning( face, + left_glyph, + right_glyph, + akerning ); + if ( !error ) + { + if ( kern_mode != FT_KERNING_UNSCALED ) + { + akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale ); + akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale ); + + if ( kern_mode != FT_KERNING_UNFITTED ) + { + /* we scale down kerning values for small ppem values */ + /* to avoid that rounding makes them too big. */ + /* `25' has been determined heuristically. */ + if ( face->size->metrics.x_ppem < 25 ) + akerning->x = FT_MulDiv( akerning->x, + face->size->metrics.x_ppem, 25 ); + if ( face->size->metrics.y_ppem < 25 ) + akerning->y = FT_MulDiv( akerning->y, + face->size->metrics.y_ppem, 25 ); + + akerning->x = FT_PIX_ROUND( akerning->x ); + akerning->y = FT_PIX_ROUND( akerning->y ); + } + } + } + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Track_Kerning( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ) + { + FT_Service_Kerning service; + FT_Error error = FT_Err_Ok; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !akerning ) + return FT_THROW( Invalid_Argument ); + + FT_FACE_FIND_SERVICE( face, service, KERNING ); + if ( !service ) + return FT_THROW( Unimplemented_Feature ); + + error = service->get_track( face, + point_size, + degree, + akerning ); + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ) + { + FT_CharMap* cur; + FT_CharMap* limit; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( encoding == FT_ENCODING_NONE ) + return FT_THROW( 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. */ + /* */ + /* This is done by find_unicode_charmap() above, to share code. */ + if ( encoding == FT_ENCODING_UNICODE ) + return find_unicode_charmap( face ); + + cur = face->charmaps; + if ( !cur ) + return FT_THROW( Invalid_CharMap_Handle ); + + limit = cur + face->num_charmaps; + + for ( ; cur < limit; cur++ ) + { + if ( cur[0]->encoding == encoding ) + { +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) + { + FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), " + "but in too late position to cache\n", + cur - face->charmaps )); + continue; + } +#endif + face->charmap = cur[0]; + return 0; + } + } + + return FT_THROW( Invalid_Argument ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ) + { + FT_CharMap* cur; + FT_CharMap* limit; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + cur = face->charmaps; + if ( !cur ) + return FT_THROW( Invalid_CharMap_Handle ); + if ( FT_Get_CMap_Format( charmap ) == 14 ) + return FT_THROW( Invalid_Argument ); + + limit = cur + face->num_charmaps; + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] == charmap ) + { +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) + { + FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), " + "but in too late position to cache\n", + cur - face->charmaps )); + continue; + } +#endif + face->charmap = cur[0]; + return 0; + } + } + return FT_THROW( Invalid_Argument ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Get_Charmap_Index( FT_CharMap charmap ) + { + FT_Int i; + + + if ( !charmap || !charmap->face ) + return -1; + + for ( i = 0; i < charmap->face->num_charmaps; i++ ) + if ( charmap->face->charmaps[i] == charmap ) + break; + + FT_ASSERT( i < charmap->face->num_charmaps ); + +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( i > FT_MAX_CHARMAP_CACHEABLE ) + { + FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), " + "but in too late position to cache\n", + i )); + return -i; + } +#endif + return i; + } + + + static void + ft_cmap_done_internal( FT_CMap cmap ) + { + FT_CMap_Class clazz = cmap->clazz; + FT_Face face = cmap->charmap.face; + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( clazz->done ) + clazz->done( cmap ); + + FT_FREE( cmap ); + } + + + FT_BASE_DEF( void ) + FT_CMap_Done( FT_CMap cmap ) + { + if ( cmap ) + { + FT_Face face = cmap->charmap.face; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Error error; + FT_Int i, j; + + + for ( i = 0; i < face->num_charmaps; i++ ) + { + if ( (FT_CMap)face->charmaps[i] == cmap ) + { + FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1]; + + + if ( FT_RENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps - 1 ) ) + return; + + /* remove it from our list of charmaps */ + for ( j = i + 1; j < face->num_charmaps; j++ ) + { + if ( j == face->num_charmaps - 1 ) + face->charmaps[j - 1] = last_charmap; + else + face->charmaps[j - 1] = face->charmaps[j]; + } + + face->num_charmaps--; + + if ( (FT_CMap)face->charmap == cmap ) + face->charmap = NULL; + + ft_cmap_done_internal( cmap ); + + break; + } + } + } + } + + + FT_BASE_DEF( FT_Error ) + FT_CMap_New( FT_CMap_Class clazz, + FT_Pointer init_data, + FT_CharMap charmap, + FT_CMap *acmap ) + { + FT_Error error = FT_Err_Ok; + FT_Face face; + FT_Memory memory; + FT_CMap cmap = NULL; + + + if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) + return FT_THROW( Invalid_Argument ); + + face = charmap->face; + memory = FT_FACE_MEMORY( face ); + + if ( !FT_ALLOC( cmap, clazz->size ) ) + { + cmap->charmap = *charmap; + cmap->clazz = clazz; + + if ( clazz->init ) + { + error = clazz->init( cmap, init_data ); + if ( error ) + goto Fail; + } + + /* add it to our list of charmaps */ + if ( FT_RENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps + 1 ) ) + goto Fail; + + face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; + } + + Exit: + if ( acmap ) + *acmap = cmap; + + return error; + + Fail: + ft_cmap_done_internal( cmap ); + cmap = NULL; + goto Exit; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ) + { + FT_UInt result = 0; + + + if ( face && face->charmap ) + { + FT_CMap cmap = FT_CMAP( face->charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); + } + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ) + { + FT_ULong result = 0; + FT_UInt gindex = 0; + + + if ( face && face->charmap && face->num_glyphs ) + { + gindex = FT_Get_Char_Index( face, 0 ); + if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs ) + result = FT_Get_Next_Char( face, 0, &gindex ); + } + + if ( agindex ) + *agindex = gindex; + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong charcode, + FT_UInt *agindex ) + { + FT_ULong result = 0; + FT_UInt gindex = 0; + + + if ( face && face->charmap && face->num_glyphs ) + { + FT_UInt32 code = (FT_UInt32)charcode; + FT_CMap cmap = FT_CMAP( face->charmap ); + + + do { + gindex = cmap->clazz->char_next( cmap, &code ); + } while ( gindex >= (FT_UInt)face->num_glyphs ); + + result = ( gindex == 0 ) ? 0 : code; + } + + if ( agindex ) + *agindex = gindex; + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_UInt result = 0; + + + if ( face && face->charmap && + face->charmap->encoding == FT_ENCODING_UNICODE ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + FT_CMap ucmap = FT_CMAP( face->charmap ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_index( vcmap, ucmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_Int result = -1; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_default( vcmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + result = vcmap->clazz->variant_list( vcmap, memory ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + + result = vcmap->clazz->charvariant_list( vcmap, memory, + (FT_UInt32)charcode ); + } + } + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->variantchar_list( vcmap, memory, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ) + { + FT_UInt result = 0; + + + if ( face && FT_HAS_GLYPH_NAMES( face ) ) + { + FT_Service_GlyphDict service; + + + FT_FACE_LOOKUP_SERVICE( face, + service, + GLYPH_DICT ); + + if ( service && service->name_index ) + result = service->name_index( face, glyph_name ); + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + + + /* clean up buffer */ + if ( buffer && buffer_max > 0 ) + ((FT_Byte*)buffer)[0] = 0; + + if ( face && + (FT_Long)glyph_index <= face->num_glyphs && + FT_HAS_GLYPH_NAMES( face ) ) + { + FT_Service_GlyphDict service; + + + FT_FACE_LOOKUP_SERVICE( face, + service, + GLYPH_DICT ); + + if ( service && service->get_name ) + error = service->get_name( face, glyph_index, buffer, buffer_max ); + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( const char* ) + FT_Get_Postscript_Name( FT_Face face ) + { + const char* result = NULL; + + + if ( !face ) + goto Exit; + + if ( !result ) + { + FT_Service_PsFontName service; + + + FT_FACE_LOOKUP_SERVICE( face, + service, + POSTSCRIPT_FONT_NAME ); + + if ( service && service->get_ps_font_name ) + result = service->get_ps_font_name( face ); + } + + Exit: + return result; + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ) + { + void* table = 0; + FT_Service_SFNT_Table service; + + + if ( face && FT_IS_SFNT( face ) ) + { + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + if ( service != NULL ) + table = service->get_table( face, tag ); + } + + return table; + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) + { + FT_Service_SFNT_Table service; + + + if ( !face || !FT_IS_SFNT( face ) ) + return FT_THROW( Invalid_Face_Handle ); + + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + if ( service == NULL ) + return FT_THROW( Unimplemented_Feature ); + + return service->load_table( face, tag, offset, buffer, length ); + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Sfnt_Table_Info( FT_Face face, + FT_UInt table_index, + FT_ULong *tag, + FT_ULong *length ) + { + FT_Service_SFNT_Table service; + FT_ULong offset; + + + if ( !face || !FT_IS_SFNT( face ) ) + return FT_THROW( Invalid_Face_Handle ); + + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + if ( service == NULL ) + return FT_THROW( Unimplemented_Feature ); + + return service->table_info( face, table_index, tag, &offset, length ); + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ) + { + FT_Service_TTCMaps service; + FT_Face face; + TT_CMapInfo cmap_info; + + + if ( !charmap || !charmap->face ) + return 0; + + face = charmap->face; + FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); + if ( service == NULL ) + return 0; + if ( service->get_cmap_info( charmap, &cmap_info )) + return 0; + + return cmap_info.language; + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_Get_CMap_Format( FT_CharMap charmap ) + { + FT_Service_TTCMaps service; + FT_Face face; + TT_CMapInfo cmap_info; + + + if ( !charmap || !charmap->face ) + return -1; + + face = charmap->face; + FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); + if ( service == NULL ) + return -1; + if ( service->get_cmap_info( charmap, &cmap_info )) + return -1; + + return cmap_info.format; + } + + + /* documentation is in ftsizes.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Activate_Size( FT_Size size ) + { + FT_Face face; + + + if ( size == NULL ) + return FT_THROW( Invalid_Argument ); + + face = size->face; + if ( face == NULL || face->driver == NULL ) + return FT_THROW( Invalid_Argument ); + + /* we don't need anything more complex than that; all size objects */ + /* are already listed by the face */ + face->size = size; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* lookup a renderer by glyph format in the library's list */ + FT_BASE_DEF( FT_Renderer ) + FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode* node ) + { + FT_ListNode cur; + FT_Renderer result = 0; + + + if ( !library ) + goto Exit; + + cur = library->renderers.head; + + if ( node ) + { + if ( *node ) + cur = (*node)->next; + *node = 0; + } + + while ( cur ) + { + FT_Renderer renderer = FT_RENDERER( cur->data ); + + + if ( renderer->glyph_format == format ) + { + if ( node ) + *node = cur; + + result = renderer; + break; + } + cur = cur->next; + } + + Exit: + return result; + } + + + static FT_Renderer + ft_lookup_glyph_renderer( FT_GlyphSlot slot ) + { + FT_Face face = slot->face; + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Renderer result = library->cur_renderer; + + + if ( !result || result->glyph_format != slot->format ) + result = FT_Lookup_Renderer( library, slot->format, 0 ); + + return result; + } + + + static void + ft_set_current_renderer( FT_Library library ) + { + FT_Renderer renderer; + + + renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 ); + library->cur_renderer = renderer; + } + + + static FT_Error + ft_add_renderer( FT_Module module ) + { + FT_Library library = module->library; + FT_Memory memory = library->memory; + FT_Error error; + FT_ListNode node = NULL; + + + if ( FT_NEW( node ) ) + goto Exit; + + { + FT_Renderer render = FT_RENDERER( module ); + FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; + + + render->clazz = clazz; + render->glyph_format = clazz->glyph_format; + + /* allocate raster object if needed */ + if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && + clazz->raster_class->raster_new ) + { + error = clazz->raster_class->raster_new( memory, &render->raster ); + if ( error ) + goto Fail; + + render->raster_render = clazz->raster_class->raster_render; + render->render = clazz->render_glyph; + } + + /* add to list */ + node->data = module; + FT_List_Add( &library->renderers, node ); + + ft_set_current_renderer( library ); + } + + Fail: + if ( error ) + FT_FREE( node ); + + Exit: + return error; + } + + + static void + ft_remove_renderer( FT_Module module ) + { + FT_Library library = module->library; + FT_Memory memory = library->memory; + FT_ListNode node; + + + node = FT_List_Find( &library->renderers, module ); + if ( node ) + { + FT_Renderer render = FT_RENDERER( module ); + + + /* release raster object, if any */ + if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && + render->raster ) + render->clazz->raster_class->raster_done( render->raster ); + + /* remove from list */ + FT_List_Remove( &library->renderers, node ); + FT_FREE( node ); + + ft_set_current_renderer( library ); + } + } + + + /* documentation is in ftrender.h */ + + FT_EXPORT_DEF( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ) + { + /* test for valid `library' delayed to FT_Lookup_Renderer() */ + + return FT_Lookup_Renderer( library, format, 0 ); + } + + + /* documentation is in ftrender.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ) + { + FT_ListNode node; + FT_Error error = FT_Err_Ok; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !renderer ) + return FT_THROW( Invalid_Argument ); + + node = FT_List_Find( &library->renderers, renderer ); + if ( !node ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_List_Up( &library->renderers, node ); + + if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) + library->cur_renderer = renderer; + + if ( num_params > 0 ) + { + FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; + + + for ( ; num_params > 0; num_params-- ) + { + error = set_mode( renderer, parameters->tag, parameters->data ); + if ( error ) + break; + parameters++; + } + } + + Exit: + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_Render_Mode render_mode ) + { + FT_Error error = FT_Err_Ok; + FT_Renderer renderer; + + + /* if it is already a bitmap, no need to do anything */ + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ + break; + + default: + { + FT_ListNode node = 0; + FT_Bool update = 0; + + + /* small shortcut for the very common case */ + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + renderer = library->cur_renderer; + node = library->renderers.head; + } + else + renderer = FT_Lookup_Renderer( library, slot->format, &node ); + + error = FT_ERR( Unimplemented_Feature ); + while ( renderer ) + { + error = renderer->render( renderer, slot, render_mode, NULL ); + if ( !error || + FT_ERR_NEQ( error, Cannot_Render_Glyph ) ) + break; + + /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ + /* is unsupported by the current renderer for this glyph image */ + /* format. */ + + /* now, look for another renderer that supports the same */ + /* format. */ + renderer = FT_Lookup_Renderer( library, slot->format, &node ); + update = 1; + } + + /* if we changed the current renderer for the glyph image format */ + /* we need to select it as the next current one */ + if ( !error && update && renderer ) + FT_Set_Renderer( library, renderer, 0, 0 ); + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + +#undef FT_COMPONENT +#define FT_COMPONENT trace_bitmap + + /* we convert to a single bitmap format for computing the checksum */ + { + FT_Bitmap bitmap; + FT_Error err; + + + FT_Bitmap_New( &bitmap ); + + err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); + if ( !err ) + { + MD5_CTX ctx; + unsigned char md5[16]; + int i; + + + MD5_Init( &ctx); + MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch ); + MD5_Final( md5, &ctx ); + + FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" + " ", + bitmap.rows, bitmap.pitch )); + for ( i = 0; i < 16; i++ ) + FT_TRACE3(( "%02X", md5[i] )); + FT_TRACE3(( "\n" )); + } + + FT_Bitmap_Done( library, &bitmap ); + } + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ) + { + FT_Library library; + + + if ( !slot || !slot->face ) + return FT_THROW( Invalid_Argument ); + + library = FT_FACE_LIBRARY( slot->face ); + + return FT_Render_Glyph_Internal( library, slot, render_mode ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Destroy_Module */ + /* */ + /* <Description> */ + /* Destroys a given module object. For drivers, this also destroys */ + /* all child faces. */ + /* */ + /* <InOut> */ + /* module :: A handle to the target driver object. */ + /* */ + /* <Note> */ + /* The driver _must_ be LOCKED! */ + /* */ + static void + Destroy_Module( FT_Module module ) + { + FT_Memory memory = module->memory; + FT_Module_Class* clazz = module->clazz; + FT_Library library = module->library; + + + if ( library && library->auto_hinter == module ) + library->auto_hinter = 0; + + /* if the module is a renderer */ + if ( FT_MODULE_IS_RENDERER( module ) ) + ft_remove_renderer( module ); + + /* if the module is a font driver, add some steps */ + if ( FT_MODULE_IS_DRIVER( module ) ) + Destroy_Driver( FT_DRIVER( module ) ); + + /* finalize the module object */ + if ( clazz->module_done ) + clazz->module_done( module ); + + /* discard it */ + FT_FREE( module ); + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ) + { + FT_Error error; + FT_Memory memory; + FT_Module module; + FT_UInt nn; + + +#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ + FREETYPE_MINOR ) + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !clazz ) + return FT_THROW( Invalid_Argument ); + + /* check freetype version */ + if ( clazz->module_requires > FREETYPE_VER_FIXED ) + return FT_THROW( Invalid_Version ); + + /* look for a module with the same name in the library's table */ + for ( nn = 0; nn < library->num_modules; nn++ ) + { + module = library->modules[nn]; + if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) + { + /* this installed module has the same name, compare their versions */ + if ( clazz->module_version <= module->clazz->module_version ) + return FT_THROW( Lower_Module_Version ); + + /* remove the module from our list, then exit the loop to replace */ + /* it by our new version.. */ + FT_Remove_Module( library, module ); + break; + } + } + + memory = library->memory; + error = FT_Err_Ok; + + if ( library->num_modules >= FT_MAX_MODULES ) + { + error = FT_THROW( Too_Many_Drivers ); + goto Exit; + } + + /* allocate module object */ + if ( FT_ALLOC( module, clazz->module_size ) ) + goto Exit; + + /* base initialization */ + module->library = library; + module->memory = memory; + module->clazz = (FT_Module_Class*)clazz; + + /* check whether the module is a renderer - this must be performed */ + /* before the normal module initialization */ + if ( FT_MODULE_IS_RENDERER( module ) ) + { + /* add to the renderers list */ + error = ft_add_renderer( module ); + if ( error ) + goto Fail; + } + + /* is the module a auto-hinter? */ + if ( FT_MODULE_IS_HINTER( module ) ) + library->auto_hinter = module; + + /* if the module is a font driver */ + if ( FT_MODULE_IS_DRIVER( module ) ) + { + /* allocate glyph loader if needed */ + FT_Driver driver = FT_DRIVER( module ); + + + driver->clazz = (FT_Driver_Class)module->clazz; + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + { + error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); + if ( error ) + goto Fail; + } + } + + if ( clazz->module_init ) + { + error = clazz->module_init( module ); + if ( error ) + goto Fail; + } + + /* add module to the library's table */ + library->modules[library->num_modules++] = module; + + Exit: + return error; + + Fail: + if ( FT_MODULE_IS_DRIVER( module ) ) + { + FT_Driver driver = FT_DRIVER( module ); + + + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + FT_GlyphLoader_Done( driver->glyph_loader ); + } + + if ( FT_MODULE_IS_RENDERER( module ) ) + { + FT_Renderer renderer = FT_RENDERER( module ); + + + if ( renderer->clazz && + renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && + renderer->raster ) + renderer->clazz->raster_class->raster_done( renderer->raster ); + } + + FT_FREE( module ); + goto Exit; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ) + { + FT_Module result = 0; + FT_Module* cur; + FT_Module* limit; + + + if ( !library || !module_name ) + return result; + + cur = library->modules; + limit = cur + library->num_modules; + + for ( ; cur < limit; cur++ ) + if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) + { + result = cur[0]; + break; + } + + return result; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( const void* ) + FT_Get_Module_Interface( FT_Library library, + const char* mod_name ) + { + FT_Module module; + + + /* test for valid `library' delayed to FT_Get_Module() */ + + module = FT_Get_Module( library, mod_name ); + + return module ? module->clazz->module_interface : 0; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_module_get_service( FT_Module module, + const char* service_id ) + { + FT_Pointer result = NULL; + + + if ( module ) + { + FT_ASSERT( module->clazz && module->clazz->get_interface ); + + /* first, look for the service in the module */ + if ( module->clazz->get_interface ) + result = module->clazz->get_interface( module, service_id ); + + if ( result == NULL ) + { + /* we didn't find it, look in all other modules then */ + FT_Library library = module->library; + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] != module ) + { + FT_ASSERT( cur[0]->clazz ); + + if ( cur[0]->clazz->get_interface ) + { + result = cur[0]->clazz->get_interface( cur[0], service_id ); + if ( result != NULL ) + break; + } + } + } + } + } + + return result; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ) + { + /* try to find the module from the table, then remove it from there */ + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( module ) + { + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] == module ) + { + /* remove it from the table */ + library->num_modules--; + limit--; + while ( cur < limit ) + { + cur[0] = cur[1]; + cur++; + } + limit[0] = 0; + + /* destroy the module */ + Destroy_Module( module ); + + return FT_Err_Ok; + } + } + } + return FT_THROW( Invalid_Driver_Handle ); + } + + + FT_Error + ft_property_do( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + void* value, + FT_Bool set ) + { + FT_Module* cur; + FT_Module* limit; + FT_Module_Interface interface; + + FT_Service_Properties service; + +#ifdef FT_DEBUG_LEVEL_ERROR + const FT_String* set_name = "FT_Property_Set"; + const FT_String* get_name = "FT_Property_Get"; + const FT_String* func_name = set ? set_name : get_name; +#endif + + FT_Bool missing_func; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !module_name || !property_name || !value ) + return FT_THROW( Invalid_Argument ); + + cur = library->modules; + limit = cur + library->num_modules; + + /* search module */ + for ( ; cur < limit; cur++ ) + if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) ) + break; + + if ( cur == limit ) + { + FT_ERROR(( "%s: can't find module `%s'\n", + func_name, module_name )); + return FT_THROW( Missing_Module ); + } + + /* check whether we have a service interface */ + if ( !cur[0]->clazz->get_interface ) + { + FT_ERROR(( "%s: module `%s' doesn't support properties\n", + func_name, module_name )); + return FT_THROW( Unimplemented_Feature ); + } + + /* search property service */ + interface = cur[0]->clazz->get_interface( cur[0], + FT_SERVICE_ID_PROPERTIES ); + if ( !interface ) + { + FT_ERROR(( "%s: module `%s' doesn't support properties\n", + func_name, module_name )); + return FT_THROW( Unimplemented_Feature ); + } + + service = (FT_Service_Properties)interface; + + if ( set ) + missing_func = (FT_Bool)( !service->set_property ); + else + missing_func = (FT_Bool)( !service->get_property ); + + if ( missing_func ) + { + FT_ERROR(( "%s: property service of module `%s' is broken\n", + func_name, module_name )); + return FT_THROW( Unimplemented_Feature ); + } + + return set ? service->set_property( cur[0], property_name, value ) + : service->get_property( cur[0], property_name, value ); + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Property_Set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + const void* value ) + { + return ft_property_do( library, + module_name, + property_name, + (void*)value, + TRUE ); + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Property_Get( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + void* value ) + { + return ft_property_do( library, + module_name, + property_name, + value, + FALSE ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Reference_Library( FT_Library library ) + { + library->refcount++; + + return FT_Err_Ok; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ) + { + FT_Library library = NULL; + FT_Error error; + + + if ( !memory ) + return FT_THROW( Invalid_Argument ); + +#ifdef FT_DEBUG_LEVEL_ERROR + /* init debugging support */ + ft_debug_init(); +#endif + + /* first of all, allocate the library object */ + if ( FT_NEW( library ) ) + return error; + + library->memory = memory; + +#ifdef FT_CONFIG_OPTION_PIC + /* initialize position independent code containers */ + error = ft_pic_container_init( library ); + if ( error ) + goto Fail; +#endif + + /* allocate the render pool */ + library->raster_pool_size = FT_RENDER_POOL_SIZE; +#if FT_RENDER_POOL_SIZE > 0 + if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) + goto Fail; +#endif + + library->version_major = FREETYPE_MAJOR; + library->version_minor = FREETYPE_MINOR; + library->version_patch = FREETYPE_PATCH; + + library->refcount = 1; + + /* That's ok now */ + *alibrary = library; + + return FT_Err_Ok; + + Fail: +#ifdef FT_CONFIG_OPTION_PIC + ft_pic_container_destroy( library ); +#endif + FT_FREE( library ); + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ) + { + FT_Int major = 0; + FT_Int minor = 0; + FT_Int patch = 0; + + + if ( library ) + { + major = library->version_major; + minor = library->version_minor; + patch = library->version_patch; + } + + if ( amajor ) + *amajor = major; + + if ( aminor ) + *aminor = minor; + + if ( apatch ) + *apatch = patch; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Library( FT_Library library ) + { + FT_Memory memory; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + library->refcount--; + if ( library->refcount > 0 ) + goto Exit; + + memory = library->memory; + + /* + * 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 + * + * Some faces are dependent on other faces, like Type42 faces that + * depend on TrueType faces synthesized internally. + * + * The order of drivers should be specified in driver_name[]. + */ + { + FT_UInt m, n; + const char* driver_name[] = { "type42", NULL }; + + + for ( m = 0; + m < sizeof ( driver_name ) / sizeof ( driver_name[0] ); + m++ ) + { + for ( n = 0; n < library->num_modules; n++ ) + { + FT_Module module = library->modules[n]; + const char* module_name = module->clazz->module_name; + FT_List faces; + + + if ( driver_name[m] && + ft_strcmp( module_name, driver_name[m] ) != 0 ) + continue; + + if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 ) + continue; + + FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name )); + + faces = &FT_DRIVER( module )->faces_list; + while ( faces->head ) + { + FT_Done_Face( FT_FACE( faces->head->data ) ); + if ( faces->head ) + FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" )); + } + } + } + } + + /* 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 */ + /* avoids double free in some occasions. It is a hack. */ + while ( library->num_modules > 0 ) + FT_Remove_Module( library, + library->modules[library->num_modules - 1] ); +#else + { + FT_UInt n; + + + for ( n = 0; n < library->num_modules; n++ ) + { + FT_Module module = library->modules[n]; + + + if ( module ) + { + Destroy_Module( module ); + library->modules[n] = 0; + } + } + } +#endif + + /* Destroy raster objects */ + FT_FREE( library->raster_pool ); + library->raster_pool_size = 0; + +#ifdef FT_CONFIG_OPTION_PIC + /* Destroy pic container contents */ + ft_pic_container_destroy( library ); +#endif + + FT_FREE( library ); + + Exit: + return FT_Err_Ok; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ) + { + if ( library && debug_hook && + hook_index < + ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) + library->debug_hooks[hook_index] = debug_hook; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_TrueTypeEngineType ) + FT_Get_TrueType_Engine_Type( FT_Library library ) + { + FT_TrueTypeEngineType result = FT_TRUETYPE_ENGINE_TYPE_NONE; + + + if ( library ) + { + FT_Module module = FT_Get_Module( library, "truetype" ); + + + if ( module ) + { + FT_Service_TrueTypeEngine service; + + + service = (FT_Service_TrueTypeEngine) + ft_module_get_service( module, + FT_SERVICE_ID_TRUETYPE_ENGINE ); + if ( service ) + result = service->engine_type; + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, + FT_UInt sub_index, + FT_Int *p_index, + FT_UInt *p_flags, + FT_Int *p_arg1, + FT_Int *p_arg2, + FT_Matrix *p_transform ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + + + if ( glyph && + glyph->subglyphs && + 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; + *p_arg1 = subg->arg1; + *p_arg2 = subg->arg2; + *p_transform = subg->transform; + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftotval.c b/drivers/freetype/src/base/ftotval.c new file mode 100644 index 0000000000..5fc73d76ab --- /dev/null +++ b/drivers/freetype/src/base/ftotval.c @@ -0,0 +1,91 @@ +/***************************************************************************/ +/* */ +/* ftotval.c */ +/* */ +/* FreeType API for validating OpenType tables (body). */ +/* */ +/* Copyright 2004, 2006, 2008, 2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_OPENTYPE_VALIDATE_H +#include FT_OPENTYPE_VALIDATE_H + + + /* documentation is in ftotval.h */ + + FT_EXPORT_DEF( 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 *JSTF_table ) + { + FT_Service_OTvalidate service; + FT_Error error; + + + if ( !face ) + { + error = FT_THROW( Invalid_Face_Handle ); + goto Exit; + } + + if ( !( BASE_table && + GDEF_table && + GPOS_table && + GSUB_table && + JSTF_table ) ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, service, OPENTYPE_VALIDATE ); + + if ( service ) + error = service->validate( face, + validation_flags, + BASE_table, + GDEF_table, + GPOS_table, + GSUB_table, + JSTF_table ); + else + error = FT_THROW( Unimplemented_Feature ); + + Exit: + return error; + } + + + FT_EXPORT_DEF( void ) + FT_OpenType_Free( FT_Face face, + FT_Bytes table ) + { + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + FT_FREE( table ); + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftoutln.c b/drivers/freetype/src/base/ftoutln.c new file mode 100644 index 0000000000..54ca5cdcf6 --- /dev/null +++ b/drivers/freetype/src/base/ftoutln.c @@ -0,0 +1,1081 @@ +/***************************************************************************/ +/* */ +/* ftoutln.c */ +/* */ +/* FreeType outline management (body). */ +/* */ +/* Copyright 1996-2008, 2010, 2012-2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* All functions are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_TRIGONOMETRY_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_outline + + + static + const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ) + { +#undef SCALED +#define SCALED( x ) ( ( (x) << shift ) - delta ) + + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + FT_Error error; + + FT_Int n; /* index of contour in outline */ + FT_UInt first; /* index of first point in contour */ + FT_Int tag; /* current point's state */ + + FT_Int shift; + FT_Pos delta; + + + if ( !outline || !func_interface ) + return FT_THROW( Invalid_Argument ); + + shift = func_interface->shift; + delta = func_interface->delta; + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + FT_Int last; /* index of last point in contour */ + + + FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + + last = outline->contours[n]; + if ( last < 0 ) + goto Invalid_Outline; + limit = outline->points + last; + + v_start = outline->points[first]; + v_start.x = SCALED( v_start.x ); + v_start.y = SCALED( v_start.y ); + + v_last = outline->points[last]; + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + FT_TRACE5(( " move to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); + error = func_interface->move_to( &v_start, user ); + if ( error ) + goto Exit; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + FT_TRACE5(( " line to (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0 )); + error = func_interface->line_to( &vec, user ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point->x ); + v_control.y = SCALED( point->y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_middle.x / 64.0, v_middle.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_middle, user ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_start, user ); + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1.x = SCALED( point[-2].x ); + vec1.y = SCALED( point[-2].y ); + + vec2.x = SCALED( point[-1].x ); + vec2.y = SCALED( point[-1].y ); + + if ( point <= limit ) + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); + error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); + error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); + goto Close; + } + } + } + + /* close the contour with a line segment */ + FT_TRACE5(( " line to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); + error = func_interface->line_to( &v_start, user ); + + Close: + if ( error ) + goto Exit; + + first = last + 1; + } + + FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); + return FT_Err_Ok; + + Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); + return error; + + Invalid_Outline: + return FT_THROW( Invalid_Outline ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ) + { + FT_Error error; + + + if ( !anoutline || !memory ) + return FT_THROW( Invalid_Argument ); + + *anoutline = null_outline; + + if ( numContours < 0 || + (FT_UInt)numContours > numPoints ) + return FT_THROW( Invalid_Argument ); + + if ( numPoints > FT_OUTLINE_POINTS_MAX ) + return FT_THROW( Array_Too_Large ); + + if ( FT_NEW_ARRAY( anoutline->points, numPoints ) || + FT_NEW_ARRAY( anoutline->tags, numPoints ) || + FT_NEW_ARRAY( anoutline->contours, numContours ) ) + goto Fail; + + anoutline->n_points = (FT_UShort)numPoints; + anoutline->n_contours = (FT_Short)numContours; + anoutline->flags |= FT_OUTLINE_OWNER; + + return FT_Err_Ok; + + Fail: + anoutline->flags |= FT_OUTLINE_OWNER; + FT_Outline_Done_Internal( memory, anoutline ); + + return error; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ) + { + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + return FT_Outline_New_Internal( library->memory, numPoints, + numContours, anoutline ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Check( FT_Outline* outline ) + { + if ( outline ) + { + FT_Int n_points = outline->n_points; + FT_Int n_contours = outline->n_contours; + FT_Int end0, end; + FT_Int n; + + + /* empty glyph? */ + if ( n_points == 0 && n_contours == 0 ) + return 0; + + /* check point and contour counts */ + if ( n_points <= 0 || n_contours <= 0 ) + goto Bad; + + end0 = end = -1; + for ( n = 0; n < n_contours; n++ ) + { + end = outline->contours[n]; + + /* note that we don't accept empty contours */ + if ( end <= end0 || end >= n_points ) + goto Bad; + + end0 = end; + } + + if ( end != n_points - 1 ) + goto Bad; + + /* XXX: check the tags array */ + return 0; + } + + Bad: + return FT_THROW( Invalid_Argument ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Copy( const FT_Outline* source, + FT_Outline *target ) + { + FT_Int is_owner; + + + if ( !source || !target || + source->n_points != target->n_points || + source->n_contours != target->n_contours ) + return FT_THROW( Invalid_Argument ); + + if ( source == target ) + return FT_Err_Ok; + + FT_ARRAY_COPY( target->points, source->points, source->n_points ); + + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); + + /* copy all flags, except the `FT_OUTLINE_OWNER' one */ + is_owner = target->flags & FT_OUTLINE_OWNER; + target->flags = source->flags; + + target->flags &= ~FT_OUTLINE_OWNER; + target->flags |= is_owner; + + return FT_Err_Ok; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ) + { + if ( memory && outline ) + { + if ( outline->flags & FT_OUTLINE_OWNER ) + { + FT_FREE( outline->points ); + FT_FREE( outline->tags ); + FT_FREE( outline->contours ); + } + *outline = null_outline; + + return FT_Err_Ok; + } + else + return FT_THROW( Invalid_Argument ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ) + { + /* check for valid `outline' in FT_Outline_Done_Internal() */ + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + return FT_Outline_Done_Internal( library->memory, outline ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ) + { + FT_Pos xMin, yMin, xMax, yMax; + + + if ( outline && acbox ) + { + if ( outline->n_points == 0 ) + { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } + else + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for ( ; vec < limit; vec++ ) + { + FT_Pos x, y; + + + x = vec->x; + if ( x < xMin ) xMin = x; + if ( x > xMax ) xMax = x; + + y = vec->y; + if ( y < yMin ) yMin = y; + if ( y > yMax ) yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Translate( const FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ) + { + FT_UShort n; + FT_Vector* vec; + + + if ( !outline ) + return; + + vec = outline->points; + + for ( n = 0; n < outline->n_points; n++ ) + { + vec->x += xOffset; + vec->y += yOffset; + vec++; + } + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Reverse( FT_Outline* outline ) + { + FT_UShort n; + FT_Int first, last; + + + if ( !outline ) + return; + + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + last = outline->contours[n]; + + /* reverse point table */ + { + FT_Vector* p = outline->points + first; + FT_Vector* q = outline->points + last; + FT_Vector swap; + + + while ( p < q ) + { + swap = *p; + *p = *q; + *q = swap; + p++; + q--; + } + } + + /* reverse tags table */ + { + char* p = outline->tags + first; + char* q = outline->tags + last; + char swap; + + + while ( p < q ) + { + swap = *p; + *p = *q; + *q = swap; + p++; + q--; + } + } + + first = last + 1; + } + + outline->flags ^= FT_OUTLINE_REVERSE_FILL; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ) + { + FT_Error error; + FT_Bool update = FALSE; + FT_Renderer renderer; + FT_ListNode node; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !outline || !params ) + return FT_THROW( Invalid_Argument ); + + renderer = library->cur_renderer; + node = library->renderers.head; + + params->source = (void*)outline; + + error = FT_ERR( Cannot_Render_Glyph ); + while ( renderer ) + { + error = renderer->raster_render( renderer->raster, params ); + if ( !error || FT_ERR_NEQ( error, Cannot_Render_Glyph ) ) + break; + + /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ + /* is unsupported by the current renderer for this glyph image */ + /* format */ + + /* now, look for another renderer that supports the same */ + /* format */ + renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, + &node ); + update = TRUE; + } + + /* if we changed the current renderer for the glyph image format */ + /* we need to select it as the next current one */ + if ( !error && update && renderer ) + FT_Set_Renderer( library, renderer, 0, 0 ); + + return error; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + const FT_Bitmap *abitmap ) + { + FT_Raster_Params params; + + + if ( !abitmap ) + return FT_THROW( Invalid_Argument ); + + /* other checks are delayed to FT_Outline_Render() */ + + params.target = abitmap; + params.flags = 0; + + if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY || + abitmap->pixel_mode == FT_PIXEL_MODE_LCD || + abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V ) + params.flags |= FT_RASTER_FLAG_AA; + + return FT_Outline_Render( library, outline, ¶ms ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Transform( FT_Vector* vector, + const FT_Matrix* matrix ) + { + FT_Pos xz, yz; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulFix( vector->x, matrix->xx ) + + FT_MulFix( vector->y, matrix->xy ); + + yz = FT_MulFix( vector->x, matrix->yx ) + + FT_MulFix( vector->y, matrix->yy ); + + vector->x = xz; + vector->y = yz; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Transform( const FT_Outline* outline, + const FT_Matrix* matrix ) + { + FT_Vector* vec; + FT_Vector* limit; + + + if ( !outline || !matrix ) + return; + + vec = outline->points; + limit = vec + outline->n_points; + + for ( ; vec < limit; vec++ ) + FT_Vector_Transform( vec, matrix ); + } + + +#if 0 + +#define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \ + do { \ + (first) = ( c > 0 ) ? (outline)->points + \ + (outline)->contours[c - 1] + 1 \ + : (outline)->points; \ + (last) = (outline)->points + (outline)->contours[c]; \ + } while ( 0 ) + + + /* Is a point in some contour? */ + /* */ + /* We treat every point of the contour as if it */ + /* it were ON. That is, we allow false positives, */ + /* but disallow false negatives. (XXX really?) */ + static FT_Bool + ft_contour_has( FT_Outline* outline, + FT_Short c, + FT_Vector* point ) + { + FT_Vector* first; + FT_Vector* last; + FT_Vector* a; + FT_Vector* b; + FT_UInt n = 0; + + + FT_OUTLINE_GET_CONTOUR( outline, c, first, last ); + + for ( a = first; a <= last; a++ ) + { + FT_Pos x; + FT_Int intersect; + + + b = ( a == last ) ? first : a + 1; + + intersect = ( a->y - point->y ) ^ ( b->y - point->y ); + + /* a and b are on the same side */ + if ( intersect >= 0 ) + { + if ( intersect == 0 && a->y == point->y ) + { + if ( ( a->x <= point->x && b->x >= point->x ) || + ( a->x >= point->x && b->x <= point->x ) ) + return 1; + } + + continue; + } + + x = a->x + ( b->x - a->x ) * (point->y - a->y ) / ( b->y - a->y ); + + if ( x < point->x ) + n++; + else if ( x == point->x ) + return 1; + } + + return n & 1; + } + + + static FT_Bool + ft_contour_enclosed( FT_Outline* outline, + FT_UShort c ) + { + FT_Vector* first; + FT_Vector* last; + FT_Short i; + + + FT_OUTLINE_GET_CONTOUR( outline, c, first, last ); + + for ( i = 0; i < outline->n_contours; i++ ) + { + if ( i != c && ft_contour_has( outline, i, first ) ) + { + FT_Vector* pt; + + + for ( pt = first + 1; pt <= last; pt++ ) + if ( !ft_contour_has( outline, i, pt ) ) + return 0; + + return 1; + } + } + + return 0; + } + + + /* This version differs from the public one in that each */ + /* part (contour not enclosed in another contour) of the */ + /* outline is checked for orientation. This is */ + /* necessary for some buggy CJK fonts. */ + static FT_Orientation + ft_outline_get_orientation( FT_Outline* outline ) + { + FT_Short i; + FT_Vector* first; + FT_Vector* last; + FT_Orientation orient = FT_ORIENTATION_NONE; + + + first = outline->points; + for ( i = 0; i < outline->n_contours; i++, first = last + 1 ) + { + FT_Vector* point; + FT_Vector* xmin_point; + FT_Pos xmin; + + + last = outline->points + outline->contours[i]; + + /* skip degenerate contours */ + if ( last < first + 2 ) + continue; + + if ( ft_contour_enclosed( outline, i ) ) + continue; + + xmin = first->x; + xmin_point = first; + + for ( point = first + 1; point <= last; point++ ) + { + if ( point->x < xmin ) + { + xmin = point->x; + xmin_point = point; + } + } + + /* check the orientation of the contour */ + { + FT_Vector* prev; + FT_Vector* next; + FT_Orientation o; + + + prev = ( xmin_point == first ) ? last : xmin_point - 1; + next = ( xmin_point == last ) ? first : xmin_point + 1; + + 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 ) ) + o = FT_ORIENTATION_POSTSCRIPT; + else + o = FT_ORIENTATION_TRUETYPE; + + if ( orient == FT_ORIENTATION_NONE ) + orient = o; + else if ( orient != o ) + return FT_ORIENTATION_NONE; + } + } + + return orient; + } + +#endif /* 0 */ + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Embolden( FT_Outline* outline, + FT_Pos strength ) + { + return FT_Outline_EmboldenXY( outline, strength, strength ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_EmboldenXY( FT_Outline* outline, + FT_Pos xstrength, + FT_Pos ystrength ) + { + FT_Vector* points; + FT_Vector v_prev, v_first, v_next, v_cur; + FT_Int c, n, first; + FT_Int orientation; + + + if ( !outline ) + return FT_THROW( Invalid_Argument ); + + xstrength /= 2; + ystrength /= 2; + if ( xstrength == 0 && ystrength == 0 ) + return FT_Err_Ok; + + orientation = FT_Outline_Get_Orientation( outline ); + if ( orientation == FT_ORIENTATION_NONE ) + { + if ( outline->n_contours ) + return FT_THROW( Invalid_Argument ); + else + return FT_Err_Ok; + } + + points = outline->points; + + first = 0; + for ( c = 0; c < outline->n_contours; c++ ) + { + FT_Vector in, out, shift; + FT_Fixed l_in, l_out, l, q, d; + int last = outline->contours[c]; + + + v_first = points[first]; + v_prev = points[last]; + v_cur = v_first; + + /* compute incoming normalized vector */ + in.x = v_cur.x - v_prev.x; + in.y = v_cur.y - v_prev.y; + l_in = FT_Vector_Length( &in ); + if ( l_in ) + { + in.x = FT_DivFix( in.x, l_in ); + in.y = FT_DivFix( in.y, l_in ); + } + + for ( n = first; n <= last; n++ ) + { + if ( n < last ) + v_next = points[n + 1]; + else + v_next = v_first; + + /* compute outgoing normalized vector */ + out.x = v_next.x - v_cur.x; + out.y = v_next.y - v_cur.y; + l_out = FT_Vector_Length( &out ); + if ( l_out ) + { + out.x = FT_DivFix( out.x, l_out ); + out.y = FT_DivFix( out.y, l_out ); + } + + d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); + + /* shift only if turn is less than ~160 degrees */ + if ( d > -0xF000L ) + { + d = d + 0x10000L; + + /* shift components are aligned along lateral bisector */ + /* and directed according to the outline orientation. */ + shift.x = in.y + out.y; + shift.y = in.x + out.x; + + if ( orientation == FT_ORIENTATION_TRUETYPE ) + shift.x = -shift.x; + else + shift.y = -shift.y; + + /* restrict shift magnitude to better handle collapsing segments */ + q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x ); + if ( orientation == FT_ORIENTATION_TRUETYPE ) + q = -q; + + l = FT_MIN( l_in, l_out ); + + /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ + if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) ) + shift.x = FT_MulDiv( shift.x, xstrength, d ); + else + shift.x = FT_MulDiv( shift.x, l, q ); + + + if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) ) + shift.y = FT_MulDiv( shift.y, ystrength, d ); + else + shift.y = FT_MulDiv( shift.y, l, q ); + } + else + shift.x = shift.y = 0; + + outline->points[n].x = v_cur.x + xstrength + shift.x; + outline->points[n].y = v_cur.y + ystrength + shift.y; + + in = out; + l_in = l_out; + v_cur = v_next; + } + + first = last + 1; + } + + return FT_Err_Ok; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ) + { + FT_BBox cbox; + FT_Int xshift, yshift; + FT_Vector* points; + FT_Vector v_prev, v_cur; + FT_Int c, n, first; + FT_Pos area = 0; + + + 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. */ + + FT_Outline_Get_CBox( outline, &cbox ); + + xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14; + xshift = FT_MAX( xshift, 0 ); + + yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14; + yshift = FT_MAX( yshift, 0 ); + + points = outline->points; + + first = 0; + for ( c = 0; c < outline->n_contours; c++ ) + { + FT_Int last = outline->contours[c]; + + + v_prev = points[last]; + + for ( n = first; n <= last; n++ ) + { + v_cur = points[n]; + area += ( ( v_cur.y - v_prev.y ) >> yshift ) * + ( ( v_cur.x + v_prev.x ) >> xshift ); + v_prev = v_cur; + } + + first = last + 1; + } + + if ( area > 0 ) + return FT_ORIENTATION_POSTSCRIPT; + else if ( area < 0 ) + return FT_ORIENTATION_TRUETYPE; + else + return FT_ORIENTATION_NONE; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftpatent.c b/drivers/freetype/src/base/ftpatent.c new file mode 100644 index 0000000000..82b42f0343 --- /dev/null +++ b/drivers/freetype/src/base/ftpatent.c @@ -0,0 +1,286 @@ +/***************************************************************************/ +/* */ +/* ftpatent.c */ +/* */ +/* FreeType API for checking patented TrueType bytecode instructions */ +/* (body). */ +/* */ +/* Copyright 2007, 2008, 2010 by David Turner. */ +/* */ +/* 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_FREETYPE_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TRUETYPE_GLYF_H + + + static FT_Bool + _tt_check_patents_in_range( FT_Stream stream, + FT_ULong size ) + { + FT_Bool result = FALSE; + FT_Error error; + FT_Bytes p, end; + + + if ( FT_FRAME_ENTER( size ) ) + return 0; + + p = stream->cursor; + end = p + size; + + while ( p < end ) + { + switch (p[0]) + { + case 0x06: /* SPvTL // */ + case 0x07: /* SPvTL + */ + case 0x08: /* SFvTL // */ + case 0x09: /* SFvTL + */ + case 0x0A: /* SPvFS */ + case 0x0B: /* SFvFS */ + result = TRUE; + goto Exit; + + case 0x40: + if ( p + 1 >= end ) + goto Exit; + + p += p[1] + 2; + break; + + case 0x41: + if ( p + 1 >= end ) + goto Exit; + + p += p[1] * 2 + 2; + break; + + case 0x71: /* DELTAP2 */ + case 0x72: /* DELTAP3 */ + case 0x73: /* DELTAC0 */ + case 0x74: /* DELTAC1 */ + case 0x75: /* DELTAC2 */ + result = TRUE; + goto Exit; + + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + p += ( p[0] - 0xB0 ) + 2; + break; + + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + p += ( p[0] - 0xB8 ) * 2 + 3; + break; + + default: + p += 1; + break; + } + } + + Exit: + FT_UNUSED( error ); + FT_FRAME_EXIT(); + return result; + } + + + static FT_Bool + _tt_check_patents_in_table( FT_Face face, + FT_ULong tag ) + { + FT_Stream stream = face->stream; + FT_Error error = FT_Err_Ok; + FT_Service_SFNT_Table service; + FT_Bool result = FALSE; + + + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + + if ( service ) + { + FT_UInt i = 0; + FT_ULong tag_i = 0, offset_i = 0, length_i = 0; + + + for ( i = 0; !error && tag_i != tag ; i++ ) + error = service->table_info( face, i, + &tag_i, &offset_i, &length_i ); + + if ( error || + FT_STREAM_SEEK( offset_i ) ) + goto Exit; + + result = _tt_check_patents_in_range( stream, length_i ); + } + + Exit: + return result; + } + + + static FT_Bool + _tt_face_check_patents( FT_Face face ) + { + FT_Stream stream = face->stream; + FT_UInt gindex; + FT_Error error; + FT_Bool result; + + FT_Service_TTGlyf service; + + + result = _tt_check_patents_in_table( face, TTAG_fpgm ); + if ( result ) + goto Exit; + + result = _tt_check_patents_in_table( face, TTAG_prep ); + if ( result ) + goto Exit; + + FT_FACE_FIND_SERVICE( face, service, TT_GLYF ); + if ( service == NULL ) + goto Exit; + + for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ ) + { + FT_ULong offset, num_ins, size; + FT_Int num_contours; + + + offset = service->get_location( face, gindex, &size ); + if ( size == 0 ) + continue; + + if ( FT_STREAM_SEEK( offset ) || + FT_READ_SHORT( num_contours ) ) + continue; + + if ( num_contours >= 0 ) /* simple glyph */ + { + if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) ) + continue; + } + else /* compound glyph */ + { + FT_Bool has_instr = 0; + + + if ( FT_STREAM_SKIP( 8 ) ) + continue; + + /* now read each component */ + for (;;) + { + FT_UInt flags, toskip; + + + if( FT_READ_USHORT( flags ) ) + break; + + toskip = 2 + 1 + 1; + + if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */ + toskip += 2; + + if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */ + toskip += 2; + else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */ + toskip += 4; + else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */ + toskip += 8; + + if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */ + has_instr = 1; + + if ( FT_STREAM_SKIP( toskip ) ) + goto NextGlyph; + + if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */ + break; + } + + if ( !has_instr ) + goto NextGlyph; + } + + if ( FT_READ_USHORT( num_ins ) ) + continue; + + result = _tt_check_patents_in_range( stream, num_ins ); + if ( result ) + goto Exit; + + NextGlyph: + ; + } + + Exit: + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Face_CheckTrueTypePatents( FT_Face face ) + { + FT_Bool result = FALSE; + + + if ( face && FT_IS_SFNT( face ) ) + result = _tt_face_check_patents( face ); + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Face_SetUnpatentedHinting( FT_Face face, + FT_Bool value ) + { + FT_Bool result = FALSE; + + +#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ + !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) + if ( face && FT_IS_SFNT( face ) ) + { + result = !face->internal->ignore_unpatented_hinter; + face->internal->ignore_unpatented_hinter = !value; + } +#else + FT_UNUSED( face ); + FT_UNUSED( value ); +#endif + + return result; + } + +/* END */ diff --git a/drivers/freetype/src/base/ftpfr.c b/drivers/freetype/src/base/ftpfr.c new file mode 100644 index 0000000000..0ba955f01f --- /dev/null +++ b/drivers/freetype/src/base/ftpfr.c @@ -0,0 +1,146 @@ +/***************************************************************************/ +/* */ +/* ftpfr.c */ +/* */ +/* FreeType API for accessing PFR-specific data (body). */ +/* */ +/* Copyright 2002-2004, 2008, 2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_PFR_H + + + /* check the format */ + static FT_Service_PfrMetrics + ft_pfr_check( FT_Face face ) + { + FT_Service_PfrMetrics service = NULL; + + + if ( face ) + FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS ); + + return service; + } + + + /* documentation is in ftpfr.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) + { + FT_Error error = FT_Err_Ok; + FT_Service_PfrMetrics service; + + + if ( !face ) + return FT_THROW( Invalid_Argument ); + + service = ft_pfr_check( face ); + if ( service ) + { + error = service->get_metrics( face, + aoutline_resolution, + ametrics_resolution, + ametrics_x_scale, + ametrics_y_scale ); + } + else + { + FT_Fixed x_scale, y_scale; + + + /* this is not a PFR font */ + if ( aoutline_resolution ) + *aoutline_resolution = face->units_per_EM; + + if ( ametrics_resolution ) + *ametrics_resolution = face->units_per_EM; + + x_scale = y_scale = 0x10000L; + if ( face->size ) + { + x_scale = face->size->metrics.x_scale; + y_scale = face->size->metrics.y_scale; + } + + if ( ametrics_x_scale ) + *ametrics_x_scale = x_scale; + + if ( ametrics_y_scale ) + *ametrics_y_scale = y_scale; + + error = FT_THROW( Unknown_File_Format ); + } + + return error; + } + + + /* documentation is in ftpfr.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ) + { + FT_Error error; + FT_Service_PfrMetrics service; + + + if ( !face ) + return FT_THROW( Invalid_Argument ); + + service = ft_pfr_check( face ); + if ( service ) + error = service->get_kerning( face, left, right, avector ); + else + error = FT_Get_Kerning( face, left, right, + FT_KERNING_UNSCALED, avector ); + + return error; + } + + + /* documentation is in ftpfr.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) + { + FT_Error error; + FT_Service_PfrMetrics service; + + + service = ft_pfr_check( face ); + if ( service ) + { + error = service->get_advance( face, gindex, aadvance ); + } + else + /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */ + error = FT_THROW( Invalid_Argument ); + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftpic.c b/drivers/freetype/src/base/ftpic.c new file mode 100644 index 0000000000..1c87101696 --- /dev/null +++ b/drivers/freetype/src/base/ftpic.c @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ftpic.c */ +/* */ +/* The FreeType position independent code services (body). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* documentation is in ftpic.h */ + + FT_BASE_DEF( FT_Error ) + ft_pic_container_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + + + FT_MEM_SET( pic_container, 0, sizeof ( *pic_container ) ); + + error = ft_base_pic_init( library ); + if ( error ) + return error; + + return FT_Err_Ok; + } + + + /* Destroy the contents of the container. */ + FT_BASE_DEF( void ) + ft_pic_container_destroy( FT_Library library ) + { + ft_base_pic_free( library ); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftrfork.c b/drivers/freetype/src/base/ftrfork.c new file mode 100644 index 0000000000..804911721d --- /dev/null +++ b/drivers/freetype/src/base/ftrfork.c @@ -0,0 +1,849 @@ +/***************************************************************************/ +/* */ +/* ftrfork.c */ +/* */ +/* Embedded resource forks accessor (body). */ +/* */ +/* Copyright 2004-2010, 2013 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ +/* derived from ftobjs.c. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_RFORK_H +#include "basepic.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** Resource fork directory access ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + FT_BASE_DEF( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ) + { + FT_Error error; + unsigned char head[16], head2[16]; + FT_Long map_pos, rdata_len; + int allzeros, allmatch, i; + FT_Long type_list; + + FT_UNUSED( library ); + + + error = FT_Stream_Seek( stream, rfork_offset ); + if ( error ) + return error; + + error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); + if ( error ) + return error; + + *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | + ( head[1] << 16 ) | + ( head[2] << 8 ) | + head[3] ); + map_pos = rfork_offset + ( ( head[4] << 24 ) | + ( head[5] << 16 ) | + ( head[6] << 8 ) | + head[7] ); + rdata_len = ( head[ 8] << 24 ) | + ( head[ 9] << 16 ) | + ( head[10] << 8 ) | + head[11]; + + /* map_len = head[12] .. head[15] */ + + if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) + return FT_THROW( Unknown_File_Format ); + + error = FT_Stream_Seek( stream, map_pos ); + if ( error ) + return error; + + head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ + + error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); + if ( error ) + return error; + + allzeros = 1; + allmatch = 1; + for ( i = 0; i < 16; ++i ) + { + if ( head2[i] != 0 ) + allzeros = 0; + if ( head2[i] != head[i] ) + allmatch = 0; + } + if ( !allzeros && !allmatch ) + return FT_THROW( Unknown_File_Format ); + + /* If we have reached this point then it is probably a mac resource */ + /* file. Now, does it contain any interesting resources? */ + /* Skip handle to next resource map, the file resource number, and */ + /* attributes. */ + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ + + 2 /* skip file resource number */ + + 2 ); /* skip attributes */ + + if ( FT_READ_USHORT( type_list ) ) + return error; + if ( type_list == -1 ) + return FT_THROW( Unknown_File_Format ); + + error = FT_Stream_Seek( stream, map_pos + type_list ); + if ( error ) + return error; + + *map_offset = map_pos + type_list; + return FT_Err_Ok; + } + + + static int + ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, + FT_RFork_Ref* b ) + { + if ( a->res_id < b->res_id ) + return -1; + else if ( a->res_id > b->res_id ) + return 1; + else + return 0; + } + + + FT_BASE_DEF( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Long **offsets, + FT_Long *count ) + { + FT_Error error; + int i, j, cnt, subcnt; + FT_Long tag_internal, rpos; + FT_Memory memory = library->memory; + FT_Long temp; + FT_Long *offsets_internal = NULL; + FT_RFork_Ref *ref = NULL; + + + error = FT_Stream_Seek( stream, map_offset ); + if ( error ) + return error; + + if ( FT_READ_USHORT( cnt ) ) + return error; + cnt++; + + for ( i = 0; i < cnt; ++i ) + { + if ( FT_READ_LONG( tag_internal ) || + FT_READ_USHORT( subcnt ) || + FT_READ_USHORT( rpos ) ) + return error; + + FT_TRACE2(( "Resource tags: %c%c%c%c\n", + (char)( 0xff & ( tag_internal >> 24 ) ), + (char)( 0xff & ( tag_internal >> 16 ) ), + (char)( 0xff & ( tag_internal >> 8 ) ), + (char)( 0xff & ( tag_internal >> 0 ) ) )); + + if ( tag_internal == tag ) + { + *count = subcnt + 1; + rpos += map_offset; + + error = FT_Stream_Seek( stream, rpos ); + if ( error ) + return error; + + if ( FT_NEW_ARRAY( ref, *count ) ) + return error; + + for ( j = 0; j < *count; ++j ) + { + if ( FT_READ_USHORT( ref[j].res_id ) ) + goto Exit; + if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + goto Exit; + if ( FT_READ_LONG( temp ) ) + goto Exit; + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + goto Exit; + + ref[j].offset = temp & 0xFFFFFFL; + } + + ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, const void*) ) + ft_raccess_sort_ref_by_id ); + + if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + goto Exit; + + /* XXX: duplicated reference ID, + * gap between reference IDs are acceptable? + * further investigation on Apple implementation is needed. + */ + for ( j = 0; j < *count; ++j ) + offsets_internal[j] = rdata_pos + ref[j].offset; + + *offsets = offsets_internal; + error = FT_Err_Ok; + + Exit: + FT_FREE( ref ); + return error; + } + } + + return FT_THROW( Cannot_Open_Resource ); + } + + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** Guessing functions ****/ + /**** ****/ + /**** When you add a new guessing function, ****/ + /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + raccess_guess_apple_double( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_apple_single( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_ufs_export( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_hfsplus( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_vfat( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_cap( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_double( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_netatalk( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + + CONST_FT_RFORK_RULE_ARRAY_BEGIN(ft_raccess_guess_table, + ft_raccess_guess_rec) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_double, apple_double) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_single, apple_single) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_ufs_export, darwin_ufs_export) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_newvfs, darwin_newvfs) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_hfsplus, darwin_hfsplus) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(vfat, vfat) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_cap, linux_cap) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_double, linux_double) + CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_netatalk, linux_netatalk) + CONST_FT_RFORK_RULE_ARRAY_END + + + /*************************************************************************/ + /**** ****/ + /**** Helper functions ****/ + /**** ****/ + /*************************************************************************/ + + static FT_Error + raccess_guess_apple_generic( FT_Library library, + FT_Stream stream, + char *base_file_name, + FT_Int32 magic, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_double_from_file_name( FT_Library library, + char * file_name, + FT_Long *result_offset ); + + static char * + raccess_make_file_name( FT_Memory memory, + const char *original_name, + const char *insertion ); + + FT_BASE_DEF( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char **new_names, + FT_Long *offsets, + FT_Error *errors ) + { + FT_Int i; + + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + new_names[i] = NULL; + if ( NULL != stream ) + errors[i] = FT_Stream_Seek( stream, 0 ); + else + errors[i] = FT_Err_Ok; + + if ( errors[i] ) + continue ; + + errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, + stream, base_name, + &(new_names[i]), + &(offsets[i]) ); + } + + return; + } + + +#ifndef FT_MACINTOSH + static FT_RFork_Rule + raccess_get_rule_type_from_rule_index( FT_Library library, + FT_UInt rule_index ) + { + FT_UNUSED( library ); + + if ( rule_index >= FT_RACCESS_N_RULES ) + return FT_RFork_Rule_invalid; + + return FT_RACCESS_GUESS_TABLE_GET[rule_index].type; + } + + + /* + * For this function, refer ftbase.h. + */ + FT_LOCAL_DEF( FT_Bool ) + ft_raccess_rule_by_darwin_vfs( FT_Library library, + FT_UInt rule_index ) + { + switch( raccess_get_rule_type_from_rule_index( library, rule_index ) ) + { + case FT_RFork_Rule_darwin_newvfs: + case FT_RFork_Rule_darwin_hfsplus: + return TRUE; + + default: + return FALSE; + } + } +#endif + + + static FT_Error + raccess_guess_apple_double( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + FT_Int32 magic = ( 0x00 << 24 ) | + ( 0x05 << 16 ) | + ( 0x16 << 8 ) | + 0x07; + + + *result_file_name = NULL; + if ( NULL == stream ) + return FT_THROW( Cannot_Open_Stream ); + + return raccess_guess_apple_generic( library, stream, base_file_name, + magic, result_offset ); + } + + + static FT_Error + raccess_guess_apple_single( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + FT_Int32 magic = ( 0x00 << 24 ) | + ( 0x05 << 16 ) | + ( 0x16 << 8 ) | + 0x00; + + + *result_file_name = NULL; + if ( NULL == stream ) + return FT_THROW( Cannot_Open_Stream ); + + return raccess_guess_apple_generic( library, stream, base_file_name, + magic, result_offset ); + } + + + static FT_Error + raccess_guess_darwin_ufs_export( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + newpath = raccess_make_file_name( memory, base_file_name, "._" ); + if ( !newpath ) + return FT_THROW( Out_Of_Memory ); + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_darwin_hfsplus( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with hfs+ drivers (or Macs). + */ + FT_Error error; + char* newpath = NULL; + FT_Memory memory; + FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name ); + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( base_file_len + 6 > FT_INT_MAX ) + return FT_THROW( Array_Too_Large ); + + if ( FT_ALLOC( newpath, base_file_len + 6 ) ) + return error; + + FT_MEM_COPY( newpath, base_file_name, base_file_len ); + FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with Mac OS X (> 10.1). + */ + FT_Error error; + char* newpath = NULL; + FT_Memory memory; + FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name ); + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( base_file_len + 18 > FT_INT_MAX ) + return FT_THROW( Array_Too_Large ); + + if ( FT_ALLOC( newpath, base_file_len + 18 ) ) + return error; + + FT_MEM_COPY( newpath, base_file_name, base_file_len ); + FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_vfat( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, + "resource.frk/" ); + if ( !newpath ) + return FT_THROW( Out_Of_Memory ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_linux_cap( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, ".resource/" ); + if ( !newpath ) + return FT_THROW( Out_Of_Memory ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_linux_double( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, "%" ); + if ( !newpath ) + return FT_THROW( Out_Of_Memory ); + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_linux_netatalk( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, + ".AppleDouble/" ); + if ( !newpath ) + return FT_THROW( Out_Of_Memory ); + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_apple_generic( FT_Library library, + FT_Stream stream, + char *base_file_name, + FT_Int32 magic, + FT_Long *result_offset ) + { + FT_Int32 magic_from_stream; + FT_Error error; + FT_Int32 version_number = 0; + FT_UShort n_of_entries; + + int i; + FT_UInt32 entry_id, entry_offset, entry_length = 0; + + const FT_UInt32 resource_fork_entry_id = 0x2; + + FT_UNUSED( library ); + FT_UNUSED( base_file_name ); + FT_UNUSED( version_number ); + FT_UNUSED( entry_length ); + + + if ( FT_READ_LONG( magic_from_stream ) ) + return error; + if ( magic_from_stream != magic ) + return FT_THROW( Unknown_File_Format ); + + if ( FT_READ_LONG( version_number ) ) + return error; + + /* filler */ + error = FT_Stream_Skip( stream, 16 ); + if ( error ) + return error; + + if ( FT_READ_USHORT( n_of_entries ) ) + return error; + if ( n_of_entries == 0 ) + return FT_THROW( Unknown_File_Format ); + + for ( i = 0; i < n_of_entries; i++ ) + { + if ( FT_READ_LONG( entry_id ) ) + return error; + if ( entry_id == resource_fork_entry_id ) + { + if ( FT_READ_LONG( entry_offset ) || + FT_READ_LONG( entry_length ) ) + continue; + *result_offset = entry_offset; + + return FT_Err_Ok; + } + else + { + error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ + if ( error ) + return error; + } + } + + return FT_THROW( Unknown_File_Format ); + } + + + static FT_Error + raccess_guess_linux_double_from_file_name( FT_Library library, + char *file_name, + FT_Long *result_offset ) + { + FT_Open_Args args2; + FT_Stream stream2; + char * nouse = NULL; + FT_Error error; + + + args2.flags = FT_OPEN_PATHNAME; + args2.pathname = file_name; + error = FT_Stream_New( library, &args2, &stream2 ); + if ( error ) + return error; + + error = raccess_guess_apple_double( library, stream2, file_name, + &nouse, result_offset ); + + FT_Stream_Free( stream2, 0 ); + + return error; + } + + + static char* + raccess_make_file_name( FT_Memory memory, + const char *original_name, + const char *insertion ) + { + char* new_name = NULL; + const char* tmp; + const char* slash; + size_t new_length; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( error ); + + + new_length = ft_strlen( original_name ) + ft_strlen( insertion ); + if ( FT_ALLOC( new_name, new_length + 1 ) ) + return NULL; + + tmp = ft_strrchr( original_name, '/' ); + if ( tmp ) + { + ft_strncpy( new_name, original_name, tmp - original_name + 1 ); + new_name[tmp - original_name + 1] = '\0'; + slash = tmp + 1; + } + else + { + slash = original_name; + new_name[0] = '\0'; + } + + ft_strcat( new_name, insertion ); + ft_strcat( new_name, slash ); + + return new_name; + } + + +#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + + /*************************************************************************/ + /* Dummy function; just sets errors */ + /*************************************************************************/ + + FT_BASE_DEF( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char *base_name, + char **new_names, + FT_Long *offsets, + FT_Error *errors ) + { + FT_Int i; + + FT_UNUSED( library ); + FT_UNUSED( stream ); + FT_UNUSED( base_name ); + + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + new_names[i] = NULL; + offsets[i] = 0; + errors[i] = FT_ERR( Unimplemented_Feature ); + } + } + + +#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftsnames.c b/drivers/freetype/src/base/ftsnames.c new file mode 100644 index 0000000000..260e91c148 --- /dev/null +++ b/drivers/freetype/src/base/ftsnames.c @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* ftsnames.c */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (body). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002, 2009 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_SFNT_NAMES_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_STREAM_H + + +#ifdef TT_CONFIG_OPTION_SFNT_NAMES + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ) + { + return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0; + } + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + + + if ( aname && face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( idx < (FT_UInt)ttface->num_names ) + { + TT_NameEntryRec* entry = ttface->name_table.names + idx; + + + /* load name on demand */ + if ( entry->stringLength > 0 && entry->string == NULL ) + { + FT_Memory memory = face->memory; + FT_Stream stream = face->stream; + + + if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + FT_STREAM_SEEK( entry->stringOffset ) || + FT_STREAM_READ( entry->string, entry->stringLength ) ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + } + + aname->platform_id = entry->platformID; + aname->encoding_id = entry->encodingID; + aname->language_id = entry->languageID; + aname->name_id = entry->nameID; + aname->string = (FT_Byte*)entry->string; + aname->string_len = entry->stringLength; + + error = FT_Err_Ok; + } + } + + return error; + } + + +#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ + + +/* END */ diff --git a/drivers/freetype/src/base/ftstream.c b/drivers/freetype/src/base/ftstream.c new file mode 100644 index 0000000000..d965333daa --- /dev/null +++ b/drivers/freetype/src/base/ftstream.c @@ -0,0 +1,865 @@ +/***************************************************************************/ +/* */ +/* ftstream.c */ +/* */ +/* I/O stream support (body). */ +/* */ +/* Copyright 2000-2002, 2004-2006, 2008-2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_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_stream + + + FT_BASE_DEF( void ) + FT_Stream_OpenMemory( FT_Stream stream, + const FT_Byte* base, + FT_ULong size ) + { + stream->base = (FT_Byte*) base; + stream->size = size; + stream->pos = 0; + stream->cursor = 0; + stream->read = 0; + stream->close = 0; + } + + + FT_BASE_DEF( void ) + FT_Stream_Close( FT_Stream stream ) + { + if ( stream && stream->close ) + stream->close( stream ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Seek( FT_Stream stream, + FT_ULong pos ) + { + FT_Error error = FT_Err_Ok; + + + if ( stream->read ) + { + if ( stream->read( stream, pos, 0, 0 ) ) + { + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + error = FT_THROW( Invalid_Stream_Operation ); + } + } + /* note that seeking to the first position after the file is valid */ + else if ( pos > stream->size ) + { + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + error = FT_THROW( Invalid_Stream_Operation ); + } + + if ( !error ) + stream->pos = pos; + + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Skip( FT_Stream stream, + FT_Long distance ) + { + if ( distance < 0 ) + return FT_THROW( Invalid_Stream_Operation ); + + return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_Pos( FT_Stream stream ) + { + return stream->pos; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Read( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_ReadAt( stream, stream->pos, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ReadAt( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_Error error = FT_Err_Ok; + FT_ULong read_bytes; + + + if ( pos >= stream->size ) + { + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + return FT_THROW( Invalid_Stream_Operation ); + } + + if ( stream->read ) + read_bytes = stream->read( stream, pos, buffer, count ); + else + { + read_bytes = stream->size - pos; + if ( read_bytes > count ) + read_bytes = count; + + FT_MEM_COPY( buffer, stream->base + pos, read_bytes ); + } + + stream->pos = pos + read_bytes; + + if ( read_bytes < count ) + { + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid read; expected %lu bytes, got %lu\n", + count, read_bytes )); + + error = FT_THROW( Invalid_Stream_Operation ); + } + + return error; + } + + + FT_BASE_DEF( FT_ULong ) + FT_Stream_TryRead( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + FT_ULong read_bytes = 0; + + + if ( stream->pos >= stream->size ) + goto Exit; + + if ( stream->read ) + read_bytes = stream->read( stream, stream->pos, buffer, count ); + else + { + read_bytes = stream->size - stream->pos; + if ( read_bytes > count ) + read_bytes = count; + + FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes ); + } + + stream->pos += read_bytes; + + Exit: + return read_bytes; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ExtractFrame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ) + { + FT_Error error; + + + error = FT_Stream_EnterFrame( stream, count ); + if ( !error ) + { + *pbytes = (FT_Byte*)stream->cursor; + + /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ + stream->cursor = 0; + stream->limit = 0; + } + + return error; + } + + + FT_BASE_DEF( void ) + FT_Stream_ReleaseFrame( FT_Stream stream, + FT_Byte** pbytes ) + { + if ( stream && stream->read ) + { + FT_Memory memory = stream->memory; + +#ifdef FT_DEBUG_MEMORY + ft_mem_free( memory, *pbytes ); + *pbytes = NULL; +#else + FT_FREE( *pbytes ); +#endif + } + *pbytes = 0; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_EnterFrame( FT_Stream stream, + FT_ULong count ) + { + FT_Error error = FT_Err_Ok; + FT_ULong read_bytes; + + + /* check for nested frame access */ + FT_ASSERT( stream && stream->cursor == 0 ); + + if ( stream->read ) + { + /* allocate the frame in memory */ + FT_Memory memory = stream->memory; + + + /* simple sanity check */ + if ( count > stream->size ) + { + FT_ERROR(( "FT_Stream_EnterFrame:" + " frame size (%lu) larger than stream size (%lu)\n", + count, stream->size )); + + error = FT_THROW( Invalid_Stream_Operation ); + goto Exit; + } + +#ifdef FT_DEBUG_MEMORY + /* assume _ft_debug_file and _ft_debug_lineno are already set */ + stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error ); + if ( error ) + goto Exit; +#else + if ( FT_QALLOC( stream->base, count ) ) + goto Exit; +#endif + /* read it */ + read_bytes = stream->read( stream, stream->pos, + stream->base, count ); + if ( read_bytes < count ) + { + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid read; expected %lu bytes, got %lu\n", + count, read_bytes )); + + FT_FREE( stream->base ); + error = FT_THROW( Invalid_Stream_Operation ); + } + stream->cursor = stream->base; + stream->limit = stream->cursor + count; + stream->pos += read_bytes; + } + else + { + /* check current and new position */ + if ( stream->pos >= stream->size || + stream->size - stream->pos < count ) + { + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", + stream->pos, count, stream->size )); + + error = FT_THROW( Invalid_Stream_Operation ); + goto Exit; + } + + /* set cursor */ + stream->cursor = stream->base + stream->pos; + stream->limit = stream->cursor + count; + stream->pos += count; + } + + Exit: + return error; + } + + + FT_BASE_DEF( void ) + FT_Stream_ExitFrame( FT_Stream stream ) + { + /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */ + /* that it is possible to access a frame of length 0 in */ + /* some weird fonts (usually, when accessing an array of */ + /* 0 records, like in some strange kern tables). */ + /* */ + /* In this case, the loader code handles the 0-length table */ + /* gracefully; however, stream.cursor is really set to 0 by the */ + /* FT_Stream_EnterFrame() call, and this is not an error. */ + /* */ + FT_ASSERT( stream ); + + if ( stream->read ) + { + FT_Memory memory = stream->memory; + +#ifdef FT_DEBUG_MEMORY + ft_mem_free( memory, stream->base ); + stream->base = NULL; +#else + FT_FREE( stream->base ); +#endif + } + stream->cursor = 0; + stream->limit = 0; + } + + + FT_BASE_DEF( FT_Char ) + FT_Stream_GetChar( FT_Stream stream ) + { + FT_Char result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + if ( stream->cursor < stream->limit ) + result = *stream->cursor++; + + return result; + } + + + FT_BASE_DEF( FT_UShort ) + FT_Stream_GetUShort( FT_Stream stream ) + { + FT_Byte* p; + FT_Short result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 1 < stream->limit ) + result = FT_NEXT_USHORT( p ); + stream->cursor = p; + + return result; + } + + + FT_BASE_DEF( FT_UShort ) + FT_Stream_GetUShortLE( FT_Stream stream ) + { + FT_Byte* p; + FT_Short result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 1 < stream->limit ) + result = FT_NEXT_USHORT_LE( p ); + stream->cursor = p; + + return result; + } + + + FT_BASE_DEF( FT_ULong ) + FT_Stream_GetUOffset( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 2 < stream->limit ) + result = FT_NEXT_UOFF3( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_ULong ) + FT_Stream_GetULong( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 3 < stream->limit ) + result = FT_NEXT_ULONG( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_ULong ) + FT_Stream_GetULongLE( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 3 < stream->limit ) + result = FT_NEXT_ULONG_LE( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_Char ) + FT_Stream_ReadChar( FT_Stream stream, + FT_Error* error ) + { + FT_Byte result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) + goto Fail; + } + else + { + if ( stream->pos < stream->size ) + result = stream->base[stream->pos]; + else + goto Fail; + } + stream->pos++; + + return result; + + Fail: + *error = FT_THROW( Invalid_Stream_Operation ); + FT_ERROR(( "FT_Stream_ReadChar:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_UShort ) + FT_Stream_ReadUShort( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_Short result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 1 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_USHORT( p ); + } + else + goto Fail; + + stream->pos += 2; + + return result; + + Fail: + *error = FT_THROW( Invalid_Stream_Operation ); + FT_ERROR(( "FT_Stream_ReadUShort:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_UShort ) + FT_Stream_ReadUShortLE( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_Short result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 1 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_USHORT_LE( p ); + } + else + goto Fail; + + stream->pos += 2; + + return result; + + Fail: + *error = FT_THROW( Invalid_Stream_Operation ); + FT_ERROR(( "FT_Stream_ReadUShortLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_ULong ) + FT_Stream_ReadUOffset( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[3]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 2 < stream->size ) + { + if ( stream->read ) + { + if (stream->read( stream, stream->pos, reads, 3L ) != 3L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_UOFF3( p ); + } + else + goto Fail; + + stream->pos += 3; + + return result; + + Fail: + *error = FT_THROW( Invalid_Stream_Operation ); + FT_ERROR(( "FT_Stream_ReadUOffset:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_ULong ) + FT_Stream_ReadULong( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[4]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 3 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_ULONG( p ); + } + else + goto Fail; + + stream->pos += 4; + + return result; + + Fail: + *error = FT_THROW( Invalid_Stream_Operation ); + FT_ERROR(( "FT_Stream_ReadULong:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_ULong ) + FT_Stream_ReadULongLE( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[4]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 3 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_ULONG_LE( p ); + } + else + goto Fail; + + stream->pos += 4; + + return result; + + Fail: + *error = FT_THROW( Invalid_Stream_Operation ); + FT_ERROR(( "FT_Stream_ReadULongLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ReadFields( FT_Stream stream, + const FT_Frame_Field* fields, + void* structure ) + { + FT_Error error; + FT_Bool frame_accessed = 0; + FT_Byte* cursor; + + + if ( !fields || !stream ) + return FT_THROW( Invalid_Argument ); + + cursor = stream->cursor; + + error = FT_Err_Ok; + do + { + FT_ULong value; + FT_Int sign_shift; + FT_Byte* p; + + + switch ( fields->value ) + { + case ft_frame_start: /* access a new frame */ + error = FT_Stream_EnterFrame( stream, fields->offset ); + if ( error ) + goto Exit; + + frame_accessed = 1; + cursor = stream->cursor; + fields++; + continue; /* loop! */ + + case ft_frame_bytes: /* read a byte sequence */ + case ft_frame_skip: /* skip some bytes */ + { + FT_UInt len = fields->size; + + + if ( cursor + len > stream->limit ) + { + error = FT_THROW( Invalid_Stream_Operation ); + goto Exit; + } + + if ( fields->value == ft_frame_bytes ) + { + p = (FT_Byte*)structure + fields->offset; + FT_MEM_COPY( p, cursor, len ); + } + cursor += len; + fields++; + continue; + } + + case ft_frame_byte: + case ft_frame_schar: /* read a single byte */ + value = FT_NEXT_BYTE( cursor ); + sign_shift = 24; + break; + + case ft_frame_short_be: + case ft_frame_ushort_be: /* read a 2-byte big-endian short */ + value = FT_NEXT_USHORT( cursor) ; + sign_shift = 16; + break; + + case ft_frame_short_le: + case ft_frame_ushort_le: /* read a 2-byte little-endian short */ + value = FT_NEXT_USHORT_LE( cursor ); + sign_shift = 16; + break; + + case ft_frame_long_be: + case ft_frame_ulong_be: /* read a 4-byte big-endian long */ + value = FT_NEXT_ULONG( cursor ); + sign_shift = 0; + break; + + case ft_frame_long_le: + case ft_frame_ulong_le: /* read a 4-byte little-endian long */ + value = FT_NEXT_ULONG_LE( cursor ); + sign_shift = 0; + break; + + case ft_frame_off3_be: + case ft_frame_uoff3_be: /* read a 3-byte big-endian long */ + value = FT_NEXT_UOFF3( cursor ); + sign_shift = 8; + break; + + case ft_frame_off3_le: + case ft_frame_uoff3_le: /* read a 3-byte little-endian long */ + value = FT_NEXT_UOFF3_LE( cursor ); + sign_shift = 8; + break; + + default: + /* otherwise, exit the loop */ + stream->cursor = cursor; + goto Exit; + } + + /* now, compute the signed value is necessary */ + if ( fields->value & FT_FRAME_OP_SIGNED ) + value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); + + /* finally, store the value in the object */ + + p = (FT_Byte*)structure + fields->offset; + switch ( fields->size ) + { + case ( 8 / FT_CHAR_BIT ): + *(FT_Byte*)p = (FT_Byte)value; + break; + + case ( 16 / FT_CHAR_BIT ): + *(FT_UShort*)p = (FT_UShort)value; + break; + + case ( 32 / FT_CHAR_BIT ): + *(FT_UInt32*)p = (FT_UInt32)value; + break; + + default: /* for 64-bit systems */ + *(FT_ULong*)p = (FT_ULong)value; + } + + /* go to next field */ + fields++; + } + while ( 1 ); + + Exit: + /* close the frame if it was opened by this read */ + if ( frame_accessed ) + FT_Stream_ExitFrame( stream ); + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftstroke.c b/drivers/freetype/src/base/ftstroke.c new file mode 100644 index 0000000000..ee61ceca0e --- /dev/null +++ b/drivers/freetype/src/base/ftstroke.c @@ -0,0 +1,2418 @@ +/***************************************************************************/ +/* */ +/* ftstroke.c */ +/* */ +/* FreeType path stroker (body). */ +/* */ +/* Copyright 2002-2006, 2008-2011, 2013 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_STROKER_H +#include FT_TRIGONOMETRY_H +#include FT_OUTLINE_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ) + { + FT_Orientation o = FT_Outline_Get_Orientation( outline ); + + + return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT + : FT_STROKER_BORDER_LEFT; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ) + { + FT_Orientation o = FT_Outline_Get_Orientation( outline ); + + + return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT + : FT_STROKER_BORDER_RIGHT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BEZIER COMPUTATIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define FT_SMALL_CONIC_THRESHOLD ( FT_ANGLE_PI / 6 ) +#define FT_SMALL_CUBIC_THRESHOLD ( FT_ANGLE_PI / 8 ) + +#define FT_EPSILON 2 + +#define FT_IS_SMALL( x ) ( (x) > -FT_EPSILON && (x) < FT_EPSILON ) + + + static FT_Pos + ft_pos_abs( FT_Pos x ) + { + return x >= 0 ? x : -x; + } + + + static void + ft_conic_split( FT_Vector* base ) + { + FT_Pos a, b; + + + base[4].x = base[2].x; + b = base[1].x; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; + + base[4].y = base[2].y; + b = base[1].y; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; + } + + + static FT_Bool + ft_conic_is_small_enough( FT_Vector* base, + FT_Angle *angle_in, + FT_Angle *angle_out ) + { + FT_Vector d1, d2; + FT_Angle theta; + FT_Int close1, close2; + + + d1.x = base[1].x - base[2].x; + d1.y = base[1].y - base[2].y; + d2.x = base[0].x - base[1].x; + d2.y = base[0].y - base[1].y; + + close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); + close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); + + if ( close1 ) + { + if ( close2 ) + { + /* basically a point; */ + /* do nothing to retain original direction */ + } + else + { + *angle_in = + *angle_out = FT_Atan2( d2.x, d2.y ); + } + } + else /* !close1 */ + { + if ( close2 ) + { + *angle_in = + *angle_out = FT_Atan2( d1.x, d1.y ); + } + else + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_out = FT_Atan2( d2.x, d2.y ); + } + } + + theta = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_out ) ); + + return FT_BOOL( theta < FT_SMALL_CONIC_THRESHOLD ); + } + + + static void + ft_cubic_split( FT_Vector* base ) + { + FT_Pos a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c ) / 2; + base[5].x = b = ( base[3].x + d ) / 2; + c = ( c + d ) / 2; + base[2].x = a = ( a + c ) / 2; + base[4].x = b = ( b + c ) / 2; + base[3].x = ( a + b ) / 2; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c ) / 2; + base[5].y = b = ( base[3].y + d ) / 2; + c = ( c + d ) / 2; + base[2].y = a = ( a + c ) / 2; + base[4].y = b = ( b + c ) / 2; + base[3].y = ( a + b ) / 2; + } + + + /* Return the average of `angle1' and `angle2'. */ + /* This gives correct result even if `angle1' and `angle2' */ + /* have opposite signs. */ + static FT_Angle + ft_angle_mean( FT_Angle angle1, + FT_Angle angle2 ) + { + return angle1 + FT_Angle_Diff( angle1, angle2 ) / 2; + } + + + static FT_Bool + ft_cubic_is_small_enough( FT_Vector* base, + FT_Angle *angle_in, + FT_Angle *angle_mid, + FT_Angle *angle_out ) + { + FT_Vector d1, d2, d3; + FT_Angle theta1, theta2; + FT_Int close1, close2, close3; + + + d1.x = base[2].x - base[3].x; + d1.y = base[2].y - base[3].y; + d2.x = base[1].x - base[2].x; + d2.y = base[1].y - base[2].y; + d3.x = base[0].x - base[1].x; + d3.y = base[0].y - base[1].y; + + close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); + close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); + close3 = FT_IS_SMALL( d3.x ) && FT_IS_SMALL( d3.y ); + + if ( close1 ) + { + if ( close2 ) + { + if ( close3 ) + { + /* basically a point; */ + /* do nothing to retain original direction */ + } + else /* !close3 */ + { + *angle_in = + *angle_mid = + *angle_out = FT_Atan2( d3.x, d3.y ); + } + } + else /* !close2 */ + { + if ( close3 ) + { + *angle_in = + *angle_mid = + *angle_out = FT_Atan2( d2.x, d2.y ); + } + else /* !close3 */ + { + *angle_in = + *angle_mid = FT_Atan2( d2.x, d2.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + } + } + } + else /* !close1 */ + { + if ( close2 ) + { + if ( close3 ) + { + *angle_in = + *angle_mid = + *angle_out = FT_Atan2( d1.x, d1.y ); + } + else /* !close3 */ + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + *angle_mid = ft_angle_mean( *angle_in, *angle_out ); + } + } + else /* !close2 */ + { + if ( close3 ) + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_mid = + *angle_out = FT_Atan2( d2.x, d2.y ); + } + else /* !close3 */ + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_mid = FT_Atan2( d2.x, d2.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + } + } + } + + theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_mid ) ); + theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) ); + + return FT_BOOL( theta1 < FT_SMALL_CUBIC_THRESHOLD && + theta2 < FT_SMALL_CUBIC_THRESHOLD ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** STROKE BORDERS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef enum FT_StrokeTags_ + { + FT_STROKE_TAG_ON = 1, /* on-curve point */ + FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ + FT_STROKE_TAG_BEGIN = 4, /* sub-path start */ + FT_STROKE_TAG_END = 8 /* sub-path end */ + + } FT_StrokeTags; + +#define FT_STROKE_TAG_BEGIN_END ( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ) + + typedef struct FT_StrokeBorderRec_ + { + FT_UInt num_points; + FT_UInt max_points; + FT_Vector* points; + FT_Byte* tags; + FT_Bool movable; /* TRUE for ends of lineto borders */ + FT_Int start; /* index of current sub-path start point */ + FT_Memory memory; + FT_Bool valid; + + } FT_StrokeBorderRec, *FT_StrokeBorder; + + + static FT_Error + ft_stroke_border_grow( FT_StrokeBorder border, + FT_UInt new_points ) + { + FT_UInt old_max = border->max_points; + FT_UInt new_max = border->num_points + new_points; + FT_Error error = FT_Err_Ok; + + + if ( new_max > old_max ) + { + FT_UInt cur_max = old_max; + FT_Memory memory = border->memory; + + + while ( cur_max < new_max ) + cur_max += ( cur_max >> 1 ) + 16; + + if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) || + FT_RENEW_ARRAY( border->tags, old_max, cur_max ) ) + goto Exit; + + border->max_points = cur_max; + } + + Exit: + return error; + } + + + static void + ft_stroke_border_close( FT_StrokeBorder border, + FT_Bool reverse ) + { + FT_UInt start = border->start; + FT_UInt count = border->num_points; + + + FT_ASSERT( border->start >= 0 ); + + /* don't record empty paths! */ + if ( count <= start + 1U ) + border->num_points = start; + else + { + /* copy the last point to the start of this sub-path, since */ + /* it contains the `adjusted' starting coordinates */ + border->num_points = --count; + border->points[start] = border->points[count]; + + if ( reverse ) + { + /* reverse the points */ + { + FT_Vector* vec1 = border->points + start + 1; + FT_Vector* vec2 = border->points + count - 1; + + + for ( ; vec1 < vec2; vec1++, vec2-- ) + { + FT_Vector tmp; + + + tmp = *vec1; + *vec1 = *vec2; + *vec2 = tmp; + } + } + + /* then the tags */ + { + FT_Byte* tag1 = border->tags + start + 1; + FT_Byte* tag2 = border->tags + count - 1; + + + for ( ; tag1 < tag2; tag1++, tag2-- ) + { + FT_Byte tmp; + + + tmp = *tag1; + *tag1 = *tag2; + *tag2 = tmp; + } + } + } + + border->tags[start ] |= FT_STROKE_TAG_BEGIN; + border->tags[count - 1] |= FT_STROKE_TAG_END; + } + + border->start = -1; + border->movable = FALSE; + } + + + static FT_Error + ft_stroke_border_lineto( FT_StrokeBorder border, + FT_Vector* to, + FT_Bool movable ) + { + FT_Error error = FT_Err_Ok; + + + FT_ASSERT( border->start >= 0 ); + + if ( border->movable ) + { + /* move last point */ + border->points[border->num_points - 1] = *to; + } + else + { + /* don't add zero-length lineto */ + if ( border->num_points > 0 && + FT_IS_SMALL( border->points[border->num_points - 1].x - to->x ) && + FT_IS_SMALL( border->points[border->num_points - 1].y - to->y ) ) + return error; + + /* add one point */ + error = ft_stroke_border_grow( border, 1 ); + if ( !error ) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + + vec[0] = *to; + tag[0] = FT_STROKE_TAG_ON; + + border->num_points += 1; + } + } + border->movable = movable; + return error; + } + + + static FT_Error + ft_stroke_border_conicto( FT_StrokeBorder border, + FT_Vector* control, + FT_Vector* to ) + { + FT_Error error; + + + FT_ASSERT( border->start >= 0 ); + + error = ft_stroke_border_grow( border, 2 ); + if ( !error ) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + + vec[0] = *control; + vec[1] = *to; + + tag[0] = 0; + tag[1] = FT_STROKE_TAG_ON; + + border->num_points += 2; + } + + border->movable = FALSE; + + return error; + } + + + static FT_Error + ft_stroke_border_cubicto( FT_StrokeBorder border, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_Error error; + + + FT_ASSERT( border->start >= 0 ); + + error = ft_stroke_border_grow( border, 3 ); + if ( !error ) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + + vec[0] = *control1; + vec[1] = *control2; + vec[2] = *to; + + tag[0] = FT_STROKE_TAG_CUBIC; + tag[1] = FT_STROKE_TAG_CUBIC; + tag[2] = FT_STROKE_TAG_ON; + + border->num_points += 3; + } + + border->movable = FALSE; + + return error; + } + + +#define FT_ARC_CUBIC_ANGLE ( FT_ANGLE_PI / 2 ) + + + static FT_Error + ft_stroke_border_arcto( FT_StrokeBorder border, + FT_Vector* center, + FT_Fixed radius, + FT_Angle angle_start, + FT_Angle angle_diff ) + { + FT_Angle total, angle, step, rotate, next, theta; + FT_Vector a, b, a2, b2; + FT_Fixed length; + FT_Error error = FT_Err_Ok; + + + /* compute start point */ + FT_Vector_From_Polar( &a, radius, angle_start ); + a.x += center->x; + a.y += center->y; + + total = angle_diff; + angle = angle_start; + rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2; + + while ( total != 0 ) + { + step = total; + if ( step > FT_ARC_CUBIC_ANGLE ) + step = FT_ARC_CUBIC_ANGLE; + + else if ( step < -FT_ARC_CUBIC_ANGLE ) + step = -FT_ARC_CUBIC_ANGLE; + + next = angle + step; + theta = step; + if ( theta < 0 ) + theta = -theta; + + theta >>= 1; + + /* compute end point */ + FT_Vector_From_Polar( &b, radius, next ); + b.x += center->x; + b.y += center->y; + + /* compute first and second control points */ + length = FT_MulDiv( radius, FT_Sin( theta ) * 4, + ( 0x10000L + FT_Cos( theta ) ) * 3 ); + + FT_Vector_From_Polar( &a2, length, angle + rotate ); + a2.x += a.x; + a2.y += a.y; + + FT_Vector_From_Polar( &b2, length, next - rotate ); + b2.x += b.x; + b2.y += b.y; + + /* add cubic arc */ + error = ft_stroke_border_cubicto( border, &a2, &b2, &b ); + if ( error ) + break; + + /* process the rest of the arc ?? */ + a = b; + total -= step; + angle = next; + } + + return error; + } + + + static FT_Error + ft_stroke_border_moveto( FT_StrokeBorder border, + FT_Vector* to ) + { + /* close current open path if any ? */ + if ( border->start >= 0 ) + ft_stroke_border_close( border, FALSE ); + + border->start = border->num_points; + border->movable = FALSE; + + return ft_stroke_border_lineto( border, to, FALSE ); + } + + + static void + ft_stroke_border_init( FT_StrokeBorder border, + FT_Memory memory ) + { + border->memory = memory; + border->points = NULL; + border->tags = NULL; + + border->num_points = 0; + border->max_points = 0; + border->start = -1; + border->valid = FALSE; + } + + + static void + ft_stroke_border_reset( FT_StrokeBorder border ) + { + border->num_points = 0; + border->start = -1; + border->valid = FALSE; + } + + + static void + ft_stroke_border_done( FT_StrokeBorder border ) + { + FT_Memory memory = border->memory; + + + FT_FREE( border->points ); + FT_FREE( border->tags ); + + border->num_points = 0; + border->max_points = 0; + border->start = -1; + border->valid = FALSE; + } + + + static FT_Error + ft_stroke_border_get_counts( FT_StrokeBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_Error error = FT_Err_Ok; + FT_UInt num_points = 0; + FT_UInt num_contours = 0; + + FT_UInt count = border->num_points; + FT_Vector* point = border->points; + FT_Byte* tags = border->tags; + FT_Int in_contour = 0; + + + for ( ; count > 0; count--, num_points++, point++, tags++ ) + { + if ( tags[0] & FT_STROKE_TAG_BEGIN ) + { + if ( in_contour != 0 ) + goto Fail; + + in_contour = 1; + } + else if ( in_contour == 0 ) + goto Fail; + + if ( tags[0] & FT_STROKE_TAG_END ) + { + in_contour = 0; + num_contours++; + } + } + + if ( in_contour != 0 ) + goto Fail; + + border->valid = TRUE; + + Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + + Fail: + num_points = 0; + num_contours = 0; + goto Exit; + } + + + static void + ft_stroke_border_export( FT_StrokeBorder border, + FT_Outline* outline ) + { + /* copy point locations */ + FT_ARRAY_COPY( outline->points + outline->n_points, + border->points, + border->num_points ); + + /* copy tags */ + { + FT_UInt count = border->num_points; + FT_Byte* read = border->tags; + FT_Byte* write = (FT_Byte*)outline->tags + outline->n_points; + + + for ( ; count > 0; count--, read++, write++ ) + { + if ( *read & FT_STROKE_TAG_ON ) + *write = FT_CURVE_TAG_ON; + else if ( *read & FT_STROKE_TAG_CUBIC ) + *write = FT_CURVE_TAG_CUBIC; + else + *write = FT_CURVE_TAG_CONIC; + } + } + + /* copy contours */ + { + FT_UInt count = border->num_points; + FT_Byte* tags = border->tags; + FT_Short* write = outline->contours + outline->n_contours; + FT_Short idx = (FT_Short)outline->n_points; + + + for ( ; count > 0; count--, tags++, idx++ ) + { + if ( *tags & FT_STROKE_TAG_END ) + { + *write++ = idx; + outline->n_contours++; + } + } + } + + outline->n_points = (short)( outline->n_points + border->num_points ); + + FT_ASSERT( FT_Outline_Check( outline ) == 0 ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** STROKER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define FT_SIDE_TO_ROTATE( s ) ( FT_ANGLE_PI2 - (s) * FT_ANGLE_PI ) + + typedef struct FT_StrokerRec_ + { + FT_Angle angle_in; /* direction into curr join */ + FT_Angle angle_out; /* direction out of join */ + FT_Vector center; /* current position */ + FT_Fixed line_length; /* length of last lineto */ + FT_Bool first_point; /* is this the start? */ + FT_Bool subpath_open; /* is the subpath open? */ + FT_Angle subpath_angle; /* subpath start direction */ + FT_Vector subpath_start; /* subpath start position */ + FT_Fixed subpath_line_length; /* subpath start lineto len */ + FT_Bool handle_wide_strokes; /* use wide strokes logic? */ + + FT_Stroker_LineCap line_cap; + FT_Stroker_LineJoin line_join; + FT_Stroker_LineJoin line_join_saved; + FT_Fixed miter_limit; + FT_Fixed radius; + + FT_StrokeBorderRec borders[2]; + FT_Library library; + + } FT_StrokerRec; + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_New( FT_Library library, + FT_Stroker *astroker ) + { + FT_Error error; /* assigned in FT_NEW */ + FT_Memory memory; + FT_Stroker stroker = NULL; + + + if ( !library ) + return FT_THROW( Invalid_Argument ); + + memory = library->memory; + + if ( !FT_NEW( stroker ) ) + { + stroker->library = library; + + ft_stroke_border_init( &stroker->borders[0], memory ); + ft_stroke_border_init( &stroker->borders[1], memory ); + } + + *astroker = stroker; + + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ) + { + stroker->radius = radius; + stroker->line_cap = line_cap; + stroker->line_join = line_join; + stroker->miter_limit = miter_limit; + + /* ensure miter limit has sensible value */ + if ( stroker->miter_limit < 0x10000 ) + stroker->miter_limit = 0x10000; + + /* save line join style: */ + /* line join style can be temporarily changed when stroking curves */ + stroker->line_join_saved = line_join; + + FT_Stroker_Rewind( stroker ); + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_Rewind( FT_Stroker stroker ) + { + if ( stroker ) + { + ft_stroke_border_reset( &stroker->borders[0] ); + ft_stroke_border_reset( &stroker->borders[1] ); + } + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_Done( FT_Stroker stroker ) + { + if ( stroker ) + { + FT_Memory memory = stroker->library->memory; + + + ft_stroke_border_done( &stroker->borders[0] ); + ft_stroke_border_done( &stroker->borders[1] ); + + stroker->library = NULL; + FT_FREE( stroker ); + } + } + + + /* create a circular arc at a corner or cap */ + static FT_Error + ft_stroker_arcto( FT_Stroker stroker, + FT_Int side ) + { + FT_Angle total, rotate; + FT_Fixed radius = stroker->radius; + FT_Error error = FT_Err_Ok; + FT_StrokeBorder border = stroker->borders + side; + + + rotate = FT_SIDE_TO_ROTATE( side ); + + total = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + if ( total == FT_ANGLE_PI ) + total = -rotate * 2; + + error = ft_stroke_border_arcto( border, + &stroker->center, + radius, + stroker->angle_in + rotate, + total ); + border->movable = FALSE; + return error; + } + + + /* add a cap at the end of an opened path */ + static FT_Error + ft_stroker_cap( FT_Stroker stroker, + FT_Angle angle, + FT_Int side ) + { + FT_Error error = FT_Err_Ok; + + + if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) + { + /* add a round cap */ + stroker->angle_in = angle; + stroker->angle_out = angle + FT_ANGLE_PI; + + error = ft_stroker_arcto( stroker, side ); + } + else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE ) + { + /* add a square cap */ + FT_Vector delta, delta2; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; + + + FT_Vector_From_Polar( &delta2, radius, angle + rotate ); + FT_Vector_From_Polar( &delta, radius, angle ); + + delta.x += stroker->center.x + delta2.x; + delta.y += stroker->center.y + delta2.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + FT_Vector_From_Polar( &delta2, radius, angle - rotate ); + FT_Vector_From_Polar( &delta, radius, angle ); + + delta.x += delta2.x + stroker->center.x; + delta.y += delta2.y + stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT ) + { + /* add a butt ending */ + FT_Vector delta; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; + + + FT_Vector_From_Polar( &delta, radius, angle + rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + FT_Vector_From_Polar( &delta, radius, angle - rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + + Exit: + return error; + } + + + /* process an inside corner, i.e. compute intersection */ + static FT_Error + ft_stroker_inside( FT_Stroker stroker, + FT_Int side, + FT_Fixed line_length ) + { + FT_StrokeBorder border = stroker->borders + side; + FT_Angle phi, theta, rotate; + FT_Fixed length, thcos; + FT_Vector delta; + FT_Error error = FT_Err_Ok; + FT_Bool intersect; /* use intersection of lines? */ + + + rotate = FT_SIDE_TO_ROTATE( side ); + + theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ) / 2; + + /* Only intersect borders if between two lineto's and both */ + /* lines are long enough (line_length is zero for curves). */ + if ( !border->movable || line_length == 0 ) + intersect = FALSE; + else + { + /* compute minimum required length of lines */ + FT_Fixed min_length = ft_pos_abs( FT_MulFix( stroker->radius, + FT_Tan( theta ) ) ); + + + intersect = FT_BOOL( stroker->line_length >= min_length && + line_length >= min_length ); + } + + if ( !intersect ) + { + FT_Vector_From_Polar( &delta, stroker->radius, + stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + border->movable = FALSE; + } + else + { + /* compute median angle */ + phi = stroker->angle_in + theta; + + thcos = FT_Cos( theta ); + + length = FT_DivFix( stroker->radius, thcos ); + + FT_Vector_From_Polar( &delta, length, phi + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + } + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + + return error; + } + + + /* process an outside corner, i.e. compute bevel/miter/round */ + static FT_Error + ft_stroker_outside( FT_Stroker stroker, + FT_Int side, + FT_Fixed line_length ) + { + FT_StrokeBorder border = stroker->borders + side; + FT_Error error; + FT_Angle rotate; + + + if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) + error = ft_stroker_arcto( stroker, side ); + else + { + /* this is a mitered (pointed) or beveled (truncated) corner */ + FT_Fixed sigma = 0, radius = stroker->radius; + FT_Angle theta = 0, phi = 0; + FT_Fixed thcos = 0; + FT_Bool bevel, fixed_bevel; + + + rotate = FT_SIDE_TO_ROTATE( side ); + + bevel = + FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_BEVEL ); + + fixed_bevel = + FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_MITER_VARIABLE ); + + if ( !bevel ) + { + theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + + if ( theta == FT_ANGLE_PI ) + { + theta = rotate; + phi = stroker->angle_in; + } + else + { + theta /= 2; + phi = stroker->angle_in + theta + rotate; + } + + thcos = FT_Cos( theta ); + sigma = FT_MulFix( stroker->miter_limit, thcos ); + + /* is miter limit exceeded? */ + if ( sigma < 0x10000L ) + { + /* don't create variable bevels for very small deviations; */ + /* FT_Sin(x) = 0 for x <= 57 */ + if ( fixed_bevel || ft_pos_abs( theta ) > 57 ) + bevel = TRUE; + } + } + + if ( bevel ) /* this is a bevel (broken angle) */ + { + if ( fixed_bevel ) + { + /* the outer corners are simply joined together */ + FT_Vector delta; + + + /* add bevel */ + FT_Vector_From_Polar( &delta, + radius, + stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + border->movable = FALSE; + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + else /* variable bevel */ + { + /* the miter is truncated */ + FT_Vector middle, delta; + FT_Fixed length; + + + /* compute middle point */ + FT_Vector_From_Polar( &middle, + FT_MulFix( radius, stroker->miter_limit ), + phi ); + middle.x += stroker->center.x; + middle.y += stroker->center.y; + + /* compute first angle point */ + length = FT_MulDiv( radius, 0x10000L - sigma, + ft_pos_abs( FT_Sin( theta ) ) ); + + FT_Vector_From_Polar( &delta, length, phi + rotate ); + delta.x += middle.x; + delta.y += middle.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + /* compute second angle point */ + FT_Vector_From_Polar( &delta, length, phi - rotate ); + delta.x += middle.x; + delta.y += middle.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + /* finally, add an end point; only needed if not lineto */ + /* (line_length is zero for curves) */ + if ( line_length == 0 ) + { + FT_Vector_From_Polar( &delta, + radius, + stroker->angle_out + rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + } + } + else /* this is a miter (intersection) */ + { + FT_Fixed length; + FT_Vector delta; + + + length = FT_DivFix( stroker->radius, thcos ); + + FT_Vector_From_Polar( &delta, length, phi ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + /* now add an end point; only needed if not lineto */ + /* (line_length is zero for curves) */ + if ( line_length == 0 ) + { + FT_Vector_From_Polar( &delta, + stroker->radius, + stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + } + } + + Exit: + return error; + } + + + static FT_Error + ft_stroker_process_corner( FT_Stroker stroker, + FT_Fixed line_length ) + { + FT_Error error = FT_Err_Ok; + FT_Angle turn; + FT_Int inside_side; + + + turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + + /* no specific corner processing is required if the turn is 0 */ + if ( turn == 0 ) + goto Exit; + + /* when we turn to the right, the inside side is 0 */ + inside_side = 0; + + /* otherwise, the inside side is 1 */ + if ( turn < 0 ) + inside_side = 1; + + /* process the inside side */ + error = ft_stroker_inside( stroker, inside_side, line_length ); + if ( error ) + goto Exit; + + /* process the outside side */ + error = ft_stroker_outside( stroker, 1 - inside_side, line_length ); + + Exit: + return error; + } + + + /* add two points to the left and right borders corresponding to the */ + /* start of the subpath */ + static FT_Error + ft_stroker_subpath_start( FT_Stroker stroker, + FT_Angle start_angle, + FT_Fixed line_length ) + { + FT_Vector delta; + FT_Vector point; + FT_Error error; + FT_StrokeBorder border; + + + FT_Vector_From_Polar( &delta, stroker->radius, + start_angle + FT_ANGLE_PI2 ); + + point.x = stroker->center.x + delta.x; + point.y = stroker->center.y + delta.y; + + border = stroker->borders; + error = ft_stroke_border_moveto( border, &point ); + if ( error ) + goto Exit; + + point.x = stroker->center.x - delta.x; + point.y = stroker->center.y - delta.y; + + border++; + error = ft_stroke_border_moveto( border, &point ); + + /* save angle, position, and line length for last join */ + /* (line_length is zero for curves) */ + stroker->subpath_angle = start_angle; + stroker->first_point = FALSE; + stroker->subpath_line_length = line_length; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ) + { + FT_Error error = FT_Err_Ok; + FT_StrokeBorder border; + FT_Vector delta; + FT_Angle angle; + FT_Int side; + FT_Fixed line_length; + + + delta.x = to->x - stroker->center.x; + delta.y = to->y - stroker->center.y; + + /* a zero-length lineto is a no-op; avoid creating a spurious corner */ + if ( delta.x == 0 && delta.y == 0 ) + goto Exit; + + /* compute length of line */ + line_length = FT_Vector_Length( &delta ); + + angle = FT_Atan2( delta.x, delta.y ); + FT_Vector_From_Polar( &delta, stroker->radius, angle + FT_ANGLE_PI2 ); + + /* process corner if necessary */ + if ( stroker->first_point ) + { + /* This is the first segment of a subpath. We need to */ + /* add a point to each border at their respective starting */ + /* point locations. */ + error = ft_stroker_subpath_start( stroker, angle, line_length ); + if ( error ) + goto Exit; + } + else + { + /* process the current corner */ + stroker->angle_out = angle; + error = ft_stroker_process_corner( stroker, line_length ); + if ( error ) + goto Exit; + } + + /* now add a line segment to both the `inside' and `outside' paths */ + for ( border = stroker->borders, side = 1; side >= 0; side--, border++ ) + { + FT_Vector point; + + + point.x = to->x + delta.x; + point.y = to->y + delta.y; + + /* the ends of lineto borders are movable */ + error = ft_stroke_border_lineto( border, &point, TRUE ); + if ( error ) + goto Exit; + + delta.x = -delta.x; + delta.y = -delta.y; + } + + stroker->angle_in = angle; + stroker->center = *to; + stroker->line_length = line_length; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ) + { + FT_Error error = FT_Err_Ok; + FT_Vector bez_stack[34]; + FT_Vector* arc; + FT_Vector* limit = bez_stack + 30; + FT_Bool first_arc = TRUE; + + + /* if all control points are coincident, this is a no-op; */ + /* avoid creating a spurious corner */ + if ( FT_IS_SMALL( stroker->center.x - control->x ) && + FT_IS_SMALL( stroker->center.y - control->y ) && + FT_IS_SMALL( control->x - to->x ) && + FT_IS_SMALL( control->y - to->y ) ) + { + stroker->center = *to; + goto Exit; + } + + arc = bez_stack; + arc[0] = *to; + arc[1] = *control; + arc[2] = stroker->center; + + while ( arc >= bez_stack ) + { + FT_Angle angle_in, angle_out; + + + /* initialize with current direction */ + angle_in = angle_out = stroker->angle_in; + + if ( arc < limit && + !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) ) + { + if ( stroker->first_point ) + stroker->angle_in = angle_in; + + ft_conic_split( arc ); + arc += 2; + continue; + } + + if ( first_arc ) + { + first_arc = FALSE; + + /* process corner if necessary */ + if ( stroker->first_point ) + error = ft_stroker_subpath_start( stroker, angle_in, 0 ); + else + { + stroker->angle_out = angle_in; + error = ft_stroker_process_corner( stroker, 0 ); + } + } + else if ( ft_pos_abs( FT_Angle_Diff( stroker->angle_in, angle_in ) ) > + FT_SMALL_CONIC_THRESHOLD / 4 ) + { + /* if the deviation from one arc to the next is too great, */ + /* add a round corner */ + stroker->center = arc[2]; + stroker->angle_out = angle_in; + stroker->line_join = FT_STROKER_LINEJOIN_ROUND; + + error = ft_stroker_process_corner( stroker, 0 ); + + /* reinstate line join style */ + stroker->line_join = stroker->line_join_saved; + } + + if ( error ) + goto Exit; + + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ + { + FT_Vector ctrl, end; + FT_Angle theta, phi, rotate, alpha0 = 0; + FT_Fixed length; + FT_StrokeBorder border; + FT_Int side; + + + theta = FT_Angle_Diff( angle_in, angle_out ) / 2; + phi = angle_in + theta; + length = FT_DivFix( stroker->radius, FT_Cos( theta ) ); + + /* compute direction of original arc */ + if ( stroker->handle_wide_strokes ) + alpha0 = FT_Atan2( arc[0].x - arc[2].x, arc[0].y - arc[2].y ); + + for ( border = stroker->borders, side = 0; + side <= 1; + side++, border++ ) + { + rotate = FT_SIDE_TO_ROTATE( side ); + + /* compute control point */ + FT_Vector_From_Polar( &ctrl, length, phi + rotate ); + ctrl.x += arc[1].x; + ctrl.y += arc[1].y; + + /* compute end point */ + FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); + end.x += arc[0].x; + end.y += arc[0].y; + + if ( stroker->handle_wide_strokes ) + { + FT_Vector start; + FT_Angle alpha1; + + + /* determine whether the border radius is greater than the */ + /* radius of curvature of the original arc */ + start = border->points[border->num_points - 1]; + + alpha1 = FT_Atan2( end.x - start.x, end.y - start.y ); + + /* is the direction of the border arc opposite to */ + /* that of the original arc? */ + if ( ft_pos_abs( FT_Angle_Diff( alpha0, alpha1 ) ) > + FT_ANGLE_PI / 2 ) + { + FT_Angle beta, gamma; + FT_Vector bvec, delta; + FT_Fixed blen, sinA, sinB, alen; + + + /* use the sine rule to find the intersection point */ + beta = FT_Atan2( arc[2].x - start.x, arc[2].y - start.y ); + gamma = FT_Atan2( arc[0].x - end.x, arc[0].y - end.y ); + + bvec.x = end.x - start.x; + bvec.y = end.y - start.y; + + blen = FT_Vector_Length( &bvec ); + + sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) ); + sinB = ft_pos_abs( FT_Sin( beta - gamma ) ); + + alen = FT_MulDiv( blen, sinA, sinB ); + + FT_Vector_From_Polar( &delta, alen, beta ); + delta.x += start.x; + delta.y += start.y; + + /* circumnavigate the negative sector backwards */ + border->movable = FALSE; + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + error = ft_stroke_border_lineto( border, &end, FALSE ); + if ( error ) + goto Exit; + error = ft_stroke_border_conicto( border, &ctrl, &start ); + if ( error ) + goto Exit; + /* and then move to the endpoint */ + error = ft_stroke_border_lineto( border, &end, FALSE ); + if ( error ) + goto Exit; + + continue; + } + + /* else fall through */ + } + + /* simply add an arc */ + error = ft_stroke_border_conicto( border, &ctrl, &end ); + if ( error ) + goto Exit; + } + } + + arc -= 2; + + stroker->angle_in = angle_out; + } + + stroker->center = *to; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_Error error = FT_Err_Ok; + FT_Vector bez_stack[37]; + FT_Vector* arc; + FT_Vector* limit = bez_stack + 32; + FT_Bool first_arc = TRUE; + + + /* if all control points are coincident, this is a no-op; */ + /* avoid creating a spurious corner */ + if ( FT_IS_SMALL( stroker->center.x - control1->x ) && + FT_IS_SMALL( stroker->center.y - control1->y ) && + FT_IS_SMALL( control1->x - control2->x ) && + FT_IS_SMALL( control1->y - control2->y ) && + FT_IS_SMALL( control2->x - to->x ) && + FT_IS_SMALL( control2->y - to->y ) ) + { + stroker->center = *to; + goto Exit; + } + + arc = bez_stack; + arc[0] = *to; + arc[1] = *control2; + arc[2] = *control1; + arc[3] = stroker->center; + + while ( arc >= bez_stack ) + { + FT_Angle angle_in, angle_mid, angle_out; + + + /* initialize with current direction */ + angle_in = angle_out = angle_mid = stroker->angle_in; + + if ( arc < limit && + !ft_cubic_is_small_enough( arc, &angle_in, + &angle_mid, &angle_out ) ) + { + if ( stroker->first_point ) + stroker->angle_in = angle_in; + + ft_cubic_split( arc ); + arc += 3; + continue; + } + + if ( first_arc ) + { + first_arc = FALSE; + + /* process corner if necessary */ + if ( stroker->first_point ) + error = ft_stroker_subpath_start( stroker, angle_in, 0 ); + else + { + stroker->angle_out = angle_in; + error = ft_stroker_process_corner( stroker, 0 ); + } + } + else if ( ft_pos_abs( FT_Angle_Diff( stroker->angle_in, angle_in ) ) > + FT_SMALL_CUBIC_THRESHOLD / 4 ) + { + /* if the deviation from one arc to the next is too great, */ + /* add a round corner */ + stroker->center = arc[3]; + stroker->angle_out = angle_in; + stroker->line_join = FT_STROKER_LINEJOIN_ROUND; + + error = ft_stroker_process_corner( stroker, 0 ); + + /* reinstate line join style */ + stroker->line_join = stroker->line_join_saved; + } + + if ( error ) + goto Exit; + + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ + { + FT_Vector ctrl1, ctrl2, end; + FT_Angle theta1, phi1, theta2, phi2, rotate, alpha0 = 0; + FT_Fixed length1, length2; + FT_StrokeBorder border; + FT_Int side; + + + theta1 = FT_Angle_Diff( angle_in, angle_mid ) / 2; + theta2 = FT_Angle_Diff( angle_mid, angle_out ) / 2; + phi1 = ft_angle_mean( angle_in, angle_mid ); + phi2 = ft_angle_mean( angle_mid, angle_out ); + length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); + length2 = FT_DivFix( stroker->radius, FT_Cos( theta2 ) ); + + /* compute direction of original arc */ + if ( stroker->handle_wide_strokes ) + alpha0 = FT_Atan2( arc[0].x - arc[3].x, arc[0].y - arc[3].y ); + + for ( border = stroker->borders, side = 0; + side <= 1; + side++, border++ ) + { + rotate = FT_SIDE_TO_ROTATE( side ); + + /* compute control points */ + FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate ); + ctrl1.x += arc[2].x; + ctrl1.y += arc[2].y; + + FT_Vector_From_Polar( &ctrl2, length2, phi2 + rotate ); + ctrl2.x += arc[1].x; + ctrl2.y += arc[1].y; + + /* compute end point */ + FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); + end.x += arc[0].x; + end.y += arc[0].y; + + if ( stroker->handle_wide_strokes ) + { + FT_Vector start; + FT_Angle alpha1; + + + /* determine whether the border radius is greater than the */ + /* radius of curvature of the original arc */ + start = border->points[border->num_points - 1]; + + alpha1 = FT_Atan2( end.x - start.x, end.y - start.y ); + + /* is the direction of the border arc opposite to */ + /* that of the original arc? */ + if ( ft_pos_abs( FT_Angle_Diff( alpha0, alpha1 ) ) > + FT_ANGLE_PI / 2 ) + { + FT_Angle beta, gamma; + FT_Vector bvec, delta; + FT_Fixed blen, sinA, sinB, alen; + + + /* use the sine rule to find the intersection point */ + beta = FT_Atan2( arc[3].x - start.x, arc[3].y - start.y ); + gamma = FT_Atan2( arc[0].x - end.x, arc[0].y - end.y ); + + bvec.x = end.x - start.x; + bvec.y = end.y - start.y; + + blen = FT_Vector_Length( &bvec ); + + sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) ); + sinB = ft_pos_abs( FT_Sin( beta - gamma ) ); + + alen = FT_MulDiv( blen, sinA, sinB ); + + FT_Vector_From_Polar( &delta, alen, beta ); + delta.x += start.x; + delta.y += start.y; + + /* circumnavigate the negative sector backwards */ + border->movable = FALSE; + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + error = ft_stroke_border_lineto( border, &end, FALSE ); + if ( error ) + goto Exit; + error = ft_stroke_border_cubicto( border, + &ctrl2, + &ctrl1, + &start ); + if ( error ) + goto Exit; + /* and then move to the endpoint */ + error = ft_stroke_border_lineto( border, &end, FALSE ); + if ( error ) + goto Exit; + + continue; + } + + /* else fall through */ + } + + /* simply add an arc */ + error = ft_stroke_border_cubicto( border, &ctrl1, &ctrl2, &end ); + if ( error ) + goto Exit; + } + } + + arc -= 3; + + stroker->angle_in = angle_out; + } + + stroker->center = *to; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ) + { + /* We cannot process the first point, because there is not enough */ + /* information regarding its corner/cap. The latter will be processed */ + /* in the `FT_Stroker_EndSubPath' routine. */ + /* */ + stroker->first_point = TRUE; + stroker->center = *to; + stroker->subpath_open = open; + + /* Determine if we need to check whether the border radius is greater */ + /* than the radius of curvature of a curve, to handle this case */ + /* specially. This is only required if bevel joins or butt caps may */ + /* be created, because round & miter joins and round & square caps */ + /* cover the negative sector created with wide strokes. */ + stroker->handle_wide_strokes = + FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_ROUND || + ( stroker->subpath_open && + stroker->line_cap == FT_STROKER_LINECAP_BUTT ) ); + + /* record the subpath start point for each border */ + stroker->subpath_start = *to; + + stroker->angle_in = 0; + + return FT_Err_Ok; + } + + + static FT_Error + ft_stroker_add_reverse_left( FT_Stroker stroker, + FT_Bool open ) + { + FT_StrokeBorder right = stroker->borders + 0; + FT_StrokeBorder left = stroker->borders + 1; + FT_Int new_points; + FT_Error error = FT_Err_Ok; + + + FT_ASSERT( left->start >= 0 ); + + new_points = left->num_points - left->start; + if ( new_points > 0 ) + { + error = ft_stroke_border_grow( right, (FT_UInt)new_points ); + if ( error ) + goto Exit; + + { + FT_Vector* dst_point = right->points + right->num_points; + FT_Byte* dst_tag = right->tags + right->num_points; + FT_Vector* src_point = left->points + left->num_points - 1; + FT_Byte* src_tag = left->tags + left->num_points - 1; + + + while ( src_point >= left->points + left->start ) + { + *dst_point = *src_point; + *dst_tag = *src_tag; + + if ( open ) + dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END; + else + { + FT_Byte ttag = + (FT_Byte)( dst_tag[0] & FT_STROKE_TAG_BEGIN_END ); + + + /* switch begin/end tags if necessary */ + if ( ttag == FT_STROKE_TAG_BEGIN || + ttag == FT_STROKE_TAG_END ) + dst_tag[0] ^= FT_STROKE_TAG_BEGIN_END; + } + + src_point--; + src_tag--; + dst_point++; + dst_tag++; + } + } + + left->num_points = left->start; + right->num_points += new_points; + + right->movable = FALSE; + left->movable = FALSE; + } + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + /* there's a lot of magic in this function! */ + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ) + { + FT_Error error = FT_Err_Ok; + + + if ( stroker->subpath_open ) + { + FT_StrokeBorder right = stroker->borders; + + + /* All right, this is an opened path, we need to add a cap between */ + /* right & left, add the reverse of left, then add a final cap */ + /* between left & right. */ + error = ft_stroker_cap( stroker, stroker->angle_in, 0 ); + if ( error ) + goto Exit; + + /* add reversed points from `left' to `right' */ + error = ft_stroker_add_reverse_left( stroker, TRUE ); + if ( error ) + goto Exit; + + /* now add the final cap */ + stroker->center = stroker->subpath_start; + error = ft_stroker_cap( stroker, + stroker->subpath_angle + FT_ANGLE_PI, 0 ); + if ( error ) + goto Exit; + + /* Now end the right subpath accordingly. The left one is */ + /* rewind and doesn't need further processing. */ + ft_stroke_border_close( right, FALSE ); + } + else + { + FT_Angle turn; + FT_Int inside_side; + + + /* close the path if needed */ + if ( stroker->center.x != stroker->subpath_start.x || + stroker->center.y != stroker->subpath_start.y ) + { + error = FT_Stroker_LineTo( stroker, &stroker->subpath_start ); + if ( error ) + goto Exit; + } + + /* process the corner */ + stroker->angle_out = stroker->subpath_angle; + turn = FT_Angle_Diff( stroker->angle_in, + stroker->angle_out ); + + /* no specific corner processing is required if the turn is 0 */ + if ( turn != 0 ) + { + /* when we turn to the right, the inside side is 0 */ + inside_side = 0; + + /* otherwise, the inside side is 1 */ + if ( turn < 0 ) + inside_side = 1; + + error = ft_stroker_inside( stroker, + inside_side, + stroker->subpath_line_length ); + if ( error ) + goto Exit; + + /* process the outside side */ + error = ft_stroker_outside( stroker, + 1 - inside_side, + stroker->subpath_line_length ); + if ( error ) + goto Exit; + } + + /* then end our two subpaths */ + ft_stroke_border_close( stroker->borders + 0, FALSE ); + ft_stroke_border_close( stroker->borders + 1, TRUE ); + } + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_UInt num_points = 0, num_contours = 0; + FT_Error error; + + + if ( !stroker || border > 1 ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + error = ft_stroke_border_get_counts( stroker->borders + border, + &num_points, &num_contours ); + Exit: + if ( anum_points ) + *anum_points = num_points; + + if ( anum_contours ) + *anum_contours = num_contours; + + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_UInt count1, count2, num_points = 0; + FT_UInt count3, count4, num_contours = 0; + FT_Error error; + + + error = ft_stroke_border_get_counts( stroker->borders + 0, + &count1, &count2 ); + if ( error ) + goto Exit; + + error = ft_stroke_border_get_counts( stroker->borders + 1, + &count3, &count4 ); + if ( error ) + goto Exit; + + num_points = count1 + count3; + num_contours = count2 + count4; + + Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ) + { + if ( border == FT_STROKER_BORDER_LEFT || + border == FT_STROKER_BORDER_RIGHT ) + { + FT_StrokeBorder sborder = & stroker->borders[border]; + + + if ( sborder->valid ) + ft_stroke_border_export( sborder, outline ); + } + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ) + { + FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_LEFT, outline ); + FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_RIGHT, outline ); + } + + + /* documentation is in ftstroke.h */ + + /* + * The following is very similar to FT_Outline_Decompose, except + * that we do support opened paths, and do not scale the outline. + */ + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ) + { + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + FT_Error error; + + FT_Int n; /* index of contour in outline */ + FT_UInt first; /* index of first point in contour */ + FT_Int tag; /* current point's state */ + + + if ( !outline || !stroker ) + return FT_THROW( Invalid_Argument ); + + FT_Stroker_Rewind( stroker ); + + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + FT_UInt last; /* index of last point in contour */ + + + last = outline->contours[n]; + limit = outline->points + last; + + /* skip empty points; we don't stroke these */ + if ( last <= first ) + { + first = last + 1; + continue; + } + + v_start = outline->points[first]; + v_last = outline->points[last]; + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* First point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + } + point--; + tags--; + } + + error = FT_Stroker_BeginSubPath( stroker, &v_start, opened ); + if ( error ) + goto Exit; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = point->x; + vec.y = point->y; + + error = FT_Stroker_LineTo( stroker, &vec ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = point->x; + v_control.y = point->y; + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec = point[0]; + + if ( tag == FT_CURVE_TAG_ON ) + { + error = FT_Stroker_ConicTo( stroker, &v_control, &vec ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + error = FT_Stroker_ConicTo( stroker, &v_control, &v_start ); + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1 = point[-2]; + vec2 = point[-1]; + + if ( point <= limit ) + { + FT_Vector vec; + + + vec = point[0]; + + error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec ); + if ( error ) + goto Exit; + continue; + } + + error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start ); + goto Close; + } + } + } + + Close: + if ( error ) + goto Exit; + + /* don't try to end the path if no segments have been generated */ + if ( !stroker->first_point ) + { + error = FT_Stroker_EndSubPath( stroker ); + if ( error ) + goto Exit; + } + + first = last + 1; + } + + return FT_Err_Ok; + + Exit: + return error; + + Invalid_Outline: + return FT_THROW( Invalid_Outline ); + } + + + /* declare an extern to access `ft_outline_glyph_class' globally */ + /* allocated in `ftglyph.c', and use the FT_OUTLINE_GLYPH_CLASS_GET */ + /* macro to access it when FT_CONFIG_OPTION_PIC is defined */ +#ifndef FT_CONFIG_OPTION_PIC + extern const FT_Glyph_Class ft_outline_glyph_class; +#endif +#include "basepic.h" + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Glyph glyph = NULL; + FT_Library library = stroker->library; + + FT_UNUSED( library ); + + + if ( pglyph == NULL ) + goto Exit; + + glyph = *pglyph; + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + goto Exit; + + { + FT_Glyph copy; + + + error = FT_Glyph_Copy( glyph, © ); + if ( error ) + goto Exit; + + glyph = copy; + } + + { + FT_OutlineGlyph oglyph = (FT_OutlineGlyph)glyph; + FT_Outline* outline = &oglyph->outline; + FT_UInt num_points, num_contours; + + + error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); + if ( error ) + goto Fail; + + (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); + + FT_Outline_Done( glyph->library, outline ); + + error = FT_Outline_New( glyph->library, + num_points, num_contours, outline ); + if ( error ) + goto Fail; + + outline->n_points = 0; + outline->n_contours = 0; + + FT_Stroker_Export( stroker, outline ); + } + + if ( destroy ) + FT_Done_Glyph( *pglyph ); + + *pglyph = glyph; + goto Exit; + + Fail: + FT_Done_Glyph( glyph ); + glyph = NULL; + + if ( !destroy ) + *pglyph = NULL; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Glyph glyph = NULL; + FT_Library library = stroker->library; + + FT_UNUSED( library ); + + + if ( pglyph == NULL ) + goto Exit; + + glyph = *pglyph; + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + goto Exit; + + { + FT_Glyph copy; + + + error = FT_Glyph_Copy( glyph, © ); + if ( error ) + goto Exit; + + glyph = copy; + } + + { + FT_OutlineGlyph oglyph = (FT_OutlineGlyph)glyph; + FT_StrokerBorder border; + FT_Outline* outline = &oglyph->outline; + FT_UInt num_points, num_contours; + + + border = FT_Outline_GetOutsideBorder( outline ); + if ( inside ) + { + if ( border == FT_STROKER_BORDER_LEFT ) + border = FT_STROKER_BORDER_RIGHT; + else + border = FT_STROKER_BORDER_LEFT; + } + + error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); + if ( error ) + goto Fail; + + (void)FT_Stroker_GetBorderCounts( stroker, border, + &num_points, &num_contours ); + + FT_Outline_Done( glyph->library, outline ); + + error = FT_Outline_New( glyph->library, + num_points, + num_contours, + outline ); + if ( error ) + goto Fail; + + outline->n_points = 0; + outline->n_contours = 0; + + FT_Stroker_ExportBorder( stroker, border, outline ); + } + + if ( destroy ) + FT_Done_Glyph( *pglyph ); + + *pglyph = glyph; + goto Exit; + + Fail: + FT_Done_Glyph( glyph ); + glyph = NULL; + + if ( !destroy ) + *pglyph = NULL; + + Exit: + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftsynth.c b/drivers/freetype/src/base/ftsynth.c new file mode 100644 index 0000000000..241d37f426 --- /dev/null +++ b/drivers/freetype/src/base/ftsynth.c @@ -0,0 +1,153 @@ +/***************************************************************************/ +/* */ +/* ftsynth.c */ +/* */ +/* FreeType synthesizing code for emboldening and slanting (body). */ +/* */ +/* Copyright 2000-2006, 2010, 2012 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_SYNTHESIS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_OUTLINE_H +#include FT_BITMAP_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_synth + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** EXPERIMENTAL OBLIQUING SUPPORT ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /* documentation is in ftsynth.h */ + + FT_EXPORT_DEF( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) + { + FT_Matrix transform; + FT_Outline* outline = &slot->outline; + + + /* only oblique outline glyphs */ + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + return; + + /* we don't touch the advance width */ + + /* For italic, simply apply a shear transform, with an angle */ + /* of about 12 degrees. */ + + transform.xx = 0x10000L; + transform.yx = 0x00000L; + + transform.xy = 0x0366AL; + transform.yy = 0x10000L; + + FT_Outline_Transform( outline, &transform ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** EXPERIMENTAL EMBOLDENING SUPPORT ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftsynth.h */ + + FT_EXPORT_DEF( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) + { + FT_Library library = slot->library; + FT_Face face = slot->face; + FT_Error error; + FT_Pos xstr, ystr; + + + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && + slot->format != FT_GLYPH_FORMAT_BITMAP ) + return; + + /* some reasonable strength */ + xstr = FT_MulFix( face->units_per_EM, + face->size->metrics.y_scale ) / 24; + ystr = xstr; + + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* ignore error */ + (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); + } + else /* slot->format == FT_GLYPH_FORMAT_BITMAP */ + { + /* round to full pixels */ + xstr &= ~63; + if ( xstr == 0 ) + xstr = 1 << 6; + ystr &= ~63; + + /* + * XXX: overflow check for 16-bit system, for compatibility + * with FT_GlyphSlot_Embolden() since freetype-2.1.10. + * unfortunately, this function return no informations + * about the cause of error. + */ + if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN ) + { + FT_TRACE1(( "FT_GlyphSlot_Embolden:" )); + FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr )); + return; + } + error = FT_GlyphSlot_Own_Bitmap( slot ); + if ( error ) + return; + + error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr ); + if ( error ) + return; + } + + if ( slot->advance.x ) + slot->advance.x += xstr; + + if ( slot->advance.y ) + slot->advance.y += ystr; + + slot->metrics.width += xstr; + slot->metrics.height += ystr; + slot->metrics.horiAdvance += xstr; + slot->metrics.vertAdvance += ystr; + + /* XXX: 16-bit overflow case must be excluded before here */ + if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) + slot->bitmap_top += (FT_Int)( ystr >> 6 ); + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftsystem.c b/drivers/freetype/src/base/ftsystem.c new file mode 100644 index 0000000000..2c6ddac10c --- /dev/null +++ b/drivers/freetype/src/base/ftsystem.c @@ -0,0 +1,320 @@ +/***************************************************************************/ +/* */ +/* ftsystem.c */ +/* */ +/* ANSI-specific FreeType low-level system interface (body). */ +/* */ +/* Copyright 1996-2002, 2006, 2008-2011, 2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This file contains the default interface used by FreeType to access */ + /* low-level, i.e. memory management, i/o access as well as thread */ + /* synchronisation. It can be replaced by user-specific routines if */ + /* necessary. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H + + + /*************************************************************************/ + /* */ + /* MEMORY MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* It is not necessary to do any error checking for the */ + /* allocation-related functions. This will be done by the higher level */ + /* routines like ft_mem_alloc() or ft_mem_realloc(). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_alloc */ + /* */ + /* <Description> */ + /* The memory allocation function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* size :: The requested size in bytes. */ + /* */ + /* <Return> */ + /* The address of newly allocated block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_alloc( FT_Memory memory, + long size ) + { + FT_UNUSED( memory ); + + return ft_smalloc( size ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_realloc */ + /* */ + /* <Description> */ + /* The memory reallocation function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* cur_size :: The current size of the allocated memory block. */ + /* */ + /* new_size :: The newly requested size in bytes. */ + /* */ + /* block :: The current address of the block in memory. */ + /* */ + /* <Return> */ + /* The address of the reallocated memory block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_realloc( FT_Memory memory, + long cur_size, + long new_size, + void* block ) + { + FT_UNUSED( memory ); + FT_UNUSED( cur_size ); + + return ft_srealloc( block, new_size ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_free */ + /* */ + /* <Description> */ + /* The memory release function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* block :: The address of block in memory to be freed. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_free( FT_Memory memory, + void* block ) + { + FT_UNUSED( memory ); + + ft_sfree( block ); + } + + + /*************************************************************************/ + /* */ + /* RESOURCE MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + +#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT + + /*************************************************************************/ + /* */ + /* 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_io + + /* We use the macro STREAM_FILE for convenience to extract the */ + /* system-specific stream handle from a given FreeType stream object */ +#define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_ansi_stream_close */ + /* */ + /* <Description> */ + /* The function to close a stream. */ + /* */ + /* <Input> */ + /* stream :: A pointer to the stream object. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_ansi_stream_close( FT_Stream stream ) + { + ft_fclose( STREAM_FILE( stream ) ); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_ansi_stream_io */ + /* */ + /* <Description> */ + /* The function to open a stream. */ + /* */ + /* <Input> */ + /* stream :: A pointer to the stream object. */ + /* */ + /* offset :: The position in the data stream to start reading. */ + /* */ + /* buffer :: The address of buffer to store the read data. */ + /* */ + /* count :: The number of bytes to read from the stream. */ + /* */ + /* <Return> */ + /* The number of bytes actually read. If `count' is zero (this is, */ + /* the function is used for seeking), a non-zero return value */ + /* indicates an error. */ + /* */ + FT_CALLBACK_DEF( unsigned long ) + ft_ansi_stream_io( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ) + { + FT_FILE* file; + + + if ( !count && offset > stream->size ) + return 1; + + file = STREAM_FILE( stream ); + + if ( stream->pos != offset ) + ft_fseek( file, offset, SEEK_SET ); + + return (unsigned long)ft_fread( buffer, 1, count, file ); + } + + + /* documentation is in ftstream.h */ + + FT_BASE_DEF( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ) + { + FT_FILE* file; + + + if ( !stream ) + return FT_THROW( Invalid_Stream_Handle ); + + stream->descriptor.pointer = NULL; + stream->pathname.pointer = (char*)filepathname; + stream->base = 0; + stream->pos = 0; + stream->read = NULL; + stream->close = NULL; + + file = ft_fopen( filepathname, "rb" ); + if ( !file ) + { + FT_ERROR(( "FT_Stream_Open:" + " could not open `%s'\n", filepathname )); + + return FT_THROW( Cannot_Open_Resource ); + } + + ft_fseek( file, 0, SEEK_END ); + stream->size = ft_ftell( file ); + if ( !stream->size ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " opened `%s' but zero-sized\n", filepathname )); + ft_fclose( file ); + return FT_THROW( Cannot_Open_Stream ); + } + ft_fseek( file, 0, SEEK_SET ); + + stream->descriptor.pointer = file; + stream->read = ft_ansi_stream_io; + stream->close = ft_ansi_stream_close; + + FT_TRACE1(( "FT_Stream_Open:" )); + FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", + filepathname, stream->size )); + + return FT_Err_Ok; + } + +#endif /* !FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ + +#ifdef FT_DEBUG_MEMORY + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ); + + extern void + ft_mem_debug_done( FT_Memory memory ); + +#endif + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( FT_Memory ) + FT_New_Memory( void ) + { + FT_Memory memory; + + + memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) ); + if ( memory ) + { + memory->user = 0; + memory->alloc = ft_alloc; + memory->realloc = ft_realloc; + memory->free = ft_free; +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_init( memory ); +#endif + } + + return memory; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( void ) + FT_Done_Memory( FT_Memory memory ) + { +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_done( memory ); +#endif + ft_sfree( memory ); + } + + +/* END */ diff --git a/drivers/freetype/src/base/fttrigon.c b/drivers/freetype/src/base/fttrigon.c new file mode 100644 index 0000000000..4ffdcb77f1 --- /dev/null +++ b/drivers/freetype/src/base/fttrigon.c @@ -0,0 +1,492 @@ +/***************************************************************************/ +/* */ +/* fttrigon.c */ +/* */ +/* FreeType trigonometric functions (body). */ +/* */ +/* Copyright 2001-2005, 2012-2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This is a fixed-point CORDIC implementation of trigonometric */ + /* functions as well as transformations between Cartesian and polar */ + /* coordinates. The angles are represented as 16.16 fixed-point values */ + /* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */ + /* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */ + /* discrete Cartesian grid can have the same or better angular */ + /* resolution. Therefore, to maintain this precision, some functions */ + /* require an interim upscaling of the vectors, whereas others operate */ + /* with 24-bit long vectors directly. */ + /* */ + /*************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_CALC_H +#include FT_TRIGONOMETRY_H + + + /* the Cordic shrink factor 0.858785336480436 * 2^32 */ +#define FT_TRIG_SCALE 0xDBD95B16UL + + /* the highest bit in overflow-safe vector components, */ + /* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */ +#define FT_TRIG_SAFE_MSB 29 + + /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ +#define FT_TRIG_MAX_ITERS 23 + + static const FT_Fixed + ft_trig_arctan_table[] = + { + 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, + 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, + 57L, 29L, 14L, 7L, 4L, 2L, 1L + }; + + +#ifdef FT_LONG64 + + /* multiply a given value by the CORDIC shrink factor */ + static FT_Fixed + ft_trig_downscale( FT_Fixed val ) + { + FT_Fixed s; + FT_Int64 v; + + + s = val; + val = FT_ABS( val ); + + v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; + val = (FT_Fixed)( v >> 32 ); + + return ( s >= 0 ) ? val : -val; + } + +#else /* !FT_LONG64 */ + + /* multiply a given value by the CORDIC shrink factor */ + static FT_Fixed + ft_trig_downscale( FT_Fixed val ) + { + FT_Fixed s; + FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; + + + s = val; + val = FT_ABS( val ); + + v1 = (FT_UInt32)val >> 16; + v2 = (FT_UInt32)( val & 0xFFFFL ); + + k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ + k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL ); /* constant */ + + hi = k1 * v1; + lo1 = k1 * v2 + k2 * v1; /* can't overflow */ + + lo2 = ( k2 * v2 ) >> 16; + lo3 = FT_MAX( lo1, lo2 ); + lo1 += lo2; + + hi += lo1 >> 16; + if ( lo1 < lo3 ) + hi += (FT_UInt32)0x10000UL; + + val = (FT_Fixed)hi; + + return ( s >= 0 ) ? val : -val; + } + +#endif /* !FT_LONG64 */ + + + static FT_Int + ft_trig_prenorm( FT_Vector* vec ) + { + FT_Pos x, y; + FT_Int shift; + + + x = vec->x; + y = vec->y; + + shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) ); + + if ( shift <= FT_TRIG_SAFE_MSB ) + { + shift = FT_TRIG_SAFE_MSB - shift; + vec->x = (FT_Pos)( (FT_ULong)x << shift ); + vec->y = (FT_Pos)( (FT_ULong)y << shift ); + } + else + { + shift -= FT_TRIG_SAFE_MSB; + vec->x = x >> shift; + vec->y = y >> shift; + shift = -shift; + } + + return shift; + } + + + static void + ft_trig_pseudo_rotate( FT_Vector* vec, + FT_Angle theta ) + { + FT_Int i; + FT_Fixed x, y, xtemp, b; + const FT_Fixed *arctanptr; + + + x = vec->x; + y = vec->y; + + /* Rotate inside [-PI/4,PI/4] sector */ + while ( theta < -FT_ANGLE_PI4 ) + { + xtemp = y; + y = -x; + x = xtemp; + theta += FT_ANGLE_PI2; + } + + while ( theta > FT_ANGLE_PI4 ) + { + xtemp = -y; + y = x; + x = xtemp; + theta -= FT_ANGLE_PI2; + } + + arctanptr = ft_trig_arctan_table; + + /* Pseudorotations, with right shifts */ + for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ ) + { + if ( theta < 0 ) + { + xtemp = x + ( ( y + b ) >> i ); + y = y - ( ( x + b ) >> i ); + x = xtemp; + theta += *arctanptr++; + } + else + { + xtemp = x - ( ( y + b ) >> i ); + y = y + ( ( x + b ) >> i ); + x = xtemp; + theta -= *arctanptr++; + } + } + + vec->x = x; + vec->y = y; + } + + + static void + ft_trig_pseudo_polarize( FT_Vector* vec ) + { + FT_Angle theta; + FT_Int i; + FT_Fixed x, y, xtemp, b; + const FT_Fixed *arctanptr; + + + x = vec->x; + y = vec->y; + + /* Get the vector into [-PI/4,PI/4] sector */ + if ( y > x ) + { + if ( y > -x ) + { + theta = FT_ANGLE_PI2; + xtemp = y; + y = -x; + x = xtemp; + } + else + { + theta = y > 0 ? FT_ANGLE_PI : -FT_ANGLE_PI; + x = -x; + y = -y; + } + } + else + { + if ( y < -x ) + { + theta = -FT_ANGLE_PI2; + xtemp = -y; + y = x; + x = xtemp; + } + else + { + theta = 0; + } + } + + arctanptr = ft_trig_arctan_table; + + /* Pseudorotations, with right shifts */ + for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ ) + { + if ( y > 0 ) + { + xtemp = x + ( ( y + b ) >> i ); + y = y - ( ( x + b ) >> i ); + x = xtemp; + theta += *arctanptr++; + } + else + { + xtemp = x - ( ( y + b ) >> i ); + y = y + ( ( x + b ) >> i ); + x = xtemp; + theta -= *arctanptr++; + } + } + + /* round theta */ + if ( theta >= 0 ) + theta = FT_PAD_ROUND( theta, 32 ); + else + theta = -FT_PAD_ROUND( -theta, 32 ); + + vec->x = x; + vec->y = theta; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Cos( FT_Angle angle ) + { + FT_Vector v; + + + v.x = FT_TRIG_SCALE >> 8; + v.y = 0; + ft_trig_pseudo_rotate( &v, angle ); + + return ( v.x + 0x80L ) >> 8; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Sin( FT_Angle angle ) + { + return FT_Cos( FT_ANGLE_PI2 - angle ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Tan( FT_Angle angle ) + { + FT_Vector v; + + + v.x = FT_TRIG_SCALE >> 8; + v.y = 0; + ft_trig_pseudo_rotate( &v, angle ); + + return FT_DivFix( v.y, v.x ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Angle ) + FT_Atan2( FT_Fixed dx, + FT_Fixed dy ) + { + FT_Vector v; + + + if ( dx == 0 && dy == 0 ) + return 0; + + v.x = dx; + v.y = dy; + ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + return v.y; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ) + { + vec->x = FT_TRIG_SCALE >> 8; + vec->y = 0; + ft_trig_pseudo_rotate( vec, angle ); + vec->x = ( vec->x + 0x80L ) >> 8; + vec->y = ( vec->y + 0x80L ) >> 8; + } + + + /* these macros return 0 for positive numbers, + and -1 for negative ones */ +#define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) ) +#define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) ) +#define FT_SIGN_INT32( x ) ( (x) >> 31 ) +#define FT_SIGN_INT16( x ) ( (x) >> 15 ) + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ) + { + FT_Int shift; + FT_Vector v; + + + v.x = vec->x; + v.y = vec->y; + + if ( angle && ( v.x != 0 || v.y != 0 ) ) + { + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_rotate( &v, angle ); + v.x = ft_trig_downscale( v.x ); + v.y = ft_trig_downscale( v.y ); + + if ( shift > 0 ) + { + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); + + + vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; + vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; + } + else + { + shift = -shift; + vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); + vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); + } + } + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ) + { + FT_Int shift; + FT_Vector v; + + + v = *vec; + + /* handle trivial cases */ + if ( v.x == 0 ) + { + return FT_ABS( v.y ); + } + else if ( v.y == 0 ) + { + return FT_ABS( v.x ); + } + + /* general case */ + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + v.x = ft_trig_downscale( v.x ); + + if ( shift > 0 ) + return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift; + + return (FT_Fixed)( (FT_UInt32)v.x << -shift ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ) + { + FT_Int shift; + FT_Vector v; + + + v = *vec; + + if ( v.x == 0 && v.y == 0 ) + return; + + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + v.x = ft_trig_downscale( v.x ); + + *length = ( shift >= 0 ) ? ( v.x >> shift ) + : (FT_Fixed)( (FT_UInt32)v.x << -shift ); + *angle = v.y; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ) + { + vec->x = length; + vec->y = 0; + + FT_Vector_Rotate( vec, angle ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ) + { + FT_Angle delta = angle2 - angle1; + + + delta %= FT_ANGLE_2PI; + if ( delta < 0 ) + delta += FT_ANGLE_2PI; + + if ( delta > FT_ANGLE_PI ) + delta -= FT_ANGLE_2PI; + + return delta; + } + + +/* END */ diff --git a/drivers/freetype/src/base/fttype1.c b/drivers/freetype/src/base/fttype1.c new file mode 100644 index 0000000000..c1f9931dbb --- /dev/null +++ b/drivers/freetype/src/base/fttype1.c @@ -0,0 +1,120 @@ +/***************************************************************************/ +/* */ +/* fttype1.c */ +/* */ +/* FreeType utility file for PS names support (body). */ +/* */ +/* Copyright 2002-2004, 2011 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + + + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_info ) + error = service->ps_get_font_info( face, afont_info ); + } + + return error; + } + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ) + { + FT_Int result = 0; + FT_Service_PsInfo service = NULL; + + + if ( face ) + { + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_has_glyph_names ) + result = service->ps_has_glyph_names( face ); + } + + return result; + } + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PS_Font_Private( FT_Face face, + PS_PrivateRec* afont_private ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + + + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_private ) + error = service->ps_get_font_private( face, afont_private ); + } + + return error; + } + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_Get_PS_Font_Value( FT_Face face, + PS_Dict_Keys key, + FT_UInt idx, + void *value, + FT_Long value_len ) + { + FT_Int result = 0; + FT_Service_PsInfo service = NULL; + + + if ( face ) + { + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_value ) + result = service->ps_get_font_value( face, key, idx, + value, value_len ); + } + + return result; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftutil.c b/drivers/freetype/src/base/ftutil.c new file mode 100644 index 0000000000..879d027529 --- /dev/null +++ b/drivers/freetype/src/base/ftutil.c @@ -0,0 +1,436 @@ +/***************************************************************************/ +/* */ +/* ftutil.c */ +/* */ +/* FreeType utility file for memory and list management (body). */ +/* */ +/* Copyright 2002, 2004-2007, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H +#include FT_LIST_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_memory + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** M E M O R Y M A N A G E M E N T *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_alloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ) + { + FT_Error error; + FT_Pointer block = ft_mem_qalloc( memory, size, &error ); + + if ( !error && size > 0 ) + FT_MEM_ZERO( block, size ); + + *p_error = error; + return block; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_qalloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ) + { + FT_Error error = FT_Err_Ok; + FT_Pointer block = NULL; + + + if ( size > 0 ) + { + block = memory->alloc( memory, size ); + if ( block == NULL ) + error = FT_THROW( Out_Of_Memory ); + } + else if ( size < 0 ) + { + /* may help catch/prevent security issues */ + error = FT_THROW( Invalid_Argument ); + } + + *p_error = error; + return block; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_realloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ) + { + FT_Error error = FT_Err_Ok; + + + block = ft_mem_qrealloc( memory, item_size, + cur_count, new_count, block, &error ); + if ( !error && new_count > cur_count ) + FT_MEM_ZERO( (char*)block + cur_count * item_size, + ( new_count - cur_count ) * item_size ); + + *p_error = error; + return block; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_qrealloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ) + { + FT_Error error = FT_Err_Ok; + + + /* 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_THROW( Invalid_Argument ); + } + else if ( new_count == 0 || item_size == 0 ) + { + ft_mem_free( memory, block ); + block = NULL; + } + else if ( new_count > FT_INT_MAX/item_size ) + { + error = FT_THROW( Array_Too_Large ); + } + else if ( cur_count == 0 ) + { + FT_ASSERT( block == NULL ); + + block = ft_mem_alloc( memory, new_count*item_size, &error ); + } + else + { + FT_Pointer block2; + FT_Long cur_size = cur_count*item_size; + FT_Long new_size = new_count*item_size; + + + block2 = memory->realloc( memory, cur_size, new_size, block ); + if ( block2 == NULL ) + error = FT_THROW( Out_Of_Memory ); + else + block = block2; + } + + *p_error = error; + return block; + } + + + FT_BASE_DEF( void ) + ft_mem_free( FT_Memory memory, + const void *P ) + { + if ( P ) + memory->free( memory, (void*)P ); + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_dup( FT_Memory memory, + const void* address, + FT_ULong size, + FT_Error *p_error ) + { + FT_Error error; + FT_Pointer p = ft_mem_qalloc( memory, size, &error ); + + + if ( !error && address ) + ft_memcpy( p, address, size ); + + *p_error = error; + return p; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_strdup( FT_Memory memory, + const char* str, + FT_Error *p_error ) + { + FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1 + : 0; + + + return ft_mem_dup( memory, str, len, p_error ); + } + + + FT_BASE_DEF( FT_Int ) + ft_mem_strcpyn( char* dst, + const char* src, + FT_ULong size ) + { + while ( size > 1 && *src != 0 ) + { + *dst++ = *src++; + size--; + } + + *dst = 0; /* always zero-terminate */ + + return *src != 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** D O U B L Y L I N K E D L I S T S *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + +#undef FT_COMPONENT +#define FT_COMPONENT trace_list + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ) + { + FT_ListNode cur; + + + cur = list->head; + while ( cur ) + { + if ( cur->data == data ) + return cur; + + cur = cur->next; + } + + return (FT_ListNode)0; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Add( FT_List list, + FT_ListNode node ) + { + FT_ListNode before = list->tail; + + + node->next = 0; + node->prev = before; + + if ( before ) + before->next = node; + else + list->head = node; + + list->tail = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ) + { + FT_ListNode after = list->head; + + + node->next = after; + node->prev = 0; + + if ( !after ) + list->tail = node; + else + after->prev = node; + + list->head = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ) + { + FT_ListNode before, after; + + + before = node->prev; + after = node->next; + + if ( before ) + before->next = after; + else + list->head = after; + + if ( after ) + after->prev = before; + else + list->tail = before; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Up( FT_List list, + FT_ListNode node ) + { + FT_ListNode before, after; + + + before = node->prev; + after = node->next; + + /* check whether we are already on top of the list */ + if ( !before ) + return; + + before->next = after; + + if ( after ) + after->prev = before; + else + list->tail = before; + + node->prev = 0; + node->next = list->head; + list->head->prev = node; + list->head = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ) + { + FT_ListNode cur = list->head; + FT_Error error = FT_Err_Ok; + + + while ( cur ) + { + FT_ListNode next = cur->next; + + + error = iterator( cur, user ); + if ( error ) + break; + + cur = next; + } + + return error; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ) + { + FT_ListNode cur; + + + cur = list->head; + while ( cur ) + { + FT_ListNode next = cur->next; + void* data = cur->data; + + + if ( destroy ) + destroy( memory, data, user ); + + FT_FREE( cur ); + cur = next; + } + + list->head = 0; + list->tail = 0; + } + + + FT_BASE_DEF( FT_UInt32 ) + ft_highpow2( FT_UInt32 value ) + { + FT_UInt32 value2; + + + /* + * We simply clear the lowest bit in each iteration. When + * we reach 0, we know that the previous value was our result. + */ + for ( ;; ) + { + value2 = value & (value - 1); /* clear lowest bit */ + if ( value2 == 0 ) + break; + + value = value2; + } + return value; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftwinfnt.c b/drivers/freetype/src/base/ftwinfnt.c new file mode 100644 index 0000000000..463ae761d8 --- /dev/null +++ b/drivers/freetype/src/base/ftwinfnt.c @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.c */ +/* */ +/* FreeType API for accessing Windows FNT specific info (body). */ +/* */ +/* Copyright 2003, 2004 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_WINFONTS_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_WINFNT_H + + + /* documentation is in ftwinfnt.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *header ) + { + FT_Service_WinFnt service; + FT_Error error; + + + error = FT_ERR( Invalid_Argument ); + + if ( face != NULL ) + { + FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); + + if ( service != NULL ) + { + error = service->get_header( face, header ); + } + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftxf86.c b/drivers/freetype/src/base/ftxf86.c new file mode 100644 index 0000000000..a4bf767dfa --- /dev/null +++ b/drivers/freetype/src/base/ftxf86.c @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* ftxf86.c */ +/* */ +/* FreeType utility file for X11 support (body). */ +/* */ +/* Copyright 2002, 2003, 2004 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_XFREE86_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_XFREE86_NAME_H + + + /* documentation is in ftxf86.h */ + + FT_EXPORT_DEF( const char* ) + FT_Get_X11_Font_Format( FT_Face face ) + { + const char* result = NULL; + + + if ( face ) + FT_FACE_FIND_SERVICE( face, result, XF86_NAME ); + + return result; + } + + +/* END */ diff --git a/drivers/freetype/src/base/md5.c b/drivers/freetype/src/base/md5.c new file mode 100644 index 0000000000..2f01c9302c --- /dev/null +++ b/drivers/freetype/src/base/md5.c @@ -0,0 +1,295 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * (This is a heavily cut-down "BSD license".) + * + * This differs from Colin Plumb's older public domain implementation in that + * no exactly 32-bit integer data type is required (any 32-bit or wider + * unsigned integer data type will do), there's no compile-time endianness + * configuration, and the function prototypes match OpenSSL's. No code from + * Colin Plumb's implementation has been reused; this comment merely compares + * the properties of the two independent implementations. + * + * The primary goals of this implementation are portability and ease of use. + * It is meant to be fast, but not as fast as possible. Some known + * optimizations are not included to reduce source code size and avoid + * compile-time configuration. + */ + +#ifndef HAVE_OPENSSL + +#include <string.h> + +#include "md5.h" + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD5_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +#define SET(n) \ + (ctx->block[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. + */ +static void *body(MD5_CTX *ctx, void *data, unsigned long size) +{ + unsigned char *ptr; + MD5_u32plus a, b, c, d; + MD5_u32plus saved_a, saved_b, saved_c, saved_d; + + ptr = (unsigned char *)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) + +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +void MD5_Init(MD5_CTX *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; +} + +void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) +{ + MD5_u32plus saved_lo; + unsigned long used, free; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (unsigned char *)data + free; + size -= free; + body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +void MD5_Final(unsigned char *result, MD5_CTX *ctx) +{ + unsigned long used, free; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + memset(&ctx->buffer[used], 0, free); + body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + memset(&ctx->buffer[used], 0, free - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = ctx->lo; + ctx->buffer[57] = ctx->lo >> 8; + ctx->buffer[58] = ctx->lo >> 16; + ctx->buffer[59] = ctx->lo >> 24; + ctx->buffer[60] = ctx->hi; + ctx->buffer[61] = ctx->hi >> 8; + ctx->buffer[62] = ctx->hi >> 16; + ctx->buffer[63] = ctx->hi >> 24; + + body(ctx, ctx->buffer, 64); + + result[0] = ctx->a; + result[1] = ctx->a >> 8; + result[2] = ctx->a >> 16; + result[3] = ctx->a >> 24; + result[4] = ctx->b; + result[5] = ctx->b >> 8; + result[6] = ctx->b >> 16; + result[7] = ctx->b >> 24; + result[8] = ctx->c; + result[9] = ctx->c >> 8; + result[10] = ctx->c >> 16; + result[11] = ctx->c >> 24; + result[12] = ctx->d; + result[13] = ctx->d >> 8; + result[14] = ctx->d >> 16; + result[15] = ctx->d >> 24; + + memset(ctx, 0, sizeof(*ctx)); +} + +#endif diff --git a/drivers/freetype/src/base/md5.h b/drivers/freetype/src/base/md5.h new file mode 100644 index 0000000000..f1a6857640 --- /dev/null +++ b/drivers/freetype/src/base/md5.h @@ -0,0 +1,45 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See md5.c for more information. + */ + +#ifdef HAVE_OPENSSL +#include <openssl/md5.h> +#elif !defined(_MD5_H) +#define _MD5_H + +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD5_u32plus; + +typedef struct { + MD5_u32plus lo, hi; + MD5_u32plus a, b, c, d; + unsigned char buffer[64]; + MD5_u32plus block[16]; +} MD5_CTX; + +extern void MD5_Init(MD5_CTX *ctx); +extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size); +extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); + +#endif diff --git a/drivers/freetype/src/base/rules.mk b/drivers/freetype/src/base/rules.mk new file mode 100644 index 0000000000..e932191157 --- /dev/null +++ b/drivers/freetype/src/base/rules.mk @@ -0,0 +1,99 @@ +# +# FreeType 2 base layer configuration rules +# + + +# Copyright 1996-2000, 2002-2009, 2013 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. + + +# It sets the following variables which are used by the master Makefile +# after the call: +# +# BASE_OBJ_S: The single-object base layer. +# BASE_OBJ_M: A list of all objects for a multiple-objects build. +# BASE_EXT_OBJ: A list of base layer extensions, i.e., components found +# in `freetype/src/base' which are not compiled within the +# base layer proper. + + +BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) + + +# Base layer sources +# +# ftsystem, ftinit, and ftdebug are handled by freetype.mk +# +# All files listed here should be included in `ftbase.c' (for a `single' +# build). +# +BASE_SRC := $(BASE_DIR)/ftadvanc.c \ + $(BASE_DIR)/ftcalc.c \ + $(BASE_DIR)/ftdbgmem.c \ + $(BASE_DIR)/ftgloadr.c \ + $(BASE_DIR)/ftobjs.c \ + $(BASE_DIR)/ftoutln.c \ + $(BASE_DIR)/ftrfork.c \ + $(BASE_DIR)/ftsnames.c \ + $(BASE_DIR)/ftstream.c \ + $(BASE_DIR)/fttrigon.c \ + $(BASE_DIR)/ftutil.c + + +ifneq ($(ftmac_c),) + BASE_SRC += $(BASE_DIR)/$(ftmac_c) +endif + +# for simplicity, we also handle `md5.c' (which gets included by `ftobjs.h') +BASE_H := $(BASE_DIR)/ftbase.h \ + $(BASE_DIR)/md5.c \ + $(BASE_DIR)/md5.h + +# Base layer `extensions' sources +# +# An extension is added to the library file as a separate object. It is +# then linked to the final executable only if one of its symbols is used by +# the application. +# +BASE_EXT_SRC := $(patsubst %,$(BASE_DIR)/%,$(BASE_EXTENSIONS)) + +# Default extensions objects +# +BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_DIR)/%.c=$(OBJ_DIR)/%.$O) + + +# Base layer object(s) +# +# BASE_OBJ_M is used during `multi' builds (each base source file compiles +# to a single object file). +# +# BASE_OBJ_S is used during `single' builds (the whole base layer is +# compiled as a single object file using ftbase.c). +# +BASE_OBJ_M := $(BASE_SRC:$(BASE_DIR)/%.c=$(OBJ_DIR)/%.$O) +BASE_OBJ_S := $(OBJ_DIR)/ftbase.$O + +# Base layer root source file for single build +# +BASE_SRC_S := $(BASE_DIR)/ftbase.c + + +# Base layer - single object build +# +$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) $(BASE_H) + $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BASE_SRC_S)) + + +# Multiple objects build + extensions +# +$(OBJ_DIR)/%.$O: $(BASE_DIR)/%.c $(FREETYPE_H) $(BASE_H) + $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# EOF diff --git a/drivers/freetype/src/bdf/Jamfile b/drivers/freetype/src/bdf/Jamfile new file mode 100644 index 0000000000..da23ccd0ad --- /dev/null +++ b/drivers/freetype/src/bdf/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/bdf Jamfile +# +# Copyright 2002 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) bdf ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = bdfdrivr bdflib ; + } + else + { + _sources = bdf ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/bdf Jamfile diff --git a/drivers/freetype/src/bdf/README b/drivers/freetype/src/bdf/README new file mode 100644 index 0000000000..b761aba2b2 --- /dev/null +++ b/drivers/freetype/src/bdf/README @@ -0,0 +1,148 @@ + FreeType font driver for BDF fonts + + Francesco Zappa Nardelli + <francesco.zappa.nardelli@ens.fr> + + +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. +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/public/developer/en/font/5005.BDF_Spec.pdf + +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. + + +Encodings +********* + +The variety of encodings that accompanies bdf fonts appears to encompass the +small set defined in freetype.h. On the other hand, two properties that +specify encoding and registry are usually defined in bdf fonts. + +I decided to make these two properties directly accessible, leaving to the +client application the work of interpreting them. For instance: + + + #include FT_INTERNAL_BDF_TYPES_H + + FT_Face face; + BDF_Public_Face bdfface; + + + FT_New_Face( library, ..., &face ); + + bdfface = (BDF_Public_Face)face; + + if ( ( bdfface->charset_registry == "ISO10646" ) && + ( bdfface->charset_encoding == "1" ) ) + [..] + + +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. + +If the two properties are not available, Adobe Standard Encoding should be +assumed. + + +Anti-Aliased Bitmaps +******************** + +The driver supports an extension to the BDF format as used in Mark Leisher's +xmbdfed bitmap font editor. Microsoft's SBIT tool expects bitmap fonts in +that format for adding anti-aliased them to TrueType fonts. It introduces a +fourth field to the `SIZE' keyword which gives the bpp value (bits per +pixel) of the glyph data in the font. Possible values are 1 (the default), +2 (four gray levels), 4 (16 gray levels), and 8 (256 gray levels). The +driver returns either a bitmap with 1 bit per pixel or a pixmap with 8bits +per pixel (using 4, 16, and 256 gray levels, respectively). + + +Known problems +************** + +- A font is entirely loaded into memory. Obviously, this is not the Right + Thing(TM). If you have big fonts I suggest you convert them into PCF + format (using the bdftopcf utility): the PCF font drive of FreeType can + perform incremental glyph loading. + +When I have some time, I will implement on-demand glyph parsing. + +- Except for encodings properties, client applications have no visibility of + the PCF_Face object. This means that applications cannot directly access + font tables and must trust FreeType. + +- Currently, glyph names are ignored. + + I plan to give full visibility of the BDF_Face object in an upcoming + revision of the driver, thus implementing also glyph names. + +- As I have never seen a BDF font that defines vertical metrics, vertical + metrics are (parsed and) discarded. If you own a BDF font that defines + vertical metrics, please let me know (I will implement them in 5-10 + minutes). + + +License +******* + +Copyright (C) 2001-2002 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 to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*** Portions of the driver (that is, bdflib.c and bdf.h): + +Copyright 2000 Computing Research Labs, New Mexico State University +Copyright 2001-2002, 2011 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 to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Credits +******* + +This driver is based on excellent Mark Leisher's bdf library. If you +find something good in this driver you should probably thank him, not +me. diff --git a/drivers/freetype/src/bdf/bdf.c b/drivers/freetype/src/bdf/bdf.c new file mode 100644 index 0000000000..f95fb76225 --- /dev/null +++ b/drivers/freetype/src/bdf/bdf.c @@ -0,0 +1,34 @@ +/* bdf.c + + FreeType font driver for bdf files + + Copyright (C) 2001, 2002 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "bdflib.c" +#include "bdfdrivr.c" + + +/* END */ diff --git a/drivers/freetype/src/bdf/bdf.h b/drivers/freetype/src/bdf/bdf.h new file mode 100644 index 0000000000..d11be6f147 --- /dev/null +++ b/drivers/freetype/src/bdf/bdf.h @@ -0,0 +1,297 @@ +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2004, 2011 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 to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef __BDF_H__ +#define __BDF_H__ + + +/* + * Based on bdf.h,v 1.16 2000/03/16 20:08:51 mleisher + */ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + +/* Imported from bdfP.h */ + +#define _bdf_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] & ( 1 << ( (e) & 31 ) ) ) +#define _bdf_set_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] |= ( 1 << ( (e) & 31 ) ) ) +#define _bdf_clear_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] &= ~( 1 << ( (e) & 31 ) ) ) + +/* end of bdfP.h */ + + + /*************************************************************************/ + /* */ + /* BDF font options macros and types. */ + /* */ + /*************************************************************************/ + + +#define BDF_CORRECT_METRICS 0x01 /* Correct invalid metrics when loading. */ +#define BDF_KEEP_COMMENTS 0x02 /* Preserve the font comments. */ +#define BDF_KEEP_UNENCODED 0x04 /* Keep the unencoded glyphs. */ +#define BDF_PROPORTIONAL 0x08 /* Font has proportional spacing. */ +#define BDF_MONOWIDTH 0x10 /* Font has mono width. */ +#define BDF_CHARCELL 0x20 /* Font has charcell spacing. */ + +#define BDF_ALL_SPACING ( BDF_PROPORTIONAL | \ + BDF_MONOWIDTH | \ + BDF_CHARCELL ) + +#define BDF_DEFAULT_LOAD_OPTIONS ( BDF_CORRECT_METRICS | \ + BDF_KEEP_COMMENTS | \ + BDF_KEEP_UNENCODED | \ + BDF_PROPORTIONAL ) + + + typedef struct bdf_options_t_ + { + int correct_metrics; + int keep_unencoded; + int keep_comments; + int font_spacing; + + } bdf_options_t; + + + /* Callback function type for unknown configuration options. */ + typedef int + (*bdf_options_callback_t)( bdf_options_t* opts, + char** params, + unsigned long nparams, + void* client_data ); + + + /*************************************************************************/ + /* */ + /* BDF font property macros and types. */ + /* */ + /*************************************************************************/ + + +#define BDF_ATOM 1 +#define BDF_INTEGER 2 +#define BDF_CARDINAL 3 + + + /* This structure represents a particular property of a font. */ + /* There are a set of defaults and each font has their own. */ + typedef struct bdf_property_t_ + { + char* name; /* Name of the property. */ + int format; /* Format of the property. */ + int builtin; /* A builtin property. */ + union + { + char* atom; + long l; + unsigned long ul; + + } value; /* Value of the property. */ + + } bdf_property_t; + + + /*************************************************************************/ + /* */ + /* BDF font metric and glyph types. */ + /* */ + /*************************************************************************/ + + + typedef struct bdf_bbx_t_ + { + unsigned short width; + unsigned short height; + + short x_offset; + short y_offset; + + short ascent; + short descent; + + } bdf_bbx_t; + + + typedef struct bdf_glyph_t_ + { + char* name; /* Glyph name. */ + long encoding; /* Glyph encoding. */ + unsigned short swidth; /* Scalable width. */ + unsigned short dwidth; /* Device width. */ + bdf_bbx_t bbx; /* Glyph bounding box. */ + unsigned char* bitmap; /* Glyph bitmap. */ + unsigned long bpr; /* Number of bytes used per row. */ + unsigned short bytes; /* Number of bytes used for the bitmap. */ + + } bdf_glyph_t; + + + typedef struct _hashnode_ + { + const char* key; + size_t data; + + } _hashnode, *hashnode; + + + typedef struct hashtable_ + { + int limit; + int size; + int used; + hashnode* table; + + } hashtable; + + + typedef struct bdf_glyphlist_t_ + { + unsigned short pad; /* Pad to 4-byte boundary. */ + unsigned short bpp; /* Bits per pixel. */ + long start; /* Beginning encoding value of glyphs. */ + long end; /* Ending encoding value of glyphs. */ + bdf_glyph_t* glyphs; /* Glyphs themselves. */ + unsigned long glyphs_size; /* Glyph structures allocated. */ + unsigned long glyphs_used; /* Glyph structures used. */ + bdf_bbx_t bbx; /* Overall bounding box of glyphs. */ + + } bdf_glyphlist_t; + + + typedef struct bdf_font_t_ + { + char* name; /* Name of the font. */ + bdf_bbx_t bbx; /* Font bounding box. */ + + long point_size; /* Point size of the font. */ + unsigned long resolution_x; /* Font horizontal resolution. */ + unsigned long resolution_y; /* Font vertical resolution. */ + + int spacing; /* Font spacing value. */ + + unsigned short monowidth; /* Logical width for monowidth font. */ + + long default_char; /* Encoding of the default glyph. */ + + long font_ascent; /* Font ascent. */ + long font_descent; /* Font descent. */ + + unsigned long glyphs_size; /* Glyph structures allocated. */ + unsigned long glyphs_used; /* Glyph structures used. */ + bdf_glyph_t* glyphs; /* Glyphs themselves. */ + + unsigned long unencoded_size; /* Unencoded glyph struct. allocated. */ + unsigned long unencoded_used; /* Unencoded glyph struct. used. */ + bdf_glyph_t* unencoded; /* Unencoded glyphs themselves. */ + + unsigned long props_size; /* Font properties allocated. */ + unsigned long props_used; /* Font properties used. */ + bdf_property_t* props; /* Font properties themselves. */ + + char* comments; /* Font comments. */ + unsigned long comments_len; /* Length of comment string. */ + + bdf_glyphlist_t overflow; /* Storage used for glyph insertion. */ + + void* internal; /* Internal data for the font. */ + + /* The size of the next two arrays must be in sync with the */ + /* size of the `have' array in the `bdf_parse_t' structure. */ + unsigned long nmod[34816]; /* Bitmap indicating modified glyphs. */ + unsigned long umod[34816]; /* Bitmap indicating modified */ + /* unencoded glyphs. */ + unsigned short modified; /* Boolean indicating font modified. */ + unsigned short bpp; /* Bits per pixel. */ + + FT_Memory memory; + + bdf_property_t* user_props; + unsigned long nuser_props; + hashtable proptbl; + + } bdf_font_t; + + + /*************************************************************************/ + /* */ + /* Types for load/save callbacks. */ + /* */ + /*************************************************************************/ + + + /* Error codes. */ +#define BDF_MISSING_START -1 +#define BDF_MISSING_FONTNAME -2 +#define BDF_MISSING_SIZE -3 +#define BDF_MISSING_CHARS -4 +#define BDF_MISSING_STARTCHAR -5 +#define BDF_MISSING_ENCODING -6 +#define BDF_MISSING_BBX -7 + +#define BDF_OUT_OF_MEMORY -20 + +#define BDF_INVALID_LINE -100 + + + /*************************************************************************/ + /* */ + /* BDF font API. */ + /* */ + /*************************************************************************/ + + FT_LOCAL( FT_Error ) + bdf_load_font( FT_Stream stream, + FT_Memory memory, + bdf_options_t* opts, + bdf_font_t* *font ); + + FT_LOCAL( void ) + bdf_free_font( bdf_font_t* font ); + + FT_LOCAL( bdf_property_t * ) + bdf_get_property( char* name, + bdf_font_t* font ); + + FT_LOCAL( bdf_property_t * ) + bdf_get_font_property( bdf_font_t* font, + const char* name ); + + +FT_END_HEADER + + +#endif /* __BDF_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/bdf/bdfdrivr.c b/drivers/freetype/src/bdf/bdfdrivr.c new file mode 100644 index 0000000000..0ea0a5ea5e --- /dev/null +++ b/drivers/freetype/src/bdf/bdfdrivr.c @@ -0,0 +1,878 @@ +/* bdfdrivr.c + + FreeType font driver for bdf files + + Copyright (C) 2001-2008, 2011, 2013 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_BDF_H +#include FT_TRUETYPE_IDS_H + +#include FT_SERVICE_BDF_H +#include FT_SERVICE_XFREE86_NAME_H + +#include "bdf.h" +#include "bdfdrivr.h" + +#include "bdferror.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_bdfdriver + + + typedef struct BDF_CMapRec_ + { + FT_CMapRec cmap; + FT_ULong num_encodings; /* ftobjs.h: FT_CMap->clazz->size */ + BDF_encoding_el* encodings; + + } BDF_CMapRec, *BDF_CMap; + + + FT_CALLBACK_DEF( FT_Error ) + bdf_cmap_init( FT_CMap bdfcmap, + FT_Pointer init_data ) + { + BDF_CMap cmap = (BDF_CMap)bdfcmap; + BDF_Face face = (BDF_Face)FT_CMAP_FACE( cmap ); + FT_UNUSED( init_data ); + + + cmap->num_encodings = face->bdffont->glyphs_used; + cmap->encodings = face->en_table; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + bdf_cmap_done( FT_CMap bdfcmap ) + { + BDF_CMap cmap = (BDF_CMap)bdfcmap; + + + cmap->encodings = NULL; + cmap->num_encodings = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + bdf_cmap_char_index( FT_CMap bdfcmap, + FT_UInt32 charcode ) + { + BDF_CMap cmap = (BDF_CMap)bdfcmap; + BDF_encoding_el* encodings = cmap->encodings; + FT_ULong min, max, mid; /* num_encodings */ + FT_UShort result = 0; /* encodings->glyph */ + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_ULong code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + /* increase glyph index by 1 -- */ + /* we reserve slot 0 for the undefined glyph */ + result = encodings[mid].glyph + 1; + break; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + bdf_cmap_char_next( FT_CMap bdfcmap, + FT_UInt32 *acharcode ) + { + BDF_CMap cmap = (BDF_CMap)bdfcmap; + BDF_encoding_el* encodings = cmap->encodings; + FT_ULong min, max, mid; /* num_encodings */ + FT_UShort result = 0; /* encodings->glyph */ + FT_ULong charcode = *acharcode + 1; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_ULong code; /* same as BDF_encoding_el.enc */ + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + /* increase glyph index by 1 -- */ + /* we reserve slot 0 for the undefined glyph */ + result = encodings[mid].glyph + 1; + goto Exit; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + charcode = 0; + if ( min < cmap->num_encodings ) + { + charcode = encodings[min].enc; + result = encodings[min].glyph + 1; + } + + Exit: + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" )); + *acharcode = 0; + /* XXX: result should be changed to indicate an overflow error */ + } + else + *acharcode = (FT_UInt32)charcode; + return result; + } + + + FT_CALLBACK_TABLE_DEF + const FT_CMap_ClassRec bdf_cmap_class = + { + sizeof ( BDF_CMapRec ), + bdf_cmap_init, + bdf_cmap_done, + bdf_cmap_char_index, + bdf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + static FT_Error + bdf_interpret_style( BDF_Face bdf ) + { + FT_Error error = FT_Err_Ok; + FT_Face face = FT_FACE( bdf ); + FT_Memory memory = face->memory; + bdf_font_t* font = bdf->bdffont; + bdf_property_t* prop; + + char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t nn, len, lengths[4]; + + + face->style_flags = 0; + + prop = bdf_get_font_property( font, (char *)"SLANT" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || + *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) + { + face->style_flags |= FT_STYLE_FLAG_ITALIC; + strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) + ? (char *)"Oblique" + : (char *)"Italic"; + } + + prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) + { + face->style_flags |= FT_STYLE_FLAG_BOLD; + strings[1] = (char *)"Bold"; + } + + prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + strings[3] = (char *)(prop->value.atom); + + prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + strings[0] = (char *)(prop->value.atom); + + len = 0; + + for ( len = 0, nn = 0; nn < 4; nn++ ) + { + lengths[nn] = 0; + if ( strings[nn] ) + { + lengths[nn] = ft_strlen( strings[nn] ); + len += lengths[nn] + 1; + } + } + + if ( len == 0 ) + { + strings[0] = (char *)"Regular"; + lengths[0] = ft_strlen( strings[0] ); + len = lengths[0] + 1; + } + + { + char* s; + + + if ( FT_ALLOC( face->style_name, len ) ) + return error; + + s = face->style_name; + + for ( nn = 0; nn < 4; nn++ ) + { + char* src = strings[nn]; + + + len = lengths[nn]; + + if ( src == NULL ) + continue; + + /* separate elements with a space */ + if ( s != face->style_name ) + *s++ = ' '; + + ft_memcpy( s, src, len ); + + /* need to convert spaces to dashes for */ + /* add_style_name and setwidth_name */ + if ( nn == 0 || nn == 3 ) + { + size_t mm; + + + for ( mm = 0; mm < len; mm++ ) + if ( s[mm] == ' ' ) + s[mm] = '-'; + } + + s += len; + } + *s = 0; + } + + return error; + } + + + FT_CALLBACK_DEF( void ) + BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */ + { + BDF_Face face = (BDF_Face)bdfface; + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + bdf_free_font( face->bdffont ); + + FT_FREE( face->en_table ); + + FT_FREE( face->charset_encoding ); + FT_FREE( face->charset_registry ); + FT_FREE( bdfface->family_name ); + FT_FREE( bdfface->style_name ); + + FT_FREE( bdfface->available_sizes ); + + FT_FREE( face->bdffont ); + } + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Face_Init( FT_Stream stream, + FT_Face bdfface, /* BDF_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error = FT_Err_Ok; + BDF_Face face = (BDF_Face)bdfface; + FT_Memory memory = FT_FACE_MEMORY( face ); + + bdf_font_t* font = NULL; + bdf_options_t options; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + + + FT_TRACE2(( "BDF driver\n" )); + + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + options.correct_metrics = 1; /* FZ XXX: options semantics */ + options.keep_unencoded = 1; + options.keep_comments = 0; + options.font_spacing = BDF_PROPORTIONAL; + + error = bdf_load_font( stream, memory, &options, &font ); + if ( FT_ERR_EQ( error, Missing_Startfont_Field ) ) + { + FT_TRACE2(( " not a BDF file\n" )); + goto Fail; + } + else if ( error ) + goto Exit; + + /* we have a bdf font: let's construct the face object */ + face->bdffont = font; + { + bdf_property_t* prop = NULL; + + + FT_TRACE4(( " number of glyphs: allocated %d (used %d)\n", + font->glyphs_size, + font->glyphs_used )); + FT_TRACE4(( " number of unencoded glyphs: allocated %d (used %d)\n", + font->unencoded_size, + font->unencoded_used )); + + bdfface->num_faces = 1; + bdfface->face_index = 0; + bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; + + prop = bdf_get_font_property( font, "SPACING" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' || + *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) ) + bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ + /* FZ XXX: I need a font to implement this */ + + prop = bdf_get_font_property( font, "FAMILY_NAME" ); + if ( prop && prop->value.atom ) + { + if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) ) + goto Exit; + } + else + bdfface->family_name = 0; + + if ( ( error = bdf_interpret_style( face ) ) != 0 ) + goto Exit; + + /* the number of glyphs (with one slot for the undefined glyph */ + /* at position 0 and all unencoded glyphs) */ + bdfface->num_glyphs = font->glyphs_size + 1; + + bdfface->num_fixed_sizes = 1; + if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) ) + goto Exit; + + { + FT_Bitmap_Size* bsize = bdfface->available_sizes; + FT_Short resolution_x = 0, resolution_y = 0; + + + FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + + bsize->height = (FT_Short)( font->font_ascent + font->font_descent ); + + prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); + if ( prop ) + bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); + else + bsize->width = (FT_Short)( bsize->height * 2/3 ); + + prop = bdf_get_font_property( font, "POINT_SIZE" ); + if ( prop ) + /* convert from 722.7 decipoints to 72 points per inch */ + bsize->size = + (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); + else + bsize->size = bsize->width << 6; + + prop = bdf_get_font_property( font, "PIXEL_SIZE" ); + if ( prop ) + bsize->y_ppem = (FT_Short)prop->value.l << 6; + + prop = bdf_get_font_property( font, "RESOLUTION_X" ); + if ( prop ) + resolution_x = (FT_Short)prop->value.l; + + prop = bdf_get_font_property( font, "RESOLUTION_Y" ); + if ( prop ) + resolution_y = (FT_Short)prop->value.l; + + if ( bsize->y_ppem == 0 ) + { + bsize->y_ppem = bsize->size; + if ( resolution_y ) + bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + } + if ( resolution_x && resolution_y ) + bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + else + bsize->x_ppem = bsize->y_ppem; + } + + /* encoding table */ + { + bdf_glyph_t* cur = font->glyphs; + unsigned long n; + + + if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) ) + goto Exit; + + face->default_glyph = 0; + for ( n = 0; n < font->glyphs_size; n++ ) + { + (face->en_table[n]).enc = cur[n].encoding; + FT_TRACE4(( " idx %d, val 0x%lX\n", n, cur[n].encoding )); + (face->en_table[n]).glyph = (FT_Short)n; + + if ( cur[n].encoding == font->default_char ) + { + if ( n < FT_UINT_MAX ) + face->default_glyph = (FT_UInt)n; + else + FT_TRACE1(( "BDF_Face_Init:" + " idx %d is too large for this system\n", n )); + } + } + } + + /* charmaps */ + { + bdf_property_t *charset_registry = 0, *charset_encoding = 0; + FT_Bool unicode_charmap = 0; + + + charset_registry = + bdf_get_font_property( font, "CHARSET_REGISTRY" ); + charset_encoding = + bdf_get_font_property( font, "CHARSET_ENCODING" ); + if ( charset_registry && charset_encoding ) + { + if ( charset_registry->format == BDF_ATOM && + charset_encoding->format == BDF_ATOM && + charset_registry->value.atom && + charset_encoding->value.atom ) + { + const char* s; + + + if ( FT_STRDUP( face->charset_encoding, + charset_encoding->value.atom ) || + FT_STRDUP( face->charset_registry, + charset_registry->value.atom ) ) + goto Exit; + + /* Uh, oh, compare first letters manually to avoid dependency */ + /* on locales. */ + s = face->charset_registry; + if ( ( s[0] == 'i' || s[0] == 'I' ) && + ( s[1] == 's' || s[1] == 'S' ) && + ( s[2] == 'o' || s[2] == 'O' ) ) + { + s += 3; + if ( !ft_strcmp( s, "10646" ) || + ( !ft_strcmp( s, "8859" ) && + !ft_strcmp( face->charset_encoding, "1" ) ) ) + unicode_charmap = 1; + } + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; + /* initial platform/encoding should indicate unset status? */ + charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; + charmap.encoding_id = TT_APPLE_ID_DEFAULT; + + if ( unicode_charmap ) + { + charmap.encoding = FT_ENCODING_UNICODE; + charmap.platform_id = TT_PLATFORM_MICROSOFT; + charmap.encoding_id = TT_MS_ID_UNICODE_CS; + } + + error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if ( bdfface->num_charmaps ) + bdfface->charmap = bdfface->charmaps[0]; +#endif + } + + goto Exit; + } + } + + /* otherwise assume Adobe standard encoding */ + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.platform_id = TT_PLATFORM_ADOBE; + charmap.encoding_id = TT_ADOBE_ID_STANDARD; + + error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); + + /* Select default charmap */ + if ( bdfface->num_charmaps ) + bdfface->charmap = bdfface->charmaps[0]; + } + } + } + + Exit: + return error; + + Fail: + BDF_Face_Done( bdfface ); + return FT_THROW( Unknown_File_Format ); + } + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Size_Select( FT_Size size, + FT_ULong strike_index ) + { + bdf_font_t* bdffont = ( (BDF_Face)size->face )->bdffont; + + + FT_Select_Metrics( size->face, strike_index ); + + size->metrics.ascender = bdffont->font_ascent << 6; + size->metrics.descender = -bdffont->font_descent << 6; + size->metrics.max_advance = bdffont->bbx.width << 6; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Size_Request( FT_Size size, + FT_Size_Request req ) + { + FT_Face face = size->face; + FT_Bitmap_Size* bsize = face->available_sizes; + bdf_font_t* bdffont = ( (BDF_Face)face )->bdffont; + FT_Error error = FT_ERR( Invalid_Pixel_Size ); + FT_Long height; + + + height = FT_REQUEST_HEIGHT( req ); + height = ( height + 32 ) >> 6; + + switch ( req->type ) + { + case FT_SIZE_REQUEST_TYPE_NOMINAL: + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) + error = FT_Err_Ok; + break; + + case FT_SIZE_REQUEST_TYPE_REAL_DIM: + if ( height == ( bdffont->font_ascent + + bdffont->font_descent ) ) + error = FT_Err_Ok; + break; + + default: + error = FT_THROW( Unimplemented_Feature ); + break; + } + + if ( error ) + return error; + else + return BDF_Size_Select( size, 0 ); + } + + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Glyph_Load( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size ); + FT_Face face = FT_FACE( bdf ); + FT_Error error = FT_Err_Ok; + FT_Bitmap* bitmap = &slot->bitmap; + bdf_glyph_t glyph; + int bpp = bdf->bdffont->bpp; + + FT_UNUSED( load_flags ); + + + if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* index 0 is the undefined glyph */ + if ( glyph_index == 0 ) + glyph_index = bdf->default_glyph; + else + glyph_index--; + + /* slot, bitmap => freetype, glyph => bdflib */ + glyph = bdf->bdffont->glyphs[glyph_index]; + + bitmap->rows = glyph.bbx.height; + bitmap->width = glyph.bbx.width; + if ( glyph.bpr > INT_MAX ) + FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n", + glyph.bpr )); + bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */ + + /* note: we don't allocate a new array to hold the bitmap; */ + /* we can simply point to it */ + ft_glyphslot_set_bitmap( slot, glyph.bitmap ); + + switch ( bpp ) + { + case 1: + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + break; + case 2: + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2; + break; + case 4: + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4; + break; + case 8: + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + break; + } + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = glyph.bbx.x_offset; + slot->bitmap_top = glyph.bbx.ascent; + + slot->metrics.horiAdvance = glyph.dwidth << 6; + slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; + slot->metrics.horiBearingY = glyph.bbx.ascent << 6; + slot->metrics.width = bitmap->width << 6; + slot->metrics.height = bitmap->rows << 6; + + /* + * XXX DWIDTH1 and VVECTOR should be parsed and + * used here, provided such fonts do exist. + */ + ft_synthesize_vertical_metrics( &slot->metrics, + bdf->bdffont->bbx.height << 6 ); + + Exit: + return error; + } + + + /* + * + * BDF SERVICE + * + */ + + static FT_Error + bdf_get_bdf_property( BDF_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + bdf_property_t* prop; + + + FT_ASSERT( face && face->bdffont ); + + prop = bdf_get_font_property( face->bdffont, prop_name ); + if ( prop ) + { + switch ( prop->format ) + { + case BDF_ATOM: + aproperty->type = BDF_PROPERTY_TYPE_ATOM; + aproperty->u.atom = prop->value.atom; + break; + + case BDF_INTEGER: + if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + { + FT_TRACE1(( "bdf_get_bdf_property:" + " too large integer 0x%x is truncated\n" )); + } + aproperty->type = BDF_PROPERTY_TYPE_INTEGER; + aproperty->u.integer = (FT_Int32)prop->value.l; + break; + + case BDF_CARDINAL: + if ( prop->value.ul > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "bdf_get_bdf_property:" + " too large cardinal 0x%x is truncated\n" )); + } + aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; + aproperty->u.cardinal = (FT_UInt32)prop->value.ul; + break; + + default: + goto Fail; + } + return 0; + } + + Fail: + return FT_THROW( Invalid_Argument ); + } + + + static FT_Error + bdf_get_charset_id( BDF_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + *acharset_encoding = face->charset_encoding; + *acharset_registry = face->charset_registry; + + return 0; + } + + + static const FT_Service_BDFRec bdf_service_bdf = + { + (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, + (FT_BDF_GetPropertyFunc) bdf_get_bdf_property + }; + + + /* + * + * SERVICES LIST + * + */ + + static const FT_ServiceDescRec bdf_services[] = + { + { FT_SERVICE_ID_BDF, &bdf_service_bdf }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + bdf_driver_requester( FT_Module module, + const char* name ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( bdf_services, name ); + } + + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec bdf_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, + sizeof ( FT_DriverRec ), + + "bdf", + 0x10000L, + 0x20000L, + + 0, + + 0, /* FT_Module_Constructor */ + 0, /* FT_Module_Destructor */ + bdf_driver_requester + }, + + sizeof ( BDF_FaceRec ), + sizeof ( FT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + BDF_Face_Init, + BDF_Face_Done, + 0, /* FT_Size_InitFunc */ + 0, /* FT_Size_DoneFunc */ + 0, /* FT_Slot_InitFunc */ + 0, /* FT_Slot_DoneFunc */ + + BDF_Glyph_Load, + + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetAdvancesFunc */ + + BDF_Size_Request, + BDF_Size_Select + }; + + +/* END */ diff --git a/drivers/freetype/src/bdf/bdfdrivr.h b/drivers/freetype/src/bdf/bdfdrivr.h new file mode 100644 index 0000000000..ca0dae50d2 --- /dev/null +++ b/drivers/freetype/src/bdf/bdfdrivr.h @@ -0,0 +1,80 @@ +/* bdfdrivr.h + + FreeType font driver for bdf fonts + + Copyright (C) 2001, 2002, 2003, 2004 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __BDFDRIVR_H__ +#define __BDFDRIVR_H__ + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + +#include "bdf.h" + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + typedef struct BDF_encoding_el_ + { + FT_ULong enc; + FT_UShort glyph; + + } BDF_encoding_el; + + + typedef struct BDF_FaceRec_ + { + FT_FaceRec root; + + char* charset_encoding; + char* charset_registry; + + bdf_font_t* bdffont; + + BDF_encoding_el* en_table; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + FT_UInt default_glyph; + + } BDF_FaceRec, *BDF_Face; + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) bdf_driver_class; + + +FT_END_HEADER + + +#endif /* __BDFDRIVR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/bdf/bdferror.h b/drivers/freetype/src/bdf/bdferror.h new file mode 100644 index 0000000000..ea545aca06 --- /dev/null +++ b/drivers/freetype/src/bdf/bdferror.h @@ -0,0 +1,45 @@ +/* + * Copyright 2001, 2002, 2012 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 to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is used to define the BDF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __BDFERROR_H__ +#define __BDFERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX BDF_Err_ +#define FT_ERR_BASE FT_Mod_Err_BDF + +#include FT_ERRORS_H + +#endif /* __BDFERROR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/bdf/bdflib.c b/drivers/freetype/src/bdf/bdflib.c new file mode 100644 index 0000000000..0b8412d9eb --- /dev/null +++ b/drivers/freetype/src/bdf/bdflib.c @@ -0,0 +1,2625 @@ +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2013 + * 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 to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> + +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H + +#include "bdf.h" +#include "bdferror.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_bdflib + + + /*************************************************************************/ + /* */ + /* Default BDF font options. */ + /* */ + /*************************************************************************/ + + + static const bdf_options_t _bdf_opts = + { + 1, /* Correct metrics. */ + 1, /* Preserve unencoded glyphs. */ + 0, /* Preserve comments. */ + BDF_PROPORTIONAL /* Default spacing. */ + }; + + + /*************************************************************************/ + /* */ + /* Builtin BDF font properties. */ + /* */ + /*************************************************************************/ + + /* List of most properties that might appear in a font. Doesn't include */ + /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts. */ + + static const bdf_property_t _bdf_properties[] = + { + { (char *)"ADD_STYLE_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } }, + { (char *)"CHARSET_ENCODING", BDF_ATOM, 1, { 0 } }, + { (char *)"CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } }, + { (char *)"COMMENT", BDF_ATOM, 1, { 0 } }, + { (char *)"COPYRIGHT", BDF_ATOM, 1, { 0 } }, + { (char *)"DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } }, + { (char *)"DESTINATION", BDF_CARDINAL, 1, { 0 } }, + { (char *)"DEVICE_FONT_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"END_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"FACE_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"FAMILY_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"FONT", BDF_ATOM, 1, { 0 } }, + { (char *)"FONTNAME_REGISTRY", BDF_ATOM, 1, { 0 } }, + { (char *)"FONT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"FONT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"FOUNDRY", BDF_ATOM, 1, { 0 } }, + { (char *)"FULL_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"ITALIC_ANGLE", BDF_INTEGER, 1, { 0 } }, + { (char *)"MAX_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"MIN_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"NORM_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"NOTICE", BDF_ATOM, 1, { 0 } }, + { (char *)"PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"POINT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_END_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_MAX_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_MIN_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_NORM_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_POINT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_PIXELSIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_POINTSIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_X_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RELATIVE_SETWIDTH", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RELATIVE_WEIGHT", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RESOLUTION", BDF_INTEGER, 1, { 0 } }, + { (char *)"RESOLUTION_X", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RESOLUTION_Y", BDF_CARDINAL, 1, { 0 } }, + { (char *)"SETWIDTH_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"SLANT", BDF_ATOM, 1, { 0 } }, + { (char *)"SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SPACING", BDF_ATOM, 1, { 0 } }, + { (char *)"STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, + { (char *)"UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, + { (char *)"WEIGHT", BDF_CARDINAL, 1, { 0 } }, + { (char *)"WEIGHT_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"X_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"_MULE_BASELINE_OFFSET", BDF_INTEGER, 1, { 0 } }, + { (char *)"_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } }, + }; + + static const unsigned long + _num_bdf_properties = sizeof ( _bdf_properties ) / + sizeof ( _bdf_properties[0] ); + + + /* Auto correction messages. */ +#define ACMSG1 "FONT_ASCENT property missing. " \ + "Added `FONT_ASCENT %hd'.\n" +#define ACMSG2 "FONT_DESCENT property missing. " \ + "Added `FONT_DESCENT %hd'.\n" +#define ACMSG3 "Font width != actual width. Old: %hd New: %hd.\n" +#define ACMSG4 "Font left bearing != actual left bearing. " \ + "Old: %hd New: %hd.\n" +#define ACMSG5 "Font ascent != actual ascent. Old: %hd New: %hd.\n" +#define ACMSG6 "Font descent != actual descent. Old: %hd New: %hd.\n" +#define ACMSG7 "Font height != actual height. Old: %hd New: %hd.\n" +#define ACMSG8 "Glyph scalable width (SWIDTH) adjustments made.\n" +#define ACMSG9 "SWIDTH field missing at line %ld. Set automatically.\n" +#define ACMSG10 "DWIDTH field missing at line %ld. Set to glyph width.\n" +#define ACMSG11 "SIZE bits per pixel field adjusted to %hd.\n" +#define ACMSG12 "Duplicate encoding %ld (%s) changed to unencoded.\n" +#define ACMSG13 "Glyph %ld extra rows removed.\n" +#define ACMSG14 "Glyph %ld extra columns removed.\n" +#define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" +#define ACMSG16 "Glyph %ld missing columns padded with zero bits.\n" + + /* Error messages. */ +#define ERRMSG1 "[line %ld] Missing `%s' line.\n" +#define ERRMSG2 "[line %ld] Font header corrupted or missing fields.\n" +#define ERRMSG3 "[line %ld] Font glyphs corrupted or missing fields.\n" +#define ERRMSG4 "[line %ld] BBX too big.\n" +#define ERRMSG5 "[line %ld] `%s' value too big.\n" +#define ERRMSG6 "[line %ld] Input line too long.\n" +#define ERRMSG7 "[line %ld] Font name too long.\n" +#define ERRMSG8 "[line %ld] Invalid `%s' value.\n" +#define ERRMSG9 "[line %ld] Invalid keyword.\n" + + /* Debug messages. */ +#define DBGMSG1 " [%6ld] %s" /* no \n */ +#define DBGMSG2 " (0x%lX)\n" + + + /*************************************************************************/ + /* */ + /* Hash table utilities for the properties. */ + /* */ + /*************************************************************************/ + + /* XXX: Replace this with FreeType's hash functions */ + + +#define INITIAL_HT_SIZE 241 + + typedef void + (*hash_free_func)( hashnode node ); + + static hashnode* + hash_bucket( const char* key, + hashtable* ht ) + { + const char* kp = key; + unsigned long res = 0; + hashnode* bp = ht->table, *ndp; + + + /* Mocklisp hash function. */ + while ( *kp ) + res = ( res << 5 ) - res + *kp++; + + ndp = bp + ( res % ht->size ); + while ( *ndp ) + { + kp = (*ndp)->key; + if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 ) + break; + ndp--; + if ( ndp < bp ) + ndp = bp + ( ht->size - 1 ); + } + + return ndp; + } + + + static FT_Error + hash_rehash( hashtable* ht, + FT_Memory memory ) + { + hashnode* obp = ht->table, *bp, *nbp; + int i, sz = ht->size; + FT_Error error = FT_Err_Ok; + + + ht->size <<= 1; + ht->limit = ht->size / 3; + + if ( FT_NEW_ARRAY( ht->table, ht->size ) ) + goto Exit; + + for ( i = 0, bp = obp; i < sz; i++, bp++ ) + { + if ( *bp ) + { + nbp = hash_bucket( (*bp)->key, ht ); + *nbp = *bp; + } + } + FT_FREE( obp ); + + Exit: + return error; + } + + + static FT_Error + hash_init( hashtable* ht, + FT_Memory memory ) + { + int sz = INITIAL_HT_SIZE; + FT_Error error = FT_Err_Ok; + + + ht->size = sz; + ht->limit = sz / 3; + ht->used = 0; + + if ( FT_NEW_ARRAY( ht->table, sz ) ) + goto Exit; + + Exit: + return error; + } + + + static void + hash_free( hashtable* ht, + FT_Memory memory ) + { + if ( ht != 0 ) + { + int i, sz = ht->size; + hashnode* bp = ht->table; + + + for ( i = 0; i < sz; i++, bp++ ) + FT_FREE( *bp ); + + FT_FREE( ht->table ); + } + } + + + static FT_Error + hash_insert( char* key, + size_t data, + hashtable* ht, + FT_Memory memory ) + { + hashnode nn; + hashnode* bp = hash_bucket( key, ht ); + FT_Error error = FT_Err_Ok; + + + nn = *bp; + if ( !nn ) + { + if ( FT_NEW( nn ) ) + goto Exit; + *bp = nn; + + nn->key = key; + nn->data = data; + + if ( ht->used >= ht->limit ) + { + error = hash_rehash( ht, memory ); + if ( error ) + goto Exit; + } + ht->used++; + } + else + nn->data = data; + + Exit: + return error; + } + + + static hashnode + hash_lookup( const char* key, + hashtable* ht ) + { + hashnode *np = hash_bucket( key, ht ); + + + return *np; + } + + + /*************************************************************************/ + /* */ + /* Utility types and functions. */ + /* */ + /*************************************************************************/ + + + /* Function type for parsing lines of a BDF font. */ + + typedef FT_Error + (*_bdf_line_func_t)( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ); + + + /* List structure for splitting lines into fields. */ + + typedef struct _bdf_list_t_ + { + char** field; + unsigned long size; + unsigned long used; + FT_Memory memory; + + } _bdf_list_t; + + + /* Structure used while loading BDF fonts. */ + + typedef struct _bdf_parse_t_ + { + unsigned long flags; + unsigned long cnt; + unsigned long row; + + short minlb; + short maxlb; + short maxrb; + short maxas; + short maxds; + + short rbearing; + + char* glyph_name; + long glyph_enc; + + bdf_font_t* font; + bdf_options_t* opts; + + unsigned long have[34816]; /* must be in sync with `nmod' and `umod' */ + /* arrays from `bdf_font_t' structure */ + _bdf_list_t list; + + FT_Memory memory; + + } _bdf_parse_t; + + +#define setsbit( m, cc ) \ + ( m[(FT_Byte)(cc) >> 3] |= (FT_Byte)( 1 << ( (cc) & 7 ) ) ) +#define sbitset( m, cc ) \ + ( m[(FT_Byte)(cc) >> 3] & ( 1 << ( (cc) & 7 ) ) ) + + + static void + _bdf_list_init( _bdf_list_t* list, + FT_Memory memory ) + { + FT_ZERO( list ); + list->memory = memory; + } + + + static void + _bdf_list_done( _bdf_list_t* list ) + { + FT_Memory memory = list->memory; + + + if ( memory ) + { + FT_FREE( list->field ); + FT_ZERO( list ); + } + } + + + static FT_Error + _bdf_list_ensure( _bdf_list_t* list, + unsigned long num_items ) /* same as _bdf_list_t.used */ + { + FT_Error error = FT_Err_Ok; + + + if ( num_items > list->size ) + { + unsigned long oldsize = list->size; /* same as _bdf_list_t.size */ + unsigned long newsize = oldsize + ( oldsize >> 1 ) + 5; + unsigned long bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) ); + FT_Memory memory = list->memory; + + + if ( oldsize == bigsize ) + { + error = FT_THROW( Out_Of_Memory ); + goto Exit; + } + else if ( newsize < oldsize || newsize > bigsize ) + newsize = bigsize; + + if ( FT_RENEW_ARRAY( list->field, oldsize, newsize ) ) + goto Exit; + + list->size = newsize; + } + + Exit: + return error; + } + + + static void + _bdf_list_shift( _bdf_list_t* list, + unsigned long n ) + { + unsigned long i, u; + + + if ( list == 0 || list->used == 0 || n == 0 ) + return; + + if ( n >= list->used ) + { + list->used = 0; + return; + } + + for ( u = n, i = 0; u < list->used; i++, u++ ) + list->field[i] = list->field[u]; + list->used -= n; + } + + + /* An empty string for empty fields. */ + + static const char empty[1] = { 0 }; /* XXX eliminate this */ + + + static char * + _bdf_list_join( _bdf_list_t* list, + int c, + unsigned long *alen ) + { + unsigned long i, j; + char* dp; + + + *alen = 0; + + if ( list == 0 || list->used == 0 ) + return 0; + + dp = list->field[0]; + for ( i = j = 0; i < list->used; i++ ) + { + char* fp = list->field[i]; + + + while ( *fp ) + dp[j++] = *fp++; + + if ( i + 1 < list->used ) + dp[j++] = (char)c; + } + if ( dp != empty ) + dp[j] = 0; + + *alen = j; + return dp; + } + + + /* The code below ensures that we have at least 4 + 1 `field' */ + /* elements in `list' (which are possibly NULL) so that we */ + /* don't have to check the number of fields in most cases. */ + + static FT_Error + _bdf_list_split( _bdf_list_t* list, + char* separators, + char* line, + unsigned long linelen ) + { + int mult, final_empty; + char *sp, *ep, *end; + char seps[32]; + FT_Error error = FT_Err_Ok; + + + /* Initialize the list. */ + list->used = 0; + if ( list->size ) + { + list->field[0] = (char*)empty; + list->field[1] = (char*)empty; + list->field[2] = (char*)empty; + list->field[3] = (char*)empty; + list->field[4] = (char*)empty; + } + + /* If the line is empty, then simply return. */ + if ( linelen == 0 || line[0] == 0 ) + goto Exit; + + /* In the original code, if the `separators' parameter is NULL or */ + /* empty, the list is split into individual bytes. We don't need */ + /* this, so an error is signaled. */ + if ( separators == 0 || *separators == 0 ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* Prepare the separator bitmap. */ + FT_MEM_ZERO( seps, 32 ); + + /* If the very last character of the separator string is a plus, then */ + /* set the `mult' flag to indicate that multiple separators should be */ + /* collapsed into one. */ + for ( mult = 0, sp = separators; sp && *sp; sp++ ) + { + if ( *sp == '+' && *( sp + 1 ) == 0 ) + mult = 1; + else + setsbit( seps, *sp ); + } + + /* Break the line up into fields. */ + for ( final_empty = 0, sp = ep = line, end = sp + linelen; + sp < end && *sp; ) + { + /* Collect everything that is not a separator. */ + for ( ; *ep && !sbitset( seps, *ep ); ep++ ) + ; + + /* Resize the list if necessary. */ + if ( list->used == list->size ) + { + error = _bdf_list_ensure( list, list->used + 1 ); + if ( error ) + goto Exit; + } + + /* Assign the field appropriately. */ + list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty; + + sp = ep; + + if ( mult ) + { + /* If multiple separators should be collapsed, do it now by */ + /* setting all the separator characters to 0. */ + for ( ; *ep && sbitset( seps, *ep ); ep++ ) + *ep = 0; + } + else if ( *ep != 0 ) + /* Don't collapse multiple separators by making them 0, so just */ + /* make the one encountered 0. */ + *ep++ = 0; + + final_empty = ( ep > sp && *ep == 0 ); + sp = ep; + } + + /* Finally, NULL-terminate the list. */ + if ( list->used + final_empty >= list->size ) + { + error = _bdf_list_ensure( list, list->used + final_empty + 1 ); + if ( error ) + goto Exit; + } + + if ( final_empty ) + list->field[list->used++] = (char*)empty; + + list->field[list->used] = 0; + + Exit: + return error; + } + + +#define NO_SKIP 256 /* this value cannot be stored in a 'char' */ + + + static FT_Error + _bdf_readstream( FT_Stream stream, + _bdf_line_func_t callback, + void* client_data, + unsigned long *lno ) + { + _bdf_line_func_t cb; + unsigned long lineno, buf_size; + int refill, hold, to_skip; + ptrdiff_t bytes, start, end, cursor, avail; + char* buf = 0; + FT_Memory memory = stream->memory; + FT_Error error = FT_Err_Ok; + + + if ( callback == 0 ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* initial size and allocation of the input buffer */ + buf_size = 1024; + + if ( FT_NEW_ARRAY( buf, buf_size ) ) + goto Exit; + + cb = callback; + lineno = 1; + buf[0] = 0; + start = 0; + end = 0; + avail = 0; + cursor = 0; + refill = 1; + to_skip = NO_SKIP; + bytes = 0; /* make compiler happy */ + + for (;;) + { + if ( refill ) + { + bytes = (ptrdiff_t)FT_Stream_TryRead( + stream, (FT_Byte*)buf + cursor, + (FT_ULong)( buf_size - cursor ) ); + avail = cursor + bytes; + cursor = 0; + refill = 0; + } + + end = start; + + /* should we skip an optional character like \n or \r? */ + if ( start < avail && buf[start] == to_skip ) + { + start += 1; + to_skip = NO_SKIP; + continue; + } + + /* try to find the end of the line */ + while ( end < avail && buf[end] != '\n' && buf[end] != '\r' ) + end++; + + /* if we hit the end of the buffer, try shifting its content */ + /* or even resizing it */ + if ( end >= avail ) + { + if ( bytes == 0 ) /* last line in file doesn't end in \r or \n */ + break; /* ignore it then exit */ + + if ( start == 0 ) + { + /* this line is definitely too long; try resizing the input */ + /* buffer a bit to handle it. */ + FT_ULong new_size; + + + if ( buf_size >= 65536UL ) /* limit ourselves to 64KByte */ + { + FT_ERROR(( "_bdf_readstream: " ERRMSG6, lineno )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + new_size = buf_size * 2; + if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) + goto Exit; + + cursor = buf_size; + buf_size = new_size; + } + else + { + bytes = avail - start; + + FT_MEM_MOVE( buf, buf + start, bytes ); + + cursor = bytes; + avail -= bytes; + start = 0; + } + refill = 1; + continue; + } + + /* Temporarily NUL-terminate the line. */ + hold = buf[end]; + buf[end] = 0; + + /* XXX: Use encoding independent value for 0x1a */ + if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) + { + error = (*cb)( buf + start, (unsigned long)( end - start ), lineno, + (void*)&cb, client_data ); + /* Redo if we have encountered CHARS without properties. */ + if ( error == -1 ) + error = (*cb)( buf + start, (unsigned long)( end - start ), lineno, + (void*)&cb, client_data ); + if ( error ) + break; + } + + lineno += 1; + buf[end] = (char)hold; + start = end + 1; + + if ( hold == '\n' ) + to_skip = '\r'; + else if ( hold == '\r' ) + to_skip = '\n'; + else + to_skip = NO_SKIP; + } + + *lno = lineno; + + Exit: + FT_FREE( buf ); + return error; + } + + + /* XXX: make this work with EBCDIC also */ + + static const unsigned char a2i[128] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + static const unsigned char odigits[32] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static const unsigned char ddigits[32] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static const unsigned char hdigits[32] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + + /* Routine to convert an ASCII string into an unsigned long integer. */ + static unsigned long + _bdf_atoul( char* s, + char** end, + int base ) + { + unsigned long v; + const unsigned char* dmap; + + + if ( s == 0 || *s == 0 ) + return 0; + + /* Make sure the radix is something recognizable. Default to 10. */ + switch ( base ) + { + case 8: + dmap = odigits; + break; + case 16: + dmap = hdigits; + break; + default: + base = 10; + dmap = ddigits; + break; + } + + /* Check for the special hex prefix. */ + if ( *s == '0' && + ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) + { + base = 16; + dmap = hdigits; + s += 2; + } + + for ( v = 0; sbitset( dmap, *s ); s++ ) + v = v * base + a2i[(int)*s]; + + if ( end != 0 ) + *end = s; + + return v; + } + + + /* Routine to convert an ASCII string into an signed long integer. */ + static long + _bdf_atol( char* s, + char** end, + int base ) + { + long v, neg; + const unsigned char* dmap; + + + if ( s == 0 || *s == 0 ) + return 0; + + /* Make sure the radix is something recognizable. Default to 10. */ + switch ( base ) + { + case 8: + dmap = odigits; + break; + case 16: + dmap = hdigits; + break; + default: + base = 10; + dmap = ddigits; + break; + } + + /* Check for a minus sign. */ + neg = 0; + if ( *s == '-' ) + { + s++; + neg = 1; + } + + /* Check for the special hex prefix. */ + if ( *s == '0' && + ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) + { + base = 16; + dmap = hdigits; + s += 2; + } + + for ( v = 0; sbitset( dmap, *s ); s++ ) + v = v * base + a2i[(int)*s]; + + if ( end != 0 ) + *end = s; + + return ( !neg ) ? v : -v; + } + + + /* Routine to convert an ASCII string into an signed short integer. */ + static short + _bdf_atos( char* s, + char** end, + int base ) + { + short v, neg; + const unsigned char* dmap; + + + if ( s == 0 || *s == 0 ) + return 0; + + /* Make sure the radix is something recognizable. Default to 10. */ + switch ( base ) + { + case 8: + dmap = odigits; + break; + case 16: + dmap = hdigits; + break; + default: + base = 10; + dmap = ddigits; + break; + } + + /* Check for a minus. */ + neg = 0; + if ( *s == '-' ) + { + s++; + neg = 1; + } + + /* Check for the special hex prefix. */ + if ( *s == '0' && + ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) + { + base = 16; + dmap = hdigits; + s += 2; + } + + for ( v = 0; sbitset( dmap, *s ); s++ ) + v = (short)( v * base + a2i[(int)*s] ); + + if ( end != 0 ) + *end = s; + + return (short)( ( !neg ) ? v : -v ); + } + + + /* Routine to compare two glyphs by encoding so they can be sorted. */ + static int + by_encoding( const void* a, + const void* b ) + { + bdf_glyph_t *c1, *c2; + + + c1 = (bdf_glyph_t *)a; + c2 = (bdf_glyph_t *)b; + + if ( c1->encoding < c2->encoding ) + return -1; + + if ( c1->encoding > c2->encoding ) + return 1; + + return 0; + } + + + static FT_Error + bdf_create_property( char* name, + int format, + bdf_font_t* font ) + { + size_t n; + bdf_property_t* p; + FT_Memory memory = font->memory; + FT_Error error = FT_Err_Ok; + + + /* First check whether the property has */ + /* already been added or not. If it has, then */ + /* simply ignore it. */ + if ( hash_lookup( name, &(font->proptbl) ) ) + goto Exit; + + if ( FT_RENEW_ARRAY( font->user_props, + font->nuser_props, + font->nuser_props + 1 ) ) + goto Exit; + + p = font->user_props + font->nuser_props; + FT_ZERO( p ); + + n = ft_strlen( name ) + 1; + if ( n > FT_ULONG_MAX ) + return FT_THROW( Invalid_Argument ); + + if ( FT_NEW_ARRAY( p->name, n ) ) + goto Exit; + + FT_MEM_COPY( (char *)p->name, name, n ); + + p->format = format; + p->builtin = 0; + + n = _num_bdf_properties + font->nuser_props; + + error = hash_insert( p->name, n, &(font->proptbl), memory ); + if ( error ) + goto Exit; + + font->nuser_props++; + + Exit: + return error; + } + + + FT_LOCAL_DEF( bdf_property_t * ) + bdf_get_property( char* name, + bdf_font_t* font ) + { + hashnode hn; + size_t propid; + + + if ( name == 0 || *name == 0 ) + return 0; + + if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) + return 0; + + propid = hn->data; + if ( propid >= _num_bdf_properties ) + return font->user_props + ( propid - _num_bdf_properties ); + + return (bdf_property_t*)_bdf_properties + propid; + } + + + /*************************************************************************/ + /* */ + /* BDF font file parsing flags and functions. */ + /* */ + /*************************************************************************/ + + + /* Parse flags. */ + +#define _BDF_START 0x0001 +#define _BDF_FONT_NAME 0x0002 +#define _BDF_SIZE 0x0004 +#define _BDF_FONT_BBX 0x0008 +#define _BDF_PROPS 0x0010 +#define _BDF_GLYPHS 0x0020 +#define _BDF_GLYPH 0x0040 +#define _BDF_ENCODING 0x0080 +#define _BDF_SWIDTH 0x0100 +#define _BDF_DWIDTH 0x0200 +#define _BDF_BBX 0x0400 +#define _BDF_BITMAP 0x0800 + +#define _BDF_SWIDTH_ADJ 0x1000 + +#define _BDF_GLYPH_BITS ( _BDF_GLYPH | \ + _BDF_ENCODING | \ + _BDF_SWIDTH | \ + _BDF_DWIDTH | \ + _BDF_BBX | \ + _BDF_BITMAP ) + +#define _BDF_GLYPH_WIDTH_CHECK 0x40000000UL +#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000UL + + + static FT_Error + _bdf_add_comment( bdf_font_t* font, + char* comment, + unsigned long len ) + { + char* cp; + FT_Memory memory = font->memory; + FT_Error error = FT_Err_Ok; + + + if ( FT_RENEW_ARRAY( font->comments, + font->comments_len, + font->comments_len + len + 1 ) ) + goto Exit; + + cp = font->comments + font->comments_len; + + FT_MEM_COPY( cp, comment, len ); + cp[len] = '\n'; + + font->comments_len += len + 1; + + Exit: + return error; + } + + + /* Set the spacing from the font name if it exists, or set it to the */ + /* default specified in the options. */ + static FT_Error + _bdf_set_default_spacing( bdf_font_t* font, + bdf_options_t* opts, + unsigned long lineno ) + { + size_t len; + char name[256]; + _bdf_list_t list; + FT_Memory memory; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( lineno ); /* only used in debug mode */ + + + if ( font == 0 || font->name == 0 || font->name[0] == 0 ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + memory = font->memory; + + _bdf_list_init( &list, memory ); + + font->spacing = opts->font_spacing; + + len = ft_strlen( font->name ) + 1; + /* Limit ourselves to 256 characters in the font name. */ + if ( len >= 256 ) + { + FT_ERROR(( "_bdf_set_default_spacing: " ERRMSG7, lineno )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_MEM_COPY( name, font->name, len ); + + error = _bdf_list_split( &list, (char *)"-", name, (unsigned long)len ); + if ( error ) + goto Fail; + + if ( list.used == 15 ) + { + switch ( list.field[11][0] ) + { + case 'C': + case 'c': + font->spacing = BDF_CHARCELL; + break; + case 'M': + case 'm': + font->spacing = BDF_MONOWIDTH; + break; + case 'P': + case 'p': + font->spacing = BDF_PROPORTIONAL; + break; + } + } + + Fail: + _bdf_list_done( &list ); + + Exit: + return error; + } + + + /* Determine whether the property is an atom or not. If it is, then */ + /* clean it up so the double quotes are removed if they exist. */ + static int + _bdf_is_atom( char* line, + unsigned long linelen, + char** name, + char** value, + bdf_font_t* font ) + { + int hold; + char *sp, *ep; + bdf_property_t* p; + + + *name = sp = ep = line; + + while ( *ep && *ep != ' ' && *ep != '\t' ) + ep++; + + hold = -1; + if ( *ep ) + { + hold = *ep; + *ep = 0; + } + + p = bdf_get_property( sp, font ); + + /* Restore the character that was saved before any return can happen. */ + if ( hold != -1 ) + *ep = (char)hold; + + /* If the property exists and is not an atom, just return here. */ + if ( p && p->format != BDF_ATOM ) + return 0; + + /* The property is an atom. Trim all leading and trailing whitespace */ + /* and double quotes for the atom value. */ + sp = ep; + ep = line + linelen; + + /* Trim the leading whitespace if it exists. */ + if ( *sp ) + *sp++ = 0; + while ( *sp && + ( *sp == ' ' || *sp == '\t' ) ) + sp++; + + /* Trim the leading double quote if it exists. */ + if ( *sp == '"' ) + sp++; + *value = sp; + + /* Trim the trailing whitespace if it exists. */ + while ( ep > sp && + ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) ) + *--ep = 0; + + /* Trim the trailing double quote if it exists. */ + if ( ep > sp && *( ep - 1 ) == '"' ) + *--ep = 0; + + return 1; + } + + + static FT_Error + _bdf_add_property( bdf_font_t* font, + char* name, + char* value, + unsigned long lineno ) + { + size_t propid; + hashnode hn; + bdf_property_t *prop, *fp; + FT_Memory memory = font->memory; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( lineno ); /* only used in debug mode */ + + + /* First, check whether the property already exists in the font. */ + if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 ) + { + /* The property already exists in the font, so simply replace */ + /* the value of the property with the current value. */ + fp = font->props + hn->data; + + switch ( fp->format ) + { + case BDF_ATOM: + /* Delete the current atom if it exists. */ + FT_FREE( fp->value.atom ); + + if ( value && value[0] != 0 ) + { + if ( FT_STRDUP( fp->value.atom, value ) ) + goto Exit; + } + break; + + case BDF_INTEGER: + fp->value.l = _bdf_atol( value, 0, 10 ); + break; + + case BDF_CARDINAL: + fp->value.ul = _bdf_atoul( value, 0, 10 ); + break; + + default: + ; + } + + goto Exit; + } + + /* See whether this property type exists yet or not. */ + /* If not, create it. */ + hn = hash_lookup( name, &(font->proptbl) ); + if ( hn == 0 ) + { + error = bdf_create_property( name, BDF_ATOM, font ); + if ( error ) + goto Exit; + hn = hash_lookup( name, &(font->proptbl) ); + } + + /* Allocate another property if this is overflow. */ + if ( font->props_used == font->props_size ) + { + if ( font->props_size == 0 ) + { + if ( FT_NEW_ARRAY( font->props, 1 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY( font->props, + font->props_size, + font->props_size + 1 ) ) + goto Exit; + } + + fp = font->props + font->props_size; + FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) ); + font->props_size++; + } + + propid = hn->data; + if ( propid >= _num_bdf_properties ) + prop = font->user_props + ( propid - _num_bdf_properties ); + else + prop = (bdf_property_t*)_bdf_properties + propid; + + fp = font->props + font->props_used; + + fp->name = prop->name; + fp->format = prop->format; + fp->builtin = prop->builtin; + + switch ( prop->format ) + { + case BDF_ATOM: + fp->value.atom = 0; + if ( value != 0 && value[0] ) + { + if ( FT_STRDUP( fp->value.atom, value ) ) + goto Exit; + } + break; + + case BDF_INTEGER: + fp->value.l = _bdf_atol( value, 0, 10 ); + break; + + case BDF_CARDINAL: + fp->value.ul = _bdf_atoul( value, 0, 10 ); + break; + } + + /* If the property happens to be a comment, then it doesn't need */ + /* to be added to the internal hash table. */ + if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) + { + /* Add the property to the font property table. */ + error = hash_insert( fp->name, + font->props_used, + (hashtable *)font->internal, + memory ); + if ( error ) + goto Exit; + } + + font->props_used++; + + /* Some special cases need to be handled here. The DEFAULT_CHAR */ + /* property needs to be located if it exists in the property list, the */ + /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are */ + /* present, and the SPACING property should override the default */ + /* spacing. */ + if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 ) + font->default_char = fp->value.l; + else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 ) + font->font_ascent = fp->value.l; + else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 ) + font->font_descent = fp->value.l; + else if ( ft_memcmp( name, "SPACING", 7 ) == 0 ) + { + if ( !fp->value.atom ) + { + FT_ERROR(( "_bdf_add_property: " ERRMSG8, lineno, "SPACING" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' ) + font->spacing = BDF_PROPORTIONAL; + else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' ) + font->spacing = BDF_MONOWIDTH; + else if ( fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C' ) + font->spacing = BDF_CHARCELL; + } + + Exit: + return error; + } + + + static const unsigned char nibble_mask[8] = + { + 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE + }; + + + /* Actually parse the glyph info and bitmaps. */ + static FT_Error + _bdf_parse_glyphs( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + int c, mask_index; + char* s; + unsigned char* bp; + unsigned long i, slen, nibbles; + + _bdf_parse_t* p; + bdf_glyph_t* glyph; + bdf_font_t* font; + + FT_Memory memory; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( call_data ); + FT_UNUSED( lineno ); /* only used in debug mode */ + + + p = (_bdf_parse_t *)client_data; + + font = p->font; + memory = font->memory; + + /* Check for a comment. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + linelen -= 7; + + s = line + 7; + if ( *s != 0 ) + { + s++; + linelen--; + } + error = _bdf_add_comment( p->font, s, linelen ); + goto Exit; + } + + /* The very first thing expected is the number of glyphs. */ + if ( !( p->flags & _BDF_GLYPHS ) ) + { + if ( ft_memcmp( line, "CHARS", 5 ) != 0 ) + { + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" )); + error = FT_THROW( Missing_Chars_Field ); + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 ); + + /* Make sure the number of glyphs is non-zero. */ + if ( p->cnt == 0 ) + font->glyphs_size = 64; + + /* Limit ourselves to 1,114,112 glyphs in the font (this is the */ + /* number of code points available in Unicode). */ + if ( p->cnt >= 0x110000UL ) + { + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "CHARS" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) ) + goto Exit; + + p->flags |= _BDF_GLYPHS; + + goto Exit; + } + + /* Check for the ENDFONT field. */ + if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 ) + { + /* Sort the glyphs by encoding. */ + ft_qsort( (char *)font->glyphs, + font->glyphs_used, + sizeof ( bdf_glyph_t ), + by_encoding ); + + p->flags &= ~_BDF_START; + + goto Exit; + } + + /* Check for the ENDCHAR field. */ + if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 ) + { + p->glyph_enc = 0; + p->flags &= ~_BDF_GLYPH_BITS; + + goto Exit; + } + + /* Check whether a glyph is being scanned but should be */ + /* ignored because it is an unencoded glyph. */ + if ( ( p->flags & _BDF_GLYPH ) && + p->glyph_enc == -1 && + p->opts->keep_unencoded == 0 ) + goto Exit; + + /* Check for the STARTCHAR field. */ + if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 ) + { + /* Set the character name in the parse info first until the */ + /* encoding can be checked for an unencoded character. */ + FT_FREE( p->glyph_name ); + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + _bdf_list_shift( &p->list, 1 ); + + s = _bdf_list_join( &p->list, ' ', &slen ); + + if ( !s ) + { + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG8, lineno, "STARTCHAR" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) ) + goto Exit; + + FT_MEM_COPY( p->glyph_name, s, slen + 1 ); + + p->flags |= _BDF_GLYPH; + + FT_TRACE4(( DBGMSG1, lineno, s )); + + goto Exit; + } + + /* Check for the ENCODING field. */ + if ( ft_memcmp( line, "ENCODING", 8 ) == 0 ) + { + if ( !( p->flags & _BDF_GLYPH ) ) + { + /* Missing STARTCHAR field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" )); + error = FT_THROW( Missing_Startchar_Field ); + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 ); + + /* Normalize negative encoding values. The specification only */ + /* allows -1, but we can be more generous here. */ + if ( p->glyph_enc < -1 ) + p->glyph_enc = -1; + + /* Check for alternative encoding format. */ + if ( p->glyph_enc == -1 && p->list.used > 2 ) + p->glyph_enc = _bdf_atol( p->list.field[2], 0, 10 ); + + if ( p->glyph_enc < -1 ) + p->glyph_enc = -1; + + FT_TRACE4(( DBGMSG2, p->glyph_enc )); + + /* Check that the encoding is in the Unicode range because */ + /* otherwise p->have (a bitmap with static size) overflows. */ + if ( p->glyph_enc > 0 && + (size_t)p->glyph_enc >= sizeof ( p->have ) / + sizeof ( unsigned long ) * 32 ) + { + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "ENCODING" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Check whether this encoding has already been encountered. */ + /* If it has then change it to unencoded so it gets added if */ + /* indicated. */ + if ( p->glyph_enc >= 0 ) + { + if ( _bdf_glyph_modified( p->have, p->glyph_enc ) ) + { + /* Emit a message saying a glyph has been moved to the */ + /* unencoded area. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12, + p->glyph_enc, p->glyph_name )); + p->glyph_enc = -1; + font->modified = 1; + } + else + _bdf_set_glyph_modified( p->have, p->glyph_enc ); + } + + if ( p->glyph_enc >= 0 ) + { + /* Make sure there are enough glyphs allocated in case the */ + /* number of characters happen to be wrong. */ + if ( font->glyphs_used == font->glyphs_size ) + { + if ( FT_RENEW_ARRAY( font->glyphs, + font->glyphs_size, + font->glyphs_size + 64 ) ) + goto Exit; + + font->glyphs_size += 64; + } + + glyph = font->glyphs + font->glyphs_used++; + glyph->name = p->glyph_name; + glyph->encoding = p->glyph_enc; + + /* Reset the initial glyph info. */ + p->glyph_name = 0; + } + else + { + /* Unencoded glyph. Check whether it should */ + /* be added or not. */ + if ( p->opts->keep_unencoded != 0 ) + { + /* Allocate the next unencoded glyph. */ + if ( font->unencoded_used == font->unencoded_size ) + { + if ( FT_RENEW_ARRAY( font->unencoded , + font->unencoded_size, + font->unencoded_size + 4 ) ) + goto Exit; + + font->unencoded_size += 4; + } + + glyph = font->unencoded + font->unencoded_used; + glyph->name = p->glyph_name; + glyph->encoding = font->unencoded_used++; + } + else + /* Free up the glyph name if the unencoded shouldn't be */ + /* kept. */ + FT_FREE( p->glyph_name ); + + p->glyph_name = 0; + } + + /* Clear the flags that might be added when width and height are */ + /* checked for consistency. */ + p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK ); + + p->flags |= _BDF_ENCODING; + + goto Exit; + } + + /* Point at the glyph being constructed. */ + if ( p->glyph_enc == -1 ) + glyph = font->unencoded + ( font->unencoded_used - 1 ); + else + glyph = font->glyphs + ( font->glyphs_used - 1 ); + + /* Check whether a bitmap is being constructed. */ + if ( p->flags & _BDF_BITMAP ) + { + /* If there are more rows than are specified in the glyph metrics, */ + /* ignore the remaining lines. */ + if ( p->row >= (unsigned long)glyph->bbx.height ) + { + if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) ) + { + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding )); + p->flags |= _BDF_GLYPH_HEIGHT_CHECK; + font->modified = 1; + } + + goto Exit; + } + + /* Only collect the number of nibbles indicated by the glyph */ + /* metrics. If there are more columns, they are simply ignored. */ + nibbles = glyph->bpr << 1; + bp = glyph->bitmap + p->row * glyph->bpr; + + for ( i = 0; i < nibbles; i++ ) + { + c = line[i]; + if ( !sbitset( hdigits, c ) ) + break; + *bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] ); + if ( i + 1 < nibbles && ( i & 1 ) ) + *++bp = 0; + } + + /* If any line has not enough columns, */ + /* indicate they have been padded with zero bits. */ + if ( i < nibbles && + !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + { + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding )); + p->flags |= _BDF_GLYPH_WIDTH_CHECK; + font->modified = 1; + } + + /* Remove possible garbage at the right. */ + mask_index = ( glyph->bbx.width * p->font->bpp ) & 7; + if ( glyph->bbx.width ) + *bp &= nibble_mask[mask_index]; + + /* If any line has extra columns, indicate they have been removed. */ + if ( i == nibbles && + sbitset( hdigits, line[nibbles] ) && + !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + { + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); + p->flags |= _BDF_GLYPH_WIDTH_CHECK; + font->modified = 1; + } + + p->row++; + goto Exit; + } + + /* Expect the SWIDTH (scalable width) field next. */ + if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 ) + { + if ( !( p->flags & _BDF_ENCODING ) ) + goto Missing_Encoding; + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + p->flags |= _BDF_SWIDTH; + + goto Exit; + } + + /* Expect the DWIDTH (scalable width) field next. */ + if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) + { + if ( !( p->flags & _BDF_ENCODING ) ) + goto Missing_Encoding; + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + + if ( !( p->flags & _BDF_SWIDTH ) ) + { + /* Missing SWIDTH field. Emit an auto correction message and set */ + /* the scalable width from the device width. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG9, lineno )); + + glyph->swidth = (unsigned short)FT_MulDiv( + glyph->dwidth, 72000L, + (FT_Long)( font->point_size * + font->resolution_x ) ); + } + + p->flags |= _BDF_DWIDTH; + goto Exit; + } + + /* Expect the BBX field next. */ + if ( ft_memcmp( line, "BBX", 3 ) == 0 ) + { + if ( !( p->flags & _BDF_ENCODING ) ) + goto Missing_Encoding; + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + glyph->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); + glyph->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); + glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); + glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + + /* Generate the ascent and descent of the character. */ + glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset ); + glyph->bbx.descent = (short)( -glyph->bbx.y_offset ); + + /* Determine the overall font bounding box as the characters are */ + /* loaded so corrections can be done later if indicated. */ + p->maxas = (short)FT_MAX( glyph->bbx.ascent, p->maxas ); + p->maxds = (short)FT_MAX( glyph->bbx.descent, p->maxds ); + + p->rbearing = (short)( glyph->bbx.width + glyph->bbx.x_offset ); + + p->maxrb = (short)FT_MAX( p->rbearing, p->maxrb ); + p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb ); + p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb ); + + if ( !( p->flags & _BDF_DWIDTH ) ) + { + /* Missing DWIDTH field. Emit an auto correction message and set */ + /* the device width to the glyph width. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG10, lineno )); + glyph->dwidth = glyph->bbx.width; + } + + /* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */ + /* value if necessary. */ + if ( p->opts->correct_metrics != 0 ) + { + /* Determine the point size of the glyph. */ + unsigned short sw = (unsigned short)FT_MulDiv( + glyph->dwidth, 72000L, + (FT_Long)( font->point_size * + font->resolution_x ) ); + + + if ( sw != glyph->swidth ) + { + glyph->swidth = sw; + + if ( p->glyph_enc == -1 ) + _bdf_set_glyph_modified( font->umod, + font->unencoded_used - 1 ); + else + _bdf_set_glyph_modified( font->nmod, glyph->encoding ); + + p->flags |= _BDF_SWIDTH_ADJ; + font->modified = 1; + } + } + + p->flags |= _BDF_BBX; + goto Exit; + } + + /* And finally, gather up the bitmap. */ + if ( ft_memcmp( line, "BITMAP", 6 ) == 0 ) + { + unsigned long bitmap_size; + + + if ( !( p->flags & _BDF_BBX ) ) + { + /* Missing BBX field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" )); + error = FT_THROW( Missing_Bbx_Field ); + goto Exit; + } + + /* Allocate enough space for the bitmap. */ + glyph->bpr = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3; + + bitmap_size = glyph->bpr * glyph->bbx.height; + if ( glyph->bpr > 0xFFFFU || bitmap_size > 0xFFFFU ) + { + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG4, lineno )); + error = FT_THROW( Bbx_Too_Big ); + goto Exit; + } + else + glyph->bytes = (unsigned short)bitmap_size; + + if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) ) + goto Exit; + + p->row = 0; + p->flags |= _BDF_BITMAP; + + goto Exit; + } + + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG9, lineno )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + + Missing_Encoding: + /* Missing ENCODING field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" )); + error = FT_THROW( Missing_Encoding_Field ); + + Exit: + if ( error && ( p->flags & _BDF_GLYPH ) ) + FT_FREE( p->glyph_name ); + + return error; + } + + + /* Load the font properties. */ + static FT_Error + _bdf_parse_properties( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + unsigned long vlen; + _bdf_line_func_t* next; + _bdf_parse_t* p; + char* name; + char* value; + char nbuf[128]; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( lineno ); + + + next = (_bdf_line_func_t *)call_data; + p = (_bdf_parse_t *) client_data; + + /* Check for the end of the properties. */ + if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 ) + { + /* If the FONT_ASCENT or FONT_DESCENT properties have not been */ + /* encountered yet, then make sure they are added as properties and */ + /* make sure they are set from the font bounding box info. */ + /* */ + /* This is *always* done regardless of the options, because X11 */ + /* requires these two fields to compile fonts. */ + if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 ) + { + p->font->font_ascent = p->font->bbx.ascent; + ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); + error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", + nbuf, lineno ); + if ( error ) + goto Exit; + + FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent )); + p->font->modified = 1; + } + + if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 ) + { + p->font->font_descent = p->font->bbx.descent; + ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); + error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", + nbuf, lineno ); + if ( error ) + goto Exit; + + FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent )); + p->font->modified = 1; + } + + p->flags &= ~_BDF_PROPS; + *next = _bdf_parse_glyphs; + + goto Exit; + } + + /* Ignore the _XFREE86_GLYPH_RANGES properties. */ + if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 ) + goto Exit; + + /* Handle COMMENT fields and properties in a special way to preserve */ + /* the spacing. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + name = value = line; + value += 7; + if ( *value ) + *value++ = 0; + error = _bdf_add_property( p->font, name, value, lineno ); + if ( error ) + goto Exit; + } + else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) ) + { + error = _bdf_add_property( p->font, name, value, lineno ); + if ( error ) + goto Exit; + } + else + { + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + name = p->list.field[0]; + + _bdf_list_shift( &p->list, 1 ); + value = _bdf_list_join( &p->list, ' ', &vlen ); + + error = _bdf_add_property( p->font, name, value, lineno ); + if ( error ) + goto Exit; + } + + Exit: + return error; + } + + + /* Load the font header. */ + static FT_Error + _bdf_parse_start( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + unsigned long slen; + _bdf_line_func_t* next; + _bdf_parse_t* p; + bdf_font_t* font; + char *s; + + FT_Memory memory = NULL; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( lineno ); /* only used in debug mode */ + + + next = (_bdf_line_func_t *)call_data; + p = (_bdf_parse_t *) client_data; + + if ( p->font ) + memory = p->font->memory; + + /* Check for a comment. This is done to handle those fonts that have */ + /* comments before the STARTFONT line for some reason. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + if ( p->opts->keep_comments != 0 && p->font != 0 ) + { + linelen -= 7; + + s = line + 7; + if ( *s != 0 ) + { + s++; + linelen--; + } + + error = _bdf_add_comment( p->font, s, linelen ); + if ( error ) + goto Exit; + /* here font is not defined! */ + } + + goto Exit; + } + + if ( !( p->flags & _BDF_START ) ) + { + memory = p->memory; + + if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 ) + { + /* we don't emit an error message since this code gets */ + /* explicitly caught one level higher */ + error = FT_THROW( Missing_Startfont_Field ); + goto Exit; + } + + p->flags = _BDF_START; + font = p->font = 0; + + if ( FT_NEW( font ) ) + goto Exit; + p->font = font; + + font->memory = p->memory; + p->memory = 0; + + { /* setup */ + size_t i; + bdf_property_t* prop; + + + error = hash_init( &(font->proptbl), memory ); + if ( error ) + goto Exit; + for ( i = 0, prop = (bdf_property_t*)_bdf_properties; + i < _num_bdf_properties; i++, prop++ ) + { + error = hash_insert( prop->name, i, + &(font->proptbl), memory ); + if ( error ) + goto Exit; + } + } + + if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) ) + goto Exit; + error = hash_init( (hashtable *)p->font->internal,memory ); + if ( error ) + goto Exit; + p->font->spacing = p->opts->font_spacing; + p->font->default_char = -1; + + goto Exit; + } + + /* Check for the start of the properties. */ + if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 ) + { + if ( !( p->flags & _BDF_FONT_BBX ) ) + { + /* Missing the FONTBOUNDINGBOX field. */ + FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); + error = FT_THROW( Missing_Fontboundingbox_Field ); + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + /* at this point, `p->font' can't be NULL */ + p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); + + if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) + { + p->font->props_size = 0; + goto Exit; + } + + p->flags |= _BDF_PROPS; + *next = _bdf_parse_properties; + + goto Exit; + } + + /* Check for the FONTBOUNDINGBOX field. */ + if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) + { + if ( !( p->flags & _BDF_SIZE ) ) + { + /* Missing the SIZE field. */ + FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" )); + error = FT_THROW( Missing_Size_Field ); + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + p->font->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); + p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); + + p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); + p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + + p->font->bbx.ascent = (short)( p->font->bbx.height + + p->font->bbx.y_offset ); + + p->font->bbx.descent = (short)( -p->font->bbx.y_offset ); + + p->flags |= _BDF_FONT_BBX; + + goto Exit; + } + + /* The next thing to check for is the FONT field. */ + if ( ft_memcmp( line, "FONT", 4 ) == 0 ) + { + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + _bdf_list_shift( &p->list, 1 ); + + s = _bdf_list_join( &p->list, ' ', &slen ); + + if ( !s ) + { + FT_ERROR(( "_bdf_parse_start: " ERRMSG8, lineno, "FONT" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */ + FT_FREE( p->font->name ); + + if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) ) + goto Exit; + FT_MEM_COPY( p->font->name, s, slen + 1 ); + + /* If the font name is an XLFD name, set the spacing to the one in */ + /* the font name. If there is no spacing fall back on the default. */ + error = _bdf_set_default_spacing( p->font, p->opts, lineno ); + if ( error ) + goto Exit; + + p->flags |= _BDF_FONT_NAME; + + goto Exit; + } + + /* Check for the SIZE field. */ + if ( ft_memcmp( line, "SIZE", 4 ) == 0 ) + { + if ( !( p->flags & _BDF_FONT_NAME ) ) + { + /* Missing the FONT field. */ + FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" )); + error = FT_THROW( Missing_Font_Field ); + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + p->font->point_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 ); + p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 ); + + /* Check for the bits per pixel field. */ + if ( p->list.used == 5 ) + { + unsigned short bitcount, i, shift; + + + p->font->bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 ); + + /* Only values 1, 2, 4, 8 are allowed. */ + shift = p->font->bpp; + bitcount = 0; + for ( i = 0; shift > 0; i++ ) + { + if ( shift & 1 ) + bitcount = i; + shift >>= 1; + } + + shift = (short)( ( bitcount > 3 ) ? 8 : ( 1 << bitcount ) ); + + if ( p->font->bpp > shift || p->font->bpp != shift ) + { + /* select next higher value */ + p->font->bpp = (unsigned short)( shift << 1 ); + FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp )); + } + } + else + p->font->bpp = 1; + + p->flags |= _BDF_SIZE; + + goto Exit; + } + + /* Check for the CHARS field -- font properties are optional */ + if ( ft_memcmp( line, "CHARS", 5 ) == 0 ) + { + char nbuf[128]; + + + if ( !( p->flags & _BDF_FONT_BBX ) ) + { + /* Missing the FONTBOUNDINGBOX field. */ + FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); + error = FT_THROW( Missing_Fontboundingbox_Field ); + goto Exit; + } + + /* Add the two standard X11 properties which are required */ + /* for compiling fonts. */ + p->font->font_ascent = p->font->bbx.ascent; + ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); + error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", + nbuf, lineno ); + if ( error ) + goto Exit; + FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent )); + + p->font->font_descent = p->font->bbx.descent; + ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); + error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", + nbuf, lineno ); + if ( error ) + goto Exit; + FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent )); + + p->font->modified = 1; + + *next = _bdf_parse_glyphs; + + /* A special return value. */ + error = -1; + goto Exit; + } + + FT_ERROR(( "_bdf_parse_start: " ERRMSG9, lineno )); + error = FT_THROW( Invalid_File_Format ); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* API. */ + /* */ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + bdf_load_font( FT_Stream stream, + FT_Memory extmemory, + bdf_options_t* opts, + bdf_font_t* *font ) + { + unsigned long lineno = 0; /* make compiler happy */ + _bdf_parse_t *p = NULL; + + FT_Memory memory = extmemory; + FT_Error error = FT_Err_Ok; + + + if ( FT_NEW( p ) ) + goto Exit; + + memory = NULL; + p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); + p->minlb = 32767; + p->memory = extmemory; /* only during font creation */ + + _bdf_list_init( &p->list, extmemory ); + + error = _bdf_readstream( stream, _bdf_parse_start, + (void *)p, &lineno ); + if ( error ) + goto Fail; + + if ( p->font != 0 ) + { + /* If the font is not proportional, set the font's monowidth */ + /* field to the width of the font bounding box. */ + memory = p->font->memory; + + if ( p->font->spacing != BDF_PROPORTIONAL ) + p->font->monowidth = p->font->bbx.width; + + /* If the number of glyphs loaded is not that of the original count, */ + /* indicate the difference. */ + if ( p->cnt != p->font->glyphs_used + p->font->unencoded_used ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG15, p->cnt, + p->font->glyphs_used + p->font->unencoded_used )); + p->font->modified = 1; + } + + /* Once the font has been loaded, adjust the overall font metrics if */ + /* necessary. */ + if ( p->opts->correct_metrics != 0 && + ( p->font->glyphs_used > 0 || p->font->unencoded_used > 0 ) ) + { + if ( p->maxrb - p->minlb != p->font->bbx.width ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG3, + p->font->bbx.width, p->maxrb - p->minlb )); + p->font->bbx.width = (unsigned short)( p->maxrb - p->minlb ); + p->font->modified = 1; + } + + if ( p->font->bbx.x_offset != p->minlb ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG4, + p->font->bbx.x_offset, p->minlb )); + p->font->bbx.x_offset = p->minlb; + p->font->modified = 1; + } + + if ( p->font->bbx.ascent != p->maxas ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG5, + p->font->bbx.ascent, p->maxas )); + p->font->bbx.ascent = p->maxas; + p->font->modified = 1; + } + + if ( p->font->bbx.descent != p->maxds ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG6, + p->font->bbx.descent, p->maxds )); + p->font->bbx.descent = p->maxds; + p->font->bbx.y_offset = (short)( -p->maxds ); + p->font->modified = 1; + } + + if ( p->maxas + p->maxds != p->font->bbx.height ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG7, + p->font->bbx.height, p->maxas + p->maxds )); + p->font->bbx.height = (unsigned short)( p->maxas + p->maxds ); + } + + if ( p->flags & _BDF_SWIDTH_ADJ ) + FT_TRACE2(( "bdf_load_font: " ACMSG8 )); + } + } + + if ( p->flags & _BDF_START ) + { + /* The ENDFONT field was never reached or did not exist. */ + if ( !( p->flags & _BDF_GLYPHS ) ) + { + /* Error happened while parsing header. */ + FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); + error = FT_THROW( Corrupted_Font_Header ); + goto Exit; + } + else + { + /* Error happened when parsing glyphs. */ + FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); + error = FT_THROW( Corrupted_Font_Glyphs ); + goto Exit; + } + } + + if ( p->font != 0 ) + { + /* Make sure the comments are NULL terminated if they exist. */ + memory = p->font->memory; + + if ( p->font->comments_len > 0 ) + { + if ( FT_RENEW_ARRAY( p->font->comments, + p->font->comments_len, + p->font->comments_len + 1 ) ) + goto Fail; + + p->font->comments[p->font->comments_len] = 0; + } + } + else if ( error == FT_Err_Ok ) + error = FT_THROW( Invalid_File_Format ); + + *font = p->font; + + Exit: + if ( p ) + { + _bdf_list_done( &p->list ); + + memory = extmemory; + + FT_FREE( p ); + } + + return error; + + Fail: + bdf_free_font( p->font ); + + memory = extmemory; + + FT_FREE( p->font ); + + goto Exit; + } + + + FT_LOCAL_DEF( void ) + bdf_free_font( bdf_font_t* font ) + { + bdf_property_t* prop; + unsigned long i; + bdf_glyph_t* glyphs; + FT_Memory memory; + + + if ( font == 0 ) + return; + + memory = font->memory; + + FT_FREE( font->name ); + + /* Free up the internal hash table of property names. */ + if ( font->internal ) + { + hash_free( (hashtable *)font->internal, memory ); + FT_FREE( font->internal ); + } + + /* Free up the comment info. */ + FT_FREE( font->comments ); + + /* Free up the properties. */ + for ( i = 0; i < font->props_size; i++ ) + { + if ( font->props[i].format == BDF_ATOM ) + FT_FREE( font->props[i].value.atom ); + } + + FT_FREE( font->props ); + + /* Free up the character info. */ + for ( i = 0, glyphs = font->glyphs; + i < font->glyphs_used; i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + for ( i = 0, glyphs = font->unencoded; i < font->unencoded_used; + i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + FT_FREE( font->glyphs ); + FT_FREE( font->unencoded ); + + /* Free up the overflow storage if it was used. */ + for ( i = 0, glyphs = font->overflow.glyphs; + i < font->overflow.glyphs_used; i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + FT_FREE( font->overflow.glyphs ); + + /* bdf_cleanup */ + hash_free( &(font->proptbl), memory ); + + /* Free up the user defined properties. */ + for ( prop = font->user_props, i = 0; + i < font->nuser_props; i++, prop++ ) + { + FT_FREE( prop->name ); + if ( prop->format == BDF_ATOM ) + FT_FREE( prop->value.atom ); + } + + FT_FREE( font->user_props ); + + /* FREE( font ); */ /* XXX Fixme */ + } + + + FT_LOCAL_DEF( bdf_property_t * ) + bdf_get_font_property( bdf_font_t* font, + const char* name ) + { + hashnode hn; + + + if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) + return 0; + + hn = hash_lookup( name, (hashtable *)font->internal ); + + return hn ? ( font->props + hn->data ) : 0; + } + + +/* END */ diff --git a/drivers/freetype/src/bdf/module.mk b/drivers/freetype/src/bdf/module.mk new file mode 100644 index 0000000000..fe06ae8e06 --- /dev/null +++ b/drivers/freetype/src/bdf/module.mk @@ -0,0 +1,34 @@ +# +# FreeType 2 BDF module definition +# + +# 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 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +FTMODULE_H_COMMANDS += BDF_DRIVER + +define BDF_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, bdf_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)bdf $(ECHO_DRIVER_DESC)bdf bitmap fonts$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/bdf/rules.mk b/drivers/freetype/src/bdf/rules.mk new file mode 100644 index 0000000000..6ff1614dde --- /dev/null +++ b/drivers/freetype/src/bdf/rules.mk @@ -0,0 +1,81 @@ +# +# FreeType 2 bdf driver configuration rules +# + + +# Copyright (C) 2001, 2002, 2003, 2008 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 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + + + +# bdf driver directory +# +BDF_DIR := $(SRC_DIR)/bdf + + +BDF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) + + +# bdf driver sources (i.e., C files) +# +BDF_DRV_SRC := $(BDF_DIR)/bdflib.c \ + $(BDF_DIR)/bdfdrivr.c + + +# bdf driver headers +# +BDF_DRV_H := $(BDF_DIR)/bdf.h \ + $(BDF_DIR)/bdfdrivr.h \ + $(BDF_DIR)/bdferror.h + +# bdf driver object(s) +# +# BDF_DRV_OBJ_M is used during `multi' builds +# BDF_DRV_OBJ_S is used during `single' builds +# +BDF_DRV_OBJ_M := $(BDF_DRV_SRC:$(BDF_DIR)/%.c=$(OBJ_DIR)/%.$O) +BDF_DRV_OBJ_S := $(OBJ_DIR)/bdf.$O + +# bdf driver source file for single build +# +BDF_DRV_SRC_S := $(BDF_DIR)/bdf.c + + +# bdf driver - single object +# +$(BDF_DRV_OBJ_S): $(BDF_DRV_SRC_S) $(BDF_DRV_SRC) $(FREETYPE_H) $(BDF_DRV_H) + $(BDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BDF_DRV_SRC_S)) + + +# bdf driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(BDF_DIR)/%.c $(FREETYPE_H) $(BDF_DRV_H) + $(BDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(BDF_DRV_OBJ_S) +DRV_OBJS_M += $(BDF_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/cache/Jamfile b/drivers/freetype/src/cache/Jamfile new file mode 100644 index 0000000000..340cff7742 --- /dev/null +++ b/drivers/freetype/src/cache/Jamfile @@ -0,0 +1,43 @@ +# FreeType 2 src/cache Jamfile +# +# Copyright 2001, 2003, 2004 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) cache ; + +# The file <freetype/ftcache.h> contains some macro definitions that are +# later used in #include statements related to the cache sub-system. It +# needs to be parsed through a HDRMACRO rule for macro definitions. +# +HDRMACRO [ FT2_SubDir include ftcache.h ] ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ftcmru + ftcmanag + ftccache + ftcglyph + ftcsbits + ftcimage + ftcbasic + ftccmap + ; + } + else + { + _sources = ftcache ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/cache Jamfile diff --git a/drivers/freetype/src/cache/ftcache.c b/drivers/freetype/src/cache/ftcache.c new file mode 100644 index 0000000000..d41e91e5ec --- /dev/null +++ b/drivers/freetype/src/cache/ftcache.c @@ -0,0 +1,31 @@ +/***************************************************************************/ +/* */ +/* ftcache.c */ +/* */ +/* The FreeType Caching sub-system (body only). */ +/* */ +/* Copyright 2000-2001, 2003 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ftcmru.c" +#include "ftcmanag.c" +#include "ftccache.c" +#include "ftccmap.c" +#include "ftcglyph.c" +#include "ftcimage.c" +#include "ftcsbits.c" +#include "ftcbasic.c" + +/* END */ diff --git a/drivers/freetype/src/cache/ftcbasic.c b/drivers/freetype/src/cache/ftcbasic.c new file mode 100644 index 0000000000..84d336d5d6 --- /dev/null +++ b/drivers/freetype/src/cache/ftcbasic.c @@ -0,0 +1,602 @@ +/***************************************************************************/ +/* */ +/* ftcbasic.c */ +/* */ +/* The FreeType basic cache interface (body). */ +/* */ +/* Copyright 2003-2007, 2009-2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_CACHE_H +#include "ftcglyph.h" +#include "ftcimage.h" +#include "ftcsbits.h" + +#include "ftccback.h" +#include "ftcerror.h" + +#define FT_COMPONENT trace_cache + + + /* + * Basic Families + * + */ + typedef struct FTC_BasicAttrRec_ + { + FTC_ScalerRec scaler; + FT_UInt load_flags; + + } FTC_BasicAttrRec, *FTC_BasicAttrs; + +#define FTC_BASIC_ATTR_COMPARE( a, b ) \ + FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ + (a)->load_flags == (b)->load_flags ) + +#define FTC_BASIC_ATTR_HASH( a ) \ + ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags ) + + + typedef struct FTC_BasicQueryRec_ + { + FTC_GQueryRec gquery; + FTC_BasicAttrRec attrs; + + } FTC_BasicQueryRec, *FTC_BasicQuery; + + + typedef struct FTC_BasicFamilyRec_ + { + FTC_FamilyRec family; + FTC_BasicAttrRec attrs; + + } FTC_BasicFamilyRec, *FTC_BasicFamily; + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_family_compare( FTC_MruNode ftcfamily, + FT_Pointer ftcquery ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; + + + return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_init( FTC_MruNode ftcfamily, + FT_Pointer ftcquery, + FT_Pointer ftccache ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; + FTC_Cache cache = (FTC_Cache)ftccache; + + + FTC_Family_Init( FTC_FAMILY( family ), cache ); + family->attrs = query->attrs; + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + ftc_basic_family_get_count( FTC_Family ftcfamily, + FTC_Manager manager ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FT_Error error; + FT_Face face; + FT_UInt result = 0; + + + error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, + &face ); + + if ( error || !face ) + return result; + + if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs ) + { + FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " )); + FT_TRACE1(( "in this face, truncated\n", face->num_glyphs )); + } + + if ( !error ) + result = (FT_UInt)face->num_glyphs; + + return result; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_load_bitmap( FTC_Family ftcfamily, + FT_UInt gindex, + FTC_Manager manager, + FT_Face *aface ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FT_Error error; + FT_Size size; + + + error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size ); + if ( !error ) + { + FT_Face face = size->face; + + + error = FT_Load_Glyph( face, gindex, + family->attrs.load_flags | FT_LOAD_RENDER ); + if ( !error ) + *aface = face; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_load_glyph( FTC_Family ftcfamily, + FT_UInt gindex, + FTC_Cache cache, + FT_Glyph *aglyph ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FT_Error error; + FTC_Scaler scaler = &family->attrs.scaler; + FT_Face face; + FT_Size size; + + + /* we will now load the glyph image */ + error = FTC_Manager_LookupSize( cache->manager, + scaler, + &size ); + if ( !error ) + { + face = size->face; + + error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); + if ( !error ) + { + if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || + face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* ok, copy it */ + FT_Glyph glyph; + + + error = FT_Get_Glyph( face->glyph, &glyph ); + if ( !error ) + { + *aglyph = glyph; + goto Exit; + } + } + else + error = FT_THROW( Invalid_Argument ); + } + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode, + FT_Pointer ftcface_id, + FTC_Cache cache, + FT_Bool* list_changed ) + { + FTC_GNode gnode = (FTC_GNode)ftcgnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + FTC_BasicFamily family = (FTC_BasicFamily)gnode->family; + FT_Bool result; + + + if ( list_changed ) + *list_changed = FALSE; + result = FT_BOOL( family->attrs.scaler.face_id == face_id ); + if ( result ) + { + /* we must call this function to avoid this node from appearing + * in later lookups with the same face_id! + */ + FTC_GNode_UnselectFamily( gnode, cache ); + } + return result; + } + + + /* + * + * basic image cache + * + */ + + FT_CALLBACK_TABLE_DEF + const FTC_IFamilyClassRec ftc_basic_image_family_class = + { + { + sizeof ( FTC_BasicFamilyRec ), + ftc_basic_family_compare, + ftc_basic_family_init, + 0, /* FTC_MruNode_ResetFunc */ + 0 /* FTC_MruNode_DoneFunc */ + }, + ftc_basic_family_load_glyph + }; + + + FT_CALLBACK_TABLE_DEF + const FTC_GCacheClassRec ftc_basic_image_cache_class = + { + { + ftc_inode_new, + ftc_inode_weight, + ftc_gnode_compare, + ftc_basic_gnode_compare_faceid, + ftc_inode_free, + + sizeof ( FTC_GCacheRec ), + ftc_gcache_init, + ftc_gcache_done + }, + (FTC_MruListClass)&ftc_basic_image_family_class + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ) + { + return FTC_GCache_New( manager, &ftc_basic_image_cache_class, + (FTC_GCache*)acache ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ) + { + FTC_BasicQueryRec query; + FTC_Node node = 0; /* make compiler happy */ + FT_Error error; + FT_PtrDist hash; + + + /* some argument checks are delayed to FTC_Cache_Lookup */ + if ( !aglyph ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + *aglyph = NULL; + if ( anode ) + *anode = NULL; + + { + if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.load_flags = (FT_UInt)type->flags; + } + + query.attrs.scaler.pixel = 1; + query.attrs.scaler.x_res = 0; /* make compilers happy */ + query.attrs.scaler.y_res = 0; + + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; + +#if 1 /* inlining is about 50% faster! */ + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_GNode_Compare, + hash, gindex, + &query, + node, + error ); +#else + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), + hash, gindex, + FTC_GQUERY( &query ), + &node ); +#endif + if ( !error ) + { + *aglyph = FTC_INODE( node )->glyph; + + if ( anode ) + { + *anode = node; + node->ref_count++; + } + } + + Exit: + return error; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_LookupScaler( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ) + { + FTC_BasicQueryRec query; + FTC_Node node = 0; /* make compiler happy */ + FT_Error error; + FT_PtrDist hash; + + + /* some argument checks are delayed to FTC_Cache_Lookup */ + if ( !aglyph || !scaler ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + *aglyph = NULL; + if ( anode ) + *anode = NULL; + + /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + if ( load_flags > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + + query.attrs.scaler = scaler[0]; + query.attrs.load_flags = (FT_UInt)load_flags; + + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; + + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_GNode_Compare, + hash, gindex, + &query, + node, + error ); + if ( !error ) + { + *aglyph = FTC_INODE( node )->glyph; + + if ( anode ) + { + *anode = node; + node->ref_count++; + } + } + + Exit: + return error; + } + + + /* + * + * basic small bitmap cache + * + */ + + FT_CALLBACK_TABLE_DEF + const FTC_SFamilyClassRec ftc_basic_sbit_family_class = + { + { + sizeof ( FTC_BasicFamilyRec ), + ftc_basic_family_compare, + ftc_basic_family_init, + 0, /* FTC_MruNode_ResetFunc */ + 0 /* FTC_MruNode_DoneFunc */ + }, + ftc_basic_family_get_count, + ftc_basic_family_load_bitmap + }; + + + FT_CALLBACK_TABLE_DEF + const FTC_GCacheClassRec ftc_basic_sbit_cache_class = + { + { + ftc_snode_new, + ftc_snode_weight, + ftc_snode_compare, + ftc_basic_gnode_compare_faceid, + ftc_snode_free, + + sizeof ( FTC_GCacheRec ), + ftc_gcache_init, + ftc_gcache_done + }, + (FTC_MruListClass)&ftc_basic_sbit_family_class + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ) + { + return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class, + (FTC_GCache*)acache ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *ansbit, + FTC_Node *anode ) + { + FT_Error error; + FTC_BasicQueryRec query; + FTC_Node node = 0; /* make compiler happy */ + FT_PtrDist hash; + + + if ( anode ) + *anode = NULL; + + /* other argument checks delayed to FTC_Cache_Lookup */ + if ( !ansbit ) + return FT_THROW( Invalid_Argument ); + + *ansbit = NULL; + + { + if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.load_flags = (FT_UInt)type->flags; + } + + query.attrs.scaler.pixel = 1; + query.attrs.scaler.x_res = 0; /* make compilers happy */ + query.attrs.scaler.y_res = 0; + + /* beware, the hash must be the same for all glyph ranges! */ + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + + gindex / FTC_SBIT_ITEMS_PER_NODE; + +#if 1 /* inlining is about 50% faster! */ + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_SNode_Compare, + hash, gindex, + &query, + node, + error ); +#else + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), + hash, + gindex, + FTC_GQUERY( &query ), + &node ); +#endif + if ( error ) + goto Exit; + + *ansbit = FTC_SNODE( node )->sbits + + ( gindex - FTC_GNODE( node )->gindex ); + + if ( anode ) + { + *anode = node; + node->ref_count++; + } + + Exit: + return error; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_LookupScaler( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FTC_SBit *ansbit, + FTC_Node *anode ) + { + FT_Error error; + FTC_BasicQueryRec query; + FTC_Node node = 0; /* make compiler happy */ + FT_PtrDist hash; + + + if ( anode ) + *anode = NULL; + + /* other argument checks delayed to FTC_Cache_Lookup */ + if ( !ansbit || !scaler ) + return FT_THROW( Invalid_Argument ); + + *ansbit = NULL; + + /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + if ( load_flags > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + + query.attrs.scaler = scaler[0]; + query.attrs.load_flags = (FT_UInt)load_flags; + + /* beware, the hash must be the same for all glyph ranges! */ + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + + gindex / FTC_SBIT_ITEMS_PER_NODE; + + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_SNode_Compare, + hash, gindex, + &query, + node, + error ); + if ( error ) + goto Exit; + + *ansbit = FTC_SNODE( node )->sbits + + ( gindex - FTC_GNODE( node )->gindex ); + + if ( anode ) + { + *anode = node; + node->ref_count++; + } + + Exit: + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/cache/ftccache.c b/drivers/freetype/src/cache/ftccache.c new file mode 100644 index 0000000000..f20dd4502c --- /dev/null +++ b/drivers/freetype/src/cache/ftccache.c @@ -0,0 +1,621 @@ +/***************************************************************************/ +/* */ +/* ftccache.c */ +/* */ +/* The FreeType internal cache interface (body). */ +/* */ +/* Copyright 2000-2007, 2009-2011, 2013 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 "ftcmanag.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftccback.h" +#include "ftcerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + + +#define FTC_HASH_MAX_LOAD 2 +#define FTC_HASH_MIN_LOAD 1 +#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD ) + + /* this one _must_ be a power of 2! */ +#define FTC_HASH_INITIAL_SIZE 8 + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE NODE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* add a new node to the head of the manager's circular MRU list */ + static void + ftc_node_mru_link( FTC_Node node, + FTC_Manager manager ) + { + void *nl = &manager->nodes_list; + + + FTC_MruNode_Prepend( (FTC_MruNode*)nl, + (FTC_MruNode)node ); + manager->num_nodes++; + } + + + /* remove a node from the manager's MRU list */ + static void + ftc_node_mru_unlink( FTC_Node node, + FTC_Manager manager ) + { + void *nl = &manager->nodes_list; + + + FTC_MruNode_Remove( (FTC_MruNode*)nl, + (FTC_MruNode)node ); + manager->num_nodes--; + } + + +#ifndef FTC_INLINE + + /* move a node to the head of the manager's MRU list */ + static void + ftc_node_mru_up( FTC_Node node, + FTC_Manager manager ) + { + FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, + (FTC_MruNode)node ); + } + + + /* get a top bucket for specified hash from cache, + * body for FTC_NODE__TOP_FOR_HASH( cache, hash ) + */ + FT_LOCAL_DEF( FTC_Node* ) + ftc_get_top_node_for_hash( FTC_Cache cache, + FT_PtrDist hash ) + { + FTC_Node* pnode; + FT_UInt idx; + + + idx = (FT_UInt)( hash & cache->mask ); + if ( idx < cache->p ) + idx = (FT_UInt)( hash & ( 2 * cache->mask + 1 ) ); + pnode = cache->buckets + idx; + return pnode; + } + +#endif /* !FTC_INLINE */ + + + /* Note that this function cannot fail. If we cannot re-size the + * buckets array appropriately, we simply degrade the hash table's + * performance! + */ + static void + ftc_cache_resize( FTC_Cache cache ) + { + for (;;) + { + FTC_Node node, *pnode; + FT_UFast p = cache->p; + FT_UFast mask = cache->mask; + FT_UFast count = mask + p + 1; /* number of buckets */ + + + /* do we need to shrink the buckets array? */ + if ( cache->slack < 0 ) + { + FTC_Node new_list = NULL; + + + /* try to expand the buckets array _before_ splitting + * the bucket lists + */ + if ( p >= mask ) + { + FT_Memory memory = cache->memory; + FT_Error error; + + + /* if we can't expand the array, leave immediately */ + if ( FT_RENEW_ARRAY( cache->buckets, + ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) ) + break; + } + + /* split a single bucket */ + pnode = cache->buckets + p; + + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->hash & ( mask + 1 ) ) + { + *pnode = node->link; + node->link = new_list; + new_list = node; + } + else + pnode = &node->link; + } + + cache->buckets[p + mask + 1] = new_list; + + cache->slack += FTC_HASH_MAX_LOAD; + + if ( p >= mask ) + { + cache->mask = 2 * mask + 1; + cache->p = 0; + } + else + cache->p = p + 1; + } + + /* do we need to expand the buckets array? */ + else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) + { + FT_UFast old_index = p + mask; + FTC_Node* pold; + + + if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE ) + break; + + if ( p == 0 ) + { + FT_Memory memory = cache->memory; + FT_Error error; + + + /* if we can't shrink the array, leave immediately */ + if ( FT_RENEW_ARRAY( cache->buckets, + ( mask + 1 ) * 2, mask + 1 ) ) + break; + + cache->mask >>= 1; + p = cache->mask; + } + else + p--; + + pnode = cache->buckets + p; + while ( *pnode ) + pnode = &(*pnode)->link; + + pold = cache->buckets + old_index; + *pnode = *pold; + *pold = NULL; + + cache->slack -= FTC_HASH_MAX_LOAD; + cache->p = p; + } + + /* otherwise, the hash table is balanced */ + else + break; + } + } + + + /* remove a node from its cache's hash table */ + static void + ftc_node_hash_unlink( FTC_Node node0, + FTC_Cache cache ) + { + FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node0->hash ); + + + for (;;) + { + FTC_Node node = *pnode; + + + if ( node == NULL ) + { + FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" )); + return; + } + + if ( node == node0 ) + break; + + pnode = &(*pnode)->link; + } + + *pnode = node0->link; + node0->link = NULL; + + cache->slack++; + ftc_cache_resize( cache ); + } + + + /* add a node to the `top' of its cache's hash table */ + static void + ftc_node_hash_link( FTC_Node node, + FTC_Cache cache ) + { + FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node->hash ); + + + node->link = *pnode; + *pnode = node; + + cache->slack--; + ftc_cache_resize( cache ); + } + + + /* remove a node from the cache manager */ + FT_LOCAL_DEF( void ) + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ) + { + FTC_Cache cache; + + +#ifdef FT_DEBUG_ERROR + /* find node's cache */ + if ( node->cache_index >= manager->num_caches ) + { + FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); + return; + } +#endif + + cache = manager->caches[node->cache_index]; + +#ifdef FT_DEBUG_ERROR + if ( cache == NULL ) + { + FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); + return; + } +#endif + + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + + /* remove node from mru list */ + ftc_node_mru_unlink( node, manager ); + + /* remove node from cache's hash table */ + ftc_node_hash_unlink( node, cache ); + + /* now finalize it */ + cache->clazz.node_free( node, cache ); + +#if 0 + /* check, just in case of general corruption :-) */ + if ( manager->num_nodes == 0 ) + FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n", + manager->num_nodes )); +#endif + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** ABSTRACT CACHE CLASS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + FTC_Cache_Init( FTC_Cache cache ) + { + return ftc_cache_init( cache ); + } + + + FT_LOCAL_DEF( FT_Error ) + ftc_cache_init( FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + FT_Error error; + + + cache->p = 0; + cache->mask = FTC_HASH_INITIAL_SIZE - 1; + cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; + + (void)FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ); + return error; + } + + + static void + FTC_Cache_Clear( FTC_Cache cache ) + { + if ( cache && cache->buckets ) + { + FTC_Manager manager = cache->manager; + FT_UFast i; + FT_UFast count; + + + count = cache->p + cache->mask + 1; + + for ( i = 0; i < count; i++ ) + { + FTC_Node *pnode = cache->buckets + i, next, node = *pnode; + + + while ( node ) + { + next = node->link; + node->link = NULL; + + /* remove node from mru list */ + ftc_node_mru_unlink( node, manager ); + + /* now finalize it */ + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + + cache->clazz.node_free( node, cache ); + node = next; + } + cache->buckets[i] = NULL; + } + ftc_cache_resize( cache ); + } + } + + + FT_LOCAL_DEF( void ) + ftc_cache_done( FTC_Cache cache ) + { + if ( cache->memory ) + { + FT_Memory memory = cache->memory; + + + FTC_Cache_Clear( cache ); + + FT_FREE( cache->buckets ); + cache->mask = 0; + cache->p = 0; + cache->slack = 0; + + cache->memory = NULL; + } + } + + + FT_LOCAL_DEF( void ) + FTC_Cache_Done( FTC_Cache cache ) + { + ftc_cache_done( cache ); + } + + + static void + ftc_cache_add( FTC_Cache cache, + FT_PtrDist hash, + FTC_Node node ) + { + node->hash = hash; + node->cache_index = (FT_UInt16)cache->index; + node->ref_count = 0; + + ftc_node_hash_link( node, cache ); + ftc_node_mru_link( node, cache->manager ); + + { + FTC_Manager manager = cache->manager; + + + manager->cur_weight += cache->clazz.node_weight( node, cache ); + + if ( manager->cur_weight >= manager->max_weight ) + { + node->ref_count++; + FTC_Manager_Compress( manager ); + node->ref_count--; + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + FTC_Cache_NewNode( FTC_Cache cache, + FT_PtrDist hash, + FT_Pointer query, + FTC_Node *anode ) + { + FT_Error error; + FTC_Node node; + + + /* + * We use the FTC_CACHE_TRYLOOP macros to support out-of-memory + * errors (OOM) correctly, i.e., by flushing the cache progressively + * in order to make more room. + */ + + FTC_CACHE_TRYLOOP( cache ) + { + error = cache->clazz.node_new( &node, query, cache ); + } + FTC_CACHE_TRYLOOP_END( NULL ); + + if ( error ) + node = NULL; + else + { + /* don't assume that the cache has the same number of buckets, since + * our allocation request might have triggered global cache flushing + */ + ftc_cache_add( cache, hash, node ); + } + + *anode = node; + return error; + } + + +#ifndef FTC_INLINE + + FT_LOCAL_DEF( FT_Error ) + FTC_Cache_Lookup( FTC_Cache cache, + FT_PtrDist hash, + FT_Pointer query, + FTC_Node *anode ) + { + FTC_Node* bucket; + FTC_Node* pnode; + FTC_Node node; + FT_Error error = FT_Err_Ok; + FT_Bool list_changed = FALSE; + + FTC_Node_CompareFunc compare = cache->clazz.node_compare; + + + if ( cache == NULL || anode == NULL ) + return FT_THROW( Invalid_Argument ); + + /* Go to the `top' node of the list sharing same masked hash */ + bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); + + /* Lookup a node with exactly same hash and queried properties. */ + /* NOTE: _nodcomp() may change the linked list to reduce memory. */ + for (;;) + { + node = *pnode; + if ( node == NULL ) + goto NewNode; + + if ( node->hash == hash && + compare( node, query, cache, &list_changed ) ) + break; + + pnode = &node->link; + } + + if ( list_changed ) + { + /* Update bucket by modified linked list */ + bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); + + /* Update pnode by modified linked list */ + while ( *pnode != node ) + { + if ( *pnode == NULL ) + { + FT_ERROR(( "FTC_Cache_Lookup: oops!!! node missing\n" )); + goto NewNode; + } + else + pnode = &((*pnode)->link); + } + } + + /* Reorder the list to move the found node to the `top' */ + if ( node != *bucket ) + { + *pnode = node->link; + node->link = *bucket; + *bucket = node; + } + + /* move to head of MRU list */ + { + FTC_Manager manager = cache->manager; + + + if ( node != manager->nodes_list ) + ftc_node_mru_up( node, manager ); + } + *anode = node; + + return error; + + NewNode: + return FTC_Cache_NewNode( cache, hash, query, anode ); + } + +#endif /* !FTC_INLINE */ + + + FT_LOCAL_DEF( void ) + FTC_Cache_RemoveFaceID( FTC_Cache cache, + FTC_FaceID face_id ) + { + FT_UFast i, count; + FTC_Manager manager = cache->manager; + FTC_Node frees = NULL; + + + count = cache->p + cache->mask + 1; + for ( i = 0; i < count; i++ ) + { + FTC_Node* bucket = cache->buckets + i; + FTC_Node* pnode = bucket; + + + for ( ;; ) + { + FTC_Node node = *pnode; + FT_Bool list_changed = FALSE; + + + if ( node == NULL ) + break; + + if ( cache->clazz.node_remove_faceid( node, face_id, + cache, &list_changed ) ) + { + *pnode = node->link; + node->link = frees; + frees = node; + } + else + pnode = &node->link; + } + } + + /* remove all nodes in the free list */ + while ( frees ) + { + FTC_Node node; + + + node = frees; + frees = node->link; + + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + ftc_node_mru_unlink( node, manager ); + + cache->clazz.node_free( node, cache ); + + cache->slack++; + } + + ftc_cache_resize( cache ); + } + + +/* END */ diff --git a/drivers/freetype/src/cache/ftccache.h b/drivers/freetype/src/cache/ftccache.h new file mode 100644 index 0000000000..4155f320e0 --- /dev/null +++ b/drivers/freetype/src/cache/ftccache.h @@ -0,0 +1,352 @@ +/***************************************************************************/ +/* */ +/* ftccache.h */ +/* */ +/* FreeType internal cache interface (specification). */ +/* */ +/* Copyright 2000-2007, 2009-2011, 2013 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 __FTCCACHE_H__ +#define __FTCCACHE_H__ + + +#include "ftcmru.h" + +FT_BEGIN_HEADER + +#define _FTC_FACE_ID_HASH( i ) \ + ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 ))) + + /* handle to cache object */ + typedef struct FTC_CacheRec_* FTC_Cache; + + /* handle to cache class */ + typedef const struct FTC_CacheClassRec_* FTC_CacheClass; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE NODE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each cache controls one or more cache nodes. Each node is part of */ + /* the global_lru list of the manager. Its `data' field however is used */ + /* as a reference count for now. */ + /* */ + /* A node can be anything, depending on the type of information held by */ + /* the cache. It can be an individual glyph image, a set of bitmaps */ + /* glyphs for a given size, some metrics, etc. */ + /* */ + /*************************************************************************/ + + /* structure size should be 20 bytes on 32-bits machines */ + typedef struct FTC_NodeRec_ + { + FTC_MruNodeRec mru; /* circular mru list pointer */ + FTC_Node link; /* used for hashing */ + FT_PtrDist hash; /* used for hashing too */ + FT_UShort cache_index; /* index of cache the node belongs to */ + FT_Short ref_count; /* reference count for this node */ + + } FTC_NodeRec; + + +#define FTC_NODE( x ) ( (FTC_Node)(x) ) +#define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) + +#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next ) +#define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) + +#ifdef FTC_INLINE +#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ + ( ( cache )->buckets + \ + ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \ + ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \ + : ( ( hash ) & ( cache )->mask ) ) ) +#else + FT_LOCAL( FTC_Node* ) + ftc_get_top_node_for_hash( FTC_Cache cache, + FT_PtrDist hash ); +#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ + ftc_get_top_node_for_hash( ( cache ), ( hash ) ) +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* initialize a new cache node */ + typedef FT_Error + (*FTC_Node_NewFunc)( FTC_Node *pnode, + FT_Pointer query, + FTC_Cache cache ); + + typedef FT_Offset + (*FTC_Node_WeightFunc)( FTC_Node node, + FTC_Cache cache ); + + /* compare a node to a given key pair */ + typedef FT_Bool + (*FTC_Node_CompareFunc)( FTC_Node node, + FT_Pointer key, + FTC_Cache cache, + FT_Bool* list_changed ); + + + typedef void + (*FTC_Node_FreeFunc)( FTC_Node node, + FTC_Cache cache ); + + typedef FT_Error + (*FTC_Cache_InitFunc)( FTC_Cache cache ); + + typedef void + (*FTC_Cache_DoneFunc)( FTC_Cache cache ); + + + typedef struct FTC_CacheClassRec_ + { + FTC_Node_NewFunc node_new; + FTC_Node_WeightFunc node_weight; + FTC_Node_CompareFunc node_compare; + FTC_Node_CompareFunc node_remove_faceid; + FTC_Node_FreeFunc node_free; + + FT_Offset cache_size; + FTC_Cache_InitFunc cache_init; + FTC_Cache_DoneFunc cache_done; + + } FTC_CacheClassRec; + + + /* each cache really implements a dynamic hash table to manage its nodes */ + typedef struct FTC_CacheRec_ + { + FT_UFast p; + FT_UFast mask; + FT_Long slack; + FTC_Node* buckets; + + FTC_CacheClassRec clazz; /* local copy, for speed */ + + FTC_Manager manager; + FT_Memory memory; + FT_UInt index; /* in manager's table */ + + FTC_CacheClass org_class; /* original class pointer */ + + } FTC_CacheRec; + + +#define FTC_CACHE( x ) ( (FTC_Cache)(x) ) +#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) + + + /* default cache initialize */ + FT_LOCAL( FT_Error ) + FTC_Cache_Init( FTC_Cache cache ); + + /* default cache finalizer */ + FT_LOCAL( void ) + FTC_Cache_Done( FTC_Cache cache ); + + /* Call this function to look up the cache. If no corresponding + * node is found, a new one is automatically created. This function + * is capable of flushing the cache adequately to make room for the + * new cache object. + */ + +#ifndef FTC_INLINE + FT_LOCAL( FT_Error ) + FTC_Cache_Lookup( FTC_Cache cache, + FT_PtrDist hash, + FT_Pointer query, + FTC_Node *anode ); +#endif + + FT_LOCAL( FT_Error ) + FTC_Cache_NewNode( FTC_Cache cache, + FT_PtrDist hash, + FT_Pointer query, + FTC_Node *anode ); + + /* Remove all nodes that relate to a given face_id. This is useful + * when un-installing fonts. Note that if a cache node relates to + * the face_id but is locked (i.e., has `ref_count > 0'), the node + * will _not_ be destroyed, but its internal face_id reference will + * be modified. + * + * The final result will be that the node will never come back + * in further lookup requests, and will be flushed on demand from + * the cache normally when its reference count reaches 0. + */ + FT_LOCAL( void ) + FTC_Cache_RemoveFaceID( FTC_Cache cache, + FTC_FaceID face_id ); + + +#ifdef FTC_INLINE + +#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ + FT_BEGIN_STMNT \ + FTC_Node *_bucket, *_pnode, _node; \ + FTC_Cache _cache = FTC_CACHE(cache); \ + FT_PtrDist _hash = (FT_PtrDist)(hash); \ + FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ + FT_Bool _list_changed = FALSE; \ + \ + \ + error = FT_Err_Ok; \ + node = NULL; \ + \ + /* Go to the `top' node of the list sharing same masked hash */ \ + _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ + \ + /* Look up a node with identical hash and queried properties. */ \ + /* NOTE: _nodcomp() may change the linked list to reduce memory. */ \ + for (;;) \ + { \ + _node = *_pnode; \ + if ( _node == NULL ) \ + goto _NewNode; \ + \ + if ( _node->hash == _hash && \ + _nodcomp( _node, query, _cache, &_list_changed ) ) \ + break; \ + \ + _pnode = &_node->link; \ + } \ + \ + if ( _list_changed ) \ + { \ + /* Update _bucket by possibly modified linked list */ \ + _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ + \ + /* Update _pnode by possibly modified linked list */ \ + while ( *_pnode != _node ) \ + { \ + if ( *_pnode == NULL ) \ + { \ + FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \ + goto _NewNode; \ + } \ + else \ + _pnode = &((*_pnode)->link); \ + } \ + } \ + \ + /* Reorder the list to move the found node to the `top' */ \ + if ( _node != *_bucket ) \ + { \ + *_pnode = _node->link; \ + _node->link = *_bucket; \ + *_bucket = _node; \ + } \ + \ + /* Update MRU list */ \ + { \ + FTC_Manager _manager = _cache->manager; \ + void* _nl = &_manager->nodes_list; \ + \ + \ + if ( _node != _manager->nodes_list ) \ + FTC_MruNode_Up( (FTC_MruNode*)_nl, \ + (FTC_MruNode)_node ); \ + } \ + goto _Ok; \ + \ + _NewNode: \ + error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ + \ + _Ok: \ + node = _node; \ + FT_END_STMNT + +#else /* !FTC_INLINE */ + +#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ + FT_BEGIN_STMNT \ + error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, \ + (FTC_Node*)&(node) ); \ + FT_END_STMNT + +#endif /* !FTC_INLINE */ + + + /* + * This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry + * loop to flush the cache repeatedly in case of memory overflows. + * + * It is used when creating a new cache node, or within a lookup + * that needs to allocate data (e.g. the sbit cache lookup). + * + * Example: + * + * { + * FTC_CACHE_TRYLOOP( cache ) + * error = load_data( ... ); + * FTC_CACHE_TRYLOOP_END() + * } + * + */ +#define FTC_CACHE_TRYLOOP( cache ) \ + { \ + FTC_Manager _try_manager = FTC_CACHE( cache )->manager; \ + FT_UInt _try_count = 4; \ + \ + \ + for (;;) \ + { \ + FT_UInt _try_done; + + +#define FTC_CACHE_TRYLOOP_END( list_changed ) \ + if ( !error || FT_ERR_NEQ( error, Out_Of_Memory ) ) \ + break; \ + \ + _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ + if ( _try_done > 0 && ( list_changed ) ) \ + *(FT_Bool*)( list_changed ) = TRUE; \ + \ + if ( _try_done == 0 ) \ + break; \ + \ + if ( _try_done == _try_count ) \ + { \ + _try_count *= 2; \ + if ( _try_count < _try_done || \ + _try_count > _try_manager->num_nodes ) \ + _try_count = _try_manager->num_nodes; \ + } \ + } \ + } + + /* */ + +FT_END_HEADER + + +#endif /* __FTCCACHE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cache/ftccback.h b/drivers/freetype/src/cache/ftccback.h new file mode 100644 index 0000000000..9528279273 --- /dev/null +++ b/drivers/freetype/src/cache/ftccback.h @@ -0,0 +1,91 @@ +/***************************************************************************/ +/* */ +/* ftccback.h */ +/* */ +/* Callback functions of the caching sub-system (specification only). */ +/* */ +/* Copyright 2004-2006, 2011, 2013 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 __FTCCBACK_H__ +#define __FTCCBACK_H__ + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcmru.h" +#include "ftcimage.h" +#include "ftcmanag.h" +#include "ftcglyph.h" +#include "ftcsbits.h" + + + FT_LOCAL( void ) + ftc_inode_free( FTC_Node inode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + ftc_inode_new( FTC_Node *pinode, + FT_Pointer gquery, + FTC_Cache cache ); + + FT_LOCAL( FT_Offset ) + ftc_inode_weight( FTC_Node inode, + FTC_Cache cache ); + + + FT_LOCAL( void ) + ftc_snode_free( FTC_Node snode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + ftc_snode_new( FTC_Node *psnode, + FT_Pointer gquery, + FTC_Cache cache ); + + FT_LOCAL( FT_Offset ) + ftc_snode_weight( FTC_Node snode, + FTC_Cache cache ); + + FT_LOCAL( FT_Bool ) + ftc_snode_compare( FTC_Node snode, + FT_Pointer gquery, + FTC_Cache cache, + FT_Bool* list_changed ); + + + FT_LOCAL( FT_Bool ) + ftc_gnode_compare( FTC_Node gnode, + FT_Pointer gquery, + FTC_Cache cache, + FT_Bool* list_changed ); + + + FT_LOCAL( FT_Error ) + ftc_gcache_init( FTC_Cache cache ); + + FT_LOCAL( void ) + ftc_gcache_done( FTC_Cache cache ); + + + FT_LOCAL( FT_Error ) + ftc_cache_init( FTC_Cache cache ); + + FT_LOCAL( void ) + ftc_cache_done( FTC_Cache cache ); + + FT_LOCAL( void ) + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ); + + +#endif /* __FTCCBACK_H__ */ + +/* END */ diff --git a/drivers/freetype/src/cache/ftccmap.c b/drivers/freetype/src/cache/ftccmap.c new file mode 100644 index 0000000000..848349be2d --- /dev/null +++ b/drivers/freetype/src/cache/ftccmap.c @@ -0,0 +1,337 @@ +/***************************************************************************/ +/* */ +/* ftccmap.c */ +/* */ +/* FreeType CharMap cache (body) */ +/* */ +/* Copyright 2000-2013 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_FREETYPE_H +#include FT_CACHE_H +#include "ftcmanag.h" +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftccback.h" +#include "ftcerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + + + /*************************************************************************/ + /* */ + /* Each FTC_CMapNode contains a simple array to map a range of character */ + /* codes to equivalent glyph indices. */ + /* */ + /* For now, the implementation is very basic: Each node maps a range of */ + /* 128 consecutive character codes to their corresponding glyph indices. */ + /* */ + /* We could do more complex things, but I don't think it is really very */ + /* useful. */ + /* */ + /*************************************************************************/ + + + /* number of glyph indices / character code per node */ +#define FTC_CMAP_INDICES_MAX 128 + + /* compute a query/node hash */ +#define FTC_CMAP_HASH( faceid, index, charcode ) \ + ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ + ( (charcode) / FTC_CMAP_INDICES_MAX ) ) + + /* the charmap query */ + typedef struct FTC_CMapQueryRec_ + { + FTC_FaceID face_id; + FT_UInt cmap_index; + FT_UInt32 char_code; + + } FTC_CMapQueryRec, *FTC_CMapQuery; + +#define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) +#define FTC_CMAP_QUERY_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) + + /* the cmap cache node */ + typedef struct FTC_CMapNodeRec_ + { + FTC_NodeRec node; + FTC_FaceID face_id; + FT_UInt cmap_index; + FT_UInt32 first; /* first character in node */ + FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ + + } FTC_CMapNodeRec, *FTC_CMapNode; + +#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) +#define FTC_CMAP_NODE_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) + + /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ + /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ +#define FTC_CMAP_UNKNOWN (FT_UInt16)~0 + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CHARMAP NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( void ) + ftc_cmap_node_free( FTC_Node ftcnode, + FTC_Cache cache ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FT_Memory memory = cache->memory; + + + FT_FREE( node ); + } + + + /* initialize a new cmap node */ + FT_CALLBACK_DEF( FT_Error ) + ftc_cmap_node_new( FTC_Node *ftcanode, + FT_Pointer ftcquery, + FTC_Cache cache ) + { + FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode; + FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; + FT_Error error; + FT_Memory memory = cache->memory; + FTC_CMapNode node = NULL; + FT_UInt nn; + + + if ( !FT_NEW( node ) ) + { + node->face_id = query->face_id; + node->cmap_index = query->cmap_index; + node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * + FTC_CMAP_INDICES_MAX; + + for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) + node->indices[nn] = FTC_CMAP_UNKNOWN; + } + + *anode = node; + return error; + } + + + /* compute the weight of a given cmap node */ + FT_CALLBACK_DEF( FT_Offset ) + ftc_cmap_node_weight( FTC_Node cnode, + FTC_Cache cache ) + { + FT_UNUSED( cnode ); + FT_UNUSED( cache ); + + return sizeof ( *cnode ); + } + + + /* compare a cmap node to a given query */ + FT_CALLBACK_DEF( FT_Bool ) + ftc_cmap_node_compare( FTC_Node ftcnode, + FT_Pointer ftcquery, + FTC_Cache cache, + FT_Bool* list_changed ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; + FT_UNUSED( cache ); + + + if ( list_changed ) + *list_changed = FALSE; + if ( node->face_id == query->face_id && + node->cmap_index == query->cmap_index ) + { + FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); + + + return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); + } + + return 0; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_cmap_node_remove_faceid( FTC_Node ftcnode, + FT_Pointer ftcface_id, + FTC_Cache cache, + FT_Bool* list_changed ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + FT_UNUSED( cache ); + + + if ( list_changed ) + *list_changed = FALSE; + return FT_BOOL( node->face_id == face_id ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE CACHE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_TABLE_DEF + const FTC_CacheClassRec ftc_cmap_cache_class = + { + ftc_cmap_node_new, + ftc_cmap_node_weight, + ftc_cmap_node_compare, + ftc_cmap_node_remove_faceid, + ftc_cmap_node_free, + + sizeof ( FTC_CacheRec ), + ftc_cache_init, + ftc_cache_done, + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ) + { + return FTC_Manager_RegisterCache( manager, + &ftc_cmap_cache_class, + FTC_CACHE_P( acache ) ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, + FTC_FaceID face_id, + FT_Int cmap_index, + FT_UInt32 char_code ) + { + FTC_Cache cache = FTC_CACHE( cmap_cache ); + FTC_CMapQueryRec query; + FTC_Node node; + FT_Error error; + FT_UInt gindex = 0; + FT_PtrDist hash; + FT_Int no_cmap_change = 0; + + + if ( cmap_index < 0 ) + { + /* Treat a negative cmap index as a special value, meaning that you */ + /* don't want to change the FT_Face's character map through this */ + /* call. This can be useful if the face requester callback already */ + /* sets the face's charmap to the appropriate value. */ + + no_cmap_change = 1; + cmap_index = 0; + } + + if ( !cache ) + { + FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); + return 0; + } + + query.face_id = face_id; + query.cmap_index = (FT_UInt)cmap_index; + query.char_code = char_code; + + hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); + +#if 1 + FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, + node, error ); +#else + error = FTC_Cache_Lookup( cache, hash, &query, &node ); +#endif + if ( error ) + goto Exit; + + FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < + FTC_CMAP_INDICES_MAX ); + + /* something rotten can happen with rogue clients */ + if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= + FTC_CMAP_INDICES_MAX ) ) + return 0; /* XXX: should return appropriate error */ + + gindex = FTC_CMAP_NODE( node )->indices[char_code - + FTC_CMAP_NODE( node )->first]; + if ( gindex == FTC_CMAP_UNKNOWN ) + { + FT_Face face; + + + gindex = 0; + + error = FTC_Manager_LookupFace( cache->manager, + FTC_CMAP_NODE( node )->face_id, + &face ); + if ( error ) + goto Exit; + +#ifdef FT_MAX_CHARMAP_CACHEABLE + /* something rotten can happen with rogue clients */ + if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE ) + return 0; /* XXX: should return appropriate error */ +#endif + + if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) + { + FT_CharMap old, cmap = NULL; + + + old = face->charmap; + cmap = face->charmaps[cmap_index]; + + if ( old != cmap && !no_cmap_change ) + FT_Set_Charmap( face, cmap ); + + gindex = FT_Get_Char_Index( face, char_code ); + + if ( old != cmap && !no_cmap_change ) + FT_Set_Charmap( face, old ); + } + + FTC_CMAP_NODE( node )->indices[char_code - + FTC_CMAP_NODE( node )->first] + = (FT_UShort)gindex; + } + + Exit: + return gindex; + } + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcerror.h b/drivers/freetype/src/cache/ftcerror.h new file mode 100644 index 0000000000..0e055709bb --- /dev/null +++ b/drivers/freetype/src/cache/ftcerror.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* ftcerror.h */ +/* */ +/* Caching sub-system error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the caching sub-system error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FTCERROR_H__ +#define __FTCERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX FTC_Err_ +#define FT_ERR_BASE FT_Mod_Err_Cache + +#include FT_ERRORS_H + +#endif /* __FTCERROR_H__ */ + +/* END */ diff --git a/drivers/freetype/src/cache/ftcglyph.c b/drivers/freetype/src/cache/ftcglyph.c new file mode 100644 index 0000000000..441e177238 --- /dev/null +++ b/drivers/freetype/src/cache/ftcglyph.c @@ -0,0 +1,219 @@ +/***************************************************************************/ +/* */ +/* ftcglyph.c */ +/* */ +/* FreeType Glyph Image (FT_Glyph) cache (body). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2009, 2011 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_CACHE_H +#include "ftcglyph.h" +#include FT_ERRORS_H + +#include "ftccback.h" +#include "ftcerror.h" + + + /* create a new chunk node, setting its cache index and ref count */ + FT_LOCAL_DEF( void ) + FTC_GNode_Init( FTC_GNode gnode, + FT_UInt gindex, + FTC_Family family ) + { + gnode->family = family; + gnode->gindex = gindex; + family->num_nodes++; + } + + + FT_LOCAL_DEF( void ) + FTC_GNode_UnselectFamily( FTC_GNode gnode, + FTC_Cache cache ) + { + FTC_Family family = gnode->family; + + + gnode->family = NULL; + if ( family && --family->num_nodes == 0 ) + FTC_FAMILY_FREE( family, cache ); + } + + + FT_LOCAL_DEF( void ) + FTC_GNode_Done( FTC_GNode gnode, + FTC_Cache cache ) + { + /* finalize the node */ + gnode->gindex = 0; + + FTC_GNode_UnselectFamily( gnode, cache ); + } + + + FT_LOCAL_DEF( FT_Bool ) + ftc_gnode_compare( FTC_Node ftcgnode, + FT_Pointer ftcgquery, + FTC_Cache cache, + FT_Bool* list_changed ) + { + FTC_GNode gnode = (FTC_GNode)ftcgnode; + FTC_GQuery gquery = (FTC_GQuery)ftcgquery; + FT_UNUSED( cache ); + + + if ( list_changed ) + *list_changed = FALSE; + return FT_BOOL( gnode->family == gquery->family && + gnode->gindex == gquery->gindex ); + } + + +#ifdef FTC_INLINE + + FT_LOCAL_DEF( FT_Bool ) + FTC_GNode_Compare( FTC_GNode gnode, + FTC_GQuery gquery, + FTC_Cache cache, + FT_Bool* list_changed ) + { + return ftc_gnode_compare( FTC_NODE( gnode ), gquery, + cache, list_changed ); + } + +#endif + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CHUNK SETS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + FTC_Family_Init( FTC_Family family, + FTC_Cache cache ) + { + FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); + + + family->clazz = clazz->family_class; + family->num_nodes = 0; + family->cache = cache; + } + + + FT_LOCAL_DEF( FT_Error ) + ftc_gcache_init( FTC_Cache ftccache ) + { + FTC_GCache cache = (FTC_GCache)ftccache; + FT_Error error; + + + error = FTC_Cache_Init( FTC_CACHE( cache ) ); + if ( !error ) + { + FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; + + FTC_MruList_Init( &cache->families, + clazz->family_class, + 0, /* no maximum here! */ + cache, + FTC_CACHE( cache )->memory ); + } + + return error; + } + + +#if 0 + + FT_LOCAL_DEF( FT_Error ) + FTC_GCache_Init( FTC_GCache cache ) + { + return ftc_gcache_init( FTC_CACHE( cache ) ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( void ) + ftc_gcache_done( FTC_Cache ftccache ) + { + FTC_GCache cache = (FTC_GCache)ftccache; + + + FTC_Cache_Done( (FTC_Cache)cache ); + FTC_MruList_Done( &cache->families ); + } + + +#if 0 + + FT_LOCAL_DEF( void ) + FTC_GCache_Done( FTC_GCache cache ) + { + ftc_gcache_done( FTC_CACHE( cache ) ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_Error ) + FTC_GCache_New( FTC_Manager manager, + FTC_GCacheClass clazz, + FTC_GCache *acache ) + { + return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz, + (FTC_Cache*)acache ); + } + + +#ifndef FTC_INLINE + + FT_LOCAL_DEF( FT_Error ) + FTC_GCache_Lookup( FTC_GCache cache, + FT_PtrDist hash, + FT_UInt gindex, + FTC_GQuery query, + FTC_Node *anode ) + { + FT_Error error; + + + query->gindex = gindex; + + FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); + if ( !error ) + { + FTC_Family family = query->family; + + + /* prevent the family from being destroyed too early when an */ + /* out-of-memory condition occurs during glyph node initialization. */ + family->num_nodes++; + + error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); + + if ( --family->num_nodes == 0 ) + FTC_FAMILY_FREE( family, cache ); + } + return error; + } + +#endif /* !FTC_INLINE */ + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcglyph.h b/drivers/freetype/src/cache/ftcglyph.h new file mode 100644 index 0000000000..5fed19cb8f --- /dev/null +++ b/drivers/freetype/src/cache/ftcglyph.h @@ -0,0 +1,329 @@ +/***************************************************************************/ +/* */ +/* ftcglyph.h */ +/* */ +/* FreeType abstract glyph cache (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 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. */ +/* */ +/***************************************************************************/ + + + /* + * + * FTC_GCache is an _abstract_ cache object optimized to store glyph + * data. It works as follows: + * + * - It manages FTC_GNode objects. Each one of them can hold one or more + * glyph `items'. Item types are not specified in the FTC_GCache but + * in classes that extend it. + * + * - Glyph attributes, like face ID, character size, render mode, etc., + * can be grouped into abstract `glyph families'. This avoids storing + * the attributes within the FTC_GCache, since it is likely that many + * FTC_GNodes will belong to the same family in typical uses. + * + * - Each FTC_GNode is thus an FTC_Node with two additional fields: + * + * * gindex: A glyph index, or the first index in a glyph range. + * * family: A pointer to a glyph `family'. + * + * - Family types are not fully specific in the FTC_Family type, but + * by classes that extend it. + * + * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. + * They share an FTC_Family sub-class called FTC_BasicFamily which is + * used to store the following data: face ID, pixel/point sizes, load + * flags. For more details see the file `src/cache/ftcbasic.c'. + * + * Client applications can extend FTC_GNode with their own FTC_GNode + * and FTC_Family sub-classes to implement more complex caches (e.g., + * handling automatic synthesis, like obliquing & emboldening, colored + * glyphs, etc.). + * + * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and + * `ftcsbits.h', which both extend FTC_GCache with additional + * optimizations. + * + * A typical FTC_GCache implementation must provide at least the + * following: + * + * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: + * my_node_new (must call FTC_GNode_Init) + * my_node_free (must call FTC_GNode_Done) + * my_node_compare (must call FTC_GNode_Compare) + * my_node_remove_faceid (must call ftc_gnode_unselect in case + * of match) + * + * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: + * my_family_compare + * my_family_init + * my_family_reset (optional) + * my_family_done + * + * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query + * data. + * + * - Constant structures for a FTC_GNodeClass. + * + * - MyCacheNew() can be implemented easily as a call to the convenience + * function FTC_GCache_New. + * + * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will + * automatically: + * + * - Search for the corresponding family in the cache, or create + * a new one if necessary. Put it in FTC_GQUERY(myquery).family + * + * - Call FTC_Cache_Lookup. + * + * If it returns NULL, you should create a new node, then call + * ftc_cache_add as usual. + */ + + + /*************************************************************************/ + /* */ + /* Important: The functions defined in this file are only used to */ + /* implement an abstract glyph cache class. You need to */ + /* provide additional logic to implement a complete cache. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS BETA CODE. *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTCGLYPH_H__ +#define __FTCGLYPH_H__ + + +#include <ft2build.h> +#include "ftcmanag.h" + + +FT_BEGIN_HEADER + + + /* + * We can group glyphs into `families'. Each family correspond to a + * given face ID, character size, transform, etc. + * + * Families are implemented as MRU list nodes. They are + * reference-counted. + */ + + typedef struct FTC_FamilyRec_ + { + FTC_MruNodeRec mrunode; + FT_UInt num_nodes; /* current number of nodes in this family */ + FTC_Cache cache; + FTC_MruListClass clazz; + + } FTC_FamilyRec, *FTC_Family; + +#define FTC_FAMILY(x) ( (FTC_Family)(x) ) +#define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) + + + typedef struct FTC_GNodeRec_ + { + FTC_NodeRec node; + FTC_Family family; + FT_UInt gindex; + + } FTC_GNodeRec, *FTC_GNode; + +#define FTC_GNODE( x ) ( (FTC_GNode)(x) ) +#define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) + + + typedef struct FTC_GQueryRec_ + { + FT_UInt gindex; + FTC_Family family; + + } FTC_GQueryRec, *FTC_GQuery; + +#define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) + + + /*************************************************************************/ + /* */ + /* These functions are exported so that they can be called from */ + /* user-provided cache classes; otherwise, they are really part of the */ + /* cache sub-system internals. */ + /* */ + + /* must be called by derived FTC_Node_InitFunc routines */ + FT_LOCAL( void ) + FTC_GNode_Init( FTC_GNode node, + FT_UInt gindex, /* glyph index for node */ + FTC_Family family ); + +#ifdef FTC_INLINE + + /* returns TRUE iff the query's glyph index correspond to the node; */ + /* this assumes that the `family' and `hash' fields of the query are */ + /* already correctly set */ + FT_LOCAL( FT_Bool ) + FTC_GNode_Compare( FTC_GNode gnode, + FTC_GQuery gquery, + FTC_Cache cache, + FT_Bool* list_changed ); + +#endif + + /* call this function to clear a node's family -- this is necessary */ + /* to implement the `node_remove_faceid' cache method correctly */ + FT_LOCAL( void ) + FTC_GNode_UnselectFamily( FTC_GNode gnode, + FTC_Cache cache ); + + /* must be called by derived FTC_Node_DoneFunc routines */ + FT_LOCAL( void ) + FTC_GNode_Done( FTC_GNode node, + FTC_Cache cache ); + + + FT_LOCAL( void ) + FTC_Family_Init( FTC_Family family, + FTC_Cache cache ); + + typedef struct FTC_GCacheRec_ + { + FTC_CacheRec cache; + FTC_MruListRec families; + + } FTC_GCacheRec, *FTC_GCache; + +#define FTC_GCACHE( x ) ((FTC_GCache)(x)) + + +#if 0 + /* can be used as @FTC_Cache_InitFunc */ + FT_LOCAL( FT_Error ) + FTC_GCache_Init( FTC_GCache cache ); +#endif + + +#if 0 + /* can be used as @FTC_Cache_DoneFunc */ + FT_LOCAL( void ) + FTC_GCache_Done( FTC_GCache cache ); +#endif + + + /* the glyph cache class adds fields for the family implementation */ + typedef struct FTC_GCacheClassRec_ + { + FTC_CacheClassRec clazz; + FTC_MruListClass family_class; + + } FTC_GCacheClassRec; + + typedef const FTC_GCacheClassRec* FTC_GCacheClass; + +#define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) + +#define FTC_CACHE__GCACHE_CLASS( x ) \ + FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) +#define FTC_CACHE__FAMILY_CLASS( x ) \ + ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) + + + /* convenience function; use it instead of FTC_Manager_Register_Cache */ + FT_LOCAL( FT_Error ) + FTC_GCache_New( FTC_Manager manager, + FTC_GCacheClass clazz, + FTC_GCache *acache ); + +#ifndef FTC_INLINE + FT_LOCAL( FT_Error ) + FTC_GCache_Lookup( FTC_GCache cache, + FT_PtrDist hash, + FT_UInt gindex, + FTC_GQuery query, + FTC_Node *anode ); +#endif + + + /* */ + + +#define FTC_FAMILY_FREE( family, cache ) \ + FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \ + (FTC_MruNode)(family) ) + + +#ifdef FTC_INLINE + +#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ + gindex, query, node, error ) \ + FT_BEGIN_STMNT \ + FTC_GCache _gcache = FTC_GCACHE( cache ); \ + FTC_GQuery _gquery = (FTC_GQuery)( query ); \ + FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ + FTC_MruNode _mrunode; \ + \ + \ + _gquery->gindex = (gindex); \ + \ + FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ + _mrunode, error ); \ + _gquery->family = FTC_FAMILY( _mrunode ); \ + if ( !error ) \ + { \ + FTC_Family _gqfamily = _gquery->family; \ + \ + \ + _gqfamily->num_nodes++; \ + \ + FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ + \ + if ( --_gqfamily->num_nodes == 0 ) \ + FTC_FAMILY_FREE( _gqfamily, _gcache ); \ + } \ + FT_END_STMNT + /* */ + +#else /* !FTC_INLINE */ + +#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ + gindex, query, node, error ) \ + FT_BEGIN_STMNT \ + \ + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ + FTC_GQUERY( query ), &node ); \ + \ + FT_END_STMNT + +#endif /* !FTC_INLINE */ + + +FT_END_HEADER + + +#endif /* __FTCGLYPH_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcimage.c b/drivers/freetype/src/cache/ftcimage.c new file mode 100644 index 0000000000..c242ece021 --- /dev/null +++ b/drivers/freetype/src/cache/ftcimage.c @@ -0,0 +1,163 @@ +/***************************************************************************/ +/* */ +/* ftcimage.c */ +/* */ +/* FreeType Image cache (body). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2010 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_CACHE_H +#include "ftcimage.h" +#include FT_INTERNAL_MEMORY_H + +#include "ftccback.h" +#include "ftcerror.h" + + + /* finalize a given glyph image node */ + FT_LOCAL_DEF( void ) + ftc_inode_free( FTC_Node ftcinode, + FTC_Cache cache ) + { + FTC_INode inode = (FTC_INode)ftcinode; + FT_Memory memory = cache->memory; + + + if ( inode->glyph ) + { + FT_Done_Glyph( inode->glyph ); + inode->glyph = NULL; + } + + FTC_GNode_Done( FTC_GNODE( inode ), cache ); + FT_FREE( inode ); + } + + + FT_LOCAL_DEF( void ) + FTC_INode_Free( FTC_INode inode, + FTC_Cache cache ) + { + ftc_inode_free( FTC_NODE( inode ), cache ); + } + + + /* initialize a new glyph image node */ + FT_LOCAL_DEF( FT_Error ) + FTC_INode_New( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + FT_Error error; + FTC_INode inode = NULL; + + + if ( !FT_NEW( inode ) ) + { + FTC_GNode gnode = FTC_GNODE( inode ); + FTC_Family family = gquery->family; + FT_UInt gindex = gquery->gindex; + FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); + + + /* initialize its inner fields */ + FTC_GNode_Init( gnode, gindex, family ); + + /* we will now load the glyph image */ + error = clazz->family_load_glyph( family, gindex, cache, + &inode->glyph ); + if ( error ) + { + FTC_INode_Free( inode, cache ); + inode = NULL; + } + } + + *pinode = inode; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + ftc_inode_new( FTC_Node *ftcpinode, + FT_Pointer ftcgquery, + FTC_Cache cache ) + { + FTC_INode *pinode = (FTC_INode*)ftcpinode; + FTC_GQuery gquery = (FTC_GQuery)ftcgquery; + + + return FTC_INode_New( pinode, gquery, cache ); + } + + + FT_LOCAL_DEF( FT_Offset ) + ftc_inode_weight( FTC_Node ftcinode, + FTC_Cache ftccache ) + { + FTC_INode inode = (FTC_INode)ftcinode; + FT_Offset size = 0; + FT_Glyph glyph = inode->glyph; + + FT_UNUSED( ftccache ); + + + switch ( glyph->format ) + { + case FT_GLYPH_FORMAT_BITMAP: + { + FT_BitmapGlyph bitg; + + + bitg = (FT_BitmapGlyph)glyph; + size = bitg->bitmap.rows * ft_labs( bitg->bitmap.pitch ) + + sizeof ( *bitg ); + } + break; + + case FT_GLYPH_FORMAT_OUTLINE: + { + FT_OutlineGlyph outg; + + + outg = (FT_OutlineGlyph)glyph; + size = outg->outline.n_points * + ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + + outg->outline.n_contours * sizeof ( FT_Short ) + + sizeof ( *outg ); + } + break; + + default: + ; + } + + size += sizeof ( *inode ); + return size; + } + + +#if 0 + + FT_LOCAL_DEF( FT_Offset ) + FTC_INode_Weight( FTC_INode inode ) + { + return ftc_inode_weight( FTC_NODE( inode ), NULL ); + } + +#endif /* 0 */ + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcimage.h b/drivers/freetype/src/cache/ftcimage.h new file mode 100644 index 0000000000..20d5d3e07d --- /dev/null +++ b/drivers/freetype/src/cache/ftcimage.h @@ -0,0 +1,107 @@ +/***************************************************************************/ +/* */ +/* ftcimage.h */ +/* */ +/* FreeType Generic Image cache (specification) */ +/* */ +/* Copyright 2000-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, */ +/* 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. */ +/* */ +/***************************************************************************/ + + + /* + * FTC_ICache is an _abstract_ cache used to store a single FT_Glyph + * image per cache node. + * + * FTC_ICache extends FTC_GCache. For an implementation example, + * see FTC_ImageCache in `src/cache/ftbasic.c'. + */ + + + /*************************************************************************/ + /* */ + /* Each image cache really manages FT_Glyph objects. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCIMAGE_H__ +#define __FTCIMAGE_H__ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcglyph.h" + +FT_BEGIN_HEADER + + + /* the FT_Glyph image node type - we store only 1 glyph per node */ + typedef struct FTC_INodeRec_ + { + FTC_GNodeRec gnode; + FT_Glyph glyph; + + } FTC_INodeRec, *FTC_INode; + +#define FTC_INODE( x ) ( (FTC_INode)( x ) ) +#define FTC_INODE_GINDEX( x ) FTC_GNODE(x)->gindex +#define FTC_INODE_FAMILY( x ) FTC_GNODE(x)->family + + typedef FT_Error + (*FTC_IFamily_LoadGlyphFunc)( FTC_Family family, + FT_UInt gindex, + FTC_Cache cache, + FT_Glyph *aglyph ); + + typedef struct FTC_IFamilyClassRec_ + { + FTC_MruListClassRec clazz; + FTC_IFamily_LoadGlyphFunc family_load_glyph; + + } FTC_IFamilyClassRec; + + typedef const FTC_IFamilyClassRec* FTC_IFamilyClass; + +#define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) + +#define FTC_CACHE__IFAMILY_CLASS( x ) \ + FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) + + + /* can be used as a @FTC_Node_FreeFunc */ + FT_LOCAL( void ) + FTC_INode_Free( FTC_INode inode, + FTC_Cache cache ); + + /* Can be used as @FTC_Node_NewFunc. `gquery.index' and `gquery.family' + * must be set correctly. This function will call the `family_load_glyph' + * method to load the FT_Glyph into the cache node. + */ + FT_LOCAL( FT_Error ) + FTC_INode_New( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ); + +#if 0 + /* can be used as @FTC_Node_WeightFunc */ + FT_LOCAL( FT_ULong ) + FTC_INode_Weight( FTC_INode inode ); +#endif + + + /* */ + +FT_END_HEADER + +#endif /* __FTCIMAGE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcmanag.c b/drivers/freetype/src/cache/ftcmanag.c new file mode 100644 index 0000000000..4eb2c5bfd6 --- /dev/null +++ b/drivers/freetype/src/cache/ftcmanag.c @@ -0,0 +1,693 @@ +/***************************************************************************/ +/* */ +/* ftcmanag.c */ +/* */ +/* FreeType Cache Manager (body). */ +/* */ +/* Copyright 2000-2006, 2008-2010, 2013 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_CACHE_H +#include "ftcmanag.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_SIZES_H + +#include "ftccback.h" +#include "ftcerror.h" + +#ifdef FT_CONFIG_OPTION_PIC +#error "cache system does not support PIC yet" +#endif + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + +#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) + + + static FT_Error + ftc_scaler_lookup_size( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ) + { + FT_Face face; + FT_Size size = NULL; + FT_Error error; + + + error = FTC_Manager_LookupFace( manager, scaler->face_id, &face ); + if ( error ) + goto Exit; + + error = FT_New_Size( face, &size ); + if ( error ) + goto Exit; + + FT_Activate_Size( size ); + + if ( scaler->pixel ) + error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); + else + error = FT_Set_Char_Size( face, scaler->width, scaler->height, + scaler->x_res, scaler->y_res ); + if ( error ) + { + FT_Done_Size( size ); + size = NULL; + } + + Exit: + *asize = size; + return error; + } + + + typedef struct FTC_SizeNodeRec_ + { + FTC_MruNodeRec node; + FT_Size size; + FTC_ScalerRec scaler; + + } FTC_SizeNodeRec, *FTC_SizeNode; + +#define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) ) + + + FT_CALLBACK_DEF( void ) + ftc_size_node_done( FTC_MruNode ftcnode, + FT_Pointer data ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FT_Size size = node->size; + FT_UNUSED( data ); + + + if ( size ) + FT_Done_Size( size ); + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_size_node_compare( FTC_MruNode ftcnode, + FT_Pointer ftcscaler ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FTC_Scaler scaler = (FTC_Scaler)ftcscaler; + FTC_Scaler scaler0 = &node->scaler; + + + if ( FTC_SCALER_COMPARE( scaler0, scaler ) ) + { + FT_Activate_Size( node->size ); + return 1; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_init( FTC_MruNode ftcnode, + FT_Pointer ftcscaler, + FT_Pointer ftcmanager ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FTC_Scaler scaler = (FTC_Scaler)ftcscaler; + FTC_Manager manager = (FTC_Manager)ftcmanager; + + + node->scaler = scaler[0]; + + return ftc_scaler_lookup_size( manager, scaler, &node->size ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_reset( FTC_MruNode ftcnode, + FT_Pointer ftcscaler, + FT_Pointer ftcmanager ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FTC_Scaler scaler = (FTC_Scaler)ftcscaler; + FTC_Manager manager = (FTC_Manager)ftcmanager; + + + FT_Done_Size( node->size ); + + node->scaler = scaler[0]; + + return ftc_scaler_lookup_size( manager, scaler, &node->size ); + } + + + FT_CALLBACK_TABLE_DEF + const FTC_MruListClassRec ftc_size_list_class = + { + sizeof ( FTC_SizeNodeRec ), + ftc_size_node_compare, + ftc_size_node_init, + ftc_size_node_reset, + ftc_size_node_done + }; + + + /* helper function used by ftc_face_node_done */ + static FT_Bool + ftc_size_node_compare_faceid( FTC_MruNode ftcnode, + FT_Pointer ftcface_id ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + + + return FT_BOOL( node->scaler.face_id == face_id ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ) + { + FT_Error error; + FTC_MruNode mrunode; + + + if ( asize == NULL ) + return FT_THROW( Invalid_Argument ); + + *asize = NULL; + + if ( !manager ) + return FT_THROW( Invalid_Cache_Handle ); + +#ifdef FTC_INLINE + + FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, + mrunode, error ); + +#else + error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode ); +#endif + + if ( !error ) + *asize = FTC_SIZE_NODE( mrunode )->size; + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FACE MRU IMPLEMENTATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct FTC_FaceNodeRec_ + { + FTC_MruNodeRec node; + FTC_FaceID face_id; + FT_Face face; + + } FTC_FaceNodeRec, *FTC_FaceNode; + +#define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) ) + + + FT_CALLBACK_DEF( FT_Error ) + ftc_face_node_init( FTC_MruNode ftcnode, + FT_Pointer ftcface_id, + FT_Pointer ftcmanager ) + { + FTC_FaceNode node = (FTC_FaceNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + FTC_Manager manager = (FTC_Manager)ftcmanager; + FT_Error error; + + + node->face_id = face_id; + + error = manager->request_face( face_id, + manager->library, + manager->request_data, + &node->face ); + if ( !error ) + { + /* destroy initial size object; it will be re-created later */ + if ( node->face->size ) + FT_Done_Size( node->face->size ); + } + + return error; + } + + + FT_CALLBACK_DEF( void ) + ftc_face_node_done( FTC_MruNode ftcnode, + FT_Pointer ftcmanager ) + { + FTC_FaceNode node = (FTC_FaceNode)ftcnode; + FTC_Manager manager = (FTC_Manager)ftcmanager; + + + /* we must begin by removing all scalers for the target face */ + /* from the manager's list */ + FTC_MruList_RemoveSelection( &manager->sizes, + ftc_size_node_compare_faceid, + node->face_id ); + + /* all right, we can discard the face now */ + FT_Done_Face( node->face ); + node->face = NULL; + node->face_id = NULL; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_face_node_compare( FTC_MruNode ftcnode, + FT_Pointer ftcface_id ) + { + FTC_FaceNode node = (FTC_FaceNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + + + return FT_BOOL( node->face_id == face_id ); + } + + + FT_CALLBACK_TABLE_DEF + const FTC_MruListClassRec ftc_face_list_class = + { + sizeof ( FTC_FaceNodeRec), + + ftc_face_node_compare, + ftc_face_node_init, + 0, /* FTC_MruNode_ResetFunc */ + ftc_face_node_done + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ) + { + FT_Error error; + FTC_MruNode mrunode; + + + if ( aface == NULL ) + return FT_THROW( Invalid_Argument ); + + *aface = NULL; + + if ( !manager ) + return FT_THROW( Invalid_Cache_Handle ); + + /* we break encapsulation for the sake of speed */ +#ifdef FTC_INLINE + + FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, + mrunode, error ); + +#else + error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode ); +#endif + + if ( !error ) + *aface = FTC_FACE_NODE( mrunode )->face; + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ) + { + FT_Error error; + FT_Memory memory; + FTC_Manager manager = 0; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + memory = library->memory; + + if ( FT_NEW( manager ) ) + goto Exit; + + if ( max_faces == 0 ) + max_faces = FTC_MAX_FACES_DEFAULT; + + if ( max_sizes == 0 ) + max_sizes = FTC_MAX_SIZES_DEFAULT; + + if ( max_bytes == 0 ) + max_bytes = FTC_MAX_BYTES_DEFAULT; + + manager->library = library; + manager->memory = memory; + manager->max_weight = max_bytes; + + manager->request_face = requester; + manager->request_data = req_data; + + FTC_MruList_Init( &manager->faces, + &ftc_face_list_class, + max_faces, + manager, + memory ); + + FTC_MruList_Init( &manager->sizes, + &ftc_size_list_class, + max_sizes, + manager, + memory ); + + *amanager = manager; + + Exit: + return error; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_Done( FTC_Manager manager ) + { + FT_Memory memory; + FT_UInt idx; + + + if ( !manager || !manager->library ) + return; + + memory = manager->memory; + + /* now discard all caches */ + for (idx = manager->num_caches; idx-- > 0; ) + { + FTC_Cache cache = manager->caches[idx]; + + + if ( cache ) + { + cache->clazz.cache_done( cache ); + FT_FREE( cache ); + manager->caches[idx] = NULL; + } + } + manager->num_caches = 0; + + /* discard faces and sizes */ + FTC_MruList_Done( &manager->sizes ); + FTC_MruList_Done( &manager->faces ); + + manager->library = NULL; + manager->memory = NULL; + + FT_FREE( manager ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_Reset( FTC_Manager manager ) + { + if ( manager ) + { + FTC_MruList_Reset( &manager->sizes ); + FTC_MruList_Reset( &manager->faces ); + } + + FTC_Manager_FlushN( manager, manager->num_nodes ); + } + + +#ifdef FT_DEBUG_ERROR + + static void + FTC_Manager_Check( FTC_Manager manager ) + { + FTC_Node node, first; + + + first = manager->nodes_list; + + /* check node weights */ + if ( first ) + { + FT_Offset weight = 0; + + + node = first; + + do + { + FTC_Cache cache = manager->caches[node->cache_index]; + + + if ( (FT_UInt)node->cache_index >= manager->num_caches ) + FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %ld\n", + node->cache_index )); + else + weight += cache->clazz.node_weight( node, cache ); + + node = FTC_NODE__NEXT( node ); + + } while ( node != first ); + + if ( weight != manager->cur_weight ) + FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", + manager->cur_weight, weight )); + } + + /* check circular list */ + if ( first ) + { + FT_UFast count = 0; + + + node = first; + do + { + count++; + node = FTC_NODE__NEXT( node ); + + } while ( node != first ); + + if ( count != manager->num_nodes ) + FT_TRACE0(( "FTC_Manager_Check:" + " invalid cache node count %d instead of %d\n", + manager->num_nodes, count )); + } + } + +#endif /* FT_DEBUG_ERROR */ + + + /* `Compress' the manager's data, i.e., get rid of old cache nodes */ + /* that are not referenced anymore in order to limit the total */ + /* memory used by the cache. */ + + /* documentation is in ftcmanag.h */ + + FT_LOCAL_DEF( void ) + FTC_Manager_Compress( FTC_Manager manager ) + { + FTC_Node node, first; + + + if ( !manager ) + return; + + first = manager->nodes_list; + +#ifdef FT_DEBUG_ERROR + FTC_Manager_Check( manager ); + + FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n", + manager->cur_weight, manager->max_weight, + manager->num_nodes )); +#endif + + if ( manager->cur_weight < manager->max_weight || first == NULL ) + return; + + /* go to last node -- it's a circular list */ + node = FTC_NODE__PREV( first ); + do + { + FTC_Node prev; + + + prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); + + if ( node->ref_count <= 0 ) + ftc_node_destroy( node, manager ); + + node = prev; + + } while ( node && manager->cur_weight > manager->max_weight ); + } + + + /* documentation is in ftcmanag.h */ + + FT_LOCAL_DEF( FT_Error ) + FTC_Manager_RegisterCache( FTC_Manager manager, + FTC_CacheClass clazz, + FTC_Cache *acache ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + FTC_Cache cache = NULL; + + + if ( manager && clazz && acache ) + { + FT_Memory memory = manager->memory; + + + if ( manager->num_caches >= FTC_MAX_CACHES ) + { + error = FT_THROW( Too_Many_Caches ); + FT_ERROR(( "FTC_Manager_RegisterCache:" + " too many registered caches\n" )); + goto Exit; + } + + if ( !FT_ALLOC( cache, clazz->cache_size ) ) + { + cache->manager = manager; + cache->memory = memory; + cache->clazz = clazz[0]; + cache->org_class = clazz; + + /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ + /* IF IT IS NOT SET CORRECTLY */ + cache->index = manager->num_caches; + + error = clazz->cache_init( cache ); + if ( error ) + { + clazz->cache_done( cache ); + FT_FREE( cache ); + goto Exit; + } + + manager->caches[manager->num_caches++] = cache; + } + } + + Exit: + if ( acache ) + *acache = cache; + return error; + } + + + FT_LOCAL_DEF( FT_UInt ) + FTC_Manager_FlushN( FTC_Manager manager, + FT_UInt count ) + { + FTC_Node first = manager->nodes_list; + FTC_Node node; + FT_UInt result; + + + /* try to remove `count' nodes from the list */ + if ( first == NULL ) /* empty list! */ + return 0; + + /* go to last node - it's a circular list */ + node = FTC_NODE__PREV(first); + for ( result = 0; result < count; ) + { + FTC_Node prev = FTC_NODE__PREV( node ); + + + /* don't touch locked nodes */ + if ( node->ref_count <= 0 ) + { + ftc_node_destroy( node, manager ); + result++; + } + + if ( node == first ) + break; + + node = prev; + } + return result; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ) + { + FT_UInt nn; + + /* this will remove all FTC_SizeNode that correspond to + * the face_id as well + */ + FTC_MruList_RemoveSelection( &manager->faces, + ftc_face_node_compare, + face_id ); + + for ( nn = 0; nn < manager->num_caches; nn++ ) + FTC_Cache_RemoveFaceID( manager->caches[nn], face_id ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ) + { + if ( node && (FT_UInt)node->cache_index < manager->num_caches ) + node->ref_count--; + } + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcmanag.h b/drivers/freetype/src/cache/ftcmanag.h new file mode 100644 index 0000000000..0aec33c584 --- /dev/null +++ b/drivers/freetype/src/cache/ftcmanag.h @@ -0,0 +1,175 @@ +/***************************************************************************/ +/* */ +/* ftcmanag.h */ +/* */ +/* FreeType Cache Manager (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2010, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A cache manager is in charge of the following: */ + /* */ + /* - Maintain a mapping between generic FTC_FaceIDs and live FT_Face */ + /* objects. The mapping itself is performed through a user-provided */ + /* callback. However, the manager maintains a small cache of FT_Face */ + /* and FT_Size objects in order to speed up things considerably. */ + /* */ + /* - Manage one or more cache objects. Each cache is in charge of */ + /* holding a varying number of `cache nodes'. Each cache node */ + /* represents a minimal amount of individually accessible cached */ + /* data. For example, a cache node can be an FT_Glyph image */ + /* containing a vector outline, or some glyph metrics, or anything */ + /* else. */ + /* */ + /* Each cache node has a certain size in bytes that is added to the */ + /* total amount of `cache memory' within the manager. */ + /* */ + /* All cache nodes are located in a global LRU list, where the oldest */ + /* node is at the tail of the list. */ + /* */ + /* Each node belongs to a single cache, and includes a reference */ + /* count to avoid destroying it (due to caching). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS BETA CODE. *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTCMANAG_H__ +#define __FTCMANAG_H__ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcmru.h" +#include "ftccache.h" + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + +#define FTC_MAX_FACES_DEFAULT 2 +#define FTC_MAX_SIZES_DEFAULT 4 +#define FTC_MAX_BYTES_DEFAULT 200000L /* ~200kByte by default */ + + /* maximum number of caches registered in a single manager */ +#define FTC_MAX_CACHES 16 + + + typedef struct FTC_ManagerRec_ + { + FT_Library library; + FT_Memory memory; + + FTC_Node nodes_list; + FT_Offset max_weight; + FT_Offset cur_weight; + FT_UInt num_nodes; + + FTC_Cache caches[FTC_MAX_CACHES]; + FT_UInt num_caches; + + FTC_MruListRec faces; + FTC_MruListRec sizes; + + FT_Pointer request_data; + FTC_Face_Requester request_face; + + } FTC_ManagerRec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Compress */ + /* */ + /* <Description> */ + /* This function is used to check the state of the cache manager if */ + /* its `num_bytes' field is greater than its `max_bytes' field. It */ + /* will flush as many old cache nodes as possible (ignoring cache */ + /* nodes with a non-zero reference count). */ + /* */ + /* <InOut> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* <Note> */ + /* Client applications should not call this function directly. It is */ + /* normally invoked by specific cache implementations. */ + /* */ + /* The reason this function is exported is to allow client-specific */ + /* cache classes. */ + /* */ + FT_LOCAL( void ) + FTC_Manager_Compress( FTC_Manager manager ); + + + /* try to flush `count' old nodes from the cache; return the number + * of really flushed nodes + */ + FT_LOCAL( FT_UInt ) + FTC_Manager_FlushN( FTC_Manager manager, + FT_UInt count ); + + + /* this must be used internally for the moment */ + FT_LOCAL( FT_Error ) + FTC_Manager_RegisterCache( FTC_Manager manager, + FTC_CacheClass clazz, + FTC_Cache *acache ); + + /* */ + +#define FTC_SCALER_COMPARE( a, b ) \ + ( (a)->face_id == (b)->face_id && \ + (a)->width == (b)->width && \ + (a)->height == (b)->height && \ + ((a)->pixel != 0) == ((b)->pixel != 0) && \ + ( (a)->pixel || \ + ( (a)->x_res == (b)->x_res && \ + (a)->y_res == (b)->y_res ) ) ) + +#define FTC_SCALER_HASH( q ) \ + ( _FTC_FACE_ID_HASH( (q)->face_id ) + \ + (q)->width + (q)->height*7 + \ + ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) ) + + /* */ + +FT_END_HEADER + +#endif /* __FTCMANAG_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcmru.c b/drivers/freetype/src/cache/ftcmru.c new file mode 100644 index 0000000000..dc8b4cc397 --- /dev/null +++ b/drivers/freetype/src/cache/ftcmru.c @@ -0,0 +1,357 @@ +/***************************************************************************/ +/* */ +/* ftcmru.c */ +/* */ +/* FreeType MRU support (body). */ +/* */ +/* Copyright 2003, 2004, 2006, 2009 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_CACHE_H +#include "ftcmru.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftcerror.h" + + + FT_LOCAL_DEF( void ) + FTC_MruNode_Prepend( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + + + if ( first ) + { + FTC_MruNode last = first->prev; + + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + + + do + { + if ( cnode == node ) + { + fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" ); + exit( 2 ); + } + cnode = cnode->next; + + } while ( cnode != first ); + } +#endif + + first->prev = node; + last->next = node; + node->next = first; + node->prev = last; + } + else + { + node->next = node; + node->prev = node; + } + *plist = node; + } + + + FT_LOCAL_DEF( void ) + FTC_MruNode_Up( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + + + FT_ASSERT( first != NULL ); + + if ( first != node ) + { + FTC_MruNode prev, next, last; + + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + do + { + if ( cnode == node ) + goto Ok; + cnode = cnode->next; + + } while ( cnode != first ); + + fprintf( stderr, "FTC_MruNode_Up: invalid action\n" ); + exit( 2 ); + Ok: + } +#endif + prev = node->prev; + next = node->next; + + prev->next = next; + next->prev = prev; + + last = first->prev; + + last->next = node; + first->prev = node; + + node->next = first; + node->prev = last; + + *plist = node; + } + } + + + FT_LOCAL_DEF( void ) + FTC_MruNode_Remove( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + FTC_MruNode prev, next; + + + FT_ASSERT( first != NULL ); + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + + + do + { + if ( cnode == node ) + goto Ok; + cnode = cnode->next; + + } while ( cnode != first ); + + fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" ); + exit( 2 ); + Ok: + } +#endif + + prev = node->prev; + next = node->next; + + prev->next = next; + next->prev = prev; + + if ( node == next ) + { + FT_ASSERT( first == node ); + FT_ASSERT( prev == node ); + + *plist = NULL; + } + else if ( node == first ) + *plist = next; + } + + + FT_LOCAL_DEF( void ) + FTC_MruList_Init( FTC_MruList list, + FTC_MruListClass clazz, + FT_UInt max_nodes, + FT_Pointer data, + FT_Memory memory ) + { + list->num_nodes = 0; + list->max_nodes = max_nodes; + list->nodes = NULL; + list->clazz = *clazz; + list->data = data; + list->memory = memory; + } + + + FT_LOCAL_DEF( void ) + FTC_MruList_Reset( FTC_MruList list ) + { + while ( list->nodes ) + FTC_MruList_Remove( list, list->nodes ); + + FT_ASSERT( list->num_nodes == 0 ); + } + + + FT_LOCAL_DEF( void ) + FTC_MruList_Done( FTC_MruList list ) + { + FTC_MruList_Reset( list ); + } + + +#ifndef FTC_INLINE + FT_LOCAL_DEF( FTC_MruNode ) + FTC_MruList_Find( FTC_MruList list, + FT_Pointer key ) + { + FTC_MruNode_CompareFunc compare = list->clazz.node_compare; + FTC_MruNode first, node; + + + first = list->nodes; + node = NULL; + + if ( first ) + { + node = first; + do + { + if ( compare( node, key ) ) + { + if ( node != first ) + FTC_MruNode_Up( &list->nodes, node ); + + return node; + } + + node = node->next; + + } while ( node != first); + } + + return NULL; + } +#endif + + FT_LOCAL_DEF( FT_Error ) + FTC_MruList_New( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ) + { + FT_Error error; + FTC_MruNode node = NULL; + FT_Memory memory = list->memory; + + + if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 ) + { + node = list->nodes->prev; + + FT_ASSERT( node ); + + if ( list->clazz.node_reset ) + { + FTC_MruNode_Up( &list->nodes, node ); + + error = list->clazz.node_reset( node, key, list->data ); + if ( !error ) + goto Exit; + } + + FTC_MruNode_Remove( &list->nodes, node ); + list->num_nodes--; + + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + } + else if ( FT_ALLOC( node, list->clazz.node_size ) ) + goto Exit; + + error = list->clazz.node_init( node, key, list->data ); + if ( error ) + goto Fail; + + FTC_MruNode_Prepend( &list->nodes, node ); + list->num_nodes++; + + Exit: + *anode = node; + return error; + + Fail: + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + + FT_FREE( node ); + goto Exit; + } + + +#ifndef FTC_INLINE + FT_LOCAL_DEF( FT_Error ) + FTC_MruList_Lookup( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ) + { + FTC_MruNode node; + + + node = FTC_MruList_Find( list, key ); + if ( node == NULL ) + return FTC_MruList_New( list, key, anode ); + + *anode = node; + return 0; + } +#endif /* FTC_INLINE */ + + FT_LOCAL_DEF( void ) + FTC_MruList_Remove( FTC_MruList list, + FTC_MruNode node ) + { + FTC_MruNode_Remove( &list->nodes, node ); + list->num_nodes--; + + { + FT_Memory memory = list->memory; + + + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + + FT_FREE( node ); + } + } + + + FT_LOCAL_DEF( void ) + FTC_MruList_RemoveSelection( FTC_MruList list, + FTC_MruNode_CompareFunc selection, + FT_Pointer key ) + { + FTC_MruNode first, node, next; + + + first = list->nodes; + while ( first && ( selection == NULL || selection( first, key ) ) ) + { + FTC_MruList_Remove( list, first ); + first = list->nodes; + } + + if ( first ) + { + node = first->next; + while ( node != first ) + { + next = node->next; + + if ( selection( node, key ) ) + FTC_MruList_Remove( list, node ); + + node = next; + } + } + } + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcmru.h b/drivers/freetype/src/cache/ftcmru.h new file mode 100644 index 0000000000..6fccf11781 --- /dev/null +++ b/drivers/freetype/src/cache/ftcmru.h @@ -0,0 +1,246 @@ +/***************************************************************************/ +/* */ +/* ftcmru.h */ +/* */ +/* Simple MRU list-cache (specification). */ +/* */ +/* Copyright 2000-2001, 2003-2006, 2010, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* An MRU is a list that cannot hold more than a certain number of */ + /* elements (`max_elements'). All elements in the list are sorted in */ + /* least-recently-used order, i.e., the `oldest' element is at the tail */ + /* of the list. */ + /* */ + /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ + /* the list is searched for an element with the corresponding key. If */ + /* it is found, the element is moved to the head of the list and is */ + /* returned. */ + /* */ + /* If no corresponding element is found, the lookup routine will try to */ + /* obtain a new element with the relevant key. If the list is already */ + /* full, the oldest element from the list is discarded and replaced by a */ + /* new one; a new element is added to the list otherwise. */ + /* */ + /* Note that it is possible to pre-allocate the element list nodes. */ + /* This is handy if `max_elements' is sufficiently small, as it saves */ + /* allocations/releases during the lookup process. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCMRU_H__ +#define __FTCMRU_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + +#define xxFT_DEBUG_ERROR +#define FTC_INLINE + +FT_BEGIN_HEADER + + typedef struct FTC_MruNodeRec_* FTC_MruNode; + + typedef struct FTC_MruNodeRec_ + { + FTC_MruNode next; + FTC_MruNode prev; + + } FTC_MruNodeRec; + + + FT_LOCAL( void ) + FTC_MruNode_Prepend( FTC_MruNode *plist, + FTC_MruNode node ); + + FT_LOCAL( void ) + FTC_MruNode_Up( FTC_MruNode *plist, + FTC_MruNode node ); + + FT_LOCAL( void ) + FTC_MruNode_Remove( FTC_MruNode *plist, + FTC_MruNode node ); + + + typedef struct FTC_MruListRec_* FTC_MruList; + + typedef struct FTC_MruListClassRec_ const * FTC_MruListClass; + + + typedef FT_Bool + (*FTC_MruNode_CompareFunc)( FTC_MruNode node, + FT_Pointer key ); + + typedef FT_Error + (*FTC_MruNode_InitFunc)( FTC_MruNode node, + FT_Pointer key, + FT_Pointer data ); + + typedef FT_Error + (*FTC_MruNode_ResetFunc)( FTC_MruNode node, + FT_Pointer key, + FT_Pointer data ); + + typedef void + (*FTC_MruNode_DoneFunc)( FTC_MruNode node, + FT_Pointer data ); + + + typedef struct FTC_MruListClassRec_ + { + FT_Offset node_size; + FTC_MruNode_CompareFunc node_compare; + FTC_MruNode_InitFunc node_init; + FTC_MruNode_ResetFunc node_reset; + FTC_MruNode_DoneFunc node_done; + + } FTC_MruListClassRec; + + typedef struct FTC_MruListRec_ + { + FT_UInt num_nodes; + FT_UInt max_nodes; + FTC_MruNode nodes; + FT_Pointer data; + FTC_MruListClassRec clazz; + FT_Memory memory; + + } FTC_MruListRec; + + + FT_LOCAL( void ) + FTC_MruList_Init( FTC_MruList list, + FTC_MruListClass clazz, + FT_UInt max_nodes, + FT_Pointer data, + FT_Memory memory ); + + FT_LOCAL( void ) + FTC_MruList_Reset( FTC_MruList list ); + + + FT_LOCAL( void ) + FTC_MruList_Done( FTC_MruList list ); + + + FT_LOCAL( FT_Error ) + FTC_MruList_New( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ); + + FT_LOCAL( void ) + FTC_MruList_Remove( FTC_MruList list, + FTC_MruNode node ); + + FT_LOCAL( void ) + FTC_MruList_RemoveSelection( FTC_MruList list, + FTC_MruNode_CompareFunc selection, + FT_Pointer key ); + + +#ifdef FTC_INLINE + +#define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \ + FT_BEGIN_STMNT \ + FTC_MruNode* _pfirst = &(list)->nodes; \ + FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ + FTC_MruNode _first, _node; \ + \ + \ + error = FT_Err_Ok; \ + _first = *(_pfirst); \ + _node = NULL; \ + \ + if ( _first ) \ + { \ + _node = _first; \ + do \ + { \ + if ( _compare( _node, (key) ) ) \ + { \ + if ( _node != _first ) \ + FTC_MruNode_Up( _pfirst, _node ); \ + \ + node = _node; \ + goto _MruOk; \ + } \ + _node = _node->next; \ + \ + } while ( _node != _first) ; \ + } \ + \ + error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ + _MruOk: \ + ; \ + FT_END_STMNT + +#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ + FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error ) + +#else /* !FTC_INLINE */ + + FT_LOCAL( FTC_MruNode ) + FTC_MruList_Find( FTC_MruList list, + FT_Pointer key ); + + FT_LOCAL( FT_Error ) + FTC_MruList_Lookup( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *pnode ); + +#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ + error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) + +#endif /* !FTC_INLINE */ + + +#define FTC_MRULIST_LOOP( list, node ) \ + FT_BEGIN_STMNT \ + FTC_MruNode _first = (list)->nodes; \ + \ + \ + if ( _first ) \ + { \ + FTC_MruNode _node = _first; \ + \ + \ + do \ + { \ + *(FTC_MruNode*)&(node) = _node; + + +#define FTC_MRULIST_LOOP_END() \ + _node = _node->next; \ + \ + } while ( _node != _first ); \ + } \ + FT_END_STMNT + + /* */ + +FT_END_HEADER + + +#endif /* __FTCMRU_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cache/ftcsbits.c b/drivers/freetype/src/cache/ftcsbits.c new file mode 100644 index 0000000000..6df1c19930 --- /dev/null +++ b/drivers/freetype/src/cache/ftcsbits.c @@ -0,0 +1,421 @@ +/***************************************************************************/ +/* */ +/* ftcsbits.c */ +/* */ +/* FreeType sbits manager (body). */ +/* */ +/* Copyright 2000-2006, 2009-2011, 2013 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_CACHE_H +#include "ftcsbits.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_ERRORS_H + +#include "ftccback.h" +#include "ftcerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SBIT CACHE NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + ftc_sbit_copy_bitmap( FTC_SBit sbit, + FT_Bitmap* bitmap, + FT_Memory memory ) + { + FT_Error error; + FT_Int pitch = bitmap->pitch; + FT_ULong size; + + + if ( pitch < 0 ) + pitch = -pitch; + + size = (FT_ULong)( pitch * bitmap->rows ); + + if ( !FT_ALLOC( sbit->buffer, size ) ) + FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); + + return error; + } + + + FT_LOCAL_DEF( void ) + ftc_snode_free( FTC_Node ftcsnode, + FTC_Cache cache ) + { + FTC_SNode snode = (FTC_SNode)ftcsnode; + FTC_SBit sbit = snode->sbits; + FT_UInt count = snode->count; + FT_Memory memory = cache->memory; + + + for ( ; count > 0; sbit++, count-- ) + FT_FREE( sbit->buffer ); + + FTC_GNode_Done( FTC_GNODE( snode ), cache ); + + FT_FREE( snode ); + } + + + FT_LOCAL_DEF( void ) + FTC_SNode_Free( FTC_SNode snode, + FTC_Cache cache ) + { + ftc_snode_free( FTC_NODE( snode ), cache ); + } + + + /* + * This function tries to load a small bitmap within a given FTC_SNode. + * Note that it returns a non-zero error code _only_ in the case of + * out-of-memory condition. For all other errors (e.g., corresponding + * to a bad font file), this function will mark the sbit as `unavailable' + * and return a value of 0. + * + * You should also read the comment within the @ftc_snode_compare + * function below to see how out-of-memory is handled during a lookup. + */ + static FT_Error + ftc_snode_load( FTC_SNode snode, + FTC_Manager manager, + FT_UInt gindex, + FT_ULong *asize ) + { + FT_Error error; + FTC_GNode gnode = FTC_GNODE( snode ); + FTC_Family family = gnode->family; + FT_Memory memory = manager->memory; + FT_Face face; + FTC_SBit sbit; + FTC_SFamilyClass clazz; + + + if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) + { + FT_ERROR(( "ftc_snode_load: invalid glyph index" )); + return FT_THROW( Invalid_Argument ); + } + + sbit = snode->sbits + ( gindex - gnode->gindex ); + clazz = (FTC_SFamilyClass)family->clazz; + + sbit->buffer = 0; + + error = clazz->family_load_glyph( family, gindex, manager, &face ); + if ( error ) + goto BadGlyph; + + { + FT_Int temp; + FT_GlyphSlot slot = face->glyph; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */ + + + if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) + { + FT_TRACE0(( "ftc_snode_load:" + " glyph loaded didn't return a bitmap\n" )); + goto BadGlyph; + } + + /* Check that our values fit into 8-bit containers! */ + /* If this is not the case, our bitmap is too large */ + /* and we will leave it as `missing' with sbit.buffer = 0 */ + +#define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) +#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) + + /* horizontal advance in pixels */ + xadvance = ( slot->advance.x + 32 ) >> 6; + yadvance = ( slot->advance.y + 32 ) >> 6; + + if ( !CHECK_BYTE( bitmap->rows ) || + !CHECK_BYTE( bitmap->width ) || + !CHECK_CHAR( bitmap->pitch ) || + !CHECK_CHAR( slot->bitmap_left ) || + !CHECK_CHAR( slot->bitmap_top ) || + !CHECK_CHAR( xadvance ) || + !CHECK_CHAR( yadvance ) ) + { + FT_TRACE2(( "ftc_snode_load:" + " glyph too large for small bitmap cache\n")); + goto BadGlyph; + } + + sbit->width = (FT_Byte)bitmap->width; + sbit->height = (FT_Byte)bitmap->rows; + sbit->pitch = (FT_Char)bitmap->pitch; + sbit->left = (FT_Char)slot->bitmap_left; + sbit->top = (FT_Char)slot->bitmap_top; + sbit->xadvance = (FT_Char)xadvance; + sbit->yadvance = (FT_Char)yadvance; + sbit->format = (FT_Byte)bitmap->pixel_mode; + sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); + + /* copy the bitmap into a new buffer -- ignore error */ + error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); + + /* now, compute size */ + if ( asize ) + *asize = FT_ABS( sbit->pitch ) * sbit->height; + + } /* glyph loading successful */ + + /* ignore the errors that might have occurred -- */ + /* we mark unloaded glyphs with `sbit.buffer == 0' */ + /* and `width == 255', `height == 0' */ + /* */ + if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) ) + { + BadGlyph: + sbit->width = 255; + sbit->height = 0; + sbit->buffer = NULL; + error = FT_Err_Ok; + if ( asize ) + *asize = 0; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + FTC_SNode_New( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + FT_Error error; + FTC_SNode snode = NULL; + FT_UInt gindex = gquery->gindex; + FTC_Family family = gquery->family; + + FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); + FT_UInt total; + FT_UInt node_count; + + + total = clazz->family_get_count( family, cache->manager ); + if ( total == 0 || gindex >= total ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( !FT_NEW( snode ) ) + { + FT_UInt count, start; + + + start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE ); + count = total - start; + if ( count > FTC_SBIT_ITEMS_PER_NODE ) + count = FTC_SBIT_ITEMS_PER_NODE; + + FTC_GNode_Init( FTC_GNODE( snode ), start, family ); + + snode->count = count; + for ( node_count = 0; node_count < count; node_count++ ) + { + snode->sbits[node_count].width = 255; + } + + error = ftc_snode_load( snode, + cache->manager, + gindex, + NULL ); + if ( error ) + { + FTC_SNode_Free( snode, cache ); + snode = NULL; + } + } + + Exit: + *psnode = snode; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + ftc_snode_new( FTC_Node *ftcpsnode, + FT_Pointer ftcgquery, + FTC_Cache cache ) + { + FTC_SNode *psnode = (FTC_SNode*)ftcpsnode; + FTC_GQuery gquery = (FTC_GQuery)ftcgquery; + + + return FTC_SNode_New( psnode, gquery, cache ); + } + + + FT_LOCAL_DEF( FT_Offset ) + ftc_snode_weight( FTC_Node ftcsnode, + FTC_Cache cache ) + { + FTC_SNode snode = (FTC_SNode)ftcsnode; + FT_UInt count = snode->count; + FTC_SBit sbit = snode->sbits; + FT_Int pitch; + FT_Offset size; + + FT_UNUSED( cache ); + + + FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE ); + + /* the node itself */ + size = sizeof ( *snode ); + + for ( ; count > 0; count--, sbit++ ) + { + if ( sbit->buffer ) + { + pitch = sbit->pitch; + if ( pitch < 0 ) + pitch = -pitch; + + /* add the size of a given glyph image */ + size += pitch * sbit->height; + } + } + + return size; + } + + +#if 0 + + FT_LOCAL_DEF( FT_Offset ) + FTC_SNode_Weight( FTC_SNode snode ) + { + return ftc_snode_weight( FTC_NODE( snode ), NULL ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_Bool ) + ftc_snode_compare( FTC_Node ftcsnode, + FT_Pointer ftcgquery, + FTC_Cache cache, + FT_Bool* list_changed ) + { + FTC_SNode snode = (FTC_SNode)ftcsnode; + FTC_GQuery gquery = (FTC_GQuery)ftcgquery; + FTC_GNode gnode = FTC_GNODE( snode ); + FT_UInt gindex = gquery->gindex; + FT_Bool result; + + + if (list_changed) + *list_changed = FALSE; + result = FT_BOOL( gnode->family == gquery->family && + (FT_UInt)( gindex - gnode->gindex ) < snode->count ); + if ( result ) + { + /* check if we need to load the glyph bitmap now */ + FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex ); + + + /* + * The following code illustrates what to do when you want to + * perform operations that may fail within a lookup function. + * + * Here, we want to load a small bitmap on-demand; we thus + * need to call the `ftc_snode_load' function which may return + * a non-zero error code only when we are out of memory (OOM). + * + * The correct thing to do is to use @FTC_CACHE_TRYLOOP and + * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop + * that is capable of flushing the cache incrementally when + * an OOM errors occur. + * + * However, we need to `lock' the node before this operation to + * prevent it from being flushed within the loop. + * + * When we exit the loop, we unlock the node, then check the `error' + * variable. If it is non-zero, this means that the cache was + * completely flushed and that no usable memory was found to load + * the bitmap. + * + * We then prefer to return a value of 0 (i.e., NO MATCH). This + * ensures that the caller will try to allocate a new node. + * This operation consequently _fail_ and the lookup function + * returns the appropriate OOM error code. + * + * Note that `buffer == NULL && width == 255' is a hack used to + * tag `unavailable' bitmaps in the array. We should never try + * to load these. + * + */ + + if ( sbit->buffer == NULL && sbit->width == 255 ) + { + FT_ULong size; + FT_Error error; + + + ftcsnode->ref_count++; /* lock node to prevent flushing */ + /* in retry loop */ + + FTC_CACHE_TRYLOOP( cache ) + { + error = ftc_snode_load( snode, cache->manager, gindex, &size ); + } + FTC_CACHE_TRYLOOP_END( list_changed ); + + ftcsnode->ref_count--; /* unlock the node */ + + if ( error ) + result = 0; + else + cache->manager->cur_weight += size; + } + } + + return result; + } + + +#ifdef FTC_INLINE + + FT_LOCAL_DEF( FT_Bool ) + FTC_SNode_Compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache, + FT_Bool* list_changed ) + { + return ftc_snode_compare( FTC_NODE( snode ), gquery, + cache, list_changed ); + } + +#endif + +/* END */ diff --git a/drivers/freetype/src/cache/ftcsbits.h b/drivers/freetype/src/cache/ftcsbits.h new file mode 100644 index 0000000000..df55dca806 --- /dev/null +++ b/drivers/freetype/src/cache/ftcsbits.h @@ -0,0 +1,103 @@ +/***************************************************************************/ +/* */ +/* ftcsbits.h */ +/* */ +/* A small-bitmap cache (specification). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2006, 2011 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 __FTCSBITS_H__ +#define __FTCSBITS_H__ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcglyph.h" + + +FT_BEGIN_HEADER + +#define FTC_SBIT_ITEMS_PER_NODE 16 + + typedef struct FTC_SNodeRec_ + { + FTC_GNodeRec gnode; + FT_UInt count; + FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; + + } FTC_SNodeRec, *FTC_SNode; + + +#define FTC_SNODE( x ) ( (FTC_SNode)( x ) ) +#define FTC_SNODE_GINDEX( x ) FTC_GNODE( x )->gindex +#define FTC_SNODE_FAMILY( x ) FTC_GNODE( x )->family + + typedef FT_UInt + (*FTC_SFamily_GetCountFunc)( FTC_Family family, + FTC_Manager manager ); + + typedef FT_Error + (*FTC_SFamily_LoadGlyphFunc)( FTC_Family family, + FT_UInt gindex, + FTC_Manager manager, + FT_Face *aface ); + + typedef struct FTC_SFamilyClassRec_ + { + FTC_MruListClassRec clazz; + FTC_SFamily_GetCountFunc family_get_count; + FTC_SFamily_LoadGlyphFunc family_load_glyph; + + } FTC_SFamilyClassRec; + + typedef const FTC_SFamilyClassRec* FTC_SFamilyClass; + +#define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) + +#define FTC_CACHE__SFAMILY_CLASS( x ) \ + FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) + + + FT_LOCAL( void ) + FTC_SNode_Free( FTC_SNode snode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + FTC_SNode_New( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ); + +#if 0 + FT_LOCAL( FT_ULong ) + FTC_SNode_Weight( FTC_SNode inode ); +#endif + + +#ifdef FTC_INLINE + + FT_LOCAL( FT_Bool ) + FTC_SNode_Compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache, + FT_Bool* list_changed); + +#endif + + /* */ + +FT_END_HEADER + +#endif /* __FTCSBITS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cache/rules.mk b/drivers/freetype/src/cache/rules.mk new file mode 100644 index 0000000000..ed75a6a91f --- /dev/null +++ b/drivers/freetype/src/cache/rules.mk @@ -0,0 +1,80 @@ +# +# FreeType 2 Cache configuration rules +# + + +# Copyright 2000, 2001, 2003, 2004, 2006, 2008 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. + + +# Cache driver directory +# +CACHE_DIR := $(SRC_DIR)/cache + +# compilation flags for the driver +# +CACHE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) + + +# Cache driver sources (i.e., C files) +# +CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ + $(CACHE_DIR)/ftccache.c \ + $(CACHE_DIR)/ftccmap.c \ + $(CACHE_DIR)/ftcglyph.c \ + $(CACHE_DIR)/ftcimage.c \ + $(CACHE_DIR)/ftcmanag.c \ + $(CACHE_DIR)/ftcmru.c \ + $(CACHE_DIR)/ftcsbits.c + +# Cache driver headers +# +CACHE_DRV_H := $(CACHE_DIR)/ftccache.h \ + $(CACHE_DIR)/ftccback.h \ + $(CACHE_DIR)/ftcerror.h \ + $(CACHE_DIR)/ftcglyph.h \ + $(CACHE_DIR)/ftcimage.h \ + $(CACHE_DIR)/ftcmanag.h \ + $(CACHE_DIR)/ftcmru.h \ + $(CACHE_DIR)/ftcsbits.h + + +# Cache driver object(s) +# +# CACHE_DRV_OBJ_M is used during `multi' builds. +# CACHE_DRV_OBJ_S is used during `single' builds. +# +CACHE_DRV_OBJ_M := $(CACHE_DRV_SRC:$(CACHE_DIR)/%.c=$(OBJ_DIR)/%.$O) +CACHE_DRV_OBJ_S := $(OBJ_DIR)/ftcache.$O + +# Cache driver source file for single build +# +CACHE_DRV_SRC_S := $(CACHE_DIR)/ftcache.c + + +# Cache driver - single object +# +$(CACHE_DRV_OBJ_S): $(CACHE_DRV_SRC_S) $(CACHE_DRV_SRC) \ + $(FREETYPE_H) $(CACHE_DRV_H) + $(CACHE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CACHE_DRV_SRC_S)) + + +# Cache driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(CACHE_DIR)/%.c $(FREETYPE_H) $(CACHE_DRV_H) + $(CACHE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(CACHE_DRV_OBJ_S) +DRV_OBJS_M += $(CACHE_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/cff/Jamfile b/drivers/freetype/src/cff/Jamfile new file mode 100644 index 0000000000..6705d3cfdb --- /dev/null +++ b/drivers/freetype/src/cff/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/cff Jamfile +# +# Copyright 2001, 2002 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) cff ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap cffpic ; + } + else + { + _sources = cff ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/cff Jamfile diff --git a/drivers/freetype/src/cff/cf2arrst.c b/drivers/freetype/src/cff/cf2arrst.c new file mode 100644 index 0000000000..c8d6f13098 --- /dev/null +++ b/drivers/freetype/src/cff/cf2arrst.c @@ -0,0 +1,241 @@ +/***************************************************************************/ +/* */ +/* cf2arrst.c */ +/* */ +/* Adobe's code for Array Stacks (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" +#include FT_INTERNAL_DEBUG_H + +#include "cf2glue.h" +#include "cf2arrst.h" + +#include "cf2error.h" + + + /* + * CF2_ArrStack uses an error pointer, to enable shared errors. + * Shared errors are necessary when multiple objects allow the program + * to continue after detecting errors. Only the first error should be + * recorded. + */ + + FT_LOCAL_DEF( void ) + cf2_arrstack_init( CF2_ArrStack arrstack, + FT_Memory memory, + FT_Error* error, + size_t sizeItem ) + { + FT_ASSERT( arrstack != NULL ); + + /* initialize the structure */ + arrstack->memory = memory; + arrstack->error = error; + arrstack->sizeItem = sizeItem; + arrstack->allocated = 0; + arrstack->chunk = 10; /* chunks of 10 items */ + arrstack->count = 0; + arrstack->totalSize = 0; + arrstack->ptr = NULL; + } + + + FT_LOCAL_DEF( void ) + cf2_arrstack_finalize( CF2_ArrStack arrstack ) + { + FT_Memory memory = arrstack->memory; /* for FT_FREE */ + + + FT_ASSERT( arrstack != NULL ); + + arrstack->allocated = 0; + arrstack->count = 0; + arrstack->totalSize = 0; + + /* free the data buffer */ + FT_FREE( arrstack->ptr ); + } + + + /* allocate or reallocate the buffer size; */ + /* return false on memory error */ + static FT_Bool + cf2_arrstack_setNumElements( CF2_ArrStack arrstack, + size_t numElements ) + { + FT_ASSERT( arrstack != NULL ); + + { + FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ + FT_Memory memory = arrstack->memory; /* for FT_REALLOC */ + + FT_Long newSize = (FT_Long)( numElements * arrstack->sizeItem ); + + + if ( numElements > LONG_MAX / arrstack->sizeItem ) + goto exit; + + + FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */ + + if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) ) + { + arrstack->allocated = numElements; + arrstack->totalSize = newSize; + + if ( arrstack->count > numElements ) + { + /* we truncated the list! */ + CF2_SET_ERROR( arrstack->error, Stack_Overflow ); + arrstack->count = numElements; + return FALSE; + } + + return TRUE; /* success */ + } + } + + exit: + /* if there's not already an error, store this one */ + CF2_SET_ERROR( arrstack->error, Out_Of_Memory ); + + return FALSE; + } + + + /* set the count, ensuring allocation is sufficient */ + FT_LOCAL_DEF( void ) + cf2_arrstack_setCount( CF2_ArrStack arrstack, + size_t numElements ) + { + FT_ASSERT( arrstack != NULL ); + + if ( numElements > arrstack->allocated ) + { + /* expand the allocation first */ + if ( !cf2_arrstack_setNumElements( arrstack, numElements ) ) + return; + } + + arrstack->count = numElements; + } + + + /* clear the count */ + FT_LOCAL_DEF( void ) + cf2_arrstack_clear( CF2_ArrStack arrstack ) + { + FT_ASSERT( arrstack != NULL ); + + arrstack->count = 0; + } + + + /* current number of items */ + FT_LOCAL_DEF( size_t ) + cf2_arrstack_size( const CF2_ArrStack arrstack ) + { + FT_ASSERT( arrstack != NULL ); + + return arrstack->count; + } + + + FT_LOCAL_DEF( void* ) + cf2_arrstack_getBuffer( const CF2_ArrStack arrstack ) + { + FT_ASSERT( arrstack != NULL ); + + return arrstack->ptr; + } + + + /* return pointer to the given element */ + FT_LOCAL_DEF( void* ) + cf2_arrstack_getPointer( const CF2_ArrStack arrstack, + size_t idx ) + { + void* newPtr; + + + FT_ASSERT( arrstack != NULL ); + + if ( idx >= arrstack->count ) + { + /* overflow */ + CF2_SET_ERROR( arrstack->error, Stack_Overflow ); + idx = 0; /* choose safe default */ + } + + newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem; + + return newPtr; + } + + + /* push (append) an element at the end of the list; */ + /* return false on memory error */ + /* TODO: should there be a length param for extra checking? */ + FT_LOCAL_DEF( void ) + cf2_arrstack_push( CF2_ArrStack arrstack, + const void* ptr ) + { + FT_ASSERT( arrstack != NULL ); + + if ( arrstack->count == arrstack->allocated ) + { + /* grow the buffer by one chunk */ + if ( !cf2_arrstack_setNumElements( + arrstack, arrstack->allocated + arrstack->chunk ) ) + { + /* on error, ignore the push */ + return; + } + } + + FT_ASSERT( ptr != NULL ); + + { + size_t offset = arrstack->count * arrstack->sizeItem; + void* newPtr = (FT_Byte*)arrstack->ptr + offset; + + + FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem ); + arrstack->count += 1; + } + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2arrst.h b/drivers/freetype/src/cff/cf2arrst.h new file mode 100644 index 0000000000..ff5ad8b126 --- /dev/null +++ b/drivers/freetype/src/cff/cf2arrst.h @@ -0,0 +1,100 @@ +/***************************************************************************/ +/* */ +/* cf2arrst.h */ +/* */ +/* Adobe's code for Array Stacks (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2ARRST_H__ +#define __CF2ARRST_H__ + + +#include "cf2error.h" + + +FT_BEGIN_HEADER + + + /* need to define the struct here (not opaque) so it can be allocated by */ + /* clients */ + typedef struct CF2_ArrStackRec_ + { + FT_Memory memory; + FT_Error* error; + + size_t sizeItem; /* bytes per element */ + size_t allocated; /* items allocated */ + size_t chunk; /* allocation increment in items */ + size_t count; /* number of elements allocated */ + size_t totalSize; /* total bytes allocated */ + + void* ptr; /* ptr to data */ + + } CF2_ArrStackRec, *CF2_ArrStack; + + + FT_LOCAL( void ) + cf2_arrstack_init( CF2_ArrStack arrstack, + FT_Memory memory, + FT_Error* error, + size_t sizeItem ); + FT_LOCAL( void ) + cf2_arrstack_finalize( CF2_ArrStack arrstack ); + + FT_LOCAL( void ) + cf2_arrstack_setCount( CF2_ArrStack arrstack, + size_t numElements ); + FT_LOCAL( void ) + cf2_arrstack_clear( CF2_ArrStack arrstack ); + FT_LOCAL( size_t ) + cf2_arrstack_size( const CF2_ArrStack arrstack ); + + FT_LOCAL( void* ) + cf2_arrstack_getBuffer( const CF2_ArrStack arrstack ); + FT_LOCAL( void* ) + cf2_arrstack_getPointer( const CF2_ArrStack arrstack, + size_t idx ); + + FT_LOCAL( void ) + cf2_arrstack_push( CF2_ArrStack arrstack, + const void* ptr ); + + +FT_END_HEADER + + +#endif /* __CF2ARRST_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2blues.c b/drivers/freetype/src/cff/cf2blues.c new file mode 100644 index 0000000000..5b348398af --- /dev/null +++ b/drivers/freetype/src/cff/cf2blues.c @@ -0,0 +1,578 @@ +/***************************************************************************/ +/* */ +/* cf2blues.c */ +/* */ +/* Adobe's code for handling Blue Zones (body). */ +/* */ +/* Copyright 2009-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" +#include FT_INTERNAL_DEBUG_H + +#include "cf2blues.h" +#include "cf2hints.h" +#include "cf2font.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_cf2blues + + + /* + * For blue values, the FreeType parser produces an array of integers, + * while the Adobe CFF engine produces an array of fixed. + * Define a macro to convert FreeType to fixed. + */ +#define cf2_blueToFixed( x ) cf2_intToFixed( x ) + + + FT_LOCAL_DEF( void ) + cf2_blues_init( CF2_Blues blues, + CF2_Font font ) + { + /* pointer to parsed font object */ + CFF_Decoder* decoder = font->decoder; + + CF2_Fixed zoneHeight; + CF2_Fixed maxZoneHeight = 0; + CF2_Fixed csUnitsPerPixel; + + size_t numBlueValues; + size_t numOtherBlues; + size_t numFamilyBlues; + size_t numFamilyOtherBlues; + + FT_Pos* blueValues; + FT_Pos* otherBlues; + FT_Pos* familyBlues; + FT_Pos* familyOtherBlues; + + size_t i; + CF2_Fixed emBoxBottom, emBoxTop; + + CF2_Int unitsPerEm = font->unitsPerEm; + + + if ( unitsPerEm == 0 ) + unitsPerEm = 1000; + + FT_ZERO( blues ); + blues->scale = font->innerTransform.d; + + cf2_getBlueMetrics( decoder, + &blues->blueScale, + &blues->blueShift, + &blues->blueFuzz ); + + cf2_getBlueValues( decoder, &numBlueValues, &blueValues ); + cf2_getOtherBlues( decoder, &numOtherBlues, &otherBlues ); + cf2_getFamilyBlues( decoder, &numFamilyBlues, &familyBlues ); + cf2_getFamilyOtherBlues( decoder, &numFamilyOtherBlues, &familyOtherBlues ); + + /* + * synthetic em box hint heuristic + * + * Apply this when ideographic dictionary (LanguageGroup 1) has no + * real alignment zones. Adobe tools generate dummy zones at -250 and + * 1100 for a 1000 unit em. Fonts with ICF-based alignment zones + * should not enable the heuristic. When the heuristic is enabled, + * the font's blue zones are ignored. + * + */ + + /* get em box from OS/2 typoAscender/Descender */ + /* TODO: FreeType does not parse these metrics. Skip them for now. */ +#if 0 + FCM_getHorizontalLineMetrics( &e, + font->font, + &ascender, + &descender, + &linegap ); + if ( ascender - descender == unitsPerEm ) + { + emBoxBottom = cf2_intToFixed( descender ); + emBoxTop = cf2_intToFixed( ascender ); + } + else +#endif + { + emBoxBottom = CF2_ICF_Bottom; + emBoxTop = CF2_ICF_Top; + } + + if ( cf2_getLanguageGroup( decoder ) == 1 && + ( numBlueValues == 0 || + ( numBlueValues == 4 && + cf2_blueToFixed( blueValues[0] ) < emBoxBottom && + cf2_blueToFixed( blueValues[1] ) < emBoxBottom && + cf2_blueToFixed( blueValues[2] ) > emBoxTop && + cf2_blueToFixed( blueValues[3] ) > emBoxTop ) ) ) + { + /* + * Construct hint edges suitable for synthetic ghost hints at top + * and bottom of em box. +-CF2_MIN_COUNTER allows for unhinted + * features above or below the last hinted edge. This also gives a + * net 1 pixel boost to the height of ideographic glyphs. + * + * Note: Adjust synthetic hints outward by epsilon (0x.0001) to + * avoid interference. E.g., some fonts have real hints at + * 880 and -120. + */ + + blues->emBoxBottomEdge.csCoord = emBoxBottom - CF2_FIXED_EPSILON; + blues->emBoxBottomEdge.dsCoord = cf2_fixedRound( + FT_MulFix( + blues->emBoxBottomEdge.csCoord, + blues->scale ) ) - + CF2_MIN_COUNTER; + blues->emBoxBottomEdge.scale = blues->scale; + blues->emBoxBottomEdge.flags = CF2_GhostBottom | + CF2_Locked | + CF2_Synthetic; + + blues->emBoxTopEdge.csCoord = emBoxTop + CF2_FIXED_EPSILON + + 2 * font->darkenY; + blues->emBoxTopEdge.dsCoord = cf2_fixedRound( + FT_MulFix( + blues->emBoxTopEdge.csCoord, + blues->scale ) ) + + CF2_MIN_COUNTER; + blues->emBoxTopEdge.scale = blues->scale; + blues->emBoxTopEdge.flags = CF2_GhostTop | + CF2_Locked | + CF2_Synthetic; + + blues->doEmBoxHints = TRUE; /* enable the heuristic */ + + return; + } + + /* copy `BlueValues' and `OtherBlues' to a combined array of top and */ + /* bottom zones */ + for ( i = 0; i < numBlueValues; i += 2 ) + { + blues->zone[blues->count].csBottomEdge = + cf2_blueToFixed( blueValues[i] ); + blues->zone[blues->count].csTopEdge = + cf2_blueToFixed( blueValues[i + 1] ); + + zoneHeight = blues->zone[blues->count].csTopEdge - + blues->zone[blues->count].csBottomEdge; + + if ( zoneHeight < 0 ) + { + FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" )); + continue; /* reject this zone */ + } + + if ( zoneHeight > maxZoneHeight ) + { + /* take maximum before darkening adjustment */ + /* so overshoot suppression point doesn't change */ + maxZoneHeight = zoneHeight; + } + + /* adjust both edges of top zone upward by twice darkening amount */ + if ( i != 0 ) + { + blues->zone[blues->count].csTopEdge += 2 * font->darkenY; + blues->zone[blues->count].csBottomEdge += 2 * font->darkenY; + } + + /* first `BlueValue' is bottom zone; others are top */ + if ( i == 0 ) + { + blues->zone[blues->count].bottomZone = + TRUE; + blues->zone[blues->count].csFlatEdge = + blues->zone[blues->count].csTopEdge; + } + else + { + blues->zone[blues->count].bottomZone = + FALSE; + blues->zone[blues->count].csFlatEdge = + blues->zone[blues->count].csBottomEdge; + } + + blues->count += 1; + } + + for ( i = 0; i < numOtherBlues; i += 2 ) + { + blues->zone[blues->count].csBottomEdge = + cf2_blueToFixed( otherBlues[i] ); + blues->zone[blues->count].csTopEdge = + cf2_blueToFixed( otherBlues[i + 1] ); + + zoneHeight = blues->zone[blues->count].csTopEdge - + blues->zone[blues->count].csBottomEdge; + + if ( zoneHeight < 0 ) + { + FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" )); + continue; /* reject this zone */ + } + + if ( zoneHeight > maxZoneHeight ) + { + /* take maximum before darkening adjustment */ + /* so overshoot suppression point doesn't change */ + maxZoneHeight = zoneHeight; + } + + /* Note: bottom zones are not adjusted for darkening amount */ + + /* all OtherBlues are bottom zone */ + blues->zone[blues->count].bottomZone = + TRUE; + blues->zone[blues->count].csFlatEdge = + blues->zone[blues->count].csTopEdge; + + blues->count += 1; + } + + /* Adjust for FamilyBlues */ + + /* Search for the nearest flat edge in `FamilyBlues' or */ + /* `FamilyOtherBlues'. According to the Black Book, any matching edge */ + /* must be within one device pixel */ + + csUnitsPerPixel = FT_DivFix( cf2_intToFixed( 1 ), blues->scale ); + + /* loop on all zones in this font */ + for ( i = 0; i < blues->count; i++ ) + { + size_t j; + CF2_Fixed minDiff; + CF2_Fixed flatFamilyEdge, diff; + /* value for this font */ + CF2_Fixed flatEdge = blues->zone[i].csFlatEdge; + + + if ( blues->zone[i].bottomZone ) + { + /* In a bottom zone, the top edge is the flat edge. */ + /* Search `FamilyOtherBlues' for bottom zones; look for closest */ + /* Family edge that is within the one pixel threshold. */ + + minDiff = CF2_FIXED_MAX; + + for ( j = 0; j < numFamilyOtherBlues; j += 2 ) + { + /* top edge */ + flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] ); + + diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); + + if ( diff < minDiff && diff < csUnitsPerPixel ) + { + blues->zone[i].csFlatEdge = flatFamilyEdge; + minDiff = diff; + + if ( diff == 0 ) + break; + } + } + + /* check the first member of FamilyBlues, which is a bottom zone */ + if ( numFamilyBlues >= 2 ) + { + /* top edge */ + flatFamilyEdge = cf2_blueToFixed( familyBlues[1] ); + + diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); + + if ( diff < minDiff && diff < csUnitsPerPixel ) + blues->zone[i].csFlatEdge = flatFamilyEdge; + } + } + else + { + /* In a top zone, the bottom edge is the flat edge. */ + /* Search `FamilyBlues' for top zones; skip first zone, which is a */ + /* bottom zone; look for closest Family edge that is within the */ + /* one pixel threshold */ + + minDiff = CF2_FIXED_MAX; + + for ( j = 2; j < numFamilyBlues; j += 2 ) + { + /* bottom edge */ + flatFamilyEdge = cf2_blueToFixed( familyBlues[j] ); + + /* adjust edges of top zone upward by twice darkening amount */ + flatFamilyEdge += 2 * font->darkenY; /* bottom edge */ + + diff = cf2_fixedAbs( flatEdge - flatFamilyEdge ); + + if ( diff < minDiff && diff < csUnitsPerPixel ) + { + blues->zone[i].csFlatEdge = flatFamilyEdge; + minDiff = diff; + + if ( diff == 0 ) + break; + } + } + } + } + + /* TODO: enforce separation of zones, including BlueFuzz */ + + /* Adjust BlueScale; similar to AdjustBlueScale() in coretype */ + /* `bcsetup.c'. */ + + if ( maxZoneHeight > 0 ) + { + if ( blues->blueScale > FT_DivFix( cf2_intToFixed( 1 ), + maxZoneHeight ) ) + { + /* clamp at maximum scale */ + blues->blueScale = FT_DivFix( cf2_intToFixed( 1 ), + maxZoneHeight ); + } + + /* + * TODO: Revisit the bug fix for 613448. The minimum scale + * requirement catches a number of library fonts. For + * example, with default BlueScale (.039625) and 0.4 minimum, + * the test below catches any font with maxZoneHeight < 10.1. + * There are library fonts ranging from 2 to 10 that get + * caught, including e.g., Eurostile LT Std Medium with + * maxZoneHeight of 6. + * + */ +#if 0 + if ( blueScale < .4 / maxZoneHeight ) + { + tetraphilia_assert( 0 ); + /* clamp at minimum scale, per bug 0613448 fix */ + blueScale = .4 / maxZoneHeight; + } +#endif + + } + + /* + * Suppress overshoot and boost blue zones at small sizes. Boost + * amount varies linearly from 0.5 pixel near 0 to 0 pixel at + * blueScale cutoff. + * Note: This boost amount is different from the coretype heuristic. + * + */ + + if ( blues->scale < blues->blueScale ) + { + blues->suppressOvershoot = TRUE; + + /* Change rounding threshold for `dsFlatEdge'. */ + /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */ + /* 10ppem Arial */ + + blues->boost = FT_MulFix( + cf2_floatToFixed( .6 ), + ( cf2_intToFixed( 1 ) - + FT_DivFix( blues->scale, + blues->blueScale ) ) ); + if ( blues->boost > 0x7FFF ) + { + /* boost must remain less than 0.5, or baseline could go negative */ + blues->boost = 0x7FFF; + } + } + + /* boost and darkening have similar effects; don't do both */ + if ( font->stemDarkened ) + blues->boost = 0; + + /* set device space alignment for each zone; */ + /* apply boost amount before rounding flat edge */ + + for ( i = 0; i < blues->count; i++ ) + { + if ( blues->zone[i].bottomZone ) + blues->zone[i].dsFlatEdge = cf2_fixedRound( + FT_MulFix( + blues->zone[i].csFlatEdge, + blues->scale ) - + blues->boost ); + else + blues->zone[i].dsFlatEdge = cf2_fixedRound( + FT_MulFix( + blues->zone[i].csFlatEdge, + blues->scale ) + + blues->boost ); + } + } + + + /* + * Check whether `stemHint' is captured by one of the blue zones. + * + * Zero, one or both edges may be valid; only valid edges can be + * captured. For compatibility with CoolType, search top and bottom + * zones in the same pass (see `BlueLock'). If a hint is captured, + * return true and position the edge(s) in one of 3 ways: + * + * 1) If `BlueScale' suppresses overshoot, position the captured edge + * at the flat edge of the zone. + * 2) If overshoot is not suppressed and `BlueShift' requires + * overshoot, position the captured edge a minimum of 1 device pixel + * from the flat edge. + * 3) If overshoot is not suppressed or required, position the captured + * edge at the nearest device pixel. + * + */ + FT_LOCAL_DEF( FT_Bool ) + cf2_blues_capture( const CF2_Blues blues, + CF2_Hint bottomHintEdge, + CF2_Hint topHintEdge ) + { + /* TODO: validate? */ + CF2_Fixed csFuzz = blues->blueFuzz; + + /* new position of captured edge */ + CF2_Fixed dsNew; + + /* amount that hint is moved when positioned */ + CF2_Fixed dsMove = 0; + + FT_Bool captured = FALSE; + CF2_UInt i; + + + /* assert edge flags are consistent */ + FT_ASSERT( !cf2_hint_isTop( bottomHintEdge ) && + !cf2_hint_isBottom( topHintEdge ) ); + + /* TODO: search once without blue fuzz for compatibility with coretype? */ + for ( i = 0; i < blues->count; i++ ) + { + if ( blues->zone[i].bottomZone && + cf2_hint_isBottom( bottomHintEdge ) ) + { + if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= + bottomHintEdge->csCoord && + bottomHintEdge->csCoord <= + ( blues->zone[i].csTopEdge + csFuzz ) ) + { + /* bottom edge captured by bottom zone */ + + if ( blues->suppressOvershoot ) + dsNew = blues->zone[i].dsFlatEdge; + + else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >= + blues->blueShift ) + { + /* guarantee minimum of 1 pixel overshoot */ + dsNew = FT_MIN( + cf2_fixedRound( bottomHintEdge->dsCoord ), + blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) ); + } + + else + { + /* simply round captured edge */ + dsNew = cf2_fixedRound( bottomHintEdge->dsCoord ); + } + + dsMove = dsNew - bottomHintEdge->dsCoord; + captured = TRUE; + + break; + } + } + + if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) ) + { + if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= + topHintEdge->csCoord && + topHintEdge->csCoord <= + ( blues->zone[i].csTopEdge + csFuzz ) ) + { + /* top edge captured by top zone */ + + if ( blues->suppressOvershoot ) + dsNew = blues->zone[i].dsFlatEdge; + + else if ( ( topHintEdge->csCoord - blues->zone[i].csBottomEdge ) >= + blues->blueShift ) + { + /* guarantee minimum of 1 pixel overshoot */ + dsNew = FT_MAX( + cf2_fixedRound( topHintEdge->dsCoord ), + blues->zone[i].dsFlatEdge + cf2_intToFixed( 1 ) ); + } + + else + { + /* simply round captured edge */ + dsNew = cf2_fixedRound( topHintEdge->dsCoord ); + } + + dsMove = dsNew - topHintEdge->dsCoord; + captured = TRUE; + + break; + } + } + } + + if ( captured ) + { + /* move both edges and flag them `locked' */ + if ( cf2_hint_isValid( bottomHintEdge ) ) + { + bottomHintEdge->dsCoord += dsMove; + cf2_hint_lock( bottomHintEdge ); + } + + if ( cf2_hint_isValid( topHintEdge ) ) + { + topHintEdge->dsCoord += dsMove; + cf2_hint_lock( topHintEdge ); + } + } + + return captured; + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2blues.h b/drivers/freetype/src/cff/cf2blues.h new file mode 100644 index 0000000000..2f38fcad8f --- /dev/null +++ b/drivers/freetype/src/cff/cf2blues.h @@ -0,0 +1,185 @@ +/***************************************************************************/ +/* */ +/* cf2blues.h */ +/* */ +/* Adobe's code for handling Blue Zones (specification). */ +/* */ +/* Copyright 2009-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + + /* + * A `CF2_Blues' object stores the blue zones (horizontal alignment + * zones) of a font. These are specified in the CFF private dictionary + * by `BlueValues', `OtherBlues', `FamilyBlues', and `FamilyOtherBlues'. + * Each zone is defined by a top and bottom edge in character space. + * Further, each zone is either a top zone or a bottom zone, as recorded + * by `bottomZone'. + * + * The maximum number of `BlueValues' and `FamilyBlues' is 7 each. + * However, these are combined to produce a total of 7 zones. + * Similarly, the maximum number of `OtherBlues' and `FamilyOtherBlues' + * is 5 and these are combined to produce an additional 5 zones. + * + * Blue zones are used to `capture' hints and force them to a common + * alignment point. This alignment is recorded in device space in + * `dsFlatEdge'. Except for this value, a `CF2_Blues' object could be + * constructed independently of scaling. Construction may occur once + * the matrix is known. Other features implemented in the Capture + * method are overshoot suppression, overshoot enforcement, and Blue + * Boost. + * + * Capture is determined by `BlueValues' and `OtherBlues', but the + * alignment point may be adjusted to the scaled flat edge of + * `FamilyBlues' or `FamilyOtherBlues'. No alignment is done to the + * curved edge of a zone. + * + */ + + +#ifndef __CF2BLUES_H__ +#define __CF2BLUES_H__ + + +#include "cf2glue.h" + + +FT_BEGIN_HEADER + + + /* + * `CF2_Hint' is shared by `cf2hints.h' and + * `cf2blues.h', but `cf2blues.h' depends on + * `cf2hints.h', so define it here. Note: The typedef is in + * `cf2glue.h'. + * + */ + enum + { + CF2_GhostBottom = 0x1, /* a single bottom edge */ + CF2_GhostTop = 0x2, /* a single top edge */ + CF2_PairBottom = 0x4, /* the bottom edge of a stem hint */ + CF2_PairTop = 0x8, /* the top edge of a stem hint */ + CF2_Locked = 0x10, /* this edge has been aligned */ + /* by a blue zone */ + CF2_Synthetic = 0x20 /* this edge was synthesized */ + }; + + + /* + * Default value for OS/2 typoAscender/Descender when their difference + * is not equal to `unitsPerEm'. The default is based on -250 and 1100 + * in `CF2_Blues', assuming 1000 units per em here. + * + */ + enum + { + CF2_ICF_Top = cf2_intToFixed( 880 ), + CF2_ICF_Bottom = cf2_intToFixed( -120 ) + }; + + + /* + * Constant used for hint adjustment and for synthetic em box hint + * placement. + */ +#define CF2_MIN_COUNTER cf2_floatToFixed( 0.5 ) + + + /* shared typedef is in cf2glue.h */ + struct CF2_HintRec_ + { + CF2_UInt flags; /* attributes of the edge */ + size_t index; /* index in original stem hint array */ + /* (if not synthetic) */ + CF2_Fixed csCoord; + CF2_Fixed dsCoord; + CF2_Fixed scale; + }; + + + typedef struct CF2_BlueRec_ + { + CF2_Fixed csBottomEdge; + CF2_Fixed csTopEdge; + CF2_Fixed csFlatEdge; /* may be from either local or Family zones */ + CF2_Fixed dsFlatEdge; /* top edge of bottom zone or bottom edge */ + /* of top zone (rounded) */ + FT_Bool bottomZone; + + } CF2_BlueRec; + + + /* max total blue zones is 12 */ + enum + { + CF2_MAX_BLUES = 7, + CF2_MAX_OTHERBLUES = 5 + }; + + + typedef struct CF2_BluesRec_ + { + CF2_Fixed scale; + CF2_UInt count; + FT_Bool suppressOvershoot; + FT_Bool doEmBoxHints; + + CF2_Fixed blueScale; + CF2_Fixed blueShift; + CF2_Fixed blueFuzz; + + CF2_Fixed boost; + + CF2_HintRec emBoxTopEdge; + CF2_HintRec emBoxBottomEdge; + + CF2_BlueRec zone[CF2_MAX_BLUES + CF2_MAX_OTHERBLUES]; + + } CF2_BluesRec, *CF2_Blues; + + + FT_LOCAL( void ) + cf2_blues_init( CF2_Blues blues, + CF2_Font font ); + FT_LOCAL( FT_Bool ) + cf2_blues_capture( const CF2_Blues blues, + CF2_Hint bottomHintEdge, + CF2_Hint topHintEdge ); + + +FT_END_HEADER + + +#endif /* __CF2BLUES_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2error.c b/drivers/freetype/src/cff/cf2error.c new file mode 100644 index 0000000000..b5595a3d1f --- /dev/null +++ b/drivers/freetype/src/cff/cf2error.c @@ -0,0 +1,52 @@ +/***************************************************************************/ +/* */ +/* cf2error.c */ +/* */ +/* Adobe's code for error handling (body). */ +/* */ +/* Copyright 2006-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" +#include "cf2error.h" + + + FT_LOCAL_DEF( void ) + cf2_setError( FT_Error* error, + FT_Error value ) + { + if ( error && *error == 0 ) + *error = value; + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2error.h b/drivers/freetype/src/cff/cf2error.h new file mode 100644 index 0000000000..6453ebcb7b --- /dev/null +++ b/drivers/freetype/src/cff/cf2error.h @@ -0,0 +1,119 @@ +/***************************************************************************/ +/* */ +/* cf2error.h */ +/* */ +/* Adobe's code for error handling (specification). */ +/* */ +/* Copyright 2006-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2ERROR_H__ +#define __CF2ERROR_H__ + + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX CF2_Err_ +#define FT_ERR_BASE FT_Mod_Err_CF2 + + +#include FT_ERRORS_H +#include "cf2ft.h" + + +FT_BEGIN_HEADER + + + /* + * A poor-man error facility. + * + * This code being written in vanilla C, doesn't have the luxury of a + * language-supported exception mechanism such as the one available in + * Java. Instead, we are stuck with using error codes that must be + * carefully managed and preserved. However, it is convenient for us to + * model our error mechanism on a Java-like exception mechanism. + * When we assign an error code we are thus `throwing' an error. + * + * The perservation of an error code is done by coding convention. + * Upon a function call if the error code is anything other than + * `FT_Err_Ok', which is guaranteed to be zero, we + * will return without altering that error. This will allow the + * error to propogate and be handled at the appropriate location in + * the code. + * + * This allows a style of code where the error code is initialized + * up front and a block of calls are made with the error code only + * being checked after the block. If a new error occurs, the original + * error will be preserved and a functional no-op should result in any + * subsequent function that has an initial error code not equal to + * `FT_Err_Ok'. + * + * Errors are encoded by calling the `FT_THROW' macro. For example, + * + * { + * FT_Error e; + * + * + * ... + * e = FT_THROW( Out_Of_Memory ); + * } + * + */ + + + /* Set error code to a particular value. */ + FT_LOCAL( void ) + cf2_setError( FT_Error* error, + FT_Error value ); + + + /* + * A macro that conditionally sets an error code. + * + * This macro will first check whether `error' is set; + * if not, it will set it to `e'. + * + */ +#define CF2_SET_ERROR( error, e ) \ + cf2_setError( error, FT_THROW( e ) ) + + +FT_END_HEADER + + +#endif /* __CF2ERROR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2fixed.h b/drivers/freetype/src/cff/cf2fixed.h new file mode 100644 index 0000000000..ed1452a7da --- /dev/null +++ b/drivers/freetype/src/cff/cf2fixed.h @@ -0,0 +1,95 @@ +/***************************************************************************/ +/* */ +/* cf2fixed.h */ +/* */ +/* Adobe's code for Fixed Point Mathematics (specification only). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2FIXED_H__ +#define __CF2FIXED_H__ + + +FT_BEGIN_HEADER + + + /* rasterizer integer and fixed point arithmetic must be 32-bit */ + +#define CF2_Fixed CF2_F16Dot16 + typedef FT_Int32 CF2_Frac; /* 2.30 fixed point */ + + +#define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL ) +#define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L ) +#define CF2_FIXED_ONE 0x10000L +#define CF2_FIXED_EPSILON 0x0001 + + /* in C 89, left and right shift of negative numbers is */ + /* implementation specific behaviour in the general case */ + +#define cf2_intToFixed( i ) \ + ( (CF2_Fixed)( (FT_UInt32)(i) << 16 ) ) +#define cf2_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) +#define cf2_fixedRound( x ) \ + ( (CF2_Fixed)( ( (x) + 0x8000 ) & 0xFFFF0000L ) ) +#define cf2_floatToFixed( f ) \ + ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) ) +#define cf2_fixedAbs( x ) \ + ( (x) < 0 ? -(x) : (x) ) +#define cf2_fixedFloor( x ) \ + ( (CF2_Fixed)( (x) & 0xFFFF0000L ) ) +#define cf2_fixedFraction( x ) \ + ( (x) - cf2_fixedFloor( x ) ) +#define cf2_fracToFixed( x ) \ + ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \ + : ( ( (x) + 0x2000 ) >> 14 ) ) + + + /* signed numeric types */ + typedef enum CF2_NumberType_ + { + CF2_NumberFixed, /* 16.16 */ + CF2_NumberFrac, /* 2.30 */ + CF2_NumberInt /* 32.0 */ + + } CF2_NumberType; + + +FT_END_HEADER + + +#endif /* __CF2FIXED_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2font.c b/drivers/freetype/src/cff/cf2font.c new file mode 100644 index 0000000000..479d9125d1 --- /dev/null +++ b/drivers/freetype/src/cff/cf2font.c @@ -0,0 +1,403 @@ +/***************************************************************************/ +/* */ +/* cf2font.c */ +/* */ +/* Adobe's code for font instances (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" + +#include "cf2glue.h" +#include "cf2font.h" +#include "cf2error.h" +#include "cf2intrp.h" + + + /* Compute a stem darkening amount in character space. */ + static void + cf2_computeDarkening( CF2_Fixed emRatio, + CF2_Fixed ppem, + CF2_Fixed stemWidth, + CF2_Fixed* darkenAmount, + CF2_Fixed boldenAmount, + FT_Bool stemDarkened ) + { + /* Internal calculations are done in units per thousand for */ + /* convenience. */ + CF2_Fixed stemWidthPer1000, scaledStem; + + + *darkenAmount = 0; + + if ( boldenAmount == 0 && !stemDarkened ) + return; + + /* protect against range problems and divide by zero */ + if ( emRatio < cf2_floatToFixed( .01 ) ) + return; + + if ( stemDarkened ) + { + /* convert from true character space to 1000 unit character space; */ + /* add synthetic emboldening effect */ + + /* we have to assure that the computation of `scaledStem' */ + /* and `stemWidthPer1000' don't overflow */ + + stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio ); + + if ( emRatio > CF2_FIXED_ONE && + stemWidthPer1000 <= ( stemWidth + boldenAmount ) ) + { + stemWidthPer1000 = 0; /* to pacify compiler */ + scaledStem = cf2_intToFixed( 2333 ); + } + else + { + scaledStem = FT_MulFix( stemWidthPer1000, ppem ); + + if ( ppem > CF2_FIXED_ONE && + scaledStem <= stemWidthPer1000 ) + scaledStem = cf2_intToFixed( 2333 ); + } + + /* + * Total darkening amount is computed in 1000 unit character space + * using the modified 5 part curve as Avalon rasterizer. + * The darkening amount is smaller for thicker stems. + * It becomes zero when the stem is thicker than 2.333 pixels. + * + * In Avalon rasterizer, + * + * darkenAmount = 0.5 pixels if scaledStem <= 0.5 pixels, + * darkenAmount = 0.333 pixels if 1 <= scaledStem <= 1.667 pixels, + * darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, + * + * and piecewise linear in-between. + * + */ + if ( scaledStem < cf2_intToFixed( 500 ) ) + *darkenAmount = FT_DivFix( cf2_intToFixed( 400 ), ppem ); + + else if ( scaledStem < cf2_intToFixed( 1000 ) ) + *darkenAmount = FT_DivFix( cf2_intToFixed( 525 ), ppem ) - + FT_MulFix( stemWidthPer1000, + cf2_floatToFixed( .25 ) ); + + else if ( scaledStem < cf2_intToFixed( 1667 ) ) + *darkenAmount = FT_DivFix( cf2_intToFixed( 275 ), ppem ); + + else if ( scaledStem < cf2_intToFixed( 2333 ) ) + *darkenAmount = FT_DivFix( cf2_intToFixed( 963 ), ppem ) - + FT_MulFix( stemWidthPer1000, + cf2_floatToFixed( .413 ) ); + + /* use half the amount on each side and convert back to true */ + /* character space */ + *darkenAmount = FT_DivFix( *darkenAmount, 2 * emRatio ); + } + + /* add synthetic emboldening effect in character space */ + *darkenAmount += boldenAmount / 2; + } + + + /* set up values for the current FontDict and matrix */ + + /* caller's transform is adjusted for subpixel positioning */ + static void + cf2_font_setup( CF2_Font font, + const CF2_Matrix* transform ) + { + /* pointer to parsed font object */ + CFF_Decoder* decoder = font->decoder; + + FT_Bool needExtraSetup; + + /* character space units */ + CF2_Fixed boldenX = font->syntheticEmboldeningAmountX; + CF2_Fixed boldenY = font->syntheticEmboldeningAmountY; + + CF2_Fixed ppem; + + + /* clear previous error */ + font->error = FT_Err_Ok; + + /* if a CID fontDict has changed, we need to recompute some cached */ + /* data */ + needExtraSetup = + (FT_Bool)( font->lastSubfont != cf2_getSubfont( decoder ) ); + + /* if ppem has changed, we need to recompute some cached data */ + /* note: because of CID font matrix concatenation, ppem and transform */ + /* do not necessarily track. */ + ppem = cf2_getPpemY( decoder ); + if ( font->ppem != ppem ) + { + font->ppem = ppem; + needExtraSetup = TRUE; + } + + /* copy hinted flag on each call */ + font->hinted = (FT_Bool)( font->renderingFlags & CF2_FlagsHinted ); + + /* determine if transform has changed; */ + /* include Fontmatrix but ignore translation */ + if ( ft_memcmp( transform, + &font->currentTransform, + 4 * sizeof ( CF2_Fixed ) ) != 0 ) + { + /* save `key' information for `cache of one' matrix data; */ + /* save client transform, without the translation */ + font->currentTransform = *transform; + font->currentTransform.tx = + font->currentTransform.ty = cf2_intToFixed( 0 ); + + /* TODO: FreeType transform is simple scalar; for now, use identity */ + /* for outer */ + font->innerTransform = *transform; + font->outerTransform.a = + font->outerTransform.d = cf2_intToFixed( 1 ); + font->outerTransform.b = + font->outerTransform.c = cf2_intToFixed( 0 ); + + needExtraSetup = TRUE; + } + + /* + * font->darkened is set to true if there is a stem darkening request or + * the font is synthetic emboldened. + * font->darkened controls whether to adjust blue zones, winding order, + * and hinting. + * + */ + if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) ) + { + font->stemDarkened = + (FT_Bool)( font->renderingFlags & CF2_FlagsDarkened ); + + /* blue zones depend on darkened flag */ + needExtraSetup = TRUE; + } + + /* recompute variables that are dependent on transform or FontDict or */ + /* darken flag */ + if ( needExtraSetup ) + { + /* StdVW is found in the private dictionary; */ + /* recompute darkening amounts whenever private dictionary or */ + /* transform change */ + /* Note: a rendering flag turns darkening on or off, so we want to */ + /* store the `on' amounts; */ + /* darkening amount is computed in character space */ + /* TODO: testing size-dependent darkening here; */ + /* what to do for rotations? */ + + CF2_Fixed emRatio; + CF2_Fixed stdHW; + CF2_Int unitsPerEm = font->unitsPerEm; + + + if ( unitsPerEm == 0 ) + unitsPerEm = 1000; + + ppem = FT_MAX( cf2_intToFixed( 4 ), + font->ppem ); /* use minimum ppem of 4 */ + +#if 0 + /* since vstem is measured in the x-direction, we use the `a' member */ + /* of the fontMatrix */ + emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a ); +#endif + + /* Freetype does not preserve the fontMatrix when parsing; use */ + /* unitsPerEm instead. */ + /* TODO: check precision of this */ + emRatio = cf2_intToFixed( 1000 ) / unitsPerEm; + font->stdVW = cf2_getStdVW( decoder ); + + if ( font->stdVW <= 0 ) + font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); + + if ( boldenX > 0 ) + { + /* Ensure that boldenX is at least 1 pixel for synthetic bold font */ + /* (similar to what Avalon does) */ + boldenX = FT_MAX( boldenX, + FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) ); + + /* Synthetic emboldening adds at least 1 pixel to darkenX, while */ + /* stem darkening adds at most half pixel. Since the purpose of */ + /* stem darkening (readability at small sizes) is met with */ + /* synthetic emboldening, no need to add stem darkening for a */ + /* synthetic bold font. */ + cf2_computeDarkening( emRatio, + ppem, + font->stdVW, + &font->darkenX, + boldenX, + FALSE ); + } + else + cf2_computeDarkening( emRatio, + ppem, + font->stdVW, + &font->darkenX, + 0, + font->stemDarkened ); + +#if 0 + /* since hstem is measured in the y-direction, we use the `d' member */ + /* of the fontMatrix */ + /* TODO: use the same units per em as above; check this */ + emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d ); +#endif + + /* set the default stem width, because it must be the same for all */ + /* family members; */ + /* choose a constant for StdHW that depends on font contrast */ + stdHW = cf2_getStdHW( decoder ); + + if ( stdHW > 0 && font->stdVW > 2 * stdHW ) + font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); + else + { + /* low contrast font gets less hstem darkening */ + font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio ); + } + + cf2_computeDarkening( emRatio, + ppem, + font->stdHW, + &font->darkenY, + boldenY, + font->stemDarkened ); + + if ( font->darkenX != 0 || font->darkenY != 0 ) + font->darkened = TRUE; + else + font->darkened = FALSE; + + font->reverseWinding = FALSE; /* initial expectation is CCW */ + + /* compute blue zones for this instance */ + cf2_blues_init( &font->blues, font ); + } + } + + + /* equivalent to AdobeGetOutline */ + FT_LOCAL_DEF( FT_Error ) + cf2_getGlyphOutline( CF2_Font font, + CF2_Buffer charstring, + const CF2_Matrix* transform, + CF2_F16Dot16* glyphWidth ) + { + FT_Error lastError = FT_Err_Ok; + + FT_Vector translation; + +#if 0 + FT_Vector advancePoint; +#endif + + CF2_Fixed advWidth = 0; + FT_Bool needWinding; + + + /* Note: use both integer and fraction for outlines. This allows bbox */ + /* to come out directly. */ + + translation.x = transform->tx; + translation.y = transform->ty; + + /* set up values based on transform */ + cf2_font_setup( font, transform ); + if ( font->error ) + goto exit; /* setup encountered an error */ + + /* reset darken direction */ + font->reverseWinding = FALSE; + + /* winding order only affects darkening */ + needWinding = font->darkened; + + while ( 1 ) + { + /* reset output buffer */ + cf2_outline_reset( &font->outline ); + + /* build the outline, passing the full translation */ + cf2_interpT2CharString( font, + charstring, + (CF2_OutlineCallbacks)&font->outline, + &translation, + FALSE, + 0, + 0, + &advWidth ); + + if ( font->error ) + goto exit; + + if ( !needWinding ) + break; + + /* check winding order */ + if ( font->outline.root.windingMomentum >= 0 ) /* CFF is CCW */ + break; + + /* invert darkening and render again */ + /* TODO: this should be a parameter to getOutline-computeOffset */ + font->reverseWinding = TRUE; + + needWinding = FALSE; /* exit after next iteration */ + } + + /* finish storing client outline */ + cf2_outline_close( &font->outline ); + + exit: + /* FreeType just wants the advance width; there is no translation */ + *glyphWidth = advWidth; + + /* free resources and collect errors from objects we've used */ + cf2_setError( &font->error, lastError ); + + return font->error; + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2font.h b/drivers/freetype/src/cff/cf2font.h new file mode 100644 index 0000000000..f9dd1bbd40 --- /dev/null +++ b/drivers/freetype/src/cff/cf2font.h @@ -0,0 +1,114 @@ +/***************************************************************************/ +/* */ +/* cf2font.h */ +/* */ +/* Adobe's code for font instances (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2FONT_H__ +#define __CF2FONT_H__ + + +#include "cf2ft.h" +#include "cf2blues.h" + + +FT_BEGIN_HEADER + + +#define CF2_OPERAND_STACK_SIZE 48 +#define CF2_MAX_SUBR 10 /* maximum subroutine nesting */ + + + /* typedef is in `cf2glue.h' */ + struct CF2_FontRec_ + { + FT_Memory memory; + FT_Error error; /* shared error for this instance */ + + CF2_RenderingFlags renderingFlags; + + /* variables that depend on Transform: */ + /* the following have zero translation; */ + /* inner * outer = font * original */ + + CF2_Matrix currentTransform; /* original client matrix */ + CF2_Matrix innerTransform; /* for hinting; erect, scaled */ + CF2_Matrix outerTransform; /* post hinting; includes rotations */ + CF2_Fixed ppem; /* transform-dependent */ + + CF2_Int unitsPerEm; + + CF2_Fixed syntheticEmboldeningAmountX; /* character space units */ + CF2_Fixed syntheticEmboldeningAmountY; /* character space units */ + + /* FreeType related members */ + CF2_OutlineRec outline; /* freetype glyph outline functions */ + CFF_Decoder* decoder; + CFF_SubFont lastSubfont; /* FreeType parsed data; */ + /* top font or subfont */ + + /* these flags can vary from one call to the next */ + FT_Bool hinted; + FT_Bool darkened; /* true if stemDarkened or synthetic bold */ + /* i.e. darkenX != 0 || darkenY != 0 */ + FT_Bool stemDarkened; + + /* variables that depend on both FontDict and Transform */ + CF2_Fixed stdVW; /* in character space; depends on dict entry */ + CF2_Fixed stdHW; /* in character space; depends on dict entry */ + CF2_Fixed darkenX; /* character space units */ + CF2_Fixed darkenY; /* depends on transform */ + /* and private dict (StdVW) */ + FT_Bool reverseWinding; /* darken assuming */ + /* counterclockwise winding */ + + CF2_BluesRec blues; /* computed zone data */ + }; + + + FT_LOCAL( FT_Error ) + cf2_getGlyphOutline( CF2_Font font, + CF2_Buffer charstring, + const CF2_Matrix* transform, + CF2_F16Dot16* glyphWidth ); + + +FT_END_HEADER + + +#endif /* __CF2FONT_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2ft.c b/drivers/freetype/src/cff/cf2ft.c new file mode 100644 index 0000000000..c09a0244a8 --- /dev/null +++ b/drivers/freetype/src/cff/cf2ft.c @@ -0,0 +1,639 @@ +/***************************************************************************/ +/* */ +/* cf2ft.c */ +/* */ +/* FreeType Glue Component to Adobe's Interpreter (body). */ +/* */ +/* Copyright 2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" +#include FT_INTERNAL_DEBUG_H + +#include "cf2font.h" +#include "cf2error.h" + + +#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */ + + + /* + * This check should avoid most internal overflow cases. Clients should + * generally respond to `Glyph_Too_Big' by getting a glyph outline + * at EM size, scaling it and filling it as a graphics operation. + * + */ + static FT_Error + cf2_checkTransform( const CF2_Matrix* transform, + CF2_Int unitsPerEm ) + { + CF2_Fixed maxScale; + + + FT_ASSERT( unitsPerEm > 0 ); + + FT_ASSERT( transform->a > 0 && transform->d > 0 ); + FT_ASSERT( transform->b == 0 && transform->c == 0 ); + FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); + + if ( unitsPerEm > 0x7FFF ) + return FT_THROW( Glyph_Too_Big ); + + maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) ); + + if ( transform->a > maxScale || transform->d > maxScale ) + return FT_THROW( Glyph_Too_Big ); + + return FT_Err_Ok; + } + + + static void + cf2_setGlyphWidth( CF2_Outline outline, + CF2_Fixed width ) + { + CFF_Decoder* decoder = outline->decoder; + + + FT_ASSERT( decoder ); + + decoder->glyph_width = cf2_fixedToInt( width ); + } + + + /* Clean up font instance. */ + static void + cf2_free_instance( void* ptr ) + { + CF2_Font font = (CF2_Font)ptr; + + + if ( font ) + { + FT_Memory memory = font->memory; + + + (void)memory; + } + } + + + /********************************************/ + /* */ + /* functions for handling client outline; */ + /* FreeType uses coordinates in 26.6 format */ + /* */ + /********************************************/ + + static void + cf2_builder_moveTo( CF2_OutlineCallbacks callbacks, + const CF2_CallbackParams params ) + { + /* downcast the object pointer */ + CF2_Outline outline = (CF2_Outline)callbacks; + CFF_Builder* builder; + + (void)params; /* only used in debug mode */ + + + FT_ASSERT( outline && outline->decoder ); + FT_ASSERT( params->op == CF2_PathOpMoveTo ); + + builder = &outline->decoder->builder; + + /* note: two successive moves simply close the contour twice */ + cff_builder_close_contour( builder ); + builder->path_begun = 0; + } + + + static void + cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, + const CF2_CallbackParams params ) + { + /* downcast the object pointer */ + CF2_Outline outline = (CF2_Outline)callbacks; + CFF_Builder* builder; + + + FT_ASSERT( outline && outline->decoder ); + FT_ASSERT( params->op == CF2_PathOpLineTo ); + + builder = &outline->decoder->builder; + + if ( !builder->path_begun ) + { + /* record the move before the line; also check points and set */ + /* `path_begun' */ + cff_builder_start_point( builder, + params->pt0.x, + params->pt0.y ); + } + + /* `cff_builder_add_point1' includes a check_points call for one point */ + cff_builder_add_point1( builder, + params->pt1.x, + params->pt1.y ); + } + + + static void + cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, + const CF2_CallbackParams params ) + { + /* downcast the object pointer */ + CF2_Outline outline = (CF2_Outline)callbacks; + CFF_Builder* builder; + + + FT_ASSERT( outline && outline->decoder ); + FT_ASSERT( params->op == CF2_PathOpCubeTo ); + + builder = &outline->decoder->builder; + + if ( !builder->path_begun ) + { + /* record the move before the line; also check points and set */ + /* `path_begun' */ + cff_builder_start_point( builder, + params->pt0.x, + params->pt0.y ); + } + + /* prepare room for 3 points: 2 off-curve, 1 on-curve */ + cff_check_points( builder, 3 ); + + cff_builder_add_point( builder, + params->pt1.x, + params->pt1.y, 0 ); + cff_builder_add_point( builder, + params->pt2.x, + params->pt2.y, 0 ); + cff_builder_add_point( builder, + params->pt3.x, + params->pt3.y, 1 ); + } + + + static void + cf2_outline_init( CF2_Outline outline, + FT_Memory memory, + FT_Error* error ) + { + FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) ); + + outline->root.memory = memory; + outline->root.error = error; + + outline->root.moveTo = cf2_builder_moveTo; + outline->root.lineTo = cf2_builder_lineTo; + outline->root.cubeTo = cf2_builder_cubeTo; + } + + + /* get scaling and hint flag from GlyphSlot */ + static void + cf2_getScaleAndHintFlag( CFF_Decoder* decoder, + CF2_Fixed* x_scale, + CF2_Fixed* y_scale, + FT_Bool* hinted, + FT_Bool* scaled ) + { + FT_ASSERT( decoder && decoder->builder.glyph ); + + /* note: FreeType scale includes a factor of 64 */ + *hinted = decoder->builder.glyph->hint; + *scaled = decoder->builder.glyph->scaled; + + if ( *hinted ) + { + *x_scale = FT_DivFix( decoder->builder.glyph->x_scale, + cf2_intToFixed( 64 ) ); + *y_scale = FT_DivFix( decoder->builder.glyph->y_scale, + cf2_intToFixed( 64 ) ); + } + else + { + /* for unhinted outlines, `cff_slot_load' does the scaling, */ + /* thus render at `unity' scale */ + + *x_scale = 0x0400; /* 1/64 as 16.16 */ + *y_scale = 0x0400; + } + } + + + /* get units per em from `FT_Face' */ + /* TODO: should handle font matrix concatenation? */ + static FT_UShort + cf2_getUnitsPerEm( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->builder.face ); + FT_ASSERT( decoder->builder.face->root.units_per_EM ); + + return decoder->builder.face->root.units_per_EM; + } + + + /* Main entry point: Render one glyph. */ + FT_LOCAL_DEF( FT_Error ) + cf2_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ) + { + FT_Memory memory; + FT_Error error = FT_Err_Ok; + CF2_Font font; + + + FT_ASSERT( decoder && decoder->cff ); + + memory = decoder->builder.memory; + + /* CF2 data is saved here across glyphs */ + font = (CF2_Font)decoder->cff->cf2_instance.data; + + /* on first glyph, allocate instance structure */ + if ( decoder->cff->cf2_instance.data == NULL ) + { + decoder->cff->cf2_instance.finalizer = + (FT_Generic_Finalizer)cf2_free_instance; + + if ( FT_ALLOC( decoder->cff->cf2_instance.data, + sizeof ( CF2_FontRec ) ) ) + return FT_THROW( Out_Of_Memory ); + + font = (CF2_Font)decoder->cff->cf2_instance.data; + + font->memory = memory; + + /* initialize a client outline, to be shared by each glyph rendered */ + cf2_outline_init( &font->outline, font->memory, &font->error ); + } + + /* save decoder; it is a stack variable and will be different on each */ + /* call */ + font->decoder = decoder; + font->outline.decoder = decoder; + + { + /* build parameters for Adobe engine */ + + CFF_Builder* builder = &decoder->builder; + CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face ); + + /* local error */ + FT_Error error2 = FT_Err_Ok; + CF2_BufferRec buf; + CF2_Matrix transform; + CF2_F16Dot16 glyphWidth; + + FT_Bool hinted; + FT_Bool scaled; + + + /* FreeType has already looked up the GID; convert to */ + /* `RegionBuffer', assuming that the input has been validated */ + FT_ASSERT( charstring_base + charstring_len >= charstring_base ); + + FT_ZERO( &buf ); + buf.start = + buf.ptr = charstring_base; + buf.end = charstring_base + charstring_len; + + FT_ZERO( &transform ); + + cf2_getScaleAndHintFlag( decoder, + &transform.a, + &transform.d, + &hinted, + &scaled ); + + font->renderingFlags = 0; + if ( hinted ) + font->renderingFlags |= CF2_FlagsHinted; + if ( scaled && !driver->no_stem_darkening ) + font->renderingFlags |= CF2_FlagsDarkened; + + /* now get an outline for this glyph; */ + /* also get units per em to validate scale */ + font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); + + error2 = cf2_checkTransform( &transform, font->unitsPerEm ); + if ( error2 ) + return error2; + + error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); + if ( error2 ) + return FT_ERR( Invalid_File_Format ); + + cf2_setGlyphWidth( &font->outline, glyphWidth ); + + return FT_Err_Ok; + } + } + + + /* get pointer to current FreeType subfont (based on current glyphID) */ + FT_LOCAL_DEF( CFF_SubFont ) + cf2_getSubfont( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return decoder->current_subfont; + } + + + /* get `y_ppem' from `CFF_Size' */ + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getPpemY( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && + decoder->builder.face && + decoder->builder.face->root.size ); + FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem ); + + return cf2_intToFixed( + decoder->builder.face->root.size->metrics.y_ppem ); + } + + + /* get standard stem widths for the current subfont; */ + /* FreeType stores these as integer font units */ + /* (note: variable names seem swapped) */ + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getStdVW( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return cf2_intToFixed( + decoder->current_subfont->private_dict.standard_height ); + } + + + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getStdHW( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return cf2_intToFixed( + decoder->current_subfont->private_dict.standard_width ); + } + + + /* note: FreeType stores 1000 times the actual value for `BlueScale' */ + FT_LOCAL_DEF( void ) + cf2_getBlueMetrics( CFF_Decoder* decoder, + CF2_Fixed* blueScale, + CF2_Fixed* blueShift, + CF2_Fixed* blueFuzz ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *blueScale = FT_DivFix( + decoder->current_subfont->private_dict.blue_scale, + cf2_intToFixed( 1000 ) ); + *blueShift = cf2_intToFixed( + decoder->current_subfont->private_dict.blue_shift ); + *blueFuzz = cf2_intToFixed( + decoder->current_subfont->private_dict.blue_fuzz ); + } + + + /* get blue values counts and arrays; the FreeType parser has validated */ + /* the counts and verified that each is an even number */ + FT_LOCAL_DEF( void ) + cf2_getBlueValues( CFF_Decoder* decoder, + size_t* count, + FT_Pos* *data ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *count = decoder->current_subfont->private_dict.num_blue_values; + *data = (FT_Pos*) + &decoder->current_subfont->private_dict.blue_values; + } + + + FT_LOCAL_DEF( void ) + cf2_getOtherBlues( CFF_Decoder* decoder, + size_t* count, + FT_Pos* *data ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *count = decoder->current_subfont->private_dict.num_other_blues; + *data = (FT_Pos*) + &decoder->current_subfont->private_dict.other_blues; + } + + + FT_LOCAL_DEF( void ) + cf2_getFamilyBlues( CFF_Decoder* decoder, + size_t* count, + FT_Pos* *data ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *count = decoder->current_subfont->private_dict.num_family_blues; + *data = (FT_Pos*) + &decoder->current_subfont->private_dict.family_blues; + } + + + FT_LOCAL_DEF( void ) + cf2_getFamilyOtherBlues( CFF_Decoder* decoder, + size_t* count, + FT_Pos* *data ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *count = decoder->current_subfont->private_dict.num_family_other_blues; + *data = (FT_Pos*) + &decoder->current_subfont->private_dict.family_other_blues; + } + + + FT_LOCAL_DEF( CF2_Int ) + cf2_getLanguageGroup( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return decoder->current_subfont->private_dict.language_group; + } + + + /* convert unbiased subroutine index to `CF2_Buffer' and */ + /* return 0 on success */ + FT_LOCAL_DEF( CF2_Int ) + cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, + CF2_UInt idx, + CF2_Buffer buf ) + { + FT_ASSERT( decoder && decoder->globals ); + + FT_ZERO( buf ); + + idx += decoder->globals_bias; + if ( idx >= decoder->num_globals ) + return TRUE; /* error */ + + buf->start = + buf->ptr = decoder->globals[idx]; + buf->end = decoder->globals[idx + 1]; + + return FALSE; /* success */ + } + + + /* convert AdobeStandardEncoding code to CF2_Buffer; */ + /* used for seac component */ + FT_LOCAL_DEF( FT_Error ) + cf2_getSeacComponent( CFF_Decoder* decoder, + CF2_UInt code, + CF2_Buffer buf ) + { + CF2_Int gid; + FT_Byte* charstring; + FT_ULong len; + FT_Error error; + + + FT_ASSERT( decoder ); + + FT_ZERO( buf ); + + gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code ); + if ( gid < 0 ) + return FT_THROW( Invalid_Glyph_Format ); + + error = cff_get_glyph_data( decoder->builder.face, + gid, + &charstring, + &len ); + /* TODO: for now, just pass the FreeType error through */ + if ( error ) + return error; + + /* assume input has been validated */ + FT_ASSERT( charstring + len >= charstring ); + + buf->start = charstring; + buf->end = charstring + len; + buf->ptr = buf->start; + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( void ) + cf2_freeSeacComponent( CFF_Decoder* decoder, + CF2_Buffer buf ) + { + FT_ASSERT( decoder ); + + cff_free_glyph_data( decoder->builder.face, + (FT_Byte**)&buf->start, + (FT_ULong)( buf->end - buf->start ) ); + } + + + FT_LOCAL_DEF( CF2_Int ) + cf2_initLocalRegionBuffer( CFF_Decoder* decoder, + CF2_UInt idx, + CF2_Buffer buf ) + { + FT_ASSERT( decoder && decoder->locals ); + + FT_ZERO( buf ); + + idx += decoder->locals_bias; + if ( idx >= decoder->num_locals ) + return TRUE; /* error */ + + buf->start = + buf->ptr = decoder->locals[idx]; + buf->end = decoder->locals[idx + 1]; + + return FALSE; /* success */ + } + + + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getDefaultWidthX( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return cf2_intToFixed( + decoder->current_subfont->private_dict.default_width ); + } + + + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getNominalWidthX( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return cf2_intToFixed( + decoder->current_subfont->private_dict.nominal_width ); + } + + + FT_LOCAL_DEF( void ) + cf2_outline_reset( CF2_Outline outline ) + { + CFF_Decoder* decoder = outline->decoder; + + + FT_ASSERT( decoder ); + + outline->root.windingMomentum = 0; + + FT_GlyphLoader_Rewind( decoder->builder.loader ); + } + + + FT_LOCAL_DEF( void ) + cf2_outline_close( CF2_Outline outline ) + { + CFF_Decoder* decoder = outline->decoder; + + + FT_ASSERT( decoder ); + + cff_builder_close_contour( &decoder->builder ); + + FT_GlyphLoader_Add( decoder->builder.loader ); + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2ft.h b/drivers/freetype/src/cff/cf2ft.h new file mode 100644 index 0000000000..731da3ca8c --- /dev/null +++ b/drivers/freetype/src/cff/cf2ft.h @@ -0,0 +1,147 @@ +/***************************************************************************/ +/* */ +/* cf2ft.h */ +/* */ +/* FreeType Glue Component to Adobe's Interpreter (specification). */ +/* */ +/* Copyright 2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2FT_H__ +#define __CF2FT_H__ + + +#include "cf2types.h" + + + /* TODO: disable asserts for now */ +#define CF2_NDEBUG + + +#include FT_SYSTEM_H + +#include "cf2glue.h" +#include "cffgload.h" /* for CFF_Decoder */ + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + cf2_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ); + + FT_LOCAL( CFF_SubFont ) + cf2_getSubfont( CFF_Decoder* decoder ); + + + FT_LOCAL( CF2_Fixed ) + cf2_getPpemY( CFF_Decoder* decoder ); + FT_LOCAL( CF2_Fixed ) + cf2_getStdVW( CFF_Decoder* decoder ); + FT_LOCAL( CF2_Fixed ) + cf2_getStdHW( CFF_Decoder* decoder ); + + FT_LOCAL( void ) + cf2_getBlueMetrics( CFF_Decoder* decoder, + CF2_Fixed* blueScale, + CF2_Fixed* blueShift, + CF2_Fixed* blueFuzz ); + FT_LOCAL( void ) + cf2_getBlueValues( CFF_Decoder* decoder, + size_t* count, + FT_Pos* *data ); + FT_LOCAL( void ) + cf2_getOtherBlues( CFF_Decoder* decoder, + size_t* count, + FT_Pos* *data ); + FT_LOCAL( void ) + cf2_getFamilyBlues( CFF_Decoder* decoder, + size_t* count, + FT_Pos* *data ); + FT_LOCAL( void ) + cf2_getFamilyOtherBlues( CFF_Decoder* decoder, + size_t* count, + FT_Pos* *data ); + + FT_LOCAL( CF2_Int ) + cf2_getLanguageGroup( CFF_Decoder* decoder ); + + FT_LOCAL( CF2_Int ) + cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, + CF2_UInt idx, + CF2_Buffer buf ); + FT_LOCAL( FT_Error ) + cf2_getSeacComponent( CFF_Decoder* decoder, + CF2_UInt code, + CF2_Buffer buf ); + FT_LOCAL( void ) + cf2_freeSeacComponent( CFF_Decoder* decoder, + CF2_Buffer buf ); + FT_LOCAL( CF2_Int ) + cf2_initLocalRegionBuffer( CFF_Decoder* decoder, + CF2_UInt idx, + CF2_Buffer buf ); + + FT_LOCAL( CF2_Fixed ) + cf2_getDefaultWidthX( CFF_Decoder* decoder ); + FT_LOCAL( CF2_Fixed ) + cf2_getNominalWidthX( CFF_Decoder* decoder ); + + + /* + * FreeType client outline + * + * process output from the charstring interpreter + */ + typedef struct CF2_OutlineRec_ + { + CF2_OutlineCallbacksRec root; /* base class must be first */ + CFF_Decoder* decoder; + + } CF2_OutlineRec, *CF2_Outline; + + + FT_LOCAL( void ) + cf2_outline_reset( CF2_Outline outline ); + FT_LOCAL( void ) + cf2_outline_close( CF2_Outline outline ); + + +FT_END_HEADER + + +#endif /* __CF2FT_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2glue.h b/drivers/freetype/src/cff/cf2glue.h new file mode 100644 index 0000000000..a24da39e93 --- /dev/null +++ b/drivers/freetype/src/cff/cf2glue.h @@ -0,0 +1,144 @@ +/***************************************************************************/ +/* */ +/* cf2glue.h */ +/* */ +/* Adobe's code for shared stuff (specification only). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2GLUE_H__ +#define __CF2GLUE_H__ + + +/* common includes for other modules */ +#include "cf2error.h" +#include "cf2fixed.h" +#include "cf2arrst.h" +#include "cf2read.h" + + +FT_BEGIN_HEADER + + + /* rendering parameters */ + + /* apply hints to rendered glyphs */ +#define CF2_FlagsHinted 1 + /* for testing */ +#define CF2_FlagsDarkened 2 + + /* type for holding the flags */ + typedef CF2_Int CF2_RenderingFlags; + + + /* elements of a glyph outline */ + typedef enum CF2_PathOp_ + { + CF2_PathOpMoveTo = 1, /* change the current point */ + CF2_PathOpLineTo = 2, /* line */ + CF2_PathOpQuadTo = 3, /* quadratic curve */ + CF2_PathOpCubeTo = 4 /* cubic curve */ + + } CF2_PathOp; + + + /* a matrix of fixed point values */ + typedef struct CF2_Matrix_ + { + CF2_F16Dot16 a; + CF2_F16Dot16 b; + CF2_F16Dot16 c; + CF2_F16Dot16 d; + CF2_F16Dot16 tx; + CF2_F16Dot16 ty; + + } CF2_Matrix; + + + /* these typedefs are needed by more than one header file */ + /* and gcc compiler doesn't allow redefinition */ + typedef struct CF2_FontRec_ CF2_FontRec, *CF2_Font; + typedef struct CF2_HintRec_ CF2_HintRec, *CF2_Hint; + + + /* A common structure for all callback parameters. */ + /* */ + /* Some members may be unused. For example, `pt0' is not used for */ + /* `moveTo' and `pt3' is not used for `quadTo'. The initial point `pt0' */ + /* is included for each path element for generality; curve conversions */ + /* need it. The `op' parameter allows one function to handle multiple */ + /* element types. */ + + typedef struct CF2_CallbackParamsRec_ + { + FT_Vector pt0; + FT_Vector pt1; + FT_Vector pt2; + FT_Vector pt3; + + CF2_Int op; + + } CF2_CallbackParamsRec, *CF2_CallbackParams; + + + /* forward reference */ + typedef struct CF2_OutlineCallbacksRec_ CF2_OutlineCallbacksRec, + *CF2_OutlineCallbacks; + + /* callback function pointers */ + typedef void + (*CF2_Callback_Type)( CF2_OutlineCallbacks callbacks, + const CF2_CallbackParams params ); + + + struct CF2_OutlineCallbacksRec_ + { + CF2_Callback_Type moveTo; + CF2_Callback_Type lineTo; + CF2_Callback_Type quadTo; + CF2_Callback_Type cubeTo; + + CF2_Int windingMomentum; /* for winding order detection */ + + FT_Memory memory; + FT_Error* error; + }; + + +FT_END_HEADER + + +#endif /* __CF2GLUE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2hints.c b/drivers/freetype/src/cff/cf2hints.c new file mode 100644 index 0000000000..96bd49f186 --- /dev/null +++ b/drivers/freetype/src/cff/cf2hints.c @@ -0,0 +1,1734 @@ +/***************************************************************************/ +/* */ +/* cf2hints.c */ +/* */ +/* Adobe's code for handling CFF hints (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" +#include FT_INTERNAL_DEBUG_H + +#include "cf2glue.h" +#include "cf2font.h" +#include "cf2hints.h" +#include "cf2intrp.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_cf2hints + + + typedef struct CF2_HintMoveRec_ + { + size_t j; /* index of upper hint map edge */ + CF2_Fixed moveUp; /* adjustment to optimum position */ + + } CF2_HintMoveRec, *CF2_HintMove; + + + /* Compute angular momentum for winding order detection. It is called */ + /* for all lines and curves, but not necessarily in element order. */ + static CF2_Int + cf2_getWindingMomentum( CF2_Fixed x1, + CF2_Fixed y1, + CF2_Fixed x2, + CF2_Fixed y2 ) + { + /* cross product of pt1 position from origin with pt2 position from */ + /* pt1; we reduce the precision so that the result fits into 32 bits */ + + return ( x1 >> 16 ) * ( ( y2 - y1 ) >> 16 ) - + ( y1 >> 16 ) * ( ( x2 - x1 ) >> 16 ); + } + + + /* + * Construct from a StemHint; this is used as a parameter to + * `cf2_blues_capture'. + * `hintOrigin' is the character space displacement of a seac accent. + * Adjust stem hint for darkening here. + * + */ + static void + cf2_hint_init( CF2_Hint hint, + const CF2_ArrStack stemHintArray, + size_t indexStemHint, + const CF2_Font font, + CF2_Fixed hintOrigin, + CF2_Fixed scale, + FT_Bool bottom ) + { + CF2_Fixed width; + const CF2_StemHintRec* stemHint; + + + FT_ZERO( hint ); + + stemHint = (const CF2_StemHintRec*)cf2_arrstack_getPointer( + stemHintArray, + indexStemHint ); + + width = stemHint->max - stemHint->min; + + if ( width == cf2_intToFixed( -21 ) ) + { + /* ghost bottom */ + + if ( bottom ) + { + hint->csCoord = stemHint->max; + hint->flags = CF2_GhostBottom; + } + else + hint->flags = 0; + } + + else if ( width == cf2_intToFixed( -20 ) ) + { + /* ghost top */ + + if ( bottom ) + hint->flags = 0; + else + { + hint->csCoord = stemHint->min; + hint->flags = CF2_GhostTop; + } + } + + else if ( width < 0 ) + { + /* inverted pair */ + + /* + * Hints with negative widths were produced by an early version of a + * non-Adobe font tool. The Type 2 spec allows edge (ghost) hints + * with negative widths, but says + * + * All other negative widths have undefined meaning. + * + * CoolType has a silent workaround that negates the hint width; for + * permissive mode, we do the same here. + * + * Note: Such fonts cannot use ghost hints, but should otherwise work. + * Note: Some poor hints in our faux fonts can produce negative + * widths at some blends. For example, see a light weight of + * `u' in ASerifMM. + * + */ + if ( bottom ) + { + hint->csCoord = stemHint->max; + hint->flags = CF2_PairBottom; + } + else + { + hint->csCoord = stemHint->min; + hint->flags = CF2_PairTop; + } + } + + else + { + /* normal pair */ + + if ( bottom ) + { + hint->csCoord = stemHint->min; + hint->flags = CF2_PairBottom; + } + else + { + hint->csCoord = stemHint->max; + hint->flags = CF2_PairTop; + } + } + + /* Now that ghost hints have been detected, adjust this edge for */ + /* darkening. Bottoms are not changed; tops are incremented by twice */ + /* `darkenY'. */ + if ( cf2_hint_isTop( hint ) ) + hint->csCoord += 2 * font->darkenY; + + hint->csCoord += hintOrigin; + hint->scale = scale; + hint->index = indexStemHint; /* index in original stem hint array */ + + /* if original stem hint has been used, use the same position */ + if ( hint->flags != 0 && stemHint->used ) + { + if ( cf2_hint_isTop( hint ) ) + hint->dsCoord = stemHint->maxDS; + else + hint->dsCoord = stemHint->minDS; + + cf2_hint_lock( hint ); + } + else + hint->dsCoord = FT_MulFix( hint->csCoord, scale ); + } + + + /* initialize an invalid hint map element */ + static void + cf2_hint_initZero( CF2_Hint hint ) + { + FT_ZERO( hint ); + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hint_isValid( const CF2_Hint hint ) + { + return (FT_Bool)( hint->flags != 0 ); + } + + + static FT_Bool + cf2_hint_isPair( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & + ( CF2_PairBottom | CF2_PairTop ) ) != 0 ); + } + + + static FT_Bool + cf2_hint_isPairTop( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & CF2_PairTop ) != 0 ); + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hint_isTop( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & + ( CF2_PairTop | CF2_GhostTop ) ) != 0 ); + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hint_isBottom( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & + ( CF2_PairBottom | CF2_GhostBottom ) ) != 0 ); + } + + + static FT_Bool + cf2_hint_isLocked( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & CF2_Locked ) != 0 ); + } + + + static FT_Bool + cf2_hint_isSynthetic( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & CF2_Synthetic ) != 0 ); + } + + + FT_LOCAL_DEF( void ) + cf2_hint_lock( CF2_Hint hint ) + { + hint->flags |= CF2_Locked; + } + + + FT_LOCAL_DEF( void ) + cf2_hintmap_init( CF2_HintMap hintmap, + CF2_Font font, + CF2_HintMap initialMap, + CF2_ArrStack hintMoves, + CF2_Fixed scale ) + { + FT_ZERO( hintmap ); + + /* copy parameters from font instance */ + hintmap->hinted = font->hinted; + hintmap->scale = scale; + hintmap->font = font; + hintmap->initialHintMap = initialMap; + /* will clear in `cf2_hintmap_adjustHints' */ + hintmap->hintMoves = hintMoves; + } + + + static FT_Bool + cf2_hintmap_isValid( const CF2_HintMap hintmap ) + { + return hintmap->isValid; + } + + + /* transform character space coordinate to device space using hint map */ + static CF2_Fixed + cf2_hintmap_map( CF2_HintMap hintmap, + CF2_Fixed csCoord ) + { + FT_ASSERT( hintmap->isValid ); /* must call Build before Map */ + FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); + + if ( hintmap->count == 0 || ! hintmap->hinted ) + { + /* there are no hints; use uniform scale and zero offset */ + return FT_MulFix( csCoord, hintmap->scale ); + } + else + { + /* start linear search from last hit */ + CF2_UInt i = hintmap->lastIndex; + + + /* search up */ + while ( i < hintmap->count - 1 && + csCoord >= hintmap->edge[i + 1].csCoord ) + i += 1; + + /* search down */ + while ( i > 0 && csCoord < hintmap->edge[i].csCoord ) + i -= 1; + + hintmap->lastIndex = i; + + if ( i == 0 && csCoord < hintmap->edge[0].csCoord ) + { + /* special case for points below first edge: use uniform scale */ + return FT_MulFix( csCoord - hintmap->edge[0].csCoord, + hintmap->scale ) + + hintmap->edge[0].dsCoord; + } + else + { + /* + * Note: entries with duplicate csCoord are allowed. + * Use edge[i], the highest entry where csCoord >= entry[i].csCoord + */ + return FT_MulFix( csCoord - hintmap->edge[i].csCoord, + hintmap->edge[i].scale ) + + hintmap->edge[i].dsCoord; + } + } + } + + + /* + * This hinting policy moves a hint pair in device space so that one of + * its two edges is on a device pixel boundary (its fractional part is + * zero). `cf2_hintmap_insertHint' guarantees no overlap in CS + * space. Ensure here that there is no overlap in DS. + * + * In the first pass, edges are adjusted relative to adjacent hints. + * Those that are below have already been adjusted. Those that are + * above have not yet been adjusted. If a hint above blocks an + * adjustment to an optimal position, we will try again in a second + * pass. The second pass is top-down. + * + */ + + static void + cf2_hintmap_adjustHints( CF2_HintMap hintmap ) + { + size_t i, j; + + + cf2_arrstack_clear( hintmap->hintMoves ); /* working storage */ + + /* + * First pass is bottom-up (font hint order) without look-ahead. + * Locked edges are already adjusted. + * Unlocked edges begin with dsCoord from `initialHintMap'. + * Save edges that are not optimally adjusted in `hintMoves' array, + * and process them in second pass. + */ + + for ( i = 0; i < hintmap->count; i++ ) + { + FT_Bool isPair = cf2_hint_isPair( &hintmap->edge[i] ); + + + /* index of upper edge (same value for ghost hint) */ + j = isPair ? i + 1 : i; + + FT_ASSERT( j < hintmap->count ); + FT_ASSERT( cf2_hint_isValid( &hintmap->edge[i] ) ); + FT_ASSERT( cf2_hint_isValid( &hintmap->edge[j] ) ); + FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) == + cf2_hint_isLocked( &hintmap->edge[j] ) ); + + if ( !cf2_hint_isLocked( &hintmap->edge[i] ) ) + { + /* hint edge is not locked, we can adjust it */ + CF2_Fixed fracDown = cf2_fixedFraction( hintmap->edge[i].dsCoord ); + CF2_Fixed fracUp = cf2_fixedFraction( hintmap->edge[j].dsCoord ); + + /* calculate all four possibilities; moves down are negative */ + CF2_Fixed downMoveDown = 0 - fracDown; + CF2_Fixed upMoveDown = 0 - fracUp; + CF2_Fixed downMoveUp = fracDown == 0 + ? 0 + : cf2_intToFixed( 1 ) - fracDown; + CF2_Fixed upMoveUp = fracUp == 0 + ? 0 + : cf2_intToFixed( 1 ) - fracUp; + + /* smallest move up */ + CF2_Fixed moveUp = FT_MIN( downMoveUp, upMoveUp ); + /* smallest move down */ + CF2_Fixed moveDown = FT_MAX( downMoveDown, upMoveDown ); + + /* final amount to move edge or edge pair */ + CF2_Fixed move; + + CF2_Fixed downMinCounter = CF2_MIN_COUNTER; + CF2_Fixed upMinCounter = CF2_MIN_COUNTER; + FT_Bool saveEdge = FALSE; + + + /* minimum counter constraint doesn't apply when adjacent edges */ + /* are synthetic */ + /* TODO: doesn't seem a big effect; for now, reduce the code */ +#if 0 + if ( i == 0 || + cf2_hint_isSynthetic( &hintmap->edge[i - 1] ) ) + downMinCounter = 0; + + if ( j >= hintmap->count - 1 || + cf2_hint_isSynthetic( &hintmap->edge[j + 1] ) ) + upMinCounter = 0; +#endif + + /* is there room to move up? */ + /* there is if we are at top of array or the next edge is at or */ + /* beyond proposed move up? */ + if ( j >= hintmap->count - 1 || + hintmap->edge[j + 1].dsCoord >= + hintmap->edge[j].dsCoord + moveUp + upMinCounter ) + { + /* there is room to move up; is there also room to move down? */ + if ( i == 0 || + hintmap->edge[i - 1].dsCoord <= + hintmap->edge[i].dsCoord + moveDown - downMinCounter ) + { + /* move smaller absolute amount */ + move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */ + } + else + move = moveUp; + } + else + { + /* is there room to move down? */ + if ( i == 0 || + hintmap->edge[i - 1].dsCoord <= + hintmap->edge[i].dsCoord + moveDown - downMinCounter ) + { + move = moveDown; + /* true if non-optimum move */ + saveEdge = (FT_Bool)( moveUp < -moveDown ); + } + else + { + /* no room to move either way without overlapping or reducing */ + /* the counter too much */ + move = 0; + saveEdge = TRUE; + } + } + + /* Identify non-moves and moves down that aren't optimal, and save */ + /* them for second pass. */ + /* Do this only if there is an unlocked edge above (which could */ + /* possibly move). */ + if ( saveEdge && + j < hintmap->count - 1 && + !cf2_hint_isLocked( &hintmap->edge[j + 1] ) ) + { + CF2_HintMoveRec savedMove; + + + savedMove.j = j; + /* desired adjustment in second pass */ + savedMove.moveUp = moveUp - move; + + cf2_arrstack_push( hintmap->hintMoves, &savedMove ); + } + + /* move the edge(s) */ + hintmap->edge[i].dsCoord += move; + if ( isPair ) + hintmap->edge[j].dsCoord += move; + } + + /* assert there are no overlaps in device space */ + FT_ASSERT( i == 0 || + hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord ); + FT_ASSERT( i < j || + hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord ); + + /* adjust the scales, avoiding divide by zero */ + if ( i > 0 ) + { + if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord ) + hintmap->edge[i - 1].scale = + FT_DivFix( + hintmap->edge[i].dsCoord - hintmap->edge[i - 1].dsCoord, + hintmap->edge[i].csCoord - hintmap->edge[i - 1].csCoord ); + } + + if ( isPair ) + { + if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord ) + hintmap->edge[j - 1].scale = + FT_DivFix( + hintmap->edge[j].dsCoord - hintmap->edge[j - 1].dsCoord, + hintmap->edge[j].csCoord - hintmap->edge[j - 1].csCoord ); + + i += 1; /* skip upper edge on next loop */ + } + } + + /* second pass tries to move non-optimal hints up, in case there is */ + /* room now */ + for ( i = cf2_arrstack_size( hintmap->hintMoves ); i > 0; i-- ) + { + CF2_HintMove hintMove = (CF2_HintMove) + cf2_arrstack_getPointer( hintmap->hintMoves, i - 1 ); + + + j = hintMove->j; + + /* this was tested before the push, above */ + FT_ASSERT( j < hintmap->count - 1 ); + + /* is there room to move up? */ + if ( hintmap->edge[j + 1].dsCoord >= + hintmap->edge[j].dsCoord + hintMove->moveUp + CF2_MIN_COUNTER ) + { + /* there is more room now, move edge up */ + hintmap->edge[j].dsCoord += hintMove->moveUp; + + if ( cf2_hint_isPair( &hintmap->edge[j] ) ) + { + FT_ASSERT( j > 0 ); + hintmap->edge[j - 1].dsCoord += hintMove->moveUp; + } + } + } + } + + + /* insert hint edges into map, sorted by csCoord */ + static void + cf2_hintmap_insertHint( CF2_HintMap hintmap, + CF2_Hint bottomHintEdge, + CF2_Hint topHintEdge ) + { + CF2_UInt indexInsert; + + /* set default values, then check for edge hints */ + FT_Bool isPair = TRUE; + CF2_Hint firstHintEdge = bottomHintEdge; + CF2_Hint secondHintEdge = topHintEdge; + + + /* one or none of the input params may be invalid when dealing with */ + /* edge hints; at least one edge must be valid */ + FT_ASSERT( cf2_hint_isValid( bottomHintEdge ) || + cf2_hint_isValid( topHintEdge ) ); + + /* determine how many and which edges to insert */ + if ( !cf2_hint_isValid( bottomHintEdge ) ) + { + /* insert only the top edge */ + firstHintEdge = topHintEdge; + isPair = FALSE; + } + else if ( !cf2_hint_isValid( topHintEdge ) ) + { + /* insert only the bottom edge */ + isPair = FALSE; + } + + /* paired edges must be in proper order */ + FT_ASSERT( !isPair || + topHintEdge->csCoord >= bottomHintEdge->csCoord ); + + /* linear search to find index value of insertion point */ + indexInsert = 0; + for ( ; indexInsert < hintmap->count; indexInsert++ ) + { + if ( hintmap->edge[indexInsert].csCoord > firstHintEdge->csCoord ) + break; + } + + /* + * Discard any hints that overlap in character space. Most often, + * this is while building the initial map, but in theory, it can also + * occur because of darkening. + * + */ + if ( indexInsert < hintmap->count ) + { + /* we are inserting before an existing edge: */ + /* verify that a new pair does not straddle the next edge */ + if ( isPair && + hintmap->edge[indexInsert].csCoord < secondHintEdge->csCoord ) + return; /* ignore overlapping stem hint */ + + /* verify that we are not inserting between paired edges */ + if ( cf2_hint_isPairTop( &hintmap->edge[indexInsert] ) ) + return; /* ignore overlapping stem hint */ + } + + /* recompute device space locations using initial hint map */ + if ( cf2_hintmap_isValid( hintmap->initialHintMap ) && + !cf2_hint_isLocked( firstHintEdge ) ) + { + if ( isPair ) + { + /* Use hint map to position the center of stem, and nominal scale */ + /* to position the two edges. This preserves the stem width. */ + CF2_Fixed midpoint = cf2_hintmap_map( + hintmap->initialHintMap, + ( secondHintEdge->csCoord + + firstHintEdge->csCoord ) / 2 ); + CF2_Fixed halfWidth = FT_MulFix( + ( secondHintEdge->csCoord - + firstHintEdge->csCoord ) / 2, + hintmap->scale ); + + + firstHintEdge->dsCoord = midpoint - halfWidth; + secondHintEdge->dsCoord = midpoint + halfWidth; + } + else + firstHintEdge->dsCoord = cf2_hintmap_map( hintmap->initialHintMap, + firstHintEdge->csCoord ); + } + + /* discard any hints that overlap in device space; this can occur */ + /* because locked hints have been moved to align with blue zones */ + if ( indexInsert > 0 ) + { + /* we are inserting after an existing edge */ + if ( firstHintEdge->dsCoord < hintmap->edge[indexInsert - 1].dsCoord ) + return; + } + + if ( indexInsert < hintmap->count ) + { + /* we are inserting before an existing edge */ + if ( isPair ) + { + if ( secondHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord ) + return; + } + else + { + if ( firstHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord ) + return; + } + } + + /* make room to insert */ + { + CF2_Int iSrc = hintmap->count - 1; + CF2_Int iDst = isPair ? hintmap->count + 1 : hintmap->count; + + CF2_Int count = hintmap->count - indexInsert; + + + if ( iDst >= CF2_MAX_HINT_EDGES ) + { + FT_TRACE4(( "cf2_hintmap_insertHint: too many hintmaps\n" )); + return; + } + + while ( count-- ) + hintmap->edge[iDst--] = hintmap->edge[iSrc--]; + + /* insert first edge */ + hintmap->edge[indexInsert] = *firstHintEdge; /* copy struct */ + hintmap->count += 1; + + if ( isPair ) + { + /* insert second edge */ + hintmap->edge[indexInsert + 1] = *secondHintEdge; /* copy struct */ + hintmap->count += 1; + } + } + + return; + } + + + /* + * Build a map from hints and mask. + * + * This function may recur one level if `hintmap->initialHintMap' is not yet + * valid. + * If `initialMap' is true, simply build initial map. + * + * Synthetic hints are used in two ways. A hint at zero is inserted, if + * needed, in the initial hint map, to prevent translations from + * propagating across the origin. If synthetic em box hints are enabled + * for ideographic dictionaries, then they are inserted in all hint + * maps, including the initial one. + * + */ + FT_LOCAL_DEF( void ) + cf2_hintmap_build( CF2_HintMap hintmap, + CF2_ArrStack hStemHintArray, + CF2_ArrStack vStemHintArray, + CF2_HintMask hintMask, + CF2_Fixed hintOrigin, + FT_Bool initialMap ) + { + FT_Byte* maskPtr; + + CF2_Font font = hintmap->font; + CF2_HintMaskRec tempHintMask; + + size_t bitCount, i; + FT_Byte maskByte; + + + /* check whether initial map is constructed */ + if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) ) + { + /* make recursive call with initialHintMap and temporary mask; */ + /* temporary mask will get all bits set, below */ + cf2_hintmask_init( &tempHintMask, hintMask->error ); + cf2_hintmap_build( hintmap->initialHintMap, + hStemHintArray, + vStemHintArray, + &tempHintMask, + hintOrigin, + TRUE ); + } + + if ( !cf2_hintmask_isValid( hintMask ) ) + { + /* without a hint mask, assume all hints are active */ + cf2_hintmask_setAll( hintMask, + cf2_arrstack_size( hStemHintArray ) + + cf2_arrstack_size( vStemHintArray ) ); + } + + /* begin by clearing the map */ + hintmap->count = 0; + hintmap->lastIndex = 0; + + /* make a copy of the hint mask so we can modify it */ + tempHintMask = *hintMask; + maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask ); + + /* use the hStem hints only, which are first in the mask */ + /* TODO: compare this to cffhintmaskGetBitCount */ + bitCount = cf2_arrstack_size( hStemHintArray ); + + /* synthetic embox hints get highest priority */ + if ( font->blues.doEmBoxHints ) + { + CF2_HintRec dummy; + + + cf2_hint_initZero( &dummy ); /* invalid hint map element */ + + /* ghost bottom */ + cf2_hintmap_insertHint( hintmap, + &font->blues.emBoxBottomEdge, + &dummy ); + /* ghost top */ + cf2_hintmap_insertHint( hintmap, + &dummy, + &font->blues.emBoxTopEdge ); + } + + /* insert hints captured by a blue zone or already locked (higher */ + /* priority) */ + for ( i = 0, maskByte = 0x80; i < bitCount; i++ ) + { + if ( maskByte & *maskPtr ) + { + /* expand StemHint into two `CF2_Hint' elements */ + CF2_HintRec bottomHintEdge, topHintEdge; + + + cf2_hint_init( &bottomHintEdge, + hStemHintArray, + i, + font, + hintOrigin, + hintmap->scale, + TRUE /* bottom */ ); + cf2_hint_init( &topHintEdge, + hStemHintArray, + i, + font, + hintOrigin, + hintmap->scale, + FALSE /* top */ ); + + if ( cf2_hint_isLocked( &bottomHintEdge ) || + cf2_hint_isLocked( &topHintEdge ) || + cf2_blues_capture( &font->blues, + &bottomHintEdge, + &topHintEdge ) ) + { + /* insert captured hint into map */ + cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge ); + + *maskPtr &= ~maskByte; /* turn off the bit for this hint */ + } + } + + if ( ( i & 7 ) == 7 ) + { + /* move to next mask byte */ + maskPtr++; + maskByte = 0x80; + } + else + maskByte >>= 1; + } + + /* initial hint map includes only captured hints plus maybe one at 0 */ + + /* + * TODO: There is a problem here because we are trying to build a + * single hint map containing all captured hints. It is + * possible for there to be conflicts between captured hints, + * either because of darkening or because the hints are in + * separate hint zones (we are ignoring hint zones for the + * initial map). An example of the latter is MinionPro-Regular + * v2.030 glyph 883 (Greek Capital Alpha with Psili) at 15ppem. + * A stem hint for the psili conflicts with the top edge hint + * for the base character. The stem hint gets priority because + * of its sort order. In glyph 884 (Greek Capital Alpha with + * Psili and Oxia), the top of the base character gets a stem + * hint, and the psili does not. This creates different initial + * maps for the two glyphs resulting in different renderings of + * the base character. Will probably defer this either as not + * worth the cost or as a font bug. I don't think there is any + * good reason for an accent to be captured by an alignment + * zone. -darnold 2/12/10 + */ + + if ( initialMap ) + { + /* Apply a heuristic that inserts a point for (0,0), unless it's */ + /* already covered by a mapping. This locks the baseline for glyphs */ + /* that have no baseline hints. */ + + if ( hintmap->count == 0 || + hintmap->edge[0].csCoord > 0 || + hintmap->edge[hintmap->count - 1].csCoord < 0 ) + { + /* all edges are above 0 or all edges are below 0; */ + /* construct a locked edge hint at 0 */ + + CF2_HintRec edge, invalid; + + + cf2_hint_initZero( &edge ); + + edge.flags = CF2_GhostBottom | + CF2_Locked | + CF2_Synthetic; + edge.scale = hintmap->scale; + + cf2_hint_initZero( &invalid ); + cf2_hintmap_insertHint( hintmap, &edge, &invalid ); + } + } + else + { + /* insert remaining hints */ + + maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask ); + + for ( i = 0, maskByte = 0x80; i < bitCount; i++ ) + { + if ( maskByte & *maskPtr ) + { + CF2_HintRec bottomHintEdge, topHintEdge; + + + cf2_hint_init( &bottomHintEdge, + hStemHintArray, + i, + font, + hintOrigin, + hintmap->scale, + TRUE /* bottom */ ); + cf2_hint_init( &topHintEdge, + hStemHintArray, + i, + font, + hintOrigin, + hintmap->scale, + FALSE /* top */ ); + + cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge ); + } + + if ( ( i & 7 ) == 7 ) + { + /* move to next mask byte */ + maskPtr++; + maskByte = 0x80; + } + else + maskByte >>= 1; + } + } + + /* + * Note: The following line is a convenient place to break when + * debugging hinting. Examine `hintmap->edge' for the list of + * enabled hints, then step over the call to see the effect of + * adjustment. We stop here first on the recursive call that + * creates the initial map, and then on each counter group and + * hint zone. + */ + + /* adjust positions of hint edges that are not locked to blue zones */ + cf2_hintmap_adjustHints( hintmap ); + + /* save the position of all hints that were used in this hint map; */ + /* if we use them again, we'll locate them in the same position */ + if ( !initialMap ) + { + for ( i = 0; i < hintmap->count; i++ ) + { + if ( !cf2_hint_isSynthetic( &hintmap->edge[i] ) ) + { + /* Note: include both valid and invalid edges */ + /* Note: top and bottom edges are copied back separately */ + CF2_StemHint stemhint = (CF2_StemHint) + cf2_arrstack_getPointer( hStemHintArray, + hintmap->edge[i].index ); + + + if ( cf2_hint_isTop( &hintmap->edge[i] ) ) + stemhint->maxDS = hintmap->edge[i].dsCoord; + else + stemhint->minDS = hintmap->edge[i].dsCoord; + + stemhint->used = TRUE; + } + } + } + + /* hint map is ready to use */ + hintmap->isValid = TRUE; + + /* remember this mask has been used */ + cf2_hintmask_setNew( hintMask, FALSE ); + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_init( CF2_GlyphPath glyphpath, + CF2_Font font, + CF2_OutlineCallbacks callbacks, + CF2_Fixed scaleY, + /* CF2_Fixed hShift, */ + CF2_ArrStack hStemHintArray, + CF2_ArrStack vStemHintArray, + CF2_HintMask hintMask, + CF2_Fixed hintOriginY, + const CF2_Blues blues, + const FT_Vector* fractionalTranslation ) + { + FT_ZERO( glyphpath ); + + glyphpath->font = font; + glyphpath->callbacks = callbacks; + + cf2_arrstack_init( &glyphpath->hintMoves, + font->memory, + &font->error, + sizeof ( CF2_HintMoveRec ) ); + + cf2_hintmap_init( &glyphpath->initialHintMap, + font, + &glyphpath->initialHintMap, + &glyphpath->hintMoves, + scaleY ); + cf2_hintmap_init( &glyphpath->firstHintMap, + font, + &glyphpath->initialHintMap, + &glyphpath->hintMoves, + scaleY ); + cf2_hintmap_init( &glyphpath->hintMap, + font, + &glyphpath->initialHintMap, + &glyphpath->hintMoves, + scaleY ); + + glyphpath->scaleX = font->innerTransform.a; + glyphpath->scaleC = font->innerTransform.c; + glyphpath->scaleY = font->innerTransform.d; + + glyphpath->fractionalTranslation = *fractionalTranslation; + +#if 0 + glyphpath->hShift = hShift; /* for fauxing */ +#endif + + glyphpath->hStemHintArray = hStemHintArray; + glyphpath->vStemHintArray = vStemHintArray; + glyphpath->hintMask = hintMask; /* ptr to current mask */ + glyphpath->hintOriginY = hintOriginY; + glyphpath->blues = blues; + glyphpath->darken = font->darkened; /* TODO: should we make copies? */ + glyphpath->xOffset = font->darkenX; + glyphpath->yOffset = font->darkenY; + glyphpath->miterLimit = 2 * FT_MAX( + cf2_fixedAbs( glyphpath->xOffset ), + cf2_fixedAbs( glyphpath->yOffset ) ); + + /* .1 character space unit */ + glyphpath->snapThreshold = cf2_floatToFixed( 0.1f ); + + glyphpath->moveIsPending = TRUE; + glyphpath->pathIsOpen = FALSE; + glyphpath->elemIsQueued = FALSE; + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_finalize( CF2_GlyphPath glyphpath ) + { + cf2_arrstack_finalize( &glyphpath->hintMoves ); + } + + + /* + * Hint point in y-direction and apply outerTransform. + * Input `current' hint map (which is actually delayed by one element). + * Input x,y point in Character Space. + * Output x,y point in Device Space, including translation. + */ + static void + cf2_glyphpath_hintPoint( CF2_GlyphPath glyphpath, + CF2_HintMap hintmap, + FT_Vector* ppt, + CF2_Fixed x, + CF2_Fixed y ) + { + FT_Vector pt; /* hinted point in upright DS */ + + + pt.x = FT_MulFix( glyphpath->scaleX, x ) + + FT_MulFix( glyphpath->scaleC, y ); + pt.y = cf2_hintmap_map( hintmap, y ); + + ppt->x = FT_MulFix( glyphpath->font->outerTransform.a, pt.x ) + + FT_MulFix( glyphpath->font->outerTransform.c, pt.y ) + + glyphpath->fractionalTranslation.x; + ppt->y = FT_MulFix( glyphpath->font->outerTransform.b, pt.x ) + + FT_MulFix( glyphpath->font->outerTransform.d, pt.y ) + + glyphpath->fractionalTranslation.y; + } + + + /* + * From two line segments, (u1,u2) and (v1,v2), compute a point of + * intersection on the corresponding lines. + * Return false if no intersection is found, or if the intersection is + * too far away from the ends of the line segments, u2 and v1. + * + */ + static FT_Bool + cf2_glyphpath_computeIntersection( CF2_GlyphPath glyphpath, + const FT_Vector* u1, + const FT_Vector* u2, + const FT_Vector* v1, + const FT_Vector* v2, + FT_Vector* intersection ) + { + /* + * Let `u' be a zero-based vector from the first segment, `v' from the + * second segment. + * Let `w 'be the zero-based vector from `u1' to `v1'. + * `perp' is the `perpendicular dot product'; see + * http://mathworld.wolfram.com/PerpDotProduct.html. + * `s' is the parameter for the parametric line for the first segment + * (`u'). + * + * See notation in + * http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm. + * Calculations are done in 16.16, but must handle the squaring of + * line lengths in character space. We scale all vectors by 1/32 to + * avoid overflow. This allows values up to 4095 to be squared. The + * scale factor cancels in the divide. + * + * TODO: the scale factor could be computed from UnitsPerEm. + * + */ + +#define cf2_perp( a, b ) \ + ( FT_MulFix( a.x, b.y ) - FT_MulFix( a.y, b.x ) ) + + /* round and divide by 32 */ +#define CF2_CS_SCALE( x ) \ + ( ( (x) + 0x10 ) >> 5 ) + + FT_Vector u, v, w; /* scaled vectors */ + CF2_Fixed denominator, s; + + + u.x = CF2_CS_SCALE( u2->x - u1->x ); + u.y = CF2_CS_SCALE( u2->y - u1->y ); + v.x = CF2_CS_SCALE( v2->x - v1->x ); + v.y = CF2_CS_SCALE( v2->y - v1->y ); + w.x = CF2_CS_SCALE( v1->x - u1->x ); + w.y = CF2_CS_SCALE( v1->y - u1->y ); + + denominator = cf2_perp( u, v ); + + if ( denominator == 0 ) + return FALSE; /* parallel or coincident lines */ + + s = FT_DivFix( cf2_perp( w, v ), denominator ); + + intersection->x = u1->x + FT_MulFix( s, u2->x - u1->x ); + intersection->y = u1->y + FT_MulFix( s, u2->y - u1->y ); + + /* + * Special case snapping for horizontal and vertical lines. + * This cleans up intersections and reduces problems with winding + * order detection. + * Sample case is sbc cd KozGoPr6N-Medium.otf 20 16685. + * Note: these calculations are in character space. + * + */ + + if ( u1->x == u2->x && + cf2_fixedAbs( intersection->x - u1->x ) < glyphpath->snapThreshold ) + intersection->x = u1->x; + if ( u1->y == u2->y && + cf2_fixedAbs( intersection->y - u1->y ) < glyphpath->snapThreshold ) + intersection->y = u1->y; + + if ( v1->x == v2->x && + cf2_fixedAbs( intersection->x - v1->x ) < glyphpath->snapThreshold ) + intersection->x = v1->x; + if ( v1->y == v2->y && + cf2_fixedAbs( intersection->y - v1->y ) < glyphpath->snapThreshold ) + intersection->y = v1->y; + + /* limit the intersection distance from midpoint of u2 and v1 */ + if ( cf2_fixedAbs( intersection->x - ( u2->x + v1->x ) / 2 ) > + glyphpath->miterLimit || + cf2_fixedAbs( intersection->y - ( u2->y + v1->y ) / 2 ) > + glyphpath->miterLimit ) + return FALSE; + + return TRUE; + } + + + /* + * Push the cached element (glyphpath->prevElem*) to the outline + * consumer. When a darkening offset is used, the end point of the + * cached element may be adjusted to an intersection point or it may be + * connected by a line to the current element. This calculation must + * use a HintMap that was valid at the time the element was saved. For + * the first point in a subpath, that is a saved HintMap. For most + * elements, it just means the caller has delayed building a HintMap + * from the current HintMask. + * + * Transform each point with outerTransform and call the outline + * callbacks. This is a general 3x3 transform: + * + * x' = a*x + c*y + tx, y' = b*x + d*y + ty + * + * but it uses 4 elements from CF2_Font and the translation part + * from CF2_GlyphPath. + * + */ + static void + cf2_glyphpath_pushPrevElem( CF2_GlyphPath glyphpath, + CF2_HintMap hintmap, + FT_Vector* nextP0, + FT_Vector nextP1, + FT_Bool close ) + { + CF2_CallbackParamsRec params; + + FT_Vector* prevP0; + FT_Vector* prevP1; + + FT_Vector intersection = { 0, 0 }; + FT_Bool useIntersection = FALSE; + + + FT_ASSERT( glyphpath->prevElemOp == CF2_PathOpLineTo || + glyphpath->prevElemOp == CF2_PathOpCubeTo ); + + if ( glyphpath->prevElemOp == CF2_PathOpLineTo ) + { + prevP0 = &glyphpath->prevElemP0; + prevP1 = &glyphpath->prevElemP1; + } + else + { + prevP0 = &glyphpath->prevElemP2; + prevP1 = &glyphpath->prevElemP3; + } + + /* optimization: if previous and next elements are offset by the same */ + /* amount, then there will be no gap, and no need to compute an */ + /* intersection. */ + if ( prevP1->x != nextP0->x || prevP1->y != nextP0->y ) + { + /* previous element does not join next element: */ + /* adjust end point of previous element to the intersection */ + useIntersection = cf2_glyphpath_computeIntersection( glyphpath, + prevP0, + prevP1, + nextP0, + &nextP1, + &intersection ); + if ( useIntersection ) + { + /* modify the last point of the cached element (either line or */ + /* curve) */ + *prevP1 = intersection; + } + } + + params.pt0 = glyphpath->currentDS; + + switch( glyphpath->prevElemOp ) + { + case CF2_PathOpLineTo: + params.op = CF2_PathOpLineTo; + + /* note: pt2 and pt3 are unused */ + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + + glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); + + glyphpath->currentDS = params.pt1; + + break; + + case CF2_PathOpCubeTo: + params.op = CF2_PathOpCubeTo; + + /* TODO: should we intersect the interior joins (p1-p2 and p2-p3)? */ + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt2, + glyphpath->prevElemP2.x, + glyphpath->prevElemP2.y ); + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt3, + glyphpath->prevElemP3.x, + glyphpath->prevElemP3.y ); + + glyphpath->callbacks->cubeTo( glyphpath->callbacks, ¶ms ); + + glyphpath->currentDS = params.pt3; + + break; + } + + if ( !useIntersection || close ) + { + /* insert connecting line between end of previous element and start */ + /* of current one */ + /* note: at the end of a subpath, we might do both, so use `nextP0' */ + /* before we change it, below */ + + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + nextP0->x, + nextP0->y ); + + if ( params.pt1.x != glyphpath->currentDS.x || + params.pt1.y != glyphpath->currentDS.y ) + { + /* length is nonzero */ + params.op = CF2_PathOpLineTo; + params.pt0 = glyphpath->currentDS; + + /* note: pt2 and pt3 are unused */ + glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); + + glyphpath->currentDS = params.pt1; + } + } + + if ( useIntersection ) + { + /* return intersection point to caller */ + *nextP0 = intersection; + } + } + + + /* push a MoveTo element based on current point and offset of current */ + /* element */ + static void + cf2_glyphpath_pushMove( CF2_GlyphPath glyphpath, + FT_Vector start ) + { + CF2_CallbackParamsRec params; + + + params.op = CF2_PathOpMoveTo; + params.pt0 = glyphpath->currentDS; + + /* Test if move has really happened yet; it would have called */ + /* `cf2_hintmap_build' to set `isValid'. */ + if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) ) + { + /* we are here iff first subpath is missing a moveto operator: */ + /* synthesize first moveTo to finish initialization of hintMap */ + cf2_glyphpath_moveTo( glyphpath, + glyphpath->start.x, + glyphpath->start.y ); + } + + cf2_glyphpath_hintPoint( glyphpath, + &glyphpath->hintMap, + ¶ms.pt1, + start.x, + start.y ); + + /* note: pt2 and pt3 are unused */ + glyphpath->callbacks->moveTo( glyphpath->callbacks, ¶ms ); + + glyphpath->currentDS = params.pt1; + glyphpath->offsetStart0 = start; + } + + + /* + * All coordinates are in character space. + * On input, (x1, y1) and (x2, y2) give line segment. + * On output, (x, y) give offset vector. + * We use a piecewise approximation to trig functions. + * + * TODO: Offset true perpendicular and proper length + * supply the y-translation for hinting here, too, + * that adds yOffset unconditionally to *y. + */ + static void + cf2_glyphpath_computeOffset( CF2_GlyphPath glyphpath, + CF2_Fixed x1, + CF2_Fixed y1, + CF2_Fixed x2, + CF2_Fixed y2, + CF2_Fixed* x, + CF2_Fixed* y ) + { + CF2_Fixed dx = x2 - x1; + CF2_Fixed dy = y2 - y1; + + + /* note: negative offsets don't work here; negate deltas to change */ + /* quadrants, below */ + if ( glyphpath->font->reverseWinding ) + { + dx = -dx; + dy = -dy; + } + + *x = *y = 0; + + if ( !glyphpath->darken ) + return; + + /* add momentum for this path element */ + glyphpath->callbacks->windingMomentum += + cf2_getWindingMomentum( x1, y1, x2, y2 ); + + /* note: allow mixed integer and fixed multiplication here */ + if ( dx >= 0 ) + { + if ( dy >= 0 ) + { + /* first quadrant, +x +y */ + + if ( dx > 2 * dy ) + { + /* +x */ + *x = 0; + *y = 0; + } + else if ( dy > 2 * dx ) + { + /* +y */ + *x = glyphpath->xOffset; + *y = glyphpath->yOffset; + } + else + { + /* +x +y */ + *x = FT_MulFix( cf2_floatToFixed( 0.7 ), + glyphpath->xOffset ); + *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ), + glyphpath->yOffset ); + } + } + else + { + /* fourth quadrant, +x -y */ + + if ( dx > -2 * dy ) + { + /* +x */ + *x = 0; + *y = 0; + } + else if ( -dy > 2 * dx ) + { + /* -y */ + *x = -glyphpath->xOffset; + *y = glyphpath->yOffset; + } + else + { + /* +x -y */ + *x = FT_MulFix( cf2_floatToFixed( -0.7 ), + glyphpath->xOffset ); + *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ), + glyphpath->yOffset ); + } + } + } + else + { + if ( dy >= 0 ) + { + /* second quadrant, -x +y */ + + if ( -dx > 2 * dy ) + { + /* -x */ + *x = 0; + *y = 2 * glyphpath->yOffset; + } + else if ( dy > -2 * dx ) + { + /* +y */ + *x = glyphpath->xOffset; + *y = glyphpath->yOffset; + } + else + { + /* -x +y */ + *x = FT_MulFix( cf2_floatToFixed( 0.7 ), + glyphpath->xOffset ); + *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ), + glyphpath->yOffset ); + } + } + else + { + /* third quadrant, -x -y */ + + if ( -dx > -2 * dy ) + { + /* -x */ + *x = 0; + *y = 2 * glyphpath->yOffset; + } + else if ( -dy > -2 * dx ) + { + /* -y */ + *x = -glyphpath->xOffset; + *y = glyphpath->xOffset; + } + else + { + /* -x -y */ + *x = FT_MulFix( cf2_floatToFixed( -0.7 ), + glyphpath->xOffset ); + *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ), + glyphpath->yOffset ); + } + } + } + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, + CF2_Fixed x, + CF2_Fixed y ) + { + cf2_glyphpath_closeOpenPath( glyphpath ); + + /* save the parameters of the move for later, when we'll know how to */ + /* offset it; */ + /* also save last move point */ + glyphpath->currentCS.x = glyphpath->start.x = x; + glyphpath->currentCS.y = glyphpath->start.y = y; + + glyphpath->moveIsPending = TRUE; + + /* ensure we have a valid map with current mask */ + if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) || + cf2_hintmask_isNew( glyphpath->hintMask ) ) + cf2_hintmap_build( &glyphpath->hintMap, + glyphpath->hStemHintArray, + glyphpath->vStemHintArray, + glyphpath->hintMask, + glyphpath->hintOriginY, + FALSE ); + + /* save a copy of current HintMap to use when drawing initial point */ + glyphpath->firstHintMap = glyphpath->hintMap; /* structure copy */ + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath, + CF2_Fixed x, + CF2_Fixed y ) + { + CF2_Fixed xOffset, yOffset; + FT_Vector P0, P1; + + + /* can't compute offset of zero length line, so ignore them */ + if ( glyphpath->currentCS.x == x && glyphpath->currentCS.y == y ) + return; + + cf2_glyphpath_computeOffset( glyphpath, + glyphpath->currentCS.x, + glyphpath->currentCS.y, + x, + y, + &xOffset, + &yOffset ); + + /* construct offset points */ + P0.x = glyphpath->currentCS.x + xOffset; + P0.y = glyphpath->currentCS.y + yOffset; + P1.x = x + xOffset; + P1.y = y + yOffset; + + if ( glyphpath->moveIsPending ) + { + /* emit offset 1st point as MoveTo */ + cf2_glyphpath_pushMove( glyphpath, P0 ); + + glyphpath->moveIsPending = FALSE; /* adjust state machine */ + glyphpath->pathIsOpen = TRUE; + + glyphpath->offsetStart1 = P1; /* record second point */ + } + + if ( glyphpath->elemIsQueued ) + { + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ); + + cf2_glyphpath_pushPrevElem( glyphpath, + &glyphpath->hintMap, + &P0, + P1, + FALSE ); + } + + /* queue the current element with offset points */ + glyphpath->elemIsQueued = TRUE; + glyphpath->prevElemOp = CF2_PathOpLineTo; + glyphpath->prevElemP0 = P0; + glyphpath->prevElemP1 = P1; + + /* update current map */ + if ( cf2_hintmask_isNew( glyphpath->hintMask ) ) + cf2_hintmap_build( &glyphpath->hintMap, + glyphpath->hStemHintArray, + glyphpath->vStemHintArray, + glyphpath->hintMask, + glyphpath->hintOriginY, + FALSE ); + + glyphpath->currentCS.x = x; /* pre-offset current point */ + glyphpath->currentCS.y = y; + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath, + CF2_Fixed x1, + CF2_Fixed y1, + CF2_Fixed x2, + CF2_Fixed y2, + CF2_Fixed x3, + CF2_Fixed y3 ) + { + CF2_Fixed xOffset1, yOffset1, xOffset3, yOffset3; + FT_Vector P0, P1, P2, P3; + + + /* TODO: ignore zero length portions of curve?? */ + cf2_glyphpath_computeOffset( glyphpath, + glyphpath->currentCS.x, + glyphpath->currentCS.y, + x1, + y1, + &xOffset1, + &yOffset1 ); + cf2_glyphpath_computeOffset( glyphpath, + x2, + y2, + x3, + y3, + &xOffset3, + &yOffset3 ); + + /* add momentum from the middle segment */ + glyphpath->callbacks->windingMomentum += + cf2_getWindingMomentum( x1, y1, x2, y2 ); + + /* construct offset points */ + P0.x = glyphpath->currentCS.x + xOffset1; + P0.y = glyphpath->currentCS.y + yOffset1; + P1.x = x1 + xOffset1; + P1.y = y1 + yOffset1; + /* note: preserve angle of final segment by using offset3 at both ends */ + P2.x = x2 + xOffset3; + P2.y = y2 + yOffset3; + P3.x = x3 + xOffset3; + P3.y = y3 + yOffset3; + + if ( glyphpath->moveIsPending ) + { + /* emit offset 1st point as MoveTo */ + cf2_glyphpath_pushMove( glyphpath, P0 ); + + glyphpath->moveIsPending = FALSE; + glyphpath->pathIsOpen = TRUE; + + glyphpath->offsetStart1 = P1; /* record second point */ + } + + if ( glyphpath->elemIsQueued ) + { + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ); + + cf2_glyphpath_pushPrevElem( glyphpath, + &glyphpath->hintMap, + &P0, + P1, + FALSE ); + } + + /* queue the current element with offset points */ + glyphpath->elemIsQueued = TRUE; + glyphpath->prevElemOp = CF2_PathOpCubeTo; + glyphpath->prevElemP0 = P0; + glyphpath->prevElemP1 = P1; + glyphpath->prevElemP2 = P2; + glyphpath->prevElemP3 = P3; + + /* update current map */ + if ( cf2_hintmask_isNew( glyphpath->hintMask ) ) + cf2_hintmap_build( &glyphpath->hintMap, + glyphpath->hStemHintArray, + glyphpath->vStemHintArray, + glyphpath->hintMask, + glyphpath->hintOriginY, + FALSE ); + + glyphpath->currentCS.x = x3; /* pre-offset current point */ + glyphpath->currentCS.y = y3; + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath ) + { + if ( glyphpath->pathIsOpen ) + { + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->firstHintMap ) ); + + /* since we need to apply an offset to the implicit lineto, we make */ + /* it explicit here */ + cf2_glyphpath_lineTo( glyphpath, + glyphpath->start.x, + glyphpath->start.y ); + + /* Draw previous element (the explicit LineTo we just created, */ + /* above) and connect it to the start point, but with the offset we */ + /* saved from the first element. */ + /* Use the saved HintMap, too. */ + FT_ASSERT( glyphpath->elemIsQueued ); + + cf2_glyphpath_pushPrevElem( glyphpath, + &glyphpath->firstHintMap, + &glyphpath->offsetStart0, + glyphpath->offsetStart1, + TRUE ); + + /* reset state machine */ + glyphpath->moveIsPending = TRUE; + glyphpath->pathIsOpen = FALSE; + glyphpath->elemIsQueued = FALSE; + } + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2hints.h b/drivers/freetype/src/cff/cf2hints.h new file mode 100644 index 0000000000..c4fa922a39 --- /dev/null +++ b/drivers/freetype/src/cff/cf2hints.h @@ -0,0 +1,287 @@ +/***************************************************************************/ +/* */ +/* cf2hints.h */ +/* */ +/* Adobe's code for handling CFF hints (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2HINTS_H__ +#define __CF2HINTS_H__ + + +FT_BEGIN_HEADER + + + enum + { + CF2_MAX_HINTS = 96 /* maximum # of hints */ + }; + + + /* + * A HintMask object stores a bit mask that specifies which hints in the + * charstring are active at a given time. Hints in CFF must be declared + * at the start, before any drawing operators, with horizontal hints + * preceding vertical hints. The HintMask is ordered the same way, with + * horizontal hints immediately followed by vertical hints. Clients are + * responsible for knowing how many of each type are present. + * + * The maximum total number of hints is 96, as specified by the CFF + * specification. + * + * A HintMask is built 0 or more times while interpreting a charstring, by + * the HintMask operator. There is only one HintMask, but it is built or + * rebuilt each time there is a hint substitution (HintMask operator) in + * the charstring. A default HintMask with all bits set is built if there + * has been no HintMask operator prior to the first drawing operator. + * + */ + + typedef struct CF2_HintMaskRec_ + { + FT_Error* error; + + FT_Bool isValid; + FT_Bool isNew; + + size_t bitCount; + size_t byteCount; + + FT_Byte mask[( CF2_MAX_HINTS + 7 ) / 8]; + + } CF2_HintMaskRec, *CF2_HintMask; + + + typedef struct CF2_StemHintRec_ + { + FT_Bool used; /* DS positions are valid */ + + CF2_Fixed min; /* original character space value */ + CF2_Fixed max; + + CF2_Fixed minDS; /* DS position after first use */ + CF2_Fixed maxDS; + + } CF2_StemHintRec, *CF2_StemHint; + + + /* + * A HintMap object stores a piecewise linear function for mapping + * y-coordinates from character space to device space, providing + * appropriate pixel alignment to stem edges. + * + * The map is implemented as an array of `CF2_Hint' elements, each + * representing an edge. When edges are paired, as from stem hints, the + * bottom edge must immediately precede the top edge in the array. + * Element character space AND device space positions must both increase + * monotonically in the array. `CF2_Hint' elements are also used as + * parameters to `cf2_blues_capture'. + * + * The `cf2_hintmap_build' method must be called before any drawing + * operation (beginning with a Move operator) and at each hint + * substitution (HintMask operator). + * + * The `cf2_hintmap_map' method is called to transform y-coordinates at + * each drawing operation (move, line, curve). + * + */ + + /* TODO: make this a CF2_ArrStack and add a deep copy method */ + enum + { + CF2_MAX_HINT_EDGES = CF2_MAX_HINTS * 2 + }; + + + typedef struct CF2_HintMapRec_ + { + CF2_Font font; + + /* initial map based on blue zones */ + struct CF2_HintMapRec_* initialHintMap; + + /* working storage for 2nd pass adjustHints */ + CF2_ArrStack hintMoves; + + FT_Bool isValid; + FT_Bool hinted; + + CF2_Fixed scale; + CF2_UInt count; + + /* start search from this index */ + CF2_UInt lastIndex; + + CF2_HintRec edge[CF2_MAX_HINT_EDGES]; /* 192 */ + + } CF2_HintMapRec, *CF2_HintMap; + + + FT_LOCAL( FT_Bool ) + cf2_hint_isValid( const CF2_Hint hint ); + FT_LOCAL( FT_Bool ) + cf2_hint_isTop( const CF2_Hint hint ); + FT_LOCAL( FT_Bool ) + cf2_hint_isBottom( const CF2_Hint hint ); + FT_LOCAL( void ) + cf2_hint_lock( CF2_Hint hint ); + + + FT_LOCAL( void ) + cf2_hintmap_init( CF2_HintMap hintmap, + CF2_Font font, + CF2_HintMap initialMap, + CF2_ArrStack hintMoves, + CF2_Fixed scale ); + FT_LOCAL( void ) + cf2_hintmap_build( CF2_HintMap hintmap, + CF2_ArrStack hStemHintArray, + CF2_ArrStack vStemHintArray, + CF2_HintMask hintMask, + CF2_Fixed hintOrigin, + FT_Bool initialMap ); + + + /* + * GlyphPath is a wrapper for drawing operations that scales the + * coordinates according to the render matrix and HintMap. It also tracks + * open paths to control ClosePath and to insert MoveTo for broken fonts. + * + */ + typedef struct CF2_GlyphPathRec_ + { + /* TODO: gather some of these into a hinting context */ + + CF2_Font font; /* font instance */ + CF2_OutlineCallbacks callbacks; /* outline consumer */ + + + CF2_HintMapRec hintMap; /* current hint map */ + CF2_HintMapRec firstHintMap; /* saved copy */ + CF2_HintMapRec initialHintMap; /* based on all captured hints */ + + CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */ + + CF2_Fixed scaleX; /* matrix a */ + CF2_Fixed scaleC; /* matrix c */ + CF2_Fixed scaleY; /* matrix d */ + + FT_Vector fractionalTranslation; /* including deviceXScale */ +#if 0 + CF2_Fixed hShift; /* character space horizontal shift */ + /* (for fauxing) */ +#endif + + FT_Bool pathIsOpen; /* true after MoveTo */ + FT_Bool darken; /* true if stem darkening */ + FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */ + + /* references used to call `cf2_hintmap_build', if necessary */ + CF2_ArrStack hStemHintArray; + CF2_ArrStack vStemHintArray; + CF2_HintMask hintMask; /* ptr to the current mask */ + CF2_Fixed hintOriginY; /* copy of current origin */ + const CF2_BluesRec* blues; + + CF2_Fixed xOffset; /* character space offsets */ + CF2_Fixed yOffset; + + /* character space miter limit threshold */ + CF2_Fixed miterLimit; + /* vertical/horzizontal snap distance in character space */ + CF2_Fixed snapThreshold; + + FT_Vector offsetStart0; /* first and second points of first */ + FT_Vector offsetStart1; /* element with offset applied */ + + /* current point, character space, before offset */ + FT_Vector currentCS; + /* current point, device space */ + FT_Vector currentDS; + FT_Vector start; /* start point of subpath */ + + /* the following members constitute the `queue' of one element */ + FT_Bool elemIsQueued; + CF2_Int prevElemOp; + + FT_Vector prevElemP0; + FT_Vector prevElemP1; + FT_Vector prevElemP2; + FT_Vector prevElemP3; + + } CF2_GlyphPathRec, *CF2_GlyphPath; + + + FT_LOCAL( void ) + cf2_glyphpath_init( CF2_GlyphPath glyphpath, + CF2_Font font, + CF2_OutlineCallbacks callbacks, + CF2_Fixed scaleY, + /* CF2_Fixed hShift, */ + CF2_ArrStack hStemHintArray, + CF2_ArrStack vStemHintArray, + CF2_HintMask hintMask, + CF2_Fixed hintOrigin, + const CF2_Blues blues, + const FT_Vector* fractionalTranslation ); + FT_LOCAL( void ) + cf2_glyphpath_finalize( CF2_GlyphPath glyphpath ); + + FT_LOCAL( void ) + cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, + CF2_Fixed x, + CF2_Fixed y ); + FT_LOCAL( void ) + cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath, + CF2_Fixed x, + CF2_Fixed y ); + FT_LOCAL( void ) + cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath, + CF2_Fixed x1, + CF2_Fixed y1, + CF2_Fixed x2, + CF2_Fixed y2, + CF2_Fixed x3, + CF2_Fixed y3 ); + FT_LOCAL( void ) + cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath ); + + +FT_END_HEADER + + +#endif /* __CF2HINTS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2intrp.c b/drivers/freetype/src/cff/cf2intrp.c new file mode 100644 index 0000000000..5610917cc3 --- /dev/null +++ b/drivers/freetype/src/cff/cf2intrp.c @@ -0,0 +1,1538 @@ +/***************************************************************************/ +/* */ +/* cf2intrp.c */ +/* */ +/* Adobe's CFF Interpreter (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" +#include FT_INTERNAL_DEBUG_H + +#include "cf2glue.h" +#include "cf2font.h" +#include "cf2stack.h" +#include "cf2hints.h" + +#include "cf2error.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_cf2interp + + + /* some operators are not implemented yet */ +#define CF2_FIXME FT_TRACE4(( "cf2_interpT2CharString:" \ + " operator not implemented yet\n" )) + + + + FT_LOCAL_DEF( void ) + cf2_hintmask_init( CF2_HintMask hintmask, + FT_Error* error ) + { + FT_ZERO( hintmask ); + + hintmask->error = error; + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hintmask_isValid( const CF2_HintMask hintmask ) + { + return hintmask->isValid; + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hintmask_isNew( const CF2_HintMask hintmask ) + { + return hintmask->isNew; + } + + + FT_LOCAL_DEF( void ) + cf2_hintmask_setNew( CF2_HintMask hintmask, + FT_Bool val ) + { + hintmask->isNew = val; + } + + + /* clients call `getMaskPtr' in order to iterate */ + /* through hint mask */ + + FT_LOCAL_DEF( FT_Byte* ) + cf2_hintmask_getMaskPtr( CF2_HintMask hintmask ) + { + return hintmask->mask; + } + + + static size_t + cf2_hintmask_setCounts( CF2_HintMask hintmask, + size_t bitCount ) + { + if ( bitCount > CF2_MAX_HINTS ) + { + /* total of h and v stems must be <= 96 */ + CF2_SET_ERROR( hintmask->error, Invalid_Glyph_Format ); + return 0; + } + + hintmask->bitCount = bitCount; + hintmask->byteCount = ( hintmask->bitCount + 7 ) / 8; + + hintmask->isValid = TRUE; + hintmask->isNew = TRUE; + + return bitCount; + } + + + /* consume the hintmask bytes from the charstring, advancing the src */ + /* pointer */ + static void + cf2_hintmask_read( CF2_HintMask hintmask, + CF2_Buffer charstring, + size_t bitCount ) + { + size_t i; + +#ifndef CF2_NDEBUG + /* these are the bits in the final mask byte that should be zero */ + /* Note: this variable is only used in an assert expression below */ + /* and then only if CF2_NDEBUG is not defined */ + CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1; +#endif + + + /* initialize counts and isValid */ + if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 ) + return; + + FT_ASSERT( hintmask->byteCount > 0 ); + + FT_TRACE4(( " (maskbytes:" )); + + /* set mask and advance interpreter's charstring pointer */ + for ( i = 0; i < hintmask->byteCount; i++ ) + { + hintmask->mask[i] = (FT_Byte)cf2_buf_readByte( charstring ); + FT_TRACE4(( " 0x%02X", hintmask->mask[i] )); + } + + FT_TRACE4(( ")\n" )); + + /* assert any unused bits in last byte are zero unless there's a prior */ + /* error */ + /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */ +#ifndef CF2_NDEBUG + FT_ASSERT( ( hintmask->mask[hintmask->byteCount - 1] & mask ) == 0 || + *hintmask->error ); +#endif + } + + + FT_LOCAL_DEF( void ) + cf2_hintmask_setAll( CF2_HintMask hintmask, + size_t bitCount ) + { + size_t i; + CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1; + + + /* initialize counts and isValid */ + if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 ) + return; + + FT_ASSERT( hintmask->byteCount > 0 ); + FT_ASSERT( hintmask->byteCount < + sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) ); + + /* set mask to all ones */ + for ( i = 0; i < hintmask->byteCount; i++ ) + hintmask->mask[i] = 0xFF; + + /* clear unused bits */ + /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */ + hintmask->mask[hintmask->byteCount - 1] &= ~mask; + } + + + /* Type2 charstring opcodes */ + enum + { + cf2_cmdRESERVED_0, /* 0 */ + cf2_cmdHSTEM, /* 1 */ + cf2_cmdRESERVED_2, /* 2 */ + cf2_cmdVSTEM, /* 3 */ + cf2_cmdVMOVETO, /* 4 */ + cf2_cmdRLINETO, /* 5 */ + cf2_cmdHLINETO, /* 6 */ + cf2_cmdVLINETO, /* 7 */ + cf2_cmdRRCURVETO, /* 8 */ + cf2_cmdRESERVED_9, /* 9 */ + cf2_cmdCALLSUBR, /* 10 */ + cf2_cmdRETURN, /* 11 */ + cf2_cmdESC, /* 12 */ + cf2_cmdRESERVED_13, /* 13 */ + cf2_cmdENDCHAR, /* 14 */ + cf2_cmdRESERVED_15, /* 15 */ + cf2_cmdRESERVED_16, /* 16 */ + cf2_cmdRESERVED_17, /* 17 */ + cf2_cmdHSTEMHM, /* 18 */ + cf2_cmdHINTMASK, /* 19 */ + cf2_cmdCNTRMASK, /* 20 */ + cf2_cmdRMOVETO, /* 21 */ + cf2_cmdHMOVETO, /* 22 */ + cf2_cmdVSTEMHM, /* 23 */ + cf2_cmdRCURVELINE, /* 24 */ + cf2_cmdRLINECURVE, /* 25 */ + cf2_cmdVVCURVETO, /* 26 */ + cf2_cmdHHCURVETO, /* 27 */ + cf2_cmdEXTENDEDNMBR, /* 28 */ + cf2_cmdCALLGSUBR, /* 29 */ + cf2_cmdVHCURVETO, /* 30 */ + cf2_cmdHVCURVETO /* 31 */ + }; + + enum + { + cf2_escDOTSECTION, /* 0 */ + cf2_escRESERVED_1, /* 1 */ + cf2_escRESERVED_2, /* 2 */ + cf2_escAND, /* 3 */ + cf2_escOR, /* 4 */ + cf2_escNOT, /* 5 */ + cf2_escRESERVED_6, /* 6 */ + cf2_escRESERVED_7, /* 7 */ + cf2_escRESERVED_8, /* 8 */ + cf2_escABS, /* 9 */ + cf2_escADD, /* 10 like otherADD */ + cf2_escSUB, /* 11 like otherSUB */ + cf2_escDIV, /* 12 */ + cf2_escRESERVED_13, /* 13 */ + cf2_escNEG, /* 14 */ + cf2_escEQ, /* 15 */ + cf2_escRESERVED_16, /* 16 */ + cf2_escRESERVED_17, /* 17 */ + cf2_escDROP, /* 18 */ + cf2_escRESERVED_19, /* 19 */ + cf2_escPUT, /* 20 like otherPUT */ + cf2_escGET, /* 21 like otherGET */ + cf2_escIFELSE, /* 22 like otherIFELSE */ + cf2_escRANDOM, /* 23 like otherRANDOM */ + cf2_escMUL, /* 24 like otherMUL */ + cf2_escRESERVED_25, /* 25 */ + cf2_escSQRT, /* 26 */ + cf2_escDUP, /* 27 like otherDUP */ + cf2_escEXCH, /* 28 like otherEXCH */ + cf2_escINDEX, /* 29 */ + cf2_escROLL, /* 30 */ + cf2_escRESERVED_31, /* 31 */ + cf2_escRESERVED_32, /* 32 */ + cf2_escRESERVED_33, /* 33 */ + cf2_escHFLEX, /* 34 */ + cf2_escFLEX, /* 35 */ + cf2_escHFLEX1, /* 36 */ + cf2_escFLEX1 /* 37 */ + }; + + + /* `stemHintArray' does not change once we start drawing the outline. */ + static void + cf2_doStems( const CF2_Font font, + CF2_Stack opStack, + CF2_ArrStack stemHintArray, + CF2_Fixed* width, + FT_Bool* haveWidth, + CF2_Fixed hintOffset ) + { + CF2_UInt i; + CF2_UInt count = cf2_stack_count( opStack ); + FT_Bool hasWidthArg = (FT_Bool)( count & 1 ); + + /* variable accumulates delta values from operand stack */ + CF2_Fixed position = hintOffset; + + if ( hasWidthArg && ! *haveWidth ) + *width = cf2_stack_getReal( opStack, 0 ) + + cf2_getNominalWidthX( font->decoder ); + + if ( font->decoder->width_only ) + goto exit; + + for ( i = hasWidthArg ? 1 : 0; i < count; i += 2 ) + { + /* construct a CF2_StemHint and push it onto the list */ + CF2_StemHintRec stemhint; + + + stemhint.min = + position += cf2_stack_getReal( opStack, i ); + stemhint.max = + position += cf2_stack_getReal( opStack, i + 1 ); + + stemhint.used = FALSE; + stemhint.maxDS = + stemhint.minDS = 0; + + cf2_arrstack_push( stemHintArray, &stemhint ); /* defer error check */ + } + + cf2_stack_clear( opStack ); + + exit: + /* cf2_doStems must define a width (may be default) */ + *haveWidth = TRUE; + } + + + static void + cf2_doFlex( CF2_Stack opStack, + CF2_Fixed* curX, + CF2_Fixed* curY, + CF2_GlyphPath glyphPath, + const FT_Bool* readFromStack, + FT_Bool doConditionalLastRead ) + { + CF2_Fixed vals[14]; + CF2_UInt index; + FT_Bool isHFlex; + CF2_Int top, i, j; + + + vals[0] = *curX; + vals[1] = *curY; + index = 0; + isHFlex = readFromStack[9] == FALSE; + top = isHFlex ? 9 : 10; + + for ( i = 0; i < top; i++ ) + { + vals[i + 2] = vals[i]; + if ( readFromStack[i] ) + vals[i + 2] += cf2_stack_getReal( opStack, index++ ); + } + + if ( isHFlex ) + vals[9 + 2] = *curY; + + if ( doConditionalLastRead ) + { + FT_Bool lastIsX = (FT_Bool)( cf2_fixedAbs( vals[10] - *curX ) > + cf2_fixedAbs( vals[11] - *curY ) ); + CF2_Fixed lastVal = cf2_stack_getReal( opStack, index ); + + + if ( lastIsX ) + { + vals[12] = vals[10] + lastVal; + vals[13] = *curY; + } + else + { + vals[12] = *curX; + vals[13] = vals[11] + lastVal; + } + } + else + { + if ( readFromStack[10] ) + vals[12] = vals[10] + cf2_stack_getReal( opStack, index++ ); + else + vals[12] = *curX; + + if ( readFromStack[11] ) + vals[13] = vals[11] + cf2_stack_getReal( opStack, index ); + else + vals[13] = *curY; + } + + for ( j = 0; j < 2; j++ ) + cf2_glyphpath_curveTo( glyphPath, vals[j * 6 + 2], + vals[j * 6 + 3], + vals[j * 6 + 4], + vals[j * 6 + 5], + vals[j * 6 + 6], + vals[j * 6 + 7] ); + + cf2_stack_clear( opStack ); + + *curX = vals[12]; + *curY = vals[13]; + } + + + /* + * `error' is a shared error code used by many objects in this + * routine. Before the code continues from an error, it must check and + * record the error in `*error'. The idea is that this shared + * error code will record the first error encountered. If testing + * for an error anyway, the cost of `goto exit' is small, so we do it, + * even if continuing would be safe. In this case, `lastError' is + * set, so the testing and storing can be done in one place, at `exit'. + * + * Continuing after an error is intended for objects which do their own + * testing of `*error', e.g., array stack functions. This allows us to + * avoid an extra test after the call. + * + * Unimplemented opcodes are ignored. + * + */ + FT_LOCAL_DEF( void ) + cf2_interpT2CharString( CF2_Font font, + CF2_Buffer buf, + CF2_OutlineCallbacks callbacks, + const FT_Vector* translation, + FT_Bool doingSeac, + CF2_Fixed curX, + CF2_Fixed curY, + CF2_Fixed* width ) + { + /* lastError is used for errors that are immediately tested */ + FT_Error lastError = FT_Err_Ok; + + /* pointer to parsed font object */ + CFF_Decoder* decoder = font->decoder; + + FT_Error* error = &font->error; + FT_Memory memory = font->memory; + + CF2_Fixed scaleY = font->innerTransform.d; + CF2_Fixed nominalWidthX = cf2_getNominalWidthX( decoder ); + + /* save this for hinting seac accents */ + CF2_Fixed hintOriginY = curY; + + CF2_Stack opStack = NULL; + FT_Byte op1; /* first opcode byte */ + + /* instruction limit; 20,000,000 matches Avalon */ + FT_UInt32 instructionLimit = 20000000UL; + + CF2_ArrStackRec subrStack; + + FT_Bool haveWidth; + CF2_Buffer charstring = NULL; + + CF2_Int charstringIndex = -1; /* initialize to empty */ + + /* TODO: placeholders for hint structures */ + + /* objects used for hinting */ + CF2_ArrStackRec hStemHintArray; + CF2_ArrStackRec vStemHintArray; + + CF2_HintMaskRec hintMask; + CF2_GlyphPathRec glyphPath; + + + /* initialize the remaining objects */ + cf2_arrstack_init( &subrStack, + memory, + error, + sizeof ( CF2_BufferRec ) ); + cf2_arrstack_init( &hStemHintArray, + memory, + error, + sizeof ( CF2_StemHintRec ) ); + cf2_arrstack_init( &vStemHintArray, + memory, + error, + sizeof ( CF2_StemHintRec ) ); + + /* initialize CF2_StemHint arrays */ + cf2_hintmask_init( &hintMask, error ); + + /* initialize path map to manage drawing operations */ + + /* Note: last 4 params are used to handle `MoveToPermissive', which */ + /* may need to call `hintMap.Build' */ + /* TODO: MoveToPermissive is gone; are these still needed? */ + cf2_glyphpath_init( &glyphPath, + font, + callbacks, + scaleY, + /* hShift, */ + &hStemHintArray, + &vStemHintArray, + &hintMask, + hintOriginY, + &font->blues, + translation ); + + /* + * Initialize state for width parsing. From the CFF Spec: + * + * The first stack-clearing operator, which must be one of hstem, + * hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, + * rmoveto, or endchar, takes an additional argument - the width (as + * described earlier), which may be expressed as zero or one numeric + * argument. + * + * What we implement here uses the first validly specified width, but + * does not detect errors for specifying more than one width. + * + * If one of the above operators occurs without explicitly specifying + * a width, we assume the default width. + * + */ + haveWidth = FALSE; + *width = cf2_getDefaultWidthX( decoder ); + + /* + * Note: at this point, all pointers to resources must be NULL + * and all local objects must be initialized. + * There must be no branches to exit: above this point. + * + */ + + /* allocate an operand stack */ + opStack = cf2_stack_init( memory, error ); + if ( !opStack ) + { + lastError = FT_THROW( Out_Of_Memory ); + goto exit; + } + + /* initialize subroutine stack by placing top level charstring as */ + /* first element (max depth plus one for the charstring) */ + /* Note: Caller owns and must finalize the first charstring. */ + /* Our copy of it does not change that requirement. */ + cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 ); + + charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack ); + *charstring = *buf; /* structure copy */ + + charstringIndex = 0; /* entry is valid now */ + + /* catch errors so far */ + if ( *error ) + goto exit; + + /* main interpreter loop */ + while ( 1 ) + { + if ( cf2_buf_isEnd( charstring ) ) + { + /* If we've reached the end of the charstring, simulate a */ + /* cf2_cmdRETURN or cf2_cmdENDCHAR. */ + if ( charstringIndex ) + op1 = cf2_cmdRETURN; /* end of buffer for subroutine */ + else + op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */ + } + else + op1 = (FT_Byte)cf2_buf_readByte( charstring ); + + /* check for errors once per loop */ + if ( *error ) + goto exit; + + instructionLimit--; + if ( instructionLimit == 0 ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + switch( op1 ) + { + case cf2_cmdRESERVED_0: + case cf2_cmdRESERVED_2: + case cf2_cmdRESERVED_9: + case cf2_cmdRESERVED_13: + case cf2_cmdRESERVED_15: + case cf2_cmdRESERVED_16: + case cf2_cmdRESERVED_17: + /* we may get here if we have a prior error */ + FT_TRACE4(( " unknown op (%d)\n", op1 )); + break; + + case cf2_cmdHSTEMHM: + case cf2_cmdHSTEM: + FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" )); + + /* never add hints after the mask is computed */ + if ( cf2_hintmask_isValid( &hintMask ) ) + FT_TRACE4(( "cf2_interpT2CharString:" + " invalid horizontal hint mask\n" )); + + cf2_doStems( font, + opStack, + &hStemHintArray, + width, + &haveWidth, + 0 ); + + if ( font->decoder->width_only ) + goto exit; + + break; + + case cf2_cmdVSTEMHM: + case cf2_cmdVSTEM: + FT_TRACE4(( op1 == cf2_cmdVSTEMHM ? " vstemhm\n" : " vstem\n" )); + + /* never add hints after the mask is computed */ + if ( cf2_hintmask_isValid( &hintMask ) ) + FT_TRACE4(( "cf2_interpT2CharString:" + " invalid vertical hint mask\n" )); + + cf2_doStems( font, + opStack, + &vStemHintArray, + width, + &haveWidth, + 0 ); + + if ( font->decoder->width_only ) + goto exit; + + break; + + case cf2_cmdVMOVETO: + FT_TRACE4(( " vmoveto\n" )); + + if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) + *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; + + /* width is defined or default after this */ + haveWidth = TRUE; + + if ( font->decoder->width_only ) + goto exit; + + curY += cf2_stack_popFixed( opStack ); + + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + + break; + + case cf2_cmdRLINETO: + { + CF2_UInt index; + CF2_UInt count = cf2_stack_count( opStack ); + + + FT_TRACE4(( " rlineto\n" )); + + for ( index = 0; index < count; index += 2 ) + { + curX += cf2_stack_getReal( opStack, index + 0 ); + curY += cf2_stack_getReal( opStack, index + 1 ); + + cf2_glyphpath_lineTo( &glyphPath, curX, curY ); + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdHLINETO: + case cf2_cmdVLINETO: + { + CF2_UInt index; + CF2_UInt count = cf2_stack_count( opStack ); + + FT_Bool isX = op1 == cf2_cmdHLINETO; + + + FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" )); + + for ( index = 0; index < count; index++ ) + { + CF2_Fixed v = cf2_stack_getReal( opStack, index ); + + + if ( isX ) + curX += v; + else + curY += v; + + isX = !isX; + + cf2_glyphpath_lineTo( &glyphPath, curX, curY ); + } + + cf2_stack_clear( opStack ); + } + continue; + + case cf2_cmdRCURVELINE: + case cf2_cmdRRCURVETO: + { + CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt index = 0; + + + FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n" + : " rrcurveto\n" )); + + while ( index + 6 <= count ) + { + CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; + CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY; + CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1; + CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1; + CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; + CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2; + + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + index += 6; + } + + if ( op1 == cf2_cmdRCURVELINE ) + { + curX += cf2_stack_getReal( opStack, index + 0 ); + curY += cf2_stack_getReal( opStack, index + 1 ); + + cf2_glyphpath_lineTo( &glyphPath, curX, curY ); + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdCALLGSUBR: + case cf2_cmdCALLSUBR: + { + CF2_UInt subrIndex; + + + FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr" + : " callsubr" )); + + if ( charstringIndex > CF2_MAX_SUBR ) + { + /* max subr plus one for charstring */ + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* overflow of stack */ + } + + /* push our current CFF charstring region on subrStack */ + charstring = (CF2_Buffer) + cf2_arrstack_getPointer( &subrStack, + charstringIndex + 1 ); + + /* set up the new CFF region and pointer */ + subrIndex = cf2_stack_popInt( opStack ); + + switch ( op1 ) + { + case cf2_cmdCALLGSUBR: + FT_TRACE4(( "(%d)\n", subrIndex + decoder->globals_bias )); + + if ( cf2_initGlobalRegionBuffer( decoder, + subrIndex, + charstring ) ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* subroutine lookup or stream error */ + } + break; + + default: + /* cf2_cmdCALLSUBR */ + FT_TRACE4(( "(%d)\n", subrIndex + decoder->locals_bias )); + + if ( cf2_initLocalRegionBuffer( decoder, + subrIndex, + charstring ) ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* subroutine lookup or stream error */ + } + } + + charstringIndex += 1; /* entry is valid now */ + } + continue; /* do not clear the stack */ + + case cf2_cmdRETURN: + FT_TRACE4(( " return\n" )); + + if ( charstringIndex < 1 ) + { + /* Note: cannot return from top charstring */ + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* underflow of stack */ + } + + /* restore position in previous charstring */ + charstring = (CF2_Buffer) + cf2_arrstack_getPointer( &subrStack, + --charstringIndex ); + continue; /* do not clear the stack */ + + case cf2_cmdESC: + { + FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring ); + + + switch ( op2 ) + { + case cf2_escDOTSECTION: + /* something about `flip type of locking' -- ignore it */ + FT_TRACE4(( " dotsection\n" )); + + break; + + /* TODO: should these operators be supported? */ + case cf2_escAND: /* in spec */ + FT_TRACE4(( " and\n" )); + + CF2_FIXME; + break; + + case cf2_escOR: /* in spec */ + FT_TRACE4(( " or\n" )); + + CF2_FIXME; + break; + + case cf2_escNOT: /* in spec */ + FT_TRACE4(( " not\n" )); + + CF2_FIXME; + break; + + case cf2_escABS: /* in spec */ + FT_TRACE4(( " abs\n" )); + + CF2_FIXME; + break; + + case cf2_escADD: /* in spec */ + FT_TRACE4(( " add\n" )); + + CF2_FIXME; + break; + + case cf2_escSUB: /* in spec */ + FT_TRACE4(( " sub\n" )); + + CF2_FIXME; + break; + + case cf2_escDIV: /* in spec */ + FT_TRACE4(( " div\n" )); + + CF2_FIXME; + break; + + case cf2_escNEG: /* in spec */ + FT_TRACE4(( " neg\n" )); + + CF2_FIXME; + break; + + case cf2_escEQ: /* in spec */ + FT_TRACE4(( " eq\n" )); + + CF2_FIXME; + break; + + case cf2_escDROP: /* in spec */ + FT_TRACE4(( " drop\n" )); + + CF2_FIXME; + break; + + case cf2_escPUT: /* in spec */ + FT_TRACE4(( " put\n" )); + + CF2_FIXME; + break; + + case cf2_escGET: /* in spec */ + FT_TRACE4(( " get\n" )); + + CF2_FIXME; + break; + + case cf2_escIFELSE: /* in spec */ + FT_TRACE4(( " ifelse\n" )); + + CF2_FIXME; + break; + + case cf2_escRANDOM: /* in spec */ + FT_TRACE4(( " random\n" )); + + CF2_FIXME; + break; + + case cf2_escMUL: /* in spec */ + FT_TRACE4(( " mul\n" )); + + CF2_FIXME; + break; + + case cf2_escSQRT: /* in spec */ + FT_TRACE4(( " sqrt\n" )); + + CF2_FIXME; + break; + + case cf2_escDUP: /* in spec */ + FT_TRACE4(( " dup\n" )); + + CF2_FIXME; + break; + + case cf2_escEXCH: /* in spec */ + FT_TRACE4(( " exch\n" )); + + CF2_FIXME; + break; + + case cf2_escINDEX: /* in spec */ + FT_TRACE4(( " index\n" )); + + CF2_FIXME; + break; + + case cf2_escROLL: /* in spec */ + FT_TRACE4(( " roll\n" )); + + CF2_FIXME; + break; + + case cf2_escHFLEX: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, FALSE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, FALSE /* dy3 */, + TRUE /* dx4 */, FALSE /* dy4 */, + TRUE /* dx5 */, FALSE /* dy5 */, + TRUE /* dx6 */, FALSE /* dy6 */ + }; + + + FT_TRACE4(( " hflex\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); + } + continue; + + case cf2_escFLEX: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, TRUE /* dy3 */, + TRUE /* dx4 */, TRUE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + TRUE /* dx6 */, TRUE /* dy6 */ + }; + + + FT_TRACE4(( " flex\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); + } + break; /* TODO: why is this not a continue? */ + + case cf2_escHFLEX1: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, FALSE /* dy3 */, + TRUE /* dx4 */, FALSE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + TRUE /* dx6 */, FALSE /* dy6 */ + }; + + + FT_TRACE4(( " hflex1\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); + } + continue; + + case cf2_escFLEX1: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, TRUE /* dy3 */, + TRUE /* dx4 */, TRUE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + FALSE /* dx6 */, FALSE /* dy6 */ + }; + + + FT_TRACE4(( " flex1\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + TRUE /* doConditionalLastRead */ ); + } + continue; + + case cf2_escRESERVED_1: + case cf2_escRESERVED_2: + case cf2_escRESERVED_6: + case cf2_escRESERVED_7: + case cf2_escRESERVED_8: + case cf2_escRESERVED_13: + case cf2_escRESERVED_16: + case cf2_escRESERVED_17: + case cf2_escRESERVED_19: + case cf2_escRESERVED_25: + case cf2_escRESERVED_31: + case cf2_escRESERVED_32: + case cf2_escRESERVED_33: + default: + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + + }; /* end of switch statement checking `op2' */ + + } /* case cf2_cmdESC */ + break; + + case cf2_cmdENDCHAR: + FT_TRACE4(( " endchar\n" )); + + if ( cf2_stack_count( opStack ) == 1 || + cf2_stack_count( opStack ) == 5 ) + { + if ( !haveWidth ) + *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; + } + + /* width is defined or default after this */ + haveWidth = TRUE; + + if ( font->decoder->width_only ) + goto exit; + + /* close path if still open */ + cf2_glyphpath_closeOpenPath( &glyphPath ); + + if ( cf2_stack_count( opStack ) > 1 ) + { + /* must be either 4 or 5 -- */ + /* this is a (deprecated) implied `seac' operator */ + + CF2_UInt achar; + CF2_UInt bchar; + CF2_BufferRec component; + CF2_Fixed dummyWidth; /* ignore component width */ + FT_Error error2; + + + if ( doingSeac ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* nested seac */ + } + + achar = cf2_stack_popInt( opStack ); + bchar = cf2_stack_popInt( opStack ); + + curY = cf2_stack_popFixed( opStack ); + curX = cf2_stack_popFixed( opStack ); + + error2 = cf2_getSeacComponent( decoder, achar, &component ); + if ( error2 ) + { + lastError = error2; /* pass FreeType error through */ + goto exit; + } + cf2_interpT2CharString( font, + &component, + callbacks, + translation, + TRUE, + curX, + curY, + &dummyWidth ); + cf2_freeSeacComponent( decoder, &component ); + + error2 = cf2_getSeacComponent( decoder, bchar, &component ); + if ( error2 ) + { + lastError = error2; /* pass FreeType error through */ + goto exit; + } + cf2_interpT2CharString( font, + &component, + callbacks, + translation, + TRUE, + 0, + 0, + &dummyWidth ); + cf2_freeSeacComponent( decoder, &component ); + } + goto exit; + + case cf2_cmdCNTRMASK: + case cf2_cmdHINTMASK: + /* the final \n in the tracing message gets added in */ + /* `cf2_hintmask_read' (which also traces the mask bytes) */ + FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" )); + + /* if there are arguments on the stack, there this is an */ + /* implied cf2_cmdVSTEMHM */ + if ( cf2_stack_count( opStack ) != 0 ) + { + /* never add hints after the mask is computed */ + if ( cf2_hintmask_isValid( &hintMask ) ) + FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" )); + } + + cf2_doStems( font, + opStack, + &vStemHintArray, + width, + &haveWidth, + 0 ); + + if ( font->decoder->width_only ) + goto exit; + + if ( op1 == cf2_cmdHINTMASK ) + { + /* consume the hint mask bytes which follow the operator */ + cf2_hintmask_read( &hintMask, + charstring, + cf2_arrstack_size( &hStemHintArray ) + + cf2_arrstack_size( &vStemHintArray ) ); + } + else + { + /* + * Consume the counter mask bytes which follow the operator: + * Build a temporary hint map, just to place and lock those + * stems participating in the counter mask. These are most + * likely the dominant hstems, and are grouped together in a + * few counter groups, not necessarily in correspondence + * with the hint groups. This reduces the chances of + * conflicts between hstems that are initially placed in + * separate hint groups and then brought together. The + * positions are copied back to `hStemHintArray', so we can + * discard `counterMask' and `counterHintMap'. + * + */ + CF2_HintMapRec counterHintMap; + CF2_HintMaskRec counterMask; + + + cf2_hintmap_init( &counterHintMap, + font, + &glyphPath.initialHintMap, + &glyphPath.hintMoves, + scaleY ); + cf2_hintmask_init( &counterMask, error ); + + cf2_hintmask_read( &counterMask, + charstring, + cf2_arrstack_size( &hStemHintArray ) + + cf2_arrstack_size( &vStemHintArray ) ); + cf2_hintmap_build( &counterHintMap, + &hStemHintArray, + &vStemHintArray, + &counterMask, + 0, + FALSE ); + } + break; + + case cf2_cmdRMOVETO: + FT_TRACE4(( " rmoveto\n" )); + + if ( cf2_stack_count( opStack ) > 2 && !haveWidth ) + *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; + + /* width is defined or default after this */ + haveWidth = TRUE; + + if ( font->decoder->width_only ) + goto exit; + + curY += cf2_stack_popFixed( opStack ); + curX += cf2_stack_popFixed( opStack ); + + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + + break; + + case cf2_cmdHMOVETO: + FT_TRACE4(( " hmoveto\n" )); + + if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) + *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; + + /* width is defined or default after this */ + haveWidth = TRUE; + + if ( font->decoder->width_only ) + goto exit; + + curX += cf2_stack_popFixed( opStack ); + + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + + break; + + case cf2_cmdRLINECURVE: + { + CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt index = 0; + + + FT_TRACE4(( " rlinecurve\n" )); + + while ( index + 6 < count ) + { + curX += cf2_stack_getReal( opStack, index + 0 ); + curY += cf2_stack_getReal( opStack, index + 1 ); + + cf2_glyphpath_lineTo( &glyphPath, curX, curY ); + index += 2; + } + + while ( index < count ) + { + CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; + CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY; + CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1; + CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1; + CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; + CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2; + + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + index += 6; + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdVVCURVETO: + { + CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt index = 0; + + + FT_TRACE4(( " vvcurveto\n" )); + + while ( index < count ) + { + CF2_Fixed x1, y1, x2, y2, x3, y3; + + + if ( ( count - index ) & 1 ) + { + x1 = cf2_stack_getReal( opStack, index ) + curX; + + ++index; + } + else + x1 = curX; + + y1 = cf2_stack_getReal( opStack, index + 0 ) + curY; + x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; + y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; + x3 = x2; + y3 = cf2_stack_getReal( opStack, index + 3 ) + y2; + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + index += 4; + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdHHCURVETO: + { + CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt index = 0; + + + FT_TRACE4(( " hhcurveto\n" )); + + while ( index < count ) + { + CF2_Fixed x1, y1, x2, y2, x3, y3; + + + if ( ( count - index ) & 1 ) + { + y1 = cf2_stack_getReal( opStack, index ) + curY; + + ++index; + } + else + y1 = curY; + + x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; + x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; + y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; + x3 = cf2_stack_getReal( opStack, index + 3 ) + x2; + y3 = y2; + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + index += 4; + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdVHCURVETO: + case cf2_cmdHVCURVETO: + { + CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt index = 0; + + FT_Bool alternate = op1 == cf2_cmdHVCURVETO; + + + FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" )); + + while ( index < count ) + { + CF2_Fixed x1, x2, x3, y1, y2, y3; + + + if ( alternate ) + { + x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; + y1 = curY; + x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; + y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; + y3 = cf2_stack_getReal( opStack, index + 3 ) + y2; + + if ( count - index == 5 ) + { + x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; + + ++index; + } + else + x3 = x2; + + alternate = FALSE; + } + else + { + x1 = curX; + y1 = cf2_stack_getReal( opStack, index + 0 ) + curY; + x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; + y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; + x3 = cf2_stack_getReal( opStack, index + 3 ) + x2; + + if ( count - index == 5 ) + { + y3 = cf2_stack_getReal( opStack, index + 4 ) + y2; + + ++index; + } + else + y3 = y2; + + alternate = TRUE; + } + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + index += 4; + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdEXTENDEDNMBR: + { + CF2_Int v; + + + v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) | + cf2_buf_readByte( charstring ) ); + + FT_TRACE4(( " %d", v )); + + cf2_stack_pushInt( opStack, v ); + } + continue; + + default: + /* numbers */ + { + if ( /* op1 >= 32 && */ op1 <= 246 ) + { + CF2_Int v; + + + v = op1 - 139; + + FT_TRACE4(( " %d", v )); + + /* -107 .. 107 */ + cf2_stack_pushInt( opStack, v ); + } + + else if ( /* op1 >= 247 && */ op1 <= 250 ) + { + CF2_Int v; + + + v = op1; + v -= 247; + v *= 256; + v += cf2_buf_readByte( charstring ); + v += 108; + + FT_TRACE4(( " %d", v )); + + /* 108 .. 1131 */ + cf2_stack_pushInt( opStack, v ); + } + + else if ( /* op1 >= 251 && */ op1 <= 254 ) + { + CF2_Int v; + + + v = op1; + v -= 251; + v *= 256; + v += cf2_buf_readByte( charstring ); + v = -v - 108; + + FT_TRACE4(( " %d", v )); + + /* -1131 .. -108 */ + cf2_stack_pushInt( opStack, v ); + } + + else /* op1 == 255 */ + { + CF2_Fixed v; + + + v = (CF2_Fixed) + ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) | + ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) | + ( (FT_UInt32)cf2_buf_readByte( charstring ) << 8 ) | + (FT_UInt32)cf2_buf_readByte( charstring ) ); + + FT_TRACE4(( " %.2f", v / 65536.0 )); + + cf2_stack_pushFixed( opStack, v ); + } + } + continue; /* don't clear stack */ + + } /* end of switch statement checking `op1' */ + + cf2_stack_clear( opStack ); + + } /* end of main interpreter loop */ + + /* we get here if the charstring ends without cf2_cmdENDCHAR */ + FT_TRACE4(( "cf2_interpT2CharString:" + " charstring ends without ENDCHAR\n" )); + + exit: + /* check whether last error seen is also the first one */ + cf2_setError( error, lastError ); + + /* free resources from objects we've used */ + cf2_glyphpath_finalize( &glyphPath ); + cf2_arrstack_finalize( &vStemHintArray ); + cf2_arrstack_finalize( &hStemHintArray ); + cf2_arrstack_finalize( &subrStack ); + cf2_stack_free( opStack ); + + FT_TRACE4(( "\n" )); + + return; + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2intrp.h b/drivers/freetype/src/cff/cf2intrp.h new file mode 100644 index 0000000000..b5d8947838 --- /dev/null +++ b/drivers/freetype/src/cff/cf2intrp.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* cf2font.h */ +/* */ +/* Adobe's CFF Interpreter (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2INTRP_H__ +#define __CF2INTRP_H__ + + +#include "cf2ft.h" +#include "cf2hints.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + cf2_hintmask_init( CF2_HintMask hintmask, + FT_Error* error ); + FT_LOCAL( FT_Bool ) + cf2_hintmask_isValid( const CF2_HintMask hintmask ); + FT_LOCAL( FT_Bool ) + cf2_hintmask_isNew( const CF2_HintMask hintmask ); + FT_LOCAL( void ) + cf2_hintmask_setNew( CF2_HintMask hintmask, + FT_Bool val ); + FT_LOCAL( FT_Byte* ) + cf2_hintmask_getMaskPtr( CF2_HintMask hintmask ); + FT_LOCAL( void ) + cf2_hintmask_setAll( CF2_HintMask hintmask, + size_t bitCount ); + + FT_LOCAL( void ) + cf2_interpT2CharString( CF2_Font font, + CF2_Buffer charstring, + CF2_OutlineCallbacks callbacks, + const FT_Vector* translation, + FT_Bool doingSeac, + CF2_Fixed curX, + CF2_Fixed curY, + CF2_Fixed* width ); + + +FT_END_HEADER + + +#endif /* __CF2INTRP_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2read.c b/drivers/freetype/src/cff/cf2read.c new file mode 100644 index 0000000000..2b429e3eeb --- /dev/null +++ b/drivers/freetype/src/cff/cf2read.c @@ -0,0 +1,112 @@ +/***************************************************************************/ +/* */ +/* cf2read.c */ +/* */ +/* Adobe's code for stream handling (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" +#include FT_INTERNAL_DEBUG_H + +#include "cf2glue.h" + +#include "cf2error.h" + + + /* Define CF2_IO_FAIL as 1 to enable random errors and random */ + /* value errors in I/O. */ +#define CF2_IO_FAIL 0 + + +#if CF2_IO_FAIL + + /* set the .00 value to a nonzero probability */ + static int + randomError2( void ) + { + /* for region buffer ReadByte (interp) function */ + return (double)rand() / RAND_MAX < .00; + } + + /* set the .00 value to a nonzero probability */ + static CF2_Int + randomValue() + { + return (double)rand() / RAND_MAX < .00 ? rand() : 0; + } + +#endif /* CF2_IO_FAIL */ + + + /* Region Buffer */ + /* */ + /* Can be constructed from a copied buffer managed by */ + /* `FCM_getDatablock'. */ + /* Reads bytes with check for end of buffer. */ + + /* reading past the end of the buffer sets error and returns zero */ + FT_LOCAL_DEF( CF2_Int ) + cf2_buf_readByte( CF2_Buffer buf ) + { + if ( buf->ptr < buf->end ) + { +#if CF2_IO_FAIL + if ( randomError2() ) + { + CF2_SET_ERROR( buf->error, Invalid_Stream_Operation ); + return 0; + } + + return *(buf->ptr)++ + randomValue(); +#else + return *(buf->ptr)++; +#endif + } + else + { + CF2_SET_ERROR( buf->error, Invalid_Stream_Operation ); + return 0; + } + } + + + /* note: end condition can occur without error */ + FT_LOCAL_DEF( FT_Bool ) + cf2_buf_isEnd( CF2_Buffer buf ) + { + return (FT_Bool)( buf->ptr >= buf->end ); + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2read.h b/drivers/freetype/src/cff/cf2read.h new file mode 100644 index 0000000000..7ef7c8c149 --- /dev/null +++ b/drivers/freetype/src/cff/cf2read.h @@ -0,0 +1,68 @@ +/***************************************************************************/ +/* */ +/* cf2read.h */ +/* */ +/* Adobe's code for stream handling (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2READ_H__ +#define __CF2READ_H__ + + +FT_BEGIN_HEADER + + + typedef struct CF2_BufferRec_ + { + FT_Error* error; + const FT_Byte* start; + const FT_Byte* end; + const FT_Byte* ptr; + + } CF2_BufferRec, *CF2_Buffer; + + + FT_LOCAL( CF2_Int ) + cf2_buf_readByte( CF2_Buffer buf ); + FT_LOCAL( FT_Bool ) + cf2_buf_isEnd( CF2_Buffer buf ); + + +FT_END_HEADER + + +#endif /* __CF2READ_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2stack.c b/drivers/freetype/src/cff/cf2stack.c new file mode 100644 index 0000000000..8332b5d91a --- /dev/null +++ b/drivers/freetype/src/cff/cf2stack.c @@ -0,0 +1,205 @@ +/***************************************************************************/ +/* */ +/* cf2stack.c */ +/* */ +/* Adobe's code for emulating a CFF stack (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "cf2ft.h" +#include FT_INTERNAL_DEBUG_H + +#include "cf2glue.h" +#include "cf2font.h" +#include "cf2stack.h" + +#include "cf2error.h" + + + /* Allocate and initialize an instance of CF2_Stack. */ + /* Note: This function returns NULL on error (does not set */ + /* `error'). */ + FT_LOCAL_DEF( CF2_Stack ) + cf2_stack_init( FT_Memory memory, + FT_Error* e ) + { + FT_Error error = FT_Err_Ok; /* for FT_QNEW */ + + CF2_Stack stack = NULL; + + + if ( !FT_QNEW( stack ) ) + { + /* initialize the structure; FT_QNEW zeroes it */ + stack->memory = memory; + stack->error = e; + stack->top = &stack->buffer[0]; /* empty stack */ + } + + return stack; + } + + + FT_LOCAL_DEF( void ) + cf2_stack_free( CF2_Stack stack ) + { + if ( stack ) + { + FT_Memory memory = stack->memory; + + + /* free the main structure */ + FT_FREE( stack ); + } + } + + + FT_LOCAL_DEF( CF2_UInt ) + cf2_stack_count( CF2_Stack stack ) + { + return (CF2_UInt)( stack->top - &stack->buffer[0] ); + } + + + FT_LOCAL_DEF( void ) + cf2_stack_pushInt( CF2_Stack stack, + CF2_Int val ) + { + if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; /* stack overflow */ + } + + stack->top->u.i = val; + stack->top->type = CF2_NumberInt; + ++stack->top; + } + + + FT_LOCAL_DEF( void ) + cf2_stack_pushFixed( CF2_Stack stack, + CF2_Fixed val ) + { + if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; /* stack overflow */ + } + + stack->top->u.r = val; + stack->top->type = CF2_NumberFixed; + ++stack->top; + } + + + /* this function is only allowed to pop an integer type */ + FT_LOCAL_DEF( CF2_Int ) + cf2_stack_popInt( CF2_Stack stack ) + { + if ( stack->top == &stack->buffer[0] ) + { + CF2_SET_ERROR( stack->error, Stack_Underflow ); + return 0; /* underflow */ + } + if ( stack->top[-1].type != CF2_NumberInt ) + { + CF2_SET_ERROR( stack->error, Syntax_Error ); + return 0; /* type mismatch */ + } + + --stack->top; + + return stack->top->u.i; + } + + + /* Note: type mismatch is silently cast */ + /* TODO: check this */ + FT_LOCAL_DEF( CF2_Fixed ) + cf2_stack_popFixed( CF2_Stack stack ) + { + if ( stack->top == &stack->buffer[0] ) + { + CF2_SET_ERROR( stack->error, Stack_Underflow ); + return cf2_intToFixed( 0 ); /* underflow */ + } + + --stack->top; + + switch ( stack->top->type ) + { + case CF2_NumberInt: + return cf2_intToFixed( stack->top->u.i ); + case CF2_NumberFrac: + return cf2_fracToFixed( stack->top->u.f ); + default: + return stack->top->u.r; + } + } + + + /* Note: type mismatch is silently cast */ + /* TODO: check this */ + FT_LOCAL_DEF( CF2_Fixed ) + cf2_stack_getReal( CF2_Stack stack, + CF2_UInt idx ) + { + FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE ); + + if ( idx >= cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return cf2_intToFixed( 0 ); /* bounds error */ + } + + switch ( stack->buffer[idx].type ) + { + case CF2_NumberInt: + return cf2_intToFixed( stack->buffer[idx].u.i ); + case CF2_NumberFrac: + return cf2_fracToFixed( stack->buffer[idx].u.f ); + default: + return stack->buffer[idx].u.r; + } + } + + + FT_LOCAL_DEF( void ) + cf2_stack_clear( CF2_Stack stack ) + { + stack->top = &stack->buffer[0]; + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2stack.h b/drivers/freetype/src/cff/cf2stack.h new file mode 100644 index 0000000000..7d6d1961fe --- /dev/null +++ b/drivers/freetype/src/cff/cf2stack.h @@ -0,0 +1,106 @@ +/***************************************************************************/ +/* */ +/* cf2stack.h */ +/* */ +/* Adobe's code for emulating a CFF stack (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2STACK_H__ +#define __CF2STACK_H__ + + +FT_BEGIN_HEADER + + + /* CFF operand stack; specified maximum of 48 or 192 values */ + typedef struct CF2_StackNumber_ + { + union + { + CF2_Fixed r; /* 16.16 fixed point */ + CF2_Frac f; /* 2.30 fixed point (for font matrix) */ + CF2_Int i; + } u; + + CF2_NumberType type; + + } CF2_StackNumber; + + + typedef struct CF2_StackRec_ + { + FT_Memory memory; + FT_Error* error; + CF2_StackNumber buffer[CF2_OPERAND_STACK_SIZE]; + CF2_StackNumber* top; + + } CF2_StackRec, *CF2_Stack; + + + FT_LOCAL( CF2_Stack ) + cf2_stack_init( FT_Memory memory, + FT_Error* error ); + FT_LOCAL( void ) + cf2_stack_free( CF2_Stack stack ); + + FT_LOCAL( CF2_UInt ) + cf2_stack_count( CF2_Stack stack ); + + FT_LOCAL( void ) + cf2_stack_pushInt( CF2_Stack stack, + CF2_Int val ); + FT_LOCAL( void ) + cf2_stack_pushFixed( CF2_Stack stack, + CF2_Fixed val ); + + FT_LOCAL( CF2_Int ) + cf2_stack_popInt( CF2_Stack stack ); + FT_LOCAL( CF2_Fixed ) + cf2_stack_popFixed( CF2_Stack stack ); + + FT_LOCAL( CF2_Fixed ) + cf2_stack_getReal( CF2_Stack stack, + CF2_UInt idx ); + + FT_LOCAL( void ) + cf2_stack_clear( CF2_Stack stack ); + + +FT_END_HEADER + + +#endif /* __CF2STACK_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cf2types.h b/drivers/freetype/src/cff/cf2types.h new file mode 100644 index 0000000000..ac6a02266e --- /dev/null +++ b/drivers/freetype/src/cff/cf2types.h @@ -0,0 +1,78 @@ +/***************************************************************************/ +/* */ +/* cf2types.h */ +/* */ +/* Adobe's code for defining data types (specification only). */ +/* */ +/* Copyright 2011-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CF2TYPES_H__ +#define __CF2TYPES_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /* + * The data models that we expect to support are as follows: + * + * name char short int long long-long pointer example + * ----------------------------------------------------- + * ILP32 8 16 32 32 64* 32 32-bit MacOS, x86 + * LLP64 8 16 32 32 64 64 x64 + * LP64 8 16 32 64 64 64 64-bit MacOS + * + * *) type may be supported by emulation on a 32-bit architecture + * + */ + + + /* integers at least 32 bits wide */ +#define CF2_UInt FT_UFast +#define CF2_Int FT_Fast + + + /* fixed-float numbers */ + typedef FT_Int32 CF2_F16Dot16; + + +FT_END_HEADER + + +#endif /* __CF2TYPES_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cff.c b/drivers/freetype/src/cff/cff.c new file mode 100644 index 0000000000..c3840b5838 --- /dev/null +++ b/drivers/freetype/src/cff/cff.c @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* cff.c */ +/* */ +/* FreeType OpenType driver component (body only). */ +/* */ +/* Copyright 1996-2001, 2002, 2013 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> + +#include "cffpic.c" +#include "cffdrivr.c" +#include "cffparse.c" +#include "cffload.c" +#include "cffobjs.c" +#include "cffgload.c" +#include "cffcmap.c" + +#include "cf2arrst.c" +#include "cf2blues.c" +#include "cf2error.c" +#include "cf2font.c" +#include "cf2ft.c" +#include "cf2hints.c" +#include "cf2intrp.c" +#include "cf2read.c" +#include "cf2stack.c" + +/* END */ diff --git a/drivers/freetype/src/cff/cffcmap.c b/drivers/freetype/src/cff/cffcmap.c new file mode 100644 index 0000000000..f6e03c6420 --- /dev/null +++ b/drivers/freetype/src/cff/cffcmap.c @@ -0,0 +1,210 @@ +/***************************************************************************/ +/* */ +/* cffcmap.c */ +/* */ +/* CFF character mapping table (cmap) support (body). */ +/* */ +/* Copyright 2002-2007, 2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include "cffcmap.h" +#include "cffload.h" + +#include "cfferrs.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Error ) + cff_cmap_encoding_init( CFF_CMapStd cmap ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Encoding encoding = &cff->encoding; + + + cmap->gids = encoding->codes; + + return 0; + } + + + FT_CALLBACK_DEF( void ) + cff_cmap_encoding_done( CFF_CMapStd cmap ) + { + cmap->gids = NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_encoding_char_index( CFF_CMapStd cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( char_code < 256 ) + result = cmap->gids[char_code]; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + cff_cmap_encoding_char_next( CFF_CMapStd cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code; + + + *pchar_code = 0; + + if ( char_code < 255 ) + { + FT_UInt code = (FT_UInt)(char_code + 1); + + + for (;;) + { + if ( code >= 256 ) + break; + + result = cmap->gids[code]; + if ( result != 0 ) + { + *pchar_code = code; + break; + } + + code++; + } + } + return result; + } + + + FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, + sizeof ( CFF_CMapStdRec ), + + (FT_CMap_InitFunc) cff_cmap_encoding_init, + (FT_CMap_DoneFunc) cff_cmap_encoding_done, + (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, + + NULL, NULL, NULL, NULL, NULL + ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( const char* ) + 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_UInt sid = charset->sids[idx]; + + + return cff_index_get_sid_string( cff, sid ); + } + + + FT_CALLBACK_DEF( FT_Error ) + cff_cmap_unicode_init( PS_Unicodes unicodes ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Charset charset = &cff->charset; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + /* can't build Unicode map for CID-keyed font */ + /* because we don't know glyph names. */ + if ( !charset->sids ) + return FT_THROW( No_Unicode_Glyph_Name ); + + return psnames->unicodes_init( memory, + unicodes, + cff->num_glyphs, + (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name, + (PS_FreeGlyphNameFunc)NULL, + (FT_Pointer)face ); + } + + + FT_CALLBACK_DEF( void ) + cff_cmap_unicode_done( PS_Unicodes unicodes ) + { + FT_Face face = FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( unicodes->maps ); + unicodes->num_maps = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_unicode_char_index( PS_Unicodes unicodes, + FT_UInt32 char_code ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + return psnames->unicodes_char_index( unicodes, char_code ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + cff_cmap_unicode_char_next( PS_Unicodes unicodes, + FT_UInt32 *pchar_code ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + return psnames->unicodes_char_next( unicodes, pchar_code ); + } + + + FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, + sizeof ( PS_UnicodesRec ), + + (FT_CMap_InitFunc) cff_cmap_unicode_init, + (FT_CMap_DoneFunc) cff_cmap_unicode_done, + (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL + ) + +/* END */ diff --git a/drivers/freetype/src/cff/cffcmap.h b/drivers/freetype/src/cff/cffcmap.h new file mode 100644 index 0000000000..3f7f67bbe0 --- /dev/null +++ b/drivers/freetype/src/cff/cffcmap.h @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* cffcmap.h */ +/* */ +/* CFF character mapping table (cmap) support (specification). */ +/* */ +/* Copyright 2002, 2003, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFCMAP_H__ +#define __CFFCMAP_H__ + +#include "cffobjs.h" + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* standard (and expert) encoding cmaps */ + typedef struct CFF_CMapStdRec_* CFF_CMapStd; + + typedef struct CFF_CMapStdRec_ + { + FT_CMapRec cmap; + FT_UShort* gids; /* up to 256 elements */ + + } CFF_CMapStdRec; + + + FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* unicode (synthetic) cmaps */ + + FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec) + + +FT_END_HEADER + +#endif /* __CFFCMAP_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cffdrivr.c b/drivers/freetype/src/cff/cffdrivr.c new file mode 100644 index 0000000000..c8ca96ba49 --- /dev/null +++ b/drivers/freetype/src/cff/cffdrivr.c @@ -0,0 +1,786 @@ +/***************************************************************************/ +/* */ +/* cffdrivr.c */ +/* */ +/* OpenType font driver implementation (body). */ +/* */ +/* Copyright 1996-2013 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_FREETYPE_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_SERVICE_CID_H +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_TT_CMAP_H + +#include "cffdrivr.h" +#include "cffgload.h" +#include "cffload.h" +#include "cffcmap.h" +#include "cffparse.h" + +#include "cfferrs.h" +#include "cffpic.h" + +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_PROPERTIES_H +#include FT_CFF_DRIVER_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_cffdriver + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F A C E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#undef PAIR_TAG +#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ + (FT_ULong)right ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_get_kerning */ + /* */ + /* <Description> */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* <Output> */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings, are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + FT_CALLBACK_DEF( FT_Error ) + cff_get_kerning( FT_Face ttface, /* TT_Face */ + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + TT_Face face = (TT_Face)ttface; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + kerning->x = 0; + kerning->y = 0; + + if ( sfnt ) + kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); + + return FT_Err_Ok; + } + + +#undef PAIR_TAG + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_glyph_load */ + /* */ + /* <Description> */ + /* A driver method used to load a glyph within a given glyph slot. */ + /* */ + /* <Input> */ + /* slot :: A handle to the target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled, loaded, etc. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_??? constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_CALLBACK_DEF( FT_Error ) + cff_glyph_load( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ + FT_Size cffsize, /* CFF_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; + CFF_Size size = (CFF_Size)cffsize; + + + if ( !slot ) + return FT_THROW( Invalid_Slot_Handle ); + + /* check whether we want a scaled outline or bitmap */ + if ( !size ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + /* reset the size object if necessary */ + if ( load_flags & FT_LOAD_NO_SCALE ) + size = NULL; + + if ( size ) + { + /* these two objects must have the same parent */ + if ( cffsize->face != cffslot->face ) + return FT_THROW( Invalid_Face_Handle ); + } + + /* now load the glyph outline if necessary */ + error = cff_slot_load( slot, size, glyph_index, load_flags ); + + /* force drop-out mode to 2 - irrelevant now */ + /* slot->outline.dropout_mode = 2; */ + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + cff_get_advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ) + { + FT_UInt nn; + FT_Error error = FT_Err_Ok; + FT_GlyphSlot slot = face->glyph; + + + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + + for ( nn = 0; nn < count; nn++ ) + { + error = cff_glyph_load( slot, face->size, start + nn, flags ); + if ( error ) + break; + + advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) + ? slot->linearVertAdvance + : slot->linearHoriAdvance; + } + + return error; + } + + + /* + * GLYPH DICT SERVICE + * + */ + + static FT_Error + cff_get_glyph_name( CFF_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + CFF_Font font = (CFF_Font)face->extra.data; + FT_String* gname; + FT_UShort sid; + FT_Error error; + + + if ( !font->psnames ) + { + FT_ERROR(( "cff_get_glyph_name:" + " cannot get glyph name from CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + + /* first, locate the sid in the charset table */ + sid = font->charset.sids[glyph_index]; + + /* now, lookup the name itself */ + gname = cff_index_get_sid_string( font, sid ); + + if ( gname ) + FT_STRCPYN( buffer, gname, buffer_max ); + + error = FT_Err_Ok; + + Exit: + return error; + } + + + static FT_UInt + cff_get_name_index( CFF_Face face, + FT_String* glyph_name ) + { + CFF_Font cff; + CFF_Charset charset; + FT_Service_PsCMaps psnames; + FT_String* name; + FT_UShort sid; + FT_UInt i; + + + cff = (CFF_FontRec *)face->extra.data; + charset = &cff->charset; + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + if ( !psnames ) + return 0; + + for ( i = 0; i < cff->num_glyphs; i++ ) + { + sid = charset->sids[i]; + + if ( sid > 390 ) + name = cff_index_get_string( cff, sid - 391 ); + else + name = (FT_String *)psnames->adobe_std_strings( sid ); + + if ( !name ) + continue; + + if ( !ft_strcmp( glyph_name, name ) ) + return i; + } + + return 0; + } + + + FT_DEFINE_SERVICE_GLYPHDICTREC( + cff_service_glyph_dict, + (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)cff_get_name_index + ) + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Int + cff_ps_has_glyph_names( FT_Face face ) + { + return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; + } + + + 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 = NULL; + 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, + dict->version ); + font_info->notice = cff_index_get_sid_string( cff, + dict->notice ); + font_info->full_name = cff_index_get_sid_string( cff, + dict->full_name ); + font_info->family_name = cff_index_get_sid_string( cff, + dict->family_name ); + font_info->weight = cff_index_get_sid_string( cff, + dict->weight ); + 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; + } + + if ( cff ) + *afont_info = *cff->font_info; + + Fail: + return error; + } + + + FT_DEFINE_SERVICE_PSINFOREC( + cff_service_ps_info, + (PS_GetFontInfoFunc) cff_ps_get_font_info, + (PS_GetFontExtraFunc) NULL, + (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, + (PS_GetFontPrivateFunc)NULL, /* unsupported with CFF fonts */ + (PS_GetFontValueFunc) NULL /* not implemented */ + ) + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + cff_get_ps_name( CFF_Face face ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + return (const char*)cff->font_name; + } + + + FT_DEFINE_SERVICE_PSFONTNAMEREC( + cff_service_ps_name, + (FT_PsName_GetFunc)cff_get_ps_name + ) + + + /* + * TT CMAP INFO + * + * If the charmap is a synthetic Unicode encoding cmap or + * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO + * service defined in SFNT module. + * + * Otherwise call the service function in the sfnt module. + * + */ + static FT_Error + cff_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ) + { + FT_CMap cmap = FT_CMAP( charmap ); + FT_Error error = FT_Err_Ok; + + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Library library = FT_FACE_LIBRARY( face ); + + + cmap_info->language = 0; + cmap_info->format = 0; + + if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET && + cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET ) + { + FT_Module sfnt = FT_Get_Module( library, "sfnt" ); + FT_Service_TTCMaps service = + (FT_Service_TTCMaps)ft_module_get_service( sfnt, + FT_SERVICE_ID_TT_CMAP ); + + + if ( service && service->get_cmap_info ) + error = service->get_cmap_info( charmap, cmap_info ); + } + + return error; + } + + + FT_DEFINE_SERVICE_TTCMAPSREC( + cff_service_get_cmap_info, + (TT_CMap_Info_GetFunc)cff_get_cmap_info + ) + + + /* + * CID INFO SERVICE + * + */ + static FT_Error + cff_get_ros( CFF_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + FT_Error error = FT_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = FT_THROW( Invalid_Argument ); + goto Fail; + } + + if ( registry ) + { + if ( cff->registry == NULL ) + cff->registry = cff_index_get_sid_string( cff, + dict->cid_registry ); + *registry = cff->registry; + } + + if ( ordering ) + { + if ( cff->ordering == NULL ) + cff->ordering = cff_index_get_sid_string( cff, + dict->cid_ordering ); + *ordering = cff->ordering; + } + + /* + * XXX: According to Adobe TechNote #5176, the supplement in CFF + * can be a real number. We truncate it to fit public API + * since freetype-2.3.6. + */ + if ( supplement ) + { + if ( dict->cid_supplement < FT_INT_MIN || + dict->cid_supplement > FT_INT_MAX ) + FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", + dict->cid_supplement )); + *supplement = (FT_Int)dict->cid_supplement; + } + } + + Fail: + return error; + } + + + static FT_Error + cff_get_is_cid( CFF_Face face, + FT_Bool *is_cid ) + { + FT_Error error = FT_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + *is_cid = 0; + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry != 0xFFFFU ) + *is_cid = 1; + } + + return error; + } + + + static FT_Error + cff_get_cid_from_glyph_index( CFF_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = FT_Err_Ok; + CFF_Font cff; + + + cff = (CFF_Font)face->extra.data; + + if ( cff ) + { + FT_UInt c; + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = FT_THROW( Invalid_Argument ); + goto Fail; + } + + if ( glyph_index > cff->num_glyphs ) + { + error = FT_THROW( Invalid_Argument ); + goto Fail; + } + + c = cff->charset.sids[glyph_index]; + + if ( cid ) + *cid = c; + } + + Fail: + return error; + } + + + FT_DEFINE_SERVICE_CIDREC( + cff_service_cid_info, + (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index + ) + + + /* + * PROPERTY SERVICE + * + */ + static FT_Error + cff_property_set( FT_Module module, /* CFF_Driver */ + const char* property_name, + const void* value ) + { + FT_Error error = FT_Err_Ok; + CFF_Driver driver = (CFF_Driver)module; + + + if ( !ft_strcmp( property_name, "hinting-engine" ) ) + { + FT_UInt* hinting_engine = (FT_UInt*)value; + + +#ifndef CFF_CONFIG_OPTION_OLD_ENGINE + if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) + error = FT_ERR( Unimplemented_Feature ); + else +#endif + driver->hinting_engine = *hinting_engine; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; + + + driver->no_stem_darkening = *no_stem_darkening; + + return error; + } + + FT_TRACE0(( "cff_property_set: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + static FT_Error + cff_property_get( FT_Module module, /* CFF_Driver */ + const char* property_name, + const void* value ) + { + FT_Error error = FT_Err_Ok; + CFF_Driver driver = (CFF_Driver)module; + + FT_UInt hinting_engine = driver->hinting_engine; + FT_Bool no_stem_darkening = driver->no_stem_darkening; + + + if ( !ft_strcmp( property_name, "hinting-engine" ) ) + { + FT_UInt* val = (FT_UInt*)value; + + + *val = hinting_engine; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool* val = (FT_Bool*)value; + + + *val = no_stem_darkening; + + return error; + } + + FT_TRACE0(( "cff_property_get: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + FT_DEFINE_SERVICE_PROPERTIESREC( + cff_service_properties, + (FT_Properties_SetFunc)cff_property_set, + (FT_Properties_GetFunc)cff_property_get ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** D R I V E R I N T E R F A C E ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + FT_DEFINE_SERVICEDESCREC7( + cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET + ) +#else + FT_DEFINE_SERVICEDESCREC6( + cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET + ) +#endif + + + FT_CALLBACK_DEF( FT_Module_Interface ) + cff_get_interface( FT_Module driver, /* CFF_Driver */ + const char* module_interface ) + { + FT_Library library; + FT_Module sfnt; + FT_Module_Interface result; + + + /* CFF_SERVICES_GET derefers `library' in PIC mode */ +#ifdef FT_CONFIG_OPTION_PIC + if ( !driver ) + return NULL; + library = driver->library; + if ( !library ) + return NULL; +#endif + + result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); + if ( result != NULL ) + return result; + + /* `driver' is not yet evaluated in non-PIC mode */ +#ifndef FT_CONFIG_OPTION_PIC + if ( !driver ) + return NULL; + library = driver->library; + if ( !library ) + return NULL; +#endif + + /* we pass our request to the `sfnt' module */ + sfnt = FT_Get_Module( library, "sfnt" ); + + return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; + } + + + /* The FT_DriverInterface structure is defined in ftdriver.h. */ + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define CFF_SIZE_SELECT cff_size_select +#else +#define CFF_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER( + cff_driver_class, + + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, + + sizeof ( CFF_DriverRec ), + "cff", + 0x10000L, + 0x20000L, + + 0, /* module-specific interface */ + + cff_driver_init, + cff_driver_done, + cff_get_interface, + + /* now the specific driver fields */ + sizeof ( TT_FaceRec ), + sizeof ( CFF_SizeRec ), + sizeof ( CFF_GlyphSlotRec ), + + cff_face_init, + cff_face_done, + cff_size_init, + cff_size_done, + cff_slot_init, + cff_slot_done, + + cff_glyph_load, + + cff_get_kerning, + 0, /* FT_Face_AttachFunc */ + cff_get_advances, + + cff_size_request, + + CFF_SIZE_SELECT + ) + + +/* END */ diff --git a/drivers/freetype/src/cff/cffdrivr.h b/drivers/freetype/src/cff/cffdrivr.h new file mode 100644 index 0000000000..50e8138701 --- /dev/null +++ b/drivers/freetype/src/cff/cffdrivr.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* cffdrivr.h */ +/* */ +/* High-level OpenType driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CFFDRIVER_H__ +#define __CFFDRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_DRIVER( cff_driver_class ) + + +FT_END_HEADER + +#endif /* __CFFDRIVER_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cfferrs.h b/drivers/freetype/src/cff/cfferrs.h new file mode 100644 index 0000000000..801d73ec6b --- /dev/null +++ b/drivers/freetype/src/cff/cfferrs.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* cfferrs.h */ +/* */ +/* CFF error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the CFF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __CFFERRS_H__ +#define __CFFERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX CFF_Err_ +#define FT_ERR_BASE FT_Mod_Err_CFF + + +#include FT_ERRORS_H + +#endif /* __CFFERRS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cffgload.c b/drivers/freetype/src/cff/cffgload.c new file mode 100644 index 0000000000..6a8494fa9f --- /dev/null +++ b/drivers/freetype/src/cff/cffgload.c @@ -0,0 +1,3068 @@ +/***************************************************************************/ +/* */ +/* cffgload.c */ +/* */ +/* OpenType Glyph Loader (body). */ +/* */ +/* Copyright 1996-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_OUTLINE_H +#include FT_CFF_DRIVER_H + +#include "cffobjs.h" +#include "cffload.h" +#include "cffgload.h" +#include "cf2ft.h" /* for cf2_decoder_parse_charstrings */ + +#include "cfferrs.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_cffgload + + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + + typedef enum CFF_Operator_ + { + cff_op_unknown = 0, + + cff_op_rmoveto, + cff_op_hmoveto, + cff_op_vmoveto, + + cff_op_rlineto, + cff_op_hlineto, + cff_op_vlineto, + + cff_op_rrcurveto, + cff_op_hhcurveto, + cff_op_hvcurveto, + cff_op_rcurveline, + cff_op_rlinecurve, + cff_op_vhcurveto, + cff_op_vvcurveto, + + cff_op_flex, + cff_op_hflex, + cff_op_hflex1, + cff_op_flex1, + + cff_op_endchar, + + cff_op_hstem, + cff_op_vstem, + cff_op_hstemhm, + cff_op_vstemhm, + + cff_op_hintmask, + cff_op_cntrmask, + cff_op_dotsection, /* deprecated, acts as no-op */ + + cff_op_abs, + cff_op_add, + cff_op_sub, + cff_op_div, + cff_op_neg, + cff_op_random, + cff_op_mul, + cff_op_sqrt, + + cff_op_blend, + + cff_op_drop, + cff_op_exch, + cff_op_index, + cff_op_roll, + cff_op_dup, + + cff_op_put, + cff_op_get, + cff_op_store, + cff_op_load, + + cff_op_and, + cff_op_or, + cff_op_not, + cff_op_eq, + cff_op_ifelse, + + cff_op_callsubr, + cff_op_callgsubr, + cff_op_return, + + /* Type 1 opcodes: invalid but seen in real life */ + cff_op_hsbw, + cff_op_closepath, + cff_op_callothersubr, + cff_op_pop, + cff_op_seac, + cff_op_sbw, + cff_op_setcurrentpoint, + + /* do not remove */ + cff_op_max + + } CFF_Operator; + + +#define CFF_COUNT_CHECK_WIDTH 0x80 +#define CFF_COUNT_EXACT 0x40 +#define CFF_COUNT_CLEAR_STACK 0x20 + + /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ + /* used for checking the width and requested numbers of arguments */ + /* only; they are set to zero afterwards */ + + /* the other two flags are informative only and unused currently */ + + static const FT_Byte cff_argument_counts[] = + { + 0, /* unknown */ + + 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ + 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, + 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, + + 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + + 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + + 13, /* flex */ + 7, + 9, + 11, + + 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ + + 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ + 2 | CFF_COUNT_CHECK_WIDTH, + 2 | CFF_COUNT_CHECK_WIDTH, + 2 | CFF_COUNT_CHECK_WIDTH, + + 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ + 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ + 0, /* dotsection */ + + 1, /* abs */ + 2, + 2, + 2, + 1, + 0, + 2, + 1, + + 1, /* blend */ + + 1, /* drop */ + 2, + 1, + 2, + 1, + + 2, /* put */ + 1, + 4, + 3, + + 2, /* and */ + 2, + 1, + 2, + 4, + + 1, /* callsubr */ + 1, + 0, + + 2, /* hsbw */ + 0, + 0, + 0, + 5, /* seac */ + 4, /* sbw */ + 2 /* setcurrentpoint */ + }; + +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** GENERIC CHARSTRING PARSING *********/ + /********** *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_builder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph builder. */ + /* */ + /* <InOut> */ + /* builder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* glyph :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ + /* */ + static void + cff_builder_init( CFF_Builder* builder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot glyph, + FT_Bool hinting ) + { + builder->path_begun = 0; + builder->load_points = 1; + + builder->face = face; + builder->glyph = glyph; + builder->memory = face->root.memory; + + if ( glyph ) + { + FT_GlyphLoader loader = glyph->root.internal->loader; + + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + FT_GlyphLoader_Rewind( loader ); + + builder->hints_globals = 0; + builder->hints_funcs = 0; + + if ( hinting && size ) + { + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + builder->hints_globals = (void *)internal->topfont; + builder->hints_funcs = glyph->root.internal->glyph_hints; + } + } + + builder->pos_x = 0; + builder->pos_y = 0; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + builder->advance.x = 0; + builder->advance.y = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_builder_done */ + /* */ + /* <Description> */ + /* Finalizes a given glyph builder. Its contents can still be used */ + /* after the call, but the function saves important information */ + /* within the corresponding glyph slot. */ + /* */ + /* <Input> */ + /* builder :: A pointer to the glyph builder to finalize. */ + /* */ + static void + cff_builder_done( CFF_Builder* builder ) + { + CFF_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->root.outline = *builder->base; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_compute_bias */ + /* */ + /* <Description> */ + /* Computes the bias value in dependence of the number of glyph */ + /* subroutines. */ + /* */ + /* <Input> */ + /* in_charstring_type :: The `CharstringType' value of the top DICT */ + /* dictionary. */ + /* */ + /* num_subrs :: The number of glyph subroutines. */ + /* */ + /* <Return> */ + /* The bias value. */ + static FT_Int + cff_compute_bias( FT_Int in_charstring_type, + FT_UInt num_subrs ) + { + FT_Int result; + + + if ( in_charstring_type == 1 ) + result = 0; + else if ( num_subrs < 1240 ) + result = 107; + else if ( num_subrs < 33900U ) + result = 1131; + else + result = 32768U; + + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_decoder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph decoder. */ + /* */ + /* <InOut> */ + /* decoder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* slot :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ + /* */ + /* hint_mode :: The hinting mode. */ + /* */ + FT_LOCAL_DEF( void ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + /* clear everything */ + FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + + /* initialize builder */ + cff_builder_init( &decoder->builder, face, size, slot, hinting ); + + /* initialize Type2 decoder */ + decoder->cff = cff; + decoder->num_globals = cff->global_subrs_index.count; + decoder->globals = cff->global_subrs; + decoder->globals_bias = cff_compute_bias( + cff->top_font.font_dict.charstring_type, + decoder->num_globals ); + + decoder->hint_mode = hint_mode; + } + + + /* this function is used to select the subfont */ + /* and the locals subrs array */ + FT_LOCAL_DEF( FT_Error ) + cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, + FT_UInt glyph_index ) + { + CFF_Builder *builder = &decoder->builder; + CFF_Font cff = (CFF_Font)builder->face->extra.data; + CFF_SubFont sub = &cff->top_font; + FT_Error error = FT_Err_Ok; + + + /* manage CID fonts */ + if ( cff->num_subfonts ) + { + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); + + + if ( fd_index >= cff->num_subfonts ) + { + FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index )); + + sub = cff->subfonts[fd_index]; + + if ( builder->hints_funcs && size ) + { + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + /* for CFFs without subfonts, this value has already been set */ + builder->hints_globals = (void *)internal->subfonts[fd_index]; + } + } +#ifdef FT_DEBUG_LEVEL_TRACE + else + FT_TRACE3(( "glyph index %d:\n", glyph_index )); +#endif + + decoder->num_locals = sub->local_subrs_index.count; + decoder->locals = sub->local_subrs; + decoder->locals_bias = cff_compute_bias( + decoder->cff->top_font.font_dict.charstring_type, + decoder->num_locals ); + + decoder->glyph_width = sub->private_dict.default_width; + decoder->nominal_width = sub->private_dict.nominal_width; + + decoder->current_subfont = sub; /* for Adobe's CFF handler */ + + Exit: + return error; + } + + + /* check that there is enough space for `count' more points */ + FT_LOCAL_DEF( FT_Error ) + cff_check_points( CFF_Builder* builder, + FT_Int count ) + { + return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + FT_LOCAL_DEF( void ) + cff_builder_add_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) + { + FT_Outline* outline = builder->current; + + + if ( builder->load_points ) + { + FT_Vector* point = outline->points + outline->n_points; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face ); + + + if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) + { + point->x = x >> 16; + point->y = y >> 16; + } + else +#endif + { + /* cf2_decoder_parse_charstrings uses 16.16 coordinates */ + point->x = x >> 10; + point->y = y >> 10; + } + *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); + } + + outline->n_points++; + } + + + /* check space for a new on-curve point, then add it */ + FT_LOCAL_DEF( FT_Error ) + cff_builder_add_point1( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error; + + + error = cff_check_points( builder, 1 ); + if ( !error ) + cff_builder_add_point( builder, x, y, 1 ); + + return error; + } + + + /* check space for a new contour, then add it */ + static FT_Error + cff_builder_add_contour( CFF_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Error error; + + + if ( !builder->load_points ) + { + outline->n_contours++; + return FT_Err_Ok; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); + if ( !error ) + { + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + + outline->n_contours++; + } + + return error; + } + + + /* if a path was begun, add its first on-curve point */ + FT_LOCAL_DEF( FT_Error ) + cff_builder_start_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = FT_Err_Ok; + + + /* test whether we are building a new contour */ + if ( !builder->path_begun ) + { + builder->path_begun = 1; + error = cff_builder_add_contour( builder ); + if ( !error ) + error = cff_builder_add_point1( builder, x, y ); + } + + return error; + } + + + /* close the current contour */ + FT_LOCAL_DEF( void ) + cff_builder_close_contour( CFF_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Int first; + + + if ( !outline ) + return; + + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ + if ( outline->n_points > 1 ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + outline->n_points - 1; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + + + /* `delete' last point only if it coincides with the first */ + /* point and if it is not a control point (which can happen). */ + if ( p1->x == p2->x && p1->y == p2->y ) + if ( *control == FT_CURVE_TAG_ON ) + outline->n_points--; + } + + if ( outline->n_contours > 0 ) + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether begin point and last point are the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } + } + + + FT_LOCAL_DEF( FT_Int ) + cff_lookup_glyph_by_stdcharcode( CFF_Font cff, + FT_Int charcode ) + { + FT_UInt n; + FT_UShort glyph_sid; + + + /* CID-keyed fonts don't have glyph names */ + if ( !cff->charset.sids ) + return -1; + + /* check range of standard char code */ + if ( charcode < 0 || charcode > 255 ) + return -1; + + /* Get code to SID mapping from `cff_standard_encoding'. */ + glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode ); + + for ( n = 0; n < cff->num_glyphs; n++ ) + { + if ( cff->charset.sids[n] == glyph_sid ) + return n; + } + + return -1; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_get_glyph_data( TT_Face face, + FT_UInt glyph_index, + FT_Byte** pointer, + FT_ULong* length ) + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data data; + FT_Error error = + face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, &data ); + + + *pointer = (FT_Byte*)data.pointer; + *length = data.length; + + return error; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + return cff_index_access_element( &cff->charstrings_index, glyph_index, + pointer, length ); + } + } + + + FT_LOCAL_DEF( void ) + cff_free_glyph_data( TT_Face face, + FT_Byte** pointer, + FT_ULong length ) + { +#ifndef FT_CONFIG_OPTION_INCREMENTAL + FT_UNUSED( length ); +#endif + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data data; + + + data.pointer = *pointer; + data.length = length; + + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, &data ); + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + cff_index_forget_element( &cff->charstrings_index, pointer ); + } + } + + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + + static FT_Error + cff_operator_seac( CFF_Decoder* decoder, + FT_Pos asb, + FT_Pos adx, + FT_Pos ady, + FT_Int bchar, + FT_Int achar ) + { + FT_Error error; + CFF_Builder* builder = &decoder->builder; + FT_Int bchar_index, achar_index; + TT_Face face = decoder->builder.face; + FT_Vector left_bearing, advance; + FT_Byte* charstring; + FT_ULong charstring_len; + FT_Pos glyph_width; + + + if ( decoder->seac ) + { + FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); + return FT_THROW( Syntax_Error ); + } + + adx += decoder->builder.left_bearing.x; + ady += decoder->builder.left_bearing.y; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Incremental fonts don't necessarily have valid charsets. */ + /* They use the character code, not the glyph index, in this case. */ + if ( face->root.internal->incremental_interface ) + { + bchar_index = bchar; + achar_index = achar; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar ); + achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar ); + } + + if ( bchar_index < 0 || achar_index < 0 ) + { + FT_ERROR(( "cff_operator_seac:" + " invalid seac character code arguments\n" )); + return FT_THROW( Syntax_Error ); + } + + /* If we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ + if ( builder->no_recurse ) + { + FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; + FT_GlyphLoader loader = glyph->internal->loader; + FT_SubGlyph subg; + + + /* reallocate subglyph array if necessary */ + error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); + if ( error ) + goto Exit; + + subg = loader->current.subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = (FT_Int)( adx >> 16 ); + subg->arg2 = (FT_Int)( ady >> 16 ); + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->subglyphs = loader->base.subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + loader->current.num_subglyphs = 2; + } + + FT_GlyphLoader_Prepare( builder->loader ); + + /* First load `bchar' in builder */ + error = cff_get_glyph_data( face, bchar_index, + &charstring, &charstring_len ); + if ( !error ) + { + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = cff_decoder_parse_charstrings( decoder, charstring, + charstring_len ); + decoder->seac = FALSE; + + cff_free_glyph_data( face, &charstring, charstring_len ); + + if ( error ) + goto Exit; + } + + /* Save the left bearing, advance and glyph width of the base */ + /* character as they will be erased by the next load. */ + + left_bearing = builder->left_bearing; + advance = builder->advance; + glyph_width = decoder->glyph_width; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + + builder->pos_x = adx - asb; + builder->pos_y = ady; + + /* Now load `achar' on top of the base outline. */ + error = cff_get_glyph_data( face, achar_index, + &charstring, &charstring_len ); + if ( !error ) + { + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = cff_decoder_parse_charstrings( decoder, charstring, + charstring_len ); + decoder->seac = FALSE; + + cff_free_glyph_data( face, &charstring, charstring_len ); + + if ( error ) + goto Exit; + } + + /* Restore the left side bearing, advance and glyph width */ + /* of the base character. */ + builder->left_bearing = left_bearing; + builder->advance = advance; + decoder->glyph_width = glyph_width; + + builder->pos_x = 0; + builder->pos_y = 0; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_decoder_parse_charstrings */ + /* */ + /* <Description> */ + /* Parses a given Type 2 charstrings program. */ + /* */ + /* <InOut> */ + /* decoder :: The current Type 1 decoder. */ + /* */ + /* <Input> */ + /* charstring_base :: The base of the charstring stream. */ + /* */ + /* charstring_len :: The length in bytes of the charstring stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cff_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ) + { + FT_Error error; + CFF_Decoder_Zone* zone; + FT_Byte* ip; + FT_Byte* limit; + CFF_Builder* builder = &decoder->builder; + FT_Pos x, y; + FT_Fixed seed; + FT_Fixed* stack; + FT_Int charstring_type = + decoder->cff->top_font.font_dict.charstring_type; + + T2_Hints_Funcs hinter; + + + /* set default width */ + decoder->num_hints = 0; + decoder->read_width = 1; + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; + if ( seed == 0 ) + seed = 0x7384; + + /* initialize the decoder */ + decoder->top = decoder->stack; + decoder->zone = decoder->zones; + zone = decoder->zones; + stack = decoder->top; + + hinter = (T2_Hints_Funcs)builder->hints_funcs; + + builder->path_begun = 0; + + zone->base = charstring_base; + limit = zone->limit = charstring_base + charstring_len; + ip = zone->cursor = zone->base; + + error = FT_Err_Ok; + + x = builder->pos_x; + y = builder->pos_y; + + /* begin hints recording session, if any */ + if ( hinter ) + hinter->open( hinter->hints ); + + /* now execute loop */ + while ( ip < limit ) + { + CFF_Operator op; + FT_Byte v; + + + /********************************************************************/ + /* */ + /* Decode operator or operand */ + /* */ + v = *ip++; + if ( v >= 32 || v == 28 ) + { + FT_Int shift = 16; + FT_Int32 val; + + + /* this is an operand, push it on the stack */ + + /* if we use shifts, all computations are done with unsigned */ + /* values; the conversion to a signed value is the last step */ + if ( v == 28 ) + { + if ( ip + 1 >= limit ) + goto Syntax_Error; + val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] ); + ip += 2; + } + else if ( v < 247 ) + val = (FT_Int32)v - 139; + else if ( v < 251 ) + { + if ( ip >= limit ) + goto Syntax_Error; + val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; + } + else if ( v < 255 ) + { + if ( ip >= limit ) + goto Syntax_Error; + val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; + } + else + { + if ( ip + 3 >= limit ) + goto Syntax_Error; + val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | + ( (FT_UInt32)ip[1] << 16 ) | + ( (FT_UInt32)ip[2] << 8 ) | + (FT_UInt32)ip[3] ); + ip += 4; + if ( charstring_type == 2 ) + shift = 0; + } + if ( decoder->top - stack >= CFF_MAX_OPERANDS ) + goto Stack_Overflow; + + val = (FT_Int32)( (FT_UInt32)val << shift ); + *decoder->top++ = val; + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !( val & 0xFFFFL ) ) + FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) )); + else + FT_TRACE4(( " %.2f", val / 65536.0 )); +#endif + + } + else + { + /* The specification says that normally arguments are to be taken */ + /* from the bottom of the stack. However, this seems not to be */ + /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ + /* arguments similar to a PS interpreter. */ + + FT_Fixed* args = decoder->top; + FT_Int num_args = (FT_Int)( args - decoder->stack ); + FT_Int req_args; + + + /* find operator */ + op = cff_op_unknown; + + switch ( v ) + { + case 1: + op = cff_op_hstem; + break; + case 3: + op = cff_op_vstem; + break; + case 4: + op = cff_op_vmoveto; + break; + case 5: + op = cff_op_rlineto; + break; + case 6: + op = cff_op_hlineto; + break; + case 7: + op = cff_op_vlineto; + break; + case 8: + op = cff_op_rrcurveto; + break; + case 9: + op = cff_op_closepath; + break; + case 10: + op = cff_op_callsubr; + break; + case 11: + op = cff_op_return; + break; + case 12: + { + if ( ip >= limit ) + goto Syntax_Error; + v = *ip++; + + switch ( v ) + { + case 0: + op = cff_op_dotsection; + break; + case 1: /* this is actually the Type1 vstem3 operator */ + op = cff_op_vstem; + break; + case 2: /* this is actually the Type1 hstem3 operator */ + op = cff_op_hstem; + break; + case 3: + op = cff_op_and; + break; + case 4: + op = cff_op_or; + break; + case 5: + op = cff_op_not; + break; + case 6: + op = cff_op_seac; + break; + case 7: + op = cff_op_sbw; + break; + case 8: + op = cff_op_store; + break; + case 9: + op = cff_op_abs; + break; + case 10: + op = cff_op_add; + break; + case 11: + op = cff_op_sub; + break; + case 12: + op = cff_op_div; + break; + case 13: + op = cff_op_load; + break; + case 14: + op = cff_op_neg; + break; + case 15: + op = cff_op_eq; + break; + case 16: + op = cff_op_callothersubr; + break; + case 17: + op = cff_op_pop; + break; + case 18: + op = cff_op_drop; + break; + case 20: + op = cff_op_put; + break; + case 21: + op = cff_op_get; + break; + case 22: + op = cff_op_ifelse; + break; + case 23: + op = cff_op_random; + break; + case 24: + op = cff_op_mul; + break; + case 26: + op = cff_op_sqrt; + break; + case 27: + op = cff_op_dup; + break; + case 28: + op = cff_op_exch; + break; + case 29: + op = cff_op_index; + break; + case 30: + op = cff_op_roll; + break; + case 33: + op = cff_op_setcurrentpoint; + break; + case 34: + op = cff_op_hflex; + break; + case 35: + op = cff_op_flex; + break; + case 36: + op = cff_op_hflex1; + break; + case 37: + op = cff_op_flex1; + break; + default: + FT_TRACE4(( " unknown op (12, %d)\n", v )); + break; + } + } + break; + case 13: + op = cff_op_hsbw; + break; + case 14: + op = cff_op_endchar; + break; + case 16: + op = cff_op_blend; + break; + case 18: + op = cff_op_hstemhm; + break; + case 19: + op = cff_op_hintmask; + break; + case 20: + op = cff_op_cntrmask; + break; + case 21: + op = cff_op_rmoveto; + break; + case 22: + op = cff_op_hmoveto; + break; + case 23: + op = cff_op_vstemhm; + break; + case 24: + op = cff_op_rcurveline; + break; + case 25: + op = cff_op_rlinecurve; + break; + case 26: + op = cff_op_vvcurveto; + break; + case 27: + op = cff_op_hhcurveto; + break; + case 29: + op = cff_op_callgsubr; + break; + case 30: + op = cff_op_vhcurveto; + break; + case 31: + op = cff_op_hvcurveto; + break; + default: + FT_TRACE4(( " unknown op (%d)\n", v )); + break; + } + + if ( op == cff_op_unknown ) + continue; + + /* check arguments */ + req_args = cff_argument_counts[op]; + if ( req_args & CFF_COUNT_CHECK_WIDTH ) + { + if ( num_args > 0 && decoder->read_width ) + { + /* If `nominal_width' is non-zero, the number is really a */ + /* difference against `nominal_width'. Else, the number here */ + /* is truly a width, not a difference against `nominal_width'. */ + /* If the font does not set `nominal_width', then */ + /* `nominal_width' defaults to zero, and so we can set */ + /* `glyph_width' to `nominal_width' plus number on the stack */ + /* -- for either case. */ + + FT_Int set_width_ok; + + + switch ( op ) + { + case cff_op_hmoveto: + case cff_op_vmoveto: + set_width_ok = num_args & 2; + break; + + case cff_op_hstem: + case cff_op_vstem: + case cff_op_hstemhm: + case cff_op_vstemhm: + case cff_op_rmoveto: + case cff_op_hintmask: + case cff_op_cntrmask: + set_width_ok = num_args & 1; + break; + + case cff_op_endchar: + /* If there is a width specified for endchar, we either have */ + /* 1 argument or 5 arguments. We like to argue. */ + set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); + break; + + default: + set_width_ok = 0; + break; + } + + if ( set_width_ok ) + { + decoder->glyph_width = decoder->nominal_width + + ( stack[0] >> 16 ); + + if ( decoder->width_only ) + { + /* we only want the advance width; stop here */ + break; + } + + /* Consumed an argument. */ + num_args--; + } + } + + decoder->read_width = 0; + req_args = 0; + } + + req_args &= 0x000F; + if ( num_args < req_args ) + goto Stack_Underflow; + args -= req_args; + num_args -= req_args; + + /* At this point, `args' points to the first argument of the */ + /* operand in case `req_args' isn't zero. Otherwise, we have */ + /* to adjust `args' manually. */ + + /* Note that we only pop arguments from the stack which we */ + /* really need and can digest so that we can continue in case */ + /* of superfluous stack elements. */ + + switch ( op ) + { + case cff_op_hstem: + case cff_op_vstem: + case cff_op_hstemhm: + case cff_op_vstemhm: + /* the number of arguments is always even here */ + FT_TRACE4(( + op == cff_op_hstem ? " hstem\n" : + ( op == cff_op_vstem ? " vstem\n" : + ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); + + if ( hinter ) + hinter->stems( hinter->hints, + ( op == cff_op_hstem || op == cff_op_hstemhm ), + num_args / 2, + args - ( num_args & ~1 ) ); + + decoder->num_hints += num_args / 2; + args = stack; + break; + + case cff_op_hintmask: + case cff_op_cntrmask: + FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); + + /* implement vstem when needed -- */ + /* the specification doesn't say it, but this also works */ + /* with the 'cntrmask' operator */ + /* */ + if ( num_args > 0 ) + { + if ( hinter ) + hinter->stems( hinter->hints, + 0, + num_args / 2, + args - ( num_args & ~1 ) ); + + decoder->num_hints += num_args / 2; + } + + /* In a valid charstring there must be at least one byte */ + /* after `hintmask' or `cntrmask' (e.g., for a `return' */ + /* instruction). Additionally, there must be space for */ + /* `num_hints' bits. */ + + if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit ) + goto Syntax_Error; + + if ( hinter ) + { + if ( op == cff_op_hintmask ) + hinter->hintmask( hinter->hints, + builder->current->n_points, + decoder->num_hints, + ip ); + else + hinter->counter( hinter->hints, + decoder->num_hints, + ip ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt maskbyte; + + + FT_TRACE4(( " (maskbytes:" )); + + for ( maskbyte = 0; + maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 ); + maskbyte++, ip++ ) + FT_TRACE4(( " 0x%02X", *ip )); + + FT_TRACE4(( ")\n" )); + } +#else + ip += ( decoder->num_hints + 7 ) >> 3; +#endif + args = stack; + break; + + case cff_op_rmoveto: + FT_TRACE4(( " rmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + x += args[-2]; + y += args[-1]; + args = stack; + break; + + case cff_op_vmoveto: + FT_TRACE4(( " vmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + y += args[-1]; + args = stack; + break; + + case cff_op_hmoveto: + FT_TRACE4(( " hmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + x += args[-1]; + args = stack; + break; + + case cff_op_rlineto: + FT_TRACE4(( " rlineto\n" )); + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, num_args / 2 ) ) + goto Fail; + + if ( num_args < 2 ) + goto Stack_Underflow; + + args -= num_args & ~1; + while ( args < decoder->top ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args += 2; + } + args = stack; + break; + + case cff_op_hlineto: + case cff_op_vlineto: + { + FT_Int phase = ( op == cff_op_hlineto ); + + + FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" + : " vlineto\n" )); + + if ( num_args < 0 ) + goto Stack_Underflow; + + /* there exist subsetted fonts (found in PDFs) */ + /* which call `hlineto' without arguments */ + if ( num_args == 0 ) + break; + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, num_args ) ) + goto Fail; + + args = stack; + while ( args < decoder->top ) + { + if ( phase ) + x += args[0]; + else + y += args[0]; + + if ( cff_builder_add_point1( builder, x, y ) ) + goto Fail; + + args++; + phase ^= 1; + } + args = stack; + } + break; + + case cff_op_rrcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " rrcurveto\n" )); + + if ( num_args < 6 ) + goto Stack_Underflow; + + nargs = num_args - num_args % 6; + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, nargs / 2 ) ) + goto Fail; + + args -= nargs; + while ( args < decoder->top ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args += 6; + } + args = stack; + } + break; + + case cff_op_vvcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " vvcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + + nargs = num_args & ~2; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + + if ( nargs & 1 ) + { + x += args[0]; + args++; + nargs--; + } + + if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + y += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + y += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; + } + break; + + case cff_op_hhcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " hhcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + + nargs = num_args & ~2; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + if ( nargs & 1 ) + { + y += args[0]; + args++; + nargs--; + } + + if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; + } + break; + + case cff_op_vhcurveto: + case cff_op_hvcurveto: + { + FT_Int phase; + FT_Int nargs; + + + FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" + : " hvcurveto\n" )); + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ + /* we enforce it by clearing the second bit */ + + nargs = num_args & ~2; + + args -= nargs; + if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) ) + goto Stack_Underflow; + + phase = ( op == cff_op_hvcurveto ); + + while ( nargs >= 4 ) + { + nargs -= 4; + if ( phase ) + { + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + y += args[3]; + if ( nargs == 1 ) + x += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + } + else + { + y += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[3]; + if ( nargs == 1 ) + y += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + } + args += 4; + phase ^= 1; + } + args = stack; + } + break; + + case cff_op_rlinecurve: + { + FT_Int num_lines; + FT_Int nargs; + + + FT_TRACE4(( " rlinecurve\n" )); + + if ( num_args < 8 ) + goto Stack_Underflow; + + nargs = num_args & ~1; + num_lines = ( nargs - 6 ) / 2; + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, num_lines + 3 ) ) + goto Fail; + + args -= nargs; + + /* first, add the line segments */ + while ( num_lines > 0 ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args += 2; + num_lines--; + } + + /* then the curve */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args = stack; + } + break; + + case cff_op_rcurveline: + { + FT_Int num_curves; + FT_Int nargs; + + + FT_TRACE4(( " rcurveline\n" )); + + if ( num_args < 8 ) + goto Stack_Underflow; + + nargs = num_args - 2; + nargs = nargs - nargs % 6 + 2; + num_curves = ( nargs - 2 ) / 6; + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, num_curves * 3 + 2 ) ) + goto Fail; + + args -= nargs; + + /* first, add the curves */ + while ( num_curves > 0 ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args += 6; + num_curves--; + } + + /* then the final line */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args = stack; + } + break; + + case cff_op_hflex1: + { + FT_Pos start_y; + + + FT_TRACE4(( " hflex1\n" )); + + /* adding five more points: 4 control points, 1 on-curve point */ + /* -- make sure we have enough space for the start point if it */ + /* needs to be added */ + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's y position for later use */ + start_y = y; + + /* first control point */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + + /* second control point */ + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x += args[5]; + cff_builder_add_point( builder, x, y, 0 ); + + /* fourth control point */ + x += args[6]; + y += args[7]; + cff_builder_add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start */ + x += args[8]; + y = start_y; + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_hflex: + { + FT_Pos start_y; + + + FT_TRACE4(( " hflex\n" )); + + /* adding six more points; 4 control points, 2 on-curve points */ + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's y-position for later use */ + start_y = y; + + /* first control point */ + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + + /* second control point */ + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x += args[4]; + cff_builder_add_point( builder, x, y, 0 ); + + /* fourth control point */ + x += args[5]; + y = start_y; + cff_builder_add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start point's */ + /* y-value -- we don't add this point, though */ + x += args[6]; + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_flex1: + { + FT_Pos start_x, start_y; /* record start x, y values for */ + /* alter use */ + FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ + /* algorithm below */ + FT_Int horizontal, count; + FT_Fixed* temp; + + + FT_TRACE4(( " flex1\n" )); + + /* adding six more points; 4 control points, 2 on-curve points */ + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's x, y position for later use */ + start_x = x; + start_y = y; + + /* XXX: figure out whether this is supposed to be a horizontal */ + /* or vertical flex; the Type 2 specification is vague... */ + + temp = args; + + /* grab up to the last argument */ + for ( count = 5; count > 0; count-- ) + { + dx += temp[0]; + dy += temp[1]; + temp += 2; + } + + if ( dx < 0 ) + dx = -dx; + if ( dy < 0 ) + dy = -dy; + + /* strange test, but here it is... */ + horizontal = ( dx > dy ); + + for ( count = 5; count > 0; count-- ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 3 ) ); + args += 2; + } + + /* is last operand an x- or y-delta? */ + if ( horizontal ) + { + x += args[0]; + y = start_y; + } + else + { + x = start_x; + y += args[0]; + } + + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_flex: + { + FT_UInt count; + + + FT_TRACE4(( " flex\n" )); + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, 6 ) ) + goto Fail; + + for ( count = 6; count > 0; count-- ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 4 || count == 1 ) ); + args += 2; + } + + args = stack; + } + break; + + case cff_op_seac: + FT_TRACE4(( " seac\n" )); + + error = cff_operator_seac( decoder, + args[0], args[1], args[2], + (FT_Int)( args[3] >> 16 ), + (FT_Int)( args[4] >> 16 ) ); + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* return now! */ + FT_TRACE4(( "\n" )); + return error; + + case cff_op_endchar: + FT_TRACE4(( " endchar\n" )); + + /* We are going to emulate the seac operator. */ + if ( num_args >= 4 ) + { + /* Save glyph width so that the subglyphs don't overwrite it. */ + FT_Pos glyph_width = decoder->glyph_width; + + + error = cff_operator_seac( decoder, + 0L, args[-4], args[-3], + (FT_Int)( args[-2] >> 16 ), + (FT_Int)( args[-1] >> 16 ) ); + + decoder->glyph_width = glyph_width; + } + else + { + if ( !error ) + error = FT_Err_Ok; + + cff_builder_close_contour( builder ); + + /* close hints recording session */ + if ( hinter ) + { + if ( hinter->close( hinter->hints, + builder->current->n_points ) ) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + } + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + } + + /* return now! */ + FT_TRACE4(( "\n" )); + return error; + + case cff_op_abs: + FT_TRACE4(( " abs\n" )); + + if ( args[0] < 0 ) + args[0] = -args[0]; + args++; + break; + + case cff_op_add: + FT_TRACE4(( " add\n" )); + + args[0] += args[1]; + args++; + break; + + case cff_op_sub: + FT_TRACE4(( " sub\n" )); + + args[0] -= args[1]; + args++; + break; + + case cff_op_div: + FT_TRACE4(( " div\n" )); + + args[0] = FT_DivFix( args[0], args[1] ); + args++; + break; + + case cff_op_neg: + FT_TRACE4(( " neg\n" )); + + args[0] = -args[0]; + args++; + break; + + case cff_op_random: + { + FT_Fixed Rand; + + + FT_TRACE4(( " rand\n" )); + + Rand = seed; + if ( Rand >= 0x8000L ) + Rand++; + + args[0] = Rand; + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + args++; + } + break; + + case cff_op_mul: + FT_TRACE4(( " mul\n" )); + + args[0] = FT_MulFix( args[0], args[1] ); + args++; + break; + + case cff_op_sqrt: + FT_TRACE4(( " sqrt\n" )); + + if ( args[0] > 0 ) + { + FT_Int count = 9; + FT_Fixed root = args[0]; + FT_Fixed new_root; + + + for (;;) + { + new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; + if ( new_root == root || count <= 0 ) + break; + root = new_root; + } + args[0] = new_root; + } + else + args[0] = 0; + args++; + break; + + case cff_op_drop: + /* nothing */ + FT_TRACE4(( " drop\n" )); + + break; + + case cff_op_exch: + { + FT_Fixed tmp; + + + FT_TRACE4(( " exch\n" )); + + tmp = args[0]; + args[0] = args[1]; + args[1] = tmp; + args += 2; + } + break; + + case cff_op_index: + { + FT_Int idx = (FT_Int)( args[0] >> 16 ); + + + FT_TRACE4(( " index\n" )); + + if ( idx < 0 ) + idx = 0; + else if ( idx > num_args - 2 ) + idx = num_args - 2; + args[0] = args[-( idx + 1 )]; + args++; + } + break; + + case cff_op_roll: + { + FT_Int count = (FT_Int)( args[0] >> 16 ); + FT_Int idx = (FT_Int)( args[1] >> 16 ); + + + FT_TRACE4(( " roll\n" )); + + if ( count <= 0 ) + count = 1; + + args -= count; + if ( args < stack ) + goto Stack_Underflow; + + if ( idx >= 0 ) + { + while ( idx > 0 ) + { + FT_Fixed tmp = args[count - 1]; + FT_Int i; + + + for ( i = count - 2; i >= 0; i-- ) + args[i + 1] = args[i]; + args[0] = tmp; + idx--; + } + } + else + { + while ( idx < 0 ) + { + FT_Fixed tmp = args[0]; + FT_Int i; + + + for ( i = 0; i < count - 1; i++ ) + args[i] = args[i + 1]; + args[count - 1] = tmp; + idx++; + } + } + args += count; + } + break; + + case cff_op_dup: + FT_TRACE4(( " dup\n" )); + + args[1] = args[0]; + args += 2; + break; + + case cff_op_put: + { + FT_Fixed val = args[0]; + FT_Int idx = (FT_Int)( args[1] >> 16 ); + + + FT_TRACE4(( " put\n" )); + + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) + decoder->buildchar[idx] = val; + } + break; + + case cff_op_get: + { + FT_Int idx = (FT_Int)( args[0] >> 16 ); + FT_Fixed val = 0; + + + FT_TRACE4(( " get\n" )); + + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) + val = decoder->buildchar[idx]; + + args[0] = val; + args++; + } + break; + + case cff_op_store: + FT_TRACE4(( " store\n")); + + goto Unimplemented; + + case cff_op_load: + FT_TRACE4(( " load\n" )); + + goto Unimplemented; + + case cff_op_dotsection: + /* this operator is deprecated and ignored by the parser */ + FT_TRACE4(( " dotsection\n" )); + break; + + case cff_op_closepath: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " closepath (invalid op)\n" )); + + args = stack; + break; + + case cff_op_hsbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " hsbw (invalid op)\n" )); + + decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = 0; + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y; + args = stack; + break; + + case cff_op_sbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " sbw (invalid op)\n" )); + + decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = args[1]; + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y + args[1]; + args = stack; + break; + + case cff_op_setcurrentpoint: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y + args[1]; + args = stack; + break; + + case cff_op_callothersubr: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " callothersubr (invalid op)\n" )); + + /* subsequent `pop' operands should add the arguments, */ + /* this is the implementation described for `unknown' other */ + /* subroutines in the Type1 spec. */ + /* */ + /* XXX Fix return arguments (see discussion below). */ + args -= 2 + ( args[-2] >> 16 ); + if ( args < stack ) + goto Stack_Underflow; + break; + + case cff_op_pop: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " pop (invalid op)\n" )); + + /* XXX Increasing `args' is wrong: After a certain number of */ + /* `pop's we get a stack overflow. Reason for doing it is */ + /* code like this (actually found in a CFF font): */ + /* */ + /* 17 1 3 callothersubr */ + /* pop */ + /* callsubr */ + /* */ + /* Since we handle `callothersubr' as a no-op, and */ + /* `callsubr' needs at least one argument, `pop' can't be a */ + /* no-op too as it basically should be. */ + /* */ + /* The right solution would be to provide real support for */ + /* `callothersubr' as done in `t1decode.c', however, given */ + /* the fact that CFF fonts with `pop' are invalid, it is */ + /* questionable whether it is worth the time. */ + args++; + break; + + case cff_op_and: + { + FT_Fixed cond = args[0] && args[1]; + + + FT_TRACE4(( " and\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_or: + { + FT_Fixed cond = args[0] || args[1]; + + + FT_TRACE4(( " or\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_eq: + { + FT_Fixed cond = !args[0]; + + + FT_TRACE4(( " eq\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_ifelse: + { + FT_Fixed cond = ( args[2] <= args[3] ); + + + FT_TRACE4(( " ifelse\n" )); + + if ( !cond ) + args[0] = args[1]; + args++; + } + break; + + case cff_op_callsubr: + { + FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + + decoder->locals_bias ); + + + FT_TRACE4(( " callsubr(%d)\n", idx )); + + if ( idx >= decoder->num_locals ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid local subr index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = decoder->locals[idx]; + zone->limit = decoder->locals[idx + 1]; + zone->cursor = zone->base; + + if ( !zone->base || zone->limit == zone->base ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invoking empty subrs\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case cff_op_callgsubr: + { + FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + + decoder->globals_bias ); + + + FT_TRACE4(( " callgsubr(%d)\n", idx )); + + if ( idx >= decoder->num_globals ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid global subr index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = decoder->globals[idx]; + zone->limit = decoder->globals[idx + 1]; + zone->cursor = zone->base; + + if ( !zone->base || zone->limit == zone->base ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invoking empty subrs\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case cff_op_return: + FT_TRACE4(( " return\n" )); + + if ( decoder->zone <= decoder->zones ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " unexpected return\n" )); + goto Syntax_Error; + } + + decoder->zone--; + zone = decoder->zone; + ip = zone->cursor; + limit = zone->limit; + break; + + default: + Unimplemented: + FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); + + if ( ip[-1] == 12 ) + FT_ERROR(( " %d", ip[0] )); + FT_ERROR(( "\n" )); + + return FT_THROW( Unimplemented_Feature ); + } + + decoder->top = args; + + if ( decoder->top - stack >= CFF_MAX_OPERANDS ) + goto Stack_Overflow; + + } /* general operator processing */ + + } /* while ip < limit */ + + FT_TRACE4(( "..end..\n\n" )); + + Fail: + return error; + + Syntax_Error: + FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); + return FT_THROW( Invalid_File_Format ); + + Stack_Underflow: + FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); + return FT_THROW( Too_Few_Arguments ); + + Stack_Overflow: + FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); + return FT_THROW( Stack_Overflow ); + } + +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#if 0 /* unused until we support pure CFF fonts */ + + + FT_LOCAL_DEF( FT_Error ) + cff_compute_max_advance( TT_Face face, + FT_Int* max_advance ) + { + FT_Error error = FT_Err_Ok; + CFF_Decoder decoder; + FT_Int glyph_index; + CFF_Font cff = (CFF_Font)face->other; + + + *max_advance = 0; + + /* Initialize load decoder */ + cff_decoder_init( &decoder, face, 0, 0, 0, 0 ); + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + /* For each glyph, parse the glyph charstring and extract */ + /* the advance width. */ + for ( glyph_index = 0; glyph_index < face->root.num_glyphs; + glyph_index++ ) + { + FT_Byte* charstring; + FT_ULong charstring_len; + + + /* now get load the unscaled outline */ + error = cff_get_glyph_data( face, glyph_index, + &charstring, &charstring_len ); + if ( !error ) + { + error = cff_decoder_prepare( &decoder, size, glyph_index ); + if ( !error ) + error = cff_decoder_parse_charstrings( &decoder, + charstring, + charstring_len ); + + cff_free_glyph_data( face, &charstring, &charstring_len ); + } + + /* ignore the error if one has occurred -- skip to next glyph */ + error = FT_Err_Ok; + } + + *max_advance = decoder.builder.advance.x; + + return FT_Err_Ok; + } + + +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_Error ) + cff_slot_load( CFF_GlyphSlot glyph, + CFF_Size size, + 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, scaled, force_scaling; + CFF_Font cff = (CFF_Font)face->extra.data; + + FT_Matrix font_matrix; + FT_Vector font_offset; + + + force_scaling = FALSE; + + /* 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 ) + { + /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */ + if ( glyph_index != 0 ) + { + glyph_index = cff_charset_cid_to_gindex( &cff->charset, + glyph_index ); + if ( glyph_index == 0 ) + return FT_THROW( Invalid_Argument ); + } + } + else if ( glyph_index >= cff->num_glyphs ) + return FT_THROW( Invalid_Argument ); + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + glyph->x_scale = 0x10000L; + glyph->y_scale = 0x10000L; + if ( size ) + { + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + } + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* try to load embedded bitmap if any */ + /* */ + /* XXX: The convention should be emphasized in */ + /* the documents because it can be confusing. */ + if ( size ) + { + CFF_Face cff_face = (CFF_Face)size->root.face; + SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt; + FT_Stream stream = cff_face->root.stream; + + + if ( size->strike_index != 0xFFFFFFFFUL && + sfnt->load_eblc && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + TT_SBit_MetricsRec metrics; + + + error = sfnt->load_sbit_image( face, + size->strike_index, + glyph_index, + (FT_Int)load_flags, + stream, + &glyph->root.bitmap, + &metrics ); + + if ( !error ) + { + FT_Bool has_vertical_info; + FT_UShort advance; + FT_Short dummy; + + + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + glyph->root.metrics.width = (FT_Pos)metrics.width << 6; + glyph->root.metrics.height = (FT_Pos)metrics.height << 6; + + glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; + glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; + glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + + glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; + glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; + glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + + glyph->root.format = FT_GLYPH_FORMAT_BITMAP; + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + glyph->root.bitmap_left = metrics.vertBearingX; + glyph->root.bitmap_top = metrics.vertBearingY; + } + else + { + glyph->root.bitmap_left = metrics.horiBearingX; + glyph->root.bitmap_top = metrics.horiBearingY; + } + + /* compute linear advance widths */ + + ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, + glyph_index, + &dummy, + &advance ); + glyph->root.linearHoriAdvance = advance; + + has_vertical_info = FT_BOOL( + face->vertical_info && + face->vertical.number_Of_VMetrics > 0 ); + + /* get the vertical metrics from the vtmx table if we have one */ + if ( has_vertical_info ) + { + ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, + glyph_index, + &dummy, + &advance ); + glyph->root.linearVertAdvance = advance; + } + else + { + /* make up vertical ones */ + if ( face->os2.version != 0xFFFFU ) + glyph->root.linearVertAdvance = (FT_Pos) + ( face->os2.sTypoAscender - face->os2.sTypoDescender ); + else + glyph->root.linearVertAdvance = (FT_Pos) + ( face->horizontal.Ascender - face->horizontal.Descender ); + } + + return error; + } + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* return immediately if we only want the embedded bitmaps */ + if ( load_flags & FT_LOAD_SBITS_ONLY ) + return FT_THROW( Invalid_Argument ); + + /* if we have a CID subfont, use its matrix (which has already */ + /* been multiplied with the root matrix) */ + + /* this scaling is only relevant if the PS hinter isn't active */ + if ( cff->num_subfonts ) + { + FT_ULong top_upm, sub_upm; + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, + glyph_index ); + + + if ( fd_index >= cff->num_subfonts ) + fd_index = (FT_Byte)( cff->num_subfonts - 1 ); + + top_upm = cff->top_font.font_dict.units_per_em; + sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; + + + font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; + font_offset = cff->subfonts[fd_index]->font_dict.font_offset; + + if ( top_upm != sub_upm ) + { + glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm ); + glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm ); + + force_scaling = TRUE; + } + } + else + { + font_matrix = cff->top_font.font_dict.font_matrix; + font_offset = cff->top_font.font_dict.font_offset; + } + + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + /* top-level code ensures that FT_LOAD_NO_HINTING is set */ + /* if FT_LOAD_NO_SCALE is active */ + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); + + glyph->hint = hinting; + glyph->scaled = scaled; + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */ + + { +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face ); +#endif + + + FT_Byte* charstring; + FT_ULong charstring_len; + + + cff_decoder_init( &decoder, face, size, glyph, hinting, + FT_LOAD_TARGET_MODE( load_flags ) ); + + if ( load_flags & FT_LOAD_ADVANCE_ONLY ) + decoder.width_only = TRUE; + + decoder.builder.no_recurse = + (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); + + /* now load the unscaled outline */ + error = cff_get_glyph_data( face, glyph_index, + &charstring, &charstring_len ); + if ( error ) + goto Glyph_Build_Finished; + + error = cff_decoder_prepare( &decoder, size, glyph_index ); + if ( error ) + goto Glyph_Build_Finished; + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + /* choose which CFF renderer to use */ + if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) + error = cff_decoder_parse_charstrings( &decoder, + charstring, + charstring_len ); + else +#endif + { + error = cf2_decoder_parse_charstrings( &decoder, + charstring, + charstring_len ); + + /* Adobe's engine uses 16.16 numbers everywhere; */ + /* as a consequence, glyphs larger than 2000ppem get rejected */ + if ( FT_ERR_EQ( error, Glyph_Too_Big ) ) + { + /* this time, we retry unhinted and scale up the glyph later on */ + /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */ + /* 0x400 for both `x_scale' and `y_scale' in this case) */ + hinting = FALSE; + force_scaling = TRUE; + glyph->hint = hinting; + + error = cf2_decoder_parse_charstrings( &decoder, + charstring, + charstring_len ); + } + } + + cff_free_glyph_data( face, &charstring, charstring_len ); + + if ( error ) + goto Glyph_Build_Finished; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Control data and length may not be available for incremental */ + /* fonts. */ + if ( face->root.internal->incremental_interface ) + { + glyph->root.control_data = 0; + glyph->root.control_len = 0; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* We set control_data and control_len if charstrings is loaded. */ + /* See how charstring loads at cff_index_access_element() in */ + /* cffload.c. */ + { + CFF_Index csindex = &cff->charstrings_index; + + + if ( csindex->offsets ) + { + glyph->root.control_data = csindex->bytes + + csindex->offsets[glyph_index] - 1; + glyph->root.control_len = charstring_len; + } + } + + Glyph_Build_Finished: + /* save new glyph tables, if no error */ + if ( !error ) + cff_builder_done( &decoder.builder ); + /* XXX: anything to do for broken glyph entry? */ + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && + face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = decoder.builder.left_bearing.x; + metrics.bearing_y = 0; + metrics.advance = decoder.builder.advance.x; + metrics.advance_v = decoder.builder.advance.y; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + + decoder.builder.left_bearing.x = metrics.bearing_x; + decoder.builder.advance.x = metrics.advance; + decoder.builder.advance.y = metrics.advance_v; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + if ( !error ) + { + /* Now, set the metrics -- this is rather simple, as */ + /* the left side bearing is the xMin, and the top side */ + /* bearing the yMax. */ + + /* For composite glyphs, return only left side bearing and */ + /* advance width. */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + FT_Slot_Internal internal = glyph->root.internal; + + + glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; + glyph->root.metrics.horiAdvance = decoder.glyph_width; + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; + } + else + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; + FT_Vector advance; + FT_Bool has_vertical_info; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.glyph_width; + glyph->root.linearHoriAdvance = decoder.glyph_width; + glyph->root.internal->glyph_transformed = 0; + + has_vertical_info = FT_BOOL( face->vertical_info && + face->vertical.number_Of_VMetrics > 0 ); + + /* get the vertical metrics from the vtmx table if we have one */ + if ( has_vertical_info ) + { + FT_Short vertBearingY = 0; + FT_UShort vertAdvance = 0; + + + ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, + glyph_index, + &vertBearingY, + &vertAdvance ); + metrics->vertBearingY = vertBearingY; + metrics->vertAdvance = vertAdvance; + } + else + { + /* make up vertical ones */ + if ( face->os2.version != 0xFFFFU ) + metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender - + face->os2.sTypoDescender ); + else + metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender - + face->horizontal.Descender ); + } + + glyph->root.linearVertAdvance = metrics->vertAdvance; + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + glyph->root.outline.flags = 0; + if ( size && size->root.metrics.y_ppem < 24 ) + glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; + + if ( !( font_matrix.xx == 0x10000L && + font_matrix.yy == 0x10000L && + font_matrix.xy == 0 && + font_matrix.yx == 0 ) ) + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); + + if ( !( font_offset.x == 0 && + font_offset.y == 0 ) ) + FT_Outline_Translate( &glyph->root.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 || force_scaling ) + { + /* scale the outline and the metrics */ + FT_Int n; + FT_Outline* cur = &glyph->root.outline; + 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( &glyph->root.outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + + if ( has_vertical_info ) + metrics->vertBearingX = metrics->horiBearingX - + metrics->horiAdvance / 2; + else + { + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } + } + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cffgload.h b/drivers/freetype/src/cff/cffgload.h new file mode 100644 index 0000000000..41df7db692 --- /dev/null +++ b/drivers/freetype/src/cff/cffgload.h @@ -0,0 +1,240 @@ +/***************************************************************************/ +/* */ +/* cffgload.h */ +/* */ +/* OpenType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2004, 2006-2009, 2013 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 __CFFGLOAD_H__ +#define __CFFGLOAD_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include "cffobjs.h" + + +FT_BEGIN_HEADER + + +#define CFF_MAX_OPERANDS 48 +#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_TRANS_ELEMENTS 32 + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* CFF_Builder */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: The current glyph loader. */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* path_begun :: A flag which indicates that a new path has begun. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* hints_funcs :: Auxiliary pointer for hinting. */ + /* */ + /* hints_globals :: Auxiliary pointer for hinting. */ + /* */ + typedef struct CFF_Builder_ + { + FT_Memory memory; + TT_Face face; + CFF_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; + + FT_Bool metrics_only; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + } CFF_Builder; + + + FT_LOCAL( FT_Error ) + cff_check_points( CFF_Builder* builder, + FT_Int count ); + + FT_LOCAL( void ) + cff_builder_add_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + FT_LOCAL( FT_Error ) + cff_builder_add_point1( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ); + FT_LOCAL( FT_Error ) + cff_builder_start_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ); + FT_LOCAL( void ) + cff_builder_close_contour( CFF_Builder* builder ); + + + FT_LOCAL( FT_Int ) + cff_lookup_glyph_by_stdcharcode( CFF_Font cff, + FT_Int charcode ); + FT_LOCAL( FT_Error ) + cff_get_glyph_data( TT_Face face, + FT_UInt glyph_index, + FT_Byte** pointer, + FT_ULong* length ); + FT_LOCAL( void ) + cff_free_glyph_data( TT_Face face, + FT_Byte** pointer, + FT_ULong length ); + + + /* execution context charstring zone */ + + typedef struct CFF_Decoder_Zone_ + { + FT_Byte* base; + FT_Byte* limit; + FT_Byte* cursor; + + } CFF_Decoder_Zone; + + + typedef struct CFF_Decoder_ + { + CFF_Builder builder; + CFF_Font cff; + + FT_Fixed stack[CFF_MAX_OPERANDS + 1]; + FT_Fixed* top; + + CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1]; + CFF_Decoder_Zone* zone; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + FT_Pos glyph_width; + FT_Pos nominal_width; + + FT_Bool read_width; + FT_Bool width_only; + FT_Int num_hints; + FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]; + + FT_UInt num_locals; + FT_UInt num_globals; + + FT_Int locals_bias; + FT_Int globals_bias; + + FT_Byte** locals; + FT_Byte** globals; + + FT_Byte** glyph_names; /* for pure CFF fonts only */ + FT_UInt num_glyphs; /* number of glyphs in font */ + + FT_Render_Mode hint_mode; + + FT_Bool seac; + + CFF_SubFont current_subfont; /* for current glyph_index */ + + } CFF_Decoder; + + + FT_LOCAL( void ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode ); + + FT_LOCAL( FT_Error ) + cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, + FT_UInt glyph_index ); + +#if 0 /* unused until we support pure CFF fonts */ + + /* Compute the maximum advance width of a font through quick parsing */ + FT_LOCAL( FT_Error ) + cff_compute_max_advance( TT_Face face, + FT_Int* max_advance ); + +#endif /* 0 */ + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + FT_LOCAL( FT_Error ) + cff_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ); +#endif + + FT_LOCAL( FT_Error ) + cff_slot_load( CFF_GlyphSlot glyph, + CFF_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __CFFGLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cffload.c b/drivers/freetype/src/cff/cffload.c new file mode 100644 index 0000000000..64b497168d --- /dev/null +++ b/drivers/freetype/src/cff/cffload.c @@ -0,0 +1,1696 @@ +/***************************************************************************/ +/* */ +/* cffload.c */ +/* */ +/* OpenType and CFF data/program tables loader (body). */ +/* */ +/* Copyright 1996-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include FT_TYPE1_TABLES_H + +#include "cffload.h" +#include "cffparse.h" + +#include "cfferrs.h" + + +#if 1 + + static const FT_UShort cff_isoadobe_charset[229] = + { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228 + }; + + static const FT_UShort cff_expert_charset[166] = + { + 0, 1, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 13, 14, 15, 99, + 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 109, 110, + 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 158, 155, 163, 319, + 320, 321, 322, 323, 324, 325, 326, 150, + 164, 169, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378 + }; + + static const FT_UShort cff_expertsubset_charset[87] = + { + 0, 1, 231, 232, 235, 236, 237, 238, + 13, 14, 15, 99, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 27, 28, + 249, 250, 251, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, + 266, 109, 110, 267, 268, 269, 270, 272, + 300, 301, 302, 305, 314, 315, 158, 155, + 163, 320, 321, 322, 323, 324, 325, 326, + 150, 164, 169, 327, 328, 329, 330, 331, + 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346 + }; + + static const FT_UShort cff_standard_encoding[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, + 0, 111, 112, 113, 114, 0, 115, 116, + 117, 118, 119, 120, 121, 122, 0, 123, + 0, 124, 125, 126, 127, 128, 129, 130, + 131, 0, 132, 133, 0, 134, 135, 136, + 137, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 138, 0, 139, 0, 0, 0, 0, + 140, 141, 142, 143, 0, 0, 0, 0, + 0, 144, 0, 0, 0, 145, 0, 0, + 146, 147, 148, 149, 0, 0, 0, 0 + }; + + static const FT_UShort cff_expert_encoding[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 229, 230, 0, 231, 232, 233, 234, + 235, 236, 237, 238, 13, 14, 15, 99, + 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 252, + 0, 253, 254, 255, 256, 257, 0, 0, + 0, 258, 0, 0, 259, 260, 261, 262, + 0, 0, 263, 264, 265, 0, 266, 109, + 110, 267, 268, 269, 0, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 304, 305, 306, 0, 0, 307, 308, + 309, 310, 311, 0, 312, 0, 0, 312, + 0, 0, 314, 315, 0, 0, 316, 317, + 318, 0, 0, 0, 158, 155, 163, 319, + 320, 321, 322, 323, 324, 325, 0, 0, + 326, 150, 164, 169, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378 + }; + +#endif /* 1 */ + + + FT_LOCAL_DEF( FT_UShort ) + cff_get_standard_encoding( FT_UInt charcode ) + { + return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] + : 0 ); + } + + + /*************************************************************************/ + /* */ + /* 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_cffload + + + /* read an offset from the index's stream current position */ + static FT_ULong + cff_index_read_offset( CFF_Index idx, + FT_Error *errorp ) + { + FT_Error error; + FT_Stream stream = idx->stream; + FT_Byte tmp[4]; + FT_ULong result = 0; + + + if ( !FT_STREAM_READ( tmp, idx->off_size ) ) + { + FT_Int nn; + + + for ( nn = 0; nn < idx->off_size; nn++ ) + result = ( result << 8 ) | tmp[nn]; + } + + *errorp = error; + return result; + } + + + static FT_Error + cff_index_init( CFF_Index idx, + FT_Stream stream, + FT_Bool load ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UShort count; + + + FT_MEM_ZERO( idx, sizeof ( *idx ) ); + + idx->stream = stream; + idx->start = FT_STREAM_POS(); + if ( !FT_READ_USHORT( count ) && + count > 0 ) + { + FT_Byte offsize; + FT_ULong size; + + + /* there is at least one element; read the offset size, */ + /* then access the offset table to compute the index's total size */ + if ( FT_READ_BYTE( offsize ) ) + goto Exit; + + if ( offsize < 1 || offsize > 4 ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + idx->count = count; + idx->off_size = offsize; + size = (FT_ULong)( count + 1 ) * offsize; + + idx->data_offset = idx->start + 3 + size; + + if ( FT_STREAM_SKIP( size - offsize ) ) + goto Exit; + + size = cff_index_read_offset( idx, &error ); + if ( error ) + goto Exit; + + if ( size == 0 ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + idx->data_size = --size; + + if ( load ) + { + /* load the data */ + if ( FT_FRAME_EXTRACT( size, idx->bytes ) ) + goto Exit; + } + else + { + /* skip the data */ + if ( FT_STREAM_SKIP( size ) ) + goto Exit; + } + } + + Exit: + if ( error ) + FT_FREE( idx->offsets ); + + return error; + } + + + static void + cff_index_done( CFF_Index idx ) + { + if ( idx->stream ) + { + FT_Stream stream = idx->stream; + FT_Memory memory = stream->memory; + + + if ( idx->bytes ) + FT_FRAME_RELEASE( idx->bytes ); + + FT_FREE( idx->offsets ); + FT_MEM_ZERO( idx, sizeof ( *idx ) ); + } + } + + + static FT_Error + cff_index_load_offsets( CFF_Index idx ) + { + FT_Error error = FT_Err_Ok; + FT_Stream stream = idx->stream; + FT_Memory memory = stream->memory; + + + if ( idx->count > 0 && idx->offsets == NULL ) + { + FT_Byte offsize = idx->off_size; + FT_ULong data_size; + FT_Byte* p; + FT_Byte* p_end; + FT_ULong* poff; + + + data_size = (FT_ULong)( idx->count + 1 ) * offsize; + + if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || + FT_STREAM_SEEK( idx->start + 3 ) || + FT_FRAME_ENTER( data_size ) ) + goto Exit; + + poff = idx->offsets; + p = (FT_Byte*)stream->cursor; + p_end = p + data_size; + + switch ( offsize ) + { + case 1: + for ( ; p < p_end; p++, poff++ ) + poff[0] = p[0]; + break; + + case 2: + for ( ; p < p_end; p += 2, poff++ ) + poff[0] = FT_PEEK_USHORT( p ); + break; + + case 3: + for ( ; p < p_end; p += 3, poff++ ) + poff[0] = FT_PEEK_OFF3( p ); + break; + + default: + for ( ; p < p_end; p += 4, poff++ ) + poff[0] = FT_PEEK_ULONG( p ); + } + + FT_FRAME_EXIT(); + } + + Exit: + if ( error ) + FT_FREE( idx->offsets ); + + return error; + } + + + /* Allocate a table containing pointers to an index's elements. */ + /* The `pool' argument makes this function convert the index */ + /* entries to C-style strings (this is, NULL-terminated). */ + static FT_Error + cff_index_get_pointers( CFF_Index idx, + FT_Byte*** table, + FT_Byte** pool ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = idx->stream->memory; + + FT_Byte** t = NULL; + FT_Byte* new_bytes = NULL; + + + *table = NULL; + + if ( idx->offsets == NULL ) + { + error = cff_index_load_offsets( idx ); + if ( error ) + goto Exit; + } + + if ( idx->count > 0 && + !FT_NEW_ARRAY( t, idx->count + 1 ) && + ( !pool || !FT_ALLOC( new_bytes, + idx->data_size + idx->count ) ) ) + { + FT_ULong n, cur_offset; + FT_ULong extra = 0; + FT_Byte* org_bytes = idx->bytes; + + + /* at this point, `idx->offsets' can't be NULL */ + cur_offset = idx->offsets[0] - 1; + + /* sanity check */ + if ( cur_offset >= idx->data_size ) + { + FT_TRACE0(( "cff_index_get_pointers:" + " invalid first offset value %d set to zero\n", + cur_offset )); + cur_offset = 0; + } + + if ( !pool ) + t[0] = org_bytes + cur_offset; + else + t[0] = new_bytes + cur_offset; + + for ( n = 1; n <= idx->count; n++ ) + { + FT_ULong next_offset = idx->offsets[n] - 1; + + + /* empty slot + two sanity checks for invalid offset tables */ + if ( next_offset == 0 || + next_offset < cur_offset || + ( next_offset >= idx->data_size && n < idx->count ) ) + next_offset = cur_offset; + + if ( !pool ) + t[n] = org_bytes + next_offset; + else + { + t[n] = new_bytes + next_offset + extra; + + if ( next_offset != cur_offset ) + { + FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] ); + t[n][0] = '\0'; + t[n] += 1; + extra++; + } + } + + cur_offset = next_offset; + } + *table = t; + + if ( pool ) + *pool = new_bytes; + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_index_access_element( CFF_Index idx, + FT_UInt element, + FT_Byte** pbytes, + FT_ULong* pbyte_len ) + { + FT_Error error = FT_Err_Ok; + + + if ( idx && idx->count > element ) + { + /* compute start and end offsets */ + FT_Stream stream = idx->stream; + FT_ULong off1, off2 = 0; + + + /* load offsets from file or the offset table */ + if ( !idx->offsets ) + { + FT_ULong pos = element * idx->off_size; + + + if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) + goto Exit; + + off1 = cff_index_read_offset( idx, &error ); + if ( error ) + goto Exit; + + if ( off1 != 0 ) + { + do + { + element++; + off2 = cff_index_read_offset( idx, &error ); + } + while ( off2 == 0 && element < idx->count ); + } + } + else /* use offsets table */ + { + off1 = idx->offsets[element]; + if ( off1 ) + { + do + { + element++; + off2 = idx->offsets[element]; + + } while ( off2 == 0 && element < idx->count ); + } + } + + /* XXX: should check off2 does not exceed the end of this entry; */ + /* at present, only truncate off2 at the end of this stream */ + if ( off2 > stream->size + 1 || + idx->data_offset > stream->size - off2 + 1 ) + { + FT_ERROR(( "cff_index_access_element:" + " offset to next entry (%d)" + " exceeds the end of stream (%d)\n", + off2, stream->size - idx->data_offset + 1 )); + off2 = stream->size - idx->data_offset + 1; + } + + /* access element */ + if ( off1 && off2 > off1 ) + { + *pbyte_len = off2 - off1; + + if ( idx->bytes ) + { + /* this index was completely loaded in memory, that's easy */ + *pbytes = idx->bytes + off1 - 1; + } + else + { + /* this index is still on disk/file, access it through a frame */ + if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) || + FT_FRAME_EXTRACT( off2 - off1, *pbytes ) ) + goto Exit; + } + } + else + { + /* empty index element */ + *pbytes = 0; + *pbyte_len = 0; + } + } + else + error = FT_THROW( Invalid_Argument ); + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cff_index_forget_element( CFF_Index idx, + FT_Byte** pbytes ) + { + if ( idx->bytes == 0 ) + { + FT_Stream stream = idx->stream; + + + FT_FRAME_RELEASE( *pbytes ); + } + } + + + /* get an entry from Name INDEX */ + FT_LOCAL_DEF( FT_String* ) + cff_index_get_name( CFF_Font font, + FT_UInt element ) + { + CFF_Index idx = &font->name_index; + FT_Memory memory = idx->stream->memory; + FT_Byte* bytes; + FT_ULong byte_len; + FT_Error error; + FT_String* name = 0; + + + error = cff_index_access_element( idx, element, &bytes, &byte_len ); + if ( error ) + goto Exit; + + if ( !FT_ALLOC( name, byte_len + 1 ) ) + { + FT_MEM_COPY( name, bytes, byte_len ); + name[byte_len] = 0; + } + cff_index_forget_element( idx, &bytes ); + + Exit: + return name; + } + + + /* get an entry from String INDEX */ + FT_LOCAL_DEF( FT_String* ) + cff_index_get_string( CFF_Font font, + FT_UInt element ) + { + return ( element < font->num_strings ) + ? (FT_String*)font->strings[element] + : NULL; + } + + + FT_LOCAL_DEF( FT_String* ) + cff_index_get_sid_string( CFF_Font font, + FT_UInt sid ) + { + /* value 0xFFFFU indicates a missing dictionary entry */ + if ( sid == 0xFFFFU ) + return NULL; + + /* if it is not a standard string, return it */ + if ( sid > 390 ) + return cff_index_get_string( font, sid - 391 ); + + /* CID-keyed CFF fonts don't have glyph names */ + if ( !font->psnames ) + return NULL; + + /* this is a standard string */ + return (FT_String *)font->psnames->adobe_std_strings( sid ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** FD Select table support ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + + + static void + CFF_Done_FD_Select( CFF_FDSelect fdselect, + FT_Stream stream ) + { + if ( fdselect->data ) + FT_FRAME_RELEASE( fdselect->data ); + + fdselect->data_size = 0; + fdselect->format = 0; + fdselect->range_count = 0; + } + + + static FT_Error + CFF_Load_FD_Select( CFF_FDSelect fdselect, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong offset ) + { + FT_Error error; + FT_Byte format; + FT_UInt num_ranges; + + + /* read format */ + if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) ) + goto Exit; + + fdselect->format = format; + fdselect->cache_count = 0; /* clear cache */ + + switch ( format ) + { + case 0: /* format 0, that's simple */ + fdselect->data_size = num_glyphs; + goto Load_Data; + + case 3: /* format 3, a tad more complex */ + if ( FT_READ_USHORT( num_ranges ) ) + goto Exit; + + fdselect->data_size = num_ranges * 3 + 2; + + Load_Data: + if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) ) + goto Exit; + break; + + default: /* hmm... that's wrong */ + error = FT_THROW( Invalid_File_Format ); + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Byte ) + cff_fd_select_get( CFF_FDSelect fdselect, + FT_UInt glyph_index ) + { + FT_Byte fd = 0; + + + switch ( fdselect->format ) + { + case 0: + fd = fdselect->data[glyph_index]; + break; + + case 3: + /* first, compare to cache */ + if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < + fdselect->cache_count ) + { + fd = fdselect->cache_fd; + break; + } + + /* then, lookup the ranges array */ + { + FT_Byte* p = fdselect->data; + FT_Byte* p_limit = p + fdselect->data_size; + FT_Byte fd2; + FT_UInt first, limit; + + + first = FT_NEXT_USHORT( p ); + do + { + if ( glyph_index < first ) + break; + + fd2 = *p++; + limit = FT_NEXT_USHORT( p ); + + if ( glyph_index < limit ) + { + fd = fd2; + + /* update cache */ + fdselect->cache_first = first; + fdselect->cache_count = limit-first; + fdselect->cache_fd = fd2; + break; + } + first = limit; + + } while ( p < p_limit ); + } + break; + + default: + ; + } + + return fd; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** CFF font support ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + cff_charset_compute_cids( CFF_Charset charset, + FT_UInt num_glyphs, + FT_Memory memory ) + { + FT_Error error = FT_Err_Ok; + FT_UInt i; + FT_Long j; + FT_UShort max_cid = 0; + + + if ( charset->max_cid > 0 ) + goto Exit; + + for ( i = 0; i < num_glyphs; i++ ) + { + if ( charset->sids[i] > max_cid ) + max_cid = charset->sids[i]; + } + + if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) ) + goto Exit; + + /* When multiple GIDs map to the same CID, we choose the lowest */ + /* GID. This is not described in any spec, but it matches the */ + /* behaviour of recent Acroread versions. */ + for ( j = num_glyphs - 1; j >= 0 ; j-- ) + charset->cids[charset->sids[j]] = (FT_UShort)j; + + charset->max_cid = max_cid; + charset->num_glyphs = num_glyphs; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_UInt ) + cff_charset_cid_to_gindex( CFF_Charset charset, + FT_UInt cid ) + { + FT_UInt result = 0; + + + if ( cid <= charset->max_cid ) + result = charset->cids[cid]; + + return result; + } + + + static void + cff_charset_free_cids( CFF_Charset charset, + FT_Memory memory ) + { + FT_FREE( charset->cids ); + charset->max_cid = 0; + } + + + static void + cff_charset_done( CFF_Charset charset, + FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + cff_charset_free_cids( charset, memory ); + + FT_FREE( charset->sids ); + charset->format = 0; + charset->offset = 0; + } + + + static FT_Error + cff_charset_load( CFF_Charset charset, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset, + FT_Bool invert ) + { + FT_Memory memory = stream->memory; + FT_Error error = FT_Err_Ok; + FT_UShort glyph_sid; + + + /* If the the offset is greater than 2, we have to parse the */ + /* charset table. */ + if ( offset > 2 ) + { + FT_UInt j; + + + charset->offset = base_offset + offset; + + /* Get the format of the table. */ + if ( FT_STREAM_SEEK( charset->offset ) || + FT_READ_BYTE( charset->format ) ) + goto Exit; + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* assign the .notdef glyph */ + charset->sids[0] = 0; + + switch ( charset->format ) + { + case 0: + if ( num_glyphs > 0 ) + { + if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) ) + goto Exit; + + for ( j = 1; j < num_glyphs; j++ ) + charset->sids[j] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + } + break; + + case 1: + case 2: + { + FT_UInt nleft; + FT_UInt i; + + + j = 1; + + while ( j < num_glyphs ) + { + /* Read the first glyph sid of the range. */ + if ( FT_READ_USHORT( glyph_sid ) ) + goto Exit; + + /* Read the number of glyphs in the range. */ + if ( charset->format == 2 ) + { + if ( FT_READ_USHORT( nleft ) ) + goto Exit; + } + else + { + if ( FT_READ_BYTE( nleft ) ) + goto Exit; + } + + /* try to rescue some of the SIDs if `nleft' is too large */ + if ( glyph_sid > 0xFFFFL - nleft ) + { + FT_ERROR(( "cff_charset_load: invalid SID range trimmed" + " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid )); + nleft = ( FT_UInt )( 0xFFFFL - glyph_sid ); + } + + /* Fill in the range of sids -- `nleft + 1' glyphs. */ + for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) + charset->sids[j] = glyph_sid; + } + } + break; + + default: + FT_ERROR(( "cff_charset_load: invalid table format\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + else + { + /* Parse default tables corresponding to offset == 0, 1, or 2. */ + /* CFF specification intimates the following: */ + /* */ + /* In order to use a predefined charset, the following must be */ + /* true: The charset constructed for the glyphs in the font's */ + /* charstrings dictionary must match the predefined charset in */ + /* the first num_glyphs. */ + + charset->offset = offset; /* record charset type */ + + switch ( (FT_UInt)offset ) + { + case 0: + if ( num_glyphs > 229 ) + { + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe ISO-Latin)\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs ); + + break; + + case 1: + if ( num_glyphs > 166 ) + { + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe Expert)\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs ); + + break; + + case 2: + if ( num_glyphs > 87 ) + { + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe Expert Subset)\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs ); + + break; + + default: + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + + /* we have to invert the `sids' array for subsetted CID-keyed fonts */ + if ( invert ) + error = cff_charset_compute_cids( charset, num_glyphs, memory ); + + Exit: + /* Clean up if there was an error. */ + if ( error ) + { + FT_FREE( charset->sids ); + FT_FREE( charset->cids ); + charset->format = 0; + charset->offset = 0; + charset->sids = 0; + } + + return error; + } + + + static void + cff_encoding_done( CFF_Encoding encoding ) + { + encoding->format = 0; + encoding->offset = 0; + encoding->count = 0; + } + + + static FT_Error + cff_encoding_load( CFF_Encoding encoding, + CFF_Charset charset, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset ) + { + FT_Error error = FT_Err_Ok; + FT_UInt count; + FT_UInt j; + FT_UShort glyph_sid; + FT_UInt glyph_code; + + + /* Check for charset->sids. If we do not have this, we fail. */ + if ( !charset->sids ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Zero out the code to gid/sid mappings. */ + for ( j = 0; j < 256; j++ ) + { + encoding->sids [j] = 0; + encoding->codes[j] = 0; + } + + /* Note: The encoding table in a CFF font is indexed by glyph index; */ + /* the first encoded glyph index is 1. Hence, we read the character */ + /* code (`glyph_code') at index j and make the assignment: */ + /* */ + /* encoding->codes[glyph_code] = j + 1 */ + /* */ + /* We also make the assignment: */ + /* */ + /* encoding->sids[glyph_code] = charset->sids[j + 1] */ + /* */ + /* This gives us both a code to GID and a code to SID mapping. */ + + if ( offset > 1 ) + { + encoding->offset = base_offset + offset; + + /* we need to parse the table to determine its size */ + if ( FT_STREAM_SEEK( encoding->offset ) || + FT_READ_BYTE( encoding->format ) || + FT_READ_BYTE( count ) ) + goto Exit; + + switch ( encoding->format & 0x7F ) + { + case 0: + { + FT_Byte* p; + + + /* By convention, GID 0 is always ".notdef" and is never */ + /* coded in the font. Hence, the number of codes found */ + /* in the table is `count+1'. */ + /* */ + encoding->count = count + 1; + + if ( FT_FRAME_ENTER( count ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + + for ( j = 1; j <= count; j++ ) + { + glyph_code = *p++; + + /* Make sure j is not too big. */ + if ( j < num_glyphs ) + { + /* Assign code to GID mapping. */ + encoding->codes[glyph_code] = (FT_UShort)j; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = charset->sids[j]; + } + } + + FT_FRAME_EXIT(); + } + break; + + case 1: + { + FT_UInt nleft; + FT_UInt i = 1; + FT_UInt k; + + + encoding->count = 0; + + /* Parse the Format1 ranges. */ + for ( j = 0; j < count; j++, i += nleft ) + { + /* Read the first glyph code of the range. */ + if ( FT_READ_BYTE( glyph_code ) ) + goto Exit; + + /* Read the number of codes in the range. */ + if ( FT_READ_BYTE( nleft ) ) + goto Exit; + + /* Increment nleft, so we read `nleft + 1' codes/sids. */ + nleft++; + + /* compute max number of character codes */ + if ( (FT_UInt)nleft > encoding->count ) + encoding->count = nleft; + + /* Fill in the range of codes/sids. */ + for ( k = i; k < nleft + i; k++, glyph_code++ ) + { + /* Make sure k is not too big. */ + if ( k < num_glyphs && glyph_code < 256 ) + { + /* Assign code to GID mapping. */ + encoding->codes[glyph_code] = (FT_UShort)k; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = charset->sids[k]; + } + } + } + + /* simple check; one never knows what can be found in a font */ + if ( encoding->count > 256 ) + encoding->count = 256; + } + break; + + default: + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Parse supplemental encodings, if any. */ + if ( encoding->format & 0x80 ) + { + FT_UInt gindex; + + + /* count supplements */ + if ( FT_READ_BYTE( count ) ) + goto Exit; + + for ( j = 0; j < count; j++ ) + { + /* Read supplemental glyph code. */ + if ( FT_READ_BYTE( glyph_code ) ) + goto Exit; + + /* Read the SID associated with this glyph code. */ + if ( FT_READ_USHORT( glyph_sid ) ) + goto Exit; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = glyph_sid; + + /* First, look up GID which has been assigned to */ + /* SID glyph_sid. */ + for ( gindex = 0; gindex < num_glyphs; gindex++ ) + { + if ( charset->sids[gindex] == glyph_sid ) + { + encoding->codes[glyph_code] = (FT_UShort)gindex; + break; + } + } + } + } + } + else + { + /* We take into account the fact a CFF font can use a predefined */ + /* encoding without containing all of the glyphs encoded by this */ + /* encoding (see the note at the end of section 12 in the CFF */ + /* specification). */ + + switch ( (FT_UInt)offset ) + { + case 0: + /* First, copy the code to SID mapping. */ + FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); + goto Populate; + + case 1: + /* First, copy the code to SID mapping. */ + FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); + + Populate: + /* Construct code to GID mapping from code to SID mapping */ + /* and charset. */ + + encoding->count = 0; + + error = cff_charset_compute_cids( charset, num_glyphs, + stream->memory ); + if ( error ) + goto Exit; + + for ( j = 0; j < 256; j++ ) + { + FT_UInt sid = encoding->sids[j]; + FT_UInt gid = 0; + + + if ( sid ) + gid = cff_charset_cid_to_gindex( charset, sid ); + + if ( gid != 0 ) + { + encoding->codes[j] = (FT_UShort)gid; + encoding->count = j + 1; + } + else + { + encoding->codes[j] = 0; + encoding->sids [j] = 0; + } + } + break; + + default: + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + + Exit: + + /* Clean up if there was an error. */ + return error; + } + + + static FT_Error + cff_subfont_load( CFF_SubFont font, + CFF_Index idx, + FT_UInt font_index, + FT_Stream stream, + FT_ULong base_offset, + FT_Library library ) + { + FT_Error error; + CFF_ParserRec parser; + FT_Byte* dict = NULL; + FT_ULong dict_len; + CFF_FontRecDict top = &font->font_dict; + CFF_Private priv = &font->private_dict; + + + cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); + + /* set defaults */ + FT_MEM_ZERO( top, sizeof ( *top ) ); + + top->underline_position = -( 100L << 16 ); + top->underline_thickness = 50L << 16; + top->charstring_type = 2; + top->font_matrix.xx = 0x10000L; + top->font_matrix.yy = 0x10000L; + top->cid_count = 8720; + + /* we use the implementation specific SID value 0xFFFF to indicate */ + /* missing entries */ + top->version = 0xFFFFU; + top->notice = 0xFFFFU; + top->copyright = 0xFFFFU; + top->full_name = 0xFFFFU; + top->family_name = 0xFFFFU; + top->weight = 0xFFFFU; + top->embedded_postscript = 0xFFFFU; + + top->cid_registry = 0xFFFFU; + top->cid_ordering = 0xFFFFU; + top->cid_font_name = 0xFFFFU; + + error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + if ( !error ) + { + FT_TRACE4(( " top dictionary:\n" )); + error = cff_parser_run( &parser, dict, dict + dict_len ); + } + + cff_index_forget_element( idx, &dict ); + + if ( error ) + goto Exit; + + /* if it is a CID font, we stop there */ + if ( top->cid_registry != 0xFFFFU ) + goto Exit; + + /* parse the private dictionary, if any */ + if ( top->private_offset && top->private_size ) + { + /* set defaults */ + FT_MEM_ZERO( priv, sizeof ( *priv ) ); + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = -1; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); + + cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); + + if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || + FT_FRAME_ENTER( font->font_dict.private_size ) ) + goto Exit; + + FT_TRACE4(( " private dictionary:\n" )); + error = cff_parser_run( &parser, + (FT_Byte*)stream->cursor, + (FT_Byte*)stream->limit ); + FT_FRAME_EXIT(); + if ( error ) + goto Exit; + + /* ensure that `num_blue_values' is even */ + priv->num_blue_values &= ~1; + } + + /* read the local subrs, if any */ + if ( priv->local_subrs_offset ) + { + if ( FT_STREAM_SEEK( base_offset + top->private_offset + + priv->local_subrs_offset ) ) + goto Exit; + + error = cff_index_init( &font->local_subrs_index, stream, 1 ); + if ( error ) + goto Exit; + + error = cff_index_get_pointers( &font->local_subrs_index, + &font->local_subrs, NULL ); + if ( error ) + goto Exit; + } + + Exit: + return error; + } + + + static void + cff_subfont_done( FT_Memory memory, + CFF_SubFont subfont ) + { + if ( subfont ) + { + cff_index_done( &subfont->local_subrs_index ); + FT_FREE( subfont->local_subrs ); + } + } + + + FT_LOCAL_DEF( FT_Error ) + cff_font_load( FT_Library library, + FT_Stream stream, + FT_Int face_index, + CFF_Font font, + FT_Bool pure_cff ) + { + static const FT_Frame_Field cff_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRec + + FT_FRAME_START( 4 ), + FT_FRAME_BYTE( version_major ), + FT_FRAME_BYTE( version_minor ), + FT_FRAME_BYTE( header_size ), + FT_FRAME_BYTE( absolute_offsize ), + FT_FRAME_END + }; + + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong base_offset; + CFF_FontRecDict dict; + CFF_IndexRec string_index; + FT_Int subfont_index; + + + FT_ZERO( font ); + FT_ZERO( &string_index ); + + font->stream = stream; + font->memory = memory; + dict = &font->top_font.font_dict; + base_offset = FT_STREAM_POS(); + + /* read CFF font header */ + if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) + goto Exit; + + /* check format */ + if ( font->version_major != 1 || + font->header_size < 4 || + font->absolute_offsize > 4 ) + { + FT_TRACE2(( " not a CFF font header\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* skip the rest of the header */ + if ( FT_STREAM_SKIP( font->header_size - 4 ) ) + goto Exit; + + /* read the name, top dict, string and global subrs index */ + if ( FT_SET_ERROR( cff_index_init( &font->name_index, + stream, 0 ) ) || + FT_SET_ERROR( cff_index_init( &font->font_dict_index, + stream, 0 ) ) || + FT_SET_ERROR( cff_index_init( &string_index, + stream, 1 ) ) || + FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1 ) ) || + FT_SET_ERROR( cff_index_get_pointers( &string_index, + &font->strings, + &font->string_pool ) ) ) + goto Exit; + + font->num_strings = string_index.count; + + if ( pure_cff ) + { + /* well, we don't really forget the `disabled' fonts... */ + subfont_index = face_index; + + if ( subfont_index >= (FT_Int)font->name_index.count ) + { + FT_ERROR(( "cff_font_load:" + " invalid subfont index for pure CFF font (%d)\n", + subfont_index )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + font->num_faces = font->name_index.count; + } + else + { + subfont_index = 0; + + if ( font->name_index.count > 1 ) + { + FT_ERROR(( "cff_font_load:" + " invalid CFF font with multiple subfonts\n" + " " + " in SFNT wrapper\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + + /* in case of a font format check, simply exit now */ + if ( face_index < 0 ) + goto Exit; + + /* now, parse the top-level font dictionary */ + FT_TRACE4(( "parsing top-level\n" )); + error = cff_subfont_load( &font->top_font, + &font->font_dict_index, + subfont_index, + stream, + base_offset, + library ); + if ( error ) + goto Exit; + + if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) + goto Exit; + + error = cff_index_init( &font->charstrings_index, stream, 0 ); + if ( error ) + goto Exit; + + /* now, check for a CID font */ + if ( dict->cid_registry != 0xFFFFU ) + { + CFF_IndexRec fd_index; + CFF_SubFont sub = NULL; + FT_UInt idx; + + + /* this is a CID-keyed font, we must now allocate a table of */ + /* sub-fonts, then load each of them separately */ + if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) + goto Exit; + + error = cff_index_init( &fd_index, stream, 0 ); + if ( error ) + goto Exit; + + if ( fd_index.count > CFF_MAX_CID_FONTS ) + { + FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); + goto Fail_CID; + } + + /* allocate & read each font dict independently */ + font->num_subfonts = fd_index.count; + if ( FT_NEW_ARRAY( sub, fd_index.count ) ) + goto Fail_CID; + + /* set up pointer table */ + for ( idx = 0; idx < fd_index.count; idx++ ) + font->subfonts[idx] = sub + idx; + + /* now load each subfont independently */ + for ( idx = 0; idx < fd_index.count; idx++ ) + { + sub = font->subfonts[idx]; + FT_TRACE4(( "parsing subfont %u\n", idx )); + error = cff_subfont_load( sub, &fd_index, idx, + stream, base_offset, library ); + if ( error ) + goto Fail_CID; + } + + /* now load the FD Select array */ + error = CFF_Load_FD_Select( &font->fd_select, + font->charstrings_index.count, + stream, + base_offset + dict->cid_fd_select_offset ); + + Fail_CID: + cff_index_done( &fd_index ); + + if ( error ) + goto Exit; + } + else + font->num_subfonts = 0; + + /* read the charstrings index now */ + if ( dict->charstrings_offset == 0 ) + { + FT_ERROR(( "cff_font_load: no charstrings offset\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + font->num_glyphs = font->charstrings_index.count; + + error = cff_index_get_pointers( &font->global_subrs_index, + &font->global_subrs, NULL ); + + if ( error ) + goto Exit; + + /* read the Charset and Encoding tables if available */ + if ( font->num_glyphs > 0 ) + { + FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); + + + error = cff_charset_load( &font->charset, font->num_glyphs, stream, + base_offset, dict->charset_offset, invert ); + if ( error ) + goto Exit; + + /* CID-keyed CFFs don't have an encoding */ + if ( dict->cid_registry == 0xFFFFU ) + { + error = cff_encoding_load( &font->encoding, + &font->charset, + font->num_glyphs, + stream, + base_offset, + dict->encoding_offset ); + if ( error ) + goto Exit; + } + } + + /* get the font name (/CIDFontName for CID-keyed fonts, */ + /* /FontName otherwise) */ + font->font_name = cff_index_get_name( font, subfont_index ); + + Exit: + cff_index_done( &string_index ); + + return error; + } + + + FT_LOCAL_DEF( void ) + cff_font_done( CFF_Font font ) + { + FT_Memory memory = font->memory; + FT_UInt idx; + + + cff_index_done( &font->global_subrs_index ); + cff_index_done( &font->font_dict_index ); + cff_index_done( &font->name_index ); + cff_index_done( &font->charstrings_index ); + + /* release font dictionaries, but only if working with */ + /* a CID keyed CFF font */ + if ( font->num_subfonts > 0 ) + { + for ( idx = 0; idx < font->num_subfonts; idx++ ) + cff_subfont_done( memory, font->subfonts[idx] ); + + /* the subfonts array has been allocated as a single block */ + FT_FREE( font->subfonts[0] ); + } + + cff_encoding_done( &font->encoding ); + cff_charset_done( &font->charset, font->stream ); + + cff_subfont_done( memory, &font->top_font ); + + CFF_Done_FD_Select( &font->fd_select, font->stream ); + + FT_FREE( font->font_info ); + + FT_FREE( font->font_name ); + FT_FREE( font->global_subrs ); + FT_FREE( font->strings ); + FT_FREE( font->string_pool ); + + if ( font->cf2_instance.finalizer ) + { + font->cf2_instance.finalizer( font->cf2_instance.data ); + FT_FREE( font->cf2_instance.data ); + } + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cffload.h b/drivers/freetype/src/cff/cffload.h new file mode 100644 index 0000000000..804961964b --- /dev/null +++ b/drivers/freetype/src/cff/cffload.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* cffload.h */ +/* */ +/* OpenType & CFF data/program tables loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2007, 2008, 2010 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 __CFFLOAD_H__ +#define __CFFLOAD_H__ + + +#include <ft2build.h> +#include "cfftypes.h" + + +FT_BEGIN_HEADER + + FT_LOCAL( FT_UShort ) + cff_get_standard_encoding( FT_UInt charcode ); + + + FT_LOCAL( FT_String* ) + cff_index_get_string( CFF_Font font, + FT_UInt element ); + + FT_LOCAL( FT_String* ) + cff_index_get_sid_string( CFF_Font font, + FT_UInt sid ); + + + FT_LOCAL( FT_Error ) + cff_index_access_element( CFF_Index idx, + FT_UInt element, + FT_Byte** pbytes, + FT_ULong* pbyte_len ); + + FT_LOCAL( void ) + cff_index_forget_element( CFF_Index idx, + FT_Byte** pbytes ); + + FT_LOCAL( FT_String* ) + cff_index_get_name( CFF_Font font, + FT_UInt element ); + + + FT_LOCAL( FT_UInt ) + cff_charset_cid_to_gindex( CFF_Charset charset, + FT_UInt cid ); + + + FT_LOCAL( FT_Error ) + cff_font_load( FT_Library library, + FT_Stream stream, + FT_Int face_index, + CFF_Font font, + FT_Bool pure_cff ); + + FT_LOCAL( void ) + cff_font_done( CFF_Font font ); + + + FT_LOCAL( FT_Byte ) + cff_fd_select_get( CFF_FDSelect fdselect, + FT_UInt glyph_index ); + + +FT_END_HEADER + +#endif /* __CFFLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cffobjs.c b/drivers/freetype/src/cff/cffobjs.c new file mode 100644 index 0000000000..dd750d1041 --- /dev/null +++ b/drivers/freetype/src/cff/cffobjs.c @@ -0,0 +1,1077 @@ +/***************************************************************************/ +/* */ +/* cffobjs.c */ +/* */ +/* OpenType objects manager (body). */ +/* */ +/* Copyright 1996-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_ERRORS_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_SFNT_H +#include FT_CFF_DRIVER_H + +#include "cffobjs.h" +#include "cffload.h" +#include "cffcmap.h" +#include "cffpic.h" + +#include "cfferrs.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_cffobjs + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /* Note that we store the global hints in the size's `internal' root */ + /* field. */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + cff_size_get_globals_funcs( CFF_Size size ) + { + CFF_Face face = (CFF_Face)size->root.face; + CFF_Font font = (CFF_Font)face->extra.data; + PSHinter_Service pshinter = font->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->root.face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0; + } + + + FT_LOCAL_DEF( void ) + cff_size_done( FT_Size cffsize ) /* CFF_Size */ + { + CFF_Size size = (CFF_Size)cffsize; + CFF_Face face = (CFF_Face)size->root.face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)cffsize->internal; + + + if ( internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = cff_size_get_globals_funcs( size ); + if ( funcs ) + { + FT_UInt i; + + + funcs->destroy( internal->topfont ); + + for ( i = font->num_subfonts; i > 0; i-- ) + funcs->destroy( internal->subfonts[i - 1] ); + } + + /* `internal' is freed by destroy_size (in ftobjs.c) */ + } + } + + + /* CFF and Type 1 private dictionaries have slightly different */ + /* structures; we need to synthesize a Type 1 dictionary on the fly */ + + static void + cff_make_private_dict( CFF_SubFont subfont, + PS_Private priv ) + { + CFF_Private cpriv = &subfont->private_dict; + FT_UInt n, count; + + + FT_MEM_ZERO( priv, sizeof ( *priv ) ); + + count = priv->num_blue_values = cpriv->num_blue_values; + for ( n = 0; n < count; n++ ) + priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; + + count = priv->num_other_blues = cpriv->num_other_blues; + for ( n = 0; n < count; n++ ) + priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; + + count = priv->num_family_blues = cpriv->num_family_blues; + for ( n = 0; n < count; n++ ) + priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; + + count = priv->num_family_other_blues = cpriv->num_family_other_blues; + for ( n = 0; n < count; n++ ) + priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; + + priv->blue_scale = cpriv->blue_scale; + priv->blue_shift = (FT_Int)cpriv->blue_shift; + priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz; + + priv->standard_width[0] = (FT_UShort)cpriv->standard_width; + priv->standard_height[0] = (FT_UShort)cpriv->standard_height; + + count = priv->num_snap_widths = cpriv->num_snap_widths; + for ( n = 0; n < count; n++ ) + priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; + + count = priv->num_snap_heights = cpriv->num_snap_heights; + for ( n = 0; n < count; n++ ) + priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; + + priv->force_bold = cpriv->force_bold; + priv->language_group = cpriv->language_group; + priv->lenIV = cpriv->lenIV; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_size_init( FT_Size cffsize ) /* CFF_Size */ + { + CFF_Size size = (CFF_Size)cffsize; + FT_Error error = FT_Err_Ok; + PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); + + + if ( funcs ) + { + CFF_Face face = (CFF_Face)cffsize->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = NULL; + + PS_PrivateRec priv; + FT_Memory memory = cffsize->face->memory; + + FT_UInt i; + + + if ( FT_NEW( internal ) ) + goto Exit; + + cff_make_private_dict( &font->top_font, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->topfont ); + if ( error ) + goto Exit; + + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + + + cff_make_private_dict( sub, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->subfonts[i - 1] ); + if ( error ) + goto Exit; + } + + cffsize->internal = (FT_Size_Internal)(void*)internal; + } + + size->strike_index = 0xFFFFFFFFUL; + + Exit: + return error; + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL_DEF( FT_Error ) + cff_size_select( FT_Size size, + FT_ULong strike_index ) + { + CFF_Size cffsize = (CFF_Size)size; + PSH_Globals_Funcs funcs; + + + cffsize->strike_index = strike_index; + + FT_Select_Metrics( size->face, strike_index ); + + funcs = cff_size_get_globals_funcs( cffsize ); + + if ( funcs ) + { + CFF_Face face = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, + 0, 0 ); + + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + + return FT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + FT_LOCAL_DEF( FT_Error ) + cff_size_request( FT_Size size, + FT_Size_Request req ) + { + CFF_Size cffsize = (CFF_Size)size; + PSH_Globals_Funcs funcs; + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + if ( FT_HAS_FIXED_SIZES( size->face ) ) + { + CFF_Face cffface = (CFF_Face)size->face; + SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; + FT_ULong strike_index; + + + if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) ) + cffsize->strike_index = 0xFFFFFFFFUL; + else + return cff_size_select( size, strike_index ); + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + FT_Request_Metrics( size->face, req ); + + funcs = cff_size_get_globals_funcs( cffsize ); + + if ( funcs ) + { + CFF_Face cffface = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)cffface->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, + 0, 0 ); + + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + cff_slot_done( FT_GlyphSlot slot ) + { + slot->internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_slot_init( FT_GlyphSlot slot ) + { + CFF_Face face = (CFF_Face)slot->face; + CFF_Font font = (CFF_Font)face->extra.data; + PSHinter_Service pshinter = font->pshinter; + + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->face->driver->root.library, + "pshinter" ); + if ( module ) + { + T2_Hints_Funcs funcs; + + + funcs = pshinter->get_t2_funcs( module ); + slot->internal->glyph_hints = (void*)funcs; + } + } + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + static FT_String* + cff_strcpy( FT_Memory memory, + const FT_String* source ) + { + FT_Error error; + FT_String* result; + + + (void)FT_STRDUP( result, source ); + + FT_UNUSED( error ); + + return result; + } + + + /* Strip all subset prefixes of the form `ABCDEF+'. Usually, there */ + /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold' */ + /* have been seen in the wild. */ + + static void + remove_subset_prefix( FT_String* name ) + { + FT_Int32 idx = 0; + FT_Int32 length = (FT_Int32)strlen( name ) + 1; + FT_Bool continue_search = 1; + + + while ( continue_search ) + { + if ( length >= 7 && name[6] == '+' ) + { + for ( idx = 0; idx < 6; idx++ ) + { + /* ASCII uppercase letters */ + if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) ) + continue_search = 0; + } + + if ( continue_search ) + { + for ( idx = 7; idx < length; idx++ ) + name[idx - 7] = name[idx]; + length -= 7; + } + } + else + continue_search = 0; + } + } + + + /* Remove the style part from the family name (if present). */ + + static void + remove_style( FT_String* family_name, + const FT_String* style_name ) + { + FT_Int32 family_name_length, style_name_length; + + + family_name_length = (FT_Int32)strlen( family_name ); + style_name_length = (FT_Int32)strlen( style_name ); + + if ( family_name_length > style_name_length ) + { + FT_Int idx; + + + for ( idx = 1; idx <= style_name_length; ++idx ) + { + if ( family_name[family_name_length - idx] != + style_name[style_name_length - idx] ) + break; + } + + if ( idx > style_name_length ) + { + /* family_name ends with style_name; remove it */ + idx = family_name_length - style_name_length - 1; + + /* also remove special characters */ + /* between real family name and style */ + while ( idx > 0 && + ( family_name[idx] == '-' || + family_name[idx] == ' ' || + family_name[idx] == '_' || + family_name[idx] == '+' ) ) + --idx; + + if ( idx > 0 ) + family_name[idx + 1] = '\0'; + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + cff_face_init( FT_Stream stream, + FT_Face cffface, /* CFF_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + CFF_Face face = (CFF_Face)cffface; + FT_Error error; + SFNT_Service sfnt; + FT_Service_PsCMaps psnames; + PSHinter_Service pshinter; + FT_Bool pure_cff = 1; + FT_Bool sfnt_format = 0; + FT_Library library = cffface->driver->root.library; + + + sfnt = (SFNT_Service)FT_Get_Module_Interface( + library, "sfnt" ); + if ( !sfnt ) + { + FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + + pshinter = (PSHinter_Service)FT_Get_Module_Interface( + library, "pshinter" ); + + FT_TRACE2(( "CFF driver\n" )); + + /* create input stream from resource */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + /* check whether we have a valid OpenType file */ + error = sfnt->init_face( stream, face, face_index, num_params, params ); + if ( !error ) + { + if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */ + { + FT_TRACE2(( " not an OpenType/CFF font\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* if we are performing a simple font format check, exit immediately */ + if ( face_index < 0 ) + return FT_Err_Ok; + + sfnt_format = 1; + + /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ + /* font; in the latter case it doesn't have a `head' table */ + error = face->goto_table( face, TTAG_head, stream, 0 ); + if ( !error ) + { + pure_cff = 0; + + /* load font directory */ + error = sfnt->load_face( stream, face, face_index, + num_params, params ); + if ( error ) + goto Exit; + } + else + { + /* load the `cmap' table explicitly */ + error = sfnt->load_cmap( face, stream ); + if ( error ) + goto Exit; + } + + /* now load the CFF part of the file */ + error = face->goto_table( face, TTAG_CFF, stream, 0 ); + if ( error ) + goto Exit; + } + else + { + /* rewind to start of file; we are going to load a pure-CFF font */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + error = FT_Err_Ok; + } + + /* now load and parse the CFF table in the file */ + { + CFF_Font cff = NULL; + CFF_FontRecDict dict; + FT_Memory memory = cffface->memory; + FT_Int32 flags; + FT_UInt i; + + + if ( FT_NEW( cff ) ) + goto Exit; + + face->extra.data = cff; + error = cff_font_load( library, stream, face_index, cff, pure_cff ); + if ( error ) + goto Exit; + + cff->pshinter = pshinter; + cff->psnames = psnames; + + cffface->face_index = face_index; + + /* Complement the root flags with some interesting information. */ + /* Note that this is only necessary for pure CFF and CEF fonts; */ + /* SFNT based fonts use the `name' table instead. */ + + cffface->num_glyphs = cff->num_glyphs; + + dict = &cff->top_font.font_dict; + + /* we need the `PSNames' module for CFF and CEF formats */ + /* which aren't CID-keyed */ + if ( dict->cid_registry == 0xFFFFU && !psnames ) + { + FT_ERROR(( "cff_face_init:" + " cannot open CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt idx; + FT_String* s; + + + FT_TRACE4(( "SIDs\n" )); + + /* dump string index, including default strings for convenience */ + for ( idx = 0; idx < cff->num_strings + 390; idx++ ) + { + s = cff_index_get_sid_string( cff, idx ); + if ( s ) + FT_TRACE4((" %5d %s\n", idx, s )); + } + } +#endif /* FT_DEBUG_LEVEL_TRACE */ + + if ( !dict->has_font_matrix ) + dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; + + /* Normalize the font matrix so that `matrix->xx' is 1; the */ + /* scaling is done with `units_per_em' then (at this point, */ + /* it already contains the scaling factor, but without */ + /* normalization of the matrix). */ + /* */ + /* Note that the offsets must be expressed in integer font */ + /* units. */ + + { + FT_Matrix* matrix = &dict->font_matrix; + FT_Vector* offset = &dict->font_offset; + FT_ULong* upm = &dict->units_per_em; + FT_Fixed temp = FT_ABS( matrix->yy ); + + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + + for ( i = cff->num_subfonts; i > 0; i-- ) + { + CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; + CFF_FontRecDict top = &cff->top_font.font_dict; + + FT_Matrix* matrix; + FT_Vector* offset; + FT_ULong* upm; + FT_Fixed temp; + + + if ( sub->has_font_matrix ) + { + FT_Long scaling; + + + /* if we have a top-level matrix, */ + /* concatenate the subfont matrix */ + + if ( top->has_font_matrix ) + { + if ( top->units_per_em > 1 && sub->units_per_em > 1 ) + scaling = FT_MIN( top->units_per_em, sub->units_per_em ); + else + scaling = 1; + + FT_Matrix_Multiply_Scaled( &top->font_matrix, + &sub->font_matrix, + scaling ); + FT_Vector_Transform_Scaled( &sub->font_offset, + &top->font_matrix, + scaling ); + + sub->units_per_em = FT_MulDiv( sub->units_per_em, + top->units_per_em, + scaling ); + } + } + else + { + sub->font_matrix = top->font_matrix; + sub->font_offset = top->font_offset; + + sub->units_per_em = top->units_per_em; + } + + matrix = &sub->font_matrix; + offset = &sub->font_offset; + upm = &sub->units_per_em; + temp = FT_ABS( matrix->yy ); + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + + if ( pure_cff ) + { + char* style_name = NULL; + + + /* set up num_faces */ + cffface->num_faces = cff->num_faces; + + /* compute number of glyphs */ + if ( dict->cid_registry != 0xFFFFU ) + cffface->num_glyphs = cff->charset.max_cid + 1; + else + cffface->num_glyphs = cff->charstrings_index.count; + + /* set global bbox, as well as EM size */ + cffface->bbox.xMin = dict->font_bbox.xMin >> 16; + cffface->bbox.yMin = dict->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16; + cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16; + + cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); + + cffface->ascender = (FT_Short)( cffface->bbox.yMax ); + cffface->descender = (FT_Short)( cffface->bbox.yMin ); + + cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 ); + if ( cffface->height < cffface->ascender - cffface->descender ) + cffface->height = (FT_Short)( cffface->ascender - cffface->descender ); + + cffface->underline_position = + (FT_Short)( dict->underline_position >> 16 ); + cffface->underline_thickness = + (FT_Short)( dict->underline_thickness >> 16 ); + + /* retrieve font family & style name */ + cffface->family_name = cff_index_get_name( cff, face_index ); + if ( cffface->family_name ) + { + char* full = cff_index_get_sid_string( cff, + dict->full_name ); + char* fullp = full; + char* family = cffface->family_name; + char* family_name = NULL; + + + remove_subset_prefix( cffface->family_name ); + + if ( dict->family_name ) + { + family_name = cff_index_get_sid_string( cff, + dict->family_name ); + if ( family_name ) + family = family_name; + } + + /* We try to extract the style name from the full name. */ + /* We need to ignore spaces and dashes during the search. */ + if ( full && family ) + { + while ( *fullp ) + { + /* skip common characters at the start of both strings */ + if ( *fullp == *family ) + { + family++; + fullp++; + continue; + } + + /* ignore spaces and dashes in full name during comparison */ + if ( *fullp == ' ' || *fullp == '-' ) + { + fullp++; + continue; + } + + /* ignore spaces and dashes in family name during comparison */ + if ( *family == ' ' || *family == '-' ) + { + family++; + continue; + } + + if ( !*family && *fullp ) + { + /* The full name begins with the same characters as the */ + /* family name, with spaces and dashes removed. In this */ + /* case, the remaining string in `fullp' will be used as */ + /* the style name. */ + style_name = cff_strcpy( memory, fullp ); + + /* remove the style part from the family name (if present) */ + remove_style( cffface->family_name, style_name ); + } + break; + } + } + } + else + { + char *cid_font_name = + cff_index_get_sid_string( cff, + dict->cid_font_name ); + + + /* do we have a `/FontName' for a CID-keyed font? */ + if ( cid_font_name ) + cffface->family_name = cff_strcpy( memory, cid_font_name ); + } + + if ( style_name ) + cffface->style_name = style_name; + else + /* assume "Regular" style if we don't know better */ + cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); + + /*******************************************************************/ + /* */ + /* Compute face flags. */ + /* */ + flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER; /* has native hinter */ + + if ( sfnt_format ) + flags |= FT_FACE_FLAG_SFNT; + + /* fixed width font? */ + if ( dict->is_fixed_pitch ) + flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ +#if 0 + /* kerning available? */ + if ( face->kern_pairs ) + flags |= FT_FACE_FLAG_KERNING; +#endif + + cffface->face_flags = flags; + + /*******************************************************************/ + /* */ + /* Compute style flags. */ + /* */ + flags = 0; + + if ( dict->italic_angle ) + flags |= FT_STYLE_FLAG_ITALIC; + + { + char *weight = cff_index_get_sid_string( cff, + dict->weight ); + + + if ( weight ) + if ( !ft_strcmp( weight, "Bold" ) || + !ft_strcmp( weight, "Black" ) ) + flags |= FT_STYLE_FLAG_BOLD; + } + + /* double check */ + if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name ) + if ( !ft_strncmp( cffface->style_name, "Bold", 4 ) || + !ft_strncmp( cffface->style_name, "Black", 5 ) ) + flags |= FT_STYLE_FLAG_BOLD; + + cffface->style_flags = flags; + } + + +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ + /* has unset this flag because of the 3.0 `post' table. */ + if ( dict->cid_registry == 0xFFFFU ) + cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; +#endif + + if ( dict->cid_registry != 0xFFFFU && pure_cff ) + cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; + + + /*******************************************************************/ + /* */ + /* Compute char maps. */ + /* */ + + /* Try to synthesize a Unicode charmap if there is none available */ + /* already. If an OpenType font contains a Unicode "cmap", we */ + /* will use it, whatever be in the CFF part of the file. */ + { + FT_CharMapRec cmaprec; + FT_CharMap cmap; + FT_UInt nn; + CFF_Encoding encoding = &cff->encoding; + + + for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ ) + { + cmap = cffface->charmaps[nn]; + + /* Windows Unicode? */ + if ( cmap->platform_id == TT_PLATFORM_MICROSOFT && + cmap->encoding_id == TT_MS_ID_UNICODE_CS ) + goto Skip_Unicode; + + /* Apple Unicode platform id? */ + if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE ) + goto Skip_Unicode; /* Apple Unicode */ + } + + /* since CID-keyed fonts don't contain glyph names, we can't */ + /* construct a cmap */ + if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) + goto Exit; + +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE ) + { + FT_ERROR(( "cff_face_init: no Unicode cmap is found, " + "and too many subtables (%d) to add synthesized cmap\n", + nn )); + goto Exit; + } +#endif + + /* we didn't find a Unicode charmap -- synthesize one */ + cmaprec.face = cffface; + cmaprec.platform_id = TT_PLATFORM_MICROSOFT; + cmaprec.encoding_id = TT_MS_ID_UNICODE_CS; + cmaprec.encoding = FT_ENCODING_UNICODE; + + nn = (FT_UInt)cffface->num_charmaps; + + error = FT_CMap_New( &CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, + &cmaprec, NULL ); + if ( error && + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + goto Exit; + error = FT_Err_Ok; + + /* if no Unicode charmap was previously selected, select this one */ + if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) + cffface->charmap = cffface->charmaps[nn]; + + Skip_Unicode: +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( nn > FT_MAX_CHARMAP_CACHEABLE ) + { + FT_ERROR(( "cff_face_init: Unicode cmap is found, " + "but too many preceding subtables (%d) to access\n", + nn - 1 )); + goto Exit; + } +#endif + if ( encoding->count > 0 ) + { + FT_CMap_Class clazz; + + + cmaprec.face = cffface; + cmaprec.platform_id = TT_PLATFORM_ADOBE; /* Adobe platform id */ + + if ( encoding->offset == 0 ) + { + cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; + cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; + clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; + } + else if ( encoding->offset == 1 ) + { + cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; + cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; + clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; + } + else + { + cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; + cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; + clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; + } + + error = FT_CMap_New( clazz, NULL, &cmaprec, NULL ); + } + } + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cff_face_done( FT_Face cffface ) /* CFF_Face */ + { + CFF_Face face = (CFF_Face)cffface; + FT_Memory memory; + SFNT_Service sfnt; + + + if ( !face ) + return; + + memory = cffface->memory; + sfnt = (SFNT_Service)face->sfnt; + + if ( sfnt ) + sfnt->done_face( face ); + + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + if ( cff ) + { + cff_font_done( cff ); + FT_FREE( face->extra.data ); + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + cff_driver_init( FT_Module module ) /* CFF_Driver */ + { + CFF_Driver driver = (CFF_Driver)module; + + + /* set default property values */ +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + driver->hinting_engine = FT_CFF_HINTING_FREETYPE; +#else + driver->hinting_engine = FT_CFF_HINTING_ADOBE; +#endif + driver->no_stem_darkening = FALSE; + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( void ) + cff_driver_done( FT_Module module ) /* CFF_Driver */ + { + FT_UNUSED( module ); + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cffobjs.h b/drivers/freetype/src/cff/cffobjs.h new file mode 100644 index 0000000000..b375c20c74 --- /dev/null +++ b/drivers/freetype/src/cff/cffobjs.h @@ -0,0 +1,183 @@ +/***************************************************************************/ +/* */ +/* cffobjs.h */ +/* */ +/* OpenType objects manager (specification). */ +/* */ +/* Copyright 1996-2004, 2006-2008, 2013 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 __CFFOBJS_H__ +#define __CFFOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "cfftypes.h" +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Driver */ + /* */ + /* <Description> */ + /* A handle to an OpenType driver object. */ + /* */ + typedef struct CFF_DriverRec_* CFF_Driver; + + typedef TT_Face CFF_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Size */ + /* */ + /* <Description> */ + /* A handle to an OpenType size object. */ + /* */ + typedef struct CFF_SizeRec_ + { + FT_SizeRec root; + FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ + + } CFF_SizeRec, *CFF_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to an OpenType glyph slot object. */ + /* */ + typedef struct CFF_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } CFF_GlyphSlotRec, *CFF_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Internal */ + /* */ + /* <Description> */ + /* The interface to the `internal' field of `FT_Size'. */ + /* */ + typedef struct CFF_InternalRec_ + { + PSH_Globals topfont; + PSH_Globals subfonts[CFF_MAX_CID_FONTS]; + + } CFF_InternalRec, *CFF_Internal; + + + /*************************************************************************/ + /* */ + /* Subglyph transformation record. */ + /* */ + typedef struct CFF_Transform_ + { + FT_Fixed xx, xy; /* transformation matrix coefficients */ + FT_Fixed yx, yy; + FT_F26Dot6 ox, oy; /* offsets */ + + } CFF_Transform; + + + /***********************************************************************/ + /* */ + /* CFF driver class. */ + /* */ + typedef struct CFF_DriverRec_ + { + FT_DriverRec root; + + FT_UInt hinting_engine; + FT_Bool no_stem_darkening; + + } CFF_DriverRec; + + + FT_LOCAL( FT_Error ) + cff_size_init( FT_Size size ); /* CFF_Size */ + + FT_LOCAL( void ) + cff_size_done( FT_Size size ); /* CFF_Size */ + + FT_LOCAL( FT_Error ) + cff_size_request( FT_Size size, + FT_Size_Request req ); + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL( FT_Error ) + cff_size_select( FT_Size size, + FT_ULong strike_index ); + +#endif + + FT_LOCAL( void ) + cff_slot_done( FT_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + cff_slot_init( FT_GlyphSlot slot ); + + + /*************************************************************************/ + /* */ + /* Face functions */ + /* */ + FT_LOCAL( FT_Error ) + cff_face_init( FT_Stream stream, + FT_Face face, /* CFF_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + cff_face_done( FT_Face face ); /* CFF_Face */ + + + /*************************************************************************/ + /* */ + /* Driver functions */ + /* */ + FT_LOCAL( FT_Error ) + cff_driver_init( FT_Module module ); /* CFF_Driver */ + + FT_LOCAL( void ) + cff_driver_done( FT_Module module ); /* CFF_Driver */ + + +FT_END_HEADER + +#endif /* __CFFOBJS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cffparse.c b/drivers/freetype/src/cff/cffparse.c new file mode 100644 index 0000000000..96222120b0 --- /dev/null +++ b/drivers/freetype/src/cff/cffparse.c @@ -0,0 +1,1177 @@ +/***************************************************************************/ +/* */ +/* cffparse.c */ +/* */ +/* CFF token stream parser (body) */ +/* */ +/* Copyright 1996-2004, 2007-2013 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 "cffparse.h" +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H + +#include "cfferrs.h" +#include "cffpic.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_cffparse + + + FT_LOCAL_DEF( void ) + cff_parser_init( CFF_Parser parser, + FT_UInt code, + void* object, + FT_Library library) + { + FT_MEM_ZERO( parser, sizeof ( *parser ) ); + + parser->top = parser->stack; + parser->object_code = code; + parser->object = object; + parser->library = library; + } + + + /* read an integer */ + static FT_Long + cff_parse_integer( FT_Byte* start, + FT_Byte* limit ) + { + FT_Byte* p = start; + FT_Int v = *p++; + FT_Long val = 0; + + + if ( v == 28 ) + { + if ( p + 2 > limit ) + goto Bad; + + val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] ); + p += 2; + } + else if ( v == 29 ) + { + if ( p + 4 > limit ) + goto Bad; + + val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) | + ( (FT_ULong)p[1] << 16 ) | + ( (FT_ULong)p[2] << 8 ) | + (FT_ULong)p[3] ); + p += 4; + } + else if ( v < 247 ) + { + val = v - 139; + } + else if ( v < 251 ) + { + if ( p + 1 > limit ) + goto Bad; + + val = ( v - 247 ) * 256 + p[0] + 108; + p++; + } + else + { + if ( p + 1 > limit ) + goto Bad; + + val = -( v - 251 ) * 256 - p[0] - 108; + p++; + } + + Exit: + return val; + + Bad: + val = 0; + FT_TRACE4(( "!!!END OF DATA:!!!" )); + goto Exit; + } + + + static const FT_Long power_tens[] = + { + 1L, + 10L, + 100L, + 1000L, + 10000L, + 100000L, + 1000000L, + 10000000L, + 100000000L, + 1000000000L + }; + + + /* read a real */ + static FT_Fixed + cff_parse_real( FT_Byte* start, + FT_Byte* limit, + FT_Long power_ten, + FT_Long* scaling ) + { + FT_Byte* p = start; + FT_UInt nib; + FT_UInt phase; + + FT_Long result, number, exponent; + FT_Int sign = 0, exponent_sign = 0, have_overflow = 0; + FT_Long exponent_add, integer_length, fraction_length; + + + if ( scaling ) + *scaling = 0; + + result = 0; + + number = 0; + exponent = 0; + + exponent_add = 0; + integer_length = 0; + fraction_length = 0; + + /* First of all, read the integer part. */ + phase = 4; + + for (;;) + { + /* If we entered this iteration with phase == 4, we need to */ + /* read a new byte. This also skips past the initial 0x1E. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Bad; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + + if ( nib == 0xE ) + sign = 1; + else if ( nib > 9 ) + break; + else + { + /* Increase exponent if we can't add the digit. */ + if ( number >= 0xCCCCCCCL ) + exponent_add++; + /* Skip leading zeros. */ + else if ( nib || number ) + { + integer_length++; + number = number * 10 + nib; + } + } + } + + /* Read fraction part, if any. */ + if ( nib == 0xa ) + for (;;) + { + /* If we entered this iteration with phase == 4, we need */ + /* to read a new byte. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Bad; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + if ( nib >= 10 ) + break; + + /* Skip leading zeros if possible. */ + if ( !nib && !number ) + exponent_add--; + /* Only add digit if we don't overflow. */ + else if ( number < 0xCCCCCCCL && fraction_length < 9 ) + { + fraction_length++; + number = number * 10 + nib; + } + } + + /* Read exponent, if any. */ + if ( nib == 12 ) + { + exponent_sign = 1; + nib = 11; + } + + if ( nib == 11 ) + { + for (;;) + { + /* If we entered this iteration with phase == 4, */ + /* we need to read a new byte. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Bad; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + if ( nib >= 10 ) + break; + + /* Arbitrarily limit exponent. */ + if ( exponent > 1000 ) + have_overflow = 1; + else + exponent = exponent * 10 + nib; + } + + if ( exponent_sign ) + exponent = -exponent; + } + + if ( !number ) + goto Exit; + + if ( have_overflow ) + { + if ( exponent_sign ) + goto Underflow; + else + goto Overflow; + } + + /* We don't check `power_ten' and `exponent_add'. */ + exponent += power_ten + exponent_add; + + if ( scaling ) + { + /* Only use `fraction_length'. */ + fraction_length += integer_length; + exponent += integer_length; + + if ( fraction_length <= 5 ) + { + if ( number > 0x7FFFL ) + { + result = FT_DivFix( number, 10 ); + *scaling = exponent - fraction_length + 1; + } + else + { + if ( exponent > 0 ) + { + FT_Long new_fraction_length, shift; + + + /* Make `scaling' as small as possible. */ + new_fraction_length = FT_MIN( exponent, 5 ); + shift = new_fraction_length - fraction_length; + + if ( shift > 0 ) + { + exponent -= new_fraction_length; + number *= power_tens[shift]; + if ( number > 0x7FFFL ) + { + number /= 10; + exponent += 1; + } + } + else + exponent -= fraction_length; + } + else + exponent -= fraction_length; + + result = (FT_Long)( (FT_ULong)number << 16 ); + *scaling = exponent; + } + } + else + { + if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL ) + { + result = FT_DivFix( number, power_tens[fraction_length - 4] ); + *scaling = exponent - 4; + } + else + { + result = FT_DivFix( number, power_tens[fraction_length - 5] ); + *scaling = exponent - 5; + } + } + } + else + { + integer_length += exponent; + fraction_length -= exponent; + + if ( integer_length > 5 ) + goto Overflow; + if ( integer_length < -5 ) + goto Underflow; + + /* Remove non-significant digits. */ + if ( integer_length < 0 ) + { + number /= power_tens[-integer_length]; + fraction_length += integer_length; + } + + /* this can only happen if exponent was non-zero */ + if ( fraction_length == 10 ) + { + number /= 10; + fraction_length -= 1; + } + + /* Convert into 16.16 format. */ + if ( fraction_length > 0 ) + { + if ( ( number / power_tens[fraction_length] ) > 0x7FFFL ) + goto Exit; + + result = FT_DivFix( number, power_tens[fraction_length] ); + } + else + { + number *= power_tens[-fraction_length]; + + if ( number > 0x7FFFL ) + goto Overflow; + + result = (FT_Long)( (FT_ULong)number << 16 ); + } + } + + Exit: + if ( sign ) + result = -result; + + return result; + + Overflow: + result = 0x7FFFFFFFL; + FT_TRACE4(( "!!!OVERFLOW:!!!" )); + goto Exit; + + Underflow: + result = 0; + FT_TRACE4(( "!!!UNDERFLOW:!!!" )); + goto Exit; + + Bad: + result = 0; + FT_TRACE4(( "!!!END OF DATA:!!!" )); + goto Exit; + } + + + /* read a number, either integer or real */ + static FT_Long + cff_parse_num( FT_Byte** d ) + { + return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) + : cff_parse_integer( d[0], d[1] ); + } + + + /* read a floating point number, either integer or real */ + static FT_Fixed + do_fixed( FT_Byte** d, + FT_Long scaling ) + { + if ( **d == 30 ) + return cff_parse_real( d[0], d[1], scaling, NULL ); + else + { + FT_Long val = cff_parse_integer( d[0], d[1] ); + + + if ( scaling ) + val *= power_tens[scaling]; + + if ( val > 0x7FFF ) + { + val = 0x7FFFFFFFL; + goto Overflow; + } + else if ( val < -0x7FFF ) + { + val = -0x7FFFFFFFL; + goto Overflow; + } + + return (FT_Long)( (FT_ULong)val << 16 ); + + Overflow: + FT_TRACE4(( "!!!OVERFLOW:!!!" )); + return val; + } + } + + + /* read a floating point number, either integer or real */ + static FT_Fixed + cff_parse_fixed( FT_Byte** d ) + { + return do_fixed( d, 0 ); + } + + + /* read a floating point number, either integer or real, */ + /* but return `10^scaling' times the number read in */ + static FT_Fixed + cff_parse_fixed_scaled( FT_Byte** d, + FT_Long scaling ) + { + return do_fixed( d, scaling ); + } + + + /* read a floating point number, either integer or real, */ + /* and return it as precise as possible -- `scaling' returns */ + /* the scaling factor (as a power of 10) */ + static FT_Fixed + cff_parse_fixed_dynamic( FT_Byte** d, + FT_Long* scaling ) + { + FT_ASSERT( scaling ); + + if ( **d == 30 ) + return cff_parse_real( d[0], d[1], 0, scaling ); + else + { + FT_Long number; + FT_Int integer_length; + + + number = cff_parse_integer( d[0], d[1] ); + + if ( number > 0x7FFFL ) + { + for ( integer_length = 5; integer_length < 10; integer_length++ ) + if ( number < power_tens[integer_length] ) + break; + + if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL ) + { + *scaling = integer_length - 4; + return FT_DivFix( number, power_tens[integer_length - 4] ); + } + else + { + *scaling = integer_length - 5; + return FT_DivFix( number, power_tens[integer_length - 5] ); + } + } + else + { + *scaling = 0; + return (FT_Long)( (FT_ULong)number << 16 ); + } + } + } + + + static FT_Error + cff_parse_font_matrix( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Matrix* matrix = &dict->font_matrix; + FT_Vector* offset = &dict->font_offset; + FT_ULong* upm = &dict->units_per_em; + FT_Byte** data = parser->stack; + FT_Error error = FT_ERR( Stack_Underflow ); + + + if ( parser->top >= parser->stack + 6 ) + { + FT_Long scaling; + + + error = FT_Err_Ok; + + dict->has_font_matrix = TRUE; + + /* We expect a well-formed font matrix, this is, the matrix elements */ + /* `xx' and `yy' are of approximately the same magnitude. To avoid */ + /* loss of precision, we use the magnitude of element `xx' to scale */ + /* all other elements. The scaling factor is then contained in the */ + /* `units_per_em' value. */ + + matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + + scaling = -scaling; + + if ( scaling < 0 || scaling > 9 ) + { + /* Return default matrix in case of unlikely values. */ + + FT_TRACE1(( "cff_parse_font_matrix:" + " strange scaling value for xx element (%d),\n" + " " + " using default matrix\n", scaling )); + + matrix->xx = 0x10000L; + matrix->yx = 0; + matrix->xy = 0; + matrix->yy = 0x10000L; + offset->x = 0; + offset->y = 0; + *upm = 1; + + goto Exit; + } + + matrix->yx = cff_parse_fixed_scaled( data++, scaling ); + matrix->xy = cff_parse_fixed_scaled( data++, scaling ); + matrix->yy = cff_parse_fixed_scaled( data++, scaling ); + offset->x = cff_parse_fixed_scaled( data++, scaling ); + offset->y = cff_parse_fixed_scaled( data, scaling ); + + *upm = power_tens[scaling]; + + FT_TRACE4(( " [%f %f %f %f %f %f]\n", + (double)matrix->xx / *upm / 65536, + (double)matrix->xy / *upm / 65536, + (double)matrix->yx / *upm / 65536, + (double)matrix->yy / *upm / 65536, + (double)offset->x / *upm / 65536, + (double)offset->y / *upm / 65536 )); + } + + Exit: + return error; + } + + + static FT_Error + cff_parse_font_bbox( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_BBox* bbox = &dict->font_bbox; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = FT_ERR( Stack_Underflow ); + + if ( parser->top >= parser->stack + 4 ) + { + bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) ); + error = FT_Err_Ok; + + FT_TRACE4(( " [%d %d %d %d]\n", + bbox->xMin / 65536, + bbox->yMin / 65536, + bbox->xMax / 65536, + bbox->yMax / 65536 )); + } + + return error; + } + + + static FT_Error + cff_parse_private_dict( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = FT_ERR( Stack_Underflow ); + + if ( parser->top >= parser->stack + 2 ) + { + dict->private_size = cff_parse_num( data++ ); + dict->private_offset = cff_parse_num( data ); + FT_TRACE4(( " %lu %lu\n", + dict->private_size, dict->private_offset )); + + error = FT_Err_Ok; + } + + return error; + } + + + static FT_Error + cff_parse_cid_ros( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = FT_ERR( Stack_Underflow ); + + if ( parser->top >= parser->stack + 3 ) + { + dict->cid_registry = (FT_UInt)cff_parse_num( data++ ); + dict->cid_ordering = (FT_UInt)cff_parse_num( data++ ); + if ( **data == 30 ) + FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); + dict->cid_supplement = cff_parse_num( data ); + if ( dict->cid_supplement < 0 ) + FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", + dict->cid_supplement )); + error = FT_Err_Ok; + + FT_TRACE4(( " %d %d %d\n", + dict->cid_registry, + dict->cid_ordering, + dict->cid_supplement )); + } + + return error; + } + + +#define CFF_FIELD_NUM( code, name, id ) \ + CFF_FIELD( code, name, id, cff_kind_num ) +#define CFF_FIELD_FIXED( code, name, id ) \ + CFF_FIELD( code, name, id, cff_kind_fixed ) +#define CFF_FIELD_FIXED_1000( code, name, id ) \ + CFF_FIELD( code, name, id, cff_kind_fixed_thousand ) +#define CFF_FIELD_STRING( code, name, id ) \ + CFF_FIELD( code, name, id, cff_kind_string ) +#define CFF_FIELD_BOOL( code, name, id ) \ + CFF_FIELD( code, name, id, cff_kind_bool ) + +#define CFFCODE_TOPDICT 0x1000 +#define CFFCODE_PRIVATE 0x2000 + + +#ifndef FT_CONFIG_OPTION_PIC + + +#undef CFF_FIELD +#undef CFF_FIELD_DELTA + + +#ifndef FT_DEBUG_LEVEL_TRACE + + +#define CFF_FIELD_CALLBACK( code, name, id ) \ + { \ + cff_kind_callback, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_ ## name, \ + 0, 0 \ + }, + +#define CFF_FIELD( code, name, id, kind ) \ + { \ + kind, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE( name ), \ + 0, 0, 0 \ + }, + +#define CFF_FIELD_DELTA( code, name, max, id ) \ + { \ + cff_kind_delta, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE_DELTA( name ), \ + 0, \ + max, \ + FT_FIELD_OFFSET( num_ ## name ) \ + }, + + static const CFF_Field_Handler cff_field_handlers[] = + { + +#include "cfftoken.h" + + { 0, 0, 0, 0, 0, 0, 0 } + }; + + +#else /* FT_DEBUG_LEVEL_TRACE */ + + + +#define CFF_FIELD_CALLBACK( code, name, id ) \ + { \ + cff_kind_callback, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_ ## name, \ + 0, 0, \ + id \ + }, + +#define CFF_FIELD( code, name, id, kind ) \ + { \ + kind, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE( name ), \ + 0, 0, 0, \ + id \ + }, + +#define CFF_FIELD_DELTA( code, name, max, id ) \ + { \ + cff_kind_delta, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE_DELTA( name ), \ + 0, \ + max, \ + FT_FIELD_OFFSET( num_ ## name ), \ + id \ + }, + + static const CFF_Field_Handler cff_field_handlers[] = + { + +#include "cfftoken.h" + + { 0, 0, 0, 0, 0, 0, 0, 0 } + }; + + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + +#else /* FT_CONFIG_OPTION_PIC */ + + + void + FT_Destroy_Class_cff_field_handlers( FT_Library library, + CFF_Field_Handler* clazz ) + { + FT_Memory memory = library->memory; + + + if ( clazz ) + FT_FREE( clazz ); + } + + + FT_Error + FT_Create_Class_cff_field_handlers( FT_Library library, + CFF_Field_Handler** output_class ) + { + CFF_Field_Handler* clazz = NULL; + FT_Error error; + FT_Memory memory = library->memory; + + int i = 0; + + +#undef CFF_FIELD +#define CFF_FIELD( code, name, id, kind ) i++; +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code, name, max, id ) i++; +#undef CFF_FIELD_CALLBACK +#define CFF_FIELD_CALLBACK( code, name, id ) i++; + +#include "cfftoken.h" + + i++; /* { 0, 0, 0, 0, 0, 0, 0 } */ + + if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) ) + return error; + + i = 0; + + +#ifndef FT_DEBUG_LEVEL_TRACE + + +#undef CFF_FIELD_CALLBACK +#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \ + clazz[i].kind = cff_kind_callback; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = 0; \ + clazz[i].size = 0; \ + clazz[i].reader = cff_parse_ ## name_; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; + +#undef CFF_FIELD +#define CFF_FIELD( code_, name_, id_, kind_ ) \ + clazz[i].kind = kind_; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; \ + +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \ + clazz[i].kind = cff_kind_delta; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = max_; \ + clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ + i++; + +#include "cfftoken.h" + + clazz[i].kind = 0; + clazz[i].code = 0; + clazz[i].offset = 0; + clazz[i].size = 0; + clazz[i].reader = 0; + clazz[i].array_max = 0; + clazz[i].count_offset = 0; + + +#else /* FT_DEBUG_LEVEL_TRACE */ + + +#undef CFF_FIELD_CALLBACK +#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \ + clazz[i].kind = cff_kind_callback; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = 0; \ + clazz[i].size = 0; \ + clazz[i].reader = cff_parse_ ## name_; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + clazz[i].id = id_; \ + i++; + +#undef CFF_FIELD +#define CFF_FIELD( code_, name_, id_, kind_ ) \ + clazz[i].kind = kind_; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + clazz[i].id = id_; \ + i++; \ + +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \ + clazz[i].kind = cff_kind_delta; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = max_; \ + clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ + clazz[i].id = id_; \ + i++; + +#include "cfftoken.h" + + clazz[i].kind = 0; + clazz[i].code = 0; + clazz[i].offset = 0; + clazz[i].size = 0; + clazz[i].reader = 0; + clazz[i].array_max = 0; + clazz[i].count_offset = 0; + clazz[i].id = 0; + + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + *output_class = clazz; + + return FT_Err_Ok; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + + FT_LOCAL_DEF( FT_Error ) + cff_parser_run( CFF_Parser parser, + FT_Byte* start, + FT_Byte* limit ) + { + FT_Byte* p = start; + FT_Error error = FT_Err_Ok; + FT_Library library = parser->library; + FT_UNUSED( library ); + + + parser->top = parser->stack; + parser->start = start; + parser->limit = limit; + parser->cursor = start; + + while ( p < limit ) + { + FT_UInt v = *p; + + + if ( v >= 27 && v != 31 ) + { + /* it's a number; we will push its position on the stack */ + if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + goto Stack_Overflow; + + *parser->top ++ = p; + + /* now, skip it */ + if ( v == 30 ) + { + /* skip real number */ + p++; + for (;;) + { + /* An unterminated floating point number at the */ + /* end of a dictionary is invalid but harmless. */ + if ( p >= limit ) + goto Exit; + v = p[0] >> 4; + if ( v == 15 ) + break; + v = p[0] & 0xF; + if ( v == 15 ) + break; + p++; + } + } + else if ( v == 28 ) + p += 2; + else if ( v == 29 ) + p += 4; + else if ( v > 246 ) + p += 1; + } + else + { + /* This is not a number, hence it's an operator. Compute its code */ + /* and look for it in our current list. */ + + FT_UInt code; + FT_UInt num_args = (FT_UInt) + ( parser->top - parser->stack ); + const CFF_Field_Handler* field; + + + *parser->top = p; + code = v; + if ( v == 12 ) + { + /* two byte operator */ + p++; + if ( p >= limit ) + goto Syntax_Error; + + code = 0x100 | p[0]; + } + code = code | parser->object_code; + + for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ ) + { + if ( field->code == (FT_Int)code ) + { + /* we found our field's handler; read it */ + FT_Long val; + FT_Byte* q = (FT_Byte*)parser->object + field->offset; + + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " %s", field->id )); +#endif + + /* check that we have enough arguments -- except for */ + /* delta encoded arrays, which can be empty */ + if ( field->kind != cff_kind_delta && num_args < 1 ) + goto Stack_Underflow; + + switch ( field->kind ) + { + case cff_kind_bool: + case cff_kind_string: + case cff_kind_num: + val = cff_parse_num( parser->stack ); + goto Store_Number; + + case cff_kind_fixed: + val = cff_parse_fixed( parser->stack ); + goto Store_Number; + + case cff_kind_fixed_thousand: + val = cff_parse_fixed_scaled( parser->stack, 3 ); + + Store_Number: + switch ( field->size ) + { + case (8 / FT_CHAR_BIT): + *(FT_Byte*)q = (FT_Byte)val; + break; + + case (16 / FT_CHAR_BIT): + *(FT_Short*)q = (FT_Short)val; + break; + + case (32 / FT_CHAR_BIT): + *(FT_Int32*)q = (FT_Int)val; + break; + + default: /* for 64-bit systems */ + *(FT_Long*)q = val; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + switch ( field->kind ) + { + case cff_kind_bool: + FT_TRACE4(( " %s\n", val ? "true" : "false" )); + break; + + case cff_kind_string: + FT_TRACE4(( " %ld (SID)\n", val )); + break; + + case cff_kind_num: + FT_TRACE4(( " %ld\n", val )); + break; + + case cff_kind_fixed: + FT_TRACE4(( " %f\n", (double)val / 65536 )); + break; + + case cff_kind_fixed_thousand: + FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 )); + + default: + ; /* never reached */ + } +#endif + + break; + + case cff_kind_delta: + { + FT_Byte* qcount = (FT_Byte*)parser->object + + field->count_offset; + + FT_Byte** data = parser->stack; + + + if ( num_args > field->array_max ) + num_args = field->array_max; + + FT_TRACE4(( " [" )); + + /* store count */ + *qcount = (FT_Byte)num_args; + + val = 0; + while ( num_args > 0 ) + { + val += cff_parse_num( data++ ); + switch ( field->size ) + { + case (8 / FT_CHAR_BIT): + *(FT_Byte*)q = (FT_Byte)val; + break; + + case (16 / FT_CHAR_BIT): + *(FT_Short*)q = (FT_Short)val; + break; + + case (32 / FT_CHAR_BIT): + *(FT_Int32*)q = (FT_Int)val; + break; + + default: /* for 64-bit systems */ + *(FT_Long*)q = val; + } + + FT_TRACE4(( " %ld", val )); + + q += field->size; + num_args--; + } + + FT_TRACE4(( "]\n" )); + } + break; + + default: /* callback */ + error = field->reader( parser ); + if ( error ) + goto Exit; + } + goto Found; + } + } + + /* this is an unknown operator, or it is unsupported; */ + /* we will ignore it for now. */ + + Found: + /* clear stack */ + parser->top = parser->stack; + } + p++; + } + + Exit: + return error; + + Stack_Overflow: + error = FT_THROW( Invalid_Argument ); + goto Exit; + + Stack_Underflow: + error = FT_THROW( Invalid_Argument ); + goto Exit; + + Syntax_Error: + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + +/* END */ diff --git a/drivers/freetype/src/cff/cffparse.h b/drivers/freetype/src/cff/cffparse.h new file mode 100644 index 0000000000..61d91ed2e2 --- /dev/null +++ b/drivers/freetype/src/cff/cffparse.h @@ -0,0 +1,106 @@ +/***************************************************************************/ +/* */ +/* cffparse.h */ +/* */ +/* CFF token stream parser (specification) */ +/* */ +/* Copyright 1996-2003, 2011 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 __CFF_PARSE_H__ +#define __CFF_PARSE_H__ + + +#include <ft2build.h> +#include "cfftypes.h" +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + +#define CFF_MAX_STACK_DEPTH 96 + +#define CFF_CODE_TOPDICT 0x1000 +#define CFF_CODE_PRIVATE 0x2000 + + + typedef struct CFF_ParserRec_ + { + FT_Library library; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* cursor; + + FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; + FT_Byte** top; + + FT_UInt object_code; + void* object; + + } CFF_ParserRec, *CFF_Parser; + + + FT_LOCAL( void ) + cff_parser_init( CFF_Parser parser, + FT_UInt code, + void* object, + FT_Library library); + + FT_LOCAL( FT_Error ) + cff_parser_run( CFF_Parser parser, + FT_Byte* start, + FT_Byte* limit ); + + + enum + { + cff_kind_none = 0, + cff_kind_num, + cff_kind_fixed, + cff_kind_fixed_thousand, + cff_kind_string, + cff_kind_bool, + cff_kind_delta, + cff_kind_callback, + + cff_kind_max /* do not remove */ + }; + + + /* now generate handlers for the most simple fields */ + typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); + + typedef struct CFF_Field_Handler_ + { + int kind; + int code; + FT_UInt offset; + FT_Byte size; + CFF_Field_Reader reader; + FT_UInt array_max; + FT_UInt count_offset; + +#ifdef FT_DEBUG_LEVEL_TRACE + const char* id; +#endif + + } CFF_Field_Handler; + + +FT_END_HEADER + + +#endif /* __CFF_PARSE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cffpic.c b/drivers/freetype/src/cff/cffpic.c new file mode 100644 index 0000000000..f22e4f0d53 --- /dev/null +++ b/drivers/freetype/src/cff/cffpic.c @@ -0,0 +1,138 @@ +/***************************************************************************/ +/* */ +/* cffpic.c */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009, 2010, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "cffcmap.h" +#include "cffpic.h" +#include "cfferrs.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from cffdrivr.c */ + FT_Error + FT_Create_Class_cff_services( FT_Library library, + FT_ServiceDescRec** output_class ); + void + FT_Destroy_Class_cff_services( FT_Library library, + FT_ServiceDescRec* clazz ); + void + FT_Init_Class_cff_service_ps_info( FT_Library library, + FT_Service_PsInfoRec* clazz ); + void + FT_Init_Class_cff_service_glyph_dict( FT_Library library, + FT_Service_GlyphDictRec* clazz ); + void + FT_Init_Class_cff_service_ps_name( FT_Library library, + FT_Service_PsFontNameRec* clazz ); + void + FT_Init_Class_cff_service_get_cmap_info( FT_Library library, + FT_Service_TTCMapsRec* clazz ); + void + FT_Init_Class_cff_service_cid_info( FT_Library library, + FT_Service_CIDRec* clazz ); + + /* forward declaration of PIC init functions from cffparse.c */ + FT_Error + FT_Create_Class_cff_field_handlers( FT_Library library, + CFF_Field_Handler** output_class ); + void + FT_Destroy_Class_cff_field_handlers( FT_Library library, + CFF_Field_Handler* clazz ); + + + void + cff_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->cff ) + { + CffModulePIC* container = (CffModulePIC*)pic_container->cff; + + + if ( container->cff_services ) + FT_Destroy_Class_cff_services( library, + container->cff_services ); + container->cff_services = NULL; + if ( container->cff_field_handlers ) + FT_Destroy_Class_cff_field_handlers( + library, container->cff_field_handlers ); + container->cff_field_handlers = NULL; + FT_FREE( container ); + pic_container->cff = NULL; + } + } + + + FT_Error + cff_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + CffModulePIC* container = NULL; + FT_Memory memory = library->memory; + + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->cff = container; + + /* initialize pointer table - */ + /* this is how the module usually expects this data */ + error = FT_Create_Class_cff_services( library, + &container->cff_services ); + if ( error ) + goto Exit; + + error = FT_Create_Class_cff_field_handlers( + library, &container->cff_field_handlers ); + if ( error ) + goto Exit; + + FT_Init_Class_cff_service_ps_info( + library, &container->cff_service_ps_info ); + FT_Init_Class_cff_service_glyph_dict( + library, &container->cff_service_glyph_dict ); + FT_Init_Class_cff_service_ps_name( + library, &container->cff_service_ps_name ); + FT_Init_Class_cff_service_get_cmap_info( + library, &container->cff_service_get_cmap_info ); + FT_Init_Class_cff_service_cid_info( + library, &container->cff_service_cid_info ); + FT_Init_Class_cff_cmap_encoding_class_rec( + library, &container->cff_cmap_encoding_class_rec ); + FT_Init_Class_cff_cmap_unicode_class_rec( + library, &container->cff_cmap_unicode_class_rec ); + + Exit: + if ( error ) + cff_driver_class_pic_free( library ); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cffpic.h b/drivers/freetype/src/cff/cffpic.h new file mode 100644 index 0000000000..50bab4c173 --- /dev/null +++ b/drivers/freetype/src/cff/cffpic.h @@ -0,0 +1,108 @@ +/***************************************************************************/ +/* */ +/* cffpic.h */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __CFFPIC_H__ +#define __CFFPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + +#ifndef FT_CONFIG_OPTION_PIC + +#define CFF_SERVICE_PS_INFO_GET cff_service_ps_info +#define CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict +#define CFF_SERVICE_PS_NAME_GET cff_service_ps_name +#define CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info +#define CFF_SERVICE_CID_INFO_GET cff_service_cid_info +#define CFF_SERVICE_PROPERTIES_GET cff_service_properties +#define CFF_SERVICES_GET cff_services +#define CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec +#define CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec +#define CFF_FIELD_HANDLERS_GET cff_field_handlers + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_GLYPH_DICT_H +#include "cffparse.h" +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_TT_CMAP_H +#include FT_SERVICE_CID_H +#include FT_SERVICE_PROPERTIES_H + + + typedef struct CffModulePIC_ + { + FT_ServiceDescRec* cff_services; + CFF_Field_Handler* cff_field_handlers; + FT_Service_PsInfoRec cff_service_ps_info; + FT_Service_GlyphDictRec cff_service_glyph_dict; + FT_Service_PsFontNameRec cff_service_ps_name; + FT_Service_TTCMapsRec cff_service_get_cmap_info; + FT_Service_CIDRec cff_service_cid_info; + FT_Service_PropertiesRec cff_service_properties; + FT_CMap_ClassRec cff_cmap_encoding_class_rec; + FT_CMap_ClassRec cff_cmap_unicode_class_rec; + + } CffModulePIC; + + +#define GET_PIC( lib ) \ + ( (CffModulePIC*)( (lib)->pic_container.cff ) ) + +#define CFF_SERVICE_PS_INFO_GET \ + ( GET_PIC( library )->cff_service_ps_info ) +#define CFF_SERVICE_GLYPH_DICT_GET \ + ( GET_PIC( library )->cff_service_glyph_dict ) +#define CFF_SERVICE_PS_NAME_GET \ + ( GET_PIC( library )->cff_service_ps_name ) +#define CFF_SERVICE_GET_CMAP_INFO_GET \ + ( GET_PIC( library )->cff_service_get_cmap_info ) +#define CFF_SERVICE_CID_INFO_GET \ + ( GET_PIC( library )->cff_service_cid_info ) +#define CFF_SERVICE_PROPERTIES_GET \ + ( GET_PIC( library )->cff_service_properties ) +#define CFF_SERVICES_GET \ + ( GET_PIC( library )->cff_services ) +#define CFF_CMAP_ENCODING_CLASS_REC_GET \ + ( GET_PIC( library )->cff_cmap_encoding_class_rec ) +#define CFF_CMAP_UNICODE_CLASS_REC_GET \ + ( GET_PIC( library )->cff_cmap_unicode_class_rec ) +#define CFF_FIELD_HANDLERS_GET \ + ( GET_PIC( library )->cff_field_handlers ) + + /* see cffpic.c for the implementation */ + void + cff_driver_class_pic_free( FT_Library library ); + + FT_Error + cff_driver_class_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __CFFPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/cfftoken.h b/drivers/freetype/src/cff/cfftoken.h new file mode 100644 index 0000000000..bcb4276a78 --- /dev/null +++ b/drivers/freetype/src/cff/cfftoken.h @@ -0,0 +1,97 @@ +/***************************************************************************/ +/* */ +/* cfftoken.h */ +/* */ +/* CFF token definitions (specification only). */ +/* */ +/* Copyright 1996-2003, 2011 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. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec + +#undef CFFCODE +#define CFFCODE CFFCODE_TOPDICT + + CFF_FIELD_STRING ( 0, version, "Version" ) + CFF_FIELD_STRING ( 1, notice, "Notice" ) + CFF_FIELD_STRING ( 0x100, copyright, "Copyright" ) + CFF_FIELD_STRING ( 2, full_name, "FullName" ) + CFF_FIELD_STRING ( 3, family_name, "FamilyName" ) + CFF_FIELD_STRING ( 4, weight, "Weight" ) + CFF_FIELD_BOOL ( 0x101, is_fixed_pitch, "isFixedPitch" ) + CFF_FIELD_FIXED ( 0x102, italic_angle, "ItalicAngle" ) + CFF_FIELD_FIXED ( 0x103, underline_position, "UnderlinePosition" ) + CFF_FIELD_FIXED ( 0x104, underline_thickness, "UnderlineThickness" ) + CFF_FIELD_NUM ( 0x105, paint_type, "PaintType" ) + CFF_FIELD_NUM ( 0x106, charstring_type, "CharstringType" ) + CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" ) + CFF_FIELD_NUM ( 13, unique_id, "UniqueID" ) + CFF_FIELD_CALLBACK( 5, font_bbox, "FontBBox" ) + CFF_FIELD_NUM ( 0x108, stroke_width, "StrokeWidth" ) + CFF_FIELD_NUM ( 15, charset_offset, "charset" ) + CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" ) + CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) + CFF_FIELD_CALLBACK( 18, private_dict, "Private" ) + CFF_FIELD_NUM ( 0x114, synthetic_base, "SyntheticBase" ) + CFF_FIELD_STRING ( 0x115, embedded_postscript, "PostScript" ) + +#if 0 + CFF_FIELD_STRING ( 0x116, base_font_name, "BaseFontName" ) + CFF_FIELD_DELTA ( 0x117, base_font_blend, 16, "BaseFontBlend" ) + CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" ) + CFF_FIELD_CALLBACK( 0x119, blend_axis_types, "BlendAxisTypes" ) +#endif + + CFF_FIELD_CALLBACK( 0x11E, cid_ros, "ROS" ) + CFF_FIELD_NUM ( 0x11F, cid_font_version, "CIDFontVersion" ) + CFF_FIELD_NUM ( 0x120, cid_font_revision, "CIDFontRevision" ) + CFF_FIELD_NUM ( 0x121, cid_font_type, "CIDFontType" ) + CFF_FIELD_NUM ( 0x122, cid_count, "CIDCount" ) + CFF_FIELD_NUM ( 0x123, cid_uid_base, "UIDBase" ) + CFF_FIELD_NUM ( 0x124, cid_fd_array_offset, "FDArray" ) + CFF_FIELD_NUM ( 0x125, cid_fd_select_offset, "FDSelect" ) + CFF_FIELD_STRING ( 0x126, cid_font_name, "FontName" ) + +#if 0 + CFF_FIELD_NUM ( 0x127, chameleon, "Chameleon" ) +#endif + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_PrivateRec +#undef CFFCODE +#define CFFCODE CFFCODE_PRIVATE + + CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) + CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) + CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" ) + CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" ) + CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" ) + CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) + CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) + CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) + CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) + CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) + CFF_FIELD_BOOL ( 0x10E, force_bold, "ForceBold" ) + CFF_FIELD_FIXED ( 0x10F, force_bold_threshold, "ForceBoldThreshold" ) + CFF_FIELD_NUM ( 0x110, lenIV, "lenIV" ) + CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) + CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) + CFF_FIELD_NUM ( 0x113, initial_random_seed, "initialRandomSeed" ) + CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) + CFF_FIELD_NUM ( 20, default_width, "defaultWidthX" ) + CFF_FIELD_NUM ( 21, nominal_width, "nominalWidthX" ) + + +/* END */ diff --git a/drivers/freetype/src/cff/cfftypes.h b/drivers/freetype/src/cff/cfftypes.h new file mode 100644 index 0000000000..8727446664 --- /dev/null +++ b/drivers/freetype/src/cff/cfftypes.h @@ -0,0 +1,284 @@ +/***************************************************************************/ +/* */ +/* cfftypes.h */ +/* */ +/* Basic OpenType/CFF type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2003, 2006-2008, 2010-2011, 2013 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 __CFFTYPES_H__ +#define __CFFTYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CFF_IndexRec */ + /* */ + /* <Description> */ + /* A structure used to model a CFF Index table. */ + /* */ + /* <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. */ + /* */ + /* data_offset :: The position of first data byte in the index's */ + /* bytes. */ + /* */ + /* 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; + + } CFF_IndexRec, *CFF_Index; + + + typedef struct CFF_EncodingRec_ + { + FT_UInt format; + FT_ULong offset; + + FT_UInt count; + FT_UShort sids [256]; /* avoid dynamic allocations */ + FT_UShort codes[256]; + + } CFF_EncodingRec, *CFF_Encoding; + + + typedef struct CFF_CharsetRec_ + { + + FT_UInt format; + FT_ULong offset; + + FT_UShort* sids; + 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; + + + typedef struct CFF_FontRecDictRec_ + { + FT_UInt version; + FT_UInt notice; + FT_UInt copyright; + FT_UInt full_name; + FT_UInt family_name; + FT_UInt weight; + FT_Bool is_fixed_pitch; + FT_Fixed italic_angle; + FT_Fixed underline_position; + FT_Fixed underline_thickness; + FT_Int paint_type; + FT_Int charstring_type; + FT_Matrix font_matrix; + FT_Bool has_font_matrix; + FT_ULong units_per_em; /* temporarily used as scaling value also */ + FT_Vector font_offset; + FT_ULong unique_id; + FT_BBox font_bbox; + FT_Pos stroke_width; + FT_ULong charset_offset; + FT_ULong encoding_offset; + FT_ULong charstrings_offset; + FT_ULong private_offset; + FT_ULong private_size; + FT_Long synthetic_base; + FT_UInt embedded_postscript; + + /* these should only be used for the top-level font dictionary */ + FT_UInt cid_registry; + FT_UInt cid_ordering; + FT_Long cid_supplement; + + FT_Long cid_font_version; + FT_Long cid_font_revision; + FT_Long cid_font_type; + FT_ULong cid_count; + FT_ULong cid_uid_base; + FT_ULong cid_fd_array_offset; + FT_ULong cid_fd_select_offset; + FT_UInt cid_font_name; + + } CFF_FontRecDictRec, *CFF_FontRecDict; + + + typedef struct CFF_PrivateRec_ + { + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Pos blue_values[14]; + FT_Pos other_blues[10]; + FT_Pos family_blues[14]; + FT_Pos family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Pos blue_shift; + FT_Pos blue_fuzz; + FT_Pos standard_width; + FT_Pos standard_height; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Pos snap_widths[13]; + FT_Pos snap_heights[13]; + FT_Bool force_bold; + FT_Fixed force_bold_threshold; + FT_Int lenIV; + FT_Int language_group; + FT_Fixed expansion_factor; + FT_Long initial_random_seed; + FT_ULong local_subrs_offset; + FT_Pos default_width; + FT_Pos nominal_width; + + } CFF_PrivateRec, *CFF_Private; + + + typedef struct CFF_FDSelectRec_ + { + FT_Byte format; + FT_UInt range_count; + + /* that's the table, taken from the file `as is' */ + FT_Byte* data; + FT_UInt data_size; + + /* small cache for format 3 only */ + FT_UInt cache_first; + FT_UInt cache_count; + FT_Byte cache_fd; + + } CFF_FDSelectRec, *CFF_FDSelect; + + + /* A SubFont packs a font dict and a private dict together. They are */ + /* needed to support CID-keyed CFF fonts. */ + typedef struct CFF_SubFontRec_ + { + CFF_FontRecDictRec font_dict; + CFF_PrivateRec private_dict; + + CFF_IndexRec local_subrs_index; + FT_Byte** local_subrs; /* array of pointers into Local Subrs INDEX data */ + + } CFF_SubFontRec, *CFF_SubFont; + + +#define CFF_MAX_CID_FONTS 256 + + + typedef struct CFF_FontRec_ + { + FT_Stream stream; + FT_Memory memory; + FT_UInt num_faces; + FT_UInt num_glyphs; + + FT_Byte version_major; + FT_Byte version_minor; + FT_Byte header_size; + FT_Byte absolute_offsize; + + + CFF_IndexRec name_index; + CFF_IndexRec top_dict_index; + CFF_IndexRec global_subrs_index; + + CFF_EncodingRec encoding; + CFF_CharsetRec charset; + + CFF_IndexRec charstrings_index; + CFF_IndexRec font_dict_index; + CFF_IndexRec private_index; + CFF_IndexRec local_subrs_index; + + FT_String* font_name; + + /* array of pointers into Global Subrs INDEX data */ + FT_Byte** global_subrs; + + /* array of pointers into String INDEX data stored at string_pool */ + FT_UInt num_strings; + FT_Byte** strings; + FT_Byte* string_pool; + + CFF_SubFontRec top_font; + FT_UInt num_subfonts; + CFF_SubFont subfonts[CFF_MAX_CID_FONTS]; + + CFF_FDSelectRec fd_select; + + /* interface to PostScript hinter */ + PSHinter_Service pshinter; + + /* interface to Postscript Names service */ + FT_Service_PsCMaps psnames; + + /* since version 2.3.0 */ + PS_FontInfoRec* font_info; /* font info dictionary */ + + /* since version 2.3.6 */ + FT_String* registry; + FT_String* ordering; + + /* since version 2.4.12 */ + FT_Generic cf2_instance; + + } CFF_FontRec, *CFF_Font; + + +FT_END_HEADER + +#endif /* __CFFTYPES_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cff/module.mk b/drivers/freetype/src/cff/module.mk new file mode 100644 index 0000000000..ef1391c279 --- /dev/null +++ b/drivers/freetype/src/cff/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 CFF module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += CFF_DRIVER + +define CFF_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, cff_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/cff/rules.mk b/drivers/freetype/src/cff/rules.mk new file mode 100644 index 0000000000..13115c2550 --- /dev/null +++ b/drivers/freetype/src/cff/rules.mk @@ -0,0 +1,86 @@ +# +# FreeType 2 OpenType/CFF driver configuration rules +# + + +# Copyright 1996-2001, 2003, 2011, 2013 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. + + +# OpenType driver directory +# +CFF_DIR := $(SRC_DIR)/cff + + +CFF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) + + +# CFF driver sources (i.e., C files) +# +CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \ + $(CFF_DIR)/cffdrivr.c \ + $(CFF_DIR)/cffgload.c \ + $(CFF_DIR)/cffload.c \ + $(CFF_DIR)/cffobjs.c \ + $(CFF_DIR)/cffparse.c \ + $(CFF_DIR)/cffpic.c \ + $(CFF_DIR)/cf2arrst.c \ + $(CFF_DIR)/cf2blues.c \ + $(CFF_DIR)/cf2error.c \ + $(CFF_DIR)/cf2font.c \ + $(CFF_DIR)/cf2ft.c \ + $(CFF_DIR)/cf2hints.c \ + $(CFF_DIR)/cf2intrp.c \ + $(CFF_DIR)/cf2read.c \ + $(CFF_DIR)/cf2stack.c + + +# CFF driver headers +# +CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ + $(CFF_DIR)/cfferrs.h \ + $(CFF_DIR)/cfftoken.h \ + $(CFF_DIR)/cfftypes.h \ + $(CFF_DIR)/cf2fixed.h \ + $(CFF_DIR)/cf2glue.h \ + $(CFF_DIR)/cf2types.h + + +# CFF driver object(s) +# +# CFF_DRV_OBJ_M is used during `multi' builds +# CFF_DRV_OBJ_S is used during `single' builds +# +CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR)/%.c=$(OBJ_DIR)/%.$O) +CFF_DRV_OBJ_S := $(OBJ_DIR)/cff.$O + +# CFF driver source file for single build +# +CFF_DRV_SRC_S := $(CFF_DIR)/cff.c + + +# CFF driver - single object +# +$(CFF_DRV_OBJ_S): $(CFF_DRV_SRC_S) $(CFF_DRV_SRC) $(FREETYPE_H) $(CFF_DRV_H) + $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CFF_DRV_SRC_S)) + + +# CFF driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(CFF_DIR)/%.c $(FREETYPE_H) $(CFF_DRV_H) + $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(CFF_DRV_OBJ_S) +DRV_OBJS_M += $(CFF_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/cid/Jamfile b/drivers/freetype/src/cid/Jamfile new file mode 100644 index 0000000000..ebeaed54ea --- /dev/null +++ b/drivers/freetype/src/cid/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/cid Jamfile +# +# Copyright 2001 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) cid ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = cidobjs cidload cidgload cidriver cidparse ; + } + else + { + _sources = type1cid ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/cid Jamfile diff --git a/drivers/freetype/src/cid/ciderrs.h b/drivers/freetype/src/cid/ciderrs.h new file mode 100644 index 0000000000..ef13155504 --- /dev/null +++ b/drivers/freetype/src/cid/ciderrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* ciderrs.h */ +/* */ +/* CID error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the CID error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __CIDERRS_H__ +#define __CIDERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX CID_Err_ +#define FT_ERR_BASE FT_Mod_Err_CID + +#include FT_ERRORS_H + +#endif /* __CIDERRS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cid/cidgload.c b/drivers/freetype/src/cid/cidgload.c new file mode 100644 index 0000000000..a1a8658693 --- /dev/null +++ b/drivers/freetype/src/cid/cidgload.c @@ -0,0 +1,442 @@ +/***************************************************************************/ +/* */ +/* cidgload.c */ +/* */ +/* CID-keyed Type1 Glyph Loader (body). */ +/* */ +/* Copyright 1996-2007, 2009, 2010, 2013 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 "cidload.h" +#include "cidgload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_OUTLINE_H +#include FT_INTERNAL_CALC_H + +#include "ciderrs.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_cidgload + + + FT_CALLBACK_DEF( FT_Error ) + cid_load_glyph( T1_Decoder decoder, + FT_UInt glyph_index ) + { + CID_Face face = (CID_Face)decoder->builder.face; + CID_FaceInfo cid = &face->cid; + FT_Byte* p; + FT_UInt fd_select; + FT_Stream stream = face->cid_stream; + FT_Error error = FT_Err_Ok; + FT_Byte* charstring = 0; + FT_Memory memory = face->root.memory; + FT_ULong glyph_length = 0; + PSAux_Service psaux = (PSAux_Service)face->psaux; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + + + FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index )); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* For incremental fonts get the character data using */ + /* the callback function. */ + if ( inc ) + { + FT_Data glyph_data; + + + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, &glyph_data ); + if ( error ) + goto Exit; + + p = (FT_Byte*)glyph_data.pointer; + fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + + if ( glyph_data.length != 0 ) + { + glyph_length = glyph_data.length - cid->fd_bytes; + (void)FT_ALLOC( charstring, glyph_length ); + if ( !error ) + ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, + glyph_length ); + } + + inc->funcs->free_glyph_data( inc->object, &glyph_data ); + + if ( error ) + goto Exit; + } + + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* For ordinary fonts read the CID font dictionary index */ + /* and charstring offset from the CIDMap. */ + { + FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; + FT_ULong off1; + + + if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + + glyph_index * entry_len ) || + FT_FRAME_ENTER( 2 * entry_len ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + p += cid->fd_bytes; + glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; + FT_FRAME_EXIT(); + + if ( fd_select >= (FT_UInt)cid->num_dicts ) + { + error = FT_THROW( Invalid_Offset ); + goto Exit; + } + if ( glyph_length == 0 ) + goto Exit; + if ( FT_ALLOC( charstring, glyph_length ) ) + goto Exit; + if ( FT_STREAM_READ_AT( cid->data_offset + off1, + charstring, glyph_length ) ) + goto Exit; + } + + /* Now set up the subrs array and parse the charstrings. */ + { + CID_FaceDict dict; + CID_Subrs cid_subrs = face->subrs + fd_select; + FT_Int cs_offset; + + + /* Set up subrs */ + decoder->num_subrs = cid_subrs->num_subrs; + decoder->subrs = cid_subrs->code; + decoder->subrs_len = 0; + + /* Set up font matrix */ + dict = cid->font_dicts + fd_select; + + decoder->font_matrix = dict->font_matrix; + decoder->font_offset = dict->font_offset; + decoder->lenIV = dict->private_dict.lenIV; + + /* Decode the charstring. */ + + /* Adjustment for seed bytes. */ + cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + + /* Decrypt only if lenIV >= 0. */ + if ( decoder->lenIV >= 0 ) + psaux->t1_decrypt( charstring, glyph_length, 4330 ); + + error = decoder->funcs.parse_charstrings( + decoder, charstring + cs_offset, + (FT_Int)glyph_length - cs_offset ); + } + + FT_FREE( charstring ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && inc && inc->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = 0; + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); + decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + Exit: + return error; + } + + +#if 0 + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + cid_face_compute_max_advance( CID_Face face, + FT_Int* max_advance ) + { + FT_Error error; + T1_DecoderRec decoder; + FT_Int glyph_index; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + *max_advance = 0; + + /* Initialize load decoder */ + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + 0, /* glyph names! XXX */ + 0, /* blend == 0 */ + 0, /* hinting == 0 */ + cid_load_glyph ); + 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; + + /* for each glyph, parse the glyph charstring and extract */ + /* the advance width */ + for ( glyph_index = 0; glyph_index < face->root.num_glyphs; + glyph_index++ ) + { + /* now get load the unscaled outline */ + error = cid_load_glyph( &decoder, glyph_index ); + /* ignore the error if one occurred - skip to next glyph */ + } + + *max_advance = FIXED_TO_INT( decoder.builder.advance.x ); + + psaux->t1_decoder_funcs->done( &decoder ); + + return FT_Err_Ok; + } + + +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_Error ) + cid_slot_load_glyph( FT_GlyphSlot cidglyph, /* CID_GlyphSlot */ + FT_Size cidsize, /* CID_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + CID_GlyphSlot glyph = (CID_GlyphSlot)cidglyph; + FT_Error error; + T1_DecoderRec decoder; + CID_Face face = (CID_Face)cidglyph->face; + FT_Bool hinting; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_Matrix font_matrix; + FT_Vector font_offset; + + + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + glyph->x_scale = cidsize->metrics.x_scale; + glyph->y_scale = cidsize->metrics.y_scale; + + cidglyph->outline.n_points = 0; + cidglyph->outline.n_contours = 0; + + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + + 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 ); + if ( error ) + goto Exit; + + /* TODO: initialize decoder.len_buildchar and decoder.buildchar */ + /* if we ever support CID-keyed multiple master fonts */ + + /* set up the decoder */ + decoder.builder.no_recurse = FT_BOOL( + ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); + + error = cid_load_glyph( &decoder, glyph_index ); + if ( error ) + goto Exit; + + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; + + /* 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 */ + 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 ) + { + FT_Slot_Internal internal = cidglyph->internal; + + + cidglyph->metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + cidglyph->metrics.horiAdvance = + FIXED_TO_INT( 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 = + FIXED_TO_INT( decoder.builder.advance.x ); + cidglyph->linearHoriAdvance = + FIXED_TO_INT( 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 ( 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; + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } + } + + Exit: + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/cid/cidgload.h b/drivers/freetype/src/cid/cidgload.h new file mode 100644 index 0000000000..a0a91bfea8 --- /dev/null +++ b/drivers/freetype/src/cid/cidgload.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* cidgload.h */ +/* */ +/* OpenType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004 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 __CIDGLOAD_H__ +#define __CIDGLOAD_H__ + + +#include <ft2build.h> +#include "cidobjs.h" + + +FT_BEGIN_HEADER + + +#if 0 + + /* Compute the maximum advance width of a font through quick parsing */ + FT_LOCAL( FT_Error ) + cid_face_compute_max_advance( CID_Face face, + FT_Int* max_advance ); + +#endif /* 0 */ + + FT_LOCAL( FT_Error ) + cid_slot_load_glyph( FT_GlyphSlot glyph, /* CID_Glyph_Slot */ + FT_Size size, /* CID_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __CIDGLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cid/cidload.c b/drivers/freetype/src/cid/cidload.c new file mode 100644 index 0000000000..f2a18ea510 --- /dev/null +++ b/drivers/freetype/src/cid/cidload.c @@ -0,0 +1,690 @@ +/***************************************************************************/ +/* */ +/* cidload.c */ +/* */ +/* CID-keyed Type1 font loader (body). */ +/* */ +/* Copyright 1996-2006, 2009, 2011-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_TYPE1_TYPES_H + +#include "cidload.h" + +#include "ciderrs.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_cidload + + + /* read a single offset */ + FT_LOCAL_DEF( FT_Long ) + cid_get_offset( FT_Byte* *start, + FT_Byte offsize ) + { + FT_ULong result; + FT_Byte* p = *start; + + + for ( result = 0; offsize > 0; offsize-- ) + { + result <<= 8; + result |= *p++; + } + + *start = p; + return (FT_Long)result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 SYMBOL PARSING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + cid_load_keyword( CID_Face face, + CID_Loader* loader, + const T1_Field keyword ) + { + FT_Error error; + CID_Parser* parser = &loader->parser; + FT_Byte* object; + void* dummy_object; + CID_FaceInfo cid = &face->cid; + + + /* if the keyword has a dedicated callback, call it */ + if ( keyword->type == T1_FIELD_TYPE_CALLBACK ) + { + keyword->reader( (FT_Face)face, parser ); + error = parser->root.error; + goto Exit; + } + + /* we must now compute the address of our target object */ + switch ( keyword->location ) + { + case T1_FIELD_LOCATION_CID_INFO: + object = (FT_Byte*)cid; + break; + + case T1_FIELD_LOCATION_FONT_INFO: + object = (FT_Byte*)&cid->font_info; + break; + + case T1_FIELD_LOCATION_FONT_EXTRA: + object = (FT_Byte*)&face->font_extra; + break; + + case T1_FIELD_LOCATION_BBOX: + object = (FT_Byte*)&cid->font_bbox; + break; + + default: + { + CID_FaceDict dict; + + + if ( parser->num_dict < 0 || parser->num_dict >= cid->num_dicts ) + { + FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n", + keyword->ident )); + error = FT_THROW( Syntax_Error ); + goto Exit; + } + + dict = cid->font_dicts + parser->num_dict; + switch ( keyword->location ) + { + case T1_FIELD_LOCATION_PRIVATE: + object = (FT_Byte*)&dict->private_dict; + break; + + default: + object = (FT_Byte*)dict; + } + } + } + + dummy_object = object; + + /* now, load the keyword data in the object's field(s) */ + if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY || + keyword->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = cid_parser_load_field_table( &loader->parser, keyword, + &dummy_object ); + else + error = cid_parser_load_field( &loader->parser, + keyword, &dummy_object ); + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + cid_parse_font_matrix( CID_Face face, + CID_Parser* parser ) + { + FT_Matrix* matrix; + FT_Vector* offset; + CID_FaceDict dict; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + + + if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) + { + dict = face->cid.font_dicts + parser->num_dict; + matrix = &dict->font_matrix; + offset = &dict->font_offset; + + (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); + + temp_scale = FT_ABS( temp[3] ); + + /* Set Units per EM based on FontMatrix values. We set the value to */ + /* 1000 / temp_scale, because temp_scale was already multiplied by */ + /* 1000 (in t1_tofixed, from psobjs.c). */ + + root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + + /* we need to scale the values by 1.0/temp[3] */ + if ( temp_scale != 0x10000L ) + { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the font offsets are expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + return FT_Err_Ok; /* this is a callback function; */ + /* we must return an error code */ + } + + + FT_CALLBACK_DEF( FT_Error ) + parse_fd_array( CID_Face face, + CID_Parser* parser ) + { + CID_FaceInfo cid = &face->cid; + FT_Memory memory = face->root.memory; + FT_Error error = FT_Err_Ok; + FT_Long num_dicts; + + + num_dicts = cid_parser_to_int( parser ); + + if ( !cid->font_dicts ) + { + FT_Int n; + + + if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) + goto Exit; + + cid->num_dicts = (FT_UInt)num_dicts; + + /* don't forget to set a few defaults */ + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + + + /* default value for lenIV */ + dict->private_dict.lenIV = 4; + } + } + + Exit: + return error; + } + + + /* by mistake, `expansion_factor' appears both in PS_PrivateRec */ + /* and CID_FaceDictRec (both are public header files and can't */ + /* changed); we simply copy the value */ + + FT_CALLBACK_DEF( FT_Error ) + parse_expansion_factor( CID_Face face, + CID_Parser* parser ) + { + CID_FaceDict dict; + + + if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) + { + dict = face->cid.font_dicts + parser->num_dict; + + dict->expansion_factor = cid_parser_to_fixed( parser, 0 ); + dict->private_dict.expansion_factor = dict->expansion_factor; + } + + return FT_Err_Ok; + } + + + static + const T1_FieldRec cid_field_records[] = + { + +#include "cidtoken.h" + + T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) + T1_FIELD_CALLBACK( "FontMatrix", cid_parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 ) + + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } + }; + + + static FT_Error + cid_parse_dict( CID_Face face, + CID_Loader* loader, + FT_Byte* base, + FT_Long size ) + { + CID_Parser* parser = &loader->parser; + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = FT_Err_Ok; + + { + FT_Byte* cur = base; + FT_Byte* limit = cur + size; + + + for (;;) + { + FT_Byte* newlimit; + + + parser->root.cursor = cur; + cid_parser_skip_spaces( parser ); + + if ( parser->root.cursor >= limit ) + newlimit = limit - 1 - 17; + else + newlimit = parser->root.cursor - 17; + + /* look for `%ADOBeginFontDict' */ + for ( ; cur < newlimit; cur++ ) + { + if ( *cur == '%' && + ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) + { + /* if /FDArray was found, then cid->num_dicts is > 0, and */ + /* we can start increasing parser->num_dict */ + if ( face->cid.num_dicts > 0 ) + parser->num_dict++; + } + } + + cur = parser->root.cursor; + /* no error can occur in cid_parser_skip_spaces */ + if ( cur >= limit ) + break; + + cid_parser_skip_PS_token( parser ); + if ( parser->root.cursor >= limit || parser->root.error ) + break; + + /* look for immediates */ + if ( *cur == '/' && cur + 2 < limit ) + { + FT_PtrDist len; + + + cur++; + len = parser->root.cursor - cur; + + if ( len > 0 && len < 22 ) + { + /* now compare the immediate name to the keyword table */ + T1_Field keyword = (T1_Field)cid_field_records; + + + for (;;) + { + FT_Byte* name; + + + name = (FT_Byte*)keyword->ident; + if ( !name ) + break; + + if ( cur[0] == name[0] && + len == (FT_PtrDist)ft_strlen( (const char*)name ) ) + { + FT_PtrDist n; + + + for ( n = 1; n < len; n++ ) + if ( cur[n] != name[n] ) + break; + + if ( n >= len ) + { + /* we found it - run the parsing callback */ + parser->root.error = cid_load_keyword( face, + loader, + keyword ); + if ( parser->root.error ) + return parser->root.error; + break; + } + } + keyword++; + } + } + } + + cur = parser->root.cursor; + } + } + return parser->root.error; + } + + + /* read the subrmap and the subrs of each font dict */ + static FT_Error + cid_read_subrs( CID_Face face ) + { + CID_FaceInfo cid = &face->cid; + FT_Memory memory = face->root.memory; + FT_Stream stream = face->cid_stream; + FT_Error error; + FT_Int n; + CID_Subrs subr; + FT_UInt max_offsets = 0; + FT_ULong* offsets = 0; + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) ) + goto Exit; + + subr = face->subrs; + for ( n = 0; n < cid->num_dicts; n++, subr++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + FT_Int lenIV = dict->private_dict.lenIV; + FT_UInt count, num_subrs = dict->num_subrs; + FT_ULong data_len; + FT_Byte* p; + + + /* Check for possible overflow. */ + if ( num_subrs == FT_UINT_MAX ) + { + error = FT_THROW( Syntax_Error ); + goto Fail; + } + + /* reallocate offsets array if needed */ + if ( num_subrs + 1 > max_offsets ) + { + FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 ); + + + if ( new_max <= max_offsets ) + { + error = FT_THROW( Syntax_Error ); + goto Fail; + } + + if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) + goto Fail; + + max_offsets = new_max; + } + + /* read the subrmap's offsets */ + if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || + FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) + goto Fail; + + p = (FT_Byte*)stream->cursor; + for ( count = 0; count <= num_subrs; count++ ) + offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); + + FT_FRAME_EXIT(); + + /* offsets must be ordered */ + for ( count = 1; count <= num_subrs; count++ ) + if ( offsets[count - 1] > offsets[count] ) + goto Fail; + + /* now, compute the size of subrs charstrings, */ + /* allocate, and read them */ + data_len = offsets[num_subrs] - offsets[0]; + + if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || + FT_ALLOC( subr->code[0], data_len ) ) + goto Fail; + + if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || + FT_STREAM_READ( subr->code[0], data_len ) ) + goto Fail; + + /* set up pointers */ + for ( count = 1; count <= num_subrs; count++ ) + { + FT_ULong len; + + + len = offsets[count] - offsets[count - 1]; + subr->code[count] = subr->code[count - 1] + len; + } + + /* decrypt subroutines, but only if lenIV >= 0 */ + if ( lenIV >= 0 ) + { + for ( count = 0; count < num_subrs; count++ ) + { + FT_ULong len; + + + len = offsets[count + 1] - offsets[count]; + psaux->t1_decrypt( subr->code[count], len, 4330 ); + } + } + + subr->num_subrs = num_subrs; + } + + Exit: + FT_FREE( offsets ); + return error; + + Fail: + if ( face->subrs ) + { + for ( n = 0; n < cid->num_dicts; n++ ) + { + if ( face->subrs[n].code ) + FT_FREE( face->subrs[n].code[0] ); + + FT_FREE( face->subrs[n].code ); + } + FT_FREE( face->subrs ); + } + goto Exit; + } + + + static void + cid_init_loader( CID_Loader* loader, + CID_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + } + + + static void + cid_done_loader( CID_Loader* loader ) + { + CID_Parser* parser = &loader->parser; + + + /* finalize parser */ + cid_parser_done( parser ); + } + + + static FT_Error + cid_hex_to_binary( FT_Byte* data, + FT_Long data_len, + FT_ULong offset, + CID_Face face ) + { + FT_Stream stream = face->root.stream; + FT_Error error; + + FT_Byte buffer[256]; + FT_Byte *p, *plimit; + FT_Byte *d, *dlimit; + FT_Byte val; + + FT_Bool upper_nibble, done; + + + if ( FT_STREAM_SEEK( offset ) ) + goto Exit; + + d = data; + dlimit = d + data_len; + p = buffer; + plimit = p; + + upper_nibble = 1; + done = 0; + + while ( d < dlimit ) + { + if ( p >= plimit ) + { + FT_ULong oldpos = FT_STREAM_POS(); + FT_ULong size = stream->size - oldpos; + + + if ( size == 0 ) + { + error = FT_THROW( Syntax_Error ); + goto Exit; + } + + if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) ) + goto Exit; + p = buffer; + plimit = p + FT_STREAM_POS() - oldpos; + } + + if ( ft_isdigit( *p ) ) + val = (FT_Byte)( *p - '0' ); + else if ( *p >= 'a' && *p <= 'f' ) + val = (FT_Byte)( *p - 'a' ); + else if ( *p >= 'A' && *p <= 'F' ) + val = (FT_Byte)( *p - 'A' + 10 ); + else if ( *p == ' ' || + *p == '\t' || + *p == '\r' || + *p == '\n' || + *p == '\f' || + *p == '\0' ) + { + p++; + continue; + } + else if ( *p == '>' ) + { + val = 0; + done = 1; + } + else + { + error = FT_THROW( Syntax_Error ); + goto Exit; + } + + if ( upper_nibble ) + *d = (FT_Byte)( val << 4 ); + else + { + *d = (FT_Byte)( *d + val ); + d++; + } + + upper_nibble = (FT_Byte)( 1 - upper_nibble ); + + if ( done ) + break; + + p++; + } + + error = FT_Err_Ok; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + cid_face_open( CID_Face face, + FT_Int face_index ) + { + CID_Loader loader; + CID_Parser* parser; + FT_Memory memory = face->root.memory; + FT_Error error; + + + cid_init_loader( &loader, face ); + + parser = &loader.parser; + error = cid_parser_new( parser, face->root.stream, face->root.memory, + (PSAux_Service)face->psaux ); + if ( error ) + goto Exit; + + error = cid_parse_dict( face, &loader, + parser->postscript, + parser->postscript_len ); + if ( error ) + goto Exit; + + if ( face_index < 0 ) + goto Exit; + + if ( FT_NEW( face->cid_stream ) ) + goto Exit; + + if ( parser->binary_length ) + { + /* we must convert the data section from hexadecimal to binary */ + if ( FT_ALLOC( face->binary_data, parser->binary_length ) || + cid_hex_to_binary( face->binary_data, parser->binary_length, + parser->data_offset, face ) ) + goto Exit; + + FT_Stream_OpenMemory( face->cid_stream, + face->binary_data, parser->binary_length ); + face->cid.data_offset = 0; + } + else + { + *face->cid_stream = *face->root.stream; + face->cid.data_offset = loader.parser.data_offset; + } + + error = cid_read_subrs( face ); + + Exit: + cid_done_loader( &loader ); + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/cid/cidload.h b/drivers/freetype/src/cid/cidload.h new file mode 100644 index 0000000000..8c172ffee2 --- /dev/null +++ b/drivers/freetype/src/cid/cidload.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* cidload.h */ +/* */ +/* CID-keyed Type1 font loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004 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 __CIDLOAD_H__ +#define __CIDLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include "cidparse.h" + + +FT_BEGIN_HEADER + + + typedef struct CID_Loader_ + { + CID_Parser parser; /* parser used to read the stream */ + FT_Int num_chars; /* number of characters in encoding */ + + } CID_Loader; + + + FT_LOCAL( FT_Long ) + cid_get_offset( FT_Byte** start, + FT_Byte offsize ); + + FT_LOCAL( FT_Error ) + cid_face_open( CID_Face face, + FT_Int face_index ); + + +FT_END_HEADER + +#endif /* __CIDLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cid/cidobjs.c b/drivers/freetype/src/cid/cidobjs.c new file mode 100644 index 0000000000..46555e2dc8 --- /dev/null +++ b/drivers/freetype/src/cid/cidobjs.c @@ -0,0 +1,491 @@ +/***************************************************************************/ +/* */ +/* cidobjs.c */ +/* */ +/* CID objects manager (body). */ +/* */ +/* Copyright 1996-2006, 2008, 2010-2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "cidgload.h" +#include "cidload.h" + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + +#include "ciderrs.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_cidobjs + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + cid_slot_done( FT_GlyphSlot slot ) + { + slot->internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + cid_slot_init( FT_GlyphSlot slot ) + { + CID_Face face; + PSHinter_Service pshinter; + + + face = (CID_Face)slot->face; + pshinter = (PSHinter_Service)face->pshinter; + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->face->driver->root.library, + "pshinter" ); + if ( module ) + { + T1_Hints_Funcs funcs; + + + funcs = pshinter->get_t1_funcs( module ); + slot->internal->glyph_hints = (void*)funcs; + } + } + + return 0; + } + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + cid_size_get_globals_funcs( CID_Size size ) + { + CID_Face face = (CID_Face)size->root.face; + PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->root.face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0; + } + + + FT_LOCAL_DEF( void ) + cid_size_done( FT_Size cidsize ) /* CID_Size */ + { + CID_Size size = (CID_Size)cidsize; + + + if ( cidsize->internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = cid_size_get_globals_funcs( size ); + if ( funcs ) + funcs->destroy( (PSH_Globals)cidsize->internal ); + + cidsize->internal = 0; + } + } + + + FT_LOCAL_DEF( FT_Error ) + cid_size_init( FT_Size cidsize ) /* CID_Size */ + { + CID_Size size = (CID_Size)cidsize; + FT_Error error = FT_Err_Ok; + PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size ); + + + if ( funcs ) + { + PSH_Globals globals; + CID_Face face = (CID_Face)cidsize->face; + CID_FaceDict dict = face->cid.font_dicts + face->root.face_index; + PS_Private priv = &dict->private_dict; + + + error = funcs->create( cidsize->face->memory, priv, &globals ); + if ( !error ) + cidsize->internal = (FT_Size_Internal)(void*)globals; + } + + return error; + } + + + FT_LOCAL( FT_Error ) + cid_size_request( FT_Size size, + FT_Size_Request req ) + { + PSH_Globals_Funcs funcs; + + + FT_Request_Metrics( size->face, req ); + + funcs = cid_size_get_globals_funcs( (CID_Size)size ); + + if ( funcs ) + funcs->set_scale( (PSH_Globals)size->internal, + size->metrics.x_scale, + size->metrics.y_scale, + 0, 0 ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_face_done */ + /* */ + /* <Description> */ + /* Finalizes a given face object. */ + /* */ + /* <Input> */ + /* face :: A pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + cid_face_done( FT_Face cidface ) /* CID_Face */ + { + CID_Face face = (CID_Face)cidface; + FT_Memory memory; + CID_FaceInfo cid; + PS_FontInfo info; + + + if ( !face ) + return; + + cid = &face->cid; + info = &cid->font_info; + memory = cidface->memory; + + /* release subrs */ + if ( face->subrs ) + { + FT_Int n; + + + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_Subrs subr = face->subrs + n; + + + if ( subr->code ) + { + FT_FREE( subr->code[0] ); + FT_FREE( subr->code ); + } + } + + FT_FREE( face->subrs ); + } + + /* release FontInfo strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + + /* release font dictionaries */ + FT_FREE( cid->font_dicts ); + cid->num_dicts = 0; + + /* release other strings */ + FT_FREE( cid->cid_font_name ); + FT_FREE( cid->registry ); + FT_FREE( cid->ordering ); + + cidface->family_name = 0; + cidface->style_name = 0; + + FT_FREE( face->binary_data ); + FT_FREE( face->cid_stream ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_face_init */ + /* */ + /* <Description> */ + /* Initializes a given CID face object. */ + /* */ + /* <Input> */ + /* stream :: The source font stream. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* <InOut> */ + /* face :: The newly built face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cid_face_init( FT_Stream stream, + FT_Face cidface, /* CID_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + CID_Face face = (CID_Face)cidface; + FT_Error error; + PSAux_Service psaux; + PSHinter_Service pshinter; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( stream ); + + + cidface->num_faces = 1; + + psaux = (PSAux_Service)face->psaux; + if ( !psaux ) + { + psaux = (PSAux_Service)FT_Get_Module_Interface( + FT_FACE_LIBRARY( face ), "psaux" ); + + if ( !psaux ) + { + FT_ERROR(( "cid_face_init: cannot access `psaux' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + + face->psaux = psaux; + } + + pshinter = (PSHinter_Service)face->pshinter; + if ( !pshinter ) + { + pshinter = (PSHinter_Service)FT_Get_Module_Interface( + FT_FACE_LIBRARY( face ), "pshinter" ); + + face->pshinter = pshinter; + } + + FT_TRACE2(( "CID driver\n" )); + + /* open the tokenizer; this will also check the font format */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + error = cid_face_open( face, face_index ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + /* XXX: handle CID fonts with more than a single face */ + if ( face_index != 0 ) + { + FT_ERROR(( "cid_face_init: invalid face index\n" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* now load the font program into the face object */ + + /* initialize the face object fields */ + + /* set up root face fields */ + { + CID_FaceInfo cid = &face->cid; + PS_FontInfo info = &cid->font_info; + + + cidface->num_glyphs = cid->cid_count; + cidface->num_charmaps = 0; + + cidface->face_index = face_index; + cidface->face_flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER; /* has native hinter */ + + if ( info->is_fixed_pitch ) + cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* XXX: TODO: add kerning with .afm support */ + + /* get style name -- be careful, some broken fonts only */ + /* have a /FontName dictionary entry! */ + cidface->family_name = info->family_name; + /* assume "Regular" style if we don't know better */ + cidface->style_name = (char *)"Regular"; + if ( cidface->family_name ) + { + char* full = info->full_name; + char* family = cidface->family_name; + + + if ( full ) + { + while ( *full ) + { + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + if ( !*family ) + cidface->style_name = full; + break; + } + } + } + } + } + else + { + /* do we have a `/FontName'? */ + if ( cid->cid_font_name ) + cidface->family_name = cid->cid_font_name; + } + + /* compute style flags */ + cidface->style_flags = 0; + if ( info->italic_angle ) + cidface->style_flags |= FT_STYLE_FLAG_ITALIC; + if ( info->weight ) + { + if ( !ft_strcmp( info->weight, "Bold" ) || + !ft_strcmp( info->weight, "Black" ) ) + cidface->style_flags |= FT_STYLE_FLAG_BOLD; + } + + /* no embedded bitmap support */ + cidface->num_fixed_sizes = 0; + cidface->available_sizes = 0; + + cidface->bbox.xMin = cid->font_bbox.xMin >> 16; + cidface->bbox.yMin = cid->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFF ) >> 16; + cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFF ) >> 16; + + if ( !cidface->units_per_EM ) + cidface->units_per_EM = 1000; + + cidface->ascender = (FT_Short)( cidface->bbox.yMax ); + cidface->descender = (FT_Short)( cidface->bbox.yMin ); + + cidface->height = (FT_Short)( ( cidface->units_per_EM * 12 ) / 10 ); + if ( cidface->height < cidface->ascender - cidface->descender ) + cidface->height = (FT_Short)( cidface->ascender - cidface->descender ); + + cidface->underline_position = (FT_Short)info->underline_position; + cidface->underline_thickness = (FT_Short)info->underline_thickness; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_driver_init */ + /* */ + /* <Description> */ + /* Initializes a given CID driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cid_driver_init( FT_Module driver ) + { + FT_UNUSED( driver ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_driver_done */ + /* */ + /* <Description> */ + /* Finalizes a given CID driver. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target CID driver. */ + /* */ + FT_LOCAL_DEF( void ) + cid_driver_done( FT_Module driver ) + { + FT_UNUSED( driver ); + } + + +/* END */ diff --git a/drivers/freetype/src/cid/cidobjs.h b/drivers/freetype/src/cid/cidobjs.h new file mode 100644 index 0000000000..aee346d1c8 --- /dev/null +++ b/drivers/freetype/src/cid/cidobjs.h @@ -0,0 +1,154 @@ +/***************************************************************************/ +/* */ +/* cidobjs.h */ +/* */ +/* CID objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __CIDOBJS_H__ +#define __CIDOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + /* The following structures must be defined by the hinter */ + typedef struct CID_Size_Hints_ CID_Size_Hints; + typedef struct CID_Glyph_Hints_ CID_Glyph_Hints; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_Driver */ + /* */ + /* <Description> */ + /* A handle to a Type 1 driver object. */ + /* */ + typedef struct CID_DriverRec_* CID_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_Size */ + /* */ + /* <Description> */ + /* A handle to a Type 1 size object. */ + /* */ + typedef struct CID_SizeRec_* CID_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a Type 1 glyph slot object. */ + /* */ + typedef struct CID_GlyphSlotRec_* CID_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_CharMap */ + /* */ + /* <Description> */ + /* A handle to a Type 1 character mapping object. */ + /* */ + /* <Note> */ + /* The Type 1 format doesn't use a charmap but an encoding table. */ + /* The driver is responsible for making up charmap objects */ + /* corresponding to these tables. */ + /* */ + typedef struct CID_CharMapRec_* CID_CharMap; + + + /*************************************************************************/ + /* */ + /* HERE BEGINS THE TYPE 1 SPECIFIC STUFF */ + /* */ + /*************************************************************************/ + + + typedef struct CID_SizeRec_ + { + FT_SizeRec root; + FT_Bool valid; + + } CID_SizeRec; + + + typedef struct CID_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } CID_GlyphSlotRec; + + + FT_LOCAL( void ) + cid_slot_done( FT_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + cid_slot_init( FT_GlyphSlot slot ); + + + FT_LOCAL( void ) + cid_size_done( FT_Size size ); /* CID_Size */ + + FT_LOCAL( FT_Error ) + cid_size_init( FT_Size size ); /* CID_Size */ + + FT_LOCAL( FT_Error ) + cid_size_request( FT_Size size, /* CID_Size */ + FT_Size_Request req ); + + FT_LOCAL( FT_Error ) + cid_face_init( FT_Stream stream, + FT_Face face, /* CID_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + cid_face_done( FT_Face face ); /* CID_Face */ + + + FT_LOCAL( FT_Error ) + cid_driver_init( FT_Module driver ); + + FT_LOCAL( void ) + cid_driver_done( FT_Module driver ); + + +FT_END_HEADER + +#endif /* __CIDOBJS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cid/cidparse.c b/drivers/freetype/src/cid/cidparse.c new file mode 100644 index 0000000000..53df3155d1 --- /dev/null +++ b/drivers/freetype/src/cid/cidparse.c @@ -0,0 +1,225 @@ +/***************************************************************************/ +/* */ +/* cidparse.c */ +/* */ +/* CID-keyed Type1 parser (body). */ +/* */ +/* Copyright 1996-2007, 2009, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H + +#include "cidparse.h" + +#include "ciderrs.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_cidparse + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INPUT STREAM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + cid_parser_new( CID_Parser* parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error; + FT_ULong base_offset, offset, ps_len; + FT_Byte *cur, *limit; + FT_Byte *arg1, *arg2; + + + FT_MEM_ZERO( parser, sizeof ( *parser ) ); + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + + parser->stream = stream; + + base_offset = FT_STREAM_POS(); + + /* first of all, check the font format in the header */ + if ( FT_FRAME_ENTER( 31 ) ) + goto Exit; + + if ( ft_strncmp( (char *)stream->cursor, + "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) + { + FT_TRACE2(( " not a CID-keyed font\n" )); + error = FT_THROW( Unknown_File_Format ); + } + + FT_FRAME_EXIT(); + if ( error ) + goto Exit; + + Again: + /* now, read the rest of the file until we find */ + /* `StartData' or `/sfnts' */ + { + FT_Byte buffer[256 + 10]; + FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ + FT_Byte* p = buffer; + + + for ( offset = FT_STREAM_POS(); ; offset += 256 ) + { + FT_Long stream_len; /* same as signed FT_Stream->size */ + + + stream_len = stream->size - FT_STREAM_POS(); + if ( stream_len == 0 ) + { + FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + read_len = FT_MIN( read_len, stream_len ); + if ( FT_STREAM_READ( p, read_len ) ) + goto Exit; + + if ( read_len < 256 ) + p[read_len] = '\0'; + + limit = p + read_len - 10; + + for ( p = buffer; p < limit; p++ ) + { + if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) + { + /* save offset of binary data after `StartData' */ + offset += (FT_ULong)( p - buffer + 10 ); + goto Found; + } + else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) + { + offset += (FT_ULong)( p - buffer + 7 ); + goto Found; + } + } + + FT_MEM_MOVE( buffer, p, 10 ); + read_len = 256; + p = buffer + 10; + } + } + + Found: + /* 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 ) || + FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) + goto Exit; + + parser->data_offset = offset; + parser->postscript_len = ps_len; + parser->root.base = parser->postscript; + parser->root.cursor = parser->postscript; + parser->root.limit = parser->root.cursor + ps_len; + parser->num_dict = -1; + + /* 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 ); + cid_parser_skip_spaces ( parser ); + arg2 = parser->root.cursor; + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + + limit = parser->root.limit; + cur = parser->root.cursor; + + while ( cur < limit ) + { + if ( parser->root.error ) + { + error = parser->root.error; + goto Exit; + } + + 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 ); + + limit = parser->root.limit; + 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 = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + arg1 = arg2; + arg2 = cur; + cur = parser->root.cursor; + } + + /* we haven't found the correct `StartData'; go back and continue */ + /* searching */ + FT_FRAME_RELEASE( parser->postscript ); + if ( !FT_STREAM_SEEK( offset ) ) + goto Again; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cid_parser_done( CID_Parser* parser ) + { + /* always free the private dictionary */ + if ( parser->postscript ) + { + FT_Stream stream = parser->stream; + + + FT_FRAME_RELEASE( parser->postscript ); + } + parser->root.funcs.done( &parser->root ); + } + + +/* END */ diff --git a/drivers/freetype/src/cid/cidparse.h b/drivers/freetype/src/cid/cidparse.h new file mode 100644 index 0000000000..ca37deab93 --- /dev/null +++ b/drivers/freetype/src/cid/cidparse.h @@ -0,0 +1,123 @@ +/***************************************************************************/ +/* */ +/* cidparse.h */ +/* */ +/* CID-keyed Type1 parser (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004 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 __CIDPARSE_H__ +#define __CIDPARSE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Parser */ + /* */ + /* <Description> */ + /* A CID_Parser is an object used to parse a Type 1 fonts very */ + /* quickly. */ + /* */ + /* <Fields> */ + /* root :: The root PS_ParserRec fields. */ + /* */ + /* stream :: The current input stream. */ + /* */ + /* postscript :: A pointer to the data to be parsed. */ + /* */ + /* postscript_len :: The length of the data to be parsed. */ + /* */ + /* data_offset :: The start position of the binary data (i.e., the */ + /* end of the data to be parsed. */ + /* */ + /* binary_length :: The length of the data after the `StartData' */ + /* command if the data format is hexadecimal. */ + /* */ + /* cid :: A structure which holds the information about */ + /* the current font. */ + /* */ + /* num_dict :: The number of font dictionaries. */ + /* */ + typedef struct CID_Parser_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* postscript; + FT_Long postscript_len; + + FT_ULong data_offset; + + FT_Long binary_length; + + CID_FaceInfo cid; + FT_Int num_dict; + + } CID_Parser; + + + FT_LOCAL( FT_Error ) + cid_parser_new( CID_Parser* parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( void ) + cid_parser_done( CID_Parser* parser ); + + + /*************************************************************************/ + /* */ + /* PARSING ROUTINES */ + /* */ + /*************************************************************************/ + +#define cid_parser_skip_spaces( p ) \ + (p)->root.funcs.skip_spaces( &(p)->root ) +#define cid_parser_skip_PS_token( p ) \ + (p)->root.funcs.skip_PS_token( &(p)->root ) + +#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) +#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) + +#define cid_parser_to_coord_array( p, m, c ) \ + (p)->root.funcs.to_coord_array( &(p)->root, m, c ) +#define cid_parser_to_fixed_array( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define cid_parser_to_token( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) +#define cid_parser_to_token_array( p, t, m, c ) \ + (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) + +#define cid_parser_load_field( p, f, o ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 ) +#define cid_parser_load_field_table( p, f, o ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 ) + + +FT_END_HEADER + +#endif /* __CIDPARSE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cid/cidriver.c b/drivers/freetype/src/cid/cidriver.c new file mode 100644 index 0000000000..6132a27763 --- /dev/null +++ b/drivers/freetype/src/cid/cidriver.c @@ -0,0 +1,236 @@ +/***************************************************************************/ +/* */ +/* cidriver.c */ +/* */ +/* CID driver interface (body). */ +/* */ +/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 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 "cidriver.h" +#include "cidgload.h" +#include FT_INTERNAL_DEBUG_H + +#include "ciderrs.h" + +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_CID_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_ciddriver + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + cid_get_postscript_name( CID_Face face ) + { + const char* result = face->cid.cid_font_name; + + + if ( result && result[0] == '/' ) + result++; + + return result; + } + + + static const FT_Service_PsFontNameRec cid_service_ps_name = + { + (FT_PsName_GetFunc) cid_get_postscript_name + }; + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + cid_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((CID_Face)face)->cid.font_info; + + return FT_Err_Ok; + } + + static FT_Error + cid_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((CID_Face)face)->font_extra; + + return FT_Err_Ok; + } + + static const FT_Service_PsInfoRec cid_service_ps_info = + { + (PS_GetFontInfoFunc) cid_ps_get_font_info, + (PS_GetFontExtraFunc) cid_ps_get_font_extra, + (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ + (PS_GetFontPrivateFunc)NULL, /* unsupported */ + (PS_GetFontValueFunc) NULL /* not implemented */ + }; + + + /* + * CID INFO SERVICE + * + */ + static FT_Error + cid_get_ros( CID_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + CID_FaceInfo cid = &face->cid; + + + if ( registry ) + *registry = cid->registry; + + if ( ordering ) + *ordering = cid->ordering; + + if ( supplement ) + *supplement = cid->supplement; + + return FT_Err_Ok; + } + + + static FT_Error + cid_get_is_cid( CID_Face face, + FT_Bool *is_cid ) + { + FT_Error error = FT_Err_Ok; + FT_UNUSED( face ); + + + if ( is_cid ) + *is_cid = 1; /* cid driver is only used for CID keyed fonts */ + + return error; + } + + + static FT_Error + cid_get_cid_from_glyph_index( CID_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = FT_Err_Ok; + FT_UNUSED( face ); + + + if ( cid ) + *cid = glyph_index; /* identity mapping */ + + return error; + } + + + static const FT_Service_CIDRec cid_service_cid_info = + { + (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index + }; + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec cid_services[] = + { + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, + { FT_SERVICE_ID_CID, &cid_service_cid_info }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + cid_get_interface( FT_Module module, + const char* cid_interface ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( cid_services, cid_interface ); + } + + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec t1cid_driver_class = + { + /* first of all, the FT_Module_Class fields */ + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, + + sizeof ( FT_DriverRec ), + "t1cid", /* module name */ + 0x10000L, /* version 1.0 of driver */ + 0x20000L, /* requires FreeType 2.0 */ + + 0, + + cid_driver_init, + cid_driver_done, + cid_get_interface + }, + + /* then the other font drivers fields */ + sizeof ( CID_FaceRec ), + sizeof ( CID_SizeRec ), + sizeof ( CID_GlyphSlotRec ), + + cid_face_init, + cid_face_done, + + cid_size_init, + cid_size_done, + cid_slot_init, + cid_slot_done, + + cid_slot_load_glyph, + + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ + + 0, /* FT_Face_GetAdvancesFunc */ + + cid_size_request, + 0 /* FT_Size_SelectFunc */ + }; + + +/* END */ diff --git a/drivers/freetype/src/cid/cidriver.h b/drivers/freetype/src/cid/cidriver.h new file mode 100644 index 0000000000..3c45e06886 --- /dev/null +++ b/drivers/freetype/src/cid/cidriver.h @@ -0,0 +1,43 @@ +/***************************************************************************/ +/* */ +/* cidriver.h */ +/* */ +/* High-level CID driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CIDRIVER_H__ +#define __CIDRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_CALLBACK_TABLE + const FT_Driver_ClassRec t1cid_driver_class; + + +FT_END_HEADER + +#endif /* __CIDRIVER_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/cid/cidtoken.h b/drivers/freetype/src/cid/cidtoken.h new file mode 100644 index 0000000000..904cb09cf4 --- /dev/null +++ b/drivers/freetype/src/cid/cidtoken.h @@ -0,0 +1,112 @@ +/***************************************************************************/ +/* */ +/* cidtoken.h */ +/* */ +/* CID token definitions (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 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. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CID_FaceInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_CID_INFO + + T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 ) + T1_FIELD_FIXED ( "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 +#define FT_STRUCTURE PS_FontInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + 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 +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, 0 ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CID_FaceDictRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + 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( "StrokeWidth", stroke_width, 0 ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_PrivateRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_PRIVATE + + 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, 0 ) + T1_FIELD_NUM ( "BlueShift", blue_shift, 0 ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, 0 ) + + 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, 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, 0 ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 ) + + T1_FIELD_BOOL ( "ForceBold", force_bold, 0 ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX + + T1_FIELD_BBOX( "FontBBox", xMin, 0 ) + + +/* END */ diff --git a/drivers/freetype/src/cid/module.mk b/drivers/freetype/src/cid/module.mk new file mode 100644 index 0000000000..ce30bfd7ae --- /dev/null +++ b/drivers/freetype/src/cid/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 CID module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += TYPE1CID_DRIVER + +define TYPE1CID_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, t1cid_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/cid/rules.mk b/drivers/freetype/src/cid/rules.mk new file mode 100644 index 0000000000..f362744612 --- /dev/null +++ b/drivers/freetype/src/cid/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 CID driver configuration rules +# + + +# Copyright 1996-2000, 2001, 2003 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. + + +# CID driver directory +# +CID_DIR := $(SRC_DIR)/cid + + +CID_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CID_DIR)) + + +# CID driver sources (i.e., C files) +# +CID_DRV_SRC := $(CID_DIR)/cidparse.c \ + $(CID_DIR)/cidload.c \ + $(CID_DIR)/cidriver.c \ + $(CID_DIR)/cidgload.c \ + $(CID_DIR)/cidobjs.c + +# CID driver headers +# +CID_DRV_H := $(CID_DRV_SRC:%.c=%.h) \ + $(CID_DIR)/cidtoken.h \ + $(CID_DIR)/ciderrs.h + + +# CID driver object(s) +# +# CID_DRV_OBJ_M is used during `multi' builds +# CID_DRV_OBJ_S is used during `single' builds +# +CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR)/%.c=$(OBJ_DIR)/%.$O) +CID_DRV_OBJ_S := $(OBJ_DIR)/type1cid.$O + +# CID driver source file for single build +# +CID_DRV_SRC_S := $(CID_DIR)/type1cid.c + + +# CID driver - single object +# +$(CID_DRV_OBJ_S): $(CID_DRV_SRC_S) $(CID_DRV_SRC) $(FREETYPE_H) $(CID_DRV_H) + $(CID_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CID_DRV_SRC_S)) + + +# CID driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(CID_DIR)/%.c $(FREETYPE_H) $(CID_DRV_H) + $(CID_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(CID_DRV_OBJ_S) +DRV_OBJS_M += $(CID_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/cid/type1cid.c b/drivers/freetype/src/cid/type1cid.c new file mode 100644 index 0000000000..0b866e97c4 --- /dev/null +++ b/drivers/freetype/src/cid/type1cid.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* type1cid.c */ +/* */ +/* FreeType OpenType driver component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "cidparse.c" +#include "cidload.c" +#include "cidobjs.c" +#include "cidriver.c" +#include "cidgload.c" + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/Jamfile b/drivers/freetype/src/gxvalid/Jamfile new file mode 100644 index 0000000000..88049a625d --- /dev/null +++ b/drivers/freetype/src/gxvalid/Jamfile @@ -0,0 +1,33 @@ +# FreeType 2 src/gxvalid Jamfile +# +# Copyright 2005 by +# suzuki toshiya, Masatake YAMATO and Red Hat K.K. +# +# 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) gxvalid ; + + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = gxvcommn gxvfeat gxvbsln gxvtrak gxvopbd gxvprop + gxvmort gxvmort0 gxvmort1 gxvmort2 gxvmort4 gxvmort5 + gxvmorx gxvmorx0 gxvmorx1 gxvmorx2 gxvmorx4 gxvmorx5 + gxvlcar gxvkern gxvmod gxvjust ; + } + else + { + _sources = gxvalid ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/gxvalid Jamfile diff --git a/drivers/freetype/src/gxvalid/README b/drivers/freetype/src/gxvalid/README new file mode 100644 index 0000000000..28e535b0bc --- /dev/null +++ b/drivers/freetype/src/gxvalid/README @@ -0,0 +1,532 @@ +gxvalid: TrueType GX validator +============================== + + +1. What is this +--------------- + + `gxvalid' is a module to validate TrueType GX tables: a collection of + additional tables in TrueType font which are used by `QuickDraw GX + Text', Apple Advanced Typography (AAT). In addition, gxvalid can + validates `kern' tables which have been extended for AAT. Like the + otvalid module, gxvalid uses Freetype 2's validator framework + (ftvalid). + + You can link gxvalid with your program; before running your own layout + engine, gxvalid validates a font file. As the result, you can remove + error-checking code from the layout engine. It is also possible to + use gxvalid as a stand-alone font validator; the `ftvalid' test + program included in the ft2demo bundle calls gxvalid internally. + A stand-alone font validator may be useful for font developers. + + This documents documents the following issues. + + - supported TrueType GX tables + - fundamental validation limitations + - permissive error handling of broken GX tables + - `kern' table issue. + + +2. Supported tables +------------------- + + The following GX tables are currently supported. + + bsln + feat + just + kern(*) + lcar + mort + morx + opbd + prop + trak + + The following GX tables are currently unsupported. + + cvar + fdsc + fmtx + fvar + gvar + Zapf + + The following GX tables won't be supported. + + acnt(**) + hsty(***) + + The following undocumented tables in TrueType fonts designed for Apple + platform aren't handled either. + + addg + CVTM + TPNM + umif + + + *) The `kern' validator handles both the classic and the new kern + formats; the former is supported on both Microsoft and Apple + platforms, while the latter is supported on Apple platforms. + + **) `acnt' tables are not supported by currently available Apple font + tools. + + ***) There is one more Apple extension, `hsty', but it is for + Newton-OS, not GX (Newton-OS is a platform by Apple, but it can + use sfnt- housed bitmap fonts only). Therefore, it should be + excluded from `Apple platform' in the context of TrueType. + gxvalid ignores it as Apple font tools do so. + + + We have checked 183 fonts bundled with MacOS 9.1, MacOS 9.2, MacOS + 10.0, MacOS X 10.1, MSIE for MacOS, and AppleWorks 6.0. In addition, + we have checked 67 Dynalab fonts (designed for MacOS) and 189 Ricoh + fonts (designed for Windows and MacOS dual platforms). The number of + fonts including TrueType GX tables are as follows. + + bsln: 76 + feat: 191 + just: 84 + kern: 59 + lcar: 4 + mort: 326 + morx: 19 + opbd: 4 + prop: 114 + trak: 16 + + Dynalab and Ricoh fonts don't have GX tables except of `feat' and + `mort'. + + +3. Fundamental validation limitations +------------------------------------- + + TrueType GX provides layout information to libraries for font + rasterizers and text layout. gxvalid can check whether the layout + data in a font is conformant to the TrueType GX format specified by + Apple. But gxvalid cannot check a how QuickDraw GX/AAT renderer uses + the stored information. + + 3-1. Validation of State Machine activity + ----------------------------------------- + + QuickDraw GX/AAT uses a `State Machine' to provide `stateful' layout + features, and TrueType GX stores the state transition diagram of + this `State Machine' in a `StateTable' data structure. While the + State Machine receives a series of glyph IDs, the State Machine + starts with `start of text' state, walks around various states and + generates various layout information to the renderer, and finally + reaches the `end of text' state. + + gxvalid can check essential errors like: + + - possibility of state transitions to undefined states + - existence of glyph IDs that the State Machine doesn't know how + to handle + - the State Machine cannot compute the layout information from + given diagram + + These errors can be checked within finite steps, and without the + State Machine itself, because these are `expression' errors of state + transition diagram. + + There is no limitation about how long the State Machine walks + around, so validation of the algorithm in the state transition + diagram requires infinite steps, even if we had a State Machine in + gxvalid. Therefore, the following errors and problems cannot be + checked. + + - existence of states which the State Machine never transits to + - the possibility that the State Machine never reaches `end of + text' + - the possibility of stack underflow/overflow in the State Machine + (in ligature and contextual glyph substitutions, the State + Machine can store 16 glyphs onto its stack) + + In addition, gxvalid doesn't check `temporary glyph IDs' used in the + chained State Machines (in `mort' and `morx' tables). If a layout + feature is implemented by a single State Machine, a glyph ID + converted by the State Machine is passed to the glyph renderer, thus + it should not point to an undefined glyph ID. But if a layout + feature is implemented by chained State Machines, a component State + Machine (if it is not the final one) is permitted to generate + undefined glyph IDs for temporary use, because it is handled by next + component State Machine and not by the glyph renderer. To validate + such temporary glyph IDs, gxvalid must stack all undefined glyph IDs + which can occur in the output of the previous State Machine and + search them in the `ClassTable' structure of the current State + Machine. It is too complex to list all possible glyph IDs from the + StateTable, especially from a ligature substitution table. + + 3-2. Validation of relationship between multiple layout features + ---------------------------------------------------------------- + + gxvalid does not validate the relationship between multiple layout + features at all. + + If multiple layout features are defined in TrueType GX tables, + possible interactions, overrides, and conflicts between layout + features are implicitly given in the font too. For example, there + are several predefined spacing control features: + + - Text Spacing (Proportional/Monospace/Half-width/Normal) + - Number Spacing (Monospaced-numbers/Proportional-numbers) + - Kana Spacing (Full-width/Proportional) + - Ideographic Spacing (Full-width/Proportional) + - CJK Roman Spacing (Half-width/Proportional/Default-roman + /Full-width-roman/Proportional) + + If all layout features are independently managed, we can activate + inconsistent typographic rules like `Text Spacing=Monospace' and + `Ideographic Spacing=Proportional' at the same time. + + The combinations of layout features is managed by a 32bit integer + (one bit each for selector setting), so we can define relationships + between up to 32 features, theoretically. But if one feature + setting affects another feature setting, we need typographic + priority rules to validate the relationship. Unfortunately, the + TrueType GX format specification does not give such information even + for predefined features. + + +4. Permissive error handling of broken GX tables +------------------------------------------------ + + When Apple's font rendering system finds an inconsistency, like a + specification violation or an unspecified value in a TrueType GX + table, it does not always return error. In most cases, the rendering + engine silently ignores such wrong values or even whole tables. In + fact, MacOS is shipped with fonts including broken GX/AAT tables, but + no harmful effects due to `officially broken' fonts are observed by + end-users. + + gxvalid is designed to continue the validation process as long as + possible. When gxvalid find wrong values, gxvalid warns it at least, + and takes a fallback procedure if possible. The fallback procedure + depends on the debug level. + + We used the following three tools to investigate Apple's error handling. + + - FontValidator (for MacOS 8.5 - 9.2) resource fork font + - ftxvalidator (for MacOS X 10.1 -) dfont or naked-sfnt + - ftxdumperfuser (for MacOS X 10.1 -) dfont or naked-sfnt + + However, all tests were done on a PowerPC based Macintosh; at present, + we have not checked those tools on a m68k-based Macintosh. + + In total, we checked 183 fonts bundled to MacOS 9.1, MacOS 9.2, MacOS + 10.0, MacOS X 10.1, MSIE for MacOS, and AppleWorks 6.0. These fonts + are distributed officially, but many broken GX/AAT tables were found + by Apple's font tools. In the following, we list typical violation of + the GX specification, in fonts officially distributed with those Apple + systems. + + 4-1. broken BinSrchHeader (19/183) + ---------------------------------- + + `BinSrchHeader' is a header of a data array for m68k platforms to + access memory efficiently. Although there are only two independent + parameters for real (`unitSize' and `nUnits'), BinSrchHeader has + three additional parameters which can be calculated from `unitSize' + and `nUnits', for fast setup. Apple font tools ignore them + silently, so gxvalid warns if it finds and inconsistency, and always + continues validation. The additional parameters are ignored + regardless of the consistency. + + 19 fonts include such inconsistencies; all breaks are in the + BinSrchHeader structure of the `kern' table. + + 4-2. too-short LookupTable (5/183) + ---------------------------------- + + LookupTable format 0 is a simple array to get a value from a given + GID (glyph ID); the index of this array is a GID too. Therefore, + the length of the array is expected to be same as the maximum GID + value defined in the `maxp' table, but there are some fonts whose + LookupTable format 0 is too short to cover all GIDs. FontValidator + ignores this error silently, ftxvalidator and ftxdumperfuser both + warn and continue. Similar problems are found in format 3 subtables + of `kern'. gxvalid warns always and abort if the validation level + is set to FT_VALIDATE_PARANOID. + + 5 fonts include too-short kern format 0 subtables. + 1 font includes too-short kern format 3 subtable. + + 4-3. broken LookupTable format 2 (1/183) + ---------------------------------------- + + LookupTable format 2, subformat 4 covers the GID space by a + collection of segments which are specified by `firstGlyph' and + `lastGlyph'. Some fonts store `firstGlyph' and `lastGlyph' in + reverse order, so the segment specification is broken. Apple font + tools ignore this error silently; a broken segment is ignored as if + it did not exist. gxvalid warns and normalize the segment at + FT_VALIDATE_DEFAULT, or ignore the segment at FT_VALIDATE_TIGHT, or + abort at FT_VALIDATE_PARANOID. + + 1 font includes broken LookupTable format 2, in the `just' table. + + *) It seems that all fonts manufactured by ITC for AppleWorks have + this error. + + 4-4. bad bracketing in glyph property (14/183) + ---------------------------------------------- + + GX/AAT defines a `bracketing' property of the glyphs in the `prop' + table, to control layout features of strings enclosed inside and + outside of brackets. Some fonts give inappropriate bracket + properties to glyphs. Apple font tools warn about this error; + gxvalid warns too and aborts at FT_VALIDATE_PARANOID. + + 14 fonts include wrong bracket properties. + + + 4-5. invalid feature number (117/183) + ------------------------------------- + + The GX/AAT extension can include 255 different layout features, but + popular layout features are predefined (see + http://developer.apple.com/fonts/Registry/index.html). Some fonts + include feature numbers which are incompatible with the predefined + feature registry. + + In our survey, there are 140 fonts including `feat' table. + + a) 67 fonts use a feature number which should not be used. + b) 117 fonts set the wrong feature range (nSetting). This is mostly + found in the `mort' and `morx' tables. + + Apple font tools give no warning, although they cannot recognize + what the feature is. At FT_VALIDATE_DEFAULT, gxvalid warns but + continues in both cases (a, b). At FT_VALIDATE_TIGHT, gxvalid warns + and aborts for (a), but continues for (b). At FT_VALIDATE_PARANOID, + gxvalid warns and aborts in both cases (a, b). + + 4-6. invalid prop version (10/183) + ---------------------------------- + + As most TrueType GX tables, the `prop' table must start with a 32bit + version identifier: 0x00010000, 0x00020000 or 0x00030000. But some + fonts store nonsense binary data instead. When Apple font tools + find them, they abort the processing immediately, and the data which + follows is unhandled. gxvalid does the same. + + 10 fonts include broken `prop' version. + + All of these fonts are classic TrueType fonts for the Japanese + script, manufactured by Apple. + + 4-7. unknown resource name (2/183) + ------------------------------------ + + NOTE: THIS IS NOT A TRUETYPE GX ERROR. + + If a TrueType font is stored in the resource fork or in dfont + format, the data must be tagged as `sfnt' in the resource fork index + to invoke TrueType font handler for the data. But the TrueType font + data in `Keyboard.dfont' is tagged as `kbd', and that in + `LastResort.dfont' is tagged as `lst'. Apple font tools can detect + that the data is in TrueType format and successfully validate them. + Maybe this is possible because they are known to be dfont. The + current implementation of the resource fork driver of FreeType + cannot do that, thus gxvalid cannot validate them. + + 2 fonts use an unknown tag for the TrueType font resource. + +5. `kern' table issues +---------------------- + + In common terminology of TrueType, `kern' is classified as a basic and + platform-independent table. But there are Apple extensions of `kern', + and there is an extension which requires a GX state machine for + contextual kerning. Therefore, gxvalid includes a special validator + for `kern' tables. Unfortunately, there is no exact algorithm to + check Apple's extension, so gxvalid includes a heuristic algorithm to + find the proper validation routines for all possible data formats, + including the data format for Microsoft. By calling + classic_kern_validate() instead of gxv_validate(), you can specify the + `kern' format explicitly. However, current FreeType2 uses Microsoft + `kern' format only, others are ignored (and should be handled in a + library one level higher than FreeType). + + 5-1. History + ------------ + + The original 16bit version of `kern' was designed by Apple in the + pre-GX era, and it was also approved by Microsoft. Afterwards, + Apple designed a new 32bit version of the `kern' table. According + to the documentation, the difference between the 16bit and 32bit + version is only the size of variables in the `kern' header. In the + following, we call the original 16bit version as `classic', and + 32bit version as `new'. + + 5-2. Versions and dialects which should be differentiated + --------------------------------------------------------- + + The `kern' table consists of a table header and several subtables. + The version number which identifies a `classic' or a `new' version + is explicitly written in the table header, but there are + undocumented differences between Microsoft's and Apple's formats. + It is called a `dialect' in the following. There are three cases + which should be handled: the new Apple-dialect, the classic + Apple-dialect, and the classic Microsoft-dialect. An analysis of + the formats and the auto detection algorithm of gxvalid is described + in the following. + + 5-2-1. Version detection: classic and new kern + ---------------------------------------------- + + According to Apple TrueType specification, there are only two + differences between the classic and the new: + + - The `kern' table header starts with the version number. + The classic version starts with 0x0000 (16bit), + the new version starts with 0x00010000 (32bit). + + - In the `kern' table header, the number of subtables follows + the version number. + In the classic version, it is stored as a 16bit value. + In the new version, it is stored as a 32bit value. + + From Apple font tool's output (DumpKERN is also tested in addition + to the three Apple font tools in above), there is another + undocumented difference. In the new version, the subtable header + includes a 16bit variable named `tupleIndex' which does not exist + in the classic version. + + The new version can store all subtable formats (0, 1, 2, and 3), + but the Apple TrueType specification does not mention the subtable + formats available in the classic version. + + 5-2-2. Available subtable formats in classic version + ---------------------------------------------------- + + Although the Apple TrueType specification recommends to use the + classic version in the case if the font is designed for both the + Apple and Microsoft platforms, it does not document the available + subtable formats in the classic version. + + According to the Microsoft TrueType specification, the subtable + format assured for Windows and OS/2 support is only subtable + format 0. The Microsoft TrueType specification also describes + subtable format 2, but does not mention which platforms support + it. Aubtable formats 1, 3, and higher are documented as reserved + for future use. Therefore, the classic version can store subtable + formats 0 and 2, at least. `ttfdump.exe', a font tool provided by + Microsoft, ignores the subtable format written in the subtable + header, and parses the table as if all subtables are in format 0. + + `kern' subtable format 1 uses a StateTable, so it cannot be + utilized without a GX State Machine. Therefore, it is reasonable + to assume that format 1 (and 3) were introduced after Apple had + introduced GX and moved to the new 32bit version. + + 5-2-3. Apple and Microsoft dialects + ----------------------------------- + + The `kern' subtable has a 16bit `coverage' field to describe + kerning attributes, but bit interpretations by Apple and Microsoft + are different: For example, Apple uses bits 0-7 to identify the + subtable, while Microsoft uses bits 8-15. + + In addition, due to the output of DumpKERN and FontValidator, + Apple's bit interpretations of coverage in classic and new version + are incompatible also. In summary, there are three dialects: + classic Apple dialect, classic Microsoft dialect, and new Apple + dialect. The classic Microsoft dialect and the new Apple dialect + are documented by each vendors' TrueType font specification, but + the documentation for classic Apple dialect is not available. + + For example, in the new Apple dialect, bit 15 is documented as + `set to 1 if the kerning is vertical'. On the other hand, in + classic Microsoft dialect, bit 1 is documented as `set to 1 if the + kerning is horizontal'. From the outputs of DumpKERN and + FontValidator, classic Apple dialect recognizes 15 as `set to 1 + when the kerning is horizontal'. From the results of similar + experiments, classic Apple dialect seems to be the Endian reverse + of the classic Microsoft dialect. + + As a conclusion it must be noted that no font tool can identify + classic Apple dialect or classic Microsoft dialect automatically. + + 5-2-4. gxvalid auto dialect detection algorithm + ----------------------------------------------- + + The first 16 bits of the `kern' table are enough to identify the + version: + + - if the first 16 bits are 0x0000, the `kern' table is in + classic Apple dialect or classic Microsoft dialect + - if the first 16 bits are 0x0001, and next 16 bits are 0x0000, + the kern table is in new Apple dialect. + + If the `kern' table is a classic one, the 16bit `coverage' field + is checked next. Firstly, the coverage bits are decoded for the + classic Apple dialect using the following bit masks (this is based + on DumpKERN output): + + 0x8000: 1=horizontal, 0=vertical + 0x4000: not used + 0x2000: 1=cross-stream, 0=normal + 0x1FF0: reserved + 0x000F: subtable format + + If any of reserved bits are set or the subtable bits is + interpreted as format 1 or 3, we take it as `impossible in classic + Apple dialect' and retry, using the classic Microsoft dialect. + + The most popular coverage in new Apple-dialect: 0x8000, + The most popular coverage in classic Apple-dialect: 0x0000, + The most popular coverage in classic Microsoft dialect: 0x0001. + + 5-3. Tested fonts + ----------------- + + We checked 59 fonts bundled with MacOS and 38 fonts bundled with + Windows, where all font include a `kern' table. + + - fonts bundled with MacOS + * new Apple dialect + format 0: 18 + format 2: 1 + format 3: 1 + * classic Apple dialect + format 0: 14 + * classic Microsoft dialect + format 0: 15 + + - fonts bundled with Windows + * classic Microsoft dialect + format 0: 38 + + It looks strange that classic Microsoft-dialect fonts are bundled to + MacOS: they come from MSIE for MacOS, except of MarkerFelt.dfont. + + + ACKNOWLEDGEMENT + --------------- + + Some parts of gxvalid are derived from both the `gxlayout' module and + the `otvalid' module. Development of gxlayout was supported by the + Information-technology Promotion Agency(IPA), Japan. + + The detailed analysis of undefined glyph ID utilization in `mort' and + `morx' tables is provided by George Williams. + +------------------------------------------------------------------------ + +Copyright 2004, 2005, 2007 by +suzuki toshiya, Masatake YAMATO, Red hat K.K., +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. + + +--- end of README --- diff --git a/drivers/freetype/src/gxvalid/gxvalid.c b/drivers/freetype/src/gxvalid/gxvalid.c new file mode 100644 index 0000000000..bc36e675d1 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvalid.c @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* gxvalid.c */ +/* */ +/* FreeType validator for TrueTypeGX/AAT tables (body only). */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> + +#include "gxvfeat.c" +#include "gxvcommn.c" +#include "gxvbsln.c" +#include "gxvtrak.c" +#include "gxvjust.c" +#include "gxvmort.c" +#include "gxvmort0.c" +#include "gxvmort1.c" +#include "gxvmort2.c" +#include "gxvmort4.c" +#include "gxvmort5.c" +#include "gxvmorx.c" +#include "gxvmorx0.c" +#include "gxvmorx1.c" +#include "gxvmorx2.c" +#include "gxvmorx4.c" +#include "gxvmorx5.c" +#include "gxvkern.c" +#include "gxvopbd.c" +#include "gxvprop.c" +#include "gxvlcar.c" +#include "gxvmod.c" + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvalid.h b/drivers/freetype/src/gxvalid/gxvalid.h new file mode 100644 index 0000000000..27be9ecca8 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvalid.h @@ -0,0 +1,107 @@ +/***************************************************************************/ +/* */ +/* gxvalid.h */ +/* */ +/* TrueTyeeGX/AAT table validation (specification only). */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __GXVALID_H__ +#define __GXVALID_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#include "gxverror.h" /* must come before FT_INTERNAL_VALIDATE_H */ + +#include FT_INTERNAL_VALIDATE_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + gxv_feat_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + + FT_LOCAL( void ) + gxv_bsln_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + + FT_LOCAL( void ) + gxv_trak_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + FT_LOCAL( void ) + gxv_just_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + FT_LOCAL( void ) + gxv_mort_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + FT_LOCAL( void ) + gxv_morx_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + FT_LOCAL( void ) + gxv_kern_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + FT_LOCAL( void ) + gxv_kern_validate_classic( FT_Bytes table, + FT_Face face, + FT_Int dialect_flags, + FT_Validator valid ); + + FT_LOCAL( void ) + gxv_opbd_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + FT_LOCAL( void ) + gxv_prop_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + FT_LOCAL( void ) + gxv_lcar_validate( FT_Bytes table, + FT_Face face, + FT_Validator valid ); + + +FT_END_HEADER + + +#endif /* __GXVALID_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvbsln.c b/drivers/freetype/src/gxvalid/gxvbsln.c new file mode 100644 index 0000000000..3d10031563 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvbsln.c @@ -0,0 +1,333 @@ +/***************************************************************************/ +/* */ +/* gxvbsln.c */ +/* */ +/* TrueTypeGX/AAT bsln table validation (body). */ +/* */ +/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvalid.h" +#include "gxvcommn.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_gxvbsln + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Data and Types *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define GXV_BSLN_VALUE_COUNT 32 +#define GXV_BSLN_VALUE_EMPTY 0xFFFFU + + + typedef struct GXV_bsln_DataRec_ + { + FT_Bytes ctlPoints_p; + FT_UShort defaultBaseline; + + } GXV_bsln_DataRec, *GXV_bsln_Data; + + +#define GXV_BSLN_DATA( field ) GXV_TABLE_DATA( bsln, field ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + gxv_bsln_LookupValue_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + FT_UShort v = value_p->u; + FT_UShort* ctlPoints; + + FT_UNUSED( glyph ); + + + GXV_NAME_ENTER( "lookup value" ); + + if ( v >= GXV_BSLN_VALUE_COUNT ) + FT_INVALID_DATA; + + ctlPoints = (FT_UShort*)GXV_BSLN_DATA( ctlPoints_p ); + if ( ctlPoints && ctlPoints[v] == GXV_BSLN_VALUE_EMPTY ) + FT_INVALID_DATA; + + GXV_EXIT; + } + + + /* + +===============+ --------+ + | lookup header | | + +===============+ | + | BinSrchHeader | | + +===============+ | + | lastGlyph[0] | | + +---------------+ | + | firstGlyph[0] | | head of lookup table + +---------------+ | + + | offset[0] | -> | offset [byte] + +===============+ | + + | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] + +---------------+ | + | firstGlyph[1] | | + +---------------+ | + | offset[1] | | + +===============+ | + | + ... | + | + 16bit value array | + +===============+ | + | value | <-------+ + ... + */ + + static GXV_LookupValueDesc + gxv_bsln_LookupFmt4_transit( FT_UShort relative_gindex, + GXV_LookupValueCPtr base_value_p, + FT_Bytes lookuptbl_limit, + GXV_Validator valid ) + { + FT_Bytes p; + FT_Bytes limit; + FT_UShort offset; + GXV_LookupValueDesc value; + + /* XXX: check range ? */ + offset = (FT_UShort)( base_value_p->u + + ( relative_gindex * sizeof ( FT_UShort ) ) ); + + p = valid->lookuptbl_head + offset; + limit = lookuptbl_limit; + GXV_LIMIT_CHECK( 2 ); + + value.u = FT_NEXT_USHORT( p ); + + return value; + } + + + static void + gxv_bsln_parts_fmt0_validate( FT_Bytes tables, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = tables; + + + GXV_NAME_ENTER( "parts format 0" ); + + /* deltas */ + GXV_LIMIT_CHECK( 2 * GXV_BSLN_VALUE_COUNT ); + + valid->table_data = NULL; /* No ctlPoints here. */ + + GXV_EXIT; + } + + + static void + gxv_bsln_parts_fmt1_validate( FT_Bytes tables, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = tables; + + + GXV_NAME_ENTER( "parts format 1" ); + + /* deltas */ + gxv_bsln_parts_fmt0_validate( p, limit, valid ); + + /* mappingData */ + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_bsln_LookupValue_validate; + valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; + gxv_LookupTable_validate( p + 2 * GXV_BSLN_VALUE_COUNT, + limit, + valid ); + + GXV_EXIT; + } + + + static void + gxv_bsln_parts_fmt2_validate( FT_Bytes tables, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = tables; + + FT_UShort stdGlyph; + FT_UShort ctlPoint; + FT_Int i; + + FT_UShort defaultBaseline = GXV_BSLN_DATA( defaultBaseline ); + + + GXV_NAME_ENTER( "parts format 2" ); + + GXV_LIMIT_CHECK( 2 + ( 2 * GXV_BSLN_VALUE_COUNT ) ); + + /* stdGlyph */ + stdGlyph = FT_NEXT_USHORT( p ); + GXV_TRACE(( " (stdGlyph = %u)\n", stdGlyph )); + + gxv_glyphid_validate( stdGlyph, valid ); + + /* Record the position of ctlPoints */ + GXV_BSLN_DATA( ctlPoints_p ) = p; + + /* ctlPoints */ + for ( i = 0; i < GXV_BSLN_VALUE_COUNT; i++ ) + { + ctlPoint = FT_NEXT_USHORT( p ); + if ( ctlPoint == GXV_BSLN_VALUE_EMPTY ) + { + if ( i == defaultBaseline ) + FT_INVALID_DATA; + } + else + gxv_ctlPoint_validate( stdGlyph, (FT_Short)ctlPoint, valid ); + } + + GXV_EXIT; + } + + + static void + gxv_bsln_parts_fmt3_validate( FT_Bytes tables, + FT_Bytes limit, + GXV_Validator valid) + { + FT_Bytes p = tables; + + + GXV_NAME_ENTER( "parts format 3" ); + + /* stdGlyph + ctlPoints */ + gxv_bsln_parts_fmt2_validate( p, limit, valid ); + + /* mappingData */ + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_bsln_LookupValue_validate; + valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; + gxv_LookupTable_validate( p + ( 2 + 2 * GXV_BSLN_VALUE_COUNT ), + limit, + valid ); + + GXV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** bsln TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + gxv_bsln_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + + GXV_bsln_DataRec bslnrec; + GXV_bsln_Data bsln = &bslnrec; + + FT_Bytes p = table; + FT_Bytes limit = 0; + + FT_ULong version; + FT_UShort format; + FT_UShort defaultBaseline; + + GXV_Validate_Func fmt_funcs_table [] = + { + gxv_bsln_parts_fmt0_validate, + gxv_bsln_parts_fmt1_validate, + gxv_bsln_parts_fmt2_validate, + gxv_bsln_parts_fmt3_validate, + }; + + + valid->root = ftvalid; + valid->table_data = bsln; + valid->face = face; + + FT_TRACE3(( "validating `bsln' table\n" )); + GXV_INIT; + + + GXV_LIMIT_CHECK( 4 + 2 + 2 ); + version = FT_NEXT_ULONG( p ); + format = FT_NEXT_USHORT( p ); + defaultBaseline = FT_NEXT_USHORT( p ); + + /* only version 1.0 is defined (1996) */ + if ( version != 0x00010000UL ) + FT_INVALID_FORMAT; + + /* only format 1, 2, 3 are defined (1996) */ + GXV_TRACE(( " (format = %d)\n", format )); + if ( format > 3 ) + FT_INVALID_FORMAT; + + if ( defaultBaseline > 31 ) + FT_INVALID_FORMAT; + + bsln->defaultBaseline = defaultBaseline; + + fmt_funcs_table[format]( p, limit, valid ); + + FT_TRACE4(( "\n" )); + } + + +/* arch-tag: ebe81143-fdaa-4c68-a4d1-b57227daa3bc + (do not change this comment) */ + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvcommn.c b/drivers/freetype/src/gxvalid/gxvcommn.c new file mode 100644 index 0000000000..2ac80be8c7 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvcommn.c @@ -0,0 +1,1744 @@ +/***************************************************************************/ +/* */ +/* gxvcommn.c */ +/* */ +/* TrueTypeGX/AAT common tables validation (body). */ +/* */ +/* Copyright 2004, 2005, 2009, 2010, 2013 */ +/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvcommn.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_gxvcommon + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** 16bit offset sorter *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static int + gxv_compare_ushort_offset( FT_UShort* a, + FT_UShort* b ) + { + if ( *a < *b ) + return -1; + else if ( *a > *b ) + return 1; + else + return 0; + } + + + FT_LOCAL_DEF( void ) + gxv_set_length_by_ushort_offset( FT_UShort* offset, + FT_UShort** length, + FT_UShort* buff, + FT_UInt nmemb, + FT_UShort limit, + GXV_Validator valid ) + { + FT_UInt i; + + + for ( i = 0; i < nmemb; i++ ) + *(length[i]) = 0; + + for ( i = 0; i < nmemb; i++ ) + buff[i] = offset[i]; + buff[nmemb] = limit; + + ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_UShort ), + ( int(*)(const void*, const void*) )gxv_compare_ushort_offset ); + + if ( buff[nmemb] > limit ) + FT_INVALID_OFFSET; + + for ( i = 0; i < nmemb; i++ ) + { + FT_UInt j; + + + for ( j = 0; j < nmemb; j++ ) + if ( buff[j] == offset[i] ) + break; + + if ( j == nmemb ) + FT_INVALID_OFFSET; + + *(length[i]) = (FT_UShort)( buff[j + 1] - buff[j] ); + + if ( 0 != offset[i] && 0 == *(length[i]) ) + FT_INVALID_OFFSET; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** 32bit offset sorter *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static int + gxv_compare_ulong_offset( FT_ULong* a, + FT_ULong* b ) + { + if ( *a < *b ) + return -1; + else if ( *a > *b ) + return 1; + else + return 0; + } + + + FT_LOCAL_DEF( void ) + gxv_set_length_by_ulong_offset( FT_ULong* offset, + FT_ULong** length, + FT_ULong* buff, + FT_UInt nmemb, + FT_ULong limit, + GXV_Validator valid) + { + FT_UInt i; + + + for ( i = 0; i < nmemb; i++ ) + *(length[i]) = 0; + + for ( i = 0; i < nmemb; i++ ) + buff[i] = offset[i]; + buff[nmemb] = limit; + + ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_ULong ), + ( int(*)(const void*, const void*) )gxv_compare_ulong_offset ); + + if ( buff[nmemb] > limit ) + FT_INVALID_OFFSET; + + for ( i = 0; i < nmemb; i++ ) + { + FT_UInt j; + + + for ( j = 0; j < nmemb; j++ ) + if ( buff[j] == offset[i] ) + break; + + if ( j == nmemb ) + FT_INVALID_OFFSET; + + *(length[i]) = buff[j + 1] - buff[j]; + + if ( 0 != offset[i] && 0 == *(length[i]) ) + FT_INVALID_OFFSET; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** scan value array and get min & max *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( void ) + gxv_array_getlimits_byte( FT_Bytes table, + FT_Bytes limit, + FT_Byte* min, + FT_Byte* max, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + *min = 0xFF; + *max = 0x00; + + while ( p < limit ) + { + FT_Byte val; + + + GXV_LIMIT_CHECK( 1 ); + val = FT_NEXT_BYTE( p ); + + *min = (FT_Byte)FT_MIN( *min, val ); + *max = (FT_Byte)FT_MAX( *max, val ); + } + + valid->subtable_length = p - table; + } + + + FT_LOCAL_DEF( void ) + gxv_array_getlimits_ushort( FT_Bytes table, + FT_Bytes limit, + FT_UShort* min, + FT_UShort* max, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + *min = 0xFFFFU; + *max = 0x0000; + + while ( p < limit ) + { + FT_UShort val; + + + GXV_LIMIT_CHECK( 2 ); + val = FT_NEXT_USHORT( p ); + + *min = (FT_Byte)FT_MIN( *min, val ); + *max = (FT_Byte)FT_MAX( *max, val ); + } + + valid->subtable_length = p - table; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BINSEARCHHEADER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct GXV_BinSrchHeader_ + { + FT_UShort unitSize; + FT_UShort nUnits; + FT_UShort searchRange; + FT_UShort entrySelector; + FT_UShort rangeShift; + + } GXV_BinSrchHeader; + + + static void + gxv_BinSrchHeader_check_consistency( GXV_BinSrchHeader* binSrchHeader, + GXV_Validator valid ) + { + FT_UShort searchRange; + FT_UShort entrySelector; + FT_UShort rangeShift; + + + if ( binSrchHeader->unitSize == 0 ) + FT_INVALID_DATA; + + if ( binSrchHeader->nUnits == 0 ) + { + if ( binSrchHeader->searchRange == 0 && + binSrchHeader->entrySelector == 0 && + binSrchHeader->rangeShift == 0 ) + return; + else + FT_INVALID_DATA; + } + + for ( searchRange = 1, entrySelector = 1; + ( searchRange * 2 ) <= binSrchHeader->nUnits && + searchRange < 0x8000U; + searchRange *= 2, entrySelector++ ) + ; + + entrySelector--; + searchRange = (FT_UShort)( searchRange * binSrchHeader->unitSize ); + rangeShift = (FT_UShort)( binSrchHeader->nUnits * binSrchHeader->unitSize + - searchRange ); + + if ( searchRange != binSrchHeader->searchRange || + entrySelector != binSrchHeader->entrySelector || + rangeShift != binSrchHeader->rangeShift ) + { + GXV_TRACE(( "Inconsistency found in BinSrchHeader\n" )); + GXV_TRACE(( "originally: unitSize=%d, nUnits=%d, " + "searchRange=%d, entrySelector=%d, " + "rangeShift=%d\n", + binSrchHeader->unitSize, binSrchHeader->nUnits, + binSrchHeader->searchRange, binSrchHeader->entrySelector, + binSrchHeader->rangeShift )); + GXV_TRACE(( "calculated: unitSize=%d, nUnits=%d, " + "searchRange=%d, entrySelector=%d, " + "rangeShift=%d\n", + binSrchHeader->unitSize, binSrchHeader->nUnits, + searchRange, entrySelector, rangeShift )); + + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + } + + + /* + * parser & validator of BinSrchHeader + * which is used in LookupTable format 2, 4, 6. + * + * Essential parameters (unitSize, nUnits) are returned by + * given pointer, others (searchRange, entrySelector, rangeShift) + * can be calculated by essential parameters, so they are just + * validated and discarded. + * + * However, wrong values in searchRange, entrySelector, rangeShift + * won't cause fatal errors, because these parameters might be + * only used in old m68k font driver in MacOS. + * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp> + */ + + FT_LOCAL_DEF( void ) + gxv_BinSrchHeader_validate( FT_Bytes table, + FT_Bytes limit, + FT_UShort* unitSize_p, + FT_UShort* nUnits_p, + GXV_Validator valid ) + { + FT_Bytes p = table; + GXV_BinSrchHeader binSrchHeader; + + + GXV_NAME_ENTER( "BinSrchHeader validate" ); + + if ( *unitSize_p == 0 ) + { + GXV_LIMIT_CHECK( 2 ); + binSrchHeader.unitSize = FT_NEXT_USHORT( p ); + } + else + binSrchHeader.unitSize = *unitSize_p; + + if ( *nUnits_p == 0 ) + { + GXV_LIMIT_CHECK( 2 ); + binSrchHeader.nUnits = FT_NEXT_USHORT( p ); + } + else + binSrchHeader.nUnits = *nUnits_p; + + GXV_LIMIT_CHECK( 2 + 2 + 2 ); + binSrchHeader.searchRange = FT_NEXT_USHORT( p ); + binSrchHeader.entrySelector = FT_NEXT_USHORT( p ); + binSrchHeader.rangeShift = FT_NEXT_USHORT( p ); + GXV_TRACE(( "nUnits %d\n", binSrchHeader.nUnits )); + + gxv_BinSrchHeader_check_consistency( &binSrchHeader, valid ); + + if ( *unitSize_p == 0 ) + *unitSize_p = binSrchHeader.unitSize; + + if ( *nUnits_p == 0 ) + *nUnits_p = binSrchHeader.nUnits; + + valid->subtable_length = p - table; + GXV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define GXV_LOOKUP_VALUE_LOAD( P, SIGNSPEC ) \ + ( P += 2, gxv_lookup_value_load( P - 2, SIGNSPEC ) ) + + static GXV_LookupValueDesc + gxv_lookup_value_load( FT_Bytes p, + int signspec ) + { + GXV_LookupValueDesc v; + + + if ( signspec == GXV_LOOKUPVALUE_UNSIGNED ) + v.u = FT_NEXT_USHORT( p ); + else + v.s = FT_NEXT_SHORT( p ); + + return v; + } + + +#define GXV_UNITSIZE_VALIDATE( FORMAT, UNITSIZE, NUNITS, CORRECTSIZE ) \ + FT_BEGIN_STMNT \ + if ( UNITSIZE != CORRECTSIZE ) \ + { \ + FT_ERROR(( "unitSize=%d differs from" \ + " expected unitSize=%d" \ + " in LookupTable %s\n", \ + UNITSIZE, CORRECTSIZE, FORMAT )); \ + if ( UNITSIZE != 0 && NUNITS != 0 ) \ + { \ + FT_ERROR(( " cannot validate anymore\n" )); \ + FT_INVALID_FORMAT; \ + } \ + else \ + FT_ERROR(( " forcibly continues\n" )); \ + } \ + FT_END_STMNT + + + /* ================= Simple Array Format 0 Lookup Table ================ */ + static void + gxv_LookupTable_fmt0_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort i; + + GXV_LookupValueDesc value; + + + GXV_NAME_ENTER( "LookupTable format 0" ); + + GXV_LIMIT_CHECK( 2 * valid->face->num_glyphs ); + + for ( i = 0; i < valid->face->num_glyphs; i++ ) + { + GXV_LIMIT_CHECK( 2 ); + if ( p + 2 >= limit ) /* some fonts have too-short fmt0 array */ + { + GXV_TRACE(( "too short, glyphs %d - %d are missing\n", + i, valid->face->num_glyphs )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + break; + } + + value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); + valid->lookupval_func( i, &value, valid ); + } + + valid->subtable_length = p - table; + GXV_EXIT; + } + + + /* ================= Segment Single Format 2 Loolup Table ============== */ + /* + * Apple spec says: + * + * To guarantee that a binary search terminates, you must include one or + * more special `end of search table' values at the end of the data to + * be searched. The number of termination values that need to be + * included is table-specific. The value that indicates binary search + * termination is 0xFFFF. + * + * The problem is that nUnits does not include this end-marker. It's + * quite difficult to discriminate whether the following 0xFFFF comes from + * the end-marker or some next data. + * + * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp> + */ + static void + gxv_LookupTable_fmt2_skip_endmarkers( FT_Bytes table, + FT_UShort unitSize, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + while ( ( p + 4 ) < valid->root->limit ) + { + if ( p[0] != 0xFF || p[1] != 0xFF || /* lastGlyph */ + p[2] != 0xFF || p[3] != 0xFF ) /* firstGlyph */ + break; + p += unitSize; + } + + valid->subtable_length = p - table; + } + + + static void + gxv_LookupTable_fmt2_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort gid; + + FT_UShort unitSize; + FT_UShort nUnits; + FT_UShort unit; + FT_UShort lastGlyph; + FT_UShort firstGlyph; + GXV_LookupValueDesc value; + + + GXV_NAME_ENTER( "LookupTable format 2" ); + + unitSize = nUnits = 0; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); + p += valid->subtable_length; + + GXV_UNITSIZE_VALIDATE( "format2", unitSize, nUnits, 6 ); + + for ( unit = 0, gid = 0; unit < nUnits; unit++ ) + { + GXV_LIMIT_CHECK( 2 + 2 + 2 ); + lastGlyph = FT_NEXT_USHORT( p ); + firstGlyph = FT_NEXT_USHORT( p ); + value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); + + gxv_glyphid_validate( firstGlyph, valid ); + gxv_glyphid_validate( lastGlyph, valid ); + + if ( lastGlyph < gid ) + { + GXV_TRACE(( "reverse ordered segment specification:" + " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n", + unit, lastGlyph, unit - 1 , gid )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + + if ( lastGlyph < firstGlyph ) + { + GXV_TRACE(( "reverse ordered range specification at unit %d:", + " lastGlyph %d < firstGlyph %d ", + unit, lastGlyph, firstGlyph )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + + if ( valid->root->level == FT_VALIDATE_TIGHT ) + continue; /* ftxvalidator silently skips such an entry */ + + FT_TRACE4(( "continuing with exchanged values\n" )); + gid = firstGlyph; + firstGlyph = lastGlyph; + lastGlyph = gid; + } + + for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) + valid->lookupval_func( gid, &value, valid ); + } + + gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); + p += valid->subtable_length; + + valid->subtable_length = p - table; + GXV_EXIT; + } + + + /* ================= Segment Array Format 4 Lookup Table =============== */ + static void + gxv_LookupTable_fmt4_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort unit; + FT_UShort gid; + + FT_UShort unitSize; + FT_UShort nUnits; + FT_UShort lastGlyph; + FT_UShort firstGlyph; + GXV_LookupValueDesc base_value; + GXV_LookupValueDesc value; + + + GXV_NAME_ENTER( "LookupTable format 4" ); + + unitSize = nUnits = 0; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); + p += valid->subtable_length; + + GXV_UNITSIZE_VALIDATE( "format4", unitSize, nUnits, 6 ); + + for ( unit = 0, gid = 0; unit < nUnits; unit++ ) + { + GXV_LIMIT_CHECK( 2 + 2 ); + lastGlyph = FT_NEXT_USHORT( p ); + firstGlyph = FT_NEXT_USHORT( p ); + + gxv_glyphid_validate( firstGlyph, valid ); + gxv_glyphid_validate( lastGlyph, valid ); + + if ( lastGlyph < gid ) + { + GXV_TRACE(( "reverse ordered segment specification:" + " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n", + unit, lastGlyph, unit - 1 , gid )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + + if ( lastGlyph < firstGlyph ) + { + GXV_TRACE(( "reverse ordered range specification at unit %d:", + " lastGlyph %d < firstGlyph %d ", + unit, lastGlyph, firstGlyph )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + + if ( valid->root->level == FT_VALIDATE_TIGHT ) + continue; /* ftxvalidator silently skips such an entry */ + + FT_TRACE4(( "continuing with exchanged values\n" )); + gid = firstGlyph; + firstGlyph = lastGlyph; + lastGlyph = gid; + } + + GXV_LIMIT_CHECK( 2 ); + base_value = GXV_LOOKUP_VALUE_LOAD( p, GXV_LOOKUPVALUE_UNSIGNED ); + + for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) + { + value = valid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), + &base_value, + limit, + valid ); + + valid->lookupval_func( gid, &value, valid ); + } + } + + gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); + p += valid->subtable_length; + + valid->subtable_length = p - table; + GXV_EXIT; + } + + + /* ================= Segment Table Format 6 Lookup Table =============== */ + static void + gxv_LookupTable_fmt6_skip_endmarkers( FT_Bytes table, + FT_UShort unitSize, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + while ( p < valid->root->limit ) + { + if ( p[0] != 0xFF || p[1] != 0xFF ) + break; + p += unitSize; + } + + valid->subtable_length = p - table; + } + + + static void + gxv_LookupTable_fmt6_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort unit; + FT_UShort prev_glyph; + + FT_UShort unitSize; + FT_UShort nUnits; + FT_UShort glyph; + GXV_LookupValueDesc value; + + + GXV_NAME_ENTER( "LookupTable format 6" ); + + unitSize = nUnits = 0; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); + p += valid->subtable_length; + + GXV_UNITSIZE_VALIDATE( "format6", unitSize, nUnits, 4 ); + + for ( unit = 0, prev_glyph = 0; unit < nUnits; unit++ ) + { + GXV_LIMIT_CHECK( 2 + 2 ); + glyph = FT_NEXT_USHORT( p ); + value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); + + if ( gxv_glyphid_validate( glyph, valid ) ) + GXV_TRACE(( " endmarker found within defined range" + " (entry %d < nUnits=%d)\n", + unit, nUnits )); + + if ( prev_glyph > glyph ) + { + GXV_TRACE(( "current gid 0x%04x < previous gid 0x%04x\n", + glyph, prev_glyph )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + prev_glyph = glyph; + + valid->lookupval_func( glyph, &value, valid ); + } + + gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, valid ); + p += valid->subtable_length; + + valid->subtable_length = p - table; + GXV_EXIT; + } + + + /* ================= Trimmed Array Format 8 Lookup Table =============== */ + static void + gxv_LookupTable_fmt8_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort i; + + GXV_LookupValueDesc value; + FT_UShort firstGlyph; + FT_UShort glyphCount; + + + GXV_NAME_ENTER( "LookupTable format 8" ); + + /* firstGlyph + glyphCount */ + GXV_LIMIT_CHECK( 2 + 2 ); + firstGlyph = FT_NEXT_USHORT( p ); + glyphCount = FT_NEXT_USHORT( p ); + + gxv_glyphid_validate( firstGlyph, valid ); + gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), valid ); + + /* valueArray */ + for ( i = 0; i < glyphCount; i++ ) + { + GXV_LIMIT_CHECK( 2 ); + value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); + valid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, valid ); + } + + valid->subtable_length = p - table; + GXV_EXIT; + } + + + FT_LOCAL_DEF( void ) + gxv_LookupTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort format; + + GXV_Validate_Func fmt_funcs_table[] = + { + gxv_LookupTable_fmt0_validate, /* 0 */ + NULL, /* 1 */ + gxv_LookupTable_fmt2_validate, /* 2 */ + NULL, /* 3 */ + gxv_LookupTable_fmt4_validate, /* 4 */ + NULL, /* 5 */ + gxv_LookupTable_fmt6_validate, /* 6 */ + NULL, /* 7 */ + gxv_LookupTable_fmt8_validate, /* 8 */ + }; + + GXV_Validate_Func func; + + + GXV_NAME_ENTER( "LookupTable" ); + + /* lookuptbl_head may be used in fmt4 transit function. */ + valid->lookuptbl_head = table; + + /* format */ + GXV_LIMIT_CHECK( 2 ); + format = FT_NEXT_USHORT( p ); + GXV_TRACE(( " (format %d)\n", format )); + + if ( format > 8 ) + FT_INVALID_FORMAT; + + func = fmt_funcs_table[format]; + if ( func == NULL ) + FT_INVALID_FORMAT; + + func( p, limit, valid ); + p += valid->subtable_length; + + valid->subtable_length = p - table; + + GXV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Glyph ID *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Int ) + gxv_glyphid_validate( FT_UShort gid, + GXV_Validator valid ) + { + FT_Face face; + + + if ( gid == 0xFFFFU ) + { + GXV_EXIT; + return 1; + } + + face = valid->face; + if ( face->num_glyphs < gid ) + { + GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n", + face->num_glyphs, gid )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CONTROL POINT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + gxv_ctlPoint_validate( FT_UShort gid, + FT_Short ctl_point, + GXV_Validator valid ) + { + FT_Face face; + FT_Error error; + + FT_GlyphSlot glyph; + FT_Outline outline; + short n_points; + + + face = valid->face; + + error = FT_Load_Glyph( face, + gid, + FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM ); + if ( error ) + FT_INVALID_GLYPH_ID; + + glyph = face->glyph; + outline = glyph->outline; + n_points = outline.n_points; + + + if ( !( ctl_point < n_points ) ) + FT_INVALID_DATA; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SFNT NAME *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + gxv_sfntName_validate( FT_UShort name_index, + FT_UShort min_index, + FT_UShort max_index, + GXV_Validator valid ) + { + FT_SfntName name; + FT_UInt i; + FT_UInt nnames; + + + GXV_NAME_ENTER( "sfntName" ); + + if ( name_index < min_index || max_index < name_index ) + FT_INVALID_FORMAT; + + nnames = FT_Get_Sfnt_Name_Count( valid->face ); + for ( i = 0; i < nnames; i++ ) + { + if ( FT_Get_Sfnt_Name( valid->face, i, &name ) != FT_Err_Ok ) + continue ; + + if ( name.name_id == name_index ) + goto Out; + } + + GXV_TRACE(( " nameIndex = %d (UNTITLED)\n", name_index )); + FT_INVALID_DATA; + goto Exit; /* make compiler happy */ + + Out: + FT_TRACE1(( " nameIndex = %d (", name_index )); + GXV_TRACE_HEXDUMP_SFNTNAME( name ); + FT_TRACE1(( ")\n" )); + + Exit: + GXV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** STATE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* -------------------------- Class Table --------------------------- */ + + /* + * highestClass specifies how many classes are defined in this + * Class Subtable. Apple spec does not mention whether undefined + * holes in the class (e.g.: 0-3 are predefined, 4 is unused, 5 is used) + * are permitted. At present, holes in a defined class are not checked. + * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp> + */ + + static void + gxv_ClassTable_validate( FT_Bytes table, + FT_UShort* length_p, + FT_UShort stateSize, + FT_Byte* maxClassID_p, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_Bytes limit = table + *length_p; + FT_UShort firstGlyph; + FT_UShort nGlyphs; + + + GXV_NAME_ENTER( "ClassTable" ); + + *maxClassID_p = 3; /* Classes 0, 2, and 3 are predefined */ + + GXV_LIMIT_CHECK( 2 + 2 ); + firstGlyph = FT_NEXT_USHORT( p ); + nGlyphs = FT_NEXT_USHORT( p ); + + GXV_TRACE(( " (firstGlyph = %d, nGlyphs = %d)\n", firstGlyph, nGlyphs )); + + if ( !nGlyphs ) + goto Out; + + gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs ), valid ); + + { + FT_Byte nGlyphInClass[256]; + FT_Byte classID; + FT_UShort i; + + + ft_memset( nGlyphInClass, 0, 256 ); + + + for ( i = 0; i < nGlyphs; i++ ) + { + GXV_LIMIT_CHECK( 1 ); + classID = FT_NEXT_BYTE( p ); + switch ( classID ) + { + /* following classes should not appear in class array */ + case 0: /* end of text */ + case 2: /* out of bounds */ + case 3: /* end of line */ + FT_INVALID_DATA; + break; + + case 1: /* out of bounds */ + default: /* user-defined: 4 - ( stateSize - 1 ) */ + if ( classID >= stateSize ) + FT_INVALID_DATA; /* assign glyph to undefined state */ + + nGlyphInClass[classID]++; + break; + } + } + *length_p = (FT_UShort)( p - table ); + + /* scan max ClassID in use */ + for ( i = 0; i < stateSize; i++ ) + if ( ( 3 < i ) && ( nGlyphInClass[i] > 0 ) ) + *maxClassID_p = (FT_Byte)i; /* XXX: Check Range? */ + } + + Out: + GXV_TRACE(( "Declared stateSize=0x%02x, Used maxClassID=0x%02x\n", + stateSize, *maxClassID_p )); + GXV_EXIT; + } + + + /* --------------------------- State Array ----------------------------- */ + + static void + gxv_StateArray_validate( FT_Bytes table, + FT_UShort* length_p, + FT_Byte maxClassID, + FT_UShort stateSize, + FT_Byte* maxState_p, + FT_Byte* maxEntry_p, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_Bytes limit = table + *length_p; + FT_Byte clazz; + FT_Byte entry; + + FT_UNUSED( stateSize ); /* for the non-debugging case */ + + + GXV_NAME_ENTER( "StateArray" ); + + GXV_TRACE(( "parse %d bytes by stateSize=%d maxClassID=%d\n", + (int)(*length_p), stateSize, (int)(maxClassID) )); + + /* + * 2 states are predefined and must be described in StateArray: + * state 0 (start of text), 1 (start of line) + */ + GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 ); + + *maxState_p = 0; + *maxEntry_p = 0; + + /* read if enough to read another state */ + while ( p + ( 1 + maxClassID ) <= limit ) + { + (*maxState_p)++; + for ( clazz = 0; clazz <= maxClassID; clazz++ ) + { + entry = FT_NEXT_BYTE( p ); + *maxEntry_p = (FT_Byte)FT_MAX( *maxEntry_p, entry ); + } + } + GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n", + *maxState_p, *maxEntry_p )); + + *length_p = (FT_UShort)( p - table ); + + GXV_EXIT; + } + + + /* --------------------------- Entry Table ----------------------------- */ + + static void + gxv_EntryTable_validate( FT_Bytes table, + FT_UShort* length_p, + FT_Byte maxEntry, + FT_UShort stateArray, + FT_UShort stateArray_length, + FT_Byte maxClassID, + FT_Bytes statetable_table, + FT_Bytes statetable_limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_Bytes limit = table + *length_p; + FT_Byte entry; + FT_Byte state; + FT_Int entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( statetable ); + + GXV_XStateTable_GlyphOffsetDesc glyphOffset; + + + GXV_NAME_ENTER( "EntryTable" ); + + GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize )); + + if ( ( maxEntry + 1 ) * entrySize > *length_p ) + { + GXV_SET_ERR_IF_PARANOID( FT_INVALID_TOO_SHORT ); + + /* ftxvalidator and FontValidator both warn and continue */ + maxEntry = (FT_Byte)( *length_p / entrySize - 1 ); + GXV_TRACE(( "too large maxEntry, shrinking to %d fit EntryTable length\n", + maxEntry )); + } + + for ( entry = 0; entry <= maxEntry; entry++ ) + { + FT_UShort newState; + FT_UShort flags; + + + GXV_LIMIT_CHECK( 2 + 2 ); + newState = FT_NEXT_USHORT( p ); + flags = FT_NEXT_USHORT( p ); + + + if ( newState < stateArray || + stateArray + stateArray_length < newState ) + { + GXV_TRACE(( " newState offset 0x%04x is out of stateArray\n", + newState )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + continue; + } + + if ( 0 != ( ( newState - stateArray ) % ( 1 + maxClassID ) ) ) + { + GXV_TRACE(( " newState offset 0x%04x is not aligned to %d-classes\n", + newState, 1 + maxClassID )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + continue; + } + + state = (FT_Byte)( ( newState - stateArray ) / ( 1 + maxClassID ) ); + + switch ( GXV_GLYPHOFFSET_FMT( statetable ) ) + { + case GXV_GLYPHOFFSET_NONE: + glyphOffset.uc = 0; /* make compiler happy */ + break; + + case GXV_GLYPHOFFSET_UCHAR: + glyphOffset.uc = FT_NEXT_BYTE( p ); + break; + + case GXV_GLYPHOFFSET_CHAR: + glyphOffset.c = FT_NEXT_CHAR( p ); + break; + + case GXV_GLYPHOFFSET_USHORT: + glyphOffset.u = FT_NEXT_USHORT( p ); + break; + + case GXV_GLYPHOFFSET_SHORT: + glyphOffset.s = FT_NEXT_SHORT( p ); + break; + + case GXV_GLYPHOFFSET_ULONG: + glyphOffset.ul = FT_NEXT_ULONG( p ); + break; + + case GXV_GLYPHOFFSET_LONG: + glyphOffset.l = FT_NEXT_LONG( p ); + break; + + default: + GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); + goto Exit; + } + + if ( NULL != valid->statetable.entry_validate_func ) + valid->statetable.entry_validate_func( state, + flags, + &glyphOffset, + statetable_table, + statetable_limit, + valid ); + } + + Exit: + *length_p = (FT_UShort)( p - table ); + + GXV_EXIT; + } + + + /* =========================== State Table ============================= */ + + FT_LOCAL_DEF( void ) + gxv_StateTable_subtable_setup( FT_UShort table_size, + FT_UShort classTable, + FT_UShort stateArray, + FT_UShort entryTable, + FT_UShort* classTable_length_p, + FT_UShort* stateArray_length_p, + FT_UShort* entryTable_length_p, + GXV_Validator valid ) + { + FT_UShort o[3]; + FT_UShort* l[3]; + FT_UShort buff[4]; + + + o[0] = classTable; + o[1] = stateArray; + o[2] = entryTable; + l[0] = classTable_length_p; + l[1] = stateArray_length_p; + l[2] = entryTable_length_p; + + gxv_set_length_by_ushort_offset( o, l, buff, 3, table_size, valid ); + } + + + FT_LOCAL_DEF( void ) + gxv_StateTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_UShort stateSize; + FT_UShort classTable; /* offset to Class(Sub)Table */ + FT_UShort stateArray; /* offset to StateArray */ + FT_UShort entryTable; /* offset to EntryTable */ + + FT_UShort classTable_length; + FT_UShort stateArray_length; + FT_UShort entryTable_length; + FT_Byte maxClassID; + FT_Byte maxState; + FT_Byte maxEntry; + + GXV_StateTable_Subtable_Setup_Func setup_func; + + FT_Bytes p = table; + + + GXV_NAME_ENTER( "StateTable" ); + + GXV_TRACE(( "StateTable header\n" )); + + GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); + stateSize = FT_NEXT_USHORT( p ); + classTable = FT_NEXT_USHORT( p ); + stateArray = FT_NEXT_USHORT( p ); + entryTable = FT_NEXT_USHORT( p ); + + GXV_TRACE(( "stateSize=0x%04x\n", stateSize )); + GXV_TRACE(( "offset to classTable=0x%04x\n", classTable )); + GXV_TRACE(( "offset to stateArray=0x%04x\n", stateArray )); + GXV_TRACE(( "offset to entryTable=0x%04x\n", entryTable )); + + if ( stateSize > 0xFF ) + FT_INVALID_DATA; + + if ( valid->statetable.optdata_load_func != NULL ) + valid->statetable.optdata_load_func( p, limit, valid ); + + if ( valid->statetable.subtable_setup_func != NULL) + setup_func = valid->statetable.subtable_setup_func; + else + setup_func = gxv_StateTable_subtable_setup; + + setup_func( (FT_UShort)( limit - table ), + classTable, + stateArray, + entryTable, + &classTable_length, + &stateArray_length, + &entryTable_length, + valid ); + + GXV_TRACE(( "StateTable Subtables\n" )); + + if ( classTable != 0 ) + gxv_ClassTable_validate( table + classTable, + &classTable_length, + stateSize, + &maxClassID, + valid ); + else + maxClassID = (FT_Byte)( stateSize - 1 ); + + if ( stateArray != 0 ) + gxv_StateArray_validate( table + stateArray, + &stateArray_length, + maxClassID, + stateSize, + &maxState, + &maxEntry, + valid ); + else + { + maxState = 1; /* 0:start of text, 1:start of line are predefined */ + maxEntry = 0; + } + + if ( maxEntry > 0 && entryTable == 0 ) + FT_INVALID_OFFSET; + + if ( entryTable != 0 ) + gxv_EntryTable_validate( table + entryTable, + &entryTable_length, + maxEntry, + stateArray, + stateArray_length, + maxClassID, + table, + limit, + valid ); + + GXV_EXIT; + } + + + /* ================= eXtended State Table (for morx) =================== */ + + FT_LOCAL_DEF( void ) + gxv_XStateTable_subtable_setup( FT_ULong table_size, + FT_ULong classTable, + FT_ULong stateArray, + FT_ULong entryTable, + FT_ULong* classTable_length_p, + FT_ULong* stateArray_length_p, + FT_ULong* entryTable_length_p, + GXV_Validator valid ) + { + FT_ULong o[3]; + FT_ULong* l[3]; + FT_ULong buff[4]; + + + o[0] = classTable; + o[1] = stateArray; + o[2] = entryTable; + l[0] = classTable_length_p; + l[1] = stateArray_length_p; + l[2] = entryTable_length_p; + + gxv_set_length_by_ulong_offset( o, l, buff, 3, table_size, valid ); + } + + + static void + gxv_XClassTable_lookupval_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + FT_UNUSED( glyph ); + + if ( value_p->u >= valid->xstatetable.nClasses ) + FT_INVALID_DATA; + if ( value_p->u > valid->xstatetable.maxClassID ) + valid->xstatetable.maxClassID = value_p->u; + } + + + /* + +===============+ --------+ + | lookup header | | + +===============+ | + | BinSrchHeader | | + +===============+ | + | lastGlyph[0] | | + +---------------+ | + | firstGlyph[0] | | head of lookup table + +---------------+ | + + | offset[0] | -> | offset [byte] + +===============+ | + + | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] + +---------------+ | + | firstGlyph[1] | | + +---------------+ | + | offset[1] | | + +===============+ | + | + .... | + | + 16bit value array | + +===============+ | + | value | <-------+ + .... + */ + static GXV_LookupValueDesc + gxv_XClassTable_lookupfmt4_transit( FT_UShort relative_gindex, + GXV_LookupValueCPtr base_value_p, + FT_Bytes lookuptbl_limit, + GXV_Validator valid ) + { + FT_Bytes p; + FT_Bytes limit; + FT_UShort offset; + GXV_LookupValueDesc value; + + /* XXX: check range? */ + offset = (FT_UShort)( base_value_p->u + + relative_gindex * sizeof ( FT_UShort ) ); + + p = valid->lookuptbl_head + offset; + limit = lookuptbl_limit; + + GXV_LIMIT_CHECK ( 2 ); + value.u = FT_NEXT_USHORT( p ); + + return value; + } + + + static void + gxv_XStateArray_validate( FT_Bytes table, + FT_ULong* length_p, + FT_UShort maxClassID, + FT_ULong stateSize, + FT_UShort* maxState_p, + FT_UShort* maxEntry_p, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_Bytes limit = table + *length_p; + FT_UShort clazz; + FT_UShort entry; + + FT_UNUSED( stateSize ); /* for the non-debugging case */ + + + GXV_NAME_ENTER( "XStateArray" ); + + GXV_TRACE(( "parse % 3d bytes by stateSize=% 3d maxClassID=% 3d\n", + (int)(*length_p), stateSize, (int)(maxClassID) )); + + /* + * 2 states are predefined and must be described: + * state 0 (start of text), 1 (start of line) + */ + GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 * 2 ); + + *maxState_p = 0; + *maxEntry_p = 0; + + /* read if enough to read another state */ + while ( p + ( ( 1 + maxClassID ) * 2 ) <= limit ) + { + (*maxState_p)++; + for ( clazz = 0; clazz <= maxClassID; clazz++ ) + { + entry = FT_NEXT_USHORT( p ); + *maxEntry_p = (FT_UShort)FT_MAX( *maxEntry_p, entry ); + } + } + GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n", + *maxState_p, *maxEntry_p )); + + *length_p = p - table; + + GXV_EXIT; + } + + + static void + gxv_XEntryTable_validate( FT_Bytes table, + FT_ULong* length_p, + FT_UShort maxEntry, + FT_ULong stateArray_length, + FT_UShort maxClassID, + FT_Bytes xstatetable_table, + FT_Bytes xstatetable_limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_Bytes limit = table + *length_p; + FT_UShort entry; + FT_UShort state; + FT_Int entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( xstatetable ); + + + GXV_NAME_ENTER( "XEntryTable" ); + GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize )); + + if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit ) + FT_INVALID_TOO_SHORT; + + for (entry = 0; entry <= maxEntry ; entry++ ) + { + FT_UShort newState_idx; + FT_UShort flags; + GXV_XStateTable_GlyphOffsetDesc glyphOffset; + + + GXV_LIMIT_CHECK( 2 + 2 ); + newState_idx = FT_NEXT_USHORT( p ); + flags = FT_NEXT_USHORT( p ); + + if ( stateArray_length < (FT_ULong)( newState_idx * 2 ) ) + { + GXV_TRACE(( " newState index 0x%04x points out of stateArray\n", + newState_idx )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } + + state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) ); + if ( 0 != ( newState_idx % ( 1 + maxClassID ) ) ) + { + FT_TRACE4(( "-> new state = %d (supposed)\n" + "but newState index 0x%04x is not aligned to %d-classes\n", + state, newState_idx, 1 + maxClassID )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } + + switch ( GXV_GLYPHOFFSET_FMT( xstatetable ) ) + { + case GXV_GLYPHOFFSET_NONE: + glyphOffset.uc = 0; /* make compiler happy */ + break; + + case GXV_GLYPHOFFSET_UCHAR: + glyphOffset.uc = FT_NEXT_BYTE( p ); + break; + + case GXV_GLYPHOFFSET_CHAR: + glyphOffset.c = FT_NEXT_CHAR( p ); + break; + + case GXV_GLYPHOFFSET_USHORT: + glyphOffset.u = FT_NEXT_USHORT( p ); + break; + + case GXV_GLYPHOFFSET_SHORT: + glyphOffset.s = FT_NEXT_SHORT( p ); + break; + + case GXV_GLYPHOFFSET_ULONG: + glyphOffset.ul = FT_NEXT_ULONG( p ); + break; + + case GXV_GLYPHOFFSET_LONG: + glyphOffset.l = FT_NEXT_LONG( p ); + break; + + default: + GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); + goto Exit; + } + + if ( NULL != valid->xstatetable.entry_validate_func ) + valid->xstatetable.entry_validate_func( state, + flags, + &glyphOffset, + xstatetable_table, + xstatetable_limit, + valid ); + } + + Exit: + *length_p = p - table; + + GXV_EXIT; + } + + + FT_LOCAL_DEF( void ) + gxv_XStateTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + /* StateHeader members */ + FT_ULong classTable; /* offset to Class(Sub)Table */ + FT_ULong stateArray; /* offset to StateArray */ + FT_ULong entryTable; /* offset to EntryTable */ + + FT_ULong classTable_length; + FT_ULong stateArray_length; + FT_ULong entryTable_length; + FT_UShort maxState; + FT_UShort maxEntry; + + GXV_XStateTable_Subtable_Setup_Func setup_func; + + FT_Bytes p = table; + + + GXV_NAME_ENTER( "XStateTable" ); + + GXV_TRACE(( "XStateTable header\n" )); + + GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); + valid->xstatetable.nClasses = FT_NEXT_ULONG( p ); + classTable = FT_NEXT_ULONG( p ); + stateArray = FT_NEXT_ULONG( p ); + entryTable = FT_NEXT_ULONG( p ); + + GXV_TRACE(( "nClasses =0x%08x\n", valid->xstatetable.nClasses )); + GXV_TRACE(( "offset to classTable=0x%08x\n", classTable )); + GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray )); + GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable )); + + if ( valid->xstatetable.nClasses > 0xFFFFU ) + FT_INVALID_DATA; + + GXV_TRACE(( "StateTable Subtables\n" )); + + if ( valid->xstatetable.optdata_load_func != NULL ) + valid->xstatetable.optdata_load_func( p, limit, valid ); + + if ( valid->xstatetable.subtable_setup_func != NULL ) + setup_func = valid->xstatetable.subtable_setup_func; + else + setup_func = gxv_XStateTable_subtable_setup; + + setup_func( limit - table, + classTable, + stateArray, + entryTable, + &classTable_length, + &stateArray_length, + &entryTable_length, + valid ); + + if ( classTable != 0 ) + { + valid->xstatetable.maxClassID = 0; + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_XClassTable_lookupval_validate; + valid->lookupfmt4_trans = gxv_XClassTable_lookupfmt4_transit; + gxv_LookupTable_validate( table + classTable, + table + classTable + classTable_length, + valid ); + if ( valid->subtable_length < classTable_length ) + classTable_length = valid->subtable_length; + } + else + { + /* XXX: check range? */ + valid->xstatetable.maxClassID = + (FT_UShort)( valid->xstatetable.nClasses - 1 ); + } + + if ( stateArray != 0 ) + gxv_XStateArray_validate( table + stateArray, + &stateArray_length, + valid->xstatetable.maxClassID, + valid->xstatetable.nClasses, + &maxState, + &maxEntry, + valid ); + else + { + maxState = 1; /* 0:start of text, 1:start of line are predefined */ + maxEntry = 0; + } + + if ( maxEntry > 0 && entryTable == 0 ) + FT_INVALID_OFFSET; + + if ( entryTable != 0 ) + gxv_XEntryTable_validate( table + entryTable, + &entryTable_length, + maxEntry, + stateArray_length, + valid->xstatetable.maxClassID, + table, + limit, + valid ); + + GXV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Table overlapping *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static int + gxv_compare_ranges( FT_Bytes table1_start, + FT_ULong table1_length, + FT_Bytes table2_start, + FT_ULong table2_length ) + { + if ( table1_start == table2_start ) + { + if ( ( table1_length == 0 || table2_length == 0 ) ) + goto Out; + } + else if ( table1_start < table2_start ) + { + if ( ( table1_start + table1_length ) <= table2_start ) + goto Out; + } + else if ( table1_start > table2_start ) + { + if ( ( table1_start >= table2_start + table2_length ) ) + goto Out; + } + return 1; + + Out: + return 0; + } + + + FT_LOCAL_DEF( void ) + gxv_odtect_add_range( FT_Bytes start, + FT_ULong length, + const FT_String* name, + GXV_odtect_Range odtect ) + { + odtect->range[odtect->nRanges].start = start; + odtect->range[odtect->nRanges].length = length; + odtect->range[odtect->nRanges].name = (FT_String*)name; + odtect->nRanges++; + } + + + FT_LOCAL_DEF( void ) + gxv_odtect_validate( GXV_odtect_Range odtect, + GXV_Validator valid ) + { + FT_UInt i, j; + + + GXV_NAME_ENTER( "check overlap among multi ranges" ); + + for ( i = 0; i < odtect->nRanges; i++ ) + for ( j = 0; j < i; j++ ) + if ( 0 != gxv_compare_ranges( odtect->range[i].start, + odtect->range[i].length, + odtect->range[j].start, + odtect->range[j].length ) ) + { + if ( odtect->range[i].name || odtect->range[j].name ) + GXV_TRACE(( "found overlap between range %d and range %d\n", + i, j )); + else + GXV_TRACE(( "found overlap between `%s' and `%s\'\n", + odtect->range[i].name, + odtect->range[j].name )); + FT_INVALID_OFFSET; + } + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvcommn.h b/drivers/freetype/src/gxvalid/gxvcommn.h new file mode 100644 index 0000000000..1ff87e4423 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvcommn.h @@ -0,0 +1,582 @@ +/***************************************************************************/ +/* */ +/* gxvcommn.h */ +/* */ +/* TrueTypeGX/AAT common tables validation (specification). */ +/* */ +/* Copyright 2004, 2005, 2012 */ +/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + + /* + * keywords in variable naming + * --------------------------- + * table: Of type FT_Bytes, pointing to the start of this table/subtable. + * limit: Of type FT_Bytes, pointing to the end of this table/subtable, + * including padding for alignment. + * offset: Of type FT_UInt, the number of octets from the start to target. + * length: Of type FT_UInt, the number of octets from the start to the + * end in this table/subtable, including padding for alignment. + * + * _MIN, _MAX: Should be added to the tail of macros, as INT_MIN, etc. + */ + + +#ifndef __GXVCOMMN_H__ +#define __GXVCOMMN_H__ + + +#include <ft2build.h> +#include "gxvalid.h" +#include FT_INTERNAL_DEBUG_H +#include FT_SFNT_NAMES_H + + +FT_BEGIN_HEADER + + + /* some variables are not evaluated or only used in trace */ + +#ifdef FT_DEBUG_LEVEL_TRACE +#define GXV_LOAD_TRACE_VARS +#else +#undef GXV_LOAD_TRACE_VARS +#endif + +#undef GXV_LOAD_UNUSED_VARS /* debug purpose */ + +#define IS_PARANOID_VALIDATION ( valid->root->level >= FT_VALIDATE_PARANOID ) +#define GXV_SET_ERR_IF_PARANOID( err ) { if ( IS_PARANOID_VALIDATION ) ( err ); } + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** VALIDATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct GXV_ValidatorRec_* GXV_Validator; + + +#define DUMMY_LIMIT 0 + + typedef void + (*GXV_Validate_Func)( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + + /* ====================== LookupTable Validator ======================== */ + + typedef union GXV_LookupValueDesc_ + { + FT_UShort u; + FT_Short s; + + } GXV_LookupValueDesc; + + typedef const GXV_LookupValueDesc* GXV_LookupValueCPtr; + + typedef enum GXV_LookupValue_SignSpec_ + { + GXV_LOOKUPVALUE_UNSIGNED = 0, + GXV_LOOKUPVALUE_SIGNED + + } GXV_LookupValue_SignSpec; + + + typedef void + (*GXV_Lookup_Value_Validate_Func)( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ); + + typedef GXV_LookupValueDesc + (*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort relative_gindex, + GXV_LookupValueCPtr base_value_p, + FT_Bytes lookuptbl_limit, + GXV_Validator valid ); + + + /* ====================== StateTable Validator ========================= */ + + typedef enum GXV_GlyphOffset_Format_ + { + GXV_GLYPHOFFSET_NONE = -1, + GXV_GLYPHOFFSET_UCHAR = 2, + GXV_GLYPHOFFSET_CHAR, + GXV_GLYPHOFFSET_USHORT = 4, + GXV_GLYPHOFFSET_SHORT, + GXV_GLYPHOFFSET_ULONG = 8, + GXV_GLYPHOFFSET_LONG + + } GXV_GlyphOffset_Format; + + +#define GXV_GLYPHOFFSET_FMT( table ) \ + ( valid->table.entry_glyphoffset_fmt ) + +#define GXV_GLYPHOFFSET_SIZE( table ) \ + ( valid->table.entry_glyphoffset_fmt / 2 ) + + + /* ----------------------- 16bit StateTable ---------------------------- */ + + typedef union GXV_StateTable_GlyphOffsetDesc_ + { + FT_Byte uc; + FT_UShort u; /* same as GXV_LookupValueDesc */ + FT_ULong ul; + FT_Char c; + FT_Short s; /* same as GXV_LookupValueDesc */ + FT_Long l; + + } GXV_StateTable_GlyphOffsetDesc; + + typedef const GXV_StateTable_GlyphOffsetDesc* GXV_StateTable_GlyphOffsetCPtr; + + typedef void + (*GXV_StateTable_Subtable_Setup_Func)( FT_UShort table_size, + FT_UShort classTable, + FT_UShort stateArray, + FT_UShort entryTable, + FT_UShort* classTable_length_p, + FT_UShort* stateArray_length_p, + FT_UShort* entryTable_length_p, + GXV_Validator valid ); + + typedef void + (*GXV_StateTable_Entry_Validate_Func)( + FT_Byte state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes statetable_table, + FT_Bytes statetable_limit, + GXV_Validator valid ); + + typedef void + (*GXV_StateTable_OptData_Load_Func)( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + typedef struct GXV_StateTable_ValidatorRec_ + { + GXV_GlyphOffset_Format entry_glyphoffset_fmt; + void* optdata; + + GXV_StateTable_Subtable_Setup_Func subtable_setup_func; + GXV_StateTable_Entry_Validate_Func entry_validate_func; + GXV_StateTable_OptData_Load_Func optdata_load_func; + + } GXV_StateTable_ValidatorRec, *GXV_StateTable_ValidatorRecData; + + + /* ---------------------- 32bit XStateTable ---------------------------- */ + + typedef GXV_StateTable_GlyphOffsetDesc GXV_XStateTable_GlyphOffsetDesc; + + typedef const GXV_XStateTable_GlyphOffsetDesc* GXV_XStateTable_GlyphOffsetCPtr; + + typedef void + (*GXV_XStateTable_Subtable_Setup_Func)( FT_ULong table_size, + FT_ULong classTable, + FT_ULong stateArray, + FT_ULong entryTable, + FT_ULong* classTable_length_p, + FT_ULong* stateArray_length_p, + FT_ULong* entryTable_length_p, + GXV_Validator valid ); + + typedef void + (*GXV_XStateTable_Entry_Validate_Func)( + FT_UShort state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes xstatetable_table, + FT_Bytes xstatetable_limit, + GXV_Validator valid ); + + + typedef GXV_StateTable_OptData_Load_Func GXV_XStateTable_OptData_Load_Func; + + + typedef struct GXV_XStateTable_ValidatorRec_ + { + int entry_glyphoffset_fmt; + void* optdata; + + GXV_XStateTable_Subtable_Setup_Func subtable_setup_func; + GXV_XStateTable_Entry_Validate_Func entry_validate_func; + GXV_XStateTable_OptData_Load_Func optdata_load_func; + + FT_ULong nClasses; + FT_UShort maxClassID; + + } GXV_XStateTable_ValidatorRec, *GXV_XStateTable_ValidatorRecData; + + + /* ===================================================================== */ + + typedef struct GXV_ValidatorRec_ + { + FT_Validator root; + + FT_Face face; + void* table_data; + + FT_ULong subtable_length; + + GXV_LookupValue_SignSpec lookupval_sign; + GXV_Lookup_Value_Validate_Func lookupval_func; + GXV_Lookup_Fmt4_Transit_Func lookupfmt4_trans; + FT_Bytes lookuptbl_head; + + FT_UShort min_gid; + FT_UShort max_gid; + + GXV_StateTable_ValidatorRec statetable; + GXV_XStateTable_ValidatorRec xstatetable; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_UInt debug_indent; + const FT_String* debug_function_name[3]; +#endif + + } GXV_ValidatorRec; + + +#define GXV_TABLE_DATA( tag, field ) \ + ( ( (GXV_ ## tag ## _Data)valid->table_data )->field ) + +#undef FT_INVALID_ +#define FT_INVALID_( _prefix, _error ) \ + ft_validator_error( valid->root, _prefix ## _error ) + +#define GXV_LIMIT_CHECK( _count ) \ + FT_BEGIN_STMNT \ + if ( p + _count > ( limit? limit : valid->root->limit ) ) \ + FT_INVALID_TOO_SHORT; \ + FT_END_STMNT + + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define GXV_INIT valid->debug_indent = 0 + +#define GXV_NAME_ENTER( name ) \ + FT_BEGIN_STMNT \ + valid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", name )); \ + FT_END_STMNT + +#define GXV_EXIT valid->debug_indent -= 2 + +#define GXV_TRACE( s ) \ + FT_BEGIN_STMNT \ + FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4( s ); \ + FT_END_STMNT + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define GXV_INIT do { } while ( 0 ) +#define GXV_NAME_ENTER( name ) do { } while ( 0 ) +#define GXV_EXIT do { } while ( 0 ) + +#define GXV_TRACE( s ) do { } while ( 0 ) + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** 32bit alignment checking *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define GXV_32BIT_ALIGNMENT_VALIDATE( a ) \ + FT_BEGIN_STMNT \ + { \ + if ( (a) & 3 ) \ + FT_INVALID_OFFSET ; \ + } \ + FT_END_STMNT + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Dumping Binary Data *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define GXV_TRACE_HEXDUMP( p, len ) \ + FT_BEGIN_STMNT \ + { \ + FT_Bytes b; \ + \ + \ + for ( b = p; b < (FT_Bytes)p + len; b++ ) \ + FT_TRACE1(("\\x%02x", *b)) ; \ + } \ + FT_END_STMNT + +#define GXV_TRACE_HEXDUMP_C( p, len ) \ + FT_BEGIN_STMNT \ + { \ + FT_Bytes b; \ + \ + \ + for ( b = p; b < (FT_Bytes)p + len; b++ ) \ + if ( 0x40 < *b && *b < 0x7e ) \ + FT_TRACE1(("%c", *b)) ; \ + else \ + FT_TRACE1(("\\x%02x", *b)) ; \ + } \ + FT_END_STMNT + +#define GXV_TRACE_HEXDUMP_SFNTNAME( n ) \ + GXV_TRACE_HEXDUMP( n.string, n.string_len ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + gxv_BinSrchHeader_validate( FT_Bytes p, + FT_Bytes limit, + FT_UShort* unitSize_p, + FT_UShort* nUnits_p, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_LookupTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Glyph ID *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( FT_Int ) + gxv_glyphid_validate( FT_UShort gid, + GXV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CONTROL POINT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + gxv_ctlPoint_validate( FT_UShort gid, + FT_Short ctl_point, + GXV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SFNT NAME *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + gxv_sfntName_validate( FT_UShort name_index, + FT_UShort min_index, + FT_UShort max_index, + GXV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** STATE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + gxv_StateTable_subtable_setup( FT_UShort table_size, + FT_UShort classTable, + FT_UShort stateArray, + FT_UShort entryTable, + FT_UShort* classTable_length_p, + FT_UShort* stateArray_length_p, + FT_UShort* entryTable_length_p, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_XStateTable_subtable_setup( FT_ULong table_size, + FT_ULong classTable, + FT_ULong stateArray, + FT_ULong entryTable, + FT_ULong* classTable_length_p, + FT_ULong* stateArray_length_p, + FT_ULong* entryTable_length_p, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_StateTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_XStateTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY MACROS AND FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + gxv_array_getlimits_byte( FT_Bytes table, + FT_Bytes limit, + FT_Byte* min, + FT_Byte* max, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_array_getlimits_ushort( FT_Bytes table, + FT_Bytes limit, + FT_UShort* min, + FT_UShort* max, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_set_length_by_ushort_offset( FT_UShort* offset, + FT_UShort** length, + FT_UShort* buff, + FT_UInt nmemb, + FT_UShort limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_set_length_by_ulong_offset( FT_ULong* offset, + FT_ULong** length, + FT_ULong* buff, + FT_UInt nmemb, + FT_ULong limit, + GXV_Validator valid); + + +#define GXV_SUBTABLE_OFFSET_CHECK( _offset ) \ + FT_BEGIN_STMNT \ + if ( (_offset) > valid->subtable_length ) \ + FT_INVALID_OFFSET; \ + FT_END_STMNT + +#define GXV_SUBTABLE_LIMIT_CHECK( _count ) \ + FT_BEGIN_STMNT \ + if ( ( p + (_count) - valid->subtable_start ) > \ + valid->subtable_length ) \ + FT_INVALID_TOO_SHORT; \ + FT_END_STMNT + +#define GXV_USHORT_TO_SHORT( _us ) \ + ( ( 0x8000U < ( _us ) ) ? ( ( _us ) - 0x8000U ) : ( _us ) ) + +#define GXV_STATETABLE_HEADER_SIZE ( 2 + 2 + 2 + 2 ) +#define GXV_STATEHEADER_SIZE GXV_STATETABLE_HEADER_SIZE + +#define GXV_XSTATETABLE_HEADER_SIZE ( 4 + 4 + 4 + 4 ) +#define GXV_XSTATEHEADER_SIZE GXV_XSTATETABLE_HEADER_SIZE + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Table overlapping *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct GXV_odtect_DataRec_ + { + FT_Bytes start; + FT_ULong length; + FT_String* name; + + } GXV_odtect_DataRec, *GXV_odtect_Data; + + typedef struct GXV_odtect_RangeRec_ + { + FT_UInt nRanges; + GXV_odtect_Data range; + + } GXV_odtect_RangeRec, *GXV_odtect_Range; + + + FT_LOCAL( void ) + gxv_odtect_add_range( FT_Bytes start, + FT_ULong length, + const FT_String* name, + GXV_odtect_Range odtect ); + + FT_LOCAL( void ) + gxv_odtect_validate( GXV_odtect_Range odtect, + GXV_Validator valid ); + + +#define GXV_ODTECT( n, odtect ) \ + GXV_odtect_DataRec odtect ## _range[n]; \ + GXV_odtect_RangeRec odtect ## _rec = { 0, NULL }; \ + GXV_odtect_Range odtect = NULL + +#define GXV_ODTECT_INIT( odtect ) \ + FT_BEGIN_STMNT \ + odtect ## _rec.nRanges = 0; \ + odtect ## _rec.range = odtect ## _range; \ + odtect = & odtect ## _rec; \ + FT_END_STMNT + + + /* */ + +FT_END_HEADER + +#endif /* __GXVCOMMN_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxverror.h b/drivers/freetype/src/gxvalid/gxverror.h new file mode 100644 index 0000000000..c573b72de7 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxverror.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* gxverror.h */ +/* */ +/* TrueTypeGX/AAT validation module error codes (specification only). */ +/* */ +/* Copyright 2004, 2005, 2012-2013 */ +/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the OpenType validation module error */ + /* enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __GXVERROR_H__ +#define __GXVERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX GXV_Err_ +#define FT_ERR_BASE FT_Mod_Err_GXvalid + +#include FT_ERRORS_H + +#endif /* __GXVERROR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvfeat.c b/drivers/freetype/src/gxvalid/gxvfeat.c new file mode 100644 index 0000000000..6f75650991 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvfeat.c @@ -0,0 +1,339 @@ +/***************************************************************************/ +/* */ +/* gxvfeat.c */ +/* */ +/* TrueTypeGX/AAT feat table validation (body). */ +/* */ +/* Copyright 2004, 2005, 2008, 2012 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvalid.h" +#include "gxvcommn.h" +#include "gxvfeat.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_gxvfeat + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Data and Types *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct GXV_feat_DataRec_ + { + FT_UInt reserved_size; + FT_UShort feature; + FT_UShort setting; + + } GXV_feat_DataRec, *GXV_feat_Data; + + +#define GXV_FEAT_DATA( field ) GXV_TABLE_DATA( feat, field ) + + + typedef enum GXV_FeatureFlagsMask_ + { + GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000U, + GXV_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000, + GXV_FEAT_MASK_UNUSED = 0x3F00, + GXV_FEAT_MASK_DEFAULT_SETTING = 0x00FF + + } GXV_FeatureFlagsMask; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + gxv_feat_registry_validate( FT_UShort feature, + FT_UShort nSettings, + FT_Bool exclusive, + GXV_Validator valid ) + { + GXV_NAME_ENTER( "feature in registry" ); + + GXV_TRACE(( " (feature = %u)\n", feature )); + + if ( feature >= gxv_feat_registry_length ) + { + GXV_TRACE(( "feature number %d is out of range %d\n", + feature, gxv_feat_registry_length )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + goto Exit; + } + + if ( gxv_feat_registry[feature].existence == 0 ) + { + GXV_TRACE(( "feature number %d is in defined range but doesn't exist\n", + feature )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + goto Exit; + } + + if ( gxv_feat_registry[feature].apple_reserved ) + { + /* Don't use here. Apple is reserved. */ + GXV_TRACE(( "feature number %d is reserved by Apple\n", feature )); + if ( valid->root->level >= FT_VALIDATE_TIGHT ) + FT_INVALID_DATA; + } + + if ( nSettings != gxv_feat_registry[feature].nSettings ) + { + GXV_TRACE(( "feature %d: nSettings %d != defined nSettings %d\n", + feature, nSettings, + gxv_feat_registry[feature].nSettings )); + if ( valid->root->level >= FT_VALIDATE_TIGHT ) + FT_INVALID_DATA; + } + + if ( exclusive != gxv_feat_registry[feature].exclusive ) + { + GXV_TRACE(( "exclusive flag %d differs from predefined value\n", + exclusive )); + if ( valid->root->level >= FT_VALIDATE_TIGHT ) + FT_INVALID_DATA; + } + + Exit: + GXV_EXIT; + } + + + static void + gxv_feat_name_index_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + FT_Short nameIndex; + + + GXV_NAME_ENTER( "nameIndex" ); + + GXV_LIMIT_CHECK( 2 ); + nameIndex = FT_NEXT_SHORT ( p ); + GXV_TRACE(( " (nameIndex = %d)\n", nameIndex )); + + gxv_sfntName_validate( (FT_UShort)nameIndex, + 255, + 32768U, + valid ); + + GXV_EXIT; + } + + + static void + gxv_feat_setting_validate( FT_Bytes table, + FT_Bytes limit, + FT_Bool exclusive, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort setting; + + + GXV_NAME_ENTER( "setting" ); + + GXV_LIMIT_CHECK( 2 ); + + setting = FT_NEXT_USHORT( p ); + + /* If we have exclusive setting, the setting should be odd. */ + if ( exclusive && ( setting & 1 ) == 0 ) + FT_INVALID_DATA; + + gxv_feat_name_index_validate( p, limit, valid ); + + GXV_FEAT_DATA( setting ) = setting; + + GXV_EXIT; + } + + + static void + gxv_feat_name_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt reserved_size = GXV_FEAT_DATA( reserved_size ); + + FT_UShort feature; + FT_UShort nSettings; + FT_ULong settingTable; + FT_UShort featureFlags; + + FT_Bool exclusive; + FT_Int last_setting; + FT_UInt i; + + + GXV_NAME_ENTER( "name" ); + + /* feature + nSettings + settingTable + featureFlags */ + GXV_LIMIT_CHECK( 2 + 2 + 4 + 2 ); + + feature = FT_NEXT_USHORT( p ); + GXV_FEAT_DATA( feature ) = feature; + + nSettings = FT_NEXT_USHORT( p ); + settingTable = FT_NEXT_ULONG ( p ); + featureFlags = FT_NEXT_USHORT( p ); + + if ( settingTable < reserved_size ) + FT_INVALID_OFFSET; + + if ( ( featureFlags & GXV_FEAT_MASK_UNUSED ) == 0 ) + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + + exclusive = FT_BOOL( featureFlags & GXV_FEAT_MASK_EXCLUSIVE_SETTINGS ); + if ( exclusive ) + { + FT_Byte dynamic_default; + + + if ( featureFlags & GXV_FEAT_MASK_DYNAMIC_DEFAULT ) + dynamic_default = (FT_Byte)( featureFlags & + GXV_FEAT_MASK_DEFAULT_SETTING ); + else + dynamic_default = 0; + + /* If exclusive, check whether default setting is in the range. */ + if ( !( dynamic_default < nSettings ) ) + FT_INVALID_FORMAT; + } + + gxv_feat_registry_validate( feature, nSettings, exclusive, valid ); + + gxv_feat_name_index_validate( p, limit, valid ); + + p = valid->root->base + settingTable; + for ( last_setting = -1, i = 0; i < nSettings; i++ ) + { + gxv_feat_setting_validate( p, limit, exclusive, valid ); + + if ( (FT_Int)GXV_FEAT_DATA( setting ) <= last_setting ) + GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); + + last_setting = (FT_Int)GXV_FEAT_DATA( setting ); + /* setting + nameIndex */ + p += ( 2 + 2 ); + } + + GXV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** feat TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + gxv_feat_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + + GXV_feat_DataRec featrec; + GXV_feat_Data feat = &featrec; + + FT_Bytes p = table; + FT_Bytes limit = 0; + + FT_UInt featureNameCount; + + FT_UInt i; + FT_Int last_feature; + + + valid->root = ftvalid; + valid->table_data = feat; + valid->face = face; + + FT_TRACE3(( "validating `feat' table\n" )); + GXV_INIT; + + feat->reserved_size = 0; + + /* version + featureNameCount + none_0 + none_1 */ + GXV_LIMIT_CHECK( 4 + 2 + 2 + 4 ); + feat->reserved_size += 4 + 2 + 2 + 4; + + if ( FT_NEXT_ULONG( p ) != 0x00010000UL ) /* Version */ + FT_INVALID_FORMAT; + + featureNameCount = FT_NEXT_USHORT( p ); + GXV_TRACE(( " (featureNameCount = %d)\n", featureNameCount )); + + if ( !( IS_PARANOID_VALIDATION ) ) + p += 6; /* skip (none) and (none) */ + else + { + if ( FT_NEXT_USHORT( p ) != 0 ) + FT_INVALID_DATA; + + if ( FT_NEXT_ULONG( p ) != 0 ) + FT_INVALID_DATA; + } + + feat->reserved_size += featureNameCount * ( 2 + 2 + 4 + 2 + 2 ); + + for ( last_feature = -1, i = 0; i < featureNameCount; i++ ) + { + gxv_feat_name_validate( p, limit, valid ); + + if ( (FT_Int)GXV_FEAT_DATA( feature ) <= last_feature ) + GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); + + last_feature = GXV_FEAT_DATA( feature ); + p += 2 + 2 + 4 + 2 + 2; + } + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvfeat.h b/drivers/freetype/src/gxvalid/gxvfeat.h new file mode 100644 index 0000000000..049d23a0b9 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvfeat.h @@ -0,0 +1,172 @@ +/***************************************************************************/ +/* */ +/* gxvfeat.h */ +/* */ +/* TrueTypeGX/AAT feat table validation (specification). */ +/* */ +/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __GXVFEAT_H__ +#define __GXVFEAT_H__ + + +#include "gxvalid.h" +#include "gxvcommn.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Registry predefined by Apple *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* TODO: More compact format */ + typedef struct GXV_Feature_RegistryRec_ + { + FT_Bool existence; + FT_Bool apple_reserved; + FT_Bool exclusive; + FT_Byte nSettings; + + } GX_Feature_RegistryRec; + + +#define gxv_feat_registry_length \ + ( sizeof ( gxv_feat_registry ) / \ + sizeof ( GX_Feature_RegistryRec ) ) + + + static GX_Feature_RegistryRec gxv_feat_registry[] = + { + /* Generated from gxvfgen.c */ + {1, 0, 0, 1}, /* All Typographic Features */ + {1, 0, 0, 8}, /* Ligatures */ + {1, 0, 1, 3}, /* Cursive Connection */ + {1, 0, 1, 6}, /* Letter Case */ + {1, 0, 0, 1}, /* Vertical Substitution */ + {1, 0, 0, 1}, /* Linguistic Rearrangement */ + {1, 0, 1, 2}, /* Number Spacing */ + {1, 1, 0, 0}, /* Apple Reserved 1 */ + {1, 0, 0, 5}, /* Smart Swashes */ + {1, 0, 1, 3}, /* Diacritics */ + {1, 0, 1, 4}, /* Vertical Position */ + {1, 0, 1, 3}, /* Fractions */ + {1, 1, 0, 0}, /* Apple Reserved 2 */ + {1, 0, 0, 1}, /* Overlapping Characters */ + {1, 0, 0, 6}, /* Typographic Extras */ + {1, 0, 0, 5}, /* Mathematical Extras */ + {1, 0, 1, 7}, /* Ornament Sets */ + {1, 0, 1, 1}, /* Character Alternatives */ + {1, 0, 1, 5}, /* Design Complexity */ + {1, 0, 1, 6}, /* Style Options */ + {1, 0, 1, 11}, /* Character Shape */ + {1, 0, 1, 2}, /* Number Case */ + {1, 0, 1, 4}, /* Text Spacing */ + {1, 0, 1, 10}, /* Transliteration */ + {1, 0, 1, 9}, /* Annotation */ + {1, 0, 1, 2}, /* Kana Spacing */ + {1, 0, 1, 2}, /* Ideographic Spacing */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {0, 0, 0, 0}, /* __EMPTY__ */ + {1, 0, 1, 4}, /* Text Spacing */ + {1, 0, 1, 2}, /* Kana Spacing */ + {1, 0, 1, 2}, /* Ideographic Spacing */ + {1, 0, 1, 4}, /* CJK Roman Spacing */ + }; + + +#endif /* __GXVFEAT_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvfgen.c b/drivers/freetype/src/gxvalid/gxvfgen.c new file mode 100644 index 0000000000..e48778a2a1 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvfgen.c @@ -0,0 +1,482 @@ +/***************************************************************************/ +/* */ +/* gxfgen.c */ +/* */ +/* Generate feature registry data for gxv `feat' validator. */ +/* This program is derived from gxfeatreg.c in gxlayout. */ +/* */ +/* Copyright 2004, 2005, 2006 by Masatake YAMATO and Redhat K.K. */ +/* */ +/* This file 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxfeatreg.c */ +/* */ +/* Database of font features pre-defined by Apple Computer, Inc. */ +/* http://developer.apple.com/fonts/Registry/ */ +/* (body). */ +/* */ +/* Copyright 2003 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* This file 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* Development of gxfeatreg.c is supported by */ +/* Information-technology Promotion Agency, Japan. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* This file is compiled as a stand-alone executable. */ +/* This file is never compiled into `libfreetype2'. */ +/* The output of this file is used in `gxvfeat.c'. */ +/* ----------------------------------------------------------------------- */ +/* Compile: gcc `pkg-config --cflags freetype2` gxvfgen.c -o gxvfgen */ +/* Run: ./gxvfgen > tmp.c */ +/* */ +/***************************************************************************/ + + /*******************************************************************/ + /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ + /*******************************************************************/ + + /* + * If you add a new setting to a feature, check the number of settings + * in the feature. If the number is greater than the value defined as + * FEATREG_MAX_SETTING, update the value. + */ +#define FEATREG_MAX_SETTING 12 + + /*******************************************************************/ + /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ + /*******************************************************************/ + + +#include <stdio.h> +#include <string.h> + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Data and Types *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define APPLE_RESERVED "Apple Reserved" +#define APPLE_RESERVED_LENGTH 14 + + typedef struct GX_Feature_RegistryRec_ + { + const char* feat_name; + char exclusive; + char* setting_name[FEATREG_MAX_SETTING]; + + } GX_Feature_RegistryRec; + + +#define EMPTYFEAT {0, 0, {NULL}} + + + static GX_Feature_RegistryRec featreg_table[] = { + { /* 0 */ + "All Typographic Features", + 0, + { + "All Type Features", + NULL + } + }, { /* 1 */ + "Ligatures", + 0, + { + "Required Ligatures", + "Common Ligatures", + "Rare Ligatures", + "Logos", + "Rebus Pictures", + "Diphthong Ligatures", + "Squared Ligatures", + "Squared Ligatures, Abbreviated", + NULL + } + }, { /* 2 */ + "Cursive Connection", + 1, + { + "Unconnected", + "Partially Connected", + "Cursive", + NULL + } + }, { /* 3 */ + "Letter Case", + 1, + { + "Upper & Lower Case", + "All Caps", + "All Lower Case", + "Small Caps", + "Initial Caps", + "Initial Caps & Small Caps", + NULL + } + }, { /* 4 */ + "Vertical Substitution", + 0, + { + /* "Substitute Vertical Forms", */ + "Turns on the feature", + NULL + } + }, { /* 5 */ + "Linguistic Rearrangement", + 0, + { + /* "Linguistic Rearrangement", */ + "Turns on the feature", + NULL + } + }, { /* 6 */ + "Number Spacing", + 1, + { + "Monospaced Numbers", + "Proportional Numbers", + NULL + } + }, { /* 7 */ + APPLE_RESERVED " 1", + 0, + {NULL} + }, { /* 8 */ + "Smart Swashes", + 0, + { + "Word Initial Swashes", + "Word Final Swashes", + "Line Initial Swashes", + "Line Final Swashes", + "Non-Final Swashes", + NULL + } + }, { /* 9 */ + "Diacritics", + 1, + { + "Show Diacritics", + "Hide Diacritics", + "Decompose Diacritics", + NULL + } + }, { /* 10 */ + "Vertical Position", + 1, + { + /* "Normal Position", */ + "No Vertical Position", + "Superiors", + "Inferiors", + "Ordinals", + NULL + } + }, { /* 11 */ + "Fractions", + 1, + { + "No Fractions", + "Vertical Fractions", + "Diagonal Fractions", + NULL + } + }, { /* 12 */ + APPLE_RESERVED " 2", + 0, + {NULL} + }, { /* 13 */ + "Overlapping Characters", + 0, + { + /* "Prevent Overlap", */ + "Turns on the feature", + NULL + } + }, { /* 14 */ + "Typographic Extras", + 0, + { + "Hyphens to Em Dash", + "Hyphens to En Dash", + "Unslashed Zero", + "Form Interrobang", + "Smart Quotes", + "Periods to Ellipsis", + NULL + } + }, { /* 15 */ + "Mathematical Extras", + 0, + { + "Hyphens to Minus", + "Asterisk to Multiply", + "Slash to Divide", + "Inequality Ligatures", + "Exponents", + NULL + } + }, { /* 16 */ + "Ornament Sets", + 1, + { + "No Ornaments", + "Dingbats", + "Pi Characters", + "Fleurons", + "Decorative Borders", + "International Symbols", + "Math Symbols", + NULL + } + }, { /* 17 */ + "Character Alternatives", + 1, + { + "No Alternates", + /* TODO */ + NULL + } + }, { /* 18 */ + "Design Complexity", + 1, + { + "Design Level 1", + "Design Level 2", + "Design Level 3", + "Design Level 4", + "Design Level 5", + /* TODO */ + NULL + } + }, { /* 19 */ + "Style Options", + 1, + { + "No Style Options", + "Display Text", + "Engraved Text", + "Illuminated Caps", + "Tilling Caps", + "Tall Caps", + NULL + } + }, { /* 20 */ + "Character Shape", + 1, + { + "Traditional Characters", + "Simplified Characters", + "JIS 1978 Characters", + "JIS 1983 Characters", + "JIS 1990 Characters", + "Traditional Characters, Alternative Set 1", + "Traditional Characters, Alternative Set 2", + "Traditional Characters, Alternative Set 3", + "Traditional Characters, Alternative Set 4", + "Traditional Characters, Alternative Set 5", + "Expert Characters", + NULL /* count => 12 */ + } + }, { /* 21 */ + "Number Case", + 1, + { + "Lower Case Numbers", + "Upper Case Numbers", + NULL + } + }, { /* 22 */ + "Text Spacing", + 1, + { + "Proportional", + "Monospaced", + "Half-width", + "Normal", + NULL + } + }, /* Here after Newer */ { /* 23 */ + "Transliteration", + 1, + { + "No Transliteration", + "Hanja To Hangul", + "Hiragana to Katakana", + "Katakana to Hiragana", + "Kana to Romanization", + "Romanization to Hiragana", + "Romanization to Katakana", + "Hanja to Hangul, Alternative Set 1", + "Hanja to Hangul, Alternative Set 2", + "Hanja to Hangul, Alternative Set 3", + NULL + } + }, { /* 24 */ + "Annotation", + 1, + { + "No Annotation", + "Box Annotation", + "Rounded Box Annotation", + "Circle Annotation", + "Inverted Circle Annotation", + "Parenthesis Annotation", + "Period Annotation", + "Roman Numeral Annotation", + "Diamond Annotation", + NULL + } + }, { /* 25 */ + "Kana Spacing", + 1, + { + "Full Width", + "Proportional", + NULL + } + }, { /* 26 */ + "Ideographic Spacing", + 1, + { + "Full Width", + "Proportional", + NULL + } + }, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 27-30 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 31-35 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 36-40 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 40-45 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 46-50 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 51-55 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 56-60 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 61-65 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 66-70 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 71-75 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 76-80 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 81-85 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 86-90 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 91-95 */ + EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 96-98 */ + EMPTYFEAT, /* 99 */ { /* 100 => 22 */ + "Text Spacing", + 1, + { + "Proportional", + "Monospaced", + "Half-width", + "Normal", + NULL + } + }, { /* 101 => 25 */ + "Kana Spacing", + 1, + { + "Full Width", + "Proportional", + NULL + } + }, { /* 102 => 26 */ + "Ideographic Spacing", + 1, + { + "Full Width", + "Proportional", + NULL + } + }, { /* 103 */ + "CJK Roman Spacing", + 1, + { + "Half-width", + "Proportional", + "Default Roman", + "Full-width Roman", + NULL + } + }, { /* 104 => 1 */ + "All Typographic Features", + 0, + { + "All Type Features", + NULL + } + } + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Generator *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + int + main( void ) + { + int i; + + + printf( " {\n" ); + printf( " /* Generated from %s */\n", __FILE__ ); + + for ( i = 0; + i < sizeof ( featreg_table ) / sizeof ( GX_Feature_RegistryRec ); + i++ ) + { + const char* feat_name; + int nSettings; + + + feat_name = featreg_table[i].feat_name; + for ( nSettings = 0; + featreg_table[i].setting_name[nSettings]; + nSettings++) + ; /* Do nothing */ + + printf( " {%1d, %1d, %1d, %2d}, /* %s */\n", + feat_name ? 1 : 0, + ( feat_name && + ( ft_strncmp( feat_name, + APPLE_RESERVED, APPLE_RESERVED_LENGTH ) == 0 ) + ) ? 1 : 0, + featreg_table[i].exclusive ? 1 : 0, + nSettings, + feat_name ? feat_name : "__EMPTY__" ); + } + + printf( " };\n" ); + + return 0; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvjust.c b/drivers/freetype/src/gxvalid/gxvjust.c new file mode 100644 index 0000000000..7816e0b7fb --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvjust.c @@ -0,0 +1,717 @@ +/***************************************************************************/ +/* */ +/* gxvjust.c */ +/* */ +/* TrueTypeGX/AAT just table validation (body). */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvalid.h" +#include "gxvcommn.h" + +#include FT_SFNT_NAMES_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_gxvjust + + /* + * referred `just' table format specification: + * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6just.html + * last updated 2000. + * ---------------------------------------------- + * [JUST HEADER]: GXV_JUST_HEADER_SIZE + * version (fixed: 32bit) = 0x00010000 + * format (uint16: 16bit) = 0 is only defined (2000) + * horizOffset (uint16: 16bit) + * vertOffset (uint16: 16bit) + * ---------------------------------------------- + */ + + typedef struct GXV_just_DataRec_ + { + FT_UShort wdc_offset_max; + FT_UShort wdc_offset_min; + FT_UShort pc_offset_max; + FT_UShort pc_offset_min; + + } GXV_just_DataRec, *GXV_just_Data; + + +#define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a ) + + + /* GX just table does not define their subset of GID */ + static void + gxv_just_check_max_gid( FT_UShort gid, + const FT_String* msg_tag, + GXV_Validator valid ) + { + if ( gid < valid->face->num_glyphs ) + return; + + GXV_TRACE(( "just table includes too large %s" + " GID=%d > %d (in maxp)\n", + msg_tag, gid, valid->face->num_glyphs )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + + + static void + gxv_just_wdp_entry_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_ULong justClass; +#ifdef GXV_LOAD_UNUSED_VARS + FT_Fixed beforeGrowLimit; + FT_Fixed beforeShrinkGrowLimit; + FT_Fixed afterGrowLimit; + FT_Fixed afterShrinkGrowLimit; + FT_UShort growFlags; + FT_UShort shrinkFlags; +#endif + + + GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 ); + justClass = FT_NEXT_ULONG( p ); +#ifndef GXV_LOAD_UNUSED_VARS + p += 4 + 4 + 4 + 4 + 2 + 2; +#else + beforeGrowLimit = FT_NEXT_ULONG( p ); + beforeShrinkGrowLimit = FT_NEXT_ULONG( p ); + afterGrowLimit = FT_NEXT_ULONG( p ); + afterShrinkGrowLimit = FT_NEXT_ULONG( p ); + growFlags = FT_NEXT_USHORT( p ); + shrinkFlags = FT_NEXT_USHORT( p ); +#endif + + /* According to Apple spec, only 7bits in justClass is used */ + if ( ( justClass & 0xFFFFFF80 ) != 0 ) + { + GXV_TRACE(( "just table includes non-zero value" + " in unused justClass higher bits" + " of WidthDeltaPair" )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + + valid->subtable_length = p - table; + } + + + static void + gxv_just_wdc_entry_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_ULong count, i; + + + GXV_LIMIT_CHECK( 4 ); + count = FT_NEXT_ULONG( p ); + for ( i = 0; i < count; i++ ) + { + GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count )); + gxv_just_wdp_entry_validate( p, limit, valid ); + p += valid->subtable_length; + } + + valid->subtable_length = p - table; + } + + + static void + gxv_just_widthDeltaClusters_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table ; + FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max ); + FT_UInt i; + + + GXV_NAME_ENTER( "just justDeltaClusters" ); + + if ( limit <= wdc_end ) + FT_INVALID_OFFSET; + + for ( i = 0; p <= wdc_end; i++ ) + { + gxv_just_wdc_entry_validate( p, limit, valid ); + p += valid->subtable_length; + } + + valid->subtable_length = p - table; + + GXV_EXIT; + } + + + static void + gxv_just_actSubrecord_type0_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + FT_Fixed lowerLimit; + FT_Fixed upperLimit; +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort order; +#endif + FT_UShort decomposedCount; + + FT_UInt i; + + + GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); + lowerLimit = FT_NEXT_ULONG( p ); + upperLimit = FT_NEXT_ULONG( p ); +#ifdef GXV_LOAD_UNUSED_VARS + order = FT_NEXT_USHORT( p ); +#else + p += 2; +#endif + decomposedCount = FT_NEXT_USHORT( p ); + + if ( lowerLimit >= upperLimit ) + { + GXV_TRACE(( "just table includes invalid range spec:" + " lowerLimit(%d) > upperLimit(%d)\n" )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + + for ( i = 0; i < decomposedCount; i++ ) + { + FT_UShort glyphs; + + + GXV_LIMIT_CHECK( 2 ); + glyphs = FT_NEXT_USHORT( p ); + gxv_just_check_max_gid( glyphs, "type0:glyphs", valid ); + } + + valid->subtable_length = p - table; + } + + + static void + gxv_just_actSubrecord_type1_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort addGlyph; + + + GXV_LIMIT_CHECK( 2 ); + addGlyph = FT_NEXT_USHORT( p ); + + gxv_just_check_max_gid( addGlyph, "type1:addGlyph", valid ); + + valid->subtable_length = p - table; + } + + + static void + gxv_just_actSubrecord_type2_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; +#ifdef GXV_LOAD_UNUSED_VARS + FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ +#endif + FT_UShort addGlyph; + FT_UShort substGlyph; + + + GXV_LIMIT_CHECK( 4 + 2 + 2 ); +#ifdef GXV_LOAD_UNUSED_VARS + substThreshhold = FT_NEXT_ULONG( p ); +#else + p += 4; +#endif + addGlyph = FT_NEXT_USHORT( p ); + substGlyph = FT_NEXT_USHORT( p ); + + if ( addGlyph != 0xFFFF ) + gxv_just_check_max_gid( addGlyph, "type2:addGlyph", valid ); + + gxv_just_check_max_gid( substGlyph, "type2:substGlyph", valid ); + + valid->subtable_length = p - table; + } + + + static void + gxv_just_actSubrecord_type4_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_ULong variantsAxis; + FT_Fixed minimumLimit; + FT_Fixed noStretchValue; + FT_Fixed maximumLimit; + + + GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); + variantsAxis = FT_NEXT_ULONG( p ); + minimumLimit = FT_NEXT_ULONG( p ); + noStretchValue = FT_NEXT_ULONG( p ); + maximumLimit = FT_NEXT_ULONG( p ); + + valid->subtable_length = p - table; + + if ( variantsAxis != 0x64756374 ) /* 'duct' */ + GXV_TRACE(( "variantsAxis 0x%08x is non default value", + variantsAxis )); + + if ( minimumLimit > noStretchValue ) + GXV_TRACE(( "type4:minimumLimit 0x%08x > noStretchValue 0x%08x\n", + minimumLimit, noStretchValue )); + else if ( noStretchValue > maximumLimit ) + GXV_TRACE(( "type4:noStretchValue 0x%08x > maximumLimit 0x%08x\n", + noStretchValue, maximumLimit )); + else if ( !IS_PARANOID_VALIDATION ) + return; + + FT_INVALID_DATA; + } + + + static void + gxv_just_actSubrecord_type5_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort flags; + FT_UShort glyph; + + + GXV_LIMIT_CHECK( 2 + 2 ); + flags = FT_NEXT_USHORT( p ); + glyph = FT_NEXT_USHORT( p ); + + if ( flags ) + GXV_TRACE(( "type5: nonzero value 0x%04x in unused flags\n", + flags )); + gxv_just_check_max_gid( glyph, "type5:glyph", valid ); + + valid->subtable_length = p - table; + } + + + /* parse single actSubrecord */ + static void + gxv_just_actSubrecord_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort actionClass; + FT_UShort actionType; + FT_ULong actionLength; + + + GXV_NAME_ENTER( "just actSubrecord" ); + + GXV_LIMIT_CHECK( 2 + 2 + 4 ); + actionClass = FT_NEXT_USHORT( p ); + actionType = FT_NEXT_USHORT( p ); + actionLength = FT_NEXT_ULONG( p ); + + /* actionClass is related with justClass using 7bit only */ + if ( ( actionClass & 0xFF80 ) != 0 ) + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + + if ( actionType == 0 ) + gxv_just_actSubrecord_type0_validate( p, limit, valid ); + else if ( actionType == 1 ) + gxv_just_actSubrecord_type1_validate( p, limit, valid ); + else if ( actionType == 2 ) + gxv_just_actSubrecord_type2_validate( p, limit, valid ); + else if ( actionType == 3 ) + ; /* Stretch glyph action: no actionData */ + else if ( actionType == 4 ) + gxv_just_actSubrecord_type4_validate( p, limit, valid ); + else if ( actionType == 5 ) + gxv_just_actSubrecord_type5_validate( p, limit, valid ); + else + FT_INVALID_DATA; + + valid->subtable_length = actionLength; + + GXV_EXIT; + } + + + static void + gxv_just_pcActionRecord_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_ULong actionCount; + FT_ULong i; + + + GXV_LIMIT_CHECK( 4 ); + actionCount = FT_NEXT_ULONG( p ); + GXV_TRACE(( "actionCount = %d\n", actionCount )); + + for ( i = 0; i < actionCount; i++ ) + { + gxv_just_actSubrecord_validate( p, limit, valid ); + p += valid->subtable_length; + } + + valid->subtable_length = p - table; + + GXV_EXIT; + } + + + static void + gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + FT_UNUSED( glyph ); + + if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) ) + GXV_JUST_DATA( pc_offset_max ) = value_p->u; + if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) ) + GXV_JUST_DATA( pc_offset_min ) = value_p->u; + } + + + static void + gxv_just_pcLookupTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + GXV_NAME_ENTER( "just pcLookupTable" ); + GXV_JUST_DATA( pc_offset_max ) = 0x0000; + GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU; + + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; + + gxv_LookupTable_validate( p, limit, valid ); + + /* subtable_length is set by gxv_LookupTable_validate() */ + + GXV_EXIT; + } + + + static void + gxv_just_postcompTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + GXV_NAME_ENTER( "just postcompTable" ); + + gxv_just_pcLookupTable_validate( p, limit, valid ); + p += valid->subtable_length; + + gxv_just_pcActionRecord_validate( p, limit, valid ); + p += valid->subtable_length; + + valid->subtable_length = p - table; + + GXV_EXIT; + } + + + static void + gxv_just_classTable_entry_validate( + FT_Byte state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_UNUSED_VARS + /* TODO: validate markClass & currentClass */ + FT_UShort setMark; + FT_UShort dontAdvance; + FT_UShort markClass; + FT_UShort currentClass; +#endif + + FT_UNUSED( state ); + FT_UNUSED( glyphOffset_p ); + FT_UNUSED( table ); + FT_UNUSED( limit ); + FT_UNUSED( valid ); + +#ifndef GXV_LOAD_UNUSED_VARS + FT_UNUSED( flags ); +#else + setMark = (FT_UShort)( ( flags >> 15 ) & 1 ); + dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); + markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F ); + currentClass = (FT_UShort)( flags & 0x7F ); +#endif + } + + + static void + gxv_just_justClassTable_validate ( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort length; + FT_UShort coverage; + FT_ULong subFeatureFlags; + + + GXV_NAME_ENTER( "just justClassTable" ); + + GXV_LIMIT_CHECK( 2 + 2 + 4 ); + length = FT_NEXT_USHORT( p ); + coverage = FT_NEXT_USHORT( p ); + subFeatureFlags = FT_NEXT_ULONG( p ); + + GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s) ", coverage )); + if ( ( coverage & 0x4000 ) == 0 ) + GXV_TRACE(( "ascending\n" )); + else + GXV_TRACE(( "descending\n" )); + + if ( subFeatureFlags ) + GXV_TRACE(( " justClassTable: nonzero value (0x%08x)" + " in unused subFeatureFlags\n", subFeatureFlags )); + + valid->statetable.optdata = NULL; + valid->statetable.optdata_load_func = NULL; + valid->statetable.subtable_setup_func = NULL; + valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + valid->statetable.entry_validate_func = + gxv_just_classTable_entry_validate; + + gxv_StateTable_validate( p, table + length, valid ); + + /* subtable_length is set by gxv_LookupTable_validate() */ + + GXV_EXIT; + } + + + static void + gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + FT_UNUSED( glyph ); + + if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) ) + GXV_JUST_DATA( wdc_offset_max ) = value_p->u; + if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) ) + GXV_JUST_DATA( wdc_offset_min ) = value_p->u; + } + + + static void + gxv_just_justData_lookuptable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + GXV_JUST_DATA( wdc_offset_max ) = 0x0000; + GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU; + + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; + + gxv_LookupTable_validate( p, limit, valid ); + + /* subtable_length is set by gxv_LookupTable_validate() */ + + GXV_EXIT; + } + + + /* + * gxv_just_justData_validate() parses and validates horizData, vertData. + */ + static void + gxv_just_justData_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + /* + * following 3 offsets are measured from the start of `just' + * (which table points to), not justData + */ + FT_UShort justClassTableOffset; + FT_UShort wdcTableOffset; + FT_UShort pcTableOffset; + FT_Bytes p = table; + + GXV_ODTECT( 4, odtect ); + + + GXV_NAME_ENTER( "just justData" ); + + GXV_ODTECT_INIT( odtect ); + GXV_LIMIT_CHECK( 2 + 2 + 2 ); + justClassTableOffset = FT_NEXT_USHORT( p ); + wdcTableOffset = FT_NEXT_USHORT( p ); + pcTableOffset = FT_NEXT_USHORT( p ); + + GXV_TRACE(( " (justClassTableOffset = 0x%04x)\n", justClassTableOffset )); + GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset )); + GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset )); + + gxv_just_justData_lookuptable_validate( p, limit, valid ); + gxv_odtect_add_range( p, valid->subtable_length, + "just_LookupTable", odtect ); + + if ( wdcTableOffset ) + { + gxv_just_widthDeltaClusters_validate( + valid->root->base + wdcTableOffset, limit, valid ); + gxv_odtect_add_range( valid->root->base + wdcTableOffset, + valid->subtable_length, "just_wdcTable", odtect ); + } + + if ( pcTableOffset ) + { + gxv_just_postcompTable_validate( valid->root->base + pcTableOffset, + limit, valid ); + gxv_odtect_add_range( valid->root->base + pcTableOffset, + valid->subtable_length, "just_pcTable", odtect ); + } + + if ( justClassTableOffset ) + { + gxv_just_justClassTable_validate( + valid->root->base + justClassTableOffset, limit, valid ); + gxv_odtect_add_range( valid->root->base + justClassTableOffset, + valid->subtable_length, "just_justClassTable", + odtect ); + } + + gxv_odtect_validate( odtect, valid ); + + GXV_EXIT; + } + + + FT_LOCAL_DEF( void ) + gxv_just_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + FT_Bytes p = table; + FT_Bytes limit = 0; + + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + GXV_just_DataRec justrec; + GXV_just_Data just = &justrec; + + FT_ULong version; + FT_UShort format; + FT_UShort horizOffset; + FT_UShort vertOffset; + + GXV_ODTECT( 3, odtect ); + + + GXV_ODTECT_INIT( odtect ); + + valid->root = ftvalid; + valid->table_data = just; + valid->face = face; + + FT_TRACE3(( "validating `just' table\n" )); + GXV_INIT; + + limit = valid->root->limit; + + GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 ); + version = FT_NEXT_ULONG( p ); + format = FT_NEXT_USHORT( p ); + horizOffset = FT_NEXT_USHORT( p ); + vertOffset = FT_NEXT_USHORT( p ); + gxv_odtect_add_range( table, p - table, "just header", odtect ); + + + /* Version 1.0 (always:2000) */ + GXV_TRACE(( " (version = 0x%08x)\n", version )); + if ( version != 0x00010000UL ) + FT_INVALID_FORMAT; + + /* format 0 (always:2000) */ + GXV_TRACE(( " (format = 0x%04x)\n", format )); + if ( format != 0x0000 ) + FT_INVALID_FORMAT; + + GXV_TRACE(( " (horizOffset = %d)\n", horizOffset )); + GXV_TRACE(( " (vertOffset = %d)\n", vertOffset )); + + + /* validate justData */ + if ( 0 < horizOffset ) + { + gxv_just_justData_validate( table + horizOffset, limit, valid ); + gxv_odtect_add_range( table + horizOffset, valid->subtable_length, + "horizJustData", odtect ); + } + + if ( 0 < vertOffset ) + { + gxv_just_justData_validate( table + vertOffset, limit, valid ); + gxv_odtect_add_range( table + vertOffset, valid->subtable_length, + "vertJustData", odtect ); + } + + gxv_odtect_validate( odtect, valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvkern.c b/drivers/freetype/src/gxvalid/gxvkern.c new file mode 100644 index 0000000000..557c5f1fe4 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvkern.c @@ -0,0 +1,920 @@ +/***************************************************************************/ +/* */ +/* gxvkern.c */ +/* */ +/* TrueTypeGX/AAT kern table validation (body). */ +/* */ +/* Copyright 2004-2007, 2013 */ +/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvalid.h" +#include "gxvcommn.h" + +#include FT_SFNT_NAMES_H +#include FT_SERVICE_GX_VALIDATE_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_gxvkern + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Data and Types *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef enum GXV_kern_Version_ + { + KERN_VERSION_CLASSIC = 0x0000, + KERN_VERSION_NEW = 0x0001 + + } GXV_kern_Version; + + + typedef enum GXV_kern_Dialect_ + { + KERN_DIALECT_UNKNOWN = 0, + KERN_DIALECT_MS = FT_VALIDATE_MS, + KERN_DIALECT_APPLE = FT_VALIDATE_APPLE, + KERN_DIALECT_ANY = FT_VALIDATE_CKERN + + } GXV_kern_Dialect; + + + typedef struct GXV_kern_DataRec_ + { + GXV_kern_Version version; + void *subtable_data; + GXV_kern_Dialect dialect_request; + + } GXV_kern_DataRec, *GXV_kern_Data; + + +#define GXV_KERN_DATA( field ) GXV_TABLE_DATA( kern, field ) + +#define KERN_IS_CLASSIC( valid ) \ + ( KERN_VERSION_CLASSIC == GXV_KERN_DATA( version ) ) +#define KERN_IS_NEW( valid ) \ + ( KERN_VERSION_NEW == GXV_KERN_DATA( version ) ) + +#define KERN_DIALECT( valid ) \ + GXV_KERN_DATA( dialect_request ) +#define KERN_ALLOWS_MS( valid ) \ + ( KERN_DIALECT( valid ) & KERN_DIALECT_MS ) +#define KERN_ALLOWS_APPLE( valid ) \ + ( KERN_DIALECT( valid ) & KERN_DIALECT_APPLE ) + +#define GXV_KERN_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 4 ) +#define GXV_KERN_SUBTABLE_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 6 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SUBTABLE VALIDATORS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* ============================= format 0 ============================== */ + + static void + gxv_kern_subtable_fmt0_pairs_validate( FT_Bytes table, + FT_Bytes limit, + FT_UShort nPairs, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort i; + + FT_UShort last_gid_left = 0; + FT_UShort last_gid_right = 0; + + FT_UNUSED( limit ); + + + GXV_NAME_ENTER( "kern format 0 pairs" ); + + for ( i = 0; i < nPairs; i++ ) + { + FT_UShort gid_left; + FT_UShort gid_right; +#ifdef GXV_LOAD_UNUSED_VARS + FT_Short kernValue; +#endif + + + /* left */ + gid_left = FT_NEXT_USHORT( p ); + gxv_glyphid_validate( gid_left, valid ); + + /* right */ + gid_right = FT_NEXT_USHORT( p ); + gxv_glyphid_validate( gid_right, valid ); + + /* Pairs of left and right GIDs must be unique and sorted. */ + GXV_TRACE(( "left gid = %u, right gid = %u\n", gid_left, gid_right )); + if ( gid_left == last_gid_left ) + { + if ( last_gid_right < gid_right ) + last_gid_right = gid_right; + else + FT_INVALID_DATA; + } + else if ( last_gid_left < gid_left ) + { + last_gid_left = gid_left; + last_gid_right = gid_right; + } + else + FT_INVALID_DATA; + + /* skip the kern value */ +#ifdef GXV_LOAD_UNUSED_VARS + kernValue = FT_NEXT_SHORT( p ); +#else + p += 2; +#endif + } + + GXV_EXIT; + } + + static void + gxv_kern_subtable_fmt0_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; + + FT_UShort nPairs; + FT_UShort unitSize; + + + GXV_NAME_ENTER( "kern subtable format 0" ); + + unitSize = 2 + 2 + 2; + nPairs = 0; + + /* nPairs, searchRange, entrySelector, rangeShift */ + GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid ); + p += 2 + 2 + 2 + 2; + + gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, valid ); + + GXV_EXIT; + } + + + /* ============================= format 1 ============================== */ + + + typedef struct GXV_kern_fmt1_StateOptRec_ + { + FT_UShort valueTable; + FT_UShort valueTable_length; + + } GXV_kern_fmt1_StateOptRec, *GXV_kern_fmt1_StateOptRecData; + + + static void + gxv_kern_subtable_fmt1_valueTable_load( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + GXV_kern_fmt1_StateOptRecData optdata = + (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + + + GXV_LIMIT_CHECK( 2 ); + optdata->valueTable = FT_NEXT_USHORT( p ); + } + + + /* + * passed tables_size covers whole StateTable, including kern fmt1 header + */ + static void + gxv_kern_subtable_fmt1_subtable_setup( FT_UShort table_size, + FT_UShort classTable, + FT_UShort stateArray, + FT_UShort entryTable, + FT_UShort* classTable_length_p, + FT_UShort* stateArray_length_p, + FT_UShort* entryTable_length_p, + GXV_Validator valid ) + { + FT_UShort o[4]; + FT_UShort *l[4]; + FT_UShort buff[5]; + + GXV_kern_fmt1_StateOptRecData optdata = + (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + + + o[0] = classTable; + o[1] = stateArray; + o[2] = entryTable; + o[3] = optdata->valueTable; + l[0] = classTable_length_p; + l[1] = stateArray_length_p; + l[2] = entryTable_length_p; + l[3] = &(optdata->valueTable_length); + + gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid ); + } + + + /* + * passed table & limit are of whole StateTable, not including subtables + */ + static void + gxv_kern_subtable_fmt1_entry_validate( + FT_Byte state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort push; + FT_UShort dontAdvance; +#endif + FT_UShort valueOffset; +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort kernAction; + FT_UShort kernValue; +#endif + + FT_UNUSED( state ); + FT_UNUSED( glyphOffset_p ); + + +#ifdef GXV_LOAD_UNUSED_VARS + push = (FT_UShort)( ( flags >> 15 ) & 1 ); + dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); +#endif + valueOffset = (FT_UShort)( flags & 0x3FFF ); + + { + GXV_kern_fmt1_StateOptRecData vt_rec = + (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + FT_Bytes p; + + + if ( valueOffset < vt_rec->valueTable ) + FT_INVALID_OFFSET; + + p = table + valueOffset; + limit = table + vt_rec->valueTable + vt_rec->valueTable_length; + + GXV_LIMIT_CHECK( 2 + 2 ); +#ifdef GXV_LOAD_UNUSED_VARS + kernAction = FT_NEXT_USHORT( p ); + kernValue = FT_NEXT_USHORT( p ); +#endif + } + } + + + static void + gxv_kern_subtable_fmt1_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + GXV_kern_fmt1_StateOptRec vt_rec; + + + GXV_NAME_ENTER( "kern subtable format 1" ); + + valid->statetable.optdata = + &vt_rec; + valid->statetable.optdata_load_func = + gxv_kern_subtable_fmt1_valueTable_load; + valid->statetable.subtable_setup_func = + gxv_kern_subtable_fmt1_subtable_setup; + valid->statetable.entry_glyphoffset_fmt = + GXV_GLYPHOFFSET_NONE; + valid->statetable.entry_validate_func = + gxv_kern_subtable_fmt1_entry_validate; + + gxv_StateTable_validate( p, limit, valid ); + + GXV_EXIT; + } + + + /* ================ Data for Class-Based Subtables 2, 3 ================ */ + + typedef enum GXV_kern_ClassSpec_ + { + GXV_KERN_CLS_L = 0, + GXV_KERN_CLS_R + + } GXV_kern_ClassSpec; + + + /* ============================= format 2 ============================== */ + + /* ---------------------- format 2 specific data ----------------------- */ + + typedef struct GXV_kern_subtable_fmt2_DataRec_ + { + FT_UShort rowWidth; + FT_UShort array; + FT_UShort offset_min[2]; + FT_UShort offset_max[2]; + const FT_String* class_tag[2]; + GXV_odtect_Range odtect; + + } GXV_kern_subtable_fmt2_DataRec, *GXV_kern_subtable_fmt2_Data; + + +#define GXV_KERN_FMT2_DATA( field ) \ + ( ( (GXV_kern_subtable_fmt2_DataRec *) \ + ( GXV_KERN_DATA( subtable_data ) ) )->field ) + + + /* -------------------------- utility functions ----------------------- */ + + static void + gxv_kern_subtable_fmt2_clstbl_validate( FT_Bytes table, + FT_Bytes limit, + GXV_kern_ClassSpec spec, + GXV_Validator valid ) + { + const FT_String* tag = GXV_KERN_FMT2_DATA( class_tag[spec] ); + GXV_odtect_Range odtect = GXV_KERN_FMT2_DATA( odtect ); + + FT_Bytes p = table; + FT_UShort firstGlyph; + FT_UShort nGlyphs; + + + GXV_NAME_ENTER( "kern format 2 classTable" ); + + GXV_LIMIT_CHECK( 2 + 2 ); + firstGlyph = FT_NEXT_USHORT( p ); + nGlyphs = FT_NEXT_USHORT( p ); + GXV_TRACE(( " %s firstGlyph=%d, nGlyphs=%d\n", + tag, firstGlyph, nGlyphs )); + + gxv_glyphid_validate( firstGlyph, valid ); + gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs - 1 ), valid ); + + gxv_array_getlimits_ushort( p, p + ( 2 * nGlyphs ), + &( GXV_KERN_FMT2_DATA( offset_min[spec] ) ), + &( GXV_KERN_FMT2_DATA( offset_max[spec] ) ), + valid ); + + gxv_odtect_add_range( table, 2 * nGlyphs, tag, odtect ); + + GXV_EXIT; + } + + + static void + gxv_kern_subtable_fmt2_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + GXV_ODTECT( 3, odtect ); + GXV_kern_subtable_fmt2_DataRec fmt2_rec = + { 0, 0, { 0, 0 }, { 0, 0 }, { "leftClass", "rightClass" }, NULL }; + + FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; + FT_UShort leftOffsetTable; + FT_UShort rightOffsetTable; + + + GXV_NAME_ENTER( "kern subtable format 2" ); + + GXV_ODTECT_INIT( odtect ); + fmt2_rec.odtect = odtect; + GXV_KERN_DATA( subtable_data ) = &fmt2_rec; + + GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); + GXV_KERN_FMT2_DATA( rowWidth ) = FT_NEXT_USHORT( p ); + leftOffsetTable = FT_NEXT_USHORT( p ); + rightOffsetTable = FT_NEXT_USHORT( p ); + GXV_KERN_FMT2_DATA( array ) = FT_NEXT_USHORT( p ); + + GXV_TRACE(( "rowWidth = %d\n", GXV_KERN_FMT2_DATA( rowWidth ) )); + + + GXV_LIMIT_CHECK( leftOffsetTable ); + GXV_LIMIT_CHECK( rightOffsetTable ); + GXV_LIMIT_CHECK( GXV_KERN_FMT2_DATA( array ) ); + + gxv_kern_subtable_fmt2_clstbl_validate( table + leftOffsetTable, limit, + GXV_KERN_CLS_L, valid ); + + gxv_kern_subtable_fmt2_clstbl_validate( table + rightOffsetTable, limit, + GXV_KERN_CLS_R, valid ); + + if ( GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_L] ) + + GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_R] ) + < GXV_KERN_FMT2_DATA( array ) ) + FT_INVALID_OFFSET; + + gxv_odtect_add_range( table + GXV_KERN_FMT2_DATA( array ), + GXV_KERN_FMT2_DATA( offset_max[GXV_KERN_CLS_L] ) + + GXV_KERN_FMT2_DATA( offset_max[GXV_KERN_CLS_R] ) + - GXV_KERN_FMT2_DATA( array ), + "array", odtect ); + + gxv_odtect_validate( odtect, valid ); + + GXV_EXIT; + } + + + /* ============================= format 3 ============================== */ + + static void + gxv_kern_subtable_fmt3_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; + FT_UShort glyphCount; + FT_Byte kernValueCount; + FT_Byte leftClassCount; + FT_Byte rightClassCount; + FT_Byte flags; + + + GXV_NAME_ENTER( "kern subtable format 3" ); + + GXV_LIMIT_CHECK( 2 + 1 + 1 + 1 + 1 ); + glyphCount = FT_NEXT_USHORT( p ); + kernValueCount = FT_NEXT_BYTE( p ); + leftClassCount = FT_NEXT_BYTE( p ); + rightClassCount = FT_NEXT_BYTE( p ); + flags = FT_NEXT_BYTE( p ); + + if ( valid->face->num_glyphs != glyphCount ) + { + GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n", + valid->face->num_glyphs, glyphCount )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + + if ( flags != 0 ) + GXV_TRACE(( "kern subtable fmt3 has nonzero value" + " (%d) in unused flag\n", flags )); + /* + * just skip kernValue[kernValueCount] + */ + GXV_LIMIT_CHECK( 2 * kernValueCount ); + p += 2 * kernValueCount; + + /* + * check leftClass[gid] < leftClassCount + */ + { + FT_Byte min, max; + + + GXV_LIMIT_CHECK( glyphCount ); + gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid ); + p += valid->subtable_length; + + if ( leftClassCount < max ) + FT_INVALID_DATA; + } + + /* + * check rightClass[gid] < rightClassCount + */ + { + FT_Byte min, max; + + + GXV_LIMIT_CHECK( glyphCount ); + gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid ); + p += valid->subtable_length; + + if ( rightClassCount < max ) + FT_INVALID_DATA; + } + + /* + * check kernIndex[i, j] < kernValueCount + */ + { + FT_UShort i, j; + + + for ( i = 0; i < leftClassCount; i++ ) + { + for ( j = 0; j < rightClassCount; j++ ) + { + GXV_LIMIT_CHECK( 1 ); + if ( kernValueCount < FT_NEXT_BYTE( p ) ) + FT_INVALID_OFFSET; + } + } + } + + valid->subtable_length = p - table; + + GXV_EXIT; + } + + + static FT_Bool + gxv_kern_coverage_new_apple_validate( FT_UShort coverage, + FT_UShort* format, + GXV_Validator valid ) + { + /* new Apple-dialect */ +#ifdef GXV_LOAD_TRACE_VARS + FT_Bool kernVertical; + FT_Bool kernCrossStream; + FT_Bool kernVariation; +#endif + + FT_UNUSED( valid ); + + + /* reserved bits = 0 */ + if ( coverage & 0x1FFC ) + return FALSE; + +#ifdef GXV_LOAD_TRACE_VARS + kernVertical = FT_BOOL( ( coverage >> 15 ) & 1 ); + kernCrossStream = FT_BOOL( ( coverage >> 14 ) & 1 ); + kernVariation = FT_BOOL( ( coverage >> 13 ) & 1 ); +#endif + + *format = (FT_UShort)( coverage & 0x0003 ); + + GXV_TRACE(( "new Apple-dialect: " + "horizontal=%d, cross-stream=%d, variation=%d, format=%d\n", + !kernVertical, kernCrossStream, kernVariation, *format )); + + GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" )); + + return TRUE; + } + + + static FT_Bool + gxv_kern_coverage_classic_apple_validate( FT_UShort coverage, + FT_UShort* format, + GXV_Validator valid ) + { + /* classic Apple-dialect */ +#ifdef GXV_LOAD_TRACE_VARS + FT_Bool horizontal; + FT_Bool cross_stream; +#endif + + + /* check expected flags, but don't check if MS-dialect is impossible */ + if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( valid ) ) + return FALSE; + + /* reserved bits = 0 */ + if ( coverage & 0x02FC ) + return FALSE; + +#ifdef GXV_LOAD_TRACE_VARS + horizontal = FT_BOOL( ( coverage >> 15 ) & 1 ); + cross_stream = FT_BOOL( ( coverage >> 13 ) & 1 ); +#endif + + *format = (FT_UShort)( coverage & 0x0003 ); + + GXV_TRACE(( "classic Apple-dialect: " + "horizontal=%d, cross-stream=%d, format=%d\n", + horizontal, cross_stream, *format )); + + /* format 1 requires GX State Machine, too new for classic */ + if ( *format == 1 ) + return FALSE; + + GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" )); + + return TRUE; + } + + + static FT_Bool + gxv_kern_coverage_classic_microsoft_validate( FT_UShort coverage, + FT_UShort* format, + GXV_Validator valid ) + { + /* classic Microsoft-dialect */ +#ifdef GXV_LOAD_TRACE_VARS + FT_Bool horizontal; + FT_Bool minimum; + FT_Bool cross_stream; + FT_Bool override; +#endif + + FT_UNUSED( valid ); + + + /* reserved bits = 0 */ + if ( coverage & 0xFDF0 ) + return FALSE; + +#ifdef GXV_LOAD_TRACE_VARS + horizontal = FT_BOOL( coverage & 1 ); + minimum = FT_BOOL( ( coverage >> 1 ) & 1 ); + cross_stream = FT_BOOL( ( coverage >> 2 ) & 1 ); + override = FT_BOOL( ( coverage >> 3 ) & 1 ); +#endif + + *format = (FT_UShort)( ( coverage >> 8 ) & 0x0003 ); + + GXV_TRACE(( "classic Microsoft-dialect: " + "horizontal=%d, minimum=%d, cross-stream=%d, " + "override=%d, format=%d\n", + horizontal, minimum, cross_stream, override, *format )); + + if ( *format == 2 ) + GXV_TRACE(( + "kerning values in Microsoft format 2 subtable are ignored\n" )); + + return TRUE; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MAIN *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static GXV_kern_Dialect + gxv_kern_coverage_validate( FT_UShort coverage, + FT_UShort* format, + GXV_Validator valid ) + { + GXV_kern_Dialect result = KERN_DIALECT_UNKNOWN; + + + GXV_NAME_ENTER( "validating coverage" ); + + GXV_TRACE(( "interprete coverage 0x%04x by Apple style\n", coverage )); + + if ( KERN_IS_NEW( valid ) ) + { + if ( gxv_kern_coverage_new_apple_validate( coverage, + format, + valid ) ) + { + result = KERN_DIALECT_APPLE; + goto Exit; + } + } + + if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_APPLE( valid ) ) + { + if ( gxv_kern_coverage_classic_apple_validate( coverage, + format, + valid ) ) + { + result = KERN_DIALECT_APPLE; + goto Exit; + } + } + + if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_MS( valid ) ) + { + if ( gxv_kern_coverage_classic_microsoft_validate( coverage, + format, + valid ) ) + { + result = KERN_DIALECT_MS; + goto Exit; + } + } + + GXV_TRACE(( "cannot interprete coverage, broken kern subtable\n" )); + + Exit: + GXV_EXIT; + return result; + } + + + static void + gxv_kern_subtable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; +#ifdef GXV_LOAD_TRACE_VARS + FT_UShort version = 0; /* MS only: subtable version, unused */ +#endif + FT_ULong length; /* MS: 16bit, Apple: 32bit*/ + FT_UShort coverage; +#ifdef GXV_LOAD_TRACE_VARS + FT_UShort tupleIndex = 0; /* Apple only */ +#endif + FT_UShort u16[2]; + FT_UShort format = 255; /* subtable format */ + + + GXV_NAME_ENTER( "kern subtable" ); + + GXV_LIMIT_CHECK( 2 + 2 + 2 ); + u16[0] = FT_NEXT_USHORT( p ); /* Apple: length_hi MS: version */ + u16[1] = FT_NEXT_USHORT( p ); /* Apple: length_lo MS: length */ + coverage = FT_NEXT_USHORT( p ); + + switch ( gxv_kern_coverage_validate( coverage, &format, valid ) ) + { + case KERN_DIALECT_MS: +#ifdef GXV_LOAD_TRACE_VARS + version = u16[0]; +#endif + length = u16[1]; +#ifdef GXV_LOAD_TRACE_VARS + tupleIndex = 0; +#endif + GXV_TRACE(( "Subtable version = %d\n", version )); + GXV_TRACE(( "Subtable length = %d\n", length )); + break; + + case KERN_DIALECT_APPLE: +#ifdef GXV_LOAD_TRACE_VARS + version = 0; +#endif + length = ( u16[0] << 16 ) + u16[1]; +#ifdef GXV_LOAD_TRACE_VARS + tupleIndex = 0; +#endif + GXV_TRACE(( "Subtable length = %d\n", length )); + + if ( KERN_IS_NEW( valid ) ) + { + GXV_LIMIT_CHECK( 2 ); +#ifdef GXV_LOAD_TRACE_VARS + tupleIndex = FT_NEXT_USHORT( p ); +#else + p += 2; +#endif + GXV_TRACE(( "Subtable tupleIndex = %d\n", tupleIndex )); + } + break; + + default: + length = u16[1]; + GXV_TRACE(( "cannot detect subtable dialect, " + "just skip %d byte\n", length )); + goto Exit; + } + + /* formats 1, 2, 3 require the position of the start of this subtable */ + if ( format == 0 ) + gxv_kern_subtable_fmt0_validate( table, table + length, valid ); + else if ( format == 1 ) + gxv_kern_subtable_fmt1_validate( table, table + length, valid ); + else if ( format == 2 ) + gxv_kern_subtable_fmt2_validate( table, table + length, valid ); + else if ( format == 3 ) + gxv_kern_subtable_fmt3_validate( table, table + length, valid ); + else + FT_INVALID_DATA; + + Exit: + valid->subtable_length = length; + GXV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** kern TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + gxv_kern_validate_generic( FT_Bytes table, + FT_Face face, + FT_Bool classic_only, + GXV_kern_Dialect dialect_request, + FT_Validator ftvalid ) + { + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + + GXV_kern_DataRec kernrec; + GXV_kern_Data kern = &kernrec; + + FT_Bytes p = table; + FT_Bytes limit = 0; + + FT_ULong nTables = 0; + FT_UInt i; + + + valid->root = ftvalid; + valid->table_data = kern; + valid->face = face; + + FT_TRACE3(( "validating `kern' table\n" )); + GXV_INIT; + KERN_DIALECT( valid ) = dialect_request; + + GXV_LIMIT_CHECK( 2 ); + GXV_KERN_DATA( version ) = (GXV_kern_Version)FT_NEXT_USHORT( p ); + GXV_TRACE(( "version 0x%04x (higher 16bit)\n", + GXV_KERN_DATA( version ) )); + + if ( 0x0001 < GXV_KERN_DATA( version ) ) + FT_INVALID_FORMAT; + else if ( KERN_IS_CLASSIC( valid ) ) + { + GXV_LIMIT_CHECK( 2 ); + nTables = FT_NEXT_USHORT( p ); + } + else if ( KERN_IS_NEW( valid ) ) + { + if ( classic_only ) + FT_INVALID_FORMAT; + + if ( 0x0000 != FT_NEXT_USHORT( p ) ) + FT_INVALID_FORMAT; + + GXV_LIMIT_CHECK( 4 ); + nTables = FT_NEXT_ULONG( p ); + } + + for ( i = 0; i < nTables; i++ ) + { + GXV_TRACE(( "validating subtable %d/%d\n", i, nTables )); + /* p should be 32bit-aligned? */ + gxv_kern_subtable_validate( p, 0, valid ); + p += valid->subtable_length; + } + + FT_TRACE4(( "\n" )); + } + + + FT_LOCAL_DEF( void ) + gxv_kern_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + gxv_kern_validate_generic( table, face, 0, KERN_DIALECT_ANY, ftvalid ); + } + + + FT_LOCAL_DEF( void ) + gxv_kern_validate_classic( FT_Bytes table, + FT_Face face, + FT_Int dialect_flags, + FT_Validator ftvalid ) + { + GXV_kern_Dialect dialect_request; + + + dialect_request = (GXV_kern_Dialect)dialect_flags; + gxv_kern_validate_generic( table, face, 1, dialect_request, ftvalid ); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvlcar.c b/drivers/freetype/src/gxvalid/gxvlcar.c new file mode 100644 index 0000000000..f14fa5b131 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvlcar.c @@ -0,0 +1,223 @@ +/***************************************************************************/ +/* */ +/* gxvlcar.c */ +/* */ +/* TrueTypeGX/AAT lcar table validation (body). */ +/* */ +/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvalid.h" +#include "gxvcommn.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_gxvlcar + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Data and Types *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct GXV_lcar_DataRec_ + { + FT_UShort format; + + } GXV_lcar_DataRec, *GXV_lcar_Data; + + +#define GXV_LCAR_DATA( FIELD ) GXV_TABLE_DATA( lcar, FIELD ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + gxv_lcar_partial_validate( FT_UShort partial, + FT_UShort glyph, + GXV_Validator valid ) + { + GXV_NAME_ENTER( "partial" ); + + if ( GXV_LCAR_DATA( format ) != 1 ) + goto Exit; + + gxv_ctlPoint_validate( glyph, partial, valid ); + + Exit: + GXV_EXIT; + } + + + static void + gxv_lcar_LookupValue_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + FT_Bytes p = valid->root->base + value_p->u; + FT_Bytes limit = valid->root->limit; + FT_UShort count; + FT_Short partial; + FT_UShort i; + + + GXV_NAME_ENTER( "element in lookupTable" ); + + GXV_LIMIT_CHECK( 2 ); + count = FT_NEXT_USHORT( p ); + + GXV_LIMIT_CHECK( 2 * count ); + for ( i = 0; i < count; i++ ) + { + partial = FT_NEXT_SHORT( p ); + gxv_lcar_partial_validate( partial, glyph, valid ); + } + + GXV_EXIT; + } + + + /* + +------ lcar --------------------+ + | | + | +===============+ | + | | looup header | | + | +===============+ | + | | BinSrchHeader | | + | +===============+ | + | | lastGlyph[0] | | + | +---------------+ | + | | firstGlyph[0] | | head of lcar sfnt table + | +---------------+ | + + | | offset[0] | -> | offset [byte] + | +===============+ | + + | | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] + | +---------------+ | + | | firstGlyph[1] | | + | +---------------+ | + | | offset[1] | | + | +===============+ | + | | + | .... | + | | + | 16bit value array | + | +===============+ | + +------| value | <-------+ + | .... + | + | + | + | + | + +----> lcar values...handled by lcar callback function + */ + + static GXV_LookupValueDesc + gxv_lcar_LookupFmt4_transit( FT_UShort relative_gindex, + GXV_LookupValueCPtr base_value_p, + FT_Bytes lookuptbl_limit, + GXV_Validator valid ) + { + FT_Bytes p; + FT_Bytes limit; + FT_UShort offset; + GXV_LookupValueDesc value; + + FT_UNUSED( lookuptbl_limit ); + + /* XXX: check range? */ + offset = (FT_UShort)( base_value_p->u + + relative_gindex * sizeof ( FT_UShort ) ); + p = valid->root->base + offset; + limit = valid->root->limit; + + GXV_LIMIT_CHECK ( 2 ); + value.u = FT_NEXT_USHORT( p ); + + return value; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** lcar TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + gxv_lcar_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + FT_Bytes p = table; + FT_Bytes limit = 0; + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + + GXV_lcar_DataRec lcarrec; + GXV_lcar_Data lcar = &lcarrec; + + FT_Fixed version; + + + valid->root = ftvalid; + valid->table_data = lcar; + valid->face = face; + + FT_TRACE3(( "validating `lcar' table\n" )); + GXV_INIT; + + GXV_LIMIT_CHECK( 4 + 2 ); + version = FT_NEXT_ULONG( p ); + GXV_LCAR_DATA( format ) = FT_NEXT_USHORT( p ); + + if ( version != 0x00010000UL) + FT_INVALID_FORMAT; + + if ( GXV_LCAR_DATA( format ) > 1 ) + FT_INVALID_FORMAT; + + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_lcar_LookupValue_validate; + valid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; + gxv_LookupTable_validate( p, limit, valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmod.c b/drivers/freetype/src/gxvalid/gxvmod.c new file mode 100644 index 0000000000..278d47688a --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmod.c @@ -0,0 +1,285 @@ +/***************************************************************************/ +/* */ +/* gxvmod.c */ +/* */ +/* FreeType's TrueTypeGX/AAT validation module implementation (body). */ +/* */ +/* Copyright 2004-2006, 2013 */ +/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H +#include FT_TRUETYPE_TAGS_H +#include FT_GX_VALIDATE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_GX_VALIDATE_H + +#include "gxvmod.h" +#include "gxvalid.h" +#include "gxvcommn.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_gxvmodule + + + static FT_Error + gxv_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 ); + + + error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); + if ( FT_ERR_EQ( error, Table_Missing ) ) + return FT_Err_Ok; + if ( error ) + goto Exit; + + if ( FT_ALLOC( *table, *table_len ) ) + goto Exit; + + error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); + + Exit: + return error; + } + + +#define GXV_TABLE_DECL( _sfnt ) \ + FT_Byte* volatile _sfnt = NULL; \ + FT_ULong len_ ## _sfnt = 0 + +#define GXV_TABLE_LOAD( _sfnt ) \ + if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \ + ( gx_flags & FT_VALIDATE_ ## _sfnt ) ) \ + { \ + error = gxv_load_table( face, TTAG_ ## _sfnt, \ + &_sfnt, &len_ ## _sfnt ); \ + if ( error ) \ + goto Exit; \ + } + +#define GXV_TABLE_VALIDATE( _sfnt ) \ + if ( _sfnt ) \ + { \ + ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \ + FT_VALIDATE_DEFAULT ); \ + if ( ft_setjmp( valid.jump_buffer ) == 0 ) \ + gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \ + error = valid.error; \ + if ( error ) \ + goto Exit; \ + } + +#define GXV_TABLE_SET( _sfnt ) \ + if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) \ + tables[FT_VALIDATE_ ## _sfnt ## _INDEX] = (FT_Bytes)_sfnt + + + static FT_Error + gxv_validate( FT_Face face, + FT_UInt gx_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_count ) + { + FT_Memory volatile memory = FT_FACE_MEMORY( face ); + + FT_Error error = FT_Err_Ok; + FT_ValidatorRec volatile valid; + + FT_UInt i; + + + GXV_TABLE_DECL( feat ); + GXV_TABLE_DECL( bsln ); + GXV_TABLE_DECL( trak ); + GXV_TABLE_DECL( just ); + GXV_TABLE_DECL( mort ); + GXV_TABLE_DECL( morx ); + GXV_TABLE_DECL( kern ); + GXV_TABLE_DECL( opbd ); + GXV_TABLE_DECL( prop ); + GXV_TABLE_DECL( lcar ); + + for ( i = 0; i < table_count; i++ ) + tables[i] = 0; + + /* load tables */ + GXV_TABLE_LOAD( feat ); + GXV_TABLE_LOAD( bsln ); + GXV_TABLE_LOAD( trak ); + GXV_TABLE_LOAD( just ); + GXV_TABLE_LOAD( mort ); + GXV_TABLE_LOAD( morx ); + GXV_TABLE_LOAD( kern ); + GXV_TABLE_LOAD( opbd ); + GXV_TABLE_LOAD( prop ); + GXV_TABLE_LOAD( lcar ); + + /* validate tables */ + GXV_TABLE_VALIDATE( feat ); + GXV_TABLE_VALIDATE( bsln ); + GXV_TABLE_VALIDATE( trak ); + GXV_TABLE_VALIDATE( just ); + GXV_TABLE_VALIDATE( mort ); + GXV_TABLE_VALIDATE( morx ); + GXV_TABLE_VALIDATE( kern ); + GXV_TABLE_VALIDATE( opbd ); + GXV_TABLE_VALIDATE( prop ); + GXV_TABLE_VALIDATE( lcar ); + + /* Set results */ + GXV_TABLE_SET( feat ); + GXV_TABLE_SET( mort ); + GXV_TABLE_SET( morx ); + GXV_TABLE_SET( bsln ); + GXV_TABLE_SET( just ); + GXV_TABLE_SET( kern ); + GXV_TABLE_SET( opbd ); + GXV_TABLE_SET( trak ); + GXV_TABLE_SET( prop ); + GXV_TABLE_SET( lcar ); + + Exit: + if ( error ) + { + FT_FREE( feat ); + FT_FREE( bsln ); + FT_FREE( trak ); + FT_FREE( just ); + FT_FREE( mort ); + FT_FREE( morx ); + FT_FREE( kern ); + FT_FREE( opbd ); + FT_FREE( prop ); + FT_FREE( lcar ); + } + + return error; + } + + + static FT_Error + classic_kern_validate( FT_Face face, + FT_UInt ckern_flags, + FT_Bytes* ckern_table ) + { + FT_Memory volatile memory = FT_FACE_MEMORY( face ); + + FT_Byte* volatile ckern = NULL; + FT_ULong len_ckern = 0; + + /* without volatile on `error' GCC 4.1.1. emits: */ + /* warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */ + /* this warning seems spurious but --- */ + FT_Error volatile error; + FT_ValidatorRec volatile valid; + + + *ckern_table = NULL; + + error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern ); + if ( error ) + goto Exit; + + if ( ckern ) + { + ft_validator_init( &valid, ckern, ckern + len_ckern, + FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + gxv_kern_validate_classic( ckern, face, + ckern_flags & FT_VALIDATE_CKERN, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + *ckern_table = ckern; + + Exit: + if ( error ) + FT_FREE( ckern ); + + return error; + } + + + static + const FT_Service_GXvalidateRec gxvalid_interface = + { + gxv_validate + }; + + + static + const FT_Service_CKERNvalidateRec ckernvalid_interface = + { + classic_kern_validate + }; + + + static + const FT_ServiceDescRec gxvalid_services[] = + { + { FT_SERVICE_ID_GX_VALIDATE, &gxvalid_interface }, + { FT_SERVICE_ID_CLASSICKERN_VALIDATE, &ckernvalid_interface }, + { NULL, NULL } + }; + + + static FT_Pointer + gxvalid_get_service( FT_Module module, + const char* service_id ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( gxvalid_services, service_id ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class gxv_module_class = + { + 0, + sizeof ( FT_ModuleRec ), + "gxvalid", + 0x10000L, + 0x20000L, + + 0, /* module-specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) gxvalid_get_service + }; + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmod.h b/drivers/freetype/src/gxvalid/gxvmod.h new file mode 100644 index 0000000000..22732ba992 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmod.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* gxvmod.h */ +/* */ +/* FreeType's TrueTypeGX/AAT validation module implementation */ +/* (specification). */ +/* */ +/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __GXVMOD_H__ +#define __GXVMOD_H__ + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Module_Class ) gxv_module_class; + + +FT_END_HEADER + +#endif /* __GXVMOD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort.c b/drivers/freetype/src/gxvalid/gxvmort.c new file mode 100644 index 0000000000..5356e67ca7 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmort.c @@ -0,0 +1,297 @@ +/***************************************************************************/ +/* */ +/* gxvmort.c */ +/* */ +/* TrueTypeGX/AAT mort table validation (body). */ +/* */ +/* Copyright 2005, 2013 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmort.h" +#include "gxvfeat.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_gxvmort + + + static void + gxv_mort_feature_validate( GXV_mort_feature f, + GXV_Validator valid ) + { + if ( f->featureType >= gxv_feat_registry_length ) + { + GXV_TRACE(( "featureType %d is out of registered range, " + "setting %d is unchecked\n", + f->featureType, f->featureSetting )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + else if ( !gxv_feat_registry[f->featureType].existence ) + { + GXV_TRACE(( "featureType %d is within registered area " + "but undefined, setting %d is unchecked\n", + f->featureType, f->featureSetting )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + else + { + FT_Byte nSettings_max; + + + /* nSettings in gxvfeat.c is halved for exclusive on/off settings */ + nSettings_max = gxv_feat_registry[f->featureType].nSettings; + if ( gxv_feat_registry[f->featureType].exclusive ) + nSettings_max = (FT_Byte)( 2 * nSettings_max ); + + GXV_TRACE(( "featureType %d is registered", f->featureType )); + GXV_TRACE(( "setting %d", f->featureSetting )); + + if ( f->featureSetting > nSettings_max ) + { + GXV_TRACE(( "out of defined range %d", nSettings_max )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + GXV_TRACE(( "\n" )); + } + + /* TODO: enableFlags must be unique value in specified chain? */ + } + + + /* + * nFeatureFlags is typed to FT_ULong to accept that in + * mort (typed FT_UShort) and morx (typed FT_ULong). + */ + FT_LOCAL_DEF( void ) + gxv_mort_featurearray_validate( FT_Bytes table, + FT_Bytes limit, + FT_ULong nFeatureFlags, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_ULong i; + + GXV_mort_featureRec f = GXV_MORT_FEATURE_OFF; + + + GXV_NAME_ENTER( "mort feature list" ); + for ( i = 0; i < nFeatureFlags; i++ ) + { + GXV_LIMIT_CHECK( 2 + 2 + 4 + 4 ); + f.featureType = FT_NEXT_USHORT( p ); + f.featureSetting = FT_NEXT_USHORT( p ); + f.enableFlags = FT_NEXT_ULONG( p ); + f.disableFlags = FT_NEXT_ULONG( p ); + + gxv_mort_feature_validate( &f, valid ); + } + + if ( !IS_GXV_MORT_FEATURE_OFF( f ) ) + FT_INVALID_DATA; + + valid->subtable_length = p - table; + GXV_EXIT; + } + + + FT_LOCAL_DEF( void ) + gxv_mort_coverage_validate( FT_UShort coverage, + GXV_Validator valid ) + { + FT_UNUSED( valid ); + + if ( coverage & 0x8000U ) + GXV_TRACE(( " this subtable is for vertical text only\n" )); + else + GXV_TRACE(( " this subtable is for horizontal text only\n" )); + + if ( coverage & 0x4000 ) + GXV_TRACE(( " this subtable is applied to glyph array " + "in descending order\n" )); + else + GXV_TRACE(( " this subtable is applied to glyph array " + "in ascending order\n" )); + + if ( coverage & 0x2000 ) + GXV_TRACE(( " this subtable is forcibly applied to " + "vertical/horizontal text\n" )); + + if ( coverage & 0x1FF8 ) + GXV_TRACE(( " coverage has non-zero bits in reserved area\n" )); + } + + + static void + gxv_mort_subtables_validate( FT_Bytes table, + FT_Bytes limit, + FT_UShort nSubtables, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_Validate_Func fmt_funcs_table[] = + { + gxv_mort_subtable_type0_validate, /* 0 */ + gxv_mort_subtable_type1_validate, /* 1 */ + gxv_mort_subtable_type2_validate, /* 2 */ + NULL, /* 3 */ + gxv_mort_subtable_type4_validate, /* 4 */ + gxv_mort_subtable_type5_validate, /* 5 */ + + }; + + FT_UShort i; + + + GXV_NAME_ENTER( "subtables in a chain" ); + + for ( i = 0; i < nSubtables; i++ ) + { + GXV_Validate_Func func; + + FT_UShort length; + FT_UShort coverage; +#ifdef GXV_LOAD_UNUSED_VARS + FT_ULong subFeatureFlags; +#endif + FT_UInt type; + FT_UInt rest; + + + GXV_LIMIT_CHECK( 2 + 2 + 4 ); + length = FT_NEXT_USHORT( p ); + coverage = FT_NEXT_USHORT( p ); +#ifdef GXV_LOAD_UNUSED_VARS + subFeatureFlags = FT_NEXT_ULONG( p ); +#else + p += 4; +#endif + + GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", + i + 1, nSubtables, length )); + type = coverage & 0x0007; + rest = length - ( 2 + 2 + 4 ); + + GXV_LIMIT_CHECK( rest ); + gxv_mort_coverage_validate( coverage, valid ); + + if ( type > 5 ) + FT_INVALID_FORMAT; + + func = fmt_funcs_table[type]; + if ( func == NULL ) + GXV_TRACE(( "morx type %d is reserved\n", type )); + + func( p, p + rest, valid ); + + p += rest; + /* TODO: validate subFeatureFlags */ + } + + valid->subtable_length = p - table; + + GXV_EXIT; + } + + + static void + gxv_mort_chain_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; +#ifdef GXV_LOAD_UNUSED_VARS + FT_ULong defaultFlags; +#endif + FT_ULong chainLength; + FT_UShort nFeatureFlags; + FT_UShort nSubtables; + + + GXV_NAME_ENTER( "mort chain header" ); + + GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); +#ifdef GXV_LOAD_UNUSED_VARS + defaultFlags = FT_NEXT_ULONG( p ); +#else + p += 4; +#endif + chainLength = FT_NEXT_ULONG( p ); + nFeatureFlags = FT_NEXT_USHORT( p ); + nSubtables = FT_NEXT_USHORT( p ); + + gxv_mort_featurearray_validate( p, table + chainLength, + nFeatureFlags, valid ); + p += valid->subtable_length; + gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid ); + valid->subtable_length = chainLength; + + /* TODO: validate defaultFlags */ + GXV_EXIT; + } + + + FT_LOCAL_DEF( void ) + gxv_mort_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + FT_Bytes p = table; + FT_Bytes limit = 0; + FT_ULong version; + FT_ULong nChains; + FT_ULong i; + + + valid->root = ftvalid; + valid->face = face; + limit = valid->root->limit; + + FT_TRACE3(( "validating `mort' table\n" )); + GXV_INIT; + + GXV_LIMIT_CHECK( 4 + 4 ); + version = FT_NEXT_ULONG( p ); + nChains = FT_NEXT_ULONG( p ); + + if (version != 0x00010000UL) + FT_INVALID_FORMAT; + + for ( i = 0; i < nChains; i++ ) + { + GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); + GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); + gxv_mort_chain_validate( p, limit, valid ); + p += valid->subtable_length; + } + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort.h b/drivers/freetype/src/gxvalid/gxvmort.h new file mode 100644 index 0000000000..1e5a1f5ab6 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmort.h @@ -0,0 +1,93 @@ +/***************************************************************************/ +/* */ +/* gxvmort.h */ +/* */ +/* TrueTypeGX/AAT common definition for mort table (specification). */ +/* */ +/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __GXVMORT_H__ +#define __GXVMORT_H__ + +#include "gxvalid.h" +#include "gxvcommn.h" + +#include FT_SFNT_NAMES_H + + + typedef struct GXV_mort_featureRec_ + { + FT_UShort featureType; + FT_UShort featureSetting; + FT_ULong enableFlags; + FT_ULong disableFlags; + + } GXV_mort_featureRec, *GXV_mort_feature; + +#define GXV_MORT_FEATURE_OFF {0, 1, 0x00000000UL, 0x00000000UL} + +#define IS_GXV_MORT_FEATURE_OFF( f ) \ + ( (f).featureType == 0 || \ + (f).featureSetting == 1 || \ + (f).enableFlags == 0x00000000UL || \ + (f).disableFlags == 0x00000000UL ) + + + FT_LOCAL( void ) + gxv_mort_featurearray_validate( FT_Bytes table, + FT_Bytes limit, + FT_ULong nFeatureFlags, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_mort_coverage_validate( FT_UShort coverage, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_mort_subtable_type0_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_mort_subtable_type1_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_mort_subtable_type2_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_mort_subtable_type4_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_mort_subtable_type5_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + +#endif /* __GXVMORT_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort0.c b/drivers/freetype/src/gxvalid/gxvmort0.c new file mode 100644 index 0000000000..b136ceda27 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmort0.c @@ -0,0 +1,151 @@ +/***************************************************************************/ +/* */ +/* gxvmort0.c */ +/* */ +/* TrueTypeGX/AAT mort table validation */ +/* body for type0 (Indic Script Rearrangement) subtable. */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmort.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_gxvmort + + + static const char* GXV_Mort_IndicScript_Msg[] = + { + "no change", + "Ax => xA", + "xD => Dx", + "AxD => DxA", + "ABx => xAB", + "ABx => xBA", + "xCD => CDx", + "xCD => DCx", + "AxCD => CDxA", + "AxCD => DCxA", + "ABxD => DxAB", + "ABxD => DxBA", + "ABxCD => CDxAB", + "ABxCD => CDxBA", + "ABxCD => DCxAB", + "ABxCD => DCxBA", + + }; + + + static void + gxv_mort_subtable_type0_entry_validate( + FT_Byte state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_UShort markFirst; + FT_UShort dontAdvance; + FT_UShort markLast; + FT_UShort reserved; + FT_UShort verb = 0; + + FT_UNUSED( state ); + FT_UNUSED( table ); + FT_UNUSED( limit ); + + FT_UNUSED( GXV_Mort_IndicScript_Msg[verb] ); /* for the non-debugging */ + FT_UNUSED( glyphOffset_p ); /* case */ + + + markFirst = (FT_UShort)( ( flags >> 15 ) & 1 ); + dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); + markLast = (FT_UShort)( ( flags >> 13 ) & 1 ); + + reserved = (FT_UShort)( flags & 0x1FF0 ); + verb = (FT_UShort)( flags & 0x000F ); + + GXV_TRACE(( " IndicScript MorphRule for glyphOffset 0x%04x", + glyphOffset_p->u )); + GXV_TRACE(( " markFirst=%01d", markFirst )); + GXV_TRACE(( " dontAdvance=%01d", dontAdvance )); + GXV_TRACE(( " markLast=%01d", markLast )); + GXV_TRACE(( " %02d", verb )); + GXV_TRACE(( " %s\n", GXV_Mort_IndicScript_Msg[verb] )); + + if ( markFirst > 0 && markLast > 0 ) + { + GXV_TRACE(( " [odd] a glyph is marked as the first and last" + " in Indic rearrangement\n" )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + + if ( markFirst > 0 && dontAdvance > 0 ) + { + GXV_TRACE(( " [odd] the first glyph is marked as dontAdvance" + " in Indic rearrangement\n" )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + + if ( 0 < reserved ) + { + GXV_TRACE(( " non-zero bits found in reserved range\n" )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + else + GXV_TRACE(( "\n" )); + } + + + FT_LOCAL_DEF( void ) + gxv_mort_subtable_type0_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + GXV_NAME_ENTER( + "mort chain subtable type0 (Indic-Script Rearrangement)" ); + + GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); + + valid->statetable.optdata = NULL; + valid->statetable.optdata_load_func = NULL; + valid->statetable.subtable_setup_func = NULL; + valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + valid->statetable.entry_validate_func = + gxv_mort_subtable_type0_entry_validate; + + gxv_StateTable_validate( p, limit, valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort1.c b/drivers/freetype/src/gxvalid/gxvmort1.c new file mode 100644 index 0000000000..1c17a5d92a --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmort1.c @@ -0,0 +1,259 @@ +/***************************************************************************/ +/* */ +/* gxvmort1.c */ +/* */ +/* TrueTypeGX/AAT mort table validation */ +/* body for type1 (Contextual Substitution) subtable. */ +/* */ +/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmort.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_gxvmort + + + typedef struct GXV_mort_subtable_type1_StateOptRec_ + { + FT_UShort substitutionTable; + FT_UShort substitutionTable_length; + + } GXV_mort_subtable_type1_StateOptRec, + *GXV_mort_subtable_type1_StateOptRecData; + +#define GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE \ + ( GXV_STATETABLE_HEADER_SIZE + 2 ) + + + static void + gxv_mort_subtable_type1_substitutionTable_load( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_mort_subtable_type1_StateOptRecData optdata = + (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata; + + + GXV_LIMIT_CHECK( 2 ); + optdata->substitutionTable = FT_NEXT_USHORT( p ); + } + + + static void + gxv_mort_subtable_type1_subtable_setup( FT_UShort table_size, + FT_UShort classTable, + FT_UShort stateArray, + FT_UShort entryTable, + FT_UShort* classTable_length_p, + FT_UShort* stateArray_length_p, + FT_UShort* entryTable_length_p, + GXV_Validator valid ) + { + FT_UShort o[4]; + FT_UShort *l[4]; + FT_UShort buff[5]; + + GXV_mort_subtable_type1_StateOptRecData optdata = + (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata; + + + o[0] = classTable; + o[1] = stateArray; + o[2] = entryTable; + o[3] = optdata->substitutionTable; + l[0] = classTable_length_p; + l[1] = stateArray_length_p; + l[2] = entryTable_length_p; + l[3] = &( optdata->substitutionTable_length ); + + gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid ); + } + + + static void + gxv_mort_subtable_type1_offset_to_subst_validate( + FT_Short wordOffset, + const FT_String* tag, + FT_Byte state, + GXV_Validator valid ) + { + FT_UShort substTable; + FT_UShort substTable_limit; + + FT_UNUSED( tag ); + FT_UNUSED( state ); + + + substTable = + ((GXV_mort_subtable_type1_StateOptRec *) + (valid->statetable.optdata))->substitutionTable; + substTable_limit = + (FT_UShort)( substTable + + ((GXV_mort_subtable_type1_StateOptRec *) + (valid->statetable.optdata))->substitutionTable_length ); + + valid->min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 ); + valid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 ); + valid->max_gid = (FT_UShort)( FT_MAX( valid->max_gid, + valid->face->num_glyphs ) ); + + /* XXX: check range? */ + + /* TODO: min_gid & max_gid comparison with ClassTable contents */ + } + + + static void + gxv_mort_subtable_type1_entry_validate( + FT_Byte state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort setMark; + FT_UShort dontAdvance; +#endif + FT_UShort reserved; + FT_Short markOffset; + FT_Short currentOffset; + + FT_UNUSED( table ); + FT_UNUSED( limit ); + + +#ifdef GXV_LOAD_UNUSED_VARS + setMark = (FT_UShort)( flags >> 15 ); + dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); +#endif + reserved = (FT_Short)( flags & 0x3FFF ); + + markOffset = (FT_Short)( glyphOffset_p->ul >> 16 ); + currentOffset = (FT_Short)( glyphOffset_p->ul ); + + if ( 0 < reserved ) + { + GXV_TRACE(( " non-zero bits found in reserved range\n" )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + + gxv_mort_subtable_type1_offset_to_subst_validate( markOffset, + "markOffset", + state, + valid ); + + gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset, + "currentOffset", + state, + valid ); + } + + + static void + gxv_mort_subtable_type1_substTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort num_gids = (FT_UShort)( + ((GXV_mort_subtable_type1_StateOptRec *) + (valid->statetable.optdata))->substitutionTable_length / 2 ); + FT_UShort i; + + + GXV_NAME_ENTER( "validating contents of substitutionTable" ); + for ( i = 0; i < num_gids ; i ++ ) + { + FT_UShort dst_gid; + + + GXV_LIMIT_CHECK( 2 ); + dst_gid = FT_NEXT_USHORT( p ); + + if ( dst_gid >= 0xFFFFU ) + continue; + + if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid ) + { + GXV_TRACE(( "substTable include a strange gid[%d]=%d >" + " out of define range (%d..%d)\n", + i, dst_gid, valid->min_gid, valid->max_gid )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + } + + GXV_EXIT; + } + + + /* + * subtable for Contextual glyph substitution is a modified StateTable. + * In addition to classTable, stateArray, and entryTable, the field + * `substitutionTable' is added. + */ + FT_LOCAL_DEF( void ) + gxv_mort_subtable_type1_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_mort_subtable_type1_StateOptRec st_rec; + + + GXV_NAME_ENTER( "mort chain subtable type1 (Contextual Glyph Subst)" ); + + GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE ); + + valid->statetable.optdata = + &st_rec; + valid->statetable.optdata_load_func = + gxv_mort_subtable_type1_substitutionTable_load; + valid->statetable.subtable_setup_func = + gxv_mort_subtable_type1_subtable_setup; + valid->statetable.entry_glyphoffset_fmt = + GXV_GLYPHOFFSET_ULONG; + valid->statetable.entry_validate_func = + + gxv_mort_subtable_type1_entry_validate; + gxv_StateTable_validate( p, limit, valid ); + + gxv_mort_subtable_type1_substTable_validate( + table + st_rec.substitutionTable, + table + st_rec.substitutionTable + st_rec.substitutionTable_length, + valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort2.c b/drivers/freetype/src/gxvalid/gxvmort2.c new file mode 100644 index 0000000000..9e08fb792a --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmort2.c @@ -0,0 +1,311 @@ +/***************************************************************************/ +/* */ +/* gxvmort2.c */ +/* */ +/* TrueTypeGX/AAT mort table validation */ +/* body for type2 (Ligature Substitution) subtable. */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmort.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_gxvmort + + + typedef struct GXV_mort_subtable_type2_StateOptRec_ + { + FT_UShort ligActionTable; + FT_UShort componentTable; + FT_UShort ligatureTable; + FT_UShort ligActionTable_length; + FT_UShort componentTable_length; + FT_UShort ligatureTable_length; + + } GXV_mort_subtable_type2_StateOptRec, + *GXV_mort_subtable_type2_StateOptRecData; + +#define GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE \ + ( GXV_STATETABLE_HEADER_SIZE + 2 + 2 + 2 ) + + + static void + gxv_mort_subtable_type2_opttable_load( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + GXV_mort_subtable_type2_StateOptRecData optdata = + (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + + + GXV_LIMIT_CHECK( 2 + 2 + 2 ); + optdata->ligActionTable = FT_NEXT_USHORT( p ); + optdata->componentTable = FT_NEXT_USHORT( p ); + optdata->ligatureTable = FT_NEXT_USHORT( p ); + + GXV_TRACE(( "offset to ligActionTable=0x%04x\n", + optdata->ligActionTable )); + GXV_TRACE(( "offset to componentTable=0x%04x\n", + optdata->componentTable )); + GXV_TRACE(( "offset to ligatureTable=0x%04x\n", + optdata->ligatureTable )); + } + + + static void + gxv_mort_subtable_type2_subtable_setup( FT_UShort table_size, + FT_UShort classTable, + FT_UShort stateArray, + FT_UShort entryTable, + FT_UShort *classTable_length_p, + FT_UShort *stateArray_length_p, + FT_UShort *entryTable_length_p, + GXV_Validator valid ) + { + FT_UShort o[6]; + FT_UShort *l[6]; + FT_UShort buff[7]; + + GXV_mort_subtable_type2_StateOptRecData optdata = + (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + + + GXV_NAME_ENTER( "subtable boundaries setup" ); + + o[0] = classTable; + o[1] = stateArray; + o[2] = entryTable; + o[3] = optdata->ligActionTable; + o[4] = optdata->componentTable; + o[5] = optdata->ligatureTable; + l[0] = classTable_length_p; + l[1] = stateArray_length_p; + l[2] = entryTable_length_p; + l[3] = &(optdata->ligActionTable_length); + l[4] = &(optdata->componentTable_length); + l[5] = &(optdata->ligatureTable_length); + + gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, valid ); + + GXV_TRACE(( "classTable: offset=0x%04x length=0x%04x\n", + classTable, *classTable_length_p )); + GXV_TRACE(( "stateArray: offset=0x%04x length=0x%04x\n", + stateArray, *stateArray_length_p )); + GXV_TRACE(( "entryTable: offset=0x%04x length=0x%04x\n", + entryTable, *entryTable_length_p )); + GXV_TRACE(( "ligActionTable: offset=0x%04x length=0x%04x\n", + optdata->ligActionTable, + optdata->ligActionTable_length )); + GXV_TRACE(( "componentTable: offset=0x%04x length=0x%04x\n", + optdata->componentTable, + optdata->componentTable_length )); + GXV_TRACE(( "ligatureTable: offset=0x%04x length=0x%04x\n", + optdata->ligatureTable, + optdata->ligatureTable_length )); + + GXV_EXIT; + } + + + static void + gxv_mort_subtable_type2_ligActionOffset_validate( + FT_Bytes table, + FT_UShort ligActionOffset, + GXV_Validator valid ) + { + /* access ligActionTable */ + GXV_mort_subtable_type2_StateOptRecData optdata = + (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + + FT_Bytes lat_base = table + optdata->ligActionTable; + FT_Bytes p = table + ligActionOffset; + FT_Bytes lat_limit = lat_base + optdata->ligActionTable; + + + GXV_32BIT_ALIGNMENT_VALIDATE( ligActionOffset ); + if ( p < lat_base ) + { + GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%d byte rewind)\n", + ligActionOffset, lat_base - p )); + + /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } + else if ( lat_limit < p ) + { + GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%d byte overrun)\n", + ligActionOffset, p - lat_limit )); + + /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } + else + { + /* validate entry in ligActionTable */ + FT_ULong lig_action; +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort last; + FT_UShort store; +#endif + FT_ULong offset; + + + lig_action = FT_NEXT_ULONG( p ); +#ifdef GXV_LOAD_UNUSED_VARS + last = (FT_UShort)( ( lig_action >> 31 ) & 1 ); + store = (FT_UShort)( ( lig_action >> 30 ) & 1 ); +#endif + + /* Apple spec defines this offset as a word offset */ + offset = lig_action & 0x3FFFFFFFUL; + if ( offset * 2 < optdata->ligatureTable ) + { + GXV_TRACE(( "too short offset 0x%08x:" + " 2 x offset < ligatureTable (%d byte rewind)\n", + offset, optdata->ligatureTable - offset * 2 )); + + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } else if ( offset * 2 > + optdata->ligatureTable + optdata->ligatureTable_length ) + { + GXV_TRACE(( "too long offset 0x%08x:" + " 2 x offset > ligatureTable + ligatureTable_length" + " (%d byte overrun)\n", + offset, + optdata->ligatureTable + optdata->ligatureTable_length + - offset * 2 )); + + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } + } + } + + + static void + gxv_mort_subtable_type2_entry_validate( + FT_Byte state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort setComponent; + FT_UShort dontAdvance; +#endif + FT_UShort offset; + + FT_UNUSED( state ); + FT_UNUSED( glyphOffset_p ); + FT_UNUSED( limit ); + + +#ifdef GXV_LOAD_UNUSED_VARS + setComponent = (FT_UShort)( ( flags >> 15 ) & 1 ); + dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); +#endif + + offset = (FT_UShort)( flags & 0x3FFFU ); + + if ( 0 < offset ) + gxv_mort_subtable_type2_ligActionOffset_validate( table, offset, + valid ); + } + + + static void + gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes table, + GXV_Validator valid ) + { + GXV_mort_subtable_type2_StateOptRecData optdata = + (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + + FT_Bytes p = table + optdata->ligatureTable; + FT_Bytes limit = table + optdata->ligatureTable + + optdata->ligatureTable_length; + + + GXV_NAME_ENTER( "mort chain subtable type2 - substitutionTable" ); + if ( 0 != optdata->ligatureTable ) + { + /* Apple does not give specification of ligatureTable format */ + while ( p < limit ) + { + FT_UShort lig_gid; + + + GXV_LIMIT_CHECK( 2 ); + lig_gid = FT_NEXT_USHORT( p ); + + if ( valid->face->num_glyphs < lig_gid ) + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + } + GXV_EXIT; + } + + + FT_LOCAL_DEF( void ) + gxv_mort_subtable_type2_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_mort_subtable_type2_StateOptRec lig_rec; + + + GXV_NAME_ENTER( "mort chain subtable type2 (Ligature Substitution)" ); + + GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ); + + valid->statetable.optdata = + &lig_rec; + valid->statetable.optdata_load_func = + gxv_mort_subtable_type2_opttable_load; + valid->statetable.subtable_setup_func = + gxv_mort_subtable_type2_subtable_setup; + valid->statetable.entry_glyphoffset_fmt = + GXV_GLYPHOFFSET_NONE; + valid->statetable.entry_validate_func = + gxv_mort_subtable_type2_entry_validate; + + gxv_StateTable_validate( p, limit, valid ); + + p += valid->subtable_length; + gxv_mort_subtable_type2_ligatureTable_validate( table, valid ); + + valid->subtable_length = p - table; + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort4.c b/drivers/freetype/src/gxvalid/gxvmort4.c new file mode 100644 index 0000000000..83470988c0 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmort4.c @@ -0,0 +1,125 @@ +/***************************************************************************/ +/* */ +/* gxvmort4.c */ +/* */ +/* TrueTypeGX/AAT mort table validation */ +/* body for type4 (Non-Contextual Glyph Substitution) subtable. */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmort.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_gxvmort + + + static void + gxv_mort_subtable_type4_lookupval_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + FT_UNUSED( glyph ); + + gxv_glyphid_validate( value_p->u, valid ); + } + + /* + +===============+ --------+ + | lookup header | | + +===============+ | + | BinSrchHeader | | + +===============+ | + | lastGlyph[0] | | + +---------------+ | + | firstGlyph[0] | | head of lookup table + +---------------+ | + + | offset[0] | -> | offset [byte] + +===============+ | + + | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] + +---------------+ | + | firstGlyph[1] | | + +---------------+ | + | offset[1] | | + +===============+ | + | + .... | + | + 16bit value array | + +===============+ | + | value | <-------+ + .... + */ + + static GXV_LookupValueDesc + gxv_mort_subtable_type4_lookupfmt4_transit( + FT_UShort relative_gindex, + GXV_LookupValueCPtr base_value_p, + FT_Bytes lookuptbl_limit, + GXV_Validator valid ) + { + FT_Bytes p; + FT_Bytes limit; + FT_UShort offset; + GXV_LookupValueDesc value; + + /* XXX: check range? */ + offset = (FT_UShort)( base_value_p->u + + relative_gindex * sizeof ( FT_UShort ) ); + + p = valid->lookuptbl_head + offset; + limit = lookuptbl_limit; + + GXV_LIMIT_CHECK( 2 ); + value.u = FT_NEXT_USHORT( p ); + + return value; + } + + + FT_LOCAL_DEF( void ) + gxv_mort_subtable_type4_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + GXV_NAME_ENTER( "mort chain subtable type4 " + "(Non-Contextual Glyph Substitution)" ); + + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_mort_subtable_type4_lookupval_validate; + valid->lookupfmt4_trans = gxv_mort_subtable_type4_lookupfmt4_transit; + + gxv_LookupTable_validate( p, limit, valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort5.c b/drivers/freetype/src/gxvalid/gxvmort5.c new file mode 100644 index 0000000000..32cfb03639 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmort5.c @@ -0,0 +1,233 @@ +/***************************************************************************/ +/* */ +/* gxvmort5.c */ +/* */ +/* TrueTypeGX/AAT mort table validation */ +/* body for type5 (Contextual Glyph Insertion) subtable. */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmort.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_gxvmort + + + /* + * mort subtable type5 (Contextual Glyph Insertion) + * has the format of StateTable with insertion-glyph-list, + * but without name. The offset is given by glyphOffset in + * entryTable. There is no table location declaration + * like xxxTable. + */ + + typedef struct GXV_mort_subtable_type5_StateOptRec_ + { + FT_UShort classTable; + FT_UShort stateArray; + FT_UShort entryTable; + +#define GXV_MORT_SUBTABLE_TYPE5_HEADER_SIZE GXV_STATETABLE_HEADER_SIZE + + FT_UShort* classTable_length_p; + FT_UShort* stateArray_length_p; + FT_UShort* entryTable_length_p; + + } GXV_mort_subtable_type5_StateOptRec, + *GXV_mort_subtable_type5_StateOptRecData; + + + FT_LOCAL_DEF( void ) + gxv_mort_subtable_type5_subtable_setup( FT_UShort table_size, + FT_UShort classTable, + FT_UShort stateArray, + FT_UShort entryTable, + FT_UShort* classTable_length_p, + FT_UShort* stateArray_length_p, + FT_UShort* entryTable_length_p, + GXV_Validator valid ) + { + GXV_mort_subtable_type5_StateOptRecData optdata = + (GXV_mort_subtable_type5_StateOptRecData)valid->statetable.optdata; + + + gxv_StateTable_subtable_setup( table_size, + classTable, + stateArray, + entryTable, + classTable_length_p, + stateArray_length_p, + entryTable_length_p, + valid ); + + optdata->classTable = classTable; + optdata->stateArray = stateArray; + optdata->entryTable = entryTable; + + optdata->classTable_length_p = classTable_length_p; + optdata->stateArray_length_p = stateArray_length_p; + optdata->entryTable_length_p = entryTable_length_p; + } + + + static void + gxv_mort_subtable_type5_InsertList_validate( FT_UShort offset, + FT_UShort count, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + /* + * We don't know the range of insertion-glyph-list. + * Set range by whole of state table. + */ + FT_Bytes p = table + offset; + + GXV_mort_subtable_type5_StateOptRecData optdata = + (GXV_mort_subtable_type5_StateOptRecData)valid->statetable.optdata; + + if ( optdata->classTable < offset && + offset < optdata->classTable + *(optdata->classTable_length_p) ) + GXV_TRACE(( " offset runs into ClassTable" )); + if ( optdata->stateArray < offset && + offset < optdata->stateArray + *(optdata->stateArray_length_p) ) + GXV_TRACE(( " offset runs into StateArray" )); + if ( optdata->entryTable < offset && + offset < optdata->entryTable + *(optdata->entryTable_length_p) ) + GXV_TRACE(( " offset runs into EntryTable" )); + +#ifndef GXV_LOAD_TRACE_VARS + GXV_LIMIT_CHECK( count * 2 ); +#else + while ( p < table + offset + ( count * 2 ) ) + { + FT_UShort insert_glyphID; + + + GXV_LIMIT_CHECK( 2 ); + insert_glyphID = FT_NEXT_USHORT( p ); + GXV_TRACE(( " 0x%04x", insert_glyphID )); + } + GXV_TRACE(( "\n" )); +#endif + } + + + static void + gxv_mort_subtable_type5_entry_validate( + FT_Byte state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_UNUSED_VARS + FT_Bool setMark; + FT_Bool dontAdvance; + FT_Bool currentIsKashidaLike; + FT_Bool markedIsKashidaLike; + FT_Bool currentInsertBefore; + FT_Bool markedInsertBefore; +#endif + FT_Byte currentInsertCount; + FT_Byte markedInsertCount; + FT_UShort currentInsertList; + FT_UShort markedInsertList; + + FT_UNUSED( state ); + + +#ifdef GXV_LOAD_UNUSED_VARS + setMark = FT_BOOL( ( flags >> 15 ) & 1 ); + dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 ); + currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 ); + markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 ); + currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 ); + markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 ); +#endif + + currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); + markedInsertCount = (FT_Byte)( flags & 0x001F ); + + currentInsertList = (FT_UShort)( glyphOffset->ul >> 16 ); + markedInsertList = (FT_UShort)( glyphOffset->ul ); + + if ( 0 != currentInsertList && 0 != currentInsertCount ) + { + gxv_mort_subtable_type5_InsertList_validate( currentInsertList, + currentInsertCount, + table, + limit, + valid ); + } + + if ( 0 != markedInsertList && 0 != markedInsertCount ) + { + gxv_mort_subtable_type5_InsertList_validate( markedInsertList, + markedInsertCount, + table, + limit, + valid ); + } + } + + + FT_LOCAL_DEF( void ) + gxv_mort_subtable_type5_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_mort_subtable_type5_StateOptRec et_rec; + GXV_mort_subtable_type5_StateOptRecData et = &et_rec; + + + GXV_NAME_ENTER( "mort chain subtable type5 (Glyph Insertion)" ); + + GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE5_HEADER_SIZE ); + + valid->statetable.optdata = + et; + valid->statetable.optdata_load_func = + NULL; + valid->statetable.subtable_setup_func = + gxv_mort_subtable_type5_subtable_setup; + valid->statetable.entry_glyphoffset_fmt = + GXV_GLYPHOFFSET_ULONG; + valid->statetable.entry_validate_func = + gxv_mort_subtable_type5_entry_validate; + + gxv_StateTable_validate( p, limit, valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmorx.c b/drivers/freetype/src/gxvalid/gxvmorx.c new file mode 100644 index 0000000000..5ae04d3212 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmorx.c @@ -0,0 +1,199 @@ +/***************************************************************************/ +/* */ +/* gxvmorx.c */ +/* */ +/* TrueTypeGX/AAT morx table validation (body). */ +/* */ +/* Copyright 2005, 2008, 2013 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmorx.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_gxvmorx + + + static void + gxv_morx_subtables_validate( FT_Bytes table, + FT_Bytes limit, + FT_UShort nSubtables, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_Validate_Func fmt_funcs_table[] = + { + gxv_morx_subtable_type0_validate, /* 0 */ + gxv_morx_subtable_type1_validate, /* 1 */ + gxv_morx_subtable_type2_validate, /* 2 */ + NULL, /* 3 */ + gxv_morx_subtable_type4_validate, /* 4 */ + gxv_morx_subtable_type5_validate, /* 5 */ + + }; + + FT_UShort i; + + + GXV_NAME_ENTER( "subtables in a chain" ); + + for ( i = 0; i < nSubtables; i++ ) + { + GXV_Validate_Func func; + + FT_ULong length; + FT_ULong coverage; +#ifdef GXV_LOAD_UNUSED_VARS + FT_ULong subFeatureFlags; +#endif + FT_ULong type; + FT_ULong rest; + + + GXV_LIMIT_CHECK( 4 + 4 + 4 ); + length = FT_NEXT_ULONG( p ); + coverage = FT_NEXT_ULONG( p ); +#ifdef GXV_LOAD_UNUSED_VARS + subFeatureFlags = FT_NEXT_ULONG( p ); +#else + p += 4; +#endif + + GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", + i + 1, nSubtables, length )); + + type = coverage & 0x0007; + rest = length - ( 4 + 4 + 4 ); + GXV_LIMIT_CHECK( rest ); + + /* morx coverage consists of mort_coverage & 16bit padding */ + gxv_mort_coverage_validate( (FT_UShort)( ( coverage >> 16 ) | coverage ), + valid ); + if ( type > 5 ) + FT_INVALID_FORMAT; + + func = fmt_funcs_table[type]; + if ( func == NULL ) + GXV_TRACE(( "morx type %d is reserved\n", type )); + + func( p, p + rest, valid ); + + /* TODO: subFeatureFlags should be unique in a table? */ + p += rest; + } + + valid->subtable_length = p - table; + + GXV_EXIT; + } + + + static void + gxv_morx_chain_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; +#ifdef GXV_LOAD_UNUSED_VARS + FT_ULong defaultFlags; +#endif + FT_ULong chainLength; + FT_ULong nFeatureFlags; + FT_ULong nSubtables; + + + GXV_NAME_ENTER( "morx chain header" ); + + GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); +#ifdef GXV_LOAD_UNUSED_VARS + defaultFlags = FT_NEXT_ULONG( p ); +#else + p += 4; +#endif + chainLength = FT_NEXT_ULONG( p ); + nFeatureFlags = FT_NEXT_ULONG( p ); + nSubtables = FT_NEXT_ULONG( p ); + + /* feature-array of morx is same with that of mort */ + gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid ); + p += valid->subtable_length; + + if ( nSubtables >= 0x10000L ) + FT_INVALID_DATA; + + gxv_morx_subtables_validate( p, table + chainLength, + (FT_UShort)nSubtables, valid ); + + valid->subtable_length = chainLength; + + /* TODO: defaultFlags should be compared with the flags in tables */ + + GXV_EXIT; + } + + + FT_LOCAL_DEF( void ) + gxv_morx_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + FT_Bytes p = table; + FT_Bytes limit = 0; + FT_ULong version; + FT_ULong nChains; + FT_ULong i; + + + valid->root = ftvalid; + valid->face = face; + + FT_TRACE3(( "validating `morx' table\n" )); + GXV_INIT; + + GXV_LIMIT_CHECK( 4 + 4 ); + version = FT_NEXT_ULONG( p ); + nChains = FT_NEXT_ULONG( p ); + + if ( version != 0x00020000UL ) + FT_INVALID_FORMAT; + + for ( i = 0; i < nChains; i++ ) + { + GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); + GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); + gxv_morx_chain_validate( p, limit, valid ); + p += valid->subtable_length; + } + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmorx.h b/drivers/freetype/src/gxvalid/gxvmorx.h new file mode 100644 index 0000000000..28c1a44f6f --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmorx.h @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* gxvmorx.h */ +/* */ +/* TrueTypeGX/AAT common definition for morx table (specification). */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __GXVMORX_H__ +#define __GXVMORX_H__ + + +#include "gxvalid.h" +#include "gxvcommn.h" +#include "gxvmort.h" + +#include FT_SFNT_NAMES_H + + + FT_LOCAL( void ) + gxv_morx_subtable_type0_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_morx_subtable_type1_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_morx_subtable_type2_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_morx_subtable_type4_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + FT_LOCAL( void ) + gxv_morx_subtable_type5_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ); + + +#endif /* __GXVMORX_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmorx0.c b/drivers/freetype/src/gxvalid/gxvmorx0.c new file mode 100644 index 0000000000..6a736c1775 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmorx0.c @@ -0,0 +1,111 @@ +/***************************************************************************/ +/* */ +/* gxvmorx0.c */ +/* */ +/* TrueTypeGX/AAT morx table validation */ +/* body for type0 (Indic Script Rearrangement) subtable. */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmorx.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_gxvmorx + + + static void + gxv_morx_subtable_type0_entry_validate( + FT_UShort state, + FT_UShort flags, + GXV_XStateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort markFirst; + FT_UShort dontAdvance; + FT_UShort markLast; +#endif + FT_UShort reserved; +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort verb; +#endif + + FT_UNUSED( state ); + FT_UNUSED( glyphOffset_p ); + FT_UNUSED( table ); + FT_UNUSED( limit ); + + +#ifdef GXV_LOAD_UNUSED_VARS + markFirst = (FT_UShort)( ( flags >> 15 ) & 1 ); + dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); + markLast = (FT_UShort)( ( flags >> 13 ) & 1 ); +#endif + + reserved = (FT_UShort)( flags & 0x1FF0 ); +#ifdef GXV_LOAD_UNUSED_VARS + verb = (FT_UShort)( flags & 0x000F ); +#endif + + if ( 0 < reserved ) + { + GXV_TRACE(( " non-zero bits found in reserved range\n" )); + FT_INVALID_DATA; + } + } + + + FT_LOCAL_DEF( void ) + gxv_morx_subtable_type0_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + + GXV_NAME_ENTER( + "morx chain subtable type0 (Indic-Script Rearrangement)" ); + + GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); + + valid->xstatetable.optdata = NULL; + valid->xstatetable.optdata_load_func = NULL; + valid->xstatetable.subtable_setup_func = NULL; + valid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + valid->xstatetable.entry_validate_func = + gxv_morx_subtable_type0_entry_validate; + + gxv_XStateTable_validate( p, limit, valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmorx1.c b/drivers/freetype/src/gxvalid/gxvmorx1.c new file mode 100644 index 0000000000..ce0009a16f --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmorx1.c @@ -0,0 +1,277 @@ +/***************************************************************************/ +/* */ +/* gxvmorx1.c */ +/* */ +/* TrueTypeGX/AAT morx table validation */ +/* body for type1 (Contextual Substitution) subtable. */ +/* */ +/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmorx.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_gxvmorx + + + typedef struct GXV_morx_subtable_type1_StateOptRec_ + { + FT_ULong substitutionTable; + FT_ULong substitutionTable_length; + FT_UShort substitutionTable_num_lookupTables; + + } GXV_morx_subtable_type1_StateOptRec, + *GXV_morx_subtable_type1_StateOptRecData; + + +#define GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE \ + ( GXV_STATETABLE_HEADER_SIZE + 2 ) + + + static void + gxv_morx_subtable_type1_substitutionTable_load( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_morx_subtable_type1_StateOptRecData optdata = + (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + + + GXV_LIMIT_CHECK( 2 ); + optdata->substitutionTable = FT_NEXT_USHORT( p ); + } + + + static void + gxv_morx_subtable_type1_subtable_setup( FT_ULong table_size, + FT_ULong classTable, + FT_ULong stateArray, + FT_ULong entryTable, + FT_ULong* classTable_length_p, + FT_ULong* stateArray_length_p, + FT_ULong* entryTable_length_p, + GXV_Validator valid ) + { + FT_ULong o[4]; + FT_ULong *l[4]; + FT_ULong buff[5]; + + GXV_morx_subtable_type1_StateOptRecData optdata = + (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + + + o[0] = classTable; + o[1] = stateArray; + o[2] = entryTable; + o[3] = optdata->substitutionTable; + l[0] = classTable_length_p; + l[1] = stateArray_length_p; + l[2] = entryTable_length_p; + l[3] = &(optdata->substitutionTable_length); + + gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid ); + } + + + static void + gxv_morx_subtable_type1_entry_validate( + FT_UShort state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_TRACE_VARS + FT_UShort setMark; + FT_UShort dontAdvance; +#endif + FT_UShort reserved; + FT_Short markIndex; + FT_Short currentIndex; + + GXV_morx_subtable_type1_StateOptRecData optdata = + (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + + FT_UNUSED( state ); + FT_UNUSED( table ); + FT_UNUSED( limit ); + + +#ifdef GXV_LOAD_TRACE_VARS + setMark = (FT_UShort)( ( flags >> 15 ) & 1 ); + dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); +#endif + + reserved = (FT_UShort)( flags & 0x3FFF ); + + markIndex = (FT_Short)( glyphOffset_p->ul >> 16 ); + currentIndex = (FT_Short)( glyphOffset_p->ul ); + + GXV_TRACE(( " setMark=%01d dontAdvance=%01d\n", + setMark, dontAdvance )); + + if ( 0 < reserved ) + { + GXV_TRACE(( " non-zero bits found in reserved range\n" )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); + } + + GXV_TRACE(( "markIndex = %d, currentIndex = %d\n", + markIndex, currentIndex )); + + if ( optdata->substitutionTable_num_lookupTables < markIndex + 1 ) + optdata->substitutionTable_num_lookupTables = + (FT_Short)( markIndex + 1 ); + + if ( optdata->substitutionTable_num_lookupTables < currentIndex + 1 ) + optdata->substitutionTable_num_lookupTables = + (FT_Short)( currentIndex + 1 ); + } + + + static void + gxv_morx_subtable_type1_LookupValue_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + FT_UNUSED( glyph ); /* for the non-debugging case */ + + GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u )); + + if ( value_p->u > valid->face->num_glyphs ) + FT_INVALID_GLYPH_ID; + } + + + static GXV_LookupValueDesc + gxv_morx_subtable_type1_LookupFmt4_transit( + FT_UShort relative_gindex, + GXV_LookupValueCPtr base_value_p, + FT_Bytes lookuptbl_limit, + GXV_Validator valid ) + { + FT_Bytes p; + FT_Bytes limit; + FT_UShort offset; + GXV_LookupValueDesc value; + + /* XXX: check range? */ + offset = (FT_UShort)( base_value_p->u + + relative_gindex * sizeof ( FT_UShort ) ); + + p = valid->lookuptbl_head + offset; + limit = lookuptbl_limit; + + GXV_LIMIT_CHECK ( 2 ); + value.u = FT_NEXT_USHORT( p ); + + return value; + } + + + /* + * TODO: length should be limit? + **/ + static void + gxv_morx_subtable_type1_substitutionTable_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort i; + + GXV_morx_subtable_type1_StateOptRecData optdata = + (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + + + /* TODO: calculate offset/length for each lookupTables */ + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_morx_subtable_type1_LookupValue_validate; + valid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit; + + for ( i = 0; i < optdata->substitutionTable_num_lookupTables; i++ ) + { + FT_ULong offset; + + + GXV_LIMIT_CHECK( 4 ); + offset = FT_NEXT_ULONG( p ); + + gxv_LookupTable_validate( table + offset, limit, valid ); + } + + /* TODO: overlapping of lookupTables in substitutionTable */ + } + + + /* + * subtable for Contextual glyph substitution is a modified StateTable. + * In addition to classTable, stateArray, entryTable, the field + * `substitutionTable' is added. + */ + FT_LOCAL_DEF( void ) + gxv_morx_subtable_type1_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_morx_subtable_type1_StateOptRec st_rec; + + + GXV_NAME_ENTER( "morx chain subtable type1 (Contextual Glyph Subst)" ); + + GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE ); + + st_rec.substitutionTable_num_lookupTables = 0; + + valid->xstatetable.optdata = + &st_rec; + valid->xstatetable.optdata_load_func = + gxv_morx_subtable_type1_substitutionTable_load; + valid->xstatetable.subtable_setup_func = + gxv_morx_subtable_type1_subtable_setup; + valid->xstatetable.entry_glyphoffset_fmt = + GXV_GLYPHOFFSET_ULONG; + valid->xstatetable.entry_validate_func = + gxv_morx_subtable_type1_entry_validate; + + gxv_XStateTable_validate( p, limit, valid ); + + gxv_morx_subtable_type1_substitutionTable_validate( + table + st_rec.substitutionTable, + table + st_rec.substitutionTable + st_rec.substitutionTable_length, + valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmorx2.c b/drivers/freetype/src/gxvalid/gxvmorx2.c new file mode 100644 index 0000000000..9d2b0bc4af --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmorx2.c @@ -0,0 +1,327 @@ +/***************************************************************************/ +/* */ +/* gxvmorx2.c */ +/* */ +/* TrueTypeGX/AAT morx table validation */ +/* body for type2 (Ligature Substitution) subtable. */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmorx.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_gxvmorx + + + typedef struct GXV_morx_subtable_type2_StateOptRec_ + { + FT_ULong ligActionTable; + FT_ULong componentTable; + FT_ULong ligatureTable; + FT_ULong ligActionTable_length; + FT_ULong componentTable_length; + FT_ULong ligatureTable_length; + + } GXV_morx_subtable_type2_StateOptRec, + *GXV_morx_subtable_type2_StateOptRecData; + + +#define GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE \ + ( GXV_XSTATETABLE_HEADER_SIZE + 4 + 4 + 4 ) + + + static void + gxv_morx_subtable_type2_opttable_load( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_morx_subtable_type2_StateOptRecData optdata = + (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + + + GXV_LIMIT_CHECK( 4 + 4 + 4 ); + optdata->ligActionTable = FT_NEXT_ULONG( p ); + optdata->componentTable = FT_NEXT_ULONG( p ); + optdata->ligatureTable = FT_NEXT_ULONG( p ); + + GXV_TRACE(( "offset to ligActionTable=0x%08x\n", + optdata->ligActionTable )); + GXV_TRACE(( "offset to componentTable=0x%08x\n", + optdata->componentTable )); + GXV_TRACE(( "offset to ligatureTable=0x%08x\n", + optdata->ligatureTable )); + } + + + static void + gxv_morx_subtable_type2_subtable_setup( FT_ULong table_size, + FT_ULong classTable, + FT_ULong stateArray, + FT_ULong entryTable, + FT_ULong* classTable_length_p, + FT_ULong* stateArray_length_p, + FT_ULong* entryTable_length_p, + GXV_Validator valid ) + { + FT_ULong o[6]; + FT_ULong* l[6]; + FT_ULong buff[7]; + + GXV_morx_subtable_type2_StateOptRecData optdata = + (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + + + GXV_NAME_ENTER( "subtable boundaries setup" ); + + o[0] = classTable; + o[1] = stateArray; + o[2] = entryTable; + o[3] = optdata->ligActionTable; + o[4] = optdata->componentTable; + o[5] = optdata->ligatureTable; + l[0] = classTable_length_p; + l[1] = stateArray_length_p; + l[2] = entryTable_length_p; + l[3] = &(optdata->ligActionTable_length); + l[4] = &(optdata->componentTable_length); + l[5] = &(optdata->ligatureTable_length); + + gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, valid ); + + GXV_TRACE(( "classTable: offset=0x%08x length=0x%08x\n", + classTable, *classTable_length_p )); + GXV_TRACE(( "stateArray: offset=0x%08x length=0x%08x\n", + stateArray, *stateArray_length_p )); + GXV_TRACE(( "entryTable: offset=0x%08x length=0x%08x\n", + entryTable, *entryTable_length_p )); + GXV_TRACE(( "ligActionTable: offset=0x%08x length=0x%08x\n", + optdata->ligActionTable, + optdata->ligActionTable_length )); + GXV_TRACE(( "componentTable: offset=0x%08x length=0x%08x\n", + optdata->componentTable, + optdata->componentTable_length )); + GXV_TRACE(( "ligatureTable: offset=0x%08x length=0x%08x\n", + optdata->ligatureTable, + optdata->ligatureTable_length )); + + GXV_EXIT; + } + + +#define GXV_MORX_LIGACTION_ENTRY_SIZE 4 + + + static void + gxv_morx_subtable_type2_ligActionIndex_validate( + FT_Bytes table, + FT_UShort ligActionIndex, + GXV_Validator valid ) + { + /* access ligActionTable */ + GXV_morx_subtable_type2_StateOptRecData optdata = + (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + + FT_Bytes lat_base = table + optdata->ligActionTable; + FT_Bytes p = lat_base + + ligActionIndex * GXV_MORX_LIGACTION_ENTRY_SIZE; + FT_Bytes lat_limit = lat_base + optdata->ligActionTable; + + + if ( p < lat_base ) + { + GXV_TRACE(( "p < lat_base (%d byte rewind)\n", lat_base - p )); + FT_INVALID_OFFSET; + } + else if ( lat_limit < p ) + { + GXV_TRACE(( "lat_limit < p (%d byte overrun)\n", p - lat_limit )); + FT_INVALID_OFFSET; + } + + { + /* validate entry in ligActionTable */ + FT_ULong lig_action; +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort last; + FT_UShort store; +#endif + FT_ULong offset; + FT_Long gid_limit; + + + lig_action = FT_NEXT_ULONG( p ); +#ifdef GXV_LOAD_UNUSED_VARS + last = (FT_UShort)( ( lig_action >> 31 ) & 1 ); + store = (FT_UShort)( ( lig_action >> 30 ) & 1 ); +#endif + + offset = lig_action & 0x3FFFFFFFUL; + + /* this offset is 30-bit signed value to add to GID */ + /* it is different from the location offset in mort */ + if ( ( offset & 0x3FFF0000UL ) == 0x3FFF0000UL ) + { /* negative offset */ + gid_limit = valid->face->num_glyphs - ( offset & 0x0000FFFFUL ); + if ( gid_limit > 0 ) + return; + + GXV_TRACE(( "ligature action table includes" + " too negative offset moving all GID" + " below defined range: 0x%04x\n", + offset & 0xFFFFU )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } + else if ( ( offset & 0x3FFF0000UL ) == 0x0000000UL ) + { /* positive offset */ + if ( (FT_Long)offset < valid->face->num_glyphs ) + return; + + GXV_TRACE(( "ligature action table includes" + " too large offset moving all GID" + " over defined range: 0x%04x\n", + offset & 0xFFFFU )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } + + GXV_TRACE(( "ligature action table includes" + " invalid offset to add to 16-bit GID:" + " 0x%08x\n", offset )); + GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); + } + } + + + static void + gxv_morx_subtable_type2_entry_validate( + FT_UShort state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_UNUSED_VARS + FT_UShort setComponent; + FT_UShort dontAdvance; + FT_UShort performAction; +#endif + FT_UShort reserved; + FT_UShort ligActionIndex; + + FT_UNUSED( state ); + FT_UNUSED( limit ); + + +#ifdef GXV_LOAD_UNUSED_VARS + setComponent = (FT_UShort)( ( flags >> 15 ) & 1 ); + dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); + performAction = (FT_UShort)( ( flags >> 13 ) & 1 ); +#endif + + reserved = (FT_UShort)( flags & 0x1FFF ); + ligActionIndex = glyphOffset_p->u; + + if ( reserved > 0 ) + GXV_TRACE(( " reserved 14bit is non-zero\n" )); + + if ( 0 < ligActionIndex ) + gxv_morx_subtable_type2_ligActionIndex_validate( + table, ligActionIndex, valid ); + } + + + static void + gxv_morx_subtable_type2_ligatureTable_validate( FT_Bytes table, + GXV_Validator valid ) + { + GXV_morx_subtable_type2_StateOptRecData optdata = + (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + + FT_Bytes p = table + optdata->ligatureTable; + FT_Bytes limit = table + optdata->ligatureTable + + optdata->ligatureTable_length; + + + GXV_NAME_ENTER( "morx chain subtable type2 - substitutionTable" ); + + if ( 0 != optdata->ligatureTable ) + { + /* Apple does not give specification of ligatureTable format */ + while ( p < limit ) + { + FT_UShort lig_gid; + + + GXV_LIMIT_CHECK( 2 ); + lig_gid = FT_NEXT_USHORT( p ); + if ( lig_gid < valid->face->num_glyphs ) + GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); + } + } + + GXV_EXIT; + } + + + FT_LOCAL_DEF( void ) + gxv_morx_subtable_type2_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_morx_subtable_type2_StateOptRec lig_rec; + + + GXV_NAME_ENTER( "morx chain subtable type2 (Ligature Substitution)" ); + + GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE ); + + valid->xstatetable.optdata = + &lig_rec; + valid->xstatetable.optdata_load_func = + gxv_morx_subtable_type2_opttable_load; + valid->xstatetable.subtable_setup_func = + gxv_morx_subtable_type2_subtable_setup; + valid->xstatetable.entry_glyphoffset_fmt = + GXV_GLYPHOFFSET_USHORT; + valid->xstatetable.entry_validate_func = + gxv_morx_subtable_type2_entry_validate; + + gxv_XStateTable_validate( p, limit, valid ); + + p += valid->subtable_length; + gxv_morx_subtable_type2_ligatureTable_validate( table, valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmorx4.c b/drivers/freetype/src/gxvalid/gxvmorx4.c new file mode 100644 index 0000000000..c0d2f78e39 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmorx4.c @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* gxvmorx4.c */ +/* */ +/* TrueTypeGX/AAT morx table validation */ +/* body for "morx" type4 (Non-Contextual Glyph Substitution) subtable. */ +/* */ +/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmorx.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_gxvmorx + + + FT_LOCAL_DEF( void ) + gxv_morx_subtable_type4_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + GXV_NAME_ENTER( "morx chain subtable type4 " + "(Non-Contextual Glyph Substitution)" ); + + gxv_mort_subtable_type4_validate( table, limit, valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmorx5.c b/drivers/freetype/src/gxvalid/gxvmorx5.c new file mode 100644 index 0000000000..d8cf700797 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvmorx5.c @@ -0,0 +1,225 @@ +/***************************************************************************/ +/* */ +/* gxvmorx5.c */ +/* */ +/* TrueTypeGX/AAT morx table validation */ +/* body for type5 (Contextual Glyph Insertion) subtable. */ +/* */ +/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvmorx.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_gxvmorx + + + /* + * `morx' subtable type5 (Contextual Glyph Insertion) + * has format of a StateTable with insertion-glyph-list + * without name. However, the 32bit offset from the head + * of subtable to the i-g-l is given after `entryTable', + * without variable name specification (the existence of + * this offset to the table is different from mort type5). + */ + + + typedef struct GXV_morx_subtable_type5_StateOptRec_ + { + FT_ULong insertionGlyphList; + FT_ULong insertionGlyphList_length; + + } GXV_morx_subtable_type5_StateOptRec, + *GXV_morx_subtable_type5_StateOptRecData; + + +#define GXV_MORX_SUBTABLE_TYPE5_HEADER_SIZE \ + ( GXV_STATETABLE_HEADER_SIZE + 4 ) + + + static void + gxv_morx_subtable_type5_insertionGlyphList_load( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_morx_subtable_type5_StateOptRecData optdata = + (GXV_morx_subtable_type5_StateOptRecData)valid->xstatetable.optdata; + + + GXV_LIMIT_CHECK( 4 ); + optdata->insertionGlyphList = FT_NEXT_ULONG( p ); + } + + + static void + gxv_morx_subtable_type5_subtable_setup( FT_ULong table_size, + FT_ULong classTable, + FT_ULong stateArray, + FT_ULong entryTable, + FT_ULong* classTable_length_p, + FT_ULong* stateArray_length_p, + FT_ULong* entryTable_length_p, + GXV_Validator valid ) + { + FT_ULong o[4]; + FT_ULong* l[4]; + FT_ULong buff[5]; + + GXV_morx_subtable_type5_StateOptRecData optdata = + (GXV_morx_subtable_type5_StateOptRecData)valid->xstatetable.optdata; + + + o[0] = classTable; + o[1] = stateArray; + o[2] = entryTable; + o[3] = optdata->insertionGlyphList; + l[0] = classTable_length_p; + l[1] = stateArray_length_p; + l[2] = entryTable_length_p; + l[3] = &(optdata->insertionGlyphList_length); + + gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid ); + } + + + static void + gxv_morx_subtable_type5_InsertList_validate( FT_UShort table_index, + FT_UShort count, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table + table_index * 2; + + +#ifndef GXV_LOAD_TRACE_VARS + GXV_LIMIT_CHECK( count * 2 ); +#else + while ( p < table + count * 2 + table_index * 2 ) + { + FT_UShort insert_glyphID; + + + GXV_LIMIT_CHECK( 2 ); + insert_glyphID = FT_NEXT_USHORT( p ); + GXV_TRACE(( " 0x%04x", insert_glyphID )); + } + + GXV_TRACE(( "\n" )); +#endif + } + + + static void + gxv_morx_subtable_type5_entry_validate( + FT_UShort state, + FT_UShort flags, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, + FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { +#ifdef GXV_LOAD_UNUSED_VARS + FT_Bool setMark; + FT_Bool dontAdvance; + FT_Bool currentIsKashidaLike; + FT_Bool markedIsKashidaLike; + FT_Bool currentInsertBefore; + FT_Bool markedInsertBefore; +#endif + FT_Byte currentInsertCount; + FT_Byte markedInsertCount; + FT_Byte currentInsertList; + FT_UShort markedInsertList; + + FT_UNUSED( state ); + + +#ifdef GXV_LOAD_UNUSED_VARS + setMark = FT_BOOL( ( flags >> 15 ) & 1 ); + dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 ); + currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 ); + markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 ); + currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 ); + markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 ); +#endif + + currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); + markedInsertCount = (FT_Byte)( flags & 0x001F ); + + currentInsertList = (FT_Byte) ( glyphOffset_p->ul >> 16 ); + markedInsertList = (FT_UShort)( glyphOffset_p->ul ); + + if ( currentInsertList && 0 != currentInsertCount ) + gxv_morx_subtable_type5_InsertList_validate( currentInsertList, + currentInsertCount, + table, limit, + valid ); + + if ( markedInsertList && 0 != markedInsertCount ) + gxv_morx_subtable_type5_InsertList_validate( markedInsertList, + markedInsertCount, + table, limit, + valid ); + } + + + FT_LOCAL_DEF( void ) + gxv_morx_subtable_type5_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + + GXV_morx_subtable_type5_StateOptRec et_rec; + GXV_morx_subtable_type5_StateOptRecData et = &et_rec; + + + GXV_NAME_ENTER( "morx chain subtable type5 (Glyph Insertion)" ); + + GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE5_HEADER_SIZE ); + + valid->xstatetable.optdata = + et; + valid->xstatetable.optdata_load_func = + gxv_morx_subtable_type5_insertionGlyphList_load; + valid->xstatetable.subtable_setup_func = + gxv_morx_subtable_type5_subtable_setup; + valid->xstatetable.entry_glyphoffset_fmt = + GXV_GLYPHOFFSET_ULONG; + valid->xstatetable.entry_validate_func = + gxv_morx_subtable_type5_entry_validate; + + gxv_XStateTable_validate( p, limit, valid ); + + GXV_EXIT; + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvopbd.c b/drivers/freetype/src/gxvalid/gxvopbd.c new file mode 100644 index 0000000000..e125060946 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvopbd.c @@ -0,0 +1,217 @@ +/***************************************************************************/ +/* */ +/* gxvopbd.c */ +/* */ +/* TrueTypeGX/AAT opbd table validation (body). */ +/* */ +/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvalid.h" +#include "gxvcommn.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_gxvopbd + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Data and Types *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct GXV_opbd_DataRec_ + { + FT_UShort format; + FT_UShort valueOffset_min; + + } GXV_opbd_DataRec, *GXV_opbd_Data; + + +#define GXV_OPBD_DATA( FIELD ) GXV_TABLE_DATA( opbd, FIELD ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + gxv_opbd_LookupValue_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + /* offset in LookupTable is measured from the head of opbd table */ + FT_Bytes p = valid->root->base + value_p->u; + FT_Bytes limit = valid->root->limit; + FT_Short delta_value; + int i; + + + if ( value_p->u < GXV_OPBD_DATA( valueOffset_min ) ) + GXV_OPBD_DATA( valueOffset_min ) = value_p->u; + + for ( i = 0; i < 4; i++ ) + { + GXV_LIMIT_CHECK( 2 ); + delta_value = FT_NEXT_SHORT( p ); + + if ( GXV_OPBD_DATA( format ) ) /* format 1, value is ctrl pt. */ + { + if ( delta_value == -1 ) + continue; + + gxv_ctlPoint_validate( glyph, delta_value, valid ); + } + else /* format 0, value is distance */ + continue; + } + } + + + /* + opbd ---------------------+ + | + +===============+ | + | lookup header | | + +===============+ | + | BinSrchHeader | | + +===============+ | + | lastGlyph[0] | | + +---------------+ | + | firstGlyph[0] | | head of opbd sfnt table + +---------------+ | + + | offset[0] | -> | offset [byte] + +===============+ | + + | lastGlyph[1] | | (glyphID - firstGlyph) * 4 * sizeof(FT_Short) [byte] + +---------------+ | + | firstGlyph[1] | | + +---------------+ | + | offset[1] | | + +===============+ | + | + .... | + | + 48bit value array | + +===============+ | + | value | <-------+ + | | + | | + | | + +---------------+ + .... */ + + static GXV_LookupValueDesc + gxv_opbd_LookupFmt4_transit( FT_UShort relative_gindex, + GXV_LookupValueCPtr base_value_p, + FT_Bytes lookuptbl_limit, + GXV_Validator valid ) + { + GXV_LookupValueDesc value; + + FT_UNUSED( lookuptbl_limit ); + FT_UNUSED( valid ); + + /* XXX: check range? */ + value.u = (FT_UShort)( base_value_p->u + + relative_gindex * 4 * sizeof ( FT_Short ) ); + + return value; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** opbd TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + gxv_opbd_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + GXV_opbd_DataRec opbdrec; + GXV_opbd_Data opbd = &opbdrec; + FT_Bytes p = table; + FT_Bytes limit = 0; + + FT_ULong version; + + + valid->root = ftvalid; + valid->table_data = opbd; + valid->face = face; + + FT_TRACE3(( "validating `opbd' table\n" )); + GXV_INIT; + GXV_OPBD_DATA( valueOffset_min ) = 0xFFFFU; + + + GXV_LIMIT_CHECK( 4 + 2 ); + version = FT_NEXT_ULONG( p ); + GXV_OPBD_DATA( format ) = FT_NEXT_USHORT( p ); + + + /* only 0x00010000 is defined (1996) */ + GXV_TRACE(( "(version=0x%08x)\n", version )); + if ( 0x00010000UL != version ) + FT_INVALID_FORMAT; + + /* only values 0 and 1 are defined (1996) */ + GXV_TRACE(( "(format=0x%04x)\n", GXV_OPBD_DATA( format ) )); + if ( 0x0001 < GXV_OPBD_DATA( format ) ) + FT_INVALID_FORMAT; + + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_opbd_LookupValue_validate; + valid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; + + gxv_LookupTable_validate( p, limit, valid ); + p += valid->subtable_length; + + if ( p > table + GXV_OPBD_DATA( valueOffset_min ) ) + { + GXV_TRACE(( + "found overlap between LookupTable and opbd_value array\n" )); + FT_INVALID_OFFSET; + } + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvprop.c b/drivers/freetype/src/gxvalid/gxvprop.c new file mode 100644 index 0000000000..0be21336f8 --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvprop.c @@ -0,0 +1,329 @@ +/***************************************************************************/ +/* */ +/* gxvprop.c */ +/* */ +/* TrueTypeGX/AAT prop table validation (body). */ +/* */ +/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvalid.h" +#include "gxvcommn.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_gxvprop + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Data and Types *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define GXV_PROP_HEADER_SIZE ( 4 + 2 + 2 ) +#define GXV_PROP_SIZE_MIN GXV_PROP_HEADER_SIZE + + typedef struct GXV_prop_DataRec_ + { + FT_Fixed version; + + } GXV_prop_DataRec, *GXV_prop_Data; + +#define GXV_PROP_DATA( field ) GXV_TABLE_DATA( prop, field ) + +#define GXV_PROP_FLOATER 0x8000U +#define GXV_PROP_USE_COMPLEMENTARY_BRACKET 0x1000U +#define GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET 0x0F00U +#define GXV_PROP_ATTACHING_TO_RIGHT 0x0080U +#define GXV_PROP_RESERVED 0x0060U +#define GXV_PROP_DIRECTIONALITY_CLASS 0x001FU + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + gxv_prop_zero_advance_validate( FT_UShort gid, + GXV_Validator valid ) + { + FT_Face face; + FT_Error error; + FT_GlyphSlot glyph; + + + GXV_NAME_ENTER( "zero advance" ); + + face = valid->face; + + error = FT_Load_Glyph( face, + gid, + FT_LOAD_IGNORE_TRANSFORM ); + if ( error ) + FT_INVALID_GLYPH_ID; + + glyph = face->glyph; + + if ( glyph->advance.x != (FT_Pos)0 || + glyph->advance.y != (FT_Pos)0 ) + { + GXV_TRACE(( " found non-zero advance in zero-advance glyph\n" )); + FT_INVALID_DATA; + } + + GXV_EXIT; + } + + + /* Pass 0 as GLYPH to check the default property */ + static void + gxv_prop_property_validate( FT_UShort property, + FT_UShort glyph, + GXV_Validator valid ) + { + if ( glyph != 0 && ( property & GXV_PROP_FLOATER ) ) + gxv_prop_zero_advance_validate( glyph, valid ); + + if ( property & GXV_PROP_USE_COMPLEMENTARY_BRACKET ) + { + FT_UShort offset; + char complement; + + + offset = (FT_UShort)( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET ); + if ( offset == 0 ) + { + GXV_TRACE(( " found zero offset to property\n" )); + FT_INVALID_OFFSET; + } + + complement = (char)( offset >> 8 ); + if ( complement & 0x08 ) + { + /* Top bit is set: negative */ + + /* Calculate the absolute offset */ + complement = (char)( ( complement & 0x07 ) + 1 ); + + /* The gid for complement must be greater than 0 */ + if ( glyph <= complement ) + { + GXV_TRACE(( " found non-positive glyph complement\n" )); + FT_INVALID_DATA; + } + } + else + { + /* The gid for complement must be the face. */ + gxv_glyphid_validate( (FT_UShort)( glyph + complement ), valid ); + } + } + else + { + if ( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET ) + GXV_TRACE(( "glyph %d cannot have complementary bracketing\n", + glyph )); + } + + /* this is introduced in version 2.0 */ + if ( property & GXV_PROP_ATTACHING_TO_RIGHT ) + { + if ( GXV_PROP_DATA( version ) == 0x00010000UL ) + { + GXV_TRACE(( " found older version (1.0) in new version table\n" )); + FT_INVALID_DATA; + } + } + + if ( property & GXV_PROP_RESERVED ) + { + GXV_TRACE(( " found non-zero bits in reserved bits\n" )); + FT_INVALID_DATA; + } + + if ( ( property & GXV_PROP_DIRECTIONALITY_CLASS ) > 11 ) + { + /* TODO: Too restricted. Use the validation level. */ + if ( GXV_PROP_DATA( version ) == 0x00010000UL || + GXV_PROP_DATA( version ) == 0x00020000UL ) + { + GXV_TRACE(( " found too old version in directionality class\n" )); + FT_INVALID_DATA; + } + } + } + + + static void + gxv_prop_LookupValue_validate( FT_UShort glyph, + GXV_LookupValueCPtr value_p, + GXV_Validator valid ) + { + gxv_prop_property_validate( value_p->u, glyph, valid ); + } + + + /* + +===============+ --------+ + | lookup header | | + +===============+ | + | BinSrchHeader | | + +===============+ | + | lastGlyph[0] | | + +---------------+ | + | firstGlyph[0] | | head of lookup table + +---------------+ | + + | offset[0] | -> | offset [byte] + +===============+ | + + | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] + +---------------+ | + | firstGlyph[1] | | + +---------------+ | + | offset[1] | | + +===============+ | + | + ... | + | + 16bit value array | + +===============+ | + | value | <-------+ + ... + */ + + static GXV_LookupValueDesc + gxv_prop_LookupFmt4_transit( FT_UShort relative_gindex, + GXV_LookupValueCPtr base_value_p, + FT_Bytes lookuptbl_limit, + GXV_Validator valid ) + { + FT_Bytes p; + FT_Bytes limit; + FT_UShort offset; + GXV_LookupValueDesc value; + + /* XXX: check range? */ + offset = (FT_UShort)( base_value_p->u + + relative_gindex * sizeof ( FT_UShort ) ); + p = valid->lookuptbl_head + offset; + limit = lookuptbl_limit; + + GXV_LIMIT_CHECK ( 2 ); + value.u = FT_NEXT_USHORT( p ); + + return value; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** prop TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + gxv_prop_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + FT_Bytes p = table; + FT_Bytes limit = 0; + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + + GXV_prop_DataRec proprec; + GXV_prop_Data prop = &proprec; + + FT_Fixed version; + FT_UShort format; + FT_UShort defaultProp; + + + valid->root = ftvalid; + valid->table_data = prop; + valid->face = face; + + FT_TRACE3(( "validating `prop' table\n" )); + GXV_INIT; + + GXV_LIMIT_CHECK( 4 + 2 + 2 ); + version = FT_NEXT_ULONG( p ); + format = FT_NEXT_USHORT( p ); + defaultProp = FT_NEXT_USHORT( p ); + + GXV_TRACE(( " version 0x%08x\n", version )); + GXV_TRACE(( " format 0x%04x\n", format )); + GXV_TRACE(( " defaultProp 0x%04x\n", defaultProp )); + + /* only versions 1.0, 2.0, 3.0 are defined (1996) */ + if ( version != 0x00010000UL && + version != 0x00020000UL && + version != 0x00030000UL ) + { + GXV_TRACE(( " found unknown version\n" )); + FT_INVALID_FORMAT; + } + + + /* only formats 0x0000, 0x0001 are defined (1996) */ + if ( format > 1 ) + { + GXV_TRACE(( " found unknown format\n" )); + FT_INVALID_FORMAT; + } + + gxv_prop_property_validate( defaultProp, 0, valid ); + + if ( format == 0 ) + { + FT_TRACE3(( "(format 0, no per-glyph properties, " + "remaining %d bytes are skipped)", limit - p )); + goto Exit; + } + + /* format == 1 */ + GXV_PROP_DATA( version ) = version; + + valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + valid->lookupval_func = gxv_prop_LookupValue_validate; + valid->lookupfmt4_trans = gxv_prop_LookupFmt4_transit; + + gxv_LookupTable_validate( p, limit, valid ); + + Exit: + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/gxvtrak.c b/drivers/freetype/src/gxvalid/gxvtrak.c new file mode 100644 index 0000000000..11fbd7ccfb --- /dev/null +++ b/drivers/freetype/src/gxvalid/gxvtrak.c @@ -0,0 +1,286 @@ +/***************************************************************************/ +/* */ +/* gxvtrak.c */ +/* */ +/* TrueTypeGX/AAT trak table validation (body). */ +/* */ +/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include "gxvalid.h" +#include "gxvcommn.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_gxvtrak + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Data and Types *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * referred track table format specification: + * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6trak.html + * last update was 1996. + * ---------------------------------------------- + * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN + * version (fixed: 32bit) = 0x00010000 + * format (uint16: 16bit) = 0 is only defined (1996) + * horizOffset (uint16: 16bit) + * vertOffset (uint16: 16bit) + * reserved (uint16: 16bit) = 0 + * ---------------------------------------------- + * [VARIABLE BODY]: + * horizData + * header ( 2 + 2 + 4 + * trackTable + nTracks * ( 4 + 2 + 2 ) + * sizeTable + nSizes * 4 ) + * ---------------------------------------------- + * vertData + * header ( 2 + 2 + 4 + * trackTable + nTracks * ( 4 + 2 + 2 ) + * sizeTable + nSizes * 4 ) + * ---------------------------------------------- + */ + typedef struct GXV_trak_DataRec_ + { + FT_UShort trackValueOffset_min; + FT_UShort trackValueOffset_max; + + } GXV_trak_DataRec, *GXV_trak_Data; + + +#define GXV_TRAK_DATA( FIELD ) GXV_TABLE_DATA( trak, FIELD ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + gxv_trak_trackTable_validate( FT_Bytes table, + FT_Bytes limit, + FT_UShort nTracks, + GXV_Validator valid ) + { + FT_Bytes p = table; + + FT_Fixed track, t; + FT_UShort nameIndex; + FT_UShort offset; + FT_UShort i, j; + + + GXV_NAME_ENTER( "trackTable" ); + + GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU; + GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000; + + GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) ); + + for ( i = 0; i < nTracks; i ++ ) + { + p = table + i * ( 4 + 2 + 2 ); + track = FT_NEXT_LONG( p ); + nameIndex = FT_NEXT_USHORT( p ); + offset = FT_NEXT_USHORT( p ); + + if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) ) + GXV_TRAK_DATA( trackValueOffset_min ) = offset; + if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) ) + GXV_TRAK_DATA( trackValueOffset_max ) = offset; + + gxv_sfntName_validate( nameIndex, 256, 32767, valid ); + + for ( j = i; j < nTracks; j ++ ) + { + p = table + j * ( 4 + 2 + 2 ); + t = FT_NEXT_LONG( p ); + if ( t == track ) + GXV_TRACE(( "duplicated entries found for track value 0x%x\n", + track )); + } + } + + valid->subtable_length = p - table; + GXV_EXIT; + } + + + static void + gxv_trak_trackData_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table; + FT_UShort nTracks; + FT_UShort nSizes; + FT_ULong sizeTableOffset; + + GXV_ODTECT( 4, odtect ); + + + GXV_ODTECT_INIT( odtect ); + GXV_NAME_ENTER( "trackData" ); + + /* read the header of trackData */ + GXV_LIMIT_CHECK( 2 + 2 + 4 ); + nTracks = FT_NEXT_USHORT( p ); + nSizes = FT_NEXT_USHORT( p ); + sizeTableOffset = FT_NEXT_ULONG( p ); + + gxv_odtect_add_range( table, p - table, "trackData header", odtect ); + + /* validate trackTable */ + gxv_trak_trackTable_validate( p, limit, nTracks, valid ); + gxv_odtect_add_range( p, valid->subtable_length, + "trackTable", odtect ); + + /* sizeTable is array of FT_Fixed, don't check contents */ + p = valid->root->base + sizeTableOffset; + GXV_LIMIT_CHECK( nSizes * 4 ); + gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect ); + + /* validate trackValueOffet */ + p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min ); + if ( limit - p < nTracks * nSizes * 2 ) + GXV_TRACE(( "too short trackValue array\n" )); + + p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max ); + GXV_LIMIT_CHECK( nSizes * 2 ); + + gxv_odtect_add_range( valid->root->base + + GXV_TRAK_DATA( trackValueOffset_min ), + GXV_TRAK_DATA( trackValueOffset_max ) + - GXV_TRAK_DATA( trackValueOffset_min ) + + nSizes * 2, + "trackValue array", odtect ); + + gxv_odtect_validate( odtect, valid ); + + GXV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** trak TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + gxv_trak_validate( FT_Bytes table, + FT_Face face, + FT_Validator ftvalid ) + { + FT_Bytes p = table; + FT_Bytes limit = 0; + + GXV_ValidatorRec validrec; + GXV_Validator valid = &validrec; + GXV_trak_DataRec trakrec; + GXV_trak_Data trak = &trakrec; + + FT_ULong version; + FT_UShort format; + FT_UShort horizOffset; + FT_UShort vertOffset; + FT_UShort reserved; + + + GXV_ODTECT( 3, odtect ); + + GXV_ODTECT_INIT( odtect ); + valid->root = ftvalid; + valid->table_data = trak; + valid->face = face; + + limit = valid->root->limit; + + FT_TRACE3(( "validating `trak' table\n" )); + GXV_INIT; + + GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 ); + version = FT_NEXT_ULONG( p ); + format = FT_NEXT_USHORT( p ); + horizOffset = FT_NEXT_USHORT( p ); + vertOffset = FT_NEXT_USHORT( p ); + reserved = FT_NEXT_USHORT( p ); + + GXV_TRACE(( " (version = 0x%08x)\n", version )); + GXV_TRACE(( " (format = 0x%04x)\n", format )); + GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset )); + GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset )); + GXV_TRACE(( " (reserved = 0x%04x)\n", reserved )); + + /* Version 1.0 (always:1996) */ + if ( version != 0x00010000UL ) + FT_INVALID_FORMAT; + + /* format 0 (always:1996) */ + if ( format != 0x0000 ) + FT_INVALID_FORMAT; + + GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset ); + GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset ); + + /* Reserved Fixed Value (always) */ + if ( reserved != 0x0000 ) + FT_INVALID_DATA; + + /* validate trackData */ + if ( 0 < horizOffset ) + { + gxv_trak_trackData_validate( table + horizOffset, limit, valid ); + gxv_odtect_add_range( table + horizOffset, valid->subtable_length, + "horizJustData", odtect ); + } + + if ( 0 < vertOffset ) + { + gxv_trak_trackData_validate( table + vertOffset, limit, valid ); + gxv_odtect_add_range( table + vertOffset, valid->subtable_length, + "vertJustData", odtect ); + } + + gxv_odtect_validate( odtect, valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/gxvalid/module.mk b/drivers/freetype/src/gxvalid/module.mk new file mode 100644 index 0000000000..9fd098e2c5 --- /dev/null +++ b/drivers/freetype/src/gxvalid/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 gxvalid module definition +# + +# Copyright 2004, 2005, 2006 +# by suzuki toshiya, Masatake YAMATO, Red Hat K.K., +# 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. + + +FTMODULE_H_COMMANDS += GXVALID_MODULE + +define GXVALID_MODULE +$(OPEN_DRIVER) FT_Module_Class, gxv_module_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)gxvalid $(ECHO_DRIVER_DESC)TrueTypeGX/AAT validation module$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/gxvalid/rules.mk b/drivers/freetype/src/gxvalid/rules.mk new file mode 100644 index 0000000000..57bc0823db --- /dev/null +++ b/drivers/freetype/src/gxvalid/rules.mk @@ -0,0 +1,94 @@ +# +# FreeType 2 TrueTypeGX/AAT validation driver configuration rules +# + + +# Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., +# 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. + + +# GXV driver directory +# +GXV_DIR := $(SRC_DIR)/gxvalid + + +# compilation flags for the driver +# +GXV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(GXV_DIR)) + + +# GXV driver sources (i.e., C files) +# +GXV_DRV_SRC := $(GXV_DIR)/gxvcommn.c \ + $(GXV_DIR)/gxvfeat.c \ + $(GXV_DIR)/gxvbsln.c \ + $(GXV_DIR)/gxvtrak.c \ + $(GXV_DIR)/gxvopbd.c \ + $(GXV_DIR)/gxvprop.c \ + $(GXV_DIR)/gxvjust.c \ + $(GXV_DIR)/gxvmort.c \ + $(GXV_DIR)/gxvmort0.c \ + $(GXV_DIR)/gxvmort1.c \ + $(GXV_DIR)/gxvmort2.c \ + $(GXV_DIR)/gxvmort4.c \ + $(GXV_DIR)/gxvmort5.c \ + $(GXV_DIR)/gxvmorx.c \ + $(GXV_DIR)/gxvmorx0.c \ + $(GXV_DIR)/gxvmorx1.c \ + $(GXV_DIR)/gxvmorx2.c \ + $(GXV_DIR)/gxvmorx4.c \ + $(GXV_DIR)/gxvmorx5.c \ + $(GXV_DIR)/gxvlcar.c \ + $(GXV_DIR)/gxvkern.c \ + $(GXV_DIR)/gxvmod.c + +# GXV driver headers +# +GXV_DRV_H := $(GXV_DIR)/gxvalid.h \ + $(GXV_DIR)/gxverror.h \ + $(GXV_DIR)/gxvcommn.h \ + $(GXV_DIR)/gxvfeat.h \ + $(GXV_DIR)/gxvmod.h \ + $(GXV_DIR)/gxvmort.h \ + $(GXV_DIR)/gxvmorx.h + + +# GXV driver object(s) +# +# GXV_DRV_OBJ_M is used during `multi' builds. +# GXV_DRV_OBJ_S is used during `single' builds. +# +GXV_DRV_OBJ_M := $(GXV_DRV_SRC:$(GXV_DIR)/%.c=$(OBJ_DIR)/%.$O) +GXV_DRV_OBJ_S := $(OBJ_DIR)/gxvalid.$O + +# GXV driver source file for single build +# +GXV_DRV_SRC_S := $(GXV_DIR)/gxvalid.c + + +# GXV driver - single object +# +$(GXV_DRV_OBJ_S): $(GXV_DRV_SRC_S) $(GXV_DRV_SRC) \ + $(FREETYPE_H) $(GXV_DRV_H) + $(GXV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(GXV_DRV_SRC_S)) + + +# GXV driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(GXV_DIR)/%.c $(FREETYPE_H) $(GXV_DRV_H) + $(GXV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(GXV_DRV_OBJ_S) +DRV_OBJS_M += $(GXV_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/otvalid/Jamfile b/drivers/freetype/src/otvalid/Jamfile new file mode 100644 index 0000000000..b457143de4 --- /dev/null +++ b/drivers/freetype/src/otvalid/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/otvalid Jamfile +# +# Copyright 2004 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) otvalid ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod otvmath ; + } + else + { + _sources = otvalid ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/otvalid Jamfile diff --git a/drivers/freetype/src/otvalid/module.mk b/drivers/freetype/src/otvalid/module.mk new file mode 100644 index 0000000000..9cadde55e4 --- /dev/null +++ b/drivers/freetype/src/otvalid/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 otvalid module definition +# + + +# Copyright 2004, 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. + + +FTMODULE_H_COMMANDS += OTVALID_MODULE + +define OTVALID_MODULE +$(OPEN_DRIVER) FT_Module_Class, otv_module_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)otvalid $(ECHO_DRIVER_DESC)OpenType validation module$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/otvalid/otvalid.c b/drivers/freetype/src/otvalid/otvalid.c new file mode 100644 index 0000000000..d5c2b75abb --- /dev/null +++ b/drivers/freetype/src/otvalid/otvalid.c @@ -0,0 +1,31 @@ +/***************************************************************************/ +/* */ +/* otvalid.c */ +/* */ +/* FreeType validator for OpenType tables (body only). */ +/* */ +/* Copyright 2004, 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. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> + +#include "otvbase.c" +#include "otvcommn.c" +#include "otvgdef.c" +#include "otvgpos.c" +#include "otvgsub.c" +#include "otvjstf.c" +#include "otvmath.c" +#include "otvmod.c" + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvalid.h b/drivers/freetype/src/otvalid/otvalid.h new file mode 100644 index 0000000000..eb99b9cc48 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvalid.h @@ -0,0 +1,78 @@ +/***************************************************************************/ +/* */ +/* otvalid.h */ +/* */ +/* OpenType table validation (specification only). */ +/* */ +/* Copyright 2004, 2008 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 __OTVALID_H__ +#define __OTVALID_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#include "otverror.h" /* must come before FT_INTERNAL_VALIDATE_H */ + +#include FT_INTERNAL_VALIDATE_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + otv_BASE_validate( FT_Bytes table, + FT_Validator valid ); + + /* GSUB and GPOS tables should already be validated; */ + /* if missing, set corresponding argument to 0 */ + FT_LOCAL( void ) + otv_GDEF_validate( FT_Bytes table, + FT_Bytes gsub, + FT_Bytes gpos, + FT_UInt glyph_count, + FT_Validator valid ); + + FT_LOCAL( void ) + otv_GPOS_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator valid ); + + FT_LOCAL( void ) + otv_GSUB_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator valid ); + + /* GSUB and GPOS tables should already be validated; */ + /* if missing, set corresponding argument to 0 */ + FT_LOCAL( void ) + otv_JSTF_validate( FT_Bytes table, + FT_Bytes gsub, + FT_Bytes gpos, + FT_UInt glyph_count, + FT_Validator valid ); + + FT_LOCAL( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ); + + +FT_END_HEADER + +#endif /* __OTVALID_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvbase.c b/drivers/freetype/src/otvalid/otvbase.c new file mode 100644 index 0000000000..d742d2dc95 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvbase.c @@ -0,0 +1,318 @@ +/***************************************************************************/ +/* */ +/* otvbase.c */ +/* */ +/* OpenType BASE table validation (body). */ +/* */ +/* Copyright 2004, 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 "otvalid.h" +#include "otvcommn.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_otvbase + + + static void + otv_BaseCoord_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BaseCoordFormat; + + + OTV_NAME_ENTER( "BaseCoord" ); + + OTV_LIMIT_CHECK( 4 ); + BaseCoordFormat = FT_NEXT_USHORT( p ); + p += 2; /* skip Coordinate */ + + OTV_TRACE(( " (format %d)\n", BaseCoordFormat )); + + switch ( BaseCoordFormat ) + { + case 1: /* BaseCoordFormat1 */ + break; + + case 2: /* BaseCoordFormat2 */ + OTV_LIMIT_CHECK( 4 ); /* ReferenceGlyph, BaseCoordPoint */ + break; + + case 3: /* BaseCoordFormat3 */ + OTV_LIMIT_CHECK( 2 ); + /* DeviceTable */ + otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + static void + otv_BaseTagList_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BaseTagCount; + + + OTV_NAME_ENTER( "BaseTagList" ); + + OTV_LIMIT_CHECK( 2 ); + + BaseTagCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BaseTagCount = %d)\n", BaseTagCount )); + + OTV_LIMIT_CHECK( BaseTagCount * 4 ); /* BaselineTag */ + + OTV_EXIT; + } + + + static void + otv_BaseValues_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BaseCoordCount; + + + OTV_NAME_ENTER( "BaseValues" ); + + OTV_LIMIT_CHECK( 4 ); + + p += 2; /* skip DefaultIndex */ + BaseCoordCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BaseCoordCount = %d)\n", BaseCoordCount )); + + OTV_LIMIT_CHECK( BaseCoordCount * 2 ); + + /* BaseCoord */ + for ( ; BaseCoordCount > 0; BaseCoordCount-- ) + otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), valid ); + + OTV_EXIT; + } + + + static void + otv_MinMax_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + FT_UInt FeatMinMaxCount; + + OTV_OPTIONAL_TABLE( MinCoord ); + OTV_OPTIONAL_TABLE( MaxCoord ); + + + OTV_NAME_ENTER( "MinMax" ); + + OTV_LIMIT_CHECK( 6 ); + + OTV_OPTIONAL_OFFSET( MinCoord ); + OTV_OPTIONAL_OFFSET( MaxCoord ); + FeatMinMaxCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (FeatMinMaxCount = %d)\n", FeatMinMaxCount )); + + table_size = FeatMinMaxCount * 8 + 6; + + OTV_SIZE_CHECK( MinCoord ); + if ( MinCoord ) + otv_BaseCoord_validate( table + MinCoord, valid ); + + OTV_SIZE_CHECK( MaxCoord ); + if ( MaxCoord ) + otv_BaseCoord_validate( table + MaxCoord, valid ); + + OTV_LIMIT_CHECK( FeatMinMaxCount * 8 ); + + /* FeatMinMaxRecord */ + for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- ) + { + p += 4; /* skip FeatureTableTag */ + + OTV_OPTIONAL_OFFSET( MinCoord ); + OTV_OPTIONAL_OFFSET( MaxCoord ); + + OTV_SIZE_CHECK( MinCoord ); + if ( MinCoord ) + otv_BaseCoord_validate( table + MinCoord, valid ); + + OTV_SIZE_CHECK( MaxCoord ); + if ( MaxCoord ) + otv_BaseCoord_validate( table + MaxCoord, valid ); + } + + OTV_EXIT; + } + + + static void + otv_BaseScript_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + FT_UInt BaseLangSysCount; + + OTV_OPTIONAL_TABLE( BaseValues ); + OTV_OPTIONAL_TABLE( DefaultMinMax ); + + + OTV_NAME_ENTER( "BaseScript" ); + + OTV_LIMIT_CHECK( 6 ); + OTV_OPTIONAL_OFFSET( BaseValues ); + OTV_OPTIONAL_OFFSET( DefaultMinMax ); + BaseLangSysCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BaseLangSysCount = %d)\n", BaseLangSysCount )); + + table_size = BaseLangSysCount * 6 + 6; + + OTV_SIZE_CHECK( BaseValues ); + if ( BaseValues ) + otv_BaseValues_validate( table + BaseValues, valid ); + + OTV_SIZE_CHECK( DefaultMinMax ); + if ( DefaultMinMax ) + otv_MinMax_validate( table + DefaultMinMax, valid ); + + OTV_LIMIT_CHECK( BaseLangSysCount * 6 ); + + /* BaseLangSysRecord */ + for ( ; BaseLangSysCount > 0; BaseLangSysCount-- ) + { + p += 4; /* skip BaseLangSysTag */ + + otv_MinMax_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + static void + otv_BaseScriptList_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BaseScriptCount; + + + OTV_NAME_ENTER( "BaseScriptList" ); + + OTV_LIMIT_CHECK( 2 ); + BaseScriptCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BaseScriptCount = %d)\n", BaseScriptCount )); + + OTV_LIMIT_CHECK( BaseScriptCount * 6 ); + + /* BaseScriptRecord */ + for ( ; BaseScriptCount > 0; BaseScriptCount-- ) + { + p += 4; /* skip BaseScriptTag */ + + /* BaseScript */ + otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + static void + otv_Axis_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( BaseTagList ); + + + OTV_NAME_ENTER( "Axis" ); + + OTV_LIMIT_CHECK( 4 ); + OTV_OPTIONAL_OFFSET( BaseTagList ); + + table_size = 4; + + OTV_SIZE_CHECK( BaseTagList ); + if ( BaseTagList ) + otv_BaseTagList_validate( table + BaseTagList, valid ); + + /* BaseScriptList */ + otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), valid ); + + OTV_EXIT; + } + + + FT_LOCAL_DEF( void ) + otv_BASE_validate( FT_Bytes table, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( HorizAxis ); + OTV_OPTIONAL_TABLE( VertAxis ); + + + valid->root = ftvalid; + + FT_TRACE3(( "validating BASE table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 6 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + table_size = 6; + + OTV_OPTIONAL_OFFSET( HorizAxis ); + OTV_SIZE_CHECK( HorizAxis ); + if ( HorizAxis ) + otv_Axis_validate( table + HorizAxis, valid ); + + OTV_OPTIONAL_OFFSET( VertAxis ); + OTV_SIZE_CHECK( VertAxis ); + if ( VertAxis ) + otv_Axis_validate( table + VertAxis, valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvcommn.c b/drivers/freetype/src/otvalid/otvcommn.c new file mode 100644 index 0000000000..a4f885b51f --- /dev/null +++ b/drivers/freetype/src/otvalid/otvcommn.c @@ -0,0 +1,1086 @@ +/***************************************************************************/ +/* */ +/* otvcommn.c */ +/* */ +/* OpenType common tables validation (body). */ +/* */ +/* 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, */ +/* 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 "otvcommn.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_otvcommon + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** COVERAGE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + otv_Coverage_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int expected_count ) + { + FT_Bytes p = table; + FT_UInt CoverageFormat; + FT_UInt total = 0; + + + OTV_NAME_ENTER( "Coverage" ); + + OTV_LIMIT_CHECK( 4 ); + CoverageFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", CoverageFormat )); + + switch ( CoverageFormat ) + { + case 1: /* CoverageFormat1 */ + { + FT_UInt GlyphCount; + FT_UInt i; + + + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ + + for ( i = 0; i < GlyphCount; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + + total = GlyphCount; + } + break; + + case 2: /* CoverageFormat2 */ + { + FT_UInt n, RangeCount; + FT_UInt Start, End, StartCoverageIndex, last = 0; + + + RangeCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (RangeCount = %d)\n", RangeCount )); + + OTV_LIMIT_CHECK( RangeCount * 6 ); + + /* RangeRecord */ + for ( n = 0; n < RangeCount; n++ ) + { + Start = FT_NEXT_USHORT( p ); + End = FT_NEXT_USHORT( p ); + StartCoverageIndex = FT_NEXT_USHORT( p ); + + if ( Start > End || StartCoverageIndex != total ) + FT_INVALID_DATA; + + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + + if ( n > 0 && Start <= last ) + FT_INVALID_DATA; + + total += End - Start + 1; + last = End; + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + /* Generally, a coverage table offset has an associated count field. */ + /* The number of glyphs in the table should match this field. If */ + /* there is no associated count, a value of -1 tells us not to check. */ + if ( expected_count != -1 && (FT_UInt)expected_count != total ) + FT_INVALID_DATA; + + OTV_EXIT; + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_Coverage_get_first( FT_Bytes table ) + { + FT_Bytes p = table; + + + p += 4; /* skip CoverageFormat and Glyph/RangeCount */ + + return FT_NEXT_USHORT( p ); + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_Coverage_get_last( FT_Bytes table ) + { + FT_Bytes p = table; + FT_UInt CoverageFormat = FT_NEXT_USHORT( p ); + FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */ + FT_UInt result = 0; + + + switch ( CoverageFormat ) + { + case 1: + p += ( count - 1 ) * 2; + result = FT_NEXT_USHORT( p ); + break; + + case 2: + p += ( count - 1 ) * 6 + 2; + result = FT_NEXT_USHORT( p ); + break; + + default: + ; + } + + return result; + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_Coverage_get_count( FT_Bytes table ) + { + FT_Bytes p = table; + FT_UInt CoverageFormat = FT_NEXT_USHORT( p ); + FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */ + FT_UInt result = 0; + + + switch ( CoverageFormat ) + { + case 1: + return count; + + case 2: + { + FT_UInt Start, End; + + + for ( ; count > 0; count-- ) + { + Start = FT_NEXT_USHORT( p ); + End = FT_NEXT_USHORT( p ); + p += 2; /* skip StartCoverageIndex */ + + result += End - Start + 1; + } + } + break; + + default: + ; + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CLASS DEFINITION TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + otv_ClassDef_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt ClassFormat; + + + OTV_NAME_ENTER( "ClassDef" ); + + OTV_LIMIT_CHECK( 4 ); + ClassFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", ClassFormat )); + + switch ( ClassFormat ) + { + case 1: /* ClassDefFormat1 */ + { + FT_UInt StartGlyph; + FT_UInt GlyphCount; + + + OTV_LIMIT_CHECK( 4 ); + + StartGlyph = FT_NEXT_USHORT( p ); + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ + + if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + break; + + case 2: /* ClassDefFormat2 */ + { + FT_UInt n, ClassRangeCount; + FT_UInt Start, End, last = 0; + + + ClassRangeCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount )); + + OTV_LIMIT_CHECK( ClassRangeCount * 6 ); + + /* ClassRangeRecord */ + for ( n = 0; n < ClassRangeCount; n++ ) + { + Start = FT_NEXT_USHORT( p ); + End = FT_NEXT_USHORT( p ); + p += 2; /* skip Class */ + + if ( Start > End || ( n > 0 && Start <= last ) ) + FT_INVALID_DATA; + + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + + last = End; + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + /* no need to check glyph indices used as input to class definition */ + /* tables since even invalid glyph indices return a meaningful result */ + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** DEVICE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + otv_Device_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt StartSize, EndSize, DeltaFormat, count; + + + OTV_NAME_ENTER( "Device" ); + + OTV_LIMIT_CHECK( 8 ); + StartSize = FT_NEXT_USHORT( p ); + EndSize = FT_NEXT_USHORT( p ); + DeltaFormat = FT_NEXT_USHORT( p ); + + if ( DeltaFormat < 1 || DeltaFormat > 3 ) + FT_INVALID_FORMAT; + + if ( EndSize < StartSize ) + FT_INVALID_DATA; + + count = EndSize - StartSize + 1; + OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */ + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->type_count */ + /* uses valid->type_funcs */ + + FT_LOCAL_DEF( void ) + otv_Lookup_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt LookupType, SubTableCount; + OTV_Validate_Func validate; + + + OTV_NAME_ENTER( "Lookup" ); + + OTV_LIMIT_CHECK( 6 ); + LookupType = FT_NEXT_USHORT( p ); + p += 2; /* skip LookupFlag */ + SubTableCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (type %d)\n", LookupType )); + + if ( LookupType == 0 || LookupType > valid->type_count ) + FT_INVALID_DATA; + + validate = valid->type_funcs[LookupType - 1]; + + OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount )); + + OTV_LIMIT_CHECK( SubTableCount * 2 ); + + /* SubTable */ + for ( ; SubTableCount > 0; SubTableCount-- ) + validate( table + FT_NEXT_USHORT( p ), valid ); + + OTV_EXIT; + } + + + /* uses valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_LookupList_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt LookupCount; + + + OTV_NAME_ENTER( "LookupList" ); + + OTV_LIMIT_CHECK( 2 ); + LookupCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookupCount = %d)\n", LookupCount )); + + OTV_LIMIT_CHECK( LookupCount * 2 ); + + valid->lookup_count = LookupCount; + + /* Lookup */ + for ( ; LookupCount > 0; LookupCount-- ) + otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid ); + + OTV_EXIT; + } + + + static FT_UInt + otv_LookupList_get_count( FT_Bytes table ) + { + return FT_NEXT_USHORT( table ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_Feature_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt LookupCount; + + + OTV_NAME_ENTER( "Feature" ); + + OTV_LIMIT_CHECK( 4 ); + p += 2; /* skip FeatureParams (unused) */ + LookupCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookupCount = %d)\n", LookupCount )); + + OTV_LIMIT_CHECK( LookupCount * 2 ); + + /* LookupListIndex */ + for ( ; LookupCount > 0; LookupCount-- ) + if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + FT_INVALID_DATA; + + OTV_EXIT; + } + + + static FT_UInt + otv_Feature_get_count( FT_Bytes table ) + { + return FT_NEXT_USHORT( table ); + } + + + /* sets valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_FeatureList_validate( FT_Bytes table, + FT_Bytes lookups, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt FeatureCount; + + + OTV_NAME_ENTER( "FeatureList" ); + + OTV_LIMIT_CHECK( 2 ); + FeatureCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); + + OTV_LIMIT_CHECK( FeatureCount * 2 ); + + valid->lookup_count = otv_LookupList_get_count( lookups ); + + /* FeatureRecord */ + for ( ; FeatureCount > 0; FeatureCount-- ) + { + p += 4; /* skip FeatureTag */ + + /* Feature */ + otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LANGUAGE SYSTEM *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* uses valid->extra1 (number of features) */ + + FT_LOCAL_DEF( void ) + otv_LangSys_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt ReqFeatureIndex; + FT_UInt FeatureCount; + + + OTV_NAME_ENTER( "LangSys" ); + + OTV_LIMIT_CHECK( 6 ); + p += 2; /* skip LookupOrder (unused) */ + ReqFeatureIndex = FT_NEXT_USHORT( p ); + FeatureCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex )); + OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); + + if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 ) + FT_INVALID_DATA; + + OTV_LIMIT_CHECK( FeatureCount * 2 ); + + /* FeatureIndex */ + for ( ; FeatureCount > 0; FeatureCount-- ) + if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + FT_INVALID_DATA; + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SCRIPTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + otv_Script_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_UInt DefaultLangSys, LangSysCount; + FT_Bytes p = table; + + + OTV_NAME_ENTER( "Script" ); + + OTV_LIMIT_CHECK( 4 ); + DefaultLangSys = FT_NEXT_USHORT( p ); + LangSysCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount )); + + if ( DefaultLangSys != 0 ) + otv_LangSys_validate( table + DefaultLangSys, valid ); + + OTV_LIMIT_CHECK( LangSysCount * 6 ); + + /* LangSysRecord */ + for ( ; LangSysCount > 0; LangSysCount-- ) + { + p += 4; /* skip LangSysTag */ + + /* LangSys */ + otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + /* sets valid->extra1 (number of features) */ + + FT_LOCAL_DEF( void ) + otv_ScriptList_validate( FT_Bytes table, + FT_Bytes features, + OTV_Validator valid ) + { + FT_UInt ScriptCount; + FT_Bytes p = table; + + + OTV_NAME_ENTER( "ScriptList" ); + + OTV_LIMIT_CHECK( 2 ); + ScriptCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount )); + + OTV_LIMIT_CHECK( ScriptCount * 6 ); + + valid->extra1 = otv_Feature_get_count( features ); + + /* ScriptRecord */ + for ( ; ScriptCount > 0; ScriptCount-- ) + { + p += 4; /* skip ScriptTag */ + + otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */ + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + u: uint16 + ux: unit16 [x] + + s: struct + sx: struct [x] + sxy: struct [x], using external y count + + x: uint16 x + + C: Coverage + + O: Offset + On: Offset (NULL) + Ox: Offset [x] + Onx: Offset (NULL) [x] + */ + + FT_LOCAL_DEF( void ) + otv_x_Ox( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count; + OTV_Validate_Func func; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 2 ); + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( Count * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + + for ( ; Count > 0; Count-- ) + func( table + FT_NEXT_USHORT( p ), valid ); + + valid->nesting_level--; + + OTV_EXIT; + } + + + FT_LOCAL_DEF( void ) + otv_u_C_x_Ox( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count, Coverage; + OTV_Validate_Func func; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 4 ); + Coverage = FT_NEXT_USHORT( p ); + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + otv_Coverage_validate( table + Coverage, valid, Count ); + + OTV_LIMIT_CHECK( Count * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + + for ( ; Count > 0; Count-- ) + func( table + FT_NEXT_USHORT( p ), valid ); + + valid->nesting_level--; + + OTV_EXIT; + } + + + /* uses valid->extra1 (if > 0: array value limit) */ + + FT_LOCAL_DEF( void ) + otv_x_ux( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 2 ); + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( Count * 2 ); + + if ( valid->extra1 ) + { + for ( ; Count > 0; Count-- ) + if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + /* `ux' in the function's name is not really correct since only x-1 */ + /* elements are tested */ + + /* uses valid->extra1 (array value limit) */ + + FT_LOCAL_DEF( void ) + otv_x_y_ux_sy( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count1, Count2; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 4 ); + Count1 = FT_NEXT_USHORT( p ); + Count2 = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count1 = %d)\n", Count1 )); + OTV_TRACE(( " (Count2 = %d)\n", Count2 )); + + if ( Count1 == 0 ) + FT_INVALID_DATA; + + OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 ); + p += ( Count1 - 1 ) * 2; + + for ( ; Count2 > 0; Count2-- ) + { + if ( FT_NEXT_USHORT( p ) >= Count1 ) + FT_INVALID_DATA; + + if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + /* `uy' in the function's name is not really correct since only y-1 */ + /* elements are tested */ + + /* uses valid->extra1 (array value limit) */ + + FT_LOCAL_DEF( void ) + otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BacktrackCount, InputCount, LookaheadCount; + FT_UInt Count; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 2 ); + BacktrackCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount )); + + OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 ); + p += BacktrackCount * 2; + + InputCount = FT_NEXT_USHORT( p ); + if ( InputCount == 0 ) + FT_INVALID_DATA; + + OTV_TRACE(( " (InputCount = %d)\n", InputCount )); + + OTV_LIMIT_CHECK( InputCount * 2 ); + p += ( InputCount - 1 ) * 2; + + LookaheadCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount )); + + OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 ); + p += LookaheadCount * 2; + + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( Count * 4 ); + + for ( ; Count > 0; Count-- ) + { + if ( FT_NEXT_USHORT( p ) >= InputCount ) + FT_INVALID_DATA; + + if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + /* sets valid->extra1 (valid->lookup_count) */ + + FT_LOCAL_DEF( void ) + otv_u_O_O_x_Onx( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Coverage, ClassDef, ClassSetCount; + OTV_Validate_Func func; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 6 ); + Coverage = FT_NEXT_USHORT( p ); + ClassDef = FT_NEXT_USHORT( p ); + ClassSetCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_ClassDef_validate( table + ClassDef, valid ); + + OTV_LIMIT_CHECK( ClassSetCount * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + valid->extra1 = valid->lookup_count; + + for ( ; ClassSetCount > 0; ClassSetCount-- ) + { + FT_UInt offset = FT_NEXT_USHORT( p ); + + + if ( offset ) + func( table + offset, valid ); + } + + valid->nesting_level--; + + OTV_EXIT; + } + + + /* uses valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_u_x_y_Ox_sy( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt GlyphCount, Count, count1; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 4 ); + GlyphCount = FT_NEXT_USHORT( p ); + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); + + for ( count1 = GlyphCount; count1 > 0; count1-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + for ( ; Count > 0; Count-- ) + { + if ( FT_NEXT_USHORT( p ) >= GlyphCount ) + FT_INVALID_DATA; + + if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + /* sets valid->extra1 (valid->lookup_count) */ + + FT_LOCAL_DEF( void ) + otv_u_O_O_O_O_x_Onx( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Coverage; + FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef; + FT_UInt ChainClassSetCount; + OTV_Validate_Func func; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 10 ); + Coverage = FT_NEXT_USHORT( p ); + BacktrackClassDef = FT_NEXT_USHORT( p ); + InputClassDef = FT_NEXT_USHORT( p ); + LookaheadClassDef = FT_NEXT_USHORT( p ); + ChainClassSetCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + + otv_ClassDef_validate( table + BacktrackClassDef, valid ); + otv_ClassDef_validate( table + InputClassDef, valid ); + otv_ClassDef_validate( table + LookaheadClassDef, valid ); + + OTV_LIMIT_CHECK( ChainClassSetCount * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + valid->extra1 = valid->lookup_count; + + for ( ; ChainClassSetCount > 0; ChainClassSetCount-- ) + { + FT_UInt offset = FT_NEXT_USHORT( p ); + + + if ( offset ) + func( table + offset, valid ); + } + + valid->nesting_level--; + + OTV_EXIT; + } + + + /* uses valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount; + FT_UInt count1, count2; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 2 ); + BacktrackGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); + + OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); + + for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + InputGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount )); + + OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); + + for ( count1 = InputGlyphCount; count1 > 0; count1-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + LookaheadGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); + + OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); + + for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + count2 = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", count2 )); + + OTV_LIMIT_CHECK( count2 * 4 ); + + for ( ; count2 > 0; count2-- ) + { + if ( FT_NEXT_USHORT( p ) >= InputGlyphCount ) + FT_INVALID_DATA; + + if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_GSUBGPOS_get_Lookup_count( FT_Bytes table ) + { + FT_Bytes p = table + 8; + + + return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) ); + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table ) + { + FT_Bytes p, lookup; + FT_UInt count; + + + if ( !table ) + return 0; + + /* LookupList */ + p = table + 8; + table += FT_NEXT_USHORT( p ); + + /* LookupCount */ + p = table; + count = FT_NEXT_USHORT( p ); + + for ( ; count > 0; count-- ) + { + FT_Bytes oldp; + + + /* Lookup */ + lookup = table + FT_NEXT_USHORT( p ); + + oldp = p; + + /* LookupFlag */ + p = lookup + 2; + if ( FT_NEXT_USHORT( p ) & 0xFF00U ) + return 1; + + p = oldp; + } + + return 0; + } + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvcommn.h b/drivers/freetype/src/otvalid/otvcommn.h new file mode 100644 index 0000000000..898887fc95 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvcommn.h @@ -0,0 +1,437 @@ +/***************************************************************************/ +/* */ +/* otvcommn.h */ +/* */ +/* OpenType common tables validation (specification). */ +/* */ +/* Copyright 2004, 2005, 2007, 2009 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 __OTVCOMMN_H__ +#define __OTVCOMMN_H__ + + +#include <ft2build.h> +#include "otvalid.h" +#include FT_INTERNAL_DEBUG_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** VALIDATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct OTV_ValidatorRec_* OTV_Validator; + + typedef void (*OTV_Validate_Func)( FT_Bytes table, + OTV_Validator valid ); + + typedef struct OTV_ValidatorRec_ + { + FT_Validator root; + FT_UInt type_count; + OTV_Validate_Func* type_funcs; + + FT_UInt lookup_count; + FT_UInt glyph_count; + + FT_UInt nesting_level; + + OTV_Validate_Func func[3]; + + FT_UInt extra1; /* for passing parameters */ + FT_UInt extra2; + FT_Bytes extra3; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_UInt debug_indent; + const FT_String* debug_function_name[3]; +#endif + + } OTV_ValidatorRec; + + +#undef FT_INVALID_ +#define FT_INVALID_( _prefix, _error ) \ + ft_validator_error( valid->root, _prefix ## _error ) + +#define OTV_OPTIONAL_TABLE( _table ) FT_UShort _table; \ + FT_Bytes _table ## _p + +#define OTV_OPTIONAL_OFFSET( _offset ) \ + FT_BEGIN_STMNT \ + _offset ## _p = p; \ + _offset = FT_NEXT_USHORT( p ); \ + FT_END_STMNT + +#define OTV_LIMIT_CHECK( _count ) \ + FT_BEGIN_STMNT \ + if ( p + (_count) > valid->root->limit ) \ + FT_INVALID_TOO_SHORT; \ + FT_END_STMNT + +#define OTV_SIZE_CHECK( _size ) \ + FT_BEGIN_STMNT \ + if ( _size > 0 && _size < table_size ) \ + { \ + if ( valid->root->level == FT_VALIDATE_PARANOID ) \ + FT_INVALID_OFFSET; \ + else \ + { \ + /* strip off `const' */ \ + FT_Byte* pp = (FT_Byte*)_size ## _p; \ + \ + \ + FT_TRACE3(( "\n" \ + "Invalid offset to optional table `%s'" \ + " set to zero.\n" \ + "\n", #_size )); \ + \ + /* always assume 16bit entities */ \ + _size = pp[0] = pp[1] = 0; \ + } \ + } \ + FT_END_STMNT + + +#define OTV_NAME_(x) #x +#define OTV_NAME(x) OTV_NAME_(x) + +#define OTV_FUNC_(x) x##Func +#define OTV_FUNC(x) OTV_FUNC_(x) + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define OTV_NEST1( x ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->debug_function_name[0] = OTV_NAME( x ); \ + FT_END_STMNT + +#define OTV_NEST2( x, y ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->func[1] = OTV_FUNC( y ); \ + valid->debug_function_name[0] = OTV_NAME( x ); \ + valid->debug_function_name[1] = OTV_NAME( y ); \ + FT_END_STMNT + +#define OTV_NEST3( x, y, z ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->func[1] = OTV_FUNC( y ); \ + valid->func[2] = OTV_FUNC( z ); \ + valid->debug_function_name[0] = OTV_NAME( x ); \ + valid->debug_function_name[1] = OTV_NAME( y ); \ + valid->debug_function_name[2] = OTV_NAME( z ); \ + FT_END_STMNT + +#define OTV_INIT valid->debug_indent = 0 + +#define OTV_ENTER \ + FT_BEGIN_STMNT \ + valid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", \ + valid->debug_function_name[valid->nesting_level] )); \ + FT_END_STMNT + +#define OTV_NAME_ENTER( name ) \ + FT_BEGIN_STMNT \ + valid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", name )); \ + FT_END_STMNT + +#define OTV_EXIT valid->debug_indent -= 2 + +#define OTV_TRACE( s ) \ + FT_BEGIN_STMNT \ + FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4( s ); \ + FT_END_STMNT + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define OTV_NEST1( x ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + FT_END_STMNT + +#define OTV_NEST2( x, y ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->func[1] = OTV_FUNC( y ); \ + FT_END_STMNT + +#define OTV_NEST3( x, y, z ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->func[1] = OTV_FUNC( y ); \ + valid->func[2] = OTV_FUNC( z ); \ + FT_END_STMNT + +#define OTV_INIT do { } while ( 0 ) +#define OTV_ENTER do { } while ( 0 ) +#define OTV_NAME_ENTER( name ) do { } while ( 0 ) +#define OTV_EXIT do { } while ( 0 ) + +#define OTV_TRACE( s ) do { } while ( 0 ) + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +#define OTV_RUN valid->func[0] + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** COVERAGE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Coverage_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int expected_count ); + + /* return first covered glyph */ + FT_LOCAL( FT_UInt ) + otv_Coverage_get_first( FT_Bytes table ); + + /* return last covered glyph */ + FT_LOCAL( FT_UInt ) + otv_Coverage_get_last( FT_Bytes table ); + + /* return number of covered glyphs */ + FT_LOCAL( FT_UInt ) + otv_Coverage_get_count( FT_Bytes table ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CLASS DEFINITION TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_ClassDef_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** DEVICE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Device_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Lookup_validate( FT_Bytes table, + OTV_Validator valid ); + + FT_LOCAL( void ) + otv_LookupList_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Feature_validate( FT_Bytes table, + OTV_Validator valid ); + + /* lookups must already be validated */ + FT_LOCAL( void ) + otv_FeatureList_validate( FT_Bytes table, + FT_Bytes lookups, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LANGUAGE SYSTEM *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_LangSys_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SCRIPTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Script_validate( FT_Bytes table, + OTV_Validator valid ); + + /* features must already be validated */ + FT_LOCAL( void ) + otv_ScriptList_validate( FT_Bytes table, + FT_Bytes features, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define ChainPosClassSetFunc otv_x_Ox +#define ChainPosRuleSetFunc otv_x_Ox +#define ChainSubClassSetFunc otv_x_Ox +#define ChainSubRuleSetFunc otv_x_Ox +#define JstfLangSysFunc otv_x_Ox +#define JstfMaxFunc otv_x_Ox +#define LigGlyphFunc otv_x_Ox +#define LigatureArrayFunc otv_x_Ox +#define LigatureSetFunc otv_x_Ox +#define PosClassSetFunc otv_x_Ox +#define PosRuleSetFunc otv_x_Ox +#define SubClassSetFunc otv_x_Ox +#define SubRuleSetFunc otv_x_Ox + + FT_LOCAL( void ) + otv_x_Ox ( FT_Bytes table, + OTV_Validator valid ); + +#define AlternateSubstFormat1Func otv_u_C_x_Ox +#define ChainContextPosFormat1Func otv_u_C_x_Ox +#define ChainContextSubstFormat1Func otv_u_C_x_Ox +#define ContextPosFormat1Func otv_u_C_x_Ox +#define ContextSubstFormat1Func otv_u_C_x_Ox +#define LigatureSubstFormat1Func otv_u_C_x_Ox +#define MultipleSubstFormat1Func otv_u_C_x_Ox + + FT_LOCAL( void ) + otv_u_C_x_Ox( FT_Bytes table, + OTV_Validator valid ); + +#define AlternateSetFunc otv_x_ux +#define AttachPointFunc otv_x_ux +#define ExtenderGlyphFunc otv_x_ux +#define JstfGPOSModListFunc otv_x_ux +#define JstfGSUBModListFunc otv_x_ux +#define SequenceFunc otv_x_ux + + FT_LOCAL( void ) + otv_x_ux( FT_Bytes table, + OTV_Validator valid ); + +#define PosClassRuleFunc otv_x_y_ux_sy +#define PosRuleFunc otv_x_y_ux_sy +#define SubClassRuleFunc otv_x_y_ux_sy +#define SubRuleFunc otv_x_y_ux_sy + + FT_LOCAL( void ) + otv_x_y_ux_sy( FT_Bytes table, + OTV_Validator valid ); + +#define ChainPosClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp +#define ChainPosRuleFunc otv_x_ux_y_uy_z_uz_p_sp +#define ChainSubClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp +#define ChainSubRuleFunc otv_x_ux_y_uy_z_uz_p_sp + + FT_LOCAL( void ) + otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, + OTV_Validator valid ); + +#define ContextPosFormat2Func otv_u_O_O_x_Onx +#define ContextSubstFormat2Func otv_u_O_O_x_Onx + + FT_LOCAL( void ) + otv_u_O_O_x_Onx( FT_Bytes table, + OTV_Validator valid ); + +#define ContextPosFormat3Func otv_u_x_y_Ox_sy +#define ContextSubstFormat3Func otv_u_x_y_Ox_sy + + FT_LOCAL( void ) + otv_u_x_y_Ox_sy( FT_Bytes table, + OTV_Validator valid ); + +#define ChainContextPosFormat2Func otv_u_O_O_O_O_x_Onx +#define ChainContextSubstFormat2Func otv_u_O_O_O_O_x_Onx + + FT_LOCAL( void ) + otv_u_O_O_O_O_x_Onx( FT_Bytes table, + OTV_Validator valid ); + +#define ChainContextPosFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp +#define ChainContextSubstFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp + + FT_LOCAL( void ) + otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, + OTV_Validator valid ); + + + FT_LOCAL( FT_UInt ) + otv_GSUBGPOS_get_Lookup_count( FT_Bytes table ); + + FT_LOCAL( FT_UInt ) + otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table ); + + /* */ + +FT_END_HEADER + +#endif /* __OTVCOMMN_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otverror.h b/drivers/freetype/src/otvalid/otverror.h new file mode 100644 index 0000000000..b6f00c9dba --- /dev/null +++ b/drivers/freetype/src/otvalid/otverror.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* otverror.h */ +/* */ +/* OpenType validation module error codes (specification only). */ +/* */ +/* Copyright 2004, 2005, 2012, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the OpenType validation module error */ + /* enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __OTVERROR_H__ +#define __OTVERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX OTV_Err_ +#define FT_ERR_BASE FT_Mod_Err_OTvalid + +#include FT_ERRORS_H + +#endif /* __OTVERROR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvgdef.c b/drivers/freetype/src/otvalid/otvgdef.c new file mode 100644 index 0000000000..3633ad0de1 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvgdef.c @@ -0,0 +1,224 @@ +/***************************************************************************/ +/* */ +/* otvgdef.c */ +/* */ +/* OpenType GDEF table validation (body). */ +/* */ +/* Copyright 2004, 2005, 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 "otvalid.h" +#include "otvcommn.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_otvgdef + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define AttachListFunc otv_O_x_Ox +#define LigCaretListFunc otv_O_x_Ox + + /* sets valid->extra1 (0) */ + + static void + otv_O_x_Ox( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_Bytes Coverage; + FT_UInt GlyphCount; + OTV_Validate_Func func; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 4 ); + Coverage = table + FT_NEXT_USHORT( p ); + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + otv_Coverage_validate( Coverage, valid, GlyphCount ); + if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) + FT_INVALID_DATA; + + OTV_LIMIT_CHECK( GlyphCount * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + valid->extra1 = 0; + + for ( ; GlyphCount > 0; GlyphCount-- ) + func( table + FT_NEXT_USHORT( p ), valid ); + + valid->nesting_level--; + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LIGATURE CARETS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define CaretValueFunc otv_CaretValue_validate + + static void + otv_CaretValue_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt CaretValueFormat; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 4 ); + + CaretValueFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format = %d)\n", CaretValueFormat )); + + switch ( CaretValueFormat ) + { + case 1: /* CaretValueFormat1 */ + /* skip Coordinate, no test */ + break; + + case 2: /* CaretValueFormat2 */ + /* skip CaretValuePoint, no test */ + break; + + case 3: /* CaretValueFormat3 */ + p += 2; /* skip Coordinate */ + + OTV_LIMIT_CHECK( 2 ); + + /* DeviceTable */ + otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GDEF TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_GDEF_validate( FT_Bytes table, + FT_Bytes gsub, + FT_Bytes gpos, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt table_size; + FT_Bool need_MarkAttachClassDef; + + OTV_OPTIONAL_TABLE( GlyphClassDef ); + OTV_OPTIONAL_TABLE( AttachListOffset ); + OTV_OPTIONAL_TABLE( LigCaretListOffset ); + OTV_OPTIONAL_TABLE( MarkAttachClassDef ); + + + valid->root = ftvalid; + + FT_TRACE3(( "validating GDEF table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 12 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + /* MarkAttachClassDef has been added to the OpenType */ + /* specification without increasing GDEF's version, */ + /* so we use this ugly hack to find out whether the */ + /* table is needed actually. */ + + need_MarkAttachClassDef = FT_BOOL( + otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) || + otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) ); + + if ( need_MarkAttachClassDef ) + table_size = 12; /* OpenType >= 1.2 */ + else + table_size = 10; /* OpenType < 1.2 */ + + valid->glyph_count = glyph_count; + + OTV_OPTIONAL_OFFSET( GlyphClassDef ); + OTV_SIZE_CHECK( GlyphClassDef ); + if ( GlyphClassDef ) + otv_ClassDef_validate( table + GlyphClassDef, valid ); + + OTV_OPTIONAL_OFFSET( AttachListOffset ); + OTV_SIZE_CHECK( AttachListOffset ); + if ( AttachListOffset ) + { + OTV_NEST2( AttachList, AttachPoint ); + OTV_RUN( table + AttachListOffset, valid ); + } + + OTV_OPTIONAL_OFFSET( LigCaretListOffset ); + OTV_SIZE_CHECK( LigCaretListOffset ); + if ( LigCaretListOffset ) + { + OTV_NEST3( LigCaretList, LigGlyph, CaretValue ); + OTV_RUN( table + LigCaretListOffset, valid ); + } + + if ( need_MarkAttachClassDef ) + { + OTV_OPTIONAL_OFFSET( MarkAttachClassDef ); + OTV_SIZE_CHECK( MarkAttachClassDef ); + if ( MarkAttachClassDef ) + otv_ClassDef_validate( table + MarkAttachClassDef, valid ); + } + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvgpos.c b/drivers/freetype/src/otvalid/otvgpos.c new file mode 100644 index 0000000000..49b46183a3 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvgpos.c @@ -0,0 +1,1017 @@ +/***************************************************************************/ +/* */ +/* otvgpos.c */ +/* */ +/* OpenType GPOS table validation (body). */ +/* */ +/* Copyright 2002, 2004, 2005, 2006, 2007, 2008 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 "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.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_otvgpos + + + static void + otv_Anchor_validate( FT_Bytes table, + OTV_Validator valid ); + + static void + otv_MarkArray_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define BaseArrayFunc otv_x_sxy +#define LigatureAttachFunc otv_x_sxy +#define Mark2ArrayFunc otv_x_sxy + + /* uses valid->extra1 (counter) */ + /* uses valid->extra2 (boolean to handle NULL anchor field) */ + + static void + otv_x_sxy( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count, count1, table_size; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 2 ); + + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( Count * valid->extra1 * 2 ); + + table_size = Count * valid->extra1 * 2 + 2; + + for ( ; Count > 0; Count-- ) + for ( count1 = valid->extra1; count1 > 0; count1-- ) + { + OTV_OPTIONAL_TABLE( anchor_offset ); + + + OTV_OPTIONAL_OFFSET( anchor_offset ); + + if ( valid->extra2 ) + { + OTV_SIZE_CHECK( anchor_offset ); + if ( anchor_offset ) + otv_Anchor_validate( table + anchor_offset, valid ); + } + else + otv_Anchor_validate( table + anchor_offset, valid ); + } + + OTV_EXIT; + } + + +#define MarkBasePosFormat1Func otv_u_O_O_u_O_O +#define MarkLigPosFormat1Func otv_u_O_O_u_O_O +#define MarkMarkPosFormat1Func otv_u_O_O_u_O_O + + /* sets valid->extra1 (class count) */ + + static void + otv_u_O_O_u_O_O( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Coverage1, Coverage2, ClassCount; + FT_UInt Array1, Array2; + OTV_Validate_Func func; + + + OTV_ENTER; + + p += 2; /* skip PosFormat */ + + OTV_LIMIT_CHECK( 10 ); + Coverage1 = FT_NEXT_USHORT( p ); + Coverage2 = FT_NEXT_USHORT( p ); + ClassCount = FT_NEXT_USHORT( p ); + Array1 = FT_NEXT_USHORT( p ); + Array2 = FT_NEXT_USHORT( p ); + + otv_Coverage_validate( table + Coverage1, valid, -1 ); + otv_Coverage_validate( table + Coverage2, valid, -1 ); + + otv_MarkArray_validate( table + Array1, valid ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + valid->extra1 = ClassCount; + + func( table + Array2, valid ); + + valid->nesting_level--; + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** VALUE RECORDS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_UInt + otv_value_length( FT_UInt format ) + { + FT_UInt count; + + + count = ( ( format & 0xAA ) >> 1 ) + ( format & 0x55 ); + count = ( ( count & 0xCC ) >> 2 ) + ( count & 0x33 ); + count = ( ( count & 0xF0 ) >> 4 ) + ( count & 0x0F ); + + return count * 2; + } + + + /* uses valid->extra3 (pointer to base table) */ + + static void + otv_ValueRecord_validate( FT_Bytes table, + FT_UInt format, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt count; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Int loop; + FT_ULong res = 0; + + + OTV_NAME_ENTER( "ValueRecord" ); + + /* display `format' in dual representation */ + for ( loop = 7; loop >= 0; loop-- ) + { + res <<= 4; + res += ( format >> loop ) & 1; + } + + OTV_TRACE(( " (format 0b%08lx)\n", res )); +#endif + + if ( format >= 0x100 ) + FT_INVALID_FORMAT; + + for ( count = 4; count > 0; count-- ) + { + if ( format & 1 ) + { + /* XPlacement, YPlacement, XAdvance, YAdvance */ + OTV_LIMIT_CHECK( 2 ); + p += 2; + } + + format >>= 1; + } + + for ( count = 4; count > 0; count-- ) + { + if ( format & 1 ) + { + FT_PtrDist table_size; + + OTV_OPTIONAL_TABLE( device ); + + + /* XPlaDevice, YPlaDevice, XAdvDevice, YAdvDevice */ + OTV_LIMIT_CHECK( 2 ); + OTV_OPTIONAL_OFFSET( device ); + + /* XXX: this value is usually too small, especially if the current */ + /* ValueRecord is part of an array -- getting the correct table */ + /* size is probably not worth the trouble */ + + table_size = p - valid->extra3; + + OTV_SIZE_CHECK( device ); + if ( device ) + otv_Device_validate( valid->extra3 + device, valid ); + } + format >>= 1; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** ANCHORS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_Anchor_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt AnchorFormat; + + + OTV_NAME_ENTER( "Anchor"); + + OTV_LIMIT_CHECK( 6 ); + AnchorFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", AnchorFormat )); + + p += 4; /* skip XCoordinate and YCoordinate */ + + switch ( AnchorFormat ) + { + case 1: + break; + + case 2: + OTV_LIMIT_CHECK( 2 ); /* AnchorPoint */ + break; + + case 3: + { + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( XDeviceTable ); + OTV_OPTIONAL_TABLE( YDeviceTable ); + + + OTV_LIMIT_CHECK( 4 ); + OTV_OPTIONAL_OFFSET( XDeviceTable ); + OTV_OPTIONAL_OFFSET( YDeviceTable ); + + table_size = 6 + 4; + + OTV_SIZE_CHECK( XDeviceTable ); + if ( XDeviceTable ) + otv_Device_validate( table + XDeviceTable, valid ); + + OTV_SIZE_CHECK( YDeviceTable ); + if ( YDeviceTable ) + otv_Device_validate( table + YDeviceTable, valid ); + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MARK ARRAYS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MarkArray_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt MarkCount; + + + OTV_NAME_ENTER( "MarkArray" ); + + OTV_LIMIT_CHECK( 2 ); + MarkCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (MarkCount = %d)\n", MarkCount )); + + OTV_LIMIT_CHECK( MarkCount * 4 ); + + /* MarkRecord */ + for ( ; MarkCount > 0; MarkCount-- ) + { + p += 2; /* skip Class */ + /* MarkAnchor */ + otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 1 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra3 (pointer to base table) */ + + static void + otv_SinglePos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "SinglePos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + valid->extra3 = table; + + switch ( PosFormat ) + { + case 1: /* SinglePosFormat1 */ + { + FT_UInt Coverage, ValueFormat; + + + OTV_LIMIT_CHECK( 4 ); + Coverage = FT_NEXT_USHORT( p ); + ValueFormat = FT_NEXT_USHORT( p ); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ + } + break; + + case 2: /* SinglePosFormat2 */ + { + FT_UInt Coverage, ValueFormat, ValueCount, len_value; + + + OTV_LIMIT_CHECK( 6 ); + Coverage = FT_NEXT_USHORT( p ); + ValueFormat = FT_NEXT_USHORT( p ); + ValueCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ValueCount = %d)\n", ValueCount )); + + len_value = otv_value_length( ValueFormat ); + + otv_Coverage_validate( table + Coverage, valid, ValueCount ); + + OTV_LIMIT_CHECK( ValueCount * len_value ); + + /* Value */ + for ( ; ValueCount > 0; ValueCount-- ) + { + otv_ValueRecord_validate( p, ValueFormat, valid ); + p += len_value; + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 2 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_PairSet_validate( FT_Bytes table, + FT_UInt format1, + FT_UInt format2, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt value_len1, value_len2, PairValueCount; + + + OTV_NAME_ENTER( "PairSet" ); + + OTV_LIMIT_CHECK( 2 ); + PairValueCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (PairValueCount = %d)\n", PairValueCount )); + + value_len1 = otv_value_length( format1 ); + value_len2 = otv_value_length( format2 ); + + OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) ); + + /* PairValueRecord */ + for ( ; PairValueCount > 0; PairValueCount-- ) + { + p += 2; /* skip SecondGlyph */ + + if ( format1 ) + otv_ValueRecord_validate( p, format1, valid ); /* Value1 */ + p += value_len1; + + if ( format2 ) + otv_ValueRecord_validate( p, format2, valid ); /* Value2 */ + p += value_len2; + } + + OTV_EXIT; + } + + + /* sets valid->extra3 (pointer to base table) */ + + static void + otv_PairPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "PairPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + valid->extra3 = table; + + switch ( PosFormat ) + { + case 1: /* PairPosFormat1 */ + { + FT_UInt Coverage, ValueFormat1, ValueFormat2, PairSetCount; + + + OTV_LIMIT_CHECK( 8 ); + Coverage = FT_NEXT_USHORT( p ); + ValueFormat1 = FT_NEXT_USHORT( p ); + ValueFormat2 = FT_NEXT_USHORT( p ); + PairSetCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + + OTV_LIMIT_CHECK( PairSetCount * 2 ); + + /* PairSetOffset */ + for ( ; PairSetCount > 0; PairSetCount-- ) + otv_PairSet_validate( table + FT_NEXT_USHORT( p ), + ValueFormat1, ValueFormat2, valid ); + } + break; + + case 2: /* PairPosFormat2 */ + { + FT_UInt Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2; + FT_UInt ClassCount1, ClassCount2, len_value1, len_value2, count; + + + OTV_LIMIT_CHECK( 14 ); + Coverage = FT_NEXT_USHORT( p ); + ValueFormat1 = FT_NEXT_USHORT( p ); + ValueFormat2 = FT_NEXT_USHORT( p ); + ClassDef1 = FT_NEXT_USHORT( p ); + ClassDef2 = FT_NEXT_USHORT( p ); + ClassCount1 = FT_NEXT_USHORT( p ); + ClassCount2 = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ClassCount1 = %d)\n", ClassCount1 )); + OTV_TRACE(( " (ClassCount2 = %d)\n", ClassCount2 )); + + len_value1 = otv_value_length( ValueFormat1 ); + len_value2 = otv_value_length( ValueFormat2 ); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_ClassDef_validate( table + ClassDef1, valid ); + otv_ClassDef_validate( table + ClassDef2, valid ); + + OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 * + ( len_value1 + len_value2 ) ); + + /* Class1Record */ + for ( ; ClassCount1 > 0; ClassCount1-- ) + { + /* Class2Record */ + for ( count = ClassCount2; count > 0; count-- ) + { + if ( ValueFormat1 ) + /* Value1 */ + otv_ValueRecord_validate( p, ValueFormat1, valid ); + p += len_value1; + + if ( ValueFormat2 ) + /* Value2 */ + otv_ValueRecord_validate( p, ValueFormat2, valid ); + p += len_value2; + } + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 3 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_CursivePos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "CursivePos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: /* CursivePosFormat1 */ + { + FT_UInt table_size; + FT_UInt Coverage, EntryExitCount; + + OTV_OPTIONAL_TABLE( EntryAnchor ); + OTV_OPTIONAL_TABLE( ExitAnchor ); + + + OTV_LIMIT_CHECK( 4 ); + Coverage = FT_NEXT_USHORT( p ); + EntryExitCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); + + otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); + + OTV_LIMIT_CHECK( EntryExitCount * 4 ); + + table_size = EntryExitCount * 4 + 4; + + /* EntryExitRecord */ + for ( ; EntryExitCount > 0; EntryExitCount-- ) + { + OTV_OPTIONAL_OFFSET( EntryAnchor ); + OTV_OPTIONAL_OFFSET( ExitAnchor ); + + OTV_SIZE_CHECK( EntryAnchor ); + if ( EntryAnchor ) + otv_Anchor_validate( table + EntryAnchor, valid ); + + OTV_SIZE_CHECK( ExitAnchor ); + if ( ExitAnchor ) + otv_Anchor_validate( table + ExitAnchor, valid ); + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 4 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* UNDOCUMENTED (in OpenType 1.5): */ + /* BaseRecord tables can contain NULL pointers. */ + + /* sets valid->extra2 (1) */ + + static void + otv_MarkBasePos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "MarkBasePos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + valid->extra2 = 1; + OTV_NEST2( MarkBasePosFormat1, BaseArray ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 5 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra2 (1) */ + + static void + otv_MarkLigPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "MarkLigPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + valid->extra2 = 1; + OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 6 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra2 (0) */ + + static void + otv_MarkMarkPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "MarkMarkPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + valid->extra2 = 0; + OTV_NEST2( MarkMarkPosFormat1, Mark2Array ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 7 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (lookup count) */ + + static void + otv_ContextPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "ContextPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + valid->extra1 = valid->lookup_count; + OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule ); + OTV_RUN( table, valid ); + break; + + case 2: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule ); + OTV_RUN( table, valid ); + break; + + case 3: + OTV_NEST1( ContextPosFormat3 ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 8 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (lookup count) */ + + static void + otv_ChainContextPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "ChainContextPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + valid->extra1 = valid->lookup_count; + OTV_NEST3( ChainContextPosFormat1, + ChainPosRuleSet, ChainPosRule ); + OTV_RUN( table, valid ); + break; + + case 2: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + OTV_NEST3( ChainContextPosFormat2, + ChainPosClassSet, ChainPosClassRule ); + OTV_RUN( table, valid ); + break; + + case 3: + OTV_NEST1( ChainContextPosFormat3 ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 9 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->type_funcs */ + + static void + otv_ExtensionPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "ExtensionPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: /* ExtensionPosFormat1 */ + { + FT_UInt ExtensionLookupType; + FT_ULong ExtensionOffset; + OTV_Validate_Func validate; + + + OTV_LIMIT_CHECK( 6 ); + ExtensionLookupType = FT_NEXT_USHORT( p ); + ExtensionOffset = FT_NEXT_ULONG( p ); + + if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 ) + FT_INVALID_DATA; + + validate = valid->type_funcs[ExtensionLookupType - 1]; + validate( table + ExtensionOffset, valid ); + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + static const OTV_Validate_Func otv_gpos_validate_funcs[9] = + { + otv_SinglePos_validate, + otv_PairPos_validate, + otv_CursivePos_validate, + otv_MarkBasePos_validate, + otv_MarkLigPos_validate, + otv_MarkMarkPos_validate, + otv_ContextPos_validate, + otv_ChainContextPos_validate, + otv_ExtensionPos_validate + }; + + + /* sets valid->type_count */ + /* sets valid->type_funcs */ + + FT_LOCAL_DEF( void ) + otv_GPOS_subtable_validate( FT_Bytes table, + OTV_Validator valid ) + { + valid->type_count = 9; + valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; + + otv_Lookup_validate( table, valid ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_GPOS_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt ScriptList, FeatureList, LookupList; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating GPOS table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + ScriptList = FT_NEXT_USHORT( p ); + FeatureList = FT_NEXT_USHORT( p ); + LookupList = FT_NEXT_USHORT( p ); + + valid->type_count = 9; + valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; + valid->glyph_count = glyph_count; + + otv_LookupList_validate( table + LookupList, + valid ); + otv_FeatureList_validate( table + FeatureList, table + LookupList, + valid ); + otv_ScriptList_validate( table + ScriptList, table + FeatureList, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvgpos.h b/drivers/freetype/src/otvalid/otvgpos.h new file mode 100644 index 0000000000..14ca408261 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvgpos.h @@ -0,0 +1,36 @@ +/***************************************************************************/ +/* */ +/* otvgpos.h */ +/* */ +/* OpenType GPOS table validator (specification). */ +/* */ +/* Copyright 2004 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 __OTVGPOS_H__ +#define __OTVGPOS_H__ + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + otv_GPOS_subtable_validate( FT_Bytes table, + OTV_Validator valid ); + + +FT_END_HEADER + +#endif /* __OTVGPOS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvgsub.c b/drivers/freetype/src/otvalid/otvgsub.c new file mode 100644 index 0000000000..ed499d1e92 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvgsub.c @@ -0,0 +1,585 @@ +/***************************************************************************/ +/* */ +/* otvgsub.c */ +/* */ +/* OpenType GSUB table validation (body). */ +/* */ +/* Copyright 2004, 2005, 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 "otvalid.h" +#include "otvcommn.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_otvgsub + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 1 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->glyph_count */ + + static void + otv_SingleSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "SingleSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: /* SingleSubstFormat1 */ + { + FT_Bytes Coverage; + FT_Int DeltaGlyphID; + FT_Long idx; + + + OTV_LIMIT_CHECK( 4 ); + Coverage = table + FT_NEXT_USHORT( p ); + DeltaGlyphID = FT_NEXT_SHORT( p ); + + otv_Coverage_validate( Coverage, valid, -1 ); + + idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; + if ( idx < 0 ) + FT_INVALID_DATA; + + idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID; + if ( (FT_UInt)idx >= valid->glyph_count ) + FT_INVALID_DATA; + } + break; + + case 2: /* SingleSubstFormat2 */ + { + FT_UInt Coverage, GlyphCount; + + + OTV_LIMIT_CHECK( 4 ); + Coverage = FT_NEXT_USHORT( p ); + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + otv_Coverage_validate( table + Coverage, valid, GlyphCount ); + + OTV_LIMIT_CHECK( GlyphCount * 2 ); + + /* Substitute */ + for ( ; GlyphCount > 0; GlyphCount-- ) + if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 2 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (glyph count) */ + + static void + otv_MultipleSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "MultipleSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + valid->extra1 = valid->glyph_count; + OTV_NEST2( MultipleSubstFormat1, Sequence ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 3 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (glyph count) */ + + static void + otv_AlternateSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "AlternateSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + valid->extra1 = valid->glyph_count; + OTV_NEST2( AlternateSubstFormat1, AlternateSet ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 4 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define LigatureFunc otv_Ligature_validate + + /* uses valid->glyph_count */ + + static void + otv_Ligature_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt LigatureGlyph, CompCount; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 4 ); + LigatureGlyph = FT_NEXT_USHORT( p ); + if ( LigatureGlyph >= valid->glyph_count ) + FT_INVALID_DATA; + + CompCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (CompCount = %d)\n", CompCount )); + + if ( CompCount == 0 ) + FT_INVALID_DATA; + + CompCount--; + + OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */ + + /* no need to check the Component glyph indices */ + + OTV_EXIT; + } + + + static void + otv_LigatureSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "LigatureSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 5 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (lookup count) */ + + static void + otv_ContextSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "ContextSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + valid->extra1 = valid->lookup_count; + OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule ); + OTV_RUN( table, valid ); + break; + + case 2: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule ); + OTV_RUN( table, valid ); + break; + + case 3: + OTV_NEST1( ContextSubstFormat3 ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 6 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (lookup count) */ + + static void + otv_ChainContextSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "ChainContextSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + valid->extra1 = valid->lookup_count; + OTV_NEST3( ChainContextSubstFormat1, + ChainSubRuleSet, ChainSubRule ); + OTV_RUN( table, valid ); + break; + + case 2: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + OTV_NEST3( ChainContextSubstFormat2, + ChainSubClassSet, ChainSubClassRule ); + OTV_RUN( table, valid ); + break; + + case 3: + OTV_NEST1( ChainContextSubstFormat3 ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 7 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->type_funcs */ + + static void + otv_ExtensionSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "ExtensionSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: /* ExtensionSubstFormat1 */ + { + FT_UInt ExtensionLookupType; + FT_ULong ExtensionOffset; + OTV_Validate_Func validate; + + + OTV_LIMIT_CHECK( 6 ); + ExtensionLookupType = FT_NEXT_USHORT( p ); + ExtensionOffset = FT_NEXT_ULONG( p ); + + if ( ExtensionLookupType == 0 || + ExtensionLookupType == 7 || + ExtensionLookupType > 8 ) + FT_INVALID_DATA; + + validate = valid->type_funcs[ExtensionLookupType - 1]; + validate( table + ExtensionOffset, valid ); + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 8 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->glyph_count */ + + static void + otv_ReverseChainSingleSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table, Coverage; + FT_UInt SubstFormat; + FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount; + + + OTV_NAME_ENTER( "ReverseChainSingleSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: /* ReverseChainSingleSubstFormat1 */ + OTV_LIMIT_CHECK( 4 ); + Coverage = table + FT_NEXT_USHORT( p ); + BacktrackGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); + + otv_Coverage_validate( Coverage, valid, -1 ); + + OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); + + for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + LookaheadGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); + + OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); + + for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) + FT_INVALID_DATA; + + OTV_LIMIT_CHECK( GlyphCount * 2 ); + + /* Substitute */ + for ( ; GlyphCount > 0; GlyphCount-- ) + if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) + FT_INVALID_DATA; + + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + static const OTV_Validate_Func otv_gsub_validate_funcs[8] = + { + otv_SingleSubst_validate, + otv_MultipleSubst_validate, + otv_AlternateSubst_validate, + otv_LigatureSubst_validate, + otv_ContextSubst_validate, + otv_ChainContextSubst_validate, + otv_ExtensionSubst_validate, + otv_ReverseChainSingleSubst_validate + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->type_count */ + /* sets valid->type_funcs */ + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_GSUB_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt ScriptList, FeatureList, LookupList; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating GSUB table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + ScriptList = FT_NEXT_USHORT( p ); + FeatureList = FT_NEXT_USHORT( p ); + LookupList = FT_NEXT_USHORT( p ); + + valid->type_count = 8; + valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; + valid->glyph_count = glyph_count; + + otv_LookupList_validate( table + LookupList, + valid ); + otv_FeatureList_validate( table + FeatureList, table + LookupList, + valid ); + otv_ScriptList_validate( table + ScriptList, table + FeatureList, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvjstf.c b/drivers/freetype/src/otvalid/otvjstf.c new file mode 100644 index 0000000000..a616a23432 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvjstf.c @@ -0,0 +1,258 @@ +/***************************************************************************/ +/* */ +/* otvjstf.c */ +/* */ +/* OpenType JSTF table validation (body). */ +/* */ +/* Copyright 2004, 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 "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.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_otvjstf + + +#define JstfPriorityFunc otv_JstfPriority_validate +#define JstfLookupFunc otv_GPOS_subtable_validate + + /* uses valid->extra1 (GSUB lookup count) */ + /* uses valid->extra2 (GPOS lookup count) */ + /* sets valid->extra1 (counter) */ + + static void + otv_JstfPriority_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + FT_UInt gsub_lookup_count, gpos_lookup_count; + + OTV_OPTIONAL_TABLE( ShrinkageEnableGSUB ); + OTV_OPTIONAL_TABLE( ShrinkageDisableGSUB ); + OTV_OPTIONAL_TABLE( ShrinkageEnableGPOS ); + OTV_OPTIONAL_TABLE( ShrinkageDisableGPOS ); + OTV_OPTIONAL_TABLE( ExtensionEnableGSUB ); + OTV_OPTIONAL_TABLE( ExtensionDisableGSUB ); + OTV_OPTIONAL_TABLE( ExtensionEnableGPOS ); + OTV_OPTIONAL_TABLE( ExtensionDisableGPOS ); + OTV_OPTIONAL_TABLE( ShrinkageJstfMax ); + OTV_OPTIONAL_TABLE( ExtensionJstfMax ); + + + OTV_ENTER; + OTV_TRACE(( "JstfPriority table\n" )); + + OTV_LIMIT_CHECK( 20 ); + + gsub_lookup_count = valid->extra1; + gpos_lookup_count = valid->extra2; + + table_size = 20; + + valid->extra1 = gsub_lookup_count; + + OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB ); + OTV_SIZE_CHECK( ShrinkageEnableGSUB ); + if ( ShrinkageEnableGSUB ) + otv_x_ux( table + ShrinkageEnableGSUB, valid ); + + OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB ); + OTV_SIZE_CHECK( ShrinkageDisableGSUB ); + if ( ShrinkageDisableGSUB ) + otv_x_ux( table + ShrinkageDisableGSUB, valid ); + + valid->extra1 = gpos_lookup_count; + + OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS ); + OTV_SIZE_CHECK( ShrinkageEnableGPOS ); + if ( ShrinkageEnableGPOS ) + otv_x_ux( table + ShrinkageEnableGPOS, valid ); + + OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS ); + OTV_SIZE_CHECK( ShrinkageDisableGPOS ); + if ( ShrinkageDisableGPOS ) + otv_x_ux( table + ShrinkageDisableGPOS, valid ); + + OTV_OPTIONAL_OFFSET( ShrinkageJstfMax ); + OTV_SIZE_CHECK( ShrinkageJstfMax ); + if ( ShrinkageJstfMax ) + { + /* XXX: check lookup types? */ + OTV_NEST2( JstfMax, JstfLookup ); + OTV_RUN( table + ShrinkageJstfMax, valid ); + } + + valid->extra1 = gsub_lookup_count; + + OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB ); + OTV_SIZE_CHECK( ExtensionEnableGSUB ); + if ( ExtensionEnableGSUB ) + otv_x_ux( table + ExtensionEnableGSUB, valid ); + + OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB ); + OTV_SIZE_CHECK( ExtensionDisableGSUB ); + if ( ExtensionDisableGSUB ) + otv_x_ux( table + ExtensionDisableGSUB, valid ); + + valid->extra1 = gpos_lookup_count; + + OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS ); + OTV_SIZE_CHECK( ExtensionEnableGPOS ); + if ( ExtensionEnableGPOS ) + otv_x_ux( table + ExtensionEnableGPOS, valid ); + + OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS ); + OTV_SIZE_CHECK( ExtensionDisableGPOS ); + if ( ExtensionDisableGPOS ) + otv_x_ux( table + ExtensionDisableGPOS, valid ); + + OTV_OPTIONAL_OFFSET( ExtensionJstfMax ); + OTV_SIZE_CHECK( ExtensionJstfMax ); + if ( ExtensionJstfMax ) + { + /* XXX: check lookup types? */ + OTV_NEST2( JstfMax, JstfLookup ); + OTV_RUN( table + ExtensionJstfMax, valid ); + } + + valid->extra1 = gsub_lookup_count; + valid->extra2 = gpos_lookup_count; + + OTV_EXIT; + } + + + /* sets valid->extra (glyph count) */ + /* sets valid->func1 (otv_JstfPriority_validate) */ + + static void + otv_JstfScript_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + FT_UInt JstfLangSysCount; + + OTV_OPTIONAL_TABLE( ExtGlyph ); + OTV_OPTIONAL_TABLE( DefJstfLangSys ); + + + OTV_NAME_ENTER( "JstfScript" ); + + OTV_LIMIT_CHECK( 6 ); + OTV_OPTIONAL_OFFSET( ExtGlyph ); + OTV_OPTIONAL_OFFSET( DefJstfLangSys ); + JstfLangSysCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (JstfLangSysCount = %d)\n", JstfLangSysCount )); + + table_size = JstfLangSysCount * 6 + 6; + + OTV_SIZE_CHECK( ExtGlyph ); + if ( ExtGlyph ) + { + valid->extra1 = valid->glyph_count; + OTV_NEST1( ExtenderGlyph ); + OTV_RUN( table + ExtGlyph, valid ); + } + + OTV_SIZE_CHECK( DefJstfLangSys ); + if ( DefJstfLangSys ) + { + OTV_NEST2( JstfLangSys, JstfPriority ); + OTV_RUN( table + DefJstfLangSys, valid ); + } + + OTV_LIMIT_CHECK( 6 * JstfLangSysCount ); + + /* JstfLangSysRecord */ + OTV_NEST2( JstfLangSys, JstfPriority ); + for ( ; JstfLangSysCount > 0; JstfLangSysCount-- ) + { + p += 4; /* skip JstfLangSysTag */ + + OTV_RUN( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + /* sets valid->extra1 (GSUB lookup count) */ + /* sets valid->extra2 (GPOS lookup count) */ + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_JSTF_validate( FT_Bytes table, + FT_Bytes gsub, + FT_Bytes gpos, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt JstfScriptCount; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating JSTF table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 6 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + JstfScriptCount = FT_NEXT_USHORT( p ); + + FT_TRACE3(( " (JstfScriptCount = %d)\n", JstfScriptCount )); + + OTV_LIMIT_CHECK( JstfScriptCount * 6 ); + + if ( gsub ) + valid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); + else + valid->extra1 = 0; + + if ( gpos ) + valid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); + else + valid->extra2 = 0; + + valid->glyph_count = glyph_count; + + /* JstfScriptRecord */ + for ( ; JstfScriptCount > 0; JstfScriptCount-- ) + { + p += 4; /* skip JstfScriptTag */ + + /* JstfScript */ + otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvmath.c b/drivers/freetype/src/otvalid/otvmath.c new file mode 100644 index 0000000000..96f841f2a9 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvmath.c @@ -0,0 +1,453 @@ +/***************************************************************************/ +/* */ +/* otvmath.c */ +/* */ +/* OpenType MATH table validation (body). */ +/* */ +/* Copyright 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by George Williams. */ +/* */ +/* 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 "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.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_otvmath + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TYPOGRAPHIC CONSTANTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathConstants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + OTV_NAME_ENTER( "MathConstants" ); + + /* 56 constants, 51 have device tables */ + OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) ); + table_size = 2 * ( 56 + 51 ); + + p += 4 * 2; /* First 4 constants have no device tables */ + for ( i = 0; i < 51; ++i ) + { + p += 2; /* skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH ITALICS CORRECTION *****/ + /***** MATH TOP ACCENT ATTACHMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int isItalic ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size ; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + FT_UNUSED( isItalic ); /* only used if tracing is active */ + + + OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo" + : "MathTopAccentAttachment" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt ); + table_size = 4 + 4 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH KERNING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathKern_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "MathKern" );*/ + + OTV_LIMIT_CHECK( 2 ); + + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt + 2 ); + table_size = 4 + 4 * cnt; + + /* Heights */ + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + /* One more Kerning value */ + for ( i = 0; i < cnt + 1; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + static void + otv_MathKernInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, j, cnt, table_size; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( MKRecordOffset ); + + + OTV_NAME_ENTER( "MathKernInfo" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * cnt ); + table_size = 4 + 8 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + for ( j = 0; j < 4; ++j ) + { + OTV_OPTIONAL_OFFSET( MKRecordOffset ); + OTV_SIZE_CHECK( MKRecordOffset ); + if ( MKRecordOffset ) + otv_MathKern_validate( table + MKRecordOffset, valid ); + } + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH INFO *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathGlyphInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; + FT_UInt ExtendedShapeCoverage, MathKernInfo; + + + OTV_NAME_ENTER( "MathGlyphInfo" ); + + OTV_LIMIT_CHECK( 8 ); + + MathItalicsCorrectionInfo = FT_NEXT_USHORT( p ); + MathTopAccentAttachment = FT_NEXT_USHORT( p ); + ExtendedShapeCoverage = FT_NEXT_USHORT( p ); + MathKernInfo = FT_NEXT_USHORT( p ); + + if ( MathItalicsCorrectionInfo ) + otv_MathItalicsCorrectionInfo_validate( + table + MathItalicsCorrectionInfo, valid, TRUE ); + + /* Italic correction and Top Accent Attachment have the same format */ + if ( MathTopAccentAttachment ) + otv_MathItalicsCorrectionInfo_validate( + table + MathTopAccentAttachment, valid, FALSE ); + + if ( ExtendedShapeCoverage ) + { + OTV_NAME_ENTER( "ExtendedShapeCoverage" ); + otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 ); + OTV_EXIT; + } + + if ( MathKernInfo ) + otv_MathKernInfo_validate( table + MathKernInfo, valid ); + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH CONSTRUCTION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_GlyphAssembly_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt pcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "GlyphAssembly" ); */ + + OTV_LIMIT_CHECK( 6 ); + + p += 2; /* Skip the Italics Correction value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + pcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * pcnt ); + table_size = 6 + 8 * pcnt; + + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + + for ( i = 0; i < pcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2*4; /* skip the Start, End, Full, and Flags fields */ + } + + /* OTV_EXIT; */ + } + + + static void + otv_MathGlyphConstruction_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( GlyphAssembly ); + + + /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */ + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( GlyphAssembly ); + vcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * vcnt ); + table_size = 4 + 4 * vcnt; + + for ( i = 0; i < vcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2; /* skip the size */ + } + + OTV_SIZE_CHECK( GlyphAssembly ); + if ( GlyphAssembly ) + otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); + + /* OTV_EXIT; */ + } + + + static void + otv_MathVariants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, hcnt, i, table_size; + + OTV_OPTIONAL_TABLE( VCoverage ); + OTV_OPTIONAL_TABLE( HCoverage ); + OTV_OPTIONAL_TABLE( Offset ); + + + OTV_NAME_ENTER( "MathVariants" ); + + OTV_LIMIT_CHECK( 10 ); + + p += 2; /* Skip the MinConnectorOverlap constant */ + OTV_OPTIONAL_OFFSET( VCoverage ); + OTV_OPTIONAL_OFFSET( HCoverage ); + vcnt = FT_NEXT_USHORT( p ); + hcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt ); + table_size = 10 + 2 * vcnt + 2 * hcnt; + + OTV_SIZE_CHECK( VCoverage ); + if ( VCoverage ) + otv_Coverage_validate( table + VCoverage, valid, vcnt ); + + OTV_SIZE_CHECK( HCoverage ); + if ( HCoverage ) + otv_Coverage_validate( table + HCoverage, valid, hcnt ); + + for ( i = 0; i < vcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + for ( i = 0; i < hcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt MathConstants, MathGlyphInfo, MathVariants; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating MATH table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + MathConstants = FT_NEXT_USHORT( p ); + MathGlyphInfo = FT_NEXT_USHORT( p ); + MathVariants = FT_NEXT_USHORT( p ); + + valid->glyph_count = glyph_count; + + otv_MathConstants_validate( table + MathConstants, + valid ); + otv_MathGlyphInfo_validate( table + MathGlyphInfo, + valid ); + otv_MathVariants_validate ( table + MathVariants, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvmod.c b/drivers/freetype/src/otvalid/otvmod.c new file mode 100644 index 0000000000..37c6e869dd --- /dev/null +++ b/drivers/freetype/src/otvalid/otvmod.c @@ -0,0 +1,282 @@ +/***************************************************************************/ +/* */ +/* otvmod.c */ +/* */ +/* FreeType's OpenType validation module implementation (body). */ +/* */ +/* Copyright 2004-2008, 2013 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_TRUETYPE_TABLES_H +#include FT_TRUETYPE_TAGS_H +#include FT_OPENTYPE_VALIDATE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_OPENTYPE_VALIDATE_H + +#include "otvmod.h" +#include "otvalid.h" +#include "otvcommn.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_otvmodule + + + static FT_Error + 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 ); + + + error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); + if ( FT_ERR_EQ( error, Table_Missing ) ) + return FT_Err_Ok; + if ( error ) + goto Exit; + + if ( FT_ALLOC( *table, *table_len ) ) + goto Exit; + + error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); + + Exit: + return error; + } + + + static FT_Error + 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 = FT_Err_Ok; + FT_Byte* volatile base; + FT_Byte* volatile gdef; + FT_Byte* volatile gpos; + FT_Byte* volatile gsub; + FT_Byte* volatile jstf; + FT_Byte* volatile math; + FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; + FT_ULong len_math; + FT_UInt num_glyphs = (FT_UInt)face->num_glyphs; + FT_ValidatorRec volatile valid; + + + base = gdef = gpos = gsub = jstf = math = NULL; + len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; + + /* + * XXX: OpenType tables cannot handle 32-bit glyph index, + * although broken TrueType can have 32-bit glyph index. + */ + if ( face->num_glyphs > 0xFFFFL ) + { + FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ", + face->num_glyphs )); + FT_TRACE1(( "are not handled by OpenType tables\n" )); + num_glyphs = 0xFFFF; + } + + /* load tables */ + + if ( ot_flags & FT_VALIDATE_BASE ) + { + error = otv_load_table( face, TTAG_BASE, &base, &len_base ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_GDEF ) + { + error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_GPOS ) + { + error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_GSUB ) + { + error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_JSTF ) + { + error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_MATH ) + { + error = otv_load_table( face, TTAG_MATH, &math, &len_math ); + if ( error ) + goto Exit; + } + + /* validate tables */ + + if ( base ) + { + ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_BASE_validate( base, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( gpos ) + { + ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_GPOS_validate( gpos, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( gsub ) + { + ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_GSUB_validate( gsub, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( gdef ) + { + ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( jstf ) + { + ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( math ) + { + ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_MATH_validate( math, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + *ot_base = (FT_Bytes)base; + *ot_gdef = (FT_Bytes)gdef; + *ot_gpos = (FT_Bytes)gpos; + *ot_gsub = (FT_Bytes)gsub; + *ot_jstf = (FT_Bytes)jstf; + + Exit: + if ( error ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( base ); + FT_FREE( gdef ); + FT_FREE( gpos ); + FT_FREE( gsub ); + FT_FREE( jstf ); + } + + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( math ); /* Can't return this as API is frozen */ + } + + return error; + } + + + static + const FT_Service_OTvalidateRec otvalid_interface = + { + otv_validate + }; + + + static + const FT_ServiceDescRec otvalid_services[] = + { + { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface }, + { NULL, NULL } + }; + + + static FT_Pointer + otvalid_get_service( FT_Module module, + const char* service_id ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( otvalid_services, service_id ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class otv_module_class = + { + 0, + sizeof ( FT_ModuleRec ), + "otvalid", + 0x10000L, + 0x20000L, + + 0, /* module-specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) otvalid_get_service + }; + + +/* END */ diff --git a/drivers/freetype/src/otvalid/otvmod.h b/drivers/freetype/src/otvalid/otvmod.h new file mode 100644 index 0000000000..f7e1550787 --- /dev/null +++ b/drivers/freetype/src/otvalid/otvmod.h @@ -0,0 +1,43 @@ +/***************************************************************************/ +/* */ +/* otvmod.h */ +/* */ +/* FreeType's OpenType validation module implementation */ +/* (specification). */ +/* */ +/* Copyright 2004 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 __OTVMOD_H__ +#define __OTVMOD_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Module_Class ) otv_module_class; + + +FT_END_HEADER + +#endif /* __OTVMOD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/otvalid/rules.mk b/drivers/freetype/src/otvalid/rules.mk new file mode 100644 index 0000000000..53bd41e5e7 --- /dev/null +++ b/drivers/freetype/src/otvalid/rules.mk @@ -0,0 +1,78 @@ +# +# FreeType 2 OpenType validation driver configuration rules +# + + +# Copyright 2004, 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. + + +# OTV driver directory +# +OTV_DIR := $(SRC_DIR)/otvalid + + +# compilation flags for the driver +# +OTV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(OTV_DIR)) + + +# OTV driver sources (i.e., C files) +# +OTV_DRV_SRC := $(OTV_DIR)/otvbase.c \ + $(OTV_DIR)/otvcommn.c \ + $(OTV_DIR)/otvgdef.c \ + $(OTV_DIR)/otvgpos.c \ + $(OTV_DIR)/otvgsub.c \ + $(OTV_DIR)/otvjstf.c \ + $(OTV_DIR)/otvmath.c \ + $(OTV_DIR)/otvmod.c + +# OTV driver headers +# +OTV_DRV_H := $(OTV_DIR)/otvalid.h \ + $(OTV_DIR)/otvcommn.h \ + $(OTV_DIR)/otverror.h \ + $(OTV_DIR)/otvgpos.h \ + $(OTV_DIR)/otvmod.h + + +# OTV driver object(s) +# +# OTV_DRV_OBJ_M is used during `multi' builds. +# OTV_DRV_OBJ_S is used during `single' builds. +# +OTV_DRV_OBJ_M := $(OTV_DRV_SRC:$(OTV_DIR)/%.c=$(OBJ_DIR)/%.$O) +OTV_DRV_OBJ_S := $(OBJ_DIR)/otvalid.$O + +# OTV driver source file for single build +# +OTV_DRV_SRC_S := $(OTV_DIR)/otvalid.c + + +# OTV driver - single object +# +$(OTV_DRV_OBJ_S): $(OTV_DRV_SRC_S) $(OTV_DRV_SRC) \ + $(FREETYPE_H) $(OTV_DRV_H) + $(OTV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(OTV_DRV_SRC_S)) + + +# OTV driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(OTV_DIR)/%.c $(FREETYPE_H) $(OTV_DRV_H) + $(OTV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(OTV_DRV_OBJ_S) +DRV_OBJS_M += $(OTV_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/pcf/Jamfile b/drivers/freetype/src/pcf/Jamfile new file mode 100644 index 0000000000..752fcac2a1 --- /dev/null +++ b/drivers/freetype/src/pcf/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/pcf Jamfile +# +# Copyright 2001, 2003 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) pcf ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = pcfdrivr pcfread pcfutil ; + } + else + { + _sources = pcf ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/pcf Jamfile diff --git a/drivers/freetype/src/pcf/README b/drivers/freetype/src/pcf/README new file mode 100644 index 0000000000..10eff15fbe --- /dev/null +++ b/drivers/freetype/src/pcf/README @@ -0,0 +1,96 @@ + FreeType font driver for PCF fonts + + Francesco Zappa Nardelli + <francesco.zappa.nardelli@ens.fr> + + +Introduction +************ + +PCF (Portable Compiled Format) is a binary bitmap font format, largely used +in X world. This code implements a PCF driver for the FreeType library. +Glyph images are loaded into memory only on demand, thus leading to a small +memory footprint. + +Information on the PCF font format can only be worked out from +`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. + + +Supported hardware +****************** + +The driver has been tested on linux/x86 and sunos5.5/sparc. In both +cases the compiler was gcc. When back in Paris, I will test it also +on linux/alpha. + + +Encodings +********* + +Use `FT_Get_BDF_Charset_ID' to access the encoding and registry. + +The driver always exports `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. + + +Known problems +************** + +- dealing explicitly with encodings breaks the uniformity of freetype2 + api. + +- except for encodings properties, client applications have no + visibility of the PCF_Face object. This means that applications + cannot directly access font tables and are obliged to trust + FreeType. + +- currently, glyph names and ink_metrics are ignored. + +I plan to give full visibility of the PCF_Face object in the next +release of the driver, thus implementing also glyph names and +ink_metrics. + +- height is defined as (ascent - descent). Is this correct? + +- if unable to read size information from the font, PCF_Init_Face + sets available_size->width and available_size->height to 12. + +- too many english grammar errors in the readme file :-( + + +License +******* + +Copyright (C) 2000 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 to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Credits +******* + +Keith Packard wrote the pcf driver found in XFree86. His work is at +the same time the specification and the sample implementation of the +PCF format. Undoubtedly, this driver is inspired from his work. diff --git a/drivers/freetype/src/pcf/module.mk b/drivers/freetype/src/pcf/module.mk new file mode 100644 index 0000000000..df383ff0fb --- /dev/null +++ b/drivers/freetype/src/pcf/module.mk @@ -0,0 +1,34 @@ +# +# FreeType 2 PCF module definition +# + +# 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 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +FTMODULE_H_COMMANDS += PCF_DRIVER + +define PCF_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, pcf_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)pcf $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/pcf/pcf.c b/drivers/freetype/src/pcf/pcf.c new file mode 100644 index 0000000000..11d5b7b2a0 --- /dev/null +++ b/drivers/freetype/src/pcf/pcf.c @@ -0,0 +1,36 @@ +/* pcf.c + + FreeType font driver for pcf fonts + + Copyright 2000-2001, 2003 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + + +#include <ft2build.h> +#include "pcfutil.c" +#include "pcfread.c" +#include "pcfdrivr.c" + +/* END */ diff --git a/drivers/freetype/src/pcf/pcf.h b/drivers/freetype/src/pcf/pcf.h new file mode 100644 index 0000000000..af0ffc3378 --- /dev/null +++ b/drivers/freetype/src/pcf/pcf.h @@ -0,0 +1,237 @@ +/* pcf.h + + FreeType font driver for pcf fonts + + Copyright (C) 2000, 2001, 2002, 2003, 2006, 2010 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCF_H__ +#define __PCF_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + typedef struct PCF_TableRec_ + { + FT_ULong type; + FT_ULong format; + FT_ULong size; + FT_ULong offset; + + } PCF_TableRec, *PCF_Table; + + + typedef struct PCF_TocRec_ + { + FT_ULong version; + FT_ULong count; + PCF_Table tables; + + } PCF_TocRec, *PCF_Toc; + + + typedef struct PCF_ParsePropertyRec_ + { + FT_Long name; + FT_Byte isString; + FT_Long value; + + } PCF_ParsePropertyRec, *PCF_ParseProperty; + + + typedef struct PCF_PropertyRec_ + { + FT_String* name; + FT_Byte isString; + + union + { + FT_String* atom; + FT_Long l; + FT_ULong ul; + + } value; + + } PCF_PropertyRec, *PCF_Property; + + + typedef struct PCF_Compressed_MetricRec_ + { + FT_Byte leftSideBearing; + FT_Byte rightSideBearing; + FT_Byte characterWidth; + FT_Byte ascent; + FT_Byte descent; + + } PCF_Compressed_MetricRec, *PCF_Compressed_Metric; + + + typedef struct PCF_MetricRec_ + { + FT_Short leftSideBearing; + FT_Short rightSideBearing; + FT_Short characterWidth; + FT_Short ascent; + FT_Short descent; + FT_Short attributes; + FT_ULong bits; + + } PCF_MetricRec, *PCF_Metric; + + + typedef struct PCF_AccelRec_ + { + FT_Byte noOverlap; + FT_Byte constantMetrics; + FT_Byte terminalFont; + FT_Byte constantWidth; + FT_Byte inkInside; + FT_Byte inkMetrics; + FT_Byte drawDirection; + FT_Long fontAscent; + FT_Long fontDescent; + FT_Long maxOverlap; + PCF_MetricRec minbounds; + PCF_MetricRec maxbounds; + PCF_MetricRec ink_minbounds; + PCF_MetricRec ink_maxbounds; + + } PCF_AccelRec, *PCF_Accel; + + + typedef struct PCF_EncodingRec_ + { + FT_Long enc; + FT_UShort glyph; + + } PCF_EncodingRec, *PCF_Encoding; + + + typedef struct PCF_FaceRec_ + { + FT_FaceRec root; + + FT_StreamRec comp_stream; + FT_Stream comp_source; + + char* charset_encoding; + char* charset_registry; + + PCF_TocRec toc; + PCF_AccelRec accel; + + int nprops; + PCF_Property properties; + + FT_Long nmetrics; + PCF_Metric metrics; + FT_Long nencodings; + PCF_Encoding encodings; + + FT_Short defaultChar; + + FT_ULong bitmapsFormat; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + } PCF_FaceRec, *PCF_Face; + + + /* macros for pcf font format */ + +#define LSBFirst 0 +#define MSBFirst 1 + +#define PCF_FILE_VERSION ( ( 'p' << 24 ) | \ + ( 'c' << 16 ) | \ + ( 'f' << 8 ) | 1 ) +#define PCF_FORMAT_MASK 0xFFFFFF00UL + +#define PCF_DEFAULT_FORMAT 0x00000000UL +#define PCF_INKBOUNDS 0x00000200UL +#define PCF_ACCEL_W_INKBOUNDS 0x00000100UL +#define PCF_COMPRESSED_METRICS 0x00000100UL + +#define PCF_FORMAT_MATCH( a, b ) \ + ( ( (a) & PCF_FORMAT_MASK ) == ( (b) & PCF_FORMAT_MASK ) ) + +#define PCF_GLYPH_PAD_MASK ( 3 << 0 ) +#define PCF_BYTE_MASK ( 1 << 2 ) +#define PCF_BIT_MASK ( 1 << 3 ) +#define PCF_SCAN_UNIT_MASK ( 3 << 4 ) + +#define PCF_BYTE_ORDER( f ) \ + ( ( (f) & PCF_BYTE_MASK ) ? MSBFirst : LSBFirst ) +#define PCF_BIT_ORDER( f ) \ + ( ( (f) & PCF_BIT_MASK ) ? MSBFirst : LSBFirst ) +#define PCF_GLYPH_PAD_INDEX( f ) \ + ( (f) & PCF_GLYPH_PAD_MASK ) +#define PCF_GLYPH_PAD( f ) \ + ( 1 << PCF_GLYPH_PAD_INDEX( f ) ) +#define PCF_SCAN_UNIT_INDEX( f ) \ + ( ( (f) & PCF_SCAN_UNIT_MASK ) >> 4 ) +#define PCF_SCAN_UNIT( f ) \ + ( 1 << PCF_SCAN_UNIT_INDEX( f ) ) +#define PCF_FORMAT_BITS( f ) \ + ( (f) & ( PCF_GLYPH_PAD_MASK | \ + PCF_BYTE_MASK | \ + PCF_BIT_MASK | \ + PCF_SCAN_UNIT_MASK ) ) + +#define PCF_SIZE_TO_INDEX( s ) ( (s) == 4 ? 2 : (s) == 2 ? 1 : 0 ) +#define PCF_INDEX_TO_SIZE( b ) ( 1 << b ) + +#define PCF_FORMAT( bit, byte, glyph, scan ) \ + ( ( PCF_SIZE_TO_INDEX( scan ) << 4 ) | \ + ( ( (bit) == MSBFirst ? 1 : 0 ) << 3 ) | \ + ( ( (byte) == MSBFirst ? 1 : 0 ) << 2 ) | \ + ( PCF_SIZE_TO_INDEX( glyph ) << 0 ) ) + +#define PCF_PROPERTIES ( 1 << 0 ) +#define PCF_ACCELERATORS ( 1 << 1 ) +#define PCF_METRICS ( 1 << 2 ) +#define PCF_BITMAPS ( 1 << 3 ) +#define PCF_INK_METRICS ( 1 << 4 ) +#define PCF_BDF_ENCODINGS ( 1 << 5 ) +#define PCF_SWIDTHS ( 1 << 6 ) +#define PCF_GLYPH_NAMES ( 1 << 7 ) +#define PCF_BDF_ACCELERATORS ( 1 << 8 ) + +#define GLYPHPADOPTIONS 4 /* I'm not sure about this */ + + FT_LOCAL( FT_Error ) + pcf_load_font( FT_Stream, + PCF_Face ); + +FT_END_HEADER + +#endif /* __PCF_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pcf/pcfdrivr.c b/drivers/freetype/src/pcf/pcfdrivr.c new file mode 100644 index 0000000000..df25a645a0 --- /dev/null +++ b/drivers/freetype/src/pcf/pcfdrivr.c @@ -0,0 +1,713 @@ +/* pcfdrivr.c + + FreeType font driver for pcf files + + Copyright (C) 2000-2004, 2006-2011, 2013 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_GZIP_H +#include FT_LZW_H +#include FT_BZIP2_H +#include FT_ERRORS_H +#include FT_BDF_H +#include FT_TRUETYPE_IDS_H + +#include "pcf.h" +#include "pcfdrivr.h" +#include "pcfread.h" + +#include "pcferror.h" +#include "pcfutil.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pcfread + +#include FT_SERVICE_BDF_H +#include FT_SERVICE_XFREE86_NAME_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_pcfdriver + + + typedef struct PCF_CMapRec_ + { + FT_CMapRec root; + FT_UInt num_encodings; + PCF_Encoding encodings; + + } PCF_CMapRec, *PCF_CMap; + + + FT_CALLBACK_DEF( FT_Error ) + pcf_cmap_init( FT_CMap pcfcmap, /* PCF_CMap */ + FT_Pointer init_data ) + { + PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap ); + + FT_UNUSED( init_data ); + + + cmap->num_encodings = (FT_UInt)face->nencodings; + cmap->encodings = face->encodings; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + pcf_cmap_done( FT_CMap pcfcmap ) /* PCF_CMap */ + { + PCF_CMap cmap = (PCF_CMap)pcfcmap; + + + cmap->encodings = NULL; + cmap->num_encodings = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */ + FT_UInt32 charcode ) + { + PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_Encoding encodings = cmap->encodings; + FT_UInt min, max, mid; + FT_UInt result = 0; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_ULong code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + result = encodings[mid].glyph + 1; + break; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */ + FT_UInt32 *acharcode ) + { + PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_Encoding encodings = cmap->encodings; + FT_UInt min, max, mid; + FT_ULong charcode = *acharcode + 1; + FT_UInt result = 0; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_ULong code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + result = encodings[mid].glyph + 1; + goto Exit; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + charcode = 0; + if ( min < cmap->num_encodings ) + { + charcode = encodings[min].enc; + result = encodings[min].glyph + 1; + } + + Exit: + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" )); + *acharcode = 0; + /* XXX: result should be changed to indicate an overflow error */ + } + else + *acharcode = (FT_UInt32)charcode; + return result; + } + + + FT_CALLBACK_TABLE_DEF + const FT_CMap_ClassRec pcf_cmap_class = + { + sizeof ( PCF_CMapRec ), + pcf_cmap_init, + pcf_cmap_done, + pcf_cmap_char_index, + pcf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + FT_CALLBACK_DEF( void ) + PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */ + { + PCF_Face face = (PCF_Face)pcfface; + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + FT_FREE( face->encodings ); + FT_FREE( face->metrics ); + + /* free properties */ + { + PCF_Property prop; + FT_Int i; + + + if ( face->properties ) + { + for ( i = 0; i < face->nprops; i++ ) + { + prop = &face->properties[i]; + + if ( prop ) + { + FT_FREE( prop->name ); + if ( prop->isString ) + FT_FREE( prop->value.atom ); + } + } + } + FT_FREE( face->properties ); + } + + FT_FREE( face->toc.tables ); + FT_FREE( pcfface->family_name ); + FT_FREE( pcfface->style_name ); + FT_FREE( pcfface->available_sizes ); + FT_FREE( face->charset_encoding ); + FT_FREE( face->charset_registry ); + + /* close compressed stream if any */ + if ( pcfface->stream == &face->comp_stream ) + { + FT_Stream_Close( &face->comp_stream ); + pcfface->stream = face->comp_source; + } + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Face_Init( FT_Stream stream, + FT_Face pcfface, /* PCF_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + PCF_Face face = (PCF_Face)pcfface; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + + + FT_TRACE2(( "PCF driver\n" )); + + error = pcf_load_font( stream, face ); + if ( error ) + { + PCF_Face_Done( pcfface ); + +#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ + defined( FT_CONFIG_OPTION_USE_LZW ) || \ + defined( FT_CONFIG_OPTION_USE_BZIP2 ) + +#ifdef FT_CONFIG_OPTION_USE_ZLIB + { + FT_Error error2; + + + /* this didn't work, try gzip support! */ + error2 = FT_Stream_OpenGzip( &face->comp_stream, stream ); + if ( FT_ERR_EQ( error2, Unimplemented_Feature ) ) + goto Fail; + + error = error2; + } +#endif /* FT_CONFIG_OPTION_USE_ZLIB */ + +#ifdef FT_CONFIG_OPTION_USE_LZW + if ( error ) + { + FT_Error error3; + + + /* this didn't work, try LZW support! */ + error3 = FT_Stream_OpenLZW( &face->comp_stream, stream ); + if ( FT_ERR_EQ( error3, Unimplemented_Feature ) ) + goto Fail; + + error = error3; + } +#endif /* FT_CONFIG_OPTION_USE_LZW */ + +#ifdef FT_CONFIG_OPTION_USE_BZIP2 + if ( error ) + { + FT_Error error4; + + + /* this didn't work, try Bzip2 support! */ + error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream ); + if ( FT_ERR_EQ( error4, Unimplemented_Feature ) ) + goto Fail; + + error = error4; + } +#endif /* FT_CONFIG_OPTION_USE_BZIP2 */ + + if ( error ) + goto Fail; + + face->comp_source = stream; + pcfface->stream = &face->comp_stream; + + stream = pcfface->stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + +#else /* !(FT_CONFIG_OPTION_USE_ZLIB || + FT_CONFIG_OPTION_USE_LZW || + FT_CONFIG_OPTION_USE_BZIP2) */ + + goto Fail; + +#endif + } + + /* set up charmap */ + { + FT_String *charset_registry = face->charset_registry; + FT_String *charset_encoding = face->charset_encoding; + FT_Bool unicode_charmap = 0; + + + if ( charset_registry && charset_encoding ) + { + char* s = charset_registry; + + + /* Uh, oh, compare first letters manually to avoid dependency + on locales. */ + if ( ( s[0] == 'i' || s[0] == 'I' ) && + ( s[1] == 's' || s[1] == 'S' ) && + ( s[2] == 'o' || s[2] == 'O' ) ) + { + s += 3; + if ( !ft_strcmp( s, "10646" ) || + ( !ft_strcmp( s, "8859" ) && + !ft_strcmp( face->charset_encoding, "1" ) ) ) + unicode_charmap = 1; + } + } + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; + /* initial platform/encoding should indicate unset status? */ + charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; + charmap.encoding_id = TT_APPLE_ID_DEFAULT; + + if ( unicode_charmap ) + { + charmap.encoding = FT_ENCODING_UNICODE; + charmap.platform_id = TT_PLATFORM_MICROSOFT; + charmap.encoding_id = TT_MS_ID_UNICODE_CS; + } + + error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if ( pcfface->num_charmaps ) + pcfface->charmap = pcfface->charmaps[0]; +#endif + } + } + + Exit: + return error; + + Fail: + FT_TRACE2(( " not a PCF file\n" )); + PCF_Face_Done( pcfface ); + error = FT_THROW( Unknown_File_Format ); /* error */ + goto Exit; + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Size_Select( FT_Size size, + FT_ULong strike_index ) + { + PCF_Accel accel = &( (PCF_Face)size->face )->accel; + + + FT_Select_Metrics( size->face, strike_index ); + + size->metrics.ascender = accel->fontAscent << 6; + size->metrics.descender = -accel->fontDescent << 6; + size->metrics.max_advance = accel->maxbounds.characterWidth << 6; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Size_Request( FT_Size size, + FT_Size_Request req ) + { + PCF_Face face = (PCF_Face)size->face; + FT_Bitmap_Size* bsize = size->face->available_sizes; + FT_Error error = FT_ERR( Invalid_Pixel_Size ); + FT_Long height; + + + height = FT_REQUEST_HEIGHT( req ); + height = ( height + 32 ) >> 6; + + switch ( req->type ) + { + case FT_SIZE_REQUEST_TYPE_NOMINAL: + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) + error = FT_Err_Ok; + break; + + case FT_SIZE_REQUEST_TYPE_REAL_DIM: + if ( height == ( face->accel.fontAscent + + face->accel.fontDescent ) ) + error = FT_Err_Ok; + break; + + default: + error = FT_THROW( Unimplemented_Feature ); + break; + } + + if ( error ) + return error; + else + return PCF_Size_Select( size, 0 ); + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Glyph_Load( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); + FT_Stream stream; + FT_Error error = FT_Err_Ok; + FT_Bitmap* bitmap = &slot->bitmap; + PCF_Metric metric; + FT_Offset bytes; + + FT_UNUSED( load_flags ); + + + FT_TRACE4(( "load_glyph %d ---", glyph_index )); + + if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + stream = face->root.stream; + + if ( glyph_index > 0 ) + glyph_index--; + + metric = face->metrics + glyph_index; + + bitmap->rows = metric->ascent + metric->descent; + bitmap->width = metric->rightSideBearing - metric->leftSideBearing; + bitmap->num_grays = 1; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n", + PCF_BIT_ORDER( face->bitmapsFormat ), + PCF_BYTE_ORDER( face->bitmapsFormat ), + PCF_GLYPH_PAD( face->bitmapsFormat ) )); + + switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) + { + case 1: + bitmap->pitch = ( bitmap->width + 7 ) >> 3; + break; + + case 2: + bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; + break; + + case 4: + bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; + break; + + case 8: + bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; + break; + + default: + return FT_THROW( Invalid_File_Format ); + } + + /* XXX: to do: are there cases that need repadding the bitmap? */ + bytes = bitmap->pitch * bitmap->rows; + + error = ft_glyphslot_alloc_bitmap( slot, (FT_ULong)bytes ); + if ( error ) + goto Exit; + + if ( FT_STREAM_SEEK( metric->bits ) || + FT_STREAM_READ( bitmap->buffer, bytes ) ) + goto Exit; + + if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst ) + BitOrderInvert( bitmap->buffer, bytes ); + + if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) != + PCF_BIT_ORDER( face->bitmapsFormat ) ) ) + { + switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) ) + { + case 1: + break; + + case 2: + TwoByteSwap( bitmap->buffer, bytes ); + break; + + case 4: + FourByteSwap( bitmap->buffer, bytes ); + break; + } + } + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = metric->leftSideBearing; + slot->bitmap_top = metric->ascent; + + slot->metrics.horiAdvance = metric->characterWidth << 6; + slot->metrics.horiBearingX = metric->leftSideBearing << 6; + slot->metrics.horiBearingY = metric->ascent << 6; + slot->metrics.width = ( metric->rightSideBearing - + metric->leftSideBearing ) << 6; + slot->metrics.height = bitmap->rows << 6; + + ft_synthesize_vertical_metrics( &slot->metrics, + ( face->accel.fontAscent + + face->accel.fontDescent ) << 6 ); + + FT_TRACE4(( " --- ok\n" )); + + Exit: + return error; + } + + + /* + * + * BDF SERVICE + * + */ + + static FT_Error + pcf_get_bdf_property( PCF_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + PCF_Property prop; + + + prop = pcf_find_property( face, prop_name ); + if ( prop != NULL ) + { + if ( prop->isString ) + { + aproperty->type = BDF_PROPERTY_TYPE_ATOM; + aproperty->u.atom = prop->value.atom; + } + else + { + if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + { + FT_TRACE1(( "pcf_get_bdf_property: " )); + FT_TRACE1(( "too large integer 0x%x is truncated\n" )); + } + /* Apparently, the PCF driver loads all properties as signed integers! + * This really doesn't seem to be a problem, because this is + * sufficient for any meaningful values. + */ + aproperty->type = BDF_PROPERTY_TYPE_INTEGER; + aproperty->u.integer = (FT_Int32)prop->value.l; + } + return 0; + } + + return FT_THROW( Invalid_Argument ); + } + + + static FT_Error + pcf_get_charset_id( PCF_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + *acharset_encoding = face->charset_encoding; + *acharset_registry = face->charset_registry; + + return 0; + } + + + static const FT_Service_BDFRec pcf_service_bdf = + { + (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, + (FT_BDF_GetPropertyFunc) pcf_get_bdf_property + }; + + + /* + * + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec pcf_services[] = + { + { FT_SERVICE_ID_BDF, &pcf_service_bdf }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + pcf_driver_requester( FT_Module module, + const char* name ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( pcf_services, name ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec pcf_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, + sizeof ( FT_DriverRec ), + + "pcf", + 0x10000L, + 0x20000L, + + 0, + + 0, /* FT_Module_Constructor */ + 0, /* FT_Module_Destructor */ + pcf_driver_requester + }, + + sizeof ( PCF_FaceRec ), + sizeof ( FT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + PCF_Face_Init, + PCF_Face_Done, + 0, /* FT_Size_InitFunc */ + 0, /* FT_Size_DoneFunc */ + 0, /* FT_Slot_InitFunc */ + 0, /* FT_Slot_DoneFunc */ + + PCF_Glyph_Load, + + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetAdvancesFunc */ + + PCF_Size_Request, + PCF_Size_Select + }; + + +/* END */ diff --git a/drivers/freetype/src/pcf/pcfdrivr.h b/drivers/freetype/src/pcf/pcfdrivr.h new file mode 100644 index 0000000000..54614951b5 --- /dev/null +++ b/drivers/freetype/src/pcf/pcfdrivr.h @@ -0,0 +1,48 @@ +/* pcfdrivr.h + + FreeType font driver for pcf fonts + + Copyright 2000-2001, 2002 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCFDRIVR_H__ +#define __PCFDRIVR_H__ + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pcf_driver_class; + +FT_END_HEADER + + +#endif /* __PCFDRIVR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pcf/pcferror.h b/drivers/freetype/src/pcf/pcferror.h new file mode 100644 index 0000000000..e51fff8ea6 --- /dev/null +++ b/drivers/freetype/src/pcf/pcferror.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* pcferror.h */ +/* */ +/* PCF error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PCF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PCFERROR_H__ +#define __PCFERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX PCF_Err_ +#define FT_ERR_BASE FT_Mod_Err_PCF + +#include FT_ERRORS_H + +#endif /* __PCFERROR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pcf/pcfread.c b/drivers/freetype/src/pcf/pcfread.c new file mode 100644 index 0000000000..3c1bb7dfa2 --- /dev/null +++ b/drivers/freetype/src/pcf/pcfread.c @@ -0,0 +1,1269 @@ +/* pcfread.c + + FreeType font driver for pcf fonts + + Copyright 2000-2010, 2012, 2013 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H + +#include "pcf.h" +#include "pcfread.h" + +#include "pcferror.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_pcfread + + +#ifdef FT_DEBUG_LEVEL_TRACE + static const char* const tableNames[] = + { + "prop", "accl", "mtrcs", "bmps", "imtrcs", + "enc", "swidth", "names", "accel" + }; +#endif + + + static + const FT_Frame_Field pcf_toc_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_TocRec + + FT_FRAME_START( 8 ), + FT_FRAME_ULONG_LE( version ), + FT_FRAME_ULONG_LE( count ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_table_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_TableRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG_LE( type ), + FT_FRAME_ULONG_LE( format ), + FT_FRAME_ULONG_LE( size ), + FT_FRAME_ULONG_LE( offset ), + FT_FRAME_END + }; + + + static FT_Error + pcf_read_TOC( FT_Stream stream, + PCF_Face face ) + { + FT_Error error; + PCF_Toc toc = &face->toc; + PCF_Table tables; + + FT_Memory memory = FT_FACE( face )->memory; + FT_UInt n; + + + if ( FT_STREAM_SEEK ( 0 ) || + FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) + return FT_THROW( Cannot_Open_Resource ); + + if ( toc->version != PCF_FILE_VERSION || + toc->count > FT_ARRAY_MAX( face->toc.tables ) || + toc->count == 0 ) + return FT_THROW( Invalid_File_Format ); + + if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) + return FT_THROW( Out_Of_Memory ); + + tables = face->toc.tables; + for ( n = 0; n < toc->count; n++ ) + { + if ( FT_STREAM_READ_FIELDS( pcf_table_header, tables ) ) + goto Exit; + 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 FT_THROW( Invalid_Offset ); + } + + if ( !have_change ) + break; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + + { + FT_UInt i, j; + const char* name = "?"; + + + FT_TRACE4(( "pcf_read_TOC:\n" )); + + FT_TRACE4(( " number of tables: %ld\n", face->toc.count )); + + tables = face->toc.tables; + for ( i = 0; i < toc->count; i++ ) + { + for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); + j++ ) + if ( tables[i].type == (FT_UInt)( 1 << j ) ) + name = tableNames[j]; + + FT_TRACE4(( " %d: type=%s, format=0x%X, " + "size=%ld (0x%lX), offset=%ld (0x%lX)\n", + i, name, + tables[i].format, + tables[i].size, tables[i].size, + tables[i].offset, tables[i].offset )); + } + } + +#endif + + return FT_Err_Ok; + + Exit: + FT_FREE( face->toc.tables ); + return error; + } + + +#define PCF_METRIC_SIZE 12 + + static + const FT_Frame_Field pcf_metric_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_MetricRec + + FT_FRAME_START( PCF_METRIC_SIZE ), + FT_FRAME_SHORT_LE( leftSideBearing ), + FT_FRAME_SHORT_LE( rightSideBearing ), + FT_FRAME_SHORT_LE( characterWidth ), + FT_FRAME_SHORT_LE( ascent ), + FT_FRAME_SHORT_LE( descent ), + FT_FRAME_SHORT_LE( attributes ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_metric_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_MetricRec + + FT_FRAME_START( PCF_METRIC_SIZE ), + FT_FRAME_SHORT( leftSideBearing ), + FT_FRAME_SHORT( rightSideBearing ), + FT_FRAME_SHORT( characterWidth ), + FT_FRAME_SHORT( ascent ), + FT_FRAME_SHORT( descent ), + FT_FRAME_SHORT( attributes ), + FT_FRAME_END + }; + + +#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( PCF_COMPRESSED_METRIC_SIZE ), + FT_FRAME_BYTE( leftSideBearing ), + FT_FRAME_BYTE( rightSideBearing ), + FT_FRAME_BYTE( characterWidth ), + FT_FRAME_BYTE( ascent ), + FT_FRAME_BYTE( descent ), + FT_FRAME_END + }; + + + static FT_Error + pcf_get_metric( FT_Stream stream, + FT_ULong format, + PCF_Metric metric ) + { + FT_Error error = FT_Err_Ok; + + + if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + { + const FT_Frame_Field* fields; + + + /* parsing normal metrics */ + fields = PCF_BYTE_ORDER( format ) == MSBFirst + ? pcf_metric_msb_header + : pcf_metric_header; + + /* the following sets `error' but doesn't return in case of failure */ + (void)FT_STREAM_READ_FIELDS( fields, metric ); + } + else + { + PCF_Compressed_MetricRec compr; + + + /* parsing compressed metrics */ + if ( FT_STREAM_READ_FIELDS( pcf_compressed_metric_header, &compr ) ) + goto Exit; + + metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 ); + metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 ); + metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 ); + metric->ascent = (FT_Short)( compr.ascent - 0x80 ); + metric->descent = (FT_Short)( compr.descent - 0x80 ); + metric->attributes = 0; + } + + Exit: + return error; + } + + + static FT_Error + pcf_seek_to_table_type( FT_Stream stream, + PCF_Table tables, + FT_ULong ntables, /* same as PCF_Toc->count */ + FT_ULong type, + FT_ULong *aformat, + FT_ULong *asize ) + { + FT_Error error = FT_ERR( Invalid_File_Format ); + FT_ULong i; + + + for ( i = 0; i < ntables; i++ ) + if ( tables[i].type == type ) + { + if ( stream->pos > tables[i].offset ) + { + error = FT_THROW( Invalid_Stream_Skip ); + goto Fail; + } + + if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) + { + error = FT_THROW( Invalid_Stream_Skip ); + goto Fail; + } + + *asize = tables[i].size; + *aformat = tables[i].format; + + return FT_Err_Ok; + } + + Fail: + *asize = 0; + return error; + } + + + static FT_Bool + pcf_has_table_type( PCF_Table tables, + FT_ULong ntables, /* same as PCF_Toc->count */ + FT_ULong type ) + { + FT_ULong i; + + + for ( i = 0; i < ntables; i++ ) + if ( tables[i].type == type ) + return TRUE; + + return FALSE; + } + + +#define PCF_PROPERTY_SIZE 9 + + static + const FT_Frame_Field pcf_property_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_ParsePropertyRec + + FT_FRAME_START( PCF_PROPERTY_SIZE ), + FT_FRAME_LONG_LE( name ), + FT_FRAME_BYTE ( isString ), + FT_FRAME_LONG_LE( value ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_property_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_ParsePropertyRec + + FT_FRAME_START( PCF_PROPERTY_SIZE ), + FT_FRAME_LONG( name ), + FT_FRAME_BYTE( isString ), + FT_FRAME_LONG( value ), + FT_FRAME_END + }; + + + FT_LOCAL_DEF( PCF_Property ) + pcf_find_property( PCF_Face face, + const FT_String* prop ) + { + PCF_Property properties = face->properties; + FT_Bool found = 0; + int i; + + + for ( i = 0 ; i < face->nprops && !found; i++ ) + { + if ( !ft_strcmp( properties[i].name, prop ) ) + found = 1; + } + + if ( found ) + return properties + i - 1; + else + return NULL; + } + + + static FT_Error + pcf_get_properties( FT_Stream stream, + PCF_Face face ) + { + PCF_ParseProperty props = 0; + PCF_Property properties = NULL; + FT_ULong nprops, i; + FT_ULong format, size; + FT_Error error; + FT_Memory memory = FT_FACE( face )->memory; + FT_ULong string_size; + FT_String* strings = 0; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_PROPERTIES, + &format, + &size ); + if ( error ) + goto Bail; + + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; + + FT_TRACE4(( "pcf_get_properties:\n" )); + + FT_TRACE4(( " format = %ld\n", format )); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + goto Bail; + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( nprops ); + else + (void)FT_READ_ULONG_LE( nprops ); + if ( error ) + goto Bail; + + FT_TRACE4(( " nprop = %d (truncate %d props)\n", + (int)nprops, nprops - (int)nprops )); + + nprops = (int)nprops; + + /* rough estimate */ + if ( nprops > size / PCF_PROPERTY_SIZE ) + { + error = FT_THROW( Invalid_Table ); + goto Bail; + } + + face->nprops = (int)nprops; + + if ( FT_NEW_ARRAY( props, nprops ) ) + goto Bail; + + for ( i = 0; i < nprops; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + if ( FT_STREAM_READ_FIELDS( pcf_property_msb_header, props + i ) ) + goto Bail; + } + else + { + if ( FT_STREAM_READ_FIELDS( pcf_property_header, props + i ) ) + goto Bail; + } + } + + /* pad the property array */ + /* */ + /* clever here - nprops is the same as the number of odd-units read, */ + /* as only isStringProp are odd length (Keith Packard) */ + /* */ + if ( nprops & 3 ) + { + i = 4 - ( nprops & 3 ); + if ( FT_STREAM_SKIP( i ) ) + { + error = FT_THROW( Invalid_Stream_Skip ); + goto Bail; + } + } + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( string_size ); + else + (void)FT_READ_ULONG_LE( string_size ); + if ( error ) + goto Bail; + + FT_TRACE4(( " string_size = %ld\n", string_size )); + + /* rough estimate */ + if ( string_size > size - nprops * PCF_PROPERTY_SIZE ) + { + error = FT_THROW( Invalid_Table ); + goto Bail; + } + + /* allocate one more byte so that we have a final null byte */ + if ( FT_NEW_ARRAY( strings, string_size + 1 ) ) + goto Bail; + + error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size ); + if ( error ) + goto Bail; + + if ( FT_NEW_ARRAY( properties, nprops ) ) + goto Bail; + + face->properties = properties; + + for ( i = 0; i < nprops; i++ ) + { + FT_Long name_offset = props[i].name; + + + if ( ( name_offset < 0 ) || + ( (FT_ULong)name_offset > string_size ) ) + { + error = FT_THROW( Invalid_Offset ); + goto Bail; + } + + if ( FT_STRDUP( properties[i].name, strings + name_offset ) ) + goto Bail; + + FT_TRACE4(( " %s:", properties[i].name )); + + properties[i].isString = props[i].isString; + + if ( props[i].isString ) + { + FT_Long value_offset = props[i].value; + + + if ( ( value_offset < 0 ) || + ( (FT_ULong)value_offset > string_size ) ) + { + error = FT_THROW( Invalid_Offset ); + goto Bail; + } + + if ( FT_STRDUP( properties[i].value.atom, strings + value_offset ) ) + goto Bail; + + FT_TRACE4(( " `%s'\n", properties[i].value.atom )); + } + else + { + properties[i].value.l = props[i].value; + + FT_TRACE4(( " %d\n", properties[i].value.l )); + } + } + + error = FT_Err_Ok; + + Bail: + FT_FREE( props ); + FT_FREE( strings ); + + return error; + } + + + static FT_Error + pcf_get_metrics( FT_Stream stream, + PCF_Face face ) + { + FT_Error error; + FT_Memory memory = FT_FACE( face )->memory; + FT_ULong format, size; + PCF_Metric metrics = 0; + FT_ULong nmetrics, i; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_METRICS, + &format, + &size ); + if ( error ) + return error; + + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && + !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ) + return FT_THROW( Invalid_File_Format ); + + if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( nmetrics ); + else + (void)FT_READ_ULONG_LE( nmetrics ); + } + else + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_USHORT( nmetrics ); + else + (void)FT_READ_USHORT_LE( nmetrics ); + } + if ( error ) + return FT_THROW( Invalid_File_Format ); + + face->nmetrics = nmetrics; + + if ( !nmetrics ) + return FT_THROW( Invalid_Table ); + + 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 FT_THROW( Invalid_Table ); + } + else + { + if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE ) + return FT_THROW( Invalid_Table ); + } + + if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) + return FT_THROW( Out_Of_Memory ); + + metrics = face->metrics; + for ( i = 0; i < nmetrics; i++ ) + { + error = pcf_get_metric( stream, format, metrics + i ); + + metrics[i].bits = 0; + + FT_TRACE5(( " idx %d: width=%d, " + "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", + i, + ( metrics + i )->characterWidth, + ( metrics + i )->leftSideBearing, + ( metrics + i )->rightSideBearing, + ( metrics + i )->ascent, + ( metrics + i )->descent, + ( metrics + i )->attributes )); + + if ( error ) + break; + } + + if ( error ) + FT_FREE( face->metrics ); + + Bail: + return error; + } + + + static FT_Error + pcf_get_bitmaps( FT_Stream stream, + PCF_Face face ) + { + FT_Error error; + FT_Memory memory = FT_FACE( face )->memory; + FT_Long* offsets = NULL; + FT_Long bitmapSizes[GLYPHPADOPTIONS]; + FT_ULong format, size; + FT_ULong nbitmaps, i, sizebitmaps = 0; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_BITMAPS, + &format, + &size ); + if ( error ) + return error; + + error = FT_Stream_EnterFrame( stream, 8 ); + if ( error ) + return error; + + format = FT_GET_ULONG_LE(); + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + nbitmaps = FT_GET_ULONG(); + else + nbitmaps = FT_GET_ULONG_LE(); + + FT_Stream_ExitFrame( stream ); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + return FT_THROW( Invalid_File_Format ); + + FT_TRACE4(( "pcf_get_bitmaps:\n" )); + + FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); + + /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ + if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) + return FT_THROW( Invalid_File_Format ); + + if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) + return error; + + for ( i = 0; i < nbitmaps; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_LONG( offsets[i] ); + else + (void)FT_READ_LONG_LE( offsets[i] ); + + FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n", + i, offsets[i], offsets[i] )); + } + if ( error ) + goto Bail; + + for ( i = 0; i < GLYPHPADOPTIONS; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_LONG( bitmapSizes[i] ); + else + (void)FT_READ_LONG_LE( bitmapSizes[i] ); + if ( error ) + goto Bail; + + sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; + + FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] )); + } + + FT_TRACE4(( " %d bitmaps, padding index %ld\n", + nbitmaps, + PCF_GLYPH_PAD_INDEX( format ) )); + FT_TRACE4(( " bitmap size = %d\n", sizebitmaps )); + + FT_UNUSED( sizebitmaps ); /* only used for debugging */ + + for ( i = 0; i < nbitmaps; i++ ) + { + /* rough estimate */ + if ( ( offsets[i] < 0 ) || + ( (FT_ULong)offsets[i] > size ) ) + { + FT_TRACE0(( "pcf_get_bitmaps:" + " invalid offset to bitmap data of glyph %d\n", i )); + } + else + face->metrics[i].bits = stream->pos + offsets[i]; + } + + face->bitmapsFormat = format; + + Bail: + FT_FREE( offsets ); + return error; + } + + + static FT_Error + pcf_get_encodings( FT_Stream stream, + PCF_Face face ) + { + FT_Error error; + FT_Memory memory = FT_FACE( face )->memory; + FT_ULong format, size; + int firstCol, lastCol; + int firstRow, lastRow; + int nencoding, encodingOffset; + int i, j, k; + PCF_Encoding encoding = NULL; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_BDF_ENCODINGS, + &format, + &size ); + if ( error ) + return error; + + error = FT_Stream_EnterFrame( stream, 14 ); + if ( error ) + return error; + + format = FT_GET_ULONG_LE(); + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + firstCol = FT_GET_SHORT(); + lastCol = FT_GET_SHORT(); + firstRow = FT_GET_SHORT(); + lastRow = FT_GET_SHORT(); + face->defaultChar = FT_GET_SHORT(); + } + else + { + firstCol = FT_GET_SHORT_LE(); + lastCol = FT_GET_SHORT_LE(); + firstRow = FT_GET_SHORT_LE(); + lastRow = FT_GET_SHORT_LE(); + face->defaultChar = FT_GET_SHORT_LE(); + } + + FT_Stream_ExitFrame( stream ); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + return FT_THROW( Invalid_File_Format ); + + FT_TRACE4(( "pdf_get_encodings:\n" )); + + FT_TRACE4(( " firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", + firstCol, lastCol, firstRow, lastRow )); + + nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 ); + + if ( FT_NEW_ARRAY( encoding, nencoding ) ) + return FT_THROW( Out_Of_Memory ); + + error = FT_Stream_EnterFrame( stream, 2 * nencoding ); + if ( error ) + goto Bail; + + k = 0; + for ( i = firstRow; i <= lastRow; i++ ) + { + for ( j = firstCol; j <= lastCol; j++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + encodingOffset = FT_GET_SHORT(); + else + encodingOffset = FT_GET_SHORT_LE(); + + if ( encodingOffset != -1 ) + { + encoding[k].enc = i * 256 + j; + encoding[k].glyph = (FT_Short)encodingOffset; + + FT_TRACE5(( " code %d (0x%04X): idx %d\n", + encoding[k].enc, encoding[k].enc, encoding[k].glyph )); + + k++; + } + } + } + FT_Stream_ExitFrame( stream ); + + if ( FT_RENEW_ARRAY( encoding, nencoding, k ) ) + goto Bail; + + face->nencodings = k; + face->encodings = encoding; + + return error; + + Bail: + FT_FREE( encoding ); + return error; + } + + + static + const FT_Frame_Field pcf_accel_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_AccelRec + + FT_FRAME_START( 20 ), + FT_FRAME_BYTE ( noOverlap ), + FT_FRAME_BYTE ( constantMetrics ), + FT_FRAME_BYTE ( terminalFont ), + FT_FRAME_BYTE ( constantWidth ), + FT_FRAME_BYTE ( inkInside ), + FT_FRAME_BYTE ( inkMetrics ), + FT_FRAME_BYTE ( drawDirection ), + FT_FRAME_SKIP_BYTES( 1 ), + FT_FRAME_LONG_LE ( fontAscent ), + FT_FRAME_LONG_LE ( fontDescent ), + FT_FRAME_LONG_LE ( maxOverlap ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_accel_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_AccelRec + + FT_FRAME_START( 20 ), + FT_FRAME_BYTE ( noOverlap ), + FT_FRAME_BYTE ( constantMetrics ), + FT_FRAME_BYTE ( terminalFont ), + FT_FRAME_BYTE ( constantWidth ), + FT_FRAME_BYTE ( inkInside ), + FT_FRAME_BYTE ( inkMetrics ), + FT_FRAME_BYTE ( drawDirection ), + FT_FRAME_SKIP_BYTES( 1 ), + FT_FRAME_LONG ( fontAscent ), + FT_FRAME_LONG ( fontDescent ), + FT_FRAME_LONG ( maxOverlap ), + FT_FRAME_END + }; + + + static FT_Error + pcf_get_accel( FT_Stream stream, + PCF_Face face, + FT_ULong type ) + { + FT_ULong format, size; + FT_Error error; + PCF_Accel accel = &face->accel; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + type, + &format, + &size ); + if ( error ) + goto Bail; + + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && + !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) + goto Bail; + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) ) + goto Bail; + } + else + { + if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) ) + goto Bail; + } + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->minbounds) ); + if ( error ) + goto Bail; + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->maxbounds) ); + if ( error ) + goto Bail; + + if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) + { + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->ink_minbounds) ); + if ( error ) + goto Bail; + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->ink_maxbounds) ); + if ( error ) + goto Bail; + } + else + { + accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */ + accel->ink_maxbounds = accel->maxbounds; + } + + Bail: + return error; + } + + + static FT_Error + pcf_interpret_style( PCF_Face pcf ) + { + FT_Error error = FT_Err_Ok; + FT_Face face = FT_FACE( pcf ); + FT_Memory memory = face->memory; + + PCF_Property prop; + + size_t nn, len; + char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t lengths[4]; + + + face->style_flags = 0; + + prop = pcf_find_property( pcf, "SLANT" ); + if ( prop && prop->isString && + ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || + *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) + { + face->style_flags |= FT_STYLE_FLAG_ITALIC; + strings[2] = ( *(prop->value.atom) == 'O' || + *(prop->value.atom) == 'o' ) ? (char *)"Oblique" + : (char *)"Italic"; + } + + prop = pcf_find_property( pcf, "WEIGHT_NAME" ); + if ( prop && prop->isString && + ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) + { + face->style_flags |= FT_STYLE_FLAG_BOLD; + strings[1] = (char*)"Bold"; + } + + prop = pcf_find_property( pcf, "SETWIDTH_NAME" ); + if ( prop && prop->isString && + *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + strings[3] = (char*)( prop->value.atom ); + + prop = pcf_find_property( pcf, "ADD_STYLE_NAME" ); + if ( prop && prop->isString && + *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + strings[0] = (char*)( prop->value.atom ); + + for ( len = 0, nn = 0; nn < 4; nn++ ) + { + lengths[nn] = 0; + if ( strings[nn] ) + { + lengths[nn] = ft_strlen( strings[nn] ); + len += lengths[nn] + 1; + } + } + + if ( len == 0 ) + { + strings[0] = (char*)"Regular"; + lengths[0] = ft_strlen( strings[0] ); + len = lengths[0] + 1; + } + + { + char* s; + + + if ( FT_ALLOC( face->style_name, len ) ) + return error; + + s = face->style_name; + + for ( nn = 0; nn < 4; nn++ ) + { + char* src = strings[nn]; + + + len = lengths[nn]; + + if ( src == NULL ) + continue; + + /* separate elements with a space */ + if ( s != face->style_name ) + *s++ = ' '; + + ft_memcpy( s, src, len ); + + /* need to convert spaces to dashes for */ + /* add_style_name and setwidth_name */ + if ( nn == 0 || nn == 3 ) + { + size_t mm; + + + for ( mm = 0; mm < len; mm++ ) + if ( s[mm] == ' ' ) + s[mm] = '-'; + } + + s += len; + } + *s = 0; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pcf_load_font( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = FT_FACE( face )->memory; + FT_Bool hasBDFAccelerators; + + + error = pcf_read_TOC( stream, face ); + if ( error ) + goto Exit; + + error = pcf_get_properties( stream, face ); + if ( error ) + goto Exit; + + /* Use the old accelerators if no BDF accelerators are in the file. */ + hasBDFAccelerators = pcf_has_table_type( face->toc.tables, + face->toc.count, + PCF_BDF_ACCELERATORS ); + if ( !hasBDFAccelerators ) + { + error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); + if ( error ) + goto Exit; + } + + /* metrics */ + error = pcf_get_metrics( stream, face ); + if ( error ) + goto Exit; + + /* bitmaps */ + error = pcf_get_bitmaps( stream, face ); + if ( error ) + goto Exit; + + /* encodings */ + error = pcf_get_encodings( stream, face ); + if ( error ) + goto Exit; + + /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ + if ( hasBDFAccelerators ) + { + error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); + if ( error ) + goto Exit; + } + + /* XXX: TO DO: inkmetrics and glyph_names are missing */ + + /* now construct the face object */ + { + FT_Face root = FT_FACE( face ); + PCF_Property prop; + + + root->num_faces = 1; + root->face_index = 0; + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; + + if ( face->accel.constantWidth ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( ( error = pcf_interpret_style( face ) ) != 0 ) + goto Exit; + + prop = pcf_find_property( face, "FAMILY_NAME" ); + if ( prop && prop->isString ) + { + if ( FT_STRDUP( root->family_name, prop->value.atom ) ) + goto Exit; + } + else + root->family_name = NULL; + + /* + * Note: We shift all glyph indices by +1 since we must + * respect the convention that glyph 0 always corresponds + * to the `missing glyph'. + * + * This implies bumping the number of `available' glyphs by 1. + */ + root->num_glyphs = face->nmetrics + 1; + + root->num_fixed_sizes = 1; + if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) + goto Exit; + + { + FT_Bitmap_Size* bsize = root->available_sizes; + FT_Short resolution_x = 0, resolution_y = 0; + + + FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + +#if 0 + bsize->height = face->accel.maxbounds.ascent << 6; +#endif + bsize->height = (FT_Short)( face->accel.fontAscent + + face->accel.fontDescent ); + + prop = pcf_find_property( face, "AVERAGE_WIDTH" ); + if ( prop ) + bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); + else + bsize->width = (FT_Short)( bsize->height * 2/3 ); + + prop = pcf_find_property( face, "POINT_SIZE" ); + if ( prop ) + /* convert from 722.7 decipoints to 72 points per inch */ + bsize->size = + (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); + + prop = pcf_find_property( face, "PIXEL_SIZE" ); + if ( prop ) + bsize->y_ppem = (FT_Short)prop->value.l << 6; + + prop = pcf_find_property( face, "RESOLUTION_X" ); + if ( prop ) + resolution_x = (FT_Short)prop->value.l; + + prop = pcf_find_property( face, "RESOLUTION_Y" ); + if ( prop ) + resolution_y = (FT_Short)prop->value.l; + + if ( bsize->y_ppem == 0 ) + { + bsize->y_ppem = bsize->size; + if ( resolution_y ) + bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + } + if ( resolution_x && resolution_y ) + bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + else + bsize->x_ppem = bsize->y_ppem; + } + + /* set up charset */ + { + PCF_Property charset_registry = 0, charset_encoding = 0; + + + charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); + charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); + + if ( charset_registry && charset_registry->isString && + charset_encoding && charset_encoding->isString ) + { + if ( FT_STRDUP( face->charset_encoding, + charset_encoding->value.atom ) || + FT_STRDUP( face->charset_registry, + charset_registry->value.atom ) ) + goto Exit; + } + } + } + + Exit: + if ( error ) + { + /* This is done to respect the behaviour of the original */ + /* PCF font driver. */ + error = FT_THROW( Invalid_File_Format ); + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/pcf/pcfread.h b/drivers/freetype/src/pcf/pcfread.h new file mode 100644 index 0000000000..c9524f1346 --- /dev/null +++ b/drivers/freetype/src/pcf/pcfread.h @@ -0,0 +1,45 @@ +/* pcfread.h + + FreeType font driver for pcf fonts + + Copyright 2003 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCFREAD_H__ +#define __PCFREAD_H__ + + +#include <ft2build.h> + +FT_BEGIN_HEADER + + FT_LOCAL( PCF_Property ) + pcf_find_property( PCF_Face face, + const FT_String* prop ); + +FT_END_HEADER + +#endif /* __PCFREAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pcf/pcfutil.c b/drivers/freetype/src/pcf/pcfutil.c new file mode 100644 index 0000000000..b91274f935 --- /dev/null +++ b/drivers/freetype/src/pcf/pcfutil.c @@ -0,0 +1,104 @@ +/* + +Copyright 1990, 1994, 1998 The Open Group + +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. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.3 1999/08/22 08:58:58 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +/* Modified for use with FreeType */ + + +#include <ft2build.h> +#include "pcfutil.h" + + + /* + * Invert bit order within each BYTE of an array. + */ + + FT_LOCAL_DEF( void ) + BitOrderInvert( unsigned char* buf, + size_t nbytes ) + { + for ( ; nbytes > 0; nbytes--, 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; + } + } + + + /* + * Invert byte order within each 16-bits of an array. + */ + + FT_LOCAL_DEF( void ) + TwoByteSwap( unsigned char* buf, + size_t nbytes ) + { + unsigned char c; + + + for ( ; nbytes >= 2; nbytes -= 2, buf += 2 ) + { + c = buf[0]; + buf[0] = buf[1]; + buf[1] = c; + } + } + + /* + * Invert byte order within each 32-bits of an array. + */ + + FT_LOCAL_DEF( void ) + FourByteSwap( unsigned char* buf, + size_t nbytes ) + { + unsigned char c; + + + for ( ; nbytes >= 4; nbytes -= 4, buf += 4 ) + { + c = buf[0]; + buf[0] = buf[3]; + buf[3] = c; + + c = buf[1]; + buf[1] = buf[2]; + buf[2] = c; + } + } + + +/* END */ diff --git a/drivers/freetype/src/pcf/pcfutil.h b/drivers/freetype/src/pcf/pcfutil.h new file mode 100644 index 0000000000..ce10fb541d --- /dev/null +++ b/drivers/freetype/src/pcf/pcfutil.h @@ -0,0 +1,55 @@ +/* pcfutil.h + + FreeType font driver for pcf fonts + + Copyright 2000, 2001, 2004 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 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCFUTIL_H__ +#define __PCFUTIL_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H + + +FT_BEGIN_HEADER + + FT_LOCAL( void ) + BitOrderInvert( unsigned char* buf, + size_t nbytes ); + + FT_LOCAL( void ) + TwoByteSwap( unsigned char* buf, + size_t nbytes ); + + FT_LOCAL( void ) + FourByteSwap( unsigned char* buf, + size_t nbytes ); + +FT_END_HEADER + +#endif /* __PCFUTIL_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pcf/rules.mk b/drivers/freetype/src/pcf/rules.mk new file mode 100644 index 0000000000..78641528fa --- /dev/null +++ b/drivers/freetype/src/pcf/rules.mk @@ -0,0 +1,79 @@ +# +# FreeType 2 pcf driver configuration rules +# + + +# Copyright (C) 2000, 2001, 2003, 2008 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 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +# pcf driver directory +# +PCF_DIR := $(SRC_DIR)/pcf + + +PCF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) + + +# pcf driver sources (i.e., C files) +# +PCF_DRV_SRC := $(PCF_DIR)/pcfdrivr.c \ + $(PCF_DIR)/pcfread.c \ + $(PCF_DIR)/pcfutil.c + +# pcf driver headers +# +PCF_DRV_H := $(PCF_DRV_SRC:%.c=%.h) \ + $(PCF_DIR)/pcf.h \ + $(PCF_DIR)/pcferror.h + +# pcf driver object(s) +# +# PCF_DRV_OBJ_M is used during `multi' builds +# PCF_DRV_OBJ_S is used during `single' builds +# +PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR)/%.c=$(OBJ_DIR)/%.$O) +PCF_DRV_OBJ_S := $(OBJ_DIR)/pcf.$O + +# pcf driver source file for single build +# +PCF_DRV_SRC_S := $(PCF_DIR)/pcf.c + + +# pcf driver - single object +# +$(PCF_DRV_OBJ_S): $(PCF_DRV_SRC_S) $(PCF_DRV_SRC) $(FREETYPE_H) $(PCF_DRV_H) + $(PCF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PCF_DRV_SRC_S)) + + +# pcf driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(PCF_DIR)/%.c $(FREETYPE_H) $(PCF_DRV_H) + $(PCF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(PCF_DRV_OBJ_S) +DRV_OBJS_M += $(PCF_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/pfr/Jamfile b/drivers/freetype/src/pfr/Jamfile new file mode 100644 index 0000000000..9e2f2b8d05 --- /dev/null +++ b/drivers/freetype/src/pfr/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/pfr Jamfile +# +# Copyright 2002 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) pfr ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ; + } + else + { + _sources = pfr ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/pfr Jamfile diff --git a/drivers/freetype/src/pfr/module.mk b/drivers/freetype/src/pfr/module.mk new file mode 100644 index 0000000000..8d1d28a9d2 --- /dev/null +++ b/drivers/freetype/src/pfr/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 PFR module definition +# + + +# Copyright 2002, 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. + + +FTMODULE_H_COMMANDS += PFR_DRIVER + +define PFR_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, pfr_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)pfr $(ECHO_DRIVER_DESC)PFR/TrueDoc font files with extension *.pfr$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/pfr/pfr.c b/drivers/freetype/src/pfr/pfr.c new file mode 100644 index 0000000000..eb2c4edb7e --- /dev/null +++ b/drivers/freetype/src/pfr/pfr.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* pfr.c */ +/* */ +/* FreeType PFR driver component. */ +/* */ +/* Copyright 2002 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. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> + +#include "pfrload.c" +#include "pfrgload.c" +#include "pfrcmap.c" +#include "pfrobjs.c" +#include "pfrdrivr.c" +#include "pfrsbit.c" + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrcmap.c b/drivers/freetype/src/pfr/pfrcmap.c new file mode 100644 index 0000000000..740c433d66 --- /dev/null +++ b/drivers/freetype/src/pfr/pfrcmap.c @@ -0,0 +1,168 @@ +/***************************************************************************/ +/* */ +/* pfrcmap.c */ +/* */ +/* FreeType PFR cmap handling (body). */ +/* */ +/* Copyright 2002, 2007, 2009, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include "pfrcmap.h" +#include "pfrobjs.h" + +#include "pfrerror.h" + + + FT_CALLBACK_DEF( FT_Error ) + pfr_cmap_init( PFR_CMap cmap ) + { + FT_Error error = FT_Err_Ok; + PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); + + + 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++ ) + { + if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + } + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( void ) + pfr_cmap_done( PFR_CMap cmap ) + { + cmap->chars = NULL; + cmap->num_chars = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pfr_cmap_char_index( PFR_CMap cmap, + FT_UInt32 char_code ) + { + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; + FT_UInt mid; + PFR_Char gchar; + + + while ( min < max ) + { + mid = min + ( max - min ) / 2; + gchar = cmap->chars + mid; + + if ( gchar->char_code == char_code ) + return mid + 1; + + if ( gchar->char_code < char_code ) + min = mid + 1; + else + max = mid; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + pfr_cmap_char_next( PFR_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + Restart: + { + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; + FT_UInt mid; + PFR_Char gchar; + + + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + gchar = cmap->chars + mid; + + if ( gchar->char_code == char_code ) + { + result = mid; + if ( result != 0 ) + { + result++; + goto Exit; + } + + char_code++; + goto Restart; + } + + if ( gchar->char_code < char_code ) + min = mid+1; + else + max = mid; + } + + /* we didn't find it, but we have a pair just above it */ + char_code = 0; + + if ( min < cmap->num_chars ) + { + gchar = cmap->chars + min; + result = min; + if ( result != 0 ) + { + result++; + char_code = gchar->char_code; + } + } + } + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + pfr_cmap_class_rec = + { + sizeof ( PFR_CMapRec ), + + (FT_CMap_InitFunc) pfr_cmap_init, + (FT_CMap_DoneFunc) pfr_cmap_done, + (FT_CMap_CharIndexFunc)pfr_cmap_char_index, + (FT_CMap_CharNextFunc) pfr_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrcmap.h b/drivers/freetype/src/pfr/pfrcmap.h new file mode 100644 index 0000000000..a626953054 --- /dev/null +++ b/drivers/freetype/src/pfr/pfrcmap.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* pfrcmap.h */ +/* */ +/* FreeType PFR cmap handling (specification). */ +/* */ +/* Copyright 2002 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 __PFRCMAP_H__ +#define __PFRCMAP_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "pfrtypes.h" + + +FT_BEGIN_HEADER + + typedef struct PFR_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt num_chars; + PFR_Char chars; + + } PFR_CMapRec, *PFR_CMap; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec pfr_cmap_class_rec; + +FT_END_HEADER + + +#endif /* __PFRCMAP_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrdrivr.c b/drivers/freetype/src/pfr/pfrdrivr.c new file mode 100644 index 0000000000..4c43947bf4 --- /dev/null +++ b/drivers/freetype/src/pfr/pfrdrivr.c @@ -0,0 +1,210 @@ +/***************************************************************************/ +/* */ +/* pfrdrivr.c */ +/* */ +/* FreeType PFR driver interface (body). */ +/* */ +/* Copyright 2002-2004, 2006, 2008, 2010, 2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_SERVICE_PFR_H +#include FT_SERVICE_XFREE86_NAME_H +#include "pfrdrivr.h" +#include "pfrobjs.h" + +#include "pfrerror.h" + + + FT_CALLBACK_DEF( FT_Error ) + pfr_get_kerning( FT_Face pfrface, /* PFR_Face */ + FT_UInt left, + FT_UInt right, + FT_Vector *avector ) + { + PFR_Face face = (PFR_Face)pfrface; + PFR_PhyFont phys = &face->phy_font; + + + pfr_face_get_kerning( pfrface, left, right, avector ); + + /* convert from metrics to outline units when necessary */ + if ( phys->outline_resolution != phys->metrics_resolution ) + { + if ( avector->x != 0 ) + avector->x = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); + + if ( avector->y != 0 ) + avector->y = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); + } + + return FT_Err_Ok; + } + + + /* + * PFR METRICS SERVICE + * + */ + + FT_CALLBACK_DEF( FT_Error ) + pfr_get_advance( FT_Face pfrface, /* PFR_Face */ + FT_UInt gindex, + FT_Pos *anadvance ) + { + PFR_Face face = (PFR_Face)pfrface; + FT_Error error = FT_ERR( Invalid_Argument ); + + + *anadvance = 0; + + if ( !gindex ) + goto Exit; + + gindex--; + + if ( face ) + { + PFR_PhyFont phys = &face->phy_font; + + + if ( gindex < phys->num_chars ) + { + *anadvance = phys->chars[gindex].advance; + error = FT_Err_Ok; + } + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + pfr_get_metrics( FT_Face pfrface, /* PFR_Face */ + FT_UInt *anoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) + { + PFR_Face face = (PFR_Face)pfrface; + PFR_PhyFont phys = &face->phy_font; + FT_Fixed x_scale, y_scale; + FT_Size size = face->root.size; + + + if ( anoutline_resolution ) + *anoutline_resolution = phys->outline_resolution; + + if ( ametrics_resolution ) + *ametrics_resolution = phys->metrics_resolution; + + x_scale = 0x10000L; + y_scale = 0x10000L; + + if ( size ) + { + x_scale = FT_DivFix( size->metrics.x_ppem << 6, + phys->metrics_resolution ); + + y_scale = FT_DivFix( size->metrics.y_ppem << 6, + phys->metrics_resolution ); + } + + if ( ametrics_x_scale ) + *ametrics_x_scale = x_scale; + + if ( ametrics_y_scale ) + *ametrics_y_scale = y_scale; + + return FT_Err_Ok; + } + + + FT_CALLBACK_TABLE_DEF + const FT_Service_PfrMetricsRec pfr_metrics_service_rec = + { + pfr_get_metrics, + pfr_face_get_kerning, + pfr_get_advance + }; + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec pfr_services[] = + { + { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + pfr_get_service( FT_Module module, + const FT_String* service_id ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( pfr_services, service_id ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec pfr_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE, + + sizeof ( FT_DriverRec ), + + "pfr", + 0x10000L, + 0x20000L, + + NULL, + + 0, /* FT_Module_Constructor */ + 0, /* FT_Module_Destructor */ + pfr_get_service + }, + + sizeof ( PFR_FaceRec ), + sizeof ( PFR_SizeRec ), + sizeof ( PFR_SlotRec ), + + pfr_face_init, + pfr_face_done, + 0, /* FT_Size_InitFunc */ + 0, /* FT_Size_DoneFunc */ + pfr_slot_init, + pfr_slot_done, + + pfr_slot_load, + + pfr_get_kerning, + 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Size_RequestFunc */ + 0, /* FT_Size_SelectFunc */ + }; + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrdrivr.h b/drivers/freetype/src/pfr/pfrdrivr.h new file mode 100644 index 0000000000..75f86c5cdd --- /dev/null +++ b/drivers/freetype/src/pfr/pfrdrivr.h @@ -0,0 +1,43 @@ +/***************************************************************************/ +/* */ +/* pfrdrivr.h */ +/* */ +/* High-level Type PFR driver interface (specification). */ +/* */ +/* Copyright 2002 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 __PFRDRIVR_H__ +#define __PFRDRIVR_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; + + +FT_END_HEADER + + +#endif /* __PFRDRIVR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrerror.h b/drivers/freetype/src/pfr/pfrerror.h new file mode 100644 index 0000000000..94dc8c5e1c --- /dev/null +++ b/drivers/freetype/src/pfr/pfrerror.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* pfrerror.h */ +/* */ +/* PFR error codes (specification only). */ +/* */ +/* Copyright 2002, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PFR error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PFRERROR_H__ +#define __PFRERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX PFR_Err_ +#define FT_ERR_BASE FT_Mod_Err_PFR + +#include FT_ERRORS_H + +#endif /* __PFRERROR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrgload.c b/drivers/freetype/src/pfr/pfrgload.c new file mode 100644 index 0000000000..88b4d66a13 --- /dev/null +++ b/drivers/freetype/src/pfr/pfrgload.c @@ -0,0 +1,844 @@ +/***************************************************************************/ +/* */ +/* pfrgload.c */ +/* */ +/* FreeType PFR glyph loader (body). */ +/* */ +/* Copyright 2002, 2003, 2005, 2007, 2010, 2013 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 "pfrgload.h" +#include "pfrsbit.h" +#include "pfrload.h" /* for macro definitions */ +#include FT_INTERNAL_DEBUG_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR GLYPH BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( void ) + pfr_glyph_init( PFR_Glyph glyph, + FT_GlyphLoader loader ) + { + FT_ZERO( glyph ); + + glyph->loader = loader; + glyph->path_begun = 0; + + FT_GlyphLoader_Rewind( loader ); + } + + + FT_LOCAL_DEF( void ) + pfr_glyph_done( PFR_Glyph glyph ) + { + FT_Memory memory = glyph->loader->memory; + + + FT_FREE( glyph->x_control ); + glyph->y_control = NULL; + + glyph->max_xy_control = 0; +#if 0 + glyph->num_x_control = 0; + glyph->num_y_control = 0; +#endif + + FT_FREE( glyph->subs ); + + glyph->max_subs = 0; + glyph->num_subs = 0; + + glyph->loader = NULL; + glyph->path_begun = 0; + } + + + /* close current contour, if any */ + static void + pfr_glyph_close_contour( PFR_Glyph glyph ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Int last, first; + + + if ( !glyph->path_begun ) + return; + + /* compute first and last point indices in current glyph outline */ + last = outline->n_points - 1; + first = 0; + if ( outline->n_contours > 0 ) + first = outline->contours[outline->n_contours - 1]; + + /* if the last point falls on the same location than the first one */ + /* we need to delete it */ + if ( last > first ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + last; + + + if ( p1->x == p2->x && p1->y == p2->y ) + { + outline->n_points--; + last--; + } + } + + /* don't add empty contours */ + if ( last >= first ) + outline->contours[outline->n_contours++] = (short)last; + + glyph->path_begun = 0; + } + + + /* reset glyph to start the loading of a new glyph */ + static void + pfr_glyph_start( PFR_Glyph glyph ) + { + glyph->path_begun = 0; + } + + + static FT_Error + pfr_glyph_line_to( PFR_Glyph glyph, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Error error; + + + /* check that we have begun a new path */ + if ( !glyph->path_begun ) + { + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" )); + goto Exit; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 ); + if ( !error ) + { + FT_UInt n = outline->n_points; + + + outline->points[n] = *to; + outline->tags [n] = FT_CURVE_TAG_ON; + + outline->n_points++; + } + + Exit: + return error; + } + + + static FT_Error + pfr_glyph_curve_to( PFR_Glyph glyph, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Error error; + + + /* check that we have begun a new path */ + if ( !glyph->path_begun ) + { + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" )); + goto Exit; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 ); + if ( !error ) + { + FT_Vector* vec = outline->points + outline->n_points; + FT_Byte* tag = (FT_Byte*)outline->tags + outline->n_points; + + + vec[0] = *control1; + vec[1] = *control2; + vec[2] = *to; + tag[0] = FT_CURVE_TAG_CUBIC; + tag[1] = FT_CURVE_TAG_CUBIC; + tag[2] = FT_CURVE_TAG_ON; + + outline->n_points = (FT_Short)( outline->n_points + 3 ); + } + + Exit: + return error; + } + + + static FT_Error + pfr_glyph_move_to( PFR_Glyph glyph, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Error error; + + + /* close current contour if any */ + pfr_glyph_close_contour( glyph ); + + /* indicate that a new contour has started */ + glyph->path_begun = 1; + + /* check that there is space for a new contour and a new point */ + error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 ); + if ( !error ) + /* add new start point */ + error = pfr_glyph_line_to( glyph, to ); + + return error; + } + + + static void + pfr_glyph_end( PFR_Glyph glyph ) + { + /* close current contour if any */ + pfr_glyph_close_contour( glyph ); + + /* merge the current glyph into the stack */ + FT_GlyphLoader_Add( glyph->loader ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR GLYPH LOADER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* load a simple glyph */ + static FT_Error + pfr_glyph_load_simple( PFR_Glyph glyph, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = glyph->loader->memory; + FT_UInt flags, x_count, y_count, i, count, mask; + FT_Int x; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + /* test for composite glyphs */ + if ( flags & PFR_GLYPH_IS_COMPOUND ) + goto Failure; + + x_count = 0; + y_count = 0; + + if ( flags & PFR_GLYPH_1BYTE_XYCOUNT ) + { + PFR_CHECK( 1 ); + count = PFR_NEXT_BYTE( p ); + x_count = count & 15; + y_count = count >> 4; + } + else + { + if ( flags & PFR_GLYPH_XCOUNT ) + { + PFR_CHECK( 1 ); + x_count = PFR_NEXT_BYTE( p ); + } + + if ( flags & PFR_GLYPH_YCOUNT ) + { + PFR_CHECK( 1 ); + y_count = PFR_NEXT_BYTE( p ); + } + } + + count = x_count + y_count; + + /* re-allocate array when necessary */ + if ( count > glyph->max_xy_control ) + { + FT_UInt new_max = FT_PAD_CEIL( count, 8 ); + + + if ( FT_RENEW_ARRAY( glyph->x_control, + glyph->max_xy_control, + new_max ) ) + goto Exit; + + glyph->max_xy_control = new_max; + } + + glyph->y_control = glyph->x_control + x_count; + + mask = 0; + x = 0; + + for ( i = 0; i < count; i++ ) + { + if ( ( i & 7 ) == 0 ) + { + PFR_CHECK( 1 ); + mask = PFR_NEXT_BYTE( p ); + } + + if ( mask & 1 ) + { + PFR_CHECK( 2 ); + x = PFR_NEXT_SHORT( p ); + } + else + { + PFR_CHECK( 1 ); + x += PFR_NEXT_BYTE( p ); + } + + glyph->x_control[i] = x; + + mask >>= 1; + } + + /* XXX: for now we ignore the secondary stroke and edge definitions */ + /* since we don't want to support native PFR hinting */ + /* */ + if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if ( error ) + goto Exit; + } + + pfr_glyph_start( glyph ); + + /* now load a simple glyph */ + { + FT_Vector pos[4]; + FT_Vector* cur; + + + pos[0].x = pos[0].y = 0; + pos[3] = pos[0]; + + for (;;) + { + FT_UInt format, format_low, args_format = 0, args_count, n; + + + /***************************************************************/ + /* read instruction */ + /* */ + PFR_CHECK( 1 ); + format = PFR_NEXT_BYTE( p ); + format_low = format & 15; + + switch ( format >> 4 ) + { + case 0: /* end glyph */ + FT_TRACE6(( "- end glyph" )); + args_count = 0; + break; + + case 1: /* general line operation */ + FT_TRACE6(( "- general line" )); + goto Line1; + + case 4: /* move to inside contour */ + FT_TRACE6(( "- move to inside" )); + goto Line1; + + case 5: /* move to outside contour */ + FT_TRACE6(( "- move to outside" )); + Line1: + args_format = format_low; + args_count = 1; + break; + + case 2: /* horizontal line to */ + FT_TRACE6(( "- horizontal line to cx.%d", format_low )); + if ( format_low >= x_count ) + goto Failure; + pos[0].x = glyph->x_control[format_low]; + pos[0].y = pos[3].y; + pos[3] = pos[0]; + args_count = 0; + break; + + case 3: /* vertical line to */ + FT_TRACE6(( "- vertical line to cy.%d", format_low )); + if ( format_low >= y_count ) + goto Failure; + pos[0].x = pos[3].x; + pos[0].y = glyph->y_control[format_low]; + pos[3] = pos[0]; + args_count = 0; + break; + + case 6: /* horizontal to vertical curve */ + FT_TRACE6(( "- hv curve " )); + args_format = 0xB8E; + args_count = 3; + break; + + case 7: /* vertical to horizontal curve */ + FT_TRACE6(( "- vh curve" )); + args_format = 0xE2B; + args_count = 3; + break; + + default: /* general curve to */ + FT_TRACE6(( "- general curve" )); + args_count = 4; + args_format = format_low; + } + + /***********************************************************/ + /* now read arguments */ + /* */ + cur = pos; + for ( n = 0; n < args_count; n++ ) + { + FT_UInt idx; + FT_Int delta; + + + /* read the X argument */ + switch ( args_format & 3 ) + { + case 0: /* 8-bit index */ + PFR_CHECK( 1 ); + idx = PFR_NEXT_BYTE( p ); + if ( idx >= x_count ) + goto Failure; + cur->x = glyph->x_control[idx]; + FT_TRACE7(( " cx#%d", idx )); + break; + + case 1: /* 16-bit value */ + PFR_CHECK( 2 ); + cur->x = PFR_NEXT_SHORT( p ); + FT_TRACE7(( " x.%d", cur->x )); + break; + + case 2: /* 8-bit delta */ + PFR_CHECK( 1 ); + delta = PFR_NEXT_INT8( p ); + cur->x = pos[3].x + delta; + FT_TRACE7(( " dx.%d", delta )); + break; + + default: + FT_TRACE7(( " |" )); + cur->x = pos[3].x; + } + + /* read the Y argument */ + switch ( ( args_format >> 2 ) & 3 ) + { + case 0: /* 8-bit index */ + PFR_CHECK( 1 ); + idx = PFR_NEXT_BYTE( p ); + if ( idx >= y_count ) + goto Failure; + cur->y = glyph->y_control[idx]; + FT_TRACE7(( " cy#%d", idx )); + break; + + case 1: /* 16-bit absolute value */ + PFR_CHECK( 2 ); + cur->y = PFR_NEXT_SHORT( p ); + FT_TRACE7(( " y.%d", cur->y )); + break; + + case 2: /* 8-bit delta */ + PFR_CHECK( 1 ); + delta = PFR_NEXT_INT8( p ); + cur->y = pos[3].y + delta; + FT_TRACE7(( " dy.%d", delta )); + break; + + default: + FT_TRACE7(( " -" )); + cur->y = pos[3].y; + } + + /* read the additional format flag for the general curve */ + if ( n == 0 && args_count == 4 ) + { + PFR_CHECK( 1 ); + args_format = PFR_NEXT_BYTE( p ); + args_count--; + } + else + args_format >>= 4; + + /* save the previous point */ + pos[3] = cur[0]; + cur++; + } + + FT_TRACE7(( "\n" )); + + /***********************************************************/ + /* finally, execute instruction */ + /* */ + switch ( format >> 4 ) + { + case 0: /* end glyph => EXIT */ + pfr_glyph_end( glyph ); + goto Exit; + + case 1: /* line operations */ + case 2: + case 3: + error = pfr_glyph_line_to( glyph, pos ); + goto Test_Error; + + case 4: /* move to inside contour */ + case 5: /* move to outside contour */ + error = pfr_glyph_move_to( glyph, pos ); + goto Test_Error; + + default: /* curve operations */ + error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); + + Test_Error: /* test error condition */ + if ( error ) + goto Exit; + } + } /* for (;;) */ + } + + Exit: + return error; + + Failure: + Too_Short: + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" )); + goto Exit; + } + + + /* load a composite/compound glyph */ + static FT_Error + pfr_glyph_load_compound( PFR_Glyph glyph, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Error error = FT_Err_Ok; + FT_GlyphLoader loader = glyph->loader; + FT_Memory memory = loader->memory; + PFR_SubGlyph subglyph; + FT_UInt flags, i, count, org_count; + FT_Int x_pos, y_pos; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + /* test for composite glyphs */ + if ( !( flags & PFR_GLYPH_IS_COMPOUND ) ) + goto Failure; + + count = flags & 0x3F; + + /* ignore extra items when present */ + /* */ + if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Exit; + } + + /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ + /* the PFR format is dumb, using direct file offsets to point to the */ + /* sub-glyphs (instead of glyph indices). Sigh. */ + /* */ + /* For now, we load the list of sub-glyphs into a different array */ + /* but this will prevent us from using the auto-hinter at its best */ + /* quality. */ + /* */ + org_count = glyph->num_subs; + + if ( org_count + count > glyph->max_subs ) + { + FT_UInt new_max = ( org_count + count + 3 ) & (FT_UInt)-4; + + + /* we arbitrarily limit the number of subglyphs */ + /* to avoid endless recursion */ + if ( new_max > 64 ) + { + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_glyph_load_compound:" + " too many compound glyphs components\n" )); + goto Exit; + } + + if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) + goto Exit; + + glyph->max_subs = new_max; + } + + subglyph = glyph->subs + org_count; + + for ( i = 0; i < count; i++, subglyph++ ) + { + FT_UInt format; + + + x_pos = 0; + y_pos = 0; + + PFR_CHECK( 1 ); + format = PFR_NEXT_BYTE( p ); + + /* read scale when available */ + subglyph->x_scale = 0x10000L; + if ( format & PFR_SUBGLYPH_XSCALE ) + { + PFR_CHECK( 2 ); + subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; + } + + subglyph->y_scale = 0x10000L; + if ( format & PFR_SUBGLYPH_YSCALE ) + { + PFR_CHECK( 2 ); + subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; + } + + /* read offset */ + switch ( format & 3 ) + { + case 1: + PFR_CHECK( 2 ); + x_pos = PFR_NEXT_SHORT( p ); + break; + + case 2: + PFR_CHECK( 1 ); + x_pos += PFR_NEXT_INT8( p ); + break; + + default: + ; + } + + switch ( ( format >> 2 ) & 3 ) + { + case 1: + PFR_CHECK( 2 ); + y_pos = PFR_NEXT_SHORT( p ); + break; + + case 2: + PFR_CHECK( 1 ); + y_pos += PFR_NEXT_INT8( p ); + break; + + default: + ; + } + + subglyph->x_delta = x_pos; + subglyph->y_delta = y_pos; + + /* read glyph position and size now */ + if ( format & PFR_SUBGLYPH_2BYTE_SIZE ) + { + PFR_CHECK( 2 ); + subglyph->gps_size = PFR_NEXT_USHORT( p ); + } + else + { + PFR_CHECK( 1 ); + subglyph->gps_size = PFR_NEXT_BYTE( p ); + } + + if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) + { + PFR_CHECK( 3 ); + subglyph->gps_offset = PFR_NEXT_LONG( p ); + } + else + { + PFR_CHECK( 2 ); + subglyph->gps_offset = PFR_NEXT_USHORT( p ); + } + + glyph->num_subs++; + } + + Exit: + return error; + + Failure: + Too_Short: + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" )); + goto Exit; + } + + + static FT_Error + pfr_glyph_load_rec( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ) + { + FT_Error error; + FT_Byte* p; + FT_Byte* limit; + + + if ( FT_STREAM_SEEK( gps_offset + offset ) || + FT_FRAME_ENTER( size ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + limit = p + size; + + if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) + { + FT_Int n, old_count, count; + FT_GlyphLoader loader = glyph->loader; + FT_Outline* base = &loader->base.outline; + + + old_count = glyph->num_subs; + + /* this is a compound glyph - load it */ + error = pfr_glyph_load_compound( glyph, p, limit ); + + FT_FRAME_EXIT(); + + if ( error ) + goto Exit; + + count = glyph->num_subs - old_count; + + FT_TRACE4(( "compound glyph with %d elements (offset %lu):\n", + count, offset )); + + /* now, load each individual glyph */ + for ( n = 0; n < count; n++ ) + { + FT_Int i, old_points, num_points; + PFR_SubGlyph subglyph; + + + FT_TRACE4(( "subglyph %d:\n", n )); + + subglyph = glyph->subs + old_count + n; + old_points = base->n_points; + + error = pfr_glyph_load_rec( glyph, stream, gps_offset, + subglyph->gps_offset, + subglyph->gps_size ); + if ( error ) + break; + + /* note that `glyph->subs' might have been re-allocated */ + subglyph = glyph->subs + old_count + n; + num_points = base->n_points - old_points; + + /* translate and eventually scale the new glyph points */ + if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L ) + { + FT_Vector* vec = base->points + old_points; + + + for ( i = 0; i < num_points; i++, vec++ ) + { + vec->x = FT_MulFix( vec->x, subglyph->x_scale ) + + subglyph->x_delta; + vec->y = FT_MulFix( vec->y, subglyph->y_scale ) + + subglyph->y_delta; + } + } + else + { + FT_Vector* vec = loader->base.outline.points + old_points; + + + for ( i = 0; i < num_points; i++, vec++ ) + { + vec->x += subglyph->x_delta; + vec->y += subglyph->y_delta; + } + } + + /* proceed to next sub-glyph */ + } + + FT_TRACE4(( "end compound glyph with %d elements\n", count )); + } + else + { + FT_TRACE4(( "simple glyph (offset %lu)\n", offset )); + + /* load a simple glyph */ + error = pfr_glyph_load_simple( glyph, p, limit ); + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_glyph_load( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ) + { + /* initialize glyph loader */ + FT_GlyphLoader_Rewind( glyph->loader ); + + glyph->num_subs = 0; + + /* load the glyph, recursively when needed */ + return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size ); + } + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrgload.h b/drivers/freetype/src/pfr/pfrgload.h new file mode 100644 index 0000000000..7cc7a8702a --- /dev/null +++ b/drivers/freetype/src/pfr/pfrgload.h @@ -0,0 +1,49 @@ +/***************************************************************************/ +/* */ +/* pfrgload.h */ +/* */ +/* FreeType PFR glyph loader (specification). */ +/* */ +/* Copyright 2002 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 __PFRGLOAD_H__ +#define __PFRGLOAD_H__ + +#include "pfrtypes.h" + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + pfr_glyph_init( PFR_Glyph glyph, + FT_GlyphLoader loader ); + + FT_LOCAL( void ) + pfr_glyph_done( PFR_Glyph glyph ); + + + FT_LOCAL( FT_Error ) + pfr_glyph_load( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ); + + +FT_END_HEADER + + +#endif /* __PFRGLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrload.c b/drivers/freetype/src/pfr/pfrload.c new file mode 100644 index 0000000000..c19fceb1ee --- /dev/null +++ b/drivers/freetype/src/pfr/pfrload.c @@ -0,0 +1,941 @@ +/***************************************************************************/ +/* */ +/* pfrload.c */ +/* */ +/* FreeType PFR loader (body). */ +/* */ +/* Copyright 2002-2005, 2007, 2009, 2010, 2013 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 "pfrload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** EXTRA ITEMS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + pfr_extra_items_skip( FT_Byte* *pp, + FT_Byte* limit ) + { + return pfr_extra_items_parse( pp, limit, NULL, NULL ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_extra_items_parse( FT_Byte* *pp, + FT_Byte* limit, + PFR_ExtraItem item_list, + FT_Pointer item_data ) + { + FT_Error error = FT_Err_Ok; + FT_Byte* p = *pp; + FT_UInt num_items, item_type, item_size; + + + PFR_CHECK( 1 ); + num_items = PFR_NEXT_BYTE( p ); + + for ( ; num_items > 0; num_items-- ) + { + PFR_CHECK( 2 ); + item_size = PFR_NEXT_BYTE( p ); + item_type = PFR_NEXT_BYTE( p ); + + PFR_CHECK( item_size ); + + if ( item_list ) + { + PFR_ExtraItem extra = item_list; + + + for ( extra = item_list; extra->parser != NULL; extra++ ) + { + if ( extra->type == item_type ) + { + error = extra->parser( p, p + item_size, item_data ); + if ( error ) goto Exit; + + break; + } + } + } + + p += item_size; + } + + Exit: + *pp = p; + return error; + + Too_Short: + FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR HEADER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static const FT_Frame_Field pfr_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PFR_HeaderRec + + FT_FRAME_START( 58 ), + FT_FRAME_ULONG ( signature ), + FT_FRAME_USHORT( version ), + FT_FRAME_USHORT( signature2 ), + FT_FRAME_USHORT( header_size ), + + FT_FRAME_USHORT( log_dir_size ), + FT_FRAME_USHORT( log_dir_offset ), + + FT_FRAME_USHORT( log_font_max_size ), + FT_FRAME_UOFF3 ( log_font_section_size ), + FT_FRAME_UOFF3 ( log_font_section_offset ), + + FT_FRAME_USHORT( phy_font_max_size ), + FT_FRAME_UOFF3 ( phy_font_section_size ), + FT_FRAME_UOFF3 ( phy_font_section_offset ), + + FT_FRAME_USHORT( gps_max_size ), + FT_FRAME_UOFF3 ( gps_section_size ), + FT_FRAME_UOFF3 ( gps_section_offset ), + + FT_FRAME_BYTE ( max_blue_values ), + FT_FRAME_BYTE ( max_x_orus ), + FT_FRAME_BYTE ( max_y_orus ), + + FT_FRAME_BYTE ( phy_font_max_size_high ), + FT_FRAME_BYTE ( color_flags ), + + FT_FRAME_UOFF3 ( bct_max_size ), + FT_FRAME_UOFF3 ( bct_set_max_size ), + FT_FRAME_UOFF3 ( phy_bct_set_max_size ), + + FT_FRAME_USHORT( num_phy_fonts ), + FT_FRAME_BYTE ( max_vert_stem_snap ), + FT_FRAME_BYTE ( max_horz_stem_snap ), + FT_FRAME_USHORT( max_chars ), + FT_FRAME_END + }; + + + FT_LOCAL_DEF( FT_Error ) + pfr_header_load( PFR_Header header, + FT_Stream stream ) + { + FT_Error error; + + + /* read header directly */ + if ( !FT_STREAM_SEEK( 0 ) && + !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) ) + { + /* make a few adjustments to the header */ + header->phy_font_max_size += + (FT_UInt32)header->phy_font_max_size_high << 16; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Bool ) + pfr_header_check( PFR_Header header ) + { + FT_Bool result = 1; + + + /* check signature and header size */ + if ( header->signature != 0x50465230L || /* "PFR0" */ + header->version > 4 || + header->header_size < 58 || + header->signature2 != 0x0d0a ) /* CR/LF */ + { + result = 0; + } + return result; + } + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR LOGICAL FONTS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + pfr_log_font_count( FT_Stream stream, + FT_UInt32 section_offset, + FT_UInt *acount ) + { + FT_Error error; + FT_UInt count; + FT_UInt result = 0; + + + if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) + goto Exit; + + result = count; + + Exit: + *acount = result; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_log_font_load( PFR_LogFont log_font, + FT_Stream stream, + FT_UInt idx, + FT_UInt32 section_offset, + FT_Bool size_increment ) + { + FT_UInt num_log_fonts; + FT_UInt flags; + FT_UInt32 offset; + FT_UInt32 size; + FT_Error error; + + + if ( FT_STREAM_SEEK( section_offset ) || + FT_READ_USHORT( num_log_fonts ) ) + goto Exit; + + if ( idx >= num_log_fonts ) + return FT_THROW( Invalid_Argument ); + + if ( FT_STREAM_SKIP( idx * 5 ) || + FT_READ_USHORT( size ) || + FT_READ_UOFF3 ( offset ) ) + goto Exit; + + /* save logical font size and offset */ + log_font->size = size; + log_font->offset = offset; + + /* now, check the rest of the table before loading it */ + { + FT_Byte* p; + FT_Byte* limit; + FT_UInt local; + + + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + goto Exit; + + p = stream->cursor; + limit = p + size; + + PFR_CHECK(13); + + log_font->matrix[0] = PFR_NEXT_LONG( p ); + log_font->matrix[1] = PFR_NEXT_LONG( p ); + log_font->matrix[2] = PFR_NEXT_LONG( p ); + log_font->matrix[3] = PFR_NEXT_LONG( p ); + + flags = PFR_NEXT_BYTE( p ); + + local = 0; + if ( flags & PFR_LOG_STROKE ) + { + local++; + if ( flags & PFR_LOG_2BYTE_STROKE ) + local++; + + if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) + local += 3; + } + if ( flags & PFR_LOG_BOLD ) + { + local++; + if ( flags & PFR_LOG_2BYTE_BOLD ) + local++; + } + + PFR_CHECK( local ); + + if ( flags & PFR_LOG_STROKE ) + { + log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE ) + ? PFR_NEXT_SHORT( p ) + : PFR_NEXT_BYTE( p ); + + if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) + log_font->miter_limit = PFR_NEXT_LONG( p ); + } + + if ( flags & PFR_LOG_BOLD ) + { + log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD ) + ? PFR_NEXT_SHORT( p ) + : PFR_NEXT_BYTE( p ); + } + + if ( flags & PFR_LOG_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Fail; + } + + PFR_CHECK(5); + log_font->phys_size = PFR_NEXT_USHORT( p ); + log_font->phys_offset = PFR_NEXT_ULONG( p ); + if ( size_increment ) + { + PFR_CHECK( 1 ); + log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16; + } + } + + Fail: + FT_FRAME_EXIT(); + + Exit: + return error; + + Too_Short: + FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" )); + error = FT_THROW( Invalid_Table ); + goto Fail; + } + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR PHYSICAL FONTS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + /* load bitmap strikes lists */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_bitmap_info( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Memory memory = phy_font->memory; + PFR_Strike strike; + FT_UInt flags0; + FT_UInt n, count, size1; + FT_Error error = FT_Err_Ok; + + + PFR_CHECK( 5 ); + + p += 3; /* skip bctSize */ + flags0 = PFR_NEXT_BYTE( p ); + count = PFR_NEXT_BYTE( p ); + + /* re-allocate when needed */ + if ( phy_font->num_strikes + count > phy_font->max_strikes ) + { + FT_UInt new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 ); + + + if ( FT_RENEW_ARRAY( phy_font->strikes, + phy_font->num_strikes, + new_max ) ) + goto Exit; + + phy_font->max_strikes = new_max; + } + + size1 = 1 + 1 + 1 + 2 + 2 + 1; + if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) + size1++; + + if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) + size1++; + + if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) + size1++; + + if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) + size1++; + + if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) + size1++; + + strike = phy_font->strikes + phy_font->num_strikes; + + PFR_CHECK( count * size1 ); + + for ( n = 0; n < count; n++, strike++ ) + { + strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + strike->flags = PFR_NEXT_BYTE( p ); + + strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + + strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + + strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + } + + phy_font->num_strikes += count; + + Exit: + return error; + + Too_Short: + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_extra_item_load_bitmap_info:" + " invalid bitmap info table\n" )); + goto Exit; + } + + + /* Load font ID. This is a so-called "unique" name that is rather + * long and descriptive (like "Tiresias ScreenFont v7.51"). + * + * Note that a PFR font's family name is contained in an *undocumented* + * string of the "auxiliary data" portion of a physical font record. This + * may also contain the "real" style name! + * + * If no family name is present, the font ID is used instead for the + * family. + */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_font_id( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = phy_font->memory; + FT_PtrDist len = limit - p; + + + if ( phy_font->font_id != NULL ) + goto Exit; + + if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) + goto Exit; + + /* copy font ID name, and terminate it for safety */ + FT_MEM_COPY( phy_font->font_id, p, len ); + phy_font->font_id[len] = 0; + + Exit: + return error; + } + + + /* load stem snap tables */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_stem_snaps( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_UInt count, num_vert, num_horz; + FT_Int* snaps = NULL; + FT_Error error = FT_Err_Ok; + FT_Memory memory = phy_font->memory; + + + if ( phy_font->vertical.stem_snaps != NULL ) + goto Exit; + + PFR_CHECK( 1 ); + count = PFR_NEXT_BYTE( p ); + + num_vert = count & 15; + num_horz = count >> 4; + count = num_vert + num_horz; + + PFR_CHECK( count * 2 ); + + if ( FT_NEW_ARRAY( snaps, count ) ) + goto Exit; + + phy_font->vertical.stem_snaps = snaps; + phy_font->horizontal.stem_snaps = snaps + num_vert; + + for ( ; count > 0; count--, snaps++ ) + *snaps = FT_NEXT_SHORT( p ); + + Exit: + return error; + + Too_Short: + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_exta_item_load_stem_snaps:" + " invalid stem snaps table\n" )); + goto Exit; + } + + + + /* load kerning pair data */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_kerning_pairs( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + PFR_KernItem item = NULL; + FT_Error error = FT_Err_Ok; + FT_Memory memory = phy_font->memory; + + + FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); + + if ( FT_NEW( item ) ) + goto Exit; + + PFR_CHECK( 4 ); + + item->pair_count = PFR_NEXT_BYTE( p ); + item->base_adj = PFR_NEXT_SHORT( p ); + item->flags = PFR_NEXT_BYTE( p ); + item->offset = phy_font->offset + ( p - phy_font->cursor ); + +#ifndef PFR_CONFIG_NO_CHECKS + item->pair_size = 3; + + if ( item->flags & PFR_KERN_2BYTE_CHAR ) + item->pair_size += 2; + + if ( item->flags & PFR_KERN_2BYTE_ADJ ) + item->pair_size += 1; + + PFR_CHECK( item->pair_count * item->pair_size ); +#endif + + /* load first and last pairs into the item to speed up */ + /* lookup later... */ + if ( item->pair_count > 0 ) + { + FT_UInt char1, char2; + FT_Byte* q; + + + if ( item->flags & PFR_KERN_2BYTE_CHAR ) + { + q = p; + char1 = PFR_NEXT_USHORT( q ); + char2 = PFR_NEXT_USHORT( q ); + + item->pair1 = PFR_KERN_INDEX( char1, char2 ); + + q = p + item->pair_size * ( item->pair_count - 1 ); + char1 = PFR_NEXT_USHORT( q ); + char2 = PFR_NEXT_USHORT( q ); + + item->pair2 = PFR_KERN_INDEX( char1, char2 ); + } + else + { + q = p; + char1 = PFR_NEXT_BYTE( q ); + char2 = PFR_NEXT_BYTE( q ); + + item->pair1 = PFR_KERN_INDEX( char1, char2 ); + + q = p + item->pair_size * ( item->pair_count - 1 ); + char1 = PFR_NEXT_BYTE( q ); + char2 = PFR_NEXT_BYTE( q ); + + item->pair2 = PFR_KERN_INDEX( char1, char2 ); + } + + /* add new item to the current list */ + item->next = NULL; + *phy_font->kern_items_tail = item; + phy_font->kern_items_tail = &item->next; + phy_font->num_kern_pairs += item->pair_count; + } + else + { + /* empty item! */ + FT_FREE( item ); + } + + Exit: + return error; + + Too_Short: + FT_FREE( item ); + + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_extra_item_load_kerning_pairs:" + " invalid kerning pairs table\n" )); + goto Exit; + } + + + + static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = + { + { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, + { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id }, + { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps }, + { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs }, + { 0, NULL } + }; + + + /* Loads a name from the auxiliary data. Since this extracts undocumented + * strings from the font file, we need to be careful here. + */ + static FT_Error + pfr_aux_name_load( FT_Byte* p, + FT_UInt len, + FT_Memory memory, + FT_String* *astring ) + { + FT_Error error = FT_Err_Ok; + FT_String* result = NULL; + FT_UInt n, ok; + + + if ( len > 0 && p[len - 1] == 0 ) + len--; + + /* check that each character is ASCII for making sure not to + load garbage + */ + ok = ( len > 0 ); + for ( n = 0; n < len; n++ ) + if ( p[n] < 32 || p[n] > 127 ) + { + ok = 0; + break; + } + + if ( ok ) + { + if ( FT_ALLOC( result, len + 1 ) ) + goto Exit; + + FT_MEM_COPY( result, p, len ); + result[len] = 0; + } + Exit: + *astring = result; + return error; + } + + + FT_LOCAL_DEF( void ) + pfr_phy_font_done( PFR_PhyFont phy_font, + FT_Memory memory ) + { + FT_FREE( phy_font->font_id ); + FT_FREE( phy_font->family_name ); + FT_FREE( phy_font->style_name ); + + FT_FREE( phy_font->vertical.stem_snaps ); + phy_font->vertical.num_stem_snaps = 0; + + phy_font->horizontal.stem_snaps = NULL; + phy_font->horizontal.num_stem_snaps = 0; + + FT_FREE( phy_font->strikes ); + phy_font->num_strikes = 0; + phy_font->max_strikes = 0; + + FT_FREE( phy_font->chars ); + phy_font->num_chars = 0; + phy_font->chars_offset = 0; + + FT_FREE( phy_font->blue_values ); + phy_font->num_blue_values = 0; + + { + PFR_KernItem item, next; + + + item = phy_font->kern_items; + while ( item ) + { + next = item->next; + FT_FREE( item ); + item = next; + } + phy_font->kern_items = NULL; + phy_font->kern_items_tail = NULL; + } + + phy_font->num_kern_pairs = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_phy_font_load( PFR_PhyFont phy_font, + FT_Stream stream, + FT_UInt32 offset, + FT_UInt32 size ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UInt flags; + FT_ULong num_aux; + FT_Byte* p; + FT_Byte* limit; + + + phy_font->memory = memory; + phy_font->offset = offset; + + phy_font->kern_items = NULL; + phy_font->kern_items_tail = &phy_font->kern_items; + + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + goto Exit; + + phy_font->cursor = stream->cursor; + + p = stream->cursor; + limit = p + size; + + PFR_CHECK( 15 ); + phy_font->font_ref_number = PFR_NEXT_USHORT( p ); + phy_font->outline_resolution = PFR_NEXT_USHORT( p ); + phy_font->metrics_resolution = PFR_NEXT_USHORT( p ); + phy_font->bbox.xMin = PFR_NEXT_SHORT( p ); + phy_font->bbox.yMin = PFR_NEXT_SHORT( p ); + phy_font->bbox.xMax = PFR_NEXT_SHORT( p ); + phy_font->bbox.yMax = PFR_NEXT_SHORT( p ); + phy_font->flags = flags = PFR_NEXT_BYTE( p ); + + /* get the standard advance for non-proportional fonts */ + if ( !(flags & PFR_PHY_PROPORTIONAL) ) + { + PFR_CHECK( 2 ); + phy_font->standard_advance = PFR_NEXT_SHORT( p ); + } + + /* load the extra items when present */ + if ( flags & PFR_PHY_EXTRA_ITEMS ) + { + error = pfr_extra_items_parse( &p, limit, + pfr_phy_font_extra_items, phy_font ); + + if ( error ) + goto Fail; + } + + /* In certain fonts, the auxiliary bytes contain interesting */ + /* information. These are not in the specification but can be */ + /* guessed by looking at the content of a few PFR0 fonts. */ + PFR_CHECK( 3 ); + num_aux = PFR_NEXT_ULONG( p ); + + if ( num_aux > 0 ) + { + FT_Byte* q = p; + FT_Byte* q2; + + + PFR_CHECK( num_aux ); + p += num_aux; + + while ( num_aux > 0 ) + { + FT_UInt length, type; + + + if ( q + 4 > p ) + break; + + length = PFR_NEXT_USHORT( q ); + if ( length < 4 || length > num_aux ) + break; + + q2 = q + length - 2; + type = PFR_NEXT_USHORT( q ); + + switch ( type ) + { + case 1: + /* this seems to correspond to the font's family name, + * padded to 16-bits with one zero when necessary + */ + error = pfr_aux_name_load( q, length - 4U, memory, + &phy_font->family_name ); + if ( error ) + goto Exit; + break; + + case 2: + if ( q + 32 > q2 ) + break; + + q += 10; + phy_font->ascent = PFR_NEXT_SHORT( q ); + phy_font->descent = PFR_NEXT_SHORT( q ); + phy_font->leading = PFR_NEXT_SHORT( q ); + q += 16; + break; + + case 3: + /* this seems to correspond to the font's style name, + * padded to 16-bits with one zero when necessary + */ + error = pfr_aux_name_load( q, length - 4U, memory, + &phy_font->style_name ); + if ( error ) + goto Exit; + break; + + default: + ; + } + + q = q2; + num_aux -= length; + } + } + + /* read the blue values */ + { + FT_UInt n, count; + + + PFR_CHECK( 1 ); + phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); + + PFR_CHECK( count * 2 ); + + if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + phy_font->blue_values[n] = PFR_NEXT_SHORT( p ); + } + + PFR_CHECK( 8 ); + phy_font->blue_fuzz = PFR_NEXT_BYTE( p ); + phy_font->blue_scale = PFR_NEXT_BYTE( p ); + + phy_font->vertical.standard = PFR_NEXT_USHORT( p ); + phy_font->horizontal.standard = PFR_NEXT_USHORT( p ); + + /* read the character descriptors */ + { + FT_UInt n, count, Size; + + + phy_font->num_chars = count = PFR_NEXT_USHORT( p ); + phy_font->chars_offset = offset + ( p - stream->cursor ); + + if ( FT_NEW_ARRAY( phy_font->chars, count ) ) + goto Fail; + + Size = 1 + 1 + 2; + if ( flags & PFR_PHY_2BYTE_CHARCODE ) + Size += 1; + + if ( flags & PFR_PHY_PROPORTIONAL ) + Size += 2; + + if ( flags & PFR_PHY_ASCII_CODE ) + Size += 1; + + if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) + Size += 1; + + if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) + Size += 1; + + PFR_CHECK( count * Size ); + + for ( n = 0; n < count; n++ ) + { + PFR_Char cur = &phy_font->chars[n]; + + + cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) + ? PFR_NEXT_SHORT( p ) + : (FT_Int) phy_font->standard_advance; + +#if 0 + cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) + ? PFR_NEXT_BYTE( p ) + : 0; +#else + if ( flags & PFR_PHY_ASCII_CODE ) + p += 1; +#endif + cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + } + } + + /* that's it! */ + + Fail: + FT_FRAME_EXIT(); + + /* save position of bitmap info */ + phy_font->bct_offset = FT_STREAM_POS(); + phy_font->cursor = NULL; + + Exit: + return error; + + Too_Short: + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); + goto Fail; + } + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrload.h b/drivers/freetype/src/pfr/pfrload.h new file mode 100644 index 0000000000..ed010715d1 --- /dev/null +++ b/drivers/freetype/src/pfr/pfrload.h @@ -0,0 +1,118 @@ +/***************************************************************************/ +/* */ +/* pfrload.h */ +/* */ +/* FreeType PFR loader (specification). */ +/* */ +/* Copyright 2002 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 __PFRLOAD_H__ +#define __PFRLOAD_H__ + +#include "pfrobjs.h" +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + +#ifdef PFR_CONFIG_NO_CHECKS +#define PFR_CHECK( x ) do { } while ( 0 ) +#else +#define PFR_CHECK( x ) do \ + { \ + if ( p + (x) > limit ) \ + goto Too_Short; \ + } while ( 0 ) +#endif + +#define PFR_NEXT_BYTE( p ) FT_NEXT_BYTE( p ) +#define PFR_NEXT_INT8( p ) FT_NEXT_CHAR( p ) +#define PFR_NEXT_SHORT( p ) FT_NEXT_SHORT( p ) +#define PFR_NEXT_USHORT( p ) FT_NEXT_USHORT( p ) +#define PFR_NEXT_LONG( p ) FT_NEXT_OFF3( p ) +#define PFR_NEXT_ULONG( p ) FT_NEXT_UOFF3( p ) + + + /* handling extra items */ + + typedef FT_Error + (*PFR_ExtraItem_ParseFunc)( FT_Byte* p, + FT_Byte* limit, + FT_Pointer data ); + + typedef struct PFR_ExtraItemRec_ + { + 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, + FT_Byte* limit ); + + FT_LOCAL( FT_Error ) + pfr_extra_items_parse( FT_Byte* *pp, + FT_Byte* limit, + PFR_ExtraItem item_list, + FT_Pointer item_data ); + + + /* load a PFR header */ + FT_LOCAL( FT_Error ) + pfr_header_load( PFR_Header header, + FT_Stream stream ); + + /* check a PFR header */ + FT_LOCAL( FT_Bool ) + pfr_header_check( PFR_Header header ); + + + /* return number of logical fonts in this file */ + FT_LOCAL( FT_Error ) + pfr_log_font_count( FT_Stream stream, + FT_UInt32 log_section_offset, + FT_UInt *acount ); + + /* load a pfr logical font entry */ + FT_LOCAL( FT_Error ) + pfr_log_font_load( PFR_LogFont log_font, + FT_Stream stream, + FT_UInt face_index, + FT_UInt32 section_offset, + FT_Bool size_increment ); + + + /* load a physical font entry */ + FT_LOCAL( FT_Error ) + pfr_phy_font_load( PFR_PhyFont phy_font, + FT_Stream stream, + FT_UInt32 offset, + FT_UInt32 size ); + + /* finalize a physical font */ + FT_LOCAL( void ) + pfr_phy_font_done( PFR_PhyFont phy_font, + FT_Memory memory ); + + /* */ + +FT_END_HEADER + +#endif /* __PFRLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrobjs.c b/drivers/freetype/src/pfr/pfrobjs.c new file mode 100644 index 0000000000..75fc4c3f1f --- /dev/null +++ b/drivers/freetype/src/pfr/pfrobjs.c @@ -0,0 +1,593 @@ +/***************************************************************************/ +/* */ +/* pfrobjs.c */ +/* */ +/* FreeType PFR object methods (body). */ +/* */ +/* Copyright 2002-2008, 2010-2011, 2013 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 "pfrobjs.h" +#include "pfrload.h" +#include "pfrgload.h" +#include "pfrcmap.h" +#include "pfrsbit.h" +#include FT_OUTLINE_H +#include FT_INTERNAL_DEBUG_H +#include FT_TRUETYPE_IDS_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FACE OBJECT METHODS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + pfr_face_done( FT_Face pfrface ) /* PFR_Face */ + { + PFR_Face face = (PFR_Face)pfrface; + FT_Memory memory; + + + if ( !face ) + return; + + memory = pfrface->driver->root.memory; + + /* we don't want dangling pointers */ + pfrface->family_name = NULL; + pfrface->style_name = NULL; + + /* finalize the physical font record */ + pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); + + /* no need to finalize the logical font or the header */ + FT_FREE( pfrface->available_sizes ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_face_init( FT_Stream stream, + FT_Face pfrface, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + PFR_Face face = (PFR_Face)pfrface; + FT_Error error; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + FT_TRACE2(( "PFR driver\n" )); + + /* load the header and check it */ + error = pfr_header_load( &face->header, stream ); + if ( error ) + goto Exit; + + if ( !pfr_header_check( &face->header ) ) + { + FT_TRACE2(( " not a PFR font\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* check face index */ + { + FT_UInt num_faces; + + + error = pfr_log_font_count( stream, + face->header.log_dir_offset, + &num_faces ); + if ( error ) + goto Exit; + + pfrface->num_faces = num_faces; + } + + if ( face_index < 0 ) + goto Exit; + + if ( face_index >= pfrface->num_faces ) + { + FT_ERROR(( "pfr_face_init: invalid face index\n" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* load the face */ + error = pfr_log_font_load( + &face->log_font, stream, face_index, + face->header.log_dir_offset, + FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); + if ( error ) + goto Exit; + + /* now load the physical font descriptor */ + error = pfr_phy_font_load( &face->phy_font, stream, + face->log_font.phys_offset, + face->log_font.phys_size ); + if ( error ) + goto Exit; + + /* 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 + 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 ) + { + if ( phy_font->num_strikes > 0 ) + pfrface->face_flags = 0; /* not scalable */ + else + { + FT_ERROR(( "pfr_face_init: font doesn't contain glyphs\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + } + + if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( phy_font->flags & PFR_PHY_VERTICAL ) + pfrface->face_flags |= FT_FACE_FLAG_VERTICAL; + else + pfrface->face_flags |= FT_FACE_FLAG_HORIZONTAL; + + if ( phy_font->num_strikes > 0 ) + pfrface->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + + if ( phy_font->num_kern_pairs > 0 ) + pfrface->face_flags |= FT_FACE_FLAG_KERNING; + + /* If no family name was found in the "undocumented" auxiliary + * data, use the font ID instead. This sucks but is better than + * nothing. + */ + pfrface->family_name = phy_font->family_name; + if ( pfrface->family_name == NULL ) + pfrface->family_name = phy_font->font_id; + + /* note that the style name can be NULL in certain PFR fonts, + * probably meaning "Regular" + */ + pfrface->style_name = phy_font->style_name; + + pfrface->num_fixed_sizes = 0; + pfrface->available_sizes = 0; + + pfrface->bbox = phy_font->bbox; + pfrface->units_per_EM = (FT_UShort)phy_font->outline_resolution; + pfrface->ascender = (FT_Short) phy_font->bbox.yMax; + pfrface->descender = (FT_Short) phy_font->bbox.yMin; + + pfrface->height = (FT_Short)( ( pfrface->units_per_EM * 12 ) / 10 ); + if ( pfrface->height < pfrface->ascender - pfrface->descender ) + pfrface->height = (FT_Short)(pfrface->ascender - pfrface->descender); + + if ( phy_font->num_strikes > 0 ) + { + FT_UInt n, count = phy_font->num_strikes; + FT_Bitmap_Size* size; + PFR_Strike strike; + FT_Memory memory = pfrface->stream->memory; + + + if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) ) + goto Exit; + + size = pfrface->available_sizes; + strike = phy_font->strikes; + for ( n = 0; n < count; n++, size++, strike++ ) + { + size->height = (FT_UShort)strike->y_ppm; + size->width = (FT_UShort)strike->x_ppm; + size->size = strike->y_ppm << 6; + size->x_ppem = strike->x_ppm << 6; + size->y_ppem = strike->y_ppm << 6; + } + pfrface->num_fixed_sizes = count; + } + + /* now compute maximum advance width */ + if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) + pfrface->max_advance_width = (FT_Short)phy_font->standard_advance; + else + { + FT_Int max = 0; + FT_UInt count = phy_font->num_chars; + PFR_Char gchar = phy_font->chars; + + + for ( ; count > 0; count--, gchar++ ) + { + if ( max < gchar->advance ) + max = gchar->advance; + } + + pfrface->max_advance_width = (FT_Short)max; + } + + pfrface->max_advance_height = pfrface->height; + + pfrface->underline_position = (FT_Short)( -pfrface->units_per_EM / 10 ); + pfrface->underline_thickness = (FT_Short)( pfrface->units_per_EM / 30 ); + + /* create charmap */ + { + FT_CharMapRec charmap; + + + charmap.face = pfrface; + charmap.platform_id = TT_PLATFORM_MICROSOFT; + charmap.encoding_id = TT_MS_ID_UNICODE_CS; + charmap.encoding = FT_ENCODING_UNICODE; + + error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if ( pfrface->num_charmaps ) + pfrface->charmap = pfrface->charmaps[0]; +#endif + } + + /* check whether we've loaded any kerning pairs */ + if ( phy_font->num_kern_pairs ) + pfrface->face_flags |= FT_FACE_FLAG_KERNING; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SLOT OBJECT METHOD *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + pfr_slot_init( FT_GlyphSlot pfrslot ) /* PFR_Slot */ + { + PFR_Slot slot = (PFR_Slot)pfrslot; + FT_GlyphLoader loader = pfrslot->internal->loader; + + + pfr_glyph_init( &slot->glyph, loader ); + + return 0; + } + + + FT_LOCAL_DEF( void ) + pfr_slot_done( FT_GlyphSlot pfrslot ) /* PFR_Slot */ + { + PFR_Slot slot = (PFR_Slot)pfrslot; + + + pfr_glyph_done( &slot->glyph ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_slot_load( FT_GlyphSlot pfrslot, /* PFR_Slot */ + FT_Size pfrsize, /* PFR_Size */ + FT_UInt gindex, + FT_Int32 load_flags ) + { + PFR_Slot slot = (PFR_Slot)pfrslot; + PFR_Size size = (PFR_Size)pfrsize; + FT_Error error; + PFR_Face face = (PFR_Face)pfrslot->face; + PFR_Char gchar; + FT_Outline* outline = &pfrslot->outline; + FT_ULong gps_offset; + + + if ( gindex > 0 ) + gindex--; + + if ( !face || gindex >= face->phy_font.num_chars ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* try to load an embedded bitmap */ + if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) + { + error = pfr_slot_load_bitmap( slot, size, gindex ); + if ( error == 0 ) + goto Exit; + } + + if ( load_flags & FT_LOAD_SBITS_ONLY ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + gchar = face->phy_font.chars + gindex; + pfrslot->format = FT_GLYPH_FORMAT_OUTLINE; + outline->n_points = 0; + outline->n_contours = 0; + gps_offset = face->header.gps_section_offset; + + /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */ + error = pfr_glyph_load( &slot->glyph, face->root.stream, + gps_offset, gchar->gps_offset, gchar->gps_size ); + + if ( !error ) + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &pfrslot->metrics; + FT_Pos advance; + FT_Int em_metrics, em_outline; + FT_Bool scaling; + + + scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); + + /* copy outline data */ + *outline = slot->glyph.loader->base.outline; + + outline->flags &= ~FT_OUTLINE_OWNER; + outline->flags |= FT_OUTLINE_REVERSE_FILL; + + if ( size && pfrsize->metrics.y_ppem < 24 ) + outline->flags |= FT_OUTLINE_HIGH_PRECISION; + + /* compute the advance vector */ + metrics->horiAdvance = 0; + metrics->vertAdvance = 0; + + advance = gchar->advance; + em_metrics = face->phy_font.metrics_resolution; + em_outline = face->phy_font.outline_resolution; + + if ( em_metrics != em_outline ) + advance = FT_MulDiv( advance, em_outline, em_metrics ); + + if ( face->phy_font.flags & PFR_PHY_VERTICAL ) + metrics->vertAdvance = advance; + else + metrics->horiAdvance = advance; + + pfrslot->linearHoriAdvance = metrics->horiAdvance; + pfrslot->linearVertAdvance = metrics->vertAdvance; + + /* make-up vertical metrics(?) */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + +#if 0 /* some fonts seem to be broken here! */ + + /* Apply the font matrix, if any. */ + /* TODO: Test existing fonts with unusual matrix */ + /* whether we have to adjust Units per EM. */ + { + FT_Matrix font_matrix; + + + font_matrix.xx = face->log_font.matrix[0] << 8; + font_matrix.yx = face->log_font.matrix[1] << 8; + font_matrix.xy = face->log_font.matrix[2] << 8; + font_matrix.yy = face->log_font.matrix[3] << 8; + + FT_Outline_Transform( outline, &font_matrix ); + } +#endif + + /* scale when needed */ + if ( scaling ) + { + FT_Int n; + FT_Fixed x_scale = pfrsize->metrics.x_scale; + FT_Fixed y_scale = pfrsize->metrics.y_scale; + FT_Vector* vec = outline->points; + + + /* scale outline points */ + for ( n = 0; n < outline->n_points; n++, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* scale the advance */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + } + + /* compute the rest of the metrics */ + FT_Outline_Get_CBox( outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax - metrics->height; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** KERNING METHOD *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ) + { + PFR_Face face = (PFR_Face)pfrface; + FT_Error error = FT_Err_Ok; + PFR_PhyFont phy_font = &face->phy_font; + FT_UInt32 code1, code2, pair; + + + kerning->x = 0; + kerning->y = 0; + + if ( glyph1 > 0 ) + glyph1--; + + if ( glyph2 > 0 ) + glyph2--; + + /* convert glyph indices to character codes */ + if ( glyph1 > phy_font->num_chars || + glyph2 > phy_font->num_chars ) + goto Exit; + + code1 = phy_font->chars[glyph1].char_code; + code2 = phy_font->chars[glyph2].char_code; + pair = PFR_KERN_INDEX( code1, code2 ); + + /* now search the list of kerning items */ + { + PFR_KernItem item = phy_font->kern_items; + FT_Stream stream = pfrface->stream; + + + for ( ; item; item = item->next ) + { + if ( pair >= item->pair1 && pair <= item->pair2 ) + goto FoundPair; + } + goto Exit; + + FoundPair: /* we found an item, now parse it and find the value if any */ + if ( FT_STREAM_SEEK( item->offset ) || + FT_FRAME_ENTER( item->pair_count * item->pair_size ) ) + 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_Bool twobyte_adj = FT_BOOL( item->flags & 2 ); + FT_Byte* p; + FT_UInt32 cpair; + + + if ( extra > 0 ) + { + p = base + extra * size; + + if ( twobytes ) + cpair = FT_NEXT_ULONG( p ); + else + cpair = PFR_NEXT_KPAIR( p ); + + if ( cpair == pair ) + goto Found; + + if ( cpair < pair ) + { + if ( twobyte_adj ) + p += 2; + else + p++; + base = p; + } + } + + while ( probe > size ) + { + probe >>= 1; + p = base + probe; + + if ( twobytes ) + cpair = FT_NEXT_ULONG( p ); + else + cpair = PFR_NEXT_KPAIR( p ); + + if ( cpair == pair ) + goto Found; + + if ( cpair < pair ) + base += probe; + } + + p = base; + + if ( twobytes ) + cpair = FT_NEXT_ULONG( p ); + else + cpair = PFR_NEXT_KPAIR( p ); + + if ( cpair == pair ) + { + FT_Int value; + + + Found: + if ( twobyte_adj ) + value = FT_PEEK_SHORT( p ); + else + value = p[0]; + + kerning->x = item->base_adj + value; + } + } + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrobjs.h b/drivers/freetype/src/pfr/pfrobjs.h new file mode 100644 index 0000000000..f6aa8b44cc --- /dev/null +++ b/drivers/freetype/src/pfr/pfrobjs.h @@ -0,0 +1,96 @@ +/***************************************************************************/ +/* */ +/* pfrobjs.h */ +/* */ +/* FreeType PFR object methods (specification). */ +/* */ +/* Copyright 2002, 2003, 2004 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 __PFROBJS_H__ +#define __PFROBJS_H__ + +#include "pfrtypes.h" + + +FT_BEGIN_HEADER + + typedef struct PFR_FaceRec_* PFR_Face; + + typedef struct PFR_SizeRec_* PFR_Size; + + typedef struct PFR_SlotRec_* PFR_Slot; + + + typedef struct PFR_FaceRec_ + { + FT_FaceRec root; + PFR_HeaderRec header; + PFR_LogFontRec log_font; + PFR_PhyFontRec phy_font; + + } PFR_FaceRec; + + + typedef struct PFR_SizeRec_ + { + FT_SizeRec root; + + } PFR_SizeRec; + + + typedef struct PFR_SlotRec_ + { + FT_GlyphSlotRec root; + PFR_GlyphRec glyph; + + } PFR_SlotRec; + + + FT_LOCAL( FT_Error ) + pfr_face_init( FT_Stream stream, + FT_Face face, /* PFR_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + pfr_face_done( FT_Face face ); /* PFR_Face */ + + + FT_LOCAL( FT_Error ) + pfr_face_get_kerning( FT_Face face, /* PFR_Face */ + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ); + + + FT_LOCAL( FT_Error ) + pfr_slot_init( FT_GlyphSlot slot ); /* PFR_Slot */ + + FT_LOCAL( void ) + pfr_slot_done( FT_GlyphSlot slot ); /* PFR_Slot */ + + + FT_LOCAL( FT_Error ) + pfr_slot_load( FT_GlyphSlot slot, /* PFR_Slot */ + FT_Size size, /* PFR_Size */ + FT_UInt gindex, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __PFROBJS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrsbit.c b/drivers/freetype/src/pfr/pfrsbit.c new file mode 100644 index 0000000000..2da1500707 --- /dev/null +++ b/drivers/freetype/src/pfr/pfrsbit.c @@ -0,0 +1,698 @@ +/***************************************************************************/ +/* */ +/* pfrsbit.c */ +/* */ +/* FreeType PFR bitmap loader (body). */ +/* */ +/* Copyright 2002, 2003, 2006, 2009, 2010, 2013 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 "pfrsbit.h" +#include "pfrload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR BIT WRITER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PFR_BitWriter_ + { + FT_Byte* line; /* current line start */ + FT_Int pitch; /* line size in bytes */ + FT_Int width; /* width in pixels/bits */ + FT_Int rows; /* number of remaining rows to scan */ + FT_Int total; /* total number of bits to draw */ + + } PFR_BitWriterRec, *PFR_BitWriter; + + + static void + pfr_bitwriter_init( PFR_BitWriter writer, + FT_Bitmap* target, + FT_Bool decreasing ) + { + writer->line = target->buffer; + writer->pitch = target->pitch; + writer->width = target->width; + writer->rows = target->rows; + writer->total = writer->width * writer->rows; + + if ( !decreasing ) + { + writer->line += writer->pitch * ( target->rows-1 ); + writer->pitch = -writer->pitch; + } + } + + + static void + pfr_bitwriter_decode_bytes( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt val = 0; + FT_UInt c = 0; + + + n = (FT_Int)( limit - p ) * 8; + if ( n > writer->total ) + n = writer->total; + + reload = n & 7; + + for ( ; n > 0; n-- ) + { + if ( ( n & 7 ) == reload ) + val = *p++; + + if ( val & 0x80 ) + c |= mask; + + val <<= 1; + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte)c; + left = writer->width; + mask = 0x80; + + writer->line += writer->pitch; + cur = writer->line; + c = 0; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte)c; + mask = 0x80; + c = 0; + cur ++; + } + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte)c; + } + + + static void + pfr_bitwriter_decode_rle1( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, phase, count, counts[2], reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt c = 0; + + + n = writer->total; + + phase = 1; + counts[0] = 0; + counts[1] = 0; + count = 0; + reload = 1; + + for ( ; n > 0; n-- ) + { + if ( reload ) + { + do + { + if ( phase ) + { + FT_Int v; + + + if ( p >= limit ) + break; + + v = *p++; + counts[0] = v >> 4; + counts[1] = v & 15; + phase = 0; + count = counts[0]; + } + else + { + phase = 1; + count = counts[1]; + } + + } while ( count == 0 ); + } + + if ( phase ) + c |= mask; + + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte) c; + left = writer->width; + mask = 0x80; + + writer->line += writer->pitch; + cur = writer->line; + c = 0; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte)c; + mask = 0x80; + c = 0; + cur ++; + } + + reload = ( --count <= 0 ); + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte) c; + } + + + static void + pfr_bitwriter_decode_rle2( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, phase, count, reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt c = 0; + + + n = writer->total; + + phase = 1; + count = 0; + reload = 1; + + for ( ; n > 0; n-- ) + { + if ( reload ) + { + do + { + if ( p >= limit ) + break; + + count = *p++; + phase = phase ^ 1; + + } while ( count == 0 ); + } + + if ( phase ) + c |= mask; + + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte) c; + c = 0; + mask = 0x80; + left = writer->width; + + writer->line += writer->pitch; + cur = writer->line; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte)c; + c = 0; + mask = 0x80; + cur ++; + } + + reload = ( --count <= 0 ); + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte) c; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BITMAP DATA DECODING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + pfr_lookup_bitmap_data( FT_Byte* base, + FT_Byte* limit, + FT_UInt count, + FT_UInt flags, + FT_UInt char_code, + FT_ULong* found_offset, + FT_ULong* found_size ) + { + FT_UInt left, right, char_len; + FT_Bool two = FT_BOOL( flags & 1 ); + FT_Byte* buff; + + + char_len = 4; + if ( two ) char_len += 1; + if ( flags & 2 ) char_len += 1; + if ( flags & 4 ) char_len += 1; + + left = 0; + right = count; + + while ( left < right ) + { + FT_UInt middle, code; + + + middle = ( left + right ) >> 1; + buff = base + middle * char_len; + + /* check that we are not outside of the table -- */ + /* this is possible with broken fonts... */ + if ( buff + char_len > limit ) + goto Fail; + + if ( two ) + code = PFR_NEXT_USHORT( buff ); + else + code = PFR_NEXT_BYTE( buff ); + + if ( code == char_code ) + goto Found_It; + + if ( code < char_code ) + left = middle; + else + right = middle; + } + + Fail: + /* Not found */ + *found_size = 0; + *found_offset = 0; + return; + + Found_It: + if ( flags & 2 ) + *found_size = PFR_NEXT_USHORT( buff ); + else + *found_size = PFR_NEXT_BYTE( buff ); + + if ( flags & 4 ) + *found_offset = PFR_NEXT_ULONG( buff ); + else + *found_offset = PFR_NEXT_USHORT( buff ); + } + + + /* load bitmap metrics. "*padvance" must be set to the default value */ + /* before calling this function... */ + /* */ + static FT_Error + pfr_load_bitmap_metrics( FT_Byte** pdata, + FT_Byte* limit, + FT_Long scaled_advance, + FT_Long *axpos, + FT_Long *aypos, + FT_UInt *axsize, + FT_UInt *aysize, + FT_Long *aadvance, + FT_UInt *aformat ) + { + FT_Error error = FT_Err_Ok; + FT_Byte flags; + FT_Char b; + FT_Byte* p = *pdata; + FT_Long xpos, ypos, advance; + FT_UInt xsize, ysize; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + xpos = 0; + ypos = 0; + xsize = 0; + ysize = 0; + advance = 0; + + switch ( flags & 3 ) + { + case 0: + PFR_CHECK( 1 ); + b = PFR_NEXT_INT8( p ); + xpos = b >> 4; + ypos = ( (FT_Char)( b << 4 ) ) >> 4; + break; + + case 1: + PFR_CHECK( 2 ); + xpos = PFR_NEXT_INT8( p ); + ypos = PFR_NEXT_INT8( p ); + break; + + case 2: + PFR_CHECK( 4 ); + xpos = PFR_NEXT_SHORT( p ); + ypos = PFR_NEXT_SHORT( p ); + break; + + case 3: + PFR_CHECK( 6 ); + xpos = PFR_NEXT_LONG( p ); + ypos = PFR_NEXT_LONG( p ); + break; + + default: + ; + } + + flags >>= 2; + switch ( flags & 3 ) + { + case 0: + /* blank image */ + xsize = 0; + ysize = 0; + break; + + case 1: + PFR_CHECK( 1 ); + b = PFR_NEXT_BYTE( p ); + xsize = ( b >> 4 ) & 0xF; + ysize = b & 0xF; + break; + + case 2: + PFR_CHECK( 2 ); + xsize = PFR_NEXT_BYTE( p ); + ysize = PFR_NEXT_BYTE( p ); + break; + + case 3: + PFR_CHECK( 4 ); + xsize = PFR_NEXT_USHORT( p ); + ysize = PFR_NEXT_USHORT( p ); + break; + + default: + ; + } + + flags >>= 2; + switch ( flags & 3 ) + { + case 0: + advance = scaled_advance; + break; + + case 1: + PFR_CHECK( 1 ); + advance = PFR_NEXT_INT8( p ) << 8; + break; + + case 2: + PFR_CHECK( 2 ); + advance = PFR_NEXT_SHORT( p ); + break; + + case 3: + PFR_CHECK( 3 ); + advance = PFR_NEXT_LONG( p ); + break; + + default: + ; + } + + *axpos = xpos; + *aypos = ypos; + *axsize = xsize; + *aysize = ysize; + *aadvance = advance; + *aformat = flags >> 2; + *pdata = p; + + Exit: + return error; + + Too_Short: + error = FT_THROW( Invalid_Table ); + FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" )); + goto Exit; + } + + + static FT_Error + pfr_load_bitmap_bits( FT_Byte* p, + FT_Byte* limit, + FT_UInt format, + FT_Bool decreasing, + FT_Bitmap* target ) + { + FT_Error error = FT_Err_Ok; + PFR_BitWriterRec writer; + + + if ( target->rows > 0 && target->width > 0 ) + { + pfr_bitwriter_init( &writer, target, decreasing ); + + switch ( format ) + { + case 0: /* packed bits */ + pfr_bitwriter_decode_bytes( &writer, p, limit ); + break; + + case 1: /* RLE1 */ + pfr_bitwriter_decode_rle1( &writer, p, limit ); + break; + + case 2: /* RLE2 */ + pfr_bitwriter_decode_rle2( &writer, p, limit ); + break; + + default: + FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); + error = FT_THROW( Invalid_File_Format ); + } + } + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BITMAP LOADING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( FT_Error ) + pfr_slot_load_bitmap( PFR_Slot glyph, + PFR_Size size, + FT_UInt glyph_index ) + { + FT_Error error; + PFR_Face face = (PFR_Face) glyph->root.face; + FT_Stream stream = face->root.stream; + PFR_PhyFont phys = &face->phy_font; + FT_ULong gps_offset; + FT_ULong gps_size; + PFR_Char character; + PFR_Strike strike; + + + character = &phys->chars[glyph_index]; + + /* Look-up a bitmap strike corresponding to the current */ + /* character dimensions */ + { + FT_UInt n; + + + strike = phys->strikes; + for ( n = 0; n < phys->num_strikes; n++ ) + { + if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && + strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) + { + goto Found_Strike; + } + + strike++; + } + + /* couldn't find it */ + return FT_THROW( Invalid_Argument ); + } + + Found_Strike: + + /* Now lookup the glyph's position within the file */ + { + FT_UInt char_len; + + + char_len = 4; + if ( strike->flags & 1 ) char_len += 1; + if ( strike->flags & 2 ) char_len += 1; + if ( strike->flags & 4 ) char_len += 1; + + /* Access data directly in the frame to speed lookups */ + if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || + FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) + goto Exit; + + pfr_lookup_bitmap_data( stream->cursor, + stream->limit, + strike->num_bitmaps, + strike->flags, + character->char_code, + &gps_offset, + &gps_size ); + + FT_FRAME_EXIT(); + + if ( gps_size == 0 ) + { + /* Could not find a bitmap program string for this glyph */ + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + } + + /* get the bitmap metrics */ + { + FT_Long xpos = 0, ypos = 0, advance = 0; + FT_UInt xsize = 0, ysize = 0, format = 0; + FT_Byte* p; + + + /* compute linear advance */ + advance = character->advance; + if ( phys->metrics_resolution != phys->outline_resolution ) + advance = FT_MulDiv( advance, + phys->outline_resolution, + phys->metrics_resolution ); + + glyph->root.linearHoriAdvance = advance; + + /* compute default advance, i.e., scaled advance. This can be */ + /* overridden in the bitmap header of certain glyphs. */ + advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8, + character->advance, + phys->metrics_resolution ); + + if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) || + FT_FRAME_ENTER( gps_size ) ) + goto Exit; + + p = stream->cursor; + error = pfr_load_bitmap_metrics( &p, stream->limit, + advance, + &xpos, &ypos, + &xsize, &ysize, + &advance, &format ); + + /* + * XXX: on 16bit system, we return an error for huge bitmap + * which causes a size truncation, because truncated + * size properties makes bitmap glyph broken. + */ + if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX ) + { + FT_TRACE1(( "pfr_slot_load_bitmap:" )); + FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n", + xpos, ypos )); + error = FT_THROW( Invalid_Pixel_Size ); + } + + if ( !error ) + { + glyph->root.format = FT_GLYPH_FORMAT_BITMAP; + + /* Set up glyph bitmap and metrics */ + + /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */ + glyph->root.bitmap.width = (FT_Int)xsize; + glyph->root.bitmap.rows = (FT_Int)ysize; + glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3; + glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; + + /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ + glyph->root.metrics.width = (FT_Pos)xsize << 6; + glyph->root.metrics.height = (FT_Pos)ysize << 6; + glyph->root.metrics.horiBearingX = xpos << 6; + glyph->root.metrics.horiBearingY = ypos << 6; + glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); + glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; + glyph->root.metrics.vertBearingY = 0; + glyph->root.metrics.vertAdvance = size->root.metrics.height; + + /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */ + glyph->root.bitmap_left = (FT_Int)xpos; + glyph->root.bitmap_top = (FT_Int)(ypos + ysize); + + /* Allocate and read bitmap data */ + { + FT_ULong len = glyph->root.bitmap.pitch * ysize; + + + error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); + if ( !error ) + { + error = pfr_load_bitmap_bits( + p, + stream->limit, + format, + FT_BOOL(face->header.color_flags & 2), + &glyph->root.bitmap ); + } + } + } + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrsbit.h b/drivers/freetype/src/pfr/pfrsbit.h new file mode 100644 index 0000000000..015e9e6dad --- /dev/null +++ b/drivers/freetype/src/pfr/pfrsbit.h @@ -0,0 +1,36 @@ +/***************************************************************************/ +/* */ +/* pfrsbit.h */ +/* */ +/* FreeType PFR bitmap loader (specification). */ +/* */ +/* Copyright 2002 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 __PFRSBIT_H__ +#define __PFRSBIT_H__ + +#include "pfrobjs.h" + +FT_BEGIN_HEADER + + FT_LOCAL( FT_Error ) + pfr_slot_load_bitmap( PFR_Slot glyph, + PFR_Size size, + FT_UInt glyph_index ); + +FT_END_HEADER + +#endif /* __PFR_SBIT_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pfr/pfrtypes.h b/drivers/freetype/src/pfr/pfrtypes.h new file mode 100644 index 0000000000..918310814c --- /dev/null +++ b/drivers/freetype/src/pfr/pfrtypes.h @@ -0,0 +1,362 @@ +/***************************************************************************/ +/* */ +/* pfrtypes.h */ +/* */ +/* FreeType PFR data structures (specification only). */ +/* */ +/* Copyright 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, */ +/* 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 __PFRTYPES_H__ +#define __PFRTYPES_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + +FT_BEGIN_HEADER + + /************************************************************************/ + + /* the PFR Header structure */ + typedef struct PFR_HeaderRec_ + { + FT_UInt32 signature; + FT_UInt version; + FT_UInt signature2; + FT_UInt header_size; + + FT_UInt log_dir_size; + FT_UInt log_dir_offset; + + FT_UInt log_font_max_size; + FT_UInt32 log_font_section_size; + FT_UInt32 log_font_section_offset; + + FT_UInt32 phy_font_max_size; + FT_UInt32 phy_font_section_size; + FT_UInt32 phy_font_section_offset; + + FT_UInt gps_max_size; + FT_UInt32 gps_section_size; + FT_UInt32 gps_section_offset; + + FT_UInt max_blue_values; + FT_UInt max_x_orus; + FT_UInt max_y_orus; + + FT_UInt phy_font_max_size_high; + FT_UInt color_flags; + + FT_UInt32 bct_max_size; + FT_UInt32 bct_set_max_size; + FT_UInt32 phy_bct_set_max_size; + + FT_UInt num_phy_fonts; + FT_UInt max_vert_stem_snap; + FT_UInt max_horz_stem_snap; + FT_UInt max_chars; + + } PFR_HeaderRec, *PFR_Header; + + + /* used in `color_flags' field of the PFR_Header */ + typedef enum PFR_HeaderFlags_ + { + PFR_FLAG_BLACK_PIXEL = 1, + PFR_FLAG_INVERT_BITMAP = 2 + + } PFR_HeaderFlags; + + + /************************************************************************/ + + typedef struct PFR_LogFontRec_ + { + FT_UInt32 size; + FT_UInt32 offset; + + FT_Int32 matrix[4]; + FT_UInt stroke_flags; + FT_Int stroke_thickness; + FT_Int bold_thickness; + FT_Int32 miter_limit; + + FT_UInt32 phys_size; + FT_UInt32 phys_offset; + + } PFR_LogFontRec, *PFR_LogFont; + + + typedef enum PFR_LogFlags_ + { + PFR_LOG_EXTRA_ITEMS = 0x40, + PFR_LOG_2BYTE_BOLD = 0x20, + PFR_LOG_BOLD = 0x10, + PFR_LOG_2BYTE_STROKE = 8, + PFR_LOG_STROKE = 4, + PFR_LINE_JOIN_MASK = 3 + + } PFR_LogFlags; + + + typedef enum PFR_LineJoinFlags_ + { + PFR_LINE_JOIN_MITER = 0, + PFR_LINE_JOIN_ROUND = 1, + PFR_LINE_JOIN_BEVEL = 2 + + } PFR_LineJoinFlags; + + + /************************************************************************/ + + typedef enum PFR_BitmapFlags_ + { + PFR_BITMAP_3BYTE_OFFSET = 4, + PFR_BITMAP_2BYTE_SIZE = 2, + PFR_BITMAP_2BYTE_CHARCODE = 1 + + } PFR_BitmapFlags; + + + typedef struct PFR_BitmapCharRec_ + { + FT_UInt char_code; + FT_UInt gps_size; + FT_UInt32 gps_offset; + + } PFR_BitmapCharRec, *PFR_BitmapChar; + + + typedef enum PFR_StrikeFlags_ + { + PFR_STRIKE_2BYTE_COUNT = 0x10, + PFR_STRIKE_3BYTE_OFFSET = 0x08, + PFR_STRIKE_3BYTE_SIZE = 0x04, + PFR_STRIKE_2BYTE_YPPM = 0x02, + PFR_STRIKE_2BYTE_XPPM = 0x01 + + } PFR_StrikeFlags; + + + typedef struct PFR_StrikeRec_ + { + FT_UInt x_ppm; + FT_UInt y_ppm; + FT_UInt flags; + + FT_UInt32 gps_size; + FT_UInt32 gps_offset; + + FT_UInt32 bct_size; + FT_UInt32 bct_offset; + + /* optional */ + FT_UInt num_bitmaps; + PFR_BitmapChar bitmaps; + + } PFR_StrikeRec, *PFR_Strike; + + + /************************************************************************/ + + typedef struct PFR_CharRec_ + { + FT_UInt char_code; + FT_Int advance; + FT_UInt gps_size; + FT_UInt32 gps_offset; + + } PFR_CharRec, *PFR_Char; + + + /************************************************************************/ + + typedef struct PFR_DimensionRec_ + { + FT_UInt standard; + FT_UInt num_stem_snaps; + FT_Int* stem_snaps; + + } PFR_DimensionRec, *PFR_Dimension; + + /************************************************************************/ + + typedef struct PFR_KernItemRec_* PFR_KernItem; + + typedef struct PFR_KernItemRec_ + { + PFR_KernItem next; + FT_Byte pair_count; + FT_Byte flags; + FT_Short base_adj; + FT_UInt pair_size; + FT_Offset offset; + FT_UInt32 pair1; + FT_UInt32 pair2; + + } PFR_KernItemRec; + + +#define PFR_KERN_INDEX( g1, g2 ) \ + ( ( (FT_UInt32)(g1) << 16 ) | (FT_UInt16)(g2) ) + +#define PFR_KERN_PAIR_INDEX( pair ) \ + PFR_KERN_INDEX( (pair)->glyph1, (pair)->glyph2 ) + +#define PFR_NEXT_KPAIR( p ) ( p += 2, \ + ( (FT_UInt32)p[-2] << 16 ) | p[-1] ) + + + /************************************************************************/ + + typedef struct PFR_PhyFontRec_ + { + FT_Memory memory; + FT_UInt32 offset; + + FT_UInt font_ref_number; + FT_UInt outline_resolution; + FT_UInt metrics_resolution; + FT_BBox bbox; + FT_UInt flags; + FT_UInt standard_advance; + + FT_Int ascent; /* optional, bbox.yMax if not present */ + FT_Int descent; /* optional, bbox.yMin if not present */ + FT_Int leading; /* optional, 0 if not present */ + + PFR_DimensionRec horizontal; + PFR_DimensionRec vertical; + + FT_String* font_id; + FT_String* family_name; + FT_String* style_name; + + FT_UInt num_strikes; + FT_UInt max_strikes; + PFR_StrikeRec* strikes; + + FT_UInt num_blue_values; + FT_Int *blue_values; + FT_UInt blue_fuzz; + FT_UInt blue_scale; + + FT_UInt num_chars; + FT_Offset chars_offset; + PFR_Char chars; + + FT_UInt num_kern_pairs; + PFR_KernItem kern_items; + PFR_KernItem* kern_items_tail; + + /* not part of the spec, but used during load */ + FT_Long bct_offset; + FT_Byte* cursor; + + } PFR_PhyFontRec, *PFR_PhyFont; + + + typedef enum PFR_PhyFlags_ + { + PFR_PHY_EXTRA_ITEMS = 0x80, + PFR_PHY_3BYTE_GPS_OFFSET = 0x20, + PFR_PHY_2BYTE_GPS_SIZE = 0x10, + PFR_PHY_ASCII_CODE = 0x08, + PFR_PHY_PROPORTIONAL = 0x04, + PFR_PHY_2BYTE_CHARCODE = 0x02, + PFR_PHY_VERTICAL = 0x01 + + } PFR_PhyFlags; + + + typedef enum PFR_KernFlags_ + { + PFR_KERN_2BYTE_CHAR = 0x01, + PFR_KERN_2BYTE_ADJ = 0x02 + + } PFR_KernFlags; + + + /************************************************************************/ + + typedef enum PFR_GlyphFlags_ + { + PFR_GLYPH_IS_COMPOUND = 0x80, + PFR_GLYPH_EXTRA_ITEMS = 0x08, + PFR_GLYPH_1BYTE_XYCOUNT = 0x04, + PFR_GLYPH_XCOUNT = 0x02, + PFR_GLYPH_YCOUNT = 0x01 + + } PFR_GlyphFlags; + + + /* controlled coordinate */ + typedef struct PFR_CoordRec_ + { + FT_UInt org; + FT_UInt cur; + + } PFR_CoordRec, *PFR_Coord; + + + typedef struct PFR_SubGlyphRec_ + { + FT_Fixed x_scale; + FT_Fixed y_scale; + FT_Int x_delta; + FT_Int y_delta; + FT_UInt32 gps_offset; + FT_UInt gps_size; + + } PFR_SubGlyphRec, *PFR_SubGlyph; + + + typedef enum PFR_SubgGlyphFlags_ + { + PFR_SUBGLYPH_3BYTE_OFFSET = 0x80, + PFR_SUBGLYPH_2BYTE_SIZE = 0x40, + PFR_SUBGLYPH_YSCALE = 0x20, + PFR_SUBGLYPH_XSCALE = 0x10 + + } PFR_SubGlyphFlags; + + + typedef struct PFR_GlyphRec_ + { + FT_Byte format; + +#if 0 + FT_UInt num_x_control; + FT_UInt num_y_control; +#endif + FT_UInt max_xy_control; + FT_Pos* x_control; + FT_Pos* y_control; + + + FT_UInt num_subs; + FT_UInt max_subs; + PFR_SubGlyphRec* subs; + + FT_GlyphLoader loader; + FT_Bool path_begun; + + } PFR_GlyphRec, *PFR_Glyph; + + +FT_END_HEADER + +#endif /* __PFRTYPES_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pfr/rules.mk b/drivers/freetype/src/pfr/rules.mk new file mode 100644 index 0000000000..60b96c7415 --- /dev/null +++ b/drivers/freetype/src/pfr/rules.mk @@ -0,0 +1,73 @@ +# +# FreeType 2 PFR driver configuration rules +# + + +# Copyright 2002, 2003 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. + + +# pfr driver directory +# +PFR_DIR := $(SRC_DIR)/pfr + + +# compilation flags for the driver +# +PFR_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PFR_DIR)) + + +# pfr driver sources (i.e., C files) +# +PFR_DRV_SRC := $(PFR_DIR)/pfrload.c \ + $(PFR_DIR)/pfrgload.c \ + $(PFR_DIR)/pfrcmap.c \ + $(PFR_DIR)/pfrdrivr.c \ + $(PFR_DIR)/pfrsbit.c \ + $(PFR_DIR)/pfrobjs.c + +# pfr driver headers +# +PFR_DRV_H := $(PFR_DRV_SRC:%.c=%.h) \ + $(PFR_DIR)/pfrerror.h \ + $(PFR_DIR)/pfrtypes.h + + +# Pfr driver object(s) +# +# PFR_DRV_OBJ_M is used during `multi' builds +# PFR_DRV_OBJ_S is used during `single' builds +# +PFR_DRV_OBJ_M := $(PFR_DRV_SRC:$(PFR_DIR)/%.c=$(OBJ_DIR)/%.$O) +PFR_DRV_OBJ_S := $(OBJ_DIR)/pfr.$O + +# pfr driver source file for single build +# +PFR_DRV_SRC_S := $(PFR_DIR)/pfr.c + + +# pfr driver - single object +# +$(PFR_DRV_OBJ_S): $(PFR_DRV_SRC_S) $(PFR_DRV_SRC) $(FREETYPE_H) $(PFR_DRV_H) + $(PFR_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PFR_DRV_SRC_S)) + + +# pfr driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(PFR_DIR)/%.c $(FREETYPE_H) $(PFR_DRV_H) + $(PFR_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(PFR_DRV_OBJ_S) +DRV_OBJS_M += $(PFR_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/psaux/Jamfile b/drivers/freetype/src/psaux/Jamfile new file mode 100644 index 0000000000..faeded9044 --- /dev/null +++ b/drivers/freetype/src/psaux/Jamfile @@ -0,0 +1,31 @@ +# FreeType 2 src/psaux Jamfile +# +# Copyright 2001, 2002 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) psaux ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = psauxmod psobjs t1decode t1cmap + psconv afmparse + ; + } + else + { + _sources = psaux ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/psaux Jamfile diff --git a/drivers/freetype/src/psaux/afmparse.c b/drivers/freetype/src/psaux/afmparse.c new file mode 100644 index 0000000000..6a40e110dc --- /dev/null +++ b/drivers/freetype/src/psaux/afmparse.c @@ -0,0 +1,964 @@ +/***************************************************************************/ +/* */ +/* afmparse.c */ +/* */ +/* AFM parser (body). */ +/* */ +/* Copyright 2006-2010, 2012, 2013 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_FREETYPE_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "afmparse.h" +#include "psconv.h" + +#include "psauxerr.h" + + +/***************************************************************************/ +/* */ +/* AFM_Stream */ +/* */ +/* The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib. */ +/* */ +/* */ + + enum + { + AFM_STREAM_STATUS_NORMAL, + AFM_STREAM_STATUS_EOC, + AFM_STREAM_STATUS_EOL, + AFM_STREAM_STATUS_EOF + }; + + + typedef struct AFM_StreamRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + + FT_Int status; + + } AFM_StreamRec; + + +#ifndef EOF +#define EOF -1 +#endif + + + /* this works because empty lines are ignored */ +#define AFM_IS_NEWLINE( ch ) ( (ch) == '\r' || (ch) == '\n' ) + +#define AFM_IS_EOF( ch ) ( (ch) == EOF || (ch) == '\x1a' ) +#define AFM_IS_SPACE( ch ) ( (ch) == ' ' || (ch) == '\t' ) + + /* column separator; there is no `column' in the spec actually */ +#define AFM_IS_SEP( ch ) ( (ch) == ';' ) + +#define AFM_GETC() \ + ( ( (stream)->cursor < (stream)->limit ) ? *(stream)->cursor++ \ + : EOF ) + +#define AFM_STREAM_KEY_BEGIN( stream ) \ + (char*)( (stream)->cursor - 1 ) + +#define AFM_STREAM_KEY_LEN( stream, key ) \ + ( (char*)(stream)->cursor - key - 1 ) + +#define AFM_STATUS_EOC( stream ) \ + ( (stream)->status >= AFM_STREAM_STATUS_EOC ) + +#define AFM_STATUS_EOL( stream ) \ + ( (stream)->status >= AFM_STREAM_STATUS_EOL ) + +#define AFM_STATUS_EOF( stream ) \ + ( (stream)->status >= AFM_STREAM_STATUS_EOF ) + + + static int + afm_stream_skip_spaces( AFM_Stream stream ) + { + int ch = 0; /* make stupid compiler happy */ + + + if ( AFM_STATUS_EOC( stream ) ) + return ';'; + + while ( 1 ) + { + ch = AFM_GETC(); + if ( !AFM_IS_SPACE( ch ) ) + break; + } + + if ( AFM_IS_NEWLINE( ch ) ) + stream->status = AFM_STREAM_STATUS_EOL; + else if ( AFM_IS_SEP( ch ) ) + stream->status = AFM_STREAM_STATUS_EOC; + else if ( AFM_IS_EOF( ch ) ) + stream->status = AFM_STREAM_STATUS_EOF; + + return ch; + } + + + /* read a key or value in current column */ + static char* + afm_stream_read_one( AFM_Stream stream ) + { + char* str; + + + afm_stream_skip_spaces( stream ); + if ( AFM_STATUS_EOC( stream ) ) + return NULL; + + str = AFM_STREAM_KEY_BEGIN( stream ); + + while ( 1 ) + { + int ch = AFM_GETC(); + + + if ( AFM_IS_SPACE( ch ) ) + break; + else if ( AFM_IS_NEWLINE( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOL; + break; + } + else if ( AFM_IS_SEP( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOC; + break; + } + else if ( AFM_IS_EOF( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOF; + break; + } + } + + return str; + } + + + /* read a string (i.e., read to EOL) */ + static char* + afm_stream_read_string( AFM_Stream stream ) + { + char* str; + + + afm_stream_skip_spaces( stream ); + if ( AFM_STATUS_EOL( stream ) ) + return NULL; + + str = AFM_STREAM_KEY_BEGIN( stream ); + + /* scan to eol */ + while ( 1 ) + { + int ch = AFM_GETC(); + + + if ( AFM_IS_NEWLINE( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOL; + break; + } + else if ( AFM_IS_EOF( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOF; + break; + } + } + + return str; + } + + + /*************************************************************************/ + /* */ + /* AFM_Parser */ + /* */ + /* */ + + /* all keys defined in Ch. 7-10 of 5004.AFM_Spec.pdf */ + typedef enum AFM_Token_ + { + AFM_TOKEN_ASCENDER, + AFM_TOKEN_AXISLABEL, + AFM_TOKEN_AXISTYPE, + AFM_TOKEN_B, + AFM_TOKEN_BLENDAXISTYPES, + AFM_TOKEN_BLENDDESIGNMAP, + AFM_TOKEN_BLENDDESIGNPOSITIONS, + AFM_TOKEN_C, + AFM_TOKEN_CC, + AFM_TOKEN_CH, + AFM_TOKEN_CAPHEIGHT, + AFM_TOKEN_CHARWIDTH, + AFM_TOKEN_CHARACTERSET, + AFM_TOKEN_CHARACTERS, + AFM_TOKEN_DESCENDER, + AFM_TOKEN_ENCODINGSCHEME, + AFM_TOKEN_ENDAXIS, + AFM_TOKEN_ENDCHARMETRICS, + AFM_TOKEN_ENDCOMPOSITES, + AFM_TOKEN_ENDDIRECTION, + AFM_TOKEN_ENDFONTMETRICS, + AFM_TOKEN_ENDKERNDATA, + AFM_TOKEN_ENDKERNPAIRS, + AFM_TOKEN_ENDTRACKKERN, + AFM_TOKEN_ESCCHAR, + AFM_TOKEN_FAMILYNAME, + AFM_TOKEN_FONTBBOX, + AFM_TOKEN_FONTNAME, + AFM_TOKEN_FULLNAME, + AFM_TOKEN_ISBASEFONT, + AFM_TOKEN_ISCIDFONT, + AFM_TOKEN_ISFIXEDPITCH, + AFM_TOKEN_ISFIXEDV, + AFM_TOKEN_ITALICANGLE, + AFM_TOKEN_KP, + AFM_TOKEN_KPH, + AFM_TOKEN_KPX, + AFM_TOKEN_KPY, + AFM_TOKEN_L, + AFM_TOKEN_MAPPINGSCHEME, + AFM_TOKEN_METRICSSETS, + AFM_TOKEN_N, + AFM_TOKEN_NOTICE, + AFM_TOKEN_PCC, + AFM_TOKEN_STARTAXIS, + AFM_TOKEN_STARTCHARMETRICS, + AFM_TOKEN_STARTCOMPOSITES, + AFM_TOKEN_STARTDIRECTION, + AFM_TOKEN_STARTFONTMETRICS, + AFM_TOKEN_STARTKERNDATA, + AFM_TOKEN_STARTKERNPAIRS, + AFM_TOKEN_STARTKERNPAIRS0, + AFM_TOKEN_STARTKERNPAIRS1, + AFM_TOKEN_STARTTRACKKERN, + AFM_TOKEN_STDHW, + AFM_TOKEN_STDVW, + AFM_TOKEN_TRACKKERN, + AFM_TOKEN_UNDERLINEPOSITION, + AFM_TOKEN_UNDERLINETHICKNESS, + AFM_TOKEN_VV, + AFM_TOKEN_VVECTOR, + AFM_TOKEN_VERSION, + AFM_TOKEN_W, + AFM_TOKEN_W0, + AFM_TOKEN_W0X, + AFM_TOKEN_W0Y, + AFM_TOKEN_W1, + AFM_TOKEN_W1X, + AFM_TOKEN_W1Y, + AFM_TOKEN_WX, + AFM_TOKEN_WY, + AFM_TOKEN_WEIGHT, + AFM_TOKEN_WEIGHTVECTOR, + AFM_TOKEN_XHEIGHT, + N_AFM_TOKENS, + AFM_TOKEN_UNKNOWN + + } AFM_Token; + + + static const char* const afm_key_table[N_AFM_TOKENS] = + { + "Ascender", + "AxisLabel", + "AxisType", + "B", + "BlendAxisTypes", + "BlendDesignMap", + "BlendDesignPositions", + "C", + "CC", + "CH", + "CapHeight", + "CharWidth", + "CharacterSet", + "Characters", + "Descender", + "EncodingScheme", + "EndAxis", + "EndCharMetrics", + "EndComposites", + "EndDirection", + "EndFontMetrics", + "EndKernData", + "EndKernPairs", + "EndTrackKern", + "EscChar", + "FamilyName", + "FontBBox", + "FontName", + "FullName", + "IsBaseFont", + "IsCIDFont", + "IsFixedPitch", + "IsFixedV", + "ItalicAngle", + "KP", + "KPH", + "KPX", + "KPY", + "L", + "MappingScheme", + "MetricsSets", + "N", + "Notice", + "PCC", + "StartAxis", + "StartCharMetrics", + "StartComposites", + "StartDirection", + "StartFontMetrics", + "StartKernData", + "StartKernPairs", + "StartKernPairs0", + "StartKernPairs1", + "StartTrackKern", + "StdHW", + "StdVW", + "TrackKern", + "UnderlinePosition", + "UnderlineThickness", + "VV", + "VVector", + "Version", + "W", + "W0", + "W0X", + "W0Y", + "W1", + "W1X", + "W1Y", + "WX", + "WY", + "Weight", + "WeightVector", + "XHeight" + }; + + + /* + * `afm_parser_read_vals' and `afm_parser_next_key' provide + * high-level operations to an AFM_Stream. The rest of the + * parser functions should use them without accessing the + * AFM_Stream directly. + */ + + FT_LOCAL_DEF( FT_Int ) + afm_parser_read_vals( AFM_Parser parser, + AFM_Value vals, + FT_UInt n ) + { + AFM_Stream stream = parser->stream; + char* str; + FT_UInt i; + + + if ( n > AFM_MAX_ARGUMENTS ) + return 0; + + for ( i = 0; i < n; i++ ) + { + FT_Offset len; + AFM_Value val = vals + i; + + + if ( val->type == AFM_VALUE_TYPE_STRING ) + str = afm_stream_read_string( stream ); + else + str = afm_stream_read_one( stream ); + + if ( !str ) + break; + + len = AFM_STREAM_KEY_LEN( stream, str ); + + switch ( val->type ) + { + case AFM_VALUE_TYPE_STRING: + case AFM_VALUE_TYPE_NAME: + { + FT_Memory memory = parser->memory; + FT_Error error; + + + if ( !FT_QALLOC( val->u.s, len + 1 ) ) + { + ft_memcpy( val->u.s, str, len ); + val->u.s[len] = '\0'; + } + } + break; + + case AFM_VALUE_TYPE_FIXED: + val->u.f = PS_Conv_ToFixed( (FT_Byte**)(void*)&str, + (FT_Byte*)str + len, 0 ); + break; + + case AFM_VALUE_TYPE_INTEGER: + val->u.i = PS_Conv_ToInt( (FT_Byte**)(void*)&str, + (FT_Byte*)str + len ); + break; + + case AFM_VALUE_TYPE_BOOL: + val->u.b = FT_BOOL( len == 4 && + !ft_strncmp( str, "true", 4 ) ); + break; + + case AFM_VALUE_TYPE_INDEX: + if ( parser->get_index ) + val->u.i = parser->get_index( str, len, parser->user_data ); + else + val->u.i = 0; + break; + } + } + + return i; + } + + + FT_LOCAL_DEF( char* ) + afm_parser_next_key( AFM_Parser parser, + FT_Bool line, + FT_Offset* len ) + { + AFM_Stream stream = parser->stream; + char* key = 0; /* make stupid compiler happy */ + + + if ( line ) + { + while ( 1 ) + { + /* skip current line */ + if ( !AFM_STATUS_EOL( stream ) ) + afm_stream_read_string( stream ); + + stream->status = AFM_STREAM_STATUS_NORMAL; + key = afm_stream_read_one( stream ); + + /* skip empty line */ + if ( !key && + !AFM_STATUS_EOF( stream ) && + AFM_STATUS_EOL( stream ) ) + continue; + + break; + } + } + else + { + while ( 1 ) + { + /* skip current column */ + while ( !AFM_STATUS_EOC( stream ) ) + afm_stream_read_one( stream ); + + stream->status = AFM_STREAM_STATUS_NORMAL; + key = afm_stream_read_one( stream ); + + /* skip empty column */ + if ( !key && + !AFM_STATUS_EOF( stream ) && + AFM_STATUS_EOC( stream ) ) + continue; + + break; + } + } + + if ( len ) + *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key ) + : 0; + + return key; + } + + + static AFM_Token + afm_tokenize( const char* key, + FT_Offset len ) + { + int n; + + + for ( n = 0; n < N_AFM_TOKENS; n++ ) + { + if ( *( afm_key_table[n] ) == *key ) + { + for ( ; n < N_AFM_TOKENS; n++ ) + { + if ( *( afm_key_table[n] ) != *key ) + return AFM_TOKEN_UNKNOWN; + + if ( ft_strncmp( afm_key_table[n], key, len ) == 0 ) + return (AFM_Token) n; + } + } + } + + return AFM_TOKEN_UNKNOWN; + } + + + FT_LOCAL_DEF( FT_Error ) + afm_parser_init( AFM_Parser parser, + FT_Memory memory, + FT_Byte* base, + FT_Byte* limit ) + { + AFM_Stream stream = NULL; + FT_Error error; + + + if ( FT_NEW( stream ) ) + return error; + + stream->cursor = stream->base = base; + stream->limit = limit; + + /* don't skip the first line during the first call */ + stream->status = AFM_STREAM_STATUS_EOL; + + parser->memory = memory; + parser->stream = stream; + parser->FontInfo = NULL; + parser->get_index = NULL; + + return FT_Err_Ok; + } + + + FT_LOCAL( void ) + afm_parser_done( AFM_Parser parser ) + { + FT_Memory memory = parser->memory; + + + FT_FREE( parser->stream ); + } + + + FT_LOCAL_DEF( FT_Error ) + afm_parser_read_int( AFM_Parser parser, + FT_Int* aint ) + { + AFM_ValueRec val; + + + val.type = AFM_VALUE_TYPE_INTEGER; + + if ( afm_parser_read_vals( parser, &val, 1 ) == 1 ) + { + *aint = val.u.i; + + return FT_Err_Ok; + } + else + return FT_THROW( Syntax_Error ); + } + + + static FT_Error + afm_parse_track_kern( AFM_Parser parser ) + { + AFM_FontInfo fi = parser->FontInfo; + AFM_TrackKern tk; + char* key; + FT_Offset len; + int n = -1; + + + if ( afm_parser_read_int( parser, &fi->NumTrackKern ) ) + goto Fail; + + if ( fi->NumTrackKern ) + { + FT_Memory memory = parser->memory; + FT_Error error; + + + if ( FT_QNEW_ARRAY( fi->TrackKerns, fi->NumTrackKern ) ) + return error; + } + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + AFM_ValueRec shared_vals[5]; + + + switch ( afm_tokenize( key, len ) ) + { + case AFM_TOKEN_TRACKKERN: + n++; + + if ( n >= fi->NumTrackKern ) + goto Fail; + + tk = fi->TrackKerns + n; + + shared_vals[0].type = AFM_VALUE_TYPE_INTEGER; + shared_vals[1].type = AFM_VALUE_TYPE_FIXED; + shared_vals[2].type = AFM_VALUE_TYPE_FIXED; + shared_vals[3].type = AFM_VALUE_TYPE_FIXED; + shared_vals[4].type = AFM_VALUE_TYPE_FIXED; + if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 ) + goto Fail; + + tk->degree = shared_vals[0].u.i; + tk->min_ptsize = shared_vals[1].u.f; + tk->min_kern = shared_vals[2].u.f; + tk->max_ptsize = shared_vals[3].u.f; + tk->max_kern = shared_vals[4].u.f; + + break; + + case AFM_TOKEN_ENDTRACKKERN: + case AFM_TOKEN_ENDKERNDATA: + case AFM_TOKEN_ENDFONTMETRICS: + fi->NumTrackKern = n + 1; + return FT_Err_Ok; + + case AFM_TOKEN_UNKNOWN: + break; + + default: + goto Fail; + } + } + + Fail: + return FT_THROW( Syntax_Error ); + } + + +#undef KERN_INDEX +#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) + + + /* compare two kerning pairs */ + FT_CALLBACK_DEF( int ) + afm_compare_kern_pairs( const void* a, + const void* b ) + { + AFM_KernPair kp1 = (AFM_KernPair)a; + AFM_KernPair kp2 = (AFM_KernPair)b; + + FT_ULong index1 = KERN_INDEX( kp1->index1, kp1->index2 ); + FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 ); + + + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; + } + + + static FT_Error + afm_parse_kern_pairs( AFM_Parser parser ) + { + AFM_FontInfo fi = parser->FontInfo; + AFM_KernPair kp; + char* key; + FT_Offset len; + int n = -1; + + + if ( afm_parser_read_int( parser, &fi->NumKernPair ) ) + goto Fail; + + if ( fi->NumKernPair ) + { + FT_Memory memory = parser->memory; + FT_Error error; + + + if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) ) + return error; + } + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + AFM_Token token = afm_tokenize( key, len ); + + + switch ( token ) + { + case AFM_TOKEN_KP: + case AFM_TOKEN_KPX: + case AFM_TOKEN_KPY: + { + FT_Int r; + AFM_ValueRec shared_vals[4]; + + + n++; + + if ( n >= fi->NumKernPair ) + goto Fail; + + kp = fi->KernPairs + n; + + shared_vals[0].type = AFM_VALUE_TYPE_INDEX; + shared_vals[1].type = AFM_VALUE_TYPE_INDEX; + shared_vals[2].type = AFM_VALUE_TYPE_INTEGER; + shared_vals[3].type = AFM_VALUE_TYPE_INTEGER; + r = afm_parser_read_vals( parser, shared_vals, 4 ); + if ( r < 3 ) + goto Fail; + + kp->index1 = shared_vals[0].u.i; + kp->index2 = shared_vals[1].u.i; + if ( token == AFM_TOKEN_KPY ) + { + kp->x = 0; + kp->y = shared_vals[2].u.i; + } + else + { + kp->x = shared_vals[2].u.i; + kp->y = ( token == AFM_TOKEN_KP && r == 4 ) + ? shared_vals[3].u.i : 0; + } + } + break; + + case AFM_TOKEN_ENDKERNPAIRS: + case AFM_TOKEN_ENDKERNDATA: + case AFM_TOKEN_ENDFONTMETRICS: + fi->NumKernPair = n + 1; + ft_qsort( fi->KernPairs, fi->NumKernPair, + sizeof ( AFM_KernPairRec ), + afm_compare_kern_pairs ); + return FT_Err_Ok; + + case AFM_TOKEN_UNKNOWN: + break; + + default: + goto Fail; + } + } + + Fail: + return FT_THROW( Syntax_Error ); + } + + + static FT_Error + afm_parse_kern_data( AFM_Parser parser ) + { + FT_Error error; + char* key; + FT_Offset len; + + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + switch ( afm_tokenize( key, len ) ) + { + case AFM_TOKEN_STARTTRACKKERN: + error = afm_parse_track_kern( parser ); + if ( error ) + return error; + break; + + case AFM_TOKEN_STARTKERNPAIRS: + case AFM_TOKEN_STARTKERNPAIRS0: + error = afm_parse_kern_pairs( parser ); + if ( error ) + return error; + break; + + case AFM_TOKEN_ENDKERNDATA: + case AFM_TOKEN_ENDFONTMETRICS: + return FT_Err_Ok; + + case AFM_TOKEN_UNKNOWN: + break; + + default: + goto Fail; + } + } + + Fail: + return FT_THROW( Syntax_Error ); + } + + + static FT_Error + afm_parser_skip_section( AFM_Parser parser, + FT_UInt n, + AFM_Token end_section ) + { + char* key; + FT_Offset len; + + + while ( n-- > 0 ) + { + key = afm_parser_next_key( parser, 1, NULL ); + if ( !key ) + goto Fail; + } + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + AFM_Token token = afm_tokenize( key, len ); + + + if ( token == end_section || token == AFM_TOKEN_ENDFONTMETRICS ) + return FT_Err_Ok; + } + + Fail: + return FT_THROW( Syntax_Error ); + } + + + FT_LOCAL_DEF( FT_Error ) + afm_parser_parse( AFM_Parser parser ) + { + FT_Memory memory = parser->memory; + AFM_FontInfo fi = parser->FontInfo; + FT_Error error = FT_ERR( Syntax_Error ); + char* key; + FT_Offset len; + FT_Int metrics_sets = 0; + + + if ( !fi ) + return FT_THROW( Invalid_Argument ); + + key = afm_parser_next_key( parser, 1, &len ); + if ( !key || len != 16 || + ft_strncmp( key, "StartFontMetrics", 16 ) != 0 ) + return FT_THROW( Unknown_File_Format ); + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + AFM_ValueRec shared_vals[4]; + + + switch ( afm_tokenize( key, len ) ) + { + case AFM_TOKEN_METRICSSETS: + if ( afm_parser_read_int( parser, &metrics_sets ) ) + goto Fail; + + if ( metrics_sets != 0 && metrics_sets != 2 ) + { + error = FT_THROW( Unimplemented_Feature ); + + goto Fail; + } + break; + + case AFM_TOKEN_ISCIDFONT: + shared_vals[0].type = AFM_VALUE_TYPE_BOOL; + if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) + goto Fail; + + fi->IsCIDFont = shared_vals[0].u.b; + break; + + case AFM_TOKEN_FONTBBOX: + shared_vals[0].type = AFM_VALUE_TYPE_FIXED; + shared_vals[1].type = AFM_VALUE_TYPE_FIXED; + shared_vals[2].type = AFM_VALUE_TYPE_FIXED; + shared_vals[3].type = AFM_VALUE_TYPE_FIXED; + if ( afm_parser_read_vals( parser, shared_vals, 4 ) != 4 ) + goto Fail; + + fi->FontBBox.xMin = shared_vals[0].u.f; + fi->FontBBox.yMin = shared_vals[1].u.f; + fi->FontBBox.xMax = shared_vals[2].u.f; + fi->FontBBox.yMax = shared_vals[3].u.f; + break; + + case AFM_TOKEN_ASCENDER: + shared_vals[0].type = AFM_VALUE_TYPE_FIXED; + if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) + goto Fail; + + fi->Ascender = shared_vals[0].u.f; + break; + + case AFM_TOKEN_DESCENDER: + shared_vals[0].type = AFM_VALUE_TYPE_FIXED; + if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) + goto Fail; + + fi->Descender = shared_vals[0].u.f; + break; + + case AFM_TOKEN_STARTCHARMETRICS: + { + FT_Int n = 0; + + + if ( afm_parser_read_int( parser, &n ) ) + goto Fail; + + error = afm_parser_skip_section( parser, n, + AFM_TOKEN_ENDCHARMETRICS ); + if ( error ) + return error; + } + break; + + case AFM_TOKEN_STARTKERNDATA: + error = afm_parse_kern_data( parser ); + if ( error ) + goto Fail; + /* fall through since we only support kern data */ + + case AFM_TOKEN_ENDFONTMETRICS: + return FT_Err_Ok; + + default: + break; + } + } + + Fail: + FT_FREE( fi->TrackKerns ); + fi->NumTrackKern = 0; + + FT_FREE( fi->KernPairs ); + fi->NumKernPair = 0; + + fi->IsCIDFont = 0; + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/psaux/afmparse.h b/drivers/freetype/src/psaux/afmparse.h new file mode 100644 index 0000000000..35d96046c5 --- /dev/null +++ b/drivers/freetype/src/psaux/afmparse.h @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* afmparse.h */ +/* */ +/* AFM parser (specification). */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFMPARSE_H__ +#define __AFMPARSE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + afm_parser_init( AFM_Parser parser, + FT_Memory memory, + FT_Byte* base, + FT_Byte* limit ); + + + FT_LOCAL( void ) + afm_parser_done( AFM_Parser parser ); + + + FT_LOCAL( FT_Error ) + afm_parser_parse( AFM_Parser parser ); + + + enum AFM_ValueType_ + { + AFM_VALUE_TYPE_STRING, + AFM_VALUE_TYPE_NAME, + AFM_VALUE_TYPE_FIXED, /* real number */ + AFM_VALUE_TYPE_INTEGER, + AFM_VALUE_TYPE_BOOL, + AFM_VALUE_TYPE_INDEX /* glyph index */ + }; + + + typedef struct AFM_ValueRec_ + { + enum AFM_ValueType_ type; + union + { + char* s; + FT_Fixed f; + FT_Int i; + FT_Bool b; + + } u; + + } AFM_ValueRec, *AFM_Value; + +#define AFM_MAX_ARGUMENTS 5 + + FT_LOCAL( FT_Int ) + afm_parser_read_vals( AFM_Parser parser, + AFM_Value vals, + FT_UInt n ); + + /* read the next key from the next line or column */ + FT_LOCAL( char* ) + afm_parser_next_key( AFM_Parser parser, + FT_Bool line, + FT_Offset* len ); + +FT_END_HEADER + +#endif /* __AFMPARSE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psaux/module.mk b/drivers/freetype/src/psaux/module.mk new file mode 100644 index 0000000000..42bf6f5199 --- /dev/null +++ b/drivers/freetype/src/psaux/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 PSaux module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += PSAUX_MODULE + +define PSAUX_MODULE +$(OPEN_DRIVER) FT_Module_Class, psaux_module_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)psaux $(ECHO_DRIVER_DESC)Postscript Type 1 & Type 2 helper module$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/psaux/psaux.c b/drivers/freetype/src/psaux/psaux.c new file mode 100644 index 0000000000..a4b9c5c6e4 --- /dev/null +++ b/drivers/freetype/src/psaux/psaux.c @@ -0,0 +1,34 @@ +/***************************************************************************/ +/* */ +/* psaux.c */ +/* */ +/* FreeType auxiliary PostScript driver component (body only). */ +/* */ +/* Copyright 1996-2001, 2002, 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "psobjs.c" +#include "psauxmod.c" +#include "t1decode.c" +#include "t1cmap.c" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "afmparse.c" +#endif + +#include "psconv.c" + + +/* END */ diff --git a/drivers/freetype/src/psaux/psauxerr.h b/drivers/freetype/src/psaux/psauxerr.h new file mode 100644 index 0000000000..d52375f8cb --- /dev/null +++ b/drivers/freetype/src/psaux/psauxerr.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* psauxerr.h */ +/* */ +/* PS auxiliary module error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PS auxiliary module error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSAUXERR_H__ +#define __PSAUXERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX PSaux_Err_ +#define FT_ERR_BASE FT_Mod_Err_PSaux + +#include FT_ERRORS_H + +#endif /* __PSAUXERR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psaux/psauxmod.c b/drivers/freetype/src/psaux/psauxmod.c new file mode 100644 index 0000000000..4b1249d49b --- /dev/null +++ b/drivers/freetype/src/psaux/psauxmod.c @@ -0,0 +1,139 @@ +/***************************************************************************/ +/* */ +/* psauxmod.c */ +/* */ +/* FreeType auxiliary PostScript module implementation (body). */ +/* */ +/* Copyright 2000-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, */ +/* 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 "psauxmod.h" +#include "psobjs.h" +#include "t1decode.h" +#include "t1cmap.h" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "afmparse.h" +#endif + + + FT_CALLBACK_TABLE_DEF + const PS_Table_FuncsRec ps_table_funcs = + { + ps_table_new, + ps_table_done, + ps_table_add, + ps_table_release + }; + + + FT_CALLBACK_TABLE_DEF + const PS_Parser_FuncsRec ps_parser_funcs = + { + ps_parser_init, + ps_parser_done, + ps_parser_skip_spaces, + ps_parser_skip_PS_token, + ps_parser_to_int, + ps_parser_to_fixed, + ps_parser_to_bytes, + ps_parser_to_coord_array, + ps_parser_to_fixed_array, + ps_parser_to_token, + ps_parser_to_token_array, + ps_parser_load_field, + ps_parser_load_field_table + }; + + + FT_CALLBACK_TABLE_DEF + const T1_Builder_FuncsRec t1_builder_funcs = + { + t1_builder_init, + t1_builder_done, + t1_builder_check_points, + t1_builder_add_point, + t1_builder_add_point1, + t1_builder_add_contour, + t1_builder_start_point, + t1_builder_close_contour + }; + + + FT_CALLBACK_TABLE_DEF + const T1_Decoder_FuncsRec t1_decoder_funcs = + { + t1_decoder_init, + t1_decoder_done, + t1_decoder_parse_charstrings + }; + + +#ifndef T1_CONFIG_OPTION_NO_AFM + FT_CALLBACK_TABLE_DEF + const AFM_Parser_FuncsRec afm_parser_funcs = + { + afm_parser_init, + afm_parser_done, + afm_parser_parse + }; +#endif + + + FT_CALLBACK_TABLE_DEF + const T1_CMap_ClassesRec t1_cmap_classes = + { + &t1_cmap_standard_class_rec, + &t1_cmap_expert_class_rec, + &t1_cmap_custom_class_rec, + &t1_cmap_unicode_class_rec + }; + + + static + const PSAux_Interface psaux_interface = + { + &ps_table_funcs, + &ps_parser_funcs, + &t1_builder_funcs, + &t1_decoder_funcs, + t1_decrypt, + + (const T1_CMap_ClassesRec*) &t1_cmap_classes, + +#ifndef T1_CONFIG_OPTION_NO_AFM + &afm_parser_funcs, +#else + 0, +#endif + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class psaux_module_class = + { + 0, + sizeof ( FT_ModuleRec ), + "psaux", + 0x20000L, + 0x20000L, + + &psaux_interface, /* module-specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }; + + +/* END */ diff --git a/drivers/freetype/src/psaux/psauxmod.h b/drivers/freetype/src/psaux/psauxmod.h new file mode 100644 index 0000000000..1217236924 --- /dev/null +++ b/drivers/freetype/src/psaux/psauxmod.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* psauxmod.h */ +/* */ +/* FreeType auxiliary PostScript module implementation (specification). */ +/* */ +/* Copyright 2000-2001 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 __PSAUXMOD_H__ +#define __PSAUXMOD_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; + + +FT_END_HEADER + +#endif /* __PSAUXMOD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psaux/psconv.c b/drivers/freetype/src/psaux/psconv.c new file mode 100644 index 0000000000..d0d8861c22 --- /dev/null +++ b/drivers/freetype/src/psaux/psconv.c @@ -0,0 +1,602 @@ +/***************************************************************************/ +/* */ +/* psconv.c */ +/* */ +/* Some convenience conversions (body). */ +/* */ +/* Copyright 2006, 2008, 2009, 2012-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_DEBUG_H + +#include "psconv.h" +#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_psconv + + + /* The following array is used by various functions to quickly convert */ + /* digits (both decimal and non-decimal) into numbers. */ + +#if 'A' == 65 + /* ASCII */ + + static const FT_Char ft_char_table[128] = + { + /* 0x00 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + }; + + /* no character >= 0x80 can represent a valid number */ +#define OP >= + +#endif /* 'A' == 65 */ + +#if 'A' == 193 + /* EBCDIC */ + + static const FT_Char ft_char_table[128] = + { + /* 0x80 */ + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, + -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, + -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + }; + + /* no character < 0x80 can represent a valid number */ +#define OP < + +#endif /* 'A' == 193 */ + + + FT_LOCAL_DEF( FT_Long ) + PS_Conv_Strtol( FT_Byte** cursor, + FT_Byte* limit, + FT_Long base ) + { + FT_Byte* p = *cursor; + + FT_Long num = 0; + FT_Bool sign = 0; + FT_Bool have_overflow = 0; + + FT_Long num_limit; + FT_Char c_limit; + + + if ( p >= limit ) + goto Bad; + + if ( base < 2 || base > 36 ) + { + FT_TRACE4(( "!!!INVALID BASE:!!!" )); + return 0; + } + + if ( *p == '-' || *p == '+' ) + { + sign = FT_BOOL( *p == '-' ); + + p++; + if ( p == limit ) + goto Bad; + } + + num_limit = 0x7FFFFFFFL / base; + c_limit = (FT_Char)( 0x7FFFFFFFL % base ); + + for ( ; p < limit; p++ ) + { + FT_Char c; + + + if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) + break; + + c = ft_char_table[*p & 0x7f]; + + if ( c < 0 || c >= base ) + break; + + if ( num > num_limit || ( num == num_limit && c > c_limit ) ) + have_overflow = 1; + else + num = num * base + c; + } + + *cursor = p; + + if ( have_overflow ) + { + num = 0x7FFFFFFFL; + FT_TRACE4(( "!!!OVERFLOW:!!!" )); + } + + if ( sign ) + num = -num; + + return num; + + Bad: + FT_TRACE4(( "!!!END OF DATA:!!!" )); + return 0; + } + + + FT_LOCAL_DEF( FT_Long ) + PS_Conv_ToInt( FT_Byte** cursor, + FT_Byte* limit ) + + { + FT_Byte* p = *cursor; + FT_Byte* curp; + + FT_Long num; + + + curp = p; + num = PS_Conv_Strtol( &p, limit, 10 ); + + if ( p == curp ) + return 0; + + if ( p < limit && *p == '#' ) + { + p++; + + curp = p; + num = PS_Conv_Strtol( &p, limit, num ); + + if ( p == curp ) + return 0; + } + + *cursor = p; + + return num; + } + + + FT_LOCAL_DEF( FT_Fixed ) + PS_Conv_ToFixed( FT_Byte** cursor, + FT_Byte* limit, + FT_Long power_ten ) + { + FT_Byte* p = *cursor; + FT_Byte* curp; + + FT_Fixed integral = 0; + FT_Long decimal = 0; + FT_Long divider = 1; + + FT_Bool sign = 0; + FT_Bool have_overflow = 0; + FT_Bool have_underflow = 0; + + + if ( p >= limit ) + goto Bad; + + if ( *p == '-' || *p == '+' ) + { + sign = FT_BOOL( *p == '-' ); + + p++; + if ( p == limit ) + goto Bad; + } + + /* read the integer part */ + if ( *p != '.' ) + { + curp = p; + integral = PS_Conv_ToInt( &p, limit ); + + if ( p == curp ) + return 0; + + if ( integral > 0x7FFF ) + have_overflow = 1; + else + integral = (FT_Fixed)( (FT_UInt32)integral << 16 ); + } + + /* read the decimal part */ + if ( p < limit && *p == '.' ) + { + p++; + + for ( ; p < limit; p++ ) + { + FT_Char c; + + + if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) + break; + + c = ft_char_table[*p & 0x7f]; + + if ( c < 0 || c >= 10 ) + break; + + if ( decimal < 0xCCCCCCCL ) + { + decimal = decimal * 10 + c; + + if ( !integral && power_ten > 0 ) + power_ten--; + else + divider *= 10; + } + } + } + + /* read exponent, if any */ + if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) ) + { + FT_Long exponent; + + + p++; + + curp = p; + exponent = PS_Conv_ToInt( &p, limit ); + + if ( curp == p ) + return 0; + + /* arbitrarily limit exponent */ + if ( exponent > 1000 ) + have_overflow = 1; + else if ( exponent < -1000 ) + have_underflow = 1; + else + power_ten += exponent; + } + + *cursor = p; + + if ( !integral && !decimal ) + return 0; + + if ( have_overflow ) + goto Overflow; + if ( have_underflow ) + goto Underflow; + + while ( power_ten > 0 ) + { + if ( integral >= 0xCCCCCCCL ) + goto Overflow; + integral *= 10; + + if ( decimal >= 0xCCCCCCCL ) + { + if ( divider == 1 ) + goto Overflow; + divider /= 10; + } + else + decimal *= 10; + + power_ten--; + } + + while ( power_ten < 0 ) + { + integral /= 10; + if ( divider < 0xCCCCCCCL ) + divider *= 10; + else + decimal /= 10; + + if ( !integral && !decimal ) + goto Underflow; + + power_ten++; + } + + if ( decimal ) + { + decimal = FT_DivFix( decimal, divider ); + /* it's not necessary to check this addition for overflow */ + /* due to the structure of the real number representation */ + integral += decimal; + } + + Exit: + if ( sign ) + integral = -integral; + + return integral; + + Bad: + FT_TRACE4(( "!!!END OF DATA:!!!" )); + return 0; + + Overflow: + integral = 0x7FFFFFFFL; + FT_TRACE4(( "!!!OVERFLOW:!!!" )); + goto Exit; + + Underflow: + FT_TRACE4(( "!!!UNDERFLOW:!!!" )); + return 0; + } + + +#if 0 + FT_LOCAL_DEF( FT_UInt ) + PS_Conv_StringDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n ) + { + FT_Byte* p; + FT_UInt r = 0; + + + for ( p = *cursor; r < n && p < limit; p++ ) + { + FT_Byte b; + + + if ( *p != '\\' ) + { + buffer[r++] = *p; + + continue; + } + + p++; + + switch ( *p ) + { + case 'n': + b = '\n'; + break; + case 'r': + b = '\r'; + break; + case 't': + b = '\t'; + break; + case 'b': + b = '\b'; + break; + case 'f': + b = '\f'; + break; + case '\r': + p++; + if ( *p != '\n' ) + { + b = *p; + + break; + } + /* no break */ + case '\n': + continue; + break; + default: + if ( IS_PS_DIGIT( *p ) ) + { + b = *p - '0'; + + p++; + + if ( IS_PS_DIGIT( *p ) ) + { + b = b * 8 + *p - '0'; + + p++; + + if ( IS_PS_DIGIT( *p ) ) + b = b * 8 + *p - '0'; + else + { + buffer[r++] = b; + b = *p; + } + } + else + { + buffer[r++] = b; + b = *p; + } + } + else + b = *p; + break; + } + + buffer[r++] = b; + } + + *cursor = p; + + return r; + } +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_UInt ) + PS_Conv_ASCIIHexDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n ) + { + FT_Byte* p; + FT_UInt r = 0; + FT_UInt w = 0; + FT_UInt pad = 0x01; + + + n *= 2; + +#if 1 + + p = *cursor; + + if ( p >= limit ) + return 0; + + 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; + + + if ( IS_PS_SPACE( *p ) ) + continue; + + if ( *p OP 0x80 ) + break; + + c = ft_char_table[*p & 0x7f]; + + if ( (unsigned)c >= 16 ) + break; + + if ( r & 1 ) + { + *buffer = (FT_Byte)(*buffer + c); + buffer++; + } + else + *buffer = (FT_Byte)(c << 4); + + r++; + } + + *cursor = p; + + return ( r + 1 ) / 2; + +#endif /* 0 */ + + } + + + FT_LOCAL_DEF( FT_UInt ) + PS_Conv_EexecDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n, + FT_UShort* seed ) + { + FT_Byte* p; + FT_UInt r; + FT_UInt s = *seed; + + +#if 1 + + p = *cursor; + + if ( p >= limit ) + return 0; + + 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 ) ); + + + s = (FT_UShort)( ( *p + s ) * 52845U + 22719 ); + *buffer++ = b; + } + *cursor = p; + *seed = s; + +#endif /* 0 */ + + return r; + } + + +/* END */ diff --git a/drivers/freetype/src/psaux/psconv.h b/drivers/freetype/src/psaux/psconv.h new file mode 100644 index 0000000000..d91c762210 --- /dev/null +++ b/drivers/freetype/src/psaux/psconv.h @@ -0,0 +1,71 @@ +/***************************************************************************/ +/* */ +/* psconv.h */ +/* */ +/* Some convenience conversions (specification). */ +/* */ +/* Copyright 2006, 2012 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 __PSCONV_H__ +#define __PSCONV_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Long ) + PS_Conv_Strtol( FT_Byte** cursor, + FT_Byte* limit, + FT_Long base ); + + + FT_LOCAL( FT_Long ) + PS_Conv_ToInt( FT_Byte** cursor, + FT_Byte* limit ); + + FT_LOCAL( FT_Fixed ) + PS_Conv_ToFixed( FT_Byte** cursor, + FT_Byte* limit, + FT_Long power_ten ); + +#if 0 + FT_LOCAL( FT_UInt ) + PS_Conv_StringDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n ); +#endif + + FT_LOCAL( FT_UInt ) + PS_Conv_ASCIIHexDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n ); + + FT_LOCAL( FT_UInt ) + PS_Conv_EexecDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n, + FT_UShort* seed ); + + +FT_END_HEADER + +#endif /* __PSCONV_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psaux/psobjs.c b/drivers/freetype/src/psaux/psobjs.c new file mode 100644 index 0000000000..dd976d3a96 --- /dev/null +++ b/drivers/freetype/src/psaux/psobjs.c @@ -0,0 +1,1765 @@ +/***************************************************************************/ +/* */ +/* psobjs.c */ +/* */ +/* Auxiliary functions for PostScript fonts (body). */ +/* */ +/* Copyright 1996-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H + +#include "psobjs.h" +#include "psconv.h" + +#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 + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_new */ + /* */ + /* <Description> */ + /* Initializes a PS_Table. */ + /* */ + /* <InOut> */ + /* table :: The address of the target table. */ + /* */ + /* <Input> */ + /* count :: The table size = the maximum number of elements. */ + /* */ + /* memory :: The memory object to use for all subsequent */ + /* reallocations. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + ps_table_new( PS_Table table, + FT_Int count, + FT_Memory memory ) + { + FT_Error error; + + + table->memory = memory; + if ( FT_NEW_ARRAY( table->elements, count ) || + FT_NEW_ARRAY( table->lengths, count ) ) + goto Exit; + + table->max_elems = count; + table->init = 0xDEADBEEFUL; + table->num_elems = 0; + table->block = 0; + table->capacity = 0; + table->cursor = 0; + + *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs; + + Exit: + if ( error ) + FT_FREE( table->elements ); + + return error; + } + + + static void + shift_elements( PS_Table table, + FT_Byte* old_base ) + { + FT_PtrDist delta = table->block - old_base; + FT_Byte** offset = table->elements; + FT_Byte** limit = offset + table->max_elems; + + + for ( ; offset < limit; offset++ ) + { + if ( offset[0] ) + offset[0] += delta; + } + } + + + static FT_Error + reallocate_t1_table( PS_Table table, + FT_Offset new_size ) + { + FT_Memory memory = table->memory; + FT_Byte* old_base = table->block; + FT_Error error; + + + /* allocate new base block */ + if ( FT_ALLOC( table->block, new_size ) ) + { + table->block = old_base; + return error; + } + + /* copy elements and shift offsets */ + if ( old_base ) + { + FT_MEM_COPY( table->block, old_base, table->capacity ); + shift_elements( table, old_base ); + FT_FREE( old_base ); + } + + table->capacity = new_size; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_add */ + /* */ + /* <Description> */ + /* Adds an object to a PS_Table, possibly growing its memory block. */ + /* */ + /* <InOut> */ + /* table :: The target table. */ + /* */ + /* <Input> */ + /* idx :: The index of the object in the table. */ + /* */ + /* object :: The address of the object to copy in memory. */ + /* */ + /* length :: The length in bytes of the source object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. An error is returned if a */ + /* reallocation fails. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ) + { + if ( idx < 0 || idx >= table->max_elems ) + { + FT_ERROR(( "ps_table_add: invalid index\n" )); + return FT_THROW( Invalid_Argument ); + } + + if ( length < 0 ) + { + FT_ERROR(( "ps_table_add: invalid length\n" )); + return FT_THROW( Invalid_Argument ); + } + + /* grow the base block if needed */ + if ( table->cursor + length > table->capacity ) + { + FT_Error error; + FT_Offset new_size = table->capacity; + FT_PtrDist in_offset; + + + in_offset = (FT_Byte*)object - table->block; + if ( in_offset < 0 || (FT_Offset)in_offset >= table->capacity ) + in_offset = -1; + + while ( new_size < table->cursor + length ) + { + /* increase size by 25% and round up to the nearest multiple + of 1024 */ + new_size += ( new_size >> 2 ) + 1; + new_size = FT_PAD_CEIL( new_size, 1024 ); + } + + error = reallocate_t1_table( table, new_size ); + if ( error ) + return error; + + if ( in_offset >= 0 ) + object = table->block + in_offset; + } + + /* add the object to the base block and adjust offset */ + table->elements[idx] = table->block + table->cursor; + table->lengths [idx] = length; + FT_MEM_COPY( table->block + table->cursor, object, length ); + + table->cursor += length; + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_done */ + /* */ + /* <Description> */ + /* Finalizes a PS_TableRec (i.e., reallocate it to its current */ + /* cursor). */ + /* */ + /* <InOut> */ + /* table :: The target table. */ + /* */ + /* <Note> */ + /* This function does NOT release the heap's memory block. It is up */ + /* to the caller to clean it, or reference it in its own structures. */ + /* */ + FT_LOCAL_DEF( void ) + ps_table_done( PS_Table table ) + { + FT_Memory memory = table->memory; + FT_Error error; + FT_Byte* old_base = table->block; + + + /* should never fail, because rec.cursor <= rec.size */ + if ( !old_base ) + return; + + if ( FT_ALLOC( table->block, table->cursor ) ) + return; + FT_MEM_COPY( table->block, old_base, table->cursor ); + shift_elements( table, old_base ); + + table->capacity = table->cursor; + FT_FREE( old_base ); + + FT_UNUSED( error ); + } + + + FT_LOCAL_DEF( void ) + ps_table_release( PS_Table table ) + { + FT_Memory memory = table->memory; + + + if ( (FT_ULong)table->init == 0xDEADBEEFUL ) + { + FT_FREE( table->block ); + FT_FREE( table->elements ); + FT_FREE( table->lengths ); + table->init = 0; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* first character must be already part of the comment */ + + static void + skip_comment( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + + + while ( cur < limit ) + { + if ( IS_PS_NEWLINE( *cur ) ) + break; + cur++; + } + + *acur = cur; + } + + + static void + skip_spaces( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + + + while ( cur < limit ) + { + if ( !IS_PS_SPACE( *cur ) ) + { + if ( *cur == '%' ) + /* According to the PLRM, a comment is equal to a space. */ + skip_comment( &cur, limit ); + else + break; + } + cur++; + } + + *acur = cur; + } + + +#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' ) + + + /* 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_Error error = FT_ERR( Invalid_File_Format ); + unsigned int i; + + + while ( cur < limit ) + { + 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 ( c == ')' ) + { + embed--; + if ( embed == 0 ) + { + error = FT_Err_Ok; + break; + } + } + } + + *acur = cur; + + return error; + } + + + /* first character must be `<' */ + + static FT_Error + skip_string( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + FT_Error err = FT_Err_Ok; + + + while ( ++cur < limit ) + { + /* All whitespace characters are ignored. */ + skip_spaces( &cur, limit ); + if ( cur >= limit ) + break; + + if ( !IS_PS_XDIGIT( *cur ) ) + break; + } + + if ( cur < limit && *cur != '>' ) + { + FT_ERROR(( "skip_string: missing closing delimiter `>'\n" )); + err = FT_THROW( Invalid_File_Format ); + } + else + 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 = FT_Err_Ok; + + + FT_ASSERT( **acur == '{' ); + + for ( cur = *acur; cur < limit && error == FT_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 = FT_THROW( Invalid_File_Format ); + + *acur = cur; + + return error; + } + + + /***********************************************************************/ + /* */ + /* All exported parsing routines handle leading whitespace and stop at */ + /* the first character which isn't part of the just handled token. */ + /* */ + /***********************************************************************/ + + + FT_LOCAL_DEF( void ) + ps_parser_skip_PS_token( PS_Parser parser ) + { + /* Note: PostScript allows any non-delimiting, non-whitespace */ + /* character in a name (PS Ref Manual, 3rd ed, p31). */ + /* PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */ + + FT_Byte* cur = parser->cursor; + FT_Byte* limit = parser->limit; + FT_Error error = FT_Err_Ok; + + + skip_spaces( &cur, limit ); /* this also skips comments */ + if ( cur >= limit ) + goto Exit; + + /* self-delimiting, single-character tokens */ + if ( *cur == '[' || *cur == ']' ) + { + cur++; + goto Exit; + } + + /* skip balanced expressions (procedures and strings) */ + + if ( *cur == '{' ) /* {...} */ + { + error = skip_procedure( &cur, limit ); + goto Exit; + } + + if ( *cur == '(' ) /* (...) */ + { + error = skip_literal_string( &cur, limit ); + goto Exit; + } + + if ( *cur == '<' ) /* <...> */ + { + if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */ + { + cur++; + cur++; + } + else + error = skip_string( &cur, limit ); + + goto Exit; + } + + if ( *cur == '>' ) + { + cur++; + if ( cur >= limit || *cur != '>' ) /* >> */ + { + FT_ERROR(( "ps_parser_skip_PS_token:" + " unexpected closing delimiter `>'\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + cur++; + goto Exit; + } + + if ( *cur == '/' ) + cur++; + + /* anything else */ + while ( cur < limit ) + { + /* *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 < limit && cur == parser->cursor ) + { + FT_ERROR(( "ps_parser_skip_PS_token:" + " current token is `%c' which is self-delimiting\n" + " " + " but invalid at this point\n", + *cur )); + + error = FT_THROW( Invalid_File_Format ); + } + + parser->error = error; + parser->cursor = cur; + } + + + FT_LOCAL_DEF( void ) + ps_parser_skip_spaces( PS_Parser parser ) + { + skip_spaces( &parser->cursor, parser->limit ); + } + + + /* `token' here means either something between balanced delimiters */ + /* or the next token; the delimiters are not removed. */ + + FT_LOCAL_DEF( void ) + ps_parser_to_token( PS_Parser parser, + T1_Token token ) + { + FT_Byte* cur; + FT_Byte* limit; + FT_Int embed; + + + token->type = T1_TOKEN_TYPE_NONE; + token->start = 0; + token->limit = 0; + + /* first of all, skip leading whitespace */ + ps_parser_skip_spaces( parser ); + + cur = parser->cursor; + limit = parser->limit; + + if ( cur >= limit ) + return; + + switch ( *cur ) + { + /************* check for literal string *****************/ + case '(': + token->type = T1_TOKEN_TYPE_STRING; + token->start = cur; + + if ( skip_literal_string( &cur, limit ) == FT_Err_Ok ) + token->limit = cur; + break; + + /************* check for programs/array *****************/ + case '{': + token->type = T1_TOKEN_TYPE_ARRAY; + token->start = cur; + + if ( skip_procedure( &cur, limit ) == FT_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; + embed = 1; + token->start = cur++; + + /* we need this to catch `[ ]' */ + parser->cursor = cur; + ps_parser_skip_spaces( parser ); + cur = parser->cursor; + + while ( cur < limit && !parser->error ) + { + /* XXX: this is wrong because it does not */ + /* skip comments, procedures, and strings */ + if ( *cur == '[' ) + embed++; + else if ( *cur == ']' ) + { + embed--; + if ( embed <= 0 ) + { + token->limit = ++cur; + break; + } + } + + parser->cursor = cur; + ps_parser_skip_PS_token( parser ); + /* we need this to catch `[XXX ]' */ + ps_parser_skip_spaces ( parser ); + cur = parser->cursor; + } + break; + + /* ************ otherwise, it is any token **************/ + default: + token->start = cur; + token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY ); + ps_parser_skip_PS_token( parser ); + cur = parser->cursor; + if ( !parser->error ) + token->limit = cur; + } + + if ( !token->limit ) + { + token->start = 0; + token->type = T1_TOKEN_TYPE_NONE; + } + + parser->cursor = cur; + } + + + /* 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, + FT_UInt max_tokens, + FT_Int* pnum_tokens ) + { + T1_TokenRec master; + + + *pnum_tokens = -1; + + /* this also handles leading whitespace */ + ps_parser_to_token( parser, &master ); + + if ( master.type == T1_TOKEN_TYPE_ARRAY ) + { + FT_Byte* old_cursor = parser->cursor; + FT_Byte* old_limit = parser->limit; + T1_Token cur = tokens; + T1_Token limit = cur + max_tokens; + + + /* don't include outermost delimiters */ + parser->cursor = master.start + 1; + parser->limit = master.limit - 1; + + while ( parser->cursor < parser->limit ) + { + T1_TokenRec token; + + + ps_parser_to_token( parser, &token ); + if ( !token.type ) + break; + + if ( tokens != NULL && cur < limit ) + *cur = token; + + cur++; + } + + *pnum_tokens = (FT_Int)( cur - tokens ); + + parser->cursor = old_cursor; + parser->limit = old_limit; + } + } + + + /* 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, + FT_Byte* limit, + FT_Int max_coords, + FT_Short* coords ) + { + FT_Byte* cur = *acur; + FT_Int count = 0; + FT_Byte c, ender; + + + if ( cur >= limit ) + goto Exit; + + /* check for the beginning of an array; otherwise, only one number */ + /* will be read */ + c = *cur; + ender = 0; + + if ( c == '[' ) + ender = ']'; + else if ( c == '{' ) + ender = '}'; + + if ( ender ) + cur++; + + /* now, read the coordinates */ + while ( cur < limit ) + { + FT_Short dummy; + FT_Byte* old_cur; + + + /* skip whitespace in front of data */ + skip_spaces( &cur, limit ); + if ( cur >= limit ) + goto Exit; + + if ( *cur == ender ) + { + cur++; + break; + } + + old_cur = cur; + + if ( coords != NULL && count >= max_coords ) + break; + + /* 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 ); + + if ( old_cur == cur ) + { + count = -1; + goto Exit; + } + else + count++; + + if ( !ender ) + break; + } + + Exit: + *acur = cur; + return count; + } + + + /* 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, + FT_Byte* limit, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ) + { + FT_Byte* cur = *acur; + FT_Int count = 0; + FT_Byte c, ender; + + + if ( cur >= limit ) + goto Exit; + + /* Check for the beginning of an array. Otherwise, only one number */ + /* will be read. */ + c = *cur; + ender = 0; + + if ( c == '[' ) + ender = ']'; + else if ( c == '{' ) + ender = '}'; + + if ( ender ) + cur++; + + /* now, read the values */ + while ( cur < limit ) + { + FT_Fixed dummy; + FT_Byte* old_cur; + + + /* skip whitespace in front of data */ + skip_spaces( &cur, limit ); + if ( cur >= limit ) + goto Exit; + + if ( *cur == ender ) + { + cur++; + break; + } + + old_cur = cur; + + if ( values != NULL && count >= max_values ) + break; + + /* 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 ); + + if ( old_cur == cur ) + { + count = -1; + goto Exit; + } + else + count++; + + if ( !ender ) + break; + } + + Exit: + *acur = cur; + return count; + } + + +#if 0 + + static FT_String* + ps_tostring( FT_Byte** cursor, + FT_Byte* limit, + FT_Memory memory ) + { + FT_Byte* cur = *cursor; + FT_PtrDist len = 0; + FT_Int count; + FT_String* result; + FT_Error error; + + + /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ + /* that simply doesn't begin with an opening parenthesis, even */ + /* though they have a closing one! E.g. "amuncial.pfb" */ + /* */ + /* We must deal with these ill-fated cases there. Note that */ + /* these fonts didn't work with the old Type 1 driver as the */ + /* notice/copyright was not recognized as a valid string token */ + /* and made the old token parser commit errors. */ + + while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) + cur++; + if ( cur + 1 >= limit ) + return 0; + + if ( *cur == '(' ) + cur++; /* skip the opening parenthesis, if there is one */ + + *cursor = cur; + count = 0; + + /* then, count its length */ + for ( ; cur < limit; cur++ ) + { + if ( *cur == '(' ) + count++; + + else if ( *cur == ')' ) + { + count--; + if ( count < 0 ) + break; + } + } + + len = cur - *cursor; + if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) + return 0; + + /* now copy the string */ + FT_MEM_COPY( result, *cursor, len ); + result[len] = '\0'; + *cursor = cur; + return result; + } + +#endif /* 0 */ + + + static int + ps_tobool( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + FT_Bool result = 0; + + + /* return 1 if we find `true', 0 otherwise */ + if ( cur + 3 < limit && + cur[0] == 't' && + cur[1] == 'r' && + cur[2] == 'u' && + cur[3] == 'e' ) + { + result = 1; + cur += 5; + } + else if ( cur + 4 < limit && + cur[0] == 'f' && + cur[1] == 'a' && + cur[2] == 'l' && + cur[3] == 's' && + cur[4] == 'e' ) + { + result = 0; + cur += 6; + } + + *acur = cur; + return result; + } + + + /* load a simple field (i.e. non-table) into the current list of objects */ + + FT_LOCAL_DEF( FT_Error ) + ps_parser_load_field( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ) + { + T1_TokenRec token; + FT_Byte* cur; + FT_Byte* limit; + FT_UInt count; + FT_UInt idx; + FT_Error error; + T1_FieldType type; + + + /* this also skips leading whitespace */ + ps_parser_to_token( parser, &token ); + if ( !token.type ) + goto Fail; + + count = 1; + idx = 0; + cur = token.start; + limit = token.limit; + + type = field->type; + + /* we must detect arrays in /FontBBox */ + if ( type == T1_FIELD_TYPE_BBOX ) + { + T1_TokenRec token2; + FT_Byte* old_cur = parser->cursor; + FT_Byte* old_limit = parser->limit; + + + /* don't include delimiters */ + parser->cursor = token.start + 1; + parser->limit = token.limit - 1; + + ps_parser_to_token( parser, &token2 ); + parser->cursor = old_cur; + parser->limit = old_limit; + + if ( token2.type == T1_TOKEN_TYPE_ARRAY ) + { + type = T1_FIELD_TYPE_MM_BBOX; + goto FieldArray; + } + } + else if ( token.type == T1_TOKEN_TYPE_ARRAY ) + { + count = max_objects; + + FieldArray: + /* if this is an array and we have no blend, an error occurs */ + if ( max_objects == 0 ) + goto Fail; + + idx = 1; + + /* don't include delimiters */ + cur++; + limit--; + } + + for ( ; count > 0; count--, idx++ ) + { + FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; + FT_Long val; + FT_String* string; + + + skip_spaces( &cur, limit ); + + switch ( type ) + { + case T1_FIELD_TYPE_BOOL: + val = ps_tobool( &cur, limit ); + goto Store_Integer; + + case T1_FIELD_TYPE_FIXED: + val = PS_Conv_ToFixed( &cur, limit, 0 ); + goto Store_Integer; + + case T1_FIELD_TYPE_FIXED_1000: + val = PS_Conv_ToFixed( &cur, limit, 3 ); + goto Store_Integer; + + case T1_FIELD_TYPE_INTEGER: + val = PS_Conv_ToInt( &cur, limit ); + /* fall through */ + + Store_Integer: + switch ( field->size ) + { + case (8 / FT_CHAR_BIT): + *(FT_Byte*)q = (FT_Byte)val; + break; + + case (16 / FT_CHAR_BIT): + *(FT_UShort*)q = (FT_UShort)val; + break; + + case (32 / FT_CHAR_BIT): + *(FT_UInt32*)q = (FT_UInt32)val; + break; + + default: /* for 64-bit systems */ + *(FT_Long*)q = val; + } + break; + + case T1_FIELD_TYPE_STRING: + case T1_FIELD_TYPE_KEY: + { + FT_Memory memory = parser->memory; + FT_UInt len = (FT_UInt)( limit - cur ); + + + if ( cur >= limit ) + break; + + /* 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 if ( token.type == T1_TOKEN_TYPE_STRING ) + { + /* 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\n" + " " + " but found token of type %d instead\n", + token.type )); + error = FT_THROW( 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; + + FT_MEM_COPY( string, cur, len ); + string[len] = 0; + + *(FT_String**)q = string; + } + break; + + case T1_FIELD_TYPE_BBOX: + { + FT_Fixed temp[4]; + FT_BBox* bbox = (FT_BBox*)q; + FT_Int result; + + + result = ps_tofixedarray( &cur, limit, 4, temp, 0 ); + + if ( result < 0 ) + { + FT_ERROR(( "ps_parser_load_field:" + " expected four integers in bounding box\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + bbox->xMin = FT_RoundFix( temp[0] ); + bbox->yMin = FT_RoundFix( temp[1] ); + bbox->xMax = FT_RoundFix( temp[2] ); + bbox->yMax = FT_RoundFix( temp[3] ); + } + break; + + case T1_FIELD_TYPE_MM_BBOX: + { + FT_Memory memory = parser->memory; + FT_Fixed* temp; + FT_Int result; + FT_UInt i; + + + if ( FT_NEW_ARRAY( temp, max_objects * 4 ) ) + goto Exit; + + for ( i = 0; i < 4; i++ ) + { + result = ps_tofixedarray( &cur, limit, max_objects, + temp + i * max_objects, 0 ); + if ( result < 0 ) + { + FT_ERROR(( "ps_parser_load_field:" + " expected %d integers in the %s subarray\n" + " " + " of /FontBBox in the /Blend dictionary\n", + max_objects, + i == 0 ? "first" + : ( i == 1 ? "second" + : ( i == 2 ? "third" + : "fourth" ) ) )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + skip_spaces( &cur, limit ); + } + + for ( i = 0; i < max_objects; i++ ) + { + FT_BBox* bbox = (FT_BBox*)objects[i]; + + + bbox->xMin = FT_RoundFix( temp[i ] ); + bbox->yMin = FT_RoundFix( temp[i + max_objects] ); + bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] ); + bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] ); + } + + FT_FREE( temp ); + } + break; + + default: + /* an error occurred */ + goto Fail; + } + } + +#if 0 /* obsolete -- keep for reference */ + if ( pflags ) + *pflags |= 1L << field->flag_bit; +#else + FT_UNUSED( pflags ); +#endif + + error = FT_Err_Ok; + + Exit: + return error; + + Fail: + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + +#define T1_MAX_TABLE_ELEMENTS 32 + + + FT_LOCAL_DEF( FT_Error ) + ps_parser_load_field_table( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ) + { + T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; + T1_Token token; + FT_Int num_elements; + FT_Error error = FT_Err_Ok; + FT_Byte* old_cursor; + FT_Byte* old_limit; + T1_FieldRec fieldrec = *(T1_Field)field; + + + fieldrec.type = T1_FIELD_TYPE_INTEGER; + if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY || + field->type == T1_FIELD_TYPE_BBOX ) + fieldrec.type = T1_FIELD_TYPE_FIXED; + + ps_parser_to_token_array( parser, elements, + T1_MAX_TABLE_ELEMENTS, &num_elements ); + if ( num_elements < 0 ) + { + error = FT_ERR( Ignore ); + goto Exit; + } + if ( (FT_UInt)num_elements > field->array_max ) + num_elements = field->array_max; + + old_cursor = parser->cursor; + old_limit = parser->limit; + + /* we store the elements count if necessary; */ + /* we further assume that `count_offset' can't be zero */ + if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 ) + *(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; + for ( ; num_elements > 0; num_elements--, token++ ) + { + parser->cursor = token->start; + parser->limit = token->limit; + ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 ); + fieldrec.offset += fieldrec.size; + } + +#if 0 /* obsolete -- keep for reference */ + if ( pflags ) + *pflags |= 1L << field->flag_bit; +#else + FT_UNUSED( pflags ); +#endif + + parser->cursor = old_cursor; + parser->limit = old_limit; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Long ) + ps_parser_to_int( PS_Parser parser ) + { + ps_parser_skip_spaces( parser ); + return PS_Conv_ToInt( &parser->cursor, parser->limit ); + } + + + /* first character must be `<' if `delimiters' is non-zero */ + + FT_LOCAL_DEF( FT_Error ) + ps_parser_to_bytes( PS_Parser parser, + FT_Byte* bytes, + FT_Offset max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ) + { + FT_Error error = FT_Err_Ok; + FT_Byte* cur; + + + ps_parser_skip_spaces( parser ); + cur = parser->cursor; + + if ( cur >= parser->limit ) + goto Exit; + + if ( delimiters ) + { + if ( *cur != '<' ) + { + FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + cur++; + } + + *pnum_bytes = PS_Conv_ASCIIHexDecode( &cur, + parser->limit, + bytes, + max_bytes ); + + if ( delimiters ) + { + if ( cur < parser->limit && *cur != '>' ) + { + FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + cur++; + } + + parser->cursor = cur; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Fixed ) + ps_parser_to_fixed( PS_Parser parser, + FT_Int power_ten ) + { + ps_parser_skip_spaces( parser ); + return PS_Conv_ToFixed( &parser->cursor, parser->limit, power_ten ); + } + + + FT_LOCAL_DEF( FT_Int ) + ps_parser_to_coord_array( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ) + { + ps_parser_skip_spaces( parser ); + return ps_tocoordarray( &parser->cursor, parser->limit, + max_coords, coords ); + } + + + FT_LOCAL_DEF( FT_Int ) + ps_parser_to_fixed_array( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ) + { + ps_parser_skip_spaces( parser ); + return ps_tofixedarray( &parser->cursor, parser->limit, + max_values, values, power_ten ); + } + + +#if 0 + + FT_LOCAL_DEF( FT_String* ) + T1_ToString( PS_Parser parser ) + { + return ps_tostring( &parser->cursor, parser->limit, parser->memory ); + } + + + FT_LOCAL_DEF( FT_Bool ) + T1_ToBool( PS_Parser parser ) + { + return ps_tobool( &parser->cursor, parser->limit ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( void ) + ps_parser_init( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ) + { + parser->error = FT_Err_Ok; + parser->base = base; + parser->limit = limit; + parser->cursor = base; + parser->memory = memory; + parser->funcs = ps_parser_funcs; + } + + + FT_LOCAL_DEF( void ) + ps_parser_done( PS_Parser parser ) + { + FT_UNUSED( parser ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_builder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph builder. */ + /* */ + /* <InOut> */ + /* builder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* glyph :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting should be applied. */ + /* */ + FT_LOCAL_DEF( void ) + t1_builder_init( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot glyph, + FT_Bool hinting ) + { + builder->parse_state = T1_Parse_Start; + builder->load_points = 1; + + builder->face = face; + builder->glyph = glyph; + builder->memory = face->memory; + + if ( glyph ) + { + FT_GlyphLoader loader = glyph->internal->loader; + + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + FT_GlyphLoader_Rewind( loader ); + + builder->hints_globals = size->internal; + builder->hints_funcs = 0; + + if ( hinting ) + builder->hints_funcs = glyph->internal->glyph_hints; + } + + builder->pos_x = 0; + builder->pos_y = 0; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + builder->advance.x = 0; + builder->advance.y = 0; + + builder->funcs = t1_builder_funcs; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_builder_done */ + /* */ + /* <Description> */ + /* Finalizes a given glyph builder. Its contents can still be used */ + /* after the call, but the function saves important information */ + /* within the corresponding glyph slot. */ + /* */ + /* <Input> */ + /* builder :: A pointer to the glyph builder to finalize. */ + /* */ + FT_LOCAL_DEF( void ) + t1_builder_done( T1_Builder builder ) + { + FT_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->outline = *builder->base; + } + + + /* check that there is enough space for `count' more points */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_check_points( T1_Builder builder, + FT_Int count ) + { + return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + FT_LOCAL_DEF( void ) + t1_builder_add_point( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) + { + FT_Outline* outline = builder->current; + + + if ( builder->load_points ) + { + FT_Vector* point = outline->points + outline->n_points; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + + + point->x = FIXED_TO_INT( x ); + point->y = FIXED_TO_INT( y ); + *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); + } + outline->n_points++; + } + + + /* check space for a new on-curve point, then add it */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_add_point1( T1_Builder builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error; + + + error = t1_builder_check_points( builder, 1 ); + if ( !error ) + t1_builder_add_point( builder, x, y, 1 ); + + return error; + } + + + /* check space for a new contour, then add it */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_add_contour( T1_Builder builder ) + { + FT_Outline* outline = builder->current; + FT_Error error; + + + /* this might happen in invalid fonts */ + if ( !outline ) + { + FT_ERROR(( "t1_builder_add_contour: no outline to add points to\n" )); + return FT_THROW( Invalid_File_Format ); + } + + if ( !builder->load_points ) + { + outline->n_contours++; + return FT_Err_Ok; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); + if ( !error ) + { + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + + outline->n_contours++; + } + + return error; + } + + + /* if a path was begun, add its first on-curve point */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_start_point( T1_Builder builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = FT_ERR( Invalid_File_Format ); + + + /* test whether we are building a new contour */ + + if ( builder->parse_state == T1_Parse_Have_Path ) + error = FT_Err_Ok; + else + { + builder->parse_state = T1_Parse_Have_Path; + error = t1_builder_add_contour( builder ); + if ( !error ) + error = t1_builder_add_point1( builder, x, y ); + } + + return error; + } + + + /* close the current contour */ + FT_LOCAL_DEF( void ) + t1_builder_close_contour( T1_Builder builder ) + { + FT_Outline* outline = builder->current; + FT_Int first; + + + if ( !outline ) + return; + + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ + if ( outline->n_points > 1 ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + outline->n_points - 1; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + + + /* `delete' last point only if it coincides with the first */ + /* point and it is not a control point (which can happen). */ + if ( p1->x == p2->x && p1->y == p2->y ) + if ( *control == FT_CURVE_TAG_ON ) + outline->n_points--; + } + + if ( outline->n_contours > 0 ) + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether the first and the last point is the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** OTHER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + t1_decrypt( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ) + { + PS_Conv_EexecDecode( &buffer, + buffer + length, + buffer, + length, + &seed ); + } + + +/* END */ diff --git a/drivers/freetype/src/psaux/psobjs.h b/drivers/freetype/src/psaux/psobjs.h new file mode 100644 index 0000000000..e380c60dab --- /dev/null +++ b/drivers/freetype/src/psaux/psobjs.h @@ -0,0 +1,212 @@ +/***************************************************************************/ +/* */ +/* psobjs.h */ +/* */ +/* Auxiliary functions for PostScript fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003 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 __PSOBJS_H__ +#define __PSOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_TABLE + const PS_Table_FuncsRec ps_table_funcs; + + FT_CALLBACK_TABLE + const PS_Parser_FuncsRec ps_parser_funcs; + + FT_CALLBACK_TABLE + const T1_Builder_FuncsRec t1_builder_funcs; + + + FT_LOCAL( FT_Error ) + ps_table_new( PS_Table table, + FT_Int count, + FT_Memory memory ); + + FT_LOCAL( FT_Error ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ); + + FT_LOCAL( void ) + ps_table_done( PS_Table table ); + + + FT_LOCAL( void ) + ps_table_release( PS_Table table ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL( void ) + ps_parser_skip_spaces( PS_Parser parser ); + + FT_LOCAL( void ) + ps_parser_skip_PS_token( PS_Parser parser ); + + FT_LOCAL( void ) + ps_parser_to_token( PS_Parser parser, + T1_Token token ); + + FT_LOCAL( void ) + ps_parser_to_token_array( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + FT_LOCAL( FT_Error ) + ps_parser_load_field( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_LOCAL( FT_Error ) + ps_parser_load_field_table( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_LOCAL( FT_Long ) + ps_parser_to_int( PS_Parser parser ); + + + FT_LOCAL( FT_Error ) + ps_parser_to_bytes( PS_Parser parser, + FT_Byte* bytes, + FT_Offset max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ); + + + FT_LOCAL( FT_Fixed ) + ps_parser_to_fixed( PS_Parser parser, + FT_Int power_ten ); + + + FT_LOCAL( FT_Int ) + ps_parser_to_coord_array( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ); + + FT_LOCAL( FT_Int ) + ps_parser_to_fixed_array( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + + FT_LOCAL( void ) + ps_parser_init( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + FT_LOCAL( void ) + ps_parser_done( PS_Parser parser ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + t1_builder_init( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot glyph, + FT_Bool hinting ); + + FT_LOCAL( void ) + t1_builder_done( T1_Builder builder ); + + FT_LOCAL( FT_Error ) + t1_builder_check_points( T1_Builder builder, + FT_Int count ); + + FT_LOCAL( void ) + t1_builder_add_point( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + FT_LOCAL( FT_Error ) + t1_builder_add_point1( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + FT_LOCAL( FT_Error ) + t1_builder_add_contour( T1_Builder builder ); + + + FT_LOCAL( FT_Error ) + t1_builder_start_point( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + + FT_LOCAL( void ) + t1_builder_close_contour( T1_Builder builder ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** OTHER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + t1_decrypt( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + +FT_END_HEADER + +#endif /* __PSOBJS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psaux/rules.mk b/drivers/freetype/src/psaux/rules.mk new file mode 100644 index 0000000000..7a1be37b69 --- /dev/null +++ b/drivers/freetype/src/psaux/rules.mk @@ -0,0 +1,73 @@ +# +# FreeType 2 PSaux driver configuration rules +# + + +# Copyright 1996-2000, 2002, 2003, 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. + + +# PSAUX driver directory +# +PSAUX_DIR := $(SRC_DIR)/psaux + + +# compilation flags for the driver +# +PSAUX_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) + + +# PSAUX driver sources (i.e., C files) +# +PSAUX_DRV_SRC := $(PSAUX_DIR)/psobjs.c \ + $(PSAUX_DIR)/t1decode.c \ + $(PSAUX_DIR)/t1cmap.c \ + $(PSAUX_DIR)/afmparse.c \ + $(PSAUX_DIR)/psconv.c \ + $(PSAUX_DIR)/psauxmod.c + +# PSAUX driver headers +# +PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \ + $(PSAUX_DIR)/psauxerr.h + + +# PSAUX driver object(s) +# +# PSAUX_DRV_OBJ_M is used during `multi' builds. +# PSAUX_DRV_OBJ_S is used during `single' builds. +# +PSAUX_DRV_OBJ_M := $(PSAUX_DRV_SRC:$(PSAUX_DIR)/%.c=$(OBJ_DIR)/%.$O) +PSAUX_DRV_OBJ_S := $(OBJ_DIR)/psaux.$O + +# PSAUX driver source file for single build +# +PSAUX_DRV_SRC_S := $(PSAUX_DIR)/psaux.c + + +# PSAUX driver - single object +# +$(PSAUX_DRV_OBJ_S): $(PSAUX_DRV_SRC_S) $(PSAUX_DRV_SRC) \ + $(FREETYPE_H) $(PSAUX_DRV_H) + $(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSAUX_DRV_SRC_S)) + + +# PSAUX driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(PSAUX_DIR)/%.c $(FREETYPE_H) $(PSAUX_DRV_H) + $(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(PSAUX_DRV_OBJ_S) +DRV_OBJS_M += $(PSAUX_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/psaux/t1cmap.c b/drivers/freetype/src/psaux/t1cmap.c new file mode 100644 index 0000000000..9e5bd34ffe --- /dev/null +++ b/drivers/freetype/src/psaux/t1cmap.c @@ -0,0 +1,341 @@ +/***************************************************************************/ +/* */ +/* t1cmap.c */ +/* */ +/* Type 1 character map support (body). */ +/* */ +/* Copyright 2002, 2003, 2006, 2007, 2012 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 "t1cmap.h" + +#include FT_INTERNAL_DEBUG_H + +#include "psauxerr.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t1_cmap_std_init( T1_CMapStd cmap, + FT_Int is_expert ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + cmap->num_glyphs = face->type1.num_glyphs; + cmap->glyph_names = (const char* const*)face->type1.glyph_names; + cmap->sid_to_string = psnames->adobe_std_strings; + cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding + : psnames->adobe_std_encoding; + + FT_ASSERT( cmap->code_to_sid != NULL ); + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_std_done( T1_CMapStd cmap ) + { + cmap->num_glyphs = 0; + cmap->glyph_names = NULL; + cmap->sid_to_string = NULL; + cmap->code_to_sid = NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_std_char_index( T1_CMapStd cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( char_code < 256 ) + { + FT_UInt code, n; + const char* glyph_name; + + + /* convert character code to Adobe SID string */ + code = cmap->code_to_sid[char_code]; + glyph_name = cmap->sid_to_string( code ); + + /* look for the corresponding glyph name */ + for ( n = 0; n < cmap->num_glyphs; n++ ) + { + const char* gname = cmap->glyph_names[n]; + + + if ( gname && gname[0] == glyph_name[0] && + ft_strcmp( gname, glyph_name ) == 0 ) + { + result = n; + break; + } + } + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + t1_cmap_std_char_next( T1_CMapStd cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + while ( char_code < 256 ) + { + result = t1_cmap_std_char_index( cmap, char_code ); + if ( result != 0 ) + goto Exit; + + char_code++; + } + char_code = 0; + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_standard_init( T1_CMapStd cmap ) + { + t1_cmap_std_init( cmap, 0 ); + return 0; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_standard_class_rec = + { + sizeof ( T1_CMapStdRec ), + + (FT_CMap_InitFunc) t1_cmap_standard_init, + (FT_CMap_DoneFunc) t1_cmap_std_done, + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_expert_init( T1_CMapStd cmap ) + { + t1_cmap_std_init( cmap, 1 ); + return 0; + } + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_expert_class_rec = + { + sizeof ( T1_CMapStdRec ), + + (FT_CMap_InitFunc) t1_cmap_expert_init, + (FT_CMap_DoneFunc) t1_cmap_std_done, + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CUSTOM ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_custom_init( T1_CMapCustom cmap ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + T1_Encoding encoding = &face->type1.encoding; + + + cmap->first = encoding->code_first; + cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); + cmap->indices = encoding->char_index; + + FT_ASSERT( cmap->indices != NULL ); + FT_ASSERT( encoding->code_first <= encoding->code_last ); + + return 0; + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_custom_done( T1_CMapCustom cmap ) + { + cmap->indices = NULL; + cmap->first = 0; + cmap->count = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_custom_char_index( T1_CMapCustom cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( ( char_code >= cmap->first ) && + ( char_code < ( cmap->first + cmap->count ) ) ) + result = cmap->indices[char_code]; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + t1_cmap_custom_char_next( T1_CMapCustom cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code; + + + ++char_code; + + if ( char_code < cmap->first ) + char_code = cmap->first; + + for ( ; char_code < ( cmap->first + cmap->count ); char_code++ ) + { + result = cmap->indices[char_code]; + if ( result != 0 ) + goto Exit; + } + + char_code = 0; + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_custom_class_rec = + { + sizeof ( T1_CMapCustomRec ), + + (FT_CMap_InitFunc) t1_cmap_custom_init, + (FT_CMap_DoneFunc) t1_cmap_custom_done, + (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( const char * ) + psaux_get_glyph_name( T1_Face face, + FT_UInt idx ) + { + return face->type1.glyph_names[idx]; + } + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_unicode_init( PS_Unicodes unicodes ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_init( memory, + unicodes, + face->type1.num_glyphs, + (PS_GetGlyphNameFunc)&psaux_get_glyph_name, + (PS_FreeGlyphNameFunc)NULL, + (FT_Pointer)face ); + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_unicode_done( PS_Unicodes unicodes ) + { + FT_Face face = FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( unicodes->maps ); + unicodes->num_maps = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_unicode_char_index( PS_Unicodes unicodes, + FT_UInt32 char_code ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_char_index( unicodes, char_code ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + t1_cmap_unicode_char_next( PS_Unicodes unicodes, + FT_UInt32 *pchar_code ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_char_next( unicodes, pchar_code ); + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_unicode_class_rec = + { + sizeof ( PS_UnicodesRec ), + + (FT_CMap_InitFunc) t1_cmap_unicode_init, + (FT_CMap_DoneFunc) t1_cmap_unicode_done, + (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + +/* END */ diff --git a/drivers/freetype/src/psaux/t1cmap.h b/drivers/freetype/src/psaux/t1cmap.h new file mode 100644 index 0000000000..7ae65d2fa1 --- /dev/null +++ b/drivers/freetype/src/psaux/t1cmap.h @@ -0,0 +1,105 @@ +/***************************************************************************/ +/* */ +/* t1cmap.h */ +/* */ +/* Type 1 character map support (specification). */ +/* */ +/* Copyright 2002, 2003, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1CMAP_H__ +#define __T1CMAP_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TYPE1_TYPES_H + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* standard (and expert) encoding cmaps */ + typedef struct T1_CMapStdRec_* T1_CMapStd; + + typedef struct T1_CMapStdRec_ + { + FT_CMapRec cmap; + + const FT_UShort* code_to_sid; + PS_Adobe_Std_StringsFunc sid_to_string; + + FT_UInt num_glyphs; + const char* const* glyph_names; + + } T1_CMapStdRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_standard_class_rec; + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_expert_class_rec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CUSTOM ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct T1_CMapCustomRec_* T1_CMapCustom; + + typedef struct T1_CMapCustomRec_ + { + FT_CMapRec cmap; + FT_UInt first; + FT_UInt count; + FT_UShort* indices; + + } T1_CMapCustomRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_custom_class_rec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* unicode (synthetic) cmaps */ + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_unicode_class_rec; + + /* */ + + +FT_END_HEADER + +#endif /* __T1CMAP_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psaux/t1decode.c b/drivers/freetype/src/psaux/t1decode.c new file mode 100644 index 0000000000..6ce370bfaa --- /dev/null +++ b/drivers/freetype/src/psaux/t1decode.c @@ -0,0 +1,1620 @@ +/***************************************************************************/ +/* */ +/* t1decode.c */ +/* */ +/* PostScript Type 1 decoding routines (body). */ +/* */ +/* Copyright 2000-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_OUTLINE_H + +#include "t1decode.h" +#include "psobjs.h" + +#include "psauxerr.h" + +/* ensure proper sign extension */ +#define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) ) + + /*************************************************************************/ + /* */ + /* 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_t1decode + + + typedef enum T1_Operator_ + { + op_none = 0, + op_endchar, + op_hsbw, + op_seac, + op_sbw, + op_closepath, + op_hlineto, + op_hmoveto, + op_hvcurveto, + op_rlineto, + op_rmoveto, + op_rrcurveto, + op_vhcurveto, + op_vlineto, + op_vmoveto, + op_dotsection, + op_hstem, + op_hstem3, + op_vstem, + op_vstem3, + op_div, + op_callothersubr, + op_callsubr, + op_pop, + op_return, + op_setcurrentpoint, + op_unknown15, + + op_max /* never remove this one */ + + } T1_Operator; + + + static + const FT_Int t1_args_count[op_max] = + { + 0, /* none */ + 0, /* endchar */ + 2, /* hsbw */ + 5, /* seac */ + 4, /* sbw */ + 0, /* closepath */ + 1, /* hlineto */ + 1, /* hmoveto */ + 4, /* hvcurveto */ + 2, /* rlineto */ + 2, /* rmoveto */ + 6, /* rrcurveto */ + 4, /* vhcurveto */ + 1, /* vlineto */ + 1, /* vmoveto */ + 0, /* dotsection */ + 2, /* hstem */ + 6, /* hstem3 */ + 2, /* vstem */ + 6, /* vstem3 */ + 2, /* div */ + -1, /* callothersubr */ + 1, /* callsubr */ + 0, /* pop */ + 0, /* return */ + 2, /* setcurrentpoint */ + 2 /* opcode 15 (undocumented and obsolete) */ + }; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_lookup_glyph_by_stdcharcode */ + /* */ + /* <Description> */ + /* Looks up a given glyph by its StandardEncoding charcode. Used to */ + /* implement the SEAC Type 1 operator. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* charcode :: The character code to look for. */ + /* */ + /* <Return> */ + /* A glyph index in the font face. Returns -1 if the corresponding */ + /* glyph wasn't found. */ + /* */ + static FT_Int + t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, + FT_Int charcode ) + { + FT_UInt n; + const FT_String* glyph_name; + FT_Service_PsCMaps psnames = decoder->psnames; + + + /* check range of standard char code */ + if ( charcode < 0 || charcode > 255 ) + return -1; + + glyph_name = psnames->adobe_std_strings( + psnames->adobe_std_encoding[charcode]); + + for ( n = 0; n < decoder->num_glyphs; n++ ) + { + FT_String* name = (FT_String*)decoder->glyph_names[n]; + + + if ( name && + name[0] == glyph_name[0] && + ft_strcmp( name, glyph_name ) == 0 ) + return n; + } + + return -1; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1operator_seac */ + /* */ + /* <Description> */ + /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ + /* */ + /* <Input> */ + /* decoder :: The current CID decoder. */ + /* */ + /* asb :: The accent's side bearing. */ + /* */ + /* adx :: The horizontal offset of the accent. */ + /* */ + /* ady :: The vertical offset of the accent. */ + /* */ + /* bchar :: The base character's StandardEncoding charcode. */ + /* */ + /* achar :: The accent character's StandardEncoding charcode. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + t1operator_seac( T1_Decoder decoder, + FT_Pos asb, + FT_Pos adx, + FT_Pos ady, + FT_Int bchar, + FT_Int achar ) + { + FT_Error error; + FT_Int bchar_index, achar_index; +#if 0 + FT_Int n_base_points; + FT_Outline* base = decoder->builder.base; +#endif + FT_Vector left_bearing, advance; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + T1_Face face = (T1_Face)decoder->builder.face; +#endif + + + if ( decoder->seac ) + { + FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); + return FT_THROW( Syntax_Error ); + } + + if ( decoder->builder.metrics_only ) + { + FT_ERROR(( "t1operator_seac: unexpected seac\n" )); + return FT_THROW( Syntax_Error ); + } + + /* seac weirdness */ + adx += decoder->builder.left_bearing.x; + + /* `glyph_names' is set to 0 for CID fonts which do not */ + /* include an encoding. How can we deal with these? */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( decoder->glyph_names == 0 && + !face->root.internal->incremental_interface ) +#else + if ( decoder->glyph_names == 0 ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + FT_ERROR(( "t1operator_seac:" + " glyph names table not available in this font\n" )); + return FT_THROW( Syntax_Error ); + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + { + /* the caller must handle the font encoding also */ + bchar_index = bchar; + achar_index = achar; + } + else +#endif + { + bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); + achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); + } + + if ( bchar_index < 0 || achar_index < 0 ) + { + FT_ERROR(( "t1operator_seac:" + " invalid seac character code arguments\n" )); + return FT_THROW( Syntax_Error ); + } + + /* if we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ + if ( decoder->builder.no_recurse ) + { + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphLoader loader = glyph->internal->loader; + FT_SubGlyph subg; + + + /* reallocate subglyph array if necessary */ + error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); + if ( error ) + goto Exit; + + subg = loader->current.subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); + subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->subglyphs = loader->base.subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + loader->current.num_subglyphs = 2; + goto Exit; + } + + /* First load `bchar' in builder */ + /* now load the unscaled outline */ + + FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = t1_decoder_parse_glyph( decoder, bchar_index ); + decoder->seac = FALSE; + if ( error ) + goto Exit; + + /* save the left bearing and width of the base character */ + /* as they will be erased by the next load. */ + + left_bearing = decoder->builder.left_bearing; + advance = decoder->builder.advance; + + decoder->builder.left_bearing.x = 0; + decoder->builder.left_bearing.y = 0; + + decoder->builder.pos_x = adx - asb; + decoder->builder.pos_y = ady; + + /* Now load `achar' on top of */ + /* the base outline */ + + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = t1_decoder_parse_glyph( decoder, achar_index ); + decoder->seac = FALSE; + if ( error ) + goto Exit; + + /* restore the left side bearing and */ + /* advance width of the base character */ + + decoder->builder.left_bearing = left_bearing; + decoder->builder.advance = advance; + + decoder->builder.pos_x = 0; + decoder->builder.pos_y = 0; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_decoder_parse_charstrings */ + /* */ + /* <Description> */ + /* Parses a given Type 1 charstrings program. */ + /* */ + /* <Input> */ + /* decoder :: The current Type 1 decoder. */ + /* */ + /* charstring_base :: The base address of the charstring stream. */ + /* */ + /* charstring_len :: The length in bytes of the charstring stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_parse_charstrings( T1_Decoder decoder, + FT_Byte* charstring_base, + FT_UInt charstring_len ) + { + FT_Error error; + T1_Decoder_Zone zone; + FT_Byte* ip; + 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; + FT_Bool large_int; + FT_Fixed seed; + + T1_Hints_Funcs hinter; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool bol = TRUE; +#endif + + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; + if ( seed == 0 ) + seed = 0x7384; + + /* First of all, initialize the decoder */ + decoder->top = decoder->stack; + decoder->zone = decoder->zones; + zone = decoder->zones; + + builder->parse_state = T1_Parse_Start; + + 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->buildchar && decoder->len_buildchar > 0 ) + ft_memset( &decoder->buildchar[0], + 0, + sizeof ( decoder->buildchar[0] ) * decoder->len_buildchar ); + + FT_TRACE4(( "\n" + "Start charstring\n" )); + + zone->base = charstring_base; + limit = zone->limit = charstring_base + charstring_len; + ip = zone->cursor = zone->base; + + error = FT_Err_Ok; + + x = orig_x = builder->pos_x; + y = orig_y = builder->pos_y; + + /* begin hints recording session, if any */ + if ( hinter ) + hinter->open( hinter->hints ); + + large_int = FALSE; + + /* now, execute loop */ + while ( ip < limit ) + { + FT_Long* top = decoder->top; + T1_Operator op = op_none; + FT_Int32 value = 0; + + + FT_ASSERT( known_othersubr_result_cnt == 0 || + unknown_othersubr_result_cnt == 0 ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( bol ) + { + FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + bol = FALSE; + } +#endif + + /*********************************************************************/ + /* */ + /* Decode operator or operand */ + /* */ + /* */ + + /* first of all, decompress operator or value */ + switch ( *ip++ ) + { + case 1: + op = op_hstem; + break; + + case 3: + op = op_vstem; + break; + case 4: + op = op_vmoveto; + break; + case 5: + op = op_rlineto; + break; + case 6: + op = op_hlineto; + break; + case 7: + op = op_vlineto; + break; + case 8: + op = op_rrcurveto; + break; + case 9: + op = op_closepath; + break; + case 10: + op = op_callsubr; + break; + case 11: + op = op_return; + break; + + case 13: + op = op_hsbw; + break; + case 14: + op = op_endchar; + break; + + case 15: /* undocumented, obsolete operator */ + op = op_unknown15; + break; + + case 21: + op = op_rmoveto; + break; + case 22: + op = op_hmoveto; + break; + + case 30: + op = op_vhcurveto; + break; + case 31: + op = op_hvcurveto; + break; + + case 12: + if ( ip > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+EOF)\n" )); + goto Syntax_Error; + } + + switch ( *ip++ ) + { + case 0: + op = op_dotsection; + break; + case 1: + op = op_vstem3; + break; + case 2: + op = op_hstem3; + break; + case 6: + op = op_seac; + break; + case 7: + op = op_sbw; + break; + case 12: + op = op_div; + break; + case 16: + op = op_callothersubr; + break; + case 17: + op = op_pop; + break; + case 33: + op = op_setcurrentpoint; + break; + + default: + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+%d)\n", + ip[-1] )); + goto Syntax_Error; + } + break; + + case 255: /* four bytes integer */ + if ( ip + 4 > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | + ( (FT_UInt32)ip[1] << 16 ) | + ( (FT_UInt32)ip[2] << 8 ) | + (FT_UInt32)ip[3] ); + ip += 4; + + /* According to the specification, values > 32000 or < -32000 must */ + /* be followed by a `div' operator to make the result be in the */ + /* range [-32000;32000]. We expect that the second argument of */ + /* `div' is not a large number. Additionally, we don't handle */ + /* stuff like `<large1> <large2> <num> div <num> div' or */ + /* <large1> <large2> <num> div div'. This is probably not allowed */ + /* anyway. */ + if ( value > 32000 || value < -32000 ) + { + if ( large_int ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + } + else + large_int = TRUE; + } + else + { + if ( !large_int ) + value = (FT_Int32)( (FT_UInt32)value << 16 ); + } + + break; + + default: + if ( ip[-1] >= 32 ) + { + if ( ip[-1] < 247 ) + value = (FT_Int32)ip[-1] - 139; + else + { + if ( ++ip > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + if ( ip[-2] < 251 ) + value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108; + else + value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 ); + } + + if ( !large_int ) + value = (FT_Int32)( (FT_UInt32)value << 16 ); + } + else + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid byte (%d)\n", ip[-1] )); + goto Syntax_Error; + } + } + + 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; + } + } + + if ( large_int && !( op == op_none || op == op_div ) ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + + large_int = FALSE; + } + + /*********************************************************************/ + /* */ + /* Push value on stack, or process operator */ + /* */ + /* */ + if ( op == op_none ) + { + if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); + goto Syntax_Error; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( large_int ) + FT_TRACE4(( " %ld", value )); + else + FT_TRACE4(( " %ld", Fix2Int( value ) )); +#endif + + *top++ = value; + decoder->top = top; + } + else if ( op == op_callothersubr ) /* callothersubr */ + { + FT_Int subr_no; + FT_Int arg_cnt; + + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " callothersubr\n" )); + bol = TRUE; +#endif + + if ( top - decoder->stack < 2 ) + goto Stack_Underflow; + + top -= 2; + + subr_no = Fix2Int( top[1] ); + arg_cnt = Fix2Int( 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 0: /* end flex feature */ + if ( arg_cnt != 3 ) + goto Unexpected_OtherSubr; + + if ( decoder->flex_state == 0 || + decoder->num_flex_vectors != 7 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected flex end\n" )); + goto Syntax_Error; + } + + /* the two `results' are popped by the following setcurrentpoint */ + top[0] = x; + top[1] = y; + known_othersubr_result_cnt = 2; + break; + + case 1: /* start flex feature */ + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + decoder->flex_state = 1; + decoder->num_flex_vectors = 0; + if ( ( error = t1_builder_start_point( builder, x, y ) ) + != FT_Err_Ok || + ( error = t1_builder_check_points( builder, 6 ) ) + != FT_Err_Ok ) + goto Fail; + break; + + case 2: /* add flex vectors */ + { + FT_Int idx; + + + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + if ( decoder->flex_state == 0 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " missing flex start\n" )); + goto Syntax_Error; + } + + /* note that we should not add a point for index 0; */ + /* this will move our current position to the flex */ + /* point without adding any point to the outline */ + idx = decoder->num_flex_vectors++; + if ( idx > 0 && idx < 7 ) + t1_builder_add_point( builder, + x, + y, + (FT_Byte)( idx == 3 || idx == 6 ) ); + } + break; + + case 3: /* change hints */ + if ( arg_cnt != 1 ) + goto Unexpected_OtherSubr; + + known_othersubr_result_cnt = 1; + + if ( hinter ) + hinter->reset( hinter->hints, builder->current->n_points ); + break; + + case 12: + case 13: + /* counter control hints, clear stack */ + top = decoder->stack; + break; + + case 14: + case 15: + case 16: + case 17: + case 18: /* multiple masters */ + { + PS_Blend blend = decoder->blend; + FT_UInt num_points, nn, mm; + FT_Long* delta; + FT_Long* values; + + + if ( !blend ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected multiple masters operator\n" )); + goto Syntax_Error; + } + + 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:" + " incorrect number of multiple masters arguments\n" )); + goto Syntax_Error; + } + + /* We want to compute */ + /* */ + /* a0*w0 + a1*w1 + ... + ak*wk */ + /* */ + /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */ + /* */ + /* However, given that w0 + w1 + ... + wk == 1, we can */ + /* rewrite it easily as */ + /* */ + /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */ + /* */ + /* where k == num_designs-1. */ + /* */ + /* I guess that's why it's written in this `compact' */ + /* form. */ + /* */ + delta = top + num_points; + values = top; + for ( nn = 0; nn < num_points; nn++ ) + { + FT_Long tmp = values[0]; + + + for ( mm = 1; mm < blend->num_designs; mm++ ) + tmp += FT_MulFix( *delta++, blend->weight_vector[mm] ); + + *values++ = tmp; + } + + known_othersubr_result_cnt = num_points; + break; + } + + 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 = Fix2Int( top[0] ); + + if ( idx < 0 || + idx + blend->num_designs > decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + ft_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] = FT_MulFix( top[0], top[1] ); + + 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] = FT_DivFix( top[0], top[1] ); + + known_othersubr_result_cnt = 1; + break; + + 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 = Fix2Int( 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 = Fix2Int( 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 which routine has left its 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; + + case 28: + /* 0 28 callothersubr pop */ + /* => push random value from interval [0, 1) onto stack */ + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + { + FT_Fixed Rand; + + + Rand = seed; + if ( Rand >= 0x8000L ) + Rand++; + + top[0] = Rand; + + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + } + + known_othersubr_result_cnt = 1; + break; + + default: + if ( arg_cnt >= 0 && subr_no >= 0 ) + { + 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; + } + /* fall through */ + + Unexpected_OtherSubr: + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid othersubr [%d %d]\n", arg_cnt, subr_no )); + goto Syntax_Error; + } + + top += known_othersubr_result_cnt; + + decoder->top = top; + } + else /* general operator */ + { + 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(( "t1_decoder_parse_charstrings:" + " too much operands on the stack" + " (seen %d, expected %d)\n", + top - decoder->stack, num_args )); + break; + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + top -= num_args; + + switch ( op ) + { + case op_endchar: + FT_TRACE4(( " endchar\n" )); + + t1_builder_close_contour( builder ); + + /* close hints recording session */ + if ( hinter ) + { + if ( hinter->close( hinter->hints, builder->current->n_points ) ) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + } + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* 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! */ + return FT_Err_Ok; + + case op_hsbw: + FT_TRACE4(( " hsbw" )); + + builder->parse_state = T1_Parse_Have_Width; + + builder->left_bearing.x += top[0]; + builder->advance.x = top[1]; + builder->advance.y = 0; + + orig_x = x = builder->pos_x + top[0]; + orig_y = y = builder->pos_y; + + FT_UNUSED( orig_y ); + + /* the `metrics_only' indicates that we only want to compute */ + /* the glyph's metrics (lsb + advance width), not load the */ + /* rest of it; so exit immediately */ + if ( builder->metrics_only ) + return FT_Err_Ok; + + break; + + case op_seac: + return t1operator_seac( decoder, + top[0], + top[1], + top[2], + Fix2Int( top[3] ), + Fix2Int( top[4] ) ); + + case op_sbw: + FT_TRACE4(( " sbw" )); + + builder->parse_state = T1_Parse_Have_Width; + + builder->left_bearing.x += top[0]; + builder->left_bearing.y += top[1]; + builder->advance.x = top[2]; + builder->advance.y = top[3]; + + x = builder->pos_x + top[0]; + y = builder->pos_y + top[1]; + + /* the `metrics_only' indicates that we only want to compute */ + /* the glyph's metrics (lsb + advance width), not load the */ + /* rest of it; so exit immediately */ + if ( builder->metrics_only ) + return FT_Err_Ok; + + break; + + case op_closepath: + FT_TRACE4(( " closepath" )); + + /* if there is no path, `closepath' is a no-op */ + if ( builder->parse_state == T1_Parse_Have_Path || + builder->parse_state == T1_Parse_Have_Moveto ) + t1_builder_close_contour( builder ); + + builder->parse_state = T1_Parse_Have_Width; + break; + + case op_hlineto: + FT_TRACE4(( " hlineto" )); + + if ( ( error = t1_builder_start_point( builder, x, y ) ) + != FT_Err_Ok ) + goto Fail; + + x += top[0]; + goto Add_Line; + + case op_hmoveto: + FT_TRACE4(( " hmoveto" )); + + x += top[0]; + if ( !decoder->flex_state ) + { + if ( builder->parse_state == T1_Parse_Start ) + goto Syntax_Error; + builder->parse_state = T1_Parse_Have_Moveto; + } + break; + + case op_hvcurveto: + FT_TRACE4(( " hvcurveto" )); + + if ( ( error = t1_builder_start_point( builder, x, y ) ) + != FT_Err_Ok || + ( error = t1_builder_check_points( builder, 3 ) ) + != FT_Err_Ok ) + goto Fail; + + x += top[0]; + t1_builder_add_point( builder, x, y, 0 ); + x += top[1]; + y += top[2]; + t1_builder_add_point( builder, x, y, 0 ); + y += top[3]; + t1_builder_add_point( builder, x, y, 1 ); + break; + + case op_rlineto: + FT_TRACE4(( " rlineto" )); + + if ( ( error = t1_builder_start_point( builder, x, y ) ) + != FT_Err_Ok ) + goto Fail; + + x += top[0]; + y += top[1]; + + Add_Line: + if ( ( error = t1_builder_add_point1( builder, x, y ) ) + != FT_Err_Ok ) + goto Fail; + break; + + case op_rmoveto: + FT_TRACE4(( " rmoveto" )); + + x += top[0]; + y += top[1]; + if ( !decoder->flex_state ) + { + if ( builder->parse_state == T1_Parse_Start ) + goto Syntax_Error; + builder->parse_state = T1_Parse_Have_Moveto; + } + break; + + case op_rrcurveto: + FT_TRACE4(( " rrcurveto" )); + + if ( ( error = t1_builder_start_point( builder, x, y ) ) + != FT_Err_Ok || + ( error = t1_builder_check_points( builder, 3 ) ) + != FT_Err_Ok ) + goto Fail; + + x += top[0]; + y += top[1]; + t1_builder_add_point( builder, x, y, 0 ); + + x += top[2]; + y += top[3]; + t1_builder_add_point( builder, x, y, 0 ); + + x += top[4]; + y += top[5]; + t1_builder_add_point( builder, x, y, 1 ); + break; + + case op_vhcurveto: + FT_TRACE4(( " vhcurveto" )); + + if ( ( error = t1_builder_start_point( builder, x, y ) ) + != FT_Err_Ok || + ( error = t1_builder_check_points( builder, 3 ) ) + != FT_Err_Ok ) + goto Fail; + + y += top[0]; + t1_builder_add_point( builder, x, y, 0 ); + x += top[1]; + y += top[2]; + t1_builder_add_point( builder, x, y, 0 ); + x += top[3]; + t1_builder_add_point( builder, x, y, 1 ); + break; + + case op_vlineto: + FT_TRACE4(( " vlineto" )); + + if ( ( error = t1_builder_start_point( builder, x, y ) ) + != FT_Err_Ok ) + goto Fail; + + y += top[0]; + goto Add_Line; + + case op_vmoveto: + FT_TRACE4(( " vmoveto" )); + + y += top[0]; + if ( !decoder->flex_state ) + { + if ( builder->parse_state == T1_Parse_Start ) + goto Syntax_Error; + builder->parse_state = T1_Parse_Have_Moveto; + } + break; + + case op_div: + FT_TRACE4(( " div" )); + + /* if `large_int' is set, we divide unscaled numbers; */ + /* otherwise, we divide numbers in 16.16 format -- */ + /* in both cases, it is the same operation */ + *top = FT_DivFix( top[0], top[1] ); + ++top; + + large_int = FALSE; + break; + + case op_callsubr: + { + FT_Int idx; + + + FT_TRACE4(( " callsubr" )); + + idx = Fix2Int( top[0] ); + if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid subrs index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + + /* The Type 1 driver stores subroutines without the seed bytes. */ + /* The CID driver stores subroutines with seed bytes. This */ + /* case is taken care of when decoder->subrs_len == 0. */ + zone->base = decoder->subrs[idx]; + + if ( decoder->subrs_len ) + zone->limit = zone->base + decoder->subrs_len[idx]; + else + { + /* We are using subroutines from a CID font. We must adjust */ + /* for the seed bytes. */ + zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + zone->limit = decoder->subrs[idx + 1]; + } + + zone->cursor = zone->base; + + if ( !zone->base ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invoking empty subrs\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + break; + } + + case op_pop: + FT_TRACE4(( " pop" )); + + 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: + FT_TRACE4(( " return" )); + + if ( zone <= decoder->zones ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected return\n" )); + goto Syntax_Error; + } + + zone--; + ip = zone->cursor; + limit = zone->limit; + decoder->zone = zone; + break; + + case op_dotsection: + FT_TRACE4(( " dotsection" )); + + break; + + case op_hstem: + FT_TRACE4(( " hstem" )); + + /* record horizontal hint */ + if ( hinter ) + { + /* top[0] += builder->left_bearing.y; */ + hinter->stem( hinter->hints, 1, top ); + } + break; + + case op_hstem3: + FT_TRACE4(( " hstem3" )); + + /* record horizontal counter-controlled hints */ + if ( hinter ) + hinter->stem3( hinter->hints, 1, top ); + break; + + case op_vstem: + FT_TRACE4(( " vstem" )); + + /* record vertical hint */ + if ( hinter ) + { + top[0] += orig_x; + hinter->stem( hinter->hints, 0, top ); + } + break; + + case op_vstem3: + FT_TRACE4(( " vstem3" )); + + /* record vertical counter-controlled hints */ + if ( hinter ) + { + FT_Pos dx = orig_x; + + + top[0] += dx; + top[2] += dx; + top[4] += dx; + hinter->stem3( hinter->hints, 0, top ); + } + break; + + case op_setcurrentpoint: + FT_TRACE4(( " setcurrentpoint" )); + + /* From the T1 specification, 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. */ + + /* Note, however, that both Ghostscript and Adobe */ + /* Distiller handle this situation by silently ignoring */ + /* the inappropriate `setcurrentpoint' instruction. So */ + /* we do the same. */ +#if 0 + + if ( decoder->flex_state != 1 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected `setcurrentpoint'\n" )); + goto Syntax_Error; + } + else + ... +#endif + + x = top[0]; + y = top[1]; + 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:" + " unhandled opcode %d\n", op )); + 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; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( "\n" )); + bol = TRUE; +#endif + + } /* general operator processing */ + + } /* while ip < limit */ + + FT_TRACE4(( "..end..\n\n" )); + + Fail: + return error; + + Syntax_Error: + return FT_THROW( Syntax_Error ); + + Stack_Underflow: + return FT_THROW( Stack_Underflow ); + } + + + /* parse a single Type 1 glyph */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_parse_glyph( T1_Decoder decoder, + FT_UInt glyph ) + { + return decoder->parse_callback( decoder, glyph ); + } + + + /* initialize T1 decoder */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_init( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback parse_callback ) + { + FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + + /* retrieve PSNames interface from list of current modules */ + { + FT_Service_PsCMaps psnames = 0; + + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + if ( !psnames ) + { + FT_ERROR(( "t1_decoder_init:" + " the `psnames' module is not available\n" )); + return FT_THROW( Unimplemented_Feature ); + } + + decoder->psnames = psnames; + } + + 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; + decoder->blend = blend; + decoder->parse_callback = parse_callback; + + decoder->funcs = t1_decoder_funcs; + + return FT_Err_Ok; + } + + + /* finalize T1 decoder */ + FT_LOCAL_DEF( void ) + t1_decoder_done( T1_Decoder decoder ) + { + t1_builder_done( &decoder->builder ); + } + + +/* END */ diff --git a/drivers/freetype/src/psaux/t1decode.h b/drivers/freetype/src/psaux/t1decode.h new file mode 100644 index 0000000000..00728db501 --- /dev/null +++ b/drivers/freetype/src/psaux/t1decode.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* t1decode.h */ +/* */ +/* PostScript Type 1 decoding routines (specification). */ +/* */ +/* Copyright 2000-2001, 2002, 2003 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 __T1DECODE_H__ +#define __T1DECODE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + FT_CALLBACK_TABLE + const T1_Decoder_FuncsRec t1_decoder_funcs; + + + FT_LOCAL( FT_Error ) + t1_decoder_parse_glyph( T1_Decoder decoder, + FT_UInt glyph_index ); + + FT_LOCAL( FT_Error ) + t1_decoder_parse_charstrings( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); + + FT_LOCAL( FT_Error ) + t1_decoder_init( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback parse_glyph ); + + FT_LOCAL( void ) + t1_decoder_done( T1_Decoder decoder ); + + +FT_END_HEADER + +#endif /* __T1DECODE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/Jamfile b/drivers/freetype/src/pshinter/Jamfile new file mode 100644 index 0000000000..779f1b0b82 --- /dev/null +++ b/drivers/freetype/src/pshinter/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/pshinter Jamfile +# +# Copyright 2001, 2003 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = pshrec pshglob pshalgo pshmod pshpic ; + } + else + { + _sources = pshinter ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/pshinter Jamfile diff --git a/drivers/freetype/src/pshinter/module.mk b/drivers/freetype/src/pshinter/module.mk new file mode 100644 index 0000000000..ed24eb7fa8 --- /dev/null +++ b/drivers/freetype/src/pshinter/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 PSHinter module definition +# + + +# Copyright 1996-2001, 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. + + +FTMODULE_H_COMMANDS += PSHINTER_MODULE + +define PSHINTER_MODULE +$(OPEN_DRIVER) FT_Module_Class, pshinter_module_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)pshinter $(ECHO_DRIVER_DESC)Postscript hinter module$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/pshinter/pshalgo.c b/drivers/freetype/src/pshinter/pshalgo.c new file mode 100644 index 0000000000..343472ddb3 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshalgo.c @@ -0,0 +1,2305 @@ +/***************************************************************************/ +/* */ +/* pshalgo.c */ +/* */ +/* PostScript hinting algorithm (body). */ +/* */ +/* Copyright 2001-2010, 2012, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used */ +/* modified and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include "pshalgo.h" + +#include "pshnterr.h" + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pshalgo2 + + +#ifdef DEBUG_HINTER + PSH_Hint_Table ps_debug_hint_table = 0; + PSH_HintFunc ps_debug_hint_func = 0; + PSH_Glyph ps_debug_glyph = 0; +#endif + + +#define COMPUTE_INFLEXS /* compute inflection points to optimize `S' */ + /* and similar glyphs */ +#define STRONGER /* slightly increase the contrast of smooth */ + /* hinting */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC HINTS RECORDINGS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* return true if two stem hints overlap */ + static FT_Int + psh_hint_overlap( PSH_Hint hint1, + PSH_Hint hint2 ) + { + return hint1->org_pos + hint1->org_len >= hint2->org_pos && + hint2->org_pos + hint2->org_len >= hint1->org_pos; + } + + + /* destroy hints table */ + static void + psh_hint_table_done( PSH_Hint_Table table, + FT_Memory memory ) + { + FT_FREE( table->zones ); + table->num_zones = 0; + table->zone = 0; + + FT_FREE( table->sort ); + FT_FREE( table->hints ); + table->num_hints = 0; + table->max_hints = 0; + table->sort_global = 0; + } + + + /* deactivate all hints in a table */ + static void + psh_hint_table_deactivate( PSH_Hint_Table table ) + { + FT_UInt count = table->max_hints; + PSH_Hint hint = table->hints; + + + for ( ; count > 0; count--, hint++ ) + { + psh_hint_deactivate( hint ); + hint->order = -1; + } + } + + + /* internal function to record a new hint */ + static void + psh_hint_table_record( PSH_Hint_Table table, + FT_UInt idx ) + { + PSH_Hint hint = table->hints + idx; + + + if ( idx >= table->max_hints ) + { + FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx )); + return; + } + + /* ignore active hints */ + if ( psh_hint_is_active( hint ) ) + return; + + psh_hint_activate( hint ); + + /* now scan the current active hint set to check */ + /* whether `hint' overlaps with another hint */ + { + PSH_Hint* sorted = table->sort_global; + FT_UInt count = table->num_hints; + PSH_Hint hint2; + + + hint->parent = 0; + for ( ; count > 0; count--, sorted++ ) + { + hint2 = sorted[0]; + + if ( psh_hint_overlap( hint, hint2 ) ) + { + hint->parent = hint2; + break; + } + } + } + + if ( table->num_hints < table->max_hints ) + table->sort_global[table->num_hints++] = hint; + else + FT_TRACE0(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); + } + + + static void + psh_hint_table_record_mask( PSH_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit; + + + limit = hint_mask->num_bits; + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + psh_hint_table_record( table, idx ); + + mask >>= 1; + } + } + + + /* create hints table */ + static FT_Error + psh_hint_table_init( PSH_Hint_Table table, + PS_Hint_Table hints, + PS_Mask_Table hint_masks, + PS_Mask_Table counter_masks, + FT_Memory memory ) + { + FT_UInt count; + FT_Error error; + + FT_UNUSED( counter_masks ); + + + count = hints->num_hints; + + /* allocate our tables */ + if ( FT_NEW_ARRAY( table->sort, 2 * count ) || + FT_NEW_ARRAY( table->hints, count ) || + FT_NEW_ARRAY( table->zones, 2 * count + 1 ) ) + goto Exit; + + table->max_hints = count; + table->sort_global = table->sort + count; + table->num_hints = 0; + table->num_zones = 0; + table->zone = 0; + + /* initialize the `table->hints' array */ + { + PSH_Hint write = table->hints; + PS_Hint read = hints->hints; + + + for ( ; count > 0; count--, write++, read++ ) + { + write->org_pos = read->pos; + write->org_len = read->len; + write->flags = read->flags; + } + } + + /* we now need to determine the initial `parent' stems; first */ + /* activate the hints that are given by the initial hint masks */ + if ( hint_masks ) + { + PS_Mask mask = hint_masks->masks; + + + count = hint_masks->num_masks; + table->hint_masks = hint_masks; + + for ( ; count > 0; count--, mask++ ) + psh_hint_table_record_mask( table, mask ); + } + + /* finally, do a linear parse in case some hints were left alone */ + if ( table->num_hints != table->max_hints ) + { + FT_UInt idx; + + + FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" )); + + count = table->max_hints; + for ( idx = 0; idx < count; idx++ ) + psh_hint_table_record( table, idx ); + } + + Exit: + return error; + } + + + static void + psh_hint_table_activate_mask( PSH_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit, count; + + + limit = hint_mask->num_bits; + count = 0; + + psh_hint_table_deactivate( table ); + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + { + PSH_Hint hint = &table->hints[idx]; + + + if ( !psh_hint_is_active( hint ) ) + { + FT_UInt count2; + +#if 0 + PSH_Hint* sort = table->sort; + PSH_Hint hint2; + + + for ( count2 = count; count2 > 0; count2--, sort++ ) + { + hint2 = sort[0]; + if ( psh_hint_overlap( hint, hint2 ) ) + FT_TRACE0(( "psh_hint_table_activate_mask:" + " found overlapping hints\n" )) + } +#else + count2 = 0; +#endif + + if ( count2 == 0 ) + { + psh_hint_activate( hint ); + if ( count < table->max_hints ) + table->sort[count++] = hint; + else + FT_TRACE0(( "psh_hint_tableactivate_mask:" + " too many active hints\n" )); + } + } + } + + mask >>= 1; + } + table->num_hints = count; + + /* now, sort the hints; they are guaranteed to not overlap */ + /* so we can compare their "org_pos" field directly */ + { + FT_Int i1, i2; + PSH_Hint hint1, hint2; + PSH_Hint* sort = table->sort; + + + /* a simple bubble sort will do, since in 99% of cases, the hints */ + /* will be already sorted -- and the sort will be linear */ + for ( i1 = 1; i1 < (FT_Int)count; i1++ ) + { + hint1 = sort[i1]; + for ( i2 = i1 - 1; i2 >= 0; i2-- ) + { + hint2 = sort[i2]; + + if ( hint2->org_pos < hint1->org_pos ) + break; + + sort[i2 + 1] = hint2; + sort[i2] = hint1; + } + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 1 + static FT_Pos + psh_dimension_quantize_len( PSH_Dimension dim, + FT_Pos len, + FT_Bool do_snapping ) + { + if ( len <= 64 ) + len = 64; + else + { + FT_Pos delta = len - dim->stdw.widths[0].cur; + + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + len = dim->stdw.widths[0].cur; + if ( len < 48 ) + len = 48; + } + + if ( len < 3 * 64 ) + { + delta = ( len & 63 ); + len &= -64; + + if ( delta < 10 ) + len += delta; + + else if ( delta < 32 ) + len += 10; + + else if ( delta < 54 ) + len += 54; + + else + len += delta; + } + else + len = FT_PIX_ROUND( len ); + } + + if ( do_snapping ) + len = FT_PIX_ROUND( len ); + + return len; + } +#endif /* 0 */ + + +#ifdef DEBUG_HINTER + + static void + ps_simple_scale( PSH_Hint_Table table, + FT_Fixed scale, + FT_Fixed delta, + FT_Int dimension ) + { + FT_UInt count; + + + for ( count = 0; count < table->max_hints; count++ ) + { + PSH_Hint hint = table->hints + count; + + + hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; + hint->cur_len = FT_MulFix( hint->org_len, scale ); + + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); + } + } + +#endif /* DEBUG_HINTER */ + + + static FT_Fixed + psh_hint_snap_stem_side_delta( FT_Fixed pos, + FT_Fixed len ) + { + FT_Fixed delta1 = FT_PIX_ROUND( pos ) - pos; + FT_Fixed delta2 = FT_PIX_ROUND( pos + len ) - pos - len; + + + if ( FT_ABS( delta1 ) <= FT_ABS( delta2 ) ) + return delta1; + else + return delta2; + } + + + static void + psh_hint_align( PSH_Hint hint, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) + { + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( !psh_hint_is_fitted( hint ) ) + { + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); + + FT_Int do_snapping; + FT_Pos fit_len; + PSH_AlignmentRec align; + + + /* ignore stem alignments when requested through the hint flags */ + if ( ( dimension == 0 && !glyph->do_horz_hints ) || + ( dimension == 1 && !glyph->do_vert_hints ) ) + { + hint->cur_pos = pos; + hint->cur_len = len; + + psh_hint_set_fitted( hint ); + return; + } + + /* perform stem snapping when requested - this is necessary + * for monochrome and LCD hinting modes only + */ + do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) || + ( dimension == 1 && glyph->do_vert_snapping ); + + hint->cur_len = fit_len = len; + + /* check blue zones for horizontal stems */ + align.align = PSH_BLUE_ALIGN_NONE; + align.align_bot = align.align_top = 0; + + if ( dimension == 1 ) + psh_blues_snap_stem( &globals->blues, + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_len; + break; + + case PSH_BLUE_ALIGN_BOT: + /* the bottom of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_bot; + break; + + case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: + /* both edges of the stem are aligned against blue zones */ + hint->cur_pos = align.align_bot; + hint->cur_len = align.align_top - align.align_bot; + break; + + default: + { + PSH_Hint parent = hint->parent; + + + if ( parent ) + { + FT_Pos par_org_center, par_cur_center; + FT_Pos cur_org_center, cur_delta; + + + /* ensure that parent is already fitted */ + if ( !psh_hint_is_fitted( parent ) ) + psh_hint_align( parent, globals, dimension, glyph ); + + /* keep original relation between hints, this is, use the */ + /* scaled distance between the centers of the hints to */ + /* compute the new position */ + par_org_center = parent->org_pos + ( parent->org_len >> 1 ); + par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 ); + cur_org_center = hint->org_pos + ( hint->org_len >> 1 ); + + cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); + pos = par_cur_center + cur_delta - ( len >> 1 ); + } + + hint->cur_pos = pos; + hint->cur_len = fit_len; + + /* Stem adjustment tries to snap stem widths to standard + * ones. This is important to prevent unpleasant rounding + * artefacts. + */ + if ( glyph->do_stem_adjust ) + { + if ( len <= 64 ) + { + /* the stem is less than one pixel; we will center it + * around the nearest pixel center + */ + if ( len >= 32 ) + { + /* This is a special case where we also widen the stem + * and align it to the pixel grid. + * + * stem_center = pos + (len/2) + * nearest_pixel_center = FT_ROUND(stem_center-32)+32 + * new_pos = nearest_pixel_center-32 + * = FT_ROUND(stem_center-32) + * = FT_FLOOR(stem_center-32+32) + * = FT_FLOOR(stem_center) + * new_len = 64 + */ + pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ); + len = 64; + } + else if ( len > 0 ) + { + /* This is a very small stem; we simply align it to the + * pixel grid, trying to find the minimum displacement. + * + * left = pos + * right = pos + len + * left_nearest_edge = ROUND(pos) + * right_nearest_edge = ROUND(right) + * + * if ( ABS(left_nearest_edge - left) <= + * ABS(right_nearest_edge - right) ) + * new_pos = left + * else + * new_pos = right + */ + FT_Pos left_nearest = FT_PIX_ROUND( pos ); + FT_Pos right_nearest = FT_PIX_ROUND( pos + len ); + FT_Pos left_disp = left_nearest - pos; + FT_Pos right_disp = right_nearest - ( pos + len ); + + + if ( left_disp < 0 ) + left_disp = -left_disp; + if ( right_disp < 0 ) + right_disp = -right_disp; + if ( left_disp <= right_disp ) + pos = left_nearest; + else + pos = right_nearest; + } + else + { + /* this is a ghost stem; we simply round it */ + pos = FT_PIX_ROUND( pos ); + } + } + else + { + len = psh_dimension_quantize_len( dim, len, 0 ); + } + } + + /* now that we have a good hinted stem width, try to position */ + /* the stem along a pixel grid integer coordinate */ + hint->cur_pos = pos + psh_hint_snap_stem_side_delta( pos, len ); + hint->cur_len = len; + } + } + + if ( do_snapping ) + { + pos = hint->cur_pos; + len = hint->cur_len; + + if ( len < 64 ) + len = 64; + else + len = FT_PIX_ROUND( len ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + hint->cur_pos = align.align_top - len; + hint->cur_len = len; + break; + + case PSH_BLUE_ALIGN_BOT: + hint->cur_len = len; + break; + + case PSH_BLUE_ALIGN_BOT | PSH_BLUE_ALIGN_TOP: + /* don't touch */ + break; + + + default: + hint->cur_len = len; + if ( len & 64 ) + pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ) + 32; + else + pos = FT_PIX_ROUND( pos + ( len >> 1 ) ); + + hint->cur_pos = pos - ( len >> 1 ); + hint->cur_len = len; + } + } + + psh_hint_set_fitted( hint ); + +#ifdef DEBUG_HINTER + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); +#endif + } + } + + +#if 0 /* not used for now, experimental */ + + /* + * A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT) + * of stems + */ + static void + psh_hint_align_light( PSH_Hint hint, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) + { + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( !psh_hint_is_fitted( hint ) ) + { + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); + + FT_Pos fit_len; + + PSH_AlignmentRec align; + + + /* ignore stem alignments when requested through the hint flags */ + if ( ( dimension == 0 && !glyph->do_horz_hints ) || + ( dimension == 1 && !glyph->do_vert_hints ) ) + { + hint->cur_pos = pos; + hint->cur_len = len; + + psh_hint_set_fitted( hint ); + return; + } + + fit_len = len; + + hint->cur_len = fit_len; + + /* check blue zones for horizontal stems */ + align.align = PSH_BLUE_ALIGN_NONE; + align.align_bot = align.align_top = 0; + + if ( dimension == 1 ) + psh_blues_snap_stem( &globals->blues, + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_len; + break; + + case PSH_BLUE_ALIGN_BOT: + /* the bottom of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_bot; + break; + + case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: + /* both edges of the stem are aligned against blue zones */ + hint->cur_pos = align.align_bot; + hint->cur_len = align.align_top - align.align_bot; + break; + + default: + { + PSH_Hint parent = hint->parent; + + + if ( parent ) + { + FT_Pos par_org_center, par_cur_center; + FT_Pos cur_org_center, cur_delta; + + + /* ensure that parent is already fitted */ + if ( !psh_hint_is_fitted( parent ) ) + psh_hint_align_light( parent, globals, dimension, glyph ); + + par_org_center = parent->org_pos + ( parent->org_len / 2 ); + par_cur_center = parent->cur_pos + ( parent->cur_len / 2 ); + cur_org_center = hint->org_pos + ( hint->org_len / 2 ); + + cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); + pos = par_cur_center + cur_delta - ( len >> 1 ); + } + + /* Stems less than one pixel wide are easy -- we want to + * make them as dark as possible, so they must fall within + * one pixel. If the stem is split between two pixels + * then snap the edge that is nearer to the pixel boundary + * to the pixel boundary. + */ + if ( len <= 64 ) + { + if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 ) + pos += psh_hint_snap_stem_side_delta ( pos, len ); + } + + /* Position stems other to minimize the amount of mid-grays. + * There are, in general, two positions that do this, + * illustrated as A) and B) below. + * + * + + + + + * + * A) |--------------------------------| + * B) |--------------------------------| + * C) |--------------------------------| + * + * Position A) (split the excess stem equally) should be better + * for stems of width N + f where f < 0.5. + * + * Position B) (split the deficiency equally) should be better + * for stems of width N + f where f > 0.5. + * + * It turns out though that minimizing the total number of lit + * pixels is also important, so position C), with one edge + * aligned with a pixel boundary is actually preferable + * to A). There are also more possibile positions for C) than + * for A) or B), so it involves less distortion of the overall + * character shape. + */ + else /* len > 64 */ + { + FT_Fixed frac_len = len & 63; + FT_Fixed center = pos + ( len >> 1 ); + FT_Fixed delta_a, delta_b; + + + if ( ( len / 64 ) & 1 ) + { + delta_a = FT_PIX_FLOOR( center ) + 32 - center; + delta_b = FT_PIX_ROUND( center ) - center; + } + else + { + delta_a = FT_PIX_ROUND( center ) - center; + delta_b = FT_PIX_FLOOR( center ) + 32 - center; + } + + /* We choose between B) and C) above based on the amount + * of fractinal stem width; for small amounts, choose + * C) always, for large amounts, B) always, and inbetween, + * pick whichever one involves less stem movement. + */ + if ( frac_len < 32 ) + { + pos += psh_hint_snap_stem_side_delta ( pos, len ); + } + else if ( frac_len < 48 ) + { + FT_Fixed side_delta = psh_hint_snap_stem_side_delta ( pos, + len ); + + if ( FT_ABS( side_delta ) < FT_ABS( delta_b ) ) + pos += side_delta; + else + pos += delta_b; + } + else + { + pos += delta_b; + } + } + + hint->cur_pos = pos; + } + } /* switch */ + + psh_hint_set_fitted( hint ); + +#ifdef DEBUG_HINTER + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); +#endif + } + } + +#endif /* 0 */ + + + static void + psh_hint_table_align_hints( PSH_Hint_Table table, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) + { + PSH_Hint hint; + FT_UInt count; + +#ifdef DEBUG_HINTER + + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( ps_debug_no_vert_hints && dimension == 0 ) + { + ps_simple_scale( table, scale, delta, dimension ); + return; + } + + if ( ps_debug_no_horz_hints && dimension == 1 ) + { + ps_simple_scale( table, scale, delta, dimension ); + return; + } + +#endif /* DEBUG_HINTER*/ + + hint = table->hints; + count = table->max_hints; + + for ( ; count > 0; count--, hint++ ) + psh_hint_align( hint, globals, dimension, glyph ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** POINTS INTERPOLATION ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define PSH_ZONE_MIN -3200000L +#define PSH_ZONE_MAX +3200000L + +#define xxDEBUG_ZONES + + +#ifdef DEBUG_ZONES + +#include FT_CONFIG_STANDARD_LIBRARY_H + + static void + psh_print_zone( PSH_Zone zone ) + { + printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + zone->scale / 65536.0, + zone->delta / 64.0, + zone->min, + zone->max ); + } + +#else + +#define psh_print_zone( x ) do { } while ( 0 ) + +#endif /* DEBUG_ZONES */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTER GLYPH MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#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 */ + static void + psh_glyph_compute_inflections( PSH_Glyph glyph ) + { + FT_UInt n; + + + for ( n = 0; n < glyph->num_contours; n++ ) + { + PSH_Point first, start, end, before, after; + FT_Pos in_x, in_y, out_x, out_y; + FT_Int orient_prev, orient_cur; + FT_Int finished = 0; + + + /* we need at least 4 points to create an inflection point */ + if ( glyph->contours[n].count < 4 ) + continue; + + /* compute first segment in contour */ + first = glyph->contours[n].start; + + start = end = first; + do + { + end = end->next; + if ( end == first ) + goto Skip; + + in_x = end->org_u - start->org_u; + in_y = end->org_v - start->org_v; + + } 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->org_u - before->org_u; + out_y = start->org_v - before->org_v; + + } while ( out_x == 0 && out_y == 0 ); + + orient_prev = psh_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->org_u - end->org_u; + out_y = after->org_v - end->org_v; + + } while ( out_x == 0 && out_y == 0 ); + + orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y ); + + } while ( orient_cur == 0 ); + + if ( ( orient_cur ^ orient_prev ) < 0 ) + { + do + { + psh_point_set_inflex( start ); + start = start->next; + } + while ( start != end ); + + psh_point_set_inflex( start ); + } + + start = end; + end = after; + orient_prev = orient_cur; + in_x = out_x; + in_y = out_y; + + } while ( !finished ); + + Skip: + ; + } + } + +#endif /* COMPUTE_INFLEXS */ + + + static void + psh_glyph_done( PSH_Glyph glyph ) + { + FT_Memory memory = glyph->memory; + + + psh_hint_table_done( &glyph->hint_tables[1], memory ); + psh_hint_table_done( &glyph->hint_tables[0], memory ); + + FT_FREE( glyph->points ); + FT_FREE( glyph->contours ); + + glyph->num_points = 0; + glyph->num_contours = 0; + + glyph->memory = 0; + } + + + static int + psh_compute_dir( FT_Pos dx, + FT_Pos dy ) + { + FT_Pos ax, ay; + int result = PSH_DIR_NONE; + + + ax = FT_ABS( dx ); + ay = FT_ABS( dy ); + + if ( ay * 12 < ax ) + { + /* |dy| <<< |dx| means a near-horizontal segment */ + result = ( dx >= 0 ) ? PSH_DIR_RIGHT : PSH_DIR_LEFT; + } + else if ( ax * 12 < ay ) + { + /* |dx| <<< |dy| means a near-vertical segment */ + result = ( dy >= 0 ) ? PSH_DIR_UP : PSH_DIR_DOWN; + } + + return result; + } + + + /* load outline point coordinates into hinter glyph */ + static void + psh_glyph_load_points( PSH_Glyph glyph, + FT_Int dimension ) + { + FT_Vector* vec = glyph->outline->points; + PSH_Point point = glyph->points; + FT_UInt count = glyph->num_points; + + + for ( ; count > 0; count--, point++, vec++ ) + { + point->flags2 = 0; + point->hint = NULL; + if ( dimension == 0 ) + { + point->org_u = vec->x; + point->org_v = vec->y; + } + else + { + point->org_u = vec->y; + point->org_v = vec->x; + } + +#ifdef DEBUG_HINTER + point->org_x = vec->x; + point->org_y = vec->y; +#endif + + } + } + + + /* save hinted point coordinates back to outline */ + static void + psh_glyph_save_points( PSH_Glyph glyph, + FT_Int dimension ) + { + FT_UInt n; + PSH_Point point = glyph->points; + FT_Vector* vec = glyph->outline->points; + char* tags = glyph->outline->tags; + + + for ( n = 0; n < glyph->num_points; n++ ) + { + if ( dimension == 0 ) + vec[n].x = point->cur_u; + else + vec[n].y = point->cur_u; + + if ( psh_point_is_strong( point ) ) + tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 ); + +#ifdef DEBUG_HINTER + + if ( dimension == 0 ) + { + point->cur_x = point->cur_u; + point->flags_x = point->flags2 | point->flags; + } + else + { + point->cur_y = point->cur_u; + point->flags_y = point->flags2 | point->flags; + } + +#endif + + point++; + } + } + + + static FT_Error + psh_glyph_init( PSH_Glyph glyph, + FT_Outline* outline, + PS_Hints ps_hints, + PSH_Globals globals ) + { + FT_Error error; + FT_Memory memory; + + + /* clear all fields */ + FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); + + memory = glyph->memory = globals->memory; + + /* allocate and setup points + contours arrays */ + if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) || + FT_NEW_ARRAY( glyph->contours, outline->n_contours ) ) + goto Exit; + + glyph->num_points = outline->n_points; + glyph->num_contours = outline->n_contours; + + { + FT_UInt first = 0, next, n; + PSH_Point points = glyph->points; + PSH_Contour contour = glyph->contours; + + + for ( n = 0; n < glyph->num_contours; n++ ) + { + FT_Int count; + PSH_Point point; + + + next = outline->contours[n] + 1; + count = next - first; + + contour->start = points + first; + contour->count = (FT_UInt)count; + + if ( count > 0 ) + { + point = points + first; + + point->prev = points + next - 1; + point->contour = contour; + + for ( ; count > 1; count-- ) + { + point[0].next = point + 1; + point[1].prev = point; + point++; + point->contour = contour; + } + point->next = points + first; + } + + contour++; + first = next; + } + } + + { + PSH_Point points = glyph->points; + PSH_Point point = points; + FT_Vector* vec = outline->points; + FT_UInt n; + + + for ( n = 0; n < glyph->num_points; n++, point++ ) + { + FT_Int n_prev = (FT_Int)( point->prev - points ); + FT_Int n_next = (FT_Int)( point->next - points ); + FT_Pos dxi, dyi, dxo, dyo; + + + if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) ) + point->flags = PSH_POINT_OFF; + + dxi = vec[n].x - vec[n_prev].x; + dyi = vec[n].y - vec[n_prev].y; + + point->dir_in = (FT_Char)psh_compute_dir( dxi, dyi ); + + dxo = vec[n_next].x - vec[n].x; + dyo = vec[n_next].y - vec[n].y; + + point->dir_out = (FT_Char)psh_compute_dir( dxo, dyo ); + + /* detect smooth points */ + if ( point->flags & PSH_POINT_OFF ) + point->flags |= PSH_POINT_SMOOTH; + + else if ( point->dir_in == point->dir_out ) + { + if ( point->dir_out != PSH_DIR_NONE || + psh_corner_is_flat( dxi, dyi, dxo, dyo ) ) + point->flags |= PSH_POINT_SMOOTH; + } + } + } + + glyph->outline = outline; + glyph->globals = globals; + +#ifdef COMPUTE_INFLEXS + psh_glyph_load_points( glyph, 0 ); + psh_glyph_compute_inflections( glyph ); +#endif /* COMPUTE_INFLEXS */ + + /* now deal with hints tables */ + error = psh_hint_table_init( &glyph->hint_tables [0], + &ps_hints->dimension[0].hints, + &ps_hints->dimension[0].masks, + &ps_hints->dimension[0].counters, + memory ); + if ( error ) + goto Exit; + + error = psh_hint_table_init( &glyph->hint_tables [1], + &ps_hints->dimension[1].hints, + &ps_hints->dimension[1].masks, + &ps_hints->dimension[1].counters, + memory ); + if ( error ) + goto Exit; + + Exit: + return error; + } + + + /* compute all extrema in a glyph for a given dimension */ + static void + psh_glyph_compute_extrema( PSH_Glyph glyph ) + { + FT_UInt n; + + + /* first of all, compute all local extrema */ + for ( n = 0; n < glyph->num_contours; n++ ) + { + PSH_Point first = glyph->contours[n].start; + PSH_Point point, before, after; + + + if ( glyph->contours[n].count == 0 ) + continue; + + point = first; + before = point; + after = point; + + do + { + before = before->prev; + if ( before == first ) + goto Skip; + + } while ( before->org_u == point->org_u ); + + first = point = before->next; + + for (;;) + { + after = point; + do + { + after = after->next; + if ( after == first ) + goto Next; + + } while ( after->org_u == point->org_u ); + + if ( before->org_u < point->org_u ) + { + if ( after->org_u < point->org_u ) + { + /* local maximum */ + goto Extremum; + } + } + else /* before->org_u > point->org_u */ + { + if ( after->org_u > point->org_u ) + { + /* local minimum */ + Extremum: + do + { + psh_point_set_extremum( point ); + point = point->next; + + } while ( point != after ); + } + } + + before = after->prev; + point = after; + + } /* for */ + + Next: + ; + } + + /* for each extremum, determine its direction along the */ + /* orthogonal axis */ + for ( n = 0; n < glyph->num_points; n++ ) + { + PSH_Point point, before, after; + + + point = &glyph->points[n]; + before = point; + after = point; + + if ( psh_point_is_extremum( point ) ) + { + do + { + before = before->prev; + if ( before == point ) + goto Skip; + + } while ( before->org_v == point->org_v ); + + do + { + after = after->next; + if ( after == point ) + goto Skip; + + } while ( after->org_v == point->org_v ); + } + + if ( before->org_v < point->org_v && + after->org_v > point->org_v ) + { + psh_point_set_positive( point ); + } + else if ( before->org_v > point->org_v && + after->org_v < point->org_v ) + { + psh_point_set_negative( point ); + } + + Skip: + ; + } + } + + + /* major_dir is the direction for points on the bottom/left of the stem; */ + /* Points on the top/right of the stem will have a direction of */ + /* -major_dir. */ + + static void + 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; + + + for ( ; count > 0; count--, point++ ) + { + FT_Int point_dir = 0; + FT_Pos org_u = point->org_u; + + + 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 ) + { + if ( point_dir == major_dir ) + { + FT_UInt nn; + + + for ( nn = 0; nn < num_hints; nn++ ) + { + 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 ) + { + FT_UInt nn; + + + 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 nn, min_flag, max_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 ) + { + for ( nn = 0; nn < num_hints; nn++ ) + { + 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 ) + { + 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 ) + { + point->flags2 |= PSH_POINT_EDGE_MAX; + point->hint = hint; + psh_point_set_strong( point ); + break; + } + } + } + + if ( point->hint == NULL ) + { + 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 */ + } + } + + + /* the accepted shift for strong points in fractional pixels */ +#define PSH_STRONG_THRESHOLD 32 + + /* the maximum shift value in font units */ +#define PSH_STRONG_THRESHOLD_MAXIMUM 30 + + + /* find strong points in a glyph */ + static void + psh_glyph_find_strong_points( PSH_Glyph glyph, + FT_Int dimension ) + { + /* a point is `strong' if it is located on a stem edge and */ + /* has an `in' or `out' tangent parallel to the hint's direction */ + + PSH_Hint_Table table = &glyph->hint_tables[dimension]; + PS_Mask mask = table->hint_masks->masks; + FT_UInt num_masks = table->hint_masks->num_masks; + FT_UInt first = 0; + FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL + : PSH_DIR_HORIZONTAL; + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Int threshold; + + + threshold = (FT_Int)FT_DivFix( PSH_STRONG_THRESHOLD, scale ); + if ( threshold > PSH_STRONG_THRESHOLD_MAXIMUM ) + threshold = PSH_STRONG_THRESHOLD_MAXIMUM; + + /* process secondary hints to `selected' points */ + if ( num_masks > 1 && glyph->num_points > 0 ) + { + /* the `endchar' op can reduce the number of points */ + first = mask->end_point > glyph->num_points + ? glyph->num_points + : mask->end_point; + mask++; + for ( ; num_masks > 1; num_masks--, mask++ ) + { + FT_UInt next; + FT_Int count; + + + next = mask->end_point > glyph->num_points + ? glyph->num_points + : mask->end_point; + count = next - first; + if ( count > 0 ) + { + PSH_Point point = glyph->points + first; + + + psh_hint_table_activate_mask( table, mask ); + + psh_hint_table_find_strong_points( table, point, count, + threshold, major_dir ); + } + first = next; + } + } + + /* process primary hints for all points */ + if ( num_masks == 1 ) + { + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + psh_hint_table_activate_mask( table, table->hint_masks->masks ); + + psh_hint_table_find_strong_points( table, point, count, + threshold, major_dir ); + } + + /* now, certain points may have been attached to a hint and */ + /* not marked as strong; update their flags then */ + { + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + if ( point->hint && !psh_point_is_strong( point ) ) + psh_point_set_strong( point ); + } + } + + + /* find points in a glyph which are in a blue zone and have `in' or */ + /* `out' tangents parallel to the horizontal axis */ + static void + psh_glyph_find_blue_points( PSH_Blues blues, + PSH_Glyph glyph ) + { + PSH_Blue_Table table; + PSH_Blue_Zone zone; + FT_UInt glyph_count = glyph->num_points; + FT_UInt blue_count; + PSH_Point point = glyph->points; + + + for ( ; glyph_count > 0; glyph_count--, point++ ) + { + FT_Pos y; + + + /* check tangents */ + if ( !PSH_DIR_COMPARE( point->dir_in, PSH_DIR_HORIZONTAL ) && + !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) ) + continue; + + /* skip strong points */ + if ( psh_point_is_strong( point ) ) + continue; + + y = point->org_u; + + /* look up top zones */ + table = &blues->normal_top; + blue_count = table->count; + zone = table->zones; + + for ( ; blue_count > 0; blue_count--, zone++ ) + { + FT_Pos delta = y - zone->org_bottom; + + + if ( delta < -blues->blue_fuzz ) + break; + + if ( y <= zone->org_top + blues->blue_fuzz ) + if ( blues->no_overshoots || delta <= blues->blue_threshold ) + { + point->cur_u = zone->cur_bottom; + psh_point_set_strong( point ); + psh_point_set_fitted( point ); + } + } + + /* look up bottom zones */ + table = &blues->normal_bottom; + blue_count = table->count; + zone = table->zones + blue_count - 1; + + for ( ; blue_count > 0; blue_count--, zone-- ) + { + FT_Pos delta = zone->org_top - y; + + + if ( delta < -blues->blue_fuzz ) + break; + + if ( y >= zone->org_bottom - blues->blue_fuzz ) + if ( blues->no_overshoots || delta < blues->blue_threshold ) + { + point->cur_u = zone->cur_top; + psh_point_set_strong( point ); + psh_point_set_fitted( point ); + } + } + } + } + + + /* interpolate strong points with the help of hinted coordinates */ + static void + psh_glyph_interpolate_strong_points( PSH_Glyph glyph, + FT_Int dimension ) + { + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + { + PSH_Hint hint = point->hint; + + + if ( hint ) + { + FT_Pos delta; + + + if ( psh_point_is_edge_min( point ) ) + point->cur_u = hint->cur_pos; + + else if ( psh_point_is_edge_max( point ) ) + point->cur_u = hint->cur_pos + hint->cur_len; + + else + { + delta = point->org_u - hint->org_pos; + + if ( delta <= 0 ) + point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); + + else if ( delta >= hint->org_len ) + point->cur_u = hint->cur_pos + hint->cur_len + + FT_MulFix( delta - hint->org_len, scale ); + + else /* hint->org_len > 0 */ + point->cur_u = hint->cur_pos + + FT_MulDiv( delta, hint->cur_len, + hint->org_len ); + } + psh_point_set_fitted( point ); + } + } + } + + +#define PSH_MAX_STRONG_INTERNAL 16 + + static void + psh_glyph_interpolate_normal_points( PSH_Glyph glyph, + FT_Int dimension ) + { + +#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; + FT_Memory memory = glyph->memory; + + 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; + + + /* 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; + + /* sometimes, some local extrema are smooth points */ + if ( psh_point_is_smooth( point ) ) + { + if ( point->dir_in == PSH_DIR_NONE || + point->dir_in != point->dir_out ) + continue; + + if ( !psh_point_is_extremum( point ) && + !psh_point_is_inflex( point ) ) + continue; + + point->flags &= ~PSH_POINT_SMOOTH; + } + + /* find best enclosing point coordinates then interpolate */ + { + PSH_Point before, after; + FT_UInt nn; + + + 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 */ + { + after = strongs[0]; + + point->cur_u = after->cur_u + + FT_MulFix( point->org_u - after->org_u, + scale ); + } + else + { + before = strongs[nn - 1]; + + 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]; + + point->cur_u = before->cur_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 */ + + } + + + /* interpolate other points */ + static void + psh_glyph_interpolate_other_points( PSH_Glyph glyph, + FT_Int dimension ) + { + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + PSH_Contour contour = glyph->contours; + FT_UInt num_contours = glyph->num_contours; + + + for ( ; num_contours > 0; num_contours--, contour++ ) + { + PSH_Point start = contour->start; + PSH_Point first, next, point; + FT_UInt fit_count; + + + /* count the number of strong points in this contour */ + next = start + contour->count; + fit_count = 0; + first = 0; + + for ( point = start; point < next; point++ ) + if ( psh_point_is_fitted( point ) ) + { + if ( !first ) + first = point; + + fit_count++; + } + + /* if there are less than 2 fitted points in the contour, we */ + /* simply scale and eventually translate the contour points */ + if ( fit_count < 2 ) + { + if ( fit_count == 1 ) + delta = first->cur_u - FT_MulFix( first->org_u, scale ); + + for ( point = start; point < next; point++ ) + if ( point != first ) + point->cur_u = FT_MulFix( point->org_u, scale ) + delta; + + goto Next_Contour; + } + + /* there are more than 2 strong points in this contour; we */ + /* need to interpolate weak points between them */ + start = first; + do + { + point = first; + + /* skip consecutive fitted points */ + for (;;) + { + next = first->next; + if ( next == start ) + goto Next_Contour; + + if ( !psh_point_is_fitted( next ) ) + break; + + first = next; + } + + /* find next fitted point after unfitted one */ + for (;;) + { + next = next->next; + if ( psh_point_is_fitted( next ) ) + break; + } + + /* now interpolate between them */ + { + FT_Pos org_a, org_ab, cur_a, cur_ab; + FT_Pos org_c, org_ac, cur_c; + FT_Fixed scale_ab; + + + if ( first->org_u <= next->org_u ) + { + org_a = first->org_u; + cur_a = first->cur_u; + org_ab = next->org_u - org_a; + cur_ab = next->cur_u - cur_a; + } + else + { + org_a = next->org_u; + cur_a = next->cur_u; + org_ab = first->org_u - org_a; + cur_ab = first->cur_u - cur_a; + } + + scale_ab = 0x10000L; + if ( org_ab > 0 ) + scale_ab = FT_DivFix( cur_ab, org_ab ); + + point = first->next; + do + { + org_c = point->org_u; + org_ac = org_c - org_a; + + if ( org_ac <= 0 ) + { + /* on the left of the interpolation zone */ + cur_c = cur_a + FT_MulFix( org_ac, scale ); + } + else if ( org_ac >= org_ab ) + { + /* on the right on the interpolation zone */ + cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale ); + } + else + { + /* within the interpolation zone */ + cur_c = cur_a + FT_MulFix( org_ac, scale_ab ); + } + + point->cur_u = cur_c; + + point = point->next; + + } while ( point != next ); + } + + /* keep going until all points in the contours have been processed */ + first = next; + + } while ( first != start ); + + Next_Contour: + ; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HIGH-LEVEL INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_Error + ps_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) + { + PSH_GlyphRec glyphrec; + PSH_Glyph glyph = &glyphrec; + FT_Error error; +#ifdef DEBUG_HINTER + FT_Memory memory; +#endif + FT_Int dimension; + + + /* something to do? */ + if ( outline->n_points == 0 || outline->n_contours == 0 ) + return FT_Err_Ok; + +#ifdef DEBUG_HINTER + + memory = globals->memory; + + if ( ps_debug_glyph ) + { + psh_glyph_done( ps_debug_glyph ); + FT_FREE( ps_debug_glyph ); + } + + if ( FT_NEW( glyph ) ) + return error; + + ps_debug_glyph = glyph; + +#endif /* DEBUG_HINTER */ + + error = psh_glyph_init( glyph, outline, ps_hints, globals ); + if ( error ) + goto Exit; + + /* try to optimize the y_scale so that the top of non-capital letters + * is aligned on a pixel boundary whenever possible + */ + { + PSH_Dimension dim_x = &glyph->globals->dimension[0]; + PSH_Dimension dim_y = &glyph->globals->dimension[1]; + + FT_Fixed x_scale = dim_x->scale_mult; + FT_Fixed y_scale = dim_y->scale_mult; + + FT_Fixed old_x_scale = x_scale; + FT_Fixed old_y_scale = y_scale; + + FT_Fixed scaled; + FT_Fixed fitted; + + FT_Bool rescale = FALSE; + + + scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale ); + fitted = FT_PIX_ROUND( scaled ); + + if ( fitted != 0 && scaled != fitted ) + { + rescale = TRUE; + + y_scale = FT_MulDiv( y_scale, fitted, scaled ); + + if ( fitted < scaled ) + x_scale -= x_scale / 50; + + psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 ); + } + + glyph->do_horz_hints = 1; + glyph->do_vert_hints = 1; + + glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD ); + + glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD_V ); + + glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); + + for ( dimension = 0; dimension < 2; dimension++ ) + { + /* load outline coordinates into glyph */ + psh_glyph_load_points( glyph, dimension ); + + /* compute local extrema */ + psh_glyph_compute_extrema( glyph ); + + /* compute aligned stem/hints positions */ + psh_hint_table_align_hints( &glyph->hint_tables[dimension], + glyph->globals, + dimension, + glyph ); + + /* find strong points, align them, then interpolate others */ + psh_glyph_find_strong_points( glyph, dimension ); + if ( dimension == 1 ) + psh_glyph_find_blue_points( &globals->blues, glyph ); + psh_glyph_interpolate_strong_points( glyph, dimension ); + psh_glyph_interpolate_normal_points( glyph, dimension ); + psh_glyph_interpolate_other_points( glyph, dimension ); + + /* save hinted coordinates back to outline */ + psh_glyph_save_points( glyph, dimension ); + + if ( rescale ) + psh_globals_set_scale( glyph->globals, + old_x_scale, old_y_scale, 0, 0 ); + } + } + + Exit: + +#ifndef DEBUG_HINTER + psh_glyph_done( glyph ); +#endif + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshalgo.h b/drivers/freetype/src/pshinter/pshalgo.h new file mode 100644 index 0000000000..c70f31ea94 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshalgo.h @@ -0,0 +1,246 @@ +/***************************************************************************/ +/* */ +/* pshalgo.h */ +/* */ +/* PostScript hinting algorithm (specification). */ +/* */ +/* Copyright 2001-2003, 2008, 2013 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 __PSHALGO_H__ +#define __PSHALGO_H__ + + +#include "pshrec.h" +#include "pshglob.h" + + +FT_BEGIN_HEADER + + + /* handle to Hint structure */ + typedef struct PSH_HintRec_* PSH_Hint; + + /* hint bit-flags */ + typedef enum PSH_Hint_Flags_ + { + PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, + PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, + PSH_HINT_ACTIVE = 4, + PSH_HINT_FITTED = 8 + + } PSH_Hint_Flags; + + +#define psh_hint_is_active( x ) ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 ) +#define psh_hint_is_ghost( x ) ( ( (x)->flags & PSH_HINT_GHOST ) != 0 ) +#define psh_hint_is_fitted( x ) ( ( (x)->flags & PSH_HINT_FITTED ) != 0 ) + +#define psh_hint_activate( x ) (x)->flags |= PSH_HINT_ACTIVE +#define psh_hint_deactivate( x ) (x)->flags &= ~PSH_HINT_ACTIVE +#define psh_hint_set_fitted( x ) (x)->flags |= PSH_HINT_FITTED + + /* hint structure */ + typedef struct PSH_HintRec_ + { + FT_Int org_pos; + FT_Int org_len; + FT_Pos cur_pos; + FT_Pos cur_len; + FT_UInt flags; + PSH_Hint parent; + FT_Int order; + + } PSH_HintRec; + + + /* this is an interpolation zone used for strong points; */ + /* weak points are interpolated according to their strong */ + /* neighbours */ + typedef struct PSH_ZoneRec_ + { + FT_Fixed scale; + FT_Fixed delta; + FT_Pos min; + FT_Pos max; + + } PSH_ZoneRec, *PSH_Zone; + + + typedef struct PSH_Hint_TableRec_ + { + FT_UInt max_hints; + FT_UInt num_hints; + PSH_Hint hints; + PSH_Hint* sort; + PSH_Hint* sort_global; + FT_UInt num_zones; + PSH_ZoneRec* zones; + PSH_Zone zone; + PS_Mask_Table hint_masks; + PS_Mask_Table counter_masks; + + } PSH_Hint_TableRec, *PSH_Hint_Table; + + + typedef struct PSH_PointRec_* PSH_Point; + typedef struct PSH_ContourRec_* PSH_Contour; + + enum + { + PSH_DIR_NONE = 4, + PSH_DIR_UP = -1, + PSH_DIR_DOWN = 1, + PSH_DIR_LEFT = -2, + PSH_DIR_RIGHT = 2 + }; + +#define PSH_DIR_HORIZONTAL 2 +#define PSH_DIR_VERTICAL 1 + +#define PSH_DIR_COMPARE( d1, d2 ) ( (d1) == (d2) || (d1) == -(d2) ) +#define PSH_DIR_IS_HORIZONTAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_HORIZONTAL ) +#define PSH_DIR_IS_VERTICAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL ) + + + /* the following bit-flags are computed once by the glyph */ + /* analyzer, for both dimensions */ + enum + { + PSH_POINT_OFF = 1, /* point is off the curve */ + PSH_POINT_SMOOTH = 2, /* point is smooth */ + PSH_POINT_INFLEX = 4 /* point is inflection */ + }; + +#define psh_point_is_smooth( p ) ( (p)->flags & PSH_POINT_SMOOTH ) +#define psh_point_is_off( p ) ( (p)->flags & PSH_POINT_OFF ) +#define psh_point_is_inflex( p ) ( (p)->flags & PSH_POINT_INFLEX ) + +#define psh_point_set_smooth( p ) (p)->flags |= PSH_POINT_SMOOTH +#define psh_point_set_off( p ) (p)->flags |= PSH_POINT_OFF +#define psh_point_set_inflex( p ) (p)->flags |= PSH_POINT_INFLEX + + /* the following bit-flags are re-computed for each dimension */ + enum + { + PSH_POINT_STRONG = 16, /* point is strong */ + PSH_POINT_FITTED = 32, /* point is already fitted */ + PSH_POINT_EXTREMUM = 64, /* point is local extremum */ + PSH_POINT_POSITIVE = 128, /* extremum has positive contour flow */ + PSH_POINT_NEGATIVE = 256, /* extremum has negative contour flow */ + PSH_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */ + PSH_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */ + }; + +#define psh_point_is_strong( p ) ( (p)->flags2 & PSH_POINT_STRONG ) +#define psh_point_is_fitted( p ) ( (p)->flags2 & PSH_POINT_FITTED ) +#define psh_point_is_extremum( p ) ( (p)->flags2 & PSH_POINT_EXTREMUM ) +#define psh_point_is_positive( p ) ( (p)->flags2 & PSH_POINT_POSITIVE ) +#define psh_point_is_negative( p ) ( (p)->flags2 & PSH_POINT_NEGATIVE ) +#define psh_point_is_edge_min( p ) ( (p)->flags2 & PSH_POINT_EDGE_MIN ) +#define psh_point_is_edge_max( p ) ( (p)->flags2 & PSH_POINT_EDGE_MAX ) + +#define psh_point_set_strong( p ) (p)->flags2 |= PSH_POINT_STRONG +#define psh_point_set_fitted( p ) (p)->flags2 |= PSH_POINT_FITTED +#define psh_point_set_extremum( p ) (p)->flags2 |= PSH_POINT_EXTREMUM +#define psh_point_set_positive( p ) (p)->flags2 |= PSH_POINT_POSITIVE +#define psh_point_set_negative( p ) (p)->flags2 |= PSH_POINT_NEGATIVE +#define psh_point_set_edge_min( p ) (p)->flags2 |= PSH_POINT_EDGE_MIN +#define psh_point_set_edge_max( p ) (p)->flags2 |= PSH_POINT_EDGE_MAX + + + typedef struct PSH_PointRec_ + { + PSH_Point prev; + PSH_Point next; + PSH_Contour contour; + FT_UInt flags; + FT_UInt flags2; + FT_Char dir_in; + FT_Char dir_out; + PSH_Hint hint; + FT_Pos org_u; + FT_Pos org_v; + FT_Pos cur_u; +#ifdef DEBUG_HINTER + FT_Pos org_x; + FT_Pos cur_x; + FT_Pos org_y; + FT_Pos cur_y; + FT_UInt flags_x; + FT_UInt flags_y; +#endif + + } PSH_PointRec; + + + typedef struct PSH_ContourRec_ + { + PSH_Point start; + FT_UInt count; + + } PSH_ContourRec; + + + typedef struct PSH_GlyphRec_ + { + FT_UInt num_points; + FT_UInt num_contours; + + PSH_Point points; + PSH_Contour contours; + + FT_Memory memory; + FT_Outline* outline; + PSH_Globals globals; + PSH_Hint_TableRec hint_tables[2]; + + FT_Bool vertical; + FT_Int major_dir; + FT_Int minor_dir; + + FT_Bool do_horz_hints; + FT_Bool do_vert_hints; + FT_Bool do_horz_snapping; + FT_Bool do_vert_snapping; + FT_Bool do_stem_adjust; + + } PSH_GlyphRec, *PSH_Glyph; + + +#ifdef DEBUG_HINTER + extern PSH_Hint_Table ps_debug_hint_table; + + typedef void + (*PSH_HintFunc)( PSH_Hint hint, + FT_Bool vertical ); + + extern PSH_HintFunc ps_debug_hint_func; + + extern PSH_Glyph ps_debug_glyph; +#endif + + + extern FT_Error + ps_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + +FT_END_HEADER + + +#endif /* __PSHALGO_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshglob.c b/drivers/freetype/src/pshinter/pshglob.c new file mode 100644 index 0000000000..9285efc9e1 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshglob.c @@ -0,0 +1,797 @@ +/***************************************************************************/ +/* */ +/* pshglob.c */ +/* */ +/* PostScript hinter global hinting management (body). */ +/* Inspired by the new auto-hinter module. */ +/* */ +/* Copyright 2001-2004, 2006, 2010, 2012 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pshglob.h" + +#ifdef DEBUG_HINTER + PSH_Globals ps_debug_globals = 0; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** STANDARD WIDTHS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* scale the widths/heights table */ + static void + psh_globals_scale_widths( PSH_Globals globals, + FT_UInt direction ) + { + PSH_Dimension dim = &globals->dimension[direction]; + PSH_Widths stdw = &dim->stdw; + FT_UInt count = stdw->count; + PSH_Width width = stdw->widths; + PSH_Width stand = width; /* standard width/height */ + FT_Fixed scale = dim->scale_mult; + + + if ( count > 0 ) + { + width->cur = FT_MulFix( width->org, scale ); + width->fit = FT_PIX_ROUND( width->cur ); + + width++; + count--; + + for ( ; count > 0; count--, width++ ) + { + FT_Pos w, dist; + + + w = FT_MulFix( width->org, scale ); + dist = w - stand->cur; + + if ( dist < 0 ) + dist = -dist; + + if ( dist < 128 ) + w = stand->cur; + + width->cur = w; + width->fit = FT_PIX_ROUND( w ); + } + } + } + + +#if 0 + + /* org_width is is font units, result in device pixels, 26.6 format */ + FT_LOCAL_DEF( FT_Pos ) + psh_dimension_snap_width( PSH_Dimension dimension, + FT_Int org_width ) + { + FT_UInt n; + FT_Pos width = FT_MulFix( org_width, dimension->scale_mult ); + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + + + for ( n = 0; n < dimension->stdw.count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = dimension->stdw.widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + if ( width >= reference ) + { + width -= 0x21; + if ( width < reference ) + width = reference; + } + else + { + width += 0x21; + if ( width > reference ) + width = reference; + } + + return width; + } + +#endif /* 0 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BLUE ZONES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + psh_blues_set_zones_0( PSH_Blues target, + FT_Bool is_others, + FT_UInt read_count, + FT_Short* read, + PSH_Blue_Table top_table, + PSH_Blue_Table bot_table ) + { + FT_UInt count_top = top_table->count; + FT_UInt count_bot = bot_table->count; + FT_Bool first = 1; + + FT_UNUSED( target ); + + + for ( ; read_count > 1; read_count -= 2 ) + { + FT_Int reference, delta; + FT_UInt count; + PSH_Blue_Zone zones, zone; + FT_Bool top; + + + /* read blue zone entry, and select target top/bottom zone */ + top = 0; + if ( first || is_others ) + { + reference = read[1]; + delta = read[0] - reference; + + zones = bot_table->zones; + count = count_bot; + first = 0; + } + else + { + reference = read[0]; + delta = read[1] - reference; + + zones = top_table->zones; + count = count_top; + top = 1; + } + + /* insert into sorted table */ + zone = zones; + for ( ; count > 0; count--, zone++ ) + { + if ( reference < zone->org_ref ) + break; + + if ( reference == zone->org_ref ) + { + FT_Int delta0 = zone->org_delta; + + + /* we have two zones on the same reference position -- */ + /* only keep the largest one */ + if ( delta < 0 ) + { + if ( delta < delta0 ) + zone->org_delta = delta; + } + else + { + if ( delta > delta0 ) + zone->org_delta = delta; + } + goto Skip; + } + } + + for ( ; count > 0; count-- ) + zone[count] = zone[count-1]; + + zone->org_ref = reference; + zone->org_delta = delta; + + if ( top ) + count_top++; + else + count_bot++; + + Skip: + read += 2; + } + + top_table->count = count_top; + bot_table->count = count_bot; + } + + + /* Re-read blue zones from the original fonts and store them into out */ + /* private structure. This function re-orders, sanitizes and */ + /* fuzz-expands the zones as well. */ + static void + psh_blues_set_zones( PSH_Blues target, + FT_UInt count, + FT_Short* blues, + FT_UInt count_others, + FT_Short* other_blues, + FT_Int fuzz, + FT_Int family ) + { + PSH_Blue_Table top_table, bot_table; + FT_Int count_top, count_bot; + + + if ( family ) + { + top_table = &target->family_top; + bot_table = &target->family_bottom; + } + else + { + top_table = &target->normal_top; + bot_table = &target->normal_bottom; + } + + /* read the input blue zones, and build two sorted tables */ + /* (one for the top zones, the other for the bottom zones) */ + top_table->count = 0; + bot_table->count = 0; + + /* first, the blues */ + psh_blues_set_zones_0( target, 0, + count, blues, top_table, bot_table ); + psh_blues_set_zones_0( target, 1, + count_others, other_blues, top_table, bot_table ); + + count_top = top_table->count; + count_bot = bot_table->count; + + /* sanitize top table */ + if ( count_top > 0 ) + { + PSH_Blue_Zone zone = top_table->zones; + + + for ( count = count_top; count > 0; count--, zone++ ) + { + FT_Int delta; + + + if ( count > 1 ) + { + delta = zone[1].org_ref - zone[0].org_ref; + if ( zone->org_delta > delta ) + zone->org_delta = delta; + } + + zone->org_bottom = zone->org_ref; + zone->org_top = zone->org_delta + zone->org_ref; + } + } + + /* sanitize bottom table */ + if ( count_bot > 0 ) + { + PSH_Blue_Zone zone = bot_table->zones; + + + for ( count = count_bot; count > 0; count--, zone++ ) + { + FT_Int delta; + + + if ( count > 1 ) + { + delta = zone[0].org_ref - zone[1].org_ref; + if ( zone->org_delta < delta ) + zone->org_delta = delta; + } + + zone->org_top = zone->org_ref; + zone->org_bottom = zone->org_delta + zone->org_ref; + } + } + + /* expand top and bottom tables with blue fuzz */ + { + FT_Int dim, top, bot, delta; + PSH_Blue_Zone zone; + + + zone = top_table->zones; + count = count_top; + + for ( dim = 1; dim >= 0; dim-- ) + { + if ( count > 0 ) + { + /* expand the bottom of the lowest zone normally */ + zone->org_bottom -= fuzz; + + /* expand the top and bottom of intermediate zones; */ + /* checking that the interval is smaller than the fuzz */ + top = zone->org_top; + + for ( count--; count > 0; count-- ) + { + bot = zone[1].org_bottom; + delta = bot - top; + + if ( delta < 2 * fuzz ) + zone[0].org_top = zone[1].org_bottom = top + delta / 2; + else + { + zone[0].org_top = top + fuzz; + zone[1].org_bottom = bot - fuzz; + } + + zone++; + top = zone->org_top; + } + + /* expand the top of the highest zone normally */ + zone->org_top = top + fuzz; + } + zone = bot_table->zones; + count = count_bot; + } + } + } + + + /* reset the blues table when the device transform changes */ + static void + psh_blues_scale_zones( PSH_Blues blues, + FT_Fixed scale, + FT_Pos delta ) + { + FT_UInt count; + FT_UInt num; + PSH_Blue_Table table = 0; + + /* */ + /* Determine whether we need to suppress overshoots or */ + /* not. We simply need to compare the vertical scale */ + /* parameter to the raw bluescale value. Here is why: */ + /* */ + /* We need to suppress overshoots for all pointsizes. */ + /* At 300dpi that satisfies: */ + /* */ + /* pointsize < 240*bluescale + 0.49 */ + /* */ + /* This corresponds to: */ + /* */ + /* pixelsize < 1000*bluescale + 49/24 */ + /* */ + /* scale*EM_Size < 1000*bluescale + 49/24 */ + /* */ + /* However, for normal Type 1 fonts, EM_Size is 1000! */ + /* We thus only check: */ + /* */ + /* scale < bluescale + 49/24000 */ + /* */ + /* which we shorten to */ + /* */ + /* "scale < bluescale" */ + /* */ + /* Note that `blue_scale' is stored 1000 times its real */ + /* value, and that `scale' converts from font units to */ + /* fractional pixels. */ + /* */ + + /* 1000 / 64 = 125 / 8 */ + if ( scale >= 0x20C49BAL ) + blues->no_overshoots = FT_BOOL( scale < blues->blue_scale * 8 / 125 ); + else + blues->no_overshoots = FT_BOOL( scale * 125 < blues->blue_scale * 8 ); + + /* */ + /* The blue threshold is the font units distance under */ + /* which overshoots are suppressed due to the BlueShift */ + /* even if the scale is greater than BlueScale. */ + /* */ + /* It is the smallest distance such that */ + /* */ + /* dist <= BlueShift && dist*scale <= 0.5 pixels */ + /* */ + { + FT_Int threshold = blues->blue_shift; + + + while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 ) + threshold--; + + blues->blue_threshold = threshold; + } + + for ( num = 0; num < 4; num++ ) + { + PSH_Blue_Zone zone; + + + switch ( num ) + { + case 0: + table = &blues->normal_top; + break; + case 1: + table = &blues->normal_bottom; + break; + case 2: + table = &blues->family_top; + break; + default: + table = &blues->family_bottom; + break; + } + + zone = table->zones; + count = table->count; + for ( ; count > 0; count--, zone++ ) + { + zone->cur_top = FT_MulFix( zone->org_top, scale ) + delta; + zone->cur_bottom = FT_MulFix( zone->org_bottom, scale ) + delta; + zone->cur_ref = FT_MulFix( zone->org_ref, scale ) + delta; + zone->cur_delta = FT_MulFix( zone->org_delta, scale ); + + /* round scaled reference position */ + zone->cur_ref = FT_PIX_ROUND( zone->cur_ref ); + +#if 0 + if ( zone->cur_ref > zone->cur_top ) + zone->cur_ref -= 64; + else if ( zone->cur_ref < zone->cur_bottom ) + zone->cur_ref += 64; +#endif + } + } + + /* process the families now */ + + for ( num = 0; num < 2; num++ ) + { + PSH_Blue_Zone zone1, zone2; + FT_UInt count1, count2; + PSH_Blue_Table normal, family; + + + switch ( num ) + { + case 0: + normal = &blues->normal_top; + family = &blues->family_top; + break; + + default: + normal = &blues->normal_bottom; + family = &blues->family_bottom; + } + + zone1 = normal->zones; + count1 = normal->count; + + for ( ; count1 > 0; count1--, zone1++ ) + { + /* try to find a family zone whose reference position is less */ + /* than 1 pixel far from the current zone */ + zone2 = family->zones; + count2 = family->count; + + for ( ; count2 > 0; count2--, zone2++ ) + { + FT_Pos Delta; + + + Delta = zone1->org_ref - zone2->org_ref; + if ( Delta < 0 ) + Delta = -Delta; + + if ( FT_MulFix( Delta, scale ) < 64 ) + { + zone1->cur_top = zone2->cur_top; + zone1->cur_bottom = zone2->cur_bottom; + zone1->cur_ref = zone2->cur_ref; + zone1->cur_delta = zone2->cur_delta; + break; + } + } + } + } + } + + + /* calculate the maximum height of given blue zones */ + static FT_Short + psh_calc_max_height( FT_UInt num, + const FT_Short* values, + FT_Short cur_max ) + { + FT_UInt count; + + + for ( count = 0; count < num; count += 2 ) + { + FT_Short cur_height = values[count + 1] - values[count]; + + + if ( cur_height > cur_max ) + cur_max = cur_height; + } + + return cur_max; + } + + + FT_LOCAL_DEF( void ) + psh_blues_snap_stem( PSH_Blues blues, + FT_Int stem_top, + FT_Int stem_bot, + PSH_Alignment alignment ) + { + PSH_Blue_Table table; + FT_UInt count; + FT_Pos delta; + PSH_Blue_Zone zone; + FT_Int no_shoots; + + + alignment->align = PSH_BLUE_ALIGN_NONE; + + no_shoots = blues->no_overshoots; + + /* look up stem top in top zones table */ + table = &blues->normal_top; + count = table->count; + zone = table->zones; + + for ( ; count > 0; count--, zone++ ) + { + delta = stem_top - zone->org_bottom; + if ( delta < -blues->blue_fuzz ) + break; + + if ( stem_top <= zone->org_top + blues->blue_fuzz ) + { + if ( no_shoots || delta <= blues->blue_threshold ) + { + alignment->align |= PSH_BLUE_ALIGN_TOP; + alignment->align_top = zone->cur_ref; + } + break; + } + } + + /* look up stem bottom in bottom zones table */ + table = &blues->normal_bottom; + count = table->count; + zone = table->zones + count-1; + + for ( ; count > 0; count--, zone-- ) + { + delta = zone->org_top - stem_bot; + if ( delta < -blues->blue_fuzz ) + break; + + if ( stem_bot >= zone->org_bottom - blues->blue_fuzz ) + { + if ( no_shoots || delta < blues->blue_threshold ) + { + alignment->align |= PSH_BLUE_ALIGN_BOT; + alignment->align_bot = zone->cur_ref; + } + break; + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLOBAL HINTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + psh_globals_destroy( PSH_Globals globals ) + { + if ( globals ) + { + FT_Memory memory; + + + memory = globals->memory; + globals->dimension[0].stdw.count = 0; + globals->dimension[1].stdw.count = 0; + + globals->blues.normal_top.count = 0; + globals->blues.normal_bottom.count = 0; + globals->blues.family_top.count = 0; + globals->blues.family_bottom.count = 0; + + FT_FREE( globals ); + +#ifdef DEBUG_HINTER + ps_debug_globals = 0; +#endif + } + } + + + static FT_Error + psh_globals_new( FT_Memory memory, + T1_Private* priv, + PSH_Globals *aglobals ) + { + PSH_Globals globals = NULL; + FT_Error error; + + + if ( !FT_NEW( globals ) ) + { + FT_UInt count; + FT_Short* read; + + + globals->memory = memory; + + /* copy standard widths */ + { + PSH_Dimension dim = &globals->dimension[1]; + PSH_Width write = dim->stdw.widths; + + + write->org = priv->standard_width[0]; + write++; + + read = priv->snap_widths; + for ( count = priv->num_snap_widths; count > 0; count-- ) + { + write->org = *read; + write++; + read++; + } + + dim->stdw.count = priv->num_snap_widths + 1; + } + + /* copy standard heights */ + { + PSH_Dimension dim = &globals->dimension[0]; + PSH_Width write = dim->stdw.widths; + + + write->org = priv->standard_height[0]; + write++; + read = priv->snap_heights; + for ( count = priv->num_snap_heights; count > 0; count-- ) + { + write->org = *read; + write++; + read++; + } + + dim->stdw.count = priv->num_snap_heights + 1; + } + + /* copy blue zones */ + psh_blues_set_zones( &globals->blues, priv->num_blue_values, + priv->blue_values, priv->num_other_blues, + priv->other_blues, priv->blue_fuzz, 0 ); + + psh_blues_set_zones( &globals->blues, priv->num_family_blues, + priv->family_blues, priv->num_family_other_blues, + priv->family_other_blues, priv->blue_fuzz, 1 ); + + /* limit the BlueScale value to `1 / max_of_blue_zone_heights' */ + { + FT_Fixed max_scale; + FT_Short max_height = 1; + + + max_height = psh_calc_max_height( priv->num_blue_values, + priv->blue_values, + max_height ); + max_height = psh_calc_max_height( priv->num_other_blues, + priv->other_blues, + max_height ); + max_height = psh_calc_max_height( priv->num_family_blues, + priv->family_blues, + max_height ); + max_height = psh_calc_max_height( priv->num_family_other_blues, + priv->family_other_blues, + max_height ); + + /* BlueScale is scaled 1000 times */ + max_scale = FT_DivFix( 1000, max_height ); + globals->blues.blue_scale = priv->blue_scale < max_scale + ? priv->blue_scale + : max_scale; + } + + globals->blues.blue_shift = priv->blue_shift; + globals->blues.blue_fuzz = priv->blue_fuzz; + + globals->dimension[0].scale_mult = 0; + globals->dimension[0].scale_delta = 0; + globals->dimension[1].scale_mult = 0; + globals->dimension[1].scale_delta = 0; + +#ifdef DEBUG_HINTER + ps_debug_globals = globals; +#endif + } + + *aglobals = globals; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + psh_globals_set_scale( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ) + { + PSH_Dimension dim = &globals->dimension[0]; + + + dim = &globals->dimension[0]; + if ( x_scale != dim->scale_mult || + x_delta != dim->scale_delta ) + { + dim->scale_mult = x_scale; + dim->scale_delta = x_delta; + + psh_globals_scale_widths( globals, 0 ); + } + + dim = &globals->dimension[1]; + if ( y_scale != dim->scale_mult || + y_delta != dim->scale_delta ) + { + dim->scale_mult = y_scale; + dim->scale_delta = y_delta; + + psh_globals_scale_widths( globals, 1 ); + psh_blues_scale_zones( &globals->blues, y_scale, y_delta ); + } + + return 0; + } + + + FT_LOCAL_DEF( void ) + psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ) + { + funcs->create = psh_globals_new; + funcs->set_scale = psh_globals_set_scale; + funcs->destroy = psh_globals_destroy; + } + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshglob.h b/drivers/freetype/src/pshinter/pshglob.h new file mode 100644 index 0000000000..c511626157 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshglob.h @@ -0,0 +1,196 @@ +/***************************************************************************/ +/* */ +/* pshglob.h */ +/* */ +/* PostScript hinter global hinting management. */ +/* */ +/* Copyright 2001, 2002, 2003 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 __PSHGLOB_H__ +#define __PSHGLOB_H__ + + +#include FT_FREETYPE_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLOBAL HINTS INTERNALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* @constant: */ + /* PS_GLOBALS_MAX_BLUE_ZONES */ + /* */ + /* @description: */ + /* The maximum number of blue zones in a font global hints structure. */ + /* See @PS_Globals_BluesRec. */ + /* */ +#define PS_GLOBALS_MAX_BLUE_ZONES 16 + + + /*************************************************************************/ + /* */ + /* @constant: */ + /* PS_GLOBALS_MAX_STD_WIDTHS */ + /* */ + /* @description: */ + /* The maximum number of standard and snap widths in either the */ + /* horizontal or vertical direction. See @PS_Globals_WidthsRec. */ + /* */ +#define PS_GLOBALS_MAX_STD_WIDTHS 16 + + + /* standard and snap width */ + typedef struct PSH_WidthRec_ + { + FT_Int org; + FT_Pos cur; + FT_Pos fit; + + } PSH_WidthRec, *PSH_Width; + + + /* standard and snap widths table */ + typedef struct PSH_WidthsRec_ + { + FT_UInt count; + PSH_WidthRec widths[PS_GLOBALS_MAX_STD_WIDTHS]; + + } PSH_WidthsRec, *PSH_Widths; + + + typedef struct PSH_DimensionRec_ + { + PSH_WidthsRec stdw; + FT_Fixed scale_mult; + FT_Fixed scale_delta; + + } PSH_DimensionRec, *PSH_Dimension; + + + /* blue zone descriptor */ + typedef struct PSH_Blue_ZoneRec_ + { + FT_Int org_ref; + FT_Int org_delta; + FT_Int org_top; + FT_Int org_bottom; + + FT_Pos cur_ref; + FT_Pos cur_delta; + FT_Pos cur_bottom; + FT_Pos cur_top; + + } PSH_Blue_ZoneRec, *PSH_Blue_Zone; + + + typedef struct PSH_Blue_TableRec_ + { + FT_UInt count; + PSH_Blue_ZoneRec zones[PS_GLOBALS_MAX_BLUE_ZONES]; + + } PSH_Blue_TableRec, *PSH_Blue_Table; + + + /* blue zones table */ + typedef struct PSH_BluesRec_ + { + PSH_Blue_TableRec normal_top; + PSH_Blue_TableRec normal_bottom; + PSH_Blue_TableRec family_top; + PSH_Blue_TableRec family_bottom; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_threshold; + FT_Int blue_fuzz; + FT_Bool no_overshoots; + + } PSH_BluesRec, *PSH_Blues; + + + /* font globals. */ + /* dimension 0 => X coordinates + vertical hints/stems */ + /* dimension 1 => Y coordinates + horizontal hints/stems */ + typedef struct PSH_GlobalsRec_ + { + FT_Memory memory; + PSH_DimensionRec dimension[2]; + PSH_BluesRec blues; + + } PSH_GlobalsRec; + + +#define PSH_BLUE_ALIGN_NONE 0 +#define PSH_BLUE_ALIGN_TOP 1 +#define PSH_BLUE_ALIGN_BOT 2 + + + typedef struct PSH_AlignmentRec_ + { + int align; + FT_Pos align_top; + FT_Pos align_bot; + + } PSH_AlignmentRec, *PSH_Alignment; + + + FT_LOCAL( void ) + psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ); + + +#if 0 + /* snap a stem width to fitter coordinates. `org_width' is in font */ + /* units. The result is in device pixels (26.6 format). */ + FT_LOCAL( FT_Pos ) + psh_dimension_snap_width( PSH_Dimension dimension, + FT_Int org_width ); +#endif + + FT_LOCAL( FT_Error ) + psh_globals_set_scale( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ); + + /* snap a stem to one or two blue zones */ + FT_LOCAL( void ) + psh_blues_snap_stem( PSH_Blues blues, + FT_Int stem_top, + FT_Int stem_bot, + PSH_Alignment alignment ); + /* */ + +#ifdef DEBUG_HINTER + extern PSH_Globals ps_debug_globals; +#endif + + +FT_END_HEADER + + +#endif /* __PSHGLOB_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshinter.c b/drivers/freetype/src/pshinter/pshinter.c new file mode 100644 index 0000000000..b35a2a91c5 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshinter.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* pshinter.c */ +/* */ +/* FreeType PostScript Hinting module */ +/* */ +/* Copyright 2001, 2003 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "pshpic.c" +#include "pshrec.c" +#include "pshglob.c" +#include "pshalgo.c" +#include "pshmod.c" + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshmod.c b/drivers/freetype/src/pshinter/pshmod.c new file mode 100644 index 0000000000..cdeaca18c9 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshmod.c @@ -0,0 +1,119 @@ +/***************************************************************************/ +/* */ +/* pshmod.c */ +/* */ +/* FreeType PostScript hinter module implementation (body). */ +/* */ +/* Copyright 2001, 2002, 2007, 2009, 2012 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "pshrec.h" +#include "pshalgo.h" +#include "pshpic.h" + + + /* the Postscript Hinter module structure */ + typedef struct PS_Hinter_Module_Rec_ + { + FT_ModuleRec root; + PS_HintsRec ps_hints; + + PSH_Globals_FuncsRec globals_funcs; + T1_Hints_FuncsRec t1_funcs; + T2_Hints_FuncsRec t2_funcs; + + } PS_Hinter_ModuleRec, *PS_Hinter_Module; + + + /* finalize module */ + FT_CALLBACK_DEF( void ) + ps_hinter_done( PS_Hinter_Module module ) + { + module->t1_funcs.hints = NULL; + module->t2_funcs.hints = NULL; + + ps_hints_done( &module->ps_hints ); + } + + + /* initialize module, create hints recorder and the interface */ + FT_CALLBACK_DEF( FT_Error ) + ps_hinter_init( PS_Hinter_Module module ) + { + FT_Memory memory = module->root.memory; + void* ph = &module->ps_hints; + + + ps_hints_init( &module->ps_hints, memory ); + + psh_globals_funcs_init( &module->globals_funcs ); + + t1_hints_funcs_init( &module->t1_funcs ); + module->t1_funcs.hints = (T1_Hints)ph; + + t2_hints_funcs_init( &module->t2_funcs ); + module->t2_funcs.hints = (T2_Hints)ph; + + return 0; + } + + + /* returns global hints interface */ + FT_CALLBACK_DEF( PSH_Globals_Funcs ) + pshinter_get_globals_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->globals_funcs; + } + + + /* return Type 1 hints interface */ + FT_CALLBACK_DEF( T1_Hints_Funcs ) + pshinter_get_t1_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->t1_funcs; + } + + + /* return Type 2 hints interface */ + FT_CALLBACK_DEF( T2_Hints_Funcs ) + pshinter_get_t2_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->t2_funcs; + } + + + FT_DEFINE_PSHINTER_INTERFACE( + pshinter_interface, + pshinter_get_globals_funcs, + pshinter_get_t1_funcs, + pshinter_get_t2_funcs ) + + + FT_DEFINE_MODULE( + pshinter_module_class, + + 0, + sizeof ( PS_Hinter_ModuleRec ), + "pshinter", + 0x10000L, + 0x20000L, + + &PSHINTER_INTERFACE_GET, /* module-specific interface */ + + (FT_Module_Constructor)ps_hinter_init, + (FT_Module_Destructor) ps_hinter_done, + (FT_Module_Requester) NULL ) /* no additional interface for now */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshmod.h b/drivers/freetype/src/pshinter/pshmod.h new file mode 100644 index 0000000000..0ae7e96f54 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshmod.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* pshmod.h */ +/* */ +/* PostScript hinter module interface (specification). */ +/* */ +/* Copyright 2001 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 __PSHMOD_H__ +#define __PSHMOD_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_MODULE( pshinter_module_class ) + + +FT_END_HEADER + + +#endif /* __PSHMOD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshnterr.h b/drivers/freetype/src/pshinter/pshnterr.h new file mode 100644 index 0000000000..7cc180f0ca --- /dev/null +++ b/drivers/freetype/src/pshinter/pshnterr.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* pshnterr.h */ +/* */ +/* PS Hinter error codes (specification only). */ +/* */ +/* Copyright 2003, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PSHinter error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSHNTERR_H__ +#define __PSHNTERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX PSH_Err_ +#define FT_ERR_BASE FT_Mod_Err_PShinter + +#include FT_ERRORS_H + +#endif /* __PSHNTERR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshpic.c b/drivers/freetype/src/pshinter/pshpic.c new file mode 100644 index 0000000000..568f4ac4b0 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshpic.c @@ -0,0 +1,76 @@ +/***************************************************************************/ +/* */ +/* pshpic.c */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009, 2010, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pshpic.h" +#include "pshnterr.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from pshmod.c */ + void + FT_Init_Class_pshinter_interface( FT_Library library, + PSHinter_Interface* clazz ); + + void + pshinter_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->pshinter ) + { + FT_FREE( pic_container->pshinter ); + pic_container->pshinter = NULL; + } + } + + + FT_Error + pshinter_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSHinterPIC* container = NULL; + FT_Memory memory = library->memory; + + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->pshinter = container; + + /* add call to initialization function when you add new scripts */ + FT_Init_Class_pshinter_interface( + library, &container->pshinter_interface ); + + if ( error ) + pshinter_module_class_pic_free( library ); + + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshpic.h b/drivers/freetype/src/pshinter/pshpic.h new file mode 100644 index 0000000000..b46f853113 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshpic.h @@ -0,0 +1,63 @@ +/***************************************************************************/ +/* */ +/* pshpic.h */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __PSHPIC_H__ +#define __PSHPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + +#ifndef FT_CONFIG_OPTION_PIC + +#define PSHINTER_INTERFACE_GET pshinter_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + typedef struct PSHinterPIC_ + { + PSHinter_Interface pshinter_interface; + + } PSHinterPIC; + + +#define GET_PIC( lib ) ( (PSHinterPIC*)( (lib)->pic_container.pshinter ) ) + +#define PSHINTER_INTERFACE_GET ( GET_PIC( library )->pshinter_interface ) + + /* see pshpic.c for the implementation */ + void + pshinter_module_class_pic_free( FT_Library library ); + + FT_Error + pshinter_module_class_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSHPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshrec.c b/drivers/freetype/src/pshinter/pshrec.c new file mode 100644 index 0000000000..cd66ea869a --- /dev/null +++ b/drivers/freetype/src/pshinter/pshrec.c @@ -0,0 +1,1225 @@ +/***************************************************************************/ +/* */ +/* pshrec.c */ +/* */ +/* FreeType PostScript hints recorder (body). */ +/* */ +/* Copyright 2001-2004, 2007, 2009, 2013 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H + +#include "pshrec.h" +#include "pshalgo.h" + +#include "pshnterr.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pshrec + +#ifdef DEBUG_HINTER + PS_Hints ps_debug_hints = 0; + int ps_debug_no_horz_hints = 0; + int ps_debug_no_vert_hints = 0; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_HINT MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* destroy hints table */ + static void + ps_hint_table_done( PS_Hint_Table table, + FT_Memory memory ) + { + FT_FREE( table->hints ); + table->num_hints = 0; + table->max_hints = 0; + } + + + /* ensure that a table can contain "count" elements */ + static FT_Error + ps_hint_table_ensure( PS_Hint_Table table, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = table->max_hints; + FT_UInt new_max = count; + FT_Error error = FT_Err_Ok; + + + if ( new_max > old_max ) + { + /* try to grow the table */ + new_max = FT_PAD_CEIL( new_max, 8 ); + if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) ) + table->max_hints = new_max; + } + return error; + } + + + static FT_Error + ps_hint_table_alloc( PS_Hint_Table table, + FT_Memory memory, + PS_Hint *ahint ) + { + FT_Error error = FT_Err_Ok; + FT_UInt count; + PS_Hint hint = 0; + + + count = table->num_hints; + count++; + + if ( count >= table->max_hints ) + { + error = ps_hint_table_ensure( table, count, memory ); + if ( error ) + goto Exit; + } + + hint = table->hints + count - 1; + hint->pos = 0; + hint->len = 0; + hint->flags = 0; + + table->num_hints = count; + + Exit: + *ahint = hint; + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_MASK MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* destroy mask */ + static void + ps_mask_done( PS_Mask mask, + FT_Memory memory ) + { + FT_FREE( mask->bytes ); + mask->num_bits = 0; + mask->max_bits = 0; + mask->end_point = 0; + } + + + /* ensure that a mask can contain "count" bits */ + static FT_Error + ps_mask_ensure( PS_Mask mask, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = ( mask->max_bits + 7 ) >> 3; + FT_UInt new_max = ( count + 7 ) >> 3; + FT_Error error = FT_Err_Ok; + + + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 8 ); + if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) ) + mask->max_bits = new_max * 8; + } + return error; + } + + + /* test a bit value in a given mask */ + static FT_Int + ps_mask_test_bit( PS_Mask mask, + FT_Int idx ) + { + if ( (FT_UInt)idx >= mask->num_bits ) + return 0; + + return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) ); + } + + + /* clear a given bit */ + static void + ps_mask_clear_bit( PS_Mask mask, + FT_Int idx ) + { + FT_Byte* p; + + + if ( (FT_UInt)idx >= mask->num_bits ) + return; + + p = mask->bytes + ( idx >> 3 ); + p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) ); + } + + + /* set a given bit, possibly grow the mask */ + static FT_Error + ps_mask_set_bit( PS_Mask mask, + FT_Int idx, + FT_Memory memory ) + { + FT_Error error = FT_Err_Ok; + FT_Byte* p; + + + if ( idx < 0 ) + goto Exit; + + if ( (FT_UInt)idx >= mask->num_bits ) + { + error = ps_mask_ensure( mask, idx + 1, memory ); + if ( error ) + goto Exit; + + mask->num_bits = idx + 1; + } + + p = mask->bytes + ( idx >> 3 ); + p[0] = (FT_Byte)( p[0] | ( 0x80 >> ( idx & 7 ) ) ); + + Exit: + return error; + } + + + /* destroy mask table */ + static void + ps_mask_table_done( PS_Mask_Table table, + FT_Memory memory ) + { + FT_UInt count = table->max_masks; + PS_Mask mask = table->masks; + + + for ( ; count > 0; count--, mask++ ) + ps_mask_done( mask, memory ); + + FT_FREE( table->masks ); + table->num_masks = 0; + table->max_masks = 0; + } + + + /* ensure that a mask table can contain "count" masks */ + static FT_Error + ps_mask_table_ensure( PS_Mask_Table table, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = table->max_masks; + FT_UInt new_max = count; + FT_Error error = FT_Err_Ok; + + + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 8 ); + if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) ) + table->max_masks = new_max; + } + return error; + } + + + /* allocate a new mask in a table */ + static FT_Error + ps_mask_table_alloc( PS_Mask_Table table, + FT_Memory memory, + PS_Mask *amask ) + { + FT_UInt count; + FT_Error error = FT_Err_Ok; + PS_Mask mask = 0; + + + count = table->num_masks; + count++; + + if ( count > table->max_masks ) + { + error = ps_mask_table_ensure( table, count, memory ); + if ( error ) + goto Exit; + } + + mask = table->masks + count - 1; + mask->num_bits = 0; + mask->end_point = 0; + table->num_masks = count; + + Exit: + *amask = mask; + return error; + } + + + /* return last hint mask in a table, create one if the table is empty */ + static FT_Error + ps_mask_table_last( PS_Mask_Table table, + FT_Memory memory, + PS_Mask *amask ) + { + FT_Error error = FT_Err_Ok; + FT_UInt count; + PS_Mask mask; + + + count = table->num_masks; + if ( count == 0 ) + { + error = ps_mask_table_alloc( table, memory, &mask ); + if ( error ) + goto Exit; + } + else + mask = table->masks + count - 1; + + Exit: + *amask = mask; + return error; + } + + + /* set a new mask to a given bit range */ + static FT_Error + ps_mask_table_set_bits( PS_Mask_Table table, + const FT_Byte* source, + FT_UInt bit_pos, + FT_UInt bit_count, + FT_Memory memory ) + { + FT_Error error; + PS_Mask mask; + + + error = ps_mask_table_last( table, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_ensure( mask, bit_count, memory ); + if ( error ) + goto Exit; + + mask->num_bits = bit_count; + + /* now, copy bits */ + { + FT_Byte* read = (FT_Byte*)source + ( bit_pos >> 3 ); + FT_Int rmask = 0x80 >> ( bit_pos & 7 ); + FT_Byte* write = mask->bytes; + FT_Int wmask = 0x80; + FT_Int val; + + + for ( ; bit_count > 0; bit_count-- ) + { + val = write[0] & ~wmask; + + if ( read[0] & rmask ) + val |= wmask; + + write[0] = (FT_Byte)val; + + rmask >>= 1; + if ( rmask == 0 ) + { + read++; + rmask = 0x80; + } + + wmask >>= 1; + if ( wmask == 0 ) + { + write++; + wmask = 0x80; + } + } + } + + Exit: + return error; + } + + + /* test whether two masks in a table intersect */ + static FT_Int + ps_mask_table_test_intersect( PS_Mask_Table table, + FT_Int index1, + FT_Int index2 ) + { + PS_Mask mask1 = table->masks + index1; + PS_Mask mask2 = table->masks + index2; + FT_Byte* p1 = mask1->bytes; + FT_Byte* p2 = mask2->bytes; + FT_UInt count1 = mask1->num_bits; + FT_UInt count2 = mask2->num_bits; + FT_UInt count; + + + count = FT_MIN( count1, count2 ); + for ( ; count >= 8; count -= 8 ) + { + if ( p1[0] & p2[0] ) + return 1; + + p1++; + p2++; + } + + if ( count == 0 ) + return 0; + + return ( p1[0] & p2[0] ) & ~( 0xFF >> count ); + } + + + /* merge two masks, used by ps_mask_table_merge_all */ + static FT_Error + ps_mask_table_merge( PS_Mask_Table table, + FT_Int index1, + FT_Int index2, + FT_Memory memory ) + { + FT_UInt temp; + FT_Error error = FT_Err_Ok; + + + /* swap index1 and index2 so that index1 < index2 */ + if ( index1 > index2 ) + { + temp = index1; + index1 = index2; + index2 = temp; + } + + if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks ) + { + /* we need to merge the bitsets of index1 and index2 with a */ + /* simple union */ + PS_Mask mask1 = table->masks + index1; + PS_Mask mask2 = table->masks + index2; + FT_UInt count1 = mask1->num_bits; + FT_UInt count2 = mask2->num_bits; + FT_Int delta; + + + if ( count2 > 0 ) + { + FT_UInt pos; + FT_Byte* read; + FT_Byte* write; + + + /* if "count2" is greater than "count1", we need to grow the */ + /* first bitset, and clear the highest bits */ + if ( count2 > count1 ) + { + error = ps_mask_ensure( mask1, count2, memory ); + if ( error ) + goto Exit; + + for ( pos = count1; pos < count2; pos++ ) + ps_mask_clear_bit( mask1, pos ); + } + + /* merge (unite) the bitsets */ + read = mask2->bytes; + write = mask1->bytes; + pos = (FT_UInt)( ( count2 + 7 ) >> 3 ); + + for ( ; pos > 0; pos-- ) + { + write[0] = (FT_Byte)( write[0] | read[0] ); + write++; + read++; + } + } + + /* Now, remove "mask2" from the list. We need to keep the masks */ + /* sorted in order of importance, so move table elements. */ + mask2->num_bits = 0; + mask2->end_point = 0; + + delta = table->num_masks - 1 - index2; /* number of masks to move */ + if ( delta > 0 ) + { + /* move to end of table for reuse */ + PS_MaskRec dummy = *mask2; + + + ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) ); + + mask2[delta] = dummy; + } + + table->num_masks--; + } + else + FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", + index1, index2 )); + + Exit: + return error; + } + + + /* Try to merge all masks in a given table. This is used to merge */ + /* all counter masks into independent counter "paths". */ + /* */ + static FT_Error + ps_mask_table_merge_all( PS_Mask_Table table, + FT_Memory memory ) + { + FT_Int index1, index2; + FT_Error error = FT_Err_Ok; + + + for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) + { + for ( index2 = index1 - 1; index2 >= 0; index2-- ) + { + if ( ps_mask_table_test_intersect( table, index1, index2 ) ) + { + error = ps_mask_table_merge( table, index2, index1, memory ); + if ( error ) + goto Exit; + + break; + } + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_DIMENSION MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* finalize a given dimension */ + static void + ps_dimension_done( PS_Dimension dimension, + FT_Memory memory ) + { + ps_mask_table_done( &dimension->counters, memory ); + ps_mask_table_done( &dimension->masks, memory ); + ps_hint_table_done( &dimension->hints, memory ); + } + + + /* initialize a given dimension */ + static void + ps_dimension_init( PS_Dimension dimension ) + { + dimension->hints.num_hints = 0; + dimension->masks.num_masks = 0; + dimension->counters.num_masks = 0; + } + + +#if 0 + + /* set a bit at a given index in the current hint mask */ + static FT_Error + ps_dimension_set_mask_bit( PS_Dimension dim, + FT_UInt idx, + FT_Memory memory ) + { + PS_Mask mask; + FT_Error error = FT_Err_Ok; + + + /* get last hint mask */ + error = ps_mask_table_last( &dim->masks, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( mask, idx, memory ); + + Exit: + return error; + } + +#endif + + /* set the end point in a mask, called from "End" & "Reset" methods */ + static void + ps_dimension_end_mask( PS_Dimension dim, + FT_UInt end_point ) + { + FT_UInt count = dim->masks.num_masks; + + + if ( count > 0 ) + { + PS_Mask mask = dim->masks.masks + count - 1; + + + mask->end_point = end_point; + } + } + + + /* set the end point in the current mask, then create a new empty one */ + /* (called by "Reset" method) */ + static FT_Error + ps_dimension_reset_mask( PS_Dimension dim, + FT_UInt end_point, + FT_Memory memory ) + { + PS_Mask mask; + + + /* end current mask */ + ps_dimension_end_mask( dim, end_point ); + + /* allocate new one */ + return ps_mask_table_alloc( &dim->masks, memory, &mask ); + } + + + /* set a new mask, called from the "T2Stem" method */ + static FT_Error + ps_dimension_set_mask_bits( PS_Dimension dim, + const FT_Byte* source, + FT_UInt source_pos, + FT_UInt source_bits, + FT_UInt end_point, + FT_Memory memory ) + { + FT_Error error; + + + /* reset current mask, if any */ + error = ps_dimension_reset_mask( dim, end_point, memory ); + if ( error ) + goto Exit; + + /* set bits in new mask */ + error = ps_mask_table_set_bits( &dim->masks, source, + source_pos, source_bits, memory ); + + Exit: + return error; + } + + + /* add a new single stem (called from "T1Stem" method) */ + static FT_Error + ps_dimension_add_t1stem( PS_Dimension dim, + FT_Int pos, + FT_Int len, + FT_Memory memory, + FT_Int *aindex ) + { + FT_Error error = FT_Err_Ok; + FT_UInt flags = 0; + + + /* detect ghost stem */ + if ( len < 0 ) + { + flags |= PS_HINT_FLAG_GHOST; + if ( len == -21 ) + { + flags |= PS_HINT_FLAG_BOTTOM; + pos += len; + } + len = 0; + } + + if ( aindex ) + *aindex = -1; + + /* now, lookup stem in the current hints table */ + { + PS_Mask mask; + FT_UInt idx; + FT_UInt max = dim->hints.num_hints; + PS_Hint hint = dim->hints.hints; + + + for ( idx = 0; idx < max; idx++, hint++ ) + { + if ( hint->pos == pos && hint->len == len ) + break; + } + + /* we need to create a new hint in the table */ + if ( idx >= max ) + { + error = ps_hint_table_alloc( &dim->hints, memory, &hint ); + if ( error ) + goto Exit; + + hint->pos = pos; + hint->len = len; + hint->flags = flags; + } + + /* now, store the hint in the current mask */ + error = ps_mask_table_last( &dim->masks, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( mask, idx, memory ); + if ( error ) + goto Exit; + + if ( aindex ) + *aindex = (FT_Int)idx; + } + + Exit: + return error; + } + + + /* add a "hstem3/vstem3" counter to our dimension table */ + static FT_Error + ps_dimension_add_counter( PS_Dimension dim, + FT_Int hint1, + FT_Int hint2, + FT_Int hint3, + FT_Memory memory ) + { + FT_Error error = FT_Err_Ok; + FT_UInt count = dim->counters.num_masks; + PS_Mask counter = dim->counters.masks; + + + /* try to find an existing counter mask that already uses */ + /* one of these stems here */ + for ( ; count > 0; count--, counter++ ) + { + if ( ps_mask_test_bit( counter, hint1 ) || + ps_mask_test_bit( counter, hint2 ) || + ps_mask_test_bit( counter, hint3 ) ) + break; + } + + /* create a new counter when needed */ + if ( count == 0 ) + { + error = ps_mask_table_alloc( &dim->counters, memory, &counter ); + if ( error ) + goto Exit; + } + + /* now, set the bits for our hints in the counter mask */ + error = ps_mask_set_bit( counter, hint1, memory ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( counter, hint2, memory ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( counter, hint3, memory ); + if ( error ) + goto Exit; + + Exit: + return error; + } + + + /* end of recording session for a given dimension */ + static FT_Error + ps_dimension_end( PS_Dimension dim, + FT_UInt end_point, + FT_Memory memory ) + { + /* end hint mask table */ + ps_dimension_end_mask( dim, end_point ); + + /* merge all counter masks into independent "paths" */ + return ps_mask_table_merge_all( &dim->counters, memory ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_RECORDER MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* destroy hints */ + FT_LOCAL( void ) + ps_hints_done( PS_Hints hints ) + { + FT_Memory memory = hints->memory; + + + ps_dimension_done( &hints->dimension[0], memory ); + ps_dimension_done( &hints->dimension[1], memory ); + + hints->error = FT_Err_Ok; + hints->memory = 0; + } + + + FT_LOCAL( FT_Error ) + ps_hints_init( PS_Hints hints, + FT_Memory memory ) + { + FT_MEM_ZERO( hints, sizeof ( *hints ) ); + hints->memory = memory; + return FT_Err_Ok; + } + + + /* initialize a hints for a new session */ + static void + ps_hints_open( PS_Hints hints, + PS_Hint_Type hint_type ) + { + switch ( hint_type ) + { + case PS_HINT_TYPE_1: + case PS_HINT_TYPE_2: + hints->error = FT_Err_Ok; + hints->hint_type = hint_type; + + ps_dimension_init( &hints->dimension[0] ); + ps_dimension_init( &hints->dimension[1] ); + break; + + default: + hints->error = FT_THROW( Invalid_Argument ); + hints->hint_type = hint_type; + + FT_TRACE0(( "ps_hints_open: invalid charstring type\n" )); + break; + } + } + + + /* add one or more stems to the current hints table */ + static void + ps_hints_stem( PS_Hints hints, + FT_Int dimension, + FT_UInt count, + FT_Long* stems ) + { + if ( !hints->error ) + { + /* limit "dimension" to 0..1 */ + if ( dimension < 0 || dimension > 1 ) + { + FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", + dimension )); + dimension = ( dimension != 0 ); + } + + /* record the stems in the current hints/masks table */ + switch ( hints->hint_type ) + { + case PS_HINT_TYPE_1: /* Type 1 "hstem" or "vstem" operator */ + case PS_HINT_TYPE_2: /* Type 2 "hstem" or "vstem" operator */ + { + PS_Dimension dim = &hints->dimension[dimension]; + + + for ( ; count > 0; count--, stems += 2 ) + { + FT_Error error; + FT_Memory memory = hints->memory; + + + error = ps_dimension_add_t1stem( + dim, (FT_Int)stems[0], (FT_Int)stems[1], + memory, NULL ); + if ( error ) + { + FT_ERROR(( "ps_hints_stem: could not add stem" + " (%d,%d) to hints table\n", stems[0], stems[1] )); + + hints->error = error; + return; + } + } + break; + } + + default: + FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n", + hints->hint_type )); + break; + } + } + } + + + /* add one Type1 counter stem to the current hints table */ + static void + ps_hints_t1stem3( PS_Hints hints, + FT_Int dimension, + FT_Fixed* stems ) + { + FT_Error error = FT_Err_Ok; + + + if ( !hints->error ) + { + PS_Dimension dim; + FT_Memory memory = hints->memory; + FT_Int count; + FT_Int idx[3]; + + + /* limit "dimension" to 0..1 */ + if ( dimension < 0 || dimension > 1 ) + { + FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n", + dimension )); + dimension = ( dimension != 0 ); + } + + dim = &hints->dimension[dimension]; + + /* there must be 6 elements in the 'stem' array */ + if ( hints->hint_type == PS_HINT_TYPE_1 ) + { + /* add the three stems to our hints/masks table */ + for ( count = 0; count < 3; count++, stems += 2 ) + { + error = ps_dimension_add_t1stem( dim, + (FT_Int)FIXED_TO_INT( stems[0] ), + (FT_Int)FIXED_TO_INT( stems[1] ), + memory, &idx[count] ); + if ( error ) + goto Fail; + } + + /* now, add the hints to the counters table */ + error = ps_dimension_add_counter( dim, idx[0], idx[1], idx[2], + memory ); + if ( error ) + goto Fail; + } + else + { + FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" )); + error = FT_THROW( Invalid_Argument ); + goto Fail; + } + } + + return; + + Fail: + FT_ERROR(( "ps_hints_t1stem3: could not add counter stems to table\n" )); + hints->error = error; + } + + + /* reset hints (only with Type 1 hints) */ + static void + ps_hints_t1reset( PS_Hints hints, + FT_UInt end_point ) + { + FT_Error error = FT_Err_Ok; + + + if ( !hints->error ) + { + FT_Memory memory = hints->memory; + + + if ( hints->hint_type == PS_HINT_TYPE_1 ) + { + error = ps_dimension_reset_mask( &hints->dimension[0], + end_point, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_reset_mask( &hints->dimension[1], + end_point, memory ); + if ( error ) + goto Fail; + } + else + { + /* invalid hint type */ + error = FT_THROW( Invalid_Argument ); + goto Fail; + } + } + return; + + Fail: + hints->error = error; + } + + + /* Type2 "hintmask" operator, add a new hintmask to each direction */ + static void + ps_hints_t2mask( PS_Hints hints, + FT_UInt end_point, + FT_UInt bit_count, + const FT_Byte* bytes ) + { + FT_Error error; + + + if ( !hints->error ) + { + PS_Dimension dim = hints->dimension; + FT_Memory memory = hints->memory; + FT_UInt count1 = dim[0].hints.num_hints; + FT_UInt count2 = dim[1].hints.num_hints; + + + /* check bit count; must be equal to current total hint count */ + if ( bit_count != count1 + count2 ) + { + FT_TRACE0(( "ps_hints_t2mask:" + " called with invalid bitcount %d (instead of %d)\n", + bit_count, count1 + count2 )); + + /* simply ignore the operator */ + return; + } + + /* set-up new horizontal and vertical hint mask now */ + error = ps_dimension_set_mask_bits( &dim[0], bytes, count2, count1, + end_point, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_set_mask_bits( &dim[1], bytes, 0, count2, + end_point, memory ); + if ( error ) + goto Fail; + } + return; + + Fail: + hints->error = error; + } + + + static void + ps_hints_t2counter( PS_Hints hints, + FT_UInt bit_count, + const FT_Byte* bytes ) + { + FT_Error error; + + + if ( !hints->error ) + { + PS_Dimension dim = hints->dimension; + FT_Memory memory = hints->memory; + FT_UInt count1 = dim[0].hints.num_hints; + FT_UInt count2 = dim[1].hints.num_hints; + + + /* check bit count, must be equal to current total hint count */ + if ( bit_count != count1 + count2 ) + { + FT_TRACE0(( "ps_hints_t2counter:" + " called with invalid bitcount %d (instead of %d)\n", + bit_count, count1 + count2 )); + + /* simply ignore the operator */ + return; + } + + /* set-up new horizontal and vertical hint mask now */ + error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1, + 0, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2, + 0, memory ); + if ( error ) + goto Fail; + } + return; + + Fail: + hints->error = error; + } + + + /* end recording session */ + static FT_Error + ps_hints_close( PS_Hints hints, + FT_UInt end_point ) + { + FT_Error error; + + + error = hints->error; + if ( !error ) + { + FT_Memory memory = hints->memory; + PS_Dimension dim = hints->dimension; + + + error = ps_dimension_end( &dim[0], end_point, memory ); + if ( !error ) + { + error = ps_dimension_end( &dim[1], end_point, memory ); + } + } + +#ifdef DEBUG_HINTER + if ( !error ) + ps_debug_hints = hints; +#endif + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 HINTS RECORDING INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t1_hints_open( T1_Hints hints ) + { + ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 ); + } + + static void + t1_hints_stem( T1_Hints hints, + FT_Int dimension, + FT_Fixed* coords ) + { + FT_Pos stems[2]; + + + stems[0] = FIXED_TO_INT( coords[0] ); + stems[1] = FIXED_TO_INT( coords[1] ); + + ps_hints_stem( (PS_Hints)hints, dimension, 1, stems ); + } + + + FT_LOCAL_DEF( void ) + t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ) + { + FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) ); + + funcs->open = (T1_Hints_OpenFunc) t1_hints_open; + funcs->close = (T1_Hints_CloseFunc) ps_hints_close; + funcs->stem = (T1_Hints_SetStemFunc) t1_hints_stem; + funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3; + funcs->reset = (T1_Hints_ResetFunc) ps_hints_t1reset; + funcs->apply = (T1_Hints_ApplyFunc) ps_hints_apply; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 2 HINTS RECORDING INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t2_hints_open( T2_Hints hints ) + { + ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_2 ); + } + + + static void + t2_hints_stems( T2_Hints hints, + FT_Int dimension, + FT_Int count, + FT_Fixed* coords ) + { + FT_Pos stems[32], y, n; + FT_Int total = count; + + + y = 0; + while ( total > 0 ) + { + /* determine number of stems to write */ + count = total; + if ( count > 16 ) + count = 16; + + /* compute integer stem positions in font units */ + for ( n = 0; n < count * 2; n++ ) + { + y += coords[n]; + stems[n] = FIXED_TO_INT( y ); + } + + /* compute lengths */ + for ( n = 0; n < count * 2; n += 2 ) + stems[n + 1] = stems[n + 1] - stems[n]; + + /* add them to the current dimension */ + ps_hints_stem( (PS_Hints)hints, dimension, count, stems ); + + total -= count; + } + } + + + FT_LOCAL_DEF( void ) + t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ) + { + FT_MEM_ZERO( funcs, sizeof ( *funcs ) ); + + funcs->open = (T2_Hints_OpenFunc) t2_hints_open; + funcs->close = (T2_Hints_CloseFunc) ps_hints_close; + funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; + funcs->hintmask= (T2_Hints_MaskFunc) ps_hints_t2mask; + funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter; + funcs->apply = (T2_Hints_ApplyFunc) ps_hints_apply; + } + + +/* END */ diff --git a/drivers/freetype/src/pshinter/pshrec.h b/drivers/freetype/src/pshinter/pshrec.h new file mode 100644 index 0000000000..dcb3197f94 --- /dev/null +++ b/drivers/freetype/src/pshinter/pshrec.h @@ -0,0 +1,176 @@ +/***************************************************************************/ +/* */ +/* pshrec.h */ +/* */ +/* Postscript (Type1/Type2) hints recorder (specification). */ +/* */ +/* Copyright 2001, 2002, 2003, 2006, 2008 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. */ +/* */ +/***************************************************************************/ + + + /**************************************************************************/ + /* */ + /* The functions defined here are called from the Type 1, CID and CFF */ + /* font drivers to record the hints of a given character/glyph. */ + /* */ + /* The hints are recorded in a unified format, and are later processed */ + /* by the `optimizer' and `fitter' to adjust the outlines to the pixel */ + /* grid. */ + /* */ + /**************************************************************************/ + + +#ifndef __PSHREC_H__ +#define __PSHREC_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include "pshglob.h" + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH HINTS RECORDER INTERNALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to hint record */ + typedef struct PS_HintRec_* PS_Hint; + + /* hint types */ + typedef enum PS_Hint_Type_ + { + PS_HINT_TYPE_1 = 1, + PS_HINT_TYPE_2 = 2 + + } PS_Hint_Type; + + + /* hint flags */ + typedef enum PS_Hint_Flags_ + { + PS_HINT_FLAG_GHOST = 1, + PS_HINT_FLAG_BOTTOM = 2 + + } PS_Hint_Flags; + + + /* hint descriptor */ + typedef struct PS_HintRec_ + { + FT_Int pos; + FT_Int len; + FT_UInt flags; + + } PS_HintRec; + + +#define ps_hint_is_active( x ) ( (x)->flags & PS_HINT_FLAG_ACTIVE ) +#define ps_hint_is_ghost( x ) ( (x)->flags & PS_HINT_FLAG_GHOST ) +#define ps_hint_is_bottom( x ) ( (x)->flags & PS_HINT_FLAG_BOTTOM ) + + + /* hints table descriptor */ + typedef struct PS_Hint_TableRec_ + { + FT_UInt num_hints; + FT_UInt max_hints; + PS_Hint hints; + + } PS_Hint_TableRec, *PS_Hint_Table; + + + /* hint and counter mask descriptor */ + typedef struct PS_MaskRec_ + { + FT_UInt num_bits; + FT_UInt max_bits; + FT_Byte* bytes; + FT_UInt end_point; + + } PS_MaskRec, *PS_Mask; + + + /* masks and counters table descriptor */ + typedef struct PS_Mask_TableRec_ + { + FT_UInt num_masks; + FT_UInt max_masks; + PS_Mask masks; + + } PS_Mask_TableRec, *PS_Mask_Table; + + + /* dimension-specific hints descriptor */ + typedef struct PS_DimensionRec_ + { + PS_Hint_TableRec hints; + PS_Mask_TableRec masks; + PS_Mask_TableRec counters; + + } PS_DimensionRec, *PS_Dimension; + + + /* glyph hints descriptor */ + /* dimension 0 => X coordinates + vertical hints/stems */ + /* dimension 1 => Y coordinates + horizontal hints/stems */ + typedef struct PS_HintsRec_ + { + FT_Memory memory; + FT_Error error; + FT_UInt32 magic; + PS_Hint_Type hint_type; + PS_DimensionRec dimension[2]; + + } PS_HintsRec, *PS_Hints; + + /* */ + + /* initialize hints recorder */ + FT_LOCAL( FT_Error ) + ps_hints_init( PS_Hints hints, + FT_Memory memory ); + + /* finalize hints recorder */ + FT_LOCAL( void ) + ps_hints_done( PS_Hints hints ); + + /* initialize Type1 hints recorder interface */ + FT_LOCAL( void ) + t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ); + + /* initialize Type2 hints recorder interface */ + FT_LOCAL( void ) + t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ); + + +#ifdef DEBUG_HINTER + extern PS_Hints ps_debug_hints; + extern int ps_debug_no_horz_hints; + extern int ps_debug_no_vert_hints; +#endif + + /* */ + + +FT_END_HEADER + + +#endif /* __PS_HINTER_RECORD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/pshinter/rules.mk b/drivers/freetype/src/pshinter/rules.mk new file mode 100644 index 0000000000..888ece1058 --- /dev/null +++ b/drivers/freetype/src/pshinter/rules.mk @@ -0,0 +1,73 @@ +# +# FreeType 2 PSHinter driver configuration rules +# + + +# Copyright 2001, 2003, 2011 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. + + +# PSHINTER driver directory +# +PSHINTER_DIR := $(SRC_DIR)/pshinter + + +# compilation flags for the driver +# +PSHINTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) + + +# PSHINTER driver sources (i.e., C files) +# +PSHINTER_DRV_SRC := $(PSHINTER_DIR)/pshalgo.c \ + $(PSHINTER_DIR)/pshglob.c \ + $(PSHINTER_DIR)/pshmod.c \ + $(PSHINTER_DIR)/pshpic.c \ + $(PSHINTER_DIR)/pshrec.c + + +# PSHINTER driver headers +# +PSHINTER_DRV_H := $(PSHINTER_DRV_SRC:%c=%h) \ + $(PSHINTER_DIR)/pshnterr.h + + +# PSHINTER driver object(s) +# +# PSHINTER_DRV_OBJ_M is used during `multi' builds. +# PSHINTER_DRV_OBJ_S is used during `single' builds. +# +PSHINTER_DRV_OBJ_M := $(PSHINTER_DRV_SRC:$(PSHINTER_DIR)/%.c=$(OBJ_DIR)/%.$O) +PSHINTER_DRV_OBJ_S := $(OBJ_DIR)/pshinter.$O + +# PSHINTER driver source file for single build +# +PSHINTER_DRV_SRC_S := $(PSHINTER_DIR)/pshinter.c + + +# PSHINTER driver - single object +# +$(PSHINTER_DRV_OBJ_S): $(PSHINTER_DRV_SRC_S) $(PSHINTER_DRV_SRC) \ + $(FREETYPE_H) $(PSHINTER_DRV_H) + $(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSHINTER_DRV_SRC_S)) + + +# PSHINTER driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(PSHINTER_DIR)/%.c $(FREETYPE_H) $(PSHINTER_DRV_H) + $(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(PSHINTER_DRV_OBJ_S) +DRV_OBJS_M += $(PSHINTER_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/psnames/Jamfile b/drivers/freetype/src/psnames/Jamfile new file mode 100644 index 0000000000..06c0dda66f --- /dev/null +++ b/drivers/freetype/src/psnames/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/psnames Jamfile +# +# Copyright 2001 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) psnames ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = psmodule pspic ; + } + else + { + _sources = psnames ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/psnames Jamfile diff --git a/drivers/freetype/src/psnames/module.mk b/drivers/freetype/src/psnames/module.mk new file mode 100644 index 0000000000..a6e908257c --- /dev/null +++ b/drivers/freetype/src/psnames/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 PSnames module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += PSNAMES_MODULE + +define PSNAMES_MODULE +$(OPEN_DRIVER) FT_Module_Class, psnames_module_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/psnames/psmodule.c b/drivers/freetype/src/psnames/psmodule.c new file mode 100644 index 0000000000..0a5bcb7d2a --- /dev/null +++ b/drivers/freetype/src/psnames/psmodule.c @@ -0,0 +1,609 @@ +/***************************************************************************/ +/* */ +/* psmodule.c */ +/* */ +/* PSNames module implementation (body). */ +/* */ +/* Copyright 1996-2003, 2005-2008, 2012, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + +#include "psmodule.h" +#include "pstables.h" + +#include "psnamerr.h" +#include "pspic.h" + + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + +#define VARIANT_BIT 0x80000000UL +#define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) ) + + + /* Return the Unicode value corresponding to a given glyph. Note that */ + /* we do deal with glyph variants by detecting a non-initial dot in */ + /* the name, as in `A.swash' or `e.final'; in this case, the */ + /* VARIANT_BIT is set in the return value. */ + /* */ + static FT_UInt32 + ps_unicode_value( const char* glyph_name ) + { + /* If the name begins with `uni', then the glyph name may be a */ + /* hard-coded unicode character code. */ + if ( glyph_name[0] == 'u' && + glyph_name[1] == 'n' && + glyph_name[2] == 'i' ) + { + /* determine whether the next four characters following are */ + /* hexadecimal. */ + + /* XXX: Add code to deal with ligatures, i.e. glyph names like */ + /* `uniXXXXYYYYZZZZ'... */ + + FT_Int count; + FT_UInt32 value = 0; + const char* p = glyph_name + 3; + + + for ( count = 4; count > 0; count--, p++ ) + { + char c = *p; + unsigned int d; + + + d = (unsigned char)c - '0'; + if ( d >= 10 ) + { + d = (unsigned char)c - 'A'; + if ( d >= 6 ) + d = 16; + else + d += 10; + } + + /* Exit if a non-uppercase hexadecimal character was found */ + /* -- this also catches character codes below `0' since such */ + /* negative numbers cast to `unsigned int' are far too big. */ + if ( d >= 16 ) + break; + + value = ( value << 4 ) + d; + } + + /* there must be exactly four hex digits */ + if ( count == 0 ) + { + if ( *p == '\0' ) + return value; + if ( *p == '.' ) + return (FT_UInt32)( value | VARIANT_BIT ); + } + } + + /* If the name begins with `u', followed by four to six uppercase */ + /* hexadecimal digits, it is a hard-coded unicode character code. */ + if ( glyph_name[0] == 'u' ) + { + FT_Int count; + FT_UInt32 value = 0; + const char* p = glyph_name + 1; + + + for ( count = 6; count > 0; count--, p++ ) + { + char c = *p; + unsigned int d; + + + d = (unsigned char)c - '0'; + if ( d >= 10 ) + { + d = (unsigned char)c - 'A'; + if ( d >= 6 ) + d = 16; + else + d += 10; + } + + if ( d >= 16 ) + break; + + value = ( value << 4 ) + d; + } + + if ( count <= 2 ) + { + if ( *p == '\0' ) + return value; + if ( *p == '.' ) + return (FT_UInt32)( value | VARIANT_BIT ); + } + } + + /* Look for a non-initial dot in the glyph name in order to */ + /* find variants like `A.swash', `e.final', etc. */ + { + const char* p = glyph_name; + const char* dot = NULL; + + + for ( ; *p; p++ ) + { + if ( *p == '.' && p > glyph_name ) + { + dot = p; + break; + } + } + + /* now look up the glyph in the Adobe Glyph List */ + if ( !dot ) + return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); + else + return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | + VARIANT_BIT ); + } + } + + + /* ft_qsort callback to sort the unicode map */ + FT_CALLBACK_DEF( int ) + compare_uni_maps( const void* a, + const void* b ) + { + PS_UniMap* map1 = (PS_UniMap*)a; + PS_UniMap* map2 = (PS_UniMap*)b; + FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode ); + FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode ); + + + /* sort base glyphs before glyph variants */ + if ( unicode1 == unicode2 ) + { + if ( map1->unicode > map2->unicode ) + return 1; + else if ( map1->unicode < map2->unicode ) + return -1; + else + return 0; + } + else + { + if ( unicode1 > unicode2 ) + return 1; + else if ( unicode1 < unicode2 ) + return -1; + else + return 0; + } + } + + + /* support for extra glyphs not handled (well) in AGL; */ + /* we add extra mappings for them if necessary */ + +#define EXTRA_GLYPH_LIST_SIZE 10 + + static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] = + { + /* WGL 4 */ + 0x0394, + 0x03A9, + 0x2215, + 0x00AD, + 0x02C9, + 0x03BC, + 0x2219, + 0x00A0, + /* Romanian */ + 0x021A, + 0x021B + }; + + static const char ft_extra_glyph_names[] = + { + 'D','e','l','t','a',0, + 'O','m','e','g','a',0, + 'f','r','a','c','t','i','o','n',0, + 'h','y','p','h','e','n',0, + 'm','a','c','r','o','n',0, + 'm','u',0, + 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0, + 's','p','a','c','e',0, + 'T','c','o','m','m','a','a','c','c','e','n','t',0, + 't','c','o','m','m','a','a','c','c','e','n','t',0 + }; + + static const FT_Int + ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] = + { + 0, + 6, + 12, + 21, + 28, + 35, + 38, + 53, + 59, + 72 + }; + + + static void + ps_check_extra_glyph_name( const char* gname, + FT_UInt glyph, + FT_UInt* extra_glyphs, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( ft_strcmp( ft_extra_glyph_names + + ft_extra_glyph_name_offsets[n], gname ) == 0 ) + { + if ( states[n] == 0 ) + { + /* mark this extra glyph as a candidate for the cmap */ + states[n] = 1; + extra_glyphs[n] = glyph; + } + + return; + } + } + } + + + static void + ps_check_extra_glyph_unicode( FT_UInt32 uni_char, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( uni_char == ft_extra_glyph_unicodes[n] ) + { + /* disable this extra glyph from being added to the cmap */ + states[n] = 2; + + return; + } + } + } + + + /* 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_GetGlyphNameFunc get_glyph_name, + PS_FreeGlyphNameFunc free_glyph_name, + FT_Pointer glyph_data ) + { + FT_Error error; + + FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE]; + + + /* we first allocate the table */ + table->num_maps = 0; + table->maps = 0; + + if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) + { + FT_UInt n; + FT_UInt count; + PS_UniMap* map; + FT_UInt32 uni_char; + + + map = table->maps; + + for ( n = 0; n < num_glyphs; n++ ) + { + const char* gname = get_glyph_name( glyph_data, n ); + + + if ( gname ) + { + ps_check_extra_glyph_name( gname, n, + extra_glyphs, extra_glyph_list_states ); + uni_char = ps_unicode_value( gname ); + + if ( BASE_GLYPH( uni_char ) != 0 ) + { + ps_check_extra_glyph_unicode( uni_char, + extra_glyph_list_states ); + map->unicode = uni_char; + map->glyph_index = n; + map++; + } + + if ( free_glyph_name ) + free_glyph_name( glyph_data, gname ); + } + } + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( extra_glyph_list_states[n] == 1 ) + { + /* This glyph name has an additional representation. */ + /* Add it to the cmap. */ + + map->unicode = ft_extra_glyph_unicodes[n]; + map->glyph_index = extra_glyphs[n]; + map++; + } + } + + /* now compress the table a bit */ + count = (FT_UInt)( map - table->maps ); + + if ( count == 0 ) + { + /* No unicode chars here! */ + FT_FREE( table->maps ); + if ( !error ) + error = FT_THROW( No_Unicode_Glyph_Name ); + } + else + { + /* Reallocate if the number of used entries is much smaller. */ + if ( count < num_glyphs / 2 ) + { + (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count ); + error = FT_Err_Ok; + } + + /* Sort the table in increasing order of unicode values, */ + /* taking care of glyph variants. */ + ft_qsort( table->maps, count, sizeof ( PS_UniMap ), + compare_uni_maps ); + } + + table->num_maps = count; + } + + return error; + } + + + static FT_UInt + ps_unicodes_char_index( PS_Unicodes table, + FT_UInt32 unicode ) + { + PS_UniMap *min, *max, *mid, *result = NULL; + + + /* Perform a binary search on the table. */ + + min = table->maps; + max = min + table->num_maps - 1; + + while ( min <= max ) + { + FT_UInt32 base_glyph; + + + mid = min + ( ( max - min ) >> 1 ); + + if ( mid->unicode == unicode ) + { + result = mid; + break; + } + + base_glyph = BASE_GLYPH( mid->unicode ); + + if ( base_glyph == unicode ) + result = mid; /* remember match but continue search for base glyph */ + + if ( min == max ) + break; + + if ( base_glyph < unicode ) + min = mid + 1; + else + max = mid - 1; + } + + if ( result ) + return result->glyph_index; + else + return 0; + } + + + static FT_UInt32 + ps_unicodes_char_next( PS_Unicodes table, + FT_UInt32 *unicode ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *unicode + 1; + + + { + FT_UInt min = 0; + FT_UInt max = table->num_maps; + FT_UInt mid; + PS_UniMap* map; + FT_UInt32 base_glyph; + + + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + map = table->maps + mid; + + if ( map->unicode == char_code ) + { + result = map->glyph_index; + goto Exit; + } + + base_glyph = BASE_GLYPH( map->unicode ); + + if ( base_glyph == char_code ) + result = map->glyph_index; + + if ( base_glyph < char_code ) + min = mid + 1; + else + max = mid; + } + + if ( result ) + goto Exit; /* we have a variant glyph */ + + /* we didn't find it; check whether we have a map just above it */ + char_code = 0; + + if ( min < table->num_maps ) + { + map = table->maps + min; + result = map->glyph_index; + char_code = BASE_GLYPH( map->unicode ); + } + } + + Exit: + *unicode = char_code; + return result; + } + + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + + static const char* + ps_get_macintosh_name( FT_UInt name_index ) + { + if ( name_index >= FT_NUM_MAC_NAMES ) + name_index = 0; + + return ft_standard_glyph_names + ft_mac_names[name_index]; + } + + + static const char* + ps_get_standard_strings( FT_UInt sid ) + { + if ( sid >= FT_NUM_SID_NAMES ) + return 0; + + return ft_standard_glyph_names + ft_sid_names[sid]; + } + + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + FT_DEFINE_SERVICE_PSCMAPSREC( + pscmaps_interface, + (PS_Unicode_ValueFunc) ps_unicode_value, + (PS_Unicodes_InitFunc) ps_unicodes_init, + (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, + (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, + + (PS_Macintosh_NameFunc) ps_get_macintosh_name, + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + + t1_standard_encoding, + t1_expert_encoding ) + +#else + + FT_DEFINE_SERVICE_PSCMAPSREC( + pscmaps_interface, + NULL, + NULL, + NULL, + NULL, + + (PS_Macintosh_NameFunc) ps_get_macintosh_name, + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + + t1_standard_encoding, + t1_expert_encoding ) + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + + FT_DEFINE_SERVICEDESCREC1( + pscmaps_services, + FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET ) + + + static FT_Pointer + psnames_get_service( FT_Module module, + const char* service_id ) + { + /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */ +#ifdef FT_CONFIG_OPTION_PIC + FT_Library library; + + + if ( !module ) + return NULL; + library = module->library; + if ( !library ) + return NULL; +#else + FT_UNUSED( module ); +#endif + + return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id ); + } + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + +#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES_SERVICE( a ) NULL +#else +#define PUT_PS_NAMES_SERVICE( a ) a +#endif + + FT_DEFINE_MODULE( + psnames_module_class, + + 0, /* this is not a font driver, nor a renderer */ + sizeof ( FT_ModuleRec ), + + "psnames", /* driver name */ + 0x10000L, /* driver version */ + 0x20000L, /* driver requires FreeType 2 or above */ + + PUT_PS_NAMES_SERVICE( + (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */ + (FT_Module_Constructor)NULL, + (FT_Module_Destructor) NULL, + (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) ) + + +/* END */ diff --git a/drivers/freetype/src/psnames/psmodule.h b/drivers/freetype/src/psnames/psmodule.h new file mode 100644 index 0000000000..28fa14807c --- /dev/null +++ b/drivers/freetype/src/psnames/psmodule.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* psmodule.h */ +/* */ +/* High-level PSNames module interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __PSMODULE_H__ +#define __PSMODULE_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_MODULE( psnames_module_class ) + + +FT_END_HEADER + +#endif /* __PSMODULE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psnames/psnamerr.h b/drivers/freetype/src/psnames/psnamerr.h new file mode 100644 index 0000000000..acda7f967e --- /dev/null +++ b/drivers/freetype/src/psnames/psnamerr.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* psnamerr.h */ +/* */ +/* PS names module error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PS names module error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSNAMERR_H__ +#define __PSNAMERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX PSnames_Err_ +#define FT_ERR_BASE FT_Mod_Err_PSnames + +#include FT_ERRORS_H + +#endif /* __PSNAMERR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psnames/psnames.c b/drivers/freetype/src/psnames/psnames.c new file mode 100644 index 0000000000..1ede225dc9 --- /dev/null +++ b/drivers/freetype/src/psnames/psnames.c @@ -0,0 +1,26 @@ +/***************************************************************************/ +/* */ +/* psnames.c */ +/* */ +/* FreeType PSNames module component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "pspic.c" +#include "psmodule.c" + + +/* END */ diff --git a/drivers/freetype/src/psnames/pspic.c b/drivers/freetype/src/psnames/pspic.c new file mode 100644 index 0000000000..3820f65a74 --- /dev/null +++ b/drivers/freetype/src/psnames/pspic.c @@ -0,0 +1,97 @@ +/***************************************************************************/ +/* */ +/* pspic.c */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009, 2010, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pspic.h" +#include "psnamerr.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from psmodule.c */ + FT_Error + FT_Create_Class_pscmaps_services( FT_Library library, + FT_ServiceDescRec** output_class ); + void + FT_Destroy_Class_pscmaps_services( FT_Library library, + FT_ServiceDescRec* clazz ); + + void + FT_Init_Class_pscmaps_interface( FT_Library library, + FT_Service_PsCMapsRec* clazz ); + + + void + psnames_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->psnames ) + { + PSModulePIC* container = (PSModulePIC*)pic_container->psnames; + + + if ( container->pscmaps_services ) + FT_Destroy_Class_pscmaps_services( library, + container->pscmaps_services ); + container->pscmaps_services = NULL; + FT_FREE( container ); + pic_container->psnames = NULL; + } + } + + + FT_Error + psnames_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSModulePIC* container = NULL; + FT_Memory memory = library->memory; + + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->psnames = container; + + /* initialize pointer table - */ + /* this is how the module usually expects this data */ + error = FT_Create_Class_pscmaps_services( + library, &container->pscmaps_services ); + if ( error ) + goto Exit; + FT_Init_Class_pscmaps_interface( library, + &container->pscmaps_interface ); + + Exit: + if ( error ) + psnames_module_class_pic_free( library ); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/psnames/pspic.h b/drivers/freetype/src/psnames/pspic.h new file mode 100644 index 0000000000..6ff002c603 --- /dev/null +++ b/drivers/freetype/src/psnames/pspic.h @@ -0,0 +1,66 @@ +/***************************************************************************/ +/* */ +/* pspic.h */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009, 2012 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __PSPIC_H__ +#define __PSPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define PSCMAPS_SERVICES_GET pscmaps_services +#define PSCMAPS_INTERFACE_GET pscmaps_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + typedef struct PSModulePIC_ + { + FT_ServiceDescRec* pscmaps_services; + FT_Service_PsCMapsRec pscmaps_interface; + + } PSModulePIC; + + +#define GET_PIC( lib ) \ + ( (PSModulePIC*)((lib)->pic_container.psnames) ) +#define PSCMAPS_SERVICES_GET ( GET_PIC( library )->pscmaps_services ) +#define PSCMAPS_INTERFACE_GET ( GET_PIC( library )->pscmaps_interface ) + + + /* see pspic.c for the implementation */ + void + psnames_module_class_pic_free( FT_Library library ); + + FT_Error + psnames_module_class_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/psnames/pstables.h b/drivers/freetype/src/psnames/pstables.h new file mode 100644 index 0000000000..0a6637f985 --- /dev/null +++ b/drivers/freetype/src/psnames/pstables.h @@ -0,0 +1,4170 @@ +/***************************************************************************/ +/* */ +/* pstables.h */ +/* */ +/* PostScript glyph names. */ +/* */ +/* Copyright 2005, 2008, 2011 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. */ +/* */ +/***************************************************************************/ + + + /* This file has been generated automatically -- do not edit! */ + + + static const char ft_standard_glyph_names[3696] = + { + '.','n','u','l','l', 0, + 'n','o','n','m','a','r','k','i','n','g','r','e','t','u','r','n', 0, + 'n','o','t','e','q','u','a','l', 0, + 'i','n','f','i','n','i','t','y', 0, + 'l','e','s','s','e','q','u','a','l', 0, + 'g','r','e','a','t','e','r','e','q','u','a','l', 0, + 'p','a','r','t','i','a','l','d','i','f','f', 0, + 's','u','m','m','a','t','i','o','n', 0, + 'p','r','o','d','u','c','t', 0, + 'p','i', 0, + 'i','n','t','e','g','r','a','l', 0, + 'O','m','e','g','a', 0, + 'r','a','d','i','c','a','l', 0, + 'a','p','p','r','o','x','e','q','u','a','l', 0, + 'D','e','l','t','a', 0, + 'n','o','n','b','r','e','a','k','i','n','g','s','p','a','c','e', 0, + 'l','o','z','e','n','g','e', 0, + 'a','p','p','l','e', 0, + 'f','r','a','n','c', 0, + 'G','b','r','e','v','e', 0, + 'g','b','r','e','v','e', 0, + 'I','d','o','t','a','c','c','e','n','t', 0, + 'S','c','e','d','i','l','l','a', 0, + 's','c','e','d','i','l','l','a', 0, + 'C','a','c','u','t','e', 0, + 'c','a','c','u','t','e', 0, + 'C','c','a','r','o','n', 0, + 'c','c','a','r','o','n', 0, + 'd','c','r','o','a','t', 0, + '.','n','o','t','d','e','f', 0, + 's','p','a','c','e', 0, + 'e','x','c','l','a','m', 0, + 'q','u','o','t','e','d','b','l', 0, + 'n','u','m','b','e','r','s','i','g','n', 0, + 'd','o','l','l','a','r', 0, + 'p','e','r','c','e','n','t', 0, + 'a','m','p','e','r','s','a','n','d', 0, + 'q','u','o','t','e','r','i','g','h','t', 0, + 'p','a','r','e','n','l','e','f','t', 0, + 'p','a','r','e','n','r','i','g','h','t', 0, + 'a','s','t','e','r','i','s','k', 0, + 'p','l','u','s', 0, + 'c','o','m','m','a', 0, + 'h','y','p','h','e','n', 0, + 'p','e','r','i','o','d', 0, + 's','l','a','s','h', 0, + 'z','e','r','o', 0, + 'o','n','e', 0, + 't','w','o', 0, + 't','h','r','e','e', 0, + 'f','o','u','r', 0, + 'f','i','v','e', 0, + 's','i','x', 0, + 's','e','v','e','n', 0, + 'e','i','g','h','t', 0, + 'n','i','n','e', 0, + 'c','o','l','o','n', 0, + 's','e','m','i','c','o','l','o','n', 0, + 'l','e','s','s', 0, + 'e','q','u','a','l', 0, + 'g','r','e','a','t','e','r', 0, + 'q','u','e','s','t','i','o','n', 0, + 'a','t', 0, + 'A', 0, + 'B', 0, + 'C', 0, + 'D', 0, + 'E', 0, + 'F', 0, + 'G', 0, + 'H', 0, + 'I', 0, + 'J', 0, + 'K', 0, + 'L', 0, + 'M', 0, + 'N', 0, + 'O', 0, + 'P', 0, + 'Q', 0, + 'R', 0, + 'S', 0, + 'T', 0, + 'U', 0, + 'V', 0, + 'W', 0, + 'X', 0, + 'Y', 0, + 'Z', 0, + 'b','r','a','c','k','e','t','l','e','f','t', 0, + 'b','a','c','k','s','l','a','s','h', 0, + 'b','r','a','c','k','e','t','r','i','g','h','t', 0, + 'a','s','c','i','i','c','i','r','c','u','m', 0, + 'u','n','d','e','r','s','c','o','r','e', 0, + 'q','u','o','t','e','l','e','f','t', 0, + 'a', 0, + 'b', 0, + 'c', 0, + 'd', 0, + 'e', 0, + 'f', 0, + 'g', 0, + 'h', 0, + 'i', 0, + 'j', 0, + 'k', 0, + 'l', 0, + 'm', 0, + 'n', 0, + 'o', 0, + 'p', 0, + 'q', 0, + 'r', 0, + 's', 0, + 't', 0, + 'u', 0, + 'v', 0, + 'w', 0, + 'x', 0, + 'y', 0, + 'z', 0, + 'b','r','a','c','e','l','e','f','t', 0, + 'b','a','r', 0, + 'b','r','a','c','e','r','i','g','h','t', 0, + 'a','s','c','i','i','t','i','l','d','e', 0, + 'e','x','c','l','a','m','d','o','w','n', 0, + 'c','e','n','t', 0, + 's','t','e','r','l','i','n','g', 0, + 'f','r','a','c','t','i','o','n', 0, + 'y','e','n', 0, + 'f','l','o','r','i','n', 0, + 's','e','c','t','i','o','n', 0, + 'c','u','r','r','e','n','c','y', 0, + 'q','u','o','t','e','s','i','n','g','l','e', 0, + 'q','u','o','t','e','d','b','l','l','e','f','t', 0, + 'g','u','i','l','l','e','m','o','t','l','e','f','t', 0, + 'g','u','i','l','s','i','n','g','l','l','e','f','t', 0, + 'g','u','i','l','s','i','n','g','l','r','i','g','h','t', 0, + 'f','i', 0, + 'f','l', 0, + 'e','n','d','a','s','h', 0, + 'd','a','g','g','e','r', 0, + 'd','a','g','g','e','r','d','b','l', 0, + 'p','e','r','i','o','d','c','e','n','t','e','r','e','d', 0, + 'p','a','r','a','g','r','a','p','h', 0, + 'b','u','l','l','e','t', 0, + 'q','u','o','t','e','s','i','n','g','l','b','a','s','e', 0, + 'q','u','o','t','e','d','b','l','b','a','s','e', 0, + 'q','u','o','t','e','d','b','l','r','i','g','h','t', 0, + 'g','u','i','l','l','e','m','o','t','r','i','g','h','t', 0, + 'e','l','l','i','p','s','i','s', 0, + 'p','e','r','t','h','o','u','s','a','n','d', 0, + 'q','u','e','s','t','i','o','n','d','o','w','n', 0, + 'g','r','a','v','e', 0, + 'a','c','u','t','e', 0, + 'c','i','r','c','u','m','f','l','e','x', 0, + 't','i','l','d','e', 0, + 'm','a','c','r','o','n', 0, + 'b','r','e','v','e', 0, + 'd','o','t','a','c','c','e','n','t', 0, + 'd','i','e','r','e','s','i','s', 0, + 'r','i','n','g', 0, + 'c','e','d','i','l','l','a', 0, + 'h','u','n','g','a','r','u','m','l','a','u','t', 0, + 'o','g','o','n','e','k', 0, + 'c','a','r','o','n', 0, + 'e','m','d','a','s','h', 0, + 'A','E', 0, + 'o','r','d','f','e','m','i','n','i','n','e', 0, + 'L','s','l','a','s','h', 0, + 'O','s','l','a','s','h', 0, + 'O','E', 0, + 'o','r','d','m','a','s','c','u','l','i','n','e', 0, + 'a','e', 0, + 'd','o','t','l','e','s','s','i', 0, + 'l','s','l','a','s','h', 0, + 'o','s','l','a','s','h', 0, + 'o','e', 0, + 'g','e','r','m','a','n','d','b','l','s', 0, + 'o','n','e','s','u','p','e','r','i','o','r', 0, + 'l','o','g','i','c','a','l','n','o','t', 0, + 'm','u', 0, + 't','r','a','d','e','m','a','r','k', 0, + 'E','t','h', 0, + 'o','n','e','h','a','l','f', 0, + 'p','l','u','s','m','i','n','u','s', 0, + 'T','h','o','r','n', 0, + 'o','n','e','q','u','a','r','t','e','r', 0, + 'd','i','v','i','d','e', 0, + 'b','r','o','k','e','n','b','a','r', 0, + 'd','e','g','r','e','e', 0, + 't','h','o','r','n', 0, + 't','h','r','e','e','q','u','a','r','t','e','r','s', 0, + 't','w','o','s','u','p','e','r','i','o','r', 0, + 'r','e','g','i','s','t','e','r','e','d', 0, + 'm','i','n','u','s', 0, + 'e','t','h', 0, + 'm','u','l','t','i','p','l','y', 0, + 't','h','r','e','e','s','u','p','e','r','i','o','r', 0, + 'c','o','p','y','r','i','g','h','t', 0, + 'A','a','c','u','t','e', 0, + 'A','c','i','r','c','u','m','f','l','e','x', 0, + 'A','d','i','e','r','e','s','i','s', 0, + 'A','g','r','a','v','e', 0, + 'A','r','i','n','g', 0, + 'A','t','i','l','d','e', 0, + 'C','c','e','d','i','l','l','a', 0, + 'E','a','c','u','t','e', 0, + 'E','c','i','r','c','u','m','f','l','e','x', 0, + 'E','d','i','e','r','e','s','i','s', 0, + 'E','g','r','a','v','e', 0, + 'I','a','c','u','t','e', 0, + 'I','c','i','r','c','u','m','f','l','e','x', 0, + 'I','d','i','e','r','e','s','i','s', 0, + 'I','g','r','a','v','e', 0, + 'N','t','i','l','d','e', 0, + 'O','a','c','u','t','e', 0, + 'O','c','i','r','c','u','m','f','l','e','x', 0, + 'O','d','i','e','r','e','s','i','s', 0, + 'O','g','r','a','v','e', 0, + 'O','t','i','l','d','e', 0, + 'S','c','a','r','o','n', 0, + 'U','a','c','u','t','e', 0, + 'U','c','i','r','c','u','m','f','l','e','x', 0, + 'U','d','i','e','r','e','s','i','s', 0, + 'U','g','r','a','v','e', 0, + 'Y','a','c','u','t','e', 0, + 'Y','d','i','e','r','e','s','i','s', 0, + 'Z','c','a','r','o','n', 0, + 'a','a','c','u','t','e', 0, + 'a','c','i','r','c','u','m','f','l','e','x', 0, + 'a','d','i','e','r','e','s','i','s', 0, + 'a','g','r','a','v','e', 0, + 'a','r','i','n','g', 0, + 'a','t','i','l','d','e', 0, + 'c','c','e','d','i','l','l','a', 0, + 'e','a','c','u','t','e', 0, + 'e','c','i','r','c','u','m','f','l','e','x', 0, + 'e','d','i','e','r','e','s','i','s', 0, + 'e','g','r','a','v','e', 0, + 'i','a','c','u','t','e', 0, + 'i','c','i','r','c','u','m','f','l','e','x', 0, + 'i','d','i','e','r','e','s','i','s', 0, + 'i','g','r','a','v','e', 0, + 'n','t','i','l','d','e', 0, + 'o','a','c','u','t','e', 0, + 'o','c','i','r','c','u','m','f','l','e','x', 0, + 'o','d','i','e','r','e','s','i','s', 0, + 'o','g','r','a','v','e', 0, + 'o','t','i','l','d','e', 0, + 's','c','a','r','o','n', 0, + 'u','a','c','u','t','e', 0, + 'u','c','i','r','c','u','m','f','l','e','x', 0, + 'u','d','i','e','r','e','s','i','s', 0, + 'u','g','r','a','v','e', 0, + 'y','a','c','u','t','e', 0, + 'y','d','i','e','r','e','s','i','s', 0, + 'z','c','a','r','o','n', 0, + 'e','x','c','l','a','m','s','m','a','l','l', 0, + 'H','u','n','g','a','r','u','m','l','a','u','t','s','m','a','l','l', 0, + 'd','o','l','l','a','r','o','l','d','s','t','y','l','e', 0, + 'd','o','l','l','a','r','s','u','p','e','r','i','o','r', 0, + 'a','m','p','e','r','s','a','n','d','s','m','a','l','l', 0, + 'A','c','u','t','e','s','m','a','l','l', 0, + 'p','a','r','e','n','l','e','f','t','s','u','p','e','r','i','o','r', 0, + 'p','a','r','e','n','r','i','g','h','t','s','u','p','e','r','i','o','r', 0, + 't','w','o','d','o','t','e','n','l','e','a','d','e','r', 0, + 'o','n','e','d','o','t','e','n','l','e','a','d','e','r', 0, + 'z','e','r','o','o','l','d','s','t','y','l','e', 0, + 'o','n','e','o','l','d','s','t','y','l','e', 0, + 't','w','o','o','l','d','s','t','y','l','e', 0, + 't','h','r','e','e','o','l','d','s','t','y','l','e', 0, + 'f','o','u','r','o','l','d','s','t','y','l','e', 0, + 'f','i','v','e','o','l','d','s','t','y','l','e', 0, + 's','i','x','o','l','d','s','t','y','l','e', 0, + 's','e','v','e','n','o','l','d','s','t','y','l','e', 0, + 'e','i','g','h','t','o','l','d','s','t','y','l','e', 0, + 'n','i','n','e','o','l','d','s','t','y','l','e', 0, + 'c','o','m','m','a','s','u','p','e','r','i','o','r', 0, + 't','h','r','e','e','q','u','a','r','t','e','r','s','e','m','d','a','s','h', 0, + 'p','e','r','i','o','d','s','u','p','e','r','i','o','r', 0, + 'q','u','e','s','t','i','o','n','s','m','a','l','l', 0, + 'a','s','u','p','e','r','i','o','r', 0, + 'b','s','u','p','e','r','i','o','r', 0, + 'c','e','n','t','s','u','p','e','r','i','o','r', 0, + 'd','s','u','p','e','r','i','o','r', 0, + 'e','s','u','p','e','r','i','o','r', 0, + 'i','s','u','p','e','r','i','o','r', 0, + 'l','s','u','p','e','r','i','o','r', 0, + 'm','s','u','p','e','r','i','o','r', 0, + 'n','s','u','p','e','r','i','o','r', 0, + 'o','s','u','p','e','r','i','o','r', 0, + 'r','s','u','p','e','r','i','o','r', 0, + 's','s','u','p','e','r','i','o','r', 0, + 't','s','u','p','e','r','i','o','r', 0, + 'f','f', 0, + 'f','f','i', 0, + 'f','f','l', 0, + 'p','a','r','e','n','l','e','f','t','i','n','f','e','r','i','o','r', 0, + 'p','a','r','e','n','r','i','g','h','t','i','n','f','e','r','i','o','r', 0, + 'C','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'h','y','p','h','e','n','s','u','p','e','r','i','o','r', 0, + 'G','r','a','v','e','s','m','a','l','l', 0, + 'A','s','m','a','l','l', 0, + 'B','s','m','a','l','l', 0, + 'C','s','m','a','l','l', 0, + 'D','s','m','a','l','l', 0, + 'E','s','m','a','l','l', 0, + 'F','s','m','a','l','l', 0, + 'G','s','m','a','l','l', 0, + 'H','s','m','a','l','l', 0, + 'I','s','m','a','l','l', 0, + 'J','s','m','a','l','l', 0, + 'K','s','m','a','l','l', 0, + 'L','s','m','a','l','l', 0, + 'M','s','m','a','l','l', 0, + 'N','s','m','a','l','l', 0, + 'O','s','m','a','l','l', 0, + 'P','s','m','a','l','l', 0, + 'Q','s','m','a','l','l', 0, + 'R','s','m','a','l','l', 0, + 'S','s','m','a','l','l', 0, + 'T','s','m','a','l','l', 0, + 'U','s','m','a','l','l', 0, + 'V','s','m','a','l','l', 0, + 'W','s','m','a','l','l', 0, + 'X','s','m','a','l','l', 0, + 'Y','s','m','a','l','l', 0, + 'Z','s','m','a','l','l', 0, + 'c','o','l','o','n','m','o','n','e','t','a','r','y', 0, + 'o','n','e','f','i','t','t','e','d', 0, + 'r','u','p','i','a','h', 0, + 'T','i','l','d','e','s','m','a','l','l', 0, + 'e','x','c','l','a','m','d','o','w','n','s','m','a','l','l', 0, + 'c','e','n','t','o','l','d','s','t','y','l','e', 0, + 'L','s','l','a','s','h','s','m','a','l','l', 0, + 'S','c','a','r','o','n','s','m','a','l','l', 0, + 'Z','c','a','r','o','n','s','m','a','l','l', 0, + 'D','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'B','r','e','v','e','s','m','a','l','l', 0, + 'C','a','r','o','n','s','m','a','l','l', 0, + 'D','o','t','a','c','c','e','n','t','s','m','a','l','l', 0, + 'M','a','c','r','o','n','s','m','a','l','l', 0, + 'f','i','g','u','r','e','d','a','s','h', 0, + 'h','y','p','h','e','n','i','n','f','e','r','i','o','r', 0, + 'O','g','o','n','e','k','s','m','a','l','l', 0, + 'R','i','n','g','s','m','a','l','l', 0, + 'C','e','d','i','l','l','a','s','m','a','l','l', 0, + 'q','u','e','s','t','i','o','n','d','o','w','n','s','m','a','l','l', 0, + 'o','n','e','e','i','g','h','t','h', 0, + 't','h','r','e','e','e','i','g','h','t','h','s', 0, + 'f','i','v','e','e','i','g','h','t','h','s', 0, + 's','e','v','e','n','e','i','g','h','t','h','s', 0, + 'o','n','e','t','h','i','r','d', 0, + 't','w','o','t','h','i','r','d','s', 0, + 'z','e','r','o','s','u','p','e','r','i','o','r', 0, + 'f','o','u','r','s','u','p','e','r','i','o','r', 0, + 'f','i','v','e','s','u','p','e','r','i','o','r', 0, + 's','i','x','s','u','p','e','r','i','o','r', 0, + 's','e','v','e','n','s','u','p','e','r','i','o','r', 0, + 'e','i','g','h','t','s','u','p','e','r','i','o','r', 0, + 'n','i','n','e','s','u','p','e','r','i','o','r', 0, + 'z','e','r','o','i','n','f','e','r','i','o','r', 0, + 'o','n','e','i','n','f','e','r','i','o','r', 0, + 't','w','o','i','n','f','e','r','i','o','r', 0, + 't','h','r','e','e','i','n','f','e','r','i','o','r', 0, + 'f','o','u','r','i','n','f','e','r','i','o','r', 0, + 'f','i','v','e','i','n','f','e','r','i','o','r', 0, + 's','i','x','i','n','f','e','r','i','o','r', 0, + 's','e','v','e','n','i','n','f','e','r','i','o','r', 0, + 'e','i','g','h','t','i','n','f','e','r','i','o','r', 0, + 'n','i','n','e','i','n','f','e','r','i','o','r', 0, + 'c','e','n','t','i','n','f','e','r','i','o','r', 0, + 'd','o','l','l','a','r','i','n','f','e','r','i','o','r', 0, + 'p','e','r','i','o','d','i','n','f','e','r','i','o','r', 0, + 'c','o','m','m','a','i','n','f','e','r','i','o','r', 0, + 'A','g','r','a','v','e','s','m','a','l','l', 0, + 'A','a','c','u','t','e','s','m','a','l','l', 0, + 'A','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'A','t','i','l','d','e','s','m','a','l','l', 0, + 'A','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'A','r','i','n','g','s','m','a','l','l', 0, + 'A','E','s','m','a','l','l', 0, + 'C','c','e','d','i','l','l','a','s','m','a','l','l', 0, + 'E','g','r','a','v','e','s','m','a','l','l', 0, + 'E','a','c','u','t','e','s','m','a','l','l', 0, + 'E','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'E','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'I','g','r','a','v','e','s','m','a','l','l', 0, + 'I','a','c','u','t','e','s','m','a','l','l', 0, + 'I','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'I','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'E','t','h','s','m','a','l','l', 0, + 'N','t','i','l','d','e','s','m','a','l','l', 0, + 'O','g','r','a','v','e','s','m','a','l','l', 0, + 'O','a','c','u','t','e','s','m','a','l','l', 0, + 'O','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'O','t','i','l','d','e','s','m','a','l','l', 0, + 'O','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'O','E','s','m','a','l','l', 0, + 'O','s','l','a','s','h','s','m','a','l','l', 0, + 'U','g','r','a','v','e','s','m','a','l','l', 0, + 'U','a','c','u','t','e','s','m','a','l','l', 0, + 'U','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'U','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'Y','a','c','u','t','e','s','m','a','l','l', 0, + 'T','h','o','r','n','s','m','a','l','l', 0, + 'Y','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + '0','0','1','.','0','0','0', 0, + '0','0','1','.','0','0','1', 0, + '0','0','1','.','0','0','2', 0, + '0','0','1','.','0','0','3', 0, + 'B','l','a','c','k', 0, + 'B','o','l','d', 0, + 'B','o','o','k', 0, + 'L','i','g','h','t', 0, + 'M','e','d','i','u','m', 0, + 'R','e','g','u','l','a','r', 0, + 'R','o','m','a','n', 0, + 'S','e','m','i','b','o','l','d', 0, + }; + + +#define FT_NUM_MAC_NAMES 258 + + /* Values are offsets into the `ft_standard_glyph_names' table */ + + static const short ft_mac_names[FT_NUM_MAC_NAMES] = + { + 253, 0, 6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351, + 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, + 436, 441, 447, 457, 462, 468, 476, 485, 488, 490, 492, 494, 496, 498, + 500, 502, 504, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, + 528, 530, 532, 534, 536, 538, 540, 552, 562, 575, 587, 979, 608, 610, + 612, 614, 616, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, + 640, 642, 644, 646, 648, 650, 652, 654, 656, 658, 660, 670, 674, 685, + 1375,1392,1405,1414,1486,1512,1562,1603,1632,1610,1622,1645,1639,1652, + 1661,1690,1668,1680,1697,1726,1704,1716,1733,1740,1769,1747,1759,1776, + 1790,1819,1797,1809, 839,1263, 707, 712, 741, 881, 871,1160,1302,1346, + 1197, 985,1031, 23,1086,1108, 32,1219, 41, 51, 730,1194, 64, 76, + 86, 94, 97,1089,1118, 106,1131,1150, 966, 696,1183, 112, 734, 120, + 132, 783, 930, 945, 138,1385,1398,1529,1115,1157, 832,1079, 770, 916, + 598, 319,1246, 155,1833,1586, 721, 749, 797, 811, 826, 829, 846, 856, + 888, 903, 954,1363,1421,1356,1433,1443,1450,1457,1469,1479,1493,1500, + 163,1522,1543,1550,1572,1134, 991,1002,1008,1015,1021,1040,1045,1053, + 1066,1073,1101,1143,1536,1783,1596,1843,1253,1207,1319,1579,1826,1229, + 1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200, + 209, 218, 225, 232, 239, 246 + }; + + +#define FT_NUM_SID_NAMES 391 + + /* Values are offsets into the `ft_standard_glyph_names' table */ + + static const short ft_sid_names[FT_NUM_SID_NAMES] = + { + 253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365, + 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, 436, 441, + 447, 457, 462, 468, 476, 485, 488, 490, 492, 494, 496, 498, 500, 502, + 504, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530, + 532, 534, 536, 538, 540, 552, 562, 575, 587, 598, 608, 610, 612, 614, + 616, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, 640, 642, + 644, 646, 648, 650, 652, 654, 656, 658, 660, 670, 674, 685, 696, 707, + 712, 721, 730, 734, 741, 749, 758, 770, 783, 797, 811, 826, 829, 832, + 839, 846, 856, 871, 881, 888, 903, 916, 930, 945, 954, 966, 979, 985, + 991,1002,1008,1015,1021,1031,1040,1045,1053,1066,1073,1079,1086,1089, + 1101,1108,1115,1118,1131,1134,1143,1150,1157,1160,1171,1183,1194,1197, + 1207,1211,1219,1229,1235,1246,1253,1263,1270,1276,1290,1302,1313,1319, + 1323,1332,1346,1356,1363,1375,1385,1392,1398,1405,1414,1421,1433,1443, + 1450,1457,1469,1479,1486,1493,1500,1512,1522,1529,1536,1543,1550,1562, + 1572,1579,1586,1596,1603,1610,1622,1632,1639,1645,1652,1661,1668,1680, + 1690,1697,1704,1716,1726,1733,1740,1747,1759,1769,1776,1783,1790,1797, + 1809,1819,1826,1833,1843,1850,1862,1880,1895,1910,1925,1936,1954,1973, + 1988,2003,2016,2028,2040,2054,2067,2080,2092,2106,2120,2133,2147,2167, + 2182,2196,2206,2216,2229,2239,2249,2259,2269,2279,2289,2299,2309,2319, + 2329,2332,2336,2340,2358,2377,2393,2408,2419,2426,2433,2440,2447,2454, + 2461,2468,2475,2482,2489,2496,2503,2510,2517,2524,2531,2538,2545,2552, + 2559,2566,2573,2580,2587,2594,2601,2615,2625,2632,2643,2659,2672,2684, + 2696,2708,2722,2733,2744,2759,2771,2782,2797,2809,2819,2832,2850,2860, + 2873,2885,2898,2907,2917,2930,2943,2956,2968,2982,2996,3009,3022,3034, + 3046,3060,3073,3086,3098,3112,3126,3139,3152,3167,3182,3196,3208,3220, + 3237,3249,3264,3275,3283,3297,3309,3321,3338,3353,3365,3377,3394,3409, + 3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586, + 3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687 + }; + + + /* the following are indices into the SID name table */ + static const unsigned short t1_standard_encoding[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110, + 0,111,112,113,114, 0,115,116,117,118,119,120,121,122, 0,123, + 0,124,125,126,127,128,129,130,131, 0,132,133, 0,134,135,136, + 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,138, 0,139, 0, 0, 0, 0,140,141,142,143, 0, 0, 0, 0, + 0,144, 0, 0, 0,145, 0, 0,146,147,148,149, 0, 0, 0, 0 + }; + + + /* the following are indices into the SID name table */ + static const unsigned short t1_expert_encoding[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1,229,230, 0,231,232,233,234,235,236,237,238, 13, 14, 15, 99, + 239,240,241,242,243,244,245,246,247,248, 27, 28,249,250,251,252, + 0,253,254,255,256,257, 0, 0, 0,258, 0, 0,259,260,261,262, + 0, 0,263,264,265, 0,266,109,110,267,268,269, 0,270,271,272, + 273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288, + 289,290,291,292,293,294,295,296,297,298,299,300,301,302,303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,304,305,306, 0, 0,307,308,309,310,311, 0,312, 0, 0,313, + 0, 0,314,315, 0, 0,316,317,318, 0, 0, 0,158,155,163,319, + 320,321,322,323,324,325, 0, 0,326,150,164,169,327,328,329,330, + 331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346, + 347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362, + 363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378 + }; + + + /* + * This table is a compressed version of the Adobe Glyph List (AGL), + * optimized for efficient searching. It has been generated by the + * `glnames.py' python script located in the `src/tools' directory. + * + * The lookup function to get the Unicode value for a given string + * is defined below the table. + */ + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + static const unsigned char ft_adobe_glyph_list[55997L] = + { + 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, + 11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88, + 22,110, 23, 32, 23, 71, 24, 77, 27,156, 29, 73, 31,247, 32,107, + 32,222, 33, 55, 34,154, 35,218, 58, 10, 64,122, 72,188, 80,109, + 88,104, 93, 61, 98,168,106, 91,114,111,115,237,122,180,127,255, + 135,164,143,132,149,213,158,108,161,115,168,175,183,147,197,199, + 202, 25,204,166,208,209,209, 81,215, 26, 65,143, 0, 65, 0,140, + 0,175, 0,193, 1, 15, 1,147, 1,233, 1,251, 2, 7, 2, 40, + 2, 57, 2, 82, 2, 91, 2,128, 2,136, 2,154, 69,131, 0,198, + 0,150, 0,158, 0,167,225,227,245,244,101,128, 1,252,237,225, + 227,242,239,110,128, 1,226,243,237,225,236,108,128,247,230,225, + 227,245,244,101,129, 0,193, 0,185,243,237,225,236,108,128,247, + 225,226,242,229,246,101,134, 1, 2, 0,213, 0,221, 0,232, 0, + 243, 0,251, 1, 7,225,227,245,244,101,128, 30,174,227,249,242, + 233,236,236,233, 99,128, 4,208,228,239,244,226,229,236,239,119, + 128, 30,182,231,242,225,246,101,128, 30,176,232,239,239,235,225, + 226,239,246,101,128, 30,178,244,233,236,228,101,128, 30,180, 99, + 4, 1, 25, 1, 32, 1,121, 1,137,225,242,239,110,128, 1,205, + 233,242, 99, 2, 1, 40, 1, 45,236,101,128, 36,182,245,237,230, + 236,229,120,134, 0,194, 1, 66, 1, 74, 1, 85, 1, 93, 1,105, + 1,113,225,227,245,244,101,128, 30,164,228,239,244,226,229,236, + 239,119,128, 30,172,231,242,225,246,101,128, 30,166,232,239,239, + 235,225,226,239,246,101,128, 30,168,243,237,225,236,108,128,247, + 226,244,233,236,228,101,128, 30,170,245,244,101,129,246,201, 1, + 129,243,237,225,236,108,128,247,180,249,242,233,236,236,233, 99, + 128, 4, 16,100, 3, 1,155, 1,165, 1,209,226,236,231,242,225, + 246,101,128, 2, 0,233,229,242,229,243,233,115,131, 0,196, 1, + 181, 1,192, 1,201,227,249,242,233,236,236,233, 99,128, 4,210, + 237,225,227,242,239,110,128, 1,222,243,237,225,236,108,128,247, + 228,239,116, 2, 1,216, 1,224,226,229,236,239,119,128, 30,160, + 237,225,227,242,239,110,128, 1,224,231,242,225,246,101,129, 0, + 192, 1,243,243,237,225,236,108,128,247,224,232,239,239,235,225, + 226,239,246,101,128, 30,162,105, 2, 2, 13, 2, 25,229,227,249, + 242,233,236,236,233, 99,128, 4,212,238,246,229,242,244,229,228, + 226,242,229,246,101,128, 2, 2,236,240,232, 97,129, 3,145, 2, + 49,244,239,238,239,115,128, 3,134,109, 2, 2, 63, 2, 71,225, + 227,242,239,110,128, 1, 0,239,238,239,243,240,225,227,101,128, + 255, 33,239,231,239,238,229,107,128, 1, 4,242,233,238,103,131, + 0,197, 2,104, 2,112, 2,120,225,227,245,244,101,128, 1,250, + 226,229,236,239,119,128, 30, 0,243,237,225,236,108,128,247,229, + 243,237,225,236,108,128,247, 97,244,233,236,228,101,129, 0,195, + 2,146,243,237,225,236,108,128,247,227,249,226,225,242,237,229, + 238,233,225,110,128, 5, 49, 66,137, 0, 66, 2,189, 2,198, 2, + 223, 3, 3, 3, 10, 3, 22, 3, 34, 3, 46, 3, 54,227,233,242, + 227,236,101,128, 36,183,228,239,116, 2, 2,206, 2,215,225,227, + 227,229,238,116,128, 30, 2,226,229,236,239,119,128, 30, 4,101, + 3, 2,231, 2,242, 2,254,227,249,242,233,236,236,233, 99,128, + 4, 17,238,225,242,237,229,238,233,225,110,128, 5, 50,244, 97, + 128, 3,146,232,239,239,107,128, 1,129,236,233,238,229,226,229, + 236,239,119,128, 30, 6,237,239,238,239,243,240,225,227,101,128, + 255, 34,242,229,246,229,243,237,225,236,108,128,246,244,243,237, + 225,236,108,128,247, 98,244,239,240,226,225,114,128, 1,130, 67, + 137, 0, 67, 3, 85, 3,127, 3,193, 3,210, 3,224, 4,171, 4, + 188, 4,200, 4,212, 97, 3, 3, 93, 3,104, 3,111,225,242,237, + 229,238,233,225,110,128, 5, 62,227,245,244,101,128, 1, 6,242, + 239,110,129,246,202, 3,119,243,237,225,236,108,128,246,245, 99, + 3, 3,135, 3,142, 3,171,225,242,239,110,128, 1, 12,229,228, + 233,236,236, 97,130, 0,199, 3,155, 3,163,225,227,245,244,101, + 128, 30, 8,243,237,225,236,108,128,247,231,233,242, 99, 2, 3, + 179, 3,184,236,101,128, 36,184,245,237,230,236,229,120,128, 1, + 8,228,239,116,129, 1, 10, 3,201,225,227,227,229,238,116,128, + 1, 10,229,228,233,236,236,225,243,237,225,236,108,128,247,184, + 104, 4, 3,234, 3,246, 4,161, 4,165,225,225,242,237,229,238, + 233,225,110,128, 5, 73,101, 6, 4, 4, 4, 24, 4, 35, 4,103, + 4,115, 4,136,225,226,235,232,225,243,233,225,238,227,249,242, + 233,236,236,233, 99,128, 4,188,227,249,242,233,236,236,233, 99, + 128, 4, 39,100, 2, 4, 41, 4, 85,229,243,227,229,238,228,229, + 114, 2, 4, 54, 4, 74,225,226,235,232,225,243,233,225,238,227, + 249,242,233,236,236,233, 99,128, 4,190,227,249,242,233,236,236, + 233, 99,128, 4,182,233,229,242,229,243,233,243,227,249,242,233, + 236,236,233, 99,128, 4,244,232,225,242,237,229,238,233,225,110, + 128, 5, 67,235,232,225,235,225,243,243,233,225,238,227,249,242, + 233,236,236,233, 99,128, 4,203,246,229,242,244,233,227,225,236, + 243,244,242,239,235,229,227,249,242,233,236,236,233, 99,128, 4, + 184,105,128, 3,167,239,239,107,128, 1,135,233,242,227,245,237, + 230,236,229,248,243,237,225,236,108,128,246,246,237,239,238,239, + 243,240,225,227,101,128,255, 35,239,225,242,237,229,238,233,225, + 110,128, 5, 81,243,237,225,236,108,128,247, 99, 68,142, 0, 68, + 4,252, 5, 10, 5, 36, 5, 96, 5,121, 5,166, 5,173, 5,231, + 5,244, 6, 0, 6, 12, 6, 28, 6, 48, 6, 57, 90,129, 1,241, + 5, 2,227,225,242,239,110,128, 1,196, 97, 2, 5, 16, 5, 27, + 225,242,237,229,238,233,225,110,128, 5, 52,230,242,233,227,225, + 110,128, 1,137, 99, 4, 5, 46, 5, 53, 5, 62, 5, 89,225,242, + 239,110,128, 1, 14,229,228,233,236,236, 97,128, 30, 16,233,242, + 99, 2, 5, 70, 5, 75,236,101,128, 36,185,245,237,230,236,229, + 248,226,229,236,239,119,128, 30, 18,242,239,225,116,128, 1, 16, + 228,239,116, 2, 5,104, 5,113,225,227,227,229,238,116,128, 30, + 10,226,229,236,239,119,128, 30, 12,101, 3, 5,129, 5,140, 5, + 150,227,249,242,233,236,236,233, 99,128, 4, 20,233,227,239,240, + 244,233, 99,128, 3,238,236,244, 97,129, 34, 6, 5,158,231,242, + 229,229,107,128, 3,148,232,239,239,107,128, 1,138,105, 2, 5, + 179, 5,218,229,242,229,243,233,115,131,246,203, 5,194, 5,202, + 5,210,193,227,245,244,101,128,246,204,199,242,225,246,101,128, + 246,205,243,237,225,236,108,128,247,168,231,225,237,237,225,231, + 242,229,229,107,128, 3,220,234,229,227,249,242,233,236,236,233, + 99,128, 4, 2,236,233,238,229,226,229,236,239,119,128, 30, 14, + 237,239,238,239,243,240,225,227,101,128,255, 36,239,244,225,227, + 227,229,238,244,243,237,225,236,108,128,246,247,115, 2, 6, 34, + 6, 41,236,225,243,104,128, 1, 16,237,225,236,108,128,247,100, + 244,239,240,226,225,114,128, 1,139,122,131, 1,242, 6, 67, 6, + 75, 6,112,227,225,242,239,110,128, 1,197,101, 2, 6, 81, 6, + 101,225,226,235,232,225,243,233,225,238,227,249,242,233,236,236, + 233, 99,128, 4,224,227,249,242,233,236,236,233, 99,128, 4, 5, + 232,229,227,249,242,233,236,236,233, 99,128, 4, 15, 69,146, 0, + 69, 6,165, 6,183, 6,191, 7, 89, 7,153, 7,165, 7,183, 7, + 211, 8, 7, 8, 36, 8, 94, 8,169, 8,189, 8,208, 8,248, 9, + 44, 9,109, 9,115,225,227,245,244,101,129, 0,201, 6,175,243, + 237,225,236,108,128,247,233,226,242,229,246,101,128, 1, 20, 99, + 5, 6,203, 6,210, 6,224, 6,236, 7, 79,225,242,239,110,128, + 1, 26,229,228,233,236,236,225,226,242,229,246,101,128, 30, 28, + 232,225,242,237,229,238,233,225,110,128, 5, 53,233,242, 99, 2, + 6,244, 6,249,236,101,128, 36,186,245,237,230,236,229,120,135, + 0,202, 7, 16, 7, 24, 7, 32, 7, 43, 7, 51, 7, 63, 7, 71, + 225,227,245,244,101,128, 30,190,226,229,236,239,119,128, 30, 24, + 228,239,244,226,229,236,239,119,128, 30,198,231,242,225,246,101, + 128, 30,192,232,239,239,235,225,226,239,246,101,128, 30,194,243, + 237,225,236,108,128,247,234,244,233,236,228,101,128, 30,196,249, + 242,233,236,236,233, 99,128, 4, 4,100, 3, 7, 97, 7,107, 7, + 127,226,236,231,242,225,246,101,128, 2, 4,233,229,242,229,243, + 233,115,129, 0,203, 7,119,243,237,225,236,108,128,247,235,239, + 116,130, 1, 22, 7,136, 7,145,225,227,227,229,238,116,128, 1, + 22,226,229,236,239,119,128, 30,184,230,227,249,242,233,236,236, + 233, 99,128, 4, 36,231,242,225,246,101,129, 0,200, 7,175,243, + 237,225,236,108,128,247,232,104, 2, 7,189, 7,200,225,242,237, + 229,238,233,225,110,128, 5, 55,239,239,235,225,226,239,246,101, + 128, 30,186,105, 3, 7,219, 7,230, 7,245,231,232,244,242,239, + 237,225,110,128, 33,103,238,246,229,242,244,229,228,226,242,229, + 246,101,128, 2, 6,239,244,233,230,233,229,228,227,249,242,233, + 236,236,233, 99,128, 4,100,108, 2, 8, 13, 8, 24,227,249,242, + 233,236,236,233, 99,128, 4, 27,229,246,229,238,242,239,237,225, + 110,128, 33,106,109, 3, 8, 44, 8, 72, 8, 83,225,227,242,239, + 110,130, 1, 18, 8, 56, 8, 64,225,227,245,244,101,128, 30, 22, + 231,242,225,246,101,128, 30, 20,227,249,242,233,236,236,233, 99, + 128, 4, 28,239,238,239,243,240,225,227,101,128,255, 37,110, 4, + 8,104, 8,115, 8,135, 8,154,227,249,242,233,236,236,233, 99, + 128, 4, 29,228,229,243,227,229,238,228,229,242,227,249,242,233, + 236,236,233, 99,128, 4,162,103,129, 1, 74, 8,141,232,229,227, + 249,242,233,236,236,233, 99,128, 4,164,232,239,239,235,227,249, + 242,233,236,236,233, 99,128, 4,199,111, 2, 8,175, 8,183,231, + 239,238,229,107,128, 1, 24,240,229,110,128, 1,144,240,243,233, + 236,239,110,129, 3,149, 8,200,244,239,238,239,115,128, 3,136, + 114, 2, 8,214, 8,225,227,249,242,233,236,236,233, 99,128, 4, + 32,229,246,229,242,243,229,100,129, 1,142, 8,237,227,249,242, + 233,236,236,233, 99,128, 4, 45,115, 4, 9, 2, 9, 13, 9, 33, + 9, 37,227,249,242,233,236,236,233, 99,128, 4, 33,228,229,243, + 227,229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4, + 170,104,128, 1,169,237,225,236,108,128,247,101,116, 3, 9, 52, + 9, 78, 9, 92, 97,130, 3,151, 9, 60, 9, 70,242,237,229,238, + 233,225,110,128, 5, 56,244,239,238,239,115,128, 3,137,104,129, + 0,208, 9, 84,243,237,225,236,108,128,247,240,233,236,228,101, + 129, 30,188, 9,101,226,229,236,239,119,128, 30, 26,245,242,111, + 128, 32,172,250,104,130, 1,183, 9,124, 9,132,227,225,242,239, + 110,128, 1,238,242,229,246,229,242,243,229,100,128, 1,184, 70, + 136, 0, 70, 9,163, 9,172, 9,184, 9,212, 9,219, 9,248, 10, + 4, 10, 15,227,233,242,227,236,101,128, 36,187,228,239,244,225, + 227,227,229,238,116,128, 30, 30,101, 2, 9,190, 9,202,232,225, + 242,237,229,238,233,225,110,128, 5, 86,233,227,239,240,244,233, + 99,128, 3,228,232,239,239,107,128, 1,145,105, 2, 9,225, 9, + 238,244,225,227,249,242,233,236,236,233, 99,128, 4,114,246,229, + 242,239,237,225,110,128, 33,100,237,239,238,239,243,240,225,227, + 101,128,255, 38,239,245,242,242,239,237,225,110,128, 33, 99,243, + 237,225,236,108,128,247,102, 71,140, 0, 71, 10, 51, 10, 61, 10, + 107, 10,115, 10,176, 10,193, 10,205, 11, 39, 11, 52, 11, 65, 11, + 90, 11,107,194,243,241,245,225,242,101,128, 51,135, 97, 3, 10, + 69, 10, 76, 10, 94,227,245,244,101,128, 1,244,237,237, 97,129, + 3,147, 10, 84,225,230,242,233,227,225,110,128, 1,148,238,231, + 233,225,227,239,240,244,233, 99,128, 3,234,226,242,229,246,101, + 128, 1, 30, 99, 4, 10,125, 10,132, 10,141, 10,163,225,242,239, + 110,128, 1,230,229,228,233,236,236, 97,128, 1, 34,233,242, 99, + 2, 10,149, 10,154,236,101,128, 36,188,245,237,230,236,229,120, + 128, 1, 28,239,237,237,225,225,227,227,229,238,116,128, 1, 34, + 228,239,116,129, 1, 32, 10,184,225,227,227,229,238,116,128, 1, + 32,229,227,249,242,233,236,236,233, 99,128, 4, 19,104, 3, 10, + 213, 10,226, 11, 33,225,228,225,242,237,229,238,233,225,110,128, + 5, 66,101, 3, 10,234, 10,255, 11, 16,237,233,228,228,236,229, + 232,239,239,235,227,249,242,233,236,236,233, 99,128, 4,148,243, + 244,242,239,235,229,227,249,242,233,236,236,233, 99,128, 4,146, + 245,240,244,245,242,238,227,249,242,233,236,236,233, 99,128, 4, + 144,239,239,107,128, 1,147,233,237,225,242,237,229,238,233,225, + 110,128, 5, 51,234,229,227,249,242,233,236,236,233, 99,128, 4, + 3,109, 2, 11, 71, 11, 79,225,227,242,239,110,128, 30, 32,239, + 238,239,243,240,225,227,101,128,255, 39,242,225,246,101,129,246, + 206, 11, 99,243,237,225,236,108,128,247, 96,115, 2, 11,113, 11, + 129,237,225,236,108,129,247,103, 11,122,232,239,239,107,128, 2, + 155,244,242,239,235,101,128, 1,228, 72,140, 0, 72, 11,165, 11, + 190, 11,198, 11,208, 12, 17, 12, 40, 12, 77, 12,117, 12,129, 12, + 157, 12,165, 12,189,177,184, 53, 3, 11,175, 11,180, 11,185,179, + 51,128, 37,207,180, 51,128, 37,170,181, 49,128, 37,171,178,178, + 176,183, 51,128, 37,161,208,243,241,245,225,242,101,128, 51,203, + 97, 3, 11,216, 11,236, 12, 0,225,226,235,232,225,243,233,225, + 238,227,249,242,233,236,236,233, 99,128, 4,168,228,229,243,227, + 229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,178, + 242,228,243,233,231,238,227,249,242,233,236,236,233, 99,128, 4, + 42, 98, 2, 12, 23, 12, 28,225,114,128, 1, 38,242,229,246,229, + 226,229,236,239,119,128, 30, 42, 99, 2, 12, 46, 12, 55,229,228, + 233,236,236, 97,128, 30, 40,233,242, 99, 2, 12, 63, 12, 68,236, + 101,128, 36,189,245,237,230,236,229,120,128, 1, 36,100, 2, 12, + 83, 12, 93,233,229,242,229,243,233,115,128, 30, 38,239,116, 2, + 12,100, 12,109,225,227,227,229,238,116,128, 30, 34,226,229,236, + 239,119,128, 30, 36,237,239,238,239,243,240,225,227,101,128,255, + 40,111, 2, 12,135, 12,146,225,242,237,229,238,233,225,110,128, + 5, 64,242,233,227,239,240,244,233, 99,128, 3,232,243,237,225, + 236,108,128,247,104,245,238,231,225,242,245,237,236,225,245,116, + 129,246,207, 12,181,243,237,225,236,108,128,246,248,250,243,241, + 245,225,242,101,128, 51,144, 73,146, 0, 73, 12,239, 12,251, 12, + 255, 13, 11, 13, 29, 13, 37, 13, 94, 13,181, 13,214, 13,224, 13, + 242, 13,254, 14, 48, 14, 86, 14, 99, 14,166, 14,187, 14,205,193, + 227,249,242,233,236,236,233, 99,128, 4, 47, 74,128, 1, 50,213, + 227,249,242,233,236,236,233, 99,128, 4, 46,225,227,245,244,101, + 129, 0,205, 13, 21,243,237,225,236,108,128,247,237,226,242,229, + 246,101,128, 1, 44, 99, 3, 13, 45, 13, 52, 13, 84,225,242,239, + 110,128, 1,207,233,242, 99, 2, 13, 60, 13, 65,236,101,128, 36, + 190,245,237,230,236,229,120,129, 0,206, 13, 76,243,237,225,236, + 108,128,247,238,249,242,233,236,236,233, 99,128, 4, 6,100, 3, + 13,102, 13,112, 13,155,226,236,231,242,225,246,101,128, 2, 8, + 233,229,242,229,243,233,115,131, 0,207, 13,128, 13,136, 13,147, + 225,227,245,244,101,128, 30, 46,227,249,242,233,236,236,233, 99, + 128, 4,228,243,237,225,236,108,128,247,239,239,116,130, 1, 48, + 13,164, 13,173,225,227,227,229,238,116,128, 1, 48,226,229,236, + 239,119,128, 30,202,101, 2, 13,187, 13,203,226,242,229,246,229, + 227,249,242,233,236,236,233, 99,128, 4,214,227,249,242,233,236, + 236,233, 99,128, 4, 21,230,242,225,235,244,245,114,128, 33, 17, + 231,242,225,246,101,129, 0,204, 13,234,243,237,225,236,108,128, + 247,236,232,239,239,235,225,226,239,246,101,128, 30,200,105, 3, + 14, 6, 14, 17, 14, 32,227,249,242,233,236,236,233, 99,128, 4, + 24,238,246,229,242,244,229,228,226,242,229,246,101,128, 2, 10, + 243,232,239,242,244,227,249,242,233,236,236,233, 99,128, 4, 25, + 109, 2, 14, 54, 14, 75,225,227,242,239,110,129, 1, 42, 14, 64, + 227,249,242,233,236,236,233, 99,128, 4,226,239,238,239,243,240, + 225,227,101,128,255, 41,238,233,225,242,237,229,238,233,225,110, + 128, 5, 59,111, 3, 14,107, 14,118, 14,126,227,249,242,233,236, + 236,233, 99,128, 4, 1,231,239,238,229,107,128, 1, 46,244, 97, + 131, 3,153, 14,137, 14,147, 14,158,225,230,242,233,227,225,110, + 128, 1,150,228,233,229,242,229,243,233,115,128, 3,170,244,239, + 238,239,115,128, 3,138,115, 2, 14,172, 14,179,237,225,236,108, + 128,247,105,244,242,239,235,101,128, 1,151,244,233,236,228,101, + 129, 1, 40, 14,197,226,229,236,239,119,128, 30, 44,250,232,233, + 244,243, 97, 2, 14,216, 14,227,227,249,242,233,236,236,233, 99, + 128, 4,116,228,226,236,231,242,225,246,229,227,249,242,233,236, + 236,233, 99,128, 4,118, 74,134, 0, 74, 15, 6, 15, 18, 15, 41, + 15, 53, 15, 67, 15, 79,225,225,242,237,229,238,233,225,110,128, + 5, 65,227,233,242, 99, 2, 15, 27, 15, 32,236,101,128, 36,191, + 245,237,230,236,229,120,128, 1, 52,229,227,249,242,233,236,236, + 233, 99,128, 4, 8,232,229,232,225,242,237,229,238,233,225,110, + 128, 5, 75,237,239,238,239,243,240,225,227,101,128,255, 42,243, + 237,225,236,108,128,247,106, 75,140, 0, 75, 15,115, 15,125, 15, + 135, 16, 18, 16, 65, 16, 76, 16,106, 16,143, 16,156, 16,168, 16, + 180, 16,208,194,243,241,245,225,242,101,128, 51,133,203,243,241, + 245,225,242,101,128, 51,205, 97, 7, 15,151, 15,169, 15,191, 15, + 211, 15,226, 15,232, 15,249,226,225,243,232,235,233,242,227,249, + 242,233,236,236,233, 99,128, 4,160, 99, 2, 15,175, 15,181,245, + 244,101,128, 30, 48,249,242,233,236,236,233, 99,128, 4, 26,228, + 229,243,227,229,238,228,229,242,227,249,242,233,236,236,233, 99, + 128, 4,154,232,239,239,235,227,249,242,233,236,236,233, 99,128, + 4,195,240,240, 97,128, 3,154,243,244,242,239,235,229,227,249, + 242,233,236,236,233, 99,128, 4,158,246,229,242,244,233,227,225, + 236,243,244,242,239,235,229,227,249,242,233,236,236,233, 99,128, + 4,156, 99, 4, 16, 28, 16, 35, 16, 44, 16, 52,225,242,239,110, + 128, 1,232,229,228,233,236,236, 97,128, 1, 54,233,242,227,236, + 101,128, 36,192,239,237,237,225,225,227,227,229,238,116,128, 1, + 54,228,239,244,226,229,236,239,119,128, 30, 50,101, 2, 16, 82, + 16, 94,232,225,242,237,229,238,233,225,110,128, 5, 84,238,225, + 242,237,229,238,233,225,110,128, 5, 63,104, 3, 16,114, 16,126, + 16,137,225,227,249,242,233,236,236,233, 99,128, 4, 37,229,233, + 227,239,240,244,233, 99,128, 3,230,239,239,107,128, 1,152,234, + 229,227,249,242,233,236,236,233, 99,128, 4, 12,236,233,238,229, + 226,229,236,239,119,128, 30, 52,237,239,238,239,243,240,225,227, + 101,128,255, 43,239,240,240, 97, 2, 16,189, 16,200,227,249,242, + 233,236,236,233, 99,128, 4,128,231,242,229,229,107,128, 3,222, + 115, 2, 16,214, 16,226,233,227,249,242,233,236,236,233, 99,128, + 4,110,237,225,236,108,128,247,107, 76,138, 0, 76, 17, 1, 17, + 5, 17, 9, 17, 29, 17, 95, 17,133, 17,147, 17,165, 17,177, 17, + 189, 74,128, 1,199, 76,128,246,191, 97, 2, 17, 15, 17, 22,227, + 245,244,101,128, 1, 57,237,226,228, 97,128, 3,155, 99, 4, 17, + 39, 17, 46, 17, 55, 17, 82,225,242,239,110,128, 1, 61,229,228, + 233,236,236, 97,128, 1, 59,233,242, 99, 2, 17, 63, 17, 68,236, + 101,128, 36,193,245,237,230,236,229,248,226,229,236,239,119,128, + 30, 60,239,237,237,225,225,227,227,229,238,116,128, 1, 59,228, + 239,116,130, 1, 63, 17,105, 17,114,225,227,227,229,238,116,128, + 1, 63,226,229,236,239,119,129, 30, 54, 17,124,237,225,227,242, + 239,110,128, 30, 56,233,247,238,225,242,237,229,238,233,225,110, + 128, 5, 60,106,129, 1,200, 17,153,229,227,249,242,233,236,236, + 233, 99,128, 4, 9,236,233,238,229,226,229,236,239,119,128, 30, + 58,237,239,238,239,243,240,225,227,101,128,255, 44,115, 2, 17, + 195, 17,212,236,225,243,104,129, 1, 65, 17,204,243,237,225,236, + 108,128,246,249,237,225,236,108,128,247,108, 77,137, 0, 77, 17, + 241, 17,251, 18, 24, 18, 33, 18, 58, 18, 71, 18, 83, 18, 91, 18, + 100,194,243,241,245,225,242,101,128, 51,134,225, 99, 2, 18, 2, + 18, 18,242,239,110,129,246,208, 18, 10,243,237,225,236,108,128, + 247,175,245,244,101,128, 30, 62,227,233,242,227,236,101,128, 36, + 194,228,239,116, 2, 18, 41, 18, 50,225,227,227,229,238,116,128, + 30, 64,226,229,236,239,119,128, 30, 66,229,238,225,242,237,229, + 238,233,225,110,128, 5, 68,237,239,238,239,243,240,225,227,101, + 128,255, 45,243,237,225,236,108,128,247,109,244,245,242,238,229, + 100,128, 1,156,117,128, 3,156, 78,141, 0, 78, 18,134, 18,138, + 18,146, 18,212, 18,237, 18,248, 19, 3, 19, 21, 19, 33, 19, 45, + 19, 58, 19, 66, 19, 84, 74,128, 1,202,225,227,245,244,101,128, + 1, 67, 99, 4, 18,156, 18,163, 18,172, 18,199,225,242,239,110, + 128, 1, 71,229,228,233,236,236, 97,128, 1, 69,233,242, 99, 2, + 18,180, 18,185,236,101,128, 36,195,245,237,230,236,229,248,226, + 229,236,239,119,128, 30, 74,239,237,237,225,225,227,227,229,238, + 116,128, 1, 69,228,239,116, 2, 18,220, 18,229,225,227,227,229, + 238,116,128, 30, 68,226,229,236,239,119,128, 30, 70,232,239,239, + 235,236,229,230,116,128, 1,157,233,238,229,242,239,237,225,110, + 128, 33,104,106,129, 1,203, 19, 9,229,227,249,242,233,236,236, + 233, 99,128, 4, 10,236,233,238,229,226,229,236,239,119,128, 30, + 72,237,239,238,239,243,240,225,227,101,128,255, 46,239,247,225, + 242,237,229,238,233,225,110,128, 5, 70,243,237,225,236,108,128, + 247,110,244,233,236,228,101,129, 0,209, 19, 76,243,237,225,236, + 108,128,247,241,117,128, 3,157, 79,141, 0, 79, 19,118, 19,132, + 19,150, 19,203, 20, 78, 20,152, 20,187, 21, 48, 21, 69, 21,213, + 21,223, 21,254, 22, 53, 69,129, 1, 82, 19,124,243,237,225,236, + 108,128,246,250,225,227,245,244,101,129, 0,211, 19,142,243,237, + 225,236,108,128,247,243, 98, 2, 19,156, 19,196,225,242,242,229, + 100, 2, 19,166, 19,177,227,249,242,233,236,236,233, 99,128, 4, + 232,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, + 99,128, 4,234,242,229,246,101,128, 1, 78, 99, 4, 19,213, 19, + 220, 19,235, 20, 68,225,242,239,110,128, 1,209,229,238,244,229, + 242,229,228,244,233,236,228,101,128, 1,159,233,242, 99, 2, 19, + 243, 19,248,236,101,128, 36,196,245,237,230,236,229,120,134, 0, + 212, 20, 13, 20, 21, 20, 32, 20, 40, 20, 52, 20, 60,225,227,245, + 244,101,128, 30,208,228,239,244,226,229,236,239,119,128, 30,216, + 231,242,225,246,101,128, 30,210,232,239,239,235,225,226,239,246, + 101,128, 30,212,243,237,225,236,108,128,247,244,244,233,236,228, + 101,128, 30,214,249,242,233,236,236,233, 99,128, 4, 30,100, 3, + 20, 86, 20,109, 20,142,226,108, 2, 20, 93, 20,101,225,227,245, + 244,101,128, 1, 80,231,242,225,246,101,128, 2, 12,233,229,242, + 229,243,233,115,130, 0,214, 20,123, 20,134,227,249,242,233,236, + 236,233, 99,128, 4,230,243,237,225,236,108,128,247,246,239,244, + 226,229,236,239,119,128, 30,204,103, 2, 20,158, 20,170,239,238, + 229,235,243,237,225,236,108,128,246,251,242,225,246,101,129, 0, + 210, 20,179,243,237,225,236,108,128,247,242,104, 4, 20,197, 20, + 208, 20,212, 21, 34,225,242,237,229,238,233,225,110,128, 5, 85, + 109,128, 33, 38,111, 2, 20,218, 20,228,239,235,225,226,239,246, + 101,128, 30,206,242,110,133, 1,160, 20,243, 20,251, 21, 6, 21, + 14, 21, 26,225,227,245,244,101,128, 30,218,228,239,244,226,229, + 236,239,119,128, 30,226,231,242,225,246,101,128, 30,220,232,239, + 239,235,225,226,239,246,101,128, 30,222,244,233,236,228,101,128, + 30,224,245,238,231,225,242,245,237,236,225,245,116,128, 1, 80, + 105,129, 1,162, 21, 54,238,246,229,242,244,229,228,226,242,229, + 246,101,128, 2, 14,109, 4, 21, 79, 21,107, 21,184, 21,202,225, + 227,242,239,110,130, 1, 76, 21, 91, 21, 99,225,227,245,244,101, + 128, 30, 82,231,242,225,246,101,128, 30, 80,229,231, 97,132, 33, + 38, 21,121, 21,132, 21,140, 21,156,227,249,242,233,236,236,233, + 99,128, 4, 96,231,242,229,229,107,128, 3,169,242,239,245,238, + 228,227,249,242,233,236,236,233, 99,128, 4,122,116, 2, 21,162, + 21,177,233,244,236,239,227,249,242,233,236,236,233, 99,128, 4, + 124,239,238,239,115,128, 3,143,233,227,242,239,110,129, 3,159, + 21,194,244,239,238,239,115,128, 3,140,239,238,239,243,240,225, + 227,101,128,255, 47,238,229,242,239,237,225,110,128, 33, 96,111, + 2, 21,229, 21,248,231,239,238,229,107,129, 1,234, 21,239,237, + 225,227,242,239,110,128, 1,236,240,229,110,128, 1,134,115, 3, + 22, 6, 22, 33, 22, 40,236,225,243,104,130, 0,216, 22, 17, 22, + 25,225,227,245,244,101,128, 1,254,243,237,225,236,108,128,247, + 248,237,225,236,108,128,247,111,244,242,239,235,229,225,227,245, + 244,101,128, 1,254,116, 2, 22, 59, 22, 70,227,249,242,233,236, + 236,233, 99,128, 4,126,233,236,228,101,131, 0,213, 22, 83, 22, + 91, 22,102,225,227,245,244,101,128, 30, 76,228,233,229,242,229, + 243,233,115,128, 30, 78,243,237,225,236,108,128,247,245, 80,136, + 0, 80, 22,130, 22,138, 22,147, 22,159, 22,211, 22,227, 22,246, + 23, 2,225,227,245,244,101,128, 30, 84,227,233,242,227,236,101, + 128, 36,197,228,239,244,225,227,227,229,238,116,128, 30, 86,101, + 3, 22,167, 22,178, 22,190,227,249,242,233,236,236,233, 99,128, + 4, 31,232,225,242,237,229,238,233,225,110,128, 5, 74,237,233, + 228,228,236,229,232,239,239,235,227,249,242,233,236,236,233, 99, + 128, 4,166,104, 2, 22,217, 22,221,105,128, 3,166,239,239,107, + 128, 1,164,105,129, 3,160, 22,233,247,242,225,242,237,229,238, + 233,225,110,128, 5, 83,237,239,238,239,243,240,225,227,101,128, + 255, 48,115, 2, 23, 8, 23, 25,105,129, 3,168, 23, 14,227,249, + 242,233,236,236,233, 99,128, 4,112,237,225,236,108,128,247,112, + 81,131, 0, 81, 23, 42, 23, 51, 23, 63,227,233,242,227,236,101, + 128, 36,198,237,239,238,239,243,240,225,227,101,128,255, 49,243, + 237,225,236,108,128,247,113, 82,138, 0, 82, 23, 95, 23,119, 23, + 166, 23,217, 23,230, 23,240, 23,245, 24, 19, 24, 31, 24, 43, 97, + 2, 23,101, 23,112,225,242,237,229,238,233,225,110,128, 5, 76, + 227,245,244,101,128, 1, 84, 99, 4, 23,129, 23,136, 23,145, 23, + 153,225,242,239,110,128, 1, 88,229,228,233,236,236, 97,128, 1, + 86,233,242,227,236,101,128, 36,199,239,237,237,225,225,227,227, + 229,238,116,128, 1, 86,100, 2, 23,172, 23,182,226,236,231,242, + 225,246,101,128, 2, 16,239,116, 2, 23,189, 23,198,225,227,227, + 229,238,116,128, 30, 88,226,229,236,239,119,129, 30, 90, 23,208, + 237,225,227,242,239,110,128, 30, 92,229,232,225,242,237,229,238, + 233,225,110,128, 5, 80,230,242,225,235,244,245,114,128, 33, 28, + 232,111,128, 3,161,233,110, 2, 23,252, 24, 5,231,243,237,225, + 236,108,128,246,252,246,229,242,244,229,228,226,242,229,246,101, + 128, 2, 18,236,233,238,229,226,229,236,239,119,128, 30, 94,237, + 239,238,239,243,240,225,227,101,128,255, 50,243,237,225,236,108, + 129,247,114, 24, 53,233,238,246,229,242,244,229,100,129, 2,129, + 24, 66,243,245,240,229,242,233,239,114,128, 2,182, 83,139, 0, + 83, 24,103, 26, 17, 26, 55, 26,182, 26,221, 26,250, 27, 84, 27, + 105, 27,117, 27,135, 27,143, 70, 6, 24,117, 24,209, 24,241, 25, + 77, 25,119, 25,221, 48, 9, 24,137, 24,145, 24,153, 24,161, 24, + 169, 24,177, 24,185, 24,193, 24,201,177,176,176,176, 48,128, 37, + 12,178,176,176,176, 48,128, 37, 20,179,176,176,176, 48,128, 37, + 16,180,176,176,176, 48,128, 37, 24,181,176,176,176, 48,128, 37, + 60,182,176,176,176, 48,128, 37, 44,183,176,176,176, 48,128, 37, + 52,184,176,176,176, 48,128, 37, 28,185,176,176,176, 48,128, 37, + 36, 49, 3, 24,217, 24,225, 24,233,176,176,176,176, 48,128, 37, + 0,177,176,176,176, 48,128, 37, 2,185,176,176,176, 48,128, 37, + 97, 50, 9, 25, 5, 25, 13, 25, 21, 25, 29, 25, 37, 25, 45, 25, + 53, 25, 61, 25, 69,176,176,176,176, 48,128, 37, 98,177,176,176, + 176, 48,128, 37, 86,178,176,176,176, 48,128, 37, 85,179,176,176, + 176, 48,128, 37, 99,180,176,176,176, 48,128, 37, 81,181,176,176, + 176, 48,128, 37, 87,182,176,176,176, 48,128, 37, 93,183,176,176, + 176, 48,128, 37, 92,184,176,176,176, 48,128, 37, 91, 51, 4, 25, + 87, 25, 95, 25,103, 25,111,182,176,176,176, 48,128, 37, 94,183, + 176,176,176, 48,128, 37, 95,184,176,176,176, 48,128, 37, 90,185, + 176,176,176, 48,128, 37, 84, 52, 10, 25,141, 25,149, 25,157, 25, + 165, 25,173, 25,181, 25,189, 25,197, 25,205, 25,213,176,176,176, + 176, 48,128, 37,105,177,176,176,176, 48,128, 37,102,178,176,176, + 176, 48,128, 37, 96,179,176,176,176, 48,128, 37, 80,180,176,176, + 176, 48,128, 37,108,181,176,176,176, 48,128, 37,103,182,176,176, + 176, 48,128, 37,104,183,176,176,176, 48,128, 37,100,184,176,176, + 176, 48,128, 37,101,185,176,176,176, 48,128, 37, 89, 53, 5, 25, + 233, 25,241, 25,249, 26, 1, 26, 9,176,176,176,176, 48,128, 37, + 88,177,176,176,176, 48,128, 37, 82,178,176,176,176, 48,128, 37, + 83,179,176,176,176, 48,128, 37,107,180,176,176,176, 48,128, 37, + 106, 97, 2, 26, 23, 26, 44,227,245,244,101,129, 1, 90, 26, 32, + 228,239,244,225,227,227,229,238,116,128, 30,100,237,240,233,231, + 242,229,229,107,128, 3,224, 99, 5, 26, 67, 26, 98, 26,107, 26, + 147, 26,169,225,242,239,110,130, 1, 96, 26, 78, 26, 90,228,239, + 244,225,227,227,229,238,116,128, 30,102,243,237,225,236,108,128, + 246,253,229,228,233,236,236, 97,128, 1, 94,232,247, 97,130, 1, + 143, 26,117, 26,128,227,249,242,233,236,236,233, 99,128, 4,216, + 228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99, + 128, 4,218,233,242, 99, 2, 26,155, 26,160,236,101,128, 36,200, + 245,237,230,236,229,120,128, 1, 92,239,237,237,225,225,227,227, + 229,238,116,128, 2, 24,228,239,116, 2, 26,190, 26,199,225,227, + 227,229,238,116,128, 30, 96,226,229,236,239,119,129, 30, 98, 26, + 209,228,239,244,225,227,227,229,238,116,128, 30,104,101, 2, 26, + 227, 26,239,232,225,242,237,229,238,233,225,110,128, 5, 77,246, + 229,238,242,239,237,225,110,128, 33,102,104, 5, 27, 6, 27, 34, + 27, 48, 27, 59, 27, 72, 97, 2, 27, 12, 27, 23,225,242,237,229, + 238,233,225,110,128, 5, 71,227,249,242,233,236,236,233, 99,128, + 4, 40,227,232,225,227,249,242,233,236,236,233, 99,128, 4, 41, + 229,233,227,239,240,244,233, 99,128, 3,226,232,225,227,249,242, + 233,236,236,233, 99,128, 4,186,233,237,225,227,239,240,244,233, + 99,128, 3,236,105, 2, 27, 90, 27, 96,231,237, 97,128, 3,163, + 248,242,239,237,225,110,128, 33,101,237,239,238,239,243,240,225, + 227,101,128,255, 51,239,230,244,243,233,231,238,227,249,242,233, + 236,236,233, 99,128, 4, 44,243,237,225,236,108,128,247,115,244, + 233,231,237,225,231,242,229,229,107,128, 3,218, 84,141, 0, 84, + 27,186, 27,191, 27,197, 28, 7, 28, 32, 28, 96, 28,147, 28,177, + 28,189, 28,201, 28,246, 29, 6, 29, 46,225,117,128, 3,164,226, + 225,114,128, 1,102, 99, 4, 27,207, 27,214, 27,223, 27,250,225, + 242,239,110,128, 1,100,229,228,233,236,236, 97,128, 1, 98,233, + 242, 99, 2, 27,231, 27,236,236,101,128, 36,201,245,237,230,236, + 229,248,226,229,236,239,119,128, 30,112,239,237,237,225,225,227, + 227,229,238,116,128, 1, 98,228,239,116, 2, 28, 15, 28, 24,225, + 227,227,229,238,116,128, 30,106,226,229,236,239,119,128, 30,108, + 101, 4, 28, 42, 28, 53, 28, 73, 28, 82,227,249,242,233,236,236, + 233, 99,128, 4, 34,228,229,243,227,229,238,228,229,242,227,249, + 242,233,236,236,233, 99,128, 4,172,238,242,239,237,225,110,128, + 33,105,244,243,229,227,249,242,233,236,236,233, 99,128, 4,180, + 104, 3, 28,104, 28,110, 28,136,229,244, 97,128, 3,152,111, 2, + 28,116, 28,121,239,107,128, 1,172,242,110,129, 0,222, 28,128, + 243,237,225,236,108,128,247,254,242,229,229,242,239,237,225,110, + 128, 33, 98,105, 2, 28,153, 28,164,236,228,229,243,237,225,236, + 108,128,246,254,247,238,225,242,237,229,238,233,225,110,128, 5, + 79,236,233,238,229,226,229,236,239,119,128, 30,110,237,239,238, + 239,243,240,225,227,101,128,255, 52,111, 2, 28,207, 28,218,225, + 242,237,229,238,233,225,110,128, 5, 57,238,101, 3, 28,227, 28, + 234, 28,240,230,233,246,101,128, 1,188,243,233,120,128, 1,132, + 244,247,111,128, 1,167,242,229,244,242,239,230,236,229,248,232, + 239,239,107,128, 1,174,115, 3, 29, 14, 29, 26, 29, 39,229,227, + 249,242,233,236,236,233, 99,128, 4, 38,232,229,227,249,242,233, + 236,236,233, 99,128, 4, 11,237,225,236,108,128,247,116,119, 2, + 29, 52, 29, 64,229,236,246,229,242,239,237,225,110,128, 33,107, + 239,242,239,237,225,110,128, 33, 97, 85,142, 0, 85, 29,105, 29, + 123, 29,131, 29,198, 30, 69, 30, 87, 30,198, 30,214, 30,226, 31, + 21, 31, 30, 31,142, 31,149, 31,219,225,227,245,244,101,129, 0, + 218, 29,115,243,237,225,236,108,128,247,250,226,242,229,246,101, + 128, 1,108, 99, 3, 29,139, 29,146, 29,188,225,242,239,110,128, + 1,211,233,242, 99, 2, 29,154, 29,159,236,101,128, 36,202,245, + 237,230,236,229,120,130, 0,219, 29,172, 29,180,226,229,236,239, + 119,128, 30,118,243,237,225,236,108,128,247,251,249,242,233,236, + 236,233, 99,128, 4, 35,100, 3, 29,206, 29,229, 30, 59,226,108, + 2, 29,213, 29,221,225,227,245,244,101,128, 1,112,231,242,225, + 246,101,128, 2, 20,233,229,242,229,243,233,115,134, 0,220, 29, + 251, 30, 3, 30, 11, 30, 34, 30, 42, 30, 51,225,227,245,244,101, + 128, 1,215,226,229,236,239,119,128, 30,114, 99, 2, 30, 17, 30, + 24,225,242,239,110,128, 1,217,249,242,233,236,236,233, 99,128, + 4,240,231,242,225,246,101,128, 1,219,237,225,227,242,239,110, + 128, 1,213,243,237,225,236,108,128,247,252,239,244,226,229,236, + 239,119,128, 30,228,231,242,225,246,101,129, 0,217, 30, 79,243, + 237,225,236,108,128,247,249,104, 2, 30, 93, 30,171,111, 2, 30, + 99, 30,109,239,235,225,226,239,246,101,128, 30,230,242,110,133, + 1,175, 30,124, 30,132, 30,143, 30,151, 30,163,225,227,245,244, + 101,128, 30,232,228,239,244,226,229,236,239,119,128, 30,240,231, + 242,225,246,101,128, 30,234,232,239,239,235,225,226,239,246,101, + 128, 30,236,244,233,236,228,101,128, 30,238,245,238,231,225,242, + 245,237,236,225,245,116,129, 1,112, 30,187,227,249,242,233,236, + 236,233, 99,128, 4,242,233,238,246,229,242,244,229,228,226,242, + 229,246,101,128, 2, 22,235,227,249,242,233,236,236,233, 99,128, + 4,120,109, 2, 30,232, 31, 10,225,227,242,239,110,130, 1,106, + 30,244, 30,255,227,249,242,233,236,236,233, 99,128, 4,238,228, + 233,229,242,229,243,233,115,128, 30,122,239,238,239,243,240,225, + 227,101,128,255, 53,239,231,239,238,229,107,128, 1,114,240,243, + 233,236,239,110,133, 3,165, 31, 49, 31, 53, 31, 90, 31,121, 31, + 134, 49,128, 3,210, 97, 2, 31, 59, 31, 81,227,245,244,229,232, + 239,239,235,243,249,237,226,239,236,231,242,229,229,107,128, 3, + 211,230,242,233,227,225,110,128, 1,177,228,233,229,242,229,243, + 233,115,129, 3,171, 31,103,232,239,239,235,243,249,237,226,239, + 236,231,242,229,229,107,128, 3,212,232,239,239,235,243,249,237, + 226,239,108,128, 3,210,244,239,238,239,115,128, 3,142,242,233, + 238,103,128, 1,110,115, 3, 31,157, 31,172, 31,179,232,239,242, + 244,227,249,242,233,236,236,233, 99,128, 4, 14,237,225,236,108, + 128,247,117,244,242,225,233,231,232,116, 2, 31,191, 31,202,227, + 249,242,233,236,236,233, 99,128, 4,174,243,244,242,239,235,229, + 227,249,242,233,236,236,233, 99,128, 4,176,244,233,236,228,101, + 130, 1,104, 31,231, 31,239,225,227,245,244,101,128, 30,120,226, + 229,236,239,119,128, 30,116, 86,136, 0, 86, 32, 11, 32, 20, 32, + 31, 32, 60, 32, 67, 32, 79, 32, 91, 32, 99,227,233,242,227,236, + 101,128, 36,203,228,239,244,226,229,236,239,119,128, 30,126,101, + 2, 32, 37, 32, 48,227,249,242,233,236,236,233, 99,128, 4, 18, + 247,225,242,237,229,238,233,225,110,128, 5, 78,232,239,239,107, + 128, 1,178,237,239,238,239,243,240,225,227,101,128,255, 54,239, + 225,242,237,229,238,233,225,110,128, 5, 72,243,237,225,236,108, + 128,247,118,244,233,236,228,101,128, 30,124, 87,134, 0, 87, 32, + 123, 32,131, 32,154, 32,194, 32,202, 32,214,225,227,245,244,101, + 128, 30,130,227,233,242, 99, 2, 32,140, 32,145,236,101,128, 36, + 204,245,237,230,236,229,120,128, 1,116,100, 2, 32,160, 32,170, + 233,229,242,229,243,233,115,128, 30,132,239,116, 2, 32,177, 32, + 186,225,227,227,229,238,116,128, 30,134,226,229,236,239,119,128, + 30,136,231,242,225,246,101,128, 30,128,237,239,238,239,243,240, + 225,227,101,128,255, 55,243,237,225,236,108,128,247,119, 88,134, + 0, 88, 32,238, 32,247, 33, 18, 33, 31, 33, 35, 33, 47,227,233, + 242,227,236,101,128, 36,205,100, 2, 32,253, 33, 7,233,229,242, + 229,243,233,115,128, 30,140,239,244,225,227,227,229,238,116,128, + 30,138,229,232,225,242,237,229,238,233,225,110,128, 5, 61,105, + 128, 3,158,237,239,238,239,243,240,225,227,101,128,255, 56,243, + 237,225,236,108,128,247,120, 89,139, 0, 89, 33, 81, 33,116, 33, + 139, 33,189, 33,228, 33,236, 33,253, 34, 40, 34, 52, 34, 60, 34, + 68, 97, 2, 33, 87, 33,104,227,245,244,101,129, 0,221, 33, 96, + 243,237,225,236,108,128,247,253,244,227,249,242,233,236,236,233, + 99,128, 4, 98,227,233,242, 99, 2, 33,125, 33,130,236,101,128, + 36,206,245,237,230,236,229,120,128, 1,118,100, 2, 33,145, 33, + 165,233,229,242,229,243,233,115,129, 1,120, 33,157,243,237,225, + 236,108,128,247,255,239,116, 2, 33,172, 33,181,225,227,227,229, + 238,116,128, 30,142,226,229,236,239,119,128, 30,244,229,114, 2, + 33,196, 33,208,233,227,249,242,233,236,236,233, 99,128, 4, 43, + 245,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, + 99,128, 4,248,231,242,225,246,101,128, 30,242,232,239,239,107, + 129, 1,179, 33,245,225,226,239,246,101,128, 30,246,105, 3, 34, + 5, 34, 16, 34, 27,225,242,237,229,238,233,225,110,128, 5, 69, + 227,249,242,233,236,236,233, 99,128, 4, 7,247,238,225,242,237, + 229,238,233,225,110,128, 5, 82,237,239,238,239,243,240,225,227, + 101,128,255, 57,243,237,225,236,108,128,247,121,244,233,236,228, + 101,128, 30,248,245,115, 2, 34, 75, 34,113,226,233,103, 2, 34, + 83, 34, 94,227,249,242,233,236,236,233, 99,128, 4,106,233,239, + 244,233,230,233,229,228,227,249,242,233,236,236,233, 99,128, 4, + 108,236,233,244,244,236,101, 2, 34,124, 34,135,227,249,242,233, + 236,236,233, 99,128, 4,102,233,239,244,233,230,233,229,228,227, + 249,242,233,236,236,233, 99,128, 4,104, 90,136, 0, 90, 34,174, + 34,198, 34,243, 35, 14, 35, 81, 35,173, 35,185, 35,197, 97, 2, + 34,180, 34,191,225,242,237,229,238,233,225,110,128, 5, 54,227, + 245,244,101,128, 1,121, 99, 2, 34,204, 34,221,225,242,239,110, + 129, 1,125, 34,213,243,237,225,236,108,128,246,255,233,242, 99, + 2, 34,229, 34,234,236,101,128, 36,207,245,237,230,236,229,120, + 128, 30,144,228,239,116,130, 1,123, 34,253, 35, 6,225,227,227, + 229,238,116,128, 1,123,226,229,236,239,119,128, 30,146,101, 3, + 35, 22, 35, 33, 35, 76,227,249,242,233,236,236,233, 99,128, 4, + 23,100, 2, 35, 39, 35, 58,229,243,227,229,238,228,229,242,227, + 249,242,233,236,236,233, 99,128, 4,152,233,229,242,229,243,233, + 243,227,249,242,233,236,236,233, 99,128, 4,222,244, 97,128, 3, + 150,232,101, 4, 35, 92, 35,103, 35,119, 35,130,225,242,237,229, + 238,233,225,110,128, 5, 58,226,242,229,246,229,227,249,242,233, + 236,236,233, 99,128, 4,193,227,249,242,233,236,236,233, 99,128, + 4, 22,100, 2, 35,136, 35,155,229,243,227,229,238,228,229,242, + 227,249,242,233,236,236,233, 99,128, 4,150,233,229,242,229,243, + 233,243,227,249,242,233,236,236,233, 99,128, 4,220,236,233,238, + 229,226,229,236,239,119,128, 30,148,237,239,238,239,243,240,225, + 227,101,128,255, 58,115, 2, 35,203, 35,210,237,225,236,108,128, + 247,122,244,242,239,235,101,128, 1,181, 97,158, 0, 97, 36, 26, + 38,154, 39, 4, 39, 68, 39,132, 39,196, 40, 4, 40, 68, 40,126, + 40,190, 41, 70, 41,217, 42,137, 42,237, 43, 17, 49,192, 49,229, + 50, 0, 50,225, 51, 7, 52, 96, 52,168, 53,123, 53,132, 54, 5, + 56, 13, 57, 3, 57, 50, 57,201, 57,215, 49,138, 39, 1, 36, 50, + 36,114, 36,154, 36,218, 37, 26, 37, 90, 37,154, 37,218, 38, 26, + 38, 90, 48,138, 39, 33, 36, 74, 36, 78, 36, 82, 36, 86, 36, 90, + 36, 94, 36, 98, 36,102, 36,106, 36,110, 48,128, 39, 94, 49,128, + 39, 97, 50,128, 39, 98, 51,128, 39, 99, 52,128, 39,100, 53,128, + 39, 16, 54,128, 39,101, 55,128, 39,102, 56,128, 39,103, 57,128, + 38, 96, 49,134, 38, 27, 36,130, 36,134, 36,138, 36,142, 36,146, + 36,150, 48,128, 38,101, 49,128, 38,102, 50,128, 38, 99, 55,128, + 39, 9, 56,128, 39, 8, 57,128, 39, 7, 50,138, 38, 30, 36,178, + 36,182, 36,186, 36,190, 36,194, 36,198, 36,202, 36,206, 36,210, + 36,214, 48,128, 36, 96, 49,128, 36, 97, 50,128, 36, 98, 51,128, + 36, 99, 52,128, 36,100, 53,128, 36,101, 54,128, 36,102, 55,128, + 36,103, 56,128, 36,104, 57,128, 36,105, 51,138, 39, 12, 36,242, + 36,246, 36,250, 36,254, 37, 2, 37, 6, 37, 10, 37, 14, 37, 18, + 37, 22, 48,128, 39,118, 49,128, 39,119, 50,128, 39,120, 51,128, + 39,121, 52,128, 39,122, 53,128, 39,123, 54,128, 39,124, 55,128, + 39,125, 56,128, 39,126, 57,128, 39,127, 52,138, 39, 13, 37, 50, + 37, 54, 37, 58, 37, 62, 37, 66, 37, 70, 37, 74, 37, 78, 37, 82, + 37, 86, 48,128, 39,128, 49,128, 39,129, 50,128, 39,130, 51,128, + 39,131, 52,128, 39,132, 53,128, 39,133, 54,128, 39,134, 55,128, + 39,135, 56,128, 39,136, 57,128, 39,137, 53,138, 39, 14, 37,114, + 37,118, 37,122, 37,126, 37,130, 37,134, 37,138, 37,142, 37,146, + 37,150, 48,128, 39,138, 49,128, 39,139, 50,128, 39,140, 51,128, + 39,141, 52,128, 39,142, 53,128, 39,143, 54,128, 39,144, 55,128, + 39,145, 56,128, 39,146, 57,128, 39,147, 54,138, 39, 15, 37,178, + 37,182, 37,186, 37,190, 37,194, 37,198, 37,202, 37,206, 37,210, + 37,214, 48,128, 39,148, 49,128, 33,146, 50,128, 39,163, 51,128, + 33,148, 52,128, 33,149, 53,128, 39,153, 54,128, 39,155, 55,128, + 39,156, 56,128, 39,157, 57,128, 39,158, 55,138, 39, 17, 37,242, + 37,246, 37,250, 37,254, 38, 2, 38, 6, 38, 10, 38, 14, 38, 18, + 38, 22, 48,128, 39,159, 49,128, 39,160, 50,128, 39,161, 51,128, + 39,162, 52,128, 39,164, 53,128, 39,165, 54,128, 39,166, 55,128, + 39,167, 56,128, 39,168, 57,128, 39,169, 56,138, 39, 18, 38, 50, + 38, 54, 38, 58, 38, 62, 38, 66, 38, 70, 38, 74, 38, 78, 38, 82, + 38, 86, 48,128, 39,171, 49,128, 39,173, 50,128, 39,175, 51,128, + 39,178, 52,128, 39,179, 53,128, 39,181, 54,128, 39,184, 55,128, + 39,186, 56,128, 39,187, 57,128, 39,188, 57,138, 39, 19, 38,114, + 38,118, 38,122, 38,126, 38,130, 38,134, 38,138, 38,142, 38,146, + 38,150, 48,128, 39,189, 49,128, 39,190, 50,128, 39,154, 51,128, + 39,170, 52,128, 39,182, 53,128, 39,185, 54,128, 39,152, 55,128, + 39,180, 56,128, 39,183, 57,128, 39,172, 50,138, 39, 2, 38,178, + 38,224, 38,228, 38,232, 38,236, 38,240, 38,244, 38,248, 38,252, + 39, 0, 48,135, 39, 20, 38,196, 38,200, 38,204, 38,208, 38,212, + 38,216, 38,220, 48,128, 39,174, 49,128, 39,177, 50,128, 39, 3, + 51,128, 39, 80, 52,128, 39, 82, 53,128, 39,110, 54,128, 39,112, + 49,128, 39, 21, 50,128, 39, 22, 51,128, 39, 23, 52,128, 39, 24, + 53,128, 39, 25, 54,128, 39, 26, 55,128, 39, 27, 56,128, 39, 28, + 57,128, 39, 34, 51,138, 39, 4, 39, 28, 39, 32, 39, 36, 39, 40, + 39, 44, 39, 48, 39, 52, 39, 56, 39, 60, 39, 64, 48,128, 39, 35, + 49,128, 39, 36, 50,128, 39, 37, 51,128, 39, 38, 52,128, 39, 39, + 53,128, 38, 5, 54,128, 39, 41, 55,128, 39, 42, 56,128, 39, 43, + 57,128, 39, 44, 52,138, 38, 14, 39, 92, 39, 96, 39,100, 39,104, + 39,108, 39,112, 39,116, 39,120, 39,124, 39,128, 48,128, 39, 45, + 49,128, 39, 46, 50,128, 39, 47, 51,128, 39, 48, 52,128, 39, 49, + 53,128, 39, 50, 54,128, 39, 51, 55,128, 39, 52, 56,128, 39, 53, + 57,128, 39, 54, 53,138, 39, 6, 39,156, 39,160, 39,164, 39,168, + 39,172, 39,176, 39,180, 39,184, 39,188, 39,192, 48,128, 39, 55, + 49,128, 39, 56, 50,128, 39, 57, 51,128, 39, 58, 52,128, 39, 59, + 53,128, 39, 60, 54,128, 39, 61, 55,128, 39, 62, 56,128, 39, 63, + 57,128, 39, 64, 54,138, 39, 29, 39,220, 39,224, 39,228, 39,232, + 39,236, 39,240, 39,244, 39,248, 39,252, 40, 0, 48,128, 39, 65, + 49,128, 39, 66, 50,128, 39, 67, 51,128, 39, 68, 52,128, 39, 69, + 53,128, 39, 70, 54,128, 39, 71, 55,128, 39, 72, 56,128, 39, 73, + 57,128, 39, 74, 55,138, 39, 30, 40, 28, 40, 32, 40, 36, 40, 40, + 40, 44, 40, 48, 40, 52, 40, 56, 40, 60, 40, 64, 48,128, 39, 75, + 49,128, 37,207, 50,128, 39, 77, 51,128, 37,160, 52,128, 39, 79, + 53,128, 39, 81, 54,128, 37,178, 55,128, 37,188, 56,128, 37,198, + 57,128, 39, 86, 56,137, 39, 31, 40, 90, 40, 94, 40, 98, 40,102, + 40,106, 40,110, 40,114, 40,118, 40,122, 49,128, 37,215, 50,128, + 39, 88, 51,128, 39, 89, 52,128, 39, 90, 53,128, 39,111, 54,128, + 39,113, 55,128, 39,114, 56,128, 39,115, 57,128, 39,104, 57,138, + 39, 32, 40,150, 40,154, 40,158, 40,162, 40,166, 40,170, 40,174, + 40,178, 40,182, 40,186, 48,128, 39,105, 49,128, 39,108, 50,128, + 39,109, 51,128, 39,106, 52,128, 39,107, 53,128, 39,116, 54,128, + 39,117, 55,128, 39, 91, 56,128, 39, 92, 57,128, 39, 93, 97, 7, + 40,206, 40,216, 40,223, 40,230, 40,255, 41, 15, 41, 26,226,229, + 238,231,225,236,105,128, 9,134,227,245,244,101,128, 0,225,228, + 229,246, 97,128, 9, 6,231,117, 2, 40,237, 40,246,234,225,242, + 225,244,105,128, 10,134,242,237,245,235,232,105,128, 10, 6,237, + 225,244,242,225,231,245,242,237,245,235,232,105,128, 10, 62,242, + 245,243,241,245,225,242,101,128, 51, 3,246,239,247,229,236,243, + 233,231,110, 3, 41, 42, 41, 52, 41, 59,226,229,238,231,225,236, + 105,128, 9,190,228,229,246, 97,128, 9, 62,231,245,234,225,242, + 225,244,105,128, 10,190, 98, 4, 41, 80, 41,121, 41,130, 41,140, + 226,242,229,246,233,225,244,233,239,110, 2, 41, 95, 41,110,237, + 225,242,235,225,242,237,229,238,233,225,110,128, 5, 95,243,233, + 231,238,228,229,246, 97,128, 9,112,229,238,231,225,236,105,128, + 9,133,239,240,239,237,239,230,111,128, 49, 26,242,229,246,101, + 134, 1, 3, 41,159, 41,167, 41,178, 41,189, 41,197, 41,209,225, + 227,245,244,101,128, 30,175,227,249,242,233,236,236,233, 99,128, + 4,209,228,239,244,226,229,236,239,119,128, 30,183,231,242,225, + 246,101,128, 30,177,232,239,239,235,225,226,239,246,101,128, 30, + 179,244,233,236,228,101,128, 30,181, 99, 4, 41,227, 41,234, 42, + 57, 42,127,225,242,239,110,128, 1,206,233,242, 99, 2, 41,242, + 41,247,236,101,128, 36,208,245,237,230,236,229,120,133, 0,226, + 42, 10, 42, 18, 42, 29, 42, 37, 42, 49,225,227,245,244,101,128, + 30,165,228,239,244,226,229,236,239,119,128, 30,173,231,242,225, + 246,101,128, 30,167,232,239,239,235,225,226,239,246,101,128, 30, + 169,244,233,236,228,101,128, 30,171,245,244,101,133, 0,180, 42, + 73, 42, 84, 42,101, 42,108, 42,117,226,229,236,239,247,227,237, + 98,128, 3, 23, 99, 2, 42, 90, 42, 95,237, 98,128, 3, 1,239, + 237, 98,128, 3, 1,228,229,246, 97,128, 9, 84,236,239,247,237, + 239,100,128, 2,207,244,239,238,229,227,237, 98,128, 3, 65,249, + 242,233,236,236,233, 99,128, 4, 48,100, 5, 42,149, 42,159, 42, + 173, 42,179, 42,213,226,236,231,242,225,246,101,128, 2, 1,228, + 225,235,231,245,242,237,245,235,232,105,128, 10,113,229,246, 97, + 128, 9, 5,233,229,242,229,243,233,115,130, 0,228, 42,193, 42, + 204,227,249,242,233,236,236,233, 99,128, 4,211,237,225,227,242, + 239,110,128, 1,223,239,116, 2, 42,220, 42,228,226,229,236,239, + 119,128, 30,161,237,225,227,242,239,110,128, 1,225,101,131, 0, + 230, 42,247, 42,255, 43, 8,225,227,245,244,101,128, 1,253,235, + 239,242,229,225,110,128, 49, 80,237,225,227,242,239,110,128, 1, + 227,230,233,105, 6, 43, 33, 43, 53, 45,246, 45,252, 46, 11, 49, + 111, 48, 2, 43, 39, 43, 46,176,178,176, 56,128, 32, 21,184,185, + 180, 49,128, 32,164,177, 48, 3, 43, 62, 45, 86, 45,221, 48, 9, + 43, 82, 43,102, 43,164, 43,226, 44, 32, 44, 94, 44,156, 44,218, + 45, 24, 49, 3, 43, 90, 43, 94, 43, 98, 55,128, 4, 16, 56,128, + 4, 17, 57,128, 4, 18, 50, 10, 43,124, 43,128, 43,132, 43,136, + 43,140, 43,144, 43,148, 43,152, 43,156, 43,160, 48,128, 4, 19, + 49,128, 4, 20, 50,128, 4, 21, 51,128, 4, 1, 52,128, 4, 22, + 53,128, 4, 23, 54,128, 4, 24, 55,128, 4, 25, 56,128, 4, 26, + 57,128, 4, 27, 51, 10, 43,186, 43,190, 43,194, 43,198, 43,202, + 43,206, 43,210, 43,214, 43,218, 43,222, 48,128, 4, 28, 49,128, + 4, 29, 50,128, 4, 30, 51,128, 4, 31, 52,128, 4, 32, 53,128, + 4, 33, 54,128, 4, 34, 55,128, 4, 35, 56,128, 4, 36, 57,128, + 4, 37, 52, 10, 43,248, 43,252, 44, 0, 44, 4, 44, 8, 44, 12, + 44, 16, 44, 20, 44, 24, 44, 28, 48,128, 4, 38, 49,128, 4, 39, + 50,128, 4, 40, 51,128, 4, 41, 52,128, 4, 42, 53,128, 4, 43, + 54,128, 4, 44, 55,128, 4, 45, 56,128, 4, 46, 57,128, 4, 47, + 53, 10, 44, 54, 44, 58, 44, 62, 44, 66, 44, 70, 44, 74, 44, 78, + 44, 82, 44, 86, 44, 90, 48,128, 4,144, 49,128, 4, 2, 50,128, + 4, 3, 51,128, 4, 4, 52,128, 4, 5, 53,128, 4, 6, 54,128, + 4, 7, 55,128, 4, 8, 56,128, 4, 9, 57,128, 4, 10, 54, 10, + 44,116, 44,120, 44,124, 44,128, 44,132, 44,136, 44,140, 44,144, + 44,148, 44,152, 48,128, 4, 11, 49,128, 4, 12, 50,128, 4, 14, + 51,128,246,196, 52,128,246,197, 53,128, 4, 48, 54,128, 4, 49, + 55,128, 4, 50, 56,128, 4, 51, 57,128, 4, 52, 55, 10, 44,178, + 44,182, 44,186, 44,190, 44,194, 44,198, 44,202, 44,206, 44,210, + 44,214, 48,128, 4, 53, 49,128, 4, 81, 50,128, 4, 54, 51,128, + 4, 55, 52,128, 4, 56, 53,128, 4, 57, 54,128, 4, 58, 55,128, + 4, 59, 56,128, 4, 60, 57,128, 4, 61, 56, 10, 44,240, 44,244, + 44,248, 44,252, 45, 0, 45, 4, 45, 8, 45, 12, 45, 16, 45, 20, + 48,128, 4, 62, 49,128, 4, 63, 50,128, 4, 64, 51,128, 4, 65, + 52,128, 4, 66, 53,128, 4, 67, 54,128, 4, 68, 55,128, 4, 69, + 56,128, 4, 70, 57,128, 4, 71, 57, 10, 45, 46, 45, 50, 45, 54, + 45, 58, 45, 62, 45, 66, 45, 70, 45, 74, 45, 78, 45, 82, 48,128, + 4, 72, 49,128, 4, 73, 50,128, 4, 74, 51,128, 4, 75, 52,128, + 4, 76, 53,128, 4, 77, 54,128, 4, 78, 55,128, 4, 79, 56,128, + 4,145, 57,128, 4, 82, 49, 4, 45, 96, 45,158, 45,163, 45,189, + 48, 10, 45,118, 45,122, 45,126, 45,130, 45,134, 45,138, 45,142, + 45,146, 45,150, 45,154, 48,128, 4, 83, 49,128, 4, 84, 50,128, + 4, 85, 51,128, 4, 86, 52,128, 4, 87, 53,128, 4, 88, 54,128, + 4, 89, 55,128, 4, 90, 56,128, 4, 91, 57,128, 4, 92,177, 48, + 128, 4, 94, 52, 4, 45,173, 45,177, 45,181, 45,185, 53,128, 4, + 15, 54,128, 4, 98, 55,128, 4,114, 56,128, 4,116, 57, 5, 45, + 201, 45,205, 45,209, 45,213, 45,217, 50,128,246,198, 51,128, 4, + 95, 52,128, 4, 99, 53,128, 4,115, 54,128, 4,117, 56, 2, 45, + 227, 45,241, 51, 2, 45,233, 45,237, 49,128,246,199, 50,128,246, + 200,180, 54,128, 4,217,178,185, 57,128, 32, 14,179, 48, 2, 46, + 3, 46, 7, 48,128, 32, 15, 49,128, 32, 13,181, 55, 7, 46, 28, + 46, 98, 47,163, 47,240, 48,197, 49, 34, 49,105, 51, 2, 46, 34, + 46, 48, 56, 2, 46, 40, 46, 44, 49,128, 6,106, 56,128, 6, 12, + 57, 8, 46, 66, 46, 70, 46, 74, 46, 78, 46, 82, 46, 86, 46, 90, + 46, 94, 50,128, 6, 96, 51,128, 6, 97, 52,128, 6, 98, 53,128, + 6, 99, 54,128, 6,100, 55,128, 6,101, 56,128, 6,102, 57,128, + 6,103, 52, 7, 46,114, 46,146, 46,208, 47, 14, 47, 46, 47,102, + 47,158, 48, 5, 46,126, 46,130, 46,134, 46,138, 46,142, 48,128, + 6,104, 49,128, 6,105, 51,128, 6, 27, 55,128, 6, 31, 57,128, + 6, 33, 49, 10, 46,168, 46,172, 46,176, 46,180, 46,184, 46,188, + 46,192, 46,196, 46,200, 46,204, 48,128, 6, 34, 49,128, 6, 35, + 50,128, 6, 36, 51,128, 6, 37, 52,128, 6, 38, 53,128, 6, 39, + 54,128, 6, 40, 55,128, 6, 41, 56,128, 6, 42, 57,128, 6, 43, + 50, 10, 46,230, 46,234, 46,238, 46,242, 46,246, 46,250, 46,254, + 47, 2, 47, 6, 47, 10, 48,128, 6, 44, 49,128, 6, 45, 50,128, + 6, 46, 51,128, 6, 47, 52,128, 6, 48, 53,128, 6, 49, 54,128, + 6, 50, 55,128, 6, 51, 56,128, 6, 52, 57,128, 6, 53, 51, 5, + 47, 26, 47, 30, 47, 34, 47, 38, 47, 42, 48,128, 6, 54, 49,128, + 6, 55, 50,128, 6, 56, 51,128, 6, 57, 52,128, 6, 58, 52, 9, + 47, 66, 47, 70, 47, 74, 47, 78, 47, 82, 47, 86, 47, 90, 47, 94, + 47, 98, 48,128, 6, 64, 49,128, 6, 65, 50,128, 6, 66, 51,128, + 6, 67, 52,128, 6, 68, 53,128, 6, 69, 54,128, 6, 70, 56,128, + 6, 72, 57,128, 6, 73, 53, 9, 47,122, 47,126, 47,130, 47,134, + 47,138, 47,142, 47,146, 47,150, 47,154, 48,128, 6, 74, 49,128, + 6, 75, 50,128, 6, 76, 51,128, 6, 77, 52,128, 6, 78, 53,128, + 6, 79, 54,128, 6, 80, 55,128, 6, 81, 56,128, 6, 82,183, 48, + 128, 6, 71, 53, 3, 47,171, 47,203, 47,235, 48, 5, 47,183, 47, + 187, 47,191, 47,195, 47,199, 53,128, 6,164, 54,128, 6,126, 55, + 128, 6,134, 56,128, 6,152, 57,128, 6,175, 49, 5, 47,215, 47, + 219, 47,223, 47,227, 47,231, 49,128, 6,121, 50,128, 6,136, 51, + 128, 6,145, 52,128, 6,186, 57,128, 6,210,179, 52,128, 6,213, + 54, 7, 48, 0, 48, 5, 48, 10, 48, 15, 48, 53, 48,115, 48,177, + 179, 54,128, 32,170,180, 53,128, 5,190,181, 56,128, 5,195, 54, + 6, 48, 29, 48, 33, 48, 37, 48, 41, 48, 45, 48, 49, 52,128, 5, + 208, 53,128, 5,209, 54,128, 5,210, 55,128, 5,211, 56,128, 5, + 212, 57,128, 5,213, 55, 10, 48, 75, 48, 79, 48, 83, 48, 87, 48, + 91, 48, 95, 48, 99, 48,103, 48,107, 48,111, 48,128, 5,214, 49, + 128, 5,215, 50,128, 5,216, 51,128, 5,217, 52,128, 5,218, 53, + 128, 5,219, 54,128, 5,220, 55,128, 5,221, 56,128, 5,222, 57, + 128, 5,223, 56, 10, 48,137, 48,141, 48,145, 48,149, 48,153, 48, + 157, 48,161, 48,165, 48,169, 48,173, 48,128, 5,224, 49,128, 5, + 225, 50,128, 5,226, 51,128, 5,227, 52,128, 5,228, 53,128, 5, + 229, 54,128, 5,230, 55,128, 5,231, 56,128, 5,232, 57,128, 5, + 233, 57, 3, 48,185, 48,189, 48,193, 48,128, 5,234, 52,128,251, + 42, 53,128,251, 43, 55, 4, 48,207, 48,221, 48,241, 48,246, 48, + 2, 48,213, 48,217, 48,128,251, 75, 53,128,251, 31, 49, 3, 48, + 229, 48,233, 48,237, 54,128, 5,240, 55,128, 5,241, 56,128, 5, + 242,178, 51,128,251, 53, 57, 7, 49, 6, 49, 10, 49, 14, 49, 18, + 49, 22, 49, 26, 49, 30, 51,128, 5,180, 52,128, 5,181, 53,128, + 5,182, 54,128, 5,187, 55,128, 5,184, 56,128, 5,183, 57,128, + 5,176, 56, 3, 49, 42, 49, 86, 49, 91, 48, 7, 49, 58, 49, 62, + 49, 66, 49, 70, 49, 74, 49, 78, 49, 82, 48,128, 5,178, 49,128, + 5,177, 50,128, 5,179, 51,128, 5,194, 52,128, 5,193, 54,128, + 5,185, 55,128, 5,188,179, 57,128, 5,189, 52, 2, 49, 97, 49, + 101, 49,128, 5,191, 50,128, 5,192,185,178, 57,128, 2,188, 54, + 3, 49,119, 49,178, 49,185, 49, 4, 49,129, 49,145, 49,151, 49, + 172, 50, 2, 49,135, 49,140,180, 56,128, 33, 5,184, 57,128, 33, + 19,179,181, 50,128, 33, 22,181, 55, 3, 49,160, 49,164, 49,168, + 51,128, 32, 44, 52,128, 32, 45, 53,128, 32, 46,182,182, 52,128, + 32, 12,179,177,182, 55,128, 6,109,180,185,179, 55,128, 2,189, + 103, 2, 49,198, 49,205,242,225,246,101,128, 0,224,117, 2, 49, + 211, 49,220,234,225,242,225,244,105,128, 10,133,242,237,245,235, + 232,105,128, 10, 5,104, 2, 49,235, 49,245,233,242,225,231,225, + 238, 97,128, 48, 66,239,239,235,225,226,239,246,101,128, 30,163, + 105, 7, 50, 16, 50, 41, 50, 48, 50, 60, 50, 85, 50,101, 50,181, + 98, 2, 50, 22, 50, 31,229,238,231,225,236,105,128, 9,144,239, + 240,239,237,239,230,111,128, 49, 30,228,229,246, 97,128, 9, 16, + 229,227,249,242,233,236,236,233, 99,128, 4,213,231,117, 2, 50, + 67, 50, 76,234,225,242,225,244,105,128, 10,144,242,237,245,235, + 232,105,128, 10, 16,237,225,244,242,225,231,245,242,237,245,235, + 232,105,128, 10, 72,110, 5, 50,113, 50,122, 50,136, 50,152, 50, + 167,225,242,225,226,233, 99,128, 6, 57,230,233,238,225,236,225, + 242,225,226,233, 99,128,254,202,233,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,254,203,237,229,228,233,225,236,225,242, + 225,226,233, 99,128,254,204,246,229,242,244,229,228,226,242,229, + 246,101,128, 2, 3,246,239,247,229,236,243,233,231,110, 3, 50, + 197, 50,207, 50,214,226,229,238,231,225,236,105,128, 9,200,228, + 229,246, 97,128, 9, 72,231,245,234,225,242,225,244,105,128, 10, + 200,107, 2, 50,231, 50,255,225,244,225,235,225,238, 97,129, 48, + 162, 50,243,232,225,236,230,247,233,228,244,104,128,255,113,239, + 242,229,225,110,128, 49, 79,108, 3, 51, 15, 52, 71, 52, 80,101, + 2, 51, 21, 52, 66,102,136, 5,208, 51, 41, 51, 50, 51, 65, 51, + 79, 51,168, 51,182, 52, 37, 52, 51,225,242,225,226,233, 99,128, + 6, 39,228,225,231,229,243,232,232,229,226,242,229,119,128,251, + 48,230,233,238,225,236,225,242,225,226,233, 99,128,254,142,104, + 2, 51, 85, 51,160,225,237,250, 97, 2, 51, 94, 51,127,225,226, + 239,246,101, 2, 51,104, 51,113,225,242,225,226,233, 99,128, 6, + 35,230,233,238,225,236,225,242,225,226,233, 99,128,254,132,226, + 229,236,239,119, 2, 51,137, 51,146,225,242,225,226,233, 99,128, + 6, 37,230,233,238,225,236,225,242,225,226,233, 99,128,254,136, + 229,226,242,229,119,128, 5,208,236,225,237,229,228,232,229,226, + 242,229,119,128,251, 79,237, 97, 2, 51,189, 51,225,228,228,225, + 225,226,239,246,101, 2, 51,202, 51,211,225,242,225,226,233, 99, + 128, 6, 34,230,233,238,225,236,225,242,225,226,233, 99,128,254, + 130,235,243,245,242, 97, 4, 51,239, 51,248, 52, 6, 52, 22,225, + 242,225,226,233, 99,128, 6, 73,230,233,238,225,236,225,242,225, + 226,233, 99,128,254,240,233,238,233,244,233,225,236,225,242,225, + 226,233, 99,128,254,243,237,229,228,233,225,236,225,242,225,226, + 233, 99,128,254,244,240,225,244,225,232,232,229,226,242,229,119, + 128,251, 46,241,225,237,225,244,243,232,229,226,242,229,119,128, + 251, 47,240,104,128, 33, 53,236,229,241,245,225,108,128, 34, 76, + 240,232, 97,129, 3,177, 52, 88,244,239,238,239,115,128, 3,172, + 109, 4, 52,106, 52,114, 52,125, 52,159,225,227,242,239,110,128, + 1, 1,239,238,239,243,240,225,227,101,128,255, 65,240,229,242, + 243,225,238,100,130, 0, 38, 52,139, 52,151,237,239,238,239,243, + 240,225,227,101,128,255, 6,243,237,225,236,108,128,247, 38,243, + 241,245,225,242,101,128, 51,194,110, 4, 52,178, 52,189, 53, 55, + 53, 65,226,239,240,239,237,239,230,111,128, 49, 34,103, 4, 52, + 199, 52,210, 52,224, 53, 47,226,239,240,239,237,239,230,111,128, + 49, 36,235,232,225,238,235,232,245,244,232,225,105,128, 14, 90, + 236,101,131, 34, 32, 52,235, 53, 32, 53, 39,226,242,225,227,235, + 229,116, 2, 52,247, 53, 11,236,229,230,116,129, 48, 8, 53, 0, + 246,229,242,244,233,227,225,108,128,254, 63,242,233,231,232,116, + 129, 48, 9, 53, 21,246,229,242,244,233,227,225,108,128,254, 64, + 236,229,230,116,128, 35, 41,242,233,231,232,116,128, 35, 42,243, + 244,242,239,109,128, 33, 43,239,244,229,236,229,233, 97,128, 3, + 135,117, 2, 53, 71, 53, 83,228,225,244,244,225,228,229,246, 97, + 128, 9, 82,243,246,225,242, 97, 3, 53, 95, 53,105, 53,112,226, + 229,238,231,225,236,105,128, 9,130,228,229,246, 97,128, 9, 2, + 231,245,234,225,242,225,244,105,128, 10,130,239,231,239,238,229, + 107,128, 1, 5,112, 3, 53,140, 53,164, 53,194, 97, 2, 53,146, + 53,158,225,244,239,243,241,245,225,242,101,128, 51, 0,242,229, + 110,128, 36,156,239,243,244,242,239,240,232,101, 2, 53,177, 53, + 188,225,242,237,229,238,233,225,110,128, 5, 90,237,239,100,128, + 2,188,112, 2, 53,200, 53,205,236,101,128,248,255,242,111, 2, + 53,212, 53,220,225,227,232,229,115,128, 34, 80,120, 2, 53,226, + 53,246,229,241,245,225,108,129, 34, 72, 53,236,239,242,233,237, + 225,231,101,128, 34, 82,233,237,225,244,229,236,249,229,241,245, + 225,108,128, 34, 69,114, 4, 54, 15, 54, 42, 54, 46, 54, 91,225, + 229, 97, 2, 54, 23, 54, 33,229,235,239,242,229,225,110,128, 49, + 142,235,239,242,229,225,110,128, 49,141, 99,128, 35, 18,105, 2, + 54, 52, 54, 66,231,232,244,232,225,236,230,242,233,238,103,128, + 30,154,238,103,130, 0,229, 54, 75, 54, 83,225,227,245,244,101, + 128, 1,251,226,229,236,239,119,128, 30, 1,242,239,119, 8, 54, + 111, 54,118, 54,247, 55, 57, 55,107, 55,162, 55,185, 56, 4,226, + 239,244,104,128, 33,148,100, 3, 54,126, 54,165, 54,212,225,243, + 104, 4, 54,138, 54,145, 54,152, 54,160,228,239,247,110,128, 33, + 227,236,229,230,116,128, 33,224,242,233,231,232,116,128, 33,226, + 245,112,128, 33,225,226,108, 5, 54,178, 54,185, 54,192, 54,199, + 54,207,226,239,244,104,128, 33,212,228,239,247,110,128, 33,211, + 236,229,230,116,128, 33,208,242,233,231,232,116,128, 33,210,245, + 112,128, 33,209,239,247,110,131, 33,147, 54,224, 54,231, 54,239, + 236,229,230,116,128, 33,153,242,233,231,232,116,128, 33,152,247, + 232,233,244,101,128, 33,233,104, 2, 54,253, 55, 48,229,225,100, + 4, 55, 9, 55, 19, 55, 29, 55, 40,228,239,247,238,237,239,100, + 128, 2,197,236,229,230,244,237,239,100,128, 2,194,242,233,231, + 232,244,237,239,100,128, 2,195,245,240,237,239,100,128, 2,196, + 239,242,233,250,229,120,128,248,231,236,229,230,116,131, 33,144, + 55, 70, 55, 87, 55, 99,228,226,108,129, 33,208, 55, 78,243,244, + 242,239,235,101,128, 33,205,239,246,229,242,242,233,231,232,116, + 128, 33,198,247,232,233,244,101,128, 33,230,242,233,231,232,116, + 132, 33,146, 55,123, 55,135, 55,143, 55,154,228,226,236,243,244, + 242,239,235,101,128, 33,207,232,229,225,246,121,128, 39,158,239, + 246,229,242,236,229,230,116,128, 33,196,247,232,233,244,101,128, + 33,232,244,225, 98, 2, 55,170, 55,177,236,229,230,116,128, 33, + 228,242,233,231,232,116,128, 33,229,245,112,132, 33,145, 55,198, + 55,226, 55,244, 55,252,100, 2, 55,204, 55,216,110,129, 33,149, + 55,210,226,243,101,128, 33,168,239,247,238,226,225,243,101,128, + 33,168,236,229,230,116,129, 33,150, 55,235,239,230,228,239,247, + 110,128, 33,197,242,233,231,232,116,128, 33,151,247,232,233,244, + 101,128, 33,231,246,229,242,244,229,120,128,248,230,115, 5, 56, + 25, 56,101, 56,146, 56,229, 56,239, 99, 2, 56, 31, 56, 83,233, + 105, 2, 56, 38, 56, 61,227,233,242,227,245,109,129, 0, 94, 56, + 49,237,239,238,239,243,240,225,227,101,128,255, 62,244,233,236, + 228,101,129, 0,126, 56, 71,237,239,238,239,243,240,225,227,101, + 128,255, 94,242,233,240,116,129, 2, 81, 56, 92,244,245,242,238, + 229,100,128, 2, 82,237,225,236,108, 2, 56,110, 56,121,232,233, + 242,225,231,225,238, 97,128, 48, 65,235,225,244,225,235,225,238, + 97,129, 48,161, 56,134,232,225,236,230,247,233,228,244,104,128, + 255,103,244,229,242,233,115, 2, 56,156, 56,225,107,131, 0, 42, + 56,166, 56,194, 56,217, 97, 2, 56,172, 56,186,236,244,239,238, + 229,225,242,225,226,233, 99,128, 6,109,242,225,226,233, 99,128, + 6,109,109, 2, 56,200, 56,206,225,244,104,128, 34, 23,239,238, + 239,243,240,225,227,101,128,255, 10,243,237,225,236,108,128,254, + 97,109,128, 32, 66,245,240,229,242,233,239,114,128,246,233,249, + 237,240,244,239,244,233,227,225,236,236,249,229,241,245,225,108, + 128, 34, 67,116,132, 0, 64, 57, 15, 57, 22, 57, 34, 57, 42,233, + 236,228,101,128, 0,227,237,239,238,239,243,240,225,227,101,128, + 255, 32,243,237,225,236,108,128,254,107,245,242,238,229,100,128, + 2, 80,117, 6, 57, 64, 57, 89, 57, 96, 57,121, 57,141, 57,157, + 98, 2, 57, 70, 57, 79,229,238,231,225,236,105,128, 9,148,239, + 240,239,237,239,230,111,128, 49, 32,228,229,246, 97,128, 9, 20, + 231,117, 2, 57,103, 57,112,234,225,242,225,244,105,128, 10,148, + 242,237,245,235,232,105,128, 10, 20,236,229,238,231,244,232,237, + 225,242,235,226,229,238,231,225,236,105,128, 9,215,237,225,244, + 242,225,231,245,242,237,245,235,232,105,128, 10, 76,246,239,247, + 229,236,243,233,231,110, 3, 57,173, 57,183, 57,190,226,229,238, + 231,225,236,105,128, 9,204,228,229,246, 97,128, 9, 76,231,245, + 234,225,242,225,244,105,128, 10,204,246,225,231,242,225,232,225, + 228,229,246, 97,128, 9, 61,121, 2, 57,221, 57,233,226,225,242, + 237,229,238,233,225,110,128, 5, 97,233,110,130, 5,226, 57,242, + 58, 1,225,236,244,239,238,229,232,229,226,242,229,119,128,251, + 32,232,229,226,242,229,119,128, 5,226, 98,144, 0, 98, 58, 46, + 58,181, 58,192, 58,201, 58,226, 60, 11, 60, 73, 60,146, 62, 72, + 62, 84, 62,127, 62,135, 62,145, 64, 15, 64, 39, 64, 48, 97, 7, + 58, 62, 58, 72, 58, 96, 58,103, 58,128, 58,152, 58,163,226,229, + 238,231,225,236,105,128, 9,172,227,235,243,236,225,243,104,129, + 0, 92, 58, 84,237,239,238,239,243,240,225,227,101,128,255, 60, + 228,229,246, 97,128, 9, 44,231,117, 2, 58,110, 58,119,234,225, + 242,225,244,105,128, 10,172,242,237,245,235,232,105,128, 10, 44, + 104, 2, 58,134, 58,144,233,242,225,231,225,238, 97,128, 48,112, + 244,244,232,225,105,128, 14, 63,235,225,244,225,235,225,238, 97, + 128, 48,208,114,129, 0,124, 58,169,237,239,238,239,243,240,225, + 227,101,128,255, 92,226,239,240,239,237,239,230,111,128, 49, 5, + 227,233,242,227,236,101,128, 36,209,228,239,116, 2, 58,209, 58, + 218,225,227,227,229,238,116,128, 30, 3,226,229,236,239,119,128, + 30, 5,101, 6, 58,240, 59, 5, 59, 28, 59,170, 59,181, 59,193, + 225,237,229,228,243,233,248,244,229,229,238,244,232,238,239,244, + 229,115,128, 38,108, 99, 2, 59, 11, 59, 18,225,245,243,101,128, + 34, 53,249,242,233,236,236,233, 99,128, 4, 49,104, 5, 59, 40, + 59, 49, 59, 63, 59, 93, 59,152,225,242,225,226,233, 99,128, 6, + 40,230,233,238,225,236,225,242,225,226,233, 99,128,254,144,105, + 2, 59, 69, 59, 84,238,233,244,233,225,236,225,242,225,226,233, + 99,128,254,145,242,225,231,225,238, 97,128, 48,121,237,101, 2, + 59,100, 59,113,228,233,225,236,225,242,225,226,233, 99,128,254, + 146,229,237,105, 2, 59,121, 59,136,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,252,159,243,239,236,225,244,229,228,225, + 242,225,226,233, 99,128,252, 8,238,239,239,238,230,233,238,225, + 236,225,242,225,226,233, 99,128,252,109,235,225,244,225,235,225, + 238, 97,128, 48,217,238,225,242,237,229,238,233,225,110,128, 5, + 98,116,132, 5,209, 59,205, 59,225, 59,245, 59,254, 97,129, 3, + 178, 59,211,243,249,237,226,239,236,231,242,229,229,107,128, 3, + 208,228,225,231,229,243,104,129,251, 49, 59,236,232,229,226,242, + 229,119,128,251, 49,232,229,226,242,229,119,128, 5,209,242,225, + 230,229,232,229,226,242,229,119,128,251, 76,104, 2, 60, 17, 60, + 67, 97, 3, 60, 25, 60, 35, 60, 42,226,229,238,231,225,236,105, + 128, 9,173,228,229,246, 97,128, 9, 45,231,117, 2, 60, 49, 60, + 58,234,225,242,225,244,105,128, 10,173,242,237,245,235,232,105, + 128, 10, 45,239,239,107,128, 2, 83,105, 5, 60, 85, 60, 96, 60, + 107, 60,121, 60,135,232,233,242,225,231,225,238, 97,128, 48,115, + 235,225,244,225,235,225,238, 97,128, 48,211,236,225,226,233,225, + 236,227,236,233,227,107,128, 2,152,238,228,233,231,245,242,237, + 245,235,232,105,128, 10, 2,242,245,243,241,245,225,242,101,128, + 51, 49,108, 3, 60,154, 62, 55, 62, 66, 97, 2, 60,160, 62, 50, + 227,107, 6, 60,175, 60,184, 60,221, 61,114, 61,169, 61,221,227, + 233,242,227,236,101,128, 37,207,100, 2, 60,190, 60,199,233,225, + 237,239,238,100,128, 37,198,239,247,238,240,239,233,238,244,233, + 238,231,244,242,233,225,238,231,236,101,128, 37,188,108, 2, 60, + 227, 61, 74,101, 2, 60,233, 61, 13,230,244,240,239,233,238,244, + 233,238,103, 2, 60,248, 61, 2,240,239,233,238,244,229,114,128, + 37,196,244,242,233,225,238,231,236,101,128, 37,192,238,244,233, + 227,245,236,225,242,226,242,225,227,235,229,116, 2, 61, 33, 61, + 53,236,229,230,116,129, 48, 16, 61, 42,246,229,242,244,233,227, + 225,108,128,254, 59,242,233,231,232,116,129, 48, 17, 61, 63,246, + 229,242,244,233,227,225,108,128,254, 60,239,247,229,114, 2, 61, + 83, 61, 98,236,229,230,244,244,242,233,225,238,231,236,101,128, + 37,227,242,233,231,232,244,244,242,233,225,238,231,236,101,128, + 37,226,114, 2, 61,120, 61,131,229,227,244,225,238,231,236,101, + 128, 37,172,233,231,232,244,240,239,233,238,244,233,238,103, 2, + 61,148, 61,158,240,239,233,238,244,229,114,128, 37,186,244,242, + 233,225,238,231,236,101,128, 37,182,115, 3, 61,177, 61,207, 61, + 215,109, 2, 61,183, 61,195,225,236,236,243,241,245,225,242,101, + 128, 37,170,233,236,233,238,231,230,225,227,101,128, 38, 59,241, + 245,225,242,101,128, 37,160,244,225,114,128, 38, 5,245,240,112, + 2, 61,229, 62, 11,229,114, 2, 61,236, 61,251,236,229,230,244, + 244,242,233,225,238,231,236,101,128, 37,228,242,233,231,232,244, + 244,242,233,225,238,231,236,101,128, 37,229,239,233,238,244,233, + 238,103, 2, 62, 23, 62, 39,243,237,225,236,236,244,242,233,225, + 238,231,236,101,128, 37,180,244,242,233,225,238,231,236,101,128, + 37,178,238,107,128, 36, 35,233,238,229,226,229,236,239,119,128, + 30, 7,239,227,107,128, 37,136,237,239,238,239,243,240,225,227, + 101,128,255, 66,111, 3, 62, 92, 62,105, 62,116,226,225,233,237, + 225,233,244,232,225,105,128, 14, 26,232,233,242,225,231,225,238, + 97,128, 48,124,235,225,244,225,235,225,238, 97,128, 48,220,240, + 225,242,229,110,128, 36,157,241,243,241,245,225,242,101,128, 51, + 195,114, 4, 62,155, 63,149, 63,222, 64, 5,225, 99, 2, 62,162, + 63, 56,101, 3, 62,170, 62,175, 62,243,229,120,128,248,244,236, + 229,230,116,133, 0,123, 62,192, 62,197, 62,219, 62,227, 62,232, + 226,116,128,248,243,109, 2, 62,203, 62,208,233,100,128,248,242, + 239,238,239,243,240,225,227,101,128,255, 91,243,237,225,236,108, + 128,254, 91,244,112,128,248,241,246,229,242,244,233,227,225,108, + 128,254, 55,242,233,231,232,116,133, 0,125, 63, 5, 63, 10, 63, + 32, 63, 40, 63, 45,226,116,128,248,254,109, 2, 63, 16, 63, 21, + 233,100,128,248,253,239,238,239,243,240,225,227,101,128,255, 93, + 243,237,225,236,108,128,254, 92,244,112,128,248,252,246,229,242, + 244,233,227,225,108,128,254, 56,235,229,116, 2, 63, 64, 63,106, + 236,229,230,116,132, 0, 91, 63, 79, 63, 84, 63, 89, 63,101,226, + 116,128,248,240,229,120,128,248,239,237,239,238,239,243,240,225, + 227,101,128,255, 59,244,112,128,248,238,242,233,231,232,116,132, + 0, 93, 63,122, 63,127, 63,132, 63,144,226,116,128,248,251,229, + 120,128,248,250,237,239,238,239,243,240,225,227,101,128,255, 61, + 244,112,128,248,249,229,246,101,131, 2,216, 63,161, 63,172, 63, + 178,226,229,236,239,247,227,237, 98,128, 3, 46,227,237, 98,128, + 3, 6,233,238,246,229,242,244,229,100, 3, 63,193, 63,204, 63, + 210,226,229,236,239,247,227,237, 98,128, 3, 47,227,237, 98,128, + 3, 17,228,239,245,226,236,229,227,237, 98,128, 3, 97,233,228, + 231,101, 2, 63,231, 63,242,226,229,236,239,247,227,237, 98,128, + 3, 42,233,238,246,229,242,244,229,228,226,229,236,239,247,227, + 237, 98,128, 3, 58,239,235,229,238,226,225,114,128, 0,166,115, + 2, 64, 21, 64, 29,244,242,239,235,101,128, 1,128,245,240,229, + 242,233,239,114,128,246,234,244,239,240,226,225,114,128, 1,131, + 117, 3, 64, 56, 64, 67, 64, 78,232,233,242,225,231,225,238, 97, + 128, 48,118,235,225,244,225,235,225,238, 97,128, 48,214,236,108, + 2, 64, 85, 64,115,229,116,130, 32, 34, 64, 94, 64,104,233,238, + 246,229,242,243,101,128, 37,216,239,240,229,242,225,244,239,114, + 128, 34, 25,243,229,249,101,128, 37,206, 99,143, 0, 99, 64,156, + 65,105, 65,116, 65,180, 65,211, 66, 48, 67,215, 68,199, 69, 43, + 69, 92, 72, 84, 72, 92, 72,102, 72,114, 72,147, 97, 9, 64,176, + 64,187, 64,197, 64,204, 64,211, 64,236, 64,246, 65, 42, 65, 51, + 225,242,237,229,238,233,225,110,128, 5,110,226,229,238,231,225, + 236,105,128, 9,154,227,245,244,101,128, 1, 7,228,229,246, 97, + 128, 9, 26,231,117, 2, 64,218, 64,227,234,225,242,225,244,105, + 128, 10,154,242,237,245,235,232,105,128, 10, 26,236,243,241,245, + 225,242,101,128, 51,136,238,228,242,225,226,233,238,228,117, 4, + 65, 8, 65, 18, 65, 24, 65, 31,226,229,238,231,225,236,105,128, + 9,129,227,237, 98,128, 3, 16,228,229,246, 97,128, 9, 1,231, + 245,234,225,242,225,244,105,128, 10,129,240,243,236,239,227,107, + 128, 33,234,114, 3, 65, 59, 65, 65, 65, 91,229,239,102,128, 33, + 5,239,110,130, 2,199, 65, 74, 65, 85,226,229,236,239,247,227, + 237, 98,128, 3, 44,227,237, 98,128, 3, 12,242,233,225,231,229, + 242,229,244,245,242,110,128, 33,181,226,239,240,239,237,239,230, + 111,128, 49, 24, 99, 4, 65,126, 65,133, 65,152, 65,174,225,242, + 239,110,128, 1, 13,229,228,233,236,236, 97,129, 0,231, 65,144, + 225,227,245,244,101,128, 30, 9,233,242, 99, 2, 65,160, 65,165, + 236,101,128, 36,210,245,237,230,236,229,120,128, 1, 9,245,242, + 108,128, 2, 85,100, 2, 65,186, 65,202,239,116,129, 1, 11, 65, + 193,225,227,227,229,238,116,128, 1, 11,243,241,245,225,242,101, + 128, 51,197,101, 2, 65,217, 65,233,228,233,236,236, 97,129, 0, + 184, 65,227,227,237, 98,128, 3, 39,238,116,132, 0,162, 65,246, + 66, 14, 66, 26, 66, 37,105, 2, 65,252, 66, 4,231,242,225,228, + 101,128, 33, 3,238,230,229,242,233,239,114,128,246,223,237,239, + 238,239,243,240,225,227,101,128,255,224,239,236,228,243,244,249, + 236,101,128,247,162,243,245,240,229,242,233,239,114,128,246,224, + 104, 5, 66, 60, 66,123, 66,134, 67, 62, 67,154, 97, 4, 66, 70, + 66, 81, 66, 91, 66, 98,225,242,237,229,238,233,225,110,128, 5, + 121,226,229,238,231,225,236,105,128, 9,155,228,229,246, 97,128, + 9, 27,231,117, 2, 66,105, 66,114,234,225,242,225,244,105,128, + 10,155,242,237,245,235,232,105,128, 10, 27,226,239,240,239,237, + 239,230,111,128, 49, 20,101, 6, 66,148, 66,168, 66,192, 67, 4, + 67, 16, 67, 37,225,226,235,232,225,243,233,225,238,227,249,242, + 233,236,236,233, 99,128, 4,189, 99, 2, 66,174, 66,182,235,237, + 225,242,107,128, 39, 19,249,242,233,236,236,233, 99,128, 4, 71, + 100, 2, 66,198, 66,242,229,243,227,229,238,228,229,114, 2, 66, + 211, 66,231,225,226,235,232,225,243,233,225,238,227,249,242,233, + 236,236,233, 99,128, 4,191,227,249,242,233,236,236,233, 99,128, + 4,183,233,229,242,229,243,233,243,227,249,242,233,236,236,233, + 99,128, 4,245,232,225,242,237,229,238,233,225,110,128, 5,115, + 235,232,225,235,225,243,243,233,225,238,227,249,242,233,236,236, + 233, 99,128, 4,204,246,229,242,244,233,227,225,236,243,244,242, + 239,235,229,227,249,242,233,236,236,233, 99,128, 4,185,105,129, + 3,199, 67, 68,229,245,227,104, 4, 67, 81, 67,116, 67,131, 67, + 140, 97, 2, 67, 87, 67,102,227,233,242,227,236,229,235,239,242, + 229,225,110,128, 50,119,240,225,242,229,238,235,239,242,229,225, + 110,128, 50, 23,227,233,242,227,236,229,235,239,242,229,225,110, + 128, 50,105,235,239,242,229,225,110,128, 49, 74,240,225,242,229, + 238,235,239,242,229,225,110,128, 50, 9,111, 2, 67,160, 67,210, + 227,104, 3, 67,169, 67,191, 67,201,225,110, 2, 67,176, 67,184, + 231,244,232,225,105,128, 14, 10,244,232,225,105,128, 14, 8,233, + 238,231,244,232,225,105,128, 14, 9,239,229,244,232,225,105,128, + 14, 12,239,107,128, 1,136,105, 2, 67,221, 68, 67,229,245, 99, + 5, 67,235, 68, 14, 68, 29, 68, 38, 68, 52, 97, 2, 67,241, 68, + 0,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,118, + 240,225,242,229,238,235,239,242,229,225,110,128, 50, 22,227,233, + 242,227,236,229,235,239,242,229,225,110,128, 50,104,235,239,242, + 229,225,110,128, 49, 72,240,225,242,229,238,235,239,242,229,225, + 110,128, 50, 8,245,240,225,242,229,238,235,239,242,229,225,110, + 128, 50, 28,242, 99, 2, 68, 74, 68,169,236,101,132, 37,203, 68, + 87, 68, 98, 68,103, 68,127,237,245,236,244,233,240,236,121,128, + 34,151,239,116,128, 34,153,112, 2, 68,109, 68,115,236,245,115, + 128, 34,149,239,243,244,225,236,237,225,242,107,128, 48, 54,247, + 233,244,104, 2, 68,136, 68,152,236,229,230,244,232,225,236,230, + 226,236,225,227,107,128, 37,208,242,233,231,232,244,232,225,236, + 230,226,236,225,227,107,128, 37,209,245,237,230,236,229,120,130, + 2,198, 68,182, 68,193,226,229,236,239,247,227,237, 98,128, 3, + 45,227,237, 98,128, 3, 2,108, 3, 68,207, 68,213, 69, 11,229, + 225,114,128, 35, 39,233,227,107, 4, 68,225, 68,236, 68,245, 68, + 255,225,236,246,229,239,236,225,114,128, 1,194,228,229,238,244, + 225,108,128, 1,192,236,225,244,229,242,225,108,128, 1,193,242, + 229,244,242,239,230,236,229,120,128, 1,195,245, 98,129, 38, 99, + 69, 18,243,245,233,116, 2, 69, 27, 69, 35,226,236,225,227,107, + 128, 38, 99,247,232,233,244,101,128, 38,103,109, 3, 69, 51, 69, + 65, 69, 76,227,245,226,229,228,243,241,245,225,242,101,128, 51, + 164,239,238,239,243,240,225,227,101,128,255, 67,243,241,245,225, + 242,229,228,243,241,245,225,242,101,128, 51,160,111, 8, 69,110, + 69,121, 69,208, 70,150, 71,179, 71,210, 72, 61, 72, 70,225,242, + 237,229,238,233,225,110,128, 5,129,236,239,110,131, 0, 58, 69, + 133, 69,158, 69,177,237,239,110, 2, 69,141, 69,149,229,244,225, + 242,121,128, 32,161,239,243,240,225,227,101,128,255, 26,115, 2, + 69,164, 69,170,233,231,110,128, 32,161,237,225,236,108,128,254, + 85,244,242,233,225,238,231,245,236,225,114, 2, 69,192, 69,202, + 232,225,236,230,237,239,100,128, 2,209,237,239,100,128, 2,208, + 109, 2, 69,214, 70,143,237, 97,134, 0, 44, 69,231, 70, 39, 70, + 50, 70, 62, 70, 92, 70,115, 97, 3, 69,239, 70, 9, 70, 17,226, + 239,246,101, 2, 69,248, 69,254,227,237, 98,128, 3, 19,242,233, + 231,232,244,227,237, 98,128, 3, 21,227,227,229,238,116,128,246, + 195,114, 2, 70, 23, 70, 30,225,226,233, 99,128, 6, 12,237,229, + 238,233,225,110,128, 5, 93,233,238,230,229,242,233,239,114,128, + 246,225,237,239,238,239,243,240,225,227,101,128,255, 12,242,229, + 246,229,242,243,229,100, 2, 70, 75, 70, 86,225,226,239,246,229, + 227,237, 98,128, 3, 20,237,239,100,128, 2,189,115, 2, 70, 98, + 70,105,237,225,236,108,128,254, 80,245,240,229,242,233,239,114, + 128,246,226,244,245,242,238,229,100, 2, 70,126, 70,137,225,226, + 239,246,229,227,237, 98,128, 3, 18,237,239,100,128, 2,187,240, + 225,243,115,128, 38, 60,110, 2, 70,156, 70,165,231,242,245,229, + 238,116,128, 34, 69,116, 2, 70,171, 70,185,239,245,242,233,238, + 244,229,231,242,225,108,128, 34, 46,242,239,108,142, 35, 3, 70, + 219, 70,225, 70,240, 70,255, 71, 43, 71, 88, 71,102, 71,107, 71, + 112, 71,117, 71,123, 71,128, 71,169, 71,174,193,195, 75,128, 0, + 6, 66, 2, 70,231, 70,236,197, 76,128, 0, 7, 83,128, 0, 8, + 67, 2, 70,246, 70,251,193, 78,128, 0, 24, 82,128, 0, 13, 68, + 3, 71, 7, 71, 33, 71, 38, 67, 4, 71, 17, 71, 21, 71, 25, 71, + 29, 49,128, 0, 17, 50,128, 0, 18, 51,128, 0, 19, 52,128, 0, + 20,197, 76,128, 0,127,204, 69,128, 0, 16, 69, 5, 71, 55, 71, + 59, 71, 64, 71, 69, 71, 74, 77,128, 0, 25,206, 81,128, 0, 5, + 207, 84,128, 0, 4,211, 67,128, 0, 27, 84, 2, 71, 80, 71, 84, + 66,128, 0, 23, 88,128, 0, 3, 70, 2, 71, 94, 71, 98, 70,128, + 0, 12, 83,128, 0, 28,199, 83,128, 0, 29,200, 84,128, 0, 9, + 204, 70,128, 0, 10,206,193, 75,128, 0, 21,210, 83,128, 0, 30, + 83, 5, 71,140, 71,144, 71,154, 71,159, 71,164, 73,128, 0, 15, + 79,129, 0, 14, 71,150, 84,128, 0, 2,212, 88,128, 0, 1,213, + 66,128, 0, 26,217, 78,128, 0, 22,213, 83,128, 0, 31,214, 84, + 128, 0, 11,240,249,242,233,231,232,116,129, 0,169, 71,191,115, + 2, 71,197, 71,203,225,238,115,128,248,233,229,242,233,102,128, + 246,217,114, 2, 71,216, 72, 44,238,229,242,226,242,225,227,235, + 229,116, 2, 71,231, 72, 9,236,229,230,116,130, 48, 12, 71,242, + 71,254,232,225,236,230,247,233,228,244,104,128,255, 98,246,229, + 242,244,233,227,225,108,128,254, 65,242,233,231,232,116,130, 48, + 13, 72, 21, 72, 33,232,225,236,230,247,233,228,244,104,128,255, + 99,246,229,242,244,233,227,225,108,128,254, 66,240,239,242,225, + 244,233,239,238,243,241,245,225,242,101,128, 51,127,243,241,245, + 225,242,101,128, 51,199,246,229,242,235,231,243,241,245,225,242, + 101,128, 51,198,240,225,242,229,110,128, 36,158,242,245,250,229, + 233,242,111,128, 32,162,243,244,242,229,244,227,232,229,100,128, + 2,151,245,114, 2, 72,121, 72,139,236,121, 2, 72,128, 72,134, + 225,238,100,128, 34,207,239,114,128, 34,206,242,229,238,227,121, + 128, 0,164,249,114, 4, 72,158, 72,166, 72,173, 72,181,194,242, + 229,246,101,128,246,209,198,236,229,120,128,246,210,226,242,229, + 246,101,128,246,212,230,236,229,120,128,246,213,100,146, 0,100, + 72,228, 74,110, 75,134, 75,194, 76,114, 77, 68, 77,130, 78, 59, + 78, 72, 78, 81, 78,107, 78,132, 78,141, 79,208, 79,216, 79,227, + 79,247, 80, 19, 97, 11, 72,252, 73, 7, 73, 17, 73, 89, 73,152, + 73,163, 73,174, 73,243, 74, 49, 74, 55, 74, 85,225,242,237,229, + 238,233,225,110,128, 5,100,226,229,238,231,225,236,105,128, 9, + 166,100, 5, 73, 29, 73, 38, 73, 44, 73, 58, 73, 74,225,242,225, + 226,233, 99,128, 6, 54,229,246, 97,128, 9, 38,230,233,238,225, + 236,225,242,225,226,233, 99,128,254,190,233,238,233,244,233,225, + 236,225,242,225,226,233, 99,128,254,191,237,229,228,233,225,236, + 225,242,225,226,233, 99,128,254,192,103, 3, 73, 97, 73,114, 73, + 128,229,243,104,129, 5,188, 73,105,232,229,226,242,229,119,128, + 5,188,231,229,114,129, 32, 32, 73,122,228,226,108,128, 32, 33, + 117, 2, 73,134, 73,143,234,225,242,225,244,105,128, 10,166,242, + 237,245,235,232,105,128, 10, 38,232,233,242,225,231,225,238, 97, + 128, 48, 96,235,225,244,225,235,225,238, 97,128, 48,192,108, 3, + 73,182, 73,191, 73,229,225,242,225,226,233, 99,128, 6, 47,229, + 116,130, 5,211, 73,200, 73,220,228,225,231,229,243,104,129,251, + 51, 73,211,232,229,226,242,229,119,128,251, 51,232,229,226,242, + 229,119,128, 5,211,230,233,238,225,236,225,242,225,226,233, 99, + 128,254,170,237,237, 97, 3, 73,253, 74, 6, 74, 18,225,242,225, + 226,233, 99,128, 6, 79,236,239,247,225,242,225,226,233, 99,128, + 6, 79,244,225,238, 97, 2, 74, 27, 74, 41,236,244,239,238,229, + 225,242,225,226,233, 99,128, 6, 76,242,225,226,233, 99,128, 6, + 76,238,228, 97,128, 9,100,242,231, 97, 2, 74, 63, 74, 72,232, + 229,226,242,229,119,128, 5,167,236,229,230,244,232,229,226,242, + 229,119,128, 5,167,243,233,225,240,238,229,245,237,225,244,225, + 227,249,242,233,236,236,233,227,227,237, 98,128, 4,133, 98, 3, + 74,118, 75,115, 75,125,108, 9, 74,138, 74,146, 75, 3, 75, 11, + 75, 27, 75, 38, 75, 56, 75, 70, 75, 81,199,242,225,246,101,128, + 246,211, 97, 2, 74,152, 74,209,238,231,236,229,226,242,225,227, + 235,229,116, 2, 74,168, 74,188,236,229,230,116,129, 48, 10, 74, + 177,246,229,242,244,233,227,225,108,128,254, 61,242,233,231,232, + 116,129, 48, 11, 74,198,246,229,242,244,233,227,225,108,128,254, + 62,114, 2, 74,215, 74,236,227,232,233,238,246,229,242,244,229, + 228,226,229,236,239,247,227,237, 98,128, 3, 43,242,239,119, 2, + 74,244, 74,251,236,229,230,116,128, 33,212,242,233,231,232,116, + 128, 33,210,228,225,238,228, 97,128, 9,101,231,242,225,246,101, + 129,246,214, 75, 21,227,237, 98,128, 3, 15,233,238,244,229,231, + 242,225,108,128, 34, 44,236,239,247,236,233,238,101,129, 32, 23, + 75, 50,227,237, 98,128, 3, 51,239,246,229,242,236,233,238,229, + 227,237, 98,128, 3, 63,240,242,233,237,229,237,239,100,128, 2, + 186,246,229,242,244,233,227,225,108, 2, 75, 94, 75,100,226,225, + 114,128, 32, 22,236,233,238,229,225,226,239,246,229,227,237, 98, + 128, 3, 14,239,240,239,237,239,230,111,128, 49, 9,243,241,245, + 225,242,101,128, 51,200, 99, 4, 75,144, 75,151, 75,160, 75,187, + 225,242,239,110,128, 1, 15,229,228,233,236,236, 97,128, 30, 17, + 233,242, 99, 2, 75,168, 75,173,236,101,128, 36,211,245,237,230, + 236,229,248,226,229,236,239,119,128, 30, 19,242,239,225,116,128, + 1, 17,100, 4, 75,204, 76, 29, 76, 39, 76, 90, 97, 4, 75,214, + 75,224, 75,231, 76, 0,226,229,238,231,225,236,105,128, 9,161, + 228,229,246, 97,128, 9, 33,231,117, 2, 75,238, 75,247,234,225, + 242,225,244,105,128, 10,161,242,237,245,235,232,105,128, 10, 33, + 108, 2, 76, 6, 76, 15,225,242,225,226,233, 99,128, 6,136,230, + 233,238,225,236,225,242,225,226,233, 99,128,251,137,228,232,225, + 228,229,246, 97,128, 9, 92,232, 97, 3, 76, 48, 76, 58, 76, 65, + 226,229,238,231,225,236,105,128, 9,162,228,229,246, 97,128, 9, + 34,231,117, 2, 76, 72, 76, 81,234,225,242,225,244,105,128, 10, + 162,242,237,245,235,232,105,128, 10, 34,239,116, 2, 76, 97, 76, + 106,225,227,227,229,238,116,128, 30, 11,226,229,236,239,119,128, + 30, 13,101, 8, 76,132, 76,185, 76,192, 76,217, 76,227, 76,238, + 77, 27, 77, 63, 99, 2, 76,138, 76,175,233,237,225,236,243,229, + 240,225,242,225,244,239,114, 2, 76,156, 76,165,225,242,225,226, + 233, 99,128, 6,107,240,229,242,243,233,225,110,128, 6,107,249, + 242,233,236,236,233, 99,128, 4, 52,231,242,229,101,128, 0,176, + 232,105, 2, 76,199, 76,208,232,229,226,242,229,119,128, 5,173, + 242,225,231,225,238, 97,128, 48,103,233,227,239,240,244,233, 99, + 128, 3,239,235,225,244,225,235,225,238, 97,128, 48,199,108, 2, + 76,244, 77, 11,229,244,101, 2, 76,252, 77, 3,236,229,230,116, + 128, 35, 43,242,233,231,232,116,128, 35, 38,244, 97,129, 3,180, + 77, 18,244,245,242,238,229,100,128, 1,141,238,239,237,233,238, + 225,244,239,242,237,233,238,245,243,239,238,229,238,245,237,229, + 242,225,244,239,242,226,229,238,231,225,236,105,128, 9,248,250, + 104,128, 2,164,104, 2, 77, 74, 77,124, 97, 3, 77, 82, 77, 92, + 77, 99,226,229,238,231,225,236,105,128, 9,167,228,229,246, 97, + 128, 9, 39,231,117, 2, 77,106, 77,115,234,225,242,225,244,105, + 128, 10,167,242,237,245,235,232,105,128, 10, 39,239,239,107,128, + 2, 87,105, 6, 77,144, 77,193, 77,253, 78, 8, 78, 19, 78, 29, + 97, 2, 77,150, 77,172,236,249,244,233,235,225,244,239,238,239, + 115,129, 3,133, 77,166,227,237, 98,128, 3, 68,237,239,238,100, + 129, 38,102, 77,181,243,245,233,244,247,232,233,244,101,128, 38, + 98,229,242,229,243,233,115,133, 0,168, 77,212, 77,220, 77,231, + 77,237, 77,245,225,227,245,244,101,128,246,215,226,229,236,239, + 247,227,237, 98,128, 3, 36,227,237, 98,128, 3, 8,231,242,225, + 246,101,128,246,216,244,239,238,239,115,128, 3,133,232,233,242, + 225,231,225,238, 97,128, 48, 98,235,225,244,225,235,225,238, 97, + 128, 48,194,244,244,239,237,225,242,107,128, 48, 3,246,105, 2, + 78, 36, 78, 47,228,101,129, 0,247, 78, 43,115,128, 34, 35,243, + 233,239,238,243,236,225,243,104,128, 34, 21,234,229,227,249,242, + 233,236,236,233, 99,128, 4, 82,235,243,232,225,228,101,128, 37, + 147,108, 2, 78, 87, 78, 98,233,238,229,226,229,236,239,119,128, + 30, 15,243,241,245,225,242,101,128, 51,151,109, 2, 78,113, 78, + 121,225,227,242,239,110,128, 1, 17,239,238,239,243,240,225,227, + 101,128,255, 68,238,226,236,239,227,107,128, 37,132,111, 10, 78, + 163, 78,175, 78,185, 78,196, 78,207, 79, 23, 79, 28, 79, 39, 79, + 154, 79,180,227,232,225,228,225,244,232,225,105,128, 14, 14,228, + 229,235,244,232,225,105,128, 14, 20,232,233,242,225,231,225,238, + 97,128, 48,105,235,225,244,225,235,225,238, 97,128, 48,201,236, + 236,225,114,132, 0, 36, 78,222, 78,233, 78,245, 79, 0,233,238, + 230,229,242,233,239,114,128,246,227,237,239,238,239,243,240,225, + 227,101,128,255, 4,239,236,228,243,244,249,236,101,128,247, 36, + 115, 2, 79, 6, 79, 13,237,225,236,108,128,254,105,245,240,229, + 242,233,239,114,128,246,228,238,103,128, 32,171,242,245,243,241, + 245,225,242,101,128, 51, 38,116, 6, 79, 53, 79, 70, 79, 92, 79, + 103, 79,135, 79,142,225,227,227,229,238,116,129, 2,217, 79, 64, + 227,237, 98,128, 3, 7,226,229,236,239,247, 99, 2, 79, 81, 79, + 86,237, 98,128, 3, 35,239,237, 98,128, 3, 35,235,225,244,225, + 235,225,238, 97,128, 48,251,236,229,243,115, 2, 79,112, 79,116, + 105,128, 1, 49,106,129,246,190, 79,122,243,244,242,239,235,229, + 232,239,239,107,128, 2,132,237,225,244,104,128, 34,197,244,229, + 228,227,233,242,227,236,101,128, 37,204,245,226,236,229,249,239, + 228,240,225,244,225,104,129,251, 31, 79,171,232,229,226,242,229, + 119,128,251, 31,247,238,244,225,227,107, 2, 79,191, 79,202,226, + 229,236,239,247,227,237, 98,128, 3, 30,237,239,100,128, 2,213, + 240,225,242,229,110,128, 36,159,243,245,240,229,242,233,239,114, + 128,246,235,116, 2, 79,233, 79,239,225,233,108,128, 2, 86,239, + 240,226,225,114,128, 1,140,117, 2, 79,253, 80, 8,232,233,242, + 225,231,225,238, 97,128, 48,101,235,225,244,225,235,225,238, 97, + 128, 48,197,122,132, 1,243, 80, 31, 80, 40, 80, 59, 80, 96,225, + 236,244,239,238,101,128, 2,163, 99, 2, 80, 46, 80, 53,225,242, + 239,110,128, 1,198,245,242,108,128, 2,165,101, 2, 80, 65, 80, + 85,225,226,235,232,225,243,233,225,238,227,249,242,233,236,236, + 233, 99,128, 4,225,227,249,242,233,236,236,233, 99,128, 4, 85, + 232,229,227,249,242,233,236,236,233, 99,128, 4, 95,101,151, 0, + 101, 80,159, 80,178, 80,212, 81,186, 81,248, 82, 25, 82, 37, 82, + 60, 82,113, 83,225, 84, 27, 84,129, 84,245, 85,124, 85,199, 85, + 230, 86, 36, 86, 89, 87, 24, 87,157, 87,177, 87,221, 88, 56, 97, + 2, 80,165, 80,172,227,245,244,101,128, 0,233,242,244,104,128, + 38, 65, 98, 3, 80,186, 80,195, 80,205,229,238,231,225,236,105, + 128, 9,143,239,240,239,237,239,230,111,128, 49, 28,242,229,246, + 101,128, 1, 21, 99, 5, 80,224, 81, 41, 81, 55, 81, 87, 81,176, + 97, 2, 80,230, 81, 35,238,228,242, 97, 3, 80,241, 80,248, 81, + 3,228,229,246, 97,128, 9, 13,231,245,234,225,242,225,244,105, + 128, 10,141,246,239,247,229,236,243,233,231,110, 2, 81, 17, 81, + 24,228,229,246, 97,128, 9, 69,231,245,234,225,242,225,244,105, + 128, 10,197,242,239,110,128, 1, 27,229,228,233,236,236,225,226, + 242,229,246,101,128, 30, 29,104, 2, 81, 61, 81, 72,225,242,237, + 229,238,233,225,110,128, 5,101,249,233,247,238,225,242,237,229, + 238,233,225,110,128, 5,135,233,242, 99, 2, 81, 95, 81,100,236, + 101,128, 36,212,245,237,230,236,229,120,134, 0,234, 81,121, 81, + 129, 81,137, 81,148, 81,156, 81,168,225,227,245,244,101,128, 30, + 191,226,229,236,239,119,128, 30, 25,228,239,244,226,229,236,239, + 119,128, 30,199,231,242,225,246,101,128, 30,193,232,239,239,235, + 225,226,239,246,101,128, 30,195,244,233,236,228,101,128, 30,197, + 249,242,233,236,236,233, 99,128, 4, 84,100, 4, 81,196, 81,206, + 81,212, 81,222,226,236,231,242,225,246,101,128, 2, 5,229,246, + 97,128, 9, 15,233,229,242,229,243,233,115,128, 0,235,239,116, + 130, 1, 23, 81,231, 81,240,225,227,227,229,238,116,128, 1, 23, + 226,229,236,239,119,128, 30,185,101, 2, 81,254, 82, 9,231,245, + 242,237,245,235,232,105,128, 10, 15,237,225,244,242,225,231,245, + 242,237,245,235,232,105,128, 10, 71,230,227,249,242,233,236,236, + 233, 99,128, 4, 68,103, 2, 82, 43, 82, 50,242,225,246,101,128, + 0,232,245,234,225,242,225,244,105,128, 10,143,104, 4, 82, 70, + 82, 81, 82, 92, 82,102,225,242,237,229,238,233,225,110,128, 5, + 103,226,239,240,239,237,239,230,111,128, 49, 29,233,242,225,231, + 225,238, 97,128, 48, 72,239,239,235,225,226,239,246,101,128, 30, + 187,105, 4, 82,123, 82,134, 83,192, 83,207,226,239,240,239,237, + 239,230,111,128, 49, 31,231,232,116,142, 0, 56, 82,168, 82,177, + 82,187, 82,217, 82,224, 83, 6, 83, 31, 83, 76, 83,110, 83,122, + 83,133, 83,166, 83,174, 83,185,225,242,225,226,233, 99,128, 6, + 104,226,229,238,231,225,236,105,128, 9,238,227,233,242,227,236, + 101,129, 36,103, 82,198,233,238,246,229,242,243,229,243,225,238, + 243,243,229,242,233,102,128, 39,145,228,229,246, 97,128, 9,110, + 229,229,110, 2, 82,232, 82,241,227,233,242,227,236,101,128, 36, + 113,112, 2, 82,247, 82,254,225,242,229,110,128, 36,133,229,242, + 233,239,100,128, 36,153,231,117, 2, 83, 13, 83, 22,234,225,242, + 225,244,105,128, 10,238,242,237,245,235,232,105,128, 10,110,104, + 2, 83, 37, 83, 63, 97, 2, 83, 43, 83, 54,227,235,225,242,225, + 226,233, 99,128, 6,104,238,231,250,232,239,117,128, 48, 40,238, + 239,244,229,226,229,225,237,229,100,128, 38,107,105, 2, 83, 82, + 83,100,228,229,239,231,242,225,240,232,233,227,240,225,242,229, + 110,128, 50, 39,238,230,229,242,233,239,114,128, 32,136,237,239, + 238,239,243,240,225,227,101,128,255, 24,239,236,228,243,244,249, + 236,101,128,247, 56,112, 2, 83,139, 83,146,225,242,229,110,128, + 36,123,229,114, 2, 83,153, 83,159,233,239,100,128, 36,143,243, + 233,225,110,128, 6,248,242,239,237,225,110,128, 33,119,243,245, + 240,229,242,233,239,114,128, 32,120,244,232,225,105,128, 14, 88, + 238,246,229,242,244,229,228,226,242,229,246,101,128, 2, 7,239, + 244,233,230,233,229,228,227,249,242,233,236,236,233, 99,128, 4, + 101,107, 2, 83,231, 83,255,225,244,225,235,225,238, 97,129, 48, + 168, 83,243,232,225,236,230,247,233,228,244,104,128,255,116,111, + 2, 84, 5, 84, 20,238,235,225,242,231,245,242,237,245,235,232, + 105,128, 10,116,242,229,225,110,128, 49, 84,108, 3, 84, 35, 84, + 46, 84,107,227,249,242,233,236,236,233, 99,128, 4, 59,101, 2, + 84, 52, 84, 59,237,229,238,116,128, 34, 8,246,229,110, 3, 84, + 69, 84, 78, 84, 99,227,233,242,227,236,101,128, 36,106,112, 2, + 84, 84, 84, 91,225,242,229,110,128, 36,126,229,242,233,239,100, + 128, 36,146,242,239,237,225,110,128, 33,122,236,233,240,243,233, + 115,129, 32, 38, 84,118,246,229,242,244,233,227,225,108,128, 34, + 238,109, 5, 84,141, 84,169, 84,180, 84,200, 84,211,225,227,242, + 239,110,130, 1, 19, 84,153, 84,161,225,227,245,244,101,128, 30, + 23,231,242,225,246,101,128, 30, 21,227,249,242,233,236,236,233, + 99,128, 4, 60,228,225,243,104,129, 32, 20, 84,189,246,229,242, + 244,233,227,225,108,128,254, 49,239,238,239,243,240,225,227,101, + 128,255, 69,112, 2, 84,217, 84,237,232,225,243,233,243,237,225, + 242,235,225,242,237,229,238,233,225,110,128, 5, 91,244,249,243, + 229,116,128, 34, 5,110, 6, 85, 3, 85, 14, 85, 25, 85, 69, 85, + 101, 85,116,226,239,240,239,237,239,230,111,128, 49, 35,227,249, + 242,233,236,236,233, 99,128, 4, 61,100, 2, 85, 31, 85, 50,225, + 243,104,129, 32, 19, 85, 39,246,229,242,244,233,227,225,108,128, + 254, 50,229,243,227,229,238,228,229,242,227,249,242,233,236,236, + 233, 99,128, 4,163,103,130, 1, 75, 85, 77, 85, 88,226,239,240, + 239,237,239,230,111,128, 49, 37,232,229,227,249,242,233,236,236, + 233, 99,128, 4,165,232,239,239,235,227,249,242,233,236,236,233, + 99,128, 4,200,243,240,225,227,101,128, 32, 2,111, 3, 85,132, + 85,140, 85,149,231,239,238,229,107,128, 1, 25,235,239,242,229, + 225,110,128, 49, 83,240,229,110,130, 2, 91, 85,159, 85,168,227, + 236,239,243,229,100,128, 2,154,242,229,246,229,242,243,229,100, + 130, 2, 92, 85,183, 85,192,227,236,239,243,229,100,128, 2, 94, + 232,239,239,107,128, 2, 93,112, 2, 85,205, 85,212,225,242,229, + 110,128, 36,160,243,233,236,239,110,129, 3,181, 85,222,244,239, + 238,239,115,128, 3,173,241,117, 2, 85,237, 86, 25,225,108,130, + 0, 61, 85,246, 86, 2,237,239,238,239,243,240,225,227,101,128, + 255, 29,115, 2, 86, 8, 86, 15,237,225,236,108,128,254,102,245, + 240,229,242,233,239,114,128, 32,124,233,246,225,236,229,238,227, + 101,128, 34, 97,114, 3, 86, 44, 86, 55, 86, 66,226,239,240,239, + 237,239,230,111,128, 49, 38,227,249,242,233,236,236,233, 99,128, + 4, 64,229,246,229,242,243,229,100,129, 2, 88, 86, 78,227,249, + 242,233,236,236,233, 99,128, 4, 77,115, 6, 86,103, 86,114, 86, + 134, 86,215, 87, 4, 87, 14,227,249,242,233,236,236,233, 99,128, + 4, 65,228,229,243,227,229,238,228,229,242,227,249,242,233,236, + 236,233, 99,128, 4,171,104,132, 2,131, 86,146, 86,153, 86,184, + 86,199,227,245,242,108,128, 2,134,239,242,116, 2, 86,161, 86, + 168,228,229,246, 97,128, 9, 14,246,239,247,229,236,243,233,231, + 238,228,229,246, 97,128, 9, 70,242,229,246,229,242,243,229,228, + 236,239,239,112,128, 1,170,243,241,245,225,244,242,229,246,229, + 242,243,229,100,128, 2,133,237,225,236,108, 2, 86,224, 86,235, + 232,233,242,225,231,225,238, 97,128, 48, 71,235,225,244,225,235, + 225,238, 97,129, 48,167, 86,248,232,225,236,230,247,233,228,244, + 104,128,255,106,244,233,237,225,244,229,100,128, 33, 46,245,240, + 229,242,233,239,114,128,246,236,116, 5, 87, 36, 87, 62, 87, 66, + 87, 83, 87,149, 97,130, 3,183, 87, 44, 87, 54,242,237,229,238, + 233,225,110,128, 5,104,244,239,238,239,115,128, 3,174,104,128, + 0,240,233,236,228,101,129, 30,189, 87, 75,226,229,236,239,119, + 128, 30, 27,238,225,232,244, 97, 3, 87, 95, 87,127, 87,136,230, + 239,245,235,104, 2, 87,105, 87,114,232,229,226,242,229,119,128, + 5,145,236,229,230,244,232,229,226,242,229,119,128, 5,145,232, + 229,226,242,229,119,128, 5,145,236,229,230,244,232,229,226,242, + 229,119,128, 5,145,245,242,238,229,100,128, 1,221,117, 2, 87, + 163, 87,172,235,239,242,229,225,110,128, 49, 97,242,111,128, 32, + 172,246,239,247,229,236,243,233,231,110, 3, 87,193, 87,203, 87, + 210,226,229,238,231,225,236,105,128, 9,199,228,229,246, 97,128, + 9, 71,231,245,234,225,242,225,244,105,128, 10,199,120, 2, 87, + 227, 88, 44,227,236,225,109,132, 0, 33, 87,242, 87,253, 88, 24, + 88, 36,225,242,237,229,238,233,225,110,128, 5, 92,100, 2, 88, + 3, 88, 8,226,108,128, 32, 60,239,247,110,129, 0,161, 88, 16, + 243,237,225,236,108,128,247,161,237,239,238,239,243,240,225,227, + 101,128,255, 1,243,237,225,236,108,128,247, 33,233,243,244,229, + 238,244,233,225,108,128, 34, 3,250,104,131, 2,146, 88, 67, 88, + 86, 88, 97, 99, 2, 88, 73, 88, 80,225,242,239,110,128, 1,239, + 245,242,108,128, 2,147,242,229,246,229,242,243,229,100,128, 1, + 185,244,225,233,108,128, 1,186,102,140, 0,102, 88,132, 88,214, + 88,225, 88,234, 88,246, 89, 93, 89,109, 91,117, 91,130, 91,156, + 93, 33, 93, 41, 97, 4, 88,142, 88,149, 88,160, 88,171,228,229, + 246, 97,128, 9, 94,231,245,242,237,245,235,232,105,128, 10, 94, + 232,242,229,238,232,229,233,116,128, 33, 9,244,232, 97, 3, 88, + 181, 88,190, 88,202,225,242,225,226,233, 99,128, 6, 78,236,239, + 247,225,242,225,226,233, 99,128, 6, 78,244,225,238,225,242,225, + 226,233, 99,128, 6, 75,226,239,240,239,237,239,230,111,128, 49, + 8,227,233,242,227,236,101,128, 36,213,228,239,244,225,227,227, + 229,238,116,128, 30, 31,101, 3, 88,254, 89, 76, 89, 86,104, 4, + 89, 8, 89, 31, 89, 45, 89, 61,225,114, 2, 89, 15, 89, 22,225, + 226,233, 99,128, 6, 65,237,229,238,233,225,110,128, 5,134,230, + 233,238,225,236,225,242,225,226,233, 99,128,254,210,233,238,233, + 244,233,225,236,225,242,225,226,233, 99,128,254,211,237,229,228, + 233,225,236,225,242,225,226,233, 99,128,254,212,233,227,239,240, + 244,233, 99,128, 3,229,237,225,236,101,128, 38, 64,102,130,251, + 0, 89,101, 89,105,105,128,251, 3,108,128,251, 4,105,136,251, + 1, 89,129, 89,169, 89,180, 89,202, 90, 68, 90, 85, 90, 93, 90, + 106,230,244,229,229,110, 2, 89,139, 89,148,227,233,242,227,236, + 101,128, 36,110,112, 2, 89,154, 89,161,225,242,229,110,128, 36, + 130,229,242,233,239,100,128, 36,150,231,245,242,229,228,225,243, + 104,128, 32, 18,236,236,229,100, 2, 89,189, 89,195,226,239,120, + 128, 37,160,242,229,227,116,128, 37,172,238,225,108, 5, 89,216, + 89,255, 90, 16, 90, 33, 90, 49,235,225,102,130, 5,218, 89,226, + 89,246,228,225,231,229,243,104,129,251, 58, 89,237,232,229,226, + 242,229,119,128,251, 58,232,229,226,242,229,119,128, 5,218,237, + 229,109,129, 5,221, 90, 7,232,229,226,242,229,119,128, 5,221, + 238,245,110,129, 5,223, 90, 24,232,229,226,242,229,119,128, 5, + 223,240,101,129, 5,227, 90, 40,232,229,226,242,229,119,128, 5, + 227,244,243,225,228,105,129, 5,229, 90, 59,232,229,226,242,229, + 119,128, 5,229,242,243,244,244,239,238,229,227,232,233,238,229, + 243,101,128, 2,201,243,232,229,249,101,128, 37,201,244,225,227, + 249,242,233,236,236,233, 99,128, 4,115,246,101,142, 0, 53, 90, + 139, 90,148, 90,158, 90,188, 90,195, 90,205, 90,230, 91, 1, 91, + 35, 91, 47, 91, 58, 91, 91, 91, 99, 91,110,225,242,225,226,233, + 99,128, 6,101,226,229,238,231,225,236,105,128, 9,235,227,233, + 242,227,236,101,129, 36,100, 90,169,233,238,246,229,242,243,229, + 243,225,238,243,243,229,242,233,102,128, 39,142,228,229,246, 97, + 128, 9,107,229,233,231,232,244,232,115,128, 33, 93,231,117, 2, + 90,212, 90,221,234,225,242,225,244,105,128, 10,235,242,237,245, + 235,232,105,128, 10,107,232, 97, 2, 90,237, 90,248,227,235,225, + 242,225,226,233, 99,128, 6,101,238,231,250,232,239,117,128, 48, + 37,105, 2, 91, 7, 91, 25,228,229,239,231,242,225,240,232,233, + 227,240,225,242,229,110,128, 50, 36,238,230,229,242,233,239,114, + 128, 32,133,237,239,238,239,243,240,225,227,101,128,255, 21,239, + 236,228,243,244,249,236,101,128,247, 53,112, 2, 91, 64, 91, 71, + 225,242,229,110,128, 36,120,229,114, 2, 91, 78, 91, 84,233,239, + 100,128, 36,140,243,233,225,110,128, 6,245,242,239,237,225,110, + 128, 33,116,243,245,240,229,242,233,239,114,128, 32,117,244,232, + 225,105,128, 14, 85,108,129,251, 2, 91,123,239,242,233,110,128, + 1,146,109, 2, 91,136, 91,147,239,238,239,243,240,225,227,101, + 128,255, 70,243,241,245,225,242,101,128, 51,153,111, 4, 91,166, + 91,188, 91,200, 91,207,230, 97, 2, 91,173, 91,181,238,244,232, + 225,105,128, 14, 31,244,232,225,105,128, 14, 29,238,231,237,225, + 238,244,232,225,105,128, 14, 79,242,225,236,108,128, 34, 0,245, + 114,142, 0, 52, 91,240, 91,249, 92, 3, 92, 33, 92, 40, 92, 65, + 92, 92, 92,126, 92,138, 92,157, 92,168, 92,201, 92,209, 92,220, + 225,242,225,226,233, 99,128, 6,100,226,229,238,231,225,236,105, + 128, 9,234,227,233,242,227,236,101,129, 36, 99, 92, 14,233,238, + 246,229,242,243,229,243,225,238,243,243,229,242,233,102,128, 39, + 141,228,229,246, 97,128, 9,106,231,117, 2, 92, 47, 92, 56,234, + 225,242,225,244,105,128, 10,234,242,237,245,235,232,105,128, 10, + 106,232, 97, 2, 92, 72, 92, 83,227,235,225,242,225,226,233, 99, + 128, 6,100,238,231,250,232,239,117,128, 48, 36,105, 2, 92, 98, + 92,116,228,229,239,231,242,225,240,232,233,227,240,225,242,229, + 110,128, 50, 35,238,230,229,242,233,239,114,128, 32,132,237,239, + 238,239,243,240,225,227,101,128,255, 20,238,245,237,229,242,225, + 244,239,242,226,229,238,231,225,236,105,128, 9,247,239,236,228, + 243,244,249,236,101,128,247, 52,112, 2, 92,174, 92,181,225,242, + 229,110,128, 36,119,229,114, 2, 92,188, 92,194,233,239,100,128, + 36,139,243,233,225,110,128, 6,244,242,239,237,225,110,128, 33, + 115,243,245,240,229,242,233,239,114,128, 32,116,116, 2, 92,226, + 93, 8,229,229,110, 2, 92,234, 92,243,227,233,242,227,236,101, + 128, 36,109,112, 2, 92,249, 93, 0,225,242,229,110,128, 36,129, + 229,242,233,239,100,128, 36,149,104, 2, 93, 14, 93, 19,225,105, + 128, 14, 84,244,239,238,229,227,232,233,238,229,243,101,128, 2, + 203,240,225,242,229,110,128, 36,161,242, 97, 2, 93, 48, 93, 56, + 227,244,233,239,110,128, 32, 68,238, 99,128, 32,163,103,144, 0, + 103, 93, 97, 94, 43, 94, 66, 94,127, 94,144, 95, 65, 96, 58, 96, + 143, 96,156, 97, 14, 97, 39, 97, 67, 97, 89, 98, 34, 98, 56, 98, + 158, 97, 9, 93,117, 93,127, 93,134, 93,141, 93,205, 93,230, 93, + 241, 93,252, 94, 30,226,229,238,231,225,236,105,128, 9,151,227, + 245,244,101,128, 1,245,228,229,246, 97,128, 9, 23,102, 4, 93, + 151, 93,160, 93,174, 93,190,225,242,225,226,233, 99,128, 6,175, + 230,233,238,225,236,225,242,225,226,233, 99,128,251,147,233,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,251,148,237,229, + 228,233,225,236,225,242,225,226,233, 99,128,251,149,231,117, 2, + 93,212, 93,221,234,225,242,225,244,105,128, 10,151,242,237,245, + 235,232,105,128, 10, 23,232,233,242,225,231,225,238, 97,128, 48, + 76,235,225,244,225,235,225,238, 97,128, 48,172,237,237, 97,130, + 3,179, 94, 6, 94, 19,236,225,244,233,238,243,237,225,236,108, + 128, 2, 99,243,245,240,229,242,233,239,114,128, 2,224,238,231, + 233,225,227,239,240,244,233, 99,128, 3,235, 98, 2, 94, 49, 94, + 59,239,240,239,237,239,230,111,128, 49, 13,242,229,246,101,128, + 1, 31, 99, 4, 94, 76, 94, 83, 94, 92, 94,114,225,242,239,110, + 128, 1,231,229,228,233,236,236, 97,128, 1, 35,233,242, 99, 2, + 94,100, 94,105,236,101,128, 36,214,245,237,230,236,229,120,128, + 1, 29,239,237,237,225,225,227,227,229,238,116,128, 1, 35,228, + 239,116,129, 1, 33, 94,135,225,227,227,229,238,116,128, 1, 33, + 101, 6, 94,158, 94,169, 94,180, 94,191, 94,210, 95, 56,227,249, + 242,233,236,236,233, 99,128, 4, 51,232,233,242,225,231,225,238, + 97,128, 48, 82,235,225,244,225,235,225,238, 97,128, 48,178,239, + 237,229,244,242,233,227,225,236,236,249,229,241,245,225,108,128, + 34, 81,114, 3, 94,218, 95, 11, 95, 21,229,243,104, 3, 94,228, + 94,243, 94,252,225,227,227,229,238,244,232,229,226,242,229,119, + 128, 5,156,232,229,226,242,229,119,128, 5,243,237,245,241,228, + 225,237,232,229,226,242,229,119,128, 5,157,237,225,238,228,226, + 236,115,128, 0,223,243,232,225,249,233,109, 2, 95, 32, 95, 47, + 225,227,227,229,238,244,232,229,226,242,229,119,128, 5,158,232, + 229,226,242,229,119,128, 5,244,244,225,237,225,242,107,128, 48, + 19,104, 5, 95, 77, 95,210, 96, 17, 96, 42, 96, 48, 97, 4, 95, + 87, 95, 97, 95,120, 95,145,226,229,238,231,225,236,105,128, 9, + 152,100, 2, 95,103, 95,114,225,242,237,229,238,233,225,110,128, + 5,114,229,246, 97,128, 9, 24,231,117, 2, 95,127, 95,136,234, + 225,242,225,244,105,128, 10,152,242,237,245,235,232,105,128, 10, + 24,233,110, 4, 95,156, 95,165, 95,179, 95,195,225,242,225,226, + 233, 99,128, 6, 58,230,233,238,225,236,225,242,225,226,233, 99, + 128,254,206,233,238,233,244,233,225,236,225,242,225,226,233, 99, + 128,254,207,237,229,228,233,225,236,225,242,225,226,233, 99,128, + 254,208,101, 3, 95,218, 95,239, 96, 0,237,233,228,228,236,229, + 232,239,239,235,227,249,242,233,236,236,233, 99,128, 4,149,243, + 244,242,239,235,229,227,249,242,233,236,236,233, 99,128, 4,147, + 245,240,244,245,242,238,227,249,242,233,236,236,233, 99,128, 4, + 145,232, 97, 2, 96, 24, 96, 31,228,229,246, 97,128, 9, 90,231, + 245,242,237,245,235,232,105,128, 10, 90,239,239,107,128, 2, 96, + 250,243,241,245,225,242,101,128, 51,147,105, 3, 96, 66, 96, 77, + 96, 88,232,233,242,225,231,225,238, 97,128, 48, 78,235,225,244, + 225,235,225,238, 97,128, 48,174,109, 2, 96, 94, 96,105,225,242, + 237,229,238,233,225,110,128, 5, 99,229,108,130, 5,210, 96,114, + 96,134,228,225,231,229,243,104,129,251, 50, 96,125,232,229,226, + 242,229,119,128,251, 50,232,229,226,242,229,119,128, 5,210,234, + 229,227,249,242,233,236,236,233, 99,128, 4, 83,236,239,244,244, + 225,108, 2, 96,167, 96,184,233,238,246,229,242,244,229,228,243, + 244,242,239,235,101,128, 1,190,243,244,239,112,132, 2,148, 96, + 199, 96,210, 96,216, 96,248,233,238,246,229,242,244,229,100,128, + 2,150,237,239,100,128, 2,192,242,229,246,229,242,243,229,100, + 130, 2,149, 96,231, 96,237,237,239,100,128, 2,193,243,245,240, + 229,242,233,239,114,128, 2,228,243,244,242,239,235,101,129, 2, + 161, 97, 3,242,229,246,229,242,243,229,100,128, 2,162,109, 2, + 97, 20, 97, 28,225,227,242,239,110,128, 30, 33,239,238,239,243, + 240,225,227,101,128,255, 71,111, 2, 97, 45, 97, 56,232,233,242, + 225,231,225,238, 97,128, 48, 84,235,225,244,225,235,225,238, 97, + 128, 48,180,240, 97, 2, 97, 74, 97, 80,242,229,110,128, 36,162, + 243,241,245,225,242,101,128, 51,172,114, 2, 97, 95, 97,192, 97, + 2, 97,101, 97,109,228,233,229,238,116,128, 34, 7,246,101,134, + 0, 96, 97,126, 97,137, 97,154, 97,161, 97,170, 97,182,226,229, + 236,239,247,227,237, 98,128, 3, 22, 99, 2, 97,143, 97,148,237, + 98,128, 3, 0,239,237, 98,128, 3, 0,228,229,246, 97,128, 9, + 83,236,239,247,237,239,100,128, 2,206,237,239,238,239,243,240, + 225,227,101,128,255, 64,244,239,238,229,227,237, 98,128, 3, 64, + 229,225,244,229,114,132, 0, 62, 97,208, 97,227, 97,239, 98, 26, + 229,241,245,225,108,129, 34,101, 97,218,239,242,236,229,243,115, + 128, 34,219,237,239,238,239,243,240,225,227,101,128,255, 30,111, + 2, 97,245, 98, 15,114, 2, 97,251, 98, 8,229,241,245,233,246, + 225,236,229,238,116,128, 34,115,236,229,243,115,128, 34,119,246, + 229,242,229,241,245,225,108,128, 34,103,243,237,225,236,108,128, + 254,101,115, 2, 98, 40, 98, 48,227,242,233,240,116,128, 2, 97, + 244,242,239,235,101,128, 1,229,117, 4, 98, 66, 98, 77, 98,134, + 98,145,232,233,242,225,231,225,238, 97,128, 48, 80,233,108, 2, + 98, 84, 98,109,236,229,237,239,116, 2, 98, 94, 98,101,236,229, + 230,116,128, 0,171,242,233,231,232,116,128, 0,187,243,233,238, + 231,108, 2, 98,119, 98,126,236,229,230,116,128, 32, 57,242,233, + 231,232,116,128, 32, 58,235,225,244,225,235,225,238, 97,128, 48, + 176,242,225,237,245,243,241,245,225,242,101,128, 51, 24,249,243, + 241,245,225,242,101,128, 51,201,104,144, 0,104, 98,204,101, 90, + 101,125,101,162,101,202,103, 90,103,110,104, 75,104, 87,104, 99, + 105,167,105,175,105,186,105,195,106, 19,106, 23, 97, 13, 98,232, + 99, 15, 99, 25, 99, 55, 99, 80, 99,158, 99,170, 99,195, 99,210, + 99,239, 99,252,100, 54,100, 63, 97, 2, 98,238, 99, 1,226,235, + 232,225,243,233,225,238,227,249,242,233,236,236,233, 99,128, 4, + 169,236,244,239,238,229,225,242,225,226,233, 99,128, 6,193,226, + 229,238,231,225,236,105,128, 9,185,228,101, 2, 99, 32, 99, 50, + 243,227,229,238,228,229,242,227,249,242,233,236,236,233, 99,128, + 4,179,246, 97,128, 9, 57,231,117, 2, 99, 62, 99, 71,234,225, + 242,225,244,105,128, 10,185,242,237,245,235,232,105,128, 10, 57, + 104, 4, 99, 90, 99, 99, 99,113, 99,143,225,242,225,226,233, 99, + 128, 6, 45,230,233,238,225,236,225,242,225,226,233, 99,128,254, + 162,105, 2, 99,119, 99,134,238,233,244,233,225,236,225,242,225, + 226,233, 99,128,254,163,242,225,231,225,238, 97,128, 48,111,237, + 229,228,233,225,236,225,242,225,226,233, 99,128,254,164,233,244, + 245,243,241,245,225,242,101,128, 51, 42,235,225,244,225,235,225, + 238, 97,129, 48,207, 99,183,232,225,236,230,247,233,228,244,104, + 128,255,138,236,225,238,244,231,245,242,237,245,235,232,105,128, + 10, 77,237,250, 97, 2, 99,218, 99,227,225,242,225,226,233, 99, + 128, 6, 33,236,239,247,225,242,225,226,233, 99,128, 6, 33,238, + 231,245,236,230,233,236,236,229,114,128, 49,100,114, 2,100, 2, + 100, 18,228,243,233,231,238,227,249,242,233,236,236,233, 99,128, + 4, 74,240,239,239,110, 2,100, 27,100, 40,236,229,230,244,226, + 225,242,226,245,112,128, 33,188,242,233,231,232,244,226,225,242, + 226,245,112,128, 33,192,243,241,245,225,242,101,128, 51,202,244, + 225,102, 3,100, 73,100,165,101, 0,240,225,244,225,104,134, 5, + 178,100, 93,100, 98,100,112,100,121,100,136,100,152,177, 54,128, + 5,178, 50, 2,100,104,100,108, 51,128, 5,178,102,128, 5,178, + 232,229,226,242,229,119,128, 5,178,238,225,242,242,239,247,232, + 229,226,242,229,119,128, 5,178,241,245,225,242,244,229,242,232, + 229,226,242,229,119,128, 5,178,247,233,228,229,232,229,226,242, + 229,119,128, 5,178,241,225,237,225,244,115,135, 5,179,100,188, + 100,193,100,198,100,203,100,212,100,227,100,243,177, 98,128, 5, + 179,178, 56,128, 5,179,179, 52,128, 5,179,232,229,226,242,229, + 119,128, 5,179,238,225,242,242,239,247,232,229,226,242,229,119, + 128, 5,179,241,245,225,242,244,229,242,232,229,226,242,229,119, + 128, 5,179,247,233,228,229,232,229,226,242,229,119,128, 5,179, + 243,229,231,239,108,135, 5,177,101, 22,101, 27,101, 32,101, 37, + 101, 46,101, 61,101, 77,177, 55,128, 5,177,178, 52,128, 5,177, + 179, 48,128, 5,177,232,229,226,242,229,119,128, 5,177,238,225, + 242,242,239,247,232,229,226,242,229,119,128, 5,177,241,245,225, + 242,244,229,242,232,229,226,242,229,119,128, 5,177,247,233,228, + 229,232,229,226,242,229,119,128, 5,177, 98, 3,101, 98,101,103, + 101,113,225,114,128, 1, 39,239,240,239,237,239,230,111,128, 49, + 15,242,229,246,229,226,229,236,239,119,128, 30, 43, 99, 2,101, + 131,101,140,229,228,233,236,236, 97,128, 30, 41,233,242, 99, 2, + 101,148,101,153,236,101,128, 36,215,245,237,230,236,229,120,128, + 1, 37,100, 2,101,168,101,178,233,229,242,229,243,233,115,128, + 30, 39,239,116, 2,101,185,101,194,225,227,227,229,238,116,128, + 30, 35,226,229,236,239,119,128, 30, 37,101,136, 5,212,101,222, + 101,255,102, 19,102,248,103, 8,103, 53,103, 62,103, 75,225,242, + 116,129, 38,101,101,230,243,245,233,116, 2,101,239,101,247,226, + 236,225,227,107,128, 38,101,247,232,233,244,101,128, 38, 97,228, + 225,231,229,243,104,129,251, 52,102, 10,232,229,226,242,229,119, + 128,251, 52,104, 6,102, 33,102, 61,102, 69,102,119,102,165,102, + 214, 97, 2,102, 39,102, 53,236,244,239,238,229,225,242,225,226, + 233, 99,128, 6,193,242,225,226,233, 99,128, 6, 71,229,226,242, + 229,119,128, 5,212,230,233,238,225,236, 97, 2,102, 80,102,111, + 236,116, 2,102, 87,102, 99,239,238,229,225,242,225,226,233, 99, + 128,251,167,244,247,239,225,242,225,226,233, 99,128,254,234,242, + 225,226,233, 99,128,254,234,232,225,237,250,225,225,226,239,246, + 101, 2,102,134,102,148,230,233,238,225,236,225,242,225,226,233, + 99,128,251,165,233,243,239,236,225,244,229,228,225,242,225,226, + 233, 99,128,251,164,105, 2,102,171,102,205,238,233,244,233,225, + 236, 97, 2,102,183,102,197,236,244,239,238,229,225,242,225,226, + 233, 99,128,251,168,242,225,226,233, 99,128,254,235,242,225,231, + 225,238, 97,128, 48,120,237,229,228,233,225,236, 97, 2,102,226, + 102,240,236,244,239,238,229,225,242,225,226,233, 99,128,251,169, + 242,225,226,233, 99,128,254,236,233,243,229,233,229,242,225,243, + 241,245,225,242,101,128, 51,123,107, 2,103, 14,103, 38,225,244, + 225,235,225,238, 97,129, 48,216,103, 26,232,225,236,230,247,233, + 228,244,104,128,255,141,245,244,225,225,242,245,243,241,245,225, + 242,101,128, 51, 54,238,231,232,239,239,107,128, 2,103,242,245, + 244,245,243,241,245,225,242,101,128, 51, 57,116,129, 5,215,103, + 81,232,229,226,242,229,119,128, 5,215,232,239,239,107,129, 2, + 102,103, 99,243,245,240,229,242,233,239,114,128, 2,177,105, 4, + 103,120,103,205,103,216,103,241,229,245,104, 4,103,132,103,167, + 103,182,103,191, 97, 2,103,138,103,153,227,233,242,227,236,229, + 235,239,242,229,225,110,128, 50,123,240,225,242,229,238,235,239, + 242,229,225,110,128, 50, 27,227,233,242,227,236,229,235,239,242, + 229,225,110,128, 50,109,235,239,242,229,225,110,128, 49, 78,240, + 225,242,229,238,235,239,242,229,225,110,128, 50, 13,232,233,242, + 225,231,225,238, 97,128, 48,114,235,225,244,225,235,225,238, 97, + 129, 48,210,103,229,232,225,236,230,247,233,228,244,104,128,255, + 139,242,233,113,134, 5,180,104, 3,104, 8,104, 22,104, 31,104, + 46,104, 62,177, 52,128, 5,180, 50, 2,104, 14,104, 18, 49,128, + 5,180,100,128, 5,180,232,229,226,242,229,119,128, 5,180,238, + 225,242,242,239,247,232,229,226,242,229,119,128, 5,180,241,245, + 225,242,244,229,242,232,229,226,242,229,119,128, 5,180,247,233, + 228,229,232,229,226,242,229,119,128, 5,180,236,233,238,229,226, + 229,236,239,119,128, 30,150,237,239,238,239,243,240,225,227,101, + 128,255, 72,111, 9,104,119,104,130,104,154,104,179,105, 11,105, + 24,105,110,105,150,105,161,225,242,237,229,238,233,225,110,128, + 5,112,232,105, 2,104,137,104,145,240,244,232,225,105,128, 14, + 43,242,225,231,225,238, 97,128, 48,123,235,225,244,225,235,225, + 238, 97,129, 48,219,104,167,232,225,236,230,247,233,228,244,104, + 128,255,142,236,225,109,135, 5,185,104,199,104,204,104,209,104, + 214,104,223,104,238,104,254,177, 57,128, 5,185,178, 54,128, 5, + 185,179, 50,128, 5,185,232,229,226,242,229,119,128, 5,185,238, + 225,242,242,239,247,232,229,226,242,229,119,128, 5,185,241,245, + 225,242,244,229,242,232,229,226,242,229,119,128, 5,185,247,233, + 228,229,232,229,226,242,229,119,128, 5,185,238,239,235,232,245, + 235,244,232,225,105,128, 14, 46,111, 2,105, 30,105,100,107, 4, + 105, 40,105, 52,105, 58,105, 80,225,226,239,246,229,227,239,237, + 98,128, 3, 9,227,237, 98,128, 3, 9,240,225,236,225,244,225, + 236,233,250,229,228,226,229,236,239,247,227,237, 98,128, 3, 33, + 242,229,244,242,239,230,236,229,248,226,229,236,239,247,227,237, + 98,128, 3, 34,238,243,241,245,225,242,101,128, 51, 66,114, 2, + 105,116,105,143,105, 2,105,122,105,131,227,239,240,244,233, 99, + 128, 3,233,250,239,238,244,225,236,226,225,114,128, 32, 21,238, + 227,237, 98,128, 3, 27,244,243,240,242,233,238,231,115,128, 38, + 104,245,243,101,128, 35, 2,240,225,242,229,110,128, 36,163,243, + 245,240,229,242,233,239,114,128, 2,176,244,245,242,238,229,100, + 128, 2,101,117, 4,105,205,105,216,105,229,105,254,232,233,242, + 225,231,225,238, 97,128, 48,117,233,233,244,239,243,241,245,225, + 242,101,128, 51, 51,235,225,244,225,235,225,238, 97,129, 48,213, + 105,242,232,225,236,230,247,233,228,244,104,128,255,140,238,231, + 225,242,245,237,236,225,245,116,129, 2,221,106, 13,227,237, 98, + 128, 3, 11,118,128, 1,149,249,240,232,229,110,132, 0, 45,106, + 39,106, 50,106, 62,106, 85,233,238,230,229,242,233,239,114,128, + 246,229,237,239,238,239,243,240,225,227,101,128,255, 13,115, 2, + 106, 68,106, 75,237,225,236,108,128,254, 99,245,240,229,242,233, + 239,114,128,246,230,244,247,111,128, 32, 16,105,149, 0,105,106, + 137,106,160,106,194,106,241,110,123,110,243,111, 24,111, 51,111, + 213,111,217,111,255,112, 21,112,105,113, 14,113, 89,113, 97,113, + 110,113,197,113,254,114, 26,114, 70,225, 99, 2,106,144,106,150, + 245,244,101,128, 0,237,249,242,233,236,236,233, 99,128, 4, 79, + 98, 3,106,168,106,177,106,187,229,238,231,225,236,105,128, 9, + 135,239,240,239,237,239,230,111,128, 49, 39,242,229,246,101,128, + 1, 45, 99, 3,106,202,106,209,106,231,225,242,239,110,128, 1, + 208,233,242, 99, 2,106,217,106,222,236,101,128, 36,216,245,237, + 230,236,229,120,128, 0,238,249,242,233,236,236,233, 99,128, 4, + 86,100, 4,106,251,107, 5,110, 80,110,113,226,236,231,242,225, + 246,101,128, 2, 9,101, 2,107, 11,110, 75,239,231,242,225,240, + 104, 7,107, 32,107, 46,107, 59,109,244,110, 19,110, 32,110, 44, + 229,225,242,244,232,227,233,242,227,236,101,128, 50,143,230,233, + 242,229,227,233,242,227,236,101,128, 50,139,233, 99, 14,107, 90, + 107,106,107,205,108, 3,108, 69,108, 98,108,114,108,171,108,220, + 108,232,109, 3,109, 70,109,208,109,237,225,236,236,233,225,238, + 227,229,240,225,242,229,110,128, 50, 63, 99, 4,107,116,107,127, + 107,141,107,148,225,236,236,240,225,242,229,110,128, 50, 58,229, + 238,244,242,229,227,233,242,227,236,101,128, 50,165,236,239,243, + 101,128, 48, 6,111, 3,107,156,107,171,107,191,237,237, 97,129, + 48, 1,107,164,236,229,230,116,128,255,100,238,231,242,225,244, + 245,236,225,244,233,239,238,240,225,242,229,110,128, 50, 55,242, + 242,229,227,244,227,233,242,227,236,101,128, 50,163,101, 3,107, + 213,107,225,107,242,225,242,244,232,240,225,242,229,110,128, 50, + 47,238,244,229,242,240,242,233,243,229,240,225,242,229,110,128, + 50, 61,248,227,229,236,236,229,238,244,227,233,242,227,236,101, + 128, 50,157,102, 2,108, 9,108, 24,229,243,244,233,246,225,236, + 240,225,242,229,110,128, 50, 64,105, 2,108, 30,108, 59,238,225, + 238,227,233,225,108, 2,108, 42,108, 51,227,233,242,227,236,101, + 128, 50,150,240,225,242,229,110,128, 50, 54,242,229,240,225,242, + 229,110,128, 50, 43,104, 2,108, 75,108, 86,225,246,229,240,225, + 242,229,110,128, 50, 50,233,231,232,227,233,242,227,236,101,128, + 50,164,233,244,229,242,225,244,233,239,238,237,225,242,107,128, + 48, 5,108, 3,108,122,108,148,108,160,225,226,239,114, 2,108, + 131,108,140,227,233,242,227,236,101,128, 50,152,240,225,242,229, + 110,128, 50, 56,229,230,244,227,233,242,227,236,101,128, 50,167, + 239,247,227,233,242,227,236,101,128, 50,166,109, 2,108,177,108, + 209,101, 2,108,183,108,198,228,233,227,233,238,229,227,233,242, + 227,236,101,128, 50,169,244,225,236,240,225,242,229,110,128, 50, + 46,239,239,238,240,225,242,229,110,128, 50, 42,238,225,237,229, + 240,225,242,229,110,128, 50, 52,112, 2,108,238,108,246,229,242, + 233,239,100,128, 48, 2,242,233,238,244,227,233,242,227,236,101, + 128, 50,158,114, 2,109, 9,109, 57,101, 3,109, 17,109, 28,109, + 43,225,227,232,240,225,242,229,110,128, 50, 67,240,242,229,243, + 229,238,244,240,225,242,229,110,128, 50, 57,243,239,245,242,227, + 229,240,225,242,229,110,128, 50, 62,233,231,232,244,227,233,242, + 227,236,101,128, 50,168,115, 5,109, 82,109,111,109,125,109,150, + 109,178,101, 2,109, 88,109,101,227,242,229,244,227,233,242,227, + 236,101,128, 50,153,236,230,240,225,242,229,110,128, 50, 66,239, + 227,233,229,244,249,240,225,242,229,110,128, 50, 51,112, 2,109, + 131,109,137,225,227,101,128, 48, 0,229,227,233,225,236,240,225, + 242,229,110,128, 50, 53,116, 2,109,156,109,167,239,227,235,240, + 225,242,229,110,128, 50, 49,245,228,249,240,225,242,229,110,128, + 50, 59,117, 2,109,184,109,193,238,240,225,242,229,110,128, 50, + 48,240,229,242,246,233,243,229,240,225,242,229,110,128, 50, 60, + 119, 2,109,214,109,226,225,244,229,242,240,225,242,229,110,128, + 50, 44,239,239,228,240,225,242,229,110,128, 50, 45,250,229,242, + 111,128, 48, 7,109, 2,109,250,110, 7,229,244,225,236,227,233, + 242,227,236,101,128, 50,142,239,239,238,227,233,242,227,236,101, + 128, 50,138,238,225,237,229,227,233,242,227,236,101,128, 50,148, + 243,245,238,227,233,242,227,236,101,128, 50,144,119, 2,110, 50, + 110, 63,225,244,229,242,227,233,242,227,236,101,128, 50,140,239, + 239,228,227,233,242,227,236,101,128, 50,141,246, 97,128, 9, 7, + 233,229,242,229,243,233,115,130, 0,239,110, 94,110,102,225,227, + 245,244,101,128, 30, 47,227,249,242,233,236,236,233, 99,128, 4, + 229,239,244,226,229,236,239,119,128, 30,203,101, 3,110,131,110, + 147,110,158,226,242,229,246,229,227,249,242,233,236,236,233, 99, + 128, 4,215,227,249,242,233,236,236,233, 99,128, 4, 53,245,238, + 103, 4,110,170,110,205,110,220,110,229, 97, 2,110,176,110,191, + 227,233,242,227,236,229,235,239,242,229,225,110,128, 50,117,240, + 225,242,229,238,235,239,242,229,225,110,128, 50, 21,227,233,242, + 227,236,229,235,239,242,229,225,110,128, 50,103,235,239,242,229, + 225,110,128, 49, 71,240,225,242,229,238,235,239,242,229,225,110, + 128, 50, 7,103, 2,110,249,111, 0,242,225,246,101,128, 0,236, + 117, 2,111, 6,111, 15,234,225,242,225,244,105,128, 10,135,242, + 237,245,235,232,105,128, 10, 7,104, 2,111, 30,111, 40,233,242, + 225,231,225,238, 97,128, 48, 68,239,239,235,225,226,239,246,101, + 128, 30,201,105, 8,111, 69,111, 79,111, 90,111, 97,111,122,111, + 138,111,153,111,169,226,229,238,231,225,236,105,128, 9,136,227, + 249,242,233,236,236,233, 99,128, 4, 56,228,229,246, 97,128, 9, + 8,231,117, 2,111,104,111,113,234,225,242,225,244,105,128, 10, + 136,242,237,245,235,232,105,128, 10, 8,237,225,244,242,225,231, + 245,242,237,245,235,232,105,128, 10, 64,238,246,229,242,244,229, + 228,226,242,229,246,101,128, 2, 11,243,232,239,242,244,227,249, + 242,233,236,236,233, 99,128, 4, 57,246,239,247,229,236,243,233, + 231,110, 3,111,185,111,195,111,202,226,229,238,231,225,236,105, + 128, 9,192,228,229,246, 97,128, 9, 64,231,245,234,225,242,225, + 244,105,128, 10,192,106,128, 1, 51,107, 2,111,223,111,247,225, + 244,225,235,225,238, 97,129, 48,164,111,235,232,225,236,230,247, + 233,228,244,104,128,255,114,239,242,229,225,110,128, 49, 99,108, + 2,112, 5,112, 10,228,101,128, 2,220,245,249,232,229,226,242, + 229,119,128, 5,172,109, 2,112, 27,112, 94, 97, 3,112, 35,112, + 55,112, 80,227,242,239,110,129, 1, 43,112, 44,227,249,242,233, + 236,236,233, 99,128, 4,227,231,229,239,242,225,240,240,242,239, + 248,233,237,225,244,229,236,249,229,241,245,225,108,128, 34, 83, + 244,242,225,231,245,242,237,245,235,232,105,128, 10, 63,239,238, + 239,243,240,225,227,101,128,255, 73,110, 5,112,117,112,127,112, + 136,112,148,112,232,227,242,229,237,229,238,116,128, 34, 6,230, + 233,238,233,244,121,128, 34, 30,233,225,242,237,229,238,233,225, + 110,128, 5,107,116, 2,112,154,112,222,101, 2,112,160,112,211, + 231,242,225,108,131, 34, 43,112,173,112,191,112,196, 98, 2,112, + 179,112,187,239,244,244,239,109,128, 35, 33,116,128, 35, 33,229, + 120,128,248,245,116, 2,112,202,112,207,239,112,128, 35, 32,112, + 128, 35, 32,242,243,229,227,244,233,239,110,128, 34, 41,233,243, + 241,245,225,242,101,128, 51, 5,118, 3,112,240,112,249,113, 2, + 226,245,236,236,229,116,128, 37,216,227,233,242,227,236,101,128, + 37,217,243,237,233,236,229,230,225,227,101,128, 38, 59,111, 3, + 113, 22,113, 33,113, 41,227,249,242,233,236,236,233, 99,128, 4, + 81,231,239,238,229,107,128, 1, 47,244, 97,131, 3,185,113, 52, + 113, 73,113, 81,228,233,229,242,229,243,233,115,129, 3,202,113, + 65,244,239,238,239,115,128, 3,144,236,225,244,233,110,128, 2, + 105,244,239,238,239,115,128, 3,175,240,225,242,229,110,128, 36, + 164,242,233,231,245,242,237,245,235,232,105,128, 10,114,115, 4, + 113,120,113,165,113,179,113,187,237,225,236,108, 2,113,129,113, + 140,232,233,242,225,231,225,238, 97,128, 48, 67,235,225,244,225, + 235,225,238, 97,129, 48,163,113,153,232,225,236,230,247,233,228, + 244,104,128,255,104,243,232,225,242,226,229,238,231,225,236,105, + 128, 9,250,244,242,239,235,101,128, 2,104,245,240,229,242,233, + 239,114,128,246,237,116, 2,113,203,113,237,229,242,225,244,233, + 239,110, 2,113,215,113,226,232,233,242,225,231,225,238, 97,128, + 48,157,235,225,244,225,235,225,238, 97,128, 48,253,233,236,228, + 101,129, 1, 41,113,246,226,229,236,239,119,128, 30, 45,117, 2, + 114, 4,114, 15,226,239,240,239,237,239,230,111,128, 49, 41,227, + 249,242,233,236,236,233, 99,128, 4, 78,246,239,247,229,236,243, + 233,231,110, 3,114, 42,114, 52,114, 59,226,229,238,231,225,236, + 105,128, 9,191,228,229,246, 97,128, 9, 63,231,245,234,225,242, + 225,244,105,128, 10,191,250,232,233,244,243, 97, 2,114, 81,114, + 92,227,249,242,233,236,236,233, 99,128, 4,117,228,226,236,231, + 242,225,246,229,227,249,242,233,236,236,233, 99,128, 4,119,106, + 138, 0,106,114,135,114,198,114,209,115, 3,115, 19,115,132,115, + 201,115,206,115,218,115,226, 97, 4,114,145,114,156,114,166,114, + 173,225,242,237,229,238,233,225,110,128, 5,113,226,229,238,231, + 225,236,105,128, 9,156,228,229,246, 97,128, 9, 28,231,117, 2, + 114,180,114,189,234,225,242,225,244,105,128, 10,156,242,237,245, + 235,232,105,128, 10, 28,226,239,240,239,237,239,230,111,128, 49, + 16, 99, 3,114,217,114,224,114,246,225,242,239,110,128, 1,240, + 233,242, 99, 2,114,232,114,237,236,101,128, 36,217,245,237,230, + 236,229,120,128, 1, 53,242,239,243,243,229,228,244,225,233,108, + 128, 2,157,228,239,244,236,229,243,243,243,244,242,239,235,101, + 128, 2, 95,101, 3,115, 27,115, 38,115,103,227,249,242,233,236, + 236,233, 99,128, 4, 88,229,109, 4,115, 49,115, 58,115, 72,115, + 88,225,242,225,226,233, 99,128, 6, 44,230,233,238,225,236,225, + 242,225,226,233, 99,128,254,158,233,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,254,159,237,229,228,233,225,236,225,242, + 225,226,233, 99,128,254,160,104, 2,115,109,115,118,225,242,225, + 226,233, 99,128, 6,152,230,233,238,225,236,225,242,225,226,233, + 99,128,251,139,104, 2,115,138,115,188, 97, 3,115,146,115,156, + 115,163,226,229,238,231,225,236,105,128, 9,157,228,229,246, 97, + 128, 9, 29,231,117, 2,115,170,115,179,234,225,242,225,244,105, + 128, 10,157,242,237,245,235,232,105,128, 10, 29,229,232,225,242, + 237,229,238,233,225,110,128, 5,123,233,115,128, 48, 4,237,239, + 238,239,243,240,225,227,101,128,255, 74,240,225,242,229,110,128, + 36,165,243,245,240,229,242,233,239,114,128, 2,178,107,146, 0, + 107,116, 21,118,110,118,121,118,183,118,194,119, 28,119, 42,120, + 150,121, 90,121,103,121,129,121,178,122, 60,122, 82,122, 95,122, + 118,122,160,122,170, 97, 12,116, 47,116, 79,116,101,116,131,116, + 245,117, 14,117, 44,117, 69,117,175,117,189,118, 56,118, 85, 98, + 2,116, 53,116, 70,225,243,232,235,233,242,227,249,242,233,236, + 236,233, 99,128, 4,161,229,238,231,225,236,105,128, 9,149, 99, + 2,116, 85,116, 91,245,244,101,128, 30, 49,249,242,233,236,236, + 233, 99,128, 4, 58,228,101, 2,116,108,116,126,243,227,229,238, + 228,229,242,227,249,242,233,236,236,233, 99,128, 4,155,246, 97, + 128, 9, 21,102,135, 5,219,116,149,116,158,116,178,116,192,116, + 201,116,217,116,232,225,242,225,226,233, 99,128, 6, 67,228,225, + 231,229,243,104,129,251, 59,116,169,232,229,226,242,229,119,128, + 251, 59,230,233,238,225,236,225,242,225,226,233, 99,128,254,218, + 232,229,226,242,229,119,128, 5,219,233,238,233,244,233,225,236, + 225,242,225,226,233, 99,128,254,219,237,229,228,233,225,236,225, + 242,225,226,233, 99,128,254,220,242,225,230,229,232,229,226,242, + 229,119,128,251, 77,231,117, 2,116,252,117, 5,234,225,242,225, + 244,105,128, 10,149,242,237,245,235,232,105,128, 10, 21,104, 2, + 117, 20,117, 30,233,242,225,231,225,238, 97,128, 48, 75,239,239, + 235,227,249,242,233,236,236,233, 99,128, 4,196,235,225,244,225, + 235,225,238, 97,129, 48,171,117, 57,232,225,236,230,247,233,228, + 244,104,128,255,118,112, 2,117, 75,117, 96,240, 97,129, 3,186, + 117, 82,243,249,237,226,239,236,231,242,229,229,107,128, 3,240, + 249,229,239,245,110, 3,117,108,117,122,117,156,237,233,229,245, + 237,235,239,242,229,225,110,128, 49,113,112, 2,117,128,117,143, + 232,233,229,245,240,232,235,239,242,229,225,110,128, 49,132,233, + 229,245,240,235,239,242,229,225,110,128, 49,120,243,243,225,238, + 231,240,233,229,245,240,235,239,242,229,225,110,128, 49,121,242, + 239,242,233,233,243,241,245,225,242,101,128, 51, 13,115, 5,117, + 201,117,245,118, 4,118, 12,118, 40,232,233,228,225,225,245,244, + 111, 2,117,214,117,223,225,242,225,226,233, 99,128, 6, 64,238, + 239,243,233,228,229,226,229,225,242,233,238,231,225,242,225,226, + 233, 99,128, 6, 64,237,225,236,236,235,225,244,225,235,225,238, + 97,128, 48,245,241,245,225,242,101,128, 51,132,242, 97, 2,118, + 19,118, 28,225,242,225,226,233, 99,128, 6, 80,244,225,238,225, + 242,225,226,233, 99,128, 6, 77,244,242,239,235,229,227,249,242, + 233,236,236,233, 99,128, 4,159,244,225,232,233,242,225,240,242, + 239,236,239,238,231,237,225,242,235,232,225,236,230,247,233,228, + 244,104,128,255,112,246,229,242,244,233,227,225,236,243,244,242, + 239,235,229,227,249,242,233,236,236,233, 99,128, 4,157,226,239, + 240,239,237,239,230,111,128, 49, 14, 99, 4,118,131,118,153,118, + 162,118,170, 97, 2,118,137,118,147,236,243,241,245,225,242,101, + 128, 51,137,242,239,110,128, 1,233,229,228,233,236,236, 97,128, + 1, 55,233,242,227,236,101,128, 36,218,239,237,237,225,225,227, + 227,229,238,116,128, 1, 55,228,239,244,226,229,236,239,119,128, + 30, 51,101, 4,118,204,118,231,119, 0,119, 12,104, 2,118,210, + 118,221,225,242,237,229,238,233,225,110,128, 5,132,233,242,225, + 231,225,238, 97,128, 48, 81,235,225,244,225,235,225,238, 97,129, + 48,177,118,244,232,225,236,230,247,233,228,244,104,128,255,121, + 238,225,242,237,229,238,233,225,110,128, 5,111,243,237,225,236, + 236,235,225,244,225,235,225,238, 97,128, 48,246,231,242,229,229, + 238,236,225,238,228,233, 99,128, 1, 56,104, 6,119, 56,119,185, + 119,196,119,221,120, 52,120,140, 97, 5,119, 68,119, 78,119, 89, + 119, 96,119,121,226,229,238,231,225,236,105,128, 9,150,227,249, + 242,233,236,236,233, 99,128, 4, 69,228,229,246, 97,128, 9, 22, + 231,117, 2,119,103,119,112,234,225,242,225,244,105,128, 10,150, + 242,237,245,235,232,105,128, 10, 22,104, 4,119,131,119,140,119, + 154,119,170,225,242,225,226,233, 99,128, 6, 46,230,233,238,225, + 236,225,242,225,226,233, 99,128,254,166,233,238,233,244,233,225, + 236,225,242,225,226,233, 99,128,254,167,237,229,228,233,225,236, + 225,242,225,226,233, 99,128,254,168,229,233,227,239,240,244,233, + 99,128, 3,231,232, 97, 2,119,203,119,210,228,229,246, 97,128, + 9, 89,231,245,242,237,245,235,232,105,128, 10, 89,233,229,245, + 235,104, 4,119,235,120, 14,120, 29,120, 38, 97, 2,119,241,120, + 0,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,120, + 240,225,242,229,238,235,239,242,229,225,110,128, 50, 24,227,233, + 242,227,236,229,235,239,242,229,225,110,128, 50,106,235,239,242, + 229,225,110,128, 49, 75,240,225,242,229,238,235,239,242,229,225, + 110,128, 50, 10,111, 4,120, 62,120,111,120,121,120,126,235,104, + 4,120, 73,120, 82,120, 91,120,101,225,233,244,232,225,105,128, + 14, 2,239,238,244,232,225,105,128, 14, 5,245,225,244,244,232, + 225,105,128, 14, 3,247,225,233,244,232,225,105,128, 14, 4,237, + 245,244,244,232,225,105,128, 14, 91,239,107,128, 1,153,242,225, + 235,232,225,238,231,244,232,225,105,128, 14, 6,250,243,241,245, + 225,242,101,128, 51,145,105, 4,120,160,120,171,120,196,120,245, + 232,233,242,225,231,225,238, 97,128, 48, 77,235,225,244,225,235, + 225,238, 97,129, 48,173,120,184,232,225,236,230,247,233,228,244, + 104,128,255,119,242,111, 3,120,205,120,220,120,236,231,245,242, + 225,237,245,243,241,245,225,242,101,128, 51, 21,237,229,229,244, + 239,242,245,243,241,245,225,242,101,128, 51, 22,243,241,245,225, + 242,101,128, 51, 20,249,229,239,107, 5,121, 4,121, 39,121, 54, + 121, 63,121, 77, 97, 2,121, 10,121, 25,227,233,242,227,236,229, + 235,239,242,229,225,110,128, 50,110,240,225,242,229,238,235,239, + 242,229,225,110,128, 50, 14,227,233,242,227,236,229,235,239,242, + 229,225,110,128, 50, 96,235,239,242,229,225,110,128, 49, 49,240, + 225,242,229,238,235,239,242,229,225,110,128, 50, 0,243,233,239, + 243,235,239,242,229,225,110,128, 49, 51,234,229,227,249,242,233, + 236,236,233, 99,128, 4, 92,108, 2,121,109,121,120,233,238,229, + 226,229,236,239,119,128, 30, 53,243,241,245,225,242,101,128, 51, + 152,109, 3,121,137,121,151,121,162,227,245,226,229,228,243,241, + 245,225,242,101,128, 51,166,239,238,239,243,240,225,227,101,128, + 255, 75,243,241,245,225,242,229,228,243,241,245,225,242,101,128, + 51,162,111, 5,121,190,121,216,121,254,122, 10,122, 24,104, 2, + 121,196,121,206,233,242,225,231,225,238, 97,128, 48, 83,237,243, + 241,245,225,242,101,128, 51,192,235, 97, 2,121,223,121,231,233, + 244,232,225,105,128, 14, 1,244,225,235,225,238, 97,129, 48,179, + 121,242,232,225,236,230,247,233,228,244,104,128,255,122,239,240, + 239,243,241,245,225,242,101,128, 51, 30,240,240,225,227,249,242, + 233,236,236,233, 99,128, 4,129,114, 2,122, 30,122, 50,229,225, + 238,243,244,225,238,228,225,242,228,243,249,237,226,239,108,128, + 50,127,239,238,233,243,227,237, 98,128, 3, 67,240, 97, 2,122, + 67,122, 73,242,229,110,128, 36,166,243,241,245,225,242,101,128, + 51,170,243,233,227,249,242,233,236,236,233, 99,128, 4,111,116, + 2,122,101,122,110,243,241,245,225,242,101,128, 51,207,245,242, + 238,229,100,128, 2,158,117, 2,122,124,122,135,232,233,242,225, + 231,225,238, 97,128, 48, 79,235,225,244,225,235,225,238, 97,129, + 48,175,122,148,232,225,236,230,247,233,228,244,104,128,255,120, + 246,243,241,245,225,242,101,128, 51,184,247,243,241,245,225,242, + 101,128, 51,190,108,146, 0,108,122,220,124,247,125, 20,125, 86, + 125,124,126, 20,126, 29,126, 45,126, 69,126, 87,126,205,126,246, + 127,125,127,133,127,166,127,175,127,183,127,245, 97, 7,122,236, + 122,246,122,253,123, 4,123, 29,123, 45,124,235,226,229,238,231, + 225,236,105,128, 9,178,227,245,244,101,128, 1, 58,228,229,246, + 97,128, 9, 50,231,117, 2,123, 11,123, 20,234,225,242,225,244, + 105,128, 10,178,242,237,245,235,232,105,128, 10, 50,235,235,232, + 225,238,231,249,225,239,244,232,225,105,128, 14, 69,109, 10,123, + 67,124, 6,124, 23,124, 61,124, 75,124, 94,124,110,124,130,124, + 150,124,173, 97, 2,123, 73,123,254,236,229,102, 4,123, 85,123, + 99,123,191,123,208,230,233,238,225,236,225,242,225,226,233, 99, + 128,254,252,232,225,237,250, 97, 2,123,109,123,150,225,226,239, + 246,101, 2,123,119,123,133,230,233,238,225,236,225,242,225,226, + 233, 99,128,254,248,233,243,239,236,225,244,229,228,225,242,225, + 226,233, 99,128,254,247,226,229,236,239,119, 2,123,160,123,174, + 230,233,238,225,236,225,242,225,226,233, 99,128,254,250,233,243, + 239,236,225,244,229,228,225,242,225,226,233, 99,128,254,249,233, + 243,239,236,225,244,229,228,225,242,225,226,233, 99,128,254,251, + 237,225,228,228,225,225,226,239,246,101, 2,123,223,123,237,230, + 233,238,225,236,225,242,225,226,233, 99,128,254,246,233,243,239, + 236,225,244,229,228,225,242,225,226,233, 99,128,254,245,242,225, + 226,233, 99,128, 6, 68,226,228, 97,129, 3,187,124, 14,243,244, + 242,239,235,101,128, 1,155,229,100,130, 5,220,124, 32,124, 52, + 228,225,231,229,243,104,129,251, 60,124, 43,232,229,226,242,229, + 119,128,251, 60,232,229,226,242,229,119,128, 5,220,230,233,238, + 225,236,225,242,225,226,233, 99,128,254,222,232,225,232,233,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,252,202,233,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,254,223,234,229, + 229,237,233,238,233,244,233,225,236,225,242,225,226,233, 99,128, + 252,201,235,232,225,232,233,238,233,244,233,225,236,225,242,225, + 226,233, 99,128,252,203,236,225,237,232,229,232,233,243,239,236, + 225,244,229,228,225,242,225,226,233, 99,128,253,242,237,101, 2, + 124,180,124,193,228,233,225,236,225,242,225,226,233, 99,128,254, + 224,229,109, 2,124,200,124,219,232,225,232,233,238,233,244,233, + 225,236,225,242,225,226,233, 99,128,253,136,233,238,233,244,233, + 225,236,225,242,225,226,233, 99,128,252,204,242,231,229,227,233, + 242,227,236,101,128, 37,239, 98, 3,124,255,125, 4,125, 10,225, + 114,128, 1,154,229,236,116,128, 2,108,239,240,239,237,239,230, + 111,128, 49, 12, 99, 4,125, 30,125, 37,125, 46,125, 73,225,242, + 239,110,128, 1, 62,229,228,233,236,236, 97,128, 1, 60,233,242, + 99, 2,125, 54,125, 59,236,101,128, 36,219,245,237,230,236,229, + 248,226,229,236,239,119,128, 30, 61,239,237,237,225,225,227,227, + 229,238,116,128, 1, 60,228,239,116,130, 1, 64,125, 96,125,105, + 225,227,227,229,238,116,128, 1, 64,226,229,236,239,119,129, 30, + 55,125,115,237,225,227,242,239,110,128, 30, 57,101, 3,125,132, + 125,170,126, 15,230,116, 2,125,139,125,155,225,238,231,236,229, + 225,226,239,246,229,227,237, 98,128, 3, 26,244,225,227,235,226, + 229,236,239,247,227,237, 98,128, 3, 24,243,115,132, 0, 60,125, + 183,125,205,125,217,126, 7,229,241,245,225,108,129, 34,100,125, + 193,239,242,231,242,229,225,244,229,114,128, 34,218,237,239,238, + 239,243,240,225,227,101,128,255, 28,111, 2,125,223,125,252,114, + 2,125,229,125,242,229,241,245,233,246,225,236,229,238,116,128, + 34,114,231,242,229,225,244,229,114,128, 34,118,246,229,242,229, + 241,245,225,108,128, 34,102,243,237,225,236,108,128,254,100,250, + 104,128, 2,110,230,226,236,239,227,107,128, 37,140,232,239,239, + 235,242,229,244,242,239,230,236,229,120,128, 2,109,105, 2,126, + 51,126, 56,242, 97,128, 32,164,247,238,225,242,237,229,238,233, + 225,110,128, 5,108,106,129, 1,201,126, 75,229,227,249,242,233, + 236,236,233, 99,128, 4, 89,108,132,246,192,126, 99,126,123,126, + 134,126,143, 97, 2,126,105,126,112,228,229,246, 97,128, 9, 51, + 231,245,234,225,242,225,244,105,128, 10,179,233,238,229,226,229, + 236,239,119,128, 30, 59,236,225,228,229,246, 97,128, 9, 52,246, + 239,227,225,236,233, 99, 3,126,157,126,167,126,174,226,229,238, + 231,225,236,105,128, 9,225,228,229,246, 97,128, 9, 97,246,239, + 247,229,236,243,233,231,110, 2,126,188,126,198,226,229,238,231, + 225,236,105,128, 9,227,228,229,246, 97,128, 9, 99,109, 3,126, + 213,126,226,126,237,233,228,228,236,229,244,233,236,228,101,128, + 2,107,239,238,239,243,240,225,227,101,128,255, 76,243,241,245, + 225,242,101,128, 51,208,111, 6,127, 4,127, 16,127, 58,127, 69, + 127, 75,127,117,227,232,245,236,225,244,232,225,105,128, 14, 44, + 231,233,227,225,108, 3,127, 28,127, 34,127, 53,225,238,100,128, + 34, 39,238,239,116,129, 0,172,127, 42,242,229,246,229,242,243, + 229,100,128, 35, 16,239,114,128, 34, 40,236,233,238,231,244,232, + 225,105,128, 14, 37,238,231,115,128, 1,127,247,236,233,238,101, + 2,127, 85,127,108, 99, 2,127, 91,127,103,229,238,244,229,242, + 236,233,238,101,128,254, 78,237, 98,128, 3, 50,228,225,243,232, + 229,100,128,254, 77,250,229,238,231,101,128, 37,202,240,225,242, + 229,110,128, 36,167,115, 3,127,141,127,148,127,156,236,225,243, + 104,128, 1, 66,241,245,225,242,101,128, 33, 19,245,240,229,242, + 233,239,114,128,246,238,244,243,232,225,228,101,128, 37,145,245, + 244,232,225,105,128, 14, 38,246,239,227,225,236,233, 99, 3,127, + 197,127,207,127,214,226,229,238,231,225,236,105,128, 9,140,228, + 229,246, 97,128, 9, 12,246,239,247,229,236,243,233,231,110, 2, + 127,228,127,238,226,229,238,231,225,236,105,128, 9,226,228,229, + 246, 97,128, 9, 98,248,243,241,245,225,242,101,128, 51,211,109, + 144, 0,109,128, 35,130,144,130,169,130,196,130,221,132, 18,132, + 40,133, 95,133,125,133,174,134, 25,134, 47,134, 72,134, 81,135, + 108,135,136, 97, 12,128, 61,128, 71,128,135,128,142,128,167,128, + 215,130, 51,130, 76,130, 81,130, 95,130,107,130,112,226,229,238, + 231,225,236,105,128, 9,174, 99, 2,128, 77,128,129,242,239,110, + 132, 0,175,128, 91,128,102,128,108,128,117,226,229,236,239,247, + 227,237, 98,128, 3, 49,227,237, 98,128, 3, 4,236,239,247,237, + 239,100,128, 2,205,237,239,238,239,243,240,225,227,101,128,255, + 227,245,244,101,128, 30, 63,228,229,246, 97,128, 9, 46,231,117, + 2,128,149,128,158,234,225,242,225,244,105,128, 10,174,242,237, + 245,235,232,105,128, 10, 46,104, 2,128,173,128,205,225,240,225, + 235,104, 2,128,183,128,192,232,229,226,242,229,119,128, 5,164, + 236,229,230,244,232,229,226,242,229,119,128, 5,164,233,242,225, + 231,225,238, 97,128, 48,126,105, 5,128,227,129, 40,129,103,129, + 133,130, 39,227,232,225,244,244,225,247, 97, 3,128,242,129, 17, + 129, 24,236,239,119, 2,128,250,129, 5,236,229,230,244,244,232, + 225,105,128,248,149,242,233,231,232,244,244,232,225,105,128,248, + 148,244,232,225,105,128, 14, 75,245,240,240,229,242,236,229,230, + 244,244,232,225,105,128,248,147,229,107, 3,129, 49,129, 80,129, + 87,236,239,119, 2,129, 57,129, 68,236,229,230,244,244,232,225, + 105,128,248,140,242,233,231,232,244,244,232,225,105,128,248,139, + 244,232,225,105,128, 14, 72,245,240,240,229,242,236,229,230,244, + 244,232,225,105,128,248,138,232,225,238,225,235,225,116, 2,129, + 115,129,126,236,229,230,244,244,232,225,105,128,248,132,244,232, + 225,105,128, 14, 49,116, 3,129,141,129,169,129,232,225,233,235, + 232,117, 2,129,151,129,162,236,229,230,244,244,232,225,105,128, + 248,137,244,232,225,105,128, 14, 71,232,111, 3,129,178,129,209, + 129,216,236,239,119, 2,129,186,129,197,236,229,230,244,244,232, + 225,105,128,248,143,242,233,231,232,244,244,232,225,105,128,248, + 142,244,232,225,105,128, 14, 73,245,240,240,229,242,236,229,230, + 244,244,232,225,105,128,248,141,242,105, 3,129,241,130, 16,130, + 23,236,239,119, 2,129,249,130, 4,236,229,230,244,244,232,225, + 105,128,248,146,242,233,231,232,244,244,232,225,105,128,248,145, + 244,232,225,105,128, 14, 74,245,240,240,229,242,236,229,230,244, + 244,232,225,105,128,248,144,249,225,237,239,235,244,232,225,105, + 128, 14, 70,235,225,244,225,235,225,238, 97,129, 48,222,130, 64, + 232,225,236,230,247,233,228,244,104,128,255,143,236,101,128, 38, + 66,238,243,249,239,238,243,241,245,225,242,101,128, 51, 71,241, + 225,230,232,229,226,242,229,119,128, 5,190,242,115,128, 38, 66, + 115, 2,130,118,130,136,239,242,225,227,233,242,227,236,229,232, + 229,226,242,229,119,128, 5,175,241,245,225,242,101,128, 51,131, + 98, 2,130,150,130,160,239,240,239,237,239,230,111,128, 49, 7, + 243,241,245,225,242,101,128, 51,212, 99, 2,130,175,130,183,233, + 242,227,236,101,128, 36,220,245,226,229,228,243,241,245,225,242, + 101,128, 51,165,228,239,116, 2,130,204,130,213,225,227,227,229, + 238,116,128, 30, 65,226,229,236,239,119,128, 30, 67,101, 7,130, + 237,131,108,131,119,131,134,131,159,131,196,131,208,101, 2,130, + 243,131, 95,109, 4,130,253,131, 6,131, 20,131, 36,225,242,225, + 226,233, 99,128, 6, 69,230,233,238,225,236,225,242,225,226,233, + 99,128,254,226,233,238,233,244,233,225,236,225,242,225,226,233, + 99,128,254,227,237,101, 2,131, 43,131, 56,228,233,225,236,225, + 242,225,226,233, 99,128,254,228,229,237,105, 2,131, 64,131, 79, + 238,233,244,233,225,236,225,242,225,226,233, 99,128,252,209,243, + 239,236,225,244,229,228,225,242,225,226,233, 99,128,252, 72,244, + 239,242,245,243,241,245,225,242,101,128, 51, 77,232,233,242,225, + 231,225,238, 97,128, 48,129,233,250,233,229,242,225,243,241,245, + 225,242,101,128, 51,126,235,225,244,225,235,225,238, 97,129, 48, + 225,131,147,232,225,236,230,247,233,228,244,104,128,255,146,109, + 130, 5,222,131,167,131,187,228,225,231,229,243,104,129,251, 62, + 131,178,232,229,226,242,229,119,128,251, 62,232,229,226,242,229, + 119,128, 5,222,238,225,242,237,229,238,233,225,110,128, 5,116, + 242,235,232, 97, 3,131,219,131,228,132, 5,232,229,226,242,229, + 119,128, 5,165,235,229,230,245,236, 97, 2,131,239,131,248,232, + 229,226,242,229,119,128, 5,166,236,229,230,244,232,229,226,242, + 229,119,128, 5,166,236,229,230,244,232,229,226,242,229,119,128, + 5,165,104, 2,132, 24,132, 30,239,239,107,128, 2,113,250,243, + 241,245,225,242,101,128, 51,146,105, 6,132, 54,132, 91,132,228, + 132,239,133, 8,133, 65,228,100, 2,132, 61,132, 86,236,229,228, + 239,244,235,225,244,225,235,225,238,225,232,225,236,230,247,233, + 228,244,104,128,255,101,239,116,128, 0,183,229,245,109, 5,132, + 105,132,140,132,155,132,164,132,215, 97, 2,132,111,132,126,227, + 233,242,227,236,229,235,239,242,229,225,110,128, 50,114,240,225, + 242,229,238,235,239,242,229,225,110,128, 50, 18,227,233,242,227, + 236,229,235,239,242,229,225,110,128, 50,100,235,239,242,229,225, + 110,128, 49, 65,112, 2,132,170,132,202, 97, 2,132,176,132,190, + 238,243,233,239,243,235,239,242,229,225,110,128, 49,112,242,229, + 238,235,239,242,229,225,110,128, 50, 4,233,229,245,240,235,239, + 242,229,225,110,128, 49,110,243,233,239,243,235,239,242,229,225, + 110,128, 49,111,232,233,242,225,231,225,238, 97,128, 48,127,235, + 225,244,225,235,225,238, 97,129, 48,223,132,252,232,225,236,230, + 247,233,228,244,104,128,255,144,238,117, 2,133, 15,133, 60,115, + 132, 34, 18,133, 27,133, 38,133, 47,133, 53,226,229,236,239,247, + 227,237, 98,128, 3, 32,227,233,242,227,236,101,128, 34,150,237, + 239,100,128, 2,215,240,236,245,115,128, 34, 19,244,101,128, 32, + 50,242,105, 2,133, 72,133, 86,226,225,225,242,245,243,241,245, + 225,242,101,128, 51, 74,243,241,245,225,242,101,128, 51, 73,108, + 2,133,101,133,116,239,238,231,236,229,231,244,245,242,238,229, + 100,128, 2,112,243,241,245,225,242,101,128, 51,150,109, 3,133, + 133,133,147,133,158,227,245,226,229,228,243,241,245,225,242,101, + 128, 51,163,239,238,239,243,240,225,227,101,128,255, 77,243,241, + 245,225,242,229,228,243,241,245,225,242,101,128, 51,159,111, 5, + 133,186,133,212,133,237,133,247,134, 0,104, 2,133,192,133,202, + 233,242,225,231,225,238, 97,128, 48,130,237,243,241,245,225,242, + 101,128, 51,193,235,225,244,225,235,225,238, 97,129, 48,226,133, + 225,232,225,236,230,247,233,228,244,104,128,255,147,236,243,241, + 245,225,242,101,128, 51,214,237,225,244,232,225,105,128, 14, 33, + 246,229,242,243,243,241,245,225,242,101,129, 51,167,134, 15,228, + 243,241,245,225,242,101,128, 51,168,240, 97, 2,134, 32,134, 38, + 242,229,110,128, 36,168,243,241,245,225,242,101,128, 51,171,115, + 2,134, 53,134, 62,243,241,245,225,242,101,128, 51,179,245,240, + 229,242,233,239,114,128,246,239,244,245,242,238,229,100,128, 2, + 111,117,141, 0,181,134,111,134,115,134,125,134,149,134,159,134, + 181,134,192,134,217,134,240,134,250,135, 24,135, 88,135, 98, 49, + 128, 0,181,225,243,241,245,225,242,101,128, 51,130,227,104, 2, + 134,132,134,142,231,242,229,225,244,229,114,128, 34,107,236,229, + 243,115,128, 34,106,230,243,241,245,225,242,101,128, 51,140,103, + 2,134,165,134,172,242,229,229,107,128, 3,188,243,241,245,225, + 242,101,128, 51,141,232,233,242,225,231,225,238, 97,128, 48,128, + 235,225,244,225,235,225,238, 97,129, 48,224,134,205,232,225,236, + 230,247,233,228,244,104,128,255,145,108, 2,134,223,134,232,243, + 241,245,225,242,101,128, 51,149,244,233,240,236,121,128, 0,215, + 237,243,241,245,225,242,101,128, 51,155,238,225,104, 2,135, 2, + 135, 11,232,229,226,242,229,119,128, 5,163,236,229,230,244,232, + 229,226,242,229,119,128, 5,163,115, 2,135, 30,135, 79,233, 99, + 3,135, 39,135, 56,135, 67,225,236,238,239,244,101,129, 38,106, + 135, 50,228,226,108,128, 38,107,230,236,225,244,243,233,231,110, + 128, 38,109,243,232,225,242,240,243,233,231,110,128, 38,111,243, + 241,245,225,242,101,128, 51,178,246,243,241,245,225,242,101,128, + 51,182,247,243,241,245,225,242,101,128, 51,188,118, 2,135,114, + 135,127,237,229,231,225,243,241,245,225,242,101,128, 51,185,243, + 241,245,225,242,101,128, 51,183,119, 2,135,142,135,155,237,229, + 231,225,243,241,245,225,242,101,128, 51,191,243,241,245,225,242, + 101,128, 51,189,110,150, 0,110,135,212,136, 90,136,114,136,180, + 136,205,137, 7,137, 17,137, 84,137,127,139,161,139,179,139,204, + 139,235,140, 5,140, 70,142, 52,142, 60,142, 85,142, 93,143, 61, + 143, 71,143, 81, 97, 8,135,230,135,250,136, 1,136, 8,136, 33, + 136, 44,136, 69,136, 81, 98, 2,135,236,135,245,229,238,231,225, + 236,105,128, 9,168,236, 97,128, 34, 7,227,245,244,101,128, 1, + 68,228,229,246, 97,128, 9, 40,231,117, 2,136, 15,136, 24,234, + 225,242,225,244,105,128, 10,168,242,237,245,235,232,105,128, 10, + 40,232,233,242,225,231,225,238, 97,128, 48,106,235,225,244,225, + 235,225,238, 97,129, 48,202,136, 57,232,225,236,230,247,233,228, + 244,104,128,255,133,240,239,243,244,242,239,240,232,101,128, 1, + 73,243,241,245,225,242,101,128, 51,129, 98, 2,136, 96,136,106, + 239,240,239,237,239,230,111,128, 49, 11,243,240,225,227,101,128, + 0,160, 99, 4,136,124,136,131,136,140,136,167,225,242,239,110, + 128, 1, 72,229,228,233,236,236, 97,128, 1, 70,233,242, 99, 2, + 136,148,136,153,236,101,128, 36,221,245,237,230,236,229,248,226, + 229,236,239,119,128, 30, 75,239,237,237,225,225,227,227,229,238, + 116,128, 1, 70,228,239,116, 2,136,188,136,197,225,227,227,229, + 238,116,128, 30, 69,226,229,236,239,119,128, 30, 71,101, 3,136, + 213,136,224,136,249,232,233,242,225,231,225,238, 97,128, 48,109, + 235,225,244,225,235,225,238, 97,129, 48,205,136,237,232,225,236, + 230,247,233,228,244,104,128,255,136,247,243,232,229,241,229,236, + 243,233,231,110,128, 32,170,230,243,241,245,225,242,101,128, 51, + 139,103, 2,137, 23,137, 73, 97, 3,137, 31,137, 41,137, 48,226, + 229,238,231,225,236,105,128, 9,153,228,229,246, 97,128, 9, 25, + 231,117, 2,137, 55,137, 64,234,225,242,225,244,105,128, 10,153, + 242,237,245,235,232,105,128, 10, 25,239,238,231,245,244,232,225, + 105,128, 14, 7,104, 2,137, 90,137,100,233,242,225,231,225,238, + 97,128, 48,147,239,239,107, 2,137,108,137,115,236,229,230,116, + 128, 2,114,242,229,244,242,239,230,236,229,120,128, 2,115,105, + 4,137,137,138, 50,138, 61,138,119,229,245,110, 7,137,155,137, + 190,137,222,137,236,137,245,138, 22,138, 35, 97, 2,137,161,137, + 176,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,111, + 240,225,242,229,238,235,239,242,229,225,110,128, 50, 15,227,105, + 2,137,197,137,209,229,245,227,235,239,242,229,225,110,128, 49, + 53,242,227,236,229,235,239,242,229,225,110,128, 50, 97,232,233, + 229,245,232,235,239,242,229,225,110,128, 49, 54,235,239,242,229, + 225,110,128, 49, 52,240, 97, 2,137,252,138, 10,238,243,233,239, + 243,235,239,242,229,225,110,128, 49,104,242,229,238,235,239,242, + 229,225,110,128, 50, 1,243,233,239,243,235,239,242,229,225,110, + 128, 49,103,244,233,235,229,245,244,235,239,242,229,225,110,128, + 49,102,232,233,242,225,231,225,238, 97,128, 48,107,107, 2,138, + 67,138, 91,225,244,225,235,225,238, 97,129, 48,203,138, 79,232, + 225,236,230,247,233,228,244,104,128,255,134,232,225,232,233,116, + 2,138,101,138,112,236,229,230,244,244,232,225,105,128,248,153, + 244,232,225,105,128, 14, 77,238,101,141, 0, 57,138,150,138,159, + 138,169,138,199,138,206,138,231,139, 2,139, 36,139, 48,139, 59, + 139, 92,139,100,139,111,225,242,225,226,233, 99,128, 6,105,226, + 229,238,231,225,236,105,128, 9,239,227,233,242,227,236,101,129, + 36,104,138,180,233,238,246,229,242,243,229,243,225,238,243,243, + 229,242,233,102,128, 39,146,228,229,246, 97,128, 9,111,231,117, + 2,138,213,138,222,234,225,242,225,244,105,128, 10,239,242,237, + 245,235,232,105,128, 10,111,232, 97, 2,138,238,138,249,227,235, + 225,242,225,226,233, 99,128, 6,105,238,231,250,232,239,117,128, + 48, 41,105, 2,139, 8,139, 26,228,229,239,231,242,225,240,232, + 233,227,240,225,242,229,110,128, 50, 40,238,230,229,242,233,239, + 114,128, 32,137,237,239,238,239,243,240,225,227,101,128,255, 25, + 239,236,228,243,244,249,236,101,128,247, 57,112, 2,139, 65,139, + 72,225,242,229,110,128, 36,124,229,114, 2,139, 79,139, 85,233, + 239,100,128, 36,144,243,233,225,110,128, 6,249,242,239,237,225, + 110,128, 33,120,243,245,240,229,242,233,239,114,128, 32,121,116, + 2,139,117,139,155,229,229,110, 2,139,125,139,134,227,233,242, + 227,236,101,128, 36,114,112, 2,139,140,139,147,225,242,229,110, + 128, 36,134,229,242,233,239,100,128, 36,154,232,225,105,128, 14, + 89,106,129, 1,204,139,167,229,227,249,242,233,236,236,233, 99, + 128, 4, 90,235,225,244,225,235,225,238, 97,129, 48,243,139,192, + 232,225,236,230,247,233,228,244,104,128,255,157,108, 2,139,210, + 139,224,229,231,242,233,231,232,244,236,239,238,103,128, 1,158, + 233,238,229,226,229,236,239,119,128, 30, 73,109, 2,139,241,139, + 252,239,238,239,243,240,225,227,101,128,255, 78,243,241,245,225, + 242,101,128, 51,154,110, 2,140, 11,140, 61, 97, 3,140, 19,140, + 29,140, 36,226,229,238,231,225,236,105,128, 9,163,228,229,246, + 97,128, 9, 35,231,117, 2,140, 43,140, 52,234,225,242,225,244, + 105,128, 10,163,242,237,245,235,232,105,128, 10, 35,238,225,228, + 229,246, 97,128, 9, 41,111, 6,140, 84,140, 95,140,120,140,161, + 141,113,142, 40,232,233,242,225,231,225,238, 97,128, 48,110,235, + 225,244,225,235,225,238, 97,129, 48,206,140,108,232,225,236,230, + 247,233,228,244,104,128,255,137,110, 3,140,128,140,144,140,153, + 226,242,229,225,235,233,238,231,243,240,225,227,101,128, 0,160, + 229,238,244,232,225,105,128, 14, 19,245,244,232,225,105,128, 14, + 25,239,110, 7,140,178,140,187,140,201,140,235,140,251,141, 36, + 141, 95,225,242,225,226,233, 99,128, 6, 70,230,233,238,225,236, + 225,242,225,226,233, 99,128,254,230,231,232,245,238,238, 97, 2, + 140,212,140,221,225,242,225,226,233, 99,128, 6,186,230,233,238, + 225,236,225,242,225,226,233, 99,128,251,159,233,238,233,244,233, + 225,236,225,242,225,226,233, 99,128,254,231,234,229,229,237,105, + 2,141, 5,141, 20,238,233,244,233,225,236,225,242,225,226,233, + 99,128,252,210,243,239,236,225,244,229,228,225,242,225,226,233, + 99,128,252, 75,237,101, 2,141, 43,141, 56,228,233,225,236,225, + 242,225,226,233, 99,128,254,232,229,237,105, 2,141, 64,141, 79, + 238,233,244,233,225,236,225,242,225,226,233, 99,128,252,213,243, + 239,236,225,244,229,228,225,242,225,226,233, 99,128,252, 78,238, + 239,239,238,230,233,238,225,236,225,242,225,226,233, 99,128,252, + 141,116, 7,141,129,141,140,141,169,141,204,141,216,141,236,142, + 6,227,239,238,244,225,233,238,115,128, 34, 12,101, 2,141,146, + 141,162,236,229,237,229,238,116,129, 34, 9,141,157,239,102,128, + 34, 9,241,245,225,108,128, 34, 96,231,242,229,225,244,229,114, + 129, 34,111,141,181,238,239,114, 2,141,189,141,197,229,241,245, + 225,108,128, 34,113,236,229,243,115,128, 34,121,233,228,229,238, + 244,233,227,225,108,128, 34, 98,236,229,243,115,129, 34,110,141, + 225,238,239,242,229,241,245,225,108,128, 34,112,112, 2,141,242, + 141,252,225,242,225,236,236,229,108,128, 34, 38,242,229,227,229, + 228,229,115,128, 34,128,243,117, 3,142, 15,142, 22,142, 31,226, + 243,229,116,128, 34,132,227,227,229,229,228,115,128, 34,129,240, + 229,242,243,229,116,128, 34,133,247,225,242,237,229,238,233,225, + 110,128, 5,118,240,225,242,229,110,128, 36,169,115, 2,142, 66, + 142, 75,243,241,245,225,242,101,128, 51,177,245,240,229,242,233, + 239,114,128, 32,127,244,233,236,228,101,128, 0,241,117,132, 3, + 189,142,105,142,116,142,197,143, 24,232,233,242,225,231,225,238, + 97,128, 48,108,107, 2,142,122,142,146,225,244,225,235,225,238, + 97,129, 48,204,142,134,232,225,236,230,247,233,228,244,104,128, + 255,135,244, 97, 3,142,155,142,165,142,172,226,229,238,231,225, + 236,105,128, 9,188,228,229,246, 97,128, 9, 60,231,117, 2,142, + 179,142,188,234,225,242,225,244,105,128, 10,188,242,237,245,235, + 232,105,128, 10, 60,109, 2,142,203,142,237,226,229,242,243,233, + 231,110,130, 0, 35,142,217,142,229,237,239,238,239,243,240,225, + 227,101,128,255, 3,243,237,225,236,108,128,254, 95,229,114, 2, + 142,244,143, 20,225,236,243,233,231,110, 2,142,255,143, 7,231, + 242,229,229,107,128, 3,116,236,239,247,229,242,231,242,229,229, + 107,128, 3,117,111,128, 33, 22,110,130, 5,224,143, 32,143, 52, + 228,225,231,229,243,104,129,251, 64,143, 43,232,229,226,242,229, + 119,128,251, 64,232,229,226,242,229,119,128, 5,224,246,243,241, + 245,225,242,101,128, 51,181,247,243,241,245,225,242,101,128, 51, + 187,249, 97, 3,143, 90,143,100,143,107,226,229,238,231,225,236, + 105,128, 9,158,228,229,246, 97,128, 9, 30,231,117, 2,143,114, + 143,123,234,225,242,225,244,105,128, 10,158,242,237,245,235,232, + 105,128, 10, 30,111,147, 0,111,143,174,143,196,144, 18,144,188, + 145, 4,145, 19,145, 59,145,182,145,203,145,241,145,252,146,174, + 148, 8,148, 72,148,105,148,151,149, 24,149, 71,149, 83, 97, 2, + 143,180,143,187,227,245,244,101,128, 0,243,238,231,244,232,225, + 105,128, 14, 45, 98, 4,143,206,143,248,144, 1,144, 11,225,242, + 242,229,100,130, 2,117,143,218,143,229,227,249,242,233,236,236, + 233, 99,128, 4,233,228,233,229,242,229,243,233,243,227,249,242, + 233,236,236,233, 99,128, 4,235,229,238,231,225,236,105,128, 9, + 147,239,240,239,237,239,230,111,128, 49, 27,242,229,246,101,128, + 1, 79, 99, 3,144, 26,144, 99,144,178, 97, 2,144, 32,144, 93, + 238,228,242, 97, 3,144, 43,144, 50,144, 61,228,229,246, 97,128, + 9, 17,231,245,234,225,242,225,244,105,128, 10,145,246,239,247, + 229,236,243,233,231,110, 2,144, 75,144, 82,228,229,246, 97,128, + 9, 73,231,245,234,225,242,225,244,105,128, 10,201,242,239,110, + 128, 1,210,233,242, 99, 2,144,107,144,112,236,101,128, 36,222, + 245,237,230,236,229,120,133, 0,244,144,131,144,139,144,150,144, + 158,144,170,225,227,245,244,101,128, 30,209,228,239,244,226,229, + 236,239,119,128, 30,217,231,242,225,246,101,128, 30,211,232,239, + 239,235,225,226,239,246,101,128, 30,213,244,233,236,228,101,128, + 30,215,249,242,233,236,236,233, 99,128, 4, 62,100, 4,144,198, + 144,221,144,227,144,250,226,108, 2,144,205,144,213,225,227,245, + 244,101,128, 1, 81,231,242,225,246,101,128, 2, 13,229,246, 97, + 128, 9, 19,233,229,242,229,243,233,115,129, 0,246,144,239,227, + 249,242,233,236,236,233, 99,128, 4,231,239,244,226,229,236,239, + 119,128, 30,205,101,129, 1, 83,145, 10,235,239,242,229,225,110, + 128, 49, 90,103, 3,145, 27,145, 42,145, 49,239,238,229,107,129, + 2,219,145, 36,227,237, 98,128, 3, 40,242,225,246,101,128, 0, + 242,245,234,225,242,225,244,105,128, 10,147,104, 4,145, 69,145, + 80,145, 90,145,168,225,242,237,229,238,233,225,110,128, 5,133, + 233,242,225,231,225,238, 97,128, 48, 74,111, 2,145, 96,145,106, + 239,235,225,226,239,246,101,128, 30,207,242,110,133, 1,161,145, + 121,145,129,145,140,145,148,145,160,225,227,245,244,101,128, 30, + 219,228,239,244,226,229,236,239,119,128, 30,227,231,242,225,246, + 101,128, 30,221,232,239,239,235,225,226,239,246,101,128, 30,223, + 244,233,236,228,101,128, 30,225,245,238,231,225,242,245,237,236, + 225,245,116,128, 1, 81,105,129, 1,163,145,188,238,246,229,242, + 244,229,228,226,242,229,246,101,128, 2, 15,107, 2,145,209,145, + 233,225,244,225,235,225,238, 97,129, 48,170,145,221,232,225,236, + 230,247,233,228,244,104,128,255,117,239,242,229,225,110,128, 49, + 87,236,229,232,229,226,242,229,119,128, 5,171,109, 6,146, 10, + 146, 38,146, 45,146,134,146,145,146,163,225,227,242,239,110,130, + 1, 77,146, 22,146, 30,225,227,245,244,101,128, 30, 83,231,242, + 225,246,101,128, 30, 81,228,229,246, 97,128, 9, 80,229,231, 97, + 133, 3,201,146, 61,146, 65,146, 76,146, 90,146,106, 49,128, 3, + 214,227,249,242,233,236,236,233, 99,128, 4, 97,236,225,244,233, + 238,227,236,239,243,229,100,128, 2,119,242,239,245,238,228,227, + 249,242,233,236,236,233, 99,128, 4,123,116, 2,146,112,146,127, + 233,244,236,239,227,249,242,233,236,236,233, 99,128, 4,125,239, + 238,239,115,128, 3,206,231,245,234,225,242,225,244,105,128, 10, + 208,233,227,242,239,110,129, 3,191,146,155,244,239,238,239,115, + 128, 3,204,239,238,239,243,240,225,227,101,128,255, 79,238,101, + 145, 0, 49,146,213,146,222,146,232,147, 6,147, 31,147, 40,147, + 49,147, 74,147,108,147,142,147,154,147,173,147,184,147,217,147, + 227,147,235,147,246,225,242,225,226,233, 99,128, 6, 97,226,229, + 238,231,225,236,105,128, 9,231,227,233,242,227,236,101,129, 36, + 96,146,243,233,238,246,229,242,243,229,243,225,238,243,243,229, + 242,233,102,128, 39,138,100, 2,147, 12,147, 18,229,246, 97,128, + 9,103,239,244,229,238,236,229,225,228,229,114,128, 32, 36,229, + 233,231,232,244,104,128, 33, 91,230,233,244,244,229,100,128,246, + 220,231,117, 2,147, 56,147, 65,234,225,242,225,244,105,128, 10, + 231,242,237,245,235,232,105,128, 10,103,232, 97, 3,147, 83,147, + 94,147, 99,227,235,225,242,225,226,233, 99,128, 6, 97,236,102, + 128, 0,189,238,231,250,232,239,117,128, 48, 33,105, 2,147,114, + 147,132,228,229,239,231,242,225,240,232,233,227,240,225,242,229, + 110,128, 50, 32,238,230,229,242,233,239,114,128, 32,129,237,239, + 238,239,243,240,225,227,101,128,255, 17,238,245,237,229,242,225, + 244,239,242,226,229,238,231,225,236,105,128, 9,244,239,236,228, + 243,244,249,236,101,128,247, 49,112, 2,147,190,147,197,225,242, + 229,110,128, 36,116,229,114, 2,147,204,147,210,233,239,100,128, + 36,136,243,233,225,110,128, 6,241,241,245,225,242,244,229,114, + 128, 0,188,242,239,237,225,110,128, 33,112,243,245,240,229,242, + 233,239,114,128, 0,185,244,104, 2,147,253,148, 2,225,105,128, + 14, 81,233,242,100,128, 33, 83,111, 3,148, 16,148, 50,148, 66, + 103, 2,148, 22,148, 40,239,238,229,107,129, 1,235,148, 31,237, + 225,227,242,239,110,128, 1,237,245,242,237,245,235,232,105,128, + 10, 19,237,225,244,242,225,231,245,242,237,245,235,232,105,128, + 10, 75,240,229,110,128, 2, 84,112, 3,148, 80,148, 87,148, 98, + 225,242,229,110,128, 36,170,229,238,226,245,236,236,229,116,128, + 37,230,244,233,239,110,128, 35, 37,114, 2,148,111,148,140,100, + 2,148,117,148,128,230,229,237,233,238,233,238,101,128, 0,170, + 237,225,243,227,245,236,233,238,101,128, 0,186,244,232,239,231, + 239,238,225,108,128, 34, 31,115, 5,148,163,148,195,148,212,149, + 1,149, 14,232,239,242,116, 2,148,172,148,179,228,229,246, 97, + 128, 9, 18,246,239,247,229,236,243,233,231,238,228,229,246, 97, + 128, 9, 74,236,225,243,104,129, 0,248,148,204,225,227,245,244, + 101,128, 1,255,237,225,236,108, 2,148,221,148,232,232,233,242, + 225,231,225,238, 97,128, 48, 73,235,225,244,225,235,225,238, 97, + 129, 48,169,148,245,232,225,236,230,247,233,228,244,104,128,255, + 107,244,242,239,235,229,225,227,245,244,101,128, 1,255,245,240, + 229,242,233,239,114,128,246,240,116, 2,149, 30,149, 41,227,249, + 242,233,236,236,233, 99,128, 4,127,233,236,228,101,130, 0,245, + 149, 52,149, 60,225,227,245,244,101,128, 30, 77,228,233,229,242, + 229,243,233,115,128, 30, 79,245,226,239,240,239,237,239,230,111, + 128, 49, 33,118, 2,149, 89,149,170,229,114, 2,149, 96,149,162, + 236,233,238,101,131, 32, 62,149,109,149,132,149,155, 99, 2,149, + 115,149,127,229,238,244,229,242,236,233,238,101,128,254, 74,237, + 98,128, 3, 5,100, 2,149,138,149,146,225,243,232,229,100,128, + 254, 73,226,236,247,225,246,121,128,254, 76,247,225,246,121,128, + 254, 75,243,227,239,242,101,128, 0,175,239,247,229,236,243,233, + 231,110, 3,149,185,149,195,149,202,226,229,238,231,225,236,105, + 128, 9,203,228,229,246, 97,128, 9, 75,231,245,234,225,242,225, + 244,105,128, 10,203,112,145, 0,112,149,251,152,123,152,134,152, + 143,152,155,154, 80,154, 90,155, 82,156,101,156,191,156,217,157, + 92,157,100,158, 2,158, 60,158, 88,158, 98, 97, 14,150, 25,150, + 57,150, 67,150, 74,150, 81,150,129,150,140,150,154,150,165,150, + 212,150,226,151,238,152, 21,152,111, 97, 2,150, 31,150, 43,237, + 240,243,243,241,245,225,242,101,128, 51,128,243,229,238,244,239, + 243,241,245,225,242,101,128, 51, 43,226,229,238,231,225,236,105, + 128, 9,170,227,245,244,101,128, 30, 85,228,229,246, 97,128, 9, + 42,103, 2,150, 87,150,105,101, 2,150, 93,150,100,228,239,247, + 110,128, 33,223,245,112,128, 33,222,117, 2,150,111,150,120,234, + 225,242,225,244,105,128, 10,170,242,237,245,235,232,105,128, 10, + 42,232,233,242,225,231,225,238, 97,128, 48,113,233,249,225,238, + 238,239,233,244,232,225,105,128, 14, 47,235,225,244,225,235,225, + 238, 97,128, 48,209,108, 2,150,171,150,196,225,244,225,236,233, + 250,225,244,233,239,238,227,249,242,233,236,236,233,227,227,237, + 98,128, 4,132,239,227,232,235,225,227,249,242,233,236,236,233, + 99,128, 4,192,238,243,233,239,243,235,239,242,229,225,110,128, + 49,127,114, 3,150,234,150,255,151,227, 97, 2,150,240,150,248, + 231,242,225,240,104,128, 0,182,236,236,229,108,128, 34, 37,229, + 110, 2,151, 6,151,116,236,229,230,116,136, 0, 40,151, 29,151, + 44,151, 49,151, 54,151, 65,151, 77,151,100,151,105,225,236,244, + 239,238,229,225,242,225,226,233, 99,128,253, 62,226,116,128,248, + 237,229,120,128,248,236,233,238,230,229,242,233,239,114,128, 32, + 141,237,239,238,239,243,240,225,227,101,128,255, 8,115, 2,151, + 83,151, 90,237,225,236,108,128,254, 89,245,240,229,242,233,239, + 114,128, 32,125,244,112,128,248,235,246,229,242,244,233,227,225, + 108,128,254, 53,242,233,231,232,116,136, 0, 41,151,140,151,155, + 151,160,151,165,151,176,151,188,151,211,151,216,225,236,244,239, + 238,229,225,242,225,226,233, 99,128,253, 63,226,116,128,248,248, + 229,120,128,248,247,233,238,230,229,242,233,239,114,128, 32,142, + 237,239,238,239,243,240,225,227,101,128,255, 9,115, 2,151,194, + 151,201,237,225,236,108,128,254, 90,245,240,229,242,233,239,114, + 128, 32,126,244,112,128,248,246,246,229,242,244,233,227,225,108, + 128,254, 54,244,233,225,236,228,233,230,102,128, 34, 2,115, 3, + 151,246,152, 1,152, 13,229,241,232,229,226,242,229,119,128, 5, + 192,232,244,225,232,229,226,242,229,119,128, 5,153,241,245,225, + 242,101,128, 51,169,244,225,104,134, 5,183,152, 39,152, 53,152, + 58,152, 67,152, 82,152, 98, 49, 2,152, 45,152, 49, 49,128, 5, + 183,100,128, 5,183,178, 97,128, 5,183,232,229,226,242,229,119, + 128, 5,183,238,225,242,242,239,247,232,229,226,242,229,119,128, + 5,183,241,245,225,242,244,229,242,232,229,226,242,229,119,128, + 5,183,247,233,228,229,232,229,226,242,229,119,128, 5,183,250, + 229,242,232,229,226,242,229,119,128, 5,161,226,239,240,239,237, + 239,230,111,128, 49, 6,227,233,242,227,236,101,128, 36,223,228, + 239,244,225,227,227,229,238,116,128, 30, 87,101,137, 5,228,152, + 177,152,188,152,208,152,220,152,240,153, 86,153, 97,153,118,154, + 73,227,249,242,233,236,236,233, 99,128, 4, 63,228,225,231,229, + 243,104,129,251, 68,152,199,232,229,226,242,229,119,128,251, 68, + 229,250,233,243,241,245,225,242,101,128, 51, 59,230,233,238,225, + 236,228,225,231,229,243,232,232,229,226,242,229,119,128,251, 67, + 104, 5,152,252,153, 19,153, 27,153, 41,153, 71,225,114, 2,153, + 3,153, 10,225,226,233, 99,128, 6,126,237,229,238,233,225,110, + 128, 5,122,229,226,242,229,119,128, 5,228,230,233,238,225,236, + 225,242,225,226,233, 99,128,251, 87,105, 2,153, 47,153, 62,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,251, 88,242,225, + 231,225,238, 97,128, 48,122,237,229,228,233,225,236,225,242,225, + 226,233, 99,128,251, 89,235,225,244,225,235,225,238, 97,128, 48, + 218,237,233,228,228,236,229,232,239,239,235,227,249,242,233,236, + 236,233, 99,128, 4,167,114, 5,153,130,153,142,153,184,154, 49, + 154, 62,225,230,229,232,229,226,242,229,119,128,251, 78,227,229, + 238,116,131, 0, 37,153,155,153,164,153,176,225,242,225,226,233, + 99,128, 6,106,237,239,238,239,243,240,225,227,101,128,255, 5, + 243,237,225,236,108,128,254,106,105, 2,153,190,154, 31,239,100, + 134, 0, 46,153,207,153,218,153,229,153,241,153,252,154, 8,225, + 242,237,229,238,233,225,110,128, 5,137,227,229,238,244,229,242, + 229,100,128, 0,183,232,225,236,230,247,233,228,244,104,128,255, + 97,233,238,230,229,242,233,239,114,128,246,231,237,239,238,239, + 243,240,225,227,101,128,255, 14,115, 2,154, 14,154, 21,237,225, + 236,108,128,254, 82,245,240,229,242,233,239,114,128,246,232,243, + 240,239,237,229,238,233,231,242,229,229,235,227,237, 98,128, 3, + 66,240,229,238,228,233,227,245,236,225,114,128, 34,165,244,232, + 239,245,243,225,238,100,128, 32, 48,243,229,244, 97,128, 32,167, + 230,243,241,245,225,242,101,128, 51,138,104, 3,154, 98,154,148, + 155, 29, 97, 3,154,106,154,116,154,123,226,229,238,231,225,236, + 105,128, 9,171,228,229,246, 97,128, 9, 43,231,117, 2,154,130, + 154,139,234,225,242,225,244,105,128, 10,171,242,237,245,235,232, + 105,128, 10, 43,105,133, 3,198,154,162,154,166,154,252,155, 4, + 155, 15, 49,128, 3,213,229,245,240,104, 4,154,179,154,214,154, + 229,154,238, 97, 2,154,185,154,200,227,233,242,227,236,229,235, + 239,242,229,225,110,128, 50,122,240,225,242,229,238,235,239,242, + 229,225,110,128, 50, 26,227,233,242,227,236,229,235,239,242,229, + 225,110,128, 50,108,235,239,242,229,225,110,128, 49, 77,240,225, + 242,229,238,235,239,242,229,225,110,128, 50, 12,236,225,244,233, + 110,128, 2,120,238,244,232,245,244,232,225,105,128, 14, 58,243, + 249,237,226,239,236,231,242,229,229,107,128, 3,213,111, 3,155, + 37,155, 42,155, 68,239,107,128, 1,165,240,104, 2,155, 49,155, + 58,225,238,244,232,225,105,128, 14, 30,245,238,231,244,232,225, + 105,128, 14, 28,243,225,237,240,232,225,239,244,232,225,105,128, + 14, 32,105,133, 3,192,155, 96,156, 52,156, 63,156, 74,156, 88, + 229,245,112, 6,155,112,155,147,155,179,155,207,155,221,156, 17, + 97, 2,155,118,155,133,227,233,242,227,236,229,235,239,242,229, + 225,110,128, 50,115,240,225,242,229,238,235,239,242,229,225,110, + 128, 50, 19,227,105, 2,155,154,155,166,229,245,227,235,239,242, + 229,225,110,128, 49,118,242,227,236,229,235,239,242,229,225,110, + 128, 50,101,107, 2,155,185,155,199,233,249,229,239,235,235,239, + 242,229,225,110,128, 49,114,239,242,229,225,110,128, 49, 66,240, + 225,242,229,238,235,239,242,229,225,110,128, 50, 5,243,233,239, + 115, 2,155,230,156, 2,107, 2,155,236,155,250,233,249,229,239, + 235,235,239,242,229,225,110,128, 49,116,239,242,229,225,110,128, + 49, 68,244,233,235,229,245,244,235,239,242,229,225,110,128, 49, + 117,116, 2,156, 23,156, 38,232,233,229,245,244,232,235,239,242, + 229,225,110,128, 49,119,233,235,229,245,244,235,239,242,229,225, + 110,128, 49,115,232,233,242,225,231,225,238, 97,128, 48,116,235, + 225,244,225,235,225,238, 97,128, 48,212,243,249,237,226,239,236, + 231,242,229,229,107,128, 3,214,247,242,225,242,237,229,238,233, + 225,110,128, 5,131,236,245,115,132, 0, 43,156,115,156,126,156, + 135,156,168,226,229,236,239,247,227,237, 98,128, 3, 31,227,233, + 242,227,236,101,128, 34,149,109, 2,156,141,156,148,233,238,245, + 115,128, 0,177,111, 2,156,154,156,158,100,128, 2,214,238,239, + 243,240,225,227,101,128,255, 11,115, 2,156,174,156,181,237,225, + 236,108,128,254, 98,245,240,229,242,233,239,114,128, 32,122,109, + 2,156,197,156,208,239,238,239,243,240,225,227,101,128,255, 80, + 243,241,245,225,242,101,128, 51,216,111, 5,156,229,156,240,157, + 51,157, 62,157, 72,232,233,242,225,231,225,238, 97,128, 48,125, + 233,238,244,233,238,231,233,238,228,229,120, 4,157, 4,157, 16, + 157, 28,157, 41,228,239,247,238,247,232,233,244,101,128, 38, 31, + 236,229,230,244,247,232,233,244,101,128, 38, 28,242,233,231,232, + 244,247,232,233,244,101,128, 38, 30,245,240,247,232,233,244,101, + 128, 38, 29,235,225,244,225,235,225,238, 97,128, 48,221,240,236, + 225,244,232,225,105,128, 14, 27,243,244,225,236,237,225,242,107, + 129, 48, 18,157, 85,230,225,227,101,128, 48, 32,240,225,242,229, + 110,128, 36,171,114, 3,157,108,157,134,157,159,101, 2,157,114, + 157,122,227,229,228,229,115,128, 34,122,243,227,242,233,240,244, + 233,239,110,128, 33, 30,233,237,101, 2,157,142,157,148,237,239, + 100,128, 2,185,242,229,246,229,242,243,229,100,128, 32, 53,111, + 4,157,169,157,176,157,186,157,199,228,245,227,116,128, 34, 15, + 234,229,227,244,233,246,101,128, 35, 5,236,239,238,231,229,228, + 235,225,238, 97,128, 48,252,112, 2,157,205,157,242,101, 2,157, + 211,157,218,236,236,239,114,128, 35, 24,242,243,117, 2,157,226, + 157,233,226,243,229,116,128, 34,130,240,229,242,243,229,116,128, + 34,131,239,242,244,233,239,110,129, 34, 55,157,253,225,108,128, + 34, 29,115, 2,158, 8,158, 51,105,130, 3,200,158, 16,158, 27, + 227,249,242,233,236,236,233, 99,128, 4,113,236,233,240,238,229, + 245,237,225,244,225,227,249,242,233,236,236,233,227,227,237, 98, + 128, 4,134,243,241,245,225,242,101,128, 51,176,117, 2,158, 66, + 158, 77,232,233,242,225,231,225,238, 97,128, 48,119,235,225,244, + 225,235,225,238, 97,128, 48,215,246,243,241,245,225,242,101,128, + 51,180,247,243,241,245,225,242,101,128, 51,186,113,136, 0,113, + 158,128,159,177,159,188,159,197,159,204,159,216,159,254,160, 6, + 97, 4,158,138,158,161,158,225,159,160,100, 2,158,144,158,150, + 229,246, 97,128, 9, 88,237,225,232,229,226,242,229,119,128, 5, + 168,102, 4,158,171,158,180,158,194,158,210,225,242,225,226,233, + 99,128, 6, 66,230,233,238,225,236,225,242,225,226,233, 99,128, + 254,214,233,238,233,244,233,225,236,225,242,225,226,233, 99,128, + 254,215,237,229,228,233,225,236,225,242,225,226,233, 99,128,254, + 216,237,225,244,115,136, 5,184,158,248,159, 12,159, 26,159, 31, + 159, 36,159, 45,159, 60,159,147, 49, 3,159, 0,159, 4,159, 8, + 48,128, 5,184, 97,128, 5,184, 99,128, 5,184, 50, 2,159, 18, + 159, 22, 55,128, 5,184, 57,128, 5,184,179, 51,128, 5,184,228, + 101,128, 5,184,232,229,226,242,229,119,128, 5,184,238,225,242, + 242,239,247,232,229,226,242,229,119,128, 5,184,113, 2,159, 66, + 159,132,225,244,225,110, 4,159, 79,159, 88,159,103,159,119,232, + 229,226,242,229,119,128, 5,184,238,225,242,242,239,247,232,229, + 226,242,229,119,128, 5,184,241,245,225,242,244,229,242,232,229, + 226,242,229,119,128, 5,184,247,233,228,229,232,229,226,242,229, + 119,128, 5,184,245,225,242,244,229,242,232,229,226,242,229,119, + 128, 5,184,247,233,228,229,232,229,226,242,229,119,128, 5,184, + 242,238,229,249,240,225,242,225,232,229,226,242,229,119,128, 5, + 159,226,239,240,239,237,239,230,111,128, 49, 17,227,233,242,227, + 236,101,128, 36,224,232,239,239,107,128, 2,160,237,239,238,239, + 243,240,225,227,101,128,255, 81,239,102,130, 5,231,159,225,159, + 245,228,225,231,229,243,104,129,251, 71,159,236,232,229,226,242, + 229,119,128,251, 71,232,229,226,242,229,119,128, 5,231,240,225, + 242,229,110,128, 36,172,117, 4,160, 16,160, 28,160,117,160,204, + 225,242,244,229,242,238,239,244,101,128, 38,105,226,245,244,115, + 135, 5,187,160, 49,160, 54,160, 59,160, 64,160, 73,160, 88,160, + 104,177, 56,128, 5,187,178, 53,128, 5,187,179, 49,128, 5,187, + 232,229,226,242,229,119,128, 5,187,238,225,242,242,239,247,232, + 229,226,242,229,119,128, 5,187,241,245,225,242,244,229,242,232, + 229,226,242,229,119,128, 5,187,247,233,228,229,232,229,226,242, + 229,119,128, 5,187,229,243,244,233,239,110,133, 0, 63,160,136, + 160,159,160,176,160,184,160,196,225,114, 2,160,143,160,150,225, + 226,233, 99,128, 6, 31,237,229,238,233,225,110,128, 5, 94,228, + 239,247,110,129, 0,191,160,168,243,237,225,236,108,128,247,191, + 231,242,229,229,107,128, 3,126,237,239,238,239,243,240,225,227, + 101,128,255, 31,243,237,225,236,108,128,247, 63,239,244,101, 4, + 160,216,161, 31,161, 51,161, 80,228,226,108,133, 0, 34,160,232, + 160,239,160,246,161, 2,161, 23,226,225,243,101,128, 32, 30,236, + 229,230,116,128, 32, 28,237,239,238,239,243,240,225,227,101,128, + 255, 2,240,242,233,237,101,129, 48, 30,161, 12,242,229,246,229, + 242,243,229,100,128, 48, 29,242,233,231,232,116,128, 32, 29,236, + 229,230,116,129, 32, 24,161, 40,242,229,246,229,242,243,229,100, + 128, 32, 27,114, 2,161, 57,161, 67,229,246,229,242,243,229,100, + 128, 32, 27,233,231,232,116,129, 32, 25,161, 76,110,128, 1, 73, + 243,233,238,231,108, 2,161, 90,161, 97,226,225,243,101,128, 32, + 26,101,129, 0, 39,161,103,237,239,238,239,243,240,225,227,101, + 128,255, 7,114,145, 0,114,161,153,162,157,162,168,162,215,163, + 10,164, 27,164, 51,164,146,166,180,166,217,166,229,167, 27,167, + 35,167,197,167,208,167,243,168, 87, 97, 11,161,177,161,188,161, + 198,161,205,162, 14,162, 30,162, 55,162, 66,162, 91,162,114,162, + 151,225,242,237,229,238,233,225,110,128, 5,124,226,229,238,231, + 225,236,105,128, 9,176,227,245,244,101,128, 1, 85,100, 4,161, + 215,161,221,161,235,162, 5,229,246, 97,128, 9, 48,233,227,225, + 108,129, 34, 26,161,230,229,120,128,248,229,239,246,229,242,243, + 243,241,245,225,242,101,129, 51,174,161,251,228,243,241,245,225, + 242,101,128, 51,175,243,241,245,225,242,101,128, 51,173,230,101, + 129, 5,191,162, 21,232,229,226,242,229,119,128, 5,191,231,117, + 2,162, 37,162, 46,234,225,242,225,244,105,128, 10,176,242,237, + 245,235,232,105,128, 10, 48,232,233,242,225,231,225,238, 97,128, + 48,137,235,225,244,225,235,225,238, 97,129, 48,233,162, 79,232, + 225,236,230,247,233,228,244,104,128,255,151,236,239,247,229,242, + 228,233,225,231,239,238,225,236,226,229,238,231,225,236,105,128, + 9,241,109, 2,162,120,162,143,233,228,228,236,229,228,233,225, + 231,239,238,225,236,226,229,238,231,225,236,105,128, 9,240,243, + 232,239,242,110,128, 2,100,244,233,111,128, 34, 54,226,239,240, + 239,237,239,230,111,128, 49, 22, 99, 4,162,178,162,185,162,194, + 162,202,225,242,239,110,128, 1, 89,229,228,233,236,236, 97,128, + 1, 87,233,242,227,236,101,128, 36,225,239,237,237,225,225,227, + 227,229,238,116,128, 1, 87,100, 2,162,221,162,231,226,236,231, + 242,225,246,101,128, 2, 17,239,116, 2,162,238,162,247,225,227, + 227,229,238,116,128, 30, 89,226,229,236,239,119,129, 30, 91,163, + 1,237,225,227,242,239,110,128, 30, 93,101, 6,163, 24,163, 69, + 163,104,163,159,163,184,163,217,102, 2,163, 30,163, 43,229,242, + 229,238,227,229,237,225,242,107,128, 32, 59,236,229,248,243,117, + 2,163, 53,163, 60,226,243,229,116,128, 34,134,240,229,242,243, + 229,116,128, 34,135,231,233,243,244,229,114, 2,163, 80,163, 85, + 229,100,128, 0,174,115, 2,163, 91,163, 97,225,238,115,128,248, + 232,229,242,233,102,128,246,218,104, 3,163,112,163,135,163,149, + 225,114, 2,163,119,163,126,225,226,233, 99,128, 6, 49,237,229, + 238,233,225,110,128, 5,128,230,233,238,225,236,225,242,225,226, + 233, 99,128,254,174,233,242,225,231,225,238, 97,128, 48,140,235, + 225,244,225,235,225,238, 97,129, 48,236,163,172,232,225,236,230, + 247,233,228,244,104,128,255,154,243,104,130, 5,232,163,193,163, + 208,228,225,231,229,243,232,232,229,226,242,229,119,128,251, 72, + 232,229,226,242,229,119,128, 5,232,118, 3,163,225,163,238,164, + 14,229,242,243,229,228,244,233,236,228,101,128, 34, 61,233, 97, + 2,163,245,163,254,232,229,226,242,229,119,128, 5,151,237,245, + 231,242,225,243,232,232,229,226,242,229,119,128, 5,151,236,239, + 231,233,227,225,236,238,239,116,128, 35, 16,230,233,243,232,232, + 239,239,107,129, 2,126,164, 40,242,229,246,229,242,243,229,100, + 128, 2,127,104, 2,164, 57,164, 80, 97, 2,164, 63,164, 73,226, + 229,238,231,225,236,105,128, 9,221,228,229,246, 97,128, 9, 93, + 111,131, 3,193,164, 90,164,119,164,133,239,107,129, 2,125,164, + 97,244,245,242,238,229,100,129, 2,123,164,108,243,245,240,229, + 242,233,239,114,128, 2,181,243,249,237,226,239,236,231,242,229, + 229,107,128, 3,241,244,233,227,232,239,239,235,237,239,100,128, + 2,222,105, 6,164,160,165,204,165,250,166, 5,166, 30,166,166, + 229,245,108, 9,164,182,164,217,164,232,164,246,165, 36,165, 50, + 165,136,165,149,165,184, 97, 2,164,188,164,203,227,233,242,227, + 236,229,235,239,242,229,225,110,128, 50,113,240,225,242,229,238, + 235,239,242,229,225,110,128, 50, 17,227,233,242,227,236,229,235, + 239,242,229,225,110,128, 50, 99,232,233,229,245,232,235,239,242, + 229,225,110,128, 49, 64,107, 2,164,252,165, 28,233,249,229,239, + 107, 2,165, 6,165, 15,235,239,242,229,225,110,128, 49, 58,243, + 233,239,243,235,239,242,229,225,110,128, 49,105,239,242,229,225, + 110,128, 49, 57,237,233,229,245,237,235,239,242,229,225,110,128, + 49, 59,112, 3,165, 58,165, 90,165,105, 97, 2,165, 64,165, 78, + 238,243,233,239,243,235,239,242,229,225,110,128, 49,108,242,229, + 238,235,239,242,229,225,110,128, 50, 3,232,233,229,245,240,232, + 235,239,242,229,225,110,128, 49, 63,233,229,245,112, 2,165,114, + 165,123,235,239,242,229,225,110,128, 49, 60,243,233,239,243,235, + 239,242,229,225,110,128, 49,107,243,233,239,243,235,239,242,229, + 225,110,128, 49, 61,116, 2,165,155,165,170,232,233,229,245,244, + 232,235,239,242,229,225,110,128, 49, 62,233,235,229,245,244,235, + 239,242,229,225,110,128, 49,106,249,229,239,242,233,238,232,233, + 229,245,232,235,239,242,229,225,110,128, 49,109,231,232,116, 2, + 165,212,165,220,225,238,231,236,101,128, 34, 31,116, 2,165,226, + 165,240,225,227,235,226,229,236,239,247,227,237, 98,128, 3, 25, + 242,233,225,238,231,236,101,128, 34,191,232,233,242,225,231,225, + 238, 97,128, 48,138,235,225,244,225,235,225,238, 97,129, 48,234, + 166, 18,232,225,236,230,247,233,228,244,104,128,255,152,110, 2, + 166, 36,166,152,103,131, 2,218,166, 46,166, 57,166, 63,226,229, + 236,239,247,227,237, 98,128, 3, 37,227,237, 98,128, 3, 10,232, + 225,236,102, 2,166, 72,166,118,236,229,230,116,131, 2,191,166, + 85,166, 96,166,107,225,242,237,229,238,233,225,110,128, 5, 89, + 226,229,236,239,247,227,237, 98,128, 3, 28,227,229,238,244,229, + 242,229,100,128, 2,211,242,233,231,232,116,130, 2,190,166,130, + 166,141,226,229,236,239,247,227,237, 98,128, 3, 57,227,229,238, + 244,229,242,229,100,128, 2,210,246,229,242,244,229,228,226,242, + 229,246,101,128, 2, 19,244,244,239,242,245,243,241,245,225,242, + 101,128, 51, 81,108, 2,166,186,166,197,233,238,229,226,229,236, + 239,119,128, 30, 95,239,238,231,236,229,103,129, 2,124,166,208, + 244,245,242,238,229,100,128, 2,122,237,239,238,239,243,240,225, + 227,101,128,255, 82,111, 3,166,237,166,248,167, 17,232,233,242, + 225,231,225,238, 97,128, 48,141,235,225,244,225,235,225,238, 97, + 129, 48,237,167, 5,232,225,236,230,247,233,228,244,104,128,255, + 155,242,245,225,244,232,225,105,128, 14, 35,240,225,242,229,110, + 128, 36,173,114, 3,167, 43,167, 79,167,109, 97, 3,167, 51,167, + 61,167, 68,226,229,238,231,225,236,105,128, 9,220,228,229,246, + 97,128, 9, 49,231,245,242,237,245,235,232,105,128, 10, 92,229, + 104, 2,167, 86,167, 95,225,242,225,226,233, 99,128, 6,145,230, + 233,238,225,236,225,242,225,226,233, 99,128,251,141,246,239,227, + 225,236,233, 99, 4,167,125,167,135,167,142,167,153,226,229,238, + 231,225,236,105,128, 9,224,228,229,246, 97,128, 9, 96,231,245, + 234,225,242,225,244,105,128, 10,224,246,239,247,229,236,243,233, + 231,110, 3,167,169,167,179,167,186,226,229,238,231,225,236,105, + 128, 9,196,228,229,246, 97,128, 9, 68,231,245,234,225,242,225, + 244,105,128, 10,196,243,245,240,229,242,233,239,114,128,246,241, + 116, 2,167,214,167,222,226,236,239,227,107,128, 37,144,245,242, + 238,229,100,129, 2,121,167,232,243,245,240,229,242,233,239,114, + 128, 2,180,117, 4,167,253,168, 8,168, 33,168, 80,232,233,242, + 225,231,225,238, 97,128, 48,139,235,225,244,225,235,225,238, 97, + 129, 48,235,168, 21,232,225,236,230,247,233,228,244,104,128,255, + 153,112, 2,168, 39,168, 74,229,101, 2,168, 46,168, 60,237,225, + 242,235,226,229,238,231,225,236,105,128, 9,242,243,233,231,238, + 226,229,238,231,225,236,105,128, 9,243,233,225,104,128,246,221, + 244,232,225,105,128, 14, 36,246,239,227,225,236,233, 99, 4,168, + 103,168,113,168,120,168,131,226,229,238,231,225,236,105,128, 9, + 139,228,229,246, 97,128, 9, 11,231,245,234,225,242,225,244,105, + 128, 10,139,246,239,247,229,236,243,233,231,110, 3,168,147,168, + 157,168,164,226,229,238,231,225,236,105,128, 9,195,228,229,246, + 97,128, 9, 67,231,245,234,225,242,225,244,105,128, 10,195,115, + 147, 0,115,168,217,170,187,170,198,171, 68,171,107,174, 49,174, + 60,176,203,179, 85,179,131,179,158,180, 93,180,160,181,193,181, + 203,182,133,182,206,183,120,183,130, 97, 9,168,237,168,247,169, + 12,169, 84,169,109,169,120,169,145,169,177,169,217,226,229,238, + 231,225,236,105,128, 9,184,227,245,244,101,129, 1, 91,169, 0, + 228,239,244,225,227,227,229,238,116,128, 30,101,100, 5,169, 24, + 169, 33,169, 39,169, 53,169, 69,225,242,225,226,233, 99,128, 6, + 53,229,246, 97,128, 9, 56,230,233,238,225,236,225,242,225,226, + 233, 99,128,254,186,233,238,233,244,233,225,236,225,242,225,226, + 233, 99,128,254,187,237,229,228,233,225,236,225,242,225,226,233, + 99,128,254,188,231,117, 2,169, 91,169,100,234,225,242,225,244, + 105,128, 10,184,242,237,245,235,232,105,128, 10, 56,232,233,242, + 225,231,225,238, 97,128, 48, 85,235,225,244,225,235,225,238, 97, + 129, 48,181,169,133,232,225,236,230,247,233,228,244,104,128,255, + 123,236,236,225,236,236,225,232,239,245,225,236,225,249,232,229, + 247,225,243,225,236,236,225,237,225,242,225,226,233, 99,128,253, + 250,237,229,235,104,130, 5,225,169,188,169,208,228,225,231,229, + 243,104,129,251, 65,169,199,232,229,226,242,229,119,128,251, 65, + 232,229,226,242,229,119,128, 5,225,242, 97, 5,169,230,170, 48, + 170, 56,170,106,170,114, 97, 5,169,242,169,250,170, 2,170, 33, + 170, 41,225,244,232,225,105,128, 14, 50,229,244,232,225,105,128, + 14, 65,233,237,225,233,109, 2,170, 12,170, 23,225,236,225,233, + 244,232,225,105,128, 14, 68,245,225,238,244,232,225,105,128, 14, + 67,237,244,232,225,105,128, 14, 51,244,232,225,105,128, 14, 48, + 229,244,232,225,105,128, 14, 64,105, 3,170, 64,170, 88,170, 99, + 105, 2,170, 70,170, 81,236,229,230,244,244,232,225,105,128,248, + 134,244,232,225,105,128, 14, 53,236,229,230,244,244,232,225,105, + 128,248,133,244,232,225,105,128, 14, 52,239,244,232,225,105,128, + 14, 66,117, 3,170,122,170,172,170,179,101, 3,170,130,170,154, + 170,165,101, 2,170,136,170,147,236,229,230,244,244,232,225,105, + 128,248,136,244,232,225,105,128, 14, 55,236,229,230,244,244,232, + 225,105,128,248,135,244,232,225,105,128, 14, 54,244,232,225,105, + 128, 14, 56,245,244,232,225,105,128, 14, 57,226,239,240,239,237, + 239,230,111,128, 49, 25, 99, 5,170,210,170,231,170,240,171, 33, + 171, 55,225,242,239,110,129, 1, 97,170,219,228,239,244,225,227, + 227,229,238,116,128, 30,103,229,228,233,236,236, 97,128, 1, 95, + 232,247, 97,131, 2, 89,170,252,171, 7,171, 26,227,249,242,233, + 236,236,233, 99,128, 4,217,228,233,229,242,229,243,233,243,227, + 249,242,233,236,236,233, 99,128, 4,219,232,239,239,107,128, 2, + 90,233,242, 99, 2,171, 41,171, 46,236,101,128, 36,226,245,237, + 230,236,229,120,128, 1, 93,239,237,237,225,225,227,227,229,238, + 116,128, 2, 25,228,239,116, 2,171, 76,171, 85,225,227,227,229, + 238,116,128, 30, 97,226,229,236,239,119,129, 30, 99,171, 95,228, + 239,244,225,227,227,229,238,116,128, 30,105,101, 9,171,127,171, + 143,171,178,171,243,172, 90,172,117,172,142,172,223,172,250,225, + 231,245,236,236,226,229,236,239,247,227,237, 98,128, 3, 60, 99, + 2,171,149,171,171,239,238,100,129, 32, 51,171,157,244,239,238, + 229,227,232,233,238,229,243,101,128, 2,202,244,233,239,110,128, + 0,167,229,110, 4,171,189,171,198,171,212,171,228,225,242,225, + 226,233, 99,128, 6, 51,230,233,238,225,236,225,242,225,226,233, + 99,128,254,178,233,238,233,244,233,225,236,225,242,225,226,233, + 99,128,254,179,237,229,228,233,225,236,225,242,225,226,233, 99, + 128,254,180,231,239,108,135, 5,182,172, 7,172, 21,172, 26,172, + 35,172, 50,172, 66,172, 77, 49, 2,172, 13,172, 17, 51,128, 5, + 182,102,128, 5,182,178, 99,128, 5,182,232,229,226,242,229,119, + 128, 5,182,238,225,242,242,239,247,232,229,226,242,229,119,128, + 5,182,241,245,225,242,244,229,242,232,229,226,242,229,119,128, + 5,182,244,225,232,229,226,242,229,119,128, 5,146,247,233,228, + 229,232,229,226,242,229,119,128, 5,182,104, 2,172, 96,172,107, + 225,242,237,229,238,233,225,110,128, 5,125,233,242,225,231,225, + 238, 97,128, 48, 91,235,225,244,225,235,225,238, 97,129, 48,187, + 172,130,232,225,236,230,247,233,228,244,104,128,255,126,237,105, + 2,172,149,172,192,227,239,236,239,110,131, 0, 59,172,163,172, + 172,172,184,225,242,225,226,233, 99,128, 6, 27,237,239,238,239, + 243,240,225,227,101,128,255, 27,243,237,225,236,108,128,254, 84, + 246,239,233,227,229,228,237,225,242,235,235,225,238, 97,129, 48, + 156,172,211,232,225,236,230,247,233,228,244,104,128,255,159,238, + 116, 2,172,230,172,240,233,243,241,245,225,242,101,128, 51, 34, + 239,243,241,245,225,242,101,128, 51, 35,246,229,110,142, 0, 55, + 173, 28,173, 37,173, 47,173, 77,173, 84,173, 94,173,119,173,146, + 173,180,173,192,173,203,173,236,173,244,173,255,225,242,225,226, + 233, 99,128, 6,103,226,229,238,231,225,236,105,128, 9,237,227, + 233,242,227,236,101,129, 36,102,173, 58,233,238,246,229,242,243, + 229,243,225,238,243,243,229,242,233,102,128, 39,144,228,229,246, + 97,128, 9,109,229,233,231,232,244,232,115,128, 33, 94,231,117, + 2,173,101,173,110,234,225,242,225,244,105,128, 10,237,242,237, + 245,235,232,105,128, 10,109,232, 97, 2,173,126,173,137,227,235, + 225,242,225,226,233, 99,128, 6,103,238,231,250,232,239,117,128, + 48, 39,105, 2,173,152,173,170,228,229,239,231,242,225,240,232, + 233,227,240,225,242,229,110,128, 50, 38,238,230,229,242,233,239, + 114,128, 32,135,237,239,238,239,243,240,225,227,101,128,255, 23, + 239,236,228,243,244,249,236,101,128,247, 55,112, 2,173,209,173, + 216,225,242,229,110,128, 36,122,229,114, 2,173,223,173,229,233, + 239,100,128, 36,142,243,233,225,110,128, 6,247,242,239,237,225, + 110,128, 33,118,243,245,240,229,242,233,239,114,128, 32,119,116, + 2,174, 5,174, 43,229,229,110, 2,174, 13,174, 22,227,233,242, + 227,236,101,128, 36,112,112, 2,174, 28,174, 35,225,242,229,110, + 128, 36,132,229,242,233,239,100,128, 36,152,232,225,105,128, 14, + 87,230,244,232,249,240,232,229,110,128, 0,173,104, 7,174, 76, + 175, 50,175, 61,175, 75,176, 20,176, 33,176,197, 97, 6,174, 90, + 174,101,174,111,174,122,175, 9,175, 34,225,242,237,229,238,233, + 225,110,128, 5,119,226,229,238,231,225,236,105,128, 9,182,227, + 249,242,233,236,236,233, 99,128, 4, 72,100, 2,174,128,174,224, + 228, 97, 4,174,139,174,148,174,179,174,193,225,242,225,226,233, + 99,128, 6, 81,228,225,237,237, 97, 2,174,158,174,167,225,242, + 225,226,233, 99,128,252, 97,244,225,238,225,242,225,226,233, 99, + 128,252, 94,230,225,244,232,225,225,242,225,226,233, 99,128,252, + 96,235,225,243,242, 97, 2,174,203,174,212,225,242,225,226,233, + 99,128,252, 98,244,225,238,225,242,225,226,233, 99,128,252, 95, + 101,132, 37,146,174,236,174,243,174,251,175, 4,228,225,242,107, + 128, 37,147,236,233,231,232,116,128, 37,145,237,229,228,233,245, + 109,128, 37,146,246, 97,128, 9, 54,231,117, 2,175, 16,175, 25, + 234,225,242,225,244,105,128, 10,182,242,237,245,235,232,105,128, + 10, 54,236,243,232,229,236,229,244,232,229,226,242,229,119,128, + 5,147,226,239,240,239,237,239,230,111,128, 49, 21,227,232,225, + 227,249,242,233,236,236,233, 99,128, 4, 73,101, 4,175, 85,175, + 150,175,160,175,177,229,110, 4,175, 96,175,105,175,119,175,135, + 225,242,225,226,233, 99,128, 6, 52,230,233,238,225,236,225,242, + 225,226,233, 99,128,254,182,233,238,233,244,233,225,236,225,242, + 225,226,233, 99,128,254,183,237,229,228,233,225,236,225,242,225, + 226,233, 99,128,254,184,233,227,239,240,244,233, 99,128, 3,227, + 241,229,108,129, 32,170,175,168,232,229,226,242,229,119,128, 32, + 170,246, 97,134, 5,176,175,194,175,209,175,223,175,232,175,247, + 176, 7, 49, 2,175,200,175,205,177, 53,128, 5,176, 53,128, 5, + 176, 50, 2,175,215,175,219, 50,128, 5,176,101,128, 5,176,232, + 229,226,242,229,119,128, 5,176,238,225,242,242,239,247,232,229, + 226,242,229,119,128, 5,176,241,245,225,242,244,229,242,232,229, + 226,242,229,119,128, 5,176,247,233,228,229,232,229,226,242,229, + 119,128, 5,176,232,225,227,249,242,233,236,236,233, 99,128, 4, + 187,105, 2,176, 39,176, 50,237,225,227,239,240,244,233, 99,128, + 3,237,110,131, 5,233,176, 60,176,143,176,152,100, 2,176, 66, + 176,132,225,231,229,243,104,130,251, 73,176, 78,176, 87,232,229, + 226,242,229,119,128,251, 73,115, 2,176, 93,176,113,232,233,238, + 228,239,116,129,251, 44,176,104,232,229,226,242,229,119,128,251, + 44,233,238,228,239,116,129,251, 45,176,123,232,229,226,242,229, + 119,128,251, 45,239,244,232,229,226,242,229,119,128, 5,193,232, + 229,226,242,229,119,128, 5,233,115, 2,176,158,176,178,232,233, + 238,228,239,116,129,251, 42,176,169,232,229,226,242,229,119,128, + 251, 42,233,238,228,239,116,129,251, 43,176,188,232,229,226,242, + 229,119,128,251, 43,239,239,107,128, 2,130,105, 8,176,221,177, + 9,177, 20,177, 45,177, 75,177, 83,177, 96,178, 11,231,237, 97, + 131, 3,195,176,233,176,237,176,245, 49,128, 3,194,230,233,238, + 225,108,128, 3,194,236,245,238,225,244,229,243,249,237,226,239, + 236,231,242,229,229,107,128, 3,242,232,233,242,225,231,225,238, + 97,128, 48, 87,235,225,244,225,235,225,238, 97,129, 48,183,177, + 33,232,225,236,230,247,233,228,244,104,128,255,124,236,245,113, + 2,177, 53,177, 62,232,229,226,242,229,119,128, 5,189,236,229, + 230,244,232,229,226,242,229,119,128, 5,189,237,233,236,225,114, + 128, 34, 60,238,228,239,244,232,229,226,242,229,119,128, 5,194, + 239,115, 6,177,111,177,146,177,178,177,206,177,220,177,252, 97, + 2,177,117,177,132,227,233,242,227,236,229,235,239,242,229,225, + 110,128, 50,116,240,225,242,229,238,235,239,242,229,225,110,128, + 50, 20,227,105, 2,177,153,177,165,229,245,227,235,239,242,229, + 225,110,128, 49,126,242,227,236,229,235,239,242,229,225,110,128, + 50,102,107, 2,177,184,177,198,233,249,229,239,235,235,239,242, + 229,225,110,128, 49,122,239,242,229,225,110,128, 49, 69,238,233, + 229,245,238,235,239,242,229,225,110,128, 49,123,112, 2,177,226, + 177,239,225,242,229,238,235,239,242,229,225,110,128, 50, 6,233, + 229,245,240,235,239,242,229,225,110,128, 49,125,244,233,235,229, + 245,244,235,239,242,229,225,110,128, 49,124,120,141, 0, 54,178, + 41,178, 50,178, 60,178, 90,178, 97,178,122,178,149,178,183,178, + 195,178,206,178,239,178,247,179, 2,225,242,225,226,233, 99,128, + 6,102,226,229,238,231,225,236,105,128, 9,236,227,233,242,227, + 236,101,129, 36,101,178, 71,233,238,246,229,242,243,229,243,225, + 238,243,243,229,242,233,102,128, 39,143,228,229,246, 97,128, 9, + 108,231,117, 2,178,104,178,113,234,225,242,225,244,105,128, 10, + 236,242,237,245,235,232,105,128, 10,108,232, 97, 2,178,129,178, + 140,227,235,225,242,225,226,233, 99,128, 6,102,238,231,250,232, + 239,117,128, 48, 38,105, 2,178,155,178,173,228,229,239,231,242, + 225,240,232,233,227,240,225,242,229,110,128, 50, 37,238,230,229, + 242,233,239,114,128, 32,134,237,239,238,239,243,240,225,227,101, + 128,255, 22,239,236,228,243,244,249,236,101,128,247, 54,112, 2, + 178,212,178,219,225,242,229,110,128, 36,121,229,114, 2,178,226, + 178,232,233,239,100,128, 36,141,243,233,225,110,128, 6,246,242, + 239,237,225,110,128, 33,117,243,245,240,229,242,233,239,114,128, + 32,118,116, 2,179, 8,179, 79,229,229,110, 2,179, 16,179, 58, + 99, 2,179, 22,179, 30,233,242,227,236,101,128, 36,111,245,242, + 242,229,238,227,249,228,229,238,239,237,233,238,225,244,239,242, + 226,229,238,231,225,236,105,128, 9,249,112, 2,179, 64,179, 71, + 225,242,229,110,128, 36,131,229,242,233,239,100,128, 36,151,232, + 225,105,128, 14, 86,108, 2,179, 91,179,111,225,243,104,129, 0, + 47,179, 99,237,239,238,239,243,240,225,227,101,128,255, 15,239, + 238,103,129, 1,127,179,119,228,239,244,225,227,227,229,238,116, + 128, 30,155,109, 2,179,137,179,147,233,236,229,230,225,227,101, + 128, 38, 58,239,238,239,243,240,225,227,101,128,255, 83,111, 6, + 179,172,179,222,179,233,180, 2,180, 47,180, 58,102, 2,179,178, + 179,192,240,225,243,245,241,232,229,226,242,229,119,128, 5,195, + 116, 2,179,198,179,207,232,249,240,232,229,110,128, 0,173,243, + 233,231,238,227,249,242,233,236,236,233, 99,128, 4, 76,232,233, + 242,225,231,225,238, 97,128, 48, 93,235,225,244,225,235,225,238, + 97,129, 48,189,179,246,232,225,236,230,247,233,228,244,104,128, + 255,127,236,233,228,245,115, 2,180, 12,180, 29,236,239,238,231, + 239,246,229,242,236,225,249,227,237, 98,128, 3, 56,243,232,239, + 242,244,239,246,229,242,236,225,249,227,237, 98,128, 3, 55,242, + 245,243,233,244,232,225,105,128, 14, 41,115, 3,180, 66,180, 76, + 180, 84,225,236,225,244,232,225,105,128, 14, 40,239,244,232,225, + 105,128, 14, 11,245,225,244,232,225,105,128, 14, 42,240, 97, 3, + 180,102,180,122,180,154,227,101,129, 0, 32,180,109,232,225,227, + 235,225,242,225,226,233, 99,128, 0, 32,228,101,129, 38, 96,180, + 129,243,245,233,116, 2,180,138,180,146,226,236,225,227,107,128, + 38, 96,247,232,233,244,101,128, 38,100,242,229,110,128, 36,174, + 241,245,225,242,101, 11,180,188,180,199,180,213,180,238,180,255, + 181, 25,181, 40,181, 73,181,100,181,156,181,171,226,229,236,239, + 247,227,237, 98,128, 3, 59, 99, 2,180,205,180,209, 99,128, 51, + 196,109,128, 51,157,228,233,225,231,239,238,225,236,227,242,239, + 243,243,232,225,244,227,232,230,233,236,108,128, 37,169,232,239, + 242,233,250,239,238,244,225,236,230,233,236,108,128, 37,164,107, + 2,181, 5,181, 9,103,128, 51,143,109,129, 51,158,181, 15,227, + 225,240,233,244,225,108,128, 51,206,108, 2,181, 31,181, 35,110, + 128, 51,209,239,103,128, 51,210,109, 4,181, 50,181, 54,181, 59, + 181, 63,103,128, 51,142,233,108,128, 51,213,109,128, 51,156,243, + 241,245,225,242,229,100,128, 51,161,239,242,244,232,239,231,239, + 238,225,236,227,242,239,243,243,232,225,244,227,232,230,233,236, + 108,128, 37,166,245,240,240,229,114, 2,181,110,181,133,236,229, + 230,244,244,239,236,239,247,229,242,242,233,231,232,244,230,233, + 236,108,128, 37,167,242,233,231,232,244,244,239,236,239,247,229, + 242,236,229,230,244,230,233,236,108,128, 37,168,246,229,242,244, + 233,227,225,236,230,233,236,108,128, 37,165,247,232,233,244,229, + 247,233,244,232,243,237,225,236,236,226,236,225,227,107,128, 37, + 163,242,243,241,245,225,242,101,128, 51,219,115, 2,181,209,182, + 123, 97, 4,181,219,181,229,181,236,181,247,226,229,238,231,225, + 236,105,128, 9,183,228,229,246, 97,128, 9, 55,231,245,234,225, + 242,225,244,105,128, 10,183,238,103, 8,182, 10,182, 24,182, 38, + 182, 52,182, 67,182, 81,182, 95,182,108,227,233,229,245,227,235, + 239,242,229,225,110,128, 49, 73,232,233,229,245,232,235,239,242, + 229,225,110,128, 49,133,233,229,245,238,231,235,239,242,229,225, + 110,128, 49,128,235,233,249,229,239,235,235,239,242,229,225,110, + 128, 49, 50,238,233,229,245,238,235,239,242,229,225,110,128, 49, + 101,240,233,229,245,240,235,239,242,229,225,110,128, 49, 67,243, + 233,239,243,235,239,242,229,225,110,128, 49, 70,244,233,235,229, + 245,244,235,239,242,229,225,110,128, 49, 56,245,240,229,242,233, + 239,114,128,246,242,116, 2,182,139,182,162,229,242,236,233,238, + 103,129, 0,163,182,150,237,239,238,239,243,240,225,227,101,128, + 255,225,242,239,235,101, 2,182,171,182,188,236,239,238,231,239, + 246,229,242,236,225,249,227,237, 98,128, 3, 54,243,232,239,242, + 244,239,246,229,242,236,225,249,227,237, 98,128, 3, 53,117, 7, + 182,222,182,254,183, 20,183, 31,183, 72,183, 82,183, 86,226,243, + 229,116,130, 34,130,182,233,182,244,238,239,244,229,241,245,225, + 108,128, 34,138,239,242,229,241,245,225,108,128, 34,134, 99, 2, + 183, 4,183, 12,227,229,229,228,115,128, 34,123,232,244,232,225, + 116,128, 34, 11,232,233,242,225,231,225,238, 97,128, 48, 89,107, + 2,183, 37,183, 61,225,244,225,235,225,238, 97,129, 48,185,183, + 49,232,225,236,230,247,233,228,244,104,128,255,125,245,238,225, + 242,225,226,233, 99,128, 6, 82,237,237,225,244,233,239,110,128, + 34, 17,110,128, 38, 60,240,229,242,243,229,116,130, 34,131,183, + 99,183,110,238,239,244,229,241,245,225,108,128, 34,139,239,242, + 229,241,245,225,108,128, 34,135,246,243,241,245,225,242,101,128, + 51,220,249,239,245,247,225,229,242,225,243,241,245,225,242,101, + 128, 51,124,116,144, 0,116,183,183,184,192,184,213,185,100,185, + 140,187,188,191, 70,192,145,192,157,192,169,193,202,193,227,194, + 57,194,237,195,165,195,255, 97, 10,183,205,183,215,183,236,183, + 243,184, 12,184, 90,184,107,184,132,184,146,184,150,226,229,238, + 231,225,236,105,128, 9,164,227,107, 2,183,222,183,229,228,239, + 247,110,128, 34,164,236,229,230,116,128, 34,163,228,229,246, 97, + 128, 9, 36,231,117, 2,183,250,184, 3,234,225,242,225,244,105, + 128, 10,164,242,237,245,235,232,105,128, 10, 36,104, 4,184, 22, + 184, 31,184, 45,184, 75,225,242,225,226,233, 99,128, 6, 55,230, + 233,238,225,236,225,242,225,226,233, 99,128,254,194,105, 2,184, + 51,184, 66,238,233,244,233,225,236,225,242,225,226,233, 99,128, + 254,195,242,225,231,225,238, 97,128, 48, 95,237,229,228,233,225, + 236,225,242,225,226,233, 99,128,254,196,233,243,249,239,245,229, + 242,225,243,241,245,225,242,101,128, 51,125,235,225,244,225,235, + 225,238, 97,129, 48,191,184,120,232,225,236,230,247,233,228,244, + 104,128,255,128,244,247,229,229,236,225,242,225,226,233, 99,128, + 6, 64,117,128, 3,196,118,130, 5,234,184,158,184,183,228,225, + 231,229,115,129,251, 74,184,168,104,129,251, 74,184,174,232,229, + 226,242,229,119,128,251, 74,232,229,226,242,229,119,128, 5,234, + 98, 2,184,198,184,203,225,114,128, 1,103,239,240,239,237,239, + 230,111,128, 49, 10, 99, 6,184,227,184,234,184,241,184,250,185, + 60,185, 87,225,242,239,110,128, 1,101,227,245,242,108,128, 2, + 168,229,228,233,236,236, 97,128, 1, 99,232,229,104, 4,185, 6, + 185, 15,185, 29,185, 45,225,242,225,226,233, 99,128, 6,134,230, + 233,238,225,236,225,242,225,226,233, 99,128,251,123,233,238,233, + 244,233,225,236,225,242,225,226,233, 99,128,251,124,237,229,228, + 233,225,236,225,242,225,226,233, 99,128,251,125,233,242, 99, 2, + 185, 68,185, 73,236,101,128, 36,227,245,237,230,236,229,248,226, + 229,236,239,119,128, 30,113,239,237,237,225,225,227,227,229,238, + 116,128, 1, 99,100, 2,185,106,185,116,233,229,242,229,243,233, + 115,128, 30,151,239,116, 2,185,123,185,132,225,227,227,229,238, + 116,128, 30,107,226,229,236,239,119,128, 30,109,101, 9,185,160, + 185,171,185,191,186,201,186,226,187, 34,187,101,187,106,187,158, + 227,249,242,233,236,236,233, 99,128, 4, 66,228,229,243,227,229, + 238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,173,104, + 7,185,207,185,216,185,230,186, 14,186, 44,186, 85,186,183,225, + 242,225,226,233, 99,128, 6, 42,230,233,238,225,236,225,242,225, + 226,233, 99,128,254,150,232,225,232,105, 2,185,239,185,254,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,252,162,243,239, + 236,225,244,229,228,225,242,225,226,233, 99,128,252, 12,105, 2, + 186, 20,186, 35,238,233,244,233,225,236,225,242,225,226,233, 99, + 128,254,151,242,225,231,225,238, 97,128, 48,102,234,229,229,237, + 105, 2,186, 54,186, 69,238,233,244,233,225,236,225,242,225,226, + 233, 99,128,252,161,243,239,236,225,244,229,228,225,242,225,226, + 233, 99,128,252, 11,109, 2,186, 91,186,125,225,242,226,245,244, + 97, 2,186,102,186,111,225,242,225,226,233, 99,128, 6, 41,230, + 233,238,225,236,225,242,225,226,233, 99,128,254,148,101, 2,186, + 131,186,144,228,233,225,236,225,242,225,226,233, 99,128,254,152, + 229,237,105, 2,186,152,186,167,238,233,244,233,225,236,225,242, + 225,226,233, 99,128,252,164,243,239,236,225,244,229,228,225,242, + 225,226,233, 99,128,252, 14,238,239,239,238,230,233,238,225,236, + 225,242,225,226,233, 99,128,252,115,235,225,244,225,235,225,238, + 97,129, 48,198,186,214,232,225,236,230,247,233,228,244,104,128, + 255,131,108, 2,186,232,186,251,229,240,232,239,238,101,129, 33, + 33,186,243,226,236,225,227,107,128, 38, 14,233,243,232, 97, 2, + 187, 4,187, 19,231,229,228,239,236,225,232,229,226,242,229,119, + 128, 5,160,241,229,244,225,238,225,232,229,226,242,229,119,128, + 5,169,110, 4,187, 44,187, 53,187, 72,187, 93,227,233,242,227, + 236,101,128, 36,105,233,228,229,239,231,242,225,240,232,233,227, + 240,225,242,229,110,128, 50, 41,112, 2,187, 78,187, 85,225,242, + 229,110,128, 36,125,229,242,233,239,100,128, 36,145,242,239,237, + 225,110,128, 33,121,243,104,128, 2,167,116,131, 5,216,187,116, + 187,136,187,145,228,225,231,229,243,104,129,251, 56,187,127,232, + 229,226,242,229,119,128,251, 56,232,229,226,242,229,119,128, 5, + 216,243,229,227,249,242,233,236,236,233, 99,128, 4,181,246,233, + 114, 2,187,166,187,175,232,229,226,242,229,119,128, 5,155,236, + 229,230,244,232,229,226,242,229,119,128, 5,155,104, 6,187,202, + 188, 98,188,220,189, 96,190, 3,191, 60, 97, 5,187,214,187,224, + 187,231,188, 0,188, 29,226,229,238,231,225,236,105,128, 9,165, + 228,229,246, 97,128, 9, 37,231,117, 2,187,238,187,247,234,225, + 242,225,244,105,128, 10,165,242,237,245,235,232,105,128, 10, 37, + 108, 2,188, 6,188, 15,225,242,225,226,233, 99,128, 6, 48,230, + 233,238,225,236,225,242,225,226,233, 99,128,254,172,238,244,232, + 225,235,232,225,116, 3,188, 44,188, 75,188, 82,236,239,119, 2, + 188, 52,188, 63,236,229,230,244,244,232,225,105,128,248,152,242, + 233,231,232,244,244,232,225,105,128,248,151,244,232,225,105,128, + 14, 76,245,240,240,229,242,236,229,230,244,244,232,225,105,128, + 248,150,101, 3,188,106,188,170,188,193,104, 4,188,116,188,125, + 188,139,188,155,225,242,225,226,233, 99,128, 6, 43,230,233,238, + 225,236,225,242,225,226,233, 99,128,254,154,233,238,233,244,233, + 225,236,225,242,225,226,233, 99,128,254,155,237,229,228,233,225, + 236,225,242,225,226,233, 99,128,254,156,242,101, 2,188,177,188, + 186,229,248,233,243,244,115,128, 34, 3,230,239,242,101,128, 34, + 52,244, 97,130, 3,184,188,202,188,206, 49,128, 3,209,243,249, + 237,226,239,236,231,242,229,229,107,128, 3,209,105, 2,188,226, + 189, 56,229,245,244,104, 4,188,239,189, 18,189, 33,189, 42, 97, + 2,188,245,189, 4,227,233,242,227,236,229,235,239,242,229,225, + 110,128, 50,121,240,225,242,229,238,235,239,242,229,225,110,128, + 50, 25,227,233,242,227,236,229,235,239,242,229,225,110,128, 50, + 107,235,239,242,229,225,110,128, 49, 76,240,225,242,229,238,235, + 239,242,229,225,110,128, 50, 11,242,244,229,229,110, 2,189, 66, + 189, 75,227,233,242,227,236,101,128, 36,108,112, 2,189, 81,189, + 88,225,242,229,110,128, 36,128,229,242,233,239,100,128, 36,148, + 111, 6,189,110,189,127,189,132,189,146,189,151,189,204,238,225, + 238,231,237,239,238,244,232,239,244,232,225,105,128, 14, 17,239, + 107,128, 1,173,240,232,245,244,232,225,239,244,232,225,105,128, + 14, 18,242,110,128, 0,254,244,104, 3,189,160,189,184,189,194, + 97, 2,189,166,189,176,232,225,238,244,232,225,105,128, 14, 23, + 238,244,232,225,105,128, 14, 16,239,238,231,244,232,225,105,128, + 14, 24,245,238,231,244,232,225,105,128, 14, 22,245,243,225,238, + 100, 2,189,214,189,225,227,249,242,233,236,236,233, 99,128, 4, + 130,243,243,229,240,225,242,225,244,239,114, 2,189,240,189,249, + 225,242,225,226,233, 99,128, 6,108,240,229,242,243,233,225,110, + 128, 6,108,242,229,101,144, 0, 51,190, 41,190, 50,190, 60,190, + 90,190, 97,190,107,190,132,190,159,190,193,190,205,190,224,190, + 235,191, 12,191, 34,191, 42,191, 53,225,242,225,226,233, 99,128, + 6, 99,226,229,238,231,225,236,105,128, 9,233,227,233,242,227, + 236,101,129, 36, 98,190, 71,233,238,246,229,242,243,229,243,225, + 238,243,243,229,242,233,102,128, 39,140,228,229,246, 97,128, 9, + 105,229,233,231,232,244,232,115,128, 33, 92,231,117, 2,190,114, + 190,123,234,225,242,225,244,105,128, 10,233,242,237,245,235,232, + 105,128, 10,105,232, 97, 2,190,139,190,150,227,235,225,242,225, + 226,233, 99,128, 6, 99,238,231,250,232,239,117,128, 48, 35,105, + 2,190,165,190,183,228,229,239,231,242,225,240,232,233,227,240, + 225,242,229,110,128, 50, 34,238,230,229,242,233,239,114,128, 32, + 131,237,239,238,239,243,240,225,227,101,128,255, 19,238,245,237, + 229,242,225,244,239,242,226,229,238,231,225,236,105,128, 9,246, + 239,236,228,243,244,249,236,101,128,247, 51,112, 2,190,241,190, + 248,225,242,229,110,128, 36,118,229,114, 2,190,255,191, 5,233, + 239,100,128, 36,138,243,233,225,110,128, 6,243,241,245,225,242, + 244,229,242,115,129, 0,190,191, 25,229,237,228,225,243,104,128, + 246,222,242,239,237,225,110,128, 33,114,243,245,240,229,242,233, + 239,114,128, 0,179,244,232,225,105,128, 14, 83,250,243,241,245, + 225,242,101,128, 51,148,105, 7,191, 86,191, 97,191,212,192, 54, + 192, 66,192,115,192,132,232,233,242,225,231,225,238, 97,128, 48, + 97,107, 2,191,103,191,127,225,244,225,235,225,238, 97,129, 48, + 193,191,115,232,225,236,230,247,233,228,244,104,128,255,129,229, + 245,116, 4,191,139,191,174,191,189,191,198, 97, 2,191,145,191, + 160,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,112, + 240,225,242,229,238,235,239,242,229,225,110,128, 50, 16,227,233, + 242,227,236,229,235,239,242,229,225,110,128, 50, 98,235,239,242, + 229,225,110,128, 49, 55,240,225,242,229,238,235,239,242,229,225, + 110,128, 50, 2,236,228,101,133, 2,220,191,228,191,239,192, 0, + 192, 12,192, 40,226,229,236,239,247,227,237, 98,128, 3, 48, 99, + 2,191,245,191,250,237, 98,128, 3, 3,239,237, 98,128, 3, 3, + 228,239,245,226,236,229,227,237, 98,128, 3, 96,111, 2,192, 18, + 192, 28,240,229,242,225,244,239,114,128, 34, 60,246,229,242,236, + 225,249,227,237, 98,128, 3, 52,246,229,242,244,233,227,225,236, + 227,237, 98,128, 3, 62,237,229,243,227,233,242,227,236,101,128, + 34,151,112, 2,192, 72,192,102,229,232, 97, 2,192, 80,192, 89, + 232,229,226,242,229,119,128, 5,150,236,229,230,244,232,229,226, + 242,229,119,128, 5,150,240,233,231,245,242,237,245,235,232,105, + 128, 10,112,244,236,239,227,249,242,233,236,236,233,227,227,237, + 98,128, 4,131,247,238,225,242,237,229,238,233,225,110,128, 5, + 127,236,233,238,229,226,229,236,239,119,128, 30,111,237,239,238, + 239,243,240,225,227,101,128,255, 84,111, 7,192,185,192,196,192, + 207,192,232,193, 96,193,108,193,192,225,242,237,229,238,233,225, + 110,128, 5,105,232,233,242,225,231,225,238, 97,128, 48,104,235, + 225,244,225,235,225,238, 97,129, 48,200,192,220,232,225,236,230, + 247,233,228,244,104,128,255,132,110, 3,192,240,193, 82,193, 87, + 101, 4,192,250,193, 63,193, 70,193, 76,226,225,114, 4,193, 6, + 193, 35,193, 45,193, 54,229,248,244,242, 97, 2,193, 16,193, 26, + 232,233,231,232,237,239,100,128, 2,229,236,239,247,237,239,100, + 128, 2,233,232,233,231,232,237,239,100,128, 2,230,236,239,247, + 237,239,100,128, 2,232,237,233,228,237,239,100,128, 2,231,230, + 233,246,101,128, 1,189,243,233,120,128, 1,133,244,247,111,128, + 1,168,239,115,128, 3,132,243,241,245,225,242,101,128, 51, 39, + 240,225,244,225,235,244,232,225,105,128, 14, 15,242,244,239,233, + 243,229,243,232,229,236,236,226,242,225,227,235,229,116, 2,193, + 131,193,161,236,229,230,116,130, 48, 20,193,142,193,150,243,237, + 225,236,108,128,254, 93,246,229,242,244,233,227,225,108,128,254, + 57,242,233,231,232,116,130, 48, 21,193,173,193,181,243,237,225, + 236,108,128,254, 94,246,229,242,244,233,227,225,108,128,254, 58, + 244,225,239,244,232,225,105,128, 14, 21,240, 97, 2,193,209,193, + 221,236,225,244,225,236,232,239,239,107,128, 1,171,242,229,110, + 128, 36,175,114, 3,193,235,194, 10,194, 25,225,228,229,237,225, + 242,107,129, 33, 34,193,247,115, 2,193,253,194, 3,225,238,115, + 128,248,234,229,242,233,102,128,246,219,229,244,242,239,230,236, + 229,248,232,239,239,107,128, 2,136,233,225,103, 4,194, 37,194, + 42,194, 47,194, 52,228,110,128, 37,188,236,102,128, 37,196,242, + 116,128, 37,186,245,112,128, 37,178,115,132, 2,166,194, 69,194, + 108,194,214,194,227,225,228,105,130, 5,230,194, 79,194, 99,228, + 225,231,229,243,104,129,251, 70,194, 90,232,229,226,242,229,119, + 128,251, 70,232,229,226,242,229,119,128, 5,230,101, 2,194,114, + 194,125,227,249,242,233,236,236,233, 99,128, 4, 70,242,101,134, + 5,181,194,142,194,156,194,161,194,170,194,185,194,201, 49, 2, + 194,148,194,152, 50,128, 5,181,101,128, 5,181,178, 98,128, 5, + 181,232,229,226,242,229,119,128, 5,181,238,225,242,242,239,247, + 232,229,226,242,229,119,128, 5,181,241,245,225,242,244,229,242, + 232,229,226,242,229,119,128, 5,181,247,233,228,229,232,229,226, + 242,229,119,128, 5,181,232,229,227,249,242,233,236,236,233, 99, + 128, 4, 91,245,240,229,242,233,239,114,128,246,243,116, 4,194, + 247,195, 41,195,106,195,157, 97, 3,194,255,195, 9,195, 16,226, + 229,238,231,225,236,105,128, 9,159,228,229,246, 97,128, 9, 31, + 231,117, 2,195, 23,195, 32,234,225,242,225,244,105,128, 10,159, + 242,237,245,235,232,105,128, 10, 31,229,104, 4,195, 52,195, 61, + 195, 75,195, 91,225,242,225,226,233, 99,128, 6,121,230,233,238, + 225,236,225,242,225,226,233, 99,128,251,103,233,238,233,244,233, + 225,236,225,242,225,226,233, 99,128,251,104,237,229,228,233,225, + 236,225,242,225,226,233, 99,128,251,105,232, 97, 3,195,115,195, + 125,195,132,226,229,238,231,225,236,105,128, 9,160,228,229,246, + 97,128, 9, 32,231,117, 2,195,139,195,148,234,225,242,225,244, + 105,128, 10,160,242,237,245,235,232,105,128, 10, 32,245,242,238, + 229,100,128, 2,135,117, 3,195,173,195,184,195,209,232,233,242, + 225,231,225,238, 97,128, 48,100,235,225,244,225,235,225,238, 97, + 129, 48,196,195,197,232,225,236,230,247,233,228,244,104,128,255, + 130,243,237,225,236,108, 2,195,219,195,230,232,233,242,225,231, + 225,238, 97,128, 48, 99,235,225,244,225,235,225,238, 97,129, 48, + 195,195,243,232,225,236,230,247,233,228,244,104,128,255,111,119, + 2,196, 5,196,110,101, 2,196, 11,196, 59,236,246,101, 3,196, + 21,196, 30,196, 51,227,233,242,227,236,101,128, 36,107,112, 2, + 196, 36,196, 43,225,242,229,110,128, 36,127,229,242,233,239,100, + 128, 36,147,242,239,237,225,110,128, 33,123,238,244,121, 3,196, + 69,196, 78,196, 89,227,233,242,227,236,101,128, 36,115,232,225, + 238,231,250,232,239,117,128, 83, 68,112, 2,196, 95,196,102,225, + 242,229,110,128, 36,135,229,242,233,239,100,128, 36,155,111,142, + 0, 50,196,142,196,151,196,161,196,191,196,243,197, 12,197, 39, + 197, 73,197, 85,197,104,197,115,197,148,197,156,197,180,225,242, + 225,226,233, 99,128, 6, 98,226,229,238,231,225,236,105,128, 9, + 232,227,233,242,227,236,101,129, 36, 97,196,172,233,238,246,229, + 242,243,229,243,225,238,243,243,229,242,233,102,128, 39,139,100, + 2,196,197,196,203,229,246, 97,128, 9,104,239,116, 2,196,210, + 196,221,229,238,236,229,225,228,229,114,128, 32, 37,236,229,225, + 228,229,114,129, 32, 37,196,232,246,229,242,244,233,227,225,108, + 128,254, 48,231,117, 2,196,250,197, 3,234,225,242,225,244,105, + 128, 10,232,242,237,245,235,232,105,128, 10,104,232, 97, 2,197, + 19,197, 30,227,235,225,242,225,226,233, 99,128, 6, 98,238,231, + 250,232,239,117,128, 48, 34,105, 2,197, 45,197, 63,228,229,239, + 231,242,225,240,232,233,227,240,225,242,229,110,128, 50, 33,238, + 230,229,242,233,239,114,128, 32,130,237,239,238,239,243,240,225, + 227,101,128,255, 18,238,245,237,229,242,225,244,239,242,226,229, + 238,231,225,236,105,128, 9,245,239,236,228,243,244,249,236,101, + 128,247, 50,112, 2,197,121,197,128,225,242,229,110,128, 36,117, + 229,114, 2,197,135,197,141,233,239,100,128, 36,137,243,233,225, + 110,128, 6,242,242,239,237,225,110,128, 33,113,115, 2,197,162, + 197,170,244,242,239,235,101,128, 1,187,245,240,229,242,233,239, + 114,128, 0,178,244,104, 2,197,187,197,192,225,105,128, 14, 82, + 233,242,228,115,128, 33, 84,117,145, 0,117,197,237,197,245,198, + 30,198, 87,198,225,199, 6,199,129,199,145,199,196,200, 10,200, + 91,200,100,200,219,200,243,201, 95,201,123,201,237,225,227,245, + 244,101,128, 0,250, 98, 4,197,255,198, 4,198, 13,198, 23,225, + 114,128, 2,137,229,238,231,225,236,105,128, 9,137,239,240,239, + 237,239,230,111,128, 49, 40,242,229,246,101,128, 1,109, 99, 3, + 198, 38,198, 45,198, 77,225,242,239,110,128, 1,212,233,242, 99, + 2,198, 53,198, 58,236,101,128, 36,228,245,237,230,236,229,120, + 129, 0,251,198, 69,226,229,236,239,119,128, 30,119,249,242,233, + 236,236,233, 99,128, 4, 67,100, 5,198, 99,198,110,198,133,198, + 139,198,215,225,244,244,225,228,229,246, 97,128, 9, 81,226,108, + 2,198,117,198,125,225,227,245,244,101,128, 1,113,231,242,225, + 246,101,128, 2, 21,229,246, 97,128, 9, 9,233,229,242,229,243, + 233,115,133, 0,252,198,159,198,167,198,175,198,198,198,206,225, + 227,245,244,101,128, 1,216,226,229,236,239,119,128, 30,115, 99, + 2,198,181,198,188,225,242,239,110,128, 1,218,249,242,233,236, + 236,233, 99,128, 4,241,231,242,225,246,101,128, 1,220,237,225, + 227,242,239,110,128, 1,214,239,244,226,229,236,239,119,128, 30, + 229,103, 2,198,231,198,238,242,225,246,101,128, 0,249,117, 2, + 198,244,198,253,234,225,242,225,244,105,128, 10,137,242,237,245, + 235,232,105,128, 10, 9,104, 3,199, 14,199, 24,199,102,233,242, + 225,231,225,238, 97,128, 48, 70,111, 2,199, 30,199, 40,239,235, + 225,226,239,246,101,128, 30,231,242,110,133, 1,176,199, 55,199, + 63,199, 74,199, 82,199, 94,225,227,245,244,101,128, 30,233,228, + 239,244,226,229,236,239,119,128, 30,241,231,242,225,246,101,128, + 30,235,232,239,239,235,225,226,239,246,101,128, 30,237,244,233, + 236,228,101,128, 30,239,245,238,231,225,242,245,237,236,225,245, + 116,129, 1,113,199,118,227,249,242,233,236,236,233, 99,128, 4, + 243,233,238,246,229,242,244,229,228,226,242,229,246,101,128, 2, + 23,107, 3,199,153,199,177,199,188,225,244,225,235,225,238, 97, + 129, 48,166,199,165,232,225,236,230,247,233,228,244,104,128,255, + 115,227,249,242,233,236,236,233, 99,128, 4,121,239,242,229,225, + 110,128, 49, 92,109, 2,199,202,199,255, 97, 2,199,208,199,241, + 227,242,239,110,130, 1,107,199,219,199,230,227,249,242,233,236, + 236,233, 99,128, 4,239,228,233,229,242,229,243,233,115,128, 30, + 123,244,242,225,231,245,242,237,245,235,232,105,128, 10, 65,239, + 238,239,243,240,225,227,101,128,255, 85,110, 2,200, 16,200, 71, + 228,229,242,243,227,239,242,101,132, 0, 95,200, 35,200, 41,200, + 53,200, 64,228,226,108,128, 32, 23,237,239,238,239,243,240,225, + 227,101,128,255, 63,246,229,242,244,233,227,225,108,128,254, 51, + 247,225,246,121,128,254, 79,105, 2,200, 77,200, 82,239,110,128, + 34, 42,246,229,242,243,225,108,128, 34, 0,239,231,239,238,229, + 107,128, 1,115,112, 5,200,112,200,119,200,127,200,142,200,193, + 225,242,229,110,128, 36,176,226,236,239,227,107,128, 37,128,240, + 229,242,228,239,244,232,229,226,242,229,119,128, 5,196,243,233, + 236,239,110,131, 3,197,200,156,200,177,200,185,228,233,229,242, + 229,243,233,115,129, 3,203,200,169,244,239,238,239,115,128, 3, + 176,236,225,244,233,110,128, 2,138,244,239,238,239,115,128, 3, + 205,244,225,227,107, 2,200,202,200,213,226,229,236,239,247,227, + 237, 98,128, 3, 29,237,239,100,128, 2,212,114, 2,200,225,200, + 237,225,231,245,242,237,245,235,232,105,128, 10,115,233,238,103, + 128, 1,111,115, 3,200,251,201, 10,201, 55,232,239,242,244,227, + 249,242,233,236,236,233, 99,128, 4, 94,237,225,236,108, 2,201, + 19,201, 30,232,233,242,225,231,225,238, 97,128, 48, 69,235,225, + 244,225,235,225,238, 97,129, 48,165,201, 43,232,225,236,230,247, + 233,228,244,104,128,255,105,244,242,225,233,231,232,116, 2,201, + 67,201, 78,227,249,242,233,236,236,233, 99,128, 4,175,243,244, + 242,239,235,229,227,249,242,233,236,236,233, 99,128, 4,177,244, + 233,236,228,101,130, 1,105,201,107,201,115,225,227,245,244,101, + 128, 30,121,226,229,236,239,119,128, 30,117,117, 5,201,135,201, + 145,201,152,201,177,201,193,226,229,238,231,225,236,105,128, 9, + 138,228,229,246, 97,128, 9, 10,231,117, 2,201,159,201,168,234, + 225,242,225,244,105,128, 10,138,242,237,245,235,232,105,128, 10, + 10,237,225,244,242,225,231,245,242,237,245,235,232,105,128, 10, + 66,246,239,247,229,236,243,233,231,110, 3,201,209,201,219,201, + 226,226,229,238,231,225,236,105,128, 9,194,228,229,246, 97,128, + 9, 66,231,245,234,225,242,225,244,105,128, 10,194,246,239,247, + 229,236,243,233,231,110, 3,201,253,202, 7,202, 14,226,229,238, + 231,225,236,105,128, 9,193,228,229,246, 97,128, 9, 65,231,245, + 234,225,242,225,244,105,128, 10,193,118,139, 0,118,202, 51,202, + 199,202,208,202,219,203,148,203,155,203,253,204, 9,204,109,204, + 117,204,138, 97, 4,202, 61,202, 68,202, 93,202,104,228,229,246, + 97,128, 9, 53,231,117, 2,202, 75,202, 84,234,225,242,225,244, + 105,128, 10,181,242,237,245,235,232,105,128, 10, 53,235,225,244, + 225,235,225,238, 97,128, 48,247,118,132, 5,213,202,116,202,143, + 202,175,202,187,228,225,231,229,243,104,130,251, 53,202,129,202, + 134,182, 53,128,251, 53,232,229,226,242,229,119,128,251, 53,104, + 2,202,149,202,157,229,226,242,229,119,128, 5,213,239,236,225, + 109,129,251, 75,202,166,232,229,226,242,229,119,128,251, 75,246, + 225,246,232,229,226,242,229,119,128, 5,240,249,239,228,232,229, + 226,242,229,119,128, 5,241,227,233,242,227,236,101,128, 36,229, + 228,239,244,226,229,236,239,119,128, 30,127,101, 6,202,233,202, + 244,203, 52,203, 63,203, 69,203,136,227,249,242,233,236,236,233, + 99,128, 4, 50,104, 4,202,254,203, 7,203, 21,203, 37,225,242, + 225,226,233, 99,128, 6,164,230,233,238,225,236,225,242,225,226, + 233, 99,128,251,107,233,238,233,244,233,225,236,225,242,225,226, + 233, 99,128,251,108,237,229,228,233,225,236,225,242,225,226,233, + 99,128,251,109,235,225,244,225,235,225,238, 97,128, 48,249,238, + 245,115,128, 38, 64,242,244,233,227,225,108, 2,203, 80,203, 86, + 226,225,114,128, 0,124,236,233,238,101, 4,203, 99,203,110,203, + 121,203,130,225,226,239,246,229,227,237, 98,128, 3, 13,226,229, + 236,239,247,227,237, 98,128, 3, 41,236,239,247,237,239,100,128, + 2,204,237,239,100,128, 2,200,247,225,242,237,229,238,233,225, + 110,128, 5,126,232,239,239,107,128, 2,139,105, 3,203,163,203, + 174,203,213,235,225,244,225,235,225,238, 97,128, 48,248,242,225, + 237, 97, 3,203,185,203,195,203,202,226,229,238,231,225,236,105, + 128, 9,205,228,229,246, 97,128, 9, 77,231,245,234,225,242,225, + 244,105,128, 10,205,243,225,242,231, 97, 3,203,225,203,235,203, + 242,226,229,238,231,225,236,105,128, 9,131,228,229,246, 97,128, + 9, 3,231,245,234,225,242,225,244,105,128, 10,131,237,239,238, + 239,243,240,225,227,101,128,255, 86,111, 3,204, 17,204, 28,204, + 98,225,242,237,229,238,233,225,110,128, 5,120,233,227,229,100, + 2,204, 37,204, 73,233,244,229,242,225,244,233,239,110, 2,204, + 51,204, 62,232,233,242,225,231,225,238, 97,128, 48,158,235,225, + 244,225,235,225,238, 97,128, 48,254,237,225,242,235,235,225,238, + 97,129, 48,155,204, 86,232,225,236,230,247,233,228,244,104,128, + 255,158,235,225,244,225,235,225,238, 97,128, 48,250,240,225,242, + 229,110,128, 36,177,116, 2,204,123,204,130,233,236,228,101,128, + 30,125,245,242,238,229,100,128, 2,140,117, 2,204,144,204,155, + 232,233,242,225,231,225,238, 97,128, 48,148,235,225,244,225,235, + 225,238, 97,128, 48,244,119,143, 0,119,204,200,205,177,205,187, + 205,210,205,250,206, 61,206, 69,208, 40,208, 81,208, 93,208,168, + 208,176,208,183,208,194,208,203, 97, 8,204,218,204,225,204,235, + 204,246,205, 28,205, 60,205, 72,205,108,227,245,244,101,128, 30, + 131,229,235,239,242,229,225,110,128, 49, 89,232,233,242,225,231, + 225,238, 97,128, 48,143,107, 2,204,252,205, 20,225,244,225,235, + 225,238, 97,129, 48,239,205, 8,232,225,236,230,247,233,228,244, + 104,128,255,156,239,242,229,225,110,128, 49, 88,243,237,225,236, + 108, 2,205, 38,205, 49,232,233,242,225,231,225,238, 97,128, 48, + 142,235,225,244,225,235,225,238, 97,128, 48,238,244,244,239,243, + 241,245,225,242,101,128, 51, 87,118, 2,205, 78,205, 86,229,228, + 225,243,104,128, 48, 28,249,245,238,228,229,242,243,227,239,242, + 229,246,229,242,244,233,227,225,108,128,254, 52,119, 3,205,116, + 205,125,205,139,225,242,225,226,233, 99,128, 6, 72,230,233,238, + 225,236,225,242,225,226,233, 99,128,254,238,232,225,237,250,225, + 225,226,239,246,101, 2,205,154,205,163,225,242,225,226,233, 99, + 128, 6, 36,230,233,238,225,236,225,242,225,226,233, 99,128,254, + 134,226,243,241,245,225,242,101,128, 51,221,227,233,242, 99, 2, + 205,196,205,201,236,101,128, 36,230,245,237,230,236,229,120,128, + 1,117,100, 2,205,216,205,226,233,229,242,229,243,233,115,128, + 30,133,239,116, 2,205,233,205,242,225,227,227,229,238,116,128, + 30,135,226,229,236,239,119,128, 30,137,101, 4,206, 4,206, 15, + 206, 27,206, 51,232,233,242,225,231,225,238, 97,128, 48,145,233, + 229,242,243,244,242,225,243,115,128, 33, 24,107, 2,206, 33,206, + 43,225,244,225,235,225,238, 97,128, 48,241,239,242,229,225,110, + 128, 49, 94,239,235,239,242,229,225,110,128, 49, 93,231,242,225, + 246,101,128, 30,129,232,233,244,101, 8,206, 90,206, 99,206,183, + 207, 17,207,101,207,146,207,198,207,254,226,245,236,236,229,116, + 128, 37,230, 99, 2,206,105,206,125,233,242,227,236,101,129, 37, + 203,206,115,233,238,246,229,242,243,101,128, 37,217,239,242,238, + 229,242,226,242,225,227,235,229,116, 2,206,142,206,162,236,229, + 230,116,129, 48, 14,206,151,246,229,242,244,233,227,225,108,128, + 254, 67,242,233,231,232,116,129, 48, 15,206,172,246,229,242,244, + 233,227,225,108,128,254, 68,100, 2,206,189,206,230,233,225,237, + 239,238,100,129, 37,199,206,200,227,239,238,244,225,233,238,233, + 238,231,226,236,225,227,235,243,237,225,236,236,228,233,225,237, + 239,238,100,128, 37,200,239,247,238,240,239,233,238,244,233,238, + 103, 2,206,246,207, 6,243,237,225,236,236,244,242,233,225,238, + 231,236,101,128, 37,191,244,242,233,225,238,231,236,101,128, 37, + 189,236,101, 2,207, 24,207, 66,230,244,240,239,233,238,244,233, + 238,103, 2,207, 39,207, 55,243,237,225,236,236,244,242,233,225, + 238,231,236,101,128, 37,195,244,242,233,225,238,231,236,101,128, + 37,193,238,244,233,227,245,236,225,242,226,242,225,227,235,229, + 116, 2,207, 86,207, 93,236,229,230,116,128, 48, 22,242,233,231, + 232,116,128, 48, 23,242,233,231,232,244,240,239,233,238,244,233, + 238,103, 2,207,119,207,135,243,237,225,236,236,244,242,233,225, + 238,231,236,101,128, 37,185,244,242,233,225,238,231,236,101,128, + 37,183,115, 3,207,154,207,184,207,192,109, 2,207,160,207,172, + 225,236,236,243,241,245,225,242,101,128, 37,171,233,236,233,238, + 231,230,225,227,101,128, 38, 58,241,245,225,242,101,128, 37,161, + 244,225,114,128, 38, 6,116, 2,207,204,207,215,229,236,229,240, + 232,239,238,101,128, 38, 15,239,242,244,239,233,243,229,243,232, + 229,236,236,226,242,225,227,235,229,116, 2,207,239,207,246,236, + 229,230,116,128, 48, 24,242,233,231,232,116,128, 48, 25,245,240, + 240,239,233,238,244,233,238,103, 2,208, 13,208, 29,243,237,225, + 236,236,244,242,233,225,238,231,236,101,128, 37,181,244,242,233, + 225,238,231,236,101,128, 37,179,105, 2,208, 46,208, 57,232,233, + 242,225,231,225,238, 97,128, 48,144,107, 2,208, 63,208, 73,225, + 244,225,235,225,238, 97,128, 48,240,239,242,229,225,110,128, 49, + 95,237,239,238,239,243,240,225,227,101,128,255, 87,111, 4,208, + 103,208,114,208,139,208,157,232,233,242,225,231,225,238, 97,128, + 48,146,235,225,244,225,235,225,238, 97,129, 48,242,208,127,232, + 225,236,230,247,233,228,244,104,128,255,102,110,129, 32,169,208, + 145,237,239,238,239,243,240,225,227,101,128,255,230,247,225,229, + 238,244,232,225,105,128, 14, 39,240,225,242,229,110,128, 36,178, + 242,233,238,103,128, 30,152,243,245,240,229,242,233,239,114,128, + 2,183,244,245,242,238,229,100,128, 2,141,249,238,110,128, 1, + 191,120,137, 0,120,208,231,208,242,208,253,209, 6,209, 33,209, + 46,209, 50,209, 62,209, 70,225,226,239,246,229,227,237, 98,128, + 3, 61,226,239,240,239,237,239,230,111,128, 49, 18,227,233,242, + 227,236,101,128, 36,231,100, 2,209, 12,209, 22,233,229,242,229, + 243,233,115,128, 30,141,239,244,225,227,227,229,238,116,128, 30, + 139,229,232,225,242,237,229,238,233,225,110,128, 5,109,105,128, + 3,190,237,239,238,239,243,240,225,227,101,128,255, 88,240,225, + 242,229,110,128, 36,179,243,245,240,229,242,233,239,114,128, 2, + 227,121,143, 0,121,209,115,210, 74,210, 97,210,137,212,103,212, + 111,212,128,212,192,212,204,213,201,213,241,213,253,214, 8,214, + 29,215, 2, 97, 11,209,139,209,151,209,161,209,168,209,175,209, + 185,209,210,209,221,210, 3,210, 16,210, 62,225,228,239,243,241, + 245,225,242,101,128, 51, 78,226,229,238,231,225,236,105,128, 9, + 175,227,245,244,101,128, 0,253,228,229,246, 97,128, 9, 47,229, + 235,239,242,229,225,110,128, 49, 82,231,117, 2,209,192,209,201, + 234,225,242,225,244,105,128, 10,175,242,237,245,235,232,105,128, + 10, 47,232,233,242,225,231,225,238, 97,128, 48,132,107, 2,209, + 227,209,251,225,244,225,235,225,238, 97,129, 48,228,209,239,232, + 225,236,230,247,233,228,244,104,128,255,148,239,242,229,225,110, + 128, 49, 81,237,225,235,235,225,238,244,232,225,105,128, 14, 78, + 243,237,225,236,108, 2,210, 26,210, 37,232,233,242,225,231,225, + 238, 97,128, 48,131,235,225,244,225,235,225,238, 97,129, 48,227, + 210, 50,232,225,236,230,247,233,228,244,104,128,255,108,244,227, + 249,242,233,236,236,233, 99,128, 4, 99,227,233,242, 99, 2,210, + 83,210, 88,236,101,128, 36,232,245,237,230,236,229,120,128, 1, + 119,100, 2,210,103,210,113,233,229,242,229,243,233,115,128, 0, + 255,239,116, 2,210,120,210,129,225,227,227,229,238,116,128, 30, + 143,226,229,236,239,119,128, 30,245,101, 7,210,153,211,161,211, + 170,211,188,211,220,212, 40,212, 91,104, 8,210,171,210,180,210, + 214,210,228,211, 45,211, 61,211,120,211,138,225,242,225,226,233, + 99,128, 6, 74,226,225,242,242,229,101, 2,210,191,210,200,225, + 242,225,226,233, 99,128, 6,210,230,233,238,225,236,225,242,225, + 226,233, 99,128,251,175,230,233,238,225,236,225,242,225,226,233, + 99,128,254,242,232,225,237,250,225,225,226,239,246,101, 4,210, + 247,211, 0,211, 14,211, 30,225,242,225,226,233, 99,128, 6, 38, + 230,233,238,225,236,225,242,225,226,233, 99,128,254,138,233,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,254,139,237,229, + 228,233,225,236,225,242,225,226,233, 99,128,254,140,233,238,233, + 244,233,225,236,225,242,225,226,233, 99,128,254,243,237,101, 2, + 211, 68,211, 81,228,233,225,236,225,242,225,226,233, 99,128,254, + 244,229,237,105, 2,211, 89,211,104,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,252,221,243,239,236,225,244,229,228,225, + 242,225,226,233, 99,128,252, 88,238,239,239,238,230,233,238,225, + 236,225,242,225,226,233, 99,128,252,148,244,232,242,229,229,228, + 239,244,243,226,229,236,239,247,225,242,225,226,233, 99,128, 6, + 209,235,239,242,229,225,110,128, 49, 86,110,129, 0,165,211,176, + 237,239,238,239,243,240,225,227,101,128,255,229,111, 2,211,194, + 211,203,235,239,242,229,225,110,128, 49, 85,242,233,238,232,233, + 229,245,232,235,239,242,229,225,110,128, 49,134,114, 3,211,228, + 212, 8,212, 20,225,232,226,229,238,249,239,237,111, 2,211,242, + 211,251,232,229,226,242,229,119,128, 5,170,236,229,230,244,232, + 229,226,242,229,119,128, 5,170,233,227,249,242,233,236,236,233, + 99,128, 4, 75,245,228,233,229,242,229,243,233,243,227,249,242, + 233,236,236,233, 99,128, 4,249,243,233,229,245,238,103, 3,212, + 53,212, 62,212, 78,235,239,242,229,225,110,128, 49,129,240,225, + 238,243,233,239,243,235,239,242,229,225,110,128, 49,131,243,233, + 239,243,235,239,242,229,225,110,128, 49,130,244,233,246,232,229, + 226,242,229,119,128, 5,154,231,242,225,246,101,128, 30,243,232, + 239,239,107,129, 1,180,212,120,225,226,239,246,101,128, 30,247, + 105, 5,212,140,212,151,212,162,212,171,212,179,225,242,237,229, + 238,233,225,110,128, 5,117,227,249,242,233,236,236,233, 99,128, + 4, 87,235,239,242,229,225,110,128, 49, 98,238,249,225,238,103, + 128, 38, 47,247,238,225,242,237,229,238,233,225,110,128, 5,130, + 237,239,238,239,243,240,225,227,101,128,255, 89,111, 7,212,220, + 213, 34,213, 45,213, 55,213, 93,213,139,213,148,100,131, 5,217, + 212,230,212,250,213, 3,228,225,231,229,243,104,129,251, 57,212, + 241,232,229,226,242,229,119,128,251, 57,232,229,226,242,229,119, + 128, 5,217,249,239,100, 2,213, 11,213, 20,232,229,226,242,229, + 119,128, 5,242,240,225,244,225,232,232,229,226,242,229,119,128, + 251, 31,232,233,242,225,231,225,238, 97,128, 48,136,233,235,239, + 242,229,225,110,128, 49,137,107, 2,213, 61,213, 85,225,244,225, + 235,225,238, 97,129, 48,232,213, 73,232,225,236,230,247,233,228, + 244,104,128,255,150,239,242,229,225,110,128, 49, 91,243,237,225, + 236,108, 2,213,103,213,114,232,233,242,225,231,225,238, 97,128, + 48,135,235,225,244,225,235,225,238, 97,129, 48,231,213,127,232, + 225,236,230,247,233,228,244,104,128,255,110,244,231,242,229,229, + 107,128, 3,243,121, 2,213,154,213,191, 97, 2,213,160,213,170, + 229,235,239,242,229,225,110,128, 49,136,107, 2,213,176,213,184, + 239,242,229,225,110,128, 49,135,244,232,225,105,128, 14, 34,233, + 238,231,244,232,225,105,128, 14, 13,112, 2,213,207,213,214,225, + 242,229,110,128, 36,180,239,231,229,231,242,225,237,237,229,238, + 105,129, 3,122,213,230,231,242,229,229,235,227,237, 98,128, 3, + 69,114,129, 1,166,213,247,233,238,103,128, 30,153,243,245,240, + 229,242,233,239,114,128, 2,184,116, 2,214, 14,214, 21,233,236, + 228,101,128, 30,249,245,242,238,229,100,128, 2,142,117, 5,214, + 41,214, 52,214, 62,214,100,214,232,232,233,242,225,231,225,238, + 97,128, 48,134,233,235,239,242,229,225,110,128, 49,140,107, 2, + 214, 68,214, 92,225,244,225,235,225,238, 97,129, 48,230,214, 80, + 232,225,236,230,247,233,228,244,104,128,255,149,239,242,229,225, + 110,128, 49, 96,115, 3,214,108,214,146,214,187,226,233,103, 2, + 214,116,214,127,227,249,242,233,236,236,233, 99,128, 4,107,233, + 239,244,233,230,233,229,228,227,249,242,233,236,236,233, 99,128, + 4,109,236,233,244,244,236,101, 2,214,157,214,168,227,249,242, + 233,236,236,233, 99,128, 4,103,233,239,244,233,230,233,229,228, + 227,249,242,233,236,236,233, 99,128, 4,105,237,225,236,108, 2, + 214,196,214,207,232,233,242,225,231,225,238, 97,128, 48,133,235, + 225,244,225,235,225,238, 97,129, 48,229,214,220,232,225,236,230, + 247,233,228,244,104,128,255,109,249,101, 2,214,239,214,248,235, + 239,242,229,225,110,128, 49,139,239,235,239,242,229,225,110,128, + 49,138,249, 97, 2,215, 9,215, 19,226,229,238,231,225,236,105, + 128, 9,223,228,229,246, 97,128, 9, 95,122,142, 0,122,215, 58, + 216, 66,216, 77,216,120,216,147,217,182,218, 34,218, 76,218, 88, + 218,100,218,128,218,136,218,152,218,161, 97, 10,215, 80,215, 91, + 215, 98,215,105,215,116,215,194,215,224,215,235,216, 15,216, 27, + 225,242,237,229,238,233,225,110,128, 5,102,227,245,244,101,128, + 1,122,228,229,246, 97,128, 9, 91,231,245,242,237,245,235,232, + 105,128, 10, 91,104, 4,215,126,215,135,215,149,215,179,225,242, + 225,226,233, 99,128, 6, 56,230,233,238,225,236,225,242,225,226, + 233, 99,128,254,198,105, 2,215,155,215,170,238,233,244,233,225, + 236,225,242,225,226,233, 99,128,254,199,242,225,231,225,238, 97, + 128, 48, 86,237,229,228,233,225,236,225,242,225,226,233, 99,128, + 254,200,233,110, 2,215,201,215,210,225,242,225,226,233, 99,128, + 6, 50,230,233,238,225,236,225,242,225,226,233, 99,128,254,176, + 235,225,244,225,235,225,238, 97,128, 48,182,241,229,102, 2,215, + 243,216, 1,231,225,228,239,236,232,229,226,242,229,119,128, 5, + 149,241,225,244,225,238,232,229,226,242,229,119,128, 5,148,242, + 241,225,232,229,226,242,229,119,128, 5,152,249,233,110,130, 5, + 214,216, 37,216, 57,228,225,231,229,243,104,129,251, 54,216, 48, + 232,229,226,242,229,119,128,251, 54,232,229,226,242,229,119,128, + 5,214,226,239,240,239,237,239,230,111,128, 49, 23, 99, 3,216, + 85,216, 92,216,114,225,242,239,110,128, 1,126,233,242, 99, 2, + 216,100,216,105,236,101,128, 36,233,245,237,230,236,229,120,128, + 30,145,245,242,108,128, 2,145,228,239,116,130, 1,124,216,130, + 216,139,225,227,227,229,238,116,128, 1,124,226,229,236,239,119, + 128, 30,147,101, 6,216,161,216,172,216,215,216,226,216,237,217, + 177,227,249,242,233,236,236,233, 99,128, 4, 55,100, 2,216,178, + 216,197,229,243,227,229,238,228,229,242,227,249,242,233,236,236, + 233, 99,128, 4,153,233,229,242,229,243,233,243,227,249,242,233, + 236,236,233, 99,128, 4,223,232,233,242,225,231,225,238, 97,128, + 48, 92,235,225,244,225,235,225,238, 97,128, 48,188,242,111,140, + 0, 48,217, 10,217, 19,217, 29,217, 36,217, 61,217, 74,217, 85, + 217, 97,217,108,217,118,217,129,217,136,225,242,225,226,233, 99, + 128, 6, 96,226,229,238,231,225,236,105,128, 9,230,228,229,246, + 97,128, 9,102,231,117, 2,217, 43,217, 52,234,225,242,225,244, + 105,128, 10,230,242,237,245,235,232,105,128, 10,102,232,225,227, + 235,225,242,225,226,233, 99,128, 6, 96,233,238,230,229,242,233, + 239,114,128, 32,128,237,239,238,239,243,240,225,227,101,128,255, + 16,239,236,228,243,244,249,236,101,128,247, 48,240,229,242,243, + 233,225,110,128, 6,240,243,245,240,229,242,233,239,114,128, 32, + 112,244,232,225,105,128, 14, 80,247,233,228,244,104, 3,217,148, + 217,157,217,169,234,239,233,238,229,114,128,254,255,238,239,238, + 234,239,233,238,229,114,128, 32, 12,243,240,225,227,101,128, 32, + 11,244, 97,128, 3,182,104, 2,217,188,217,199,226,239,240,239, + 237,239,230,111,128, 49, 19,101, 4,217,209,217,220,217,236,217, + 247,225,242,237,229,238,233,225,110,128, 5,106,226,242,229,246, + 229,227,249,242,233,236,236,233, 99,128, 4,194,227,249,242,233, + 236,236,233, 99,128, 4, 54,100, 2,217,253,218, 16,229,243,227, + 229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,151, + 233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99,128, + 4,221,105, 3,218, 42,218, 53,218, 64,232,233,242,225,231,225, + 238, 97,128, 48, 88,235,225,244,225,235,225,238, 97,128, 48,184, + 238,239,242,232,229,226,242,229,119,128, 5,174,236,233,238,229, + 226,229,236,239,119,128, 30,149,237,239,238,239,243,240,225,227, + 101,128,255, 90,111, 2,218,106,218,117,232,233,242,225,231,225, + 238, 97,128, 48, 94,235,225,244,225,235,225,238, 97,128, 48,190, + 240,225,242,229,110,128, 36,181,242,229,244,242,239,230,236,229, + 248,232,239,239,107,128, 2,144,243,244,242,239,235,101,128, 1, + 182,117, 2,218,167,218,178,232,233,242,225,231,225,238, 97,128, + 48, 90,235,225,244,225,235,225,238, 97,128, 48,186 + }; + + + /* + * This function searches the compressed table efficiently. + */ + static unsigned long + ft_get_adobe_glyph_index( const char* name, + const char* limit ) + { + int c = 0; + int count, min, max; + const unsigned char* p = ft_adobe_glyph_list; + + + if ( name == 0 || name >= limit ) + goto NotFound; + + c = *name++; + count = p[1]; + p += 2; + + min = 0; + max = count; + + while ( min < max ) + { + int mid = ( min + max ) >> 1; + const unsigned char* q = p + mid * 2; + int c2; + + + q = ft_adobe_glyph_list + ( ( (int)q[0] << 8 ) | q[1] ); + + c2 = q[0] & 127; + if ( c2 == c ) + { + p = q; + goto Found; + } + if ( c2 < c ) + min = mid + 1; + else + max = mid; + } + goto NotFound; + + Found: + for (;;) + { + /* assert (*p & 127) == c */ + + if ( name >= limit ) + { + if ( (p[0] & 128) == 0 && + (p[1] & 128) != 0 ) + return (unsigned long)( ( (int)p[2] << 8 ) | p[3] ); + + goto NotFound; + } + c = *name++; + if ( p[0] & 128 ) + { + p++; + if ( c != (p[0] & 127) ) + goto NotFound; + + continue; + } + + p++; + count = p[0] & 127; + if ( p[0] & 128 ) + p += 2; + + p++; + + for ( ; count > 0; count--, p += 2 ) + { + int offset = ( (int)p[0] << 8 ) | p[1]; + const unsigned char* q = ft_adobe_glyph_list + offset; + + if ( c == ( q[0] & 127 ) ) + { + p = q; + goto NextIter; + } + } + goto NotFound; + + NextIter: + ; + } + + NotFound: + return 0; + } + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + +/* END */ diff --git a/drivers/freetype/src/psnames/rules.mk b/drivers/freetype/src/psnames/rules.mk new file mode 100644 index 0000000000..4cd39a8ccf --- /dev/null +++ b/drivers/freetype/src/psnames/rules.mk @@ -0,0 +1,71 @@ +# +# FreeType 2 PSNames driver configuration rules +# + + +# Copyright 1996-2000, 2001, 2003, 2011 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. + + +# PSNames driver directory +# +PSNAMES_DIR := $(SRC_DIR)/psnames + + +# compilation flags for the driver +# +PSNAMES_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR)) + + +# PSNames driver sources (i.e., C files) +# +PSNAMES_DRV_SRC := $(PSNAMES_DIR)/psmodule.c \ + $(PSNAMES_DIR)/pspic.c + + +# PSNames driver headers +# +PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ + $(PSNAMES_DIR)/psnamerr.h \ + $(PSNAMES_DIR)/pstables.h + + +# PSNames driver object(s) +# +# PSNAMES_DRV_OBJ_M is used during `multi' builds +# PSNAMES_DRV_OBJ_S is used during `single' builds +# +PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR)/%.c=$(OBJ_DIR)/%.$O) +PSNAMES_DRV_OBJ_S := $(OBJ_DIR)/psnames.$O + +# PSNames driver source file for single build +# +PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psmodule.c + + +# PSNames driver - single object +# +$(PSNAMES_DRV_OBJ_S): $(PSNAMES_DRV_SRC_S) $(PSNAMES_DRV_SRC) \ + $(FREETYPE_H) $(PSNAMES_DRV_H) + $(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSNAMES_DRV_SRC_S)) + + +# PSNames driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(PSNAMES_DIR)/%.c $(FREETYPE_H) $(PSNAMES_DRV_H) + $(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(PSNAMES_DRV_OBJ_S) +DRV_OBJS_M += $(PSNAMES_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/raster/Jamfile b/drivers/freetype/src/raster/Jamfile new file mode 100644 index 0000000000..4f60e87c78 --- /dev/null +++ b/drivers/freetype/src/raster/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/raster Jamfile +# +# Copyright 2001 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) raster ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ftraster ftrend1 rastpic ; + } + else + { + _sources = raster ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/raster Jamfile diff --git a/drivers/freetype/src/raster/ftmisc.h b/drivers/freetype/src/raster/ftmisc.h new file mode 100644 index 0000000000..703155a429 --- /dev/null +++ b/drivers/freetype/src/raster/ftmisc.h @@ -0,0 +1,142 @@ +/***************************************************************************/ +/* */ +/* ftmisc.h */ +/* */ +/* Miscellaneous macros for stand-alone rasterizer (specification */ +/* only). */ +/* */ +/* Copyright 2005, 2009, 2010 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. */ +/* */ +/***************************************************************************/ + + + /***************************************************/ + /* */ + /* This file is *not* portable! You have to adapt */ + /* its definitions to your platform. */ + /* */ + /***************************************************/ + +#ifndef __FTMISC_H__ +#define __FTMISC_H__ + + + /* memset */ +#include FT_CONFIG_STANDARD_LIBRARY_H + +#define FT_BEGIN_HEADER +#define FT_END_HEADER + +#define FT_LOCAL_DEF( x ) static x + + + /* from include/freetype2/fttypes.h */ + + typedef unsigned char FT_Byte; + typedef signed int FT_Int; + typedef unsigned int FT_UInt; + typedef signed long FT_Long; + typedef unsigned long FT_ULong; + typedef signed long FT_F26Dot6; + typedef int FT_Error; + +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /* from include/freetype2/ftsystem.h */ + + typedef struct FT_MemoryRec_* FT_Memory; + + typedef void* (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + typedef void (*FT_Free_Func)( FT_Memory memory, + void* block ); + + typedef void* (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + typedef struct FT_MemoryRec_ + { + void* user; + + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + + } FT_MemoryRec; + + + /* from src/ftcalc.c */ + +#if ( defined _WIN32 || defined _WIN64 ) + + typedef __int64 FT_Int64; + +#else + +#include "inttypes.h" + + typedef int64_t FT_Int64; + +#endif + + + static FT_Long + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + + + static FT_Long + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + +#endif /* __FTMISC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/raster/ftraster.c b/drivers/freetype/src/raster/ftraster.c new file mode 100644 index 0000000000..bbd503d97d --- /dev/null +++ b/drivers/freetype/src/raster/ftraster.c @@ -0,0 +1,3640 @@ +/***************************************************************************/ +/* */ +/* ftraster.c */ +/* */ +/* The FreeType glyph rasterizer (body). */ +/* */ +/* Copyright 1996-2003, 2005, 2007-2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This file can be compiled without the rest of the FreeType engine, by */ + /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ + /* directory. Typically, you should do something like */ + /* */ + /* - copy `src/raster/ftraster.c' (this file) to your current directory */ + /* */ + /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' */ + /* to your current directory */ + /* */ + /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ + /* */ + /* cc -c -D_STANDALONE_ ftraster.c */ + /* */ + /* The renderer can be initialized with a call to */ + /* `ft_standard_raster.raster_new'; a bitmap can be generated */ + /* with a call to `ft_standard_raster.raster_render'. */ + /* */ + /* See the comments and documentation in the file `ftimage.h' for more */ + /* details on how the raster works. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This is a rewrite of the FreeType 1.x scan-line converter */ + /* */ + /*************************************************************************/ + +#ifdef _STANDALONE_ + +#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> + +#include <string.h> /* for memset */ + +#include "ftmisc.h" +#include "ftimage.h" + +#else /* !_STANDALONE_ */ + +#include <ft2build.h> +#include "ftraster.h" +#include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */ + +#include "rastpic.h" + +#endif /* !_STANDALONE_ */ + + + /*************************************************************************/ + /* */ + /* A simple technical note on how the raster works */ + /* ----------------------------------------------- */ + /* */ + /* Converting an outline into a bitmap is achieved in several steps: */ + /* */ + /* 1 - Decomposing the outline into successive `profiles'. Each */ + /* profile is simply an array of scanline intersections on a given */ + /* dimension. A profile's main attributes are */ + /* */ + /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ + /* */ + /* o an array of intersection coordinates for each scanline */ + /* between `Ymin' and `Ymax' */ + /* */ + /* o a direction, indicating whether it was built going `up' or */ + /* `down', as this is very important for filling rules */ + /* */ + /* o its drop-out mode */ + /* */ + /* 2 - Sweeping the target map's scanlines in order to compute segment */ + /* `spans' which are then filled. Additionally, this pass */ + /* performs drop-out control. */ + /* */ + /* The outline data is parsed during step 1 only. The profiles are */ + /* built from the bottom of the render pool, used as a stack. The */ + /* following graphics shows the profile list under construction: */ + /* */ + /* __________________________________________________________ _ _ */ + /* | | | | | */ + /* | profile | coordinates for | profile | coordinates for |--> */ + /* | 1 | profile 1 | 2 | profile 2 |--> */ + /* |_________|_________________|_________|_________________|__ _ _ */ + /* */ + /* ^ ^ */ + /* | | */ + /* start of render pool top */ + /* */ + /* The top of the profile stack is kept in the `top' variable. */ + /* */ + /* As you can see, a profile record is pushed on top of the render */ + /* pool, which is then followed by its coordinates/intersections. If */ + /* a change of direction is detected in the outline, a new profile is */ + /* generated until the end of the outline. */ + /* */ + /* Note that when all profiles have been generated, the function */ + /* Finalize_Profile_Table() is used to record, for each profile, its */ + /* bottom-most scanline as well as the scanline above its upmost */ + /* boundary. These positions are called `y-turns' because they (sort */ + /* of) correspond to local extrema. They are stored in a sorted list */ + /* built from the top of the render pool as a downwards stack: */ + /* */ + /* _ _ _______________________________________ */ + /* | | */ + /* <--| sorted list of | */ + /* <--| extrema scanlines | */ + /* _ _ __________________|____________________| */ + /* */ + /* ^ ^ */ + /* | | */ + /* maxBuff sizeBuff = end of pool */ + /* */ + /* This list is later used during the sweep phase in order to */ + /* optimize performance (see technical note on the sweep below). */ + /* */ + /* Of course, the raster detects whether the two stacks collide and */ + /* handles the situation properly. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** CONFIGURATION MACROS **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /* define DEBUG_RASTER if you want to compile a debugging version */ +/* #define DEBUG_RASTER */ + + /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ + /* 5-levels anti-aliasing */ +/* #define FT_RASTER_OPTION_ANTI_ALIASING */ + + /* The size of the two-lines intermediate bitmap used */ + /* for anti-aliasing, in bytes. */ +#define RASTER_GRAY_LINES 2048 + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** OTHER MACROS (do not change) **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* 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_raster + + +#ifdef _STANDALONE_ + + /* Auxiliary macros for token concatenation. */ +#define FT_ERR_XCAT( x, y ) x ## y +#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) + + /* This macro is used to indicate that a function parameter is unused. */ + /* Its purpose is simply to reduce compiler warnings. Note also that */ + /* simply defining it as `(void)x' doesn't avoid warnings with certain */ + /* ANSI compilers (e.g. LCC). */ +#define FT_UNUSED( x ) (x) = (x) + + /* Disable the tracing mechanism for simplicity -- developers can */ + /* activate it easily by redefining these macros. */ +#ifndef FT_ERROR +#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ +#endif + +#ifndef FT_TRACE +#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ +#endif + +#ifndef FT_THROW +#define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e ) +#endif + +#define Raster_Err_None 0 +#define Raster_Err_Not_Ini -1 +#define Raster_Err_Overflow -2 +#define Raster_Err_Neg_Height -3 +#define Raster_Err_Invalid -4 +#define Raster_Err_Unsupported -5 + +#define ft_memset memset + +#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, \ + raster_render_, raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; + +#else /* !_STANDALONE_ */ + + +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H /* for FT_TRACE, FT_ERROR, and FT_THROW */ + +#include "rasterrs.h" + +#define Raster_Err_None FT_Err_Ok +#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized +#define Raster_Err_Overflow Raster_Err_Raster_Overflow +#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height +#define Raster_Err_Invalid Raster_Err_Invalid_Outline +#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph + + +#endif /* !_STANDALONE_ */ + + +#ifndef FT_MEM_SET +#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) +#endif + +#ifndef FT_MEM_ZERO +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) +#endif + + /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ + /* typically a small value and the result of a*b is known to fit into */ + /* 32 bits. */ +#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) + + /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ + /* for clipping computations. It simply uses the FT_MulDiv() function */ + /* defined in `ftcalc.h'. */ +#define SMulDiv FT_MulDiv +#define SMulDiv_No_Round FT_MulDiv_No_Round + + /* The rasterizer is a very general purpose component; please leave */ + /* the following redefinitions there (you never know your target */ + /* environment). */ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + +#ifndef SUCCESS +#define SUCCESS 0 +#endif + +#ifndef FAILURE +#define FAILURE 1 +#endif + + +#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ + /* Setting this constant to more than 32 is a */ + /* pure waste of space. */ + +#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** SIMPLE TYPE DECLARATIONS **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + typedef int Int; + typedef unsigned int UInt; + typedef short Short; + typedef unsigned short UShort, *PUShort; + typedef long Long, *PLong; + typedef unsigned long ULong; + + typedef unsigned char Byte, *PByte; + typedef char Bool; + + + typedef union Alignment_ + { + long l; + void* p; + void (*f)(void); + + } Alignment, *PAlignment; + + + typedef struct TPoint_ + { + Long x; + Long y; + + } TPoint; + + + /* values for the `flags' bit field */ +#define Flow_Up 0x8 +#define Overshoot_Top 0x10 +#define Overshoot_Bottom 0x20 + + + /* States of each line, arc, and profile */ + typedef enum TStates_ + { + Unknown_State, + Ascending_State, + Descending_State, + Flat_State + + } TStates; + + + typedef struct TProfile_ TProfile; + typedef TProfile* PProfile; + + struct TProfile_ + { + FT_F26Dot6 X; /* current coordinate during sweep */ + PProfile link; /* link to next profile (various purposes) */ + PLong offset; /* start of profile's data in render pool */ + unsigned flags; /* Bit 0-2: drop-out mode */ + /* Bit 3: profile orientation (up/down) */ + /* Bit 4: is top profile? */ + /* Bit 5: is bottom profile? */ + long height; /* profile's height in scanlines */ + long start; /* profile's starting scanline */ + + unsigned countL; /* number of lines to step before this */ + /* profile becomes drawable */ + + PProfile next; /* next profile in same contour, used */ + /* during drop-out control */ + }; + + typedef PProfile TProfileList; + typedef PProfile* PProfileList; + + + /* Simple record used to implement a stack of bands, required */ + /* by the sub-banding mechanism */ + typedef struct black_TBand_ + { + Short y_min; /* band's minimum */ + Short y_max; /* band's maximum */ + + } black_TBand; + + +#define AlignProfileSize \ + ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) + + +#undef RAS_ARG +#undef RAS_ARGS +#undef RAS_VAR +#undef RAS_VARS + +#ifdef FT_STATIC_RASTER + + +#define RAS_ARGS /* void */ +#define RAS_ARG /* void */ + +#define RAS_VARS /* void */ +#define RAS_VAR /* void */ + +#define FT_UNUSED_RASTER do { } while ( 0 ) + + +#else /* !FT_STATIC_RASTER */ + + +#define RAS_ARGS black_PWorker worker, +#define RAS_ARG black_PWorker worker + +#define RAS_VARS worker, +#define RAS_VAR worker + +#define FT_UNUSED_RASTER FT_UNUSED( worker ) + + +#endif /* !FT_STATIC_RASTER */ + + + typedef struct black_TWorker_ black_TWorker, *black_PWorker; + + + /* prototypes used for sweep function dispatch */ + typedef void + Function_Sweep_Init( RAS_ARGS Short* min, + Short* max ); + + typedef void + Function_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ); + + typedef void + Function_Sweep_Step( RAS_ARG ); + + + /* NOTE: These operations are only valid on 2's complement processors */ +#undef FLOOR +#undef CEILING +#undef TRUNC +#undef SCALED + +#define FLOOR( x ) ( (x) & -ras.precision ) +#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) +#define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) +#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) +#define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half ) + +#define IS_BOTTOM_OVERSHOOT( x ) \ + (Bool)( CEILING( x ) - x >= ras.precision_half ) +#define IS_TOP_OVERSHOOT( x ) \ + (Bool)( x - FLOOR( x ) >= ras.precision_half ) + + /* The most used variables are positioned at the top of the structure. */ + /* Thus, their offset can be coded with less opcodes, resulting in a */ + /* smaller executable. */ + + struct black_TWorker_ + { + Int precision_bits; /* precision related variables */ + Int precision; + Int precision_half; + Int precision_shift; + Int precision_step; + Int precision_jitter; + + Int scale_shift; /* == precision_shift for bitmaps */ + /* == precision_shift+1 for pixmaps */ + + PLong buff; /* The profiles buffer */ + PLong sizeBuff; /* Render pool size */ + PLong maxBuff; /* Profiles buffer size */ + PLong top; /* Current cursor in buffer */ + + FT_Error error; + + Int numTurns; /* number of Y-turns in outline */ + + TPoint* arc; /* current Bezier arc pointer */ + + UShort bWidth; /* target bitmap width */ + PByte bTarget; /* target bitmap buffer */ + PByte gTarget; /* target pixmap buffer */ + + Long lastX, lastY; + Long minY, maxY; + + UShort num_Profs; /* current number of profiles */ + + Bool fresh; /* signals a fresh new profile which */ + /* `start' field must be completed */ + Bool joint; /* signals that the last arc ended */ + /* exactly on a scanline. Allows */ + /* removal of doublets */ + PProfile cProfile; /* current profile */ + PProfile fProfile; /* head of linked list of profiles */ + PProfile gProfile; /* contour's first profile in case */ + /* of impact */ + + TStates state; /* rendering state */ + + FT_Bitmap target; /* description of target bit/pixmap */ + FT_Outline outline; + + Long traceOfs; /* current offset in target bitmap */ + Long traceG; /* current offset in target pixmap */ + + Short traceIncr; /* sweep's increment in target bitmap */ + + Short gray_min_x; /* current min x during gray rendering */ + Short gray_max_x; /* current max x during gray rendering */ + + /* dispatch variables */ + + Function_Sweep_Init* Proc_Sweep_Init; + Function_Sweep_Span* Proc_Sweep_Span; + Function_Sweep_Span* Proc_Sweep_Drop; + Function_Sweep_Step* Proc_Sweep_Step; + + Byte dropOutControl; /* current drop_out control method */ + + Bool second_pass; /* indicates whether a horizontal pass */ + /* should be performed to control */ + /* drop-out accurately when calling */ + /* Render_Glyph. Note that there is */ + /* no horizontal pass during gray */ + /* rendering. */ + + TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ + + black_TBand band_stack[16]; /* band stack used for sub-banding */ + Int band_top; /* band stack top */ + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + Byte* grays; + + Byte gray_lines[RASTER_GRAY_LINES]; + /* Intermediate table used to render the */ + /* graylevels pixmaps. */ + /* gray_lines is a buffer holding two */ + /* monochrome scanlines */ + + Short gray_width; /* width in bytes of one monochrome */ + /* intermediate scanline of gray_lines. */ + /* Each gray pixel takes 2 bits long there */ + + /* The gray_lines must hold 2 lines, thus with size */ + /* in bytes of at least `gray_width*2'. */ + +#endif /* FT_RASTER_ANTI_ALIASING */ + + }; + + + typedef struct black_TRaster_ + { + char* buffer; + long buffer_size; + void* memory; + black_PWorker worker; + Byte grays[5]; + Short gray_width; + + } black_TRaster, *black_PRaster; + +#ifdef FT_STATIC_RASTER + + static black_TWorker cur_ras; +#define ras cur_ras + +#else /* !FT_STATIC_RASTER */ + +#define ras (*worker) + +#endif /* !FT_STATIC_RASTER */ + + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + /* A lookup table used to quickly count set bits in four gray 2x2 */ + /* cells. The values of the table have been produced with the */ + /* following code: */ + /* */ + /* for ( i = 0; i < 256; i++ ) */ + /* { */ + /* l = 0; */ + /* j = i; */ + /* */ + /* for ( c = 0; c < 4; c++ ) */ + /* { */ + /* l <<= 4; */ + /* */ + /* if ( j & 0x80 ) l++; */ + /* if ( j & 0x40 ) l++; */ + /* */ + /* j = ( j << 2 ) & 0xFF; */ + /* } */ + /* printf( "0x%04X", l ); */ + /* } */ + /* */ + + static const short count_table[256] = + { + 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, + 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, + 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, + 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, + 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 + }; + +#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ + + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** PROFILES COMPUTATION **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Set_High_Precision */ + /* */ + /* <Description> */ + /* Set precision variables according to param flag. */ + /* */ + /* <Input> */ + /* High :: Set to True for high precision (typically for ppem < 24), */ + /* false otherwise. */ + /* */ + static void + Set_High_Precision( RAS_ARGS Int High ) + { + /* + * `precision_step' is used in `Bezier_Up' to decide when to split a + * given y-monotonous Bezier arc that crosses a scanline before + * approximating it as a straight segment. The default value of 32 (for + * low accuracy) corresponds to + * + * 32 / 64 == 0.5 pixels , + * + * while for the high accuracy case we have + * + * 256/ (1 << 12) = 0.0625 pixels . + * + * `precision_jitter' is an epsilon threshold used in + * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier + * decomposition (after all, we are working with approximations only); + * it avoids switching on additional pixels which would cause artifacts + * otherwise. + * + * The value of `precision_jitter' has been determined heuristically. + * + */ + + if ( High ) + { + ras.precision_bits = 12; + ras.precision_step = 256; + ras.precision_jitter = 30; + } + else + { + ras.precision_bits = 6; + ras.precision_step = 32; + ras.precision_jitter = 2; + } + + FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); + + ras.precision = 1 << ras.precision_bits; + ras.precision_half = ras.precision / 2; + ras.precision_shift = ras.precision_bits - Pixel_Bits; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* New_Profile */ + /* */ + /* <Description> */ + /* Create a new profile in the render pool. */ + /* */ + /* <Input> */ + /* aState :: The state/orientation of the new profile. */ + /* */ + /* overshoot :: Whether the profile's unrounded start position */ + /* differs by at least a half pixel. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ + /* profile. */ + /* */ + static Bool + New_Profile( RAS_ARGS TStates aState, + Bool overshoot ) + { + if ( !ras.fProfile ) + { + ras.cProfile = (PProfile)ras.top; + ras.fProfile = ras.cProfile; + ras.top += AlignProfileSize; + } + + if ( ras.top >= ras.maxBuff ) + { + ras.error = FT_THROW( Overflow ); + return FAILURE; + } + + ras.cProfile->flags = 0; + ras.cProfile->start = 0; + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + ras.cProfile->link = (PProfile)0; + ras.cProfile->next = (PProfile)0; + ras.cProfile->flags = ras.dropOutControl; + + switch ( aState ) + { + case Ascending_State: + ras.cProfile->flags |= Flow_Up; + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Bottom; + + FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile )); + break; + + case Descending_State: + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Top; + FT_TRACE6(( "New descending profile = %p\n", ras.cProfile )); + break; + + default: + FT_ERROR(( "New_Profile: invalid profile direction\n" )); + ras.error = FT_THROW( Invalid ); + return FAILURE; + } + + if ( !ras.gProfile ) + ras.gProfile = ras.cProfile; + + ras.state = aState; + ras.fresh = TRUE; + ras.joint = FALSE; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* End_Profile */ + /* */ + /* <Description> */ + /* Finalize the current profile. */ + /* */ + /* <Input> */ + /* overshoot :: Whether the profile's unrounded end position differs */ + /* by at least a half pixel. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ + /* */ + static Bool + End_Profile( RAS_ARGS Bool overshoot ) + { + Long h; + + + h = (Long)( ras.top - ras.cProfile->offset ); + + if ( h < 0 ) + { + FT_ERROR(( "End_Profile: negative height encountered\n" )); + ras.error = FT_THROW( Neg_Height ); + return FAILURE; + } + + if ( h > 0 ) + { + PProfile oldProfile; + + + FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n", + ras.cProfile, ras.cProfile->start, h )); + + ras.cProfile->height = h; + if ( overshoot ) + { + if ( ras.cProfile->flags & Flow_Up ) + ras.cProfile->flags |= Overshoot_Top; + else + ras.cProfile->flags |= Overshoot_Bottom; + } + + oldProfile = ras.cProfile; + ras.cProfile = (PProfile)ras.top; + + ras.top += AlignProfileSize; + + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + + oldProfile->next = ras.cProfile; + ras.num_Profs++; + } + + if ( ras.top >= ras.maxBuff ) + { + FT_TRACE1(( "overflow in End_Profile\n" )); + ras.error = FT_THROW( Overflow ); + return FAILURE; + } + + ras.joint = FALSE; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Insert_Y_Turn */ + /* */ + /* <Description> */ + /* Insert a salient into the sorted list placed on top of the render */ + /* pool. */ + /* */ + /* <Input> */ + /* New y scanline position. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow. */ + /* */ + static Bool + Insert_Y_Turn( RAS_ARGS Int y ) + { + PLong y_turns; + Int n; + + + n = ras.numTurns - 1; + y_turns = ras.sizeBuff - ras.numTurns; + + /* look for first y value that is <= */ + while ( n >= 0 && y < y_turns[n] ) + n--; + + /* if it is <, simply insert it, ignore if == */ + if ( n >= 0 && y > y_turns[n] ) + while ( n >= 0 ) + { + Int y2 = (Int)y_turns[n]; + + + y_turns[n] = y; + y = y2; + n--; + } + + if ( n < 0 ) + { + ras.maxBuff--; + if ( ras.maxBuff <= ras.top ) + { + ras.error = FT_THROW( Overflow ); + return FAILURE; + } + ras.numTurns++; + ras.sizeBuff[-ras.numTurns] = y; + } + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Finalize_Profile_Table */ + /* */ + /* <Description> */ + /* Adjust all links in the profiles list. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow. */ + /* */ + static Bool + Finalize_Profile_Table( RAS_ARG ) + { + UShort n; + PProfile p; + + + n = ras.num_Profs; + p = ras.fProfile; + + if ( n > 1 && p ) + { + while ( n > 0 ) + { + Int bottom, top; + + + if ( n > 1 ) + p->link = (PProfile)( p->offset + p->height ); + else + p->link = NULL; + + if ( p->flags & Flow_Up ) + { + bottom = (Int)p->start; + top = (Int)( p->start + p->height - 1 ); + } + else + { + bottom = (Int)( p->start - p->height + 1 ); + top = (Int)p->start; + p->start = bottom; + p->offset += p->height - 1; + } + + if ( Insert_Y_Turn( RAS_VARS bottom ) || + Insert_Y_Turn( RAS_VARS top + 1 ) ) + return FAILURE; + + p = p->link; + n--; + } + } + else + ras.fProfile = NULL; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Split_Conic */ + /* */ + /* <Description> */ + /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ + /* stack. */ + /* */ + /* <Input> */ + /* None (subdivided Bezier is taken from the top of the stack). */ + /* */ + /* <Note> */ + /* This routine is the `beef' of this component. It is _the_ inner */ + /* loop that should be optimized to hell to get the best performance. */ + /* */ + static void + Split_Conic( TPoint* base ) + { + Long a, b; + + + base[4].x = base[2].x; + b = base[1].x; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; + + base[4].y = base[2].y; + b = base[1].y; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; + + /* hand optimized. gcc doesn't seem to be too good at common */ + /* expression substitution and instruction scheduling ;-) */ + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Split_Cubic */ + /* */ + /* <Description> */ + /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ + /* Bezier stack. */ + /* */ + /* <Note> */ + /* This routine is the `beef' of the component. It is one of _the_ */ + /* inner loops that should be optimized like hell to get the best */ + /* performance. */ + /* */ + static void + Split_Cubic( TPoint* base ) + { + Long a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c + 1 ) >> 1; + base[5].x = b = ( base[3].x + d + 1 ) >> 1; + c = ( c + d + 1 ) >> 1; + base[2].x = a = ( a + c + 1 ) >> 1; + base[4].x = b = ( b + c + 1 ) >> 1; + base[3].x = ( a + b + 1 ) >> 1; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c + 1 ) >> 1; + base[5].y = b = ( base[3].y + d + 1 ) >> 1; + c = ( c + d + 1 ) >> 1; + base[2].y = a = ( a + c + 1 ) >> 1; + base[4].y = b = ( b + c + 1 ) >> 1; + base[3].y = ( a + b + 1 ) >> 1; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Line_Up */ + /* */ + /* <Description> */ + /* Compute the x-coordinates of an ascending line segment and store */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* x1 :: The x-coordinate of the segment's start point. */ + /* */ + /* y1 :: The y-coordinate of the segment's start point. */ + /* */ + /* x2 :: The x-coordinate of the segment's end point. */ + /* */ + /* y2 :: The y-coordinate of the segment's end point. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Line_Up( RAS_ARGS Long x1, + Long y1, + Long x2, + Long y2, + Long miny, + Long maxy ) + { + Long Dx, Dy; + Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ + Long Ix, Rx, Ax; + + PLong top; + + + Dx = x2 - x1; + Dy = y2 - y1; + + if ( Dy <= 0 || y2 < miny || y1 > maxy ) + return SUCCESS; + + if ( y1 < miny ) + { + /* Take care: miny-y1 can be a very large value; we use */ + /* a slow MulDiv function to avoid clipping bugs */ + x1 += SMulDiv( Dx, miny - y1, Dy ); + e1 = (Int)TRUNC( miny ); + f1 = 0; + } + else + { + e1 = (Int)TRUNC( y1 ); + f1 = (Int)FRAC( y1 ); + } + + if ( y2 > maxy ) + { + /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ + e2 = (Int)TRUNC( maxy ); + f2 = 0; + } + else + { + e2 = (Int)TRUNC( y2 ); + f2 = (Int)FRAC( y2 ); + } + + if ( f1 > 0 ) + { + if ( e1 == e2 ) + return SUCCESS; + else + { + x1 += SMulDiv( Dx, ras.precision - f1, Dy ); + e1 += 1; + } + } + else + if ( ras.joint ) + { + ras.top--; + ras.joint = FALSE; + } + + ras.joint = (char)( f2 == 0 ); + + if ( ras.fresh ) + { + ras.cProfile->start = e1; + ras.fresh = FALSE; + } + + size = e2 - e1 + 1; + if ( ras.top + size >= ras.maxBuff ) + { + ras.error = FT_THROW( Overflow ); + return FAILURE; + } + + if ( Dx > 0 ) + { + Ix = SMulDiv_No_Round( ras.precision, Dx, Dy ); + Rx = ( ras.precision * Dx ) % Dy; + Dx = 1; + } + else + { + Ix = -SMulDiv_No_Round( ras.precision, -Dx, Dy ); + Rx = ( ras.precision * -Dx ) % Dy; + Dx = -1; + } + + Ax = -Dy; + top = ras.top; + + while ( size > 0 ) + { + *top++ = x1; + + x1 += Ix; + Ax += Rx; + if ( Ax >= 0 ) + { + Ax -= Dy; + x1 += Dx; + } + size--; + } + + ras.top = top; + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Line_Down */ + /* */ + /* <Description> */ + /* Compute the x-coordinates of an descending line segment and store */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* x1 :: The x-coordinate of the segment's start point. */ + /* */ + /* y1 :: The y-coordinate of the segment's start point. */ + /* */ + /* x2 :: The x-coordinate of the segment's end point. */ + /* */ + /* y2 :: The y-coordinate of the segment's end point. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Line_Down( RAS_ARGS Long x1, + Long y1, + Long x2, + Long y2, + Long miny, + Long maxy ) + { + Bool result, fresh; + + + fresh = ras.fresh; + + result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); + + if ( fresh && !ras.fresh ) + ras.cProfile->start = -ras.cProfile->start; + + return result; + } + + + /* A function type describing the functions used to split Bezier arcs */ + typedef void (*TSplitter)( TPoint* base ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Bezier_Up */ + /* */ + /* <Description> */ + /* Compute the x-coordinates of an ascending Bezier arc and store */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* degree :: The degree of the Bezier arc (either 2 or 3). */ + /* */ + /* splitter :: The function to split Bezier arcs. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Bezier_Up( RAS_ARGS Int degree, + TSplitter splitter, + Long miny, + Long maxy ) + { + Long y1, y2, e, e2, e0; + Short f1; + + TPoint* arc; + TPoint* start_arc; + + PLong top; + + + arc = ras.arc; + y1 = arc[degree].y; + y2 = arc[0].y; + top = ras.top; + + if ( y2 < miny || y1 > maxy ) + goto Fin; + + e2 = FLOOR( y2 ); + + if ( e2 > maxy ) + e2 = maxy; + + e0 = miny; + + if ( y1 < miny ) + e = miny; + else + { + e = CEILING( y1 ); + f1 = (Short)( FRAC( y1 ) ); + e0 = e; + + if ( f1 == 0 ) + { + if ( ras.joint ) + { + top--; + ras.joint = FALSE; + } + + *top++ = arc[degree].x; + + e += ras.precision; + } + } + + if ( ras.fresh ) + { + ras.cProfile->start = TRUNC( e0 ); + ras.fresh = FALSE; + } + + if ( e2 < e ) + goto Fin; + + if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) + { + ras.top = top; + ras.error = FT_THROW( Overflow ); + return FAILURE; + } + + start_arc = arc; + + while ( arc >= start_arc && e <= e2 ) + { + ras.joint = FALSE; + + y2 = arc[0].y; + + if ( y2 > e ) + { + y1 = arc[degree].y; + if ( y2 - y1 >= ras.precision_step ) + { + splitter( arc ); + arc += degree; + } + else + { + *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, + e - y1, y2 - y1 ); + arc -= degree; + e += ras.precision; + } + } + else + { + if ( y2 == e ) + { + ras.joint = TRUE; + *top++ = arc[0].x; + + e += ras.precision; + } + arc -= degree; + } + } + + Fin: + ras.top = top; + ras.arc -= degree; + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Bezier_Down */ + /* */ + /* <Description> */ + /* Compute the x-coordinates of an descending Bezier arc and store */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* degree :: The degree of the Bezier arc (either 2 or 3). */ + /* */ + /* splitter :: The function to split Bezier arcs. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Bezier_Down( RAS_ARGS Int degree, + TSplitter splitter, + Long miny, + Long maxy ) + { + TPoint* arc = ras.arc; + Bool result, fresh; + + + arc[0].y = -arc[0].y; + arc[1].y = -arc[1].y; + arc[2].y = -arc[2].y; + if ( degree > 2 ) + arc[3].y = -arc[3].y; + + fresh = ras.fresh; + + result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); + + if ( fresh && !ras.fresh ) + ras.cProfile->start = -ras.cProfile->start; + + arc[0].y = -arc[0].y; + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Line_To */ + /* */ + /* <Description> */ + /* Inject a new line segment and adjust the Profiles list. */ + /* */ + /* <Input> */ + /* x :: The x-coordinate of the segment's end point (its start point */ + /* is stored in `lastX'). */ + /* */ + /* y :: The y-coordinate of the segment's end point (its start point */ + /* is stored in `lastY'). */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ + /* profile. */ + /* */ + static Bool + Line_To( RAS_ARGS Long x, + Long y ) + { + /* First, detect a change of direction */ + + switch ( ras.state ) + { + case Unknown_State: + if ( y > ras.lastY ) + { + if ( New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) + return FAILURE; + } + else + { + if ( y < ras.lastY ) + if ( New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) + return FAILURE; + } + break; + + case Ascending_State: + if ( y < ras.lastY ) + { + if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) + return FAILURE; + } + break; + + case Descending_State: + if ( y > ras.lastY ) + { + if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) + return FAILURE; + } + break; + + default: + ; + } + + /* Then compute the lines */ + + switch ( ras.state ) + { + case Ascending_State: + if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + case Descending_State: + if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + default: + ; + } + + ras.lastX = x; + ras.lastY = y; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Conic_To */ + /* */ + /* <Description> */ + /* Inject a new conic arc and adjust the profile list. */ + /* */ + /* <Input> */ + /* cx :: The x-coordinate of the arc's new control point. */ + /* */ + /* cy :: The y-coordinate of the arc's new control point. */ + /* */ + /* x :: The x-coordinate of the arc's end point (its start point is */ + /* stored in `lastX'). */ + /* */ + /* y :: The y-coordinate of the arc's end point (its start point is */ + /* stored in `lastY'). */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ + /* profile. */ + /* */ + static Bool + Conic_To( RAS_ARGS Long cx, + Long cy, + Long x, + Long y ) + { + Long y1, y2, y3, x3, ymin, ymax; + TStates state_bez; + + + ras.arc = ras.arcs; + ras.arc[2].x = ras.lastX; + ras.arc[2].y = ras.lastY; + ras.arc[1].x = cx; + ras.arc[1].y = cy; + ras.arc[0].x = x; + ras.arc[0].y = y; + + do + { + y1 = ras.arc[2].y; + y2 = ras.arc[1].y; + y3 = ras.arc[0].y; + x3 = ras.arc[0].x; + + /* first, categorize the Bezier arc */ + + if ( y1 <= y3 ) + { + ymin = y1; + ymax = y3; + } + else + { + ymin = y3; + ymax = y1; + } + + if ( y2 < ymin || y2 > ymax ) + { + /* this arc has no given direction, split it! */ + Split_Conic( ras.arc ); + ras.arc += 2; + } + else if ( y1 == y3 ) + { + /* this arc is flat, ignore it and pop it from the Bezier stack */ + ras.arc -= 2; + } + else + { + /* the arc is y-monotonous, either ascending or descending */ + /* detect a change of direction */ + state_bez = y1 < y3 ? Ascending_State : Descending_State; + if ( ras.state != state_bez ) + { + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) + goto Fail; + + /* create a new profile */ + if ( New_Profile( RAS_VARS state_bez, o ) ) + goto Fail; + } + + /* now call the appropriate routine */ + if ( state_bez == Ascending_State ) + { + if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) + goto Fail; + } + else + if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) + goto Fail; + } + + } while ( ras.arc >= ras.arcs ); + + ras.lastX = x3; + ras.lastY = y3; + + return SUCCESS; + + Fail: + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Cubic_To */ + /* */ + /* <Description> */ + /* Inject a new cubic arc and adjust the profile list. */ + /* */ + /* <Input> */ + /* cx1 :: The x-coordinate of the arc's first new control point. */ + /* */ + /* cy1 :: The y-coordinate of the arc's first new control point. */ + /* */ + /* cx2 :: The x-coordinate of the arc's second new control point. */ + /* */ + /* cy2 :: The y-coordinate of the arc's second new control point. */ + /* */ + /* x :: The x-coordinate of the arc's end point (its start point is */ + /* stored in `lastX'). */ + /* */ + /* y :: The y-coordinate of the arc's end point (its start point is */ + /* stored in `lastY'). */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ + /* profile. */ + /* */ + static Bool + Cubic_To( RAS_ARGS Long cx1, + Long cy1, + Long cx2, + Long cy2, + Long x, + Long y ) + { + Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; + TStates state_bez; + + + ras.arc = ras.arcs; + ras.arc[3].x = ras.lastX; + ras.arc[3].y = ras.lastY; + ras.arc[2].x = cx1; + ras.arc[2].y = cy1; + ras.arc[1].x = cx2; + ras.arc[1].y = cy2; + ras.arc[0].x = x; + ras.arc[0].y = y; + + do + { + y1 = ras.arc[3].y; + y2 = ras.arc[2].y; + y3 = ras.arc[1].y; + y4 = ras.arc[0].y; + x4 = ras.arc[0].x; + + /* first, categorize the Bezier arc */ + + if ( y1 <= y4 ) + { + ymin1 = y1; + ymax1 = y4; + } + else + { + ymin1 = y4; + ymax1 = y1; + } + + if ( y2 <= y3 ) + { + ymin2 = y2; + ymax2 = y3; + } + else + { + ymin2 = y3; + ymax2 = y2; + } + + if ( ymin2 < ymin1 || ymax2 > ymax1 ) + { + /* this arc has no given direction, split it! */ + Split_Cubic( ras.arc ); + ras.arc += 3; + } + else if ( y1 == y4 ) + { + /* this arc is flat, ignore it and pop it from the Bezier stack */ + ras.arc -= 3; + } + else + { + state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; + + /* detect a change of direction */ + if ( ras.state != state_bez ) + { + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) + goto Fail; + + if ( New_Profile( RAS_VARS state_bez, o ) ) + goto Fail; + } + + /* compute intersections */ + if ( state_bez == Ascending_State ) + { + if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) + goto Fail; + } + else + if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) + goto Fail; + } + + } while ( ras.arc >= ras.arcs ); + + ras.lastX = x4; + ras.lastY = y4; + + return SUCCESS; + + Fail: + return FAILURE; + } + + +#undef SWAP_ +#define SWAP_( x, y ) do \ + { \ + Long swap = x; \ + \ + \ + x = y; \ + y = swap; \ + } while ( 0 ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Decompose_Curve */ + /* */ + /* <Description> */ + /* Scan the outline arrays in order to emit individual segments and */ + /* Beziers by calling Line_To() and Bezier_To(). It handles all */ + /* weird cases, like when the first point is off the curve, or when */ + /* there are simply no `on' points in the contour! */ + /* */ + /* <Input> */ + /* first :: The index of the first point in the contour. */ + /* */ + /* last :: The index of the last point in the contour. */ + /* */ + /* flipped :: If set, flip the direction of the curve. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on error. */ + /* */ + static Bool + Decompose_Curve( RAS_ARGS UShort first, + UShort last, + int flipped ) + { + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* points; + FT_Vector* point; + FT_Vector* limit; + char* tags; + + unsigned tag; /* current point's state */ + + + points = ras.outline.points; + limit = points + last; + + v_start.x = SCALED( points[first].x ); + v_start.y = SCALED( points[first].y ); + v_last.x = SCALED( points[last].x ); + v_last.y = SCALED( points[last].y ); + + if ( flipped ) + { + SWAP_( v_start.x, v_start.y ); + SWAP_( v_last.x, v_last.y ); + } + + v_control = v_start; + + point = points + first; + tags = ras.outline.tags + first; + + /* set scan mode if necessary */ + if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) + ras.dropOutControl = (Byte)tags[0] >> 5; + + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + ras.lastX = v_start.x; + ras.lastY = v_start.y; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + Long x, y; + + + x = SCALED( point->x ); + y = SCALED( point->y ); + if ( flipped ) + SWAP_( x, y ); + + if ( Line_To( RAS_VARS x, y ) ) + goto Fail; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point[0].x ); + v_control.y = SCALED( point[0].y ); + + if ( flipped ) + SWAP_( v_control.x, v_control.y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector v_middle; + Long x, y; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + x = SCALED( point[0].x ); + y = SCALED( point[0].y ); + + if ( flipped ) + SWAP_( x, y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) + goto Fail; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + x ) / 2; + v_middle.y = ( v_control.y + y ) / 2; + + if ( Conic_To( RAS_VARS v_control.x, v_control.y, + v_middle.x, v_middle.y ) ) + goto Fail; + + v_control.x = x; + v_control.y = y; + + goto Do_Conic; + } + + if ( Conic_To( RAS_VARS v_control.x, v_control.y, + v_start.x, v_start.y ) ) + goto Fail; + + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + Long x1, y1, x2, y2, x3, y3; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + x1 = SCALED( point[-2].x ); + y1 = SCALED( point[-2].y ); + x2 = SCALED( point[-1].x ); + y2 = SCALED( point[-1].y ); + + if ( flipped ) + { + SWAP_( x1, y1 ); + SWAP_( x2, y2 ); + } + + if ( point <= limit ) + { + x3 = SCALED( point[0].x ); + y3 = SCALED( point[0].y ); + + if ( flipped ) + SWAP_( x3, y3 ); + + if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) + goto Fail; + continue; + } + + if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) + goto Fail; + goto Close; + } + } + } + + /* close the contour with a line segment */ + if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) + goto Fail; + + Close: + return SUCCESS; + + Invalid_Outline: + ras.error = FT_THROW( Invalid ); + + Fail: + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Convert_Glyph */ + /* */ + /* <Description> */ + /* Convert a glyph into a series of segments and arcs and make a */ + /* profiles list with them. */ + /* */ + /* <Input> */ + /* flipped :: If set, flip the direction of curve. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE if any error was encountered during */ + /* rendering. */ + /* */ + static Bool + Convert_Glyph( RAS_ARGS int flipped ) + { + int i; + unsigned start; + + + ras.fProfile = NULL; + ras.joint = FALSE; + ras.fresh = FALSE; + + ras.maxBuff = ras.sizeBuff - AlignProfileSize; + + ras.numTurns = 0; + + ras.cProfile = (PProfile)ras.top; + ras.cProfile->offset = ras.top; + ras.num_Profs = 0; + + start = 0; + + for ( i = 0; i < ras.outline.n_contours; i++ ) + { + PProfile lastProfile; + Bool o; + + + ras.state = Unknown_State; + ras.gProfile = NULL; + + if ( Decompose_Curve( RAS_VARS (unsigned short)start, + ras.outline.contours[i], + flipped ) ) + return FAILURE; + + start = ras.outline.contours[i] + 1; + + /* we must now check whether the extreme arcs join or not */ + if ( FRAC( ras.lastY ) == 0 && + ras.lastY >= ras.minY && + ras.lastY <= ras.maxY ) + if ( ras.gProfile && + ( ras.gProfile->flags & Flow_Up ) == + ( ras.cProfile->flags & Flow_Up ) ) + ras.top--; + /* Note that ras.gProfile can be nil if the contour was too small */ + /* to be drawn. */ + + lastProfile = ras.cProfile; + if ( ras.cProfile->flags & Flow_Up ) + o = IS_TOP_OVERSHOOT( ras.lastY ); + else + o = IS_BOTTOM_OVERSHOOT( ras.lastY ); + if ( End_Profile( RAS_VARS o ) ) + return FAILURE; + + /* close the `next profile in contour' linked list */ + if ( ras.gProfile ) + lastProfile->next = ras.gProfile; + } + + if ( Finalize_Profile_Table( RAS_VAR ) ) + return FAILURE; + + return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** SCAN-LINE SWEEPS AND DRAWING **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Init_Linked */ + /* */ + /* Initializes an empty linked list. */ + /* */ + static void + Init_Linked( TProfileList* l ) + { + *l = NULL; + } + + + /*************************************************************************/ + /* */ + /* InsNew */ + /* */ + /* Inserts a new profile in a linked list. */ + /* */ + static void + InsNew( PProfileList list, + PProfile profile ) + { + PProfile *old, current; + Long x; + + + old = list; + current = *old; + x = profile->X; + + while ( current ) + { + if ( x < current->X ) + break; + old = ¤t->link; + current = *old; + } + + profile->link = current; + *old = profile; + } + + + /*************************************************************************/ + /* */ + /* DelOld */ + /* */ + /* Removes an old profile from a linked list. */ + /* */ + static void + DelOld( PProfileList list, + PProfile profile ) + { + PProfile *old, current; + + + old = list; + current = *old; + + while ( current ) + { + if ( current == profile ) + { + *old = current->link; + return; + } + + old = ¤t->link; + current = *old; + } + + /* we should never get there, unless the profile was not part of */ + /* the list. */ + } + + + /*************************************************************************/ + /* */ + /* Sort */ + /* */ + /* Sorts a trace list. In 95%, the list is already sorted. We need */ + /* an algorithm which is fast in this case. Bubble sort is enough */ + /* and simple. */ + /* */ + static void + Sort( PProfileList list ) + { + PProfile *old, current, next; + + + /* First, set the new X coordinate of each profile */ + current = *list; + while ( current ) + { + current->X = *current->offset; + current->offset += current->flags & Flow_Up ? 1 : -1; + current->height--; + current = current->link; + } + + /* Then sort them */ + old = list; + current = *old; + + if ( !current ) + return; + + next = current->link; + + while ( next ) + { + if ( current->X <= next->X ) + { + old = ¤t->link; + current = *old; + + if ( !current ) + return; + } + else + { + *old = next; + current->link = next->link; + next->link = current; + + old = list; + current = *old; + } + + next = current->link; + } + } + + + /*************************************************************************/ + /* */ + /* Vertical Sweep Procedure Set */ + /* */ + /* These four routines are used during the vertical black/white sweep */ + /* phase by the generic Draw_Sweep() function. */ + /* */ + /*************************************************************************/ + + static void + Vertical_Sweep_Init( RAS_ARGS Short* min, + Short* max ) + { + Long pitch = ras.target.pitch; + + FT_UNUSED( max ); + + + ras.traceIncr = (Short)-pitch; + ras.traceOfs = -*min * pitch; + if ( pitch > 0 ) + ras.traceOfs += ( ras.target.rows - 1 ) * pitch; + + ras.gray_min_x = 0; + ras.gray_max_x = 0; + } + + + static void + Vertical_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + Byte* target; + + FT_UNUSED( y ); + FT_UNUSED( left ); + FT_UNUSED( right ); + + + /* Drop-out control */ + + e1 = TRUNC( CEILING( x1 ) ); + + if ( x2 - x1 - ras.precision <= ras.precision_jitter ) + e2 = e1; + else + e2 = TRUNC( FLOOR( x2 ) ); + + if ( e2 >= 0 && e1 < ras.bWidth ) + { + int c1, c2; + Byte f1, f2; + + + if ( e1 < 0 ) + e1 = 0; + if ( e2 >= ras.bWidth ) + e2 = ras.bWidth - 1; + + c1 = (Short)( e1 >> 3 ); + c2 = (Short)( e2 >> 3 ); + + f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); + f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); + + if ( ras.gray_min_x > c1 ) + ras.gray_min_x = (short)c1; + if ( ras.gray_max_x < c2 ) + ras.gray_max_x = (short)c2; + + target = ras.bTarget + ras.traceOfs + c1; + c2 -= c1; + + if ( c2 > 0 ) + { + target[0] |= f1; + + /* memset() is slower than the following code on many platforms. */ + /* This is due to the fact that, in the vast majority of cases, */ + /* the span length in bytes is relatively small. */ + c2--; + while ( c2 > 0 ) + { + *(++target) = 0xFF; + c2--; + } + target[1] |= f2; + } + else + *target |= ( f1 & f2 ); + } + } + + + static void + Vertical_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2, pxl; + Short c1, f1; + + + /* Drop-out control */ + + /* e2 x2 x1 e1 */ + /* */ + /* ^ | */ + /* | | */ + /* +-------------+---------------------+------------+ */ + /* | | */ + /* | v */ + /* */ + /* pixel contour contour pixel */ + /* center center */ + + /* drop-out mode scan conversion rules (as defined in OpenType) */ + /* --------------------------------------------------------------- */ + /* 0 1, 2, 3 */ + /* 1 1, 2, 4 */ + /* 2 1, 2 */ + /* 3 same as mode 2 */ + /* 4 1, 2, 5 */ + /* 5 1, 2, 6 */ + /* 6, 7 same as mode 2 */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + pxl = e1; + + if ( e1 > e2 ) + { + Int dropOutControl = left->flags & 7; + + + if ( e1 == e2 + ras.precision ) + { + switch ( dropOutControl ) + { + case 0: /* simple drop-outs including stubs */ + pxl = e2; + break; + + case 4: /* smart drop-outs including stubs */ + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + + /* Drop-out Control Rules #4 and #6 */ + + /* The specification neither provides an exact definition */ + /* of a `stub' nor gives exact rules to exclude them. */ + /* */ + /* Here the constraints we use to recognize a stub. */ + /* */ + /* upper stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Right is the successor of P_Left in that contour */ + /* - y is the top of P_Left and P_Right */ + /* */ + /* lower stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Left is the successor of P_Right in that contour */ + /* - y is the bottom of P_Left */ + /* */ + /* We draw a stub if the following constraints are met. */ + /* */ + /* - for an upper or lower stub, there is top or bottom */ + /* overshoot, respectively */ + /* - the covered interval is greater or equal to a half */ + /* pixel */ + + /* upper stub test */ + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) + return; + + /* lower stub test */ + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) + return; + + if ( dropOutControl == 1 ) + pxl = e2; + else + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ + } + + /* undocumented but confirmed: If the drop-out would result in a */ + /* pixel outside of the bounding box, use the pixel inside of the */ + /* bounding box instead */ + if ( pxl < 0 ) + pxl = e1; + else if ( TRUNC( pxl ) >= ras.bWidth ) + pxl = e2; + + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; + + e1 = TRUNC( e1 ); + + c1 = (Short)( e1 >> 3 ); + f1 = (Short)( e1 & 7 ); + + if ( e1 >= 0 && e1 < ras.bWidth && + ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) + return; + } + else + return; + } + + e1 = TRUNC( pxl ); + + if ( e1 >= 0 && e1 < ras.bWidth ) + { + c1 = (Short)( e1 >> 3 ); + f1 = (Short)( e1 & 7 ); + + if ( ras.gray_min_x > c1 ) + ras.gray_min_x = c1; + if ( ras.gray_max_x < c1 ) + ras.gray_max_x = c1; + + ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); + } + } + + + static void + Vertical_Sweep_Step( RAS_ARG ) + { + ras.traceOfs += ras.traceIncr; + } + + + /***********************************************************************/ + /* */ + /* Horizontal Sweep Procedure Set */ + /* */ + /* These four routines are used during the horizontal black/white */ + /* sweep phase by the generic Draw_Sweep() function. */ + /* */ + /***********************************************************************/ + + static void + Horizontal_Sweep_Init( RAS_ARGS Short* min, + Short* max ) + { + /* nothing, really */ + FT_UNUSED_RASTER; + FT_UNUSED( min ); + FT_UNUSED( max ); + } + + + static void + Horizontal_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + FT_UNUSED( left ); + FT_UNUSED( right ); + + + if ( x2 - x1 < ras.precision ) + { + Long e1, e2; + + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 == e2 ) + { + Byte f1; + PByte bits; + + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + + e1 = TRUNC( e1 ); + + if ( e1 >= 0 && e1 < ras.target.rows ) + { + PByte p; + + + p = bits - e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + p += ( ras.target.rows - 1 ) * ras.target.pitch; + + p[0] |= f1; + } + } + } + } + + + static void + Horizontal_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2, pxl; + PByte bits; + Byte f1; + + + /* During the horizontal sweep, we only take care of drop-outs */ + + /* e1 + <-- pixel center */ + /* | */ + /* x1 ---+--> <-- contour */ + /* | */ + /* | */ + /* x2 <--+--- <-- contour */ + /* | */ + /* | */ + /* e2 + <-- pixel center */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + pxl = e1; + + if ( e1 > e2 ) + { + Int dropOutControl = left->flags & 7; + + + if ( e1 == e2 + ras.precision ) + { + switch ( dropOutControl ) + { + case 0: /* simple drop-outs including stubs */ + pxl = e2; + break; + + case 4: /* smart drop-outs including stubs */ + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ + + /* rightmost stub test */ + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) + return; + + /* leftmost stub test */ + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) + return; + + if ( dropOutControl == 1 ) + pxl = e2; + else + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ + } + + /* undocumented but confirmed: If the drop-out would result in a */ + /* pixel outside of the bounding box, use the pixel inside of the */ + /* bounding box instead */ + if ( pxl < 0 ) + pxl = e1; + else if ( TRUNC( pxl ) >= ras.target.rows ) + pxl = e2; + + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; + + e1 = TRUNC( e1 ); + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; + + if ( e1 >= 0 && + e1 < ras.target.rows && + *bits & f1 ) + return; + } + else + return; + } + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + + e1 = TRUNC( pxl ); + + if ( e1 >= 0 && e1 < ras.target.rows ) + { + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; + + bits[0] |= f1; + } + } + + + static void + Horizontal_Sweep_Step( RAS_ARG ) + { + /* Nothing, really */ + FT_UNUSED_RASTER; + } + + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + + /*************************************************************************/ + /* */ + /* Vertical Gray Sweep Procedure Set */ + /* */ + /* These two routines are used during the vertical gray-levels sweep */ + /* phase by the generic Draw_Sweep() function. */ + /* */ + /* NOTES */ + /* */ + /* - The target pixmap's width *must* be a multiple of 4. */ + /* */ + /* - You have to use the function Vertical_Sweep_Span() for the gray */ + /* span call. */ + /* */ + /*************************************************************************/ + + static void + Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, + Short* max ) + { + Long pitch, byte_len; + + + *min = *min & -2; + *max = ( *max + 3 ) & -2; + + ras.traceOfs = 0; + pitch = ras.target.pitch; + byte_len = -pitch; + ras.traceIncr = (Short)byte_len; + ras.traceG = ( *min / 2 ) * byte_len; + + if ( pitch > 0 ) + { + ras.traceG += ( ras.target.rows - 1 ) * pitch; + byte_len = -byte_len; + } + + ras.gray_min_x = (Short)byte_len; + ras.gray_max_x = -(Short)byte_len; + } + + + static void + Vertical_Gray_Sweep_Step( RAS_ARG ) + { + short* count = (short*)count_table; + Byte* grays; + + + ras.traceOfs += ras.gray_width; + + if ( ras.traceOfs > ras.gray_width ) + { + PByte pix; + + + pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; + grays = ras.grays; + + if ( ras.gray_max_x >= 0 ) + { + Long last_pixel = ras.target.width - 1; + Int last_cell = last_pixel >> 2; + Int last_bit = last_pixel & 3; + Bool over = 0; + + Int c1, c2; + PByte bit, bit2; + + + if ( ras.gray_max_x >= last_cell && last_bit != 3 ) + { + ras.gray_max_x = last_cell - 1; + over = 1; + } + + if ( ras.gray_min_x < 0 ) + ras.gray_min_x = 0; + + bit = ras.bTarget + ras.gray_min_x; + bit2 = bit + ras.gray_width; + + c1 = ras.gray_max_x - ras.gray_min_x; + + while ( c1 >= 0 ) + { + c2 = count[*bit] + count[*bit2]; + + if ( c2 ) + { + pix[0] = grays[(c2 >> 12) & 0x000F]; + pix[1] = grays[(c2 >> 8 ) & 0x000F]; + pix[2] = grays[(c2 >> 4 ) & 0x000F]; + pix[3] = grays[ c2 & 0x000F]; + + *bit = 0; + *bit2 = 0; + } + + bit++; + bit2++; + pix += 4; + c1--; + } + + if ( over ) + { + c2 = count[*bit] + count[*bit2]; + if ( c2 ) + { + switch ( last_bit ) + { + case 2: + pix[2] = grays[(c2 >> 4 ) & 0x000F]; + case 1: + pix[1] = grays[(c2 >> 8 ) & 0x000F]; + default: + pix[0] = grays[(c2 >> 12) & 0x000F]; + } + + *bit = 0; + *bit2 = 0; + } + } + } + + ras.traceOfs = 0; + ras.traceG += ras.traceIncr; + + ras.gray_min_x = 32000; + ras.gray_max_x = -32000; + } + } + + + static void + Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + /* nothing, really */ + FT_UNUSED_RASTER; + FT_UNUSED( y ); + FT_UNUSED( x1 ); + FT_UNUSED( x2 ); + FT_UNUSED( left ); + FT_UNUSED( right ); + } + + + static void + Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte pixel; + + + /* During the horizontal sweep, we only take care of drop-outs */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 > e2 ) + { + Int dropOutControl = left->flags & 7; + + + if ( e1 == e2 + ras.precision ) + { + switch ( dropOutControl ) + { + case 0: /* simple drop-outs including stubs */ + e1 = e2; + break; + + case 4: /* smart drop-outs including stubs */ + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ + + /* rightmost stub test */ + if ( left->next == right && left->height <= 0 ) + return; + + /* leftmost stub test */ + if ( right->next == left && left->start == y ) + return; + + if ( dropOutControl == 1 ) + e1 = e2; + else + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + + break; + + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ + } + } + else + return; + } + + if ( e1 >= 0 ) + { + Byte color; + + + if ( x2 - x1 >= ras.precision_half ) + color = ras.grays[2]; + else + color = ras.grays[1]; + + e1 = TRUNC( e1 ) / 2; + if ( e1 < ras.target.rows ) + { + pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; + if ( ras.target.pitch > 0 ) + pixel += ( ras.target.rows - 1 ) * ras.target.pitch; + + if ( pixel[0] == ras.grays[0] ) + pixel[0] = color; + } + } + } + + +#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ + + + /*************************************************************************/ + /* */ + /* Generic Sweep Drawing routine */ + /* */ + /*************************************************************************/ + + static Bool + Draw_Sweep( RAS_ARG ) + { + Short y, y_change, y_height; + + PProfile P, Q, P_Left, P_Right; + + Short min_Y, max_Y, top, bottom, dropouts; + + Long x1, x2, xs, e1, e2; + + TProfileList waiting; + TProfileList draw_left, draw_right; + + + /* initialize empty linked lists */ + + Init_Linked( &waiting ); + + Init_Linked( &draw_left ); + Init_Linked( &draw_right ); + + /* first, compute min and max Y */ + + P = ras.fProfile; + max_Y = (Short)TRUNC( ras.minY ); + min_Y = (Short)TRUNC( ras.maxY ); + + while ( P ) + { + Q = P->link; + + bottom = (Short)P->start; + top = (Short)( P->start + P->height - 1 ); + + if ( min_Y > bottom ) + min_Y = bottom; + if ( max_Y < top ) + max_Y = top; + + P->X = 0; + InsNew( &waiting, P ); + + P = Q; + } + + /* check the Y-turns */ + if ( ras.numTurns == 0 ) + { + ras.error = FT_THROW( Invalid ); + return FAILURE; + } + + /* now initialize the sweep */ + + ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); + + /* then compute the distance of each profile from min_Y */ + + P = waiting; + + while ( P ) + { + P->countL = (UShort)( P->start - min_Y ); + P = P->link; + } + + /* let's go */ + + y = min_Y; + y_height = 0; + + if ( ras.numTurns > 0 && + ras.sizeBuff[-ras.numTurns] == min_Y ) + ras.numTurns--; + + while ( ras.numTurns > 0 ) + { + /* check waiting list for new activations */ + + P = waiting; + + while ( P ) + { + Q = P->link; + P->countL -= y_height; + if ( P->countL == 0 ) + { + DelOld( &waiting, P ); + + if ( P->flags & Flow_Up ) + InsNew( &draw_left, P ); + else + InsNew( &draw_right, P ); + } + + P = Q; + } + + /* sort the drawing lists */ + + Sort( &draw_left ); + Sort( &draw_right ); + + y_change = (Short)ras.sizeBuff[-ras.numTurns--]; + y_height = (Short)( y_change - y ); + + while ( y < y_change ) + { + /* let's trace */ + + dropouts = 0; + + P_Left = draw_left; + P_Right = draw_right; + + while ( P_Left ) + { + x1 = P_Left ->X; + x2 = P_Right->X; + + if ( x1 > x2 ) + { + xs = x1; + x1 = x2; + x2 = xs; + } + + e1 = FLOOR( x1 ); + e2 = CEILING( x2 ); + + if ( x2 - x1 <= ras.precision && + e1 != x1 && e2 != x2 ) + { + if ( e1 > e2 || e2 == e1 + ras.precision ) + { + Int dropOutControl = P_Left->flags & 7; + + + if ( dropOutControl != 2 ) + { + /* a drop-out was detected */ + + P_Left ->X = x1; + P_Right->X = x2; + + /* mark profile for drop-out processing */ + P_Left->countL = 1; + dropouts++; + } + + goto Skip_To_Next; + } + } + + ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); + + Skip_To_Next: + + P_Left = P_Left->link; + P_Right = P_Right->link; + } + + /* handle drop-outs _after_ the span drawing -- */ + /* drop-out processing has been moved out of the loop */ + /* for performance tuning */ + if ( dropouts > 0 ) + goto Scan_DropOuts; + + Next_Line: + + ras.Proc_Sweep_Step( RAS_VAR ); + + y++; + + if ( y < y_change ) + { + Sort( &draw_left ); + Sort( &draw_right ); + } + } + + /* now finalize the profiles that need it */ + + P = draw_left; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_left, P ); + P = Q; + } + + P = draw_right; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_right, P ); + P = Q; + } + } + + /* for gray-scaling, flush the bitmap scanline cache */ + while ( y <= max_Y ) + { + ras.Proc_Sweep_Step( RAS_VAR ); + y++; + } + + return SUCCESS; + + Scan_DropOuts: + + P_Left = draw_left; + P_Right = draw_right; + + while ( P_Left ) + { + if ( P_Left->countL ) + { + P_Left->countL = 0; +#if 0 + dropouts--; /* -- this is useful when debugging only */ +#endif + ras.Proc_Sweep_Drop( RAS_VARS y, + P_Left->X, + P_Right->X, + P_Left, + P_Right ); + } + + P_Left = P_Left->link; + P_Right = P_Right->link; + } + + goto Next_Line; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Render_Single_Pass */ + /* */ + /* <Description> */ + /* Perform one sweep with sub-banding. */ + /* */ + /* <Input> */ + /* flipped :: If set, flip the direction of the outline. */ + /* */ + /* <Return> */ + /* Renderer error code. */ + /* */ + static int + Render_Single_Pass( RAS_ARGS Bool flipped ) + { + Short i, j, k; + + + while ( ras.band_top >= 0 ) + { + ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; + ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; + + ras.top = ras.buff; + + ras.error = Raster_Err_None; + + if ( Convert_Glyph( RAS_VARS flipped ) ) + { + if ( ras.error != Raster_Err_Overflow ) + return FAILURE; + + ras.error = Raster_Err_None; + + /* sub-banding */ + +#ifdef DEBUG_RASTER + ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); +#endif + + i = ras.band_stack[ras.band_top].y_min; + j = ras.band_stack[ras.band_top].y_max; + + k = (Short)( ( i + j ) / 2 ); + + if ( ras.band_top >= 7 || k < i ) + { + ras.band_top = 0; + ras.error = FT_THROW( Invalid ); + + return ras.error; + } + + ras.band_stack[ras.band_top + 1].y_min = k; + ras.band_stack[ras.band_top + 1].y_max = j; + + ras.band_stack[ras.band_top].y_max = (Short)( k - 1 ); + + ras.band_top++; + } + else + { + if ( ras.fProfile ) + if ( Draw_Sweep( RAS_VAR ) ) + return ras.error; + ras.band_top--; + } + } + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Render_Glyph */ + /* */ + /* <Description> */ + /* Render a glyph in a bitmap. Sub-banding if needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + Render_Glyph( RAS_ARG ) + { + FT_Error error; + + + Set_High_Precision( RAS_VARS ras.outline.flags & + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift; + + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) + ras.dropOutControl = 2; + else + { + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl = 4; + else + ras.dropOutControl = 0; + + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl += 1; + } + + ras.second_pass = (FT_Byte)( !( ras.outline.flags & + FT_OUTLINE_SINGLE_PASS ) ); + + /* Vertical Sweep */ + ras.Proc_Sweep_Init = Vertical_Sweep_Init; + ras.Proc_Sweep_Span = Vertical_Sweep_Span; + ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; + ras.Proc_Sweep_Step = Vertical_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); + + ras.bWidth = (unsigned short)ras.target.width; + ras.bTarget = (Byte*)ras.target.buffer; + + if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) + return error; + + /* Horizontal Sweep */ + if ( ras.second_pass && ras.dropOutControl != 2 ) + { + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; + ras.Proc_Sweep_Span = Horizontal_Sweep_Span; + ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; + ras.Proc_Sweep_Step = Horizontal_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); + + if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) + return error; + } + + return Raster_Err_None; + } + + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Render_Gray_Glyph */ + /* */ + /* <Description> */ + /* Render a glyph with grayscaling. Sub-banding if needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + Render_Gray_Glyph( RAS_ARG ) + { + Long pixel_width; + FT_Error error; + + + Set_High_Precision( RAS_VARS ras.outline.flags & + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift + 1; + + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) + ras.dropOutControl = 2; + else + { + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl = 4; + else + ras.dropOutControl = 0; + + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl += 1; + } + + ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); + + /* Vertical Sweep */ + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = 2 * ras.target.rows - 1; + + ras.bWidth = ras.gray_width; + pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); + + if ( ras.bWidth > pixel_width ) + ras.bWidth = pixel_width; + + ras.bWidth = ras.bWidth * 8; + ras.bTarget = (Byte*)ras.gray_lines; + ras.gTarget = (Byte*)ras.target.buffer; + + ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; + ras.Proc_Sweep_Span = Vertical_Sweep_Span; + ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; + ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; + + error = Render_Single_Pass( RAS_VARS 0 ); + if ( error ) + return error; + + /* Horizontal Sweep */ + if ( ras.second_pass && ras.dropOutControl != 2 ) + { + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; + ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; + ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; + ras.Proc_Sweep_Step = Horizontal_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = ras.target.width * 2 - 1; + + error = Render_Single_Pass( RAS_VARS 1 ); + if ( error ) + return error; + } + + return Raster_Err_None; + } + +#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ + + FT_LOCAL_DEF( FT_Error ) + Render_Gray_Glyph( RAS_ARG ) + { + FT_UNUSED_RASTER; + + return FT_THROW( Unsupported ); + } + +#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ + + + static void + ft_black_init( black_PRaster 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; + + raster->gray_width = RASTER_GRAY_LINES / 2; +#else + FT_UNUSED( raster ); +#endif + } + + + /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ + /**** a static object. *****/ + + +#ifdef _STANDALONE_ + + + static int + ft_black_new( void* memory, + FT_Raster *araster ) + { + static black_TRaster the_raster; + FT_UNUSED( memory ); + + + *araster = (FT_Raster)&the_raster; + FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + ft_black_init( &the_raster ); + + return 0; + } + + + static void + ft_black_done( FT_Raster raster ) + { + /* nothing */ + FT_UNUSED( raster ); + } + + +#else /* !_STANDALONE_ */ + + + static int + ft_black_new( FT_Memory memory, + black_PRaster *araster ) + { + FT_Error error; + black_PRaster raster = NULL; + + + *araster = 0; + if ( !FT_NEW( raster ) ) + { + raster->memory = memory; + ft_black_init( raster ); + + *araster = raster; + } + + return error; + } + + + static void + ft_black_done( black_PRaster raster ) + { + FT_Memory memory = (FT_Memory)raster->memory; + + + FT_FREE( raster ); + } + + +#endif /* !_STANDALONE_ */ + + + static void + ft_black_reset( black_PRaster raster, + char* pool_base, + long pool_size ) + { + if ( raster ) + { + if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 ) + { + black_PWorker worker = (black_PWorker)pool_base; + + + raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 ); + raster->buffer_size = (long)( pool_base + pool_size - + (char*)raster->buffer ); + raster->worker = worker; + } + else + { + raster->buffer = NULL; + raster->buffer_size = 0; + raster->worker = NULL; + } + } + } + + + static void + ft_black_set_mode( black_PRaster raster, + unsigned long mode, + const char* palette ) + { +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) + { + /* set 5-levels gray palette */ + 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 + + FT_UNUSED( raster ); + FT_UNUSED( mode ); + FT_UNUSED( palette ); + +#endif + } + + + static int + ft_black_render( black_PRaster raster, + const FT_Raster_Params* params ) + { + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; + black_PWorker worker; + + + if ( !raster || !raster->buffer || !raster->buffer_size ) + return FT_THROW( Not_Ini ); + + if ( !outline ) + return FT_THROW( Invalid ); + + /* return immediately if the outline is empty */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + return Raster_Err_None; + + if ( !outline->contours || !outline->points ) + return FT_THROW( Invalid ); + + if ( outline->n_points != + outline->contours[outline->n_contours - 1] + 1 ) + return FT_THROW( Invalid ); + + worker = raster->worker; + + /* this version of the raster does not support direct rendering, sorry */ + if ( params->flags & FT_RASTER_FLAG_DIRECT ) + return FT_THROW( Unsupported ); + + if ( !target_map ) + return FT_THROW( Invalid ); + + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return Raster_Err_None; + + if ( !target_map->buffer ) + return FT_THROW( Invalid ); + + 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; + + FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); +#endif + + return ( params->flags & FT_RASTER_FLAG_AA ) + ? Render_Gray_Glyph( RAS_VAR ) + : Render_Glyph( RAS_VAR ); + } + + + FT_DEFINE_RASTER_FUNCS( ft_standard_raster, + FT_GLYPH_FORMAT_OUTLINE, + (FT_Raster_New_Func) ft_black_new, + (FT_Raster_Reset_Func) ft_black_reset, + (FT_Raster_Set_Mode_Func)ft_black_set_mode, + (FT_Raster_Render_Func) ft_black_render, + (FT_Raster_Done_Func) ft_black_done + ) + + +/* END */ diff --git a/drivers/freetype/src/raster/ftraster.h b/drivers/freetype/src/raster/ftraster.h new file mode 100644 index 0000000000..80fe46deba --- /dev/null +++ b/drivers/freetype/src/raster/ftraster.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* ftraster.h */ +/* */ +/* The FreeType glyph rasterizer (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTRASTER_H__ +#define __FTRASTER_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_IMAGE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Uncomment the following line if you are using ftraster.c as a */ + /* standalone module, fully independent of FreeType. */ + /* */ +/* #define _STANDALONE_ */ + + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; + + +FT_END_HEADER + +#endif /* __FTRASTER_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/raster/ftrend1.c b/drivers/freetype/src/raster/ftrend1.c new file mode 100644 index 0000000000..aa7f6d5664 --- /dev/null +++ b/drivers/freetype/src/raster/ftrend1.c @@ -0,0 +1,306 @@ +/***************************************************************************/ +/* */ +/* ftrend1.c */ +/* */ +/* The FreeType glyph rasterizer interface (body). */ +/* */ +/* Copyright 1996-2003, 2005, 2006, 2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_OUTLINE_H +#include "ftrend1.h" +#include "ftraster.h" +#include "rastpic.h" + +#include "rasterrs.h" + + + /* initialize renderer -- init its raster */ + static FT_Error + ft_raster1_init( FT_Renderer render ) + { + FT_Library library = FT_MODULE_LIBRARY( render ); + + + render->clazz->raster_class->raster_reset( render->raster, + library->raster_pool, + library->raster_pool_size ); + + return FT_Err_Ok; + } + + + /* set render-specific mode */ + static FT_Error + ft_raster1_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* we simply pass it to the raster */ + return render->clazz->raster_class->raster_set_mode( render->raster, + mode_tag, + data ); + } + + + /* transform a given glyph image */ + static FT_Error + ft_raster1_transform( FT_Renderer render, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ) + { + FT_Error error = FT_Err_Ok; + + + if ( slot->format != render->glyph_format ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( matrix ) + FT_Outline_Transform( &slot->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &slot->outline, delta->x, delta->y ); + + Exit: + return error; + } + + + /* return the glyph's control box */ + static void + ft_raster1_get_cbox( FT_Renderer render, + FT_GlyphSlot slot, + FT_BBox* cbox ) + { + FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + + if ( slot->format == render->glyph_format ) + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_raster1_render( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Error error; + FT_Outline* outline; + FT_BBox cbox; + FT_UInt width, height, pitch; + FT_Bitmap* bitmap; + FT_Memory memory; + + FT_Raster_Params params; + + + /* check glyph image format */ + if ( slot->format != render->glyph_format ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* check rendering mode */ +#ifndef FT_CONFIG_OPTION_PIC + if ( mode != FT_RENDER_MODE_MONO ) + { + /* raster1 is only capable of producing monochrome bitmaps */ + if ( render->clazz == &ft_raster1_renderer_class ) + return FT_THROW( Cannot_Render_Glyph ); + } + else + { + /* raster5 is only capable of producing 5-gray-levels bitmaps */ + if ( render->clazz == &ft_raster5_renderer_class ) + return FT_THROW( Cannot_Render_Glyph ); + } +#else /* FT_CONFIG_OPTION_PIC */ + /* When PIC is enabled, we cannot get to the class object */ + /* so instead we check the final character in the class name */ + /* ("raster5" or "raster1"). Yes this is a hack. */ + /* The "correct" thing to do is have different render function */ + /* for each of the classes. */ + if ( mode != FT_RENDER_MODE_MONO ) + { + /* raster1 is only capable of producing monochrome bitmaps */ + if ( render->clazz->root.module_name[6] == '1' ) + return FT_THROW( Cannot_Render_Glyph ); + } + else + { + /* raster5 is only capable of producing 5-gray-levels bitmaps */ + if ( render->clazz->root.module_name[6] == '5' ) + return FT_THROW( Cannot_Render_Glyph ); + } +#endif /* FT_CONFIG_OPTION_PIC */ + + outline = &slot->outline; + + /* translate the outline to the new origin if needed */ + if ( origin ) + FT_Outline_Translate( outline, origin->x, origin->y ); + + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); + + /* undocumented but confirmed: bbox values get rounded */ +#if 1 + cbox.xMin = FT_PIX_ROUND( cbox.xMin ); + cbox.yMin = FT_PIX_ROUND( cbox.yMin ); + cbox.xMax = FT_PIX_ROUND( cbox.xMax ); + cbox.yMax = FT_PIX_ROUND( cbox.yMax ); +#else + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); +#endif + + width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + + if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + bitmap = &slot->bitmap; + memory = render->root.memory; + + /* release old bitmap buffer */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + /* allocate new one, depends on pixel format */ + if ( !( mode & FT_RENDER_MODE_MONO ) ) + { + /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ + pitch = FT_PAD_CEIL( width, 4 ); + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + } + else + { + pitch = ( ( width + 15 ) >> 4 ) << 1; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + } + + bitmap->width = width; + bitmap->rows = height; + bitmap->pitch = pitch; + + if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) + goto Exit; + + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); + + /* set up parameters */ + params.target = bitmap; + params.source = outline; + params.flags = 0; + + if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) + params.flags |= FT_RASTER_FLAG_AA; + + /* render outline into the bitmap */ + error = render->raster_render( render->raster, ¶ms ); + + FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); + + if ( error ) + goto Exit; + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); + slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); + + Exit: + return error; + } + + + FT_DEFINE_RENDERER( ft_raster1_renderer_class, + + FT_MODULE_RENDERER, + sizeof ( FT_RendererRec ), + + "raster1", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_raster1_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_raster1_render, + (FT_Renderer_TransformFunc)ft_raster1_transform, + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) + + + /* This renderer is _NOT_ part of the default modules; you will need */ + /* to register it by hand in your application. It should only be */ + /* used for backwards-compatibility with FT 1.x anyway. */ + /* */ + FT_DEFINE_RENDERER( ft_raster5_renderer_class, + + FT_MODULE_RENDERER, + sizeof ( FT_RendererRec ), + + "raster5", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_raster1_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_raster1_render, + (FT_Renderer_TransformFunc)ft_raster1_transform, + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) + + +/* END */ diff --git a/drivers/freetype/src/raster/ftrend1.h b/drivers/freetype/src/raster/ftrend1.h new file mode 100644 index 0000000000..4cf128622a --- /dev/null +++ b/drivers/freetype/src/raster/ftrend1.h @@ -0,0 +1,44 @@ +/***************************************************************************/ +/* */ +/* ftrend1.h */ +/* */ +/* The FreeType glyph rasterizer interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTREND1_H__ +#define __FTREND1_H__ + + +#include <ft2build.h> +#include FT_RENDER_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_RENDERER( ft_raster1_renderer_class ) + + /* this renderer is _NOT_ part of the default modules, you'll need */ + /* to register it by hand in your application. It should only be */ + /* used for backwards-compatibility with FT 1.x anyway. */ + /* */ + FT_DECLARE_RENDERER( ft_raster5_renderer_class ) + + +FT_END_HEADER + +#endif /* __FTREND1_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/raster/module.mk b/drivers/freetype/src/raster/module.mk new file mode 100644 index 0000000000..cbff5df96e --- /dev/null +++ b/drivers/freetype/src/raster/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 renderer module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += RASTER_MODULE + +define RASTER_MODULE +$(OPEN_DRIVER) FT_Renderer_Class, ft_raster1_renderer_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)raster $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/raster/raster.c b/drivers/freetype/src/raster/raster.c new file mode 100644 index 0000000000..1202a116cd --- /dev/null +++ b/drivers/freetype/src/raster/raster.c @@ -0,0 +1,27 @@ +/***************************************************************************/ +/* */ +/* raster.c */ +/* */ +/* FreeType monochrome rasterer module component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "rastpic.c" +#include "ftraster.c" +#include "ftrend1.c" + + +/* END */ diff --git a/drivers/freetype/src/raster/rasterrs.h b/drivers/freetype/src/raster/rasterrs.h new file mode 100644 index 0000000000..ab85c002a3 --- /dev/null +++ b/drivers/freetype/src/raster/rasterrs.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* rasterrs.h */ +/* */ +/* monochrome renderer error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the monochrome renderer error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __RASTERRS_H__ +#define __RASTERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX Raster_Err_ +#define FT_ERR_BASE FT_Mod_Err_Raster + +#include FT_ERRORS_H + +#endif /* __RASTERRS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/raster/rastpic.c b/drivers/freetype/src/raster/rastpic.c new file mode 100644 index 0000000000..5e9f7cc9c4 --- /dev/null +++ b/drivers/freetype/src/raster/rastpic.c @@ -0,0 +1,103 @@ +/***************************************************************************/ +/* */ +/* rastpic.c */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009, 2010, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "rastpic.h" +#include "rasterrs.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftraster.c */ + void + FT_Init_Class_ft_standard_raster( FT_Raster_Funcs* funcs ); + + + void + ft_raster1_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->raster ) + { + RasterPIC* container = (RasterPIC*)pic_container->raster; + + + if ( --container->ref_count ) + return; + FT_FREE( container ); + pic_container->raster = NULL; + } + } + + + FT_Error + ft_raster1_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + RasterPIC* container = NULL; + FT_Memory memory = library->memory; + + + /* since this function also serves raster5 renderer, */ + /* it implements reference counting */ + if ( pic_container->raster ) + { + ((RasterPIC*)pic_container->raster)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->raster = container; + + container->ref_count = 1; + + /* initialize pointer table - */ + /* this is how the module usually expects this data */ + FT_Init_Class_ft_standard_raster( &container->ft_standard_raster ); + + return error; + } + + + /* re-route these init and free functions to the above functions */ + FT_Error + ft_raster5_renderer_class_pic_init( FT_Library library ) + { + return ft_raster1_renderer_class_pic_init( library ); + } + + + void + ft_raster5_renderer_class_pic_free( FT_Library library ) + { + ft_raster1_renderer_class_pic_free( library ); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/raster/rastpic.h b/drivers/freetype/src/raster/rastpic.h new file mode 100644 index 0000000000..e0ddba624e --- /dev/null +++ b/drivers/freetype/src/raster/rastpic.h @@ -0,0 +1,69 @@ +/***************************************************************************/ +/* */ +/* rastpic.h */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __RASTPIC_H__ +#define __RASTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_STANDARD_RASTER_GET ft_standard_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct RasterPIC_ + { + int ref_count; + FT_Raster_Funcs ft_standard_raster; + + } RasterPIC; + + +#define GET_PIC( lib ) \ + ( (RasterPIC*)( (lib)->pic_container.raster ) ) +#define FT_STANDARD_RASTER_GET ( GET_PIC( library )->ft_standard_raster ) + + + /* see rastpic.c for the implementation */ + void + ft_raster1_renderer_class_pic_free( FT_Library library ); + + void + ft_raster5_renderer_class_pic_free( FT_Library library ); + + FT_Error + ft_raster1_renderer_class_pic_init( FT_Library library ); + + FT_Error + ft_raster5_renderer_class_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __RASTPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/raster/rules.mk b/drivers/freetype/src/raster/rules.mk new file mode 100644 index 0000000000..0e0b5e4ebd --- /dev/null +++ b/drivers/freetype/src/raster/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 renderer module build rules +# + + +# Copyright 1996-2000, 2001, 2003, 2008, 2009, 2011 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. + + +# raster driver directory +# +RASTER_DIR := $(SRC_DIR)/raster + +# compilation flags for the driver +# +RASTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR)) + + +# raster driver sources (i.e., C files) +# +RASTER_DRV_SRC := $(RASTER_DIR)/ftraster.c \ + $(RASTER_DIR)/ftrend1.c \ + $(RASTER_DIR)/rastpic.c + + +# raster driver headers +# +RASTER_DRV_H := $(RASTER_DRV_SRC:%.c=%.h) \ + $(RASTER_DIR)/rasterrs.h + + +# raster driver object(s) +# +# RASTER_DRV_OBJ_M is used during `multi' builds. +# RASTER_DRV_OBJ_S is used during `single' builds. +# +RASTER_DRV_OBJ_M := $(RASTER_DRV_SRC:$(RASTER_DIR)/%.c=$(OBJ_DIR)/%.$O) +RASTER_DRV_OBJ_S := $(OBJ_DIR)/raster.$O + +# raster driver source file for single build +# +RASTER_DRV_SRC_S := $(RASTER_DIR)/raster.c + + +# raster driver - single object +# +$(RASTER_DRV_OBJ_S): $(RASTER_DRV_SRC_S) $(RASTER_DRV_SRC) \ + $(FREETYPE_H) $(RASTER_DRV_H) + $(RASTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(RASTER_DRV_SRC_S)) + + +# raster driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(RASTER_DIR)/%.c $(FREETYPE_H) $(RASTER_DRV_H) + $(RASTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(RASTER_DRV_OBJ_S) +DRV_OBJS_M += $(RASTER_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/sfnt/Jamfile b/drivers/freetype/src/sfnt/Jamfile new file mode 100644 index 0000000000..cb20b1b04b --- /dev/null +++ b/drivers/freetype/src/sfnt/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/sfnt Jamfile +# +# Copyright 2001, 2002, 2004, 2005 by +# David Turner, Robert Wilhelm, and Werner Lemberg. +# +# This file is part of the FreeType project, and may only be used, modified, +# and distributed under the terms of the FreeType project license, +# LICENSE.TXT. By continuing to use, modify, or distribute this file you +# indicate that you have read the license and understand and accept it +# fully. + +SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = sfobjs sfdriver ttcmap ttmtx ttpost ttload ttsbit ttkern ttbdf sfntpic ; + } + else + { + _sources = sfnt ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/sfnt Jamfile diff --git a/drivers/freetype/src/sfnt/module.mk b/drivers/freetype/src/sfnt/module.mk new file mode 100644 index 0000000000..95fd6a3143 --- /dev/null +++ b/drivers/freetype/src/sfnt/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 SFNT module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += SFNT_MODULE + +define SFNT_MODULE +$(OPEN_DRIVER) FT_Module_Class, sfnt_module_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/sfnt/pngshim.c b/drivers/freetype/src/sfnt/pngshim.c new file mode 100644 index 0000000000..408f879c34 --- /dev/null +++ b/drivers/freetype/src/sfnt/pngshim.c @@ -0,0 +1,336 @@ +/***************************************************************************/ +/* */ +/* pngshim.c */ +/* */ +/* PNG Bitmap glyph support. */ +/* */ +/* Copyright 2013 by Google, Inc. */ +/* Written by Stuart Gill and Behdad Esfahbod. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + + +#ifdef FT_CONFIG_OPTION_USE_PNG + + /* We always include <stjmp.h>, so make libpng shut up! */ +#define PNG_SKIP_SETJMP_CHECK 1 +#include <png.h> +#include "pngshim.h" + +#include "sferrors.h" + + + /* This code is freely based on cairo-png.c. There's so many ways */ + /* to call libpng, and the way cairo does it is defacto standard. */ + + static int + multiply_alpha( int alpha, + int color ) + { + int temp = ( alpha * color ) + 0x80; + + + return ( temp + ( temp >> 8 ) ) >> 8; + } + + + /* Premultiplies data and converts RGBA bytes => native endian. */ + static void + premultiply_data( png_structp png, + png_row_infop row_info, + png_bytep data ) + { + unsigned int i; + + FT_UNUSED( png ); + + + for ( i = 0; i < row_info->rowbytes; i += 4 ) + { + unsigned char* base = &data[i]; + unsigned int alpha = base[3]; + + + if ( alpha == 0 ) + base[0] = base[1] = base[2] = base[3] = 0; + + else + { + unsigned int red = base[0]; + unsigned int green = base[1]; + unsigned int blue = base[2]; + + + if ( alpha != 0xFF ) + { + red = multiply_alpha( alpha, red ); + green = multiply_alpha( alpha, green ); + blue = multiply_alpha( alpha, blue ); + } + + base[0] = blue; + base[1] = green; + base[2] = red; + base[3] = alpha; + } + } + } + + + /* Converts RGBx bytes to BGRA. */ + static void + convert_bytes_to_data( png_structp png, + png_row_infop row_info, + png_bytep data ) + { + unsigned int i; + + FT_UNUSED( png ); + + + for ( i = 0; i < row_info->rowbytes; i += 4 ) + { + unsigned char* base = &data[i]; + unsigned int red = base[0]; + unsigned int green = base[1]; + unsigned int blue = base[2]; + + + base[0] = blue; + base[1] = green; + base[2] = red; + base[3] = 0xFF; + } + } + + + /* Use error callback to avoid png writing to stderr. */ + static void + error_callback( png_structp png, + png_const_charp error_msg ) + { + FT_Error* error = png_get_error_ptr( png ); + + FT_UNUSED( error_msg ); + + + *error = FT_THROW( Out_Of_Memory ); +#ifdef PNG_SETJMP_SUPPORTED + longjmp( png_jmpbuf( png ), 1 ); +#endif + /* if we get here, then we have no choice but to abort ... */ + } + + + /* Use warning callback to avoid png writing to stderr. */ + static void + warning_callback( png_structp png, + png_const_charp error_msg ) + { + FT_UNUSED( png ); + FT_UNUSED( error_msg ); + + /* Just ignore warnings. */ + } + + + static void + read_data_from_FT_Stream( png_structp png, + png_bytep data, + png_size_t length ) + { + FT_Error error; + png_voidp p = png_get_io_ptr( png ); + FT_Stream stream = (FT_Stream)p; + + + if ( FT_FRAME_ENTER( length ) ) + { + FT_Error* e = png_get_error_ptr( png ); + + + *e = FT_THROW( Invalid_Stream_Read ); + png_error( png, NULL ); + + return; + } + + memcpy( data, stream->cursor, length ); + + FT_FRAME_EXIT(); + } + + + static FT_Error + Load_SBit_Png( FT_Bitmap* map, + FT_Int x_offset, + FT_Int y_offset, + FT_Int pix_bits, + TT_SBit_Metrics metrics, + FT_Memory memory, + FT_Byte* data, + FT_UInt png_len ) + { + FT_Error error = FT_Err_Ok; + FT_StreamRec stream; + + png_structp png; + png_infop info; + png_uint_32 imgWidth, imgHeight; + + int bitdepth, color_type, interlace; + FT_Int i; + png_byte* *rows; + + + if ( x_offset < 0 || x_offset + metrics->width > map->width || + y_offset < 0 || y_offset + metrics->height > map->rows || + pix_bits != 32 || map->pixel_mode != FT_PIXEL_MODE_BGRA ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_Stream_OpenMemory( &stream, data, png_len ); + + png = png_create_read_struct( PNG_LIBPNG_VER_STRING, + &error, + error_callback, + warning_callback ); + if ( !png ) + { + error = FT_THROW( Out_Of_Memory ); + goto Exit; + } + + info = png_create_info_struct( png ); + if ( !info ) + { + error = FT_THROW( Out_Of_Memory ); + png_destroy_read_struct( &png, NULL, NULL ); + goto Exit; + } + + if ( ft_setjmp( png_jmpbuf( png ) ) ) + { + error = FT_THROW( Invalid_File_Format ); + goto DestroyExit; + } + + png_set_read_fn( png, &stream, read_data_from_FT_Stream ); + + png_read_info( png, info ); + png_get_IHDR( png, info, + &imgWidth, &imgHeight, + &bitdepth, &color_type, &interlace, + NULL, NULL ); + + if ( error != FT_Err_Ok || + (FT_Int)imgWidth != metrics->width || + (FT_Int)imgHeight != metrics->height ) + goto DestroyExit; + + /* convert palette/gray image to rgb */ + if ( color_type == PNG_COLOR_TYPE_PALETTE ) + png_set_palette_to_rgb( png ); + + /* expand gray bit depth if needed */ + if ( color_type == PNG_COLOR_TYPE_GRAY ) + { +#if PNG_LIBPNG_VER >= 10209 + png_set_expand_gray_1_2_4_to_8( png ); +#else + png_set_gray_1_2_4_to_8( png ); +#endif + } + + /* transform transparency to alpha */ + if ( png_get_valid(png, info, PNG_INFO_tRNS ) ) + png_set_tRNS_to_alpha( png ); + + if ( bitdepth == 16 ) + png_set_strip_16( png ); + + if ( bitdepth < 8 ) + png_set_packing( png ); + + /* convert grayscale to RGB */ + if ( color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) + png_set_gray_to_rgb( png ); + + if ( interlace != PNG_INTERLACE_NONE ) + png_set_interlace_handling( png ); + + png_set_filler( png, 0xFF, PNG_FILLER_AFTER ); + + /* recheck header after setting EXPAND options */ + png_read_update_info(png, info ); + png_get_IHDR( png, info, + &imgWidth, &imgHeight, + &bitdepth, &color_type, &interlace, + NULL, NULL ); + + if ( bitdepth != 8 || + !( color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA ) ) + { + error = FT_THROW( Invalid_File_Format ); + goto DestroyExit; + } + + switch ( color_type ) + { + default: + /* Shouldn't happen, but fall through. */ + + case PNG_COLOR_TYPE_RGB_ALPHA: + png_set_read_user_transform_fn( png, premultiply_data ); + break; + + case PNG_COLOR_TYPE_RGB: + /* Humm, this smells. Carry on though. */ + png_set_read_user_transform_fn( png, convert_bytes_to_data ); + break; + } + + if ( FT_NEW_ARRAY( rows, imgHeight ) ) + { + error = FT_THROW( Out_Of_Memory ); + goto DestroyExit; + } + + for ( i = 0; i < (FT_Int)imgHeight; i++ ) + rows[i] = map->buffer + ( y_offset + i ) * map->pitch + x_offset * 4; + + png_read_image( png, rows ); + + FT_FREE( rows ); + + png_read_end( png, info ); + + DestroyExit: + png_destroy_read_struct( &png, &info, NULL ); + FT_Stream_Close( &stream ); + + Exit: + return error; + } + +#endif /* FT_CONFIG_OPTION_USE_PNG */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/pngshim.h b/drivers/freetype/src/sfnt/pngshim.h new file mode 100644 index 0000000000..8a2e69ccf9 --- /dev/null +++ b/drivers/freetype/src/sfnt/pngshim.h @@ -0,0 +1,48 @@ +/***************************************************************************/ +/* */ +/* pngshim.h */ +/* */ +/* PNG Bitmap glyph support. */ +/* */ +/* Copyright 2013 by Google, Inc. */ +/* Written by Stuart Gill and Behdad Esfahbod. */ +/* */ +/* 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 __PNGSHIM_H__ +#define __PNGSHIM_H__ + + +#include <ft2build.h> +#include "ttload.h" + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_USE_PNG + + FT_LOCAL( FT_Error ) + Load_SBit_Png( FT_Bitmap* map, + FT_Int x_offset, + FT_Int y_offset, + FT_Int pix_bits, + TT_SBit_Metrics metrics, + FT_Memory memory, + FT_Byte* data, + FT_UInt png_len ); + +#endif + +FT_END_HEADER + +#endif /* __PNGSHIM_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/rules.mk b/drivers/freetype/src/sfnt/rules.mk new file mode 100644 index 0000000000..a6c956ab65 --- /dev/null +++ b/drivers/freetype/src/sfnt/rules.mk @@ -0,0 +1,78 @@ +# +# FreeType 2 SFNT driver configuration rules +# + + +# Copyright 1996-2000, 2002-2007, 2009, 2011, 2013 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. + + +# SFNT driver directory +# +SFNT_DIR := $(SRC_DIR)/sfnt + + +# compilation flags for the driver +# +SFNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) + + +# SFNT driver sources (i.e., C files) +# +SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \ + $(SFNT_DIR)/ttmtx.c \ + $(SFNT_DIR)/ttcmap.c \ + $(SFNT_DIR)/ttsbit.c \ + $(SFNT_DIR)/ttpost.c \ + $(SFNT_DIR)/ttkern.c \ + $(SFNT_DIR)/ttbdf.c \ + $(SFNT_DIR)/sfobjs.c \ + $(SFNT_DIR)/sfdriver.c \ + $(SFNT_DIR)/sfntpic.c \ + $(SFNT_DIR)/pngshim.c + +# SFNT driver headers +# +SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ + $(SFNT_DIR)/sferrors.h + + +# SFNT driver object(s) +# +# SFNT_DRV_OBJ_M is used during `multi' builds. +# SFNT_DRV_OBJ_S is used during `single' builds. +# +SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR)/%.c=$(OBJ_DIR)/%.$O) +SFNT_DRV_OBJ_S := $(OBJ_DIR)/sfnt.$O + +# SFNT driver source file for single build +# +SFNT_DRV_SRC_S := $(SFNT_DIR)/sfnt.c + + +# SFNT driver - single object +# +$(SFNT_DRV_OBJ_S): $(SFNT_DRV_SRC_S) $(SFNT_DRV_SRC) \ + $(FREETYPE_H) $(SFNT_DRV_H) + $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SFNT_DRV_SRC_S)) + + +# SFNT driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(SFNT_DIR)/%.c $(FREETYPE_H) $(SFNT_DRV_H) + $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(SFNT_DRV_OBJ_S) +DRV_OBJS_M += $(SFNT_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/sfnt/sfdriver.c b/drivers/freetype/src/sfnt/sfdriver.c new file mode 100644 index 0000000000..a368b8caea --- /dev/null +++ b/drivers/freetype/src/sfnt/sfdriver.c @@ -0,0 +1,529 @@ +/***************************************************************************/ +/* */ +/* sfdriver.c */ +/* */ +/* High-level SFNT driver interface (body). */ +/* */ +/* Copyright 1996-2007, 2009-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_OBJECTS_H + +#include "sfdriver.h" +#include "ttload.h" +#include "sfobjs.h" +#include "sfntpic.h" + +#include "sferrors.h" + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#include "ttsbit.h" +#endif + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#include "ttpost.h" +#endif + +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#include FT_SERVICE_BDF_H +#endif + +#include "ttcmap.h" +#include "ttkern.h" +#include "ttmtx.h" + +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_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_sfdriver + + + /* + * SFNT TABLE SERVICE + * + */ + + static void* + get_sfnt_table( TT_Face face, + FT_Sfnt_Tag tag ) + { + void* table; + + + switch ( tag ) + { + case ft_sfnt_head: + table = &face->header; + break; + + case ft_sfnt_hhea: + table = &face->horizontal; + break; + + case ft_sfnt_vhea: + table = face->vertical_info ? &face->vertical : 0; + break; + + case ft_sfnt_os2: + table = face->os2.version == 0xFFFFU ? 0 : &face->os2; + break; + + case ft_sfnt_post: + table = &face->postscript; + break; + + case ft_sfnt_maxp: + table = &face->max_profile; + break; + + case ft_sfnt_pclt: + table = face->pclt.Version ? &face->pclt : 0; + break; + + default: + table = 0; + } + + return table; + } + + + static FT_Error + sfnt_table_info( TT_Face face, + FT_UInt idx, + FT_ULong *tag, + FT_ULong *offset, + FT_ULong *length ) + { + if ( !offset || !length ) + return FT_THROW( Invalid_Argument ); + + if ( !tag ) + *length = face->num_tables; + else + { + if ( idx >= face->num_tables ) + return FT_THROW( Table_Missing ); + + *tag = face->dir_tables[idx].Tag; + *offset = face->dir_tables[idx].Offset; + *length = face->dir_tables[idx].Length; + } + + return FT_Err_Ok; + } + + + FT_DEFINE_SERVICE_SFNT_TABLEREC( + sfnt_service_sfnt_table, + (FT_SFNT_TableLoadFunc)tt_face_load_any, + (FT_SFNT_TableGetFunc) get_sfnt_table, + (FT_SFNT_TableInfoFunc)sfnt_table_info ) + + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + /* + * GLYPH DICT SERVICE + * + */ + + static FT_Error + sfnt_get_glyph_name( TT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_String* gname; + FT_Error error; + + + error = tt_face_get_ps_name( face, glyph_index, &gname ); + if ( !error ) + FT_STRCPYN( buffer, gname, buffer_max ); + + return error; + } + + + static FT_UInt + sfnt_get_name_index( TT_Face face, + FT_String* glyph_name ) + { + FT_Face root = &face->root; + + FT_UInt i, max_gid = FT_UINT_MAX; + + + if ( root->num_glyphs < 0 ) + return 0; + else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX ) + max_gid = (FT_UInt)root->num_glyphs; + else + FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", + FT_UINT_MAX, root->num_glyphs )); + + for ( i = 0; i < max_gid; i++ ) + { + FT_String* gname; + FT_Error error = tt_face_get_ps_name( face, i, &gname ); + + + if ( error ) + continue; + + if ( !ft_strcmp( glyph_name, gname ) ) + return i; + } + + return 0; + } + + + FT_DEFINE_SERVICE_GLYPHDICTREC( + sfnt_service_glyph_dict, + (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) + + +#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + sfnt_get_ps_name( TT_Face face ) + { + FT_Int n, found_win, found_apple; + const char* result = NULL; + + + /* shouldn't happen, but just in case to avoid memory leaks */ + if ( face->postscript_name ) + return face->postscript_name; + + /* scan the name table to see whether we have a Postscript name here, */ + /* either in Macintosh or Windows platform encodings */ + found_win = -1; + found_apple = -1; + + for ( n = 0; n < face->num_names; n++ ) + { + TT_NameEntryRec* name = face->name_table.names + n; + + + if ( name->nameID == 6 && name->stringLength > 0 ) + { + if ( name->platformID == 3 && + name->encodingID == 1 && + name->languageID == 0x409 ) + found_win = n; + + if ( name->platformID == 1 && + name->encodingID == 0 && + name->languageID == 0 ) + found_apple = n; + } + } + + if ( found_win != -1 ) + { + FT_Memory memory = face->root.memory; + TT_NameEntryRec* name = face->name_table.names + found_win; + FT_UInt len = name->stringLength / 2; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( error ); + + + if ( !FT_ALLOC( result, name->stringLength + 1 ) ) + { + FT_Stream stream = face->name_table.stream; + FT_String* r = (FT_String*)result; + FT_Byte* p = (FT_Byte*)name->string; + + + if ( FT_STREAM_SEEK( name->stringOffset ) || + FT_FRAME_ENTER( name->stringLength ) ) + { + FT_FREE( result ); + name->stringLength = 0; + name->stringOffset = 0; + FT_FREE( name->string ); + + goto Exit; + } + + p = (FT_Byte*)stream->cursor; + + for ( ; len > 0; len--, p += 2 ) + { + if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 ) + *r++ = p[1]; + } + *r = '\0'; + + FT_FRAME_EXIT(); + } + goto Exit; + } + + if ( found_apple != -1 ) + { + FT_Memory memory = face->root.memory; + TT_NameEntryRec* name = face->name_table.names + found_apple; + FT_UInt len = name->stringLength; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( error ); + + + if ( !FT_ALLOC( result, len + 1 ) ) + { + FT_Stream stream = face->name_table.stream; + + + if ( FT_STREAM_SEEK( name->stringOffset ) || + FT_STREAM_READ( result, len ) ) + { + name->stringOffset = 0; + name->stringLength = 0; + FT_FREE( name->string ); + FT_FREE( result ); + goto Exit; + } + ((char*)result)[len] = '\0'; + } + } + + Exit: + face->postscript_name = result; + return result; + } + + + FT_DEFINE_SERVICE_PSFONTNAMEREC( + sfnt_service_ps_name, + (FT_PsName_GetFunc)sfnt_get_ps_name ) + + + /* + * TT CMAP INFO + */ + FT_DEFINE_SERVICE_TTCMAPSREC( + tt_service_get_cmap_info, + (TT_CMap_Info_GetFunc)tt_get_cmap_info ) + + +#ifdef TT_CONFIG_OPTION_BDF + + static FT_Error + sfnt_get_charset_id( TT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + BDF_PropertyRec encoding, registry; + FT_Error error; + + + /* XXX: I don't know whether this is correct, since + * tt_face_find_bdf_prop only returns something correct if we have + * previously selected a size that is listed in the BDF table. + * Should we change the BDF table format to include single offsets + * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'? + */ + error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", ®istry ); + if ( !error ) + { + error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding ); + if ( !error ) + { + if ( registry.type == BDF_PROPERTY_TYPE_ATOM && + encoding.type == BDF_PROPERTY_TYPE_ATOM ) + { + *acharset_encoding = encoding.u.atom; + *acharset_registry = registry.u.atom; + } + else + error = FT_THROW( Invalid_Argument ); + } + } + + return error; + } + + + FT_DEFINE_SERVICE_BDFRec( + sfnt_service_bdf, + (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) + + +#endif /* TT_CONFIG_OPTION_BDF */ + + + /* + * SERVICE LIST + */ + +#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC5( + sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) +#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_DEFINE_SERVICEDESCREC4( + sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) +#elif defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC4( + sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) +#else + FT_DEFINE_SERVICEDESCREC3( + sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) +#endif + + + FT_CALLBACK_DEF( FT_Module_Interface ) + sfnt_get_interface( FT_Module module, + const char* module_interface ) + { + /* SFNT_SERVICES_GET derefers `library' in PIC mode */ +#ifdef FT_CONFIG_OPTION_PIC + FT_Library library; + + + if ( !module ) + return NULL; + library = module->library; + if ( !library ) + return NULL; +#else + FT_UNUSED( module ); +#endif + + return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface ); + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define PUT_EMBEDDED_BITMAPS( a ) a +#else +#define PUT_EMBEDDED_BITMAPS( a ) NULL +#endif + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES( a ) a +#else +#define PUT_PS_NAMES( a ) NULL +#endif + + FT_DEFINE_SFNT_INTERFACE( + sfnt_interface, + tt_face_goto_table, + + sfnt_init_face, + sfnt_load_face, + sfnt_done_face, + sfnt_get_interface, + + tt_face_load_any, + + tt_face_load_head, + tt_face_load_hhea, + tt_face_load_cmap, + tt_face_load_maxp, + tt_face_load_os2, + tt_face_load_post, + + tt_face_load_name, + tt_face_free_name, + + tt_face_load_kern, + tt_face_load_gasp, + tt_face_load_pclt, + + /* see `ttload.h' */ + PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ), + + PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ), + + /* see `ttpost.h' */ + PUT_PS_NAMES( tt_face_get_ps_name ), + PUT_PS_NAMES( tt_face_free_ps_names ), + + /* since version 2.1.8 */ + tt_face_get_kerning, + + /* since version 2.2 */ + tt_face_load_font_dir, + tt_face_load_hmtx, + + /* see `ttsbit.h' and `sfnt.h' */ + PUT_EMBEDDED_BITMAPS( tt_face_load_eblc ), + PUT_EMBEDDED_BITMAPS( tt_face_free_eblc ), + + PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), + PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), + + tt_face_get_metrics + ) + + + FT_DEFINE_MODULE( + sfnt_module_class, + + 0, /* not a font driver or renderer */ + sizeof ( FT_ModuleRec ), + + "sfnt", /* driver name */ + 0x10000L, /* driver version 1.0 */ + 0x20000L, /* driver requires FreeType 2.0 or higher */ + + (const void*)&SFNT_INTERFACE_GET, /* module specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) sfnt_get_interface ) + + +/* END */ diff --git a/drivers/freetype/src/sfnt/sfdriver.h b/drivers/freetype/src/sfnt/sfdriver.h new file mode 100644 index 0000000000..5de25d51ca --- /dev/null +++ b/drivers/freetype/src/sfnt/sfdriver.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* sfdriver.h */ +/* */ +/* High-level SFNT driver interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __SFDRIVER_H__ +#define __SFDRIVER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_MODULE( sfnt_module_class ) + + +FT_END_HEADER + +#endif /* __SFDRIVER_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/sferrors.h b/drivers/freetype/src/sfnt/sferrors.h new file mode 100644 index 0000000000..e981e1d26f --- /dev/null +++ b/drivers/freetype/src/sfnt/sferrors.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* sferrors.h */ +/* */ +/* SFNT error codes (specification only). */ +/* */ +/* Copyright 2001, 2004, 2012, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the SFNT error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __SFERRORS_H__ +#define __SFERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX SFNT_Err_ +#define FT_ERR_BASE FT_Mod_Err_SFNT + +#include FT_ERRORS_H + +#endif /* __SFERRORS_H__ */ + +/* END */ diff --git a/drivers/freetype/src/sfnt/sfnt.c b/drivers/freetype/src/sfnt/sfnt.c new file mode 100644 index 0000000000..d62ed4e0b5 --- /dev/null +++ b/drivers/freetype/src/sfnt/sfnt.c @@ -0,0 +1,43 @@ +/***************************************************************************/ +/* */ +/* sfnt.c */ +/* */ +/* Single object library component. */ +/* */ +/* Copyright 1996-2006, 2013 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "sfntpic.c" +#include "ttload.c" +#include "ttmtx.c" +#include "ttcmap.c" +#include "ttkern.c" +#include "sfobjs.c" +#include "sfdriver.c" + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#include "pngshim.c" +#include "ttsbit.c" +#endif + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#include "ttpost.c" +#endif + +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.c" +#endif + +/* END */ diff --git a/drivers/freetype/src/sfnt/sfntpic.c b/drivers/freetype/src/sfnt/sfntpic.c new file mode 100644 index 0000000000..b3fb24b3f0 --- /dev/null +++ b/drivers/freetype/src/sfnt/sfntpic.c @@ -0,0 +1,143 @@ +/***************************************************************************/ +/* */ +/* sfntpic.c */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009, 2010, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "sfntpic.h" +#include "sferrors.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from sfdriver.c */ + FT_Error + FT_Create_Class_sfnt_services( FT_Library library, + FT_ServiceDescRec** output_class ); + void + FT_Destroy_Class_sfnt_services( FT_Library library, + FT_ServiceDescRec* clazz ); + void + FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec* clazz ); + void + FT_Init_Class_sfnt_interface( FT_Library library, + SFNT_Interface* clazz ); + void + FT_Init_Class_sfnt_service_glyph_dict( + FT_Library library, + FT_Service_GlyphDictRec* clazz ); + void + FT_Init_Class_sfnt_service_ps_name( + FT_Library library, + FT_Service_PsFontNameRec* clazz ); + void + FT_Init_Class_tt_service_get_cmap_info( + FT_Library library, + FT_Service_TTCMapsRec* clazz ); + void + FT_Init_Class_sfnt_service_sfnt_table( + FT_Service_SFNT_TableRec* clazz ); + + + /* forward declaration of PIC init functions from ttcmap.c */ + FT_Error + FT_Create_Class_tt_cmap_classes( FT_Library library, + TT_CMap_Class** output_class ); + void + FT_Destroy_Class_tt_cmap_classes( FT_Library library, + TT_CMap_Class* clazz ); + + + void + sfnt_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->sfnt ) + { + sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt; + + + if ( container->sfnt_services ) + FT_Destroy_Class_sfnt_services( library, + container->sfnt_services ); + container->sfnt_services = NULL; + + if ( container->tt_cmap_classes ) + FT_Destroy_Class_tt_cmap_classes( library, + container->tt_cmap_classes ); + container->tt_cmap_classes = NULL; + + FT_FREE( container ); + pic_container->sfnt = NULL; + } + } + + + FT_Error + sfnt_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + sfntModulePIC* container = NULL; + FT_Memory memory = library->memory; + + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->sfnt = container; + + /* initialize pointer table - */ + /* this is how the module usually expects this data */ + error = FT_Create_Class_sfnt_services( library, + &container->sfnt_services ); + if ( error ) + goto Exit; + + error = FT_Create_Class_tt_cmap_classes( library, + &container->tt_cmap_classes ); + if ( error ) + goto Exit; + + FT_Init_Class_sfnt_service_glyph_dict( + library, &container->sfnt_service_glyph_dict ); + FT_Init_Class_sfnt_service_ps_name( + library, &container->sfnt_service_ps_name ); + FT_Init_Class_tt_service_get_cmap_info( + library, &container->tt_service_get_cmap_info ); + FT_Init_Class_sfnt_service_sfnt_table( + &container->sfnt_service_sfnt_table ); +#ifdef TT_CONFIG_OPTION_BDF + FT_Init_Class_sfnt_service_bdf( &container->sfnt_service_bdf ); +#endif + FT_Init_Class_sfnt_interface( library, &container->sfnt_interface ); + + Exit: + if ( error ) + sfnt_module_class_pic_free( library ); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/sfntpic.h b/drivers/freetype/src/sfnt/sfntpic.h new file mode 100644 index 0000000000..b09a9141e0 --- /dev/null +++ b/drivers/freetype/src/sfnt/sfntpic.h @@ -0,0 +1,114 @@ +/***************************************************************************/ +/* */ +/* sfntpic.h */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009, 2012 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __SFNTPIC_H__ +#define __SFNTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + +#ifndef FT_CONFIG_OPTION_PIC + +#define SFNT_SERVICES_GET sfnt_services +#define SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict +#define SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name +#define TT_SERVICE_CMAP_INFO_GET tt_service_get_cmap_info +#define SFNT_SERVICES_GET sfnt_services +#define TT_CMAP_CLASSES_GET tt_cmap_classes +#define SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table +#define SFNT_SERVICE_BDF_GET sfnt_service_bdf +#define SFNT_INTERFACE_GET sfnt_interface + +#else /* FT_CONFIG_OPTION_PIC */ + + /* some include files required for members of sfntModulePIC */ +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_H + +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#include FT_SERVICE_BDF_H +#endif + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include "ttcmap.h" + + + typedef struct sfntModulePIC_ + { + FT_ServiceDescRec* sfnt_services; + FT_Service_GlyphDictRec sfnt_service_glyph_dict; + FT_Service_PsFontNameRec sfnt_service_ps_name; + FT_Service_TTCMapsRec tt_service_get_cmap_info; + TT_CMap_Class* tt_cmap_classes; + FT_Service_SFNT_TableRec sfnt_service_sfnt_table; +#ifdef TT_CONFIG_OPTION_BDF + FT_Service_BDFRec sfnt_service_bdf; +#endif + SFNT_Interface sfnt_interface; + + } sfntModulePIC; + + +#define GET_PIC( lib ) \ + ( (sfntModulePIC*)( (lib)->pic_container.sfnt ) ) + +#define SFNT_SERVICES_GET \ + ( GET_PIC( library )->sfnt_services ) +#define SFNT_SERVICE_GLYPH_DICT_GET \ + ( GET_PIC( library )->sfnt_service_glyph_dict ) +#define SFNT_SERVICE_PS_NAME_GET \ + ( GET_PIC( library )->sfnt_service_ps_name ) +#define TT_SERVICE_CMAP_INFO_GET \ + ( GET_PIC( library )->tt_service_get_cmap_info ) +#define SFNT_SERVICES_GET \ + ( GET_PIC( library )->sfnt_services ) +#define TT_CMAP_CLASSES_GET \ + ( GET_PIC( library )->tt_cmap_classes ) +#define SFNT_SERVICE_SFNT_TABLE_GET \ + ( GET_PIC( library )->sfnt_service_sfnt_table ) +#define SFNT_SERVICE_BDF_GET \ + ( GET_PIC( library )->sfnt_service_bdf ) +#define SFNT_INTERFACE_GET \ + ( GET_PIC( library )->sfnt_interface ) + + + /* see sfntpic.c for the implementation */ + void + sfnt_module_class_pic_free( FT_Library library ); + + FT_Error + sfnt_module_class_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __SFNTPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/sfobjs.c b/drivers/freetype/src/sfnt/sfobjs.c new file mode 100644 index 0000000000..f975e71c3b --- /dev/null +++ b/drivers/freetype/src/sfnt/sfobjs.c @@ -0,0 +1,1163 @@ +/***************************************************************************/ +/* */ +/* sfobjs.c */ +/* */ +/* SFNT object management (base). */ +/* */ +/* Copyright 1996-2008, 2010-2013 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 "sfobjs.h" +#include "ttload.h" +#include "ttcmap.h" +#include "ttkern.h" +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_DEBUG_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TAGS_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SFNT_NAMES_H +#include "sferrors.h" + +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#endif + + + /*************************************************************************/ + /* */ + /* 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_sfobjs + + + + /* convert a UTF-16 name entry to ASCII */ + static FT_String* + tt_name_entry_ascii_from_utf16( TT_NameEntry entry, + FT_Memory memory ) + { + FT_String* string = NULL; + FT_UInt len, code, n; + FT_Byte* read = (FT_Byte*)entry->string; + FT_Error error; + + + len = (FT_UInt)entry->stringLength / 2; + + if ( FT_NEW_ARRAY( string, len + 1 ) ) + return NULL; + + for ( n = 0; n < len; n++ ) + { + code = FT_NEXT_USHORT( read ); + + if ( code == 0 ) + break; + + if ( code < 32 || code > 127 ) + code = '?'; + + string[n] = (char)code; + } + + string[n] = 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, + FT_Memory memory ) + { + FT_String* string = NULL; + FT_UInt len, code, n; + FT_Byte* read = (FT_Byte*)entry->string; + FT_Error error; + + + len = (FT_UInt)entry->stringLength; + + if ( FT_NEW_ARRAY( string, len + 1 ) ) + return NULL; + + for ( n = 0; n < len; n++ ) + { + code = *read++; + + if ( code == 0 ) + break; + + if ( code < 32 || code > 127 ) + code = '?'; + + string[n] = (char)code; + } + + string[n] = 0; + + return string; + } + + + typedef FT_String* (*TT_NameEntry_ConvertFunc)( TT_NameEntry entry, + FT_Memory memory ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_get_name */ + /* */ + /* <Description> */ + /* Returns a given ENGLISH name record in ASCII. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* nameid :: The name id of the name record to return. */ + /* */ + /* <InOut> */ + /* name :: The address of a string pointer. NULL if no name is */ + /* present. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_face_get_name( TT_Face face, + FT_UShort nameid, + FT_String** name ) + { + FT_Memory memory = face->root.memory; + FT_Error error = FT_Err_Ok; + FT_String* result = NULL; + FT_UShort n; + TT_NameEntryRec* rec; + 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; + + TT_NameEntry_ConvertFunc convert; + + + FT_ASSERT( name ); + + rec = face->name_table.names; + for ( n = 0; n < face->num_names; n++, rec++ ) + { + /* According to the OpenType 1.3 specification, only Microsoft or */ + /* Apple platform IDs might be used in the `name' table. The */ + /* `Unicode' platform is reserved for the `cmap' table, and the */ + /* `ISO' one is deprecated. */ + /* */ + /* However, the Apple TrueType specification doesn't say the same */ + /* thing and goes to suggest that all Unicode `name' table entries */ + /* should be coded in UTF-16 (in big-endian format I suppose). */ + /* */ + if ( rec->nameID == nameid && rec->stringLength > 0 ) + { + switch ( rec->platformID ) + { + case TT_PLATFORM_APPLE_UNICODE: + case TT_PLATFORM_ISO: + /* there is `languageID' to check there. We should use this */ + /* field only as a last solution when nothing else is */ + /* available. */ + /* */ + found_unicode = n; + 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_english = n; + else if ( rec->encodingID == TT_MAC_ID_ROMAN ) + found_apple_roman = n; + break; + + case TT_PLATFORM_MICROSOFT: + /* we only take a non-English name when there is nothing */ + /* else available in the font */ + /* */ + if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 ) + { + switch ( rec->encodingID ) + { + case TT_MS_ID_SYMBOL_CS: + case TT_MS_ID_UNICODE_CS: + case TT_MS_ID_UCS_4: + is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 ); + found_win = n; + break; + + default: + ; + } + } + break; + + default: + ; + } + } + } + + 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) */ + /* */ + convert = NULL; + if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) ) + { + 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: + /* 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: + ; + } + } + else if ( found_apple >= 0 ) + { + rec = face->name_table.names + found_apple; + convert = tt_name_entry_ascii_from_other; + } + else if ( found_unicode >= 0 ) + { + rec = face->name_table.names + found_unicode; + convert = tt_name_entry_ascii_from_utf16; + } + + if ( rec && convert ) + { + if ( rec->string == NULL ) + { + FT_Stream stream = face->name_table.stream; + + + if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || + FT_STREAM_SEEK( rec->stringOffset ) || + FT_STREAM_READ( rec->string, rec->stringLength ) ) + { + FT_FREE( rec->string ); + rec->stringLength = 0; + result = NULL; + goto Exit; + } + } + + result = convert( rec, memory ); + } + + Exit: + *name = result; + return error; + } + + + static FT_Encoding + sfnt_find_encoding( int platform_id, + int encoding_id ) + { + typedef struct TEncoding_ + { + int platform_id; + int encoding_id; + FT_Encoding encoding; + + } TEncoding; + + static + const TEncoding tt_encodings[] = + { + { TT_PLATFORM_ISO, -1, FT_ENCODING_UNICODE }, + + { TT_PLATFORM_APPLE_UNICODE, -1, FT_ENCODING_UNICODE }, + + { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, FT_ENCODING_APPLE_ROMAN }, + + { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_SJIS }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_GB2312 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_BIG5 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_WANSUNG }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_JOHAB } + }; + + const TEncoding *cur, *limit; + + + cur = tt_encodings; + limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] ); + + for ( ; cur < limit; cur++ ) + { + if ( cur->platform_id == platform_id ) + { + if ( cur->encoding_id == encoding_id || + cur->encoding_id == -1 ) + return cur->encoding; + } + } + + return FT_ENCODING_NONE; + } + + + /* Fill in face->ttc_header. If the font is not a TTC, it is */ + /* synthesized into a TTC with one offset table. */ + static FT_Error + sfnt_open_font( FT_Stream stream, + TT_Face face ) + { + FT_Memory memory = stream->memory; + FT_Error error; + FT_ULong tag, offset; + + static const FT_Frame_Field ttc_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TTC_HeaderRec + + FT_FRAME_START( 8 ), + FT_FRAME_LONG( version ), + FT_FRAME_LONG( count ), /* this is ULong in the specs */ + FT_FRAME_END + }; + + + face->ttc_header.tag = 0; + face->ttc_header.version = 0; + face->ttc_header.count = 0; + + offset = FT_STREAM_POS(); + + if ( FT_READ_ULONG( tag ) ) + return error; + + if ( tag != 0x00010000UL && + tag != TTAG_ttcf && + tag != TTAG_OTTO && + tag != TTAG_true && + tag != TTAG_typ1 && + tag != 0x00020000UL ) + { + FT_TRACE2(( " not a font using the SFNT container format\n" )); + return FT_THROW( Unknown_File_Format ); + } + + face->ttc_header.tag = TTAG_ttcf; + + if ( tag == TTAG_ttcf ) + { + FT_Int n; + + + FT_TRACE3(( "sfnt_open_font: file is a collection\n" )); + + if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) + return error; + + if ( face->ttc_header.count == 0 ) + return FT_THROW( Invalid_Table ); + + /* a rough size estimate: let's conservatively assume that there */ + /* is just a single table info in each subfont header (12 + 16*1 = */ + /* 28 bytes), thus we have (at least) `12 + 4*count' bytes for the */ + /* size of the TTC header plus `28*count' bytes for all subfont */ + /* headers */ + if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) ) + return FT_THROW( Array_Too_Large ); + + /* now read the offsets of each font in the file */ + if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) ) + return error; + + if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) ) + return error; + + for ( n = 0; n < face->ttc_header.count; n++ ) + face->ttc_header.offsets[n] = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + } + else + { + FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" )); + + face->ttc_header.version = 1 << 16; + face->ttc_header.count = 1; + + if ( FT_NEW( face->ttc_header.offsets ) ) + return error; + + face->ttc_header.offsets[0] = offset; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + sfnt_init_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Library library = face->root.driver->root.library; + SFNT_Service sfnt; + + + /* for now, parameters are unused */ + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + sfnt = (SFNT_Service)face->sfnt; + if ( !sfnt ) + { + sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); + if ( !sfnt ) + { + FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" )); + return FT_THROW( Missing_Module ); + } + + face->sfnt = sfnt; + face->goto_table = sfnt->goto_table; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS ); + + FT_TRACE2(( "SFNT driver\n" )); + + error = sfnt_open_font( stream, face ); + if ( error ) + return error; + + FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index )); + + if ( face_index < 0 ) + face_index = 0; + + if ( face_index >= face->ttc_header.count ) + return FT_THROW( Invalid_Argument ); + + if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) + return error; + + /* check that we have a valid TrueType file */ + error = sfnt->load_font_dir( face, stream ); + if ( error ) + return error; + + face->root.num_faces = face->ttc_header.count; + face->root.face_index = face_index; + + return error; + } + + +#define LOAD_( x ) \ + do { \ + FT_TRACE2(( "`" #x "' " )); \ + FT_TRACE3(( "-->\n" )); \ + \ + error = sfnt->load_ ## x( face, stream ); \ + \ + FT_TRACE2(( "%s\n", ( !error ) \ + ? "loaded" \ + : FT_ERR_EQ( error, Table_Missing ) \ + ? "missing" \ + : "failed to load" )); \ + FT_TRACE3(( "\n" )); \ + } while ( 0 ) + +#define LOADM_( x, vertical ) \ + do { \ + FT_TRACE2(( "`%s" #x "' ", \ + vertical ? "vertical " : "" )); \ + FT_TRACE3(( "-->\n" )); \ + \ + error = sfnt->load_ ## x( face, stream, vertical ); \ + \ + FT_TRACE2(( "%s\n", ( !error ) \ + ? "loaded" \ + : FT_ERR_EQ( error, Table_Missing ) \ + ? "missing" \ + : "failed to load" )); \ + FT_TRACE3(( "\n" )); \ + } while ( 0 ) + +#define GET_NAME( id, field ) \ + do { \ + error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \ + if ( error ) \ + goto Exit; \ + } while ( 0 ) + + + FT_LOCAL_DEF( FT_Error ) + sfnt_load_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Error psnames_error; +#endif + FT_Bool has_outline; + FT_Bool is_apple_sbit; + FT_Bool ignore_preferred_family = FALSE; + FT_Bool ignore_preferred_subfamily = FALSE; + + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_UNUSED( face_index ); + + + /* Check parameters */ + + { + FT_Int i; + + + for ( i = 0; i < num_params; i++ ) + { + if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY ) + ignore_preferred_family = TRUE; + else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY ) + ignore_preferred_subfamily = TRUE; + } + } + + /* Load tables */ + + /* We now support two SFNT-based bitmapped font formats. They */ + /* are recognized easily as they do not include a `glyf' */ + /* table. */ + /* */ + /* The first format comes from Apple, and uses a table named */ + /* `bhed' instead of `head' to store the font header (using */ + /* the same format). It also doesn't include horizontal and */ + /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */ + /* missing). */ + /* */ + /* The other format comes from Microsoft, and is used with */ + /* WinCE/PocketPC. It looks like a standard TTF, except that */ + /* it doesn't contain outlines. */ + /* */ + + FT_TRACE2(( "sfnt_load_face: %08p\n\n", face )); + + /* do we have outlines in there? */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || + tt_face_lookup_table( face, TTAG_glyf ) != 0 || + tt_face_lookup_table( face, TTAG_CFF ) != 0 ); +#else + has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || + tt_face_lookup_table( face, TTAG_CFF ) != 0 ); +#endif + + is_apple_sbit = 0; + + /* if this font doesn't contain outlines, we try to load */ + /* a `bhed' table */ + if ( !has_outline && sfnt->load_bhed ) + { + LOAD_( bhed ); + is_apple_sbit = FT_BOOL( !error ); + } + + /* load the font header (`head' table) if this isn't an Apple */ + /* sbit font file */ + if ( !is_apple_sbit ) + { + LOAD_( head ); + if ( error ) + goto Exit; + } + + if ( face->header.Units_Per_EM == 0 ) + { + error = FT_THROW( Invalid_Table ); + + goto Exit; + } + + /* the following tables are often not present in embedded TrueType */ + /* fonts within PDF documents, so don't check for them. */ + LOAD_( maxp ); + LOAD_( cmap ); + + /* the following tables are optional in PCL fonts -- */ + /* don't check for errors */ + LOAD_( name ); + LOAD_( post ); + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + psnames_error = error; +#endif + + /* do not load the metrics headers and tables if this is an Apple */ + /* sbit font file */ + if ( !is_apple_sbit ) + { + /* load the `hhea' and `hmtx' tables */ + LOADM_( hhea, 0 ); + if ( !error ) + { + LOADM_( hmtx, 0 ); + if ( FT_ERR_EQ( error, Table_Missing ) ) + { + error = FT_THROW( Hmtx_Table_Missing ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* If this is an incrementally loaded font and there are */ + /* overriding metrics, tolerate a missing `hmtx' table. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs-> + get_glyph_metrics ) + { + face->horizontal.number_Of_HMetrics = 0; + error = FT_Err_Ok; + } +#endif + } + } + else if ( FT_ERR_EQ( error, Table_Missing ) ) + { + /* No `hhea' table necessary for SFNT Mac fonts. */ + if ( face->format_tag == TTAG_true ) + { + FT_TRACE2(( "This is an SFNT Mac font.\n" )); + + has_outline = 0; + error = FT_Err_Ok; + } + else + { + error = FT_THROW( Horiz_Header_Missing ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* If this is an incrementally loaded font and there are */ + /* overriding metrics, tolerate a missing `hhea' table. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs-> + get_glyph_metrics ) + { + face->horizontal.number_Of_HMetrics = 0; + error = FT_Err_Ok; + } +#endif + + } + } + + if ( error ) + goto Exit; + + /* try to load the `vhea' and `vmtx' tables */ + LOADM_( hhea, 1 ); + if ( !error ) + { + LOADM_( hmtx, 1 ); + if ( !error ) + face->vertical_info = 1; + } + + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + + LOAD_( os2 ); + if ( error ) + { + /* we treat the table as missing if there are any errors */ + face->os2.version = 0xFFFFU; + } + } + + /* the optional tables */ + + /* embedded bitmap support */ + if ( sfnt->load_eblc ) + { + LOAD_( eblc ); + if ( error ) + { + /* a font which contains neither bitmaps nor outlines is */ + /* still valid (although rather useless in most cases); */ + /* however, you can find such stripped fonts in PDFs */ + if ( FT_ERR_EQ( error, Table_Missing ) ) + error = FT_Err_Ok; + else + goto Exit; + } + } + + LOAD_( pclt ); + if ( error ) + { + if ( FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + + face->pclt.Version = 0; + } + + /* consider the kerning and gasp tables as optional */ + LOAD_( gasp ); + LOAD_( kern ); + + face->root.num_glyphs = face->max_profile.numGlyphs; + + /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ + /* a WWS-only font face. `WWS' stands for `weight', width', and */ + /* `slope', a term used by Microsoft's Windows Presentation */ + /* Foundation (WPF). This flag has been introduced in version */ + /* 1.5 of the OpenType specification (May 2008). */ + + face->root.family_name = NULL; + face->root.style_name = NULL; + if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) + { + if ( !ignore_preferred_family ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( FONT_FAMILY, &face->root.family_name ); + + if ( !ignore_preferred_subfamily ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); + } + else + { + GET_NAME( WWS_FAMILY, &face->root.family_name ); + if ( !face->root.family_name && !ignore_preferred_family ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( FONT_FAMILY, &face->root.family_name ); + + GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name && !ignore_preferred_subfamily ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); + } + + /* now set up root fields */ + { + FT_Face root = &face->root; + FT_Long flags = root->face_flags; + + + /*********************************************************************/ + /* */ + /* Compute face flags. */ + /* */ + if ( has_outline == TRUE ) + flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */ + + /* The sfnt driver only supports bitmap fonts natively, thus we */ + /* don't set FT_FACE_FLAG_HINTER. */ + flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */ + FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + if ( !psnames_error && + face->postscript.FormatType != 0x00030000L ) + flags |= FT_FACE_FLAG_GLYPH_NAMES; +#endif + + /* fixed width font? */ + if ( face->postscript.isFixedPitch ) + flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* vertical information? */ + if ( face->vertical_info ) + flags |= FT_FACE_FLAG_VERTICAL; + + /* kerning available ? */ + if ( TT_FACE_HAS_KERNING( face ) ) + flags |= FT_FACE_FLAG_KERNING; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* Don't bother to load the tables unless somebody asks for them. */ + /* No need to do work which will (probably) not be used. */ + if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && + tt_face_lookup_table( face, TTAG_fvar ) != 0 && + tt_face_lookup_table( face, TTAG_gvar ) != 0 ) + flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; +#endif + + root->face_flags = flags; + + /*********************************************************************/ + /* */ + /* Compute style flags. */ + /* */ + + flags = 0; + if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) + { + /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ + /* indicates an oblique font face. This flag has been */ + /* introduced in version 1.5 of the OpenType specification. */ + + if ( face->os2.fsSelection & 512 ) /* bit 9 */ + flags |= FT_STYLE_FLAG_ITALIC; + else if ( face->os2.fsSelection & 1 ) /* bit 0 */ + flags |= FT_STYLE_FLAG_ITALIC; + + if ( face->os2.fsSelection & 32 ) /* bit 5 */ + flags |= FT_STYLE_FLAG_BOLD; + } + else + { + /* this is an old Mac font, use the header field */ + + if ( face->header.Mac_Style & 1 ) + flags |= FT_STYLE_FLAG_BOLD; + + if ( face->header.Mac_Style & 2 ) + flags |= FT_STYLE_FLAG_ITALIC; + } + + root->style_flags = flags; + + /*********************************************************************/ + /* */ + /* Polish the charmaps. */ + /* */ + /* Try to set the charmap encoding according to the platform & */ + /* encoding ID of each charmap. */ + /* */ + + tt_face_build_cmaps( face ); /* ignore errors */ + + + /* set the encoding fields */ + { + FT_Int m; + + + for ( m = 0; m < root->num_charmaps; m++ ) + { + FT_CharMap charmap = root->charmaps[m]; + + + charmap->encoding = sfnt_find_encoding( charmap->platform_id, + charmap->encoding_id ); + +#if 0 + if ( root->charmap == NULL && + charmap->encoding == FT_ENCODING_UNICODE ) + { + /* set 'root->charmap' to the first Unicode encoding we find */ + root->charmap = charmap; + } +#endif + } + } + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* + * Now allocate the root array of FT_Bitmap_Size records and + * populate them. Unfortunately, it isn't possible to indicate bit + * depths in the FT_Bitmap_Size record. This is a design error. + */ + { + FT_UInt i, count; + + + count = face->sbit_num_strikes; + + if ( count > 0 ) + { + FT_Memory memory = face->root.stream->memory; + FT_UShort em_size = face->header.Units_Per_EM; + FT_Short avgwidth = face->os2.xAvgCharWidth; + FT_Size_Metrics metrics; + + + if ( em_size == 0 || face->os2.version == 0xFFFFU ) + { + avgwidth = 0; + em_size = 1; + } + + if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + goto Exit; + + for ( i = 0; i < count; i++ ) + { + FT_Bitmap_Size* bsize = root->available_sizes + i; + + + error = sfnt->load_strike_metrics( face, i, &metrics ); + if ( error ) + goto Exit; + + bsize->height = (FT_Short)( metrics.height >> 6 ); + bsize->width = (FT_Short)( + ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); + + bsize->x_ppem = metrics.x_ppem << 6; + bsize->y_ppem = metrics.y_ppem << 6; + + /* assume 72dpi */ + bsize->size = metrics.y_ppem << 6; + } + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + root->num_fixed_sizes = (FT_Int)count; + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* a font with no bitmaps and no outlines is scalable; */ + /* it has only empty glyphs then */ + if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) ) + root->face_flags |= FT_FACE_FLAG_SCALABLE; + + + /*********************************************************************/ + /* */ + /* Set up metrics. */ + /* */ + if ( FT_IS_SCALABLE( root ) ) + { + /* XXX What about if outline header is missing */ + /* (e.g. sfnt wrapped bitmap)? */ + root->bbox.xMin = face->header.xMin; + root->bbox.yMin = face->header.yMin; + root->bbox.xMax = face->header.xMax; + root->bbox.yMax = face->header.yMax; + root->units_per_EM = face->header.Units_Per_EM; + + + /* XXX: Computing the ascender/descender/height is very different */ + /* from what the specification tells you. Apparently, we */ + /* must be careful because */ + /* */ + /* - not all fonts have an OS/2 table; in this case, we take */ + /* the values in the horizontal header. However, these */ + /* values very often are not reliable. */ + /* */ + /* - otherwise, the correct typographic values are in the */ + /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */ + /* */ + /* However, certain fonts have these fields set to 0. */ + /* Rather, they have usWinAscent & usWinDescent correctly */ + /* set (but with different values). */ + /* */ + /* As an example, Arial Narrow is implemented through four */ + /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */ + /* */ + /* Strangely, all fonts have the same values in their */ + /* sTypoXXX fields, except ARIALNB which sets them to 0. */ + /* */ + /* On the other hand, they all have different */ + /* usWinAscent/Descent values -- as a conclusion, the OS/2 */ + /* table cannot be used to compute the text height reliably! */ + /* */ + + /* The ascender and descender are taken from the `hhea' table. */ + /* If zero, they are taken from the `OS/2' table. */ + + root->ascender = face->horizontal.Ascender; + root->descender = face->horizontal.Descender; + + root->height = (FT_Short)( root->ascender - root->descender + + face->horizontal.Line_Gap ); + + if ( !( root->ascender || root->descender ) ) + { + if ( face->os2.version != 0xFFFFU ) + { + if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) + { + root->ascender = face->os2.sTypoAscender; + root->descender = face->os2.sTypoDescender; + + root->height = (FT_Short)( root->ascender - root->descender + + face->os2.sTypoLineGap ); + } + else + { + root->ascender = (FT_Short)face->os2.usWinAscent; + root->descender = -(FT_Short)face->os2.usWinDescent; + + root->height = (FT_UShort)( root->ascender - root->descender ); + } + } + } + + root->max_advance_width = face->horizontal.advance_Width_Max; + root->max_advance_height = (FT_Short)( face->vertical_info + ? face->vertical.advance_Height_Max + : root->height ); + + /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ + /* Adjust underline position from top edge to centre of */ + /* stroke to convert TrueType meaning to FreeType meaning. */ + root->underline_position = face->postscript.underlinePosition - + face->postscript.underlineThickness / 2; + root->underline_thickness = face->postscript.underlineThickness; + } + + } + + Exit: + FT_TRACE2(( "sfnt_load_face: done\n" )); + + return error; + } + + +#undef LOAD_ +#undef LOADM_ +#undef GET_NAME + + + FT_LOCAL_DEF( void ) + sfnt_done_face( TT_Face face ) + { + FT_Memory memory; + SFNT_Service sfnt; + + + if ( !face ) + return; + + memory = face->root.memory; + sfnt = (SFNT_Service)face->sfnt; + + if ( sfnt ) + { + /* destroy the postscript names table if it is loaded */ + if ( sfnt->free_psnames ) + sfnt->free_psnames( face ); + + /* destroy the embedded bitmaps table if it is loaded */ + if ( sfnt->free_eblc ) + sfnt->free_eblc( face ); + } + +#ifdef TT_CONFIG_OPTION_BDF + /* freeing the embedded BDF properties */ + tt_face_free_bdf_props( face ); +#endif + + /* freeing the kerning table */ + tt_face_done_kern( face ); + + /* freeing the collection table */ + FT_FREE( face->ttc_header.offsets ); + face->ttc_header.count = 0; + + /* freeing table directory */ + FT_FREE( face->dir_tables ); + face->num_tables = 0; + + { + FT_Stream stream = FT_FACE_STREAM( face ); + + + /* simply release the 'cmap' table frame */ + FT_FRAME_RELEASE( face->cmap_table ); + face->cmap_size = 0; + } + + /* freeing the horizontal metrics */ + { + FT_Stream stream = FT_FACE_STREAM( face ); + + + FT_FRAME_RELEASE( face->horz_metrics ); + FT_FRAME_RELEASE( face->vert_metrics ); + face->horz_metrics_size = 0; + face->vert_metrics_size = 0; + } + + /* freeing the vertical ones, if any */ + if ( face->vertical_info ) + { + FT_FREE( face->vertical.long_metrics ); + FT_FREE( face->vertical.short_metrics ); + face->vertical_info = 0; + } + + /* freeing the gasp table */ + FT_FREE( face->gasp.gaspRanges ); + face->gasp.numRanges = 0; + + /* freeing the name table */ + if ( sfnt ) + sfnt->free_name( face ); + + /* freeing family and style name */ + FT_FREE( face->root.family_name ); + FT_FREE( face->root.style_name ); + + /* freeing sbit size table */ + FT_FREE( face->root.available_sizes ); + face->root.num_fixed_sizes = 0; + + FT_FREE( face->postscript_name ); + + face->sfnt = 0; + } + + +/* END */ diff --git a/drivers/freetype/src/sfnt/sfobjs.h b/drivers/freetype/src/sfnt/sfobjs.h new file mode 100644 index 0000000000..6241c93b39 --- /dev/null +++ b/drivers/freetype/src/sfnt/sfobjs.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* sfobjs.h */ +/* */ +/* SFNT object management (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __SFOBJS_H__ +#define __SFOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + sfnt_init_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( FT_Error ) + sfnt_load_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + sfnt_done_face( TT_Face face ); + + +FT_END_HEADER + +#endif /* __SFDRIVER_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttbdf.c b/drivers/freetype/src/sfnt/ttbdf.c new file mode 100644 index 0000000000..9401dae5f8 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttbdf.c @@ -0,0 +1,250 @@ +/***************************************************************************/ +/* */ +/* ttbdf.c */ +/* */ +/* TrueType and OpenType embedded BDF properties (body). */ +/* */ +/* Copyright 2005, 2006, 2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttbdf.h" + +#include "sferrors.h" + + +#ifdef TT_CONFIG_OPTION_BDF + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttbdf + + + FT_LOCAL_DEF( void ) + tt_face_free_bdf_props( TT_Face face ) + { + TT_BDF bdf = &face->bdf; + + + if ( bdf->loaded ) + { + FT_Stream stream = FT_FACE(face)->stream; + + + if ( bdf->table != NULL ) + FT_FRAME_RELEASE( bdf->table ); + + bdf->table_end = NULL; + bdf->strings = NULL; + bdf->strings_size = 0; + } + } + + + static FT_Error + tt_face_load_bdf_props( TT_Face face, + FT_Stream stream ) + { + TT_BDF bdf = &face->bdf; + FT_ULong length; + FT_Error error; + + + FT_ZERO( bdf ); + + error = tt_face_goto_table( face, TTAG_BDF, stream, &length ); + if ( error || + length < 8 || + FT_FRAME_EXTRACT( length, bdf->table ) ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + bdf->table_end = bdf->table + length; + + { + FT_Byte* p = bdf->table; + FT_UInt version = FT_NEXT_USHORT( p ); + FT_UInt num_strikes = FT_NEXT_USHORT( p ); + FT_ULong strings = FT_NEXT_ULONG ( p ); + FT_UInt count; + FT_Byte* strike; + + + if ( version != 0x0001 || + strings < 8 || + ( strings - 8 ) / 4 < num_strikes || + strings + 1 > length ) + { + goto BadTable; + } + + bdf->num_strikes = num_strikes; + bdf->strings = bdf->table + strings; + bdf->strings_size = length - strings; + + count = bdf->num_strikes; + p = bdf->table + 8; + strike = p + count * 4; + + + for ( ; count > 0; count-- ) + { + FT_UInt num_items = FT_PEEK_USHORT( p + 2 ); + + /* + * We don't need to check the value sets themselves, since this + * is done later. + */ + strike += 10 * num_items; + + p += 4; + } + + if ( strike > bdf->strings ) + goto BadTable; + } + + bdf->loaded = 1; + + Exit: + return error; + + BadTable: + FT_FRAME_RELEASE( bdf->table ); + FT_ZERO( bdf ); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_find_bdf_prop( TT_Face face, + const char* property_name, + BDF_PropertyRec *aprop ) + { + TT_BDF bdf = &face->bdf; + FT_Size size = FT_FACE(face)->size; + FT_Error error = FT_Err_Ok; + FT_Byte* p; + FT_UInt count; + FT_Byte* strike; + FT_Offset property_len; + + + aprop->type = BDF_PROPERTY_TYPE_NONE; + + if ( bdf->loaded == 0 ) + { + error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); + if ( error ) + goto Exit; + } + + count = bdf->num_strikes; + p = bdf->table + 8; + strike = p + 4 * count; + + error = FT_ERR( Invalid_Argument ); + + if ( size == NULL || property_name == NULL ) + goto Exit; + + property_len = ft_strlen( property_name ); + if ( property_len == 0 ) + goto Exit; + + for ( ; count > 0; count-- ) + { + FT_UInt _ppem = FT_NEXT_USHORT( p ); + FT_UInt _count = FT_NEXT_USHORT( p ); + + if ( _ppem == size->metrics.y_ppem ) + { + count = _count; + goto FoundStrike; + } + + strike += 10 * _count; + } + goto Exit; + + FoundStrike: + p = strike; + for ( ; count > 0; count-- ) + { + FT_UInt type = FT_PEEK_USHORT( p + 4 ); + + if ( ( type & 0x10 ) != 0 ) + { + FT_UInt32 name_offset = FT_PEEK_ULONG( p ); + FT_UInt32 value = FT_PEEK_ULONG( p + 6 ); + + /* be a bit paranoid for invalid entries here */ + if ( name_offset < bdf->strings_size && + property_len < bdf->strings_size - name_offset && + ft_strncmp( property_name, + (const char*)bdf->strings + name_offset, + bdf->strings_size - name_offset ) == 0 ) + { + switch ( type & 0x0F ) + { + case 0x00: /* string */ + case 0x01: /* atoms */ + /* check that the content is really 0-terminated */ + if ( value < bdf->strings_size && + ft_memchr( bdf->strings + value, 0, bdf->strings_size ) ) + { + aprop->type = BDF_PROPERTY_TYPE_ATOM; + aprop->u.atom = (const char*)bdf->strings + value; + error = FT_Err_Ok; + goto Exit; + } + break; + + case 0x02: + aprop->type = BDF_PROPERTY_TYPE_INTEGER; + aprop->u.integer = (FT_Int32)value; + error = FT_Err_Ok; + goto Exit; + + case 0x03: + aprop->type = BDF_PROPERTY_TYPE_CARDINAL; + aprop->u.cardinal = value; + error = FT_Err_Ok; + goto Exit; + + default: + ; + } + } + } + p += 10; + } + + Exit: + return error; + } + +#endif /* TT_CONFIG_OPTION_BDF */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttbdf.h b/drivers/freetype/src/sfnt/ttbdf.h new file mode 100644 index 0000000000..48a10d6e9b --- /dev/null +++ b/drivers/freetype/src/sfnt/ttbdf.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* ttbdf.h */ +/* */ +/* TrueType and OpenType embedded BDF properties (specification). */ +/* */ +/* Copyright 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTBDF_H__ +#define __TTBDF_H__ + + +#include <ft2build.h> +#include "ttload.h" +#include FT_BDF_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + tt_face_free_bdf_props( TT_Face face ); + + + FT_LOCAL( FT_Error ) + tt_face_find_bdf_prop( TT_Face face, + const char* property_name, + BDF_PropertyRec *aprop ); + + +FT_END_HEADER + +#endif /* __TTBDF_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttcmap.c b/drivers/freetype/src/sfnt/ttcmap.c new file mode 100644 index 0000000000..1507202ea8 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttcmap.c @@ -0,0 +1,3557 @@ +/***************************************************************************/ +/* */ +/* ttcmap.c */ +/* */ +/* TrueType character mapping table (cmap) support (body). */ +/* */ +/* Copyright 2002-2010, 2012, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include "sferrors.h" /* must come before FT_INTERNAL_VALIDATE_H */ + +#include FT_INTERNAL_VALIDATE_H +#include FT_INTERNAL_STREAM_H +#include "ttload.h" +#include "ttcmap.h" +#include "sfntpic.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_ttcmap + + +#define TT_PEEK_SHORT FT_PEEK_SHORT +#define TT_PEEK_USHORT FT_PEEK_USHORT +#define TT_PEEK_UINT24 FT_PEEK_UOFF3 +#define TT_PEEK_LONG FT_PEEK_LONG +#define TT_PEEK_ULONG FT_PEEK_ULONG + +#define TT_NEXT_SHORT FT_NEXT_SHORT +#define TT_NEXT_USHORT FT_NEXT_USHORT +#define TT_NEXT_UINT24 FT_NEXT_UOFF3 +#define TT_NEXT_LONG FT_NEXT_LONG +#define TT_NEXT_ULONG FT_NEXT_ULONG + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap_init( TT_CMap cmap, + FT_Byte* table ) + { + cmap->data = table; + return FT_Err_Ok; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 0 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 0 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* glyph_ids 6 BYTE[256] array of glyph indices */ + /* 262 */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap0_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; + FT_UInt length = TT_NEXT_USHORT( p ); + + + if ( table + length > valid->limit || length < 262 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices whenever necessary */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt n, idx; + + + p = table + 6; + for ( n = 0; n < 256; n++ ) + { + idx = *p++; + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap0_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + + + return char_code < 256 ? table[6 + char_code] : 0; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap0_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 charcode = *pchar_code; + FT_UInt32 result = 0; + FT_UInt gindex = 0; + + + table += 6; /* go to glyph IDs */ + while ( ++charcode < 256 ) + { + gindex = table[charcode]; + if ( gindex != 0 ) + { + result = charcode; + break; + } + } + + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap0_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->format = 0; + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP( + tt_cmap0_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap0_char_index, + (FT_CMap_CharNextFunc) tt_cmap0_char_next, + + NULL, + NULL, + NULL, + NULL, + NULL, + + 0, + (TT_CMap_ValidateFunc)tt_cmap0_validate, + (TT_CMap_Info_GetFunc)tt_cmap0_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_0 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 2 *****/ + /***** *****/ + /***** This is used for certain CJK encodings that encode text in a *****/ + /***** mixed 8/16 bits encoding along the following lines: *****/ + /***** *****/ + /***** * Certain byte values correspond to an 8-bit character code *****/ + /***** (typically in the range 0..127 for ASCII compatibility). *****/ + /***** *****/ + /***** * Certain byte values signal the first byte of a 2-byte *****/ + /***** character code (but these values are also valid as the *****/ + /***** second byte of a 2-byte character). *****/ + /***** *****/ + /***** The following charmap lookup and iteration functions all *****/ + /***** assume that the value "charcode" correspond to following: *****/ + /***** *****/ + /***** - For one byte characters, "charcode" is simply the *****/ + /***** character code. *****/ + /***** *****/ + /***** - For two byte characters, "charcode" is the 2-byte *****/ + /***** character code in big endian format. More exactly: *****/ + /***** *****/ + /***** (charcode >> 8) is the first byte value *****/ + /***** (charcode & 0xFF) is the second byte value *****/ + /***** *****/ + /***** Note that not all values of "charcode" are valid according *****/ + /***** to these rules, and the function moderately check the *****/ + /***** arguments. *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 2 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* keys 6 USHORT[256] sub-header keys */ + /* subs 518 SUBHEAD[NSUBS] sub-headers array */ + /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ + /* */ + /* The `keys' table is used to map charcode high-bytes to sub-headers. */ + /* The value of `NSUBS' is the number of sub-headers defined in the */ + /* table and is computed by finding the maximum of the `keys' table. */ + /* */ + /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ + /* table, i.e., it is the corresponding sub-header index multiplied */ + /* by 8. */ + /* */ + /* Each sub-header has the following format: */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* first 0 USHORT first valid low-byte */ + /* count 2 USHORT number of valid low-bytes */ + /* delta 4 SHORT see below */ + /* offset 6 USHORT see below */ + /* */ + /* A sub-header defines, for each high-byte, the range of valid */ + /* low-bytes within the charmap. Note that the range defined by `first' */ + /* and `count' must be completely included in the interval [0..255] */ + /* according to the specification. */ + /* */ + /* If a character code is contained within a given sub-header, then */ + /* mapping it to a glyph index is done as follows: */ + /* */ + /* * The value of `offset' is read. This is a _byte_ distance from the */ + /* location of the `offset' field itself into a slice of the */ + /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ + /* */ + /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ + /* no glyph for the charcode. Otherwise, the value of `delta' is */ + /* added to it (modulo 65536) to form a new glyph index. */ + /* */ + /* It is up to the validation routine to check that all offsets fall */ + /* within the glyph IDs table (and not within the `subs' table itself or */ + /* outside of the CMap). */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap2_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; /* skip format */ + FT_UInt length = TT_PEEK_USHORT( p ); + FT_UInt n, max_subs; + FT_Byte* keys; /* keys table */ + FT_Byte* subs; /* sub-headers */ + FT_Byte* glyph_ids; /* glyph ID array */ + + + if ( table + length > valid->limit || length < 6 + 512 ) + FT_INVALID_TOO_SHORT; + + keys = table + 6; + + /* parse keys to compute sub-headers count */ + p = keys; + max_subs = 0; + for ( n = 0; n < 256; n++ ) + { + FT_UInt idx = TT_NEXT_USHORT( p ); + + + /* value must be multiple of 8 */ + if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 ) + FT_INVALID_DATA; + + idx >>= 3; + + if ( idx > max_subs ) + max_subs = idx; + } + + FT_ASSERT( p == table + 518 ); + + subs = p; + glyph_ids = subs + (max_subs + 1) * 8; + if ( glyph_ids > valid->limit ) + FT_INVALID_TOO_SHORT; + + /* parse sub-headers */ + for ( n = 0; n <= max_subs; n++ ) + { + FT_UInt first_code, code_count, offset; + FT_Int delta; + FT_Byte* ids; + + + first_code = TT_NEXT_USHORT( p ); + code_count = TT_NEXT_USHORT( p ); + delta = TT_NEXT_SHORT( p ); + offset = TT_NEXT_USHORT( p ); + + /* many Dynalab fonts have empty sub-headers */ + if ( code_count == 0 ) + continue; + + /* check range within 0..255 */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + if ( first_code >= 256 || first_code + code_count > 256 ) + FT_INVALID_DATA; + } + + /* check offset */ + if ( offset != 0 ) + { + ids = p - 2 + offset; + if ( ids < glyph_ids || ids + code_count*2 > table + length ) + FT_INVALID_OFFSET; + + /* check glyph IDs */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_Byte* limit = p + code_count * 2; + FT_UInt idx; + + + for ( ; p < limit; ) + { + idx = TT_NEXT_USHORT( p ); + if ( idx != 0 ) + { + idx = ( idx + delta ) & 0xFFFFU; + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + } + + return FT_Err_Ok; + } + + + /* return sub header corresponding to a given character code */ + /* NULL on invalid charcode */ + static FT_Byte* + tt_cmap2_get_subheader( FT_Byte* table, + FT_UInt32 char_code ) + { + FT_Byte* result = NULL; + + + if ( char_code < 0x10000UL ) + { + FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); + FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); + FT_Byte* p = table + 6; /* keys table */ + FT_Byte* subs = table + 518; /* subheaders table */ + FT_Byte* sub; + + + if ( char_hi == 0 ) + { + /* an 8-bit character code -- we use subHeader 0 in this case */ + /* to test whether the character code is in the charmap */ + /* */ + sub = subs; /* jump to first sub-header */ + + /* check that the sub-header for this byte is 0, which */ + /* indicates that it is really a valid one-byte value */ + /* Otherwise, return 0 */ + /* */ + p += char_lo * 2; + if ( TT_PEEK_USHORT( p ) != 0 ) + goto Exit; + } + else + { + /* a 16-bit character code */ + + /* jump to key entry */ + p += char_hi * 2; + /* jump to sub-header */ + sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); + + /* check that the high byte isn't a valid one-byte value */ + if ( sub == subs ) + goto Exit; + } + result = sub; + } + Exit: + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap2_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* subheader; + + + subheader = tt_cmap2_get_subheader( table, char_code ); + if ( subheader ) + { + FT_Byte* p = subheader; + FT_UInt idx = (FT_UInt)(char_code & 0xFF); + FT_UInt start, count; + FT_Int delta; + FT_UInt offset; + + + start = TT_NEXT_USHORT( p ); + count = TT_NEXT_USHORT( p ); + delta = TT_NEXT_SHORT ( p ); + offset = TT_PEEK_USHORT( p ); + + idx -= start; + if ( idx < count && offset != 0 ) + { + p += offset + 2 * idx; + idx = TT_PEEK_USHORT( p ); + + if ( idx != 0 ) + result = (FT_UInt)( idx + delta ) & 0xFFFFU; + } + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap2_char_next( TT_CMap cmap, + FT_UInt32 *pcharcode ) + { + FT_Byte* table = cmap->data; + FT_UInt gindex = 0; + FT_UInt32 result = 0; + FT_UInt32 charcode = *pcharcode + 1; + FT_Byte* subheader; + + + while ( charcode < 0x10000UL ) + { + subheader = tt_cmap2_get_subheader( table, charcode ); + if ( subheader ) + { + FT_Byte* p = subheader; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_Int delta = TT_NEXT_SHORT ( p ); + FT_UInt offset = TT_PEEK_USHORT( p ); + FT_UInt char_lo = (FT_UInt)( charcode & 0xFF ); + FT_UInt pos, idx; + + + if ( offset == 0 ) + goto Next_SubHeader; + + if ( char_lo < start ) + { + char_lo = start; + pos = 0; + } + else + pos = (FT_UInt)( char_lo - start ); + + p += offset + pos * 2; + charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; + + for ( ; pos < count; pos++, charcode++ ) + { + idx = TT_NEXT_USHORT( p ); + + if ( idx != 0 ) + { + gindex = ( idx + delta ) & 0xFFFFU; + if ( gindex != 0 ) + { + result = charcode; + goto Exit; + } + } + } + } + + /* jump to next sub-header, i.e. higher byte value */ + Next_SubHeader: + charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; + } + + Exit: + *pcharcode = result; + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap2_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->format = 2; + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP( + tt_cmap2_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap2_char_index, + (FT_CMap_CharNextFunc) tt_cmap2_char_next, + + NULL, + NULL, + NULL, + NULL, + NULL, + + 2, + (TT_CMap_ValidateFunc)tt_cmap2_validate, + (TT_CMap_Info_GetFunc)tt_cmap2_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_2 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 4 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 4 */ + /* length 2 USHORT table length */ + /* in bytes */ + /* language 4 USHORT Mac language code */ + /* */ + /* segCountX2 6 USHORT 2*NUM_SEGS */ + /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */ + /* entrySelector 10 USHORT LOG_SEGS */ + /* rangeShift 12 USHORT segCountX2 - */ + /* searchRange */ + /* */ + /* endCount 14 USHORT[NUM_SEGS] end charcode for */ + /* each segment; last */ + /* is 0xFFFF */ + /* */ + /* pad 14+NUM_SEGS*2 USHORT padding */ + /* */ + /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */ + /* each segment */ + /* */ + /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */ + /* segment */ + /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */ + /* each segment; can be */ + /* zero */ + /* */ + /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ + /* ranges */ + /* */ + /* Character codes are modelled by a series of ordered (increasing) */ + /* intervals called segments. Each segment has start and end codes, */ + /* provided by the `startCount' and `endCount' arrays. Segments must */ + /* not overlap, and the last segment should always contain the value */ + /* 0xFFFF for `endCount'. */ + /* */ + /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ + /* ignored (they are traces of over-engineering in the TrueType */ + /* specification). */ + /* */ + /* Each segment also has a signed `delta', as well as an optional offset */ + /* within the `glyphIds' table. */ + /* */ + /* If a segment's idOffset is 0, the glyph index corresponding to any */ + /* charcode within the segment is obtained by adding the value of */ + /* `idDelta' directly to the charcode, modulo 65536. */ + /* */ + /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ + /* the segment, and the value of `idDelta' is added to it. */ + /* */ + /* */ + /* Finally, note that a lot of fonts contain an invalid last segment, */ + /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ + /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ + /* OpenOffice.org). We need special code to deal with them correctly. */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + + typedef struct TT_CMap4Rec_ + { + TT_CMapRec cmap; + FT_UInt32 cur_charcode; /* current charcode */ + FT_UInt cur_gindex; /* current glyph index */ + + FT_UInt num_ranges; + FT_UInt cur_range; + FT_UInt cur_start; + FT_UInt cur_end; + FT_Int cur_delta; + FT_Byte* cur_values; + + } TT_CMap4Rec, *TT_CMap4; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap4_init( TT_CMap4 cmap, + FT_Byte* table ) + { + FT_Byte* p; + + + cmap->cmap.data = table; + + p = table + 6; + cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; + cmap->cur_gindex = 0; + + return FT_Err_Ok; + } + + + static FT_Int + tt_cmap4_set_range( TT_CMap4 cmap, + FT_UInt range_index ) + { + FT_Byte* table = cmap->cmap.data; + FT_Byte* p; + FT_UInt num_ranges = cmap->num_ranges; + + + while ( range_index < num_ranges ) + { + FT_UInt offset; + + + p = table + 14 + range_index * 2; + cmap->cur_end = FT_PEEK_USHORT( p ); + + p += 2 + num_ranges * 2; + cmap->cur_start = FT_PEEK_USHORT( p ); + + p += num_ranges * 2; + cmap->cur_delta = FT_PEEK_SHORT( p ); + + p += num_ranges * 2; + offset = FT_PEEK_USHORT( p ); + + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( range_index >= num_ranges - 1 && + cmap->cur_start == 0xFFFFU && + cmap->cur_end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + cmap->cur_delta = 1; + offset = 0; + } + } + + if ( offset != 0xFFFFU ) + { + cmap->cur_values = offset ? p + offset : NULL; + cmap->cur_range = range_index; + return 0; + } + + /* we skip empty segments */ + range_index++; + } + + return -1; + } + + + /* search the index of the charcode next to cmap->cur_charcode; */ + /* caller should call tt_cmap4_set_range with proper range */ + /* before calling this function */ + /* */ + static void + tt_cmap4_next( TT_CMap4 cmap ) + { + FT_UInt charcode; + + + if ( cmap->cur_charcode >= 0xFFFFUL ) + goto Fail; + + charcode = (FT_UInt)cmap->cur_charcode + 1; + + if ( charcode < cmap->cur_start ) + charcode = cmap->cur_start; + + for ( ;; ) + { + FT_Byte* values = cmap->cur_values; + FT_UInt end = cmap->cur_end; + FT_Int delta = cmap->cur_delta; + + + if ( charcode <= end ) + { + if ( values ) + { + FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); + + + do + { + FT_UInt gindex = FT_NEXT_USHORT( p ); + + + if ( gindex != 0 ) + { + gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); + if ( gindex != 0 ) + { + cmap->cur_charcode = charcode; + cmap->cur_gindex = gindex; + return; + } + } + } while ( ++charcode <= end ); + } + else + { + do + { + FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); + + + if ( gindex != 0 ) + { + cmap->cur_charcode = charcode; + cmap->cur_gindex = gindex; + return; + } + } while ( ++charcode <= end ); + } + } + + /* we need to find another range */ + if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) + break; + + if ( charcode < cmap->cur_start ) + charcode = cmap->cur_start; + } + + Fail: + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; + cmap->cur_gindex = 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap4_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; /* skip format */ + FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; + FT_UInt num_segs; + FT_Error error = FT_Err_Ok; + + + if ( length < 16 ) + FT_INVALID_TOO_SHORT; + + /* in certain fonts, the `length' field is invalid and goes */ + /* out of bound. We try to correct this here... */ + if ( table + length > valid->limit ) + { + if ( valid->level >= FT_VALIDATE_TIGHT ) + FT_INVALID_TOO_SHORT; + + length = (FT_UInt)( valid->limit - table ); + } + + p = table + 6; + num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ + + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + /* check that we have an even value here */ + if ( num_segs & 1 ) + FT_INVALID_DATA; + } + + num_segs /= 2; + + if ( length < 16 + num_segs * 2 * 4 ) + FT_INVALID_TOO_SHORT; + + /* check the search parameters - even though we never use them */ + /* */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + /* check the values of `searchRange', `entrySelector', `rangeShift' */ + FT_UInt search_range = TT_NEXT_USHORT( p ); + FT_UInt entry_selector = TT_NEXT_USHORT( p ); + FT_UInt range_shift = TT_NEXT_USHORT( p ); + + + if ( ( search_range | range_shift ) & 1 ) /* must be even values */ + FT_INVALID_DATA; + + search_range /= 2; + range_shift /= 2; + + /* `search range' is the greatest power of 2 that is <= num_segs */ + + if ( search_range > num_segs || + search_range * 2 < num_segs || + search_range + range_shift != num_segs || + search_range != ( 1U << entry_selector ) ) + FT_INVALID_DATA; + } + + ends = table + 14; + starts = table + 16 + num_segs * 2; + deltas = starts + num_segs * 2; + offsets = deltas + num_segs * 2; + glyph_ids = offsets + num_segs * 2; + + /* check last segment; its end count value must be 0xFFFF */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + p = ends + ( num_segs - 1 ) * 2; + if ( TT_PEEK_USHORT( p ) != 0xFFFFU ) + FT_INVALID_DATA; + } + + { + FT_UInt start, end, offset, n; + FT_UInt last_start = 0, last_end = 0; + FT_Int delta; + FT_Byte* p_start = starts; + FT_Byte* p_end = ends; + FT_Byte* p_delta = deltas; + FT_Byte* p_offset = offsets; + + + for ( n = 0; n < num_segs; n++ ) + { + p = p_offset; + start = TT_NEXT_USHORT( p_start ); + end = TT_NEXT_USHORT( p_end ); + delta = TT_NEXT_SHORT( p_delta ); + offset = TT_NEXT_USHORT( p_offset ); + + if ( start > end ) + FT_INVALID_DATA; + + /* this test should be performed at default validation level; */ + /* unfortunately, some popular Asian fonts have overlapping */ + /* ranges in their charmaps */ + /* */ + if ( start <= last_end && n > 0 ) + { + if ( valid->level >= FT_VALIDATE_TIGHT ) + FT_INVALID_DATA; + else + { + /* allow overlapping segments, provided their start points */ + /* and end points, respectively, are in ascending order */ + /* */ + if ( last_start > start || last_end > end ) + error |= TT_CMAP_FLAG_UNSORTED; + else + error |= TT_CMAP_FLAG_OVERLAPPING; + } + } + + if ( offset && offset != 0xFFFFU ) + { + p += offset; /* start of glyph ID array */ + + /* check that we point within the glyph IDs table only */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( p < glyph_ids || + p + ( end - start + 1 ) * 2 > table + length ) + FT_INVALID_DATA; + } + /* Some fonts handle the last segment incorrectly. In */ + /* theory, 0xFFFF might point to an ordinary glyph -- */ + /* a cmap 4 is versatile and could be used for any */ + /* encoding, not only Unicode. However, reality shows */ + /* that far too many fonts are sloppy and incorrectly */ + /* set all fields but `start' and `end' for the last */ + /* segment if it contains only a single character. */ + /* */ + /* We thus omit the test here, delaying it to the */ + /* routines which actually access the cmap. */ + else if ( n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU ) ) + { + if ( p < glyph_ids || + p + ( end - start + 1 ) * 2 > valid->limit ) + FT_INVALID_DATA; + } + + /* check glyph indices within the segment range */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt i, idx; + + + for ( i = start; i < end; i++ ) + { + idx = FT_NEXT_USHORT( p ); + if ( idx != 0 ) + { + idx = (FT_UInt)( idx + delta ) & 0xFFFFU; + + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + else if ( offset == 0xFFFFU ) + { + /* some fonts (erroneously?) use a range offset of 0xFFFF */ + /* to mean missing glyph in cmap table */ + /* */ + if ( valid->level >= FT_VALIDATE_PARANOID || + n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU ) ) + FT_INVALID_DATA; + } + + last_start = start; + last_end = end; + } + } + + return error; + } + + + static FT_UInt + tt_cmap4_char_map_linear( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) + { + FT_UInt num_segs2, start, end, offset; + FT_Int delta; + FT_UInt i, num_segs; + FT_UInt32 charcode = *pcharcode; + FT_UInt gindex = 0; + FT_Byte* p; + + + p = cmap->data + 6; + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); + + num_segs = num_segs2 >> 1; + + if ( !num_segs ) + return 0; + + if ( next ) + charcode++; + + /* linear search */ + for ( ; charcode <= 0xFFFFU; charcode++ ) + { + FT_Byte* q; + + + p = cmap->data + 14; /* ends table */ + q = cmap->data + 16 + num_segs2; /* starts table */ + + for ( i = 0; i < num_segs; i++ ) + { + end = TT_NEXT_USHORT( p ); + start = TT_NEXT_USHORT( q ); + + if ( charcode >= start && charcode <= end ) + { + p = q - 2 + num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( i >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + delta = 1; + offset = 0; + } + } + + if ( offset == 0xFFFFU ) + continue; + + if ( offset ) + { + p += offset + ( charcode - start ) * 2; + gindex = TT_PEEK_USHORT( p ); + if ( gindex != 0 ) + gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + } + else + gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; + + break; + } + } + + if ( !next || gindex ) + break; + } + + if ( next && gindex ) + *pcharcode = charcode; + + return gindex; + } + + + static FT_UInt + tt_cmap4_char_map_binary( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) + { + FT_UInt num_segs2, start, end, offset; + FT_Int delta; + FT_UInt max, min, mid, num_segs; + FT_UInt charcode = (FT_UInt)*pcharcode; + FT_UInt gindex = 0; + FT_Byte* p; + + + p = cmap->data + 6; + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); + + if ( !num_segs2 ) + return 0; + + num_segs = num_segs2 >> 1; + + /* make compiler happy */ + mid = num_segs; + end = 0xFFFFU; + + if ( next ) + charcode++; + + min = 0; + max = num_segs; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 14 + mid * 2; + end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + + if ( charcode < start ) + max = mid; + else if ( charcode > end ) + min = mid + 1; + else + { + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( mid >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + delta = 1; + offset = 0; + } + } + + /* search the first segment containing `charcode' */ + if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) + { + FT_UInt i; + + + /* call the current segment `max' */ + max = mid; + + if ( offset == 0xFFFFU ) + mid = max + 1; + + /* search in segments before the current segment */ + for ( i = max ; i > 0; i-- ) + { + FT_UInt prev_end; + FT_Byte* old_p; + + + old_p = p; + p = cmap->data + 14 + ( i - 1 ) * 2; + prev_end = TT_PEEK_USHORT( p ); + + if ( charcode > prev_end ) + { + p = old_p; + break; + } + + end = prev_end; + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset != 0xFFFFU ) + mid = i - 1; + } + + /* no luck */ + if ( mid == max + 1 ) + { + if ( i != max ) + { + p = cmap->data + 14 + max * 2; + end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + } + + mid = max; + + /* search in segments after the current segment */ + for ( i = max + 1; i < num_segs; i++ ) + { + FT_UInt next_end, next_start; + + + p = cmap->data + 14 + i * 2; + next_end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + next_start = TT_PEEK_USHORT( p ); + + if ( charcode < next_start ) + break; + + end = next_end; + start = next_start; + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset != 0xFFFFU ) + mid = i; + } + i--; + + /* still no luck */ + if ( mid == max ) + { + mid = i; + + break; + } + } + + /* end, start, delta, and offset are for the i'th segment */ + if ( mid != i ) + { + p = cmap->data + 14 + mid * 2; + end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + } + } + else + { + if ( offset == 0xFFFFU ) + break; + } + + if ( offset ) + { + p += offset + ( charcode - start ) * 2; + gindex = TT_PEEK_USHORT( p ); + if ( gindex != 0 ) + gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + } + else + gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; + + break; + } + } + + if ( next ) + { + TT_CMap4 cmap4 = (TT_CMap4)cmap; + + + /* if `charcode' is not in any segment, then `mid' is */ + /* the segment nearest to `charcode' */ + /* */ + + if ( charcode > end ) + { + mid++; + if ( mid == num_segs ) + return 0; + } + + if ( tt_cmap4_set_range( cmap4, mid ) ) + { + if ( gindex ) + *pcharcode = charcode; + } + else + { + cmap4->cur_charcode = charcode; + + if ( gindex ) + cmap4->cur_gindex = gindex; + else + { + cmap4->cur_charcode = charcode; + tt_cmap4_next( cmap4 ); + gindex = cmap4->cur_gindex; + } + + if ( gindex ) + *pcharcode = cmap4->cur_charcode; + } + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap4_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + if ( char_code >= 0x10000UL ) + return 0; + + if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) + return tt_cmap4_char_map_linear( cmap, &char_code, 0 ); + else + return tt_cmap4_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap4_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt gindex; + + + if ( *pchar_code >= 0xFFFFU ) + return 0; + + if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) + gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 ); + else + { + TT_CMap4 cmap4 = (TT_CMap4)cmap; + + + /* no need to search */ + if ( *pchar_code == cmap4->cur_charcode ) + { + tt_cmap4_next( cmap4 ); + gindex = cmap4->cur_gindex; + if ( gindex ) + *pchar_code = cmap4->cur_charcode; + } + else + gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 ); + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap4_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->format = 4; + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP( + tt_cmap4_class_rec, + sizeof ( TT_CMap4Rec ), + (FT_CMap_InitFunc) tt_cmap4_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap4_char_index, + (FT_CMap_CharNextFunc) tt_cmap4_char_next, + + NULL, + NULL, + NULL, + NULL, + NULL, + + 4, + (TT_CMap_ValidateFunc)tt_cmap4_validate, + (TT_CMap_Info_GetFunc)tt_cmap4_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_4 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 6 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 4 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* */ + /* first 6 USHORT first segment code */ + /* count 8 USHORT segment size in chars */ + /* glyphIds 10 USHORT[count] glyph IDs */ + /* */ + /* A very simplified segment mapping. */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap6_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_UInt length, count; + + + if ( table + 10 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; + length = TT_NEXT_USHORT( p ); + + p = table + 8; /* skip language and start index */ + count = TT_NEXT_USHORT( p ); + + if ( table + length > valid->limit || length < 10 + count * 2 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt gindex; + + + for ( ; count > 0; count-- ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap6_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 6; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_UInt idx = (FT_UInt)( char_code - start ); + + + if ( idx < count ) + { + p += 2 * idx; + result = TT_PEEK_USHORT( p ); + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap6_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + + FT_Byte* p = table + 6; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_UInt idx; + + + if ( char_code >= 0x10000UL ) + goto Exit; + + if ( char_code < start ) + char_code = start; + + idx = (FT_UInt)( char_code - start ); + p += 2 * idx; + + for ( ; idx < count; idx++ ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + { + result = char_code; + break; + } + char_code++; + } + + Exit: + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap6_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->format = 6; + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP( + tt_cmap6_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap6_char_index, + (FT_CMap_CharNextFunc) tt_cmap6_char_next, + + NULL, + NULL, + NULL, + NULL, + NULL, + + 6, + (TT_CMap_ValidateFunc)tt_cmap6_validate, + (TT_CMap_Info_GetFunc)tt_cmap6_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_6 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 8 *****/ + /***** *****/ + /***** It is hard to completely understand what the OpenType spec *****/ + /***** says about this format, but here is my conclusion. *****/ + /***** *****/ + /***** The purpose of this format is to easily map UTF-16 text to *****/ + /***** glyph indices. Basically, the `char_code' must be in one of *****/ + /***** the following formats: *****/ + /***** *****/ + /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ + /***** Area (i.e. U+D800-U+DFFF). *****/ + /***** *****/ + /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ + /***** `char_code = (char_hi << 16) | char_lo', then both *****/ + /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ + /***** Area. *****/ + /***** *****/ + /***** The `is32' table embedded in the charmap indicates whether a *****/ + /***** given 16-bit value is in the surrogates area or not. *****/ + /***** *****/ + /***** So, for any given `char_code', we can assert the following: *****/ + /***** *****/ + /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ + /***** *****/ + /***** If `char_hi != 0' then we must have both *****/ + /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 8 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* is32 12 BYTE[8192] 32-bitness bitmap */ + /* count 8204 ULONG number of groups */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* startId 8 ULONG start glyph ID for the group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap8_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 4; + FT_Byte* is32; + FT_UInt32 length; + FT_UInt32 num_groups; + + + if ( table + 16 + 8192 > valid->limit ) + FT_INVALID_TOO_SHORT; + + length = TT_NEXT_ULONG( p ); + if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) + FT_INVALID_TOO_SHORT; + + is32 = table + 12; + p = is32 + 8192; /* skip `is32' array */ + num_groups = TT_NEXT_ULONG( p ); + + if ( p + num_groups * 12 > valid->limit ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_UInt32 n, start, end, start_id, count, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + FT_UInt hi, lo; + + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + + count = (FT_UInt32)( end - start + 1 ); + + if ( start & ~0xFFFFU ) + { + /* start_hi != 0; check that is32[i] is 1 for each i in */ + /* the `hi' and `lo' of the range [start..end] */ + for ( ; count > 0; count--, start++ ) + { + hi = (FT_UInt)( start >> 16 ); + lo = (FT_UInt)( start & 0xFFFFU ); + + if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 ) + FT_INVALID_DATA; + + if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 ) + FT_INVALID_DATA; + } + } + else + { + /* start_hi == 0; check that is32[i] is 0 for each i in */ + /* the range [start..end] */ + + /* end_hi cannot be != 0! */ + if ( end & ~0xFFFFU ) + FT_INVALID_DATA; + + for ( ; count > 0; count--, start++ ) + { + lo = (FT_UInt)( start & 0xFFFFU ); + + if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 ) + FT_INVALID_DATA; + } + } + } + + last = end; + } + } + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap8_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 8204; + FT_UInt32 num_groups = TT_NEXT_ULONG( p ); + FT_UInt32 start, end, start_id; + + + for ( ; num_groups > 0; num_groups-- ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + break; + + if ( char_code <= end ) + { + result = (FT_UInt)( start_id + char_code - start ); + break; + } + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap8_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + FT_Byte* table = cmap->data; + FT_Byte* p = table + 8204; + FT_UInt32 num_groups = TT_NEXT_ULONG( p ); + FT_UInt32 start, end, start_id; + + + p = table + 8208; + + for ( ; num_groups > 0; num_groups-- ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)( char_code - start + start_id ); + if ( gindex != 0 ) + { + result = char_code; + goto Exit; + } + } + } + + Exit: + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap8_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 8; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return FT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP( + tt_cmap8_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap8_char_index, + (FT_CMap_CharNextFunc) tt_cmap8_char_next, + + NULL, + NULL, + NULL, + NULL, + NULL, + + 8, + (TT_CMap_ValidateFunc)tt_cmap8_validate, + (TT_CMap_Info_GetFunc)tt_cmap8_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_8 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 10 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 10 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* */ + /* start 12 ULONG first char in range */ + /* count 16 ULONG number of chars in range */ + /* glyphIds 20 USHORT[count] glyph indices covered */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap10_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 4; + FT_ULong length, count; + + + if ( table + 20 > valid->limit ) + FT_INVALID_TOO_SHORT; + + length = TT_NEXT_ULONG( p ); + p = table + 16; + count = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 20 + count * 2 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt gindex; + + + for ( ; count > 0; count-- ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap10_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 12; + FT_UInt32 start = TT_NEXT_ULONG( p ); + FT_UInt32 count = TT_NEXT_ULONG( p ); + FT_UInt32 idx = (FT_ULong)( char_code - start ); + + + if ( idx < count ) + { + p += 2 * idx; + result = TT_PEEK_USHORT( p ); + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap10_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + FT_Byte* p = table + 12; + FT_UInt32 start = TT_NEXT_ULONG( p ); + FT_UInt32 count = TT_NEXT_ULONG( p ); + FT_UInt32 idx; + + + if ( char_code < start ) + char_code = start; + + idx = (FT_UInt32)( char_code - start ); + p += 2 * idx; + + for ( ; idx < count; idx++ ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + break; + char_code++; + } + + *pchar_code = char_code; + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap10_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 10; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return FT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP( + tt_cmap10_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap10_char_index, + (FT_CMap_CharNextFunc) tt_cmap10_char_next, + + NULL, + NULL, + NULL, + NULL, + NULL, + + 10, + (TT_CMap_ValidateFunc)tt_cmap10_validate, + (TT_CMap_Info_GetFunc)tt_cmap10_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_10 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 12 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 12 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* startId 8 ULONG start glyph ID for the group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + + typedef struct TT_CMap12Rec_ + { + TT_CMapRec cmap; + FT_Bool valid; + FT_ULong cur_charcode; + FT_UInt cur_gindex; + FT_ULong cur_group; + FT_ULong num_groups; + + } TT_CMap12Rec, *TT_CMap12; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap12_init( TT_CMap12 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 12; + cmap->num_groups = FT_PEEK_ULONG( table ); + + cmap->valid = 0; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap12_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, start_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + + return FT_Err_Ok; + } + + + /* search the index of the charcode next to cmap->cur_charcode */ + /* cmap->cur_group should be set up properly by caller */ + /* */ + static void + tt_cmap12_next( TT_CMap12 cmap ) + { + FT_Byte* p; + FT_ULong start, end, start_id, char_code; + FT_ULong n; + FT_UInt gindex; + + + if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) + goto Fail; + + char_code = cmap->cur_charcode + 1; + + n = cmap->cur_group; + + for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + { + p = cmap->cmap.data + 16 + 12 * n; + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_PEEK_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + for ( ; char_code <= end; char_code++ ) + { + gindex = (FT_UInt)( start_id + char_code - start ); + + if ( gindex ) + { + cmap->cur_charcode = char_code;; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; + } + } + } + + Fail: + cmap->valid = 0; + } + + + static FT_UInt + tt_cmap12_char_map_binary( TT_CMap cmap, + FT_UInt32* pchar_code, + FT_Bool next ) + { + FT_UInt gindex = 0; + FT_Byte* p = cmap->data + 12; + FT_UInt32 num_groups = TT_PEEK_ULONG( p ); + FT_UInt32 char_code = *pchar_code; + FT_UInt32 start, end, start_id; + FT_UInt32 max, min, mid; + + + if ( !num_groups ) + return 0; + + /* make compiler happy */ + mid = num_groups; + end = 0xFFFFFFFFUL; + + if ( next ) + char_code++; + + min = 0; + max = num_groups; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 16 + 12 * mid; + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + max = mid; + else if ( char_code > end ) + min = mid + 1; + else + { + start_id = TT_PEEK_ULONG( p ); + gindex = (FT_UInt)( start_id + char_code - start ); + + break; + } + } + + if ( next ) + { + TT_CMap12 cmap12 = (TT_CMap12)cmap; + + + /* if `char_code' is not in any group, then `mid' is */ + /* the group nearest to `char_code' */ + /* */ + + if ( char_code > end ) + { + mid++; + if ( mid == num_groups ) + return 0; + } + + cmap12->valid = 1; + cmap12->cur_charcode = char_code; + cmap12->cur_group = mid; + + if ( !gindex ) + { + tt_cmap12_next( cmap12 ); + + if ( cmap12->valid ) + gindex = cmap12->cur_gindex; + } + else + cmap12->cur_gindex = gindex; + + if ( gindex ) + *pchar_code = cmap12->cur_charcode; + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap12_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap12_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + TT_CMap12 cmap12 = (TT_CMap12)cmap; + FT_ULong gindex; + + + if ( cmap12->cur_charcode >= 0xFFFFFFFFUL ) + return 0; + + /* no need to search */ + if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) + { + tt_cmap12_next( cmap12 ); + if ( cmap12->valid ) + { + gindex = cmap12->cur_gindex; + + /* XXX: check cur_charcode overflow is expected */ + if ( gindex ) + *pchar_code = (FT_UInt32)cmap12->cur_charcode; + } + else + gindex = 0; + } + else + gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); + + /* XXX: check gindex overflow is expected */ + return (FT_UInt32)gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap12_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 12; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return FT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP( + tt_cmap12_class_rec, + sizeof ( TT_CMap12Rec ), + + (FT_CMap_InitFunc) tt_cmap12_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap12_char_index, + (FT_CMap_CharNextFunc) tt_cmap12_char_next, + + NULL, + NULL, + NULL, + NULL, + NULL, + + 12, + (TT_CMap_ValidateFunc)tt_cmap12_validate, + (TT_CMap_Info_GetFunc)tt_cmap12_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_12 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 13 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 13 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* glyphId 8 ULONG glyph ID for the whole group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + + typedef struct TT_CMap13Rec_ + { + TT_CMapRec cmap; + FT_Bool valid; + FT_ULong cur_charcode; + FT_UInt cur_gindex; + FT_ULong cur_group; + FT_ULong num_groups; + + } TT_CMap13Rec, *TT_CMap13; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_init( TT_CMap13 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 12; + cmap->num_groups = FT_PEEK_ULONG( table ); + + cmap->valid = 0; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, glyph_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + + return FT_Err_Ok; + } + + + /* search the index of the charcode next to cmap->cur_charcode */ + /* cmap->cur_group should be set up properly by caller */ + /* */ + static void + tt_cmap13_next( TT_CMap13 cmap ) + { + FT_Byte* p; + FT_ULong start, end, glyph_id, char_code; + FT_ULong n; + FT_UInt gindex; + + + if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) + goto Fail; + + char_code = cmap->cur_charcode + 1; + + n = cmap->cur_group; + + for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + { + p = cmap->cmap.data + 16 + 12 * n; + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_PEEK_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)glyph_id; + + if ( gindex ) + { + cmap->cur_charcode = char_code;; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; + } + } + } + + Fail: + cmap->valid = 0; + } + + + static FT_UInt + tt_cmap13_char_map_binary( TT_CMap cmap, + FT_UInt32* pchar_code, + FT_Bool next ) + { + FT_UInt gindex = 0; + FT_Byte* p = cmap->data + 12; + FT_UInt32 num_groups = TT_PEEK_ULONG( p ); + FT_UInt32 char_code = *pchar_code; + FT_UInt32 start, end; + FT_UInt32 max, min, mid; + + + if ( !num_groups ) + return 0; + + /* make compiler happy */ + mid = num_groups; + end = 0xFFFFFFFFUL; + + if ( next ) + char_code++; + + min = 0; + max = num_groups; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 16 + 12 * mid; + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + max = mid; + else if ( char_code > end ) + min = mid + 1; + else + { + gindex = (FT_UInt)TT_PEEK_ULONG( p ); + + break; + } + } + + if ( next ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + + + /* if `char_code' is not in any group, then `mid' is */ + /* the group nearest to `char_code' */ + + if ( char_code > end ) + { + mid++; + if ( mid == num_groups ) + return 0; + } + + cmap13->valid = 1; + cmap13->cur_charcode = char_code; + cmap13->cur_group = mid; + + if ( !gindex ) + { + tt_cmap13_next( cmap13 ); + + if ( cmap13->valid ) + gindex = cmap13->cur_gindex; + } + else + cmap13->cur_gindex = gindex; + + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap13_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap13_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + FT_UInt gindex; + + + if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) + return 0; + + /* no need to search */ + if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) + { + tt_cmap13_next( cmap13 ); + if ( cmap13->valid ) + { + gindex = cmap13->cur_gindex; + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + else + gindex = 0; + } + else + gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 13; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return FT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP( + tt_cmap13_class_rec, + sizeof ( TT_CMap13Rec ), + + (FT_CMap_InitFunc) tt_cmap13_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap13_char_index, + (FT_CMap_CharNextFunc) tt_cmap13_char_next, + + NULL, + NULL, + NULL, + NULL, + NULL, + + 13, + (TT_CMap_ValidateFunc)tt_cmap13_validate, + (TT_CMap_Info_GetFunc)tt_cmap13_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_13 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 14 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 14 */ + /* length 2 ULONG table length in bytes */ + /* numSelector 6 ULONG number of variation sel. records */ + /* */ + /* Followed by numSelector records, each of which looks like */ + /* */ + /* varSelector 0 UINT24 Unicode codepoint of sel. */ + /* defaultOff 3 ULONG offset to a default UVS table */ + /* describing any variants to be found in */ + /* the normal Unicode subtable. */ + /* nonDefOff 7 ULONG offset to a non-default UVS table */ + /* describing any variants not in the */ + /* standard cmap, with GIDs here */ + /* (either offset may be 0 NULL) */ + /* */ + /* Selectors are sorted by code point. */ + /* */ + /* A default Unicode Variation Selector (UVS) subtable is just a list of */ + /* ranges of code points which are to be found in the standard cmap. No */ + /* glyph IDs (GIDs) here. */ + /* */ + /* numRanges 0 ULONG number of ranges following */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* additionalCnt 3 UBYTE count of additional characters in this */ + /* range (zero means a range of a single */ + /* character) */ + /* */ + /* Ranges are sorted by `uniStart'. */ + /* */ + /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ + /* mappings from codepoint to GID. */ + /* */ + /* numMappings 0 ULONG number of mappings */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* GID 3 USHORT and its GID */ + /* */ + /* Ranges are sorted by `uniStart'. */ + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + + typedef struct TT_CMap14Rec_ + { + TT_CMapRec cmap; + FT_ULong num_selectors; + + /* This array is used to store the results of various + * cmap 14 query functions. The data is overwritten + * on each call to these functions. + */ + FT_UInt32 max_results; + FT_UInt32* results; + FT_Memory memory; + + } TT_CMap14Rec, *TT_CMap14; + + + FT_CALLBACK_DEF( void ) + tt_cmap14_done( TT_CMap14 cmap ) + { + FT_Memory memory = cmap->memory; + + + cmap->max_results = 0; + if ( memory != NULL && cmap->results != NULL ) + FT_FREE( cmap->results ); + } + + + static FT_Error + tt_cmap14_ensure( TT_CMap14 cmap, + FT_UInt32 num_results, + FT_Memory memory ) + { + FT_UInt32 old_max = cmap->max_results; + FT_Error error = FT_Err_Ok; + + + if ( num_results > cmap->max_results ) + { + cmap->memory = memory; + + if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) + return error; + + cmap->max_results = num_results; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_init( TT_CMap14 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 6; + cmap->num_selectors = FT_PEEK_ULONG( table ); + cmap->max_results = 0; + cmap->results = NULL; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; + FT_ULong length = TT_NEXT_ULONG( p ); + FT_ULong num_selectors = TT_NEXT_ULONG( p ); + + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 10 + 11 * num_selectors ) + FT_INVALID_TOO_SHORT; + + /* check selectors, they must be in increasing order */ + { + /* we start lastVarSel at 1 because a variant selector value of 0 + * isn't valid. + */ + FT_ULong n, lastVarSel = 1; + + + for ( n = 0; n < num_selectors; n++ ) + { + FT_ULong varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( defOff >= length || nondefOff >= length ) + FT_INVALID_TOO_SHORT; + + if ( varSel < lastVarSel ) + FT_INVALID_DATA; + + lastVarSel = varSel + 1; + + /* check the default table (these glyphs should be reached */ + /* through the normal Unicode cmap, no GIDs, just check order) */ + if ( defOff != 0 ) + { + FT_Byte* defp = table + defOff; + FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_ULong i; + FT_ULong lastBase = 0; + + + if ( defp + numRanges * 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numRanges; ++i ) + { + FT_ULong base = TT_NEXT_UINT24( defp ); + FT_ULong cnt = FT_NEXT_BYTE( defp ); + + + if ( base + cnt >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( base < lastBase ) + FT_INVALID_DATA; + + lastBase = base + cnt + 1U; + } + } + + /* and the non-default table (these glyphs are specified here) */ + if ( nondefOff != 0 ) + { + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings = TT_NEXT_ULONG( ndp ); + FT_ULong i, lastUni = 0; + + + if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numMappings; ++i ) + { + FT_ULong uni = TT_NEXT_UINT24( ndp ); + FT_ULong gid = TT_NEXT_USHORT( ndp ); + + + if ( uni >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( uni < lastUni ) + FT_INVALID_DATA; + + lastUni = uni + 1U; + + if ( valid->level >= FT_VALIDATE_TIGHT && + gid >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UNUSED( cmap ); + FT_UNUSED( char_code ); + + /* This can't happen */ + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap14_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UNUSED( cmap ); + + /* This can't happen */ + *pchar_code = 0; + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_UNUSED( cmap ); + + cmap_info->format = 14; + /* subtable 14 does not define a language field */ + cmap_info->language = 0xFFFFFFFFUL; + + return FT_Err_Ok; + } + + + static FT_UInt + tt_cmap14_char_map_def_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numRanges = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numRanges; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 4 * mid; + FT_ULong start = TT_NEXT_UINT24( p ); + FT_UInt cnt = FT_NEXT_BYTE( p ); + + + if ( char_code < start ) + max = mid; + else if ( char_code > start+cnt ) + min = mid + 1; + else + return TRUE; + } + + return FALSE; + } + + + static FT_UInt + tt_cmap14_char_map_nondef_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numMappings = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numMappings; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 5 * mid; + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); + + + if ( char_code < uni ) + max = mid; + else if ( char_code > uni ) + min = mid + 1; + else + return TT_PEEK_USHORT( p ); + } + + return 0; + } + + + static FT_Byte* + tt_cmap14_find_variant( FT_Byte *base, + FT_UInt32 variantCode ) + { + FT_UInt32 numVar = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numVar; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 11 * mid; + FT_ULong varSel = TT_NEXT_UINT24( p ); + + + if ( variantCode < varSel ) + max = mid; + else if ( variantCode > varSel ) + min = mid + 1; + else + return p; + } + + return NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_var_index( TT_CMap cmap, + TT_CMap ucmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector ) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return 0; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_PEEK_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + { + /* This is the default variant of this charcode. GID not stored */ + /* here; stored in the normal Unicode charmap instead. */ + return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); + } + + if ( nondefOff != 0 ) + return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ); + + return 0; + } + + + FT_CALLBACK_DEF( FT_Int ) + tt_cmap14_char_var_isdefault( TT_CMap cmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector ) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return -1; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + return 1; + + if ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ) != 0 ) + return 0; + + return -1; + } + + + FT_CALLBACK_DEF( FT_UInt32* ) + tt_cmap14_variants( TT_CMap cmap, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14)cmap; + FT_UInt32 count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* result; + FT_UInt32 i; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + result = cmap14->results; + for ( i = 0; i < count; ++i ) + { + result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 8; + } + result[i] = 0; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_char_variants( TT_CMap cmap, + FT_Memory memory, + FT_UInt32 charCode ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* q; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; count > 0; --count ) + { + FT_UInt32 varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, + charCode ) ) || + ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charCode ) != 0 ) ) + { + q[0] = varSel; + q++; + } + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt + tt_cmap14_def_char_count( FT_Byte *p ) + { + FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); + FT_UInt tot = 0; + + + p += 3; /* point to the first `cnt' field */ + for ( ; numRanges > 0; numRanges-- ) + { + tot += 1 + p[0]; + p += 4; + } + + return tot; + } + + + static FT_UInt32* + tt_cmap14_get_def_chars( TT_CMap cmap, + FT_Byte* p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt cnt; + FT_UInt32* q; + + + cnt = tt_cmap14_def_char_count( p ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; numRanges > 0; --numRanges ) + { + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); + + + cnt = FT_NEXT_BYTE( p ) + 1; + do + { + q[0] = uni; + uni += 1; + q += 1; + + } while ( --cnt != 0 ); + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt32* + tt_cmap14_get_nondef_chars( TT_CMap cmap, + FT_Byte *p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numMappings; + FT_UInt i; + FT_UInt32 *ret; + + + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + for ( i = 0; i < numMappings; ++i ) + { + ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + } + ret[i] = 0; + + return ret; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_variant_chars( TT_CMap cmap, + FT_Memory memory, + FT_UInt32 variantSelector ) + { + FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, + variantSelector ); + FT_UInt32 *ret; + FT_Int i; + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return NULL; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff == 0 && nondefOff == 0 ) + return NULL; + + if ( defOff == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + else if ( nondefOff == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + else + { + /* Both a default and a non-default glyph set? That's probably not */ + /* good font design, but the spec allows for it... */ + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt32 numMappings; + FT_UInt32 duni; + FT_UInt32 dcnt; + FT_UInt32 nuni; + FT_Byte* dp; + FT_UInt di, ni, k; + + + p = cmap->data + nondefOff; + dp = cmap->data + defOff; + + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); + dcnt = tt_cmap14_def_char_count( dp ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); + + if ( numMappings == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + if ( dcnt == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + + if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + di = 1; + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + ni = 1; + i = 0; + + for ( ;; ) + { + if ( nuni > duni + dcnt ) + { + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + ++di; + + if ( di > numRanges ) + break; + + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + } + else + { + if ( nuni < duni ) + ret[i++] = nuni; + /* If it is within the default range then ignore it -- */ + /* that should not have happened */ + ++ni; + if ( ni > numMappings ) + break; + + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + } + } + + if ( ni <= numMappings ) + { + /* If we get here then we have run out of all default ranges. */ + /* We have read one non-default mapping which we haven't stored */ + /* and there may be others that need to be read. */ + ret[i++] = nuni; + while ( ni < numMappings ) + { + ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + ++ni; + } + } + else if ( di <= numRanges ) + { + /* If we get here then we have run out of all non-default */ + /* mappings. We have read one default range which we haven't */ + /* stored and there may be others that need to be read. */ + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + while ( di < numRanges ) + { + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + ++di; + } + } + + ret[i] = 0; + + return ret; + } + } + + + FT_DEFINE_TT_CMAP( + tt_cmap14_class_rec, + sizeof ( TT_CMap14Rec ), + + (FT_CMap_InitFunc) tt_cmap14_init, + (FT_CMap_DoneFunc) tt_cmap14_done, + (FT_CMap_CharIndexFunc)tt_cmap14_char_index, + (FT_CMap_CharNextFunc) tt_cmap14_char_next, + + /* Format 14 extension functions */ + (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, + (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, + (FT_CMap_VariantListFunc) tt_cmap14_variants, + (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, + (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, + + 14, + (TT_CMap_ValidateFunc)tt_cmap14_validate, + (TT_CMap_Info_GetFunc)tt_cmap14_get_info ) + +#endif /* TT_CONFIG_CMAP_FORMAT_14 */ + + +#ifndef FT_CONFIG_OPTION_PIC + + static const TT_CMap_Class tt_cmap_classes[] = + { +#define TTCMAPCITEM( a ) &a, +#include "ttcmapc.h" + NULL, + }; + +#else /*FT_CONFIG_OPTION_PIC*/ + + void + FT_Destroy_Class_tt_cmap_classes( FT_Library library, + TT_CMap_Class* clazz ) + { + FT_Memory memory = library->memory; + + + if ( clazz ) + FT_FREE( clazz ); + } + + + FT_Error + FT_Create_Class_tt_cmap_classes( FT_Library library, + TT_CMap_Class** output_class ) + { + TT_CMap_Class* clazz = NULL; + TT_CMap_ClassRec* recs; + FT_Error error; + FT_Memory memory = library->memory; + + int i = 0; + + +#define TTCMAPCITEM( a ) i++; +#include "ttcmapc.h" + + /* allocate enough space for both the pointers */ + /* plus terminator and the class instances */ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * ( i + 1 ) + + sizeof ( TT_CMap_ClassRec ) * i ) ) + return error; + + /* the location of the class instances follows the array of pointers */ + recs = (TT_CMap_ClassRec*)( (char*)clazz + + sizeof ( *clazz ) * ( i + 1 ) ); + i = 0; + +#undef TTCMAPCITEM +#define TTCMAPCITEM( a ) \ + FT_Init_Class_ ## a( &recs[i] ); \ + clazz[i] = &recs[i]; \ + i++; +#include "ttcmapc.h" + + clazz[i] = NULL; + + *output_class = clazz; + return FT_Err_Ok; + } + +#endif /*FT_CONFIG_OPTION_PIC*/ + + + /* parse the `cmap' table and build the corresponding TT_CMap objects */ + /* in the current face */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_build_cmaps( TT_Face face ) + { + FT_Byte* table = face->cmap_table; + FT_Byte* limit = table + face->cmap_size; + FT_UInt volatile num_cmaps; + FT_Byte* volatile p = table; + FT_Library library = FT_FACE_LIBRARY( face ); + + FT_UNUSED( library ); + + + if ( !p || p + 4 > limit ) + return FT_THROW( Invalid_Table ); + + /* only recognize format 0 */ + if ( TT_NEXT_USHORT( p ) != 0 ) + { + p -= 2; + FT_ERROR(( "tt_face_build_cmaps:" + " unsupported `cmap' table format = %d\n", + TT_PEEK_USHORT( p ) )); + return FT_THROW( Invalid_Table ); + } + + num_cmaps = TT_NEXT_USHORT( p ); + +#ifdef FT_MAX_CHARMAP_CACHEABLE + if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE ) + FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n" + " subtable #%d and higher are loaded" + " but cannot be searched\n", + num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 )); +#endif + + for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) + { + FT_CharMapRec charmap; + FT_UInt32 offset; + + + charmap.platform_id = TT_NEXT_USHORT( p ); + charmap.encoding_id = TT_NEXT_USHORT( p ); + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; /* will be filled later */ + offset = TT_NEXT_ULONG( p ); + + if ( offset && offset <= face->cmap_size - 2 ) + { + FT_Byte* volatile cmap = table + offset; + volatile FT_UInt format = TT_PEEK_USHORT( cmap ); + const TT_CMap_Class* volatile pclazz = TT_CMAP_CLASSES_GET; + TT_CMap_Class volatile clazz; + + + for ( ; *pclazz; pclazz++ ) + { + clazz = *pclazz; + if ( clazz->format == format ) + { + volatile TT_ValidatorRec valid; + volatile FT_Error error = FT_Err_Ok; + + + ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, + FT_VALIDATE_DEFAULT ); + + valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs; + + if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 ) + { + /* validate this cmap sub-table */ + error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); + } + + if ( valid.validator.error == 0 ) + { + FT_CMap ttcmap; + + + /* It might make sense to store the single variation */ + /* selector cmap somewhere special. But it would have to be */ + /* in the public FT_FaceRec, and we can't change that. */ + + if ( !FT_CMap_New( (FT_CMap_Class)clazz, + cmap, &charmap, &ttcmap ) ) + { + /* it is simpler to directly set `flags' than adding */ + /* a parameter to FT_CMap_New */ + ((TT_CMap)ttcmap)->flags = (FT_Int)error; + } + } + else + { + FT_TRACE0(( "tt_face_build_cmaps:" + " broken cmap sub-table ignored\n" )); + } + break; + } + } + + if ( *pclazz == NULL ) + { + FT_TRACE0(( "tt_face_build_cmaps:" + " unsupported cmap sub-table ignored\n" )); + } + } + } + + return FT_Err_Ok; + } + + + FT_LOCAL( FT_Error ) + tt_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ) + { + FT_CMap cmap = (FT_CMap)charmap; + TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; + + + return clazz->get_cmap_info( charmap, cmap_info ); + } + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttcmap.h b/drivers/freetype/src/sfnt/ttcmap.h new file mode 100644 index 0000000000..0fde1676bf --- /dev/null +++ b/drivers/freetype/src/sfnt/ttcmap.h @@ -0,0 +1,158 @@ +/***************************************************************************/ +/* */ +/* ttcmap.h */ +/* */ +/* TrueType character mapping table (cmap) support (specification). */ +/* */ +/* Copyright 2002-2005, 2009, 2012 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 __TTCMAP_H__ +#define __TTCMAP_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_VALIDATE_H +#include FT_SERVICE_TT_CMAP_H + +FT_BEGIN_HEADER + + +#define TT_CMAP_FLAG_UNSORTED 1 +#define TT_CMAP_FLAG_OVERLAPPING 2 + + typedef struct TT_CMapRec_ + { + FT_CMapRec cmap; + FT_Byte* data; /* pointer to in-memory cmap table */ + FT_Int flags; /* for format 4 only */ + + } TT_CMapRec, *TT_CMap; + + typedef const struct TT_CMap_ClassRec_* TT_CMap_Class; + + + typedef FT_Error + (*TT_CMap_ValidateFunc)( FT_Byte* data, + FT_Validator valid ); + + typedef struct TT_CMap_ClassRec_ + { + FT_CMap_ClassRec clazz; + FT_UInt format; + TT_CMap_ValidateFunc validate; + TT_CMap_Info_GetFunc get_cmap_info; + + } TT_CMap_ClassRec; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_TT_CMAP( class_, \ + size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_, \ + format_, \ + validate_, \ + get_cmap_info_ ) \ + FT_CALLBACK_TABLE_DEF \ + const TT_CMap_ClassRec class_ = \ + { \ + { size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_ \ + }, \ + \ + format_, \ + validate_, \ + get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_TT_CMAP( class_, \ + size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_, \ + format_, \ + validate_, \ + get_cmap_info_ ) \ + void \ + FT_Init_Class_ ## class_( TT_CMap_ClassRec* clazz ) \ + { \ + clazz->clazz.size = size_; \ + clazz->clazz.init = init_; \ + clazz->clazz.done = done_; \ + clazz->clazz.char_index = char_index_; \ + clazz->clazz.char_next = char_next_; \ + clazz->clazz.char_var_index = char_var_index_; \ + clazz->clazz.char_var_default = char_var_default_; \ + clazz->clazz.variant_list = variant_list_; \ + clazz->clazz.charvariant_list = charvariant_list_; \ + clazz->clazz.variantchar_list = variantchar_list_; \ + clazz->format = format_; \ + clazz->validate = validate_; \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + typedef struct TT_ValidatorRec_ + { + FT_ValidatorRec validator; + FT_UInt num_glyphs; + + } TT_ValidatorRec, *TT_Validator; + + +#define TT_VALIDATOR( x ) ( (TT_Validator)( x ) ) +#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs + + + FT_LOCAL( FT_Error ) + tt_face_build_cmaps( TT_Face face ); + + /* used in tt-cmaps service */ + FT_LOCAL( FT_Error ) + tt_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + + +FT_END_HEADER + +#endif /* __TTCMAP_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttcmapc.h b/drivers/freetype/src/sfnt/ttcmapc.h new file mode 100644 index 0000000000..2ea204309c --- /dev/null +++ b/drivers/freetype/src/sfnt/ttcmapc.h @@ -0,0 +1,56 @@ +/***************************************************************************/ +/* */ +/* ttcmapc.h */ +/* */ +/* TT CMAP classes definitions (specification only). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + TTCMAPCITEM( tt_cmap0_class_rec ) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + TTCMAPCITEM( tt_cmap2_class_rec ) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + TTCMAPCITEM( tt_cmap4_class_rec ) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + TTCMAPCITEM( tt_cmap6_class_rec ) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + TTCMAPCITEM( tt_cmap8_class_rec ) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + TTCMAPCITEM( tt_cmap10_class_rec ) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + TTCMAPCITEM( tt_cmap12_class_rec ) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + TTCMAPCITEM( tt_cmap13_class_rec ) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + TTCMAPCITEM( tt_cmap14_class_rec ) +#endif + + + /* END */ diff --git a/drivers/freetype/src/sfnt/ttkern.c b/drivers/freetype/src/sfnt/ttkern.c new file mode 100644 index 0000000000..60ee546d79 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttkern.c @@ -0,0 +1,306 @@ +/***************************************************************************/ +/* */ +/* ttkern.c */ +/* */ +/* Load the basic TrueType kerning table. This doesn't handle */ +/* kerning data within the GPOS table at the moment. */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttkern.h" + +#include "sferrors.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_ttkern + + +#undef TT_KERN_INDEX +#define TT_KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_kern( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_ULong table_size; + FT_Byte* p; + FT_Byte* p_limit; + FT_UInt nn, num_tables; + FT_UInt32 avail = 0, ordered = 0; + + + /* the kern table is optional; exit silently if it is missing */ + error = face->goto_table( face, TTAG_kern, stream, &table_size ); + if ( error ) + goto Exit; + + if ( table_size < 4 ) /* the case of a malformed table */ + { + FT_ERROR(( "tt_face_load_kern:" + " kerning table is too small - ignored\n" )); + error = FT_THROW( Table_Missing ); + goto Exit; + } + + if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) ) + { + FT_ERROR(( "tt_face_load_kern:" + " could not extract kerning table\n" )); + goto Exit; + } + + face->kern_table_size = table_size; + + p = face->kern_table; + p_limit = p + table_size; + + p += 2; /* skip version */ + num_tables = FT_NEXT_USHORT( p ); + + if ( num_tables > 32 ) /* we only support up to 32 sub-tables */ + num_tables = 32; + + for ( nn = 0; nn < num_tables; nn++ ) + { + FT_UInt num_pairs, length, coverage; + FT_Byte* p_next; + FT_UInt32 mask = (FT_UInt32)1UL << nn; + + + if ( p + 6 > p_limit ) + break; + + p_next = p; + + p += 2; /* skip version */ + length = FT_NEXT_USHORT( p ); + coverage = FT_NEXT_USHORT( p ); + + if ( length <= 6 ) + break; + + p_next += length; + + if ( p_next > p_limit ) /* handle broken table */ + p_next = p_limit; + + /* only use horizontal kerning tables */ + if ( ( coverage & ~8 ) != 0x0001 || + p + 8 > p_limit ) + goto NextTable; + + num_pairs = FT_NEXT_USHORT( p ); + p += 6; + + if ( ( p_next - p ) < 6 * (int)num_pairs ) /* handle broken count */ + num_pairs = (FT_UInt)( ( p_next - p ) / 6 ); + + avail |= mask; + + /* + * Now check whether the pairs in this table are ordered. + * We then can use binary search. + */ + if ( num_pairs > 0 ) + { + FT_ULong count; + FT_ULong old_pair; + + + old_pair = FT_NEXT_ULONG( p ); + p += 2; + + for ( count = num_pairs - 1; count > 0; count-- ) + { + FT_UInt32 cur_pair; + + + cur_pair = FT_NEXT_ULONG( p ); + if ( cur_pair <= old_pair ) + break; + + p += 2; + old_pair = cur_pair; + } + + if ( count == 0 ) + ordered |= mask; + } + + NextTable: + p = p_next; + } + + face->num_kern_tables = nn; + face->kern_avail_bits = avail; + face->kern_order_bits = ordered; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + tt_face_done_kern( TT_Face face ) + { + FT_Stream stream = face->root.stream; + + + FT_FRAME_RELEASE( face->kern_table ); + face->kern_table_size = 0; + face->num_kern_tables = 0; + face->kern_avail_bits = 0; + face->kern_order_bits = 0; + } + + + FT_LOCAL_DEF( FT_Int ) + tt_face_get_kerning( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph ) + { + FT_Int result = 0; + FT_UInt count, mask = 1; + FT_Byte* p = face->kern_table; + FT_Byte* p_limit = p + face->kern_table_size; + + + p += 4; + mask = 0x0001; + + for ( count = face->num_kern_tables; + count > 0 && p + 6 <= p_limit; + count--, mask <<= 1 ) + { + FT_Byte* base = p; + FT_Byte* next = base; + FT_UInt version = FT_NEXT_USHORT( p ); + FT_UInt length = FT_NEXT_USHORT( p ); + FT_UInt coverage = FT_NEXT_USHORT( p ); + FT_UInt num_pairs; + FT_Int value = 0; + + FT_UNUSED( version ); + + + next = base + length; + + if ( next > p_limit ) /* handle broken table */ + next = p_limit; + + if ( ( face->kern_avail_bits & mask ) == 0 ) + goto NextTable; + + if ( p + 8 > next ) + goto NextTable; + + num_pairs = FT_NEXT_USHORT( p ); + p += 6; + + if ( ( next - p ) < 6 * (int)num_pairs ) /* handle broken count */ + num_pairs = (FT_UInt)( ( next - p ) / 6 ); + + switch ( coverage >> 8 ) + { + case 0: + { + FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); + + + if ( face->kern_order_bits & mask ) /* binary search */ + { + FT_UInt min = 0; + FT_UInt max = num_pairs; + + + while ( min < max ) + { + FT_UInt mid = ( min + max ) >> 1; + FT_Byte* q = p + 6 * mid; + FT_ULong key; + + + key = FT_NEXT_ULONG( q ); + + if ( key == key0 ) + { + value = FT_PEEK_SHORT( q ); + goto Found; + } + if ( key < key0 ) + min = mid + 1; + else + max = mid; + } + } + else /* linear search */ + { + FT_UInt count2; + + + for ( count2 = num_pairs; count2 > 0; count2-- ) + { + FT_ULong key = FT_NEXT_ULONG( p ); + + + if ( key == key0 ) + { + value = FT_PEEK_SHORT( p ); + goto Found; + } + p += 2; + } + } + } + break; + + /* + * We don't support format 2 because we haven't seen a single font + * using it in real life... + */ + + default: + ; + } + + goto NextTable; + + Found: + if ( coverage & 8 ) /* override or add */ + result = value; + else + result += value; + + NextTable: + p = next; + } + + return result; + } + +#undef TT_KERN_INDEX + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttkern.h b/drivers/freetype/src/sfnt/ttkern.h new file mode 100644 index 0000000000..df1da9b273 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttkern.h @@ -0,0 +1,52 @@ +/***************************************************************************/ +/* */ +/* ttkern.h */ +/* */ +/* Load the basic TrueType kerning table. This doesn't handle */ +/* kerning data within the GPOS table at the moment. */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 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 __TTKERN_H__ +#define __TTKERN_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_kern( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_done_kern( TT_Face face ); + + FT_LOCAL( FT_Int ) + tt_face_get_kerning( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph ); + +#define TT_FACE_HAS_KERNING( face ) ( (face)->kern_avail_bits != 0 ) + + +FT_END_HEADER + +#endif /* __TTKERN_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttload.c b/drivers/freetype/src/sfnt/ttload.c new file mode 100644 index 0000000000..fbe70f7974 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttload.c @@ -0,0 +1,1269 @@ +/***************************************************************************/ +/* */ +/* ttload.c */ +/* */ +/* Load the basic TrueType tables, i.e., tables that can be either in */ +/* TTF or OTF fonts (body). */ +/* */ +/* Copyright 1996-2010, 2012, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttload.h" + +#include "sferrors.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_ttload + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_lookup_table */ + /* */ + /* <Description> */ + /* Looks for a TrueType table by name. */ + /* */ + /* <Input> */ + /* face :: A face object handle. */ + /* */ + /* tag :: The searched tag. */ + /* */ + /* <Return> */ + /* A pointer to the table directory entry. 0 if not found. */ + /* */ + FT_LOCAL_DEF( TT_Table ) + tt_face_lookup_table( TT_Face face, + FT_ULong tag ) + { + TT_Table entry; + TT_Table limit; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool zero_length = FALSE; +#endif + + + FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ", + face, + (FT_Char)( tag >> 24 ), + (FT_Char)( tag >> 16 ), + (FT_Char)( tag >> 8 ), + (FT_Char)( tag ) )); + + entry = face->dir_tables; + limit = entry + face->num_tables; + + for ( ; entry < limit; entry++ ) + { + /* For compatibility with Windows, we consider */ + /* zero-length tables the same as missing tables. */ + if ( entry->Tag == tag ) + { + if ( entry->Length != 0 ) + { + FT_TRACE4(( "found table.\n" )); + return entry; + } +#ifdef FT_DEBUG_LEVEL_TRACE + zero_length = TRUE; +#endif + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( zero_length ) + FT_TRACE4(( "ignoring empty table\n" )); + else + FT_TRACE4(( "could not find table\n" )); +#endif + + return NULL; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_goto_table */ + /* */ + /* <Description> */ + /* Looks for a TrueType table by name, then seek a stream to it. */ + /* */ + /* <Input> */ + /* face :: A face object handle. */ + /* */ + /* tag :: The searched tag. */ + /* */ + /* stream :: The stream to seek when the table is found. */ + /* */ + /* <Output> */ + /* length :: The length of the table if found, undefined otherwise. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_goto_table( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ) + { + TT_Table table; + FT_Error error; + + + table = tt_face_lookup_table( face, tag ); + if ( table ) + { + if ( length ) + *length = table->Length; + + if ( FT_STREAM_SEEK( table->Offset ) ) + goto Exit; + } + else + error = FT_THROW( Table_Missing ); + + Exit: + return error; + } + + + /* Here, we */ + /* */ + /* - check that `num_tables' is valid (and adjust it if necessary) */ + /* */ + /* - look for a `head' table, check its size, and parse it to check */ + /* whether its `magic' field is correctly set */ + /* */ + /* - errors (except errors returned by stream handling) */ + /* */ + /* SFNT_Err_Unknown_File_Format: */ + /* no table is defined in directory, it is not sfnt-wrapped */ + /* data */ + /* SFNT_Err_Table_Missing: */ + /* table directory is valid, but essential tables */ + /* (head/bhed/SING) are missing */ + /* */ + static FT_Error + check_table_dir( SFNT_Header sfnt, + FT_Stream stream ) + { + FT_Error error; + FT_UShort nn, valid_entries = 0; + FT_UInt has_head = 0, has_sing = 0, has_meta = 0; + FT_ULong offset = sfnt->offset + 12; + + static const FT_Frame_Field table_dir_entry_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_TableRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG( Tag ), + FT_FRAME_ULONG( CheckSum ), + FT_FRAME_ULONG( Offset ), + FT_FRAME_ULONG( Length ), + FT_FRAME_END + }; + + + if ( FT_STREAM_SEEK( offset ) ) + goto Exit; + + for ( nn = 0; nn < sfnt->num_tables; nn++ ) + { + TT_TableRec table; + + + if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) ) + { + nn--; + FT_TRACE2(( "check_table_dir:" + " can read only %d table%s in font (instead of %d)\n", + nn, nn == 1 ? "" : "s", sfnt->num_tables )); + sfnt->num_tables = nn; + break; + } + + /* we ignore invalid tables */ + if ( table.Offset + table.Length > stream->size ) + { + FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); + continue; + } + else + valid_entries++; + + if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) + { + FT_UInt32 magic; + + +#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + if ( table.Tag == TTAG_head ) +#endif + has_head = 1; + + /* + * The table length should be 0x36, but certain font tools make it + * 0x38, so we will just check that it is greater. + * + * Note that according to the specification, the table must be + * padded to 32-bit lengths, but this doesn't apply to the value of + * its `Length' field! + * + */ + if ( table.Length < 0x36 ) + { + FT_TRACE2(( "check_table_dir: `head' table too small\n" )); + error = FT_THROW( Table_Missing ); + goto Exit; + } + + if ( FT_STREAM_SEEK( table.Offset + 12 ) || + FT_READ_ULONG( magic ) ) + goto Exit; + + if ( magic != 0x5F0F3CF5UL ) + { + FT_TRACE2(( "check_table_dir:" + " no magic number found in `head' table\n")); + error = FT_THROW( Table_Missing ); + goto Exit; + } + + if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) + goto Exit; + } + else if ( table.Tag == TTAG_SING ) + has_sing = 1; + else if ( table.Tag == TTAG_META ) + has_meta = 1; + } + + sfnt->num_tables = valid_entries; + + if ( sfnt->num_tables == 0 ) + { + FT_TRACE2(( "check_table_dir: no tables found\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* if `sing' and `meta' tables are present, there is no `head' table */ + if ( has_head || ( has_sing && has_meta ) ) + { + error = FT_Err_Ok; + goto Exit; + } + else + { + FT_TRACE2(( "check_table_dir:" )); +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" )); +#else + FT_TRACE2(( " neither `head' nor `sing' table found\n" )); +#endif + error = FT_THROW( Table_Missing ); + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_font_dir */ + /* */ + /* <Description> */ + /* Loads the header of a SFNT font file. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the beginning of the font directory. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_font_dir( TT_Face face, + FT_Stream stream ) + { + SFNT_HeaderRec sfnt; + FT_Error error; + FT_Memory memory = stream->memory; + TT_TableRec* entry; + FT_Int nn; + + static const FT_Frame_Field offset_table_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE SFNT_HeaderRec + + FT_FRAME_START( 8 ), + FT_FRAME_USHORT( num_tables ), + FT_FRAME_USHORT( search_range ), + FT_FRAME_USHORT( entry_selector ), + FT_FRAME_USHORT( range_shift ), + FT_FRAME_END + }; + + + FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face )); + + /* read the offset table */ + + sfnt.offset = FT_STREAM_POS(); + + if ( FT_READ_ULONG( sfnt.format_tag ) || + FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) ) + goto Exit; + + /* many fonts don't have these fields set correctly */ +#if 0 + if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) || + sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 ) + return FT_THROW( Unknown_File_Format ); +#endif + + /* load the table directory */ + + FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables )); + FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag )); + + if ( sfnt.format_tag != TTAG_OTTO ) + { + /* check first */ + error = check_table_dir( &sfnt, stream ); + if ( error ) + { + FT_TRACE2(( "tt_face_load_font_dir:" + " invalid table directory for TrueType\n" )); + + goto Exit; + } + } + + face->num_tables = sfnt.num_tables; + face->format_tag = sfnt.format_tag; + + if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) + goto Exit; + + if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || + FT_FRAME_ENTER( face->num_tables * 16L ) ) + goto Exit; + + entry = face->dir_tables; + + FT_TRACE2(( "\n" + " tag offset length checksum\n" + " ----------------------------------\n" )); + + for ( nn = 0; nn < sfnt.num_tables; nn++ ) + { + entry->Tag = FT_GET_TAG4(); + entry->CheckSum = FT_GET_ULONG(); + entry->Offset = FT_GET_LONG(); + entry->Length = FT_GET_LONG(); + + /* ignore invalid tables */ + if ( entry->Offset + entry->Length > stream->size ) + continue; + else + { + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n", + (FT_Char)( entry->Tag >> 24 ), + (FT_Char)( entry->Tag >> 16 ), + (FT_Char)( entry->Tag >> 8 ), + (FT_Char)( entry->Tag ), + entry->Offset, + entry->Length, + entry->CheckSum )); + entry++; + } + } + + FT_FRAME_EXIT(); + + FT_TRACE2(( "table directory loaded\n\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_any */ + /* */ + /* <Description> */ + /* Loads any font table into client memory. */ + /* */ + /* <Input> */ + /* face :: The face object to look for. */ + /* */ + /* tag :: The tag of table to load. Use the value 0 if you want */ + /* to access the whole font file, else set this parameter */ + /* to a valid TrueType table tag that you can forge with */ + /* the MAKE_TT_TAG macro. */ + /* */ + /* offset :: The starting offset in the table (or the file if */ + /* tag == 0). */ + /* */ + /* length :: The address of the decision variable: */ + /* */ + /* If length == NULL: */ + /* Loads the whole table. Returns an error if */ + /* `offset' == 0! */ + /* */ + /* If *length == 0: */ + /* Exits immediately; returning the length of the given */ + /* table or of the font file, depending on the value of */ + /* `tag'. */ + /* */ + /* If *length != 0: */ + /* Loads the next `length' bytes of table or font, */ + /* starting at offset `offset' (in table or font too). */ + /* */ + /* <Output> */ + /* buffer :: The address of target buffer. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_any( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) + { + FT_Error error; + FT_Stream stream; + TT_Table table; + FT_ULong size; + + + if ( tag != 0 ) + { + /* look for tag in font directory */ + table = tt_face_lookup_table( face, tag ); + if ( !table ) + { + error = FT_THROW( Table_Missing ); + goto Exit; + } + + offset += table->Offset; + size = table->Length; + } + else + /* tag == 0 -- the user wants to access the font file directly */ + size = face->root.stream->size; + + if ( length && *length == 0 ) + { + *length = size; + + return FT_Err_Ok; + } + + if ( length ) + size = *length; + + stream = face->root.stream; + /* the `if' is syntactic sugar for picky compilers */ + if ( FT_STREAM_READ_AT( offset, buffer, size ) ) + goto Exit; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_generic_header */ + /* */ + /* <Description> */ + /* Loads the TrueType table `head' or `bhed'. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_face_load_generic_header( TT_Face face, + FT_Stream stream, + FT_ULong tag ) + { + FT_Error error; + TT_Header* header; + + static const FT_Frame_Field header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_Header + + FT_FRAME_START( 54 ), + FT_FRAME_ULONG ( Table_Version ), + FT_FRAME_ULONG ( Font_Revision ), + FT_FRAME_LONG ( CheckSum_Adjust ), + FT_FRAME_LONG ( Magic_Number ), + FT_FRAME_USHORT( Flags ), + FT_FRAME_USHORT( Units_Per_EM ), + FT_FRAME_LONG ( Created[0] ), + FT_FRAME_LONG ( Created[1] ), + FT_FRAME_LONG ( Modified[0] ), + FT_FRAME_LONG ( Modified[1] ), + FT_FRAME_SHORT ( xMin ), + FT_FRAME_SHORT ( yMin ), + FT_FRAME_SHORT ( xMax ), + FT_FRAME_SHORT ( yMax ), + FT_FRAME_USHORT( Mac_Style ), + FT_FRAME_USHORT( Lowest_Rec_PPEM ), + FT_FRAME_SHORT ( Font_Direction ), + FT_FRAME_SHORT ( Index_To_Loc_Format ), + FT_FRAME_SHORT ( Glyph_Data_Format ), + FT_FRAME_END + }; + + + error = face->goto_table( face, tag, stream, 0 ); + if ( error ) + goto Exit; + + header = &face->header; + + if ( FT_STREAM_READ_FIELDS( header_fields, header ) ) + goto Exit; + + FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM )); + FT_TRACE3(( "IndexToLoc: %4d\n", header->Index_To_Loc_Format )); + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_head( TT_Face face, + FT_Stream stream ) + { + return tt_face_load_generic_header( face, stream, TTAG_head ); + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_bhed( TT_Face face, + FT_Stream stream ) + { + return tt_face_load_generic_header( face, stream, TTAG_bhed ); + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_max_profile */ + /* */ + /* <Description> */ + /* Loads the maximum profile into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_maxp( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_MaxProfile* maxProfile = &face->max_profile; + + static const FT_Frame_Field maxp_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_MaxProfile + + FT_FRAME_START( 6 ), + FT_FRAME_LONG ( version ), + FT_FRAME_USHORT( numGlyphs ), + FT_FRAME_END + }; + + static const FT_Frame_Field maxp_fields_extra[] = + { + FT_FRAME_START( 26 ), + FT_FRAME_USHORT( maxPoints ), + FT_FRAME_USHORT( maxContours ), + FT_FRAME_USHORT( maxCompositePoints ), + FT_FRAME_USHORT( maxCompositeContours ), + FT_FRAME_USHORT( maxZones ), + FT_FRAME_USHORT( maxTwilightPoints ), + FT_FRAME_USHORT( maxStorage ), + FT_FRAME_USHORT( maxFunctionDefs ), + FT_FRAME_USHORT( maxInstructionDefs ), + FT_FRAME_USHORT( maxStackElements ), + FT_FRAME_USHORT( maxSizeOfInstructions ), + FT_FRAME_USHORT( maxComponentElements ), + FT_FRAME_USHORT( maxComponentDepth ), + FT_FRAME_END + }; + + + error = face->goto_table( face, TTAG_maxp, stream, 0 ); + if ( error ) + goto Exit; + + if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) ) + goto Exit; + + maxProfile->maxPoints = 0; + maxProfile->maxContours = 0; + maxProfile->maxCompositePoints = 0; + maxProfile->maxCompositeContours = 0; + maxProfile->maxZones = 0; + maxProfile->maxTwilightPoints = 0; + maxProfile->maxStorage = 0; + maxProfile->maxFunctionDefs = 0; + maxProfile->maxInstructionDefs = 0; + maxProfile->maxStackElements = 0; + maxProfile->maxSizeOfInstructions = 0; + maxProfile->maxComponentElements = 0; + maxProfile->maxComponentDepth = 0; + + if ( maxProfile->version >= 0x10000L ) + { + if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) ) + goto Exit; + + /* XXX: an adjustment that is necessary to load certain */ + /* broken fonts like `Keystrokes MT' :-( */ + /* */ + /* We allocate 64 function entries by default when */ + /* the maxFunctionDefs value is smaller. */ + + if ( maxProfile->maxFunctionDefs < 64 ) + maxProfile->maxFunctionDefs = 64; + + /* we add 4 phantom points later */ + if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) + { + FT_TRACE0(( "tt_face_load_maxp:" + " too much twilight points in `maxp' table;\n" + " " + " some glyphs might be rendered incorrectly\n" )); + + maxProfile->maxTwilightPoints = 0xFFFFU - 4; + } + + /* we arbitrarily limit recursion to avoid stack exhaustion */ + if ( maxProfile->maxComponentDepth > 100 ) + { + FT_TRACE0(( "tt_face_load_maxp:" + " abnormally large component depth (%d) set to 100\n", + maxProfile->maxComponentDepth )); + maxProfile->maxComponentDepth = 100; + } + } + + FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_name */ + /* */ + /* <Description> */ + /* Loads the name records. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_name( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong table_pos, table_len; + FT_ULong storage_start, storage_limit; + FT_UInt count; + TT_NameTable table; + + static const FT_Frame_Field name_table_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_NameTableRec + + FT_FRAME_START( 6 ), + FT_FRAME_USHORT( format ), + FT_FRAME_USHORT( numNameRecords ), + FT_FRAME_USHORT( storageOffset ), + FT_FRAME_END + }; + + static const FT_Frame_Field name_record_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_NameEntryRec + + /* no FT_FRAME_START */ + FT_FRAME_USHORT( platformID ), + FT_FRAME_USHORT( encodingID ), + FT_FRAME_USHORT( languageID ), + FT_FRAME_USHORT( nameID ), + FT_FRAME_USHORT( stringLength ), + FT_FRAME_USHORT( stringOffset ), + FT_FRAME_END + }; + + + table = &face->name_table; + table->stream = stream; + + error = face->goto_table( face, TTAG_name, stream, &table_len ); + if ( error ) + goto Exit; + + table_pos = FT_STREAM_POS(); + + + if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) ) + goto Exit; + + /* Some popular Asian fonts have an invalid `storageOffset' value */ + /* (it should be at least "6 + 12*num_names"). However, the string */ + /* offsets, computed as "storageOffset + entry->stringOffset", are */ + /* valid pointers within the name table... */ + /* */ + /* We thus can't check `storageOffset' right now. */ + /* */ + storage_start = table_pos + 6 + 12*table->numNameRecords; + storage_limit = table_pos + table_len; + + if ( storage_start > storage_limit ) + { + FT_ERROR(( "tt_face_load_name: invalid `name' table\n" )); + error = FT_THROW( Name_Table_Missing ); + goto Exit; + } + + /* Allocate the array of name records. */ + count = table->numNameRecords; + table->numNameRecords = 0; + + if ( FT_NEW_ARRAY( table->names, count ) || + FT_FRAME_ENTER( count * 12 ) ) + goto Exit; + + /* Load the name records and determine how much storage is needed */ + /* to hold the strings themselves. */ + { + TT_NameEntryRec* entry = table->names; + + + for ( ; count > 0; count-- ) + { + if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) ) + continue; + + /* check that the name is not empty */ + if ( entry->stringLength == 0 ) + continue; + + /* check that the name string is within the table */ + entry->stringOffset += table_pos + table->storageOffset; + if ( entry->stringOffset < storage_start || + entry->stringOffset + entry->stringLength > storage_limit ) + { + /* invalid entry - ignore it */ + entry->stringOffset = 0; + entry->stringLength = 0; + continue; + } + + entry++; + } + + table->numNameRecords = (FT_UInt)( entry - table->names ); + } + + FT_FRAME_EXIT(); + + /* everything went well, update face->num_names */ + face->num_names = (FT_UShort) table->numNameRecords; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_free_names */ + /* */ + /* <Description> */ + /* Frees the name records. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_free_name( TT_Face face ) + { + FT_Memory memory = face->root.driver->root.memory; + TT_NameTable table = &face->name_table; + TT_NameEntry entry = table->names; + FT_UInt count = table->numNameRecords; + + + if ( table->names ) + { + for ( ; count > 0; count--, entry++ ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + + /* free strings table */ + FT_FREE( table->names ); + } + + table->numNameRecords = 0; + table->format = 0; + table->storageOffset = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_cmap */ + /* */ + /* <Description> */ + /* Loads the cmap directory in a face object. The cmaps themselves */ + /* are loaded on demand in the `ttcmap.c' module. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_cmap( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + + + error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size ); + if ( error ) + goto Exit; + + if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) ) + face->cmap_size = 0; + + Exit: + return error; + } + + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_os2 */ + /* */ + /* <Description> */ + /* Loads the OS2 table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_os2( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_OS2* os2; + + static const FT_Frame_Field os2_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_OS2 + + FT_FRAME_START( 78 ), + FT_FRAME_USHORT( version ), + FT_FRAME_SHORT ( xAvgCharWidth ), + FT_FRAME_USHORT( usWeightClass ), + FT_FRAME_USHORT( usWidthClass ), + FT_FRAME_SHORT ( fsType ), + FT_FRAME_SHORT ( ySubscriptXSize ), + FT_FRAME_SHORT ( ySubscriptYSize ), + FT_FRAME_SHORT ( ySubscriptXOffset ), + FT_FRAME_SHORT ( ySubscriptYOffset ), + FT_FRAME_SHORT ( ySuperscriptXSize ), + FT_FRAME_SHORT ( ySuperscriptYSize ), + FT_FRAME_SHORT ( ySuperscriptXOffset ), + FT_FRAME_SHORT ( ySuperscriptYOffset ), + FT_FRAME_SHORT ( yStrikeoutSize ), + FT_FRAME_SHORT ( yStrikeoutPosition ), + FT_FRAME_SHORT ( sFamilyClass ), + FT_FRAME_BYTE ( panose[0] ), + FT_FRAME_BYTE ( panose[1] ), + FT_FRAME_BYTE ( panose[2] ), + FT_FRAME_BYTE ( panose[3] ), + FT_FRAME_BYTE ( panose[4] ), + FT_FRAME_BYTE ( panose[5] ), + FT_FRAME_BYTE ( panose[6] ), + FT_FRAME_BYTE ( panose[7] ), + FT_FRAME_BYTE ( panose[8] ), + FT_FRAME_BYTE ( panose[9] ), + FT_FRAME_ULONG ( ulUnicodeRange1 ), + FT_FRAME_ULONG ( ulUnicodeRange2 ), + FT_FRAME_ULONG ( ulUnicodeRange3 ), + FT_FRAME_ULONG ( ulUnicodeRange4 ), + FT_FRAME_BYTE ( achVendID[0] ), + FT_FRAME_BYTE ( achVendID[1] ), + FT_FRAME_BYTE ( achVendID[2] ), + FT_FRAME_BYTE ( achVendID[3] ), + + FT_FRAME_USHORT( fsSelection ), + FT_FRAME_USHORT( usFirstCharIndex ), + FT_FRAME_USHORT( usLastCharIndex ), + FT_FRAME_SHORT ( sTypoAscender ), + FT_FRAME_SHORT ( sTypoDescender ), + FT_FRAME_SHORT ( sTypoLineGap ), + FT_FRAME_USHORT( usWinAscent ), + FT_FRAME_USHORT( usWinDescent ), + FT_FRAME_END + }; + + static const FT_Frame_Field os2_fields_extra[] = + { + FT_FRAME_START( 8 ), + FT_FRAME_ULONG( ulCodePageRange1 ), + FT_FRAME_ULONG( ulCodePageRange2 ), + FT_FRAME_END + }; + + static const FT_Frame_Field os2_fields_extra2[] = + { + FT_FRAME_START( 10 ), + FT_FRAME_SHORT ( sxHeight ), + FT_FRAME_SHORT ( sCapHeight ), + FT_FRAME_USHORT( usDefaultChar ), + FT_FRAME_USHORT( usBreakChar ), + FT_FRAME_USHORT( usMaxContext ), + FT_FRAME_END + }; + + + /* We now support old Mac fonts where the OS/2 table doesn't */ + /* exist. Simply put, we set the `version' field to 0xFFFF */ + /* and test this value each time we need to access the table. */ + error = face->goto_table( face, TTAG_OS2, stream, 0 ); + if ( error ) + goto Exit; + + os2 = &face->os2; + + if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) ) + goto Exit; + + os2->ulCodePageRange1 = 0; + os2->ulCodePageRange2 = 0; + os2->sxHeight = 0; + os2->sCapHeight = 0; + os2->usDefaultChar = 0; + os2->usBreakChar = 0; + os2->usMaxContext = 0; + + if ( os2->version >= 0x0001 ) + { + /* only version 1 tables */ + if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) ) + goto Exit; + + if ( os2->version >= 0x0002 ) + { + /* only version 2 tables */ + if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) ) + goto Exit; + } + } + + FT_TRACE3(( "sTypoAscender: %4d\n", os2->sTypoAscender )); + FT_TRACE3(( "sTypoDescender: %4d\n", os2->sTypoDescender )); + FT_TRACE3(( "usWinAscent: %4u\n", os2->usWinAscent )); + FT_TRACE3(( "usWinDescent: %4u\n", os2->usWinDescent )); + FT_TRACE3(( "fsSelection: 0x%2x\n", os2->fsSelection )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_postscript */ + /* */ + /* <Description> */ + /* Loads the Postscript table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_post( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_Postscript* post = &face->postscript; + + static const FT_Frame_Field post_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_Postscript + + FT_FRAME_START( 32 ), + FT_FRAME_ULONG( FormatType ), + FT_FRAME_ULONG( italicAngle ), + FT_FRAME_SHORT( underlinePosition ), + FT_FRAME_SHORT( underlineThickness ), + FT_FRAME_ULONG( isFixedPitch ), + FT_FRAME_ULONG( minMemType42 ), + FT_FRAME_ULONG( maxMemType42 ), + FT_FRAME_ULONG( minMemType1 ), + FT_FRAME_ULONG( maxMemType1 ), + FT_FRAME_END + }; + + + error = face->goto_table( face, TTAG_post, stream, 0 ); + if ( error ) + return error; + + if ( FT_STREAM_READ_FIELDS( post_fields, post ) ) + return error; + + /* we don't load the glyph names, we do that in another */ + /* module (ttpost). */ + + FT_TRACE3(( "FormatType: 0x%x\n", post->FormatType )); + FT_TRACE3(( "isFixedPitch: %s\n", post->isFixedPitch + ? " yes" : " no" )); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_pclt */ + /* */ + /* <Description> */ + /* Loads the PCL 5 Table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_pclt( TT_Face face, + FT_Stream stream ) + { + static const FT_Frame_Field pclt_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_PCLT + + FT_FRAME_START( 54 ), + FT_FRAME_ULONG ( Version ), + FT_FRAME_ULONG ( FontNumber ), + FT_FRAME_USHORT( Pitch ), + FT_FRAME_USHORT( xHeight ), + FT_FRAME_USHORT( Style ), + FT_FRAME_USHORT( TypeFamily ), + FT_FRAME_USHORT( CapHeight ), + FT_FRAME_BYTES ( TypeFace, 16 ), + FT_FRAME_BYTES ( CharacterComplement, 8 ), + FT_FRAME_BYTES ( FileName, 6 ), + FT_FRAME_CHAR ( StrokeWeight ), + FT_FRAME_CHAR ( WidthType ), + FT_FRAME_BYTE ( SerifStyle ), + FT_FRAME_BYTE ( Reserved ), + FT_FRAME_END + }; + + FT_Error error; + TT_PCLT* pclt = &face->pclt; + + + /* optional table */ + error = face->goto_table( face, TTAG_PCLT, stream, 0 ); + if ( error ) + goto Exit; + + if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) ) + goto Exit; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_gasp */ + /* */ + /* <Description> */ + /* Loads the `gasp' table into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_gasp( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + FT_UInt j,num_ranges; + TT_GaspRange gaspranges = NULL; + + + /* the gasp table is optional */ + error = face->goto_table( face, TTAG_gasp, stream, 0 ); + if ( error ) + goto Exit; + + if ( FT_FRAME_ENTER( 4L ) ) + goto Exit; + + face->gasp.version = FT_GET_USHORT(); + face->gasp.numRanges = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + /* only support versions 0 and 1 of the table */ + if ( face->gasp.version >= 2 ) + { + face->gasp.numRanges = 0; + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + num_ranges = face->gasp.numRanges; + FT_TRACE3(( "numRanges: %u\n", num_ranges )); + + if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) || + FT_FRAME_ENTER( num_ranges * 4L ) ) + goto Exit; + + gaspranges = face->gasp.gaspRanges; + + for ( j = 0; j < num_ranges; j++ ) + { + gaspranges[j].maxPPEM = FT_GET_USHORT(); + gaspranges[j].gaspFlag = FT_GET_USHORT(); + + FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n", + j, + gaspranges[j].maxPPEM, + gaspranges[j].gaspFlag )); + } + + FT_FRAME_EXIT(); + + Exit: + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttload.h b/drivers/freetype/src/sfnt/ttload.h new file mode 100644 index 0000000000..49a1aee163 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttload.h @@ -0,0 +1,112 @@ +/***************************************************************************/ +/* */ +/* ttload.h */ +/* */ +/* Load the basic TrueType tables, i.e., tables that can be either in */ +/* TTF or OTF fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTLOAD_H__ +#define __TTLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( TT_Table ) + tt_face_lookup_table( TT_Face face, + FT_ULong tag ); + + FT_LOCAL( FT_Error ) + tt_face_goto_table( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ); + + + FT_LOCAL( FT_Error ) + tt_face_load_font_dir( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_any( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + FT_LOCAL( FT_Error ) + tt_face_load_head( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_cmap( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_maxp( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_name( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_os2( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_post( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_pclt( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_name( TT_Face face ); + + + FT_LOCAL( FT_Error ) + tt_face_load_gasp( TT_Face face, + FT_Stream stream ); + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL( FT_Error ) + tt_face_load_bhed( TT_Face face, + FT_Stream stream ); + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + +FT_END_HEADER + +#endif /* __TTLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttmtx.c b/drivers/freetype/src/sfnt/ttmtx.c new file mode 100644 index 0000000000..371a9edabe --- /dev/null +++ b/drivers/freetype/src/sfnt/ttmtx.c @@ -0,0 +1,279 @@ +/***************************************************************************/ +/* */ +/* ttmtx.c */ +/* */ +/* Load the metrics tables common to TTF and OTF fonts (body). */ +/* */ +/* Copyright 2006-2009, 2011-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttmtx.h" + +#include "sferrors.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_ttmtx + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_hmtx */ + /* */ + /* <Description> */ + /* Load the `hmtx' or `vmtx' table into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load `vmtx'. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_hmtx( TT_Face face, + FT_Stream stream, + FT_Bool vertical ) + { + FT_Error error; + FT_ULong tag, table_size; + FT_ULong* ptable_offset; + FT_ULong* ptable_size; + + + if ( vertical ) + { + tag = TTAG_vmtx; + ptable_offset = &face->vert_metrics_offset; + ptable_size = &face->vert_metrics_size; + } + else + { + tag = TTAG_hmtx; + ptable_offset = &face->horz_metrics_offset; + ptable_size = &face->horz_metrics_size; + } + + error = face->goto_table( face, tag, stream, &table_size ); + if ( error ) + goto Fail; + + *ptable_size = table_size; + *ptable_offset = FT_STREAM_POS(); + + Fail: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_hhea */ + /* */ + /* <Description> */ + /* Load the `hhea' or 'vhea' table into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load `vhea'. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_hhea( TT_Face face, + FT_Stream stream, + FT_Bool vertical ) + { + FT_Error error; + TT_HoriHeader* header; + + static const FT_Frame_Field metrics_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_HoriHeader + + FT_FRAME_START( 36 ), + FT_FRAME_ULONG ( Version ), + FT_FRAME_SHORT ( Ascender ), + FT_FRAME_SHORT ( Descender ), + FT_FRAME_SHORT ( Line_Gap ), + FT_FRAME_USHORT( advance_Width_Max ), + FT_FRAME_SHORT ( min_Left_Side_Bearing ), + FT_FRAME_SHORT ( min_Right_Side_Bearing ), + FT_FRAME_SHORT ( xMax_Extent ), + FT_FRAME_SHORT ( caret_Slope_Rise ), + FT_FRAME_SHORT ( caret_Slope_Run ), + FT_FRAME_SHORT ( caret_Offset ), + FT_FRAME_SHORT ( Reserved[0] ), + FT_FRAME_SHORT ( Reserved[1] ), + FT_FRAME_SHORT ( Reserved[2] ), + FT_FRAME_SHORT ( Reserved[3] ), + FT_FRAME_SHORT ( metric_Data_Format ), + FT_FRAME_USHORT( number_Of_HMetrics ), + FT_FRAME_END + }; + + + if ( vertical ) + { + void *v = &face->vertical; + + + error = face->goto_table( face, TTAG_vhea, stream, 0 ); + if ( error ) + goto Fail; + + header = (TT_HoriHeader*)v; + } + else + { + error = face->goto_table( face, TTAG_hhea, stream, 0 ); + if ( error ) + goto Fail; + + header = &face->horizontal; + } + + if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) ) + goto Fail; + + FT_TRACE3(( "Ascender: %5d\n", header->Ascender )); + FT_TRACE3(( "Descender: %5d\n", header->Descender )); + FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics )); + + header->long_metrics = NULL; + header->short_metrics = NULL; + + Fail: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_get_metrics */ + /* */ + /* <Description> */ + /* Returns the horizontal or vertical metrics in font units for a */ + /* given glyph. The metrics are the left side bearing (resp. top */ + /* side bearing) and advance width (resp. advance height). */ + /* */ + /* <Input> */ + /* header :: A pointer to either the horizontal or vertical metrics */ + /* structure. */ + /* */ + /* idx :: The glyph index. */ + /* */ + /* <Output> */ + /* bearing :: The bearing, either left side or top side. */ + /* */ + /* advance :: The advance width resp. advance height. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_get_metrics( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short *abearing, + FT_UShort *aadvance ) + { + FT_Error error; + FT_Stream stream = face->root.stream; + TT_HoriHeader* header; + FT_ULong table_pos, table_size, table_end; + FT_UShort k; + + + if ( vertical ) + { + void* v = &face->vertical; + + + header = (TT_HoriHeader*)v; + table_pos = face->vert_metrics_offset; + table_size = face->vert_metrics_size; + } + else + { + header = &face->horizontal; + table_pos = face->horz_metrics_offset; + table_size = face->horz_metrics_size; + } + + table_end = table_pos + table_size; + + k = header->number_Of_HMetrics; + + if ( k > 0 ) + { + if ( gindex < (FT_UInt)k ) + { + table_pos += 4 * gindex; + if ( table_pos + 4 > table_end ) + goto NoData; + + if ( FT_STREAM_SEEK( table_pos ) || + FT_READ_USHORT( *aadvance ) || + FT_READ_SHORT( *abearing ) ) + goto NoData; + } + else + { + table_pos += 4 * ( k - 1 ); + if ( table_pos + 4 > table_end ) + goto NoData; + + if ( FT_STREAM_SEEK( table_pos ) || + FT_READ_USHORT( *aadvance ) ) + goto NoData; + + table_pos += 4 + 2 * ( gindex - k ); + if ( table_pos + 2 > table_end ) + *abearing = 0; + else + { + if ( !FT_STREAM_SEEK( table_pos ) ) + (void)FT_READ_SHORT( *abearing ); + } + } + } + else + { + NoData: + *abearing = 0; + *aadvance = 0; + } + + return FT_Err_Ok; + } + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttmtx.h b/drivers/freetype/src/sfnt/ttmtx.h new file mode 100644 index 0000000000..8b91a113d8 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttmtx.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ttmtx.h */ +/* */ +/* Load the metrics tables common to TTF and OTF fonts (specification). */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTMTX_H__ +#define __TTMTX_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_hhea( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + FT_LOCAL( FT_Error ) + tt_face_load_hmtx( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + FT_LOCAL( FT_Error ) + tt_face_get_metrics( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short* abearing, + FT_UShort* aadvance ); + +FT_END_HEADER + +#endif /* __TTMTX_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttpost.c b/drivers/freetype/src/sfnt/ttpost.c new file mode 100644 index 0000000000..47a85c0c9f --- /dev/null +++ b/drivers/freetype/src/sfnt/ttpost.c @@ -0,0 +1,563 @@ +/***************************************************************************/ +/* */ +/* ttpost.c */ +/* */ +/* Postcript name table processing for TrueType and OpenType fonts */ +/* (body). */ +/* */ +/* Copyright 1996-2003, 2006-2010, 2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* The post table is not completely loaded by the core engine. This */ + /* file loads the missing PS glyph names and implements an API to access */ + /* them. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttpost.h" + +#include "sferrors.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_ttpost + + + /* If this configuration macro is defined, we rely on the `PSNames' */ + /* module to grab the glyph names. */ + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + +#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) + + +#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + /* Otherwise, we ignore the `PSNames' module, and provide our own */ + /* table of Mac names. Thus, it is possible to build a version of */ + /* FreeType without the Type 1 driver & PSNames module. */ + +#define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) + + /* the 258 default Mac PS glyph names */ + + static const FT_String* const tt_post_default_names[258] = + { + /* 0 */ + ".notdef", ".null", "CR", "space", "exclam", + "quotedbl", "numbersign", "dollar", "percent", "ampersand", + /* 10 */ + "quotesingle", "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", "zero", + /* 20 */ + "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "colon", + /* 30 */ + "semicolon", "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", + /* 40 */ + "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", + /* 50 */ + "O", "P", "Q", "R", "S", + "T", "U", "V", "W", "X", + /* 60 */ + "Y", "Z", "bracketleft", "backslash", "bracketright", + "asciicircum", "underscore", "grave", "a", "b", + /* 70 */ + "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", + /* 80 */ + "m", "n", "o", "p", "q", + "r", "s", "t", "u", "v", + /* 90 */ + "w", "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", "Aring", + /* 100 */ + "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", + "aacute", "agrave", "acircumflex", "adieresis", "atilde", + /* 110 */ + "aring", "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", "idieresis", + /* 120 */ + "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", + "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", + /* 130 */ + "dagger", "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", "copyright", + /* 140 */ + "trademark", "acute", "dieresis", "notequal", "AE", + "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", + /* 150 */ + "yen", "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", "Omega", + /* 160 */ + "ae", "oslash", "questiondown", "exclamdown", "logicalnot", + "radical", "florin", "approxequal", "Delta", "guillemotleft", + /* 170 */ + "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", "emdash", + /* 180 */ + "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", + "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", + /* 190 */ + "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", + /* 200 */ + "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", + "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", + /* 210 */ + "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", "breve", + /* 220 */ + "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", + "caron", "Lslash", "lslash", "Scaron", "scaron", + /* 230 */ + "Zcaron", "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", "minus", + /* 240 */ + "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", + "onequarter", "threequarters", "franc", "Gbreve", "gbreve", + /* 250 */ + "Idot", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dmacron", + }; + + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + static FT_Error + load_format_20( TT_Face face, + FT_Stream stream, + FT_Long post_limit ) + { + FT_Memory memory = stream->memory; + FT_Error error; + + FT_Int num_glyphs; + FT_UShort num_names; + + FT_UShort* glyph_indices = 0; + FT_Char** name_strings = 0; + + + if ( FT_READ_USHORT( num_glyphs ) ) + goto Exit; + + /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ + /* than the value in the maxp table (cf. cyberbit.ttf). */ + + /* There already exist fonts which have more than 32768 glyph names */ + /* in this table, so the test for this threshold has been dropped. */ + + if ( num_glyphs > face->max_profile.numGlyphs ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* load the indices */ + { + FT_Int n; + + + if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) || + FT_FRAME_ENTER( num_glyphs * 2L ) ) + goto Fail; + + for ( n = 0; n < num_glyphs; n++ ) + glyph_indices[n] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + } + + /* compute number of names stored in table */ + { + FT_Int n; + + + num_names = 0; + + for ( n = 0; n < num_glyphs; n++ ) + { + FT_Int idx; + + + idx = glyph_indices[n]; + if ( idx >= 258 ) + { + idx -= 257; + if ( idx > num_names ) + num_names = (FT_UShort)idx; + } + } + } + + /* now load the name strings */ + { + FT_UShort n; + + + if ( FT_NEW_ARRAY( name_strings, num_names ) ) + goto Fail; + + for ( n = 0; n < num_names; n++ ) + { + FT_UInt len; + + + if ( FT_STREAM_POS() >= post_limit ) + break; + else + { + FT_TRACE6(( "load_format_20: %d byte left in post table\n", + post_limit - FT_STREAM_POS() )); + + if ( FT_READ_BYTE( len ) ) + goto Fail1; + } + + if ( (FT_Int)len > post_limit || + FT_STREAM_POS() > post_limit - (FT_Int)len ) + { + FT_ERROR(( "load_format_20:" + " exceeding string length (%d)," + " truncating at end of post table (%d byte left)\n", + len, post_limit - FT_STREAM_POS() )); + len = FT_MAX( 0, post_limit - FT_STREAM_POS() ); + } + + if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) || + FT_STREAM_READ( name_strings[n], len ) ) + goto Fail1; + + name_strings[n][len] = '\0'; + } + + if ( n < num_names ) + { + FT_ERROR(( "load_format_20:" + " all entries in post table are already parsed," + " using NULL names for gid %d - %d\n", + n, num_names - 1 )); + for ( ; n < num_names; n++ ) + if ( FT_NEW_ARRAY( name_strings[n], 1 ) ) + goto Fail1; + else + name_strings[n][0] = '\0'; + } + } + + /* all right, set table fields and exit successfully */ + { + TT_Post_20 table = &face->postscript_names.names.format_20; + + + table->num_glyphs = (FT_UShort)num_glyphs; + table->num_names = (FT_UShort)num_names; + table->glyph_indices = glyph_indices; + table->glyph_names = name_strings; + } + return FT_Err_Ok; + + Fail1: + { + FT_UShort n; + + + for ( n = 0; n < num_names; n++ ) + FT_FREE( name_strings[n] ); + } + + Fail: + FT_FREE( name_strings ); + FT_FREE( glyph_indices ); + + Exit: + return error; + } + + + static FT_Error + load_format_25( TT_Face face, + FT_Stream stream, + FT_Long post_limit ) + { + FT_Memory memory = stream->memory; + FT_Error error; + + FT_Int num_glyphs; + FT_Char* offset_table = 0; + + FT_UNUSED( post_limit ); + + + /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ + if ( FT_READ_USHORT( num_glyphs ) ) + goto Exit; + + /* check the number of glyphs */ + if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( FT_NEW_ARRAY( offset_table, num_glyphs ) || + FT_STREAM_READ( offset_table, num_glyphs ) ) + goto Fail; + + /* now check the offset table */ + { + FT_Int n; + + + for ( n = 0; n < num_glyphs; n++ ) + { + FT_Long idx = (FT_Long)n + offset_table[n]; + + + if ( idx < 0 || idx > num_glyphs ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + } + } + + /* OK, set table fields and exit successfully */ + { + TT_Post_25 table = &face->postscript_names.names.format_25; + + + table->num_glyphs = (FT_UShort)num_glyphs; + table->offsets = offset_table; + } + + return FT_Err_Ok; + + Fail: + FT_FREE( offset_table ); + + Exit: + return error; + } + + + static FT_Error + load_post_names( TT_Face face ) + { + FT_Stream stream; + FT_Error error; + FT_Fixed format; + FT_ULong post_len; + FT_Long post_limit; + + + /* get a stream for the face's resource */ + stream = face->root.stream; + + /* seek to the beginning of the PS names table */ + error = face->goto_table( face, TTAG_post, stream, &post_len ); + if ( error ) + goto Exit; + + post_limit = FT_STREAM_POS() + post_len; + + format = face->postscript.FormatType; + + /* go to beginning of subtable */ + if ( FT_STREAM_SKIP( 32 ) ) + goto Exit; + + /* now read postscript table */ + if ( format == 0x00020000L ) + error = load_format_20( face, stream, post_limit ); + else if ( format == 0x00028000L ) + error = load_format_25( face, stream, post_limit ); + else + error = FT_THROW( Invalid_File_Format ); + + face->postscript_names.loaded = 1; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_ps_names( TT_Face face ) + { + FT_Memory memory = face->root.memory; + TT_Post_Names names = &face->postscript_names; + FT_Fixed format; + + + if ( names->loaded ) + { + format = face->postscript.FormatType; + + if ( format == 0x00020000L ) + { + TT_Post_20 table = &names->names.format_20; + FT_UShort n; + + + FT_FREE( table->glyph_indices ); + table->num_glyphs = 0; + + for ( n = 0; n < table->num_names; n++ ) + FT_FREE( table->glyph_names[n] ); + + FT_FREE( table->glyph_names ); + table->num_names = 0; + } + else if ( format == 0x00028000L ) + { + TT_Post_25 table = &names->names.format_25; + + + FT_FREE( table->offsets ); + table->num_glyphs = 0; + } + } + names->loaded = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_get_ps_name */ + /* */ + /* <Description> */ + /* Get the PostScript glyph name of a glyph. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face. */ + /* */ + /* idx :: The glyph index. */ + /* */ + /* <InOut> */ + /* PSname :: The address of a string pointer. Will be NULL in case */ + /* of error, otherwise it is a pointer to the glyph name. */ + /* */ + /* You must not modify the returned string! */ + /* */ + /* <Output> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_get_ps_name( TT_Face face, + FT_UInt idx, + FT_String** PSname ) + { + FT_Error error; + TT_Post_Names names; + FT_Fixed format; + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Service_PsCMaps psnames; +#endif + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( idx >= (FT_UInt)face->max_profile.numGlyphs ) + return FT_THROW( Invalid_Glyph_Index ); + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + psnames = (FT_Service_PsCMaps)face->psnames; + if ( !psnames ) + return FT_THROW( Unimplemented_Feature ); +#endif + + names = &face->postscript_names; + + /* `.notdef' by default */ + *PSname = MAC_NAME( 0 ); + + format = face->postscript.FormatType; + + if ( format == 0x00010000L ) + { + if ( idx < 258 ) /* paranoid checking */ + *PSname = MAC_NAME( idx ); + } + else if ( format == 0x00020000L ) + { + TT_Post_20 table = &names->names.format_20; + + + if ( !names->loaded ) + { + error = load_post_names( face ); + if ( error ) + goto End; + } + + if ( idx < (FT_UInt)table->num_glyphs ) + { + FT_UShort name_index = table->glyph_indices[idx]; + + + if ( name_index < 258 ) + *PSname = MAC_NAME( name_index ); + else + *PSname = (FT_String*)table->glyph_names[name_index - 258]; + } + } + else if ( format == 0x00028000L ) + { + TT_Post_25 table = &names->names.format_25; + + + if ( !names->loaded ) + { + error = load_post_names( face ); + if ( error ) + goto End; + } + + if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */ + { + idx += table->offsets[idx]; + *PSname = MAC_NAME( idx ); + } + } + + /* nothing to do for format == 0x00030000L */ + + End: + return FT_Err_Ok; + } + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttpost.h b/drivers/freetype/src/sfnt/ttpost.h new file mode 100644 index 0000000000..6f06d75a71 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttpost.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* ttpost.h */ +/* */ +/* Postcript name table processing for TrueType and OpenType fonts */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTPOST_H__ +#define __TTPOST_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_get_ps_name( TT_Face face, + FT_UInt idx, + FT_String** PSname ); + + FT_LOCAL( void ) + tt_face_free_ps_names( TT_Face face ); + + +FT_END_HEADER + +#endif /* __TTPOST_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/sfnt/ttsbit.c b/drivers/freetype/src/sfnt/ttsbit.c new file mode 100644 index 0000000000..cd3e5a4a00 --- /dev/null +++ b/drivers/freetype/src/sfnt/ttsbit.c @@ -0,0 +1,1177 @@ +/***************************************************************************/ +/* */ +/* ttsbit.c */ +/* */ +/* TrueType and OpenType embedded bitmap support (body). */ +/* */ +/* Copyright 2005-2009, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Copyright 2013 by Google, Inc. */ +/* Google Author(s): Behdad Esfahbod. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include FT_BITMAP_H +#include "ttsbit.h" + +#include "sferrors.h" + +#include "pngshim.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_ttsbit + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_eblc( TT_Face face, + FT_Stream stream ) + { + FT_Error error = FT_Err_Ok; + FT_Fixed version; + FT_ULong num_strikes, table_size; + FT_Byte* p; + FT_Byte* p_limit; + FT_UInt count; + + + face->sbit_num_strikes = 0; + + /* this table is optional */ + error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); + if ( error ) + error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); + if ( error ) + error = face->goto_table( face, TTAG_bloc, stream, &table_size ); + if ( error ) + goto Exit; + + if ( table_size < 8 ) + { + FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) + goto Exit; + + face->sbit_table_size = table_size; + + p = face->sbit_table; + p_limit = p + table_size; + + version = FT_NEXT_ULONG( p ); + num_strikes = FT_NEXT_ULONG( p ); + + if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) + { + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* + * Count the number of strikes available in the table. We are a bit + * paranoid there and don't trust the data. + */ + count = (FT_UInt)num_strikes; + if ( 8 + 48UL * count > table_size ) + count = (FT_UInt)( ( p_limit - p ) / 48 ); + + face->sbit_num_strikes = count; + + FT_TRACE3(( "sbit_num_strikes: %u\n", count )); + Exit: + return error; + + Fail: + FT_FRAME_RELEASE( face->sbit_table ); + face->sbit_table_size = 0; + goto Exit; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_eblc( TT_Face face ) + { + FT_Stream stream = face->root.stream; + + + FT_FRAME_RELEASE( face->sbit_table ); + face->sbit_table_size = 0; + face->sbit_num_strikes = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_set_sbit_strike( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ) + { + return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_strike_metrics( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ) + { + FT_Byte* strike; + + + if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) + return FT_THROW( Invalid_Argument ); + + strike = face->sbit_table + 8 + strike_index * 48; + + metrics->x_ppem = (FT_UShort)strike[44]; + metrics->y_ppem = (FT_UShort)strike[45]; + + metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ + metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ + metrics->height = metrics->ascender - metrics->descender; + + /* XXX: Is this correct? */ + metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ + strike[18] + /* max_width */ + (FT_Char)strike[23] /* min_advance_SB */ + ) << 6; + + return FT_Err_Ok; + } + + + typedef struct TT_SBitDecoderRec_ + { + TT_Face face; + FT_Stream stream; + FT_Bitmap* bitmap; + TT_SBit_Metrics metrics; + FT_Bool metrics_loaded; + FT_Bool bitmap_allocated; + FT_Byte bit_depth; + + FT_ULong ebdt_start; + FT_ULong ebdt_size; + + FT_ULong strike_index_array; + FT_ULong strike_index_count; + FT_Byte* eblc_base; + FT_Byte* eblc_limit; + + } TT_SBitDecoderRec, *TT_SBitDecoder; + + + static FT_Error + tt_sbit_decoder_init( TT_SBitDecoder decoder, + TT_Face face, + FT_ULong strike_index, + TT_SBit_MetricsRec* metrics ) + { + FT_Error error; + FT_Stream stream = face->root.stream; + FT_ULong ebdt_size; + + + error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size ); + if ( error ) + error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); + if ( error ) + error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); + if ( error ) + goto Exit; + + decoder->face = face; + decoder->stream = stream; + decoder->bitmap = &face->root.glyph->bitmap; + decoder->metrics = metrics; + + decoder->metrics_loaded = 0; + decoder->bitmap_allocated = 0; + + decoder->ebdt_start = FT_STREAM_POS(); + decoder->ebdt_size = ebdt_size; + + decoder->eblc_base = face->sbit_table; + decoder->eblc_limit = face->sbit_table + face->sbit_table_size; + + /* now find the strike corresponding to the index */ + { + FT_Byte* p; + + + if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + p = decoder->eblc_base + 8 + 48 * strike_index; + + decoder->strike_index_array = FT_NEXT_ULONG( p ); + p += 4; + decoder->strike_index_count = FT_NEXT_ULONG( p ); + p += 34; + decoder->bit_depth = *p; + + if ( decoder->strike_index_array > face->sbit_table_size || + decoder->strike_index_array + 8 * decoder->strike_index_count > + face->sbit_table_size ) + error = FT_THROW( Invalid_File_Format ); + } + + Exit: + return error; + } + + + static void + tt_sbit_decoder_done( TT_SBitDecoder decoder ) + { + FT_UNUSED( decoder ); + } + + + static FT_Error + tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, + FT_UInt load_flags ) + { + FT_Error error = FT_Err_Ok; + FT_UInt width, height; + FT_Bitmap* map = decoder->bitmap; + FT_Long size; + + + if ( !decoder->metrics_loaded ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + width = decoder->metrics->width; + height = decoder->metrics->height; + + map->width = (int)width; + map->rows = (int)height; + + switch ( decoder->bit_depth ) + { + case 1: + map->pixel_mode = FT_PIXEL_MODE_MONO; + map->pitch = ( map->width + 7 ) >> 3; + map->num_grays = 2; + break; + + case 2: + map->pixel_mode = FT_PIXEL_MODE_GRAY2; + map->pitch = ( map->width + 3 ) >> 2; + map->num_grays = 4; + break; + + case 4: + map->pixel_mode = FT_PIXEL_MODE_GRAY4; + map->pitch = ( map->width + 1 ) >> 1; + map->num_grays = 16; + break; + + case 8: + map->pixel_mode = FT_PIXEL_MODE_GRAY; + map->pitch = map->width; + map->num_grays = 256; + break; + + case 32: + if ( load_flags & FT_LOAD_COLOR ) + { + map->pixel_mode = FT_PIXEL_MODE_BGRA; + map->pitch = map->width * 4; + map->num_grays = 256; + } + else + { + map->pixel_mode = FT_PIXEL_MODE_GRAY; + map->pitch = map->width; + map->num_grays = 256; + } + break; + + default: + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + size = map->rows * map->pitch; + + /* check that there is no empty image */ + if ( size == 0 ) + goto Exit; /* exit successfully! */ + + error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); + if ( error ) + goto Exit; + + decoder->bitmap_allocated = 1; + + Exit: + return error; + } + + + static FT_Error + tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder, + FT_Byte* *pp, + FT_Byte* limit, + FT_Bool big ) + { + FT_Byte* p = *pp; + TT_SBit_Metrics metrics = decoder->metrics; + + + if ( p + 5 > limit ) + goto Fail; + + metrics->height = p[0]; + metrics->width = p[1]; + metrics->horiBearingX = (FT_Char)p[2]; + metrics->horiBearingY = (FT_Char)p[3]; + metrics->horiAdvance = p[4]; + + p += 5; + if ( big ) + { + if ( p + 3 > limit ) + goto Fail; + + metrics->vertBearingX = (FT_Char)p[0]; + metrics->vertBearingY = (FT_Char)p[1]; + metrics->vertAdvance = p[2]; + + p += 3; + } + + decoder->metrics_loaded = 1; + *pp = p; + return FT_Err_Ok; + + Fail: + FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" )); + return FT_THROW( Invalid_Argument ); + } + + + /* forward declaration */ + static FT_Error + tt_sbit_decoder_load_image( TT_SBitDecoder decoder, + FT_UInt load_flags, + FT_UInt glyph_index, + FT_Int x_pos, + FT_Int y_pos ); + + typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, + FT_UInt load_flags, + FT_Byte* p, + FT_Byte* plimit, + FT_Int x_pos, + FT_Int y_pos ); + + + static FT_Error + tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, + FT_UInt load_flags, + FT_Byte* p, + FT_Byte* limit, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error = FT_Err_Ok; + FT_Byte* line; + FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; + FT_Bitmap* bitmap; + + FT_UNUSED( load_flags ); + + + /* check that we can write the glyph into the bitmap */ + bitmap = decoder->bitmap; + bit_width = bitmap->width; + bit_height = bitmap->rows; + pitch = bitmap->pitch; + line = bitmap->buffer; + + width = decoder->metrics->width; + height = decoder->metrics->height; + + line_bits = width * decoder->bit_depth; + + if ( x_pos < 0 || x_pos + width > bit_width || + y_pos < 0 || y_pos + height > bit_height ) + { + FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:" + " invalid bitmap dimensions\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit ) + { + FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* now do the blit */ + line += y_pos * pitch + ( x_pos >> 3 ); + x_pos &= 7; + + if ( x_pos == 0 ) /* the easy one */ + { + for ( h = height; h > 0; h--, line += pitch ) + { + FT_Byte* pwrite = line; + FT_Int w; + + + for ( w = line_bits; w >= 8; w -= 8 ) + { + pwrite[0] = (FT_Byte)( pwrite[0] | *p++ ); + pwrite += 1; + } + + if ( w > 0 ) + pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) ); + } + } + else /* x_pos > 0 */ + { + for ( h = height; h > 0; h--, line += pitch ) + { + FT_Byte* pwrite = line; + FT_Int w; + FT_UInt wval = 0; + + + for ( w = line_bits; w >= 8; w -= 8 ) + { + wval = (FT_UInt)( wval | *p++ ); + pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); + pwrite += 1; + wval <<= 8; + } + + if ( w > 0 ) + wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); + + /* all bits read and there are `x_pos + w' bits to be written */ + + pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); + + if ( x_pos + w > 8 ) + { + pwrite++; + wval <<= 8; + pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); + } + } + } + + Exit: + if ( !error ) + FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" )); + return error; + } + + + /* + * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap + * (with pointer `pwrite'). In the example below, the width is 3 pixel, + * and `x_pos' is 1 pixel. + * + * p p+1 + * | | | + * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... + * | | | + * +-------+ +-------+ +-------+ ... + * . . . + * . . . + * v . . + * +-------+ . . + * | | . + * | 7 6 5 4 3 2 1 0 | . + * | | . + * pwrite . . + * . . + * v . + * +-------+ . + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * pwrite+1 . + * . + * v + * +-------+ + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * pwrite+2 + * + */ + + static FT_Error + tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, + FT_UInt load_flags, + FT_Byte* p, + FT_Byte* limit, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error = FT_Err_Ok; + FT_Byte* line; + FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits; + FT_Bitmap* bitmap; + FT_UShort rval; + + FT_UNUSED( load_flags ); + + + /* check that we can write the glyph into the bitmap */ + bitmap = decoder->bitmap; + bit_width = bitmap->width; + bit_height = bitmap->rows; + pitch = bitmap->pitch; + line = bitmap->buffer; + + width = decoder->metrics->width; + height = decoder->metrics->height; + + line_bits = width * decoder->bit_depth; + + if ( x_pos < 0 || x_pos + width > bit_width || + y_pos < 0 || y_pos + height > bit_height ) + { + FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:" + " invalid bitmap dimensions\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit ) + { + FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* now do the blit */ + + /* adjust `line' to point to the first byte of the bitmap */ + line += y_pos * pitch + ( x_pos >> 3 ); + x_pos &= 7; + + /* the higher byte of `rval' is used as a buffer */ + rval = 0; + nbits = 0; + + for ( h = height; h > 0; h--, line += pitch ) + { + FT_Byte* pwrite = line; + FT_Int w = line_bits; + + + /* handle initial byte (in target bitmap) specially if necessary */ + if ( x_pos ) + { + w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos; + + if ( h == height ) + { + rval = *p++; + nbits = x_pos; + } + else if ( nbits < w ) + { + if ( p < limit ) + rval |= *p++; + nbits += 8 - w; + } + else + { + rval >>= 8; + nbits -= w; + } + + *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) & + ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); + rval <<= 8; + + w = line_bits - w; + } + + /* handle medial bytes */ + for ( ; w >= 8; w -= 8 ) + { + rval |= *p++; + *pwrite++ |= ( rval >> nbits ) & 0xFF; + + rval <<= 8; + } + + /* handle final byte if necessary */ + if ( w > 0 ) + { + if ( nbits < w ) + { + if ( p < limit ) + rval |= *p++; + *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); + nbits += 8 - w; + + rval <<= 8; + } + else + { + *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); + nbits -= w; + } + } + } + + Exit: + if ( !error ) + FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" )); + return error; + } + + + static FT_Error + tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, + FT_UInt load_flags, + FT_Byte* p, + FT_Byte* limit, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error = FT_Err_Ok; + FT_UInt num_components, nn; + + FT_Char horiBearingX = decoder->metrics->horiBearingX; + FT_Char horiBearingY = decoder->metrics->horiBearingY; + FT_Byte horiAdvance = decoder->metrics->horiAdvance; + FT_Char vertBearingX = decoder->metrics->vertBearingX; + FT_Char vertBearingY = decoder->metrics->vertBearingY; + FT_Byte vertAdvance = decoder->metrics->vertAdvance; + + + if ( p + 2 > limit ) + goto Fail; + + num_components = FT_NEXT_USHORT( p ); + if ( p + 4 * num_components > limit ) + { + FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" )); + goto Fail; + } + + FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n", + num_components )); + + for ( nn = 0; nn < num_components; nn++ ) + { + FT_UInt gindex = FT_NEXT_USHORT( p ); + FT_Byte dx = FT_NEXT_BYTE( p ); + FT_Byte dy = FT_NEXT_BYTE( p ); + + + /* NB: a recursive call */ + error = tt_sbit_decoder_load_image( decoder, load_flags, gindex, + x_pos + dx, y_pos + dy ); + if ( error ) + break; + } + + FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" )); + + decoder->metrics->horiBearingX = horiBearingX; + decoder->metrics->horiBearingY = horiBearingY; + decoder->metrics->horiAdvance = horiAdvance; + decoder->metrics->vertBearingX = vertBearingX; + decoder->metrics->vertBearingY = vertBearingY; + decoder->metrics->vertAdvance = vertAdvance; + decoder->metrics->width = (FT_Byte)decoder->bitmap->width; + decoder->metrics->height = (FT_Byte)decoder->bitmap->rows; + + Exit: + return error; + + Fail: + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + +#ifdef FT_CONFIG_OPTION_USE_PNG + + static FT_Error + tt_sbit_decoder_load_png( TT_SBitDecoder decoder, + FT_UInt load_flags, + FT_Byte* p, + FT_Byte* limit, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error = FT_Err_Ok; + FT_ULong png_len; + + FT_UNUSED( load_flags ); + + + if ( limit - p < 4 ) + { + FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + png_len = FT_NEXT_ULONG( p ); + if ( (FT_ULong)( limit - p ) < png_len ) + { + FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + error = Load_SBit_Png( decoder->bitmap, + x_pos, + y_pos, + decoder->bit_depth, + decoder->metrics, + decoder->stream->memory, + p, + png_len ); + + Exit: + if ( !error ) + FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" )); + return error; + } + +#endif /* FT_CONFIG_OPTION_USE_PNG */ + + + static FT_Error + tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, + FT_UInt load_flags, + FT_UInt glyph_format, + FT_ULong glyph_start, + FT_ULong glyph_size, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error; + FT_Stream stream = decoder->stream; + FT_Byte* p; + FT_Byte* p_limit; + FT_Byte* data; + + + /* seek into the EBDT table now */ + if ( glyph_start + glyph_size > decoder->ebdt_size ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || + FT_FRAME_EXTRACT( glyph_size, data ) ) + goto Exit; + + p = data; + p_limit = p + glyph_size; + + /* read the data, depending on the glyph format */ + switch ( glyph_format ) + { + case 1: + case 2: + case 8: + case 17: + error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); + break; + + case 6: + case 7: + case 9: + case 18: + error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); + break; + + default: + error = FT_Err_Ok; + } + + if ( error ) + goto Fail; + + { + TT_SBitDecoder_LoadFunc loader; + + + switch ( glyph_format ) + { + case 1: + case 6: + loader = tt_sbit_decoder_load_byte_aligned; + break; + + case 2: + case 5: + case 7: + loader = tt_sbit_decoder_load_bit_aligned; + break; + + case 8: + if ( p + 1 > p_limit ) + goto Fail; + + p += 1; /* skip padding */ + /* fall-through */ + + case 9: + loader = tt_sbit_decoder_load_compound; + break; + +#ifdef FT_CONFIG_OPTION_USE_PNG + case 17: /* small metrics, PNG image data */ + case 18: /* big metrics, PNG image data */ + case 19: /* metrics in EBLC, PNG image data */ + loader = tt_sbit_decoder_load_png; + break; +#endif /* FT_CONFIG_OPTION_USE_PNG */ + + default: + error = FT_THROW( Invalid_Table ); + goto Fail; + } + + if ( !decoder->bitmap_allocated ) + { + error = tt_sbit_decoder_alloc_bitmap( decoder, load_flags ); + if ( error ) + goto Fail; + } + + if ( decoder->bit_depth == 32 && + decoder->bitmap->pixel_mode != FT_PIXEL_MODE_BGRA ) + { + /* Flatten color bitmaps if color was not requested. */ + + FT_Library library = decoder->face->root.glyph->library; + FT_Memory memory = decoder->stream->memory; + + FT_Bitmap color, *orig; + + + if ( decoder->bitmap->pixel_mode != FT_PIXEL_MODE_GRAY || + x_pos != 0 || y_pos != 0 ) + { + /* Shouldn't happen. */ + error = FT_THROW( Invalid_Table ); + goto Fail; + } + + FT_Bitmap_New( &color ); + + color.rows = decoder->bitmap->rows; + color.width = decoder->bitmap->width; + color.pitch = color.width * 4; + color.pixel_mode = FT_PIXEL_MODE_BGRA; + + if ( FT_ALLOC( color.buffer, color.rows * color.pitch ) ) + goto Fail; + + orig = decoder->bitmap; + decoder->bitmap = &color; + + error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); + + decoder->bitmap = orig; + + /* explicitly test against FT_Err_Ok to avoid compiler warnings */ + /* (we do an assignment within a conditional) */ + if ( error || + ( error = FT_Bitmap_Convert( library, + &color, + decoder->bitmap, + 1 ) ) != FT_Err_Ok ) + { + FT_Bitmap_Done( library, &color ); + goto Fail; + } + + FT_Bitmap_Done( library, &color ); + } + + else + error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); + } + + Fail: + FT_FRAME_RELEASE( data ); + + Exit: + return error; + } + + + static FT_Error + tt_sbit_decoder_load_image( TT_SBitDecoder decoder, + FT_UInt load_flags, + FT_UInt glyph_index, + FT_Int x_pos, + FT_Int y_pos ) + { + /* + * First, we find the correct strike range that applies to this + * glyph index. + */ + + FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; + FT_Byte* p_limit = decoder->eblc_limit; + FT_ULong num_ranges = decoder->strike_index_count; + FT_UInt start, end, index_format, image_format; + FT_ULong image_start = 0, image_end = 0, image_offset; + + + for ( ; num_ranges > 0; num_ranges-- ) + { + start = FT_NEXT_USHORT( p ); + end = FT_NEXT_USHORT( p ); + + if ( glyph_index >= start && glyph_index <= end ) + goto FoundRange; + + p += 4; /* ignore index offset */ + } + goto NoBitmap; + + FoundRange: + image_offset = FT_NEXT_ULONG( p ); + + /* overflow check */ + p = decoder->eblc_base + decoder->strike_index_array; + if ( image_offset > (FT_ULong)( p_limit - p ) ) + goto Failure; + + p += image_offset; + if ( p + 8 > p_limit ) + goto NoBitmap; + + /* now find the glyph's location and extend within the ebdt table */ + index_format = FT_NEXT_USHORT( p ); + image_format = FT_NEXT_USHORT( p ); + image_offset = FT_NEXT_ULONG ( p ); + + switch ( index_format ) + { + case 1: /* 4-byte offsets relative to `image_offset' */ + { + p += 4 * ( glyph_index - start ); + if ( p + 8 > p_limit ) + goto NoBitmap; + + image_start = FT_NEXT_ULONG( p ); + image_end = FT_NEXT_ULONG( p ); + + if ( image_start == image_end ) /* missing glyph */ + goto NoBitmap; + } + break; + + case 2: /* big metrics, constant image size */ + { + FT_ULong image_size; + + + if ( p + 12 > p_limit ) + goto NoBitmap; + + image_size = FT_NEXT_ULONG( p ); + + if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) + goto NoBitmap; + + image_start = image_size * ( glyph_index - start ); + image_end = image_start + image_size; + } + break; + + case 3: /* 2-byte offsets relative to 'image_offset' */ + { + p += 2 * ( glyph_index - start ); + if ( p + 4 > p_limit ) + goto NoBitmap; + + image_start = FT_NEXT_USHORT( p ); + image_end = FT_NEXT_USHORT( p ); + + if ( image_start == image_end ) /* missing glyph */ + goto NoBitmap; + } + break; + + case 4: /* sparse glyph array with (glyph,offset) pairs */ + { + FT_ULong mm, num_glyphs; + + + if ( p + 4 > p_limit ) + goto NoBitmap; + + num_glyphs = FT_NEXT_ULONG( p ); + + /* overflow check for p + ( num_glyphs + 1 ) * 4 */ + if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) + goto NoBitmap; + + for ( mm = 0; mm < num_glyphs; mm++ ) + { + FT_UInt gindex = FT_NEXT_USHORT( p ); + + + if ( gindex == glyph_index ) + { + image_start = FT_NEXT_USHORT( p ); + p += 2; + image_end = FT_PEEK_USHORT( p ); + break; + } + p += 2; + } + + if ( mm >= num_glyphs ) + goto NoBitmap; + } + break; + + case 5: /* constant metrics with sparse glyph codes */ + case 19: + { + FT_ULong image_size, mm, num_glyphs; + + + if ( p + 16 > p_limit ) + goto NoBitmap; + + image_size = FT_NEXT_ULONG( p ); + + if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) + goto NoBitmap; + + num_glyphs = FT_NEXT_ULONG( p ); + + /* overflow check for p + 2 * num_glyphs */ + if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) ) + goto NoBitmap; + + for ( mm = 0; mm < num_glyphs; mm++ ) + { + FT_UInt gindex = FT_NEXT_USHORT( p ); + + + if ( gindex == glyph_index ) + break; + } + + if ( mm >= num_glyphs ) + goto NoBitmap; + + image_start = image_size * mm; + image_end = image_start + image_size; + } + break; + + default: + goto NoBitmap; + } + + if ( image_start > image_end ) + goto NoBitmap; + + image_end -= image_start; + image_start = image_offset + image_start; + + FT_TRACE3(( "tt_sbit_decoder_load_image:" + " found sbit (format %d) for glyph index %d\n", + image_format, glyph_index )); + + return tt_sbit_decoder_load_bitmap( decoder, + load_flags, + image_format, + image_start, + image_end, + x_pos, + y_pos ); + + Failure: + return FT_THROW( Invalid_Table ); + + NoBitmap: + FT_TRACE4(( "tt_sbit_decoder_load_image:" + " no sbit found for glyph index %d\n", glyph_index )); + + return FT_THROW( Invalid_Argument ); + } + + + FT_LOCAL( FT_Error ) + tt_face_load_sbit_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ) + { + TT_SBitDecoderRec decoder[1]; + FT_Error error; + + FT_UNUSED( load_flags ); + FT_UNUSED( stream ); + FT_UNUSED( map ); + + + error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); + if ( !error ) + { + error = tt_sbit_decoder_load_image( decoder, + load_flags, + glyph_index, + 0, + 0 ); + tt_sbit_decoder_done( decoder ); + } + + return error; + } + + +/* EOF */ diff --git a/drivers/freetype/src/sfnt/ttsbit.h b/drivers/freetype/src/sfnt/ttsbit.h new file mode 100644 index 0000000000..ea0b5f8ada --- /dev/null +++ b/drivers/freetype/src/sfnt/ttsbit.h @@ -0,0 +1,63 @@ +/***************************************************************************/ +/* */ +/* ttsbit.h */ +/* */ +/* TrueType and OpenType embedded bitmap support (specification). */ +/* */ +/* Copyright 1996-2008, 2013 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 __TTSBIT_H__ +#define __TTSBIT_H__ + + +#include <ft2build.h> +#include "ttload.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_eblc( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_eblc( TT_Face face ); + + + FT_LOCAL( FT_Error ) + tt_face_set_sbit_strike( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ); + + FT_LOCAL( FT_Error ) + tt_face_load_strike_metrics( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ); + + FT_LOCAL( FT_Error ) + tt_face_load_sbit_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ); + + +FT_END_HEADER + +#endif /* __TTSBIT_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/smooth/Jamfile b/drivers/freetype/src/smooth/Jamfile new file mode 100644 index 0000000000..a8496aa2c2 --- /dev/null +++ b/drivers/freetype/src/smooth/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/smooth Jamfile +# +# Copyright 2001 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) smooth ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ftgrays ftsmooth ftspic ; + } + else + { + _sources = smooth ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/smooth Jamfile diff --git a/drivers/freetype/src/smooth/ftgrays.c b/drivers/freetype/src/smooth/ftgrays.c new file mode 100644 index 0000000000..7532a35829 --- /dev/null +++ b/drivers/freetype/src/smooth/ftgrays.c @@ -0,0 +1,2132 @@ +/***************************************************************************/ +/* */ +/* ftgrays.c */ +/* */ +/* A new `perfect' anti-aliasing renderer (body). */ +/* */ +/* Copyright 2000-2003, 2005-2013 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This file can be compiled without the rest of the FreeType engine, by */ + /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* put the files `ftgrays.h' and `ftimage.h' into the current */ + /* compilation directory. Typically, you could do something like */ + /* */ + /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */ + /* */ + /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ + /* same directory */ + /* */ + /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ + /* */ + /* cc -c -D_STANDALONE_ ftgrays.c */ + /* */ + /* The renderer can be initialized with a call to */ + /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ + /* with a call to `ft_gray_raster.raster_render'. */ + /* */ + /* See the comments and documentation in the file `ftimage.h' for more */ + /* details on how the raster works. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* This is a new anti-aliasing scan-converter for FreeType 2. The */ + /* algorithm used here is _very_ different from the one in the standard */ + /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ + /* coverage of the outline on each pixel cell. */ + /* */ + /* It is based on ideas that I initially found in Raph Levien's */ + /* excellent LibArt graphics library (see http://www.levien.com/libart */ + /* for more information, though the web pages do not tell anything */ + /* about the renderer; you'll have to dive into the source code to */ + /* understand how it works). */ + /* */ + /* Note, however, that this is a _very_ different implementation */ + /* compared to Raph's. Coverage information is stored in a very */ + /* different way, and I don't use sorted vector paths. Also, it doesn't */ + /* use floating point values. */ + /* */ + /* This renderer has the following advantages: */ + /* */ + /* - It doesn't need an intermediate bitmap. Instead, one can supply a */ + /* callback function that will be called by the renderer to draw gray */ + /* spans on any target surface. You can thus do direct composition on */ + /* any kind of bitmap, provided that you give the renderer the right */ + /* callback. */ + /* */ + /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ + /* each pixel cell. */ + /* */ + /* - It performs a single pass on the outline (the `standard' FT2 */ + /* renderer makes two passes). */ + /* */ + /* - It can easily be modified to render to _any_ number of gray levels */ + /* cheaply. */ + /* */ + /* - For small (< 20) pixel sizes, it is faster than the standard */ + /* renderer. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* 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_smooth + + +#ifdef _STANDALONE_ + + + /* Auxiliary macros for token concatenation. */ +#define FT_ERR_XCAT( x, y ) x ## y +#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) + + + /* define this to dump debugging information */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + +#ifdef FT_DEBUG_LEVEL_TRACE +#include <stdio.h> +#include <stdarg.h> +#endif + +#include <stddef.h> +#include <string.h> +#include <setjmp.h> +#include <limits.h> +#define FT_UINT_MAX UINT_MAX +#define FT_INT_MAX INT_MAX + +#define ft_memset memset + +#define ft_setjmp setjmp +#define ft_longjmp longjmp +#define ft_jmp_buf jmp_buf + +typedef ptrdiff_t FT_PtrDist; + + +#define ErrRaster_Invalid_Mode -2 +#define ErrRaster_Invalid_Outline -1 +#define ErrRaster_Invalid_Argument -3 +#define ErrRaster_Memory_Overflow -4 + +#define FT_BEGIN_HEADER +#define FT_END_HEADER + +#include "ftimage.h" +#include "ftgrays.h" + + + /* This macro is used to indicate that a function parameter is unused. */ + /* Its purpose is simply to reduce compiler warnings. Note also that */ + /* simply defining it as `(void)x' doesn't avoid warnings with certain */ + /* ANSI compilers (e.g. LCC). */ +#define FT_UNUSED( x ) (x) = (x) + + + /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + void + FT_Message( const char* fmt, + ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + } + + + /* empty function useful for setting a breakpoint to catch errors */ + int + FT_Throw( int error, + int line, + const char* file ) + { + FT_UNUSED( error ); + FT_UNUSED( line ); + FT_UNUSED( file ); + + return 0; + } + + + /* we don't handle tracing levels in stand-alone mode; */ +#ifndef FT_TRACE5 +#define FT_TRACE5( varformat ) FT_Message varformat +#endif +#ifndef FT_TRACE7 +#define FT_TRACE7( varformat ) FT_Message varformat +#endif +#ifndef FT_ERROR +#define FT_ERROR( varformat ) FT_Message varformat +#endif + +#define FT_THROW( e ) \ + ( FT_Throw( FT_ERR_CAT( ErrRaster, e ), \ + __LINE__, \ + __FILE__ ) | \ + FT_ERR_CAT( ErrRaster, e ) ) + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ +#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ +#define FT_THROW( e ) FT_ERR_CAT( ErrRaster_, e ) + + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +#define FT_DEFINE_OUTLINE_FUNCS( class_, \ + move_to_, line_to_, \ + conic_to_, cubic_to_, \ + shift_, delta_ ) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ \ + }; + +#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \ + raster_new_, raster_reset_, \ + raster_set_mode_, raster_render_, \ + raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; + + +#else /* !_STANDALONE_ */ + + +#include <ft2build.h> +#include "ftgrays.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_OUTLINE_H + +#include "ftsmerrs.h" + +#include "ftspic.h" + +#define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph +#define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory +#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory + + +#endif /* !_STANDALONE_ */ + + +#ifndef FT_MEM_SET +#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) +#endif + +#ifndef FT_MEM_ZERO +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) +#endif + + /* as usual, for the speed hungry :-) */ + +#undef RAS_ARG +#undef RAS_ARG_ +#undef RAS_VAR +#undef RAS_VAR_ + +#ifndef FT_STATIC_RASTER + +#define RAS_ARG gray_PWorker worker +#define RAS_ARG_ gray_PWorker worker, + +#define RAS_VAR worker +#define RAS_VAR_ worker, + +#else /* FT_STATIC_RASTER */ + +#define RAS_ARG /* empty */ +#define RAS_ARG_ /* empty */ +#define RAS_VAR /* empty */ +#define RAS_VAR_ /* empty */ + +#endif /* FT_STATIC_RASTER */ + + + /* must be at least 6 bits! */ +#define PIXEL_BITS 8 + +#undef FLOOR +#undef CEILING +#undef TRUNC +#undef SCALED + +#define ONE_PIXEL ( 1L << PIXEL_BITS ) +#define PIXEL_MASK ( -1L << PIXEL_BITS ) +#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) +#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) +#define FLOOR( x ) ( (x) & -ONE_PIXEL ) +#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) +#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) + +#if PIXEL_BITS >= 6 +#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) +#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) +#else +#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) +#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) +#endif + + + /*************************************************************************/ + /* */ + /* TYPE DEFINITIONS */ + /* */ + + /* don't change the following types to FT_Int or FT_Pos, since we might */ + /* need to define them to "float" or "double" when experimenting with */ + /* new algorithms */ + + typedef long TCoord; /* integer scanline/pixel coordinate */ + typedef long TPos; /* sub-pixel coordinate */ + + /* determine the type used to store cell areas. This normally takes at */ + /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ + /* `long' instead of `int', otherwise bad things happen */ + +#if PIXEL_BITS <= 7 + + typedef int TArea; + +#else /* PIXEL_BITS >= 8 */ + + /* approximately determine the size of integers using an ANSI-C header */ +#if FT_UINT_MAX == 0xFFFFU + typedef long TArea; +#else + typedef int TArea; +#endif + +#endif /* PIXEL_BITS >= 8 */ + + + /* maximum number of gray spans in a call to the span callback */ +#define FT_MAX_GRAY_SPANS 32 + + + typedef struct TCell_* PCell; + + typedef struct TCell_ + { + TPos x; /* same with gray_TWorker.ex */ + TCoord cover; /* same with gray_TWorker.cover */ + TArea area; + PCell next; + + } TCell; + + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + /* We disable the warning `structure was padded due to */ + /* __declspec(align())' in order to compile cleanly with */ + /* the maximum level of warnings. */ +#pragma warning( push ) +#pragma warning( disable : 4324 ) +#endif /* _MSC_VER */ + + typedef struct gray_TWorker_ + { + TCoord ex, ey; + TPos min_ex, max_ex; + TPos min_ey, max_ey; + TPos count_ex, count_ey; + + TArea area; + TCoord cover; + int invalid; + + PCell cells; + FT_PtrDist max_cells; + FT_PtrDist num_cells; + + TCoord cx, cy; + TPos x, y; + + TPos last_ey; + + FT_Vector bez_stack[32 * 3 + 1]; + int lev_stack[32]; + + FT_Outline outline; + FT_Bitmap target; + FT_BBox clip_box; + + FT_Span gray_spans[FT_MAX_GRAY_SPANS]; + int num_gray_spans; + + FT_Raster_Span_Func render_span; + void* render_span_data; + int span_y; + + int band_size; + int band_shoot; + + ft_jmp_buf jump_buffer; + + void* buffer; + long buffer_size; + + PCell* ycells; + TPos ycount; + + } gray_TWorker, *gray_PWorker; + +#if defined( _MSC_VER ) +#pragma warning( pop ) +#endif + + +#ifndef FT_STATIC_RASTER +#define ras (*worker) +#else + static gray_TWorker ras; +#endif + + + typedef struct gray_TRaster_ + { + void* buffer; + long buffer_size; + int band_size; + void* memory; + gray_PWorker worker; + + } gray_TRaster, *gray_PRaster; + + + + /*************************************************************************/ + /* */ + /* Initialize the cells table. */ + /* */ + static void + gray_init_cells( RAS_ARG_ void* buffer, + long byte_size ) + { + ras.buffer = buffer; + ras.buffer_size = byte_size; + + ras.ycells = (PCell*) buffer; + ras.cells = NULL; + ras.max_cells = 0; + ras.num_cells = 0; + ras.area = 0; + ras.cover = 0; + ras.invalid = 1; + } + + + /*************************************************************************/ + /* */ + /* Compute the outline bounding box. */ + /* */ + static void + gray_compute_cbox( RAS_ARG ) + { + FT_Outline* outline = &ras.outline; + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + if ( outline->n_points <= 0 ) + { + ras.min_ex = ras.max_ex = 0; + ras.min_ey = ras.max_ey = 0; + return; + } + + ras.min_ex = ras.max_ex = vec->x; + ras.min_ey = ras.max_ey = vec->y; + + vec++; + + for ( ; vec < limit; vec++ ) + { + TPos x = vec->x; + TPos y = vec->y; + + + if ( x < ras.min_ex ) ras.min_ex = x; + if ( x > ras.max_ex ) ras.max_ex = x; + if ( y < ras.min_ey ) ras.min_ey = y; + if ( y > ras.max_ey ) ras.max_ey = y; + } + + /* truncate the bounding box to integer pixels */ + ras.min_ex = ras.min_ex >> 6; + ras.min_ey = ras.min_ey >> 6; + ras.max_ex = ( ras.max_ex + 63 ) >> 6; + ras.max_ey = ( ras.max_ey + 63 ) >> 6; + } + + + /*************************************************************************/ + /* */ + /* Record the current cell in the table. */ + /* */ + static PCell + gray_find_cell( RAS_ARG ) + { + PCell *pcell, cell; + TPos x = ras.ex; + + + if ( x > ras.count_ex ) + x = ras.count_ex; + + pcell = &ras.ycells[ras.ey]; + for (;;) + { + cell = *pcell; + if ( cell == NULL || cell->x > x ) + break; + + if ( cell->x == x ) + goto Exit; + + pcell = &cell->next; + } + + if ( ras.num_cells >= ras.max_cells ) + ft_longjmp( ras.jump_buffer, 1 ); + + cell = ras.cells + ras.num_cells++; + cell->x = x; + cell->area = 0; + cell->cover = 0; + + cell->next = *pcell; + *pcell = cell; + + Exit: + return cell; + } + + + static void + gray_record_cell( RAS_ARG ) + { + if ( !ras.invalid && ( ras.area | ras.cover ) ) + { + PCell cell = gray_find_cell( RAS_VAR ); + + + cell->area += ras.area; + cell->cover += ras.cover; + } + } + + + /*************************************************************************/ + /* */ + /* Set the current cell to a new position. */ + /* */ + static void + gray_set_cell( RAS_ARG_ TCoord ex, + TCoord ey ) + { + /* Move the cell pointer to a new position. We set the `invalid' */ + /* flag to indicate that the cell isn't part of those we're interested */ + /* in during the render phase. This means that: */ + /* */ + /* . the new vertical position must be within min_ey..max_ey-1. */ + /* . the new horizontal position must be strictly less than max_ex */ + /* */ + /* Note that if a cell is to the left of the clipping region, it is */ + /* actually set to the (min_ex-1) horizontal position. */ + + /* All cells that are on the left of the clipping region go to the */ + /* min_ex - 1 horizontal position. */ + ey -= ras.min_ey; + + if ( ex > ras.max_ex ) + ex = ras.max_ex; + + ex -= ras.min_ex; + if ( ex < 0 ) + ex = -1; + + /* are we moving to a different cell ? */ + if ( ex != ras.ex || ey != ras.ey ) + { + /* record the current one if it is valid */ + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); + + ras.area = 0; + ras.cover = 0; + } + + ras.ex = ex; + ras.ey = ey; + ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey || + ex >= ras.count_ex ); + } + + + /*************************************************************************/ + /* */ + /* Start a new contour at a given cell. */ + /* */ + static void + gray_start_cell( RAS_ARG_ TCoord ex, + TCoord ey ) + { + if ( ex > ras.max_ex ) + ex = (TCoord)( ras.max_ex ); + + if ( ex < ras.min_ex ) + ex = (TCoord)( ras.min_ex - 1 ); + + ras.area = 0; + ras.cover = 0; + ras.ex = ex - ras.min_ex; + ras.ey = ey - ras.min_ey; + ras.last_ey = SUBPIXELS( ey ); + ras.invalid = 0; + + gray_set_cell( RAS_VAR_ ex, ey ); + } + + + /*************************************************************************/ + /* */ + /* Render a scanline as one or more cells. */ + /* */ + static void + gray_render_scanline( RAS_ARG_ TCoord ey, + TPos x1, + TCoord y1, + TPos x2, + TCoord y2 ) + { + TCoord ex1, ex2, fx1, fx2, delta, mod; + long p, first, dx; + int incr; + + + dx = x2 - x1; + + ex1 = TRUNC( x1 ); + ex2 = TRUNC( x2 ); + fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); + fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); + + /* trivial case. Happens often */ + if ( y1 == y2 ) + { + gray_set_cell( RAS_VAR_ ex2, ey ); + return; + } + + /* everything is located in a single cell. That is easy! */ + /* */ + if ( ex1 == ex2 ) + { + delta = y2 - y1; + ras.area += (TArea)(( fx1 + fx2 ) * delta); + ras.cover += delta; + return; + } + + /* ok, we'll have to render a run of adjacent cells on the same */ + /* scanline... */ + /* */ + p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); + first = ONE_PIXEL; + incr = 1; + + if ( dx < 0 ) + { + p = fx1 * ( y2 - y1 ); + first = 0; + incr = -1; + dx = -dx; + } + + delta = (TCoord)( p / dx ); + mod = (TCoord)( p % dx ); + if ( mod < 0 ) + { + delta--; + mod += (TCoord)dx; + } + + ras.area += (TArea)(( fx1 + first ) * delta); + ras.cover += delta; + + ex1 += incr; + gray_set_cell( RAS_VAR_ ex1, ey ); + y1 += delta; + + if ( ex1 != ex2 ) + { + TCoord lift, rem; + + + p = ONE_PIXEL * ( y2 - y1 + delta ); + lift = (TCoord)( p / dx ); + rem = (TCoord)( p % dx ); + if ( rem < 0 ) + { + lift--; + rem += (TCoord)dx; + } + + mod -= (int)dx; + + while ( ex1 != ex2 ) + { + delta = lift; + mod += rem; + if ( mod >= 0 ) + { + mod -= (TCoord)dx; + delta++; + } + + ras.area += (TArea)(ONE_PIXEL * delta); + ras.cover += delta; + y1 += delta; + ex1 += incr; + gray_set_cell( RAS_VAR_ ex1, ey ); + } + } + + delta = y2 - y1; + ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); + ras.cover += delta; + } + + + /*************************************************************************/ + /* */ + /* Render a given line as a series of scanlines. */ + /* */ + static void + gray_render_line( RAS_ARG_ TPos to_x, + TPos to_y ) + { + TCoord ey1, ey2, fy1, fy2, mod; + TPos dx, dy, x, x2; + long p, first; + int delta, rem, lift, incr; + + + ey1 = TRUNC( ras.last_ey ); + ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ + fy1 = (TCoord)( ras.y - ras.last_ey ); + fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); + + dx = to_x - ras.x; + dy = to_y - ras.y; + + /* XXX: we should do something about the trivial case where dx == 0, */ + /* as it happens very often! */ + + /* perform vertical clipping */ + { + TCoord min, max; + + + min = ey1; + max = ey2; + if ( ey1 > ey2 ) + { + min = ey2; + max = ey1; + } + if ( min >= ras.max_ey || max < ras.min_ey ) + goto End; + } + + /* everything is on a single scanline */ + if ( ey1 == ey2 ) + { + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ); + goto End; + } + + /* vertical line - avoid calling gray_render_scanline */ + incr = 1; + + if ( dx == 0 ) + { + TCoord ex = TRUNC( ras.x ); + TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); + TArea area; + + + first = ONE_PIXEL; + if ( dy < 0 ) + { + first = 0; + incr = -1; + } + + delta = (int)( first - fy1 ); + ras.area += (TArea)two_fx * delta; + ras.cover += delta; + ey1 += incr; + + gray_set_cell( RAS_VAR_ ex, ey1 ); + + delta = (int)( first + first - ONE_PIXEL ); + area = (TArea)two_fx * delta; + while ( ey1 != ey2 ) + { + ras.area += area; + ras.cover += delta; + ey1 += incr; + + gray_set_cell( RAS_VAR_ ex, ey1 ); + } + + delta = (int)( fy2 - ONE_PIXEL + first ); + ras.area += (TArea)two_fx * delta; + ras.cover += delta; + + goto End; + } + + /* ok, we have to render several scanlines */ + p = ( ONE_PIXEL - fy1 ) * dx; + first = ONE_PIXEL; + incr = 1; + + if ( dy < 0 ) + { + p = fy1 * dx; + first = 0; + incr = -1; + dy = -dy; + } + + delta = (int)( p / dy ); + mod = (int)( p % dy ); + if ( mod < 0 ) + { + delta--; + mod += (TCoord)dy; + } + + x = ras.x + delta; + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); + + ey1 += incr; + gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); + + if ( ey1 != ey2 ) + { + p = ONE_PIXEL * dx; + lift = (int)( p / dy ); + rem = (int)( p % dy ); + if ( rem < 0 ) + { + lift--; + rem += (int)dy; + } + mod -= (int)dy; + + while ( ey1 != ey2 ) + { + delta = lift; + mod += rem; + if ( mod >= 0 ) + { + mod -= (int)dy; + delta++; + } + + x2 = x + delta; + gray_render_scanline( RAS_VAR_ ey1, x, + (TCoord)( ONE_PIXEL - first ), x2, + (TCoord)first ); + x = x2; + + ey1 += incr; + gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); + } + } + + gray_render_scanline( RAS_VAR_ ey1, x, + (TCoord)( ONE_PIXEL - first ), to_x, + fy2 ); + + End: + ras.x = to_x; + ras.y = to_y; + ras.last_ey = SUBPIXELS( ey2 ); + } + + + static void + gray_split_conic( FT_Vector* base ) + { + TPos a, b; + + + base[4].x = base[2].x; + b = base[1].x; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; + + base[4].y = base[2].y; + b = base[1].y; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; + } + + + static void + gray_render_conic( RAS_ARG_ const FT_Vector* control, + const FT_Vector* to ) + { + TPos dx, dy; + TPos min, max, y; + int top, level; + int* levels; + FT_Vector* arc; + + + levels = ras.lev_stack; + + arc = ras.bez_stack; + arc[0].x = UPSCALE( to->x ); + arc[0].y = UPSCALE( to->y ); + arc[1].x = UPSCALE( control->x ); + arc[1].y = UPSCALE( control->y ); + arc[2].x = ras.x; + arc[2].y = ras.y; + top = 0; + + dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x ); + dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y ); + if ( dx < dy ) + dx = dy; + + if ( dx < ONE_PIXEL / 4 ) + goto Draw; + + /* short-cut the arc that crosses the current band */ + min = max = arc[0].y; + + y = arc[1].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + + y = arc[2].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + + if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) + goto Draw; + + level = 0; + do + { + dx >>= 2; + level++; + } while ( dx > ONE_PIXEL / 4 ); + + levels[0] = level; + + do + { + level = levels[top]; + if ( level > 0 ) + { + gray_split_conic( arc ); + arc += 2; + top++; + levels[top] = levels[top - 1] = level - 1; + continue; + } + + Draw: + gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); + top--; + arc -= 2; + + } while ( top >= 0 ); + } + + + static void + gray_split_cubic( FT_Vector* base ) + { + TPos a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c ) / 2; + base[5].x = b = ( base[3].x + d ) / 2; + c = ( c + d ) / 2; + base[2].x = a = ( a + c ) / 2; + base[4].x = b = ( b + c ) / 2; + base[3].x = ( a + b ) / 2; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c ) / 2; + base[5].y = b = ( base[3].y + d ) / 2; + c = ( c + d ) / 2; + base[2].y = a = ( a + c ) / 2; + base[4].y = b = ( b + c ) / 2; + base[3].y = ( a + b ) / 2; + } + + + static void + gray_render_cubic( RAS_ARG_ const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to ) + { + FT_Vector* arc; + TPos min, max, y; + + + arc = ras.bez_stack; + arc[0].x = UPSCALE( to->x ); + arc[0].y = UPSCALE( to->y ); + arc[1].x = UPSCALE( control2->x ); + arc[1].y = UPSCALE( control2->y ); + arc[2].x = UPSCALE( control1->x ); + arc[2].y = UPSCALE( control1->y ); + arc[3].x = ras.x; + arc[3].y = ras.y; + + /* Short-cut the arc that crosses the current band. */ + min = max = arc[0].y; + + y = arc[1].y; + if ( y < min ) + min = y; + if ( y > max ) + max = y; + + y = arc[2].y; + if ( y < min ) + min = y; + if ( y > max ) + max = y; + + y = arc[3].y; + if ( y < min ) + min = y; + if ( y > max ) + max = y; + + if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) + goto Draw; + + for (;;) + { + /* Decide whether to split or draw. See `Rapid Termination */ + /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */ + /* F. Hain, at */ + /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ + + { + TPos dx, dy, dx_, dy_; + TPos dx1, dy1, dx2, dy2; + TPos L, s, s_limit; + + + /* dx and dy are x and y components of the P0-P3 chord vector. */ + dx = arc[3].x - arc[0].x; + dy = arc[3].y - arc[0].y; + + /* L is an (under)estimate of the Euclidean distance P0-P3. */ + /* */ + /* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated */ + /* with least maximum error by */ + /* */ + /* r_upperbound = dx + (sqrt(2) - 1) * dy , */ + /* */ + /* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */ + /* error of no more than 8.4%. */ + /* */ + /* Similarly, some elementary calculus shows that r can be */ + /* underestimated with least maximum error by */ + /* */ + /* r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx */ + /* + sqrt(2 - sqrt(2)) / 2 * dy . */ + /* */ + /* 236/256 and 97/256 are (under)estimates of the two algebraic */ + /* numbers, giving an error of no more than 8.1%. */ + + dx_ = FT_ABS( dx ); + dy_ = FT_ABS( dy ); + + /* This is the same as */ + /* */ + /* L = ( 236 * FT_MAX( dx_, dy_ ) */ + /* + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */ + L = ( dx_ > dy_ ? 236 * dx_ + 97 * dy_ + : 97 * dx_ + 236 * dy_ ) >> 8; + + /* Avoid possible arithmetic overflow below by splitting. */ + if ( L > 32767 ) + goto Split; + + /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ + s_limit = L * (TPos)( ONE_PIXEL / 6 ); + + /* s is L * the perpendicular distance from P1 to the line P0-P3. */ + dx1 = arc[1].x - arc[0].x; + dy1 = arc[1].y - arc[0].y; + s = FT_ABS( dy * dx1 - dx * dy1 ); + + if ( s > s_limit ) + goto Split; + + /* s is L * the perpendicular distance from P2 to the line P0-P3. */ + dx2 = arc[2].x - arc[0].x; + dy2 = arc[2].y - arc[0].y; + s = FT_ABS( dy * dx2 - dx * dy2 ); + + if ( s > s_limit ) + goto Split; + + /* Split super curvy segments where the off points are so far + from the chord that the angles P0-P1-P3 or P0-P2-P3 become + acute as detected by appropriate dot products. */ + if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || + dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) + goto Split; + + /* No reason to split. */ + goto Draw; + } + + Split: + gray_split_cubic( arc ); + arc += 3; + continue; + + Draw: + gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); + + if ( arc == ras.bez_stack ) + return; + + arc -= 3; + } + } + + + static int + gray_move_to( const FT_Vector* to, + gray_PWorker worker ) + { + TPos x, y; + + + /* record current cell, if any */ + gray_record_cell( RAS_VAR ); + + /* start to a new position */ + x = UPSCALE( to->x ); + y = UPSCALE( to->y ); + + gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); + + worker->x = x; + worker->y = y; + return 0; + } + + + static int + gray_line_to( const FT_Vector* to, + gray_PWorker worker ) + { + gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) ); + return 0; + } + + + static int + gray_conic_to( const FT_Vector* control, + const FT_Vector* to, + gray_PWorker worker ) + { + gray_render_conic( RAS_VAR_ control, to ); + return 0; + } + + + static int + gray_cubic_to( const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to, + gray_PWorker worker ) + { + gray_render_cubic( RAS_VAR_ control1, control2, to ); + return 0; + } + + + static void + gray_render_span( int y, + int count, + const FT_Span* spans, + gray_PWorker worker ) + { + unsigned char* p; + FT_Bitmap* map = &worker->target; + + + /* first of all, compute the scanline offset */ + p = (unsigned char*)map->buffer - y * map->pitch; + if ( map->pitch >= 0 ) + p += (unsigned)( ( map->rows - 1 ) * map->pitch ); + + for ( ; count > 0; count--, spans++ ) + { + unsigned char coverage = spans->coverage; + + + if ( coverage ) + { + /* For small-spans it is faster to do it by ourselves than + * calling `memset'. This is mainly due to the cost of the + * function call. + */ + if ( spans->len >= 8 ) + FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); + else + { + unsigned char* q = p + spans->x; + + + switch ( spans->len ) + { + case 7: *q++ = (unsigned char)coverage; + case 6: *q++ = (unsigned char)coverage; + case 5: *q++ = (unsigned char)coverage; + case 4: *q++ = (unsigned char)coverage; + case 3: *q++ = (unsigned char)coverage; + case 2: *q++ = (unsigned char)coverage; + case 1: *q = (unsigned char)coverage; + default: + ; + } + } + } + } + } + + + static void + gray_hline( RAS_ARG_ TCoord x, + TCoord y, + TPos area, + TCoord acount ) + { + int coverage; + + + /* compute the coverage line's coverage, depending on the */ + /* outline fill rule */ + /* */ + /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ + /* */ + coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); + /* use range 0..256 */ + if ( coverage < 0 ) + coverage = -coverage; + + if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) + { + coverage &= 511; + + if ( coverage > 256 ) + coverage = 512 - coverage; + else if ( coverage == 256 ) + coverage = 255; + } + else + { + /* normal non-zero winding rule */ + if ( coverage >= 256 ) + coverage = 255; + } + + y += (TCoord)ras.min_ey; + x += (TCoord)ras.min_ex; + + /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ + if ( x >= 32767 ) + x = 32767; + + /* FT_Span.y is an integer, so limit our coordinates appropriately */ + if ( y >= FT_INT_MAX ) + y = FT_INT_MAX; + + if ( coverage ) + { + FT_Span* span; + int count; + + + /* see whether we can add this span to the current list */ + count = ras.num_gray_spans; + span = ras.gray_spans + count - 1; + if ( count > 0 && + ras.span_y == y && + (int)span->x + span->len == (int)x && + span->coverage == coverage ) + { + span->len = (unsigned short)( span->len + acount ); + return; + } + + if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) + { + if ( ras.render_span && count > 0 ) + ras.render_span( ras.span_y, count, ras.gray_spans, + ras.render_span_data ); + +#ifdef FT_DEBUG_LEVEL_TRACE + + if ( count > 0 ) + { + int n; + + + FT_TRACE7(( "y = %3d ", ras.span_y )); + span = ras.gray_spans; + for ( n = 0; n < count; n++, span++ ) + FT_TRACE7(( "[%d..%d]:%02x ", + span->x, span->x + span->len - 1, span->coverage )); + FT_TRACE7(( "\n" )); + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + ras.num_gray_spans = 0; + ras.span_y = (int)y; + + count = 0; + span = ras.gray_spans; + } + else + span++; + + /* add a gray span to the current list */ + span->x = (short)x; + span->len = (unsigned short)acount; + span->coverage = (unsigned char)coverage; + + ras.num_gray_spans++; + } + } + + +#ifdef FT_DEBUG_LEVEL_TRACE + + /* to be called while in the debugger -- */ + /* this function causes a compiler warning since it is unused otherwise */ + static void + gray_dump_cells( RAS_ARG ) + { + int yindex; + + + for ( yindex = 0; yindex < ras.ycount; yindex++ ) + { + PCell cell; + + + printf( "%3d:", yindex ); + + for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) + printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); + printf( "\n" ); + } + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + static void + gray_sweep( RAS_ARG_ const FT_Bitmap* target ) + { + int yindex; + + FT_UNUSED( target ); + + + if ( ras.num_cells == 0 ) + return; + + ras.num_gray_spans = 0; + + FT_TRACE7(( "gray_sweep: start\n" )); + + for ( yindex = 0; yindex < ras.ycount; yindex++ ) + { + PCell cell = ras.ycells[yindex]; + TCoord cover = 0; + TCoord x = 0; + + + for ( ; cell != NULL; cell = cell->next ) + { + TPos area; + + + if ( cell->x > x && cover != 0 ) + gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + cell->x - x ); + + cover += cell->cover; + area = cover * ( ONE_PIXEL * 2 ) - cell->area; + + if ( area != 0 && cell->x >= 0 ) + gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); + + x = cell->x + 1; + } + + if ( cover != 0 ) + gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + ras.count_ex - x ); + } + + if ( ras.render_span && ras.num_gray_spans > 0 ) + ras.render_span( ras.span_y, ras.num_gray_spans, + ras.gray_spans, ras.render_span_data ); + +#ifdef FT_DEBUG_LEVEL_TRACE + + if ( ras.num_gray_spans > 0 ) + { + FT_Span* span; + int n; + + + FT_TRACE7(( "y = %3d ", ras.span_y )); + span = ras.gray_spans; + for ( n = 0; n < ras.num_gray_spans; n++, span++ ) + FT_TRACE7(( "[%d..%d]:%02x ", + span->x, span->x + span->len - 1, span->coverage )); + FT_TRACE7(( "\n" )); + } + + FT_TRACE7(( "gray_sweep: end\n" )); + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + } + + +#ifdef _STANDALONE_ + + /*************************************************************************/ + /* */ + /* The following function should only compile in stand-alone mode, */ + /* i.e., when building this component without the rest of FreeType. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and Bézier arcs. This function is also able to emit */ + /* `move to' and `close to' operations to indicate the start and end */ + /* of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e., function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* <InOut> */ + /* user :: A typeless pointer which is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* Error code. 0 means success. */ + /* */ + static int + FT_Outline_Decompose( const FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ) + { +#undef SCALED +#define SCALED( x ) ( ( (x) << shift ) - delta ) + + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + int error; + + int n; /* index of contour in outline */ + int first; /* index of first point in contour */ + char tag; /* current point's state */ + + int shift; + TPos delta; + + + if ( !outline || !func_interface ) + return FT_THROW( Invalid_Argument ); + + shift = func_interface->shift; + delta = func_interface->delta; + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + int last; /* index of last point in contour */ + + + FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + + last = outline->contours[n]; + if ( last < 0 ) + goto Invalid_Outline; + limit = outline->points + last; + + v_start = outline->points[first]; + v_start.x = SCALED( v_start.x ); + v_start.y = SCALED( v_start.y ); + + v_last = outline->points[last]; + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + FT_TRACE5(( " move to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); + error = func_interface->move_to( &v_start, user ); + if ( error ) + goto Exit; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + FT_TRACE5(( " line to (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0 )); + error = func_interface->line_to( &vec, user ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point->x ); + v_control.y = SCALED( point->y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_middle.x / 64.0, v_middle.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_middle, user ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_start, user ); + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1.x = SCALED( point[-2].x ); + vec1.y = SCALED( point[-2].y ); + + vec2.x = SCALED( point[-1].x ); + vec2.y = SCALED( point[-1].y ); + + if ( point <= limit ) + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); + error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); + error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); + goto Close; + } + } + } + + /* close the contour with a line segment */ + FT_TRACE5(( " line to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); + error = func_interface->line_to( &v_start, user ); + + Close: + if ( error ) + goto Exit; + + first = last + 1; + } + + FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); + return 0; + + Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); + return error; + + Invalid_Outline: + return FT_THROW( Invalid_Outline ); + } + +#endif /* _STANDALONE_ */ + + + typedef struct gray_TBand_ + { + TPos min, max; + + } gray_TBand; + + FT_DEFINE_OUTLINE_FUNCS(func_interface, + (FT_Outline_MoveTo_Func) gray_move_to, + (FT_Outline_LineTo_Func) gray_line_to, + (FT_Outline_ConicTo_Func)gray_conic_to, + (FT_Outline_CubicTo_Func)gray_cubic_to, + 0, + 0 + ) + + static int + gray_convert_glyph_inner( RAS_ARG ) + { + + volatile int error = 0; + +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs func_interface; + Init_Class_func_interface(&func_interface); +#endif + + if ( ft_setjmp( ras.jump_buffer ) == 0 ) + { + error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); + gray_record_cell( RAS_VAR ); + } + else + error = FT_THROW( Memory_Overflow ); + + return error; + } + + + static int + gray_convert_glyph( RAS_ARG ) + { + gray_TBand bands[40]; + gray_TBand* volatile band; + int volatile n, num_bands; + TPos volatile min, max, max_y; + FT_BBox* clip; + + + /* Set up state in the raster object */ + gray_compute_cbox( RAS_VAR ); + + /* clip to target bitmap, exit if nothing to do */ + clip = &ras.clip_box; + + if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || + ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) + return 0; + + if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; + if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; + + if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; + if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; + + ras.count_ex = ras.max_ex - ras.min_ex; + ras.count_ey = ras.max_ey - ras.min_ey; + + /* set up vertical bands */ + num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); + if ( num_bands == 0 ) + num_bands = 1; + if ( num_bands >= 39 ) + num_bands = 39; + + ras.band_shoot = 0; + + min = ras.min_ey; + max_y = ras.max_ey; + + for ( n = 0; n < num_bands; n++, min = max ) + { + max = min + ras.band_size; + if ( n == num_bands - 1 || max > max_y ) + max = max_y; + + bands[0].min = min; + bands[0].max = max; + band = bands; + + while ( band >= bands ) + { + TPos bottom, top, middle; + int error; + + { + PCell cells_max; + int yindex; + long cell_start, cell_end, cell_mod; + + + ras.ycells = (PCell*)ras.buffer; + ras.ycount = band->max - band->min; + + cell_start = sizeof ( PCell ) * ras.ycount; + cell_mod = cell_start % sizeof ( TCell ); + if ( cell_mod > 0 ) + cell_start += sizeof ( TCell ) - cell_mod; + + cell_end = ras.buffer_size; + cell_end -= cell_end % sizeof ( TCell ); + + cells_max = (PCell)( (char*)ras.buffer + cell_end ); + ras.cells = (PCell)( (char*)ras.buffer + cell_start ); + if ( ras.cells >= cells_max ) + goto ReduceBands; + + ras.max_cells = cells_max - ras.cells; + if ( ras.max_cells < 2 ) + goto ReduceBands; + + for ( yindex = 0; yindex < ras.ycount; yindex++ ) + ras.ycells[yindex] = NULL; + } + + ras.num_cells = 0; + ras.invalid = 1; + ras.min_ey = band->min; + ras.max_ey = band->max; + ras.count_ey = band->max - band->min; + + error = gray_convert_glyph_inner( RAS_VAR ); + + if ( !error ) + { + gray_sweep( RAS_VAR_ &ras.target ); + band--; + continue; + } + else if ( error != ErrRaster_Memory_Overflow ) + return 1; + + ReduceBands: + /* render pool overflow; we will reduce the render band by half */ + bottom = band->min; + top = band->max; + middle = bottom + ( ( top - bottom ) >> 1 ); + + /* This is too complex for a single scanline; there must */ + /* be some problems. */ + if ( middle == bottom ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); +#endif + return 1; + } + + if ( bottom-top >= ras.band_size ) + ras.band_shoot++; + + band[1].min = bottom; + band[1].max = middle; + band[0].min = middle; + band[0].max = top; + band++; + } + } + + if ( ras.band_shoot > 8 && ras.band_size > 16 ) + ras.band_size = ras.band_size / 2; + + return 0; + } + + + static int + gray_raster_render( gray_PRaster raster, + const FT_Raster_Params* params ) + { + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; + gray_PWorker worker; + + + if ( !raster || !raster->buffer || !raster->buffer_size ) + return FT_THROW( Invalid_Argument ); + + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + /* return immediately if the outline is empty */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + return 0; + + if ( !outline->contours || !outline->points ) + return FT_THROW( Invalid_Outline ); + + if ( outline->n_points != + outline->contours[outline->n_contours - 1] + 1 ) + return FT_THROW( Invalid_Outline ); + + worker = raster->worker; + + /* if direct mode is not set, we must have a target bitmap */ + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) + { + if ( !target_map ) + return FT_THROW( Invalid_Argument ); + + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return 0; + + if ( !target_map->buffer ) + return FT_THROW( Invalid_Argument ); + } + + /* this version does not support monochrome rendering */ + if ( !( params->flags & FT_RASTER_FLAG_AA ) ) + return FT_THROW( Invalid_Mode ); + + /* compute clipping box */ + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) + { + /* compute clip box from target pixmap */ + ras.clip_box.xMin = 0; + ras.clip_box.yMin = 0; + ras.clip_box.xMax = target_map->width; + ras.clip_box.yMax = target_map->rows; + } + else if ( params->flags & FT_RASTER_FLAG_CLIP ) + ras.clip_box = params->clip_box; + else + { + ras.clip_box.xMin = -32768L; + ras.clip_box.yMin = -32768L; + ras.clip_box.xMax = 32767L; + ras.clip_box.yMax = 32767L; + } + + gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); + + ras.outline = *outline; + ras.num_cells = 0; + ras.invalid = 1; + ras.band_size = raster->band_size; + ras.num_gray_spans = 0; + + if ( params->flags & FT_RASTER_FLAG_DIRECT ) + { + ras.render_span = (FT_Raster_Span_Func)params->gray_spans; + ras.render_span_data = params->user; + } + else + { + ras.target = *target_map; + ras.render_span = (FT_Raster_Span_Func)gray_render_span; + ras.render_span_data = &ras; + } + + return gray_convert_glyph( RAS_VAR ); + } + + + /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ + /**** a static object. *****/ + +#ifdef _STANDALONE_ + + static int + gray_raster_new( void* memory, + FT_Raster* araster ) + { + static gray_TRaster the_raster; + + FT_UNUSED( memory ); + + + *araster = (FT_Raster)&the_raster; + FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + + return 0; + } + + + static void + gray_raster_done( FT_Raster raster ) + { + /* nothing */ + FT_UNUSED( raster ); + } + +#else /* !_STANDALONE_ */ + + static int + gray_raster_new( FT_Memory memory, + FT_Raster* araster ) + { + FT_Error error; + gray_PRaster raster = NULL; + + + *araster = 0; + if ( !FT_ALLOC( raster, sizeof ( gray_TRaster ) ) ) + { + raster->memory = memory; + *araster = (FT_Raster)raster; + } + + return error; + } + + + static void + gray_raster_done( FT_Raster raster ) + { + FT_Memory memory = (FT_Memory)((gray_PRaster)raster)->memory; + + + FT_FREE( raster ); + } + +#endif /* !_STANDALONE_ */ + + + static void + gray_raster_reset( FT_Raster raster, + char* pool_base, + long pool_size ) + { + gray_PRaster rast = (gray_PRaster)raster; + + + if ( raster ) + { + if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 ) + { + gray_PWorker worker = (gray_PWorker)pool_base; + + + rast->worker = worker; + rast->buffer = pool_base + + ( ( sizeof ( gray_TWorker ) + + sizeof ( TCell ) - 1 ) & + ~( sizeof ( TCell ) - 1 ) ); + rast->buffer_size = (long)( ( pool_base + pool_size ) - + (char*)rast->buffer ) & + ~( sizeof ( TCell ) - 1 ); + rast->band_size = (int)( rast->buffer_size / + ( sizeof ( TCell ) * 8 ) ); + } + else + { + rast->buffer = NULL; + rast->buffer_size = 0; + rast->worker = NULL; + } + } + } + + + FT_DEFINE_RASTER_FUNCS(ft_grays_raster, + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Raster_New_Func) gray_raster_new, + (FT_Raster_Reset_Func) gray_raster_reset, + (FT_Raster_Set_Mode_Func)0, + (FT_Raster_Render_Func) gray_raster_render, + (FT_Raster_Done_Func) gray_raster_done + ) + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/drivers/freetype/src/smooth/ftgrays.h b/drivers/freetype/src/smooth/ftgrays.h new file mode 100644 index 0000000000..f20f55f14b --- /dev/null +++ b/drivers/freetype/src/smooth/ftgrays.h @@ -0,0 +1,58 @@ +/***************************************************************************/ +/* */ +/* ftgrays.h */ +/* */ +/* FreeType smooth renderer declaration */ +/* */ +/* Copyright 1996-2001 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 __FTGRAYS_H__ +#define __FTGRAYS_H__ + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef _STANDALONE_ +#include "ftimage.h" +#else +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */ +#include FT_IMAGE_H +#endif + + + /*************************************************************************/ + /* */ + /* To make ftgrays.h independent from configuration files we check */ + /* whether FT_EXPORT_VAR has been defined already. */ + /* */ + /* On some systems and compilers (Win32 mostly), an extra keyword is */ + /* necessary to compile the library as a DLL. */ + /* */ +#ifndef FT_EXPORT_VAR +#define FT_EXPORT_VAR( x ) extern x +#endif + + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_grays_raster; + + +#ifdef __cplusplus + } +#endif + +#endif /* __FTGRAYS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/smooth/ftsmerrs.h b/drivers/freetype/src/smooth/ftsmerrs.h new file mode 100644 index 0000000000..413d2f1f70 --- /dev/null +++ b/drivers/freetype/src/smooth/ftsmerrs.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* ftsmerrs.h */ +/* */ +/* smooth renderer error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the smooth renderer error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FTSMERRS_H__ +#define __FTSMERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX Smooth_Err_ +#define FT_ERR_BASE FT_Mod_Err_Smooth + +#include FT_ERRORS_H + +#endif /* __FTSMERRS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/smooth/ftsmooth.c b/drivers/freetype/src/smooth/ftsmooth.c new file mode 100644 index 0000000000..89088cd091 --- /dev/null +++ b/drivers/freetype/src/smooth/ftsmooth.c @@ -0,0 +1,534 @@ +/***************************************************************************/ +/* */ +/* ftsmooth.c */ +/* */ +/* Anti-aliasing renderer interface (body). */ +/* */ +/* Copyright 2000-2006, 2009-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_OUTLINE_H +#include "ftsmooth.h" +#include "ftgrays.h" +#include "ftspic.h" + +#include "ftsmerrs.h" + + + /* initialize renderer -- init its raster */ + static FT_Error + ft_smooth_init( FT_Renderer render ) + { + FT_Library library = FT_MODULE_LIBRARY( render ); + + + render->clazz->raster_class->raster_reset( render->raster, + library->raster_pool, + library->raster_pool_size ); + + return 0; + } + + + /* sets render-specific mode */ + static FT_Error + ft_smooth_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* we simply pass it to the raster */ + return render->clazz->raster_class->raster_set_mode( render->raster, + mode_tag, + data ); + } + + /* transform a given glyph image */ + static FT_Error + ft_smooth_transform( FT_Renderer render, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ) + { + FT_Error error = FT_Err_Ok; + + + if ( slot->format != render->glyph_format ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( matrix ) + FT_Outline_Transform( &slot->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &slot->outline, delta->x, delta->y ); + + Exit: + return error; + } + + + /* return the glyph's control box */ + static void + ft_smooth_get_cbox( FT_Renderer render, + FT_GlyphSlot slot, + FT_BBox* cbox ) + { + FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + + if ( slot->format == render->glyph_format ) + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_smooth_render_generic( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin, + FT_Render_Mode required_mode ) + { + FT_Error error; + FT_Outline* outline = NULL; + FT_BBox cbox; + FT_Pos width, height, pitch; +#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + FT_Pos height_org, width_org; +#endif + FT_Bitmap* bitmap = &slot->bitmap; + FT_Memory memory = render->root.memory; + FT_Int hmul = mode == FT_RENDER_MODE_LCD; + FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; + FT_Pos x_shift = 0; + FT_Pos y_shift = 0; + FT_Pos x_left, y_top; + + FT_Raster_Params params; + + FT_Bool have_translated_origin = FALSE; + FT_Bool have_outline_shifted = FALSE; + FT_Bool have_buffer = FALSE; + + + /* check glyph image format */ + if ( slot->format != render->glyph_format ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* check mode */ + if ( mode != required_mode ) + { + error = FT_THROW( Cannot_Render_Glyph ); + goto Exit; + } + + outline = &slot->outline; + + /* translate the outline to the new origin if needed */ + if ( origin ) + { + FT_Outline_Translate( outline, origin->x, origin->y ); + have_translated_origin = TRUE; + } + + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); + + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); + + if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) + { + FT_ERROR(( "ft_smooth_render_generic: glyph too large:" + " xMin = %d, xMax = %d\n", + cbox.xMin >> 6, cbox.xMax >> 6 )); + error = FT_THROW( Raster_Overflow ); + goto Exit; + } + else + width = ( cbox.xMax - cbox.xMin ) >> 6; + + if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) + { + FT_ERROR(( "ft_smooth_render_generic: glyph too large:" + " yMin = %d, yMax = %d\n", + cbox.yMin >> 6, cbox.yMax >> 6 )); + error = FT_THROW( Raster_Overflow ); + goto Exit; + } + else + height = ( cbox.yMax - cbox.yMin ) >> 6; + +#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + width_org = width; + height_org = height; +#endif + + /* release old bitmap buffer */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + /* allocate new one */ + pitch = width; + if ( hmul ) + { + width = width * 3; + pitch = FT_PAD_CEIL( width, 4 ); + } + + if ( vmul ) + height *= 3; + + x_shift = (FT_Int) cbox.xMin; + y_shift = (FT_Int) cbox.yMin; + x_left = (FT_Int)( cbox.xMin >> 6 ); + y_top = (FT_Int)( cbox.yMax >> 6 ); + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + if ( slot->library->lcd_filter_func ) + { + FT_Int extra = slot->library->lcd_extra; + + + if ( hmul ) + { + x_shift -= 64 * ( extra >> 1 ); + width += 3 * extra; + pitch = FT_PAD_CEIL( width, 4 ); + x_left -= extra >> 1; + } + + if ( vmul ) + { + y_shift -= 64 * ( extra >> 1 ); + height += 3 * extra; + y_top += extra >> 1; + } + } + +#endif + +#if FT_UINT_MAX > 0xFFFFU + + /* Required check is (pitch * height < FT_ULONG_MAX), */ + /* but we care realistic cases only. Always pitch <= width. */ + if ( width > 0x7FFF || height > 0x7FFF ) + { + FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", + width, height )); + error = FT_THROW( Raster_Overflow ); + goto Exit; + } + +#endif + + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + bitmap->width = width; + bitmap->rows = height; + bitmap->pitch = pitch; + + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -x_shift, -y_shift ); + have_outline_shifted = TRUE; + + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) + goto Exit; + else + have_buffer = TRUE; + + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + + /* set up parameters */ + params.target = bitmap; + params.source = outline; + params.flags = FT_RASTER_FLAG_AA; + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + /* implode outline if needed */ + { + FT_Vector* points = outline->points; + FT_Vector* points_end = points + outline->n_points; + FT_Vector* vec; + + + if ( hmul ) + for ( vec = points; vec < points_end; vec++ ) + vec->x *= 3; + + if ( vmul ) + for ( vec = points; vec < points_end; vec++ ) + vec->y *= 3; + } + + /* render outline into the bitmap */ + error = render->raster_render( render->raster, ¶ms ); + + /* deflate outline if needed */ + { + FT_Vector* points = outline->points; + FT_Vector* points_end = points + outline->n_points; + FT_Vector* vec; + + + if ( hmul ) + for ( vec = points; vec < points_end; vec++ ) + vec->x /= 3; + + if ( vmul ) + for ( vec = points; vec < points_end; vec++ ) + vec->y /= 3; + } + + if ( error ) + goto Exit; + + if ( slot->library->lcd_filter_func ) + slot->library->lcd_filter_func( bitmap, mode, slot->library ); + +#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + /* render outline into bitmap */ + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + /* expand it horizontally */ + if ( hmul ) + { + FT_Byte* line = bitmap->buffer; + FT_UInt hh; + + + for ( hh = height_org; hh > 0; hh--, line += pitch ) + { + FT_UInt xx; + FT_Byte* end = line + width; + + + for ( xx = width_org; xx > 0; xx-- ) + { + FT_UInt pixel = line[xx-1]; + + + end[-3] = (FT_Byte)pixel; + end[-2] = (FT_Byte)pixel; + end[-1] = (FT_Byte)pixel; + end -= 3; + } + } + } + + /* expand it vertically */ + if ( vmul ) + { + FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; + FT_Byte* write = bitmap->buffer; + FT_UInt hh; + + + for ( hh = height_org; hh > 0; hh-- ) + { + ft_memcpy( write, read, pitch ); + write += pitch; + + ft_memcpy( write, read, pitch ); + write += pitch; + + ft_memcpy( write, read, pitch ); + write += pitch; + read += pitch; + } + } + +#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + /* + * XXX: on 16bit system, we return an error for huge bitmap + * to prevent an overflow. + */ + if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) + { + error = FT_THROW( Invalid_Pixel_Size ); + goto Exit; + } + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = (FT_Int)x_left; + slot->bitmap_top = (FT_Int)y_top; + + /* everything is fine; don't deallocate buffer */ + have_buffer = FALSE; + + error = FT_Err_Ok; + + Exit: + if ( have_outline_shifted ) + FT_Outline_Translate( outline, x_shift, y_shift ); + if ( have_translated_origin ) + FT_Outline_Translate( outline, -origin->x, -origin->y ); + if ( have_buffer ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + return error; + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_smooth_render( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + if ( mode == FT_RENDER_MODE_LIGHT ) + mode = FT_RENDER_MODE_NORMAL; + + return ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_NORMAL ); + } + + + /* convert a slot's glyph image into a horizontal LCD bitmap */ + static FT_Error + ft_smooth_render_lcd( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Error error; + + error = ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_LCD ); + if ( !error ) + slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; + + return error; + } + + + /* convert a slot's glyph image into a vertical LCD bitmap */ + static FT_Error + ft_smooth_render_lcd_v( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Error error; + + error = ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_LCD_V ); + if ( !error ) + slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V; + + return error; + } + + + FT_DEFINE_RENDERER( ft_smooth_renderer_class, + + FT_MODULE_RENDERER, + sizeof ( FT_RendererRec ), + + "smooth", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + + + FT_DEFINE_RENDERER( ft_smooth_lcd_renderer_class, + + FT_MODULE_RENDERER, + sizeof ( FT_RendererRec ), + + "smooth-lcd", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render_lcd, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + + FT_DEFINE_RENDERER( ft_smooth_lcdv_renderer_class, + + FT_MODULE_RENDERER, + sizeof ( FT_RendererRec ), + + "smooth-lcdv", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + + +/* END */ diff --git a/drivers/freetype/src/smooth/ftsmooth.h b/drivers/freetype/src/smooth/ftsmooth.h new file mode 100644 index 0000000000..3708790df1 --- /dev/null +++ b/drivers/freetype/src/smooth/ftsmooth.h @@ -0,0 +1,49 @@ +/***************************************************************************/ +/* */ +/* ftsmooth.h */ +/* */ +/* Anti-aliasing renderer interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTSMOOTH_H__ +#define __FTSMOOTH_H__ + + +#include <ft2build.h> +#include FT_RENDER_H + + +FT_BEGIN_HEADER + + +#ifndef FT_CONFIG_OPTION_NO_STD_RASTER + FT_DECLARE_RENDERER( ft_std_renderer_class ) +#endif + +#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER + FT_DECLARE_RENDERER( ft_smooth_renderer_class ) + + FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class ) + + FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class ) +#endif + + + +FT_END_HEADER + +#endif /* __FTSMOOTH_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/smooth/ftspic.c b/drivers/freetype/src/smooth/ftspic.c new file mode 100644 index 0000000000..67a2b8310c --- /dev/null +++ b/drivers/freetype/src/smooth/ftspic.c @@ -0,0 +1,118 @@ +/***************************************************************************/ +/* */ +/* ftspic.c */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009, 2010, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ftspic.h" +#include "ftsmerrs.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftgrays.c */ + void + FT_Init_Class_ft_grays_raster( FT_Raster_Funcs* funcs ); + + + void + ft_smooth_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->smooth ) + { + SmoothPIC* container = (SmoothPIC*)pic_container->smooth; + + + if ( --container->ref_count ) + return; + + FT_FREE( container ); + pic_container->smooth = NULL; + } + } + + + FT_Error + ft_smooth_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + SmoothPIC* container = NULL; + FT_Memory memory = library->memory; + + + /* since this function also serve smooth_lcd and smooth_lcdv renderers, + it implements reference counting */ + if ( pic_container->smooth ) + { + ((SmoothPIC*)pic_container->smooth)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->smooth = container; + + container->ref_count = 1; + + /* initialize pointer table - */ + /* this is how the module usually expects this data */ + FT_Init_Class_ft_grays_raster( &container->ft_grays_raster ); + + return error; + } + + + /* re-route these init and free functions to the above functions */ + FT_Error + ft_smooth_lcd_renderer_class_pic_init( FT_Library library ) + { + return ft_smooth_renderer_class_pic_init( library ); + } + + + void + ft_smooth_lcd_renderer_class_pic_free( FT_Library library ) + { + ft_smooth_renderer_class_pic_free( library ); + } + + + FT_Error + ft_smooth_lcdv_renderer_class_pic_init( FT_Library library ) + { + return ft_smooth_renderer_class_pic_init( library ); + } + + + void + ft_smooth_lcdv_renderer_class_pic_free( FT_Library library ) + { + ft_smooth_renderer_class_pic_free( library ); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/smooth/ftspic.h b/drivers/freetype/src/smooth/ftspic.h new file mode 100644 index 0000000000..334b51c3f1 --- /dev/null +++ b/drivers/freetype/src/smooth/ftspic.h @@ -0,0 +1,74 @@ +/***************************************************************************/ +/* */ +/* ftspic.h */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __FTSPIC_H__ +#define __FTSPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_GRAYS_RASTER_GET ft_grays_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct SmoothPIC_ + { + int ref_count; + FT_Raster_Funcs ft_grays_raster; + + } SmoothPIC; + + +#define GET_PIC( lib ) \ + ( (SmoothPIC*)( (lib)->pic_container.smooth ) ) +#define FT_GRAYS_RASTER_GET ( GET_PIC( library )->ft_grays_raster ) + + + /* see ftspic.c for the implementation */ + void + ft_smooth_renderer_class_pic_free( FT_Library library ); + + void + ft_smooth_lcd_renderer_class_pic_free( FT_Library library ); + + void + ft_smooth_lcdv_renderer_class_pic_free( FT_Library library ); + + FT_Error + ft_smooth_renderer_class_pic_init( FT_Library library ); + + FT_Error + ft_smooth_lcd_renderer_class_pic_init( FT_Library library ); + + FT_Error + ft_smooth_lcdv_renderer_class_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTSPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/smooth/module.mk b/drivers/freetype/src/smooth/module.mk new file mode 100644 index 0000000000..47f6c04076 --- /dev/null +++ b/drivers/freetype/src/smooth/module.mk @@ -0,0 +1,27 @@ +# +# FreeType 2 smooth renderer module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += SMOOTH_RENDERER + +define SMOOTH_RENDERER +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_renderer_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcd_renderer_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for LCDs$(ECHO_DRIVER_DONE) +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcdv_renderer_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for vertical LCDs$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/smooth/rules.mk b/drivers/freetype/src/smooth/rules.mk new file mode 100644 index 0000000000..88d0aa53ac --- /dev/null +++ b/drivers/freetype/src/smooth/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 smooth renderer module build rules +# + + +# Copyright 1996-2000, 2001, 2003, 2011 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. + + +# smooth driver directory +# +SMOOTH_DIR := $(SRC_DIR)/smooth + +# compilation flags for the driver +# +SMOOTH_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SMOOTH_DIR)) + + +# smooth driver sources (i.e., C files) +# +SMOOTH_DRV_SRC := $(SMOOTH_DIR)/ftgrays.c \ + $(SMOOTH_DIR)/ftsmooth.c \ + $(SMOOTH_DIR)/ftspic.c + + +# smooth driver headers +# +SMOOTH_DRV_H := $(SMOOTH_DRV_SRC:%c=%h) \ + $(SMOOTH_DIR)/ftsmerrs.h + + +# smooth driver object(s) +# +# SMOOTH_DRV_OBJ_M is used during `multi' builds. +# SMOOTH_DRV_OBJ_S is used during `single' builds. +# +SMOOTH_DRV_OBJ_M := $(SMOOTH_DRV_SRC:$(SMOOTH_DIR)/%.c=$(OBJ_DIR)/%.$O) +SMOOTH_DRV_OBJ_S := $(OBJ_DIR)/smooth.$O + +# smooth driver source file for single build +# +SMOOTH_DRV_SRC_S := $(SMOOTH_DIR)/smooth.c + + +# smooth driver - single object +# +$(SMOOTH_DRV_OBJ_S): $(SMOOTH_DRV_SRC_S) $(SMOOTH_DRV_SRC) \ + $(FREETYPE_H) $(SMOOTH_DRV_H) + $(SMOOTH_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SMOOTH_DRV_SRC_S)) + + +# smooth driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(SMOOTH_DIR)/%.c $(FREETYPE_H) $(SMOOTH_DRV_H) + $(SMOOTH_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(SMOOTH_DRV_OBJ_S) +DRV_OBJS_M += $(SMOOTH_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/smooth/smooth.c b/drivers/freetype/src/smooth/smooth.c new file mode 100644 index 0000000000..a8ac51f9f8 --- /dev/null +++ b/drivers/freetype/src/smooth/smooth.c @@ -0,0 +1,27 @@ +/***************************************************************************/ +/* */ +/* smooth.c */ +/* */ +/* FreeType anti-aliasing rasterer module component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ftspic.c" +#include "ftgrays.c" +#include "ftsmooth.c" + + +/* END */ diff --git a/drivers/freetype/src/truetype/Jamfile b/drivers/freetype/src/truetype/Jamfile new file mode 100644 index 0000000000..a8cccfe137 --- /dev/null +++ b/drivers/freetype/src/truetype/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/truetype Jamfile +# +# Copyright 2001, 2004 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) truetype ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ttpic ; + } + else + { + _sources = truetype ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/truetype Jamfile diff --git a/drivers/freetype/src/truetype/module.mk b/drivers/freetype/src/truetype/module.mk new file mode 100644 index 0000000000..baee81a773 --- /dev/null +++ b/drivers/freetype/src/truetype/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 TrueType module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += TRUETYPE_DRIVER + +define TRUETYPE_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, tt_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/truetype/rules.mk b/drivers/freetype/src/truetype/rules.mk new file mode 100644 index 0000000000..d4b69f578b --- /dev/null +++ b/drivers/freetype/src/truetype/rules.mk @@ -0,0 +1,74 @@ +# +# FreeType 2 TrueType driver configuration rules +# + + +# Copyright 1996-2001, 2003-2004, 2011-2012 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. + + +# TrueType driver directory +# +TT_DIR := $(SRC_DIR)/truetype + + +# compilation flags for the driver +# +TT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) + + +# TrueType driver sources (i.e., C files) +# +TT_DRV_SRC := $(TT_DIR)/ttdriver.c \ + $(TT_DIR)/ttgload.c \ + $(TT_DIR)/ttgxvar.c \ + $(TT_DIR)/ttinterp.c \ + $(TT_DIR)/ttobjs.c \ + $(TT_DIR)/ttpic.c \ + $(TT_DIR)/ttpload.c \ + $(TT_DIR)/ttsubpix.c + +# TrueType driver headers +# +TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) \ + $(TT_DIR)/tterrors.h + + +# TrueType driver object(s) +# +# TT_DRV_OBJ_M is used during `multi' builds +# TT_DRV_OBJ_S is used during `single' builds +# +TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR)/%.c=$(OBJ_DIR)/%.$O) +TT_DRV_OBJ_S := $(OBJ_DIR)/truetype.$O + +# TrueType driver source file for single build +# +TT_DRV_SRC_S := $(TT_DIR)/truetype.c + + +# TrueType driver - single object +# +$(TT_DRV_OBJ_S): $(TT_DRV_SRC_S) $(TT_DRV_SRC) $(FREETYPE_H) $(TT_DRV_H) + $(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(TT_DRV_SRC_S)) + + +# driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(TT_DIR)/%.c $(FREETYPE_H) $(TT_DRV_H) + $(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(TT_DRV_OBJ_S) +DRV_OBJS_M += $(TT_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/truetype/truetype.c b/drivers/freetype/src/truetype/truetype.c new file mode 100644 index 0000000000..576912b219 --- /dev/null +++ b/drivers/freetype/src/truetype/truetype.c @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* truetype.c */ +/* */ +/* FreeType TrueType driver component (body only). */ +/* */ +/* Copyright 1996-2001, 2004, 2006, 2012 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ttpic.c" +#include "ttdriver.c" /* driver interface */ +#include "ttpload.c" /* tables loader */ +#include "ttgload.c" /* glyph loader */ +#include "ttobjs.c" /* object manager */ + +#ifdef TT_USE_BYTECODE_INTERPRETER +#include "ttinterp.c" +#include "ttsubpix.c" +#endif + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.c" /* gx distortable font */ +#endif + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttdriver.c b/drivers/freetype/src/truetype/ttdriver.c new file mode 100644 index 0000000000..fb25706ab8 --- /dev/null +++ b/drivers/freetype/src/truetype/ttdriver.c @@ -0,0 +1,572 @@ +/***************************************************************************/ +/* */ +/* ttdriver.c */ +/* */ +/* TrueType font driver implementation (body). */ +/* */ +/* Copyright 1996-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_SERVICE_XFREE86_NAME_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif + +#include FT_SERVICE_TRUETYPE_ENGINE_H +#include FT_SERVICE_TRUETYPE_GLYF_H +#include FT_SERVICE_PROPERTIES_H +#include FT_TRUETYPE_DRIVER_H + +#include "ttdriver.h" +#include "ttgload.h" +#include "ttpload.h" + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif + +#include "tterrors.h" + +#include "ttpic.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_ttdriver + + + /* + * PROPERTY SERVICE + * + */ + static FT_Error + tt_property_set( FT_Module module, /* TT_Driver */ + const char* property_name, + const void* value ) + { + FT_Error error = FT_Err_Ok; + TT_Driver driver = (TT_Driver)module; + + + if ( !ft_strcmp( property_name, "interpreter-version" ) ) + { + FT_UInt* interpreter_version = (FT_UInt*)value; + + +#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) + error = FT_ERR( Unimplemented_Feature ); + else +#endif + driver->interpreter_version = *interpreter_version; + + return error; + } + + FT_TRACE0(( "tt_property_set: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + static FT_Error + tt_property_get( FT_Module module, /* TT_Driver */ + const char* property_name, + const void* value ) + { + FT_Error error = FT_Err_Ok; + TT_Driver driver = (TT_Driver)module; + + FT_UInt interpreter_version = driver->interpreter_version; + + + if ( !ft_strcmp( property_name, "interpreter-version" ) ) + { + FT_UInt* val = (FT_UInt*)value; + + + *val = interpreter_version; + + return error; + } + + FT_TRACE0(( "tt_property_get: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + FT_DEFINE_SERVICE_PROPERTIESREC( + tt_service_properties, + (FT_Properties_SetFunc)tt_property_set, + (FT_Properties_GetFunc)tt_property_get ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F A C E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#undef PAIR_TAG +#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ + (FT_ULong)right ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_get_kerning */ + /* */ + /* <Description> */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* <Output> */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings, are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + static FT_Error + tt_get_kerning( FT_Face ttface, /* TT_Face */ + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + TT_Face face = (TT_Face)ttface; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + kerning->x = 0; + kerning->y = 0; + + if ( sfnt ) + kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); + + return 0; + } + + +#undef PAIR_TAG + + + static FT_Error + tt_get_advances( FT_Face ttface, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed *advances ) + { + FT_UInt nn; + TT_Face face = (TT_Face) ttface; + + + /* XXX: TODO: check for sbits */ + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + { + FT_Short tsb; + FT_UShort ah; + + + TT_Get_VMetrics( face, start + nn, &tsb, &ah ); + advances[nn] = ah; + } + } + else + { + for ( nn = 0; nn < count; nn++ ) + { + FT_Short lsb; + FT_UShort aw; + + + TT_Get_HMetrics( face, start + nn, &lsb, &aw ); + advances[nn] = aw; + } + } + + return FT_Err_Ok; + } + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** S I Z E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + static FT_Error + tt_size_select( FT_Size size, + FT_ULong strike_index ) + { + TT_Face ttface = (TT_Face)size->face; + TT_Size ttsize = (TT_Size)size; + FT_Error error = FT_Err_Ok; + + + ttsize->strike_index = strike_index; + + if ( FT_IS_SCALABLE( size->face ) ) + { + /* use the scaled metrics, even when tt_size_reset fails */ + FT_Select_Metrics( size->face, strike_index ); + + tt_size_reset( ttsize ); + } + else + { + SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + FT_Size_Metrics* metrics = &size->metrics; + + + error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); + if ( error ) + ttsize->strike_index = 0xFFFFFFFFUL; + } + + return error; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + static FT_Error + tt_size_request( FT_Size size, + FT_Size_Request req ) + { + TT_Size ttsize = (TT_Size)size; + FT_Error error = FT_Err_Ok; + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + if ( FT_HAS_FIXED_SIZES( size->face ) ) + { + TT_Face ttface = (TT_Face)size->face; + SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + FT_ULong strike_index; + + + error = sfnt->set_sbit_strike( ttface, req, &strike_index ); + + if ( error ) + ttsize->strike_index = 0xFFFFFFFFUL; + else + return tt_size_select( size, strike_index ); + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + FT_Request_Metrics( size->face, req ); + + if ( FT_IS_SCALABLE( size->face ) ) + { + error = tt_size_reset( ttsize ); + ttsize->root.metrics = ttsize->metrics; + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_glyph_load */ + /* */ + /* <Description> */ + /* A driver method used to load a glyph within a given glyph slot. */ + /* */ + /* <Input> */ + /* slot :: A handle to the target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled, loaded, etc. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ + FT_Size ttsize, /* TT_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; + TT_Size size = (TT_Size)ttsize; + FT_Face face = ttslot->face; + FT_Error error; + + + if ( !slot ) + return FT_THROW( Invalid_Slot_Handle ); + + if ( !size ) + return FT_THROW( Invalid_Size_Handle ); + + if ( !face ) + return FT_THROW( Invalid_Argument ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_index >= (FT_UInt)face->num_glyphs && + !face->internal->incremental_interface ) +#else + if ( glyph_index >= (FT_UInt)face->num_glyphs ) +#endif + return FT_THROW( Invalid_Argument ); + + if ( load_flags & FT_LOAD_NO_HINTING ) + { + /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ + /* are necessary to disable hinting for tricky fonts */ + + if ( FT_IS_TRICKY( face ) ) + load_flags &= ~FT_LOAD_NO_HINTING; + + if ( load_flags & FT_LOAD_NO_AUTOHINT ) + load_flags |= FT_LOAD_NO_HINTING; + } + + if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) + { + load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; + + if ( !FT_IS_TRICKY( face ) ) + load_flags |= FT_LOAD_NO_HINTING; + } + + /* now load the glyph outline if necessary */ + error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); + + /* force drop-out mode to 2 - irrelevant now */ + /* slot->outline.dropout_mode = 2; */ + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** D R I V E R I N T E R F A C E ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICE_MULTIMASTERSREC( + tt_service_gx_multi_masters, + (FT_Get_MM_Func) NULL, + (FT_Set_MM_Design_Func) NULL, + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, + (FT_Get_MM_Var_Func) TT_Get_MM_Var, + (FT_Set_Var_Design_Func)TT_Set_Var_Design ) +#endif + + static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = + { +#ifdef TT_USE_BYTECODE_INTERPRETER + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_TRUETYPE_ENGINE_TYPE_UNPATENTED +#else + FT_TRUETYPE_ENGINE_TYPE_PATENTED +#endif + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_TRUETYPE_ENGINE_TYPE_NONE + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + }; + + FT_DEFINE_SERVICE_TTGLYFREC( + tt_service_truetype_glyf, + (TT_Glyf_GetLocationFunc)tt_face_get_location ) + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICEDESCREC5( + tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, + FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) +#else + FT_DEFINE_SERVICEDESCREC4( + tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, + FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) +#endif + + + FT_CALLBACK_DEF( FT_Module_Interface ) + tt_get_interface( FT_Module driver, /* TT_Driver */ + const char* tt_interface ) + { + FT_Library library; + FT_Module_Interface result; + FT_Module sfntd; + SFNT_Service sfnt; + + + /* TT_SERVICES_GET derefers `library' in PIC mode */ +#ifdef FT_CONFIG_OPTION_PIC + if ( !driver ) + return NULL; + library = driver->library; + if ( !library ) + return NULL; +#endif + + result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); + if ( result != NULL ) + return result; + +#ifndef FT_CONFIG_OPTION_PIC + if ( !driver ) + return NULL; + library = driver->library; + if ( !library ) + return NULL; +#endif + + /* only return the default interface from the SFNT module */ + sfntd = FT_Get_Module( library, "sfnt" ); + if ( sfntd ) + { + sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); + if ( sfnt ) + return sfnt->get_interface( driver, tt_interface ); + } + + return 0; + } + + + /* The FT_DriverInterface structure is defined in ftdriver.h. */ + +#ifdef TT_USE_BYTECODE_INTERPRETER +#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER +#else +#define TT_HINTER_FLAG 0 +#endif + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define TT_SIZE_SELECT tt_size_select +#else +#define TT_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER( + tt_driver_class, + + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + TT_HINTER_FLAG, + + sizeof ( TT_DriverRec ), + + "truetype", /* driver name */ + 0x10000L, /* driver version == 1.0 */ + 0x20000L, /* driver requires FreeType 2.0 or above */ + + (void*)0, /* driver specific interface */ + + tt_driver_init, + tt_driver_done, + tt_get_interface, + + sizeof ( TT_FaceRec ), + sizeof ( TT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + tt_face_init, + tt_face_done, + tt_size_init, + tt_size_done, + tt_slot_init, + 0, /* FT_Slot_DoneFunc */ + + tt_glyph_load, + + tt_get_kerning, + 0, /* FT_Face_AttachFunc */ + tt_get_advances, + + tt_size_request, + TT_SIZE_SELECT + ) + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttdriver.h b/drivers/freetype/src/truetype/ttdriver.h new file mode 100644 index 0000000000..aae00f2617 --- /dev/null +++ b/drivers/freetype/src/truetype/ttdriver.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* ttdriver.h */ +/* */ +/* High-level TrueType driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTDRIVER_H__ +#define __TTDRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_DRIVER( tt_driver_class ) + + +FT_END_HEADER + +#endif /* __TTDRIVER_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/tterrors.h b/drivers/freetype/src/truetype/tterrors.h new file mode 100644 index 0000000000..78d138fab2 --- /dev/null +++ b/drivers/freetype/src/truetype/tterrors.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* tterrors.h */ +/* */ +/* TrueType error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the TrueType error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __TTERRORS_H__ +#define __TTERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX TT_Err_ +#define FT_ERR_BASE FT_Mod_Err_TrueType + +#include FT_ERRORS_H + +#endif /* __TTERRORS_H__ */ + +/* END */ diff --git a/drivers/freetype/src/truetype/ttgload.c b/drivers/freetype/src/truetype/ttgload.c new file mode 100644 index 0000000000..f640a6c78e --- /dev/null +++ b/drivers/freetype/src/truetype/ttgload.c @@ -0,0 +1,2328 @@ +/***************************************************************************/ +/* */ +/* ttgload.c */ +/* */ +/* TrueType Glyph Loader (body). */ +/* */ +/* Copyright 1996-2013 */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_TAGS_H +#include FT_OUTLINE_H +#include FT_TRUETYPE_DRIVER_H + +#include "ttgload.h" +#include "ttpload.h" + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif + +#include "tterrors.h" +#include "ttsubpix.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_ttgload + + + /*************************************************************************/ + /* */ + /* Composite glyph flags. */ + /* */ +#define ARGS_ARE_WORDS 0x0001 +#define ARGS_ARE_XY_VALUES 0x0002 +#define ROUND_XY_TO_GRID 0x0004 +#define WE_HAVE_A_SCALE 0x0008 +/* reserved 0x0010 */ +#define MORE_COMPONENTS 0x0020 +#define WE_HAVE_AN_XY_SCALE 0x0040 +#define WE_HAVE_A_2X2 0x0080 +#define WE_HAVE_INSTR 0x0100 +#define USE_MY_METRICS 0x0200 +#define OVERLAP_COMPOUND 0x0400 +#define SCALED_COMPONENT_OFFSET 0x0800 +#define UNSCALED_COMPONENT_OFFSET 0x1000 + + + /*************************************************************************/ + /* */ + /* Return the horizontal metrics in font units for a given glyph. */ + /* */ + FT_LOCAL_DEF( void ) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Short* lsb, + FT_UShort* aw ) + { + ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw ); + + FT_TRACE5(( " advance width (font units): %d\n", *aw )); + FT_TRACE5(( " left side bearing (font units): %d\n", *lsb )); + } + + + /*************************************************************************/ + /* */ + /* Return the vertical metrics in font units for a given glyph. */ + /* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */ + /* table, typoAscender/Descender from the `OS/2' table would be used */ + /* instead, and if there were no `OS/2' table, use ascender/descender */ + /* from the `hhea' table. But that is not what Microsoft's rasterizer */ + /* apparently does: It uses the ppem value as the advance height, and */ + /* sets the top side bearing to be zero. */ + /* */ + FT_LOCAL_DEF( void ) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Short* tsb, + FT_UShort* ah ) + { + if ( face->vertical_info ) + ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah ); + +#if 1 /* Empirically determined, at variance with what MS said */ + + else + { + *tsb = 0; + *ah = face->root.units_per_EM; + } + +#else /* This is what MS said to do. It isn't what they do, however. */ + + else if ( face->os2.version != 0xFFFFU ) + { + *tsb = face->os2.sTypoAscender; + *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; + } + else + { + *tsb = face->horizontal.Ascender; + *ah = face->horizontal.Ascender - face->horizontal.Descender; + } + +#endif + + FT_TRACE5(( " advance height (font units): %d\n", *ah )); + FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); + } + + + static void + tt_get_metrics( TT_Loader loader, + FT_UInt glyph_index ) + { + TT_Face face = (TT_Face)loader->face; +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); +#endif + + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + + + TT_Get_HMetrics( face, glyph_index, + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + &top_bearing, + &advance_height ); + + loader->left_bearing = left_bearing; + loader->advance = advance_width; + loader->top_bearing = top_bearing; + loader->vadvance = advance_height; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + if ( loader->exec ) + loader->exec->sph_tweak_flags = 0; + + /* this may not be the right place for this, but it works */ + if ( loader->exec && loader->exec->ignore_x_mode ) + sph_set_tweaks( loader, glyph_index ); + } +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } + } + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + static void + tt_get_metrics_incr_overrides( TT_Loader loader, + FT_UInt glyph_index ) + { + TT_Face face = (TT_Face)loader->face; + + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + + + /* If this is an incrementally loaded font check whether there are */ + /* overriding metrics for this glyph. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + FT_Error error; + + + metrics.bearing_x = loader->left_bearing; + metrics.bearing_y = 0; + metrics.advance = loader->advance; + metrics.advance_v = 0; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + if ( error ) + goto Exit; + + left_bearing = (FT_Short)metrics.bearing_x; + advance_width = (FT_UShort)metrics.advance; + +#if 0 + + /* GWW: Do I do the same for vertical metrics? */ + metrics.bearing_x = 0; + metrics.bearing_y = loader->top_bearing; + metrics.advance = loader->vadvance; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, TRUE, &metrics ); + if ( error ) + goto Exit; + + top_bearing = (FT_Short)metrics.bearing_y; + advance_height = (FT_UShort)metrics.advance; + +#endif /* 0 */ + + loader->left_bearing = left_bearing; + loader->advance = advance_width; + loader->top_bearing = top_bearing; + loader->vadvance = advance_height; + + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } + } + + Exit: + return; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + + /*************************************************************************/ + /* */ + /* Translates an array of coordinates. */ + /* */ + static void + translate_array( FT_UInt n, + FT_Vector* coords, + FT_Pos delta_x, + FT_Pos delta_y ) + { + FT_UInt k; + + + if ( delta_x ) + for ( k = 0; k < n; k++ ) + coords[k].x += delta_x; + + if ( delta_y ) + for ( k = 0; k < n; k++ ) + coords[k].y += delta_y; + } + + + /*************************************************************************/ + /* */ + /* The following functions are used by default with TrueType fonts. */ + /* However, they can be replaced by alternatives if we need to support */ + /* TrueType-compressed formats (like MicroType) in the future. */ + /* */ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Error ) + TT_Access_Glyph_Frame( TT_Loader loader, + FT_UInt glyph_index, + FT_ULong offset, + FT_UInt byte_count ) + { + FT_Error error; + FT_Stream stream = loader->stream; + + /* for non-debug mode */ + FT_UNUSED( glyph_index ); + + + FT_TRACE4(( "Glyph %ld\n", glyph_index )); + + /* the following line sets the `error' variable through macros! */ + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) + return error; + + loader->cursor = stream->cursor; + loader->limit = stream->limit; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + TT_Forget_Glyph_Frame( TT_Loader loader ) + { + FT_Stream stream = loader->stream; + + + FT_FRAME_EXIT(); + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Glyph_Header( TT_Loader loader ) + { + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; + + + if ( p + 10 > limit ) + return FT_THROW( Invalid_Outline ); + + loader->n_contours = FT_NEXT_SHORT( p ); + + loader->bbox.xMin = FT_NEXT_SHORT( p ); + loader->bbox.yMin = FT_NEXT_SHORT( p ); + loader->bbox.xMax = FT_NEXT_SHORT( p ); + loader->bbox.yMax = FT_NEXT_SHORT( p ); + + FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); + FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, + loader->bbox.xMax )); + FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, + loader->bbox.yMax )); + loader->cursor = p; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Simple_Glyph( TT_Loader load ) + { + FT_Error error; + FT_Byte* p = load->cursor; + FT_Byte* limit = load->limit; + FT_GlyphLoader gloader = load->gloader; + FT_Int n_contours = load->n_contours; + FT_Outline* outline; + TT_Face face = (TT_Face)load->face; + FT_UShort n_ins; + FT_Int n_points; + + FT_Byte *flag, *flag_limit; + FT_Byte c, count; + FT_Vector *vec, *vec_limit; + FT_Pos x; + FT_Short *cont, *cont_limit, prev_cont; + FT_Int xy_size = 0; + + + /* check that we can add the contours to the glyph */ + error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours ); + if ( error ) + goto Fail; + + /* reading the contours' endpoints & number of points */ + cont = gloader->current.outline.contours; + cont_limit = cont + n_contours; + + /* check space for contours array + instructions count */ + if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) + goto Invalid_Outline; + + prev_cont = FT_NEXT_SHORT( p ); + + if ( n_contours > 0 ) + cont[0] = prev_cont; + + if ( prev_cont < 0 ) + goto Invalid_Outline; + + for ( cont++; cont < cont_limit; cont++ ) + { + cont[0] = FT_NEXT_SHORT( p ); + if ( cont[0] <= prev_cont ) + { + /* unordered contours: this is invalid */ + goto Invalid_Outline; + } + prev_cont = cont[0]; + } + + n_points = 0; + if ( n_contours > 0 ) + { + n_points = cont[-1] + 1; + if ( n_points < 0 ) + goto Invalid_Outline; + } + + /* note that we will add four phantom points later */ + error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 ); + if ( error ) + goto Fail; + + /* reading the bytecode instructions */ + load->glyph->control_len = 0; + load->glyph->control_data = 0; + + if ( p + 2 > limit ) + goto Invalid_Outline; + + n_ins = FT_NEXT_USHORT( p ); + + FT_TRACE5(( " Instructions size: %u\n", n_ins )); + + if ( n_ins > face->max_profile.maxSizeOfInstructions ) + { + FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", + n_ins )); + error = FT_THROW( Too_Many_Hints ); + goto Fail; + } + + if ( ( limit - p ) < n_ins ) + { + FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); + error = FT_THROW( Too_Many_Hints ); + goto Fail; + } + +#ifdef TT_USE_BYTECODE_INTERPRETER + + if ( IS_HINTED( load->load_flags ) ) + { + load->glyph->control_len = n_ins; + load->glyph->control_data = load->exec->glyphIns; + + FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + p += n_ins; + + outline = &gloader->current.outline; + + /* reading the point tags */ + flag = (FT_Byte*)outline->tags; + flag_limit = flag + n_points; + + FT_ASSERT( flag != NULL ); + + while ( flag < flag_limit ) + { + if ( p + 1 > limit ) + goto Invalid_Outline; + + *flag++ = c = FT_NEXT_BYTE( p ); + if ( c & 8 ) + { + if ( p + 1 > limit ) + goto Invalid_Outline; + + count = FT_NEXT_BYTE( p ); + if ( flag + (FT_Int)count > flag_limit ) + goto Invalid_Outline; + + for ( ; count > 0; count-- ) + *flag++ = c; + } + } + + /* reading the X coordinates */ + + vec = outline->points; + vec_limit = vec + n_points; + flag = (FT_Byte*)outline->tags; + x = 0; + + if ( p + xy_size > limit ) + goto Invalid_Outline; + + for ( ; vec < vec_limit; vec++, flag++ ) + { + FT_Pos y = 0; + FT_Byte f = *flag; + + + if ( f & 2 ) + { + if ( p + 1 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_BYTE( p ); + if ( ( f & 16 ) == 0 ) + y = -y; + } + else if ( ( f & 16 ) == 0 ) + { + if ( p + 2 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_SHORT( p ); + } + + x += y; + vec->x = x; + /* the cast is for stupid compilers */ + *flag = (FT_Byte)( f & ~( 2 | 16 ) ); + } + + /* reading the Y coordinates */ + + vec = gloader->current.outline.points; + vec_limit = vec + n_points; + flag = (FT_Byte*)outline->tags; + x = 0; + + for ( ; vec < vec_limit; vec++, flag++ ) + { + FT_Pos y = 0; + FT_Byte f = *flag; + + + if ( f & 4 ) + { + if ( p + 1 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_BYTE( p ); + if ( ( f & 32 ) == 0 ) + y = -y; + } + else if ( ( f & 32 ) == 0 ) + { + if ( p + 2 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_SHORT( p ); + } + + x += y; + vec->y = x; + /* the cast is for stupid compilers */ + *flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); + } + + outline->n_points = (FT_UShort)n_points; + outline->n_contours = (FT_Short) n_contours; + + load->cursor = p; + + Fail: + return error; + + Invalid_Outline: + error = FT_THROW( Invalid_Outline ); + goto Fail; + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Composite_Glyph( TT_Loader loader ) + { + FT_Error error; + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; + FT_GlyphLoader gloader = loader->gloader; + FT_SubGlyph subglyph; + FT_UInt num_subglyphs; + + + num_subglyphs = 0; + + do + { + FT_Fixed xx, xy, yy, yx; + FT_UInt count; + + + /* check that we can load a new subglyph */ + error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 ); + if ( error ) + goto Fail; + + /* check space */ + if ( p + 4 > limit ) + goto Invalid_Composite; + + subglyph = gloader->current.subglyphs + num_subglyphs; + + subglyph->arg1 = subglyph->arg2 = 0; + + subglyph->flags = FT_NEXT_USHORT( p ); + subglyph->index = FT_NEXT_USHORT( p ); + + /* check space */ + count = 2; + if ( subglyph->flags & ARGS_ARE_WORDS ) + count += 2; + if ( subglyph->flags & WE_HAVE_A_SCALE ) + count += 2; + else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) + count += 4; + else if ( subglyph->flags & WE_HAVE_A_2X2 ) + count += 8; + + if ( p + count > limit ) + goto Invalid_Composite; + + /* read arguments */ + if ( subglyph->flags & ARGS_ARE_WORDS ) + { + subglyph->arg1 = FT_NEXT_SHORT( p ); + subglyph->arg2 = FT_NEXT_SHORT( p ); + } + else + { + subglyph->arg1 = FT_NEXT_CHAR( p ); + subglyph->arg2 = FT_NEXT_CHAR( p ); + } + + /* read transform */ + xx = yy = 0x10000L; + xy = yx = 0; + + if ( subglyph->flags & WE_HAVE_A_SCALE ) + { + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = xx; + } + else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) + { + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + } + else if ( subglyph->flags & WE_HAVE_A_2X2 ) + { + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + } + + subglyph->transform.xx = xx; + subglyph->transform.xy = xy; + subglyph->transform.yx = yx; + subglyph->transform.yy = yy; + + num_subglyphs++; + + } while ( subglyph->flags & MORE_COMPONENTS ); + + gloader->current.num_subglyphs = num_subglyphs; + +#ifdef TT_USE_BYTECODE_INTERPRETER + + { + FT_Stream stream = loader->stream; + + + /* we must undo the FT_FRAME_ENTER in order to point */ + /* to the composite instructions, if we find some. */ + /* We will process them later. */ + /* */ + loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + + p - limit ); + } + +#endif + + loader->cursor = p; + + Fail: + return error; + + Invalid_Composite: + error = FT_THROW( Invalid_Composite ); + goto Fail; + } + + + FT_LOCAL_DEF( void ) + TT_Init_Glyph_Loading( TT_Face face ) + { + face->access_glyph_frame = TT_Access_Glyph_Frame; + face->read_glyph_header = TT_Load_Glyph_Header; + face->read_simple_glyph = TT_Load_Simple_Glyph; + face->read_composite_glyph = TT_Load_Composite_Glyph; + face->forget_glyph_frame = TT_Forget_Glyph_Frame; + } + + + static void + tt_prepare_zone( TT_GlyphZone zone, + FT_GlyphLoad load, + FT_UInt start_point, + FT_UInt start_contour ) + { + zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); + zone->n_contours = (FT_Short) ( load->outline.n_contours - + start_contour ); + zone->org = load->extra_points + start_point; + zone->cur = load->outline.points + start_point; + zone->orus = load->extra_points2 + start_point; + zone->tags = (FT_Byte*)load->outline.tags + start_point; + zone->contours = (FT_UShort*)load->outline.contours + start_contour; + zone->first_point = (FT_UShort)start_point; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Hint_Glyph */ + /* */ + /* <Description> */ + /* Hint the glyph using the zone prepared by the caller. Note that */ + /* the zone is supposed to include four phantom points. */ + /* */ + static FT_Error + TT_Hint_Glyph( TT_Loader loader, + FT_Bool is_composite ) + { +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Face face = (TT_Face)loader->face; + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); +#endif + + TT_GlyphZone zone = &loader->zone; + FT_Pos origin; + +#ifdef TT_USE_BYTECODE_INTERPRETER + FT_UInt n_ins; +#else + FT_UNUSED( is_composite ); +#endif + + +#ifdef TT_USE_BYTECODE_INTERPRETER + if ( loader->glyph->control_len > 0xFFFFL ) + { + FT_TRACE1(( "TT_Hint_Glyph: too long instructions " )); + FT_TRACE1(( "(0x%lx byte) is truncated\n", + loader->glyph->control_len )); + } + n_ins = (FT_UInt)( loader->glyph->control_len ); +#endif + + origin = zone->cur[zone->n_points - 4].x; + origin = FT_PIX_ROUND( origin ) - origin; + if ( origin ) + translate_array( zone->n_points, zone->cur, origin, 0 ); + +#ifdef TT_USE_BYTECODE_INTERPRETER + /* save original point position in org */ + if ( n_ins > 0 ) + FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); + + /* Reset graphics state. */ + loader->exec->GS = ((TT_Size)loader->size)->GS; + + /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ + /* completely refer to the (already) hinted subglyphs. */ + if ( is_composite ) + { + loader->exec->metrics.x_scale = 1 << 16; + loader->exec->metrics.y_scale = 1 << 16; + + FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); + } + else + { + loader->exec->metrics.x_scale = + ((TT_Size)loader->size)->metrics.x_scale; + loader->exec->metrics.y_scale = + ((TT_Size)loader->size)->metrics.y_scale; + } +#endif + + /* round pp2 and pp4 */ + zone->cur[zone->n_points - 3].x = + FT_PIX_ROUND( zone->cur[zone->n_points - 3].x ); + zone->cur[zone->n_points - 1].y = + FT_PIX_ROUND( zone->cur[zone->n_points - 1].y ); + +#ifdef TT_USE_BYTECODE_INTERPRETER + + if ( n_ins > 0 ) + { + FT_Bool debug; + FT_Error error; + + FT_GlyphLoader gloader = loader->gloader; + FT_Outline current_outline = gloader->current.outline; + + + error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, + loader->exec->glyphIns, n_ins ); + if ( error ) + return error; + + loader->exec->is_composite = is_composite; + loader->exec->pts = *zone; + + debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && + ((TT_Size)loader->size)->debug ); + + error = TT_Run_Context( loader->exec, debug ); + if ( error && loader->exec->pedantic_hinting ) + return error; + + /* store drop-out mode in bits 5-7; set bit 2 also as a marker */ + current_outline.tags[0] |= + ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; + } + +#endif + + /* save glyph phantom points */ + if ( !loader->preserve_pps ) + { + loader->pp1 = zone->cur[zone->n_points - 4]; + loader->pp2 = zone->cur[zone->n_points - 3]; + loader->pp3 = zone->cur[zone->n_points - 2]; + loader->pp4 = zone->cur[zone->n_points - 1]; + } + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) + FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 ); + + else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) + FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); + } +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Process_Simple_Glyph */ + /* */ + /* <Description> */ + /* Once a simple glyph has been loaded, it needs to be processed. */ + /* Usually, this means scaling and hinting through bytecode */ + /* interpretation. */ + /* */ + static FT_Error + TT_Process_Simple_Glyph( TT_Loader loader ) + { + FT_GlyphLoader gloader = loader->gloader; + FT_Error error = FT_Err_Ok; + FT_Outline* outline; + FT_Int n_points; + + + outline = &gloader->current.outline; + n_points = outline->n_points; + + /* set phantom points */ + + outline->points[n_points ] = loader->pp1; + outline->points[n_points + 1] = loader->pp2; + outline->points[n_points + 2] = loader->pp3; + outline->points[n_points + 3] = loader->pp4; + + outline->tags[n_points ] = 0; + outline->tags[n_points + 1] = 0; + outline->tags[n_points + 2] = 0; + outline->tags[n_points + 3] = 0; + + n_points += 4; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + if ( ((TT_Face)loader->face)->doblend ) + { + /* Deltas apply to the unscaled data. */ + FT_Vector* deltas; + FT_Memory memory = loader->face->memory; + FT_Int i; + + + error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), + loader->glyph_index, + &deltas, + n_points ); + if ( error ) + return error; + + for ( i = 0; i < n_points; ++i ) + { + outline->points[i].x += deltas[i].x; + outline->points[i].y += deltas[i].y; + } + + FT_FREE( deltas ); + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + if ( IS_HINTED( loader->load_flags ) ) + { + tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); + + FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, + loader->zone.n_points + 4 ); + } + + { +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Face face = (TT_Face)loader->face; + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); + + FT_String* family = face->root.family_name; + FT_Int ppem = loader->size->metrics.x_ppem; + FT_String* style = face->root.style_name; + FT_Int x_scale_factor = 1000; +#endif + + FT_Vector* vec = outline->points; + FT_Vector* limit = outline->points + n_points; + + FT_Fixed x_scale = 0; /* pacify compiler */ + FT_Fixed y_scale = 0; + + FT_Bool do_scale = FALSE; + + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + /* scale, but only if enabled and only if TT hinting is being used */ + if ( IS_HINTED( loader->load_flags ) ) + x_scale_factor = sph_test_tweak_x_scaling( face, + family, + ppem, + style, + loader->glyph_index ); + /* scale the glyph */ + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || + x_scale_factor != 1000 ) + { + x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale, + x_scale_factor, 1000 ); + y_scale = ((TT_Size)loader->size)->metrics.y_scale; + + /* compensate for any scaling by de/emboldening; */ + /* the amount was determined via experimentation */ + if ( x_scale_factor != 1000 && ppem > 11 ) + FT_Outline_EmboldenXY( outline, + FT_MulFix( 1280 * ppem, + 1000 - x_scale_factor ), + 0 ); + do_scale = TRUE; + } + } + else + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + { + /* scale the glyph */ + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + x_scale = ((TT_Size)loader->size)->metrics.x_scale; + y_scale = ((TT_Size)loader->size)->metrics.y_scale; + + do_scale = TRUE; + } + } + + if ( do_scale ) + { + for ( ; vec < limit; vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + loader->pp1 = outline->points[n_points - 4]; + loader->pp2 = outline->points[n_points - 3]; + loader->pp3 = outline->points[n_points - 2]; + loader->pp4 = outline->points[n_points - 1]; + } + } + + if ( IS_HINTED( loader->load_flags ) ) + { + loader->zone.n_points += 4; + + error = TT_Hint_Glyph( loader, 0 ); + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Process_Composite_Component */ + /* */ + /* <Description> */ + /* Once a composite component has been loaded, it needs to be */ + /* processed. Usually, this means transforming and translating. */ + /* */ + static FT_Error + TT_Process_Composite_Component( TT_Loader loader, + FT_SubGlyph subglyph, + FT_UInt start_point, + FT_UInt num_base_points ) + { + FT_GlyphLoader gloader = loader->gloader; + FT_Vector* base_vec = gloader->base.outline.points; + FT_UInt num_points = gloader->base.outline.n_points; + FT_Bool have_scale; + FT_Pos x, y; + + + have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE | + WE_HAVE_AN_XY_SCALE | + WE_HAVE_A_2X2 ) ); + + /* perform the transform required for this subglyph */ + if ( have_scale ) + { + FT_UInt i; + + + for ( i = num_base_points; i < num_points; i++ ) + FT_Vector_Transform( base_vec + i, &subglyph->transform ); + } + + /* get offset */ + if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) + { + FT_UInt k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; + + + /* match l-th point of the newly loaded component to the k-th point */ + /* of the previously loaded components. */ + + /* change to the point numbers used by our outline */ + k += start_point; + l += num_base_points; + if ( k >= num_base_points || + l >= num_points ) + return FT_THROW( Invalid_Composite ); + + p1 = gloader->base.outline.points + k; + p2 = gloader->base.outline.points + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; + } + else + { + x = subglyph->arg1; + y = subglyph->arg2; + + if ( !x && !y ) + return FT_Err_Ok; + + /* Use a default value dependent on */ + /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */ + /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */ + + if ( have_scale && +#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) ) +#else + ( subglyph->flags & SCALED_COMPONENT_OFFSET ) ) +#endif + { + +#if 0 + + /*************************************************************************/ + /* */ + /* This algorithm is what Apple documents. But it doesn't work. */ + /* */ + int a = subglyph->transform.xx > 0 ? subglyph->transform.xx + : -subglyph->transform.xx; + int b = subglyph->transform.yx > 0 ? subglyph->transform.yx + : -subglyph->transform.yx; + int c = subglyph->transform.xy > 0 ? subglyph->transform.xy + : -subglyph->transform.xy; + int d = subglyph->transform.yy > 0 ? subglyph->transform.yy + : -subglyph->transform.yy; + int m = a > b ? a : b; + int n = c > d ? c : d; + + + if ( a - b <= 33 && a - b >= -33 ) + m *= 2; + if ( c - d <= 33 && c - d >= -33 ) + n *= 2; + x = FT_MulFix( x, m ); + y = FT_MulFix( y, n ); + +#else /* 0 */ + + /*************************************************************************/ + /* */ + /* This algorithm is a guess and works much better than the above. */ + /* */ + FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx, + subglyph->transform.xy ); + FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy, + subglyph->transform.yx ); + + + x = FT_MulFix( x, mac_xscale ); + y = FT_MulFix( y, mac_yscale ); + +#endif /* 0 */ + + } + + if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) + { + FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; + FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; + + + x = FT_MulFix( x, x_scale ); + y = FT_MulFix( y, y_scale ); + + if ( subglyph->flags & ROUND_XY_TO_GRID ) + { + x = FT_PIX_ROUND( x ); + y = FT_PIX_ROUND( y ); + } + } + } + + if ( x || y ) + translate_array( num_points - num_base_points, + base_vec + num_base_points, + x, y ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Process_Composite_Glyph */ + /* */ + /* <Description> */ + /* This is slightly different from TT_Process_Simple_Glyph, in that */ + /* its sole purpose is to hint the glyph. Thus this function is */ + /* only available when bytecode interpreter is enabled. */ + /* */ + static FT_Error + TT_Process_Composite_Glyph( TT_Loader loader, + FT_UInt start_point, + FT_UInt start_contour ) + { + FT_Error error; + FT_Outline* outline; + FT_UInt i; + + + outline = &loader->gloader->base.outline; + + /* make room for phantom points */ + error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader, + outline->n_points + 4, + 0 ); + if ( error ) + return error; + + outline->points[outline->n_points ] = loader->pp1; + outline->points[outline->n_points + 1] = loader->pp2; + outline->points[outline->n_points + 2] = loader->pp3; + outline->points[outline->n_points + 3] = loader->pp4; + + outline->tags[outline->n_points ] = 0; + outline->tags[outline->n_points + 1] = 0; + outline->tags[outline->n_points + 2] = 0; + outline->tags[outline->n_points + 3] = 0; + +#ifdef TT_USE_BYTECODE_INTERPRETER + + { + FT_Stream stream = loader->stream; + FT_UShort n_ins, max_ins; + FT_ULong tmp; + + + /* TT_Load_Composite_Glyph only gives us the offset of instructions */ + /* so we read them here */ + if ( FT_STREAM_SEEK( loader->ins_pos ) || + FT_READ_USHORT( n_ins ) ) + return error; + + FT_TRACE5(( " Instructions size = %d\n", n_ins )); + + /* check it */ + max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions; + if ( n_ins > max_ins ) + { + /* acroread ignores this field, so we only do a rough safety check */ + if ( (FT_Int)n_ins > loader->byte_len ) + { + FT_TRACE1(( "TT_Process_Composite_Glyph: " + "too many instructions (%d) for glyph with length %d\n", + n_ins, loader->byte_len )); + return FT_THROW( Too_Many_Hints ); + } + + tmp = loader->exec->glyphSize; + error = Update_Max( loader->exec->memory, + &tmp, + sizeof ( FT_Byte ), + (void*)&loader->exec->glyphIns, + n_ins ); + loader->exec->glyphSize = (FT_UShort)tmp; + if ( error ) + return error; + } + else if ( n_ins == 0 ) + return FT_Err_Ok; + + if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) ) + return error; + + loader->glyph->control_data = loader->exec->glyphIns; + loader->glyph->control_len = n_ins; + } + +#endif + + tt_prepare_zone( &loader->zone, &loader->gloader->base, + start_point, start_contour ); + + /* Some points are likely touched during execution of */ + /* instructions on components. So let's untouch them. */ + for ( i = start_point; i < loader->zone.n_points; i++ ) + loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; + + loader->zone.n_points += 4; + + return TT_Hint_Glyph( loader, 1 ); + } + + + /* Calculate the four phantom points. */ + /* The first two stand for horizontal origin and advance. */ + /* The last two stand for vertical origin and advance. */ +#define TT_LOADER_SET_PP( loader ) \ + do { \ + (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ + (loader)->pp1.y = 0; \ + (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ + (loader)->pp2.y = 0; \ + (loader)->pp3.x = 0; \ + (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax; \ + (loader)->pp4.x = 0; \ + (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ + } while ( 0 ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* load_truetype_glyph */ + /* */ + /* <Description> */ + /* Loads a given truetype glyph. Handles composites and uses a */ + /* TT_Loader object. */ + /* */ + static FT_Error + load_truetype_glyph( TT_Loader loader, + FT_UInt glyph_index, + FT_UInt recurse_count, + FT_Bool header_only ) + { + FT_Error error = FT_Err_Ok; + FT_Fixed x_scale, y_scale; + FT_ULong offset; + TT_Face face = (TT_Face)loader->face; + FT_GlyphLoader gloader = loader->gloader; + FT_Bool opened_frame = 0; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Vector* deltas = NULL; +#endif + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_StreamRec inc_stream; + FT_Data glyph_data; + FT_Bool glyph_data_loaded = 0; +#endif + + + /* some fonts have an incorrect value of `maxComponentDepth', */ + /* thus we allow depth 1 to catch the majority of them */ + if ( recurse_count > 1 && + recurse_count > face->max_profile.maxComponentDepth ) + { + error = FT_THROW( Invalid_Composite ); + goto Exit; + } + + /* check glyph index */ + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = FT_THROW( Invalid_Glyph_Index ); + goto Exit; + } + + loader->glyph_index = glyph_index; + + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + x_scale = ((TT_Size)loader->size)->metrics.x_scale; + y_scale = ((TT_Size)loader->size)->metrics.y_scale; + } + else + { + x_scale = 0x10000L; + y_scale = 0x10000L; + } + + tt_get_metrics( loader, glyph_index ); + + /* Set `offset' to the start of the glyph relative to the start of */ + /* the `glyf' table, and `byte_len' to the length of the glyph in */ + /* bytes. */ + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* If we are loading glyph data via the incremental interface, set */ + /* the loader stream to a memory stream reading the data returned */ + /* by the interface. */ + if ( face->root.internal->incremental_interface ) + { + error = face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, &glyph_data ); + if ( error ) + goto Exit; + + glyph_data_loaded = 1; + offset = 0; + loader->byte_len = glyph_data.length; + + FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); + FT_Stream_OpenMemory( &inc_stream, + glyph_data.pointer, glyph_data.length ); + + loader->stream = &inc_stream; + } + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + offset = tt_face_get_location( face, glyph_index, + (FT_UInt*)&loader->byte_len ); + + if ( loader->byte_len > 0 ) + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* for the incremental interface, `glyf_offset' is always zero */ + if ( !loader->glyf_offset && + !face->root.internal->incremental_interface ) +#else + if ( !loader->glyf_offset ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + error = face->access_glyph_frame( loader, glyph_index, + loader->glyf_offset + offset, + loader->byte_len ); + if ( error ) + goto Exit; + + opened_frame = 1; + + /* read glyph header first */ + error = face->read_glyph_header( loader ); + if ( error || header_only ) + goto Exit; + } + + if ( loader->byte_len == 0 || loader->n_contours == 0 ) + { + loader->bbox.xMin = 0; + loader->bbox.xMax = 0; + loader->bbox.yMin = 0; + loader->bbox.yMax = 0; + + if ( header_only ) + goto Exit; + + /* must initialize points before (possibly) overriding */ + /* glyph metrics from the incremental interface */ + TT_LOADER_SET_PP( loader ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + tt_get_metrics_incr_overrides( loader, glyph_index ); +#endif + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + if ( ((TT_Face)(loader->face))->doblend ) + { + /* this must be done before scaling */ + FT_Memory memory = loader->face->memory; + + + error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), + glyph_index, &deltas, 4 ); + if ( error ) + goto Exit; + + loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y; + loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y; + loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y; + loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y; + + FT_FREE( deltas ); + } + +#endif + + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); + loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); + } + + error = FT_Err_Ok; + goto Exit; + } + + /* must initialize points before (possibly) overriding */ + /* glyph metrics from the incremental interface */ + TT_LOADER_SET_PP( loader ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + tt_get_metrics_incr_overrides( loader, glyph_index ); +#endif + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + /* if it is a simple glyph, load it */ + + if ( loader->n_contours > 0 ) + { + error = face->read_simple_glyph( loader ); + if ( error ) + goto Exit; + + /* all data have been read */ + face->forget_glyph_frame( loader ); + opened_frame = 0; + + error = TT_Process_Simple_Glyph( loader ); + if ( error ) + goto Exit; + + FT_GlyphLoader_Add( gloader ); + } + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + /* otherwise, load a composite! */ + else if ( loader->n_contours == -1 ) + { + FT_UInt start_point; + FT_UInt start_contour; + FT_ULong ins_pos; /* position of composite instructions, if any */ + + + start_point = gloader->base.outline.n_points; + start_contour = gloader->base.outline.n_contours; + + /* for each subglyph, read composite header */ + error = face->read_composite_glyph( loader ); + if ( error ) + goto Exit; + + /* store the offset of instructions */ + ins_pos = loader->ins_pos; + + /* all data we need are read */ + face->forget_glyph_frame( loader ); + opened_frame = 0; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + if ( face->doblend ) + { + FT_Int i, limit; + FT_SubGlyph subglyph; + FT_Memory memory = face->root.memory; + + + /* this provides additional offsets */ + /* for each component's translation */ + + if ( ( error = TT_Vary_Get_Glyph_Deltas( + face, + glyph_index, + &deltas, + gloader->current.num_subglyphs + 4 )) != 0 ) + goto Exit; + + subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; + limit = gloader->current.num_subglyphs; + + for ( i = 0; i < limit; ++i, ++subglyph ) + { + if ( subglyph->flags & ARGS_ARE_XY_VALUES ) + { + /* XXX: overflow check for subglyph->{arg1,arg2}. */ + /* deltas[i].{x,y} must be within signed 16-bit, */ + /* but the restriction of summed delta is not clear */ + subglyph->arg1 += (FT_Int16)deltas[i].x; + subglyph->arg2 += (FT_Int16)deltas[i].y; + } + } + + loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y; + loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y; + loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y; + loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y; + + FT_FREE( deltas ); + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); + loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); + } + + /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ + /* `as is' in the glyph slot (the client application will be */ + /* responsible for interpreting these data)... */ + if ( loader->load_flags & FT_LOAD_NO_RECURSE ) + { + FT_GlyphLoader_Add( gloader ); + loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + goto Exit; + } + + /*********************************************************************/ + /*********************************************************************/ + /*********************************************************************/ + + { + FT_UInt n, num_base_points; + FT_SubGlyph subglyph = 0; + + FT_UInt num_points = start_point; + FT_UInt num_subglyphs = gloader->current.num_subglyphs; + FT_UInt num_base_subgs = gloader->base.num_subglyphs; + + FT_Stream old_stream = loader->stream; + FT_Int old_byte_len = loader->byte_len; + + + FT_GlyphLoader_Add( gloader ); + + /* read each subglyph independently */ + for ( n = 0; n < num_subglyphs; n++ ) + { + FT_Vector pp[4]; + + + /* Each time we call load_truetype_glyph in this loop, the */ + /* value of `gloader.base.subglyphs' can change due to table */ + /* reallocations. We thus need to recompute the subglyph */ + /* pointer on each iteration. */ + subglyph = gloader->base.subglyphs + num_base_subgs + n; + + pp[0] = loader->pp1; + pp[1] = loader->pp2; + pp[2] = loader->pp3; + pp[3] = loader->pp4; + + num_base_points = gloader->base.outline.n_points; + + error = load_truetype_glyph( loader, subglyph->index, + recurse_count + 1, FALSE ); + if ( error ) + goto Exit; + + /* restore subglyph pointer */ + subglyph = gloader->base.subglyphs + num_base_subgs + n; + + if ( !( subglyph->flags & USE_MY_METRICS ) ) + { + loader->pp1 = pp[0]; + loader->pp2 = pp[1]; + loader->pp3 = pp[2]; + loader->pp4 = pp[3]; + } + + num_points = gloader->base.outline.n_points; + + if ( num_points == num_base_points ) + continue; + + /* gloader->base.outline consists of three parts: */ + /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */ + /* */ + /* (1): exists from the beginning */ + /* (2): components that have been loaded so far */ + /* (3): the newly loaded component */ + TT_Process_Composite_Component( loader, subglyph, start_point, + num_base_points ); + } + + loader->stream = old_stream; + loader->byte_len = old_byte_len; + + /* process the glyph */ + loader->ins_pos = ins_pos; + if ( IS_HINTED( loader->load_flags ) && + +#ifdef TT_USE_BYTECODE_INTERPRETER + + subglyph->flags & WE_HAVE_INSTR && + +#endif + + num_points > start_point ) + TT_Process_Composite_Glyph( loader, start_point, start_contour ); + + } + } + else + { + /* invalid composite count (negative but not -1) */ + error = FT_THROW( Invalid_Outline ); + goto Exit; + } + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + Exit: + + if ( opened_frame ) + face->forget_glyph_frame( loader ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( glyph_data_loaded ) + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + +#endif + + return error; + } + + + static FT_Error + compute_glyph_metrics( TT_Loader loader, + FT_UInt glyph_index ) + { + TT_Face face = (TT_Face)loader->face; +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); +#endif + + FT_BBox bbox; + FT_Fixed y_scale; + TT_GlyphSlot glyph = loader->glyph; + TT_Size size = (TT_Size)loader->size; + + + y_scale = 0x10000L; + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + y_scale = size->root.metrics.y_scale; + + if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) + FT_Outline_Get_CBox( &glyph->outline, &bbox ); + else + bbox = loader->bbox; + + /* get the device-independent horizontal advance; it is scaled later */ + /* by the base layer. */ + glyph->linearHoriAdvance = loader->linear; + + glyph->metrics.horiBearingX = bbox.xMin; + glyph->metrics.horiBearingY = bbox.yMax; + glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + + /* adjust advance width to the value contained in the hdmx table */ + if ( !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) ) + { + FT_Byte* widthp; + + + widthp = tt_face_get_device_metrics( face, + size->root.metrics.x_ppem, + glyph_index ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + FT_Bool ignore_x_mode; + + + ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) != + FT_RENDER_MODE_MONO ); + + if ( widthp && + ( ( ignore_x_mode && loader->exec->compatible_widths ) || + !ignore_x_mode || + SPH_OPTION_BITMAP_WIDTHS ) ) + glyph->metrics.horiAdvance = *widthp << 6; + } + else + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + { + if ( widthp ) + glyph->metrics.horiAdvance = *widthp << 6; + } + } + + /* set glyph dimensions */ + glyph->metrics.width = bbox.xMax - bbox.xMin; + glyph->metrics.height = bbox.yMax - bbox.yMin; + + /* Now take care of vertical metrics. In the case where there is */ + /* no vertical information within the font (relatively common), */ + /* create some metrics manually */ + { + FT_Pos top; /* scaled vertical top side bearing */ + FT_Pos advance; /* scaled vertical advance height */ + + + /* Get the unscaled top bearing and advance height. */ + if ( face->vertical_info && + face->vertical.number_Of_VMetrics > 0 ) + { + top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax, + y_scale ); + + if ( loader->pp3.y <= loader->pp4.y ) + advance = 0; + else + advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y, + y_scale ); + } + else + { + FT_Pos height; + + + /* XXX Compute top side bearing and advance height in */ + /* Get_VMetrics instead of here. */ + + /* NOTE: The OS/2 values are the only `portable' ones, */ + /* which is why we use them, if there is an OS/2 */ + /* table in the font. Otherwise, we use the */ + /* values defined in the horizontal header. */ + + height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin, + y_scale ); + if ( face->os2.version != 0xFFFFU ) + advance = (FT_Pos)( face->os2.sTypoAscender - + face->os2.sTypoDescender ); + else + advance = (FT_Pos)( face->horizontal.Ascender - + face->horizontal.Descender ); + + top = ( advance - height ) / 2; + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + { + FT_Incremental_InterfaceRec* incr; + FT_Incremental_MetricsRec metrics; + FT_Error error; + + + incr = face->root.internal->incremental_interface; + + /* If this is an incrementally loaded font see if there are */ + /* overriding metrics for this glyph. */ + if ( incr && incr->funcs->get_glyph_metrics ) + { + metrics.bearing_x = 0; + metrics.bearing_y = top; + metrics.advance = advance; + + error = incr->funcs->get_glyph_metrics( incr->object, + glyph_index, + TRUE, + &metrics ); + if ( error ) + return error; + + top = metrics.bearing_y; + advance = metrics.advance; + } + } + + /* GWW: Do vertical metrics get loaded incrementally too? */ + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + glyph->linearVertAdvance = advance; + + /* scale the metrics */ + if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) + { + top = FT_MulFix( top, y_scale ); + advance = FT_MulFix( advance, y_scale ); + } + + /* XXX: for now, we have no better algorithm for the lsb, but it */ + /* should work fine. */ + /* */ + glyph->metrics.vertBearingX = glyph->metrics.horiBearingX - + glyph->metrics.horiAdvance / 2; + glyph->metrics.vertBearingY = top; + glyph->metrics.vertAdvance = advance; + } + + return 0; + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + static FT_Error + load_sbit_image( TT_Size size, + TT_GlyphSlot glyph, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + TT_Face face; + SFNT_Service sfnt; + FT_Stream stream; + FT_Error error; + TT_SBit_MetricsRec metrics; + + + face = (TT_Face)glyph->face; + sfnt = (SFNT_Service)face->sfnt; + stream = face->root.stream; + + error = sfnt->load_sbit_image( face, + size->strike_index, + glyph_index, + (FT_Int)load_flags, + stream, + &glyph->bitmap, + &metrics ); + if ( !error ) + { + glyph->outline.n_points = 0; + glyph->outline.n_contours = 0; + + glyph->metrics.width = (FT_Pos)metrics.width << 6; + glyph->metrics.height = (FT_Pos)metrics.height << 6; + + glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; + glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; + glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + + glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; + glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; + glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + + glyph->format = FT_GLYPH_FORMAT_BITMAP; + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + glyph->bitmap_left = metrics.vertBearingX; + glyph->bitmap_top = metrics.vertBearingY; + } + else + { + glyph->bitmap_left = metrics.horiBearingX; + glyph->bitmap_top = metrics.horiBearingY; + } + } + + return error; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + static FT_Error + tt_loader_init( TT_Loader loader, + TT_Size size, + TT_GlyphSlot glyph, + FT_Int32 load_flags, + FT_Bool glyf_table_only ) + { + TT_Face face; + FT_Stream stream; +#ifdef TT_USE_BYTECODE_INTERPRETER + FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); +#endif + + + face = (TT_Face)glyph->face; + stream = face->root.stream; + + FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /* load execution context */ + if ( IS_HINTED( load_flags ) && !glyf_table_only ) + { + TT_ExecContext exec; + FT_Bool grayscale; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); + + FT_Bool subpixel_hinting = FALSE; + FT_Bool grayscale_hinting = TRUE; + +#if 0 + /* not used yet */ + FT_Bool compatible_widths; + FT_Bool symmetrical_smoothing; + FT_Bool bgr; + FT_Bool subpixel_positioned; +#endif +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + FT_Bool reexecute = FALSE; + + + if ( !size->cvt_ready ) + { + FT_Error error = tt_size_ready_bytecode( size, pedantic ); + + + if ( error ) + return error; + } + + /* query new execution context */ + exec = size->debug ? size->context + : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; + if ( !exec ) + return FT_THROW( Could_Not_Find_Context ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) + != FT_RENDER_MODE_MONO ) && + SPH_OPTION_SET_SUBPIXEL ); + + if ( subpixel_hinting ) + grayscale = grayscale_hinting = FALSE; + else if ( SPH_OPTION_SET_GRAYSCALE ) + { + grayscale = grayscale_hinting = TRUE; + subpixel_hinting = FALSE; + } + else + grayscale = grayscale_hinting = FALSE; + + if ( FT_IS_TRICKY( glyph->face ) ) + subpixel_hinting = grayscale_hinting = FALSE; + + exec->ignore_x_mode = subpixel_hinting || grayscale_hinting; + exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; + if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) + exec->rasterizer_version = TT_INTERPRETER_VERSION_35; + +#if 1 + exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; + exec->symmetrical_smoothing = FALSE; + exec->bgr = FALSE; + exec->subpixel_positioned = TRUE; +#else /* 0 */ + exec->compatible_widths = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + TT_LOAD_COMPATIBLE_WIDTHS ); + exec->symmetrical_smoothing = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + TT_LOAD_SYMMETRICAL_SMOOTHING ); + exec->bgr = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + TT_LOAD_BGR ); + exec->subpixel_positioned = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + TT_LOAD_SUBPIXEL_POSITIONED ); +#endif /* 0 */ + + } + else + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + { + grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ); + } + + TT_Load_Context( exec, face, size ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + /* a change from mono to subpixel rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( subpixel_hinting != exec->subpixel_hinting ) + { + FT_TRACE4(( "tt_loader_init: subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->subpixel_hinting = subpixel_hinting; + reexecute = TRUE; + } + + /* a change from mono to grayscale rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( grayscale != exec->grayscale_hinting ) + { + FT_TRACE4(( "tt_loader_init: grayscale hinting change," + " re-executing `prep' table\n" )); + + exec->grayscale_hinting = grayscale_hinting; + reexecute = TRUE; + } + } + else + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + { + /* a change from mono to grayscale rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( grayscale != exec->grayscale ) + { + FT_TRACE4(( "tt_loader_init: grayscale change," + " re-executing `prep' table\n" )); + + exec->grayscale = grayscale; + reexecute = TRUE; + } + } + + if ( reexecute ) + { + FT_UInt i; + + + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + tt_size_run_prep( size, pedantic ); + } + + /* see whether the cvt program has disabled hinting */ + if ( exec->GS.instruct_control & 1 ) + load_flags |= FT_LOAD_NO_HINTING; + + /* load default graphics state -- if needed */ + if ( exec->GS.instruct_control & 2 ) + exec->GS = tt_default_graphics_state; + + exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); + loader->exec = exec; + loader->instructions = exec->glyphIns; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + /* seek to the beginning of the glyph table -- for Type 42 fonts */ + /* the table might be accessed from a Postscript stream or something */ + /* else... */ + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( face->root.internal->incremental_interface ) + loader->glyf_offset = 0; + else + +#endif + + { + FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); + + + if ( FT_ERR_EQ( error, Table_Missing ) ) + loader->glyf_offset = 0; + else if ( error ) + { + FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); + return error; + } + else + loader->glyf_offset = FT_STREAM_POS(); + } + + /* get face's glyph loader */ + if ( !glyf_table_only ) + { + FT_GlyphLoader gloader = glyph->internal->loader; + + + FT_GlyphLoader_Rewind( gloader ); + loader->gloader = gloader; + } + + loader->load_flags = load_flags; + + loader->face = (FT_Face)face; + loader->size = (FT_Size)size; + loader->glyph = (FT_GlyphSlot)glyph; + loader->stream = stream; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Load_Glyph */ + /* */ + /* <Description> */ + /* A function used to load a single glyph within a given glyph slot, */ + /* for a given size. */ + /* */ + /* <Input> */ + /* glyph :: A handle to a target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled/loaded. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Load_Glyph( TT_Size size, + TT_GlyphSlot glyph, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + TT_LoaderRec loader; + + + error = FT_Err_Ok; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* try to load embedded bitmap if any */ + /* */ + /* XXX: The convention should be emphasized in */ + /* the documents because it can be confusing. */ + if ( size->strike_index != 0xFFFFFFFFUL && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + error = load_sbit_image( size, glyph, glyph_index, load_flags ); + if ( !error ) + { + if ( FT_IS_SCALABLE( glyph->face ) ) + { + /* for the bbox we need the header only */ + (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); + (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + glyph->linearHoriAdvance = loader.linear; + glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - + loader.vadvance; + + /* sanity check: if `horiAdvance' in the sbit metric */ + /* structure isn't set, use `linearHoriAdvance' */ + if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance ) + glyph->metrics.horiAdvance = + FT_MulFix( glyph->linearHoriAdvance, + size->root.metrics.x_scale ); + } + + return FT_Err_Ok; + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */ + if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid ) + return FT_THROW( Invalid_Size_Handle ); + + if ( load_flags & FT_LOAD_SBITS_ONLY ) + return FT_THROW( Invalid_Argument ); + + error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); + if ( error ) + return error; + + glyph->format = FT_GLYPH_FORMAT_OUTLINE; + glyph->num_subglyphs = 0; + glyph->outline.flags = 0; + + /* main loading loop */ + error = load_truetype_glyph( &loader, glyph_index, 0, FALSE ); + if ( !error ) + { + if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE ) + { + glyph->num_subglyphs = loader.gloader->base.num_subglyphs; + glyph->subglyphs = loader.gloader->base.subglyphs; + } + else + { + glyph->outline = loader.gloader->base.outline; + glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS; + + /* Translate array so that (0,0) is the glyph's origin. Note */ + /* that this behaviour is independent on the value of bit 1 of */ + /* the `flags' field in the `head' table -- at least major */ + /* applications like Acroread indicate that. */ + if ( loader.pp1.x ) + FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 ); + } + +#ifdef TT_USE_BYTECODE_INTERPRETER + + if ( IS_HINTED( load_flags ) ) + { + if ( loader.exec->GS.scan_control ) + { + /* convert scan conversion mode to FT_OUTLINE_XXX flags */ + switch ( loader.exec->GS.scan_type ) + { + case 0: /* simple drop-outs including stubs */ + glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS; + break; + case 1: /* simple drop-outs excluding stubs */ + /* nothing; it's the default rendering mode */ + break; + case 4: /* smart drop-outs including stubs */ + glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS | + FT_OUTLINE_INCLUDE_STUBS; + break; + case 5: /* smart drop-outs excluding stubs */ + glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS; + break; + + default: /* no drop-out control */ + glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; + break; + } + } + else + glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + compute_glyph_metrics( &loader, glyph_index ); + } + + /* Set the `high precision' bit flag. */ + /* This is _critical_ to get correct output for monochrome */ + /* TrueType glyphs at all sizes using the bytecode interpreter. */ + /* */ + if ( !( load_flags & FT_LOAD_NO_SCALE ) && + size->root.metrics.y_ppem < 24 ) + glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttgload.h b/drivers/freetype/src/truetype/ttgload.h new file mode 100644 index 0000000000..05f75882dc --- /dev/null +++ b/drivers/freetype/src/truetype/ttgload.h @@ -0,0 +1,61 @@ +/***************************************************************************/ +/* */ +/* ttgload.h */ +/* */ +/* TrueType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2006, 2008, 2011 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 __TTGLOAD_H__ +#define __TTGLOAD_H__ + + +#include <ft2build.h> +#include "ttobjs.h" + +#ifdef TT_USE_BYTECODE_INTERPRETER +#include "ttinterp.h" +#endif + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + TT_Init_Glyph_Loading( TT_Face face ); + + FT_LOCAL( void ) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Short* lsb, + FT_UShort* aw ); + + FT_LOCAL( void ) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Short* tsb, + FT_UShort* ah ); + + FT_LOCAL( FT_Error ) + TT_Load_Glyph( TT_Size size, + TT_GlyphSlot glyph, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __TTGLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttgxvar.c b/drivers/freetype/src/truetype/ttgxvar.c new file mode 100644 index 0000000000..7899d3671d --- /dev/null +++ b/drivers/freetype/src/truetype/ttgxvar.c @@ -0,0 +1,1532 @@ +/***************************************************************************/ +/* */ +/* ttgxvar.c */ +/* */ +/* TrueType GX Font Variation loader */ +/* */ +/* Copyright 2004-2013 by */ +/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ + /* */ + /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ + /* */ + /* The documentation for `fvar' is inconsistent. At one point it says */ + /* that `countSizePairs' should be 3, at another point 2. It should */ + /* be 2. */ + /* */ + /* The documentation for `gvar' is not intelligible; `cvar' refers you */ + /* to `gvar' and is thus also incomprehensible. */ + /* */ + /* The documentation for `avar' appears correct, but Apple has no fonts */ + /* with an `avar' table, so it is hard to test. */ + /* */ + /* Many thanks to John Jenkins (at Apple) in figuring this out. */ + /* */ + /* */ + /* Apple's `kern' table has some references to tuple indices, but as */ + /* there is no indication where these indices are defined, nor how to */ + /* interpolate the kerning values (different tuples have different */ + /* classes) this issue is ignored. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_TAGS_H +#include FT_MULTIPLE_MASTERS_H + +#include "ttpload.h" +#include "ttgxvar.h" + +#include "tterrors.h" + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + +#define FT_Stream_FTell( stream ) \ + (FT_ULong)( (stream)->cursor - (stream)->base ) +#define FT_Stream_SeekSet( stream, off ) \ + ( (stream)->cursor = (stream)->base + (off) ) + + + /*************************************************************************/ + /* */ + /* 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_ttgxvar + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Internal Routines *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It */ + /* indicates that there is a delta for every point without needing to */ + /* enumerate all of them. */ + /* */ + + /* ensure that value `0' has the same width as a pointer */ +#define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0 + + +#define GX_PT_POINTS_ARE_WORDS 0x80 +#define GX_PT_POINT_RUN_COUNT_MASK 0x7F + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_readpackedpoints */ + /* */ + /* <Description> */ + /* Read a set of points to which the following deltas will apply. */ + /* Points are packed with a run length encoding. */ + /* */ + /* <Input> */ + /* stream :: The data stream. */ + /* */ + /* <Output> */ + /* point_cnt :: The number of points read. A zero value means that */ + /* all points in the glyph will be affected, without */ + /* enumerating them individually. */ + /* */ + /* <Return> */ + /* An array of FT_UShort containing the affected points or the */ + /* special value ALL_POINTS. */ + /* */ + static FT_UShort* + ft_var_readpackedpoints( FT_Stream stream, + FT_UInt *point_cnt ) + { + FT_UShort *points = NULL; + FT_Int n; + FT_Int runcnt; + FT_Int i; + FT_Int j; + FT_Int first; + FT_Memory memory = stream->memory; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( error ); + + + *point_cnt = n = FT_GET_BYTE(); + if ( n == 0 ) + return ALL_POINTS; + + if ( n & GX_PT_POINTS_ARE_WORDS ) + n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 ); + + if ( FT_NEW_ARRAY( points, n ) ) + return NULL; + + i = 0; + while ( i < n ) + { + runcnt = FT_GET_BYTE(); + if ( runcnt & GX_PT_POINTS_ARE_WORDS ) + { + runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; + first = points[i++] = FT_GET_USHORT(); + + if ( runcnt < 1 || i + runcnt >= n ) + goto Exit; + + /* first point not included in runcount */ + for ( j = 0; j < runcnt; ++j ) + points[i++] = (FT_UShort)( first += FT_GET_USHORT() ); + } + else + { + first = points[i++] = FT_GET_BYTE(); + + if ( runcnt < 1 || i + runcnt >= n ) + goto Exit; + + for ( j = 0; j < runcnt; ++j ) + points[i++] = (FT_UShort)( first += FT_GET_BYTE() ); + } + } + + Exit: + return points; + } + + + enum + { + GX_DT_DELTAS_ARE_ZERO = 0x80, + GX_DT_DELTAS_ARE_WORDS = 0x40, + GX_DT_DELTA_RUN_COUNT_MASK = 0x3F + }; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_readpackeddeltas */ + /* */ + /* <Description> */ + /* Read a set of deltas. These are packed slightly differently than */ + /* points. In particular there is no overall count. */ + /* */ + /* <Input> */ + /* stream :: The data stream. */ + /* */ + /* delta_cnt :: The number of to be read. */ + /* */ + /* <Return> */ + /* An array of FT_Short containing the deltas for the affected */ + /* points. (This only gets the deltas for one dimension. It will */ + /* generally be called twice, once for x, once for y. When used in */ + /* cvt table, it will only be called once.) */ + /* */ + static FT_Short* + ft_var_readpackeddeltas( FT_Stream stream, + FT_Offset delta_cnt ) + { + FT_Short *deltas = NULL; + FT_UInt runcnt; + FT_Offset i; + FT_UInt j; + FT_Memory memory = stream->memory; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( error ); + + + if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) + return NULL; + + i = 0; + while ( i < delta_cnt ) + { + runcnt = FT_GET_BYTE(); + if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) + { + /* runcnt zeroes get added */ + for ( j = 0; + j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; + ++j ) + deltas[i++] = 0; + } + else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) + { + /* runcnt shorts from the stack */ + for ( j = 0; + j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; + ++j ) + deltas[i++] = FT_GET_SHORT(); + } + else + { + /* runcnt signed bytes from the stack */ + for ( j = 0; + j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; + ++j ) + deltas[i++] = FT_GET_CHAR(); + } + + if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) ) + { + /* Bad format */ + FT_FREE( deltas ); + return NULL; + } + } + + return deltas; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_load_avar */ + /* */ + /* <Description> */ + /* Parse the `avar' table if present. It need not be, so we return */ + /* nothing. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* */ + static void + ft_var_load_avar( TT_Face face ) + { + FT_Stream stream = FT_FACE_STREAM(face); + FT_Memory memory = stream->memory; + GX_Blend blend = face->blend; + GX_AVarSegment segment; + FT_Error error = FT_Err_Ok; + FT_ULong version; + FT_Long axisCount; + FT_Int i, j; + FT_ULong table_len; + + FT_UNUSED( error ); + + + blend->avar_checked = TRUE; + if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0 ) + return; + + if ( FT_FRAME_ENTER( table_len ) ) + return; + + version = FT_GET_LONG(); + axisCount = FT_GET_LONG(); + + if ( version != 0x00010000L || + axisCount != (FT_Long)blend->mmvar->num_axis ) + goto Exit; + + if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) ) + goto Exit; + + segment = &blend->avar_segment[0]; + for ( i = 0; i < axisCount; ++i, ++segment ) + { + segment->pairCount = FT_GET_USHORT(); + if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) + { + /* Failure. Free everything we have done so far. We must do */ + /* it right now since loading the `avar' table is optional. */ + + for ( j = i - 1; j >= 0; --j ) + FT_FREE( blend->avar_segment[j].correspondence ); + + FT_FREE( blend->avar_segment ); + blend->avar_segment = NULL; + goto Exit; + } + + for ( j = 0; j < segment->pairCount; ++j ) + { + segment->correspondence[j].fromCoord = + FT_GET_SHORT() << 2; /* convert to Fixed */ + segment->correspondence[j].toCoord = + FT_GET_SHORT()<<2; /* convert to Fixed */ + } + } + + Exit: + FT_FRAME_EXIT(); + } + + + typedef struct GX_GVar_Head_ + { + FT_Long version; + FT_UShort axisCount; + FT_UShort globalCoordCount; + FT_ULong offsetToCoord; + FT_UShort glyphCount; + FT_UShort flags; + FT_ULong offsetToData; + + } GX_GVar_Head; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_load_gvar */ + /* */ + /* <Description> */ + /* Parses the `gvar' table if present. If `fvar' is there, `gvar' */ + /* had better be there too. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + ft_var_load_gvar( TT_Face face ) + { + FT_Stream stream = FT_FACE_STREAM(face); + FT_Memory memory = stream->memory; + GX_Blend blend = face->blend; + FT_Error error; + FT_UInt i, j; + FT_ULong table_len; + FT_ULong gvar_start; + FT_ULong offsetToData; + GX_GVar_Head gvar_head; + + static const FT_Frame_Field gvar_fields[] = + { + +#undef FT_STRUCTURE +#define FT_STRUCTURE GX_GVar_Head + + FT_FRAME_START( 20 ), + FT_FRAME_LONG ( version ), + FT_FRAME_USHORT( axisCount ), + FT_FRAME_USHORT( globalCoordCount ), + FT_FRAME_ULONG ( offsetToCoord ), + FT_FRAME_USHORT( glyphCount ), + FT_FRAME_USHORT( flags ), + FT_FRAME_ULONG ( offsetToData ), + FT_FRAME_END + }; + + if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 ) + goto Exit; + + gvar_start = FT_STREAM_POS( ); + if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) + goto Exit; + + blend->tuplecount = gvar_head.globalCoordCount; + blend->gv_glyphcnt = gvar_head.glyphCount; + offsetToData = gvar_start + gvar_head.offsetToData; + + if ( gvar_head.version != (FT_Long)0x00010000L || + gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) + goto Exit; + + if ( gvar_head.flags & 1 ) + { + /* long offsets (one more offset than glyphs, to mark size of last) */ + if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) + goto Exit; + + for ( i = 0; i <= blend->gv_glyphcnt; ++i ) + blend->glyphoffsets[i] = offsetToData + FT_GET_LONG(); + + FT_FRAME_EXIT(); + } + else + { + /* short offsets (one more offset than glyphs, to mark size of last) */ + if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) + goto Exit; + + for ( i = 0; i <= blend->gv_glyphcnt; ++i ) + blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; + /* XXX: Undocumented: `*2'! */ + + FT_FRAME_EXIT(); + } + + if ( blend->tuplecount != 0 ) + { + if ( FT_NEW_ARRAY( blend->tuplecoords, + gvar_head.axisCount * blend->tuplecount ) ) + goto Exit; + + if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || + FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) + goto Exit; + + for ( i = 0; i < blend->tuplecount; ++i ) + for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j ) + blend->tuplecoords[i * gvar_head.axisCount + j] = + FT_GET_SHORT() << 2; /* convert to FT_Fixed */ + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_apply_tuple */ + /* */ + /* <Description> */ + /* Figure out whether a given tuple (design) applies to the current */ + /* blend, and if so, what is the scaling factor. */ + /* */ + /* <Input> */ + /* blend :: The current blend of the font. */ + /* */ + /* tupleIndex :: A flag saying whether this is an intermediate */ + /* tuple or not. */ + /* */ + /* tuple_coords :: The coordinates of the tuple in normalized axis */ + /* units. */ + /* */ + /* im_start_coords :: The initial coordinates where this tuple starts */ + /* to apply (for intermediate coordinates). */ + /* */ + /* im_end_coords :: The final coordinates after which this tuple no */ + /* longer applies (for intermediate coordinates). */ + /* */ + /* <Return> */ + /* An FT_Fixed value containing the scaling factor. */ + /* */ + static FT_Fixed + ft_var_apply_tuple( GX_Blend blend, + FT_UShort tupleIndex, + FT_Fixed* tuple_coords, + FT_Fixed* im_start_coords, + FT_Fixed* im_end_coords ) + { + FT_UInt i; + FT_Fixed apply = 0x10000L; + + + for ( i = 0; i < blend->num_axis; ++i ) + { + if ( tuple_coords[i] == 0 ) + /* It's not clear why (for intermediate tuples) we don't need */ + /* to check against start/end -- the documentation says we don't. */ + /* Similarly, it's unclear why we don't need to scale along the */ + /* axis. */ + continue; + + else if ( blend->normalizedcoords[i] == 0 || + ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || + ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) + { + apply = 0; + break; + } + + else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) + /* not an intermediate tuple */ + apply = FT_MulFix( apply, + blend->normalizedcoords[i] > 0 + ? blend->normalizedcoords[i] + : -blend->normalizedcoords[i] ); + + else if ( blend->normalizedcoords[i] <= im_start_coords[i] || + blend->normalizedcoords[i] >= im_end_coords[i] ) + { + apply = 0; + break; + } + + else if ( blend->normalizedcoords[i] < tuple_coords[i] ) + apply = FT_MulDiv( apply, + blend->normalizedcoords[i] - im_start_coords[i], + tuple_coords[i] - im_start_coords[i] ); + + else + apply = FT_MulDiv( apply, + im_end_coords[i] - blend->normalizedcoords[i], + im_end_coords[i] - tuple_coords[i] ); + } + + return apply; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MULTIPLE MASTERS SERVICE FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct GX_FVar_Head_ + { + FT_Long version; + FT_UShort offsetToData; + FT_UShort countSizePairs; + FT_UShort axisCount; + FT_UShort axisSize; + FT_UShort instanceCount; + FT_UShort instanceSize; + + } GX_FVar_Head; + + + typedef struct fvar_axis_ + { + FT_ULong axisTag; + FT_ULong minValue; + FT_ULong defaultValue; + FT_ULong maxValue; + FT_UShort flags; + FT_UShort nameID; + + } GX_FVar_Axis; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Get_MM_Var */ + /* */ + /* <Description> */ + /* Check that the font's `fvar' table is valid, parse it, and return */ + /* those data. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* TT_Get_MM_Var initializes the blend structure. */ + /* */ + /* <Output> */ + /* master :: The `fvar' data (must be freed by caller). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_MM_Var( TT_Face face, + FT_MM_Var* *master ) + { + FT_Stream stream = face->root.stream; + FT_Memory memory = face->root.memory; + FT_ULong table_len; + FT_Error error = FT_Err_Ok; + FT_ULong fvar_start; + FT_Int i, j; + FT_MM_Var* mmvar = NULL; + FT_Fixed* next_coords; + FT_String* next_name; + FT_Var_Axis* a; + FT_Var_Named_Style* ns; + GX_FVar_Head fvar_head; + + static const FT_Frame_Field fvar_fields[] = + { + +#undef FT_STRUCTURE +#define FT_STRUCTURE GX_FVar_Head + + FT_FRAME_START( 16 ), + FT_FRAME_LONG ( version ), + FT_FRAME_USHORT( offsetToData ), + FT_FRAME_USHORT( countSizePairs ), + FT_FRAME_USHORT( axisCount ), + FT_FRAME_USHORT( axisSize ), + FT_FRAME_USHORT( instanceCount ), + FT_FRAME_USHORT( instanceSize ), + FT_FRAME_END + }; + + static const FT_Frame_Field fvaraxis_fields[] = + { + +#undef FT_STRUCTURE +#define FT_STRUCTURE GX_FVar_Axis + + FT_FRAME_START( 20 ), + FT_FRAME_ULONG ( axisTag ), + FT_FRAME_ULONG ( minValue ), + FT_FRAME_ULONG ( defaultValue ), + FT_FRAME_ULONG ( maxValue ), + FT_FRAME_USHORT( flags ), + FT_FRAME_USHORT( nameID ), + FT_FRAME_END + }; + + + if ( face->blend == NULL ) + { + /* both `fvar' and `gvar' must be present */ + if ( (error = face->goto_table( face, TTAG_gvar, + stream, &table_len )) != 0 ) + goto Exit; + + if ( (error = face->goto_table( face, TTAG_fvar, + stream, &table_len )) != 0 ) + goto Exit; + + fvar_start = FT_STREAM_POS( ); + + if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) ) + goto Exit; + + if ( fvar_head.version != (FT_Long)0x00010000L || + fvar_head.countSizePairs != 2 || + fvar_head.axisSize != 20 || + /* axisCount limit implied by 16-bit instanceSize */ + fvar_head.axisCount > 0x3FFE || + fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount || + /* instanceCount limit implied by limited range of name IDs */ + fvar_head.instanceCount > 0x7EFF || + fvar_head.offsetToData + fvar_head.axisCount * 20U + + fvar_head.instanceCount * fvar_head.instanceSize > table_len ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( FT_NEW( face->blend ) ) + goto Exit; + + /* cannot overflow 32-bit arithmetic because of limits above */ + face->blend->mmvar_len = + sizeof ( FT_MM_Var ) + + fvar_head.axisCount * sizeof ( FT_Var_Axis ) + + fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) + + fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) + + 5 * fvar_head.axisCount; + + if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + goto Exit; + face->blend->mmvar = mmvar; + + mmvar->num_axis = + fvar_head.axisCount; + mmvar->num_designs = + ~0U; /* meaningless in this context; each glyph */ + /* may have a different number of designs */ + /* (or tuples, as called by Apple) */ + mmvar->num_namedstyles = + fvar_head.instanceCount; + mmvar->axis = + (FT_Var_Axis*)&(mmvar[1]); + mmvar->namedstyle = + (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]); + + next_coords = + (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]); + for ( i = 0; i < fvar_head.instanceCount; ++i ) + { + mmvar->namedstyle[i].coords = next_coords; + next_coords += fvar_head.axisCount; + } + + next_name = (FT_String*)next_coords; + for ( i = 0; i < fvar_head.axisCount; ++i ) + { + mmvar->axis[i].name = next_name; + next_name += 5; + } + + if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) ) + goto Exit; + + a = mmvar->axis; + for ( i = 0; i < fvar_head.axisCount; ++i ) + { + GX_FVar_Axis axis_rec; + + + if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) + goto Exit; + a->tag = axis_rec.axisTag; + a->minimum = axis_rec.minValue; /* A Fixed */ + a->def = axis_rec.defaultValue; /* A Fixed */ + a->maximum = axis_rec.maxValue; /* A Fixed */ + a->strid = axis_rec.nameID; + + a->name[0] = (FT_String)( a->tag >> 24 ); + a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF ); + a->name[2] = (FT_String)( ( a->tag >> 8 ) & 0xFF ); + a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); + a->name[4] = 0; + + ++a; + } + + ns = mmvar->namedstyle; + for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns ) + { + if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) + goto Exit; + + ns->strid = FT_GET_USHORT(); + (void) /* flags = */ FT_GET_USHORT(); + + for ( j = 0; j < fvar_head.axisCount; ++j ) + ns->coords[j] = FT_GET_ULONG(); /* A Fixed */ + + FT_FRAME_EXIT(); + } + } + + if ( master != NULL ) + { + FT_UInt n; + + + if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + goto Exit; + FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); + + mmvar->axis = + (FT_Var_Axis*)&(mmvar[1]); + mmvar->namedstyle = + (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]); + next_coords = + (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]); + + for ( n = 0; n < mmvar->num_namedstyles; ++n ) + { + mmvar->namedstyle[n].coords = next_coords; + next_coords += mmvar->num_axis; + } + + a = mmvar->axis; + next_name = (FT_String*)next_coords; + for ( n = 0; n < mmvar->num_axis; ++n ) + { + a->name = next_name; + + /* standard PostScript names for some standard apple tags */ + if ( a->tag == TTAG_wght ) + a->name = (char *)"Weight"; + else if ( a->tag == TTAG_wdth ) + a->name = (char *)"Width"; + else if ( a->tag == TTAG_opsz ) + a->name = (char *)"OpticalSize"; + else if ( a->tag == TTAG_slnt ) + a->name = (char *)"Slant"; + + next_name += 5; + ++a; + } + + *master = mmvar; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Set_MM_Blend */ + /* */ + /* <Description> */ + /* Set the blend (normalized) coordinates for this instance of the */ + /* font. Check that the `gvar' table is reasonable and does some */ + /* initial preparation. */ + /* */ + /* <InOut> */ + /* face :: The font. */ + /* Initialize the blend structure with `gvar' data. */ + /* */ + /* <Input> */ + /* num_coords :: Must be the axis count of the font. */ + /* */ + /* coords :: An array of num_coords, each between [-1,1]. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_MM_Var* mmvar; + FT_UInt i; + FT_Memory memory = face->root.memory; + + enum + { + mcvt_retain, + mcvt_modify, + mcvt_load + + } manageCvt; + + + face->doblend = FALSE; + + if ( face->blend == NULL ) + { + if ( (error = TT_Get_MM_Var( face, NULL)) != 0 ) + goto Exit; + } + + blend = face->blend; + mmvar = blend->mmvar; + + if ( num_coords != mmvar->num_axis ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + for ( i = 0; i < num_coords; ++i ) + if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( blend->glyphoffsets == NULL ) + if ( (error = ft_var_load_gvar( face )) != 0 ) + goto Exit; + + if ( blend->normalizedcoords == NULL ) + { + if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) ) + goto Exit; + + manageCvt = mcvt_modify; + + /* If we have not set the blend coordinates before this, then the */ + /* cvt table will still be what we read from the `cvt ' table and */ + /* we don't need to reload it. We may need to change it though... */ + } + else + { + manageCvt = mcvt_retain; + for ( i = 0; i < num_coords; ++i ) + { + if ( blend->normalizedcoords[i] != coords[i] ) + { + manageCvt = mcvt_load; + break; + } + } + + /* If we don't change the blend coords then we don't need to do */ + /* anything to the cvt table. It will be correct. Otherwise we */ + /* no longer have the original cvt (it was modified when we set */ + /* the blend last time), so we must reload and then modify it. */ + } + + blend->num_axis = num_coords; + FT_MEM_COPY( blend->normalizedcoords, + coords, + num_coords * sizeof ( FT_Fixed ) ); + + face->doblend = TRUE; + + if ( face->cvt != NULL ) + { + switch ( manageCvt ) + { + case mcvt_load: + /* The cvt table has been loaded already; every time we change the */ + /* blend we may need to reload and remodify the cvt table. */ + FT_FREE( face->cvt ); + face->cvt = NULL; + + tt_face_load_cvt( face, face->root.stream ); + break; + + case mcvt_modify: + /* The original cvt table is in memory. All we need to do is */ + /* apply the `cvar' table (if any). */ + tt_face_vary_cvt( face, face->root.stream ); + break; + + case mcvt_retain: + /* The cvt table is correct for this set of coordinates. */ + break; + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Set_Var_Design */ + /* */ + /* <Description> */ + /* Set the coordinates for the instance, measured in the user */ + /* coordinate system. Parse the `avar' table (if present) to convert */ + /* from user to normalized coordinates. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* Initialize the blend struct with `gvar' data. */ + /* */ + /* <Input> */ + /* num_coords :: This must be the axis count of the font. */ + /* */ + /* coords :: A coordinate array with `num_coords' elements. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_Var_Design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = FT_Err_Ok; + FT_Fixed* normalized = NULL; + GX_Blend blend; + FT_MM_Var* mmvar; + FT_UInt i, j; + FT_Var_Axis* a; + GX_AVarSegment av; + FT_Memory memory = face->root.memory; + + + if ( face->blend == NULL ) + { + if ( (error = TT_Get_MM_Var( face, NULL )) != 0 ) + goto Exit; + } + + blend = face->blend; + mmvar = blend->mmvar; + + if ( num_coords != mmvar->num_axis ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* Axis normalization is a two stage process. First we normalize */ + /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ + /* Then, if there's an `avar' table, we renormalize this range. */ + + if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) + goto Exit; + + a = mmvar->axis; + for ( i = 0; i < mmvar->num_axis; ++i, ++a ) + { + if ( coords[i] > a->maximum || coords[i] < a->minimum ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( coords[i] < a->def ) + normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def ); + else if ( a->maximum == a->def ) + normalized[i] = 0; + else + normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def ); + } + + if ( !blend->avar_checked ) + ft_var_load_avar( face ); + + if ( blend->avar_segment != NULL ) + { + av = blend->avar_segment; + for ( i = 0; i < mmvar->num_axis; ++i, ++av ) + { + for ( j = 1; j < (FT_UInt)av->pairCount; ++j ) + if ( normalized[i] < av->correspondence[j].fromCoord ) + { + normalized[i] = + FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, + av->correspondence[j].toCoord - + av->correspondence[j - 1].toCoord, + av->correspondence[j].fromCoord - + av->correspondence[j - 1].fromCoord ) + + av->correspondence[j - 1].toCoord; + break; + } + } + } + + error = TT_Set_MM_Blend( face, num_coords, normalized ); + + Exit: + FT_FREE( normalized ); + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GX VAR PARSING ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_vary_cvt */ + /* */ + /* <Description> */ + /* Modify the loaded cvt table according to the `cvar' table and the */ + /* font's blend. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* Most errors are ignored. It is perfectly valid not to have a */ + /* `cvar' table even if there is a `gvar' and `fvar' table. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_vary_cvt( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong table_start; + FT_ULong table_len; + FT_UInt tupleCount; + FT_ULong offsetToData; + FT_ULong here; + FT_UInt i, j; + FT_Fixed* tuple_coords = NULL; + FT_Fixed* im_start_coords = NULL; + FT_Fixed* im_end_coords = NULL; + GX_Blend blend = face->blend; + FT_UInt point_count; + FT_UShort* localpoints; + FT_Short* deltas; + + + FT_TRACE2(( "CVAR " )); + + if ( blend == NULL ) + { + FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); + + error = FT_Err_Ok; + goto Exit; + } + + if ( face->cvt == NULL ) + { + FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); + + error = FT_Err_Ok; + goto Exit; + } + + error = face->goto_table( face, TTAG_cvar, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing\n" )); + + error = FT_Err_Ok; + goto Exit; + } + + if ( FT_FRAME_ENTER( table_len ) ) + { + error = FT_Err_Ok; + goto Exit; + } + + table_start = FT_Stream_FTell( stream ); + if ( FT_GET_LONG() != 0x00010000L ) + { + FT_TRACE2(( "bad table version\n" )); + + error = FT_Err_Ok; + goto FExit; + } + + if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || + FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || + FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) + goto FExit; + + tupleCount = FT_GET_USHORT(); + offsetToData = table_start + FT_GET_USHORT(); + + /* The documentation implies there are flags packed into the */ + /* tuplecount, but John Jenkins says that shared points don't apply */ + /* to `cvar', and no other flags are defined. */ + + for ( i = 0; i < ( tupleCount & 0xFFF ); ++i ) + { + FT_UInt tupleDataSize; + FT_UInt tupleIndex; + FT_Fixed apply; + + + tupleDataSize = FT_GET_USHORT(); + tupleIndex = FT_GET_USHORT(); + + /* There is no provision here for a global tuple coordinate section, */ + /* so John says. There are no tuple indices, just embedded tuples. */ + + if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) + { + for ( j = 0; j < blend->num_axis; ++j ) + tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + /* short frac to fixed */ + } + else + { + /* skip this tuple; it makes no sense */ + + if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) + for ( j = 0; j < 2 * blend->num_axis; ++j ) + (void)FT_GET_SHORT(); + + offsetToData += tupleDataSize; + continue; + } + + if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) + { + for ( j = 0; j < blend->num_axis; ++j ) + im_start_coords[j] = FT_GET_SHORT() << 2; + for ( j = 0; j < blend->num_axis; ++j ) + im_end_coords[j] = FT_GET_SHORT() << 2; + } + + apply = ft_var_apply_tuple( blend, + (FT_UShort)tupleIndex, + tuple_coords, + im_start_coords, + im_end_coords ); + if ( /* tuple isn't active for our blend */ + apply == 0 || + /* global points not allowed, */ + /* if they aren't local, makes no sense */ + !( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) ) + { + offsetToData += tupleDataSize; + continue; + } + + here = FT_Stream_FTell( stream ); + + FT_Stream_SeekSet( stream, offsetToData ); + + localpoints = ft_var_readpackedpoints( stream, &point_count ); + deltas = ft_var_readpackeddeltas( stream, + point_count == 0 ? face->cvt_size + : point_count ); + if ( localpoints == NULL || deltas == NULL ) + /* failure, ignore it */; + + else if ( localpoints == ALL_POINTS ) + { + /* this means that there are deltas for every entry in cvt */ + for ( j = 0; j < face->cvt_size; ++j ) + face->cvt[j] = (FT_Short)( face->cvt[j] + + FT_MulFix( deltas[j], apply ) ); + } + + else + { + for ( j = 0; j < point_count; ++j ) + { + int pindex = localpoints[j]; + + face->cvt[pindex] = (FT_Short)( face->cvt[pindex] + + FT_MulFix( deltas[j], apply ) ); + } + } + + if ( localpoints != ALL_POINTS ) + FT_FREE( localpoints ); + FT_FREE( deltas ); + + offsetToData += tupleDataSize; + + FT_Stream_SeekSet( stream, here ); + } + + FExit: + FT_FRAME_EXIT(); + + Exit: + FT_FREE( tuple_coords ); + FT_FREE( im_start_coords ); + FT_FREE( im_end_coords ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Vary_Get_Glyph_Deltas */ + /* */ + /* <Description> */ + /* Load the appropriate deltas for the current glyph. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* glyph_index :: The index of the glyph being modified. */ + /* */ + /* n_points :: The number of the points in the glyph, including */ + /* phantom points. */ + /* */ + /* <Output> */ + /* deltas :: The array of points to change. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Vary_Get_Glyph_Deltas( TT_Face face, + FT_UInt glyph_index, + FT_Vector* *deltas, + FT_UInt n_points ) + { + FT_Stream stream = face->root.stream; + FT_Memory memory = stream->memory; + GX_Blend blend = face->blend; + FT_Vector* delta_xy = NULL; + + FT_Error error; + FT_ULong glyph_start; + FT_UInt tupleCount; + FT_ULong offsetToData; + FT_ULong here; + FT_UInt i, j; + FT_Fixed* tuple_coords = NULL; + FT_Fixed* im_start_coords = NULL; + FT_Fixed* im_end_coords = NULL; + FT_UInt point_count, spoint_count = 0; + FT_UShort* sharedpoints = NULL; + FT_UShort* localpoints = NULL; + FT_UShort* points; + FT_Short *deltas_x, *deltas_y; + + + if ( !face->doblend || blend == NULL ) + return FT_THROW( Invalid_Argument ); + + /* to be freed by the caller */ + if ( FT_NEW_ARRAY( delta_xy, n_points ) ) + goto Exit; + *deltas = delta_xy; + + if ( glyph_index >= blend->gv_glyphcnt || + blend->glyphoffsets[glyph_index] == + blend->glyphoffsets[glyph_index + 1] ) + return FT_Err_Ok; /* no variation data for this glyph */ + + if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || + FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - + blend->glyphoffsets[glyph_index] ) ) + goto Fail1; + + glyph_start = FT_Stream_FTell( stream ); + + /* each set of glyph variation data is formatted similarly to `cvar' */ + /* (except we get shared points and global tuples) */ + + if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || + FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || + FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) + goto Fail2; + + tupleCount = FT_GET_USHORT(); + offsetToData = glyph_start + FT_GET_USHORT(); + + if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) + { + here = FT_Stream_FTell( stream ); + + FT_Stream_SeekSet( stream, offsetToData ); + + sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); + offsetToData = FT_Stream_FTell( stream ); + + FT_Stream_SeekSet( stream, here ); + } + + for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i ) + { + FT_UInt tupleDataSize; + FT_UInt tupleIndex; + FT_Fixed apply; + + + tupleDataSize = FT_GET_USHORT(); + tupleIndex = FT_GET_USHORT(); + + if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) + { + for ( j = 0; j < blend->num_axis; ++j ) + tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + /* short frac to fixed */ + } + else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) + { + error = FT_THROW( Invalid_Table ); + goto Fail3; + } + else + { + FT_MEM_COPY( + tuple_coords, + &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis], + blend->num_axis * sizeof ( FT_Fixed ) ); + } + + if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) + { + for ( j = 0; j < blend->num_axis; ++j ) + im_start_coords[j] = FT_GET_SHORT() << 2; + for ( j = 0; j < blend->num_axis; ++j ) + im_end_coords[j] = FT_GET_SHORT() << 2; + } + + apply = ft_var_apply_tuple( blend, + (FT_UShort)tupleIndex, + tuple_coords, + im_start_coords, + im_end_coords ); + + if ( apply == 0 ) /* tuple isn't active for our blend */ + { + offsetToData += tupleDataSize; + continue; + } + + here = FT_Stream_FTell( stream ); + + if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) + { + FT_Stream_SeekSet( stream, offsetToData ); + + localpoints = ft_var_readpackedpoints( stream, &point_count ); + points = localpoints; + } + else + { + points = sharedpoints; + point_count = spoint_count; + } + + deltas_x = ft_var_readpackeddeltas( stream, + point_count == 0 ? n_points + : point_count ); + deltas_y = ft_var_readpackeddeltas( stream, + point_count == 0 ? n_points + : point_count ); + + if ( points == NULL || deltas_y == NULL || deltas_x == NULL ) + ; /* failure, ignore it */ + + else if ( points == ALL_POINTS ) + { + /* this means that there are deltas for every point in the glyph */ + for ( j = 0; j < n_points; ++j ) + { + delta_xy[j].x += FT_MulFix( deltas_x[j], apply ); + delta_xy[j].y += FT_MulFix( deltas_y[j], apply ); + } + } + + else + { + for ( j = 0; j < point_count; ++j ) + { + if ( localpoints[j] >= n_points ) + continue; + + delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply ); + delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply ); + } + } + + if ( localpoints != ALL_POINTS ) + FT_FREE( localpoints ); + FT_FREE( deltas_x ); + FT_FREE( deltas_y ); + + offsetToData += tupleDataSize; + + FT_Stream_SeekSet( stream, here ); + } + + Fail3: + FT_FREE( tuple_coords ); + FT_FREE( im_start_coords ); + FT_FREE( im_end_coords ); + + Fail2: + FT_FRAME_EXIT(); + + Fail1: + if ( error ) + { + FT_FREE( delta_xy ); + *deltas = NULL; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_done_blend */ + /* */ + /* <Description> */ + /* Frees the blend internal data structure. */ + /* */ + FT_LOCAL_DEF( void ) + tt_done_blend( FT_Memory memory, + GX_Blend blend ) + { + if ( blend != NULL ) + { + FT_UInt i; + + + FT_FREE( blend->normalizedcoords ); + FT_FREE( blend->mmvar ); + + if ( blend->avar_segment != NULL ) + { + for ( i = 0; i < blend->num_axis; ++i ) + FT_FREE( blend->avar_segment[i].correspondence ); + FT_FREE( blend->avar_segment ); + } + + FT_FREE( blend->tuplecoords ); + FT_FREE( blend->glyphoffsets ); + FT_FREE( blend ); + } + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttgxvar.h b/drivers/freetype/src/truetype/ttgxvar.h new file mode 100644 index 0000000000..82dfc4431f --- /dev/null +++ b/drivers/freetype/src/truetype/ttgxvar.h @@ -0,0 +1,182 @@ +/***************************************************************************/ +/* */ +/* ttgxvar.h */ +/* */ +/* TrueType GX Font Variation loader (specification) */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */ +/* */ +/* 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 __TTGXVAR_H__ +#define __TTGXVAR_H__ + + +#include <ft2build.h> +#include "ttobjs.h" + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* GX_AVarCorrespondenceRec */ + /* */ + /* <Description> */ + /* A data structure representing `shortFracCorrespondence' in `avar' */ + /* table according to the specifications from Apple. */ + /* */ + typedef struct GX_AVarCorrespondenceRec_ + { + FT_Fixed fromCoord; + FT_Fixed toCoord; + + } GX_AVarCorrespondenceRec_, *GX_AVarCorrespondence; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* GX_AVarRec */ + /* */ + /* <Description> */ + /* Data from the segment field of `avar' table. */ + /* There is one of these for each axis. */ + /* */ + typedef struct GX_AVarSegmentRec_ + { + FT_UShort pairCount; + GX_AVarCorrespondence correspondence; /* array with pairCount entries */ + + } GX_AVarSegmentRec, *GX_AVarSegment; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* GX_BlendRec */ + /* */ + /* <Description> */ + /* Data for interpolating a font from a distortable font specified */ + /* by the GX *var tables ([fgca]var). */ + /* */ + /* <Fields> */ + /* num_axis :: The number of axes along which interpolation */ + /* may happen */ + /* */ + /* normalizedcoords :: A normalized value (between [-1,1]) indicating */ + /* the contribution along each axis to the final */ + /* interpolated font. */ + /* */ + typedef struct GX_BlendRec_ + { + FT_UInt num_axis; + FT_Fixed* normalizedcoords; + + FT_MM_Var* mmvar; + FT_Offset mmvar_len; + + FT_Bool avar_checked; + GX_AVarSegment avar_segment; + + FT_UInt tuplecount; /* shared tuples in `gvar' */ + FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */ + + FT_UInt gv_glyphcnt; + FT_ULong* glyphoffsets; + + } GX_BlendRec; + + + /*************************************************************************/ + /* */ + /* <enum> */ + /* GX_TupleCountFlags */ + /* */ + /* <Description> */ + /* Flags used within the `TupleCount' field of the `gvar' table. */ + /* */ + typedef enum GX_TupleCountFlags_ + { + GX_TC_TUPLES_SHARE_POINT_NUMBERS = 0x8000, + GX_TC_RESERVED_TUPLE_FLAGS = 0x7000, + GX_TC_TUPLE_COUNT_MASK = 0x0FFF + + } GX_TupleCountFlags; + + + /*************************************************************************/ + /* */ + /* <enum> */ + /* GX_TupleIndexFlags */ + /* */ + /* <Description> */ + /* Flags used within the `TupleIndex' field of the `gvar' and `cvar' */ + /* tables. */ + /* */ + typedef enum GX_TupleIndexFlags_ + { + GX_TI_EMBEDDED_TUPLE_COORD = 0x8000, + GX_TI_INTERMEDIATE_TUPLE = 0x4000, + GX_TI_PRIVATE_POINT_NUMBERS = 0x2000, + GX_TI_RESERVED_TUPLE_FLAG = 0x1000, + GX_TI_TUPLE_INDEX_MASK = 0x0FFF + + } GX_TupleIndexFlags; + + +#define TTAG_wght FT_MAKE_TAG( 'w', 'g', 'h', 't' ) +#define TTAG_wdth FT_MAKE_TAG( 'w', 'd', 't', 'h' ) +#define TTAG_opsz FT_MAKE_TAG( 'o', 'p', 's', 'z' ) +#define TTAG_slnt FT_MAKE_TAG( 's', 'l', 'n', 't' ) + + + FT_LOCAL( FT_Error ) + TT_Set_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) + TT_Set_Var_Design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) + TT_Get_MM_Var( TT_Face face, + FT_MM_Var* *master ); + + + FT_LOCAL( FT_Error ) + tt_face_vary_cvt( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + TT_Vary_Get_Glyph_Deltas( TT_Face face, + FT_UInt glyph_index, + FT_Vector* *deltas, + FT_UInt n_points ); + + + FT_LOCAL( void ) + tt_done_blend( FT_Memory memory, + GX_Blend blend ); + + +FT_END_HEADER + + +#endif /* __TTGXVAR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttinterp.c b/drivers/freetype/src/truetype/ttinterp.c new file mode 100644 index 0000000000..e7ffb987ce --- /dev/null +++ b/drivers/freetype/src/truetype/ttinterp.c @@ -0,0 +1,8948 @@ +/***************************************************************************/ +/* */ +/* ttinterp.c */ +/* */ +/* TrueType bytecode interpreter (body). */ +/* */ +/* Copyright 1996-2013 */ +/* 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. */ +/* */ +/***************************************************************************/ + + +/* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ +/* issues; many thanks! */ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_TRIGONOMETRY_H +#include FT_SYSTEM_H +#include FT_TRUETYPE_DRIVER_H + +#include "ttinterp.h" +#include "tterrors.h" +#include "ttsubpix.h" + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + + /*************************************************************************/ + /* */ + /* 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_ttinterp + + /*************************************************************************/ + /* */ + /* In order to detect infinite loops in the code, we set up a counter */ + /* within the run loop. A single stroke of interpretation is now */ + /* limited to a maximum number of opcodes defined below. */ + /* */ +#define MAX_RUNNABLE_OPCODES 1000000L + + + /*************************************************************************/ + /* */ + /* There are two kinds of implementations: */ + /* */ + /* a. static implementation */ + /* */ + /* The current execution context is a static variable, which fields */ + /* are accessed directly by the interpreter during execution. The */ + /* context is named `cur'. */ + /* */ + /* This version is non-reentrant, of course. */ + /* */ + /* b. indirect implementation */ + /* */ + /* The current execution context is passed to _each_ function as its */ + /* first argument, and each field is thus accessed indirectly. */ + /* */ + /* This version is fully re-entrant. */ + /* */ + /* The idea is that an indirect implementation may be slower to execute */ + /* on low-end processors that are used in some systems (like 386s or */ + /* even 486s). */ + /* */ + /* As a consequence, the indirect implementation is now the default, as */ + /* its performance costs can be considered negligible in our context. */ + /* Note, however, that we kept the same source with macros because: */ + /* */ + /* - The code is kept very close in design to the Pascal code used for */ + /* development. */ + /* */ + /* - It's much more readable that way! */ + /* */ + /* - It's still open to experimentation and tuning. */ + /* */ + /*************************************************************************/ + + +#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ + +#define CUR (*exc) /* see ttobjs.h */ + + /*************************************************************************/ + /* */ + /* This macro is used whenever `exec' is unused in a function, to avoid */ + /* stupid warnings from pedantic compilers. */ + /* */ +#define FT_UNUSED_EXEC FT_UNUSED( exc ) + +#else /* static implementation */ + +#define CUR cur + +#define FT_UNUSED_EXEC int __dummy = __dummy + + static + TT_ExecContextRec cur; /* static exec. context variable */ + + /* apparently, we have a _lot_ of direct indexing when accessing */ + /* the static `cur', which makes the code bigger (due to all the */ + /* four bytes addresses). */ + +#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* The instruction argument stack. */ + /* */ +#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ + + + /*************************************************************************/ + /* */ + /* This macro is used whenever `args' is unused in a function, to avoid */ + /* stupid warnings from pedantic compilers. */ + /* */ +#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) + + +#define SUBPIXEL_HINTING \ + ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_38 ) + + + /*************************************************************************/ + /* */ + /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ + /* increase readability of the code. */ + /* */ + /*************************************************************************/ + + +#define SKIP_Code() \ + SkipCode( EXEC_ARG ) + +#define GET_ShortIns() \ + GetShortIns( EXEC_ARG ) + +#define NORMalize( x, y, v ) \ + Normalize( EXEC_ARG_ x, y, v ) + +#define SET_SuperRound( scale, flags ) \ + SetSuperRound( EXEC_ARG_ scale, flags ) + +#define ROUND_None( d, c ) \ + Round_None( EXEC_ARG_ d, c ) + +#define INS_Goto_CodeRange( range, ip ) \ + Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) + +#define CUR_Func_move( z, p, d ) \ + CUR.func_move( EXEC_ARG_ z, p, d ) + +#define CUR_Func_move_orig( z, p, d ) \ + CUR.func_move_orig( EXEC_ARG_ z, p, d ) + +#define CUR_Func_round( d, c ) \ + CUR.func_round( EXEC_ARG_ d, c ) + +#define CUR_Func_read_cvt( index ) \ + CUR.func_read_cvt( EXEC_ARG_ index ) + +#define CUR_Func_write_cvt( index, val ) \ + CUR.func_write_cvt( EXEC_ARG_ index, val ) + +#define CUR_Func_move_cvt( index, val ) \ + CUR.func_move_cvt( EXEC_ARG_ index, val ) + +#define CURRENT_Ratio() \ + Current_Ratio( EXEC_ARG ) + +#define CURRENT_Ppem() \ + Current_Ppem( EXEC_ARG ) + +#define CUR_Ppem() \ + Cur_PPEM( EXEC_ARG ) + +#define INS_SxVTL( a, b, c, d ) \ + Ins_SxVTL( EXEC_ARG_ a, b, c, d ) + +#define COMPUTE_Funcs() \ + Compute_Funcs( EXEC_ARG ) + +#define COMPUTE_Round( a ) \ + Compute_Round( EXEC_ARG_ a ) + +#define COMPUTE_Point_Displacement( a, b, c, d ) \ + Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) + +#define MOVE_Zp2_Point( a, b, c, t ) \ + Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) + + +#define CUR_Func_project( v1, v2 ) \ + CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) + +#define CUR_Func_dualproj( v1, v2 ) \ + CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) + +#define CUR_fast_project( v ) \ + CUR.func_project( EXEC_ARG_ (v)->x, (v)->y ) + +#define CUR_fast_dualproj( v ) \ + CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y ) + + + /*************************************************************************/ + /* */ + /* Instruction dispatch function, as used by the interpreter. */ + /* */ + typedef void (*TInstruction_Function)( INS_ARG ); + + + /*************************************************************************/ + /* */ + /* Two simple bounds-checking macros. */ + /* */ +#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) +#define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) + + /*************************************************************************/ + /* */ + /* This macro computes (a*2^14)/b and complements TT_MulFix14. */ + /* */ +#define TT_DivFix14( a, b ) \ + FT_DivFix( a, (b) << 2 ) + + +#undef SUCCESS +#define SUCCESS 0 + +#undef FAILURE +#define FAILURE 1 + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define GUESS_VECTOR( V ) \ + if ( CUR.face->unpatented_hinting ) \ + { \ + CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \ + CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \ + } +#else +#define GUESS_VECTOR( V ) +#endif + + /*************************************************************************/ + /* */ + /* CODERANGE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Goto_CodeRange */ + /* */ + /* <Description> */ + /* Switches to a new code range (updates the code related elements in */ + /* `exec', and `IP'). */ + /* */ + /* <Input> */ + /* range :: The new execution code range. */ + /* */ + /* IP :: The new IP in the new code range. */ + /* */ + /* <InOut> */ + /* exec :: The target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Goto_CodeRange( TT_ExecContext exec, + FT_Int range, + FT_Long IP ) + { + TT_CodeRange* coderange; + + + FT_ASSERT( range >= 1 && range <= 3 ); + + coderange = &exec->codeRangeTable[range - 1]; + + FT_ASSERT( coderange->base != NULL ); + + /* NOTE: Because the last instruction of a program may be a CALL */ + /* which will return to the first byte *after* the code */ + /* range, we test for IP <= Size instead of IP < Size. */ + /* */ + FT_ASSERT( (FT_ULong)IP <= coderange->size ); + + exec->code = coderange->base; + exec->codeSize = coderange->size; + exec->IP = IP; + exec->curRange = range; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Set_CodeRange */ + /* */ + /* <Description> */ + /* Sets a code range. */ + /* */ + /* <Input> */ + /* range :: The code range index. */ + /* */ + /* base :: The new code base. */ + /* */ + /* length :: The range size in bytes. */ + /* */ + /* <InOut> */ + /* exec :: The target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_CodeRange( TT_ExecContext exec, + FT_Int range, + void* base, + FT_Long length ) + { + FT_ASSERT( range >= 1 && range <= 3 ); + + exec->codeRangeTable[range - 1].base = (FT_Byte*)base; + exec->codeRangeTable[range - 1].size = length; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Clear_CodeRange */ + /* */ + /* <Description> */ + /* Clears a code range. */ + /* */ + /* <Input> */ + /* range :: The code range index. */ + /* */ + /* <InOut> */ + /* exec :: The target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Does not set the Error variable. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Clear_CodeRange( TT_ExecContext exec, + FT_Int range ) + { + FT_ASSERT( range >= 1 && range <= 3 ); + + exec->codeRangeTable[range - 1].base = NULL; + exec->codeRangeTable[range - 1].size = 0; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* EXECUTION CONTEXT ROUTINES */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Done_Context */ + /* */ + /* <Description> */ + /* Destroys a given context. */ + /* */ + /* <Input> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Done_Context( TT_ExecContext exec ) + { + FT_Memory memory = exec->memory; + + + /* points zone */ + exec->maxPoints = 0; + exec->maxContours = 0; + + /* free stack */ + FT_FREE( exec->stack ); + exec->stackSize = 0; + + /* free call stack */ + FT_FREE( exec->callStack ); + exec->callSize = 0; + exec->callTop = 0; + + /* free glyph code range */ + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; + + exec->size = NULL; + exec->face = NULL; + + FT_FREE( exec ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Init_Context */ + /* */ + /* <Description> */ + /* Initializes a context object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* <InOut> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Init_Context( TT_ExecContext exec, + FT_Memory memory ) + { + FT_Error error; + + + FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec )); + + exec->memory = memory; + exec->callSize = 32; + + if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) ) + goto Fail_Memory; + + /* all values in the context are set to 0 already, but this is */ + /* here as a remainder */ + exec->maxPoints = 0; + exec->maxContours = 0; + + exec->stackSize = 0; + exec->glyphSize = 0; + + exec->stack = NULL; + exec->glyphIns = NULL; + + exec->face = NULL; + exec->size = NULL; + + return FT_Err_Ok; + + Fail_Memory: + FT_ERROR(( "Init_Context: not enough memory for %p\n", exec )); + TT_Done_Context( exec ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Update_Max */ + /* */ + /* <Description> */ + /* Checks the size of a buffer and reallocates it if necessary. */ + /* */ + /* <Input> */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* multiplier :: The size in bytes of each element in the buffer. */ + /* */ + /* new_max :: The new capacity (size) of the buffer. */ + /* */ + /* <InOut> */ + /* size :: The address of the buffer's current size expressed */ + /* in elements. */ + /* */ + /* buff :: The address of the buffer base pointer. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + Update_Max( FT_Memory memory, + FT_ULong* size, + FT_Long multiplier, + void* _pbuff, + FT_ULong new_max ) + { + FT_Error error; + void** pbuff = (void**)_pbuff; + + + if ( *size < new_max ) + { + if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) + return error; + *size = new_max; + } + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Load_Context */ + /* */ + /* <Description> */ + /* Prepare an execution context for glyph hinting. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* size :: A handle to the source size object. */ + /* */ + /* <InOut> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Load_Context( TT_ExecContext exec, + TT_Face face, + TT_Size size ) + { + FT_Int i; + FT_ULong tmp; + TT_MaxProfile* maxp; + FT_Error error; + + + exec->face = face; + maxp = &face->max_profile; + exec->size = size; + + if ( size ) + { + exec->numFDefs = size->num_function_defs; + exec->maxFDefs = size->max_function_defs; + exec->numIDefs = size->num_instruction_defs; + exec->maxIDefs = size->max_instruction_defs; + exec->FDefs = size->function_defs; + exec->IDefs = size->instruction_defs; + exec->tt_metrics = size->ttmetrics; + exec->metrics = size->metrics; + + exec->maxFunc = size->max_func; + exec->maxIns = size->max_ins; + + for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) + exec->codeRangeTable[i] = size->codeRangeTable[i]; + + /* set graphics state */ + exec->GS = size->GS; + + exec->cvtSize = size->cvt_size; + exec->cvt = size->cvt; + + exec->storeSize = size->storage_size; + exec->storage = size->storage; + + exec->twilight = size->twilight; + + /* In case of multi-threading it can happen that the old size object */ + /* no longer exists, thus we must clear all glyph zone references. */ + ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) ); + exec->zp1 = exec->zp0; + exec->zp2 = exec->zp0; + } + + /* XXX: We reserve a little more elements on the stack to deal safely */ + /* with broken fonts like arialbs, courbs, timesbs, etc. */ + tmp = exec->stackSize; + error = Update_Max( exec->memory, + &tmp, + sizeof ( FT_F26Dot6 ), + (void*)&exec->stack, + maxp->maxStackElements + 32 ); + exec->stackSize = (FT_UInt)tmp; + if ( error ) + return error; + + tmp = exec->glyphSize; + error = Update_Max( exec->memory, + &tmp, + sizeof ( FT_Byte ), + (void*)&exec->glyphIns, + maxp->maxSizeOfInstructions ); + exec->glyphSize = (FT_UShort)tmp; + if ( error ) + return error; + + exec->pts.n_points = 0; + exec->pts.n_contours = 0; + + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + exec->zp0 = exec->pts; + + exec->instruction_trap = FALSE; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Save_Context */ + /* */ + /* <Description> */ + /* Saves the code ranges in a `size' object. */ + /* */ + /* <Input> */ + /* exec :: A handle to the source execution context. */ + /* */ + /* <InOut> */ + /* size :: A handle to the target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Save_Context( TT_ExecContext exec, + TT_Size size ) + { + FT_Int i; + + + /* XXX: Will probably disappear soon with all the code range */ + /* management, which is now rather obsolete. */ + /* */ + size->num_function_defs = exec->numFDefs; + size->num_instruction_defs = exec->numIDefs; + + size->max_func = exec->maxFunc; + size->max_ins = exec->maxIns; + + for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) + size->codeRangeTable[i] = exec->codeRangeTable[i]; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Run_Context */ + /* */ + /* <Description> */ + /* Executes one or more instructions in the execution context. */ + /* */ + /* <Input> */ + /* debug :: A Boolean flag. If set, the function sets some internal */ + /* variables and returns immediately, otherwise TT_RunIns() */ + /* is called. */ + /* */ + /* This is commented out currently. */ + /* */ + /* <Input> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* <Return> */ + /* TrueType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Run_Context( TT_ExecContext exec, + FT_Bool debug ) + { + FT_Error error; + + + if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) + != FT_Err_Ok ) + return error; + + exec->zp0 = exec->pts; + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + + exec->GS.gep0 = 1; + exec->GS.gep1 = 1; + exec->GS.gep2 = 1; + + exec->GS.projVector.x = 0x4000; + exec->GS.projVector.y = 0x0000; + + exec->GS.freeVector = exec->GS.projVector; + exec->GS.dualVector = exec->GS.projVector; + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + exec->GS.both_x_axis = TRUE; +#endif + + exec->GS.round_state = 1; + exec->GS.loop = 1; + + /* some glyphs leave something on the stack. so we clean it */ + /* before a new execution. */ + exec->top = 0; + exec->callTop = 0; + +#if 1 + FT_UNUSED( debug ); + + return exec->face->interpreter( exec ); +#else + if ( !debug ) + return TT_RunIns( exec ); + else + return FT_Err_Ok; +#endif + } + + + /* The default value for `scan_control' is documented as FALSE in the */ + /* TrueType specification. This is confusing since it implies a */ + /* Boolean value. However, this is not the case, thus both the */ + /* default values of our `scan_type' and `scan_control' fields (which */ + /* the documentation's `scan_control' variable is split into) are */ + /* zero. */ + + const TT_GraphicsState tt_default_graphics_state = + { + 0, 0, 0, + { 0x4000, 0 }, + { 0x4000, 0 }, + { 0x4000, 0 }, + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + TRUE, +#endif + + 1, 64, 1, + TRUE, 68, 0, 0, 9, 3, + 0, FALSE, 0, 1, 1, 1 + }; + + + /* documentation is in ttinterp.h */ + + FT_EXPORT_DEF( TT_ExecContext ) + TT_New_Context( TT_Driver driver ) + { + TT_ExecContext exec; + FT_Memory memory; + + + memory = driver->root.root.memory; + exec = driver->context; + + if ( !driver->context ) + { + FT_Error error; + + + /* allocate object */ + if ( FT_NEW( exec ) ) + goto Fail; + + /* initialize it; in case of error this deallocates `exec' too */ + error = Init_Context( exec, memory ); + if ( error ) + goto Fail; + + /* store it into the driver */ + driver->context = exec; + } + + return driver->context; + + Fail: + return NULL; + } + + + /*************************************************************************/ + /* */ + /* Before an opcode is executed, the interpreter verifies that there are */ + /* enough arguments on the stack, with the help of the `Pop_Push_Count' */ + /* table. */ + /* */ + /* For each opcode, the first column gives the number of arguments that */ + /* are popped from the stack; the second one gives the number of those */ + /* that are pushed in result. */ + /* */ + /* Opcodes which have a varying number of parameters in the data stream */ + /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */ + /* the `opcode_length' table, and the value in `Pop_Push_Count' is set */ + /* to zero. */ + /* */ + /*************************************************************************/ + + +#undef PACK +#define PACK( x, y ) ( ( x << 4 ) | y ) + + + static + const FT_Byte Pop_Push_Count[256] = + { + /* opcodes are gathered in groups of 16 */ + /* please keep the spaces as they are */ + + /* SVTCA y */ PACK( 0, 0 ), + /* SVTCA x */ PACK( 0, 0 ), + /* SPvTCA y */ PACK( 0, 0 ), + /* SPvTCA x */ PACK( 0, 0 ), + /* SFvTCA y */ PACK( 0, 0 ), + /* SFvTCA x */ PACK( 0, 0 ), + /* SPvTL // */ PACK( 2, 0 ), + /* SPvTL + */ PACK( 2, 0 ), + /* SFvTL // */ PACK( 2, 0 ), + /* SFvTL + */ PACK( 2, 0 ), + /* SPvFS */ PACK( 2, 0 ), + /* SFvFS */ PACK( 2, 0 ), + /* GPV */ PACK( 0, 2 ), + /* GFV */ PACK( 0, 2 ), + /* SFvTPv */ PACK( 0, 0 ), + /* ISECT */ PACK( 5, 0 ), + + /* SRP0 */ PACK( 1, 0 ), + /* SRP1 */ PACK( 1, 0 ), + /* SRP2 */ PACK( 1, 0 ), + /* SZP0 */ PACK( 1, 0 ), + /* SZP1 */ PACK( 1, 0 ), + /* SZP2 */ PACK( 1, 0 ), + /* SZPS */ PACK( 1, 0 ), + /* SLOOP */ PACK( 1, 0 ), + /* RTG */ PACK( 0, 0 ), + /* RTHG */ PACK( 0, 0 ), + /* SMD */ PACK( 1, 0 ), + /* ELSE */ PACK( 0, 0 ), + /* JMPR */ PACK( 1, 0 ), + /* SCvTCi */ PACK( 1, 0 ), + /* SSwCi */ PACK( 1, 0 ), + /* SSW */ PACK( 1, 0 ), + + /* DUP */ PACK( 1, 2 ), + /* POP */ PACK( 1, 0 ), + /* CLEAR */ PACK( 0, 0 ), + /* SWAP */ PACK( 2, 2 ), + /* DEPTH */ PACK( 0, 1 ), + /* CINDEX */ PACK( 1, 1 ), + /* MINDEX */ PACK( 1, 0 ), + /* AlignPTS */ PACK( 2, 0 ), + /* INS_$28 */ PACK( 0, 0 ), + /* UTP */ PACK( 1, 0 ), + /* LOOPCALL */ PACK( 2, 0 ), + /* CALL */ PACK( 1, 0 ), + /* FDEF */ PACK( 1, 0 ), + /* ENDF */ PACK( 0, 0 ), + /* MDAP[0] */ PACK( 1, 0 ), + /* MDAP[1] */ PACK( 1, 0 ), + + /* IUP[0] */ PACK( 0, 0 ), + /* IUP[1] */ PACK( 0, 0 ), + /* SHP[0] */ PACK( 0, 0 ), + /* SHP[1] */ PACK( 0, 0 ), + /* SHC[0] */ PACK( 1, 0 ), + /* SHC[1] */ PACK( 1, 0 ), + /* SHZ[0] */ PACK( 1, 0 ), + /* SHZ[1] */ PACK( 1, 0 ), + /* SHPIX */ PACK( 1, 0 ), + /* IP */ PACK( 0, 0 ), + /* MSIRP[0] */ PACK( 2, 0 ), + /* MSIRP[1] */ PACK( 2, 0 ), + /* AlignRP */ PACK( 0, 0 ), + /* RTDG */ PACK( 0, 0 ), + /* MIAP[0] */ PACK( 2, 0 ), + /* MIAP[1] */ PACK( 2, 0 ), + + /* NPushB */ PACK( 0, 0 ), + /* NPushW */ PACK( 0, 0 ), + /* WS */ PACK( 2, 0 ), + /* RS */ PACK( 1, 1 ), + /* WCvtP */ PACK( 2, 0 ), + /* RCvt */ PACK( 1, 1 ), + /* GC[0] */ PACK( 1, 1 ), + /* GC[1] */ PACK( 1, 1 ), + /* SCFS */ PACK( 2, 0 ), + /* MD[0] */ PACK( 2, 1 ), + /* MD[1] */ PACK( 2, 1 ), + /* MPPEM */ PACK( 0, 1 ), + /* MPS */ PACK( 0, 1 ), + /* FlipON */ PACK( 0, 0 ), + /* FlipOFF */ PACK( 0, 0 ), + /* DEBUG */ PACK( 1, 0 ), + + /* LT */ PACK( 2, 1 ), + /* LTEQ */ PACK( 2, 1 ), + /* GT */ PACK( 2, 1 ), + /* GTEQ */ PACK( 2, 1 ), + /* EQ */ PACK( 2, 1 ), + /* NEQ */ PACK( 2, 1 ), + /* ODD */ PACK( 1, 1 ), + /* EVEN */ PACK( 1, 1 ), + /* IF */ PACK( 1, 0 ), + /* EIF */ PACK( 0, 0 ), + /* AND */ PACK( 2, 1 ), + /* OR */ PACK( 2, 1 ), + /* NOT */ PACK( 1, 1 ), + /* DeltaP1 */ PACK( 1, 0 ), + /* SDB */ PACK( 1, 0 ), + /* SDS */ PACK( 1, 0 ), + + /* ADD */ PACK( 2, 1 ), + /* SUB */ PACK( 2, 1 ), + /* DIV */ PACK( 2, 1 ), + /* MUL */ PACK( 2, 1 ), + /* ABS */ PACK( 1, 1 ), + /* NEG */ PACK( 1, 1 ), + /* FLOOR */ PACK( 1, 1 ), + /* CEILING */ PACK( 1, 1 ), + /* ROUND[0] */ PACK( 1, 1 ), + /* ROUND[1] */ PACK( 1, 1 ), + /* ROUND[2] */ PACK( 1, 1 ), + /* ROUND[3] */ PACK( 1, 1 ), + /* NROUND[0] */ PACK( 1, 1 ), + /* NROUND[1] */ PACK( 1, 1 ), + /* NROUND[2] */ PACK( 1, 1 ), + /* NROUND[3] */ PACK( 1, 1 ), + + /* WCvtF */ PACK( 2, 0 ), + /* DeltaP2 */ PACK( 1, 0 ), + /* DeltaP3 */ PACK( 1, 0 ), + /* DeltaCn[0] */ PACK( 1, 0 ), + /* DeltaCn[1] */ PACK( 1, 0 ), + /* DeltaCn[2] */ PACK( 1, 0 ), + /* SROUND */ PACK( 1, 0 ), + /* S45Round */ PACK( 1, 0 ), + /* JROT */ PACK( 2, 0 ), + /* JROF */ PACK( 2, 0 ), + /* ROFF */ PACK( 0, 0 ), + /* INS_$7B */ PACK( 0, 0 ), + /* RUTG */ PACK( 0, 0 ), + /* RDTG */ PACK( 0, 0 ), + /* SANGW */ PACK( 1, 0 ), + /* AA */ PACK( 1, 0 ), + + /* FlipPT */ PACK( 0, 0 ), + /* FlipRgON */ PACK( 2, 0 ), + /* FlipRgOFF */ PACK( 2, 0 ), + /* INS_$83 */ PACK( 0, 0 ), + /* INS_$84 */ PACK( 0, 0 ), + /* ScanCTRL */ PACK( 1, 0 ), + /* SDPVTL[0] */ PACK( 2, 0 ), + /* SDPVTL[1] */ PACK( 2, 0 ), + /* GetINFO */ PACK( 1, 1 ), + /* IDEF */ PACK( 1, 0 ), + /* ROLL */ PACK( 3, 3 ), + /* MAX */ PACK( 2, 1 ), + /* MIN */ PACK( 2, 1 ), + /* ScanTYPE */ PACK( 1, 0 ), + /* InstCTRL */ PACK( 2, 0 ), + /* INS_$8F */ PACK( 0, 0 ), + + /* INS_$90 */ PACK( 0, 0 ), + /* INS_$91 */ PACK( 0, 0 ), + /* INS_$92 */ PACK( 0, 0 ), + /* INS_$93 */ PACK( 0, 0 ), + /* INS_$94 */ PACK( 0, 0 ), + /* INS_$95 */ PACK( 0, 0 ), + /* INS_$96 */ PACK( 0, 0 ), + /* INS_$97 */ PACK( 0, 0 ), + /* INS_$98 */ PACK( 0, 0 ), + /* INS_$99 */ PACK( 0, 0 ), + /* INS_$9A */ PACK( 0, 0 ), + /* INS_$9B */ PACK( 0, 0 ), + /* INS_$9C */ PACK( 0, 0 ), + /* INS_$9D */ PACK( 0, 0 ), + /* INS_$9E */ PACK( 0, 0 ), + /* INS_$9F */ PACK( 0, 0 ), + + /* INS_$A0 */ PACK( 0, 0 ), + /* INS_$A1 */ PACK( 0, 0 ), + /* INS_$A2 */ PACK( 0, 0 ), + /* INS_$A3 */ PACK( 0, 0 ), + /* INS_$A4 */ PACK( 0, 0 ), + /* INS_$A5 */ PACK( 0, 0 ), + /* INS_$A6 */ PACK( 0, 0 ), + /* INS_$A7 */ PACK( 0, 0 ), + /* INS_$A8 */ PACK( 0, 0 ), + /* INS_$A9 */ PACK( 0, 0 ), + /* INS_$AA */ PACK( 0, 0 ), + /* INS_$AB */ PACK( 0, 0 ), + /* INS_$AC */ PACK( 0, 0 ), + /* INS_$AD */ PACK( 0, 0 ), + /* INS_$AE */ PACK( 0, 0 ), + /* INS_$AF */ PACK( 0, 0 ), + + /* PushB[0] */ PACK( 0, 1 ), + /* PushB[1] */ PACK( 0, 2 ), + /* PushB[2] */ PACK( 0, 3 ), + /* PushB[3] */ PACK( 0, 4 ), + /* PushB[4] */ PACK( 0, 5 ), + /* PushB[5] */ PACK( 0, 6 ), + /* PushB[6] */ PACK( 0, 7 ), + /* PushB[7] */ PACK( 0, 8 ), + /* PushW[0] */ PACK( 0, 1 ), + /* PushW[1] */ PACK( 0, 2 ), + /* PushW[2] */ PACK( 0, 3 ), + /* PushW[3] */ PACK( 0, 4 ), + /* PushW[4] */ PACK( 0, 5 ), + /* PushW[5] */ PACK( 0, 6 ), + /* PushW[6] */ PACK( 0, 7 ), + /* PushW[7] */ PACK( 0, 8 ), + + /* MDRP[00] */ PACK( 1, 0 ), + /* MDRP[01] */ PACK( 1, 0 ), + /* MDRP[02] */ PACK( 1, 0 ), + /* MDRP[03] */ PACK( 1, 0 ), + /* MDRP[04] */ PACK( 1, 0 ), + /* MDRP[05] */ PACK( 1, 0 ), + /* MDRP[06] */ PACK( 1, 0 ), + /* MDRP[07] */ PACK( 1, 0 ), + /* MDRP[08] */ PACK( 1, 0 ), + /* MDRP[09] */ PACK( 1, 0 ), + /* MDRP[10] */ PACK( 1, 0 ), + /* MDRP[11] */ PACK( 1, 0 ), + /* MDRP[12] */ PACK( 1, 0 ), + /* MDRP[13] */ PACK( 1, 0 ), + /* MDRP[14] */ PACK( 1, 0 ), + /* MDRP[15] */ PACK( 1, 0 ), + + /* MDRP[16] */ PACK( 1, 0 ), + /* MDRP[17] */ PACK( 1, 0 ), + /* MDRP[18] */ PACK( 1, 0 ), + /* MDRP[19] */ PACK( 1, 0 ), + /* MDRP[20] */ PACK( 1, 0 ), + /* MDRP[21] */ PACK( 1, 0 ), + /* MDRP[22] */ PACK( 1, 0 ), + /* MDRP[23] */ PACK( 1, 0 ), + /* MDRP[24] */ PACK( 1, 0 ), + /* MDRP[25] */ PACK( 1, 0 ), + /* MDRP[26] */ PACK( 1, 0 ), + /* MDRP[27] */ PACK( 1, 0 ), + /* MDRP[28] */ PACK( 1, 0 ), + /* MDRP[29] */ PACK( 1, 0 ), + /* MDRP[30] */ PACK( 1, 0 ), + /* MDRP[31] */ PACK( 1, 0 ), + + /* MIRP[00] */ PACK( 2, 0 ), + /* MIRP[01] */ PACK( 2, 0 ), + /* MIRP[02] */ PACK( 2, 0 ), + /* MIRP[03] */ PACK( 2, 0 ), + /* MIRP[04] */ PACK( 2, 0 ), + /* MIRP[05] */ PACK( 2, 0 ), + /* MIRP[06] */ PACK( 2, 0 ), + /* MIRP[07] */ PACK( 2, 0 ), + /* MIRP[08] */ PACK( 2, 0 ), + /* MIRP[09] */ PACK( 2, 0 ), + /* MIRP[10] */ PACK( 2, 0 ), + /* MIRP[11] */ PACK( 2, 0 ), + /* MIRP[12] */ PACK( 2, 0 ), + /* MIRP[13] */ PACK( 2, 0 ), + /* MIRP[14] */ PACK( 2, 0 ), + /* MIRP[15] */ PACK( 2, 0 ), + + /* MIRP[16] */ PACK( 2, 0 ), + /* MIRP[17] */ PACK( 2, 0 ), + /* MIRP[18] */ PACK( 2, 0 ), + /* MIRP[19] */ PACK( 2, 0 ), + /* MIRP[20] */ PACK( 2, 0 ), + /* MIRP[21] */ PACK( 2, 0 ), + /* MIRP[22] */ PACK( 2, 0 ), + /* MIRP[23] */ PACK( 2, 0 ), + /* MIRP[24] */ PACK( 2, 0 ), + /* MIRP[25] */ PACK( 2, 0 ), + /* MIRP[26] */ PACK( 2, 0 ), + /* MIRP[27] */ PACK( 2, 0 ), + /* MIRP[28] */ PACK( 2, 0 ), + /* MIRP[29] */ PACK( 2, 0 ), + /* MIRP[30] */ PACK( 2, 0 ), + /* MIRP[31] */ PACK( 2, 0 ) + }; + + +#ifdef FT_DEBUG_LEVEL_TRACE + + static + const char* const opcode_name[256] = + { + "SVTCA y", + "SVTCA x", + "SPvTCA y", + "SPvTCA x", + "SFvTCA y", + "SFvTCA x", + "SPvTL ||", + "SPvTL +", + "SFvTL ||", + "SFvTL +", + "SPvFS", + "SFvFS", + "GPV", + "GFV", + "SFvTPv", + "ISECT", + + "SRP0", + "SRP1", + "SRP2", + "SZP0", + "SZP1", + "SZP2", + "SZPS", + "SLOOP", + "RTG", + "RTHG", + "SMD", + "ELSE", + "JMPR", + "SCvTCi", + "SSwCi", + "SSW", + + "DUP", + "POP", + "CLEAR", + "SWAP", + "DEPTH", + "CINDEX", + "MINDEX", + "AlignPTS", + "INS_$28", + "UTP", + "LOOPCALL", + "CALL", + "FDEF", + "ENDF", + "MDAP[0]", + "MDAP[1]", + + "IUP[0]", + "IUP[1]", + "SHP[0]", + "SHP[1]", + "SHC[0]", + "SHC[1]", + "SHZ[0]", + "SHZ[1]", + "SHPIX", + "IP", + "MSIRP[0]", + "MSIRP[1]", + "AlignRP", + "RTDG", + "MIAP[0]", + "MIAP[1]", + + "NPushB", + "NPushW", + "WS", + "RS", + "WCvtP", + "RCvt", + "GC[0]", + "GC[1]", + "SCFS", + "MD[0]", + "MD[1]", + "MPPEM", + "MPS", + "FlipON", + "FlipOFF", + "DEBUG", + + "LT", + "LTEQ", + "GT", + "GTEQ", + "EQ", + "NEQ", + "ODD", + "EVEN", + "IF", + "EIF", + "AND", + "OR", + "NOT", + "DeltaP1", + "SDB", + "SDS", + + "ADD", + "SUB", + "DIV", + "MUL", + "ABS", + "NEG", + "FLOOR", + "CEILING", + "ROUND[0]", + "ROUND[1]", + "ROUND[2]", + "ROUND[3]", + "NROUND[0]", + "NROUND[1]", + "NROUND[2]", + "NROUND[3]", + + "WCvtF", + "DeltaP2", + "DeltaP3", + "DeltaCn[0]", + "DeltaCn[1]", + "DeltaCn[2]", + "SROUND", + "S45Round", + "JROT", + "JROF", + "ROFF", + "INS_$7B", + "RUTG", + "RDTG", + "SANGW", + "AA", + + "FlipPT", + "FlipRgON", + "FlipRgOFF", + "INS_$83", + "INS_$84", + "ScanCTRL", + "SDVPTL[0]", + "SDVPTL[1]", + "GetINFO", + "IDEF", + "ROLL", + "MAX", + "MIN", + "ScanTYPE", + "InstCTRL", + "INS_$8F", + + "INS_$90", + "INS_$91", + "INS_$92", + "INS_$93", + "INS_$94", + "INS_$95", + "INS_$96", + "INS_$97", + "INS_$98", + "INS_$99", + "INS_$9A", + "INS_$9B", + "INS_$9C", + "INS_$9D", + "INS_$9E", + "INS_$9F", + + "INS_$A0", + "INS_$A1", + "INS_$A2", + "INS_$A3", + "INS_$A4", + "INS_$A5", + "INS_$A6", + "INS_$A7", + "INS_$A8", + "INS_$A9", + "INS_$AA", + "INS_$AB", + "INS_$AC", + "INS_$AD", + "INS_$AE", + "INS_$AF", + + "PushB[0]", + "PushB[1]", + "PushB[2]", + "PushB[3]", + "PushB[4]", + "PushB[5]", + "PushB[6]", + "PushB[7]", + "PushW[0]", + "PushW[1]", + "PushW[2]", + "PushW[3]", + "PushW[4]", + "PushW[5]", + "PushW[6]", + "PushW[7]", + + "MDRP[00]", + "MDRP[01]", + "MDRP[02]", + "MDRP[03]", + "MDRP[04]", + "MDRP[05]", + "MDRP[06]", + "MDRP[07]", + "MDRP[08]", + "MDRP[09]", + "MDRP[10]", + "MDRP[11]", + "MDRP[12]", + "MDRP[13]", + "MDRP[14]", + "MDRP[15]", + + "MDRP[16]", + "MDRP[17]", + "MDRP[18]", + "MDRP[19]", + "MDRP[20]", + "MDRP[21]", + "MDRP[22]", + "MDRP[23]", + "MDRP[24]", + "MDRP[25]", + "MDRP[26]", + "MDRP[27]", + "MDRP[28]", + "MDRP[29]", + "MDRP[30]", + "MDRP[31]", + + "MIRP[00]", + "MIRP[01]", + "MIRP[02]", + "MIRP[03]", + "MIRP[04]", + "MIRP[05]", + "MIRP[06]", + "MIRP[07]", + "MIRP[08]", + "MIRP[09]", + "MIRP[10]", + "MIRP[11]", + "MIRP[12]", + "MIRP[13]", + "MIRP[14]", + "MIRP[15]", + + "MIRP[16]", + "MIRP[17]", + "MIRP[18]", + "MIRP[19]", + "MIRP[20]", + "MIRP[21]", + "MIRP[22]", + "MIRP[23]", + "MIRP[24]", + "MIRP[25]", + "MIRP[26]", + "MIRP[27]", + "MIRP[28]", + "MIRP[29]", + "MIRP[30]", + "MIRP[31]" + }; + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + static + const FT_Char opcode_length[256] = + { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + -1,-2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + +#undef PACK + +#if 1 + + static FT_Int32 + TT_MulFix14( FT_Int32 a, + FT_Int b ) + { + FT_Int32 sign; + FT_UInt32 ah, al, mid, lo, hi; + + + sign = a ^ b; + + if ( a < 0 ) + a = -a; + if ( b < 0 ) + b = -b; + + ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU ); + al = (FT_UInt32)( a & 0xFFFFU ); + + lo = al * b; + mid = ah * b; + hi = mid >> 16; + mid = ( mid << 16 ) + ( 1 << 13 ); /* rounding */ + lo += mid; + if ( lo < mid ) + hi += 1; + + mid = ( lo >> 14 ) | ( hi << 18 ); + + return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid; + } + +#else + + /* compute (a*b)/2^14 with maximum accuracy and rounding */ + static FT_Int32 + TT_MulFix14( FT_Int32 a, + FT_Int b ) + { + FT_Int32 m, s, hi; + FT_UInt32 l, lo; + + + /* compute ax*bx as 64-bit value */ + l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); + m = ( a >> 16 ) * b; + + lo = l + ( (FT_UInt32)m << 16 ); + hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); + + /* divide the result by 2^14 with rounding */ + s = hi >> 31; + l = lo + (FT_UInt32)s; + hi += s + ( l < lo ); + lo = l; + + l = lo + 0x2000U; + hi += l < lo; + + return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); + } +#endif + + + /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */ + static FT_Int32 + TT_DotFix14( FT_Int32 ax, + FT_Int32 ay, + FT_Int bx, + FT_Int by ) + { + FT_Int32 m, s, hi1, hi2, hi; + FT_UInt32 l, lo1, lo2, lo; + + + /* compute ax*bx as 64-bit value */ + l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx ); + m = ( ax >> 16 ) * bx; + + lo1 = l + ( (FT_UInt32)m << 16 ); + hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l ); + + /* compute ay*by as 64-bit value */ + l = (FT_UInt32)( ( ay & 0xFFFFU ) * by ); + m = ( ay >> 16 ) * by; + + lo2 = l + ( (FT_UInt32)m << 16 ); + hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l ); + + /* add them */ + lo = lo1 + lo2; + hi = hi1 + hi2 + ( lo < lo1 ); + + /* divide the result by 2^14 with rounding */ + s = hi >> 31; + l = lo + (FT_UInt32)s; + hi += s + ( l < lo ); + lo = l; + + l = lo + 0x2000U; + hi += ( l < lo ); + + return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Current_Ratio */ + /* */ + /* <Description> */ + /* Returns the current aspect ratio scaling factor depending on the */ + /* projection vector's state and device resolutions. */ + /* */ + /* <Return> */ + /* The aspect ratio in 16.16 format, always <= 1.0 . */ + /* */ + static FT_Long + Current_Ratio( EXEC_OP ) + { + if ( !CUR.tt_metrics.ratio ) + { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; + else + CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + } + else +#endif + { + if ( CUR.GS.projVector.y == 0 ) + CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; + + else if ( CUR.GS.projVector.x == 0 ) + CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + + else + { + FT_F26Dot6 x, y; + + + x = TT_MulFix14( CUR.tt_metrics.x_ratio, + CUR.GS.projVector.x ); + y = TT_MulFix14( CUR.tt_metrics.y_ratio, + CUR.GS.projVector.y ); + CUR.tt_metrics.ratio = FT_Hypot( x, y ); + } + } + } + return CUR.tt_metrics.ratio; + } + + + static FT_Long + Current_Ppem( EXEC_OP ) + { + return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() ); + } + + + /*************************************************************************/ + /* */ + /* Functions related to the control value table (CVT). */ + /* */ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_F26Dot6 ) + Read_CVT( EXEC_OP_ FT_ULong idx ) + { + return CUR.cvt[idx]; + } + + + FT_CALLBACK_DEF( FT_F26Dot6 ) + Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) + { + return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() ); + } + + + FT_CALLBACK_DEF( void ) + Write_CVT( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] = value; + } + + + FT_CALLBACK_DEF( void ) + Write_CVT_Stretched( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() ); + } + + + FT_CALLBACK_DEF( void ) + Move_CVT( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] += value; + } + + + FT_CALLBACK_DEF( void ) + Move_CVT_Stretched( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* GetShortIns */ + /* */ + /* <Description> */ + /* Returns a short integer taken from the instruction stream at */ + /* address IP. */ + /* */ + /* <Return> */ + /* Short read at code[IP]. */ + /* */ + /* <Note> */ + /* This one could become a macro. */ + /* */ + static FT_Short + GetShortIns( EXEC_OP ) + { + /* Reading a byte stream so there is no endianess (DaveP) */ + CUR.IP += 2; + return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + + CUR.code[CUR.IP - 1] ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Ins_Goto_CodeRange */ + /* */ + /* <Description> */ + /* Goes to a certain code range in the instruction stream. */ + /* */ + /* <Input> */ + /* aRange :: The index of the code range. */ + /* */ + /* aIP :: The new IP address in the code range. */ + /* */ + /* <Return> */ + /* SUCCESS or FAILURE. */ + /* */ + static FT_Bool + Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, + FT_ULong aIP ) + { + TT_CodeRange* range; + + + if ( aRange < 1 || aRange > 3 ) + { + CUR.error = FT_THROW( Bad_Argument ); + return FAILURE; + } + + range = &CUR.codeRangeTable[aRange - 1]; + + if ( range->base == NULL ) /* invalid coderange */ + { + CUR.error = FT_THROW( Invalid_CodeRange ); + return FAILURE; + } + + /* NOTE: Because the last instruction of a program may be a CALL */ + /* which will return to the first byte *after* the code */ + /* range, we test for aIP <= Size, instead of aIP < Size. */ + + if ( aIP > range->size ) + { + CUR.error = FT_THROW( Code_Overflow ); + return FAILURE; + } + + CUR.code = range->base; + CUR.codeSize = range->size; + CUR.IP = aIP; + CUR.curRange = aRange; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Direct_Move */ + /* */ + /* <Description> */ + /* Moves a point by a given distance along the freedom vector. The */ + /* point will be `touched'. */ + /* */ + /* <Input> */ + /* point :: The index of the point to move. */ + /* */ + /* distance :: The distance to apply. */ + /* */ + /* <InOut> */ + /* zone :: The affected glyph zone. */ + /* */ + static void + Direct_Move( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_F26Dot6 v; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + { +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( !SUBPIXEL_HINTING || + ( !CUR.ignore_x_mode || + ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + { + zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Direct_Move_Orig */ + /* */ + /* <Description> */ + /* Moves the *original* position of a point by a given distance along */ + /* the freedom vector. Obviously, the point will not be `touched'. */ + /* */ + /* <Input> */ + /* point :: The index of the point to move. */ + /* */ + /* distance :: The distance to apply. */ + /* */ + /* <InOut> */ + /* zone :: The affected glyph zone. */ + /* */ + static void + Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_F26Dot6 v; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); + } + + + /*************************************************************************/ + /* */ + /* Special versions of Direct_Move() */ + /* */ + /* The following versions are used whenever both vectors are both */ + /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* */ + /*************************************************************************/ + + + static void + Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( !SUBPIXEL_HINTING || + !CUR.ignore_x_mode ) +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + zone->cur[point].x += distance; + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + + static void + Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->cur[point].y += distance; + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + + + /*************************************************************************/ + /* */ + /* Special versions of Direct_Move_Orig() */ + /* */ + /* The following versions are used whenever both vectors are both */ + /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* */ + /*************************************************************************/ + + + static void + Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].x += distance; + } + + + static void + Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].y += distance; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_None */ + /* */ + /* <Description> */ + /* Does not round, but adds engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance (not) to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* The compensated distance. */ + /* */ + /* <Note> */ + /* The TrueType specification says very few about the relationship */ + /* between rounding and engine compensation. However, it seems from */ + /* the description of super round that we should add the compensation */ + /* before rounding. */ + /* */ + static FT_F26Dot6 + Round_None( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( distance && val < 0 ) + val = 0; + } + else + { + val = distance - compensation; + if ( val > 0 ) + val = 0; + } + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_To_Grid */ + /* */ + /* <Description> */ + /* Rounds value to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation + 32; + if ( distance && val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -FT_PIX_ROUND( compensation - distance ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_To_Half_Grid */ + /* */ + /* <Description> */ + /* Rounds value to half grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = FT_PIX_FLOOR( distance + compensation ) + 32; + if ( distance && val < 0 ) + val = 0; + } + else + { + val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_Down_To_Grid */ + /* */ + /* <Description> */ + /* Rounds value down to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( distance && val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -( ( compensation - distance ) & -64 ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_Up_To_Grid */ + /* */ + /* <Description> */ + /* Rounds value up to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation + 63; + if ( distance && val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -FT_PIX_CEIL( compensation - distance ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_To_Double_Grid */ + /* */ + /* <Description> */ + /* Rounds value to double grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation + 16; + if ( distance && val > 0 ) + val &= ~31; + else + val = 0; + } + else + { + val = -FT_PAD_ROUND( compensation - distance, 32 ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_Super */ + /* */ + /* <Description> */ + /* Super-rounds value to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + /* <Note> */ + /* The TrueType specification says very few about the relationship */ + /* between rounding and engine compensation. However, it seems from */ + /* the description of super round that we should add the compensation */ + /* before rounding. */ + /* */ + static FT_F26Dot6 + Round_Super( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = ( distance - CUR.phase + CUR.threshold + compensation ) & + -CUR.period; + if ( distance && val < 0 ) + val = 0; + val += CUR.phase; + } + else + { + val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & + -CUR.period ); + if ( val > 0 ) + val = 0; + val -= CUR.phase; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_Super_45 */ + /* */ + /* <Description> */ + /* Super-rounds value to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + /* <Note> */ + /* There is a separate function for Round_Super_45() as we may need */ + /* greater precision. */ + /* */ + static FT_F26Dot6 + Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / + CUR.period ) * CUR.period; + if ( distance && val < 0 ) + val = 0; + val += CUR.phase; + } + else + { + val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / + CUR.period ) * CUR.period ); + if ( val > 0 ) + val = 0; + val -= CUR.phase; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Compute_Round */ + /* */ + /* <Description> */ + /* Sets the rounding mode. */ + /* */ + /* <Input> */ + /* round_mode :: The rounding mode to be used. */ + /* */ + static void + Compute_Round( EXEC_OP_ FT_Byte round_mode ) + { + switch ( round_mode ) + { + case TT_Round_Off: + CUR.func_round = (TT_Round_Func)Round_None; + break; + + case TT_Round_To_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Grid; + break; + + case TT_Round_Up_To_Grid: + CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + break; + + case TT_Round_Down_To_Grid: + CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + break; + + case TT_Round_To_Half_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + break; + + case TT_Round_To_Double_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + break; + + case TT_Round_Super: + CUR.func_round = (TT_Round_Func)Round_Super; + break; + + case TT_Round_Super_45: + CUR.func_round = (TT_Round_Func)Round_Super_45; + break; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* SetSuperRound */ + /* */ + /* <Description> */ + /* Sets Super Round parameters. */ + /* */ + /* <Input> */ + /* GridPeriod :: The grid period. */ + /* */ + /* selector :: The SROUND opcode. */ + /* */ + static void + SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, + FT_Long selector ) + { + switch ( (FT_Int)( selector & 0xC0 ) ) + { + case 0: + CUR.period = GridPeriod / 2; + break; + + case 0x40: + CUR.period = GridPeriod; + break; + + case 0x80: + CUR.period = GridPeriod * 2; + break; + + /* This opcode is reserved, but... */ + + case 0xC0: + CUR.period = GridPeriod; + break; + } + + switch ( (FT_Int)( selector & 0x30 ) ) + { + case 0: + CUR.phase = 0; + break; + + case 0x10: + CUR.phase = CUR.period / 4; + break; + + case 0x20: + CUR.phase = CUR.period / 2; + break; + + case 0x30: + CUR.phase = CUR.period * 3 / 4; + break; + } + + if ( ( selector & 0x0F ) == 0 ) + CUR.threshold = CUR.period - 1; + else + CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; + + CUR.period /= 256; + CUR.phase /= 256; + CUR.threshold /= 256; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Project */ + /* */ + /* <Description> */ + /* Computes the projection of vector given by (v2-v1) along the */ + /* current projection vector. */ + /* */ + /* <Input> */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* <Return> */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project( EXEC_OP_ FT_Pos dx, + FT_Pos dy ) + { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, + CUR.GS.projVector.x, + CUR.GS.projVector.y ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Dual_Project */ + /* */ + /* <Description> */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* current dual vector. */ + /* */ + /* <Input> */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* <Return> */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Dual_Project( EXEC_OP_ FT_Pos dx, + FT_Pos dy ) + { + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, + CUR.GS.dualVector.x, + CUR.GS.dualVector.y ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Project_x */ + /* */ + /* <Description> */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* horizontal axis. */ + /* */ + /* <Input> */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* <Return> */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project_x( EXEC_OP_ FT_Pos dx, + FT_Pos dy ) + { + FT_UNUSED_EXEC; + FT_UNUSED( dy ); + + return dx; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Project_y */ + /* */ + /* <Description> */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* vertical axis. */ + /* */ + /* <Input> */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* <Return> */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project_y( EXEC_OP_ FT_Pos dx, + FT_Pos dy ) + { + FT_UNUSED_EXEC; + FT_UNUSED( dx ); + + return dy; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Compute_Funcs */ + /* */ + /* <Description> */ + /* Computes the projection and movement function pointers according */ + /* to the current graphics state. */ + /* */ + static void + Compute_Funcs( EXEC_OP ) + { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + /* If both vectors point rightwards along the x axis, set */ + /* `both-x-axis' true, otherwise set it false. The x values only */ + /* need be tested because the vector has been normalised to a unit */ + /* vector of length 0x4000 = unity. */ + CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 && + CUR.GS.freeVector.x == 0x4000 ); + + /* Throw away projection and freedom vector information */ + /* because the patents don't allow them to be stored. */ + /* The relevant US Patents are 5155805 and 5325479. */ + CUR.GS.projVector.x = 0; + CUR.GS.projVector.y = 0; + CUR.GS.freeVector.x = 0; + CUR.GS.freeVector.y = 0; + + if ( CUR.GS.both_x_axis ) + { + CUR.func_project = Project_x; + CUR.func_move = Direct_Move_X; + CUR.func_move_orig = Direct_Move_Orig_X; + } + else + { + CUR.func_project = Project_y; + CUR.func_move = Direct_Move_Y; + CUR.func_move_orig = Direct_Move_Orig_Y; + } + + if ( CUR.GS.dualVector.x == 0x4000 ) + CUR.func_dualproj = Project_x; + else if ( CUR.GS.dualVector.y == 0x4000 ) + CUR.func_dualproj = Project_y; + else + CUR.func_dualproj = Dual_Project; + + /* Force recalculation of cached aspect ratio */ + CUR.tt_metrics.ratio = 0; + + return; + } +#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ + + if ( CUR.GS.freeVector.x == 0x4000 ) + CUR.F_dot_P = CUR.GS.projVector.x; + else if ( CUR.GS.freeVector.y == 0x4000 ) + CUR.F_dot_P = CUR.GS.projVector.y; + else + CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x + + (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >> + 14; + + if ( CUR.GS.projVector.x == 0x4000 ) + CUR.func_project = (TT_Project_Func)Project_x; + else if ( CUR.GS.projVector.y == 0x4000 ) + CUR.func_project = (TT_Project_Func)Project_y; + else + CUR.func_project = (TT_Project_Func)Project; + + if ( CUR.GS.dualVector.x == 0x4000 ) + CUR.func_dualproj = (TT_Project_Func)Project_x; + else if ( CUR.GS.dualVector.y == 0x4000 ) + CUR.func_dualproj = (TT_Project_Func)Project_y; + else + CUR.func_dualproj = (TT_Project_Func)Dual_Project; + + CUR.func_move = (TT_Move_Func)Direct_Move; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; + + if ( CUR.F_dot_P == 0x4000L ) + { + if ( CUR.GS.freeVector.x == 0x4000 ) + { + CUR.func_move = (TT_Move_Func)Direct_Move_X; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; + } + else if ( CUR.GS.freeVector.y == 0x4000 ) + { + CUR.func_move = (TT_Move_Func)Direct_Move_Y; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; + } + } + + /* at small sizes, F_dot_P can become too small, resulting */ + /* in overflows and `spikes' in a number of glyphs like `w'. */ + + if ( FT_ABS( CUR.F_dot_P ) < 0x400L ) + CUR.F_dot_P = 0x4000L; + + /* Disable cached aspect ratio */ + CUR.tt_metrics.ratio = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Normalize */ + /* */ + /* <Description> */ + /* Norms a vector. */ + /* */ + /* <Input> */ + /* Vx :: The horizontal input vector coordinate. */ + /* Vy :: The vertical input vector coordinate. */ + /* */ + /* <Output> */ + /* R :: The normed unit vector. */ + /* */ + /* <Return> */ + /* Returns FAILURE if a vector parameter is zero. */ + /* */ + /* <Note> */ + /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ + /* R is undefined. */ + /* */ + static FT_Bool + Normalize( EXEC_OP_ FT_F26Dot6 Vx, + FT_F26Dot6 Vy, + FT_UnitVector* R ) + { + FT_F26Dot6 W; + + FT_UNUSED_EXEC; + + + if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L ) + { + if ( Vx == 0 && Vy == 0 ) + { + /* XXX: UNDOCUMENTED! It seems that it is possible to try */ + /* to normalize the vector (0,0). Return immediately. */ + return SUCCESS; + } + + Vx *= 0x4000; + Vy *= 0x4000; + } + + W = FT_Hypot( Vx, Vy ); + + R->x = (FT_F2Dot14)TT_DivFix14( Vx, W ); + R->y = (FT_F2Dot14)TT_DivFix14( Vy, W ); + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* Here we start with the implementation of the various opcodes. */ + /* */ + /*************************************************************************/ + + + static FT_Bool + Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, + FT_UShort aIdx2, + FT_Int aOpc, + FT_UnitVector* Vec ) + { + FT_Long A, B, C; + FT_Vector* p1; + FT_Vector* p2; + + + if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || + BOUNDS( aIdx2, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return FAILURE; + } + + p1 = CUR.zp1.cur + aIdx2; + p2 = CUR.zp2.cur + aIdx1; + + A = p1->x - p2->x; + B = p1->y - p2->y; + + /* If p1 == p2, SPVTL and SFVTL behave the same as */ + /* SPVTCA[X] and SFVTCA[X], respectively. */ + /* */ + /* Confirmed by Greg Hitchcock. */ + + if ( A == 0 && B == 0 ) + { + A = 0x4000; + aOpc = 0; + } + + if ( ( aOpc & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, Vec ); + + return SUCCESS; + } + + + /* When not using the big switch statements, the interpreter uses a */ + /* call table defined later below in this source. Each opcode must */ + /* thus have a corresponding function, even trivial ones. */ + /* */ + /* They are all defined there. */ + +#define DO_SVTCA \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.projVector.x = A; \ + CUR.GS.dualVector.x = A; \ + \ + CUR.GS.freeVector.y = B; \ + CUR.GS.projVector.y = B; \ + CUR.GS.dualVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTCA \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_Short)0x4000; \ + \ + CUR.GS.projVector.x = A; \ + CUR.GS.dualVector.x = A; \ + \ + CUR.GS.projVector.y = B; \ + CUR.GS.dualVector.y = B; \ + \ + GUESS_VECTOR( freeVector ); \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTCA \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.freeVector.y = B; \ + \ + GUESS_VECTOR( projVector ); \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTL \ + if ( INS_SxVTL( (FT_UShort)args[1], \ + (FT_UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.projVector ) == SUCCESS ) \ + { \ + CUR.GS.dualVector = CUR.GS.projVector; \ + GUESS_VECTOR( freeVector ); \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTL \ + if ( INS_SxVTL( (FT_UShort)args[1], \ + (FT_UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.freeVector ) == SUCCESS ) \ + { \ + GUESS_VECTOR( projVector ); \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTPV \ + GUESS_VECTOR( projVector ); \ + CUR.GS.freeVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); + + +#define DO_SPVFS \ + { \ + FT_Short S; \ + FT_Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (FT_Short)args[1]; \ + Y = (FT_Long)S; \ + S = (FT_Short)args[0]; \ + X = (FT_Long)S; \ + \ + NORMalize( X, Y, &CUR.GS.projVector ); \ + \ + CUR.GS.dualVector = CUR.GS.projVector; \ + GUESS_VECTOR( freeVector ); \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVFS \ + { \ + FT_Short S; \ + FT_Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (FT_Short)args[1]; \ + Y = (FT_Long)S; \ + S = (FT_Short)args[0]; \ + X = S; \ + \ + NORMalize( X, Y, &CUR.GS.freeVector ); \ + GUESS_VECTOR( projVector ); \ + COMPUTE_Funcs(); \ + } + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define DO_GPV \ + if ( CUR.face->unpatented_hinting ) \ + { \ + args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ + args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ + } \ + else \ + { \ + args[0] = CUR.GS.projVector.x; \ + args[1] = CUR.GS.projVector.y; \ + } +#else +#define DO_GPV \ + args[0] = CUR.GS.projVector.x; \ + args[1] = CUR.GS.projVector.y; +#endif + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define DO_GFV \ + if ( CUR.face->unpatented_hinting ) \ + { \ + args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ + args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ + } \ + else \ + { \ + args[0] = CUR.GS.freeVector.x; \ + args[1] = CUR.GS.freeVector.y; \ + } +#else +#define DO_GFV \ + args[0] = CUR.GS.freeVector.x; \ + args[1] = CUR.GS.freeVector.y; +#endif + + +#define DO_SRP0 \ + CUR.GS.rp0 = (FT_UShort)args[0]; + + +#define DO_SRP1 \ + CUR.GS.rp1 = (FT_UShort)args[0]; + + +#define DO_SRP2 \ + CUR.GS.rp2 = (FT_UShort)args[0]; + + +#define DO_RTHG \ + CUR.GS.round_state = TT_Round_To_Half_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + + +#define DO_RTG \ + CUR.GS.round_state = TT_Round_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Grid; + + +#define DO_RTDG \ + CUR.GS.round_state = TT_Round_To_Double_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + + +#define DO_RUTG \ + CUR.GS.round_state = TT_Round_Up_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + + +#define DO_RDTG \ + CUR.GS.round_state = TT_Round_Down_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + + +#define DO_ROFF \ + CUR.GS.round_state = TT_Round_Off; \ + CUR.func_round = (TT_Round_Func)Round_None; + + +#define DO_SROUND \ + SET_SuperRound( 0x4000, args[0] ); \ + CUR.GS.round_state = TT_Round_Super; \ + CUR.func_round = (TT_Round_Func)Round_Super; + + +#define DO_S45ROUND \ + SET_SuperRound( 0x2D41, args[0] ); \ + CUR.GS.round_state = TT_Round_Super_45; \ + CUR.func_round = (TT_Round_Func)Round_Super_45; + + +#define DO_SLOOP \ + if ( args[0] < 0 ) \ + CUR.error = FT_THROW( Bad_Argument ); \ + else \ + CUR.GS.loop = args[0]; + + +#define DO_SMD \ + CUR.GS.minimum_distance = args[0]; + + +#define DO_SCVTCI \ + CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; + + +#define DO_SSWCI \ + CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; + + +#define DO_SSW \ + CUR.GS.single_width_value = FT_MulFix( args[0], \ + CUR.tt_metrics.scale ); + + +#define DO_FLIPON \ + CUR.GS.auto_flip = TRUE; + + +#define DO_FLIPOFF \ + CUR.GS.auto_flip = FALSE; + + +#define DO_SDB \ + CUR.GS.delta_base = (FT_Short)args[0]; + + +#define DO_SDS \ + CUR.GS.delta_shift = (FT_Short)args[0]; + + +#define DO_MD /* nothing */ + + +#define DO_MPPEM \ + args[0] = CURRENT_Ppem(); + + + /* Note: The pointSize should be irrelevant in a given font program; */ + /* we thus decide to return only the ppem. */ +#if 0 + +#define DO_MPS \ + args[0] = CUR.metrics.pointSize; + +#else + +#define DO_MPS \ + args[0] = CURRENT_Ppem(); + +#endif /* 0 */ + + +#define DO_DUP \ + args[1] = args[0]; + + +#define DO_CLEAR \ + CUR.new_top = 0; + + +#define DO_SWAP \ + { \ + FT_Long L; \ + \ + \ + L = args[0]; \ + args[0] = args[1]; \ + args[1] = L; \ + } + + +#define DO_DEPTH \ + args[0] = CUR.top; + + +#define DO_CINDEX \ + { \ + FT_Long L; \ + \ + \ + L = args[0]; \ + \ + if ( L <= 0 || L > CUR.args ) \ + { \ + if ( CUR.pedantic_hinting ) \ + CUR.error = FT_THROW( Invalid_Reference ); \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR.stack[CUR.args - L]; \ + } + + +#define DO_JROT \ + if ( args[1] != 0 ) \ + { \ + if ( args[0] == 0 && CUR.args == 0 ) \ + CUR.error = FT_THROW( Bad_Argument ); \ + CUR.IP += args[0]; \ + if ( CUR.IP < 0 || \ + ( CUR.callTop > 0 && \ + CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ + CUR.error = FT_THROW( Bad_Argument ); \ + CUR.step_ins = FALSE; \ + } + + +#define DO_JMPR \ + if ( args[0] == 0 && CUR.args == 0 ) \ + CUR.error = FT_THROW( Bad_Argument ); \ + CUR.IP += args[0]; \ + if ( CUR.IP < 0 || \ + ( CUR.callTop > 0 && \ + CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ + CUR.error = FT_THROW( Bad_Argument ); \ + CUR.step_ins = FALSE; + + +#define DO_JROF \ + if ( args[1] == 0 ) \ + { \ + if ( args[0] == 0 && CUR.args == 0 ) \ + CUR.error = FT_THROW( Bad_Argument ); \ + CUR.IP += args[0]; \ + if ( CUR.IP < 0 || \ + ( CUR.callTop > 0 && \ + CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ + CUR.error = FT_THROW( Bad_Argument ); \ + CUR.step_ins = FALSE; \ + } + + +#define DO_LT \ + args[0] = ( args[0] < args[1] ); + + +#define DO_LTEQ \ + args[0] = ( args[0] <= args[1] ); + + +#define DO_GT \ + args[0] = ( args[0] > args[1] ); + + +#define DO_GTEQ \ + args[0] = ( args[0] >= args[1] ); + + +#define DO_EQ \ + args[0] = ( args[0] == args[1] ); + + +#define DO_NEQ \ + args[0] = ( args[0] != args[1] ); + + +#define DO_ODD \ + args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); + + +#define DO_EVEN \ + args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); + + +#define DO_AND \ + args[0] = ( args[0] && args[1] ); + + +#define DO_OR \ + args[0] = ( args[0] || args[1] ); + + +#define DO_NOT \ + args[0] = !args[0]; + + +#define DO_ADD \ + args[0] += args[1]; + + +#define DO_SUB \ + args[0] -= args[1]; + + +#define DO_DIV \ + if ( args[1] == 0 ) \ + CUR.error = FT_THROW( Divide_By_Zero ); \ + else \ + args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); + + +#define DO_MUL \ + args[0] = FT_MulDiv( args[0], args[1], 64L ); + + +#define DO_ABS \ + args[0] = FT_ABS( args[0] ); + + +#define DO_NEG \ + args[0] = -args[0]; + + +#define DO_FLOOR \ + args[0] = FT_PIX_FLOOR( args[0] ); + + +#define DO_CEILING \ + args[0] = FT_PIX_CEIL( args[0] ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + +#define DO_RS \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDSL( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + ARRAY_BOUND_ERROR; \ + else \ + args[0] = 0; \ + } \ + else \ + { \ + /* subpixel hinting - avoid Typeman Dstroke and */ \ + /* IStroke and Vacuform rounds */ \ + \ + if ( SUBPIXEL_HINTING && \ + CUR.ignore_x_mode && \ + ( ( I == 24 && \ + ( CUR.face->sph_found_func_flags & \ + ( SPH_FDEF_SPACING_1 | \ + SPH_FDEF_SPACING_2 ) ) ) || \ + ( I == 22 && \ + ( CUR.sph_in_func_flags & \ + SPH_FDEF_TYPEMAN_STROKES ) ) || \ + ( I == 8 && \ + ( CUR.face->sph_found_func_flags & \ + SPH_FDEF_VACUFORM_ROUND_1 ) && \ + CUR.iup_called ) ) ) \ + args[0] = 0; \ + else \ + args[0] = CUR.storage[I]; \ + } \ + } + +#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + +#define DO_RS \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDSL( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + else \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR.storage[I]; \ + } + +#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + +#define DO_WS \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDSL( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.storage[I] = args[1]; \ + } + + +#define DO_RCVT \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDSL( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + else \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR_Func_read_cvt( I ); \ + } + + +#define DO_WCVTP \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDSL( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR_Func_write_cvt( I, args[1] ); \ + } + + +#define DO_WCVTF \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDSL( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \ + } + + +#define DO_DEBUG \ + CUR.error = FT_THROW( Debug_OpCode ); + + +#define DO_ROUND \ + args[0] = CUR_Func_round( \ + args[0], \ + CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); + + +#define DO_NROUND \ + args[0] = ROUND_None( args[0], \ + CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); + + +#define DO_MAX \ + if ( args[1] > args[0] ) \ + args[0] = args[1]; + + +#define DO_MIN \ + if ( args[1] < args[0] ) \ + args[0] = args[1]; + + +#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +#undef ARRAY_BOUND_ERROR +#define ARRAY_BOUND_ERROR \ + { \ + CUR.error = FT_THROW( Invalid_Reference ); \ + return; \ + } + + + /*************************************************************************/ + /* */ + /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ + /* Opcode range: 0x00-0x01 */ + /* Stack: --> */ + /* */ + static void + Ins_SVTCA( INS_ARG ) + { + DO_SVTCA + } + + + /*************************************************************************/ + /* */ + /* SPVTCA[a]: Set PVector to Coordinate Axis */ + /* Opcode range: 0x02-0x03 */ + /* Stack: --> */ + /* */ + static void + Ins_SPVTCA( INS_ARG ) + { + DO_SPVTCA + } + + + /*************************************************************************/ + /* */ + /* SFVTCA[a]: Set FVector to Coordinate Axis */ + /* Opcode range: 0x04-0x05 */ + /* Stack: --> */ + /* */ + static void + Ins_SFVTCA( INS_ARG ) + { + DO_SFVTCA + } + + + /*************************************************************************/ + /* */ + /* SPVTL[a]: Set PVector To Line */ + /* Opcode range: 0x06-0x07 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SPVTL( INS_ARG ) + { + DO_SPVTL + } + + + /*************************************************************************/ + /* */ + /* SFVTL[a]: Set FVector To Line */ + /* Opcode range: 0x08-0x09 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SFVTL( INS_ARG ) + { + DO_SFVTL + } + + + /*************************************************************************/ + /* */ + /* SFVTPV[]: Set FVector To PVector */ + /* Opcode range: 0x0E */ + /* Stack: --> */ + /* */ + static void + Ins_SFVTPV( INS_ARG ) + { + DO_SFVTPV + } + + + /*************************************************************************/ + /* */ + /* SPVFS[]: Set PVector From Stack */ + /* Opcode range: 0x0A */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SPVFS( INS_ARG ) + { + DO_SPVFS + } + + + /*************************************************************************/ + /* */ + /* SFVFS[]: Set FVector From Stack */ + /* Opcode range: 0x0B */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SFVFS( INS_ARG ) + { + DO_SFVFS + } + + + /*************************************************************************/ + /* */ + /* GPV[]: Get Projection Vector */ + /* Opcode range: 0x0C */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GPV( INS_ARG ) + { + DO_GPV + } + + + /*************************************************************************/ + /* GFV[]: Get Freedom Vector */ + /* Opcode range: 0x0D */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GFV( INS_ARG ) + { + DO_GFV + } + + + /*************************************************************************/ + /* */ + /* SRP0[]: Set Reference Point 0 */ + /* Opcode range: 0x10 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP0( INS_ARG ) + { + DO_SRP0 + } + + + /*************************************************************************/ + /* */ + /* SRP1[]: Set Reference Point 1 */ + /* Opcode range: 0x11 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP1( INS_ARG ) + { + DO_SRP1 + } + + + /*************************************************************************/ + /* */ + /* SRP2[]: Set Reference Point 2 */ + /* Opcode range: 0x12 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP2( INS_ARG ) + { + DO_SRP2 + } + + + /*************************************************************************/ + /* */ + /* RTHG[]: Round To Half Grid */ + /* Opcode range: 0x19 */ + /* Stack: --> */ + /* */ + static void + Ins_RTHG( INS_ARG ) + { + DO_RTHG + } + + + /*************************************************************************/ + /* */ + /* RTG[]: Round To Grid */ + /* Opcode range: 0x18 */ + /* Stack: --> */ + /* */ + static void + Ins_RTG( INS_ARG ) + { + DO_RTG + } + + + /*************************************************************************/ + /* RTDG[]: Round To Double Grid */ + /* Opcode range: 0x3D */ + /* Stack: --> */ + /* */ + static void + Ins_RTDG( INS_ARG ) + { + DO_RTDG + } + + + /*************************************************************************/ + /* RUTG[]: Round Up To Grid */ + /* Opcode range: 0x7C */ + /* Stack: --> */ + /* */ + static void + Ins_RUTG( INS_ARG ) + { + DO_RUTG + } + + + /*************************************************************************/ + /* */ + /* RDTG[]: Round Down To Grid */ + /* Opcode range: 0x7D */ + /* Stack: --> */ + /* */ + static void + Ins_RDTG( INS_ARG ) + { + DO_RDTG + } + + + /*************************************************************************/ + /* */ + /* ROFF[]: Round OFF */ + /* Opcode range: 0x7A */ + /* Stack: --> */ + /* */ + static void + Ins_ROFF( INS_ARG ) + { + DO_ROFF + } + + + /*************************************************************************/ + /* */ + /* SROUND[]: Super ROUND */ + /* Opcode range: 0x76 */ + /* Stack: Eint8 --> */ + /* */ + static void + Ins_SROUND( INS_ARG ) + { + DO_SROUND + } + + + /*************************************************************************/ + /* */ + /* S45ROUND[]: Super ROUND 45 degrees */ + /* Opcode range: 0x77 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_S45ROUND( INS_ARG ) + { + DO_S45ROUND + } + + + /*************************************************************************/ + /* */ + /* SLOOP[]: Set LOOP variable */ + /* Opcode range: 0x17 */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SLOOP( INS_ARG ) + { + DO_SLOOP + } + + + /*************************************************************************/ + /* */ + /* SMD[]: Set Minimum Distance */ + /* Opcode range: 0x1A */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SMD( INS_ARG ) + { + DO_SMD + } + + + /*************************************************************************/ + /* */ + /* SCVTCI[]: Set Control Value Table Cut In */ + /* Opcode range: 0x1D */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SCVTCI( INS_ARG ) + { + DO_SCVTCI + } + + + /*************************************************************************/ + /* */ + /* SSWCI[]: Set Single Width Cut In */ + /* Opcode range: 0x1E */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SSWCI( INS_ARG ) + { + DO_SSWCI + } + + + /*************************************************************************/ + /* */ + /* SSW[]: Set Single Width */ + /* Opcode range: 0x1F */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SSW( INS_ARG ) + { + DO_SSW + } + + + /*************************************************************************/ + /* */ + /* FLIPON[]: Set auto-FLIP to ON */ + /* Opcode range: 0x4D */ + /* Stack: --> */ + /* */ + static void + Ins_FLIPON( INS_ARG ) + { + DO_FLIPON + } + + + /*************************************************************************/ + /* */ + /* FLIPOFF[]: Set auto-FLIP to OFF */ + /* Opcode range: 0x4E */ + /* Stack: --> */ + /* */ + static void + Ins_FLIPOFF( INS_ARG ) + { + DO_FLIPOFF + } + + + /*************************************************************************/ + /* */ + /* SANGW[]: Set ANGle Weight */ + /* Opcode range: 0x7E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SANGW( INS_ARG ) + { + /* instruction not supported anymore */ + } + + + /*************************************************************************/ + /* */ + /* SDB[]: Set Delta Base */ + /* Opcode range: 0x5E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDB( INS_ARG ) + { + DO_SDB + } + + + /*************************************************************************/ + /* */ + /* SDS[]: Set Delta Shift */ + /* Opcode range: 0x5F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDS( INS_ARG ) + { + DO_SDS + } + + + /*************************************************************************/ + /* */ + /* MPPEM[]: Measure Pixel Per EM */ + /* Opcode range: 0x4B */ + /* Stack: --> Euint16 */ + /* */ + static void + Ins_MPPEM( INS_ARG ) + { + DO_MPPEM + } + + + /*************************************************************************/ + /* */ + /* MPS[]: Measure Point Size */ + /* Opcode range: 0x4C */ + /* Stack: --> Euint16 */ + /* */ + static void + Ins_MPS( INS_ARG ) + { + DO_MPS + } + + + /*************************************************************************/ + /* */ + /* DUP[]: DUPlicate the top stack's element */ + /* Opcode range: 0x20 */ + /* Stack: StkElt --> StkElt StkElt */ + /* */ + static void + Ins_DUP( INS_ARG ) + { + DO_DUP + } + + + /*************************************************************************/ + /* */ + /* POP[]: POP the stack's top element */ + /* Opcode range: 0x21 */ + /* Stack: StkElt --> */ + /* */ + static void + Ins_POP( INS_ARG ) + { + /* nothing to do */ + } + + + /*************************************************************************/ + /* */ + /* CLEAR[]: CLEAR the entire stack */ + /* Opcode range: 0x22 */ + /* Stack: StkElt... --> */ + /* */ + static void + Ins_CLEAR( INS_ARG ) + { + DO_CLEAR + } + + + /*************************************************************************/ + /* */ + /* SWAP[]: SWAP the stack's top two elements */ + /* Opcode range: 0x23 */ + /* Stack: 2 * StkElt --> 2 * StkElt */ + /* */ + static void + Ins_SWAP( INS_ARG ) + { + DO_SWAP + } + + + /*************************************************************************/ + /* */ + /* DEPTH[]: return the stack DEPTH */ + /* Opcode range: 0x24 */ + /* Stack: --> uint32 */ + /* */ + static void + Ins_DEPTH( INS_ARG ) + { + DO_DEPTH + } + + + /*************************************************************************/ + /* */ + /* CINDEX[]: Copy INDEXed element */ + /* Opcode range: 0x25 */ + /* Stack: int32 --> StkElt */ + /* */ + static void + Ins_CINDEX( INS_ARG ) + { + DO_CINDEX + } + + + /*************************************************************************/ + /* */ + /* EIF[]: End IF */ + /* Opcode range: 0x59 */ + /* Stack: --> */ + /* */ + static void + Ins_EIF( INS_ARG ) + { + /* nothing to do */ + } + + + /*************************************************************************/ + /* */ + /* JROT[]: Jump Relative On True */ + /* Opcode range: 0x78 */ + /* Stack: StkElt int32 --> */ + /* */ + static void + Ins_JROT( INS_ARG ) + { + DO_JROT + } + + + /*************************************************************************/ + /* */ + /* JMPR[]: JuMP Relative */ + /* Opcode range: 0x1C */ + /* Stack: int32 --> */ + /* */ + static void + Ins_JMPR( INS_ARG ) + { + DO_JMPR + } + + + /*************************************************************************/ + /* */ + /* JROF[]: Jump Relative On False */ + /* Opcode range: 0x79 */ + /* Stack: StkElt int32 --> */ + /* */ + static void + Ins_JROF( INS_ARG ) + { + DO_JROF + } + + + /*************************************************************************/ + /* */ + /* LT[]: Less Than */ + /* Opcode range: 0x50 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_LT( INS_ARG ) + { + DO_LT + } + + + /*************************************************************************/ + /* */ + /* LTEQ[]: Less Than or EQual */ + /* Opcode range: 0x51 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_LTEQ( INS_ARG ) + { + DO_LTEQ + } + + + /*************************************************************************/ + /* */ + /* GT[]: Greater Than */ + /* Opcode range: 0x52 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_GT( INS_ARG ) + { + DO_GT + } + + + /*************************************************************************/ + /* */ + /* GTEQ[]: Greater Than or EQual */ + /* Opcode range: 0x53 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_GTEQ( INS_ARG ) + { + DO_GTEQ + } + + + /*************************************************************************/ + /* */ + /* EQ[]: EQual */ + /* Opcode range: 0x54 */ + /* Stack: StkElt StkElt --> bool */ + /* */ + static void + Ins_EQ( INS_ARG ) + { + DO_EQ + } + + + /*************************************************************************/ + /* */ + /* NEQ[]: Not EQual */ + /* Opcode range: 0x55 */ + /* Stack: StkElt StkElt --> bool */ + /* */ + static void + Ins_NEQ( INS_ARG ) + { + DO_NEQ + } + + + /*************************************************************************/ + /* */ + /* ODD[]: Is ODD */ + /* Opcode range: 0x56 */ + /* Stack: f26.6 --> bool */ + /* */ + static void + Ins_ODD( INS_ARG ) + { + DO_ODD + } + + + /*************************************************************************/ + /* */ + /* EVEN[]: Is EVEN */ + /* Opcode range: 0x57 */ + /* Stack: f26.6 --> bool */ + /* */ + static void + Ins_EVEN( INS_ARG ) + { + DO_EVEN + } + + + /*************************************************************************/ + /* */ + /* AND[]: logical AND */ + /* Opcode range: 0x5A */ + /* Stack: uint32 uint32 --> uint32 */ + /* */ + static void + Ins_AND( INS_ARG ) + { + DO_AND + } + + + /*************************************************************************/ + /* */ + /* OR[]: logical OR */ + /* Opcode range: 0x5B */ + /* Stack: uint32 uint32 --> uint32 */ + /* */ + static void + Ins_OR( INS_ARG ) + { + DO_OR + } + + + /*************************************************************************/ + /* */ + /* NOT[]: logical NOT */ + /* Opcode range: 0x5C */ + /* Stack: StkElt --> uint32 */ + /* */ + static void + Ins_NOT( INS_ARG ) + { + DO_NOT + } + + + /*************************************************************************/ + /* */ + /* ADD[]: ADD */ + /* Opcode range: 0x60 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_ADD( INS_ARG ) + { + DO_ADD + } + + + /*************************************************************************/ + /* */ + /* SUB[]: SUBtract */ + /* Opcode range: 0x61 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_SUB( INS_ARG ) + { + DO_SUB + } + + + /*************************************************************************/ + /* */ + /* DIV[]: DIVide */ + /* Opcode range: 0x62 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_DIV( INS_ARG ) + { + DO_DIV + } + + + /*************************************************************************/ + /* */ + /* MUL[]: MULtiply */ + /* Opcode range: 0x63 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_MUL( INS_ARG ) + { + DO_MUL + } + + + /*************************************************************************/ + /* */ + /* ABS[]: ABSolute value */ + /* Opcode range: 0x64 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_ABS( INS_ARG ) + { + DO_ABS + } + + + /*************************************************************************/ + /* */ + /* NEG[]: NEGate */ + /* Opcode range: 0x65 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_NEG( INS_ARG ) + { + DO_NEG + } + + + /*************************************************************************/ + /* */ + /* FLOOR[]: FLOOR */ + /* Opcode range: 0x66 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_FLOOR( INS_ARG ) + { + DO_FLOOR + } + + + /*************************************************************************/ + /* */ + /* CEILING[]: CEILING */ + /* Opcode range: 0x67 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_CEILING( INS_ARG ) + { + DO_CEILING + } + + + /*************************************************************************/ + /* */ + /* RS[]: Read Store */ + /* Opcode range: 0x43 */ + /* Stack: uint32 --> uint32 */ + /* */ + static void + Ins_RS( INS_ARG ) + { + DO_RS + } + + + /*************************************************************************/ + /* */ + /* WS[]: Write Store */ + /* Opcode range: 0x42 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_WS( INS_ARG ) + { + DO_WS + } + + + /*************************************************************************/ + /* */ + /* WCVTP[]: Write CVT in Pixel units */ + /* Opcode range: 0x44 */ + /* Stack: f26.6 uint32 --> */ + /* */ + static void + Ins_WCVTP( INS_ARG ) + { + DO_WCVTP + } + + + /*************************************************************************/ + /* */ + /* WCVTF[]: Write CVT in Funits */ + /* Opcode range: 0x70 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_WCVTF( INS_ARG ) + { + DO_WCVTF + } + + + /*************************************************************************/ + /* */ + /* RCVT[]: Read CVT */ + /* Opcode range: 0x45 */ + /* Stack: uint32 --> f26.6 */ + /* */ + static void + Ins_RCVT( INS_ARG ) + { + DO_RCVT + } + + + /*************************************************************************/ + /* */ + /* AA[]: Adjust Angle */ + /* Opcode range: 0x7F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_AA( INS_ARG ) + { + /* intentionally no longer supported */ + } + + + /*************************************************************************/ + /* */ + /* DEBUG[]: DEBUG. Unsupported. */ + /* Opcode range: 0x4F */ + /* Stack: uint32 --> */ + /* */ + /* Note: The original instruction pops a value from the stack. */ + /* */ + static void + Ins_DEBUG( INS_ARG ) + { + DO_DEBUG + } + + + /*************************************************************************/ + /* */ + /* ROUND[ab]: ROUND value */ + /* Opcode range: 0x68-0x6B */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_ROUND( INS_ARG ) + { + DO_ROUND + } + + + /*************************************************************************/ + /* */ + /* NROUND[ab]: No ROUNDing of value */ + /* Opcode range: 0x6C-0x6F */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_NROUND( INS_ARG ) + { + DO_NROUND + } + + + /*************************************************************************/ + /* */ + /* MAX[]: MAXimum */ + /* Opcode range: 0x68 */ + /* Stack: int32? int32? --> int32 */ + /* */ + static void + Ins_MAX( INS_ARG ) + { + DO_MAX + } + + + /*************************************************************************/ + /* */ + /* MIN[]: MINimum */ + /* Opcode range: 0x69 */ + /* Stack: int32? int32? --> int32 */ + /* */ + static void + Ins_MIN( INS_ARG ) + { + DO_MIN + } + + +#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + + /*************************************************************************/ + /* */ + /* The following functions are called as is within the switch statement. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* MINDEX[]: Move INDEXed element */ + /* Opcode range: 0x26 */ + /* Stack: int32? --> StkElt */ + /* */ + static void + Ins_MINDEX( INS_ARG ) + { + FT_Long L, K; + + + L = args[0]; + + if ( L <= 0 || L > CUR.args ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + } + else + { + K = CUR.stack[CUR.args - L]; + + FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], + &CUR.stack[CUR.args - L + 1], + ( L - 1 ) ); + + CUR.stack[CUR.args - 1] = K; + } + } + + + /*************************************************************************/ + /* */ + /* ROLL[]: ROLL top three elements */ + /* Opcode range: 0x8A */ + /* Stack: 3 * StkElt --> 3 * StkElt */ + /* */ + static void + Ins_ROLL( INS_ARG ) + { + FT_Long A, B, C; + + FT_UNUSED_EXEC; + + + A = args[2]; + B = args[1]; + C = args[0]; + + args[2] = C; + args[1] = A; + args[0] = B; + } + + + /*************************************************************************/ + /* */ + /* MANAGING THE FLOW OF CONTROL */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + static FT_Bool + SkipCode( EXEC_OP ) + { + CUR.IP += CUR.length; + + if ( CUR.IP < CUR.codeSize ) + { + CUR.opcode = CUR.code[CUR.IP]; + + CUR.length = opcode_length[CUR.opcode]; + if ( CUR.length < 0 ) + { + if ( CUR.IP + 1 >= CUR.codeSize ) + goto Fail_Overflow; + CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; + } + + if ( CUR.IP + CUR.length <= CUR.codeSize ) + return SUCCESS; + } + + Fail_Overflow: + CUR.error = FT_THROW( Code_Overflow ); + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* IF[]: IF test */ + /* Opcode range: 0x58 */ + /* Stack: StkElt --> */ + /* */ + static void + Ins_IF( INS_ARG ) + { + FT_Int nIfs; + FT_Bool Out; + + + if ( args[0] != 0 ) + return; + + nIfs = 1; + Out = 0; + + do + { + if ( SKIP_Code() == FAILURE ) + return; + + switch ( CUR.opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + + case 0x1B: /* ELSE */ + Out = FT_BOOL( nIfs == 1 ); + break; + + case 0x59: /* EIF */ + nIfs--; + Out = FT_BOOL( nIfs == 0 ); + break; + } + } while ( Out == 0 ); + } + + + /*************************************************************************/ + /* */ + /* ELSE[]: ELSE */ + /* Opcode range: 0x1B */ + /* Stack: --> */ + /* */ + static void + Ins_ELSE( INS_ARG ) + { + FT_Int nIfs; + + FT_UNUSED_ARG; + + + nIfs = 1; + + do + { + if ( SKIP_Code() == FAILURE ) + return; + + switch ( CUR.opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + + case 0x59: /* EIF */ + nIfs--; + break; + } + } while ( nIfs != 0 ); + } + + + /*************************************************************************/ + /* */ + /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* FDEF[]: Function DEFinition */ + /* Opcode range: 0x2C */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_FDEF( INS_ARG ) + { + FT_ULong n; + TT_DefRecord* rec; + TT_DefRecord* limit; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* arguments to opcodes are skipped by `SKIP_Code' */ + FT_Byte opcode_pattern[9][12] = { + /* #0 inline delta function 1 */ + { + 0x4B, /* PPEM */ + 0x53, /* GTEQ */ + 0x23, /* SWAP */ + 0x4B, /* PPEM */ + 0x51, /* LTEQ */ + 0x5A, /* AND */ + 0x58, /* IF */ + 0x38, /* SHPIX */ + 0x1B, /* ELSE */ + 0x21, /* POP */ + 0x21, /* POP */ + 0x59 /* EIF */ + }, + /* #1 inline delta function 2 */ + { + 0x4B, /* PPEM */ + 0x54, /* EQ */ + 0x58, /* IF */ + 0x38, /* SHPIX */ + 0x1B, /* ELSE */ + 0x21, /* POP */ + 0x21, /* POP */ + 0x59 /* EIF */ + }, + /* #2 diagonal stroke function */ + { + 0x20, /* DUP */ + 0x20, /* DUP */ + 0xB0, /* PUSHB_1 */ + /* 1 */ + 0x60, /* ADD */ + 0x46, /* GC_cur */ + 0xB0, /* PUSHB_1 */ + /* 64 */ + 0x23, /* SWAP */ + 0x42 /* WS */ + }, + /* #3 VacuFormRound function */ + { + 0x45, /* RCVT */ + 0x23, /* SWAP */ + 0x46, /* GC_cur */ + 0x60, /* ADD */ + 0x20, /* DUP */ + 0xB0 /* PUSHB_1 */ + /* 38 */ + }, + /* #4 TTFautohint bytecode (old) */ + { + 0x20, /* DUP */ + 0x64, /* ABS */ + 0xB0, /* PUSHB_1 */ + /* 32 */ + 0x60, /* ADD */ + 0x66, /* FLOOR */ + 0x23, /* SWAP */ + 0xB0 /* PUSHB_1 */ + }, + /* #5 spacing function 1 */ + { + 0x01, /* SVTCA_x */ + 0xB0, /* PUSHB_1 */ + /* 24 */ + 0x43, /* RS */ + 0x58 /* IF */ + }, + /* #6 spacing function 2 */ + { + 0x01, /* SVTCA_x */ + 0x18, /* RTG */ + 0xB0, /* PUSHB_1 */ + /* 24 */ + 0x43, /* RS */ + 0x58 /* IF */ + }, + /* #7 TypeMan Talk DiagEndCtrl function */ + { + 0x01, /* SVTCA_x */ + 0x20, /* DUP */ + 0xB0, /* PUSHB_1 */ + /* 3 */ + 0x25, /* CINDEX */ + }, + /* #8 TypeMan Talk Align */ + { + 0x06, /* SPVTL */ + 0x7D, /* RDTG */ + }, + }; + FT_UShort opcode_patterns = 9; + FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; + FT_UShort i; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + + /* some font programs are broken enough to redefine functions! */ + /* We will then parse the current table. */ + + rec = CUR.FDefs; + limit = rec + CUR.numFDefs; + n = args[0]; + + for ( ; rec < limit; rec++ ) + { + if ( rec->opc == n ) + break; + } + + if ( rec == limit ) + { + /* check that there is enough room for new functions */ + if ( CUR.numFDefs >= CUR.maxFDefs ) + { + CUR.error = FT_THROW( Too_Many_Function_Defs ); + return; + } + CUR.numFDefs++; + } + + /* Although FDEF takes unsigned 32-bit integer, */ + /* func # must be within unsigned 16-bit integer */ + if ( n > 0xFFFFU ) + { + CUR.error = FT_THROW( Too_Many_Function_Defs ); + return; + } + + rec->range = CUR.curRange; + rec->opc = (FT_UInt16)n; + rec->start = CUR.IP + 1; + rec->active = TRUE; + rec->inline_delta = FALSE; + rec->sph_fdef_flags = 0x0000; + + if ( n > CUR.maxFunc ) + CUR.maxFunc = (FT_UInt16)n; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* We don't know for sure these are typeman functions, */ + /* however they are only active when RS 22 is called */ + if ( n >= 64 && n <= 66 ) + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES; +#endif + + /* Now skip the whole function definition. */ + /* We don't allow nested IDEFS & FDEFs. */ + + while ( SKIP_Code() == SUCCESS ) + { + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + if ( SUBPIXEL_HINTING ) + { + for ( i = 0; i < opcode_patterns; i++ ) + { + if ( opcode_pointer[i] < opcode_size[i] && + CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) + { + opcode_pointer[i] += 1; + + if ( opcode_pointer[i] == opcode_size[i] ) + { + FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n", + i, n, + CUR.face->root.family_name, + CUR.face->root.style_name )); + + switch ( i ) + { + case 0: + rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; + CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; + break; + + case 1: + rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; + CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; + break; + + case 2: + switch ( n ) + { + /* needs to be implemented still */ + case 58: + rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; + CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; + } + break; + + case 3: + switch ( n ) + { + case 0: + rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; + CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; + } + break; + + case 4: + /* probably not necessary to detect anymore */ + rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; + CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; + break; + + case 5: + switch ( n ) + { + case 0: + case 1: + case 2: + case 4: + case 7: + case 8: + rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; + CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1; + } + break; + + case 6: + switch ( n ) + { + case 0: + case 1: + case 2: + case 4: + case 7: + case 8: + rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; + CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2; + } + break; + + case 7: + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + break; + + case 8: +#if 0 + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; +#endif + break; + } + opcode_pointer[i] = 0; + } + } + + else + opcode_pointer[i] = 0; + } + + /* Set sph_compatibility_mode only when deltas are detected */ + CUR.face->sph_compatibility_mode = + ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | + ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); + } + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + switch ( CUR.opcode ) + { + case 0x89: /* IDEF */ + case 0x2C: /* FDEF */ + CUR.error = FT_THROW( Nested_DEFS ); + return; + + case 0x2D: /* ENDF */ + rec->end = CUR.IP; + return; + } + } + } + + + /*************************************************************************/ + /* */ + /* ENDF[]: END Function definition */ + /* Opcode range: 0x2D */ + /* Stack: --> */ + /* */ + static void + Ins_ENDF( INS_ARG ) + { + TT_CallRec* pRec; + + FT_UNUSED_ARG; + + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + CUR.sph_in_func_flags = 0x0000; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ + { + CUR.error = FT_THROW( ENDF_In_Exec_Stream ); + return; + } + + CUR.callTop--; + + pRec = &CUR.callStack[CUR.callTop]; + + pRec->Cur_Count--; + + CUR.step_ins = FALSE; + + if ( pRec->Cur_Count > 0 ) + { + CUR.callTop++; + CUR.IP = pRec->Cur_Restart; + } + else + /* Loop through the current function */ + INS_Goto_CodeRange( pRec->Caller_Range, + pRec->Caller_IP ); + + /* Exit the current call frame. */ + + /* NOTE: If the last instruction of a program is a */ + /* CALL or LOOPCALL, the return address is */ + /* always out of the code range. This is a */ + /* valid address, and it is why we do not test */ + /* the result of Ins_Goto_CodeRange() here! */ + } + + + /*************************************************************************/ + /* */ + /* CALL[]: CALL function */ + /* Opcode range: 0x2B */ + /* Stack: uint32? --> */ + /* */ + static void + Ins_CALL( INS_ARG ) + { + FT_ULong F; + TT_CallRec* pCrec; + TT_DefRecord* def; + + + /* first of all, check the index */ + + F = args[0]; + if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) + goto Fail; + + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font are defined in increasing order, starting from 0. This */ + /* means that we normally have */ + /* */ + /* CUR.maxFunc+1 == CUR.numFDefs */ + /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ + /* */ + /* If this isn't true, we need to look up the function table. */ + + def = CUR.FDefs + F; + if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + { + /* look up the FDefs table */ + TT_DefRecord* limit; + + + def = CUR.FDefs; + limit = def + CUR.numFDefs; + + while ( def < limit && def->opc != F ) + def++; + + if ( def == limit ) + goto Fail; + } + + /* check that the function is active */ + if ( !def->active ) + goto Fail; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + ( ( CUR.iup_called && + ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || + ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) + goto Fail; + else + CUR.sph_in_func_flags = def->sph_fdef_flags; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + /* check the call stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = FT_THROW( Stack_Overflow ); + return; + } + + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = 1; + pCrec->Cur_Restart = def->start; + pCrec->Cur_End = def->end; + + CUR.callTop++; + + INS_Goto_CodeRange( def->range, + def->start ); + + CUR.step_ins = FALSE; + + return; + + Fail: + CUR.error = FT_THROW( Invalid_Reference ); + } + + + /*************************************************************************/ + /* */ + /* LOOPCALL[]: LOOP and CALL function */ + /* Opcode range: 0x2A */ + /* Stack: uint32? Eint16? --> */ + /* */ + static void + Ins_LOOPCALL( INS_ARG ) + { + FT_ULong F; + TT_CallRec* pCrec; + TT_DefRecord* def; + + + /* first of all, check the index */ + F = args[1]; + if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) + goto Fail; + + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font are defined in increasing order, starting from 0. This */ + /* means that we normally have */ + /* */ + /* CUR.maxFunc+1 == CUR.numFDefs */ + /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ + /* */ + /* If this isn't true, we need to look up the function table. */ + + def = CUR.FDefs + F; + if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + { + /* look up the FDefs table */ + TT_DefRecord* limit; + + + def = CUR.FDefs; + limit = def + CUR.numFDefs; + + while ( def < limit && def->opc != F ) + def++; + + if ( def == limit ) + goto Fail; + } + + /* check that the function is active */ + if ( !def->active ) + goto Fail; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) + goto Fail; + else + CUR.sph_in_func_flags = def->sph_fdef_flags; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + /* check stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = FT_THROW( Stack_Overflow ); + return; + } + + if ( args[0] > 0 ) + { + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = (FT_Int)args[0]; + pCrec->Cur_Restart = def->start; + pCrec->Cur_End = def->end; + + CUR.callTop++; + + INS_Goto_CodeRange( def->range, def->start ); + + CUR.step_ins = FALSE; + } + + return; + + Fail: + CUR.error = FT_THROW( Invalid_Reference ); + } + + + /*************************************************************************/ + /* */ + /* IDEF[]: Instruction DEFinition */ + /* Opcode range: 0x89 */ + /* Stack: Eint8 --> */ + /* */ + static void + Ins_IDEF( INS_ARG ) + { + TT_DefRecord* def; + TT_DefRecord* limit; + + + /* First of all, look for the same function in our table */ + + def = CUR.IDefs; + limit = def + CUR.numIDefs; + + for ( ; def < limit; def++ ) + if ( def->opc == (FT_ULong)args[0] ) + break; + + if ( def == limit ) + { + /* check that there is enough room for a new instruction */ + if ( CUR.numIDefs >= CUR.maxIDefs ) + { + CUR.error = FT_THROW( Too_Many_Instruction_Defs ); + return; + } + CUR.numIDefs++; + } + + /* opcode must be unsigned 8-bit integer */ + if ( 0 > args[0] || args[0] > 0x00FF ) + { + CUR.error = FT_THROW( Too_Many_Instruction_Defs ); + return; + } + + def->opc = (FT_Byte)args[0]; + def->start = CUR.IP + 1; + def->range = CUR.curRange; + def->active = TRUE; + + if ( (FT_ULong)args[0] > CUR.maxIns ) + CUR.maxIns = (FT_Byte)args[0]; + + /* Now skip the whole function definition. */ + /* We don't allow nested IDEFs & FDEFs. */ + + while ( SKIP_Code() == SUCCESS ) + { + switch ( CUR.opcode ) + { + case 0x89: /* IDEF */ + case 0x2C: /* FDEF */ + CUR.error = FT_THROW( Nested_DEFS ); + return; + case 0x2D: /* ENDF */ + return; + } + } + } + + + /*************************************************************************/ + /* */ + /* PUSHING DATA ONTO THE INTERPRETER STACK */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* NPUSHB[]: PUSH N Bytes */ + /* Opcode range: 0x40 */ + /* Stack: --> uint32... */ + /* */ + static void + Ins_NPUSHB( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_UShort)CUR.code[CUR.IP + 1]; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = FT_THROW( Stack_Overflow ); + return; + } + + for ( K = 1; K <= L; K++ ) + args[K - 1] = CUR.code[CUR.IP + K + 1]; + + CUR.new_top += L; + } + + + /*************************************************************************/ + /* */ + /* NPUSHW[]: PUSH N Words */ + /* Opcode range: 0x41 */ + /* Stack: --> int32... */ + /* */ + static void + Ins_NPUSHW( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_UShort)CUR.code[CUR.IP + 1]; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = FT_THROW( Stack_Overflow ); + return; + } + + CUR.IP += 2; + + for ( K = 0; K < L; K++ ) + args[K] = GET_ShortIns(); + + CUR.step_ins = FALSE; + CUR.new_top += L; + } + + + /*************************************************************************/ + /* */ + /* PUSHB[abc]: PUSH Bytes */ + /* Opcode range: 0xB0-0xB7 */ + /* Stack: --> uint32... */ + /* */ + static void + Ins_PUSHB( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_UShort)( CUR.opcode - 0xB0 + 1 ); + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = FT_THROW( Stack_Overflow ); + return; + } + + for ( K = 1; K <= L; K++ ) + args[K - 1] = CUR.code[CUR.IP + K]; + } + + + /*************************************************************************/ + /* */ + /* PUSHW[abc]: PUSH Words */ + /* Opcode range: 0xB8-0xBF */ + /* Stack: --> int32... */ + /* */ + static void + Ins_PUSHW( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_UShort)( CUR.opcode - 0xB8 + 1 ); + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = FT_THROW( Stack_Overflow ); + return; + } + + CUR.IP++; + + for ( K = 0; K < L; K++ ) + args[K] = GET_ShortIns(); + + CUR.step_ins = FALSE; + } + + + /*************************************************************************/ + /* */ + /* MANAGING THE GRAPHICS STATE */ + /* */ + /* Instructions appear in the specs' order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* GC[a]: Get Coordinate projected onto */ + /* Opcode range: 0x46-0x47 */ + /* Stack: uint32 --> f26.6 */ + /* */ + /* XXX: UNDOCUMENTED: Measures from the original glyph must be taken */ + /* along the dual projection vector! */ + /* */ + static void + Ins_GC( INS_ARG ) + { + FT_ULong L; + FT_F26Dot6 R; + + + L = (FT_ULong)args[0]; + + if ( BOUNDSL( L, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + R = 0; + } + else + { + if ( CUR.opcode & 1 ) + R = CUR_fast_dualproj( &CUR.zp2.org[L] ); + else + R = CUR_fast_project( &CUR.zp2.cur[L] ); + } + + args[0] = R; + } + + + /*************************************************************************/ + /* */ + /* SCFS[]: Set Coordinate From Stack */ + /* Opcode range: 0x48 */ + /* Stack: f26.6 uint32 --> */ + /* */ + /* Formula: */ + /* */ + /* OA := OA + ( value - OA.p )/( f.p ) * f */ + /* */ + static void + Ins_SCFS( INS_ARG ) + { + FT_Long K; + FT_UShort L; + + + L = (FT_UShort)args[0]; + + if ( BOUNDS( L, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + K = CUR_fast_project( &CUR.zp2.cur[L] ); + + CUR_Func_move( &CUR.zp2, L, args[1] - K ); + + /* UNDOCUMENTED! The MS rasterizer does that with */ + /* twilight points (confirmed by Greg Hitchcock) */ + if ( CUR.GS.gep2 == 0 ) + CUR.zp2.org[L] = CUR.zp2.cur[L]; + } + + + /*************************************************************************/ + /* */ + /* MD[a]: Measure Distance */ + /* Opcode range: 0x49-0x4A */ + /* Stack: uint32 uint32 --> f26.6 */ + /* */ + /* XXX: UNDOCUMENTED: Measure taken in the original glyph must be along */ + /* the dual projection vector. */ + /* */ + /* XXX: UNDOCUMENTED: Flag attributes are inverted! */ + /* 0 => measure distance in original outline */ + /* 1 => measure distance in grid-fitted outline */ + /* */ + /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */ + /* */ + static void + Ins_MD( INS_ARG ) + { + FT_UShort K, L; + FT_F26Dot6 D; + + + K = (FT_UShort)args[1]; + L = (FT_UShort)args[0]; + + if ( BOUNDS( L, CUR.zp0.n_points ) || + BOUNDS( K, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + D = 0; + } + else + { + if ( CUR.opcode & 1 ) + D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); + else + { + /* XXX: UNDOCUMENTED: twilight zone special case */ + + if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + { + FT_Vector* vec1 = CUR.zp0.org + L; + FT_Vector* vec2 = CUR.zp1.org + K; + + + D = CUR_Func_dualproj( vec1, vec2 ); + } + else + { + FT_Vector* vec1 = CUR.zp0.orus + L; + FT_Vector* vec2 = CUR.zp1.orus + K; + + + if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + { + /* this should be faster */ + D = CUR_Func_dualproj( vec1, vec2 ); + D = FT_MulFix( D, CUR.metrics.x_scale ); + } + else + { + FT_Vector vec; + + + vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); + vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); + + D = CUR_fast_dualproj( &vec ); + } + } + } + } + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && FT_ABS( D ) == 64 ) + D += 1; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + args[0] = D; + } + + + /*************************************************************************/ + /* */ + /* SDPVTL[a]: Set Dual PVector to Line */ + /* Opcode range: 0x86-0x87 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SDPVTL( INS_ARG ) + { + FT_Long A, B, C; + FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ + FT_Int aOpc = CUR.opcode; + + + p1 = (FT_UShort)args[1]; + p2 = (FT_UShort)args[0]; + + if ( BOUNDS( p2, CUR.zp1.n_points ) || + BOUNDS( p1, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + { + FT_Vector* v1 = CUR.zp1.org + p2; + FT_Vector* v2 = CUR.zp2.org + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + + /* If v1 == v2, SDPVTL behaves the same as */ + /* SVTCA[X], respectively. */ + /* */ + /* Confirmed by Greg Hitchcock. */ + + if ( A == 0 && B == 0 ) + { + A = 0x4000; + aOpc = 0; + } + } + + if ( ( aOpc & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.dualVector ); + + { + FT_Vector* v1 = CUR.zp1.cur + p2; + FT_Vector* v2 = CUR.zp2.cur + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + + if ( A == 0 && B == 0 ) + { + A = 0x4000; + aOpc = 0; + } + } + + if ( ( aOpc & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.projVector ); + + GUESS_VECTOR( freeVector ); + + COMPUTE_Funcs(); + } + + + /*************************************************************************/ + /* */ + /* SZP0[]: Set Zone Pointer 0 */ + /* Opcode range: 0x13 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP0( INS_ARG ) + { + switch ( (FT_Int)args[0] ) + { + case 0: + CUR.zp0 = CUR.twilight; + break; + + case 1: + CUR.zp0 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + CUR.GS.gep0 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZP1[]: Set Zone Pointer 1 */ + /* Opcode range: 0x14 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP1( INS_ARG ) + { + switch ( (FT_Int)args[0] ) + { + case 0: + CUR.zp1 = CUR.twilight; + break; + + case 1: + CUR.zp1 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + CUR.GS.gep1 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZP2[]: Set Zone Pointer 2 */ + /* Opcode range: 0x15 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP2( INS_ARG ) + { + switch ( (FT_Int)args[0] ) + { + case 0: + CUR.zp2 = CUR.twilight; + break; + + case 1: + CUR.zp2 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + CUR.GS.gep2 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZPS[]: Set Zone PointerS */ + /* Opcode range: 0x16 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZPS( INS_ARG ) + { + switch ( (FT_Int)args[0] ) + { + case 0: + CUR.zp0 = CUR.twilight; + break; + + case 1: + CUR.zp0 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + CUR.zp1 = CUR.zp0; + CUR.zp2 = CUR.zp0; + + CUR.GS.gep0 = (FT_UShort)args[0]; + CUR.GS.gep1 = (FT_UShort)args[0]; + CUR.GS.gep2 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* INSTCTRL[]: INSTruction ConTRoL */ + /* Opcode range: 0x8e */ + /* Stack: int32 int32 --> */ + /* */ + static void + Ins_INSTCTRL( INS_ARG ) + { + FT_Long K, L; + + + K = args[1]; + L = args[0]; + + if ( K < 1 || K > 2 ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + if ( L != 0 ) + L = K; + + CUR.GS.instruct_control = FT_BOOL( + ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); + } + + + /*************************************************************************/ + /* */ + /* SCANCTRL[]: SCAN ConTRoL */ + /* Opcode range: 0x85 */ + /* Stack: uint32? --> */ + /* */ + static void + Ins_SCANCTRL( INS_ARG ) + { + FT_Int A; + + + /* Get Threshold */ + A = (FT_Int)( args[0] & 0xFF ); + + if ( A == 0xFF ) + { + CUR.GS.scan_control = TRUE; + return; + } + else if ( A == 0 ) + { + CUR.GS.scan_control = FALSE; + return; + } + + if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A ) + CUR.GS.scan_control = TRUE; + + if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated ) + CUR.GS.scan_control = TRUE; + + if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched ) + CUR.GS.scan_control = TRUE; + + if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A ) + CUR.GS.scan_control = FALSE; + + if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated ) + CUR.GS.scan_control = FALSE; + + if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched ) + CUR.GS.scan_control = FALSE; + } + + + /*************************************************************************/ + /* */ + /* SCANTYPE[]: SCAN TYPE */ + /* Opcode range: 0x8D */ + /* Stack: uint32? --> */ + /* */ + static void + Ins_SCANTYPE( INS_ARG ) + { + if ( args[0] >= 0 ) + CUR.GS.scan_type = (FT_Int)args[0]; + } + + + /*************************************************************************/ + /* */ + /* MANAGING OUTLINES */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* FLIPPT[]: FLIP PoinT */ + /* Opcode range: 0x80 */ + /* Stack: uint32... --> */ + /* */ + static void + Ins_FLIPPT( INS_ARG ) + { + FT_UShort point; + + FT_UNUSED_ARG; + + + if ( CUR.top < CUR.GS.loop ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Too_Few_Arguments ); + goto Fail; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + } + else + CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; + + CUR.GS.loop--; + } + + Fail: + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* FLIPRGON[]: FLIP RanGe ON */ + /* Opcode range: 0x81 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_FLIPRGON( INS_ARG ) + { + FT_UShort I, K, L; + + + K = (FT_UShort)args[1]; + L = (FT_UShort)args[0]; + + if ( BOUNDS( K, CUR.pts.n_points ) || + BOUNDS( L, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + for ( I = L; I <= K; I++ ) + CUR.pts.tags[I] |= FT_CURVE_TAG_ON; + } + + + /*************************************************************************/ + /* */ + /* FLIPRGOFF: FLIP RanGe OFF */ + /* Opcode range: 0x82 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_FLIPRGOFF( INS_ARG ) + { + FT_UShort I, K, L; + + + K = (FT_UShort)args[1]; + L = (FT_UShort)args[0]; + + if ( BOUNDS( K, CUR.pts.n_points ) || + BOUNDS( L, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + for ( I = L; I <= K; I++ ) + CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; + } + + + static FT_Bool + Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, + FT_F26Dot6* y, + TT_GlyphZone zone, + FT_UShort* refp ) + { + TT_GlyphZoneRec zp; + FT_UShort p; + FT_F26Dot6 d; + + + if ( CUR.opcode & 1 ) + { + zp = CUR.zp0; + p = CUR.GS.rp1; + } + else + { + zp = CUR.zp1; + p = CUR.GS.rp2; + } + + if ( BOUNDS( p, zp.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + *refp = 0; + return FAILURE; + } + + *zone = zp; + *refp = p; + + d = CUR_Func_project( zp.cur + p, zp.org + p ); + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + *x = d; + *y = 0; + } + else + { + *x = 0; + *y = d; + } + } + else +#endif + { + *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P ); + *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P ); + } + + return SUCCESS; + } + + + static void + Move_Zp2_Point( EXEC_OP_ FT_UShort point, + FT_F26Dot6 dx, + FT_F26Dot6 dy, + FT_Bool touch ) + { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + CUR.zp2.cur[point].x += dx; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + else + { + CUR.zp2.cur[point].y += dy; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + return; + } +#endif + + if ( CUR.GS.freeVector.x != 0 ) + { + CUR.zp2.cur[point].x += dx; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + if ( CUR.GS.freeVector.y != 0 ) + { + CUR.zp2.cur[point].y += dy; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + } + + + /*************************************************************************/ + /* */ + /* SHP[a]: SHift Point by the last point */ + /* Opcode range: 0x32-0x33 */ + /* Stack: uint32... --> */ + /* */ + static void + Ins_SHP( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + + FT_F26Dot6 dx, + dy; + FT_UShort point; + + FT_UNUSED_ARG; + + + if ( CUR.top < CUR.GS.loop ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + point = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + } + else +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* doesn't follow Cleartype spec but produces better result */ + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode ) + MOVE_Zp2_Point( point, 0, dy, TRUE ); + else +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + CUR.GS.loop--; + } + + Fail: + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* SHC[a]: SHift Contour */ + /* Opcode range: 0x34-35 */ + /* Stack: uint32 --> */ + /* */ + /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */ + /* contour in the twilight zone, namely contour number */ + /* zero which includes all points of it. */ + /* */ + static void + Ins_SHC( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + FT_F26Dot6 dx, dy; + + FT_Short contour, bounds; + FT_UShort start, limit, i; + + + contour = (FT_UShort)args[0]; + bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours; + + if ( BOUNDS( contour, bounds ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + if ( contour == 0 ) + start = 0; + else + start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 - + CUR.zp2.first_point ); + + /* we use the number of points if in the twilight zone */ + if ( CUR.GS.gep2 == 0 ) + limit = CUR.zp2.n_points; + else + limit = (FT_UShort)( CUR.zp2.contours[contour] - + CUR.zp2.first_point + 1 ); + + for ( i = start; i < limit; i++ ) + { + if ( zp.cur != CUR.zp2.cur || refp != i ) + MOVE_Zp2_Point( i, dx, dy, TRUE ); + } + } + + + /*************************************************************************/ + /* */ + /* SHZ[a]: SHift Zone */ + /* Opcode range: 0x36-37 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SHZ( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + FT_F26Dot6 dx, + dy; + + FT_UShort limit, i; + + + if ( BOUNDS( args[0], 2 ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ + /* Twilight zone has no real contours, so use `n_points'. */ + /* Normal zone's `n_points' includes phantoms, so must */ + /* use end of last contour. */ + if ( CUR.GS.gep2 == 0 ) + limit = (FT_UShort)CUR.zp2.n_points; + else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) + limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 ); + else + limit = 0; + + /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ + for ( i = 0; i < limit; i++ ) + { + if ( zp.cur != CUR.zp2.cur || refp != i ) + MOVE_Zp2_Point( i, dx, dy, FALSE ); + } + } + + + /*************************************************************************/ + /* */ + /* SHPIX[]: SHift points by a PIXel amount */ + /* Opcode range: 0x38 */ + /* Stack: f26.6 uint32... --> */ + /* */ + static void + Ins_SHPIX( INS_ARG ) + { + FT_F26Dot6 dx, dy; + FT_UShort point; +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + FT_Int B1, B2; +#endif + + + if ( CUR.top < CUR.GS.loop + 1 ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + dx = (FT_UInt32)args[0]; + dy = 0; + } + else + { + dx = 0; + dy = (FT_UInt32)args[0]; + } + } + else +#endif + { + dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); + dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + } + else +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + { + /* If not using ignore_x_mode rendering, allow ZP2 move. */ + /* If inline deltas aren't allowed, skip ZP2 move. */ + /* If using ignore_x_mode rendering, allow ZP2 point move if: */ + /* - freedom vector is y and sph_compatibility_mode is off */ + /* - the glyph is composite and the move is in the Y direction */ + /* - the glyph is specifically set to allow SHPIX moves */ + /* - the move is on a previously Y-touched point */ + + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode ) + { + /* save point for later comparison */ + if ( CUR.GS.freeVector.y != 0 ) + B1 = CUR.zp2.cur[point].y; + else + B1 = CUR.zp2.cur[point].x; + + if ( !CUR.face->sph_compatibility_mode && + CUR.GS.freeVector.y != 0 ) + { + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + /* save new point */ + if ( CUR.GS.freeVector.y != 0 ) + { + B2 = CUR.zp2.cur[point].y; + + /* reverse any disallowed moves */ + if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && + ( B1 & 63 ) != 0 && + ( B2 & 63 ) != 0 && + B1 != B2 ) + MOVE_Zp2_Point( point, -dx, -dy, TRUE ); + } + } + else if ( CUR.face->sph_compatibility_mode ) + { + if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) + { + dx = FT_PIX_ROUND( B1 + dx ) - B1; + dy = FT_PIX_ROUND( B1 + dy ) - B1; + } + + /* skip post-iup deltas */ + if ( CUR.iup_called && + ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || + ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) + goto Skip; + + if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && + ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || + ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || + ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) + MOVE_Zp2_Point( point, 0, dy, TRUE ); + + /* save new point */ + if ( CUR.GS.freeVector.y != 0 ) + { + B2 = CUR.zp2.cur[point].y; + + /* reverse any disallowed moves */ + if ( ( B1 & 63 ) == 0 && + ( B2 & 63 ) != 0 && + B1 != B2 ) + MOVE_Zp2_Point( point, 0, -dy, TRUE ); + } + } + else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) + MOVE_Zp2_Point( point, dx, dy, TRUE ); + } + else + MOVE_Zp2_Point( point, dx, dy, TRUE ); + } + + Skip: + +#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + MOVE_Zp2_Point( point, dx, dy, TRUE ); + +#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + CUR.GS.loop--; + } + + Fail: + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* MSIRP[a]: Move Stack Indirect Relative Position */ + /* Opcode range: 0x3A-0x3B */ + /* Stack: f26.6 uint32 --> */ + /* */ + static void + Ins_MSIRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 distance; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */ + + + if ( SUBPIXEL_HINTING ) + { + control_value_cutin = CUR.GS.control_value_cutin; + + if ( CUR.ignore_x_mode && + CUR.GS.freeVector.x != 0 && + !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) + control_value_cutin = 0; + } + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + /* UNDOCUMENTED! The MS rasterizer does that with */ + /* twilight points (confirmed by Greg Hitchcock) */ + if ( CUR.GS.gep1 == 0 ) + { + CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; + CUR_Func_move_orig( &CUR.zp1, point, args[1] ); + CUR.zp1.cur[point] = CUR.zp1.org[point]; + } + + distance = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* subpixel hinting - make MSIRP respect CVT cut-in; */ + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.freeVector.x != 0 && + FT_ABS( distance - args[1] ) >= control_value_cutin ) + distance = args[1]; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + CUR_Func_move( &CUR.zp1, point, args[1] - distance ); + + CUR.GS.rp1 = CUR.GS.rp0; + CUR.GS.rp2 = point; + + if ( ( CUR.opcode & 1 ) != 0 ) + CUR.GS.rp0 = point; + } + + + /*************************************************************************/ + /* */ + /* MDAP[a]: Move Direct Absolute Point */ + /* Opcode range: 0x2E-0x2F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_MDAP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 cur_dist; + FT_F26Dot6 distance; + + + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + if ( ( CUR.opcode & 1 ) != 0 ) + { + cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.freeVector.x != 0 ) + distance = ROUND_None( + cur_dist, + CUR.tt_metrics.compensations[0] ) - cur_dist; + else +#endif + distance = CUR_Func_round( + cur_dist, + CUR.tt_metrics.compensations[0] ) - cur_dist; + } + else + distance = 0; + + CUR_Func_move( &CUR.zp0, point, distance ); + + CUR.GS.rp0 = point; + CUR.GS.rp1 = point; + } + + + /*************************************************************************/ + /* */ + /* MIAP[a]: Move Indirect Absolute Point */ + /* Opcode range: 0x3E-0x3F */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_MIAP( INS_ARG ) + { + FT_ULong cvtEntry; + FT_UShort point; + FT_F26Dot6 distance; + FT_F26Dot6 org_dist; + FT_F26Dot6 control_value_cutin; + + + control_value_cutin = CUR.GS.control_value_cutin; + cvtEntry = (FT_ULong)args[1]; + point = (FT_UShort)args[0]; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.freeVector.x != 0 && + CUR.GS.freeVector.y == 0 && + !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) + control_value_cutin = 0; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + if ( BOUNDS( point, CUR.zp0.n_points ) || + BOUNDSL( cvtEntry, CUR.cvtSize ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } + + /* UNDOCUMENTED! */ + /* */ + /* The behaviour of an MIAP instruction is quite different when used */ + /* in the twilight zone. */ + /* */ + /* First, no control value cut-in test is performed as it would fail */ + /* anyway. Second, the original point, i.e. (org_x,org_y) of */ + /* zp0.point, is set to the absolute, unrounded distance found in the */ + /* CVT. */ + /* */ + /* This is used in the CVT programs of the Microsoft fonts Arial, */ + /* Times, etc., in order to re-adjust some key font heights. It */ + /* allows the use of the IP instruction in the twilight zone, which */ + /* otherwise would be invalid according to the specification. */ + /* */ + /* We implement it with a special sequence for the twilight zone. */ + /* This is a bad hack, but it seems to work. */ + /* */ + /* Confirmed by Greg Hitchcock. */ + + distance = CUR_Func_read_cvt( cvtEntry ); + + if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ + { +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ + /* Determined via experimentation and may be incorrect... */ + if ( !SUBPIXEL_HINTING || + ( !CUR.ignore_x_mode || + !CUR.face->sph_compatibility_mode ) ) +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, + CUR.GS.freeVector.x ); + CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, + CUR.GS.freeVector.y ), + CUR.zp0.cur[point] = CUR.zp0.org[point]; + } +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && + distance > 0 && + CUR.GS.freeVector.y != 0 ) + distance = 0; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); + + if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ + { + if ( FT_ABS( distance - org_dist ) > control_value_cutin ) + distance = org_dist; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.freeVector.x != 0 ) + distance = ROUND_None( distance, + CUR.tt_metrics.compensations[0] ); + else +#endif + distance = CUR_Func_round( distance, + CUR.tt_metrics.compensations[0] ); + } + + CUR_Func_move( &CUR.zp0, point, distance - org_dist ); + + Fail: + CUR.GS.rp0 = point; + CUR.GS.rp1 = point; + } + + + /*************************************************************************/ + /* */ + /* MDRP[abcde]: Move Direct Relative Point */ + /* Opcode range: 0xC0-0xDF */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_MDRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 org_dist, distance, minimum_distance; + + + minimum_distance = CUR.GS.minimum_distance; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.freeVector.x != 0 && + !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) + minimum_distance = 0; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } + + /* XXX: Is there some undocumented feature while in the */ + /* twilight zone? */ + + /* XXX: UNDOCUMENTED: twilight zone special case */ + + if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + { + FT_Vector* vec1 = &CUR.zp1.org[point]; + FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0]; + + + org_dist = CUR_Func_dualproj( vec1, vec2 ); + } + else + { + FT_Vector* vec1 = &CUR.zp1.orus[point]; + FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0]; + + + if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + { + /* this should be faster */ + org_dist = CUR_Func_dualproj( vec1, vec2 ); + org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale ); + } + else + { + FT_Vector vec; + + + vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); + vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); + + org_dist = CUR_fast_dualproj( &vec ); + } + } + + /* single width cut-in test */ + + if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < + CUR.GS.single_width_cutin ) + { + if ( org_dist >= 0 ) + org_dist = CUR.GS.single_width_value; + else + org_dist = -CUR.GS.single_width_value; + } + + /* round flag */ + + if ( ( CUR.opcode & 4 ) != 0 ) + { +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.freeVector.x != 0 ) + distance = ROUND_None( + org_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + else +#endif + distance = CUR_Func_round( + org_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } + else + distance = ROUND_None( + org_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + + /* minimum distance flag */ + + if ( ( CUR.opcode & 8 ) != 0 ) + { + if ( org_dist >= 0 ) + { + if ( distance < minimum_distance ) + distance = minimum_distance; + } + else + { + if ( distance > -minimum_distance ) + distance = -minimum_distance; + } + } + + /* now move the point */ + + org_dist = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, distance - org_dist ); + + Fail: + CUR.GS.rp1 = CUR.GS.rp0; + CUR.GS.rp2 = point; + + if ( ( CUR.opcode & 16 ) != 0 ) + CUR.GS.rp0 = point; + } + + + /*************************************************************************/ + /* */ + /* MIRP[abcde]: Move Indirect Relative Point */ + /* Opcode range: 0xE0-0xFF */ + /* Stack: int32? uint32 --> */ + /* */ + static void + Ins_MIRP( INS_ARG ) + { + FT_UShort point; + FT_ULong cvtEntry; + + FT_F26Dot6 cvt_dist, + distance, + cur_dist, + org_dist, + control_value_cutin, + minimum_distance; +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + FT_Int B1 = 0; /* pacify compiler */ + FT_Int B2 = 0; + FT_Bool reverse_move = FALSE; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + + minimum_distance = CUR.GS.minimum_distance; + control_value_cutin = CUR.GS.control_value_cutin; + point = (FT_UShort)args[0]; + cvtEntry = (FT_ULong)( args[1] + 1 ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.freeVector.x != 0 && + !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) + control_value_cutin = minimum_distance = 0; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } + + if ( !cvtEntry ) + cvt_dist = 0; + else + cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); + + /* single width test */ + + if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) < + CUR.GS.single_width_cutin ) + { + if ( cvt_dist >= 0 ) + cvt_dist = CUR.GS.single_width_value; + else + cvt_dist = -CUR.GS.single_width_value; + } + + /* UNDOCUMENTED! The MS rasterizer does that with */ + /* twilight points (confirmed by Greg Hitchcock) */ + if ( CUR.GS.gep1 == 0 ) + { + CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.x ); + CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.y ); + CUR.zp1.cur[point] = CUR.zp1.org[point]; + } + + org_dist = CUR_Func_dualproj( &CUR.zp1.org[point], + &CUR.zp0.org[CUR.GS.rp0] ); + cur_dist = CUR_Func_project ( &CUR.zp1.cur[point], + &CUR.zp0.cur[CUR.GS.rp0] ); + + /* auto-flip test */ + + if ( CUR.GS.auto_flip ) + { + if ( ( org_dist ^ cvt_dist ) < 0 ) + cvt_dist = -cvt_dist; + } + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.freeVector.y != 0 && + ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) + { + if ( cur_dist < -64 ) + cvt_dist -= 16; + else if ( cur_dist > 64 && cur_dist < 84 ) + cvt_dist += 32; + } +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + /* control value cut-in and round */ + + if ( ( CUR.opcode & 4 ) != 0 ) + { + /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ + /* refer to the same zone. */ + + if ( CUR.GS.gep0 == CUR.GS.gep1 ) + { + /* XXX: According to Greg Hitchcock, the following wording is */ + /* the right one: */ + /* */ + /* When the absolute difference between the value in */ + /* the table [CVT] and the measurement directly from */ + /* the outline is _greater_ than the cut_in value, the */ + /* outline measurement is used. */ + /* */ + /* This is from `instgly.doc'. The description in */ + /* `ttinst2.doc', version 1.66, is thus incorrect since */ + /* it implies `>=' instead of `>'. */ + + if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) + cvt_dist = org_dist; + } + + distance = CUR_Func_round( + cvt_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } + else + { + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* do cvt cut-in always in MIRP for sph */ + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.GS.gep0 == CUR.GS.gep1 ) + { + if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) + cvt_dist = org_dist; + } +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + distance = ROUND_None( + cvt_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } + + /* minimum distance test */ + + if ( ( CUR.opcode & 8 ) != 0 ) + { + if ( org_dist >= 0 ) + { + if ( distance < minimum_distance ) + distance = minimum_distance; + } + else + { + if ( distance > -minimum_distance ) + distance = -minimum_distance; + } + } + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING ) + { + B1 = CUR.zp1.cur[point].y; + + /* Round moves if necessary */ + if ( CUR.ignore_x_mode && + CUR.GS.freeVector.y != 0 && + ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) + distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; + + if ( CUR.ignore_x_mode && + CUR.GS.freeVector.y != 0 && + ( CUR.opcode & 16 ) == 0 && + ( CUR.opcode & 8 ) == 0 && + ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) + distance += 64; + } +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING ) + { + B2 = CUR.zp1.cur[point].y; + + /* Reverse move if necessary */ + if ( CUR.ignore_x_mode ) + { + if ( CUR.face->sph_compatibility_mode && + CUR.GS.freeVector.y != 0 && + ( B1 & 63 ) == 0 && + ( B2 & 63 ) != 0 ) + reverse_move = TRUE; + + if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && + CUR.GS.freeVector.y != 0 && + ( B2 & 63 ) != 0 && + ( B1 & 63 ) != 0 ) + reverse_move = TRUE; + } + + if ( reverse_move ) + CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) ); + } + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + Fail: + CUR.GS.rp1 = CUR.GS.rp0; + + if ( ( CUR.opcode & 16 ) != 0 ) + CUR.GS.rp0 = point; + + CUR.GS.rp2 = point; + } + + + /*************************************************************************/ + /* */ + /* ALIGNRP[]: ALIGN Relative Point */ + /* Opcode range: 0x3C */ + /* Stack: uint32 uint32... --> */ + /* */ + static void + Ins_ALIGNRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 distance; + + FT_UNUSED_ARG; + + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.iup_called && + ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) + { + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + if ( CUR.top < CUR.GS.loop || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + } + else + { + distance = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, -distance ); + } + + CUR.GS.loop--; + } + + Fail: + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* ISECT[]: moves point to InterSECTion */ + /* Opcode range: 0x0F */ + /* Stack: 5 * uint32 --> */ + /* */ + static void + Ins_ISECT( INS_ARG ) + { + FT_UShort point, + a0, a1, + b0, b1; + + FT_F26Dot6 discriminant, dotproduct; + + FT_F26Dot6 dx, dy, + dax, day, + dbx, dby; + + FT_F26Dot6 val; + + FT_Vector R; + + + point = (FT_UShort)args[0]; + + a0 = (FT_UShort)args[1]; + a1 = (FT_UShort)args[2]; + b0 = (FT_UShort)args[3]; + b1 = (FT_UShort)args[4]; + + if ( BOUNDS( b0, CUR.zp0.n_points ) || + BOUNDS( b1, CUR.zp0.n_points ) || + BOUNDS( a0, CUR.zp1.n_points ) || + BOUNDS( a1, CUR.zp1.n_points ) || + BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + /* Cramer's rule */ + + dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; + dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; + + dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; + day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; + + dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; + dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; + + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; + + discriminant = FT_MulDiv( dax, -dby, 0x40 ) + + FT_MulDiv( day, dbx, 0x40 ); + dotproduct = FT_MulDiv( dax, dbx, 0x40 ) + + FT_MulDiv( day, dby, 0x40 ); + + /* The discriminant above is actually a cross product of vectors */ + /* da and db. Together with the dot product, they can be used as */ + /* surrogates for sine and cosine of the angle between the vectors. */ + /* Indeed, */ + /* dotproduct = |da||db|cos(angle) */ + /* discriminant = |da||db|sin(angle) . */ + /* We use these equations to reject grazing intersections by */ + /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */ + if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) ) + { + val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 ); + + R.x = FT_MulDiv( val, dax, discriminant ); + R.y = FT_MulDiv( val, day, discriminant ); + + CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; + CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; + } + else + { + /* else, take the middle of the middles of A and B */ + + CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + + CUR.zp1.cur[a1].x + + CUR.zp0.cur[b0].x + + CUR.zp0.cur[b1].x ) / 4; + CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + + CUR.zp1.cur[a1].y + + CUR.zp0.cur[b0].y + + CUR.zp0.cur[b1].y ) / 4; + } + } + + + /*************************************************************************/ + /* */ + /* ALIGNPTS[]: ALIGN PoinTS */ + /* Opcode range: 0x27 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_ALIGNPTS( INS_ARG ) + { + FT_UShort p1, p2; + FT_F26Dot6 distance; + + + p1 = (FT_UShort)args[0]; + p2 = (FT_UShort)args[1]; + + if ( BOUNDS( p1, CUR.zp1.n_points ) || + BOUNDS( p2, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + distance = CUR_Func_project( CUR.zp0.cur + p2, + CUR.zp1.cur + p1 ) / 2; + + CUR_Func_move( &CUR.zp1, p1, distance ); + CUR_Func_move( &CUR.zp0, p2, -distance ); + } + + + /*************************************************************************/ + /* */ + /* IP[]: Interpolate Point */ + /* Opcode range: 0x39 */ + /* Stack: uint32... --> */ + /* */ + + /* SOMETIMES, DUMBER CODE IS BETTER CODE */ + + static void + Ins_IP( INS_ARG ) + { + FT_F26Dot6 old_range, cur_range; + FT_Vector* orus_base; + FT_Vector* cur_base; + FT_Int twilight; + + FT_UNUSED_ARG; + + + if ( CUR.top < CUR.GS.loop ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } + + /* + * We need to deal in a special way with the twilight zone. + * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0), + * for every n. + */ + twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; + + if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + goto Fail; + } + + if ( twilight ) + orus_base = &CUR.zp0.org[CUR.GS.rp1]; + else + orus_base = &CUR.zp0.orus[CUR.GS.rp1]; + + cur_base = &CUR.zp0.cur[CUR.GS.rp1]; + + /* XXX: There are some glyphs in some braindead but popular */ + /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ + /* calling IP[] with bad values of rp[12]. */ + /* Do something sane when this odd thing happens. */ + if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || + BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) + { + old_range = 0; + cur_range = 0; + } + else + { + if ( twilight ) + old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], + orus_base ); + else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2], + orus_base ); + else + { + FT_Vector vec; + + + vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x, + CUR.metrics.x_scale ); + vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y, + CUR.metrics.y_scale ); + + old_range = CUR_fast_dualproj( &vec ); + } + + cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); + } + + for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) + { + FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; + FT_F26Dot6 org_dist, cur_dist, new_dist; + + + /* check point bounds */ + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + continue; + } + + if ( twilight ) + org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); + else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); + else + { + FT_Vector vec; + + + vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x, + CUR.metrics.x_scale ); + vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y, + CUR.metrics.y_scale ); + + org_dist = CUR_fast_dualproj( &vec ); + } + + cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); + + if ( org_dist ) + { + if ( old_range ) + new_dist = FT_MulDiv( org_dist, cur_range, old_range ); + else + { + /* This is the same as what MS does for the invalid case: */ + /* */ + /* delta = (Original_Pt - Original_RP1) - */ + /* (Current_Pt - Current_RP1) */ + /* */ + /* In FreeType speak: */ + /* */ + /* new_dist = cur_dist - */ + /* org_dist - cur_dist; */ + + new_dist = -org_dist; + } + } + else + new_dist = 0; + + CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); + } + + Fail: + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* UTP[a]: UnTouch Point */ + /* Opcode range: 0x29 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_UTP( INS_ARG ) + { + FT_UShort point; + FT_Byte mask; + + + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + + mask = 0xFF; + + if ( CUR.GS.freeVector.x != 0 ) + mask &= ~FT_CURVE_TAG_TOUCH_X; + + if ( CUR.GS.freeVector.y != 0 ) + mask &= ~FT_CURVE_TAG_TOUCH_Y; + + CUR.zp0.tags[point] &= mask; + } + + + /* Local variables for Ins_IUP: */ + typedef struct IUP_WorkerRec_ + { + FT_Vector* orgs; /* original and current coordinate */ + FT_Vector* curs; /* arrays */ + FT_Vector* orus; + FT_UInt max_points; + + } IUP_WorkerRec, *IUP_Worker; + + + static void + _iup_worker_shift( IUP_Worker worker, + FT_UInt p1, + FT_UInt p2, + FT_UInt p ) + { + FT_UInt i; + FT_F26Dot6 dx; + + + dx = worker->curs[p].x - worker->orgs[p].x; + if ( dx != 0 ) + { + for ( i = p1; i < p; i++ ) + worker->curs[i].x += dx; + + for ( i = p + 1; i <= p2; i++ ) + worker->curs[i].x += dx; + } + } + + + static void + _iup_worker_interpolate( IUP_Worker worker, + FT_UInt p1, + FT_UInt p2, + FT_UInt ref1, + FT_UInt ref2 ) + { + FT_UInt i; + FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2; + + + if ( p1 > p2 ) + return; + + if ( BOUNDS( ref1, worker->max_points ) || + BOUNDS( ref2, worker->max_points ) ) + return; + + orus1 = worker->orus[ref1].x; + orus2 = worker->orus[ref2].x; + + if ( orus1 > orus2 ) + { + FT_F26Dot6 tmp_o; + FT_UInt tmp_r; + + + tmp_o = orus1; + orus1 = orus2; + orus2 = tmp_o; + + tmp_r = ref1; + ref1 = ref2; + ref2 = tmp_r; + } + + org1 = worker->orgs[ref1].x; + org2 = worker->orgs[ref2].x; + delta1 = worker->curs[ref1].x - org1; + delta2 = worker->curs[ref2].x - org2; + + if ( orus1 == orus2 ) + { + /* simple shift of untouched points */ + for ( i = p1; i <= p2; i++ ) + { + FT_F26Dot6 x = worker->orgs[i].x; + + + if ( x <= org1 ) + x += delta1; + else + x += delta2; + + worker->curs[i].x = x; + } + } + else + { + FT_Fixed scale = 0; + FT_Bool scale_valid = 0; + + + /* interpolation */ + for ( i = p1; i <= p2; i++ ) + { + FT_F26Dot6 x = worker->orgs[i].x; + + + if ( x <= org1 ) + x += delta1; + + else if ( x >= org2 ) + x += delta2; + + else + { + if ( !scale_valid ) + { + scale_valid = 1; + scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ), + orus2 - orus1 ); + } + + x = ( org1 + delta1 ) + + FT_MulFix( worker->orus[i].x - orus1, scale ); + } + worker->curs[i].x = x; + } + } + } + + + /*************************************************************************/ + /* */ + /* IUP[a]: Interpolate Untouched Points */ + /* Opcode range: 0x30-0x31 */ + /* Stack: --> */ + /* */ + static void + Ins_IUP( INS_ARG ) + { + IUP_WorkerRec V; + FT_Byte mask; + + FT_UInt first_point; /* first point of contour */ + FT_UInt end_point; /* end point (last+1) of contour */ + + FT_UInt first_touched; /* first touched point in contour */ + FT_UInt cur_touched; /* current touched point in contour */ + + FT_UInt point; /* current point */ + FT_Short contour; /* current contour */ + + FT_UNUSED_ARG; + + + /* ignore empty outlines */ + if ( CUR.pts.n_contours == 0 ) + return; + + if ( CUR.opcode & 1 ) + { + mask = FT_CURVE_TAG_TOUCH_X; + V.orgs = CUR.pts.org; + V.curs = CUR.pts.cur; + V.orus = CUR.pts.orus; + } + else + { + mask = FT_CURVE_TAG_TOUCH_Y; + V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); + V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); + V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); + } + V.max_points = CUR.pts.n_points; + + contour = 0; + point = 0; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode ) + { + CUR.iup_called = TRUE; + if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) + return; + } +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + do + { + end_point = CUR.pts.contours[contour] - CUR.pts.first_point; + first_point = point; + + if ( BOUNDS ( end_point, CUR.pts.n_points ) ) + end_point = CUR.pts.n_points - 1; + + while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) + point++; + + if ( point <= end_point ) + { + first_touched = point; + cur_touched = point; + + point++; + + while ( point <= end_point ) + { + if ( ( CUR.pts.tags[point] & mask ) != 0 ) + { + _iup_worker_interpolate( &V, + cur_touched + 1, + point - 1, + cur_touched, + point ); + cur_touched = point; + } + + point++; + } + + if ( cur_touched == first_touched ) + _iup_worker_shift( &V, first_point, end_point, cur_touched ); + else + { + _iup_worker_interpolate( &V, + (FT_UShort)( cur_touched + 1 ), + end_point, + cur_touched, + first_touched ); + + if ( first_touched > 0 ) + _iup_worker_interpolate( &V, + first_point, + first_touched - 1, + cur_touched, + first_touched ); + } + } + contour++; + } while ( contour < CUR.pts.n_contours ); + } + + + /*************************************************************************/ + /* */ + /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ + /* Opcode range: 0x5D,0x71,0x72 */ + /* Stack: uint32 (2 * uint32)... --> */ + /* */ + static void + Ins_DELTAP( INS_ARG ) + { + FT_ULong k, nump; + FT_UShort A; + FT_ULong C; + FT_Long B; +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + FT_UShort B1, B2; + + + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.iup_called && + ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) + goto Fail; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Delta hinting is covered by US Patent 5159668. */ + if ( CUR.face->unpatented_hinting ) + { + FT_Long n = args[0] * 2; + + + if ( CUR.args < n ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Too_Few_Arguments ); + n = CUR.args; + } + + CUR.args -= n; + CUR.new_top = CUR.args; + return; + } +#endif + + nump = (FT_ULong)args[0]; /* some points theoretically may occur more + than once, thus UShort isn't enough */ + + for ( k = 1; k <= nump; k++ ) + { + if ( CUR.args < 2 ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Too_Few_Arguments ); + CUR.args = 0; + goto Fail; + } + + CUR.args -= 2; + + A = (FT_UShort)CUR.stack[CUR.args + 1]; + B = CUR.stack[CUR.args]; + + /* XXX: Because some popular fonts contain some invalid DeltaP */ + /* instructions, we simply ignore them when the stacked */ + /* point reference is off limit, rather than returning an */ + /* error. As a delta instruction doesn't change a glyph */ + /* in great ways, this shouldn't be a problem. */ + + if ( !BOUNDS( A, CUR.zp0.n_points ) ) + { + C = ( (FT_ULong)B & 0xF0 ) >> 4; + + switch ( CUR.opcode ) + { + case 0x5D: + break; + + case 0x71: + C += 16; + break; + + case 0x72: + C += 32; + break; + } + + C += CUR.GS.delta_base; + + if ( CURRENT_Ppem() == (FT_Long)C ) + { + B = ( (FT_ULong)B & 0xF ) - 8; + if ( B >= 0 ) + B++; + B = B * 64 / ( 1L << CUR.GS.delta_shift ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + if ( SUBPIXEL_HINTING ) + { + /* + * Allow delta move if + * + * - not using ignore_x_mode rendering + * - glyph is specifically set to allow it + * - glyph is composite and freedom vector is not subpixel + * vector + */ + if ( !CUR.ignore_x_mode || + ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || + ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ) + CUR_Func_move( &CUR.zp0, A, B ); + + /* Otherwise apply subpixel hinting and */ + /* compatibility mode rules */ + else if ( CUR.ignore_x_mode ) + { + if ( CUR.GS.freeVector.y != 0 ) + B1 = CUR.zp0.cur[A].y; + else + B1 = CUR.zp0.cur[A].x; + +#if 0 + /* Standard Subpixel Hinting: Allow y move. */ + /* This messes up dejavu and may not be needed... */ + if ( !CUR.face->sph_compatibility_mode && + CUR.GS.freeVector.y != 0 ) + CUR_Func_move( &CUR.zp0, A, B ); + else +#endif /* 0 */ + + /* Compatibility Mode: Allow x or y move if point touched in */ + /* Y direction. */ + if ( CUR.face->sph_compatibility_mode && + !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) + { + /* save the y value of the point now; compare after move */ + B1 = CUR.zp0.cur[A].y; + + if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) + B = FT_PIX_ROUND( B1 + B ) - B1; + + /* Allow delta move if using sph_compatibility_mode, */ + /* IUP has not been called, and point is touched on Y. */ + if ( !CUR.iup_called && + ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) + CUR_Func_move( &CUR.zp0, A, B ); + } + + B2 = CUR.zp0.cur[A].y; + + /* Reverse this move if it results in a disallowed move */ + if ( CUR.GS.freeVector.y != 0 && + ( ( CUR.face->sph_compatibility_mode && + ( B1 & 63 ) == 0 && + ( B2 & 63 ) != 0 ) || + ( ( CUR.sph_tweak_flags & + SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && + ( B1 & 63 ) != 0 && + ( B2 & 63 ) != 0 ) ) ) + CUR_Func_move( &CUR.zp0, A, -B ); + } + } + else +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + CUR_Func_move( &CUR.zp0, A, B ); + } + } + else + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Invalid_Reference ); + } + + Fail: + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* DELTACn[]: DELTA exceptions C1, C2, C3 */ + /* Opcode range: 0x73,0x74,0x75 */ + /* Stack: uint32 (2 * uint32)... --> */ + /* */ + static void + Ins_DELTAC( INS_ARG ) + { + FT_ULong nump, k; + FT_ULong A, C; + FT_Long B; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Delta hinting is covered by US Patent 5159668. */ + if ( CUR.face->unpatented_hinting ) + { + FT_Long n = args[0] * 2; + + + if ( CUR.args < n ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Too_Few_Arguments ); + n = CUR.args; + } + + CUR.args -= n; + CUR.new_top = CUR.args; + return; + } +#endif + + nump = (FT_ULong)args[0]; + + for ( k = 1; k <= nump; k++ ) + { + if ( CUR.args < 2 ) + { + if ( CUR.pedantic_hinting ) + CUR.error = FT_THROW( Too_Few_Arguments ); + CUR.args = 0; + goto Fail; + } + + CUR.args -= 2; + + A = (FT_ULong)CUR.stack[CUR.args + 1]; + B = CUR.stack[CUR.args]; + + if ( BOUNDSL( A, CUR.cvtSize ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = FT_THROW( Invalid_Reference ); + return; + } + } + else + { + C = ( (FT_ULong)B & 0xF0 ) >> 4; + + switch ( CUR.opcode ) + { + case 0x73: + break; + + case 0x74: + C += 16; + break; + + case 0x75: + C += 32; + break; + } + + C += CUR.GS.delta_base; + + if ( CURRENT_Ppem() == (FT_Long)C ) + { + B = ( (FT_ULong)B & 0xF ) - 8; + if ( B >= 0 ) + B++; + B = B * 64 / ( 1L << CUR.GS.delta_shift ); + + CUR_Func_move_cvt( A, B ); + } + } + } + + Fail: + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* MISC. INSTRUCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* GETINFO[]: GET INFOrmation */ + /* Opcode range: 0x88 */ + /* Stack: uint32 --> uint32 */ + /* */ + static void + Ins_GETINFO( INS_ARG ) + { + FT_Long K; + + + K = 0; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /********************************/ + /* RASTERIZER VERSION */ + /* Selector Bit: 0 */ + /* Return Bit(s): 0-7 */ + /* */ + if ( SUBPIXEL_HINTING && + ( args[0] & 1 ) != 0 && + CUR.ignore_x_mode ) + { + K = CUR.rasterizer_version; + FT_TRACE7(( "Setting rasterizer version %d\n", + CUR.rasterizer_version )); + } + else +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + if ( ( args[0] & 1 ) != 0 ) + K = TT_INTERPRETER_VERSION_35; + + /********************************/ + /* GLYPH ROTATED */ + /* Selector Bit: 1 */ + /* Return Bit(s): 8 */ + /* */ + if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) + K |= 0x80; + + /********************************/ + /* GLYPH STRETCHED */ + /* Selector Bit: 2 */ + /* Return Bit(s): 9 */ + /* */ + if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) + K |= 1 << 8; + + /********************************/ + /* HINTING FOR GRAYSCALE */ + /* Selector Bit: 5 */ + /* Return Bit(s): 12 */ + /* */ + if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) + K |= 1 << 12; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode && + CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 ) + { + /********************************/ + /* HINTING FOR GRAYSCALE */ + /* Selector Bit: 5 */ + /* Return Bit(s): 12 */ + /* */ + if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting ) + K |= 1 << 12; + + /********************************/ + /* HINTING FOR SUBPIXEL */ + /* Selector Bit: 6 */ + /* Return Bit(s): 13 */ + /* */ + if ( ( args[0] & 64 ) != 0 && + CUR.subpixel_hinting && + CUR.rasterizer_version >= 37 ) + { + K |= 1 << 13; + + /* the stuff below is irrelevant if subpixel_hinting is not set */ + + /********************************/ + /* COMPATIBLE WIDTHS ENABLED */ + /* Selector Bit: 7 */ + /* Return Bit(s): 14 */ + /* */ + /* Functionality still needs to be added */ + if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) + K |= 1 << 14; + + /********************************/ + /* SYMMETRICAL SMOOTHING */ + /* Selector Bit: 8 */ + /* Return Bit(s): 15 */ + /* */ + /* Functionality still needs to be added */ + if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing ) + K |= 1 << 15; + + /********************************/ + /* HINTING FOR BGR? */ + /* Selector Bit: 9 */ + /* Return Bit(s): 16 */ + /* */ + /* Functionality still needs to be added */ + if ( ( args[0] & 512 ) != 0 && CUR.bgr ) + K |= 1 << 16; + + if ( CUR.rasterizer_version >= 38 ) + { + /********************************/ + /* SUBPIXEL POSITIONED? */ + /* Selector Bit: 10 */ + /* Return Bit(s): 17 */ + /* */ + /* Functionality still needs to be added */ + if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned ) + K |= 1 << 17; + } + } + } + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + args[0] = K; + } + + + static void + Ins_UNKNOWN( INS_ARG ) + { + TT_DefRecord* def = CUR.IDefs; + TT_DefRecord* limit = def + CUR.numIDefs; + + FT_UNUSED_ARG; + + + for ( ; def < limit; def++ ) + { + if ( (FT_Byte)def->opc == CUR.opcode && def->active ) + { + TT_CallRec* call; + + + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = FT_THROW( Stack_Overflow ); + return; + } + + call = CUR.callStack + CUR.callTop++; + + call->Caller_Range = CUR.curRange; + call->Caller_IP = CUR.IP + 1; + call->Cur_Count = 1; + call->Cur_Restart = def->start; + call->Cur_End = def->end; + + INS_Goto_CodeRange( def->range, def->start ); + + CUR.step_ins = FALSE; + return; + } + } + + CUR.error = FT_THROW( Invalid_Opcode ); + } + + +#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + static + TInstruction_Function Instruct_Dispatch[256] = + { + /* Opcodes are gathered in groups of 16. */ + /* Please keep the spaces as they are. */ + + /* SVTCA y */ Ins_SVTCA, + /* SVTCA x */ Ins_SVTCA, + /* SPvTCA y */ Ins_SPVTCA, + /* SPvTCA x */ Ins_SPVTCA, + /* SFvTCA y */ Ins_SFVTCA, + /* SFvTCA x */ Ins_SFVTCA, + /* SPvTL // */ Ins_SPVTL, + /* SPvTL + */ Ins_SPVTL, + /* SFvTL // */ Ins_SFVTL, + /* SFvTL + */ Ins_SFVTL, + /* SPvFS */ Ins_SPVFS, + /* SFvFS */ Ins_SFVFS, + /* GPV */ Ins_GPV, + /* GFV */ Ins_GFV, + /* SFvTPv */ Ins_SFVTPV, + /* ISECT */ Ins_ISECT, + + /* SRP0 */ Ins_SRP0, + /* SRP1 */ Ins_SRP1, + /* SRP2 */ Ins_SRP2, + /* SZP0 */ Ins_SZP0, + /* SZP1 */ Ins_SZP1, + /* SZP2 */ Ins_SZP2, + /* SZPS */ Ins_SZPS, + /* SLOOP */ Ins_SLOOP, + /* RTG */ Ins_RTG, + /* RTHG */ Ins_RTHG, + /* SMD */ Ins_SMD, + /* ELSE */ Ins_ELSE, + /* JMPR */ Ins_JMPR, + /* SCvTCi */ Ins_SCVTCI, + /* SSwCi */ Ins_SSWCI, + /* SSW */ Ins_SSW, + + /* DUP */ Ins_DUP, + /* POP */ Ins_POP, + /* CLEAR */ Ins_CLEAR, + /* SWAP */ Ins_SWAP, + /* DEPTH */ Ins_DEPTH, + /* CINDEX */ Ins_CINDEX, + /* MINDEX */ Ins_MINDEX, + /* AlignPTS */ Ins_ALIGNPTS, + /* INS_0x28 */ Ins_UNKNOWN, + /* UTP */ Ins_UTP, + /* LOOPCALL */ Ins_LOOPCALL, + /* CALL */ Ins_CALL, + /* FDEF */ Ins_FDEF, + /* ENDF */ Ins_ENDF, + /* MDAP[0] */ Ins_MDAP, + /* MDAP[1] */ Ins_MDAP, + + /* IUP[0] */ Ins_IUP, + /* IUP[1] */ Ins_IUP, + /* SHP[0] */ Ins_SHP, + /* SHP[1] */ Ins_SHP, + /* SHC[0] */ Ins_SHC, + /* SHC[1] */ Ins_SHC, + /* SHZ[0] */ Ins_SHZ, + /* SHZ[1] */ Ins_SHZ, + /* SHPIX */ Ins_SHPIX, + /* IP */ Ins_IP, + /* MSIRP[0] */ Ins_MSIRP, + /* MSIRP[1] */ Ins_MSIRP, + /* AlignRP */ Ins_ALIGNRP, + /* RTDG */ Ins_RTDG, + /* MIAP[0] */ Ins_MIAP, + /* MIAP[1] */ Ins_MIAP, + + /* NPushB */ Ins_NPUSHB, + /* NPushW */ Ins_NPUSHW, + /* WS */ Ins_WS, + /* RS */ Ins_RS, + /* WCvtP */ Ins_WCVTP, + /* RCvt */ Ins_RCVT, + /* GC[0] */ Ins_GC, + /* GC[1] */ Ins_GC, + /* SCFS */ Ins_SCFS, + /* MD[0] */ Ins_MD, + /* MD[1] */ Ins_MD, + /* MPPEM */ Ins_MPPEM, + /* MPS */ Ins_MPS, + /* FlipON */ Ins_FLIPON, + /* FlipOFF */ Ins_FLIPOFF, + /* DEBUG */ Ins_DEBUG, + + /* LT */ Ins_LT, + /* LTEQ */ Ins_LTEQ, + /* GT */ Ins_GT, + /* GTEQ */ Ins_GTEQ, + /* EQ */ Ins_EQ, + /* NEQ */ Ins_NEQ, + /* ODD */ Ins_ODD, + /* EVEN */ Ins_EVEN, + /* IF */ Ins_IF, + /* EIF */ Ins_EIF, + /* AND */ Ins_AND, + /* OR */ Ins_OR, + /* NOT */ Ins_NOT, + /* DeltaP1 */ Ins_DELTAP, + /* SDB */ Ins_SDB, + /* SDS */ Ins_SDS, + + /* ADD */ Ins_ADD, + /* SUB */ Ins_SUB, + /* DIV */ Ins_DIV, + /* MUL */ Ins_MUL, + /* ABS */ Ins_ABS, + /* NEG */ Ins_NEG, + /* FLOOR */ Ins_FLOOR, + /* CEILING */ Ins_CEILING, + /* ROUND[0] */ Ins_ROUND, + /* ROUND[1] */ Ins_ROUND, + /* ROUND[2] */ Ins_ROUND, + /* ROUND[3] */ Ins_ROUND, + /* NROUND[0] */ Ins_NROUND, + /* NROUND[1] */ Ins_NROUND, + /* NROUND[2] */ Ins_NROUND, + /* NROUND[3] */ Ins_NROUND, + + /* WCvtF */ Ins_WCVTF, + /* DeltaP2 */ Ins_DELTAP, + /* DeltaP3 */ Ins_DELTAP, + /* DeltaCn[0] */ Ins_DELTAC, + /* DeltaCn[1] */ Ins_DELTAC, + /* DeltaCn[2] */ Ins_DELTAC, + /* SROUND */ Ins_SROUND, + /* S45Round */ Ins_S45ROUND, + /* JROT */ Ins_JROT, + /* JROF */ Ins_JROF, + /* ROFF */ Ins_ROFF, + /* INS_0x7B */ Ins_UNKNOWN, + /* RUTG */ Ins_RUTG, + /* RDTG */ Ins_RDTG, + /* SANGW */ Ins_SANGW, + /* AA */ Ins_AA, + + /* FlipPT */ Ins_FLIPPT, + /* FlipRgON */ Ins_FLIPRGON, + /* FlipRgOFF */ Ins_FLIPRGOFF, + /* INS_0x83 */ Ins_UNKNOWN, + /* INS_0x84 */ Ins_UNKNOWN, + /* ScanCTRL */ Ins_SCANCTRL, + /* SDPVTL[0] */ Ins_SDPVTL, + /* SDPVTL[1] */ Ins_SDPVTL, + /* GetINFO */ Ins_GETINFO, + /* IDEF */ Ins_IDEF, + /* ROLL */ Ins_ROLL, + /* MAX */ Ins_MAX, + /* MIN */ Ins_MIN, + /* ScanTYPE */ Ins_SCANTYPE, + /* InstCTRL */ Ins_INSTCTRL, + /* INS_0x8F */ Ins_UNKNOWN, + + /* INS_0x90 */ Ins_UNKNOWN, + /* INS_0x91 */ Ins_UNKNOWN, + /* INS_0x92 */ Ins_UNKNOWN, + /* INS_0x93 */ Ins_UNKNOWN, + /* INS_0x94 */ Ins_UNKNOWN, + /* INS_0x95 */ Ins_UNKNOWN, + /* INS_0x96 */ Ins_UNKNOWN, + /* INS_0x97 */ Ins_UNKNOWN, + /* INS_0x98 */ Ins_UNKNOWN, + /* INS_0x99 */ Ins_UNKNOWN, + /* INS_0x9A */ Ins_UNKNOWN, + /* INS_0x9B */ Ins_UNKNOWN, + /* INS_0x9C */ Ins_UNKNOWN, + /* INS_0x9D */ Ins_UNKNOWN, + /* INS_0x9E */ Ins_UNKNOWN, + /* INS_0x9F */ Ins_UNKNOWN, + + /* INS_0xA0 */ Ins_UNKNOWN, + /* INS_0xA1 */ Ins_UNKNOWN, + /* INS_0xA2 */ Ins_UNKNOWN, + /* INS_0xA3 */ Ins_UNKNOWN, + /* INS_0xA4 */ Ins_UNKNOWN, + /* INS_0xA5 */ Ins_UNKNOWN, + /* INS_0xA6 */ Ins_UNKNOWN, + /* INS_0xA7 */ Ins_UNKNOWN, + /* INS_0xA8 */ Ins_UNKNOWN, + /* INS_0xA9 */ Ins_UNKNOWN, + /* INS_0xAA */ Ins_UNKNOWN, + /* INS_0xAB */ Ins_UNKNOWN, + /* INS_0xAC */ Ins_UNKNOWN, + /* INS_0xAD */ Ins_UNKNOWN, + /* INS_0xAE */ Ins_UNKNOWN, + /* INS_0xAF */ Ins_UNKNOWN, + + /* PushB[0] */ Ins_PUSHB, + /* PushB[1] */ Ins_PUSHB, + /* PushB[2] */ Ins_PUSHB, + /* PushB[3] */ Ins_PUSHB, + /* PushB[4] */ Ins_PUSHB, + /* PushB[5] */ Ins_PUSHB, + /* PushB[6] */ Ins_PUSHB, + /* PushB[7] */ Ins_PUSHB, + /* PushW[0] */ Ins_PUSHW, + /* PushW[1] */ Ins_PUSHW, + /* PushW[2] */ Ins_PUSHW, + /* PushW[3] */ Ins_PUSHW, + /* PushW[4] */ Ins_PUSHW, + /* PushW[5] */ Ins_PUSHW, + /* PushW[6] */ Ins_PUSHW, + /* PushW[7] */ Ins_PUSHW, + + /* MDRP[00] */ Ins_MDRP, + /* MDRP[01] */ Ins_MDRP, + /* MDRP[02] */ Ins_MDRP, + /* MDRP[03] */ Ins_MDRP, + /* MDRP[04] */ Ins_MDRP, + /* MDRP[05] */ Ins_MDRP, + /* MDRP[06] */ Ins_MDRP, + /* MDRP[07] */ Ins_MDRP, + /* MDRP[08] */ Ins_MDRP, + /* MDRP[09] */ Ins_MDRP, + /* MDRP[10] */ Ins_MDRP, + /* MDRP[11] */ Ins_MDRP, + /* MDRP[12] */ Ins_MDRP, + /* MDRP[13] */ Ins_MDRP, + /* MDRP[14] */ Ins_MDRP, + /* MDRP[15] */ Ins_MDRP, + + /* MDRP[16] */ Ins_MDRP, + /* MDRP[17] */ Ins_MDRP, + /* MDRP[18] */ Ins_MDRP, + /* MDRP[19] */ Ins_MDRP, + /* MDRP[20] */ Ins_MDRP, + /* MDRP[21] */ Ins_MDRP, + /* MDRP[22] */ Ins_MDRP, + /* MDRP[23] */ Ins_MDRP, + /* MDRP[24] */ Ins_MDRP, + /* MDRP[25] */ Ins_MDRP, + /* MDRP[26] */ Ins_MDRP, + /* MDRP[27] */ Ins_MDRP, + /* MDRP[28] */ Ins_MDRP, + /* MDRP[29] */ Ins_MDRP, + /* MDRP[30] */ Ins_MDRP, + /* MDRP[31] */ Ins_MDRP, + + /* MIRP[00] */ Ins_MIRP, + /* MIRP[01] */ Ins_MIRP, + /* MIRP[02] */ Ins_MIRP, + /* MIRP[03] */ Ins_MIRP, + /* MIRP[04] */ Ins_MIRP, + /* MIRP[05] */ Ins_MIRP, + /* MIRP[06] */ Ins_MIRP, + /* MIRP[07] */ Ins_MIRP, + /* MIRP[08] */ Ins_MIRP, + /* MIRP[09] */ Ins_MIRP, + /* MIRP[10] */ Ins_MIRP, + /* MIRP[11] */ Ins_MIRP, + /* MIRP[12] */ Ins_MIRP, + /* MIRP[13] */ Ins_MIRP, + /* MIRP[14] */ Ins_MIRP, + /* MIRP[15] */ Ins_MIRP, + + /* MIRP[16] */ Ins_MIRP, + /* MIRP[17] */ Ins_MIRP, + /* MIRP[18] */ Ins_MIRP, + /* MIRP[19] */ Ins_MIRP, + /* MIRP[20] */ Ins_MIRP, + /* MIRP[21] */ Ins_MIRP, + /* MIRP[22] */ Ins_MIRP, + /* MIRP[23] */ Ins_MIRP, + /* MIRP[24] */ Ins_MIRP, + /* MIRP[25] */ Ins_MIRP, + /* MIRP[26] */ Ins_MIRP, + /* MIRP[27] */ Ins_MIRP, + /* MIRP[28] */ Ins_MIRP, + /* MIRP[29] */ Ins_MIRP, + /* MIRP[30] */ Ins_MIRP, + /* MIRP[31] */ Ins_MIRP + }; + + +#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + + /*************************************************************************/ + /* */ + /* RUN */ + /* */ + /* This function executes a run of opcodes. It will exit in the */ + /* following cases: */ + /* */ + /* - Errors (in which case it returns FALSE). */ + /* */ + /* - Reaching the end of the main code range (returns TRUE). */ + /* Reaching the end of a code range within a function call is an */ + /* error. */ + /* */ + /* - After executing one single opcode, if the flag `Instruction_Trap' */ + /* is set to TRUE (returns TRUE). */ + /* */ + /* On exit with TRUE, test IP < CodeSize to know whether it comes from */ + /* an instruction trap or a normal termination. */ + /* */ + /* */ + /* Note: The documented DEBUG opcode pops a value from the stack. This */ + /* behaviour is unsupported; here a DEBUG opcode is always an */ + /* error. */ + /* */ + /* */ + /* THIS IS THE INTERPRETER'S MAIN LOOP. */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /* documentation is in ttinterp.h */ + + FT_EXPORT_DEF( FT_Error ) + TT_RunIns( TT_ExecContext exc ) + { + FT_Long ins_counter = 0; /* executed instructions counter */ + FT_UShort i; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + FT_Byte opcode_pattern[1][2] = { + /* #8 TypeMan Talk Align */ + { + 0x06, /* SPVTL */ + 0x7D, /* RDTG */ + }, + }; + FT_UShort opcode_patterns = 1; + FT_UShort opcode_pointer[1] = { 0 }; + FT_UShort opcode_size[1] = { 1 }; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + cur = *exc; +#endif + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + CUR.iup_called = FALSE; +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + /* set CVT functions */ + CUR.tt_metrics.ratio = 0; + if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) + { + /* non-square pixels, use the stretched routines */ + CUR.func_read_cvt = Read_CVT_Stretched; + CUR.func_write_cvt = Write_CVT_Stretched; + CUR.func_move_cvt = Move_CVT_Stretched; + } + else + { + /* square pixels, use normal routines */ + CUR.func_read_cvt = Read_CVT; + CUR.func_write_cvt = Write_CVT; + CUR.func_move_cvt = Move_CVT; + } + + COMPUTE_Funcs(); + COMPUTE_Round( (FT_Byte)exc->GS.round_state ); + + do + { + CUR.opcode = CUR.code[CUR.IP]; + + FT_TRACE7(( " " )); + FT_TRACE7(( opcode_name[CUR.opcode] )); + FT_TRACE7(( "\n" )); + + if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) + { + if ( CUR.IP + 1 >= CUR.codeSize ) + goto LErrorCodeOverflow_; + + CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; + } + + if ( CUR.IP + CUR.length > CUR.codeSize ) + goto LErrorCodeOverflow_; + + /* First, let's check for empty stack and overflow */ + CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); + + /* `args' is the top of the stack once arguments have been popped. */ + /* One can also interpret it as the index of the last argument. */ + if ( CUR.args < 0 ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = FT_THROW( Too_Few_Arguments ); + goto LErrorLabel_; + } + + /* push zeroes onto the stack */ + for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ ) + CUR.stack[i] = 0; + CUR.args = 0; + } + + CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); + + /* `new_top' is the new top of the stack, after the instruction's */ + /* execution. `top' will be set to `new_top' after the `switch' */ + /* statement. */ + if ( CUR.new_top > CUR.stackSize ) + { + CUR.error = FT_THROW( Stack_Overflow ); + goto LErrorLabel_; + } + + CUR.step_ins = TRUE; + CUR.error = FT_Err_Ok; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + if ( SUBPIXEL_HINTING ) + { + for ( i = 0; i < opcode_patterns; i++ ) + { + if ( opcode_pointer[i] < opcode_size[i] && + CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) + { + opcode_pointer[i] += 1; + + if ( opcode_pointer[i] == opcode_size[i] ) + { + FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n", + i, + CUR.face->root.family_name, + CUR.face->root.style_name )); + + switch ( i ) + { + case 0: + break; + } + opcode_pointer[i] = 0; + } + } + else + opcode_pointer[i] = 0; + } + } + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + +#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + { + FT_Long* args = CUR.stack + CUR.args; + FT_Byte opcode = CUR.opcode; + + +#undef ARRAY_BOUND_ERROR +#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref + + + switch ( opcode ) + { + case 0x00: /* SVTCA y */ + case 0x01: /* SVTCA x */ + case 0x02: /* SPvTCA y */ + case 0x03: /* SPvTCA x */ + case 0x04: /* SFvTCA y */ + case 0x05: /* SFvTCA x */ + { + FT_Short AA, BB; + + + AA = (FT_Short)( ( opcode & 1 ) << 14 ); + BB = (FT_Short)( AA ^ 0x4000 ); + + if ( opcode < 4 ) + { + CUR.GS.projVector.x = AA; + CUR.GS.projVector.y = BB; + + CUR.GS.dualVector.x = AA; + CUR.GS.dualVector.y = BB; + } + else + { + GUESS_VECTOR( projVector ); + } + + if ( ( opcode & 2 ) == 0 ) + { + CUR.GS.freeVector.x = AA; + CUR.GS.freeVector.y = BB; + } + else + { + GUESS_VECTOR( freeVector ); + } + + COMPUTE_Funcs(); + } + break; + + case 0x06: /* SPvTL // */ + case 0x07: /* SPvTL + */ + DO_SPVTL + break; + + case 0x08: /* SFvTL // */ + case 0x09: /* SFvTL + */ + DO_SFVTL + break; + + case 0x0A: /* SPvFS */ + DO_SPVFS + break; + + case 0x0B: /* SFvFS */ + DO_SFVFS + break; + + case 0x0C: /* GPV */ + DO_GPV + break; + + case 0x0D: /* GFV */ + DO_GFV + break; + + case 0x0E: /* SFvTPv */ + DO_SFVTPV + break; + + case 0x0F: /* ISECT */ + Ins_ISECT( EXEC_ARG_ args ); + break; + + case 0x10: /* SRP0 */ + DO_SRP0 + break; + + case 0x11: /* SRP1 */ + DO_SRP1 + break; + + case 0x12: /* SRP2 */ + DO_SRP2 + break; + + case 0x13: /* SZP0 */ + Ins_SZP0( EXEC_ARG_ args ); + break; + + case 0x14: /* SZP1 */ + Ins_SZP1( EXEC_ARG_ args ); + break; + + case 0x15: /* SZP2 */ + Ins_SZP2( EXEC_ARG_ args ); + break; + + case 0x16: /* SZPS */ + Ins_SZPS( EXEC_ARG_ args ); + break; + + case 0x17: /* SLOOP */ + DO_SLOOP + break; + + case 0x18: /* RTG */ + DO_RTG + break; + + case 0x19: /* RTHG */ + DO_RTHG + break; + + case 0x1A: /* SMD */ + DO_SMD + break; + + case 0x1B: /* ELSE */ + Ins_ELSE( EXEC_ARG_ args ); + break; + + case 0x1C: /* JMPR */ + DO_JMPR + break; + + case 0x1D: /* SCVTCI */ + DO_SCVTCI + break; + + case 0x1E: /* SSWCI */ + DO_SSWCI + break; + + case 0x1F: /* SSW */ + DO_SSW + break; + + case 0x20: /* DUP */ + DO_DUP + break; + + case 0x21: /* POP */ + /* nothing :-) */ + break; + + case 0x22: /* CLEAR */ + DO_CLEAR + break; + + case 0x23: /* SWAP */ + DO_SWAP + break; + + case 0x24: /* DEPTH */ + DO_DEPTH + break; + + case 0x25: /* CINDEX */ + DO_CINDEX + break; + + case 0x26: /* MINDEX */ + Ins_MINDEX( EXEC_ARG_ args ); + break; + + case 0x27: /* ALIGNPTS */ + Ins_ALIGNPTS( EXEC_ARG_ args ); + break; + + case 0x28: /* ???? */ + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + case 0x29: /* UTP */ + Ins_UTP( EXEC_ARG_ args ); + break; + + case 0x2A: /* LOOPCALL */ + Ins_LOOPCALL( EXEC_ARG_ args ); + break; + + case 0x2B: /* CALL */ + Ins_CALL( EXEC_ARG_ args ); + break; + + case 0x2C: /* FDEF */ + Ins_FDEF( EXEC_ARG_ args ); + break; + + case 0x2D: /* ENDF */ + Ins_ENDF( EXEC_ARG_ args ); + break; + + case 0x2E: /* MDAP */ + case 0x2F: /* MDAP */ + Ins_MDAP( EXEC_ARG_ args ); + break; + + case 0x30: /* IUP */ + case 0x31: /* IUP */ + Ins_IUP( EXEC_ARG_ args ); + break; + + case 0x32: /* SHP */ + case 0x33: /* SHP */ + Ins_SHP( EXEC_ARG_ args ); + break; + + case 0x34: /* SHC */ + case 0x35: /* SHC */ + Ins_SHC( EXEC_ARG_ args ); + break; + + case 0x36: /* SHZ */ + case 0x37: /* SHZ */ + Ins_SHZ( EXEC_ARG_ args ); + break; + + case 0x38: /* SHPIX */ + Ins_SHPIX( EXEC_ARG_ args ); + break; + + case 0x39: /* IP */ + Ins_IP( EXEC_ARG_ args ); + break; + + case 0x3A: /* MSIRP */ + case 0x3B: /* MSIRP */ + Ins_MSIRP( EXEC_ARG_ args ); + break; + + case 0x3C: /* AlignRP */ + Ins_ALIGNRP( EXEC_ARG_ args ); + break; + + case 0x3D: /* RTDG */ + DO_RTDG + break; + + case 0x3E: /* MIAP */ + case 0x3F: /* MIAP */ + Ins_MIAP( EXEC_ARG_ args ); + break; + + case 0x40: /* NPUSHB */ + Ins_NPUSHB( EXEC_ARG_ args ); + break; + + case 0x41: /* NPUSHW */ + Ins_NPUSHW( EXEC_ARG_ args ); + break; + + case 0x42: /* WS */ + DO_WS + break; + + Set_Invalid_Ref: + CUR.error = FT_THROW( Invalid_Reference ); + break; + + case 0x43: /* RS */ + DO_RS + break; + + case 0x44: /* WCVTP */ + DO_WCVTP + break; + + case 0x45: /* RCVT */ + DO_RCVT + break; + + case 0x46: /* GC */ + case 0x47: /* GC */ + Ins_GC( EXEC_ARG_ args ); + break; + + case 0x48: /* SCFS */ + Ins_SCFS( EXEC_ARG_ args ); + break; + + case 0x49: /* MD */ + case 0x4A: /* MD */ + Ins_MD( EXEC_ARG_ args ); + break; + + case 0x4B: /* MPPEM */ + DO_MPPEM + break; + + case 0x4C: /* MPS */ + DO_MPS + break; + + case 0x4D: /* FLIPON */ + DO_FLIPON + break; + + case 0x4E: /* FLIPOFF */ + DO_FLIPOFF + break; + + case 0x4F: /* DEBUG */ + DO_DEBUG + break; + + case 0x50: /* LT */ + DO_LT + break; + + case 0x51: /* LTEQ */ + DO_LTEQ + break; + + case 0x52: /* GT */ + DO_GT + break; + + case 0x53: /* GTEQ */ + DO_GTEQ + break; + + case 0x54: /* EQ */ + DO_EQ + break; + + case 0x55: /* NEQ */ + DO_NEQ + break; + + case 0x56: /* ODD */ + DO_ODD + break; + + case 0x57: /* EVEN */ + DO_EVEN + break; + + case 0x58: /* IF */ + Ins_IF( EXEC_ARG_ args ); + break; + + case 0x59: /* EIF */ + /* do nothing */ + break; + + case 0x5A: /* AND */ + DO_AND + break; + + case 0x5B: /* OR */ + DO_OR + break; + + case 0x5C: /* NOT */ + DO_NOT + break; + + case 0x5D: /* DELTAP1 */ + Ins_DELTAP( EXEC_ARG_ args ); + break; + + case 0x5E: /* SDB */ + DO_SDB + break; + + case 0x5F: /* SDS */ + DO_SDS + break; + + case 0x60: /* ADD */ + DO_ADD + break; + + case 0x61: /* SUB */ + DO_SUB + break; + + case 0x62: /* DIV */ + DO_DIV + break; + + case 0x63: /* MUL */ + DO_MUL + break; + + case 0x64: /* ABS */ + DO_ABS + break; + + case 0x65: /* NEG */ + DO_NEG + break; + + case 0x66: /* FLOOR */ + DO_FLOOR + break; + + case 0x67: /* CEILING */ + DO_CEILING + break; + + case 0x68: /* ROUND */ + case 0x69: /* ROUND */ + case 0x6A: /* ROUND */ + case 0x6B: /* ROUND */ + DO_ROUND + break; + + case 0x6C: /* NROUND */ + case 0x6D: /* NROUND */ + case 0x6E: /* NRRUND */ + case 0x6F: /* NROUND */ + DO_NROUND + break; + + case 0x70: /* WCVTF */ + DO_WCVTF + break; + + case 0x71: /* DELTAP2 */ + case 0x72: /* DELTAP3 */ + Ins_DELTAP( EXEC_ARG_ args ); + break; + + case 0x73: /* DELTAC0 */ + case 0x74: /* DELTAC1 */ + case 0x75: /* DELTAC2 */ + Ins_DELTAC( EXEC_ARG_ args ); + break; + + case 0x76: /* SROUND */ + DO_SROUND + break; + + case 0x77: /* S45Round */ + DO_S45ROUND + break; + + case 0x78: /* JROT */ + DO_JROT + break; + + case 0x79: /* JROF */ + DO_JROF + break; + + case 0x7A: /* ROFF */ + DO_ROFF + break; + + case 0x7B: /* ???? */ + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + case 0x7C: /* RUTG */ + DO_RUTG + break; + + case 0x7D: /* RDTG */ + DO_RDTG + break; + + case 0x7E: /* SANGW */ + case 0x7F: /* AA */ + /* nothing - obsolete */ + break; + + case 0x80: /* FLIPPT */ + Ins_FLIPPT( EXEC_ARG_ args ); + break; + + case 0x81: /* FLIPRGON */ + Ins_FLIPRGON( EXEC_ARG_ args ); + break; + + case 0x82: /* FLIPRGOFF */ + Ins_FLIPRGOFF( EXEC_ARG_ args ); + break; + + case 0x83: /* UNKNOWN */ + case 0x84: /* UNKNOWN */ + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + case 0x85: /* SCANCTRL */ + Ins_SCANCTRL( EXEC_ARG_ args ); + break; + + case 0x86: /* SDPVTL */ + case 0x87: /* SDPVTL */ + Ins_SDPVTL( EXEC_ARG_ args ); + break; + + case 0x88: /* GETINFO */ + Ins_GETINFO( EXEC_ARG_ args ); + break; + + case 0x89: /* IDEF */ + Ins_IDEF( EXEC_ARG_ args ); + break; + + case 0x8A: /* ROLL */ + Ins_ROLL( EXEC_ARG_ args ); + break; + + case 0x8B: /* MAX */ + DO_MAX + break; + + case 0x8C: /* MIN */ + DO_MIN + break; + + case 0x8D: /* SCANTYPE */ + Ins_SCANTYPE( EXEC_ARG_ args ); + break; + + case 0x8E: /* INSTCTRL */ + Ins_INSTCTRL( EXEC_ARG_ args ); + break; + + case 0x8F: + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + default: + if ( opcode >= 0xE0 ) + Ins_MIRP( EXEC_ARG_ args ); + else if ( opcode >= 0xC0 ) + Ins_MDRP( EXEC_ARG_ args ); + else if ( opcode >= 0xB8 ) + Ins_PUSHW( EXEC_ARG_ args ); + else if ( opcode >= 0xB0 ) + Ins_PUSHB( EXEC_ARG_ args ); + else + Ins_UNKNOWN( EXEC_ARG_ args ); + } + + } + +#else + + Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); + +#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + if ( CUR.error ) + { + switch ( CUR.error ) + { + /* looking for redefined instructions */ + case FT_ERR( Invalid_Opcode ): + { + TT_DefRecord* def = CUR.IDefs; + TT_DefRecord* limit = def + CUR.numIDefs; + + + for ( ; def < limit; def++ ) + { + if ( def->active && CUR.opcode == (FT_Byte)def->opc ) + { + TT_CallRec* callrec; + + + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = FT_THROW( Invalid_Reference ); + goto LErrorLabel_; + } + + callrec = &CUR.callStack[CUR.callTop]; + + callrec->Caller_Range = CUR.curRange; + callrec->Caller_IP = CUR.IP + 1; + callrec->Cur_Count = 1; + callrec->Cur_Restart = def->start; + callrec->Cur_End = def->end; + + if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) + goto LErrorLabel_; + + goto LSuiteLabel_; + } + } + } + + CUR.error = FT_THROW( Invalid_Opcode ); + goto LErrorLabel_; + +#if 0 + break; /* Unreachable code warning suppression. */ + /* Leave to remind in case a later change the editor */ + /* to consider break; */ +#endif + + default: + goto LErrorLabel_; + +#if 0 + break; +#endif + } + } + + CUR.top = CUR.new_top; + + if ( CUR.step_ins ) + CUR.IP += CUR.length; + + /* increment instruction counter and check if we didn't */ + /* run this program for too long (e.g. infinite loops). */ + if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + return FT_THROW( Execution_Too_Long ); + + LSuiteLabel_: + if ( CUR.IP >= CUR.codeSize ) + { + if ( CUR.callTop > 0 ) + { + CUR.error = FT_THROW( Code_Overflow ); + goto LErrorLabel_; + } + else + goto LNo_Error_; + } + } while ( !CUR.instruction_trap ); + + LNo_Error_: + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + *exc = cur; +#endif + + return FT_Err_Ok; + + LErrorCodeOverflow_: + CUR.error = FT_THROW( Code_Overflow ); + + LErrorLabel_: + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + *exc = cur; +#endif + + /* If any errors have occurred, function tables may be broken. */ + /* Force a re-execution of `prep' and `fpgm' tables if no */ + /* bytecode debugger is run. */ + if ( CUR.error && !CUR.instruction_trap ) + { + FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); + exc->size->cvt_ready = FALSE; + } + + return CUR.error; + } + + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttinterp.h b/drivers/freetype/src/truetype/ttinterp.h new file mode 100644 index 0000000000..69f5011ed4 --- /dev/null +++ b/drivers/freetype/src/truetype/ttinterp.h @@ -0,0 +1,397 @@ +/***************************************************************************/ +/* */ +/* ttinterp.h */ +/* */ +/* TrueType bytecode interpreter (specification). */ +/* */ +/* Copyright 1996-2007, 2010, 2012-2013 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 __TTINTERP_H__ +#define __TTINTERP_H__ + +#include <ft2build.h> +#include "ttobjs.h" + + +FT_BEGIN_HEADER + + +#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ + +#define EXEC_OP_ TT_ExecContext exc, +#define EXEC_OP TT_ExecContext exc +#define EXEC_ARG_ exc, +#define EXEC_ARG exc + +#else /* static implementation */ + +#define EXEC_OP_ /* void */ +#define EXEC_OP /* void */ +#define EXEC_ARG_ /* void */ +#define EXEC_ARG /* void */ + +#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* Rounding mode constants. */ + /* */ +#define TT_Round_Off 5 +#define TT_Round_To_Half_Grid 0 +#define TT_Round_To_Grid 1 +#define TT_Round_To_Double_Grid 2 +#define TT_Round_Up_To_Grid 4 +#define TT_Round_Down_To_Grid 3 +#define TT_Round_Super 6 +#define TT_Round_Super_45 7 + + + /*************************************************************************/ + /* */ + /* Function types used by the interpreter, depending on various modes */ + /* (e.g. the rounding mode, whether to render a vertical or horizontal */ + /* line etc). */ + /* */ + /*************************************************************************/ + + /* Rounding function */ + typedef FT_F26Dot6 + (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ); + + /* Point displacement along the freedom vector routine */ + typedef void + (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ); + + /* Distance projection along one of the projection vectors */ + typedef FT_F26Dot6 + (*TT_Project_Func)( EXEC_OP_ FT_Pos dx, + FT_Pos dy ); + + /* reading a cvt value. Take care of non-square pixels if necessary */ + typedef FT_F26Dot6 + (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx ); + + /* setting or moving a cvt value. Take care of non-square pixels */ + /* if necessary */ + typedef void + (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ); + + + /*************************************************************************/ + /* */ + /* This structure defines a call record, used to manage function calls. */ + /* */ + typedef struct TT_CallRec_ + { + FT_Int Caller_Range; + FT_Long Caller_IP; + FT_Long Cur_Count; + FT_Long Cur_Restart; + FT_Long Cur_End; + + } TT_CallRec, *TT_CallStack; + + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + /*************************************************************************/ + /* */ + /* These structures define rules used to tweak subpixel hinting for */ + /* various fonts. "", 0, "", NULL value indicates to match any value. */ + /* */ + +#define SPH_MAX_NAME_SIZE 32 +#define SPH_MAX_CLASS_MEMBERS 100 + + typedef struct SPH_TweakRule_ + { + const char family[SPH_MAX_NAME_SIZE]; + const FT_UInt ppem; + const char style[SPH_MAX_NAME_SIZE]; + const FT_ULong glyph; + + } SPH_TweakRule; + + + typedef struct SPH_ScaleRule_ + { + const char family[SPH_MAX_NAME_SIZE]; + const FT_UInt ppem; + const char style[SPH_MAX_NAME_SIZE]; + const FT_ULong glyph; + const FT_ULong scale; + + } SPH_ScaleRule; + + + typedef struct SPH_Font_Class_ + { + const char name[SPH_MAX_NAME_SIZE]; + const char member[SPH_MAX_CLASS_MEMBERS][SPH_MAX_NAME_SIZE]; + + } SPH_Font_Class; + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + + /*************************************************************************/ + /* */ + /* The main structure for the interpreter which collects all necessary */ + /* variables and states. */ + /* */ + typedef struct TT_ExecContextRec_ + { + TT_Face face; + TT_Size size; + FT_Memory memory; + + /* instructions state */ + + FT_Error error; /* last execution error */ + + FT_Long top; /* top of exec. stack */ + + FT_UInt stackSize; /* size of exec. stack */ + FT_Long* stack; /* current exec. stack */ + + FT_Long args; + FT_UInt new_top; /* new top after exec. */ + + TT_GlyphZoneRec zp0, /* zone records */ + zp1, + zp2, + pts, + twilight; + + FT_Size_Metrics metrics; + TT_Size_Metrics tt_metrics; /* size metrics */ + + TT_GraphicsState GS; /* current graphics state */ + + FT_Int curRange; /* current code range number */ + FT_Byte* code; /* current code range */ + FT_Long IP; /* current instruction pointer */ + FT_Long codeSize; /* size of current range */ + + FT_Byte opcode; /* current opcode */ + FT_Int length; /* length of current opcode */ + + FT_Bool step_ins; /* true if the interpreter must */ + /* increment IP after ins. exec */ + FT_ULong cvtSize; + FT_Long* cvt; + + FT_UInt glyphSize; /* glyph instructions buffer size */ + FT_Byte* glyphIns; /* glyph instructions buffer */ + + FT_UInt numFDefs; /* number of function defs */ + FT_UInt maxFDefs; /* maximum number of function defs */ + TT_DefArray FDefs; /* table of FDefs entries */ + + FT_UInt numIDefs; /* number of instruction defs */ + FT_UInt maxIDefs; /* maximum number of ins defs */ + TT_DefArray IDefs; /* table of IDefs entries */ + + FT_UInt maxFunc; /* maximum function index */ + FT_UInt maxIns; /* maximum instruction index */ + + FT_Int callTop, /* top of call stack during execution */ + callSize; /* size of call stack */ + TT_CallStack callStack; /* call stack */ + + FT_UShort maxPoints; /* capacity of this context's `pts' */ + FT_Short maxContours; /* record, expressed in points and */ + /* contours. */ + + TT_CodeRangeTable codeRangeTable; /* table of valid code ranges */ + /* useful for the debugger */ + + FT_UShort storeSize; /* size of current storage */ + FT_Long* storage; /* storage area */ + + FT_F26Dot6 period; /* values used for the */ + FT_F26Dot6 phase; /* `SuperRounding' */ + FT_F26Dot6 threshold; + +#if 0 + /* this seems to be unused */ + FT_Int cur_ppem; /* ppem along the current proj vector */ +#endif + + FT_Bool instruction_trap; /* If `True', the interpreter will */ + /* exit after each instruction */ + + TT_GraphicsState default_GS; /* graphics state resulting from */ + /* the prep program */ + FT_Bool is_composite; /* true if the glyph is composite */ + FT_Bool pedantic_hinting; /* true if pedantic interpretation */ + + /* latest interpreter additions */ + + FT_Long F_dot_P; /* dot product of freedom and projection */ + /* vectors */ + TT_Round_Func func_round; /* current rounding function */ + + TT_Project_Func func_project, /* current projection function */ + func_dualproj, /* current dual proj. function */ + func_freeProj; /* current freedom proj. func */ + + TT_Move_Func func_move; /* current point move function */ + TT_Move_Func func_move_orig; /* move original position function */ + + TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ + TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ + TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ + + FT_Bool grayscale; /* are we hinting for grayscale? */ + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Round_Func func_round_sphn; /* subpixel rounding function */ + + FT_Bool grayscale_hinting; /* Using grayscale hinting? */ + FT_Bool subpixel_hinting; /* Using subpixel hinting? */ + FT_Bool native_hinting; /* Using native hinting? */ + FT_Bool ignore_x_mode; /* Standard rendering mode for */ + /* subpixel hinting. On if gray */ + /* or subpixel hinting is on ) */ + + /* The following 4 aren't fully implemented but here for MS rasterizer */ + /* compatibility. */ + FT_Bool compatible_widths; /* compatible widths? */ + FT_Bool symmetrical_smoothing; /* symmetrical_smoothing? */ + FT_Bool bgr; /* bgr instead of rgb? */ + FT_Bool subpixel_positioned; /* subpixel positioned */ + /* (DirectWrite ClearType)? */ + + FT_Int rasterizer_version; /* MS rasterizer version */ + + FT_Bool iup_called; /* IUP called for glyph? */ + + FT_ULong sph_tweak_flags; /* flags to control */ + /* hint tweaks */ + + FT_ULong sph_in_func_flags; /* flags to indicate if in */ + /* special functions */ + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + } TT_ExecContextRec; + + + extern const TT_GraphicsState tt_default_graphics_state; + + +#ifdef TT_USE_BYTECODE_INTERPRETER + FT_LOCAL( FT_Error ) + TT_Goto_CodeRange( TT_ExecContext exec, + FT_Int range, + FT_Long IP ); + + FT_LOCAL( FT_Error ) + TT_Set_CodeRange( TT_ExecContext exec, + FT_Int range, + void* base, + FT_Long length ); + + FT_LOCAL( FT_Error ) + TT_Clear_CodeRange( TT_ExecContext exec, + FT_Int range ); + + + FT_LOCAL( FT_Error ) + Update_Max( FT_Memory memory, + FT_ULong* size, + FT_Long multiplier, + void* _pbuff, + FT_ULong new_max ); +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_New_Context */ + /* */ + /* <Description> */ + /* Queries the face context for a given font. Note that there is */ + /* now a _single_ execution context in the TrueType driver which is */ + /* shared among faces. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* A handle to the execution context. Initialized for `face'. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_EXPORT( TT_ExecContext ) + TT_New_Context( TT_Driver driver ); + + +#ifdef TT_USE_BYTECODE_INTERPRETER + FT_LOCAL( FT_Error ) + TT_Done_Context( TT_ExecContext exec ); + + FT_LOCAL( FT_Error ) + TT_Load_Context( TT_ExecContext exec, + TT_Face face, + TT_Size size ); + + FT_LOCAL( FT_Error ) + TT_Save_Context( TT_ExecContext exec, + TT_Size ins ); + + FT_LOCAL( FT_Error ) + TT_Run_Context( TT_ExecContext exec, + FT_Bool debug ); +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_RunIns */ + /* */ + /* <Description> */ + /* Executes one or more instruction in the execution context. This */ + /* is the main function of the TrueType opcode interpreter. */ + /* */ + /* <Input> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the object manager and debugger should call this function. */ + /* */ + /* This function is publicly exported because it is directly */ + /* invoked by the TrueType debugger. */ + /* */ + FT_EXPORT( FT_Error ) + TT_RunIns( TT_ExecContext exec ); + + +FT_END_HEADER + +#endif /* __TTINTERP_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttobjs.c b/drivers/freetype/src/truetype/ttobjs.c new file mode 100644 index 0000000000..7897efa77a --- /dev/null +++ b/drivers/freetype/src/truetype/ttobjs.c @@ -0,0 +1,1331 @@ +/***************************************************************************/ +/* */ +/* ttobjs.c */ +/* */ +/* Objects manager (body). */ +/* */ +/* Copyright 1996-2013 */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_DRIVER_H + +#include "ttgload.h" +#include "ttpload.h" + +#include "tterrors.h" + +#ifdef TT_USE_BYTECODE_INTERPRETER +#include "ttinterp.h" +#endif + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#include FT_TRUETYPE_UNPATENTED_H +#endif + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif + + /*************************************************************************/ + /* */ + /* 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_ttobjs + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /*************************************************************************/ + /* */ + /* GLYPH ZONE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_glyphzone_done */ + /* */ + /* <Description> */ + /* Deallocate a glyph zone. */ + /* */ + /* <Input> */ + /* zone :: A pointer to the target glyph zone. */ + /* */ + FT_LOCAL_DEF( void ) + tt_glyphzone_done( TT_GlyphZone zone ) + { + FT_Memory memory = zone->memory; + + + if ( memory ) + { + FT_FREE( zone->contours ); + FT_FREE( zone->tags ); + FT_FREE( zone->cur ); + FT_FREE( zone->org ); + FT_FREE( zone->orus ); + + zone->max_points = zone->n_points = 0; + zone->max_contours = zone->n_contours = 0; + zone->memory = NULL; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_glyphzone_new */ + /* */ + /* <Description> */ + /* Allocate a new glyph zone. */ + /* */ + /* <Input> */ + /* memory :: A handle to the current memory object. */ + /* */ + /* maxPoints :: The capacity of glyph zone in points. */ + /* */ + /* maxContours :: The capacity of glyph zone in contours. */ + /* */ + /* <Output> */ + /* zone :: A pointer to the target glyph zone record. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_glyphzone_new( FT_Memory memory, + FT_UShort maxPoints, + FT_Short maxContours, + TT_GlyphZone zone ) + { + FT_Error error; + + + FT_MEM_ZERO( zone, sizeof ( *zone ) ); + zone->memory = memory; + + if ( FT_NEW_ARRAY( zone->org, maxPoints ) || + FT_NEW_ARRAY( zone->cur, maxPoints ) || + FT_NEW_ARRAY( zone->orus, maxPoints ) || + FT_NEW_ARRAY( zone->tags, maxPoints ) || + FT_NEW_ARRAY( zone->contours, maxContours ) ) + { + tt_glyphzone_done( zone ); + } + else + { + zone->max_points = maxPoints; + zone->max_contours = maxContours; + } + + return error; + } +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /* Compare the face with a list of well-known `tricky' fonts. */ + /* This list shall be expanded as we find more of them. */ + + static FT_Bool + tt_check_trickyness_family( FT_String* name ) + { + +#define TRICK_NAMES_MAX_CHARACTERS 16 +#define TRICK_NAMES_COUNT 8 + + static const char trick_names[TRICK_NAMES_COUNT] + [TRICK_NAMES_MAX_CHARACTERS + 1] = + { + "DFKaiSho-SB", /* dfkaisb.ttf */ + "DFKaiShu", + "DFKai-SB", /* kaiu.ttf */ + "HuaTianKaiTi?", /* htkt2.ttf */ + "HuaTianSongTi?", /* htst3.ttf */ + "MingLiU", /* mingliu.ttf & mingliu.ttc */ + "PMingLiU", /* mingliu.ttc */ + "MingLi43", /* mingli.ttf */ + }; + + int nn; + + + for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) + if ( ft_strstr( name, trick_names[nn] ) ) + return TRUE; + + return FALSE; + } + + + /* XXX: This function should be in the `sfnt' module. */ + + /* Some PDF generators clear the checksums in the TrueType header table. */ + /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */ + /* Printer clears the entries for subsetted subtables. We thus have to */ + /* recalculate the checksums where necessary. */ + + static FT_UInt32 + tt_synth_sfnt_checksum( FT_Stream stream, + FT_ULong length ) + { + FT_Error error; + FT_UInt32 checksum = 0; + int i; + + + if ( FT_FRAME_ENTER( length ) ) + return 0; + + for ( ; length > 3; length -= 4 ) + checksum += (FT_UInt32)FT_GET_ULONG(); + + for ( i = 3; length > 0; length --, i-- ) + checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) ); + + FT_FRAME_EXIT(); + + return checksum; + } + + + /* XXX: This function should be in the `sfnt' module. */ + + static FT_ULong + tt_get_sfnt_checksum( TT_Face face, + FT_UShort i ) + { +#if 0 /* if we believe the written value, use following part. */ + if ( face->dir_tables[i].CheckSum ) + return face->dir_tables[i].CheckSum; +#endif + + if ( !face->goto_table ) + return 0; + + if ( face->goto_table( face, + face->dir_tables[i].Tag, + face->root.stream, + NULL ) ) + return 0; + + return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream, + face->dir_tables[i].Length ); + } + + + typedef struct tt_sfnt_id_rec_ + { + FT_ULong CheckSum; + FT_ULong Length; + + } tt_sfnt_id_rec; + + + static FT_Bool + tt_check_trickyness_sfnt_ids( TT_Face face ) + { +#define TRICK_SFNT_IDS_PER_FACE 3 +#define TRICK_SFNT_IDS_NUM_FACES 17 + + static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] + [TRICK_SFNT_IDS_PER_FACE] = { + +#define TRICK_SFNT_ID_cvt 0 +#define TRICK_SFNT_ID_fpgm 1 +#define TRICK_SFNT_ID_prep 2 + + { /* MingLiU 1995 */ + { 0x05bcf058, 0x000002e4 }, /* cvt */ + { 0x28233bf1, 0x000087c4 }, /* fpgm */ + { 0xa344a1ea, 0x000001e1 } /* prep */ + }, + { /* MingLiU 1996- */ + { 0x05bcf058, 0x000002e4 }, /* cvt */ + { 0x28233bf1, 0x000087c4 }, /* fpgm */ + { 0xa344a1eb, 0x000001e1 } /* prep */ + }, + { /* DFKaiShu */ + { 0x11e5ead4, 0x00000350 }, /* cvt */ + { 0x5a30ca3b, 0x00009063 }, /* fpgm */ + { 0x13a42602, 0x0000007e } /* prep */ + }, + { /* HuaTianKaiTi */ + { 0xfffbfffc, 0x00000008 }, /* cvt */ + { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */ + { 0x70020112, 0x00000008 } /* prep */ + }, + { /* HuaTianSongTi */ + { 0xfffbfffc, 0x00000008 }, /* cvt */ + { 0x0a5a0483, 0x00017c39 }, /* fpgm */ + { 0x70020112, 0x00000008 } /* prep */ + }, + { /* NEC fadpop7.ttf */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x40c92555, 0x000000e5 }, /* fpgm */ + { 0xa39b58e3, 0x0000117c } /* prep */ + }, + { /* NEC fadrei5.ttf */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x33c41652, 0x000000e5 }, /* fpgm */ + { 0x26d6c52a, 0x00000f6a } /* prep */ + }, + { /* NEC fangot7.ttf */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x6db1651d, 0x0000019d }, /* fpgm */ + { 0x6c6e4b03, 0x00002492 } /* prep */ + }, + { /* NEC fangyo5.ttf */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x40c92555, 0x000000e5 }, /* fpgm */ + { 0xde51fad0, 0x0000117c } /* prep */ + }, + { /* NEC fankyo5.ttf */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x85e47664, 0x000000e5 }, /* fpgm */ + { 0xa6c62831, 0x00001caa } /* prep */ + }, + { /* NEC fanrgo5.ttf */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x2d891cfd, 0x0000019d }, /* fpgm */ + { 0xa0604633, 0x00001de8 } /* prep */ + }, + { /* NEC fangot5.ttc */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x40aa774c, 0x000001cb }, /* fpgm */ + { 0x9b5caa96, 0x00001f9a } /* prep */ + }, + { /* NEC fanmin3.ttc */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x0d3de9cb, 0x00000141 }, /* fpgm */ + { 0xd4127766, 0x00002280 } /* prep */ + }, + { /* NEC FA-Gothic, 1996 */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x4a692698, 0x000001f0 }, /* fpgm */ + { 0x340d4346, 0x00001fca } /* prep */ + }, + { /* NEC FA-Minchou, 1996 */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0xcd34c604, 0x00000166 }, /* fpgm */ + { 0x6cf31046, 0x000022b0 } /* prep */ + }, + { /* NEC FA-RoundGothicB, 1996 */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0x5da75315, 0x0000019d }, /* fpgm */ + { 0x40745a5f, 0x000022e0 } /* prep */ + }, + { /* NEC FA-RoundGothicM, 1996 */ + { 0x00000000, 0x00000000 }, /* cvt */ + { 0xf055fc48, 0x000001c2 }, /* fpgm */ + { 0x3900ded3, 0x00001e18 } /* prep */ + } + }; + + FT_ULong checksum; + int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES]; + FT_Bool has_cvt, has_fpgm, has_prep; + FT_UShort i; + int j, k; + + + FT_MEM_SET( num_matched_ids, 0, + sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES ); + has_cvt = FALSE; + has_fpgm = FALSE; + has_prep = FALSE; + + for ( i = 0; i < face->num_tables; i++ ) + { + checksum = 0; + + switch( face->dir_tables[i].Tag ) + { + case TTAG_cvt: + k = TRICK_SFNT_ID_cvt; + has_cvt = TRUE; + break; + + case TTAG_fpgm: + k = TRICK_SFNT_ID_fpgm; + has_fpgm = TRUE; + break; + + case TTAG_prep: + k = TRICK_SFNT_ID_prep; + has_prep = TRUE; + break; + + default: + continue; + } + + for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) + if ( face->dir_tables[i].Length == sfnt_id[j][k].Length ) + { + if ( !checksum ) + checksum = tt_get_sfnt_checksum( face, i ); + + if ( sfnt_id[j][k].CheckSum == checksum ) + num_matched_ids[j]++; + + if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) + return TRUE; + } + } + + for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) + { + if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) + num_matched_ids[j] ++; + if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) + num_matched_ids[j] ++; + if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) + num_matched_ids[j] ++; + if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) + return TRUE; + } + + return FALSE; + } + + + static FT_Bool + tt_check_trickyness( FT_Face face ) + { + if ( !face ) + return FALSE; + + /* For first, check the face name for quick check. */ + if ( face->family_name && + tt_check_trickyness_family( face->family_name ) ) + return TRUE; + + /* Type42 fonts may lack `name' tables, we thus try to identify */ + /* tricky fonts by checking the checksums of Type42-persistent */ + /* sfnt tables (`cvt', `fpgm', and `prep'). */ + if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) ) + return TRUE; + + return FALSE; + } + + + /* Check whether `.notdef' is the only glyph in the `loca' table. */ + static FT_Bool + tt_check_single_notdef( FT_Face ttface ) + { + FT_Bool result = FALSE; + + TT_Face face = (TT_Face)ttface; + FT_UInt asize; + FT_ULong i; + FT_ULong glyph_index = 0; + FT_UInt count = 0; + + + for( i = 0; i < face->num_locations; i++ ) + { + tt_face_get_location( face, i, &asize ); + if ( asize > 0 ) + { + count += 1; + if ( count > 1 ) + break; + glyph_index = i; + } + } + + /* Only have a single outline. */ + if ( count == 1 ) + { + if ( glyph_index == 0 ) + result = TRUE; + else + { + /* FIXME: Need to test glyphname == .notdef ? */ + FT_Error error; + char buf[8]; + + + error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 ); + if ( !error && + buf[0] == '.' && !ft_strncmp( buf, ".notdef", 8 ) ) + result = TRUE; + } + } + + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_init */ + /* */ + /* <Description> */ + /* Initialize a given TrueType face object. */ + /* */ + /* <Input> */ + /* stream :: The source font stream. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* <InOut> */ + /* face :: The newly built face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_init( FT_Stream stream, + FT_Face ttface, /* TT_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Library library; + SFNT_Service sfnt; + TT_Face face = (TT_Face)ttface; + + + FT_TRACE2(( "TTF driver\n" )); + + library = ttface->driver->root.library; + + sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); + if ( !sfnt ) + { + FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + + /* create input stream from resource */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + /* check that we have a valid TrueType file */ + error = sfnt->init_face( stream, face, face_index, num_params, params ); + if ( error ) + goto Exit; + + /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ + /* The 0x00020000 tag is completely undocumented; some fonts from */ + /* Arphic made for Chinese Windows 3.1 have this. */ + if ( face->format_tag != 0x00010000L && /* MS fonts */ + face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ + face->format_tag != TTAG_true ) /* Mac fonts */ + { + FT_TRACE2(( " not a TTF font\n" )); + goto Bad_Format; + } + +#ifdef TT_USE_BYTECODE_INTERPRETER + ttface->face_flags |= FT_FACE_FLAG_HINTER; +#endif + + /* If we are performing a simple font format check, exit immediately. */ + if ( face_index < 0 ) + return FT_Err_Ok; + + /* Load font directory */ + error = sfnt->load_face( stream, face, face_index, num_params, params ); + if ( error ) + goto Exit; + + if ( tt_check_trickyness( ttface ) ) + ttface->face_flags |= FT_FACE_FLAG_TRICKY; + + error = tt_face_load_hdmx( face, stream ); + if ( error ) + goto Exit; + + if ( FT_IS_SCALABLE( ttface ) ) + { + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( !ttface->internal->incremental_interface ) + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); + + /* Check the scalable flag based on `loca'. */ + if ( !ttface->internal->incremental_interface && + ttface->num_fixed_sizes && + face->glyph_locations && + tt_check_single_notdef( ttface ) ) + { + FT_TRACE5(( "tt_face_init:" + " Only the `.notdef' glyph has an outline.\n" + " " + " Resetting scalable flag to FALSE.\n" )); + + ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + } + +#else + + if ( !error ) + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); + + /* Check the scalable flag based on `loca'. */ + if ( ttface->num_fixed_sizes && + face->glyph_locations && + tt_check_single_notdef( ttface ) ) + { + FT_TRACE5(( "tt_face_init:" + " Only the `.notdef' glyph has an outline.\n" + " " + " Resetting scalable flag to FALSE.\n" )); + + ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + } + +#endif + + } + +#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ + !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) + + { + FT_Bool unpatented_hinting; + int i; + + + /* Determine whether unpatented hinting is to be used for this face. */ + unpatented_hinting = FT_BOOL + ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); + + for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) + if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) + unpatented_hinting = TRUE; + + if ( !unpatented_hinting ) + ttface->internal->ignore_unpatented_hinter = TRUE; + } + +#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && + !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* initialize standard glyph loading routines */ + TT_Init_Glyph_Loading( face ); + + Exit: + return error; + + Bad_Format: + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_done */ + /* */ + /* <Description> */ + /* Finalize a given face object. */ + /* */ + /* <Input> */ + /* face :: A pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_done( FT_Face ttface ) /* TT_Face */ + { + TT_Face face = (TT_Face)ttface; + FT_Memory memory; + FT_Stream stream; + SFNT_Service sfnt; + + + if ( !face ) + return; + + memory = ttface->memory; + stream = ttface->stream; + sfnt = (SFNT_Service)face->sfnt; + + /* for `extended TrueType formats' (i.e. compressed versions) */ + if ( face->extra.finalizer ) + face->extra.finalizer( face->extra.data ); + + if ( sfnt ) + sfnt->done_face( face ); + + /* freeing the locations table */ + tt_face_done_loca( face ); + + tt_face_free_hdmx( face ); + + /* freeing the CVT */ + FT_FREE( face->cvt ); + face->cvt_size = 0; + + /* freeing the programs */ + FT_FRAME_RELEASE( face->font_program ); + FT_FRAME_RELEASE( face->cvt_program ); + face->font_program_size = 0; + face->cvt_program_size = 0; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + tt_done_blend( memory, face->blend ); + face->blend = NULL; +#endif + } + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /*************************************************************************/ + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_run_fpgm */ + /* */ + /* <Description> */ + /* Run the font program. */ + /* */ + /* <Input> */ + /* size :: A handle to the size object. */ + /* */ + /* pedantic :: Set if bytecode execution should be pedantic. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_run_fpgm( TT_Size size, + FT_Bool pedantic ) + { + TT_Face face = (TT_Face)size->root.face; + TT_ExecContext exec; + FT_Error error; + + + /* debugging instances have their own context */ + if ( size->debug ) + exec = size->context; + else + exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; + + if ( !exec ) + return FT_THROW( Could_Not_Find_Context ); + + TT_Load_Context( exec, face, size ); + + exec->callTop = 0; + exec->top = 0; + + exec->period = 64; + exec->phase = 0; + exec->threshold = 0; + + exec->instruction_trap = FALSE; + exec->F_dot_P = 0x4000L; + + exec->pedantic_hinting = pedantic; + + { + FT_Size_Metrics* metrics = &exec->metrics; + TT_Size_Metrics* tt_metrics = &exec->tt_metrics; + + + metrics->x_ppem = 0; + metrics->y_ppem = 0; + metrics->x_scale = 0; + metrics->y_scale = 0; + + tt_metrics->ppem = 0; + tt_metrics->scale = 0; + tt_metrics->ratio = 0x10000L; + } + + /* allow font program execution */ + TT_Set_CodeRange( exec, + tt_coderange_font, + face->font_program, + face->font_program_size ); + + /* disable CVT and glyph programs coderange */ + TT_Clear_CodeRange( exec, tt_coderange_cvt ); + TT_Clear_CodeRange( exec, tt_coderange_glyph ); + + if ( face->font_program_size > 0 ) + { + error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); + + if ( !error ) + { + FT_TRACE4(( "Executing `fpgm' table.\n" )); + + error = face->interpreter( exec ); + } + } + else + error = FT_Err_Ok; + + if ( !error ) + TT_Save_Context( exec, size ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_run_prep */ + /* */ + /* <Description> */ + /* Run the control value program. */ + /* */ + /* <Input> */ + /* size :: A handle to the size object. */ + /* */ + /* pedantic :: Set if bytecode execution should be pedantic. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_run_prep( TT_Size size, + FT_Bool pedantic ) + { + TT_Face face = (TT_Face)size->root.face; + TT_ExecContext exec; + FT_Error error; + + + /* debugging instances have their own context */ + if ( size->debug ) + exec = size->context; + else + exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; + + if ( !exec ) + return FT_THROW( Could_Not_Find_Context ); + + TT_Load_Context( exec, face, size ); + + exec->callTop = 0; + exec->top = 0; + + exec->instruction_trap = FALSE; + + exec->pedantic_hinting = pedantic; + + TT_Set_CodeRange( exec, + tt_coderange_cvt, + face->cvt_program, + face->cvt_program_size ); + + TT_Clear_CodeRange( exec, tt_coderange_glyph ); + + if ( face->cvt_program_size > 0 ) + { + error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); + + if ( !error && !size->debug ) + { + FT_TRACE4(( "Executing `prep' table.\n" )); + + error = face->interpreter( exec ); + } + } + else + error = FT_Err_Ok; + + /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */ + /* graphics state variables to be modified by the CVT program. */ + + exec->GS.dualVector.x = 0x4000; + exec->GS.dualVector.y = 0; + exec->GS.projVector.x = 0x4000; + exec->GS.projVector.y = 0x0; + exec->GS.freeVector.x = 0x4000; + exec->GS.freeVector.y = 0x0; + + exec->GS.rp0 = 0; + exec->GS.rp1 = 0; + exec->GS.rp2 = 0; + + exec->GS.gep0 = 1; + exec->GS.gep1 = 1; + exec->GS.gep2 = 1; + + exec->GS.loop = 1; + + /* save as default graphics state */ + size->GS = exec->GS; + + TT_Save_Context( exec, size ); + + return error; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + static void + tt_size_done_bytecode( FT_Size ftsize ) + { + TT_Size size = (TT_Size)ftsize; + TT_Face face = (TT_Face)ftsize->face; + FT_Memory memory = face->root.memory; + + + if ( size->debug ) + { + /* the debug context must be deleted by the debugger itself */ + size->context = NULL; + size->debug = FALSE; + } + + FT_FREE( size->cvt ); + size->cvt_size = 0; + + /* free storage area */ + FT_FREE( size->storage ); + size->storage_size = 0; + + /* twilight zone */ + tt_glyphzone_done( &size->twilight ); + + FT_FREE( size->function_defs ); + FT_FREE( size->instruction_defs ); + + size->num_function_defs = 0; + size->max_function_defs = 0; + size->num_instruction_defs = 0; + size->max_instruction_defs = 0; + + size->max_func = 0; + size->max_ins = 0; + + size->bytecode_ready = 0; + size->cvt_ready = 0; + } + + + /* Initialize bytecode-related fields in the size object. */ + /* We do this only if bytecode interpretation is really needed. */ + static FT_Error + tt_size_init_bytecode( FT_Size ftsize, + FT_Bool pedantic ) + { + FT_Error error; + TT_Size size = (TT_Size)ftsize; + TT_Face face = (TT_Face)ftsize->face; + FT_Memory memory = face->root.memory; + FT_Int i; + + FT_UShort n_twilight; + TT_MaxProfile* maxp = &face->max_profile; + + + size->bytecode_ready = 1; + size->cvt_ready = 0; + + size->max_function_defs = maxp->maxFunctionDefs; + size->max_instruction_defs = maxp->maxInstructionDefs; + + size->num_function_defs = 0; + size->num_instruction_defs = 0; + + size->max_func = 0; + size->max_ins = 0; + + size->cvt_size = face->cvt_size; + size->storage_size = maxp->maxStorage; + + /* Set default metrics */ + { + TT_Size_Metrics* metrics = &size->ttmetrics; + + + metrics->rotated = FALSE; + metrics->stretched = FALSE; + + /* set default compensation (all 0) */ + for ( i = 0; i < 4; i++ ) + metrics->compensations[i] = 0; + } + + /* allocate function defs, instruction defs, cvt, and storage area */ + if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || + FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || + FT_NEW_ARRAY( size->cvt, size->cvt_size ) || + FT_NEW_ARRAY( size->storage, size->storage_size ) ) + goto Exit; + + /* reserve twilight zone */ + n_twilight = maxp->maxTwilightPoints; + + /* there are 4 phantom points (do we need this?) */ + n_twilight += 4; + + error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); + if ( error ) + goto Exit; + + size->twilight.n_points = n_twilight; + + size->GS = tt_default_graphics_state; + + /* set `face->interpreter' according to the debug hook present */ + { + FT_Library library = face->root.driver->root.library; + + + face->interpreter = (TT_Interpreter) + library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; + if ( !face->interpreter ) + face->interpreter = (TT_Interpreter)TT_RunIns; + } + + /* Fine, now run the font program! */ + error = tt_size_run_fpgm( size, pedantic ); + + Exit: + if ( error ) + tt_size_done_bytecode( ftsize ); + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_size_ready_bytecode( TT_Size size, + FT_Bool pedantic ) + { + FT_Error error = FT_Err_Ok; + + + if ( !size->bytecode_ready ) + { + error = tt_size_init_bytecode( (FT_Size)size, pedantic ); + if ( error ) + goto Exit; + } + + /* rescale CVT when needed */ + if ( !size->cvt_ready ) + { + FT_UInt i; + TT_Face face = (TT_Face)size->root.face; + + + /* Scale the cvt values to the new ppem. */ + /* We use by default the y ppem to scale the CVT. */ + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + + /* all twilight points are originally zero */ + for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) + { + size->twilight.org[i].x = 0; + size->twilight.org[i].y = 0; + size->twilight.cur[i].x = 0; + size->twilight.cur[i].y = 0; + } + + /* clear storage area */ + for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) + size->storage[i] = 0; + + size->GS = tt_default_graphics_state; + + error = tt_size_run_prep( size, pedantic ); + if ( !error ) + size->cvt_ready = 1; + } + + Exit: + return error; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_init */ + /* */ + /* <Description> */ + /* Initialize a new TrueType size object. */ + /* */ + /* <InOut> */ + /* size :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_init( FT_Size ttsize ) /* TT_Size */ + { + TT_Size size = (TT_Size)ttsize; + FT_Error error = FT_Err_Ok; + +#ifdef TT_USE_BYTECODE_INTERPRETER + size->bytecode_ready = 0; + size->cvt_ready = 0; +#endif + + size->ttmetrics.valid = FALSE; + size->strike_index = 0xFFFFFFFFUL; + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_done */ + /* */ + /* <Description> */ + /* The TrueType size object finalizer. */ + /* */ + /* <Input> */ + /* size :: A handle to the target size object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_size_done( FT_Size ttsize ) /* TT_Size */ + { + TT_Size size = (TT_Size)ttsize; + + +#ifdef TT_USE_BYTECODE_INTERPRETER + if ( size->bytecode_ready ) + tt_size_done_bytecode( ttsize ); +#endif + + size->ttmetrics.valid = FALSE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_reset */ + /* */ + /* <Description> */ + /* Reset a TrueType size when resolutions and character dimensions */ + /* have been changed. */ + /* */ + /* <Input> */ + /* size :: A handle to the target size object. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_reset( TT_Size size ) + { + TT_Face face; + FT_Error error = FT_Err_Ok; + FT_Size_Metrics* metrics; + + + size->ttmetrics.valid = FALSE; + + face = (TT_Face)size->root.face; + + metrics = &size->metrics; + + /* copy the result from base layer */ + *metrics = size->root.metrics; + + if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) + return FT_THROW( Invalid_PPem ); + + /* This bit flag, if set, indicates that the ppems must be */ + /* rounded to integers. Nearly all TrueType fonts have this bit */ + /* set, as hinting won't work really well otherwise. */ + /* */ + if ( face->header.Flags & 8 ) + { + metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, + face->root.units_per_EM ); + metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, + face->root.units_per_EM ); + + metrics->ascender = + FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); + metrics->descender = + FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); + metrics->height = + FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); + metrics->max_advance = + FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, + metrics->x_scale ) ); + } + + /* compute new transformation */ + if ( metrics->x_ppem >= metrics->y_ppem ) + { + size->ttmetrics.scale = metrics->x_scale; + size->ttmetrics.ppem = metrics->x_ppem; + size->ttmetrics.x_ratio = 0x10000L; + size->ttmetrics.y_ratio = FT_DivFix( metrics->y_ppem, + metrics->x_ppem ); + } + else + { + size->ttmetrics.scale = metrics->y_scale; + size->ttmetrics.ppem = metrics->y_ppem; + size->ttmetrics.x_ratio = FT_DivFix( metrics->x_ppem, + metrics->y_ppem ); + size->ttmetrics.y_ratio = 0x10000L; + } + +#ifdef TT_USE_BYTECODE_INTERPRETER + size->cvt_ready = 0; +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + if ( !error ) + size->ttmetrics.valid = TRUE; + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_driver_init */ + /* */ + /* <Description> */ + /* Initialize a given TrueType driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ + { + +#ifdef TT_USE_BYTECODE_INTERPRETER + + TT_Driver driver = (TT_Driver)ttdriver; + + + if ( !TT_New_Context( driver ) ) + return FT_THROW( Could_Not_Find_Context ); + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + driver->interpreter_version = TT_INTERPRETER_VERSION_38; +#else + driver->interpreter_version = TT_INTERPRETER_VERSION_35; +#endif + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_UNUSED( ttdriver ); + +#endif /* !TT_USE_BYTECODE_INTERPRETER */ + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_driver_done */ + /* */ + /* <Description> */ + /* Finalize a given TrueType driver. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target TrueType driver. */ + /* */ + FT_LOCAL_DEF( void ) + tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ + { +#ifdef TT_USE_BYTECODE_INTERPRETER + TT_Driver driver = (TT_Driver)ttdriver; + + + /* destroy the execution context */ + if ( driver->context ) + { + TT_Done_Context( driver->context ); + driver->context = NULL; + } +#else + FT_UNUSED( ttdriver ); +#endif + + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_slot_init */ + /* */ + /* <Description> */ + /* Initialize a new slot object. */ + /* */ + /* <InOut> */ + /* slot :: A handle to the slot object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_slot_init( FT_GlyphSlot slot ) + { + return FT_GlyphLoader_CreateExtra( slot->internal->loader ); + } + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttobjs.h b/drivers/freetype/src/truetype/ttobjs.h new file mode 100644 index 0000000000..a11dd3752a --- /dev/null +++ b/drivers/freetype/src/truetype/ttobjs.h @@ -0,0 +1,442 @@ +/***************************************************************************/ +/* */ +/* ttobjs.h */ +/* */ +/* Objects manager (specification). */ +/* */ +/* Copyright 1996-2009, 2011-2013 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 __TTOBJS_H__ +#define __TTOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Driver */ + /* */ + /* <Description> */ + /* A handle to a TrueType driver object. */ + /* */ + typedef struct TT_DriverRec_* TT_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Instance */ + /* */ + /* <Description> */ + /* A handle to a TrueType size object. */ + /* */ + typedef struct TT_SizeRec_* TT_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a TrueType glyph slot object. */ + /* */ + /* <Note> */ + /* This is a direct typedef of FT_GlyphSlot, as there is nothing */ + /* specific about the TrueType glyph slot. */ + /* */ + typedef FT_GlyphSlot TT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GraphicsState */ + /* */ + /* <Description> */ + /* The TrueType graphics state used during bytecode interpretation. */ + /* */ + typedef struct TT_GraphicsState_ + { + FT_UShort rp0; + FT_UShort rp1; + FT_UShort rp2; + + FT_UnitVector dualVector; + FT_UnitVector projVector; + FT_UnitVector freeVector; + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_Bool both_x_axis; +#endif + + FT_Long loop; + FT_F26Dot6 minimum_distance; + FT_Int round_state; + + FT_Bool auto_flip; + FT_F26Dot6 control_value_cutin; + FT_F26Dot6 single_width_cutin; + FT_F26Dot6 single_width_value; + FT_Short delta_base; + FT_Short delta_shift; + + FT_Byte instruct_control; + /* According to Greg Hitchcock from Microsoft, the `scan_control' */ + /* variable as documented in the TrueType specification is a 32-bit */ + /* integer; the high-word part holds the SCANTYPE value, the low-word */ + /* part the SCANCTRL value. We separate it into two fields. */ + FT_Bool scan_control; + FT_Int scan_type; + + FT_UShort gep0; + FT_UShort gep1; + FT_UShort gep2; + + } TT_GraphicsState; + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_LOCAL( void ) + tt_glyphzone_done( TT_GlyphZone zone ); + + FT_LOCAL( FT_Error ) + tt_glyphzone_new( FT_Memory memory, + FT_UShort maxPoints, + FT_Short maxContours, + TT_GlyphZone zone ); + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + + /*************************************************************************/ + /* */ + /* EXECUTION SUBTABLES */ + /* */ + /* These sub-tables relate to instruction execution. */ + /* */ + /*************************************************************************/ + + +#define TT_MAX_CODE_RANGES 3 + + + /*************************************************************************/ + /* */ + /* There can only be 3 active code ranges at once: */ + /* - the Font Program */ + /* - the CVT Program */ + /* - a glyph's instructions set */ + /* */ + typedef enum TT_CodeRange_Tag_ + { + tt_coderange_none = 0, + tt_coderange_font, + tt_coderange_cvt, + tt_coderange_glyph + + } TT_CodeRange_Tag; + + + typedef struct TT_CodeRange_ + { + FT_Byte* base; + FT_ULong size; + + } TT_CodeRange; + + typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES]; + + + /*************************************************************************/ + /* */ + /* Defines a function/instruction definition record. */ + /* */ + typedef struct TT_DefRecord_ + { + FT_Int range; /* in which code range is it located? */ + FT_Long start; /* where does it start? */ + FT_Long end; /* where does it end? */ + FT_UInt opc; /* function #, or instruction code */ + FT_Bool active; /* is it active? */ + FT_Bool inline_delta; /* is function that defines inline delta? */ + FT_ULong sph_fdef_flags; /* flags to identify special functions */ + + } TT_DefRecord, *TT_DefArray; + + + /*************************************************************************/ + /* */ + /* Subglyph transformation record. */ + /* */ + typedef struct TT_Transform_ + { + FT_Fixed xx, xy; /* transformation matrix coefficients */ + FT_Fixed yx, yy; + FT_F26Dot6 ox, oy; /* offsets */ + + } TT_Transform; + + + /*************************************************************************/ + /* */ + /* A note regarding non-squared pixels: */ + /* */ + /* (This text will probably go into some docs at some time; for now, it */ + /* is kept here to explain some definitions in the TT_Size_Metrics */ + /* record). */ + /* */ + /* The CVT is a one-dimensional array containing values that control */ + /* certain important characteristics in a font, like the height of all */ + /* capitals, all lowercase letter, default spacing or stem width/height. */ + /* */ + /* These values are found in FUnits in the font file, and must be scaled */ + /* to pixel coordinates before being used by the CVT and glyph programs. */ + /* Unfortunately, when using distinct x and y resolutions (or distinct x */ + /* and y pointsizes), there are two possible scalings. */ + /* */ + /* A first try was to implement a `lazy' scheme where all values were */ + /* scaled when first used. However, while some values are always used */ + /* in the same direction, some others are used under many different */ + /* circumstances and orientations. */ + /* */ + /* I have found a simpler way to do the same, and it even seems to work */ + /* in most of the cases: */ + /* */ + /* - All CVT values are scaled to the maximum ppem size. */ + /* */ + /* - When performing a read or write in the CVT, a ratio factor is used */ + /* to perform adequate scaling. Example: */ + /* */ + /* x_ppem = 14 */ + /* y_ppem = 10 */ + /* */ + /* We choose ppem = x_ppem = 14 as the CVT scaling size. All cvt */ + /* entries are scaled to it. */ + /* */ + /* x_ratio = 1.0 */ + /* y_ratio = y_ppem/ppem (< 1.0) */ + /* */ + /* We compute the current ratio like: */ + /* */ + /* - If projVector is horizontal, */ + /* ratio = x_ratio = 1.0 */ + /* */ + /* - if projVector is vertical, */ + /* ratio = y_ratio */ + /* */ + /* - else, */ + /* ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) */ + /* */ + /* Reading a cvt value returns */ + /* ratio * cvt[index] */ + /* */ + /* Writing a cvt value in pixels: */ + /* cvt[index] / ratio */ + /* */ + /* The current ppem is simply */ + /* ratio * ppem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Metrics used by the TrueType size and context objects. */ + /* */ + typedef struct TT_Size_Metrics_ + { + /* for non-square pixels */ + FT_Long x_ratio; + FT_Long y_ratio; + + FT_UShort ppem; /* maximum ppem size */ + FT_Long ratio; /* current ratio */ + FT_Fixed scale; + + FT_F26Dot6 compensations[4]; /* device-specific compensations */ + + FT_Bool valid; + + FT_Bool rotated; /* `is the glyph rotated?'-flag */ + FT_Bool stretched; /* `is the glyph stretched?'-flag */ + + } TT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* TrueType size class. */ + /* */ + typedef struct TT_SizeRec_ + { + FT_SizeRec root; + + /* we have our own copy of metrics so that we can modify */ + /* it without affecting auto-hinting (when used) */ + FT_Size_Metrics metrics; + + TT_Size_Metrics ttmetrics; + + FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ + +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_UInt num_function_defs; /* number of function definitions */ + FT_UInt max_function_defs; + TT_DefArray function_defs; /* table of function definitions */ + + FT_UInt num_instruction_defs; /* number of ins. definitions */ + FT_UInt max_instruction_defs; + TT_DefArray instruction_defs; /* table of ins. definitions */ + + FT_UInt max_func; + FT_UInt max_ins; + + TT_CodeRangeTable codeRangeTable; + + TT_GraphicsState GS; + + FT_ULong cvt_size; /* the scaled control value table */ + FT_Long* cvt; + + FT_UShort storage_size; /* The storage area is now part of */ + FT_Long* storage; /* the instance */ + + TT_GlyphZoneRec twilight; /* The instance's twilight zone */ + + /* debugging variables */ + + /* When using the debugger, we must keep the */ + /* execution context tied to the instance */ + /* object rather than asking it on demand. */ + + FT_Bool debug; + TT_ExecContext context; + + FT_Bool bytecode_ready; + FT_Bool cvt_ready; + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + } TT_SizeRec; + + + /*************************************************************************/ + /* */ + /* TrueType driver class. */ + /* */ + typedef struct TT_DriverRec_ + { + FT_DriverRec root; + + TT_ExecContext context; /* execution context */ + TT_GlyphZoneRec zone; /* glyph loader points zone */ + + FT_UInt interpreter_version; + + } TT_DriverRec; + + + /* Note: All of the functions below (except tt_size_reset()) are used */ + /* as function pointers in a FT_Driver_ClassRec. Therefore their */ + /* parameters are of types FT_Face, FT_Size, etc., rather than TT_Face, */ + /* TT_Size, etc., so that the compiler can confirm that the types and */ + /* number of parameters are correct. In all cases the FT_xxx types are */ + /* cast to their TT_xxx counterparts inside the functions since FreeType */ + /* will always use the TT driver to create them. */ + + + /*************************************************************************/ + /* */ + /* Face functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_face_init( FT_Stream stream, + FT_Face ttface, /* TT_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + tt_face_done( FT_Face ttface ); /* TT_Face */ + + + /*************************************************************************/ + /* */ + /* Size functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_size_init( FT_Size ttsize ); /* TT_Size */ + + FT_LOCAL( void ) + tt_size_done( FT_Size ttsize ); /* TT_Size */ + +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_LOCAL( FT_Error ) + tt_size_run_fpgm( TT_Size size, + FT_Bool pedantic ); + + FT_LOCAL( FT_Error ) + tt_size_run_prep( TT_Size size, + FT_Bool pedantic ); + + FT_LOCAL( FT_Error ) + tt_size_ready_bytecode( TT_Size size, + FT_Bool pedantic ); + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + FT_LOCAL( FT_Error ) + tt_size_reset( TT_Size size ); + + + /*************************************************************************/ + /* */ + /* Driver functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_driver_init( FT_Module ttdriver ); /* TT_Driver */ + + FT_LOCAL( void ) + tt_driver_done( FT_Module ttdriver ); /* TT_Driver */ + + + /*************************************************************************/ + /* */ + /* Slot functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_slot_init( FT_GlyphSlot slot ); + + + /* auxiliary */ +#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) + + +FT_END_HEADER + +#endif /* __TTOBJS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttpic.c b/drivers/freetype/src/truetype/ttpic.c new file mode 100644 index 0000000000..edefae72c5 --- /dev/null +++ b/drivers/freetype/src/truetype/ttpic.c @@ -0,0 +1,101 @@ +/***************************************************************************/ +/* */ +/* ttpic.c */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009, 2010, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ttpic.h" +#include "tterrors.h" + + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ttdriver.c */ + FT_Error + FT_Create_Class_tt_services( FT_Library library, + FT_ServiceDescRec** output_class ); + void + FT_Destroy_Class_tt_services( FT_Library library, + FT_ServiceDescRec* clazz ); + void + FT_Init_Class_tt_service_gx_multi_masters( + FT_Service_MultiMastersRec* sv_mm ); + void + FT_Init_Class_tt_service_truetype_glyf( + FT_Service_TTGlyfRec* sv_ttglyf ); + + + void + tt_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + + + if ( pic_container->truetype ) + { + TTModulePIC* container = (TTModulePIC*)pic_container->truetype; + + + if ( container->tt_services ) + FT_Destroy_Class_tt_services( library, container->tt_services ); + container->tt_services = NULL; + FT_FREE( container ); + pic_container->truetype = NULL; + } + } + + + FT_Error + tt_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + TTModulePIC* container = NULL; + FT_Memory memory = library->memory; + + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof ( *container ) ); + pic_container->truetype = container; + + /* initialize pointer table - this is how the module usually */ + /* expects this data */ + error = FT_Create_Class_tt_services( library, + &container->tt_services ); + if ( error ) + goto Exit; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Init_Class_tt_service_gx_multi_masters( + &container->tt_service_gx_multi_masters ); +#endif + FT_Init_Class_tt_service_truetype_glyf( + &container->tt_service_truetype_glyf ); + + Exit: + if ( error ) + tt_driver_class_pic_free( library ); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttpic.h b/drivers/freetype/src/truetype/ttpic.h new file mode 100644 index 0000000000..cfb4ee6281 --- /dev/null +++ b/drivers/freetype/src/truetype/ttpic.h @@ -0,0 +1,81 @@ +/***************************************************************************/ +/* */ +/* ttpic.h */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009, 2012, 2013 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __TTPIC_H__ +#define __TTPIC_H__ + + +FT_BEGIN_HEADER + +#ifndef FT_CONFIG_OPTION_PIC + +#define TT_SERVICES_GET tt_services +#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters +#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf +#define TT_SERVICE_PROPERTIES_GET tt_service_properties + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_TRUETYPE_GLYF_H +#include FT_SERVICE_PROPERTIES_H + + + typedef struct TTModulePIC_ + { + FT_ServiceDescRec* tt_services; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_MultiMastersRec tt_service_gx_multi_masters; +#endif + FT_Service_TTGlyfRec tt_service_truetype_glyf; + FT_Service_PropertiesRec tt_service_properties; + + } TTModulePIC; + + +#define GET_PIC( lib ) \ + ( (TTModulePIC*)((lib)->pic_container.truetype) ) +#define TT_SERVICES_GET \ + ( GET_PIC( library )->tt_services ) +#define TT_SERVICE_GX_MULTI_MASTERS_GET \ + ( GET_PIC( library )->tt_service_gx_multi_masters ) +#define TT_SERVICE_TRUETYPE_GLYF_GET \ + ( GET_PIC( library )->tt_service_truetype_glyf ) +#define TT_SERVICE_PROPERTIES_GET \ + ( GET_PIC( library )->tt_service_properties ) + + + /* see ttpic.c for the implementation */ + void + tt_driver_class_pic_free( FT_Library library ); + + FT_Error + tt_driver_class_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* __TTPIC_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttpload.c b/drivers/freetype/src/truetype/ttpload.c new file mode 100644 index 0000000000..9723a515b9 --- /dev/null +++ b/drivers/freetype/src/truetype/ttpload.c @@ -0,0 +1,599 @@ +/***************************************************************************/ +/* */ +/* ttpload.c */ +/* */ +/* TrueType-specific tables loader (body). */ +/* */ +/* Copyright 1996-2002, 2004-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H + +#include "ttpload.h" + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif + +#include "tterrors.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_ttpload + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_loca */ + /* */ + /* <Description> */ + /* Load the locations table. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_loca( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_ULong table_len; + FT_Int shift; + + + /* we need the size of the `glyf' table for malformed `loca' tables */ + error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len ); + + /* it is possible that a font doesn't have a glyf table at all */ + /* or its size is zero */ + if ( FT_ERR_EQ( error, Table_Missing ) ) + face->glyf_len = 0; + else if ( error ) + goto Exit; + + FT_TRACE2(( "Locations " )); + error = face->goto_table( face, TTAG_loca, stream, &table_len ); + if ( error ) + { + error = FT_THROW( Locations_Missing ); + goto Exit; + } + + if ( face->header.Index_To_Loc_Format != 0 ) + { + shift = 2; + + if ( table_len >= 0x40000L ) + { + FT_TRACE2(( "table too large\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + face->num_locations = table_len >> shift; + } + else + { + shift = 1; + + if ( table_len >= 0x20000L ) + { + FT_TRACE2(( "table too large\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + face->num_locations = table_len >> shift; + } + + if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 ) + { + FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", + face->num_locations - 1, face->root.num_glyphs )); + + /* we only handle the case where `maxp' gives a larger value */ + if ( face->num_locations <= (FT_ULong)face->root.num_glyphs ) + { + FT_Long new_loca_len = + ( (FT_Long)( face->root.num_glyphs ) + 1 ) << shift; + + TT_Table entry = face->dir_tables; + TT_Table limit = entry + face->num_tables; + + FT_Long pos = FT_Stream_Pos( stream ); + FT_Long dist = 0x7FFFFFFFL; + + + /* compute the distance to next table in font file */ + for ( ; entry < limit; entry++ ) + { + FT_Long diff = entry->Offset - pos; + + + if ( diff > 0 && diff < dist ) + dist = diff; + } + + if ( entry == limit ) + { + /* `loca' is the last table */ + dist = stream->size - pos; + } + + if ( new_loca_len <= dist ) + { + face->num_locations = face->root.num_glyphs + 1; + table_len = new_loca_len; + + FT_TRACE2(( "adjusting num_locations to %d\n", + face->num_locations )); + } + } + } + + /* + * Extract the frame. We don't need to decompress it since + * we are able to parse it directly. + */ + if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) ) + goto Exit; + + FT_TRACE2(( "loaded\n" )); + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_ULong ) + tt_face_get_location( TT_Face face, + FT_UInt gindex, + FT_UInt *asize ) + { + FT_ULong pos1, pos2; + FT_Byte* p; + FT_Byte* p_limit; + + + pos1 = pos2 = 0; + + if ( gindex < face->num_locations ) + { + if ( face->header.Index_To_Loc_Format != 0 ) + { + p = face->glyph_locations + gindex * 4; + p_limit = face->glyph_locations + face->num_locations * 4; + + pos1 = FT_NEXT_ULONG( p ); + pos2 = pos1; + + if ( p + 4 <= p_limit ) + pos2 = FT_NEXT_ULONG( p ); + } + else + { + p = face->glyph_locations + gindex * 2; + p_limit = face->glyph_locations + face->num_locations * 2; + + pos1 = FT_NEXT_USHORT( p ); + pos2 = pos1; + + if ( p + 2 <= p_limit ) + pos2 = FT_NEXT_USHORT( p ); + + pos1 <<= 1; + pos2 <<= 1; + } + } + + /* Check broken location data */ + if ( pos1 > face->glyf_len ) + { + FT_TRACE1(( "tt_face_get_location:" + " too large offset=0x%08lx found for gid=0x%04lx," + " exceeding the end of glyf table (0x%08lx)\n", + pos1, gindex, face->glyf_len )); + *asize = 0; + return 0; + } + + if ( pos2 > face->glyf_len ) + { + FT_TRACE1(( "tt_face_get_location:" + " too large offset=0x%08lx found for gid=0x%04lx," + " truncate at the end of glyf table (0x%08lx)\n", + pos2, gindex + 1, face->glyf_len )); + pos2 = face->glyf_len; + } + + /* The `loca' table must be ordered; it refers to the length of */ + /* an entry as the difference between the current and the next */ + /* position. However, there do exist (malformed) fonts which */ + /* don't obey this rule, so we are only able to provide an */ + /* upper bound for the size. */ + /* */ + /* We get (intentionally) a wrong, non-zero result in case the */ + /* `glyf' table is missing. */ + if ( pos2 >= pos1 ) + *asize = (FT_UInt)( pos2 - pos1 ); + else + *asize = (FT_UInt)( face->glyf_len - pos1 ); + + return pos1; + } + + + FT_LOCAL_DEF( void ) + tt_face_done_loca( TT_Face face ) + { + FT_Stream stream = face->root.stream; + + + FT_FRAME_RELEASE( face->glyph_locations ); + face->num_locations = 0; + } + + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_cvt */ + /* */ + /* <Description> */ + /* Load the control value table into a face object. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_cvt( TT_Face face, + FT_Stream stream ) + { +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong table_len; + + + FT_TRACE2(( "CVT " )); + + error = face->goto_table( face, TTAG_cvt, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing\n" )); + + face->cvt_size = 0; + face->cvt = NULL; + error = FT_Err_Ok; + + goto Exit; + } + + face->cvt_size = table_len / 2; + + if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) + goto Exit; + + if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) + goto Exit; + + { + FT_Short* cur = face->cvt; + FT_Short* limit = cur + face->cvt_size; + + + for ( ; cur < limit; cur++ ) + *cur = FT_GET_SHORT(); + } + + FT_FRAME_EXIT(); + FT_TRACE2(( "loaded\n" )); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( face->doblend ) + error = tt_face_vary_cvt( face, stream ); +#endif + + Exit: + return error; + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_UNUSED( face ); + FT_UNUSED( stream ); + + return FT_Err_Ok; + +#endif + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_fpgm */ + /* */ + /* <Description> */ + /* Load the font program. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_fpgm( TT_Face face, + FT_Stream stream ) + { +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_Error error; + FT_ULong table_len; + + + FT_TRACE2(( "Font program " )); + + /* The font program is optional */ + error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); + if ( error ) + { + face->font_program = NULL; + face->font_program_size = 0; + error = FT_Err_Ok; + + FT_TRACE2(( "is missing\n" )); + } + else + { + face->font_program_size = table_len; + if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) + goto Exit; + + FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); + } + + Exit: + return error; + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_UNUSED( face ); + FT_UNUSED( stream ); + + return FT_Err_Ok; + +#endif + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_prep */ + /* */ + /* <Description> */ + /* Load the cvt program. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_prep( TT_Face face, + FT_Stream stream ) + { +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_Error error; + FT_ULong table_len; + + + FT_TRACE2(( "Prep program " )); + + error = face->goto_table( face, TTAG_prep, stream, &table_len ); + if ( error ) + { + face->cvt_program = NULL; + face->cvt_program_size = 0; + error = FT_Err_Ok; + + FT_TRACE2(( "is missing\n" )); + } + else + { + face->cvt_program_size = table_len; + if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) + goto Exit; + + FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); + } + + Exit: + return error; + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_UNUSED( face ); + FT_UNUSED( stream ); + + return FT_Err_Ok; + +#endif + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_hdmx */ + /* */ + /* <Description> */ + /* Load the `hdmx' table into the face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_hdmx( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UInt version, nn, num_records; + FT_ULong table_size, record_size; + FT_Byte* p; + FT_Byte* limit; + + + /* this table is optional */ + error = face->goto_table( face, TTAG_hdmx, stream, &table_size ); + if ( error || table_size < 8 ) + return FT_Err_Ok; + + if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) ) + goto Exit; + + p = face->hdmx_table; + limit = p + table_size; + + version = FT_NEXT_USHORT( p ); + num_records = FT_NEXT_USHORT( p ); + record_size = FT_NEXT_ULONG( p ); + + /* The maximum number of bytes in an hdmx device record is the */ + /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ + /* the reason why `record_size' is a long (which we read as */ + /* unsigned long for convenience). In practice, two bytes */ + /* sufficient to hold the size value. */ + /* */ + /* There are at least two fonts, HANNOM-A and HANNOM-B version */ + /* 2.0 (2005), which get this wrong: The upper two bytes of */ + /* the size value are set to 0xFF instead of 0x00. We catch */ + /* and fix this. */ + + if ( record_size >= 0xFFFF0000UL ) + record_size &= 0xFFFFU; + + /* The limit for `num_records' is a heuristic value. */ + + if ( version != 0 || num_records > 255 || record_size > 0x10001L ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) ) + goto Fail; + + for ( nn = 0; nn < num_records; nn++ ) + { + if ( p + record_size > limit ) + break; + + face->hdmx_record_sizes[nn] = p[0]; + p += record_size; + } + + face->hdmx_record_count = nn; + face->hdmx_table_size = table_size; + face->hdmx_record_size = record_size; + + Exit: + return error; + + Fail: + FT_FRAME_RELEASE( face->hdmx_table ); + face->hdmx_table_size = 0; + goto Exit; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_hdmx( TT_Face face ) + { + FT_Stream stream = face->root.stream; + FT_Memory memory = stream->memory; + + + FT_FREE( face->hdmx_record_sizes ); + FT_FRAME_RELEASE( face->hdmx_table ); + } + + + /*************************************************************************/ + /* */ + /* Return the advance width table for a given pixel size if it is found */ + /* in the font's `hdmx' table (if any). */ + /* */ + FT_LOCAL_DEF( FT_Byte* ) + tt_face_get_device_metrics( TT_Face face, + FT_UInt ppem, + FT_UInt gindex ) + { + FT_UInt nn; + FT_Byte* result = NULL; + FT_ULong record_size = face->hdmx_record_size; + FT_Byte* record = face->hdmx_table + 8; + + + for ( nn = 0; nn < face->hdmx_record_count; nn++ ) + if ( face->hdmx_record_sizes[nn] == ppem ) + { + gindex += 2; + if ( gindex < record_size ) + result = record + nn * record_size + gindex; + break; + } + + return result; + } + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttpload.h b/drivers/freetype/src/truetype/ttpload.h new file mode 100644 index 0000000000..f61ac079ce --- /dev/null +++ b/drivers/freetype/src/truetype/ttpload.h @@ -0,0 +1,75 @@ +/***************************************************************************/ +/* */ +/* ttpload.h */ +/* */ +/* TrueType-specific tables loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTPLOAD_H__ +#define __TTPLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_loca( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( FT_ULong ) + tt_face_get_location( TT_Face face, + FT_UInt gindex, + FT_UInt *asize ); + + FT_LOCAL( void ) + tt_face_done_loca( TT_Face face ); + + FT_LOCAL( FT_Error ) + tt_face_load_cvt( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( FT_Error ) + tt_face_load_fpgm( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_prep( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_hdmx( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( void ) + tt_face_free_hdmx( TT_Face face ); + + + FT_LOCAL( FT_Byte* ) + tt_face_get_device_metrics( TT_Face face, + FT_UInt ppem, + FT_UInt gindex ); + +FT_END_HEADER + +#endif /* __TTPLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttsubpix.c b/drivers/freetype/src/truetype/ttsubpix.c new file mode 100644 index 0000000000..28470ad655 --- /dev/null +++ b/drivers/freetype/src/truetype/ttsubpix.c @@ -0,0 +1,1011 @@ +/***************************************************************************/ +/* */ +/* ttsubpix.c */ +/* */ +/* TrueType Subpixel Hinting. */ +/* */ +/* Copyright 2010-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_TAGS_H +#include FT_OUTLINE_H +#include FT_TRUETYPE_DRIVER_H + +#include "ttsubpix.h" + + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + /*************************************************************************/ + /* */ + /* These rules affect how the TT Interpreter does hinting, with the */ + /* goal of doing subpixel hinting by (in general) ignoring x moves. */ + /* Some of these rules are fixes that go above and beyond the */ + /* stated techniques in the MS whitepaper on Cleartype, due to */ + /* artifacts in many glyphs. So, these rules make some glyphs render */ + /* better than they do in the MS rasterizer. */ + /* */ + /* "" string or 0 int/char indicates to apply to all glyphs. */ + /* "-" used as dummy placeholders, but any non-matching string works. */ + /* */ + /* Some of this could arguably be implemented in fontconfig, however: */ + /* */ + /* - Fontconfig can't set things on a glyph-by-glyph basis. */ + /* - The tweaks that happen here are very low-level, from an average */ + /* user's point of view and are best implemented in the hinter. */ + /* */ + /* The goal is to make the subpixel hinting techniques as generalized */ + /* as possible across all fonts to prevent the need for extra rules such */ + /* as these. */ + /* */ + /* The rule structure is designed so that entirely new rules can easily */ + /* be added when a new compatibility feature is discovered. */ + /* */ + /* The rule structures could also use some enhancement to handle ranges. */ + /* */ + /* ****************** WORK IN PROGRESS ******************* */ + /* */ + + /* These are `classes' of fonts that can be grouped together and used in */ + /* rules below. A blank entry "" is required at the end of these! */ +#define FAMILY_CLASS_RULES_SIZE 7 + + static const SPH_Font_Class FAMILY_CLASS_Rules + [FAMILY_CLASS_RULES_SIZE] = + { + { "MS Legacy Fonts", + { "Aharoni", + "Andale Mono", + "Andalus", + "Angsana New", + "AngsanaUPC", + "Arabic Transparent", + "Arial Black", + "Arial Narrow", + "Arial Unicode MS", + "Arial", + "Batang", + "Browallia New", + "BrowalliaUPC", + "Comic Sans MS", + "Cordia New", + "CordiaUPC", + "Courier New", + "DFKai-SB", + "David Transparent", + "David", + "DilleniaUPC", + "Estrangelo Edessa", + "EucrosiaUPC", + "FangSong_GB2312", + "Fixed Miriam Transparent", + "FrankRuehl", + "Franklin Gothic Medium", + "FreesiaUPC", + "Garamond", + "Gautami", + "Georgia", + "Gulim", + "Impact", + "IrisUPC", + "JasmineUPC", + "KaiTi_GB2312", + "KodchiangUPC", + "Latha", + "Levenim MT", + "LilyUPC", + "Lucida Console", + "Lucida Sans Unicode", + "MS Gothic", + "MS Mincho", + "MV Boli", + "Mangal", + "Marlett", + "Microsoft Sans Serif", + "Mingliu", + "Miriam Fixed", + "Miriam Transparent", + "Miriam", + "Narkisim", + "Palatino Linotype", + "Raavi", + "Rod Transparent", + "Rod", + "Shruti", + "SimHei", + "Simplified Arabic Fixed", + "Simplified Arabic", + "Simsun", + "Sylfaen", + "Symbol", + "Tahoma", + "Times New Roman", + "Traditional Arabic", + "Trebuchet MS", + "Tunga", + "Verdana", + "Webdings", + "Wingdings", + "", + }, + }, + { "Core MS Legacy Fonts", + { "Arial Black", + "Arial Narrow", + "Arial Unicode MS", + "Arial", + "Comic Sans MS", + "Courier New", + "Garamond", + "Georgia", + "Impact", + "Lucida Console", + "Lucida Sans Unicode", + "Microsoft Sans Serif", + "Palatino Linotype", + "Tahoma", + "Times New Roman", + "Trebuchet MS", + "Verdana", + "", + }, + }, + { "Apple Legacy Fonts", + { "Geneva", + "Times", + "Monaco", + "Century", + "Chalkboard", + "Lobster", + "Century Gothic", + "Optima", + "Lucida Grande", + "Gill Sans", + "Baskerville", + "Helvetica", + "Helvetica Neue", + "", + }, + }, + { "Legacy Sans Fonts", + { "Andale Mono", + "Arial Unicode MS", + "Arial", + "Century Gothic", + "Comic Sans MS", + "Franklin Gothic Medium", + "Geneva", + "Lucida Console", + "Lucida Grande", + "Lucida Sans Unicode", + "Lucida Sans Typewriter", + "Microsoft Sans Serif", + "Monaco", + "Tahoma", + "Trebuchet MS", + "Verdana", + "", + }, + }, + + { "Misc Legacy Fonts", + { "Dark Courier", "", }, }, + { "Verdana Clones", + { "DejaVu Sans", + "Bitstream Vera Sans", "", }, }, + { "Verdana and Clones", + { "DejaVu Sans", + "Bitstream Vera Sans", + "Verdana", "", }, }, + }; + + + /* Define this to force natural (i.e. not bitmap-compatible) widths. */ + /* The default leans strongly towards natural widths except for a few */ + /* legacy fonts where a selective combination produces nicer results. */ +/* #define FORCE_NATURAL_WIDTHS */ + + + /* Define `classes' of styles that can be grouped together and used in */ + /* rules below. A blank entry "" is required at the end of these! */ +#define STYLE_CLASS_RULES_SIZE 5 + + const SPH_Font_Class STYLE_CLASS_Rules + [STYLE_CLASS_RULES_SIZE] = + { + { "Regular Class", + { "Regular", + "Book", + "Medium", + "Roman", + "Normal", + "", + }, + }, + { "Regular/Italic Class", + { "Regular", + "Book", + "Medium", + "Italic", + "Oblique", + "Roman", + "Normal", + "", + }, + }, + { "Bold/BoldItalic Class", + { "Bold", + "Bold Italic", + "Black", + "", + }, + }, + { "Bold/Italic/BoldItalic Class", + { "Bold", + "Bold Italic", + "Black", + "Italic", + "Oblique", + "", + }, + }, + { "Regular/Bold Class", + { "Regular", + "Book", + "Medium", + "Normal", + "Roman", + "Bold", + "Black", + "", + }, + }, + }; + + + /* Force special legacy fixes for fonts. */ +#define COMPATIBILITY_MODE_RULES_SIZE 1 + + const SPH_TweakRule COMPATIBILITY_MODE_Rules + [COMPATIBILITY_MODE_RULES_SIZE] = + { + { "-", 0, "", 0 }, + }; + + + /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting. */ +#define PIXEL_HINTING_RULES_SIZE 2 + + const SPH_TweakRule PIXEL_HINTING_Rules + [PIXEL_HINTING_RULES_SIZE] = + { + /* these characters are almost always safe */ + { "Courier New", 12, "Italic", 'z' }, + { "Courier New", 11, "Italic", 'z' }, + }; + + + /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */ +#define DO_SHPIX_RULES_SIZE 1 + + const SPH_TweakRule DO_SHPIX_Rules + [DO_SHPIX_RULES_SIZE] = + { + { "-", 0, "", 0 }, + }; + + + /* Skip Y moves that start with a point that is not on a Y pixel */ + /* boundary and don't move that point to a Y pixel boundary. */ +#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 4 + + const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules + [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = + { + /* fix vwxyz thinness*/ + { "Consolas", 0, "", 0 }, + /* Fix thin middle stems */ + { "Core MS Legacy Fonts", 0, "Regular", 0 }, + /* Cyrillic small letter I */ + { "Legacy Sans Fonts", 0, "", 0 }, + /* Fix artifacts with some Regular & Bold */ + { "Verdana Clones", 0, "", 0 }, + }; + + +#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 + + const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions + [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + { + /* Fixes < and > */ + { "Courier New", 0, "Regular", 0 }, + }; + + + /* Skip Y moves that start with a point that is not on a Y pixel */ + /* boundary and don't move that point to a Y pixel boundary. */ +#define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE 2 + + const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules + [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] = + { + /* Maintain thickness of diagonal in 'N' */ + { "Times New Roman", 0, "Regular/Bold Class", 'N' }, + { "Georgia", 0, "Regular/Bold Class", 'N' }, + }; + + + /* Skip Y moves that move a point off a Y pixel boundary. */ +#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 1 + + const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules + [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = + { + { "-", 0, "", 0 }, + }; + + +#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 + + const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions + [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + { + { "-", 0, "", 0 }, + }; + + + /* Round moves that don't move a point to a Y pixel boundary. */ +#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 2 + + const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules + [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = + { + /* Droid font instructions don't snap Y to pixels */ + { "Droid Sans", 0, "Regular/Italic Class", 0 }, + { "Droid Sans Mono", 0, "", 0 }, + }; + + +#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 + + const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions + [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + { + { "-", 0, "", 0 }, + }; + + + /* Allow a Direct_Move along X freedom vector if matched. */ +#define ALLOW_X_DMOVE_RULES_SIZE 1 + + const SPH_TweakRule ALLOW_X_DMOVE_Rules + [ALLOW_X_DMOVE_RULES_SIZE] = + { + /* Fixes vanishing diagonal in 4 */ + { "Verdana", 0, "Regular", '4' }, + }; + + + /* Return MS rasterizer version 35 if matched. */ +#define RASTERIZER_35_RULES_SIZE 8 + + const SPH_TweakRule RASTERIZER_35_Rules + [RASTERIZER_35_RULES_SIZE] = + { + /* This seems to be the only way to make these look good */ + { "Times New Roman", 0, "Regular", 'i' }, + { "Times New Roman", 0, "Regular", 'j' }, + { "Times New Roman", 0, "Regular", 'm' }, + { "Times New Roman", 0, "Regular", 'r' }, + { "Times New Roman", 0, "Regular", 'a' }, + { "Times New Roman", 0, "Regular", 'n' }, + { "Times New Roman", 0, "Regular", 'p' }, + { "Times", 0, "", 0 }, + }; + + + /* Don't round to the subpixel grid. Round to pixel grid. */ +#define NORMAL_ROUND_RULES_SIZE 1 + + const SPH_TweakRule NORMAL_ROUND_Rules + [NORMAL_ROUND_RULES_SIZE] = + { + /* Fix serif thickness for certain ppems */ + /* Can probably be generalized somehow */ + { "Courier New", 0, "", 0 }, + }; + + + /* Skip IUP instructions if matched. */ +#define SKIP_IUP_RULES_SIZE 1 + + const SPH_TweakRule SKIP_IUP_Rules + [SKIP_IUP_RULES_SIZE] = + { + { "Arial", 13, "Regular", 'a' }, + }; + + + /* Skip MIAP Twilight hack if matched. */ +#define MIAP_HACK_RULES_SIZE 1 + + const SPH_TweakRule MIAP_HACK_Rules + [MIAP_HACK_RULES_SIZE] = + { + { "Geneva", 12, "", 0 }, + }; + + + /* Skip DELTAP instructions if matched. */ +#define ALWAYS_SKIP_DELTAP_RULES_SIZE 23 + + const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules + [ALWAYS_SKIP_DELTAP_RULES_SIZE] = + { + { "Georgia", 0, "Regular", 'k' }, + /* fix various problems with e in different versions */ + { "Trebuchet MS", 14, "Regular", 'e' }, + { "Trebuchet MS", 13, "Regular", 'e' }, + { "Trebuchet MS", 15, "Regular", 'e' }, + { "Trebuchet MS", 0, "Italic", 'v' }, + { "Trebuchet MS", 0, "Italic", 'w' }, + { "Trebuchet MS", 0, "Regular", 'Y' }, + { "Arial", 11, "Regular", 's' }, + /* prevent problems with '3' and others */ + { "Verdana", 10, "Regular", 0 }, + { "Verdana", 9, "Regular", 0 }, + /* Cyrillic small letter short I */ + { "Legacy Sans Fonts", 0, "", 0x438 }, + { "Legacy Sans Fonts", 0, "", 0x439 }, + { "Arial", 10, "Regular", '6' }, + { "Arial", 0, "Bold/BoldItalic Class", 'a' }, + /* Make horizontal stems consistent with the rest */ + { "Arial", 24, "Bold", 'a' }, + { "Arial", 25, "Bold", 'a' }, + { "Arial", 24, "Bold", 's' }, + { "Arial", 25, "Bold", 's' }, + { "Arial", 34, "Bold", 's' }, + { "Arial", 35, "Bold", 's' }, + { "Arial", 36, "Bold", 's' }, + { "Arial", 25, "Regular", 's' }, + { "Arial", 26, "Regular", 's' }, + }; + + + /* Always do DELTAP instructions if matched. */ +#define ALWAYS_DO_DELTAP_RULES_SIZE 1 + + const SPH_TweakRule ALWAYS_DO_DELTAP_Rules + [ALWAYS_DO_DELTAP_RULES_SIZE] = + { + { "-", 0, "", 0 }, + }; + + + /* Don't allow ALIGNRP after IUP. */ +#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE 1 + + static const SPH_TweakRule NO_ALIGNRP_AFTER_IUP_Rules + [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] = + { + /* Prevent creation of dents in outline */ + { "-", 0, "", 0 }, + }; + + + /* Don't allow DELTAP after IUP. */ +#define NO_DELTAP_AFTER_IUP_RULES_SIZE 1 + + static const SPH_TweakRule NO_DELTAP_AFTER_IUP_Rules + [NO_DELTAP_AFTER_IUP_RULES_SIZE] = + { + { "-", 0, "", 0 }, + }; + + + /* Don't allow CALL after IUP. */ +#define NO_CALL_AFTER_IUP_RULES_SIZE 1 + + static const SPH_TweakRule NO_CALL_AFTER_IUP_Rules + [NO_CALL_AFTER_IUP_RULES_SIZE] = + { + /* Prevent creation of dents in outline */ + { "-", 0, "", 0 }, + }; + + + /* De-embolden these glyphs slightly. */ +#define DEEMBOLDEN_RULES_SIZE 9 + + static const SPH_TweakRule DEEMBOLDEN_Rules + [DEEMBOLDEN_RULES_SIZE] = + { + { "Courier New", 0, "Bold", 'A' }, + { "Courier New", 0, "Bold", 'W' }, + { "Courier New", 0, "Bold", 'w' }, + { "Courier New", 0, "Bold", 'M' }, + { "Courier New", 0, "Bold", 'X' }, + { "Courier New", 0, "Bold", 'K' }, + { "Courier New", 0, "Bold", 'x' }, + { "Courier New", 0, "Bold", 'z' }, + { "Courier New", 0, "Bold", 'v' }, + }; + + + /* Embolden these glyphs slightly. */ +#define EMBOLDEN_RULES_SIZE 2 + + static const SPH_TweakRule EMBOLDEN_Rules + [EMBOLDEN_RULES_SIZE] = + { + { "Courier New", 0, "Regular", 0 }, + { "Courier New", 0, "Italic", 0 }, + }; + + + /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7 */ + /* similar to Windows XP. */ +#define TIMES_NEW_ROMAN_HACK_RULES_SIZE 12 + + static const SPH_TweakRule TIMES_NEW_ROMAN_HACK_Rules + [TIMES_NEW_ROMAN_HACK_RULES_SIZE] = + { + { "Times New Roman", 16, "Italic", '2' }, + { "Times New Roman", 16, "Italic", '5' }, + { "Times New Roman", 16, "Italic", '7' }, + { "Times New Roman", 16, "Regular", '2' }, + { "Times New Roman", 16, "Regular", '5' }, + { "Times New Roman", 16, "Regular", '7' }, + { "Times New Roman", 17, "Italic", '2' }, + { "Times New Roman", 17, "Italic", '5' }, + { "Times New Roman", 17, "Italic", '7' }, + { "Times New Roman", 17, "Regular", '2' }, + { "Times New Roman", 17, "Regular", '5' }, + { "Times New Roman", 17, "Regular", '7' }, + }; + + + /* This fudges distance on 2 to get rid of the vanishing stem issue. */ + /* A real solution to this is certainly welcome. */ +#define COURIER_NEW_2_HACK_RULES_SIZE 15 + + static const SPH_TweakRule COURIER_NEW_2_HACK_Rules + [COURIER_NEW_2_HACK_RULES_SIZE] = + { + { "Courier New", 10, "Regular", '2' }, + { "Courier New", 11, "Regular", '2' }, + { "Courier New", 12, "Regular", '2' }, + { "Courier New", 13, "Regular", '2' }, + { "Courier New", 14, "Regular", '2' }, + { "Courier New", 15, "Regular", '2' }, + { "Courier New", 16, "Regular", '2' }, + { "Courier New", 17, "Regular", '2' }, + { "Courier New", 18, "Regular", '2' }, + { "Courier New", 19, "Regular", '2' }, + { "Courier New", 20, "Regular", '2' }, + { "Courier New", 21, "Regular", '2' }, + { "Courier New", 22, "Regular", '2' }, + { "Courier New", 23, "Regular", '2' }, + { "Courier New", 24, "Regular", '2' }, + }; + + +#ifndef FORCE_NATURAL_WIDTHS + + /* Use compatible widths with these glyphs. Compatible widths is always */ + /* on when doing B/W TrueType instructing, but is used selectively here, */ + /* typically on glyphs with 3 or more vertical stems. */ +#define COMPATIBLE_WIDTHS_RULES_SIZE 38 + + static const SPH_TweakRule COMPATIBLE_WIDTHS_Rules + [COMPATIBLE_WIDTHS_RULES_SIZE] = + { + { "Arial Unicode MS", 12, "Regular Class", 'm' }, + { "Arial Unicode MS", 14, "Regular Class", 'm' }, + /* Cyrillic small letter sha */ + { "Arial", 10, "Regular Class", 0x448 }, + { "Arial", 11, "Regular Class", 'm' }, + { "Arial", 12, "Regular Class", 'm' }, + /* Cyrillic small letter sha */ + { "Arial", 12, "Regular Class", 0x448 }, + { "Arial", 13, "Regular Class", 0x448 }, + { "Arial", 14, "Regular Class", 'm' }, + /* Cyrillic small letter sha */ + { "Arial", 14, "Regular Class", 0x448 }, + { "Arial", 15, "Regular Class", 0x448 }, + { "Arial", 17, "Regular Class", 'm' }, + { "DejaVu Sans", 15, "Regular Class", 0 }, + { "Microsoft Sans Serif", 11, "Regular Class", 0 }, + { "Microsoft Sans Serif", 12, "Regular Class", 0 }, + { "Segoe UI", 11, "Regular Class", 0 }, + { "Monaco", 0, "Regular Class", 0 }, + { "Segoe UI", 12, "Regular Class", 'm' }, + { "Segoe UI", 14, "Regular Class", 'm' }, + { "Tahoma", 11, "Regular Class", 0 }, + { "Times New Roman", 16, "Regular Class", 'c' }, + { "Times New Roman", 16, "Regular Class", 'm' }, + { "Times New Roman", 16, "Regular Class", 'o' }, + { "Times New Roman", 16, "Regular Class", 'w' }, + { "Trebuchet MS", 11, "Regular Class", 0 }, + { "Trebuchet MS", 12, "Regular Class", 0 }, + { "Trebuchet MS", 14, "Regular Class", 0 }, + { "Trebuchet MS", 15, "Regular Class", 0 }, + { "Ubuntu", 12, "Regular Class", 'm' }, + /* Cyrillic small letter sha */ + { "Verdana", 10, "Regular Class", 0x448 }, + { "Verdana", 11, "Regular Class", 0x448 }, + { "Verdana and Clones", 12, "Regular Class", 'i' }, + { "Verdana and Clones", 12, "Regular Class", 'j' }, + { "Verdana and Clones", 12, "Regular Class", 'l' }, + { "Verdana and Clones", 12, "Regular Class", 'm' }, + { "Verdana and Clones", 13, "Regular Class", 'i' }, + { "Verdana and Clones", 13, "Regular Class", 'j' }, + { "Verdana and Clones", 13, "Regular Class", 'l' }, + { "Verdana and Clones", 14, "Regular Class", 'm' }, + }; + + + /* Scaling slightly in the x-direction prior to hinting results in */ + /* more visually pleasing glyphs in certain cases. */ + /* This sometimes needs to be coordinated with compatible width rules. */ + /* A value of 1000 corresponds to a scaled value of 1.0. */ + +#define X_SCALING_RULES_SIZE 50 + + static const SPH_ScaleRule X_SCALING_Rules[X_SCALING_RULES_SIZE] = + { + { "DejaVu Sans", 12, "Regular Class", 'm', 950 }, + { "Verdana and Clones", 12, "Regular Class", 'a', 1100 }, + { "Verdana and Clones", 13, "Regular Class", 'a', 1050 }, + { "Arial", 11, "Regular Class", 'm', 975 }, + { "Arial", 12, "Regular Class", 'm', 1050 }, + /* Cyrillic small letter el */ + { "Arial", 13, "Regular Class", 0x43B, 950 }, + { "Arial", 13, "Regular Class", 'o', 950 }, + { "Arial", 13, "Regular Class", 'e', 950 }, + { "Arial", 14, "Regular Class", 'm', 950 }, + /* Cyrillic small letter el */ + { "Arial", 15, "Regular Class", 0x43B, 925 }, + { "Bitstream Vera Sans", 10, "Regular/Italic Class", 0, 1100 }, + { "Bitstream Vera Sans", 12, "Regular/Italic Class", 0, 1050 }, + { "Bitstream Vera Sans", 16, "Regular Class", 0, 1050 }, + { "Bitstream Vera Sans", 9, "Regular/Italic Class", 0, 1050 }, + { "DejaVu Sans", 12, "Regular Class", 'l', 975 }, + { "DejaVu Sans", 12, "Regular Class", 'i', 975 }, + { "DejaVu Sans", 12, "Regular Class", 'j', 975 }, + { "DejaVu Sans", 13, "Regular Class", 'l', 950 }, + { "DejaVu Sans", 13, "Regular Class", 'i', 950 }, + { "DejaVu Sans", 13, "Regular Class", 'j', 950 }, + { "DejaVu Sans", 10, "Regular/Italic Class", 0, 1100 }, + { "DejaVu Sans", 12, "Regular/Italic Class", 0, 1050 }, + { "Georgia", 10, "", 0, 1050 }, + { "Georgia", 11, "", 0, 1100 }, + { "Georgia", 12, "", 0, 1025 }, + { "Georgia", 13, "", 0, 1050 }, + { "Georgia", 16, "", 0, 1050 }, + { "Georgia", 17, "", 0, 1030 }, + { "Liberation Sans", 12, "Regular Class", 'm', 1100 }, + { "Lucida Grande", 11, "Regular Class", 'm', 1100 }, + { "Microsoft Sans Serif", 11, "Regular Class", 'm', 950 }, + { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1050 }, + { "Segoe UI", 12, "Regular Class", 'H', 1050 }, + { "Segoe UI", 12, "Regular Class", 'm', 1050 }, + { "Segoe UI", 14, "Regular Class", 'm', 1050 }, + { "Tahoma", 11, "Regular Class", 'i', 975 }, + { "Tahoma", 11, "Regular Class", 'l', 975 }, + { "Tahoma", 11, "Regular Class", 'j', 900 }, + { "Tahoma", 11, "Regular Class", 'm', 918 }, + { "Verdana", 10, "Regular/Italic Class", 0, 1100 }, + { "Verdana", 12, "Regular Class", 'm', 975 }, + { "Verdana", 12, "Regular/Italic Class", 0, 1050 }, + { "Verdana", 13, "Regular/Italic Class", 'i', 950 }, + { "Verdana", 13, "Regular/Italic Class", 'j', 950 }, + { "Verdana", 13, "Regular/Italic Class", 'l', 950 }, + { "Verdana", 16, "Regular Class", 0, 1050 }, + { "Verdana", 9, "Regular/Italic Class", 0, 1050 }, + { "Times New Roman", 16, "Regular Class", 'm', 918 }, + { "Trebuchet MS", 11, "Regular Class", 'm', 800 }, + { "Trebuchet MS", 12, "Regular Class", 'm', 800 }, + }; + +#else + +#define COMPATIBLE_WIDTHS_RULES_SIZE 1 + + static const SPH_TweakRule COMPATIBLE_WIDTHS_Rules + [COMPATIBLE_WIDTHS_RULES_SIZE] = + { + { "-", 0, "", 0 }, + }; + + +#define X_SCALING_RULES_SIZE 1 + + static const SPH_ScaleRule X_SCALING_Rules + [X_SCALING_RULES_SIZE] = + { + { "-", 0, "", 0, 1000 }, + }; + +#endif /* FORCE_NATURAL_WIDTHS */ + + + FT_LOCAL_DEF( FT_Bool ) + is_member_of_family_class( const FT_String* detected_font_name, + const FT_String* rule_font_name ) + { + FT_UInt i, j; + + + /* Does font name match rule family? */ + if ( strcmp( detected_font_name, rule_font_name ) == 0 ) + return TRUE; + + /* Is font name a wildcard ""? */ + if ( strcmp( rule_font_name, "" ) == 0 ) + return TRUE; + + /* Is font name contained in a class list? */ + for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ ) + { + if ( strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 ) + { + for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ ) + { + if ( strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 ) + continue; + if ( strcmp( FAMILY_CLASS_Rules[i].member[j], + detected_font_name ) == 0 ) + return TRUE; + } + } + } + + return FALSE; + } + + + FT_LOCAL_DEF( FT_Bool ) + is_member_of_style_class( const FT_String* detected_font_style, + const FT_String* rule_font_style ) + { + FT_UInt i, j; + + + /* Does font style match rule style? */ + if ( strcmp( detected_font_style, rule_font_style ) == 0 ) + return TRUE; + + /* Is font style a wildcard ""? */ + if ( strcmp( rule_font_style, "" ) == 0 ) + return TRUE; + + /* Is font style contained in a class list? */ + for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ ) + { + if ( strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 ) + { + for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ ) + { + if ( strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 ) + continue; + if ( strcmp( STYLE_CLASS_Rules[i].member[j], + detected_font_style ) == 0 ) + return TRUE; + } + } + } + + return FALSE; + } + + + FT_LOCAL_DEF( FT_Bool ) + sph_test_tweak( TT_Face face, + const FT_String* family, + FT_UInt ppem, + const FT_String* style, + FT_UInt glyph_index, + const SPH_TweakRule* rule, + FT_UInt num_rules ) + { + FT_UInt i; + + + /* rule checks may be able to be optimized further */ + for ( i = 0; i < num_rules; i++ ) + { + if ( family && + ( is_member_of_family_class ( family, rule[i].family ) ) ) + if ( rule[i].ppem == 0 || + rule[i].ppem == ppem ) + if ( style && + is_member_of_style_class ( style, rule[i].style ) ) + if ( rule[i].glyph == 0 || + FT_Get_Char_Index( (FT_Face)face, + rule[i].glyph ) == glyph_index ) + return TRUE; + } + + return FALSE; + } + + + static FT_UInt + scale_test_tweak( TT_Face face, + const FT_String* family, + FT_UInt ppem, + const FT_String* style, + FT_UInt glyph_index, + const SPH_ScaleRule* rule, + FT_UInt num_rules ) + { + FT_UInt i; + + + /* rule checks may be able to be optimized further */ + for ( i = 0; i < num_rules; i++ ) + { + if ( family && + ( is_member_of_family_class ( family, rule[i].family ) ) ) + if ( rule[i].ppem == 0 || + rule[i].ppem == ppem ) + if ( style && + is_member_of_style_class( style, rule[i].style ) ) + if ( rule[i].glyph == 0 || + FT_Get_Char_Index( (FT_Face)face, + rule[i].glyph ) == glyph_index ) + return rule[i].scale; + } + + return 1000; + } + + + FT_LOCAL_DEF( FT_UInt ) + sph_test_tweak_x_scaling( TT_Face face, + const FT_String* family, + FT_UInt ppem, + const FT_String* style, + FT_UInt glyph_index ) + { + return scale_test_tweak( face, family, ppem, style, glyph_index, + X_SCALING_Rules, X_SCALING_RULES_SIZE ); + } + + +#define TWEAK_RULES( x ) \ + if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ + x##_Rules, x##_RULES_SIZE ) ) \ + loader->exec->sph_tweak_flags |= SPH_TWEAK_##x; + +#define TWEAK_RULES_EXCEPTIONS( x ) \ + if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ + x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \ + loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x; + + + FT_LOCAL_DEF( void ) + sph_set_tweaks( TT_Loader loader, + FT_UInt glyph_index ) + { + TT_Face face = (TT_Face)loader->face; + FT_String* family = face->root.family_name; + int ppem = loader->size->metrics.x_ppem; + FT_String* style = face->root.style_name; + + + /* don't apply rules if style isn't set */ + if ( !face->root.style_name ) + return; + +#ifdef SPH_DEBUG_MORE_VERBOSE + printf( "%s,%d,%s,%c=%d ", + family, ppem, style, glyph_index, glyph_index ); +#endif + + TWEAK_RULES( PIXEL_HINTING ); + + if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING ) + { + loader->exec->ignore_x_mode = FALSE; + return; + } + + TWEAK_RULES( ALLOW_X_DMOVE ); + TWEAK_RULES( ALWAYS_DO_DELTAP ); + TWEAK_RULES( ALWAYS_SKIP_DELTAP ); + TWEAK_RULES( DEEMBOLDEN ); + TWEAK_RULES( DO_SHPIX ); + TWEAK_RULES( EMBOLDEN ); + TWEAK_RULES( MIAP_HACK ); + TWEAK_RULES( NORMAL_ROUND ); + TWEAK_RULES( NO_ALIGNRP_AFTER_IUP ); + TWEAK_RULES( NO_CALL_AFTER_IUP ); + TWEAK_RULES( NO_DELTAP_AFTER_IUP ); + TWEAK_RULES( RASTERIZER_35 ); + TWEAK_RULES( SKIP_IUP ); + + TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES ); + TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES ); + + TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES_DELTAP ); + + TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES ); + TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES ); + + TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES ); + TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES ); + + if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) + { + if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 ) + { + loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; + loader->exec->size->cvt_ready = FALSE; + + tt_size_ready_bytecode( + loader->exec->size, + FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); + } + else + loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; + } + else + { + if ( loader->exec->rasterizer_version != + SPH_OPTION_SET_RASTERIZER_VERSION ) + { + loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; + loader->exec->size->cvt_ready = FALSE; + + tt_size_ready_bytecode( + loader->exec->size, + FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); + } + else + loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; + } + + if ( IS_HINTED( loader->load_flags ) ) + { + TWEAK_RULES( TIMES_NEW_ROMAN_HACK ); + TWEAK_RULES( COURIER_NEW_2_HACK ); + } + + if ( sph_test_tweak( face, family, ppem, style, glyph_index, + COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) ) + loader->exec->face->sph_compatibility_mode = TRUE; + + + if ( IS_HINTED( loader->load_flags ) ) + { + if ( sph_test_tweak( face, family, ppem, style, glyph_index, + COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) ) + loader->exec->compatible_widths |= TRUE; + } + } + +#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + /* ANSI C doesn't like empty source files */ + typedef int _tt_subpix_dummy; + +#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + +/* END */ diff --git a/drivers/freetype/src/truetype/ttsubpix.h b/drivers/freetype/src/truetype/ttsubpix.h new file mode 100644 index 0000000000..8a54fc7cc7 --- /dev/null +++ b/drivers/freetype/src/truetype/ttsubpix.h @@ -0,0 +1,110 @@ +/***************************************************************************/ +/* */ +/* ttsubpix.h */ +/* */ +/* TrueType Subpixel Hinting. */ +/* */ +/* Copyright 2010-2013 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 __TTSUBPIX_H__ +#define __TTSUBPIX_H__ + +#include <ft2build.h> +#include "ttobjs.h" +#include "ttinterp.h" + + +FT_BEGIN_HEADER + + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + + /*************************************************************************/ + /* */ + /* ID flags to identify special functions at FDEF and runtime. */ + /* */ + /* */ +#define SPH_FDEF_INLINE_DELTA_1 0x0000001 +#define SPH_FDEF_INLINE_DELTA_2 0x0000002 +#define SPH_FDEF_DIAGONAL_STROKE 0x0000004 +#define SPH_FDEF_VACUFORM_ROUND_1 0x0000008 +#define SPH_FDEF_TTFAUTOHINT_1 0x0000010 +#define SPH_FDEF_SPACING_1 0x0000020 +#define SPH_FDEF_SPACING_2 0x0000040 +#define SPH_FDEF_TYPEMAN_STROKES 0x0000080 +#define SPH_FDEF_TYPEMAN_DIAGENDCTRL 0x0000100 + + + /*************************************************************************/ + /* */ + /* Tweak flags that are set for each glyph by the below rules. */ + /* */ + /* */ +#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001 +#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002 +#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004 +#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008 +#define SPH_TWEAK_DEEMBOLDEN 0x0000010 +#define SPH_TWEAK_DO_SHPIX 0x0000020 +#define SPH_TWEAK_EMBOLDEN 0x0000040 +#define SPH_TWEAK_MIAP_HACK 0x0000080 +#define SPH_TWEAK_NORMAL_ROUND 0x0000100 +#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200 +#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400 +#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800 +#define SPH_TWEAK_PIXEL_HINTING 0x0001000 +#define SPH_TWEAK_RASTERIZER_35 0x0002000 +#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000 +#define SPH_TWEAK_SKIP_IUP 0x0008000 +#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000 +#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000 +#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000 +#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000 + + + FT_LOCAL( FT_Bool ) + sph_test_tweak( TT_Face face, + const FT_String* family, + FT_UInt ppem, + const FT_String* style, + FT_UInt glyph_index, + const SPH_TweakRule* rule, + FT_UInt num_rules ); + + FT_LOCAL( FT_UInt ) + sph_test_tweak_x_scaling( TT_Face face, + const FT_String* family, + FT_UInt ppem, + const FT_String* style, + FT_UInt glyph_index ); + + FT_LOCAL( void ) + sph_set_tweaks( TT_Loader loader, + FT_UInt glyph_index ); + + + /* These macros are defined absent a method for setting them */ +#define SPH_OPTION_BITMAP_WIDTHS FALSE +#define SPH_OPTION_SET_SUBPIXEL TRUE +#define SPH_OPTION_SET_GRAYSCALE FALSE +#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE +#define SPH_OPTION_SET_RASTERIZER_VERSION 38 + +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + +FT_END_HEADER + +#endif /* __TTSUBPIX_H__ */ + +/* END */ diff --git a/drivers/freetype/src/type1/Jamfile b/drivers/freetype/src/type1/Jamfile new file mode 100644 index 0000000000..8e366baae5 --- /dev/null +++ b/drivers/freetype/src/type1/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/type1 Jamfile +# +# Copyright 2001 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) type1 ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = t1afm t1driver t1objs t1load t1gload t1parse ; + } + else + { + _sources = type1 ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/type1 Jamfile diff --git a/drivers/freetype/src/type1/module.mk b/drivers/freetype/src/type1/module.mk new file mode 100644 index 0000000000..ade0210d76 --- /dev/null +++ b/drivers/freetype/src/type1/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 Type1 module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += TYPE1_DRIVER + +define TYPE1_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, t1_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/type1/rules.mk b/drivers/freetype/src/type1/rules.mk new file mode 100644 index 0000000000..15087b0304 --- /dev/null +++ b/drivers/freetype/src/type1/rules.mk @@ -0,0 +1,73 @@ +# +# FreeType 2 Type1 driver configuration rules +# + + +# Copyright 1996-2000, 2001, 2003 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. + + +# Type1 driver directory +# +T1_DIR := $(SRC_DIR)/type1 + + +# compilation flags for the driver +# +T1_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T1_DIR)) + + +# Type1 driver sources (i.e., C files) +# +T1_DRV_SRC := $(T1_DIR)/t1parse.c \ + $(T1_DIR)/t1load.c \ + $(T1_DIR)/t1driver.c \ + $(T1_DIR)/t1afm.c \ + $(T1_DIR)/t1gload.c \ + $(T1_DIR)/t1objs.c + +# Type1 driver headers +# +T1_DRV_H := $(T1_DRV_SRC:%.c=%.h) \ + $(T1_DIR)/t1tokens.h \ + $(T1_DIR)/t1errors.h + + +# Type1 driver object(s) +# +# T1_DRV_OBJ_M is used during `multi' builds +# T1_DRV_OBJ_S is used during `single' builds +# +T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR)/%.c=$(OBJ_DIR)/%.$O) +T1_DRV_OBJ_S := $(OBJ_DIR)/type1.$O + +# Type1 driver source file for single build +# +T1_DRV_SRC_S := $(T1_DIR)/type1.c + + +# Type1 driver - single object +# +$(T1_DRV_OBJ_S): $(T1_DRV_SRC_S) $(T1_DRV_SRC) $(FREETYPE_H) $(T1_DRV_H) + $(T1_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(T1_DRV_SRC_S)) + + +# Type1 driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(T1_DIR)/%.c $(FREETYPE_H) $(T1_DRV_H) + $(T1_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(T1_DRV_OBJ_S) +DRV_OBJS_M += $(T1_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/type1/t1afm.c b/drivers/freetype/src/type1/t1afm.c new file mode 100644 index 0000000000..de9c1997c4 --- /dev/null +++ b/drivers/freetype/src/type1/t1afm.c @@ -0,0 +1,396 @@ +/***************************************************************************/ +/* */ +/* t1afm.c */ +/* */ +/* AFM support for Type 1 fonts (body). */ +/* */ +/* Copyright 1996-2011, 2013 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 "t1afm.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include "t1errors.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_t1afm + + + FT_LOCAL_DEF( void ) + T1_Done_Metrics( FT_Memory memory, + AFM_FontInfo fi ) + { + FT_FREE( fi->KernPairs ); + fi->NumKernPair = 0; + + FT_FREE( fi->TrackKerns ); + fi->NumTrackKern = 0; + + FT_FREE( fi ); + } + + + /* read a glyph name and return the equivalent glyph index */ + static FT_Int + t1_get_index( const char* name, + FT_Offset len, + void* user_data ) + { + T1_Font type1 = (T1_Font)user_data; + FT_Int n; + + + /* PS string/name length must be < 16-bit */ + if ( len > 0xFFFFU ) + return 0; + + for ( n = 0; n < type1->num_glyphs; n++ ) + { + char* gname = (char*)type1->glyph_names[n]; + + + if ( gname && gname[0] == name[0] && + ft_strlen( gname ) == len && + ft_strncmp( gname, name, len ) == 0 ) + return n; + } + + return 0; + } + + +#undef KERN_INDEX +#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) + + + /* compare two kerning pairs */ + FT_CALLBACK_DEF( int ) + compare_kern_pairs( const void* a, + const void* b ) + { + AFM_KernPair pair1 = (AFM_KernPair)a; + AFM_KernPair pair2 = (AFM_KernPair)b; + + FT_ULong index1 = KERN_INDEX( pair1->index1, pair1->index2 ); + FT_ULong index2 = KERN_INDEX( pair2->index1, pair2->index2 ); + + + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; + } + + + /* parse a PFM file -- for now, only read the kerning pairs */ + static FT_Error + T1_Read_PFM( FT_Face t1_face, + FT_Stream stream, + AFM_FontInfo fi ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = stream->memory; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* p; + AFM_KernPair kp; + FT_Int width_table_length; + FT_CharMap oldcharmap; + FT_CharMap charmap; + FT_Int n; + + + start = (FT_Byte*)stream->cursor; + limit = (FT_Byte*)stream->limit; + + /* Figure out how long the width table is. */ + /* This info is a little-endian short at offset 99. */ + p = start + 99; + if ( p + 2 > limit ) + { + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + width_table_length = FT_PEEK_USHORT_LE( p ); + + p += 18 + width_table_length; + if ( p + 0x12 > limit || FT_PEEK_USHORT_LE( p ) < 0x12 ) + /* extension table is probably optional */ + goto Exit; + + /* Kerning offset is 14 bytes from start of extensions table. */ + p += 14; + p = start + FT_PEEK_ULONG_LE( p ); + + if ( p == start ) + /* zero offset means no table */ + goto Exit; + + if ( p + 2 > limit ) + { + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + fi->NumKernPair = FT_PEEK_USHORT_LE( p ); + p += 2; + if ( p + 4 * fi->NumKernPair > limit ) + { + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* Actually, kerning pairs are simply optional! */ + if ( fi->NumKernPair == 0 ) + goto Exit; + + /* allocate the pairs */ + if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) ) + goto Exit; + + /* now, read each kern pair */ + kp = fi->KernPairs; + limit = p + 4 * fi->NumKernPair; + + /* PFM kerning data are stored by encoding rather than glyph index, */ + /* so find the PostScript charmap of this font and install it */ + /* temporarily. If we find no PostScript charmap, then just use */ + /* the default and hope it is the right one. */ + oldcharmap = t1_face->charmap; + charmap = NULL; + + for ( n = 0; n < t1_face->num_charmaps; n++ ) + { + charmap = t1_face->charmaps[n]; + /* check against PostScript pseudo platform */ + if ( charmap->platform_id == 7 ) + { + error = FT_Set_Charmap( t1_face, charmap ); + if ( error ) + goto Exit; + break; + } + } + + /* Kerning info is stored as: */ + /* */ + /* encoding of first glyph (1 byte) */ + /* encoding of second glyph (1 byte) */ + /* offset (little-endian short) */ + for ( ; p < limit ; p += 4 ) + { + kp->index1 = FT_Get_Char_Index( t1_face, p[0] ); + kp->index2 = FT_Get_Char_Index( t1_face, p[1] ); + + kp->x = (FT_Int)FT_PEEK_SHORT_LE(p + 2); + kp->y = 0; + + kp++; + } + + if ( oldcharmap != NULL ) + error = FT_Set_Charmap( t1_face, oldcharmap ); + if ( error ) + goto Exit; + + /* now, sort the kern pairs according to their glyph indices */ + ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ), + compare_kern_pairs ); + + Exit: + if ( error ) + { + FT_FREE( fi->KernPairs ); + fi->NumKernPair = 0; + } + + return error; + } + + + /* parse a metrics file -- either AFM or PFM depending on what */ + /* it turns out to be */ + FT_LOCAL_DEF( FT_Error ) + T1_Read_Metrics( FT_Face t1_face, + FT_Stream stream ) + { + PSAux_Service psaux; + FT_Memory memory = stream->memory; + AFM_ParserRec parser; + AFM_FontInfo fi = NULL; + FT_Error error = FT_ERR( Unknown_File_Format ); + T1_Font t1_font = &( (T1_Face)t1_face )->type1; + + + if ( FT_NEW( fi ) || + FT_FRAME_ENTER( stream->size ) ) + goto Exit; + + fi->FontBBox = t1_font->font_bbox; + fi->Ascender = t1_font->font_bbox.yMax; + fi->Descender = t1_font->font_bbox.yMin; + + psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; + if ( psaux->afm_parser_funcs ) + { + error = psaux->afm_parser_funcs->init( &parser, + stream->memory, + stream->cursor, + stream->limit ); + + if ( !error ) + { + parser.FontInfo = fi; + parser.get_index = t1_get_index; + parser.user_data = t1_font; + + error = psaux->afm_parser_funcs->parse( &parser ); + psaux->afm_parser_funcs->done( &parser ); + } + } + + if ( FT_ERR_EQ( error, Unknown_File_Format ) ) + { + FT_Byte* start = stream->cursor; + + + /* MS Windows allows versions up to 0x3FF without complaining */ + if ( stream->size > 6 && + start[1] < 4 && + FT_PEEK_ULONG_LE( start + 2 ) == stream->size ) + error = T1_Read_PFM( t1_face, stream, fi ); + } + + if ( !error ) + { + t1_font->font_bbox = fi->FontBBox; + + t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; + t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16; + t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16; + + /* no `U' suffix here to 0x8000! */ + t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000 ) >> 16 ); + t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 ); + + if ( fi->NumKernPair ) + { + t1_face->face_flags |= FT_FACE_FLAG_KERNING; + ( (T1_Face)t1_face )->afm_data = fi; + fi = NULL; + } + } + + FT_FRAME_EXIT(); + + Exit: + if ( fi != NULL ) + T1_Done_Metrics( memory, fi ); + + return error; + } + + + /* find the kerning for a given glyph pair */ + FT_LOCAL_DEF( void ) + T1_Get_Kerning( AFM_FontInfo fi, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ) + { + AFM_KernPair min, mid, max; + FT_ULong idx = KERN_INDEX( glyph1, glyph2 ); + + + /* simple binary search */ + min = fi->KernPairs; + max = min + fi->NumKernPair - 1; + + while ( min <= max ) + { + FT_ULong midi; + + + mid = min + ( max - min ) / 2; + midi = KERN_INDEX( mid->index1, mid->index2 ); + + if ( midi == idx ) + { + kerning->x = mid->x; + kerning->y = mid->y; + + return; + } + + if ( midi < idx ) + min = mid + 1; + else + max = mid - 1; + } + + kerning->x = 0; + kerning->y = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Track_Kerning( FT_Face face, + FT_Fixed ptsize, + FT_Int degree, + FT_Fixed* kerning ) + { + AFM_FontInfo fi = (AFM_FontInfo)( (T1_Face)face )->afm_data; + FT_Int i; + + + if ( !fi ) + return FT_THROW( Invalid_Argument ); + + for ( i = 0; i < fi->NumTrackKern; i++ ) + { + AFM_TrackKern tk = fi->TrackKerns + i; + + + if ( tk->degree != degree ) + continue; + + if ( ptsize < tk->min_ptsize ) + *kerning = tk->min_kern; + else if ( ptsize > tk->max_ptsize ) + *kerning = tk->max_kern; + else + { + *kerning = FT_MulDiv( ptsize - tk->min_ptsize, + tk->max_kern - tk->min_kern, + tk->max_ptsize - tk->min_ptsize ) + + tk->min_kern; + } + } + + return FT_Err_Ok; + } + + +/* END */ diff --git a/drivers/freetype/src/type1/t1afm.h b/drivers/freetype/src/type1/t1afm.h new file mode 100644 index 0000000000..8eb1764de7 --- /dev/null +++ b/drivers/freetype/src/type1/t1afm.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* t1afm.h */ +/* */ +/* AFM support for Type 1 fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1AFM_H__ +#define __T1AFM_H__ + +#include <ft2build.h> +#include "t1objs.h" +#include FT_INTERNAL_TYPE1_TYPES_H + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + T1_Read_Metrics( FT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + T1_Done_Metrics( FT_Memory memory, + AFM_FontInfo fi ); + + FT_LOCAL( void ) + T1_Get_Kerning( AFM_FontInfo fi, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ); + + FT_LOCAL( FT_Error ) + T1_Get_Track_Kerning( FT_Face face, + FT_Fixed ptsize, + FT_Int degree, + FT_Fixed* kerning ); + +FT_END_HEADER + +#endif /* __T1AFM_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type1/t1driver.c b/drivers/freetype/src/type1/t1driver.c new file mode 100644 index 0000000000..697288d66d --- /dev/null +++ b/drivers/freetype/src/type1/t1driver.c @@ -0,0 +1,726 @@ +/***************************************************************************/ +/* */ +/* t1driver.c */ +/* */ +/* Type 1 driver interface (body). */ +/* */ +/* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013 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 "t1driver.h" +#include "t1gload.h" +#include "t1load.h" + +#include "t1errors.h" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.h" +#endif + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_KERNING_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_t1driver + + /* + * GLYPH DICT SERVICE + * + */ + + static FT_Error + t1_get_glyph_name( T1_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); + + return FT_Err_Ok; + } + + + static FT_UInt + t1_get_name_index( T1_Face face, + FT_String* glyph_name ) + { + FT_Int i; + + + for ( i = 0; i < face->type1.num_glyphs; i++ ) + { + FT_String* gname = face->type1.glyph_names[i]; + + + if ( !ft_strcmp( glyph_name, gname ) ) + return (FT_UInt)i; + } + + return 0; + } + + + static const FT_Service_GlyphDictRec t1_service_glyph_dict = + { + (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)t1_get_name_index + }; + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + t1_get_ps_name( T1_Face face ) + { + return (const char*) face->type1.font_name; + } + + + static const FT_Service_PsFontNameRec t1_service_ps_name = + { + (FT_PsName_GetFunc)t1_get_ps_name + }; + + + /* + * MULTIPLE MASTERS SERVICE + * + */ + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + static const FT_Service_MultiMastersRec t1_service_multi_masters = + { + (FT_Get_MM_Func) T1_Get_Multi_Master, + (FT_Set_MM_Design_Func) T1_Set_MM_Design, + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, + (FT_Get_MM_Var_Func) T1_Get_MM_Var, + (FT_Set_Var_Design_Func)T1_Set_Var_Design + }; +#endif + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + t1_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((T1_Face)face)->type1.font_info; + + return FT_Err_Ok; + } + + + static FT_Error + t1_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T1_Face)face)->type1.font_extra; + + return FT_Err_Ok; + } + + + static FT_Int + t1_ps_has_glyph_names( FT_Face face ) + { + FT_UNUSED( face ); + + return 1; + } + + + static FT_Error + t1_ps_get_font_private( FT_Face face, + PS_PrivateRec* afont_private ) + { + *afont_private = ((T1_Face)face)->type1.private_dict; + + return FT_Err_Ok; + } + + + static FT_Long + t1_ps_get_font_value( FT_Face face, + PS_Dict_Keys key, + FT_UInt idx, + void *value, + FT_Long value_len ) + { + FT_Long retval = -1; + T1_Face t1face = (T1_Face)face; + T1_Font type1 = &t1face->type1; + + + switch ( key ) + { + case PS_DICT_FONT_TYPE: + retval = sizeof ( type1->font_type ); + if ( value && value_len >= retval ) + *((FT_Byte *)value) = type1->font_type; + break; + + case PS_DICT_FONT_MATRIX: + if ( idx < sizeof ( type1->font_matrix ) / + sizeof ( type1->font_matrix.xx ) ) + { + FT_Fixed val = 0; + + + retval = sizeof ( val ); + if ( value && value_len >= retval ) + { + switch ( idx ) + { + case 0: + val = type1->font_matrix.xx; + break; + case 1: + val = type1->font_matrix.xy; + break; + case 2: + val = type1->font_matrix.yx; + break; + case 3: + val = type1->font_matrix.yy; + break; + } + *((FT_Fixed *)value) = val; + } + } + break; + + case PS_DICT_FONT_BBOX: + if ( idx < sizeof ( type1->font_bbox ) / + sizeof ( type1->font_bbox.xMin ) ) + { + FT_Fixed val = 0; + + + retval = sizeof ( val ); + if ( value && value_len >= retval ) + { + switch ( idx ) + { + case 0: + val = type1->font_bbox.xMin; + break; + case 1: + val = type1->font_bbox.yMin; + break; + case 2: + val = type1->font_bbox.xMax; + break; + case 3: + val = type1->font_bbox.yMax; + break; + } + *((FT_Fixed *)value) = val; + } + } + break; + + case PS_DICT_PAINT_TYPE: + retval = sizeof ( type1->paint_type ); + if ( value && value_len >= retval ) + *((FT_Byte *)value) = type1->paint_type; + break; + + case PS_DICT_FONT_NAME: + retval = (FT_Long)( ft_strlen( type1->font_name ) + 1 ); + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_name ), retval ); + break; + + case PS_DICT_UNIQUE_ID: + retval = sizeof ( type1->private_dict.unique_id ); + if ( value && value_len >= retval ) + *((FT_Int *)value) = type1->private_dict.unique_id; + break; + + case PS_DICT_NUM_CHAR_STRINGS: + retval = sizeof ( type1->num_glyphs ); + if ( value && value_len >= retval ) + *((FT_Int *)value) = type1->num_glyphs; + break; + + case PS_DICT_CHAR_STRING_KEY: + if ( idx < (FT_UInt)type1->num_glyphs ) + { + retval = (FT_Long)( ft_strlen( type1->glyph_names[idx] ) + 1 ); + if ( value && value_len >= retval ) + { + ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval ); + ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + } + } + break; + + case PS_DICT_CHAR_STRING: + if ( idx < (FT_UInt)type1->num_glyphs ) + { + retval = (FT_Long)( type1->charstrings_len[idx] + 1 ); + if ( value && value_len >= retval ) + { + ft_memcpy( value, (void *)( type1->charstrings[idx] ), + retval - 1 ); + ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + } + } + break; + + case PS_DICT_ENCODING_TYPE: + retval = sizeof ( type1->encoding_type ); + if ( value && value_len >= retval ) + *((T1_EncodingType *)value) = type1->encoding_type; + break; + + case PS_DICT_ENCODING_ENTRY: + if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY && + idx < (FT_UInt)type1->encoding.num_chars ) + { + retval = (FT_Long)( ft_strlen( type1->encoding.char_name[idx] ) + 1 ); + if ( value && value_len >= retval ) + { + ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ), + retval - 1 ); + ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + } + } + break; + + case PS_DICT_NUM_SUBRS: + retval = sizeof ( type1->num_subrs ); + if ( value && value_len >= retval ) + *((FT_Int *)value) = type1->num_subrs; + break; + + case PS_DICT_SUBR: + if ( idx < (FT_UInt)type1->num_subrs ) + { + retval = (FT_Long)( type1->subrs_len[idx] + 1 ); + if ( value && value_len >= retval ) + { + ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); + ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + } + } + break; + + case PS_DICT_STD_HW: + retval = sizeof ( type1->private_dict.standard_width[0] ); + if ( value && value_len >= retval ) + *((FT_UShort *)value) = type1->private_dict.standard_width[0]; + break; + + case PS_DICT_STD_VW: + retval = sizeof ( type1->private_dict.standard_height[0] ); + if ( value && value_len >= retval ) + *((FT_UShort *)value) = type1->private_dict.standard_height[0]; + break; + + case PS_DICT_NUM_BLUE_VALUES: + retval = sizeof ( type1->private_dict.num_blue_values ); + if ( value && value_len >= retval ) + *((FT_Byte *)value) = type1->private_dict.num_blue_values; + break; + + case PS_DICT_BLUE_VALUE: + if ( idx < type1->private_dict.num_blue_values ) + { + retval = sizeof ( type1->private_dict.blue_values[idx] ); + if ( value && value_len >= retval ) + *((FT_Short *)value) = type1->private_dict.blue_values[idx]; + } + break; + + case PS_DICT_BLUE_SCALE: + retval = sizeof ( type1->private_dict.blue_scale ); + if ( value && value_len >= retval ) + *((FT_Fixed *)value) = type1->private_dict.blue_scale; + break; + + case PS_DICT_BLUE_FUZZ: + retval = sizeof ( type1->private_dict.blue_fuzz ); + if ( value && value_len >= retval ) + *((FT_Int *)value) = type1->private_dict.blue_fuzz; + break; + + case PS_DICT_BLUE_SHIFT: + retval = sizeof ( type1->private_dict.blue_shift ); + if ( value && value_len >= retval ) + *((FT_Int *)value) = type1->private_dict.blue_shift; + break; + + case PS_DICT_NUM_OTHER_BLUES: + retval = sizeof ( type1->private_dict.num_other_blues ); + if ( value && value_len >= retval ) + *((FT_Byte *)value) = type1->private_dict.num_other_blues; + break; + + case PS_DICT_OTHER_BLUE: + if ( idx < type1->private_dict.num_other_blues ) + { + retval = sizeof ( type1->private_dict.other_blues[idx] ); + if ( value && value_len >= retval ) + *((FT_Short *)value) = type1->private_dict.other_blues[idx]; + } + break; + + case PS_DICT_NUM_FAMILY_BLUES: + retval = sizeof ( type1->private_dict.num_family_blues ); + if ( value && value_len >= retval ) + *((FT_Byte *)value) = type1->private_dict.num_family_blues; + break; + + case PS_DICT_FAMILY_BLUE: + if ( idx < type1->private_dict.num_family_blues ) + { + retval = sizeof ( type1->private_dict.family_blues[idx] ); + if ( value && value_len >= retval ) + *((FT_Short *)value) = type1->private_dict.family_blues[idx]; + } + break; + + case PS_DICT_NUM_FAMILY_OTHER_BLUES: + retval = sizeof ( type1->private_dict.num_family_other_blues ); + if ( value && value_len >= retval ) + *((FT_Byte *)value) = type1->private_dict.num_family_other_blues; + break; + + case PS_DICT_FAMILY_OTHER_BLUE: + if ( idx < type1->private_dict.num_family_other_blues ) + { + retval = sizeof ( type1->private_dict.family_other_blues[idx] ); + if ( value && value_len >= retval ) + *((FT_Short *)value) = type1->private_dict.family_other_blues[idx]; + } + break; + + case PS_DICT_NUM_STEM_SNAP_H: + retval = sizeof ( type1->private_dict.num_snap_widths ); + if ( value && value_len >= retval ) + *((FT_Byte *)value) = type1->private_dict.num_snap_widths; + break; + + case PS_DICT_STEM_SNAP_H: + if ( idx < type1->private_dict.num_snap_widths ) + { + retval = sizeof ( type1->private_dict.snap_widths[idx] ); + if ( value && value_len >= retval ) + *((FT_Short *)value) = type1->private_dict.snap_widths[idx]; + } + break; + + case PS_DICT_NUM_STEM_SNAP_V: + retval = sizeof ( type1->private_dict.num_snap_heights ); + if ( value && value_len >= retval ) + *((FT_Byte *)value) = type1->private_dict.num_snap_heights; + break; + + case PS_DICT_STEM_SNAP_V: + if ( idx < type1->private_dict.num_snap_heights ) + { + retval = sizeof ( type1->private_dict.snap_heights[idx] ); + if ( value && value_len >= retval ) + *((FT_Short *)value) = type1->private_dict.snap_heights[idx]; + } + break; + + case PS_DICT_RND_STEM_UP: + retval = sizeof ( type1->private_dict.round_stem_up ); + if ( value && value_len >= retval ) + *((FT_Bool *)value) = type1->private_dict.round_stem_up; + break; + + case PS_DICT_FORCE_BOLD: + retval = sizeof ( type1->private_dict.force_bold ); + if ( value && value_len >= retval ) + *((FT_Bool *)value) = type1->private_dict.force_bold; + break; + + case PS_DICT_MIN_FEATURE: + if ( idx < sizeof ( type1->private_dict.min_feature ) / + sizeof ( type1->private_dict.min_feature[0] ) ) + { + retval = sizeof ( type1->private_dict.min_feature[idx] ); + if ( value && value_len >= retval ) + *((FT_Short *)value) = type1->private_dict.min_feature[idx]; + } + break; + + case PS_DICT_LEN_IV: + retval = sizeof ( type1->private_dict.lenIV ); + if ( value && value_len >= retval ) + *((FT_Int *)value) = type1->private_dict.lenIV; + break; + + case PS_DICT_PASSWORD: + retval = sizeof ( type1->private_dict.password ); + if ( value && value_len >= retval ) + *((FT_Long *)value) = type1->private_dict.password; + break; + + case PS_DICT_LANGUAGE_GROUP: + retval = sizeof ( type1->private_dict.language_group ); + if ( value && value_len >= retval ) + *((FT_Long *)value) = type1->private_dict.language_group; + break; + + case PS_DICT_IS_FIXED_PITCH: + retval = sizeof ( type1->font_info.is_fixed_pitch ); + if ( value && value_len >= retval ) + *((FT_Bool *)value) = type1->font_info.is_fixed_pitch; + break; + + case PS_DICT_UNDERLINE_POSITION: + retval = sizeof ( type1->font_info.underline_position ); + if ( value && value_len >= retval ) + *((FT_Short *)value) = type1->font_info.underline_position; + break; + + case PS_DICT_UNDERLINE_THICKNESS: + retval = sizeof ( type1->font_info.underline_thickness ); + if ( value && value_len >= retval ) + *((FT_UShort *)value) = type1->font_info.underline_thickness; + break; + + case PS_DICT_FS_TYPE: + retval = sizeof ( type1->font_extra.fs_type ); + if ( value && value_len >= retval ) + *((FT_UShort *)value) = type1->font_extra.fs_type; + break; + + case PS_DICT_VERSION: + retval = (FT_Long)( ft_strlen( type1->font_info.version ) + 1 ); + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.version ), retval ); + break; + + case PS_DICT_NOTICE: + retval = (FT_Long)( ft_strlen( type1->font_info.notice ) + 1 ); + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.notice ), retval ); + break; + + case PS_DICT_FULL_NAME: + retval = (FT_Long)( ft_strlen( type1->font_info.full_name ) + 1 ); + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.full_name ), retval ); + break; + + case PS_DICT_FAMILY_NAME: + retval = (FT_Long)( ft_strlen( type1->font_info.family_name ) + 1 ); + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.family_name ), retval ); + break; + + case PS_DICT_WEIGHT: + retval = (FT_Long)( ft_strlen( type1->font_info.weight ) + 1 ); + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.weight ), retval ); + break; + + case PS_DICT_ITALIC_ANGLE: + retval = sizeof ( type1->font_info.italic_angle ); + if ( value && value_len >= retval ) + *((FT_Long *)value) = type1->font_info.italic_angle; + break; + + default: + break; + } + + return retval; + } + + + static const FT_Service_PsInfoRec t1_service_ps_info = + { + (PS_GetFontInfoFunc) t1_ps_get_font_info, + (PS_GetFontExtraFunc) t1_ps_get_font_extra, + (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, + (PS_GetFontPrivateFunc)t1_ps_get_font_private, + (PS_GetFontValueFunc) t1_ps_get_font_value, + }; + + +#ifndef T1_CONFIG_OPTION_NO_AFM + static const FT_Service_KerningRec t1_service_kerning = + { + T1_Get_Track_Kerning, + }; +#endif + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec t1_services[] = + { + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name }, + { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_1 }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, + +#ifndef T1_CONFIG_OPTION_NO_AFM + { FT_SERVICE_ID_KERNING, &t1_service_kerning }, +#endif + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + { FT_SERVICE_ID_MULTI_MASTERS, &t1_service_multi_masters }, +#endif + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + Get_Interface( FT_Module module, + const FT_String* t1_interface ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( t1_services, t1_interface ); + } + + +#ifndef T1_CONFIG_OPTION_NO_AFM + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Get_Kerning */ + /* */ + /* <Description> */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* <Output> */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + static FT_Error + Get_Kerning( FT_Face t1face, /* T1_Face */ + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + T1_Face face = (T1_Face)t1face; + + + kerning->x = 0; + kerning->y = 0; + + if ( face->afm_data ) + T1_Get_Kerning( (AFM_FontInfo)face->afm_data, + left_glyph, + right_glyph, + kerning ); + + return FT_Err_Ok; + } + + +#endif /* T1_CONFIG_OPTION_NO_AFM */ + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec t1_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, + + sizeof ( FT_DriverRec ), + + "type1", + 0x10000L, + 0x20000L, + + 0, /* format interface */ + + T1_Driver_Init, + T1_Driver_Done, + Get_Interface, + }, + + sizeof ( T1_FaceRec ), + sizeof ( T1_SizeRec ), + sizeof ( T1_GlyphSlotRec ), + + T1_Face_Init, + T1_Face_Done, + T1_Size_Init, + T1_Size_Done, + T1_GlyphSlot_Init, + T1_GlyphSlot_Done, + + T1_Load_Glyph, + +#ifdef T1_CONFIG_OPTION_NO_AFM + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ +#else + Get_Kerning, + T1_Read_Metrics, +#endif + T1_Get_Advances, + T1_Size_Request, + 0 /* FT_Size_SelectFunc */ + }; + + +/* END */ diff --git a/drivers/freetype/src/type1/t1driver.h b/drivers/freetype/src/type1/t1driver.h new file mode 100644 index 0000000000..639cd4a7ad --- /dev/null +++ b/drivers/freetype/src/type1/t1driver.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* t1driver.h */ +/* */ +/* High-level Type 1 driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1DRIVER_H__ +#define __T1DRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; + + +FT_END_HEADER + +#endif /* __T1DRIVER_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type1/t1errors.h b/drivers/freetype/src/type1/t1errors.h new file mode 100644 index 0000000000..8740530eef --- /dev/null +++ b/drivers/freetype/src/type1/t1errors.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* t1errors.h */ +/* */ +/* Type 1 error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the Type 1 error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __T1ERRORS_H__ +#define __T1ERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX T1_Err_ +#define FT_ERR_BASE FT_Mod_Err_Type1 + +#include FT_ERRORS_H + +#endif /* __T1ERRORS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type1/t1gload.c b/drivers/freetype/src/type1/t1gload.c new file mode 100644 index 0000000000..23478d1288 --- /dev/null +++ b/drivers/freetype/src/type1/t1gload.c @@ -0,0 +1,517 @@ +/***************************************************************************/ +/* */ +/* t1gload.c */ +/* */ +/* Type 1 Glyph Loader (body). */ +/* */ +/* Copyright 1996-2006, 2008-2010, 2013 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 "t1gload.h" +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_OUTLINE_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "t1errors.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_t1gload + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, + FT_UInt glyph_index, + FT_Data* char_string ) + { + T1_Face face = (T1_Face)decoder->builder.face; + T1_Font type1 = &face->type1; + FT_Error error = FT_Err_Ok; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + + + decoder->font_matrix = type1->font_matrix; + decoder->font_offset = type1->font_offset; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( inc ) + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, char_string ); + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* For ordinary fonts get the character data stored in the face record. */ + { + char_string->pointer = type1->charstrings[glyph_index]; + char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; + } + + if ( !error ) + error = decoder->funcs.parse_charstrings( + decoder, (FT_Byte*)char_string->pointer, + char_string->length ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && inc && inc->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = 0; + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); + decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + T1_Parse_Glyph( T1_Decoder decoder, + FT_UInt glyph_index ) + { + FT_Data glyph_data; + FT_Error error = T1_Parse_Glyph_And_Get_Char_String( + decoder, glyph_index, &glyph_data ); + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( !error ) + { + T1_Face face = (T1_Face)decoder->builder.face; + + + if ( face->root.internal->incremental_interface ) + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Compute_Max_Advance( T1_Face face, + FT_Pos* max_advance ) + { + FT_Error error; + T1_DecoderRec decoder; + FT_Int glyph_index; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + + *max_advance = 0; + + /* initialize load decoder */ + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + (FT_Byte**)type1->glyph_names, + face->blend, + 0, + FT_RENDER_MODE_NORMAL, + T1_Parse_Glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + *max_advance = 0; + + /* for each glyph, parse the glyph charstring and extract */ + /* the advance width */ + for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) + { + /* now get load the unscaled outline */ + error = T1_Parse_Glyph( &decoder, glyph_index ); + if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) + *max_advance = decoder.builder.advance.x; + + /* ignore the error if one occurred - skip to next glyph */ + } + + psaux->t1_decoder_funcs->done( &decoder ); + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Advances( FT_Face t1face, /* T1_Face */ + FT_UInt first, + FT_UInt count, + FT_Int32 load_flags, + FT_Fixed* advances ) + { + T1_Face face = (T1_Face)t1face; + T1_DecoderRec decoder; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_UInt nn; + FT_Error error; + + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + advances[nn] = 0; + + return FT_Err_Ok; + } + + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + (FT_Byte**)type1->glyph_names, + face->blend, + 0, + FT_RENDER_MODE_NORMAL, + T1_Parse_Glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + for ( nn = 0; nn < count; nn++ ) + { + error = T1_Parse_Glyph( &decoder, first + nn ); + if ( !error ) + advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); + else + advances[nn] = 0; + } + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Load_Glyph( FT_GlyphSlot t1glyph, /* T1_GlyphSlot */ + FT_Size t1size, /* T1_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + T1_GlyphSlot glyph = (T1_GlyphSlot)t1glyph; + FT_Error error; + T1_DecoderRec decoder; + T1_Face face = (T1_Face)t1glyph->face; + FT_Bool hinting; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; + + FT_Matrix font_matrix; + FT_Vector font_offset; + FT_Data glyph_data; + FT_Bool must_finish_decoder = FALSE; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Bool glyph_data_loaded = 0; +#endif + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_index >= (FT_UInt)face->root.num_glyphs && + !face->root.internal->incremental_interface ) +#else + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + if ( t1size ) + { + glyph->x_scale = t1size->metrics.x_scale; + glyph->y_scale = t1size->metrics.y_scale; + } + else + { + glyph->x_scale = 0x10000L; + glyph->y_scale = 0x10000L; + } + + t1glyph->outline.n_points = 0; + t1glyph->outline.n_contours = 0; + + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + + t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; + + error = decoder_funcs->init( &decoder, + t1glyph->face, + t1size, + t1glyph, + (FT_Byte**)type1->glyph_names, + face->blend, + FT_BOOL( hinting ), + FT_LOAD_TARGET_MODE( load_flags ), + T1_Parse_Glyph ); + if ( error ) + goto Exit; + + must_finish_decoder = TRUE; + + decoder.builder.no_recurse = FT_BOOL( + ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + /* now load the unscaled outline */ + error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, + &glyph_data ); + if ( error ) + goto Exit; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + glyph_data_loaded = 1; +#endif + + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; + + /* save new glyph tables */ + decoder_funcs->done( &decoder ); + + must_finish_decoder = FALSE; + + /* 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 ) + { + t1glyph->outline.flags &= FT_OUTLINE_OWNER; + t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; + + /* for composite glyphs, return only left side bearing and */ + /* advance width */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + FT_Slot_Internal internal = t1glyph->internal; + + + t1glyph->metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + t1glyph->metrics.horiAdvance = + FIXED_TO_INT( 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 = &t1glyph->metrics; + FT_Vector advance; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + t1glyph->linearHoriAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + t1glyph->internal->glyph_transformed = 0; + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + metrics->vertAdvance = ( face->type1.font_bbox.yMax - + face->type1.font_bbox.yMin ) >> 16; + t1glyph->linearVertAdvance = metrics->vertAdvance; + } + else + { + metrics->vertAdvance = + FIXED_TO_INT( decoder.builder.advance.y ); + t1glyph->linearVertAdvance = + FIXED_TO_INT( decoder.builder.advance.y ); + } + + t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; + + if ( t1size && t1size->metrics.y_ppem < 24 ) + t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; + +#if 1 + /* apply the font matrix, if any */ + if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + FT_Outline_Transform( &t1glyph->outline, &font_matrix ); + + if ( font_offset.x || font_offset.y ) + FT_Outline_Translate( &t1glyph->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; +#endif + + 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 we are not hinting */ + 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( &t1glyph->outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } + } + + /* Set control data to the glyph charstrings. Note that this is */ + /* _not_ zero-terminated. */ + t1glyph->control_data = (FT_Byte*)glyph_data.pointer; + t1glyph->control_len = glyph_data.length; + } + + + Exit: + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_data_loaded && face->root.internal->incremental_interface ) + { + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + + /* Set the control data to null - it is no longer available if */ + /* loaded incrementally. */ + t1glyph->control_data = 0; + t1glyph->control_len = 0; + } +#endif + + if ( must_finish_decoder ) + decoder_funcs->done( &decoder ); + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/type1/t1gload.h b/drivers/freetype/src/type1/t1gload.h new file mode 100644 index 0000000000..0bdea3a8d5 --- /dev/null +++ b/drivers/freetype/src/type1/t1gload.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* t1gload.h */ +/* */ +/* Type 1 Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2008, 2011 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 __T1GLOAD_H__ +#define __T1GLOAD_H__ + + +#include <ft2build.h> +#include "t1objs.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + T1_Compute_Max_Advance( T1_Face face, + FT_Pos* max_advance ); + + FT_LOCAL( FT_Error ) + T1_Get_Advances( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Int32 load_flags, + FT_Fixed* advances ); + + FT_LOCAL( FT_Error ) + T1_Load_Glyph( FT_GlyphSlot glyph, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __T1GLOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type1/t1load.c b/drivers/freetype/src/type1/t1load.c new file mode 100644 index 0000000000..1c834a17bb --- /dev/null +++ b/drivers/freetype/src/type1/t1load.c @@ -0,0 +1,2267 @@ +/***************************************************************************/ +/* */ +/* t1load.c */ +/* */ +/* Type 1 font loader (body). */ +/* */ +/* Copyright 1996-2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This is the new and improved Type 1 data loader for FreeType 2. The */ + /* old loader has several problems: it is slow, complex, difficult to */ + /* maintain, and contains incredible hacks to make it accept some */ + /* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of */ + /* the Type 1 fonts on my machine still aren't loaded correctly by it. */ + /* */ + /* This version is much simpler, much faster and also easier to read and */ + /* maintain by a great order of magnitude. The idea behind it is to */ + /* _not_ try to read the Type 1 token stream with a state machine (i.e. */ + /* a Postscript-like interpreter) but rather to perform simple pattern */ + /* matching. */ + /* */ + /* Indeed, nearly all data definitions follow a simple pattern like */ + /* */ + /* ... /Field <data> ... */ + /* */ + /* where <data> can be a number, a boolean, a string, or an array of */ + /* numbers. There are a few exceptions, namely the encoding, font name, */ + /* charstrings, and subrs; they are handled with a special pattern */ + /* matching routine. */ + /* */ + /* All other common cases are handled very simply. The matching rules */ + /* are defined in the file `t1tokens.h' through the use of several */ + /* macros calls PARSE_XXX. This file is included twice here; the first */ + /* time to generate parsing callback functions, the second time to */ + /* generate a table of keywords (with pointers to the associated */ + /* callback functions). */ + /* */ + /* The function `parse_dict' simply scans *linearly* a given dictionary */ + /* (either the top-level or private one) and calls the appropriate */ + /* callback when it encounters an immediate keyword. */ + /* */ + /* This is by far the fastest way one can find to parse and read all */ + /* data. */ + /* */ + /* This led to tremendous code size reduction. Note that later, the */ + /* glyph loader will also be _greatly_ simplified, and the automatic */ + /* hinter will replace the clumsy `t1hinter'. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_CALC_H + +#include "t1load.h" +#include "t1errors.h" + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL +#define IS_INCREMENTAL (FT_Bool)( face->root.internal->incremental_interface != 0 ) +#else +#define IS_INCREMENTAL 0 +#endif + + + /*************************************************************************/ + /* */ + /* 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_t1load + + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MULTIPLE MASTERS SUPPORT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + t1_allocate_blend( T1_Face face, + FT_UInt num_designs, + FT_UInt num_axis ) + { + PS_Blend blend; + FT_Memory memory = face->root.memory; + FT_Error error = FT_Err_Ok; + + + blend = face->blend; + if ( !blend ) + { + if ( FT_NEW( blend ) ) + goto Exit; + + blend->num_default_design_vector = 0; + + face->blend = blend; + } + + /* allocate design data if needed */ + if ( num_designs > 0 ) + { + if ( blend->num_designs == 0 ) + { + FT_UInt nn; + + + /* allocate the blend `private' and `font_info' dictionaries */ + if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) || + FT_NEW_ARRAY( blend->privates [1], num_designs ) || + FT_NEW_ARRAY( blend->bboxes [1], num_designs ) || + FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) ) + goto Exit; + + blend->default_weight_vector = blend->weight_vector + num_designs; + + blend->font_infos[0] = &face->type1.font_info; + blend->privates [0] = &face->type1.private_dict; + blend->bboxes [0] = &face->type1.font_bbox; + + for ( nn = 2; nn <= num_designs; nn++ ) + { + blend->font_infos[nn] = blend->font_infos[nn - 1] + 1; + blend->privates [nn] = blend->privates [nn - 1] + 1; + blend->bboxes [nn] = blend->bboxes [nn - 1] + 1; + } + + blend->num_designs = num_designs; + } + else if ( blend->num_designs != num_designs ) + goto Fail; + } + + /* allocate axis data if needed */ + if ( num_axis > 0 ) + { + if ( blend->num_axis != 0 && blend->num_axis != num_axis ) + goto Fail; + + blend->num_axis = num_axis; + } + + /* allocate the blend design pos table if needed */ + num_designs = blend->num_designs; + num_axis = blend->num_axis; + if ( num_designs && num_axis && blend->design_pos[0] == 0 ) + { + FT_UInt n; + + + if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) ) + goto Exit; + + for ( n = 1; n < num_designs; n++ ) + blend->design_pos[n] = blend->design_pos[0] + num_axis * n; + } + + Exit: + return error; + + Fail: + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Multi_Master( T1_Face face, + FT_Multi_Master* master ) + { + PS_Blend blend = face->blend; + FT_UInt n; + FT_Error error; + + + error = FT_THROW( Invalid_Argument ); + + if ( blend ) + { + master->num_axis = blend->num_axis; + master->num_designs = blend->num_designs; + + for ( n = 0; n < blend->num_axis; n++ ) + { + FT_MM_Axis* axis = master->axis + n; + PS_DesignMap map = blend->design_map + n; + + + axis->name = blend->axis_names[n]; + axis->minimum = map->design_points[0]; + axis->maximum = map->design_points[map->num_points - 1]; + } + + error = FT_Err_Ok; + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* Given a normalized (blend) coordinate, figure out the design */ + /* coordinate appropriate for that value. */ + /* */ + FT_LOCAL_DEF( FT_Fixed ) + mm_axis_unmap( PS_DesignMap axismap, + FT_Fixed ncv ) + { + int j; + + + if ( ncv <= axismap->blend_points[0] ) + return INT_TO_FIXED( axismap->design_points[0] ); + + for ( j = 1; j < axismap->num_points; ++j ) + { + if ( ncv <= axismap->blend_points[j] ) + return INT_TO_FIXED( axismap->design_points[j - 1] ) + + ( axismap->design_points[j] - axismap->design_points[j - 1] ) * + FT_DivFix( ncv - axismap->blend_points[j - 1], + axismap->blend_points[j] - + axismap->blend_points[j - 1] ); + } + + return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] ); + } + + + /*************************************************************************/ + /* */ + /* Given a vector of weights, one for each design, figure out the */ + /* normalized axis coordinates which gave rise to those weights. */ + /* */ + FT_LOCAL_DEF( void ) + mm_weights_unmap( FT_Fixed* weights, + FT_Fixed* axiscoords, + FT_UInt axis_count ) + { + FT_ASSERT( axis_count <= T1_MAX_MM_AXIS ); + + if ( axis_count == 1 ) + axiscoords[0] = weights[1]; + + else if ( axis_count == 2 ) + { + axiscoords[0] = weights[3] + weights[1]; + axiscoords[1] = weights[3] + weights[2]; + } + + else if ( axis_count == 3 ) + { + axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1]; + axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2]; + axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4]; + } + + else + { + axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] + + weights[7] + weights[5] + weights[3] + weights[1]; + axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] + + weights[7] + weights[6] + weights[3] + weights[2]; + axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] + + weights[7] + weights[6] + weights[5] + weights[4]; + axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] + + weights[11] + weights[10] + weights[9] + weights[8]; + } + } + + + /*************************************************************************/ + /* */ + /* Just a wrapper around T1_Get_Multi_Master to support the different */ + /* arguments needed by the GX var distortable fonts. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_Var( T1_Face face, + FT_MM_Var* *master ) + { + FT_Memory memory = face->root.memory; + FT_MM_Var *mmvar = NULL; + FT_Multi_Master mmaster; + FT_Error error; + FT_UInt i; + FT_Fixed axiscoords[T1_MAX_MM_AXIS]; + PS_Blend blend = face->blend; + + + error = T1_Get_Multi_Master( face, &mmaster ); + if ( error ) + goto Exit; + if ( FT_ALLOC( mmvar, + sizeof ( FT_MM_Var ) + + mmaster.num_axis * sizeof ( FT_Var_Axis ) ) ) + goto Exit; + + mmvar->num_axis = mmaster.num_axis; + mmvar->num_designs = mmaster.num_designs; + mmvar->num_namedstyles = ~0U; /* Does not apply */ + mmvar->axis = (FT_Var_Axis*)&mmvar[1]; + /* Point to axes after MM_Var struct */ + mmvar->namedstyle = NULL; + + for ( i = 0 ; i < mmaster.num_axis; ++i ) + { + mmvar->axis[i].name = mmaster.axis[i].name; + mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); + mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum); + mmvar->axis[i].def = ( mmvar->axis[i].minimum + + mmvar->axis[i].maximum ) / 2; + /* Does not apply. But this value is in range */ + mmvar->axis[i].strid = ~0U; /* Does not apply */ + mmvar->axis[i].tag = ~0U; /* Does not apply */ + + if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); + else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' ); + else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' ); + } + + if ( blend->num_designs == ( 1U << blend->num_axis ) ) + { + mm_weights_unmap( blend->default_weight_vector, + axiscoords, + blend->num_axis ); + + for ( i = 0; i < mmaster.num_axis; ++i ) + mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], + axiscoords[i] ); + } + + *master = mmvar; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + FT_Error error; + FT_UInt n, m; + + + error = FT_ERR( Invalid_Argument ); + + if ( blend && blend->num_axis == num_coords ) + { + /* recompute the weight vector from the blend coordinates */ + error = FT_Err_Ok; + + for ( n = 0; n < blend->num_designs; n++ ) + { + FT_Fixed result = 0x10000L; /* 1.0 fixed */ + + + for ( m = 0; m < blend->num_axis; m++ ) + { + FT_Fixed factor; + + + /* get current blend axis position */ + factor = coords[m]; + if ( factor < 0 ) + factor = 0; + if ( factor > 0x10000L ) + factor = 0x10000L; + + if ( ( n & ( 1 << m ) ) == 0 ) + factor = 0x10000L - factor; + + result = FT_MulFix( result, factor ); + } + blend->weight_vector[n] = result; + } + + error = FT_Err_Ok; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_Design( T1_Face face, + FT_UInt num_coords, + FT_Long* coords ) + { + PS_Blend blend = face->blend; + FT_Error error; + FT_UInt n, p; + + + error = FT_ERR( Invalid_Argument ); + if ( blend && blend->num_axis == num_coords ) + { + /* compute the blend coordinates through the blend design map */ + FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; + + + for ( n = 0; n < blend->num_axis; n++ ) + { + FT_Long design = coords[n]; + FT_Fixed the_blend; + PS_DesignMap map = blend->design_map + n; + FT_Long* designs = map->design_points; + FT_Fixed* blends = map->blend_points; + FT_Int before = -1, after = -1; + + + for ( p = 0; p < (FT_UInt)map->num_points; p++ ) + { + FT_Long p_design = designs[p]; + + + /* exact match? */ + if ( design == p_design ) + { + the_blend = blends[p]; + goto Found; + } + + if ( design < p_design ) + { + after = p; + break; + } + + before = p; + } + + /* now interpolate if necessary */ + if ( before < 0 ) + the_blend = blends[0]; + + else if ( after < 0 ) + the_blend = blends[map->num_points - 1]; + + else + the_blend = FT_MulDiv( design - designs[before], + blends [after] - blends [before], + designs[after] - designs[before] ); + + Found: + final_blends[n] = the_blend; + } + + error = T1_Set_MM_Blend( face, num_coords, final_blends ); + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* Just a wrapper around T1_Set_MM_Design to support the different */ + /* arguments needed by the GX var distortable fonts. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Set_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Long lcoords[4]; /* maximum axis count is 4 */ + FT_UInt i; + FT_Error error; + + + error = FT_ERR( Invalid_Argument ); + if ( num_coords <= 4 && num_coords > 0 ) + { + for ( i = 0; i < num_coords; ++i ) + lcoords[i] = FIXED_TO_INT( coords[i] ); + error = T1_Set_MM_Design( face, num_coords, lcoords ); + } + + return error; + } + + + FT_LOCAL_DEF( void ) + T1_Done_Blend( T1_Face face ) + { + FT_Memory memory = face->root.memory; + PS_Blend blend = face->blend; + + + if ( blend ) + { + FT_UInt num_designs = blend->num_designs; + FT_UInt num_axis = blend->num_axis; + FT_UInt n; + + + /* release design pos table */ + FT_FREE( blend->design_pos[0] ); + for ( n = 1; n < num_designs; n++ ) + blend->design_pos[n] = NULL; + + /* release blend `private' and `font info' dictionaries */ + FT_FREE( blend->privates[1] ); + FT_FREE( blend->font_infos[1] ); + FT_FREE( blend->bboxes[1] ); + + for ( n = 0; n < num_designs; n++ ) + { + blend->privates [n] = NULL; + blend->font_infos[n] = NULL; + blend->bboxes [n] = NULL; + } + + /* release weight vectors */ + FT_FREE( blend->weight_vector ); + blend->default_weight_vector = NULL; + + /* release axis names */ + for ( n = 0; n < num_axis; n++ ) + FT_FREE( blend->axis_names[n] ); + + /* release design map */ + for ( n = 0; n < num_axis; n++ ) + { + PS_DesignMap dmap = blend->design_map + n; + + + FT_FREE( dmap->design_points ); + dmap->num_points = 0; + } + + FT_FREE( face->blend ); + } + } + + + static void + parse_blend_axis_types( T1_Face face, + T1_Loader loader ) + { + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; + FT_Int n, num_axis; + FT_Error error = FT_Err_Ok; + PS_Blend blend; + FT_Memory memory; + + + /* take an array of objects */ + T1_ToTokenArray( &loader->parser, axis_tokens, + T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis < 0 ) + { + error = FT_ERR( Ignore ); + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", + num_axis )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* allocate blend if necessary */ + error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); + if ( error ) + goto Exit; + + blend = face->blend; + memory = face->root.memory; + + /* each token is an immediate containing the name of the axis */ + for ( n = 0; n < num_axis; n++ ) + { + T1_Token token = axis_tokens + n; + FT_Byte* name; + FT_PtrDist len; + + + /* skip first slash, if any */ + if ( token->start[0] == '/' ) + token->start++; + + len = token->limit - token->start; + if ( len == 0 ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( FT_ALLOC( blend->axis_names[n], (FT_Long)( len + 1 ) ) ) + goto Exit; + + name = (FT_Byte*)blend->axis_names[n]; + FT_MEM_COPY( name, token->start, len ); + name[len] = '\0'; + } + + Exit: + loader->parser.root.error = error; + } + + + static void + parse_blend_design_positions( T1_Face face, + T1_Loader loader ) + { + T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; + FT_Int num_designs; + FT_Int num_axis; + T1_Parser parser = &loader->parser; + + FT_Error error = FT_Err_Ok; + PS_Blend blend; + + + /* get the array of design tokens -- compute number of designs */ + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) + { + error = FT_ERR( Ignore ); + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) + { + FT_ERROR(( "parse_blend_design_positions:" + " incorrect number of designs: %d\n", + num_designs )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + { + FT_Byte* old_cursor = parser->root.cursor; + FT_Byte* old_limit = parser->root.limit; + FT_Int n; + + + blend = face->blend; + num_axis = 0; /* make compiler happy */ + + for ( n = 0; n < num_designs; n++ ) + { + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; + T1_Token token; + FT_Int axis, n_axis; + + + /* read axis/coordinates tokens */ + token = design_tokens + n; + parser->root.cursor = token->start; + parser->root.limit = token->limit; + T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis ); + + if ( n == 0 ) + { + if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_positions:" + " invalid number of axes: %d\n", + n_axis )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + num_axis = n_axis; + error = t1_allocate_blend( face, num_designs, num_axis ); + if ( error ) + goto Exit; + blend = face->blend; + } + else if ( n_axis != num_axis ) + { + FT_ERROR(( "parse_blend_design_positions: incorrect table\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* now read each axis token into the design position */ + for ( axis = 0; axis < n_axis; axis++ ) + { + T1_Token token2 = axis_tokens + axis; + + + parser->root.cursor = token2->start; + parser->root.limit = token2->limit; + blend->design_pos[n][axis] = T1_ToFixed( parser, 0 ); + } + } + + loader->parser.root.cursor = old_cursor; + loader->parser.root.limit = old_limit; + } + + Exit: + loader->parser.root.error = error; + } + + + static void + parse_blend_design_map( T1_Face face, + T1_Loader loader ) + { + FT_Error error = FT_Err_Ok; + T1_Parser parser = &loader->parser; + PS_Blend blend; + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; + FT_Int n, num_axis; + FT_Byte* old_cursor; + FT_Byte* old_limit; + FT_Memory memory = face->root.memory; + + + T1_ToTokenArray( parser, axis_tokens, + T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis < 0 ) + { + error = FT_ERR( Ignore ); + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", + num_axis )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + old_cursor = parser->root.cursor; + old_limit = parser->root.limit; + + error = t1_allocate_blend( face, 0, num_axis ); + if ( error ) + goto Exit; + blend = face->blend; + + /* now read each axis design map */ + for ( n = 0; n < num_axis; n++ ) + { + PS_DesignMap map = blend->design_map + n; + T1_Token axis_token; + T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS]; + FT_Int p, num_points; + + + axis_token = axis_tokens + n; + + parser->root.cursor = axis_token->start; + parser->root.limit = axis_token->limit; + T1_ToTokenArray( parser, point_tokens, + T1_MAX_MM_MAP_POINTS, &num_points ); + + if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) + { + FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* allocate design map data */ + if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) ) + goto Exit; + map->blend_points = map->design_points + num_points; + map->num_points = (FT_Byte)num_points; + + for ( p = 0; p < num_points; p++ ) + { + T1_Token point_token; + + + point_token = point_tokens + p; + + /* don't include delimiting brackets */ + parser->root.cursor = point_token->start + 1; + parser->root.limit = point_token->limit - 1; + + map->design_points[p] = T1_ToInt( parser ); + map->blend_points [p] = T1_ToFixed( parser, 0 ); + } + } + + parser->root.cursor = old_cursor; + parser->root.limit = old_limit; + + Exit: + parser->root.error = error; + } + + + static void + parse_weight_vector( T1_Face face, + T1_Loader loader ) + { + T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; + FT_Int num_designs; + FT_Error error = FT_Err_Ok; + T1_Parser parser = &loader->parser; + PS_Blend blend = face->blend; + T1_Token token; + FT_Int n; + FT_Byte* old_cursor; + FT_Byte* old_limit; + + + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) + { + error = FT_ERR( Ignore ); + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) + { + FT_ERROR(( "parse_weight_vector:" + " incorrect number of designs: %d\n", + num_designs )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( !blend || !blend->num_designs ) + { + error = t1_allocate_blend( face, num_designs, 0 ); + if ( error ) + goto Exit; + blend = face->blend; + } + else if ( blend->num_designs != (FT_UInt)num_designs ) + { + FT_ERROR(( "parse_weight_vector:" + " /BlendDesignPosition and /WeightVector have\n" + " " + " different number of elements\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + old_cursor = parser->root.cursor; + old_limit = parser->root.limit; + + for ( n = 0; n < num_designs; n++ ) + { + token = design_tokens + n; + parser->root.cursor = token->start; + parser->root.limit = token->limit; + + blend->default_weight_vector[n] = + blend->weight_vector[n] = T1_ToFixed( parser, 0 ); + } + + parser->root.cursor = old_cursor; + parser->root.limit = old_limit; + + Exit: + parser->root.error = error; + } + + + /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def */ + /* we're only interested in the number of array elements */ + static void + parse_buildchar( T1_Face face, + T1_Loader loader ) + { + face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 ); + + return; + } + + +#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 SYMBOL PARSING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + t1_load_keyword( T1_Face face, + T1_Loader loader, + const T1_Field field ) + { + FT_Error error; + void* dummy_object; + void** objects; + FT_UInt max_objects; + PS_Blend blend = face->blend; + + + if ( blend && blend->num_designs == 0 ) + blend = NULL; + + /* if the keyword has a dedicated callback, call it */ + if ( field->type == T1_FIELD_TYPE_CALLBACK ) + { + field->reader( (FT_Face)face, loader ); + error = loader->parser.root.error; + goto Exit; + } + + /* now, the keyword is either a simple field, or a table of fields; */ + /* we are now going to take care of it */ + switch ( field->location ) + { + case T1_FIELD_LOCATION_FONT_INFO: + dummy_object = &face->type1.font_info; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->font_infos; + max_objects = blend->num_designs; + } + break; + + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + objects = &dummy_object; + max_objects = 0; + break; + + case T1_FIELD_LOCATION_PRIVATE: + dummy_object = &face->type1.private_dict; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->privates; + max_objects = blend->num_designs; + } + break; + + case T1_FIELD_LOCATION_BBOX: + dummy_object = &face->type1.font_bbox; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->bboxes; + max_objects = blend->num_designs; + } + break; + + case T1_FIELD_LOCATION_LOADER: + dummy_object = loader; + objects = &dummy_object; + max_objects = 0; + break; + + case T1_FIELD_LOCATION_FACE: + dummy_object = face; + objects = &dummy_object; + max_objects = 0; + break; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + case T1_FIELD_LOCATION_BLEND: + dummy_object = face->blend; + objects = &dummy_object; + max_objects = 0; + break; +#endif + + default: + dummy_object = &face->type1; + objects = &dummy_object; + max_objects = 0; + } + + if ( *objects ) + { + if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || + field->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = T1_Load_Field_Table( &loader->parser, field, + objects, max_objects, 0 ); + else + error = T1_Load_Field( &loader->parser, field, + objects, max_objects, 0 ); + } + else + { + FT_TRACE1(( "t1_load_keyword: ignoring keyword `%s'" + " which is not valid at this point\n" + " (probably due to missing keywords)\n", + field->ident )); + error = FT_Err_Ok; + } + + Exit: + return error; + } + + + static void + parse_private( T1_Face face, + T1_Loader loader ) + { + FT_UNUSED( face ); + + loader->keywords_encountered |= T1_PRIVATE; + } + + + static int + read_binary_data( T1_Parser parser, + FT_Long* size, + FT_Byte** base, + FT_Bool incremental ) + { + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + + + /* the binary data has one of the following formats */ + /* */ + /* `size' [white*] RD white ....... ND */ + /* `size' [white*] -| white ....... |- */ + /* */ + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + + if ( cur < limit && ft_isdigit( *cur ) ) + { + FT_Long s = T1_ToInt( parser ); + + + T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */ + + /* there is only one whitespace char after the */ + /* `RD' or `-|' token */ + *base = parser->root.cursor + 1; + + if ( s >= 0 && s < limit - *base ) + { + parser->root.cursor += s + 1; + *size = s; + return !parser->root.error; + } + } + + if( !incremental ) + { + FT_ERROR(( "read_binary_data: invalid size field\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + } + + return 0; + } + + + /* We now define the routines to handle the `/Encoding', `/Subrs', */ + /* and `/CharStrings' dictionaries. */ + + static void + t1_parse_font_matrix( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + FT_Matrix* matrix = &face->type1.font_matrix; + FT_Vector* offset = &face->type1.font_offset; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + FT_Int result; + + + result = T1_ToFixedArray( parser, 6, temp, 3 ); + + if ( result < 0 ) + { + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + temp_scale = FT_ABS( temp[3] ); + + if ( temp_scale == 0 ) + { + FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + /* Set Units per EM based on FontMatrix values. We set the value to */ + /* 1000 / temp_scale, because temp_scale was already multiplied by */ + /* 1000 (in t1_tofixed, from psobjs.c). */ + + root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + + /* we need to scale the values by 1.0/temp_scale */ + if ( temp_scale != 0x10000L ) + { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the offsets must be expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + + static void + parse_encoding( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + if ( cur >= limit ) + { + FT_ERROR(( "parse_encoding: out of bounds\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + /* if we have a number or `[', the encoding is an array, */ + /* and we must load it now */ + if ( ft_isdigit( *cur ) || *cur == '[' ) + { + T1_Encoding encode = &face->type1.encoding; + FT_Int count, n; + PS_Table char_table = &loader->encoding_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + FT_Bool only_immediates = 0; + + + /* read the number of entries in the encoding; should be 256 */ + if ( *cur == '[' ) + { + count = 256; + only_immediates = 1; + parser->root.cursor++; + } + else + count = (FT_Int)T1_ToInt( parser ); + + T1_Skip_Spaces( parser ); + if ( parser->root.cursor >= limit ) + return; + + /* we use a T1_Table to store our charnames */ + loader->num_chars = encode->num_chars = count; + if ( FT_NEW_ARRAY( encode->char_index, count ) || + FT_NEW_ARRAY( encode->char_name, count ) || + FT_SET_ERROR( psaux->ps_table_funcs->init( + char_table, count, memory ) ) ) + { + parser->root.error = error; + return; + } + + /* We need to `zero' out encoding_table.elements */ + for ( n = 0; n < count; n++ ) + { + char* notdef = (char *)".notdef"; + + + T1_Add_Table( char_table, n, notdef, 8 ); + } + + /* Now we need to read records of the form */ + /* */ + /* ... charcode /charname ... */ + /* */ + /* for each entry in our table. */ + /* */ + /* We simply look for a number followed by an immediate */ + /* name. Note that this ignores correctly the sequence */ + /* that is often seen in type1 fonts: */ + /* */ + /* 0 1 255 { 1 index exch /.notdef put } for dup */ + /* */ + /* used to clean the encoding array before anything else. */ + /* */ + /* Alternatively, if the array is directly given as */ + /* */ + /* /Encoding [ ... ] */ + /* */ + /* we only read immediates. */ + + n = 0; + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) + { + cur = parser->root.cursor; + + /* we stop when we encounter a `def' or `]' */ + if ( *cur == 'd' && cur + 3 < limit ) + { + if ( cur[1] == 'e' && + cur[2] == 'f' && + IS_PS_DELIM( cur[3] ) ) + { + FT_TRACE6(( "encoding end\n" )); + cur += 3; + break; + } + } + if ( *cur == ']' ) + { + FT_TRACE6(( "encoding end\n" )); + cur++; + break; + } + + /* check whether we've found an entry */ + if ( ft_isdigit( *cur ) || only_immediates ) + { + FT_Int charcode; + + + if ( only_immediates ) + charcode = n; + else + { + charcode = (FT_Int)T1_ToInt( parser ); + T1_Skip_Spaces( parser ); + } + + cur = parser->root.cursor; + + if ( cur + 2 < limit && *cur == '/' && n < count ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.cursor >= limit ) + return; + if ( parser->root.error ) + return; + + len = parser->root.cursor - cur; + + parser->root.error = T1_Add_Table( char_table, charcode, + cur, len + 1 ); + if ( parser->root.error ) + return; + char_table->elements[charcode][len] = '\0'; + + n++; + } + else if ( only_immediates ) + { + /* Since the current position is not updated for */ + /* immediates-only mode we would get an infinite loop if */ + /* we don't do anything here. */ + /* */ + /* This encoding array is not valid according to the type1 */ + /* specification (it might be an encoding for a CID type1 */ + /* font, however), so we conclude that this font is NOT a */ + /* type1 font. */ + parser->root.error = FT_THROW( Unknown_File_Format ); + return; + } + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + } + + T1_Skip_Spaces( parser ); + } + + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; + } + + /* Otherwise, we should have either `StandardEncoding', */ + /* `ExpertEncoding', or `ISOLatin1Encoding' */ + else + { + if ( cur + 17 < limit && + ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + + else if ( cur + 15 < limit && + ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + + else if ( cur + 18 < limit && + ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + + else + parser->root.error = FT_ERR( Ignore ); + } + } + + + static void + parse_subrs( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + PS_Table table = &loader->subrs; + FT_Memory memory = parser->root.memory; + FT_Error error; + FT_Int num_subrs; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + T1_Skip_Spaces( parser ); + + /* test for empty array */ + if ( parser->root.cursor < parser->root.limit && + *parser->root.cursor == '[' ) + { + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + if ( parser->root.cursor >= parser->root.limit || + *parser->root.cursor != ']' ) + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + num_subrs = (FT_Int)T1_ToInt( parser ); + + /* position the parser right before the `dup' of the first subr */ + T1_Skip_PS_Token( parser ); /* `array' */ + if ( parser->root.error ) + return; + T1_Skip_Spaces( parser ); + + /* initialize subrs array -- with synthetic fonts it is possible */ + /* we get here twice */ + if ( !loader->num_subrs ) + { + error = psaux->ps_table_funcs->init( table, num_subrs, memory ); + if ( error ) + goto Fail; + } + + /* the format is simple: */ + /* */ + /* `index' + binary data */ + /* */ + for (;;) + { + FT_Long idx, size; + FT_Byte* base; + + + /* If we are out of data, or if the next token isn't `dup', */ + /* we are done. */ + if ( parser->root.cursor + 4 >= parser->root.limit || + ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) + break; + + T1_Skip_PS_Token( parser ); /* `dup' */ + + idx = T1_ToInt( parser ); + + if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) + return; + + /* The binary string is followed by one token, e.g. `NP' */ + /* (bound to `noaccess put') or by two separate tokens: */ + /* `noaccess' & `put'. We position the parser right */ + /* before the next `dup', if any. */ + T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */ + if ( parser->root.error ) + return; + T1_Skip_Spaces ( parser ); + + if ( parser->root.cursor + 4 < parser->root.limit && + ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) + { + T1_Skip_PS_Token( parser ); /* skip `put' */ + T1_Skip_Spaces ( parser ); + } + + /* with synthetic fonts it is possible we get here twice */ + if ( loader->num_subrs ) + continue; + + /* some fonts use a value of -1 for lenIV to indicate that */ + /* the charstrings are unencoded */ + /* */ + /* thanks to Tom Kacvinsky for pointing this out */ + /* */ + if ( face->type1.private_dict.lenIV >= 0 ) + { + FT_Byte* temp; + + + /* some fonts define empty subr records -- this is not totally */ + /* compliant to the specification (which says they should at */ + /* least contain a `return'), but we support them anyway */ + if ( size < face->type1.private_dict.lenIV ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* t1_decrypt() shouldn't write to base -- make temporary copy */ + if ( FT_ALLOC( temp, size ) ) + goto Fail; + FT_MEM_COPY( temp, base, size ); + psaux->t1_decrypt( temp, size, 4330 ); + size -= face->type1.private_dict.lenIV; + error = T1_Add_Table( table, (FT_Int)idx, + temp + face->type1.private_dict.lenIV, size ); + FT_FREE( temp ); + } + else + error = T1_Add_Table( table, (FT_Int)idx, base, size ); + if ( error ) + goto Fail; + } + + if ( !loader->num_subrs ) + loader->num_subrs = num_subrs; + + return; + + Fail: + parser->root.error = error; + } + + +#define TABLE_EXTEND 5 + + + static void + parse_charstrings( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + PS_Table code_table = &loader->charstrings; + PS_Table name_table = &loader->glyph_names; + PS_Table swap_table = &loader->swap_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + FT_Int n, num_glyphs; + FT_UInt notdef_index = 0; + FT_Byte notdef_found = 0; + + + num_glyphs = (FT_Int)T1_ToInt( parser ); + if ( num_glyphs < 0 ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* some fonts like Optima-Oblique not only define the /CharStrings */ + /* array but access it also */ + if ( num_glyphs == 0 || parser->root.error ) + return; + + /* initialize tables, leaving space for addition of .notdef, */ + /* if necessary, and a few other glyphs to handle buggy */ + /* fonts which have more glyphs than specified. */ + + /* for some non-standard fonts like `Optima' which provides */ + /* different outlines depending on the resolution it is */ + /* possible to get here twice */ + if ( !loader->num_glyphs ) + { + error = psaux->ps_table_funcs->init( + code_table, num_glyphs + 1 + TABLE_EXTEND, memory ); + if ( error ) + goto Fail; + + error = psaux->ps_table_funcs->init( + name_table, num_glyphs + 1 + TABLE_EXTEND, memory ); + if ( error ) + goto Fail; + + /* Initialize table for swapping index notdef_index and */ + /* index 0 names and codes (if necessary). */ + + error = psaux->ps_table_funcs->init( swap_table, 4, memory ); + if ( error ) + goto Fail; + } + + n = 0; + + for (;;) + { + FT_Long size; + FT_Byte* base; + + + /* the format is simple: */ + /* `/glyphname' + binary data */ + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + if ( cur >= limit ) + break; + + /* we stop when we find a `def' or `end' keyword */ + if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) ) + { + if ( cur[0] == 'd' && + cur[1] == 'e' && + cur[2] == 'f' ) + { + /* There are fonts which have this: */ + /* */ + /* /CharStrings 118 dict def */ + /* Private begin */ + /* CharStrings begin */ + /* ... */ + /* */ + /* To catch this we ignore `def' if */ + /* no charstring has actually been */ + /* seen. */ + if ( n ) + break; + } + + if ( cur[0] == 'e' && + cur[1] == 'n' && + cur[2] == 'd' ) + break; + } + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + + if ( *cur == '/' ) + { + FT_PtrDist len; + + + if ( cur + 1 >= limit ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + cur++; /* skip `/' */ + len = parser->root.cursor - cur; + + if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) + return; + + /* for some non-standard fonts like `Optima' which provides */ + /* different outlines depending on the resolution it is */ + /* possible to get here twice */ + if ( loader->num_glyphs ) + continue; + + error = T1_Add_Table( name_table, n, cur, len + 1 ); + if ( error ) + goto Fail; + + /* add a trailing zero to the name table */ + name_table->elements[n][len] = '\0'; + + /* record index of /.notdef */ + if ( *cur == '.' && + ft_strcmp( ".notdef", + (const char*)(name_table->elements[n]) ) == 0 ) + { + notdef_index = n; + notdef_found = 1; + } + + if ( face->type1.private_dict.lenIV >= 0 && + n < num_glyphs + TABLE_EXTEND ) + { + FT_Byte* temp; + + + if ( size <= face->type1.private_dict.lenIV ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* t1_decrypt() shouldn't write to base -- make temporary copy */ + if ( FT_ALLOC( temp, size ) ) + goto Fail; + FT_MEM_COPY( temp, base, size ); + psaux->t1_decrypt( temp, size, 4330 ); + size -= face->type1.private_dict.lenIV; + error = T1_Add_Table( code_table, n, + temp + face->type1.private_dict.lenIV, size ); + FT_FREE( temp ); + } + else + error = T1_Add_Table( code_table, n, base, size ); + if ( error ) + goto Fail; + + n++; + } + } + + loader->num_glyphs = n; + + /* if /.notdef is found but does not occupy index 0, do our magic. */ + if ( notdef_found && + ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) ) + { + /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ + /* name and code entries to swap_table. Then place notdef_index */ + /* name and code entries into swap_table. Then swap name and code */ + /* entries at indices notdef_index and 0 using values stored in */ + /* swap_table. */ + + /* Index 0 name */ + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index 0 code */ + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index notdef_index name */ + error = T1_Add_Table( swap_table, 2, + name_table->elements[notdef_index], + name_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + /* Index notdef_index code */ + error = T1_Add_Table( swap_table, 3, + code_table->elements[notdef_index], + code_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, notdef_index, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, notdef_index, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, + swap_table->elements[2], + swap_table->lengths [2] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, + swap_table->elements[3], + swap_table->lengths [3] ); + if ( error ) + goto Fail; + + } + else if ( !notdef_found ) + { + /* notdef_index is already 0, or /.notdef is undefined in */ + /* charstrings dictionary. Worry about /.notdef undefined. */ + /* We take index 0 and add it to the end of the table(s) */ + /* and add our own /.notdef glyph to index 0. */ + + /* 0 333 hsbw endchar */ + FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E }; + char* notdef_name = (char *)".notdef"; + + + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, notdef_name, 8 ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, notdef_glyph, 5 ); + + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, n, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, n, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + /* we added a glyph. */ + loader->num_glyphs += 1; + } + + return; + + Fail: + parser->root.error = error; + } + + + /*************************************************************************/ + /* */ + /* Define the token field static variables. This is a set of */ + /* T1_FieldRec variables. */ + /* */ + /*************************************************************************/ + + + static + const T1_FieldRec t1_keywords[] = + { + +#include "t1tokens.h" + + /* now add the special functions... */ + T1_FIELD_CALLBACK( "FontMatrix", t1_parse_font_matrix, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "Encoding", parse_encoding, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "Subrs", parse_subrs, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_CALLBACK( "CharStrings", parse_charstrings, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_CALLBACK( "Private", parse_private, + T1_FIELD_DICT_FONTDICT ) + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar, + T1_FIELD_DICT_PRIVATE ) +#endif + + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } + }; + + +#define T1_FIELD_COUNT \ + ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) ) + + + static FT_Error + parse_dict( T1_Face face, + T1_Loader loader, + FT_Byte* base, + FT_Long size ) + { + T1_Parser parser = &loader->parser; + FT_Byte *limit, *start_binary = NULL; + FT_Bool have_integer = 0; + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = FT_Err_Ok; + + limit = parser->root.limit; + + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) + { + FT_Byte* cur; + + + cur = parser->root.cursor; + + /* look for `eexec' */ + if ( IS_PS_TOKEN( cur, limit, "eexec" ) ) + break; + + /* look for `closefile' which ends the eexec section */ + else if ( IS_PS_TOKEN( cur, limit, "closefile" ) ) + break; + + /* in a synthetic font the base font starts after a */ + /* `FontDictionary' token that is placed after a Private dict */ + else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) ) + { + if ( loader->keywords_encountered & T1_PRIVATE ) + loader->keywords_encountered |= + T1_FONTDIR_AFTER_PRIVATE; + parser->root.cursor += 13; + } + + /* check whether we have an integer */ + else if ( ft_isdigit( *cur ) ) + { + start_binary = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + have_integer = 1; + } + + /* in valid Type 1 fonts we don't see `RD' or `-|' directly */ + /* since those tokens are handled by parse_subrs and */ + /* parse_charstrings */ + else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' && + have_integer ) + { + FT_Long s; + FT_Byte* b; + + + parser->root.cursor = start_binary; + if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) ) + return FT_THROW( Invalid_File_Format ); + have_integer = 0; + } + + else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' && + have_integer ) + { + FT_Long s; + FT_Byte* b; + + + parser->root.cursor = start_binary; + if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) ) + return FT_THROW( Invalid_File_Format ); + have_integer = 0; + } + + /* look for immediates */ + else if ( *cur == '/' && cur + 2 < limit ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + + len = parser->root.cursor - cur; + + if ( len > 0 && len < 22 && parser->root.cursor < limit ) + { + /* now compare the immediate name to the keyword table */ + T1_Field keyword = (T1_Field)t1_keywords; + + + for (;;) + { + FT_Byte* name; + + + name = (FT_Byte*)keyword->ident; + if ( !name ) + break; + + if ( cur[0] == name[0] && + len == (FT_PtrDist)ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) + { + /* We found it -- run the parsing callback! */ + /* We record every instance of every field */ + /* (until we reach the base font of a */ + /* synthetic font) to deal adequately with */ + /* multiple master fonts; this is also */ + /* necessary because later PostScript */ + /* definitions override earlier ones. */ + + /* Once we encounter `FontDirectory' after */ + /* `/Private', we know that this is a synthetic */ + /* font; except for `/CharStrings' we are not */ + /* interested in anything that follows this */ + /* `FontDirectory'. */ + + /* MM fonts have more than one /Private token at */ + /* the top level; let's hope that all the junk */ + /* that follows the first /Private token is not */ + /* interesting to us. */ + + /* According to Adobe Tech Note #5175 (CID-Keyed */ + /* Font Installation for ATM Software) a `begin' */ + /* must be followed by exactly one `end', and */ + /* `begin' -- `end' pairs must be accurately */ + /* paired. We could use this to distinguish */ + /* between the global Private and the Private */ + /* dict that is a member of the Blend dict. */ + + const FT_UInt dict = + ( loader->keywords_encountered & T1_PRIVATE ) + ? T1_FIELD_DICT_PRIVATE + : T1_FIELD_DICT_FONTDICT; + + if ( !( dict & keyword->dict ) ) + { + FT_TRACE1(( "parse_dict: found `%s' but ignoring it" + " since it is in the wrong dictionary\n", + keyword->ident )); + break; + } + + if ( !( loader->keywords_encountered & + T1_FONTDIR_AFTER_PRIVATE ) || + ft_strcmp( (const char*)name, "CharStrings" ) == 0 ) + { + parser->root.error = t1_load_keyword( face, + loader, + keyword ); + if ( parser->root.error != FT_Err_Ok ) + { + if ( FT_ERR_EQ( parser->root.error, Ignore ) ) + parser->root.error = FT_Err_Ok; + else + return parser->root.error; + } + } + break; + } + + keyword++; + } + } + + have_integer = 0; + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + have_integer = 0; + } + + T1_Skip_Spaces( parser ); + } + + Exit: + return parser->root.error; + } + + + static void + t1_init_loader( T1_Loader loader, + T1_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + loader->num_glyphs = 0; + loader->num_chars = 0; + + /* initialize the tables -- simply set their `init' field to 0 */ + loader->encoding_table.init = 0; + loader->charstrings.init = 0; + loader->glyph_names.init = 0; + loader->subrs.init = 0; + loader->swap_table.init = 0; + loader->fontdata = 0; + loader->keywords_encountered = 0; + } + + + static void + t1_done_loader( T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + + + /* finalize tables */ + T1_Release_Table( &loader->encoding_table ); + T1_Release_Table( &loader->charstrings ); + T1_Release_Table( &loader->glyph_names ); + T1_Release_Table( &loader->swap_table ); + T1_Release_Table( &loader->subrs ); + + /* finalize parser */ + T1_Finalize_Parser( parser ); + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Open_Face( T1_Face face ) + { + T1_LoaderRec loader; + T1_Parser parser; + T1_Font type1 = &face->type1; + PS_Private priv = &type1->private_dict; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + t1_init_loader( &loader, face ); + + /* default values */ + face->ndv_idx = -1; + face->cdv_idx = -1; + face->len_buildchar = 0; + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = 4; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); + + parser = &loader.parser; + error = T1_New_Parser( parser, + face->root.stream, + face->root.memory, + psaux ); + if ( error ) + goto Exit; + + error = parse_dict( face, &loader, + parser->base_dict, parser->base_len ); + if ( error ) + goto Exit; + + error = T1_Get_Private_Dict( parser, psaux ); + if ( error ) + goto Exit; + + error = parse_dict( face, &loader, + parser->private_dict, parser->private_len ); + if ( error ) + goto Exit; + + /* ensure even-ness of `num_blue_values' */ + priv->num_blue_values &= ~1; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + if ( face->blend && + face->blend->num_default_design_vector != 0 && + face->blend->num_default_design_vector != face->blend->num_axis ) + { + /* we don't use it currently so just warn, reset, and ignore */ + FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries " + "while there are %u axes.\n", + face->blend->num_default_design_vector, + face->blend->num_axis )); + + face->blend->num_default_design_vector = 0; + } + + /* the following can happen for MM instances; we then treat the */ + /* font as a normal PS font */ + if ( face->blend && + ( !face->blend->num_designs || !face->blend->num_axis ) ) + T1_Done_Blend( face ); + + /* another safety check */ + if ( face->blend ) + { + FT_UInt i; + + + for ( i = 0; i < face->blend->num_axis; i++ ) + if ( !face->blend->design_map[i].num_points ) + { + T1_Done_Blend( face ); + break; + } + } + + if ( face->blend ) + { + if ( face->len_buildchar > 0 ) + { + FT_Memory memory = face->root.memory; + + + if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) ) + { + FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" )); + face->len_buildchar = 0; + goto Exit; + } + } + } + else + face->len_buildchar = 0; + +#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + /* now, propagate the subrs, charstrings, and glyphnames tables */ + /* to the Type1 data */ + type1->num_glyphs = loader.num_glyphs; + + if ( loader.subrs.init ) + { + loader.subrs.init = 0; + type1->num_subrs = loader.num_subrs; + type1->subrs_block = loader.subrs.block; + type1->subrs = loader.subrs.elements; + type1->subrs_len = loader.subrs.lengths; + } + + if ( !IS_INCREMENTAL ) + if ( !loader.charstrings.init ) + { + FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" )); + error = FT_THROW( Invalid_File_Format ); + } + + loader.charstrings.init = 0; + type1->charstrings_block = loader.charstrings.block; + type1->charstrings = loader.charstrings.elements; + type1->charstrings_len = loader.charstrings.lengths; + + /* we copy the glyph names `block' and `elements' fields; */ + /* the `lengths' field must be released later */ + type1->glyph_names_block = loader.glyph_names.block; + type1->glyph_names = (FT_String**)loader.glyph_names.elements; + loader.glyph_names.block = 0; + loader.glyph_names.elements = 0; + + /* we must now build type1.encoding when we have a custom array */ + if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) + { + FT_Int charcode, idx, min_char, max_char; + FT_Byte* char_name; + FT_Byte* glyph_name; + + + /* OK, we do the following: for each element in the encoding */ + /* table, look up the index of the glyph having the same name */ + /* the index is then stored in type1.encoding.char_index, and */ + /* the name to type1.encoding.char_name */ + + min_char = 0; + max_char = 0; + + charcode = 0; + for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) + { + type1->encoding.char_index[charcode] = 0; + type1->encoding.char_name [charcode] = (char *)".notdef"; + + char_name = loader.encoding_table.elements[charcode]; + if ( char_name ) + for ( idx = 0; idx < type1->num_glyphs; idx++ ) + { + glyph_name = (FT_Byte*)type1->glyph_names[idx]; + if ( ft_strcmp( (const char*)char_name, + (const char*)glyph_name ) == 0 ) + { + type1->encoding.char_index[charcode] = (FT_UShort)idx; + type1->encoding.char_name [charcode] = (char*)glyph_name; + + /* Change min/max encoded char only if glyph name is */ + /* not /.notdef */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)glyph_name ) != 0 ) + { + if ( charcode < min_char ) + min_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; + } + break; + } + } + } + + type1->encoding.code_first = min_char; + type1->encoding.code_last = max_char; + type1->encoding.num_chars = loader.num_chars; + } + + Exit: + t1_done_loader( &loader ); + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/type1/t1load.h b/drivers/freetype/src/type1/t1load.h new file mode 100644 index 0000000000..546fc33530 --- /dev/null +++ b/drivers/freetype/src/type1/t1load.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* t1load.h */ +/* */ +/* Type 1 font loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 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 __T1LOAD_H__ +#define __T1LOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_MULTIPLE_MASTERS_H + +#include "t1parse.h" + + +FT_BEGIN_HEADER + + + typedef struct T1_Loader_ + { + T1_ParserRec parser; /* parser used to read the stream */ + + FT_Int num_chars; /* number of characters in encoding */ + PS_TableRec encoding_table; /* PS_Table used to store the */ + /* encoding character names */ + + FT_Int num_glyphs; + PS_TableRec glyph_names; + PS_TableRec charstrings; + PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ + + FT_Int num_subrs; + PS_TableRec subrs; + FT_Bool fontdata; + + FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */ + + } T1_LoaderRec, *T1_Loader; + + + /* treatment of some keywords differs depending on whether */ + /* they precede or follow certain other keywords */ + +#define T1_PRIVATE ( 1 << 0 ) +#define T1_FONTDIR_AFTER_PRIVATE ( 1 << 1 ) + + + FT_LOCAL( FT_Error ) + T1_Open_Face( T1_Face face ); + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + FT_LOCAL( FT_Error ) + T1_Get_Multi_Master( T1_Face face, + FT_Multi_Master* master ); + + FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_Var( T1_Face face, + FT_MM_Var* *master ); + + FT_LOCAL( FT_Error ) + T1_Set_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) + T1_Set_MM_Design( T1_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + FT_LOCAL_DEF( FT_Error ) + T1_Set_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( void ) + T1_Done_Blend( T1_Face face ); + +#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + +FT_END_HEADER + +#endif /* __T1LOAD_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type1/t1objs.c b/drivers/freetype/src/type1/t1objs.c new file mode 100644 index 0000000000..837b7911d4 --- /dev/null +++ b/drivers/freetype/src/type1/t1objs.c @@ -0,0 +1,616 @@ +/***************************************************************************/ +/* */ +/* t1objs.c */ +/* */ +/* Type 1 objects manager (body). */ +/* */ +/* Copyright 1996-2009, 2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_IDS_H + +#include "t1gload.h" +#include "t1load.h" + +#include "t1errors.h" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.h" +#endif + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_AUX_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_t1objs + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /* note that we store the global hints in the size's "internal" root */ + /* field */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + T1_Size_Get_Globals_Funcs( T1_Size size ) + { + T1_Face face = (T1_Face)size->root.face; + PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->root.face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0 ; + } + + + FT_LOCAL_DEF( void ) + T1_Size_Done( FT_Size t1size ) /* T1_Size */ + { + T1_Size size = (T1_Size)t1size; + + + if ( size->root.internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = T1_Size_Get_Globals_Funcs( size ); + if ( funcs ) + funcs->destroy( (PSH_Globals)size->root.internal ); + + size->root.internal = 0; + } + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Size_Init( FT_Size t1size ) /* T1_Size */ + { + T1_Size size = (T1_Size)t1size; + FT_Error error = FT_Err_Ok; + PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); + + + if ( funcs ) + { + PSH_Globals globals; + T1_Face face = (T1_Face)size->root.face; + + + error = funcs->create( size->root.face->memory, + &face->type1.private_dict, &globals ); + if ( !error ) + size->root.internal = (FT_Size_Internal)(void*)globals; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Size_Request( FT_Size t1size, /* T1_Size */ + FT_Size_Request req ) + { + T1_Size size = (T1_Size)t1size; + PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); + + + FT_Request_Metrics( size->root.face, req ); + + if ( funcs ) + funcs->set_scale( (PSH_Globals)size->root.internal, + size->root.metrics.x_scale, + size->root.metrics.y_scale, + 0, 0 ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + T1_GlyphSlot_Done( FT_GlyphSlot slot ) + { + slot->internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_GlyphSlot_Init( FT_GlyphSlot slot ) + { + T1_Face face; + PSHinter_Service pshinter; + + + face = (T1_Face)slot->face; + pshinter = (PSHinter_Service)face->pshinter; + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->face->driver->root.library, + "pshinter" ); + if ( module ) + { + T1_Hints_Funcs funcs; + + + funcs = pshinter->get_t1_funcs( module ); + slot->internal->glyph_hints = (void*)funcs; + } + } + + return 0; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T1_Face_Done */ + /* */ + /* <Description> */ + /* The face object destructor. */ + /* */ + /* <Input> */ + /* face :: A typeless pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + T1_Face_Done( FT_Face t1face ) /* T1_Face */ + { + T1_Face face = (T1_Face)t1face; + FT_Memory memory; + T1_Font type1; + + + if ( !face ) + return; + + memory = face->root.memory; + type1 = &face->type1; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + /* release multiple masters information */ + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + + if ( face->buildchar ) + { + FT_FREE( face->buildchar ); + + face->buildchar = NULL; + face->len_buildchar = 0; + } + + T1_Done_Blend( face ); + face->blend = 0; +#endif + + /* release font info strings */ + { + PS_FontInfo info = &type1->font_info; + + + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + } + + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); + + FT_FREE( type1->subrs ); + FT_FREE( type1->subrs_len ); + + FT_FREE( type1->subrs_block ); + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); + + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); + +#ifndef T1_CONFIG_OPTION_NO_AFM + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); +#endif + + /* release unicode map, if any */ +#if 0 + FT_FREE( face->unicode_map_rec.maps ); + face->unicode_map_rec.num_maps = 0; + face->unicode_map = NULL; +#endif + + face->root.family_name = NULL; + face->root.style_name = NULL; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T1_Face_Init */ + /* */ + /* <Description> */ + /* The face object constructor. */ + /* */ + /* <Input> */ + /* stream :: input stream where to load font data. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* <InOut> */ + /* face :: The face record to build. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Face_Init( FT_Stream stream, + FT_Face t1face, /* T1_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + T1_Face face = (T1_Face)t1face; + FT_Error error; + FT_Service_PsCMaps psnames; + PSAux_Service psaux; + T1_Font type1 = &face->type1; + PS_FontInfo info = &type1->font_info; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( stream ); + + + face->root.num_faces = 1; + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + face->psnames = psnames; + + face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "psaux" ); + psaux = (PSAux_Service)face->psaux; + if ( !psaux ) + { + FT_ERROR(( "T1_Face_Init: cannot access `psaux' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + + face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "pshinter" ); + + FT_TRACE2(( "Type 1 driver\n" )); + + /* open the tokenizer; this will also check the font format */ + error = T1_Open_Face( face ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + if ( face_index > 0 ) + { + FT_ERROR(( "T1_Face_Init: invalid face index\n" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* now load the font program into the face object */ + + /* initialize the face object fields */ + + /* set up root face fields */ + { + FT_Face root = (FT_Face)&face->root; + + + root->num_glyphs = type1->num_glyphs; + root->face_index = 0; + + root->face_flags = FT_FACE_FLAG_SCALABLE | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_GLYPH_NAMES | + FT_FACE_FLAG_HINTER; + + if ( info->is_fixed_pitch ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( face->blend ) + root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + + /* XXX: TODO -- add kerning with .afm support */ + + + /* The following code to extract the family and the style is very */ + /* simplistic and might get some things wrong. For a full-featured */ + /* algorithm you might have a look at the whitepaper given at */ + /* */ + /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ + + /* get style name -- be careful, some broken fonts only */ + /* have a `/FontName' dictionary entry! */ + root->family_name = info->family_name; + root->style_name = NULL; + + if ( root->family_name ) + { + char* full = info->full_name; + char* family = root->family_name; + + + if ( full ) + { + FT_Bool the_same = TRUE; + + + while ( *full ) + { + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + the_same = FALSE; + + if ( !*family ) + root->style_name = full; + break; + } + } + } + + if ( the_same ) + root->style_name = (char *)"Regular"; + } + } + else + { + /* do we have a `/FontName'? */ + if ( type1->font_name ) + root->family_name = type1->font_name; + } + + if ( !root->style_name ) + { + if ( info->weight ) + root->style_name = info->weight; + else + /* assume `Regular' style because we don't know better */ + root->style_name = (char *)"Regular"; + } + + /* compute style flags */ + root->style_flags = 0; + if ( info->italic_angle ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + if ( info->weight ) + { + if ( !ft_strcmp( info->weight, "Bold" ) || + !ft_strcmp( info->weight, "Black" ) ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + } + + /* no embedded bitmap support */ + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + root->bbox.xMin = type1->font_bbox.xMin >> 16; + root->bbox.yMin = type1->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16; + root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16; + + /* Set units_per_EM if we didn't set it in t1_parse_font_matrix. */ + if ( !root->units_per_EM ) + root->units_per_EM = 1000; + + root->ascender = (FT_Short)( root->bbox.yMax ); + root->descender = (FT_Short)( root->bbox.yMin ); + + root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 ); + if ( root->height < root->ascender - root->descender ) + root->height = (FT_Short)( root->ascender - root->descender ); + + /* now compute the maximum advance width */ + root->max_advance_width = + (FT_Short)( root->bbox.xMax ); + { + FT_Pos max_advance; + + + error = T1_Compute_Max_Advance( face, &max_advance ); + + /* in case of error, keep the standard width */ + if ( !error ) + root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); + else + error = FT_Err_Ok; /* clear error */ + } + + root->max_advance_height = root->height; + + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; + } + + { + FT_Face root = &face->root; + + + if ( psnames ) + { + FT_CharMapRec charmap; + T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; + FT_CMap_Class clazz; + + + charmap.face = root; + + /* first of all, try to synthesize a Unicode charmap */ + charmap.platform_id = TT_PLATFORM_MICROSOFT; + charmap.encoding_id = TT_MS_ID_UNICODE_CS; + charmap.encoding = FT_ENCODING_UNICODE; + + error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); + if ( error && + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + goto Exit; + error = FT_Err_Ok; + + /* now, generate an Adobe Standard encoding when appropriate */ + charmap.platform_id = TT_PLATFORM_ADOBE; + clazz = NULL; + + switch ( type1->encoding_type ) + { + case T1_ENCODING_TYPE_STANDARD: + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.encoding_id = TT_ADOBE_ID_STANDARD; + clazz = cmap_classes->standard; + break; + + case T1_ENCODING_TYPE_EXPERT: + charmap.encoding = FT_ENCODING_ADOBE_EXPERT; + charmap.encoding_id = TT_ADOBE_ID_EXPERT; + clazz = cmap_classes->expert; + break; + + case T1_ENCODING_TYPE_ARRAY: + charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; + charmap.encoding_id = TT_ADOBE_ID_CUSTOM; + clazz = cmap_classes->custom; + break; + + case T1_ENCODING_TYPE_ISOLATIN1: + charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; + charmap.encoding_id = TT_ADOBE_ID_LATIN_1; + clazz = cmap_classes->unicode; + break; + + default: + ; + } + + if ( clazz ) + error = FT_CMap_New( clazz, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if (root->num_charmaps) + root->charmap = root->charmaps[0]; +#endif + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T1_Driver_Init */ + /* */ + /* <Description> */ + /* Initializes a given Type 1 driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Driver_Init( FT_Module driver ) + { + FT_UNUSED( driver ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T1_Driver_Done */ + /* */ + /* <Description> */ + /* Finalizes a given Type 1 driver. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target Type 1 driver. */ + /* */ + FT_LOCAL_DEF( void ) + T1_Driver_Done( FT_Module driver ) + { + FT_UNUSED( driver ); + } + + +/* END */ diff --git a/drivers/freetype/src/type1/t1objs.h b/drivers/freetype/src/type1/t1objs.h new file mode 100644 index 0000000000..54ccbb996a --- /dev/null +++ b/drivers/freetype/src/type1/t1objs.h @@ -0,0 +1,160 @@ +/***************************************************************************/ +/* */ +/* t1objs.h */ +/* */ +/* Type 1 objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2006, 2011 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 __T1OBJS_H__ +#define __T1OBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + /* The following structures must be defined by the hinter */ + typedef struct T1_Size_Hints_ T1_Size_Hints; + typedef struct T1_Glyph_Hints_ T1_Glyph_Hints; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_Size */ + /* */ + /* <Description> */ + /* A handle to a Type 1 size object. */ + /* */ + typedef struct T1_SizeRec_* T1_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a Type 1 glyph slot object. */ + /* */ + typedef struct T1_GlyphSlotRec_* T1_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_CharMap */ + /* */ + /* <Description> */ + /* A handle to a Type 1 character mapping object. */ + /* */ + /* <Note> */ + /* The Type 1 format doesn't use a charmap but an encoding table. */ + /* The driver is responsible for making up charmap objects */ + /* corresponding to these tables. */ + /* */ + typedef struct T1_CharMapRec_* T1_CharMap; + + + /*************************************************************************/ + /* */ + /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_SizeRec */ + /* */ + /* <Description> */ + /* Type 1 size record. */ + /* */ + typedef struct T1_SizeRec_ + { + FT_SizeRec root; + + } T1_SizeRec; + + + FT_LOCAL( void ) + T1_Size_Done( FT_Size size ); + + FT_LOCAL( FT_Error ) + T1_Size_Request( FT_Size size, + FT_Size_Request req ); + + FT_LOCAL( FT_Error ) + T1_Size_Init( FT_Size size ); + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_GlyphSlotRec */ + /* */ + /* <Description> */ + /* Type 1 glyph slot record. */ + /* */ + typedef struct T1_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Int max_points; + FT_Int max_contours; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } T1_GlyphSlotRec; + + + FT_LOCAL( FT_Error ) + T1_Face_Init( FT_Stream stream, + FT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + T1_Face_Done( FT_Face face ); + + FT_LOCAL( FT_Error ) + T1_GlyphSlot_Init( FT_GlyphSlot slot ); + + FT_LOCAL( void ) + T1_GlyphSlot_Done( FT_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + T1_Driver_Init( FT_Module driver ); + + FT_LOCAL( void ) + T1_Driver_Done( FT_Module driver ); + + +FT_END_HEADER + +#endif /* __T1OBJS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type1/t1parse.c b/drivers/freetype/src/type1/t1parse.c new file mode 100644 index 0000000000..106e4e7ecd --- /dev/null +++ b/drivers/freetype/src/type1/t1parse.c @@ -0,0 +1,497 @@ +/***************************************************************************/ +/* */ +/* t1parse.c */ +/* */ +/* Type 1 parser (body). */ +/* */ +/* Copyright 1996-2005, 2008, 2009, 2012, 2013 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The Type 1 parser is in charge of the following: */ + /* */ + /* - provide an implementation of a growing sequence of objects called */ + /* a `T1_Table' (used to build various tables needed by the loader). */ + /* */ + /* - opening .pfb and .pfa files to extract their top-level and private */ + /* dictionaries. */ + /* */ + /* - read numbers, arrays & strings from any dictionary. */ + /* */ + /* See `t1load.c' to see how data is loaded from the font file. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "t1parse.h" + +#include "t1errors.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_t1parse + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INPUT STREAM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* see Adobe Technical Note 5040.Download_Fonts.pdf */ + + static FT_Error + read_pfb_tag( FT_Stream stream, + FT_UShort *atag, + FT_ULong *asize ) + { + FT_Error error; + FT_UShort tag; + FT_ULong size; + + + *atag = 0; + *asize = 0; + + if ( !FT_READ_USHORT( tag ) ) + { + if ( tag == 0x8001U || tag == 0x8002U ) + { + if ( !FT_READ_ULONG_LE( size ) ) + *asize = size; + } + + *atag = tag; + } + + return error; + } + + + static FT_Error + check_type1_format( FT_Stream stream, + const char* header_string, + size_t header_length ) + { + FT_Error error; + FT_UShort tag; + FT_ULong dummy; + + + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + error = read_pfb_tag( stream, &tag, &dummy ); + if ( error ) + goto Exit; + + /* We assume that the first segment in a PFB is always encoded as */ + /* text. This might be wrong (and the specification doesn't insist */ + /* on that), but we have never seen a counterexample. */ + if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) + goto Exit; + + if ( !FT_FRAME_ENTER( header_length ) ) + { + error = FT_Err_Ok; + + if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) + error = FT_THROW( Unknown_File_Format ); + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_New_Parser( T1_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error; + FT_UShort tag; + FT_ULong size; + + + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + + parser->stream = stream; + parser->base_len = 0; + parser->base_dict = 0; + parser->private_len = 0; + parser->private_dict = 0; + parser->in_pfb = 0; + parser->in_memory = 0; + parser->single_block = 0; + + /* check the header format */ + error = check_type1_format( stream, "%!PS-AdobeFont", 14 ); + if ( error ) + { + if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) + goto Exit; + + error = check_type1_format( stream, "%!FontType", 10 ); + if ( error ) + { + FT_TRACE2(( " not a Type 1 font\n" )); + goto Exit; + } + } + + /******************************************************************/ + /* */ + /* Here a short summary of what is going on: */ + /* */ + /* When creating a new Type 1 parser, we try to locate and load */ + /* the base dictionary if this is possible (i.e., for PFB */ + /* files). Otherwise, we load the whole font into memory. */ + /* */ + /* When `loading' the base dictionary, we only setup pointers */ + /* in the case of a memory-based stream. Otherwise, we */ + /* allocate and load the base dictionary in it. */ + /* */ + /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ + /* parser->in_memory is set if we have a memory stream. */ + /* */ + + /* try to compute the size of the base dictionary; */ + /* look for a Postscript binary file tag, i.e., 0x8001 */ + if ( FT_STREAM_SEEK( 0L ) ) + goto Exit; + + error = read_pfb_tag( stream, &tag, &size ); + if ( error ) + goto Exit; + + if ( tag != 0x8001U ) + { + /* assume that this is a PFA file for now; an error will */ + /* be produced later when more things are checked */ + if ( FT_STREAM_SEEK( 0L ) ) + goto Exit; + size = stream->size; + } + else + parser->in_pfb = 1; + + /* now, try to load `size' bytes of the `base' dictionary we */ + /* found previously */ + + /* if it is a memory-based resource, set up pointers */ + if ( !stream->read ) + { + parser->base_dict = (FT_Byte*)stream->base + stream->pos; + parser->base_len = size; + parser->in_memory = 1; + + /* check that the `size' field is valid */ + if ( FT_STREAM_SKIP( size ) ) + goto Exit; + } + else + { + /* read segment in memory -- this is clumsy, but so does the format */ + if ( FT_ALLOC( parser->base_dict, size ) || + FT_STREAM_READ( parser->base_dict, size ) ) + goto Exit; + parser->base_len = size; + } + + parser->root.base = parser->base_dict; + parser->root.cursor = parser->base_dict; + parser->root.limit = parser->root.cursor + parser->base_len; + + Exit: + if ( error && !parser->in_memory ) + FT_FREE( parser->base_dict ); + + return error; + } + + + FT_LOCAL_DEF( void ) + T1_Finalize_Parser( T1_Parser parser ) + { + FT_Memory memory = parser->root.memory; + + + /* always free the private dictionary */ + FT_FREE( parser->private_dict ); + + /* free the base dictionary only when we have a disk stream */ + if ( !parser->in_memory ) + FT_FREE( parser->base_dict ); + + parser->root.funcs.done( &parser->root ); + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Private_Dict( T1_Parser parser, + PSAux_Service psaux ) + { + FT_Stream stream = parser->stream; + FT_Memory memory = parser->root.memory; + FT_Error error = FT_Err_Ok; + FT_ULong size; + + + if ( parser->in_pfb ) + { + /* in the case of the PFB format, the private dictionary can be */ + /* made of several segments. We thus first read the number of */ + /* segments to compute the total size of the private dictionary */ + /* then re-read them into memory. */ + FT_Long start_pos = FT_STREAM_POS(); + FT_UShort tag; + + + parser->private_len = 0; + for (;;) + { + error = read_pfb_tag( stream, &tag, &size ); + if ( error ) + goto Fail; + + if ( tag != 0x8002U ) + break; + + parser->private_len += size; + + if ( FT_STREAM_SKIP( size ) ) + goto Fail; + } + + /* Check that we have a private dictionary there */ + /* and allocate private dictionary buffer */ + if ( parser->private_len == 0 ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " invalid private dictionary section\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + if ( FT_STREAM_SEEK( start_pos ) || + FT_ALLOC( parser->private_dict, parser->private_len ) ) + goto Fail; + + parser->private_len = 0; + for (;;) + { + error = read_pfb_tag( stream, &tag, &size ); + if ( error || tag != 0x8002U ) + { + error = FT_Err_Ok; + break; + } + + if ( FT_STREAM_READ( parser->private_dict + parser->private_len, + size ) ) + goto Fail; + + parser->private_len += size; + } + } + else + { + /* We have already `loaded' the whole PFA font file into memory; */ + /* if this is a memory resource, allocate a new block to hold */ + /* the private dict. Otherwise, simply overwrite into the base */ + /* dictionary block in the heap. */ + + /* first of all, look at the `eexec' keyword */ + FT_Byte* cur = parser->base_dict; + FT_Byte* limit = cur + parser->base_len; + FT_Byte c; + + + Again: + for (;;) + { + c = cur[0]; + if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ + /* whitespace + 4 chars */ + { + if ( cur[1] == 'e' && + cur[2] == 'x' && + cur[3] == 'e' && + cur[4] == 'c' ) + break; + } + cur++; + if ( cur >= limit ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " could not find `eexec' keyword\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + + /* check whether `eexec' was real -- it could be in a comment */ + /* or string (as e.g. in u003043t.gsf from ghostscript) */ + + parser->root.cursor = parser->base_dict; + /* set limit to `eexec' + whitespace + 4 characters */ + parser->root.limit = cur + 10; + + cur = parser->root.cursor; + limit = parser->root.limit; + + while ( cur < limit ) + { + if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) + goto Found; + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + break; + T1_Skip_Spaces ( parser ); + cur = parser->root.cursor; + } + + /* we haven't found the correct `eexec'; go back and continue */ + /* searching */ + + cur = limit; + limit = parser->base_dict + parser->base_len; + goto Again; + + /* now determine where to write the _encrypted_ binary private */ + /* dictionary. We overwrite the base dictionary for disk-based */ + /* resources and allocate a new block otherwise */ + + Found: + parser->root.limit = parser->base_dict + parser->base_len; + + T1_Skip_PS_Token( parser ); + cur = parser->root.cursor; + limit = parser->root.limit; + + /* according to the Type1 spec, the first cipher byte must not be */ + /* an ASCII whitespace character code (blank, tab, carriage return */ + /* or line feed). We have seen Type 1 fonts with two line feed */ + /* characters... So skip now all whitespace character codes. */ + while ( cur < limit && + ( *cur == ' ' || + *cur == '\t' || + *cur == '\r' || + *cur == '\n' ) ) + ++cur; + if ( cur >= limit ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " `eexec' not properly terminated\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + size = (FT_ULong)( parser->base_len - ( cur - parser->base_dict ) ); + + if ( parser->in_memory ) + { + /* note that we allocate one more byte to put a terminating `0' */ + if ( FT_ALLOC( parser->private_dict, size + 1 ) ) + goto Fail; + parser->private_len = size; + } + else + { + parser->single_block = 1; + parser->private_dict = parser->base_dict; + parser->private_len = size; + parser->base_dict = 0; + parser->base_len = 0; + } + + /* now determine whether the private dictionary is encoded in binary */ + /* or hexadecimal ASCII format -- decode it accordingly */ + + /* we need to access the next 4 bytes (after the final whitespace */ + /* following the `eexec' keyword); if they all are hexadecimal */ + /* digits, then we have a case of ASCII storage */ + + if ( cur + 3 < limit && + ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && + ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) + { + /* ASCII hexadecimal encoding */ + FT_Long len; + + + parser->root.cursor = cur; + (void)psaux->ps_parser_funcs->to_bytes( &parser->root, + parser->private_dict, + parser->private_len, + &len, + 0 ); + parser->private_len = len; + + /* put a safeguard */ + parser->private_dict[len] = '\0'; + } + else + /* binary encoding -- copy the private dict */ + FT_MEM_MOVE( parser->private_dict, cur, size ); + } + + /* we now decrypt the encoded binary private dictionary */ + psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U ); + + if ( parser->private_len < 4 ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " invalid private dictionary section\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* replace the four random bytes at the beginning with whitespace */ + parser->private_dict[0] = ' '; + parser->private_dict[1] = ' '; + parser->private_dict[2] = ' '; + parser->private_dict[3] = ' '; + + parser->root.base = parser->private_dict; + parser->root.cursor = parser->private_dict; + parser->root.limit = parser->root.cursor + parser->private_len; + + Fail: + Exit: + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/type1/t1parse.h b/drivers/freetype/src/type1/t1parse.h new file mode 100644 index 0000000000..fb1c8a8830 --- /dev/null +++ b/drivers/freetype/src/type1/t1parse.h @@ -0,0 +1,135 @@ +/***************************************************************************/ +/* */ +/* t1parse.h */ +/* */ +/* Type 1 parser (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2008 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 __T1PARSE_H__ +#define __T1PARSE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_ParserRec */ + /* */ + /* <Description> */ + /* A PS_ParserRec is an object used to parse a Type 1 fonts very */ + /* quickly. */ + /* */ + /* <Fields> */ + /* root :: The root parser. */ + /* */ + /* stream :: The current input stream. */ + /* */ + /* base_dict :: A pointer to the top-level dictionary. */ + /* */ + /* base_len :: The length in bytes of the top dictionary. */ + /* */ + /* private_dict :: A pointer to the private dictionary. */ + /* */ + /* private_len :: The length in bytes of the private dictionary. */ + /* */ + /* in_pfb :: A boolean. Indicates that we are handling a PFB */ + /* file. */ + /* */ + /* in_memory :: A boolean. Indicates a memory-based stream. */ + /* */ + /* single_block :: A boolean. Indicates that the private dictionary */ + /* is stored in lieu of the base dictionary. */ + /* */ + typedef struct T1_ParserRec_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* base_dict; + FT_ULong base_len; + + FT_Byte* private_dict; + FT_ULong private_len; + + FT_Bool in_pfb; + FT_Bool in_memory; + FT_Bool single_block; + + } T1_ParserRec, *T1_Parser; + + +#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) +#define T1_Done_Table( p ) \ + do \ + { \ + if ( (p)->funcs.done ) \ + (p)->funcs.done( p ); \ + } while ( 0 ) +#define T1_Release_Table( p ) \ + do \ + { \ + if ( (p)->funcs.release ) \ + (p)->funcs.release( p ); \ + } while ( 0 ) + + +#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root ) + +#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root ) +#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) + +#define T1_ToCoordArray( p, m, c ) \ + (p)->root.funcs.to_coord_array( &(p)->root, m, c ) +#define T1_ToFixedArray( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define T1_ToToken( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) +#define T1_ToTokenArray( p, t, m, c ) \ + (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) + +#define T1_Load_Field( p, f, o, m, pf ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) + +#define T1_Load_Field_Table( p, f, o, m, pf ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) + + + FT_LOCAL( FT_Error ) + T1_New_Parser( T1_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( FT_Error ) + T1_Get_Private_Dict( T1_Parser parser, + PSAux_Service psaux ); + + FT_LOCAL( void ) + T1_Finalize_Parser( T1_Parser parser ); + + +FT_END_HEADER + +#endif /* __T1PARSE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type1/t1tokens.h b/drivers/freetype/src/type1/t1tokens.h new file mode 100644 index 0000000000..e37276b908 --- /dev/null +++ b/drivers/freetype/src/type1/t1tokens.h @@ -0,0 +1,143 @@ +/***************************************************************************/ +/* */ +/* t1tokens.h */ +/* */ +/* Type 1 tokenizer (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 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. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + T1_FIELD_STRING( "version", version, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "Notice", notice, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "FullName", full_name, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "FamilyName", family_name, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "Weight", weight, + T1_FIELD_DICT_FONTDICT ) + + /* we use pointers to detect modifications made by synthetic fonts */ + T1_FIELD_NUM ( "ItalicAngle", italic_angle, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, + T1_FIELD_DICT_FONTDICT ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, + T1_FIELD_DICT_FONTDICT ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_PrivateRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_PRIVATE + + T1_FIELD_NUM ( "UniqueID", unique_id, + T1_FIELD_DICT_FONTDICT | T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "lenIV", lenIV, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "LanguageGroup", language_group, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "password", password, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_FIXED_1000( "BlueScale", blue_scale, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "BlueShift", blue_shift, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_BOOL ( "ForceBold", force_bold, + T1_FIELD_DICT_PRIVATE ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + T1_FIELD_KEY ( "FontName", font_name, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "PaintType", paint_type, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "FontType", font_type, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width, T1_FIELD_DICT_FONTDICT ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX + + T1_FIELD_BBOX( "FontBBox", xMin, T1_FIELD_DICT_FONTDICT ) + + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FaceRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FACE + + T1_FIELD_NUM( "NDV", ndv_idx, T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM( "CDV", cdv_idx, T1_FIELD_DICT_PRIVATE ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_BlendRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BLEND + + T1_FIELD_NUM_TABLE( "DesignVector", default_design_vector, + T1_MAX_MM_DESIGNS, T1_FIELD_DICT_FONTDICT ) + + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + +/* END */ diff --git a/drivers/freetype/src/type1/type1.c b/drivers/freetype/src/type1/type1.c new file mode 100644 index 0000000000..ccc12be103 --- /dev/null +++ b/drivers/freetype/src/type1/type1.c @@ -0,0 +1,33 @@ +/***************************************************************************/ +/* */ +/* type1.c */ +/* */ +/* FreeType Type 1 driver component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "t1parse.c" +#include "t1load.c" +#include "t1objs.c" +#include "t1driver.c" +#include "t1gload.c" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.c" +#endif + + +/* END */ diff --git a/drivers/freetype/src/type42/Jamfile b/drivers/freetype/src/type42/Jamfile new file mode 100644 index 0000000000..00371d54f3 --- /dev/null +++ b/drivers/freetype/src/type42/Jamfile @@ -0,0 +1,29 @@ +# FreeType 2 src/type42 Jamfile +# +# Copyright 2002 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) type42 ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = t42objs t42parse t42drivr ; + } + else + { + _sources = type42 ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/type42 Jamfile diff --git a/drivers/freetype/src/type42/module.mk b/drivers/freetype/src/type42/module.mk new file mode 100644 index 0000000000..b3f10a8d3c --- /dev/null +++ b/drivers/freetype/src/type42/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 Type42 module definition +# + + +# Copyright 2002, 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. + + +FTMODULE_H_COMMANDS += TYPE42_DRIVER + +define TYPE42_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, t42_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)type42 $(ECHO_DRIVER_DESC)Type 42 font files with no known extension$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/type42/rules.mk b/drivers/freetype/src/type42/rules.mk new file mode 100644 index 0000000000..eac1081eb1 --- /dev/null +++ b/drivers/freetype/src/type42/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 Type42 driver configuration rules +# + + +# Copyright 2002, 2003, 2008 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. + + +# Type42 driver directory +# +T42_DIR := $(SRC_DIR)/type42 + + +# compilation flags for the driver +# +T42_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T42_DIR)) + + +# Type42 driver source +# +T42_DRV_SRC := $(T42_DIR)/t42objs.c \ + $(T42_DIR)/t42parse.c \ + $(T42_DIR)/t42drivr.c + +# Type42 driver headers +# +T42_DRV_H := $(T42_DRV_SRC:%.c=%.h) \ + $(T42_DIR)/t42error.h \ + $(T42_DIR)/t42types.h + + +# Type42 driver object(s) +# +# T42_DRV_OBJ_M is used during `multi' builds +# T42_DRV_OBJ_S is used during `single' builds +# +T42_DRV_OBJ_M := $(T42_DRV_SRC:$(T42_DIR)/%.c=$(OBJ_DIR)/%.$O) +T42_DRV_OBJ_S := $(OBJ_DIR)/type42.$O + +# Type42 driver source file for single build +# +T42_DRV_SRC_S := $(T42_DIR)/type42.c + + +# Type42 driver - single object +# +$(T42_DRV_OBJ_S): $(T42_DRV_SRC_S) $(T42_DRV_SRC) $(FREETYPE_H) $(T42_DRV_H) + $(T42_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(T42_DRV_SRC_S)) + + +# Type42 driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(T42_DIR)/%.c $(FREETYPE_H) $(T42_DRV_H) + $(T42_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(T42_DRV_OBJ_S) +DRV_OBJS_M += $(T42_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/type42/t42drivr.c b/drivers/freetype/src/type42/t42drivr.c new file mode 100644 index 0000000000..3ad1bde79f --- /dev/null +++ b/drivers/freetype/src/type42/t42drivr.c @@ -0,0 +1,244 @@ +/***************************************************************************/ +/* */ +/* t42drivr.c */ +/* */ +/* High-level Type 42 driver interface (body). */ +/* */ +/* Copyright 2002-2004, 2006, 2007, 2009, 2011, 2013 by */ +/* Roberto Alameda. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This driver implements Type42 fonts as described in the */ + /* Technical Note #5012 from Adobe, with these limitations: */ + /* */ + /* 1) CID Fonts are not currently supported. */ + /* 2) Incremental fonts making use of the GlyphDirectory keyword */ + /* will be loaded, but the rendering will be using the TrueType */ + /* tables. */ + /* 3) As for Type1 fonts, CDevProc is not supported. */ + /* 4) The Metrics dictionary is not supported. */ + /* 5) AFM metrics are not supported. */ + /* */ + /* In other words, this driver supports Type42 fonts derived from */ + /* TrueType fonts in a non-CID manner, as done by usual conversion */ + /* programs. */ + /* */ + /*************************************************************************/ + + +#include "t42drivr.h" +#include "t42objs.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H + +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + +#undef FT_COMPONENT +#define FT_COMPONENT trace_t42 + + + /* + * + * GLYPH DICT SERVICE + * + */ + + static FT_Error + t42_get_glyph_name( T42_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); + + return FT_Err_Ok; + } + + + static FT_UInt + t42_get_name_index( T42_Face face, + FT_String* glyph_name ) + { + FT_Int i; + + + for ( i = 0; i < face->type1.num_glyphs; i++ ) + { + FT_String* gname = face->type1.glyph_names[i]; + + + if ( glyph_name[0] == gname[0] && !ft_strcmp( glyph_name, gname ) ) + return (FT_UInt)ft_atol( (const char *)face->type1.charstrings[i] ); + } + + return 0; + } + + + static const FT_Service_GlyphDictRec t42_service_glyph_dict = + { + (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)t42_get_name_index + }; + + + /* + * + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + t42_get_ps_font_name( T42_Face face ) + { + return (const char*)face->type1.font_name; + } + + + static const FT_Service_PsFontNameRec t42_service_ps_font_name = + { + (FT_PsName_GetFunc)t42_get_ps_font_name + }; + + + /* + * + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + t42_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((T42_Face)face)->type1.font_info; + + return FT_Err_Ok; + } + + + static FT_Error + t42_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T42_Face)face)->type1.font_extra; + + return FT_Err_Ok; + } + + + static FT_Int + t42_ps_has_glyph_names( FT_Face face ) + { + FT_UNUSED( face ); + + return 1; + } + + + static FT_Error + t42_ps_get_font_private( FT_Face face, + PS_PrivateRec* afont_private ) + { + *afont_private = ((T42_Face)face)->type1.private_dict; + + return FT_Err_Ok; + } + + + static const FT_Service_PsInfoRec t42_service_ps_info = + { + (PS_GetFontInfoFunc) t42_ps_get_font_info, + (PS_GetFontExtraFunc) t42_ps_get_font_extra, + (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, + (PS_GetFontPrivateFunc)t42_ps_get_font_private, + (PS_GetFontValueFunc) NULL /* not implemented */ + }; + + + /* + * + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec t42_services[] = + { + { FT_SERVICE_ID_GLYPH_DICT, &t42_service_glyph_dict }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t42_service_ps_font_name }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &t42_service_ps_info }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_42 }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + T42_Get_Interface( FT_Module module, + const FT_String* t42_interface ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( t42_services, t42_interface ); + } + + + const FT_Driver_ClassRec t42_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | +#ifdef TT_USE_BYTECODE_INTERPRETER + FT_MODULE_DRIVER_HAS_HINTER, +#else + 0, +#endif + + sizeof ( T42_DriverRec ), + + "type42", + 0x10000L, + 0x20000L, + + 0, /* format interface */ + + T42_Driver_Init, + T42_Driver_Done, + T42_Get_Interface, + }, + + sizeof ( T42_FaceRec ), + sizeof ( T42_SizeRec ), + sizeof ( T42_GlyphSlotRec ), + + T42_Face_Init, + T42_Face_Done, + T42_Size_Init, + T42_Size_Done, + T42_GlyphSlot_Init, + T42_GlyphSlot_Done, + + T42_GlyphSlot_Load, + + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ + + 0, /* FT_Face_GetAdvancesFunc */ + T42_Size_Request, + T42_Size_Select + }; + + +/* END */ diff --git a/drivers/freetype/src/type42/t42drivr.h b/drivers/freetype/src/type42/t42drivr.h new file mode 100644 index 0000000000..9a1e97e30e --- /dev/null +++ b/drivers/freetype/src/type42/t42drivr.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* t42drivr.h */ +/* */ +/* High-level Type 42 driver interface (specification). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* 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 __T42DRIVR_H__ +#define __T42DRIVR_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t42_driver_class; + + +FT_END_HEADER + + +#endif /* __T42DRIVR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type42/t42error.h b/drivers/freetype/src/type42/t42error.h new file mode 100644 index 0000000000..217ae8bd52 --- /dev/null +++ b/drivers/freetype/src/type42/t42error.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* t42error.h */ +/* */ +/* Type 42 error codes (specification only). */ +/* */ +/* Copyright 2002, 2003, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the Type 42 error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __T42ERROR_H__ +#define __T42ERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX T42_Err_ +#define FT_ERR_BASE FT_Mod_Err_Type42 + +#include FT_ERRORS_H + +#endif /* __T42ERROR_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type42/t42objs.c b/drivers/freetype/src/type42/t42objs.c new file mode 100644 index 0000000000..18e2c0b625 --- /dev/null +++ b/drivers/freetype/src/type42/t42objs.c @@ -0,0 +1,682 @@ +/***************************************************************************/ +/* */ +/* t42objs.c */ +/* */ +/* Type 42 objects manager (body). */ +/* */ +/* Copyright 2002-2009, 2011, 2013 */ +/* by Roberto Alameda. */ +/* */ +/* 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 "t42objs.h" +#include "t42parse.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H +#include FT_LIST_H +#include FT_TRUETYPE_IDS_H + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_t42 + + + static FT_Error + T42_Open_Face( T42_Face face ) + { + T42_LoaderRec loader; + T42_Parser parser; + T1_Font type1 = &face->type1; + FT_Memory memory = face->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + t42_loader_init( &loader, face ); + + parser = &loader.parser; + + if ( FT_ALLOC( face->ttf_data, 12 ) ) + goto Exit; + + error = t42_parser_init( parser, + face->root.stream, + memory, + psaux); + if ( error ) + goto Exit; + + error = t42_parse_dict( face, &loader, + parser->base_dict, parser->base_len ); + if ( error ) + goto Exit; + + if ( type1->font_type != 42 ) + { + FT_ERROR(( "T42_Open_Face: cannot handle FontType %d\n", + type1->font_type )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* now, propagate the charstrings and glyphnames tables */ + /* to the Type1 data */ + type1->num_glyphs = loader.num_glyphs; + + if ( !loader.charstrings.init ) + { + FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" )); + error = FT_THROW( Invalid_File_Format ); + } + + loader.charstrings.init = 0; + type1->charstrings_block = loader.charstrings.block; + type1->charstrings = loader.charstrings.elements; + type1->charstrings_len = loader.charstrings.lengths; + + /* we copy the glyph names `block' and `elements' fields; */ + /* the `lengths' field must be released later */ + type1->glyph_names_block = loader.glyph_names.block; + type1->glyph_names = (FT_String**)loader.glyph_names.elements; + loader.glyph_names.block = 0; + loader.glyph_names.elements = 0; + + /* we must now build type1.encoding when we have a custom array */ + if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) + { + FT_Int charcode, idx, min_char, max_char; + FT_Byte* glyph_name; + + + /* OK, we do the following: for each element in the encoding */ + /* table, look up the index of the glyph having the same name */ + /* as defined in the CharStrings array. */ + /* The index is then stored in type1.encoding.char_index, and */ + /* the name in type1.encoding.char_name */ + + min_char = 0; + max_char = 0; + + charcode = 0; + for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) + { + FT_Byte* char_name; + + + type1->encoding.char_index[charcode] = 0; + type1->encoding.char_name [charcode] = (char *)".notdef"; + + char_name = loader.encoding_table.elements[charcode]; + if ( char_name ) + for ( idx = 0; idx < type1->num_glyphs; idx++ ) + { + glyph_name = (FT_Byte*)type1->glyph_names[idx]; + if ( ft_strcmp( (const char*)char_name, + (const char*)glyph_name ) == 0 ) + { + type1->encoding.char_index[charcode] = (FT_UShort)idx; + type1->encoding.char_name [charcode] = (char*)glyph_name; + + /* Change min/max encoded char only if glyph name is */ + /* not /.notdef */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)glyph_name ) != 0 ) + { + if ( charcode < min_char ) + min_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; + } + break; + } + } + } + + type1->encoding.code_first = min_char; + type1->encoding.code_last = max_char; + type1->encoding.num_chars = loader.num_chars; + } + + Exit: + t42_loader_done( &loader ); + return error; + } + + + /***************** Driver Functions *************/ + + + FT_LOCAL_DEF( FT_Error ) + T42_Face_Init( FT_Stream stream, + FT_Face t42face, /* T42_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + T42_Face face = (T42_Face)t42face; + FT_Error error; + FT_Service_PsCMaps psnames; + PSAux_Service psaux; + FT_Face root = (FT_Face)&face->root; + T1_Font type1 = &face->type1; + PS_FontInfo info = &type1->font_info; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + FT_UNUSED( stream ); + + + face->ttf_face = NULL; + face->root.num_faces = 1; + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + face->psnames = psnames; + + face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "psaux" ); + psaux = (PSAux_Service)face->psaux; + if ( !psaux ) + { + FT_ERROR(( "T42_Face_Init: cannot access `psaux' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + + FT_TRACE2(( "Type 42 driver\n" )); + + /* open the tokenizer, this will also check the font format */ + error = T42_Open_Face( face ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + if ( face_index > 0 ) + { + FT_ERROR(( "T42_Face_Init: invalid face index\n" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* Now load the font program into the face object */ + + /* Init the face object fields */ + /* Now set up root face fields */ + + root->num_glyphs = type1->num_glyphs; + root->num_charmaps = 0; + root->face_index = 0; + + root->face_flags = FT_FACE_FLAG_SCALABLE | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_GLYPH_NAMES; + + if ( info->is_fixed_pitch ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* We only set this flag if we have the patented bytecode interpreter. */ + /* There are no known `tricky' Type42 fonts that could be loaded with */ + /* the unpatented interpreter. */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + root->face_flags |= FT_FACE_FLAG_HINTER; +#endif + + /* XXX: TODO -- add kerning with .afm support */ + + /* get style name -- be careful, some broken fonts only */ + /* have a `/FontName' dictionary entry! */ + root->family_name = info->family_name; + /* assume "Regular" style if we don't know better */ + root->style_name = (char *)"Regular"; + if ( root->family_name ) + { + char* full = info->full_name; + char* family = root->family_name; + + + if ( full ) + { + while ( *full ) + { + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + if ( !*family ) + root->style_name = full; + break; + } + } + } + } + } + else + { + /* do we have a `/FontName'? */ + if ( type1->font_name ) + root->family_name = type1->font_name; + } + + /* no embedded bitmap support */ + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + /* Load the TTF font embedded in the T42 font */ + { + FT_Open_Args args; + + + args.flags = FT_OPEN_MEMORY; + args.memory_base = face->ttf_data; + args.memory_size = face->ttf_size; + + if ( num_params ) + { + args.flags |= FT_OPEN_PARAMS; + args.num_params = num_params; + args.params = params; + } + + error = FT_Open_Face( FT_FACE_LIBRARY( face ), + &args, 0, &face->ttf_face ); + } + + if ( error ) + goto Exit; + + FT_Done_Size( face->ttf_face->size ); + + /* Ignore info in FontInfo dictionary and use the info from the */ + /* loaded TTF font. The PostScript interpreter also ignores it. */ + root->bbox = face->ttf_face->bbox; + root->units_per_EM = face->ttf_face->units_per_EM; + + root->ascender = face->ttf_face->ascender; + root->descender = face->ttf_face->descender; + root->height = face->ttf_face->height; + + root->max_advance_width = face->ttf_face->max_advance_width; + root->max_advance_height = face->ttf_face->max_advance_height; + + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; + + /* compute style flags */ + root->style_flags = 0; + if ( info->italic_angle ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + + if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + + if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) + root->face_flags |= FT_FACE_FLAG_VERTICAL; + + { + if ( psnames ) + { + FT_CharMapRec charmap; + T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; + FT_CMap_Class clazz; + + + charmap.face = root; + + /* first of all, try to synthesize a Unicode charmap */ + charmap.platform_id = TT_PLATFORM_MICROSOFT; + charmap.encoding_id = TT_MS_ID_UNICODE_CS; + charmap.encoding = FT_ENCODING_UNICODE; + + error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); + if ( error && + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + goto Exit; + error = FT_Err_Ok; + + /* now, generate an Adobe Standard encoding when appropriate */ + charmap.platform_id = TT_PLATFORM_ADOBE; + clazz = NULL; + + switch ( type1->encoding_type ) + { + case T1_ENCODING_TYPE_STANDARD: + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.encoding_id = TT_ADOBE_ID_STANDARD; + clazz = cmap_classes->standard; + break; + + case T1_ENCODING_TYPE_EXPERT: + charmap.encoding = FT_ENCODING_ADOBE_EXPERT; + charmap.encoding_id = TT_ADOBE_ID_EXPERT; + clazz = cmap_classes->expert; + break; + + case T1_ENCODING_TYPE_ARRAY: + charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; + charmap.encoding_id = TT_ADOBE_ID_CUSTOM; + clazz = cmap_classes->custom; + break; + + case T1_ENCODING_TYPE_ISOLATIN1: + charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; + charmap.encoding_id = TT_ADOBE_ID_LATIN_1; + clazz = cmap_classes->unicode; + break; + + default: + ; + } + + if ( clazz ) + error = FT_CMap_New( clazz, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if ( root->num_charmaps ) + root->charmap = root->charmaps[0]; +#endif + } + } + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + T42_Face_Done( FT_Face t42face ) + { + T42_Face face = (T42_Face)t42face; + T1_Font type1; + PS_FontInfo info; + FT_Memory memory; + + + if ( !face ) + return; + + type1 = &face->type1; + info = &type1->font_info; + memory = face->root.memory; + + /* delete internal ttf face prior to freeing face->ttf_data */ + if ( face->ttf_face ) + FT_Done_Face( face->ttf_face ); + + /* release font info strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); + + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); + + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); + + FT_FREE( face->ttf_data ); + +#if 0 + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); +#endif + + /* release unicode map, if any */ + FT_FREE( face->unicode_map.maps ); + face->unicode_map.num_maps = 0; + + face->root.family_name = 0; + face->root.style_name = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T42_Driver_Init */ + /* */ + /* <Description> */ + /* Initializes a given Type 42 driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T42_Driver_Init( FT_Module module ) /* T42_Driver */ + { + T42_Driver driver = (T42_Driver)module; + FT_Module ttmodule; + + + ttmodule = FT_Get_Module( module->library, "truetype" ); + if ( !ttmodule ) + { + FT_ERROR(( "T42_Driver_Init: cannot access `truetype' module\n" )); + return FT_THROW( Missing_Module ); + } + + driver->ttclazz = (FT_Driver_Class)ttmodule->clazz; + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( void ) + T42_Driver_Done( FT_Module module ) + { + FT_UNUSED( module ); + } + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_Init( FT_Size size ) /* T42_Size */ + { + T42_Size t42size = (T42_Size)size; + FT_Face face = size->face; + T42_Face t42face = (T42_Face)face; + FT_Size ttsize; + FT_Error error = FT_Err_Ok; + + + error = FT_New_Size( t42face->ttf_face, &ttsize ); + t42size->ttsize = ttsize; + + FT_Activate_Size( ttsize ); + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_Request( FT_Size t42size, /* T42_Size */ + FT_Size_Request req ) + { + T42_Size size = (T42_Size)t42size; + T42_Face face = (T42_Face)t42size->face; + FT_Error error; + + + FT_Activate_Size( size->ttsize ); + + error = FT_Request_Size( face->ttf_face, req ); + if ( !error ) + t42size->metrics = face->ttf_face->size->metrics; + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_Select( FT_Size t42size, /* T42_Size */ + FT_ULong strike_index ) + { + T42_Size size = (T42_Size)t42size; + T42_Face face = (T42_Face)t42size->face; + FT_Error error; + + + FT_Activate_Size( size->ttsize ); + + error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index ); + if ( !error ) + t42size->metrics = face->ttf_face->size->metrics; + + return error; + + } + + + FT_LOCAL_DEF( void ) + T42_Size_Done( FT_Size t42size ) /* T42_Size */ + { + T42_Size size = (T42_Size)t42size; + FT_Face face = t42size->face; + T42_Face t42face = (T42_Face)face; + FT_ListNode node; + + + node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize ); + if ( node ) + { + FT_Done_Size( size->ttsize ); + size->ttsize = NULL; + } + } + + + FT_LOCAL_DEF( FT_Error ) + T42_GlyphSlot_Init( FT_GlyphSlot t42slot ) /* T42_GlyphSlot */ + { + T42_GlyphSlot slot = (T42_GlyphSlot)t42slot; + FT_Face face = t42slot->face; + T42_Face t42face = (T42_Face)face; + FT_GlyphSlot ttslot; + FT_Error error = FT_Err_Ok; + + + if ( face->glyph == NULL ) + { + /* First glyph slot for this face */ + slot->ttslot = t42face->ttf_face->glyph; + } + else + { + error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot ); + slot->ttslot = ttslot; + } + + return error; + } + + + FT_LOCAL_DEF( void ) + T42_GlyphSlot_Done( FT_GlyphSlot t42slot ) /* T42_GlyphSlot */ + { + T42_GlyphSlot slot = (T42_GlyphSlot)t42slot; + + + FT_Done_GlyphSlot( slot->ttslot ); + } + + + static void + t42_glyphslot_clear( FT_GlyphSlot slot ) + { + /* free bitmap if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* clear all public fields in the glyph slot */ + FT_ZERO( &slot->metrics ); + FT_ZERO( &slot->outline ); + FT_ZERO( &slot->bitmap ); + + slot->bitmap_left = 0; + slot->bitmap_top = 0; + slot->num_subglyphs = 0; + slot->subglyphs = 0; + slot->control_data = 0; + slot->control_len = 0; + slot->other = 0; + slot->format = FT_GLYPH_FORMAT_NONE; + + slot->linearHoriAdvance = 0; + slot->linearVertAdvance = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + T42_GlyphSlot_Load( FT_GlyphSlot glyph, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph; + T42_Size t42size = (T42_Size)size; + FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; + + + t42_glyphslot_clear( t42slot->ttslot ); + error = ttclazz->load_glyph( t42slot->ttslot, + t42size->ttsize, + glyph_index, + load_flags | FT_LOAD_NO_BITMAP ); + + if ( !error ) + { + glyph->metrics = t42slot->ttslot->metrics; + + glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance; + glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance; + + glyph->format = t42slot->ttslot->format; + glyph->outline = t42slot->ttslot->outline; + + glyph->bitmap = t42slot->ttslot->bitmap; + glyph->bitmap_left = t42slot->ttslot->bitmap_left; + glyph->bitmap_top = t42slot->ttslot->bitmap_top; + + glyph->num_subglyphs = t42slot->ttslot->num_subglyphs; + glyph->subglyphs = t42slot->ttslot->subglyphs; + + glyph->control_data = t42slot->ttslot->control_data; + glyph->control_len = t42slot->ttslot->control_len; + } + + return error; + } + + +/* END */ diff --git a/drivers/freetype/src/type42/t42objs.h b/drivers/freetype/src/type42/t42objs.h new file mode 100644 index 0000000000..02d13259be --- /dev/null +++ b/drivers/freetype/src/type42/t42objs.h @@ -0,0 +1,124 @@ +/***************************************************************************/ +/* */ +/* t42objs.h */ +/* */ +/* Type 42 objects manager (specification). */ +/* */ +/* Copyright 2002, 2003, 2006, 2007, 2011 by Roberto Alameda. */ +/* */ +/* 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 __T42OBJS_H__ +#define __T42OBJS_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include "t42types.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DRIVER_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /* Type42 size */ + typedef struct T42_SizeRec_ + { + FT_SizeRec root; + FT_Size ttsize; + + } T42_SizeRec, *T42_Size; + + + /* Type42 slot */ + typedef struct T42_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + FT_GlyphSlot ttslot; + + } T42_GlyphSlotRec, *T42_GlyphSlot; + + + /* Type 42 driver */ + typedef struct T42_DriverRec_ + { + FT_DriverRec root; + FT_Driver_Class ttclazz; + void* extension_component; + + } T42_DriverRec, *T42_Driver; + + + /* */ + + + FT_LOCAL( FT_Error ) + T42_Face_Init( FT_Stream stream, + FT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + FT_LOCAL( void ) + T42_Face_Done( FT_Face face ); + + + FT_LOCAL( FT_Error ) + T42_Size_Init( FT_Size size ); + + + FT_LOCAL( FT_Error ) + T42_Size_Request( FT_Size size, + FT_Size_Request req ); + + + FT_LOCAL( FT_Error ) + T42_Size_Select( FT_Size size, + FT_ULong strike_index ); + + + FT_LOCAL( void ) + T42_Size_Done( FT_Size size ); + + + FT_LOCAL( FT_Error ) + T42_GlyphSlot_Init( FT_GlyphSlot slot ); + + + FT_LOCAL( FT_Error ) + T42_GlyphSlot_Load( FT_GlyphSlot glyph, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + FT_LOCAL( void ) + T42_GlyphSlot_Done( FT_GlyphSlot slot ); + + + FT_LOCAL( FT_Error ) + T42_Driver_Init( FT_Module module ); + + FT_LOCAL( void ) + T42_Driver_Done( FT_Module module ); + + /* */ + +FT_END_HEADER + + +#endif /* __T42OBJS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type42/t42parse.c b/drivers/freetype/src/type42/t42parse.c new file mode 100644 index 0000000000..3cdd8a1acf --- /dev/null +++ b/drivers/freetype/src/type42/t42parse.c @@ -0,0 +1,1187 @@ +/***************************************************************************/ +/* */ +/* t42parse.c */ +/* */ +/* Type 42 font parser (body). */ +/* */ +/* Copyright 2002-2013 by */ +/* Roberto Alameda. */ +/* */ +/* 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 "t42parse.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_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_t42 + + + static void + t42_parse_font_matrix( T42_Face face, + T42_Loader loader ); + static void + t42_parse_encoding( T42_Face face, + T42_Loader loader ); + + static void + t42_parse_charstrings( T42_Face face, + T42_Loader loader ); + + static void + t42_parse_sfnts( T42_Face face, + T42_Loader loader ); + + + /* as Type42 fonts have no Private dict, */ + /* we set the last argument of T1_FIELD_XXX to 0 */ + static const + T1_FieldRec t42_keywords[] = + { + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontInfo +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + 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 +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, 0 ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + T1_FIELD_KEY ( "FontName", font_name, 0 ) + T1_FIELD_NUM ( "PaintType", paint_type, 0 ) + T1_FIELD_NUM ( "FontType", font_type, 0 ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX + + T1_FIELD_BBOX("FontBBox", xMin, 0 ) + + T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding, 0 ) + T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings, 0 ) + T1_FIELD_CALLBACK( "sfnts", t42_parse_sfnts, 0 ) + + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } + }; + + +#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) +#define T1_Done_Table( p ) \ + do \ + { \ + if ( (p)->funcs.done ) \ + (p)->funcs.done( p ); \ + } while ( 0 ) +#define T1_Release_Table( p ) \ + do \ + { \ + if ( (p)->funcs.release ) \ + (p)->funcs.release( p ); \ + } while ( 0 ) + +#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root ) + +#define T1_ToInt( p ) \ + (p)->root.funcs.to_int( &(p)->root ) +#define T1_ToBytes( p, b, m, n, d ) \ + (p)->root.funcs.to_bytes( &(p)->root, b, m, n, d ) + +#define T1_ToFixedArray( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define T1_ToToken( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) + +#define T1_Load_Field( p, f, o, m, pf ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) +#define T1_Load_Field_Table( p, f, o, m, pf ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) + + + /********************* Parsing Functions ******************/ + + FT_LOCAL_DEF( FT_Error ) + t42_parser_init( T42_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error = FT_Err_Ok; + FT_Long size; + + + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + + parser->stream = stream; + parser->base_len = 0; + parser->base_dict = 0; + parser->in_memory = 0; + + /*******************************************************************/ + /* */ + /* Here a short summary of what is going on: */ + /* */ + /* When creating a new Type 42 parser, we try to locate and load */ + /* the base dictionary, loading the whole font into memory. */ + /* */ + /* When `loading' the base dictionary, we only set up pointers */ + /* in the case of a memory-based stream. Otherwise, we allocate */ + /* and load the base dictionary in it. */ + /* */ + /* parser->in_memory is set if we have a memory stream. */ + /* */ + + if ( FT_STREAM_SEEK( 0L ) || + FT_FRAME_ENTER( 17 ) ) + goto Exit; + + if ( ft_memcmp( stream->cursor, "%!PS-TrueTypeFont", 17 ) != 0 ) + { + FT_TRACE2(( " not a Type42 font\n" )); + error = FT_THROW( Unknown_File_Format ); + } + + FT_FRAME_EXIT(); + + if ( error || FT_STREAM_SEEK( 0 ) ) + goto Exit; + + size = stream->size; + + /* now, try to load `size' bytes of the `base' dictionary we */ + /* found previously */ + + /* if it is a memory-based resource, set up pointers */ + if ( !stream->read ) + { + parser->base_dict = (FT_Byte*)stream->base + stream->pos; + parser->base_len = size; + parser->in_memory = 1; + + /* check that the `size' field is valid */ + if ( FT_STREAM_SKIP( size ) ) + goto Exit; + } + else + { + /* read segment in memory */ + if ( FT_ALLOC( parser->base_dict, size ) || + FT_STREAM_READ( parser->base_dict, size ) ) + goto Exit; + + parser->base_len = size; + } + + parser->root.base = parser->base_dict; + parser->root.cursor = parser->base_dict; + parser->root.limit = parser->root.cursor + parser->base_len; + + Exit: + if ( error && !parser->in_memory ) + FT_FREE( parser->base_dict ); + + return error; + } + + + FT_LOCAL_DEF( void ) + t42_parser_done( T42_Parser parser ) + { + FT_Memory memory = parser->root.memory; + + + /* free the base dictionary only when we have a disk stream */ + if ( !parser->in_memory ) + FT_FREE( parser->base_dict ); + + parser->root.funcs.done( &parser->root ); + } + + + static int + t42_is_space( FT_Byte c ) + { + return ( c == ' ' || c == '\t' || + c == '\r' || c == '\n' || c == '\f' || + c == '\0' ); + } + + + static void + t42_parse_font_matrix( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Matrix* matrix = &face->type1.font_matrix; + FT_Vector* offset = &face->type1.font_offset; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + + + (void)T1_ToFixedArray( parser, 6, temp, 3 ); + + temp_scale = FT_ABS( temp[3] ); + + /* Set Units per EM based on FontMatrix values. We set the value to */ + /* 1000 / temp_scale, because temp_scale was already multiplied by */ + /* 1000 (in t1_tofixed, from psobjs.c). */ + + root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + + /* we need to scale the values by 1.0/temp_scale */ + if ( temp_scale != 0x10000L ) + { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the offsets must be expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + + static void + t42_parse_encoding( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + if ( cur >= limit ) + { + FT_ERROR(( "t42_parse_encoding: out of bounds\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + /* if we have a number or `[', the encoding is an array, */ + /* and we must load it now */ + if ( ft_isdigit( *cur ) || *cur == '[' ) + { + T1_Encoding encode = &face->type1.encoding; + FT_UInt count, n; + PS_Table char_table = &loader->encoding_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + FT_Bool only_immediates = 0; + + + /* read the number of entries in the encoding; should be 256 */ + if ( *cur == '[' ) + { + count = 256; + only_immediates = 1; + parser->root.cursor++; + } + else + count = (FT_UInt)T1_ToInt( parser ); + + T1_Skip_Spaces( parser ); + if ( parser->root.cursor >= limit ) + return; + + /* we use a T1_Table to store our charnames */ + loader->num_chars = encode->num_chars = count; + if ( FT_NEW_ARRAY( encode->char_index, count ) || + FT_NEW_ARRAY( encode->char_name, count ) || + FT_SET_ERROR( psaux->ps_table_funcs->init( + char_table, count, memory ) ) ) + { + parser->root.error = error; + return; + } + + /* We need to `zero' out encoding_table.elements */ + for ( n = 0; n < count; n++ ) + { + char* notdef = (char *)".notdef"; + + + T1_Add_Table( char_table, n, notdef, 8 ); + } + + /* Now we need to read records of the form */ + /* */ + /* ... charcode /charname ... */ + /* */ + /* for each entry in our table. */ + /* */ + /* We simply look for a number followed by an immediate */ + /* name. Note that this ignores correctly the sequence */ + /* that is often seen in type42 fonts: */ + /* */ + /* 0 1 255 { 1 index exch /.notdef put } for dup */ + /* */ + /* used to clean the encoding array before anything else. */ + /* */ + /* Alternatively, if the array is directly given as */ + /* */ + /* /Encoding [ ... ] */ + /* */ + /* we only read immediates. */ + + n = 0; + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) + { + cur = parser->root.cursor; + + /* we stop when we encounter `def' or `]' */ + if ( *cur == 'd' && cur + 3 < limit ) + { + if ( cur[1] == 'e' && + cur[2] == 'f' && + t42_is_space( cur[3] ) ) + { + FT_TRACE6(( "encoding end\n" )); + cur += 3; + break; + } + } + if ( *cur == ']' ) + { + FT_TRACE6(( "encoding end\n" )); + cur++; + break; + } + + /* check whether we have found an entry */ + if ( ft_isdigit( *cur ) || only_immediates ) + { + FT_Int charcode; + + + if ( only_immediates ) + charcode = n; + else + { + charcode = (FT_Int)T1_ToInt( parser ); + T1_Skip_Spaces( parser ); + } + + cur = parser->root.cursor; + + if ( *cur == '/' && cur + 2 < limit && n < count ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + + len = parser->root.cursor - cur; + + parser->root.error = T1_Add_Table( char_table, charcode, + cur, len + 1 ); + if ( parser->root.error ) + return; + char_table->elements[charcode][len] = '\0'; + + n++; + } + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + } + + T1_Skip_Spaces( parser ); + } + + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; + } + + /* Otherwise, we should have either `StandardEncoding', */ + /* `ExpertEncoding', or `ISOLatin1Encoding' */ + else + { + if ( cur + 17 < limit && + ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + + else if ( cur + 15 < limit && + ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + + else if ( cur + 18 < limit && + ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + + else + { + FT_ERROR(( "t42_parse_encoding: invalid token\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + } + } + } + + + typedef enum T42_Load_Status_ + { + BEFORE_START, + BEFORE_TABLE_DIR, + OTHER_TABLES + + } T42_Load_Status; + + + static void + t42_parse_sfnts( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Memory memory = parser->root.memory; + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + FT_Error error; + FT_Int num_tables = 0; + FT_ULong count, ttf_size = 0; + + FT_Long n, string_size, old_string_size, real_size; + FT_Byte* string_buf = NULL; + FT_Bool allocated = 0; + + T42_Load_Status status; + + + /* The format is */ + /* */ + /* /sfnts [ <hexstring> <hexstring> ... ] def */ + /* */ + /* or */ + /* */ + /* /sfnts [ */ + /* <num_bin_bytes> RD <binary data> */ + /* <num_bin_bytes> RD <binary data> */ + /* ... */ + /* ] def */ + /* */ + /* with exactly one space after the `RD' token. */ + + T1_Skip_Spaces( parser ); + + if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' ) + { + FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + T1_Skip_Spaces( parser ); + status = BEFORE_START; + string_size = 0; + old_string_size = 0; + count = 0; + + while ( parser->root.cursor < limit ) + { + cur = parser->root.cursor; + + if ( *cur == ']' ) + { + parser->root.cursor++; + goto Exit; + } + + else if ( *cur == '<' ) + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + + /* don't include delimiters */ + string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); + if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) + goto Fail; + + allocated = 1; + + parser->root.cursor = cur; + (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 ); + old_string_size = string_size; + string_size = real_size; + } + + else if ( ft_isdigit( *cur ) ) + { + if ( allocated ) + { + FT_ERROR(( "t42_parse_sfnts: " + "can't handle mixed binary and hex strings\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + string_size = T1_ToInt( parser ); + if ( string_size < 0 ) + { + FT_ERROR(( "t42_parse_sfnts: invalid string size\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + T1_Skip_PS_Token( parser ); /* `RD' */ + if ( parser->root.error ) + return; + + string_buf = parser->root.cursor + 1; /* one space after `RD' */ + + if ( limit - parser->root.cursor < string_size ) + { + FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + else + parser->root.cursor += string_size + 1; + } + + if ( !string_buf ) + { + FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* A string can have a trailing zero (odd) byte for padding. */ + /* Ignore it. */ + if ( ( string_size & 1 ) && string_buf[string_size - 1] == 0 ) + string_size--; + + if ( !string_size ) + { + FT_ERROR(( "t42_parse_sfnts: invalid string\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + for ( n = 0; n < string_size; n++ ) + { + switch ( status ) + { + case BEFORE_START: + /* load offset table, 12 bytes */ + if ( count < 12 ) + { + face->ttf_data[count++] = string_buf[n]; + continue; + } + else + { + num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; + status = BEFORE_TABLE_DIR; + ttf_size = 12 + 16 * num_tables; + + if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) + goto Fail; + } + /* fall through */ + + case BEFORE_TABLE_DIR: + /* the offset table is read; read the table directory */ + if ( count < ttf_size ) + { + face->ttf_data[count++] = string_buf[n]; + continue; + } + else + { + int i; + FT_ULong len; + + + for ( i = 0; i < num_tables; i++ ) + { + FT_Byte* p = face->ttf_data + 12 + 16 * i + 12; + + + len = FT_PEEK_ULONG( p ); + + /* Pad to a 4-byte boundary length */ + ttf_size += ( len + 3 ) & ~3; + } + + status = OTHER_TABLES; + face->ttf_size = ttf_size; + + /* there are no more than 256 tables, so no size check here */ + if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, + ttf_size + 1 ) ) + goto Fail; + } + /* fall through */ + + case OTHER_TABLES: + /* all other tables are just copied */ + if ( count >= ttf_size ) + { + FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + face->ttf_data[count++] = string_buf[n]; + } + } + + T1_Skip_Spaces( parser ); + } + + /* if control reaches this point, the format was not valid */ + error = FT_THROW( Invalid_File_Format ); + + Fail: + parser->root.error = error; + + Exit: + if ( allocated ) + FT_FREE( string_buf ); + } + + + static void + t42_parse_charstrings( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + PS_Table code_table = &loader->charstrings; + PS_Table name_table = &loader->glyph_names; + PS_Table swap_table = &loader->swap_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + FT_UInt n; + FT_UInt notdef_index = 0; + FT_Byte notdef_found = 0; + + + T1_Skip_Spaces( parser ); + + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + if ( ft_isdigit( *parser->root.cursor ) ) + { + loader->num_glyphs = (FT_UInt)T1_ToInt( parser ); + if ( parser->root.error ) + return; + } + else if ( *parser->root.cursor == '<' ) + { + /* We have `<< ... >>'. Count the number of `/' in the dictionary */ + /* to get its size. */ + FT_UInt count = 0; + + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + + while ( parser->root.cursor < limit ) + { + if ( *parser->root.cursor == '/' ) + count++; + else if ( *parser->root.cursor == '>' ) + { + loader->num_glyphs = count; + parser->root.cursor = cur; /* rewind */ + break; + } + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + T1_Skip_Spaces( parser ); + } + } + else + { + FT_ERROR(( "t42_parse_charstrings: invalid token\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* initialize tables */ + + error = psaux->ps_table_funcs->init( code_table, + loader->num_glyphs, + memory ); + if ( error ) + goto Fail; + + error = psaux->ps_table_funcs->init( name_table, + loader->num_glyphs, + memory ); + if ( error ) + goto Fail; + + /* Initialize table for swapping index notdef_index and */ + /* index 0 names and codes (if necessary). */ + + error = psaux->ps_table_funcs->init( swap_table, 4, memory ); + if ( error ) + goto Fail; + + n = 0; + + for (;;) + { + /* The format is simple: */ + /* `/glyphname' + index [+ def] */ + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + if ( cur >= limit ) + break; + + /* We stop when we find an `end' keyword or '>' */ + if ( *cur == 'e' && + cur + 3 < limit && + cur[1] == 'n' && + cur[2] == 'd' && + t42_is_space( cur[3] ) ) + break; + if ( *cur == '>' ) + break; + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + + if ( *cur == '/' ) + { + FT_PtrDist len; + + + if ( cur + 1 >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + cur++; /* skip `/' */ + len = parser->root.cursor - cur; + + error = T1_Add_Table( name_table, n, cur, len + 1 ); + if ( error ) + goto Fail; + + /* add a trailing zero to the name table */ + name_table->elements[n][len] = '\0'; + + /* record index of /.notdef */ + if ( *cur == '.' && + ft_strcmp( ".notdef", + (const char*)(name_table->elements[n]) ) == 0 ) + { + notdef_index = n; + notdef_found = 1; + } + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + + (void)T1_ToInt( parser ); + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + len = parser->root.cursor - cur; + + error = T1_Add_Table( code_table, n, cur, len + 1 ); + if ( error ) + goto Fail; + + code_table->elements[n][len] = '\0'; + + n++; + if ( n >= loader->num_glyphs ) + break; + } + } + + loader->num_glyphs = n; + + if ( !notdef_found ) + { + FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* if /.notdef does not occupy index 0, do our magic. */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)name_table->elements[0] ) ) + { + /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ + /* name and code entries to swap_table. Then place notdef_index */ + /* name and code entries into swap_table. Then swap name and code */ + /* entries at indices notdef_index and 0 using values stored in */ + /* swap_table. */ + + /* Index 0 name */ + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index 0 code */ + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index notdef_index name */ + error = T1_Add_Table( swap_table, 2, + name_table->elements[notdef_index], + name_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + /* Index notdef_index code */ + error = T1_Add_Table( swap_table, 3, + code_table->elements[notdef_index], + code_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, notdef_index, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, notdef_index, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, + swap_table->elements[2], + swap_table->lengths [2] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, + swap_table->elements[3], + swap_table->lengths [3] ); + if ( error ) + goto Fail; + + } + + return; + + Fail: + parser->root.error = error; + } + + + static FT_Error + t42_load_keyword( T42_Face face, + T42_Loader loader, + T1_Field field ) + { + FT_Error error; + void* dummy_object; + void** objects; + FT_UInt max_objects = 0; + + + /* if the keyword has a dedicated callback, call it */ + if ( field->type == T1_FIELD_TYPE_CALLBACK ) + { + field->reader( (FT_Face)face, loader ); + error = loader->parser.root.error; + goto Exit; + } + + /* now the keyword is either a simple field or a table of fields; */ + /* we are now going to take care of it */ + + switch ( field->location ) + { + case T1_FIELD_LOCATION_FONT_INFO: + dummy_object = &face->type1.font_info; + break; + + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + break; + + case T1_FIELD_LOCATION_BBOX: + dummy_object = &face->type1.font_bbox; + break; + + default: + dummy_object = &face->type1; + } + + objects = &dummy_object; + + if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || + field->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = T1_Load_Field_Table( &loader->parser, field, + objects, max_objects, 0 ); + else + error = T1_Load_Field( &loader->parser, field, + objects, max_objects, 0 ); + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + t42_parse_dict( T42_Face face, + T42_Loader loader, + FT_Byte* base, + FT_Long size ) + { + T42_Parser parser = &loader->parser; + FT_Byte* limit; + FT_Int n_keywords = (FT_Int)( sizeof ( t42_keywords ) / + sizeof ( t42_keywords[0] ) ); + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = FT_Err_Ok; + + limit = parser->root.limit; + + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) + { + FT_Byte* cur; + + + cur = parser->root.cursor; + + /* look for `FontDirectory' which causes problems for some fonts */ + if ( *cur == 'F' && cur + 25 < limit && + ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) + { + FT_Byte* cur2; + + + /* skip the `FontDirectory' keyword */ + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + cur = cur2 = parser->root.cursor; + + /* look up the `known' keyword */ + while ( cur < limit ) + { + if ( *cur == 'k' && cur + 5 < limit && + ft_strncmp( (char*)cur, "known", 5 ) == 0 ) + break; + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + T1_Skip_Spaces ( parser ); + cur = parser->root.cursor; + } + + if ( cur < limit ) + { + T1_TokenRec token; + + + /* skip the `known' keyword and the token following it */ + T1_Skip_PS_Token( parser ); + T1_ToToken( parser, &token ); + + /* if the last token was an array, skip it! */ + if ( token.type == T1_TOKEN_TYPE_ARRAY ) + cur2 = parser->root.cursor; + } + parser->root.cursor = cur2; + } + + /* look for immediates */ + else if ( *cur == '/' && cur + 2 < limit ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + + len = parser->root.cursor - cur; + + if ( len > 0 && len < 22 && parser->root.cursor < limit ) + { + int i; + + + /* now compare the immediate name to the keyword table */ + + /* loop through all known keywords */ + for ( i = 0; i < n_keywords; i++ ) + { + T1_Field keyword = (T1_Field)&t42_keywords[i]; + FT_Byte *name = (FT_Byte*)keyword->ident; + + + if ( !name ) + continue; + + if ( cur[0] == name[0] && + len == (FT_PtrDist)ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) + { + /* we found it -- run the parsing callback! */ + parser->root.error = t42_load_keyword( face, + loader, + keyword ); + if ( parser->root.error ) + return parser->root.error; + break; + } + } + } + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + } + + T1_Skip_Spaces( parser ); + } + + Exit: + return parser->root.error; + } + + + FT_LOCAL_DEF( void ) + t42_loader_init( T42_Loader loader, + T42_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + loader->num_glyphs = 0; + loader->num_chars = 0; + + /* initialize the tables -- simply set their `init' field to 0 */ + loader->encoding_table.init = 0; + loader->charstrings.init = 0; + loader->glyph_names.init = 0; + } + + + FT_LOCAL_DEF( void ) + t42_loader_done( T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + + + /* finalize tables */ + T1_Release_Table( &loader->encoding_table ); + T1_Release_Table( &loader->charstrings ); + T1_Release_Table( &loader->glyph_names ); + T1_Release_Table( &loader->swap_table ); + + /* finalize parser */ + t42_parser_done( parser ); + } + + +/* END */ diff --git a/drivers/freetype/src/type42/t42parse.h b/drivers/freetype/src/type42/t42parse.h new file mode 100644 index 0000000000..f77ec4af4f --- /dev/null +++ b/drivers/freetype/src/type42/t42parse.h @@ -0,0 +1,90 @@ +/***************************************************************************/ +/* */ +/* t42parse.h */ +/* */ +/* Type 42 font parser (specification). */ +/* */ +/* Copyright 2002, 2003 by Roberto Alameda. */ +/* */ +/* 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 __T42PARSE_H__ +#define __T42PARSE_H__ + + +#include "t42objs.h" +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + typedef struct T42_ParserRec_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* base_dict; + FT_Long base_len; + + FT_Bool in_memory; + + } T42_ParserRec, *T42_Parser; + + + typedef struct T42_Loader_ + { + T42_ParserRec parser; /* parser used to read the stream */ + + FT_UInt num_chars; /* number of characters in encoding */ + PS_TableRec encoding_table; /* PS_Table used to store the */ + /* encoding character names */ + + FT_UInt num_glyphs; + PS_TableRec glyph_names; + PS_TableRec charstrings; + PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ + + } T42_LoaderRec, *T42_Loader; + + + FT_LOCAL( FT_Error ) + t42_parser_init( T42_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( void ) + t42_parser_done( T42_Parser parser ); + + + FT_LOCAL( FT_Error ) + t42_parse_dict( T42_Face face, + T42_Loader loader, + FT_Byte* base, + FT_Long size ); + + + FT_LOCAL( void ) + t42_loader_init( T42_Loader loader, + T42_Face face ); + + FT_LOCAL( void ) + t42_loader_done( T42_Loader loader ); + + + /* */ + +FT_END_HEADER + + +#endif /* __T42PARSE_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type42/t42types.h b/drivers/freetype/src/type42/t42types.h new file mode 100644 index 0000000000..c7c2db490d --- /dev/null +++ b/drivers/freetype/src/type42/t42types.h @@ -0,0 +1,56 @@ +/***************************************************************************/ +/* */ +/* t42types.h */ +/* */ +/* Type 42 font data types (specification only). */ +/* */ +/* Copyright 2002, 2003, 2006, 2008 by Roberto Alameda. */ +/* */ +/* 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 __T42TYPES_H__ +#define __T42TYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + typedef struct T42_FaceRec_ + { + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; +#if 0 + const void* afm_data; +#endif + FT_Byte* ttf_data; + FT_ULong ttf_size; + FT_Face ttf_face; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; + PS_UnicodesRec unicode_map; + + } T42_FaceRec, *T42_Face; + + +FT_END_HEADER + +#endif /* __T42TYPES_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/type42/type42.c b/drivers/freetype/src/type42/type42.c new file mode 100644 index 0000000000..d13df56b10 --- /dev/null +++ b/drivers/freetype/src/type42/type42.c @@ -0,0 +1,25 @@ +/***************************************************************************/ +/* */ +/* type42.c */ +/* */ +/* FreeType Type 42 driver component. */ +/* */ +/* Copyright 2002 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. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "t42objs.c" +#include "t42parse.c" +#include "t42drivr.c" + +/* END */ diff --git a/drivers/freetype/src/winfonts/Jamfile b/drivers/freetype/src/winfonts/Jamfile new file mode 100644 index 0000000000..71cf5678e8 --- /dev/null +++ b/drivers/freetype/src/winfonts/Jamfile @@ -0,0 +1,16 @@ +# FreeType 2 src/winfonts Jamfile +# +# Copyright 2001 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. + +SubDir FT2_TOP $(FT2_SRC_DIR) winfonts ; + +Library $(FT2_LIB) : winfnt.c ; + +# end of src/winfonts Jamfile diff --git a/drivers/freetype/src/winfonts/fnterrs.h b/drivers/freetype/src/winfonts/fnterrs.h new file mode 100644 index 0000000000..463ba77ee2 --- /dev/null +++ b/drivers/freetype/src/winfonts/fnterrs.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* fnterrs.h */ +/* */ +/* Win FNT/FON error codes (specification only). */ +/* */ +/* Copyright 2001, 2012 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the Windows FNT/FON error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FNTERRS_H__ +#define __FNTERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX FNT_Err_ +#define FT_ERR_BASE FT_Mod_Err_Winfonts + +#include FT_ERRORS_H + +#endif /* __FNTERRS_H__ */ + + +/* END */ diff --git a/drivers/freetype/src/winfonts/module.mk b/drivers/freetype/src/winfonts/module.mk new file mode 100644 index 0000000000..b44d7f0570 --- /dev/null +++ b/drivers/freetype/src/winfonts/module.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 Windows FNT/FON module definition +# + + +# Copyright 1996-2000, 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. + + +FTMODULE_H_COMMANDS += WINDOWS_DRIVER + +define WINDOWS_DRIVER +$(OPEN_DRIVER) FT_Driver_ClassRec, winfnt_driver_class $(CLOSE_DRIVER) +$(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) +endef + +# EOF diff --git a/drivers/freetype/src/winfonts/rules.mk b/drivers/freetype/src/winfonts/rules.mk new file mode 100644 index 0000000000..71a7df2d8a --- /dev/null +++ b/drivers/freetype/src/winfonts/rules.mk @@ -0,0 +1,65 @@ +# +# FreeType 2 Windows FNT/FON driver configuration rules +# + + +# Copyright 1996-2000, 2001, 2003 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. + + +# Windows driver directory +# +FNT_DIR := $(SRC_DIR)/winfonts + + +FNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(FNT_DIR)) + + +# Windows driver sources (i.e., C files) +# +FNT_DRV_SRC := $(FNT_DIR)/winfnt.c + +# Windows driver headers +# +FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h) \ + $(FNT_DIR)/fnterrs.h + + +# Windows driver object(s) +# +# FNT_DRV_OBJ_M is used during `multi' builds +# FNT_DRV_OBJ_S is used during `single' builds +# +FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR)/%.c=$(OBJ_DIR)/%.$O) +FNT_DRV_OBJ_S := $(OBJ_DIR)/winfnt.$O + +# Windows driver source file for single build +# +FNT_DRV_SRC_S := $(FNT_DIR)/winfnt.c + + +# Windows driver - single object +# +$(FNT_DRV_OBJ_S): $(FNT_DRV_SRC_S) $(FNT_DRV_SRC) $(FREETYPE_H) $(FNT_DRV_H) + $(FNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(FNT_DRV_SRC_S)) + + +# Windows driver - multiple objects +# +$(OBJ_DIR)/%.$O: $(FNT_DIR)/%.c $(FREETYPE_H) $(FNT_DRV_H) + $(FNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(FNT_DRV_OBJ_S) +DRV_OBJS_M += $(FNT_DRV_OBJ_M) + + +# EOF diff --git a/drivers/freetype/src/winfonts/winfnt.c b/drivers/freetype/src/winfonts/winfnt.c new file mode 100644 index 0000000000..e8055c0898 --- /dev/null +++ b/drivers/freetype/src/winfonts/winfnt.c @@ -0,0 +1,1155 @@ +/***************************************************************************/ +/* */ +/* winfnt.c */ +/* */ +/* FreeType font driver for Windows FNT/FON files */ +/* */ +/* Copyright 1996-2004, 2006-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* Copyright 2003 Huw D M Davies for Codeweavers */ +/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ +/* */ +/* 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_WINFONTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_TRUETYPE_IDS_H + +#include "winfnt.h" +#include "fnterrs.h" +#include FT_SERVICE_WINFNT_H +#include FT_SERVICE_XFREE86_NAME_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_winfnt + + + static const FT_Frame_Field winmz_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinMZ_HeaderRec + + FT_FRAME_START( 64 ), + FT_FRAME_USHORT_LE ( magic ), + FT_FRAME_SKIP_BYTES( 29 * 2 ), + FT_FRAME_ULONG_LE ( lfanew ), + FT_FRAME_END + }; + + static const FT_Frame_Field winne_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinNE_HeaderRec + + FT_FRAME_START( 40 ), + FT_FRAME_USHORT_LE ( magic ), + FT_FRAME_SKIP_BYTES( 34 ), + FT_FRAME_USHORT_LE ( resource_tab_offset ), + FT_FRAME_USHORT_LE ( rname_tab_offset ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe32_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE32_HeaderRec + + FT_FRAME_START( 248 ), + FT_FRAME_ULONG_LE ( magic ), /* PE00 */ + FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */ + FT_FRAME_USHORT_LE ( number_of_sections ), + FT_FRAME_SKIP_BYTES( 12 ), + FT_FRAME_USHORT_LE ( size_of_optional_header ), + FT_FRAME_SKIP_BYTES( 2 ), + FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */ + FT_FRAME_SKIP_BYTES( 110 ), + FT_FRAME_ULONG_LE ( rsrc_virtual_address ), + FT_FRAME_ULONG_LE ( rsrc_size ), + FT_FRAME_SKIP_BYTES( 104 ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe32_section_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE32_SectionRec + + FT_FRAME_START( 40 ), + FT_FRAME_BYTES ( name, 8 ), + FT_FRAME_SKIP_BYTES( 4 ), + FT_FRAME_ULONG_LE ( virtual_address ), + FT_FRAME_ULONG_LE ( size_of_raw_data ), + FT_FRAME_ULONG_LE ( pointer_to_raw_data ), + FT_FRAME_SKIP_BYTES( 16 ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe_rsrc_dir_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE_RsrcDirRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG_LE ( characteristics ), + FT_FRAME_ULONG_LE ( time_date_stamp ), + FT_FRAME_USHORT_LE( major_version ), + FT_FRAME_USHORT_LE( minor_version ), + FT_FRAME_USHORT_LE( number_of_named_entries ), + FT_FRAME_USHORT_LE( number_of_id_entries ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe_rsrc_dir_entry_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE_RsrcDirEntryRec + + FT_FRAME_START( 8 ), + FT_FRAME_ULONG_LE( name ), + FT_FRAME_ULONG_LE( offset ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe_rsrc_data_entry_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE_RsrcDataEntryRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG_LE( offset_to_data ), + FT_FRAME_ULONG_LE( size ), + FT_FRAME_ULONG_LE( code_page ), + FT_FRAME_ULONG_LE( reserved ), + FT_FRAME_END + }; + + static const FT_Frame_Field winfnt_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_WinFNT_HeaderRec + + FT_FRAME_START( 148 ), + FT_FRAME_USHORT_LE( version ), + FT_FRAME_ULONG_LE ( file_size ), + FT_FRAME_BYTES ( copyright, 60 ), + FT_FRAME_USHORT_LE( file_type ), + FT_FRAME_USHORT_LE( nominal_point_size ), + FT_FRAME_USHORT_LE( vertical_resolution ), + FT_FRAME_USHORT_LE( horizontal_resolution ), + FT_FRAME_USHORT_LE( ascent ), + FT_FRAME_USHORT_LE( internal_leading ), + FT_FRAME_USHORT_LE( external_leading ), + FT_FRAME_BYTE ( italic ), + FT_FRAME_BYTE ( underline ), + FT_FRAME_BYTE ( strike_out ), + FT_FRAME_USHORT_LE( weight ), + FT_FRAME_BYTE ( charset ), + FT_FRAME_USHORT_LE( pixel_width ), + FT_FRAME_USHORT_LE( pixel_height ), + FT_FRAME_BYTE ( pitch_and_family ), + FT_FRAME_USHORT_LE( avg_width ), + FT_FRAME_USHORT_LE( max_width ), + FT_FRAME_BYTE ( first_char ), + FT_FRAME_BYTE ( last_char ), + FT_FRAME_BYTE ( default_char ), + FT_FRAME_BYTE ( break_char ), + FT_FRAME_USHORT_LE( bytes_per_row ), + FT_FRAME_ULONG_LE ( device_offset ), + FT_FRAME_ULONG_LE ( face_name_offset ), + FT_FRAME_ULONG_LE ( bits_pointer ), + FT_FRAME_ULONG_LE ( bits_offset ), + FT_FRAME_BYTE ( reserved ), + FT_FRAME_ULONG_LE ( flags ), + FT_FRAME_USHORT_LE( A_space ), + FT_FRAME_USHORT_LE( B_space ), + FT_FRAME_USHORT_LE( C_space ), + FT_FRAME_ULONG_LE ( color_table_offset ), + FT_FRAME_BYTES ( reserved1, 16 ), + FT_FRAME_END + }; + + + static void + fnt_font_done( FNT_Face face ) + { + FT_Memory memory = FT_FACE( face )->memory; + FT_Stream stream = FT_FACE( face )->stream; + FNT_Font font = face->font; + + + if ( !font ) + return; + + if ( font->fnt_frame ) + FT_FRAME_RELEASE( font->fnt_frame ); + FT_FREE( font->family_name ); + + FT_FREE( font ); + face->font = 0; + } + + + static FT_Error + fnt_font_load( FNT_Font font, + FT_Stream stream ) + { + FT_Error error; + FT_WinFNT_Header header = &font->header; + FT_Bool new_format; + FT_UInt size; + + + /* first of all, read the FNT header */ + if ( FT_STREAM_SEEK( font->offset ) || + FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) ) + goto Exit; + + /* check header */ + if ( header->version != 0x200 && + header->version != 0x300 ) + { + FT_TRACE2(( " not a Windows FNT file\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + new_format = FT_BOOL( font->header.version == 0x300 ); + size = new_format ? 148 : 118; + + if ( header->file_size < size ) + { + FT_TRACE2(( " not a Windows FNT file\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* Version 2 doesn't have these fields */ + if ( header->version == 0x200 ) + { + header->flags = 0; + header->A_space = 0; + header->B_space = 0; + header->C_space = 0; + + header->color_table_offset = 0; + } + + if ( header->file_type & 1 ) + { + FT_TRACE2(( "[can't handle vector FNT fonts]\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* this is a FNT file/table; extract its frame */ + if ( FT_STREAM_SEEK( font->offset ) || + FT_FRAME_EXTRACT( header->file_size, font->fnt_frame ) ) + goto Exit; + + Exit: + return error; + } + + + static FT_Error + fnt_face_get_dll_font( FNT_Face face, + FT_Int face_index ) + { + FT_Error error; + FT_Stream stream = FT_FACE( face )->stream; + FT_Memory memory = FT_FACE( face )->memory; + WinMZ_HeaderRec mz_header; + + + face->font = 0; + + /* does it begin with an MZ header? */ + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) ) + goto Exit; + + error = FT_ERR( Unknown_File_Format ); + if ( mz_header.magic == WINFNT_MZ_MAGIC ) + { + /* yes, now look for an NE header in the file */ + WinNE_HeaderRec ne_header; + + + FT_TRACE2(( "MZ signature found\n" )); + + if ( FT_STREAM_SEEK( mz_header.lfanew ) || + FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) ) + goto Exit; + + error = FT_ERR( Unknown_File_Format ); + if ( ne_header.magic == WINFNT_NE_MAGIC ) + { + /* good, now look into the resource table for each FNT resource */ + FT_ULong res_offset = mz_header.lfanew + + ne_header.resource_tab_offset; + FT_UShort size_shift; + FT_UShort font_count = 0; + FT_ULong font_offset = 0; + + + FT_TRACE2(( "NE signature found\n" )); + + if ( FT_STREAM_SEEK( res_offset ) || + FT_FRAME_ENTER( ne_header.rname_tab_offset - + ne_header.resource_tab_offset ) ) + goto Exit; + + size_shift = FT_GET_USHORT_LE(); + + for (;;) + { + FT_UShort type_id, count; + + + type_id = FT_GET_USHORT_LE(); + if ( !type_id ) + break; + + count = FT_GET_USHORT_LE(); + + if ( type_id == 0x8008U ) + { + font_count = count; + font_offset = (FT_ULong)( FT_STREAM_POS() + 4 + + ( stream->cursor - stream->limit ) ); + break; + } + + stream->cursor += 4 + count * 12; + } + + FT_FRAME_EXIT(); + + if ( !font_count || !font_offset ) + { + FT_TRACE2(( "this file doesn't contain any FNT resources\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* loading `winfnt_header_fields' needs at least 118 bytes; */ + /* use this as a rough measure to check the expected font size */ + if ( font_count * 118UL > stream->size ) + { + FT_TRACE2(( "invalid number of faces\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + face->root.num_faces = font_count; + + if ( face_index >= font_count ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + else if ( face_index < 0 ) + goto Exit; + + if ( FT_NEW( face->font ) ) + goto Exit; + + if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) || + FT_FRAME_ENTER( 12 ) ) + goto Fail; + + face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; + face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift; + + stream->cursor += 8; + + FT_FRAME_EXIT(); + + error = fnt_font_load( face->font, stream ); + } + else if ( ne_header.magic == WINFNT_PE_MAGIC ) + { + WinPE32_HeaderRec pe32_header; + WinPE32_SectionRec pe32_section; + WinPE_RsrcDirRec root_dir, name_dir, lang_dir; + WinPE_RsrcDirEntryRec dir_entry1, dir_entry2, dir_entry3; + WinPE_RsrcDataEntryRec data_entry; + + FT_Long root_dir_offset, name_dir_offset, lang_dir_offset; + FT_UShort i, j, k; + + + FT_TRACE2(( "PE signature found\n" )); + + if ( FT_STREAM_SEEK( mz_header.lfanew ) || + FT_STREAM_READ_FIELDS( winpe32_header_fields, &pe32_header ) ) + goto Exit; + + FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, " + "size_of_optional_header %02x\n" + "magic32 %02x, rsrc_virtual_address %04lx, " + "rsrc_size %04lx\n", + pe32_header.magic, pe32_header.machine, + pe32_header.number_of_sections, + pe32_header.size_of_optional_header, + pe32_header.magic32, pe32_header.rsrc_virtual_address, + pe32_header.rsrc_size )); + + if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ || + pe32_header.machine != 0x014c /* i386 */ || + pe32_header.size_of_optional_header != 0xe0 /* FIXME */ || + pe32_header.magic32 != 0x10b ) + { + FT_TRACE2(( "this file has an invalid PE header\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + face->root.num_faces = 0; + + for ( i = 0; i < pe32_header.number_of_sections; i++ ) + { + if ( FT_STREAM_READ_FIELDS( winpe32_section_fields, + &pe32_section ) ) + goto Exit; + + FT_TRACE2(( "name %.8s, va %04lx, size %04lx, offset %04lx\n", + pe32_section.name, pe32_section.virtual_address, + pe32_section.size_of_raw_data, + pe32_section.pointer_to_raw_data )); + + if ( pe32_header.rsrc_virtual_address == + pe32_section.virtual_address ) + goto Found_rsrc_section; + } + + FT_TRACE2(( "this file doesn't contain any resources\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + + Found_rsrc_section: + FT_TRACE2(( "found resources section %.8s\n", pe32_section.name )); + + if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &root_dir ) ) + goto Exit; + + root_dir_offset = pe32_section.pointer_to_raw_data; + + for ( i = 0; i < root_dir.number_of_named_entries + + root_dir.number_of_id_entries; i++ ) + { + if ( FT_STREAM_SEEK( root_dir_offset + 16 + i * 8 ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, + &dir_entry1 ) ) + goto Exit; + + if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + dir_entry1.offset &= ~0x80000000UL; + + name_dir_offset = pe32_section.pointer_to_raw_data + + dir_entry1.offset; + + if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data + + dir_entry1.offset ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &name_dir ) ) + goto Exit; + + for ( j = 0; j < name_dir.number_of_named_entries + + name_dir.number_of_id_entries; j++ ) + { + if ( FT_STREAM_SEEK( name_dir_offset + 16 + j * 8 ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, + &dir_entry2 ) ) + goto Exit; + + if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + dir_entry2.offset &= ~0x80000000UL; + + lang_dir_offset = pe32_section.pointer_to_raw_data + + dir_entry2.offset; + + if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data + + dir_entry2.offset ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &lang_dir ) ) + goto Exit; + + for ( k = 0; k < lang_dir.number_of_named_entries + + lang_dir.number_of_id_entries; k++ ) + { + if ( FT_STREAM_SEEK( lang_dir_offset + 16 + k * 8 ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, + &dir_entry3 ) ) + goto Exit; + + if ( dir_entry2.offset & 0x80000000UL /* DataIsDirectory */ ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dir_entry1.name == 8 /* RT_FONT */ ) + { + if ( FT_STREAM_SEEK( root_dir_offset + dir_entry3.offset ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_data_entry_fields, + &data_entry ) ) + goto Exit; + + FT_TRACE2(( "found font #%lu, offset %04lx, " + "size %04lx, cp %lu\n", + dir_entry2.name, + pe32_section.pointer_to_raw_data + + data_entry.offset_to_data - + pe32_section.virtual_address, + data_entry.size, data_entry.code_page )); + + if ( face_index == face->root.num_faces ) + { + if ( FT_NEW( face->font ) ) + goto Exit; + + face->font->offset = pe32_section.pointer_to_raw_data + + data_entry.offset_to_data - + pe32_section.virtual_address; + face->font->fnt_size = data_entry.size; + + error = fnt_font_load( face->font, stream ); + if ( error ) + { + FT_TRACE2(( "font #%lu load error %d\n", + dir_entry2.name, error )); + goto Fail; + } + else + FT_TRACE2(( "font #%lu successfully loaded\n", + dir_entry2.name )); + } + + face->root.num_faces++; + } + } + } + } + } + + if ( !face->root.num_faces ) + { + FT_TRACE2(( "this file doesn't contain any RT_FONT resources\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( face_index >= face->root.num_faces ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + } + + Fail: + if ( error ) + fnt_font_done( face ); + + Exit: + return error; + } + + + typedef struct FNT_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt32 first; + FT_UInt32 count; + + } FNT_CMapRec, *FNT_CMap; + + + static FT_Error + fnt_cmap_init( FNT_CMap cmap ) + { + FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); + FNT_Font font = face->font; + + + cmap->first = (FT_UInt32) font->header.first_char; + cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 ); + + return 0; + } + + + static FT_UInt + fnt_cmap_char_index( FNT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UInt gindex = 0; + + + char_code -= cmap->first; + if ( char_code < cmap->count ) + /* we artificially increase the glyph index; */ + /* FNT_Load_Glyph reverts to the right one */ + gindex = (FT_UInt)( char_code + 1 ); + return gindex; + } + + + static FT_UInt32 + fnt_cmap_char_next( FNT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt gindex = 0; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + if ( char_code <= cmap->first ) + { + result = cmap->first; + gindex = 1; + } + else + { + char_code -= cmap->first; + if ( char_code < cmap->count ) + { + result = cmap->first + char_code; + gindex = (FT_UInt)( char_code + 1 ); + } + } + + *pchar_code = result; + return gindex; + } + + + static const FT_CMap_ClassRec fnt_cmap_class_rec = + { + sizeof ( FNT_CMapRec ), + + (FT_CMap_InitFunc) fnt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)fnt_cmap_char_index, + (FT_CMap_CharNextFunc) fnt_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + static FT_CMap_Class const fnt_cmap_class = &fnt_cmap_class_rec; + + + static void + FNT_Face_Done( FT_Face fntface ) /* FNT_Face */ + { + FNT_Face face = (FNT_Face)fntface; + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + fnt_font_done( face ); + + FT_FREE( fntface->available_sizes ); + fntface->num_fixed_sizes = 0; + } + + + static FT_Error + FNT_Face_Init( FT_Stream stream, + FT_Face fntface, /* FNT_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FNT_Face face = (FNT_Face)fntface; + FT_Error error; + FT_Memory memory = FT_FACE_MEMORY( face ); + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + FT_TRACE2(( "Windows FNT driver\n" )); + + /* try to load font from a DLL */ + error = fnt_face_get_dll_font( face, face_index ); + if ( !error && face_index < 0 ) + goto Exit; + + if ( FT_ERR_EQ( error, Unknown_File_Format ) ) + { + /* this didn't work; try to load a single FNT font */ + FNT_Font font; + + if ( FT_NEW( face->font ) ) + goto Exit; + + fntface->num_faces = 1; + + font = face->font; + font->offset = 0; + font->fnt_size = stream->size; + + error = fnt_font_load( font, stream ); + + if ( !error ) + { + if ( face_index > 0 ) + error = FT_THROW( Invalid_Argument ); + else if ( face_index < 0 ) + goto Exit; + } + } + + if ( error ) + goto Fail; + + /* we now need to fill the root FT_Face fields */ + /* with relevant information */ + { + FT_Face root = FT_FACE( face ); + FNT_Font font = face->font; + FT_PtrDist family_size; + + + root->face_index = face_index; + + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL; + + if ( font->header.avg_width == font->header.max_width ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( font->header.italic ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + + if ( font->header.weight >= 800 ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + + /* set up the `fixed_sizes' array */ + if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) + goto Fail; + + root->num_fixed_sizes = 1; + + { + FT_Bitmap_Size* bsize = root->available_sizes; + FT_UShort x_res, y_res; + + + bsize->width = font->header.avg_width; + bsize->height = (FT_Short)( + font->header.pixel_height + font->header.external_leading ); + bsize->size = font->header.nominal_point_size << 6; + + x_res = font->header.horizontal_resolution; + if ( !x_res ) + x_res = 72; + + y_res = font->header.vertical_resolution; + if ( !y_res ) + y_res = 72; + + bsize->y_ppem = FT_MulDiv( bsize->size, y_res, 72 ); + bsize->y_ppem = FT_PIX_ROUND( bsize->y_ppem ); + + /* + * this reads: + * + * the nominal height is larger than the bbox's height + * + * => nominal_point_size contains incorrect value; + * use pixel_height as the nominal height + */ + if ( bsize->y_ppem > ( font->header.pixel_height << 6 ) ) + { + FT_TRACE2(( "use pixel_height as the nominal height\n" )); + + bsize->y_ppem = font->header.pixel_height << 6; + bsize->size = FT_MulDiv( bsize->y_ppem, 72, y_res ); + } + + bsize->x_ppem = FT_MulDiv( bsize->size, x_res, 72 ); + bsize->x_ppem = FT_PIX_ROUND( bsize->x_ppem ); + } + + { + FT_CharMapRec charmap; + + + charmap.encoding = FT_ENCODING_NONE; + /* initial platform/encoding should indicate unset status? */ + charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; + charmap.encoding_id = TT_APPLE_ID_DEFAULT; + charmap.face = root; + + if ( font->header.charset == FT_WinFNT_ID_MAC ) + { + charmap.encoding = FT_ENCODING_APPLE_ROMAN; + charmap.platform_id = TT_PLATFORM_MACINTOSH; +/* charmap.encoding_id = TT_MAC_ID_ROMAN; */ + } + + error = FT_CMap_New( fnt_cmap_class, + NULL, + &charmap, + NULL ); + if ( error ) + goto Fail; + + /* Select default charmap */ + if ( root->num_charmaps ) + root->charmap = root->charmaps[0]; + } + + /* set up remaining flags */ + + if ( font->header.last_char < font->header.first_char ) + { + FT_TRACE2(( "invalid number of glyphs\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* reserve one slot for the .notdef glyph at index 0 */ + root->num_glyphs = font->header.last_char - + font->header.first_char + 1 + 1; + + if ( font->header.face_name_offset >= font->header.file_size ) + { + FT_TRACE2(( "invalid family name offset\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + family_size = font->header.file_size - font->header.face_name_offset; + /* Some broken fonts don't delimit the face name with a final */ + /* NULL byte -- the frame is erroneously one byte too small. */ + /* We thus allocate one more byte, setting it explicitly to */ + /* zero. */ + if ( FT_ALLOC( font->family_name, family_size + 1 ) ) + goto Fail; + + FT_MEM_COPY( font->family_name, + font->fnt_frame + font->header.face_name_offset, + family_size ); + + font->family_name[family_size] = '\0'; + + if ( FT_REALLOC( font->family_name, + family_size, + ft_strlen( font->family_name ) + 1 ) ) + goto Fail; + + root->family_name = font->family_name; + root->style_name = (char *)"Regular"; + + if ( root->style_flags & FT_STYLE_FLAG_BOLD ) + { + if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Bold Italic"; + else + root->style_name = (char *)"Bold"; + } + else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Italic"; + } + goto Exit; + + Fail: + FNT_Face_Done( fntface ); + + Exit: + return error; + } + + + static FT_Error + FNT_Size_Select( FT_Size size, + FT_ULong strike_index ) + { + FNT_Face face = (FNT_Face)size->face; + FT_WinFNT_Header header = &face->font->header; + + FT_UNUSED( strike_index ); + + + FT_Select_Metrics( size->face, 0 ); + + size->metrics.ascender = header->ascent * 64; + size->metrics.descender = -( header->pixel_height - + header->ascent ) * 64; + size->metrics.max_advance = header->max_width * 64; + + return FT_Err_Ok; + } + + + static FT_Error + FNT_Size_Request( FT_Size size, + FT_Size_Request req ) + { + FNT_Face face = (FNT_Face)size->face; + FT_WinFNT_Header header = &face->font->header; + FT_Bitmap_Size* bsize = size->face->available_sizes; + FT_Error error = FT_ERR( Invalid_Pixel_Size ); + FT_Long height; + + + height = FT_REQUEST_HEIGHT( req ); + height = ( height + 32 ) >> 6; + + switch ( req->type ) + { + case FT_SIZE_REQUEST_TYPE_NOMINAL: + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) + error = FT_Err_Ok; + break; + + case FT_SIZE_REQUEST_TYPE_REAL_DIM: + if ( height == header->pixel_height ) + error = FT_Err_Ok; + break; + + default: + error = FT_THROW( Unimplemented_Feature ); + break; + } + + if ( error ) + return error; + else + return FNT_Size_Select( size, 0 ); + } + + + static FT_Error + FNT_Load_Glyph( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); + FNT_Font font; + FT_Error error = FT_Err_Ok; + FT_Byte* p; + FT_Int len; + FT_Bitmap* bitmap = &slot->bitmap; + FT_ULong offset; + FT_Bool new_format; + + FT_UNUSED( load_flags ); + + + if ( !face ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + font = face->font; + + if ( !font || + glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( glyph_index > 0 ) + glyph_index--; /* revert to real index */ + else + glyph_index = font->header.default_char; /* the .notdef glyph */ + + new_format = FT_BOOL( font->header.version == 0x300 ); + len = new_format ? 6 : 4; + + /* jump to glyph entry */ + p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index; + + bitmap->width = FT_NEXT_SHORT_LE( p ); + + if ( new_format ) + offset = FT_NEXT_ULONG_LE( p ); + else + offset = FT_NEXT_USHORT_LE( p ); + + if ( offset >= font->header.file_size ) + { + FT_TRACE2(( "invalid FNT offset\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* jump to glyph data */ + p = font->fnt_frame + /* font->header.bits_offset */ + offset; + + /* allocate and build bitmap */ + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + FT_Int pitch = ( bitmap->width + 7 ) >> 3; + FT_Byte* column; + FT_Byte* write; + + + bitmap->pitch = pitch; + bitmap->rows = font->header.pixel_height; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + if ( offset + pitch * bitmap->rows >= font->header.file_size ) + { + FT_TRACE2(( "invalid bitmap width\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* note: since glyphs are stored in columns and not in rows we */ + /* can't use ft_glyphslot_set_bitmap */ + if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) ) + goto Exit; + + column = (FT_Byte*)bitmap->buffer; + + for ( ; pitch > 0; pitch--, column++ ) + { + FT_Byte* limit = p + bitmap->rows; + + + for ( write = column; p < limit; p++, write += bitmap->pitch ) + *write = *p; + } + } + + slot->internal->flags = FT_GLYPH_OWN_BITMAP; + slot->bitmap_left = 0; + slot->bitmap_top = font->header.ascent; + slot->format = FT_GLYPH_FORMAT_BITMAP; + + /* now set up metrics */ + slot->metrics.width = bitmap->width << 6; + slot->metrics.height = bitmap->rows << 6; + slot->metrics.horiAdvance = bitmap->width << 6; + slot->metrics.horiBearingX = 0; + slot->metrics.horiBearingY = slot->bitmap_top << 6; + + ft_synthesize_vertical_metrics( &slot->metrics, + bitmap->rows << 6 ); + + Exit: + return error; + } + + + static FT_Error + winfnt_get_header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ) + { + FNT_Font font = ((FNT_Face)face)->font; + + + *aheader = font->header; + + return 0; + } + + + static const FT_Service_WinFntRec winfnt_service_rec = + { + winfnt_get_header + }; + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec winfnt_services[] = + { + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT }, + { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, + { NULL, NULL } + }; + + + static FT_Module_Interface + winfnt_get_service( FT_Module module, + const FT_String* service_id ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( winfnt_services, service_id ); + } + + + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec winfnt_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, + sizeof ( FT_DriverRec ), + + "winfonts", + 0x10000L, + 0x20000L, + + 0, + + 0, /* FT_Module_Constructor */ + 0, /* FT_Module_Destructor */ + winfnt_get_service + }, + + sizeof ( FNT_FaceRec ), + sizeof ( FT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + FNT_Face_Init, + FNT_Face_Done, + 0, /* FT_Size_InitFunc */ + 0, /* FT_Size_DoneFunc */ + 0, /* FT_Slot_InitFunc */ + 0, /* FT_Slot_DoneFunc */ + + FNT_Load_Glyph, + + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetAdvancesFunc */ + + FNT_Size_Request, + FNT_Size_Select + }; + + +/* END */ diff --git a/drivers/freetype/src/winfonts/winfnt.h b/drivers/freetype/src/winfonts/winfnt.h new file mode 100644 index 0000000000..b7a80736d8 --- /dev/null +++ b/drivers/freetype/src/winfonts/winfnt.h @@ -0,0 +1,171 @@ +/***************************************************************************/ +/* */ +/* winfnt.h */ +/* */ +/* FreeType font driver for Windows FNT/FON files */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ +/* */ +/* 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 __WINFNT_H__ +#define __WINFNT_H__ + + +#include <ft2build.h> +#include FT_WINFONTS_H +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + typedef struct WinMZ_HeaderRec_ + { + FT_UShort magic; + /* skipped content */ + FT_UShort lfanew; + + } WinMZ_HeaderRec; + + + typedef struct WinNE_HeaderRec_ + { + FT_UShort magic; + /* skipped content */ + FT_UShort resource_tab_offset; + FT_UShort rname_tab_offset; + + } WinNE_HeaderRec; + + + typedef struct WinPE32_HeaderRec_ + { + FT_ULong magic; + FT_UShort machine; + FT_UShort number_of_sections; + /* skipped content */ + FT_UShort size_of_optional_header; + /* skipped content */ + FT_UShort magic32; + /* skipped content */ + FT_ULong rsrc_virtual_address; + FT_ULong rsrc_size; + /* skipped content */ + + } WinPE32_HeaderRec; + + + typedef struct WinPE32_SectionRec_ + { + FT_Byte name[8]; + /* skipped content */ + FT_ULong virtual_address; + FT_ULong size_of_raw_data; + FT_ULong pointer_to_raw_data; + /* skipped content */ + + } WinPE32_SectionRec; + + + typedef struct WinPE_RsrcDirRec_ + { + FT_ULong characteristics; + FT_ULong time_date_stamp; + FT_UShort major_version; + FT_UShort minor_version; + FT_UShort number_of_named_entries; + FT_UShort number_of_id_entries; + + } WinPE_RsrcDirRec; + + + typedef struct WinPE_RsrcDirEntryRec_ + { + FT_ULong name; + FT_ULong offset; + + } WinPE_RsrcDirEntryRec; + + + typedef struct WinPE_RsrcDataEntryRec_ + { + FT_ULong offset_to_data; + FT_ULong size; + FT_ULong code_page; + FT_ULong reserved; + + } WinPE_RsrcDataEntryRec; + + + typedef struct WinNameInfoRec_ + { + FT_UShort offset; + FT_UShort length; + FT_UShort flags; + FT_UShort id; + FT_UShort handle; + FT_UShort usage; + + } WinNameInfoRec; + + + typedef struct WinResourceInfoRec_ + { + FT_UShort type_id; + FT_UShort count; + + } WinResourceInfoRec; + + +#define WINFNT_MZ_MAGIC 0x5A4D +#define WINFNT_NE_MAGIC 0x454E +#define WINFNT_PE_MAGIC 0x4550 + + + typedef struct FNT_FontRec_ + { + FT_ULong offset; + + FT_WinFNT_HeaderRec header; + + FT_Byte* fnt_frame; + FT_ULong fnt_size; + FT_String* family_name; + + } FNT_FontRec, *FNT_Font; + + + typedef struct FNT_FaceRec_ + { + FT_FaceRec root; + FNT_Font font; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + } FNT_FaceRec, *FNT_Face; + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) winfnt_driver_class; + + +FT_END_HEADER + + +#endif /* __WINFNT_H__ */ + + +/* END */ -- cgit v1.2.3 From 4d4cb1bfabc8545ad593149df65340389bcb7ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= <rverschelde@gmail.com> Date: Fri, 22 Jul 2016 23:29:25 +0200 Subject: FreeType: Update to upstream version 2.6.5 The only diffs to the upstream sources are to be found in `include/ft2build.h` and `include/freetype/config/ftoption.h`. --- drivers/freetype/SCsub | 2 +- .../freetype/include/freetype/config/ftconfig.h | 211 +- .../freetype/include/freetype/config/ftheader.h | 25 +- .../freetype/include/freetype/config/ftoption.h | 244 +- .../freetype/include/freetype/config/ftstdlib.h | 16 +- drivers/freetype/include/freetype/freetype.h | 798 +- drivers/freetype/include/freetype/ftadvanc.h | 21 +- drivers/freetype/include/freetype/ftautoh.h | 184 +- drivers/freetype/include/freetype/ftbbox.h | 13 +- drivers/freetype/include/freetype/ftbdf.h | 15 +- drivers/freetype/include/freetype/ftbitmap.h | 27 +- drivers/freetype/include/freetype/ftbzip2.h | 10 +- drivers/freetype/include/freetype/ftcache.h | 28 +- drivers/freetype/include/freetype/ftcffdrv.h | 139 +- drivers/freetype/include/freetype/ftchapters.h | 17 +- drivers/freetype/include/freetype/ftcid.h | 16 +- drivers/freetype/include/freetype/fterrdef.h | 233 +- drivers/freetype/include/freetype/fterrors.h | 118 +- drivers/freetype/include/freetype/ftfntfmt.h | 95 + drivers/freetype/include/freetype/ftgasp.h | 11 +- drivers/freetype/include/freetype/ftglyph.h | 35 +- drivers/freetype/include/freetype/ftgxval.h | 41 +- drivers/freetype/include/freetype/ftgzip.h | 56 +- drivers/freetype/include/freetype/ftimage.h | 252 +- drivers/freetype/include/freetype/ftincrem.h | 11 +- drivers/freetype/include/freetype/ftlcdfil.h | 187 +- drivers/freetype/include/freetype/ftlist.h | 21 +- drivers/freetype/include/freetype/ftlzw.h | 10 +- drivers/freetype/include/freetype/ftmac.h | 12 +- drivers/freetype/include/freetype/ftmm.h | 48 +- drivers/freetype/include/freetype/ftmodapi.h | 72 +- drivers/freetype/include/freetype/ftmoderr.h | 10 +- drivers/freetype/include/freetype/ftotval.h | 37 +- drivers/freetype/include/freetype/ftoutln.h | 52 +- drivers/freetype/include/freetype/ftpfr.h | 10 +- drivers/freetype/include/freetype/ftrender.h | 18 +- drivers/freetype/include/freetype/ftsizes.h | 10 +- drivers/freetype/include/freetype/ftsnames.h | 12 +- drivers/freetype/include/freetype/ftstroke.h | 50 +- drivers/freetype/include/freetype/ftsynth.h | 17 +- drivers/freetype/include/freetype/ftsystem.h | 18 +- drivers/freetype/include/freetype/fttrigon.h | 16 +- drivers/freetype/include/freetype/ftttdrv.h | 231 +- drivers/freetype/include/freetype/fttypes.h | 20 +- drivers/freetype/include/freetype/ftwinfnt.h | 19 +- drivers/freetype/include/freetype/ftxf86.h | 83 - .../freetype/include/freetype/internal/autohint.h | 8 +- .../freetype/include/freetype/internal/ftcalc.h | 305 +- .../freetype/include/freetype/internal/ftdebug.h | 10 +- .../freetype/include/freetype/internal/ftdriver.h | 10 +- .../freetype/include/freetype/internal/ftgloadr.h | 58 +- .../freetype/include/freetype/internal/fthash.h | 136 + .../freetype/include/freetype/internal/ftmemory.h | 38 +- .../freetype/include/freetype/internal/ftobjs.h | 87 +- drivers/freetype/include/freetype/internal/ftpic.h | 8 +- .../freetype/include/freetype/internal/ftrfork.h | 22 +- .../freetype/include/freetype/internal/ftserv.h | 10 +- .../freetype/include/freetype/internal/ftstream.h | 10 +- .../freetype/include/freetype/internal/fttrace.h | 4 +- .../freetype/include/freetype/internal/ftvalid.h | 30 +- .../freetype/include/freetype/internal/internal.h | 4 +- drivers/freetype/include/freetype/internal/psaux.h | 28 +- .../freetype/include/freetype/internal/pshints.h | 12 +- .../include/freetype/internal/services/svbdf.h | 8 +- .../include/freetype/internal/services/svcid.h | 9 +- .../include/freetype/internal/services/svfntfmt.h | 55 + .../include/freetype/internal/services/svgldict.h | 11 +- .../include/freetype/internal/services/svgxval.h | 8 +- .../include/freetype/internal/services/svkern.h | 8 +- .../include/freetype/internal/services/svmm.h | 8 +- .../include/freetype/internal/services/svotval.h | 8 +- .../include/freetype/internal/services/svpfr.h | 8 +- .../include/freetype/internal/services/svpostnm.h | 8 +- .../include/freetype/internal/services/svprop.h | 8 +- .../include/freetype/internal/services/svpscmap.h | 8 +- .../include/freetype/internal/services/svpsinfo.h | 8 +- .../include/freetype/internal/services/svsfnt.h | 8 +- .../include/freetype/internal/services/svttcmap.h | 19 +- .../include/freetype/internal/services/svtteng.h | 8 +- .../include/freetype/internal/services/svttglyf.h | 9 +- .../include/freetype/internal/services/svwinfnt.h | 8 +- .../include/freetype/internal/services/svxf86nm.h | 55 - drivers/freetype/include/freetype/internal/sfnt.h | 67 +- .../freetype/include/freetype/internal/t1types.h | 28 +- .../freetype/include/freetype/internal/tttypes.h | 156 +- drivers/freetype/include/freetype/t1tables.h | 131 +- drivers/freetype/include/freetype/ttnameid.h | 240 +- drivers/freetype/include/freetype/tttables.h | 108 +- drivers/freetype/include/freetype/tttags.h | 10 +- drivers/freetype/include/freetype/ttunpat.h | 22 +- drivers/freetype/include/ft2build.h | 21 +- drivers/freetype/src/Jamfile | 8 +- drivers/freetype/src/autofit/Jamfile | 20 +- drivers/freetype/src/autofit/afangles.c | 64 +- drivers/freetype/src/autofit/afblue.c | 459 ++ drivers/freetype/src/autofit/afblue.cin | 39 + drivers/freetype/src/autofit/afblue.dat | 718 ++ drivers/freetype/src/autofit/afblue.h | 308 + drivers/freetype/src/autofit/afblue.hin | 146 + drivers/freetype/src/autofit/afcjk.c | 906 ++- drivers/freetype/src/autofit/afcjk.h | 73 +- drivers/freetype/src/autofit/afcover.h | 105 + drivers/freetype/src/autofit/afdummy.c | 51 +- drivers/freetype/src/autofit/afdummy.h | 14 +- drivers/freetype/src/autofit/aferrors.h | 11 +- drivers/freetype/src/autofit/afglobal.c | 415 +- drivers/freetype/src/autofit/afglobal.h | 114 +- drivers/freetype/src/autofit/afhints.c | 776 +- drivers/freetype/src/autofit/afhints.h | 187 +- drivers/freetype/src/autofit/afindic.c | 84 +- drivers/freetype/src/autofit/afindic.h | 15 +- drivers/freetype/src/autofit/aflatin.c | 1741 ++++- drivers/freetype/src/autofit/aflatin.h | 94 +- drivers/freetype/src/autofit/aflatin2.c | 157 +- drivers/freetype/src/autofit/aflatin2.h | 21 +- drivers/freetype/src/autofit/afloader.c | 543 +- drivers/freetype/src/autofit/afloader.h | 34 +- drivers/freetype/src/autofit/afmodule.c | 278 +- drivers/freetype/src/autofit/afmodule.h | 30 +- drivers/freetype/src/autofit/afpic.c | 67 +- drivers/freetype/src/autofit/afpic.h | 55 +- drivers/freetype/src/autofit/afranges.c | 714 ++ drivers/freetype/src/autofit/afranges.h | 47 + drivers/freetype/src/autofit/afscript.h | 245 + drivers/freetype/src/autofit/afshaper.c | 683 ++ drivers/freetype/src/autofit/afshaper.h | 72 + drivers/freetype/src/autofit/afstyles.h | 301 + drivers/freetype/src/autofit/aftypes.h | 510 +- drivers/freetype/src/autofit/afwarp.c | 10 +- drivers/freetype/src/autofit/afwarp.h | 10 +- drivers/freetype/src/autofit/afwrtsys.h | 52 + drivers/freetype/src/autofit/autofit.c | 7 +- drivers/freetype/src/autofit/module.mk | 2 +- drivers/freetype/src/autofit/rules.mk | 16 +- drivers/freetype/src/base/Jamfile | 48 +- drivers/freetype/src/base/basepic.c | 6 +- drivers/freetype/src/base/basepic.h | 17 +- drivers/freetype/src/base/ftadvanc.c | 24 +- drivers/freetype/src/base/ftapi.c | 2 +- drivers/freetype/src/base/ftbase.c | 3 +- drivers/freetype/src/base/ftbase.h | 13 +- drivers/freetype/src/base/ftbbox.c | 434 +- drivers/freetype/src/base/ftbdf.c | 43 +- drivers/freetype/src/base/ftbitmap.c | 275 +- drivers/freetype/src/base/ftcalc.c | 791 +- drivers/freetype/src/base/ftcid.c | 3 +- drivers/freetype/src/base/ftdbgmem.c | 131 +- drivers/freetype/src/base/ftdebug.c | 6 +- drivers/freetype/src/base/ftfntfmt.c | 55 + drivers/freetype/src/base/ftfstype.c | 4 +- drivers/freetype/src/base/ftgasp.c | 2 +- drivers/freetype/src/base/ftgloadr.c | 17 +- drivers/freetype/src/base/ftglyph.c | 100 +- drivers/freetype/src/base/ftgxval.c | 6 +- drivers/freetype/src/base/fthash.c | 339 + drivers/freetype/src/base/ftinit.c | 30 +- drivers/freetype/src/base/ftlcdfil.c | 75 +- drivers/freetype/src/base/ftmac.c | 37 +- drivers/freetype/src/base/ftmm.c | 32 +- drivers/freetype/src/base/ftobjs.c | 624 +- drivers/freetype/src/base/ftotval.c | 2 +- drivers/freetype/src/base/ftoutln.c | 245 +- drivers/freetype/src/base/ftpatent.c | 247 +- drivers/freetype/src/base/ftpfr.c | 15 +- drivers/freetype/src/base/ftpic.c | 4 +- drivers/freetype/src/base/ftrfork.c | 91 +- drivers/freetype/src/base/ftsnames.c | 2 +- drivers/freetype/src/base/ftstream.c | 95 +- drivers/freetype/src/base/ftstroke.c | 151 +- drivers/freetype/src/base/ftsynth.c | 34 +- drivers/freetype/src/base/ftsystem.c | 16 +- drivers/freetype/src/base/fttrigon.c | 168 +- drivers/freetype/src/base/fttype1.c | 45 +- drivers/freetype/src/base/ftutil.c | 77 +- drivers/freetype/src/base/ftwinfnt.c | 22 +- drivers/freetype/src/base/ftxf86.c | 40 - drivers/freetype/src/base/md5.c | 108 +- drivers/freetype/src/base/md5.h | 2 +- drivers/freetype/src/base/rules.mk | 21 +- drivers/freetype/src/bdf/Jamfile | 6 +- drivers/freetype/src/bdf/bdf.h | 41 +- drivers/freetype/src/bdf/bdfdrivr.c | 112 +- drivers/freetype/src/bdf/bdfdrivr.h | 8 +- drivers/freetype/src/bdf/bdferror.h | 8 +- drivers/freetype/src/bdf/bdflib.c | 719 +- drivers/freetype/src/bdf/rules.mk | 5 +- drivers/freetype/src/cache/Jamfile | 16 +- drivers/freetype/src/cache/ftcache.c | 2 +- drivers/freetype/src/cache/ftcbasic.c | 103 +- drivers/freetype/src/cache/ftccache.c | 30 +- drivers/freetype/src/cache/ftccache.h | 48 +- drivers/freetype/src/cache/ftccback.h | 9 +- drivers/freetype/src/cache/ftccmap.c | 20 +- drivers/freetype/src/cache/ftcerror.h | 11 +- drivers/freetype/src/cache/ftcglyph.c | 6 +- drivers/freetype/src/cache/ftcglyph.h | 16 +- drivers/freetype/src/cache/ftcimage.c | 11 +- drivers/freetype/src/cache/ftcimage.h | 12 +- drivers/freetype/src/cache/ftcmanag.c | 52 +- drivers/freetype/src/cache/ftcmanag.h | 10 +- drivers/freetype/src/cache/ftcmru.c | 2 +- drivers/freetype/src/cache/ftcmru.h | 14 +- drivers/freetype/src/cache/ftcsbits.c | 18 +- drivers/freetype/src/cache/ftcsbits.h | 12 +- drivers/freetype/src/cache/rules.mk | 9 +- drivers/freetype/src/cff/Jamfile | 20 +- drivers/freetype/src/cff/cf2arrst.c | 4 +- drivers/freetype/src/cff/cf2arrst.h | 6 +- drivers/freetype/src/cff/cf2blues.c | 13 +- drivers/freetype/src/cff/cf2blues.h | 6 +- drivers/freetype/src/cff/cf2error.h | 10 +- drivers/freetype/src/cff/cf2fixed.h | 28 +- drivers/freetype/src/cff/cf2font.c | 211 +- drivers/freetype/src/cff/cf2font.h | 16 +- drivers/freetype/src/cff/cf2ft.c | 129 +- drivers/freetype/src/cff/cf2ft.h | 12 +- drivers/freetype/src/cff/cf2glue.h | 6 +- drivers/freetype/src/cff/cf2hints.c | 228 +- drivers/freetype/src/cff/cf2hints.h | 12 +- drivers/freetype/src/cff/cf2intrp.c | 467 +- drivers/freetype/src/cff/cf2intrp.h | 6 +- drivers/freetype/src/cff/cf2read.h | 6 +- drivers/freetype/src/cff/cf2stack.c | 84 +- drivers/freetype/src/cff/cf2stack.h | 11 +- drivers/freetype/src/cff/cf2types.h | 6 +- drivers/freetype/src/cff/cff.c | 2 +- drivers/freetype/src/cff/cffcmap.c | 12 +- drivers/freetype/src/cff/cffcmap.h | 8 +- drivers/freetype/src/cff/cffdrivr.c | 245 +- drivers/freetype/src/cff/cffdrivr.h | 8 +- drivers/freetype/src/cff/cfferrs.h | 10 +- drivers/freetype/src/cff/cffgload.c | 317 +- drivers/freetype/src/cff/cffgload.h | 18 +- drivers/freetype/src/cff/cffload.c | 87 +- drivers/freetype/src/cff/cffload.h | 8 +- drivers/freetype/src/cff/cffobjs.c | 147 +- drivers/freetype/src/cff/cffobjs.h | 10 +- drivers/freetype/src/cff/cffparse.c | 302 +- drivers/freetype/src/cff/cffparse.h | 31 +- drivers/freetype/src/cff/cffpic.c | 2 +- drivers/freetype/src/cff/cffpic.h | 16 +- drivers/freetype/src/cff/cfftoken.h | 12 +- drivers/freetype/src/cff/cfftypes.h | 15 +- drivers/freetype/src/cff/module.mk | 2 +- drivers/freetype/src/cff/rules.mk | 7 +- drivers/freetype/src/cid/Jamfile | 9 +- drivers/freetype/src/cid/ciderrs.h | 10 +- drivers/freetype/src/cid/cidgload.c | 88 +- drivers/freetype/src/cid/cidgload.h | 8 +- drivers/freetype/src/cid/cidload.c | 226 +- drivers/freetype/src/cid/cidload.h | 10 +- drivers/freetype/src/cid/cidobjs.c | 25 +- drivers/freetype/src/cid/cidobjs.h | 8 +- drivers/freetype/src/cid/cidparse.c | 106 +- drivers/freetype/src/cid/cidparse.h | 32 +- drivers/freetype/src/cid/cidriver.c | 68 +- drivers/freetype/src/cid/cidriver.h | 8 +- drivers/freetype/src/cid/cidtoken.h | 2 +- drivers/freetype/src/cid/module.mk | 2 +- drivers/freetype/src/cid/rules.mk | 7 +- drivers/freetype/src/cid/type1cid.c | 2 +- drivers/freetype/src/gxvalid/Jamfile | 29 +- drivers/freetype/src/gxvalid/README | 2 +- drivers/freetype/src/gxvalid/gxvalid.c | 3 +- drivers/freetype/src/gxvalid/gxvalid.h | 9 +- drivers/freetype/src/gxvalid/gxvbsln.c | 59 +- drivers/freetype/src/gxvalid/gxvcommn.c | 308 +- drivers/freetype/src/gxvalid/gxvcommn.h | 96 +- drivers/freetype/src/gxvalid/gxverror.h | 12 +- drivers/freetype/src/gxvalid/gxvfeat.c | 40 +- drivers/freetype/src/gxvalid/gxvfeat.h | 9 +- drivers/freetype/src/gxvalid/gxvfgen.c | 3 +- drivers/freetype/src/gxvalid/gxvjust.c | 206 +- drivers/freetype/src/gxvalid/gxvkern.c | 162 +- drivers/freetype/src/gxvalid/gxvlcar.c | 45 +- drivers/freetype/src/gxvalid/gxvmod.c | 8 +- drivers/freetype/src/gxvalid/gxvmod.h | 9 +- drivers/freetype/src/gxvalid/gxvmort.c | 49 +- drivers/freetype/src/gxvalid/gxvmort.h | 23 +- drivers/freetype/src/gxvalid/gxvmort0.c | 19 +- drivers/freetype/src/gxvalid/gxvmort1.c | 61 +- drivers/freetype/src/gxvalid/gxvmort2.c | 49 +- drivers/freetype/src/gxvalid/gxvmort4.c | 21 +- drivers/freetype/src/gxvalid/gxvmort5.c | 33 +- drivers/freetype/src/gxvalid/gxvmorx.c | 32 +- drivers/freetype/src/gxvalid/gxvmorx.h | 19 +- drivers/freetype/src/gxvalid/gxvmorx0.c | 19 +- drivers/freetype/src/gxvalid/gxvmorx1.c | 57 +- drivers/freetype/src/gxvalid/gxvmorx2.c | 54 +- drivers/freetype/src/gxvalid/gxvmorx4.c | 7 +- drivers/freetype/src/gxvalid/gxvmorx5.c | 37 +- drivers/freetype/src/gxvalid/gxvopbd.c | 35 +- drivers/freetype/src/gxvalid/gxvprop.c | 43 +- drivers/freetype/src/gxvalid/gxvtrak.c | 58 +- drivers/freetype/src/gxvalid/module.mk | 6 +- drivers/freetype/src/gxvalid/rules.mk | 8 +- drivers/freetype/src/otvalid/Jamfile | 12 +- drivers/freetype/src/otvalid/module.mk | 2 +- drivers/freetype/src/otvalid/otvalid.c | 2 +- drivers/freetype/src/otvalid/otvalid.h | 8 +- drivers/freetype/src/otvalid/otvbase.c | 52 +- drivers/freetype/src/otvalid/otvcommn.c | 172 +- drivers/freetype/src/otvalid/otvcommn.h | 164 +- drivers/freetype/src/otvalid/otverror.h | 10 +- drivers/freetype/src/otvalid/otvgdef.c | 38 +- drivers/freetype/src/otvalid/otvgpos.c | 192 +- drivers/freetype/src/otvalid/otvgpos.h | 8 +- drivers/freetype/src/otvalid/otvgsub.c | 116 +- drivers/freetype/src/otvalid/otvjstf.c | 85 +- drivers/freetype/src/otvalid/otvmath.c | 76 +- drivers/freetype/src/otvalid/otvmod.c | 4 +- drivers/freetype/src/otvalid/otvmod.h | 8 +- drivers/freetype/src/otvalid/rules.mk | 7 +- drivers/freetype/src/pcf/Jamfile | 7 +- drivers/freetype/src/pcf/pcf.h | 15 +- drivers/freetype/src/pcf/pcfdrivr.c | 155 +- drivers/freetype/src/pcf/pcfdrivr.h | 6 +- drivers/freetype/src/pcf/pcferror.h | 8 +- drivers/freetype/src/pcf/pcfread.c | 252 +- drivers/freetype/src/pcf/pcfread.h | 6 +- drivers/freetype/src/pcf/pcfutil.c | 12 +- drivers/freetype/src/pcf/pcfutil.h | 6 +- drivers/freetype/src/pcf/rules.mk | 5 +- drivers/freetype/src/pfr/Jamfile | 10 +- drivers/freetype/src/pfr/module.mk | 2 +- drivers/freetype/src/pfr/pfr.c | 2 +- drivers/freetype/src/pfr/pfrcmap.c | 19 +- drivers/freetype/src/pfr/pfrcmap.h | 8 +- drivers/freetype/src/pfr/pfrdrivr.c | 63 +- drivers/freetype/src/pfr/pfrdrivr.h | 8 +- drivers/freetype/src/pfr/pfrerror.h | 10 +- drivers/freetype/src/pfr/pfrgload.c | 69 +- drivers/freetype/src/pfr/pfrgload.h | 8 +- drivers/freetype/src/pfr/pfrload.c | 206 +- drivers/freetype/src/pfr/pfrload.h | 25 +- drivers/freetype/src/pfr/pfrobjs.c | 67 +- drivers/freetype/src/pfr/pfrobjs.h | 8 +- drivers/freetype/src/pfr/pfrsbit.c | 268 +- drivers/freetype/src/pfr/pfrsbit.h | 8 +- drivers/freetype/src/pfr/pfrtypes.h | 126 +- drivers/freetype/src/pfr/rules.mk | 7 +- drivers/freetype/src/psaux/Jamfile | 10 +- drivers/freetype/src/psaux/afmparse.c | 45 +- drivers/freetype/src/psaux/afmparse.h | 11 +- drivers/freetype/src/psaux/module.mk | 2 +- drivers/freetype/src/psaux/psaux.c | 2 +- drivers/freetype/src/psaux/psauxerr.h | 10 +- drivers/freetype/src/psaux/psauxmod.c | 2 +- drivers/freetype/src/psaux/psauxmod.h | 8 +- drivers/freetype/src/psaux/psconv.c | 15 +- drivers/freetype/src/psaux/psconv.h | 8 +- drivers/freetype/src/psaux/psobjs.c | 67 +- drivers/freetype/src/psaux/psobjs.h | 18 +- drivers/freetype/src/psaux/rules.mk | 7 +- drivers/freetype/src/psaux/t1cmap.c | 32 +- drivers/freetype/src/psaux/t1cmap.h | 8 +- drivers/freetype/src/psaux/t1decode.c | 60 +- drivers/freetype/src/psaux/t1decode.h | 8 +- drivers/freetype/src/pshinter/Jamfile | 9 +- drivers/freetype/src/pshinter/module.mk | 2 +- drivers/freetype/src/pshinter/pshalgo.c | 150 +- drivers/freetype/src/pshinter/pshalgo.h | 55 +- drivers/freetype/src/pshinter/pshglob.c | 20 +- drivers/freetype/src/pshinter/pshglob.h | 10 +- drivers/freetype/src/pshinter/pshinter.c | 2 +- drivers/freetype/src/pshinter/pshmod.c | 2 +- drivers/freetype/src/pshinter/pshmod.h | 8 +- drivers/freetype/src/pshinter/pshnterr.h | 10 +- drivers/freetype/src/pshinter/pshpic.c | 2 +- drivers/freetype/src/pshinter/pshpic.h | 16 +- drivers/freetype/src/pshinter/pshrec.c | 193 +- drivers/freetype/src/pshinter/pshrec.h | 18 +- drivers/freetype/src/pshinter/rules.mk | 7 +- drivers/freetype/src/psnames/Jamfile | 6 +- drivers/freetype/src/psnames/module.mk | 2 +- drivers/freetype/src/psnames/psmodule.c | 38 +- drivers/freetype/src/psnames/psmodule.h | 8 +- drivers/freetype/src/psnames/psnamerr.h | 10 +- drivers/freetype/src/psnames/psnames.c | 2 +- drivers/freetype/src/psnames/pspic.c | 2 +- drivers/freetype/src/psnames/pspic.h | 18 +- drivers/freetype/src/psnames/pstables.h | 2 +- drivers/freetype/src/psnames/rules.mk | 9 +- drivers/freetype/src/raster/Jamfile | 7 +- drivers/freetype/src/raster/ftmisc.h | 12 +- drivers/freetype/src/raster/ftraster.c | 812 +-- drivers/freetype/src/raster/ftraster.h | 10 +- drivers/freetype/src/raster/ftrend1.c | 114 +- drivers/freetype/src/raster/ftrend1.h | 14 +- drivers/freetype/src/raster/module.mk | 2 +- drivers/freetype/src/raster/raster.c | 2 +- drivers/freetype/src/raster/rasterrs.h | 10 +- drivers/freetype/src/raster/rastpic.c | 22 +- drivers/freetype/src/raster/rastpic.h | 18 +- drivers/freetype/src/raster/rules.mk | 7 +- drivers/freetype/src/sfnt/Jamfile | 15 +- drivers/freetype/src/sfnt/module.mk | 2 +- drivers/freetype/src/sfnt/pngshim.c | 92 +- drivers/freetype/src/sfnt/pngshim.h | 14 +- drivers/freetype/src/sfnt/rules.mk | 7 +- drivers/freetype/src/sfnt/sfdriver.c | 58 +- drivers/freetype/src/sfnt/sfdriver.h | 8 +- drivers/freetype/src/sfnt/sferrors.h | 11 +- drivers/freetype/src/sfnt/sfnt.c | 2 +- drivers/freetype/src/sfnt/sfntpic.c | 2 +- drivers/freetype/src/sfnt/sfntpic.h | 20 +- drivers/freetype/src/sfnt/sfobjs.c | 594 +- drivers/freetype/src/sfnt/sfobjs.h | 17 +- drivers/freetype/src/sfnt/ttbdf.c | 2 +- drivers/freetype/src/sfnt/ttbdf.h | 8 +- drivers/freetype/src/sfnt/ttcmap.c | 502 +- drivers/freetype/src/sfnt/ttcmap.h | 8 +- drivers/freetype/src/sfnt/ttcmapc.h | 2 +- drivers/freetype/src/sfnt/ttkern.c | 12 +- drivers/freetype/src/sfnt/ttkern.h | 8 +- drivers/freetype/src/sfnt/ttload.c | 186 +- drivers/freetype/src/sfnt/ttload.h | 8 +- drivers/freetype/src/sfnt/ttmtx.c | 25 +- drivers/freetype/src/sfnt/ttmtx.h | 10 +- drivers/freetype/src/sfnt/ttpost.c | 46 +- drivers/freetype/src/sfnt/ttpost.h | 10 +- drivers/freetype/src/sfnt/ttsbit.c | 818 ++- drivers/freetype/src/sfnt/ttsbit.h | 12 +- drivers/freetype/src/smooth/Jamfile | 7 +- drivers/freetype/src/smooth/ftgrays.c | 1190 +-- drivers/freetype/src/smooth/ftgrays.h | 10 +- drivers/freetype/src/smooth/ftsmerrs.h | 10 +- drivers/freetype/src/smooth/ftsmooth.c | 153 +- drivers/freetype/src/smooth/ftsmooth.h | 8 +- drivers/freetype/src/smooth/ftspic.c | 2 +- drivers/freetype/src/smooth/ftspic.h | 13 +- drivers/freetype/src/smooth/module.mk | 2 +- drivers/freetype/src/smooth/rules.mk | 8 +- drivers/freetype/src/smooth/smooth.c | 2 +- drivers/freetype/src/truetype/Jamfile | 12 +- drivers/freetype/src/truetype/module.mk | 2 +- drivers/freetype/src/truetype/rules.mk | 7 +- drivers/freetype/src/truetype/truetype.c | 2 +- drivers/freetype/src/truetype/ttdriver.c | 96 +- drivers/freetype/src/truetype/ttdriver.h | 8 +- drivers/freetype/src/truetype/tterrors.h | 11 +- drivers/freetype/src/truetype/ttgload.c | 1065 ++- drivers/freetype/src/truetype/ttgload.h | 9 +- drivers/freetype/src/truetype/ttgxvar.c | 1109 ++- drivers/freetype/src/truetype/ttgxvar.h | 18 +- drivers/freetype/src/truetype/ttinterp.c | 7602 +++++++++----------- drivers/freetype/src/truetype/ttinterp.h | 233 +- drivers/freetype/src/truetype/ttobjs.c | 360 +- drivers/freetype/src/truetype/ttobjs.h | 43 +- drivers/freetype/src/truetype/ttpic.c | 2 +- drivers/freetype/src/truetype/ttpic.h | 18 +- drivers/freetype/src/truetype/ttpload.c | 52 +- drivers/freetype/src/truetype/ttpload.h | 8 +- drivers/freetype/src/truetype/ttsubpix.c | 98 +- drivers/freetype/src/truetype/ttsubpix.h | 53 +- drivers/freetype/src/type1/Jamfile | 10 +- drivers/freetype/src/type1/module.mk | 2 +- drivers/freetype/src/type1/rules.mk | 7 +- drivers/freetype/src/type1/t1afm.c | 26 +- drivers/freetype/src/type1/t1afm.h | 8 +- drivers/freetype/src/type1/t1driver.c | 137 +- drivers/freetype/src/type1/t1driver.h | 8 +- drivers/freetype/src/type1/t1errors.h | 10 +- drivers/freetype/src/type1/t1gload.c | 45 +- drivers/freetype/src/type1/t1gload.h | 8 +- drivers/freetype/src/type1/t1load.c | 404 +- drivers/freetype/src/type1/t1load.h | 9 +- drivers/freetype/src/type1/t1objs.c | 28 +- drivers/freetype/src/type1/t1objs.h | 8 +- drivers/freetype/src/type1/t1parse.c | 72 +- drivers/freetype/src/type1/t1parse.h | 14 +- drivers/freetype/src/type1/t1tokens.h | 2 +- drivers/freetype/src/type1/type1.c | 2 +- drivers/freetype/src/type42/Jamfile | 7 +- drivers/freetype/src/type42/module.mk | 2 +- drivers/freetype/src/type42/rules.mk | 7 +- drivers/freetype/src/type42/t42drivr.c | 55 +- drivers/freetype/src/type42/t42drivr.h | 9 +- drivers/freetype/src/type42/t42error.h | 10 +- drivers/freetype/src/type42/t42objs.c | 51 +- drivers/freetype/src/type42/t42objs.h | 10 +- drivers/freetype/src/type42/t42parse.c | 246 +- drivers/freetype/src/type42/t42parse.h | 13 +- drivers/freetype/src/type42/t42types.h | 11 +- drivers/freetype/src/type42/type42.c | 2 +- drivers/freetype/src/winfonts/Jamfile | 2 +- drivers/freetype/src/winfonts/fnterrs.h | 10 +- drivers/freetype/src/winfonts/module.mk | 2 +- drivers/freetype/src/winfonts/rules.mk | 7 +- drivers/freetype/src/winfonts/winfnt.c | 166 +- drivers/freetype/src/winfonts/winfnt.h | 8 +- 491 files changed, 29030 insertions(+), 17567 deletions(-) create mode 100644 drivers/freetype/include/freetype/ftfntfmt.h delete mode 100644 drivers/freetype/include/freetype/ftxf86.h create mode 100644 drivers/freetype/include/freetype/internal/fthash.h create mode 100644 drivers/freetype/include/freetype/internal/services/svfntfmt.h delete mode 100644 drivers/freetype/include/freetype/internal/services/svxf86nm.h create mode 100644 drivers/freetype/src/autofit/afblue.c create mode 100644 drivers/freetype/src/autofit/afblue.cin create mode 100644 drivers/freetype/src/autofit/afblue.dat create mode 100644 drivers/freetype/src/autofit/afblue.h create mode 100644 drivers/freetype/src/autofit/afblue.hin create mode 100644 drivers/freetype/src/autofit/afcover.h create mode 100644 drivers/freetype/src/autofit/afranges.c create mode 100644 drivers/freetype/src/autofit/afranges.h create mode 100644 drivers/freetype/src/autofit/afscript.h create mode 100644 drivers/freetype/src/autofit/afshaper.c create mode 100644 drivers/freetype/src/autofit/afshaper.h create mode 100644 drivers/freetype/src/autofit/afstyles.h create mode 100644 drivers/freetype/src/autofit/afwrtsys.h create mode 100644 drivers/freetype/src/base/ftfntfmt.c create mode 100644 drivers/freetype/src/base/fthash.c delete mode 100644 drivers/freetype/src/base/ftxf86.c (limited to 'drivers') diff --git a/drivers/freetype/SCsub b/drivers/freetype/SCsub index 0ea29d25ab..0c7ab91ba2 100644 --- a/drivers/freetype/SCsub +++ b/drivers/freetype/SCsub @@ -9,6 +9,7 @@ ft_sources=[\ "src/base/ftbitmap.c",\ "src/base/ftcid.c",\ "src/base/ftdebug.c",\ +"src/base/ftfntfmt.c",\ "src/base/ftfstype.c",\ "src/base/ftgasp.c",\ "src/base/ftglyph.c",\ @@ -25,7 +26,6 @@ ft_sources=[\ "src/base/ftsystem.c",\ "src/base/fttype1.c",\ "src/base/ftwinfnt.c",\ -"src/base/ftxf86.c",\ "src/bdf/bdf.c",\ "src/cache/ftcache.c",\ "src/cff/cff.c",\ diff --git a/drivers/freetype/include/freetype/config/ftconfig.h b/drivers/freetype/include/freetype/config/ftconfig.h index 5dce30ef3e..157a704fa8 100644 --- a/drivers/freetype/include/freetype/config/ftconfig.h +++ b/drivers/freetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2004, 2006-2008, 2010-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,16 +27,16 @@ /* Note however that if some specific modifications are needed, we */ /* advise you to place a modified copy in your build directory. */ /* */ - /* The build directory is usually `freetype/builds/<system>', and */ - /* contains system-specific files that are always included first when */ - /* building the library. */ + /* The build directory is usually `builds/<system>', and contains */ + /* system-specific files that are always included first when building */ + /* the library. */ /* */ - /* This ANSI version should stay in `include/freetype/config'. */ + /* This ANSI version should stay in `include/config/'. */ /* */ /*************************************************************************/ -#ifndef __FTCONFIG_H__ -#define __FTCONFIG_H__ +#ifndef FTCONFIG_H_ +#define FTCONFIG_H_ #include <ft2build.h> #include FT_CONFIG_OPTIONS_H @@ -53,7 +53,7 @@ FT_BEGIN_HEADER /* These macros can be toggled to suit a specific system. The current */ /* ones are defaults used to compile FreeType in an ANSI C environment */ /* (16bit compilers are also supported). Copy this file to your own */ - /* `freetype/builds/<system>' directory, and edit it to port the engine. */ + /* `builds/<system>' directory, and edit it to port the engine. */ /* */ /*************************************************************************/ @@ -266,6 +266,21 @@ FT_BEGIN_HEADER #define FT_INT64 long #define FT_UINT64 unsigned long + /*************************************************************************/ + /* */ + /* A 64-bit data type may create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ + /* types if __STDC__ is defined. You can however ignore this rule */ + /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L + +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + #elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ @@ -300,27 +315,9 @@ FT_BEGIN_HEADER #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ - - - /*************************************************************************/ - /* */ - /* A 64-bit data type will create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ - /* is defined. You can however ignore this rule by defining the */ - /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ - /* */ -#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) - -#ifdef __STDC__ - - /* undefine the 64-bit macros in strict ANSI compilation mode */ -#undef FT_LONG64 -#undef FT_INT64 - -#endif /* __STDC__ */ +#endif /* __STDC_VERSION__ >= 199901L */ -#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ #ifdef FT_LONG64 typedef FT_INT64 FT_Int64; @@ -328,150 +325,25 @@ FT_BEGIN_HEADER #endif + /*************************************************************************/ + /* */ + /* miscellaneous */ + /* */ + /*************************************************************************/ + + #define FT_BEGIN_STMNT do { #define FT_END_STMNT } while ( 0 ) #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT -#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER - /* Provide assembler fragments for performance-critical functions. */ - /* These must be defined `static __inline__' with GCC. */ - -#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm - { - smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ - mov a, t, asr #31 /* a = (hi >> 31) */ - add a, a, #0x8000 /* a += 0x8000 */ - adds t2, t2, a /* t2 += a */ - adc t, t, #0 /* t += carry */ - mov a, t2, lsr #16 /* a = t2 >> 16 */ - orr a, a, t, lsl #16 /* a |= t << 16 */ - } - return a; - } - -#endif /* __CC_ARM || __ARMCC__ */ - - -#ifdef __GNUC__ - -#if defined( __arm__ ) && !defined( __thumb__ ) && \ - !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm__ __volatile__ ( - "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ - "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ - "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ - "adds %1, %1, %0\n\t" /* %1 += %0 */ - "adc %2, %2, #0\n\t" /* %2 += carry */ - "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ - "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ - : "=r"(a), "=&r"(t2), "=&r"(t) - : "r"(a), "r"(b) - : "cc" ); - return a; - } - -#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */ - -#if defined( __i386__ ) -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 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" - : "=a"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx", "cc" ); - return result; - } - -#endif /* i386 */ - -#endif /* __GNUC__ */ - - -#ifdef _MSC_VER /* Visual C++ */ - -#ifdef _M_IX86 - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - __asm - { - mov eax, a - mov edx, b - imul edx - mov ecx, edx - sar ecx, 31 - add ecx, 8000h - add eax, ecx - adc edx, 0 - shr eax, 16 - shl edx, 16 - add eax, edx - mov result, eax - } - return result; - } - -#endif /* _M_IX86 */ - -#endif /* _MSC_VER */ - -#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ - - -#ifdef FT_CONFIG_OPTION_INLINE_MULFIX -#ifdef FT_MULFIX_ASSEMBLER -#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER -#endif + /* typeof condition taken from gnulib's `intprops.h' header file */ +#if ( __GNUC__ >= 2 || \ + defined( __IBM__TYPEOF__ ) || \ + ( __SUNPRO_C >= 0x5110 && !__STDC__ ) ) +#define FT_TYPEOF( type ) (__typeof__ (type)) +#else +#define FT_TYPEOF( type ) /* empty */ #endif @@ -492,6 +364,9 @@ FT_BEGIN_HEADER #endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ +#define FT_LOCAL_ARRAY( x ) extern const x +#define FT_LOCAL_ARRAY_DEF( x ) const x + #ifndef FT_BASE @@ -592,7 +467,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCONFIG_H__ */ +#endif /* FTCONFIG_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/config/ftheader.h b/drivers/freetype/include/freetype/config/ftheader.h index 8371a31611..68e14834d4 100644 --- a/drivers/freetype/include/freetype/config/ftheader.h +++ b/drivers/freetype/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2008, 2010, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __FT_HEADER_H__ -#define __FT_HEADER_H__ +#ifndef FTHEADER_H_ +#define FTHEADER_H_ /*@***********************************************************************/ @@ -710,14 +710,16 @@ /************************************************************************* * * @macro: - * FT_XFREE86_H + * FT_FONT_FORMATS_H * * @description: * A macro used in #include statements to name the file containing the - * FreeType~2 API which provides functions specific to the XFree86 and - * X.Org X11 servers. + * FreeType~2 API which provides functions specific to font formats. */ -#define FT_XFREE86_H <freetype/ftxf86.h> +#define FT_FONT_FORMATS_H <freetype/ftfntfmt.h> + + /* deprecated */ +#define FT_XFREE86_H FT_FONT_FORMATS_H /************************************************************************* @@ -751,8 +753,7 @@ * FT_UNPATENTED_HINTING_H * * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs color filtering for subpixel rendering. + * Deprecated. */ #define FT_UNPATENTED_HINTING_H <freetype/ttunpat.h> @@ -764,7 +765,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs color filtering for subpixel rendering. + * FreeType~2 API which performs incremental glyph loading. */ #define FT_INCREMENTAL_H <freetype/ftincrem.h> @@ -817,7 +818,7 @@ /* - * Include internal headers definitions from <freetype/internal/...> + * Include internal headers definitions from <internal/...> * only when building the library. */ #ifdef FT2_BUILD_LIBRARY @@ -826,7 +827,7 @@ #endif /* FT2_BUILD_LIBRARY */ -#endif /* __FT2_BUILD_H__ */ +#endif /* FTHEADER_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/config/ftoption.h b/drivers/freetype/include/freetype/config/ftoption.h index b9d840b41f..afd32f1cda 100644 --- a/drivers/freetype/include/freetype/config/ftoption.h +++ b/drivers/freetype/include/freetype/config/ftoption.h @@ -4,7 +4,7 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTOPTION_H__ -#define __FTOPTION_H__ +#ifndef FTOPTION_H_ +#define FTOPTION_H_ #include <ft2build.h> @@ -61,7 +61,7 @@ FT_BEGIN_HEADER /* that are statically linked to the library at compile time. By */ /* default, this file is <freetype/config/ftmodule.h>. */ /* */ - /* We highly recommend using the third method whenever possible. */ + /* We highly recommend using the third method whenever possible. */ /* */ /*************************************************************************/ @@ -216,7 +216,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* PNG bitmap support. */ + /* PNG bitmap support. */ /* */ /* FreeType now handles loading color bitmap glyphs in the PNG format. */ /* This requires help from the external libpng library. Uncompressed */ @@ -228,6 +228,19 @@ FT_BEGIN_HEADER /* #define FT_CONFIG_OPTION_USE_PNG */ + /*************************************************************************/ + /* */ + /* HarfBuzz support. */ + /* */ + /* FreeType uses the HarfBuzz library to improve auto-hinting of */ + /* OpenType fonts. If available, many glyphs not directly addressable */ + /* by a font's character map will be hinted also. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ + + /*************************************************************************/ /* */ /* DLL export compilation */ @@ -365,10 +378,6 @@ FT_BEGIN_HEADER /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ /* */ - /* This must be greater than 4KByte if you use FreeType to rasterize */ - /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ - /* allocation of the render pool. */ - /* */ #define FT_RENDER_POOL_SIZE 16384L @@ -422,6 +431,8 @@ FT_BEGIN_HEADER /* af_glyph_hints_dump_points */ /* af_glyph_hints_dump_segments */ /* af_glyph_hints_dump_edges */ + /* af_glyph_hints_get_num_segments */ + /* af_glyph_hints_get_segment_offset */ /* */ /* As an argument, they use another global variable: */ /* */ @@ -528,7 +539,7 @@ FT_BEGIN_HEADER /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftsnames.h'. */ + /* `ftsnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES @@ -575,86 +586,53 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ - /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ - /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ + /* subpixel hinting support into the TrueType driver. This modifies the */ + /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ + /* requested. */ /* */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /*************************************************************************/ - /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ - /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ - /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ - /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ + /* In particular, it modifies the bytecode interpreter to interpret (or */ + /* not) instructions in a certain way so that all TrueType fonts look */ + /* like they do in a Windows ClearType (DirectWrite) environment. See */ + /* [1] for a technical overview on what this means. See `ttinterp.h' */ + /* for more details on the LEAN option. */ /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ + /* There are three options. */ /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ + /* 1. This option is associated with the `Infinality' moniker. */ + /* Contributed by an individual nicknamed Infinality with the goal of */ + /* making TrueType fonts render better than on Windows. A high */ + /* amount of configurability and flexibility, down to rules for */ + /* single glyphs in fonts, but also very slow. Its experimental and */ + /* slow nature and the original developer losing interest meant that */ + /* this option was never enabled in default builds. */ /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ + /* 2. The new default mode for the TrueType driver. The Infinality code */ + /* base was stripped to the bare minimum and all configurability */ + /* removed in the name of speed and simplicity. The configurability */ + /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ + /* Courier. Legacy fonts are fonts that modify vertical stems to */ + /* achieve clean black-and-white bitmaps. The new mode focuses on */ + /* applying a minimal set of rules to all fonts indiscriminately so */ + /* that modern and web fonts render well while legacy fonts render */ + /* okay. */ /* */ + /* 3. Compile both. */ /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ - /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - - /*************************************************************************/ + /* By undefining these, you get rendering behavior like on Windows */ + /* without ClearType, i.e., Windows XP without ClearType enabled and */ + /* Win9x (interpreter version v35). Or not, depending on how much */ + /* hinting blood and testing tears the font designer put into a given */ + /* font. If you define one or both subpixel hinting options, you can */ + /* switch between between v35 and the ones you define. */ /* */ - /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ - /* bytecode interpreter with a huge switch statement, rather than a call */ - /* table. This results in smaller and faster code for a number of */ - /* architectures. */ + /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ + /* defined. */ /* */ - /* Note however that on some compiler/processor combinations, undefining */ - /* this macro will generate faster, though larger, code. */ + /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ /* */ -#define TT_CONFIG_OPTION_INTERPRETER_SWITCH +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ /*************************************************************************/ @@ -671,7 +649,7 @@ FT_BEGIN_HEADER /* fonts will not have them. */ /* */ /* http://www.microsoft.com/typography/otspec/glyf.htm */ - /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ /* */ #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED @@ -694,6 +672,24 @@ FT_BEGIN_HEADER #define TT_CONFIG_OPTION_BDF + /*************************************************************************/ + /* */ + /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ + /* number of bytecode instructions executed for a single run of the */ + /* bytecode interpreter, needed to prevent infinite loops. You don't */ + /* want to change this except for very special situations (e.g., making */ + /* a library fuzzer spend less time to handle broken fonts). */ + /* */ + /* It is not expected that this value is ever modified by a configuring */ + /* script; instead, it gets surrounded with #ifndef ... #endif so that */ + /* the value can be set as a preprocessor option on the compiler's */ + /* command line. */ + /* */ +#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES +#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L +#endif + + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -758,6 +754,30 @@ FT_BEGIN_HEADER /*************************************************************************/ + /*************************************************************************/ + /* */ + /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ + /* possible to set up the default values of the four control points that */ + /* define the stem darkening behaviour of the (new) CFF engine. For */ + /* more details please read the documentation of the */ + /* `darkening-parameters' property of the cff driver module (file */ + /* `ftcffdrv.h'), which allows the control at run-time. */ + /* */ + /* Do *not* undefine these macros! */ + /* */ +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 + + /*************************************************************************/ /* */ /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ @@ -765,7 +785,7 @@ FT_BEGIN_HEADER /* switch between the two engines using the `hinting-engine' property of */ /* the cff driver module. */ /* */ -/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ // -GODOT- +/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ /*************************************************************************/ @@ -798,36 +818,72 @@ FT_BEGIN_HEADER /* grid. To find out the optimal scaling and shifting value, various */ /* parameter combinations are tried and scored. */ /* */ - /* This experimental option is only active if the render mode is */ - /* FT_RENDER_MODE_LIGHT. */ + /* This experimental option is active only if the rendering mode is */ + /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ + /* `warping' property of the auto-hinter (see file `ftautoh.h' for more */ + /* information; by default it is switched off). */ /* */ -/* #define AF_CONFIG_OPTION_USE_WARPER */ +#define AF_CONFIG_OPTION_USE_WARPER /* */ /* - * This macro is obsolete. Support has been removed in FreeType - * version 2.5. + * This macro is obsolete. Support has been removed in FreeType + * version 2.5. */ /* #define FT_CONFIG_OPTION_OLD_INTERNALS */ /* - * This macro is defined if either unpatented or native TrueType - * hinting is requested by the definitions above. + * This macro is defined if native TrueType hinting is requested by the + * definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 +#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#endif + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 +#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#endif +#endif + + + /* + * Check CFF darkening parameters. The checks are the same as in function + * `cff_property_set' in file `cffdrivr.c'. + */ +#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500 +#error "Invalid CFF darkening parameters!" #endif FT_END_HEADER -#endif /* __FTOPTION_H__ */ +#endif /* FTOPTION_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/config/ftstdlib.h b/drivers/freetype/include/freetype/config/ftstdlib.h index b940efc427..562e255810 100644 --- a/drivers/freetype/include/freetype/config/ftstdlib.h +++ b/drivers/freetype/include/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ /* ANSI-specific library and header configuration file (specification */ /* only). */ /* */ -/* Copyright 2002-2007, 2009, 2011-2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,14 +23,13 @@ /* FreeType normally requires. It also defines macros to rename the */ /* standard functions within the FreeType source code. */ /* */ - /* Load a file which defines __FTSTDLIB_H__ before this one to override */ - /* it. */ + /* Load a file which defines FTSTDLIB_H_ before this one to override it. */ /* */ /*************************************************************************/ -#ifndef __FTSTDLIB_H__ -#define __FTSTDLIB_H__ +#ifndef FTSTDLIB_H_ +#define FTSTDLIB_H_ #include <stddef.h> @@ -64,6 +63,8 @@ #define FT_INT_MAX INT_MAX #define FT_INT_MIN INT_MIN #define FT_UINT_MAX UINT_MAX +#define FT_LONG_MIN LONG_MIN +#define FT_LONG_MAX LONG_MAX #define FT_ULONG_MAX ULONG_MAX @@ -141,8 +142,7 @@ /**********************************************************************/ -#define ft_atol atol -#define ft_labs labs +#define ft_atol atol /**********************************************************************/ @@ -168,7 +168,7 @@ #include <stdarg.h> -#endif /* __FTSTDLIB_H__ */ +#endif /* FTSTDLIB_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/freetype.h b/drivers/freetype/include/freetype/freetype.h index fe46d22978..45e10c48a2 100644 --- a/drivers/freetype/include/freetype/freetype.h +++ b/drivers/freetype/include/freetype/freetype.h @@ -4,7 +4,7 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FREETYPE_H__ -#define __FREETYPE_H__ +#ifndef FREETYPE_H_ +#define FREETYPE_H_ #ifndef FT_FREETYPE_H @@ -39,6 +39,38 @@ FT_BEGIN_HEADER + /*************************************************************************/ + /* */ + /* <Section> */ + /* header_inclusion */ + /* */ + /* <Title> */ + /* FreeType's header inclusion scheme */ + /* */ + /* <Abstract> */ + /* How client applications should include FreeType header files. */ + /* */ + /* <Description> */ + /* To be as flexible as possible (and for historical reasons), */ + /* FreeType uses a very special inclusion scheme to load header */ + /* files, for example */ + /* */ + /* { */ + /* #include <ft2build.h> */ + /* */ + /* #include FT_FREETYPE_H */ + /* #include FT_OUTLINE_H */ + /* } */ + /* */ + /* A compiler and its preprocessor only needs an include path to find */ + /* the file `ft2build.h'; the exact locations and names of the other */ + /* FreeType header files are hidden by preprocessor macro names, */ + /* loaded by `ft2build.h'. The API documentation always gives the */ + /* header macro name needed for a particular function. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ /* */ /* <Section> */ @@ -81,7 +113,8 @@ FT_BEGIN_HEADER /* The FreeType~2 base font interface. */ /* */ /* <Description> */ - /* This section describes the public high-level API of FreeType~2. */ + /* This section describes the most important public high-level API */ + /* functions of FreeType~2. */ /* */ /* <Order> */ /* FT_Library */ @@ -90,6 +123,7 @@ FT_BEGIN_HEADER /* FT_GlyphSlot */ /* FT_CharMap */ /* FT_Encoding */ + /* FT_ENC_TAG */ /* */ /* FT_FaceRec */ /* */ @@ -98,14 +132,30 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_FIXED_WIDTH */ /* FT_FACE_FLAG_HORIZONTAL */ /* FT_FACE_FLAG_VERTICAL */ + /* FT_FACE_FLAG_COLOR */ /* FT_FACE_FLAG_SFNT */ + /* FT_FACE_FLAG_CID_KEYED */ + /* FT_FACE_FLAG_TRICKY */ /* FT_FACE_FLAG_KERNING */ /* FT_FACE_FLAG_MULTIPLE_MASTERS */ /* FT_FACE_FLAG_GLYPH_NAMES */ /* FT_FACE_FLAG_EXTERNAL_STREAM */ - /* FT_FACE_FLAG_FAST_GLYPHS */ /* FT_FACE_FLAG_HINTER */ /* */ + /* FT_HAS_HORIZONTAL */ + /* FT_HAS_VERTICAL */ + /* FT_HAS_KERNING */ + /* FT_HAS_FIXED_SIZES */ + /* FT_HAS_GLYPH_NAMES */ + /* FT_HAS_MULTIPLE_MASTERS */ + /* FT_HAS_COLOR */ + /* */ + /* FT_IS_SFNT */ + /* FT_IS_SCALABLE */ + /* FT_IS_FIXED_WIDTH */ + /* FT_IS_CID_KEYED */ + /* FT_IS_TRICKY */ + /* */ /* FT_STYLE_FLAG_BOLD */ /* FT_STYLE_FLAG_ITALIC */ /* */ @@ -123,6 +173,7 @@ FT_BEGIN_HEADER /* */ /* FT_New_Face */ /* FT_Done_Face */ + /* FT_Reference_Face */ /* FT_New_Memory_Face */ /* FT_Open_Face */ /* FT_Open_Args */ @@ -135,10 +186,13 @@ FT_BEGIN_HEADER /* FT_Request_Size */ /* FT_Select_Size */ /* FT_Size_Request_Type */ + /* FT_Size_RequestRec */ /* FT_Size_Request */ /* FT_Set_Transform */ /* FT_Load_Glyph */ /* FT_Get_Char_Index */ + /* FT_Get_First_Char */ + /* FT_Get_Next_Char */ /* FT_Get_Name_Index */ /* FT_Load_Char */ /* */ @@ -155,11 +209,11 @@ FT_BEGIN_HEADER /* FT_LOAD_NO_SCALE */ /* FT_LOAD_NO_HINTING */ /* FT_LOAD_NO_BITMAP */ - /* FT_LOAD_CROP_BITMAP */ + /* FT_LOAD_NO_AUTOHINT */ + /* FT_LOAD_COLOR */ /* */ /* FT_LOAD_VERTICAL_LAYOUT */ /* FT_LOAD_IGNORE_TRANSFORM */ - /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ /* FT_LOAD_FORCE_AUTOHINT */ /* FT_LOAD_NO_RECURSE */ /* FT_LOAD_PEDANTIC */ @@ -170,6 +224,8 @@ FT_BEGIN_HEADER /* FT_LOAD_TARGET_LCD */ /* FT_LOAD_TARGET_LCD_V */ /* */ + /* FT_LOAD_TARGET_MODE */ + /* */ /* FT_Render_Glyph */ /* FT_Render_Mode */ /* FT_Get_Kerning */ @@ -183,14 +239,22 @@ FT_BEGIN_HEADER /* FT_Set_Charmap */ /* FT_Get_Charmap_Index */ /* */ - /* FT_FSTYPE_INSTALLABLE_EMBEDDING */ - /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING */ - /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING */ - /* FT_FSTYPE_EDITABLE_EMBEDDING */ - /* FT_FSTYPE_NO_SUBSETTING */ - /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY */ - /* */ /* FT_Get_FSType_Flags */ + /* FT_Get_SubGlyph_Info */ + /* */ + /* FT_Face_Internal */ + /* FT_Size_Internal */ + /* FT_Slot_Internal */ + /* */ + /* FT_FACE_FLAG_XXX */ + /* FT_STYLE_FLAG_XXX */ + /* FT_OPEN_XXX */ + /* FT_LOAD_XXX */ + /* FT_LOAD_TARGET_XXX */ + /* FT_SUBGLYPH_FLAG_XXX */ + /* FT_FSTYPE_XXX */ + /* */ + /* FT_HAS_FAST_GLYPHS */ /* */ /*************************************************************************/ @@ -329,8 +393,11 @@ FT_BEGIN_HEADER /* It also embeds a memory manager (see @FT_Memory), as well as a */ /* scan-line converter object (see @FT_Raster). */ /* */ - /* In multi-threaded applications, make sure that the same FT_Library */ - /* object or any of its children doesn't get accessed in parallel. */ + /* In multi-threaded applications it is easiest to use one */ + /* `FT_Library' object per thread. In case this is too cumbersome, */ + /* a single `FT_Library' object across threads is possible also */ + /* (since FreeType version 2.5.6), as long as a mutex lock is used */ + /* around @FT_New_Face and @FT_Done_Face. */ /* */ /* <Note> */ /* Library objects are normally created by @FT_Init_FreeType, and */ @@ -341,6 +408,13 @@ FT_BEGIN_HEADER typedef struct FT_LibraryRec_ *FT_Library; + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + /*************************************************************************/ /* */ /* <Type> */ @@ -380,6 +454,13 @@ FT_BEGIN_HEADER typedef struct FT_RendererRec_* FT_Renderer; + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /*************************************************************************/ + /*************************************************************************/ /* */ /* <Type> */ @@ -398,6 +479,14 @@ FT_BEGIN_HEADER /* */ /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ /* */ + /* An `FT_Face' object can only be safely used from one thread at a */ + /* time. Similarly, creation and destruction of `FT_Face' with the */ + /* same @FT_Library object can only be done from one thread at a */ + /* time. On the other hand, functions like @FT_Load_Glyph and its */ + /* siblings are thread-safe and do not need the lock to be held as */ + /* long as the same `FT_Face' object is not used from multiple */ + /* threads at the same time. */ + /* */ /* <Also> */ /* See @FT_FaceRec for the publicly accessible fields of a given face */ /* object. */ @@ -417,7 +506,8 @@ FT_BEGIN_HEADER /* <Note> */ /* Each @FT_Face has an _active_ @FT_Size object that is used by */ /* functions like @FT_Load_Glyph to determine the scaling */ - /* transformation which is used to load and hint glyphs and metrics. */ + /* transformation that in turn is used to load and hint glyphs and */ + /* metrics. */ /* */ /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ /* @FT_Request_Size or even @FT_Select_Size to change the content */ @@ -551,16 +641,21 @@ FT_BEGIN_HEADER /* */ /* FT_ENCODING_MS_SYMBOL :: */ /* Corresponds to the Microsoft Symbol encoding, used to encode */ - /* mathematical symbols in the 32..255 character code range. For */ - /* more information, see `http://www.ceviz.net/symbol.htm'. */ + /* mathematical symbols and wingdings. For more information, see */ + /* `http://www.microsoft.com/typography/otspec/recom.htm', */ + /* `http://www.kostis.net/charsets/symbol.htm', and */ + /* `http://www.kostis.net/charsets/wingding.htm'. */ + /* */ + /* This encoding uses character codes from the PUA (Private Unicode */ + /* Area) in the range U+F020-U+F0FF. */ /* */ /* FT_ENCODING_SJIS :: */ /* Corresponds to Japanese SJIS encoding. More info at */ - /* at `http://langsupport.japanreference.com/encoding.shtml'. */ + /* `http://en.wikipedia.org/wiki/Shift_JIS'. */ /* See note on multi-byte encodings below. */ /* */ /* FT_ENCODING_GB2312 :: */ - /* Corresponds to an encoding system for Simplified Chinese as used */ + /* Corresponds to an encoding system for Simplified Chinese as */ /* used in mainland China. */ /* */ /* FT_ENCODING_BIG5 :: */ @@ -570,7 +665,7 @@ FT_BEGIN_HEADER /* FT_ENCODING_WANSUNG :: */ /* Corresponds to the Korean encoding system known as Wansung. */ /* For more information see */ - /* `http://www.microsoft.com/typography/unicode/949.txt'. */ + /* `https://msdn.microsoft.com/en-US/goglobal/cc305154'. */ /* */ /* FT_ENCODING_JOHAB :: */ /* The Korean standard character set (KS~C 5601-1992), which */ @@ -645,10 +740,10 @@ FT_BEGIN_HEADER /* FT_ENCODING_APPLE_ROMAN). */ /* */ /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ - /* @FT_Get_CMap_Language_ID to query the Mac language ID which may */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID that may */ /* be needed to be able to distinguish Apple encoding variants. See */ /* */ - /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt */ /* */ /* to get an idea how to do that. Basically, if the language ID */ /* is~0, don't use it, otherwise subtract 1 from the language ID. */ @@ -690,15 +785,8 @@ FT_BEGIN_HEADER } FT_Encoding; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_encoding_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated; use the corresponding @FT_Encoding */ - /* values instead. */ - /* */ + /* these constants are deprecated; use the corresponding `FT_Encoding' */ + /* values instead */ #define ft_encoding_none FT_ENCODING_NONE #define ft_encoding_unicode FT_ENCODING_UNICODE #define ft_encoding_symbol FT_ENCODING_MS_SYMBOL @@ -787,17 +875,36 @@ FT_BEGIN_HEADER /* font formats can have multiple faces in */ /* a font file. */ /* */ - /* face_index :: The index of the face in the font file. It */ - /* is set to~0 if there is only one face in */ + /* face_index :: This field holds two different values. */ + /* Bits 0-15 are the index of the face in the */ + /* font file (starting with value~0). They */ + /* are set to~0 if there is only one face in */ /* the font file. */ /* */ + /* Bits 16-30 are relevant to GX variation */ + /* fonts only, holding the named instance */ + /* index for the current face index (starting */ + /* with value~1; value~0 indicates font access */ + /* without GX variation data). For non-GX */ + /* fonts, bits 16-30 are ignored. If we have */ + /* the third named instance of face~4, say, */ + /* `face_index' is set to 0x00030004. */ + /* */ + /* Bit 31 is always zero (this is, */ + /* `face_index' is always a positive value). */ + /* */ /* face_flags :: A set of bit flags that give important */ /* information about the face; see */ /* @FT_FACE_FLAG_XXX for the details. */ /* */ - /* style_flags :: A set of bit flags indicating the style of */ - /* the face; see @FT_STYLE_FLAG_XXX for the */ - /* details. */ + /* style_flags :: The lower 16~bits contain a set of bit */ + /* flags indicating the style of the face; see */ + /* @FT_STYLE_FLAG_XXX for the details. Bits */ + /* 16-30 hold the number of named instances */ + /* available for the current face if we have a */ + /* GX variation (sub)font. Bit 31 is always */ + /* zero (this is, `style_flags' is always a */ + /* positive value). */ /* */ /* num_glyphs :: The number of glyphs in the face. If the */ /* face is scalable and has sbits (see */ @@ -808,7 +915,7 @@ FT_BEGIN_HEADER /* highest CID used in the font. */ /* */ /* family_name :: The face's family name. This is an ASCII */ - /* string, usually in English, which describes */ + /* string, usually in English, that describes */ /* the typeface's family (like `Times New */ /* Roman', `Bodoni', `Garamond', etc). This */ /* is a least common denominator used to list */ @@ -819,8 +926,13 @@ FT_BEGIN_HEADER /* Can be NULL (e.g., in fonts embedded in a */ /* PDF file). */ /* */ + /* In case the font doesn't provide a specific */ + /* family name entry, FreeType tries to */ + /* synthesize one, deriving it from other name */ + /* entries. */ + /* */ /* style_name :: The face's style name. This is an ASCII */ - /* string, usually in English, which describes */ + /* string, usually in English, that describes */ /* the typeface's style (like `Italic', */ /* `Bold', `Condensed', etc). Not all font */ /* formats provide a style name, so this field */ @@ -991,7 +1103,7 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_SCALABLE :: */ /* Indicates that the face contains outline glyphs. This doesn't */ /* prevent bitmap strikes, i.e., a face can have both this and */ - /* and @FT_FACE_FLAG_FIXED_SIZES set. */ + /* @FT_FACE_FLAG_FIXED_SIZES set. */ /* */ /* FT_FACE_FLAG_FIXED_SIZES :: */ /* Indicates that the face contains bitmap strikes. See also the */ @@ -1054,7 +1166,7 @@ FT_BEGIN_HEADER /* exist make FT_Load_Glyph return successfully; in all other cases */ /* you get an `FT_Err_Invalid_Argument' error. */ /* */ - /* Note that CID-keyed fonts which are in an SFNT wrapper don't */ + /* Note that CID-keyed fonts that are in an SFNT wrapper don't */ /* have this flag set since the glyphs are accessed in the normal */ /* way (using contiguous indices); the `CID-ness' isn't visible to */ /* the application. */ @@ -1062,11 +1174,11 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_TRICKY :: */ /* Set if the font is `tricky', this is, it always needs the */ /* font format's native hinting engine to get a reasonable result. */ - /* A typical example is the Chinese font `mingli.ttf' which uses */ + /* A typical example is the Chinese font `mingli.ttf' that uses */ /* TrueType bytecode instructions to move and scale all of its */ /* subglyphs. */ /* */ - /* It is not possible to autohint such fonts using */ + /* It is not possible to auto-hint such fonts using */ /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */ /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ @@ -1075,6 +1187,10 @@ FT_BEGIN_HEADER /* Currently, there are about a dozen TrueType fonts in the list of */ /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ /* */ + /* FT_FACE_FLAG_COLOR :: */ + /* Set if the font has color glyph tables. To access color glyphs */ + /* use @FT_LOAD_COLOR. */ + /* */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) #define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) @@ -1089,6 +1205,7 @@ FT_BEGIN_HEADER #define FT_FACE_FLAG_HINTER ( 1L << 11 ) #define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) #define FT_FACE_FLAG_TRICKY ( 1L << 13 ) +#define FT_FACE_FLAG_COLOR ( 1L << 14 ) /************************************************************************* @@ -1105,7 +1222,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_HORIZONTAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) /************************************************************************* @@ -1119,7 +1236,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_VERTICAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + ( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) /************************************************************************* @@ -1133,7 +1250,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_KERNING( face ) \ - ( face->face_flags & FT_FACE_FLAG_KERNING ) + ( (face)->face_flags & FT_FACE_FLAG_KERNING ) /************************************************************************* @@ -1148,7 +1265,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_SCALABLE( face ) \ - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + ( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) /************************************************************************* @@ -1167,7 +1284,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_SFNT( face ) \ - ( face->face_flags & FT_FACE_FLAG_SFNT ) + ( (face)->face_flags & FT_FACE_FLAG_SFNT ) /************************************************************************* @@ -1182,7 +1299,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_FIXED_WIDTH( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) /************************************************************************* @@ -1197,7 +1314,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_FIXED_SIZES( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) /************************************************************************* @@ -1223,7 +1340,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_GLYPH_NAMES( face ) \ - ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) /************************************************************************* @@ -1238,7 +1355,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_MULTIPLE_MASTERS( face ) \ - ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) /************************************************************************* @@ -1256,7 +1373,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_CID_KEYED( face ) \ - ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) /************************************************************************* @@ -1270,7 +1387,21 @@ FT_BEGIN_HEADER * */ #define FT_IS_TRICKY( face ) \ - ( face->face_flags & FT_FACE_FLAG_TRICKY ) + ( (face)->face_flags & FT_FACE_FLAG_TRICKY ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_COLOR( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * tables for color glyphs. + * + */ +#define FT_HAS_COLOR( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_COLOR ) /*************************************************************************/ @@ -1279,7 +1410,7 @@ FT_BEGIN_HEADER /* FT_STYLE_FLAG_XXX */ /* */ /* <Description> */ - /* A list of bit-flags used to indicate the style of a given face. */ + /* A list of bit flags used to indicate the style of a given face. */ /* These are used in the `style_flags' field of @FT_FaceRec. */ /* */ /* <Values> */ @@ -1394,9 +1525,9 @@ FT_BEGIN_HEADER /* <Fields> */ /* face :: Handle to the parent face object. */ /* */ - /* generic :: A typeless pointer, which is unused by the FreeType */ - /* library or any of its drivers. It can be used by */ - /* client applications to link their own data to each size */ + /* generic :: A typeless pointer, unused by the FreeType library or */ + /* any of its drivers. It can be used by client */ + /* applications to link their own data to each size */ /* object. */ /* */ /* metrics :: Metrics for this size object. This field is read-only. */ @@ -1464,10 +1595,10 @@ FT_BEGIN_HEADER /* listed through a direct, single-linked list */ /* using its `next' field. */ /* */ - /* generic :: A typeless pointer which is unused by the */ - /* FreeType library or any of its drivers. It */ - /* can be used by client applications to link */ - /* their own data to each glyph slot object. */ + /* generic :: A typeless pointer unused by the FreeType */ + /* library or any of its drivers. It can be */ + /* used by client applications to link their own */ + /* data to each glyph slot object. */ /* */ /* metrics :: The metrics of the last loaded glyph in the */ /* slot. The returned values depend on the last */ @@ -1494,8 +1625,8 @@ FT_BEGIN_HEADER /* */ /* advance :: This shorthand is, depending on */ /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ - /* advance width for the glyph (in 26.6 */ - /* fractional pixel format). As specified with */ + /* (hinted) advance width for the glyph, in 26.6 */ + /* fractional pixel format. As specified with */ /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ /* `horiAdvance' or the `vertAdvance' value of */ /* `metrics' field. */ @@ -1514,15 +1645,15 @@ FT_BEGIN_HEADER /* change between calls of @FT_Load_Glyph and a */ /* few other functions. */ /* */ - /* bitmap_left :: This is the bitmap's left bearing expressed */ - /* in integer pixels. Of course, this is only */ - /* valid if the format is */ - /* @FT_GLYPH_FORMAT_BITMAP. */ + /* bitmap_left :: The bitmap's left bearing expressed in */ + /* integer pixels. Only valid if the format is */ + /* @FT_GLYPH_FORMAT_BITMAP, this is, if the */ + /* glyph slot contains a bitmap. */ /* */ - /* bitmap_top :: This is the bitmap's top bearing expressed in */ - /* integer pixels. Remember that this is the */ - /* distance from the baseline to the top-most */ - /* glyph scanline, upwards y~coordinates being */ + /* bitmap_top :: The bitmap's top bearing expressed in integer */ + /* pixels. Remember that this is the distance */ + /* from the baseline to the top-most glyph */ + /* scanline, upwards y~coordinates being */ /* *positive*. */ /* */ /* outline :: The outline descriptor for the current glyph */ @@ -1536,7 +1667,6 @@ FT_BEGIN_HEADER /* This field is only valid for the composite */ /* glyph format that should normally only be */ /* loaded with the @FT_LOAD_NO_RECURSE flag. */ - /* For now this is internal to FreeType. */ /* */ /* subglyphs :: An array of subglyph descriptors for */ /* composite glyphs. There are `num_subglyphs' */ @@ -1557,11 +1687,11 @@ FT_BEGIN_HEADER /* needs to know about the image format. */ /* */ /* lsb_delta :: The difference between hinted and unhinted */ - /* left side bearing while autohinting is */ + /* left side bearing while auto-hinting is */ /* active. Zero otherwise. */ /* */ /* rsb_delta :: The difference between hinted and unhinted */ - /* right side bearing while autohinting is */ + /* right side bearing while auto-hinting is */ /* active. Zero otherwise. */ /* */ /* <Note> */ @@ -1584,7 +1714,7 @@ FT_BEGIN_HEADER /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ /* */ /* <Note> */ - /* Here a small pseudo code fragment which shows how to use */ + /* Here is a small pseudo code fragment that shows how to use */ /* `lsb_delta' and `rsb_delta': */ /* */ /* { */ @@ -1677,8 +1807,8 @@ FT_BEGIN_HEADER /* use @FT_New_Library instead, followed by a call to */ /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ /* */ - /* For multi-threading applications each thread should have its own */ - /* FT_Library object. */ + /* See the documentation of @FT_Library and @FT_Face for */ + /* multi-threading issues. */ /* */ /* If you need reference-counting (cf. @FT_Reference_Library), use */ /* @FT_New_Library and @FT_Done_Library. */ @@ -1712,7 +1842,7 @@ FT_BEGIN_HEADER /* FT_OPEN_XXX */ /* */ /* <Description> */ - /* A list of bit-field constants used within the `flags' field of the */ + /* A list of bit field constants used within the `flags' field of the */ /* @FT_Open_Args structure. */ /* */ /* <Values> */ @@ -1727,16 +1857,6 @@ FT_BEGIN_HEADER /* */ /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ /* */ - /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ - /* */ - /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ - /* */ - /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ - /* */ - /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ - /* */ - /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ - /* */ /* <Note> */ /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ /* flags are mutually exclusive. */ @@ -1747,11 +1867,14 @@ FT_BEGIN_HEADER #define FT_OPEN_DRIVER 0x8 #define FT_OPEN_PARAMS 0x10 -#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ -#define ft_open_stream FT_OPEN_STREAM /* deprecated */ -#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ -#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ -#define ft_open_params FT_OPEN_PARAMS /* deprecated */ + + /* these constants are deprecated; use the corresponding `FT_OPEN_XXX' */ + /* values instead */ +#define ft_open_memory FT_OPEN_MEMORY +#define ft_open_stream FT_OPEN_STREAM +#define ft_open_pathname FT_OPEN_PATHNAME +#define ft_open_driver FT_OPEN_DRIVER +#define ft_open_params FT_OPEN_PARAMS /*************************************************************************/ @@ -1813,25 +1936,25 @@ FT_BEGIN_HEADER /* opening a new face. */ /* */ /* <Note> */ - /* The stream type is determined by the contents of `flags' which */ + /* The stream type is determined by the contents of `flags' that */ /* are tested in the following order by @FT_Open_Face: */ /* */ - /* If the `FT_OPEN_MEMORY' bit is set, assume that this is a */ + /* If the @FT_OPEN_MEMORY bit is set, assume that this is a */ /* memory file of `memory_size' bytes, located at `memory_address'. */ - /* The data are are not copied, and the client is responsible for */ + /* The data are not copied, and the client is responsible for */ /* releasing and destroying them _after_ the corresponding call to */ /* @FT_Done_Face. */ /* */ - /* Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a */ + /* Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a */ /* custom input stream `stream' is used. */ /* */ - /* Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this */ + /* Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this */ /* is a normal file and use `pathname' to open it. */ /* */ - /* If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to */ + /* If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to */ /* open the file with the driver whose handler is in `driver'. */ /* */ - /* If the `FT_OPEN_PARAMS' bit is set, the parameters given by */ + /* If the @FT_OPEN_PARAMS bit is set, the parameters given by */ /* `num_params' and `params' is used. They are ignored otherwise. */ /* */ /* Ideally, both the `pathname' and `params' fields should be tagged */ @@ -1866,13 +1989,12 @@ FT_BEGIN_HEADER /* <Input> */ /* pathname :: A path to the font file. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: See @FT_Open_Face for a detailed description of this */ + /* parameter. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See @FT_Open_Face for more details. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -1894,7 +2016,7 @@ FT_BEGIN_HEADER /* FT_New_Memory_Face */ /* */ /* <Description> */ - /* This function calls @FT_Open_Face to open a font which has been */ + /* This function calls @FT_Open_Face to open a font that has been */ /* loaded into memory. */ /* */ /* <InOut> */ @@ -1905,13 +2027,12 @@ FT_BEGIN_HEADER /* */ /* file_size :: The size of the memory chunk used by the font data. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: See @FT_Open_Face for a detailed description of this */ + /* parameter. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See @FT_Open_Face for more details. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -1940,35 +2061,55 @@ FT_BEGIN_HEADER /* library :: A handle to the library resource. */ /* */ /* <Input> */ - /* args :: A pointer to an `FT_Open_Args' structure which must */ + /* args :: A pointer to an `FT_Open_Args' structure that must */ /* be filled by the caller. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: This field holds two different values. Bits 0-15 */ + /* are the index of the face in the font file (starting */ + /* with value~0). Set it to~0 if there is only one */ + /* face in the font file. */ + /* */ + /* Bits 16-30 are relevant to GX variation fonts only, */ + /* specifying the named instance index for the current */ + /* face index (starting with value~1; value~0 makes */ + /* FreeType ignore named instances). For non-GX fonts, */ + /* bits 16-30 are ignored. Assuming that you want to */ + /* access the third named instance in face~4, */ + /* `face_index' should be set to 0x00030004. If you */ + /* want to access face~4 without GX variation handling, */ + /* simply set `face_index' to value~4. */ + /* */ + /* FT_Open_Face and its siblings can be used to quickly */ + /* check whether the font format of a given font */ + /* resource is supported by FreeType. In general, if */ + /* the `face_index' argument is negative, the */ + /* function's return value is~0 if the font format is */ + /* recognized, or non-zero otherwise. The function */ + /* allocates a more or less empty face handle in */ + /* `*aface' (if `aface' isn't NULL); the only two */ + /* useful fields in this special case are */ + /* `face->num_faces' and `face->style_flags'. For any */ + /* negative value of `face_index', `face->num_faces' */ + /* gives the number of faces within the font file. For */ + /* the negative value `-(N+1)' (with `N' a 16-bit */ + /* value), bits 16-30 in `face->style_flags' give the */ + /* number of named instances in face `N' if we have a */ + /* GX variation font (or zero otherwise). After */ + /* examination, the returned @FT_Face structure should */ + /* be deallocated with a call to @FT_Done_Face. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See note below. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ + /* slot for the face object that can be accessed directly through */ /* `face->glyph'. */ /* */ - /* FT_Open_Face can be used to quickly check whether the font */ - /* format of a given font resource is supported by FreeType. If the */ - /* `face_index' field is negative, the function's return value is~0 */ - /* if the font format is recognized, or non-zero otherwise; */ - /* the function returns a more or less empty face handle in `*aface' */ - /* (if `aface' isn't NULL). The only useful field in this special */ - /* case is `face->num_faces' which gives the number of faces within */ - /* the font file. After examination, the returned @FT_Face structure */ - /* should be deallocated with a call to @FT_Done_Face. */ - /* */ /* Each new face object created with this function also owns a */ /* default @FT_Size object, accessible as `face->size'. */ /* */ @@ -1979,6 +2120,74 @@ FT_BEGIN_HEADER /* See the discussion of reference counters in the description of */ /* @FT_Reference_Face. */ /* */ + /* To loop over all faces, use code similar to the following snippet */ + /* (omitting the error handling). */ + /* */ + /* { */ + /* ... */ + /* FT_Face face; */ + /* FT_Long i, num_faces; */ + /* */ + /* */ + /* error = FT_Open_Face( library, args, -1, &face ); */ + /* if ( error ) { ... } */ + /* */ + /* num_faces = face->num_faces; */ + /* FT_Done_Face( face ); */ + /* */ + /* for ( i = 0; i < num_faces; i++ ) */ + /* { */ + /* ... */ + /* error = FT_Open_Face( library, args, i, &face ); */ + /* ... */ + /* FT_Done_Face( face ); */ + /* ... */ + /* } */ + /* } */ + /* */ + /* To loop over all valid values for `face_index', use something */ + /* similar to the following snippet, again without error handling. */ + /* The code accesses all faces immediately (thus only a single call */ + /* of `FT_Open_Face' within the do-loop), with and without named */ + /* instances. */ + /* */ + /* { */ + /* ... */ + /* FT_Face face; */ + /* */ + /* FT_Long num_faces = 0; */ + /* FT_Long num_instances = 0; */ + /* */ + /* FT_Long face_idx = 0; */ + /* FT_Long instance_idx = 0; */ + /* */ + /* */ + /* do */ + /* { */ + /* FT_Long id = ( instance_idx << 16 ) + face_idx; */ + /* */ + /* */ + /* error = FT_Open_Face( library, args, id, &face ); */ + /* if ( error ) { ... } */ + /* */ + /* num_faces = face->num_faces; */ + /* num_instances = face->style_flags >> 16; */ + /* */ + /* ... */ + /* */ + /* FT_Done_Face( face ); */ + /* */ + /* if ( instance_idx < num_instances ) */ + /* instance_idx++; */ + /* else */ + /* { */ + /* face_idx++; */ + /* instance_idx = 0; */ + /* } */ + /* */ + /* } while ( face_idx < num_faces ) */ + /* } */ + /* */ FT_EXPORT( FT_Error ) FT_Open_Face( FT_Library library, const FT_Open_Args* args, @@ -2023,7 +2232,7 @@ FT_BEGIN_HEADER /* face :: The target face object. */ /* */ /* <Input> */ - /* parameters :: A pointer to @FT_Open_Args which must be filled by */ + /* parameters :: A pointer to @FT_Open_Args that must be filled by */ /* the caller. */ /* */ /* <Return> */ @@ -2054,7 +2263,7 @@ FT_BEGIN_HEADER /* then only destroys a face if the counter is~1, otherwise it simply */ /* decrements the counter. */ /* */ - /* This function helps in managing life-cycles of structures which */ + /* This function helps in managing life-cycles of structures that */ /* reference @FT_Face objects. */ /* */ /* <Input> */ @@ -2130,9 +2339,9 @@ FT_BEGIN_HEADER /* used to determine both scaling values. */ /* */ /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ - /* The real dimension. The sum of the the `ascender' and (minus */ - /* of) the `descender' fields of @FT_FaceRec are used to determine */ - /* both scaling values. */ + /* The real dimension. The sum of the `ascender' and (minus of) */ + /* the `descender' fields of @FT_FaceRec are used to determine both */ + /* scaling values. */ /* */ /* FT_SIZE_REQUEST_TYPE_BBOX :: */ /* The font bounding box. The width and height of the `bbox' field */ @@ -2249,6 +2458,8 @@ FT_BEGIN_HEADER /* glyph relative to this size. For more information refer to */ /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */ /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Request_Size( FT_Face face, FT_Size_Request req ); @@ -2323,6 +2534,8 @@ FT_BEGIN_HEADER /* constrained, to this pixel size. Refer to @FT_Request_Size to */ /* understand how requested sizes relate to actual sizes. */ /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, FT_UInt pixel_width, @@ -2361,10 +2574,14 @@ FT_BEGIN_HEADER /* the details. */ /* */ /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ - /* returned for invalid CID values (this is, for CID values which */ + /* returned for invalid CID values (this is, for CID values that */ /* don't have a corresponding glyph in the font). See the discussion */ /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ /* */ + /* If you receive `FT_Err_Glyph_Too_Big', try getting the glyph */ + /* outline at EM size, then scale it manually and fill it as a */ + /* graphics operation. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, @@ -2412,7 +2629,7 @@ FT_BEGIN_HEADER * FT_LOAD_XXX * * @description: - * A list of bit-field constants used with @FT_Load_Glyph to indicate + * A list of bit field constants used with @FT_Load_Glyph to indicate * what kind of operations to perform during glyph loading. * * @values: @@ -2481,11 +2698,6 @@ FT_BEGIN_HEADER * Indicates that the auto-hinter is preferred over the font's native * hinter. See also the note below. * - * FT_LOAD_CROP_BITMAP :: - * Indicates that the font driver should crop the loaded bitmap glyph - * (i.e., remove all space around its black bits). Not all drivers - * implement this. - * * FT_LOAD_PEDANTIC :: * Indicates that the font driver should perform pedantic verifications * during glyph loading. This is mostly used to detect broken glyphs @@ -2496,18 +2708,12 @@ FT_BEGIN_HEADER * result in partially hinted or distorted glyphs in case a glyph's * bytecode is buggy. * - * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: - * Ignored. Deprecated. - * * FT_LOAD_NO_RECURSE :: - * This flag is only used internally. It merely indicates that the - * font driver should not load composite glyphs recursively. Instead, - * it should set the `num_subglyph' and `subglyphs' values of the - * glyph slot accordingly, and set `glyph->format' to - * @FT_GLYPH_FORMAT_COMPOSITE. - * - * The description of sub-glyphs is not available to client - * applications for now. + * Indicate that the font driver should not load composite glyphs + * recursively. Instead, it should set the `num_subglyph' and + * `subglyphs' values of the glyph slot accordingly, and set + * `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE. The description of + * subglyphs can then be accessed with @FT_Get_SubGlyph_Info. * * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. * @@ -2540,6 +2746,22 @@ FT_BEGIN_HEADER * bitmaps transparently. Those bitmaps will be in the * @FT_PIXEL_MODE_GRAY format. * + * FT_LOAD_COMPUTE_METRICS :: + * This flag sets computing glyph metrics without the use of bundled + * metrics tables (for example, the `hdmx' table in TrueType fonts). + * Well-behaving fonts have optimized bundled metrics and these should + * be used. This flag is mainly used by font validating or font + * editing applications, which need to ignore, verify, or edit those + * tables. + * + * Currently, this flag is only implemented for TrueType fonts. + * + * FT_LOAD_CROP_BITMAP :: + * Ignored. Deprecated. + * + * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: + * Ignored. Deprecated. + * * @note: * By default, hinting is enabled and the font's native hinter (see * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can @@ -2579,6 +2801,7 @@ FT_BEGIN_HEADER #define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ #define FT_LOAD_COLOR ( 1L << 20 ) +#define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) /* */ @@ -2601,9 +2824,6 @@ FT_BEGIN_HEADER * have specified (e.g., the TrueType bytecode interpreter). You can set * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. * - * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it - * always implies @FT_LOAD_FORCE_AUTOHINT. - * * @values: * FT_LOAD_TARGET_NORMAL :: * This corresponds to the default hinting algorithm, optimized for @@ -2611,11 +2831,14 @@ FT_BEGIN_HEADER * @FT_LOAD_TARGET_MONO instead. * * FT_LOAD_TARGET_LIGHT :: - * A lighter hinting algorithm for non-monochrome modes. Many - * generated glyphs are more fuzzy but better resemble its original - * shape. A bit like rendering on Mac OS~X. - * - * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. + * A lighter hinting algorithm for gray-level modes. Many generated + * glyphs are fuzzier but better resemble their original shape. This + * is achieved by snapping glyphs to the pixel grid only vertically + * (Y-axis), as is done by Microsoft's ClearType and Adobe's + * proprietary font renderer. This preserves inter-glyph spacing in + * horizontal text. The snapping is done either by the native font + * driver if the driver itself and the font support it or by the + * auto-hinter. * * FT_LOAD_TARGET_MONO :: * Strong hinting algorithm that should only be used for monochrome @@ -2635,8 +2858,8 @@ FT_BEGIN_HEADER * `load_flags'. They can't be ORed. * * If @FT_LOAD_RENDER is also set, the glyph is rendered in the - * corresponding mode (i.e., the mode which matches the used algorithm - * best). An exeption is FT_LOAD_TARGET_MONO since it implies + * corresponding mode (i.e., the mode that matches the used algorithm + * best). An exception is FT_LOAD_TARGET_MONO since it implies * @FT_LOAD_MONOCHROME. * * You can use a hinting algorithm that doesn't correspond to the same @@ -2722,7 +2945,10 @@ FT_BEGIN_HEADER /* field in the @FT_GlyphSlotRec structure gives the format of the */ /* returned bitmap. */ /* */ - /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity, */ + /* indicating pixel coverage. Use linear alpha blending and gamma */ + /* correction to correctly render non-monochrome glyph bitmaps onto a */ + /* surface; see @FT_Render_Glyph. */ /* */ /* <Values> */ /* FT_RENDER_MODE_NORMAL :: */ @@ -2776,19 +3002,8 @@ FT_BEGIN_HEADER } FT_Render_Mode; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_render_mode_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated. Use the corresponding */ - /* @FT_Render_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ - /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ - /* */ + /* these constants are deprecated; use the corresponding */ + /* `FT_Render_Mode' values instead */ #define ft_render_mode_normal FT_RENDER_MODE_NORMAL #define ft_render_mode_mono FT_RENDER_MODE_MONO @@ -2815,6 +3030,87 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* To get meaningful results, font scaling values must be set with */ + /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* */ + /* When FreeType outputs a bitmap of a glyph, it really outputs an */ + /* alpha coverage map. If a pixel is completely covered by a */ + /* filled-in outline, the bitmap contains 0xFF at that pixel, meaning */ + /* that 0xFF/0xFF fraction of that pixel is covered, meaning the */ + /* pixel is 100% black (or 0% bright). If a pixel is only 50% */ + /* covered (value 0x80), the pixel is made 50% black (50% bright or a */ + /* middle shade of grey). 0% covered means 0% black (100% bright or */ + /* white). */ + /* */ + /* On high-DPI screens like on smartphones and tablets, the pixels */ + /* are so small that their chance of being completely covered and */ + /* therefore completely black are fairly good. On the low-DPI */ + /* screens, however, the situation is different. The pixels are too */ + /* large for most of the details of a glyph and shades of gray are */ + /* the norm rather than the exception. */ + /* */ + /* This is relevant because all our screens have a second problem: */ + /* they are not linear. 1~+~1 is not~2. Twice the value does not */ + /* result in twice the brightness. When a pixel is only 50% covered, */ + /* the coverage map says 50% black, and this translates to a pixel */ + /* value of 128 when you use 8~bits per channel (0-255). However, */ + /* this does not translate to 50% brightness for that pixel on our */ + /* sRGB and gamma~2.2 screens. Due to their non-linearity, they */ + /* dwell longer in the darks and only a pixel value of about 186 */ + /* results in 50% brightness – 128 ends up too dark on both bright */ + /* and dark backgrounds. The net result is that dark text looks */ + /* burnt-out, pixely and blotchy on bright background, bright text */ + /* too frail on dark backgrounds, and colored text on colored */ + /* background (for example, red on green) seems to have dark halos or */ + /* `dirt' around it. The situation is especially ugly for diagonal */ + /* stems like in `w' glyph shapes where the quality of FreeType's */ + /* anti-aliasing depends on the correct display of grays. On */ + /* high-DPI screens where smaller, fully black pixels reign supreme, */ + /* this doesn't matter, but on our low-DPI screens with all the gray */ + /* shades, it does. 0% and 100% brightness are the same things in */ + /* linear and non-linear space, just all the shades in-between */ + /* aren't. */ + /* */ + /* The blending function for placing text over a background is */ + /* */ + /* { */ + /* dst = alpha * src + (1 - alpha) * dst , */ + /* } */ + /* */ + /* which is known as the OVER operator. */ + /* */ + /* To correctly composite an antialiased pixel of a glyph onto a */ + /* surface, */ + /* */ + /* 1. take the foreground and background colors (e.g., in sRGB space) */ + /* and apply gamma to get them in a linear space, */ + /* */ + /* 2. use OVER to blend the two linear colors using the glyph pixel */ + /* as the alpha value (remember, the glyph bitmap is an alpha */ + /* coverage bitmap), and */ + /* */ + /* 3. apply inverse gamma to the blended pixel and write it back to */ + /* the image. */ + /* */ + /* Internal testing at Adobe found that a target inverse gamma of~1.8 */ + /* for step~3 gives good results across a wide range of displays with */ + /* an sRGB gamma curve or a similar one. */ + /* */ + /* This process can cost performance. There is an approximation that */ + /* does not need to know about the background color; see */ + /* https://bel.fi/alankila/lcd/ and */ + /* https://bel.fi/alankila/lcd/alpcor.html for details. */ + /* */ + /* *ATTENTION*: Linear blending is even more important when dealing */ + /* with subpixel-rendered glyphs to prevent color-fringing! A */ + /* subpixel-rendered glyph must first be filtered with a filter that */ + /* gives equal weight to the three color primaries and does not */ + /* exceed a sum of 0x100, see section @lcd_filtering. Then the */ + /* only difference to gray linear blending is that subpixel-rendered */ + /* linear blending is done 3~times per pixel: red foreground subpixel */ + /* to red background subpixel and so on for green and blue. */ + /* */ FT_EXPORT( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, FT_Render_Mode render_mode ); @@ -2830,15 +3126,22 @@ FT_BEGIN_HEADER /* @FT_Get_Kerning. */ /* */ /* <Values> */ - /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ - /* distances (value is~0). */ + /* FT_KERNING_DEFAULT :: Return grid-fitted kerning distances in */ + /* pixels (value is~0). Whether they are */ + /* scaled depends on @FT_LOAD_NO_SCALE. */ /* */ - /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ - /* distances. */ + /* FT_KERNING_UNFITTED :: Return un-grid-fitted kerning distances in */ + /* 26.6 fractional pixels. Whether they are */ + /* scaled depends on @FT_LOAD_NO_SCALE. */ /* */ /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ /* units. */ /* */ + /* <Note> */ + /* FT_KERNING_DEFAULT returns full pixel values; it also makes */ + /* FreeType heuristically scale down kerning distances at small ppem */ + /* values so that they don't become too big. */ + /* */ typedef enum FT_Kerning_Mode_ { FT_KERNING_DEFAULT = 0, @@ -2848,39 +3151,10 @@ FT_BEGIN_HEADER } FT_Kerning_Mode; - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_default */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_DEFAULT */ - /* instead. */ - /* */ + /* these constants are deprecated; use the corresponding */ + /* `FT_Kerning_Mode' values instead */ #define ft_kerning_default FT_KERNING_DEFAULT - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_unfitted */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_UNFITTED */ - /* instead. */ - /* */ #define ft_kerning_unfitted FT_KERNING_UNFITTED - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_unscaled */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_UNSCALED */ - /* instead. */ - /* */ #define ft_kerning_unscaled FT_KERNING_UNSCALED @@ -2904,9 +3178,10 @@ FT_BEGIN_HEADER /* kerning vector. */ /* */ /* <Output> */ - /* akerning :: The kerning vector. This is either in font units */ - /* or in pixels (26.6 format) for scalable formats, */ - /* and in pixels for fixed-sizes formats. */ + /* akerning :: The kerning vector. This is either in font units, */ + /* fractional pixels (26.6 format), or pixels for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -3001,9 +3276,8 @@ FT_BEGIN_HEADER /* glyph index~0 always corresponds to the `missing glyph' (called */ /* `.notdef'). */ /* */ - /* This function is not compiled within the library if the config */ - /* macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in */ - /* `include/freetype/config/ftoptions.h'. */ + /* This function always returns an error if the config macro */ + /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph_Name( FT_Face face, @@ -3059,8 +3333,8 @@ FT_BEGIN_HEADER /* */ /* Because many fonts contain more than a single cmap for Unicode */ /* encoding, this function has some special code to select the one */ - /* which covers Unicode best (`best' in the sense that a UCS-4 cmap */ - /* is preferred to a UCS-2 cmap). It is thus preferable to */ + /* that covers Unicode best (`best' in the sense that a UCS-4 cmap is */ + /* preferred to a UCS-2 cmap). It is thus preferable to */ /* @FT_Set_Charmap in this case. */ /* */ FT_EXPORT( FT_Error ) @@ -3192,6 +3466,13 @@ FT_BEGIN_HEADER /* } */ /* } */ /* */ + /* Be aware that character codes can have values up to 0xFFFFFFFF; */ + /* this might happen for non-Unicode or malformed cmaps. However, */ + /* even with regular Unicode encoding, so-called `last resort fonts' */ + /* (using SFNT cmap format 13, see function @FT_Get_CMap_Format) */ + /* normally have entries for all Unicode characters up to 0x1FFFFF, */ + /* which can cause *a lot* of iterations. */ + /* */ /* Note that `*agindex' is set to~0 if the charmap is empty. The */ /* result itself can be~0 in two cases: if the charmap is empty or */ /* if the value~0 is the first valid character code. */ @@ -3351,8 +3632,9 @@ FT_BEGIN_HEADER /* @FT_Get_FSType_Flags; they inform client applications of embedding */ /* and subsetting restrictions associated with a font. */ /* */ - /* See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for */ - /* more details. */ + /* See */ + /* http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf */ + /* for more details. */ /* */ /* <Values> */ /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ @@ -3386,6 +3668,9 @@ FT_BEGIN_HEADER /* bitmaps available in the font, then the font is unembeddable. */ /* */ /* <Note> */ + /* The flags are ORed together, thus more than a single value can be */ + /* returned. */ + /* */ /* While the fsType flags can indicate that a font may be embedded, a */ /* license with the font vendor may be separately required to use the */ /* font in this way. */ @@ -3414,7 +3699,7 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* Use this function rather than directly reading the `fs_type' field */ - /* in the @PS_FontInfoRec structure which is only guaranteed to */ + /* in the @PS_FontInfoRec structure, which is only guaranteed to */ /* return the correct results for Type~1 fonts. */ /* */ /* <Since> */ @@ -3451,8 +3736,8 @@ FT_BEGIN_HEADER /* */ /* http://www.unicode.org/reports/tr37/ */ /* */ - /* To date (November 2012), the character with the most variants is */ - /* U+9089, having 31 such IVS. */ + /* To date (November 2014), the character with the most variants is */ + /* U+9089, having 32 such IVS. */ /* */ /* Adobe and MS decided to support IVS with a new cmap subtable */ /* (format~14). It is an odd subtable because it is not a mapping of */ @@ -3594,7 +3879,7 @@ FT_BEGIN_HEADER /* The character codepoint in Unicode. */ /* */ /* <Return> */ - /* A pointer to an array of variant selector code points which are */ + /* A pointer to an array of variant selector code points that are */ /* active for the given character, or NULL if the corresponding list */ /* is empty. */ /* */ @@ -3628,7 +3913,7 @@ FT_BEGIN_HEADER /* The variant selector code point in Unicode. */ /* */ /* <Return> */ - /* A list of all the code points which are specified by this selector */ + /* A list of all the code points that are specified by this selector */ /* (both default and non-default codes are returned) or NULL if there */ /* is no valid cmap or the variant selector is invalid. */ /* */ @@ -3703,12 +3988,6 @@ FT_BEGIN_HEADER FT_Long c ); - /* */ - - /* The following #if 0 ... #endif is for the documentation formatter, */ - /* hiding the internal `FT_MULFIX_INLINED' macro. */ - -#if 0 /*************************************************************************/ /* */ /* <Function> */ @@ -3742,17 +4021,6 @@ FT_BEGIN_HEADER FT_MulFix( FT_Long a, FT_Long b ); - /* */ -#endif - -#ifdef FT_MULFIX_INLINED -#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b ) -#else - FT_EXPORT( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ); -#endif - /*************************************************************************/ /* */ @@ -3765,18 +4033,12 @@ FT_BEGIN_HEADER /* used to divide a given value by a 16.16 fixed-point factor. */ /* */ /* <Input> */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ + /* a :: The numerator. */ + /* b :: The denominator. Use a 16.16 factor here. */ /* */ /* <Return> */ /* The result of `(a*0x10000)/b'. */ /* */ - /* <Note> */ - /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ - /* 32~bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of @FT_MulDiv. */ - /* */ FT_EXPORT( FT_Long ) FT_DivFix( FT_Long a, FT_Long b ); @@ -3794,7 +4056,8 @@ FT_BEGIN_HEADER /* a :: The number to be rounded. */ /* */ /* <Return> */ - /* The result of `(a + 0x8000) & -0x10000'. */ + /* `a' rounded to nearest 16.16 fixed integer, halfway cases away */ + /* from zero. */ /* */ FT_EXPORT( FT_Fixed ) FT_RoundFix( FT_Fixed a ); @@ -3813,7 +4076,7 @@ FT_BEGIN_HEADER /* a :: The number for which the ceiling function is to be computed. */ /* */ /* <Return> */ - /* The result of `(a + 0x10000 - 1) & -0x10000'. */ + /* `a' rounded towards plus infinity. */ /* */ FT_EXPORT( FT_Fixed ) FT_CeilFix( FT_Fixed a ); @@ -3832,7 +4095,7 @@ FT_BEGIN_HEADER /* a :: The number for which the floor function is to be computed. */ /* */ /* <Return> */ - /* The result of `a & -0x10000'. */ + /* `a' rounded towards minus infinity. */ /* */ FT_EXPORT( FT_Fixed ) FT_FloorFix( FT_Fixed a ); @@ -3876,6 +4139,18 @@ FT_BEGIN_HEADER /* even a new release of FreeType with only documentation changes */ /* increases the version number. */ /* */ + /* <Order> */ + /* FT_Library_Version */ + /* */ + /* FREETYPE_MAJOR */ + /* FREETYPE_MINOR */ + /* FREETYPE_PATCH */ + /* */ + /* FT_Face_CheckTrueTypePatents */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* FREETYPE_XXX */ + /* */ /*************************************************************************/ @@ -3900,8 +4175,8 @@ FT_BEGIN_HEADER * */ #define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 5 -#define FREETYPE_PATCH 0 +#define FREETYPE_MINOR 6 +#define FREETYPE_PATCH 5 /*************************************************************************/ @@ -3946,20 +4221,13 @@ FT_BEGIN_HEADER /* FT_Face_CheckTrueTypePatents */ /* */ /* <Description> */ - /* Parse all bytecode instructions of a TrueType font file to check */ - /* whether any of the patented opcodes are used. This is only useful */ - /* if you want to be able to use the unpatented hinter with */ - /* fonts that do *not* use these opcodes. */ - /* */ - /* Note that this function parses *all* glyph instructions in the */ - /* font file, which may be slow. */ + /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ /* */ /* <Return> */ - /* 1~if this is a TrueType font that uses one of the patented */ - /* opcodes, 0~otherwise. */ + /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ @@ -3977,9 +4245,7 @@ FT_BEGIN_HEADER /* FT_Face_SetUnpatentedHinting */ /* */ /* <Description> */ - /* Enable or disable the unpatented hinter for a given face. */ - /* Only enable it if you have determined that the face doesn't */ - /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ + /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ @@ -3987,9 +4253,7 @@ FT_BEGIN_HEADER /* value :: New boolean setting. */ /* */ /* <Return> */ - /* The old setting value. This will always be false if this is not */ - /* an SFNT font, or if the unpatented hinter is not compiled in this */ - /* instance of the library. */ + /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ @@ -4006,7 +4270,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FREETYPE_H__ */ +#endif /* FREETYPE_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftadvanc.h b/drivers/freetype/include/freetype/ftadvanc.h index 012b74b812..023dd84b7a 100644 --- a/drivers/freetype/include/freetype/ftadvanc.h +++ b/drivers/freetype/include/freetype/ftadvanc.h @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (specification only). */ /* */ -/* Copyright 2008, 2013 by */ +/* Copyright 2008-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTADVANC_H__ -#define __FTADVANC_H__ +#ifndef FTADVANC_H_ +#define FTADVANC_H_ #include <ft2build.h> @@ -48,6 +48,11 @@ FT_BEGIN_HEADER * @description: * This section contains functions to quickly extract advance values * without handling glyph outlines, if possible. + * + * @order: + * FT_Get_Advance + * FT_Get_Advances + * */ @@ -64,15 +69,15 @@ FT_BEGIN_HEADER /* corresponding hinting mode or font driver doesn't allow for very */ /* quick advance computation. */ /* */ - /* Typically, glyphs which are either unscaled, unhinted, bitmapped, */ + /* Typically, glyphs that are either unscaled, unhinted, bitmapped, */ /* or light-hinted can have their advance width computed very */ /* quickly. */ /* */ - /* Normal and bytecode hinted modes, which require loading, scaling, */ + /* Normal and bytecode hinted modes that require loading, scaling, */ /* and hinting of the glyph outline, are extremely slow by */ /* comparison. */ /* */ -#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000UL +#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000L /*************************************************************************/ @@ -171,12 +176,12 @@ FT_BEGIN_HEADER FT_Int32 load_flags, FT_Fixed *padvances ); -/* */ + /* */ FT_END_HEADER -#endif /* __FTADVANC_H__ */ +#endif /* FTADVANC_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftautoh.h b/drivers/freetype/include/freetype/ftautoh.h index 5e1153a1c1..40c8003c4a 100644 --- a/drivers/freetype/include/freetype/ftautoh.h +++ b/drivers/freetype/include/freetype/ftautoh.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for controlling the auto-hinter (specification only). */ /* */ -/* Copyright 2012, 2013 by */ +/* Copyright 2012-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTAUTOH_H__ -#define __FTAUTOH_H__ +#ifndef FTAUTOH_H_ +#define FTAUTOH_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -79,7 +79,7 @@ FT_BEGIN_HEADER * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an * array with `num_glyphs' elements, as found in the font's @FT_Face * structure. The `glyph-to-script-map' property returns a pointer to - * this array which can be modified as needed. Note that the + * this array, which can be modified as needed. Note that the * modification should happen before the first glyph gets processed by * the auto-hinter so that the global analysis of the font shapes * actually uses the modified mapping. @@ -219,8 +219,8 @@ FT_BEGIN_HEADER * U+0F00 - U+0FFF // Tibetan * U+1900 - U+194F // Limbu * U+1B80 - U+1BBF // Sundanese - * U+1C80 - U+1CDF // Meetei Mayak * U+A800 - U+A82F // Syloti Nagri + * U+ABC0 - U+ABFF // Meetei Mayek * U+11800 - U+118DF // Sharada * } * @@ -245,12 +245,12 @@ FT_BEGIN_HEADER * The data exchange structure for the @glyph-to-script-map property. * */ - typedef struct FT_Prop_GlyphToScriptMap_ - { - FT_Face face; - FT_Byte* map; + typedef struct FT_Prop_GlyphToScriptMap_ + { + FT_Face face; + FT_UShort* map; - } FT_Prop_GlyphToScriptMap; + } FT_Prop_GlyphToScriptMap; /************************************************************************** @@ -282,12 +282,57 @@ FT_BEGIN_HEADER * This property can be used with @FT_Property_Get also. * * It's important to use the right timing for changing this value: The - * creation of the glyph-to-script map which eventually uses the + * creation of the glyph-to-script map that eventually uses the * fallback script value gets triggered either by setting or reading a * face-specific property like @glyph-to-script-map, or by auto-hinting * any glyph from that face. In particular, if you have already created * an @FT_Face structure but not loaded any glyph (using the - * auto-hinter), a change of the fallback glyph will affect this face. + * auto-hinter), a change of the fallback script will affect this face. + * + */ + + + /************************************************************************** + * + * @property: + * default-script + * + * @description: + * *Experimental* *only* + * + * If FreeType gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make + * the HarfBuzz library access OpenType features for getting better + * glyph coverages, this property sets the (auto-fitter) script to be + * used for the default (OpenType) script data of a font's GSUB table. + * Features for the default script are intended for all scripts not + * explicitly handled in GSUB; an example is a `dlig' feature, + * containing the combination of the characters `T', `E', and `L' to + * form a `TEL' ligature. + * + * By default, this is @FT_AUTOHINTER_SCRIPT_LATIN. Using the + * `default-script' property, this default value can be changed. + * + * { + * FT_Library library; + * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "default-script", &default_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * default script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the default script will affect this face. * */ @@ -339,19 +384,120 @@ FT_BEGIN_HEADER * The data exchange structure for the @increase-x-height property. * */ - typedef struct FT_Prop_IncreaseXHeight_ - { - FT_Face face; - FT_UInt limit; + typedef struct FT_Prop_IncreaseXHeight_ + { + FT_Face face; + FT_UInt limit; + + } FT_Prop_IncreaseXHeight; + + + /************************************************************************** + * + * @property: + * warping + * + * @description: + * *Experimental* *only* + * + * If FreeType gets compiled with option AF_CONFIG_OPTION_USE_WARPER to + * activate the warp hinting code in the auto-hinter, this property + * switches warping on and off. + * + * Warping only works in `light' auto-hinting mode. The idea of the + * code is to slightly scale and shift a glyph along the non-hinted + * dimension (which is usually the horizontal axis) so that as much of + * its segments are aligned (more or less) to the grid. To find out a + * glyph's optimal scaling and shifting value, various parameter + * combinations are tried and scored. + * + * By default, warping is off. The example below shows how to switch on + * warping (omitting the error handling). + * + * { + * FT_Library library; + * FT_Bool warping = 1; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "warping", &warping ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * The warping code can also change advance widths. Have a look at the + * `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure + * for details on improving inter-glyph distances while rendering. + * + * Since warping is a global property of the auto-hinter it is best to + * change its value before rendering any face. Otherwise, you should + * reload all faces that get auto-hinted in `light' hinting mode. + * + */ + + + /************************************************************************** + * + * @property: + * no-stem-darkening[autofit] + * + * @description: + * *Experimental* *only,* *requires* *linear* *alpha* *blending* *and* + * *gamma* *correction* + * + * Stem darkening emboldens glyphs at smaller sizes to make them more + * readable on common low-DPI screens when using linear alpha blending + * and gamma correction, see @FT_Render_Glyph. When not using linear + * alpha blending and gamma correction, glyphs will appear heavy and + * fuzzy! + * + * Gamma correction essentially lightens fonts since shades of grey are + * shifted to higher pixel values (=~higher brightness) to match the + * original intention to the reality of our screens. The side-effect is + * that glyphs `thin out'. Mac OS~X and Adobe's proprietary font + * rendering library implement a counter-measure: stem darkening at + * smaller sizes where shades of gray dominate. By emboldening a glyph + * slightly in relation to its pixel size, individual pixels get higher + * coverage of filled-in outlines and are therefore `blacker'. This + * counteracts the `thinning out' of glyphs, making text remain readable + * at smaller sizes. All glyphs that pass through the auto-hinter will + * be emboldened unless this property is set to TRUE. + * + * See the description of the CFF driver for algorithmic details. Total + * consistency with the CFF driver is currently not achieved because the + * emboldening method differs and glyphs must be scaled down on the + * Y-axis to keep outline points inside their precomputed blue zones. + * The smaller the size (especially 9ppem and down), the higher the loss + * of emboldening versus the CFF driver. + * + */ + + + /************************************************************************** + * + * @property: + * darkening-parameters[autofit] + * + * @description: + * *Experimental* *only* + * + * See the description of the CFF driver for details. This + * implementation appropriates the + * CFF_CONFIG_OPTION_DARKENING_PARAMETER_* #defines for consistency. + * Note the differences described in @no-stem-darkening[autofit]. + * + */ - } FT_Prop_IncreaseXHeight; + /* */ - /* */ FT_END_HEADER -#endif /* __FTAUTOH_H__ */ +#endif /* FTAUTOH_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftbbox.h b/drivers/freetype/include/freetype/ftbbox.h index 976691956f..2a4d214416 100644 --- a/drivers/freetype/include/freetype/ftbbox.h +++ b/drivers/freetype/include/freetype/ftbbox.h @@ -4,7 +4,7 @@ /* */ /* FreeType exact bbox computation (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2007, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,8 @@ /*************************************************************************/ -#ifndef __FTBBOX_H__ -#define __FTBBOX_H__ +#ifndef FTBBOX_H_ +#define FTBBOX_H_ #include <ft2build.h> @@ -60,7 +60,7 @@ FT_BEGIN_HEADER /* <Description> */ /* Compute the exact bounding box of an outline. This is slower */ /* than computing the control box. However, it uses an advanced */ - /* algorithm which returns _very_ quickly when the two boxes */ + /* algorithm that returns _very_ quickly when the two boxes */ /* coincide. Otherwise, the outline Bézier arcs are traversed to */ /* extract their extrema. */ /* */ @@ -78,20 +78,19 @@ FT_BEGIN_HEADER /* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */ /* reasonable values for the BBox it is necessary to load the glyph */ /* at a large ppem value (so that the hinting instructions can */ - /* properly shift and scale the subglyphs), then extracting the BBox */ + /* properly shift and scale the subglyphs), then extracting the BBox, */ /* which can be eventually converted back to font units. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, FT_BBox *abbox ); - /* */ FT_END_HEADER -#endif /* __FTBBOX_H__ */ +#endif /* FTBBOX_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftbdf.h b/drivers/freetype/include/freetype/ftbdf.h index 4f8baf8401..016dba086d 100644 --- a/drivers/freetype/include/freetype/ftbdf.h +++ b/drivers/freetype/include/freetype/ftbdf.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (specification). */ /* */ -/* Copyright 2002, 2003, 2004, 2006, 2009 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBDF_H__ -#define __FTBDF_H__ +#ifndef FTBDF_H_ +#define FTBDF_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -53,7 +53,7 @@ FT_BEGIN_HEADER /********************************************************************** * * @enum: - * FT_PropertyType + * BDF_PropertyType * * @description: * A list of BDF property types. @@ -106,7 +106,8 @@ FT_BEGIN_HEADER * The property type. * * u.atom :: - * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be + * NULL, indicating an empty string. * * u.integer :: * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. @@ -199,11 +200,11 @@ FT_BEGIN_HEADER const char* prop_name, BDF_PropertyRec *aproperty ); - /* */ + /* */ FT_END_HEADER -#endif /* __FTBDF_H__ */ +#endif /* FTBDF_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftbitmap.h b/drivers/freetype/include/freetype/ftbitmap.h index 7dbf5ba3fe..0eac7b9d7d 100644 --- a/drivers/freetype/include/freetype/ftbitmap.h +++ b/drivers/freetype/include/freetype/ftbitmap.h @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (specification). */ /* */ -/* Copyright 2004-2006, 2008, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBITMAP_H__ -#define __FTBITMAP_H__ +#ifndef FTBITMAP_H_ +#define FTBITMAP_H_ #include <ft2build.h> @@ -45,7 +45,9 @@ FT_BEGIN_HEADER /* Handling FT_Bitmap objects. */ /* */ /* <Description> */ - /* This section contains functions for converting FT_Bitmap objects. */ + /* This section contains functions for handling @FT_Bitmap objects. */ + /* Note that none of the functions changes the bitmap's `flow' (as */ + /* indicated by the sign of the `pitch' field in `FT_Bitmap'). */ /* */ /*************************************************************************/ @@ -53,7 +55,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Function> */ - /* FT_Bitmap_New */ + /* FT_Bitmap_Init */ /* */ /* <Description> */ /* Initialize a pointer to an @FT_Bitmap structure. */ @@ -61,6 +63,14 @@ FT_BEGIN_HEADER /* <InOut> */ /* abitmap :: A pointer to the bitmap structure. */ /* */ + /* <Note> */ + /* A deprecated name for the same function is `FT_Bitmap_New'. */ + /* */ + FT_EXPORT( void ) + FT_Bitmap_Init( FT_Bitmap *abitmap ); + + + /* deprecated */ FT_EXPORT( void ) FT_Bitmap_New( FT_Bitmap *abitmap ); @@ -122,6 +132,9 @@ FT_BEGIN_HEADER /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ /* */ + /* Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format */ + /* are converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp). */ + /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Embolden( FT_Library library, FT_Bitmap* bitmap, @@ -197,7 +210,7 @@ FT_BEGIN_HEADER /* FT_Bitmap_Done */ /* */ /* <Description> */ - /* Destroy a bitmap object created with @FT_Bitmap_New. */ + /* Destroy a bitmap object initialized with @FT_Bitmap_Init. */ /* */ /* <Input> */ /* library :: A handle to a library object. */ @@ -221,7 +234,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBITMAP_H__ */ +#endif /* FTBITMAP_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftbzip2.h b/drivers/freetype/include/freetype/ftbzip2.h index 1bf81b15e8..b7f2eee87d 100644 --- a/drivers/freetype/include/freetype/ftbzip2.h +++ b/drivers/freetype/include/freetype/ftbzip2.h @@ -4,7 +4,7 @@ /* */ /* Bzip2-compressed stream support. */ /* */ -/* Copyright 2010 by */ +/* Copyright 2010-2016 by */ /* Joel Klinghed. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBZIP2_H__ -#define __FTBZIP2_H__ +#ifndef FTBZIP2_H_ +#define FTBZIP2_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -91,12 +91,12 @@ FT_BEGIN_HEADER FT_Stream_OpenBzip2( FT_Stream stream, FT_Stream source ); - /* */ + /* */ FT_END_HEADER -#endif /* __FTBZIP2_H__ */ +#endif /* FTBZIP2_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftcache.h b/drivers/freetype/include/freetype/ftcache.h index 4ec9587cf6..883c88d5d2 100644 --- a/drivers/freetype/include/freetype/ftcache.h +++ b/drivers/freetype/include/freetype/ftcache.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache subsystem (specification). */ /* */ -/* Copyright 1996-2008, 2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCACHE_H__ -#define __FTCACHE_H__ +#ifndef FTCACHE_H_ +#define FTCACHE_H_ #include <ft2build.h> @@ -156,7 +156,7 @@ FT_BEGIN_HEADER * @note: * Never use NULL as a valid @FTC_FaceID. * - * Face IDs are passed by the client to the cache manager, which calls, + * Face IDs are passed by the client to the cache manager that calls, * when needed, the @FTC_Face_Requester to translate them into new * @FT_Face objects. * @@ -209,10 +209,10 @@ FT_BEGIN_HEADER typedef FT_Error (*FTC_Face_Requester)( FTC_FaceID face_id, FT_Library library, - FT_Pointer request_data, + FT_Pointer req_data, FT_Face* aface ); - /* */ + /* */ /*************************************************************************/ @@ -667,8 +667,8 @@ FT_BEGIN_HEADER typedef struct FTC_ImageTypeRec_ { FTC_FaceID face_id; - FT_Int width; - FT_Int height; + FT_UInt width; + FT_UInt height; FT_Int32 flags; } FTC_ImageTypeRec; @@ -749,7 +749,7 @@ FT_BEGIN_HEADER /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ - /* anode :: Used to return the address of of the corresponding cache */ + /* anode :: Used to return the address of the corresponding cache */ /* node after incrementing its reference count (see note */ /* below). */ /* */ @@ -802,7 +802,7 @@ FT_BEGIN_HEADER /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ - /* anode :: Used to return the address of of the corresponding */ + /* anode :: Used to return the address of the corresponding */ /* cache node after incrementing its reference count */ /* (see note below). */ /* */ @@ -957,7 +957,7 @@ FT_BEGIN_HEADER /* <Output> */ /* sbit :: A handle to a small bitmap descriptor. */ /* */ - /* anode :: Used to return the address of of the corresponding cache */ + /* anode :: Used to return the address of the corresponding cache */ /* node after incrementing its reference count (see note */ /* below). */ /* */ @@ -1012,7 +1012,7 @@ FT_BEGIN_HEADER /* <Output> */ /* sbit :: A handle to a small bitmap descriptor. */ /* */ - /* anode :: Used to return the address of of the corresponding */ + /* anode :: Used to return the address of the corresponding */ /* cache node after incrementing its reference count */ /* (see note below). */ /* */ @@ -1046,12 +1046,12 @@ FT_BEGIN_HEADER FTC_SBit *sbit, FTC_Node *anode ); + /* */ - /* */ FT_END_HEADER -#endif /* __FTCACHE_H__ */ +#endif /* FTCACHE_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftcffdrv.h b/drivers/freetype/include/freetype/ftcffdrv.h index ccbcbccaa8..ad34541fdb 100644 --- a/drivers/freetype/include/freetype/ftcffdrv.h +++ b/drivers/freetype/include/freetype/ftcffdrv.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for controlling the CFF driver (specification only). */ /* */ -/* Copyright 2013 by */ +/* Copyright 2013-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCFFDRV_H__ -#define __FTCFFDRV_H__ +#ifndef FTCFFDRV_H_ +#define FTCFFDRV_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -46,18 +46,81 @@ FT_BEGIN_HEADER * @description: * While FreeType's CFF driver doesn't expose API functions by itself, * it is possible to control its behaviour with @FT_Property_Set and - * @FT_Property_Get. The following lists the available properties + * @FT_Property_Get. The list below gives the available properties * together with the necessary macros and structures. * * The CFF driver's module name is `cff'. * + * *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine* + * + * The rasterizer is positioning horizontal features (e.g., ascender + * height & x-height, or crossbars) on the pixel grid and minimizing the + * amount of antialiasing applied to them, while placing vertical + * features (vertical stems) on the pixel grid without hinting, thus + * representing the stem position and weight accurately. Sometimes the + * vertical stems may be only partially black. In this context, + * `antialiasing' means that stems are not positioned exactly on pixel + * borders, causing a fuzzy appearance. + * + * There are two principles behind this approach. + * + * 1) No hinting in the horizontal direction: Unlike `superhinted' + * TrueType, which changes glyph widths to accommodate regular + * inter-glyph spacing, Adobe's approach is `faithful to the design' in + * representing both the glyph width and the inter-glyph spacing + * designed for the font. This makes the screen display as close as it + * can be to the result one would get with infinite resolution, while + * preserving what is considered the key characteristics of each glyph. + * Note that the distances between unhinted and grid-fitted positions at + * small sizes are comparable to kerning values and thus would be + * noticeable (and distracting) while reading if hinting were applied. + * + * One of the reasons to not hint horizontally is antialiasing for LCD + * screens: The pixel geometry of modern displays supplies three + * vertical sub-pixels as the eye moves horizontally across each visible + * pixel. On devices where we can be certain this characteristic is + * present a rasterizer can take advantage of the sub-pixels to add + * increments of weight. In Western writing systems this turns out to + * be the more critical direction anyway; the weights and spacing of + * vertical stems (see above) are central to Armenian, Cyrillic, Greek, + * and Latin type designs. Even when the rasterizer uses greyscale + * antialiasing instead of color (a necessary compromise when one + * doesn't know the screen characteristics), the unhinted vertical + * features preserve the design's weight and spacing much better than + * aliased type would. + * + * 2) Alignment in the vertical direction: Weights and spacing along the + * y~axis are less critical; what is much more important is the visual + * alignment of related features (like cap-height and x-height). The + * sense of alignment for these is enhanced by the sharpness of grid-fit + * edges, while the cruder vertical resolution (full pixels instead of + * 1/3 pixels) is less of a problem. + * + * On the technical side, horizontal alignment zones for ascender, + * x-height, and other important height values (traditionally called + * `blue zones') as defined in the font are positioned independently, + * each being rounded to the nearest pixel edge, taking care of + * overshoot suppression at small sizes, stem darkening, and scaling. + * + * Hstems (this is, hint values defined in the font to help align + * horizontal features) that fall within a blue zone are said to be + * `captured' and are aligned to that zone. Uncaptured stems are moved + * in one of four ways, top edge up or down, bottom edge up or down. + * Unless there are conflicting hstems, the smallest movement is taken + * to minimize distortion. + * + * @order: + * hinting-engine[cff] + * no-stem-darkening[cff] + * darkening-parameters[cff] + * */ /************************************************************************** * * @property: - * hinting-engine + * hinting-engine[cff] * * @description: * Thanks to Adobe, which contributed a new hinting (and parsing) @@ -73,7 +136,6 @@ FT_BEGIN_HEADER * * { * FT_Library library; - * FT_Face face; * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; * * @@ -95,8 +157,8 @@ FT_BEGIN_HEADER * FT_CFF_HINTING_XXX * * @description: - * A list of constants used for the @hinting-engine property to select - * the hinting engine for CFF fonts. + * A list of constants used for the @hinting-engine[cff] property to + * select the hinting engine for CFF fonts. * * @values: * FT_CFF_HINTING_FREETYPE :: @@ -113,18 +175,18 @@ FT_BEGIN_HEADER /************************************************************************** * * @property: - * no-stem-darkening + * no-stem-darkening[cff] * * @description: * By default, the Adobe CFF engine darkens stems at smaller sizes, - * regardless of hinting, to enhance contrast. Setting this property, - * stem darkening gets switched off. + * regardless of hinting, to enhance contrast. This feature requires + * a rendering system with proper gamma correction. Setting this + * property, stem darkening gets switched off. * * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. * * { * FT_Library library; - * FT_Face face; * FT_Bool no_stem_darkening = TRUE; * * @@ -140,12 +202,61 @@ FT_BEGIN_HEADER */ - /* */ + /************************************************************************** + * + * @property: + * darkening-parameters[cff] + * + * @description: + * By default, the Adobe CFF engine darkens stems as follows (if the + * `no-stem-darkening' property isn't set): + * + * { + * stem width <= 0.5px: darkening amount = 0.4px + * stem width = 1px: darkening amount = 0.275px + * stem width = 1.667px: darkening amount = 0.275px + * stem width >= 2.333px: darkening amount = 0px + * } + * + * and piecewise linear in-between. At configuration time, these four + * control points can be set with the macro + * `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'. At runtime, the control + * points can be changed using the `darkening-parameters' property, as + * the following example demonstrates. + * + * { + * FT_Library library; + * FT_Int darken_params[8] = { 500, 300, // x1, y1 + * 1000, 200, // x2, y2 + * 1500, 100, // x3, y3 + * 2000, 0 }; // x4, y4 + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "darkening-parameters", darken_params ); + * } + * + * The x~values give the stem width, and the y~values the darkening + * amount. The unit is 1000th of pixels. All coordinate values must be + * positive; the x~values must be monotonically increasing; the + * y~values must be monotonically decreasing and smaller than or + * equal to 500 (corresponding to half a pixel); the slope of each + * linear piece must be shallower than -1 (e.g., -.4). + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + /* */ + FT_END_HEADER -#endif /* __FTCFFDRV_H__ */ +#endif /* FTCFFDRV_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftchapters.h b/drivers/freetype/include/freetype/ftchapters.h index c55670d1d2..ab4389530e 100644 --- a/drivers/freetype/include/freetype/ftchapters.h +++ b/drivers/freetype/include/freetype/ftchapters.h @@ -1,7 +1,7 @@ /***************************************************************************/ /* */ /* This file defines the structure of the FreeType reference. */ -/* It is used by the python script which generates the HTML files. */ +/* It is used by the python script that generates the HTML files. */ /* */ /***************************************************************************/ @@ -15,6 +15,7 @@ /* General Remarks */ /* */ /* <Sections> */ +/* header_inclusion */ /* user_allocation */ /* */ /***************************************************************************/ @@ -118,3 +119,17 @@ /* lcd_filtering */ /* */ /***************************************************************************/ + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* error_codes */ +/* */ +/* <Title> */ +/* Error Codes */ +/* */ +/* <Sections> */ +/* error_enumerations */ +/* error_code_values */ +/* */ +/***************************************************************************/ diff --git a/drivers/freetype/include/freetype/ftcid.h b/drivers/freetype/include/freetype/ftcid.h index 203a30caf8..e1bc9fe015 100644 --- a/drivers/freetype/include/freetype/ftcid.h +++ b/drivers/freetype/include/freetype/ftcid.h @@ -4,7 +4,8 @@ /* */ /* FreeType API for accessing CID font information (specification). */ /* */ -/* Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal. */ +/* Copyright 2007-2016 by */ +/* Dereg Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCID_H__ -#define __FTCID_H__ +#ifndef FTCID_H_ +#define FTCID_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -96,8 +97,8 @@ FT_BEGIN_HEADER * * @description: * Retrieve the type of the input face, CID keyed or not. In - * constrast to the @FT_IS_CID_KEYED macro this function returns - * successfully also for CID-keyed fonts in an SNFT wrapper. + * contrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SFNT wrapper. * * @input: * face :: @@ -156,11 +157,12 @@ FT_BEGIN_HEADER FT_UInt glyph_index, FT_UInt *cid ); - /* */ + /* */ + FT_END_HEADER -#endif /* __FTCID_H__ */ +#endif /* FTCID_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/fterrdef.h b/drivers/freetype/include/freetype/fterrdef.h index 76c7b9e36f..3f53dd5820 100644 --- a/drivers/freetype/include/freetype/fterrdef.h +++ b/drivers/freetype/include/freetype/fterrdef.h @@ -4,7 +4,7 @@ /* */ /* FreeType error codes (specification). */ /* */ -/* Copyright 2002, 2004, 2006, 2007, 2010-2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,234 +16,261 @@ /***************************************************************************/ - /*******************************************************************/ - /*******************************************************************/ - /***** *****/ - /***** LIST OF ERROR CODES/MESSAGES *****/ - /***** *****/ - /*******************************************************************/ - /*******************************************************************/ + /*************************************************************************/ + /* */ + /* <Section> */ + /* error_code_values */ + /* */ + /* <Title> */ + /* Error Code Values */ + /* */ + /* <Abstract> */ + /* All possible error codes returned by FreeType functions. */ + /* */ + /* <Description> */ + /* The list below is taken verbatim from the file `fterrdef.h' */ + /* (loaded automatically by including `FT_FREETYPE_H'). The first */ + /* argument of the `FT_ERROR_DEF_' macro is the error label; by */ + /* default, the prefix `FT_Err_' gets added so that you get error */ + /* names like `FT_Err_Cannot_Open_Resource'. The second argument is */ + /* the error code, and the last argument an error string, which is not */ + /* used by FreeType. */ + /* */ + /* Within your application you should *only* use error names and */ + /* *never* its numeric values! The latter might (and actually do) */ + /* change in forthcoming FreeType versions. */ + /* */ + /* Macro `FT_NOERRORDEF_' defines `FT_Err_Ok', which is always zero. */ + /* See the `Error Enumerations' subsection how to automatically */ + /* generate a list of error strings. */ + /* */ + /*************************************************************************/ - /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */ - /* including this file. */ - + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Err_XXX */ + /* */ + /*************************************************************************/ /* generic errors */ - FT_NOERRORDEF_( Ok, 0x00, \ + FT_NOERRORDEF_( Ok, 0x00, "no error" ) - FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, "cannot open resource" ) - FT_ERRORDEF_( Unknown_File_Format, 0x02, \ + FT_ERRORDEF_( Unknown_File_Format, 0x02, "unknown file format" ) - FT_ERRORDEF_( Invalid_File_Format, 0x03, \ + FT_ERRORDEF_( Invalid_File_Format, 0x03, "broken file" ) - FT_ERRORDEF_( Invalid_Version, 0x04, \ + FT_ERRORDEF_( Invalid_Version, 0x04, "invalid FreeType version" ) - FT_ERRORDEF_( Lower_Module_Version, 0x05, \ + FT_ERRORDEF_( Lower_Module_Version, 0x05, "module version is too low" ) - FT_ERRORDEF_( Invalid_Argument, 0x06, \ + FT_ERRORDEF_( Invalid_Argument, 0x06, "invalid argument" ) - FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ + FT_ERRORDEF_( Unimplemented_Feature, 0x07, "unimplemented feature" ) - FT_ERRORDEF_( Invalid_Table, 0x08, \ + FT_ERRORDEF_( Invalid_Table, 0x08, "broken table" ) - FT_ERRORDEF_( Invalid_Offset, 0x09, \ + FT_ERRORDEF_( Invalid_Offset, 0x09, "broken offset within table" ) - FT_ERRORDEF_( Array_Too_Large, 0x0A, \ + FT_ERRORDEF_( Array_Too_Large, 0x0A, "array allocation size too large" ) - FT_ERRORDEF_( Missing_Module, 0x0B, \ + FT_ERRORDEF_( Missing_Module, 0x0B, "missing module" ) - FT_ERRORDEF_( Missing_Property, 0x0C, \ + FT_ERRORDEF_( Missing_Property, 0x0C, "missing property" ) /* glyph/character errors */ - FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, "invalid glyph index" ) - FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ + FT_ERRORDEF_( Invalid_Character_Code, 0x11, "invalid character code" ) - FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, "unsupported glyph image format" ) - FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, "cannot render this glyph format" ) - FT_ERRORDEF_( Invalid_Outline, 0x14, \ + FT_ERRORDEF_( Invalid_Outline, 0x14, "invalid outline" ) - FT_ERRORDEF_( Invalid_Composite, 0x15, \ + FT_ERRORDEF_( Invalid_Composite, 0x15, "invalid composite glyph" ) - FT_ERRORDEF_( Too_Many_Hints, 0x16, \ + FT_ERRORDEF_( Too_Many_Hints, 0x16, "too many hints" ) - FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, "invalid pixel size" ) /* handle errors */ - FT_ERRORDEF_( Invalid_Handle, 0x20, \ + FT_ERRORDEF_( Invalid_Handle, 0x20, "invalid object handle" ) - FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, "invalid library handle" ) - FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, "invalid module handle" ) - FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, "invalid face handle" ) - FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, "invalid size handle" ) - FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, "invalid glyph slot handle" ) - FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, "invalid charmap handle" ) - FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, "invalid cache manager handle" ) - FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, "invalid stream handle" ) /* driver errors */ - FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ + FT_ERRORDEF_( Too_Many_Drivers, 0x30, "too many modules" ) - FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ + FT_ERRORDEF_( Too_Many_Extensions, 0x31, "too many extensions" ) /* memory errors */ - FT_ERRORDEF_( Out_Of_Memory, 0x40, \ + FT_ERRORDEF_( Out_Of_Memory, 0x40, "out of memory" ) - FT_ERRORDEF_( Unlisted_Object, 0x41, \ + FT_ERRORDEF_( Unlisted_Object, 0x41, "unlisted object" ) /* stream errors */ - FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, "cannot open stream" ) - FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, "invalid stream seek" ) - FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, "invalid stream skip" ) - FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, "invalid stream read" ) - FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, "invalid stream operation" ) - FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, "invalid frame operation" ) - FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ + FT_ERRORDEF_( Nested_Frame_Access, 0x57, "nested frame access" ) - FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, "invalid frame read" ) /* raster errors */ - FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ + FT_ERRORDEF_( Raster_Uninitialized, 0x60, "raster uninitialized" ) - FT_ERRORDEF_( Raster_Corrupted, 0x61, \ + FT_ERRORDEF_( Raster_Corrupted, 0x61, "raster corrupted" ) - FT_ERRORDEF_( Raster_Overflow, 0x62, \ + FT_ERRORDEF_( Raster_Overflow, 0x62, "raster overflow" ) - FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ + FT_ERRORDEF_( Raster_Negative_Height, 0x63, "negative height while rastering" ) /* cache errors */ - FT_ERRORDEF_( Too_Many_Caches, 0x70, \ + FT_ERRORDEF_( Too_Many_Caches, 0x70, "too many registered caches" ) /* TrueType and SFNT errors */ - FT_ERRORDEF_( Invalid_Opcode, 0x80, \ + FT_ERRORDEF_( Invalid_Opcode, 0x80, "invalid opcode" ) - FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ + FT_ERRORDEF_( Too_Few_Arguments, 0x81, "too few arguments" ) - FT_ERRORDEF_( Stack_Overflow, 0x82, \ + FT_ERRORDEF_( Stack_Overflow, 0x82, "stack overflow" ) - FT_ERRORDEF_( Code_Overflow, 0x83, \ + FT_ERRORDEF_( Code_Overflow, 0x83, "code overflow" ) - FT_ERRORDEF_( Bad_Argument, 0x84, \ + FT_ERRORDEF_( Bad_Argument, 0x84, "bad argument" ) - FT_ERRORDEF_( Divide_By_Zero, 0x85, \ + FT_ERRORDEF_( Divide_By_Zero, 0x85, "division by zero" ) - FT_ERRORDEF_( Invalid_Reference, 0x86, \ + FT_ERRORDEF_( Invalid_Reference, 0x86, "invalid reference" ) - FT_ERRORDEF_( Debug_OpCode, 0x87, \ + FT_ERRORDEF_( Debug_OpCode, 0x87, "found debug opcode" ) - FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, "found ENDF opcode in execution stream" ) - FT_ERRORDEF_( Nested_DEFS, 0x89, \ + FT_ERRORDEF_( Nested_DEFS, 0x89, "nested DEFS" ) - FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, "invalid code range" ) - FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ + FT_ERRORDEF_( Execution_Too_Long, 0x8B, "execution context too long" ) - FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, "too many function definitions" ) - FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, "too many instruction definitions" ) - FT_ERRORDEF_( Table_Missing, 0x8E, \ + FT_ERRORDEF_( Table_Missing, 0x8E, "SFNT font table missing" ) - FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, "horizontal header (hhea) table missing" ) - FT_ERRORDEF_( Locations_Missing, 0x90, \ + FT_ERRORDEF_( Locations_Missing, 0x90, "locations (loca) table missing" ) - FT_ERRORDEF_( Name_Table_Missing, 0x91, \ + FT_ERRORDEF_( Name_Table_Missing, 0x91, "name table missing" ) - FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ + FT_ERRORDEF_( CMap_Table_Missing, 0x92, "character map (cmap) table missing" ) - FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, "horizontal metrics (hmtx) table missing" ) - FT_ERRORDEF_( Post_Table_Missing, 0x94, \ + FT_ERRORDEF_( Post_Table_Missing, 0x94, "PostScript (post) table missing" ) - FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, "invalid horizontal metrics" ) - FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, "invalid character map (cmap) format" ) - FT_ERRORDEF_( Invalid_PPem, 0x97, \ + FT_ERRORDEF_( Invalid_PPem, 0x97, "invalid ppem value" ) - FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, "invalid vertical metrics" ) - FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, "could not find context" ) - FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, "invalid PostScript (post) table format" ) - FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, "invalid PostScript (post) table" ) /* CFF, CID, and Type 1 errors */ - FT_ERRORDEF_( Syntax_Error, 0xA0, \ + FT_ERRORDEF_( Syntax_Error, 0xA0, "opcode syntax error" ) - FT_ERRORDEF_( Stack_Underflow, 0xA1, \ + FT_ERRORDEF_( Stack_Underflow, 0xA1, "argument stack underflow" ) - FT_ERRORDEF_( Ignore, 0xA2, \ + FT_ERRORDEF_( Ignore, 0xA2, "ignore" ) - FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \ + FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, "no Unicode glyph name found" ) - FT_ERRORDEF_( Glyph_Too_Big, 0xA4, \ - "glyph to big for hinting" ) + FT_ERRORDEF_( Glyph_Too_Big, 0xA4, + "glyph too big for hinting" ) /* BDF errors */ - FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, "`STARTFONT' field missing" ) - FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ + FT_ERRORDEF_( Missing_Font_Field, 0xB1, "`FONT' field missing" ) - FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ + FT_ERRORDEF_( Missing_Size_Field, 0xB2, "`SIZE' field missing" ) - FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, \ + FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, "`FONTBOUNDINGBOX' field missing" ) - FT_ERRORDEF_( Missing_Chars_Field, 0xB4, \ + FT_ERRORDEF_( Missing_Chars_Field, 0xB4, "`CHARS' field missing" ) - FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, \ + FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, "`STARTCHAR' field missing" ) - FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, \ + FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, "`ENCODING' field missing" ) - FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, \ + FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, "`BBX' field missing" ) - FT_ERRORDEF_( Bbx_Too_Big, 0xB8, \ + FT_ERRORDEF_( Bbx_Too_Big, 0xB8, "`BBX' too big" ) - FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, \ + FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, "Font header corrupted or missing fields" ) - FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, \ + FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, "Font glyphs corrupted or missing fields" ) + /* */ + /* END */ diff --git a/drivers/freetype/include/freetype/fterrors.h b/drivers/freetype/include/freetype/fterrors.h index 0fa3e4dce1..e15bfb001e 100644 --- a/drivers/freetype/include/freetype/fterrors.h +++ b/drivers/freetype/include/freetype/fterrors.h @@ -4,7 +4,7 @@ /* */ /* FreeType error code handling (specification). */ /* */ -/* Copyright 1996-2002, 2004, 2007, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,70 +18,98 @@ /*************************************************************************/ /* */ - /* This special header file is used to define the handling of FT2 */ - /* enumeration constants. It can also be used to generate error message */ - /* strings with a small macro trick explained below. */ + /* <Section> */ + /* error_enumerations */ /* */ - /* I - Error Formats */ - /* ----------------- */ + /* <Title> */ + /* Error Enumerations */ + /* */ + /* <Abstract> */ + /* How to handle errors and error strings. */ + /* */ + /* <Description> */ + /* The header file `fterrors.h' (which is automatically included by */ + /* `freetype.h' defines the handling of FreeType's enumeration */ + /* constants. It can also be used to generate error message strings */ + /* with a small macro trick explained below. */ + /* */ + /* *Error* *Formats* */ /* */ /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ - /* defined in ftoption.h in order to make the higher byte indicate */ + /* defined in `ftoption.h' in order to make the higher byte indicate */ /* the module where the error has happened (this is not compatible */ - /* with standard builds of FreeType 2). See the file `ftmoderr.h' for */ - /* more details. */ + /* with standard builds of FreeType 2, however). See the file */ + /* `ftmoderr.h' for more details. */ /* */ + /* *Error* *Message* *Strings* */ /* */ - /* II - Error Message strings */ - /* -------------------------- */ - /* */ - /* The error definitions below are made through special macros that */ - /* allow client applications to build a table of error message strings */ - /* if they need it. The strings are not included in a normal build of */ - /* FreeType 2 to save space (most client applications do not use */ - /* them). */ + /* Error definitions are set up with special macros that allow client */ + /* applications to build a table of error message strings. The */ + /* strings are not included in a normal build of FreeType 2 to */ + /* save space (most client applications do not use them). */ /* */ /* To do so, you have to define the following macros before including */ - /* this file: */ + /* this file. */ /* */ - /* FT_ERROR_START_LIST :: */ - /* This macro is called before anything else to define the start of */ - /* the error list. It is followed by several FT_ERROR_DEF calls */ - /* (see below). */ + /* { */ + /* FT_ERROR_START_LIST */ + /* } */ /* */ - /* FT_ERROR_DEF( e, v, s ) :: */ - /* This macro is called to define one single error. */ - /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ - /* `v' is the error numerical value. */ - /* `s' is the corresponding error string. */ + /* This macro is called before anything else to define the start of */ + /* the error list. It is followed by several FT_ERROR_DEF calls. */ /* */ - /* FT_ERROR_END_LIST :: */ - /* This macro ends the list. */ + /* { */ + /* FT_ERROR_DEF( e, v, s ) */ + /* } */ /* */ - /* Additionally, you have to undefine __FTERRORS_H__ before #including */ + /* This macro is called to define one single error. `e' is the error */ + /* code identifier (e.g., `Invalid_Argument'), `v' is the error's */ + /* numerical value, and `s' is the corresponding error string. */ + /* */ + /* { */ + /* FT_ERROR_END_LIST */ + /* } */ + /* */ + /* This macro ends the list. */ + /* */ + /* Additionally, you have to undefine `FTERRORS_H_' before #including */ /* this file. */ /* */ - /* Here is a simple example: */ + /* Here is a simple example. */ /* */ + /* { */ + /* #undef FTERRORS_H_ */ + /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ + /* #define FT_ERROR_START_LIST { */ + /* #define FT_ERROR_END_LIST { 0, NULL } }; */ + /* */ + /* const struct */ /* { */ - /* #undef __FTERRORS_H__ */ - /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ - /* #define FT_ERROR_START_LIST { */ - /* #define FT_ERROR_END_LIST { 0, 0 } }; */ + /* int err_code; */ + /* const char* err_msg; */ + /* } ft_errors[] = */ /* */ - /* const struct */ - /* { */ - /* int err_code; */ - /* const char* err_msg; */ - /* } ft_errors[] = */ + /* #include FT_ERRORS_H */ + /* } */ /* */ - /* #include FT_ERRORS_H */ - /* } */ + /* Note that `FT_Err_Ok' is _not_ defined with `FT_ERRORDEF' but with */ + /* `FT_NOERRORDEF'; it is always zero. */ /* */ /*************************************************************************/ - -#ifndef __FTERRORS_H__ + /* */ + + /* In previous FreeType versions we used `__FTERRORS_H__'. However, */ + /* using two successive underscores in a non-system symbol name */ + /* violates the C (and C++) standard, so it was changed to the */ + /* current form. In spite of this, we have to make */ + /* */ + /* #undefine __FTERRORS_H__ */ + /* */ + /* work for backwards compatibility. */ + /* */ +#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) ) +#define FTERRORS_H_ #define __FTERRORS_H__ @@ -192,7 +220,7 @@ #undef FT_ERR_PREFIX #endif -#endif /* __FTERRORS_H__ */ +#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */ /* END */ diff --git a/drivers/freetype/include/freetype/ftfntfmt.h b/drivers/freetype/include/freetype/ftfntfmt.h new file mode 100644 index 0000000000..bd423247bb --- /dev/null +++ b/drivers/freetype/include/freetype/ftfntfmt.h @@ -0,0 +1,95 @@ +/***************************************************************************/ +/* */ +/* ftfntfmt.h */ +/* */ +/* Support functions for font formats. */ +/* */ +/* Copyright 2002-2016 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 FTFNTFMT_H_ +#define FTFNTFMT_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* font_formats */ + /* */ + /* <Title> */ + /* Font Formats */ + /* */ + /* <Abstract> */ + /* Getting the font format. */ + /* */ + /* <Description> */ + /* 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, in spite of FreeType's uniform API. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Font_Format */ + /* */ + /* <Description> */ + /* Return a string describing the format of a given face. Possible */ + /* values are `TrueType', `Type~1', `BDF', `PCF', `Type~42', */ + /* `CID~Type~1', `CFF', `PFR', and `Windows~FNT'. */ + /* */ + /* The return value is suitable to be used as an X11 FONT_PROPERTY. */ + /* */ + /* <Input> */ + /* face :: */ + /* Input face handle. */ + /* */ + /* <Return> */ + /* Font format string. NULL in case of error. */ + /* */ + /* <Note> */ + /* A deprecated name for the same function is */ + /* `FT_Get_X11_Font_Format'. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Font_Format( FT_Face face ); + + + /* deprecated */ + FT_EXPORT( const char* ) + FT_Get_X11_Font_Format( FT_Face face ); + + + /* */ + + +FT_END_HEADER + +#endif /* FTFNTFMT_H_ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/ftgasp.h b/drivers/freetype/include/freetype/ftgasp.h index 453d4fa42c..3f5b3bc695 100644 --- a/drivers/freetype/include/freetype/ftgasp.h +++ b/drivers/freetype/include/freetype/ftgasp.h @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (specification). */ /* */ -/* Copyright 2007, 2008, 2011 by */ +/* Copyright 2007-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef _FT_GASP_H_ -#define _FT_GASP_H_ +#ifndef FTGASP_H_ +#define FTGASP_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -120,9 +120,10 @@ FT_Get_Gasp( FT_Face face, FT_UInt ppem ); -/* */ + /* */ -#endif /* _FT_GASP_H_ */ + +#endif /* FTGASP_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftglyph.h b/drivers/freetype/include/freetype/ftglyph.h index 31dc33187d..d9840a81fc 100644 --- a/drivers/freetype/include/freetype/ftglyph.h +++ b/drivers/freetype/include/freetype/ftglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (specification). */ /* */ -/* Copyright 1996-2003, 2006, 2008, 2009, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,8 +29,8 @@ /*************************************************************************/ -#ifndef __FTGLYPH_H__ -#define __FTGLYPH_H__ +#ifndef FTGLYPH_H_ +#define FTGLYPH_H_ #include <ft2build.h> @@ -325,22 +325,8 @@ FT_BEGIN_HEADER } FT_Glyph_BBox_Mode; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_glyph_bbox_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated. Use the corresponding */ - /* @FT_Glyph_BBox_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_glyph_bbox_unscaled :: See @FT_GLYPH_BBOX_UNSCALED. */ - /* ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS. */ - /* ft_glyph_bbox_gridfit :: See @FT_GLYPH_BBOX_GRIDFIT. */ - /* ft_glyph_bbox_truncate :: See @FT_GLYPH_BBOX_TRUNCATE. */ - /* ft_glyph_bbox_pixels :: See @FT_GLYPH_BBOX_PIXELS. */ - /* */ + /* these constants are deprecated; use the corresponding */ + /* `FT_Glyph_BBox_Mode' values instead */ #define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED #define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS #define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT @@ -358,17 +344,17 @@ FT_BEGIN_HEADER /* outline's points, including Bézier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bézier outside arcs). */ + /* that contains Bézier outside arcs). */ /* */ /* Computing the control box is very fast, while getting the bounding */ /* box can take much more time as it needs to walk over all segments */ /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ + /* `ftbbox' component, which is dedicated to this single task. */ /* */ /* <Input> */ /* glyph :: A handle to the source glyph object. */ /* */ - /* mode :: The mode which indicates how to interpret the returned */ + /* mode :: The mode that indicates how to interpret the returned */ /* bounding box values. */ /* */ /* <Output> */ @@ -388,7 +374,7 @@ FT_BEGIN_HEADER /* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */ /* reasonable values for the CBox it is necessary to load the glyph */ /* at a large ppem value (so that the hinting instructions can */ - /* properly shift and scale the subglyphs), then extracting the CBox */ + /* properly shift and scale the subglyphs), then extracting the CBox, */ /* which can be eventually converted back to font units. */ /* */ /* Note that the maximum coordinates are exclusive, which means that */ @@ -603,13 +589,12 @@ FT_BEGIN_HEADER FT_EXPORT( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ); - /* */ FT_END_HEADER -#endif /* __FTGLYPH_H__ */ +#endif /* FTGLYPH_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftgxval.h b/drivers/freetype/include/freetype/ftgxval.h index 497015c101..a58e86a040 100644 --- a/drivers/freetype/include/freetype/ftgxval.h +++ b/drivers/freetype/include/freetype/ftgxval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTypeGX/AAT tables (specification). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO, Redhat K.K, */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __FTGXVAL_H__ -#define __FTGXVAL_H__ +#ifndef FTGXVAL_H_ +#define FTGXVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -57,9 +57,19 @@ FT_BEGIN_HEADER /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ /* trak, prop, lcar). */ /* */ + /* <Order> */ + /* FT_TrueTypeGX_Validate */ + /* FT_TrueTypeGX_Free */ + /* */ + /* FT_ClassicKern_Validate */ + /* FT_ClassicKern_Free */ + /* */ + /* FT_VALIDATE_GX_LENGTH */ + /* FT_VALIDATE_GXXXX */ + /* FT_VALIDATE_CKERNXXX */ + /* */ /*************************************************************************/ - /*************************************************************************/ /* */ /* */ @@ -171,8 +181,6 @@ FT_BEGIN_HEADER FT_VALIDATE_lcar ) - /* */ - /********************************************************************** * * @function: @@ -180,7 +188,7 @@ FT_BEGIN_HEADER * * @description: * Validate various TrueTypeGX tables to assure that all offsets and - * indices are valid. The idea is that a higher-level library which + * indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without * error checking (which can be quite time consuming). * @@ -189,7 +197,7 @@ FT_BEGIN_HEADER * A handle to the input face. * * validation_flags :: - * A bit field which specifies the tables to be validated. See + * A bit field that specifies the tables to be validated. See * @FT_VALIDATE_GXXXX for possible values. * * table_length :: @@ -221,8 +229,6 @@ FT_BEGIN_HEADER FT_UInt table_length ); - /* */ - /********************************************************************** * * @function: @@ -248,8 +254,6 @@ FT_BEGIN_HEADER FT_Bytes table ); - /* */ - /********************************************************************** * * @enum: @@ -277,8 +281,6 @@ FT_BEGIN_HEADER #define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) - /* */ - /********************************************************************** * * @function: @@ -286,7 +288,7 @@ FT_BEGIN_HEADER * * @description: * Validate classic (16-bit format) kern table to assure that the offsets - * and indices are valid. The idea is that a higher-level library which + * and indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without error * checking (which can be quite time consuming). * @@ -299,7 +301,7 @@ FT_BEGIN_HEADER * A handle to the input face. * * validation_flags :: - * A bit field which specifies the dialect to be validated. See + * A bit field that specifies the dialect to be validated. See * @FT_VALIDATE_CKERNXXX for possible values. * * @output: @@ -320,8 +322,6 @@ FT_BEGIN_HEADER FT_Bytes *ckern_table ); - /* */ - /********************************************************************** * * @function: @@ -346,13 +346,12 @@ FT_BEGIN_HEADER FT_ClassicKern_Free( FT_Face face, FT_Bytes table ); - - /* */ + /* */ FT_END_HEADER -#endif /* __FTGXVAL_H__ */ +#endif /* FTGXVAL_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftgzip.h b/drivers/freetype/include/freetype/ftgzip.h index acbc4f0327..3932ce6887 100644 --- a/drivers/freetype/include/freetype/ftgzip.h +++ b/drivers/freetype/include/freetype/ftgzip.h @@ -4,7 +4,7 @@ /* */ /* Gzip-compressed stream support. */ /* */ -/* Copyright 2002, 2003, 2004, 2006 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTGZIP_H__ -#define __FTGZIP_H__ +#ifndef FTGZIP_H_ +#define FTGZIP_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -91,12 +91,58 @@ FT_BEGIN_HEADER FT_Stream_OpenGzip( FT_Stream stream, FT_Stream source ); - /* */ + + /************************************************************************ + * + * @function: + * FT_Gzip_Uncompress + * + * @description: + * Decompress a zipped input buffer into an output buffer. This function + * is modeled after zlib's `uncompress' function. + * + * @input: + * memory :: + * A FreeType memory handle. + * + * input :: + * The input buffer. + * + * input_len :: + * The length of the input buffer. + * + * @output: + * output:: + * The output buffer. + * + * @inout: + * output_len :: + * Before calling the function, this is the total size of the output + * buffer, which must be large enough to hold the entire uncompressed + * data (so the size of the uncompressed data must be known in + * advance). After calling the function, `output_len' is the size of + * the used data in `output'. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Gzip_Uncompress( FT_Memory memory, + FT_Byte* output, + FT_ULong* output_len, + const FT_Byte* input, + FT_ULong input_len ); + + /* */ FT_END_HEADER -#endif /* __FTGZIP_H__ */ +#endif /* FTGZIP_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftimage.h b/drivers/freetype/include/freetype/ftimage.h index 3b826b1d32..28b2704e80 100644 --- a/drivers/freetype/include/freetype/ftimage.h +++ b/drivers/freetype/include/freetype/ftimage.h @@ -5,7 +5,7 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,12 +24,12 @@ /*************************************************************************/ -#ifndef __FTIMAGE_H__ -#define __FTIMAGE_H__ +#ifndef FTIMAGE_H_ +#define FTIMAGE_H_ - /* _STANDALONE_ is from ftgrays.c */ -#ifndef _STANDALONE_ + /* STANDALONE_ is from ftgrays.c */ +#ifndef STANDALONE_ #include <ft2build.h> #endif @@ -193,67 +193,14 @@ FT_BEGIN_HEADER } FT_Pixel_Mode; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_pixel_mode_xxx */ - /* */ - /* <Description> */ - /* A list of deprecated constants. Use the corresponding */ - /* @FT_Pixel_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_pixel_mode_none :: See @FT_PIXEL_MODE_NONE. */ - /* ft_pixel_mode_mono :: See @FT_PIXEL_MODE_MONO. */ - /* ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY. */ - /* ft_pixel_mode_pal2 :: See @FT_PIXEL_MODE_GRAY2. */ - /* ft_pixel_mode_pal4 :: See @FT_PIXEL_MODE_GRAY4. */ - /* */ + /* these constants are deprecated; use the corresponding `FT_Pixel_Mode' */ + /* values instead. */ #define ft_pixel_mode_none FT_PIXEL_MODE_NONE #define ft_pixel_mode_mono FT_PIXEL_MODE_MONO #define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY #define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 #define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 - /* */ - -#if 0 - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Palette_Mode */ - /* */ - /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT! */ - /* */ - /* An enumeration type to describe the format of a bitmap palette, */ - /* used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ - /* */ - /* <Values> */ - /* ft_palette_mode_rgb :: The palette is an array of 3-byte RGB */ - /* records. */ - /* */ - /* ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA */ - /* records. */ - /* */ - /* <Note> */ - /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ - /* FreeType, these types are not handled by the library itself. */ - /* */ - typedef enum FT_Palette_Mode_ - { - ft_palette_mode_rgb = 0, - ft_palette_mode_rgba, - - ft_palette_mode_max /* do not remove */ - - } FT_Palette_Mode; - - /* */ - -#endif - /*************************************************************************/ /* */ @@ -311,20 +258,15 @@ FT_BEGIN_HEADER /* field is intended for paletted pixel modes. Not */ /* used currently. */ /* */ - /* <Note> */ - /* For now, the only pixel modes supported by FreeType are mono and */ - /* grays. However, drivers might be added in the future to support */ - /* more `colorful' options. */ - /* */ typedef struct FT_Bitmap_ { - int rows; - int width; + unsigned int rows; + unsigned int width; int pitch; unsigned char* buffer; - short num_grays; - char pixel_mode; - char palette_mode; + unsigned short num_grays; + unsigned char pixel_mode; + unsigned char palette_mode; void* palette; } FT_Bitmap; @@ -381,7 +323,7 @@ FT_BEGIN_HEADER /* */ /* flags :: A set of bit flags used to characterize the outline */ /* and give hints to the scan-converter and hinter on */ - /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ + /* how to convert/grid-fit it. See @FT_OUTLINE_XXX. */ /* */ /* <Note> */ /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ @@ -402,6 +344,8 @@ FT_BEGIN_HEADER } FT_Outline; + /* */ + /* Following limits must be consistent with */ /* FT_Outline.{n_contours,n_points} */ #define FT_OUTLINE_CONTOURS_MAX SHRT_MAX @@ -411,7 +355,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Enum> */ - /* FT_OUTLINE_FLAGS */ + /* FT_OUTLINE_XXX */ /* */ /* <Description> */ /* A list of bit-field constants use for the flags in an outline's */ @@ -492,24 +436,8 @@ FT_BEGIN_HEADER #define FT_OUTLINE_SINGLE_PASS 0x200 - /************************************************************************* - * - * @enum: - * ft_outline_flags - * - * @description: - * These constants are deprecated. Please use the corresponding - * @FT_OUTLINE_FLAGS values. - * - * @values: - * ft_outline_none :: See @FT_OUTLINE_NONE. - * ft_outline_owner :: See @FT_OUTLINE_OWNER. - * ft_outline_even_odd_fill :: See @FT_OUTLINE_EVEN_ODD_FILL. - * ft_outline_reverse_fill :: See @FT_OUTLINE_REVERSE_FILL. - * ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS. - * ft_outline_high_precision :: See @FT_OUTLINE_HIGH_PRECISION. - * ft_outline_single_pass :: See @FT_OUTLINE_SINGLE_PASS. - */ + /* these constants are deprecated; use the corresponding */ + /* `FT_OUTLINE_XXX' values instead */ #define ft_outline_none FT_OUTLINE_NONE #define ft_outline_owner FT_OUTLINE_OWNER #define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL @@ -555,7 +483,7 @@ FT_BEGIN_HEADER /* <Input> */ /* to :: A pointer to the target point of the `move to'. */ /* */ - /* user :: A typeless pointer which is passed from the caller of the */ + /* user :: A typeless pointer, which is passed from the caller of the */ /* decomposition function. */ /* */ /* <Return> */ @@ -582,7 +510,7 @@ FT_BEGIN_HEADER /* <Input> */ /* to :: A pointer to the target point of the `line to'. */ /* */ - /* user :: A typeless pointer which is passed from the caller of the */ + /* user :: A typeless pointer, which is passed from the caller of the */ /* decomposition function. */ /* */ /* <Return> */ @@ -613,7 +541,7 @@ FT_BEGIN_HEADER /* */ /* to :: A pointer to the target end point of the conic arc. */ /* */ - /* user :: A typeless pointer which is passed from the caller of */ + /* user :: A typeless pointer, which is passed from the caller of */ /* the decomposition function. */ /* */ /* <Return> */ @@ -645,7 +573,7 @@ FT_BEGIN_HEADER /* */ /* to :: A pointer to the target end point. */ /* */ - /* user :: A typeless pointer which is passed from the caller of */ + /* user :: A typeless pointer, which is passed from the caller of */ /* the decomposition function. */ /* */ /* <Return> */ @@ -796,22 +724,8 @@ FT_BEGIN_HEADER } FT_Glyph_Format; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_glyph_format_xxx */ - /* */ - /* <Description> */ - /* A list of deprecated constants. Use the corresponding */ - /* @FT_Glyph_Format values instead. */ - /* */ - /* <Values> */ - /* ft_glyph_format_none :: See @FT_GLYPH_FORMAT_NONE. */ - /* ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE. */ - /* ft_glyph_format_bitmap :: See @FT_GLYPH_FORMAT_BITMAP. */ - /* ft_glyph_format_outline :: See @FT_GLYPH_FORMAT_OUTLINE. */ - /* ft_glyph_format_plotter :: See @FT_GLYPH_FORMAT_PLOTTER. */ - /* */ + /* these constants are deprecated; use the corresponding */ + /* `FT_Glyph_Format' values instead. */ #define ft_glyph_format_none FT_GLYPH_FORMAT_NONE #define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE #define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP @@ -833,11 +747,11 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* A raster is a scan converter, in charge of rendering an outline into */ - /* a a bitmap. This section contains the public API for rasters. */ + /* a bitmap. This section contains the public API for rasters. */ /* */ /* Note that in FreeType 2, all rasters are now encapsulated within */ - /* specific modules called `renderers'. See `freetype/ftrender.h' for */ - /* more details on renderers. */ + /* specific modules called `renderers'. See `ftrender.h' for more */ + /* details on renderers. */ /* */ /*************************************************************************/ @@ -856,6 +770,21 @@ FT_BEGIN_HEADER /* <Description> */ /* This section contains technical definitions. */ /* */ + /* <Order> */ + /* FT_Raster */ + /* FT_Span */ + /* FT_SpanFunc */ + /* */ + /* FT_Raster_Params */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* FT_Raster_NewFunc */ + /* FT_Raster_DoneFunc */ + /* FT_Raster_ResetFunc */ + /* FT_Raster_SetModeFunc */ + /* FT_Raster_RenderFunc */ + /* FT_Raster_Funcs */ + /* */ /*************************************************************************/ @@ -865,8 +794,8 @@ FT_BEGIN_HEADER /* FT_Raster */ /* */ /* <Description> */ - /* A handle (pointer) to a raster object. Each object can be used */ - /* independently to convert an outline into a bitmap or pixmap. */ + /* An opaque handle (pointer) to a raster object. Each object can be */ + /* used independently to convert an outline into a bitmap or pixmap. */ /* */ typedef struct FT_RasterRec_* FT_Raster; @@ -877,8 +806,8 @@ FT_BEGIN_HEADER /* FT_Span */ /* */ /* <Description> */ - /* A structure used to model a single span of gray (or black) pixels */ - /* when rendering a monochrome or anti-aliased bitmap. */ + /* A structure used to model a single span of gray pixels when */ + /* rendering an anti-aliased bitmap. */ /* */ /* <Fields> */ /* x :: The span's horizontal start position. */ @@ -886,13 +815,12 @@ FT_BEGIN_HEADER /* len :: The span's length in pixels. */ /* */ /* coverage :: The span color/coverage, ranging from 0 (background) */ - /* to 255 (foreground). Only used for anti-aliased */ - /* rendering. */ + /* to 255 (foreground). */ /* */ /* <Note> */ /* This structure is used by the span drawing callback type named */ - /* @FT_SpanFunc which takes the y~coordinate of the span as a */ - /* a parameter. */ + /* @FT_SpanFunc that takes the y~coordinate of the span as a */ + /* parameter. */ /* */ /* The coverage value is always between 0 and 255. If you want less */ /* gray values, the callback function has to reduce them. */ @@ -957,22 +885,7 @@ FT_BEGIN_HEADER /* FT_Raster_BitTest_Func */ /* */ /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to test whether a given target pixel is already set to the drawing */ - /* `color'. These tests are crucial to implement drop-out control */ - /* per-se the TrueType spec. */ - /* */ - /* <Input> */ - /* y :: The pixel's y~coordinate. */ - /* */ - /* x :: The pixel's x~coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* <Return> */ - /* 1~if the pixel is `set', 0~otherwise. */ + /* Deprecated, unimplemented. */ /* */ typedef int (*FT_Raster_BitTest_Func)( int y, @@ -986,21 +899,7 @@ FT_BEGIN_HEADER /* FT_Raster_BitSet_Func */ /* */ /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to set an individual target pixel. This is crucial to implement */ - /* drop-out control according to the TrueType specification. */ - /* */ - /* <Input> */ - /* y :: The pixel's y~coordinate. */ - /* */ - /* x :: The pixel's x~coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* <Return> */ - /* 1~if the pixel is `set', 0~otherwise. */ + /* Deprecated, unimplemented. */ /* */ typedef void (*FT_Raster_BitSet_Func)( int y, @@ -1034,8 +933,8 @@ FT_BEGIN_HEADER /* pixmap's buffer _must_ be zeroed before */ /* rendering. */ /* */ - /* Note that for now, direct rendering is */ - /* only possible with anti-aliased glyphs. */ + /* Direct rendering is only possible with */ + /* anti-aliased glyphs. */ /* */ /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ /* rendering mode. If set, the output will */ @@ -1053,7 +952,8 @@ FT_BEGIN_HEADER #define FT_RASTER_FLAG_DIRECT 0x2 #define FT_RASTER_FLAG_CLIP 0x4 - /* deprecated */ + /* these constants are deprecated; use the corresponding */ + /* `FT_RASTER_FLAG_XXX' values instead */ #define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT #define ft_raster_flag_aa FT_RASTER_FLAG_AA #define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT @@ -1079,11 +979,11 @@ FT_BEGIN_HEADER /* */ /* gray_spans :: The gray span drawing callback. */ /* */ - /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ + /* black_spans :: Unused. */ /* */ - /* bit_test :: The bit test callback. UNIMPLEMENTED! */ + /* bit_test :: Unused. */ /* */ - /* bit_set :: The bit set callback. UNIMPLEMENTED! */ + /* bit_set :: Unused. */ /* */ /* user :: User-supplied data that is passed to each drawing */ /* callback. */ @@ -1100,15 +1000,9 @@ FT_BEGIN_HEADER /* */ /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ /* raster will call the `gray_spans' callback to draw gray pixel */ - /* spans, in the case of an aa glyph bitmap, it will call */ - /* `black_spans', and `bit_test' and `bit_set' in the case of a */ - /* monochrome bitmap. This allows direct composition over a */ - /* pre-existing bitmap through user-provided callbacks to perform the */ - /* span drawing/composition. */ - /* */ - /* Note that the `bit_test' and `bit_set' callbacks are required when */ - /* rendering a monochrome bitmap, as they are crucial to implement */ - /* correct drop-out control as defined in the TrueType specification. */ + /* spans. This allows direct composition over a pre-existing bitmap */ + /* through user-provided callbacks to perform the span drawing and */ + /* composition. Not supported by the monochrome rasterizer. */ /* */ typedef struct FT_Raster_Params_ { @@ -1116,9 +1010,9 @@ FT_BEGIN_HEADER const void* source; int flags; FT_SpanFunc gray_spans; - FT_SpanFunc black_spans; /* doesn't work! */ - FT_Raster_BitTest_Func bit_test; /* doesn't work! */ - FT_Raster_BitSet_Func bit_set; /* doesn't work! */ + FT_SpanFunc black_spans; /* unused */ + FT_Raster_BitTest_Func bit_test; /* unused */ + FT_Raster_BitSet_Func bit_set; /* unused */ void* user; FT_BBox clip_box; @@ -1179,10 +1073,10 @@ FT_BEGIN_HEADER /* FT_Raster_ResetFunc */ /* */ /* <Description> */ - /* FreeType provides an area of memory called the `render pool', */ - /* available to all registered rasters. This pool can be freely used */ - /* during a given scan-conversion but is shared by all rasters. Its */ - /* content is thus transient. */ + /* FreeType used to provide an area of memory called the `render */ + /* pool' available to all registered rasters. This was not thread */ + /* safe however and now FreeType never allocates this pool. NULL */ + /* is always passed in as pool_base. */ /* */ /* This function is called each time the render pool changes, or just */ /* after a new raster object is created. */ @@ -1195,10 +1089,9 @@ FT_BEGIN_HEADER /* pool_size :: The size in bytes of the render pool. */ /* */ /* <Note> */ - /* Rasters can ignore the render pool and rely on dynamic memory */ + /* Rasters should ignore the render pool and rely on dynamic or stack */ /* allocation if they want to (a handle to the memory allocator is */ - /* passed to the raster constructor). However, this is not */ - /* recommended for efficiency purposes. */ + /* passed to the raster constructor). */ /* */ typedef void (*FT_Raster_ResetFunc)( FT_Raster raster, @@ -1265,7 +1158,7 @@ FT_BEGIN_HEADER /* XXX: For now, the standard raster doesn't support direct */ /* composition but this should change for the final release (see */ /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ - /* for examples of distinct implementations which support direct */ + /* for examples of distinct implementations that support direct */ /* composition). */ /* */ typedef int @@ -1305,13 +1198,12 @@ FT_BEGIN_HEADER } FT_Raster_Funcs; - /* */ FT_END_HEADER -#endif /* __FTIMAGE_H__ */ +#endif /* FTIMAGE_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftincrem.h b/drivers/freetype/include/freetype/ftincrem.h index aaf689ff16..46b58b7917 100644 --- a/drivers/freetype/include/freetype/ftincrem.h +++ b/drivers/freetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002, 2003, 2006, 2007, 2008, 2010 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTINCREM_H__ -#define __FTINCREM_H__ +#ifndef FTINCREM_H_ +#define FTINCREM_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -45,7 +45,7 @@ FT_BEGIN_HEADER * @description: * This section contains various functions used to perform so-called * `incremental' glyph loading. This is a mode where all glyphs loaded - * from a given @FT_Face are provided by the client application, + * from a given @FT_Face are provided by the client application. * * Apart from that, all other tables are loaded normally from the font * file. This mode is useful when FreeType is used within another @@ -345,9 +345,10 @@ FT_BEGIN_HEADER /* */ + FT_END_HEADER -#endif /* __FTINCREM_H__ */ +#endif /* FTINCREM_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftlcdfil.h b/drivers/freetype/include/freetype/ftlcdfil.h index 8b253f118b..e06a8957f5 100644 --- a/drivers/freetype/include/freetype/ftlcdfil.h +++ b/drivers/freetype/include/freetype/ftlcdfil.h @@ -5,7 +5,7 @@ /* FreeType API for color filtering of subpixel bitmap glyphs */ /* (specification). */ /* */ -/* Copyright 2006, 2007, 2008, 2010 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FT_LCD_FILTER_H__ -#define __FT_LCD_FILTER_H__ +#ifndef FTLCDFIL_H_ +#define FTLCDFIL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -41,56 +41,91 @@ FT_BEGIN_HEADER * LCD Filtering * * @abstract: - * Reduce color fringes of LCD-optimized bitmaps. + * Reduce color fringes of subpixel-rendered 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. + * Subpixel rendering exploits the color-striped structure of LCD + * pixels, increasing the available resolution in the direction of the + * stripe (usually horizontal RGB) by a factor of~3. Since these + * subpixels are color pixels, using them unfiltered creates severe + * color fringes. Use the @FT_Library_SetLcdFilter API to specify a + * low-pass filter, which is then applied to subpixel-rendered bitmaps + * generated through @FT_Render_Glyph. The filter sacrifices some of + * the higher resolution to reduce color fringes, making the glyph image + * slightly blurrier. Positional improvements will remain. * * 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. - * - * FreeType generates alpha coverage maps, which are linear by nature. - * For instance, the value 0x80 in bitmap representation means that - * (within numerical precision) 0x80/0xff fraction of that pixel is - * covered by the glyph's outline. The blending function for placing - * text over a background is - * - * { - * dst = alpha * src + (1 - alpha) * dst , - * } - * - * which is known as OVER. However, when calculating the output of the - * OVER operator, the source colors should first be transformed to a - * linear color space, then alpha blended in that space, and transformed - * back to the output color space. - * - * When linear light blending is used, the default FIR5 filtering - * weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as - * they have been designed for black on white rendering while lacking - * gamma correction. To preserve color neutrality, weights for a FIR5 - * filter should be chosen according to two free parameters `a' and `c', - * and the FIR weights should be - * - * { - * [a - c, a + c, 2 * a, a + c, a - c] . - * } - * - * This formula generates equal weights for all the color primaries - * across the filter kernel, which makes it colorless. One suggested - * set of weights is - * - * { - * [0x10, 0x50, 0x60, 0x50, 0x10] , - * } - * - * where `a' has value 0x30 and `b' value 0x20. The weights in filter - * may have a sum larger than 0x100, which increases coloration slightly - * but also improves contrast. + * in order to activate it and explicitly call @FT_Library_SetLcdFilter + * to enable it. + * + * A filter should have two properties: + * + * 1) It should be normalized, meaning the sum of the 5~components + * should be 256 (0x100). It is possible to go above or under this + * target sum, however: going under means tossing out contrast, going + * over means invoking clamping and thereby non-linearities that + * increase contrast somewhat at the expense of greater distortion + * and color-fringing. Contrast is better enhanced through stem + * darkening. + * + * 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' + * where a~+ b~=~c. It distributes the computed coverage for one + * subpixel to all subpixels equally, sacrificing some won resolution + * but drastically reducing color-fringing. Positioning improvements + * remain! Note that color-fringing can only really be minimized + * when using a color-balanced filter and alpha-blending the glyph + * onto a surface in linear space; see @FT_Render_Glyph. + * + * Regarding the form, a filter can be a `boxy' filter or a `beveled' + * filter. Boxy filters are sharper but are less forgiving of non-ideal + * gamma curves of a screen (viewing angles!), beveled filters are + * fuzzier but more tolerant. + * + * Examples: + * + * - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor + * normalized. + * + * - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not + * normalized. + * + * - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not + * balanced. + * + * - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not + * balanced. + * + * - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost + * balanced. + * + * - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost + * balanced. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @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 wider or taller than the dimensions of the corresponding + * outline with regard to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and + * 3~subpixels to the right. The bitmap offset values are adjusted + * accordingly, so clients shouldn't need to modify their layout and + * glyph positioning code when enabling the filter. + * + * It is important to understand that linear alpha blending and gamma + * correction is critical for correctly rendering glyphs onto surfaces + * without artifacts and even more critical when subpixel rendering is + * involved. + * + * Each of the 3~alpha values (subpixels) is independently used to blend + * one color channel. That is, red alpha blends the red channel of the + * text color with the red channel of the background pixel. The + * distribution of density values by the color-balanced filter assumes + * alpha blending is done in linear space; only then color artifacts + * cancel out. */ @@ -111,10 +146,23 @@ FT_BEGIN_HEADER * The default filter reduces color fringes considerably, at the cost * of a slight blurriness in the output. * + * It is a beveled, normalized, and color-balanced five-tap filter + * that is more forgiving to screens with non-ideal gamma curves and + * viewing angles. Note that while color-fringing is reduced, it can + * only be minimized by using linear alpha blending and gamma + * correction to render glyphs onto surfaces. The default filter + * weights are [0x08 0x4D 0x56 0x4D 0x08]. + * * 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. + * The light filter is a variant that is sharper at the cost of + * slightly more color fringes than the default one. + * + * It is a boxy, normalized, and color-balanced three-tap filter that + * is less forgiving to screens with non-ideal gamma curves and + * viewing angles. This filter works best when the rendering system + * uses linear alpha blending and gamma correction to render glyphs + * onto surfaces. The light filter weights are + * [0x00 0x55 0x56 0x55 0x00]. * * FT_LCD_FILTER_LEGACY :: * This filter corresponds to the original libXft color filter. It @@ -126,14 +174,23 @@ FT_BEGIN_HEADER * This filter is only provided for comparison purposes, and might be * disabled or stay unsupported in the future. * + * FT_LCD_FILTER_LEGACY1 :: + * For historical reasons, the FontConfig library returns a different + * enumeration value for legacy LCD filtering. To make code work that + * (incorrectly) forwards FontConfig's enumeration value to + * @FT_Library_SetLcdFilter without proper mapping, it is thus easiest + * to have another enumeration value, which is completely equal to + * `FT_LCD_FILTER_LEGACY'. + * * @since: - * 2.3.0 + * 2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2) */ typedef enum FT_LcdFilter_ { FT_LCD_FILTER_NONE = 0, FT_LCD_FILTER_DEFAULT = 1, FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY1 = 3, FT_LCD_FILTER_LEGACY = 16, FT_LCD_FILTER_MAX /* do not remove */ @@ -176,22 +233,6 @@ FT_BEGIN_HEADER * 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 */ @@ -206,11 +247,8 @@ FT_BEGIN_HEADER * FT_Library_SetLcdFilterWeights * * @description: - * Use this function to override the filter weights selected by - * @FT_Library_SetLcdFilter. By default, FreeType uses the quintuple - * (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10, - * 0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and - * FT_LCD_FILTER_LEGACY. + * This function can be used to enable LCD filter with custom weights, + * instead of using presets in @FT_Library_SetLcdFilter. * * @input: * library :: @@ -230,9 +268,6 @@ FT_BEGIN_HEADER * defined in your build of the library, which should correspond to all * default builds of FreeType. * - * This function must be called after @FT_Library_SetLcdFilter to have - * any effect. - * * @since: * 2.4.0 */ @@ -245,7 +280,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_LCD_FILTER_H__ */ +#endif /* FTLCDFIL_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftlist.h b/drivers/freetype/include/freetype/ftlist.h index bb6f7f119d..82f437ac61 100644 --- a/drivers/freetype/include/freetype/ftlist.h +++ b/drivers/freetype/include/freetype/ftlist.h @@ -4,7 +4,7 @@ /* */ /* Generic list support for FreeType (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2007, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +24,8 @@ /*************************************************************************/ -#ifndef __FTLIST_H__ -#define __FTLIST_H__ +#ifndef FTLIST_H_ +#define FTLIST_H_ #include <ft2build.h> @@ -173,7 +173,7 @@ FT_BEGIN_HEADER /* FT_List_Iterator */ /* */ /* <Description> */ - /* An FT_List iterator function which is called during a list parse */ + /* An FT_List iterator function that is called during a list parse */ /* by @FT_List_Iterate. */ /* */ /* <Input> */ @@ -200,7 +200,7 @@ FT_BEGIN_HEADER /* <Input> */ /* list :: A handle to the list. */ /* iterator :: An iterator function, called on each node of the list. */ - /* user :: A user-supplied field which is passed as the second */ + /* user :: A user-supplied field that is passed as the second */ /* argument to the iterator. */ /* */ /* <Return> */ @@ -218,7 +218,7 @@ FT_BEGIN_HEADER /* FT_List_Destructor */ /* */ /* <Description> */ - /* An @FT_List iterator function which is called during a list */ + /* An @FT_List iterator function that is called during a list */ /* finalization by @FT_List_Finalize to destroy all elements in a */ /* given list. */ /* */ @@ -248,11 +248,11 @@ FT_BEGIN_HEADER /* list :: A handle to the list. */ /* */ /* destroy :: A list destructor that will be applied to each element */ - /* of the list. */ + /* of the list. Set this to NULL if not needed. */ /* */ - /* memory :: The current memory object which handles deallocation. */ + /* memory :: The current memory object that handles deallocation. */ /* */ - /* user :: A user-supplied field which is passed as the last */ + /* user :: A user-supplied field that is passed as the last */ /* argument to the destructor. */ /* */ /* <Note> */ @@ -265,13 +265,12 @@ FT_BEGIN_HEADER FT_Memory memory, void* user ); - /* */ FT_END_HEADER -#endif /* __FTLIST_H__ */ +#endif /* FTLIST_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftlzw.h b/drivers/freetype/include/freetype/ftlzw.h index 00d40169a7..582e2c1465 100644 --- a/drivers/freetype/include/freetype/ftlzw.h +++ b/drivers/freetype/include/freetype/ftlzw.h @@ -4,7 +4,7 @@ /* */ /* LZW-compressed stream support. */ /* */ -/* Copyright 2004, 2006 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTLZW_H__ -#define __FTLZW_H__ +#ifndef FTLZW_H_ +#define FTLZW_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -88,12 +88,12 @@ FT_BEGIN_HEADER FT_Stream_OpenLZW( FT_Stream stream, FT_Stream source ); - /* */ + /* */ FT_END_HEADER -#endif /* __FTLZW_H__ */ +#endif /* FTLZW_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftmac.h b/drivers/freetype/include/freetype/ftmac.h index ab5bab5170..adb15cadf3 100644 --- a/drivers/freetype/include/freetype/ftmac.h +++ b/drivers/freetype/include/freetype/ftmac.h @@ -4,7 +4,7 @@ /* */ /* Additional Mac-specific API. */ /* */ -/* Copyright 1996-2001, 2004, 2006, 2007 by */ +/* Copyright 1996-2016 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,15 +18,15 @@ /***************************************************************************/ /* */ -/* NOTE: Include this file after <freetype/freetype.h> and after any */ +/* NOTE: Include this file after FT_FREETYPE_H and after any */ /* Mac-specific headers (because this header uses Mac types such as */ /* Handle, FSSpec, FSRef, etc.) */ /* */ /***************************************************************************/ -#ifndef __FTMAC_H__ -#define __FTMAC_H__ +#ifndef FTMAC_H_ +#define FTMAC_H_ #include <ft2build.h> @@ -168,7 +168,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Return a pathname of the disk file and face index for given font */ - /* name which is handled by ATS framework. */ + /* name that is handled by ATS framework. */ /* */ /* <Input> */ /* fontName :: Mac OS name of the font in ATS framework. */ @@ -268,7 +268,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMAC_H__ */ +#endif /* FTMAC_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftmm.h b/drivers/freetype/include/freetype/ftmm.h index 3aefb9e4f2..6c05f0c390 100644 --- a/drivers/freetype/include/freetype/ftmm.h +++ b/drivers/freetype/include/freetype/ftmm.h @@ -4,7 +4,7 @@ /* */ /* FreeType Multiple Master font interface (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMM_H__ -#define __FTMM_H__ +#ifndef FTMM_H_ +#define FTMM_H_ #include <ft2build.h> @@ -95,8 +95,8 @@ FT_BEGIN_HEADER /* */ /* num_designs :: Number of designs; should be normally 2^num_axis */ /* even though the Type~1 specification strangely */ - /* allows for intermediate designs to be present. This */ - /* number cannot exceed~16. */ + /* allows for intermediate designs to be present. */ + /* This number cannot exceed~16. */ /* */ /* axis :: A table of axis descriptors. */ /* */ @@ -196,16 +196,20 @@ FT_BEGIN_HEADER /* number of designs). */ /* */ /* num_namedstyles :: The number of named styles; only meaningful for */ - /* GX which allows certain design coordinates to */ + /* GX that allows certain design coordinates to */ /* have a string ID (in the `name' table) */ /* associated with them. The font can tell the */ /* user that, for example, Weight=1.5 is `Bold'. */ /* */ - /* axis :: A table of axis descriptors. */ + /* axis :: An axis descriptor table. */ /* GX fonts contain slightly more data than MM. */ + /* Memory management of this pointer is done */ + /* internally by FreeType. */ /* */ - /* namedstyles :: A table of named styles. */ + /* namedstyle :: A named style table. */ /* Only meaningful with GX. */ + /* Memory management of this pointer is done */ + /* internally by FreeType. */ /* */ typedef struct FT_MM_Var_ { @@ -218,9 +222,6 @@ FT_BEGIN_HEADER } FT_MM_Var; - /* */ - - /*************************************************************************/ /* */ /* <Function> */ @@ -258,8 +259,8 @@ FT_BEGIN_HEADER /* */ /* <Output> */ /* amaster :: The Multiple Masters/GX var descriptor. */ - /* Allocates a data structure, which the user must free */ - /* (a single call to FT_FREE will do it). */ + /* Allocates a data structure, which the user must */ + /* deallocate with `free' after use. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -284,8 +285,10 @@ FT_BEGIN_HEADER /* face :: A handle to the source face. */ /* */ /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ /* */ /* coords :: An array of design coordinates. */ /* */ @@ -311,8 +314,10 @@ FT_BEGIN_HEADER /* face :: A handle to the source face. */ /* */ /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ /* */ /* coords :: An array of design coordinates. */ /* */ @@ -338,8 +343,10 @@ FT_BEGIN_HEADER /* face :: A handle to the source face. */ /* */ /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ /* */ /* coords :: The design coordinates array (each element must be */ /* between 0 and 1.0). */ @@ -366,13 +373,12 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); - /* */ FT_END_HEADER -#endif /* __FTMM_H__ */ +#endif /* FTMM_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftmodapi.h b/drivers/freetype/include/freetype/ftmodapi.h index 8abffb558f..b4d2758efa 100644 --- a/drivers/freetype/include/freetype/ftmodapi.h +++ b/drivers/freetype/include/freetype/ftmodapi.h @@ -4,7 +4,7 @@ /* */ /* FreeType modules public interface (specification). */ /* */ -/* Copyright 1996-2003, 2006, 2008-2010, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMODAPI_H__ -#define __FTMODAPI_H__ +#ifndef FTMODAPI_H_ +#define FTMODAPI_H_ #include <ft2build.h> @@ -63,7 +63,7 @@ FT_BEGIN_HEADER /* psaux */ /* pshinter */ /* psnames */ - /* raster1, raster5 */ + /* raster1 */ /* sfnt */ /* smooth, smooth-lcd, smooth-lcdv */ /* truetype */ @@ -75,6 +75,33 @@ FT_BEGIN_HEADER /* */ /* Note that the FreeType Cache sub-system is not a FreeType module. */ /* */ + /* <Order> */ + /* FT_Module */ + /* FT_Module_Constructor */ + /* FT_Module_Destructor */ + /* FT_Module_Requester */ + /* FT_Module_Class */ + /* */ + /* FT_Add_Module */ + /* FT_Get_Module */ + /* FT_Remove_Module */ + /* FT_Add_Default_Modules */ + /* */ + /* FT_Property_Set */ + /* FT_Property_Get */ + /* */ + /* FT_New_Library */ + /* FT_Done_Library */ + /* FT_Reference_Library */ + /* */ + /* FT_Renderer */ + /* FT_Renderer_Class */ + /* */ + /* FT_Get_Renderer */ + /* FT_Set_Renderer */ + /* */ + /* FT_Set_Debug_Hook */ + /* */ /*************************************************************************/ @@ -84,12 +111,14 @@ FT_BEGIN_HEADER #define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ #define FT_MODULE_STYLER 8 /* this module is a styler */ -#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ /* scalable fonts */ -#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ /* support vector outlines */ -#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ /* own hinter */ +#define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800 /* the driver's hinter */ + /* produces LIGHT hints */ /* deprecated values */ @@ -98,9 +127,10 @@ FT_BEGIN_HEADER #define ft_module_hinter FT_MODULE_HINTER #define ft_module_styler FT_MODULE_STYLER -#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE -#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES -#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_hints_lightly FT_MODULE_DRIVER_HINTS_LIGHTLY typedef FT_Pointer FT_Module_Interface; @@ -298,7 +328,7 @@ FT_BEGIN_HEADER * Note that only a few modules have properties. * * value :: - * A generic pointer to a variable or structure which gives the new + * A generic pointer to a variable or structure that gives the new * value of the property. The exact definition of `value' is * dependent on the property; see the `Synopsis' subsection of the * module's documentation. @@ -364,7 +394,7 @@ FT_BEGIN_HEADER * * @inout: * value :: - * A generic pointer to a variable or structure which gives the + * A generic pointer to a variable or structure that gives the * value of the property. The exact definition of `value' is * dependent on the property; see the `Synopsis' subsection of the * module's documentation. @@ -418,7 +448,7 @@ FT_BEGIN_HEADER /* @FT_Done_Library then only destroys a library if the counter is~1, */ /* otherwise it simply decrements the counter. */ /* */ - /* This function helps in managing life-cycles of structures which */ + /* This function helps in managing life-cycles of structures that */ /* reference @FT_Library objects. */ /* */ /* <Input> */ @@ -442,7 +472,9 @@ FT_BEGIN_HEADER /* <Description> */ /* This function is used to create a new FreeType library instance */ /* from a given memory object. It is thus possible to use libraries */ - /* with distinct memory allocators within the same program. */ + /* with distinct memory allocators within the same program. Note, */ + /* however, that the used @FT_Memory structure is expected to remain */ + /* valid for the life of the @FT_Library object. */ /* */ /* Normally, you would call this function (followed by a call to */ /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ @@ -491,7 +523,7 @@ FT_BEGIN_HEADER FT_EXPORT( FT_Error ) FT_Done_Library( FT_Library library ); -/* */ + /* */ typedef void (*FT_DebugHook_Func)( void* arg ); @@ -581,12 +613,7 @@ FT_BEGIN_HEADER * The library doesn't implement any kind of bytecode interpreter. * * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: - * The library implements a bytecode interpreter that doesn't - * support the patented operations of the TrueType virtual machine. - * - * Its main use is to load certain Asian fonts which position and - * scale glyph components with bytecode instructions. It produces - * bad output for most other fonts. + * Deprecated and removed. * * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: * The library implements a bytecode interpreter that covers @@ -629,13 +656,12 @@ FT_BEGIN_HEADER FT_EXPORT( FT_TrueTypeEngineType ) FT_Get_TrueType_Engine_Type( FT_Library library ); - /* */ FT_END_HEADER -#endif /* __FTMODAPI_H__ */ +#endif /* FTMODAPI_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftmoderr.h b/drivers/freetype/include/freetype/ftmoderr.h index 5a27db151a..2a7671c816 100644 --- a/drivers/freetype/include/freetype/ftmoderr.h +++ b/drivers/freetype/include/freetype/ftmoderr.h @@ -4,7 +4,7 @@ /* */ /* FreeType module error offsets (specification). */ /* */ -/* Copyright 2001-2005, 2010, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ /* with something like */ /* */ /* { */ - /* #undef __FTMODERR_H__ */ + /* #undef FTMODERR_H_ */ /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ /* #define FT_MODERR_START_LIST { */ /* #define FT_MODERR_END_LIST { 0, 0 } }; */ @@ -91,8 +91,8 @@ /*************************************************************************/ -#ifndef __FTMODERR_H__ -#define __FTMODERR_H__ +#ifndef FTMODERR_H_ +#define FTMODERR_H_ /*******************************************************************/ @@ -188,7 +188,7 @@ #undef FT_NEED_EXTERN_C -#endif /* __FTMODERR_H__ */ +#endif /* FTMODERR_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftotval.h b/drivers/freetype/include/freetype/ftotval.h index 027f2e8865..3e6e18d8a6 100644 --- a/drivers/freetype/include/freetype/ftotval.h +++ b/drivers/freetype/include/freetype/ftotval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (specification). */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,8 @@ /***************************************************************************/ -#ifndef __FTOTVAL_H__ -#define __FTOTVAL_H__ +#ifndef FTOTVAL_H_ +#define FTOTVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -58,6 +58,12 @@ FT_BEGIN_HEADER /* This section contains the declaration of functions to validate */ /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ /* */ + /* <Order> */ + /* FT_OpenType_Validate */ + /* FT_OpenType_Free */ + /* */ + /* FT_VALIDATE_OTXXX */ + /* */ /*************************************************************************/ @@ -100,14 +106,12 @@ FT_BEGIN_HEADER #define FT_VALIDATE_JSTF 0x1000 #define FT_VALIDATE_MATH 0x2000 -#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ - FT_VALIDATE_GDEF | \ - FT_VALIDATE_GPOS | \ - FT_VALIDATE_GSUB | \ - FT_VALIDATE_JSTF | \ - FT_VALIDATE_MATH - - /* */ +#define FT_VALIDATE_OT ( FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH ) /********************************************************************** * @@ -116,7 +120,7 @@ FT_BEGIN_HEADER * * @description: * Validate various OpenType tables to assure that all offsets and - * indices are valid. The idea is that a higher-level library which + * indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without * error checking (which can be quite time consuming). * @@ -125,7 +129,7 @@ FT_BEGIN_HEADER * A handle to the input face. * * validation_flags :: - * A bit field which specifies the tables to be validated. See + * A bit field that specifies the tables to be validated. See * @FT_VALIDATE_OTXXX for possible values. * * @output: @@ -165,8 +169,6 @@ FT_BEGIN_HEADER FT_Bytes *GSUB_table, FT_Bytes *JSTF_table ); - /* */ - /********************************************************************** * * @function: @@ -191,13 +193,12 @@ FT_BEGIN_HEADER FT_OpenType_Free( FT_Face face, FT_Bytes table ); - - /* */ + /* */ FT_END_HEADER -#endif /* __FTOTVAL_H__ */ +#endif /* FTOTVAL_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftoutln.h b/drivers/freetype/include/freetype/ftoutln.h index fd69f28292..6a6451207c 100644 --- a/drivers/freetype/include/freetype/ftoutln.h +++ b/drivers/freetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ -/* Copyright 1996-2003, 2005-2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FTOUTLN_H__ -#define __FTOUTLN_H__ +#ifndef FTOUTLN_H_ +#define FTOUTLN_H_ #include <ft2build.h> @@ -52,7 +52,6 @@ FT_BEGIN_HEADER /* */ /* <Order> */ /* FT_Outline */ - /* FT_OUTLINE_FLAGS */ /* FT_Outline_New */ /* FT_Outline_Done */ /* FT_Outline_Copy */ @@ -68,13 +67,17 @@ FT_BEGIN_HEADER /* */ /* FT_Outline_Get_Bitmap */ /* FT_Outline_Render */ - /* */ /* FT_Outline_Decompose */ /* FT_Outline_Funcs */ - /* FT_Outline_MoveTo_Func */ - /* FT_Outline_LineTo_Func */ - /* FT_Outline_ConicTo_Func */ - /* FT_Outline_CubicTo_Func */ + /* FT_Outline_MoveToFunc */ + /* FT_Outline_LineToFunc */ + /* FT_Outline_ConicToFunc */ + /* FT_Outline_CubicToFunc */ + /* */ + /* FT_Orientation */ + /* FT_Outline_Get_Orientation */ + /* */ + /* FT_OUTLINE_XXX */ /* */ /*************************************************************************/ @@ -97,7 +100,7 @@ FT_BEGIN_HEADER /* operations. */ /* */ /* <InOut> */ - /* user :: A typeless pointer which is passed to each */ + /* user :: A typeless pointer that is passed to each */ /* emitter during the decomposition. It can be */ /* used to store the state during the */ /* decomposition. */ @@ -105,6 +108,13 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* A contour that contains a single point only is represented by a */ + /* `move to' operation followed by `line to' to the same point. In */ + /* most cases, it is best to filter this out before using the */ + /* outline for stroking purposes (otherwise it would result in a */ + /* visible dot when round caps are used). */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Decompose( FT_Outline* outline, const FT_Outline_Funcs* func_interface, @@ -217,12 +227,12 @@ FT_BEGIN_HEADER /* the outline's points, including Bézier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bézier outside arcs). */ + /* that contains Bézier outside arcs). */ /* */ /* Computing the control box is very fast, while getting the bounding */ /* box can take much more time as it needs to walk over all segments */ /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ + /* `ftbbox' component, which is dedicated to this single task. */ /* */ /* <Input> */ /* outline :: A pointer to the source outline descriptor. */ @@ -344,10 +354,13 @@ FT_BEGIN_HEADER /* */ /* { */ /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ - /* if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE ) */ - /* FT_Outline_Embolden( &face->slot->outline, strength ); */ + /* if ( face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) */ + /* FT_Outline_Embolden( &face->glyph->outline, strength ); */ /* } */ /* */ + /* To get meaningful results, font scaling values must be set with */ + /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Embolden( FT_Outline* outline, FT_Pos strength ); @@ -525,9 +538,11 @@ FT_BEGIN_HEADER * * @description: * This function analyzes a glyph outline and tries to compute its - * fill orientation (see @FT_Orientation). This is done by computing - * the direction of each global horizontal and/or vertical extrema - * within the outline. + * fill orientation (see @FT_Orientation). This is done by integrating + * the total area covered by the outline. The positive integral + * corresponds to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT + * is returned. The negative integral corresponds to the counter-clockwise + * orientation and @FT_ORIENTATION_TRUETYPE is returned. * * Note that this will return @FT_ORIENTATION_TRUETYPE for empty * outlines. @@ -543,13 +558,12 @@ FT_BEGIN_HEADER FT_EXPORT( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ); - /* */ FT_END_HEADER -#endif /* __FTOUTLN_H__ */ +#endif /* FTOUTLN_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftpfr.h b/drivers/freetype/include/freetype/ftpfr.h index 0b7b7d427c..2e1bff2f67 100644 --- a/drivers/freetype/include/freetype/ftpfr.h +++ b/drivers/freetype/include/freetype/ftpfr.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (specification only). */ /* */ -/* Copyright 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTPFR_H__ -#define __FTPFR_H__ +#ifndef FTPFR_H_ +#define FTPFR_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -161,12 +161,12 @@ FT_BEGIN_HEADER FT_UInt gindex, FT_Pos *aadvance ); - /* */ + /* */ FT_END_HEADER -#endif /* __FTPFR_H__ */ +#endif /* FTPFR_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftrender.h b/drivers/freetype/include/freetype/ftrender.h index dd0229b815..9f7ed9e9d9 100644 --- a/drivers/freetype/include/freetype/ftrender.h +++ b/drivers/freetype/include/freetype/ftrender.h @@ -4,7 +4,7 @@ /* */ /* FreeType renderer modules public interface (specification). */ /* */ -/* Copyright 1996-2001, 2005, 2006, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTRENDER_H__ -#define __FTRENDER_H__ +#ifndef FTRENDER_H_ +#define FTRENDER_H_ #include <ft2build.h> @@ -212,13 +212,8 @@ FT_BEGIN_HEADER /* */ /* This doesn't change the current renderer for other formats. */ /* */ - /* Currently, only the B/W renderer, if compiled with */ - /* FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels */ - /* anti-aliasing mode; this option must be set directly in */ - /* `ftraster.c' and is undefined by default) accepts a single tag */ - /* `pal5' to set its gray palette as a character string with */ - /* 5~elements. Consequently, the third and fourth argument are zero */ - /* normally. */ + /* Currently, no FreeType renderer module uses `parameters'; you */ + /* should thus always pass NULL as the value. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Renderer( FT_Library library, @@ -226,13 +221,12 @@ FT_BEGIN_HEADER FT_UInt num_params, FT_Parameter* parameters ); - /* */ FT_END_HEADER -#endif /* __FTRENDER_H__ */ +#endif /* FTRENDER_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftsizes.h b/drivers/freetype/include/freetype/ftsizes.h index 3e548cc39f..55e0d5ccfd 100644 --- a/drivers/freetype/include/freetype/ftsizes.h +++ b/drivers/freetype/include/freetype/ftsizes.h @@ -4,7 +4,7 @@ /* */ /* FreeType size objects management (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,8 +25,8 @@ /*************************************************************************/ -#ifndef __FTSIZES_H__ -#define __FTSIZES_H__ +#ifndef FTSIZES_H_ +#define FTSIZES_H_ #include <ft2build.h> @@ -129,7 +129,7 @@ FT_BEGIN_HEADER /* <Description> */ /* Even though it is possible to create several size objects for a */ /* given face (see @FT_New_Size for details), functions like */ - /* @FT_Load_Glyph or @FT_Load_Char only use the one which has been */ + /* @FT_Load_Glyph or @FT_Load_Char only use the one that has been */ /* activated last to determine the `current character pixel size'. */ /* */ /* This function can be used to `activate' a previously created size */ @@ -153,7 +153,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSIZES_H__ */ +#endif /* FTSIZES_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftsnames.h b/drivers/freetype/include/freetype/ftsnames.h index 485e4e162e..a7b51c2cba 100644 --- a/drivers/freetype/include/freetype/ftsnames.h +++ b/drivers/freetype/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,8 +19,8 @@ /***************************************************************************/ -#ifndef __FT_SFNT_NAMES_H__ -#define __FT_SFNT_NAMES_H__ +#ifndef FTSNAMES_H_ +#define FTSNAMES_H_ #include <ft2build.h> @@ -169,7 +169,7 @@ FT_BEGIN_HEADER * A constant used as the tag of @FT_Parameter structures to make * FT_Open_Face() ignore preferred family subfamily names in `name' * table since OpenType version 1.4. For backwards compatibility with - * legacy systems which has 4-face-per-family restriction. + * legacy systems that have a 4-face-per-family restriction. * */ #define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) @@ -184,7 +184,7 @@ FT_BEGIN_HEADER * A constant used as the tag of @FT_Parameter structures to make * FT_Open_Face() ignore preferred subfamily names in `name' table since * OpenType version 1.4. For backwards compatibility with legacy - * systems which has 4-face-per-family restriction. + * systems that have a 4-face-per-family restriction. * */ #define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) @@ -194,7 +194,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_SFNT_NAMES_H__ */ +#endif /* FTSNAMES_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftstroke.h b/drivers/freetype/include/freetype/ftstroke.h index a498e4a883..b3b9922dad 100644 --- a/drivers/freetype/include/freetype/ftstroke.h +++ b/drivers/freetype/include/freetype/ftstroke.h @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (specification). */ /* */ -/* Copyright 2002-2006, 2008, 2009, 2011-2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FT_STROKE_H__ -#define __FT_STROKE_H__ +#ifndef FTSTROKE_H_ +#define FTSTROKE_H_ #include <ft2build.h> #include FT_OUTLINE_H @@ -46,6 +46,38 @@ FT_BEGIN_HEADER * This can be useful to generate `bordered' glyph, i.e., glyphs * displayed with a coloured (and anti-aliased) border around their * shape. + * + * @order: + * FT_Stroker + * + * FT_Stroker_LineJoin + * FT_Stroker_LineCap + * FT_StrokerBorder + * + * FT_Outline_GetInsideBorder + * FT_Outline_GetOutsideBorder + * + * FT_Glyph_Stroke + * FT_Glyph_StrokeBorder + * + * FT_Stroker_New + * FT_Stroker_Set + * FT_Stroker_Rewind + * FT_Stroker_ParseOutline + * FT_Stroker_Done + * + * FT_Stroker_BeginSubPath + * FT_Stroker_EndSubPath + * + * FT_Stroker_LineTo + * FT_Stroker_ConicTo + * FT_Stroker_CubicTo + * + * FT_Stroker_GetBorderCounts + * FT_Stroker_ExportBorder + * FT_Stroker_GetCounts + * FT_Stroker_Export + * */ @@ -55,7 +87,7 @@ FT_BEGIN_HEADER * FT_Stroker * * @description: - * Opaque handler to a path stroker object. + * Opaque handle to a path stroker object. */ typedef struct FT_StrokerRec_* FT_Stroker; @@ -276,6 +308,8 @@ FT_BEGIN_HEADER * @note: * The radius is expressed in the same units as the outline * coordinates. + * + * This function calls @FT_Stroker_Rewind automatically. */ FT_EXPORT( void ) FT_Stroker_Set( FT_Stroker stroker, @@ -570,10 +604,10 @@ FT_BEGIN_HEADER * receive all new data. * * When an outline, or a sub-path, is `closed', the stroker generates - * two independent `border' outlines, named `left' and `right' + * two independent `border' outlines, named `left' and `right'. * * When the outline, or a sub-path, is `opened', the stroker merges - * the `border' outlines with caps. The `left' border receives all + * the `border' outlines with caps. The `left' border receives all * points, while the `right' border becomes empty. * * Use the function @FT_Stroker_Export instead if you want to @@ -736,11 +770,11 @@ FT_BEGIN_HEADER FT_Bool inside, FT_Bool destroy ); - /* */ + /* */ FT_END_HEADER -#endif /* __FT_STROKE_H__ */ +#endif /* FTSTROKE_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftsynth.h b/drivers/freetype/include/freetype/ftsynth.h index 2074503cf6..fdfcb6912b 100644 --- a/drivers/freetype/include/freetype/ftsynth.h +++ b/drivers/freetype/include/freetype/ftsynth.h @@ -5,7 +5,7 @@ /* FreeType synthesizing code for emboldening and slanting */ /* (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2006, 2008, 2012 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,12 +37,12 @@ /* Main reason for not lifting the functions in this module to a */ /* `standard' API is that the used parameters for emboldening and */ /* slanting are not configurable. Consider the functions as a */ - /* code resource which should be copied into the application and */ + /* code resource that should be copied into the application and */ /* adapted to the particular needs. */ -#ifndef __FTSYNTH_H__ -#define __FTSYNTH_H__ +#ifndef FTSYNTH_H_ +#define FTSYNTH_H_ #include <ft2build.h> @@ -62,8 +62,10 @@ FT_BEGIN_HEADER /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ /* */ /* For emboldened outlines the height, width, and advance metrics are */ - /* increased by the strength of the emboldening. You can also call */ - /* @FT_Outline_Get_CBox to get precise values. */ + /* increased by the strength of the emboldening -- this even affects */ + /* mono-width fonts! */ + /* */ + /* You can also call @FT_Outline_Get_CBox to get precise values. */ FT_EXPORT( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); @@ -73,9 +75,10 @@ FT_BEGIN_HEADER /* */ + FT_END_HEADER -#endif /* __FTSYNTH_H__ */ +#endif /* FTSYNTH_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftsystem.h b/drivers/freetype/include/freetype/ftsystem.h index e07460c55d..a75f958022 100644 --- a/drivers/freetype/include/freetype/ftsystem.h +++ b/drivers/freetype/include/freetype/ftsystem.h @@ -4,7 +4,7 @@ /* */ /* FreeType low-level system interface definition (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSYSTEM_H__ -#define __FTSYSTEM_H__ +#ifndef FTSYSTEM_H_ +#define FTSYSTEM_H_ #include <ft2build.h> @@ -192,6 +192,10 @@ FT_BEGIN_HEADER * @description: * A handle to an input stream. * + * @also: + * See @FT_StreamRec for the publicly accessible fields of a given + * stream object. + * */ typedef struct FT_StreamRec_* FT_Stream; @@ -285,6 +289,11 @@ FT_BEGIN_HEADER * size :: * The stream size in bytes. * + * In case of compressed streams where the size is unknown before + * actually doing the decompression, the value is set to 0x7FFFFFFF. + * (Note that this size value can occur for normal streams also; it is + * thus just a hint.) + * * pos :: * The current position within the stream. * @@ -335,13 +344,12 @@ FT_BEGIN_HEADER } FT_StreamRec; - /* */ FT_END_HEADER -#endif /* __FTSYSTEM_H__ */ +#endif /* FTSYSTEM_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/fttrigon.h b/drivers/freetype/include/freetype/fttrigon.h index 65143cb8c8..f789b524cb 100644 --- a/drivers/freetype/include/freetype/fttrigon.h +++ b/drivers/freetype/include/freetype/fttrigon.h @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (specification). */ /* */ -/* Copyright 2001, 2003, 2005, 2007, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTTRIGON_H__ -#define __FTTRIGON_H__ +#ifndef FTTRIGON_H_ +#define FTTRIGON_H_ #include FT_FREETYPE_H @@ -225,8 +225,8 @@ FT_BEGIN_HEADER * * @description: * Return the unit vector corresponding to a given angle. After the - * call, the value of `vec.x' will be `sin(angle)', and the value of - * `vec.y' will be `cos(angle)'. + * call, the value of `vec.x' will be `cos(angle)', and the value of + * `vec.y' will be `sin(angle)'. * * This function is useful to retrieve both the sinus and cosinus of a * given angle quickly. @@ -237,7 +237,7 @@ FT_BEGIN_HEADER * * @input: * angle :: - * The address of angle. + * The input angle. * */ FT_EXPORT( void ) @@ -259,7 +259,7 @@ FT_BEGIN_HEADER * * @input: * angle :: - * The address of angle. + * The input angle. * */ FT_EXPORT( void ) @@ -344,7 +344,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTRIGON_H__ */ +#endif /* FTTRIGON_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftttdrv.h b/drivers/freetype/include/freetype/ftttdrv.h index d5d3f1ccc1..0d868bc259 100644 --- a/drivers/freetype/include/freetype/ftttdrv.h +++ b/drivers/freetype/include/freetype/ftttdrv.h @@ -5,7 +5,7 @@ /* FreeType API for controlling the TrueType driver */ /* (specification only). */ /* */ -/* Copyright 2013 by */ +/* Copyright 2013-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FTTTDRV_H__ -#define __FTTTDRV_H__ +#ifndef FTTTDRV_H_ +#define FTTTDRV_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -52,6 +52,83 @@ FT_BEGIN_HEADER * * The TrueType driver's module name is `truetype'. * + * We start with a list of definitions, kindly provided by Greg + * Hitchcock. + * + * _Bi-Level_ _Rendering_ + * + * Monochromatic rendering, exclusively used in the early days of + * TrueType by both Apple and Microsoft. Microsoft's GDI interface + * supported hinting of the right-side bearing point, such that the + * advance width could be non-linear. Most often this was done to + * achieve some level of glyph symmetry. To enable reasonable + * performance (e.g., not having to run hinting on all glyphs just to + * get the widths) there was a bit in the head table indicating if the + * side bearing was hinted, and additional tables, `hdmx' and `LTSH', to + * cache hinting widths across multiple sizes and device aspect ratios. + * + * _Font_ _Smoothing_ + * + * Microsoft's GDI implementation of anti-aliasing. Not traditional + * anti-aliasing as the outlines were hinted before the sampling. The + * widths matched the bi-level rendering. + * + * _ClearType_ _Rendering_ + * + * Technique that uses physical subpixels to improve rendering on LCD + * (and other) displays. Because of the higher resolution, many methods + * of improving symmetry in glyphs through hinting the right-side + * bearing were no longer necessary. This lead to what GDI calls + * `natural widths' ClearType, see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec21. Since hinting + * has extra resolution, most non-linearity went away, but it is still + * possible for hints to change the advance widths in this mode. + * + * _ClearType_ _Compatible_ _Widths_ + * + * One of the earliest challenges with ClearType was allowing the + * implementation in GDI to be selected without requiring all UI and + * documents to reflow. To address this, a compatible method of + * rendering ClearType was added where the font hints are executed once + * to determine the width in bi-level rendering, and then re-run in + * ClearType, with the difference in widths being absorbed in the font + * hints for ClearType (mostly in the white space of hints); see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec20. Somewhat by + * definition, compatible width ClearType allows for non-linear widths, + * but only when the bi-level version has non-linear widths. + * + * _ClearType_ _Subpixel_ _Positioning_ + * + * One of the nice benefits of ClearType is the ability to more crisply + * display fractional widths; unfortunately, the GDI model of integer + * bitmaps did not support this. However, the WPF and Direct Write + * frameworks do support fractional widths. DWrite calls this `natural + * mode', not to be confused with GDI's `natural widths'. Subpixel + * positioning, in the current implementation of Direct Write, + * unfortunately does not support hinted advance widths, see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec22. Note that the + * TrueType interpreter fully allows the advance width to be adjusted in + * this mode, just the DWrite client will ignore those changes. + * + * _ClearType_ _Backwards_ _Compatibility_ + * + * This is a set of exceptions made in the TrueType interpreter to + * minimize hinting techniques that were problematic with the extra + * resolution of ClearType; see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec1 and + * http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx. + * This technique is not to be confused with ClearType compatible + * widths. ClearType backwards compatibility has no direct impact on + * changing advance widths, but there might be an indirect impact on + * disabling some deltas. This could be worked around in backwards + * compatibility mode. + * + * _Native_ _ClearType_ _Mode_ + * + * (Not to be confused with `natural widths'.) This mode removes all + * the exceptions in the TrueType interpreter when running with + * ClearType. Any issues on widths would still apply, though. + * */ @@ -61,31 +138,37 @@ FT_BEGIN_HEADER * interpreter-version * * @description: - * Currently, two versions are available which represent the bytecode - * interpreter with and without subpixel hinting support, - * respectively. The default is subpixel support if - * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel - * support otherwise (since it isn't available then). - * - * If subpixel hinting is on, many TrueType bytecode instructions - * behave differently compared to B/W or grayscale rendering. The - * main idea is to render at a much increased horizontal resolution, - * then sampling down the created output to subpixel precision. - * However, many older fonts are not suited to this and must be - * specially taken care of by applying (hardcoded) font-specific - * tweaks. + + * Currently, three versions are available, two representing the + * bytecode interpreter with subpixel hinting support (old `Infinality' + * code and new stripped-down and higher performance `minimal' code) and + * one without, respectively. The default is subpixel support if + * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support + * otherwise (since it isn't available then). + * + * If subpixel hinting is on, many TrueType bytecode instructions behave + * differently compared to B/W or grayscale rendering (except if `native + * ClearType' is selected by the font). Microsoft's main idea is to + * render at a much increased horizontal resolution, then sampling down + * the created output to subpixel precision. However, many older fonts + * are not suited to this and must be specially taken care of by + * applying (hardcoded) tweaks in Microsoft's interpreter. * * Details on subpixel hinting and some of the necessary tweaks can be * found in Greg Hitchcock's whitepaper at - * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2, + * or 6x5 supersampling) like discussed in the paper. Depending on the + * chosen interpreter, it simply ignores instructions on vertical stems + * to arrive at very similar results. * - * The following example code demonstrates how to activate subpixel + * The following example code demonstrates how to deactivate subpixel * hinting (omitting the error handling). * * { * FT_Library library; * FT_Face face; - * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_38; + * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35; * * * FT_Init_FreeType( &library ); @@ -120,9 +203,19 @@ FT_BEGIN_HEADER * * TT_INTERPRETER_VERSION_38 :: * Version~38 corresponds to MS rasterizer v.1.9; it is roughly - * equivalent to the hinting provided by DirectWrite ClearType (as - * can be found, for example, in the Internet Explorer~9 running on - * Windows~7). + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in the Internet Explorer~9 running on + * Windows~7). It is used in FreeType to select the `Infinality' + * subpixel hinting code. The code may be removed in a future + * version. + * + * TT_INTERPRETER_VERSION_40 :: + * Version~40 corresponds to MS rasterizer v.2.1; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in Microsoft's Edge Browser on Windows~10). + * It is used in FreeType to select the `minimal' subpixel hinting + * code, a stripped-down and higher performance version of the + * `Infinality' code. * * @note: * This property controls the behaviour of the bytecode interpreter @@ -130,21 +223,105 @@ FT_BEGIN_HEADER * get rasterized! In particular, it does not control subpixel color * filtering. * - * If FreeType has not been compiled with configuration option - * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an - * `FT_Err_Unimplemented_Feature' error. + * If FreeType has not been compiled with the configuration option + * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes + * an `FT_Err_Unimplemented_Feature' error. + * + * Depending on the graphics framework, Microsoft uses different + * bytecode and rendering engines. As a consequence, the version + * numbers returned by a call to the `GETINFO' bytecode instruction are + * more convoluted than desired. + * + * Here are two tables that try to shed some light on the possible + * values for the MS rasterizer engine, together with the additional + * features introduced by it. + * + * { + * GETINFO framework version feature + * ------------------------------------------------------------------- + * 3 GDI (Win 3.1), v1.0 16-bit, first version + * TrueImage + * 33 GDI (Win NT 3.1), v1.5 32-bit + * HP Laserjet + * 34 GDI (Win 95) v1.6 font smoothing, + * new SCANTYPE opcode + * 35 GDI (Win 98/2000) v1.7 (UN)SCALED_COMPONENT_OFFSET + * bits in composite glyphs + * 36 MGDI (Win CE 2) v1.6+ classic ClearType + * 37 GDI (XP and later), v1.8 ClearType + * GDI+ old (before Vista) + * 38 GDI+ old (Vista, Win 7), v1.9 subpixel ClearType, + * WPF Y-direction ClearType, + * additional error checking + * 39 DWrite (before Win 8) v2.0 subpixel ClearType flags + * in GETINFO opcode, + * bug fixes + * 40 GDI+ (after Win 7), v2.1 Y-direction ClearType flag + * DWrite (Win 8) in GETINFO opcode, + * Gray ClearType + * } + * + * The `version' field gives a rough orientation only, since some + * applications provided certain features much earlier (as an example, + * Microsoft Reader used subpixel and Y-direction ClearType already in + * Windows 2000). Similarly, updates to a given framework might include + * improved hinting support. + * + * { + * version sampling rendering comment + * x y x y + * -------------------------------------------------------------- + * v1.0 normal normal B/W B/W bi-level + * v1.6 high high gray gray grayscale + * v1.8 high normal color-filter B/W (GDI) ClearType + * v1.9 high high color-filter gray Color ClearType + * v2.1 high normal gray B/W Gray ClearType + * v2.1 high high gray gray Gray ClearType + * } + * + * Color and Gray ClearType are the two available variants of + * `Y-direction ClearType', meaning grayscale rasterization along the + * Y-direction; the name used in the TrueType specification for this + * feature is `symmetric smoothing'. `Classic ClearType' is the + * original algorithm used before introducing a modified version in + * Win~XP. Another name for v1.6's grayscale rendering is `font + * smoothing', and `Color ClearType' is sometimes also called `DWrite + * ClearType'. To differentiate between today's Color ClearType and the + * earlier ClearType variant with B/W rendering along the vertical axis, + * the latter is sometimes called `GDI ClearType'. + * + * `Normal' and `high' sampling describe the (virtual) resolution to + * access the rasterized outline after the hinting process. `Normal' + * means 1 sample per grid line (i.e., B/W). In the current Microsoft + * implementation, `high' means an extra virtual resolution of 16x16 (or + * 16x1) grid lines per pixel for bytecode instructions like `MIRP'. + * After hinting, these 16 grid lines are mapped to 6x5 (or 6x1) grid + * lines for color filtering if Color ClearType is activated. + * + * Note that `Gray ClearType' is essentially the same as v1.6's + * grayscale rendering. However, the GETINFO instruction handles it + * differently: v1.6 returns bit~12 (hinting for grayscale), while v2.1 + * returns bits~13 (hinting for ClearType), 18 (symmetrical smoothing), + * and~19 (Gray ClearType). Also, this mode respects bits 2 and~3 for + * the version~1 gasp table exclusively (like Color ClearType), while + * v1.6 only respects the values of version~0 (bits 0 and~1). + * + * Keep in mind that the features of the above interpreter versions + * might not map exactly to FreeType features or behavior because it is + * a fundamentally different library with different internals. * */ #define TT_INTERPRETER_VERSION_35 35 #define TT_INTERPRETER_VERSION_38 38 - +#define TT_INTERPRETER_VERSION_40 40 /* */ + FT_END_HEADER -#endif /* __FTTTDRV_H__ */ +#endif /* FTTTDRV_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/fttypes.h b/drivers/freetype/include/freetype/fttypes.h index 027e59ce11..2673e79c3c 100644 --- a/drivers/freetype/include/freetype/fttypes.h +++ b/drivers/freetype/include/freetype/fttypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType simple types definitions (specification only). */ /* */ -/* Copyright 1996-2002, 2004, 2006-2009, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTTYPES_H__ -#define __FTTYPES_H__ +#ifndef FTTYPES_H_ +#define FTTYPES_H_ #include <ft2build.h> @@ -57,6 +57,8 @@ FT_BEGIN_HEADER /* FT_UInt16 */ /* FT_Int32 */ /* FT_UInt32 */ + /* FT_Int64 */ + /* FT_UInt64 */ /* FT_Short */ /* FT_UShort */ /* FT_Long */ @@ -78,7 +80,9 @@ FT_BEGIN_HEADER /* FT_F2Dot14 */ /* FT_UnitVector */ /* FT_F26Dot6 */ + /* FT_Data */ /* */ + /* FT_MAKE_TAG */ /* */ /* FT_Generic */ /* FT_Generic_Finalizer */ @@ -418,7 +422,7 @@ FT_BEGIN_HEADER /* details of usage. */ /* */ /* <Input> */ - /* The address of the FreeType object which is under finalization. */ + /* The address of the FreeType object that is under finalization. */ /* Its client data is accessed through its `generic' field. */ /* */ typedef void (*FT_Generic_Finalizer)(void* object); @@ -466,8 +470,8 @@ FT_BEGIN_HEADER /* FT_MAKE_TAG */ /* */ /* <Description> */ - /* This macro converts four-letter tags which are used to label */ - /* TrueType tables into an unsigned long to be used within FreeType. */ + /* This macro converts four-letter tags that are used to label */ + /* TrueType tables into an unsigned long, to be used within FreeType. */ /* */ /* <Note> */ /* The produced values *must* be 32-bit integers. Don't redefine */ @@ -567,9 +571,9 @@ FT_BEGIN_HEADER } FT_ListRec; - /* */ + #define FT_IS_EMPTY( list ) ( (list).head == 0 ) #define FT_BOOL( x ) ( (FT_Bool)( x ) ) @@ -592,7 +596,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTYPES_H__ */ +#endif /* FTTYPES_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftwinfnt.h b/drivers/freetype/include/freetype/ftwinfnt.h index ea33353536..a1a715baa1 100644 --- a/drivers/freetype/include/freetype/ftwinfnt.h +++ b/drivers/freetype/include/freetype/ftwinfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows fnt-specific data. */ /* */ -/* Copyright 2003, 2004, 2008 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTWINFNT_H__ -#define __FTWINFNT_H__ +#ifndef FTWINFNT_H_ +#define FTWINFNT_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -58,9 +58,10 @@ FT_BEGIN_HEADER * @description: * A list of valid values for the `charset' byte in * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX - * encodings (except for cp1361) can be found at ftp://ftp.unicode.org - * in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory. cp1361 is - * roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * encodings (except for cp1361) can be found at + * ftp://ftp.unicode.org/Public in the MAPPINGS/VENDORS/MICSFT/WINDOWS + * subdirectory. cp1361 is roughly a superset of + * MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. * * @values: * FT_WinFNT_ID_DEFAULT :: @@ -94,7 +95,7 @@ FT_BEGIN_HEADER * second default codepage that most international versions of * Windows have. It is one of the OEM codepages from * - * http://www.microsoft.com/globaldev/reference/cphome.mspx, + * https://msdn.microsoft.com/en-us/goglobal/bb964655, * * and is used for the `DOS boxes', to support legacy applications. * A German Windows version for example usually uses ANSI codepage @@ -258,12 +259,12 @@ FT_BEGIN_HEADER FT_Get_WinFNT_Header( FT_Face face, FT_WinFNT_HeaderRec *aheader ); - /* */ + FT_END_HEADER -#endif /* __FTWINFNT_H__ */ +#endif /* FTWINFNT_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftxf86.h b/drivers/freetype/include/freetype/ftxf86.h deleted file mode 100644 index 8c68afdcc5..0000000000 --- a/drivers/freetype/include/freetype/ftxf86.h +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftxf86.h */ -/* */ -/* Support functions for X11. */ -/* */ -/* Copyright 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, */ -/* 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 __FTXF86_H__ -#define __FTXF86_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* font_formats */ - /* */ - /* <Title> */ - /* Font Formats */ - /* */ - /* <Abstract> */ - /* Getting the font format. */ - /* */ - /* <Description> */ - /* 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, in spite of FreeType's uniform API. */ - /* */ - /* This function is in the X11/xf86 namespace for historical reasons */ - /* and in no way depends on that windowing system. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <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. */ - /* */ - /* <Return> */ - /* Font format string. NULL in case of error. */ - /* */ - FT_EXPORT( const char* ) - FT_Get_X11_Font_Format( FT_Face face ); - - /* */ - -FT_END_HEADER - -#endif /* __FTXF86_H__ */ diff --git a/drivers/freetype/include/freetype/internal/autohint.h b/drivers/freetype/include/freetype/internal/autohint.h index 545de938c2..7ef82b8f3c 100644 --- a/drivers/freetype/include/freetype/internal/autohint.h +++ b/drivers/freetype/include/freetype/internal/autohint.h @@ -4,7 +4,7 @@ /* */ /* High-level `autohint' module-specific interface (specification). */ /* */ -/* Copyright 1996-2002, 2007, 2009, 2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +24,8 @@ /*************************************************************************/ -#ifndef __AUTOHINT_H__ -#define __AUTOHINT_H__ +#ifndef AUTOHINT_H_ +#define AUTOHINT_H_ /*************************************************************************/ @@ -238,7 +238,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AUTOHINT_H__ */ +#endif /* AUTOHINT_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftcalc.h b/drivers/freetype/include/freetype/internal/ftcalc.h index faac3a3867..8a884f680a 100644 --- a/drivers/freetype/include/freetype/internal/ftcalc.h +++ b/drivers/freetype/include/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (specification). */ /* */ -/* Copyright 1996-2006, 2008, 2009, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCALC_H__ -#define __FTCALC_H__ +#ifndef FTCALC_H_ +#define FTCALC_H_ #include <ft2build.h> @@ -27,33 +27,224 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_FixedSqrt */ - /* */ - /* <Description> */ - /* Computes the square root of a 16.16 fixed-point value. */ - /* */ - /* <Input> */ - /* x :: The value to compute the root for. */ - /* */ - /* <Return> */ - /* The result of `sqrt(x)'. */ - /* */ - /* <Note> */ - /* This function is not very fast. */ - /* */ - FT_BASE( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ); - - /*************************************************************************/ /* */ /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ /* */ /*************************************************************************/ +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + /* Provide assembler fragments for performance-critical functions. */ + /* These must be defined `static __inline__' with GCC. */ + +#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ + +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 t, t2; + + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x8000 /* a += 0x8000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #16 /* a = t2 >> 16 */ + orr a, a, t, lsl #16 /* a |= t << 16 */ + } + return a; + } + +#endif /* __CC_ARM || __ARMCC__ */ + + +#ifdef __GNUC__ + +#if defined( __arm__ ) && \ + ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \ + !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 t, t2; + + + __asm__ __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ +#if defined( __clang__ ) && defined( __thumb2__ ) + "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ +#else + "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ +#endif + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ + "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) + : "cc" ); + return a; + } + +#endif /* __arm__ && */ + /* ( __thumb2__ || !__thumb__ ) && */ + /* !( __CC_ARM || __ARMCC__ ) */ + + +#if defined( __i386__ ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 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" + : "=a"(result), "=d"(b) + : "a"(a), "d"(b) + : "%ecx", "cc" ); + return result; + } + +#endif /* i386 */ + +#endif /* __GNUC__ */ + + +#ifdef _MSC_VER /* Visual C++ */ + +#ifdef _M_IX86 + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 result; + + __asm + { + mov eax, a + mov edx, b + imul edx + mov ecx, edx + sar ecx, 31 + add ecx, 8000h + add eax, ecx + adc edx, 0 + shr eax, 16 + shl edx, 16 + add eax, edx + mov result, eax + } + return result; + } + +#endif /* _M_IX86 */ + +#endif /* _MSC_VER */ + + +#if defined( __GNUC__ ) && defined( __x86_64__ ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64 + + static __inline__ FT_Int32 + FT_MulFix_x86_64( FT_Int32 a, + FT_Int32 b ) + { + /* Temporarily disable the warning that C90 doesn't support */ + /* `long long'. */ +#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlong-long" +#endif + +#if 1 + /* Technically not an assembly fragment, but GCC does a really good */ + /* job at inlining it and generating good machine code for it. */ + long long ret, tmp; + + + ret = (long long)a * b; + tmp = ret >> 63; + ret += 0x8000 + tmp; + + return (FT_Int32)( ret >> 16 ); +#else + + /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */ + /* code from the lines below. The main issue is that `wide_a' is not */ + /* properly initialized by sign-extending `a'. Instead, the generated */ + /* machine code assumes that the register that contains `a' on input */ + /* can be used directly as a 64-bit value, which is wrong most of the */ + /* time. */ + long long wide_a = (long long)a; + long long wide_b = (long long)b; + long long result; + + + __asm__ __volatile__ ( + "imul %2, %1\n" + "mov %1, %0\n" + "sar $63, %0\n" + "lea 0x8000(%1, %0), %0\n" + "sar $16, %0\n" + : "=&r"(result), "=&r"(wide_a) + : "r"(wide_b) + : "cc" ); + + return (FT_Int32)result; +#endif + +#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) +#pragma GCC diagnostic pop +#endif + } + +#endif /* __GNUC__ && __x86_64__ */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX +#ifdef FT_MULFIX_ASSEMBLER +#define FT_MulFix( a, b ) FT_MULFIX_ASSEMBLER( (FT_Int32)(a), (FT_Int32)(b) ) +#endif +#endif + /*************************************************************************/ /* */ @@ -108,6 +299,18 @@ FT_BEGIN_HEADER FT_Long scaling ); + /* + * This function normalizes a vector and returns its original length. + * The normalized vector is a 16.16 fixed-point unit vector with length + * close to 0x10000. The accuracy of the returned length is limited to + * 16 bits also. The function utilizes quick inverse square root + * approximation without divisions and square roots relying on Newton's + * iterations instead. + */ + FT_BASE( FT_UInt32 ) + FT_Vector_NormLen( FT_Vector* vector ); + + /* * Return -1, 0, or +1, depending on the orientation of a given corner. * We use the Cartesian coordinate system, with positive vertical values @@ -120,10 +323,11 @@ FT_BEGIN_HEADER 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. + * saying that the corner point is close to its neighbors, or inside an + * ellipse defined by the neighbor focal points to be more precise. */ FT_BASE( FT_Int ) ft_corner_is_flat( FT_Pos in_x, @@ -135,9 +339,31 @@ FT_BEGIN_HEADER /* * Return the most significant bit index. */ + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER +#if defined( __GNUC__ ) && \ + ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) ) + +#if FT_SIZEOF_INT == 4 + +#define FT_MSB( x ) ( 31 - __builtin_clz( x ) ) + +#elif FT_SIZEOF_LONG == 4 + +#define FT_MSB( x ) ( 31 - __builtin_clzl( x ) ) + +#endif + +#endif /* __GNUC__ */ +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + +#ifndef FT_MSB + FT_BASE( FT_Int ) FT_MSB( FT_UInt32 z ); +#endif + /* * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses @@ -148,6 +374,31 @@ FT_BEGIN_HEADER FT_Fixed y ); +#if 0 + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_SqrtFixed */ + /* */ + /* <Description> */ + /* Computes the square root of a 16.16 fixed-point value. */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + /* <Note> */ + /* This function is not very fast. */ + /* */ + FT_BASE( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ); + +#endif /* 0 */ + + #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) @@ -161,7 +412,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCALC_H__ */ +#endif /* FTCALC_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftdebug.h b/drivers/freetype/include/freetype/internal/ftdebug.h index 58a3916d7e..d110457157 100644 --- a/drivers/freetype/include/freetype/internal/ftdebug.h +++ b/drivers/freetype/include/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (specification). */ /* */ -/* Copyright 1996-2002, 2004, 2006-2009, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ /***************************************************************************/ -#ifndef __FTDEBUG_H__ -#define __FTDEBUG_H__ +#ifndef FTDEBUG_H_ +#define FTDEBUG_H_ #include <ft2build.h> @@ -140,7 +140,7 @@ FT_BEGIN_HEADER /* This function may be useful if you want to control FreeType 2's */ /* debug level in your application. */ /* */ - FT_BASE( const char * ) + FT_BASE( const char* ) FT_Trace_Get_Name( FT_Int idx ); @@ -249,7 +249,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTDEBUG_H__ */ +#endif /* FTDEBUG_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftdriver.h b/drivers/freetype/include/freetype/internal/ftdriver.h index 940218e62d..3e1e66e979 100644 --- a/drivers/freetype/include/freetype/internal/ftdriver.h +++ b/drivers/freetype/include/freetype/internal/ftdriver.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver interface (specification). */ /* */ -/* Copyright 1996-2003, 2006, 2008, 2011-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTDRIVER_H__ -#define __FTDRIVER_H__ +#ifndef FTDRIVER_H_ +#define FTDRIVER_H_ #include <ft2build.h> @@ -213,7 +213,7 @@ FT_BEGIN_HEADER /* And when it is no longer needed a `destroy' function needs to be */ /* called to release that allocation. */ /* */ - /* `fcinit.c' (ft_create_default_module_classes) already contains a */ + /* `ftinit.c' (ft_create_default_module_classes) already contains a */ /* mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -403,7 +403,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTDRIVER_H__ */ +#endif /* FTDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftgloadr.h b/drivers/freetype/include/freetype/internal/ftgloadr.h index ce4dc6c9cc..bebf5dbba2 100644 --- a/drivers/freetype/include/freetype/internal/ftgloadr.h +++ b/drivers/freetype/include/freetype/internal/ftgloadr.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (specification). */ /* */ -/* Copyright 2002, 2003, 2005, 2006 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTGLOADR_H__ -#define __FTGLOADR_H__ +#ifndef FTGLOADR_H_ +#define FTGLOADR_H_ #include <ft2build.h> @@ -36,24 +36,6 @@ FT_BEGIN_HEADER /* The glyph loader is an internal object used to load several glyphs */ /* together (for example, in the case of composites). */ /* */ - /* <Note> */ - /* The glyph loader implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; - - -#if 0 /* moved to freetype.h in version 2.2 */ -#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 -#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 -#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 -#define FT_SUBGLYPH_FLAG_SCALE 8 -#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 -#define FT_SUBGLYPH_FLAG_2X2 0x80 -#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 -#endif - - typedef struct FT_SubGlyphRec_ { FT_Int index; @@ -89,7 +71,7 @@ FT_BEGIN_HEADER void* other; /* for possible future extension? */ - } FT_GlyphLoaderRec; + } FT_GlyphLoaderRec, *FT_GlyphLoader; /* create new empty glyph loader */ @@ -121,21 +103,25 @@ FT_BEGIN_HEADER FT_UInt n_contours ); -#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ - ( (_count) == 0 || ((_loader)->base.outline.n_points + \ - (_loader)->current.outline.n_points + \ - (unsigned long)(_count)) <= (_loader)->max_points ) +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || \ + ( (FT_UInt)(_loader)->base.outline.n_points + \ + (FT_UInt)(_loader)->current.outline.n_points + \ + (FT_UInt)(_count) ) <= (_loader)->max_points ) -#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ - ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ - (_loader)->current.outline.n_contours + \ - (unsigned long)(_count)) <= (_loader)->max_contours ) +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || \ + ( (FT_UInt)(_loader)->base.outline.n_contours + \ + (FT_UInt)(_loader)->current.outline.n_contours + \ + (FT_UInt)(_count) ) <= (_loader)->max_contours ) -#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ - ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ - FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ - ? 0 \ - : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) ) +#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points, _contours ) \ + ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ + FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ + ? 0 \ + : FT_GlyphLoader_CheckPoints( (_loader), \ + (FT_UInt)(_points), \ + (FT_UInt)(_contours) ) ) /* check that there is enough space to add `n_subs' sub-glyphs to */ @@ -162,7 +148,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGLOADR_H__ */ +#endif /* FTGLOADR_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/fthash.h b/drivers/freetype/include/freetype/internal/fthash.h new file mode 100644 index 0000000000..f22f9d5d39 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/fthash.h @@ -0,0 +1,136 @@ +/***************************************************************************/ +/* */ +/* fthash.h */ +/* */ +/* Hashing functions (specification). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * 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 to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#ifndef FTHASH_H_ +#define FTHASH_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef union FT_Hashkey_ + { + FT_Int num; + const char* str; + + } FT_Hashkey; + + + typedef struct FT_HashnodeRec_ + { + FT_Hashkey key; + size_t data; + + } FT_HashnodeRec; + + typedef struct FT_HashnodeRec_ *FT_Hashnode; + + + typedef FT_ULong + (*FT_Hash_LookupFunc)( FT_Hashkey* key ); + + typedef FT_Bool + (*FT_Hash_CompareFunc)( FT_Hashkey* a, + FT_Hashkey* b ); + + + typedef struct FT_HashRec_ + { + FT_UInt limit; + FT_UInt size; + FT_UInt used; + + FT_Hash_LookupFunc lookup; + FT_Hash_CompareFunc compare; + + FT_Hashnode* table; + + } FT_HashRec; + + typedef struct FT_HashRec_ *FT_Hash; + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ); + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ); + +#define ft_hash_num_free ft_hash_str_free + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ); + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ); + + +FT_END_HEADER + + +#endif /* FTHASH_H_ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/ftmemory.h b/drivers/freetype/include/freetype/internal/ftmemory.h index 3d51aeec69..8c06fc21a5 100644 --- a/drivers/freetype/include/freetype/internal/ftmemory.h +++ b/drivers/freetype/include/freetype/internal/ftmemory.h @@ -4,7 +4,7 @@ /* */ /* The FreeType memory management macros (specification). */ /* */ -/* Copyright 1996-2002, 2004-2007, 2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMEMORY_H__ -#define __FTMEMORY_H__ +#ifndef FTMEMORY_H_ +#define FTMEMORY_H_ #include <ft2build.h> @@ -65,13 +65,15 @@ FT_BEGIN_HEADER #ifdef __cplusplus - extern "C++" +extern "C++" +{ template <typename T> inline T* cplusplus_typeof( T*, void *v ) { return static_cast <T*> ( v ); } +} #define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) ) @@ -215,11 +217,14 @@ FT_BEGIN_HEADER #define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) -#define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) +#define FT_MEM_SET( dest, byte, count ) \ + ft_memset( dest, byte, (FT_Offset)(count) ) -#define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) +#define FT_MEM_COPY( dest, source, count ) \ + ft_memcpy( dest, source, (FT_Offset)(count) ) -#define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) +#define FT_MEM_MOVE( dest, source, count ) \ + ft_memmove( dest, source, (FT_Offset)(count) ) #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) @@ -227,14 +232,19 @@ FT_BEGIN_HEADER #define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) -#define FT_ARRAY_ZERO( dest, count ) \ - FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) ) +#define FT_ARRAY_ZERO( dest, count ) \ + FT_MEM_ZERO( dest, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) -#define FT_ARRAY_COPY( dest, source, count ) \ - FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) ) +#define FT_ARRAY_COPY( dest, source, count ) \ + FT_MEM_COPY( dest, \ + source, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) -#define FT_ARRAY_MOVE( dest, source, count ) \ - FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) ) +#define FT_ARRAY_MOVE( dest, source, count ) \ + FT_MEM_MOVE( dest, \ + source, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) /* @@ -372,7 +382,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMEMORY_H__ */ +#endif /* FTMEMORY_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftobjs.h b/drivers/freetype/include/freetype/internal/ftobjs.h index 701c850eb7..e3fa32083b 100644 --- a/drivers/freetype/include/freetype/internal/ftobjs.h +++ b/drivers/freetype/include/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (specification). */ /* */ -/* Copyright 1996-2006, 2008, 2010, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /*************************************************************************/ -#ifndef __FTOBJS_H__ -#define __FTOBJS_H__ +#ifndef FTOBJS_H_ +#define FTOBJS_H_ #include <ft2build.h> #include FT_RENDER_H @@ -72,24 +72,27 @@ FT_BEGIN_HEADER #define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) - -#define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) ) + /* + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. + */ +#define FT_HYPOT( x, y ) \ + ( x = FT_ABS( x ), \ + y = FT_ABS( y ), \ + x > y ? x + ( 3 * y >> 3 ) \ + : y + ( 3 * x >> 3 ) ) + + /* we use FT_TYPEOF to suppress signedness compilation warnings */ +#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n)-1 ) ) #define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) #define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) -#define FT_PIX_FLOOR( x ) ( (x) & ~63 ) +#define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) #define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) - /* - * Return the highest power of 2 that is <= value; this correspond to - * the highest bit in a given 32-bit value. - */ - FT_BASE( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ); - - /* * character classification functions -- since these are used to parse * font files, we must not use those in <ctypes.h> which are @@ -338,12 +341,6 @@ 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. */ - /* */ /* refcount :: */ /* A counter initialized to~1 at the time an @FT_Face structure is */ /* created. @FT_Reference_Face increments this counter, and */ @@ -362,7 +359,6 @@ FT_BEGIN_HEADER FT_Incremental_InterfaceRec* incremental_interface; #endif - FT_Bool ignore_unpatented_hinter; FT_Int refcount; } FT_Face_InternalRec; @@ -402,7 +398,7 @@ FT_BEGIN_HEADER /* glyph_hints :: Format-specific glyph hints management. */ /* */ -#define FT_GLYPH_OWN_BITMAP 0x1 +#define FT_GLYPH_OWN_BITMAP 0x1U typedef struct FT_Slot_InternalRec_ { @@ -503,6 +499,9 @@ FT_BEGIN_HEADER #define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ FT_MODULE_DRIVER_HAS_HINTER ) +#define FT_DRIVER_HINTS_LIGHTLY( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HINTS_LIGHTLY ) + /*************************************************************************/ /* */ @@ -611,12 +610,12 @@ FT_BEGIN_HEADER #define FT_REQUEST_WIDTH( req ) \ ( (req)->horiResolution \ - ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \ + ? ( (req)->width * (FT_Pos)(req)->horiResolution + 36 ) / 72 \ : (req)->width ) #define FT_REQUEST_HEIGHT( req ) \ ( (req)->vertResolution \ - ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \ + ? ( (req)->height * (FT_Pos)(req)->vertResolution + 36 ) / 72 \ : (req)->height ) @@ -738,9 +737,8 @@ FT_BEGIN_HEADER /* faces_list :: The list of faces currently opened by this */ /* driver. */ /* */ - /* glyph_loader :: The glyph loader for all faces managed by this */ - /* driver. This object isn't defined for unscalable */ - /* formats. */ + /* glyph_loader :: Unused. Used to be glyph loader for all faces */ + /* managed by this driver. */ /* */ typedef struct FT_DriverRec_ { @@ -770,13 +768,6 @@ FT_BEGIN_HEADER #define FT_DEBUG_HOOK_TRUETYPE 0 - /* Set this debug hook to a non-null pointer to force unpatented hinting */ - /* 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 ); @@ -842,7 +833,7 @@ FT_BEGIN_HEADER /* filtering callback function. */ /* */ /* pic_container :: Contains global structs and tables, instead */ - /* of defining them globallly. */ + /* of defining them globally. */ /* */ /* refcount :: A counter initialized to~1 at the time an */ /* @FT_Library structure is created. */ @@ -980,8 +971,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Outline_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1039,8 +1030,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Raster_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1099,8 +1090,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Glyph_Class struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated stcture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1173,11 +1164,11 @@ FT_BEGIN_HEADER /* <Description> */ /* Used to initialize an instance of FT_Renderer_Class struct. */ /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need */ - /* to be called with a pointer where the allocated structure is */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function will */ + /* need to be called with a pointer where the allocated structure is */ /* returned. And when it is no longer needed a `destroy' function */ /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ /* a mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -1377,11 +1368,11 @@ FT_BEGIN_HEADER /* <Description> */ /* Used to initialize an instance of an FT_Module_Class struct. */ /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to */ - /* be called with a pointer where the allocated structure is */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs */ + /* to be called with a pointer where the allocated structure is */ /* returned. And when it is no longer needed a `destroy' function */ /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ /* a mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -1563,7 +1554,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOBJS_H__ */ +#endif /* FTOBJS_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftpic.h b/drivers/freetype/include/freetype/internal/ftpic.h index 485ce7a24e..6d800a08a1 100644 --- a/drivers/freetype/include/freetype/internal/ftpic.h +++ b/drivers/freetype/include/freetype/internal/ftpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (declaration). */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /*************************************************************************/ -#ifndef __FTPIC_H__ -#define __FTPIC_H__ +#ifndef FTPIC_H_ +#define FTPIC_H_ FT_BEGIN_HEADER @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTPIC_H__ */ +#endif /* FTPIC_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftrfork.h b/drivers/freetype/include/freetype/internal/ftrfork.h index 6307f2d0c5..b923401e68 100644 --- a/drivers/freetype/include/freetype/internal/ftrfork.h +++ b/drivers/freetype/include/freetype/internal/ftrfork.h @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (specification). */ /* */ -/* Copyright 2004, 2006, 2007, 2012 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ /***************************************************************************/ -#ifndef __FTRFORK_H__ -#define __FTRFORK_H__ +#ifndef FTRFORK_H_ +#define FTRFORK_H_ #include <ft2build.h> @@ -44,7 +44,7 @@ FT_BEGIN_HEADER typedef struct FT_RFork_Ref_ { FT_UShort res_id; - FT_ULong offset; + FT_Long offset; } FT_RFork_Ref; @@ -83,7 +83,7 @@ FT_BEGIN_HEADER /* this array is a storage in non-PIC mode, so ; is needed in END */ #define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ - const type name[] = { + static const type name[] = { #define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ { raccess_guess_ ## func_suffix, \ FT_RFork_Rule_ ## type_suffix }, @@ -94,7 +94,7 @@ FT_BEGIN_HEADER /* this array is a function in PIC mode, so no ; is needed in END */ #define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ void \ - FT_Init_ ## name( type* storage ) \ + FT_Init_Table_ ## name( type* storage ) \ { \ type* local = storage; \ \ @@ -224,6 +224,13 @@ FT_BEGIN_HEADER /* tag :: */ /* The resource tag. */ /* */ + /* sort_by_res_id :: */ + /* A Boolean to sort the fragmented resource by their ids. */ + /* The fragmented resources for `POST' resource should be sorted */ + /* to restore Type1 font properly. For `sfnt' resources, sorting */ + /* may induce a different order of the faces in comparison to that */ + /* by QuickDraw API. */ + /* */ /* <Output> */ /* offsets :: */ /* The stream offsets for the resource data specified by `tag'. */ @@ -246,13 +253,14 @@ FT_BEGIN_HEADER FT_Long map_offset, FT_Long rdata_pos, FT_Long tag, + FT_Bool sort_by_res_id, FT_Long **offsets, FT_Long *count ); FT_END_HEADER -#endif /* __FTRFORK_H__ */ +#endif /* FTRFORK_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftserv.h b/drivers/freetype/include/freetype/internal/ftserv.h index cd5fbd0fac..91897177ba 100644 --- a/drivers/freetype/include/freetype/internal/ftserv.h +++ b/drivers/freetype/include/freetype/internal/ftserv.h @@ -4,7 +4,7 @@ /* */ /* The FreeType services (specification only). */ /* */ -/* Copyright 2003-2007, 2009, 2012, 2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,8 @@ /*************************************************************************/ -#ifndef __FTSERV_H__ -#define __FTSERV_H__ +#ifndef FTSERV_H_ +#define FTSERV_H_ FT_BEGIN_HEADER @@ -750,14 +750,14 @@ FT_BEGIN_HEADER #define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> #define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> #define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> -#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> +#define FT_SERVICE_FONT_FORMAT_H <freetype/internal/services/svfntfmt.h> #define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> /* */ FT_END_HEADER -#endif /* __FTSERV_H__ */ +#endif /* FTSERV_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftstream.h b/drivers/freetype/include/freetype/internal/ftstream.h index 2661858320..6d04875657 100644 --- a/drivers/freetype/include/freetype/internal/ftstream.h +++ b/drivers/freetype/include/freetype/internal/ftstream.h @@ -4,7 +4,7 @@ /* */ /* Stream handling (specification). */ /* */ -/* Copyright 1996-2002, 2004-2006, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSTREAM_H__ -#define __FTSTREAM_H__ +#ifndef FTSTREAM_H_ +#define FTSTREAM_H_ #include <ft2build.h> @@ -361,7 +361,7 @@ FT_BEGIN_HEADER FT_Long distance ); /* return current stream position */ - FT_BASE( FT_Long ) + FT_BASE( FT_ULong ) FT_Stream_Pos( FT_Stream stream ); /* read bytes from a stream into a user-allocated buffer, returns an */ @@ -530,7 +530,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSTREAM_H__ */ +#endif /* FTSTREAM_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/fttrace.h b/drivers/freetype/include/freetype/internal/fttrace.h index a9d98b60aa..efb3355954 100644 --- a/drivers/freetype/include/freetype/internal/fttrace.h +++ b/drivers/freetype/include/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ /* */ /* Tracing handling (specification only). */ /* */ -/* Copyright 2002, 2004-2007, 2009, 2011-2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -148,5 +148,7 @@ FT_TRACE_DEF( afcjk ) FT_TRACE_DEF( aflatin ) FT_TRACE_DEF( aflatin2 ) FT_TRACE_DEF( afwarp ) +FT_TRACE_DEF( afshaper ) +FT_TRACE_DEF( afglobal ) /* END */ diff --git a/drivers/freetype/include/freetype/internal/ftvalid.h b/drivers/freetype/include/freetype/internal/ftvalid.h index 12ad03685a..aac92c9af8 100644 --- a/drivers/freetype/include/freetype/internal/ftvalid.h +++ b/drivers/freetype/include/freetype/internal/ftvalid.h @@ -4,7 +4,7 @@ /* */ /* FreeType validation support (specification). */ /* */ -/* Copyright 2004, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTVALID_H__ -#define __FTVALID_H__ +#ifndef FTVALID_H_ +#define FTVALID_H_ #include <ft2build.h> #include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ @@ -87,13 +87,13 @@ FT_BEGIN_HEADER /* validator structure */ typedef struct FT_ValidatorRec_ { + ft_jmp_buf jump_buffer; /* used for exception handling */ + const FT_Byte* base; /* address of table in memory */ const FT_Byte* limit; /* `base' + sizeof(table) in memory */ FT_ValidationLevel level; /* validation level */ FT_Error error; /* error returned. 0 means success */ - ft_jmp_buf jump_buffer; /* used for exception handling */ - } FT_ValidatorRec; #if defined( _MSC_VER ) @@ -126,36 +126,34 @@ FT_BEGIN_HEADER /* Calls ft_validate_error. Assumes that the `valid' local variable */ /* holds a pointer to the current validator object. */ /* */ - /* Use preprocessor prescan to pass FT_ERR_PREFIX. */ - /* */ -#define FT_INVALID( _prefix, _error ) FT_INVALID_( _prefix, _error ) -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid, _prefix ## _error ) +#define FT_INVALID( _error ) FT_INVALID_( _error ) +#define FT_INVALID_( _error ) \ + ft_validator_error( valid, FT_THROW( _error ) ) /* called when a broken table is detected */ #define FT_INVALID_TOO_SHORT \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + FT_INVALID( Invalid_Table ) /* called when an invalid offset is detected */ #define FT_INVALID_OFFSET \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Offset ) + FT_INVALID( Invalid_Offset ) /* called when an invalid format/value is detected */ #define FT_INVALID_FORMAT \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + FT_INVALID( Invalid_Table ) /* called when an invalid glyph index is detected */ #define FT_INVALID_GLYPH_ID \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index ) + FT_INVALID( Invalid_Glyph_Index ) /* called when an invalid field value is detected */ #define FT_INVALID_DATA \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + FT_INVALID( Invalid_Table ) FT_END_HEADER -#endif /* __FTVALID_H__ */ +#endif /* FTVALID_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/internal.h b/drivers/freetype/include/freetype/internal/internal.h index 262afcfa8a..8c3c14c12a 100644 --- a/drivers/freetype/include/freetype/internal/internal.h +++ b/drivers/freetype/include/freetype/internal/internal.h @@ -4,7 +4,7 @@ /* */ /* Internal header files (specification only). */ /* */ -/* Copyright 1996-2004, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,6 +30,7 @@ #define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> #define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> #define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> +#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h> #define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> #define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> #define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> @@ -43,7 +44,6 @@ #define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> #define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> -#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> #define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> diff --git a/drivers/freetype/include/freetype/internal/psaux.h b/drivers/freetype/include/freetype/internal/psaux.h index e903114f84..15dedfd28e 100644 --- a/drivers/freetype/include/freetype/internal/psaux.h +++ b/drivers/freetype/include/freetype/internal/psaux.h @@ -5,7 +5,7 @@ /* Auxiliary functions and data structures related to PostScript fonts */ /* (specification). */ /* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,13 +17,14 @@ /***************************************************************************/ -#ifndef __PSAUX_H__ -#define __PSAUX_H__ +#ifndef PSAUX_H_ +#define PSAUX_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H @@ -71,10 +72,10 @@ FT_BEGIN_HEADER (*done)( PS_Table table ); FT_Error - (*add)( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ); + (*add)( PS_Table table, + FT_Int idx, + void* object, + FT_UInt length ); void (*release)( PS_Table table ); @@ -122,12 +123,12 @@ FT_BEGIN_HEADER FT_Byte* block; /* current memory block */ FT_Offset cursor; /* current cursor in memory block */ FT_Offset capacity; /* current size of memory block */ - FT_Long init; + FT_ULong init; FT_Int max_elems; FT_Int num_elems; FT_Byte** elements; /* addresses of table elements */ - FT_PtrDist* lengths; /* lengths of table elements */ + FT_UInt* lengths; /* lengths of table elements */ FT_Memory memory; PS_Table_FuncsRec funcs; @@ -365,7 +366,7 @@ FT_BEGIN_HEADER (*to_bytes)( PS_Parser parser, FT_Byte* bytes, FT_Offset max_bytes, - FT_Long* pnum_bytes, + FT_ULong* pnum_bytes, FT_Bool delimiters ); FT_Int @@ -675,9 +676,10 @@ FT_BEGIN_HEADER FT_Byte** glyph_names; FT_Int lenIV; /* internal for sub routine calls */ - FT_UInt num_subrs; + FT_Int num_subrs; FT_Byte** subrs; - FT_PtrDist* subrs_len; /* array of subrs length (optional) */ + FT_UInt* subrs_len; /* array of subrs length (optional) */ + FT_Hash subrs_hash; /* used if `num_subrs' was massaged */ FT_Matrix font_matrix; FT_Vector font_offset; @@ -871,7 +873,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSAUX_H__ */ +#endif /* PSAUX_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/pshints.h b/drivers/freetype/include/freetype/internal/pshints.h index 3fb18dc2d5..e60dc9cd55 100644 --- a/drivers/freetype/include/freetype/internal/pshints.h +++ b/drivers/freetype/include/freetype/internal/pshints.h @@ -6,7 +6,7 @@ /* recorders (specification only). These are used to support native */ /* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ /* */ -/* Copyright 2001-2003, 2005-2007, 2009, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,8 +18,8 @@ /***************************************************************************/ -#ifndef __PSHINTS_H__ -#define __PSHINTS_H__ +#ifndef PSHINTS_H_ +#define PSHINTS_H_ #include <ft2build.h> @@ -45,7 +45,7 @@ FT_BEGIN_HEADER T1_Private* private_dict, PSH_Globals* aglobals ); - typedef FT_Error + typedef void (*PSH_Globals_SetScaleFunc)( PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, @@ -465,7 +465,7 @@ FT_BEGIN_HEADER typedef void (*T2_Hints_StemsFunc)( T2_Hints hints, FT_UInt dimension, - FT_UInt count, + FT_Int count, FT_Fixed* coordinates ); @@ -716,7 +716,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHINTS_H__ */ +#endif /* PSHINTS_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svbdf.h b/drivers/freetype/include/freetype/internal/services/svbdf.h index 0974752a79..c24475fc20 100644 --- a/drivers/freetype/include/freetype/internal/services/svbdf.h +++ b/drivers/freetype/include/freetype/internal/services/svbdf.h @@ -4,7 +4,7 @@ /* */ /* The FreeType BDF services (specification). */ /* */ -/* Copyright 2003, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVBDF_H__ -#define __SVBDF_H__ +#ifndef SVBDF_H_ +#define SVBDF_H_ #include FT_BDF_H #include FT_INTERNAL_SERVICE_H @@ -76,7 +76,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVBDF_H__ */ +#endif /* SVBDF_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svcid.h b/drivers/freetype/include/freetype/internal/services/svcid.h index 6be3f9374d..dbbe6044a4 100644 --- a/drivers/freetype/include/freetype/internal/services/svcid.h +++ b/drivers/freetype/include/freetype/internal/services/svcid.h @@ -4,7 +4,8 @@ /* */ /* The FreeType CID font services (specification). */ /* */ -/* Copyright 2007, 2009, 2012 by Derek Clegg, Michael Toftdal. */ +/* Copyright 2007-2016 by */ +/* Derek Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVCID_H__ -#define __SVCID_H__ +#ifndef SVCID_H_ +#define SVCID_H_ #include FT_INTERNAL_SERVICE_H @@ -83,7 +84,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVCID_H__ */ +#endif /* SVCID_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svfntfmt.h b/drivers/freetype/include/freetype/internal/services/svfntfmt.h new file mode 100644 index 0000000000..bd295c9c6b --- /dev/null +++ b/drivers/freetype/include/freetype/internal/services/svfntfmt.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svfntfmt.h */ +/* */ +/* The FreeType font format service (specification only). */ +/* */ +/* Copyright 2003-2016 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 SVFNTFMT_H_ +#define SVFNTFMT_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A trivial service used to return the name of a face's font driver, + * according to the XFree86 nomenclature. Note that the service data + * is a simple constant string pointer. + */ + +#define FT_SERVICE_ID_FONT_FORMAT "font-format" + +#define FT_FONT_FORMAT_TRUETYPE "TrueType" +#define FT_FONT_FORMAT_TYPE_1 "Type 1" +#define FT_FONT_FORMAT_BDF "BDF" +#define FT_FONT_FORMAT_PCF "PCF" +#define FT_FONT_FORMAT_TYPE_42 "Type 42" +#define FT_FONT_FORMAT_CID "CID Type 1" +#define FT_FONT_FORMAT_CFF "CFF" +#define FT_FONT_FORMAT_PFR "PFR" +#define FT_FONT_FORMAT_WINFNT "Windows FNT" + + /* */ + + +FT_END_HEADER + + +#endif /* SVFNTFMT_H_ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svgldict.h b/drivers/freetype/include/freetype/internal/services/svgldict.h index 1d12534725..fff29bc40c 100644 --- a/drivers/freetype/include/freetype/internal/services/svgldict.h +++ b/drivers/freetype/include/freetype/internal/services/svgldict.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph dictionary services (specification). */ /* */ -/* Copyright 2003, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVGLDICT_H__ -#define __SVGLDICT_H__ +#ifndef SVGLDICT_H_ +#define SVGLDICT_H_ #include FT_INTERNAL_SERVICE_H @@ -85,4 +85,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVGLDICT_H__ */ +#endif /* SVGLDICT_H_ */ + + +/* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svgxval.h b/drivers/freetype/include/freetype/internal/services/svgxval.h index 2cdab50655..fb8ffba83c 100644 --- a/drivers/freetype/include/freetype/internal/services/svgxval.h +++ b/drivers/freetype/include/freetype/internal/services/svgxval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTypeGX/AAT tables (specification). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __SVGXVAL_H__ -#define __SVGXVAL_H__ +#ifndef SVGXVAL_H_ +#define SVGXVAL_H_ #include FT_GX_VALIDATE_H #include FT_INTERNAL_VALIDATE_H @@ -66,7 +66,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVGXVAL_H__ */ +#endif /* SVGXVAL_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svkern.h b/drivers/freetype/include/freetype/internal/services/svkern.h index 1488adf493..a636f1af1c 100644 --- a/drivers/freetype/include/freetype/internal/services/svkern.h +++ b/drivers/freetype/include/freetype/internal/services/svkern.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Kerning service (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVKERN_H__ -#define __SVKERN_H__ +#ifndef SVKERN_H_ +#define SVKERN_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVKERN_H__ */ +#endif /* SVKERN_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svmm.h b/drivers/freetype/include/freetype/internal/services/svmm.h index b08a663d66..b78a19f8e0 100644 --- a/drivers/freetype/include/freetype/internal/services/svmm.h +++ b/drivers/freetype/include/freetype/internal/services/svmm.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Multiple Masters and GX var services (specification). */ /* */ -/* Copyright 2003, 2004, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVMM_H__ -#define __SVMM_H__ +#ifndef SVMM_H_ +#define SVMM_H_ #include FT_INTERNAL_SERVICE_H @@ -107,7 +107,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVMM_H__ */ +#endif /* SVMM_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svotval.h b/drivers/freetype/include/freetype/internal/services/svotval.h index 970bbd5759..bc929d4bd9 100644 --- a/drivers/freetype/include/freetype/internal/services/svotval.h +++ b/drivers/freetype/include/freetype/internal/services/svotval.h @@ -4,7 +4,7 @@ /* */ /* The FreeType OpenType validation service (specification). */ /* */ -/* Copyright 2004, 2006 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVOTVAL_H__ -#define __SVOTVAL_H__ +#ifndef SVOTVAL_H_ +#define SVOTVAL_H_ #include FT_OPENTYPE_VALIDATE_H #include FT_INTERNAL_VALIDATE_H @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVOTVAL_H__ */ +#endif /* SVOTVAL_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svpfr.h b/drivers/freetype/include/freetype/internal/services/svpfr.h index 462786f9ce..d0f7c4df95 100644 --- a/drivers/freetype/include/freetype/internal/services/svpfr.h +++ b/drivers/freetype/include/freetype/internal/services/svpfr.h @@ -4,7 +4,7 @@ /* */ /* Internal PFR service functions (specification). */ /* */ -/* Copyright 2003, 2006 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPFR_H__ -#define __SVPFR_H__ +#ifndef SVPFR_H_ +#define SVPFR_H_ #include FT_PFR_H #include FT_INTERNAL_SERVICE_H @@ -60,7 +60,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPFR_H__ */ +#endif /* SVPFR_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svpostnm.h b/drivers/freetype/include/freetype/internal/services/svpostnm.h index a76b4fe057..f124380050 100644 --- a/drivers/freetype/include/freetype/internal/services/svpostnm.h +++ b/drivers/freetype/include/freetype/internal/services/svpostnm.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript name services (specification). */ /* */ -/* Copyright 2003, 2007, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPOSTNM_H__ -#define __SVPOSTNM_H__ +#ifndef SVPOSTNM_H_ +#define SVPOSTNM_H_ #include FT_INTERNAL_SERVICE_H @@ -75,7 +75,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPOSTNM_H__ */ +#endif /* SVPOSTNM_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svprop.h b/drivers/freetype/include/freetype/internal/services/svprop.h index 22da0bbc69..870e90ed7c 100644 --- a/drivers/freetype/include/freetype/internal/services/svprop.h +++ b/drivers/freetype/include/freetype/internal/services/svprop.h @@ -4,7 +4,7 @@ /* */ /* The FreeType property service (specification). */ /* */ -/* Copyright 2012 by */ +/* Copyright 2012-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPROP_H__ -#define __SVPROP_H__ +#ifndef SVPROP_H_ +#define SVPROP_H_ FT_BEGIN_HEADER @@ -75,7 +75,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPROP_H__ */ +#endif /* SVPROP_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svpscmap.h b/drivers/freetype/include/freetype/internal/services/svpscmap.h index 030948ea64..9acc21690f 100644 --- a/drivers/freetype/include/freetype/internal/services/svpscmap.h +++ b/drivers/freetype/include/freetype/internal/services/svpscmap.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript charmap service (specification). */ /* */ -/* Copyright 2003, 2006, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPSCMAP_H__ -#define __SVPSCMAP_H__ +#ifndef SVPSCMAP_H_ +#define SVPSCMAP_H_ #include FT_INTERNAL_OBJECTS_H @@ -171,7 +171,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPSCMAP_H__ */ +#endif /* SVPSCMAP_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svpsinfo.h b/drivers/freetype/include/freetype/internal/services/svpsinfo.h index 4bfb506711..f2c8060440 100644 --- a/drivers/freetype/include/freetype/internal/services/svpsinfo.h +++ b/drivers/freetype/include/freetype/internal/services/svpsinfo.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript info service (specification). */ /* */ -/* Copyright 2003, 2004, 2009, 2011, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPSINFO_H__ -#define __SVPSINFO_H__ +#ifndef SVPSINFO_H_ +#define SVPSINFO_H_ #include FT_INTERNAL_SERVICE_H #include FT_INTERNAL_TYPE1_TYPES_H @@ -105,7 +105,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPSINFO_H__ */ +#endif /* SVPSINFO_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svsfnt.h b/drivers/freetype/include/freetype/internal/services/svsfnt.h index d3835aa1c2..0f38cf195f 100644 --- a/drivers/freetype/include/freetype/internal/services/svsfnt.h +++ b/drivers/freetype/include/freetype/internal/services/svsfnt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType SFNT table loading service (specification). */ /* */ -/* Copyright 2003, 2004, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVSFNT_H__ -#define __SVSFNT_H__ +#ifndef SVSFNT_H_ +#define SVSFNT_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -97,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVSFNT_H__ */ +#endif /* SVSFNT_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svttcmap.h b/drivers/freetype/include/freetype/internal/services/svttcmap.h index 83994aaf8a..772c72189e 100644 --- a/drivers/freetype/include/freetype/internal/services/svttcmap.h +++ b/drivers/freetype/include/freetype/internal/services/svttcmap.h @@ -4,10 +4,8 @@ /* */ /* The FreeType TrueType/sfnt cmap extra information service. */ /* */ -/* Copyright 2003 by */ -/* Masatake YAMATO, Redhat K.K. */ -/* */ -/* Copyright 2003, 2008, 2009, 2012 by */ +/* Copyright 2003-2016 by */ +/* Masatake YAMATO, Redhat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +19,8 @@ /* Development of this service is support of Information-technology Promotion Agency, Japan. */ -#ifndef __SVTTCMAP_H__ -#define __SVTTCMAP_H__ +#ifndef SVTTCMAP_H_ +#define SVTTCMAP_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -47,14 +45,15 @@ FT_BEGIN_HEADER /* <Fields> */ /* language :: */ /* The language ID used in Mac fonts. Definitions of values are in */ - /* freetype/ttnameid.h. */ + /* `ttnameid.h'. */ /* */ /* format :: */ - /* The cmap format. OpenType 1.5 defines the formats 0 (byte */ + /* The cmap format. OpenType 1.6 defines the formats 0 (byte */ /* encoding table), 2~(high-byte mapping through table), 4~(segment */ /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ - /* coverage), and 14 (Unicode Variation Sequences). */ + /* coverage), 13~(last resort font), and 14 (Unicode Variation */ + /* Sequences). */ /* */ typedef struct TT_CMapInfo_ { @@ -101,7 +100,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTCMAP_H__ */ +#endif /* SVTTCMAP_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svtteng.h b/drivers/freetype/include/freetype/internal/services/svtteng.h index 58e02a6f9d..c55061a034 100644 --- a/drivers/freetype/include/freetype/internal/services/svtteng.h +++ b/drivers/freetype/include/freetype/internal/services/svtteng.h @@ -4,7 +4,7 @@ /* */ /* The FreeType TrueType engine query service (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVTTENG_H__ -#define __SVTTENG_H__ +#ifndef SVTTENG_H_ +#define SVTTENG_H_ #include FT_INTERNAL_SERVICE_H #include FT_MODULE_H @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTENG_H__ */ +#endif /* SVTTENG_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svttglyf.h b/drivers/freetype/include/freetype/internal/services/svttglyf.h index 369eb8421b..c33edd46de 100644 --- a/drivers/freetype/include/freetype/internal/services/svttglyf.h +++ b/drivers/freetype/include/freetype/internal/services/svttglyf.h @@ -4,7 +4,8 @@ /* */ /* The FreeType TrueType glyph service. */ /* */ -/* Copyright 2007, 2009, 2012 by David Turner. */ +/* Copyright 2007-2016 by */ +/* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -14,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __SVTTGLYF_H__ -#define __SVTTGLYF_H__ +#ifndef SVTTGLYF_H_ +#define SVTTGLYF_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -62,7 +63,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTGLYF_H__ */ +#endif /* SVTTGLYF_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svwinfnt.h b/drivers/freetype/include/freetype/internal/services/svwinfnt.h index 57f7765d92..c2f6d4c6d3 100644 --- a/drivers/freetype/include/freetype/internal/services/svwinfnt.h +++ b/drivers/freetype/include/freetype/internal/services/svwinfnt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Windows FNT/FONT service (specification). */ /* */ -/* Copyright 2003 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVWINFNT_H__ -#define __SVWINFNT_H__ +#ifndef SVWINFNT_H_ +#define SVWINFNT_H_ #include FT_INTERNAL_SERVICE_H #include FT_WINFONTS_H @@ -44,7 +44,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVWINFNT_H__ */ +#endif /* SVWINFNT_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/services/svxf86nm.h b/drivers/freetype/include/freetype/internal/services/svxf86nm.h deleted file mode 100644 index ca5d884a83..0000000000 --- a/drivers/freetype/include/freetype/internal/services/svxf86nm.h +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************/ -/* */ -/* svxf86nm.h */ -/* */ -/* The FreeType XFree86 services (specification only). */ -/* */ -/* Copyright 2003 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 __SVXF86NM_H__ -#define __SVXF86NM_H__ - -#include FT_INTERNAL_SERVICE_H - - -FT_BEGIN_HEADER - - - /* - * A trivial service used to return the name of a face's font driver, - * according to the XFree86 nomenclature. Note that the service data - * is a simple constant string pointer. - */ - -#define FT_SERVICE_ID_XF86_NAME "xf86-driver-name" - -#define FT_XF86_FORMAT_TRUETYPE "TrueType" -#define FT_XF86_FORMAT_TYPE_1 "Type 1" -#define FT_XF86_FORMAT_BDF "BDF" -#define FT_XF86_FORMAT_PCF "PCF" -#define FT_XF86_FORMAT_TYPE_42 "Type 42" -#define FT_XF86_FORMAT_CID "CID Type 1" -#define FT_XF86_FORMAT_CFF "CFF" -#define FT_XF86_FORMAT_PFR "PFR" -#define FT_XF86_FORMAT_WINFNT "Windows FNT" - - /* */ - - -FT_END_HEADER - - -#endif /* __SVXF86NM_H__ */ - - -/* END */ diff --git a/drivers/freetype/include/freetype/internal/sfnt.h b/drivers/freetype/include/freetype/internal/sfnt.h index 6b5e41f1ad..e139315a1f 100644 --- a/drivers/freetype/include/freetype/internal/sfnt.h +++ b/drivers/freetype/include/freetype/internal/sfnt.h @@ -4,7 +4,7 @@ /* */ /* High-level `sfnt' driver interface (specification). */ /* */ -/* Copyright 1996-2006, 2009, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFNT_H__ -#define __SFNT_H__ +#ifndef SFNT_H_ +#define SFNT_H_ #include <ft2build.h> @@ -44,7 +44,9 @@ FT_BEGIN_HEADER /* face :: A handle to the target face object. */ /* */ /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: The number of additional parameters. */ /* */ @@ -87,7 +89,9 @@ FT_BEGIN_HEADER /* face :: A handle to the target face object. */ /* */ /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: The number of additional parameters. */ /* */ @@ -405,14 +409,18 @@ FT_BEGIN_HEADER /* <Input> */ /* face :: A handle to the target face object. */ /* */ - /* stream :: The input stream. */ - /* */ /* vertical :: A boolean flag. If set, load vertical metrics. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ + /* gindex :: The glyph index. */ /* */ - typedef FT_Error + /* <Output> */ + /* abearing :: The horizontal (or vertical) bearing. Set to zero in */ + /* case of error. */ + /* */ + /* aadvance :: The horizontal (or vertical) advance. Set to zero in */ + /* case of error. */ + /* */ + typedef void (*TT_Get_Metrics_Func)( TT_Face face, FT_Bool vertical, FT_UInt gindex, @@ -420,6 +428,33 @@ FT_BEGIN_HEADER FT_UShort* aadvance ); + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_Name_Func */ + /* */ + /* <Description> */ + /* From the `name' table, return a given ENGLISH name record in */ + /* ASCII. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* nameid :: The name id of the name record to return. */ + /* */ + /* <InOut> */ + /* name :: The address of an allocated string pointer. NULL if */ + /* no name is present. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_Name_Func)( TT_Face face, + FT_UShort nameid, + FT_String** name ); + + /*************************************************************************/ /* */ /* <FuncType> */ @@ -552,6 +587,8 @@ FT_BEGIN_HEADER TT_Get_Metrics_Func get_metrics; + TT_Get_Name_Func get_name; + } SFNT_Interface; @@ -590,7 +627,8 @@ FT_BEGIN_HEADER free_eblc_, \ set_sbit_strike_, \ load_strike_metrics_, \ - get_metrics_ ) \ + get_metrics_, \ + get_name_ ) \ static const SFNT_Interface class_ = \ { \ goto_table_, \ @@ -622,6 +660,7 @@ FT_BEGIN_HEADER set_sbit_strike_, \ load_strike_metrics_, \ get_metrics_, \ + get_name_, \ }; #else /* FT_CONFIG_OPTION_PIC */ @@ -659,7 +698,8 @@ FT_BEGIN_HEADER free_eblc_, \ set_sbit_strike_, \ load_strike_metrics_, \ - get_metrics_ ) \ + get_metrics_, \ + get_name_ ) \ void \ FT_Init_Class_ ## class_( FT_Library library, \ SFNT_Interface* clazz ) \ @@ -695,13 +735,14 @@ FT_BEGIN_HEADER clazz->set_sbit_strike = set_sbit_strike_; \ clazz->load_strike_metrics = load_strike_metrics_; \ clazz->get_metrics = get_metrics_; \ + clazz->get_name = get_name_; \ } #endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER -#endif /* __SFNT_H__ */ +#endif /* SFNT_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/t1types.h b/drivers/freetype/include/freetype/internal/t1types.h index e20237c14d..494c011fc7 100644 --- a/drivers/freetype/include/freetype/internal/t1types.h +++ b/drivers/freetype/include/freetype/internal/t1types.h @@ -5,7 +5,7 @@ /* Basic Type1/Type2 type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,14 +17,15 @@ /***************************************************************************/ -#ifndef __T1TYPES_H__ -#define __T1TYPES_H__ +#ifndef T1TYPES_H_ +#define T1TYPES_H_ #include <ft2build.h> #include FT_TYPE1_TABLES_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H @@ -106,12 +107,13 @@ FT_BEGIN_HEADER FT_Int num_subrs; FT_Byte** subrs; - FT_PtrDist* subrs_len; + FT_UInt* subrs_len; + FT_Hash subrs_hash; FT_Int num_glyphs; FT_String** glyph_names; /* array of glyph names */ FT_Byte** charstrings; /* array of glyph charstrings */ - FT_PtrDist* charstrings_len; + FT_UInt* charstrings_len; FT_Byte paint_type; FT_Byte font_type; @@ -127,7 +129,7 @@ FT_BEGIN_HEADER typedef struct CID_SubrsRec_ { - FT_UInt num_subrs; + FT_Int num_subrs; FT_Byte** code; } CID_SubrsRec, *CID_Subrs; @@ -157,10 +159,10 @@ FT_BEGIN_HEADER typedef struct AFM_KernPairRec_ { - FT_Int index1; - FT_Int index2; - FT_Int x; - FT_Int y; + FT_UInt index1; + FT_UInt index2; + FT_Int x; + FT_Int y; } AFM_KernPairRec, *AFM_KernPair; @@ -171,9 +173,9 @@ FT_BEGIN_HEADER FT_Fixed Ascender; FT_Fixed Descender; AFM_TrackKern TrackKerns; /* free if non-NULL */ - FT_Int NumTrackKern; + FT_UInt NumTrackKern; AFM_KernPair KernPairs; /* free if non-NULL */ - FT_Int NumKernPair; + FT_UInt NumKernPair; } AFM_FontInfoRec, *AFM_FontInfo; @@ -249,7 +251,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TYPES_H__ */ +#endif /* T1TYPES_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/tttypes.h b/drivers/freetype/include/freetype/internal/tttypes.h index 1bbfe499c5..4110d50285 100644 --- a/drivers/freetype/include/freetype/internal/tttypes.h +++ b/drivers/freetype/include/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2002, 2004-2008, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTTYPES_H__ -#define __TTTYPES_H__ +#ifndef TTTYPES_H_ +#define TTTYPES_H_ #include <ft2build.h> @@ -137,6 +137,75 @@ FT_BEGIN_HEADER } TT_TableRec, *TT_Table; + /*************************************************************************/ + /* */ + /* <Struct> */ + /* WOFF_HeaderRec */ + /* */ + /* <Description> */ + /* WOFF file format header. */ + /* */ + /* <Fields> */ + /* See */ + /* */ + /* http://www.w3.org/TR/WOFF/#WOFFHeader */ + /* */ + typedef struct WOFF_HeaderRec_ + { + FT_ULong signature; + FT_ULong flavor; + FT_ULong length; + FT_UShort num_tables; + FT_UShort reserved; + FT_ULong totalSfntSize; + FT_UShort majorVersion; + FT_UShort minorVersion; + FT_ULong metaOffset; + FT_ULong metaLength; + FT_ULong metaOrigLength; + FT_ULong privOffset; + FT_ULong privLength; + + } WOFF_HeaderRec, *WOFF_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* WOFF_TableRec */ + /* */ + /* <Description> */ + /* This structure describes a given table of a WOFF font. */ + /* */ + /* <Fields> */ + /* Tag :: A four-bytes tag describing the table. */ + /* */ + /* Offset :: The offset of the table from the start of the WOFF */ + /* font in its resource. */ + /* */ + /* CompLength :: Compressed table length (in bytes). */ + /* */ + /* OrigLength :: Uncompressed table length (in bytes). */ + /* */ + /* CheckSum :: The table checksum. This value can be ignored. */ + /* */ + /* OrigOffset :: The uncompressed table file offset. This value gets */ + /* computed while constructing the (uncompressed) SFNT */ + /* header. It is not contained in the WOFF file. */ + /* */ + typedef struct WOFF_TableRec_ + { + FT_ULong Tag; /* table ID */ + FT_ULong Offset; /* table file offset */ + FT_ULong CompLength; /* compressed table length */ + FT_ULong OrigLength; /* uncompressed table length */ + FT_ULong CheckSum; /* uncompressed checksum */ + + FT_ULong OrigOffset; /* uncompressed table file offset */ + /* (not in the WOFF file) */ + } WOFF_TableRec, *WOFF_Table; + + /*************************************************************************/ /* */ /* <Struct> */ @@ -353,16 +422,16 @@ FT_BEGIN_HEADER /* */ typedef struct TT_SBit_MetricsRec_ { - FT_Byte height; - FT_Byte width; + FT_UShort height; + FT_UShort width; - FT_Char horiBearingX; - FT_Char horiBearingY; - FT_Byte horiAdvance; + FT_Short horiBearingX; + FT_Short horiBearingY; + FT_UShort horiAdvance; - FT_Char vertBearingX; - FT_Char vertBearingY; - FT_Byte vertAdvance; + FT_Short vertBearingX; + FT_Short vertBearingY; + FT_UShort vertAdvance; } TT_SBit_MetricsRec, *TT_SBit_Metrics; @@ -545,8 +614,7 @@ FT_BEGIN_HEADER /* in use by other platforms (e.g. Newton). */ /* For details, please see */ /* */ - /* http://fonts.apple.com/ */ - /* TTRefMan/RM06/Chap6bloc.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */ /* */ /* hori :: The line metrics for horizontal layouts. */ /* */ @@ -566,8 +634,7 @@ FT_BEGIN_HEADER /* flags :: Is this a vertical or horizontal strike? For */ /* details, please see */ /* */ - /* http://fonts.apple.com/ */ - /* TTRefMan/RM06/Chap6bloc.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */ /* */ typedef struct TT_SBit_StrikeRec_ { @@ -979,6 +1046,20 @@ FT_BEGIN_HEADER (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); + typedef enum TT_SbitTableType_ + { + TT_SBIT_TABLE_TYPE_NONE = 0, + TT_SBIT_TABLE_TYPE_EBLC, /* `EBLC' (Microsoft), */ + /* `bloc' (Apple) */ + TT_SBIT_TABLE_TYPE_CBLC, /* `CBLC' (Google) */ + TT_SBIT_TABLE_TYPE_SBIX, /* `sbix' (Apple) */ + + /* do not remove */ + TT_SBIT_TABLE_TYPE_MAX + + } TT_SbitTableType; + + /*************************************************************************/ /* */ /* TrueType Face Type */ @@ -1030,7 +1111,7 @@ FT_BEGIN_HEADER /* This field also contains the associated */ /* vertical metrics table (`vmtx'), if found. */ /* IMPORTANT: The contents of this field is */ - /* undefined if the `verticalInfo' field is */ + /* undefined if the `vertical_info' field is */ /* unset. */ /* */ /* num_names :: The number of name records within this */ @@ -1090,13 +1171,6 @@ FT_BEGIN_HEADER /* */ /* pclt :: The `pclt' SFNT table. */ /* */ - /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ - /* sizes, embedded in this font. */ - /* */ - /* sbit_strikes :: An array of sbit strikes embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ /* num_sbit_scales :: The number of sbit scales for this font. */ /* */ /* sbit_scales :: Array of sbit scales embedded in this */ @@ -1159,9 +1233,6 @@ FT_BEGIN_HEADER /* interpreters field is also used to hook */ /* the debugger in `ttdebug'. */ /* */ - /* unpatented_hinting :: If true, use only unpatented methods in */ - /* the bytecode interpreter. */ - /* */ /* doblend :: A boolean which is set if the font should */ /* be blended (this is for GX var). */ /* */ @@ -1260,10 +1331,6 @@ FT_BEGIN_HEADER /* used to hook the debugger for the `ttdebug' utility. */ TT_Interpreter interpreter; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Use unpatented hinting only. */ - FT_Bool unpatented_hinting; -#endif /***********************************************************************/ /* */ @@ -1302,6 +1369,7 @@ FT_BEGIN_HEADER FT_Byte* sbit_table; FT_ULong sbit_table_size; + TT_SbitTableType sbit_table_type; FT_UInt sbit_num_strikes; FT_Byte* kern_table; @@ -1318,12 +1386,12 @@ FT_BEGIN_HEADER FT_ULong horz_metrics_offset; FT_ULong vert_metrics_offset; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* since 2.4.12 */ FT_ULong sph_found_func_flags; /* special functions found */ /* for this face */ FT_Bool sph_compatibility_mode; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ } TT_FaceRec; @@ -1363,7 +1431,7 @@ FT_BEGIN_HEADER { FT_Memory memory; FT_UShort max_points; - FT_UShort max_contours; + FT_Short max_contours; FT_UShort n_points; /* number of points in zone */ FT_Short n_contours; /* number of contours */ @@ -1382,11 +1450,23 @@ FT_BEGIN_HEADER /* handle to execution context */ typedef struct TT_ExecContextRec_* TT_ExecContext; + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Size */ + /* */ + /* <Description> */ + /* A handle to a TrueType size object. */ + /* */ + typedef struct TT_SizeRec_* TT_Size; + + /* glyph loader structure */ typedef struct TT_LoaderRec_ { - FT_Face face; - FT_Size size; + TT_Face face; + TT_Size size; FT_GlyphSlot glyph; FT_GlyphLoader gloader; @@ -1402,7 +1482,6 @@ FT_BEGIN_HEADER FT_Int advance; FT_Int linear; FT_Bool linear_def; - FT_Bool preserve_pps; FT_Vector pp1; FT_Vector pp2; @@ -1429,12 +1508,15 @@ FT_BEGIN_HEADER FT_Byte* cursor; FT_Byte* limit; + /* since version 2.6.2 */ + FT_ListRec composites; + } TT_LoaderRec; FT_END_HEADER -#endif /* __TTTYPES_H__ */ +#endif /* TTTYPES_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/t1tables.h b/drivers/freetype/include/freetype/t1tables.h index a14255e5f5..e272324ba2 100644 --- a/drivers/freetype/include/freetype/t1tables.h +++ b/drivers/freetype/include/freetype/t1tables.h @@ -5,7 +5,7 @@ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __T1TABLES_H__ -#define __T1TABLES_H__ +#ifndef T1TABLES_H_ +#define T1TABLES_H_ #include <ft2build.h> @@ -49,6 +49,26 @@ FT_BEGIN_HEADER /* This section contains the definition of Type 1-specific tables, */ /* including structures related to other PostScript font formats. */ /* */ + /* <Order> */ + /* PS_FontInfoRec */ + /* PS_FontInfo */ + /* PS_PrivateRec */ + /* PS_Private */ + /* */ + /* CID_FaceDictRec */ + /* CID_FaceDict */ + /* CID_FaceInfoRec */ + /* CID_FaceInfo */ + /* */ + /* FT_Has_PS_Glyph_Names */ + /* FT_Get_PS_Font_Info */ + /* FT_Get_PS_Font_Private */ + /* FT_Get_PS_Font_Value */ + /* */ + /* T1_Blend_Flags */ + /* T1_EncodingType */ + /* PS_Dict_Keys */ + /* */ /*************************************************************************/ @@ -190,14 +210,30 @@ FT_BEGIN_HEADER /* given blend dictionary (font info or private). Used to support */ /* Multiple Masters fonts. */ /* */ + /* <Values> */ + /* T1_BLEND_UNDERLINE_POSITION :: */ + /* T1_BLEND_UNDERLINE_THICKNESS :: */ + /* T1_BLEND_ITALIC_ANGLE :: */ + /* T1_BLEND_BLUE_VALUES :: */ + /* T1_BLEND_OTHER_BLUES :: */ + /* T1_BLEND_STANDARD_WIDTH :: */ + /* T1_BLEND_STANDARD_HEIGHT :: */ + /* T1_BLEND_STEM_SNAP_WIDTHS :: */ + /* T1_BLEND_STEM_SNAP_HEIGHTS :: */ + /* T1_BLEND_BLUE_SCALE :: */ + /* T1_BLEND_BLUE_SHIFT :: */ + /* T1_BLEND_FAMILY_BLUES :: */ + /* T1_BLEND_FAMILY_OTHER_BLUES :: */ + /* T1_BLEND_FORCE_BOLD :: */ + /* */ typedef enum T1_Blend_Flags_ { - /*# required fields in a FontInfo blend dictionary */ + /* required fields in a FontInfo blend dictionary */ T1_BLEND_UNDERLINE_POSITION = 0, T1_BLEND_UNDERLINE_THICKNESS, T1_BLEND_ITALIC_ANGLE, - /*# required fields in a Private blend dictionary */ + /* required fields in a Private blend dictionary */ T1_BLEND_BLUE_VALUES, T1_BLEND_OTHER_BLUES, T1_BLEND_STANDARD_WIDTH, @@ -210,15 +246,13 @@ FT_BEGIN_HEADER T1_BLEND_FAMILY_OTHER_BLUES, T1_BLEND_FORCE_BOLD, - /*# never remove */ - T1_BLEND_MAX + T1_BLEND_MAX /* do not remove */ } T1_Blend_Flags; - /* */ - - /*# backwards compatible definitions */ + /* these constants are deprecated; use the corresponding */ + /* `T1_Blend_Flags' values instead */ #define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION #define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS #define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE @@ -235,6 +269,8 @@ FT_BEGIN_HEADER #define t1_blend_force_bold T1_BLEND_FORCE_BOLD #define t1_blend_max T1_BLEND_MAX + /* */ + /* maximum number of Multiple Masters designs, as defined in the spec */ #define T1_MAX_MM_DESIGNS 16 @@ -333,10 +369,17 @@ FT_BEGIN_HEADER /* */ typedef struct CID_FaceDictRec_* CID_FaceDict; - /* */ - - /* backwards-compatible definition */ + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FontDict */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceDictRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ typedef CID_FaceDictRec CID_FontDict; @@ -449,8 +492,9 @@ FT_BEGIN_HEADER * FreeType error code. 0~means success. * * @note: - * The string pointers within the font info structure are owned by - * the face and don't need to be freed by the caller. + * String pointers within the @PS_FontInfoRec structure are owned by + * the face and don't need to be freed by the caller. Missing entries + * in the font's FontInfo dictionary are represented by NULL pointers. * * If the font's format is not PostScript-based, this function will * return the `FT_Err_Invalid_Argument' error code. @@ -503,6 +547,13 @@ FT_BEGIN_HEADER /* An enumeration describing the `Encoding' entry in a Type 1 */ /* dictionary. */ /* */ + /* <Values> */ + /* T1_ENCODING_TYPE_NONE :: */ + /* T1_ENCODING_TYPE_ARRAY :: */ + /* T1_ENCODING_TYPE_STANDARD :: */ + /* T1_ENCODING_TYPE_ISOLATIN1 :: */ + /* T1_ENCODING_TYPE_EXPERT :: */ + /* */ typedef enum T1_EncodingType_ { T1_ENCODING_TYPE_NONE = 0, @@ -523,6 +574,54 @@ FT_BEGIN_HEADER /* An enumeration used in calls to @FT_Get_PS_Font_Value to identify */ /* the Type~1 dictionary entry to retrieve. */ /* */ + /* <Values> */ + /* PS_DICT_FONT_TYPE :: */ + /* PS_DICT_FONT_MATRIX :: */ + /* PS_DICT_FONT_BBOX :: */ + /* PS_DICT_PAINT_TYPE :: */ + /* PS_DICT_FONT_NAME :: */ + /* PS_DICT_UNIQUE_ID :: */ + /* PS_DICT_NUM_CHAR_STRINGS :: */ + /* PS_DICT_CHAR_STRING_KEY :: */ + /* PS_DICT_CHAR_STRING :: */ + /* PS_DICT_ENCODING_TYPE :: */ + /* PS_DICT_ENCODING_ENTRY :: */ + /* PS_DICT_NUM_SUBRS :: */ + /* PS_DICT_SUBR :: */ + /* PS_DICT_STD_HW :: */ + /* PS_DICT_STD_VW :: */ + /* PS_DICT_NUM_BLUE_VALUES :: */ + /* PS_DICT_BLUE_VALUE :: */ + /* PS_DICT_BLUE_FUZZ :: */ + /* PS_DICT_NUM_OTHER_BLUES :: */ + /* PS_DICT_OTHER_BLUE :: */ + /* PS_DICT_NUM_FAMILY_BLUES :: */ + /* PS_DICT_FAMILY_BLUE :: */ + /* PS_DICT_NUM_FAMILY_OTHER_BLUES :: */ + /* PS_DICT_FAMILY_OTHER_BLUE :: */ + /* PS_DICT_BLUE_SCALE :: */ + /* PS_DICT_BLUE_SHIFT :: */ + /* PS_DICT_NUM_STEM_SNAP_H :: */ + /* PS_DICT_STEM_SNAP_H :: */ + /* PS_DICT_NUM_STEM_SNAP_V :: */ + /* PS_DICT_STEM_SNAP_V :: */ + /* PS_DICT_FORCE_BOLD :: */ + /* PS_DICT_RND_STEM_UP :: */ + /* PS_DICT_MIN_FEATURE :: */ + /* PS_DICT_LEN_IV :: */ + /* PS_DICT_PASSWORD :: */ + /* PS_DICT_LANGUAGE_GROUP :: */ + /* PS_DICT_VERSION :: */ + /* PS_DICT_NOTICE :: */ + /* PS_DICT_FULL_NAME :: */ + /* PS_DICT_FAMILY_NAME :: */ + /* PS_DICT_WEIGHT :: */ + /* PS_DICT_IS_FIXED_PITCH :: */ + /* PS_DICT_UNDERLINE_POSITION :: */ + /* PS_DICT_UNDERLINE_THICKNESS :: */ + /* PS_DICT_FS_TYPE :: */ + /* PS_DICT_ITALIC_ANGLE :: */ + /* */ typedef enum PS_Dict_Keys_ { /* conventionally in the font dictionary */ @@ -656,7 +755,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TABLES_H__ */ +#endif /* T1TABLES_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ttnameid.h b/drivers/freetype/include/freetype/ttnameid.h index 173f88c950..ce707f1645 100644 --- a/drivers/freetype/include/freetype/ttnameid.h +++ b/drivers/freetype/include/freetype/ttnameid.h @@ -4,7 +4,7 @@ /* */ /* TrueType name ID definitions (specification only). */ /* */ -/* Copyright 1996-2004, 2006-2008, 2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTNAMEID_H__ -#define __TTNAMEID_H__ +#ifndef TTNAMEID_H_ +#define TTNAMEID_H_ #include <ft2build.h> @@ -321,7 +321,7 @@ FT_BEGIN_HEADER /* */ /* The canonical source for the Apple assigned Language ID's is at */ /* */ - /* https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html */ /* */ #define TT_MAC_LANGID_ENGLISH 0 #define TT_MAC_LANGID_FRENCH 1 @@ -470,26 +470,26 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_ARABIC_GENERAL 0x0001 #define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 #define TT_MS_LANGID_ARABIC_IRAQ 0x0801 -#define TT_MS_LANGID_ARABIC_EGYPT 0x0c01 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0C01 #define TT_MS_LANGID_ARABIC_LIBYA 0x1001 #define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 #define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 -#define TT_MS_LANGID_ARABIC_TUNISIA 0x1c01 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1C01 #define TT_MS_LANGID_ARABIC_OMAN 0x2001 #define TT_MS_LANGID_ARABIC_YEMEN 0x2401 #define TT_MS_LANGID_ARABIC_SYRIA 0x2801 -#define TT_MS_LANGID_ARABIC_JORDAN 0x2c01 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2C01 #define TT_MS_LANGID_ARABIC_LEBANON 0x3001 #define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 #define TT_MS_LANGID_ARABIC_UAE 0x3801 -#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3c01 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3C01 #define TT_MS_LANGID_ARABIC_QATAR 0x4001 #define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 #define TT_MS_LANGID_CATALAN_SPAIN 0x0403 #define TT_MS_LANGID_CHINESE_GENERAL 0x0004 #define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 #define TT_MS_LANGID_CHINESE_PRC 0x0804 -#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0c04 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0C04 #define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 #if 1 /* this looks like the correct value */ @@ -507,7 +507,7 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_DANISH_DENMARK 0x0406 #define TT_MS_LANGID_GERMAN_GERMANY 0x0407 #define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 -#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0c07 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0C07 #define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 #define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 #define TT_MS_LANGID_GREEK_GREECE 0x0408 @@ -520,69 +520,69 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 #define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 #define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 -#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0c09 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0C09 #define TT_MS_LANGID_ENGLISH_CANADA 0x1009 #define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 #define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 -#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1c09 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1C09 #define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 #define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 #define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 -#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2c09 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2C09 #define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 #define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 #define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 -#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3c09 +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3C09 #define TT_MS_LANGID_ENGLISH_INDIA 0x4009 #define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 #define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 -#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040a -#define TT_MS_LANGID_SPANISH_MEXICO 0x080a -#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0c0a -#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100a -#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140a -#define TT_MS_LANGID_SPANISH_PANAMA 0x180a -#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1c0a -#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200a -#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240a -#define TT_MS_LANGID_SPANISH_PERU 0x280a -#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2c0a -#define TT_MS_LANGID_SPANISH_ECUADOR 0x300a -#define TT_MS_LANGID_SPANISH_CHILE 0x340a -#define TT_MS_LANGID_SPANISH_URUGUAY 0x380a -#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3c0a -#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400a -#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440a -#define TT_MS_LANGID_SPANISH_HONDURAS 0x480a -#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4c0a -#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500a -#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540a +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040A +#define TT_MS_LANGID_SPANISH_MEXICO 0x080A +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0C0A +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100A +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140A +#define TT_MS_LANGID_SPANISH_PANAMA 0x180A +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1C0A +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200A +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240A +#define TT_MS_LANGID_SPANISH_PERU 0x280A +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2C0A +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300A +#define TT_MS_LANGID_SPANISH_CHILE 0x340A +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380A +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3C0A +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400A +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440A +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480A +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4C0A +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500A +#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540A /* The following ID blatantly violate MS specs by using a */ /* sublanguage > 0x1F. */ -#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40aU -#define TT_MS_LANGID_FINNISH_FINLAND 0x040b -#define TT_MS_LANGID_FRENCH_FRANCE 0x040c -#define TT_MS_LANGID_FRENCH_BELGIUM 0x080c -#define TT_MS_LANGID_FRENCH_CANADA 0x0c0c -#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100c -#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140c -#define TT_MS_LANGID_FRENCH_MONACO 0x180c -#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1c0c -#define TT_MS_LANGID_FRENCH_REUNION 0x200c -#define TT_MS_LANGID_FRENCH_CONGO 0x240c +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40AU +#define TT_MS_LANGID_FINNISH_FINLAND 0x040B +#define TT_MS_LANGID_FRENCH_FRANCE 0x040C +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080C +#define TT_MS_LANGID_FRENCH_CANADA 0x0C0C +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100C +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140C +#define TT_MS_LANGID_FRENCH_MONACO 0x180C +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1C0C +#define TT_MS_LANGID_FRENCH_REUNION 0x200C +#define TT_MS_LANGID_FRENCH_CONGO 0x240C /* which was formerly: */ #define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO -#define TT_MS_LANGID_FRENCH_SENEGAL 0x280c -#define TT_MS_LANGID_FRENCH_CAMEROON 0x2c0c -#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300c -#define TT_MS_LANGID_FRENCH_MALI 0x340c -#define TT_MS_LANGID_FRENCH_MOROCCO 0x380c -#define TT_MS_LANGID_FRENCH_HAITI 0x3c0c - /* and another violation of the spec (see 0xE40aU) */ -#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40cU -#define TT_MS_LANGID_HEBREW_ISRAEL 0x040d -#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040e -#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040f +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280C +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2C0C +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300C +#define TT_MS_LANGID_FRENCH_MALI 0x340C +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380C +#define TT_MS_LANGID_FRENCH_HAITI 0x3C0C + /* and another violation of the spec (see 0xE40AU) */ +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40CU +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040D +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040E +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040F #define TT_MS_LANGID_ITALIAN_ITALY 0x0410 #define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 #define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 @@ -600,27 +600,27 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 #define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 #define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 -#define TT_MS_LANGID_CROATIAN_CROATIA 0x041a -#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081a -#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0c1a +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041A +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081A +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0C1A #if 0 /* this used to be this value, but it looks like we were wrong */ -#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101a +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101A #else /* current sources say */ -#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101a -#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141a +#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101A +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141A /* and XPsp2 Platform SDK added (2004-07-26) */ /* Names are shortened to be significant within 40 chars. */ -#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181a -#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181a +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181A +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181A #endif -#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041b -#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041c -#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041d -#define TT_MS_LANGID_SWEDISH_FINLAND 0x081d -#define TT_MS_LANGID_THAI_THAILAND 0x041e -#define TT_MS_LANGID_TURKISH_TURKEY 0x041f +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041B +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041C +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041D +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081D +#define TT_MS_LANGID_THAI_THAILAND 0x041E +#define TT_MS_LANGID_TURKISH_TURKEY 0x041F #define TT_MS_LANGID_URDU_PAKISTAN 0x0420 #define TT_MS_LANGID_URDU_INDIA 0x0820 #define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 @@ -633,13 +633,13 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 #define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 #define TT_MS_LANGID_FARSI_IRAN 0x0429 -#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042a -#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042b -#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042c -#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082c -#define TT_MS_LANGID_BASQUE_SPAIN 0x042d -#define TT_MS_LANGID_SORBIAN_GERMANY 0x042e -#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042f +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042A +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042B +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042C +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082C +#define TT_MS_LANGID_BASQUE_SPAIN 0x042D +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042E +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042F #define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 #define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 #define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 @@ -650,32 +650,32 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 #define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 #define TT_MS_LANGID_HINDI_INDIA 0x0439 -#define TT_MS_LANGID_MALTESE_MALTA 0x043a +#define TT_MS_LANGID_MALTESE_MALTA 0x043A /* Added by XPsp2 Platform SDK (2004-07-26) */ -#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043b -#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083b -#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3b -#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103b -#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143b -#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183b -#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3b -#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203b -#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243b +#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043B +#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083B +#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3B +#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103B +#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143B +#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183B +#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3B +#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203B +#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243B /* ... and we also keep our old identifier... */ -#define TT_MS_LANGID_SAAMI_LAPONIA 0x043b +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043B #if 0 /* this seems to be a previous inversion */ -#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c -#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C #else -#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c -#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C #endif -#define TT_MS_LANGID_YIDDISH_GERMANY 0x043d -#define TT_MS_LANGID_MALAY_MALAYSIA 0x043e -#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083e -#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043f +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043D +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043E +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083E +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043F #define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 /* alias declared in Windows 2000 */ #define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ @@ -693,12 +693,12 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_GUJARATI_INDIA 0x0447 #define TT_MS_LANGID_ORIYA_INDIA 0x0448 #define TT_MS_LANGID_TAMIL_INDIA 0x0449 -#define TT_MS_LANGID_TELUGU_INDIA 0x044a -#define TT_MS_LANGID_KANNADA_INDIA 0x044b -#define TT_MS_LANGID_MALAYALAM_INDIA 0x044c -#define TT_MS_LANGID_ASSAMESE_INDIA 0x044d -#define TT_MS_LANGID_MARATHI_INDIA 0x044e -#define TT_MS_LANGID_SANSKRIT_INDIA 0x044f +#define TT_MS_LANGID_TELUGU_INDIA 0x044A +#define TT_MS_LANGID_KANNADA_INDIA 0x044B +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044C +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044D +#define TT_MS_LANGID_MARATHI_INDIA 0x044E +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044F #define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 #define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 #define TT_MS_LANGID_TIBETAN_CHINA 0x0451 @@ -732,13 +732,13 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 #define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 /* Missing a LCID for Sindhi in Devanagari script */ -#define TT_MS_LANGID_SYRIAC_SYRIA 0x045a -#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045b -#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045c -#define TT_MS_LANGID_INUKTITUT_CANADA 0x045d -#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045e -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045f -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085f +#define TT_MS_LANGID_SYRIAC_SYRIA 0x045A +#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045B +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045C +#define TT_MS_LANGID_INUKTITUT_CANADA 0x045D +#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045E +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045F +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085F /* Missing a LCID for Tifinagh script */ #define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ @@ -758,15 +758,15 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 #define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 #define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 -#define TT_MS_LANGID_YORUBA_NIGERIA 0x046a -#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046b -#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086b -#define TT_MS_LANGID_QUECHUA_PERU 0x0c6b -#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046c +#define TT_MS_LANGID_YORUBA_NIGERIA 0x046A +#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046B +#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086B +#define TT_MS_LANGID_QUECHUA_PERU 0x0C6B +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046C /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ #define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ TT_MS_LANGID_SEPEDI_SOUTH_AFRICA - /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */ + /* language codes 0x046D, 0x046E and 0x046F are (still) unknown. */ #define TT_MS_LANGID_IGBO_NIGERIA 0x0470 #define TT_MS_LANGID_KANURI_NIGERIA 0x0471 #define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 @@ -783,12 +783,12 @@ FT_BEGIN_HEADER /* studying). */ #define TT_MS_LANGID_YI_CHINA 0x0478 #define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 - /* language codes from 0x047a to 0x047f are (still) unknown. */ + /* language codes from 0x047A to 0x047F are (still) unknown. */ #define TT_MS_LANGID_UIGHUR_CHINA 0x0480 #define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 #if 0 /* not deemed useful for fonts */ -#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04ff +#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04FF #endif @@ -1208,7 +1208,7 @@ FT_BEGIN_HEADER /* */ /* Here some alias #defines in order to be clearer. */ /* */ - /* These are not always #defined to stay within the 31~character limit */ + /* These are not always #defined to stay within the 31~character limit, */ /* which some compilers have. */ /* */ /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ @@ -1231,7 +1231,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTNAMEID_H__ */ +#endif /* TTNAMEID_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/tttables.h b/drivers/freetype/include/freetype/tttables.h index fe07117b0b..1c075dcf66 100644 --- a/drivers/freetype/include/freetype/tttables.h +++ b/drivers/freetype/include/freetype/tttables.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType tables definitions and interface */ /* (specification only). */ /* */ -/* Copyright 1996-2005, 2008-2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTTABLES_H__ -#define __TTTABLES_H__ +#ifndef TTTABLES_H_ +#define TTTABLES_H_ #include <ft2build.h> @@ -48,6 +48,25 @@ FT_BEGIN_HEADER /* This section contains the definition of TrueType-specific tables */ /* as well as some routines used to access and process them. */ /* */ + /* <Order> */ + /* TT_Header */ + /* TT_HoriHeader */ + /* TT_VertHeader */ + /* TT_OS2 */ + /* TT_Postscript */ + /* TT_PCLT */ + /* TT_MaxProfile */ + /* */ + /* FT_Sfnt_Tag */ + /* FT_Get_Sfnt_Table */ + /* FT_Load_Sfnt_Table */ + /* FT_Sfnt_Table_Info */ + /* */ + /* FT_Get_CMap_Language_ID */ + /* FT_Get_CMap_Format */ + /* */ + /* FT_PARAM_TAG_UNPATENTED_HINTING */ + /* */ /*************************************************************************/ @@ -170,8 +189,8 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ + /* be identical except for the names of their fields, */ + /* which are different. */ /* */ /* This ensures that a single function in the `ttload' */ /* module is able to read both the horizontal and vertical */ @@ -296,8 +315,8 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ + /* be identical except for the names of their fields, */ + /* which are different. */ /* */ /* This ensures that a single function in the `ttload' */ /* module is able to read both the horizontal and vertical */ @@ -340,12 +359,11 @@ FT_BEGIN_HEADER /* TT_OS2 */ /* */ /* <Description> */ - /* A structure used to model a TrueType OS/2 table. This is the long */ - /* table version. All fields comply to the TrueType specification. */ + /* A structure used to model a TrueType OS/2 table. All fields */ + /* comply to the OpenType specification. */ /* */ - /* Note that we now support old Mac fonts which do not include an */ - /* OS/2 table. In this case, the `version' field is always set to */ - /* 0xFFFF. */ + /* Note that we now support old Mac fonts that do not include an OS/2 */ + /* table. In this case, the `version' field is always set to 0xFFFF. */ /* */ typedef struct TT_OS2_ { @@ -353,7 +371,7 @@ FT_BEGIN_HEADER FT_Short xAvgCharWidth; FT_UShort usWeightClass; FT_UShort usWidthClass; - FT_Short fsType; + FT_UShort fsType; FT_Short ySubscriptXSize; FT_Short ySubscriptYSize; FT_Short ySubscriptXOffset; @@ -384,12 +402,12 @@ FT_BEGIN_HEADER FT_UShort usWinAscent; FT_UShort usWinDescent; - /* only version 1 tables: */ + /* only version 1 and higher: */ FT_ULong ulCodePageRange1; /* Bits 0-31 */ FT_ULong ulCodePageRange2; /* Bits 32-63 */ - /* only version 2 tables: */ + /* only version 2 and higher: */ FT_Short sxHeight; FT_Short sCapHeight; @@ -397,6 +415,11 @@ FT_BEGIN_HEADER FT_UShort usBreakChar; FT_UShort usMaxContext; + /* only version 5 and higher: */ + + FT_UShort usLowerOpticalPointSize; /* in twips (1/20th points) */ + FT_UShort usUpperOpticalPointSize; /* in twips (1/20th points) */ + } TT_OS2; @@ -465,7 +488,7 @@ FT_BEGIN_HEADER /* TT_MaxProfile */ /* */ /* <Description> */ - /* The maximum profile is a table containing many max values which */ + /* The maximum profile is a table containing many max values, which */ /* can be used to pre-allocate arrays. This ensures that no memory */ /* allocation occurs during a glyph load. */ /* */ @@ -555,21 +578,44 @@ FT_BEGIN_HEADER /* An enumeration used to specify the index of an SFNT table. */ /* Used in the @FT_Get_Sfnt_Table API function. */ /* */ + /* <Values> */ + /* FT_SFNT_HEAD :: To access the font's @TT_Header structure. */ + /* */ + /* FT_SFNT_MAXP :: To access the font's @TT_MaxProfile structure. */ + /* */ + /* FT_SFNT_OS2 :: To access the font's @TT_OS2 structure. */ + /* */ + /* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */ + /* */ + /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure. */ + /* */ + /* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */ + /* */ + /* FT_SFNT_PCLT :: To access the font's @TT_PCLT structure. */ + /* */ typedef enum FT_Sfnt_Tag_ { - ft_sfnt_head = 0, /* TT_Header */ - ft_sfnt_maxp = 1, /* TT_MaxProfile */ - ft_sfnt_os2 = 2, /* TT_OS2 */ - ft_sfnt_hhea = 3, /* TT_HoriHeader */ - ft_sfnt_vhea = 4, /* TT_VertHeader */ - ft_sfnt_post = 5, /* TT_Postscript */ - ft_sfnt_pclt = 6, /* TT_PCLT */ + FT_SFNT_HEAD, + FT_SFNT_MAXP, + FT_SFNT_OS2, + FT_SFNT_HHEA, + FT_SFNT_VHEA, + FT_SFNT_POST, + FT_SFNT_PCLT, - sfnt_max /* internal end mark */ + FT_SFNT_MAX } FT_Sfnt_Tag; - /* */ + /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag' */ + /* values instead */ +#define ft_sfnt_head FT_SFNT_HEAD +#define ft_sfnt_maxp FT_SFNT_MAXP +#define ft_sfnt_os2 FT_SFNT_OS2 +#define ft_sfnt_hhea FT_SFNT_HHEA +#define ft_sfnt_vhea FT_SFNT_VHEA +#define ft_sfnt_post FT_SFNT_POST +#define ft_sfnt_pclt FT_SFNT_PCLT /*************************************************************************/ @@ -607,7 +653,7 @@ FT_BEGIN_HEADER /* */ /* */ /* vert_header = */ - /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, ft_sfnt_vhea ); */ + /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA ); */ /* } */ /* */ FT_EXPORT( void* ) @@ -672,6 +718,12 @@ FT_BEGIN_HEADER * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); * if ( error ) { ... could not load table ... } * } + * + * Note that structures like @TT_Header or @TT_OS2 can't be used with + * this function; they are limited to @FT_Get_Sfnt_Table. Reason is that + * those structures depend on the processor architecture, with varying + * size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian). + * */ FT_EXPORT( FT_Error ) FT_Load_Sfnt_Table( FT_Face face, @@ -730,7 +782,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Return TrueType/sfnt specific cmap language ID. Definitions of */ - /* language ID values are in `freetype/ttnameid.h'. */ + /* language ID values are in `ttnameid.h'. */ /* */ /* <Input> */ /* charmap :: */ @@ -771,7 +823,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTTABLES_H__ */ +#endif /* TTTABLES_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/tttags.h b/drivers/freetype/include/freetype/tttags.h index be8c524edb..f3c9aa5fc7 100644 --- a/drivers/freetype/include/freetype/tttags.h +++ b/drivers/freetype/include/freetype/tttags.h @@ -4,7 +4,7 @@ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ -/* Copyright 1996-2001, 2004, 2005, 2007, 2008, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTAGS_H__ -#define __TTAGS_H__ +#ifndef TTAGS_H_ +#define TTAGS_H_ #include <ft2build.h> @@ -88,6 +88,7 @@ FT_BEGIN_HEADER #define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) #define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) #define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_sbix FT_MAKE_TAG( 's', 'b', 'i', 'x' ) #define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) #define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) #define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) @@ -99,11 +100,12 @@ FT_BEGIN_HEADER #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) +#define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) FT_END_HEADER -#endif /* __TTAGS_H__ */ +#endif /* TTAGS_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ttunpat.h b/drivers/freetype/include/freetype/ttunpat.h index a0162759b7..ca4676baf8 100644 --- a/drivers/freetype/include/freetype/ttunpat.h +++ b/drivers/freetype/include/freetype/ttunpat.h @@ -2,9 +2,10 @@ /* */ /* ttunpat.h */ /* */ -/* Definitions for the unpatented TrueType hinting system */ +/* Definitions for the unpatented TrueType hinting system. */ +/* Obsolete, retained for backwards compatibility. */ /* */ -/* Copyright 2003, 2006 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Written by Graham Asher <graham.asher@btinternet.com> */ @@ -18,8 +19,8 @@ /***************************************************************************/ -#ifndef __TTUNPAT_H__ -#define __TTUNPAT_H__ +#ifndef TTUNPAT_H_ +#define TTUNPAT_H_ #include <ft2build.h> @@ -41,19 +42,22 @@ FT_BEGIN_HEADER * FT_PARAM_TAG_UNPATENTED_HINTING * * @description: - * A constant used as the tag of an @FT_Parameter structure to indicate - * that unpatented methods only should be used by the TrueType bytecode - * interpreter for a typeface opened by @FT_Open_Face. + * Deprecated. + * + * Previously: A constant used as the tag of an @FT_Parameter structure to + * indicate that unpatented methods only should be used by the TrueType + * bytecode interpreter for a typeface opened by @FT_Open_Face. * */ #define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) - /* */ + /* */ + FT_END_HEADER -#endif /* __TTUNPAT_H__ */ +#endif /* TTUNPAT_H_ */ /* END */ diff --git a/drivers/freetype/include/ft2build.h b/drivers/freetype/include/ft2build.h index cb23b8e24b..1e8a9b4994 100644 --- a/drivers/freetype/include/ft2build.h +++ b/drivers/freetype/include/ft2build.h @@ -3,9 +3,8 @@ /* ft2build.h */ /* */ /* FreeType 2 build and setup macros. */ -/* (Generic version) */ /* */ -/* Copyright 1996-2001, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,22 +18,26 @@ /*************************************************************************/ /* */ - /* This file corresponds to the default `ft2build.h' file for */ - /* FreeType 2. It uses the `freetype' include root. */ + /* This is the `entry point' for FreeType header file inclusions. It is */ + /* the only header file which should be included directly; all other */ + /* FreeType header files should be accessed with macro names (after */ + /* including `ft2build.h'). */ /* */ - /* Note that specific platforms might use a different configuration. */ - /* See builds/unix/ft2unix.h for an example. */ + /* A typical example is */ + /* */ + /* #include <ft2build.h> */ + /* #include FT_FREETYPE_H */ /* */ /*************************************************************************/ -#ifndef __FT2_BUILD_GENERIC_H__ -#define __FT2_BUILD_GENERIC_H__ +#ifndef FT2BUILD_H_ +#define FT2BUILD_H_ #define FT2_BUILD_LIBRARY #include <freetype/config/ftheader.h> -#endif /* __FT2_BUILD_GENERIC_H__ */ +#endif /* FT2BUILD_H_ */ /* END */ diff --git a/drivers/freetype/src/Jamfile b/drivers/freetype/src/Jamfile index 76ee0f46e6..ebc036983e 100644 --- a/drivers/freetype/src/Jamfile +++ b/drivers/freetype/src/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src Jamfile # -# Copyright 2001, 2002 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -11,12 +11,6 @@ SubDir FT2_TOP $(FT2_SRC_DIR) ; -# The file <freetype/internal/internal.h> is used to define macros that are -# later used in #include statements. It needs to be parsed in order to -# record these definitions. -# -HDRMACRO [ FT2_SubDir $(FT2_INCLUDE_DIR) internal internal.h ] ; - for xx in $(FT2_COMPONENTS) { SubInclude FT2_TOP $(FT2_SRC_DIR) $(xx) ; diff --git a/drivers/freetype/src/autofit/Jamfile b/drivers/freetype/src/autofit/Jamfile index 2714765b5b..638b229724 100644 --- a/drivers/freetype/src/autofit/Jamfile +++ b/drivers/freetype/src/autofit/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/autofit Jamfile # -# Copyright 2003, 2004, 2005, 2006, 2007, 2009 by +# Copyright 2003-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,11 +17,25 @@ SubDir FT2_TOP src autofit ; # define FT2_AUTOFIT2 to enable experimental latin hinter replacement if $(FT2_AUTOFIT2) { - DEFINES += FT_OPTION_AUTOFIT2 ; + CCFLAGS += FT_OPTION_AUTOFIT2 ; } if $(FT2_MULTI) { - _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp afpic ; + _sources = afangles + afblue + afcjk + afdummy + afglobal + afhints + afindic + aflatin + afloader + afmodule + afpic + afranges + afshaper + afwarp + ; if $(FT2_AUTOFIT2) { diff --git a/drivers/freetype/src/autofit/afangles.c b/drivers/freetype/src/autofit/afangles.c index b44a5ba2c6..b856e57a8b 100644 --- a/drivers/freetype/src/autofit/afangles.c +++ b/drivers/freetype/src/autofit/afangles.c @@ -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-2006, 2011-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,66 +20,6 @@ #include "aftypes.h" -#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 /* 0 */ - - /* * We are not using `af_angle_atan' anymore, but we keep the source * code below just in case... @@ -319,7 +259,7 @@ sum += table[j].org; table[j].org = 0; } - table[cur_idx].org = sum / j; + table[cur_idx].org = sum / (FT_Pos)j; if ( i < *count - 1 ) { diff --git a/drivers/freetype/src/autofit/afblue.c b/drivers/freetype/src/autofit/afblue.c new file mode 100644 index 0000000000..95786ed6f2 --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.c @@ -0,0 +1,459 @@ +/* This file has been generated by the Perl script `afblue.pl', */ +/* using data from file `afblue.dat'. */ + +/***************************************************************************/ +/* */ +/* afblue.c */ +/* */ +/* Auto-fitter data for blue strings (body). */ +/* */ +/* Copyright 2013-2016 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 "aftypes.h" + + + FT_LOCAL_ARRAY_DEF( char ) + af_blue_strings[] = + { + /* */ + '\xD8', '\xA7', ' ', '\xD8', '\xA5', ' ', '\xD9', '\x84', ' ', '\xD9', '\x83', ' ', '\xD8', '\xB7', ' ', '\xD8', '\xB8', /* ا إ ل ك ط ظ */ + '\0', + '\xD8', '\xAA', ' ', '\xD8', '\xAB', ' ', '\xD8', '\xB7', ' ', '\xD8', '\xB8', ' ', '\xD9', '\x83', /* ت ث ط ظ ك */ + '\0', + '\xD9', '\x80', /* ـ */ + '\0', + '\xD4', '\xB1', ' ', '\xD5', '\x84', ' ', '\xD5', '\x92', ' ', '\xD5', '\x93', ' ', '\xD4', '\xB2', ' ', '\xD4', '\xB3', ' ', '\xD4', '\xB4', ' ', '\xD5', '\x95', /* Ա Մ Ւ Փ Բ Գ Դ Օ */ + '\0', + '\xD5', '\x92', ' ', '\xD5', '\x88', ' ', '\xD5', '\x93', ' ', '\xD5', '\x83', ' ', '\xD5', '\x87', ' ', '\xD5', '\x8D', ' ', '\xD5', '\x8F', ' ', '\xD5', '\x95', /* Ւ Ո Փ Ճ Շ Ս Տ Օ */ + '\0', + '\xD5', '\xA5', ' ', '\xD5', '\xA7', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xB4', ' ', '\xD5', '\xBE', ' ', '\xD6', '\x83', ' ', '\xD6', '\x86', ' ', '\xD6', '\x83', /* ե է ի մ վ փ ֆ փ */ + '\0', + '\xD5', '\xA1', ' ', '\xD5', '\xB5', ' ', '\xD6', '\x82', ' ', '\xD5', '\xBD', ' ', '\xD5', '\xA3', ' ', '\xD5', '\xBB', ' ', '\xD6', '\x80', ' ', '\xD6', '\x85', /* ա յ ւ ս գ ջ ր օ */ + '\0', + '\xD5', '\xB0', ' ', '\xD5', '\xB8', ' ', '\xD5', '\xB3', ' ', '\xD5', '\xA1', ' ', '\xD5', '\xA5', ' ', '\xD5', '\xAE', ' ', '\xD5', '\xBD', ' ', '\xD6', '\x85', /* հ ո ճ ա ե ծ ս օ */ + '\0', + '\xD5', '\xA2', ' ', '\xD5', '\xA8', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xAC', ' ', '\xD5', '\xB2', ' ', '\xD5', '\xBA', ' ', '\xD6', '\x83', ' ', '\xD6', '\x81', /* բ ը ի լ ղ պ փ ց */ + '\0', + '\xE0', '\xA6', '\x85', ' ', '\xE0', '\xA6', '\xA1', ' ', '\xE0', '\xA6', '\xA4', ' ', '\xE0', '\xA6', '\xA8', ' ', '\xE0', '\xA6', '\xAC', ' ', '\xE0', '\xA6', '\xAD', ' ', '\xE0', '\xA6', '\xB2', ' ', '\xE0', '\xA6', '\x95', /* অ ড ত ন ব ভ ল ক */ + '\0', + '\xE0', '\xA6', '\x87', ' ', '\xE0', '\xA6', '\x9F', ' ', '\xE0', '\xA6', '\xA0', ' ', '\xE0', '\xA6', '\xBF', ' ', '\xE0', '\xA7', '\x80', ' ', '\xE0', '\xA7', '\x88', ' ', '\xE0', '\xA7', '\x97', /* ই ট ঠ ি ী ৈ ৗ */ + '\0', + '\xE0', '\xA6', '\x93', ' ', '\xE0', '\xA6', '\x8F', ' ', '\xE0', '\xA6', '\xA1', ' ', '\xE0', '\xA6', '\xA4', ' ', '\xE0', '\xA6', '\xA8', ' ', '\xE0', '\xA6', '\xAC', ' ', '\xE0', '\xA6', '\xB2', ' ', '\xE0', '\xA6', '\x95', /* ও এ ড ত ন ব ল ক */ + '\0', + '\xE1', '\x8F', '\x86', ' ', '\xE1', '\x8E', '\xBB', ' ', '\xE1', '\x8E', '\xAC', ' ', '\xE1', '\x8F', '\x83', ' ', '\xE1', '\x8E', '\xA4', ' ', '\xE1', '\x8F', '\xA3', ' ', '\xE1', '\x8E', '\xA6', ' ', '\xE1', '\x8F', '\x95', /* Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ */ + '\0', + '\xEA', '\xAE', '\x92', ' ', '\xEA', '\xAE', '\xA4', ' ', '\xEA', '\xAE', '\xB6', ' ', '\xEA', '\xAD', '\xB4', ' ', '\xEA', '\xAD', '\xBE', ' ', '\xEA', '\xAE', '\x97', ' ', '\xEA', '\xAE', '\x9D', ' ', '\xEA', '\xAE', '\xBF', /* ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ */ + '\0', + '\xEA', '\xAE', '\x96', ' ', '\xEA', '\xAD', '\xBC', ' ', '\xEA', '\xAE', '\x93', ' ', '\xEA', '\xAE', '\xA0', ' ', '\xEA', '\xAE', '\xB3', ' ', '\xEA', '\xAD', '\xB6', ' ', '\xEA', '\xAE', '\xA5', ' ', '\xEA', '\xAE', '\xBB', /* ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ */ + '\0', + '\xE1', '\x8F', '\xB8', ' ', '\xEA', '\xAE', '\x90', ' ', '\xEA', '\xAD', '\xB9', ' ', '\xEA', '\xAD', '\xBB', /* ᏸ ꮐ ꭹ ꭻ */ + '\0', + '\xD0', '\x91', ' ', '\xD0', '\x92', ' ', '\xD0', '\x95', ' ', '\xD0', '\x9F', ' ', '\xD0', '\x97', ' ', '\xD0', '\x9E', ' ', '\xD0', '\xA1', ' ', '\xD0', '\xAD', /* Б В Е П З О С Э */ + '\0', + '\xD0', '\x91', ' ', '\xD0', '\x92', ' ', '\xD0', '\x95', ' ', '\xD0', '\xA8', ' ', '\xD0', '\x97', ' ', '\xD0', '\x9E', ' ', '\xD0', '\xA1', ' ', '\xD0', '\xAD', /* Б В Е Ш З О С Э */ + '\0', + '\xD1', '\x85', ' ', '\xD0', '\xBF', ' ', '\xD0', '\xBD', ' ', '\xD1', '\x88', ' ', '\xD0', '\xB5', ' ', '\xD0', '\xB7', ' ', '\xD0', '\xBE', ' ', '\xD1', '\x81', /* х п н ш е з о с */ + '\0', + '\xD1', '\x80', ' ', '\xD1', '\x83', ' ', '\xD1', '\x84', /* р у ф */ + '\0', + '\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x85', ' ', '\xE0', '\xA4', '\x86', ' ', '\xE0', '\xA4', '\xA5', ' ', '\xE0', '\xA4', '\xA7', ' ', '\xE0', '\xA4', '\xAD', ' ', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\0', + '\xE0', '\xA4', '\x88', ' ', '\xE0', '\xA4', '\x90', ' ', '\xE0', '\xA4', '\x93', ' ', '\xE0', '\xA4', '\x94', ' ', '\xE0', '\xA4', '\xBF', ' ', '\xE0', '\xA5', '\x80', ' ', '\xE0', '\xA5', '\x8B', ' ', '\xE0', '\xA5', '\x8C', /* ई ऐ ओ औ ि ी ो ौ */ + '\0', + '\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x85', ' ', '\xE0', '\xA4', '\x86', ' ', '\xE0', '\xA4', '\xA5', ' ', '\xE0', '\xA4', '\xA7', ' ', '\xE0', '\xA4', '\xAD', ' ', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\0', + '\xE0', '\xA5', '\x81', ' ', '\xE0', '\xA5', '\x83', /* ु ृ */ + '\0', + '\xE1', '\x88', '\x80', ' ', '\xE1', '\x88', '\x83', ' ', '\xE1', '\x8B', '\x98', ' ', '\xE1', '\x8D', '\x90', ' ', '\xE1', '\x88', '\x9B', ' ', '\xE1', '\x89', '\xA0', ' ', '\xE1', '\x8B', '\x8B', ' ', '\xE1', '\x8B', '\x90', /* ሀ ሃ ዘ ፐ ማ በ ዋ ዐ */ + '\0', + '\xE1', '\x88', '\x88', ' ', '\xE1', '\x88', '\x90', ' ', '\xE1', '\x89', '\xA0', ' ', '\xE1', '\x8B', '\x98', ' ', '\xE1', '\x88', '\x80', ' ', '\xE1', '\x88', '\xAA', ' ', '\xE1', '\x8B', '\x90', ' ', '\xE1', '\x8C', '\xA8', /* ለ ሐ በ ዘ ሀ ሪ ዐ ጨ */ + '\0', + '\xE1', '\x83', '\x92', ' ', '\xE1', '\x83', '\x93', ' ', '\xE1', '\x83', '\x94', ' ', '\xE1', '\x83', '\x95', ' ', '\xE1', '\x83', '\x97', ' ', '\xE1', '\x83', '\x98', ' ', '\xE1', '\x83', '\x9D', ' ', '\xE1', '\x83', '\xA6', /* გ დ ე ვ თ ი ო ღ */ + '\0', + '\xE1', '\x83', '\x90', ' ', '\xE1', '\x83', '\x96', ' ', '\xE1', '\x83', '\x9B', ' ', '\xE1', '\x83', '\xA1', ' ', '\xE1', '\x83', '\xA8', ' ', '\xE1', '\x83', '\xAB', ' ', '\xE1', '\x83', '\xAE', ' ', '\xE1', '\x83', '\x9E', /* ა ზ მ ს შ ძ ხ პ */ + '\0', + '\xE1', '\x83', '\xA1', ' ', '\xE1', '\x83', '\xAE', ' ', '\xE1', '\x83', '\xA5', ' ', '\xE1', '\x83', '\x96', ' ', '\xE1', '\x83', '\x9B', ' ', '\xE1', '\x83', '\xA8', ' ', '\xE1', '\x83', '\xA9', ' ', '\xE1', '\x83', '\xAC', /* ს ხ ქ ზ მ შ ჩ წ */ + '\0', + '\xE1', '\x83', '\x94', ' ', '\xE1', '\x83', '\x95', ' ', '\xE1', '\x83', '\x9F', ' ', '\xE1', '\x83', '\xA2', ' ', '\xE1', '\x83', '\xA3', ' ', '\xE1', '\x83', '\xA4', ' ', '\xE1', '\x83', '\xA5', ' ', '\xE1', '\x83', '\xA7', /* ე ვ ჟ ტ უ ფ ქ ყ */ + '\0', + '\xE1', '\x82', '\xB1', ' ', '\xE1', '\x82', '\xA7', ' ', '\xE1', '\x82', '\xB9', ' ', '\xE1', '\x82', '\xBC', ' ', '\xE1', '\x82', '\xA4', ' ', '\xE1', '\x82', '\xA5', ' ', '\xE1', '\x82', '\xB3', ' ', '\xE1', '\x82', '\xBA', /* Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ */ + '\0', + '\xE1', '\x82', '\xA4', ' ', '\xE1', '\x82', '\xA5', ' ', '\xE1', '\x82', '\xA7', ' ', '\xE1', '\x82', '\xA8', ' ', '\xE1', '\x82', '\xA6', ' ', '\xE1', '\x82', '\xB1', ' ', '\xE1', '\x82', '\xAA', ' ', '\xE1', '\x82', '\xAB', /* Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ */ + '\0', + '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x97', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x87', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x96', /* ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ */ + '\0', + '\xE2', '\xB4', '\x88', ' ', '\xE2', '\xB4', '\x8C', ' ', '\xE2', '\xB4', '\x96', ' ', '\xE2', '\xB4', '\x8E', ' ', '\xE2', '\xB4', '\x83', ' ', '\xE2', '\xB4', '\x86', ' ', '\xE2', '\xB4', '\x8B', ' ', '\xE2', '\xB4', '\xA2', /* ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ */ + '\0', + '\xE2', '\xB4', '\x90', ' ', '\xE2', '\xB4', '\x91', ' ', '\xE2', '\xB4', '\x93', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x99', ' ', '\xE2', '\xB4', '\x9B', ' ', '\xE2', '\xB4', '\xA1', ' ', '\xE2', '\xB4', '\xA3', /* ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ */ + '\0', + '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x98', ' ', '\xE2', '\xB4', '\x9D', /* ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ */ + '\0', + '\xCE', '\x93', ' ', '\xCE', '\x92', ' ', '\xCE', '\x95', ' ', '\xCE', '\x96', ' ', '\xCE', '\x98', ' ', '\xCE', '\x9F', ' ', '\xCE', '\xA9', /* Γ Β Ε Ζ Θ Ο Ω */ + '\0', + '\xCE', '\x92', ' ', '\xCE', '\x94', ' ', '\xCE', '\x96', ' ', '\xCE', '\x9E', ' ', '\xCE', '\x98', ' ', '\xCE', '\x9F', /* Β Δ Ζ Ξ Θ Ο */ + '\0', + '\xCE', '\xB2', ' ', '\xCE', '\xB8', ' ', '\xCE', '\xB4', ' ', '\xCE', '\xB6', ' ', '\xCE', '\xBB', ' ', '\xCE', '\xBE', /* β θ δ ζ λ ξ */ + '\0', + '\xCE', '\xB1', ' ', '\xCE', '\xB5', ' ', '\xCE', '\xB9', ' ', '\xCE', '\xBF', ' ', '\xCF', '\x80', ' ', '\xCF', '\x83', ' ', '\xCF', '\x84', ' ', '\xCF', '\x89', /* α ε ι ο π σ τ ω */ + '\0', + '\xCE', '\xB2', ' ', '\xCE', '\xB3', ' ', '\xCE', '\xB7', ' ', '\xCE', '\xBC', ' ', '\xCF', '\x81', ' ', '\xCF', '\x86', ' ', '\xCF', '\x87', ' ', '\xCF', '\x88', /* β γ η μ ρ φ χ ψ */ + '\0', + '\xE0', '\xAA', '\xA4', ' ', '\xE0', '\xAA', '\xA8', ' ', '\xE0', '\xAA', '\x8B', ' ', '\xE0', '\xAA', '\x8C', ' ', '\xE0', '\xAA', '\x9B', ' ', '\xE0', '\xAA', '\x9F', ' ', '\xE0', '\xAA', '\xB0', ' ', '\xE0', '\xAB', '\xA6', /* ત ન ઋ ઌ છ ટ ર ૦ */ + '\0', + '\xE0', '\xAA', '\x96', ' ', '\xE0', '\xAA', '\x97', ' ', '\xE0', '\xAA', '\x98', ' ', '\xE0', '\xAA', '\x9E', ' ', '\xE0', '\xAA', '\x87', ' ', '\xE0', '\xAA', '\x88', ' ', '\xE0', '\xAA', '\xA0', ' ', '\xE0', '\xAA', '\x9C', /* ખ ગ ઘ ઞ ઇ ઈ ઠ જ */ + '\0', + '\xE0', '\xAA', '\x88', ' ', '\xE0', '\xAA', '\x8A', ' ', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAB', '\x80', ' ', '\xE0', '\xAA', '\xB2', '\xE0', '\xAB', '\x80', ' ', '\xE0', '\xAA', '\xB6', '\xE0', '\xAB', '\x8D', '\xE0', '\xAA', '\x9A', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAA', '\x9C', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAA', '\xB8', '\xE0', '\xAB', '\x80', /* ઈ ઊ િ ી લી શ્ચિ જિ સી */ + '\0', + '\xE0', '\xAB', '\x81', ' ', '\xE0', '\xAB', '\x83', ' ', '\xE0', '\xAB', '\x84', ' ', '\xE0', '\xAA', '\x96', '\xE0', '\xAB', '\x81', ' ', '\xE0', '\xAA', '\x9B', '\xE0', '\xAB', '\x83', ' ', '\xE0', '\xAA', '\x9B', '\xE0', '\xAB', '\x84', /* ુ ૃ ૄ ખુ છૃ છૄ */ + '\0', + '\xE0', '\xAB', '\xA6', ' ', '\xE0', '\xAB', '\xA7', ' ', '\xE0', '\xAB', '\xA8', ' ', '\xE0', '\xAB', '\xA9', ' ', '\xE0', '\xAB', '\xAD', /* ૦ ૧ ૨ ૩ ૭ */ + '\0', + '\xE0', '\xA8', '\x95', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x99', ' ', '\xE0', '\xA8', '\x9A', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA4', ' ', '\xE0', '\xA8', '\xA7', ' ', '\xE0', '\xA8', '\xB8', /* ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ */ + '\0', + '\xE0', '\xA8', '\x95', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x99', ' ', '\xE0', '\xA8', '\x9A', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA4', ' ', '\xE0', '\xA8', '\xA7', ' ', '\xE0', '\xA8', '\xB8', /* ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ */ + '\0', + '\xE0', '\xA8', '\x87', ' ', '\xE0', '\xA8', '\x88', ' ', '\xE0', '\xA8', '\x89', ' ', '\xE0', '\xA8', '\x8F', ' ', '\xE0', '\xA8', '\x93', ' ', '\xE0', '\xA9', '\xB3', ' ', '\xE0', '\xA8', '\xBF', ' ', '\xE0', '\xA9', '\x80', /* ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ */ + '\0', + '\xE0', '\xA8', '\x85', ' ', '\xE0', '\xA8', '\x8F', ' ', '\xE0', '\xA8', '\x93', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA0', ' ', '\xE0', '\xA8', '\xB0', ' ', '\xE0', '\xA8', '\xB8', /* ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ */ + '\0', + '\xE0', '\xA9', '\xA6', ' ', '\xE0', '\xA9', '\xA7', ' ', '\xE0', '\xA9', '\xA8', ' ', '\xE0', '\xA9', '\xA9', ' ', '\xE0', '\xA9', '\xAD', /* ੦ ੧ ੨ ੩ ੭ */ + '\0', + '\xD7', '\x91', ' ', '\xD7', '\x93', ' ', '\xD7', '\x94', ' ', '\xD7', '\x97', ' ', '\xD7', '\x9A', ' ', '\xD7', '\x9B', ' ', '\xD7', '\x9D', ' ', '\xD7', '\xA1', /* ב ד ה ח ך כ ם ס */ + '\0', + '\xD7', '\x91', ' ', '\xD7', '\x98', ' ', '\xD7', '\x9B', ' ', '\xD7', '\x9D', ' ', '\xD7', '\xA1', ' ', '\xD7', '\xA6', /* ב ט כ ם ס צ */ + '\0', + '\xD7', '\xA7', ' ', '\xD7', '\x9A', ' ', '\xD7', '\x9F', ' ', '\xD7', '\xA3', ' ', '\xD7', '\xA5', /* ק ך ן ף ץ */ + '\0', + '\xE0', '\xB2', '\x87', ' ', '\xE0', '\xB2', '\x8A', ' ', '\xE0', '\xB2', '\x90', ' ', '\xE0', '\xB2', '\xA3', ' ', '\xE0', '\xB2', '\xB8', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xA8', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xA6', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xB0', '\xE0', '\xB2', '\xBE', /* ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ */ + '\0', + '\xE0', '\xB2', '\x85', ' ', '\xE0', '\xB2', '\x89', ' ', '\xE0', '\xB2', '\x8E', ' ', '\xE0', '\xB2', '\xB2', ' ', '\xE0', '\xB3', '\xA6', ' ', '\xE0', '\xB3', '\xA8', ' ', '\xE0', '\xB3', '\xAC', ' ', '\xE0', '\xB3', '\xAD', /* ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭ */ + '\0', + '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x91', ' ', '\xE1', '\x9E', '\x93', ' ', '\xE1', '\x9E', '\xA7', ' ', '\xE1', '\x9E', '\xA9', ' ', '\xE1', '\x9E', '\xB6', /* ខ ទ ន ឧ ឩ ា */ + '\0', + '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x80', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x82', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x90', /* ក្ក ក្ខ ក្គ ក្ថ */ + '\0', + '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x83', ' ', '\xE1', '\x9E', '\x85', ' ', '\xE1', '\x9E', '\x8B', ' ', '\xE1', '\x9E', '\x94', ' ', '\xE1', '\x9E', '\x98', ' ', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\xB2', /* ខ ឃ ច ឋ ប ម យ ឲ */ + '\0', + '\xE1', '\x9E', '\x8F', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', ' ', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\xB2', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\xA2', '\xE1', '\x9E', '\xBF', /* ត្រ រៀ ឲ្យ អឿ */ + '\0', + '\xE1', '\x9E', '\x93', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x8F', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x83', ' ', '\xE1', '\x9E', '\x84', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x81', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x94', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\x85', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\x93', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x8F', '\xE1', '\x9E', '\xBF', ' ', '\xE1', '\x9E', '\x9B', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x94', '\xE1', '\x9E', '\xBF', /* ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ */ + '\0', + '\xE1', '\xA7', '\xA0', ' ', '\xE1', '\xA7', '\xA1', /* ᧠ ᧡ */ + '\0', + '\xE1', '\xA7', '\xB6', ' ', '\xE1', '\xA7', '\xB9', /* ᧶ ᧹ */ + '\0', + '\xE0', '\xBA', '\xB2', ' ', '\xE0', '\xBA', '\x94', ' ', '\xE0', '\xBA', '\xAD', ' ', '\xE0', '\xBA', '\xA1', ' ', '\xE0', '\xBA', '\xA5', ' ', '\xE0', '\xBA', '\xA7', ' ', '\xE0', '\xBA', '\xA3', ' ', '\xE0', '\xBA', '\x87', /* າ ດ ອ ມ ລ ວ ຣ ງ */ + '\0', + '\xE0', '\xBA', '\xB2', ' ', '\xE0', '\xBA', '\xAD', ' ', '\xE0', '\xBA', '\x9A', ' ', '\xE0', '\xBA', '\x8D', ' ', '\xE0', '\xBA', '\xA3', ' ', '\xE0', '\xBA', '\xAE', ' ', '\xE0', '\xBA', '\xA7', ' ', '\xE0', '\xBA', '\xA2', /* າ ອ ບ ຍ ຣ ຮ ວ ຢ */ + '\0', + '\xE0', '\xBA', '\x9B', ' ', '\xE0', '\xBA', '\xA2', ' ', '\xE0', '\xBA', '\x9F', ' ', '\xE0', '\xBA', '\x9D', /* ປ ຢ ຟ ຝ */ + '\0', + '\xE0', '\xBB', '\x82', ' ', '\xE0', '\xBB', '\x84', ' ', '\xE0', '\xBB', '\x83', /* ໂ ໄ ໃ */ + '\0', + '\xE0', '\xBA', '\x87', ' ', '\xE0', '\xBA', '\x8A', ' ', '\xE0', '\xBA', '\x96', ' ', '\xE0', '\xBA', '\xBD', ' ', '\xE0', '\xBB', '\x86', ' ', '\xE0', '\xBA', '\xAF', /* ງ ຊ ຖ ຽ ໆ ຯ */ + '\0', + 'T', ' ', 'H', ' ', 'E', ' ', 'Z', ' ', 'O', ' ', 'C', ' ', 'Q', ' ', 'S', /* T H E Z O C Q S */ + '\0', + 'H', ' ', 'E', ' ', 'Z', ' ', 'L', ' ', 'O', ' ', 'C', ' ', 'U', ' ', 'S', /* H E Z L O C U S */ + '\0', + 'f', ' ', 'i', ' ', 'j', ' ', 'k', ' ', 'd', ' ', 'b', ' ', 'h', /* f i j k d b h */ + '\0', + 'x', ' ', 'z', ' ', 'r', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c', /* x z r o e s c */ + '\0', + 'p', ' ', 'q', ' ', 'g', ' ', 'j', ' ', 'y', /* p q g j y */ + '\0', + '\xE2', '\x82', '\x80', ' ', '\xE2', '\x82', '\x83', ' ', '\xE2', '\x82', '\x85', ' ', '\xE2', '\x82', '\x87', ' ', '\xE2', '\x82', '\x88', /* ₀ ₃ ₅ ₇ ₈ */ + '\0', + '\xE2', '\x82', '\x80', ' ', '\xE2', '\x82', '\x81', ' ', '\xE2', '\x82', '\x82', ' ', '\xE2', '\x82', '\x83', ' ', '\xE2', '\x82', '\x88', /* ₀ ₁ ₂ ₃ ₈ */ + '\0', + '\xE1', '\xB5', '\xA2', ' ', '\xE2', '\xB1', '\xBC', ' ', '\xE2', '\x82', '\x95', ' ', '\xE2', '\x82', '\x96', ' ', '\xE2', '\x82', '\x97', /* ᵢ ⱼ ₕ ₖ ₗ */ + '\0', + '\xE2', '\x82', '\x90', ' ', '\xE2', '\x82', '\x91', ' ', '\xE2', '\x82', '\x92', ' ', '\xE2', '\x82', '\x93', ' ', '\xE2', '\x82', '\x99', ' ', '\xE2', '\x82', '\x9B', ' ', '\xE1', '\xB5', '\xA5', ' ', '\xE1', '\xB5', '\xA4', ' ', '\xE1', '\xB5', '\xA3', /* ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ */ + '\0', + '\xE1', '\xB5', '\xA6', ' ', '\xE1', '\xB5', '\xA7', ' ', '\xE1', '\xB5', '\xA8', ' ', '\xE1', '\xB5', '\xA9', ' ', '\xE2', '\x82', '\x9A', /* ᵦ ᵧ ᵨ ᵩ ₚ */ + '\0', + '\xE2', '\x81', '\xB0', ' ', '\xC2', '\xB3', ' ', '\xE2', '\x81', '\xB5', ' ', '\xE2', '\x81', '\xB7', ' ', '\xE1', '\xB5', '\x80', ' ', '\xE1', '\xB4', '\xB4', ' ', '\xE1', '\xB4', '\xB1', ' ', '\xE1', '\xB4', '\xBC', /* ⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ */ + '\0', + '\xE2', '\x81', '\xB0', ' ', '\xC2', '\xB9', ' ', '\xC2', '\xB2', ' ', '\xC2', '\xB3', ' ', '\xE1', '\xB4', '\xB1', ' ', '\xE1', '\xB4', '\xB8', ' ', '\xE1', '\xB4', '\xBC', ' ', '\xE1', '\xB5', '\x81', /* ⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ */ + '\0', + '\xE1', '\xB5', '\x87', ' ', '\xE1', '\xB5', '\x88', ' ', '\xE1', '\xB5', '\x8F', ' ', '\xCA', '\xB0', ' ', '\xCA', '\xB2', ' ', '\xE1', '\xB6', '\xA0', ' ', '\xE2', '\x81', '\xB1', /* ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ */ + '\0', + '\xE1', '\xB5', '\x89', ' ', '\xE1', '\xB5', '\x92', ' ', '\xCA', '\xB3', ' ', '\xCB', '\xA2', ' ', '\xCB', '\xA3', ' ', '\xE1', '\xB6', '\x9C', ' ', '\xE1', '\xB6', '\xBB', /* ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ */ + '\0', + '\xE1', '\xB5', '\x96', ' ', '\xCA', '\xB8', ' ', '\xE1', '\xB5', '\x8D', /* ᵖ ʸ ᵍ */ + '\0', + '\xE0', '\xB4', '\x92', ' ', '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xB1', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xAA', ' ', '\xE0', '\xB4', '\x9A', '\xE0', '\xB5', '\x8D', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xAA', '\xE0', '\xB5', '\x8D', '\xE0', '\xB4', '\xAA', /* ഒ ട ഠ റ ച പ ച്ച പ്പ */ + '\0', + '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xA7', ' ', '\xE0', '\xB4', '\xB6', ' ', '\xE0', '\xB4', '\x98', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xA5', ' ', '\xE0', '\xB4', '\xB2', /* ട ഠ ധ ശ ഘ ച ഥ ല */ + '\0', + '\xE1', '\x80', '\x81', ' ', '\xE1', '\x80', '\x82', ' ', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\xA5', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* ခ ဂ င ဒ ဝ ၥ ၊ ။ */ + '\0', + '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x8E', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x95', ' ', '\xE1', '\x80', '\x97', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* င ဎ ဒ ပ ဗ ဝ ၊ ။ */ + '\0', + '\xE1', '\x80', '\xA9', ' ', '\xE1', '\x80', '\xBC', ' ', '\xE1', '\x81', '\x8D', ' ', '\xE1', '\x81', '\x8F', ' ', '\xE1', '\x81', '\x86', ' ', '\xE1', '\x80', '\xAB', ' ', '\xE1', '\x80', '\xAD', /* ဩ ြ ၍ ၏ ၆ ါ ိ */ + '\0', + '\xE1', '\x80', '\x89', ' ', '\xE1', '\x80', '\x8A', ' ', '\xE1', '\x80', '\xA5', ' ', '\xE1', '\x80', '\xA9', ' ', '\xE1', '\x80', '\xA8', ' ', '\xE1', '\x81', '\x82', ' ', '\xE1', '\x81', '\x85', ' ', '\xE1', '\x81', '\x89', /* ဉ ည ဥ ဩ ဨ ၂ ၅ ၉ */ + '\0', + '\xE0', '\xB6', '\x89', ' ', '\xE0', '\xB6', '\x9A', ' ', '\xE0', '\xB6', '\x9D', ' ', '\xE0', '\xB6', '\xB3', ' ', '\xE0', '\xB6', '\xB4', ' ', '\xE0', '\xB6', '\xBA', ' ', '\xE0', '\xB6', '\xBD', ' ', '\xE0', '\xB7', '\x86', /* ඉ ක ඝ ඳ ප ය ල ෆ */ + '\0', + '\xE0', '\xB6', '\x91', ' ', '\xE0', '\xB6', '\x94', ' ', '\xE0', '\xB6', '\x9D', ' ', '\xE0', '\xB6', '\xA2', ' ', '\xE0', '\xB6', '\xA7', ' ', '\xE0', '\xB6', '\xAE', ' ', '\xE0', '\xB6', '\xB0', ' ', '\xE0', '\xB6', '\xBB', /* එ ඔ ඝ ජ ට ථ ධ ර */ + '\0', + '\xE0', '\xB6', '\xAF', ' ', '\xE0', '\xB6', '\xB3', ' ', '\xE0', '\xB6', '\x8B', ' ', '\xE0', '\xB6', '\xBD', ' ', '\xE0', '\xB6', '\xAD', '\xE0', '\xB7', '\x96', ' ', '\xE0', '\xB6', '\xAD', '\xE0', '\xB7', '\x94', ' ', '\xE0', '\xB6', '\xB6', '\xE0', '\xB7', '\x94', ' ', '\xE0', '\xB6', '\xAF', '\xE0', '\xB7', '\x94', /* ද ඳ උ ල තූ තු බු දු */ + '\0', + '\xE0', '\xAE', '\x89', ' ', '\xE0', '\xAE', '\x92', ' ', '\xE0', '\xAE', '\x93', ' ', '\xE0', '\xAE', '\xB1', ' ', '\xE0', '\xAE', '\x88', ' ', '\xE0', '\xAE', '\x95', ' ', '\xE0', '\xAE', '\x99', ' ', '\xE0', '\xAE', '\x9A', /* உ ஒ ஓ ற ஈ க ங ச */ + '\0', + '\xE0', '\xAE', '\x95', ' ', '\xE0', '\xAE', '\x9A', ' ', '\xE0', '\xAE', '\xB2', ' ', '\xE0', '\xAE', '\xB6', ' ', '\xE0', '\xAE', '\x89', ' ', '\xE0', '\xAE', '\x99', ' ', '\xE0', '\xAE', '\x9F', ' ', '\xE0', '\xAE', '\xAA', /* க ச ல ஶ உ ங ட ப */ + '\0', + '\xE0', '\xB0', '\x87', ' ', '\xE0', '\xB0', '\x8C', ' ', '\xE0', '\xB0', '\x99', ' ', '\xE0', '\xB0', '\x9E', ' ', '\xE0', '\xB0', '\xA3', ' ', '\xE0', '\xB0', '\xB1', ' ', '\xE0', '\xB1', '\xAF', /* ఇ ఌ ఙ ఞ ణ ఱ ౯ */ + '\0', + '\xE0', '\xB0', '\x85', ' ', '\xE0', '\xB0', '\x95', ' ', '\xE0', '\xB0', '\x9A', ' ', '\xE0', '\xB0', '\xB0', ' ', '\xE0', '\xB0', '\xBD', ' ', '\xE0', '\xB1', '\xA8', ' ', '\xE0', '\xB1', '\xAC', /* అ క చ ర ఽ ౨ ౬ */ + '\0', + '\xE0', '\xB8', '\x9A', ' ', '\xE0', '\xB9', '\x80', ' ', '\xE0', '\xB9', '\x81', ' ', '\xE0', '\xB8', '\xAD', ' ', '\xE0', '\xB8', '\x81', ' ', '\xE0', '\xB8', '\xB2', /* บ เ แ อ ก า */ + '\0', + '\xE0', '\xB8', '\x9A', ' ', '\xE0', '\xB8', '\x9B', ' ', '\xE0', '\xB8', '\xA9', ' ', '\xE0', '\xB8', '\xAF', ' ', '\xE0', '\xB8', '\xAD', ' ', '\xE0', '\xB8', '\xA2', ' ', '\xE0', '\xB8', '\xAE', /* บ ป ษ ฯ อ ย ฮ */ + '\0', + '\xE0', '\xB8', '\x9B', ' ', '\xE0', '\xB8', '\x9D', ' ', '\xE0', '\xB8', '\x9F', /* ป ฝ ฟ */ + '\0', + '\xE0', '\xB9', '\x82', ' ', '\xE0', '\xB9', '\x83', ' ', '\xE0', '\xB9', '\x84', /* โ ใ ไ */ + '\0', + '\xE0', '\xB8', '\x8E', ' ', '\xE0', '\xB8', '\x8F', ' ', '\xE0', '\xB8', '\xA4', ' ', '\xE0', '\xB8', '\xA6', /* ฎ ฏ ฤ ฦ */ + '\0', + '\xE0', '\xB8', '\x8D', ' ', '\xE0', '\xB8', '\x90', /* ญ ฐ */ + '\0', + '\xE0', '\xB9', '\x90', ' ', '\xE0', '\xB9', '\x91', ' ', '\xE0', '\xB9', '\x93', /* ๐ ๑ ๓ */ +#ifdef AF_CONFIG_OPTION_CJK + '\0', + '\xE4', '\xBB', '\x96', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\x9C', '\xB0', /* 他 们 你 來 們 到 和 地 */ + ' ', '\xE5', '\xAF', '\xB9', ' ', '\xE5', '\xB0', '\x8D', ' ', '\xE5', '\xB0', '\xB1', ' ', '\xE5', '\xB8', '\xAD', ' ', '\xE6', '\x88', '\x91', ' ', '\xE6', '\x97', '\xB6', ' ', '\xE6', '\x99', '\x82', ' ', '\xE6', '\x9C', '\x83', /* 对 對 就 席 我 时 時 會 */ + ' ', '\xE6', '\x9D', '\xA5', ' ', '\xE7', '\x82', '\xBA', ' ', '\xE8', '\x83', '\xBD', ' ', '\xE8', '\x88', '\xB0', ' ', '\xE8', '\xAA', '\xAA', ' ', '\xE8', '\xAF', '\xB4', ' ', '\xE8', '\xBF', '\x99', ' ', '\xE9', '\x80', '\x99', /* 来 為 能 舰 說 说 这 這 */ + ' ', '\xE9', '\xBD', '\x8A', ' ', '|', /* 齊 | */ + ' ', '\xE5', '\x86', '\x9B', ' ', '\xE5', '\x90', '\x8C', ' ', '\xE5', '\xB7', '\xB2', ' ', '\xE6', '\x84', '\xBF', ' ', '\xE6', '\x97', '\xA2', ' ', '\xE6', '\x98', '\x9F', ' ', '\xE6', '\x98', '\xAF', ' ', '\xE6', '\x99', '\xAF', /* 军 同 已 愿 既 星 是 景 */ + ' ', '\xE6', '\xB0', '\x91', ' ', '\xE7', '\x85', '\xA7', ' ', '\xE7', '\x8E', '\xB0', ' ', '\xE7', '\x8F', '\xBE', ' ', '\xE7', '\x90', '\x86', ' ', '\xE7', '\x94', '\xA8', ' ', '\xE7', '\xBD', '\xAE', ' ', '\xE8', '\xA6', '\x81', /* 民 照 现 現 理 用 置 要 */ + ' ', '\xE8', '\xBB', '\x8D', ' ', '\xE9', '\x82', '\xA3', ' ', '\xE9', '\x85', '\x8D', ' ', '\xE9', '\x87', '\x8C', ' ', '\xE9', '\x96', '\x8B', ' ', '\xE9', '\x9B', '\xB7', ' ', '\xE9', '\x9C', '\xB2', ' ', '\xE9', '\x9D', '\xA2', /* 軍 那 配 里 開 雷 露 面 */ + ' ', '\xE9', '\xA1', '\xBE', /* 顾 */ + '\0', + '\xE4', '\xB8', '\xAA', ' ', '\xE4', '\xB8', '\xBA', ' ', '\xE4', '\xBA', '\xBA', ' ', '\xE4', '\xBB', '\x96', ' ', '\xE4', '\xBB', '\xA5', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', /* 个 为 人 他 以 们 你 來 */ + ' ', '\xE5', '\x80', '\x8B', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\xA4', '\xA7', ' ', '\xE5', '\xAF', '\xB9', ' ', '\xE5', '\xB0', '\x8D', ' ', '\xE5', '\xB0', '\xB1', /* 個 們 到 和 大 对 對 就 */ + ' ', '\xE6', '\x88', '\x91', ' ', '\xE6', '\x97', '\xB6', ' ', '\xE6', '\x99', '\x82', ' ', '\xE6', '\x9C', '\x89', ' ', '\xE6', '\x9D', '\xA5', ' ', '\xE7', '\x82', '\xBA', ' ', '\xE8', '\xA6', '\x81', ' ', '\xE8', '\xAA', '\xAA', /* 我 时 時 有 来 為 要 說 */ + ' ', '\xE8', '\xAF', '\xB4', ' ', '|', /* 说 | */ + ' ', '\xE4', '\xB8', '\xBB', ' ', '\xE4', '\xBA', '\x9B', ' ', '\xE5', '\x9B', '\xA0', ' ', '\xE5', '\xAE', '\x83', ' ', '\xE6', '\x83', '\xB3', ' ', '\xE6', '\x84', '\x8F', ' ', '\xE7', '\x90', '\x86', ' ', '\xE7', '\x94', '\x9F', /* 主 些 因 它 想 意 理 生 */ + ' ', '\xE7', '\x95', '\xB6', ' ', '\xE7', '\x9C', '\x8B', ' ', '\xE7', '\x9D', '\x80', ' ', '\xE7', '\xBD', '\xAE', ' ', '\xE8', '\x80', '\x85', ' ', '\xE8', '\x87', '\xAA', ' ', '\xE8', '\x91', '\x97', ' ', '\xE8', '\xA3', '\xA1', /* 當 看 着 置 者 自 著 裡 */ + ' ', '\xE8', '\xBF', '\x87', ' ', '\xE8', '\xBF', '\x98', ' ', '\xE8', '\xBF', '\x9B', ' ', '\xE9', '\x80', '\xB2', ' ', '\xE9', '\x81', '\x8E', ' ', '\xE9', '\x81', '\x93', ' ', '\xE9', '\x82', '\x84', ' ', '\xE9', '\x87', '\x8C', /* 过 还 进 進 過 道 還 里 */ + ' ', '\xE9', '\x9D', '\xA2', /* 面 */ +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + '\0', + ' ', '\xE4', '\xBA', '\x9B', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\x9C', '\xB0', /* 些 们 你 來 們 到 和 地 */ + ' ', '\xE5', '\xA5', '\xB9', ' ', '\xE5', '\xB0', '\x86', ' ', '\xE5', '\xB0', '\x87', ' ', '\xE5', '\xB0', '\xB1', ' ', '\xE5', '\xB9', '\xB4', ' ', '\xE5', '\xBE', '\x97', ' ', '\xE6', '\x83', '\x85', ' ', '\xE6', '\x9C', '\x80', /* 她 将 將 就 年 得 情 最 */ + ' ', '\xE6', '\xA0', '\xB7', ' ', '\xE6', '\xA8', '\xA3', ' ', '\xE7', '\x90', '\x86', ' ', '\xE8', '\x83', '\xBD', ' ', '\xE8', '\xAA', '\xAA', ' ', '\xE8', '\xAF', '\xB4', ' ', '\xE8', '\xBF', '\x99', ' ', '\xE9', '\x80', '\x99', /* 样 樣 理 能 說 说 这 這 */ + ' ', '\xE9', '\x80', '\x9A', ' ', '|', /* 通 | */ + ' ', '\xE5', '\x8D', '\xB3', ' ', '\xE5', '\x90', '\x97', ' ', '\xE5', '\x90', '\xA7', ' ', '\xE5', '\x90', '\xAC', ' ', '\xE5', '\x91', '\xA2', ' ', '\xE5', '\x93', '\x81', ' ', '\xE5', '\x93', '\x8D', ' ', '\xE5', '\x97', '\x8E', /* 即 吗 吧 听 呢 品 响 嗎 */ + ' ', '\xE5', '\xB8', '\x88', ' ', '\xE5', '\xB8', '\xAB', ' ', '\xE6', '\x94', '\xB6', ' ', '\xE6', '\x96', '\xAD', ' ', '\xE6', '\x96', '\xB7', ' ', '\xE6', '\x98', '\x8E', ' ', '\xE7', '\x9C', '\xBC', ' ', '\xE9', '\x96', '\x93', /* 师 師 收 断 斷 明 眼 間 */ + ' ', '\xE9', '\x97', '\xB4', ' ', '\xE9', '\x99', '\x85', ' ', '\xE9', '\x99', '\x88', ' ', '\xE9', '\x99', '\x90', ' ', '\xE9', '\x99', '\xA4', ' ', '\xE9', '\x99', '\xB3', ' ', '\xE9', '\x9A', '\x8F', ' ', '\xE9', '\x9A', '\x9B', /* 间 际 陈 限 除 陳 随 際 */ + ' ', '\xE9', '\x9A', '\xA8', /* 隨 */ + '\0', + '\xE4', '\xBA', '\x8B', ' ', '\xE5', '\x89', '\x8D', ' ', '\xE5', '\xAD', '\xB8', ' ', '\xE5', '\xB0', '\x86', ' ', '\xE5', '\xB0', '\x87', ' ', '\xE6', '\x83', '\x85', ' ', '\xE6', '\x83', '\xB3', ' ', '\xE6', '\x88', '\x96', /* 事 前 學 将 將 情 想 或 */ + ' ', '\xE6', '\x94', '\xBF', ' ', '\xE6', '\x96', '\xAF', ' ', '\xE6', '\x96', '\xB0', ' ', '\xE6', '\xA0', '\xB7', ' ', '\xE6', '\xA8', '\xA3', ' ', '\xE6', '\xB0', '\x91', ' ', '\xE6', '\xB2', '\x92', ' ', '\xE6', '\xB2', '\xA1', /* 政 斯 新 样 樣 民 沒 没 */ + ' ', '\xE7', '\x84', '\xB6', ' ', '\xE7', '\x89', '\xB9', ' ', '\xE7', '\x8E', '\xB0', ' ', '\xE7', '\x8F', '\xBE', ' ', '\xE7', '\x90', '\x83', ' ', '\xE7', '\xAC', '\xAC', ' ', '\xE7', '\xB6', '\x93', ' ', '\xE8', '\xB0', '\x81', /* 然 特 现 現 球 第 經 谁 */ + ' ', '\xE8', '\xB5', '\xB7', ' ', '|', /* 起 | */ + ' ', '\xE4', '\xBE', '\x8B', ' ', '\xE5', '\x88', '\xA5', ' ', '\xE5', '\x88', '\xAB', ' ', '\xE5', '\x88', '\xB6', ' ', '\xE5', '\x8A', '\xA8', ' ', '\xE5', '\x8B', '\x95', ' ', '\xE5', '\x90', '\x97', ' ', '\xE5', '\x97', '\x8E', /* 例 別 别 制 动 動 吗 嗎 */ + ' ', '\xE5', '\xA2', '\x9E', ' ', '\xE6', '\x8C', '\x87', ' ', '\xE6', '\x98', '\x8E', ' ', '\xE6', '\x9C', '\x9D', ' ', '\xE6', '\x9C', '\x9F', ' ', '\xE6', '\x9E', '\x84', ' ', '\xE7', '\x89', '\xA9', ' ', '\xE7', '\xA1', '\xAE', /* 增 指 明 朝 期 构 物 确 */ + ' ', '\xE7', '\xA7', '\x8D', ' ', '\xE8', '\xAA', '\xBF', ' ', '\xE8', '\xB0', '\x83', ' ', '\xE8', '\xB2', '\xBB', ' ', '\xE8', '\xB4', '\xB9', ' ', '\xE9', '\x82', '\xA3', ' ', '\xE9', '\x83', '\xBD', ' ', '\xE9', '\x96', '\x93', /* 种 調 调 費 费 那 都 間 */ + ' ', '\xE9', '\x97', '\xB4', /* 间 */ +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ +#endif /* AF_CONFIG_OPTION_CJK */ + '\0', + + }; + + + /* stringsets are specific to styles */ + FT_LOCAL_ARRAY_DEF( AF_Blue_StringRec ) + af_blue_stringsets[] = + { + /* */ + { AF_BLUE_STRING_ARABIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ARABIC_BOTTOM, 0 }, + { AF_BLUE_STRING_ARABIC_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ARMENIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_BENGALI_BASE, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CHEROKEE_CAPITAL, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CHEROKEE_CAPITAL, 0 }, + { AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CHEROKEE_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_CHEROKEE_SMALL, 0 }, + { AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_CYRILLIC_SMALL, 0 }, + { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_DEVANAGARI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_DEVANAGARI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_DEVANAGARI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_DEVANAGARI_BASE, 0 }, + { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_ETHIOPIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_GREEK_SMALL_BETA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GREEK_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GREEK_SMALL, 0 }, + { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GUJARATI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GUJARATI_BOTTOM, 0 }, + { AF_BLUE_STRING_GUJARATI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GUJARATI_DESCENDER, 0 }, + { AF_BLUE_STRING_GUJARATI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GURMUKHI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GURMUKHI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GURMUKHI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GURMUKHI_BOTTOM, 0 }, + { AF_BLUE_STRING_GURMUKHI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_LONG }, + { AF_BLUE_STRING_HEBREW_BOTTOM, 0 }, + { AF_BLUE_STRING_HEBREW_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_KANNADA_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP }, + { AF_BLUE_STRING_KHMER_BOTTOM, 0 }, + { AF_BLUE_STRING_KHMER_DESCENDER, 0 }, + { AF_BLUE_STRING_KHMER_LARGE_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LAO_BOTTOM, 0 }, + { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LAO_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LATIN_SMALL, 0 }, + { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SUBS_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LATIN_SUBS_SMALL, 0 }, + { AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SUPS_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LATIN_SUPS_SMALL, 0 }, + { AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_MYANMAR_BOTTOM, 0 }, + { AF_BLUE_STRING_MYANMAR_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MYANMAR_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_SINHALA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_SINHALA_BOTTOM, 0 }, + { AF_BLUE_STRING_SINHALA_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_TAMIL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_TAMIL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_TELUGU_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_THAI_BOTTOM, 0 }, + { AF_BLUE_STRING_THAI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_THAI_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_THAI_DESCENDER, 0 }, + { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 }, + { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 }, + { AF_BLUE_STRING_MAX, 0 }, +#ifdef AF_CONFIG_OPTION_CJK + { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP }, + { AF_BLUE_STRING_CJK_BOTTOM, 0 }, +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + { AF_BLUE_STRING_CJK_LEFT, AF_BLUE_PROPERTY_CJK_HORIZ }, + { AF_BLUE_STRING_CJK_RIGHT, AF_BLUE_PROPERTY_CJK_HORIZ | + AF_BLUE_PROPERTY_CJK_RIGHT }, +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + { AF_BLUE_STRING_MAX, 0 }, +#endif /* AF_CONFIG_OPTION_CJK */ + + }; + + +/* END */ diff --git a/drivers/freetype/src/autofit/afblue.cin b/drivers/freetype/src/autofit/afblue.cin new file mode 100644 index 0000000000..0c3cae818f --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.cin @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* afblue.c */ +/* */ +/* Auto-fitter data for blue strings (body). */ +/* */ +/* Copyright 2013-2016 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 "aftypes.h" + + + FT_LOCAL_ARRAY_DEF( char ) + af_blue_strings[] = + { + /* */ +@AF_BLUE_STRINGS_ARRAY@ + }; + + + /* stringsets are specific to styles */ + FT_LOCAL_ARRAY_DEF( AF_Blue_StringRec ) + af_blue_stringsets[] = + { + /* */ +@AF_BLUE_STRINGSETS_ARRAY@ + }; + + +/* END */ diff --git a/drivers/freetype/src/autofit/afblue.dat b/drivers/freetype/src/autofit/afblue.dat new file mode 100644 index 0000000000..0734ec71f0 --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.dat @@ -0,0 +1,718 @@ +// afblue.dat +// +// Auto-fitter data for blue strings. +// +// Copyright 2013-2016 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. + + +// This file contains data specific to blue zones. It gets processed by +// a script to simulate `jagged arrays', with enumeration values holding +// offsets into the arrays. +// +// The format of the file is rather simple: A section starts with three +// labels separated by whitespace and followed by a colon (everything in a +// single line); the first label gives the name of the enumeration template, +// the second the name of the array template, and the third the name of the +// `maximum' template. The script then fills the corresponding templates +// (indicated by `@' characters around the name). +// +// A section contains one or more data records. Each data record consists +// of two or more lines. The first line holds the enumeration name, and the +// remaining lines the corresponding array data. +// +// There are two possible representations for array data. +// +// - A string of characters or character clusters (for example, representing +// Aksharas, Devanagari syllables) in UTF-8 encoding enclosed in double +// quotes, using C syntax, where the elements are separated by spaces. +// There can be only one string per line, thus the starting and ending +// double quote must be the first and last character in the line, +// respectively, ignoring whitespace before and after the string. If +// there are multiple strings (in multiple lines), they are concatenated +// to a single string. In the output, a string gets represented as a +// series of singles bytes, followed by a zero byte. The enumeration +// values simply hold byte offsets to the start of the corresponding +// strings. +// +// For strings, the `maximum' template holds the maximum number of +// non-space characters in all strings. +// +// - Data blocks enclosed in balanced braces, which get copied verbatim and +// which can span multiple lines. The opening brace of a block must be +// the first character of a line (ignoring whitespace), and the closing +// brace the last (ignoring whitespace also). The script appends a comma +// character after each block and counts the number of blocks to set the +// enumeration values. +// +// For data blocks, the `maximum' template holds the maximum number of +// array elements. +// +// A section can contain either strings only or data blocks only. +// +// A comment line starts with `//'; it gets removed. A preprocessor +// directive line (using the standard syntax of `cpp') starts with `#' and +// gets copied verbatim to both the enumeration and the array. Whitespace +// outside of a string is insignificant. +// +// Preprocessor directives are ignored while the script computes maximum +// values; this essentially means that the maximum values can easily be too +// large. Given that the purpose of those values is to create local +// fixed-size arrays at compile time for further processing of the blue zone +// data, this isn't a problem. Note the final zero byte of a string is not +// counted. Note also that the count holds the number of UTF-8 encoded +// characters, not bytes. + + +// The blue zone string data, to be used in the blue stringsets below. + +AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: + + AF_BLUE_STRING_ARABIC_TOP + "ا إ ل ك ط ظ" + AF_BLUE_STRING_ARABIC_BOTTOM + "ت ث ط ظ ك" + // We don't necessarily have access to medial forms via Unicode in case + // Arabic presentational forms are missing. The only character that is + // guaranteed to have the same vertical position with joining (this is, + // non-isolated) forms is U+0640, ARABIC TATWEEL, which must join both + // round and flat curves. + AF_BLUE_STRING_ARABIC_JOIN + "ـ" + + AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP + "Ա Մ Ւ Փ Բ Գ Դ Օ" + AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM + "Ւ Ո Փ Ճ Շ Ս Տ Օ" + AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER + "ե է ի մ վ փ ֆ փ" + AF_BLUE_STRING_ARMENIAN_SMALL_TOP + "ա յ ւ ս գ ջ ր օ" + AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM + "հ ո ճ ա ե ծ ս օ" + AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER + "բ ը ի լ ղ պ փ ց" + + AF_BLUE_STRING_BENGALI_BASE + "অ ড ত ন ব ভ ল ক" + AF_BLUE_STRING_BENGALI_TOP + "ই ট ঠ ি ী ৈ ৗ" + AF_BLUE_STRING_BENGALI_HEAD + "ও এ ড ত ন ব ল ক" + + AF_BLUE_STRING_CHEROKEE_CAPITAL + "Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ" + AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER + "ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ" + AF_BLUE_STRING_CHEROKEE_SMALL + "ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ" + AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER + "ᏸ ꮐ ꭹ ꭻ" + + AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP + "Б В Е П З О С Э" + AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM + "Б В Е Ш З О С Э" + AF_BLUE_STRING_CYRILLIC_SMALL + "х п н ш е з о с" + AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER + "р у ф" + + AF_BLUE_STRING_DEVANAGARI_BASE + "क म अ आ थ ध भ श" + AF_BLUE_STRING_DEVANAGARI_TOP + "ई ऐ ओ औ ि ी ो ौ" + // note that some fonts have extreme variation in the height of the + // round head elements; for this reason we also define the `base' + // blue zone, which must be always present + AF_BLUE_STRING_DEVANAGARI_HEAD + "क म अ आ थ ध भ श" + AF_BLUE_STRING_DEVANAGARI_BOTTOM + "ु ृ" + + AF_BLUE_STRING_ETHIOPIC_TOP + "ሀ ሃ ዘ ፐ ማ በ ዋ ዐ" + AF_BLUE_STRING_ETHIOPIC_BOTTOM + "ለ ሐ በ ዘ ሀ ሪ ዐ ጨ" + + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP + "გ დ ე ვ თ ი ო ღ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM + "ა ზ მ ს შ ძ ხ პ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER + "ს ხ ქ ზ მ შ ჩ წ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER + "ე ვ ჟ ტ უ ფ ქ ყ" + + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP + "Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ" + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM + "Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ" + + AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP + "ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM + "ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER + "ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER + "ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ" + + AF_BLUE_STRING_GREEK_CAPITAL_TOP + "Γ Β Ε Ζ Θ Ο Ω" + AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM + "Β Δ Ζ Ξ Θ Ο" + AF_BLUE_STRING_GREEK_SMALL_BETA_TOP + "β θ δ ζ λ ξ" + AF_BLUE_STRING_GREEK_SMALL + "α ε ι ο π σ τ ω" + AF_BLUE_STRING_GREEK_SMALL_DESCENDER + "β γ η μ ρ φ χ ψ" + + AF_BLUE_STRING_GUJARATI_TOP + "ત ન ઋ ઌ છ ટ ર ૦" + AF_BLUE_STRING_GUJARATI_BOTTOM + "ખ ગ ઘ ઞ ઇ ઈ ઠ જ" + AF_BLUE_STRING_GUJARATI_ASCENDER + "ઈ ઊ િ ી લી શ્ચિ જિ સી" + AF_BLUE_STRING_GUJARATI_DESCENDER + "ુ ૃ ૄ ખુ છૃ છૄ" + AF_BLUE_STRING_GUJARATI_DIGIT_TOP + "૦ ૧ ૨ ૩ ૭" + + AF_BLUE_STRING_GURMUKHI_BASE + "ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ" + AF_BLUE_STRING_GURMUKHI_HEAD + "ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ" + AF_BLUE_STRING_GURMUKHI_TOP + "ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ" + AF_BLUE_STRING_GURMUKHI_BOTTOM + "ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ" + AF_BLUE_STRING_GURMUKHI_DIGIT_TOP + "੦ ੧ ੨ ੩ ੭" + + AF_BLUE_STRING_HEBREW_TOP + "ב ד ה ח ך כ ם ס" + AF_BLUE_STRING_HEBREW_BOTTOM + "ב ט כ ם ס צ" + AF_BLUE_STRING_HEBREW_DESCENDER + "ק ך ן ף ץ" + + AF_BLUE_STRING_KANNADA_TOP + "ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ" + AF_BLUE_STRING_KANNADA_BOTTOM + "ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭" + + AF_BLUE_STRING_KHMER_TOP + "ខ ទ ន ឧ ឩ ា" + AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP + "ក្ក ក្ខ ក្គ ក្ថ" + AF_BLUE_STRING_KHMER_BOTTOM + "ខ ឃ ច ឋ ប ម យ ឲ" + AF_BLUE_STRING_KHMER_DESCENDER + "ត្រ រៀ ឲ្យ អឿ" + AF_BLUE_STRING_KHMER_LARGE_DESCENDER + "ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ" + + AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP + "᧠ ᧡" + AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM + "᧶ ᧹" + + AF_BLUE_STRING_LAO_TOP + "າ ດ ອ ມ ລ ວ ຣ ງ" + AF_BLUE_STRING_LAO_BOTTOM + "າ ອ ບ ຍ ຣ ຮ ວ ຢ" + AF_BLUE_STRING_LAO_ASCENDER + "ປ ຢ ຟ ຝ" + AF_BLUE_STRING_LAO_LARGE_ASCENDER + "ໂ ໄ ໃ" + AF_BLUE_STRING_LAO_DESCENDER + "ງ ຊ ຖ ຽ ໆ ຯ" + + AF_BLUE_STRING_LATIN_CAPITAL_TOP + "T H E Z O C Q S" + AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM + "H E Z L O C U S" + AF_BLUE_STRING_LATIN_SMALL_F_TOP + "f i j k d b h" + AF_BLUE_STRING_LATIN_SMALL + "x z r o e s c" + AF_BLUE_STRING_LATIN_SMALL_DESCENDER + "p q g j y" + + // we assume that both the subscript and superscript ranges + // don't contain oldstyle digits (actually, most fonts probably + // have digits only in those ranges) + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP + "₀ ₃ ₅ ₇ ₈" + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM + "₀ ₁ ₂ ₃ ₈" + AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP + "ᵢ ⱼ ₕ ₖ ₗ" + AF_BLUE_STRING_LATIN_SUBS_SMALL + "ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ" + AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER + "ᵦ ᵧ ᵨ ᵩ ₚ" + + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP + "⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ" + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM + "⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ" + AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP + "ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ" + AF_BLUE_STRING_LATIN_SUPS_SMALL + "ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ" + AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER + "ᵖ ʸ ᵍ" + + AF_BLUE_STRING_MALAYALAM_TOP + "ഒ ട ഠ റ ച പ ച്ച പ്പ" + AF_BLUE_STRING_MALAYALAM_BOTTOM + "ട ഠ ധ ശ ഘ ച ഥ ല" + + AF_BLUE_STRING_MYANMAR_TOP + "ခ ဂ င ဒ ဝ ၥ ၊ ။" + AF_BLUE_STRING_MYANMAR_BOTTOM + "င ဎ ဒ ပ ဗ ဝ ၊ ။" + AF_BLUE_STRING_MYANMAR_ASCENDER + "ဩ ြ ၍ ၏ ၆ ါ ိ" + AF_BLUE_STRING_MYANMAR_DESCENDER + "ဉ ည ဥ ဩ ဨ ၂ ၅ ၉" + + AF_BLUE_STRING_SINHALA_TOP + "ඉ ක ඝ ඳ ප ය ල ෆ" + AF_BLUE_STRING_SINHALA_BOTTOM + "එ ඔ ඝ ජ ට ථ ධ ර" + AF_BLUE_STRING_SINHALA_DESCENDER + "ද ඳ උ ල තූ තු බු දු" + + AF_BLUE_STRING_TAMIL_TOP + "உ ஒ ஓ ற ஈ க ங ச" + AF_BLUE_STRING_TAMIL_BOTTOM + "க ச ல ஶ உ ங ட ப" + + AF_BLUE_STRING_TELUGU_TOP + "ఇ ఌ ఙ ఞ ణ ఱ ౯" + AF_BLUE_STRING_TELUGU_BOTTOM + "అ క చ ర ఽ ౨ ౬" + + AF_BLUE_STRING_THAI_TOP + "บ เ แ อ ก า" + AF_BLUE_STRING_THAI_BOTTOM + "บ ป ษ ฯ อ ย ฮ" + AF_BLUE_STRING_THAI_ASCENDER + "ป ฝ ฟ" + AF_BLUE_STRING_THAI_LARGE_ASCENDER + "โ ใ ไ" + AF_BLUE_STRING_THAI_DESCENDER + "ฎ ฏ ฤ ฦ" + AF_BLUE_STRING_THAI_LARGE_DESCENDER + "ญ ฐ" + AF_BLUE_STRING_THAI_DIGIT_TOP + "๐ ๑ ๓" + + +#ifdef AF_CONFIG_OPTION_CJK + + AF_BLUE_STRING_CJK_TOP + "他 们 你 來 們 到 和 地" + " 对 對 就 席 我 时 時 會" + " 来 為 能 舰 說 说 这 這" + " 齊 |" + " 军 同 已 愿 既 星 是 景" + " 民 照 现 現 理 用 置 要" + " 軍 那 配 里 開 雷 露 面" + " 顾" + AF_BLUE_STRING_CJK_BOTTOM + "个 为 人 他 以 们 你 來" + " 個 們 到 和 大 对 對 就" + " 我 时 時 有 来 為 要 說" + " 说 |" + " 主 些 因 它 想 意 理 生" + " 當 看 着 置 者 自 著 裡" + " 过 还 进 進 過 道 還 里" + " 面" + +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + + AF_BLUE_STRING_CJK_LEFT + " 些 们 你 來 們 到 和 地" + " 她 将 將 就 年 得 情 最" + " 样 樣 理 能 說 说 这 這" + " 通 |" + " 即 吗 吧 听 呢 品 响 嗎" + " 师 師 收 断 斷 明 眼 間" + " 间 际 陈 限 除 陳 随 際" + " 隨" + AF_BLUE_STRING_CJK_RIGHT + "事 前 學 将 將 情 想 或" + " 政 斯 新 样 樣 民 沒 没" + " 然 特 现 現 球 第 經 谁" + " 起 |" + " 例 別 别 制 动 動 吗 嗎" + " 增 指 明 朝 期 构 物 确" + " 种 調 调 費 费 那 都 間" + " 间" + +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + +#endif /* AF_CONFIG_OPTION_CJK */ + + +// The blue zone stringsets, as used in the script styles, cf. `afstyles.h'. +// +// The AF_BLUE_PROPERTY_XXX flags are defined in `afblue.h'; here some +// explanations. +// +// A blue zone in general is defined by a reference and an overshoot line. +// During the hinting process, all coordinate values between those two lines +// are set equal to the reference value, provided that the blue zone is not +// wider than 0.75 pixels (otherwise the blue zone gets ignored). All +// entries must have `AF_BLUE_STRING_MAX' as the final line. +// +// During the glyph analysis, edges are sorted from bottom to top, and then +// sequentially checked, edge by edge, against the blue zones in the order +// given below. +// +// +// latin auto-hinter +// ----------------- +// +// Characters in a blue string are automatically classified as having a flat +// (reference) or a round (overshoot) extremum. The blue zone is then set +// up by the mean values of all flat extrema and all round extrema, +// respectively. Only horizontal blue zones (i.e., adjusting vertical +// coordinate values) are supported. +// +// Some scripts like Khmer need character composition to get all necessary +// blue zones, since Unicode only provides an abstract data model that +// doesn't represent all possible glyph shapes. For such character +// clusters, the HarfBuzz library is used to convert them into the +// corresponding glyphs. The largest glyph element (where `largest' can be +// either `largest ascender' or `largest descender') then defines the +// corresponding flat or round extremum. +// +// For the latin auto-hinter, the overshoot should be larger than the +// reference for top zones, and vice versa for bottom zones. +// +// LATIN_TOP +// Take the maximum flat and round coordinate values of the blue string +// characters for computing the blue zone's reference and overshoot +// values. +// +// If not set, take the minimum values. +// +// Mutually exclusive with `LATIN_SUB_TOP'. +// +// LATIN_SUB_TOP +// For all glyphs of a character cluster, compute the maximum flat +// and round coordinate values of each component, then take the +// smallest of the maximum values. The idea is to get the top of +// subscript glyphs, as used in Khmer, for example. Note that +// this mechanism doesn't work for ordinary ligatures. +// +// This flags indicates a secondary blue zone: It gets removed if +// there is a non-LATIN_SUB_TOP blue zone at the same coordinate +// value (after scaling). +// +// Mutually exclusive with `LATIN_TOP'. +// +// LATIN_NEUTRAL +// Ignore round extrema and define the blue zone with flat values only. +// Both top and bottom of contours can match. This is useful for +// scripts like Devanagari where vowel signs attach to the base +// character and are implemented as components of composite glyphs. +// +// If not set, both round and flat extrema are taken into account. +// Additionally, only the top or the bottom of a contour can match, +// depending on the LATIN_TOP flag. +// +// Neutral blue zones should always follow non-neutral blue zones. +// +// LATIN_X_HEIGHT +// Scale all glyphs vertically from the corresponding script to make the +// reference line of this blue zone align on the grid. The scaling +// takes place before all other blue zones get aligned to the grid. +// Only one blue character string of a script style can have this flag. +// +// LATIN_LONG +// Apply an additional constraint for blue zone values: Don't +// necessarily use the extremum as-is but a segment of the topmost (or +// bottommost) contour that is longer than a heuristic threshold, and +// which is not too far away vertically from the real extremum. This +// ensures that small bumps in the outline are ignored (for example, the +// `vertical serifs' found in many Hebrew glyph designs). +// +// The segment must be at least EM/25 font units long, and the distance +// to the extremum must be smaller than EM/4. +// +// +// cjk auto-hinter +// --------------- +// +// Characters in a blue string are *not* automatically classified. Instead, +// first come the characters used for the overshoot value, then the +// character `|', then the characters used for the reference value +// (everything separated by space characters). The blue zone is then set up +// by the mean values of all reference values and all overshoot values, +// respectively. Both horizontal and vertical blue zones (i.e., adjusting +// vertical and horizontal coordinate values, respectively) are supported. +// +// For the cjk auto-hinter, the overshoot should be smaller than the +// reference for top zones, and vice versa for bottom zones. +// +// CJK_TOP +// Take the maximum flat and round coordinate values of the blue string +// characters. If not set, take the minimum values. +// +// CJK_RIGHT +// A synonym for CJK_TOP. If CJK_HORIZ is set, this flag indicates the +// right blue zone, taking horizontal maximum values. +// +// CJK_HORIZ +// Define a blue zone for horizontal hinting (i.e., vertical blue +// zones). If not set, this is a blue zone for vertical hinting. + + +AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: + + AF_BLUE_STRINGSET_ARAB + { AF_BLUE_STRING_ARABIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ARABIC_BOTTOM, 0 } + { AF_BLUE_STRING_ARABIC_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_ARMN + { AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ARMENIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_BENG + { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_BENGALI_BASE, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CHER + { AF_BLUE_STRING_CHEROKEE_CAPITAL, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CHEROKEE_CAPITAL, 0 } + { AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CHEROKEE_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_CHEROKEE_SMALL, 0 } + { AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CYRL + { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_CYRILLIC_SMALL, 0 } + { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_DEVA + { AF_BLUE_STRING_DEVANAGARI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_DEVANAGARI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_DEVANAGARI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_DEVANAGARI_BASE, 0 } + { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_ETHI + { AF_BLUE_STRING_ETHIOPIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + // blue zones for Mtavruli are missing (not yet defined in Unicode) + AF_BLUE_STRINGSET_GEOR + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GEOK + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GREK + { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_GREEK_SMALL_BETA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GREEK_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GREEK_SMALL, 0 } + { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GUJR + { AF_BLUE_STRING_GUJARATI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GUJARATI_BOTTOM, 0 } + { AF_BLUE_STRING_GUJARATI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GUJARATI_DESCENDER, 0 } + { AF_BLUE_STRING_GUJARATI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GURU + { AF_BLUE_STRING_GURMUKHI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GURMUKHI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GURMUKHI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GURMUKHI_BOTTOM, 0 } + { AF_BLUE_STRING_GURMUKHI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_HEBR + { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_LONG } + { AF_BLUE_STRING_HEBREW_BOTTOM, 0 } + { AF_BLUE_STRING_HEBREW_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KNDA + { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_KANNADA_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KHMR + { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP } + { AF_BLUE_STRING_KHMER_BOTTOM, 0 } + { AF_BLUE_STRING_KHMER_DESCENDER, 0 } + { AF_BLUE_STRING_KHMER_LARGE_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KHMS + { AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_LAO + { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LAO_BOTTOM, 0 } + { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LAO_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_LATN + { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LATIN_SMALL, 0 } + { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_LATB + { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SUBS_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LATIN_SUBS_SMALL, 0 } + { AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_LATP + { AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SUPS_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LATIN_SUPS_SMALL, 0 } + { AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_MLYM + { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_MYMR + { AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_MYANMAR_BOTTOM, 0 } + { AF_BLUE_STRING_MYANMAR_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MYANMAR_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_NONE + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_SINH + { AF_BLUE_STRING_SINHALA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_SINHALA_BOTTOM, 0 } + { AF_BLUE_STRING_SINHALA_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_TAML + { AF_BLUE_STRING_TAMIL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_TAMIL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_TELU + { AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_TELUGU_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_THAI + { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_THAI_BOTTOM, 0 } + { AF_BLUE_STRING_THAI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_THAI_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_THAI_DESCENDER, 0 } + { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 } + { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 } + { AF_BLUE_STRING_MAX, 0 } + + +#ifdef AF_CONFIG_OPTION_CJK + + AF_BLUE_STRINGSET_HANI + { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP } + { AF_BLUE_STRING_CJK_BOTTOM, 0 } +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + { AF_BLUE_STRING_CJK_LEFT, AF_BLUE_PROPERTY_CJK_HORIZ } + { AF_BLUE_STRING_CJK_RIGHT, AF_BLUE_PROPERTY_CJK_HORIZ | + AF_BLUE_PROPERTY_CJK_RIGHT } +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + { AF_BLUE_STRING_MAX, 0 } + +#endif /* AF_CONFIG_OPTION_CJK */ + + +// END diff --git a/drivers/freetype/src/autofit/afblue.h b/drivers/freetype/src/autofit/afblue.h new file mode 100644 index 0000000000..41f838e457 --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.h @@ -0,0 +1,308 @@ +/* This file has been generated by the Perl script `afblue.pl', */ +/* using data from file `afblue.dat'. */ + +/***************************************************************************/ +/* */ +/* afblue.h */ +/* */ +/* Auto-fitter data for blue strings (specification). */ +/* */ +/* Copyright 2013-2016 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 AFBLUE_H_ +#define AFBLUE_H_ + + +FT_BEGIN_HEADER + + + /* an auxiliary macro to decode a UTF-8 character -- since we only use */ + /* hard-coded, self-converted data, no error checking is performed */ +#define GET_UTF8_CHAR( ch, p ) \ + do \ + { \ + ch = (unsigned char)*p++; \ + if ( ch >= 0x80 ) \ + { \ + FT_UInt len_; \ + \ + \ + if ( ch < 0xE0 ) \ + { \ + len_ = 1; \ + ch &= 0x1F; \ + } \ + else if ( ch < 0xF0 ) \ + { \ + len_ = 2; \ + ch &= 0x0F; \ + } \ + else \ + { \ + len_ = 3; \ + ch &= 0x07; \ + } \ + \ + for ( ; len_ > 0; len_-- ) \ + ch = ( ch << 6 ) | ( *p++ & 0x3F ); \ + } \ + } while ( 0 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** B L U E S T R I N G S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* At the bottommost level, we define strings for finding blue zones. */ + + +#define AF_BLUE_STRING_MAX_LEN 51 + + /* The AF_Blue_String enumeration values are offsets into the */ + /* `af_blue_strings' array. */ + + typedef enum AF_Blue_String_ + { + AF_BLUE_STRING_ARABIC_TOP = 0, + AF_BLUE_STRING_ARABIC_BOTTOM = 18, + AF_BLUE_STRING_ARABIC_JOIN = 33, + AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP = 36, + AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM = 60, + AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER = 84, + AF_BLUE_STRING_ARMENIAN_SMALL_TOP = 108, + AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM = 132, + AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER = 156, + AF_BLUE_STRING_BENGALI_BASE = 180, + AF_BLUE_STRING_BENGALI_TOP = 212, + AF_BLUE_STRING_BENGALI_HEAD = 240, + AF_BLUE_STRING_CHEROKEE_CAPITAL = 272, + AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER = 304, + AF_BLUE_STRING_CHEROKEE_SMALL = 336, + AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER = 368, + AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 384, + AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 408, + AF_BLUE_STRING_CYRILLIC_SMALL = 432, + AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 456, + AF_BLUE_STRING_DEVANAGARI_BASE = 465, + AF_BLUE_STRING_DEVANAGARI_TOP = 497, + AF_BLUE_STRING_DEVANAGARI_HEAD = 529, + AF_BLUE_STRING_DEVANAGARI_BOTTOM = 561, + AF_BLUE_STRING_ETHIOPIC_TOP = 569, + AF_BLUE_STRING_ETHIOPIC_BOTTOM = 601, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP = 633, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM = 665, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER = 697, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER = 729, + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP = 761, + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM = 793, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP = 825, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM = 857, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER = 889, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER = 921, + AF_BLUE_STRING_GREEK_CAPITAL_TOP = 953, + AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 974, + AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 992, + AF_BLUE_STRING_GREEK_SMALL = 1010, + AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 1034, + AF_BLUE_STRING_GUJARATI_TOP = 1058, + AF_BLUE_STRING_GUJARATI_BOTTOM = 1090, + AF_BLUE_STRING_GUJARATI_ASCENDER = 1122, + AF_BLUE_STRING_GUJARATI_DESCENDER = 1172, + AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 1205, + AF_BLUE_STRING_GURMUKHI_BASE = 1225, + AF_BLUE_STRING_GURMUKHI_HEAD = 1257, + AF_BLUE_STRING_GURMUKHI_TOP = 1289, + AF_BLUE_STRING_GURMUKHI_BOTTOM = 1321, + AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 1353, + AF_BLUE_STRING_HEBREW_TOP = 1373, + AF_BLUE_STRING_HEBREW_BOTTOM = 1397, + AF_BLUE_STRING_HEBREW_DESCENDER = 1415, + AF_BLUE_STRING_KANNADA_TOP = 1430, + AF_BLUE_STRING_KANNADA_BOTTOM = 1474, + AF_BLUE_STRING_KHMER_TOP = 1506, + AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 1530, + AF_BLUE_STRING_KHMER_BOTTOM = 1570, + AF_BLUE_STRING_KHMER_DESCENDER = 1602, + AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 1636, + AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 1723, + AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 1731, + AF_BLUE_STRING_LAO_TOP = 1739, + AF_BLUE_STRING_LAO_BOTTOM = 1771, + AF_BLUE_STRING_LAO_ASCENDER = 1803, + AF_BLUE_STRING_LAO_LARGE_ASCENDER = 1819, + AF_BLUE_STRING_LAO_DESCENDER = 1831, + AF_BLUE_STRING_LATIN_CAPITAL_TOP = 1855, + AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 1871, + AF_BLUE_STRING_LATIN_SMALL_F_TOP = 1887, + AF_BLUE_STRING_LATIN_SMALL = 1901, + AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 1915, + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 1925, + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 1945, + AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 1965, + AF_BLUE_STRING_LATIN_SUBS_SMALL = 1985, + AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 2021, + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 2041, + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 2072, + AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 2101, + AF_BLUE_STRING_LATIN_SUPS_SMALL = 2127, + AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 2152, + AF_BLUE_STRING_MALAYALAM_TOP = 2163, + AF_BLUE_STRING_MALAYALAM_BOTTOM = 2207, + AF_BLUE_STRING_MYANMAR_TOP = 2239, + AF_BLUE_STRING_MYANMAR_BOTTOM = 2271, + AF_BLUE_STRING_MYANMAR_ASCENDER = 2303, + AF_BLUE_STRING_MYANMAR_DESCENDER = 2331, + AF_BLUE_STRING_SINHALA_TOP = 2363, + AF_BLUE_STRING_SINHALA_BOTTOM = 2395, + AF_BLUE_STRING_SINHALA_DESCENDER = 2427, + AF_BLUE_STRING_TAMIL_TOP = 2471, + AF_BLUE_STRING_TAMIL_BOTTOM = 2503, + AF_BLUE_STRING_TELUGU_TOP = 2535, + AF_BLUE_STRING_TELUGU_BOTTOM = 2563, + AF_BLUE_STRING_THAI_TOP = 2591, + AF_BLUE_STRING_THAI_BOTTOM = 2615, + AF_BLUE_STRING_THAI_ASCENDER = 2643, + AF_BLUE_STRING_THAI_LARGE_ASCENDER = 2655, + AF_BLUE_STRING_THAI_DESCENDER = 2667, + AF_BLUE_STRING_THAI_LARGE_DESCENDER = 2683, + AF_BLUE_STRING_THAI_DIGIT_TOP = 2691, + af_blue_1_1 = 2702, +#ifdef AF_CONFIG_OPTION_CJK + AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1, + AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203, + af_blue_1_1_1 = af_blue_1_1 + 404, +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + AF_BLUE_STRING_CJK_LEFT = af_blue_1_1_1 + 1, + AF_BLUE_STRING_CJK_RIGHT = af_blue_1_1_1 + 204, + af_blue_1_1_2 = af_blue_1_1_1 + 405, +#else + af_blue_1_1_2 = af_blue_1_1_1 + 0, +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + af_blue_1_2 = af_blue_1_1_2 + 0, +#else + af_blue_1_2 = af_blue_1_1 + 0, +#endif /* AF_CONFIG_OPTION_CJK */ + + + AF_BLUE_STRING_MAX /* do not remove */ + + } AF_Blue_String; + + + FT_LOCAL_ARRAY( char ) + af_blue_strings[]; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** B L U E S T R I N G S E T S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* The next level is to group blue strings into style-specific sets. */ + + + /* Properties are specific to a writing system. We assume that a given */ + /* blue string can't be used in more than a single writing system, which */ + /* is a safe bet. */ +#define AF_BLUE_PROPERTY_LATIN_TOP ( 1U << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_LATIN_SUB_TOP ( 1U << 1 ) +#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 2 ) +#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 3 ) +#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 4 ) + +#define AF_BLUE_PROPERTY_CJK_TOP ( 1U << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1U << 1 ) /* must have value 2 */ +#define AF_BLUE_PROPERTY_CJK_RIGHT AF_BLUE_PROPERTY_CJK_TOP + + +#define AF_BLUE_STRINGSET_MAX_LEN 8 + + /* The AF_Blue_Stringset enumeration values are offsets into the */ + /* `af_blue_stringsets' array. */ + + typedef enum AF_Blue_Stringset_ + { + AF_BLUE_STRINGSET_ARAB = 0, + AF_BLUE_STRINGSET_ARMN = 4, + AF_BLUE_STRINGSET_BENG = 11, + AF_BLUE_STRINGSET_CHER = 16, + AF_BLUE_STRINGSET_CYRL = 23, + AF_BLUE_STRINGSET_DEVA = 29, + AF_BLUE_STRINGSET_ETHI = 35, + AF_BLUE_STRINGSET_GEOR = 38, + AF_BLUE_STRINGSET_GEOK = 43, + AF_BLUE_STRINGSET_GREK = 50, + AF_BLUE_STRINGSET_GUJR = 57, + AF_BLUE_STRINGSET_GURU = 63, + AF_BLUE_STRINGSET_HEBR = 69, + AF_BLUE_STRINGSET_KNDA = 73, + AF_BLUE_STRINGSET_KHMR = 76, + AF_BLUE_STRINGSET_KHMS = 82, + AF_BLUE_STRINGSET_LAO = 85, + AF_BLUE_STRINGSET_LATN = 91, + AF_BLUE_STRINGSET_LATB = 98, + AF_BLUE_STRINGSET_LATP = 105, + AF_BLUE_STRINGSET_MLYM = 112, + AF_BLUE_STRINGSET_MYMR = 115, + AF_BLUE_STRINGSET_NONE = 120, + AF_BLUE_STRINGSET_SINH = 121, + AF_BLUE_STRINGSET_TAML = 125, + AF_BLUE_STRINGSET_TELU = 128, + AF_BLUE_STRINGSET_THAI = 131, + af_blue_2_1 = 139, +#ifdef AF_CONFIG_OPTION_CJK + AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0, + af_blue_2_1_1 = af_blue_2_1 + 2, +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + af_blue_2_1_2 = af_blue_2_1_1 + 2, +#else + af_blue_2_1_2 = af_blue_2_1_1 + 0, +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + af_blue_2_2 = af_blue_2_1_2 + 1, +#else + af_blue_2_2 = af_blue_2_1 + 0, +#endif /* AF_CONFIG_OPTION_CJK */ + + + AF_BLUE_STRINGSET_MAX /* do not remove */ + + } AF_Blue_Stringset; + + + typedef struct AF_Blue_StringRec_ + { + AF_Blue_String string; + FT_UShort properties; + + } AF_Blue_StringRec; + + + FT_LOCAL_ARRAY( AF_Blue_StringRec ) + af_blue_stringsets[]; + +/* */ + +FT_END_HEADER + + +#endif /* AFBLUE_H_ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afblue.hin b/drivers/freetype/src/autofit/afblue.hin new file mode 100644 index 0000000000..dd44e77254 --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.hin @@ -0,0 +1,146 @@ +/***************************************************************************/ +/* */ +/* afblue.h */ +/* */ +/* Auto-fitter data for blue strings (specification). */ +/* */ +/* Copyright 2013-2016 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 AFBLUE_H_ +#define AFBLUE_H_ + + +FT_BEGIN_HEADER + + + /* an auxiliary macro to decode a UTF-8 character -- since we only use */ + /* hard-coded, self-converted data, no error checking is performed */ +#define GET_UTF8_CHAR( ch, p ) \ + do \ + { \ + ch = (unsigned char)*p++; \ + if ( ch >= 0x80 ) \ + { \ + FT_UInt len_; \ + \ + \ + if ( ch < 0xE0 ) \ + { \ + len_ = 1; \ + ch &= 0x1F; \ + } \ + else if ( ch < 0xF0 ) \ + { \ + len_ = 2; \ + ch &= 0x0F; \ + } \ + else \ + { \ + len_ = 3; \ + ch &= 0x07; \ + } \ + \ + for ( ; len_ > 0; len_-- ) \ + ch = ( ch << 6 ) | ( *p++ & 0x3F ); \ + } \ + } while ( 0 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** B L U E S T R I N G S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* At the bottommost level, we define strings for finding blue zones. */ + + +#define AF_BLUE_STRING_MAX_LEN @AF_BLUE_STRING_MAX_LEN@ + + /* The AF_Blue_String enumeration values are offsets into the */ + /* `af_blue_strings' array. */ + + typedef enum AF_Blue_String_ + { +@AF_BLUE_STRING_ENUM@ + + AF_BLUE_STRING_MAX /* do not remove */ + + } AF_Blue_String; + + + FT_LOCAL_ARRAY( char ) + af_blue_strings[]; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** B L U E S T R I N G S E T S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* The next level is to group blue strings into style-specific sets. */ + + + /* Properties are specific to a writing system. We assume that a given */ + /* blue string can't be used in more than a single writing system, which */ + /* is a safe bet. */ +#define AF_BLUE_PROPERTY_LATIN_TOP ( 1U << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_LATIN_SUB_TOP ( 1U << 1 ) +#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 2 ) +#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 3 ) +#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 4 ) + +#define AF_BLUE_PROPERTY_CJK_TOP ( 1U << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1U << 1 ) /* must have value 2 */ +#define AF_BLUE_PROPERTY_CJK_RIGHT AF_BLUE_PROPERTY_CJK_TOP + + +#define AF_BLUE_STRINGSET_MAX_LEN @AF_BLUE_STRINGSET_MAX_LEN@ + + /* The AF_Blue_Stringset enumeration values are offsets into the */ + /* `af_blue_stringsets' array. */ + + typedef enum AF_Blue_Stringset_ + { +@AF_BLUE_STRINGSET_ENUM@ + + AF_BLUE_STRINGSET_MAX /* do not remove */ + + } AF_Blue_Stringset; + + + typedef struct AF_Blue_StringRec_ + { + AF_Blue_String string; + FT_UShort properties; + + } AF_Blue_StringRec; + + + FT_LOCAL_ARRAY( AF_Blue_StringRec ) + af_blue_stringsets[]; + +/* */ + +FT_END_HEADER + + +#endif /* AFBLUE_H_ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afcjk.c b/drivers/freetype/src/autofit/afcjk.c index f69a528e3b..4823c1d7f8 100644 --- a/drivers/freetype/src/autofit/afcjk.c +++ b/drivers/freetype/src/autofit/afcjk.c @@ -2,9 +2,9 @@ /* */ /* afcjk.c */ /* */ -/* Auto-fitter hinting routines for CJK script (body). */ +/* Auto-fitter hinting routines for CJK writing system (body). */ /* */ -/* Copyright 2006-2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,7 +26,8 @@ #include FT_ADVANCES_H #include FT_INTERNAL_DEBUG_H -#include "aftypes.h" +#include "afglobal.h" +#include "afpic.h" #include "aflatin.h" @@ -73,6 +74,12 @@ AF_GlyphHintsRec hints[1]; + FT_TRACE5(( "\n" + "cjk standard widths computation (style `%s')\n" + "===================================================\n" + "\n", + af_style_names[metrics->root.style_class->style] )); + af_glyph_hints_init( hints, face->memory ); metrics->axis[AF_DIMENSION_HORZ].width_count = 0; @@ -80,17 +87,75 @@ { FT_Error error; - FT_UInt glyph_index; + FT_ULong glyph_index; int dim; AF_CJKMetricsRec dummy[1]; AF_Scaler scaler = &dummy->root.scaler; +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = metrics->root.globals; +#endif + + AF_StyleClass style_class = metrics->root.style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + void* shaper_buf; + const char* p; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong ch = 0; +#endif + + p = script_class->standard_charstring; + shaper_buf = af_shaper_buf_create( face ); + + /* We check a list of standard characters. The first match wins. */ + + glyph_index = 0; + while ( *p ) + { + unsigned int num_idx; + +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; +#endif + + + while ( *p == ' ' ) + p++; - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); - if ( glyph_index == 0 ) +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; + + /* otherwise exit loop if we have a result */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); + if ( glyph_index ) + break; + } + + af_shaper_buf_destroy( face, shaper_buf ); + + if ( !glyph_index ) + goto Exit; + + if ( !glyph_index ) goto Exit; + FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n", + ch, glyph_index )); + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); if ( error || face->glyph->outline.n_points <= 0 ) goto Exit; @@ -108,7 +173,7 @@ scaler->render_mode = FT_RENDER_MODE_NORMAL; scaler->flags = 0; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy ); error = af_glyph_hints_reload( hints, &face->glyph->outline ); if ( error ) @@ -122,11 +187,21 @@ FT_UInt num_widths = 0; - error = af_latin_hints_compute_segments( hints, (AF_Dimension)dim ); + error = af_latin_hints_compute_segments( hints, + (AF_Dimension)dim ); if ( error ) goto Exit; - af_latin_hints_link_segments( hints, (AF_Dimension)dim ); + /* + * We assume that the glyphs selected for the stem width + * computation are `featureless' enough so that the linking + * algorithm works fine without adjustments of its scoring + * function. + */ + af_latin_hints_link_segments( hints, + 0, + NULL, + (AF_Dimension)dim ); seg = axhints->segments; limit = seg + axhints->num_segments; @@ -151,7 +226,7 @@ } /* this also replaces multiple almost identical stem widths */ - /* with a single one (the value 100 is heuristic) */ + /* with a single one (the value 100 is heuristic) */ af_sort_and_quantize_widths( &num_widths, axis->widths, dummy->units_per_em / 100 ); axis->width_count = num_widths; @@ -171,264 +246,239 @@ axis->edge_distance_threshold = stdw / 5; axis->standard_width = stdw; axis->extra_light = 0; + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt i; + + + FT_TRACE5(( "%s widths:\n", + dim == AF_DIMENSION_VERT ? "horizontal" + : "vertical" )); + + FT_TRACE5(( " %d (standard)", axis->standard_width )); + for ( i = 1; i < axis->width_count; i++ ) + FT_TRACE5(( " %d", axis->widths[i].org )); + + FT_TRACE5(( "\n" )); + } +#endif } } + FT_TRACE5(( "\n" )); + af_glyph_hints_done( hints ); } -#define AF_CJK_MAX_TEST_CHARACTERS 32 + /* Find all blue zones. */ + static void + af_cjk_metrics_init_blues( AF_CJKMetrics metrics, + FT_Face face ) + { + FT_Pos fills[AF_BLUE_STRING_MAX_LEN]; + FT_Pos flats[AF_BLUE_STRING_MAX_LEN]; - /* Each blue zone has two types of fill and unfill, this is, */ - /* filling the entire glyph square or not. */ + FT_UInt num_fills; + FT_UInt num_flats; - enum - { - AF_CJK_BLUE_TYPE_FILL, - AF_CJK_BLUE_TYPE_UNFILL, - AF_CJK_BLUE_TYPE_MAX - }; + FT_Bool fill; + AF_CJKBlue blue; + FT_Error error; + AF_CJKAxis axis; + FT_Outline outline; - /* Put some common and representative Han Ideographs characters here. */ - static const FT_ULong af_cjk_hani_blue_chars[AF_CJK_BLUE_MAX] - [AF_CJK_BLUE_TYPE_MAX] - [AF_CJK_MAX_TEST_CHARACTERS] = - { - { - { - 0x4ED6, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730, - 0x5BF9, 0x5C0D, 0x5C31, 0x5E2D, 0x6211, 0x65F6, 0x6642, 0x6703, - 0x6765, 0x70BA, 0x80FD, 0x8230, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019, - 0x9F4A /* top fill */ - }, - { - 0x519B, 0x540C, 0x5DF2, 0x613F, 0x65E2, 0x661F, 0x662F, 0x666F, - 0x6C11, 0x7167, 0x73B0, 0x73FE, 0x7406, 0x7528, 0x7F6E, 0x8981, - 0x8ECD, 0x90A3, 0x914D, 0x91CC, 0x958B, 0x96F7, 0x9732, 0x9762, - 0x987E /* top unfill */ - } - }, - { - { - 0x4E2A, 0x4E3A, 0x4EBA, 0x4ED6, 0x4EE5, 0x4EEC, 0x4F60, 0x4F86, - 0x500B, 0x5011, 0x5230, 0x548C, 0x5927, 0x5BF9, 0x5C0D, 0x5C31, - 0x6211, 0x65F6, 0x6642, 0x6709, 0x6765, 0x70BA, 0x8981, 0x8AAA, - 0x8BF4 /* bottom fill */ - }, - { - 0x4E3B, 0x4E9B, 0x56E0, 0x5B83, 0x60F3, 0x610F, 0x7406, 0x751F, - 0x7576, 0x770B, 0x7740, 0x7F6E, 0x8005, 0x81EA, 0x8457, 0x88E1, - 0x8FC7, 0x8FD8, 0x8FDB, 0x9032, 0x904E, 0x9053, 0x9084, 0x91CC, - 0x9762 /* bottom unfill */ - } - }, -#ifndef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - { {0x0000}, {0x0000} }, - { {0x0000}, {0x0000} } -#else - { - { - 0x4E9B, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730, - 0x5979, 0x5C06, 0x5C07, 0x5C31, 0x5E74, 0x5F97, 0x60C5, 0x6700, - 0x6837, 0x6A23, 0x7406, 0x80FD, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019, - 0x901A /* left fill */ - }, - { - 0x5373, 0x5417, 0x5427, 0x542C, 0x5462, 0x54C1, 0x54CD, 0x55CE, - 0x5E08, 0x5E2B, 0x6536, 0x65AD, 0x65B7, 0x660E, 0x773C, 0x9593, - 0x95F4, 0x9645, 0x9648, 0x9650, 0x9664, 0x9673, 0x968F, 0x969B, - 0x96A8 /* left unfill */ - } - }, - { - { - 0x4E8B, 0x524D, 0x5B78, 0x5C06, 0x5C07, 0x60C5, 0x60F3, 0x6216, - 0x653F, 0x65AF, 0x65B0, 0x6837, 0x6A23, 0x6C11, 0x6C92, 0x6CA1, - 0x7136, 0x7279, 0x73B0, 0x73FE, 0x7403, 0x7B2C, 0x7D93, 0x8C01, - 0x8D77 /* right fill */ - }, - { - 0x4F8B, 0x5225, 0x522B, 0x5236, 0x52A8, 0x52D5, 0x5417, 0x55CE, - 0x589E, 0x6307, 0x660E, 0x671D, 0x671F, 0x6784, 0x7269, 0x786E, - 0x79CD, 0x8ABF, 0x8C03, 0x8CBB, 0x8D39, 0x90A3, 0x90FD, 0x9593, - 0x95F4 /* right unfill */ - } - } -#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ - }; + AF_StyleClass sc = metrics->root.style_class; + AF_Blue_Stringset bss = sc->blue_stringset; + const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; - /* Calculate blue zones for all the CJK_BLUE_XXX's. */ + void* shaper_buf; - static void - af_cjk_metrics_init_blues( AF_CJKMetrics metrics, - FT_Face face, - const FT_ULong blue_chars - [AF_CJK_BLUE_MAX] - [AF_CJK_BLUE_TYPE_MAX] - [AF_CJK_MAX_TEST_CHARACTERS] ) - { - FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS]; - FT_Pos flats[AF_CJK_MAX_TEST_CHARACTERS]; - FT_Int num_fills; - FT_Int num_flats; + /* we walk over the blue character strings as specified in the */ + /* style's entry in the `af_blue_stringset' array, computing its */ + /* extremum points (depending on the string properties) */ - FT_Int bb; - AF_CJKBlue blue; - FT_Error error; - AF_CJKAxis axis; - FT_GlyphSlot glyph = face->glyph; + FT_TRACE5(( "cjk blue zones computation\n" + "==========================\n" + "\n" )); -#ifdef FT_DEBUG_LEVEL_TRACE - FT_String* cjk_blue_name[AF_CJK_BLUE_MAX] = { - (FT_String*)"top", - (FT_String*)"bottom", - (FT_String*)"left", - (FT_String*)"right" - }; - FT_String* cjk_blue_type_name[AF_CJK_BLUE_TYPE_MAX] = { - (FT_String*)"filled", - (FT_String*)"unfilled" - }; -#endif + shaper_buf = af_shaper_buf_create( face ); + + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) + { + const char* p = &af_blue_strings[bs->string]; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; - /* We compute the blues simply by loading each character from the */ - /* `blue_chars[blues]' string, then computing its extreme points */ - /* (depending blue zone type etc.). */ + if ( AF_CJK_IS_HORIZ_BLUE( bs ) ) + axis = &metrics->axis[AF_DIMENSION_HORZ]; + else + axis = &metrics->axis[AF_DIMENSION_VERT]; - FT_TRACE5(( "cjk blue zones computation\n" )); - FT_TRACE5(( "------------------------------------------------\n" )); +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_String* cjk_blue_name[4] = + { + (FT_String*)"bottom", /* -- , -- */ + (FT_String*)"top", /* -- , TOP */ + (FT_String*)"left", /* HORIZ, -- */ + (FT_String*)"right" /* HORIZ, TOP */ + }; - for ( bb = 0; bb < AF_CJK_BLUE_MAX; bb++ ) - { - FT_Int fill_type; - FT_Pos* blue_ref; - FT_Pos* blue_shoot; + FT_TRACE5(( "blue zone %d (%s):\n", + axis->blue_count, + cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) | + AF_CJK_IS_TOP_BLUE( bs ) ] )); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ num_fills = 0; num_flats = 0; - for ( fill_type = 0; fill_type < AF_CJK_BLUE_TYPE_MAX; fill_type++ ) + fill = 1; /* start with characters that define fill values */ + FT_TRACE5(( " [overshoot values]\n" )); + + while ( *p ) { - const FT_ULong* p = blue_chars[bb][fill_type]; - const FT_ULong* limit = p + AF_CJK_MAX_TEST_CHARACTERS; - FT_Bool fill = FT_BOOL( - fill_type == AF_CJK_BLUE_TYPE_FILL ); + FT_ULong glyph_index; + FT_Pos best_pos; /* same as points.y or points.x, resp. */ + FT_Int best_point; + FT_Vector* points; + unsigned int num_idx; - FT_TRACE5(( "cjk blue %s/%s\n", cjk_blue_name[bb], - cjk_blue_type_name[fill_type] )); +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; + FT_ULong ch; +#endif - for ( ; p < limit && *p; p++ ) - { - FT_UInt glyph_index; - FT_Pos best_pos; /* same as points.y */ - FT_Int best_point; - FT_Vector* points; + while ( *p == ' ' ) + p++; +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif - FT_TRACE5(( " U+%lX...", *p )); + /* switch to characters that define flat values */ + if ( *p == '|' ) + { + fill = 0; + FT_TRACE5(( " [reference values]\n" )); + p++; + continue; + } - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, *p ); - if ( glyph_index == 0 ) - { - FT_TRACE5(( "unavailable\n" )); - continue; - } + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || glyph->outline.n_points <= 0 ) - { - FT_TRACE5(( "no outline\n" )); - continue; - } + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); + if ( glyph_index == 0 ) + { + FT_TRACE5(( " U+%04lX unavailable\n", ch )); + continue; + } - /* now compute min or max point indices and coordinates */ - points = glyph->outline.points; - best_point = -1; - best_pos = 0; /* make compiler happy */ + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + outline = face->glyph->outline; + if ( error || outline.n_points <= 2 ) + { + FT_TRACE5(( " U+%04lX contains no (usable) outlines\n", ch )); + continue; + } - { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; + /* now compute min or max point indices and coordinates */ + points = outline.points; + best_point = -1; + best_pos = 0; /* make compiler happy */ + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; - for ( nn = 0; - nn < glyph->outline.n_contours; - first = last + 1, nn++ ) - { - FT_Int pp; + + for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) + { + FT_Int pp; - last = glyph->outline.contours[nn]; + last = outline.contours[nn]; - /* Avoid single-point contours since they are never */ - /* rasterized. In some fonts, they correspond to mark */ - /* attachment points which are way outside of the glyph's */ - /* real outline. */ - if ( last <= first ) - continue; + /* Avoid single-point contours since they are never rasterized. */ + /* In some fonts, they correspond to mark attachment points */ + /* which are way outside of the glyph's real outline. */ + if ( last <= first ) + continue; - switch ( bb ) + if ( AF_CJK_IS_HORIZ_BLUE( bs ) ) + { + if ( AF_CJK_IS_RIGHT_BLUE( bs ) ) { - case AF_CJK_BLUE_TOP: for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_pos ) + if ( best_point < 0 || points[pp].x > best_pos ) { best_point = pp; - best_pos = points[pp].y; + best_pos = points[pp].x; } - break; - - case AF_CJK_BLUE_BOTTOM: + } + else + { for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_pos ) + if ( best_point < 0 || points[pp].x < best_pos ) { best_point = pp; - best_pos = points[pp].y; + best_pos = points[pp].x; } - break; - - case AF_CJK_BLUE_LEFT: + } + } + else + { + if ( AF_CJK_IS_TOP_BLUE( bs ) ) + { for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].x < best_pos ) + if ( best_point < 0 || points[pp].y > best_pos ) { best_point = pp; - best_pos = points[pp].x; + best_pos = points[pp].y; } - break; - - case AF_CJK_BLUE_RIGHT: + } + else + { for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].x > best_pos ) + if ( best_point < 0 || points[pp].y < best_pos ) { best_point = pp; - best_pos = points[pp].x; + best_pos = points[pp].y; } - break; - - default: - ; } } - FT_TRACE5(( "best_pos=%5ld\n", best_pos )); } - if ( fill ) - fills[num_fills++] = best_pos; - else - flats[num_flats++] = best_pos; + FT_TRACE5(( " U+%04lX: best_pos = %5ld\n", ch, best_pos )); } - } + + if ( fill ) + fills[num_fills++] = best_pos; + else + flats[num_flats++] = best_pos; + + } /* end while loop */ if ( num_flats == 0 && num_fills == 0 ) { @@ -436,34 +486,30 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - FT_TRACE5(( "empty\n" )); + FT_TRACE5(( " empty\n" )); continue; } - /* we have computed the contents of the `fill' and `flats' tables, */ - /* now determine the reference position of the blue -- */ - /* we simply take the median value after a simple sort */ - af_sort_pos( num_flats, flats ); + /* we have computed the contents of the `fill' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ af_sort_pos( num_fills, fills ); + af_sort_pos( num_flats, flats ); - if ( AF_CJK_BLUE_TOP == bb || AF_CJK_BLUE_BOTTOM == bb ) - axis = &metrics->axis[AF_DIMENSION_VERT]; - else - axis = &metrics->axis[AF_DIMENSION_HORZ]; - - blue = & axis->blues[axis->blue_count]; - blue_ref = & blue->ref.org; - blue_shoot = & blue->shoot.org; + blue = &axis->blues[axis->blue_count]; + blue_ref = &blue->ref.org; + blue_shoot = &blue->shoot.org; axis->blue_count++; + if ( num_flats == 0 ) { - *blue_ref = fills[num_fills / 2]; + *blue_ref = *blue_shoot = fills[num_fills / 2]; } else if ( num_fills == 0 ) { - *blue_ref = flats[num_flats / 2]; + *blue_ref = *blue_shoot = flats[num_flats / 2]; } else @@ -481,51 +527,71 @@ FT_Bool under_ref = FT_BOOL( shoot < ref ); - if ( ( AF_CJK_BLUE_TOP == bb || - AF_CJK_BLUE_RIGHT == bb ) ^ under_ref ) - *blue_shoot = *blue_ref = ( shoot + ref ) / 2; + /* AF_CJK_IS_TOP_BLUE covers `right' and `top' */ + if ( AF_CJK_IS_TOP_BLUE( bs ) ^ under_ref ) + { + *blue_ref = + *blue_shoot = ( shoot + ref ) / 2; + + FT_TRACE5(( " [reference smaller than overshoot," + " taking mean value]\n" )); + } } blue->flags = 0; - if ( AF_CJK_BLUE_TOP == bb ) - blue->flags |= AF_CJK_BLUE_IS_TOP; - else if ( AF_CJK_BLUE_RIGHT == bb ) - blue->flags |= AF_CJK_BLUE_IS_RIGHT; + if ( AF_CJK_IS_TOP_BLUE( bs ) ) + blue->flags |= AF_CJK_BLUE_TOP; - FT_TRACE5(( "-- cjk %s bluezone ref = %ld shoot = %ld\n", - cjk_blue_name[bb], *blue_ref, *blue_shoot )); - } + FT_TRACE5(( " -> reference = %ld\n" + " overshoot = %ld\n", + *blue_ref, *blue_shoot )); + + } /* end for loop */ + + af_shaper_buf_destroy( face, shaper_buf ); + + FT_TRACE5(( "\n" )); return; } /* Basically the Latin version with type AF_CJKMetrics for metrics. */ + FT_LOCAL_DEF( void ) af_cjk_metrics_check_digits( AF_CJKMetrics metrics, FT_Face face ) { - FT_UInt i; FT_Bool started = 0, same_width = 1; FT_Fixed advance, old_advance = 0; + void* shaper_buf; + + /* in all supported charmaps, digits have character codes 0x30-0x39 */ + const char digits[] = "0 1 2 3 4 5 6 7 8 9"; + const char* p; + - /* check whether all ASCII digits have the same advance width; */ - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) + p = digits; + shaper_buf = af_shaper_buf_create( face ); + + while ( *p ) { - FT_UInt glyph_index; + FT_ULong glyph_index; + unsigned int num_idx; - glyph_index = FT_Get_Char_Index( face, i ); - if ( glyph_index == 0 ) + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) continue; - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + &advance, + NULL ); + if ( !glyph_index ) continue; if ( started ) @@ -543,10 +609,14 @@ } } + af_shaper_buf_destroy( face, shaper_buf ); + metrics->root.digits_have_same_width = same_width; } + /* Initialize global metrics. */ + FT_LOCAL_DEF( FT_Error ) af_cjk_metrics_init( AF_CJKMetrics metrics, FT_Face face ) @@ -556,21 +626,21 @@ metrics->units_per_em = face->units_per_EM; - if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) - face->charmap = NULL; - else + if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) { af_cjk_metrics_init_widths( metrics, face ); - af_cjk_metrics_init_blues( metrics, face, af_cjk_hani_blue_chars ); + af_cjk_metrics_init_blues( metrics, face ); af_cjk_metrics_check_digits( metrics, face ); } FT_Set_Charmap( face, oldmap ); - return FT_Err_Ok; } + /* Adjust scaling value, then scale and shift widths */ + /* and blue zones (if applicable) for given dimension. */ + static void af_cjk_metrics_scale_dim( AF_CJKMetrics metrics, AF_Scaler scaler, @@ -582,8 +652,6 @@ FT_UInt nn; - axis = &metrics->axis[dim]; - if ( dim == AF_DIMENSION_HORZ ) { scale = scaler->x_scale; @@ -595,6 +663,8 @@ delta = scaler->y_delta; } + axis = &metrics->axis[dim]; + if ( axis->org_scale == scale && axis->org_delta == delta ) return; @@ -650,12 +720,13 @@ blue->shoot.fit = blue->ref.fit - delta2; - FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]: " - "ref: cur=%.2f fit=%.2f shoot: cur=%.2f fit=%.2f\n", - ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V', - nn, blue->ref.org, blue->shoot.org, - blue->ref.cur / 64.0, blue->ref.fit / 64.0, - blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); + FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]:\n" + " ref: cur=%.2f fit=%.2f\n" + " shoot: cur=%.2f fit=%.2f\n", + ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V', + nn, blue->ref.org, blue->shoot.org, + blue->ref.cur / 64.0, blue->ref.fit / 64.0, + blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); blue->flags |= AF_CJK_BLUE_ACTIVE; } @@ -663,10 +734,14 @@ } + /* Scale global values in both directions. */ + FT_LOCAL_DEF( void ) af_cjk_metrics_scale( AF_CJKMetrics metrics, AF_Scaler scaler ) { + /* we copy the whole structure since the x and y scaling values */ + /* are not modified, contrary to e.g. the `latin' auto-hinter */ metrics->root.scaler = *scaler; af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); @@ -674,6 +749,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_cjk_get_standard_widths( AF_CJKMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -682,6 +773,9 @@ /*************************************************************************/ /*************************************************************************/ + + /* Walk over all contours and compute its segments. */ + static FT_Error af_cjk_hints_compute_segments( AF_GlyphHints hints, AF_Dimension dim ) @@ -703,8 +797,8 @@ { AF_Point pt = seg->first; AF_Point last = seg->last; - AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); - AF_Flags f1; + FT_UInt f0 = pt->flags & AF_FLAG_CONTROL; + FT_UInt f1; seg->flags &= ~AF_EDGE_ROUND; @@ -712,7 +806,7 @@ for ( ; pt != last; f0 = f1 ) { pt = pt->next; - f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); + f1 = pt->flags & AF_FLAG_CONTROL; if ( !f0 && !f1 ) break; @@ -748,10 +842,6 @@ /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are for metrics hinting only */ - if ( seg1->first == seg1->last ) - continue; - if ( seg1->dir != major_dir ) continue; @@ -850,19 +940,19 @@ if ( link == seg2 ) { - seg->link = 0; + seg->link = NULL; seg->serif = link1; } else if ( link == link2 ) { - seg->link = 0; + seg->link = NULL; seg->serif = seg1; } } } else { - seg1->link = link1->link = 0; + seg1->link = link1->link = NULL; break; } @@ -876,15 +966,12 @@ if ( seg2 ) { - seg2->num_linked++; if ( seg2->link != seg1 ) { - seg1->link = 0; + seg1->link = NULL; if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 ) seg1->serif = seg2->link; - else - seg2->num_linked--; } } } @@ -938,7 +1025,7 @@ for ( seg = segments; seg < segment_limit; seg++ ) { - AF_Edge found = 0; + AF_Edge found = NULL; FT_Pos best = 0xFFFFU; FT_Int ee; @@ -1001,7 +1088,7 @@ /* insert a new edge in the list and */ /* sort according to the position */ error = af_axis_hints_new_edge( axis, seg->pos, - (AF_Direction)seg->dir, + (AF_Direction)seg->dir, 0, memory, &edge ); if ( error ) goto Exit; @@ -1011,10 +1098,11 @@ edge->first = seg; edge->last = seg; + edge->dir = seg->dir; edge->fpos = seg->pos; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + edge->opos = FT_MulFix( seg->pos, scale ); + edge->pos = edge->opos; seg->edge_next = seg; - edge->dir = seg->dir; } else { @@ -1026,25 +1114,26 @@ } } - /*********************************************************************/ - /* */ - /* Good, we now compute each edge's properties according to segments */ - /* found on its position. Basically, these are as follows. */ - /* */ - /* - edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straight or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /*********************************************************************/ - - /* first of all, set the `edge' field in each segment -- this is */ - /* required in order to compute edge links */ - /* */ - /* Note that removing this loop and setting the `edge' field of each */ - /* segment directly in the code above slows down execution speed for */ - /* some reasons on platforms like the Sun. */ + /******************************************************************/ + /* */ + /* Good, we now compute each edge's properties according to the */ + /* segments found on its position. Basically, these are */ + /* */ + /* - the edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /******************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + /* + * Note that removing this loop and setting the `edge' field of each + * segment directly in the code above slows down execution speed for + * some reasons on platforms like the Sun. + */ { AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; @@ -1144,7 +1233,7 @@ /* Example: the `c' in cour.pfa at size 13 */ if ( edge->serif && edge->link ) - edge->serif = 0; + edge->serif = NULL; } } @@ -1153,6 +1242,8 @@ } + /* Detect segments and edges for given dimension. */ + static FT_Error af_cjk_hints_detect_features( AF_GlyphHints hints, AF_Dimension dim ) @@ -1171,7 +1262,9 @@ } - FT_LOCAL_DEF( void ) + /* Compute all edges which lie within blue zones. */ + + static void af_cjk_hints_compute_blue_edges( AF_GlyphHints hints, AF_CJKMetrics metrics, AF_Dimension dim ) @@ -1218,10 +1311,10 @@ /* zone, check for left edges */ /* */ /* of course, that's for TrueType */ - is_top_right_blue = - FT_BOOL( ( ( blue->flags & AF_CJK_BLUE_IS_TOP ) != 0 ) || - ( ( blue->flags & AF_CJK_BLUE_IS_RIGHT ) != 0 ) ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + is_top_right_blue = + (FT_Byte)( ( blue->flags & AF_CJK_BLUE_TOP ) != 0 ); + is_major_dir = + FT_BOOL( edge->dir == axis->major_dir ); /* if it is a top zone, the edge must be against the major */ /* direction; if it is a bottom zone, it must be in the major */ @@ -1258,6 +1351,8 @@ } + /* Initalize hinting engine. */ + FT_LOCAL_DEF( FT_Error ) af_cjk_hints_init( AF_GlyphHints hints, AF_CJKMetrics metrics ) @@ -1266,7 +1361,7 @@ FT_UInt32 scaler_flags, other_flags; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* * correct x_scale and y_scale when needed, since they may have @@ -1280,7 +1375,7 @@ /* compute flags depending on render mode, etc. */ mode = metrics->root.scaler.render_mode; -#ifdef AF_CONFIG_OPTION_USE_WARPER +#if 0 /* AF_CONFIG_OPTION_USE_WARPER */ if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; #endif @@ -1313,10 +1408,16 @@ scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE; +#ifdef AF_CONFIG_OPTION_USE_WARPER + /* get (global) warper flag */ + if ( !metrics->root.globals->module->warping ) + scaler_flags |= AF_SCALER_FLAG_NO_WARPER; +#endif + hints->scaler_flags = scaler_flags; hints->other_flags = other_flags; - return 0; + return FT_Err_Ok; } @@ -1328,18 +1429,18 @@ /*************************************************************************/ /*************************************************************************/ - /* snap a given width in scaled coordinates to one of the */ - /* current standard widths */ + /* Snap a given width in scaled coordinates to one of the */ + /* current standard widths. */ static FT_Pos af_cjk_snap_width( AF_Width widths, - FT_Int count, + FT_UInt count, FT_Pos width ) { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; + FT_UInt n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; for ( n = 0; n < count; n++ ) @@ -1376,17 +1477,19 @@ } - /* compute the snapped width of a given stem */ + /* Compute the snapped width of a given stem. */ + /* There is a lot of voodoo in this function; changing the hard-coded */ + /* parameters influence the whole hinting process. */ static FT_Pos af_cjk_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) + FT_UInt base_flags, + FT_UInt stem_flags ) { - AF_CJKMetrics metrics = (AF_CJKMetrics) hints->metrics; - AF_CJKAxis axis = & metrics->axis[dim]; + AF_CJKMetrics metrics = (AF_CJKMetrics)hints->metrics; + AF_CJKAxis axis = &metrics->axis[dim]; FT_Pos dist = width; FT_Int sign = 0; FT_Bool vertical = FT_BOOL( dim == AF_DIMENSION_VERT ); @@ -1422,7 +1525,7 @@ } if ( dist < 54 ) - dist += ( 54 - dist ) / 2 ; + dist += ( 54 - dist ) / 2; else if ( dist < 3 * 64 ) { FT_Pos delta; @@ -1497,7 +1600,7 @@ } - /* align one stem edge relative to the previous stem edge */ + /* Align one stem edge relative to the previous stem edge. */ static void af_cjk_align_linked_edge( AF_GlyphHints hints, @@ -1507,16 +1610,24 @@ { FT_Pos dist = stem_edge->opos - base_edge->opos; - FT_Pos fitted_width = af_cjk_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); + FT_Pos fitted_width = af_cjk_compute_stem_width( hints, dim, dist, + base_edge->flags, + stem_edge->flags ); stem_edge->pos = base_edge->pos + fitted_width; + + FT_TRACE5(( " CJKLINK: edge %d @%d (opos=%.2f) linked to %.2f," + " dist was %.2f, now %.2f\n", + stem_edge - hints->axis[dim].edges, stem_edge->fpos, + stem_edge->opos / 64.0, stem_edge->pos / 64.0, + dist / 64.0, fitted_width / 64.0 )); } + /* Shift the coordinates of the `serif' edge by the same amount */ + /* as the corresponding `base' edge has been moved already. */ + static void af_cjk_align_serif_edge( AF_GlyphHints hints, AF_Edge base, @@ -1579,8 +1690,8 @@ org_len = edge2->opos - edge->opos; cur_len = af_cjk_compute_stem_width( hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + edge->flags, + edge2->flags ); org_center = ( edge->opos + edge2->opos ) / 2 + anchor; cur_pos1 = org_center - cur_len / 2; @@ -1670,6 +1781,8 @@ } + /* The main grid-fitting routine. */ + static void af_cjk_hint_edges( AF_GlyphHints hints, AF_Dimension dim ) @@ -1679,16 +1792,22 @@ AF_Edge edge_limit = edges + axis->num_edges; FT_PtrDist n_edges; AF_Edge edge; - AF_Edge anchor = 0; + AF_Edge anchor = NULL; FT_Pos delta = 0; FT_Int skipped = 0; FT_Bool has_last_stem = FALSE; FT_Pos last_stem_pos = 0; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_UInt num_actions = 0; +#endif + + + FT_TRACE5(( "cjk %s edge hinting (style `%s')\n", + dim == AF_DIMENSION_VERT ? "horizontal" : "vertical", + af_style_names[hints->metrics->style_class->style] )); /* we begin by aligning all stems relative to the blue zone */ - FT_TRACE5(( "==== cjk hinting %s edges =====\n", - dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); if ( AF_HINTS_DO_BLUES( hints ) ) { @@ -1719,10 +1838,14 @@ if ( !edge1 ) continue; - FT_TRACE5(( "CJKBLUE: edge %d @%d (opos=%.2f) snapped to (%.2f), " - "was (%.2f)\n", - edge1-edges, edge1->fpos, edge1->opos / 64.0, blue->fit / 64.0, - edge1->pos / 64.0 )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE5(( " CJKBLUE: edge %d @%d (opos=%.2f) snapped to %.2f," + " was %.2f\n", + edge1 - edges, edge1->fpos, edge1->opos / 64.0, + blue->fit / 64.0, edge1->pos / 64.0 )); + + num_actions++; +#endif edge1->pos = blue->fit; edge1->flags |= AF_EDGE_DONE; @@ -1731,6 +1854,10 @@ { af_cjk_align_linked_edge( hints, dim, edge1, edge2 ); edge2->flags |= AF_EDGE_DONE; + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif } if ( !anchor ) @@ -1772,6 +1899,7 @@ } /* now align the stem */ + /* this should not happen, but it's better to be safe */ if ( edge2->blue_edge ) { @@ -1779,6 +1907,11 @@ af_cjk_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif + continue; } @@ -1786,6 +1919,11 @@ { af_cjk_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif + /* We rarely reaches here it seems; * usually the two edges belonging * to one stem are marked as DONE together @@ -1953,7 +2091,7 @@ } if ( !skipped ) - return; + goto Exit; /* * now hint the remaining edges (serifs and single) in order @@ -1973,7 +2111,7 @@ } if ( !skipped ) - return; + goto Exit; for ( edge = edges; edge < edge_limit; edge++ ) { @@ -2011,6 +2149,16 @@ } } } + + Exit: + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !num_actions ) + FT_TRACE5(( " (none)\n" )); + FT_TRACE5(( "\n" )); +#endif + + return; } @@ -2104,8 +2252,11 @@ } + /* Apply the complete hinting algorithm to a CJK glyph. */ + FT_LOCAL_DEF( FT_Error ) - af_cjk_hints_apply( AF_GlyphHints hints, + af_cjk_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_CJKMetrics metrics ) { @@ -2113,6 +2264,7 @@ int dim; FT_UNUSED( metrics ); + FT_UNUSED( glyph_index ); error = af_glyph_hints_reload( hints, outline ); @@ -2120,7 +2272,13 @@ goto Exit; /* analyze glyph outline */ +#ifdef AF_CONFIG_OPTION_USE_WARPER + if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) || + AF_HINTS_DO_HORIZONTAL( hints ) ) +#else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) +#endif { error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ ); if ( error ) @@ -2146,8 +2304,9 @@ { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2169,12 +2328,6 @@ } } -#if 0 - af_glyph_hints_dump_points( hints ); - af_glyph_hints_dump_segments( hints ); - af_glyph_hints_dump_edges( hints ); -#endif - af_glyph_hints_save( hints, outline ); Exit: @@ -2191,84 +2344,43 @@ /*************************************************************************/ - /* this corresponds to Unicode 6.0 */ + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_cjk_writing_system_class, - static const AF_Script_UniRangeRec af_cjk_uniranges[] = - { - AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), /* Hangul Jamo */ - AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ - AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ - AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), /* Ideographic Description Characters */ - AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ - AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ - AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ - AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ - AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ - AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), /* Kanbun */ - AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ - AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ - AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ - AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */ - AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ - AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ - AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ - AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ - AF_UNIRANGE_REC( 0xA960UL, 0xA97FUL ), /* Hangul Jamo Extended-A */ - AF_UNIRANGE_REC( 0xAC00UL, 0xD7AFUL ), /* Hangul Syllables */ - AF_UNIRANGE_REC( 0xD7B0UL, 0xD7FFUL ), /* Hangul Jamo Extended-B */ - AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ - AF_UNIRANGE_REC( 0xFE10UL, 0xFE1FUL ), /* Vertical forms */ - AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ - AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ - AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ), /* Kana Supplement */ - AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ), /* Tai Xuan Hing Symbols */ - AF_UNIRANGE_REC( 0x1F200UL, 0x1F2FFUL ), /* Enclosed Ideographic Supplement */ - AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ - AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ), /* CJK Unified Ideographs Extension C */ - AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ), /* CJK Unified Ideographs Extension D */ - AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class, - AF_SCRIPT_CJK, - af_cjk_uniranges, - 0x7530, /* 田 */ + AF_WRITING_SYSTEM_CJK, sizeof ( AF_CJKMetricsRec ), - (AF_Script_InitMetricsFunc) af_cjk_metrics_init, - (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init, + (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths, - (AF_Script_InitHintsFunc) af_cjk_hints_init, - (AF_Script_ApplyHintsFunc) af_cjk_hints_apply + (AF_WritingSystem_InitHintsFunc) af_cjk_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_cjk_hints_apply ) + #else /* !AF_CONFIG_OPTION_CJK */ - static const AF_Script_UniRangeRec af_cjk_uniranges[] = - { - AF_UNIRANGE_REC( 0UL, 0UL ) - }; + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_cjk_writing_system_class, - AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class, - AF_SCRIPT_CJK, - af_cjk_uniranges, - 0, + AF_WRITING_SYSTEM_CJK, sizeof ( AF_CJKMetricsRec ), - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, + (AF_WritingSystem_ScaleMetricsFunc)NULL, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)NULL, - (AF_Script_InitHintsFunc) NULL, - (AF_Script_ApplyHintsFunc) NULL + (AF_WritingSystem_InitHintsFunc) NULL, + (AF_WritingSystem_ApplyHintsFunc) NULL ) + #endif /* !AF_CONFIG_OPTION_CJK */ diff --git a/drivers/freetype/src/autofit/afcjk.h b/drivers/freetype/src/autofit/afcjk.h index ab816f20b1..40d1184386 100644 --- a/drivers/freetype/src/autofit/afcjk.h +++ b/drivers/freetype/src/autofit/afcjk.h @@ -2,9 +2,9 @@ /* */ /* afcjk.h */ /* */ -/* Auto-fitter hinting routines for CJK script (specification). */ +/* Auto-fitter hinting routines for CJK writing system (specification). */ /* */ -/* Copyright 2006, 2007, 2011, 2012 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFCJK_H__ -#define __AFCJK_H__ +#ifndef AFCJK_H_ +#define AFCJK_H_ #include "afhints.h" #include "aflatin.h" @@ -26,41 +26,39 @@ FT_BEGIN_HEADER - /* the CJK-specific script class */ + /* the CJK-specific writing system */ - AF_DECLARE_SCRIPT_CLASS( af_cjk_script_class ) + AF_DECLARE_WRITING_SYSTEM_CLASS( af_cjk_writing_system_class ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ - /* CJK (global) metrics management */ /* * CJK glyphs tend to fill the square. So we have both vertical and * horizontal blue zones. But some glyphs have flat bounding strokes that * leave some space between neighbour glyphs. */ - enum - { - AF_CJK_BLUE_TOP, - AF_CJK_BLUE_BOTTOM, - AF_CJK_BLUE_LEFT, - AF_CJK_BLUE_RIGHT, - - AF_CJK_BLUE_MAX - }; +#define AF_CJK_IS_TOP_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_CJK_TOP ) +#define AF_CJK_IS_HORIZ_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_CJK_HORIZ ) +#define AF_CJK_IS_RIGHT_BLUE AF_CJK_IS_TOP_BLUE #define AF_CJK_MAX_WIDTHS 16 -#define AF_CJK_MAX_BLUES AF_CJK_BLUE_MAX - enum - { - AF_CJK_BLUE_ACTIVE = 1 << 0, - AF_CJK_BLUE_IS_TOP = 1 << 1, - AF_CJK_BLUE_IS_RIGHT = 1 << 2, - AF_CJK_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment */ - /* optimization */ - AF_CJK_BLUE_FLAG_MAX - }; +#define AF_CJK_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */ +#define AF_CJK_BLUE_TOP ( 1U << 1 ) /* result of AF_CJK_IS_TOP_BLUE */ +#define AF_CJK_BLUE_ADJUSTMENT ( 1U << 2 ) /* used for scale adjustment */ + /* optimization */ typedef struct AF_CJKBlueRec_ @@ -77,16 +75,16 @@ FT_BEGIN_HEADER FT_Fixed scale; FT_Pos delta; - FT_UInt width_count; - AF_WidthRec widths[AF_CJK_MAX_WIDTHS]; - FT_Pos edge_distance_threshold; - FT_Pos standard_width; - FT_Bool extra_light; + FT_UInt width_count; /* number of used widths */ + AF_WidthRec widths[AF_CJK_MAX_WIDTHS]; /* widths array */ + FT_Pos edge_distance_threshold; /* used for creating edges */ + FT_Pos standard_width; /* the default stem thickness */ + FT_Bool extra_light; /* is standard width very light? */ /* used for horizontal metrics too for CJK */ FT_Bool control_overshoot; FT_UInt blue_count; - AF_CJKBlueRec blues[AF_CJK_BLUE_MAX]; + AF_CJKBlueRec blues[AF_BLUE_STRINGSET_MAX]; FT_Fixed org_scale; FT_Pos org_delta; @@ -96,9 +94,9 @@ FT_BEGIN_HEADER typedef struct AF_CJKMetricsRec_ { - AF_ScriptMetricsRec root; - FT_UInt units_per_em; - AF_CJKAxisRec axis[AF_DIMENSION_MAX]; + AF_StyleMetricsRec root; + FT_UInt units_per_em; + AF_CJKAxisRec axis[AF_DIMENSION_MAX]; } AF_CJKMetricsRec, *AF_CJKMetrics; @@ -117,7 +115,8 @@ FT_BEGIN_HEADER AF_CJKMetrics metrics ); FT_LOCAL( FT_Error ) - af_cjk_hints_apply( AF_GlyphHints hints, + af_cjk_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_CJKMetrics metrics ); @@ -136,7 +135,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFCJK_H__ */ +#endif /* AFCJK_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afcover.h b/drivers/freetype/src/autofit/afcover.h new file mode 100644 index 0000000000..1c39a707ef --- /dev/null +++ b/drivers/freetype/src/autofit/afcover.h @@ -0,0 +1,105 @@ +/***************************************************************************/ +/* */ +/* afcover.h */ +/* */ +/* Auto-fitter coverages (specification only). */ +/* */ +/* Copyright 2013-2016 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. */ +/* */ +/***************************************************************************/ + + + /* This header file can be included multiple times. */ + /* Define `COVERAGE' as needed. */ + + + /* Add new coverages here. The first and second arguments are the */ + /* coverage name in lowercase and uppercase, respectively, followed */ + /* by a description string. The last four arguments are the four */ + /* characters defining the corresponding OpenType feature. */ + +#if 0 + /* XXX: It's not possible to define blue zone characters in advance. */ + COVERAGE( alternative_fractions, ALTERNATIVE_FRACTIONS, + "alternative fractions", + 'a', 'f', 'r', 'c' ) +#endif + + COVERAGE( petite_capitals_from_capitals, PETITE_CAPITALS_FROM_CAPITALS, + "petite capitals from capitals", + 'c', '2', 'c', 'p' ) + + COVERAGE( small_capitals_from_capitals, SMALL_CAPITALS_FROM_CAPITALS, + "small capitals from capitals", + 'c', '2', 's', 'c' ) + +#if 0 + /* XXX: Only digits are in this coverage, however, both normal style */ + /* and oldstyle representation forms are possible. */ + COVERAGE( denominators, DENOMINATORS, + "denominators", + 'd', 'n', 'o', 'm' ) +#endif + +#if 0 + /* XXX: It's not possible to define blue zone characters in advance. */ + COVERAGE( fractions, FRACTIONS, + "fractions", + 'f', 'r', 'a', 'c' ) +#endif + +#if 0 + /* XXX: Only digits are in this coverage, however, both normal style */ + /* and oldstyle representation forms are possible. */ + COVERAGE( numerators, NUMERATORS, + "numerators", + 'n', 'u', 'm', 'r' ) +#endif + + COVERAGE( ordinals, ORDINALS, + "ordinals", + 'o', 'r', 'd', 'n' ) + + COVERAGE( petite_capitals, PETITE_CAPITALS, + "petite capitals", + 'p', 'c', 'a', 'p' ) + + COVERAGE( ruby, RUBY, + "ruby", + 'r', 'u', 'b', 'y' ) + + COVERAGE( scientific_inferiors, SCIENTIFIC_INFERIORS, + "scientific inferiors", + 's', 'i', 'n', 'f' ) + + COVERAGE( small_capitals, SMALL_CAPITALS, + "small capitals", + 's', 'm', 'c', 'p' ) + + COVERAGE( subscript, SUBSCRIPT, + "subscript", + 's', 'u', 'b', 's' ) + + COVERAGE( superscript, SUPERSCRIPT, + "superscript", + 's', 'u', 'p', 's' ) + + COVERAGE( titling, TITLING, + "titling", + 't', 'i', 't', 'l' ) + +#if 0 + /* to be always excluded */ + COVERAGE(nalt, 'n', 'a', 'l', 't'); /* Alternate Annotation Forms (?) */ + COVERAGE(ornm, 'o', 'r', 'n', 'm'); /* Ornaments (?) */ +#endif + + +/* END */ diff --git a/drivers/freetype/src/autofit/afdummy.c b/drivers/freetype/src/autofit/afdummy.c index 22944559da..f3960c85fd 100644 --- a/drivers/freetype/src/autofit/afdummy.c +++ b/drivers/freetype/src/autofit/afdummy.c @@ -5,7 +5,7 @@ /* Auto-fitter dummy routines to be used if no hinting should be */ /* performed (body). */ /* */ -/* Copyright 2003-2005, 2011, 2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,39 +23,52 @@ static FT_Error - af_dummy_hints_init( AF_GlyphHints hints, - AF_ScriptMetrics metrics ) + af_dummy_hints_init( AF_GlyphHints hints, + AF_StyleMetrics metrics ) { - af_glyph_hints_rescale( hints, - metrics ); + af_glyph_hints_rescale( hints, metrics ); + + hints->x_scale = metrics->scaler.x_scale; + hints->y_scale = metrics->scaler.y_scale; + hints->x_delta = metrics->scaler.x_delta; + hints->y_delta = metrics->scaler.y_delta; + return FT_Err_Ok; } static FT_Error - af_dummy_hints_apply( AF_GlyphHints hints, + af_dummy_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline ) { - FT_UNUSED( hints ); - FT_UNUSED( outline ); + FT_Error error; - return FT_Err_Ok; + FT_UNUSED( glyph_index ); + + + error = af_glyph_hints_reload( hints, outline ); + if ( !error ) + af_glyph_hints_save( hints, outline ); + + return error; } - AF_DEFINE_SCRIPT_CLASS( af_dummy_script_class, - AF_SCRIPT_DUMMY, - NULL, - 0, + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_dummy_writing_system_class, + + AF_WRITING_SYSTEM_DUMMY, - sizeof ( AF_ScriptMetricsRec ), + sizeof ( AF_StyleMetricsRec ), - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, + (AF_WritingSystem_ScaleMetricsFunc)NULL, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)NULL, - (AF_Script_InitHintsFunc) af_dummy_hints_init, - (AF_Script_ApplyHintsFunc) af_dummy_hints_apply + (AF_WritingSystem_InitHintsFunc) af_dummy_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_dummy_hints_apply ) diff --git a/drivers/freetype/src/autofit/afdummy.h b/drivers/freetype/src/autofit/afdummy.h index 95d8f8cf19..7e58d1a9a5 100644 --- a/drivers/freetype/src/autofit/afdummy.h +++ b/drivers/freetype/src/autofit/afdummy.h @@ -5,7 +5,7 @@ /* Auto-fitter dummy routines to be used if no hinting should be */ /* performed (specification). */ /* */ -/* Copyright 2003-2005, 2011 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,26 +17,24 @@ /***************************************************************************/ -#ifndef __AFDUMMY_H__ -#define __AFDUMMY_H__ +#ifndef AFDUMMY_H_ +#define AFDUMMY_H_ #include "aftypes.h" FT_BEGIN_HEADER - /* A dummy script metrics class used when no hinting should - * be performed. This is the default for non-latin glyphs! - */ + /* A dummy writing system used when no hinting should be performed. */ - AF_DECLARE_SCRIPT_CLASS( af_dummy_script_class ) + AF_DECLARE_WRITING_SYSTEM_CLASS( af_dummy_writing_system_class ) /* */ FT_END_HEADER -#endif /* __AFDUMMY_H__ */ +#endif /* AFDUMMY_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/aferrors.h b/drivers/freetype/src/autofit/aferrors.h index 50e1a22dd5..53c01f64dd 100644 --- a/drivers/freetype/src/autofit/aferrors.h +++ b/drivers/freetype/src/autofit/aferrors.h @@ -4,7 +4,7 @@ /* */ /* Autofitter error codes (specification only). */ /* */ -/* Copyright 2005, 2012 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __AFERRORS_H__ -#define __AFERRORS_H__ +#ifndef AFERRORS_H_ +#define AFERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX AF_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __AFERRORS_H__ */ +#endif /* AFERRORS_H_ */ + /* END */ diff --git a/drivers/freetype/src/autofit/afglobal.c b/drivers/freetype/src/autofit/afglobal.c index 3e41465756..ac6dcafc0f 100644 --- a/drivers/freetype/src/autofit/afglobal.c +++ b/drivers/freetype/src/autofit/afglobal.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter routines to compute global hinting values (body). */ /* */ -/* Copyright 2003-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,109 +17,247 @@ #include "afglobal.h" -#include "afdummy.h" -#include "aflatin.h" -#include "afcjk.h" -#include "afindic.h" -#include "afpic.h" +#include "afranges.h" +#include "afshaper.h" +#include FT_INTERNAL_DEBUG_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_afglobal + + + /* get writing system specific header files */ +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) /* empty */ +#include "afwrtsys.h" #include "aferrors.h" +#include "afpic.h" + + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + AF_DEFINE_SCRIPT_CLASS( \ + af_ ## s ## _script_class, \ + AF_SCRIPT_ ## S, \ + af_ ## s ## _uniranges, \ + af_ ## s ## _nonbase_uniranges, \ + AF_ ## H, \ + ss ) + +#include "afscript.h" + + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) \ + AF_DEFINE_STYLE_CLASS( \ + af_ ## s ## _style_class, \ + AF_STYLE_ ## S, \ + ws, \ + sc, \ + ss, \ + c ) + +#include "afstyles.h" -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.h" -#endif #ifndef FT_CONFIG_OPTION_PIC - /* when updating this table, don't forget to update */ - /* AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) \ + &af_ ## ws ## _writing_system_class, - /* populate this list when you add new scripts */ - static AF_ScriptClass const af_script_classes[] = + FT_LOCAL_ARRAY_DEF( AF_WritingSystemClass ) + af_writing_system_classes[] = { - &af_dummy_script_class, -#ifdef FT_OPTION_AUTOFIT2 - &af_latin2_script_class, -#endif - &af_latin_script_class, - &af_cjk_script_class, - &af_indic_script_class, + +#include "afwrtsys.h" + + NULL /* do not remove */ + }; + + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + &af_ ## s ## _script_class, + + FT_LOCAL_ARRAY_DEF( AF_ScriptClass ) + af_script_classes[] = + { + +#include "afscript.h" + + NULL /* do not remove */ + }; + + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) \ + &af_ ## s ## _style_class, + + FT_LOCAL_ARRAY_DEF( AF_StyleClass ) + af_style_classes[] = + { + +#include "afstyles.h" + NULL /* do not remove */ }; #endif /* !FT_CONFIG_OPTION_PIC */ - /* Compute the script index of each glyph within a given face. */ +#ifdef FT_DEBUG_LEVEL_TRACE + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) #s, + + FT_LOCAL_ARRAY_DEF( char* ) + af_style_names[] = + { + +#include "afstyles.h" + + }; + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + /* Compute the style index of each glyph within a given face. */ static FT_Error - af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) + af_face_globals_compute_style_coverage( AF_FaceGlobals globals ) { FT_Error error; FT_Face face = globals->face; FT_CharMap old_charmap = face->charmap; - FT_Byte* gscripts = globals->glyph_scripts; + FT_UShort* gstyles = globals->glyph_styles; FT_UInt ss; FT_UInt i; + FT_UInt dflt = ~0U; /* a non-valid value */ - /* the value AF_SCRIPT_NONE means `uncovered glyph' */ - FT_MEM_SET( globals->glyph_scripts, - AF_SCRIPT_NONE, - globals->glyph_count ); + /* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */ + for ( i = 0; i < (FT_UInt)globals->glyph_count; i++ ) + gstyles[i] = AF_STYLE_UNASSIGNED; error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); if ( error ) { - /* - * Ignore this error; we simply use the fallback script. - * XXX: Shouldn't we rather disable hinting? - */ + /* + * Ignore this error; we simply use the fallback style. + * XXX: Shouldn't we rather disable hinting? + */ error = FT_Err_Ok; goto Exit; } - /* scan each script in a Unicode charmap */ - for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) + /* scan each style in a Unicode charmap */ + for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) { - AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; + AF_StyleClass style_class = + AF_STYLE_CLASSES_GET[ss]; + AF_ScriptClass script_class = + AF_SCRIPT_CLASSES_GET[style_class->script]; AF_Script_UniRange range; - if ( clazz->script_uni_ranges == NULL ) + if ( script_class->script_uni_ranges == NULL ) continue; /* * Scan all Unicode points in the range and set the corresponding - * glyph script index. + * glyph style index. */ - for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) + if ( style_class->coverage == AF_COVERAGE_DEFAULT ) { - FT_ULong charcode = range->first; - FT_UInt gindex; + if ( (FT_UInt)style_class->script == + globals->module->default_script ) + dflt = ss; + for ( range = script_class->script_uni_ranges; + range->first != 0; + range++ ) + { + FT_ULong charcode = range->first; + FT_UInt gindex; + + + gindex = FT_Get_Char_Index( face, charcode ); - gindex = FT_Get_Char_Index( face, charcode ); + if ( gindex != 0 && + gindex < (FT_ULong)globals->glyph_count && + ( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED ) + gstyles[gindex] = (FT_UShort)ss; - if ( gindex != 0 && - gindex < (FT_ULong)globals->glyph_count && - gscripts[gindex] == AF_SCRIPT_NONE ) - gscripts[gindex] = (FT_Byte)ss; + for (;;) + { + charcode = FT_Get_Next_Char( face, charcode, &gindex ); + + if ( gindex == 0 || charcode > range->last ) + break; + + if ( gindex < (FT_ULong)globals->glyph_count && + ( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED ) + gstyles[gindex] = (FT_UShort)ss; + } + } - for (;;) + /* do the same for the script's non-base characters */ + for ( range = script_class->script_uni_nonbase_ranges; + range->first != 0; + range++ ) { - charcode = FT_Get_Next_Char( face, charcode, &gindex ); + FT_ULong charcode = range->first; + FT_UInt gindex; - if ( gindex == 0 || charcode > range->last ) - break; - if ( gindex < (FT_ULong)globals->glyph_count && - gscripts[gindex] == AF_SCRIPT_NONE ) - gscripts[gindex] = (FT_Byte)ss; + gindex = FT_Get_Char_Index( face, charcode ); + + if ( gindex != 0 && + gindex < (FT_ULong)globals->glyph_count && + ( gstyles[gindex] & AF_STYLE_MASK ) == (FT_UShort)ss ) + gstyles[gindex] |= AF_NONBASE; + + for (;;) + { + charcode = FT_Get_Next_Char( face, charcode, &gindex ); + + if ( gindex == 0 || charcode > range->last ) + break; + + if ( gindex < (FT_ULong)globals->glyph_count && + ( gstyles[gindex] & AF_STYLE_MASK ) == (FT_UShort)ss ) + gstyles[gindex] |= AF_NONBASE; + } } } + else + { + /* get glyphs not directly addressable by cmap */ + af_shaper_get_coverage( globals, style_class, gstyles, 0 ); + } + } + + /* handle the remaining default OpenType features ... */ + for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + { + AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + + + if ( style_class->coverage == AF_COVERAGE_DEFAULT ) + af_shaper_get_coverage( globals, style_class, gstyles, 0 ); } + /* ... and finally the default OpenType features of the default script */ + af_shaper_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles, 1 ); + /* mark ASCII digits */ for ( i = 0x30; i <= 0x39; i++ ) { @@ -127,29 +265,68 @@ if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) - gscripts[gindex] |= AF_DIGIT; + gstyles[gindex] |= AF_DIGIT; } Exit: /* - * By default, all uncovered glyphs are set to the fallback script. + * By default, all uncovered glyphs are set to the fallback style. * XXX: Shouldn't we disable hinting or do something similar? */ - if ( globals->module->fallback_script != AF_SCRIPT_NONE ) + if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED ) { FT_Long nn; for ( nn = 0; nn < globals->glyph_count; nn++ ) { - if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_NONE ) + if ( ( gstyles[nn] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED ) + { + gstyles[nn] &= ~AF_STYLE_MASK; + gstyles[nn] |= globals->module->fallback_style; + } + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + + FT_TRACE4(( "\n" + "style coverage\n" + "==============\n" + "\n" )); + + for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + { + AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + FT_UInt count = 0; + FT_Long idx; + + + FT_TRACE4(( "%s:\n", af_style_names[style_class->style] )); + + for ( idx = 0; idx < globals->glyph_count; idx++ ) + { + if ( ( gstyles[idx] & AF_STYLE_MASK ) == style_class->style ) { - gscripts[nn] &= ~AF_SCRIPT_NONE; - gscripts[nn] |= globals->module->fallback_script; + if ( !( count % 10 ) ) + FT_TRACE4(( " " )); + + FT_TRACE4(( " %d", idx )); + count++; + + if ( !( count % 10 ) ) + FT_TRACE4(( "\n" )); } } + + if ( !count ) + FT_TRACE4(( " (none)\n" )); + if ( count % 10 ) + FT_TRACE4(( "\n" )); } +#endif /* FT_DEBUG_LEVEL_TRACE */ + FT_Set_Charmap( face, old_charmap ); return error; } @@ -167,23 +344,38 @@ memory = face->memory; - if ( FT_ALLOC( globals, sizeof ( *globals ) + - face->num_glyphs * sizeof ( FT_Byte ) ) ) + /* we allocate an AF_FaceGlobals structure together */ + /* with the glyph_styles array */ + if ( FT_ALLOC( globals, + sizeof ( *globals ) + + (FT_ULong)face->num_glyphs * sizeof ( FT_UShort ) ) ) goto Exit; - globals->face = face; - globals->glyph_count = face->num_glyphs; - globals->glyph_scripts = (FT_Byte*)( globals + 1 ); - globals->module = module; + globals->face = face; + globals->glyph_count = face->num_glyphs; + /* right after the globals structure come the glyph styles */ + globals->glyph_styles = (FT_UShort*)( globals + 1 ); + globals->module = module; + globals->stem_darkening_for_ppem = 0; + globals->darken_x = 0; + globals->darken_y = 0; + globals->standard_vertical_width = 0; + globals->standard_horizontal_width = 0; + globals->scale_down_factor = 0; + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + globals->hb_font = hb_ft_font_create( face, NULL ); + globals->hb_buf = hb_buffer_create(); +#endif - error = af_face_globals_compute_script_coverage( globals ); + error = af_face_globals_compute_style_coverage( globals ); if ( error ) { af_face_globals_free( globals ); globals = NULL; } - - globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; + else + globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; Exit: *aglobals = globals; @@ -200,25 +392,41 @@ FT_UInt nn; - for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ ) + for ( nn = 0; nn < AF_STYLE_MAX; nn++ ) { if ( globals->metrics[nn] ) { - AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[nn]; - + AF_StyleClass style_class = + AF_STYLE_CLASSES_GET[nn]; + AF_WritingSystemClass writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; - FT_ASSERT( globals->metrics[nn]->clazz == clazz ); - if ( clazz->script_metrics_done ) - clazz->script_metrics_done( globals->metrics[nn] ); + if ( writing_system_class->style_metrics_done ) + writing_system_class->style_metrics_done( globals->metrics[nn] ); FT_FREE( globals->metrics[nn] ); } } - globals->glyph_count = 0; - globals->glyph_scripts = NULL; /* no need to free this one! */ - globals->face = NULL; +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + hb_font_destroy( globals->hb_font ); + globals->hb_font = NULL; + + hb_buffer_destroy( globals->hb_buf ); + globals->hb_buf = NULL; +#endif + + globals->glyph_count = 0; + globals->stem_darkening_for_ppem = 0; + globals->darken_x = 0; + globals->darken_y = 0; + globals->standard_vertical_width = 0; + globals->standard_horizontal_width = 0; + globals->scale_down_factor = 0; + /* no need to free this one! */ + globals->glyph_styles = NULL; + globals->face = NULL; FT_FREE( globals ); } @@ -226,18 +434,18 @@ FT_LOCAL_DEF( FT_Error ) - af_face_globals_get_metrics( AF_FaceGlobals globals, - FT_UInt gindex, - FT_UInt options, - AF_ScriptMetrics *ametrics ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + FT_UInt options, + AF_StyleMetrics *ametrics ) { - AF_ScriptMetrics metrics = NULL; - FT_UInt gidx; - AF_ScriptClass clazz; - FT_UInt script = options & 15; - const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / - sizeof ( AF_SCRIPT_CLASSES_GET[0] ); - FT_Error error = FT_Err_Ok; + AF_StyleMetrics metrics = NULL; + + AF_Style style = (AF_Style)options; + AF_WritingSystemClass writing_system_class; + AF_StyleClass style_class; + + FT_Error error = FT_Err_Ok; if ( gindex >= (FT_ULong)globals->glyph_count ) @@ -246,41 +454,44 @@ goto Exit; } - gidx = script; - if ( gidx == 0 || gidx + 1 >= script_max ) - gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_NONE; + /* if we have a forced style (via `options'), use it, */ + /* otherwise look into `glyph_styles' array */ + if ( style == AF_STYLE_NONE_DFLT || style + 1 >= AF_STYLE_MAX ) + style = (AF_Style)( globals->glyph_styles[gindex] & + AF_STYLE_UNASSIGNED ); - clazz = AF_SCRIPT_CLASSES_GET[gidx]; - if ( script == 0 ) - script = clazz->script; + style_class = AF_STYLE_CLASSES_GET[style]; + writing_system_class = AF_WRITING_SYSTEM_CLASSES_GET + [style_class->writing_system]; - metrics = globals->metrics[clazz->script]; + metrics = globals->metrics[style]; if ( metrics == NULL ) { /* create the global metrics object if necessary */ FT_Memory memory = globals->face->memory; - if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) + if ( FT_ALLOC( metrics, writing_system_class->style_metrics_size ) ) goto Exit; - metrics->clazz = clazz; - metrics->globals = globals; + metrics->style_class = style_class; + metrics->globals = globals; - if ( clazz->script_metrics_init ) + if ( writing_system_class->style_metrics_init ) { - error = clazz->script_metrics_init( metrics, globals->face ); + error = writing_system_class->style_metrics_init( metrics, + globals->face ); if ( error ) { - if ( clazz->script_metrics_done ) - clazz->script_metrics_done( metrics ); + if ( writing_system_class->style_metrics_done ) + writing_system_class->style_metrics_done( metrics ); FT_FREE( metrics ); goto Exit; } } - globals->metrics[clazz->script] = metrics; + globals->metrics[style] = metrics; } Exit: @@ -295,7 +506,7 @@ FT_UInt gindex ) { if ( gindex < (FT_ULong)globals->glyph_count ) - return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); + return (FT_Bool)( globals->glyph_styles[gindex] & AF_DIGIT ); return (FT_Bool)0; } diff --git a/drivers/freetype/src/autofit/afglobal.h b/drivers/freetype/src/autofit/afglobal.h index 2e24900822..ce6b9e8f26 100644 --- a/drivers/freetype/src/autofit/afglobal.h +++ b/drivers/freetype/src/autofit/afglobal.h @@ -5,7 +5,7 @@ /* Auto-fitter routines to compute global hinting values */ /* (specification). */ /* */ -/* Copyright 2003-2005, 2007, 2009, 2011-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,28 +17,71 @@ /***************************************************************************/ -#ifndef __AFGLOBAL_H__ -#define __AFGLOBAL_H__ +#ifndef AFGLOBAL_H_ +#define AFGLOBAL_H_ #include "aftypes.h" #include "afmodule.h" +#include "afshaper.h" FT_BEGIN_HEADER + FT_LOCAL_ARRAY( AF_WritingSystemClass ) + af_writing_system_classes[]; + + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + AF_DECLARE_SCRIPT_CLASS( af_ ## s ## _script_class ) + +#include "afscript.h" + + FT_LOCAL_ARRAY( AF_ScriptClass ) + af_script_classes[]; + + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) \ + AF_DECLARE_STYLE_CLASS( af_ ## s ## _style_class ) + +#include "afstyles.h" + + FT_LOCAL_ARRAY( AF_StyleClass ) + af_style_classes[]; + + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_LOCAL_ARRAY( char* ) + af_style_names[]; +#endif + + /* * Default values and flags for both autofitter globals (found in * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec). */ - /* index of fallback script in `af_script_classes' */ -#define AF_SCRIPT_FALLBACK 2 - /* a bit mask indicating an uncovered glyph */ -#define AF_SCRIPT_NONE 0x7F - /* if this flag is set, we have an ASCII digit */ -#define AF_DIGIT 0x80 + /* index of fallback style in `af_style_classes' */ +#ifdef AF_CONFIG_OPTION_CJK +#define AF_STYLE_FALLBACK AF_STYLE_HANI_DFLT +#else +#define AF_STYLE_FALLBACK AF_STYLE_NONE_DFLT +#endif + /* default script for OpenType; ignored if HarfBuzz isn't used */ +#define AF_SCRIPT_DEFAULT AF_SCRIPT_LATN + + /* a bit mask for AF_DIGIT and AF_NONBASE */ +#define AF_STYLE_MASK 0x3FFF + /* an uncovered glyph */ +#define AF_STYLE_UNASSIGNED AF_STYLE_MASK + + /* if this flag is set, we have an ASCII digit */ +#define AF_DIGIT 0x8000U + /* if this flag is set, we have a non-base character */ +#define AF_NONBASE 0x4000U /* `increase-x-height' property */ #define AF_PROP_INCREASE_X_HEIGHT_MIN 6 @@ -55,29 +98,50 @@ FT_BEGIN_HEADER /* - * Note that glyph_scripts[] is used to map each glyph into - * an index into the `af_script_classes' array. + * Note that glyph_styles[] maps each glyph to an index into the + * `af_style_classes' array. * */ typedef struct AF_FaceGlobalsRec_ { - FT_Face face; - FT_Long glyph_count; /* same as face->num_glyphs */ - FT_Byte* glyph_scripts; + FT_Face face; + FT_Long glyph_count; /* same as face->num_glyphs */ + FT_UShort* glyph_styles; - /* per-face auto-hinter properties */ - FT_UInt increase_x_height; - - AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + hb_font_t* hb_font; + hb_buffer_t* hb_buf; /* for feature comparison */ +#endif - AF_Module module; /* to access global properties */ + /* per-face auto-hinter properties */ + FT_UInt increase_x_height; + + AF_StyleMetrics metrics[AF_STYLE_MAX]; + + /* Compute darkening amount once per size. Use this to check whether */ + /* darken_{x,y} needs to be recomputed. */ + FT_UShort stem_darkening_for_ppem; + /* Copy from e.g. AF_LatinMetrics.axis[AF_DIMENSION_HORZ] */ + /* to compute the darkening amount. */ + FT_Pos standard_vertical_width; + /* Copy from e.g. AF_LatinMetrics.axis[AF_DIMENSION_VERT] */ + /* to compute the darkening amount. */ + FT_Pos standard_horizontal_width; + /* The actual amount to darken a glyph along the X axis. */ + FT_Pos darken_x; + /* The actual amount to darken a glyph along the Y axis. */ + FT_Pos darken_y; + /* Amount to scale down by to keep emboldened points */ + /* on the Y-axis in pre-computed blue zones. */ + FT_Fixed scale_down_factor; + AF_Module module; /* to access global properties */ } AF_FaceGlobalsRec; /* * model the global hints data for a given face, decomposed into - * script-specific items + * style-specific items */ FT_LOCAL( FT_Error ) @@ -86,10 +150,10 @@ FT_BEGIN_HEADER AF_Module module ); FT_LOCAL( FT_Error ) - af_face_globals_get_metrics( AF_FaceGlobals globals, - FT_UInt gindex, - FT_UInt options, - AF_ScriptMetrics *ametrics ); + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + FT_UInt options, + AF_StyleMetrics *ametrics ); FT_LOCAL( void ) af_face_globals_free( AF_FaceGlobals globals ); @@ -103,7 +167,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFGLOBAL_H__ */ +#endif /* AFGLOBAL_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afhints.c b/drivers/freetype/src/autofit/afhints.c index e8defaa88d..6c3d032d1c 100644 --- a/drivers/freetype/src/autofit/afhints.c +++ b/drivers/freetype/src/autofit/afhints.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (body). */ /* */ -/* Copyright 2003-2007, 2009-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -43,7 +43,15 @@ AF_Segment segment = NULL; - if ( axis->num_segments >= axis->max_segments ) + if ( axis->num_segments < AF_SEGMENTS_EMBEDDED ) + { + if ( axis->segments == NULL ) + { + axis->segments = axis->embedded.segments; + axis->max_segments = AF_SEGMENTS_EMBEDDED; + } + } + else if ( axis->num_segments >= axis->max_segments ) { FT_Int old_max = axis->max_segments; FT_Int new_max = old_max; @@ -60,8 +68,18 @@ if ( new_max < old_max || new_max > big_max ) new_max = big_max; - if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) - goto Exit; + if ( axis->segments == axis->embedded.segments ) + { + if ( FT_NEW_ARRAY( axis->segments, new_max ) ) + goto Exit; + ft_memcpy( axis->segments, axis->embedded.segments, + sizeof ( axis->embedded.segments ) ); + } + else + { + if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) + goto Exit; + } axis->max_segments = new_max; } @@ -74,12 +92,14 @@ } - /* Get new edge for given axis, direction, and position. */ + /* Get new edge for given axis, direction, and position, */ + /* without initializing the edge itself. */ FT_LOCAL( FT_Error ) af_axis_hints_new_edge( AF_AxisHints axis, FT_Int fpos, AF_Direction dir, + FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *anedge ) { @@ -88,7 +108,15 @@ AF_Edge edges; - if ( axis->num_edges >= axis->max_edges ) + if ( axis->num_edges < AF_EDGES_EMBEDDED ) + { + if ( axis->edges == NULL ) + { + axis->edges = axis->embedded.edges; + axis->max_edges = AF_EDGES_EMBEDDED; + } + } + else if ( axis->num_edges >= axis->max_edges ) { FT_Int old_max = axis->max_edges; FT_Int new_max = old_max; @@ -105,8 +133,18 @@ if ( new_max < old_max || new_max > big_max ) new_max = big_max; - if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) - goto Exit; + if ( axis->edges == axis->embedded.edges ) + { + if ( FT_NEW_ARRAY( axis->edges, new_max ) ) + goto Exit; + ft_memcpy( axis->edges, axis->embedded.edges, + sizeof ( axis->embedded.edges ) ); + } + else + { + if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) + goto Exit; + } axis->max_edges = new_max; } @@ -116,7 +154,8 @@ while ( edge > edges ) { - if ( edge[-1].fpos < fpos ) + if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos ) + : ( edge[-1].fpos < fpos ) ) break; /* we want the edge with same position and minor direction */ @@ -130,10 +169,6 @@ axis->num_edges++; - FT_ZERO( edge ); - edge->fpos = (FT_Short)fpos; - edge->dir = (FT_Char)dir; - Exit: *anedge = edge; return error; @@ -144,6 +179,17 @@ #include FT_CONFIG_STANDARD_LIBRARY_H + /* The dump functions are used in the `ftgrid' demo program, too. */ +#define AF_DUMP( varformat ) \ + do \ + { \ + if ( to_stdout ) \ + printf varformat; \ + else \ + FT_TRACE7( varformat ); \ + } while ( 0 ) + + static const char* af_dir_str( AF_Direction dir ) { @@ -172,41 +218,146 @@ } -#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 ) +#define AF_INDEX_NUM( ptr, base ) (int)( (ptr) ? ( (ptr) - (base) ) : -1 ) + + + static char* + af_print_idx( char* p, + int idx ) + { + if ( idx == -1 ) + { + p[0] = '-'; + p[1] = '-'; + p[2] = '\0'; + } + else + ft_sprintf( p, "%d", idx ); + + return p; + } + + + static int + af_get_segment_index( AF_GlyphHints hints, + int point_idx, + int dimension ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Point point = hints->points + point_idx; + AF_Segment segments = axis->segments; + AF_Segment limit = segments + axis->num_segments; + AF_Segment segment; + + + for ( segment = segments; segment < limit; segment++ ) + { + if ( segment->first <= segment->last ) + { + if ( point >= segment->first && point <= segment->last ) + break; + } + else + { + AF_Point p = segment->first; + + + for (;;) + { + if ( point == p ) + goto Exit; + + if ( p == segment->last ) + break; + + p = p->next; + } + } + } + + Exit: + if ( segment == limit ) + return -1; + + return (int)( segment - segments ); + } + + + static int + af_get_edge_index( AF_GlyphHints hints, + int segment_idx, + int dimension ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Edge edges = axis->edges; + AF_Segment segment = axis->segments + segment_idx; + + + return segment_idx == -1 ? -1 : AF_INDEX_NUM( segment->edge, edges ); + } #ifdef __cplusplus extern "C" { #endif void - af_glyph_hints_dump_points( AF_GlyphHints hints ) + af_glyph_hints_dump_points( AF_GlyphHints hints, + FT_Bool to_stdout ) { - AF_Point points = hints->points; - AF_Point limit = points + hints->num_points; - AF_Point point; + AF_Point points = hints->points; + AF_Point limit = points + hints->num_points; + AF_Point* contour = hints->contours; + AF_Point* climit = contour + hints->num_contours; + AF_Point point; + + AF_DUMP(( "Table of points:\n" )); - FT_TRACE7(( "Table of points:\n" - " [ index | xorg | yorg | xscale | yscale" - " | xfit | yfit | flags ]\n" )); + if ( hints->num_points ) + AF_DUMP(( " index hedge hseg vedge vseg flags " + " xorg yorg xscale yscale xfit yfit" )); + else + AF_DUMP(( " (none)\n" )); for ( point = points; point < limit; point++ ) - FT_TRACE7(( " [ %5d | %5d | %5d | %6.2f | %6.2f" - " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n", - point - points, - point->fx, - point->fy, - point->ox / 64.0, - point->oy / 64.0, - point->x / 64.0, - point->y / 64.0, - ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', - ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', - ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', - ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ', - ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ', - ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' ')); - FT_TRACE7(( "\n" )); + { + int point_idx = AF_INDEX_NUM( point, points ); + int segment_idx_0 = af_get_segment_index( hints, point_idx, 0 ); + int segment_idx_1 = af_get_segment_index( hints, point_idx, 1 ); + + char buf1[16], buf2[16], buf3[16], buf4[16]; + + + /* insert extra newline at the beginning of a contour */ + if ( contour < climit && *contour == point ) + { + AF_DUMP(( "\n" )); + contour++; + } + + AF_DUMP(( " %5d %5s %5s %5s %5s %s" + " %5d %5d %7.2f %7.2f %7.2f %7.2f\n", + point_idx, + af_print_idx( buf1, + af_get_edge_index( hints, segment_idx_1, 1 ) ), + af_print_idx( buf2, segment_idx_1 ), + af_print_idx( buf3, + af_get_edge_index( hints, segment_idx_0, 0 ) ), + af_print_idx( buf4, segment_idx_0 ), + ( point->flags & AF_FLAG_NEAR ) + ? " near " + : ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + ? " weak " + : "strong", + + point->fx, + point->fy, + point->ox / 64.0, + point->oy / 64.0, + point->x / 64.0, + point->y / 64.0 )); + } + AF_DUMP(( "\n" )); } #ifdef __cplusplus } @@ -214,7 +365,7 @@ static const char* - af_edge_flags_to_string( AF_Edge_Flags flags ) + af_edge_flags_to_string( FT_UInt flags ) { static char temp[32]; int pos = 0; @@ -247,7 +398,8 @@ extern "C" { #endif void - af_glyph_hints_dump_segments( AF_GlyphHints hints ) + af_glyph_hints_dump_segments( AF_GlyphHints hints, + FT_Bool to_stdout ) { FT_Int dimension; @@ -261,35 +413,39 @@ AF_Segment limit = segments + axis->num_segments; AF_Segment seg; + char buf1[16], buf2[16], buf3[16]; - FT_TRACE7(( "Table of %s segments:\n", - dimension == AF_DIMENSION_HORZ ? "vertical" - : "horizontal" )); + + AF_DUMP(( "Table of %s segments:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" + : "horizontal" )); if ( axis->num_segments ) - FT_TRACE7(( " [ index | pos | dir | from" - " | to | link | serif | edge" - " | height | extra | flags ]\n" )); + AF_DUMP(( " index pos dir from to" + " link serif edge" + " height extra flags\n" )); else - FT_TRACE7(( " (none)\n" )); + AF_DUMP(( " (none)\n" )); for ( seg = segments; seg < limit; seg++ ) - FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d" - " | %4d | %4d | %5d | %4d" - " | %6d | %5d | %11s ]\n", - seg - segments, - dimension == AF_DIMENSION_HORZ - ? (int)seg->first->ox / 64.0 - : (int)seg->first->oy / 64.0, - af_dir_str( (AF_Direction)seg->dir ), - AF_INDEX_NUM( seg->first, points ), - AF_INDEX_NUM( seg->last, points ), - AF_INDEX_NUM( seg->link, segments ), - AF_INDEX_NUM( seg->serif, segments ), - AF_INDEX_NUM( seg->edge, edges ), - seg->height, - seg->height - ( seg->max_coord - seg->min_coord ), - af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) )); - FT_TRACE7(( "\n" )); + AF_DUMP(( " %5d %5.2g %5s %4d %4d" + " %4s %5s %4s" + " %6d %5d %11s\n", + AF_INDEX_NUM( seg, segments ), + dimension == AF_DIMENSION_HORZ + ? (int)seg->first->ox / 64.0 + : (int)seg->first->oy / 64.0, + af_dir_str( (AF_Direction)seg->dir ), + AF_INDEX_NUM( seg->first, points ), + AF_INDEX_NUM( seg->last, points ), + + af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ), + af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ), + af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ), + + seg->height, + seg->height - ( seg->max_coord - seg->min_coord ), + af_edge_flags_to_string( seg->flags ) )); + AF_DUMP(( "\n" )); } } #ifdef __cplusplus @@ -332,7 +488,9 @@ af_glyph_hints_get_segment_offset( AF_GlyphHints hints, FT_Int dimension, FT_Int idx, - FT_Pos* offset ) + FT_Pos *offset, + FT_Bool *is_blue, + FT_Pos *blue_offset ) { AF_Dimension dim; AF_AxisHints axis; @@ -349,9 +507,18 @@ if ( idx < 0 || idx >= axis->num_segments ) return FT_THROW( Invalid_Argument ); - seg = &axis->segments[idx]; - *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox - : seg->first->oy; + seg = &axis->segments[idx]; + *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox + : seg->first->oy; + if ( seg->edge ) + *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); + else + *is_blue = FALSE; + + if ( *is_blue ) + *blue_offset = seg->edge->blue_edge->cur; + else + *blue_offset = 0; return FT_Err_Ok; } @@ -366,7 +533,8 @@ extern "C" { #endif void - af_glyph_hints_dump_edges( AF_GlyphHints hints ) + af_glyph_hints_dump_edges( AF_GlyphHints hints, + FT_Bool to_stdout ) { FT_Int dimension; @@ -378,99 +546,43 @@ AF_Edge limit = edges + axis->num_edges; AF_Edge edge; + char buf1[16], buf2[16]; + /* * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges * since they have a constant X coordinate. */ - FT_TRACE7(( "Table of %s edges:\n", - dimension == AF_DIMENSION_HORZ ? "vertical" - : "horizontal" )); + AF_DUMP(( "Table of %s edges:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" + : "horizontal" )); if ( axis->num_edges ) - FT_TRACE7(( " [ index | pos | dir | link" - " | serif | blue | opos | pos | flags ]\n" )); + AF_DUMP(( " index pos dir link serif" + " blue opos pos flags\n" )); else - FT_TRACE7(( " (none)\n" )); + AF_DUMP(( " (none)\n" )); for ( edge = edges; edge < limit; edge++ ) - FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d" - " | %5d | %c | %5.2f | %5.2f | %11s ]\n", - edge - edges, - (int)edge->opos / 64.0, - af_dir_str( (AF_Direction)edge->dir ), - AF_INDEX_NUM( edge->link, edges ), - AF_INDEX_NUM( edge->serif, edges ), - edge->blue_edge ? 'y' : 'n', - edge->opos / 64.0, - edge->pos / 64.0, - af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) )); - FT_TRACE7(( "\n" )); + AF_DUMP(( " %5d %5.2g %5s %4s %5s" + " %c %5.2f %5.2f %11s\n", + AF_INDEX_NUM( edge, edges ), + (int)edge->opos / 64.0, + af_dir_str( (AF_Direction)edge->dir ), + af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ), + af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ), + + edge->blue_edge ? 'y' : 'n', + edge->opos / 64.0, + edge->pos / 64.0, + af_edge_flags_to_string( edge->flags ) )); + AF_DUMP(( "\n" )); } } #ifdef __cplusplus } #endif -#else /* !FT_DEBUG_AUTOFIT */ - - /* these empty stubs are only used to link the `ftgrid' test program */ - /* if debugging is disabled */ - -#ifdef __cplusplus - extern "C" { -#endif - - void - af_glyph_hints_dump_points( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - - - void - af_glyph_hints_dump_segments( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - - - FT_Error - af_glyph_hints_get_num_segments( AF_GlyphHints hints, - FT_Int dimension, - FT_Int* num_segments ) - { - FT_UNUSED( hints ); - FT_UNUSED( dimension ); - FT_UNUSED( num_segments ); - - return 0; - } - - - FT_Error - af_glyph_hints_get_segment_offset( AF_GlyphHints hints, - FT_Int dimension, - FT_Int idx, - FT_Pos* offset ) - { - FT_UNUSED( hints ); - FT_UNUSED( dimension ); - FT_UNUSED( idx ); - FT_UNUSED( offset ); - - return 0; - } - - - void - af_glyph_hints_dump_edges( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - -#ifdef __cplusplus - } -#endif +#undef AF_DUMP #endif /* !FT_DEBUG_AUTOFIT */ @@ -511,15 +623,15 @@ else { dir = AF_DIR_DOWN; - ll = dy; + ll = -dy; ss = dx; } } - /* return no direction if arm lengths differ too much */ + /* return no direction if arm lengths do not differ enough */ /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */ - ss *= 14; - if ( FT_ABS( ll ) <= FT_ABS( ss ) ) + /* the long arm is never negative */ + if ( ll <= 14 * FT_ABS( ss ) ) dir = AF_DIR_NONE; return dir; @@ -530,7 +642,8 @@ af_glyph_hints_init( AF_GlyphHints hints, FT_Memory memory ) { - FT_ZERO( hints ); + /* no need to initialize the embedded items */ + FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) ); hints->memory = memory; } @@ -538,13 +651,15 @@ FT_LOCAL_DEF( void ) af_glyph_hints_done( AF_GlyphHints hints ) { - FT_Memory memory = hints->memory; + FT_Memory memory; int dim; if ( !( hints && hints->memory ) ) return; + memory = hints->memory; + /* * note that we don't need to free the segment and edge * buffers since they are really within the hints->points array @@ -556,20 +671,24 @@ axis->num_segments = 0; axis->max_segments = 0; - FT_FREE( axis->segments ); + if ( axis->segments != axis->embedded.segments ) + FT_FREE( axis->segments ); axis->num_edges = 0; axis->max_edges = 0; - FT_FREE( axis->edges ); + if ( axis->edges != axis->embedded.edges ) + FT_FREE( axis->edges ); } - FT_FREE( hints->contours ); + if ( hints->contours != hints->embedded.contours ) + FT_FREE( hints->contours ); hints->max_contours = 0; hints->num_contours = 0; - FT_FREE( hints->points ); - hints->num_points = 0; + if ( hints->points != hints->embedded.points ) + FT_FREE( hints->points ); hints->max_points = 0; + hints->num_points = 0; hints->memory = NULL; } @@ -578,8 +697,8 @@ /* Reset metrics. */ FT_LOCAL_DEF( void ) - af_glyph_hints_rescale( AF_GlyphHints hints, - AF_ScriptMetrics metrics ) + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_StyleMetrics metrics ) { hints->metrics = metrics; hints->scaler_flags = metrics->scaler.flags; @@ -613,15 +732,27 @@ /* first of all, reallocate the contours array if necessary */ new_max = (FT_UInt)outline->n_contours; - old_max = hints->max_contours; - if ( new_max > old_max ) + old_max = (FT_UInt)hints->max_contours; + + if ( new_max <= AF_CONTOURS_EMBEDDED ) { - new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */ + if ( hints->contours == NULL ) + { + hints->contours = hints->embedded.contours; + hints->max_contours = AF_CONTOURS_EMBEDDED; + } + } + else if ( new_max > old_max ) + { + if ( hints->contours == hints->embedded.contours ) + hints->contours = NULL; + + new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */ if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) goto Exit; - hints->max_contours = new_max; + hints->max_contours = (FT_Int)new_max; } /* @@ -630,15 +761,27 @@ * hint metrics appropriately */ new_max = (FT_UInt)( outline->n_points + 2 ); - old_max = hints->max_points; - if ( new_max > old_max ) + old_max = (FT_UInt)hints->max_points; + + if ( new_max <= AF_POINTS_EMBEDDED ) + { + if ( hints->points == NULL ) + { + hints->points = hints->embedded.points; + hints->max_points = AF_POINTS_EMBEDDED; + } + } + else if ( new_max > old_max ) { - new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */ + if ( hints->points == hints->embedded.points ) + hints->points = NULL; + + new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */ if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) goto Exit; - hints->max_points = new_max; + hints->max_points = (FT_Int)new_max; } hints->num_points = outline->n_points; @@ -673,23 +816,37 @@ AF_Point point; AF_Point point_limit = points + hints->num_points; + /* value 20 in `near_limit' is heuristic */ + FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; + FT_Int near_limit = 20 * units_per_em / 2048; + /* compute coordinates & Bezier flags, next and prev */ { FT_Vector* vec = outline->points; char* tag = outline->tags; - AF_Point end = points + outline->contours[0]; + FT_Short endpoint = outline->contours[0]; + AF_Point end = points + endpoint; AF_Point prev = end; FT_Int contour_index = 0; for ( point = points; point < point_limit; point++, vec++, tag++ ) { + FT_Pos out_x, out_y; + + + point->in_dir = (FT_Char)AF_DIR_NONE; + point->out_dir = (FT_Char)AF_DIR_NONE; + point->fx = (FT_Short)vec->x; point->fy = (FT_Short)vec->y; point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; + end->fx = (FT_Short)outline->points[endpoint].x; + end->fy = (FT_Short)outline->points[endpoint].y; + switch ( FT_CURVE_TAG( *tag ) ) { case FT_CURVE_TAG_CONIC: @@ -702,6 +859,12 @@ point->flags = AF_FLAG_NONE; } + out_x = point->fx - prev->fx; + out_y = point->fy - prev->fy; + + if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) + prev->flags |= AF_FLAG_NEAR; + point->prev = prev; prev->next = point; prev = point; @@ -710,8 +873,9 @@ { if ( ++contour_index < outline->n_contours ) { - end = points + outline->contours[contour_index]; - prev = end; + endpoint = outline->contours[contour_index]; + end = points + endpoint; + prev = end; } } } @@ -732,60 +896,221 @@ } } - /* compute directions of in & out vectors */ { - AF_Point first = points; - AF_Point prev = NULL; - FT_Pos in_x = 0; - FT_Pos in_y = 0; - AF_Direction in_dir = AF_DIR_NONE; + /* + * Compute directions of `in' and `out' vectors. + * + * Note that distances between points that are very near to each + * other are accumulated. In other words, the auto-hinter either + * prepends the small vectors between near points to the first + * non-near vector, or the sum of small vector lengths exceeds a + * threshold, thus `grouping' the small vectors. All intermediate + * points are tagged as weak; the directions are adjusted also to + * be equal to the accumulated one. + */ + FT_Int near_limit2 = 2 * near_limit - 1; - for ( point = points; point < point_limit; point++ ) + AF_Point* contour; + AF_Point* contour_limit = hints->contours + hints->num_contours; + + + for ( contour = hints->contours; contour < contour_limit; contour++ ) { - AF_Point next; - FT_Pos out_x, out_y; + AF_Point first = *contour; + AF_Point next, prev, curr; + FT_Pos out_x, out_y; - if ( point == first ) + + /* since the first point of a contour could be part of a */ + /* series of near points, go backwards to find the first */ + /* non-near point and adjust `first' */ + + point = first; + prev = first->prev; + + while ( prev != first ) { - prev = first->prev; - in_x = first->fx - prev->fx; - in_y = first->fy - prev->fy; - in_dir = af_direction_compute( in_x, in_y ); - first = prev + 1; + out_x = point->fx - prev->fx; + out_y = point->fy - prev->fy; + + /* + * We use Taxicab metrics to measure the vector length. + * + * Note that the accumulated distances so far could have the + * opposite direction of the distance measured here. For this + * reason we use `near_limit2' for the comparison to get a + * non-near point even in the worst case. + */ + if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 ) + break; + + point = prev; + prev = prev->prev; } - point->in_dir = (FT_Char)in_dir; + /* adjust first point */ + first = point; + + /* now loop over all points of the contour to get */ + /* `in' and `out' vector directions */ + + curr = first; + + /* + * We abuse the `u' and `v' fields to store index deltas to the + * next and previous non-near point, respectively. + * + * To avoid problems with not having non-near points, we point to + * `first' by default as the next non-near point. + * + */ + curr->u = (FT_Pos)( first - curr ); + first->v = -curr->u; + + out_x = 0; + out_y = 0; + + next = first; + do + { + AF_Direction out_dir; + + + point = next; + next = point->next; + + out_x += next->fx - point->fx; + out_y += next->fy - point->fy; + + if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) + { + next->flags |= AF_FLAG_WEAK_INTERPOLATION; + continue; + } + + curr->u = (FT_Pos)( next - curr ); + next->v = -curr->u; + + out_dir = af_direction_compute( out_x, out_y ); + + /* adjust directions for all points inbetween; */ + /* the loop also updates position of `curr' */ + curr->out_dir = (FT_Char)out_dir; + for ( curr = curr->next; curr != next; curr = curr->next ) + { + curr->in_dir = (FT_Char)out_dir; + curr->out_dir = (FT_Char)out_dir; + } + next->in_dir = (FT_Char)out_dir; + + curr->u = (FT_Pos)( first - curr ); + first->v = -curr->u; + + out_x = 0; + out_y = 0; + + } while ( next != first ); + } + + /* + * The next step is to `simplify' an outline's topology so that we + * can identify local extrema more reliably: A series of + * non-horizontal or non-vertical vectors pointing into the same + * quadrant are handled as a single, long vector. From a + * topological point of the view, the intermediate points are of no + * interest and thus tagged as weak. + */ + + for ( point = points; point < point_limit; point++ ) + { + if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + continue; + + if ( point->in_dir == AF_DIR_NONE && + point->out_dir == AF_DIR_NONE ) + { + /* check whether both vectors point into the same quadrant */ + + FT_Pos in_x, in_y; + FT_Pos out_x, out_y; + + AF_Point next_u = point + point->u; + AF_Point prev_v = point + point->v; + + + in_x = point->fx - prev_v->fx; + in_y = point->fy - prev_v->fy; - next = point->next; - out_x = next->fx - point->fx; - out_y = next->fy - point->fy; + out_x = next_u->fx - point->fx; + out_y = next_u->fy - point->fy; - in_dir = af_direction_compute( out_x, out_y ); - point->out_dir = (FT_Char)in_dir; + if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 ) + { + /* yes, so tag current point as weak */ + /* and update index deltas */ + + point->flags |= AF_FLAG_WEAK_INTERPOLATION; + + prev_v->u = (FT_Pos)( next_u - prev_v ); + next_u->v = -prev_v->u; + } + } + } + + /* + * Finally, check for remaining weak points. Everything else not + * collected in edges so far is then implicitly classified as strong + * points. + */ - /* check for weak points */ + for ( point = points; point < point_limit; point++ ) + { + if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + continue; if ( point->flags & AF_FLAG_CONTROL ) { + /* control points are always weak */ Is_Weak_Point: point->flags |= AF_FLAG_WEAK_INTERPOLATION; } else if ( point->out_dir == point->in_dir ) { if ( point->out_dir != AF_DIR_NONE ) + { + /* current point lies on a horizontal or */ + /* vertical segment (but doesn't start or end it) */ goto Is_Weak_Point; + } - if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) ) - goto Is_Weak_Point; + { + AF_Point next_u = point + point->u; + AF_Point prev_v = point + point->v; + + + if ( ft_corner_is_flat( point->fx - prev_v->fx, + point->fy - prev_v->fy, + next_u->fx - point->fx, + next_u->fy - point->fy ) ) + { + /* either the `in' or the `out' vector is much more */ + /* dominant than the other one, so tag current point */ + /* as weak and update index deltas */ + + prev_v->u = (FT_Pos)( next_u - prev_v ); + next_u->v = -prev_v->u; + + goto Is_Weak_Point; + } + } } else if ( point->in_dir == -point->out_dir ) + { + /* current point forms a spike */ goto Is_Weak_Point; - - in_x = out_x; - in_y = out_y; - prev = point; + } } } } @@ -916,7 +1241,7 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - AF_Flags touch_flag; + FT_UInt touch_flag; if ( dim == AF_DIMENSION_HORZ ) @@ -942,8 +1267,7 @@ /* if this point is candidate to weak interpolation, we */ /* interpolate it after all strong points have been processed */ - if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && - !( point->flags & AF_FLAG_INFLECTION ) ) + if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ) continue; if ( dim == AF_DIMENSION_VERT ) @@ -1098,33 +1422,27 @@ AF_Point ref2 ) { AF_Point p; - FT_Pos u; - FT_Pos v1 = ref1->v; - FT_Pos v2 = ref2->v; - FT_Pos d1 = ref1->u - v1; - FT_Pos d2 = ref2->u - v2; + FT_Pos u, v1, v2, u1, u2, d1, d2; if ( p1 > p2 ) return; - if ( v1 == v2 ) + if ( ref1->v > ref2->v ) { - for ( p = p1; p <= p2; p++ ) - { - u = p->v; - - if ( u <= v1 ) - u += d1; - else - u += d2; - - p->u = u; - } - return; + p = ref1; + ref1 = ref2; + ref2 = p; } - if ( v1 < v2 ) + v1 = ref1->v; + v2 = ref2->v; + u1 = ref1->u; + u2 = ref2->u; + d1 = u1 - v1; + d2 = u2 - v2; + + if ( u1 == u2 || v1 == v2 ) { for ( p = p1; p <= p2; p++ ) { @@ -1135,23 +1453,26 @@ else if ( u >= v2 ) u += d2; else - u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + u = u1; p->u = u; } } else { + FT_Fixed scale = FT_DivFix( u2 - u1, v2 - v1 ); + + for ( p = p1; p <= p2; p++ ) { u = p->v; - if ( u <= v2 ) - u += d2; - else if ( u >= v1 ) + if ( u <= v1 ) u += d1; + else if ( u >= v2 ) + u += d2; else - u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + u = u1 + FT_MulFix( u - v1, scale ); p->u = u; } @@ -1170,7 +1491,7 @@ AF_Point point_limit = points + hints->num_points; AF_Point* contour = hints->contours; AF_Point* contour_limit = contour + hints->num_contours; - AF_Flags touch_flag; + FT_UInt touch_flag; AF_Point point; AF_Point end_point; AF_Point first_point; @@ -1199,8 +1520,6 @@ } } - point = points; - for ( ; contour < contour_limit; contour++ ) { AF_Point first_touched, last_touched; @@ -1223,7 +1542,6 @@ } first_touched = point; - last_touched = point; for (;;) { diff --git a/drivers/freetype/src/autofit/afhints.h b/drivers/freetype/src/autofit/afhints.h index 776b3c844e..5142e6ed21 100644 --- a/drivers/freetype/src/autofit/afhints.h +++ b/drivers/freetype/src/autofit/afhints.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (specification). */ /* */ -/* Copyright 2003-2008, 2010-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFHINTS_H__ -#define __AFHINTS_H__ +#ifndef AFHINTS_H_ +#define AFHINTS_H_ #include "aftypes.h" @@ -27,7 +27,7 @@ FT_BEGIN_HEADER /* * The definition of outline glyph hints. These are shared by all - * script analysis routines (until now). + * writing system analysis routines (until now). */ typedef enum AF_Dimension_ @@ -62,33 +62,34 @@ FT_BEGIN_HEADER * * by David Turner and Werner Lemberg * - * http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf + * http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf + * + * with appropriate updates. * * * Segments * * `af_{cjk,latin,...}_hints_compute_segments' are the functions to - * find segments in an outline. A segment is a series of consecutive - * points that are approximately aligned along a coordinate axis. The - * analysis to do so is specific to a script. + * find segments in an outline. * - * A segment must have at least two points, except in the case of - * `fake' segments that are generated to hint metrics appropriately, - * and which consist of a single point. + * A segment is a series of at least two consecutive points that are + * approximately aligned along a coordinate axis. The analysis to do + * so is specific to a writing system. * * * Edges * + * `af_{cjk,latin,...}_hints_compute_edges' are the functions to find + * edges. + * * As soon as segments are defined, the auto-hinter groups them into * edges. An edge corresponds to a single position on the main * dimension that collects one or more segments (allowing for a small * threshold). * - * The auto-hinter first tries to grid fit edges, then to align - * segments on the edges unless it detects that they form a serif. - * - * `af_{cjk,latin,...}_hints_compute_edges' are the functions to find - * edges; they are specific to a script. + * As an example, the `latin' writing system first tries to grid-fit + * edges, then to align segments on the edges unless it detects that + * they form a serif. * * * A H @@ -107,6 +108,8 @@ FT_BEGIN_HEADER * * Stems * + * Stems are detected by `af_{cjk,latin,...}_hint_edges'. + * * Segments need to be `linked' to other ones in order to detect stems. * A stem is made of two segments that face each other in opposite * directions and that are sufficiently close to each other. Using @@ -127,17 +130,21 @@ FT_BEGIN_HEADER * The best candidate is stored in field `link' in structure * `AF_Segment'. * - * Stems are detected by `af_{cjk,latin,...}_hint_edges'. - * * In the above ASCII drawing, the best candidate for both AB and CD is * GH, while the best candidate for GH is AB. Similarly, the best * candidate for EF and GH is AB, while the best candidate for AB is * GH. * + * The detection and handling of stems is dependent on the writing + * system. + * * * Serifs * - * On the opposite, a serif has + * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. + * + * In comparison to a stem, a serif (as handled by the auto-hinter + * module that takes care of the `latin' writing system) has * * best segment_1 = segment_2 && best segment_2 != segment_1 * @@ -147,8 +154,6 @@ FT_BEGIN_HEADER * The best candidate is stored in field `serif' in structure * `AF_Segment' (and `link' is set to NULL). * - * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. - * * * Touched points * @@ -169,18 +174,19 @@ FT_BEGIN_HEADER * * Strong Points * - * Experience has shown that points which are not part of an edge need - * to be interpolated linearly between their two closest edges, even if - * these are not part of the contour of those particular points. - * Typical candidates for this are + * Experience has shown that points not part of an edge need to be + * interpolated linearly between their two closest edges, even if these + * are not part of the contour of those particular points. Typical + * candidates for this are * * - angle points (i.e., points where the `in' and `out' direction * differ greatly) * * - inflection points (i.e., where the `in' and `out' angles are the - * same, but the curvature changes sign) + * same, but the curvature changes sign) [currently, such points + * aren't handled specially in the auto-hinter] * - * `af_glyph_hints_align_strong_points' is the function which takes + * `af_glyph_hints_align_strong_points' is the function that takes * care of such situations; it is equivalent to the TrueType `IP' * hinting instruction. * @@ -201,45 +207,30 @@ FT_BEGIN_HEADER /* point hint flags */ - typedef enum AF_Flags_ - { - AF_FLAG_NONE = 0, - - /* point type flags */ - AF_FLAG_CONIC = 1 << 0, - AF_FLAG_CUBIC = 1 << 1, - AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, - - /* point extremum flags */ - AF_FLAG_EXTREMA_X = 1 << 2, - AF_FLAG_EXTREMA_Y = 1 << 3, +#define AF_FLAG_NONE 0 - /* point roundness flags */ - AF_FLAG_ROUND_X = 1 << 4, - AF_FLAG_ROUND_Y = 1 << 5, + /* point type flags */ +#define AF_FLAG_CONIC ( 1U << 0 ) +#define AF_FLAG_CUBIC ( 1U << 1 ) +#define AF_FLAG_CONTROL ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) - /* point touch flags */ - AF_FLAG_TOUCH_X = 1 << 6, - AF_FLAG_TOUCH_Y = 1 << 7, + /* point touch flags */ +#define AF_FLAG_TOUCH_X ( 1U << 2 ) +#define AF_FLAG_TOUCH_Y ( 1U << 3 ) - /* candidates for weak interpolation have this flag set */ - AF_FLAG_WEAK_INTERPOLATION = 1 << 8, + /* candidates for weak interpolation have this flag set */ +#define AF_FLAG_WEAK_INTERPOLATION ( 1U << 4 ) - /* all inflection points in the outline have this flag set */ - AF_FLAG_INFLECTION = 1 << 9 - - } AF_Flags; + /* the distance to the next point is very small */ +#define AF_FLAG_NEAR ( 1U << 5 ) /* edge hint flags */ - typedef enum AF_Edge_Flags_ - { - AF_EDGE_NORMAL = 0, - AF_EDGE_ROUND = 1 << 0, - AF_EDGE_SERIF = 1 << 1, - AF_EDGE_DONE = 1 << 2 - - } AF_Edge_Flags; +#define AF_EDGE_NORMAL 0 +#define AF_EDGE_ROUND ( 1U << 0 ) +#define AF_EDGE_SERIF ( 1U << 1 ) +#define AF_EDGE_DONE ( 1U << 2 ) +#define AF_EDGE_NEUTRAL ( 1U << 3 ) /* edge aligns to a neutral blue zone */ typedef struct AF_PointRec_* AF_Point; @@ -278,7 +269,6 @@ FT_BEGIN_HEADER AF_Segment link; /* (stem) link segment */ AF_Segment serif; /* primary segment for serifs */ - FT_Pos num_linked; /* number of linked segments */ FT_Pos score; /* used during stem matching */ FT_Pos len; /* used during stem matching */ @@ -301,7 +291,6 @@ FT_BEGIN_HEADER AF_Width blue_edge; /* non-NULL if this is a blue edge */ AF_Edge link; /* link edge */ AF_Edge serif; /* primary edge for serifs */ - FT_Short num_linked; /* number of linked edges */ FT_Int score; /* used during stem matching */ AF_Segment first; /* first segment in edge */ @@ -309,6 +298,8 @@ FT_BEGIN_HEADER } AF_EdgeRec; +#define AF_SEGMENTS_EMBEDDED 18 /* number of embedded segments */ +#define AF_EDGES_EMBEDDED 12 /* number of embedded edges */ typedef struct AF_AxisHintsRec_ { @@ -325,36 +316,55 @@ FT_BEGIN_HEADER AF_Direction major_dir; /* either vertical or horizontal */ + /* two arrays to avoid allocation penalty */ + struct + { + AF_SegmentRec segments[AF_SEGMENTS_EMBEDDED]; + AF_EdgeRec edges[AF_EDGES_EMBEDDED]; + } embedded; + + } AF_AxisHintsRec, *AF_AxisHints; +#define AF_POINTS_EMBEDDED 96 /* number of embedded points */ +#define AF_CONTOURS_EMBEDDED 8 /* number of embedded contours */ + typedef struct AF_GlyphHintsRec_ { - FT_Memory memory; + FT_Memory memory; + + FT_Fixed x_scale; + FT_Pos x_delta; - FT_Fixed x_scale; - FT_Pos x_delta; + FT_Fixed y_scale; + FT_Pos y_delta; - FT_Fixed y_scale; - FT_Pos y_delta; + FT_Int max_points; /* number of allocated points */ + FT_Int num_points; /* number of used points */ + AF_Point points; /* points array */ - FT_Int max_points; /* number of allocated points */ - FT_Int num_points; /* number of used points */ - AF_Point points; /* points array */ + FT_Int max_contours; /* number of allocated contours */ + FT_Int num_contours; /* number of used contours */ + AF_Point* contours; /* contours array */ - FT_Int max_contours; /* number of allocated contours */ - FT_Int num_contours; /* number of used contours */ - AF_Point* contours; /* contours array */ + AF_AxisHintsRec axis[AF_DIMENSION_MAX]; - AF_AxisHintsRec axis[AF_DIMENSION_MAX]; + FT_UInt32 scaler_flags; /* copy of scaler flags */ + FT_UInt32 other_flags; /* free for style-specific */ + /* implementations */ + AF_StyleMetrics metrics; - FT_UInt32 scaler_flags; /* copy of scaler flags */ - FT_UInt32 other_flags; /* free for script-specific */ - /* implementations */ - AF_ScriptMetrics metrics; + FT_Pos xmin_delta; /* used for warping */ + FT_Pos xmax_delta; - FT_Pos xmin_delta; /* used for warping */ - FT_Pos xmax_delta; + /* Two arrays to avoid allocation penalty. */ + /* The `embedded' structure must be the last element! */ + struct + { + AF_Point contours[AF_CONTOURS_EMBEDDED]; + AF_PointRec points[AF_POINTS_EMBEDDED]; + } embedded; } AF_GlyphHintsRec; @@ -373,9 +383,6 @@ FT_BEGIN_HEADER ( !_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 /* !FT_DEBUG_AUTOFIT */ @@ -386,12 +393,17 @@ FT_BEGIN_HEADER #define AF_HINTS_DO_VERTICAL( h ) \ !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) +#define AF_HINTS_DO_BLUES( h ) 1 + +#endif /* !FT_DEBUG_AUTOFIT */ + + #define AF_HINTS_DO_ADVANCE( h ) \ !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE ) -#define AF_HINTS_DO_BLUES( h ) 1 +#define AF_HINTS_DO_WARP( h ) \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_WARPER ) -#endif /* !FT_DEBUG_AUTOFIT */ FT_LOCAL( AF_Direction ) @@ -408,6 +420,7 @@ FT_BEGIN_HEADER af_axis_hints_new_edge( AF_AxisHints axis, FT_Int fpos, AF_Direction dir, + FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *edge ); @@ -416,8 +429,8 @@ FT_BEGIN_HEADER FT_Memory memory ); FT_LOCAL( void ) - af_glyph_hints_rescale( AF_GlyphHints hints, - AF_ScriptMetrics metrics ); + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_StyleMetrics metrics ); FT_LOCAL( FT_Error ) af_glyph_hints_reload( AF_GlyphHints hints, @@ -461,7 +474,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFHINTS_H__ */ +#endif /* AFHINTS_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afindic.c b/drivers/freetype/src/autofit/afindic.c index 8c24972598..097a2b2995 100644 --- a/drivers/freetype/src/autofit/afindic.c +++ b/drivers/freetype/src/autofit/afindic.c @@ -2,9 +2,9 @@ /* */ /* afindic.c */ /* */ -/* Auto-fitter hinting routines for Indic scripts (body). */ +/* Auto-fitter hinting routines for Indic writing system (body). */ /* */ -/* Copyright 2007, 2011-2013 by */ +/* Copyright 2007-2016 by */ /* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,12 +79,29 @@ static FT_Error - af_indic_hints_apply( AF_GlyphHints hints, + af_indic_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_CJKMetrics metrics ) { /* use CJK routines */ - return af_cjk_hints_apply( hints, outline, metrics ); + return af_cjk_hints_apply( glyph_index, hints, outline, metrics ); + } + + + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + static void + af_indic_get_standard_widths( AF_CJKMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; } @@ -97,60 +114,43 @@ /*************************************************************************/ - static const AF_Script_UniRangeRec af_indic_uniranges[] = - { -#if 0 - AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ -#endif - AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ - AF_UNIRANGE_REC( 0x0F00UL, 0x0FFFUL), /* Tibetan */ - AF_UNIRANGE_REC( 0x1900UL, 0x194FUL), /* Limbu */ - AF_UNIRANGE_REC( 0x1B80UL, 0x1BBFUL), /* Sundanese */ - AF_UNIRANGE_REC( 0x1C80UL, 0x1CDFUL), /* Meetei Mayak */ - AF_UNIRANGE_REC( 0xA800UL, 0xA82FUL), /* Syloti Nagri */ - AF_UNIRANGE_REC( 0x11800UL, 0x118DFUL), /* Sharada */ - AF_UNIRANGE_REC( 0UL, 0UL) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, - AF_SCRIPT_INDIC, - af_indic_uniranges, - 'o', /* XXX */ + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_indic_writing_system_class, + + AF_WRITING_SYSTEM_INDIC, sizeof ( AF_CJKMetricsRec ), - (AF_Script_InitMetricsFunc) af_indic_metrics_init, - (AF_Script_ScaleMetricsFunc)af_indic_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init, + (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths, - (AF_Script_InitHintsFunc) af_indic_hints_init, - (AF_Script_ApplyHintsFunc) af_indic_hints_apply + (AF_WritingSystem_InitHintsFunc) af_indic_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_indic_hints_apply ) + #else /* !AF_CONFIG_OPTION_INDIC */ - static const AF_Script_UniRangeRec af_indic_uniranges[] = - { - { 0, 0 } - }; + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_indic_writing_system_class, - AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, - AF_SCRIPT_INDIC, - af_indic_uniranges, - 0, + AF_WRITING_SYSTEM_INDIC, sizeof ( AF_CJKMetricsRec ), - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, + (AF_WritingSystem_ScaleMetricsFunc)NULL, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)NULL, - (AF_Script_InitHintsFunc) NULL, - (AF_Script_ApplyHintsFunc) NULL + (AF_WritingSystem_InitHintsFunc) NULL, + (AF_WritingSystem_ApplyHintsFunc) NULL ) + #endif /* !AF_CONFIG_OPTION_INDIC */ diff --git a/drivers/freetype/src/autofit/afindic.h b/drivers/freetype/src/autofit/afindic.h index c252cf20da..0772e07a29 100644 --- a/drivers/freetype/src/autofit/afindic.h +++ b/drivers/freetype/src/autofit/afindic.h @@ -2,9 +2,10 @@ /* */ /* afindic.h */ /* */ -/* Auto-fitter hinting routines for Indic scripts (specification). */ +/* Auto-fitter hinting routines for Indic writing system */ +/* (specification). */ /* */ -/* Copyright 2007, 2012 by */ +/* Copyright 2007-2016 by */ /* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +17,8 @@ /***************************************************************************/ -#ifndef __AFINDIC_H__ -#define __AFINDIC_H__ +#ifndef AFINDIC_H_ +#define AFINDIC_H_ #include "afhints.h" @@ -25,16 +26,16 @@ FT_BEGIN_HEADER - /* the Indic-specific script class */ + /* the `indic' writing system */ - AF_DECLARE_SCRIPT_CLASS( af_indic_script_class ) + AF_DECLARE_WRITING_SYSTEM_CLASS( af_indic_writing_system_class ) /* */ FT_END_HEADER -#endif /* __AFINDIC_H__ */ +#endif /* AFINDIC_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/aflatin.c b/drivers/freetype/src/autofit/aflatin.c index ef0157a13e..7ccf3f6e37 100644 --- a/drivers/freetype/src/autofit/aflatin.c +++ b/drivers/freetype/src/autofit/aflatin.c @@ -2,9 +2,9 @@ /* */ /* aflatin.c */ /* */ -/* Auto-fitter hinting routines for latin script (body). */ +/* Auto-fitter hinting routines for latin writing system (body). */ /* */ -/* Copyright 2003-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,6 +21,7 @@ #include FT_INTERNAL_DEBUG_H #include "afglobal.h" +#include "afpic.h" #include "aflatin.h" #include "aferrors.h" @@ -40,6 +41,10 @@ #define FT_COMPONENT trace_aflatin + /* needed for computation of round vs. flat segments */ +#define FLAT_THRESHOLD( x ) ( x / 14 ) + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -60,8 +65,11 @@ AF_GlyphHintsRec hints[1]; - FT_TRACE5(( "standard widths computation\n" - "===========================\n\n" )); + FT_TRACE5(( "\n" + "latin standard widths computation (style `%s')\n" + "=====================================================\n" + "\n", + af_style_names[metrics->root.style_class->style] )); af_glyph_hints_init( hints, face->memory ); @@ -70,19 +78,76 @@ { FT_Error error; - FT_UInt glyph_index; + FT_ULong glyph_index; int dim; AF_LatinMetricsRec dummy[1]; AF_Scaler scaler = &dummy->root.scaler; +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = metrics->root.globals; +#endif + + AF_StyleClass style_class = metrics->root.style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + void* shaper_buf; + const char* p; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong ch = 0; +#endif + + p = script_class->standard_charstring; + shaper_buf = af_shaper_buf_create( face ); + + /* + * We check a list of standard characters to catch features like + * `c2sc' (small caps from caps) that don't contain lowercase letters + * by definition, or other features that mainly operate on numerals. + * The first match wins. + */ + + glyph_index = 0; + while ( *p ) + { + unsigned int num_idx; + +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; +#endif + + + while ( *p == ' ' ) + p++; + +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; + + /* otherwise exit loop if we have a result */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); + if ( glyph_index ) + break; + } - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); - if ( glyph_index == 0 ) + af_shaper_buf_destroy( face, shaper_buf ); + + if ( !glyph_index ) goto Exit; - FT_TRACE5(( "standard character: 0x%X (glyph index %d)\n", - metrics->root.clazz->standard_char, glyph_index )); + FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n", + ch, glyph_index )); error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); if ( error || face->glyph->outline.n_points <= 0 ) @@ -101,7 +166,7 @@ scaler->render_mode = FT_RENDER_MODE_NORMAL; scaler->flags = 0; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy ); error = af_glyph_hints_reload( hints, &face->glyph->outline ); if ( error ) @@ -120,7 +185,15 @@ if ( error ) goto Exit; + /* + * We assume that the glyphs selected for the stem width + * computation are `featureless' enough so that the linking + * algorithm works fine without adjustments of its scoring + * function. + */ af_latin_hints_link_segments( hints, + 0, + NULL, (AF_Dimension)dim ); seg = axhints->segments; @@ -146,22 +219,21 @@ } /* this also replaces multiple almost identical stem widths */ - /* with a single one (the value 100 is heuristic) */ + /* with a single one (the value 100 is heuristic) */ af_sort_and_quantize_widths( &num_widths, axis->widths, dummy->units_per_em / 100 ); axis->width_count = num_widths; } - Exit: + Exit: for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { AF_LatinAxis axis = &metrics->axis[dim]; FT_Pos stdw; - stdw = ( axis->width_count > 0 ) - ? axis->widths[0].org - : AF_LATIN_CONSTANT( metrics, 50 ); + stdw = ( axis->width_count > 0 ) ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); /* let's try 20% of the smallest width */ axis->edge_distance_threshold = stdw / 5; @@ -193,22 +265,6 @@ } - -#define AF_LATIN_MAX_TEST_CHARACTERS 12 - - - static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] - [AF_LATIN_MAX_TEST_CHARACTERS + 1] = - { - "THEZOCQS", - "HEZLOCUS", - "fijkdbh", - "xzroesc", - "xzroesc", - "pqgjy" - }; - - /* Find all blue zones. Flat segments give the reference points, */ /* round segments the overshoot positions. */ @@ -216,203 +272,575 @@ af_latin_metrics_init_blues( AF_LatinMetrics metrics, FT_Face face ) { - FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Int num_flats; - FT_Int num_rounds; - FT_Int bb; + FT_Pos flats [AF_BLUE_STRING_MAX_LEN]; + FT_Pos rounds[AF_BLUE_STRING_MAX_LEN]; + + FT_UInt num_flats; + FT_UInt num_rounds; + AF_LatinBlue blue; FT_Error error; - AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; + AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; FT_Outline outline; + AF_StyleClass sc = metrics->root.style_class; + + AF_Blue_Stringset bss = sc->blue_stringset; + const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; + + FT_Pos flat_threshold = FLAT_THRESHOLD( metrics->units_per_em ); + + void* shaper_buf; + + + /* we walk over the blue character strings as specified in the */ + /* style's entry in the `af_blue_stringset' array */ - /* we compute the blues simply by loading each character from the */ - /* `af_latin_blue_chars[blues]' string, then finding its top-most or */ - /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ + FT_TRACE5(( "latin blue zones computation\n" + "============================\n" + "\n" )); - FT_TRACE5(( "blue zones computation\n" - "======================\n\n" )); + shaper_buf = af_shaper_buf_create( face ); - for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) { - const char* p = af_latin_blue_chars[bb]; - const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; + const char* p = &af_blue_strings[bs->string]; FT_Pos* blue_ref; FT_Pos* blue_shoot; + FT_Pos ascender; + FT_Pos descender; - FT_TRACE5(( "blue zone %d:\n", bb )); +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Bool have_flag = 0; + + + FT_TRACE5(( "blue zone %d", axis->blue_count )); + + if ( bs->properties ) + { + FT_TRACE5(( " (" )); + + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) + { + FT_TRACE5(( "top" )); + have_flag = 1; + } + else if ( AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) + { + FT_TRACE5(( "sub top" )); + have_flag = 1; + } + + if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) + { + if ( have_flag ) + FT_TRACE5(( ", " )); + FT_TRACE5(( "neutral" )); + have_flag = 1; + } + + if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) ) + { + if ( have_flag ) + FT_TRACE5(( ", " )); + FT_TRACE5(( "small top" )); + have_flag = 1; + } + + if ( AF_LATIN_IS_LONG_BLUE( bs ) ) + { + if ( have_flag ) + FT_TRACE5(( ", " )); + FT_TRACE5(( "long" )); + } + + FT_TRACE5(( ")" )); + } + + FT_TRACE5(( ":\n" )); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ num_flats = 0; num_rounds = 0; + ascender = 0; + descender = 0; - for ( ; p < limit && *p; p++ ) + while ( *p ) { - FT_UInt glyph_index; - FT_Pos best_y; /* same as points.y */ + FT_ULong glyph_index; + FT_Long y_offset; FT_Int best_point, best_contour_first, best_contour_last; FT_Vector* points; - FT_Bool round = 0; + FT_Pos best_y_extremum; /* same as points.y */ + FT_Bool best_round = 0; - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); - if ( glyph_index == 0 ) - continue; + unsigned int i, num_idx; - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - outline = face->glyph->outline; - if ( error || outline.n_points <= 0 ) +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; + FT_ULong ch; +#endif + + + while ( *p == ' ' ) + p++; + +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + + if ( !num_idx ) + { + FT_TRACE5(( " U+%04lX unavailable\n", ch )); continue; + } - /* now compute min or max point indices and coordinates */ - points = outline.points; - best_point = -1; - best_y = 0; /* make compiler happy */ - best_contour_first = 0; /* ditto */ - best_contour_last = 0; /* ditto */ + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) + best_y_extremum = FT_INT_MIN; + else + best_y_extremum = FT_INT_MAX; + /* iterate over all glyph elements of the character cluster */ + /* and get the data of the `biggest' one */ + for ( i = 0; i < num_idx; i++ ) { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; + FT_Pos best_y; + FT_Bool round = 0; - for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + i, + NULL, + &y_offset ); + if ( glyph_index == 0 ) { - FT_Int old_best_point = best_point; - FT_Int pp; + FT_TRACE5(( " U+%04lX unavailable\n", ch )); + continue; + } + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + outline = face->glyph->outline; + /* reject glyphs that don't produce any rendering */ + if ( error || outline.n_points <= 2 ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( num_idx == 1 ) + FT_TRACE5(( " U+%04lX contains no (usable) outlines\n", ch )); + else + FT_TRACE5(( " component %d of cluster starting with U+%04lX" + " contains no (usable) outlines\n", i, ch )); +#endif + continue; + } + /* now compute min or max point indices and coordinates */ + points = outline.points; + best_point = -1; + best_y = 0; /* make compiler happy */ + best_contour_first = 0; /* ditto */ + best_contour_last = 0; /* ditto */ - last = outline.contours[nn]; + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; - /* Avoid single-point contours since they are never rasterized. */ - /* In some fonts, they correspond to mark attachment points */ - /* which are way outside of the glyph's real outline. */ - if ( last <= first ) - continue; - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_y ) + FT_Int old_best_point = best_point; + FT_Int pp; + + + last = outline.contours[nn]; + + /* Avoid single-point contours since they are never */ + /* rasterized. In some fonts, they correspond to mark */ + /* attachment points that are way outside of the glyph's */ + /* real outline. */ + if ( last <= first ) + continue; + + if ( AF_LATIN_IS_TOP_BLUE( bs ) || + AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) + { + for ( pp = first; pp <= last; pp++ ) { - best_point = pp; - best_y = points[pp].y; + if ( best_point < 0 || points[pp].y > best_y ) + { + best_point = pp; + best_y = points[pp].y; + ascender = FT_MAX( ascender, best_y + y_offset ); + } + else + descender = FT_MIN( descender, points[pp].y + y_offset ); } - } - else - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_y ) + } + else + { + for ( pp = first; pp <= last; pp++ ) { - best_point = pp; - best_y = points[pp].y; + if ( best_point < 0 || points[pp].y < best_y ) + { + best_point = pp; + best_y = points[pp].y; + descender = FT_MIN( descender, best_y + y_offset ); + } + else + ascender = FT_MAX( ascender, points[pp].y + y_offset ); } + } + + if ( best_point != old_best_point ) + { + best_contour_first = first; + best_contour_last = last; + } } + } - if ( best_point != old_best_point ) + /* now check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then inspect its previous and next points */ + if ( best_point >= 0 ) + { + FT_Pos best_x = points[best_point].x; + FT_Int prev, next; + FT_Int best_segment_first, best_segment_last; + FT_Int best_on_point_first, best_on_point_last; + FT_Pos dist; + + + best_segment_first = best_point; + best_segment_last = best_point; + + if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) { - best_contour_first = first; - best_contour_last = last; + best_on_point_first = best_point; + best_on_point_last = best_point; + } + else + { + best_on_point_first = -1; + best_on_point_last = -1; } - } - FT_TRACE5(( " %c %ld", *p, best_y )); - } - /* now check whether the point belongs to a straight or round */ - /* segment; we first need to find in which contour the extremum */ - /* lies, then inspect its previous and next points */ - if ( best_point >= 0 ) - { - FT_Pos best_x = points[best_point].x; - FT_Int prev, next; - FT_Int best_on_point_first, best_on_point_last; - FT_Pos dist; + /* look for the previous and next points on the contour */ + /* that are not on the same Y coordinate, then threshold */ + /* the `closeness'... */ + prev = best_point; + next = prev; + do + { + if ( prev > best_contour_first ) + prev--; + else + prev = best_contour_last; - if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) - { - best_on_point_first = best_point; - best_on_point_last = best_point; - } - else - { - best_on_point_first = -1; - best_on_point_last = -1; - } + dist = FT_ABS( points[prev].y - best_y ); + /* accept a small distance or a small angle (both values are */ + /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ + if ( dist > 5 ) + if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) + break; - /* look for the previous and next points that are not on the */ - /* same Y coordinate, then threshold the `closeness'... */ - prev = best_point; - next = prev; + best_segment_first = prev; - do - { - if ( prev > best_contour_first ) - prev--; - else - prev = best_contour_last; + if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) + { + best_on_point_first = prev; + if ( best_on_point_last < 0 ) + best_on_point_last = prev; + } - dist = FT_ABS( points[prev].y - best_y ); - /* accept a small distance or a small angle (both values are */ - /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ - if ( dist > 5 ) - if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) - break; + } while ( prev != best_point ); - if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) + do { - best_on_point_first = prev; - if ( best_on_point_last < 0 ) - best_on_point_last = prev; + if ( next < best_contour_last ) + next++; + else + next = best_contour_first; + + dist = FT_ABS( points[next].y - best_y ); + if ( dist > 5 ) + if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) + break; + + best_segment_last = next; + + if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) + { + best_on_point_last = next; + if ( best_on_point_first < 0 ) + best_on_point_first = next; + } + + } while ( next != best_point ); + + if ( AF_LATIN_IS_LONG_BLUE( bs ) ) + { + /* If this flag is set, we have an additional constraint to */ + /* get the blue zone distance: Find a segment of the topmost */ + /* (or bottommost) contour that is longer than a heuristic */ + /* threshold. This ensures that small bumps in the outline */ + /* are ignored (for example, the `vertical serifs' found in */ + /* many Hebrew glyph designs). */ + + /* If this segment is long enough, we are done. Otherwise, */ + /* search the segment next to the extremum that is long */ + /* enough, has the same direction, and a not too large */ + /* vertical distance from the extremum. Note that the */ + /* algorithm doesn't check whether the found segment is */ + /* actually the one (vertically) nearest to the extremum. */ + + /* heuristic threshold value */ + FT_Pos length_threshold = metrics->units_per_em / 25; + + + dist = FT_ABS( points[best_segment_last].x - + points[best_segment_first].x ); + + if ( dist < length_threshold && + best_segment_last - best_segment_first + 2 <= + best_contour_last - best_contour_first ) + { + /* heuristic threshold value */ + FT_Pos height_threshold = metrics->units_per_em / 4; + + FT_Int first; + FT_Int last; + FT_Bool hit; + + /* we intentionally declare these two variables */ + /* outside of the loop since various compilers emit */ + /* incorrect warning messages otherwise, talking about */ + /* `possibly uninitialized variables' */ + FT_Int p_first = 0; /* make compiler happy */ + FT_Int p_last = 0; + + FT_Bool left2right; + + + /* compute direction */ + prev = best_point; + + do + { + if ( prev > best_contour_first ) + prev--; + else + prev = best_contour_last; + + if ( points[prev].x != best_x ) + break; + + } while ( prev != best_point ); + + /* skip glyph for the degenerate case */ + if ( prev == best_point ) + continue; + + left2right = FT_BOOL( points[prev].x < points[best_point].x ); + + first = best_segment_last; + last = first; + hit = 0; + + do + { + FT_Bool l2r; + FT_Pos d; + + + if ( !hit ) + { + /* no hit; adjust first point */ + first = last; + + /* also adjust first and last on point */ + if ( FT_CURVE_TAG( outline.tags[first] ) == + FT_CURVE_TAG_ON ) + { + p_first = first; + p_last = first; + } + else + { + p_first = -1; + p_last = -1; + } + + hit = 1; + } + + if ( last < best_contour_last ) + last++; + else + last = best_contour_first; + + if ( FT_ABS( best_y - points[first].y ) > height_threshold ) + { + /* vertical distance too large */ + hit = 0; + continue; + } + + /* same test as above */ + dist = FT_ABS( points[last].y - points[first].y ); + if ( dist > 5 ) + if ( FT_ABS( points[last].x - points[first].x ) <= + 20 * dist ) + { + hit = 0; + continue; + } + + if ( FT_CURVE_TAG( outline.tags[last] ) == FT_CURVE_TAG_ON ) + { + p_last = last; + if ( p_first < 0 ) + p_first = last; + } + + l2r = FT_BOOL( points[first].x < points[last].x ); + d = FT_ABS( points[last].x - points[first].x ); + + if ( l2r == left2right && + d >= length_threshold ) + { + /* all constraints are met; update segment after */ + /* finding its end */ + do + { + if ( last < best_contour_last ) + last++; + else + last = best_contour_first; + + d = FT_ABS( points[last].y - points[first].y ); + if ( d > 5 ) + if ( FT_ABS( points[next].x - points[first].x ) <= + 20 * dist ) + { + if ( last > best_contour_first ) + last--; + else + last = best_contour_last; + break; + } + + p_last = last; + + if ( FT_CURVE_TAG( outline.tags[last] ) == + FT_CURVE_TAG_ON ) + { + p_last = last; + if ( p_first < 0 ) + p_first = last; + } + + } while ( last != best_segment_first ); + + best_y = points[first].y; + + best_segment_first = first; + best_segment_last = last; + + best_on_point_first = p_first; + best_on_point_last = p_last; + + break; + } + + } while ( last != best_segment_first ); + } } - } while ( prev != best_point ); + /* for computing blue zones, we add the y offset as returned */ + /* by the currently used OpenType feature -- for example, */ + /* superscript glyphs might be identical to subscript glyphs */ + /* with a vertical shift */ + best_y += y_offset; - do - { - if ( next < best_contour_last ) - next++; +#ifdef FT_DEBUG_LEVEL_TRACE + if ( num_idx == 1 ) + FT_TRACE5(( " U+%04lX: best_y = %5ld", ch, best_y )); else - next = best_contour_first; + FT_TRACE5(( " component %d of cluster starting with U+%04lX:" + " best_y = %5ld", i, ch, best_y )); +#endif - dist = FT_ABS( points[next].y - best_y ); - if ( dist > 5 ) - if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) - break; + /* now set the `round' flag depending on the segment's kind: */ + /* */ + /* - if the horizontal distance between the first and last */ + /* `on' point is larger than a heuristic threshold */ + /* we have a flat segment */ + /* - if either the first or the last point of the segment is */ + /* an `off' point, the segment is round, otherwise it is */ + /* flat */ + if ( best_on_point_first >= 0 && + best_on_point_last >= 0 && + ( FT_ABS( points[best_on_point_last].x - + points[best_on_point_first].x ) ) > + flat_threshold ) + round = 0; + else + round = FT_BOOL( + FT_CURVE_TAG( outline.tags[best_segment_first] ) != + FT_CURVE_TAG_ON || + FT_CURVE_TAG( outline.tags[best_segment_last] ) != + FT_CURVE_TAG_ON ); - if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) + if ( round && AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) { - best_on_point_last = next; - if ( best_on_point_first < 0 ) - best_on_point_first = next; + /* only use flat segments for a neutral blue zone */ + FT_TRACE5(( " (round, skipped)\n" )); + continue; } - } while ( next != best_point ); + FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); + } - /* now set the `round' flag depending on the segment's kind */ - /* (value 8 is heuristic) */ - if ( best_on_point_first >= 0 && - best_on_point_last >= 0 && - (FT_UInt)( FT_ABS( points[best_on_point_last].x - - points[best_on_point_first].x ) ) > - metrics->units_per_em / 8 ) - round = 0; + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) + { + if ( best_y > best_y_extremum ) + { + best_y_extremum = best_y; + best_round = round; + } + } else - round = FT_BOOL( - FT_CURVE_TAG( outline.tags[prev] ) != FT_CURVE_TAG_ON || - FT_CURVE_TAG( outline.tags[next] ) != FT_CURVE_TAG_ON ); + { + if ( best_y < best_y_extremum ) + { + best_y_extremum = best_y; + best_round = round; + } + } + + } /* end for loop */ - FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); + if ( !( best_y_extremum == FT_INT_MIN || + best_y_extremum == FT_INT_MAX ) ) + { + if ( best_round ) + rounds[num_rounds++] = best_y_extremum; + else + flats[num_flats++] = best_y_extremum; } - if ( round ) - rounds[num_rounds++] = best_y; - else - flats[num_flats++] = best_y; - } + } /* end while loop */ if ( num_flats == 0 && num_rounds == 0 ) { @@ -448,7 +876,7 @@ } else { - *blue_ref = flats[num_flats / 2]; + *blue_ref = flats [num_flats / 2]; *blue_shoot = rounds[num_rounds / 2]; } @@ -462,7 +890,8 @@ FT_Bool over_ref = FT_BOOL( shoot > ref ); - if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) + if ( ( AF_LATIN_IS_TOP_BLUE( bs ) || + AF_LATIN_IS_SUB_TOP_BLUE( bs) ) ^ over_ref ) { *blue_ref = *blue_shoot = ( shoot + ref ) / 2; @@ -472,22 +901,32 @@ } } + blue->ascender = ascender; + blue->descender = descender; + blue->flags = 0; - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) blue->flags |= AF_LATIN_BLUE_TOP; + if ( AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) + blue->flags |= AF_LATIN_BLUE_SUB_TOP; + if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) + blue->flags |= AF_LATIN_BLUE_NEUTRAL; /* * The following flag is used later to adjust the y and x scales * in order to optimize the pixel grid alignment of the top of small * letters. */ - if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) ) blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; FT_TRACE5(( " -> reference = %ld\n" " overshoot = %ld\n", *blue_ref, *blue_shoot )); - } + + } /* end for loop */ + + af_shaper_buf_destroy( face, shaper_buf ); FT_TRACE5(( "\n" )); @@ -501,26 +940,36 @@ af_latin_metrics_check_digits( AF_LatinMetrics metrics, FT_Face face ) { - FT_UInt i; FT_Bool started = 0, same_width = 1; FT_Fixed advance, old_advance = 0; + void* shaper_buf; + + /* in all supported charmaps, digits have character codes 0x30-0x39 */ + const char digits[] = "0 1 2 3 4 5 6 7 8 9"; + const char* p; - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) + + p = digits; + shaper_buf = af_shaper_buf_create( face ); + + while ( *p ) { - FT_UInt glyph_index; + FT_ULong glyph_index; + unsigned int num_idx; - glyph_index = FT_Get_Char_Index( face, i ); - if ( glyph_index == 0 ) + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) continue; - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + &advance, + NULL ); + if ( !glyph_index ) continue; if ( started ) @@ -538,6 +987,8 @@ } } + af_shaper_buf_destroy( face, shaper_buf ); + metrics->root.digits_have_same_width = same_width; } @@ -650,7 +1101,54 @@ else #endif if ( dim == AF_DIMENSION_VERT ) - scale = FT_MulDiv( scale, fitted, scaled ); + { + FT_Pos max_height; + FT_Pos dist; + FT_Fixed new_scale; + + + new_scale = FT_MulDiv( scale, fitted, scaled ); + + /* the scaling should not change the result by more than two pixels */ + max_height = metrics->units_per_em; + + for ( nn = 0; nn < Axis->blue_count; nn++ ) + { + max_height = FT_MAX( max_height, Axis->blues[nn].ascender ); + max_height = FT_MAX( max_height, -Axis->blues[nn].descender ); + } + + dist = FT_ABS( FT_MulFix( max_height, new_scale - scale ) ); + dist &= ~127; + + if ( dist == 0 ) + { + scale = new_scale; + + FT_TRACE5(( + "af_latin_metrics_scale_dim:" + " x height alignment (style `%s'):\n" + " " + " vertical scaling changed from %.4f to %.4f (by %d%%)\n" + "\n", + af_style_names[metrics->root.style_class->style], + axis->org_scale / 65536.0, + scale / 65536.0, + ( fitted - scaled ) * 100 / scaled )); + } +#ifdef FT_DEBUG_LEVEL_TRACE + else + { + FT_TRACE5(( + "af_latin_metrics_scale_dim:" + " x height alignment (style `%s'):\n" + " " + " excessive vertical scaling abandoned\n" + "\n", + af_style_names[metrics->root.style_class->style] )); + } +#endif + } } } } @@ -669,6 +1167,10 @@ metrics->root.scaler.y_delta = delta; } + FT_TRACE5(( "%s widths (style `%s')\n", + dim == AF_DIMENSION_HORZ ? "horizontal" : "vertical", + af_style_names[metrics->root.style_class->style] )); + /* scale the widths */ for ( nn = 0; nn < axis->width_count; nn++ ) { @@ -677,15 +1179,34 @@ width->cur = FT_MulFix( width->org, scale ); width->fit = width->cur; + + FT_TRACE5(( " %d scaled to %.2f\n", + width->org, + width->cur / 64.0 )); } + FT_TRACE5(( "\n" )); + /* an extra-light axis corresponds to a standard width that is */ /* smaller than 5/8 pixels */ axis->extra_light = (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( axis->extra_light ) + FT_TRACE5(( "`%s' style is extra light (at current resolution)\n" + "\n", + af_style_names[metrics->root.style_class->style] )); +#endif + if ( dim == AF_DIMENSION_VERT ) { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( axis->blue_count ) + FT_TRACE5(( "blue zones (style `%s')\n", + af_style_names[metrics->root.style_class->style] )); +#endif + /* scale the blue zones */ for ( nn = 0; nn < axis->blue_count; nn++ ) { @@ -759,6 +1280,61 @@ blue->flags |= AF_LATIN_BLUE_ACTIVE; } } + + /* use sub-top blue zone only if it doesn't overlap with */ + /* another (non-sup-top) blue zone; otherwise, the */ + /* effect would be similar to a neutral blue zone, which */ + /* is not desired here */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + FT_UInt i; + + + if ( !( blue->flags & AF_LATIN_BLUE_SUB_TOP ) ) + continue; + if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + for ( i = 0; i < axis->blue_count; i++ ) + { + AF_LatinBlue b = &axis->blues[i]; + + + if ( b->flags & AF_LATIN_BLUE_SUB_TOP ) + continue; + if ( !( b->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + if ( b->ref.fit <= blue->shoot.fit && + b->shoot.fit >= blue->ref.fit ) + { + blue->flags &= ~AF_LATIN_BLUE_ACTIVE; + break; + } + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + + + FT_TRACE5(( " reference %d: %d scaled to %.2f%s\n" + " overshoot %d: %d scaled to %.2f%s\n", + nn, + blue->ref.org, + blue->ref.fit / 64.0, + blue->flags & AF_LATIN_BLUE_ACTIVE ? "" + : " (inactive)", + nn, + blue->shoot.org, + blue->shoot.fit / 64.0, + blue->flags & AF_LATIN_BLUE_ACTIVE ? "" + : " (inactive)" )); + } +#endif } } @@ -778,6 +1354,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_latin_get_standard_widths( AF_LatinMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -793,14 +1385,17 @@ af_latin_hints_compute_segments( AF_GlyphHints hints, AF_Dimension dim ) { - AF_AxisHints axis = &hints->axis[dim]; - FT_Memory memory = hints->memory; - FT_Error error = FT_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; + AF_LatinMetrics metrics = (AF_LatinMetrics)hints->metrics; + AF_AxisHints axis = &hints->axis[dim]; + FT_Memory memory = hints->memory; + FT_Error error = FT_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; + + FT_Pos flat_threshold = FLAT_THRESHOLD( metrics->units_per_em ); FT_ZERO( &seg0 ); @@ -841,16 +1436,35 @@ /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { - AF_Point point = contour[0]; - AF_Point last = point->prev; - int on_edge = 0; - FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */ - FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ - FT_Bool passed; - + AF_Point point = contour[0]; + AF_Point last = point->prev; + int on_edge = 0; + + /* we call values measured along a segment (point->v) */ + /* `coordinates', and values orthogonal to it (point->u) */ + /* `positions' */ + FT_Pos min_pos = 32000; + FT_Pos max_pos = -32000; + FT_Pos min_coord = 32000; + FT_Pos max_coord = -32000; + FT_UShort min_flags = AF_FLAG_NONE; + FT_UShort max_flags = AF_FLAG_NONE; + FT_Pos min_on_coord = 32000; + FT_Pos max_on_coord = -32000; + + FT_Bool passed; + + AF_Segment prev_segment = NULL; + + FT_Pos prev_min_pos = min_pos; + FT_Pos prev_max_pos = max_pos; + FT_Pos prev_min_coord = min_coord; + FT_Pos prev_max_coord = max_coord; + FT_UShort prev_min_flags = min_flags; + FT_UShort prev_max_flags = max_flags; + FT_Pos prev_min_on_coord = min_on_coord; + FT_Pos prev_max_on_coord = max_on_coord; - if ( point == last ) /* skip singletons -- just in case */ - continue; if ( FT_ABS( last->out_dir ) == major_dir && FT_ABS( point->out_dir ) == major_dir ) @@ -881,40 +1495,181 @@ if ( on_edge ) { + /* get minimum and maximum position */ u = point->u; if ( u < min_pos ) min_pos = u; if ( u > max_pos ) max_pos = u; + /* get minimum and maximum coordinate together with flags */ + v = point->v; + if ( v < min_coord ) + { + min_coord = v; + min_flags = point->flags; + } + if ( v > max_coord ) + { + max_coord = v; + max_flags = point->flags; + } + + /* get minimum and maximum coordinate of `on' points */ + if ( !( point->flags & AF_FLAG_CONTROL ) ) + { + v = point->v; + if ( v < min_on_coord ) + min_on_coord = v; + if ( v > max_on_coord ) + max_on_coord = v; + } + if ( point->out_dir != segment_dir || point == last ) { - /* we are just leaving an edge; record a new segment! */ - segment->last = point; - segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); - - /* a segment is round if either its first or last point */ - /* is a control point */ - if ( ( segment->first->flags | point->flags ) & - AF_FLAG_CONTROL ) - segment->flags |= AF_EDGE_ROUND; + /* check whether the new segment's start point is identical to */ + /* the previous segment's end point; for example, this might */ + /* happen for spikes */ - /* compute segment size */ - min_pos = max_pos = point->v; + if ( !prev_segment || segment->first != prev_segment->last ) + { + /* points are different: we are just leaving an edge, thus */ + /* record a new segment */ + + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + + /* a segment is round if either its first or last point */ + /* is a control point, and the length of the on points */ + /* inbetween doesn't exceed a heuristic limit */ + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + segment->flags |= AF_EDGE_ROUND; + + segment->min_coord = (FT_Short)min_coord; + segment->max_coord = (FT_Short)max_coord; + segment->height = segment->max_coord - segment->min_coord; + + prev_segment = segment; + prev_min_pos = min_pos; + prev_max_pos = max_pos; + prev_min_coord = min_coord; + prev_max_coord = max_coord; + prev_min_flags = min_flags; + prev_max_flags = max_flags; + prev_min_on_coord = min_on_coord; + prev_max_on_coord = max_on_coord; + } + else + { + /* points are the same: we don't create a new segment but */ + /* merge the current segment with the previous one */ - v = segment->first->v; - if ( v < min_pos ) - min_pos = v; - if ( v > max_pos ) - max_pos = v; + if ( prev_segment->last->in_dir == point->in_dir ) + { + /* we have identical directions (this can happen for */ + /* degenerate outlines that move zig-zag along the main */ + /* axis without changing the coordinate value of the other */ + /* axis, and where the segments have just been merged): */ + /* unify segments */ + + /* update constraints */ - segment->min_coord = (FT_Short)min_pos; - segment->max_coord = (FT_Short)max_pos; - segment->height = (FT_Short)( segment->max_coord - - segment->min_coord ); + if ( prev_min_pos < min_pos ) + min_pos = prev_min_pos; + if ( prev_max_pos > max_pos ) + max_pos = prev_max_pos; + + if ( prev_min_coord < min_coord ) + { + min_coord = prev_min_coord; + min_flags = prev_min_flags; + } + if ( prev_max_coord > max_coord ) + { + max_coord = prev_max_coord; + max_flags = prev_max_flags; + } + + if ( prev_min_on_coord < min_on_coord ) + min_on_coord = prev_min_on_coord; + if ( prev_max_on_coord > max_on_coord ) + max_on_coord = prev_max_on_coord; + + prev_segment->last = point; + prev_segment->pos = (FT_Short)( ( min_pos + + max_pos ) >> 1 ); + + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + prev_segment->flags |= AF_EDGE_ROUND; + else + prev_segment->flags &= ~AF_EDGE_ROUND; + + prev_segment->min_coord = (FT_Short)min_coord; + prev_segment->max_coord = (FT_Short)max_coord; + prev_segment->height = prev_segment->max_coord - + prev_segment->min_coord; + } + else + { + /* we have different directions; use the properties of the */ + /* longer segment and discard the other one */ + + if ( FT_ABS( prev_max_coord - prev_min_coord ) > + FT_ABS( max_coord - min_coord ) ) + { + /* discard current segment */ + + if ( min_pos < prev_min_pos ) + prev_min_pos = min_pos; + if ( max_pos > prev_max_pos ) + prev_max_pos = max_pos; + + prev_segment->last = point; + prev_segment->pos = (FT_Short)( ( prev_min_pos + + prev_max_pos ) >> 1 ); + } + else + { + /* discard previous segment */ + + if ( prev_min_pos < min_pos ) + min_pos = prev_min_pos; + if ( prev_max_pos > max_pos ) + max_pos = prev_max_pos; + + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + segment->flags |= AF_EDGE_ROUND; + + segment->min_coord = (FT_Short)min_coord; + segment->max_coord = (FT_Short)max_coord; + segment->height = segment->max_coord - + segment->min_coord; + + *prev_segment = *segment; + + prev_min_pos = min_pos; + prev_max_pos = max_pos; + prev_min_coord = min_coord; + prev_max_coord = max_coord; + prev_min_flags = min_flags; + prev_max_flags = max_flags; + prev_min_on_coord = min_on_coord; + prev_max_on_coord = max_on_coord; + } + } + + axis->num_segments--; + } on_edge = 0; segment = NULL; + /* fall through */ } } @@ -927,22 +1682,63 @@ passed = 1; } - if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) + /* if we are not on an edge, check whether the major direction */ + /* coincides with the current point's `out' direction, or */ + /* whether we have a single-point contour */ + if ( !on_edge && + ( FT_ABS( point->out_dir ) == major_dir || + point == point->prev ) ) { /* this is the start of a new segment! */ segment_dir = (AF_Direction)point->out_dir; - /* clear all segment fields */ error = af_axis_hints_new_segment( axis, memory, &segment ); if ( error ) goto Exit; - segment[0] = seg0; - segment->dir = (FT_Char)segment_dir; - min_pos = max_pos = point->u; - segment->first = point; - segment->last = point; - on_edge = 1; + /* clear all segment fields */ + segment[0] = seg0; + + segment->dir = (FT_Char)segment_dir; + segment->first = point; + segment->last = point; + + /* `af_axis_hints_new_segment' reallocates memory, */ + /* thus we have to refresh the `prev_segment' pointer */ + if ( prev_segment ) + prev_segment = segment - 1; + + min_pos = max_pos = point->u; + min_coord = max_coord = point->v; + min_flags = max_flags = point->flags; + + if ( point->flags & AF_FLAG_CONTROL ) + { + min_on_coord = 32000; + max_on_coord = -32000; + } + else + min_on_coord = max_on_coord = point->v; + + on_edge = 1; + + if ( point == point->prev ) + { + /* we have a one-point segment: this is a one-point */ + /* contour with `in' and `out' direction set to */ + /* AF_DIR_NONE */ + segment->pos = (FT_Short)min_pos; + + if (point->flags & AF_FLAG_CONTROL) + segment->flags |= AF_EDGE_ROUND; + + segment->min_coord = (FT_Short)point->v; + segment->max_coord = (FT_Short)point->v; + segment->height = 0; + + on_edge = 0; + segment = NULL; + } } point = point->next; @@ -966,9 +1762,6 @@ FT_Pos last_v = last->v; - if ( first == last ) - continue; - if ( first_v < last_v ) { AF_Point p; @@ -1007,31 +1800,44 @@ } - /* Link segments to form stems and serifs. */ + /* Link segments to form stems and serifs. If `width_count' and */ + /* `widths' are non-zero, use them to fine-tune the scoring function. */ FT_LOCAL_DEF( void ) af_latin_hints_link_segments( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ) { AF_AxisHints axis = &hints->axis[dim]; AF_Segment segments = axis->segments; AF_Segment segment_limit = segments + axis->num_segments; - FT_Pos len_threshold, len_score; + FT_Pos len_threshold, len_score, dist_score, max_width; AF_Segment seg1, seg2; + if ( width_count ) + max_width = widths[width_count - 1].org; + else + max_width = 0; + + /* a heuristic value to set up a minimum value for overlapping */ len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); if ( len_threshold == 0 ) len_threshold = 1; + /* a heuristic value to weight lengths */ len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); + /* a heuristic value to weight distances (no call to */ + /* AF_LATIN_CONSTANT needed, since we work on multiples */ + /* of the stem width) */ + dist_score = 3000; + /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; /* search for stems having opposite directions, */ @@ -1045,10 +1851,9 @@ if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 ) { /* compute distance between the two segments */ - FT_Pos dist = pos2 - pos1; - FT_Pos min = seg1->min_coord; - FT_Pos max = seg1->max_coord; - FT_Pos len, score; + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len; if ( min < seg2->min_coord ) @@ -1058,15 +1863,49 @@ max = seg2->max_coord; /* compute maximum coordinate difference of the two segments */ + /* (this is, how much they overlap) */ len = max - min; if ( len >= len_threshold ) { - /* small coordinate differences cause a higher score, and */ - /* segments with a greater distance cause a higher score also */ - score = dist + len_score / len; + /* + * The score is the sum of two demerits indicating the + * `badness' of a fit, measured along the segments' main axis + * and orthogonal to it, respectively. + * + * o The less overlapping along the main axis, the worse it + * is, causing a larger demerit. + * + * o The nearer the orthogonal distance to a stem width, the + * better it is, causing a smaller demerit. For simplicity, + * however, we only increase the demerit for values that + * exceed the largest stem width. + */ + + FT_Pos dist = pos2 - pos1; + + FT_Pos dist_demerit, score; + + + if ( max_width ) + { + /* distance demerits are based on multiples of `max_width'; */ + /* we scale by 1024 for getting more precision */ + FT_Pos delta = ( dist << 10 ) / max_width - ( 1 << 10 ); + + + if ( delta > 10000 ) + dist_demerit = 32000; + else if ( delta > 0 ) + dist_demerit = delta * delta / dist_score; + else + dist_demerit = 0; + } + else + dist_demerit = dist; /* default if no widths available */ + + score = dist_demerit + len_score / len; /* and we search for the smallest score */ - /* of the sum of the two values */ if ( score < seg1->score ) { seg1->score = score; @@ -1111,6 +1950,12 @@ FT_Memory memory = hints->memory; AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; + AF_StyleClass style_class = hints->metrics->style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + FT_Bool top_to_bottom_hinting = 0; + AF_Segment segments = axis->segments; AF_Segment segment_limit = segments + axis->num_segments; AF_Segment seg; @@ -1133,6 +1978,9 @@ : AF_DIR_RIGHT; #endif + if ( dim == AF_DIMENSION_VERT ) + top_to_bottom_hinting = script_class->top_to_bottom_hinting; + /* * We ignore all segments that are less than 1 pixel in length * to avoid many problems with serif fonts. We compute the @@ -1174,7 +2022,10 @@ FT_Int ee; - if ( seg->height < segment_length_threshold ) + /* ignore too short segments and, in this loop, */ + /* one-point segments without a direction */ + if ( seg->height < segment_length_threshold || + seg->dir == AF_DIR_NONE ) continue; /* A special case for serif edges: If they are smaller than */ @@ -1210,6 +2061,7 @@ /* sort according to the position */ error = af_axis_hints_new_edge( axis, seg->pos, (AF_Direction)seg->dir, + top_to_bottom_hinting, memory, &edge ); if ( error ) goto Exit; @@ -1235,6 +2087,44 @@ } } + /* we loop again over all segments to catch one-point segments */ + /* without a direction: if possible, link them to existing edges */ + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = NULL; + FT_Int ee; + + + if ( seg->dir != AF_DIR_NONE ) + continue; + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold ) + { + found = edge; + break; + } + } + + /* one-point segments without a match are ignored */ + if ( found ) + { + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + /******************************************************************/ /* */ @@ -1385,7 +2275,7 @@ /* Example: the `c' in cour.pfa at size 13 */ if ( edge->serif && edge->link ) - edge->serif = 0; + edge->serif = NULL; } } @@ -1398,6 +2288,8 @@ FT_LOCAL_DEF( FT_Error ) af_latin_hints_detect_features( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ) { FT_Error error; @@ -1406,7 +2298,7 @@ error = af_latin_hints_compute_segments( hints, dim ); if ( !error ) { - af_latin_hints_link_segments( hints, dim ); + af_latin_hints_link_segments( hints, width_count, widths, dim ); error = af_latin_hints_compute_edges( hints, dim ); } @@ -1417,7 +2309,7 @@ /* Compute all edges which lie within blue zones. */ - FT_LOCAL_DEF( void ) + static void af_latin_hints_compute_blue_edges( AF_GlyphHints hints, AF_LatinMetrics metrics ) { @@ -1435,8 +2327,9 @@ for ( ; edge < edge_limit; edge++ ) { FT_UInt bb; - AF_Width best_blue = NULL; - FT_Pos best_dist; /* initial threshold */ + AF_Width best_blue = NULL; + FT_Bool best_blue_is_neutral = 0; + FT_Pos best_dist; /* initial threshold */ /* compute the initial threshold as a fraction of the EM size */ @@ -1450,24 +2343,27 @@ for ( bb = 0; bb < latin->blue_count; bb++ ) { AF_LatinBlue blue = latin->blues + bb; - FT_Bool is_top_blue, is_major_dir; + FT_Bool is_top_blue, is_neutral_blue, is_major_dir; /* skip inactive blue zones (i.e., those that are too large) */ if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) continue; - /* if it is a top zone, check for right edges -- if it is a bottom */ - /* zone, check for left edges */ - /* */ - /* of course, that's for TrueType */ - is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); - - /* if it is a top zone, the edge must be against the major */ - /* direction; if it is a bottom zone, it must be in the major */ - /* direction */ - if ( is_top_blue ^ is_major_dir ) + /* if it is a top zone, check for right edges (against the major */ + /* direction); if it is a bottom zone, check for left edges (in */ + /* the major direction) -- this assumes the TrueType convention */ + /* for the orientation of contours */ + is_top_blue = + (FT_Byte)( ( blue->flags & ( AF_LATIN_BLUE_TOP | + AF_LATIN_BLUE_SUB_TOP ) ) != 0 ); + is_neutral_blue = + (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_NEUTRAL ) != 0); + is_major_dir = + FT_BOOL( edge->dir == axis->major_dir ); + + /* neutral blue zones are handled for both directions */ + if ( is_top_blue ^ is_major_dir || is_neutral_blue ) { FT_Pos dist; @@ -1480,15 +2376,19 @@ dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { - best_dist = dist; - best_blue = &blue->ref; + best_dist = dist; + best_blue = &blue->ref; + best_blue_is_neutral = is_neutral_blue; } /* now compare it to the overshoot position and check whether */ /* the edge is rounded, and whether the edge is over the */ /* reference position of a top zone, or under the reference */ - /* position of a bottom zone */ - if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) + /* position of a bottom zone (provided we don't have a */ + /* neutral blue zone) */ + if ( edge->flags & AF_EDGE_ROUND && + dist != 0 && + !is_neutral_blue ) { FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); @@ -1502,8 +2402,9 @@ dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { - best_dist = dist; - best_blue = &blue->shoot; + best_dist = dist; + best_blue = &blue->shoot; + best_blue_is_neutral = is_neutral_blue; } } } @@ -1511,7 +2412,11 @@ } if ( best_blue ) + { edge->blue_edge = best_blue; + if ( best_blue_is_neutral ) + edge->flags |= AF_EDGE_NEUTRAL; + } } } @@ -1527,7 +2432,7 @@ FT_Face face = metrics->root.scaler.face; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* * correct x_scale and y_scale if needed, since they may have @@ -1575,11 +2480,20 @@ /* * In `light' hinting mode we disable horizontal hinting completely. * We also do it if the face is italic. + * + * However, if warping is enabled (which only works in `light' hinting + * mode), advance widths get adjusted, too. */ if ( mode == FT_RENDER_MODE_LIGHT || ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; +#ifdef AF_CONFIG_OPTION_USE_WARPER + /* get (global) warper flag */ + if ( !metrics->root.globals->module->warping ) + scaler_flags |= AF_SCALER_FLAG_NO_WARPER; +#endif + hints->scaler_flags = scaler_flags; hints->other_flags = other_flags; @@ -1600,13 +2514,13 @@ static FT_Pos af_latin_snap_width( AF_Width widths, - FT_Int count, + FT_UInt count, FT_Pos width ) { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; + FT_UInt n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; for ( n = 0; n < count; n++ ) @@ -1651,11 +2565,12 @@ af_latin_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) + FT_Pos base_delta, + FT_UInt base_flags, + FT_UInt stem_flags ) { - AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; - AF_LatinAxis axis = & metrics->axis[dim]; + AF_LatinMetrics metrics = (AF_LatinMetrics)hints->metrics; + AF_LatinAxis axis = &metrics->axis[dim]; FT_Pos dist = width; FT_Int sign = 0; FT_Int vertical = ( dim == AF_DIMENSION_VERT ); @@ -1728,7 +2643,39 @@ dist += delta; } else - dist = ( dist + 32 ) & ~63; + { + /* A stem's end position depends on two values: the start */ + /* position and the stem length. The former gets usually */ + /* rounded to the grid, while the latter gets rounded also if it */ + /* exceeds a certain length (see below in this function). This */ + /* `double rounding' can lead to a great difference to the */ + /* original, unhinted position; this normally doesn't matter for */ + /* large PPEM values, but for small sizes it can easily make */ + /* outlines collide. For this reason, we adjust the stem length */ + /* by a small amount depending on the PPEM value in case the */ + /* former and latter rounding both point into the same */ + /* direction. */ + + FT_Pos bdelta = 0; + + + if ( ( ( width > 0 ) && ( base_delta > 0 ) ) || + ( ( width < 0 ) && ( base_delta < 0 ) ) ) + { + FT_UInt ppem = metrics->root.scaler.face->size->metrics.x_ppem; + + + if ( ppem < 10 ) + bdelta = base_delta; + else if ( ppem < 30 ) + bdelta = ( base_delta * (FT_Pos)( 30 - ppem ) ) / 20; + + if ( bdelta < 0 ) + bdelta = -bdelta; + } + + dist = ( dist - bdelta + 32 ) & ~63; + } } } else @@ -1817,19 +2764,24 @@ AF_Edge base_edge, AF_Edge stem_edge ) { - FT_Pos dist = stem_edge->opos - base_edge->opos; + FT_Pos dist, base_delta; + FT_Pos fitted_width; - FT_Pos fitted_width = af_latin_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); + + dist = stem_edge->opos - base_edge->opos; + base_delta = base_edge->pos - base_edge->opos; + + fitted_width = af_latin_compute_stem_width( hints, dim, + dist, base_delta, + base_edge->flags, + stem_edge->flags ); stem_edge->pos = base_edge->pos + fitted_width; FT_TRACE5(( " 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 - hints->axis[dim].edges, stem_edge->opos / 64.0, stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); } @@ -1861,7 +2813,7 @@ /* The main grid-fitting routine. */ - FT_LOCAL_DEF( void ) + static void af_latin_hint_edges( AF_GlyphHints hints, AF_Dimension dim ) { @@ -1873,13 +2825,23 @@ AF_Edge anchor = NULL; FT_Int has_serifs = 0; + AF_StyleClass style_class = hints->metrics->style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + FT_Bool top_to_bottom_hinting = 0; + #ifdef FT_DEBUG_LEVEL_TRACE - FT_UInt num_actions = 0; + FT_UInt num_actions = 0; #endif - FT_TRACE5(( "%s edge hinting\n", - dim == AF_DIMENSION_VERT ? "horizontal" : "vertical" )); + FT_TRACE5(( "latin %s edge hinting (style `%s')\n", + dim == AF_DIMENSION_VERT ? "horizontal" : "vertical", + af_style_names[hints->metrics->style_class->style] )); + + if ( dim == AF_DIMENSION_VERT ) + top_to_bottom_hinting = script_class->top_to_bottom_hinting; /* we begin by aligning all stems relative to the blue zone */ /* if needed -- that's only for horizontal edges */ @@ -1895,14 +2857,41 @@ if ( edge->flags & AF_EDGE_DONE ) continue; - blue = edge->blue_edge; edge1 = NULL; edge2 = edge->link; + /* + * If a stem contains both a neutral and a non-neutral blue zone, + * skip the neutral one. Otherwise, outlines with different + * directions might be incorrectly aligned at the same vertical + * position. + * + * If we have two neutral blue zones, skip one of them. + * + */ + if ( edge->blue_edge && edge2 && edge2->blue_edge ) + { + FT_Byte neutral = edge->flags & AF_EDGE_NEUTRAL; + FT_Byte neutral2 = edge2->flags & AF_EDGE_NEUTRAL; + + + if ( neutral2 ) + { + edge2->blue_edge = NULL; + edge2->flags &= ~AF_EDGE_NEUTRAL; + } + else if ( neutral ) + { + edge->blue_edge = NULL; + edge->flags &= ~AF_EDGE_NEUTRAL; + } + } + + blue = edge->blue_edge; if ( blue ) edge1 = edge; - /* flip edges if the other stem is aligned to a blue zone */ + /* flip edges if the other edge is aligned to a blue zone */ else if ( edge2 && edge2->blue_edge ) { blue = edge2->blue_edge; @@ -1969,7 +2958,7 @@ /* this should not happen, but it's better to be safe */ if ( edge2->blue_edge ) { - FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2-edges )); + FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2 - edges )); af_latin_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; @@ -1989,10 +2978,10 @@ org_len = edge2->opos - edge->opos; - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, + edge->flags, + edge2->flags ); /* some voodoo to specially round edges for small stem widths; */ /* the idea is to align the center of a stem, then shifting */ @@ -2059,10 +3048,10 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, + edge->flags, + edge2->flags ); if ( edge2->flags & AF_EDGE_DONE ) { @@ -2120,10 +3109,10 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, + edge->flags, + edge2->flags ); cur_pos1 = FT_PIX_ROUND( org_pos ); delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center; @@ -2152,16 +3141,25 @@ edge->flags |= AF_EDGE_DONE; edge2->flags |= AF_EDGE_DONE; - if ( edge > edges && edge->pos < edge[-1].pos ) + if ( edge > edges && + ( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos ) + : ( edge->pos < edge[-1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[-1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[-1].pos; + edge->pos = edge[-1].pos; + } } } } @@ -2313,29 +3311,46 @@ #endif edge->flags |= AF_EDGE_DONE; - if ( edge > edges && edge->pos < edge[-1].pos ) + if ( edge > edges && + ( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos ) + : ( edge->pos < edge[-1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[-1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[-1].pos; + edge->pos = edge[-1].pos; + } } - if ( edge + 1 < edge_limit && - edge[1].flags & AF_EDGE_DONE && - edge->pos > edge[1].pos ) + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + ( top_to_bottom_hinting ? ( edge->pos < edge[1].pos ) + : ( edge->pos > edge[1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[1].pos; + edge->pos = edge[1].pos; + } } } } @@ -2351,13 +3366,16 @@ /* Apply the complete hinting algorithm to a latin glyph. */ static FT_Error - af_latin_hints_apply( AF_GlyphHints hints, + af_latin_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_LatinMetrics metrics ) { FT_Error error; int dim; + AF_LatinAxis axis; + error = af_glyph_hints_reload( hints, outline ); if ( error ) @@ -2365,24 +3383,35 @@ /* analyze glyph outline */ #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || - AF_HINTS_DO_HORIZONTAL( hints ) ) + if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) || + AF_HINTS_DO_HORIZONTAL( hints ) ) #else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) #endif { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); + axis = &metrics->axis[AF_DIMENSION_HORZ]; + error = af_latin_hints_detect_features( hints, + axis->width_count, + axis->widths, + AF_DIMENSION_HORZ ); if ( error ) goto Exit; } if ( AF_HINTS_DO_VERTICAL( hints ) ) { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + axis = &metrics->axis[AF_DIMENSION_VERT]; + error = af_latin_hints_detect_features( hints, + axis->width_count, + axis->widths, + AF_DIMENSION_VERT ); if ( error ) goto Exit; - af_latin_hints_compute_blue_edges( hints, metrics ); + /* apply blue zones to base characters only */ + if ( !( metrics->root.globals->glyph_styles[glyph_index] & AF_NONBASE ) ) + af_latin_hints_compute_blue_edges( hints, metrics ); } /* grid-fit the outline */ @@ -2390,7 +3419,8 @@ { #ifdef AF_CONFIG_OPTION_USE_WARPER if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2403,7 +3433,7 @@ scale, delta ); continue; } -#endif +#endif /* AF_CONFIG_OPTION_USE_WARPER */ if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) @@ -2414,6 +3444,7 @@ af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); } } + af_glyph_hints_save( hints, outline ); Exit: @@ -2430,56 +3461,20 @@ /*************************************************************************/ - /* XXX: this should probably fine tuned to differentiate better between */ - /* scripts... */ + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_latin_writing_system_class, - static const AF_Script_UniRangeRec af_latin_uniranges[] = - { - AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ - AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ - AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ - AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ - AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ - AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ - AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ - AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ - AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ - AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ - AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ - AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ - AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ - AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ - AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ - AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ - AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ - AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ - AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ - AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ - AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ - AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ - AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */ - AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ - AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ - AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ - AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ - AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_latin_script_class, - AF_SCRIPT_LATIN, - af_latin_uniranges, - 'o', + AF_WRITING_SYSTEM_LATIN, sizeof ( AF_LatinMetricsRec ), - (AF_Script_InitMetricsFunc) af_latin_metrics_init, - (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init, + (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, - (AF_Script_InitHintsFunc) af_latin_hints_init, - (AF_Script_ApplyHintsFunc) af_latin_hints_apply + (AF_WritingSystem_InitHintsFunc) af_latin_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_latin_hints_apply ) diff --git a/drivers/freetype/src/autofit/aflatin.h b/drivers/freetype/src/autofit/aflatin.h index d9170b3dcc..fe6bbd801a 100644 --- a/drivers/freetype/src/autofit/aflatin.h +++ b/drivers/freetype/src/autofit/aflatin.h @@ -2,9 +2,10 @@ /* */ /* aflatin.h */ /* */ -/* Auto-fitter hinting routines for latin script (specification). */ +/* Auto-fitter hinting routines for latin writing system */ +/* (specification). */ /* */ -/* Copyright 2003-2007, 2009, 2011-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,18 +17,17 @@ /***************************************************************************/ -#ifndef __AFLATIN_H__ -#define __AFLATIN_H__ +#ifndef AFLATIN_H_ +#define AFLATIN_H_ #include "afhints.h" FT_BEGIN_HEADER + /* the `latin' writing system */ - /* the latin-specific script class */ - - AF_DECLARE_SCRIPT_CLASS( af_latin_script_class ) + AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin_writing_system_class ) /* constants are given with units_per_em == 2048 in mind */ @@ -46,48 +46,40 @@ FT_BEGIN_HEADER /* * The following declarations could be embedded in the file `aflatin.c'; - * they have been made semi-public to allow alternate script hinters to - * re-use some of them. + * they have been made semi-public to allow alternate writing system + * hinters to re-use some of them. */ - /* Latin (global) metrics management */ - - enum - { - AF_LATIN_BLUE_CAPITAL_TOP, - AF_LATIN_BLUE_CAPITAL_BOTTOM, - AF_LATIN_BLUE_SMALL_F_TOP, - AF_LATIN_BLUE_SMALL_TOP, - AF_LATIN_BLUE_SMALL_BOTTOM, - AF_LATIN_BLUE_SMALL_MINOR, - - AF_LATIN_BLUE_MAX - }; - - -#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \ - (b) == AF_LATIN_BLUE_SMALL_F_TOP || \ - (b) == AF_LATIN_BLUE_SMALL_TOP ) +#define AF_LATIN_IS_TOP_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP ) +#define AF_LATIN_IS_SUB_TOP_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_SUB_TOP ) +#define AF_LATIN_IS_NEUTRAL_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL ) +#define AF_LATIN_IS_X_HEIGHT_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_X_HEIGHT ) +#define AF_LATIN_IS_LONG_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_LONG ) #define AF_LATIN_MAX_WIDTHS 16 -#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX - enum - { - AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */ - AF_LATIN_BLUE_TOP = 1 << 1, /* result of AF_LATIN_IS_TOP_BLUE */ - AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */ - /* optimization */ - AF_LATIN_BLUE_FLAG_MAX - }; +#define AF_LATIN_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */ +#define AF_LATIN_BLUE_TOP ( 1U << 1 ) /* we have a top blue zone */ +#define AF_LATIN_BLUE_SUB_TOP ( 1U << 2 ) /* we have a subscript top */ + /* blue zone */ +#define AF_LATIN_BLUE_NEUTRAL ( 1U << 3 ) /* we have neutral blue zone */ +#define AF_LATIN_BLUE_ADJUSTMENT ( 1U << 4 ) /* used for scale adjustment */ + /* optimization */ typedef struct AF_LatinBlueRec_ { AF_WidthRec ref; AF_WidthRec shoot; + FT_Pos ascender; + FT_Pos descender; FT_UInt flags; } AF_LatinBlueRec, *AF_LatinBlue; @@ -106,7 +98,7 @@ FT_BEGIN_HEADER /* ignored for horizontal metrics */ FT_UInt blue_count; - AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX]; + AF_LatinBlueRec blues[AF_BLUE_STRINGSET_MAX]; FT_Fixed org_scale; FT_Pos org_delta; @@ -116,9 +108,9 @@ FT_BEGIN_HEADER typedef struct AF_LatinMetricsRec_ { - AF_ScriptMetricsRec root; - FT_UInt units_per_em; - AF_LatinAxisRec axis[AF_DIMENSION_MAX]; + AF_StyleMetricsRec root; + FT_UInt units_per_em; + AF_LatinAxisRec axis[AF_DIMENSION_MAX]; } AF_LatinMetricsRec, *AF_LatinMetrics; @@ -148,15 +140,11 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - enum - { - AF_LATIN_HINTS_HORZ_SNAP = 1 << 0, /* enable stem width snapping */ - AF_LATIN_HINTS_VERT_SNAP = 1 << 1, /* enable stem height snapping */ - AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, /* enable stem width/height */ - /* adjustment */ - AF_LATIN_HINTS_MONO = 1 << 3 /* indicate monochrome */ - /* rendering */ - }; +#define AF_LATIN_HINTS_HORZ_SNAP ( 1U << 0 ) /* stem width snapping */ +#define AF_LATIN_HINTS_VERT_SNAP ( 1U << 1 ) /* stem height snapping */ +#define AF_LATIN_HINTS_STEM_ADJUST ( 1U << 2 ) /* stem width/height */ + /* adjustment */ +#define AF_LATIN_HINTS_MONO ( 1U << 3 ) /* monochrome rendering */ #define AF_LATIN_HINTS_DO_HORZ_SNAP( h ) \ @@ -174,7 +162,7 @@ FT_BEGIN_HEADER /* * The next functions shouldn't normally be exported. However, other - * scripts might like to use these functions as-is. + * writing systems might like to use these functions as-is. */ FT_LOCAL( FT_Error ) af_latin_hints_compute_segments( AF_GlyphHints hints, @@ -182,6 +170,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) af_latin_hints_link_segments( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ); FT_LOCAL( FT_Error ) @@ -190,13 +180,15 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) af_latin_hints_detect_features( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ); /* */ FT_END_HEADER -#endif /* __AFLATIN_H__ */ +#endif /* AFLATIN_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/aflatin2.c b/drivers/freetype/src/autofit/aflatin2.c index b1e9658d5d..5db4a41141 100644 --- a/drivers/freetype/src/autofit/aflatin2.c +++ b/drivers/freetype/src/autofit/aflatin2.c @@ -1,10 +1,15 @@ +/* ATTENTION: This file doesn't compile. It is only here as a reference */ +/* of an alternative latin hinting algorithm that was always */ +/* marked as experimental. */ + + /***************************************************************************/ /* */ /* aflatin2.c */ /* */ -/* Auto-fitter hinting routines for latin script (body). */ +/* Auto-fitter hinting routines for latin writing system (body). */ /* */ -/* Copyright 2003-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,8 +81,9 @@ AF_Scaler scaler = &dummy->root.scaler; - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); + glyph_index = FT_Get_Char_Index( + face, + metrics->root.style_class->standard_char ); if ( glyph_index == 0 ) goto Exit; @@ -94,7 +100,7 @@ scaler->render_mode = FT_RENDER_MODE_NORMAL; scaler->flags = 0; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy ); error = af_glyph_hints_reload( hints, &face->glyph->outline ); if ( error ) @@ -409,11 +415,11 @@ blue->flags |= AF_LATIN_BLUE_TOP; /* - * The following flags is used later to adjust the y and x scales + * The following flag is used later to adjust the y and x scales * in order to optimize the pixel grid alignment of the top of small * letters. */ - if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + if ( AF_LATIN_IS_X_HEIGHT_BLUE( bb ) ) blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; FT_TRACE5(( " -> reference = %ld\n" @@ -692,6 +698,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_latin2_get_standard_widths( AF_LatinMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -834,8 +856,8 @@ { AF_Point pt = first; AF_Point last = point; - AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); - AF_Flags f1; + FT_UInt f0 = pt->flags & AF_FLAG_CONTROL; + FT_UInt f1; segment->flags &= ~AF_EDGE_ROUND; @@ -843,7 +865,7 @@ for ( ; pt != last; f0 = f1 ) { pt = pt->next; - f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); + f1 = pt->flags & AF_FLAG_CONTROL; if ( !f0 && !f1 ) break; @@ -889,9 +911,6 @@ FT_Pos last_v = last->v; - if ( first == last ) - continue; - if ( first_v < last_v ) { p = first->prev; @@ -983,7 +1002,7 @@ #ifdef AF_SORT_SEGMENTS for ( seg1 = segments; seg1 < segment_mid; seg1++ ) { - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ ) @@ -991,9 +1010,7 @@ /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; for ( seg2 = segments; seg2 < segment_limit; seg2++ ) @@ -1052,7 +1069,7 @@ { if ( seg2->link != seg1 ) { - seg1->link = 0; + seg1->link = NULL; seg1->serif = seg2->link; } } @@ -1132,7 +1149,7 @@ for ( seg = segments; seg < segment_limit; seg++ ) { - AF_Edge found = 0; + AF_Edge found = NULL; FT_Int ee; @@ -1183,7 +1200,7 @@ /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, + error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, 0, memory, &edge ); if ( error ) goto Exit; @@ -1193,9 +1210,10 @@ edge->first = seg; edge->last = seg; - edge->fpos = seg->pos; edge->dir = seg->dir; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + edge->fpos = seg->pos; + edge->opos = FT_MulFix( seg->pos, scale ); + edge->pos = edge->opos; seg->edge_next = seg; } else @@ -1358,7 +1376,7 @@ /* Example: the `c' in cour.pfa at size 13 */ if ( edge->serif && edge->link ) - edge->serif = 0; + edge->serif = NULL; } } @@ -1385,7 +1403,7 @@ } - FT_LOCAL_DEF( void ) + static void af_latin2_hints_compute_blue_edges( AF_GlyphHints hints, AF_LatinMetrics metrics ) { @@ -1500,7 +1518,7 @@ FT_Face face = metrics->root.scaler.face; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* * correct x_scale and y_scale if needed, since they may have @@ -1516,9 +1534,7 @@ #if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) - { metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; - } #endif scaler_flags = hints->scaler_flags; @@ -1555,6 +1571,12 @@ ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; +#ifdef AF_CONFIG_OPTION_USE_WARPER + /* get (global) warper flag */ + if ( !metrics->root.globals->module->warping ) + scaler_flags |= AF_SCALER_FLAG_NO_WARPER; +#endif + hints->scaler_flags = scaler_flags; hints->other_flags = other_flags; @@ -1575,13 +1597,13 @@ static FT_Pos af_latin2_snap_width( AF_Width widths, - FT_Int count, + FT_UInt count, FT_Pos width ) { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; + FT_UInt n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; for ( n = 0; n < count; n++ ) @@ -1624,8 +1646,8 @@ af_latin2_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) + FT_UInt base_flags, + FT_UInt stem_flags ) { AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; AF_LatinAxis axis = & metrics->axis[dim]; @@ -1796,10 +1818,9 @@ { FT_Pos dist = stem_edge->opos - base_edge->opos; - FT_Pos fitted_width = af_latin2_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); + FT_Pos fitted_width = af_latin2_compute_stem_width( hints, dim, dist, + base_edge->flags, + stem_edge->flags ); stem_edge->pos = base_edge->pos + fitted_width; @@ -1833,7 +1854,7 @@ /*************************************************************************/ - FT_LOCAL_DEF( void ) + static void af_latin2_hint_edges( AF_GlyphHints hints, AF_Dimension dim ) { @@ -1841,7 +1862,7 @@ AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; AF_Edge edge; - AF_Edge anchor = 0; + AF_Edge anchor = NULL; FT_Int has_serifs = 0; FT_Pos anchor_drift = 0; @@ -1945,10 +1966,9 @@ org_len = edge2->opos - edge->opos; - cur_len = af_latin2_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin2_compute_stem_width( hints, dim, org_len, + edge->flags, + edge2->flags ); if ( cur_len <= 64 ) u_off = d_off = 32; else @@ -2010,10 +2030,9 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin2_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin2_compute_stem_width( hints, dim, org_len, + edge->flags, + edge2->flags ); org_left = org_pos + ( ( org_len - cur_len ) >> 1 ); org_right = org_pos + ( ( org_len + cur_len ) >> 1 ); @@ -2302,13 +2321,16 @@ static FT_Error - af_latin2_hints_apply( AF_GlyphHints hints, + af_latin2_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_LatinMetrics metrics ) { FT_Error error; int dim; + FT_UNUSED( glyph_index ); + error = af_glyph_hints_reload( hints, outline ); if ( error ) @@ -2316,8 +2338,9 @@ /* analyze glyph outline */ #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || - AF_HINTS_DO_HORIZONTAL( hints ) ) + if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) || + AF_HINTS_DO_HORIZONTAL( hints ) ) #else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) #endif @@ -2340,8 +2363,9 @@ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2352,7 +2376,7 @@ af_glyph_hints_scale_dim( hints, dim, scale, delta ); continue; } -#endif +#endif /* AF_CONFIG_OPTION_USE_WARPER */ if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) @@ -2379,27 +2403,20 @@ /*************************************************************************/ - static const AF_Script_UniRangeRec af_latin2_uniranges[] = - { - AF_UNIRANGE_REC( 32UL, 127UL ), /* TODO: Add new Unicode ranges here! */ - AF_UNIRANGE_REC( 160UL, 255UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_latin2_writing_system_class, - AF_DEFINE_SCRIPT_CLASS( af_latin2_script_class, - AF_SCRIPT_LATIN2, - af_latin2_uniranges, - 'o', + AF_WRITING_SYSTEM_LATIN2, sizeof ( AF_LatinMetricsRec ), - (AF_Script_InitMetricsFunc) af_latin2_metrics_init, - (AF_Script_ScaleMetricsFunc)af_latin2_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init, + (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, - (AF_Script_InitHintsFunc) af_latin2_hints_init, - (AF_Script_ApplyHintsFunc) af_latin2_hints_apply + (AF_WritingSystem_InitHintsFunc) af_latin2_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_latin2_hints_apply ) diff --git a/drivers/freetype/src/autofit/aflatin2.h b/drivers/freetype/src/autofit/aflatin2.h index cbfa395522..f83f704289 100644 --- a/drivers/freetype/src/autofit/aflatin2.h +++ b/drivers/freetype/src/autofit/aflatin2.h @@ -1,10 +1,16 @@ +/* ATTENTION: This file doesn't compile. It is only here as a reference */ +/* of an alternative latin hinting algorithm that was always */ +/* marked as experimental. */ + + /***************************************************************************/ /* */ /* aflatin2.h */ /* */ -/* Auto-fitter hinting routines for latin script (specification). */ +/* Auto-fitter hinting routines for latin writing system */ +/* (specification). */ /* */ -/* Copyright 2003-2007, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +22,8 @@ /***************************************************************************/ -#ifndef __AFLATIN2_H__ -#define __AFLATIN2_H__ +#ifndef AFLATIN2_H_ +#define AFLATIN2_H_ #include "afhints.h" @@ -25,15 +31,16 @@ FT_BEGIN_HEADER - /* the latin-specific script class */ + /* the `latin' writing system */ + + AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin2_writing_system_class ) - AF_DECLARE_SCRIPT_CLASS( af_latin2_script_class ) /* */ FT_END_HEADER -#endif /* __AFLATIN_H__ */ +#endif /* AFLATIN_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afloader.c b/drivers/freetype/src/autofit/afloader.c index 17a6fb7c3b..26bba065bb 100644 --- a/drivers/freetype/src/autofit/afloader.c +++ b/drivers/freetype/src/autofit/afloader.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (body). */ /* */ -/* Copyright 2003-2009, 2011-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,42 +21,36 @@ #include "afhints.h" #include "aferrors.h" #include "afmodule.h" +#include "afpic.h" + +#include FT_INTERNAL_CALC_H /* Initialize glyph loader. */ - FT_LOCAL_DEF( FT_Error ) - af_loader_init( AF_Module module ) + FT_LOCAL_DEF( void ) + af_loader_init( AF_Loader loader, + AF_GlyphHints hints ) { - AF_Loader loader = module->loader; - FT_Memory memory = module->root.library->memory; - - FT_ZERO( loader ); - af_glyph_hints_init( &loader->hints, memory ); -#ifdef FT_DEBUG_AUTOFIT - _af_debug_hints = &loader->hints; -#endif - return FT_GlyphLoader_New( memory, &loader->gloader ); + loader->hints = hints; } /* Reset glyph loader and compute globals if necessary. */ FT_LOCAL_DEF( FT_Error ) - af_loader_reset( AF_Module module, + af_loader_reset( AF_Loader loader, + AF_Module module, FT_Face face ) { - FT_Error error = FT_Err_Ok; - AF_Loader loader = module->loader; + FT_Error error = FT_Err_Ok; loader->face = face; loader->globals = (AF_FaceGlobals)face->autohint.data; - FT_GlyphLoader_Rewind( loader->gloader ); - if ( loader->globals == NULL ) { error = af_face_globals_new( face, &loader->globals, module ); @@ -76,42 +70,43 @@ /* Finalize glyph loader. */ FT_LOCAL_DEF( void ) - af_loader_done( AF_Module module ) + af_loader_done( AF_Loader loader ) { - AF_Loader loader = module->loader; - - - af_glyph_hints_done( &loader->hints ); - loader->face = NULL; loader->globals = NULL; - -#ifdef FT_DEBUG_AUTOFIT - _af_debug_hints = NULL; -#endif - FT_GlyphLoader_Done( loader->gloader ); - loader->gloader = NULL; + loader->hints = NULL; } - /* Load a single glyph component. This routine calls itself */ - /* recursively, if necessary, and does the main work of */ - /* `af_loader_load_glyph.' */ +#define af_intToFixed( i ) \ + ( (FT_Fixed)( (FT_UInt32)(i) << 16 ) ) +#define af_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) +#define af_floatToFixed( f ) \ + ( (FT_Fixed)( (f) * 65536.0 + 0.5 ) ) + + + /* Do the main work of `af_loader_load_glyph'. Note that we never */ + /* have to deal with composite glyphs as those get loaded into */ + /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */ + /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies */ + /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called. */ static FT_Error af_loader_load_g( AF_Loader loader, AF_Scaler scaler, FT_UInt glyph_index, - FT_Int32 load_flags, - FT_UInt depth ) + FT_Int32 load_flags ) { + AF_Module module = loader->globals->module; + FT_Error error; FT_Face face = loader->face; - FT_GlyphLoader gloader = loader->gloader; - AF_ScriptMetrics metrics = loader->metrics; - AF_GlyphHints hints = &loader->hints; + AF_StyleMetrics metrics = loader->metrics; + AF_GlyphHints hints = loader->hints; FT_GlyphSlot slot = face->glyph; FT_Slot_Internal internal = slot->internal; + FT_GlyphLoader gloader = internal->loader; FT_Int32 flags; @@ -120,6 +115,132 @@ if ( error ) goto Exit; + /* + * Apply stem darkening (emboldening) here before hints are applied to + * the outline. Glyphs are scaled down proportionally to the + * emboldening so that curve points don't fall outside their precomputed + * blue zones. + * + * Any emboldening done by the font driver (e.g., the CFF driver) + * doesn't reach here because the autohinter loads the unprocessed + * glyphs in font units for analysis (functions `af_*_metrics_init_*') + * and then above to prepare it for the rasterizers by itself, + * independently of the font driver. So emboldening must be done here, + * within the autohinter. + * + * All glyphs to be autohinted pass through here one by one. The + * standard widths can therefore change from one glyph to the next, + * depending on what script a glyph is assigned to (each script has its + * own set of standard widths and other metrics). The darkening amount + * must therefore be recomputed for each size and + * `standard_{vertical,horizontal}_width' change. + */ + if ( !module->no_stem_darkening ) + { + AF_FaceGlobals globals = loader->globals; + AF_WritingSystemClass writing_system_class; + + FT_Pos stdVW = 0; + FT_Pos stdHW = 0; + + FT_Bool size_changed = face->size->metrics.x_ppem + != globals->stem_darkening_for_ppem; + + FT_Fixed em_size = af_intToFixed( face->units_per_EM ); + FT_Fixed em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size ); + + FT_Matrix scale_down_matrix = { 0x10000L, 0, 0, 0x10000L }; + + + /* Skip stem darkening for broken fonts. */ + if ( !face->units_per_EM ) + goto After_Emboldening; + + /* + * We depend on the writing system (script analyzers) to supply + * standard widths for the script of the glyph we are looking at. If + * it can't deliver, stem darkening is effectively disabled. + */ + writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[metrics->style_class->writing_system]; + + if ( writing_system_class->style_metrics_getstdw ) + writing_system_class->style_metrics_getstdw( metrics, + &stdHW, + &stdVW ); + else + goto After_Emboldening; + + + if ( size_changed || + ( stdVW > 0 && stdVW != globals->standard_vertical_width ) ) + { + FT_Fixed darken_by_font_units_x, darken_x; + + + darken_by_font_units_x = + af_intToFixed( af_loader_compute_darkening( loader, + face, + stdVW ) ); + darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x, + face->size->metrics.x_scale ), + em_ratio ); + + globals->standard_vertical_width = stdVW; + globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; + globals->darken_x = af_fixedToInt( darken_x ); + } + + if ( size_changed || + ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) ) + { + FT_Fixed darken_by_font_units_y, darken_y; + + + darken_by_font_units_y = + af_intToFixed( af_loader_compute_darkening( loader, + face, + stdHW ) ); + darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y, + face->size->metrics.y_scale ), + em_ratio ); + + globals->standard_horizontal_width = stdHW; + globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; + globals->darken_y = af_fixedToInt( darken_y ); + + /* + * Scale outlines down on the Y-axis to keep them inside their blue + * zones. The stronger the emboldening, the stronger the + * downscaling (plus heuristical padding to prevent outlines still + * falling out their zones due to rounding). + * + * Reason: `FT_Outline_Embolden' works by shifting the rightmost + * points of stems farther to the right, and topmost points farther + * up. This positions points on the Y-axis outside their + * pre-computed blue zones and leads to distortion when applying the + * hints in the code further below. Code outside this emboldening + * block doesn't know we are presenting it with modified outlines + * the analyzer didn't see! + * + * An unfortunate side effect of downscaling is that the emboldening + * effect is slightly decreased. The loss becomes more pronounced + * versus the CFF driver at smaller sizes, e.g., at 9ppem and below. + */ + globals->scale_down_factor = + FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ), + em_size ); + } + + FT_Outline_EmboldenXY( &slot->outline, + globals->darken_x, + globals->darken_y ); + + scale_down_matrix.yy = globals->scale_down_factor; + FT_Outline_Transform( &slot->outline, &scale_down_matrix ); + } + + After_Emboldening: loader->transformed = internal->glyph_transformed; if ( loader->transformed ) { @@ -130,8 +251,8 @@ loader->trans_delta = internal->glyph_delta; inverse = loader->trans_matrix; - FT_Matrix_Invert( &inverse ); - FT_Vector_Transform( &loader->trans_delta, &inverse ); + if ( !FT_Matrix_Invert( &inverse ) ) + FT_Vector_Transform( &loader->trans_delta, &inverse ); } switch ( slot->format ) @@ -143,29 +264,6 @@ loader->trans_delta.x, loader->trans_delta.y ); - /* copy the outline points in the loader's current */ - /* extra points which are used to keep original glyph coordinates */ - error = FT_GLYPHLOADER_CHECK_POINTS( gloader, - slot->outline.n_points + 4, - slot->outline.n_contours ); - if ( error ) - goto Exit; - - FT_ARRAY_COPY( gloader->current.outline.points, - slot->outline.points, - slot->outline.n_points ); - - FT_ARRAY_COPY( gloader->current.outline.contours, - slot->outline.contours, - slot->outline.n_contours ); - - FT_ARRAY_COPY( gloader->current.outline.tags, - slot->outline.tags, - slot->outline.n_points ); - - gloader->current.outline.n_points = slot->outline.n_points; - gloader->current.outline.n_contours = slot->outline.n_contours; - /* compute original horizontal phantom points (and ignore */ /* vertical ones) */ loader->pp1.x = hints->x_delta; @@ -180,10 +278,21 @@ /* now load the slot image into the auto-outline and run the */ /* automatic hinting process */ - if ( metrics->clazz->script_hints_apply ) - metrics->clazz->script_hints_apply( hints, - &gloader->current.outline, - metrics ); + { +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = loader->globals; +#endif + AF_StyleClass style_class = metrics->style_class; + AF_WritingSystemClass writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + + + if ( writing_system_class->style_hints_apply ) + writing_system_class->style_hints_apply( glyph_index, + hints, + &gloader->base.outline, + metrics ); + } /* we now need to adjust the metrics according to the change in */ /* width/positioning that occurred during the hinting process */ @@ -256,133 +365,6 @@ slot->rsb_delta = loader->pp2.x - pp2x; } - /* good, we simply add the glyph to our loader's base */ - FT_GlyphLoader_Add( gloader ); - break; - - case FT_GLYPH_FORMAT_COMPOSITE: - { - FT_UInt nn, num_subglyphs = slot->num_subglyphs; - FT_UInt num_base_subgs, start_point; - FT_SubGlyph subglyph; - - - start_point = gloader->base.outline.n_points; - - /* first of all, copy the subglyph descriptors in the glyph loader */ - error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs ); - if ( error ) - goto Exit; - - FT_ARRAY_COPY( gloader->current.subglyphs, - slot->subglyphs, - num_subglyphs ); - - gloader->current.num_subglyphs = num_subglyphs; - num_base_subgs = gloader->base.num_subglyphs; - - /* now read each subglyph independently */ - for ( nn = 0; nn < num_subglyphs; nn++ ) - { - FT_Vector pp1, pp2; - FT_Pos x, y; - FT_UInt num_points, num_new_points, num_base_points; - - - /* gloader.current.subglyphs can change during glyph loading due */ - /* to re-allocation -- we must recompute the current subglyph on */ - /* each iteration */ - subglyph = gloader->base.subglyphs + num_base_subgs + nn; - - pp1 = loader->pp1; - pp2 = loader->pp2; - - num_base_points = gloader->base.outline.n_points; - - error = af_loader_load_g( loader, scaler, subglyph->index, - load_flags, depth + 1 ); - if ( error ) - goto Exit; - - /* recompute subglyph pointer */ - subglyph = gloader->base.subglyphs + num_base_subgs + nn; - - if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) - { - pp1 = loader->pp1; - pp2 = loader->pp2; - } - else - { - loader->pp1 = pp1; - loader->pp2 = pp2; - } - - num_points = gloader->base.outline.n_points; - num_new_points = num_points - num_base_points; - - /* now perform the transformation required for this subglyph */ - - if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | - FT_SUBGLYPH_FLAG_XY_SCALE | - FT_SUBGLYPH_FLAG_2X2 ) ) - { - FT_Vector* cur = gloader->base.outline.points + - num_base_points; - FT_Vector* limit = cur + num_new_points; - - - for ( ; cur < limit; cur++ ) - FT_Vector_Transform( cur, &subglyph->transform ); - } - - /* apply offset */ - - if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) - { - FT_Int k = subglyph->arg1; - FT_UInt l = subglyph->arg2; - FT_Vector* p1; - FT_Vector* p2; - - - if ( start_point + k >= num_base_points || - l >= (FT_UInt)num_new_points ) - { - error = FT_THROW( Invalid_Composite ); - goto Exit; - } - - l += num_base_points; - - /* for now, only use the current point coordinates; */ - /* we eventually may consider another approach */ - p1 = gloader->base.outline.points + start_point + k; - p2 = gloader->base.outline.points + start_point + l; - - x = p1->x - p2->x; - y = p1->y - p2->y; - } - else - { - x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; - y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; - - x = FT_PIX_ROUND( x ); - y = FT_PIX_ROUND( y ); - } - - { - FT_Outline dummy = gloader->base.outline; - - - dummy.points += num_base_points; - dummy.n_points = (short)num_new_points; - - FT_Outline_Translate( &dummy, x, y ); - } - } - } break; default: @@ -391,7 +373,6 @@ } Hint_Metrics: - if ( depth == 0 ) { FT_BBox bbox; FT_Vector vvector; @@ -466,18 +447,14 @@ slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); - /* now copy outline into glyph slot */ - FT_GlyphLoader_Rewind( internal->loader ); - error = FT_GlyphLoader_CopyPoints( internal->loader, gloader ); - if ( error ) - goto Exit; - +#if 0 /* reassign all outline fields except flags to protect them */ slot->outline.n_contours = internal->loader->base.outline.n_contours; slot->outline.n_points = internal->loader->base.outline.n_points; slot->outline.points = internal->loader->base.outline.points; slot->outline.tags = internal->loader->base.outline.tags; slot->outline.contours = internal->loader->base.outline.contours; +#endif slot->format = FT_GLYPH_FORMAT_OUTLINE; } @@ -490,19 +467,19 @@ /* Load a glyph. */ FT_LOCAL_DEF( FT_Error ) - af_loader_load_glyph( AF_Module module, + af_loader_load_glyph( AF_Loader loader, + AF_Module module, FT_Face face, FT_UInt gindex, FT_Int32 load_flags ) { FT_Error error; FT_Size size = face->size; - AF_Loader loader = module->loader; AF_ScalerRec scaler; if ( !size ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Size_Handle ); FT_ZERO( &scaler ); @@ -515,42 +492,50 @@ scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); scaler.flags = 0; /* XXX: fix this */ - error = af_loader_reset( module, face ); + error = af_loader_reset( loader, module, face ); if ( !error ) { - AF_ScriptMetrics metrics; - FT_UInt options = 0; + AF_StyleMetrics metrics; + FT_UInt options = AF_STYLE_NONE_DFLT; #ifdef FT_OPTION_AUTOFIT2 - /* XXX: undocumented hook to activate the latin2 hinter */ + /* XXX: undocumented hook to activate the latin2 writing system */ if ( load_flags & ( 1UL << 20 ) ) - options = 2; + options = AF_STYLE_LTN2_DFLT; #endif error = af_face_globals_get_metrics( loader->globals, gindex, options, &metrics ); if ( !error ) { +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = loader->globals; +#endif + AF_StyleClass style_class = metrics->style_class; + AF_WritingSystemClass writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + + loader->metrics = metrics; - if ( metrics->clazz->script_metrics_scale ) - metrics->clazz->script_metrics_scale( metrics, &scaler ); + if ( writing_system_class->style_metrics_scale ) + writing_system_class->style_metrics_scale( metrics, &scaler ); else metrics->scaler = scaler; load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; load_flags &= ~FT_LOAD_RENDER; - if ( metrics->clazz->script_hints_init ) + if ( writing_system_class->style_hints_init ) { - error = metrics->clazz->script_hints_init( &loader->hints, - metrics ); + error = writing_system_class->style_hints_init( loader->hints, + metrics ); if ( error ) goto Exit; } - error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); + error = af_loader_load_g( loader, &scaler, gindex, load_flags ); } } Exit: @@ -558,4 +543,134 @@ } + /* + * Compute amount of font units the face should be emboldened by, in + * analogy to the CFF driver's `cf2_computeDarkening' function. See there + * for details of the algorithm. + * + * XXX: Currently a crude adaption of the original algorithm. Do better? + */ + FT_LOCAL_DEF( FT_Int32 ) + af_loader_compute_darkening( AF_Loader loader, + FT_Face face, + FT_Pos standard_width ) + { + AF_Module module = loader->globals->module; + + FT_UShort units_per_EM; + FT_Fixed ppem, em_ratio; + FT_Fixed stem_width, stem_width_per_1000, scaled_stem, darken_amount; + FT_Int log_base_2; + FT_Int x1, y1, x2, y2, x3, y3, x4, y4; + + + ppem = FT_MAX( af_intToFixed( 4 ), + af_intToFixed( face->size->metrics.x_ppem ) ); + units_per_EM = face->units_per_EM; + + em_ratio = FT_DivFix( af_intToFixed( 1000 ), + af_intToFixed ( units_per_EM ) ); + if ( em_ratio < af_floatToFixed( .01 ) ) + { + /* If something goes wrong, don't embolden. */ + return 0; + } + + x1 = module->darken_params[0]; + y1 = module->darken_params[1]; + x2 = module->darken_params[2]; + y2 = module->darken_params[3]; + x3 = module->darken_params[4]; + y3 = module->darken_params[5]; + x4 = module->darken_params[6]; + y4 = module->darken_params[7]; + + if ( standard_width <= 0 ) + { + stem_width = af_intToFixed( 75 ); /* taken from cf2font.c */ + stem_width_per_1000 = stem_width; + } + else + { + stem_width = af_intToFixed( standard_width ); + stem_width_per_1000 = FT_MulFix( stem_width, em_ratio ); + } + + log_base_2 = FT_MSB( (FT_UInt32)stem_width_per_1000 ) + + FT_MSB( (FT_UInt32)ppem ); + + if ( log_base_2 >= 46 ) + { + /* possible overflow */ + scaled_stem = af_intToFixed( x4 ); + } + else + scaled_stem = FT_MulFix( stem_width_per_1000, ppem ); + + /* now apply the darkening parameters */ + if ( scaled_stem < af_intToFixed( x1 ) ) + darken_amount = FT_DivFix( af_intToFixed( y1 ), ppem ); + + else if ( scaled_stem < af_intToFixed( x2 ) ) + { + FT_Int xdelta = x2 - x1; + FT_Int ydelta = y2 - y1; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x1 ), ppem ); + + + if ( !xdelta ) + goto Try_x3; + + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y1 ), ppem ); + } + + else if ( scaled_stem < af_intToFixed( x3 ) ) + { + Try_x3: + { + FT_Int xdelta = x3 - x2; + FT_Int ydelta = y3 - y2; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x2 ), ppem ); + + + if ( !xdelta ) + goto Try_x4; + + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y2 ), ppem ); + } + } + + else if ( scaled_stem < af_intToFixed( x4 ) ) + { + Try_x4: + { + FT_Int xdelta = x4 - x3; + FT_Int ydelta = y4 - y3; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x3 ), ppem ); + + + if ( !xdelta ) + goto Use_y4; + + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y3 ), ppem ); + } + } + + else + { + Use_y4: + darken_amount = FT_DivFix( af_intToFixed( y4 ), ppem ); + } + + /* Convert darken_amount from per 1000 em to true character space. */ + return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) ); + } + + /* END */ diff --git a/drivers/freetype/src/autofit/afloader.h b/drivers/freetype/src/autofit/afloader.h index 1f34d17cce..0062eb9b07 100644 --- a/drivers/freetype/src/autofit/afloader.h +++ b/drivers/freetype/src/autofit/afloader.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (specification). */ /* */ -/* Copyright 2003-2005, 2011-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,17 +16,16 @@ /***************************************************************************/ -#ifndef __AFLOADER_H__ -#define __AFLOADER_H__ +#ifndef AFLOADER_H_ +#define AFLOADER_H_ #include "afhints.h" +#include "afmodule.h" #include "afglobal.h" FT_BEGIN_HEADER - typedef struct AF_ModuleRec_* AF_Module; - /* * The autofitter module's (global) data structure to communicate with * actual fonts. If necessary, `local' data like the current face, the @@ -42,9 +41,8 @@ FT_BEGIN_HEADER AF_FaceGlobals globals; /* current glyph data */ - FT_GlyphLoader gloader; - AF_GlyphHintsRec hints; - AF_ScriptMetrics metrics; + AF_GlyphHints hints; + AF_StyleMetrics metrics; FT_Bool transformed; FT_Matrix trans_matrix; FT_Vector trans_delta; @@ -55,31 +53,39 @@ FT_BEGIN_HEADER } AF_LoaderRec, *AF_Loader; - FT_LOCAL( FT_Error ) - af_loader_init( AF_Module module ); + FT_LOCAL( void ) + af_loader_init( AF_Loader loader, + AF_GlyphHints hints ); FT_LOCAL( FT_Error ) - af_loader_reset( AF_Module module, + af_loader_reset( AF_Loader loader, + AF_Module module, FT_Face face ); FT_LOCAL( void ) - af_loader_done( AF_Module module ); + af_loader_done( AF_Loader loader ); FT_LOCAL( FT_Error ) - af_loader_load_glyph( AF_Module module, + af_loader_load_glyph( AF_Loader loader, + AF_Module module, FT_Face face, FT_UInt gindex, FT_Int32 load_flags ); + FT_LOCAL_DEF( FT_Int32 ) + af_loader_compute_darkening( AF_Loader loader, + FT_Face face, + FT_Pos standard_width ); + /* */ FT_END_HEADER -#endif /* __AFLOADER_H__ */ +#endif /* AFLOADER_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afmodule.c b/drivers/freetype/src/autofit/afmodule.c index b1bb5ee0ed..4127382c00 100644 --- a/drivers/freetype/src/autofit/afmodule.c +++ b/drivers/freetype/src/autofit/afmodule.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module implementation (body). */ /* */ -/* Copyright 2003-2006, 2009, 2011-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,10 +23,35 @@ #include "afpic.h" #ifdef FT_DEBUG_AUTOFIT - int _af_debug_disable_horz_hints; - int _af_debug_disable_vert_hints; - int _af_debug_disable_blue_hints; - void* _af_debug_hints; + +#ifndef FT_MAKE_OPTION_SINGLE_OBJECT + +#ifdef __cplusplus + extern "C" { +#endif + extern void + af_glyph_hints_dump_segments( AF_GlyphHints hints, + FT_Bool to_stdout ); + extern void + af_glyph_hints_dump_points( AF_GlyphHints hints, + FT_Bool to_stdout ); + extern void + af_glyph_hints_dump_edges( AF_GlyphHints hints, + FT_Bool to_stdout ); +#ifdef __cplusplus + } +#endif + +#endif + + int _af_debug_disable_horz_hints; + int _af_debug_disable_vert_hints; + int _af_debug_disable_blue_hints; + + /* we use a global object instead of a local one for debugging */ + AF_GlyphHintsRec _af_debug_hints_rec[1]; + + void* _af_debug_hints = _af_debug_hints_rec; #endif #include FT_INTERNAL_OBJECTS_H @@ -45,7 +70,7 @@ #define FT_COMPONENT trace_afmodule - FT_Error + static FT_Error af_property_get_face_globals( FT_Face face, AF_FaceGlobals* aglobals, AF_Module module ) @@ -55,13 +80,13 @@ if ( !face ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Face_Handle ); globals = (AF_FaceGlobals)face->autohint.data; if ( !globals ) { - /* trigger computation of the global script data */ - /* in case it hasn't been done yet */ + /* trigger computation of the global style data */ + /* in case it hasn't been done yet */ error = af_face_globals_new( face, &globals, module ); if ( !error ) { @@ -79,7 +104,7 @@ } - FT_Error + static FT_Error af_property_set( FT_Module ft_module, const char* property_name, const void* value ) @@ -92,8 +117,40 @@ { FT_UInt* fallback_script = (FT_UInt*)value; + FT_UInt ss; + + + /* We translate the fallback script to a fallback style that uses */ + /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */ + /* coverage value. */ + for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + { + AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + + + if ( (FT_UInt)style_class->script == *fallback_script && + style_class->coverage == AF_COVERAGE_DEFAULT ) + { + module->fallback_style = ss; + break; + } + } + + if ( !AF_STYLE_CLASSES_GET[ss] ) + { + FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n", + fallback_script, property_name )); + return FT_THROW( Invalid_Argument ); + } + + return error; + } + else if ( !ft_strcmp( property_name, "default-script" ) ) + { + FT_UInt* default_script = (FT_UInt*)value; + - module->fallback_script = *fallback_script; + module->default_script = *default_script; return error; } @@ -109,6 +166,57 @@ return error; } +#ifdef AF_CONFIG_OPTION_USE_WARPER + else if ( !ft_strcmp( property_name, "warping" ) ) + { + FT_Bool* warping = (FT_Bool*)value; + + + module->warping = *warping; + + return error; + } +#endif /* AF_CONFIG_OPTION_USE_WARPER */ + else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = (FT_Int*)value; + + FT_Int x1 = darken_params[0]; + FT_Int y1 = darken_params[1]; + FT_Int x2 = darken_params[2]; + FT_Int y2 = darken_params[3]; + FT_Int x3 = darken_params[4]; + FT_Int y3 = darken_params[5]; + FT_Int x4 = darken_params[6]; + FT_Int y4 = darken_params[7]; + + + if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || + y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || + x1 > x2 || x2 > x3 || x3 > x4 || + y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) + return FT_THROW( Invalid_Argument ); + + module->darken_params[0] = x1; + module->darken_params[1] = y1; + module->darken_params[2] = x2; + module->darken_params[3] = y2; + module->darken_params[4] = x3; + module->darken_params[5] = y3; + module->darken_params[6] = x4; + module->darken_params[7] = y4; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; + + + module->no_stem_darkening = *no_stem_darkening; + + return error; + } FT_TRACE0(( "af_property_set: missing property `%s'\n", property_name )); @@ -116,14 +224,18 @@ } - FT_Error + static FT_Error af_property_get( FT_Module ft_module, const char* property_name, void* value ) { - FT_Error error = FT_Err_Ok; - AF_Module module = (AF_Module)ft_module; - FT_UInt fallback_script = module->fallback_script; + FT_Error error = FT_Err_Ok; + AF_Module module = (AF_Module)ft_module; + FT_UInt fallback_style = module->fallback_style; + FT_UInt default_script = module->default_script; +#ifdef AF_CONFIG_OPTION_USE_WARPER + FT_Bool warping = module->warping; +#endif if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) @@ -134,7 +246,7 @@ error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) - prop->map = globals->glyph_scripts; + prop->map = globals->glyph_styles; return error; } @@ -142,8 +254,19 @@ { FT_UInt* val = (FT_UInt*)value; + AF_StyleClass style_class = AF_STYLE_CLASSES_GET[fallback_style]; + + + *val = style_class->script; + + return error; + } + else if ( !ft_strcmp( property_name, "default-script" ) ) + { + FT_UInt* val = (FT_UInt*)value; + - *val = fallback_script; + *val = default_script; return error; } @@ -159,7 +282,44 @@ return error; } +#ifdef AF_CONFIG_OPTION_USE_WARPER + else if ( !ft_strcmp( property_name, "warping" ) ) + { + FT_Bool* val = (FT_Bool*)value; + + + *val = warping; + + return error; + } +#endif /* AF_CONFIG_OPTION_USE_WARPER */ + else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = module->darken_params; + FT_Int* val = (FT_Int*)value; + + + val[0] = darken_params[0]; + val[1] = darken_params[1]; + val[2] = darken_params[2]; + val[3] = darken_params[3]; + val[4] = darken_params[4]; + val[5] = darken_params[5]; + val[6] = darken_params[6]; + val[7] = darken_params[7]; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool no_stem_darkening = module->no_stem_darkening; + FT_Bool* val = (FT_Bool*)value; + + *val = no_stem_darkening; + + return error; + } FT_TRACE0(( "af_property_get: missing property `%s'\n", property_name )); @@ -169,8 +329,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( af_service_properties, - (FT_Properties_SetFunc)af_property_set, - (FT_Properties_GetFunc)af_property_get ) + (FT_Properties_SetFunc)af_property_set, /* set_property */ + (FT_Properties_GetFunc)af_property_get ) /* get_property */ FT_DEFINE_SERVICEDESCREC1( @@ -182,7 +342,7 @@ af_get_interface( FT_Module module, const char* module_interface ) { - /* AF_SERVICES_GET derefers `library' in PIC mode */ + /* AF_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC FT_Library library; @@ -206,19 +366,35 @@ AF_Module module = (AF_Module)ft_module; - module->fallback_script = AF_SCRIPT_FALLBACK; - - return af_loader_init( module ); + module->fallback_style = AF_STYLE_FALLBACK; + module->default_script = AF_SCRIPT_DEFAULT; +#ifdef AF_CONFIG_OPTION_USE_WARPER + module->warping = 0; +#endif + module->no_stem_darkening = TRUE; + + module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + module->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; + module->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; + module->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; + module->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; + module->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; + module->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; + module->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; + + return FT_Err_Ok; } FT_CALLBACK_DEF( void ) af_autofitter_done( FT_Module ft_module ) /* AF_Module */ { - AF_Module module = (AF_Module)ft_module; + FT_UNUSED( ft_module ); - - af_loader_done( module ); +#ifdef FT_DEBUG_AUTOFIT + if ( _af_debug_hints_rec->memory ) + af_glyph_hints_done( _af_debug_hints_rec ); +#endif } @@ -229,10 +405,56 @@ FT_UInt glyph_index, FT_Int32 load_flags ) { + FT_Error error = FT_Err_Ok; + FT_Memory memory = module->root.library->memory; + +#ifdef FT_DEBUG_AUTOFIT + + /* in debug mode, we use a global object that survives this routine */ + + AF_GlyphHints hints = _af_debug_hints_rec; + AF_LoaderRec loader[1]; + + FT_UNUSED( size ); + + + if ( hints->memory ) + af_glyph_hints_done( hints ); + + af_glyph_hints_init( hints, memory ); + af_loader_init( loader, hints ); + + error = af_loader_load_glyph( loader, module, slot->face, + glyph_index, load_flags ); + + af_glyph_hints_dump_points( hints, 0 ); + af_glyph_hints_dump_segments( hints, 0 ); + af_glyph_hints_dump_edges( hints, 0 ); + + af_loader_done( loader ); + + return error; + +#else /* !FT_DEBUG_AUTOFIT */ + + AF_GlyphHintsRec hints[1]; + AF_LoaderRec loader[1]; + FT_UNUSED( size ); - return af_loader_load_glyph( module, slot->face, - glyph_index, load_flags ); + + af_glyph_hints_init( hints, memory ); + af_loader_init( loader, hints ); + + error = af_loader_load_glyph( loader, module, slot->face, + glyph_index, load_flags ); + + af_loader_done( loader ); + af_glyph_hints_done( hints ); + + return error; + +#endif /* !FT_DEBUG_AUTOFIT */ } diff --git a/drivers/freetype/src/autofit/afmodule.h b/drivers/freetype/src/autofit/afmodule.h index c4e8f8f66a..e65db5f5cb 100644 --- a/drivers/freetype/src/autofit/afmodule.h +++ b/drivers/freetype/src/autofit/afmodule.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module implementation (specification). */ /* */ -/* Copyright 2003, 2004, 2005 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,43 +16,43 @@ /***************************************************************************/ -#ifndef __AFMODULE_H__ -#define __AFMODULE_H__ +#ifndef AFMODULE_H_ +#define AFMODULE_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_MODULE_H -#include "afloader.h" - FT_BEGIN_HEADER /* - * This is the `extended' FT_Module structure which holds the - * autofitter's global data. Right before hinting a glyph, the data - * specific to the glyph's face (blue zones, stem widths, etc.) are - * loaded into `loader' (see function `af_loader_reset'). + * This is the `extended' FT_Module structure that holds the + * autofitter's global data. */ typedef struct AF_ModuleRec_ { FT_ModuleRec root; - FT_UInt fallback_script; - - AF_LoaderRec loader[1]; + FT_UInt fallback_style; + FT_UInt default_script; +#ifdef AF_CONFIG_OPTION_USE_WARPER + FT_Bool warping; +#endif + FT_Bool no_stem_darkening; + FT_Int darken_params[8]; - } AF_ModuleRec; + } AF_ModuleRec, *AF_Module; -FT_DECLARE_MODULE(autofit_module_class) +FT_DECLARE_MODULE( autofit_module_class ) FT_END_HEADER -#endif /* __AFMODULE_H__ */ +#endif /* AFMODULE_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afpic.c b/drivers/freetype/src/autofit/afpic.c index 45e1448c08..3cbd9168e3 100644 --- a/drivers/freetype/src/autofit/afpic.c +++ b/drivers/freetype/src/autofit/afpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for autofit module. */ /* */ -/* Copyright 2009-2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_FREETYPE_H #include FT_INTERNAL_OBJECTS_H #include "afpic.h" +#include "afglobal.h" #include "aferrors.h" @@ -42,14 +43,11 @@ FT_AutoHinter_InterfaceRec* clazz ); - /* forward declaration of PIC init functions from script classes */ -#include "aflatin.h" -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.h" -#endif -#include "afcjk.h" -#include "afdummy.h" -#include "afindic.h" + /* forward declaration of PIC init functions from writing system classes */ +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) /* empty */ + +#include "afwrtsys.h" void @@ -100,27 +98,44 @@ FT_Init_Class_af_service_properties( &container->af_service_properties ); - for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) - { + for ( ss = 0; ss < AF_WRITING_SYSTEM_MAX; ss++ ) + container->af_writing_system_classes[ss] = + &container->af_writing_system_classes_rec[ss]; + container->af_writing_system_classes[AF_WRITING_SYSTEM_MAX] = NULL; + + for ( ss = 0; ss < AF_SCRIPT_MAX; ss++ ) container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; - } - container->af_script_classes[AF_SCRIPT_CLASSES_COUNT - 1] = NULL; + container->af_script_classes[AF_SCRIPT_MAX] = NULL; + + for ( ss = 0; ss < AF_STYLE_MAX; ss++ ) + container->af_style_classes[ss] = + &container->af_style_classes_rec[ss]; + container->af_style_classes[AF_STYLE_MAX] = NULL; + +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) \ + FT_Init_Class_af_ ## ws ## _writing_system_class( \ + &container->af_writing_system_classes_rec[ss++] ); + + ss = 0; +#include "afwrtsys.h" + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, sss ) \ + FT_Init_Class_af_ ## s ## _script_class( \ + &container->af_script_classes_rec[ss++] ); + + ss = 0; +#include "afscript.h" + +#undef STYLE +#define STYLE( s, S, d, ws, sc, bss, c ) \ + FT_Init_Class_af_ ## s ## _style_class( \ + &container->af_style_classes_rec[ss++] ); - /* add call to initialization function when you add new scripts */ ss = 0; - FT_Init_Class_af_dummy_script_class( - &container->af_script_classes_rec[ss++] ); -#ifdef FT_OPTION_AUTOFIT2 - FT_Init_Class_af_latin2_script_class( - &container->af_script_classes_rec[ss++] ); -#endif - FT_Init_Class_af_latin_script_class( - &container->af_script_classes_rec[ss++] ); - FT_Init_Class_af_cjk_script_class( - &container->af_script_classes_rec[ss++] ); - FT_Init_Class_af_indic_script_class( - &container->af_script_classes_rec[ss++] ); +#include "afstyles.h" FT_Init_Class_af_autofitter_interface( library, &container->af_autofitter_interface ); diff --git a/drivers/freetype/src/autofit/afpic.h b/drivers/freetype/src/autofit/afpic.h index 0acf803894..98a45a26ba 100644 --- a/drivers/freetype/src/autofit/afpic.h +++ b/drivers/freetype/src/autofit/afpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for autofit module. */ /* */ -/* Copyright 2009, 2011-2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,22 +16,22 @@ /***************************************************************************/ -#ifndef __AFPIC_H__ -#define __AFPIC_H__ +#ifndef AFPIC_H_ +#define AFPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H #ifndef FT_CONFIG_OPTION_PIC -#define AF_SERVICES_GET af_services -#define AF_SERVICE_PROPERTIES_GET af_service_properties +#define AF_SERVICES_GET af_services +#define AF_SERVICE_PROPERTIES_GET af_service_properties -#define AF_SCRIPT_CLASSES_GET af_script_classes -#define AF_INTERFACE_GET af_autofitter_interface +#define AF_WRITING_SYSTEM_CLASSES_GET af_writing_system_classes +#define AF_SCRIPT_CLASSES_GET af_script_classes +#define AF_STYLE_CLASSES_GET af_style_classes +#define AF_INTERFACE_GET af_autofitter_interface #else /* FT_CONFIG_OPTION_PIC */ @@ -40,24 +40,29 @@ FT_BEGIN_HEADER #include "aftypes.h" - /* increase these when you add new scripts, */ - /* and update autofit_module_class_pic_init */ -#ifdef FT_OPTION_AUTOFIT2 -#define AF_SCRIPT_CLASSES_COUNT 6 -#else -#define AF_SCRIPT_CLASSES_COUNT 5 -#endif - -#define AF_SCRIPT_CLASSES_REC_COUNT ( AF_SCRIPT_CLASSES_COUNT - 1 ) +FT_BEGIN_HEADER typedef struct AFModulePIC_ { FT_ServiceDescRec* af_services; FT_Service_PropertiesRec af_service_properties; - AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; - AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; + AF_WritingSystemClass af_writing_system_classes + [AF_WRITING_SYSTEM_MAX + 1]; + AF_WritingSystemClassRec af_writing_system_classes_rec + [AF_WRITING_SYSTEM_MAX]; + + AF_ScriptClass af_script_classes + [AF_SCRIPT_MAX + 1]; + AF_ScriptClassRec af_script_classes_rec + [AF_SCRIPT_MAX]; + + AF_StyleClass af_style_classes + [AF_STYLE_MAX + 1]; + AF_StyleClassRec af_style_classes_rec + [AF_STYLE_MAX]; + FT_AutoHinter_InterfaceRec af_autofitter_interface; } AFModulePIC; @@ -71,8 +76,12 @@ FT_BEGIN_HEADER #define AF_SERVICE_PROPERTIES_GET \ ( GET_PIC( library )->af_service_properties ) +#define AF_WRITING_SYSTEM_CLASSES_GET \ + ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_writing_system_classes ) #define AF_SCRIPT_CLASSES_GET \ ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_script_classes ) +#define AF_STYLE_CLASSES_GET \ + ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_style_classes ) #define AF_INTERFACE_GET \ ( GET_PIC( library )->af_autofitter_interface ) @@ -84,13 +93,13 @@ FT_BEGIN_HEADER FT_Error autofit_module_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __AFPIC_H__ */ +#endif /* AFPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afranges.c b/drivers/freetype/src/autofit/afranges.c new file mode 100644 index 0000000000..732f3d1629 --- /dev/null +++ b/drivers/freetype/src/autofit/afranges.c @@ -0,0 +1,714 @@ +/***************************************************************************/ +/* */ +/* afranges.c */ +/* */ +/* Auto-fitter Unicode script ranges (body). */ +/* */ +/* Copyright 2013-2016 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 "afranges.h" + + /* + * The algorithm for assigning properties and styles to the `glyph_styles' + * array is as follows (cf. the implementation in + * `af_face_globals_compute_style_coverage'). + * + * Walk over all scripts (as listed in `afscript.h'). + * + * For a given script, walk over all styles (as listed in `afstyles.h'). + * The order of styles is important and should be as follows. + * + * - First come styles based on OpenType features (small caps, for + * example). Since features rely on glyph indices, thus completely + * bypassing character codes, no properties are assigned. + * + * - Next comes the default style, using the character ranges as defined + * below. This also assigns properties. + * + * Note that there also exist fallback scripts, mainly covering + * superscript and subscript glyphs of a script that are not present as + * OpenType features. Fallback scripts are defined below, also + * assigning properties; they are applied after the corresponding + * script. + * + */ + + + /* XXX Check base character ranges again: */ + /* Right now, they are quickly derived by visual inspection. */ + /* I can imagine that fine-tuning is necessary. */ + + /* for the auto-hinter, a `non-base character' is something that should */ + /* not be affected by blue zones, regardless of whether this is a */ + /* spacing or no-spacing glyph */ + + /* the `ta_xxxx_nonbase_uniranges' ranges must be strict subsets */ + /* of the corresponding `ta_xxxx_uniranges' ranges */ + + + const AF_Script_UniRangeRec af_arab_uniranges[] = + { + AF_UNIRANGE_REC( 0x0600, 0x06FF ), /* Arabic */ + AF_UNIRANGE_REC( 0x0750, 0x07FF ), /* Arabic Supplement */ + AF_UNIRANGE_REC( 0x08A0, 0x08FF ), /* Arabic Extended-A */ + AF_UNIRANGE_REC( 0xFB50, 0xFDFF ), /* Arabic Presentation Forms-A */ + AF_UNIRANGE_REC( 0xFE70, 0xFEFF ), /* Arabic Presentation Forms-B */ + AF_UNIRANGE_REC( 0x1EE00, 0x1EEFF ), /* Arabic Mathematical Alphabetic Symbols */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_arab_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0600, 0x0605 ), + AF_UNIRANGE_REC( 0x0610, 0x061A ), + AF_UNIRANGE_REC( 0x064B, 0x065F ), + AF_UNIRANGE_REC( 0x0670, 0x0670 ), + AF_UNIRANGE_REC( 0x06D6, 0x06DC ), + AF_UNIRANGE_REC( 0x06DF, 0x06E4 ), + AF_UNIRANGE_REC( 0x06E7, 0x06E8 ), + AF_UNIRANGE_REC( 0x06EA, 0x06ED ), + AF_UNIRANGE_REC( 0x08D4, 0x08E1 ), + AF_UNIRANGE_REC( 0x08E3, 0x08FF ), + AF_UNIRANGE_REC( 0xFBB2, 0xFBC1 ), + AF_UNIRANGE_REC( 0xFE70, 0xFE70 ), + AF_UNIRANGE_REC( 0xFE72, 0xFE72 ), + AF_UNIRANGE_REC( 0xFE74, 0xFE74 ), + AF_UNIRANGE_REC( 0xFE76, 0xFE76 ), + AF_UNIRANGE_REC( 0xFE78, 0xFE78 ), + AF_UNIRANGE_REC( 0xFE7A, 0xFE7A ), + AF_UNIRANGE_REC( 0xFE7C, 0xFE7C ), + AF_UNIRANGE_REC( 0xFE7E, 0xFE7E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_armn_uniranges[] = + { + AF_UNIRANGE_REC( 0x0530, 0x058F ), /* Armenian */ + AF_UNIRANGE_REC( 0xFB13, 0xFB17 ), /* Alphab. Present. Forms (Armenian) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_armn_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0559, 0x055F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_beng_uniranges[] = + { + AF_UNIRANGE_REC( 0x0980, 0x09FF ), /* Bengali */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_beng_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0981, 0x0981 ), + AF_UNIRANGE_REC( 0x09BC, 0x09BC ), + AF_UNIRANGE_REC( 0x09C1, 0x09C4 ), + AF_UNIRANGE_REC( 0x09CD, 0x09CD ), + AF_UNIRANGE_REC( 0x09E2, 0x09E3 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cher_uniranges[] = + { + AF_UNIRANGE_REC( 0x13A0, 0x13FF ), /* Cherokee */ + AF_UNIRANGE_REC( 0xAB70, 0xABBF ), /* Cherokee Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cher_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cyrl_uniranges[] = + { + AF_UNIRANGE_REC( 0x0400, 0x04FF ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0500, 0x052F ), /* Cyrillic Supplement */ + AF_UNIRANGE_REC( 0x2DE0, 0x2DFF ), /* Cyrillic Extended-A */ + AF_UNIRANGE_REC( 0xA640, 0xA69F ), /* Cyrillic Extended-B */ + AF_UNIRANGE_REC( 0x1C80, 0x1C8F ), /* Cyrillic Extended-C */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cyrl_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0483, 0x0489 ), + AF_UNIRANGE_REC( 0x2DE0, 0x2DFF ), + AF_UNIRANGE_REC( 0xA66F, 0xA67F ), + AF_UNIRANGE_REC( 0xA69E, 0xA69F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + /* There are some characters in the Devanagari Unicode block that are */ + /* generic to Indic scripts; we omit them so that their presence doesn't */ + /* trigger Devanagari. */ + + const AF_Script_UniRangeRec af_deva_uniranges[] = + { + AF_UNIRANGE_REC( 0x0900, 0x093B ), /* Devanagari */ + /* omitting U+093C nukta */ + AF_UNIRANGE_REC( 0x093D, 0x0950 ), /* ... continued */ + /* omitting U+0951 udatta, U+0952 anudatta */ + AF_UNIRANGE_REC( 0x0953, 0x0963 ), /* ... continued */ + /* omitting U+0964 danda, U+0965 double danda */ + AF_UNIRANGE_REC( 0x0966, 0x097F ), /* ... continued */ + AF_UNIRANGE_REC( 0x20B9, 0x20B9 ), /* (new) Rupee sign */ + AF_UNIRANGE_REC( 0xA8E0, 0xA8FF ), /* Devanagari Extended */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_deva_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0900, 0x0902 ), + AF_UNIRANGE_REC( 0x093A, 0x093A ), + AF_UNIRANGE_REC( 0x0941, 0x0948 ), + AF_UNIRANGE_REC( 0x094D, 0x094D ), + AF_UNIRANGE_REC( 0x0953, 0x0957 ), + AF_UNIRANGE_REC( 0x0962, 0x0963 ), + AF_UNIRANGE_REC( 0xA8E0, 0xA8F1 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_ethi_uniranges[] = + { + AF_UNIRANGE_REC( 0x1200, 0x137F ), /* Ethiopic */ + AF_UNIRANGE_REC( 0x1380, 0x139F ), /* Ethiopic Supplement */ + AF_UNIRANGE_REC( 0x2D80, 0x2DDF ), /* Ethiopic Extended */ + AF_UNIRANGE_REC( 0xAB00, 0xAB2F ), /* Ethiopic Extended-A */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_ethi_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x135D, 0x135F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_geor_uniranges[] = + { + AF_UNIRANGE_REC( 0x10D0, 0x10FF ), /* Georgian (Mkhedruli) */ +#if 0 + /* the following range is proposed for inclusion in Unicode */ + AF_UNIRANGE_REC( 0x1C90, 0x1CBF ), /* Georgian (Mtavruli) */ +#endif + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_geor_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_geok_uniranges[] = + { + /* Khutsuri */ + AF_UNIRANGE_REC( 0x10A0, 0x10CD ), /* Georgian (Asomtavruli) */ + AF_UNIRANGE_REC( 0x2D00, 0x2D2D ), /* Georgian (Nuskhuri) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_geok_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_grek_uniranges[] = + { + AF_UNIRANGE_REC( 0x0370, 0x03FF ), /* Greek and Coptic */ + AF_UNIRANGE_REC( 0x1F00, 0x1FFF ), /* Greek Extended */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_grek_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x037A, 0x037A ), + AF_UNIRANGE_REC( 0x0384, 0x0385 ), + AF_UNIRANGE_REC( 0x1FBD, 0x1FC1 ), + AF_UNIRANGE_REC( 0x1FCD, 0x1FCF ), + AF_UNIRANGE_REC( 0x1FDD, 0x1FDF ), + AF_UNIRANGE_REC( 0x1FED, 0x1FEF ), + AF_UNIRANGE_REC( 0x1FFD, 0x1FFE ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_gujr_uniranges[] = + { + AF_UNIRANGE_REC( 0x0A80, 0x0AFF ), /* Gujarati */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_gujr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0A81, 0x0A82 ), + AF_UNIRANGE_REC( 0x0ABC, 0x0ABC ), + AF_UNIRANGE_REC( 0x0AC1, 0x0AC8 ), + AF_UNIRANGE_REC( 0x0ACD, 0x0ACD ), + AF_UNIRANGE_REC( 0x0AE2, 0x0AE3 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_guru_uniranges[] = + { + AF_UNIRANGE_REC( 0x0A00, 0x0A7F ), /* Gurmukhi */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_guru_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0A01, 0x0A02 ), + AF_UNIRANGE_REC( 0x0A3C, 0x0A3C ), + AF_UNIRANGE_REC( 0x0A41, 0x0A51 ), + AF_UNIRANGE_REC( 0x0A70, 0x0A71 ), + AF_UNIRANGE_REC( 0x0A75, 0x0A75 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_hebr_uniranges[] = + { + AF_UNIRANGE_REC( 0x0590, 0x05FF ), /* Hebrew */ + AF_UNIRANGE_REC( 0xFB1D, 0xFB4F ), /* Alphab. Present. Forms (Hebrew) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_hebr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0591, 0x05BF ), + AF_UNIRANGE_REC( 0x05C1, 0x05C2 ), + AF_UNIRANGE_REC( 0x05C4, 0x05C5 ), + AF_UNIRANGE_REC( 0x05C7, 0x05C7 ), + AF_UNIRANGE_REC( 0xFB1E, 0xFB1E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_knda_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C80, 0x0CFF ), /* Kannada */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_knda_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C81, 0x0C81 ), + AF_UNIRANGE_REC( 0x0CBC, 0x0CBC ), + AF_UNIRANGE_REC( 0x0CBF, 0x0CBF ), + AF_UNIRANGE_REC( 0x0CC6, 0x0CC6 ), + AF_UNIRANGE_REC( 0x0CCC, 0x0CCD ), + AF_UNIRANGE_REC( 0x0CE2, 0x0CE3 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_khmr_uniranges[] = + { + AF_UNIRANGE_REC( 0x1780, 0x17FF ), /* Khmer */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_khmr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x17B7, 0x17BD ), + AF_UNIRANGE_REC( 0x17C6, 0x17C6 ), + AF_UNIRANGE_REC( 0x17C9, 0x17D3 ), + AF_UNIRANGE_REC( 0x17DD, 0x17DD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_khms_uniranges[] = + { + AF_UNIRANGE_REC( 0x19E0, 0x19FF ), /* Khmer Symbols */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_khms_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_lao_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E80, 0x0EFF ), /* Lao */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_lao_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0EB1, 0x0EB1 ), + AF_UNIRANGE_REC( 0x0EB4, 0x0EBC ), + AF_UNIRANGE_REC( 0x0EC8, 0x0ECD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latn_uniranges[] = + { + AF_UNIRANGE_REC( 0x0020, 0x007F ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0, 0x00A9 ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x00AB, 0x00B1 ), /* ... continued */ + AF_UNIRANGE_REC( 0x00B4, 0x00B8 ), /* ... continued */ + AF_UNIRANGE_REC( 0x00BB, 0x00FF ), /* ... continued */ + AF_UNIRANGE_REC( 0x0100, 0x017F ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180, 0x024F ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250, 0x02AF ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B9, 0x02DF ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x02E5, 0x02FF ), /* ... continued */ + AF_UNIRANGE_REC( 0x0300, 0x036F ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x1AB0, 0x1ABE ), /* Combining Diacritical Marks Extended */ + AF_UNIRANGE_REC( 0x1D00, 0x1D2B ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D6B, 0x1D77 ), /* ... continued */ + AF_UNIRANGE_REC( 0x1D79, 0x1D7F ), /* ... continued */ + AF_UNIRANGE_REC( 0x1D80, 0x1D9A ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x1DC0, 0x1DFF ), /* Combining Diacritical Marks Supplement */ + AF_UNIRANGE_REC( 0x1E00, 0x1EFF ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x2000, 0x206F ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x20A0, 0x20B8 ), /* Currency Symbols ... */ + AF_UNIRANGE_REC( 0x20BA, 0x20CF ), /* ... except new Rupee sign */ + AF_UNIRANGE_REC( 0x2150, 0x218F ), /* Number Forms */ + AF_UNIRANGE_REC( 0x2C60, 0x2C7B ), /* Latin Extended-C */ + AF_UNIRANGE_REC( 0x2C7E, 0x2C7F ), /* ... continued */ + AF_UNIRANGE_REC( 0x2E00, 0x2E7F ), /* Supplemental Punctuation */ + AF_UNIRANGE_REC( 0xA720, 0xA76F ), /* Latin Extended-D */ + AF_UNIRANGE_REC( 0xA771, 0xA7F7 ), /* ... continued */ + AF_UNIRANGE_REC( 0xA7FA, 0xA7FF ), /* ... continued */ + AF_UNIRANGE_REC( 0xAB30, 0xAB5B ), /* Latin Extended-E */ + AF_UNIRANGE_REC( 0xAB60, 0xAB6F ), /* ... continued */ + AF_UNIRANGE_REC( 0xFB00, 0xFB06 ), /* Alphab. Present. Forms (Latin Ligs) */ + AF_UNIRANGE_REC( 0x1D400, 0x1D7FF ), /* Mathematical Alphanumeric Symbols */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latn_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x005E, 0x0060 ), + AF_UNIRANGE_REC( 0x007E, 0x007E ), + AF_UNIRANGE_REC( 0x00A8, 0x00A9 ), + AF_UNIRANGE_REC( 0x00AE, 0x00B0 ), + AF_UNIRANGE_REC( 0x00B4, 0x00B4 ), + AF_UNIRANGE_REC( 0x00B8, 0x00B8 ), + AF_UNIRANGE_REC( 0x00BC, 0x00BE ), + AF_UNIRANGE_REC( 0x02B9, 0x02DF ), + AF_UNIRANGE_REC( 0x02E5, 0x02FF ), + AF_UNIRANGE_REC( 0x0300, 0x036F ), + AF_UNIRANGE_REC( 0x1AB0, 0x1ABE ), + AF_UNIRANGE_REC( 0x1DC0, 0x1DFF ), + AF_UNIRANGE_REC( 0x2017, 0x2017 ), + AF_UNIRANGE_REC( 0x203E, 0x203E ), + AF_UNIRANGE_REC( 0xA788, 0xA788 ), + AF_UNIRANGE_REC( 0xA7F8, 0xA7FA ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latb_uniranges[] = + { + AF_UNIRANGE_REC( 0x1D62, 0x1D6A ), /* some small subscript letters */ + AF_UNIRANGE_REC( 0x2080, 0x209C ), /* subscript digits and letters */ + AF_UNIRANGE_REC( 0x2C7C, 0x2C7C ), /* latin subscript small letter j */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latb_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latp_uniranges[] = + { + AF_UNIRANGE_REC( 0x00AA, 0x00AA ), /* feminine ordinal indicator */ + AF_UNIRANGE_REC( 0x00B2, 0x00B3 ), /* superscript two and three */ + AF_UNIRANGE_REC( 0x00B9, 0x00BA ), /* superscript one, masc. ord. indic. */ + AF_UNIRANGE_REC( 0x02B0, 0x02B8 ), /* some latin superscript mod. letters */ + AF_UNIRANGE_REC( 0x02E0, 0x02E4 ), /* some IPA modifier letters */ + AF_UNIRANGE_REC( 0x1D2C, 0x1D61 ), /* latin superscript modifier letters */ + AF_UNIRANGE_REC( 0x1D78, 0x1D78 ), /* modifier letter cyrillic en */ + AF_UNIRANGE_REC( 0x1D9B, 0x1DBF ), /* more modifier letters */ + AF_UNIRANGE_REC( 0x2070, 0x207F ), /* superscript digits and letters */ + AF_UNIRANGE_REC( 0x2C7D, 0x2C7D ), /* modifier letter capital v */ + AF_UNIRANGE_REC( 0xA770, 0xA770 ), /* modifier letter us */ + AF_UNIRANGE_REC( 0xA7F8, 0xA7F9 ), /* more modifier letters */ + AF_UNIRANGE_REC( 0xAB5C, 0xAB5F ), /* more modifier letters */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latp_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_mlym_uniranges[] = + { + AF_UNIRANGE_REC( 0x0D00, 0x0D7F ), /* Malayalam */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_mlym_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0D01, 0x0D01 ), + AF_UNIRANGE_REC( 0x0D4D, 0x0D4E ), + AF_UNIRANGE_REC( 0x0D62, 0x0D63 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_mymr_uniranges[] = + { + AF_UNIRANGE_REC( 0x1000, 0x109F ), /* Myanmar */ + AF_UNIRANGE_REC( 0xA9E0, 0xA9FF ), /* Myanmar Extended-B */ + AF_UNIRANGE_REC( 0xAA60, 0xAA7F ), /* Myanmar Extended-A */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_mymr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x102D, 0x1030 ), + AF_UNIRANGE_REC( 0x1032, 0x1037 ), + AF_UNIRANGE_REC( 0x103A, 0x103A ), + AF_UNIRANGE_REC( 0x103D, 0x103E ), + AF_UNIRANGE_REC( 0x1058, 0x1059 ), + AF_UNIRANGE_REC( 0x105E, 0x1060 ), + AF_UNIRANGE_REC( 0x1071, 0x1074 ), + AF_UNIRANGE_REC( 0x1082, 0x1082 ), + AF_UNIRANGE_REC( 0x1085, 0x1086 ), + AF_UNIRANGE_REC( 0x108D, 0x108D ), + AF_UNIRANGE_REC( 0xA9E5, 0xA9E5 ), + AF_UNIRANGE_REC( 0xAA7C, 0xAA7C ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_none_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_none_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_sinh_uniranges[] = + { + AF_UNIRANGE_REC( 0x0D80, 0x0DFF ), /* Sinhala */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_sinh_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0DCA, 0x0DCA ), + AF_UNIRANGE_REC( 0x0DD2, 0x0DD6 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_taml_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B80, 0x0BFF ), /* Tamil */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_taml_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B82, 0x0B82 ), + AF_UNIRANGE_REC( 0x0BC0, 0x0BC2 ), + AF_UNIRANGE_REC( 0x0BCD, 0x0BCD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_telu_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C00, 0x0C7F ), /* Telugu */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_telu_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C00, 0x0C00 ), + AF_UNIRANGE_REC( 0x0C3E, 0x0C40 ), + AF_UNIRANGE_REC( 0x0C46, 0x0C56 ), + AF_UNIRANGE_REC( 0x0C62, 0x0C63 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_thai_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E00, 0x0E7F ), /* Thai */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_thai_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E31, 0x0E31 ), + AF_UNIRANGE_REC( 0x0E34, 0x0E3A ), + AF_UNIRANGE_REC( 0x0E47, 0x0E4E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + +#ifdef AF_CONFIG_OPTION_INDIC + + const AF_Script_UniRangeRec af_limb_uniranges[] = + { + AF_UNIRANGE_REC( 0x1900, 0x194F ), /* Limbu */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_limb_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1920, 0x1922 ), + AF_UNIRANGE_REC( 0x1927, 0x1934 ), + AF_UNIRANGE_REC( 0x1937, 0x193B ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_orya_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B00, 0x0B7F ), /* Oriya */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_orya_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B01, 0x0B02 ), + AF_UNIRANGE_REC( 0x0B3C, 0x0B3C ), + AF_UNIRANGE_REC( 0x0B3F, 0x0B3F ), + AF_UNIRANGE_REC( 0x0B41, 0x0B44 ), + AF_UNIRANGE_REC( 0x0B4D, 0x0B56 ), + AF_UNIRANGE_REC( 0x0B62, 0x0B63 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_sund_uniranges[] = + { + AF_UNIRANGE_REC( 0x1B80, 0x1BBF ), /* Sundanese */ + AF_UNIRANGE_REC( 0x1CC0, 0x1CCF ), /* Sundanese Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_sund_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1B80, 0x1B82 ), + AF_UNIRANGE_REC( 0x1BA1, 0x1BAD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_sylo_uniranges[] = + { + AF_UNIRANGE_REC( 0xA800, 0xA82F ), /* Syloti Nagri */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_sylo_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0xA802, 0xA802 ), + AF_UNIRANGE_REC( 0xA806, 0xA806 ), + AF_UNIRANGE_REC( 0xA80B, 0xA80B ), + AF_UNIRANGE_REC( 0xA825, 0xA826 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_tibt_uniranges[] = + { + AF_UNIRANGE_REC( 0x0F00, 0x0FFF ), /* Tibetan */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_tibt_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0F18, 0x0F19 ), + AF_UNIRANGE_REC( 0x0F35, 0x0F35 ), + AF_UNIRANGE_REC( 0x0F37, 0x0F37 ), + AF_UNIRANGE_REC( 0x0F39, 0x0F39 ), + AF_UNIRANGE_REC( 0x0F3E, 0x0F3F ), + AF_UNIRANGE_REC( 0x0F71, 0x0F7E ), + AF_UNIRANGE_REC( 0x0F80, 0x0F84 ), + AF_UNIRANGE_REC( 0x0F86, 0x0F87 ), + AF_UNIRANGE_REC( 0x0F8D, 0x0FBC ), + AF_UNIRANGE_REC( 0, 0 ) + }; + +#endif /* !AF_CONFIG_OPTION_INDIC */ + +#ifdef AF_CONFIG_OPTION_CJK + + /* this corresponds to Unicode 6.0 */ + + const AF_Script_UniRangeRec af_hani_uniranges[] = + { + AF_UNIRANGE_REC( 0x1100, 0x11FF ), /* Hangul Jamo */ + AF_UNIRANGE_REC( 0x2E80, 0x2EFF ), /* CJK Radicals Supplement */ + AF_UNIRANGE_REC( 0x2F00, 0x2FDF ), /* Kangxi Radicals */ + AF_UNIRANGE_REC( 0x2FF0, 0x2FFF ), /* Ideographic Description Characters */ + AF_UNIRANGE_REC( 0x3000, 0x303F ), /* CJK Symbols and Punctuation */ + AF_UNIRANGE_REC( 0x3040, 0x309F ), /* Hiragana */ + AF_UNIRANGE_REC( 0x30A0, 0x30FF ), /* Katakana */ + AF_UNIRANGE_REC( 0x3100, 0x312F ), /* Bopomofo */ + AF_UNIRANGE_REC( 0x3130, 0x318F ), /* Hangul Compatibility Jamo */ + AF_UNIRANGE_REC( 0x3190, 0x319F ), /* Kanbun */ + AF_UNIRANGE_REC( 0x31A0, 0x31BF ), /* Bopomofo Extended */ + AF_UNIRANGE_REC( 0x31C0, 0x31EF ), /* CJK Strokes */ + AF_UNIRANGE_REC( 0x31F0, 0x31FF ), /* Katakana Phonetic Extensions */ + AF_UNIRANGE_REC( 0x3300, 0x33FF ), /* CJK Compatibility */ + AF_UNIRANGE_REC( 0x3400, 0x4DBF ), /* CJK Unified Ideographs Extension A */ + AF_UNIRANGE_REC( 0x4DC0, 0x4DFF ), /* Yijing Hexagram Symbols */ + AF_UNIRANGE_REC( 0x4E00, 0x9FFF ), /* CJK Unified Ideographs */ + AF_UNIRANGE_REC( 0xA960, 0xA97F ), /* Hangul Jamo Extended-A */ + AF_UNIRANGE_REC( 0xAC00, 0xD7AF ), /* Hangul Syllables */ + AF_UNIRANGE_REC( 0xD7B0, 0xD7FF ), /* Hangul Jamo Extended-B */ + AF_UNIRANGE_REC( 0xF900, 0xFAFF ), /* CJK Compatibility Ideographs */ + AF_UNIRANGE_REC( 0xFE10, 0xFE1F ), /* Vertical forms */ + AF_UNIRANGE_REC( 0xFE30, 0xFE4F ), /* CJK Compatibility Forms */ + AF_UNIRANGE_REC( 0xFF00, 0xFFEF ), /* Halfwidth and Fullwidth Forms */ + AF_UNIRANGE_REC( 0x1B000, 0x1B0FF ), /* Kana Supplement */ + AF_UNIRANGE_REC( 0x1D300, 0x1D35F ), /* Tai Xuan Hing Symbols */ + AF_UNIRANGE_REC( 0x20000, 0x2A6DF ), /* CJK Unified Ideographs Extension B */ + AF_UNIRANGE_REC( 0x2A700, 0x2B73F ), /* CJK Unified Ideographs Extension C */ + AF_UNIRANGE_REC( 0x2B740, 0x2B81F ), /* CJK Unified Ideographs Extension D */ + AF_UNIRANGE_REC( 0x2F800, 0x2FA1F ), /* CJK Compatibility Ideographs Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_hani_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x302A, 0x302F ), + AF_UNIRANGE_REC( 0x3190, 0x319F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + +#endif /* !AF_CONFIG_OPTION_CJK */ + +/* END */ diff --git a/drivers/freetype/src/autofit/afranges.h b/drivers/freetype/src/autofit/afranges.h new file mode 100644 index 0000000000..1a0e4b1535 --- /dev/null +++ b/drivers/freetype/src/autofit/afranges.h @@ -0,0 +1,47 @@ +/***************************************************************************/ +/* */ +/* afranges.h */ +/* */ +/* Auto-fitter Unicode script ranges (specification). */ +/* */ +/* Copyright 2013-2016 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 AFRANGES_H_ +#define AFRANGES_H_ + + +#include "aftypes.h" + + +FT_BEGIN_HEADER + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + extern const AF_Script_UniRangeRec af_ ## s ## _uniranges[]; + +#include "afscript.h" + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + extern const AF_Script_UniRangeRec af_ ## s ## _nonbase_uniranges[]; + +#include "afscript.h" + + /* */ + +FT_END_HEADER + +#endif /* AFRANGES_H_ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afscript.h b/drivers/freetype/src/autofit/afscript.h new file mode 100644 index 0000000000..33c3012981 --- /dev/null +++ b/drivers/freetype/src/autofit/afscript.h @@ -0,0 +1,245 @@ +/***************************************************************************/ +/* */ +/* afscript.h */ +/* */ +/* Auto-fitter scripts (specification only). */ +/* */ +/* Copyright 2013-2016 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. */ +/* */ +/***************************************************************************/ + + + /* The following part can be included multiple times. */ + /* Define `SCRIPT' as needed. */ + + + /* Add new scripts here. The first and second arguments are the */ + /* script name in lowercase and uppercase, respectively, followed */ + /* by a description string. Then comes the corresponding HarfBuzz */ + /* script name tag, followed by a string of standard characters (to */ + /* derive the standard width and height of stems). */ + /* */ + /* Note that fallback scripts only have a default style, thus we */ + /* use `HB_SCRIPT_INVALID' as the HarfBuzz script name tag for */ + /* them. */ + + SCRIPT( arab, ARAB, + "Arabic", + HB_SCRIPT_ARABIC, + HINTING_BOTTOM_TO_TOP, + "\xD9\x84 \xD8\xAD \xD9\x80" ) /* ل ح ـ */ + + SCRIPT( armn, ARMN, + "Armenian", + HB_SCRIPT_ARMENIAN, + HINTING_BOTTOM_TO_TOP, + "\xD6\x85 \xD5\x95" ) /* օ Օ */ + + /* there are no simple forms for letters; we thus use two digit shapes */ + SCRIPT( beng, BENG, + "Bengali", + HB_SCRIPT_BENGALI, + HINTING_TOP_TO_BOTTOM, + "\xE0\xA7\xA6 \xE0\xA7\xAA" ) /* ০ ৪ */ + + SCRIPT( cher, CHER, + "Cherokee", + HB_SCRIPT_CHEROKEE, + HINTING_BOTTOM_TO_TOP, + "\xE1\x8E\xA4 \xE1\x8F\x85 \xEA\xAE\x95" ) /* Ꭴ Ꮕ ꮕ */ + + SCRIPT( cyrl, CYRL, + "Cyrillic", + HB_SCRIPT_CYRILLIC, + HINTING_BOTTOM_TO_TOP, + "\xD0\xBE \xD0\x9E" ) /* о О */ + + SCRIPT( deva, DEVA, + "Devanagari", + HB_SCRIPT_DEVANAGARI, + HINTING_TOP_TO_BOTTOM, + "\xE0\xA4\xA0 \xE0\xA4\xB5 \xE0\xA4\x9F" ) /* ठ व ट */ + + SCRIPT( ethi, ETHI, + "Ethiopic", + HB_SCRIPT_ETHIOPIC, + HINTING_BOTTOM_TO_TOP, + "\xE1\x8B\x90" ) /* ዐ */ + + SCRIPT( geor, GEOR, + "Georgian (Mkhedruli)", + HB_SCRIPT_GEORGIAN, + HINTING_BOTTOM_TO_TOP, + "\xE1\x83\x98 \xE1\x83\x94 \xE1\x83\x90" ) /* ი ე ა */ + + SCRIPT( geok, GEOK, + "Georgian (Khutsuri)", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE1\x82\xB6 \xE1\x82\xB1 \xE2\xB4\x99" ) /* Ⴖ Ⴑ ⴙ */ + + SCRIPT( grek, GREK, + "Greek", + HB_SCRIPT_GREEK, + HINTING_BOTTOM_TO_TOP, + "\xCE\xBF \xCE\x9F" ) /* ο Ο */ + + SCRIPT( gujr, GUJR, + "Gujarati", + HB_SCRIPT_GUJARATI, + HINTING_BOTTOM_TO_TOP, + "\xE0\xAA\x9F \xE0\xAB\xA6" ) /* ટ ૦ */ + + SCRIPT( guru, GURU, + "Gurmukhi", + HB_SCRIPT_GURMUKHI, + HINTING_TOP_TO_BOTTOM, + "\xE0\xA8\xA0 \xE0\xA8\xB0 \xE0\xA9\xA6" ) /* ਠ ਰ ੦ */ + + SCRIPT( hebr, HEBR, + "Hebrew", + HB_SCRIPT_HEBREW, + HINTING_BOTTOM_TO_TOP, + "\xD7\x9D" ) /* ם */ + + SCRIPT( knda, KNDA, + "Kannada", + HB_SCRIPT_KANNADA, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB3\xA6 \xE0\xB2\xAC" ) /* ೦ ಬ */ + + /* only digit zero has a simple shape in the Khmer script */ + SCRIPT( khmr, KHMR, + "Khmer", + HB_SCRIPT_KHMER, + HINTING_BOTTOM_TO_TOP, + "\xE1\x9F\xA0" ) /* ០ */ + + SCRIPT( khms, KHMS, + "Khmer Symbols", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE1\xA7\xA1 \xE1\xA7\xAA" ) /* ᧡ ᧪ */ + + /* only digit zero has a simple shape in the Lao script */ + SCRIPT( lao, LAO, + "Lao", + HB_SCRIPT_LAO, + HINTING_BOTTOM_TO_TOP, + "\xE0\xBB\x90" ) /* ໐ */ + + SCRIPT( latn, LATN, + "Latin", + HB_SCRIPT_LATIN, + HINTING_BOTTOM_TO_TOP, + "o O 0" ) + + SCRIPT( latb, LATB, + "Latin Subscript Fallback", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE2\x82\x92 \xE2\x82\x80" ) /* ₒ ₀ */ + + SCRIPT( latp, LATP, + "Latin Superscript Fallback", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE1\xB5\x92 \xE1\xB4\xBC \xE2\x81\xB0" ) /* ᵒ ᴼ ⁰ */ + + SCRIPT( mlym, MLYM, + "Malayalam", + HB_SCRIPT_MALAYALAM, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* ഠ റ */ + + SCRIPT( mymr, MYMR, + "Myanmar", + HB_SCRIPT_MYANMAR, + HINTING_BOTTOM_TO_TOP, + "\xE1\x80\x9D \xE1\x80\x84 \xE1\x80\x82" ) /* ဝ င ဂ */ + + SCRIPT( none, NONE, + "no script", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "" ) + + SCRIPT( sinh, SINH, + "Sinhala", + HB_SCRIPT_SINHALA, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB6\xA7" ) /* ට */ + + /* only digit zero has a simple (round) shape in the Tamil script */ + SCRIPT( taml, TAML, + "Tamil", + HB_SCRIPT_TAMIL, + HINTING_BOTTOM_TO_TOP, + "\xE0\xAF\xA6" ) /* ௦ */ + + /* there are no simple forms for letters; we thus use two digit shapes */ + SCRIPT( telu, TELU, + "Telugu", + HB_SCRIPT_TELUGU, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB1\xA6 \xE0\xB1\xA7" ) /* ౦ ౧ */ + + SCRIPT( thai, THAI, + "Thai", + HB_SCRIPT_THAI, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB8\xB2 \xE0\xB9\x85 \xE0\xB9\x90" ) /* า ๅ ๐ */ + +#ifdef AF_CONFIG_OPTION_INDIC + + SCRIPT( limb, LIMB, + "Limbu", + HB_SCRIPT_LIMBU, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + + SCRIPT( orya, ORYA, + "Oriya", + HB_SCRIPT_ORIYA, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + + SCRIPT( sund, SUND, + "Sundanese", + HB_SCRIPT_SUNDANESE, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + + SCRIPT( sylo, SYLO, + "Syloti Nagri", + HB_SCRIPT_SYLOTI_NAGRI, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + + SCRIPT( tibt, TIBT, + "Tibetan", + HB_SCRIPT_TIBETAN, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + +#endif /* AF_CONFIG_OPTION_INDIC */ + +#ifdef AF_CONFIG_OPTION_CJK + + SCRIPT( hani, HANI, + "CJKV ideographs", + HB_SCRIPT_HAN, + HINTING_BOTTOM_TO_TOP, + "\xE7\x94\xB0 \xE5\x9B\x97" ) /* 田 囗 */ + +#endif /* AF_CONFIG_OPTION_CJK */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afshaper.c b/drivers/freetype/src/autofit/afshaper.c new file mode 100644 index 0000000000..6d13b65859 --- /dev/null +++ b/drivers/freetype/src/autofit/afshaper.c @@ -0,0 +1,683 @@ +/***************************************************************************/ +/* */ +/* afshaper.c */ +/* */ +/* HarfBuzz interface for accessing OpenType features (body). */ +/* */ +/* Copyright 2013-2016 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_FREETYPE_H +#include "afglobal.h" +#include "aftypes.h" +#include "afshaper.h" + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + + + /*************************************************************************/ + /* */ + /* 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_afshaper + + + /* + * We use `sets' (in the HarfBuzz sense, which comes quite near to the + * usual mathematical meaning) to manage both lookups and glyph indices. + * + * 1. For each coverage, collect lookup IDs in a set. Note that an + * auto-hinter `coverage' is represented by one `feature', and a + * feature consists of an arbitrary number of (font specific) `lookup's + * that actually do the mapping job. Please check the OpenType + * specification for more details on features and lookups. + * + * 2. Create glyph ID sets from the corresponding lookup sets. + * + * 3. The glyph set corresponding to AF_COVERAGE_DEFAULT is computed + * with all lookups specific to the OpenType script activated. It + * relies on the order of AF_DEFINE_STYLE_CLASS entries so that + * special coverages (like `oldstyle figures') don't get overwritten. + * + */ + + + /* load coverage tags */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + static const hb_tag_t name ## _coverage[] = \ + { \ + HB_TAG( tag1, tag2, tag3, tag4 ), \ + HB_TAG_NONE \ + }; + + +#include "afcover.h" + + + /* define mapping between coverage tags and AF_Coverage */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + name ## _coverage, + + + static const hb_tag_t* coverages[] = + { +#include "afcover.h" + + NULL /* AF_COVERAGE_DEFAULT */ + }; + + + /* load HarfBuzz script tags */ +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) h, + + + static const hb_script_t scripts[] = + { +#include "afscript.h" + }; + + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ) + { + hb_face_t* face; + + hb_set_t* gsub_lookups; /* GSUB lookups for a given script */ + hb_set_t* gsub_glyphs; /* glyphs covered by GSUB lookups */ + hb_set_t* gpos_lookups; /* GPOS lookups for a given script */ + hb_set_t* gpos_glyphs; /* glyphs covered by GPOS lookups */ + + hb_script_t script; + const hb_tag_t* coverage_tags; + hb_tag_t script_tags[] = { HB_TAG_NONE, + HB_TAG_NONE, + HB_TAG_NONE, + HB_TAG_NONE }; + + hb_codepoint_t idx; +#ifdef FT_DEBUG_LEVEL_TRACE + int count; +#endif + + + if ( !globals || !style_class || !gstyles ) + return FT_THROW( Invalid_Argument ); + + face = hb_font_get_face( globals->hb_font ); + + gsub_lookups = hb_set_create(); + gsub_glyphs = hb_set_create(); + gpos_lookups = hb_set_create(); + gpos_glyphs = hb_set_create(); + + coverage_tags = coverages[style_class->coverage]; + script = scripts[style_class->script]; + + /* Convert a HarfBuzz script tag into the corresponding OpenType */ + /* tag or tags -- some Indic scripts like Devanagari have an old */ + /* and a new set of features. */ + hb_ot_tags_from_script( script, + &script_tags[0], + &script_tags[1] ); + + /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */ + /* as the second tag. We change that to HB_TAG_NONE except for the */ + /* default script. */ + if ( default_script ) + { + if ( script_tags[0] == HB_TAG_NONE ) + script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT; + else + { + if ( script_tags[1] == HB_TAG_NONE ) + script_tags[1] = HB_OT_TAG_DEFAULT_SCRIPT; + else if ( script_tags[1] != HB_OT_TAG_DEFAULT_SCRIPT ) + script_tags[2] = HB_OT_TAG_DEFAULT_SCRIPT; + } + } + else + { + /* we use non-standard tags like `khms' for special purposes; */ + /* HarfBuzz maps them to `DFLT', which we don't want to handle here */ + if ( script_tags[0] == HB_OT_TAG_DEFAULT_SCRIPT ) + goto Exit; + + if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT ) + script_tags[1] = HB_TAG_NONE; + } + + hb_ot_layout_collect_lookups( face, + HB_OT_TAG_GSUB, + script_tags, + NULL, + coverage_tags, + gsub_lookups ); + + if ( hb_set_is_empty( gsub_lookups ) ) + goto Exit; /* nothing to do */ + + hb_ot_layout_collect_lookups( face, + HB_OT_TAG_GPOS, + script_tags, + NULL, + coverage_tags, + gpos_lookups ); + + FT_TRACE4(( "GSUB lookups (style `%s'):\n" + " ", + af_style_names[style_class->style] )); + +#ifdef FT_DEBUG_LEVEL_TRACE + count = 0; +#endif + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* get output coverage of GSUB feature */ + hb_ot_layout_lookup_collect_glyphs( face, + HB_OT_TAG_GSUB, + idx, + NULL, + NULL, + NULL, + gsub_glyphs ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + FT_TRACE4(( "GPOS lookups (style `%s'):\n" + " ", + af_style_names[style_class->style] )); + +#ifdef FT_DEBUG_LEVEL_TRACE + count = 0; +#endif + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gpos_lookups, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* get input coverage of GPOS feature */ + hb_ot_layout_lookup_collect_glyphs( face, + HB_OT_TAG_GPOS, + idx, + NULL, + gpos_glyphs, + NULL, + NULL ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + /* + * We now check whether we can construct blue zones, using glyphs + * covered by the feature only. In case there is not a single zone + * (this is, not a single character is covered), we skip this coverage. + * + */ + if ( style_class->coverage != AF_COVERAGE_DEFAULT ) + { + AF_Blue_Stringset bss = style_class->blue_stringset; + const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; + + FT_Bool found = 0; + + + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) + { + const char* p = &af_blue_strings[bs->string]; + + + while ( *p ) + { + hb_codepoint_t ch; + + + GET_UTF8_CHAR( ch, p ); + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, + &idx ); ) + { + hb_codepoint_t gidx = FT_Get_Char_Index( globals->face, ch ); + + + if ( hb_ot_layout_lookup_would_substitute( face, idx, + &gidx, 1, 1 ) ) + { + found = 1; + break; + } + } + } + } + + if ( !found ) + { + FT_TRACE4(( " no blue characters found; style skipped\n" )); + goto Exit; + } + } + + /* + * Various OpenType features might use the same glyphs at different + * vertical positions; for example, superscript and subscript glyphs + * could be the same. However, the auto-hinter is completely + * agnostic of OpenType features after the feature analysis has been + * completed: The engine then simply receives a glyph index and returns a + * hinted and usually rendered glyph. + * + * Consider the superscript feature of font `pala.ttf': Some of the + * glyphs are `real', this is, they have a zero vertical offset, but + * most of them are small caps glyphs shifted up to the superscript + * position (this is, the `sups' feature is present in both the GSUB and + * GPOS tables). The code for blue zones computation actually uses a + * feature's y offset so that the `real' glyphs get correct hints. But + * later on it is impossible to decide whether a glyph index belongs to, + * say, the small caps or superscript feature. + * + * For this reason, we don't assign a style to a glyph if the current + * feature covers the glyph in both the GSUB and the GPOS tables. This + * is quite a broad condition, assuming that + * + * (a) glyphs that get used in multiple features are present in a + * feature without vertical shift, + * + * and + * + * (b) a feature's GPOS data really moves the glyph vertically. + * + * Not fulfilling condition (a) makes a font larger; it would also + * reduce the number of glyphs that could be addressed directly without + * using OpenType features, so this assumption is rather strong. + * + * Condition (b) is much weaker, and there might be glyphs which get + * missed. However, the OpenType features we are going to handle are + * primarily located in GSUB, and HarfBuzz doesn't provide an API to + * directly get the necessary information from the GPOS table. A + * possible solution might be to directly parse the GPOS table to find + * out whether a glyph gets shifted vertically, but this is something I + * would like to avoid if not really necessary. + * + * Note that we don't follow this logic for the default coverage. + * Complex scripts like Devanagari have mandatory GPOS features to + * position many glyph elements, using mark-to-base or mark-to-ligature + * tables; the number of glyphs missed due to condition (b) would be far + * too large. + * + */ + if ( style_class->coverage != AF_COVERAGE_DEFAULT ) + hb_set_subtract( gsub_glyphs, gpos_glyphs ); + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " glyphs without GPOS data (`*' means already assigned)" )); + count = 0; +#endif + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_glyphs, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !( count % 10 ) ) + FT_TRACE4(( "\n" + " " )); + + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* glyph indices returned by `hb_ot_layout_lookup_collect_glyphs' */ + /* can be arbitrary: some fonts use fake indices for processing */ + /* internal to GSUB or GPOS, which is fully valid */ + if ( idx >= (hb_codepoint_t)globals->glyph_count ) + continue; + + if ( gstyles[idx] == AF_STYLE_UNASSIGNED ) + gstyles[idx] = (FT_UShort)style_class->style; +#ifdef FT_DEBUG_LEVEL_TRACE + else + FT_TRACE4(( "*" )); +#endif + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( "\n" + " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + Exit: + hb_set_destroy( gsub_lookups ); + hb_set_destroy( gsub_glyphs ); + hb_set_destroy( gpos_lookups ); + hb_set_destroy( gpos_glyphs ); + + return FT_Err_Ok; + } + + + /* construct HarfBuzz features */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + static const hb_feature_t name ## _feature[] = \ + { \ + { \ + HB_TAG( tag1, tag2, tag3, tag4 ), \ + 1, 0, (unsigned int)-1 \ + } \ + }; + + +#include "afcover.h" + + + /* define mapping between HarfBuzz features and AF_Coverage */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + name ## _feature, + + + static const hb_feature_t* features[] = + { +#include "afcover.h" + + NULL /* AF_COVERAGE_DEFAULT */ + }; + + + void* + af_shaper_buf_create( FT_Face face ) + { + FT_UNUSED( face ); + + return (void*)hb_buffer_create(); + } + + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ) + { + FT_UNUSED( face ); + + hb_buffer_destroy( (hb_buffer_t*)buf ); + } + + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ) + { + AF_StyleClass style_class; + const hb_feature_t* feature; + FT_Int upem; + const char* q; + int len; + + hb_buffer_t* buf = (hb_buffer_t*)buf_; + hb_font_t* font; + hb_codepoint_t dummy; + + + upem = (FT_Int)metrics->globals->face->units_per_EM; + style_class = metrics->style_class; + feature = features[style_class->coverage]; + + font = metrics->globals->hb_font; + + /* we shape at a size of units per EM; this means font units */ + hb_font_set_scale( font, upem, upem ); + + while ( *p == ' ' ) + p++; + + /* count bytes up to next space (or end of buffer) */ + q = p; + while ( !( *q == ' ' || *q == '\0' ) ) + GET_UTF8_CHAR( dummy, q ); + len = (int)( q - p ); + + /* feed character(s) to the HarfBuzz buffer */ + hb_buffer_clear_contents( buf ); + hb_buffer_add_utf8( buf, p, len, 0, len ); + + /* we let HarfBuzz guess the script and writing direction */ + hb_buffer_guess_segment_properties( buf ); + + /* shape buffer, which means conversion from character codes to */ + /* glyph indices, possibly applying a feature */ + hb_shape( font, buf, feature, feature ? 1 : 0 ); + + if ( feature ) + { + hb_buffer_t* hb_buf = metrics->globals->hb_buf; + + unsigned int gcount; + hb_glyph_info_t* ginfo; + + unsigned int hb_gcount; + hb_glyph_info_t* hb_ginfo; + + + /* we have to check whether applying a feature does actually change */ + /* glyph indices; otherwise the affected glyph or glyphs aren't */ + /* available at all in the feature */ + + hb_buffer_clear_contents( hb_buf ); + hb_buffer_add_utf8( hb_buf, p, len, 0, len ); + hb_buffer_guess_segment_properties( hb_buf ); + hb_shape( font, hb_buf, NULL, 0 ); + + ginfo = hb_buffer_get_glyph_infos( buf, &gcount ); + hb_ginfo = hb_buffer_get_glyph_infos( hb_buf, &hb_gcount ); + + if ( gcount == hb_gcount ) + { + unsigned int i; + + + for (i = 0; i < gcount; i++ ) + if ( ginfo[i].codepoint != hb_ginfo[i].codepoint ) + break; + + if ( i == gcount ) + { + /* both buffers have identical glyph indices */ + hb_buffer_clear_contents( buf ); + } + } + } + + *count = hb_buffer_get_length( buf ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( feature && *count > 1 ) + FT_TRACE1(( "af_shaper_get_cluster:" + " input character mapped to multiple glyphs\n" )); +#endif + + return q; + } + + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* advance, + FT_Long* y_offset ) + { + hb_buffer_t* buf = (hb_buffer_t*)buf_; + hb_glyph_info_t* ginfo; + hb_glyph_position_t* gpos; + unsigned int gcount; + + FT_UNUSED( metrics ); + + + ginfo = hb_buffer_get_glyph_infos( buf, &gcount ); + gpos = hb_buffer_get_glyph_positions( buf, &gcount ); + + if ( idx >= gcount ) + return 0; + + if ( advance ) + *advance = gpos[idx].x_advance; + if ( y_offset ) + *y_offset = gpos[idx].y_offset; + + return ginfo[idx].codepoint; + } + + +#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */ + + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ) + { + FT_UNUSED( globals ); + FT_UNUSED( style_class ); + FT_UNUSED( gstyles ); + FT_UNUSED( default_script ); + + return FT_Err_Ok; + } + + + void* + af_shaper_buf_create( FT_Face face ) + { + FT_Error error; + FT_Memory memory = face->memory; + FT_ULong* buf; + + + FT_MEM_ALLOC( buf, sizeof ( FT_ULong ) ); + + return (void*)buf; + } + + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ) + { + FT_Memory memory = face->memory; + + + FT_FREE( buf ); + } + + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ) + { + FT_Face face = metrics->globals->face; + FT_ULong ch, dummy = 0; + FT_ULong* buf = (FT_ULong*)buf_; + + + while ( *p == ' ' ) + p++; + + GET_UTF8_CHAR( ch, p ); + + /* since we don't have an engine to handle clusters, */ + /* we scan the characters but return zero */ + while ( !( *p == ' ' || *p == '\0' ) ) + GET_UTF8_CHAR( dummy, p ); + + if ( dummy ) + { + *buf = 0; + *count = 0; + } + else + { + *buf = FT_Get_Char_Index( face, ch ); + *count = 1; + } + + return p; + } + + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* advance, + FT_Long* y_offset ) + { + FT_Face face = metrics->globals->face; + FT_ULong glyph_index = *(FT_ULong*)buf_; + + FT_UNUSED( idx ); + + + if ( advance ) + FT_Get_Advance( face, + glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + advance ); + + if ( y_offset ) + *y_offset = 0; + + return glyph_index; + } + + +#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afshaper.h b/drivers/freetype/src/autofit/afshaper.h new file mode 100644 index 0000000000..0d41f78762 --- /dev/null +++ b/drivers/freetype/src/autofit/afshaper.h @@ -0,0 +1,72 @@ +/***************************************************************************/ +/* */ +/* afshaper.h */ +/* */ +/* HarfBuzz interface for accessing OpenType features (specification). */ +/* */ +/* Copyright 2013-2016 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 AFSHAPER_H_ +#define AFSHAPER_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + +#include <hb.h> +#include <hb-ot.h> +#include <hb-ft.h> + +#endif + + +FT_BEGIN_HEADER + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ); + + + void* + af_shaper_buf_create( FT_Face face ); + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ); + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ); + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* x_advance, + FT_Long* y_offset ); + + /* */ + +FT_END_HEADER + +#endif /* AFSHAPER_H_ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afstyles.h b/drivers/freetype/src/autofit/afstyles.h new file mode 100644 index 0000000000..e83a95bb59 --- /dev/null +++ b/drivers/freetype/src/autofit/afstyles.h @@ -0,0 +1,301 @@ +/***************************************************************************/ +/* */ +/* afstyles.h */ +/* */ +/* Auto-fitter styles (specification only). */ +/* */ +/* Copyright 2013-2016 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. */ +/* */ +/***************************************************************************/ + + + /* The following part can be included multiple times. */ + /* Define `STYLE' as needed. */ + + + /* Add new styles here. The first and second arguments are the */ + /* style name in lowercase and uppercase, respectively, followed */ + /* by a description string. The next arguments are the */ + /* corresponding writing system, script, blue stringset, and */ + /* coverage. */ + /* */ + /* Note that styles using `AF_COVERAGE_DEFAULT' should always */ + /* come after styles with other coverages. Also note that */ + /* fallback scripts only use `AF_COVERAGE_DEFAULT' for its */ + /* style. */ + /* */ + /* Example: */ + /* */ + /* STYLE( cyrl_dflt, CYRL_DFLT, */ + /* "Cyrillic default style", */ + /* AF_WRITING_SYSTEM_LATIN, */ + /* AF_SCRIPT_CYRL, */ + /* AF_BLUE_STRINGSET_CYRL, */ + /* AF_COVERAGE_DEFAULT ) */ + +#undef STYLE_LATIN +#define STYLE_LATIN( s, S, f, F, ds, df, C ) \ + STYLE( s ## _ ## f, S ## _ ## F, \ + ds " " df " style", \ + AF_WRITING_SYSTEM_LATIN, \ + AF_SCRIPT_ ## S, \ + AF_BLUE_STRINGSET_ ## S, \ + AF_COVERAGE_ ## C ) + +#undef META_STYLE_LATIN +#define META_STYLE_LATIN( s, S, ds ) \ + STYLE_LATIN( s, S, c2cp, C2CP, ds, \ + "petite capitals from capitals", \ + PETITE_CAPITALS_FROM_CAPITALS ) \ + STYLE_LATIN( s, S, c2sc, C2SC, ds, \ + "small capitals from capitals", \ + SMALL_CAPITALS_FROM_CAPITALS ) \ + STYLE_LATIN( s, S, ordn, ORDN, ds, \ + "ordinals", \ + ORDINALS ) \ + STYLE_LATIN( s, S, pcap, PCAP, ds, \ + "petite capitals", \ + PETITE_CAPITALS ) \ + STYLE_LATIN( s, S, sinf, SINF, ds, \ + "scientific inferiors", \ + SCIENTIFIC_INFERIORS ) \ + STYLE_LATIN( s, S, smcp, SMCP, ds, \ + "small capitals", \ + SMALL_CAPITALS ) \ + STYLE_LATIN( s, S, subs, SUBS, ds, \ + "subscript", \ + SUBSCRIPT ) \ + STYLE_LATIN( s, S, sups, SUPS, ds, \ + "superscript", \ + SUPERSCRIPT ) \ + STYLE_LATIN( s, S, titl, TITL, ds, \ + "titling", \ + TITLING ) \ + STYLE_LATIN( s, S, dflt, DFLT, ds, \ + "default", \ + DEFAULT ) + + + STYLE( arab_dflt, ARAB_DFLT, + "Arabic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ARAB, + AF_BLUE_STRINGSET_ARAB, + AF_COVERAGE_DEFAULT ) + + STYLE( armn_dflt, ARMN_DFLT, + "Armenian default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ARMN, + AF_BLUE_STRINGSET_ARMN, + AF_COVERAGE_DEFAULT ) + + STYLE( beng_dflt, BENG_DFLT, + "Bengali default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_BENG, + AF_BLUE_STRINGSET_BENG, + AF_COVERAGE_DEFAULT ) + + STYLE( cher_dflt, CHER_DFLT, + "Cherokee default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_CHER, + AF_BLUE_STRINGSET_CHER, + AF_COVERAGE_DEFAULT ) + + META_STYLE_LATIN( cyrl, CYRL, "Cyrillic" ) + + STYLE( deva_dflt, DEVA_DFLT, + "Devanagari default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_DEVA, + AF_BLUE_STRINGSET_DEVA, + AF_COVERAGE_DEFAULT ) + + STYLE( ethi_dflt, ETHI_DFLT, + "Ethiopic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ETHI, + AF_BLUE_STRINGSET_ETHI, + AF_COVERAGE_DEFAULT ) + + STYLE( geor_dflt, GEOR_DFLT, + "Georgian (Mkhedruli) default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GEOR, + AF_BLUE_STRINGSET_GEOR, + AF_COVERAGE_DEFAULT ) + + STYLE( geok_dflt, GEOK_DFLT, + "Georgian (Khutsuri) default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GEOK, + AF_BLUE_STRINGSET_GEOK, + AF_COVERAGE_DEFAULT ) + + META_STYLE_LATIN( grek, GREK, "Greek" ) + + STYLE( gujr_dflt, GUJR_DFLT, + "Gujarati default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GUJR, + AF_BLUE_STRINGSET_GUJR, + AF_COVERAGE_DEFAULT ) + + STYLE( guru_dflt, GURU_DFLT, + "Gurmukhi default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GURU, + AF_BLUE_STRINGSET_GURU, + AF_COVERAGE_DEFAULT ) + + STYLE( hebr_dflt, HEBR_DFLT, + "Hebrew default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_HEBR, + AF_BLUE_STRINGSET_HEBR, + AF_COVERAGE_DEFAULT ) + + STYLE( knda_dflt, KNDA_DFLT, + "Kannada default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KNDA, + AF_BLUE_STRINGSET_KNDA, + AF_COVERAGE_DEFAULT ) + + STYLE( khmr_dflt, KHMR_DFLT, + "Khmer default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KHMR, + AF_BLUE_STRINGSET_KHMR, + AF_COVERAGE_DEFAULT ) + + STYLE( khms_dflt, KHMS_DFLT, + "Khmer Symbols default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KHMS, + AF_BLUE_STRINGSET_KHMS, + AF_COVERAGE_DEFAULT ) + + STYLE( lao_dflt, LAO_DFLT, + "Lao default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_LAO, + AF_BLUE_STRINGSET_LAO, + AF_COVERAGE_DEFAULT ) + + META_STYLE_LATIN( latn, LATN, "Latin" ) + + STYLE( latb_dflt, LATB_DFLT, + "Latin subscript fallback default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_LATB, + AF_BLUE_STRINGSET_LATB, + AF_COVERAGE_DEFAULT ) + + STYLE( latp_dflt, LATP_DFLT, + "Latin superscript fallback default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_LATP, + AF_BLUE_STRINGSET_LATP, + AF_COVERAGE_DEFAULT ) + +#ifdef FT_OPTION_AUTOFIT2 + STYLE( ltn2_dflt, LTN2_DFLT, + "Latin 2 default style", + AF_WRITING_SYSTEM_LATIN2, + AF_SCRIPT_LATN, + AF_BLUE_STRINGSET_LATN, + AF_COVERAGE_DEFAULT ) +#endif + + STYLE( mlym_dflt, MLYM_DFLT, + "Malayalam default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_MLYM, + AF_BLUE_STRINGSET_MLYM, + AF_COVERAGE_DEFAULT ) + + STYLE( mymr_dflt, MYMR_DFLT, + "Myanmar default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_MYMR, + AF_BLUE_STRINGSET_MYMR, + AF_COVERAGE_DEFAULT ) + + STYLE( none_dflt, NONE_DFLT, + "no style", + AF_WRITING_SYSTEM_DUMMY, + AF_SCRIPT_NONE, + AF_BLUE_STRINGSET_NONE, + AF_COVERAGE_DEFAULT ) + + STYLE( sinh_dflt, SINH_DFLT, + "Sinhala default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_SINH, + AF_BLUE_STRINGSET_SINH, + AF_COVERAGE_DEFAULT ) + + STYLE( taml_dflt, TAML_DFLT, + "Tamil default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_TAML, + AF_BLUE_STRINGSET_TAML, + AF_COVERAGE_DEFAULT ) + + STYLE( telu_dflt, TELU_DFLT, + "Telugu default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_TELU, + AF_BLUE_STRINGSET_TELU, + AF_COVERAGE_DEFAULT ) + + STYLE( thai_dflt, THAI_DFLT, + "Thai default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_THAI, + AF_BLUE_STRINGSET_THAI, + AF_COVERAGE_DEFAULT ) + +#ifdef AF_CONFIG_OPTION_INDIC + + /* no blue stringset support for the Indic writing system yet */ +#undef STYLE_DEFAULT_INDIC +#define STYLE_DEFAULT_INDIC( s, S, d ) \ + STYLE( s ## _dflt, S ## _DFLT, \ + d " default style", \ + AF_WRITING_SYSTEM_INDIC, \ + AF_SCRIPT_ ## S, \ + (AF_Blue_Stringset)0, \ + AF_COVERAGE_DEFAULT ) + + STYLE_DEFAULT_INDIC( limb, LIMB, "Limbu" ) + STYLE_DEFAULT_INDIC( orya, ORYA, "Oriya" ) + STYLE_DEFAULT_INDIC( sund, SUND, "Sundanese" ) + STYLE_DEFAULT_INDIC( sylo, SYLO, "Syloti Nagri" ) + STYLE_DEFAULT_INDIC( tibt, TIBT, "Tibetan" ) + +#endif /* AF_CONFIG_OPTION_INDIC */ + +#ifdef AF_CONFIG_OPTION_CJK + + STYLE( hani_dflt, HANI_DFLT, + "CJKV ideographs default style", + AF_WRITING_SYSTEM_CJK, + AF_SCRIPT_HANI, + AF_BLUE_STRINGSET_HANI, + AF_COVERAGE_DEFAULT ) + +#endif /* AF_CONFIG_OPTION_CJK */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/aftypes.h b/drivers/freetype/src/autofit/aftypes.h index 9acd7ad6d2..ef62043c8a 100644 --- a/drivers/freetype/src/autofit/aftypes.h +++ b/drivers/freetype/src/autofit/aftypes.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter types (specification only). */ /* */ -/* Copyright 2003-2009, 2011-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,20 +20,17 @@ * * The auto-fitter is a complete rewrite of the old auto-hinter. * Its main feature is the ability to differentiate between different - * scripts in order to apply language-specific rules. + * writing systems and scripts in order to apply specific rules. * - * The code has also been compartmentized into several entities that + * The code has also been compartmentalized into several entities that * should make algorithmic experimentation easier than with the old * code. * - * Finally, we get rid of the Catharon license, since this code is - * released under the FreeType one. - * *************************************************************************/ -#ifndef __AFTYPES_H__ -#define __AFTYPES_H__ +#ifndef AFTYPES_H_ +#define AFTYPES_H_ #include <ft2build.h> @@ -42,6 +39,12 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include "afblue.h" + +#ifdef FT_DEBUG_AUTOFIT +#include FT_CONFIG_STANDARD_LIBRARY_H +#endif + FT_BEGIN_HEADER @@ -55,8 +58,6 @@ FT_BEGIN_HEADER #ifdef FT_DEBUG_AUTOFIT -#include FT_CONFIG_STANDARD_LIBRARY_H - extern int _af_debug_disable_horz_hints; extern int _af_debug_disable_vert_hints; extern int _af_debug_disable_blue_hints; @@ -139,11 +140,10 @@ extern void* _af_debug_hints; AF_Angle _delta = (angle2) - (angle1); \ \ \ - _delta %= AF_ANGLE_2PI; \ - if ( _delta < 0 ) \ + while ( _delta <= -AF_ANGLE_PI ) \ _delta += AF_ANGLE_2PI; \ \ - if ( _delta > AF_ANGLE_PI ) \ + while ( _delta > AF_ANGLE_PI ) \ _delta -= AF_ANGLE_2PI; \ \ result = _delta; \ @@ -169,13 +169,10 @@ extern void* _af_debug_hints; * auto-hinted glyph image. */ - typedef enum AF_ScalerFlags_ - { - AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ - AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ - AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */ - - } AF_ScalerFlags; +#define AF_SCALER_FLAG_NO_HORIZONTAL 1U /* disable horizontal hinting */ +#define AF_SCALER_FLAG_NO_VERTICAL 2U /* disable vertical hinting */ +#define AF_SCALER_FLAG_NO_ADVANCE 4U /* disable advance hinting */ +#define AF_SCALER_FLAG_NO_WARPER 8U /* disable warper */ typedef struct AF_ScalerRec_ @@ -198,90 +195,132 @@ extern void* _af_debug_hints; (a)->y_delta == (b)->y_delta ) + typedef struct AF_StyleMetricsRec_* AF_StyleMetrics; + + /* This function parses an FT_Face to compute global metrics for + * a specific style. + */ + typedef FT_Error + (*AF_WritingSystem_InitMetricsFunc)( AF_StyleMetrics metrics, + FT_Face face ); + + typedef void + (*AF_WritingSystem_ScaleMetricsFunc)( AF_StyleMetrics metrics, + AF_Scaler scaler ); + + typedef void + (*AF_WritingSystem_DoneMetricsFunc)( AF_StyleMetrics metrics ); + + typedef void + (*AF_WritingSystem_GetStdWidthsFunc)( AF_StyleMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ); + + + typedef FT_Error + (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints hints, + AF_StyleMetrics metrics ); + + typedef void + (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt glyph_index, + AF_GlyphHints hints, + FT_Outline* outline, + AF_StyleMetrics metrics ); + + /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** S C R I P T S *****/ + /***** W R I T I N G S Y S T E M S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* - * The list of known scripts. Each different script corresponds to the - * following information: + * For the auto-hinter, a writing system consists of multiple scripts that + * can be handled similarly *in a typographical way*; the relationship is + * not based on history. For example, both the Greek and the unrelated + * Armenian scripts share the same features like ascender, descender, + * x-height, etc. Essentially, a writing system is covered by a + * submodule of the auto-fitter; it contains * - * - A set of Unicode ranges to test whether the face supports the - * script. + * - a specific global analyzer that computes global metrics specific to + * the script (based on script-specific characters to identify ascender + * height, x-height, etc.), * - * - A specific global analyzer that will compute global metrics - * specific to the script. + * - a specific glyph analyzer that computes segments and edges for each + * glyph covered by the script, * - * - A specific glyph analyzer that will compute segments and - * edges for each glyph covered by the script. - * - * - A specific grid-fitting algorithm that will distort the - * scaled glyph outline according to the results of the glyph - * analyzer. - * - * Note that a given analyzer and/or grid-fitting algorithm can be - * used by more than one script. + * - a specific grid-fitting algorithm that distorts the scaled glyph + * outline according to the results of the glyph analyzer. */ - typedef enum AF_Script_ +#define AFWRTSYS_H_ /* don't load header files */ +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) \ + AF_WRITING_SYSTEM_ ## WS, + + /* The list of known writing systems. */ + typedef enum AF_WritingSystem_ { - AF_SCRIPT_DUMMY = 0, - AF_SCRIPT_LATIN = 1, - AF_SCRIPT_CJK = 2, - AF_SCRIPT_INDIC = 3, -#ifdef FT_OPTION_AUTOFIT2 - AF_SCRIPT_LATIN2 = 4, -#endif - /* add new scripts here. Don't forget to update the list in */ - /* `afglobal.c'. */ +#include "afwrtsys.h" - AF_SCRIPT_MAX /* do not remove */ + AF_WRITING_SYSTEM_MAX /* do not remove */ - } AF_Script; + } AF_WritingSystem; +#undef AFWRTSYS_H_ - typedef struct AF_ScriptClassRec_ const* AF_ScriptClass; - typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; - typedef struct AF_ScriptMetricsRec_ + typedef struct AF_WritingSystemClassRec_ { - AF_ScriptClass clazz; - AF_ScalerRec scaler; - FT_Bool digits_have_same_width; + AF_WritingSystem writing_system; - AF_FaceGlobals globals; /* to access properties */ + FT_Offset style_metrics_size; + AF_WritingSystem_InitMetricsFunc style_metrics_init; + AF_WritingSystem_ScaleMetricsFunc style_metrics_scale; + AF_WritingSystem_DoneMetricsFunc style_metrics_done; + AF_WritingSystem_GetStdWidthsFunc style_metrics_getstdw; - } AF_ScriptMetricsRec, *AF_ScriptMetrics; + AF_WritingSystem_InitHintsFunc style_hints_init; + AF_WritingSystem_ApplyHintsFunc style_hints_apply; + } AF_WritingSystemClassRec; - /* This function parses an FT_Face to compute global metrics for - * a specific script. + typedef const AF_WritingSystemClassRec* AF_WritingSystemClass; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S C R I P T S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * Each script is associated with two sets of Unicode ranges to test + * whether the font face supports the script, and which non-base + * characters the script contains. + * + * We use four-letter script tags from the OpenType specification, + * extended by `NONE', which indicates `no script'. */ - typedef FT_Error - (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, - FT_Face face ); - typedef void - (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics, - AF_Scaler scaler ); +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + AF_SCRIPT_ ## S, - typedef void - (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics ); + /* The list of known scripts. */ + typedef enum AF_Script_ + { +#include "afscript.h" - typedef FT_Error - (*AF_Script_InitHintsFunc)( AF_GlyphHints hints, - AF_ScriptMetrics metrics ); + AF_SCRIPT_MAX /* do not remove */ - typedef void - (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints, - FT_Outline* outline, - AF_ScriptMetrics metrics ); + } AF_Script; typedef struct AF_Script_UniRangeRec_ @@ -293,76 +332,309 @@ extern void* _af_debug_hints; #define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } - typedef const AF_Script_UniRangeRec *AF_Script_UniRange; + typedef const AF_Script_UniRangeRec* AF_Script_UniRange; typedef struct AF_ScriptClassRec_ { - AF_Script script; - AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ - FT_UInt32 standard_char; /* for default width and height */ + AF_Script script; + + /* last element in the ranges must be { 0, 0 } */ + AF_Script_UniRange script_uni_ranges; + AF_Script_UniRange script_uni_nonbase_ranges; - FT_Offset script_metrics_size; - AF_Script_InitMetricsFunc script_metrics_init; - AF_Script_ScaleMetricsFunc script_metrics_scale; - AF_Script_DoneMetricsFunc script_metrics_done; + FT_Bool top_to_bottom_hinting; - AF_Script_InitHintsFunc script_hints_init; - AF_Script_ApplyHintsFunc script_hints_apply; + const char* standard_charstring; /* for default width and height */ } AF_ScriptClassRec; + typedef const AF_ScriptClassRec* AF_ScriptClass; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C O V E R A G E S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * Usually, a font contains more glyphs than can be addressed by its + * character map. + * + * In the PostScript font world, encoding vectors specific to a given + * task are used to select such glyphs, and these glyphs can be often + * recognized by having a suffix in its glyph names. For example, a + * superscript glyph `A' might be called `A.sup'. Unfortunately, this + * naming scheme is not standardized and thus unusable for us. + * + * In the OpenType world, a better solution was invented, namely + * `features', which cleanly separate a character's input encoding from + * the corresponding glyph's appearance, and which don't use glyph names + * at all. For our purposes, and slightly generalized, an OpenType + * feature is a name of a mapping that maps character codes to + * non-standard glyph indices (features get used for other things also). + * For example, the `sups' feature provides superscript glyphs, thus + * mapping character codes like `A' or `B' to superscript glyph + * representation forms. How this mapping happens is completely + * uninteresting to us. + * + * For the auto-hinter, a `coverage' represents all glyphs of an OpenType + * feature collected in a set (as listed below) that can be hinted + * together. To continue the above example, superscript glyphs must not + * be hinted together with normal glyphs because the blue zones + * completely differ. + * + * Note that FreeType itself doesn't compute coverages; it only provides + * the glyphs addressable by the default Unicode character map. Instead, + * we use the HarfBuzz library (if available), which has many functions + * exactly for this purpose. + * + * AF_COVERAGE_DEFAULT is special: It should cover everything that isn't + * listed separately (including the glyphs addressable by the character + * map). In case HarfBuzz isn't available, it exactly covers the glyphs + * addressable by the character map. + * + */ + +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + AF_COVERAGE_ ## NAME, + + + typedef enum AF_Coverage_ + { +#include "afcover.h" + + AF_COVERAGE_DEFAULT + + } AF_Coverage; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S T Y L E S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The topmost structure for modelling the auto-hinter glyph input data + * is a `style class', grouping everything together. + */ + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) \ + AF_STYLE_ ## S, + + /* The list of known styles. */ + typedef enum AF_Style_ + { + +#include "afstyles.h" + + AF_STYLE_MAX /* do not remove */ + + } AF_Style; + + + typedef struct AF_StyleClassRec_ + { + AF_Style style; + + AF_WritingSystem writing_system; + AF_Script script; + AF_Blue_Stringset blue_stringset; + AF_Coverage coverage; + + } AF_StyleClassRec; + + typedef const AF_StyleClassRec* AF_StyleClass; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S T Y L E M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; + + /* This is the main structure that combines everything. Autofit modules */ + /* specific to writing systems derive their structures from it, for */ + /* example `AF_LatinMetrics'. */ + + typedef struct AF_StyleMetricsRec_ + { + AF_StyleClass style_class; + AF_ScalerRec scaler; + FT_Bool digits_have_same_width; + + AF_FaceGlobals globals; /* to access properties */ + + } AF_StyleMetricsRec; + + +#define AF_HINTING_BOTTOM_TO_TOP 0 +#define AF_HINTING_TOP_TO_BOTTOM 1 + /* Declare and define vtables for classes */ #ifndef FT_CONFIG_OPTION_PIC +#define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class ) \ + FT_CALLBACK_TABLE const AF_WritingSystemClassRec \ + writing_system_class; + +#define AF_DEFINE_WRITING_SYSTEM_CLASS( \ + writing_system_class, \ + system, \ + m_size, \ + m_init, \ + m_scale, \ + m_done, \ + m_stdw, \ + h_init, \ + h_apply ) \ + FT_CALLBACK_TABLE_DEF \ + const AF_WritingSystemClassRec writing_system_class = \ + { \ + system, \ + \ + m_size, \ + \ + m_init, \ + m_scale, \ + m_done, \ + m_stdw, \ + \ + h_init, \ + h_apply \ + }; + + #define AF_DECLARE_SCRIPT_CLASS( script_class ) \ FT_CALLBACK_TABLE const AF_ScriptClassRec \ script_class; -#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \ - m_size, \ - m_init, m_scale, m_done, h_init, h_apply ) \ - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec script_class = \ - { \ - script_, \ - ranges, \ - def_char, \ - \ - m_size, \ - \ - m_init, \ - m_scale, \ - m_done, \ - \ - h_init, \ - h_apply \ +#define AF_DEFINE_SCRIPT_CLASS( \ + script_class, \ + script, \ + ranges, \ + nonbase_ranges, \ + top_to_bottom, \ + std_charstring ) \ + FT_CALLBACK_TABLE_DEF \ + const AF_ScriptClassRec script_class = \ + { \ + script, \ + ranges, \ + nonbase_ranges, \ + top_to_bottom, \ + std_charstring, \ + }; + + +#define AF_DECLARE_STYLE_CLASS( style_class ) \ + FT_CALLBACK_TABLE const AF_StyleClassRec \ + style_class; + +#define AF_DEFINE_STYLE_CLASS( \ + style_class, \ + style, \ + writing_system, \ + script, \ + blue_stringset, \ + coverage ) \ + FT_CALLBACK_TABLE_DEF \ + const AF_StyleClassRec style_class = \ + { \ + style, \ + writing_system, \ + script, \ + blue_stringset, \ + coverage \ }; #else /* FT_CONFIG_OPTION_PIC */ +#define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class ) \ + FT_LOCAL( void ) \ + FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec* ac ); + +#define AF_DEFINE_WRITING_SYSTEM_CLASS( \ + writing_system_class, \ + system, \ + m_size, \ + m_init, \ + m_scale, \ + m_done, \ + h_init, \ + h_apply ) \ + FT_LOCAL_DEF( void ) \ + FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec* ac ) \ + { \ + ac->writing_system = system; \ + \ + ac->style_metrics_size = m_size; \ + \ + ac->style_metrics_init = m_init; \ + ac->style_metrics_scale = m_scale; \ + ac->style_metrics_done = m_done; \ + ac->style_metrics_getstdw = m_stdw; \ + \ + ac->style_hints_init = h_init; \ + ac->style_hints_apply = h_apply; \ + } + + #define AF_DECLARE_SCRIPT_CLASS( script_class ) \ FT_LOCAL( void ) \ FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ); -#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \ - m_size, \ - m_init, m_scale, m_done, h_init, h_apply ) \ - FT_LOCAL_DEF( void ) \ - FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \ - { \ - ac->script = script_; \ - ac->script_uni_ranges = ranges; \ - ac->default_char = def_char; \ - \ - ac->script_metrics_size = m_size; \ - \ - ac->script_metrics_init = m_init; \ - ac->script_metrics_scale = m_scale; \ - ac->script_metrics_done = m_done; \ - \ - ac->script_hints_init = h_init; \ - ac->script_hints_apply = h_apply; \ +#define AF_DEFINE_SCRIPT_CLASS( \ + script_class, \ + script_, \ + ranges, \ + nonbase_ranges, \ + top_to_bottom, \ + std_charstring ) \ + FT_LOCAL_DEF( void ) \ + FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \ + { \ + ac->script = script_; \ + ac->script_uni_ranges = ranges; \ + ac->script_uni_nonbase_ranges = nonbase_ranges; \ + ac->top_to_bottom_hinting = top_to_bottom; \ + ac->standard_charstring = std_charstring; \ + } + + +#define AF_DECLARE_STYLE_CLASS( style_class ) \ + FT_LOCAL( void ) \ + FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ); + +#define AF_DEFINE_STYLE_CLASS( \ + style_class, \ + style_, \ + writing_system_, \ + script_, \ + blue_stringset_, \ + coverage_ ) \ + FT_LOCAL_DEF( void ) \ + FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ) \ + { \ + ac->style = style_; \ + ac->writing_system = writing_system_; \ + ac->script = script_; \ + ac->blue_stringset = blue_stringset_; \ + ac->coverage = coverage_; \ } #endif /* FT_CONFIG_OPTION_PIC */ @@ -372,7 +644,7 @@ extern void* _af_debug_hints; FT_END_HEADER -#endif /* __AFTYPES_H__ */ +#endif /* AFTYPES_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afwarp.c b/drivers/freetype/src/autofit/afwarp.c index 34a97ffc57..ce1806c9d3 100644 --- a/drivers/freetype/src/autofit/afwarp.c +++ b/drivers/freetype/src/autofit/afwarp.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter warping algorithm (body). */ /* */ -/* Copyright 2006, 2007, 2011 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,10 +76,10 @@ FT_Pos xx2, AF_WarpScore base_distort, AF_Segment segments, - FT_UInt num_segments ) + FT_Int num_segments ) { FT_Int idx_min, idx_max, idx0; - FT_UInt nn; + FT_Int nn; AF_WarpScore scores[65]; @@ -171,7 +171,7 @@ FT_Fixed org_scale; FT_Pos org_delta; - FT_UInt nn, num_points, num_segments; + FT_Int nn, num_points, num_segments; FT_Int X1, X2; FT_Int w; @@ -193,7 +193,7 @@ warper->best_scale = org_scale; warper->best_delta = org_delta; - warper->best_score = INT_MIN; + warper->best_score = FT_INT_MIN; warper->best_distort = 0; axis = &hints->axis[dim]; diff --git a/drivers/freetype/src/autofit/afwarp.h b/drivers/freetype/src/autofit/afwarp.h index 7343fdd5ef..6d96f86d73 100644 --- a/drivers/freetype/src/autofit/afwarp.h +++ b/drivers/freetype/src/autofit/afwarp.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter warping algorithm (specification). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFWARP_H__ -#define __AFWARP_H__ +#ifndef AFWARP_H_ +#define AFWARP_H_ #include "afhints.h" @@ -25,7 +25,7 @@ FT_BEGIN_HEADER #define AF_WARPER_SCALE -#define AF_WARPER_FLOOR( x ) ( (x) & ~63 ) +#define AF_WARPER_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) #define AF_WARPER_CEIL( x ) AF_WARPER_FLOOR( (x) + 63 ) @@ -58,7 +58,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFWARP_H__ */ +#endif /* AFWARP_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afwrtsys.h b/drivers/freetype/src/autofit/afwrtsys.h new file mode 100644 index 0000000000..842f4921a4 --- /dev/null +++ b/drivers/freetype/src/autofit/afwrtsys.h @@ -0,0 +1,52 @@ +/***************************************************************************/ +/* */ +/* afwrtsys.h */ +/* */ +/* Auto-fitter writing systems (specification only). */ +/* */ +/* Copyright 2013-2016 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 AFWRTSYS_H_ +#define AFWRTSYS_H_ + + /* Since preprocessor directives can't create other preprocessor */ + /* directives, we have to include the header files manually. */ + +#include "afdummy.h" +#include "aflatin.h" +#include "afcjk.h" +#include "afindic.h" +#ifdef FT_OPTION_AUTOFIT2 +#include "aflatin2.h" +#endif + +#endif /* AFWRTSYS_H_ */ + + + /* The following part can be included multiple times. */ + /* Define `WRITING_SYSTEM' as needed. */ + + + /* Add new writing systems here. The arguments are the writing system */ + /* name in lowercase and uppercase, respectively. */ + + WRITING_SYSTEM( dummy, DUMMY ) + WRITING_SYSTEM( latin, LATIN ) + WRITING_SYSTEM( cjk, CJK ) + WRITING_SYSTEM( indic, INDIC ) +#ifdef FT_OPTION_AUTOFIT2 + WRITING_SYSTEM( latin2, LATIN2 ) +#endif + + +/* END */ diff --git a/drivers/freetype/src/autofit/autofit.c b/drivers/freetype/src/autofit/autofit.c index 3883a0a706..dda9aeb6d7 100644 --- a/drivers/freetype/src/autofit/autofit.c +++ b/drivers/freetype/src/autofit/autofit.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module (body). */ /* */ -/* Copyright 2003-2007, 2011 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,9 +20,12 @@ #include <ft2build.h> #include "afpic.c" #include "afangles.c" +#include "afblue.c" #include "afglobal.c" #include "afhints.c" +#include "afranges.c" + #include "afdummy.c" #include "aflatin.c" #ifdef FT_OPTION_AUTOFIT2 @@ -31,6 +34,8 @@ #include "afcjk.c" #include "afindic.c" +#include "afshaper.c" + #include "afloader.c" #include "afmodule.c" diff --git a/drivers/freetype/src/autofit/module.mk b/drivers/freetype/src/autofit/module.mk index 6ec60912ab..98f0612b99 100644 --- a/drivers/freetype/src/autofit/module.mk +++ b/drivers/freetype/src/autofit/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2003, 2004, 2005, 2006 by +# Copyright 2003-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/autofit/rules.mk b/drivers/freetype/src/autofit/rules.mk index b76bb79ab4..1ef4704649 100644 --- a/drivers/freetype/src/autofit/rules.mk +++ b/drivers/freetype/src/autofit/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2003, 2004, 2005, 2006, 2007, 2011 by +# Copyright 2003-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,12 +20,16 @@ AUTOF_DIR := $(SRC_DIR)/autofit # compilation flags for the driver # -AUTOF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR)) +AUTOF_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # AUTOF driver sources (i.e., C files) # AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ + $(AUTOF_DIR)/afblue.c \ $(AUTOF_DIR)/afcjk.c \ $(AUTOF_DIR)/afdummy.c \ $(AUTOF_DIR)/afglobal.c \ @@ -35,13 +39,19 @@ AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ $(AUTOF_DIR)/afloader.c \ $(AUTOF_DIR)/afmodule.c \ $(AUTOF_DIR)/afpic.c \ + $(AUTOF_DIR)/afranges.c \ + $(AUTOF_DIR)/afshaper.c \ $(AUTOF_DIR)/afwarp.c # AUTOF driver headers # AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ + $(AUTOF_DIR)/afcover.h \ $(AUTOF_DIR)/aferrors.h \ - $(AUTOF_DIR)/aftypes.h + $(AUTOF_DIR)/afscript.h \ + $(AUTOF_DIR)/afstyles.h \ + $(AUTOF_DIR)/aftypes.h \ + $(AUTOF_DIR)/afwrtsys.h # AUTOF driver object(s) diff --git a/drivers/freetype/src/base/Jamfile b/drivers/freetype/src/base/Jamfile index 832e8b8424..cfc69657fe 100644 --- a/drivers/freetype/src/base/Jamfile +++ b/drivers/freetype/src/base/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/base Jamfile # -# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,10 +17,20 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; if $(FT2_MULTI) { - _sources = ftadvanc ftcalc ftdbgmem ftgloadr - ftobjs ftoutln ftrfork ftsnames - ftstream fttrigon ftutil - basepic ftpic + _sources = basepic + ftadvanc + ftcalc + ftdbgmem + ftgloadr + fthash + ftobjs + ftoutln + ftpic + ftrfork + ftsnames + ftstream + fttrigon + ftutil ; } else @@ -34,13 +44,31 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; # Add the optional/replaceable files. # { - local _sources = bbox bdf bitmap debug gasp - glyph gxval init lcdfil mm - otval pfr stroke synth system - type1 winfnt xf86 patent + local _sources = ftapi + ftbbox + ftbdf + ftbitmap + ftcid + ftdebug + ftfntfmt + ftfstype + ftgasp + ftglyph + ftgxval + ftinit + ftlcdfil + ftmm + ftotval + ftpatent + ftpfr + ftstroke + ftsynth + ftsystem + fttype1 + ftwinfnt ; - Library $(FT2_LIB) : ft$(_sources).c ; + Library $(FT2_LIB) : $(_sources).c ; } # Add Macintosh-specific file to the library when necessary. diff --git a/drivers/freetype/src/base/basepic.c b/drivers/freetype/src/base/basepic.c index 0af770ebc2..f2cea90d7c 100644 --- a/drivers/freetype/src/base/basepic.c +++ b/drivers/freetype/src/base/basepic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,7 @@ /* forward declaration of PIC init function from ftrfork.c */ /* (not modularized) */ void - FT_Init_Table_raccess_guess_table( ft_raccess_guess_rec* record ); + FT_Init_Table_ft_raccess_guess_table( ft_raccess_guess_rec* record ); #endif /* forward declaration of PIC init functions from ftinit.c */ @@ -92,7 +92,7 @@ FT_Init_Class_ft_bitmap_glyph_class( &container->ft_bitmap_glyph_class ); #ifdef FT_CONFIG_OPTION_MAC_FONTS - FT_Init_Table_raccess_guess_table( + FT_Init_Table_ft_raccess_guess_table( (ft_raccess_guess_rec*)&container->ft_raccess_guess_table ); #endif diff --git a/drivers/freetype/src/base/basepic.h b/drivers/freetype/src/base/basepic.h index 329d7c8fd6..a1a75a0bad 100644 --- a/drivers/freetype/src/base/basepic.h +++ b/drivers/freetype/src/base/basepic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,14 +16,13 @@ /***************************************************************************/ -#ifndef __BASEPIC_H__ -#define __BASEPIC_H__ +#ifndef BASEPIC_H_ +#define BASEPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H + #ifndef FT_CONFIG_OPTION_PIC #define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class @@ -43,6 +42,8 @@ FT_BEGIN_HEADER #endif +FT_BEGIN_HEADER + typedef struct BasePIC_ { FT_Module_Class** default_module_classes; @@ -78,13 +79,13 @@ FT_BEGIN_HEADER FT_Error ft_base_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __BASEPIC_H__ */ +#endif /* BASEPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/base/ftadvanc.c b/drivers/freetype/src/base/ftadvanc.c index 52078478df..9e2ab89845 100644 --- a/drivers/freetype/src/base/ftadvanc.c +++ b/drivers/freetype/src/base/ftadvanc.c @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (body). */ /* */ -/* Copyright 2008, 2009, 2011, 2013 by */ +/* Copyright 2008-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -60,10 +60,12 @@ /* - unscaled load */ /* - unhinted load */ /* - light-hinted load */ + /* - neither a MM nor a GX font */ -#define LOAD_ADVANCE_FAST_CHECK( flags ) \ - ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ - FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) +#define LOAD_ADVANCE_FAST_CHECK( face, flags ) \ + ( ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ + FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) && \ + !FT_HAS_MULTIPLE_MASTERS( face ) ) /* documentation is in ftadvanc.h */ @@ -80,11 +82,14 @@ if ( !face ) return FT_THROW( Invalid_Face_Handle ); + if ( !padvance ) + return FT_THROW( Invalid_Argument ); + if ( gindex >= (FT_UInt)face->num_glyphs ) return FT_THROW( Invalid_Glyph_Index ); func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { FT_Error error; @@ -118,6 +123,9 @@ if ( !face ) return FT_THROW( Invalid_Face_Handle ); + if ( !padvances ) + return FT_THROW( Invalid_Argument ); + num = (FT_UInt)face->num_glyphs; end = start + count; if ( start >= num || end < start || end > num ) @@ -127,7 +135,7 @@ return FT_Err_Ok; func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { error = func( face, start, count, flags, padvances ); if ( !error ) @@ -151,8 +159,8 @@ /* scale from 26.6 to 16.16 */ padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) - ? face->glyph->advance.y << 10 - : face->glyph->advance.x << 10; + ? face->glyph->advance.y * 1024 + : face->glyph->advance.x * 1024; } return error; diff --git a/drivers/freetype/src/base/ftapi.c b/drivers/freetype/src/base/ftapi.c index 8914d1f4e9..b94c3eb9fb 100644 --- a/drivers/freetype/src/base/ftapi.c +++ b/drivers/freetype/src/base/ftapi.c @@ -4,7 +4,7 @@ /* */ /* The FreeType compatibility functions (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/base/ftbase.c b/drivers/freetype/src/base/ftbase.c index 5e5d70ec4b..ab1af6f9f3 100644 --- a/drivers/freetype/src/base/ftbase.c +++ b/drivers/freetype/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include "ftcalc.c" #include "ftdbgmem.c" #include "ftgloadr.c" +#include "fthash.c" #include "ftobjs.c" #include "ftoutln.c" #include "ftrfork.c" diff --git a/drivers/freetype/src/base/ftbase.h b/drivers/freetype/src/base/ftbase.h index 51a1db18b8..717fdaae24 100644 --- a/drivers/freetype/src/base/ftbase.h +++ b/drivers/freetype/src/base/ftbase.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private functions used in base module (specification). */ /* */ -/* Copyright 2008, 2010 by */ +/* Copyright 2008-2016 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBASE_H__ -#define __FTBASE_H__ +#ifndef FTBASE_H_ +#define FTBASE_H_ #include <ft2build.h> @@ -27,6 +27,11 @@ FT_BEGIN_HEADER + /* MacOS resource fork cannot exceed 16MB at least for Carbon code; */ + /* see https://support.microsoft.com/en-us/kb/130437 */ +#define FT_MAC_RFORK_MAX_LEN 0x00FFFFFFUL + + /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ /* font, and try to load a face specified by the face_index. */ FT_LOCAL( FT_Error ) @@ -63,7 +68,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBASE_H__ */ +#endif /* FTBASE_H_ */ /* END */ diff --git a/drivers/freetype/src/base/ftbbox.c b/drivers/freetype/src/base/ftbbox.c index 6d1c44cb2e..d3e45ffa0d 100644 --- a/drivers/freetype/src/base/ftbbox.c +++ b/drivers/freetype/src/base/ftbbox.c @@ -4,7 +4,7 @@ /* */ /* FreeType bbox computation (body). */ /* */ -/* Copyright 1996-2002, 2004, 2006, 2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -42,16 +42,35 @@ } TBBox_Rec; +#define FT_UPDATE_BBOX( p, bbox ) \ + FT_BEGIN_STMNT \ + if ( p->x < bbox.xMin ) \ + bbox.xMin = p->x; \ + if ( p->x > bbox.xMax ) \ + bbox.xMax = p->x; \ + if ( p->y < bbox.yMin ) \ + bbox.yMin = p->y; \ + if ( p->y > bbox.yMax ) \ + bbox.yMax = p->y; \ + FT_END_STMNT + +#define CHECK_X( p, bbox ) \ + ( p->x < bbox.xMin || p->x > bbox.xMax ) + +#define CHECK_Y( p, bbox ) \ + ( p->y < bbox.yMin || p->y > bbox.yMax ) + + /*************************************************************************/ /* */ /* <Function> */ /* BBox_Move_To */ /* */ /* <Description> */ - /* This function is used as a `move_to' and `line_to' emitter during */ + /* This function is used as a `move_to' emitter during */ /* FT_Outline_Decompose(). It simply records the destination point */ - /* in `user->last'; no further computations are necessary since we */ - /* use the cbox as the starting bbox which must be refined. */ + /* in `user->last'. We also update bbox in case contour starts with */ + /* an implicit `on' point. */ /* */ /* <Input> */ /* to :: A pointer to the destination vector. */ @@ -66,17 +85,42 @@ BBox_Move_To( FT_Vector* to, TBBox_Rec* user ) { + FT_UPDATE_BBOX( to, user->bbox ); + user->last = *to; return 0; } -#define CHECK_X( p, bbox ) \ - ( p->x < bbox.xMin || p->x > bbox.xMax ) + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Line_To */ + /* */ + /* <Description> */ + /* This function is used as a `line_to' emitter during */ + /* FT_Outline_Decompose(). It simply records the destination point */ + /* in `user->last'; no further computations are necessary because */ + /* bbox already contains both explicit ends of the line segment. */ + /* */ + /* <Input> */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: A pointer to the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + static int + BBox_Line_To( FT_Vector* to, + TBBox_Rec* user ) + { + user->last = *to; -#define CHECK_Y( p, bbox ) \ - ( p->y < bbox.yMin || p->y > bbox.yMax ) + return 0; + } /*************************************************************************/ @@ -85,7 +129,7 @@ /* BBox_Conic_Check */ /* */ /* <Description> */ - /* Finds the extrema of a 1-dimensional conic Bezier curve and update */ + /* Find the extrema of a 1-dimensional conic Bezier curve and update */ /* a bounding range. This version uses direct computation, as it */ /* doesn't need square roots. */ /* */ @@ -108,30 +152,19 @@ FT_Pos* min, FT_Pos* max ) { - if ( y1 <= y3 && y2 == y1 ) /* flat arc */ - goto Suite; - - if ( y1 < y3 ) - { - if ( y2 >= y1 && y2 <= y3 ) /* ascending arc */ - goto Suite; - } - else - { - if ( y2 >= y3 && y2 <= y1 ) /* descending arc */ - { - y2 = y1; - y1 = y3; - y3 = y2; - goto Suite; - } - } - - y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 ); - - Suite: - if ( y1 < *min ) *min = y1; - if ( y3 > *max ) *max = y3; + /* This function is only called when a control off-point is outside */ + /* the bbox that contains all on-points. It finds a local extremum */ + /* within the segment, equal to (y1*y3 - y2*y2)/(y1 - 2*y2 + y3). */ + /* Or, offsetting from y2, we get */ + + y1 -= y2; + y3 -= y2; + y2 += FT_MulDiv( y1, y3, y1 + y3 ); + + if ( y2 < *min ) + *min = y2; + if ( y2 > *max ) + *max = y2; } @@ -166,8 +199,8 @@ FT_Vector* to, TBBox_Rec* user ) { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ + /* in case `to' is implicit and not included in bbox yet */ + FT_UPDATE_BBOX( to, user->bbox ); if ( CHECK_X( control, user->bbox ) ) BBox_Conic_Check( user->last.x, @@ -195,9 +228,9 @@ /* BBox_Cubic_Check */ /* */ /* <Description> */ - /* Finds the extrema of a 1-dimensional cubic Bezier curve and */ - /* updates a bounding range. This version uses splitting because we */ - /* don't want to use square roots and extra accuracy. */ + /* Find the extrema of a 1-dimensional cubic Bezier curve and */ + /* update a bounding range. This version uses iterative splitting */ + /* because it is faster than the exact solution with square roots. */ /* */ /* <Input> */ /* p1 :: The start coordinate. */ @@ -213,28 +246,52 @@ /* */ /* max :: The address of the current maximum. */ /* */ + static FT_Pos + cubic_peak( FT_Pos q1, + FT_Pos q2, + FT_Pos q3, + FT_Pos q4 ) + { + FT_Pos peak = 0; + FT_Int shift; -#if 0 - static void - BBox_Cubic_Check( FT_Pos p1, - FT_Pos p2, - FT_Pos p3, - FT_Pos p4, - FT_Pos* min, - FT_Pos* max ) - { - FT_Pos q1, q2, q3, q4; + /* This function finds a peak of a cubic segment if it is above 0 */ + /* using iterative bisection of the segment, or returns 0. */ + /* The fixed-point arithmetic of bisection is inherently stable */ + /* but may loose accuracy in the two lowest bits. To compensate, */ + /* we upscale the segment if there is room. Large values may need */ + /* to be downscaled to avoid overflows during bisection. */ + /* It is called with either q2 or q3 positive, which is necessary */ + /* for the peak to exist and avoids undefined FT_MSB. */ + shift = 27 - FT_MSB( (FT_UInt32)( FT_ABS( q1 ) | + FT_ABS( q2 ) | + FT_ABS( q3 ) | + FT_ABS( q4 ) ) ); - q1 = p1; - q2 = p2; - q3 = p3; - q4 = p4; + if ( shift > 0 ) + { + /* upscaling too much just wastes time */ + if ( shift > 2 ) + shift = 2; + + q1 <<= shift; + q2 <<= shift; + q3 <<= shift; + q4 <<= shift; + } + else + { + q1 >>= -shift; + q2 >>= -shift; + q3 >>= -shift; + q4 >>= -shift; + } - /* for a conic segment to possibly reach new maximum */ - /* one of its off-points must be above the current value */ - while ( q2 > *max || q3 > *max ) + /* for a peak to exist above 0, the cubic segment must have */ + /* at least one of its control off-points above 0. */ + while ( q2 > 0 || q3 > 0 ) { /* determine which half contains the maximum and split */ if ( q1 + q2 > q3 + q4 ) /* first half */ @@ -260,232 +317,49 @@ q3 = q3 / 2; } - /* check if either end reached the maximum */ + /* check whether either end reached the maximum */ if ( q1 == q2 && q1 >= q3 ) { - *max = q1; + peak = q1; break; } if ( q3 == q4 && q2 <= q4 ) { - *max = q4; - break; - } - } - - q1 = p1; - q2 = p2; - q3 = p3; - q4 = p4; - - /* for a conic segment to possibly reach new minimum */ - /* one of its off-points must be below the current value */ - while ( q2 < *min || q3 < *min ) - { - /* determine which half contains the minimum and split */ - if ( q1 + q2 < q3 + q4 ) /* first half */ - { - q4 = q4 + q3; - q3 = q3 + q2; - q2 = q2 + q1; - q4 = q4 + q3; - q3 = q3 + q2; - q4 = ( q4 + q3 ) / 8; - q3 = q3 / 4; - q2 = q2 / 2; - } - else /* second half */ - { - q1 = q1 + q2; - q2 = q2 + q3; - q3 = q3 + q4; - q1 = q1 + q2; - q2 = q2 + q3; - q1 = ( q1 + q2 ) / 8; - q2 = q2 / 4; - q3 = q3 / 2; - } - - /* check if either end reached the minimum */ - if ( q1 == q2 && q1 <= q3 ) - { - *min = q1; - break; - } - if ( q3 == q4 && q2 >= q4 ) - { - *min = q4; + peak = q4; break; } } - } -#else - - static void - test_cubic_extrema( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos y4, - FT_Fixed u, - FT_Pos* min, - FT_Pos* max ) - { - /* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */ - FT_Pos b = y3 - 2*y2 + y1; - FT_Pos c = y2 - y1; - FT_Pos d = y1; - FT_Pos y; - FT_Fixed uu; - - FT_UNUSED ( y4 ); - - - /* The polynomial is */ - /* */ - /* P(x) = a*x^3 + 3b*x^2 + 3c*x + d , */ - /* */ - /* dP/dx = 3a*x^2 + 6b*x + 3c . */ - /* */ - /* However, we also have */ - /* */ - /* dP/dx(u) = 0 , */ - /* */ - /* which implies by subtraction that */ - /* */ - /* P(u) = b*u^2 + 2c*u + d . */ - - if ( u > 0 && u < 0x10000L ) - { - uu = FT_MulFix( u, u ); - y = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu ); + if ( shift > 0 ) + peak >>= shift; + else + peak <<= -shift; - if ( y < *min ) *min = y; - if ( y > *max ) *max = y; - } + return peak; } static void - BBox_Cubic_Check( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos y4, + BBox_Cubic_Check( FT_Pos p1, + FT_Pos p2, + FT_Pos p3, + FT_Pos p4, FT_Pos* min, FT_Pos* max ) { - /* always compare first and last points */ - if ( y1 < *min ) *min = y1; - else if ( y1 > *max ) *max = y1; - - if ( y4 < *min ) *min = y4; - else if ( y4 > *max ) *max = y4; - - /* now, try to see if there are split points here */ - if ( y1 <= y4 ) - { - /* flat or ascending arc test */ - if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) - return; - } - else /* y1 > y4 */ - { - /* descending arc test */ - if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) - return; - } - - /* There are some split points. Find them. */ - /* We already made sure that a, b, and c below cannot be all zero. */ - { - FT_Pos a = y4 - 3*y3 + 3*y2 - y1; - FT_Pos b = y3 - 2*y2 + y1; - FT_Pos c = y2 - y1; - FT_Pos d; - FT_Fixed t; - FT_Int shift; - - - /* We need to solve `ax^2+2bx+c' here, without floating points! */ - /* The trick is to normalize to a different representation in order */ - /* to use our 16.16 fixed-point routines. */ - /* */ - /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */ - /* These values must fit into a single 16.16 value. */ - /* */ - /* We normalize a, b, and c to `8.16' fixed-point values to ensure */ - /* that their product is held in a `16.16' value including the sign. */ - /* Necessarily, we need to shift `a', `b', and `c' so that the most */ - /* significant bit of their absolute values is at position 22. */ - /* */ - /* This also means that we are using 23 bits of precision to compute */ - /* the zeros, independently of the range of the original polynomial */ - /* coefficients. */ - /* */ - /* This algorithm should ensure reasonably accurate values for the */ - /* zeros. Note that they are only expressed with 16 bits when */ - /* computing the extrema (the zeros need to be in 0..1 exclusive */ - /* to be considered part of the arc). */ - - shift = FT_MSB( FT_ABS( a ) | FT_ABS( b ) | FT_ABS( c ) ); - - if ( shift > 22 ) - { - shift -= 22; - - /* this loses some bits of precision, but we use 23 of them */ - /* for the computation anyway */ - a >>= shift; - b >>= shift; - c >>= shift; - } - else - { - shift = 22 - shift; + /* This function is only called when a control off-point is outside */ + /* the bbox that contains all on-points. So at least one of the */ + /* conditions below holds and cubic_peak is called with at least one */ + /* non-zero argument. */ - a <<= shift; - b <<= shift; - c <<= shift; - } + if ( p2 > *max || p3 > *max ) + *max += cubic_peak( p1 - *max, p2 - *max, p3 - *max, p4 - *max ); - /* handle a == 0 */ - if ( a == 0 ) - { - if ( b != 0 ) - { - t = - FT_DivFix( c, b ) / 2; - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - } - else - { - /* solve the equation now */ - d = FT_MulFix( b, b ) - FT_MulFix( a, c ); - if ( d < 0 ) - return; - - if ( d == 0 ) - { - /* there is a single split point at -b/a */ - t = - FT_DivFix( b, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - else - { - /* there are two solutions; we need to filter them */ - d = FT_SqrtFixed( (FT_Int32)d ); - t = - FT_DivFix( b - d, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - - t = - FT_DivFix( b + d, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - } - } + /* now flip the signs to update the minimum */ + if ( p2 < *min || p3 < *min ) + *min -= cubic_peak( *min - p1, *min - p2, *min - p3, *min - p4 ); } -#endif - /*************************************************************************/ /* */ @@ -521,8 +395,9 @@ FT_Vector* to, TBBox_Rec* user ) { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ + /* We don't need to check `to' since it is always an on-point, */ + /* thus within the bbox. Only segments with an off-point outside */ + /* the bbox can possibly reach new extreme values. */ if ( CHECK_X( control1, user->bbox ) || CHECK_X( control2, user->bbox ) ) @@ -547,22 +422,26 @@ return 0; } -FT_DEFINE_OUTLINE_FUNCS(bbox_interface, + + FT_DEFINE_OUTLINE_FUNCS(bbox_interface, (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Line_To, (FT_Outline_ConicTo_Func)BBox_Conic_To, (FT_Outline_CubicTo_Func)BBox_Cubic_To, 0, 0 ) + /* documentation is in ftbbox.h */ FT_EXPORT_DEF( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, FT_BBox *abbox ) { - FT_BBox cbox; - FT_BBox bbox; + FT_BBox cbox = { 0x7FFFFFFFL, 0x7FFFFFFFL, + -0x7FFFFFFFL, -0x7FFFFFFFL }; + FT_BBox bbox = { 0x7FFFFFFFL, 0x7FFFFFFFL, + -0x7FFFFFFFL, -0x7FFFFFFFL }; FT_Vector* vec; FT_UShort n; @@ -586,32 +465,13 @@ FT_DEFINE_OUTLINE_FUNCS(bbox_interface, /* coincide, we exit immediately. */ vec = outline->points; - bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x; - bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y; - vec++; - for ( n = 1; n < outline->n_points; n++ ) + for ( n = 0; n < outline->n_points; n++ ) { - FT_Pos x = vec->x; - FT_Pos y = vec->y; - - - /* update control box */ - if ( x < cbox.xMin ) cbox.xMin = x; - if ( x > cbox.xMax ) cbox.xMax = x; - - if ( y < cbox.yMin ) cbox.yMin = y; - if ( y > cbox.yMax ) cbox.yMax = y; + FT_UPDATE_BBOX( vec, cbox); if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) - { - /* update bbox for `on' points only */ - if ( x < bbox.xMin ) bbox.xMin = x; - if ( x > bbox.xMax ) bbox.xMax = x; - - if ( y < bbox.yMin ) bbox.yMin = y; - if ( y > bbox.yMax ) bbox.yMax = y; - } + FT_UPDATE_BBOX( vec, bbox); vec++; } diff --git a/drivers/freetype/src/base/ftbdf.c b/drivers/freetype/src/base/ftbdf.c index 5755f8558d..4aafc2b98e 100644 --- a/drivers/freetype/src/base/ftbdf.c +++ b/drivers/freetype/src/base/ftbdf.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (body). */ /* */ -/* Copyright 2002-2004, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,8 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_BDF_H @@ -32,19 +34,18 @@ const char* encoding = NULL; const char* registry = NULL; + FT_Service_BDF service; - error = FT_ERR( Invalid_Argument ); - - if ( face ) - { - FT_Service_BDF service; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - FT_FACE_FIND_SERVICE( face, service, BDF ); + FT_FACE_FIND_SERVICE( face, service, BDF ); - if ( service && service->get_charset_id ) - error = service->get_charset_id( face, &encoding, ®istry ); - } + if ( service && service->get_charset_id ) + error = service->get_charset_id( face, &encoding, ®istry ); + else + error = FT_THROW( Invalid_Argument ); if ( acharset_encoding ) *acharset_encoding = encoding; @@ -65,23 +66,25 @@ { FT_Error error; + FT_Service_BDF service; - error = FT_ERR( Invalid_Argument ); - aproperty->type = BDF_PROPERTY_TYPE_NONE; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - if ( face ) - { - FT_Service_BDF service; + if ( !aproperty ) + return FT_THROW( Invalid_Argument ); + aproperty->type = BDF_PROPERTY_TYPE_NONE; - FT_FACE_FIND_SERVICE( face, service, BDF ); + FT_FACE_FIND_SERVICE( face, service, BDF ); - if ( service && service->get_property ) - error = service->get_property( face, prop_name, aproperty ); - } + if ( service && service->get_property ) + error = service->get_property( face, prop_name, aproperty ); + else + error = FT_THROW( Invalid_Argument ); - return error; + return error; } diff --git a/drivers/freetype/src/base/ftbitmap.c b/drivers/freetype/src/base/ftbitmap.c index 975818e14f..24fead3e15 100644 --- a/drivers/freetype/src/base/ftbitmap.c +++ b/drivers/freetype/src/base/ftbitmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (body). */ /* */ -/* Copyright 2004-2009, 2011, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,10 +30,21 @@ /* documentation is in ftbitmap.h */ + FT_EXPORT_DEF( void ) + FT_Bitmap_Init( FT_Bitmap *abitmap ) + { + if ( abitmap ) + *abitmap = null_bitmap; + } + + + /* deprecated function name; retained for ABI compatibility */ + FT_EXPORT_DEF( void ) FT_Bitmap_New( FT_Bitmap *abitmap ) { - *abitmap = null_bitmap; + if ( abitmap ) + *abitmap = null_bitmap; } @@ -44,25 +55,42 @@ const FT_Bitmap *source, FT_Bitmap *target) { - FT_Memory memory = library->memory; + FT_Memory memory; FT_Error error = FT_Err_Ok; - FT_Int pitch = source->pitch; - FT_ULong size; + FT_Int pitch; + FT_ULong size; + + FT_Int source_pitch_sign, target_pitch_sign; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !source || !target ) + return FT_THROW( Invalid_Argument ); if ( source == target ) return FT_Err_Ok; + source_pitch_sign = source->pitch < 0 ? -1 : 1; + target_pitch_sign = target->pitch < 0 ? -1 : 1; + if ( source->buffer == NULL ) { *target = *source; + if ( source_pitch_sign != target_pitch_sign ) + target->pitch = -target->pitch; return FT_Err_Ok; } + memory = library->memory; + pitch = source->pitch; + if ( pitch < 0 ) pitch = -pitch; - size = (FT_ULong)( pitch * source->rows ); + size = (FT_ULong)pitch * source->rows; if ( target->buffer ) { @@ -70,9 +98,9 @@ FT_ULong target_size; - if ( target_pitch < 0 ) + if ( target_pitch < 0 ) target_pitch = -target_pitch; - target_size = (FT_ULong)( target_pitch * target->rows ); + target_size = (FT_ULong)target_pitch * target->rows; if ( target_size != size ) (void)FT_QREALLOC( target->buffer, target_size, size ); @@ -89,13 +117,35 @@ *target = *source; target->buffer = p; - FT_MEM_COPY( target->buffer, source->buffer, size ); + if ( source_pitch_sign == target_pitch_sign ) + FT_MEM_COPY( target->buffer, source->buffer, size ); + else + { + /* take care of bitmap flow */ + FT_UInt i; + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + + + t += (FT_ULong)pitch * ( target->rows - 1 ); + + for ( i = target->rows; i > 0; i-- ) + { + FT_ARRAY_COPY( t, s, pitch ); + + s += pitch; + t -= pitch; + } + } } return error; } + /* Enlarge `bitmap' horizontally and vertically by `xpixels' */ + /* and `ypixels', respectively. */ + static FT_Error ft_bitmap_assure_buffer( FT_Memory memory, FT_Bitmap* bitmap, @@ -106,7 +156,7 @@ int pitch; int new_pitch; FT_UInt bpp; - FT_Int i, width, height; + FT_UInt i, width, height; unsigned char* buffer = NULL; @@ -120,21 +170,21 @@ { case FT_PIXEL_MODE_MONO: bpp = 1; - new_pitch = ( width + xpixels + 7 ) >> 3; + new_pitch = (int)( ( width + xpixels + 7 ) >> 3 ); break; case FT_PIXEL_MODE_GRAY2: bpp = 2; - new_pitch = ( width + xpixels + 3 ) >> 2; + new_pitch = (int)( ( width + xpixels + 3 ) >> 2 ); break; case FT_PIXEL_MODE_GRAY4: bpp = 4; - new_pitch = ( width + xpixels + 1 ) >> 1; + new_pitch = (int)( ( width + xpixels + 1 ) >> 1 ); break; case FT_PIXEL_MODE_GRAY: case FT_PIXEL_MODE_LCD: case FT_PIXEL_MODE_LCD_V: bpp = 8; - new_pitch = ( width + xpixels ); + new_pitch = (int)( width + xpixels ); break; default: return FT_THROW( Invalid_Glyph_Format ); @@ -144,17 +194,17 @@ if ( ypixels == 0 && new_pitch <= pitch ) { /* zero the padding */ - FT_Int bit_width = pitch * 8; - FT_Int bit_last = ( width + xpixels ) * bpp; + FT_UInt bit_width = (FT_UInt)pitch * 8; + FT_UInt bit_last = ( width + xpixels ) * bpp; if ( bit_last < bit_width ) { FT_Byte* line = bitmap->buffer + ( bit_last >> 3 ); FT_Byte* end = bitmap->buffer + pitch; - FT_Int shift = bit_last & 7; + FT_UInt shift = bit_last & 7; FT_UInt mask = 0xFF00U >> shift; - FT_Int count = height; + FT_UInt count = height; for ( ; count > 0; count--, line += pitch, end += pitch ) @@ -168,33 +218,38 @@ write++; } if ( write < end ) - FT_MEM_ZERO( write, end-write ); + FT_MEM_ZERO( write, end - write ); } } return FT_Err_Ok; } + /* otherwise allocate new buffer */ if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) return error; + /* new rows get added at the top of the bitmap, */ + /* thus take care of the flow direction */ if ( bitmap->pitch > 0 ) { - FT_Int len = ( width * bpp + 7 ) >> 3; + FT_UInt len = ( width * bpp + 7 ) >> 3; for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ), - bitmap->buffer + pitch * i, len ); + FT_MEM_COPY( buffer + (FT_UInt)new_pitch * ( ypixels + i ), + bitmap->buffer + (FT_UInt)pitch * i, + len ); } else { - FT_Int len = ( width * bpp + 7 ) >> 3; + FT_UInt len = ( width * bpp + 7 ) >> 3; for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * i, - bitmap->buffer + pitch * i, len ); + FT_MEM_COPY( buffer + (FT_UInt)new_pitch * i, + bitmap->buffer + (FT_UInt)pitch * i, + len ); } FT_FREE( bitmap->buffer ); @@ -220,7 +275,8 @@ { FT_Error error; unsigned char* p; - FT_Int i, x, y, pitch; + FT_Int i, x, pitch; + FT_UInt y; FT_Int xstr, ystr; @@ -248,17 +304,11 @@ case FT_PIXEL_MODE_GRAY4: { FT_Bitmap tmp; - FT_Int align; - if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 ) - align = ( bitmap->width + xstr + 3 ) / 4; - else - align = ( bitmap->width + xstr + 1 ) / 2; - - FT_Bitmap_New( &tmp ); - - error = FT_Bitmap_Convert( library, bitmap, &tmp, align ); + /* convert to 8bpp */ + FT_Bitmap_Init( &tmp ); + error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 ); if ( error ) return error; @@ -285,21 +335,23 @@ return FT_Err_Ok; } - error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); + error = ft_bitmap_assure_buffer( library->memory, bitmap, + (FT_UInt)xstr, (FT_UInt)ystr ); if ( error ) return error; + /* take care of bitmap flow */ pitch = bitmap->pitch; if ( pitch > 0 ) p = bitmap->buffer + pitch * ystr; else { pitch = -pitch; - p = bitmap->buffer + pitch * ( bitmap->rows - 1 ); + p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 ); } /* for each row */ - for ( y = 0; y < bitmap->rows ; y++ ) + for ( y = 0; y < bitmap->rows; y++ ) { /* * Horizontally: @@ -309,7 +361,7 @@ */ for ( x = pitch - 1; x >= 0; x-- ) { - unsigned char tmp; + unsigned char tmp; tmp = p[x]; @@ -324,7 +376,7 @@ p[x] |= p[x - 1] << ( 8 - i ); #if 0 - if ( p[x] == 0xff ) + if ( p[x] == 0xFF ) break; #endif } @@ -334,12 +386,12 @@ { if ( p[x] + p[x - i] > bitmap->num_grays - 1 ) { - p[x] = (unsigned char)(bitmap->num_grays - 1); + p[x] = (unsigned char)( bitmap->num_grays - 1 ); break; } else { - p[x] = (unsigned char)(p[x] + p[x-i]); + p[x] = (unsigned char)( p[x] + p[x - i] ); if ( p[x] == bitmap->num_grays - 1 ) break; } @@ -368,63 +420,56 @@ p += bitmap->pitch; } - bitmap->width += xstr; - bitmap->rows += ystr; + bitmap->width += (FT_UInt)xstr; + bitmap->rows += (FT_UInt)ystr; return FT_Err_Ok; } - FT_Byte + static FT_Byte ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra ) { - FT_Long a = bgra[3]; - FT_Long b = bgra[0]; - FT_Long g = bgra[1]; - FT_Long r = bgra[2]; - FT_Long l; + FT_UInt a = bgra[3]; + FT_UInt l; + /* Short-circuit transparent color to avoid division by zero. */ + if ( !a ) + return 0; + /* * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722 * coefficients for RGB channels *on the linear colors*. * A gamma of 2.2 is fair to assume. And then, we need to * undo the premultiplication too. * - * http://accessibility.kde.org/hsl-adjusted.php + * http://accessibility.kde.org/hsl-adjusted.php + * + * We do the computation with integers only, applying a gamma of 2.0. + * We guarantee 32-bit arithmetic to avoid overflow but the resulting + * luminosity fits into 16 bits. * - * We do the computation with integers only. */ - /* Undo premultification, get the number in a 16.16 form. */ - b = FT_MulDiv( b, 65536, a ); - g = FT_MulDiv( g, 65536, a ); - r = FT_MulDiv( r, 65536, a ); - a = a * 256; - - /* Apply gamma of 2.0 instead of 2.2. */ - b = FT_MulFix( b, b ); - g = FT_MulFix( g, g ); - r = FT_MulFix( r, r ); - - /* Apply coefficients. */ - b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ ); - g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ ); - r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ ); - - l = r + g + b; + l = ( 4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] + + 46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] + + 13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16; /* - * Final transparency can be determined this way: + * Final transparency can be determined as follows. * * - If alpha is zero, we want 0. * - If alpha is zero and luminosity is zero, we want 255. * - If alpha is zero and luminosity is one, we want 0. * - * So the formula is a * (1 - l). + * So the formula is a * (1 - l) = a - l * a. + * + * We still need to undo premultiplication by dividing l by a*a. + * */ - return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 ); + return (FT_Byte)( a - l / a ); } @@ -439,10 +484,16 @@ FT_Error error = FT_Err_Ok; FT_Memory memory; + FT_Byte* s; + FT_Byte* t; + if ( !library ) return FT_THROW( Invalid_Library_Handle ); + if ( !source || !target ) + return FT_THROW( Invalid_Argument ); + memory = library->memory; switch ( source->pixel_mode ) @@ -455,13 +506,15 @@ case FT_PIXEL_MODE_LCD_V: case FT_PIXEL_MODE_BGRA: { - FT_Int pad; - FT_Long old_size; + FT_Int pad, old_target_pitch, target_pitch; + FT_ULong old_size; + + old_target_pitch = target->pitch; + if ( old_target_pitch < 0 ) + old_target_pitch = -old_target_pitch; - old_size = target->rows * target->pitch; - if ( old_size < 0 ) - old_size = -old_size; + old_size = target->rows * (FT_UInt)old_target_pitch; target->pixel_mode = FT_PIXEL_MODE_GRAY; target->rows = source->rows; @@ -470,21 +523,23 @@ pad = 0; if ( alignment > 0 ) { - pad = source->width % alignment; + pad = (FT_Int)source->width % alignment; if ( pad != 0 ) pad = alignment - pad; } - target->pitch = source->width + pad; + target_pitch = (FT_Int)source->width + pad; - if ( target->pitch > 0 && - (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch ) + if ( target_pitch > 0 && + (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch ) return FT_THROW( Invalid_Argument ); - if ( target->rows * target->pitch > old_size && + if ( target->rows * (FT_ULong)target_pitch > old_size && FT_QREALLOC( target->buffer, - old_size, target->rows * target->pitch ) ) + old_size, target->rows * (FT_UInt)target_pitch ) ) return error; + + target->pitch = target->pitch < 0 ? -target_pitch : target_pitch; } break; @@ -492,13 +547,20 @@ error = FT_THROW( Invalid_Argument ); } + s = source->buffer; + t = target->buffer; + + /* take care of bitmap flow */ + if ( source->pitch < 0 ) + s -= source->pitch * (FT_Int)( source->rows - 1 ); + if ( target->pitch < 0 ) + t -= target->pitch * (FT_Int)( target->rows - 1 ); + switch ( source->pixel_mode ) { case FT_PIXEL_MODE_MONO: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 2; @@ -507,7 +569,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -555,12 +617,8 @@ case FT_PIXEL_MODE_LCD: case FT_PIXEL_MODE_LCD_V: { - FT_Int width = source->width; - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; + FT_UInt width = source->width; + FT_UInt i; target->num_grays = 256; @@ -569,8 +627,8 @@ { FT_ARRAY_COPY( t, s, width ); - s += s_pitch; - t += t_pitch; + s += source->pitch; + t += target->pitch; } } break; @@ -578,9 +636,7 @@ case FT_PIXEL_MODE_GRAY2: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 4; @@ -589,7 +645,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -630,9 +686,7 @@ case FT_PIXEL_MODE_GRAY4: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 16; @@ -641,7 +695,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -666,13 +720,10 @@ } break; + case FT_PIXEL_MODE_BGRA: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; + FT_UInt i; target->num_grays = 256; @@ -681,7 +732,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; for ( j = source->width; j > 0; j-- ) @@ -692,8 +743,8 @@ tt += 1; } - s += s_pitch; - t += t_pitch; + s += source->pitch; + t += target->pitch; } } break; @@ -718,7 +769,7 @@ FT_Error error; - FT_Bitmap_New( &bitmap ); + FT_Bitmap_Init( &bitmap ); error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); if ( error ) return error; diff --git a/drivers/freetype/src/base/ftcalc.c b/drivers/freetype/src/base/ftcalc.c index 0ec0d78930..67549d0c43 100644 --- a/drivers/freetype/src/base/ftcalc.c +++ b/drivers/freetype/src/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2006, 2008, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,7 +39,8 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H -#ifdef FT_MULFIX_INLINED + +#ifdef FT_MULFIX_ASSEMBLER #undef FT_MulFix #endif @@ -67,6 +68,16 @@ #define FT_COMPONENT trace_calc + /* transfer sign leaving a positive number */ +#define FT_MOVE_SIGN( x, s ) \ + FT_BEGIN_STMNT \ + if ( x < 0 ) \ + { \ + x = -x; \ + s = -s; \ + } \ + FT_END_STMNT + /* The following three functions are available regardless of whether */ /* FT_LONG64 is defined. */ @@ -75,8 +86,7 @@ FT_EXPORT_DEF( FT_Fixed ) FT_RoundFix( FT_Fixed a ) { - return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL - : -((-a + 0x8000L ) & ~0xFFFFL ); + return ( a + 0x8000L - ( a < 0 ) ) & ~0xFFFFL; } @@ -85,8 +95,7 @@ FT_EXPORT_DEF( FT_Fixed ) FT_CeilFix( FT_Fixed a ) { - return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL - : -((-a + 0xFFFFL ) & ~0xFFFFL ); + return ( a + 0xFFFFL ) & ~0xFFFFL; } @@ -95,46 +104,49 @@ FT_EXPORT_DEF( FT_Fixed ) FT_FloorFix( FT_Fixed a ) { - return ( a >= 0 ) ? a & ~0xFFFFL - : -((-a) & ~0xFFFFL ); + return a & ~0xFFFFL; } +#ifndef FT_MSB FT_BASE_DEF ( FT_Int ) FT_MSB( FT_UInt32 z ) { - FT_Int shift = 0; + FT_Int shift = 0; + /* determine msb bit index in `shift' */ - if ( z >= ( 1L << 16 ) ) + if ( z & 0xFFFF0000UL ) { z >>= 16; shift += 16; } - if ( z >= ( 1L << 8 ) ) + if ( z & 0x0000FF00UL ) { z >>= 8; shift += 8; } - if ( z >= ( 1L << 4 ) ) + if ( z & 0x000000F0UL ) { z >>= 4; shift += 4; } - if ( z >= ( 1L << 2 ) ) + if ( z & 0x0000000CUL ) { z >>= 2; shift += 2; } - if ( z >= ( 1L << 1 ) ) + if ( z & 0x00000002UL ) { - z >>= 1; + /* z >>= 1; */ shift += 1; } return shift; } +#endif /* !FT_MSB */ + /* documentation is in ftcalc.h */ @@ -158,80 +170,77 @@ /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) + FT_MulDiv( FT_Long a_, + FT_Long b_, + FT_Long c_ ) { - FT_Int s; - FT_Long d; + FT_Int s = 1; + FT_UInt64 a, b, c, d; + FT_Long d_; + + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + c = (FT_UInt64)c_; - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } + d = c > 0 ? ( a * b + ( c >> 1 ) ) / c + : 0x7FFFFFFFUL; - d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c - : 0x7FFFFFFFL ); + d_ = (FT_Long)d; - return ( s > 0 ) ? d : -d; + return s < 0 ? -d_ : d_; } /* documentation is in ftcalc.h */ FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) + FT_MulDiv_No_Round( FT_Long a_, + FT_Long b_, + FT_Long c_ ) { - FT_Int s; - FT_Long d; + FT_Int s = 1; + FT_UInt64 a, b, c, d; + FT_Long d_; - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); - d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c - : 0x7FFFFFFFL ); + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + c = (FT_UInt64)c_; - return ( s > 0 ) ? d : -d; + d = c > 0 ? a * b / c + : 0x7FFFFFFFUL; + + d_ = (FT_Long)d; + + return s < 0 ? -d_ : d_; } /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) + FT_MulFix( FT_Long a_, + FT_Long b_ ) { #ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER( a, b ); + return FT_MULFIX_ASSEMBLER( (FT_Int32)a_, (FT_Int32)b_ ); #else - FT_Int s = 1; - FT_Long c; - + FT_Int64 ab = (FT_Int64)a_ * (FT_Int64)b_; - if ( a < 0 ) - { - a = -a; - s = -1; - } - - if ( b < 0 ) - { - b = -b; - s = -s; - } - - c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); - - return ( s > 0 ) ? c : -c; + /* this requires arithmetic right shift of signed numbers */ + return (FT_Long)( ( ab + 0x8000L - ( ab < 0 ) ) >> 16 ); #endif /* FT_MULFIX_ASSEMBLER */ } @@ -240,33 +249,26 @@ /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) + FT_DivFix( FT_Long a_, + FT_Long b_ ) { - FT_Int32 s; - FT_UInt32 q; + FT_Int s = 1; + FT_UInt64 a, b, q; + FT_Long q_; - s = 1; - if ( a < 0 ) - { - a = -a; - s = -1; - } - if ( b < 0 ) - { - b = -b; - s = -s; - } + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); - if ( b == 0 ) - /* check for division by 0 */ - q = 0x7FFFFFFFL; - else - /* compute result directly */ - q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b ); + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; - return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); + q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b + : 0x7FFFFFFFUL; + + q_ = (FT_Long)q; + + return s < 0 ? -q_ : q_; } @@ -314,25 +316,30 @@ FT_Int i; - q = 0; - r = hi; - - if ( r >= y ) + if ( hi >= y ) return (FT_UInt32)0x7FFFFFFFL; - i = 32; + /* We shift as many bits as we can into the high register, perform */ + /* 32-bit division with modulo there, then work through the remaining */ + /* bits with long division. This optimization is especially noticeable */ + /* for smaller dividends that barely use the high register. */ + + i = 31 - FT_MSB( hi ); + r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */ + q = r / y; + r -= q * y; /* remainder */ + + i = 32 - i; /* bits remaining in low register */ do { - r <<= 1; q <<= 1; - r |= lo >> 31; + r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1; if ( r >= y ) { r -= y; q |= 1; } - lo <<= 1; } while ( --i ); return q; @@ -344,7 +351,7 @@ FT_Int64* y, FT_Int64 *z ) { - register FT_UInt32 lo, hi; + FT_UInt32 lo, hi; lo = x->lo + y->lo; @@ -355,105 +362,155 @@ } - /* 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). */ + /* The FT_MulDiv function has been optimized thanks to ideas from */ + /* Graham Asher and Alexei Podtelezhnikov. The trick is to optimize */ + /* a rather common case when everything fits within 32-bits. */ + /* */ + /* We compute 'a*b+c/2', then divide it by 'c' (all positive values). */ + /* */ + /* The product of two positive numbers never exceeds the square of */ + /* its mean values. Therefore, we always avoid the overflow by */ + /* imposing */ + /* */ + /* (a + b) / 2 <= sqrt(X - c/2) , */ + /* */ + /* where X = 2^32 - 1, the maximum unsigned 32-bit value, and using */ + /* unsigned arithmetic. Now we replace `sqrt' with a linear function */ + /* that is smaller or equal for all values of c in the interval */ + /* [0;X/2]; it should be equal to sqrt(X) and sqrt(3X/4) at the */ + /* endpoints. Substituting the linear solution and explicit numbers */ + /* we get */ + /* */ + /* a + b <= 131071.99 - c / 122291.84 . */ + /* */ + /* In practice, we should use a faster and even stronger inequality */ /* */ - /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ + /* a + b <= 131071 - (c >> 16) */ /* */ - /* 46340 is FLOOR(SQRT(2^31-1)). */ + /* or, alternatively, */ /* */ - /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ + /* a + b <= 129894 - (c >> 17) . */ /* */ - /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ + /* FT_MulFix, on the other hand, is optimized for a small value of */ + /* the first argument, when the second argument can be much larger. */ + /* This can be achieved by scaling the second argument and the limit */ + /* in the above inequalities. For example, */ /* */ - /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ + /* a + (b >> 8) <= (131071 >> 4) */ /* */ - /* and 2*0x157F0 = 176096 */ + /* covers the practical range of use. The actual test below is a bit */ + /* tighter to avoid the border case overflows. */ /* */ + /* In the case of FT_DivFix, the exact overflow check */ + /* */ + /* a << 16 <= X - c/2 */ + /* */ + /* is scaled down by 2^16 and we use */ + /* */ + /* a <= 65535 - (c >> 17) . */ + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) + FT_MulDiv( FT_Long a_, + FT_Long b_, + FT_Long c_ ) { - long s; + FT_Int s = 1; + FT_UInt32 a, b, c; /* XXX: this function does not allow 64-bit arguments */ - if ( a == 0 || b == c ) - return a; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + c = (FT_UInt32)c_; - if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) + if ( c == 0 ) + a = 0x7FFFFFFFUL; + + else if ( a + b <= 129894UL - ( c >> 17 ) ) a = ( a * b + ( c >> 1 ) ) / c; - else if ( (FT_Int32)c > 0 ) + else { FT_Int64 temp, temp2; - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + ft_multo64( a, b, &temp ); temp2.hi = 0; - temp2.lo = (FT_UInt32)(c >> 1); + temp2.lo = c >> 1; + FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + + /* last attempt to ditch long division */ + a = temp.hi == 0 ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } - else - a = 0x7FFFFFFFL; - return ( s < 0 ? -a : a ); + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; } FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) + FT_MulDiv_No_Round( FT_Long a_, + FT_Long b_, + FT_Long c_ ) { - long s; + FT_Int s = 1; + FT_UInt32 a, b, c; - if ( a == 0 || b == c ) - return a; + /* XXX: this function does not allow 64-bit arguments */ + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + c = (FT_UInt32)c_; - if ( a <= 46340L && b <= 46340L && c > 0 ) + if ( c == 0 ) + a = 0x7FFFFFFFUL; + + else if ( a + b <= 131071UL ) a = a * b / c; - else if ( (FT_Int32)c > 0 ) + else { FT_Int64 temp; - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + ft_multo64( a, b, &temp ); + + /* last attempt to ditch long division */ + a = temp.hi == 0 ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } - else - a = 0x7FFFFFFFL; - return ( s < 0 ? -a : a ); + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; } /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) + FT_MulFix( FT_Long a_, + FT_Long b_ ) { #ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER( a, b ); + return FT_MULFIX_ASSEMBLER( a_, b_ ); #elif 0 @@ -464,13 +521,10 @@ * the leftmost bits by copying the sign bit, it might be faster. */ - FT_Long sa, sb; - FT_ULong ua, ub; + FT_Long sa, sb; + FT_UInt32 a, b; - if ( a == 0 || b == 0x10000L ) - return a; - /* * This is a clever way of converting a signed number `a' into its * absolute value (stored back into `a') and its sign. The sign is @@ -489,57 +543,58 @@ * with the value 1 rather than -1. After that, everything else goes * wrong. */ - sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); - a = ( a ^ sa ) - sa; - sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); - b = ( b ^ sb ) - sb; + sa = ( a_ >> ( sizeof ( a_ ) * 8 - 1 ) ); + a = ( a_ ^ sa ) - sa; + sb = ( b_ >> ( sizeof ( b_ ) * 8 - 1 ) ); + b = ( b_ ^ sb ) - sb; - ua = (FT_ULong)a; - ub = (FT_ULong)b; + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000U ) >> 16; + if ( a + ( b >> 8 ) <= 8190UL ) + a = ( a * b + 0x8000U ) >> 16; else { - FT_ULong al = ua & 0xFFFFU; + FT_UInt32 al = a & 0xFFFFUL; - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); + a = ( a >> 16 ) * b + al * ( b >> 16 ) + + ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 ); } - sa ^= sb, - ua = (FT_ULong)(( ua ^ sa ) - sa); + sa ^= sb; + a = ( a ^ sa ) - sa; - return (FT_Long)ua; + return (FT_Long)a; #else /* 0 */ - FT_Long s; - FT_ULong ua, ub; + FT_Int s = 1; + FT_UInt32 a, b; - if ( a == 0 || b == 0x10000L ) - return a; + /* XXX: this function does not allow 64-bit arguments */ - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); - ua = (FT_ULong)a; - ub = (FT_ULong)b; + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000UL ) >> 16; + if ( a + ( b >> 8 ) <= 8190UL ) + a = ( a * b + 0x8000UL ) >> 16; else { - FT_ULong al = ua & 0xFFFFUL; + FT_UInt32 al = a & 0xFFFFUL; - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); + a = ( a >> 16 ) * b + al * ( b >> 16 ) + + ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 ); } - return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; #endif /* 0 */ @@ -549,26 +604,31 @@ /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) + FT_DivFix( FT_Long a_, + FT_Long b_ ) { - FT_Int32 s; - FT_UInt32 q; + FT_Int s = 1; + FT_UInt32 a, b, q; + FT_Long q_; /* XXX: this function does not allow 64-bit arguments */ - s = (FT_Int32)a; a = FT_ABS( a ); - s ^= (FT_Int32)b; b = FT_ABS( b ); - if ( (FT_UInt32)b == 0 ) + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + + if ( b == 0 ) { /* check for division by 0 */ - q = (FT_UInt32)0x7FFFFFFFL; + q = 0x7FFFFFFFUL; } - else if ( ( a >> 16 ) == 0 ) + else if ( a <= 65535UL - ( b >> 17 ) ) { /* compute result directly */ - q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; + q = ( ( a << 16 ) + ( b >> 1 ) ) / b; } else { @@ -576,140 +636,22 @@ FT_Int64 temp, temp2; - temp.hi = (FT_Int32)( a >> 16 ); - temp.lo = (FT_UInt32)a << 16; + temp.hi = a >> 16; + temp.lo = a << 16; temp2.hi = 0; - temp2.lo = (FT_UInt32)( b >> 1 ); - FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - -#if 0 - - /* documentation is in ftcalc.h */ - - FT_EXPORT_DEF( void ) - FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64 *z ) - { - FT_Int32 s; - - - s = x; x = FT_ABS( x ); - s ^= y; y = FT_ABS( y ); - - ft_multo64( x, y, z ); - - if ( s < 0 ) - { - z->lo = (FT_UInt32)-(FT_Int32)z->lo; - z->hi = ~z->hi + !( z->lo ); - } - } - - - /* apparently, the second version of this code is not compiled correctly */ - /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ - -#if 1 - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q, r, i, lo; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = x->lo / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - r = x->hi; - lo = x->lo; - - 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! */ - q = 0; - for ( i = 0; i < 32; i++ ) - { - r <<= 1; - q <<= 1; - r |= lo >> 31; + temp2.lo = b >> 1; - if ( r >= (FT_UInt32)y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#else /* 0 */ - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = ( x->lo + ( y >> 1 ) ) / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + FT_Add64( &temp, &temp2, &temp ); + q = ft_div64by32( temp.hi, temp.lo, b ); } - q = ft_div64by32( x->hi, x->lo, y ); + q_ = (FT_Long)q; - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + return s < 0 ? -q_ : q_; } -#endif /* 0 */ - -#endif /* 0 */ - -#endif /* FT_LONG64 */ +#endif /* !FT_LONG64 */ /* documentation is in ftglyph.h */ @@ -816,6 +758,104 @@ } + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_UInt32 ) + FT_Vector_NormLen( FT_Vector* vector ) + { + FT_Int32 x_ = vector->x; + FT_Int32 y_ = vector->y; + FT_Int32 b, z; + FT_UInt32 x, y, u, v, l; + FT_Int sx = 1, sy = 1, shift; + + + FT_MOVE_SIGN( x_, sx ); + FT_MOVE_SIGN( y_, sy ); + + x = (FT_UInt32)x_; + y = (FT_UInt32)y_; + + /* trivial cases */ + if ( x == 0 ) + { + if ( y > 0 ) + vector->y = sy * 0x10000; + return y; + } + else if ( y == 0 ) + { + if ( x > 0 ) + vector->x = sx * 0x10000; + return x; + } + + /* Estimate length and prenormalize by shifting so that */ + /* the new approximate length is between 2/3 and 4/3. */ + /* The magic constant 0xAAAAAAAAUL (2/3 of 2^32) helps */ + /* achieve this in 16.16 fixed-point representation. */ + l = x > y ? x + ( y >> 1 ) + : y + ( x >> 1 ); + + shift = 31 - FT_MSB( l ); + shift -= 15 + ( l >= ( 0xAAAAAAAAUL >> shift ) ); + + if ( shift > 0 ) + { + x <<= shift; + y <<= shift; + + /* re-estimate length for tiny vectors */ + l = x > y ? x + ( y >> 1 ) + : y + ( x >> 1 ); + } + else + { + x >>= -shift; + y >>= -shift; + l >>= -shift; + } + + /* lower linear approximation for reciprocal length minus one */ + b = 0x10000 - (FT_Int32)l; + + x_ = (FT_Int32)x; + y_ = (FT_Int32)y; + + /* Newton's iterations */ + do + { + u = (FT_UInt32)( x_ + ( x_ * b >> 16 ) ); + v = (FT_UInt32)( y_ + ( y_ * b >> 16 ) ); + + /* Normalized squared length in the parentheses approaches 2^32. */ + /* On two's complement systems, converting to signed gives the */ + /* difference with 2^32 even if the expression wraps around. */ + z = -(FT_Int32)( u * u + v * v ) / 0x200; + z = z * ( ( 0x10000 + b ) >> 8 ) / 0x10000; + + b += z; + + } while ( z > 0 ); + + vector->x = sx < 0 ? -(FT_Pos)u : (FT_Pos)u; + vector->y = sy < 0 ? -(FT_Pos)v : (FT_Pos)v; + + /* Conversion to signed helps to recover from likely wrap around */ + /* in calculating the prenormalized length, because it gives the */ + /* correct difference with 2^32 on two's complement systems. */ + l = (FT_UInt32)( 0x10000 + (FT_Int32)( u * x + v * y ) / 0x10000 ); + if ( shift > 0 ) + l = ( l + ( 1 << ( shift - 1 ) ) ) >> shift; + else + l <<= -shift; + + return l; + } + + +#if 0 + /* documentation is in ftcalc.h */ FT_BASE_DEF( FT_Int32 ) @@ -830,7 +870,7 @@ if ( x > 0 ) { rem_hi = 0; - rem_lo = x; + rem_lo = (FT_UInt32)x; count = 24; do { @@ -850,6 +890,8 @@ return (FT_Int32)root; } +#endif /* 0 */ + /* documentation is in ftcalc.h */ @@ -859,58 +901,40 @@ FT_Pos out_x, FT_Pos out_y ) { - FT_Long result; /* avoid overflow on 16-bit system */ - - - /* 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; + 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 ); + return ( delta > 0 ) - ( delta < 0 ); #else + FT_Int result; + + + if ( (FT_ULong)FT_ABS( in_x ) + (FT_ULong)FT_ABS( out_y ) <= 131071UL && + (FT_ULong)FT_ABS( in_y ) + (FT_ULong)FT_ABS( out_x ) <= 131071UL ) + { + FT_Long z1 = in_x * out_y; + FT_Long z2 = in_y * out_x; + + + if ( z1 > z2 ) + result = +1; + else if ( z1 < z2 ) + result = -1; + else + result = 0; + } + else /* products might overflow 32 bits */ + { FT_Int64 z1, z2; /* XXX: this function does not allow 64-bit arguments */ - ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); - ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); + ft_multo64( (FT_UInt32)in_x, (FT_UInt32)out_y, &z1 ); + ft_multo64( (FT_UInt32)in_y, (FT_UInt32)out_x, &z2 ); if ( z1.hi > z2.hi ) result = +1; @@ -922,12 +946,12 @@ result = -1; else result = 0; - -#endif } /* XXX: only the sign of return value, +1/0/-1 must be used */ - return (FT_Int)result; + return result; + +#endif } @@ -939,35 +963,40 @@ 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 ); + FT_Pos ax = in_x + out_x; + FT_Pos ay = in_y + out_y; + + FT_Pos d_in, d_out, d_hypot; + + + /* The idea of this function is to compare the length of the */ + /* hypotenuse with the `in' and `out' length. The `corner' */ + /* represented by `in' and `out' is flat if the hypotenuse's */ + /* length isn't too large. */ + /* */ + /* This approach has the advantage that the angle between */ + /* `in' and `out' is not checked. In case one of the two */ + /* vectors is `dominant', this is, much larger than the */ + /* other vector, we thus always have a flat corner. */ + /* */ + /* hypotenuse */ + /* x---------------------------x */ + /* \ / */ + /* \ / */ + /* in \ / out */ + /* \ / */ + /* o */ + /* Point */ + + d_in = FT_HYPOT( in_x, in_y ); + d_out = FT_HYPOT( out_x, out_y ); + d_hypot = FT_HYPOT( ax, ay ); + + /* now do a simple length comparison: */ + /* */ + /* d_in + d_out < 17/16 d_hypot */ + + return ( d_in + d_out - d_hypot ) < ( d_hypot >> 4 ); } diff --git a/drivers/freetype/src/base/ftcid.c b/drivers/freetype/src/base/ftcid.c index 741879d922..251bbd009a 100644 --- a/drivers/freetype/src/base/ftcid.c +++ b/drivers/freetype/src/base/ftcid.c @@ -4,7 +4,8 @@ /* */ /* FreeType API for accessing CID font information. */ /* */ -/* Copyright 2007, 2009, 2013 by Derek Clegg, Michael Toftdal. */ +/* Copyright 2007-2016 by */ +/* Derek Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ diff --git a/drivers/freetype/src/base/ftdbgmem.c b/drivers/freetype/src/base/ftdbgmem.c index 6fb86fe77d..6ab5072748 100644 --- a/drivers/freetype/src/base/ftdbgmem.c +++ b/drivers/freetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001-2006, 2009, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,7 @@ #include FT_CONFIG_STANDARD_LIBRARY_H - FT_BASE_DEF( const char* ) _ft_debug_file = 0; + FT_BASE_DEF( const char* ) _ft_debug_file = NULL; FT_BASE_DEF( long ) _ft_debug_lineno = 0; extern void @@ -47,7 +47,7 @@ typedef struct FT_MemTableRec_* FT_MemTable; -#define FT_MEM_VAL( addr ) ((FT_PtrDist)(FT_Pointer)( addr )) +#define FT_MEM_VAL( addr ) ( (FT_PtrDist)(FT_Pointer)( addr ) ) /* * This structure holds statistics for a single allocation/release @@ -76,7 +76,7 @@ /* - * We don't need a resizable array for the memory sources, because + * We don't need a resizable array for the memory sources because * their number is pretty limited within FreeType. */ #define FT_MEM_SOURCE_BUCKETS 128 @@ -85,8 +85,8 @@ * This structure holds information related to a single allocated * memory block. If KEEPALIVE is defined, blocks that are freed by * FreeType are never released to the system. Instead, their `size' - * field is set to -size. This is mainly useful to detect double frees, - * at the price of large memory footprint during execution. + * field is set to `-size'. This is mainly useful to detect double + * frees, at the price of a large memory footprint during execution. */ typedef struct FT_MemNodeRec_ { @@ -111,20 +111,20 @@ */ typedef struct FT_MemTableRec_ { - FT_ULong size; - FT_ULong nodes; + FT_Long size; + FT_Long nodes; FT_MemNode* buckets; - FT_ULong alloc_total; - FT_ULong alloc_current; - FT_ULong alloc_max; - FT_ULong alloc_count; + FT_Long alloc_total; + FT_Long alloc_current; + FT_Long alloc_max; + FT_Long alloc_count; FT_Bool bound_total; - FT_ULong alloc_total_max; + FT_Long alloc_total_max; FT_Bool bound_count; - FT_ULong alloc_count_max; + FT_Long alloc_count_max; FT_MemSource sources[FT_MEM_SOURCE_BUCKETS]; @@ -142,14 +142,14 @@ #define FT_MEM_SIZE_MIN 7 #define FT_MEM_SIZE_MAX 13845163 -#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") +#define FT_FILENAME( x ) ( (x) ? (x) : "unknown file" ) /* * Prime numbers are ugly to handle. It would be better to implement * L-Hashing, which is 10% faster and doesn't require divisions. */ - static const FT_UInt ft_mem_primes[] = + static const FT_Int ft_mem_primes[] = { 7, 11, @@ -189,10 +189,10 @@ }; - static FT_ULong - ft_mem_closest_prime( FT_ULong num ) + static FT_Long + ft_mem_closest_prime( FT_Long num ) { - FT_UInt i; + size_t i; for ( i = 0; @@ -204,7 +204,7 @@ } - extern void + static void ft_mem_debug_panic( const char* fmt, ... ) { @@ -254,19 +254,20 @@ static void ft_mem_table_resize( FT_MemTable table ) { - FT_ULong new_size; + FT_Long new_size; new_size = ft_mem_closest_prime( table->nodes ); if ( new_size != table->size ) { FT_MemNode* new_buckets; - FT_ULong i; + FT_Long i; new_buckets = (FT_MemNode *) - ft_mem_table_alloc( table, - new_size * sizeof ( FT_MemNode ) ); + ft_mem_table_alloc( + table, + new_size * (FT_Long)sizeof ( FT_MemNode ) ); if ( new_buckets == NULL ) return; @@ -282,7 +283,7 @@ while ( node ) { next = node->link; - hash = FT_MEM_VAL( node->address ) % new_size; + hash = FT_MEM_VAL( node->address ) % (FT_PtrDist)new_size; pnode = new_buckets + hash; node->link = pnode[0]; @@ -325,8 +326,9 @@ table->free = memory->free; table->buckets = (FT_MemNode *) - memory->alloc( memory, - table->size * sizeof ( FT_MemNode ) ); + memory->alloc( + memory, + table->size * (FT_Long)sizeof ( FT_MemNode ) ); if ( table->buckets ) FT_ARRAY_ZERO( table->buckets, table->size ); else @@ -343,9 +345,9 @@ static void ft_mem_table_destroy( FT_MemTable table ) { - FT_ULong i; - FT_Long leak_count = 0; - FT_ULong leaks = 0; + FT_Long i; + FT_Long leak_count = 0; + FT_Long leaks = 0; FT_DumpMemory( table->memory ); @@ -359,13 +361,14 @@ while ( node ) { next = node->link; - node->link = 0; + node->link = NULL; if ( node->size > 0 ) { printf( "leaked memory block at address %p, size %8ld in (%s:%ld)\n", - node->address, node->size, + (void*)node->address, + node->size, FT_FILENAME( node->source->file_name ), node->source->line_no ); @@ -381,7 +384,7 @@ ft_mem_table_free( table, node ); node = next; } - table->buckets[i] = 0; + table->buckets[i] = NULL; } ft_mem_table_free( table, table->buckets ); @@ -430,7 +433,7 @@ hash = FT_MEM_VAL( address ); - pnode = table->buckets + ( hash % table->size ); + pnode = table->buckets + ( hash % (FT_PtrDist)table->size ); for (;;) { @@ -460,14 +463,14 @@ (FT_UInt32)( 5 * _ft_debug_lineno ); pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; - for ( ;; ) + for (;;) { node = *pnode; if ( node == NULL ) break; - if ( node->file_name == _ft_debug_file && - node->line_no == _ft_debug_lineno ) + if ( node->file_name == _ft_debug_file && + node->line_no == _ft_debug_lineno ) goto Exit; pnode = &node->link; @@ -485,11 +488,11 @@ node->max_blocks = 0; node->all_blocks = 0; - node->cur_size = 0; - node->max_size = 0; - node->all_size = 0; + node->cur_size = 0; + node->max_size = 0; + node->all_size = 0; - node->cur_max = 0; + node->cur_max = 0; node->link = NULL; node->hash = hash; @@ -503,7 +506,7 @@ static void ft_mem_table_set( FT_MemTable table, FT_Byte* address, - FT_ULong size, + FT_Long size, FT_Long delta ) { FT_MemNode *pnode, node; @@ -558,7 +561,7 @@ source->max_blocks = source->cur_blocks; } - if ( size > (FT_ULong)source->cur_max ) + if ( size > source->cur_max ) source->cur_max = size; if ( delta != 0 ) @@ -671,7 +674,7 @@ } - extern FT_Pointer + static FT_Pointer ft_mem_debug_alloc( FT_Memory memory, FT_Long size ) { @@ -688,14 +691,14 @@ return NULL; /* return NULL if this allocation would overflow the maximum heap size */ - if ( table->bound_total && - table->alloc_total_max - table->alloc_current > (FT_ULong)size ) + if ( table->bound_total && + table->alloc_total_max - table->alloc_current > size ) return NULL; block = (FT_Byte *)ft_mem_table_alloc( table, size ); if ( block ) { - ft_mem_table_set( table, block, (FT_ULong)size, 0 ); + ft_mem_table_set( table, block, size, 0 ); table->alloc_count++; } @@ -707,7 +710,7 @@ } - extern void + static void ft_mem_debug_free( FT_Memory memory, FT_Pointer block ) { @@ -731,7 +734,7 @@ } - extern FT_Pointer + static FT_Pointer ft_mem_debug_realloc( FT_Memory memory, FT_Long cur_size, FT_Long new_size, @@ -787,21 +790,22 @@ table->alloc_count >= table->alloc_count_max ) return NULL; - delta = (FT_Long)( new_size - cur_size ); + delta = new_size - cur_size; /* return NULL if this allocation would overflow the maximum heap size */ - if ( delta > 0 && - table->bound_total && - table->alloc_current + (FT_ULong)delta > table->alloc_total_max ) + if ( delta > 0 && + table->bound_total && + table->alloc_current + delta > table->alloc_total_max ) return NULL; - new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size ); + new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size ); if ( new_block == NULL ) return NULL; ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); - ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); + ft_memcpy( new_block, block, cur_size < new_size ? (size_t)cur_size + : (size_t)new_size ); ft_mem_table_remove( table, (FT_Byte*)block, delta ); @@ -844,7 +848,7 @@ if ( total_max > 0 ) { table->bound_total = 1; - table->alloc_total_max = (FT_ULong)total_max; + table->alloc_total_max = total_max; } } @@ -857,7 +861,7 @@ if ( total_count > 0 ) { table->bound_count = 1; - table->alloc_count_max = (FT_ULong)total_count; + table->alloc_count_max = total_count; } } @@ -896,7 +900,6 @@ } - static int ft_mem_source_compare( const void* p1, const void* p2 ) @@ -925,7 +928,7 @@ FT_MemSource* bucket = table->sources; FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; FT_MemSource* sources; - FT_UInt nn, count; + FT_Int nn, count; const char* fmt; @@ -939,8 +942,9 @@ count++; } - sources = (FT_MemSource*)ft_mem_table_alloc( - table, sizeof ( *sources ) * count ); + sources = (FT_MemSource*) + ft_mem_table_alloc( + table, count * (FT_Long)sizeof ( *sources ) ); count = 0; for ( bucket = table->sources; bucket < limit; bucket++ ) @@ -952,7 +956,10 @@ sources[count++] = source; } - ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare ); + ft_qsort( sources, + (size_t)count, + sizeof ( *sources ), + ft_mem_source_compare ); printf( "FreeType Memory Dump: " "current=%ld max=%ld total=%ld count=%ld\n", diff --git a/drivers/freetype/src/base/ftdebug.c b/drivers/freetype/src/base/ftdebug.c index b9156d15ee..40925d14a0 100644 --- a/drivers/freetype/src/base/ftdebug.c +++ b/drivers/freetype/src/base/ftdebug.c @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2008, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -152,8 +152,8 @@ /* the memory and stream components which are set to 7 and 5, */ /* respectively. */ /* */ - /* See the file <include/freetype/internal/fttrace.h> for details of the */ - /* available toggle names. */ + /* See the file `include/freetype/internal/fttrace.h' for details of */ + /* the available toggle names. */ /* */ /* The level must be between 0 and 7; 0 means quiet (except for serious */ /* runtime errors), and 7 means _very_ verbose. */ diff --git a/drivers/freetype/src/base/ftfntfmt.c b/drivers/freetype/src/base/ftfntfmt.c new file mode 100644 index 0000000000..c6eb3190c6 --- /dev/null +++ b/drivers/freetype/src/base/ftfntfmt.c @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ftfntfmt.c */ +/* */ +/* FreeType utility file for font formats (body). */ +/* */ +/* Copyright 2002-2016 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_FONT_FORMATS_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_FONT_FORMAT_H + + + /* documentation is in ftfntfmt.h */ + + FT_EXPORT_DEF( const char* ) + FT_Get_Font_Format( FT_Face face ) + { + const char* result = NULL; + + + if ( face ) + FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT ); + + return result; + } + + + /* deprecated function name; retained for ABI compatibility */ + + FT_EXPORT_DEF( const char* ) + FT_Get_X11_Font_Format( FT_Face face ) + { + const char* result = NULL; + + + if ( face ) + FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT ); + + return result; + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftfstype.c b/drivers/freetype/src/base/ftfstype.c index d0ef7b7c1b..ae56c8fc8d 100644 --- a/drivers/freetype/src/base/ftfstype.c +++ b/drivers/freetype/src/base/ftfstype.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file to access FSType data (body). */ /* */ -/* Copyright 2008, 2009 by */ +/* Copyright 2008-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -51,7 +51,7 @@ /* look at FSType before fsType for Type42 */ - if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL && + if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, FT_SFNT_OS2 ) ) != NULL && os2->version != 0xFFFFU ) return os2->fsType; diff --git a/drivers/freetype/src/base/ftgasp.c b/drivers/freetype/src/base/ftgasp.c index 8485d29259..e38e55b6c0 100644 --- a/drivers/freetype/src/base/ftgasp.c +++ b/drivers/freetype/src/base/ftgasp.c @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (body). */ /* */ -/* Copyright 2007 by */ +/* Copyright 2007-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/base/ftgloadr.c b/drivers/freetype/src/base/ftgloadr.c index 3cc5c7a805..c4f0ff70f4 100644 --- a/drivers/freetype/src/base/ftgloadr.c +++ b/drivers/freetype/src/base/ftgloadr.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002-2006, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -212,7 +212,8 @@ /* check points & tags */ - new_max = base->n_points + current->n_points + n_points; + new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points + + n_points; old_max = loader->max_points; if ( new_max > old_max ) @@ -245,7 +246,7 @@ /* check contours */ old_max = loader->max_contours; - new_max = base->n_contours + current->n_contours + + new_max = (FT_UInt)base->n_contours + (FT_UInt)current->n_contours + n_contours; if ( new_max > old_max ) { @@ -329,9 +330,9 @@ FT_GlyphLoad base; FT_GlyphLoad current; - FT_UInt n_curr_contours; - FT_UInt n_base_points; - FT_UInt n; + FT_Int n_curr_contours; + FT_Int n_base_points; + FT_Int n; if ( !loader ) @@ -365,8 +366,8 @@ FT_GlyphLoader source ) { FT_Error error; - FT_UInt num_points = source->base.outline.n_points; - FT_UInt num_contours = source->base.outline.n_contours; + FT_UInt num_points = (FT_UInt)source->base.outline.n_points; + FT_UInt num_contours = (FT_UInt)source->base.outline.n_contours; error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); diff --git a/drivers/freetype/src/base/ftglyph.c b/drivers/freetype/src/base/ftglyph.c index 5dd28a8c52..c2376dd03a 100644 --- a/drivers/freetype/src/base/ftglyph.c +++ b/drivers/freetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2005, 2007, 2008, 2010, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -82,7 +82,7 @@ } else { - FT_Bitmap_New( &glyph->bitmap ); + FT_Bitmap_Init( &glyph->bitmap ); error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap ); } @@ -125,10 +125,10 @@ FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); - cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); + cbox->xMin = glyph->left * 64; + cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width * 64 ); + cbox->yMax = glyph->top * 64; + cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows * 64 ); } @@ -173,7 +173,9 @@ } /* allocate new outline */ - error = FT_Outline_New( library, source->n_points, source->n_contours, + error = FT_Outline_New( library, + (FT_UInt)source->n_points, + source->n_contours, &glyph->outline ); if ( error ) goto Exit; @@ -205,8 +207,10 @@ FT_Library library = FT_GLYPH( source )->library; - error = FT_Outline_New( library, source->outline.n_points, - source->outline.n_contours, &target->outline ); + error = FT_Outline_New( library, + (FT_UInt)source->outline.n_points, + source->outline.n_contours, + &target->outline ); if ( !error ) FT_Outline_Copy( &source->outline, &target->outline ); @@ -287,7 +291,7 @@ FT_Glyph glyph = NULL; - *aglyph = 0; + *aglyph = NULL; if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) { @@ -314,13 +318,13 @@ /* check arguments */ - if ( !target ) + if ( !target || !source || !source->clazz ) { error = FT_THROW( Invalid_Argument ); goto Exit; } - *target = 0; + *target = NULL; if ( !source || !source->clazz ) { @@ -359,7 +363,7 @@ FT_Error error; FT_Glyph glyph; - const FT_Glyph_Class* clazz = 0; + const FT_Glyph_Class* clazz = NULL; if ( !slot ) @@ -399,9 +403,9 @@ if ( error ) goto Exit; - /* copy advance while converting it to 16.16 format */ - glyph->advance.x = slot->advance.x << 10; - glyph->advance.y = slot->advance.y << 10; + /* copy advance while converting 26.6 to 16.16 format */ + glyph->advance.x = slot->advance.x * 1024; + glyph->advance.y = slot->advance.y * 1024; /* now import the image from the glyph slot */ error = clazz->glyph_init( glyph, slot ); @@ -424,15 +428,16 @@ FT_Matrix* matrix, FT_Vector* delta ) { - const FT_Glyph_Class* clazz; - FT_Error error = FT_Err_Ok; + FT_Error error = FT_Err_Ok; if ( !glyph || !glyph->clazz ) error = FT_THROW( Invalid_Argument ); else { - clazz = glyph->clazz; + const FT_Glyph_Class* clazz = glyph->clazz; + + if ( clazz->glyph_transform ) { /* transform glyph image */ @@ -466,38 +471,33 @@ if ( !glyph || !glyph->clazz ) return; - else + + clazz = glyph->clazz; + if ( !clazz->glyph_bbox ) + return; + + /* retrieve bbox in 26.6 coordinates */ + clazz->glyph_bbox( glyph, acbox ); + + /* perform grid fitting if needed */ + if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) { - clazz = glyph->clazz; - if ( !clazz->glyph_bbox ) - return; - else - { - /* retrieve bbox in 26.6 coordinates */ - clazz->glyph_bbox( glyph, acbox ); - - /* perform grid fitting if needed */ - if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || - bbox_mode == FT_GLYPH_BBOX_PIXELS ) - { - acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); - acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); - acbox->xMax = FT_PIX_CEIL( acbox->xMax ); - acbox->yMax = FT_PIX_CEIL( acbox->yMax ); - } - - /* convert to integer pixels if needed */ - if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || - bbox_mode == FT_GLYPH_BBOX_PIXELS ) - { - acbox->xMin >>= 6; - acbox->yMin >>= 6; - acbox->xMax >>= 6; - acbox->yMax >>= 6; - } - } + acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); + acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); + acbox->xMax = FT_PIX_CEIL( acbox->xMax ); + acbox->yMax = FT_PIX_CEIL( acbox->yMax ); + } + + /* convert to integer pixels if needed */ + if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) + { + acbox->xMin >>= 6; + acbox->yMin >>= 6; + acbox->xMax >>= 6; + acbox->yMax >>= 6; } - return; } @@ -516,7 +516,7 @@ FT_BitmapGlyph bitmap = NULL; const FT_Glyph_Class* clazz; - /* FT_BITMAP_GLYPH_CLASS_GET derefers `library' in PIC mode */ + /* FT_BITMAP_GLYPH_CLASS_GET dereferences `library' in PIC mode */ FT_Library library; diff --git a/drivers/freetype/src/base/ftgxval.c b/drivers/freetype/src/base/ftgxval.c index a8ec44ac00..6667b371a1 100644 --- a/drivers/freetype/src/base/ftgxval.c +++ b/drivers/freetype/src/base/ftgxval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTyepGX/AAT tables (body). */ /* */ -/* Copyright 2004-2006, 2010, 2013 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO, Redhat K.K, */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -50,7 +50,7 @@ goto Exit; } - if ( tables == NULL ) + if ( !tables ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -102,7 +102,7 @@ goto Exit; } - if ( ckern_table == NULL ) + if ( !ckern_table ) { error = FT_THROW( Invalid_Argument ); goto Exit; diff --git a/drivers/freetype/src/base/fthash.c b/drivers/freetype/src/base/fthash.c new file mode 100644 index 0000000000..21bc8dd5b4 --- /dev/null +++ b/drivers/freetype/src/base/fthash.c @@ -0,0 +1,339 @@ +/***************************************************************************/ +/* */ +/* fthash.c */ +/* */ +/* Hashing functions (body). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * 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 to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_HASH_H +#include FT_INTERNAL_MEMORY_H + + +#define INITIAL_HT_SIZE 241 + + + static FT_ULong + hash_str_lookup( FT_Hashkey* key ) + { + const char* kp = key->str; + FT_ULong res = 0; + + + /* Mocklisp hash function. */ + while ( *kp ) + res = ( res << 5 ) - res + (FT_ULong)*kp++; + + return res; + } + + + static FT_ULong + hash_num_lookup( FT_Hashkey* key ) + { + FT_ULong num = (FT_ULong)key->num; + FT_ULong res; + + + /* Mocklisp hash function. */ + res = num & 0xFF; + res = ( res << 5 ) - res + ( ( num >> 8 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 16 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 24 ) & 0xFF ); + + return res; + } + + + static FT_Bool + hash_str_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->str[0] == b->str[0] && + ft_strcmp( a->str, b->str ) == 0 ) + return 1; + + return 0; + } + + + static FT_Bool + hash_num_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->num == b->num ) + return 1; + + return 0; + } + + + static FT_Hashnode* + hash_bucket( FT_Hashkey key, + FT_Hash hash ) + { + FT_ULong res = 0; + FT_Hashnode* bp = hash->table; + FT_Hashnode* ndp; + + + res = (hash->lookup)( &key ); + + ndp = bp + ( res % hash->size ); + while ( *ndp ) + { + if ( (hash->compare)( &(*ndp)->key, &key ) ) + break; + + ndp--; + if ( ndp < bp ) + ndp = bp + ( hash->size - 1 ); + } + + return ndp; + } + + + static FT_Error + hash_rehash( FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode* obp = hash->table; + FT_Hashnode* bp; + FT_Hashnode* nbp; + + FT_UInt i, sz = hash->size; + FT_Error error = FT_Err_Ok; + + + hash->size <<= 1; + hash->limit = hash->size / 3; + + if ( FT_NEW_ARRAY( hash->table, hash->size ) ) + goto Exit; + + for ( i = 0, bp = obp; i < sz; i++, bp++ ) + { + if ( *bp ) + { + nbp = hash_bucket( (*bp)->key, hash ); + *nbp = *bp; + } + } + + FT_FREE( obp ); + + Exit: + return error; + } + + + static FT_Error + hash_init( FT_Hash hash, + FT_Bool is_num, + FT_Memory memory ) + { + FT_UInt sz = INITIAL_HT_SIZE; + FT_Error error; + + + hash->size = sz; + hash->limit = sz / 3; + hash->used = 0; + + if ( is_num ) + { + hash->lookup = hash_num_lookup; + hash->compare = hash_num_compare; + } + else + { + hash->lookup = hash_str_lookup; + hash->compare = hash_str_compare; + } + + FT_MEM_NEW_ARRAY( hash->table, sz ); + + return error; + } + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 0, memory ); + } + + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 1, memory ); + } + + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ) + { + if ( hash ) + { + FT_UInt sz = hash->size; + FT_Hashnode* bp = hash->table; + FT_UInt i; + + + for ( i = 0; i < sz; i++, bp++ ) + FT_FREE( *bp ); + + FT_FREE( hash->table ); + } + } + + + /* `ft_hash_num_free' is the same as `ft_hash_str_free' */ + + + static FT_Error + hash_insert( FT_Hashkey key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode nn; + FT_Hashnode* bp = hash_bucket( key, hash ); + FT_Error error = FT_Err_Ok; + + + nn = *bp; + if ( !nn ) + { + if ( FT_NEW( nn ) ) + goto Exit; + *bp = nn; + + nn->key = key; + nn->data = data; + + if ( hash->used >= hash->limit ) + { + error = hash_rehash( hash, memory ); + if ( error ) + goto Exit; + } + + hash->used++; + } + else + nn->data = data; + + Exit: + return error; + } + + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_insert( hk, data, hash, memory ); + } + + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_insert( hk, data, hash, memory ); + } + + + static size_t* + hash_lookup( FT_Hashkey key, + FT_Hash hash ) + { + FT_Hashnode* np = hash_bucket( key, hash ); + + + return (*np) ? &(*np)->data + : NULL; + } + + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_lookup( hk, hash ); + } + + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_lookup( hk, hash ); + } + + +/* END */ diff --git a/drivers/freetype/src/base/ftinit.c b/drivers/freetype/src/base/ftinit.c index 85f321fd2d..c2dd0a7b37 100644 --- a/drivers/freetype/src/base/ftinit.c +++ b/drivers/freetype/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2002, 2005, 2007, 2009, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -138,7 +138,7 @@ #include FT_CONFIG_MODULES_H FT_FREE( classes ); - pic_container->default_module_classes = 0; + pic_container->default_module_classes = NULL; } @@ -164,7 +164,7 @@ memory = library->memory; - pic_container->default_module_classes = 0; + pic_container->default_module_classes = NULL; if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) * ( FT_NUM_MODULE_CLASSES + 1 ) ) ) @@ -172,8 +172,8 @@ /* initialize all pointers to 0, especially the last one */ for ( i = 0; i < FT_NUM_MODULE_CLASSES; i++ ) - classes[i] = 0; - classes[FT_NUM_MODULE_CLASSES] = 0; + classes[i] = NULL; + classes[FT_NUM_MODULE_CLASSES] = NULL; i = 0; @@ -235,6 +235,8 @@ FT_Memory memory; + /* check of `alibrary' delayed to `FT_New_Library' */ + /* First of all, allocate a new system object -- this function is part */ /* of the system-specific component, i.e. `ftsystem.c'. */ @@ -263,17 +265,19 @@ FT_EXPORT_DEF( FT_Error ) FT_Done_FreeType( FT_Library library ) { - if ( library ) - { - FT_Memory memory = library->memory; + FT_Memory memory; - /* Discard the library object */ - FT_Done_Library( library ); + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); - /* discard memory manager */ - FT_Done_Memory( memory ); - } + memory = library->memory; + + /* Discard the library object */ + FT_Done_Library( library ); + + /* discard memory manager */ + FT_Done_Memory( memory ); return FT_Err_Ok; } diff --git a/drivers/freetype/src/base/ftlcdfil.c b/drivers/freetype/src/base/ftlcdfil.c index 852fb32982..8bcbed7aab 100644 --- a/drivers/freetype/src/base/ftlcdfil.c +++ b/drivers/freetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006, 2008-2010, 2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,9 +46,16 @@ FT_Byte* line = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + + /* `fir' and `pix' must be at least 32 bit wide, since the sum of */ + /* the values in `weights' can exceed 0xFF */ + for ( ; height > 0; height--, line += bitmap->pitch ) { - FT_UInt fir[5]; + FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ FT_UInt val1, xx; @@ -57,7 +64,6 @@ fir[1] = weights[3] * val1; fir[2] = weights[4] * val1; fir[3] = 0; - fir[4] = 0; val1 = line[1]; fir[0] += weights[1] * val1; @@ -78,7 +84,7 @@ fir[3] = weights[4] * val; pix >>= 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 2] = (FT_Byte)pix; } @@ -87,11 +93,11 @@ pix = fir[0] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 2] = (FT_Byte)pix; pix = fir[1] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 1] = (FT_Byte)pix; } } @@ -104,10 +110,14 @@ FT_Int pitch = bitmap->pitch; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; - FT_UInt fir[5]; + FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ FT_UInt val1, yy; @@ -116,7 +126,6 @@ fir[1] = weights[3] * val1; fir[2] = weights[4] * val1; fir[3] = 0; - fir[4] = 0; col += pitch; val1 = col[0]; @@ -139,7 +148,7 @@ fir[3] = weights[4] * val; pix >>= 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-2 * pitch] = (FT_Byte)pix; col += pitch; } @@ -149,11 +158,11 @@ pix = fir[0] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-2 * pitch] = (FT_Byte)pix; pix = fir[1] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-pitch] = (FT_Byte)pix; } } @@ -173,7 +182,7 @@ FT_UInt height = (FT_UInt)bitmap->rows; FT_Int pitch = bitmap->pitch; - static const int filters[3][3] = + static const unsigned int filters[3][3] = { { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 }, { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 }, @@ -189,6 +198,10 @@ FT_Byte* line = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; height > 0; height--, line += pitch ) { FT_UInt xx; @@ -228,10 +241,14 @@ FT_Byte* column = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; - FT_Byte* col_end = col + height * pitch; + FT_Byte* col_end = col + (FT_Int)height * pitch; for ( ; col < col_end; col += 3 * pitch ) @@ -272,10 +289,15 @@ FT_Library_SetLcdFilterWeights( FT_Library library, unsigned char *weights ) { - if ( !library || !weights ) + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !weights ) return FT_THROW( Invalid_Argument ); ft_memcpy( library->lcd_weights, weights, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; return FT_Err_Ok; } @@ -285,16 +307,14 @@ FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { + static const FT_Byte default_filter[5] = + { 0x08, 0x4d, 0x56, 0x4d, 0x08 }; static const FT_Byte light_filter[5] = { 0x00, 0x55, 0x56, 0x55, 0x00 }; - /* 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 ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Library_Handle ); switch ( filter ) { @@ -304,25 +324,9 @@ 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 ) - - ft_memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#else - ft_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: @@ -334,6 +338,7 @@ #ifdef USE_LEGACY case FT_LCD_FILTER_LEGACY: + case FT_LCD_FILTER_LEGACY1: library->lcd_filter_func = _ft_lcd_filter_legacy; library->lcd_extra = 0; break; diff --git a/drivers/freetype/src/base/ftmac.c b/drivers/freetype/src/base/ftmac.c index 5b5aae61cc..e97fdbfc22 100644 --- a/drivers/freetype/src/base/ftmac.c +++ b/drivers/freetype/src/base/ftmac.c @@ -8,7 +8,7 @@ /* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ /* classic platforms built by MPW. */ /* */ -/* Copyright 1996-2009, 2013 by */ +/* Copyright 1996-2016 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -227,6 +227,9 @@ FT_Error err; + if ( !fontName || !face_index ) + return FT_THROW( Invalid_Argument); + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); if ( err ) return err; @@ -256,6 +259,9 @@ FT_Error err; + if ( !fontName || !face_index ) + return FT_THROW( Invalid_Argument ); + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); if ( err ) return err; @@ -440,9 +446,10 @@ style = (StyleTable*)p; p += sizeof ( StyleTable ); string_count = EndianS16_BtoN( *(short*)(p) ); + string_count = FT_MIN( 64, string_count ); p += sizeof ( short ); - for ( i = 0; i < string_count && i < 64; i++ ) + for ( i = 0; i < string_count; i++ ) { names[i] = p; p += names[i][0]; @@ -459,7 +466,7 @@ ps_name[ps_name_len] = 0; } if ( style->indexes[face_index] > 1 && - style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) + style->indexes[face_index] <= string_count ) { unsigned char* suffixes = names[style->indexes[face_index] - 1]; @@ -611,11 +618,11 @@ total_size += 6; /* code + 4 bytes chunk length */ } - total_size += GetHandleSize( post_data ) - 2; + total_size += (FT_ULong)GetHandleSize( post_data ) - 2; last_code = code; - /* detect integer overflows */ - if ( total_size < old_total_size ) + /* detect resource fork overflow */ + if ( FT_MAC_RFORK_MAX_LEN < total_size ) { error = FT_THROW( Array_Too_Large ); goto Error; @@ -740,6 +747,11 @@ return FT_THROW( Invalid_Handle ); sfnt_size = (FT_ULong)GetHandleSize( sfnt ); + + /* detect resource fork overflow */ + if ( FT_MAC_RFORK_MAX_LEN < sfnt_size ) + return FT_THROW( Array_Too_Large ); + if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) { ReleaseResource( sfnt ); @@ -852,6 +864,8 @@ FT_Error error = FT_Err_Ok; + /* check of `library' and `aface' delayed to `FT_New_Face_From_XXX' */ + GetResInfo( fond, &fond_id, &fond_type, fond_name ); if ( ResError() != noErr || fond_type != TTAG_FOND ) return FT_THROW( Invalid_File_Format ); @@ -963,7 +977,6 @@ if ( !pathname ) return FT_THROW( Invalid_Argument ); - error = FT_Err_Ok; *aface = NULL; /* try resourcefork based font: LWFN, FFIL */ @@ -998,10 +1011,14 @@ { FT_Error error; FT_Open_Args args; - OSErr err; - UInt8 pathname[PATH_MAX]; + + OSErr err; + UInt8 pathname[PATH_MAX]; + /* check of `library' and `aface' delayed to */ + /* `FT_New_Face_From_Resource' */ + if ( !ref ) return FT_THROW( Invalid_Argument ); @@ -1048,6 +1065,8 @@ FSRef ref; + /* check of `library' and `aface' delayed to `FT_New_Face_From_FSRef' */ + if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr ) return FT_THROW( Invalid_Argument ); else diff --git a/drivers/freetype/src/base/ftmm.c b/drivers/freetype/src/base/ftmm.c index 18ff879bfc..6b759ca467 100644 --- a/drivers/freetype/src/base/ftmm.c +++ b/drivers/freetype/src/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2009, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,6 +72,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !amaster ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -94,6 +99,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !amaster ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -117,6 +127,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -140,6 +155,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -163,6 +183,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -189,6 +214,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { diff --git a/drivers/freetype/src/base/ftobjs.c b/drivers/freetype/src/base/ftobjs.c index 157bf45634..c2dc6183b0 100644 --- a/drivers/freetype/src/base/ftobjs.c +++ b/drivers/freetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -55,10 +55,19 @@ #pragma warning( disable : 4244 ) #endif /* _MSC_VER */ - /* it's easiest to include `md5.c' directly */ -#define free md5_free /* suppress a shadow warning */ + /* It's easiest to include `md5.c' directly. However, since OpenSSL */ + /* also provides the same functions, there might be conflicts if */ + /* both FreeType and OpenSSL are built as static libraries. For */ + /* this reason, we put the MD5 stuff into the `FT_' namespace. */ +#define MD5_u32plus FT_MD5_u32plus +#define MD5_CTX FT_MD5_CTX +#define MD5_Init FT_MD5_Init +#define MD5_Update FT_MD5_Update +#define MD5_Final FT_MD5_Final + +#undef HAVE_OPENSSL + #include "md5.c" -#undef free #if defined( _MSC_VER ) #pragma warning( pop ) @@ -160,7 +169,7 @@ FT_Stream stream = NULL; - *astream = 0; + *astream = NULL; if ( !library ) return FT_THROW( Invalid_Library_Handle ); @@ -180,7 +189,7 @@ /* create a memory-based stream */ FT_Stream_OpenMemory( stream, (const FT_Byte*)args->memory_base, - args->memory_size ); + (FT_ULong)args->memory_size ); } #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT @@ -355,10 +364,10 @@ slot->bitmap_left = 0; slot->bitmap_top = 0; slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; + slot->subglyphs = NULL; + slot->control_data = NULL; slot->control_len = 0; - slot->other = 0; + slot->other = NULL; slot->format = FT_GLYPH_FORMAT_NONE; slot->linearHoriAdvance = 0; @@ -389,7 +398,7 @@ if ( FT_DRIVER_USES_OUTLINES( driver ) ) { FT_GlyphLoader_Done( slot->internal->loader ); - slot->internal->loader = 0; + slot->internal->loader = NULL; } FT_FREE( slot->internal ); @@ -410,7 +419,10 @@ FT_GlyphSlot slot = NULL; - if ( !face || !face->driver ) + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !face->driver ) return FT_THROW( Invalid_Argument ); driver = face->driver; @@ -437,7 +449,7 @@ *aslot = slot; } else if ( aslot ) - *aslot = 0; + *aslot = NULL; Exit: @@ -510,6 +522,7 @@ internal->transform_matrix.xy = 0; internal->transform_matrix.yx = 0; internal->transform_matrix.yy = 0x10000L; + matrix = &internal->transform_matrix; } else @@ -525,6 +538,7 @@ { internal->transform_delta.x = 0; internal->transform_delta.y = 0; + delta = &internal->transform_delta; } else @@ -667,11 +681,18 @@ /* the check for `num_locations' assures that we actually */ /* test for instructions in a TTF and not in a CFF-based OTF */ - if ( mode == FT_RENDER_MODE_LIGHT || - face->internal->ignore_unpatented_hinter || + /* */ + /* since `maxSizeOfInstructions' might be unreliable, we */ + /* check the size of the `fpgm' and `prep' tables, too -- */ + /* the assumption is that there don't exist real TTFs where */ + /* both `fpgm' and `prep' tables are missing */ + if ( ( mode == FT_RENDER_MODE_LIGHT && + !FT_DRIVER_HINTS_LIGHTLY( driver ) ) || ( FT_IS_SFNT( face ) && ttface->num_locations && - ttface->max_profile.maxSizeOfInstructions == 0 ) ) + ttface->max_profile.maxSizeOfInstructions == 0 && + ttface->font_program_size == 0 && + ttface->cvt_program_size == 0 ) ) autohint = TRUE; } } @@ -922,7 +943,7 @@ (FT_List_Destructor)destroy_size, memory, driver ); - face->size = 0; + face->size = NULL; /* now discard client data */ if ( face->generic.finalizer ) @@ -940,7 +961,7 @@ face->stream, ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); - face->stream = 0; + face->stream = NULL; /* get rid of it */ if ( face->internal ) @@ -958,10 +979,6 @@ (FT_List_Destructor)destroy_face, driver->root.memory, driver ); - - /* check whether we need to drop the driver's glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); } @@ -1035,14 +1052,6 @@ ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif face->charmap = cur[0]; return FT_Err_Ok; } @@ -1057,14 +1066,6 @@ { if ( cur[0]->encoding == FT_ENCODING_UNICODE ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif face->charmap = cur[0]; return FT_Err_Ok; } @@ -1106,17 +1107,7 @@ if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && FT_Get_CMap_Format( cur[0] ) == 14 ) - { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UVS cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif return cur[0]; - } } return NULL; @@ -1133,7 +1124,8 @@ /* */ static FT_Error open_face( FT_Driver driver, - FT_Stream stream, + FT_Stream *astream, + FT_Bool external_stream, FT_Long face_index, FT_Int num_params, FT_Parameter* params, @@ -1141,10 +1133,11 @@ { FT_Memory memory; FT_Driver_Class clazz; - FT_Face face = 0; - FT_Error error, error2; + FT_Face face = NULL; FT_Face_Internal internal = NULL; + FT_Error error, error2; + clazz = driver->clazz; memory = driver->root.memory; @@ -1155,7 +1148,11 @@ face->driver = driver; face->memory = memory; - face->stream = stream; + face->stream = *astream; + + /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ + if ( external_stream ) + face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; if ( FT_NEW( internal ) ) goto Fail; @@ -1167,7 +1164,7 @@ int i; - face->internal->incremental_interface = 0; + face->internal->incremental_interface = NULL; for ( i = 0; i < num_params && !face->internal->incremental_interface; i++ ) if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) @@ -1177,11 +1174,12 @@ #endif if ( clazz->init_face ) - error = clazz->init_face( stream, + error = clazz->init_face( *astream, face, (FT_Int)face_index, num_params, params ); + *astream = face->stream; /* Stream may have been changed. */ if ( error ) goto Fail; @@ -1208,7 +1206,7 @@ clazz->done_face( face ); FT_FREE( internal ); FT_FREE( face ); - *aface = 0; + *aface = NULL; } return error; @@ -1231,7 +1229,7 @@ FT_Open_Args args; - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + /* test for valid `library' and `aface' delayed to `FT_Open_Face' */ if ( !pathname ) return FT_THROW( Invalid_Argument ); @@ -1257,7 +1255,7 @@ FT_Open_Args args; - /* test for valid `library' and `face' delayed to FT_Open_Face() */ + /* test for valid `library' and `face' delayed to `FT_Open_Face' */ if ( !file_base ) return FT_THROW( Invalid_Argument ); @@ -1311,8 +1309,8 @@ FT_FREE( stream->base ); stream->size = 0; - stream->base = 0; - stream->close = 0; + stream->base = NULL; + stream->close = NULL; } @@ -1336,7 +1334,7 @@ if ( !base ) return FT_THROW( Invalid_Argument ); - *astream = 0; + *astream = NULL; memory = library->memory; if ( FT_NEW( stream ) ) goto Exit; @@ -1388,13 +1386,13 @@ } #ifdef FT_MACINTOSH - /* At this point, face_index has served its purpose; */ + /* At this point, the face index has served its purpose; */ /* whoever calls this function has already used it to */ /* locate the correct font data. We should not propagate */ /* this index to FT_Open_Face() (unless it is negative). */ if ( face_index > 0 ) - face_index = 0; + face_index &= 0x7FFF0000L; /* retain GX data */ #endif error = FT_Open_Face( library, &args, face_index, aface ); @@ -1420,7 +1418,7 @@ /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ /* format too. Here, since we can't expect that the TrueType font */ - /* driver is loaded unconditially, we must parse the font by */ + /* driver is loaded unconditionally, we must parse the font by */ /* ourselves. We are only interested in the name of the table and */ /* the offset. */ @@ -1485,6 +1483,7 @@ if ( face_index >= 0 && pstable_index == face_index ) return FT_Err_Ok; } + return FT_THROW( Table_Missing ); } @@ -1500,7 +1499,7 @@ FT_Error error; FT_Memory memory = library->memory; FT_ULong offset, length; - FT_Long pos; + FT_ULong pos; FT_Bool is_sfnt_cid; FT_Byte* sfnt_ps = NULL; @@ -1508,7 +1507,11 @@ FT_UNUSED( params ); - pos = FT_Stream_Pos( stream ); + /* ignore GX stuff */ + if ( face_index > 0 ) + face_index &= 0xFFFFL; + + pos = FT_STREAM_POS(); error = ft_lookup_PS_in_sfnt_stream( stream, face_index, @@ -1518,7 +1521,21 @@ if ( error ) goto Exit; - if ( FT_Stream_Seek( stream, pos + offset ) ) + if ( offset > stream->size ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table offset\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + else if ( length > stream->size - offset ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + error = FT_Stream_Seek( stream, pos + offset ); + if ( error ) goto Exit; if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) @@ -1526,7 +1543,10 @@ error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); if ( error ) + { + FT_FREE( sfnt_ps ); goto Exit; + } error = open_face_from_buffer( library, sfnt_ps, @@ -1571,9 +1591,9 @@ FT_Memory memory = library->memory; FT_Byte* pfb_data = NULL; int i, type, flags; - FT_Long len; - FT_Long pfb_len, pfb_pos, pfb_lenpos; - FT_Long rlen, temp; + FT_ULong len; + FT_ULong pfb_len, pfb_pos, pfb_lenpos; + FT_ULong rlen, temp; if ( face_index == -1 ) @@ -1586,14 +1606,39 @@ pfb_len = 0; for ( i = 0; i < resource_cnt; ++i ) { - error = FT_Stream_Seek( stream, offsets[i] ); + error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit; - if ( FT_READ_LONG( temp ) ) + if ( FT_READ_ULONG( temp ) ) + goto Exit; + + /* FT2 allocator takes signed long buffer length, + * too large value causing overflow should be checked + */ + FT_TRACE4(( " POST fragment #%d: length=0x%08x" + " total pfb_len=0x%08x\n", + i, temp, pfb_len + temp + 6)); + if ( FT_MAC_RFORK_MAX_LEN < temp || + FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 ) + { + FT_TRACE2(( " MacOS resource length cannot exceed" + " 0x%08x\n", FT_MAC_RFORK_MAX_LEN )); + error = FT_THROW( Invalid_Offset ); goto Exit; + } + pfb_len += temp + 6; } + FT_TRACE2(( " total buffer size to concatenate %d" + " POST fragments: 0x%08x\n", + resource_cnt, pfb_len + 2)); + if ( pfb_len + 2 < 6 ) { + FT_TRACE2(( " too long fragment length makes" + " pfb_len confused: pfb_len=0x%08x\n", pfb_len )); + error = FT_THROW( Array_Too_Large ); + goto Exit; + } if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; @@ -1610,19 +1655,33 @@ type = 1; for ( i = 0; i < resource_cnt; ++i ) { - error = FT_Stream_Seek( stream, offsets[i] ); + error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit2; - if ( FT_READ_LONG( rlen ) ) - goto Exit; + if ( FT_READ_ULONG( rlen ) ) + goto Exit2; + + /* FT2 allocator takes signed long buffer length, + * too large fragment length causing overflow should be checked + */ + if ( 0x7FFFFFFFUL < rlen ) + { + error = FT_THROW( Invalid_Offset ); + goto Exit2; + } + if ( FT_READ_USHORT( flags ) ) - goto Exit; + goto Exit2; FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", i, offsets[i], rlen, flags )); + error = FT_ERR( Array_Too_Large ); /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ + { + FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", i )); continue; + } /* the flags are part of the resource, so rlen >= 2. */ /* but some fonts declare rlen = 0 for empty fragment */ @@ -1635,6 +1694,8 @@ len += rlen; else { + FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" + " %p + 0x%08x\n", i, pfb_data, pfb_lenpos )); if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_lenpos ] = (FT_Byte)( len ); @@ -1645,6 +1706,8 @@ if ( ( flags >> 8 ) == 5 ) /* End of font mark */ break; + FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" + " %p + 0x%08x\n", i, pfb_data, pfb_pos )); if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1660,16 +1723,18 @@ pfb_data[pfb_pos++] = 0; } - error = FT_ERR( Cannot_Open_Resource ); if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len ) goto Exit2; + FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" + " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos )); error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) goto Exit2; pfb_pos += rlen; } + error = FT_ERR( Array_Too_Large ); if ( pfb_pos + 2 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1690,6 +1755,13 @@ aface ); Exit2: + if ( error == FT_ERR( Array_Too_Large ) ) + FT_TRACE2(( " Abort due to too-short buffer to store" + " all POST fragments\n" )); + else if ( error == FT_ERR( Invalid_Offset ) ) + FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" )); + if ( error ) + error = FT_ERR( Cannot_Open_Resource ); FT_FREE( pfb_data ); Exit: @@ -1700,7 +1772,7 @@ /* The resource header says we've got resource_cnt `sfnt' */ /* (TrueType/OpenType) resources in this file. Look through */ /* them for the one indicated by face_index, load it into mem, */ - /* pass it on the the truetype driver and return it. */ + /* pass it on to the truetype driver, and return it. */ /* */ static FT_Error Mac_Read_sfnt_Resource( FT_Library library, @@ -1713,18 +1785,18 @@ FT_Memory memory = library->memory; FT_Byte* sfnt_data = NULL; FT_Error error; - FT_Long flag_offset; + FT_ULong flag_offset; FT_Long rlen; int is_cff; FT_Long face_index_in_resource = 0; - if ( face_index == -1 ) - face_index = 0; + if ( face_index < 0 ) + face_index = -face_index - 1; if ( face_index >= resource_cnt ) return FT_THROW( Cannot_Open_Resource ); - flag_offset = offsets[face_index]; + flag_offset = (FT_ULong)offsets[face_index]; error = FT_Stream_Seek( stream, flag_offset ); if ( error ) goto Exit; @@ -1733,6 +1805,8 @@ goto Exit; if ( rlen == -1 ) return FT_THROW( Cannot_Open_Resource ); + if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN ) + return FT_THROW( Invalid_Offset ); error = open_face_PS_from_sfnt_stream( library, stream, @@ -1743,19 +1817,22 @@ goto Exit; /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ - if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + error = FT_Stream_Seek( stream, flag_offset + 4 ); + if ( error ) goto Exit; - if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) + if ( FT_ALLOC( sfnt_data, rlen ) ) return error; - error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); - if ( error ) + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen ); + if ( error ) { + FT_FREE( sfnt_data ); goto Exit; + } is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); error = open_face_from_buffer( library, sfnt_data, - rlen, + (FT_ULong)rlen, face_index_in_resource, is_cff ? "cff" : "truetype", aface ); @@ -1789,9 +1866,10 @@ if ( error ) return error; + /* POST resources must be sorted to concatenate properly */ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - TTAG_POST, + TTAG_POST, TRUE, &data_offsets, &count ); if ( !error ) { @@ -1804,9 +1882,11 @@ return error; } + /* sfnt resources should not be sorted to preserve the face order by + QuickDraw API */ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - TTAG_sfnt, + TTAG_sfnt, FALSE, &data_offsets, &count ); if ( !error ) { @@ -1849,13 +1929,14 @@ if ( error ) goto Exit; - if ( header[ 0] != 0 || - header[74] != 0 || - header[82] != 0 || - header[ 1] == 0 || - header[ 1] > 33 || - header[63] != 0 || - header[2 + header[1]] != 0 ) + if ( header[ 0] != 0 || + header[74] != 0 || + header[82] != 0 || + header[ 1] == 0 || + header[ 1] > 33 || + header[63] != 0 || + header[2 + header[1]] != 0 || + header[0x53] > 0x7F ) return FT_THROW( Unknown_File_Format ); dlen = ( header[0x53] << 24 ) | @@ -1866,7 +1947,7 @@ rlen = ( header[0x57] << 24 ) | ( header[0x58] << 16 ) | ( header[0x59] << 8 ) | - header[0x5a]; + header[0x5A]; #endif /* 0 */ offset = 128 + ( ( dlen + 127 ) & ~127 ); @@ -1890,7 +1971,7 @@ FT_Memory memory = library->memory; FT_Error error = FT_ERR( Unknown_File_Format ); - int i; + FT_UInt i; char * file_names[FT_RACCESS_N_RULES]; FT_Long offsets[FT_RACCESS_N_RULES]; @@ -1898,7 +1979,7 @@ FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ FT_Open_Args args2; - FT_Stream stream2 = 0; + FT_Stream stream2 = NULL; FT_Raccess_Guess( library, stream, @@ -1992,7 +2073,11 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_raccess - FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE3(( "Try as dfont: " )); + if ( !( args->flags & FT_OPEN_MEMORY ) ) + FT_TRACE3(( "%s ...", args->pathname )); +#endif error = IsMacResource( library, stream, 0, face_index, aface ); @@ -2034,8 +2119,7 @@ FT_Module* limit; - /* test for valid `library' delayed to */ - /* FT_Stream_New() */ + /* test for valid `library' delayed to `FT_Stream_New' */ if ( ( !aface && face_index >= 0 ) || !args ) return FT_THROW( Invalid_Argument ); @@ -2060,7 +2144,7 @@ if ( FT_MODULE_IS_DRIVER( driver ) ) { FT_Int num_params = 0; - FT_Parameter* params = 0; + FT_Parameter* params = NULL; if ( args->flags & FT_OPEN_PARAMS ) @@ -2069,7 +2153,7 @@ params = args->params; } - error = open_face( driver, stream, face_index, + error = open_face( driver, &stream, external_stream, face_index, num_params, params, &face ); if ( !error ) goto Success; @@ -2094,7 +2178,7 @@ if ( FT_MODULE_IS_DRIVER( cur[0] ) ) { FT_Int num_params = 0; - FT_Parameter* params = 0; + FT_Parameter* params = NULL; driver = FT_DRIVER( cur[0] ); @@ -2105,7 +2189,7 @@ params = args->params; } - error = open_face( driver, stream, face_index, + error = open_face( driver, &stream, external_stream, face_index, num_params, params, &face ); if ( !error ) goto Success; @@ -2115,7 +2199,8 @@ FT_ERR_EQ( error, Table_Missing ) ) { /* TrueType but essential tables are missing */ - if ( FT_Stream_Seek( stream, 0 ) ) + error = FT_Stream_Seek( stream, 0 ); + if ( error ) break; error = open_face_PS_from_sfnt_stream( library, @@ -2174,10 +2259,6 @@ Success: FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); - /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ - if ( external_stream ) - face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; - /* add the face object to its driver's list */ if ( FT_NEW( node ) ) goto Fail; @@ -2286,7 +2367,7 @@ FT_Open_Args open; - /* test for valid `face' delayed to FT_Attach_Stream() */ + /* test for valid `face' delayed to `FT_Attach_Stream' */ if ( !filepathname ) return FT_THROW( Invalid_Argument ); @@ -2312,7 +2393,7 @@ FT_Driver_Class clazz; - /* test for valid `parameters' delayed to FT_Stream_New() */ + /* test for valid `parameters' delayed to `FT_Stream_New' */ if ( !face ) return FT_THROW( Invalid_Face_Handle ); @@ -2348,6 +2429,9 @@ FT_EXPORT_DEF( FT_Error ) FT_Reference_Face( FT_Face face ) { + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + face->internal->refcount++; return FT_Err_Ok; @@ -2406,20 +2490,20 @@ FT_Driver driver; FT_Driver_Class clazz; - FT_Size size = 0; - FT_ListNode node = 0; + FT_Size size = NULL; + FT_ListNode node = NULL; if ( !face ) return FT_THROW( Invalid_Face_Handle ); if ( !asize ) - return FT_THROW( Invalid_Size_Handle ); + return FT_THROW( Invalid_Argument ); if ( !face->driver ) return FT_THROW( Invalid_Driver_Handle ); - *asize = 0; + *asize = NULL; driver = face->driver; clazz = driver->clazz; @@ -2432,7 +2516,7 @@ size->face = face; /* for now, do not use any internal fields in size objects */ - size->internal = 0; + size->internal = NULL; if ( clazz->init_size ) error = clazz->init_size( size ); @@ -2490,7 +2574,7 @@ if ( face->size == size ) { - face->size = 0; + face->size = NULL; if ( face->sizes_list.head ) face->size = (FT_Size)(face->sizes_list.head->data); } @@ -2923,6 +3007,8 @@ FT_Size_RequestRec req; + /* check of `face' delayed to `FT_Request_Size' */ + if ( !char_width ) char_width = char_height; else if ( !char_height ) @@ -2961,6 +3047,8 @@ FT_Size_RequestRec req; + /* check of `face' delayed to `FT_Request_Size' */ + if ( pixel_width == 0 ) pixel_width = pixel_height; else if ( pixel_height == 0 ) @@ -2972,14 +3060,14 @@ pixel_height = 1; /* use `>=' to avoid potential compiler warning on 16bit platforms */ - if ( pixel_width >= 0xFFFFU ) - pixel_width = 0xFFFFU; + if ( pixel_width >= 0xFFFFU ) + pixel_width = 0xFFFFU; if ( pixel_height >= 0xFFFFU ) pixel_height = 0xFFFFU; req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = pixel_width << 6; - req.height = pixel_height << 6; + req.width = (FT_Long)( pixel_width << 6 ); + req.height = (FT_Long)( pixel_height << 6 ); req.horiResolution = 0; req.vertResolution = 0; @@ -3026,18 +3114,37 @@ if ( kern_mode != FT_KERNING_UNFITTED ) { + FT_Pos orig_x = akerning->x; + FT_Pos orig_y = akerning->y; + + /* we scale down kerning values for small ppem values */ /* to avoid that rounding makes them too big. */ /* `25' has been determined heuristically. */ if ( face->size->metrics.x_ppem < 25 ) - akerning->x = FT_MulDiv( akerning->x, + akerning->x = FT_MulDiv( orig_x, face->size->metrics.x_ppem, 25 ); if ( face->size->metrics.y_ppem < 25 ) - akerning->y = FT_MulDiv( akerning->y, + akerning->y = FT_MulDiv( orig_y, face->size->metrics.y_ppem, 25 ); akerning->x = FT_PIX_ROUND( akerning->x ); akerning->y = FT_PIX_ROUND( akerning->y ); + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Pos orig_x_rounded = FT_PIX_ROUND( orig_x ); + FT_Pos orig_y_rounded = FT_PIX_ROUND( orig_y ); + + + if ( akerning->x != orig_x_rounded || + akerning->y != orig_y_rounded ) + FT_TRACE5(( "FT_Get_Kerning: horizontal kerning" + " (%d, %d) scaled down to (%d, %d) pixels\n", + orig_x_rounded / 64, orig_y_rounded / 64, + akerning->x / 64, akerning->y / 64 )); + } +#endif } } } @@ -3111,15 +3218,6 @@ { if ( cur[0]->encoding == encoding ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), " - "but in too late position to cache\n", - cur - face->charmaps )); - continue; - } -#endif face->charmap = cur[0]; return 0; } @@ -3143,8 +3241,9 @@ return FT_THROW( Invalid_Face_Handle ); cur = face->charmaps; - if ( !cur ) + if ( !cur || !charmap ) return FT_THROW( Invalid_CharMap_Handle ); + if ( FT_Get_CMap_Format( charmap ) == 14 ) return FT_THROW( Invalid_Argument ); @@ -3154,19 +3253,11 @@ { if ( cur[0] == charmap ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), " - "but in too late position to cache\n", - cur - face->charmaps )); - continue; - } -#endif face->charmap = cur[0]; - return 0; + return FT_Err_Ok; } } + return FT_THROW( Invalid_Argument ); } @@ -3188,15 +3279,6 @@ FT_ASSERT( i < charmap->face->num_charmaps ); -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( i > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), " - "but in too late position to cache\n", - i )); - return -i; - } -#endif return i; } @@ -3333,8 +3415,12 @@ FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); FT_TRACE1(( " 0x%x is truncated\n", charcode )); } + result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); + if ( result >= (FT_UInt)face->num_glyphs ) + result = 0; } + return result; } @@ -3349,10 +3435,11 @@ FT_UInt gindex = 0; + /* only do something if we have a charmap, and we have glyphs at all */ if ( face && face->charmap && face->num_glyphs ) { gindex = FT_Get_Char_Index( face, 0 ); - if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs ) + if ( gindex == 0 ) result = FT_Get_Next_Char( face, 0, &gindex ); } @@ -3380,8 +3467,10 @@ FT_CMap cmap = FT_CMAP( face->charmap ); - do { + do + { gindex = cmap->clazz->char_next( cmap, &code ); + } while ( gindex >= (FT_UInt)face->num_glyphs ); result = ( gindex == 0 ) ? 0 : code; @@ -3404,8 +3493,9 @@ FT_UInt result = 0; - if ( face && face->charmap && - face->charmap->encoding == FT_ENCODING_UNICODE ) + if ( face && + face->charmap && + face->charmap->encoding == FT_ENCODING_UNICODE ) { FT_CharMap charmap = find_variant_selector_charmap( face ); FT_CMap ucmap = FT_CMAP( face->charmap ); @@ -3583,7 +3673,9 @@ FT_UInt result = 0; - if ( face && FT_HAS_GLYPH_NAMES( face ) ) + if ( face && + FT_HAS_GLYPH_NAMES( face ) && + glyph_name ) { FT_Service_GlyphDict service; @@ -3608,27 +3700,30 @@ FT_Pointer buffer, FT_UInt buffer_max ) { - FT_Error error = FT_ERR( Invalid_Argument ); + FT_Error error; + FT_Service_GlyphDict service; - /* clean up buffer */ - if ( buffer && buffer_max > 0 ) - ((FT_Byte*)buffer)[0] = 0; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - if ( face && - (FT_Long)glyph_index <= face->num_glyphs && - FT_HAS_GLYPH_NAMES( face ) ) - { - FT_Service_GlyphDict service; + if ( !buffer || buffer_max == 0 ) + return FT_THROW( Invalid_Argument ); + /* clean up buffer */ + ((FT_Byte*)buffer)[0] = '\0'; - FT_FACE_LOOKUP_SERVICE( face, - service, - GLYPH_DICT ); + if ( (FT_Long)glyph_index >= face->num_glyphs ) + return FT_THROW( Invalid_Glyph_Index ); - if ( service && service->get_name ) - error = service->get_name( face, glyph_index, buffer, buffer_max ); - } + if ( !FT_HAS_GLYPH_NAMES( face ) ) + return FT_THROW( Invalid_Argument ); + + FT_FACE_LOOKUP_SERVICE( face, service, GLYPH_DICT ); + if ( service && service->get_name ) + error = service->get_name( face, glyph_index, buffer, buffer_max ); + else + error = FT_THROW( Invalid_Argument ); return error; } @@ -3669,7 +3764,7 @@ FT_Get_Sfnt_Table( FT_Face face, FT_Sfnt_Tag tag ) { - void* table = 0; + void* table = NULL; FT_Service_SFNT_Table service; @@ -3719,6 +3814,8 @@ FT_ULong offset; + /* test for valid `length' delayed to `service->table_info' */ + if ( !face || !FT_IS_SFNT( face ) ) return FT_THROW( Invalid_Face_Handle ); @@ -3786,12 +3883,12 @@ FT_Face face; - if ( size == NULL ) - return FT_THROW( Invalid_Argument ); + if ( !size ) + return FT_THROW( Invalid_Size_Handle ); face = size->face; - if ( face == NULL || face->driver == NULL ) - return FT_THROW( Invalid_Argument ); + if ( !face || !face->driver ) + return FT_THROW( Invalid_Face_Handle ); /* we don't need anything more complex than that; all size objects */ /* are already listed by the face */ @@ -3820,7 +3917,7 @@ FT_ListNode* node ) { FT_ListNode cur; - FT_Renderer result = 0; + FT_Renderer result = NULL; if ( !library ) @@ -3832,7 +3929,7 @@ { if ( *node ) cur = (*node)->next; - *node = 0; + *node = NULL; } while ( cur ) @@ -3933,11 +4030,17 @@ static void ft_remove_renderer( FT_Module module ) { - FT_Library library = module->library; - FT_Memory memory = library->memory; + FT_Library library; + FT_Memory memory; FT_ListNode node; + library = module->library; + if ( !library ) + return; + + memory = library->memory; + node = FT_List_Find( &library->renderers, module ); if ( node ) { @@ -3964,7 +4067,7 @@ FT_Get_Renderer( FT_Library library, FT_Glyph_Format format ) { - /* test for valid `library' delayed to FT_Lookup_Renderer() */ + /* test for valid `library' delayed to `FT_Lookup_Renderer' */ return FT_Lookup_Renderer( library, format, 0 ); } @@ -3981,12 +4084,26 @@ FT_ListNode node; FT_Error error = FT_Err_Ok; + FT_Renderer_SetModeFunc set_mode; + if ( !library ) - return FT_THROW( Invalid_Library_Handle ); + { + error = FT_THROW( Invalid_Library_Handle ); + goto Exit; + } if ( !renderer ) - return FT_THROW( Invalid_Argument ); + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( num_params > 0 && !parameters ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } node = FT_List_Find( &library->renderers, renderer ); if ( !node ) @@ -4000,18 +4117,14 @@ if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) library->cur_renderer = renderer; - if ( num_params > 0 ) - { - FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; - + set_mode = renderer->clazz->set_mode; - for ( ; num_params > 0; num_params-- ) - { - error = set_mode( renderer, parameters->tag, parameters->data ); - if ( error ) - break; - parameters++; - } + for ( ; num_params > 0; num_params-- ) + { + error = set_mode( renderer, parameters->tag, parameters->data ); + if ( error ) + break; + parameters++; } Exit: @@ -4036,8 +4149,7 @@ default: { - FT_ListNode node = 0; - FT_Bool update = 0; + FT_ListNode node = NULL; /* small shortcut for the very common case */ @@ -4064,13 +4176,7 @@ /* now, look for another renderer that supports the same */ /* format. */ renderer = FT_Lookup_Renderer( library, slot->format, &node ); - update = 1; } - - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); } } @@ -4079,35 +4185,51 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_bitmap - /* we convert to a single bitmap format for computing the checksum */ - { - FT_Bitmap bitmap; - FT_Error err; - - - FT_Bitmap_New( &bitmap ); + /* + * Computing the MD5 checksum is expensive, unnecessarily distorting a + * possible profiling of FreeType if compiled with tracing support. For + * this reason, we execute the following code only if explicitly + * requested. + */ - err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); - if ( !err ) + /* we use FT_TRACE3 in this block */ + if ( ft_trace_levels[trace_bitmap] >= 3 ) + { + /* we convert to a single bitmap format for computing the checksum */ + if ( !error ) { - MD5_CTX ctx; - unsigned char md5[16]; - int i; + FT_Bitmap bitmap; + FT_Error err; - MD5_Init( &ctx); - MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch ); - MD5_Final( md5, &ctx ); + FT_Bitmap_Init( &bitmap ); - FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" - " ", - bitmap.rows, bitmap.pitch )); - for ( i = 0; i < 16; i++ ) - FT_TRACE3(( "%02X", md5[i] )); - FT_TRACE3(( "\n" )); - } + /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ + err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); + if ( !err ) + { + MD5_CTX ctx; + unsigned char md5[16]; + int i; + unsigned int rows = bitmap.rows; + unsigned int pitch = (unsigned int)bitmap.pitch; + + + MD5_Init( &ctx ); + if ( bitmap.buffer ) + MD5_Update( &ctx, bitmap.buffer, rows * pitch ); + MD5_Final( md5, &ctx ); + + FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" + " ", + rows, pitch )); + for ( i = 0; i < 16; i++ ) + FT_TRACE3(( "%02X", md5[i] )); + FT_TRACE3(( "\n" )); + } - FT_Bitmap_Done( library, &bitmap ); + FT_Bitmap_Done( library, &bitmap ); + } } #undef FT_COMPONENT @@ -4174,7 +4296,7 @@ if ( library && library->auto_hinter == module ) - library->auto_hinter = 0; + library->auto_hinter = NULL; /* if the module is a renderer */ if ( FT_MODULE_IS_RENDERER( module ) ) @@ -4201,7 +4323,7 @@ { FT_Error error; FT_Memory memory; - FT_Module module; + FT_Module module = NULL; FT_UInt nn; @@ -4270,17 +4392,10 @@ /* if the module is a font driver */ if ( FT_MODULE_IS_DRIVER( module ) ) { - /* allocate glyph loader if needed */ FT_Driver driver = FT_DRIVER( module ); driver->clazz = (FT_Driver_Class)module->clazz; - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - { - error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); - if ( error ) - goto Fail; - } } if ( clazz->module_init ) @@ -4297,15 +4412,6 @@ return error; Fail: - if ( FT_MODULE_IS_DRIVER( module ) ) - { - FT_Driver driver = FT_DRIVER( module ); - - - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); - } - if ( FT_MODULE_IS_RENDERER( module ) ) { FT_Renderer renderer = FT_RENDERER( module ); @@ -4328,7 +4434,7 @@ FT_Get_Module( FT_Library library, const char* module_name ) { - FT_Module result = 0; + FT_Module result = NULL; FT_Module* cur; FT_Module* limit; @@ -4440,7 +4546,7 @@ cur[0] = cur[1]; cur++; } - limit[0] = 0; + limit[0] = NULL; /* destroy the module */ Destroy_Module( module ); @@ -4453,7 +4559,7 @@ } - FT_Error + static FT_Error ft_property_do( FT_Library library, const FT_String* module_name, const FT_String* property_name, @@ -4583,6 +4689,9 @@ FT_EXPORT_DEF( FT_Error ) FT_Reference_Library( FT_Library library ) { + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + library->refcount++; return FT_Err_Ok; @@ -4599,7 +4708,7 @@ FT_Error error; - if ( !memory ) + if ( !memory || !alibrary ) return FT_THROW( Invalid_Argument ); #ifdef FT_DEBUG_LEVEL_ERROR @@ -4620,12 +4729,9 @@ goto Fail; #endif - /* allocate the render pool */ - library->raster_pool_size = FT_RENDER_POOL_SIZE; -#if FT_RENDER_POOL_SIZE > 0 - if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; -#endif + /* we don't use raster_pool anymore. */ + library->raster_pool_size = 0; + library->raster_pool = NULL; library->version_major = FREETYPE_MAJOR; library->version_minor = FREETYPE_MINOR; @@ -4638,8 +4744,8 @@ return FT_Err_Ok; - Fail: #ifdef FT_CONFIG_OPTION_PIC + Fail: ft_pic_container_destroy( library ); #endif FT_FREE( library ); @@ -4768,16 +4874,12 @@ if ( module ) { Destroy_Module( module ); - library->modules[n] = 0; + library->modules[n] = NULL; } } } #endif - /* Destroy raster objects */ - FT_FREE( library->raster_pool ); - library->raster_pool_size = 0; - #ifdef FT_CONFIG_OPTION_PIC /* Destroy pic container contents */ ft_pic_container_destroy( library ); @@ -4861,6 +4963,8 @@ *p_arg1 = subg->arg1; *p_arg2 = subg->arg2; *p_transform = subg->transform; + + error = FT_Err_Ok; } return error; diff --git a/drivers/freetype/src/base/ftotval.c b/drivers/freetype/src/base/ftotval.c index 5fc73d76ab..fe54e0228a 100644 --- a/drivers/freetype/src/base/ftotval.c +++ b/drivers/freetype/src/base/ftotval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (body). */ /* */ -/* Copyright 2004, 2006, 2008, 2010, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/base/ftoutln.c b/drivers/freetype/src/base/ftoutln.c index 54ca5cdcf6..fc28225c6a 100644 --- a/drivers/freetype/src/base/ftoutln.c +++ b/drivers/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2008, 2010, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,7 +42,7 @@ static - const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; + const FT_Outline null_outline = { 0, 0, NULL, NULL, NULL, 0 }; /* documentation is in ftoutln.h */ @@ -52,8 +52,9 @@ const FT_Outline_Funcs* func_interface, void* user ) { -#undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) +#undef SCALED +#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << shift ) \ + : ( (x) << shift ) ) - delta ) FT_Vector v_last; FT_Vector v_control; @@ -73,7 +74,10 @@ FT_Pos delta; - if ( !outline || !func_interface ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !func_interface ) return FT_THROW( Invalid_Argument ); shift = func_interface->shift; @@ -128,7 +132,7 @@ v_start.x = ( v_start.x + v_last.x ) / 2; v_start.y = ( v_start.y + v_last.y ) / 2; - v_last = v_start; + /* v_last = v_start; */ } point--; tags--; @@ -276,7 +280,7 @@ if ( error ) goto Exit; - first = last + 1; + first = (FT_UInt)last + 1; } FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); @@ -317,7 +321,7 @@ FT_NEW_ARRAY( anoutline->contours, numContours ) ) goto Fail; - anoutline->n_points = (FT_UShort)numPoints; + anoutline->n_points = (FT_Short)numPoints; anoutline->n_contours = (FT_Short)numContours; anoutline->flags |= FT_OUTLINE_OWNER; @@ -362,7 +366,7 @@ /* empty glyph? */ if ( n_points == 0 && n_contours == 0 ) - return 0; + return FT_Err_Ok; /* check point and contour counts */ if ( n_points <= 0 || n_contours <= 0 ) @@ -384,7 +388,7 @@ goto Bad; /* XXX: check the tags array */ - return 0; + return FT_Err_Ok; } Bad: @@ -401,19 +405,24 @@ FT_Int is_owner; - if ( !source || !target || - source->n_points != target->n_points || + if ( !source || !target ) + return FT_THROW( Invalid_Outline ); + + if ( source->n_points != target->n_points || source->n_contours != target->n_contours ) return FT_THROW( Invalid_Argument ); if ( source == target ) return FT_Err_Ok; - FT_ARRAY_COPY( target->points, source->points, source->n_points ); - - FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + if ( source->n_points ) + { + FT_ARRAY_COPY( target->points, source->points, source->n_points ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + } - FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); + if ( source->n_contours ) + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ is_owner = target->flags & FT_OUTLINE_OWNER; @@ -430,20 +439,21 @@ FT_Outline_Done_Internal( FT_Memory memory, FT_Outline* outline ) { - if ( memory && outline ) - { - if ( outline->flags & FT_OUTLINE_OWNER ) - { - FT_FREE( outline->points ); - FT_FREE( outline->tags ); - FT_FREE( outline->contours ); - } - *outline = null_outline; + if ( !outline ) + return FT_THROW( Invalid_Outline ); - return FT_Err_Ok; - } - else + if ( !memory ) return FT_THROW( Invalid_Argument ); + + if ( outline->flags & FT_OUTLINE_OWNER ) + { + FT_FREE( outline->points ); + FT_FREE( outline->tags ); + FT_FREE( outline->contours ); + } + *outline = null_outline; + + return FT_Err_Ok; } @@ -576,11 +586,13 @@ { char* p = outline->tags + first; char* q = outline->tags + last; - char swap; while ( p < q ) { + char swap; + + swap = *p; *p = *q; *q = swap; @@ -604,7 +616,6 @@ FT_Raster_Params* params ) { FT_Error error; - FT_Bool update = FALSE; FT_Renderer renderer; FT_ListNode node; @@ -612,7 +623,10 @@ if ( !library ) return FT_THROW( Invalid_Library_Handle ); - if ( !outline || !params ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !params ) return FT_THROW( Invalid_Argument ); renderer = library->cur_renderer; @@ -635,14 +649,8 @@ /* format */ renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, &node ); - update = TRUE; } - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); - return error; } @@ -660,7 +668,7 @@ if ( !abitmap ) return FT_THROW( Invalid_Argument ); - /* other checks are delayed to FT_Outline_Render() */ + /* other checks are delayed to `FT_Outline_Render' */ params.target = abitmap; params.flags = 0; @@ -721,7 +729,8 @@ #if 0 #define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \ - do { \ + do \ + { \ (first) = ( c > 0 ) ? (outline)->points + \ (outline)->contours[c - 1] + 1 \ : (outline)->points; \ @@ -902,13 +911,12 @@ FT_Pos ystrength ) { FT_Vector* points; - FT_Vector v_prev, v_first, v_next, v_cur; - FT_Int c, n, first; + FT_Int c, first, last; FT_Int orientation; if ( !outline ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Outline ); xstrength /= 2; ystrength /= 2; @@ -929,87 +937,98 @@ first = 0; for ( c = 0; c < outline->n_contours; c++ ) { - FT_Vector in, out, shift; - FT_Fixed l_in, l_out, l, q, d; - int last = outline->contours[c]; + FT_Vector in, out, anchor, shift; + FT_Fixed l_in, l_out, l_anchor = 0, l, q, d; + FT_Int i, j, k; - v_first = points[first]; - v_prev = points[last]; - v_cur = v_first; + l_in = 0; + last = outline->contours[c]; - /* compute incoming normalized vector */ - in.x = v_cur.x - v_prev.x; - in.y = v_cur.y - v_prev.y; - l_in = FT_Vector_Length( &in ); - if ( l_in ) - { - in.x = FT_DivFix( in.x, l_in ); - in.y = FT_DivFix( in.y, l_in ); - } + /* pacify compiler */ + in.x = in.y = anchor.x = anchor.y = 0; - for ( n = first; n <= last; n++ ) + /* Counter j cycles though the points; counter i advances only */ + /* when points are moved; anchor k marks the first moved point. */ + for ( i = last, j = first, k = -1; + j != i && i != k; + j = j < last ? j + 1 : first ) { - if ( n < last ) - v_next = points[n + 1]; - else - v_next = v_first; + if ( j != k ) + { + out.x = points[j].x - points[i].x; + out.y = points[j].y - points[i].y; + l_out = (FT_Fixed)FT_Vector_NormLen( &out ); - /* compute outgoing normalized vector */ - out.x = v_next.x - v_cur.x; - out.y = v_next.y - v_cur.y; - l_out = FT_Vector_Length( &out ); - if ( l_out ) + if ( l_out == 0 ) + continue; + } + else { - out.x = FT_DivFix( out.x, l_out ); - out.y = FT_DivFix( out.y, l_out ); + out = anchor; + l_out = l_anchor; } - d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); - - /* shift only if turn is less than ~160 degrees */ - if ( d > -0xF000L ) + if ( l_in != 0 ) { - d = d + 0x10000L; + if ( k < 0 ) + { + k = i; + anchor = in; + l_anchor = l_in; + } - /* shift components are aligned along lateral bisector */ - /* and directed according to the outline orientation. */ - shift.x = in.y + out.y; - shift.y = in.x + out.x; + d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); - if ( orientation == FT_ORIENTATION_TRUETYPE ) - shift.x = -shift.x; - else - shift.y = -shift.y; + /* shift only if turn is less than ~160 degrees */ + if ( d > -0xF000L ) + { + d = d + 0x10000L; - /* restrict shift magnitude to better handle collapsing segments */ - q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x ); - if ( orientation == FT_ORIENTATION_TRUETYPE ) - q = -q; + /* shift components along lateral bisector in proper orientation */ + shift.x = in.y + out.y; + shift.y = in.x + out.x; - l = FT_MIN( l_in, l_out ); + if ( orientation == FT_ORIENTATION_TRUETYPE ) + shift.x = -shift.x; + else + shift.y = -shift.y; - /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ - if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) ) - shift.x = FT_MulDiv( shift.x, xstrength, d ); - else - shift.x = FT_MulDiv( shift.x, l, q ); + /* restrict shift magnitude to better handle collapsing segments */ + q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x ); + if ( orientation == FT_ORIENTATION_TRUETYPE ) + q = -q; + + l = FT_MIN( l_in, l_out ); + + /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ + if ( FT_MulFix( xstrength, q ) <= FT_MulFix( l, d ) ) + shift.x = FT_MulDiv( shift.x, xstrength, d ); + else + shift.x = FT_MulDiv( shift.x, l, q ); - if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) ) - shift.y = FT_MulDiv( shift.y, ystrength, d ); + if ( FT_MulFix( ystrength, q ) <= FT_MulFix( l, d ) ) + shift.y = FT_MulDiv( shift.y, ystrength, d ); + else + shift.y = FT_MulDiv( shift.y, l, q ); + } else - shift.y = FT_MulDiv( shift.y, l, q ); + shift.x = shift.y = 0; + + for ( ; + i != j; + i = i < last ? i + 1 : first ) + { + points[i].x += xstrength + shift.x; + points[i].y += ystrength + shift.y; + } } else - shift.x = shift.y = 0; - - outline->points[n].x = v_cur.x + xstrength + shift.x; - outline->points[n].y = v_cur.y + ystrength + shift.y; + i = j; - in = out; - l_in = l_out; - v_cur = v_next; + in = out; + l_in = l_out; } first = last + 1; @@ -1038,14 +1057,19 @@ /* 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. */ + /* only that is spanned up by the control points. */ FT_Outline_Get_CBox( outline, &cbox ); - xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14; + /* Handle collapsed outlines to avoid undefined FT_MSB. */ + if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax ) + return FT_ORIENTATION_NONE; + + xshift = FT_MSB( (FT_UInt32)( FT_ABS( cbox.xMax ) | + FT_ABS( cbox.xMin ) ) ) - 14; xshift = FT_MAX( xshift, 0 ); - yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14; + yshift = FT_MSB( (FT_UInt32)( cbox.yMax - cbox.yMin ) ) - 14; yshift = FT_MAX( yshift, 0 ); points = outline->points; @@ -1056,13 +1080,16 @@ FT_Int last = outline->contours[c]; - v_prev = points[last]; + v_prev.x = points[last].x >> xshift; + v_prev.y = points[last].y >> yshift; for ( n = first; n <= last; n++ ) { - v_cur = points[n]; - area += ( ( v_cur.y - v_prev.y ) >> yshift ) * - ( ( v_cur.x + v_prev.x ) >> xshift ); + v_cur.x = points[n].x >> xshift; + v_cur.y = points[n].y >> yshift; + + area += ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ); + v_prev = v_cur; } diff --git a/drivers/freetype/src/base/ftpatent.c b/drivers/freetype/src/base/ftpatent.c index 82b42f0343..4861be130e 100644 --- a/drivers/freetype/src/base/ftpatent.c +++ b/drivers/freetype/src/base/ftpatent.c @@ -3,9 +3,10 @@ /* ftpatent.c */ /* */ /* FreeType API for checking patented TrueType bytecode instructions */ -/* (body). */ +/* (body). Obsolete, retained for backwards compatibility. */ /* */ -/* Copyright 2007, 2008, 2010 by David Turner. */ +/* Copyright 2007-2016 by */ +/* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -24,238 +25,14 @@ #include FT_SERVICE_TRUETYPE_GLYF_H - static FT_Bool - _tt_check_patents_in_range( FT_Stream stream, - FT_ULong size ) - { - FT_Bool result = FALSE; - FT_Error error; - FT_Bytes p, end; - - - if ( FT_FRAME_ENTER( size ) ) - return 0; - - p = stream->cursor; - end = p + size; - - while ( p < end ) - { - switch (p[0]) - { - case 0x06: /* SPvTL // */ - case 0x07: /* SPvTL + */ - case 0x08: /* SFvTL // */ - case 0x09: /* SFvTL + */ - case 0x0A: /* SPvFS */ - case 0x0B: /* SFvFS */ - result = TRUE; - goto Exit; - - case 0x40: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] + 2; - break; - - case 0x41: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] * 2 + 2; - break; - - case 0x71: /* DELTAP2 */ - case 0x72: /* DELTAP3 */ - case 0x73: /* DELTAC0 */ - case 0x74: /* DELTAC1 */ - case 0x75: /* DELTAC2 */ - result = TRUE; - goto Exit; - - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - p += ( p[0] - 0xB0 ) + 2; - break; - - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - p += ( p[0] - 0xB8 ) * 2 + 3; - break; - - default: - p += 1; - break; - } - } - - Exit: - FT_UNUSED( error ); - FT_FRAME_EXIT(); - return result; - } - - - static FT_Bool - _tt_check_patents_in_table( FT_Face face, - FT_ULong tag ) - { - FT_Stream stream = face->stream; - FT_Error error = FT_Err_Ok; - FT_Service_SFNT_Table service; - FT_Bool result = FALSE; - - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - - if ( service ) - { - FT_UInt i = 0; - FT_ULong tag_i = 0, offset_i = 0, length_i = 0; - - - for ( i = 0; !error && tag_i != tag ; i++ ) - error = service->table_info( face, i, - &tag_i, &offset_i, &length_i ); - - if ( error || - FT_STREAM_SEEK( offset_i ) ) - goto Exit; - - result = _tt_check_patents_in_range( stream, length_i ); - } - - Exit: - return result; - } - - - static FT_Bool - _tt_face_check_patents( FT_Face face ) - { - FT_Stream stream = face->stream; - FT_UInt gindex; - FT_Error error; - FT_Bool result; - - FT_Service_TTGlyf service; - - - result = _tt_check_patents_in_table( face, TTAG_fpgm ); - if ( result ) - goto Exit; - - result = _tt_check_patents_in_table( face, TTAG_prep ); - if ( result ) - goto Exit; - - FT_FACE_FIND_SERVICE( face, service, TT_GLYF ); - if ( service == NULL ) - goto Exit; - - for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ ) - { - FT_ULong offset, num_ins, size; - FT_Int num_contours; - - - offset = service->get_location( face, gindex, &size ); - if ( size == 0 ) - continue; - - if ( FT_STREAM_SEEK( offset ) || - FT_READ_SHORT( num_contours ) ) - continue; - - if ( num_contours >= 0 ) /* simple glyph */ - { - if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) ) - continue; - } - else /* compound glyph */ - { - FT_Bool has_instr = 0; - - - if ( FT_STREAM_SKIP( 8 ) ) - continue; - - /* now read each component */ - for (;;) - { - FT_UInt flags, toskip; - - - if( FT_READ_USHORT( flags ) ) - break; - - toskip = 2 + 1 + 1; - - if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */ - toskip += 2; - - if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */ - toskip += 2; - else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */ - toskip += 4; - else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */ - toskip += 8; - - if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */ - has_instr = 1; - - if ( FT_STREAM_SKIP( toskip ) ) - goto NextGlyph; - - if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */ - break; - } - - if ( !has_instr ) - goto NextGlyph; - } - - if ( FT_READ_USHORT( num_ins ) ) - continue; - - result = _tt_check_patents_in_range( stream, num_ins ); - if ( result ) - goto Exit; - - NextGlyph: - ; - } - - Exit: - return result; - } - - /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Bool ) FT_Face_CheckTrueTypePatents( FT_Face face ) { - FT_Bool result = FALSE; - - - if ( face && FT_IS_SFNT( face ) ) - result = _tt_face_check_patents( face ); + FT_UNUSED( face ); - return result; + return FALSE; } @@ -265,22 +42,10 @@ FT_Face_SetUnpatentedHinting( FT_Face face, FT_Bool value ) { - FT_Bool result = FALSE; - - -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) - if ( face && FT_IS_SFNT( face ) ) - { - result = !face->internal->ignore_unpatented_hinter; - face->internal->ignore_unpatented_hinter = !value; - } -#else FT_UNUSED( face ); FT_UNUSED( value ); -#endif - return result; + return FALSE; } /* END */ diff --git a/drivers/freetype/src/base/ftpfr.c b/drivers/freetype/src/base/ftpfr.c index 0ba955f01f..81faa529c3 100644 --- a/drivers/freetype/src/base/ftpfr.c +++ b/drivers/freetype/src/base/ftpfr.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (body). */ /* */ -/* Copyright 2002-2004, 2008, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,7 +50,7 @@ if ( !face ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Face_Handle ); service = ft_pfr_check( face ); if ( service ) @@ -106,6 +106,9 @@ if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !avector ) return FT_THROW( Invalid_Argument ); service = ft_pfr_check( face ); @@ -130,11 +133,15 @@ FT_Service_PfrMetrics service; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !aadvance ) + return FT_THROW( Invalid_Argument ); + service = ft_pfr_check( face ); if ( service ) - { error = service->get_advance( face, gindex, aadvance ); - } else /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */ error = FT_THROW( Invalid_Argument ); diff --git a/drivers/freetype/src/base/ftpic.c b/drivers/freetype/src/base/ftpic.c index 1c87101696..03769dba22 100644 --- a/drivers/freetype/src/base/ftpic.c +++ b/drivers/freetype/src/base/ftpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (body). */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,7 +29,7 @@ ft_pic_container_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; + FT_Error error; FT_MEM_SET( pic_container, 0, sizeof ( *pic_container ) ); diff --git a/drivers/freetype/src/base/ftrfork.c b/drivers/freetype/src/base/ftrfork.c index 804911721d..4660c971cf 100644 --- a/drivers/freetype/src/base/ftrfork.c +++ b/drivers/freetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004-2010, 2013 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -29,6 +29,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_RFORK_H #include "basepic.h" +#include "ftbase.h" #undef FT_COMPONENT #define FT_COMPONENT trace_raccess @@ -62,7 +63,7 @@ FT_UNUSED( library ); - error = FT_Stream_Seek( stream, rfork_offset ); + error = FT_Stream_Seek( stream, (FT_ULong)rfork_offset ); if ( error ) return error; @@ -70,25 +71,36 @@ if ( error ) return error; - *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | - ( head[1] << 16 ) | - ( head[2] << 8 ) | - head[3] ); - map_pos = rfork_offset + ( ( head[4] << 24 ) | - ( head[5] << 16 ) | - ( head[6] << 8 ) | - head[7] ); - rdata_len = ( head[ 8] << 24 ) | - ( head[ 9] << 16 ) | - ( head[10] << 8 ) | - head[11]; + /* ensure positive values */ + if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 ) + return FT_THROW( Unknown_File_Format ); + + *rdata_pos = ( head[ 0] << 24 ) | + ( head[ 1] << 16 ) | + ( head[ 2] << 8 ) | + head[ 3]; + map_pos = ( head[ 4] << 24 ) | + ( head[ 5] << 16 ) | + ( head[ 6] << 8 ) | + head[ 7]; + rdata_len = ( head[ 8] << 24 ) | + ( head[ 9] << 16 ) | + ( head[10] << 8 ) | + head[11]; /* map_len = head[12] .. head[15] */ - if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) + if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 ) + return FT_THROW( Unknown_File_Format ); + + if ( FT_LONG_MAX - rfork_offset < *rdata_pos || + FT_LONG_MAX - rfork_offset < map_pos ) return FT_THROW( Unknown_File_Format ); - error = FT_Stream_Seek( stream, map_pos ); + *rdata_pos += rfork_offset; + map_pos += rfork_offset; + + error = FT_Stream_Seek( stream, (FT_ULong)map_pos ); if ( error ) return error; @@ -123,7 +135,7 @@ if ( type_list == -1 ) return FT_THROW( Unknown_File_Format ); - error = FT_Stream_Seek( stream, map_pos + type_list ); + error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) ); if ( error ) return error; @@ -151,6 +163,7 @@ FT_Long map_offset, FT_Long rdata_pos, FT_Long tag, + FT_Bool sort_by_res_id, FT_Long **offsets, FT_Long *count ) { @@ -163,7 +176,8 @@ FT_RFork_Ref *ref = NULL; - error = FT_Stream_Seek( stream, map_offset ); + FT_TRACE3(( "\n" )); + error = FT_Stream_Seek( stream, (FT_ULong)map_offset ); if ( error ) return error; @@ -179,17 +193,19 @@ return error; FT_TRACE2(( "Resource tags: %c%c%c%c\n", - (char)( 0xff & ( tag_internal >> 24 ) ), - (char)( 0xff & ( tag_internal >> 16 ) ), - (char)( 0xff & ( tag_internal >> 8 ) ), - (char)( 0xff & ( tag_internal >> 0 ) ) )); + (char)( 0xFF & ( tag_internal >> 24 ) ), + (char)( 0xFF & ( tag_internal >> 16 ) ), + (char)( 0xFF & ( tag_internal >> 8 ) ), + (char)( 0xFF & ( tag_internal >> 0 ) ) )); + FT_TRACE3(( " : subcount=%d, suboffset=0x%04x\n", + subcnt, rpos )); if ( tag_internal == tag ) { *count = subcnt + 1; rpos += map_offset; - error = FT_Stream_Seek( stream, rpos ); + error = FT_Stream_Seek( stream, (FT_ULong)rpos ); if ( error ) return error; @@ -208,11 +224,24 @@ goto Exit; ref[j].offset = temp & 0xFFFFFFL; + FT_TRACE3(( " [%d]:" + " resource_id=0x%04x, offset=0x%08x\n", + j, ref[j].res_id, ref[j].offset )); } - ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); + if (sort_by_res_id) + { + ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, const void*) ) + ft_raccess_sort_ref_by_id ); + + FT_TRACE3(( " -- sort resources by their ids --\n" )); + for ( j = 0; j < *count; ++ j ) { + FT_TRACE3(( " [%d]:" + " resource_id=0x%04x, offset=0x%08x\n", + j, ref[j].res_id, ref[j].offset )); + } + } if ( FT_NEW_ARRAY( offsets_internal, *count ) ) goto Exit; @@ -374,7 +403,7 @@ errors[i] = FT_Err_Ok; if ( errors[i] ) - continue ; + continue; errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, stream, base_name, @@ -695,9 +724,9 @@ FT_UShort n_of_entries; int i; - FT_UInt32 entry_id, entry_offset, entry_length = 0; + FT_Int32 entry_id, entry_offset, entry_length = 0; - const FT_UInt32 resource_fork_entry_id = 0x2; + const FT_Int32 resource_fork_entry_id = 0x2; FT_UNUSED( library ); FT_UNUSED( base_file_name ); @@ -795,7 +824,9 @@ tmp = ft_strrchr( original_name, '/' ); if ( tmp ) { - ft_strncpy( new_name, original_name, tmp - original_name + 1 ); + ft_strncpy( new_name, + original_name, + (size_t)( tmp - original_name + 1 ) ); new_name[tmp - original_name + 1] = '\0'; slash = tmp + 1; } diff --git a/drivers/freetype/src/base/ftsnames.c b/drivers/freetype/src/base/ftsnames.c index 260e91c148..ce7964118c 100644 --- a/drivers/freetype/src/base/ftsnames.c +++ b/drivers/freetype/src/base/ftsnames.c @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/base/ftstream.c b/drivers/freetype/src/base/ftstream.c index d965333daa..bb512a7ccb 100644 --- a/drivers/freetype/src/base/ftstream.c +++ b/drivers/freetype/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2002, 2004-2006, 2008-2011, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,9 +39,9 @@ stream->base = (FT_Byte*) base; stream->size = size; stream->pos = 0; - stream->cursor = 0; - stream->read = 0; - stream->close = 0; + stream->cursor = NULL; + stream->read = NULL; + stream->close = NULL; } @@ -95,11 +95,11 @@ if ( distance < 0 ) return FT_THROW( Invalid_Stream_Operation ); - return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); + return FT_Stream_Seek( stream, stream->pos + (FT_ULong)distance ); } - FT_BASE_DEF( FT_Long ) + FT_BASE_DEF( FT_ULong ) FT_Stream_Pos( FT_Stream stream ) { return stream->pos; @@ -203,8 +203,8 @@ *pbytes = (FT_Byte*)stream->cursor; /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ - stream->cursor = 0; - stream->limit = 0; + stream->cursor = NULL; + stream->limit = NULL; } return error; @@ -226,7 +226,7 @@ FT_FREE( *pbytes ); #endif } - *pbytes = 0; + *pbytes = NULL; } @@ -260,7 +260,9 @@ #ifdef FT_DEBUG_MEMORY /* assume _ft_debug_file and _ft_debug_lineno are already set */ - stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error ); + stream->base = (unsigned char*)ft_mem_qalloc( memory, + (FT_Long)count, + &error ); if ( error ) goto Exit; #else @@ -333,8 +335,8 @@ FT_FREE( stream->base ); #endif } - stream->cursor = 0; - stream->limit = 0; + stream->cursor = NULL; + stream->limit = NULL; } @@ -348,7 +350,7 @@ result = 0; if ( stream->cursor < stream->limit ) - result = *stream->cursor++; + result = (FT_Char)*stream->cursor++; return result; } @@ -357,8 +359,8 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_GetUShort( FT_Stream stream ) { - FT_Byte* p; - FT_Short result; + FT_Byte* p; + FT_UShort result; FT_ASSERT( stream && stream->cursor ); @@ -376,8 +378,8 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_GetUShortLE( FT_Stream stream ) { - FT_Byte* p; - FT_Short result; + FT_Byte* p; + FT_UShort result; FT_ASSERT( stream && stream->cursor ); @@ -396,7 +398,7 @@ FT_Stream_GetUOffset( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -414,7 +416,7 @@ FT_Stream_GetULong( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -432,7 +434,7 @@ FT_Stream_GetULongLE( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -471,7 +473,7 @@ } stream->pos++; - return result; + return (FT_Char)result; Fail: *error = FT_THROW( Invalid_Stream_Operation ); @@ -485,11 +487,11 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_ReadUShort( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_UShort result = 0; FT_ASSERT( stream ); @@ -506,9 +508,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_USHORT( p ); @@ -532,11 +532,11 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_ReadUShortLE( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_UShort result = 0; FT_ASSERT( stream ); @@ -553,9 +553,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_USHORT_LE( p ); @@ -579,11 +577,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadUOffset( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[3]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -600,9 +598,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_UOFF3( p ); @@ -626,11 +622,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadULong( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -647,9 +643,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_ULONG( p ); @@ -673,11 +667,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadULongLE( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -694,9 +688,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_ULONG_LE( p ); @@ -728,9 +720,12 @@ FT_Byte* cursor; - if ( !fields || !stream ) + if ( !fields ) return FT_THROW( Invalid_Argument ); + if ( !stream ) + return FT_THROW( Invalid_Stream_Handle ); + cursor = stream->cursor; error = FT_Err_Ok; @@ -783,7 +778,7 @@ case ft_frame_short_be: case ft_frame_ushort_be: /* read a 2-byte big-endian short */ - value = FT_NEXT_USHORT( cursor) ; + value = FT_NEXT_USHORT( cursor ); sign_shift = 16; break; diff --git a/drivers/freetype/src/base/ftstroke.c b/drivers/freetype/src/base/ftstroke.c index ee61ceca0e..4f3c4937b5 100644 --- a/drivers/freetype/src/base/ftstroke.c +++ b/drivers/freetype/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002-2006, 2008-2011, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,16 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + + + /* declare an extern to access `ft_outline_glyph_class' globally */ + /* allocated in `ftglyph.c', and use the FT_OUTLINE_GLYPH_CLASS_GET */ + /* macro to access it when FT_CONFIG_OPTION_PIC is defined */ +#ifndef FT_CONFIG_OPTION_PIC + FT_CALLBACK_TABLE const FT_Glyph_Class ft_outline_glyph_class; +#endif + /* documentation is in ftstroke.h */ @@ -347,7 +357,7 @@ ft_stroke_border_close( FT_StrokeBorder border, FT_Bool reverse ) { - FT_UInt start = border->start; + FT_UInt start = (FT_UInt)border->start; FT_UInt count = border->num_points; @@ -599,7 +609,7 @@ if ( border->start >= 0 ) ft_stroke_border_close( border, FALSE ); - border->start = border->num_points; + border->start = (FT_Int)border->num_points; border->movable = FALSE; return ft_stroke_border_lineto( border, to, FALSE ); @@ -702,9 +712,10 @@ FT_Outline* outline ) { /* copy point locations */ - FT_ARRAY_COPY( outline->points + outline->n_points, - border->points, - border->num_points ); + if ( border->num_points ) + FT_ARRAY_COPY( outline->points + outline->n_points, + border->points, + border->num_points ); /* copy tags */ { @@ -742,7 +753,7 @@ } } - outline->n_points = (short)( outline->n_points + border->num_points ); + outline->n_points += (short)border->num_points; FT_ASSERT( FT_Outline_Check( outline ) == 0 ); } @@ -795,6 +806,9 @@ if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !astroker ) return FT_THROW( Invalid_Argument ); memory = library->memory; @@ -822,14 +836,17 @@ FT_Stroker_LineJoin line_join, FT_Fixed miter_limit ) { + if ( !stroker ) + return; + stroker->radius = radius; stroker->line_cap = line_cap; stroker->line_join = line_join; stroker->miter_limit = miter_limit; /* ensure miter limit has sensible value */ - if ( stroker->miter_limit < 0x10000 ) - stroker->miter_limit = 0x10000; + if ( stroker->miter_limit < 0x10000L ) + stroker->miter_limit = 0x10000L; /* save line join style: */ /* line join style can be temporarily changed when stroking curves */ @@ -993,7 +1010,9 @@ /* Only intersect borders if between two lineto's and both */ /* lines are long enough (line_length is zero for curves). */ - if ( !border->movable || line_length == 0 ) + /* Also avoid U-turns of nearly 180 degree. */ + if ( !border->movable || line_length == 0 || + theta > 0x59C000 || theta < -0x59C000 ) intersect = FALSE; else { @@ -1002,7 +1021,8 @@ FT_Tan( theta ) ) ); - intersect = FT_BOOL( stroker->line_length >= min_length && + intersect = FT_BOOL( min_length && + stroker->line_length >= min_length && line_length >= min_length ); } @@ -1213,11 +1233,8 @@ goto Exit; /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; + inside_side = ( turn < 0 ); /* process the inside side */ error = ft_stroker_inside( stroker, inside_side, line_length ); @@ -1225,7 +1242,7 @@ goto Exit; /* process the outside side */ - error = ft_stroker_outside( stroker, 1 - inside_side, line_length ); + error = ft_stroker_outside( stroker, !inside_side, line_length ); Exit: return error; @@ -1287,6 +1304,9 @@ FT_Fixed line_length; + if ( !stroker || !to ) + return FT_THROW( Invalid_Argument ); + delta.x = to->x - stroker->center.x; delta.y = to->y - stroker->center.y; @@ -1360,6 +1380,12 @@ FT_Bool first_arc = TRUE; + if ( !stroker || !control || !to ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + /* if all control points are coincident, this is a no-op; */ /* avoid creating a spurious corner */ if ( FT_IS_SMALL( stroker->center.x - control->x ) && @@ -1556,6 +1582,12 @@ FT_Bool first_arc = TRUE; + if ( !stroker || !control1 || !control2 || !to ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + /* if all control points are coincident, this is a no-op; */ /* avoid creating a spurious corner */ if ( FT_IS_SMALL( stroker->center.x - control1->x ) && @@ -1758,6 +1790,9 @@ FT_Vector* to, FT_Bool open ) { + if ( !stroker || !to ) + return FT_THROW( Invalid_Argument ); + /* We cannot process the first point, because there is not enough */ /* information regarding its corner/cap. The latter will be processed */ /* in the `FT_Stroker_EndSubPath' routine. */ @@ -1797,7 +1832,7 @@ FT_ASSERT( left->start >= 0 ); - new_points = left->num_points - left->start; + new_points = (FT_Int)left->num_points - left->start; if ( new_points > 0 ) { error = ft_stroke_border_grow( right, (FT_UInt)new_points ); @@ -1837,8 +1872,8 @@ } } - left->num_points = left->start; - right->num_points += new_points; + left->num_points = (FT_UInt)left->start; + right->num_points += (FT_UInt)new_points; right->movable = FALSE; left->movable = FALSE; @@ -1858,6 +1893,12 @@ FT_Error error = FT_Err_Ok; + if ( !stroker ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + if ( stroker->subpath_open ) { FT_StrokeBorder right = stroker->borders; @@ -1910,11 +1951,8 @@ if ( turn != 0 ) { /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; + inside_side = ( turn < 0 ); error = ft_stroker_inside( stroker, inside_side, @@ -1924,7 +1962,7 @@ /* process the outside side */ error = ft_stroker_outside( stroker, - 1 - inside_side, + !inside_side, stroker->subpath_line_length ); if ( error ) goto Exit; @@ -1983,6 +2021,12 @@ FT_Error error; + if ( !stroker ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + error = ft_stroke_border_get_counts( stroker->borders + 0, &count1, &count2 ); if ( error ) @@ -1997,8 +2041,12 @@ num_contours = count2 + count4; Exit: - *anum_points = num_points; - *anum_contours = num_contours; + if ( anum_points ) + *anum_points = num_points; + + if ( anum_contours ) + *anum_contours = num_contours; + return error; } @@ -2010,6 +2058,9 @@ FT_StrokerBorder border, FT_Outline* outline ) { + if ( !stroker || !outline ) + return; + if ( border == FT_STROKER_BORDER_LEFT || border == FT_STROKER_BORDER_RIGHT ) { @@ -2059,7 +2110,10 @@ FT_Int tag; /* current point's state */ - if ( !outline || !stroker ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !stroker ) return FT_THROW( Invalid_Argument ); FT_Stroker_Rewind( stroker ); @@ -2071,7 +2125,7 @@ FT_UInt last; /* index of last point in contour */ - last = outline->contours[n]; + last = (FT_UInt)outline->contours[n]; limit = outline->points + last; /* skip empty points; we don't stroke these */ @@ -2242,15 +2296,6 @@ } - /* declare an extern to access `ft_outline_glyph_class' globally */ - /* allocated in `ftglyph.c', and use the FT_OUTLINE_GLYPH_CLASS_GET */ - /* macro to access it when FT_CONFIG_OPTION_PIC is defined */ -#ifndef FT_CONFIG_OPTION_PIC - extern const FT_Glyph_Class ft_outline_glyph_class; -#endif -#include "basepic.h" - - /* documentation is in ftstroke.h */ FT_EXPORT_DEF( FT_Error ) @@ -2258,18 +2303,20 @@ FT_Stroker stroker, FT_Bool destroy ) { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Glyph glyph = NULL; + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Glyph glyph = NULL; + + /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */ FT_Library library = stroker->library; FT_UNUSED( library ); - if ( pglyph == NULL ) + if ( !pglyph ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -2293,12 +2340,14 @@ if ( error ) goto Fail; - (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); + FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); FT_Outline_Done( glyph->library, outline ); error = FT_Outline_New( glyph->library, - num_points, num_contours, outline ); + num_points, + (FT_Int)num_contours, + outline ); if ( error ) goto Fail; @@ -2334,18 +2383,20 @@ FT_Bool inside, FT_Bool destroy ) { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Glyph glyph = NULL; + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Glyph glyph = NULL; + + /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */ FT_Library library = stroker->library; FT_UNUSED( library ); - if ( pglyph == NULL ) + if ( !pglyph ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -2379,14 +2430,14 @@ if ( error ) goto Fail; - (void)FT_Stroker_GetBorderCounts( stroker, border, - &num_points, &num_contours ); + FT_Stroker_GetBorderCounts( stroker, border, + &num_points, &num_contours ); FT_Outline_Done( glyph->library, outline ); error = FT_Outline_New( glyph->library, num_points, - num_contours, + (FT_Int)num_contours, outline ); if ( error ) goto Fail; diff --git a/drivers/freetype/src/base/ftsynth.c b/drivers/freetype/src/base/ftsynth.c index 241d37f426..4b66a33c3f 100644 --- a/drivers/freetype/src/base/ftsynth.c +++ b/drivers/freetype/src/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2006, 2010, 2012 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -48,9 +48,14 @@ FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) { FT_Matrix transform; - FT_Outline* outline = &slot->outline; + FT_Outline* outline; + if ( !slot ) + return; + + outline = &slot->outline; + /* only oblique outline glyphs */ if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) return; @@ -84,12 +89,18 @@ FT_EXPORT_DEF( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) { - FT_Library library = slot->library; - FT_Face face = slot->face; + FT_Library library; + FT_Face face; FT_Error error; FT_Pos xstr, ystr; + if ( !slot ) + return; + + library = slot->library; + face = slot->face; + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && slot->format != FT_GLYPH_FORMAT_BITMAP ) return; @@ -100,10 +111,8 @@ ystr = xstr; if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* ignore error */ - (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); - } + FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); + else /* slot->format == FT_GLYPH_FORMAT_BITMAP */ { /* round to full pixels */ @@ -139,10 +148,11 @@ if ( slot->advance.y ) slot->advance.y += ystr; - slot->metrics.width += xstr; - slot->metrics.height += ystr; - slot->metrics.horiAdvance += xstr; - slot->metrics.vertAdvance += ystr; + slot->metrics.width += xstr; + slot->metrics.height += ystr; + slot->metrics.horiAdvance += xstr; + slot->metrics.vertAdvance += ystr; + slot->metrics.horiBearingY += ystr; /* XXX: 16-bit overflow case must be excluded before here */ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) diff --git a/drivers/freetype/src/base/ftsystem.c b/drivers/freetype/src/base/ftsystem.c index 2c6ddac10c..ac1f01c8bc 100644 --- a/drivers/freetype/src/base/ftsystem.c +++ b/drivers/freetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* ANSI-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2002, 2006, 2008-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -71,7 +71,7 @@ { FT_UNUSED( memory ); - return ft_smalloc( size ); + return ft_smalloc( (size_t)size ); } @@ -104,7 +104,7 @@ FT_UNUSED( memory ); FT_UNUSED( cur_size ); - return ft_srealloc( block, new_size ); + return ft_srealloc( block, (size_t)new_size ); } @@ -171,7 +171,7 @@ stream->descriptor.pointer = NULL; stream->size = 0; - stream->base = 0; + stream->base = NULL; } @@ -212,7 +212,7 @@ file = STREAM_FILE( stream ); if ( stream->pos != offset ) - ft_fseek( file, offset, SEEK_SET ); + ft_fseek( file, (long)offset, SEEK_SET ); return (unsigned long)ft_fread( buffer, 1, count, file ); } @@ -232,7 +232,7 @@ stream->descriptor.pointer = NULL; stream->pathname.pointer = (char*)filepathname; - stream->base = 0; + stream->base = NULL; stream->pos = 0; stream->read = NULL; stream->close = NULL; @@ -247,7 +247,7 @@ } ft_fseek( file, 0, SEEK_END ); - stream->size = ft_ftell( file ); + stream->size = (unsigned long)ft_ftell( file ); if ( !stream->size ) { FT_ERROR(( "FT_Stream_Open:" )); @@ -292,7 +292,7 @@ memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) ); if ( memory ) { - memory->user = 0; + memory->user = NULL; memory->alloc = ft_alloc; memory->realloc = ft_realloc; memory->free = ft_free; diff --git a/drivers/freetype/src/base/fttrigon.c b/drivers/freetype/src/base/fttrigon.c index 4ffdcb77f1..7b582c8a3d 100644 --- a/drivers/freetype/src/base/fttrigon.c +++ b/drivers/freetype/src/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001-2005, 2012-2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ #define FT_TRIG_MAX_ITERS 23 - static const FT_Fixed + static const FT_Angle ft_trig_arctan_table[] = { 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, @@ -60,17 +60,21 @@ static FT_Fixed ft_trig_downscale( FT_Fixed val ) { - FT_Fixed s; - FT_Int64 v; + FT_Int s = 1; - s = val; - val = FT_ABS( val ); + if ( val < 0 ) + { + val = -val; + s = -1; + } - v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; - val = (FT_Fixed)( v >> 32 ); + /* 0x40000000 comes from regression analysis between true */ + /* and CORDIC hypotenuse, so it minimizes the error */ + val = (FT_Fixed)( + ( (FT_UInt64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); - return ( s >= 0 ) ? val : -val; + return s < 0 ? -val : val; } #else /* !FT_LONG64 */ @@ -79,38 +83,53 @@ static FT_Fixed ft_trig_downscale( FT_Fixed val ) { - FT_Fixed s; - FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; + FT_Int s = 1; + FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + if ( val < 0 ) + { + val = -val; + s = -1; + } + lo1 = (FT_UInt32)val & 0x0000FFFFU; + hi1 = (FT_UInt32)val >> 16; + lo2 = FT_TRIG_SCALE & 0x0000FFFFU; + hi2 = FT_TRIG_SCALE >> 16; - s = val; - val = FT_ABS( val ); + lo = lo1 * lo2; + i1 = lo1 * hi2; + i2 = lo2 * hi1; + hi = hi1 * hi2; - v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)( val & 0xFFFFL ); + /* Check carry overflow of i1 + i2 */ + i1 += i2; + hi += (FT_UInt32)( i1 < i2 ) << 16; - k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ - k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL ); /* constant */ + hi += i1 >> 16; + i1 = i1 << 16; - hi = k1 * v1; - lo1 = k1 * v2 + k2 * v1; /* can't overflow */ + /* Check carry overflow of i1 + lo */ + lo += i1; + hi += ( lo < i1 ); - lo2 = ( k2 * v2 ) >> 16; - lo3 = FT_MAX( lo1, lo2 ); - lo1 += lo2; + /* 0x40000000 comes from regression analysis between true */ + /* and CORDIC hypotenuse, so it minimizes the error */ - hi += lo1 >> 16; - if ( lo1 < lo3 ) - hi += (FT_UInt32)0x10000UL; + /* Check carry overflow of lo + 0x40000000 */ + lo += 0x40000000UL; + hi += ( lo < 0x40000000UL ); - val = (FT_Fixed)hi; + val = (FT_Fixed)hi; - return ( s >= 0 ) ? val : -val; + return s < 0 ? -val : val; } #endif /* !FT_LONG64 */ + /* undefined and never called for zero vector */ static FT_Int ft_trig_prenorm( FT_Vector* vec ) { @@ -121,7 +140,7 @@ x = vec->x; y = vec->y; - shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) ); + shift = FT_MSB( (FT_UInt32)( FT_ABS( x ) | FT_ABS( y ) ) ); if ( shift <= FT_TRIG_SAFE_MSB ) { @@ -147,7 +166,7 @@ { FT_Int i; FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; + const FT_Angle *arctanptr; x = vec->x; @@ -202,7 +221,7 @@ FT_Angle theta; FT_Int i; FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; + const FT_Angle *arctanptr; x = vec->x; @@ -261,11 +280,12 @@ } } - /* round theta */ + /* round theta to acknowledge its error that mostly comes */ + /* from accumulated rounding errors in the arctan table */ if ( theta >= 0 ) - theta = FT_PAD_ROUND( theta, 32 ); + theta = FT_PAD_ROUND( theta, 16 ); else - theta = -FT_PAD_ROUND( -theta, 32 ); + theta = -FT_PAD_ROUND( -theta, 16 ); vec->x = x; vec->y = theta; @@ -280,11 +300,9 @@ FT_Vector v; - v.x = FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); + FT_Vector_Unit( &v, angle ); - return ( v.x + 0x80L ) >> 8; + return v.x; } @@ -293,7 +311,12 @@ FT_EXPORT_DEF( FT_Fixed ) FT_Sin( FT_Angle angle ) { - return FT_Cos( FT_ANGLE_PI2 - angle ); + FT_Vector v; + + + FT_Vector_Unit( &v, angle ); + + return v.y; } @@ -305,9 +328,7 @@ FT_Vector v; - v.x = FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); + FT_Vector_Unit( &v, angle ); return FT_DivFix( v.y, v.x ); } @@ -340,6 +361,9 @@ FT_Vector_Unit( FT_Vector* vec, FT_Angle angle ) { + if ( !vec ) + return; + vec->x = FT_TRIG_SCALE >> 8; vec->y = 0; ft_trig_pseudo_rotate( vec, angle ); @@ -366,30 +390,32 @@ FT_Vector v; - v.x = vec->x; - v.y = vec->y; + if ( !vec || !angle ) + return; - if ( angle && ( v.x != 0 || v.y != 0 ) ) - { - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_rotate( &v, angle ); - v.x = ft_trig_downscale( v.x ); - v.y = ft_trig_downscale( v.y ); + v = *vec; - if ( shift > 0 ) - { - FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); + if ( v.x == 0 && v.y == 0 ) + return; + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_rotate( &v, angle ); + v.x = ft_trig_downscale( v.x ); + v.y = ft_trig_downscale( v.y ); - vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; - vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; - } - else - { - shift = -shift; - vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); - vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); - } + if ( shift > 0 ) + { + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); + + + vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; + vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; + } + else + { + shift = -shift; + vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); + vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); } } @@ -403,6 +429,9 @@ FT_Vector v; + if ( !vec ) + return 0; + v = *vec; /* handle trivial cases */ @@ -422,7 +451,7 @@ v.x = ft_trig_downscale( v.x ); if ( shift > 0 ) - return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift; + return ( v.x + ( 1L << ( shift - 1 ) ) ) >> shift; return (FT_Fixed)( (FT_UInt32)v.x << -shift ); } @@ -439,6 +468,9 @@ FT_Vector v; + if ( !vec || !length || !angle ) + return; + v = *vec; if ( v.x == 0 && v.y == 0 ) @@ -449,8 +481,8 @@ v.x = ft_trig_downscale( v.x ); - *length = ( shift >= 0 ) ? ( v.x >> shift ) - : (FT_Fixed)( (FT_UInt32)v.x << -shift ); + *length = shift >= 0 ? ( v.x >> shift ) + : (FT_Fixed)( (FT_UInt32)v.x << -shift ); *angle = v.y; } @@ -462,6 +494,9 @@ FT_Fixed length, FT_Angle angle ) { + if ( !vec ) + return; + vec->x = length; vec->y = 0; @@ -478,11 +513,10 @@ FT_Angle delta = angle2 - angle1; - delta %= FT_ANGLE_2PI; - if ( delta < 0 ) + while ( delta <= -FT_ANGLE_PI ) delta += FT_ANGLE_2PI; - if ( delta > FT_ANGLE_PI ) + while ( delta > FT_ANGLE_PI ) delta -= FT_ANGLE_2PI; return delta; diff --git a/drivers/freetype/src/base/fttype1.c b/drivers/freetype/src/base/fttype1.c index c1f9931dbb..5c0fce8686 100644 --- a/drivers/freetype/src/base/fttype1.c +++ b/drivers/freetype/src/base/fttype1.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for PS names support (body). */ /* */ -/* Copyright 2002-2004, 2011 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_SERVICE_H #include FT_SERVICE_POSTSCRIPT_INFO_H @@ -28,19 +29,22 @@ FT_Get_PS_Font_Info( FT_Face face, PS_FontInfoRec* afont_info ) { - FT_Error error = FT_ERR( Invalid_Argument ); + FT_Error error; + FT_Service_PsInfo service; - if ( face ) - { - FT_Service_PsInfo service = NULL; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + if ( !afont_info ) + return FT_THROW( Invalid_Argument ); - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - if ( service && service->ps_get_font_info ) - error = service->ps_get_font_info( face, afont_info ); - } + if ( service && service->ps_get_font_info ) + error = service->ps_get_font_info( face, afont_info ); + else + error = FT_THROW( Invalid_Argument ); return error; } @@ -51,8 +55,8 @@ FT_EXPORT_DEF( FT_Int ) FT_Has_PS_Glyph_Names( FT_Face face ) { - FT_Int result = 0; - FT_Service_PsInfo service = NULL; + FT_Int result = 0; + FT_Service_PsInfo service; if ( face ) @@ -73,19 +77,22 @@ FT_Get_PS_Font_Private( FT_Face face, PS_PrivateRec* afont_private ) { - FT_Error error = FT_ERR( Invalid_Argument ); + FT_Error error; + FT_Service_PsInfo service; - if ( face ) - { - FT_Service_PsInfo service = NULL; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + if ( !afont_private ) + return FT_THROW( Invalid_Argument ); - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - if ( service && service->ps_get_font_private ) - error = service->ps_get_font_private( face, afont_private ); - } + if ( service && service->ps_get_font_private ) + error = service->ps_get_font_private( face, afont_private ); + else + error = FT_THROW( Invalid_Argument ); return error; } diff --git a/drivers/freetype/src/base/ftutil.c b/drivers/freetype/src/base/ftutil.c index 879d027529..fad7d1a5fb 100644 --- a/drivers/freetype/src/base/ftutil.c +++ b/drivers/freetype/src/base/ftutil.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for memory and list management (body). */ /* */ -/* Copyright 2002, 2004-2007, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -180,7 +180,7 @@ FT_Error *p_error ) { FT_Error error; - FT_Pointer p = ft_mem_qalloc( memory, size, &error ); + FT_Pointer p = ft_mem_qalloc( memory, (FT_Long)size, &error ); if ( !error && address ) @@ -245,6 +245,9 @@ FT_ListNode cur; + if ( !list ) + return NULL; + cur = list->head; while ( cur ) { @@ -254,7 +257,7 @@ cur = cur->next; } - return (FT_ListNode)0; + return NULL; } @@ -264,10 +267,15 @@ FT_List_Add( FT_List list, FT_ListNode node ) { - FT_ListNode before = list->tail; + FT_ListNode before; + + + if ( !list || !node ) + return; + before = list->tail; - node->next = 0; + node->next = NULL; node->prev = before; if ( before ) @@ -285,11 +293,16 @@ FT_List_Insert( FT_List list, FT_ListNode node ) { - FT_ListNode after = list->head; + FT_ListNode after; + + + if ( !list || !node ) + return; + after = list->head; node->next = after; - node->prev = 0; + node->prev = NULL; if ( !after ) list->tail = node; @@ -309,6 +322,9 @@ FT_ListNode before, after; + if ( !list || !node ) + return; + before = node->prev; after = node->next; @@ -333,6 +349,9 @@ FT_ListNode before, after; + if ( !list || !node ) + return; + before = node->prev; after = node->next; @@ -347,7 +366,7 @@ else list->tail = before; - node->prev = 0; + node->prev = NULL; node->next = list->head; list->head->prev = node; list->head = node; @@ -357,14 +376,19 @@ /* documentation is in ftlist.h */ FT_EXPORT_DEF( FT_Error ) - FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ) { - FT_ListNode cur = list->head; + FT_ListNode cur; FT_Error error = FT_Err_Ok; + if ( !list || !iterator ) + return FT_THROW( Invalid_Argument ); + + cur = list->head; + while ( cur ) { FT_ListNode next = cur->next; @@ -392,6 +416,9 @@ FT_ListNode cur; + if ( !list || !memory ) + return; + cur = list->head; while ( cur ) { @@ -406,30 +433,8 @@ cur = next; } - list->head = 0; - list->tail = 0; - } - - - FT_BASE_DEF( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ) - { - FT_UInt32 value2; - - - /* - * We simply clear the lowest bit in each iteration. When - * we reach 0, we know that the previous value was our result. - */ - for ( ;; ) - { - value2 = value & (value - 1); /* clear lowest bit */ - if ( value2 == 0 ) - break; - - value = value2; - } - return value; + list->head = NULL; + list->tail = NULL; } diff --git a/drivers/freetype/src/base/ftwinfnt.c b/drivers/freetype/src/base/ftwinfnt.c index 463ae761d8..89e9155098 100644 --- a/drivers/freetype/src/base/ftwinfnt.c +++ b/drivers/freetype/src/base/ftwinfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows FNT specific info (body). */ /* */ -/* Copyright 2003, 2004 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_WINFONTS_H #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_WINFNT_H @@ -32,17 +33,18 @@ FT_Error error; - error = FT_ERR( Invalid_Argument ); + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - if ( face != NULL ) - { - FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); + if ( !header ) + return FT_THROW( Invalid_Argument ); - if ( service != NULL ) - { - error = service->get_header( face, header ); - } - } + FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); + + if ( service ) + error = service->get_header( face, header ); + else + error = FT_THROW( Invalid_Argument ); return error; } diff --git a/drivers/freetype/src/base/ftxf86.c b/drivers/freetype/src/base/ftxf86.c deleted file mode 100644 index a4bf767dfa..0000000000 --- a/drivers/freetype/src/base/ftxf86.c +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftxf86.c */ -/* */ -/* FreeType utility file for X11 support (body). */ -/* */ -/* Copyright 2002, 2003, 2004 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_XFREE86_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_XFREE86_NAME_H - - - /* documentation is in ftxf86.h */ - - FT_EXPORT_DEF( const char* ) - FT_Get_X11_Font_Format( FT_Face face ) - { - const char* result = NULL; - - - if ( face ) - FT_FACE_FIND_SERVICE( face, result, XF86_NAME ); - - return result; - } - - -/* END */ diff --git a/drivers/freetype/src/base/md5.c b/drivers/freetype/src/base/md5.c index 2f01c9302c..b235e17a56 100644 --- a/drivers/freetype/src/base/md5.c +++ b/drivers/freetype/src/base/md5.c @@ -50,7 +50,8 @@ */ #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) #define I(x, y, z) ((y) ^ ((x) | ~(z))) /* @@ -62,12 +63,19 @@ (a) += (b); /* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. + * SET reads 4 input bytes in little-endian byte order and stores them in a + * properly aligned word in host byte order. * - * The check for little-endian architectures that tolerate unaligned - * memory accesses is just an optimization. Nothing will break if it - * doesn't work. + * The check for little-endian architectures that tolerate unaligned memory + * accesses is just an optimization. Nothing will break if it fails to detect + * a suitable architecture. + * + * Unfortunately, this optimization may be a C strict aliasing rules violation + * if the caller's data buffer has effective type that cannot be aliased by + * MD5_u32plus. In practice, this problem may occur if these MD5 routines are + * inlined into a calling function, or with future and dangerously advanced + * link-time optimizations. For the time being, keeping these MD5 routines in + * their own translation unit avoids the problem. */ #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) #define SET(n) \ @@ -86,16 +94,16 @@ #endif /* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. + * This processes one or more 64-byte data blocks, but does NOT update the bit + * counters. There are no alignment requirements. */ -static void *body(MD5_CTX *ctx, void *data, unsigned long size) +static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) { - unsigned char *ptr; + const unsigned char *ptr; MD5_u32plus a, b, c, d; MD5_u32plus saved_a, saved_b, saved_c, saved_d; - ptr = (unsigned char *)data; + ptr = (const unsigned char *)data; a = ctx->a; b = ctx->b; @@ -146,21 +154,21 @@ static void *body(MD5_CTX *ctx, void *data, unsigned long size) /* Round 3 */ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) - STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) - STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) - STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) - STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) - STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) - STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) - STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) - STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) + STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) /* Round 4 */ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) @@ -207,10 +215,10 @@ void MD5_Init(MD5_CTX *ctx) ctx->hi = 0; } -void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) +void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) { MD5_u32plus saved_lo; - unsigned long used, free; + unsigned long used, available; saved_lo = ctx->lo; if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) @@ -220,16 +228,16 @@ void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) used = saved_lo & 0x3f; if (used) { - free = 64 - used; + available = 64 - used; - if (size < free) { + if (size < available) { memcpy(&ctx->buffer[used], data, size); return; } - memcpy(&ctx->buffer[used], data, free); - data = (unsigned char *)data + free; - size -= free; + memcpy(&ctx->buffer[used], data, available); + data = (const unsigned char *)data + available; + size -= available; body(ctx, ctx->buffer, 64); } @@ -241,53 +249,41 @@ void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) memcpy(ctx->buffer, data, size); } +#define OUT(dst, src) \ + (dst)[0] = (unsigned char)(src); \ + (dst)[1] = (unsigned char)((src) >> 8); \ + (dst)[2] = (unsigned char)((src) >> 16); \ + (dst)[3] = (unsigned char)((src) >> 24); + void MD5_Final(unsigned char *result, MD5_CTX *ctx) { - unsigned long used, free; + unsigned long used, available; used = ctx->lo & 0x3f; ctx->buffer[used++] = 0x80; - free = 64 - used; + available = 64 - used; - if (free < 8) { - memset(&ctx->buffer[used], 0, free); + if (available < 8) { + memset(&ctx->buffer[used], 0, available); body(ctx, ctx->buffer, 64); used = 0; - free = 64; + available = 64; } - memset(&ctx->buffer[used], 0, free - 8); + memset(&ctx->buffer[used], 0, available - 8); ctx->lo <<= 3; - ctx->buffer[56] = ctx->lo; - ctx->buffer[57] = ctx->lo >> 8; - ctx->buffer[58] = ctx->lo >> 16; - ctx->buffer[59] = ctx->lo >> 24; - ctx->buffer[60] = ctx->hi; - ctx->buffer[61] = ctx->hi >> 8; - ctx->buffer[62] = ctx->hi >> 16; - ctx->buffer[63] = ctx->hi >> 24; + OUT(&ctx->buffer[56], ctx->lo) + OUT(&ctx->buffer[60], ctx->hi) body(ctx, ctx->buffer, 64); - result[0] = ctx->a; - result[1] = ctx->a >> 8; - result[2] = ctx->a >> 16; - result[3] = ctx->a >> 24; - result[4] = ctx->b; - result[5] = ctx->b >> 8; - result[6] = ctx->b >> 16; - result[7] = ctx->b >> 24; - result[8] = ctx->c; - result[9] = ctx->c >> 8; - result[10] = ctx->c >> 16; - result[11] = ctx->c >> 24; - result[12] = ctx->d; - result[13] = ctx->d >> 8; - result[14] = ctx->d >> 16; - result[15] = ctx->d >> 24; + OUT(&result[0], ctx->a) + OUT(&result[4], ctx->b) + OUT(&result[8], ctx->c) + OUT(&result[12], ctx->d) memset(ctx, 0, sizeof(*ctx)); } diff --git a/drivers/freetype/src/base/md5.h b/drivers/freetype/src/base/md5.h index f1a6857640..2da44bf355 100644 --- a/drivers/freetype/src/base/md5.h +++ b/drivers/freetype/src/base/md5.h @@ -39,7 +39,7 @@ typedef struct { } MD5_CTX; extern void MD5_Init(MD5_CTX *ctx); -extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size); +extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); #endif diff --git a/drivers/freetype/src/base/rules.mk b/drivers/freetype/src/base/rules.mk index e932191157..aa424c5463 100644 --- a/drivers/freetype/src/base/rules.mk +++ b/drivers/freetype/src/base/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002-2009, 2013 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -19,11 +19,14 @@ # BASE_OBJ_S: The single-object base layer. # BASE_OBJ_M: A list of all objects for a multiple-objects build. # BASE_EXT_OBJ: A list of base layer extensions, i.e., components found -# in `freetype/src/base' which are not compiled within the -# base layer proper. +# in `src/base' which are not compiled within the base +# layer proper. -BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) +BASE_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(BASE_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Base layer sources @@ -33,12 +36,15 @@ BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) # All files listed here should be included in `ftbase.c' (for a `single' # build). # -BASE_SRC := $(BASE_DIR)/ftadvanc.c \ +BASE_SRC := $(BASE_DIR)/basepic.c \ + $(BASE_DIR)/ftadvanc.c \ $(BASE_DIR)/ftcalc.c \ $(BASE_DIR)/ftdbgmem.c \ $(BASE_DIR)/ftgloadr.c \ + $(BASE_DIR)/fthash.c \ $(BASE_DIR)/ftobjs.c \ $(BASE_DIR)/ftoutln.c \ + $(BASE_DIR)/ftpic.c \ $(BASE_DIR)/ftrfork.c \ $(BASE_DIR)/ftsnames.c \ $(BASE_DIR)/ftstream.c \ @@ -51,8 +57,9 @@ ifneq ($(ftmac_c),) endif # for simplicity, we also handle `md5.c' (which gets included by `ftobjs.h') -BASE_H := $(BASE_DIR)/ftbase.h \ - $(BASE_DIR)/md5.c \ +BASE_H := $(BASE_DIR)/basepic.h \ + $(BASE_DIR)/ftbase.h \ + $(BASE_DIR)/md5.c \ $(BASE_DIR)/md5.h # Base layer `extensions' sources diff --git a/drivers/freetype/src/bdf/Jamfile b/drivers/freetype/src/bdf/Jamfile index da23ccd0ad..2f0147bbba 100644 --- a/drivers/freetype/src/bdf/Jamfile +++ b/drivers/freetype/src/bdf/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/bdf Jamfile # -# Copyright 2002 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,9 @@ SubDir FT2_TOP $(FT2_SRC_DIR) bdf ; if $(FT2_MULTI) { - _sources = bdfdrivr bdflib ; + _sources = bdfdrivr + bdflib + ; } else { diff --git a/drivers/freetype/src/bdf/bdf.h b/drivers/freetype/src/bdf/bdf.h index d11be6f147..9012727c7e 100644 --- a/drivers/freetype/src/bdf/bdf.h +++ b/drivers/freetype/src/bdf/bdf.h @@ -22,8 +22,8 @@ */ -#ifndef __BDF_H__ -#define __BDF_H__ +#ifndef BDF_H_ +#define BDF_H_ /* @@ -33,6 +33,7 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_HASH_H FT_BEGIN_HEADER @@ -40,12 +41,12 @@ FT_BEGIN_HEADER /* Imported from bdfP.h */ -#define _bdf_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] & ( 1 << ( (e) & 31 ) ) ) -#define _bdf_set_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] |= ( 1 << ( (e) & 31 ) ) ) -#define _bdf_clear_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] &= ~( 1 << ( (e) & 31 ) ) ) +#define _bdf_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] & ( 1UL << ( (e) & 31 ) ) ) +#define _bdf_set_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] |= ( 1UL << ( (e) & 31 ) ) ) +#define _bdf_clear_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] &= ~( 1UL << ( (e) & 31 ) ) ) /* end of bdfP.h */ @@ -157,24 +158,6 @@ FT_BEGIN_HEADER } bdf_glyph_t; - typedef struct _hashnode_ - { - const char* key; - size_t data; - - } _hashnode, *hashnode; - - - typedef struct hashtable_ - { - int limit; - int size; - int used; - hashnode* table; - - } hashtable; - - typedef struct bdf_glyphlist_t_ { unsigned short pad; /* Pad to 4-byte boundary. */ @@ -194,7 +177,7 @@ FT_BEGIN_HEADER char* name; /* Name of the font. */ bdf_bbx_t bbx; /* Font bounding box. */ - long point_size; /* Point size of the font. */ + unsigned long point_size; /* Point size of the font. */ unsigned long resolution_x; /* Font horizontal resolution. */ unsigned long resolution_y; /* Font vertical resolution. */ @@ -238,7 +221,7 @@ FT_BEGIN_HEADER bdf_property_t* user_props; unsigned long nuser_props; - hashtable proptbl; + FT_HashRec proptbl; } bdf_font_t; @@ -291,7 +274,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __BDF_H__ */ +#endif /* BDF_H_ */ /* END */ diff --git a/drivers/freetype/src/bdf/bdfdrivr.c b/drivers/freetype/src/bdf/bdfdrivr.c index 0ea0a5ea5e..a381cf68f5 100644 --- a/drivers/freetype/src/bdf/bdfdrivr.c +++ b/drivers/freetype/src/bdf/bdfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for bdf files - Copyright (C) 2001-2008, 2011, 2013 by + Copyright (C) 2001-2008, 2011, 2013, 2014 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -33,7 +33,7 @@ THE SOFTWARE. #include FT_TRUETYPE_IDS_H #include FT_SERVICE_BDF_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include "bdf.h" #include "bdfdrivr.h" @@ -106,7 +106,7 @@ THE SOFTWARE. mid = ( min + max ) >> 1; - code = encodings[mid].enc; + code = (FT_ULong)encodings[mid].enc; if ( charcode == code ) { @@ -146,7 +146,7 @@ THE SOFTWARE. mid = ( min + max ) >> 1; - code = encodings[mid].enc; + code = (FT_ULong)encodings[mid].enc; if ( charcode == code ) { @@ -165,7 +165,7 @@ THE SOFTWARE. charcode = 0; if ( min < cmap->num_encodings ) { - charcode = encodings[min].enc; + charcode = (FT_ULong)encodings[min].enc; result = encodings[min].glyph + 1; } @@ -182,7 +182,7 @@ THE SOFTWARE. } - FT_CALLBACK_TABLE_DEF + static const FT_CMap_ClassRec bdf_cmap_class = { sizeof ( BDF_CMapRec ), @@ -243,8 +243,6 @@ THE SOFTWARE. !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) strings[0] = (char *)(prop->value.atom); - len = 0; - for ( len = 0, nn = 0; nn < 4; nn++ ) { lengths[nn] = 0; @@ -351,7 +349,6 @@ THE SOFTWARE. FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_TRACE2(( "BDF driver\n" )); @@ -375,6 +372,20 @@ THE SOFTWARE. /* we have a bdf font: let's construct the face object */ face->bdffont = font; + + /* BDF could not have multiple face in single font file. + * XXX: non-zero face_index is already invalid argument, but + * Type1, Type42 driver has a convention to return + * an invalid argument error when the font could be + * opened by the specified driver. + */ + if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) + { + FT_ERROR(( "BDF_Face_Init: invalid face index\n" )); + BDF_Face_Done( bdfface ); + return FT_THROW( Invalid_Argument ); + } + { bdf_property_t* prop = NULL; @@ -388,9 +399,10 @@ THE SOFTWARE. bdfface->num_faces = 1; bdfface->face_index = 0; - bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_FAST_GLYPHS; + + bdfface->face_flags |= FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; prop = bdf_get_font_property( font, "SPACING" ); if ( prop && prop->format == BDF_ATOM && @@ -409,14 +421,14 @@ THE SOFTWARE. goto Exit; } else - bdfface->family_name = 0; + bdfface->family_name = NULL; if ( ( error = bdf_interpret_style( face ) ) != 0 ) goto Exit; /* the number of glyphs (with one slot for the undefined glyph */ /* at position 0 and all unencoded glyphs) */ - bdfface->num_glyphs = font->glyphs_size + 1; + bdfface->num_glyphs = (FT_Long)( font->glyphs_size + 1 ); bdfface->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) ) @@ -483,7 +495,7 @@ THE SOFTWARE. { (face->en_table[n]).enc = cur[n].encoding; FT_TRACE4(( " idx %d, val 0x%lX\n", n, cur[n].encoding )); - (face->en_table[n]).glyph = (FT_Short)n; + (face->en_table[n]).glyph = (FT_UShort)n; if ( cur[n].encoding == font->default_char ) { @@ -498,7 +510,7 @@ THE SOFTWARE. /* charmaps */ { - bdf_property_t *charset_registry = 0, *charset_encoding = 0; + bdf_property_t *charset_registry, *charset_encoding; FT_Bool unicode_charmap = 0; @@ -604,9 +616,9 @@ THE SOFTWARE. FT_Select_Metrics( size->face, strike_index ); - size->metrics.ascender = bdffont->font_ascent << 6; - size->metrics.descender = -bdffont->font_descent << 6; - size->metrics.max_advance = bdffont->bbx.width << 6; + size->metrics.ascender = bdffont->font_ascent * 64; + size->metrics.descender = -bdffont->font_descent * 64; + size->metrics.max_advance = bdffont->bbx.width * 64; return FT_Err_Ok; } @@ -668,12 +680,20 @@ THE SOFTWARE. FT_UNUSED( load_flags ); - if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + if ( !face ) + { + error = FT_THROW( Invalid_Face_Handle ); + goto Exit; + } + + if ( glyph_index >= (FT_UInt)face->num_glyphs ) { error = FT_THROW( Invalid_Argument ); goto Exit; } + FT_TRACE1(( "BDF_Glyph_Load: glyph index %d\n", glyph_index )); + /* index 0 is the undefined glyph */ if ( glyph_index == 0 ) glyph_index = bdf->default_glyph; @@ -715,18 +735,18 @@ THE SOFTWARE. slot->bitmap_left = glyph.bbx.x_offset; slot->bitmap_top = glyph.bbx.ascent; - slot->metrics.horiAdvance = glyph.dwidth << 6; - slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; - slot->metrics.horiBearingY = glyph.bbx.ascent << 6; - slot->metrics.width = bitmap->width << 6; - slot->metrics.height = bitmap->rows << 6; + slot->metrics.horiAdvance = (FT_Pos)( glyph.dwidth * 64 ); + slot->metrics.horiBearingX = (FT_Pos)( glyph.bbx.x_offset * 64 ); + slot->metrics.horiBearingY = (FT_Pos)( glyph.bbx.ascent * 64 ); + slot->metrics.width = (FT_Pos)( bitmap->width * 64 ); + slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); /* * XXX DWIDTH1 and VVECTOR should be parsed and * used here, provided such fonts do exist. */ ft_synthesize_vertical_metrics( &slot->metrics, - bdf->bdffont->bbx.height << 6 ); + bdf->bdffont->bbx.height * 64 ); Exit: return error; @@ -804,8 +824,8 @@ THE SOFTWARE. static const FT_Service_BDFRec bdf_service_bdf = { - (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, - (FT_BDF_GetPropertyFunc) bdf_get_bdf_property + (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) bdf_get_bdf_property /* get_property */ }; @@ -817,8 +837,8 @@ THE SOFTWARE. static const FT_ServiceDescRec bdf_services[] = { - { FT_SERVICE_ID_BDF, &bdf_service_bdf }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF }, + { FT_SERVICE_ID_BDF, &bdf_service_bdf }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_BDF }, { NULL, NULL } }; @@ -846,32 +866,32 @@ THE SOFTWARE. 0x10000L, 0x20000L, - 0, + 0, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - bdf_driver_requester + 0, /* FT_Module_Constructor module_init */ + 0, /* FT_Module_Destructor module_done */ + bdf_driver_requester /* FT_Module_Requester get_interface */ }, sizeof ( BDF_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - BDF_Face_Init, - BDF_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + BDF_Face_Init, /* FT_Face_InitFunc init_face */ + BDF_Face_Done, /* FT_Face_DoneFunc done_face */ + 0, /* FT_Size_InitFunc init_size */ + 0, /* FT_Size_DoneFunc done_size */ + 0, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - BDF_Glyph_Load, + BDF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - BDF_Size_Request, - BDF_Size_Select + BDF_Size_Request, /* FT_Size_RequestFunc request_size */ + BDF_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/src/bdf/bdfdrivr.h b/drivers/freetype/src/bdf/bdfdrivr.h index ca0dae50d2..94550818c1 100644 --- a/drivers/freetype/src/bdf/bdfdrivr.h +++ b/drivers/freetype/src/bdf/bdfdrivr.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __BDFDRIVR_H__ -#define __BDFDRIVR_H__ +#ifndef BDFDRIVR_H_ +#define BDFDRIVR_H_ #include <ft2build.h> #include FT_INTERNAL_DRIVER_H @@ -43,7 +43,7 @@ FT_BEGIN_HEADER typedef struct BDF_encoding_el_ { - FT_ULong enc; + FT_Long enc; FT_UShort glyph; } BDF_encoding_el; @@ -74,7 +74,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __BDFDRIVR_H__ */ +#endif /* BDFDRIVR_H_ */ /* END */ diff --git a/drivers/freetype/src/bdf/bdferror.h b/drivers/freetype/src/bdf/bdferror.h index ea545aca06..b462c7d3b5 100644 --- a/drivers/freetype/src/bdf/bdferror.h +++ b/drivers/freetype/src/bdf/bdferror.h @@ -26,12 +26,12 @@ /* */ /*************************************************************************/ -#ifndef __BDFERROR_H__ -#define __BDFERROR_H__ +#ifndef BDFERROR_H_ +#define BDFERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX BDF_Err_ @@ -39,7 +39,7 @@ #include FT_ERRORS_H -#endif /* __BDFERROR_H__ */ +#endif /* BDFERROR_H_ */ /* END */ diff --git a/drivers/freetype/src/bdf/bdflib.c b/drivers/freetype/src/bdf/bdflib.c index 0b8412d9eb..e1dce954ff 100644 --- a/drivers/freetype/src/bdf/bdflib.c +++ b/drivers/freetype/src/bdf/bdflib.c @@ -1,6 +1,6 @@ /* * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001-2013 + * Copyright 2001-2014 * Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a @@ -169,6 +169,18 @@ sizeof ( _bdf_properties[0] ); + /* An auxiliary macro to parse properties, to be used in conditionals. */ + /* It behaves like `strncmp' but also tests the following character */ + /* whether it is a whitespace or NULL. */ + /* `property' is a constant string of length `n' to compare with. */ +#define _bdf_strncmp( name, property, n ) \ + ( ft_strncmp( name, property, n ) || \ + !( name[n] == ' ' || \ + name[n] == '\0' || \ + name[n] == '\n' || \ + name[n] == '\r' || \ + name[n] == '\t' ) ) + /* Auto correction messages. */ #define ACMSG1 "FONT_ASCENT property missing. " \ "Added `FONT_ASCENT %hd'.\n" @@ -189,6 +201,7 @@ #define ACMSG14 "Glyph %ld extra columns removed.\n" #define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" #define ACMSG16 "Glyph %ld missing columns padded with zero bits.\n" +#define ACMSG17 "Adjusting number of glyphs to %ld.\n" /* Error messages. */ #define ERRMSG1 "[line %ld] Missing `%s' line.\n" @@ -206,164 +219,6 @@ #define DBGMSG2 " (0x%lX)\n" - /*************************************************************************/ - /* */ - /* Hash table utilities for the properties. */ - /* */ - /*************************************************************************/ - - /* XXX: Replace this with FreeType's hash functions */ - - -#define INITIAL_HT_SIZE 241 - - typedef void - (*hash_free_func)( hashnode node ); - - static hashnode* - hash_bucket( const char* key, - hashtable* ht ) - { - const char* kp = key; - unsigned long res = 0; - hashnode* bp = ht->table, *ndp; - - - /* Mocklisp hash function. */ - while ( *kp ) - res = ( res << 5 ) - res + *kp++; - - ndp = bp + ( res % ht->size ); - while ( *ndp ) - { - kp = (*ndp)->key; - if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 ) - break; - ndp--; - if ( ndp < bp ) - ndp = bp + ( ht->size - 1 ); - } - - return ndp; - } - - - static FT_Error - hash_rehash( hashtable* ht, - FT_Memory memory ) - { - hashnode* obp = ht->table, *bp, *nbp; - int i, sz = ht->size; - FT_Error error = FT_Err_Ok; - - - ht->size <<= 1; - ht->limit = ht->size / 3; - - if ( FT_NEW_ARRAY( ht->table, ht->size ) ) - goto Exit; - - for ( i = 0, bp = obp; i < sz; i++, bp++ ) - { - if ( *bp ) - { - nbp = hash_bucket( (*bp)->key, ht ); - *nbp = *bp; - } - } - FT_FREE( obp ); - - Exit: - return error; - } - - - static FT_Error - hash_init( hashtable* ht, - FT_Memory memory ) - { - int sz = INITIAL_HT_SIZE; - FT_Error error = FT_Err_Ok; - - - ht->size = sz; - ht->limit = sz / 3; - ht->used = 0; - - if ( FT_NEW_ARRAY( ht->table, sz ) ) - goto Exit; - - Exit: - return error; - } - - - static void - hash_free( hashtable* ht, - FT_Memory memory ) - { - if ( ht != 0 ) - { - int i, sz = ht->size; - hashnode* bp = ht->table; - - - for ( i = 0; i < sz; i++, bp++ ) - FT_FREE( *bp ); - - FT_FREE( ht->table ); - } - } - - - static FT_Error - hash_insert( char* key, - size_t data, - hashtable* ht, - FT_Memory memory ) - { - hashnode nn; - hashnode* bp = hash_bucket( key, ht ); - FT_Error error = FT_Err_Ok; - - - nn = *bp; - if ( !nn ) - { - if ( FT_NEW( nn ) ) - goto Exit; - *bp = nn; - - nn->key = key; - nn->data = data; - - if ( ht->used >= ht->limit ) - { - error = hash_rehash( ht, memory ); - if ( error ) - goto Exit; - } - ht->used++; - } - else - nn->data = data; - - Exit: - return error; - } - - - static hashnode - hash_lookup( const char* key, - hashtable* ht ) - { - hashnode *np = hash_bucket( key, ht ); - - - return *np; - } - - /*************************************************************************/ /* */ /* Utility types and functions. */ @@ -420,6 +275,7 @@ _bdf_list_t list; FT_Memory memory; + unsigned long size; /* the stream size */ } _bdf_parse_t; @@ -558,10 +414,11 @@ char* line, unsigned long linelen ) { - int mult, final_empty; - char *sp, *ep, *end; - char seps[32]; - FT_Error error = FT_Err_Ok; + unsigned long final_empty; + int mult; + char *sp, *ep, *end; + char seps[32]; + FT_Error error = FT_Err_Ok; /* Initialize the list. */ @@ -670,7 +527,7 @@ unsigned long lineno, buf_size; int refill, hold, to_skip; ptrdiff_t bytes, start, end, cursor, avail; - char* buf = 0; + char* buf = NULL; FT_Memory memory = stream->memory; FT_Error error = FT_Err_Ok; @@ -691,7 +548,6 @@ lineno = 1; buf[0] = 0; start = 0; - end = 0; avail = 0; cursor = 0; refill = 1; @@ -704,7 +560,7 @@ { bytes = (ptrdiff_t)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, - (FT_ULong)( buf_size - cursor ) ); + buf_size - (unsigned long)cursor ); avail = cursor + bytes; cursor = 0; refill = 0; @@ -749,7 +605,7 @@ if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) goto Exit; - cursor = buf_size; + cursor = (ptrdiff_t)buf_size; buf_size = new_size; } else @@ -770,8 +626,8 @@ hold = buf[end]; buf[end] = 0; - /* XXX: Use encoding independent value for 0x1a */ - if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) + /* XXX: Use encoding independent value for 0x1A */ + if ( buf[start] != '#' && buf[start] != 0x1A && end > start ) { error = (*cb)( buf + start, (unsigned long)( end - start ), lineno, (void*)&cb, client_data ); @@ -812,25 +668,17 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const unsigned char odigits[32] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - static const unsigned char ddigits[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -838,88 +686,40 @@ static const unsigned char hdigits[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, - 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, + 0x7E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; - /* Routine to convert an ASCII string into an unsigned long integer. */ + /* Routine to convert a decimal ASCII string to an unsigned long integer. */ static unsigned long - _bdf_atoul( char* s, - char** end, - int base ) + _bdf_atoul( char* s ) { - unsigned long v; - const unsigned char* dmap; + unsigned long v; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = v * base + a2i[(int)*s]; - - if ( end != 0 ) - *end = s; + for ( v = 0; sbitset( ddigits, *s ); s++ ) + v = v * 10 + a2i[(int)*s]; return v; } - /* Routine to convert an ASCII string into an signed long integer. */ + /* Routine to convert a decimal ASCII string to a signed long integer. */ static long - _bdf_atol( char* s, - char** end, - int base ) + _bdf_atol( char* s ) { - long v, neg; - const unsigned char* dmap; + long v, neg; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - /* Check for a minus sign. */ neg = 0; if ( *s == '-' ) @@ -928,53 +728,40 @@ neg = 1; } - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } + for ( v = 0; sbitset( ddigits, *s ); s++ ) + v = v * 10 + a2i[(int)*s]; - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = v * base + a2i[(int)*s]; + return ( !neg ) ? v : -v; + } - if ( end != 0 ) - *end = s; - return ( !neg ) ? v : -v; + /* Routine to convert a decimal ASCII string to an unsigned short integer. */ + static unsigned short + _bdf_atous( char* s ) + { + unsigned short v; + + + if ( s == 0 || *s == 0 ) + return 0; + + for ( v = 0; sbitset( ddigits, *s ); s++ ) + v = (unsigned short)( v * 10 + a2i[(int)*s] ); + + return v; } - /* Routine to convert an ASCII string into an signed short integer. */ + /* Routine to convert a decimal ASCII string to a signed short integer. */ static short - _bdf_atos( char* s, - char** end, - int base ) + _bdf_atos( char* s ) { - short v, neg; - const unsigned char* dmap; + short v, neg; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - /* Check for a minus. */ neg = 0; if ( *s == '-' ) @@ -983,20 +770,8 @@ neg = 1; } - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = (short)( v * base + a2i[(int)*s] ); - - if ( end != 0 ) - *end = s; + for ( v = 0; sbitset( ddigits, *s ); s++ ) + v = (short)( v * 10 + a2i[(int)*s] ); return (short)( ( !neg ) ? v : -v ); } @@ -1037,7 +812,7 @@ /* First check whether the property has */ /* already been added or not. If it has, then */ /* simply ignore it. */ - if ( hash_lookup( name, &(font->proptbl) ) ) + if ( ft_hash_str_lookup( name, &(font->proptbl) ) ) goto Exit; if ( FT_RENEW_ARRAY( font->user_props, @@ -1062,7 +837,7 @@ n = _num_bdf_properties + font->nuser_props; - error = hash_insert( p->name, n, &(font->proptbl), memory ); + error = ft_hash_str_insert( p->name, n, &(font->proptbl), memory ); if ( error ) goto Exit; @@ -1073,25 +848,23 @@ } - FT_LOCAL_DEF( bdf_property_t * ) + FT_LOCAL_DEF( bdf_property_t* ) bdf_get_property( char* name, bdf_font_t* font ) { - hashnode hn; - size_t propid; + size_t* propid; if ( name == 0 || *name == 0 ) return 0; - if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) + if ( ( propid = ft_hash_str_lookup( name, &(font->proptbl) ) ) == NULL ) return 0; - propid = hn->data; - if ( propid >= _num_bdf_properties ) - return font->user_props + ( propid - _num_bdf_properties ); + if ( *propid >= _num_bdf_properties ) + return font->user_props + ( *propid - _num_bdf_properties ); - return (bdf_property_t*)_bdf_properties + propid; + return (bdf_property_t*)_bdf_properties + *propid; } @@ -1104,30 +877,30 @@ /* Parse flags. */ -#define _BDF_START 0x0001 -#define _BDF_FONT_NAME 0x0002 -#define _BDF_SIZE 0x0004 -#define _BDF_FONT_BBX 0x0008 -#define _BDF_PROPS 0x0010 -#define _BDF_GLYPHS 0x0020 -#define _BDF_GLYPH 0x0040 -#define _BDF_ENCODING 0x0080 -#define _BDF_SWIDTH 0x0100 -#define _BDF_DWIDTH 0x0200 -#define _BDF_BBX 0x0400 -#define _BDF_BITMAP 0x0800 +#define BDF_START_ 0x0001U +#define BDF_FONT_NAME_ 0x0002U +#define BDF_SIZE_ 0x0004U +#define BDF_FONT_BBX_ 0x0008U +#define BDF_PROPS_ 0x0010U +#define BDF_GLYPHS_ 0x0020U +#define BDF_GLYPH_ 0x0040U +#define BDF_ENCODING_ 0x0080U +#define BDF_SWIDTH_ 0x0100U +#define BDF_DWIDTH_ 0x0200U +#define BDF_BBX_ 0x0400U +#define BDF_BITMAP_ 0x0800U -#define _BDF_SWIDTH_ADJ 0x1000 +#define BDF_SWIDTH_ADJ_ 0x1000U -#define _BDF_GLYPH_BITS ( _BDF_GLYPH | \ - _BDF_ENCODING | \ - _BDF_SWIDTH | \ - _BDF_DWIDTH | \ - _BDF_BBX | \ - _BDF_BITMAP ) +#define BDF_GLYPH_BITS_ ( BDF_GLYPH_ | \ + BDF_ENCODING_ | \ + BDF_SWIDTH_ | \ + BDF_DWIDTH_ | \ + BDF_BBX_ | \ + BDF_BITMAP_ ) -#define _BDF_GLYPH_WIDTH_CHECK 0x40000000UL -#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000UL +#define BDF_GLYPH_WIDTH_CHECK_ 0x40000000UL +#define BDF_GLYPH_HEIGHT_CHECK_ 0x80000000UL static FT_Error @@ -1299,8 +1072,7 @@ char* value, unsigned long lineno ) { - size_t propid; - hashnode hn; + size_t* propid; bdf_property_t *prop, *fp; FT_Memory memory = font->memory; FT_Error error = FT_Err_Ok; @@ -1309,11 +1081,12 @@ /* First, check whether the property already exists in the font. */ - if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 ) + if ( ( propid = ft_hash_str_lookup( name, + (FT_Hash)font->internal ) ) != NULL ) { /* The property already exists in the font, so simply replace */ /* the value of the property with the current value. */ - fp = font->props + hn->data; + fp = font->props + *propid; switch ( fp->format ) { @@ -1329,11 +1102,11 @@ break; case BDF_INTEGER: - fp->value.l = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value ); break; case BDF_CARDINAL: - fp->value.ul = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value ); break; default: @@ -1345,16 +1118,16 @@ /* See whether this property type exists yet or not. */ /* If not, create it. */ - hn = hash_lookup( name, &(font->proptbl) ); - if ( hn == 0 ) + propid = ft_hash_str_lookup( name, &(font->proptbl) ); + if ( propid == NULL ) { error = bdf_create_property( name, BDF_ATOM, font ); if ( error ) goto Exit; - hn = hash_lookup( name, &(font->proptbl) ); + propid = ft_hash_str_lookup( name, &(font->proptbl) ); } - /* Allocate another property if this is overflow. */ + /* Allocate another property if this is overflowing. */ if ( font->props_used == font->props_size ) { if ( font->props_size == 0 ) @@ -1375,11 +1148,10 @@ font->props_size++; } - propid = hn->data; - if ( propid >= _num_bdf_properties ) - prop = font->user_props + ( propid - _num_bdf_properties ); + if ( *propid >= _num_bdf_properties ) + prop = font->user_props + ( *propid - _num_bdf_properties ); else - prop = (bdf_property_t*)_bdf_properties + propid; + prop = (bdf_property_t*)_bdf_properties + *propid; fp = font->props + font->props_used; @@ -1399,23 +1171,23 @@ break; case BDF_INTEGER: - fp->value.l = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value ); break; case BDF_CARDINAL: - fp->value.ul = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value ); break; } /* If the property happens to be a comment, then it doesn't need */ /* to be added to the internal hash table. */ - if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) + if ( _bdf_strncmp( name, "COMMENT", 7 ) != 0 ) { /* Add the property to the font property table. */ - error = hash_insert( fp->name, - font->props_used, - (hashtable *)font->internal, - memory ); + error = ft_hash_str_insert( fp->name, + font->props_used, + (FT_Hash)font->internal, + memory ); if ( error ) goto Exit; } @@ -1427,13 +1199,13 @@ /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are */ /* present, and the SPACING property should override the default */ /* spacing. */ - if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 ) + if ( _bdf_strncmp( name, "DEFAULT_CHAR", 12 ) == 0 ) font->default_char = fp->value.l; - else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 ) + else if ( _bdf_strncmp( name, "FONT_ASCENT", 11 ) == 0 ) font->font_ascent = fp->value.l; - else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 ) + else if ( _bdf_strncmp( name, "FONT_DESCENT", 12 ) == 0 ) font->font_descent = fp->value.l; - else if ( ft_memcmp( name, "SPACING", 7 ) == 0 ) + else if ( _bdf_strncmp( name, "SPACING", 7 ) == 0 ) { if ( !fp->value.atom ) { @@ -1491,7 +1263,7 @@ memory = font->memory; /* Check for a comment. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 ) { linelen -= 7; @@ -1506,9 +1278,9 @@ } /* The very first thing expected is the number of glyphs. */ - if ( !( p->flags & _BDF_GLYPHS ) ) + if ( !( p->flags & BDF_GLYPHS_ ) ) { - if ( ft_memcmp( line, "CHARS", 5 ) != 0 ) + if ( _bdf_strncmp( line, "CHARS", 5 ) != 0 ) { FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" )); error = FT_THROW( Missing_Chars_Field ); @@ -1518,7 +1290,14 @@ error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1] ); + + /* We need at least 20 bytes per glyph. */ + if ( p->cnt > p->size / 20 ) + { + p->cnt = font->glyphs_size = p->size / 20; + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG17, p->cnt )); + } /* Make sure the number of glyphs is non-zero. */ if ( p->cnt == 0 ) @@ -1536,44 +1315,60 @@ if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) ) goto Exit; - p->flags |= _BDF_GLYPHS; + p->flags |= BDF_GLYPHS_; goto Exit; } /* Check for the ENDFONT field. */ - if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 ) + if ( _bdf_strncmp( line, "ENDFONT", 7 ) == 0 ) { + if ( p->flags & BDF_GLYPH_BITS_ ) + { + /* Missing ENDCHAR field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" )); + error = FT_THROW( Corrupted_Font_Glyphs ); + goto Exit; + } + /* Sort the glyphs by encoding. */ ft_qsort( (char *)font->glyphs, font->glyphs_used, sizeof ( bdf_glyph_t ), by_encoding ); - p->flags &= ~_BDF_START; + p->flags &= ~BDF_START_; goto Exit; } /* Check for the ENDCHAR field. */ - if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 ) + if ( _bdf_strncmp( line, "ENDCHAR", 7 ) == 0 ) { p->glyph_enc = 0; - p->flags &= ~_BDF_GLYPH_BITS; + p->flags &= ~BDF_GLYPH_BITS_; goto Exit; } /* Check whether a glyph is being scanned but should be */ /* ignored because it is an unencoded glyph. */ - if ( ( p->flags & _BDF_GLYPH ) && + if ( ( p->flags & BDF_GLYPH_ ) && p->glyph_enc == -1 && p->opts->keep_unencoded == 0 ) goto Exit; /* Check for the STARTCHAR field. */ - if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 ) + if ( _bdf_strncmp( line, "STARTCHAR", 9 ) == 0 ) { + if ( p->flags & BDF_GLYPH_BITS_ ) + { + /* Missing ENDCHAR field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" )); + error = FT_THROW( Missing_Startchar_Field ); + goto Exit; + } + /* Set the character name in the parse info first until the */ /* encoding can be checked for an unencoded character. */ FT_FREE( p->glyph_name ); @@ -1598,7 +1393,7 @@ FT_MEM_COPY( p->glyph_name, s, slen + 1 ); - p->flags |= _BDF_GLYPH; + p->flags |= BDF_GLYPH_; FT_TRACE4(( DBGMSG1, lineno, s )); @@ -1606,9 +1401,9 @@ } /* Check for the ENCODING field. */ - if ( ft_memcmp( line, "ENCODING", 8 ) == 0 ) + if ( _bdf_strncmp( line, "ENCODING", 8 ) == 0 ) { - if ( !( p->flags & _BDF_GLYPH ) ) + if ( !( p->flags & BDF_GLYPH_ ) ) { /* Missing STARTCHAR field. */ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" )); @@ -1620,7 +1415,7 @@ if ( error ) goto Exit; - p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 ); + p->glyph_enc = _bdf_atol( p->list.field[1] ); /* Normalize negative encoding values. The specification only */ /* allows -1, but we can be more generous here. */ @@ -1629,7 +1424,7 @@ /* Check for alternative encoding format. */ if ( p->glyph_enc == -1 && p->list.used > 2 ) - p->glyph_enc = _bdf_atol( p->list.field[2], 0, 10 ); + p->glyph_enc = _bdf_atol( p->list.field[2] ); if ( p->glyph_enc < -1 ) p->glyph_enc = -1; @@ -1684,7 +1479,7 @@ glyph->encoding = p->glyph_enc; /* Reset the initial glyph info. */ - p->glyph_name = 0; + p->glyph_name = NULL; } else { @@ -1705,21 +1500,26 @@ glyph = font->unencoded + font->unencoded_used; glyph->name = p->glyph_name; - glyph->encoding = font->unencoded_used++; + glyph->encoding = (long)font->unencoded_used++; + + /* Reset the initial glyph info. */ + p->glyph_name = NULL; } else + { /* Free up the glyph name if the unencoded shouldn't be */ /* kept. */ FT_FREE( p->glyph_name ); + } - p->glyph_name = 0; + p->glyph_name = NULL; } /* Clear the flags that might be added when width and height are */ /* checked for consistency. */ - p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK ); + p->flags &= ~( BDF_GLYPH_WIDTH_CHECK_ | BDF_GLYPH_HEIGHT_CHECK_ ); - p->flags |= _BDF_ENCODING; + p->flags |= BDF_ENCODING_; goto Exit; } @@ -1731,16 +1531,16 @@ glyph = font->glyphs + ( font->glyphs_used - 1 ); /* Check whether a bitmap is being constructed. */ - if ( p->flags & _BDF_BITMAP ) + if ( p->flags & BDF_BITMAP_ ) { /* If there are more rows than are specified in the glyph metrics, */ /* ignore the remaining lines. */ if ( p->row >= (unsigned long)glyph->bbx.height ) { - if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) ) + if ( !( p->flags & BDF_GLYPH_HEIGHT_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding )); - p->flags |= _BDF_GLYPH_HEIGHT_CHECK; + p->flags |= BDF_GLYPH_HEIGHT_CHECK_; font->modified = 1; } @@ -1765,10 +1565,10 @@ /* If any line has not enough columns, */ /* indicate they have been padded with zero bits. */ if ( i < nibbles && - !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding )); - p->flags |= _BDF_GLYPH_WIDTH_CHECK; + p->flags |= BDF_GLYPH_WIDTH_CHECK_; font->modified = 1; } @@ -1780,10 +1580,10 @@ /* If any line has extra columns, indicate they have been removed. */ if ( i == nibbles && sbitset( hdigits, line[nibbles] ) && - !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); - p->flags |= _BDF_GLYPH_WIDTH_CHECK; + p->flags |= BDF_GLYPH_WIDTH_CHECK_; font->modified = 1; } @@ -1792,34 +1592,34 @@ } /* Expect the SWIDTH (scalable width) field next. */ - if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 ) + if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); - p->flags |= _BDF_SWIDTH; + glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1] ); + p->flags |= BDF_SWIDTH_; goto Exit; } /* Expect the DWIDTH (scalable width) field next. */ - if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) + if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1] ); - if ( !( p->flags & _BDF_SWIDTH ) ) + if ( !( p->flags & BDF_SWIDTH_ ) ) { /* Missing SWIDTH field. Emit an auto correction message and set */ /* the scalable width from the device width. */ @@ -1831,24 +1631,24 @@ font->resolution_x ) ); } - p->flags |= _BDF_DWIDTH; + p->flags |= BDF_DWIDTH_; goto Exit; } /* Expect the BBX field next. */ - if ( ft_memcmp( line, "BBX", 3 ) == 0 ) + if ( _bdf_strncmp( line, "BBX", 3 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); - glyph->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); - glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); - glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + glyph->bbx.width = _bdf_atous( p->list.field[1] ); + glyph->bbx.height = _bdf_atous( p->list.field[2] ); + glyph->bbx.x_offset = _bdf_atos( p->list.field[3] ); + glyph->bbx.y_offset = _bdf_atos( p->list.field[4] ); /* Generate the ascent and descent of the character. */ glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset ); @@ -1865,7 +1665,7 @@ p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb ); p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb ); - if ( !( p->flags & _BDF_DWIDTH ) ) + if ( !( p->flags & BDF_DWIDTH_ ) ) { /* Missing DWIDTH field. Emit an auto correction message and set */ /* the device width to the glyph width. */ @@ -1894,22 +1694,22 @@ else _bdf_set_glyph_modified( font->nmod, glyph->encoding ); - p->flags |= _BDF_SWIDTH_ADJ; + p->flags |= BDF_SWIDTH_ADJ_; font->modified = 1; } } - p->flags |= _BDF_BBX; + p->flags |= BDF_BBX_; goto Exit; } /* And finally, gather up the bitmap. */ - if ( ft_memcmp( line, "BITMAP", 6 ) == 0 ) + if ( _bdf_strncmp( line, "BITMAP", 6 ) == 0 ) { unsigned long bitmap_size; - if ( !( p->flags & _BDF_BBX ) ) + if ( !( p->flags & BDF_BBX_ ) ) { /* Missing BBX field. */ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" )); @@ -1934,7 +1734,7 @@ goto Exit; p->row = 0; - p->flags |= _BDF_BITMAP; + p->flags |= BDF_BITMAP_; goto Exit; } @@ -1949,7 +1749,7 @@ error = FT_THROW( Missing_Encoding_Field ); Exit: - if ( error && ( p->flags & _BDF_GLYPH ) ) + if ( error && ( p->flags & BDF_GLYPH_ ) ) FT_FREE( p->glyph_name ); return error; @@ -1979,7 +1779,7 @@ p = (_bdf_parse_t *) client_data; /* Check for the end of the properties. */ - if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 ) + if ( _bdf_strncmp( line, "ENDPROPERTIES", 13 ) == 0 ) { /* If the FONT_ASCENT or FONT_DESCENT properties have not been */ /* encountered yet, then make sure they are added as properties and */ @@ -2013,19 +1813,19 @@ p->font->modified = 1; } - p->flags &= ~_BDF_PROPS; + p->flags &= ~BDF_PROPS_; *next = _bdf_parse_glyphs; goto Exit; } /* Ignore the _XFREE86_GLYPH_RANGES properties. */ - if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 ) + if ( _bdf_strncmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 ) goto Exit; /* Handle COMMENT fields and properties in a special way to preserve */ /* the spacing. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 ) { name = value = line; value += 7; @@ -2089,7 +1889,7 @@ /* Check for a comment. This is done to handle those fonts that have */ /* comments before the STARTFONT line for some reason. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 ) { if ( p->opts->keep_comments != 0 && p->font != 0 ) { @@ -2111,11 +1911,11 @@ goto Exit; } - if ( !( p->flags & _BDF_START ) ) + if ( !( p->flags & BDF_START_ ) ) { memory = p->memory; - if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 ) + if ( _bdf_strncmp( line, "STARTFONT", 9 ) != 0 ) { /* we don't emit an error message since this code gets */ /* explicitly caught one level higher */ @@ -2123,7 +1923,7 @@ goto Exit; } - p->flags = _BDF_START; + p->flags = BDF_START_; font = p->font = 0; if ( FT_NEW( font ) ) @@ -2138,22 +1938,22 @@ bdf_property_t* prop; - error = hash_init( &(font->proptbl), memory ); + error = ft_hash_str_init( &(font->proptbl), memory ); if ( error ) goto Exit; for ( i = 0, prop = (bdf_property_t*)_bdf_properties; i < _num_bdf_properties; i++, prop++ ) { - error = hash_insert( prop->name, i, - &(font->proptbl), memory ); + error = ft_hash_str_insert( prop->name, i, + &(font->proptbl), memory ); if ( error ) goto Exit; } } - if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) ) + if ( FT_ALLOC( p->font->internal, sizeof ( FT_HashRec ) ) ) goto Exit; - error = hash_init( (hashtable *)p->font->internal,memory ); + error = ft_hash_str_init( (FT_Hash)p->font->internal, memory ); if ( error ) goto Exit; p->font->spacing = p->opts->font_spacing; @@ -2163,9 +1963,9 @@ } /* Check for the start of the properties. */ - if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 ) + if ( _bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 ) { - if ( !( p->flags & _BDF_FONT_BBX ) ) + if ( !( p->flags & BDF_FONT_BBX_ ) ) { /* Missing the FONTBOUNDINGBOX field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); @@ -2176,8 +1976,18 @@ error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; + /* at this point, `p->font' can't be NULL */ - p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1] ); + /* We need at least 4 bytes per property. */ + if ( p->cnt > p->size / 4 ) + { + p->font->props_size = 0; + + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "STARTPROPERTIES" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) { @@ -2185,16 +1995,16 @@ goto Exit; } - p->flags |= _BDF_PROPS; + p->flags |= BDF_PROPS_; *next = _bdf_parse_properties; goto Exit; } /* Check for the FONTBOUNDINGBOX field. */ - if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) + if ( _bdf_strncmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) { - if ( !( p->flags & _BDF_SIZE ) ) + if ( !( p->flags & BDF_SIZE_ ) ) { /* Missing the SIZE field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" )); @@ -2206,24 +2016,24 @@ if ( error ) goto Exit; - p->font->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); - p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); + p->font->bbx.width = _bdf_atous( p->list.field[1] ); + p->font->bbx.height = _bdf_atous( p->list.field[2] ); - p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); - p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + p->font->bbx.x_offset = _bdf_atos( p->list.field[3] ); + p->font->bbx.y_offset = _bdf_atos( p->list.field[4] ); p->font->bbx.ascent = (short)( p->font->bbx.height + p->font->bbx.y_offset ); p->font->bbx.descent = (short)( -p->font->bbx.y_offset ); - p->flags |= _BDF_FONT_BBX; + p->flags |= BDF_FONT_BBX_; goto Exit; } /* The next thing to check for is the FONT field. */ - if ( ft_memcmp( line, "FONT", 4 ) == 0 ) + if ( _bdf_strncmp( line, "FONT", 4 ) == 0 ) { error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) @@ -2252,15 +2062,15 @@ if ( error ) goto Exit; - p->flags |= _BDF_FONT_NAME; + p->flags |= BDF_FONT_NAME_; goto Exit; } /* Check for the SIZE field. */ - if ( ft_memcmp( line, "SIZE", 4 ) == 0 ) + if ( _bdf_strncmp( line, "SIZE", 4 ) == 0 ) { - if ( !( p->flags & _BDF_FONT_NAME ) ) + if ( !( p->flags & BDF_FONT_NAME_ ) ) { /* Missing the FONT field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" )); @@ -2272,52 +2082,46 @@ if ( error ) goto Exit; - p->font->point_size = _bdf_atoul( p->list.field[1], 0, 10 ); - p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 ); - p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 ); + p->font->point_size = _bdf_atoul( p->list.field[1] ); + p->font->resolution_x = _bdf_atoul( p->list.field[2] ); + p->font->resolution_y = _bdf_atoul( p->list.field[3] ); /* Check for the bits per pixel field. */ if ( p->list.used == 5 ) { - unsigned short bitcount, i, shift; + unsigned short bpp; - p->font->bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 ); + bpp = (unsigned short)_bdf_atos( p->list.field[4] ); - /* Only values 1, 2, 4, 8 are allowed. */ - shift = p->font->bpp; - bitcount = 0; - for ( i = 0; shift > 0; i++ ) - { - if ( shift & 1 ) - bitcount = i; - shift >>= 1; - } - - shift = (short)( ( bitcount > 3 ) ? 8 : ( 1 << bitcount ) ); + /* Only values 1, 2, 4, 8 are allowed for greymap fonts. */ + if ( bpp > 4 ) + p->font->bpp = 8; + else if ( bpp > 2 ) + p->font->bpp = 4; + else if ( bpp > 1 ) + p->font->bpp = 2; + else + p->font->bpp = 1; - if ( p->font->bpp > shift || p->font->bpp != shift ) - { - /* select next higher value */ - p->font->bpp = (unsigned short)( shift << 1 ); + if ( p->font->bpp != bpp ) FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp )); - } } else p->font->bpp = 1; - p->flags |= _BDF_SIZE; + p->flags |= BDF_SIZE_; goto Exit; } /* Check for the CHARS field -- font properties are optional */ - if ( ft_memcmp( line, "CHARS", 5 ) == 0 ) + if ( _bdf_strncmp( line, "CHARS", 5 ) == 0 ) { char nbuf[128]; - if ( !( p->flags & _BDF_FONT_BBX ) ) + if ( !( p->flags & BDF_FONT_BBX_ ) ) { /* Missing the FONTBOUNDINGBOX field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); @@ -2376,8 +2180,8 @@ unsigned long lineno = 0; /* make compiler happy */ _bdf_parse_t *p = NULL; - FT_Memory memory = extmemory; - FT_Error error = FT_Err_Ok; + FT_Memory memory = extmemory; /* needed for FT_NEW */ + FT_Error error = FT_Err_Ok; if ( FT_NEW( p ) ) @@ -2386,6 +2190,7 @@ memory = NULL; p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); p->minlb = 32767; + p->size = stream->size; p->memory = extmemory; /* only during font creation */ _bdf_list_init( &p->list, extmemory ); @@ -2399,7 +2204,6 @@ { /* If the font is not proportional, set the font's monowidth */ /* field to the width of the font bounding box. */ - memory = p->font->memory; if ( p->font->spacing != BDF_PROPORTIONAL ) p->font->monowidth = p->font->bbx.width; @@ -2458,27 +2262,27 @@ p->font->bbx.height = (unsigned short)( p->maxas + p->maxds ); } - if ( p->flags & _BDF_SWIDTH_ADJ ) + if ( p->flags & BDF_SWIDTH_ADJ_ ) FT_TRACE2(( "bdf_load_font: " ACMSG8 )); } } - if ( p->flags & _BDF_START ) + if ( p->flags & BDF_START_ ) { /* The ENDFONT field was never reached or did not exist. */ - if ( !( p->flags & _BDF_GLYPHS ) ) + if ( !( p->flags & BDF_GLYPHS_ ) ) { /* Error happened while parsing header. */ FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); error = FT_THROW( Corrupted_Font_Header ); - goto Exit; + goto Fail; } else { /* Error happened when parsing glyphs. */ FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); error = FT_THROW( Corrupted_Font_Glyphs ); - goto Exit; + goto Fail; } } @@ -2509,6 +2313,7 @@ memory = extmemory; + FT_FREE( p->glyph_name ); FT_FREE( p ); } @@ -2544,7 +2349,7 @@ /* Free up the internal hash table of property names. */ if ( font->internal ) { - hash_free( (hashtable *)font->internal, memory ); + ft_hash_str_free( (FT_Hash)font->internal, memory ); FT_FREE( font->internal ); } @@ -2589,7 +2394,7 @@ FT_FREE( font->overflow.glyphs ); /* bdf_cleanup */ - hash_free( &(font->proptbl), memory ); + ft_hash_str_free( &(font->proptbl), memory ); /* Free up the user defined properties. */ for ( prop = font->user_props, i = 0; @@ -2610,15 +2415,15 @@ bdf_get_font_property( bdf_font_t* font, const char* name ) { - hashnode hn; + size_t* propid; if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) return 0; - hn = hash_lookup( name, (hashtable *)font->internal ); + propid = ft_hash_str_lookup( name, (FT_Hash)font->internal ); - return hn ? ( font->props + hn->data ) : 0; + return propid ? ( font->props + *propid ) : 0; } diff --git a/drivers/freetype/src/bdf/rules.mk b/drivers/freetype/src/bdf/rules.mk index 6ff1614dde..d1dd76b1c3 100644 --- a/drivers/freetype/src/bdf/rules.mk +++ b/drivers/freetype/src/bdf/rules.mk @@ -32,7 +32,10 @@ BDF_DIR := $(SRC_DIR)/bdf -BDF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) +BDF_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # bdf driver sources (i.e., C files) diff --git a/drivers/freetype/src/cache/Jamfile b/drivers/freetype/src/cache/Jamfile index 340cff7742..da6551015b 100644 --- a/drivers/freetype/src/cache/Jamfile +++ b/drivers/freetype/src/cache/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cache Jamfile # -# Copyright 2001, 2003, 2004 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -11,25 +11,19 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cache ; -# The file <freetype/ftcache.h> contains some macro definitions that are -# later used in #include statements related to the cache sub-system. It -# needs to be parsed through a HDRMACRO rule for macro definitions. -# -HDRMACRO [ FT2_SubDir include ftcache.h ] ; - { local _sources ; if $(FT2_MULTI) { - _sources = ftcmru - ftcmanag + _sources = ftcbasic ftccache ftcglyph - ftcsbits ftcimage - ftcbasic + ftcmanag ftccmap + ftcmru + ftcsbits ; } else diff --git a/drivers/freetype/src/cache/ftcache.c b/drivers/freetype/src/cache/ftcache.c index d41e91e5ec..50941df4c4 100644 --- a/drivers/freetype/src/cache/ftcache.c +++ b/drivers/freetype/src/cache/ftcache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType Caching sub-system (body only). */ /* */ -/* Copyright 2000-2001, 2003 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/cache/ftcbasic.c b/drivers/freetype/src/cache/ftcbasic.c index 84d336d5d6..8e6de8c41c 100644 --- a/drivers/freetype/src/cache/ftcbasic.c +++ b/drivers/freetype/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType basic cache interface (body). */ /* */ -/* Copyright 2003-2007, 2009-2011, 2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,8 +45,8 @@ FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ (a)->load_flags == (b)->load_flags ) -#define FTC_BASIC_ATTR_HASH( a ) \ - ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags ) +#define FTC_BASIC_ATTR_HASH( a ) \ + ( FTC_SCALER_HASH( &(a)->scaler ) + 31 * (a)->load_flags ) typedef struct FTC_BasicQueryRec_ @@ -110,10 +110,9 @@ return result; if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs ) - { - FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " )); - FT_TRACE1(( "in this face, truncated\n", face->num_glyphs )); - } + FT_TRACE1(( "ftc_basic_family_get_count:" + " too large number of glyphs in this face, truncated\n", + face->num_glyphs )); if ( !error ) result = (FT_UInt)face->num_glyphs; @@ -139,8 +138,10 @@ FT_Face face = size->face; - error = FT_Load_Glyph( face, gindex, - family->attrs.load_flags | FT_LOAD_RENDER ); + error = FT_Load_Glyph( + face, + gindex, + (FT_Int)family->attrs.load_flags | FT_LOAD_RENDER ); if ( !error ) *aface = face; } @@ -170,7 +171,9 @@ { face = size->face; - error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); + error = FT_Load_Glyph( face, + gindex, + (FT_Int)family->attrs.load_flags ); if ( !error ) { if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || @@ -229,7 +232,7 @@ * */ - FT_CALLBACK_TABLE_DEF + static const FTC_IFamilyClassRec ftc_basic_image_family_class = { { @@ -243,7 +246,7 @@ }; - FT_CALLBACK_TABLE_DEF + static const FTC_GCacheClassRec ftc_basic_image_cache_class = { { @@ -284,10 +287,10 @@ FTC_BasicQueryRec query; FTC_Node node = 0; /* make compiler happy */ FT_Error error; - FT_PtrDist hash; + FT_Offset hash; - /* some argument checks are delayed to FTC_Cache_Lookup */ + /* some argument checks are delayed to `FTC_Cache_Lookup' */ if ( !aglyph ) { error = FT_THROW( Invalid_Argument ); @@ -298,18 +301,15 @@ if ( anode ) *anode = NULL; - { - if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); - } + if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX ) + FT_TRACE1(( "FTC_ImageCache_Lookup:" + " higher bits in load_flags 0x%x are dropped\n", + (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); - query.attrs.scaler.face_id = type->face_id; - query.attrs.scaler.width = type->width; - query.attrs.scaler.height = type->height; - query.attrs.load_flags = (FT_UInt)type->flags; - } + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.load_flags = (FT_UInt)type->flags; query.attrs.scaler.pixel = 1; query.attrs.scaler.x_res = 0; /* make compilers happy */ @@ -360,10 +360,10 @@ FTC_BasicQueryRec query; FTC_Node node = 0; /* make compiler happy */ FT_Error error; - FT_PtrDist hash; + FT_Offset hash; - /* some argument checks are delayed to FTC_Cache_Lookup */ + /* some argument checks are delayed to `FTC_Cache_Lookup' */ if ( !aglyph || !scaler ) { error = FT_THROW( Invalid_Argument ); @@ -374,12 +374,11 @@ if ( anode ) *anode = NULL; - /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */ if ( load_flags > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); - } + FT_TRACE1(( "FTC_ImageCache_LookupScaler:" + " higher bits in load_flags 0x%x are dropped\n", + load_flags & ~((FT_ULong)FT_UINT_MAX) )); query.attrs.scaler = scaler[0]; query.attrs.load_flags = (FT_UInt)load_flags; @@ -415,7 +414,7 @@ * */ - FT_CALLBACK_TABLE_DEF + static const FTC_SFamilyClassRec ftc_basic_sbit_family_class = { { @@ -430,7 +429,7 @@ }; - FT_CALLBACK_TABLE_DEF + static const FTC_GCacheClassRec ftc_basic_sbit_cache_class = { { @@ -471,30 +470,27 @@ FT_Error error; FTC_BasicQueryRec query; FTC_Node node = 0; /* make compiler happy */ - FT_PtrDist hash; + FT_Offset hash; if ( anode ) *anode = NULL; - /* other argument checks delayed to FTC_Cache_Lookup */ + /* other argument checks delayed to `FTC_Cache_Lookup' */ if ( !ansbit ) return FT_THROW( Invalid_Argument ); *ansbit = NULL; - { - if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); - } + if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX ) + FT_TRACE1(( "FTC_ImageCache_Lookup:" + " higher bits in load_flags 0x%x are dropped\n", + (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); - query.attrs.scaler.face_id = type->face_id; - query.attrs.scaler.width = type->width; - query.attrs.scaler.height = type->height; - query.attrs.load_flags = (FT_UInt)type->flags; - } + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.load_flags = (FT_UInt)type->flags; query.attrs.scaler.pixel = 1; query.attrs.scaler.x_res = 0; /* make compilers happy */ @@ -549,24 +545,23 @@ FT_Error error; FTC_BasicQueryRec query; FTC_Node node = 0; /* make compiler happy */ - FT_PtrDist hash; + FT_Offset hash; if ( anode ) *anode = NULL; - /* other argument checks delayed to FTC_Cache_Lookup */ + /* other argument checks delayed to `FTC_Cache_Lookup' */ if ( !ansbit || !scaler ) return FT_THROW( Invalid_Argument ); *ansbit = NULL; - /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */ if ( load_flags > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); - } + FT_TRACE1(( "FTC_ImageCache_LookupScaler:" + " higher bits in load_flags 0x%x are dropped\n", + load_flags & ~((FT_ULong)FT_UINT_MAX) )); query.attrs.scaler = scaler[0]; query.attrs.load_flags = (FT_UInt)load_flags; diff --git a/drivers/freetype/src/cache/ftccache.c b/drivers/freetype/src/cache/ftccache.c index f20dd4502c..3b1a4bc7e4 100644 --- a/drivers/freetype/src/cache/ftccache.c +++ b/drivers/freetype/src/cache/ftccache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2007, 2009-2011, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,19 +85,19 @@ /* get a top bucket for specified hash from cache, - * body for FTC_NODE__TOP_FOR_HASH( cache, hash ) + * body for FTC_NODE_TOP_FOR_HASH( cache, hash ) */ FT_LOCAL_DEF( FTC_Node* ) - ftc_get_top_node_for_hash( FTC_Cache cache, - FT_PtrDist hash ) + ftc_get_top_node_for_hash( FTC_Cache cache, + FT_Offset hash ) { FTC_Node* pnode; - FT_UInt idx; + FT_Offset idx; - idx = (FT_UInt)( hash & cache->mask ); + idx = hash & cache->mask; if ( idx < cache->p ) - idx = (FT_UInt)( hash & ( 2 * cache->mask + 1 ) ); + idx = hash & ( 2 * cache->mask + 1 ); pnode = cache->buckets + idx; return pnode; } @@ -224,7 +224,7 @@ ftc_node_hash_unlink( FTC_Node node0, FTC_Cache cache ) { - FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node0->hash ); + FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node0->hash ); for (;;) @@ -257,7 +257,7 @@ ftc_node_hash_link( FTC_Node node, FTC_Cache cache ) { - FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node->hash ); + FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node->hash ); node->link = *pnode; @@ -414,7 +414,7 @@ static void ftc_cache_add( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FTC_Node node ) { node->hash = hash; @@ -442,7 +442,7 @@ FT_LOCAL_DEF( FT_Error ) FTC_Cache_NewNode( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FT_Pointer query, FTC_Node *anode ) { @@ -481,7 +481,7 @@ FT_LOCAL_DEF( FT_Error ) FTC_Cache_Lookup( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FT_Pointer query, FTC_Node *anode ) { @@ -498,7 +498,7 @@ return FT_THROW( Invalid_Argument ); /* Go to the `top' node of the list sharing same masked hash */ - bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); + bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash ); /* Lookup a node with exactly same hash and queried properties. */ /* NOTE: _nodcomp() may change the linked list to reduce memory. */ @@ -518,7 +518,7 @@ if ( list_changed ) { /* Update bucket by modified linked list */ - bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); + bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash ); /* Update pnode by modified linked list */ while ( *pnode != node ) @@ -576,7 +576,7 @@ FTC_Node* pnode = bucket; - for ( ;; ) + for (;;) { FTC_Node node = *pnode; FT_Bool list_changed = FALSE; diff --git a/drivers/freetype/src/cache/ftccache.h b/drivers/freetype/src/cache/ftccache.h index 4155f320e0..1b1295951f 100644 --- a/drivers/freetype/src/cache/ftccache.h +++ b/drivers/freetype/src/cache/ftccache.h @@ -4,7 +4,7 @@ /* */ /* FreeType internal cache interface (specification). */ /* */ -/* Copyright 2000-2007, 2009-2011, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,16 +16,16 @@ /***************************************************************************/ -#ifndef __FTCCACHE_H__ -#define __FTCCACHE_H__ +#ifndef FTCCACHE_H_ +#define FTCCACHE_H_ #include "ftcmru.h" FT_BEGIN_HEADER -#define _FTC_FACE_ID_HASH( i ) \ - ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 ))) +#define FTC_FACE_ID_HASH( i ) \ + ( ( (FT_Offset)(i) >> 3 ) ^ ( (FT_Offset)(i) << 7 ) ) /* handle to cache object */ typedef struct FTC_CacheRec_* FTC_Cache; @@ -59,7 +59,7 @@ FT_BEGIN_HEADER { FTC_MruNodeRec mru; /* circular mru list pointer */ FTC_Node link; /* used for hashing */ - FT_PtrDist hash; /* used for hashing too */ + FT_Offset hash; /* used for hashing too */ FT_UShort cache_index; /* index of cache the node belongs to */ FT_Short ref_count; /* reference count for this node */ @@ -69,20 +69,20 @@ FT_BEGIN_HEADER #define FTC_NODE( x ) ( (FTC_Node)(x) ) #define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) -#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next ) -#define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) +#define FTC_NODE_NEXT( x ) FTC_NODE( (x)->mru.next ) +#define FTC_NODE_PREV( x ) FTC_NODE( (x)->mru.prev ) #ifdef FTC_INLINE -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ +#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \ ( ( cache )->buckets + \ ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \ ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \ : ( ( hash ) & ( cache )->mask ) ) ) #else FT_LOCAL( FTC_Node* ) - ftc_get_top_node_for_hash( FTC_Cache cache, - FT_PtrDist hash ); -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ + ftc_get_top_node_for_hash( FTC_Cache cache, + FT_Offset hash ); +#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \ ftc_get_top_node_for_hash( ( cache ), ( hash ) ) #endif @@ -179,14 +179,14 @@ FT_BEGIN_HEADER #ifndef FTC_INLINE FT_LOCAL( FT_Error ) FTC_Cache_Lookup( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FT_Pointer query, FTC_Node *anode ); #endif FT_LOCAL( FT_Error ) FTC_Cache_NewNode( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FT_Pointer query, FTC_Node *anode ); @@ -211,7 +211,7 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ FTC_Node *_bucket, *_pnode, _node; \ FTC_Cache _cache = FTC_CACHE(cache); \ - FT_PtrDist _hash = (FT_PtrDist)(hash); \ + FT_Offset _hash = (FT_Offset)(hash); \ FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ FT_Bool _list_changed = FALSE; \ \ @@ -220,7 +220,7 @@ FT_BEGIN_HEADER node = NULL; \ \ /* Go to the `top' node of the list sharing same masked hash */ \ - _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ + _bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \ \ /* Look up a node with identical hash and queried properties. */ \ /* NOTE: _nodcomp() may change the linked list to reduce memory. */ \ @@ -228,7 +228,7 @@ FT_BEGIN_HEADER { \ _node = *_pnode; \ if ( _node == NULL ) \ - goto _NewNode; \ + goto NewNode_; \ \ if ( _node->hash == _hash && \ _nodcomp( _node, query, _cache, &_list_changed ) ) \ @@ -240,7 +240,7 @@ FT_BEGIN_HEADER if ( _list_changed ) \ { \ /* Update _bucket by possibly modified linked list */ \ - _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ + _bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \ \ /* Update _pnode by possibly modified linked list */ \ while ( *_pnode != _node ) \ @@ -248,7 +248,7 @@ FT_BEGIN_HEADER if ( *_pnode == NULL ) \ { \ FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \ - goto _NewNode; \ + goto NewNode_; \ } \ else \ _pnode = &((*_pnode)->link); \ @@ -273,12 +273,12 @@ FT_BEGIN_HEADER FTC_MruNode_Up( (FTC_MruNode*)_nl, \ (FTC_MruNode)_node ); \ } \ - goto _Ok; \ + goto Ok_; \ \ - _NewNode: \ + NewNode_: \ error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ \ - _Ok: \ + Ok_: \ node = _node; \ FT_END_STMNT @@ -325,7 +325,7 @@ FT_BEGIN_HEADER break; \ \ _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ - if ( _try_done > 0 && ( list_changed ) ) \ + if ( _try_done > 0 && ( list_changed != NULL ) ) \ *(FT_Bool*)( list_changed ) = TRUE; \ \ if ( _try_done == 0 ) \ @@ -346,7 +346,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCCACHE_H__ */ +#endif /* FTCCACHE_H_ */ /* END */ diff --git a/drivers/freetype/src/cache/ftccback.h b/drivers/freetype/src/cache/ftccback.h index 9528279273..279e94d923 100644 --- a/drivers/freetype/src/cache/ftccback.h +++ b/drivers/freetype/src/cache/ftccback.h @@ -4,7 +4,7 @@ /* */ /* Callback functions of the caching sub-system (specification only). */ /* */ -/* Copyright 2004-2006, 2011, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __FTCCBACK_H__ -#define __FTCCBACK_H__ +#ifndef FTCCBACK_H_ +#define FTCCBACK_H_ #include <ft2build.h> #include FT_CACHE_H @@ -86,6 +86,7 @@ FTC_Manager manager ); -#endif /* __FTCCBACK_H__ */ +#endif /* FTCCBACK_H_ */ + /* END */ diff --git a/drivers/freetype/src/cache/ftccmap.c b/drivers/freetype/src/cache/ftccmap.c index 848349be2d..41a0ce97dd 100644 --- a/drivers/freetype/src/cache/ftccmap.c +++ b/drivers/freetype/src/cache/ftccmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,7 +50,7 @@ /* compute a query/node hash */ #define FTC_CMAP_HASH( faceid, index, charcode ) \ - ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ ( (charcode) / FTC_CMAP_INDICES_MAX ) ) /* the charmap query */ @@ -63,8 +63,6 @@ } FTC_CMapQueryRec, *FTC_CMapQuery; #define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) -#define FTC_CMAP_QUERY_HASH( x ) \ - FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) /* the cmap cache node */ typedef struct FTC_CMapNodeRec_ @@ -78,8 +76,6 @@ } FTC_CMapNodeRec, *FTC_CMapNode; #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) -#define FTC_CMAP_NODE_HASH( x ) \ - FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ @@ -202,7 +198,7 @@ /*************************************************************************/ - FT_CALLBACK_TABLE_DEF + static const FTC_CacheClassRec ftc_cmap_cache_class = { ftc_cmap_node_new, @@ -242,7 +238,7 @@ FTC_Node node; FT_Error error; FT_UInt gindex = 0; - FT_PtrDist hash; + FT_Offset hash; FT_Int no_cmap_change = 0; @@ -267,7 +263,7 @@ query.cmap_index = (FT_UInt)cmap_index; query.char_code = char_code; - hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); + hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code ); #if 1 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, @@ -301,12 +297,6 @@ if ( error ) goto Exit; -#ifdef FT_MAX_CHARMAP_CACHEABLE - /* something rotten can happen with rogue clients */ - if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE ) - return 0; /* XXX: should return appropriate error */ -#endif - if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) { FT_CharMap old, cmap = NULL; diff --git a/drivers/freetype/src/cache/ftcerror.h b/drivers/freetype/src/cache/ftcerror.h index 0e055709bb..1fd7357a8b 100644 --- a/drivers/freetype/src/cache/ftcerror.h +++ b/drivers/freetype/src/cache/ftcerror.h @@ -4,7 +4,7 @@ /* */ /* Caching sub-system error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FTCERROR_H__ -#define __FTCERROR_H__ +#ifndef FTCERROR_H_ +#define FTCERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX FTC_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __FTCERROR_H__ */ +#endif /* FTCERROR_H_ */ + /* END */ diff --git a/drivers/freetype/src/cache/ftcglyph.c b/drivers/freetype/src/cache/ftcglyph.c index 441e177238..c4046812dd 100644 --- a/drivers/freetype/src/cache/ftcglyph.c +++ b/drivers/freetype/src/cache/ftcglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2009, 2011 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -106,7 +106,7 @@ FTC_Family_Init( FTC_Family family, FTC_Cache cache ) { - FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); + FTC_GCacheClass clazz = FTC_CACHE_GCACHE_CLASS( cache ); family->clazz = clazz->family_class; @@ -185,7 +185,7 @@ FT_LOCAL_DEF( FT_Error ) FTC_GCache_Lookup( FTC_GCache cache, - FT_PtrDist hash, + FT_Offset hash, FT_UInt gindex, FTC_GQuery query, FTC_Node *anode ) diff --git a/drivers/freetype/src/cache/ftcglyph.h b/drivers/freetype/src/cache/ftcglyph.h index 5fed19cb8f..dc7be06f03 100644 --- a/drivers/freetype/src/cache/ftcglyph.h +++ b/drivers/freetype/src/cache/ftcglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType abstract glyph cache (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -113,8 +113,8 @@ /*************************************************************************/ -#ifndef __FTCGLYPH_H__ -#define __FTCGLYPH_H__ +#ifndef FTCGLYPH_H_ +#define FTCGLYPH_H_ #include <ft2build.h> @@ -245,10 +245,10 @@ FT_BEGIN_HEADER #define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) -#define FTC_CACHE__GCACHE_CLASS( x ) \ +#define FTC_CACHE_GCACHE_CLASS( x ) \ FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) -#define FTC_CACHE__FAMILY_CLASS( x ) \ - ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) +#define FTC_CACHE_FAMILY_CLASS( x ) \ + ( (FTC_MruListClass)FTC_CACHE_GCACHE_CLASS( x )->family_class ) /* convenience function; use it instead of FTC_Manager_Register_Cache */ @@ -260,7 +260,7 @@ FT_BEGIN_HEADER #ifndef FTC_INLINE FT_LOCAL( FT_Error ) FTC_GCache_Lookup( FTC_GCache cache, - FT_PtrDist hash, + FT_Offset hash, FT_UInt gindex, FTC_GQuery query, FTC_Node *anode ); @@ -323,7 +323,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCGLYPH_H__ */ +#endif /* FTCGLYPH_H_ */ /* END */ diff --git a/drivers/freetype/src/cache/ftcimage.c b/drivers/freetype/src/cache/ftcimage.c index c242ece021..74040aa745 100644 --- a/drivers/freetype/src/cache/ftcimage.c +++ b/drivers/freetype/src/cache/ftcimage.c @@ -4,7 +4,7 @@ /* */ /* FreeType Image cache (body). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2010 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_CACHE_H #include "ftcimage.h" #include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H #include "ftccback.h" #include "ftcerror.h" @@ -69,7 +70,7 @@ FTC_GNode gnode = FTC_GNODE( inode ); FTC_Family family = gquery->family; FT_UInt gindex = gquery->gindex; - FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); + FTC_IFamilyClass clazz = FTC_CACHE_IFAMILY_CLASS( cache ); /* initialize its inner fields */ @@ -122,7 +123,7 @@ bitg = (FT_BitmapGlyph)glyph; - size = bitg->bitmap.rows * ft_labs( bitg->bitmap.pitch ) + + size = bitg->bitmap.rows * (FT_Offset)FT_ABS( bitg->bitmap.pitch ) + sizeof ( *bitg ); } break; @@ -133,9 +134,9 @@ outg = (FT_OutlineGlyph)glyph; - size = outg->outline.n_points * + size = (FT_Offset)outg->outline.n_points * ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + - outg->outline.n_contours * sizeof ( FT_Short ) + + (FT_Offset)outg->outline.n_contours * sizeof ( FT_Short ) + sizeof ( *outg ); } break; diff --git a/drivers/freetype/src/cache/ftcimage.h b/drivers/freetype/src/cache/ftcimage.h index 20d5d3e07d..25aa43b97e 100644 --- a/drivers/freetype/src/cache/ftcimage.h +++ b/drivers/freetype/src/cache/ftcimage.h @@ -4,7 +4,7 @@ /* */ /* FreeType Generic Image cache (specification) */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2006 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,8 +32,8 @@ /*************************************************************************/ -#ifndef __FTCIMAGE_H__ -#define __FTCIMAGE_H__ +#ifndef FTCIMAGE_H_ +#define FTCIMAGE_H_ #include <ft2build.h> @@ -72,8 +72,8 @@ FT_BEGIN_HEADER #define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) -#define FTC_CACHE__IFAMILY_CLASS( x ) \ - FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) +#define FTC_CACHE_IFAMILY_CLASS( x ) \ + FTC_IFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS(x)->family_class ) /* can be used as a @FTC_Node_FreeFunc */ @@ -101,7 +101,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCIMAGE_H__ */ +#endif /* FTCIMAGE_H_ */ /* END */ diff --git a/drivers/freetype/src/cache/ftcmanag.c b/drivers/freetype/src/cache/ftcmanag.c index 4eb2c5bfd6..661a32af5b 100644 --- a/drivers/freetype/src/cache/ftcmanag.c +++ b/drivers/freetype/src/cache/ftcmanag.c @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2006, 2008-2010, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,8 +34,6 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_cache -#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) - static FT_Error ftc_scaler_lookup_size( FTC_Manager manager, @@ -60,8 +58,11 @@ if ( scaler->pixel ) error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); else - error = FT_Set_Char_Size( face, scaler->width, scaler->height, - scaler->x_res, scaler->y_res ); + error = FT_Set_Char_Size( face, + (FT_F26Dot6)scaler->width, + (FT_F26Dot6)scaler->height, + scaler->x_res, + scaler->y_res ); if ( error ) { FT_Done_Size( size ); @@ -151,7 +152,7 @@ } - FT_CALLBACK_TABLE_DEF + static const FTC_MruListClassRec ftc_size_list_class = { sizeof ( FTC_SizeNodeRec ), @@ -186,7 +187,7 @@ FTC_MruNode mrunode; - if ( asize == NULL ) + if ( !asize || !scaler ) return FT_THROW( Invalid_Argument ); *asize = NULL; @@ -290,7 +291,7 @@ } - FT_CALLBACK_TABLE_DEF + static const FTC_MruListClassRec ftc_face_list_class = { sizeof ( FTC_FaceNodeRec), @@ -313,7 +314,7 @@ FTC_MruNode mrunode; - if ( aface == NULL ) + if ( !aface ) return FT_THROW( Invalid_Argument ); *aface = NULL; @@ -366,6 +367,9 @@ if ( !library ) return FT_THROW( Invalid_Library_Handle ); + if ( !amanager || !requester ) + return FT_THROW( Invalid_Argument ); + memory = library->memory; if ( FT_NEW( manager ) ) @@ -451,11 +455,11 @@ FT_EXPORT_DEF( void ) FTC_Manager_Reset( FTC_Manager manager ) { - if ( manager ) - { - FTC_MruList_Reset( &manager->sizes ); - FTC_MruList_Reset( &manager->faces ); - } + if ( !manager ) + return; + + FTC_MruList_Reset( &manager->sizes ); + FTC_MruList_Reset( &manager->faces ); FTC_Manager_FlushN( manager, manager->num_nodes ); } @@ -490,7 +494,7 @@ else weight += cache->clazz.node_weight( node, cache ); - node = FTC_NODE__NEXT( node ); + node = FTC_NODE_NEXT( node ); } while ( node != first ); @@ -509,7 +513,7 @@ do { count++; - node = FTC_NODE__NEXT( node ); + node = FTC_NODE_NEXT( node ); } while ( node != first ); @@ -552,13 +556,13 @@ return; /* go to last node -- it's a circular list */ - node = FTC_NODE__PREV( first ); + node = FTC_NODE_PREV( first ); do { FTC_Node prev; - prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); + prev = ( node == first ) ? NULL : FTC_NODE_PREV( node ); if ( node->ref_count <= 0 ) ftc_node_destroy( node, manager ); @@ -637,10 +641,10 @@ return 0; /* go to last node - it's a circular list */ - node = FTC_NODE__PREV(first); + node = FTC_NODE_PREV(first); for ( result = 0; result < count; ) { - FTC_Node prev = FTC_NODE__PREV( node ); + FTC_Node prev = FTC_NODE_PREV( node ); /* don't touch locked nodes */ @@ -667,6 +671,10 @@ { FT_UInt nn; + + if ( !manager ) + return; + /* this will remove all FTC_SizeNode that correspond to * the face_id as well */ @@ -685,7 +693,9 @@ FTC_Node_Unref( FTC_Node node, FTC_Manager manager ) { - if ( node && (FT_UInt)node->cache_index < manager->num_caches ) + if ( node && + manager && + (FT_UInt)node->cache_index < manager->num_caches ) node->ref_count--; } diff --git a/drivers/freetype/src/cache/ftcmanag.h b/drivers/freetype/src/cache/ftcmanag.h index 0aec33c584..f2c434a135 100644 --- a/drivers/freetype/src/cache/ftcmanag.h +++ b/drivers/freetype/src/cache/ftcmanag.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2010, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,8 +59,8 @@ /*************************************************************************/ -#ifndef __FTCMANAG_H__ -#define __FTCMANAG_H__ +#ifndef FTCMANAG_H_ +#define FTCMANAG_H_ #include <ft2build.h> @@ -161,7 +161,7 @@ FT_BEGIN_HEADER (a)->y_res == (b)->y_res ) ) ) #define FTC_SCALER_HASH( q ) \ - ( _FTC_FACE_ID_HASH( (q)->face_id ) + \ + ( FTC_FACE_ID_HASH( (q)->face_id ) + \ (q)->width + (q)->height*7 + \ ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) ) @@ -169,7 +169,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCMANAG_H__ */ +#endif /* FTCMANAG_H_ */ /* END */ diff --git a/drivers/freetype/src/cache/ftcmru.c b/drivers/freetype/src/cache/ftcmru.c index dc8b4cc397..d107584a19 100644 --- a/drivers/freetype/src/cache/ftcmru.c +++ b/drivers/freetype/src/cache/ftcmru.c @@ -4,7 +4,7 @@ /* */ /* FreeType MRU support (body). */ /* */ -/* Copyright 2003, 2004, 2006, 2009 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/cache/ftcmru.h b/drivers/freetype/src/cache/ftcmru.h index 6fccf11781..ae3c4ce23a 100644 --- a/drivers/freetype/src/cache/ftcmru.h +++ b/drivers/freetype/src/cache/ftcmru.h @@ -4,7 +4,7 @@ /* */ /* Simple MRU list-cache (specification). */ /* */ -/* Copyright 2000-2001, 2003-2006, 2010, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -40,8 +40,8 @@ /*************************************************************************/ -#ifndef __FTCMRU_H__ -#define __FTCMRU_H__ +#ifndef FTCMRU_H_ +#define FTCMRU_H_ #include <ft2build.h> @@ -181,15 +181,15 @@ FT_BEGIN_HEADER FTC_MruNode_Up( _pfirst, _node ); \ \ node = _node; \ - goto _MruOk; \ + goto MruOk_; \ } \ _node = _node->next; \ \ - } while ( _node != _first) ; \ + } while ( _node != _first); \ } \ \ error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ - _MruOk: \ + MruOk_: \ ; \ FT_END_STMNT @@ -240,7 +240,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCMRU_H__ */ +#endif /* FTCMRU_H_ */ /* END */ diff --git a/drivers/freetype/src/cache/ftcsbits.c b/drivers/freetype/src/cache/ftcsbits.c index 6df1c19930..d6f1ddcd4e 100644 --- a/drivers/freetype/src/cache/ftcsbits.c +++ b/drivers/freetype/src/cache/ftcsbits.c @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2006, 2009-2011, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,9 @@ if ( pitch < 0 ) pitch = -pitch; - size = (FT_ULong)( pitch * bitmap->rows ); + size = (FT_ULong)pitch * bitmap->rows; + if ( !size ) + return FT_Err_Ok; if ( !FT_ALLOC( sbit->buffer, size ) ) FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); @@ -142,12 +144,12 @@ goto BadGlyph; } - /* Check that our values fit into 8-bit containers! */ + /* Check whether our values fit into 8-bit containers! */ /* If this is not the case, our bitmap is too large */ /* and we will leave it as `missing' with sbit.buffer = 0 */ -#define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) -#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) +#define CHECK_CHAR( d ) ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d ) +#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d ) /* horizontal advance in pixels */ xadvance = ( slot->advance.x + 32 ) >> 6; @@ -181,7 +183,7 @@ /* now, compute size */ if ( asize ) - *asize = FT_ABS( sbit->pitch ) * sbit->height; + *asize = (FT_ULong)FT_ABS( sbit->pitch ) * sbit->height; } /* glyph loading successful */ @@ -215,7 +217,7 @@ FT_UInt gindex = gquery->gindex; FTC_Family family = gquery->family; - FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); + FTC_SFamilyClass clazz = FTC_CACHE_SFAMILY_CLASS( cache ); FT_UInt total; FT_UInt node_count; @@ -302,7 +304,7 @@ pitch = -pitch; /* add the size of a given glyph image */ - size += pitch * sbit->height; + size += (FT_Offset)pitch * sbit->height; } } diff --git a/drivers/freetype/src/cache/ftcsbits.h b/drivers/freetype/src/cache/ftcsbits.h index df55dca806..a0600ede09 100644 --- a/drivers/freetype/src/cache/ftcsbits.h +++ b/drivers/freetype/src/cache/ftcsbits.h @@ -4,7 +4,7 @@ /* */ /* A small-bitmap cache (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2006, 2011 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCSBITS_H__ -#define __FTCSBITS_H__ +#ifndef FTCSBITS_H_ +#define FTCSBITS_H_ #include <ft2build.h> @@ -64,8 +64,8 @@ FT_BEGIN_HEADER #define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) -#define FTC_CACHE__SFAMILY_CLASS( x ) \ - FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) +#define FTC_CACHE_SFAMILY_CLASS( x ) \ + FTC_SFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS( x )->family_class ) FT_LOCAL( void ) @@ -97,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCSBITS_H__ */ +#endif /* FTCSBITS_H_ */ /* END */ diff --git a/drivers/freetype/src/cache/rules.mk b/drivers/freetype/src/cache/rules.mk index ed75a6a91f..827e259f90 100644 --- a/drivers/freetype/src/cache/rules.mk +++ b/drivers/freetype/src/cache/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2000, 2001, 2003, 2004, 2006, 2008 by +# Copyright 2000-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,9 +17,13 @@ # CACHE_DIR := $(SRC_DIR)/cache + # compilation flags for the driver # -CACHE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) +CACHE_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Cache driver sources (i.e., C files) @@ -33,6 +37,7 @@ CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ $(CACHE_DIR)/ftcmru.c \ $(CACHE_DIR)/ftcsbits.c + # Cache driver headers # CACHE_DRV_H := $(CACHE_DIR)/ftccache.h \ diff --git a/drivers/freetype/src/cff/Jamfile b/drivers/freetype/src/cff/Jamfile index 6705d3cfdb..8067e6b29c 100644 --- a/drivers/freetype/src/cff/Jamfile +++ b/drivers/freetype/src/cff/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cff Jamfile # -# Copyright 2001, 2002 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,23 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cff ; if $(FT2_MULTI) { - _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap cffpic ; + _sources = cffcmap + cffdrivr + cffgload + cffload + cffobjs + cffparse + cffpic + cf2arrst + cf2blues + cf2error + cf2font + cf2ft + cf2hints + cf2intrp + cf2read + cf2stack + ; } else { diff --git a/drivers/freetype/src/cff/cf2arrst.c b/drivers/freetype/src/cff/cf2arrst.c index c8d6f13098..89f3e9f1d7 100644 --- a/drivers/freetype/src/cff/cf2arrst.c +++ b/drivers/freetype/src/cff/cf2arrst.c @@ -101,10 +101,10 @@ FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ FT_Memory memory = arrstack->memory; /* for FT_REALLOC */ - FT_Long newSize = (FT_Long)( numElements * arrstack->sizeItem ); + size_t newSize = numElements * arrstack->sizeItem; - if ( numElements > LONG_MAX / arrstack->sizeItem ) + if ( numElements > FT_LONG_MAX / arrstack->sizeItem ) goto exit; diff --git a/drivers/freetype/src/cff/cf2arrst.h b/drivers/freetype/src/cff/cf2arrst.h index ff5ad8b126..3c21a3b672 100644 --- a/drivers/freetype/src/cff/cf2arrst.h +++ b/drivers/freetype/src/cff/cf2arrst.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2ARRST_H__ -#define __CF2ARRST_H__ +#ifndef CF2ARRST_H_ +#define CF2ARRST_H_ #include "cf2error.h" @@ -94,7 +94,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2ARRST_H__ */ +#endif /* CF2ARRST_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2blues.c b/drivers/freetype/src/cff/cf2blues.c index 5b348398af..250f89e0df 100644 --- a/drivers/freetype/src/cff/cf2blues.c +++ b/drivers/freetype/src/cff/cf2blues.c @@ -4,7 +4,7 @@ /* */ /* Adobe's code for handling Blue Zones (body). */ /* */ -/* Copyright 2009-2013 Adobe Systems Incorporated. */ +/* Copyright 2009-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -86,11 +86,13 @@ size_t i; CF2_Fixed emBoxBottom, emBoxTop; +#if 0 CF2_Int unitsPerEm = font->unitsPerEm; if ( unitsPerEm == 0 ) unitsPerEm = 1000; +#endif FT_ZERO( blues ); blues->scale = font->innerTransform.d; @@ -406,11 +408,10 @@ /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */ /* 10ppem Arial */ - blues->boost = FT_MulFix( - cf2_floatToFixed( .6 ), - ( cf2_intToFixed( 1 ) - - FT_DivFix( blues->scale, - blues->blueScale ) ) ); + blues->boost = cf2_floatToFixed( .6 ) - + FT_MulDiv( cf2_floatToFixed ( .6 ), + blues->scale, + blues->blueScale ); if ( blues->boost > 0x7FFF ) { /* boost must remain less than 0.5, or baseline could go negative */ diff --git a/drivers/freetype/src/cff/cf2blues.h b/drivers/freetype/src/cff/cf2blues.h index 2f38fcad8f..96fb60f38d 100644 --- a/drivers/freetype/src/cff/cf2blues.h +++ b/drivers/freetype/src/cff/cf2blues.h @@ -65,8 +65,8 @@ */ -#ifndef __CF2BLUES_H__ -#define __CF2BLUES_H__ +#ifndef CF2BLUES_H_ +#define CF2BLUES_H_ #include "cf2glue.h" @@ -179,7 +179,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2BLUES_H__ */ +#endif /* CF2BLUES_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2error.h b/drivers/freetype/src/cff/cf2error.h index 6453ebcb7b..512edd1d21 100644 --- a/drivers/freetype/src/cff/cf2error.h +++ b/drivers/freetype/src/cff/cf2error.h @@ -36,13 +36,13 @@ /***************************************************************************/ -#ifndef __CF2ERROR_H__ -#define __CF2ERROR_H__ +#ifndef CF2ERROR_H_ +#define CF2ERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CF2_Err_ @@ -70,7 +70,7 @@ FT_BEGIN_HEADER * Upon a function call if the error code is anything other than * `FT_Err_Ok', which is guaranteed to be zero, we * will return without altering that error. This will allow the - * error to propogate and be handled at the appropriate location in + * error to propagate and be handled at the appropriate location in * the code. * * This allows a style of code where the error code is initialized @@ -113,7 +113,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2ERROR_H__ */ +#endif /* CF2ERROR_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2fixed.h b/drivers/freetype/src/cff/cf2fixed.h index ed1452a7da..74af37708b 100644 --- a/drivers/freetype/src/cff/cf2fixed.h +++ b/drivers/freetype/src/cff/cf2fixed.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2FIXED_H__ -#define __CF2FIXED_H__ +#ifndef CF2FIXED_H_ +#define CF2FIXED_H_ FT_BEGIN_HEADER @@ -57,22 +57,22 @@ FT_BEGIN_HEADER /* in C 89, left and right shift of negative numbers is */ /* implementation specific behaviour in the general case */ -#define cf2_intToFixed( i ) \ +#define cf2_intToFixed( i ) \ ( (CF2_Fixed)( (FT_UInt32)(i) << 16 ) ) -#define cf2_fixedToInt( x ) \ +#define cf2_fixedToInt( x ) \ ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) -#define cf2_fixedRound( x ) \ - ( (CF2_Fixed)( ( (x) + 0x8000 ) & 0xFFFF0000L ) ) -#define cf2_floatToFixed( f ) \ +#define cf2_fixedRound( x ) \ + ( (CF2_Fixed)( ( (FT_UInt32)(x) + 0x8000U ) & 0xFFFF0000UL ) ) +#define cf2_floatToFixed( f ) \ ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) ) -#define cf2_fixedAbs( x ) \ +#define cf2_fixedAbs( x ) \ ( (x) < 0 ? -(x) : (x) ) -#define cf2_fixedFloor( x ) \ - ( (CF2_Fixed)( (x) & 0xFFFF0000L ) ) -#define cf2_fixedFraction( x ) \ +#define cf2_fixedFloor( x ) \ + ( (CF2_Fixed)( (FT_UInt32)(x) & 0xFFFF0000UL ) ) +#define cf2_fixedFraction( x ) \ ( (x) - cf2_fixedFloor( x ) ) -#define cf2_fracToFixed( x ) \ - ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \ +#define cf2_fracToFixed( x ) \ + ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \ : ( ( (x) + 0x2000 ) >> 14 ) ) @@ -89,7 +89,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FIXED_H__ */ +#endif /* CF2FIXED_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2font.c b/drivers/freetype/src/cff/cf2font.c index 479d9125d1..83fd348f2d 100644 --- a/drivers/freetype/src/cff/cf2font.c +++ b/drivers/freetype/src/cff/cf2font.c @@ -4,7 +4,7 @@ /* */ /* Adobe's code for font instances (body). */ /* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -36,6 +36,9 @@ /***************************************************************************/ +#include <ft2build.h> +#include FT_INTERNAL_CALC_H + #include "cf2ft.h" #include "cf2glue.h" @@ -51,11 +54,61 @@ CF2_Fixed stemWidth, CF2_Fixed* darkenAmount, CF2_Fixed boldenAmount, - FT_Bool stemDarkened ) + FT_Bool stemDarkened, + FT_Int* darkenParams ) { + /* + * Total darkening amount is computed in 1000 unit character space + * using the modified 5 part curve as Adobe's Avalon rasterizer. + * The darkening amount is smaller for thicker stems. + * It becomes zero when the stem is thicker than 2.333 pixels. + * + * By default, we use + * + * darkenAmount = 0.4 pixels if scaledStem <= 0.5 pixels, + * darkenAmount = 0.275 pixels if 1 <= scaledStem <= 1.667 pixels, + * darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, + * + * and piecewise linear in-between: + * + * + * darkening + * ^ + * | + * | (x1,y1) + * |--------+ + * | \ + * | \ + * | \ (x3,y3) + * | +----------+ + * | (x2,y2) \ + * | \ + * | \ + * | +----------------- + * | (x4,y4) + * +---------------------------------------------> stem + * thickness + * + * + * This corresponds to the following values for the + * `darkening-parameters' property: + * + * (x1, y1) = (500, 400) + * (x2, y2) = (1000, 275) + * (x3, y3) = (1667, 275) + * (x4, y4) = (2333, 0) + * + */ + /* Internal calculations are done in units per thousand for */ - /* convenience. */ + /* convenience. The x axis is scaled stem width in */ + /* thousandths of a pixel. That is, 1000 is 1 pixel. */ + /* The y axis is darkening amount in thousandths of a pixel.*/ + /* In the code, below, dividing by ppem and */ + /* adjusting for emRatio converts darkenAmount to character */ + /* space (font units). */ CF2_Fixed stemWidthPer1000, scaledStem; + FT_Int logBase2; *darkenAmount = 0; @@ -69,59 +122,107 @@ if ( stemDarkened ) { + FT_Int x1 = darkenParams[0]; + FT_Int y1 = darkenParams[1]; + FT_Int x2 = darkenParams[2]; + FT_Int y2 = darkenParams[3]; + FT_Int x3 = darkenParams[4]; + FT_Int y3 = darkenParams[5]; + FT_Int x4 = darkenParams[6]; + FT_Int y4 = darkenParams[7]; + + /* convert from true character space to 1000 unit character space; */ /* add synthetic emboldening effect */ - /* we have to assure that the computation of `scaledStem' */ - /* and `stemWidthPer1000' don't overflow */ + /* `stemWidthPer1000' will not overflow for a legitimate font */ stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio ); - if ( emRatio > CF2_FIXED_ONE && - stemWidthPer1000 <= ( stemWidth + boldenAmount ) ) + /* `scaledStem' can easily overflow, so we must clamp its maximum */ + /* value; the test doesn't need to be precise, but must be */ + /* conservative. The clamp value (default 2333) where */ + /* `darkenAmount' is zero is well below the overflow value of */ + /* 32767. */ + /* */ + /* FT_MSB computes the integer part of the base 2 logarithm. The */ + /* number of bits for the product is 1 or 2 more than the sum of */ + /* logarithms; remembering that the 16 lowest bits of the fraction */ + /* are dropped this is correct to within a factor of almost 4. */ + /* For example, 0x80.0000 * 0x80.0000 = 0x4000.0000 is 23+23 and */ + /* is flagged as possible overflow because 0xFF.FFFF * 0xFF.FFFF = */ + /* 0xFFFF.FE00 is also 23+23. */ + + logBase2 = FT_MSB( (FT_UInt32)stemWidthPer1000 ) + + FT_MSB( (FT_UInt32)ppem ); + + if ( logBase2 >= 46 ) + /* possible overflow */ + scaledStem = cf2_intToFixed( x4 ); + else + scaledStem = FT_MulFix( stemWidthPer1000, ppem ); + + /* now apply the darkening parameters */ + + if ( scaledStem < cf2_intToFixed( x1 ) ) + *darkenAmount = FT_DivFix( cf2_intToFixed( y1 ), ppem ); + + else if ( scaledStem < cf2_intToFixed( x2 ) ) { - stemWidthPer1000 = 0; /* to pacify compiler */ - scaledStem = cf2_intToFixed( 2333 ); + FT_Int xdelta = x2 - x1; + FT_Int ydelta = y2 - y1; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x1 ), ppem ); + + + if ( !xdelta ) + goto Try_x3; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y1 ), ppem ); } - else + + else if ( scaledStem < cf2_intToFixed( x3 ) ) { - scaledStem = FT_MulFix( stemWidthPer1000, ppem ); + Try_x3: + { + FT_Int xdelta = x3 - x2; + FT_Int ydelta = y3 - y2; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x2 ), ppem ); + + + if ( !xdelta ) + goto Try_x4; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y2 ), ppem ); + } + } - if ( ppem > CF2_FIXED_ONE && - scaledStem <= stemWidthPer1000 ) - scaledStem = cf2_intToFixed( 2333 ); + else if ( scaledStem < cf2_intToFixed( x4 ) ) + { + Try_x4: + { + FT_Int xdelta = x4 - x3; + FT_Int ydelta = y4 - y3; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x3 ), ppem ); + + + if ( !xdelta ) + goto Use_y4; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y3 ), ppem ); + } } - /* - * Total darkening amount is computed in 1000 unit character space - * using the modified 5 part curve as Avalon rasterizer. - * The darkening amount is smaller for thicker stems. - * It becomes zero when the stem is thicker than 2.333 pixels. - * - * In Avalon rasterizer, - * - * darkenAmount = 0.5 pixels if scaledStem <= 0.5 pixels, - * darkenAmount = 0.333 pixels if 1 <= scaledStem <= 1.667 pixels, - * darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, - * - * and piecewise linear in-between. - * - */ - if ( scaledStem < cf2_intToFixed( 500 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 400 ), ppem ); - - else if ( scaledStem < cf2_intToFixed( 1000 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 525 ), ppem ) - - FT_MulFix( stemWidthPer1000, - cf2_floatToFixed( .25 ) ); - - else if ( scaledStem < cf2_intToFixed( 1667 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 275 ), ppem ); - - else if ( scaledStem < cf2_intToFixed( 2333 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 963 ), ppem ) - - FT_MulFix( stemWidthPer1000, - cf2_floatToFixed( .413 ) ); + else + { + Use_y4: + *darkenAmount = FT_DivFix( cf2_intToFixed( y4 ), ppem ); + } /* use half the amount on each side and convert back to true */ /* character space */ @@ -143,13 +244,14 @@ /* pointer to parsed font object */ CFF_Decoder* decoder = font->decoder; - FT_Bool needExtraSetup; + FT_Bool needExtraSetup = FALSE; /* character space units */ CF2_Fixed boldenX = font->syntheticEmboldeningAmountX; CF2_Fixed boldenY = font->syntheticEmboldeningAmountY; - CF2_Fixed ppem; + CFF_SubFont subFont; + CF2_Fixed ppem; /* clear previous error */ @@ -157,8 +259,12 @@ /* if a CID fontDict has changed, we need to recompute some cached */ /* data */ - needExtraSetup = - (FT_Bool)( font->lastSubfont != cf2_getSubfont( decoder ) ); + subFont = cf2_getSubfont( decoder ); + if ( font->lastSubfont != subFont ) + { + font->lastSubfont = subFont; + needExtraSetup = TRUE; + } /* if ppem has changed, we need to recompute some cached data */ /* note: because of CID font matrix concatenation, ppem and transform */ @@ -268,7 +374,8 @@ font->stdVW, &font->darkenX, boldenX, - FALSE ); + FALSE, + font->darkenParams ); } else cf2_computeDarkening( emRatio, @@ -276,7 +383,8 @@ font->stdVW, &font->darkenX, 0, - font->stemDarkened ); + font->stemDarkened, + font->darkenParams ); #if 0 /* since hstem is measured in the y-direction, we use the `d' member */ @@ -303,7 +411,8 @@ font->stdHW, &font->darkenY, boldenY, - font->stemDarkened ); + font->stemDarkened, + font->darkenParams ); if ( font->darkenX != 0 || font->darkenY != 0 ) font->darkened = TRUE; diff --git a/drivers/freetype/src/cff/cf2font.h b/drivers/freetype/src/cff/cf2font.h index f9dd1bbd40..bd05e69e7b 100644 --- a/drivers/freetype/src/cff/cf2font.h +++ b/drivers/freetype/src/cff/cf2font.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2FONT_H__ -#define __CF2FONT_H__ +#ifndef CF2FONT_H_ +#define CF2FONT_H_ #include "cf2ft.h" @@ -48,7 +48,13 @@ FT_BEGIN_HEADER #define CF2_OPERAND_STACK_SIZE 48 -#define CF2_MAX_SUBR 10 /* maximum subroutine nesting */ +#define CF2_MAX_SUBR 16 /* maximum subroutine nesting; */ + /* only 10 are allowed but there exist */ + /* fonts like `HiraKakuProN-W3.ttf' */ + /* (Hiragino Kaku Gothic ProN W3; */ + /* 8.2d6e1; 2014-12-19) that exceed */ + /* this limit */ +#define CF2_STORAGE_SIZE 32 /* typedef is in `cf2glue.h' */ @@ -85,6 +91,8 @@ FT_BEGIN_HEADER /* i.e. darkenX != 0 || darkenY != 0 */ FT_Bool stemDarkened; + FT_Int darkenParams[8]; /* 1000 unit character space */ + /* variables that depend on both FontDict and Transform */ CF2_Fixed stdVW; /* in character space; depends on dict entry */ CF2_Fixed stdHW; /* in character space; depends on dict entry */ @@ -108,7 +116,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FONT_H__ */ +#endif /* CF2FONT_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2ft.c b/drivers/freetype/src/cff/cf2ft.c index c09a0244a8..55f3206ac2 100644 --- a/drivers/freetype/src/cff/cf2ft.c +++ b/drivers/freetype/src/cff/cf2ft.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glue Component to Adobe's Interpreter (body). */ /* */ -/* Copyright 2013 Adobe Systems Incorporated. */ +/* Copyright 2013-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -61,7 +61,9 @@ FT_ASSERT( unitsPerEm > 0 ); - FT_ASSERT( transform->a > 0 && transform->d > 0 ); + if ( transform->a <= 0 || transform->d <= 0 ) + return FT_THROW( Invalid_Size_Handle ); + FT_ASSERT( transform->b == 0 && transform->c == 0 ); FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); @@ -140,6 +142,8 @@ cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, const CF2_CallbackParams params ) { + FT_Error error; + /* downcast the object pointer */ CF2_Outline outline = (CF2_Outline)callbacks; CFF_Builder* builder; @@ -154,15 +158,27 @@ { /* record the move before the line; also check points and set */ /* `path_begun' */ - cff_builder_start_point( builder, - params->pt0.x, - params->pt0.y ); + error = cff_builder_start_point( builder, + params->pt0.x, + params->pt0.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } } /* `cff_builder_add_point1' includes a check_points call for one point */ - cff_builder_add_point1( builder, - params->pt1.x, - params->pt1.y ); + error = cff_builder_add_point1( builder, + params->pt1.x, + params->pt1.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } } @@ -170,6 +186,8 @@ cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, const CF2_CallbackParams params ) { + FT_Error error; + /* downcast the object pointer */ CF2_Outline outline = (CF2_Outline)callbacks; CFF_Builder* builder; @@ -184,13 +202,25 @@ { /* record the move before the line; also check points and set */ /* `path_begun' */ - cff_builder_start_point( builder, - params->pt0.x, - params->pt0.y ); + error = cff_builder_start_point( builder, + params->pt0.x, + params->pt0.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } } /* prepare room for 3 points: 2 off-curve, 1 on-curve */ - cff_check_points( builder, 3 ); + error = cff_check_points( builder, 3 ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } cff_builder_add_point( builder, params->pt1.x, @@ -236,10 +266,8 @@ if ( *hinted ) { - *x_scale = FT_DivFix( decoder->builder.glyph->x_scale, - cf2_intToFixed( 64 ) ); - *y_scale = FT_DivFix( decoder->builder.glyph->y_scale, - cf2_intToFixed( 64 ) ); + *x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64; + *y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64; } else { @@ -344,13 +372,25 @@ if ( scaled && !driver->no_stem_darkening ) font->renderingFlags |= CF2_FlagsDarkened; + font->darkenParams[0] = driver->darken_params[0]; + font->darkenParams[1] = driver->darken_params[1]; + font->darkenParams[2] = driver->darken_params[2]; + font->darkenParams[3] = driver->darken_params[3]; + font->darkenParams[4] = driver->darken_params[4]; + font->darkenParams[5] = driver->darken_params[5]; + font->darkenParams[6] = driver->darken_params[6]; + font->darkenParams[7] = driver->darken_params[7]; + /* now get an outline for this glyph; */ /* also get units per em to validate scale */ font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); - error2 = cf2_checkTransform( &transform, font->unitsPerEm ); - if ( error2 ) - return error2; + if ( scaled ) + { + error2 = cf2_checkTransform( &transform, font->unitsPerEm ); + if ( error2 ) + return error2; + } error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); if ( error2 ) @@ -380,8 +420,16 @@ FT_ASSERT( decoder && decoder->builder.face && decoder->builder.face->root.size ); - FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem ); + /* + * Note that `y_ppem' can be zero if there wasn't a call to + * `FT_Set_Char_Size' or something similar. However, this isn't a + * problem since we come to this place in the code only if + * FT_LOAD_NO_SCALE is set (the other case gets caught by + * `cf2_checkTransform'). The ppem value is needed to compute the stem + * darkening, which is disabled for getting the unscaled outline. + * + */ return cf2_intToFixed( decoder->builder.face->root.size->metrics.y_ppem ); } @@ -496,17 +544,22 @@ /* return 0 on success */ FT_LOCAL_DEF( CF2_Int ) cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ) { - FT_ASSERT( decoder && decoder->globals ); + CF2_UInt idx; + + + FT_ASSERT( decoder ); FT_ZERO( buf ); - idx += decoder->globals_bias; + idx = (CF2_UInt)( subrNum + decoder->globals_bias ); if ( idx >= decoder->num_globals ) return TRUE; /* error */ + FT_ASSERT( decoder->globals ); + buf->start = buf->ptr = decoder->globals[idx]; buf->end = decoder->globals[idx + 1]; @@ -519,7 +572,7 @@ /* used for seac component */ FT_LOCAL_DEF( FT_Error ) cf2_getSeacComponent( CFF_Decoder* decoder, - CF2_UInt code, + CF2_Int code, CF2_Buffer buf ) { CF2_Int gid; @@ -532,12 +585,21 @@ FT_ZERO( buf ); - gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code ); - if ( gid < 0 ) - return FT_THROW( Invalid_Glyph_Format ); +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Incremental fonts don't necessarily have valid charsets. */ + /* They use the character code, not the glyph index, in this case. */ + if ( decoder->builder.face->root.internal->incremental_interface ) + gid = code; + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code ); + if ( gid < 0 ) + return FT_THROW( Invalid_Glyph_Format ); + } error = cff_get_glyph_data( decoder->builder.face, - gid, + (CF2_UInt)gid, &charstring, &len ); /* TODO: for now, just pass the FreeType error through */ @@ -569,17 +631,22 @@ FT_LOCAL_DEF( CF2_Int ) cf2_initLocalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ) { - FT_ASSERT( decoder && decoder->locals ); + CF2_UInt idx; + + + FT_ASSERT( decoder ); FT_ZERO( buf ); - idx += decoder->locals_bias; + idx = (CF2_UInt)( subrNum + decoder->locals_bias ); if ( idx >= decoder->num_locals ) return TRUE; /* error */ + FT_ASSERT( decoder->locals ); + buf->start = buf->ptr = decoder->locals[idx]; buf->end = decoder->locals[idx + 1]; diff --git a/drivers/freetype/src/cff/cf2ft.h b/drivers/freetype/src/cff/cf2ft.h index 731da3ca8c..8e55e841a0 100644 --- a/drivers/freetype/src/cff/cf2ft.h +++ b/drivers/freetype/src/cff/cf2ft.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2FT_H__ -#define __CF2FT_H__ +#ifndef CF2FT_H_ +#define CF2FT_H_ #include "cf2types.h" @@ -99,18 +99,18 @@ FT_BEGIN_HEADER FT_LOCAL( CF2_Int ) cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ); FT_LOCAL( FT_Error ) cf2_getSeacComponent( CFF_Decoder* decoder, - CF2_UInt code, + CF2_Int code, CF2_Buffer buf ); FT_LOCAL( void ) cf2_freeSeacComponent( CFF_Decoder* decoder, CF2_Buffer buf ); FT_LOCAL( CF2_Int ) cf2_initLocalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ); FT_LOCAL( CF2_Fixed ) @@ -141,7 +141,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FT_H__ */ +#endif /* CF2FT_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2glue.h b/drivers/freetype/src/cff/cf2glue.h index a24da39e93..56a7c248f4 100644 --- a/drivers/freetype/src/cff/cf2glue.h +++ b/drivers/freetype/src/cff/cf2glue.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2GLUE_H__ -#define __CF2GLUE_H__ +#ifndef CF2GLUE_H_ +#define CF2GLUE_H_ /* common includes for other modules */ @@ -138,7 +138,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2GLUE_H__ */ +#endif /* CF2GLUE_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2hints.c b/drivers/freetype/src/cff/cf2hints.c index 96bd49f186..bbbe8e3c32 100644 --- a/drivers/freetype/src/cff/cf2hints.c +++ b/drivers/freetype/src/cff/cf2hints.c @@ -4,7 +4,7 @@ /* */ /* Adobe's code for handling CFF hints (body). */ /* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -304,9 +304,6 @@ cf2_hintmap_map( CF2_HintMap hintmap, CF2_Fixed csCoord ) { - FT_ASSERT( hintmap->isValid ); /* must call Build before Map */ - FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); - if ( hintmap->count == 0 || ! hintmap->hinted ) { /* there are no hints; use uniform scale and zero offset */ @@ -317,6 +314,7 @@ /* start linear search from last hit */ CF2_UInt i = hintmap->lastIndex; + FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); /* search up */ while ( i < hintmap->count - 1 && @@ -589,29 +587,39 @@ } /* paired edges must be in proper order */ - FT_ASSERT( !isPair || - topHintEdge->csCoord >= bottomHintEdge->csCoord ); + if ( isPair && + topHintEdge->csCoord < bottomHintEdge->csCoord ) + return; /* linear search to find index value of insertion point */ indexInsert = 0; for ( ; indexInsert < hintmap->count; indexInsert++ ) { - if ( hintmap->edge[indexInsert].csCoord > firstHintEdge->csCoord ) + if ( hintmap->edge[indexInsert].csCoord >= firstHintEdge->csCoord ) break; } /* - * Discard any hints that overlap in character space. Most often, - * this is while building the initial map, but in theory, it can also - * occur because of darkening. + * Discard any hints that overlap in character space. Most often, this + * is while building the initial map, where captured hints from all + * zones are combined. Define overlap to include hints that `touch' + * (overlap zero). Hiragino Sans/Gothic fonts have numerous hints that + * touch. Some fonts have non-ideographic glyphs that overlap our + * synthetic hints. + * + * Overlap also occurs when darkening stem hints that are close. * */ if ( indexInsert < hintmap->count ) { - /* we are inserting before an existing edge: */ + /* we are inserting before an existing edge: */ + /* verify that an existing edge is not the same */ + if ( hintmap->edge[indexInsert].csCoord == firstHintEdge->csCoord ) + return; /* ignore overlapping stem hint */ + /* verify that a new pair does not straddle the next edge */ - if ( isPair && - hintmap->edge[indexInsert].csCoord < secondHintEdge->csCoord ) + if ( isPair && + hintmap->edge[indexInsert].csCoord <= secondHintEdge->csCoord ) return; /* ignore overlapping stem hint */ /* verify that we are not inserting between paired edges */ @@ -645,8 +653,27 @@ firstHintEdge->csCoord ); } - /* discard any hints that overlap in device space; this can occur */ - /* because locked hints have been moved to align with blue zones */ + /* + * Discard any hints that overlap in device space; this can occur + * because locked hints have been moved to align with blue zones. + * + * TODO: Although we might correct this later during adjustment, we + * don't currently have a way to delete a conflicting hint once it has + * been inserted. See v2.030 MinionPro-Regular, 12 ppem darkened, + * initial hint map for second path, glyph 945 (the perispomeni (tilde) + * in U+1F6E, Greek omega with psili and perispomeni). Darkening is + * 25. Pair 667,747 initially conflicts in design space with top edge + * 660. This is because 667 maps to 7.87, and the top edge was + * captured by a zone at 8.0. The pair is later successfully inserted + * in a zone without the top edge. In this zone it is adjusted to 8.0, + * and no longer conflicts with the top edge in design space. This + * means it can be included in yet a later zone which does have the top + * edge hint. This produces a small mismatch between the first and + * last points of this path, even though the hint masks are the same. + * The density map difference is tiny (1/256). + * + */ + if ( indexInsert > 0 ) { /* we are inserting after an existing edge */ @@ -671,10 +698,10 @@ /* make room to insert */ { - CF2_Int iSrc = hintmap->count - 1; - CF2_Int iDst = isPair ? hintmap->count + 1 : hintmap->count; + CF2_UInt iSrc = hintmap->count - 1; + CF2_UInt iDst = isPair ? hintmap->count + 1 : hintmap->count; - CF2_Int count = hintmap->count - indexInsert; + CF2_UInt count = hintmap->count - indexInsert; if ( iDst >= CF2_MAX_HINT_EDGES ) @@ -753,6 +780,8 @@ cf2_hintmask_setAll( hintMask, cf2_arrstack_size( hStemHintArray ) + cf2_arrstack_size( vStemHintArray ) ); + if ( !cf2_hintmask_isValid( hintMask ) ) + return; /* too many stem hints */ } /* begin by clearing the map */ @@ -764,9 +793,12 @@ maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask ); /* use the hStem hints only, which are first in the mask */ - /* TODO: compare this to cffhintmaskGetBitCount */ bitCount = cf2_arrstack_size( hStemHintArray ); + /* Defense-in-depth. Should never return here. */ + if ( bitCount > hintMask->bitCount ) + return; + /* synthetic embox hints get highest priority */ if ( font->blues.doEmBoxHints ) { @@ -1035,6 +1067,7 @@ glyphpath->moveIsPending = TRUE; glyphpath->pathIsOpen = FALSE; + glyphpath->pathIsClosing = FALSE; glyphpath->elemIsQueued = FALSE; } @@ -1175,12 +1208,16 @@ /* * Push the cached element (glyphpath->prevElem*) to the outline * consumer. When a darkening offset is used, the end point of the - * cached element may be adjusted to an intersection point or it may be - * connected by a line to the current element. This calculation must - * use a HintMap that was valid at the time the element was saved. For - * the first point in a subpath, that is a saved HintMap. For most - * elements, it just means the caller has delayed building a HintMap - * from the current HintMask. + * cached element may be adjusted to an intersection point or we may + * synthesize a connecting line to the current element. If we are + * closing a subpath, we may also generate a connecting line to the start + * point. + * + * This is where Character Space (CS) is converted to Device Space (DS) + * using a hint map. This calculation must use a HintMap that was valid + * at the time the element was saved. For the first point in a subpath, + * that is a saved HintMap. For most elements, it just means the caller + * has delayed building a HintMap from the current HintMask. * * Transform each point with outerTransform and call the outline * callbacks. This is a general 3x3 transform: @@ -1250,16 +1287,32 @@ params.op = CF2_PathOpLineTo; /* note: pt2 and pt3 are unused */ - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt1, - glyphpath->prevElemP1.x, - glyphpath->prevElemP1.y ); - glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); + if ( close ) + { + /* use first hint map if closing */ + cf2_glyphpath_hintPoint( glyphpath, + &glyphpath->firstHintMap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + } + else + { + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + } - glyphpath->currentDS = params.pt1; + /* output only non-zero length lines */ + if ( params.pt0.x != params.pt1.x || params.pt0.y != params.pt1.y ) + { + glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); + glyphpath->currentDS = params.pt1; + } break; case CF2_PathOpCubeTo: @@ -1296,11 +1349,24 @@ /* note: at the end of a subpath, we might do both, so use `nextP0' */ /* before we change it, below */ - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt1, - nextP0->x, - nextP0->y ); + if ( close ) + { + /* if we are closing the subpath, then nextP0 is in the first */ + /* hint zone */ + cf2_glyphpath_hintPoint( glyphpath, + &glyphpath->firstHintMap, + ¶ms.pt1, + nextP0->x, + nextP0->y ); + } + else + { + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + nextP0->x, + nextP0->y ); + } if ( params.pt1.x != glyphpath->currentDS.x || params.pt1.y != glyphpath->currentDS.y ) @@ -1496,7 +1562,7 @@ { /* -y */ *x = -glyphpath->xOffset; - *y = glyphpath->xOffset; + *y = glyphpath->yOffset; } else { @@ -1511,6 +1577,16 @@ } + /* + * The functions cf2_glyphpath_{moveTo,lineTo,curveTo,closeOpenPath} are + * called by the interpreter with Character Space (CS) coordinates. Each + * path element is placed into a queue of length one to await the + * calculation of the following element. At that time, the darkening + * offset of the following element is known and joins can be computed, + * including possible modification of this element, before mapping to + * Device Space (DS) and passing it on to the outline consumer. + * + */ FT_LOCAL_DEF( void ) cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, CF2_Fixed x, @@ -1548,10 +1624,46 @@ { CF2_Fixed xOffset, yOffset; FT_Vector P0, P1; + FT_Bool newHintMap; + /* + * New hints will be applied after cf2_glyphpath_pushPrevElem has run. + * In case this is a synthesized closing line, any new hints should be + * delayed until this path is closed (`cf2_hintmask_isNew' will be + * called again before the next line or curve). + */ - /* can't compute offset of zero length line, so ignore them */ - if ( glyphpath->currentCS.x == x && glyphpath->currentCS.y == y ) + /* true if new hint map not on close */ + newHintMap = cf2_hintmask_isNew( glyphpath->hintMask ) && + !glyphpath->pathIsClosing; + + /* + * Zero-length lines may occur in the charstring. Because we cannot + * compute darkening offsets or intersections from zero-length lines, + * it is best to remove them and avoid artifacts. However, zero-length + * lines in CS at the start of a new hint map can generate non-zero + * lines in DS due to hint substitution. We detect a change in hint + * map here and pass those zero-length lines along. + */ + + /* + * Note: Find explicitly closed paths here with a conditional + * breakpoint using + * + * !gp->pathIsClosing && gp->start.x == x && gp->start.y == y + * + */ + + if ( glyphpath->currentCS.x == x && + glyphpath->currentCS.y == y && + !newHintMap ) + /* + * Ignore zero-length lines in CS where the hint map is the same + * because the line in DS will also be zero length. + * + * Ignore zero-length lines when we synthesize a closing line because + * the close will be handled in cf2_glyphPath_pushPrevElem. + */ return; cf2_glyphpath_computeOffset( glyphpath, @@ -1581,7 +1693,8 @@ if ( glyphpath->elemIsQueued ) { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ); + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) || + glyphpath->hintMap.count == 0 ); cf2_glyphpath_pushPrevElem( glyphpath, &glyphpath->hintMap, @@ -1597,7 +1710,7 @@ glyphpath->prevElemP1 = P1; /* update current map */ - if ( cf2_hintmask_isNew( glyphpath->hintMask ) ) + if ( newHintMap ) cf2_hintmap_build( &glyphpath->hintMap, glyphpath->hStemHintArray, glyphpath->vStemHintArray, @@ -1667,7 +1780,8 @@ if ( glyphpath->elemIsQueued ) { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ); + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) || + glyphpath->hintMap.count == 0 ); cf2_glyphpath_pushPrevElem( glyphpath, &glyphpath->hintMap, @@ -1703,29 +1817,29 @@ { if ( glyphpath->pathIsOpen ) { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->firstHintMap ) ); + /* + * A closing line in Character Space line is always generated below + * with `cf2_glyphPath_lineTo'. It may be ignored later if it turns + * out to be zero length in Device Space. + */ + glyphpath->pathIsClosing = TRUE; - /* since we need to apply an offset to the implicit lineto, we make */ - /* it explicit here */ cf2_glyphpath_lineTo( glyphpath, glyphpath->start.x, glyphpath->start.y ); - /* Draw previous element (the explicit LineTo we just created, */ - /* above) and connect it to the start point, but with the offset we */ - /* saved from the first element. */ - /* Use the saved HintMap, too. */ - FT_ASSERT( glyphpath->elemIsQueued ); - - cf2_glyphpath_pushPrevElem( glyphpath, - &glyphpath->firstHintMap, - &glyphpath->offsetStart0, - glyphpath->offsetStart1, - TRUE ); + /* empty the final element from the queue and close the path */ + if ( glyphpath->elemIsQueued ) + cf2_glyphpath_pushPrevElem( glyphpath, + &glyphpath->hintMap, + &glyphpath->offsetStart0, + glyphpath->offsetStart1, + TRUE ); /* reset state machine */ glyphpath->moveIsPending = TRUE; glyphpath->pathIsOpen = FALSE; + glyphpath->pathIsClosing = FALSE; glyphpath->elemIsQueued = FALSE; } } diff --git a/drivers/freetype/src/cff/cf2hints.h b/drivers/freetype/src/cff/cf2hints.h index c4fa922a39..a8984542a0 100644 --- a/drivers/freetype/src/cff/cf2hints.h +++ b/drivers/freetype/src/cff/cf2hints.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2HINTS_H__ -#define __CF2HINTS_H__ +#ifndef CF2HINTS_H_ +#define CF2HINTS_H_ FT_BEGIN_HEADER @@ -204,6 +204,7 @@ FT_BEGIN_HEADER #endif FT_Bool pathIsOpen; /* true after MoveTo */ + FT_Bool pathIsClosing; /* true when synthesizing closepath line */ FT_Bool darken; /* true if stem darkening */ FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */ @@ -219,7 +220,7 @@ FT_BEGIN_HEADER /* character space miter limit threshold */ CF2_Fixed miterLimit; - /* vertical/horzizontal snap distance in character space */ + /* vertical/horizontal snap distance in character space */ CF2_Fixed snapThreshold; FT_Vector offsetStart0; /* first and second points of first */ @@ -229,7 +230,8 @@ FT_BEGIN_HEADER FT_Vector currentCS; /* current point, device space */ FT_Vector currentDS; - FT_Vector start; /* start point of subpath */ + /* start point of subpath, character space */ + FT_Vector start; /* the following members constitute the `queue' of one element */ FT_Bool elemIsQueued; @@ -281,7 +283,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2HINTS_H__ */ +#endif /* CF2HINTS_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2intrp.c b/drivers/freetype/src/cff/cf2intrp.c index 5610917cc3..7d663dd0ec 100644 --- a/drivers/freetype/src/cff/cf2intrp.c +++ b/drivers/freetype/src/cff/cf2intrp.c @@ -4,7 +4,7 @@ /* */ /* Adobe's CFF Interpreter (body). */ /* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -43,6 +43,7 @@ #include "cf2font.h" #include "cf2stack.h" #include "cf2hints.h" +#include "cf2intrp.h" #include "cf2error.h" @@ -183,7 +184,7 @@ return; FT_ASSERT( hintmask->byteCount > 0 ); - FT_ASSERT( hintmask->byteCount < + FT_ASSERT( hintmask->byteCount <= sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) ); /* set mask to all ones */ @@ -292,7 +293,8 @@ /* variable accumulates delta values from operand stack */ CF2_Fixed position = hintOffset; - if ( hasWidthArg && ! *haveWidth ) + + if ( hasWidthArg && !*haveWidth ) *width = cf2_stack_getReal( opStack, 0 ) + cf2_getNominalWidthX( font->decoder ); @@ -445,6 +447,8 @@ CF2_Stack opStack = NULL; FT_Byte op1; /* first opcode byte */ + CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */ + /* instruction limit; 20,000,000 matches Avalon */ FT_UInt32 instructionLimit = 20000000UL; @@ -593,8 +597,11 @@ /* never add hints after the mask is computed */ if ( cf2_hintmask_isValid( &hintMask ) ) + { FT_TRACE4(( "cf2_interpT2CharString:" " invalid horizontal hint mask\n" )); + break; + } cf2_doStems( font, opStack, @@ -604,7 +611,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; break; @@ -614,8 +621,11 @@ /* never add hints after the mask is computed */ if ( cf2_hintmask_isValid( &hintMask ) ) + { FT_TRACE4(( "cf2_interpT2CharString:" " invalid vertical hint mask\n" )); + break; + } cf2_doStems( font, opStack, @@ -625,7 +635,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; break; @@ -639,7 +649,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curY += cf2_stack_popFixed( opStack ); @@ -739,7 +749,7 @@ case cf2_cmdCALLGSUBR: case cf2_cmdCALLSUBR: { - CF2_UInt subrIndex; + CF2_Int subrNum; FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr" @@ -754,19 +764,22 @@ /* push our current CFF charstring region on subrStack */ charstring = (CF2_Buffer) - cf2_arrstack_getPointer( &subrStack, - charstringIndex + 1 ); + cf2_arrstack_getPointer( + &subrStack, + (size_t)charstringIndex + 1 ); /* set up the new CFF region and pointer */ - subrIndex = cf2_stack_popInt( opStack ); + subrNum = cf2_stack_popInt( opStack ); switch ( op1 ) { case cf2_cmdCALLGSUBR: - FT_TRACE4(( "(%d)\n", subrIndex + decoder->globals_bias )); + FT_TRACE4(( " (idx %d, entering level %d)\n", + subrNum + decoder->globals_bias, + charstringIndex + 1 )); if ( cf2_initGlobalRegionBuffer( decoder, - subrIndex, + subrNum, charstring ) ) { lastError = FT_THROW( Invalid_Glyph_Format ); @@ -776,10 +789,12 @@ default: /* cf2_cmdCALLSUBR */ - FT_TRACE4(( "(%d)\n", subrIndex + decoder->locals_bias )); + FT_TRACE4(( " (idx %d, entering level %d)\n", + subrNum + decoder->locals_bias, + charstringIndex + 1 )); if ( cf2_initLocalRegionBuffer( decoder, - subrIndex, + subrNum, charstring ) ) { lastError = FT_THROW( Invalid_Glyph_Format ); @@ -792,7 +807,7 @@ continue; /* do not clear the stack */ case cf2_cmdRETURN: - FT_TRACE4(( " return\n" )); + FT_TRACE4(( " return (leaving level %d)\n", charstringIndex )); if ( charstringIndex < 1 ) { @@ -803,8 +818,9 @@ /* restore position in previous charstring */ charstring = (CF2_Buffer) - cf2_arrstack_getPointer( &subrStack, - --charstringIndex ); + cf2_arrstack_getPointer( + &subrStack, + (CF2_UInt)--charstringIndex ); continue; /* do not clear the stack */ case cf2_cmdESC: @@ -820,84 +836,189 @@ break; - /* TODO: should these operators be supported? */ - case cf2_escAND: /* in spec */ - FT_TRACE4(( " and\n" )); + case cf2_escAND: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; - CF2_FIXME; - break; - case cf2_escOR: /* in spec */ - FT_TRACE4(( " or\n" )); + FT_TRACE4(( " and\n" )); - CF2_FIXME; - break; + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - case cf2_escNOT: /* in spec */ - FT_TRACE4(( " not\n" )); + cf2_stack_pushInt( opStack, arg1 && arg2 ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escOR: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; - case cf2_escABS: /* in spec */ - FT_TRACE4(( " abs\n" )); - CF2_FIXME; - break; + FT_TRACE4(( " or\n" )); - case cf2_escADD: /* in spec */ - FT_TRACE4(( " add\n" )); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - CF2_FIXME; - break; + cf2_stack_pushInt( opStack, arg1 || arg2 ); + } + continue; /* do not clear the stack */ - case cf2_escSUB: /* in spec */ - FT_TRACE4(( " sub\n" )); + case cf2_escNOT: + { + CF2_F16Dot16 arg; - CF2_FIXME; - break; - case cf2_escDIV: /* in spec */ - FT_TRACE4(( " div\n" )); + FT_TRACE4(( " not\n" )); - CF2_FIXME; - break; + arg = cf2_stack_popFixed( opStack ); - case cf2_escNEG: /* in spec */ - FT_TRACE4(( " neg\n" )); + cf2_stack_pushInt( opStack, !arg ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escABS: + { + CF2_F16Dot16 arg; - case cf2_escEQ: /* in spec */ - FT_TRACE4(( " eq\n" )); - CF2_FIXME; - break; + FT_TRACE4(( " abs\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, FT_ABS( arg ) ); + } + continue; /* do not clear the stack */ + + case cf2_escADD: + { + CF2_F16Dot16 summand1; + CF2_F16Dot16 summand2; + + + FT_TRACE4(( " add\n" )); - case cf2_escDROP: /* in spec */ + summand2 = cf2_stack_popFixed( opStack ); + summand1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, summand1 + summand2 ); + } + continue; /* do not clear the stack */ + + case cf2_escSUB: + { + CF2_F16Dot16 minuend; + CF2_F16Dot16 subtrahend; + + + FT_TRACE4(( " sub\n" )); + + subtrahend = cf2_stack_popFixed( opStack ); + minuend = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, minuend - subtrahend ); + } + continue; /* do not clear the stack */ + + case cf2_escDIV: + { + CF2_F16Dot16 dividend; + CF2_F16Dot16 divisor; + + + FT_TRACE4(( " div\n" )); + + divisor = cf2_stack_popFixed( opStack ); + dividend = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) ); + } + continue; /* do not clear the stack */ + + case cf2_escNEG: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " neg\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, -arg ); + } + continue; /* do not clear the stack */ + + case cf2_escEQ: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " eq\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, arg1 == arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escDROP: FT_TRACE4(( " drop\n" )); - CF2_FIXME; - break; + (void)cf2_stack_popFixed( opStack ); + continue; /* do not clear the stack */ - case cf2_escPUT: /* in spec */ - FT_TRACE4(( " put\n" )); + case cf2_escPUT: + { + CF2_F16Dot16 val; + CF2_Int idx; - CF2_FIXME; - break; - case cf2_escGET: /* in spec */ - FT_TRACE4(( " get\n" )); + FT_TRACE4(( " put\n" )); - CF2_FIXME; - break; + idx = cf2_stack_popInt( opStack ); + val = cf2_stack_popFixed( opStack ); - case cf2_escIFELSE: /* in spec */ - FT_TRACE4(( " ifelse\n" )); + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + storage[idx] = val; + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escGET: + { + CF2_Int idx; + + + FT_TRACE4(( " get\n" )); + + idx = cf2_stack_popInt( opStack ); + + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + cf2_stack_pushFixed( opStack, storage[idx] ); + } + continue; /* do not clear the stack */ + + case cf2_escIFELSE: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + CF2_F16Dot16 cond1; + CF2_F16Dot16 cond2; + + + FT_TRACE4(( " ifelse\n" )); + + cond2 = cf2_stack_popFixed( opStack ); + cond1 = cf2_stack_popFixed( opStack ); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 ); + } + continue; /* do not clear the stack */ case cf2_escRANDOM: /* in spec */ FT_TRACE4(( " random\n" )); @@ -905,41 +1026,126 @@ CF2_FIXME; break; - case cf2_escMUL: /* in spec */ - FT_TRACE4(( " mul\n" )); + case cf2_escMUL: + { + CF2_F16Dot16 factor1; + CF2_F16Dot16 factor2; - CF2_FIXME; - break; - case cf2_escSQRT: /* in spec */ - FT_TRACE4(( " sqrt\n" )); + FT_TRACE4(( " mul\n" )); - CF2_FIXME; - break; + factor2 = cf2_stack_popFixed( opStack ); + factor1 = cf2_stack_popFixed( opStack ); - case cf2_escDUP: /* in spec */ - FT_TRACE4(( " dup\n" )); + cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escSQRT: + { + CF2_F16Dot16 arg; - case cf2_escEXCH: /* in spec */ - FT_TRACE4(( " exch\n" )); - CF2_FIXME; - break; + FT_TRACE4(( " sqrt\n" )); + + arg = cf2_stack_popFixed( opStack ); + if ( arg > 0 ) + { + FT_Fixed root = arg; + FT_Fixed new_root; + + + /* Babylonian method */ + for (;;) + { + new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1; + if ( new_root == root ) + break; + root = new_root; + } + arg = new_root; + } + else + arg = 0; - case cf2_escINDEX: /* in spec */ - FT_TRACE4(( " index\n" )); + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escDUP: + { + CF2_F16Dot16 arg; - case cf2_escROLL: /* in spec */ - FT_TRACE4(( " roll\n" )); - CF2_FIXME; - break; + FT_TRACE4(( " dup\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, arg ); + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ + + case cf2_escEXCH: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " exch\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, arg2 ); + cf2_stack_pushFixed( opStack, arg1 ); + } + continue; /* do not clear the stack */ + + case cf2_escINDEX: + { + CF2_Int idx; + CF2_UInt size; + + + FT_TRACE4(( " index\n" )); + + idx = cf2_stack_popInt( opStack ); + size = cf2_stack_count( opStack ); + + if ( size > 0 ) + { + /* for `cf2_stack_getReal', index 0 is bottom of stack */ + CF2_UInt gr_idx; + + + if ( idx < 0 ) + gr_idx = size - 1; + else if ( (CF2_UInt)idx >= size ) + gr_idx = 0; + else + gr_idx = size - 1 - (CF2_UInt)idx; + + cf2_stack_pushFixed( opStack, + cf2_stack_getReal( opStack, gr_idx ) ); + } + } + continue; /* do not clear the stack */ + + case cf2_escROLL: + { + CF2_Int idx; + CF2_Int count; + + + FT_TRACE4(( " roll\n" )); + + idx = cf2_stack_popInt( opStack ); + count = cf2_stack_popInt( opStack ); + + cf2_stack_roll( opStack, count, idx ); + } + continue; /* do not clear the stack */ case cf2_escHFLEX: { @@ -1072,7 +1278,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; /* close path if still open */ cf2_glyphpath_closeOpenPath( &glyphPath ); @@ -1082,8 +1288,8 @@ /* must be either 4 or 5 -- */ /* this is a (deprecated) implied `seac' operator */ - CF2_UInt achar; - CF2_UInt bchar; + CF2_Int achar; + CF2_Int bchar; CF2_BufferRec component; CF2_Fixed dummyWidth; /* ignore component width */ FT_Error error2; @@ -1104,8 +1310,8 @@ error2 = cf2_getSeacComponent( decoder, achar, &component ); if ( error2 ) { - lastError = error2; /* pass FreeType error through */ - goto exit; + lastError = error2; /* pass FreeType error through */ + goto exit; } cf2_interpT2CharString( font, &component, @@ -1141,15 +1347,16 @@ /* `cf2_hintmask_read' (which also traces the mask bytes) */ FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" )); - /* if there are arguments on the stack, there this is an */ - /* implied cf2_cmdVSTEMHM */ - if ( cf2_stack_count( opStack ) != 0 ) + /* never add hints after the mask is computed */ + if ( cf2_stack_count( opStack ) > 1 && + cf2_hintmask_isValid( &hintMask ) ) { - /* never add hints after the mask is computed */ - if ( cf2_hintmask_isValid( &hintMask ) ) - FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" )); + FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" )); + break; } + /* if there are arguments on the stack, there this is an */ + /* implied cf2_cmdVSTEMHM */ cf2_doStems( font, opStack, &vStemHintArray, @@ -1158,7 +1365,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; if ( op1 == cf2_cmdHINTMASK ) { @@ -1217,7 +1424,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curY += cf2_stack_popFixed( opStack ); curX += cf2_stack_popFixed( opStack ); @@ -1236,7 +1443,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curX += cf2_stack_popFixed( opStack ); @@ -1284,10 +1491,16 @@ case cf2_cmdVVCURVETO: { - CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt count, count1 = cf2_stack_count( opStack ); CF2_UInt index = 0; + /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + index += count1 - count; + FT_TRACE4(( " vvcurveto\n" )); while ( index < count ) @@ -1323,10 +1536,16 @@ case cf2_cmdHHCURVETO: { - CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt count, count1 = cf2_stack_count( opStack ); CF2_UInt index = 0; + /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + index += count1 - count; + FT_TRACE4(( " hhcurveto\n" )); while ( index < count ) @@ -1363,12 +1582,19 @@ case cf2_cmdVHCURVETO: case cf2_cmdHVCURVETO: { - CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt count, count1 = cf2_stack_count( opStack ); CF2_UInt index = 0; FT_Bool alternate = op1 == cf2_cmdHVCURVETO; + /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */ + /* 8n+4, or 8n+5, we enforce it by clearing the */ + /* second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + index += count1 - count; + FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" )); while ( index < count ) @@ -1430,9 +1656,12 @@ { CF2_Int v; + CF2_Int byte1 = cf2_buf_readByte( charstring ); + CF2_Int byte2 = cf2_buf_readByte( charstring ); - v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) | - cf2_buf_readByte( charstring ) ); + + v = (FT_Short)( ( byte1 << 8 ) | + byte2 ); FT_TRACE4(( " %d", v )); @@ -1494,12 +1723,16 @@ { CF2_Fixed v; + FT_UInt32 byte1 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte2 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte3 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte4 = (FT_UInt32)cf2_buf_readByte( charstring ); + - v = (CF2_Fixed) - ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) | - ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) | - ( (FT_UInt32)cf2_buf_readByte( charstring ) << 8 ) | - (FT_UInt32)cf2_buf_readByte( charstring ) ); + v = (CF2_Fixed)( ( byte1 << 24 ) | + ( byte2 << 16 ) | + ( byte3 << 8 ) | + byte4 ); FT_TRACE4(( " %.2f", v / 65536.0 )); diff --git a/drivers/freetype/src/cff/cf2intrp.h b/drivers/freetype/src/cff/cf2intrp.h index b5d8947838..ec030e8944 100644 --- a/drivers/freetype/src/cff/cf2intrp.h +++ b/drivers/freetype/src/cff/cf2intrp.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2INTRP_H__ -#define __CF2INTRP_H__ +#ifndef CF2INTRP_H_ +#define CF2INTRP_H_ #include "cf2ft.h" @@ -77,7 +77,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2INTRP_H__ */ +#endif /* CF2INTRP_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2read.h b/drivers/freetype/src/cff/cf2read.h index 7ef7c8c149..b0b0db803a 100644 --- a/drivers/freetype/src/cff/cf2read.h +++ b/drivers/freetype/src/cff/cf2read.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2READ_H__ -#define __CF2READ_H__ +#ifndef CF2READ_H_ +#define CF2READ_H_ FT_BEGIN_HEADER @@ -62,7 +62,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2READ_H__ */ +#endif /* CF2READ_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2stack.c b/drivers/freetype/src/cff/cf2stack.c index 8332b5d91a..6fafd901f3 100644 --- a/drivers/freetype/src/cff/cf2stack.c +++ b/drivers/freetype/src/cff/cf2stack.c @@ -145,7 +145,7 @@ /* Note: type mismatch is silently cast */ - /* TODO: check this */ + /* TODO: check this */ FT_LOCAL_DEF( CF2_Fixed ) cf2_stack_popFixed( CF2_Stack stack ) { @@ -170,7 +170,7 @@ /* Note: type mismatch is silently cast */ - /* TODO: check this */ + /* TODO: check this */ FT_LOCAL_DEF( CF2_Fixed ) cf2_stack_getReal( CF2_Stack stack, CF2_UInt idx ) @@ -195,6 +195,86 @@ } + FT_LOCAL( void ) + cf2_stack_roll( CF2_Stack stack, + CF2_Int count, + CF2_Int shift ) + { + /* we initialize this variable to avoid compiler warnings */ + CF2_StackNumber last = { { 0 }, CF2_NumberInt }; + + CF2_Int start_idx, idx, i; + + + if ( count < 2 ) + return; /* nothing to do (values 0 and 1), or undefined value */ + + if ( (CF2_UInt)count > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; + } + + if ( shift < 0 ) + shift = -( ( -shift ) % count ); + else + shift %= count; + + if ( shift == 0 ) + return; /* nothing to do */ + + /* We use the following algorithm to do the rolling, */ + /* which needs two temporary variables only. */ + /* */ + /* Example: */ + /* */ + /* count = 8 */ + /* shift = 2 */ + /* */ + /* stack indices before roll: 7 6 5 4 3 2 1 0 */ + /* stack indices after roll: 1 0 7 6 5 4 3 2 */ + /* */ + /* The value of index 0 gets moved to index 2, while */ + /* the old value of index 2 gets moved to index 4, */ + /* and so on. We thus have the following copying */ + /* chains for shift value 2. */ + /* */ + /* 0 -> 2 -> 4 -> 6 -> 0 */ + /* 1 -> 3 -> 5 -> 7 -> 1 */ + /* */ + /* If `count' and `shift' are incommensurable, we */ + /* have a single chain only. Otherwise, increase */ + /* the start index by 1 after the first chain, then */ + /* do the next chain until all elements in all */ + /* chains are handled. */ + + start_idx = -1; + idx = -1; + for ( i = 0; i < count; i++ ) + { + CF2_StackNumber tmp; + + + if ( start_idx == idx ) + { + start_idx++; + idx = start_idx; + last = stack->buffer[idx]; + } + + idx += shift; + if ( idx >= count ) + idx -= count; + else if ( idx < 0 ) + idx += count; + + tmp = stack->buffer[idx]; + stack->buffer[idx] = last; + last = tmp; + } + } + + FT_LOCAL_DEF( void ) cf2_stack_clear( CF2_Stack stack ) { diff --git a/drivers/freetype/src/cff/cf2stack.h b/drivers/freetype/src/cff/cf2stack.h index 7d6d1961fe..e740a7ac41 100644 --- a/drivers/freetype/src/cff/cf2stack.h +++ b/drivers/freetype/src/cff/cf2stack.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2STACK_H__ -#define __CF2STACK_H__ +#ifndef CF2STACK_H_ +#define CF2STACK_H_ FT_BEGIN_HEADER @@ -93,6 +93,11 @@ FT_BEGIN_HEADER cf2_stack_getReal( CF2_Stack stack, CF2_UInt idx ); + FT_LOCAL( void ) + cf2_stack_roll( CF2_Stack stack, + CF2_Int count, + CF2_Int idx ); + FT_LOCAL( void ) cf2_stack_clear( CF2_Stack stack ); @@ -100,7 +105,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2STACK_H__ */ +#endif /* CF2STACK_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cf2types.h b/drivers/freetype/src/cff/cf2types.h index ac6a02266e..5b7e1239af 100644 --- a/drivers/freetype/src/cff/cf2types.h +++ b/drivers/freetype/src/cff/cf2types.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2TYPES_H__ -#define __CF2TYPES_H__ +#ifndef CF2TYPES_H_ +#define CF2TYPES_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -72,7 +72,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2TYPES_H__ */ +#endif /* CF2TYPES_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cff.c b/drivers/freetype/src/cff/cff.c index c3840b5838..86ca1be040 100644 --- a/drivers/freetype/src/cff/cff.c +++ b/drivers/freetype/src/cff/cff.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/cff/cffcmap.c b/drivers/freetype/src/cff/cffcmap.c index f6e03c6420..3ef48328c5 100644 --- a/drivers/freetype/src/cff/cffcmap.c +++ b/drivers/freetype/src/cff/cffcmap.c @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002-2007, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,12 +33,15 @@ /*************************************************************************/ FT_CALLBACK_DEF( FT_Error ) - cff_cmap_encoding_init( CFF_CMapStd cmap ) + cff_cmap_encoding_init( CFF_CMapStd cmap, + FT_Pointer pointer ) { TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); CFF_Font cff = (CFF_Font)face->extra.data; CFF_Encoding encoding = &cff->encoding; + FT_UNUSED( pointer ); + cmap->gids = encoding->codes; @@ -135,7 +138,8 @@ FT_CALLBACK_DEF( FT_Error ) - cff_cmap_unicode_init( PS_Unicodes unicodes ) + cff_cmap_unicode_init( PS_Unicodes unicodes, + FT_Pointer pointer ) { TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -143,6 +147,8 @@ CFF_Charset charset = &cff->charset; FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + FT_UNUSED( pointer ); + /* can't build Unicode map for CID-keyed font */ /* because we don't know glyph names. */ diff --git a/drivers/freetype/src/cff/cffcmap.h b/drivers/freetype/src/cff/cffcmap.h index 3f7f67bbe0..23795d5090 100644 --- a/drivers/freetype/src/cff/cffcmap.h +++ b/drivers/freetype/src/cff/cffcmap.h @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFCMAP_H__ -#define __CFFCMAP_H__ +#ifndef CFFCMAP_H_ +#define CFFCMAP_H_ #include "cffobjs.h" @@ -61,7 +61,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFCMAP_H__ */ +#endif /* CFFCMAP_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cffdrivr.c b/drivers/freetype/src/cff/cffdrivr.c index c8ca96ba49..950a9605c3 100644 --- a/drivers/freetype/src/cff/cffdrivr.c +++ b/drivers/freetype/src/cff/cffdrivr.c @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,7 @@ #include "cfferrs.h" #include "cffpic.h" -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_GLYPH_DICT_H #include FT_SERVICE_PROPERTIES_H #include FT_CFF_DRIVER_H @@ -64,11 +64,6 @@ /*************************************************************************/ -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - /*************************************************************************/ /* */ /* <Function> */ @@ -121,9 +116,6 @@ } -#undef PAIR_TAG - - /*************************************************************************/ /* */ /* <Function> */ @@ -164,6 +156,8 @@ if ( !slot ) return FT_THROW( Invalid_Slot_Handle ); + FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index )); + /* check whether we want a scaled outline or bitmap */ if ( !size ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; @@ -201,6 +195,68 @@ FT_GlyphSlot slot = face->glyph; + if ( FT_IS_SFNT( face ) ) + { + /* OpenType 1.7 mandates that the data from `hmtx' table be used; */ + /* it is no longer necessary that those values are identical to */ + /* the values in the `CFF' table */ + + TT_Face ttface = (TT_Face)face; + FT_Short dummy; + + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* check whether we have data from the `vmtx' table at all; */ + /* otherwise we extract the info from the CFF glyphstrings */ + /* (instead of synthesizing a global value using the `OS/2' */ + /* table) */ + if ( !ttface->vertical_info ) + goto Missing_Table; + + for ( nn = 0; nn < count; nn++ ) + { + FT_UShort ah; + + + ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, + 1, + start + nn, + &dummy, + &ah ); + + FT_TRACE5(( " idx %d: advance height %d font units\n", + start + nn, ah )); + advances[nn] = ah; + } + } + else + { + /* check whether we have data from the `hmtx' table at all */ + if ( !ttface->horizontal.number_Of_HMetrics ) + goto Missing_Table; + + for ( nn = 0; nn < count; nn++ ) + { + FT_UShort aw; + + + ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, + 0, + start + nn, + &dummy, + &aw ); + + FT_TRACE5(( " idx %d: advance width %d font units\n", + start + nn, aw )); + advances[nn] = aw; + } + } + + return error; + } + + Missing_Table: flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; for ( nn = 0; nn < count; nn++ ) @@ -302,8 +358,8 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( cff_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)cff_get_name_index + (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)cff_get_name_index /* name_index */ ) @@ -350,7 +406,7 @@ 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; + font_info->underline_thickness = (FT_UShort)dict->underline_thickness; cff->font_info = font_info; } @@ -365,11 +421,13 @@ FT_DEFINE_SERVICE_PSINFOREC( cff_service_ps_info, - (PS_GetFontInfoFunc) cff_ps_get_font_info, - (PS_GetFontExtraFunc) NULL, - (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, - (PS_GetFontPrivateFunc)NULL, /* unsupported with CFF fonts */ - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) cff_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) NULL, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, /* ps_has_glyph_names */ + /* unsupported with CFF fonts */ + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ ) @@ -381,16 +439,34 @@ static const char* cff_get_ps_name( CFF_Face face ) { - CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Font cff = (CFF_Font)face->extra.data; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + /* following the OpenType specification 1.7, we return the name stored */ + /* in the `name' table for a CFF wrapped into an SFNT container */ + + if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt ) + { + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); + FT_Service_PsFontName service = + (FT_Service_PsFontName)ft_module_get_service( + sfnt_module, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME ); + if ( service && service->get_ps_font_name ) + return service->get_ps_font_name( FT_FACE( face ) ); + } + return (const char*)cff->font_name; } FT_DEFINE_SERVICE_PSFONTNAMEREC( cff_service_ps_name, - (FT_PsName_GetFunc)cff_get_ps_name + (FT_PsName_GetFunc)cff_get_ps_name /* get_ps_font_name */ ) @@ -437,7 +513,7 @@ FT_DEFINE_SERVICE_TTCMAPSREC( cff_service_get_cmap_info, - (TT_CMap_Info_GetFunc)cff_get_cmap_info + (TT_CMap_Info_GetFunc)cff_get_cmap_info /* get_cmap_info */ ) @@ -567,9 +643,12 @@ FT_DEFINE_SERVICE_CIDREC( cff_service_cid_info, - (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index + (FT_CID_GetRegistryOrderingSupplementFunc) + cff_get_ros, /* get_ros */ + (FT_CID_GetIsInternallyCIDKeyedFunc) + cff_get_is_cid, /* get_is_cid */ + (FT_CID_GetCIDFromGlyphIndexFunc) + cff_get_cid_from_glyph_index /* get_cid_from_glyph_index */ ) @@ -586,17 +665,50 @@ CFF_Driver driver = (CFF_Driver)module; - if ( !ft_strcmp( property_name, "hinting-engine" ) ) + if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = (FT_Int*)value; + + FT_Int x1 = darken_params[0]; + FT_Int y1 = darken_params[1]; + FT_Int x2 = darken_params[2]; + FT_Int y2 = darken_params[3]; + FT_Int x3 = darken_params[4]; + FT_Int y3 = darken_params[5]; + FT_Int x4 = darken_params[6]; + FT_Int y4 = darken_params[7]; + + + if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || + y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || + x1 > x2 || x2 > x3 || x3 > x4 || + y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) + return FT_THROW( Invalid_Argument ); + + driver->darken_params[0] = x1; + driver->darken_params[1] = y1; + driver->darken_params[2] = x2; + driver->darken_params[3] = y2; + driver->darken_params[4] = x3; + driver->darken_params[5] = y3; + driver->darken_params[6] = x4; + driver->darken_params[7] = y4; + + return error; + } + else if ( !ft_strcmp( property_name, "hinting-engine" ) ) { FT_UInt* hinting_engine = (FT_UInt*)value; -#ifndef CFF_CONFIG_OPTION_OLD_ENGINE - if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) - error = FT_ERR( Unimplemented_Feature ); - else + if ( *hinting_engine == FT_CFF_HINTING_ADOBE +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + || *hinting_engine == FT_CFF_HINTING_FREETYPE #endif + ) driver->hinting_engine = *hinting_engine; + else + error = FT_ERR( Unimplemented_Feature ); return error; } @@ -624,13 +736,28 @@ FT_Error error = FT_Err_Ok; CFF_Driver driver = (CFF_Driver)module; - FT_UInt hinting_engine = driver->hinting_engine; - FT_Bool no_stem_darkening = driver->no_stem_darkening; + if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = driver->darken_params; + FT_Int* val = (FT_Int*)value; + + + val[0] = darken_params[0]; + val[1] = darken_params[1]; + val[2] = darken_params[2]; + val[3] = darken_params[3]; + val[4] = darken_params[4]; + val[5] = darken_params[5]; + val[6] = darken_params[6]; + val[7] = darken_params[7]; - if ( !ft_strcmp( property_name, "hinting-engine" ) ) + return error; + } + else if ( !ft_strcmp( property_name, "hinting-engine" ) ) { - FT_UInt* val = (FT_UInt*)value; + FT_UInt hinting_engine = driver->hinting_engine; + FT_UInt* val = (FT_UInt*)value; *val = hinting_engine; @@ -639,7 +766,8 @@ } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { - FT_Bool* val = (FT_Bool*)value; + FT_Bool no_stem_darkening = driver->no_stem_darkening; + FT_Bool* val = (FT_Bool*)value; *val = no_stem_darkening; @@ -655,8 +783,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( cff_service_properties, - (FT_Properties_SetFunc)cff_property_set, - (FT_Properties_GetFunc)cff_property_get ) + (FT_Properties_SetFunc)cff_property_set, /* set_property */ + (FT_Properties_GetFunc)cff_property_get ) /* get_property */ /*************************************************************************/ @@ -674,7 +802,7 @@ #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES FT_DEFINE_SERVICEDESCREC7( cff_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, @@ -685,7 +813,7 @@ #else FT_DEFINE_SERVICEDESCREC6( cff_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, @@ -704,7 +832,7 @@ FT_Module_Interface result; - /* CFF_SERVICES_GET derefers `library' in PIC mode */ + /* CFF_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC if ( !driver ) return NULL; @@ -744,9 +872,10 @@ FT_DEFINE_DRIVER( cff_driver_class, - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - FT_MODULE_DRIVER_HAS_HINTER, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER | + FT_MODULE_DRIVER_HINTS_LIGHTLY, sizeof ( CFF_DriverRec ), "cff", @@ -755,31 +884,29 @@ 0, /* module-specific interface */ - cff_driver_init, - cff_driver_done, - cff_get_interface, + cff_driver_init, /* FT_Module_Constructor module_init */ + cff_driver_done, /* FT_Module_Destructor module_done */ + cff_get_interface, /* FT_Module_Requester get_interface */ - /* now the specific driver fields */ sizeof ( TT_FaceRec ), sizeof ( CFF_SizeRec ), sizeof ( CFF_GlyphSlotRec ), - cff_face_init, - cff_face_done, - cff_size_init, - cff_size_done, - cff_slot_init, - cff_slot_done, - - cff_glyph_load, + cff_face_init, /* FT_Face_InitFunc init_face */ + cff_face_done, /* FT_Face_DoneFunc done_face */ + cff_size_init, /* FT_Size_InitFunc init_size */ + cff_size_done, /* FT_Size_DoneFunc done_size */ + cff_slot_init, /* FT_Slot_InitFunc init_slot */ + cff_slot_done, /* FT_Slot_DoneFunc done_slot */ - cff_get_kerning, - 0, /* FT_Face_AttachFunc */ - cff_get_advances, + cff_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - cff_size_request, + cff_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + cff_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - CFF_SIZE_SELECT + cff_size_request, /* FT_Size_RequestFunc request_size */ + CFF_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/drivers/freetype/src/cff/cffdrivr.h b/drivers/freetype/src/cff/cffdrivr.h index 50e8138701..d7b0598374 100644 --- a/drivers/freetype/src/cff/cffdrivr.h +++ b/drivers/freetype/src/cff/cffdrivr.h @@ -4,7 +4,7 @@ /* */ /* High-level OpenType driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFDRIVER_H__ -#define __CFFDRIVER_H__ +#ifndef CFFDRIVER_H_ +#define CFFDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFDRIVER_H__ */ +#endif /* CFFDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cfferrs.h b/drivers/freetype/src/cff/cfferrs.h index 801d73ec6b..e7fc6eb71c 100644 --- a/drivers/freetype/src/cff/cfferrs.h +++ b/drivers/freetype/src/cff/cfferrs.h @@ -4,7 +4,7 @@ /* */ /* CFF error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __CFFERRS_H__ -#define __CFFERRS_H__ +#ifndef CFFERRS_H_ +#define CFFERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CFF_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __CFFERRS_H__ */ +#endif /* CFFERRS_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cffgload.c b/drivers/freetype/src/cff/cffgload.c index 6a8494fa9f..752c18ed92 100644 --- a/drivers/freetype/src/cff/cffgload.c +++ b/drivers/freetype/src/cff/cffgload.c @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -273,8 +273,8 @@ builder->current = &loader->current.outline; FT_GlyphLoader_Rewind( loader ); - builder->hints_globals = 0; - builder->hints_funcs = 0; + builder->hints_globals = NULL; + builder->hints_funcs = NULL; if ( hinting && size ) { @@ -434,7 +434,7 @@ goto Exit; } - FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index )); + FT_TRACE3(( " in subfont %d:\n", fd_index )); sub = cff->subfonts[fd_index]; @@ -447,10 +447,6 @@ builder->hints_globals = (void *)internal->subfonts[fd_index]; } } -#ifdef FT_DEBUG_LEVEL_TRACE - else - FT_TRACE3(( "glyph index %d:\n", glyph_index )); -#endif decoder->num_locals = sub->local_subrs_index.count; decoder->locals = sub->local_subrs; @@ -650,7 +646,7 @@ for ( n = 0; n < cff->num_glyphs; n++ ) { if ( cff->charset.sids[n] == glyph_sid ) - return n; + return (FT_Int)n; } return -1; @@ -676,7 +672,7 @@ *pointer = (FT_Byte*)data.pointer; - *length = data.length; + *length = (FT_ULong)data.length; return error; } @@ -684,7 +680,7 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ { - CFF_Font cff = (CFF_Font)(face->extra.data); + CFF_Font cff = (CFF_Font)(face->extra.data); return cff_index_access_element( &cff->charstrings_index, glyph_index, @@ -707,11 +703,11 @@ /* callback function. */ if ( face->root.internal->incremental_interface ) { - FT_Data data; + FT_Data data; data.pointer = *pointer; - data.length = length; + data.length = (FT_Int)length; face->root.internal->incremental_interface->funcs->free_glyph_data( face->root.internal->incremental_interface->object, &data ); @@ -823,14 +819,14 @@ FT_GlyphLoader_Prepare( builder->loader ); /* First load `bchar' in builder */ - error = cff_get_glyph_data( face, bchar_index, + error = cff_get_glyph_data( face, (FT_UInt)bchar_index, &charstring, &charstring_len ); if ( !error ) { /* the seac operator must not be nested */ decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); + charstring_len, 0 ); decoder->seac = FALSE; cff_free_glyph_data( face, &charstring, charstring_len ); @@ -853,14 +849,14 @@ builder->pos_y = ady; /* Now load `achar' on top of the base outline. */ - error = cff_get_glyph_data( face, achar_index, + error = cff_get_glyph_data( face, (FT_UInt)achar_index, &charstring, &charstring_len ); if ( !error ) { /* the seac operator must not be nested */ decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); + charstring_len, 0 ); decoder->seac = FALSE; cff_free_glyph_data( face, &charstring, charstring_len ); @@ -899,13 +895,17 @@ /* */ /* charstring_len :: The length in bytes of the charstring stream. */ /* */ + /* in_dict :: Set to 1 if function is called from top or */ + /* private DICT (needed for Multiple Master CFFs). */ + /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) cff_decoder_parse_charstrings( CFF_Decoder* decoder, FT_Byte* charstring_base, - FT_ULong charstring_len ) + FT_ULong charstring_len, + FT_Bool in_dict ) { FT_Error error; CFF_Decoder_Zone* zone; @@ -917,6 +917,10 @@ FT_Fixed* stack; FT_Int charstring_type = decoder->cff->top_font.font_dict.charstring_type; + FT_UShort num_designs = + decoder->cff->top_font.font_dict.num_designs; + FT_UShort num_axes = + decoder->cff->top_font.font_dict.num_axes; T2_Hints_Funcs hinter; @@ -926,10 +930,10 @@ decoder->read_width = 1; /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ - (FT_PtrDist)(char*)&decoder ^ - (FT_PtrDist)(char*)&charstring_base ) & - FT_ULONG_MAX ) ; + seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed ^ + (FT_Offset)(char*)&decoder ^ + (FT_Offset)(char*)&charstring_base ) & + FT_ULONG_MAX ); seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; if ( seed == 0 ) seed = 0x7384; @@ -1245,6 +1249,44 @@ if ( op == cff_op_unknown ) continue; + /* in Multiple Master CFFs, T2 charstrings can appear in */ + /* dictionaries, but some operators are prohibited */ + if ( in_dict ) + { + switch ( op ) + { + case cff_op_hstem: + case cff_op_vstem: + case cff_op_vmoveto: + case cff_op_rlineto: + case cff_op_hlineto: + case cff_op_vlineto: + case cff_op_rrcurveto: + case cff_op_hstemhm: + case cff_op_hintmask: + case cff_op_cntrmask: + case cff_op_rmoveto: + case cff_op_hmoveto: + case cff_op_vstemhm: + case cff_op_rcurveline: + case cff_op_rlinecurve: + case cff_op_vvcurveto: + case cff_op_hhcurveto: + case cff_op_vhcurveto: + case cff_op_hvcurveto: + case cff_op_hflex: + case cff_op_flex: + case cff_op_hflex1: + case cff_op_flex1: + case cff_op_callsubr: + case cff_op_callgsubr: + goto MM_Error; + + default: + break; + } + } + /* check arguments */ req_args = cff_argument_counts[op]; if ( req_args & CFF_COUNT_CHECK_WIDTH ) @@ -1282,7 +1324,9 @@ case cff_op_endchar: /* If there is a width specified for endchar, we either have */ /* 1 argument or 5 arguments. We like to argue. */ - set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); + set_width_ok = in_dict + ? 0 + : ( ( num_args == 5 ) || ( num_args == 1 ) ); break; default: @@ -1377,12 +1421,12 @@ { if ( op == cff_op_hintmask ) hinter->hintmask( hinter->hints, - builder->current->n_points, - decoder->num_hints, + (FT_UInt)builder->current->n_points, + (FT_UInt)decoder->num_hints, ip ); else hinter->counter( hinter->hints, - decoder->num_hints, + (FT_UInt)decoder->num_hints, ip ); } @@ -1975,6 +2019,10 @@ return error; case cff_op_endchar: + /* in dictionaries, `endchar' simply indicates end of data */ + if ( in_dict ) + return error; + FT_TRACE4(( " endchar\n" )); /* We are going to emulate the seac operator. */ @@ -1993,23 +2041,22 @@ } else { - if ( !error ) - error = FT_Err_Ok; - cff_builder_close_contour( builder ); /* close hints recording session */ if ( hinter ) { if ( hinter->close( hinter->hints, - builder->current->n_points ) ) + (FT_UInt)builder->current->n_points ) ) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ - hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_mode ); + error = hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + if ( error ) + goto Fail; } /* add current outline to the glyph slot */ @@ -2087,15 +2134,14 @@ if ( args[0] > 0 ) { - FT_Int count = 9; - FT_Fixed root = args[0]; + FT_Fixed root = args[0]; FT_Fixed new_root; for (;;) { new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; - if ( new_root == root || count <= 0 ) + if ( new_root == root ) break; root = new_root; } @@ -2204,6 +2250,10 @@ FT_TRACE4(( " put\n" )); + /* the Type2 specification before version 16-March-2000 */ + /* didn't give a hard-coded size limit of the temporary */ + /* storage array; instead, an argument of the */ + /* `MultipleMaster' operator set the size */ if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) decoder->buildchar[idx] = val; } @@ -2226,14 +2276,68 @@ break; case cff_op_store: - FT_TRACE4(( " store\n")); + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ - goto Unimplemented; + /* since we currently don't handle interpolation of multiple */ + /* master fonts, this is a no-op */ + FT_TRACE4(( " store\n")); + break; case cff_op_load: - FT_TRACE4(( " load\n" )); + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + { + FT_Int reg_idx = (FT_Int)args[0]; + FT_Int idx = (FT_Int)args[1]; + FT_Int count = (FT_Int)args[2]; - goto Unimplemented; + + FT_TRACE4(( " load\n" )); + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, we store a vector [1 0 0 ...] in the */ + /* temporary storage array regardless of the Registry index */ + if ( reg_idx >= 0 && reg_idx <= 2 && + idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS && + count >= 0 && count <= num_axes ) + { + FT_Int end, i; + + + end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS ); + + if ( idx < end ) + decoder->buildchar[idx] = 1 << 16; + + for ( i = idx + 1; i < end; i++ ) + decoder->buildchar[i] = 0; + } + } + break; + + case cff_op_blend: + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + { + FT_Int num_results = (FT_Int)( args[0] >> 16 ); + + + FT_TRACE4(( " blend\n" )); + + if ( num_results < 0 ) + goto Syntax_Error; + + if ( num_results * (FT_Int)num_designs > num_args ) + goto Stack_Underflow; + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, return the `num_results' values of the */ + /* first master */ + args -= num_results * ( num_designs - 1 ); + num_args -= num_results * ( num_designs - 1 ); + } + break; case cff_op_dotsection: /* this operator is deprecated and ignored by the parser */ @@ -2363,11 +2467,23 @@ } break; - case cff_op_eq: + case cff_op_not: { FT_Fixed cond = !args[0]; + FT_TRACE4(( " not\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_eq: + { + FT_Fixed cond = args[0] == args[1]; + + FT_TRACE4(( " eq\n" )); args[0] = cond ? 0x10000L : 0; @@ -2394,7 +2510,9 @@ decoder->locals_bias ); - FT_TRACE4(( " callsubr(%d)\n", idx )); + FT_TRACE4(( " callsubr (idx %d, entering level %d)\n", + idx, + zone - decoder->zones + 1 )); if ( idx >= decoder->num_locals ) { @@ -2436,7 +2554,9 @@ decoder->globals_bias ); - FT_TRACE4(( " callgsubr(%d)\n", idx )); + FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n", + idx, + zone - decoder->zones + 1 )); if ( idx >= decoder->num_globals ) { @@ -2473,7 +2593,8 @@ break; case cff_op_return: - FT_TRACE4(( " return\n" )); + FT_TRACE4(( " return (leaving level %d)\n", + decoder->zone - decoder->zones )); if ( decoder->zone <= decoder->zones ) { @@ -2489,7 +2610,6 @@ break; default: - Unimplemented: FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); if ( ip[-1] == 12 ) @@ -2513,6 +2633,11 @@ Fail: return error; + MM_Error: + FT_TRACE4(( "cff_decoder_parse_charstrings:" + " invalid opcode found in top DICT charstring\n")); + return FT_THROW( Invalid_File_Format ); + Syntax_Error: FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); return FT_THROW( Invalid_File_Format ); @@ -2586,7 +2711,8 @@ if ( !error ) error = cff_decoder_parse_charstrings( &decoder, charstring, - charstring_len ); + charstring_len, + 0 ); cff_free_glyph_data( face, &charstring, &charstring_len ); } @@ -2674,7 +2800,7 @@ error = sfnt->load_sbit_image( face, size->strike_index, glyph_index, - (FT_Int)load_flags, + (FT_UInt)load_flags, stream, &glyph->root.bitmap, &metrics ); @@ -2715,23 +2841,23 @@ /* compute linear advance widths */ - ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, - glyph_index, - &dummy, - &advance ); + (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 0, + glyph_index, + &dummy, + &advance ); glyph->root.linearHoriAdvance = advance; has_vertical_info = FT_BOOL( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ); - /* get the vertical metrics from the vtmx table if we have one */ + /* get the vertical metrics from the vmtx table if we have one */ if ( has_vertical_info ) { - ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, - glyph_index, - &dummy, - &advance ); + (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1, + glyph_index, + &dummy, + &advance ); glyph->root.linearVertAdvance = advance; } else @@ -2762,16 +2888,16 @@ /* this scaling is only relevant if the PS hinter isn't active */ if ( cff->num_subfonts ) { - FT_ULong top_upm, sub_upm; - FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, - glyph_index ); + FT_Long top_upm, sub_upm; + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, + glyph_index ); if ( fd_index >= cff->num_subfonts ) fd_index = (FT_Byte)( cff->num_subfonts - 1 ); - top_upm = cff->top_font.font_dict.units_per_em; - sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; + top_upm = (FT_Long)cff->top_font.font_dict.units_per_em; + sub_upm = (FT_Long)cff->subfonts[fd_index]->font_dict.units_per_em; font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; @@ -2837,7 +2963,8 @@ if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) error = cff_decoder_parse_charstrings( &decoder, charstring, - charstring_len ); + charstring_len, + 0 ); else #endif { @@ -2872,7 +2999,7 @@ /* fonts. */ if ( face->root.internal->incremental_interface ) { - glyph->root.control_data = 0; + glyph->root.control_data = NULL; glyph->root.control_len = 0; } else @@ -2889,7 +3016,7 @@ { glyph->root.control_data = csindex->bytes + csindex->offsets[glyph_index] - 1; - glyph->root.control_len = charstring_len; + glyph->root.control_len = (FT_Long)charstring_len; } } @@ -2949,19 +3076,36 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &glyph->root.metrics; - FT_Vector advance; FT_Bool has_vertical_info; - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.glyph_width; - glyph->root.linearHoriAdvance = decoder.glyph_width; + if ( face->horizontal.number_Of_HMetrics ) + { + FT_Short horiBearingX = 0; + FT_UShort horiAdvance = 0; + + + ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, + glyph_index, + &horiBearingX, + &horiAdvance ); + metrics->horiAdvance = horiAdvance; + metrics->horiBearingX = horiBearingX; + glyph->root.linearHoriAdvance = horiAdvance; + } + else + { + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.glyph_width; + glyph->root.linearHoriAdvance = decoder.glyph_width; + } + glyph->root.internal->glyph_transformed = 0; has_vertical_info = FT_BOOL( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ); - /* get the vertical metrics from the vtmx table if we have one */ + /* get the vertical metrics from the vmtx table if we have one */ if ( has_vertical_info ) { FT_Short vertBearingY = 0; @@ -2996,26 +3140,27 @@ glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; - if ( !( font_matrix.xx == 0x10000L && - font_matrix.yy == 0x10000L && - font_matrix.xy == 0 && - font_matrix.yx == 0 ) ) + /* apply the font matrix, if any */ + if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + { FT_Outline_Transform( &glyph->root.outline, &font_matrix ); - if ( !( font_offset.x == 0 && - font_offset.y == 0 ) ) - FT_Outline_Translate( &glyph->root.outline, - font_offset.x, font_offset.y ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, + font_matrix.xx ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, + font_matrix.yy ); + } - advance.x = metrics->horiAdvance; - advance.y = 0; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->horiAdvance = advance.x + font_offset.x; + if ( font_offset.x || font_offset.y ) + { + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, + font_offset.y ); - advance.x = 0; - advance.y = metrics->vertAdvance; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->vertAdvance = advance.y + font_offset.y; + metrics->horiAdvance += font_offset.x; + metrics->vertAdvance += font_offset.y; + } if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) { diff --git a/drivers/freetype/src/cff/cffgload.h b/drivers/freetype/src/cff/cffgload.h index 41df7db692..b875fbed90 100644 --- a/drivers/freetype/src/cff/cffgload.h +++ b/drivers/freetype/src/cff/cffgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2004, 2006-2009, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFGLOAD_H__ -#define __CFFGLOAD_H__ +#ifndef CFFGLOAD_H_ +#define CFFGLOAD_H_ #include <ft2build.h> @@ -29,7 +29,12 @@ FT_BEGIN_HEADER #define CFF_MAX_OPERANDS 48 -#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */ + /* only 10 are allowed but there exist */ + /* fonts like `HiraKakuProN-W3.ttf' */ + /* (Hiragino Kaku Gothic ProN W3; */ + /* 8.2d6e1; 2014-12-19) that exceed */ + /* this limit */ #define CFF_MAX_TRANS_ELEMENTS 32 @@ -222,7 +227,8 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) cff_decoder_parse_charstrings( CFF_Decoder* decoder, FT_Byte* charstring_base, - FT_ULong charstring_len ); + FT_ULong charstring_len, + FT_Bool in_dict ); #endif FT_LOCAL( FT_Error ) @@ -234,7 +240,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFGLOAD_H__ */ +#endif /* CFFGLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cffload.c b/drivers/freetype/src/cff/cffload.c index 64b497168d..3d1bda97b9 100644 --- a/drivers/freetype/src/cff/cffload.c +++ b/drivers/freetype/src/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -357,7 +357,7 @@ case 3: for ( ; p < p_end; p += 3, poff++ ) - poff[0] = FT_PEEK_OFF3( p ); + poff[0] = FT_PEEK_UOFF3( p ); break; default: @@ -382,13 +382,15 @@ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, - FT_Byte** pool ) + FT_Byte** pool, + FT_ULong* pool_size ) { FT_Error error = FT_Err_Ok; FT_Memory memory = idx->stream->memory; FT_Byte** t = NULL; FT_Byte* new_bytes = NULL; + FT_ULong new_size; *table = NULL; @@ -400,10 +402,11 @@ goto Exit; } - if ( idx->count > 0 && - !FT_NEW_ARRAY( t, idx->count + 1 ) && - ( !pool || !FT_ALLOC( new_bytes, - idx->data_size + idx->count ) ) ) + new_size = idx->data_size + idx->count; + + if ( idx->count > 0 && + !FT_NEW_ARRAY( t, idx->count + 1 ) && + ( !pool || !FT_ALLOC( new_bytes, new_size ) ) ) { FT_ULong n, cur_offset; FT_ULong extra = 0; @@ -414,7 +417,7 @@ cur_offset = idx->offsets[0] - 1; /* sanity check */ - if ( cur_offset >= idx->data_size ) + if ( cur_offset != 0 ) { FT_TRACE0(( "cff_index_get_pointers:" " invalid first offset value %d set to zero\n", @@ -432,11 +435,11 @@ FT_ULong next_offset = idx->offsets[n] - 1; - /* empty slot + two sanity checks for invalid offset tables */ - if ( next_offset == 0 || - next_offset < cur_offset || - ( next_offset >= idx->data_size && n < idx->count ) ) + /* two sanity checks for invalid offset tables */ + if ( next_offset < cur_offset ) next_offset = cur_offset; + else if ( next_offset > idx->data_size ) + next_offset = idx->data_size; if ( !pool ) t[n] = org_bytes + next_offset; @@ -459,6 +462,8 @@ if ( pool ) *pool = new_bytes; + if ( pool_size ) + *pool_size = new_size; } Exit: @@ -501,8 +506,8 @@ { element++; off2 = cff_index_read_offset( idx, &error ); - } - while ( off2 == 0 && element < idx->count ); + + } while ( off2 == 0 && element < idx->count ); } } else /* use offsets table */ @@ -689,6 +694,13 @@ if ( FT_READ_USHORT( num_ranges ) ) goto Exit; + if ( !num_ranges ) + { + FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + fdselect->data_size = num_ranges * 3 + 2; Load_Data: @@ -719,7 +731,7 @@ break; case 3: - /* first, compare to cache */ + /* first, compare to the cache */ if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < fdselect->cache_count ) { @@ -727,7 +739,7 @@ break; } - /* then, lookup the ranges array */ + /* then, look up the ranges array */ { FT_Byte* p = fdselect->data; FT_Byte* p_limit = p + fdselect->data_size; @@ -750,7 +762,7 @@ /* update cache */ fdselect->cache_first = first; - fdselect->cache_count = limit-first; + fdselect->cache_count = limit - first; fdselect->cache_fd = fd2; break; } @@ -802,7 +814,7 @@ /* When multiple GIDs map to the same CID, we choose the lowest */ /* GID. This is not described in any spec, but it matches the */ /* behaviour of recent Acroread versions. */ - for ( j = num_glyphs - 1; j >= 0 ; j-- ) + for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- ) charset->cids[charset->sids[j]] = (FT_UShort)j; charset->max_cid = max_cid; @@ -864,8 +876,8 @@ FT_UShort glyph_sid; - /* If the the offset is greater than 2, we have to parse the */ - /* charset table. */ + /* If the offset is greater than 2, we have to parse the charset */ + /* table. */ if ( offset > 2 ) { FT_UInt j; @@ -1309,7 +1321,12 @@ CFF_Private priv = &font->private_dict; - cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); + cff_parser_init( &parser, + CFF_CODE_TOPDICT, + &font->font_dict, + library, + 0, + 0 ); /* set defaults */ FT_MEM_ZERO( top, sizeof ( *top ) ); @@ -1363,7 +1380,12 @@ priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); + cff_parser_init( &parser, + CFF_CODE_PRIVATE, + priv, + library, + top->num_designs, + top->num_axes ); if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || FT_FRAME_ENTER( font->font_dict.private_size ) ) @@ -1393,7 +1415,7 @@ goto Exit; error = cff_index_get_pointers( &font->local_subrs_index, - &font->local_subrs, NULL ); + &font->local_subrs, NULL, NULL ); if ( error ) goto Exit; } @@ -1440,7 +1462,7 @@ FT_ULong base_offset; CFF_FontRecDict dict; CFF_IndexRec string_index; - FT_Int subfont_index; + FT_UInt subfont_index; FT_ZERO( font ); @@ -1471,16 +1493,17 @@ /* read the name, top dict, string and global subrs index */ if ( FT_SET_ERROR( cff_index_init( &font->name_index, - stream, 0 ) ) || + stream, 0 ) ) || FT_SET_ERROR( cff_index_init( &font->font_dict_index, - stream, 0 ) ) || + stream, 0 ) ) || FT_SET_ERROR( cff_index_init( &string_index, - stream, 1 ) ) || + stream, 1 ) ) || FT_SET_ERROR( cff_index_init( &font->global_subrs_index, - stream, 1 ) ) || + stream, 1 ) ) || FT_SET_ERROR( cff_index_get_pointers( &string_index, &font->strings, - &font->string_pool ) ) ) + &font->string_pool, + &font->string_pool_size ) ) ) goto Exit; font->num_strings = string_index.count; @@ -1488,9 +1511,9 @@ if ( pure_cff ) { /* well, we don't really forget the `disabled' fonts... */ - subfont_index = face_index; + subfont_index = (FT_UInt)( face_index & 0xFFFF ); - if ( subfont_index >= (FT_Int)font->name_index.count ) + if ( face_index > 0 && subfont_index >= font->name_index.count ) { FT_ERROR(( "cff_font_load:" " invalid subfont index for pure CFF font (%d)\n", @@ -1607,7 +1630,7 @@ font->num_glyphs = font->charstrings_index.count; error = cff_index_get_pointers( &font->global_subrs_index, - &font->global_subrs, NULL ); + &font->global_subrs, NULL, NULL ); if ( error ) goto Exit; diff --git a/drivers/freetype/src/cff/cffload.h b/drivers/freetype/src/cff/cffload.h index 804961964b..1dd07baf11 100644 --- a/drivers/freetype/src/cff/cffload.h +++ b/drivers/freetype/src/cff/cffload.h @@ -4,7 +4,7 @@ /* */ /* OpenType & CFF data/program tables loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2007, 2008, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFLOAD_H__ -#define __CFFLOAD_H__ +#ifndef CFFLOAD_H_ +#define CFFLOAD_H_ #include <ft2build.h> @@ -77,7 +77,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFLOAD_H__ */ +#endif /* CFFLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cffobjs.c b/drivers/freetype/src/cff/cffobjs.c index dd750d1041..0f0769677f 100644 --- a/drivers/freetype/src/cff/cffobjs.c +++ b/drivers/freetype/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -226,8 +226,8 @@ CFF_Font font = (CFF_Font)face->extra.data; CFF_Internal internal = (CFF_Internal)size->internal; - FT_ULong top_upm = font->top_font.font_dict.units_per_em; - FT_UInt i; + FT_Long top_upm = (FT_Long)font->top_font.font_dict.units_per_em; + FT_UInt i; funcs->set_scale( internal->topfont, @@ -237,7 +237,7 @@ for ( i = font->num_subfonts; i > 0; i-- ) { CFF_SubFont sub = font->subfonts[i - 1]; - FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Long sub_upm = (FT_Long)sub->font_dict.units_per_em; FT_Pos x_scale, y_scale; @@ -298,8 +298,8 @@ CFF_Font font = (CFF_Font)cffface->extra.data; CFF_Internal internal = (CFF_Internal)size->internal; - FT_ULong top_upm = font->top_font.font_dict.units_per_em; - FT_UInt i; + FT_Long top_upm = (FT_Long)font->top_font.font_dict.units_per_em; + FT_UInt i; funcs->set_scale( internal->topfont, @@ -309,7 +309,7 @@ for ( i = font->num_subfonts; i > 0; i-- ) { CFF_SubFont sub = font->subfonts[i - 1]; - FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Long sub_upm = (FT_Long)sub->font_dict.units_per_em; FT_Pos x_scale, y_scale; @@ -342,7 +342,7 @@ FT_LOCAL_DEF( void ) cff_slot_done( FT_GlyphSlot slot ) { - slot->internal->glyph_hints = 0; + slot->internal->glyph_hints = NULL; } @@ -583,16 +583,24 @@ if ( error ) goto Exit; + /* if we are performing a simple font format check, exit immediately */ + /* (this is here for pure CFF) */ + if ( face_index < 0 ) + { + cffface->num_faces = (FT_Long)cff->num_faces; + return FT_Err_Ok; + } + cff->pshinter = pshinter; cff->psnames = psnames; - cffface->face_index = face_index; + cffface->face_index = face_index & 0xFFFF; /* Complement the root flags with some interesting information. */ /* Note that this is only necessary for pure CFF and CEF fonts; */ /* SFNT based fonts use the `name' table instead. */ - cffface->num_glyphs = cff->num_glyphs; + cffface->num_glyphs = (FT_Long)cff->num_glyphs; dict = &cff->top_font.font_dict; @@ -617,11 +625,44 @@ FT_TRACE4(( "SIDs\n" )); /* dump string index, including default strings for convenience */ - for ( idx = 0; idx < cff->num_strings + 390; idx++ ) + for ( idx = 0; idx <= 390; idx++ ) { s = cff_index_get_sid_string( cff, idx ); if ( s ) - FT_TRACE4((" %5d %s\n", idx, s )); + FT_TRACE4(( " %5d %s\n", idx, s )); + } + + /* In Multiple Master CFFs, two SIDs hold the Normalize Design */ + /* Vector (NDV) and Convert Design Vector (CDV) charstrings, */ + /* which may contain NULL bytes in the middle of the data, too. */ + /* We thus access `cff->strings' directly. */ + for ( idx = 1; idx < cff->num_strings; idx++ ) + { + FT_Byte* s1 = cff->strings[idx - 1]; + FT_Byte* s2 = cff->strings[idx]; + FT_PtrDist s1len = s2 - s1 - 1; /* without the final NULL byte */ + FT_PtrDist l; + + + FT_TRACE4(( " %5d ", idx + 390 )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); + } + + /* print last element */ + if ( cff->num_strings ) + { + FT_Byte* s1 = cff->strings[cff->num_strings - 1]; + FT_Byte* s2 = cff->string_pool + cff->string_pool_size; + FT_PtrDist s1len = s2 - s1 - 1; + FT_PtrDist l; + + + FT_TRACE4(( " %5d ", cff->num_strings + 390 )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); } } #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -629,10 +670,11 @@ if ( !dict->has_font_matrix ) dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; - /* Normalize the font matrix so that `matrix->xx' is 1; the */ - /* scaling is done with `units_per_em' then (at this point, */ - /* it already contains the scaling factor, but without */ - /* normalization of the matrix). */ + /* Normalize the font matrix so that `matrix->yy' is 1; if */ + /* it is zero, we use `matrix->yx' instead. The scaling is */ + /* done with `units_per_em' then (at this point, it already */ + /* contains the scaling factor, but without normalization */ + /* of the matrix). */ /* */ /* Note that the offsets must be expressed in integer font */ /* units. */ @@ -641,12 +683,15 @@ FT_Matrix* matrix = &dict->font_matrix; FT_Vector* offset = &dict->font_offset; FT_ULong* upm = &dict->units_per_em; - FT_Fixed temp = FT_ABS( matrix->yy ); + FT_Fixed temp; + temp = matrix->yy ? FT_ABS( matrix->yy ) + : FT_ABS( matrix->yx ); + if ( temp != 0x10000L ) { - *upm = FT_DivFix( *upm, temp ); + *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp ); matrix->xx = FT_DivFix( matrix->xx, temp ); matrix->yx = FT_DivFix( matrix->yx, temp ); @@ -682,7 +727,8 @@ if ( top->has_font_matrix ) { if ( top->units_per_em > 1 && sub->units_per_em > 1 ) - scaling = FT_MIN( top->units_per_em, sub->units_per_em ); + scaling = (FT_Long)FT_MIN( top->units_per_em, + sub->units_per_em ); else scaling = 1; @@ -693,9 +739,10 @@ &top->font_matrix, scaling ); - sub->units_per_em = FT_MulDiv( sub->units_per_em, - top->units_per_em, - scaling ); + sub->units_per_em = (FT_ULong) + FT_MulDiv( (FT_Long)sub->units_per_em, + (FT_Long)top->units_per_em, + scaling ); } } else @@ -709,11 +756,14 @@ matrix = &sub->font_matrix; offset = &sub->font_offset; upm = &sub->units_per_em; - temp = FT_ABS( matrix->yy ); + + temp = matrix->yy ? FT_ABS( matrix->yy ) + : FT_ABS( matrix->yx ); + if ( temp != 0x10000L ) { - *upm = FT_DivFix( *upm, temp ); + *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp ); matrix->xx = FT_DivFix( matrix->xx, temp ); matrix->yx = FT_DivFix( matrix->yx, temp ); @@ -733,13 +783,13 @@ /* set up num_faces */ - cffface->num_faces = cff->num_faces; + cffface->num_faces = (FT_Long)cff->num_faces; /* compute number of glyphs */ if ( dict->cid_registry != 0xFFFFU ) - cffface->num_glyphs = cff->charset.max_cid + 1; + cffface->num_glyphs = (FT_Long)( cff->charset.max_cid + 1 ); else - cffface->num_glyphs = cff->charstrings_index.count; + cffface->num_glyphs = (FT_Long)cff->charstrings_index.count; /* set global bbox, as well as EM size */ cffface->bbox.xMin = dict->font_bbox.xMin >> 16; @@ -763,7 +813,9 @@ (FT_Short)( dict->underline_thickness >> 16 ); /* retrieve font family & style name */ - cffface->family_name = cff_index_get_name( cff, face_index ); + cffface->family_name = cff_index_get_name( + cff, + (FT_UInt)( face_index & 0xFFFF ) ); if ( cffface->family_name ) { char* full = cff_index_get_sid_string( cff, @@ -866,7 +918,7 @@ flags |= FT_FACE_FLAG_KERNING; #endif - cffface->face_flags = flags; + cffface->face_flags |= flags; /*******************************************************************/ /* */ @@ -943,16 +995,6 @@ if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) goto Exit; -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "cff_face_init: no Unicode cmap is found, " - "and too many subtables (%d) to add synthesized cmap\n", - nn )); - goto Exit; - } -#endif - /* we didn't find a Unicode charmap -- synthesize one */ cmaprec.face = cffface; cmaprec.platform_id = TT_PLATFORM_MICROSOFT; @@ -973,15 +1015,6 @@ cffface->charmap = cffface->charmaps[nn]; Skip_Unicode: -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( nn > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "cff_face_init: Unicode cmap is found, " - "but too many preceding subtables (%d) to access\n", - nn - 1 )); - goto Exit; - } -#endif if ( encoding->count > 0 ) { FT_CMap_Class clazz; @@ -1055,13 +1088,23 @@ CFF_Driver driver = (CFF_Driver)module; - /* set default property values */ + /* set default property values, cf. `ftcffdrv.h' */ #ifdef CFF_CONFIG_OPTION_OLD_ENGINE - driver->hinting_engine = FT_CFF_HINTING_FREETYPE; + driver->hinting_engine = FT_CFF_HINTING_FREETYPE; #else - driver->hinting_engine = FT_CFF_HINTING_ADOBE; + driver->hinting_engine = FT_CFF_HINTING_ADOBE; #endif - driver->no_stem_darkening = FALSE; + + driver->no_stem_darkening = TRUE; + + driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; + driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; + driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; + driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; + driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; + driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; + driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; return FT_Err_Ok; } diff --git a/drivers/freetype/src/cff/cffobjs.h b/drivers/freetype/src/cff/cffobjs.h index b375c20c74..9dc77536bd 100644 --- a/drivers/freetype/src/cff/cffobjs.h +++ b/drivers/freetype/src/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2004, 2006-2008, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFOBJS_H__ -#define __CFFOBJS_H__ +#ifndef CFFOBJS_H_ +#define CFFOBJS_H_ #include <ft2build.h> @@ -121,6 +121,8 @@ FT_BEGIN_HEADER FT_UInt hinting_engine; FT_Bool no_stem_darkening; + FT_Int darken_params[8]; + } CFF_DriverRec; @@ -177,7 +179,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFOBJS_H__ */ +#endif /* CFFOBJS_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cffparse.c b/drivers/freetype/src/cff/cffparse.c index 96222120b0..a4f986b67c 100644 --- a/drivers/freetype/src/cff/cffparse.c +++ b/drivers/freetype/src/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2004, 2007-2013 by */ +/* Copyright 1996-2016 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 "cfferrs.h" #include "cffpic.h" +#include "cffgload.h" /*************************************************************************/ @@ -39,7 +40,9 @@ cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, - FT_Library library) + FT_Library library, + FT_UShort num_designs, + FT_UShort num_axes ) { FT_MEM_ZERO( parser, sizeof ( *parser ) ); @@ -47,6 +50,8 @@ parser->object_code = code; parser->object = object; parser->library = library; + parser->num_designs = num_designs; + parser->num_axes = num_axes; } @@ -66,7 +71,6 @@ goto Bad; val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] ); - p += 2; } else if ( v == 29 ) { @@ -77,7 +81,6 @@ ( (FT_ULong)p[1] << 16 ) | ( (FT_ULong)p[2] << 8 ) | (FT_ULong)p[3] ); - p += 4; } else if ( v < 247 ) { @@ -89,7 +92,6 @@ goto Bad; val = ( v - 247 ) * 256 + p[0] + 108; - p++; } else { @@ -97,7 +99,6 @@ goto Bad; val = -( v - 251 ) * 256 - p[0] - 108; - p++; } Exit: @@ -133,7 +134,7 @@ FT_Long* scaling ) { FT_Byte* p = start; - FT_UInt nib; + FT_Int nib; FT_UInt phase; FT_Long result, number, exponent; @@ -170,7 +171,7 @@ } /* Get the nibble. */ - nib = ( p[0] >> phase ) & 0xF; + nib = (FT_Int)( p[0] >> phase ) & 0xF; phase = 4 - phase; if ( nib == 0xE ) @@ -192,7 +193,7 @@ } /* Read fraction part, if any. */ - if ( nib == 0xa ) + if ( nib == 0xA ) for (;;) { /* If we entered this iteration with phase == 4, we need */ @@ -520,7 +521,11 @@ if ( parser->top >= parser->stack + 6 ) { - FT_Long scaling; + FT_Fixed values[6]; + FT_Long scalings[6]; + + FT_Long min_scaling, max_scaling; + int i; error = FT_Err_Ok; @@ -529,22 +534,36 @@ /* We expect a well-formed font matrix, this is, the matrix elements */ /* `xx' and `yy' are of approximately the same magnitude. To avoid */ - /* loss of precision, we use the magnitude of element `xx' to scale */ - /* all other elements. The scaling factor is then contained in the */ - /* `units_per_em' value. */ + /* loss of precision, we use the magnitude of the largest matrix */ + /* element to scale all other elements. The scaling factor is then */ + /* contained in the `units_per_em' value. */ - matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + max_scaling = FT_LONG_MIN; + min_scaling = FT_LONG_MAX; - scaling = -scaling; + for ( i = 0; i < 6; i++ ) + { + values[i] = cff_parse_fixed_dynamic( data++, &scalings[i] ); + if ( values[i] ) + { + if ( scalings[i] > max_scaling ) + max_scaling = scalings[i]; + if ( scalings[i] < min_scaling ) + min_scaling = scalings[i]; + } + } - if ( scaling < 0 || scaling > 9 ) + if ( max_scaling < -9 || + max_scaling > 0 || + ( max_scaling - min_scaling ) < 0 || + ( max_scaling - min_scaling ) > 9 ) { /* Return default matrix in case of unlikely values. */ FT_TRACE1(( "cff_parse_font_matrix:" - " strange scaling value for xx element (%d),\n" + " strange scaling values (minimum %d, maximum %d),\n" " " - " using default matrix\n", scaling )); + " using default matrix\n", min_scaling, max_scaling )); matrix->xx = 0x10000L; matrix->yx = 0; @@ -557,13 +576,42 @@ goto Exit; } - matrix->yx = cff_parse_fixed_scaled( data++, scaling ); - matrix->xy = cff_parse_fixed_scaled( data++, scaling ); - matrix->yy = cff_parse_fixed_scaled( data++, scaling ); - offset->x = cff_parse_fixed_scaled( data++, scaling ); - offset->y = cff_parse_fixed_scaled( data, scaling ); + for ( i = 0; i < 6; i++ ) + { + FT_Fixed value = values[i]; + FT_Long divisor, half_divisor; + + + if ( !value ) + continue; + + divisor = power_tens[max_scaling - scalings[i]]; + half_divisor = divisor >> 1; + + if ( value < 0 ) + { + if ( FT_LONG_MIN + half_divisor < value ) + values[i] = ( value - half_divisor ) / divisor; + else + values[i] = FT_LONG_MIN / divisor; + } + else + { + if ( FT_LONG_MAX - half_divisor > value ) + values[i] = ( value + half_divisor ) / divisor; + else + values[i] = FT_LONG_MAX / divisor; + } + } + + matrix->xx = values[0]; + matrix->yx = values[1]; + matrix->xy = values[2]; + matrix->yy = values[3]; + offset->x = values[4]; + offset->y = values[5]; - *upm = power_tens[scaling]; + *upm = (FT_ULong)power_tens[-max_scaling]; FT_TRACE4(( " [%f %f %f %f %f %f]\n", (double)matrix->xx / *upm / 65536, @@ -621,14 +669,84 @@ if ( parser->top >= parser->stack + 2 ) { - dict->private_size = cff_parse_num( data++ ); - dict->private_offset = cff_parse_num( data ); + FT_Long tmp; + + + tmp = cff_parse_num( data++ ); + if ( tmp < 0 ) + { + FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + dict->private_size = (FT_ULong)tmp; + + tmp = cff_parse_num( data ); + if ( tmp < 0 ) + { + FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + dict->private_offset = (FT_ULong)tmp; + FT_TRACE4(( " %lu %lu\n", dict->private_size, dict->private_offset )); error = FT_Err_Ok; } + Fail: + return error; + } + + + /* The `MultipleMaster' operator comes before any */ + /* top DICT operators that contain T2 charstrings. */ + + static FT_Error + cff_parse_multiple_master( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Error error; + + +#ifdef FT_DEBUG_LEVEL_TRACE + /* beautify tracing message */ + if ( ft_trace_levels[FT_COMPONENT] < 4 ) + FT_TRACE1(( "Multiple Master CFFs not supported yet," + " handling first master design only\n" )); + else + FT_TRACE1(( " (not supported yet," + " handling first master design only)\n" )); +#endif + + error = FT_ERR( Stack_Underflow ); + + /* currently, we handle only the first argument */ + if ( parser->top >= parser->stack + 5 ) + { + FT_Long num_designs = cff_parse_num( parser->stack ); + + + if ( num_designs > 16 || num_designs < 2 ) + { + FT_ERROR(( "cff_parse_multiple_master:" + " Invalid number of designs\n" )); + error = FT_THROW( Invalid_File_Format ); + } + else + { + dict->num_designs = (FT_UShort)num_designs; + dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 ); + + parser->num_designs = dict->num_designs; + parser->num_axes = dict->num_axes; + + error = FT_Err_Ok; + } + } + return error; } @@ -956,7 +1074,7 @@ if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) goto Stack_Overflow; - *parser->top ++ = p; + *parser->top++ = p; /* now, skip it */ if ( v == 30 ) @@ -985,6 +1103,136 @@ else if ( v > 246 ) p += 1; } +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + else if ( v == 31 ) + { + /* a Type 2 charstring */ + + CFF_Decoder decoder; + CFF_FontRec cff_rec; + FT_Byte* charstring_base; + FT_ULong charstring_len; + + FT_Fixed* stack; + FT_Byte* q; + + + charstring_base = ++p; + + /* search `endchar' operator */ + for (;;) + { + if ( p >= limit ) + goto Exit; + if ( *p == 14 ) + break; + p++; + } + + charstring_len = (FT_ULong)( p - charstring_base ) + 1; + + /* construct CFF_Decoder object */ + FT_MEM_ZERO( &decoder, sizeof ( decoder ) ); + FT_MEM_ZERO( &cff_rec, sizeof ( cff_rec ) ); + + cff_rec.top_font.font_dict.num_designs = parser->num_designs; + cff_rec.top_font.font_dict.num_axes = parser->num_axes; + decoder.cff = &cff_rec; + + error = cff_decoder_parse_charstrings( &decoder, + charstring_base, + charstring_len, + 1 ); + + /* Now copy the stack data in the temporary decoder object, */ + /* converting it back to charstring number representations */ + /* (this is ugly, I know). */ + /* */ + /* We overwrite the original top DICT charstring under the */ + /* assumption that the charstring representation of the result */ + /* of `cff_decoder_parse_charstrings' is shorter, which should */ + /* be always true. */ + + q = charstring_base - 1; + stack = decoder.stack; + + while ( stack < decoder.top ) + { + FT_ULong num; + FT_Bool neg; + + + if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + goto Stack_Overflow; + + *parser->top++ = q; + + if ( *stack < 0 ) + { + num = (FT_ULong)-*stack; + neg = 1; + } + else + { + num = (FT_ULong)*stack; + neg = 0; + } + + if ( num & 0xFFFFU ) + { + if ( neg ) + num = (FT_ULong)-num; + + *q++ = 255; + *q++ = ( num & 0xFF000000U ) >> 24; + *q++ = ( num & 0x00FF0000U ) >> 16; + *q++ = ( num & 0x0000FF00U ) >> 8; + *q++ = num & 0x000000FFU; + } + else + { + num >>= 16; + + if ( neg ) + { + if ( num <= 107 ) + *q++ = (FT_Byte)( 139 - num ); + else if ( num <= 1131 ) + { + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else + { + num = (FT_ULong)-num; + + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); + } + } + else + { + if ( num <= 107 ) + *q++ = (FT_Byte)( num + 139 ); + else if ( num <= 1131 ) + { + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else + { + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); + } + } + } + + stack++; + } + } +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ else { /* This is not a number, hence it's an operator. Compute its code */ diff --git a/drivers/freetype/src/cff/cffparse.h b/drivers/freetype/src/cff/cffparse.h index 61d91ed2e2..a95970edcb 100644 --- a/drivers/freetype/src/cff/cffparse.h +++ b/drivers/freetype/src/cff/cffparse.h @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (specification) */ /* */ -/* Copyright 1996-2003, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFF_PARSE_H__ -#define __CFF_PARSE_H__ +#ifndef CFFPARSE_H_ +#define CFFPARSE_H_ #include <ft2build.h> @@ -36,16 +36,19 @@ FT_BEGIN_HEADER typedef struct CFF_ParserRec_ { - FT_Library library; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* cursor; + FT_Library library; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* cursor; - FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; - FT_Byte** top; + FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; + FT_Byte** top; - FT_UInt object_code; - void* object; + FT_UInt object_code; + void* object; + + FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */ + FT_UShort num_axes; /* a copy of `CFF_FontRecDict->num_axes' */ } CFF_ParserRec, *CFF_Parser; @@ -54,7 +57,9 @@ FT_BEGIN_HEADER cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, - FT_Library library); + FT_Library library, + FT_UShort num_designs, + FT_UShort num_axes ); FT_LOCAL( FT_Error ) cff_parser_run( CFF_Parser parser, @@ -100,7 +105,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFF_PARSE_H__ */ +#endif /* CFFPARSE_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cffpic.c b/drivers/freetype/src/cff/cffpic.c index f22e4f0d53..a0bc34fd5f 100644 --- a/drivers/freetype/src/cff/cffpic.c +++ b/drivers/freetype/src/cff/cffpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for cff module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/cff/cffpic.h b/drivers/freetype/src/cff/cffpic.h index 50bab4c173..bed6b35a86 100644 --- a/drivers/freetype/src/cff/cffpic.h +++ b/drivers/freetype/src/cff/cffpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for cff module. */ /* */ -/* Copyright 2009, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,10 @@ /***************************************************************************/ -#ifndef __CFFPIC_H__ -#define __CFFPIC_H__ +#ifndef CFFPIC_H_ +#define CFFPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H @@ -49,6 +47,8 @@ FT_BEGIN_HEADER #include FT_SERVICE_PROPERTIES_H +FT_BEGIN_HEADER + typedef struct CffModulePIC_ { FT_ServiceDescRec* cff_services; @@ -96,13 +96,13 @@ FT_BEGIN_HEADER FT_Error cff_driver_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __CFFPIC_H__ */ +#endif /* CFFPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/cfftoken.h b/drivers/freetype/src/cff/cfftoken.h index bcb4276a78..22637c780b 100644 --- a/drivers/freetype/src/cff/cfftoken.h +++ b/drivers/freetype/src/cff/cfftoken.h @@ -4,7 +4,7 @@ /* */ /* CFF token definitions (specification only). */ /* */ -/* Copyright 1996-2003, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,6 +38,9 @@ CFF_FIELD_NUM ( 13, unique_id, "UniqueID" ) CFF_FIELD_CALLBACK( 5, font_bbox, "FontBBox" ) CFF_FIELD_NUM ( 0x108, stroke_width, "StrokeWidth" ) +#if 0 + CFF_FIELD_DELTA ( 14, xuid, 16, "XUID" ) +#endif CFF_FIELD_NUM ( 15, charset_offset, "charset" ) CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" ) CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) @@ -48,8 +51,13 @@ #if 0 CFF_FIELD_STRING ( 0x116, base_font_name, "BaseFontName" ) CFF_FIELD_DELTA ( 0x117, base_font_blend, 16, "BaseFontBlend" ) +#endif + + /* the next two operators were removed from the Type2 specification */ + /* in version 16-March-2000 */ CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" ) - CFF_FIELD_CALLBACK( 0x119, blend_axis_types, "BlendAxisTypes" ) +#if 0 + CFF_FIELD_CALLBACK( 0x11A, blend_axis_types, "BlendAxisTypes" ) #endif CFF_FIELD_CALLBACK( 0x11E, cid_ros, "ROS" ) diff --git a/drivers/freetype/src/cff/cfftypes.h b/drivers/freetype/src/cff/cfftypes.h index 8727446664..4426c7e4f1 100644 --- a/drivers/freetype/src/cff/cfftypes.h +++ b/drivers/freetype/src/cff/cfftypes.h @@ -5,7 +5,7 @@ /* Basic OpenType/CFF type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2003, 2006-2008, 2010-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __CFFTYPES_H__ -#define __CFFTYPES_H__ +#ifndef CFFTYPES_H_ +#define CFFTYPES_H_ #include <ft2build.h> @@ -145,6 +145,12 @@ FT_BEGIN_HEADER FT_ULong cid_fd_select_offset; FT_UInt cid_font_name; + /* the next fields come from the data of the deprecated */ + /* `MultipleMaster' operator; they are needed to parse the (also */ + /* deprecated) `blend' operator in Type 2 charstrings */ + FT_UShort num_designs; + FT_UShort num_axes; + } CFF_FontRecDictRec, *CFF_FontRecDict; @@ -250,6 +256,7 @@ FT_BEGIN_HEADER FT_UInt num_strings; FT_Byte** strings; FT_Byte* string_pool; + FT_ULong string_pool_size; CFF_SubFontRec top_font; FT_UInt num_subfonts; @@ -278,7 +285,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFTYPES_H__ */ +#endif /* CFFTYPES_H_ */ /* END */ diff --git a/drivers/freetype/src/cff/module.mk b/drivers/freetype/src/cff/module.mk index ef1391c279..1b4781afed 100644 --- a/drivers/freetype/src/cff/module.mk +++ b/drivers/freetype/src/cff/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/cff/rules.mk b/drivers/freetype/src/cff/rules.mk index 13115c2550..92f68b1ede 100644 --- a/drivers/freetype/src/cff/rules.mk +++ b/drivers/freetype/src/cff/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2001, 2003, 2011, 2013 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -18,7 +18,10 @@ CFF_DIR := $(SRC_DIR)/cff -CFF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) +CFF_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # CFF driver sources (i.e., C files) diff --git a/drivers/freetype/src/cid/Jamfile b/drivers/freetype/src/cid/Jamfile index ebeaed54ea..4b4eea17d9 100644 --- a/drivers/freetype/src/cid/Jamfile +++ b/drivers/freetype/src/cid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cid Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,12 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cid ; if $(FT2_MULTI) { - _sources = cidobjs cidload cidgload cidriver cidparse ; + _sources = cidgload + cidload + cidobjs + cidparse + cidriver + ; } else { diff --git a/drivers/freetype/src/cid/ciderrs.h b/drivers/freetype/src/cid/ciderrs.h index ef13155504..1dc98c7cdd 100644 --- a/drivers/freetype/src/cid/ciderrs.h +++ b/drivers/freetype/src/cid/ciderrs.h @@ -4,7 +4,7 @@ /* */ /* CID error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __CIDERRS_H__ -#define __CIDERRS_H__ +#ifndef CIDERRS_H_ +#define CIDERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CID_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __CIDERRS_H__ */ +#endif /* CIDERRS_H_ */ /* END */ diff --git a/drivers/freetype/src/cid/cidgload.c b/drivers/freetype/src/cid/cidgload.c index a1a8658693..c7b95593ee 100644 --- a/drivers/freetype/src/cid/cidgload.c +++ b/drivers/freetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2007, 2009, 2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -44,10 +44,10 @@ CID_Face face = (CID_Face)decoder->builder.face; CID_FaceInfo cid = &face->cid; FT_Byte* p; - FT_UInt fd_select; + FT_ULong fd_select; FT_Stream stream = face->cid_stream; FT_Error error = FT_Err_Ok; - FT_Byte* charstring = 0; + FT_Byte* charstring = NULL; FT_Memory memory = face->root.memory; FT_ULong glyph_length = 0; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -58,7 +58,7 @@ #endif - FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index )); + FT_TRACE1(( "cid_load_glyph: glyph index %d\n", glyph_index )); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -75,11 +75,11 @@ goto Exit; p = (FT_Byte*)glyph_data.pointer; - fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); if ( glyph_data.length != 0 ) { - glyph_length = glyph_data.length - cid->fd_bytes; + glyph_length = (FT_ULong)( glyph_data.length - cid->fd_bytes ); (void)FT_ALLOC( charstring, glyph_length ); if ( !error ) ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, @@ -99,8 +99,8 @@ /* For ordinary fonts read the CID font dictionary index */ /* and charstring offset from the CIDMap. */ { - FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; - FT_ULong off1; + FT_UInt entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes ); + FT_ULong off1, off2; if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + @@ -108,18 +108,23 @@ FT_FRAME_ENTER( 2 * entry_len ) ) goto Exit; - p = (FT_Byte*)stream->cursor; - fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); - p += cid->fd_bytes; - glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; + p = (FT_Byte*)stream->cursor; + fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + p += cid->fd_bytes; + off2 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); FT_FRAME_EXIT(); - if ( fd_select >= (FT_UInt)cid->num_dicts ) + if ( fd_select >= (FT_ULong)cid->num_dicts || + off2 > stream->size || + off1 > off2 ) { + FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); error = FT_THROW( Invalid_Offset ); goto Exit; } + + glyph_length = off2 - off1; if ( glyph_length == 0 ) goto Exit; if ( FT_ALLOC( charstring, glyph_length ) ) @@ -133,13 +138,14 @@ { CID_FaceDict dict; CID_Subrs cid_subrs = face->subrs + fd_select; - FT_Int cs_offset; + FT_UInt cs_offset; /* Set up subrs */ - decoder->num_subrs = cid_subrs->num_subrs; - decoder->subrs = cid_subrs->code; - decoder->subrs_len = 0; + decoder->num_subrs = cid_subrs->num_subrs; + decoder->subrs = cid_subrs->code; + decoder->subrs_len = 0; + decoder->subrs_hash = NULL; /* Set up font matrix */ dict = cid->font_dicts + fd_select; @@ -151,7 +157,13 @@ /* Decode the charstring. */ /* Adjustment for seed bytes. */ - cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0; + if ( cs_offset > glyph_length ) + { + FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); + error = FT_THROW( Invalid_Offset ); + goto Exit; + } /* Decrypt only if lenIV >= 0. */ if ( decoder->lenIV >= 0 ) @@ -159,11 +171,9 @@ error = decoder->funcs.parse_charstrings( decoder, charstring + cs_offset, - (FT_Int)glyph_length - cs_offset ); + glyph_length - cs_offset ); } - FT_FREE( charstring ); - #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ @@ -188,6 +198,8 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ Exit: + FT_FREE( charstring ); + return error; } @@ -357,7 +369,6 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &cidglyph->metrics; - FT_Vector advance; /* copy the _unscaled_ advance width */ @@ -377,22 +388,27 @@ if ( cidsize->metrics.y_ppem < 24 ) cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; - /* apply the font matrix */ - FT_Outline_Transform( &cidglyph->outline, &font_matrix ); + /* apply the font matrix, if any */ + if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + { + FT_Outline_Transform( &cidglyph->outline, &font_matrix ); - FT_Outline_Translate( &cidglyph->outline, - font_offset.x, - font_offset.y ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, + font_matrix.xx ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, + font_matrix.yy ); + } - advance.x = metrics->horiAdvance; - advance.y = 0; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->horiAdvance = advance.x + font_offset.x; + if ( font_offset.x || font_offset.y ) + { + FT_Outline_Translate( &cidglyph->outline, + font_offset.x, + font_offset.y ); - advance.x = 0; - advance.y = metrics->vertAdvance; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->vertAdvance = advance.y + font_offset.y; + metrics->horiAdvance += font_offset.x; + metrics->vertAdvance += font_offset.y; + } if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) { diff --git a/drivers/freetype/src/cid/cidgload.h b/drivers/freetype/src/cid/cidgload.h index a0a91bfea8..62d664b3af 100644 --- a/drivers/freetype/src/cid/cidgload.h +++ b/drivers/freetype/src/cid/cidgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDGLOAD_H__ -#define __CIDGLOAD_H__ +#ifndef CIDGLOAD_H_ +#define CIDGLOAD_H_ #include <ft2build.h> @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDGLOAD_H__ */ +#endif /* CIDGLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/cid/cidload.c b/drivers/freetype/src/cid/cidload.c index f2a18ea510..d4f1ad1a7f 100644 --- a/drivers/freetype/src/cid/cidload.c +++ b/drivers/freetype/src/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2006, 2009, 2011-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,7 +38,7 @@ /* read a single offset */ - FT_LOCAL_DEF( FT_Long ) + FT_LOCAL_DEF( FT_ULong ) cid_get_offset( FT_Byte* *start, FT_Byte offsize ) { @@ -53,7 +53,7 @@ } *start = p; - return (FT_Long)result; + return result; } @@ -150,8 +150,6 @@ cid_parse_font_matrix( CID_Face face, CID_Parser* parser ) { - FT_Matrix* matrix; - FT_Vector* offset; CID_FaceDict dict; FT_Face root = (FT_Face)&face->root; FT_Fixed temp[6]; @@ -160,29 +158,41 @@ if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) { + FT_Matrix* matrix; + FT_Vector* offset; + FT_Int result; + + dict = face->cid.font_dicts + parser->num_dict; matrix = &dict->font_matrix; offset = &dict->font_offset; - (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); + /* input is scaled by 1000 to accommodate default FontMatrix */ + result = cid_parser_to_fixed_array( parser, 6, temp, 3 ); - temp_scale = FT_ABS( temp[3] ); + if ( result < 6 ) + return FT_THROW( Invalid_File_Format ); - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ + temp_scale = FT_ABS( temp[3] ); - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + if ( temp_scale == 0 ) + { + FT_ERROR(( "cid_parse_font_matrix: invalid font matrix\n" )); + return FT_THROW( Invalid_File_Format ); + } - /* we need to scale the values by 1.0/temp[3] */ + /* atypical case */ if ( temp_scale != 0x10000L ) { + /* set units per EM based on FontMatrix values */ + root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + temp[0] = FT_DivFix( temp[0], temp_scale ); temp[1] = FT_DivFix( temp[1], temp_scale ); temp[2] = FT_DivFix( temp[2], temp_scale ); temp[4] = FT_DivFix( temp[4], temp_scale ); temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; + temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; } matrix->xx = temp[0]; @@ -195,8 +205,7 @@ offset->y = temp[5] >> 16; } - return FT_Err_Ok; /* this is a callback function; */ - /* we must return an error code */ + return FT_Err_Ok; } @@ -206,11 +215,43 @@ { CID_FaceInfo cid = &face->cid; FT_Memory memory = face->root.memory; + FT_Stream stream = parser->stream; FT_Error error = FT_Err_Ok; FT_Long num_dicts; num_dicts = cid_parser_to_int( parser ); + if ( num_dicts < 0 ) + { + FT_ERROR(( "parse_fd_array: invalid number of dictionaries\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* + * A single entry in the FDArray must (at least) contain the following + * structure elements. + * + * %ADOBeginFontDict 18 + * X dict begin 13 + * /FontMatrix [X X X X] 22 + * /Private X dict begin 22 + * end 4 + * end 4 + * %ADOEndFontDict 16 + * + * This needs 18+13+22+22+4+4+16=99 bytes or more. Normally, you also + * need a `dup X' at the very beginning and a `put' at the end, so a + * rough guess using 100 bytes as the minimum is justified. + */ + if ( (FT_ULong)num_dicts > stream->size / 100 ) + { + FT_TRACE0(( "parse_fd_array: adjusting FDArray size" + " (from %d to %d)\n", + num_dicts, + stream->size / 100 )); + num_dicts = (FT_Long)( stream->size / 100 ); + } if ( !cid->font_dicts ) { @@ -220,7 +261,7 @@ if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) goto Exit; - cid->num_dicts = (FT_UInt)num_dicts; + cid->num_dicts = num_dicts; /* don't forget to set a few defaults */ for ( n = 0; n < cid->num_dicts; n++ ) @@ -279,7 +320,7 @@ cid_parse_dict( CID_Face face, CID_Loader* loader, FT_Byte* base, - FT_Long size ) + FT_ULong size ) { CID_Parser* parser = &loader->parser; @@ -331,11 +372,11 @@ /* look for immediates */ if ( *cur == '/' && cur + 2 < limit ) { - FT_PtrDist len; + FT_UInt len; cur++; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); if ( len > 0 && len < 22 ) { @@ -352,10 +393,10 @@ if ( !name ) break; - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char*)name ) ) + if ( cur[0] == name[0] && + len == ft_strlen( (const char*)name ) ) { - FT_PtrDist n; + FT_UInt n; for ( n = 1; n < len; n++ ) @@ -380,7 +421,14 @@ cur = parser->root.cursor; } + + if ( !face->cid.num_dicts ) + { + FT_ERROR(( "cid_parse_dict: No font dictionary found\n" )); + return FT_THROW( Invalid_File_Format ); + } } + return parser->root.error; } @@ -396,7 +444,7 @@ FT_Int n; CID_Subrs subr; FT_UInt max_offsets = 0; - FT_ULong* offsets = 0; + FT_ULong* offsets = NULL; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -413,13 +461,6 @@ FT_Byte* p; - /* Check for possible overflow. */ - if ( num_subrs == FT_UINT_MAX ) - { - error = FT_THROW( Syntax_Error ); - goto Fail; - } - /* reallocate offsets array if needed */ if ( num_subrs + 1 > max_offsets ) { @@ -439,8 +480,8 @@ } /* read the subrmap's offsets */ - if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || - FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) + if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || + FT_FRAME_ENTER( ( num_subrs + 1 ) * (FT_UInt)dict->sd_bytes ) ) goto Fail; p = (FT_Byte*)stream->cursor; @@ -452,14 +493,25 @@ /* offsets must be ordered */ for ( count = 1; count <= num_subrs; count++ ) if ( offsets[count - 1] > offsets[count] ) + { + FT_ERROR(( "cid_read_subrs: offsets are not ordered\n" )); + error = FT_THROW( Invalid_File_Format ); goto Fail; + } + + if ( offsets[num_subrs] > stream->size - cid->data_offset ) + { + FT_ERROR(( "cid_read_subrs: too large `subrs' offsets\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } /* now, compute the size of subrs charstrings, */ /* allocate, and read them */ data_len = offsets[num_subrs] - offsets[0]; if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || - FT_ALLOC( subr->code[0], data_len ) ) + FT_ALLOC( subr->code[0], data_len ) ) goto Fail; if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || @@ -489,7 +541,7 @@ } } - subr->num_subrs = num_subrs; + subr->num_subrs = (FT_Int)num_subrs; } Exit: @@ -535,7 +587,7 @@ static FT_Error cid_hex_to_binary( FT_Byte* data, - FT_Long data_len, + FT_ULong data_len, FT_ULong offset, CID_Face face ) { @@ -639,6 +691,12 @@ CID_Parser* parser; FT_Memory memory = face->root.memory; FT_Error error; + FT_Int n; + + CID_FaceInfo cid = &face->cid; + + FT_ULong binary_length; + FT_ULong entry_len; cid_init_loader( &loader, face ); @@ -663,6 +721,17 @@ if ( parser->binary_length ) { + if ( parser->binary_length > + face->root.stream->size - parser->data_offset ) + { + FT_TRACE0(( "cid_face_open: adjusting length of binary data\n" + " (from %d to %d bytes)\n", + parser->binary_length, + face->root.stream->size - parser->data_offset )); + parser->binary_length = face->root.stream->size - + parser->data_offset; + } + /* we must convert the data section from hexadecimal to binary */ if ( FT_ALLOC( face->binary_data, parser->binary_length ) || cid_hex_to_binary( face->binary_data, parser->binary_length, @@ -671,14 +740,95 @@ FT_Stream_OpenMemory( face->cid_stream, face->binary_data, parser->binary_length ); - face->cid.data_offset = 0; + cid->data_offset = 0; } else { - *face->cid_stream = *face->root.stream; - face->cid.data_offset = loader.parser.data_offset; + *face->cid_stream = *face->root.stream; + cid->data_offset = loader.parser.data_offset; + } + + /* sanity tests */ + + if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 ) + { + FT_ERROR(( "cid_parse_dict:" + " Invalid `FDBytes' or `GDBytes' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* allow at most 32bit offsets */ + if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 ) + { + FT_ERROR(( "cid_parse_dict:" + " Values of `FDBytes' or `GDBytes' larger than 4\n" + " " + " are not supported\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + binary_length = face->cid_stream->size - cid->data_offset; + entry_len = (FT_ULong)( cid->fd_bytes + cid->gd_bytes ); + + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + + + if ( dict->sd_bytes < 0 ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SDBytes' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dict->sd_bytes > 4 ) + { + FT_ERROR(( "cid_parse_dict:" + " Values of `SDBytes' larger than 4" + " are not supported\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dict->subrmap_offset > binary_length ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SubrMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* `num_subrs' is scanned as a signed integer */ + if ( (FT_Int)dict->num_subrs < 0 || + ( dict->sd_bytes && + dict->num_subrs > ( binary_length - dict->subrmap_offset ) / + (FT_UInt)dict->sd_bytes ) ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SubrCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + + if ( cid->cidmap_offset > binary_length ) + { + FT_ERROR(( "cid_parse_dict: Invalid `CIDMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( entry_len && + cid->cid_count > + ( binary_length - cid->cidmap_offset ) / entry_len ) + { + FT_ERROR(( "cid_parse_dict: Invalid `CIDCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; } + /* we can now safely proceed */ error = cid_read_subrs( face ); Exit: diff --git a/drivers/freetype/src/cid/cidload.h b/drivers/freetype/src/cid/cidload.h index 8c172ffee2..680f0d8fc5 100644 --- a/drivers/freetype/src/cid/cidload.h +++ b/drivers/freetype/src/cid/cidload.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDLOAD_H__ -#define __CIDLOAD_H__ +#ifndef CIDLOAD_H_ +#define CIDLOAD_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER } CID_Loader; - FT_LOCAL( FT_Long ) + FT_LOCAL( FT_ULong ) cid_get_offset( FT_Byte** start, FT_Byte offsize ); @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDLOAD_H__ */ +#endif /* CIDLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/cid/cidobjs.c b/drivers/freetype/src/cid/cidobjs.c index 46555e2dc8..2d2600fd4c 100644 --- a/drivers/freetype/src/cid/cidobjs.c +++ b/drivers/freetype/src/cid/cidobjs.c @@ -4,7 +4,7 @@ /* */ /* CID objects manager (body). */ /* */ -/* Copyright 1996-2006, 2008, 2010-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -49,7 +49,7 @@ FT_LOCAL_DEF( void ) cid_slot_done( FT_GlyphSlot slot ) { - slot->internal->glyph_hints = 0; + slot->internal->glyph_hints = NULL; } @@ -122,7 +122,7 @@ if ( funcs ) funcs->destroy( (PSH_Globals)cidsize->internal ); - cidsize->internal = 0; + cidsize->internal = NULL; } } @@ -243,8 +243,8 @@ FT_FREE( cid->registry ); FT_FREE( cid->ordering ); - cidface->family_name = 0; - cidface->style_name = 0; + cidface->family_name = NULL; + cidface->style_name = NULL; FT_FREE( face->binary_data ); FT_FREE( face->cid_stream ); @@ -334,7 +334,7 @@ /* check the face index */ /* XXX: handle CID fonts with more than a single face */ - if ( face_index != 0 ) + if ( ( face_index & 0xFFFF ) != 0 ) { FT_ERROR(( "cid_face_init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -351,13 +351,14 @@ PS_FontInfo info = &cid->font_info; - cidface->num_glyphs = cid->cid_count; + cidface->num_glyphs = (FT_Long)cid->cid_count; cidface->num_charmaps = 0; - cidface->face_index = face_index; - cidface->face_flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ - FT_FACE_FLAG_HINTER; /* has native hinter */ + cidface->face_index = face_index & 0xFFFF; + + cidface->face_flags |= FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER; /* has native hinter */ if ( info->is_fixed_pitch ) cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -420,7 +421,7 @@ /* no embedded bitmap support */ cidface->num_fixed_sizes = 0; - cidface->available_sizes = 0; + cidface->available_sizes = NULL; cidface->bbox.xMin = cid->font_bbox.xMin >> 16; cidface->bbox.yMin = cid->font_bbox.yMin >> 16; diff --git a/drivers/freetype/src/cid/cidobjs.h b/drivers/freetype/src/cid/cidobjs.h index aee346d1c8..5dd377a9f8 100644 --- a/drivers/freetype/src/cid/cidobjs.h +++ b/drivers/freetype/src/cid/cidobjs.h @@ -4,7 +4,7 @@ /* */ /* CID objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDOBJS_H__ -#define __CIDOBJS_H__ +#ifndef CIDOBJS_H_ +#define CIDOBJS_H_ #include <ft2build.h> @@ -148,7 +148,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDOBJS_H__ */ +#endif /* CIDOBJS_H_ */ /* END */ diff --git a/drivers/freetype/src/cid/cidparse.c b/drivers/freetype/src/cid/cidparse.c index 53df3155d1..73aca2ac6a 100644 --- a/drivers/freetype/src/cid/cidparse.c +++ b/drivers/freetype/src/cid/cidparse.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2007, 2009, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -47,6 +47,12 @@ /*************************************************************************/ +#define STARTDATA "StartData" +#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 ) +#define SFNTS "/sfnts" +#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 ) + + FT_LOCAL_DEF( FT_Error ) cid_parser_new( CID_Parser* parser, FT_Stream stream, @@ -85,51 +91,79 @@ /* now, read the rest of the file until we find */ /* `StartData' or `/sfnts' */ { - FT_Byte buffer[256 + 10]; - FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ - FT_Byte* p = buffer; + /* + * The algorithm is as follows (omitting the case with less than 256 + * bytes to fill for simplicity). + * + * 1. Fill the buffer with 256 + STARTDATA_LEN bytes. + * + * 2. Search for the STARTDATA and SFNTS strings at positions + * buffer[0], buffer[1], ..., + * buffer[255 + STARTDATA_LEN - SFNTS_LEN]. + * + * 3. Move the last STARTDATA_LEN bytes to buffer[0]. + * + * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN. + * + * 5. Repeat with step 2. + * + */ + FT_Byte buffer[256 + STARTDATA_LEN + 1]; + + /* values for the first loop */ + FT_ULong read_len = 256 + STARTDATA_LEN; + FT_ULong read_offset = 0; + FT_Byte* p = buffer; for ( offset = FT_STREAM_POS(); ; offset += 256 ) { - FT_Long stream_len; /* same as signed FT_Stream->size */ + FT_ULong stream_len; stream_len = stream->size - FT_STREAM_POS(); - if ( stream_len == 0 ) - { - FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } read_len = FT_MIN( read_len, stream_len ); if ( FT_STREAM_READ( p, read_len ) ) goto Exit; - if ( read_len < 256 ) - p[read_len] = '\0'; + /* ensure that we do not compare with data beyond the buffer */ + p[read_len] = '\0'; - limit = p + read_len - 10; + limit = p + read_len - SFNTS_LEN; for ( p = buffer; p < limit; p++ ) { - if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) + if ( p[0] == 'S' && + ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 ) { /* save offset of binary data after `StartData' */ - offset += (FT_ULong)( p - buffer + 10 ); + offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN; goto Found; } - else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) + else if ( p[1] == 's' && + ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 ) { - offset += (FT_ULong)( p - buffer + 7 ); + offset += (FT_ULong)( p - buffer ) + SFNTS_LEN; goto Found; } } - FT_MEM_MOVE( buffer, p, 10 ); - read_len = 256; - p = buffer + 10; + if ( read_offset + read_len < STARTDATA_LEN ) + { + FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + FT_MEM_MOVE( buffer, + buffer + read_offset + read_len - STARTDATA_LEN, + STARTDATA_LEN ); + + /* values for the next loop */ + read_len = 256; + read_offset = STARTDATA_LEN; + p = buffer + read_offset; } } @@ -165,7 +199,7 @@ limit = parser->root.limit; cur = parser->root.cursor; - while ( cur < limit ) + while ( cur < limit - SFNTS_LEN ) { if ( parser->root.error ) { @@ -173,16 +207,28 @@ goto Exit; } - if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) + if ( cur[0] == 'S' && + cur < limit - STARTDATA_LEN && + ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) - parser->binary_length = ft_atol( (const char *)arg2 ); + { + FT_Long tmp = ft_atol( (const char *)arg2 ); + + + if ( tmp < 0 ) + { + FT_ERROR(( "cid_parser_new: invalid length of hex data\n" )); + error = FT_THROW( Invalid_File_Format ); + } + else + parser->binary_length = (FT_ULong)tmp; + } - limit = parser->root.limit; - cur = parser->root.cursor; goto Exit; } - else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) + else if ( cur[1] == 's' && + ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 ) { FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); error = FT_THROW( Unknown_File_Format ); @@ -207,6 +253,12 @@ } +#undef STARTDATA +#undef STARTDATA_LEN +#undef SFNTS +#undef SFNTS_LEN + + FT_LOCAL_DEF( void ) cid_parser_done( CID_Parser* parser ) { diff --git a/drivers/freetype/src/cid/cidparse.h b/drivers/freetype/src/cid/cidparse.h index ca37deab93..7268dc6ae8 100644 --- a/drivers/freetype/src/cid/cidparse.h +++ b/drivers/freetype/src/cid/cidparse.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDPARSE_H__ -#define __CIDPARSE_H__ +#ifndef CIDPARSE_H_ +#define CIDPARSE_H_ #include <ft2build.h> @@ -64,11 +64,11 @@ FT_BEGIN_HEADER FT_Stream stream; FT_Byte* postscript; - FT_Long postscript_len; + FT_ULong postscript_len; FT_ULong data_offset; - FT_Long binary_length; + FT_ULong binary_length; CID_FaceInfo cid; FT_Int num_dict; @@ -92,32 +92,32 @@ FT_BEGIN_HEADER /* */ /*************************************************************************/ -#define cid_parser_skip_spaces( p ) \ +#define cid_parser_skip_spaces( p ) \ (p)->root.funcs.skip_spaces( &(p)->root ) -#define cid_parser_skip_PS_token( p ) \ +#define cid_parser_skip_PS_token( p ) \ (p)->root.funcs.skip_PS_token( &(p)->root ) -#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) -#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) +#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) +#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) -#define cid_parser_to_coord_array( p, m, c ) \ +#define cid_parser_to_coord_array( p, m, c ) \ (p)->root.funcs.to_coord_array( &(p)->root, m, c ) -#define cid_parser_to_fixed_array( p, m, f, t ) \ +#define cid_parser_to_fixed_array( p, m, f, t ) \ (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) -#define cid_parser_to_token( p, t ) \ +#define cid_parser_to_token( p, t ) \ (p)->root.funcs.to_token( &(p)->root, t ) -#define cid_parser_to_token_array( p, t, m, c ) \ +#define cid_parser_to_token_array( p, t, m, c ) \ (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) -#define cid_parser_load_field( p, f, o ) \ +#define cid_parser_load_field( p, f, o ) \ (p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 ) -#define cid_parser_load_field_table( p, f, o ) \ +#define cid_parser_load_field_table( p, f, o ) \ (p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 ) FT_END_HEADER -#endif /* __CIDPARSE_H__ */ +#endif /* CIDPARSE_H_ */ /* END */ diff --git a/drivers/freetype/src/cid/cidriver.c b/drivers/freetype/src/cid/cidriver.c index 6132a27763..64141ab6b1 100644 --- a/drivers/freetype/src/cid/cidriver.c +++ b/drivers/freetype/src/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,7 +24,7 @@ #include "ciderrs.h" #include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_POSTSCRIPT_INFO_H #include FT_SERVICE_CID_H @@ -59,7 +59,7 @@ static const FT_Service_PsFontNameRec cid_service_ps_name = { - (FT_PsName_GetFunc) cid_get_postscript_name + (FT_PsName_GetFunc)cid_get_postscript_name /* get_ps_font_name */ }; @@ -88,11 +88,14 @@ static const FT_Service_PsInfoRec cid_service_ps_info = { - (PS_GetFontInfoFunc) cid_ps_get_font_info, - (PS_GetFontExtraFunc) cid_ps_get_font_extra, - (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ - (PS_GetFontPrivateFunc)NULL, /* unsupported */ - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) cid_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) cid_ps_get_font_extra, /* ps_get_font_extra */ + /* unsupported with CID fonts */ + (PS_HasGlyphNamesFunc) NULL, /* ps_has_glyph_names */ + /* unsupported */ + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ }; @@ -155,9 +158,12 @@ static const FT_Service_CIDRec cid_service_cid_info = { - (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index + (FT_CID_GetRegistryOrderingSupplementFunc) + cid_get_ros, /* get_ros */ + (FT_CID_GetIsInternallyCIDKeyedFunc) + cid_get_is_cid, /* get_is_cid */ + (FT_CID_GetCIDFromGlyphIndexFunc) + cid_get_cid_from_glyph_index /* get_cid_from_glyph_index */ }; @@ -168,7 +174,7 @@ static const FT_ServiceDescRec cid_services[] = { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CID }, { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, { FT_SERVICE_ID_CID, &cid_service_cid_info }, @@ -190,46 +196,42 @@ FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec t1cid_driver_class = { - /* first of all, the FT_Module_Class fields */ { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, - sizeof ( FT_DriverRec ), + "t1cid", /* module name */ 0x10000L, /* version 1.0 of driver */ 0x20000L, /* requires FreeType 2.0 */ - 0, + 0, /* module-specific interface */ - cid_driver_init, - cid_driver_done, - cid_get_interface + cid_driver_init, /* FT_Module_Constructor module_init */ + cid_driver_done, /* FT_Module_Destructor module_done */ + cid_get_interface /* FT_Module_Requester get_interface */ }, - /* then the other font drivers fields */ sizeof ( CID_FaceRec ), sizeof ( CID_SizeRec ), sizeof ( CID_GlyphSlotRec ), - cid_face_init, - cid_face_done, - - cid_size_init, - cid_size_done, - cid_slot_init, - cid_slot_done, - - cid_slot_load_glyph, + cid_face_init, /* FT_Face_InitFunc init_face */ + cid_face_done, /* FT_Face_DoneFunc done_face */ + cid_size_init, /* FT_Size_InitFunc init_size */ + cid_size_done, /* FT_Size_DoneFunc done_size */ + cid_slot_init, /* FT_Slot_InitFunc init_slot */ + cid_slot_done, /* FT_Slot_DoneFunc done_slot */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + cid_slot_load_glyph, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - cid_size_request, - 0 /* FT_Size_SelectFunc */ + cid_size_request, /* FT_Size_RequestFunc request_size */ + 0 /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/src/cid/cidriver.h b/drivers/freetype/src/cid/cidriver.h index 3c45e06886..a359a78907 100644 --- a/drivers/freetype/src/cid/cidriver.h +++ b/drivers/freetype/src/cid/cidriver.h @@ -4,7 +4,7 @@ /* */ /* High-level CID driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDRIVER_H__ -#define __CIDRIVER_H__ +#ifndef CIDRIVER_H_ +#define CIDRIVER_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDRIVER_H__ */ +#endif /* CIDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/src/cid/cidtoken.h b/drivers/freetype/src/cid/cidtoken.h index 904cb09cf4..9c773fd094 100644 --- a/drivers/freetype/src/cid/cidtoken.h +++ b/drivers/freetype/src/cid/cidtoken.h @@ -4,7 +4,7 @@ /* */ /* CID token definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/cid/module.mk b/drivers/freetype/src/cid/module.mk index ce30bfd7ae..d9585d7816 100644 --- a/drivers/freetype/src/cid/module.mk +++ b/drivers/freetype/src/cid/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/cid/rules.mk b/drivers/freetype/src/cid/rules.mk index f362744612..f33aab00d6 100644 --- a/drivers/freetype/src/cid/rules.mk +++ b/drivers/freetype/src/cid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -18,7 +18,10 @@ CID_DIR := $(SRC_DIR)/cid -CID_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CID_DIR)) +CID_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(CID_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # CID driver sources (i.e., C files) diff --git a/drivers/freetype/src/cid/type1cid.c b/drivers/freetype/src/cid/type1cid.c index 0b866e97c4..de3bdf7705 100644 --- a/drivers/freetype/src/cid/type1cid.c +++ b/drivers/freetype/src/cid/type1cid.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/gxvalid/Jamfile b/drivers/freetype/src/gxvalid/Jamfile index 88049a625d..9738677e05 100644 --- a/drivers/freetype/src/gxvalid/Jamfile +++ b/drivers/freetype/src/gxvalid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/gxvalid Jamfile # -# Copyright 2005 by +# Copyright 2005-2016 by # suzuki toshiya, Masatake YAMATO and Red Hat K.K. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,10 +17,29 @@ SubDir FT2_TOP $(FT2_SRC_DIR) gxvalid ; if $(FT2_MULTI) { - _sources = gxvcommn gxvfeat gxvbsln gxvtrak gxvopbd gxvprop - gxvmort gxvmort0 gxvmort1 gxvmort2 gxvmort4 gxvmort5 - gxvmorx gxvmorx0 gxvmorx1 gxvmorx2 gxvmorx4 gxvmorx5 - gxvlcar gxvkern gxvmod gxvjust ; + _sources = gxvbsln + gxvcommn + gxvfeat + gxvjust + gxvkern + gxvlcar + gxvmod + gxvmort + gxvmort0 + gxvmort1 + gxvmort2 + gxvmort4 + gxvmort5 + gxvmorx + gxvmorx0 + gxvmorx1 + gxvmorx2 + gxvmorx4 + gxvmorx5 + gxvopbd + gxvprop + gxvtrak + ; } else { diff --git a/drivers/freetype/src/gxvalid/README b/drivers/freetype/src/gxvalid/README index 28e535b0bc..d3ac49c3e2 100644 --- a/drivers/freetype/src/gxvalid/README +++ b/drivers/freetype/src/gxvalid/README @@ -518,7 +518,7 @@ gxvalid: TrueType GX validator ------------------------------------------------------------------------ -Copyright 2004, 2005, 2007 by +Copyright 2004-2016 by suzuki toshiya, Masatake YAMATO, Red hat K.K., David Turner, Robert Wilhelm, and Werner Lemberg. diff --git a/drivers/freetype/src/gxvalid/gxvalid.c b/drivers/freetype/src/gxvalid/gxvalid.c index bc36e675d1..7fb868cad1 100644 --- a/drivers/freetype/src/gxvalid/gxvalid.c +++ b/drivers/freetype/src/gxvalid/gxvalid.c @@ -4,7 +4,8 @@ /* */ /* FreeType validator for TrueTypeGX/AAT tables (body only). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/gxvalid/gxvalid.h b/drivers/freetype/src/gxvalid/gxvalid.h index 27be9ecca8..7a3ab795ef 100644 --- a/drivers/freetype/src/gxvalid/gxvalid.h +++ b/drivers/freetype/src/gxvalid/gxvalid.h @@ -4,7 +4,8 @@ /* */ /* TrueTyeeGX/AAT table validation (specification only). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVALID_H__ -#define __GXVALID_H__ +#ifndef GXVALID_H_ +#define GXVALID_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -101,7 +102,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVALID_H__ */ +#endif /* GXVALID_H_ */ /* END */ diff --git a/drivers/freetype/src/gxvalid/gxvbsln.c b/drivers/freetype/src/gxvalid/gxvbsln.c index 3d10031563..493b20c31a 100644 --- a/drivers/freetype/src/gxvalid/gxvbsln.c +++ b/drivers/freetype/src/gxvalid/gxvbsln.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT bsln table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,10 +73,10 @@ static void gxv_bsln_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_UShort v = value_p->u; - FT_UShort* ctlPoints; + FT_UShort v = value_p->u; + FT_UShort* ctlPoints; FT_UNUSED( glyph ); @@ -124,7 +125,7 @@ gxv_bsln_LookupFmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -135,7 +136,7 @@ offset = (FT_UShort)( base_value_p->u + ( relative_gindex * sizeof ( FT_UShort ) ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK( 2 ); @@ -148,7 +149,7 @@ static void gxv_bsln_parts_fmt0_validate( FT_Bytes tables, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = tables; @@ -158,7 +159,7 @@ /* deltas */ GXV_LIMIT_CHECK( 2 * GXV_BSLN_VALUE_COUNT ); - valid->table_data = NULL; /* No ctlPoints here. */ + gxvalid->table_data = NULL; /* No ctlPoints here. */ GXV_EXIT; } @@ -167,7 +168,7 @@ static void gxv_bsln_parts_fmt1_validate( FT_Bytes tables, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = tables; @@ -175,15 +176,15 @@ GXV_NAME_ENTER( "parts format 1" ); /* deltas */ - gxv_bsln_parts_fmt0_validate( p, limit, valid ); + gxv_bsln_parts_fmt0_validate( p, limit, gxvalid ); /* mappingData */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_bsln_LookupValue_validate; - valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_bsln_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; gxv_LookupTable_validate( p + 2 * GXV_BSLN_VALUE_COUNT, limit, - valid ); + gxvalid ); GXV_EXIT; } @@ -192,7 +193,7 @@ static void gxv_bsln_parts_fmt2_validate( FT_Bytes tables, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = tables; @@ -211,7 +212,7 @@ stdGlyph = FT_NEXT_USHORT( p ); GXV_TRACE(( " (stdGlyph = %u)\n", stdGlyph )); - gxv_glyphid_validate( stdGlyph, valid ); + gxv_glyphid_validate( stdGlyph, gxvalid ); /* Record the position of ctlPoints */ GXV_BSLN_DATA( ctlPoints_p ) = p; @@ -226,7 +227,7 @@ FT_INVALID_DATA; } else - gxv_ctlPoint_validate( stdGlyph, (FT_Short)ctlPoint, valid ); + gxv_ctlPoint_validate( stdGlyph, ctlPoint, gxvalid ); } GXV_EXIT; @@ -236,7 +237,7 @@ static void gxv_bsln_parts_fmt3_validate( FT_Bytes tables, FT_Bytes limit, - GXV_Validator valid) + GXV_Validator gxvalid) { FT_Bytes p = tables; @@ -244,15 +245,15 @@ GXV_NAME_ENTER( "parts format 3" ); /* stdGlyph + ctlPoints */ - gxv_bsln_parts_fmt2_validate( p, limit, valid ); + gxv_bsln_parts_fmt2_validate( p, limit, gxvalid ); /* mappingData */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_bsln_LookupValue_validate; - valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_bsln_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; gxv_LookupTable_validate( p + ( 2 + 2 * GXV_BSLN_VALUE_COUNT ), limit, - valid ); + gxvalid ); GXV_EXIT; } @@ -271,8 +272,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_bsln_DataRec bslnrec; GXV_bsln_Data bsln = &bslnrec; @@ -293,9 +294,9 @@ }; - valid->root = ftvalid; - valid->table_data = bsln; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = bsln; + gxvalid->face = face; FT_TRACE3(( "validating `bsln' table\n" )); GXV_INIT; @@ -320,7 +321,7 @@ bsln->defaultBaseline = defaultBaseline; - fmt_funcs_table[format]( p, limit, valid ); + fmt_funcs_table[format]( p, limit, gxvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/src/gxvalid/gxvcommn.c b/drivers/freetype/src/gxvalid/gxvcommn.c index 2ac80be8c7..4b5e41539a 100644 --- a/drivers/freetype/src/gxvalid/gxvcommn.c +++ b/drivers/freetype/src/gxvalid/gxvcommn.c @@ -4,8 +4,8 @@ /* */ /* TrueTypeGX/AAT common tables validation (body). */ /* */ -/* Copyright 2004, 2005, 2009, 2010, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,7 +65,7 @@ FT_UShort* buff, FT_UInt nmemb, FT_UShort limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UInt i; @@ -130,7 +130,7 @@ FT_ULong* buff, FT_UInt nmemb, FT_ULong limit, - GXV_Validator valid) + GXV_Validator gxvalid) { FT_UInt i; @@ -182,7 +182,7 @@ FT_Bytes limit, FT_Byte* min, FT_Byte* max, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -202,7 +202,7 @@ *max = (FT_Byte)FT_MAX( *max, val ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } @@ -211,7 +211,7 @@ FT_Bytes limit, FT_UShort* min, FT_UShort* max, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -231,7 +231,7 @@ *max = (FT_Byte)FT_MAX( *max, val ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } @@ -256,7 +256,7 @@ static void gxv_BinSrchHeader_check_consistency( GXV_BinSrchHeader* binSrchHeader, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort searchRange; FT_UShort entrySelector; @@ -329,7 +329,7 @@ FT_Bytes limit, FT_UShort* unitSize_p, FT_UShort* nUnits_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_BinSrchHeader binSrchHeader; @@ -359,7 +359,7 @@ binSrchHeader.rangeShift = FT_NEXT_USHORT( p ); GXV_TRACE(( "nUnits %d\n", binSrchHeader.nUnits )); - gxv_BinSrchHeader_check_consistency( &binSrchHeader, valid ); + gxv_BinSrchHeader_check_consistency( &binSrchHeader, gxvalid ); if ( *unitSize_p == 0 ) *unitSize_p = binSrchHeader.unitSize; @@ -367,7 +367,7 @@ if ( *nUnits_p == 0 ) *nUnits_p = binSrchHeader.nUnits; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -422,7 +422,7 @@ static void gxv_LookupTable_fmt0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort i; @@ -432,24 +432,24 @@ GXV_NAME_ENTER( "LookupTable format 0" ); - GXV_LIMIT_CHECK( 2 * valid->face->num_glyphs ); + GXV_LIMIT_CHECK( 2 * gxvalid->face->num_glyphs ); - for ( i = 0; i < valid->face->num_glyphs; i++ ) + for ( i = 0; i < gxvalid->face->num_glyphs; i++ ) { GXV_LIMIT_CHECK( 2 ); if ( p + 2 >= limit ) /* some fonts have too-short fmt0 array */ { GXV_TRACE(( "too short, glyphs %d - %d are missing\n", - i, valid->face->num_glyphs )); + i, gxvalid->face->num_glyphs )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); break; } - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( i, &value, valid ); + value = GXV_LOOKUP_VALUE_LOAD( p, gxvalid->lookupval_sign ); + gxvalid->lookupval_func( i, &value, gxvalid ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -473,12 +473,12 @@ static void gxv_LookupTable_fmt2_skip_endmarkers( FT_Bytes table, FT_UShort unitSize, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; - while ( ( p + 4 ) < valid->root->limit ) + while ( ( p + 4 ) < gxvalid->root->limit ) { if ( p[0] != 0xFF || p[1] != 0xFF || /* lastGlyph */ p[2] != 0xFF || p[3] != 0xFF ) /* firstGlyph */ @@ -486,14 +486,14 @@ p += unitSize; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_LookupTable_fmt2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort gid; @@ -509,8 +509,8 @@ GXV_NAME_ENTER( "LookupTable format 2" ); unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid ); + p += gxvalid->subtable_length; GXV_UNITSIZE_VALIDATE( "format2", unitSize, nUnits, 6 ); @@ -519,10 +519,10 @@ GXV_LIMIT_CHECK( 2 + 2 + 2 ); lastGlyph = FT_NEXT_USHORT( p ); firstGlyph = FT_NEXT_USHORT( p ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); + value = GXV_LOOKUP_VALUE_LOAD( p, gxvalid->lookupval_sign ); - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( lastGlyph, valid ); + gxv_glyphid_validate( firstGlyph, gxvalid ); + gxv_glyphid_validate( lastGlyph, gxvalid ); if ( lastGlyph < gid ) { @@ -539,7 +539,7 @@ unit, lastGlyph, firstGlyph )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - if ( valid->root->level == FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level == FT_VALIDATE_TIGHT ) continue; /* ftxvalidator silently skips such an entry */ FT_TRACE4(( "continuing with exchanged values\n" )); @@ -549,13 +549,13 @@ } for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) - valid->lookupval_func( gid, &value, valid ); + gxvalid->lookupval_func( gid, &value, gxvalid ); } - gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; + gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -564,7 +564,7 @@ static void gxv_LookupTable_fmt4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort unit; @@ -581,8 +581,8 @@ GXV_NAME_ENTER( "LookupTable format 4" ); unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid ); + p += gxvalid->subtable_length; GXV_UNITSIZE_VALIDATE( "format4", unitSize, nUnits, 6 ); @@ -592,8 +592,8 @@ lastGlyph = FT_NEXT_USHORT( p ); firstGlyph = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( lastGlyph, valid ); + gxv_glyphid_validate( firstGlyph, gxvalid ); + gxv_glyphid_validate( lastGlyph, gxvalid ); if ( lastGlyph < gid ) { @@ -610,7 +610,7 @@ unit, lastGlyph, firstGlyph )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - if ( valid->root->level == FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level == FT_VALIDATE_TIGHT ) continue; /* ftxvalidator silently skips such an entry */ FT_TRACE4(( "continuing with exchanged values\n" )); @@ -624,19 +624,19 @@ for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) { - value = valid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), + value = gxvalid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), &base_value, limit, - valid ); + gxvalid ); - valid->lookupval_func( gid, &value, valid ); + gxvalid->lookupval_func( gid, &value, gxvalid ); } } - gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; + gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -645,26 +645,26 @@ static void gxv_LookupTable_fmt6_skip_endmarkers( FT_Bytes table, FT_UShort unitSize, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; - while ( p < valid->root->limit ) + while ( p < gxvalid->root->limit ) { if ( p[0] != 0xFF || p[1] != 0xFF ) break; p += unitSize; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_LookupTable_fmt6_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort unit; @@ -679,8 +679,8 @@ GXV_NAME_ENTER( "LookupTable format 6" ); unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid ); + p += gxvalid->subtable_length; GXV_UNITSIZE_VALIDATE( "format6", unitSize, nUnits, 4 ); @@ -688,9 +688,9 @@ { GXV_LIMIT_CHECK( 2 + 2 ); glyph = FT_NEXT_USHORT( p ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); + value = GXV_LOOKUP_VALUE_LOAD( p, gxvalid->lookupval_sign ); - if ( gxv_glyphid_validate( glyph, valid ) ) + if ( gxv_glyphid_validate( glyph, gxvalid ) ) GXV_TRACE(( " endmarker found within defined range" " (entry %d < nUnits=%d)\n", unit, nUnits )); @@ -703,13 +703,13 @@ } prev_glyph = glyph; - valid->lookupval_func( glyph, &value, valid ); + gxvalid->lookupval_func( glyph, &value, gxvalid ); } - gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; + gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -718,7 +718,7 @@ static void gxv_LookupTable_fmt8_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort i; @@ -735,18 +735,18 @@ firstGlyph = FT_NEXT_USHORT( p ); glyphCount = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), valid ); + gxv_glyphid_validate( firstGlyph, gxvalid ); + gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), gxvalid ); /* valueArray */ for ( i = 0; i < glyphCount; i++ ) { GXV_LIMIT_CHECK( 2 ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, valid ); + value = GXV_LOOKUP_VALUE_LOAD( p, gxvalid->lookupval_sign ); + gxvalid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, gxvalid ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -754,7 +754,7 @@ FT_LOCAL_DEF( void ) gxv_LookupTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort format; @@ -778,7 +778,7 @@ GXV_NAME_ENTER( "LookupTable" ); /* lookuptbl_head may be used in fmt4 transit function. */ - valid->lookuptbl_head = table; + gxvalid->lookuptbl_head = table; /* format */ GXV_LIMIT_CHECK( 2 ); @@ -792,10 +792,10 @@ if ( func == NULL ) FT_INVALID_FORMAT; - func( p, limit, valid ); - p += valid->subtable_length; + func( p, limit, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -811,7 +811,7 @@ FT_LOCAL_DEF( FT_Int ) gxv_glyphid_validate( FT_UShort gid, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Face face; @@ -822,7 +822,7 @@ return 1; } - face = valid->face; + face = gxvalid->face; if ( face->num_glyphs < gid ) { GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n", @@ -844,18 +844,18 @@ FT_LOCAL_DEF( void ) gxv_ctlPoint_validate( FT_UShort gid, - FT_Short ctl_point, - GXV_Validator valid ) + FT_UShort ctl_point, + GXV_Validator gxvalid ) { FT_Face face; FT_Error error; FT_GlyphSlot glyph; FT_Outline outline; - short n_points; + FT_UShort n_points; - face = valid->face; + face = gxvalid->face; error = FT_Load_Glyph( face, gid, @@ -865,8 +865,7 @@ glyph = face->glyph; outline = glyph->outline; - n_points = outline.n_points; - + n_points = (FT_UShort)outline.n_points; if ( !( ctl_point < n_points ) ) FT_INVALID_DATA; @@ -885,7 +884,7 @@ gxv_sfntName_validate( FT_UShort name_index, FT_UShort min_index, FT_UShort max_index, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_SfntName name; FT_UInt i; @@ -897,11 +896,11 @@ if ( name_index < min_index || max_index < name_index ) FT_INVALID_FORMAT; - nnames = FT_Get_Sfnt_Name_Count( valid->face ); + nnames = FT_Get_Sfnt_Name_Count( gxvalid->face ); for ( i = 0; i < nnames; i++ ) { - if ( FT_Get_Sfnt_Name( valid->face, i, &name ) != FT_Err_Ok ) - continue ; + if ( FT_Get_Sfnt_Name( gxvalid->face, i, &name ) != FT_Err_Ok ) + continue; if ( name.name_id == name_index ) goto Out; @@ -944,7 +943,7 @@ FT_UShort* length_p, FT_UShort stateSize, FT_Byte* maxClassID_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Bytes limit = table + *length_p; @@ -965,7 +964,7 @@ if ( !nGlyphs ) goto Out; - gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs ), valid ); + gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs ), gxvalid ); { FT_Byte nGlyphInClass[256]; @@ -1022,9 +1021,9 @@ FT_UShort stateSize, FT_Byte* maxState_p, FT_Byte* maxEntry_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table; + FT_Bytes p = table; FT_Bytes limit = table + *length_p; FT_Byte clazz; FT_Byte entry; @@ -1076,7 +1075,7 @@ FT_Byte maxClassID, FT_Bytes statetable_table, FT_Bytes statetable_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Bytes limit = table + *length_p; @@ -1160,22 +1159,17 @@ case GXV_GLYPHOFFSET_LONG: glyphOffset.l = FT_NEXT_LONG( p ); break; - - default: - GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); - goto Exit; } - if ( NULL != valid->statetable.entry_validate_func ) - valid->statetable.entry_validate_func( state, - flags, - &glyphOffset, - statetable_table, - statetable_limit, - valid ); + if ( NULL != gxvalid->statetable.entry_validate_func ) + gxvalid->statetable.entry_validate_func( state, + flags, + &glyphOffset, + statetable_table, + statetable_limit, + gxvalid ); } - Exit: *length_p = (FT_UShort)( p - table ); GXV_EXIT; @@ -1192,7 +1186,7 @@ FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort o[3]; FT_UShort* l[3]; @@ -1206,14 +1200,14 @@ l[1] = stateArray_length_p; l[2] = entryTable_length_p; - gxv_set_length_by_ushort_offset( o, l, buff, 3, table_size, valid ); + gxv_set_length_by_ushort_offset( o, l, buff, 3, table_size, gxvalid ); } FT_LOCAL_DEF( void ) gxv_StateTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort stateSize; FT_UShort classTable; /* offset to Class(Sub)Table */ @@ -1250,11 +1244,11 @@ if ( stateSize > 0xFF ) FT_INVALID_DATA; - if ( valid->statetable.optdata_load_func != NULL ) - valid->statetable.optdata_load_func( p, limit, valid ); + if ( gxvalid->statetable.optdata_load_func != NULL ) + gxvalid->statetable.optdata_load_func( p, limit, gxvalid ); - if ( valid->statetable.subtable_setup_func != NULL) - setup_func = valid->statetable.subtable_setup_func; + if ( gxvalid->statetable.subtable_setup_func != NULL) + setup_func = gxvalid->statetable.subtable_setup_func; else setup_func = gxv_StateTable_subtable_setup; @@ -1265,7 +1259,7 @@ &classTable_length, &stateArray_length, &entryTable_length, - valid ); + gxvalid ); GXV_TRACE(( "StateTable Subtables\n" )); @@ -1274,7 +1268,7 @@ &classTable_length, stateSize, &maxClassID, - valid ); + gxvalid ); else maxClassID = (FT_Byte)( stateSize - 1 ); @@ -1285,10 +1279,12 @@ stateSize, &maxState, &maxEntry, - valid ); + gxvalid ); else { +#if 0 maxState = 1; /* 0:start of text, 1:start of line are predefined */ +#endif maxEntry = 0; } @@ -1304,7 +1300,7 @@ maxClassID, table, limit, - valid ); + gxvalid ); GXV_EXIT; } @@ -1320,7 +1316,7 @@ FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_ULong o[3]; FT_ULong* l[3]; @@ -1334,21 +1330,21 @@ l[1] = stateArray_length_p; l[2] = entryTable_length_p; - gxv_set_length_by_ulong_offset( o, l, buff, 3, table_size, valid ); + gxv_set_length_by_ulong_offset( o, l, buff, 3, table_size, gxvalid ); } static void gxv_XClassTable_lookupval_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); - if ( value_p->u >= valid->xstatetable.nClasses ) + if ( value_p->u >= gxvalid->xstatetable.nClasses ) FT_INVALID_DATA; - if ( value_p->u > valid->xstatetable.maxClassID ) - valid->xstatetable.maxClassID = value_p->u; + if ( value_p->u > gxvalid->xstatetable.maxClassID ) + gxvalid->xstatetable.maxClassID = value_p->u; } @@ -1382,7 +1378,7 @@ gxv_XClassTable_lookupfmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -1393,7 +1389,7 @@ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK ( 2 ); @@ -1410,7 +1406,7 @@ FT_ULong stateSize, FT_UShort* maxState_p, FT_UShort* maxEntry_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Bytes limit = table + *length_p; @@ -1447,7 +1443,7 @@ GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n", *maxState_p, *maxEntry_p )); - *length_p = p - table; + *length_p = (FT_ULong)( p - table ); GXV_EXIT; } @@ -1461,7 +1457,7 @@ FT_UShort maxClassID, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Bytes limit = table + *length_p; @@ -1476,7 +1472,7 @@ if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit ) FT_INVALID_TOO_SHORT; - for (entry = 0; entry <= maxEntry ; entry++ ) + for (entry = 0; entry <= maxEntry; entry++ ) { FT_UShort newState_idx; FT_UShort flags; @@ -1538,17 +1534,17 @@ goto Exit; } - if ( NULL != valid->xstatetable.entry_validate_func ) - valid->xstatetable.entry_validate_func( state, - flags, - &glyphOffset, - xstatetable_table, - xstatetable_limit, - valid ); + if ( NULL != gxvalid->xstatetable.entry_validate_func ) + gxvalid->xstatetable.entry_validate_func( state, + flags, + &glyphOffset, + xstatetable_table, + xstatetable_limit, + gxvalid ); } Exit: - *length_p = p - table; + *length_p = (FT_ULong)( p - table ); GXV_EXIT; } @@ -1557,7 +1553,7 @@ FT_LOCAL_DEF( void ) gxv_XStateTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* StateHeader members */ FT_ULong classTable; /* offset to Class(Sub)Table */ @@ -1580,68 +1576,72 @@ GXV_TRACE(( "XStateTable header\n" )); GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); - valid->xstatetable.nClasses = FT_NEXT_ULONG( p ); + gxvalid->xstatetable.nClasses = FT_NEXT_ULONG( p ); classTable = FT_NEXT_ULONG( p ); stateArray = FT_NEXT_ULONG( p ); entryTable = FT_NEXT_ULONG( p ); - GXV_TRACE(( "nClasses =0x%08x\n", valid->xstatetable.nClasses )); + GXV_TRACE(( "nClasses =0x%08x\n", gxvalid->xstatetable.nClasses )); GXV_TRACE(( "offset to classTable=0x%08x\n", classTable )); GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray )); GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable )); - if ( valid->xstatetable.nClasses > 0xFFFFU ) + if ( gxvalid->xstatetable.nClasses > 0xFFFFU ) FT_INVALID_DATA; GXV_TRACE(( "StateTable Subtables\n" )); - if ( valid->xstatetable.optdata_load_func != NULL ) - valid->xstatetable.optdata_load_func( p, limit, valid ); + if ( gxvalid->xstatetable.optdata_load_func != NULL ) + gxvalid->xstatetable.optdata_load_func( p, limit, gxvalid ); - if ( valid->xstatetable.subtable_setup_func != NULL ) - setup_func = valid->xstatetable.subtable_setup_func; + if ( gxvalid->xstatetable.subtable_setup_func != NULL ) + setup_func = gxvalid->xstatetable.subtable_setup_func; else setup_func = gxv_XStateTable_subtable_setup; - setup_func( limit - table, + setup_func( (FT_ULong)( limit - table ), classTable, stateArray, entryTable, &classTable_length, &stateArray_length, &entryTable_length, - valid ); + gxvalid ); if ( classTable != 0 ) { - valid->xstatetable.maxClassID = 0; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_XClassTable_lookupval_validate; - valid->lookupfmt4_trans = gxv_XClassTable_lookupfmt4_transit; + gxvalid->xstatetable.maxClassID = 0; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_XClassTable_lookupval_validate; + gxvalid->lookupfmt4_trans = gxv_XClassTable_lookupfmt4_transit; gxv_LookupTable_validate( table + classTable, table + classTable + classTable_length, - valid ); - if ( valid->subtable_length < classTable_length ) - classTable_length = valid->subtable_length; + gxvalid ); +#if 0 + if ( gxvalid->subtable_length < classTable_length ) + classTable_length = gxvalid->subtable_length; +#endif } else { /* XXX: check range? */ - valid->xstatetable.maxClassID = - (FT_UShort)( valid->xstatetable.nClasses - 1 ); + gxvalid->xstatetable.maxClassID = + (FT_UShort)( gxvalid->xstatetable.nClasses - 1 ); } if ( stateArray != 0 ) gxv_XStateArray_validate( table + stateArray, &stateArray_length, - valid->xstatetable.maxClassID, - valid->xstatetable.nClasses, + gxvalid->xstatetable.maxClassID, + gxvalid->xstatetable.nClasses, &maxState, &maxEntry, - valid ); + gxvalid ); else { +#if 0 maxState = 1; /* 0:start of text, 1:start of line are predefined */ +#endif maxEntry = 0; } @@ -1653,10 +1653,10 @@ &entryTable_length, maxEntry, stateArray_length, - valid->xstatetable.maxClassID, + gxvalid->xstatetable.maxClassID, table, limit, - valid ); + gxvalid ); GXV_EXIT; } @@ -1713,7 +1713,7 @@ FT_LOCAL_DEF( void ) gxv_odtect_validate( GXV_odtect_Range odtect, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UInt i, j; @@ -1727,6 +1727,7 @@ odtect->range[j].start, odtect->range[j].length ) ) { +#ifdef FT_DEBUG_LEVEL_TRACE if ( odtect->range[i].name || odtect->range[j].name ) GXV_TRACE(( "found overlap between range %d and range %d\n", i, j )); @@ -1734,6 +1735,7 @@ GXV_TRACE(( "found overlap between `%s' and `%s\'\n", odtect->range[i].name, odtect->range[j].name )); +#endif FT_INVALID_OFFSET; } diff --git a/drivers/freetype/src/gxvalid/gxvcommn.h b/drivers/freetype/src/gxvalid/gxvcommn.h index 1ff87e4423..9470c8412b 100644 --- a/drivers/freetype/src/gxvalid/gxvcommn.h +++ b/drivers/freetype/src/gxvalid/gxvcommn.h @@ -4,8 +4,8 @@ /* */ /* TrueTypeGX/AAT common tables validation (specification). */ /* */ -/* Copyright 2004, 2005, 2012 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,8 +39,8 @@ */ -#ifndef __GXVCOMMN_H__ -#define __GXVCOMMN_H__ +#ifndef GXVCOMMN_H_ +#define GXVCOMMN_H_ #include <ft2build.h> @@ -62,7 +62,7 @@ FT_BEGIN_HEADER #undef GXV_LOAD_UNUSED_VARS /* debug purpose */ -#define IS_PARANOID_VALIDATION ( valid->root->level >= FT_VALIDATE_PARANOID ) +#define IS_PARANOID_VALIDATION ( gxvalid->root->level >= FT_VALIDATE_PARANOID ) #define GXV_SET_ERR_IF_PARANOID( err ) { if ( IS_PARANOID_VALIDATION ) ( err ); } /*************************************************************************/ @@ -81,7 +81,7 @@ FT_BEGIN_HEADER typedef void (*GXV_Validate_Func)( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); /* ====================== LookupTable Validator ======================== */ @@ -106,13 +106,13 @@ FT_BEGIN_HEADER typedef void (*GXV_Lookup_Value_Validate_Func)( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef GXV_LookupValueDesc (*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); /* ====================== StateTable Validator ========================= */ @@ -131,10 +131,10 @@ FT_BEGIN_HEADER #define GXV_GLYPHOFFSET_FMT( table ) \ - ( valid->table.entry_glyphoffset_fmt ) + ( gxvalid->table.entry_glyphoffset_fmt ) #define GXV_GLYPHOFFSET_SIZE( table ) \ - ( valid->table.entry_glyphoffset_fmt / 2 ) + ( gxvalid->table.entry_glyphoffset_fmt / 2 ) /* ----------------------- 16bit StateTable ---------------------------- */ @@ -160,7 +160,7 @@ FT_BEGIN_HEADER FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef void (*GXV_StateTable_Entry_Validate_Func)( @@ -169,12 +169,12 @@ FT_BEGIN_HEADER GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes statetable_table, FT_Bytes statetable_limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef void (*GXV_StateTable_OptData_Load_Func)( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef struct GXV_StateTable_ValidatorRec_ { @@ -202,7 +202,7 @@ FT_BEGIN_HEADER FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef void (*GXV_XStateTable_Entry_Validate_Func)( @@ -211,7 +211,7 @@ FT_BEGIN_HEADER GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef GXV_StateTable_OptData_Load_Func GXV_XStateTable_OptData_Load_Func; @@ -263,35 +263,35 @@ FT_BEGIN_HEADER #define GXV_TABLE_DATA( tag, field ) \ - ( ( (GXV_ ## tag ## _Data)valid->table_data )->field ) + ( ( (GXV_ ## tag ## _Data)gxvalid->table_data )->field ) #undef FT_INVALID_ -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid->root, _prefix ## _error ) +#define FT_INVALID_( _error ) \ + ft_validator_error( gxvalid->root, FT_THROW( _error ) ) #define GXV_LIMIT_CHECK( _count ) \ FT_BEGIN_STMNT \ - if ( p + _count > ( limit? limit : valid->root->limit ) ) \ + if ( p + _count > ( limit? limit : gxvalid->root->limit ) ) \ FT_INVALID_TOO_SHORT; \ FT_END_STMNT #ifdef FT_DEBUG_LEVEL_TRACE -#define GXV_INIT valid->debug_indent = 0 +#define GXV_INIT gxvalid->debug_indent = 0 #define GXV_NAME_ENTER( name ) \ FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + gxvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \ FT_TRACE4(( "%s table\n", name )); \ FT_END_STMNT -#define GXV_EXIT valid->debug_indent -= 2 +#define GXV_EXIT gxvalid->debug_indent -= 2 #define GXV_TRACE( s ) \ FT_BEGIN_STMNT \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \ FT_TRACE4( s ); \ FT_END_STMNT @@ -318,7 +318,7 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ { \ if ( (a) & 3 ) \ - FT_INVALID_OFFSET ; \ + FT_INVALID_OFFSET; \ } \ FT_END_STMNT @@ -338,7 +338,7 @@ FT_BEGIN_HEADER \ \ for ( b = p; b < (FT_Bytes)p + len; b++ ) \ - FT_TRACE1(("\\x%02x", *b)) ; \ + FT_TRACE1(("\\x%02x", *b)); \ } \ FT_END_STMNT @@ -349,10 +349,10 @@ FT_BEGIN_HEADER \ \ for ( b = p; b < (FT_Bytes)p + len; b++ ) \ - if ( 0x40 < *b && *b < 0x7e ) \ - FT_TRACE1(("%c", *b)) ; \ + if ( 0x40 < *b && *b < 0x7E ) \ + FT_TRACE1(("%c", *b)); \ else \ - FT_TRACE1(("\\x%02x", *b)) ; \ + FT_TRACE1(("\\x%02x", *b)); \ } \ FT_END_STMNT @@ -373,12 +373,12 @@ FT_BEGIN_HEADER FT_Bytes limit, FT_UShort* unitSize_p, FT_UShort* nUnits_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_LookupTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); /*************************************************************************/ @@ -391,7 +391,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Int ) gxv_glyphid_validate( FT_UShort gid, - GXV_Validator valid ); + GXV_Validator gxvalid ); /*************************************************************************/ @@ -404,8 +404,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) gxv_ctlPoint_validate( FT_UShort gid, - FT_Short ctl_point, - GXV_Validator valid ); + FT_UShort ctl_point, + GXV_Validator gxvalid ); /*************************************************************************/ @@ -420,7 +420,7 @@ FT_BEGIN_HEADER gxv_sfntName_validate( FT_UShort name_index, FT_UShort min_index, FT_UShort max_index, - GXV_Validator valid ); + GXV_Validator gxvalid ); /*************************************************************************/ @@ -439,7 +439,7 @@ FT_BEGIN_HEADER FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_XStateTable_subtable_setup( FT_ULong table_size, @@ -449,17 +449,17 @@ FT_BEGIN_HEADER FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_StateTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_XStateTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); /*************************************************************************/ @@ -475,14 +475,14 @@ FT_BEGIN_HEADER FT_Bytes limit, FT_Byte* min, FT_Byte* max, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_array_getlimits_ushort( FT_Bytes table, FT_Bytes limit, FT_UShort* min, FT_UShort* max, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_set_length_by_ushort_offset( FT_UShort* offset, @@ -490,7 +490,7 @@ FT_BEGIN_HEADER FT_UShort* buff, FT_UInt nmemb, FT_UShort limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_set_length_by_ulong_offset( FT_ULong* offset, @@ -498,19 +498,19 @@ FT_BEGIN_HEADER FT_ULong* buff, FT_UInt nmemb, FT_ULong limit, - GXV_Validator valid); + GXV_Validator gxvalid); #define GXV_SUBTABLE_OFFSET_CHECK( _offset ) \ FT_BEGIN_STMNT \ - if ( (_offset) > valid->subtable_length ) \ + if ( (_offset) > gxvalid->subtable_length ) \ FT_INVALID_OFFSET; \ FT_END_STMNT #define GXV_SUBTABLE_LIMIT_CHECK( _count ) \ FT_BEGIN_STMNT \ - if ( ( p + (_count) - valid->subtable_start ) > \ - valid->subtable_length ) \ + if ( ( p + (_count) - gxvalid->subtable_start ) > \ + gxvalid->subtable_length ) \ FT_INVALID_TOO_SHORT; \ FT_END_STMNT @@ -556,7 +556,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) gxv_odtect_validate( GXV_odtect_Range odtect, - GXV_Validator valid ); + GXV_Validator gxvalid ); #define GXV_ODTECT( n, odtect ) \ @@ -576,7 +576,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVCOMMN_H__ */ +#endif /* GXVCOMMN_H_ */ /* END */ diff --git a/drivers/freetype/src/gxvalid/gxverror.h b/drivers/freetype/src/gxvalid/gxverror.h index c573b72de7..2e53355ce4 100644 --- a/drivers/freetype/src/gxvalid/gxverror.h +++ b/drivers/freetype/src/gxvalid/gxverror.h @@ -4,8 +4,8 @@ /* */ /* TrueTypeGX/AAT validation module error codes (specification only). */ /* */ -/* Copyright 2004, 2005, 2012-2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,12 +32,12 @@ /* */ /*************************************************************************/ -#ifndef __GXVERROR_H__ -#define __GXVERROR_H__ +#ifndef GXVERROR_H_ +#define GXVERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX GXV_Err_ @@ -45,7 +45,7 @@ #include FT_ERRORS_H -#endif /* __GXVERROR_H__ */ +#endif /* GXVERROR_H_ */ /* END */ diff --git a/drivers/freetype/src/gxvalid/gxvfeat.c b/drivers/freetype/src/gxvalid/gxvfeat.c index 6f75650991..5bff7c261d 100644 --- a/drivers/freetype/src/gxvalid/gxvfeat.c +++ b/drivers/freetype/src/gxvalid/gxvfeat.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT feat table validation (body). */ /* */ -/* Copyright 2004, 2005, 2008, 2012 by */ +/* Copyright 2004-2016 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -82,7 +82,7 @@ gxv_feat_registry_validate( FT_UShort feature, FT_UShort nSettings, FT_Bool exclusive, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_NAME_ENTER( "feature in registry" ); @@ -108,7 +108,7 @@ { /* Don't use here. Apple is reserved. */ GXV_TRACE(( "feature number %d is reserved by Apple\n", feature )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level >= FT_VALIDATE_TIGHT ) FT_INVALID_DATA; } @@ -117,7 +117,7 @@ GXV_TRACE(( "feature %d: nSettings %d != defined nSettings %d\n", feature, nSettings, gxv_feat_registry[feature].nSettings )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level >= FT_VALIDATE_TIGHT ) FT_INVALID_DATA; } @@ -125,7 +125,7 @@ { GXV_TRACE(( "exclusive flag %d differs from predefined value\n", exclusive )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level >= FT_VALIDATE_TIGHT ) FT_INVALID_DATA; } @@ -137,7 +137,7 @@ static void gxv_feat_name_index_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -153,7 +153,7 @@ gxv_sfntName_validate( (FT_UShort)nameIndex, 255, 32768U, - valid ); + gxvalid ); GXV_EXIT; } @@ -163,7 +163,7 @@ gxv_feat_setting_validate( FT_Bytes table, FT_Bytes limit, FT_Bool exclusive, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort setting; @@ -179,7 +179,7 @@ if ( exclusive && ( setting & 1 ) == 0 ) FT_INVALID_DATA; - gxv_feat_name_index_validate( p, limit, valid ); + gxv_feat_name_index_validate( p, limit, gxvalid ); GXV_FEAT_DATA( setting ) = setting; @@ -190,7 +190,7 @@ static void gxv_feat_name_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UInt reserved_size = GXV_FEAT_DATA( reserved_size ); @@ -240,14 +240,14 @@ FT_INVALID_FORMAT; } - gxv_feat_registry_validate( feature, nSettings, exclusive, valid ); + gxv_feat_registry_validate( feature, nSettings, exclusive, gxvalid ); - gxv_feat_name_index_validate( p, limit, valid ); + gxv_feat_name_index_validate( p, limit, gxvalid ); - p = valid->root->base + settingTable; + p = gxvalid->root->base + settingTable; for ( last_setting = -1, i = 0; i < nSettings; i++ ) { - gxv_feat_setting_validate( p, limit, exclusive, valid ); + gxv_feat_setting_validate( p, limit, exclusive, gxvalid ); if ( (FT_Int)GXV_FEAT_DATA( setting ) <= last_setting ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); @@ -274,8 +274,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_feat_DataRec featrec; GXV_feat_Data feat = &featrec; @@ -289,9 +289,9 @@ FT_Int last_feature; - valid->root = ftvalid; - valid->table_data = feat; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = feat; + gxvalid->face = face; FT_TRACE3(( "validating `feat' table\n" )); GXV_INIT; @@ -323,7 +323,7 @@ for ( last_feature = -1, i = 0; i < featureNameCount; i++ ) { - gxv_feat_name_validate( p, limit, valid ); + gxv_feat_name_validate( p, limit, gxvalid ); if ( (FT_Int)GXV_FEAT_DATA( feature ) <= last_feature ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); diff --git a/drivers/freetype/src/gxvalid/gxvfeat.h b/drivers/freetype/src/gxvalid/gxvfeat.h index 049d23a0b9..284bada891 100644 --- a/drivers/freetype/src/gxvalid/gxvfeat.h +++ b/drivers/freetype/src/gxvalid/gxvfeat.h @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT feat table validation (specification). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVFEAT_H__ -#define __GXVFEAT_H__ +#ifndef GXVFEAT_H_ +#define GXVFEAT_H_ #include "gxvalid.h" @@ -166,7 +167,7 @@ }; -#endif /* __GXVFEAT_H__ */ +#endif /* GXVFEAT_H_ */ /* END */ diff --git a/drivers/freetype/src/gxvalid/gxvfgen.c b/drivers/freetype/src/gxvalid/gxvfgen.c index e48778a2a1..667dac3cde 100644 --- a/drivers/freetype/src/gxvalid/gxvfgen.c +++ b/drivers/freetype/src/gxvalid/gxvfgen.c @@ -5,7 +5,8 @@ /* Generate feature registry data for gxv `feat' validator. */ /* This program is derived from gxfeatreg.c in gxlayout. */ /* */ -/* Copyright 2004, 2005, 2006 by Masatake YAMATO and Redhat K.K. */ +/* Copyright 2004-2016 by */ +/* Masatake YAMATO and Redhat K.K. */ /* */ /* This file may only be used, */ /* modified, and distributed under the terms of the FreeType project */ diff --git a/drivers/freetype/src/gxvalid/gxvjust.c b/drivers/freetype/src/gxvalid/gxvjust.c index 7816e0b7fb..20d29bfbc8 100644 --- a/drivers/freetype/src/gxvalid/gxvjust.c +++ b/drivers/freetype/src/gxvalid/gxvjust.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT just table validation (body). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,7 +42,7 @@ /* * referred `just' table format specification: - * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6just.html + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6just.html * last updated 2000. * ---------------------------------------------- * [JUST HEADER]: GXV_JUST_HEADER_SIZE @@ -69,14 +70,14 @@ static void gxv_just_check_max_gid( FT_UShort gid, const FT_String* msg_tag, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - if ( gid < valid->face->num_glyphs ) + if ( gid < gxvalid->face->num_glyphs ) return; GXV_TRACE(( "just table includes too large %s" " GID=%d > %d (in maxp)\n", - msg_tag, gid, valid->face->num_glyphs )); + msg_tag, gid, gxvalid->face->num_glyphs )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } @@ -84,7 +85,7 @@ static void gxv_just_wdp_entry_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong justClass; @@ -112,7 +113,7 @@ #endif /* According to Apple spec, only 7bits in justClass is used */ - if ( ( justClass & 0xFFFFFF80 ) != 0 ) + if ( ( justClass & 0xFFFFFF80UL ) != 0 ) { GXV_TRACE(( "just table includes non-zero value" " in unused justClass higher bits" @@ -120,14 +121,14 @@ GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_wdc_entry_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong count, i; @@ -138,20 +139,20 @@ for ( i = 0; i < count; i++ ) { GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count )); - gxv_just_wdp_entry_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_wdp_entry_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_widthDeltaClusters_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table ; + FT_Bytes p = table; FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max ); FT_UInt i; @@ -163,11 +164,11 @@ for ( i = 0; p <= wdc_end; i++ ) { - gxv_just_wdc_entry_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_wdc_entry_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -176,7 +177,7 @@ static void gxv_just_actSubrecord_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -191,8 +192,8 @@ GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); - lowerLimit = FT_NEXT_ULONG( p ); - upperLimit = FT_NEXT_ULONG( p ); + lowerLimit = FT_NEXT_LONG( p ); + upperLimit = FT_NEXT_LONG( p ); #ifdef GXV_LOAD_UNUSED_VARS order = FT_NEXT_USHORT( p ); #else @@ -214,17 +215,17 @@ GXV_LIMIT_CHECK( 2 ); glyphs = FT_NEXT_USHORT( p ); - gxv_just_check_max_gid( glyphs, "type0:glyphs", valid ); + gxv_just_check_max_gid( glyphs, "type0:glyphs", gxvalid ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_actSubrecord_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort addGlyph; @@ -233,20 +234,20 @@ GXV_LIMIT_CHECK( 2 ); addGlyph = FT_NEXT_USHORT( p ); - gxv_just_check_max_gid( addGlyph, "type1:addGlyph", valid ); + gxv_just_check_max_gid( addGlyph, "type1:addGlyph", gxvalid ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_actSubrecord_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_UNUSED_VARS - FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ + FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ #endif FT_UShort addGlyph; FT_UShort substGlyph; @@ -262,18 +263,18 @@ substGlyph = FT_NEXT_USHORT( p ); if ( addGlyph != 0xFFFF ) - gxv_just_check_max_gid( addGlyph, "type2:addGlyph", valid ); + gxv_just_check_max_gid( addGlyph, "type2:addGlyph", gxvalid ); - gxv_just_check_max_gid( substGlyph, "type2:substGlyph", valid ); + gxv_just_check_max_gid( substGlyph, "type2:substGlyph", gxvalid ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_actSubrecord_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong variantsAxis; @@ -284,13 +285,13 @@ GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); variantsAxis = FT_NEXT_ULONG( p ); - minimumLimit = FT_NEXT_ULONG( p ); - noStretchValue = FT_NEXT_ULONG( p ); - maximumLimit = FT_NEXT_ULONG( p ); + minimumLimit = FT_NEXT_LONG( p ); + noStretchValue = FT_NEXT_LONG( p ); + maximumLimit = FT_NEXT_LONG( p ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); - if ( variantsAxis != 0x64756374 ) /* 'duct' */ + if ( variantsAxis != 0x64756374L ) /* 'duct' */ GXV_TRACE(( "variantsAxis 0x%08x is non default value", variantsAxis )); @@ -310,7 +311,7 @@ static void gxv_just_actSubrecord_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort flags; @@ -324,9 +325,9 @@ if ( flags ) GXV_TRACE(( "type5: nonzero value 0x%04x in unused flags\n", flags )); - gxv_just_check_max_gid( glyph, "type5:glyph", valid ); + gxv_just_check_max_gid( glyph, "type5:glyph", gxvalid ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } @@ -334,7 +335,7 @@ static void gxv_just_actSubrecord_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort actionClass; @@ -354,21 +355,21 @@ GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); if ( actionType == 0 ) - gxv_just_actSubrecord_type0_validate( p, limit, valid ); + gxv_just_actSubrecord_type0_validate( p, limit, gxvalid ); else if ( actionType == 1 ) - gxv_just_actSubrecord_type1_validate( p, limit, valid ); + gxv_just_actSubrecord_type1_validate( p, limit, gxvalid ); else if ( actionType == 2 ) - gxv_just_actSubrecord_type2_validate( p, limit, valid ); + gxv_just_actSubrecord_type2_validate( p, limit, gxvalid ); else if ( actionType == 3 ) ; /* Stretch glyph action: no actionData */ else if ( actionType == 4 ) - gxv_just_actSubrecord_type4_validate( p, limit, valid ); + gxv_just_actSubrecord_type4_validate( p, limit, gxvalid ); else if ( actionType == 5 ) - gxv_just_actSubrecord_type5_validate( p, limit, valid ); + gxv_just_actSubrecord_type5_validate( p, limit, gxvalid ); else FT_INVALID_DATA; - valid->subtable_length = actionLength; + gxvalid->subtable_length = actionLength; GXV_EXIT; } @@ -377,7 +378,7 @@ static void gxv_just_pcActionRecord_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong actionCount; @@ -390,11 +391,11 @@ for ( i = 0; i < actionCount; i++ ) { - gxv_just_actSubrecord_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_actSubrecord_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -403,7 +404,7 @@ static void gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); @@ -417,19 +418,19 @@ static void gxv_just_pcLookupTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table; + FT_Bytes p = table; GXV_NAME_ENTER( "just pcLookupTable" ); GXV_JUST_DATA( pc_offset_max ) = 0x0000; GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; - gxv_LookupTable_validate( p, limit, valid ); + gxv_LookupTable_validate( p, limit, gxvalid ); /* subtable_length is set by gxv_LookupTable_validate() */ @@ -440,20 +441,20 @@ static void gxv_just_postcompTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_NAME_ENTER( "just postcompTable" ); - gxv_just_pcLookupTable_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_pcLookupTable_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; - gxv_just_pcActionRecord_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_pcActionRecord_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -466,7 +467,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS /* TODO: validate markClass & currentClass */ @@ -480,7 +481,7 @@ FT_UNUSED( glyphOffset_p ); FT_UNUSED( table ); FT_UNUSED( limit ); - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); #ifndef GXV_LOAD_UNUSED_VARS FT_UNUSED( flags ); @@ -496,7 +497,7 @@ static void gxv_just_justClassTable_validate ( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort length; @@ -521,14 +522,14 @@ GXV_TRACE(( " justClassTable: nonzero value (0x%08x)" " in unused subFeatureFlags\n", subFeatureFlags )); - valid->statetable.optdata = NULL; - valid->statetable.optdata_load_func = NULL; - valid->statetable.subtable_setup_func = NULL; - valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = + gxvalid->statetable.optdata = NULL; + gxvalid->statetable.optdata_load_func = NULL; + gxvalid->statetable.subtable_setup_func = NULL; + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + gxvalid->statetable.entry_validate_func = gxv_just_classTable_entry_validate; - gxv_StateTable_validate( p, table + length, valid ); + gxv_StateTable_validate( p, table + length, gxvalid ); /* subtable_length is set by gxv_LookupTable_validate() */ @@ -539,7 +540,7 @@ static void gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); @@ -553,7 +554,7 @@ static void gxv_just_justData_lookuptable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -561,10 +562,10 @@ GXV_JUST_DATA( wdc_offset_max ) = 0x0000; GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; - gxv_LookupTable_validate( p, limit, valid ); + gxv_LookupTable_validate( p, limit, gxvalid ); /* subtable_length is set by gxv_LookupTable_validate() */ @@ -578,7 +579,7 @@ static void gxv_just_justData_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* * following 3 offsets are measured from the start of `just' @@ -604,36 +605,36 @@ GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset )); GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset )); - gxv_just_justData_lookuptable_validate( p, limit, valid ); - gxv_odtect_add_range( p, valid->subtable_length, + gxv_just_justData_lookuptable_validate( p, limit, gxvalid ); + gxv_odtect_add_range( p, gxvalid->subtable_length, "just_LookupTable", odtect ); if ( wdcTableOffset ) { gxv_just_widthDeltaClusters_validate( - valid->root->base + wdcTableOffset, limit, valid ); - gxv_odtect_add_range( valid->root->base + wdcTableOffset, - valid->subtable_length, "just_wdcTable", odtect ); + gxvalid->root->base + wdcTableOffset, limit, gxvalid ); + gxv_odtect_add_range( gxvalid->root->base + wdcTableOffset, + gxvalid->subtable_length, "just_wdcTable", odtect ); } if ( pcTableOffset ) { - gxv_just_postcompTable_validate( valid->root->base + pcTableOffset, - limit, valid ); - gxv_odtect_add_range( valid->root->base + pcTableOffset, - valid->subtable_length, "just_pcTable", odtect ); + gxv_just_postcompTable_validate( gxvalid->root->base + pcTableOffset, + limit, gxvalid ); + gxv_odtect_add_range( gxvalid->root->base + pcTableOffset, + gxvalid->subtable_length, "just_pcTable", odtect ); } if ( justClassTableOffset ) { gxv_just_justClassTable_validate( - valid->root->base + justClassTableOffset, limit, valid ); - gxv_odtect_add_range( valid->root->base + justClassTableOffset, - valid->subtable_length, "just_justClassTable", + gxvalid->root->base + justClassTableOffset, limit, gxvalid ); + gxv_odtect_add_range( gxvalid->root->base + justClassTableOffset, + gxvalid->subtable_length, "just_justClassTable", odtect ); } - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); GXV_EXIT; } @@ -647,8 +648,8 @@ FT_Bytes p = table; FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_just_DataRec justrec; GXV_just_Data just = &justrec; @@ -662,21 +663,22 @@ GXV_ODTECT_INIT( odtect ); - valid->root = ftvalid; - valid->table_data = just; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = just; + gxvalid->face = face; FT_TRACE3(( "validating `just' table\n" )); GXV_INIT; - limit = valid->root->limit; + limit = gxvalid->root->limit; GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 ); version = FT_NEXT_ULONG( p ); format = FT_NEXT_USHORT( p ); horizOffset = FT_NEXT_USHORT( p ); vertOffset = FT_NEXT_USHORT( p ); - gxv_odtect_add_range( table, p - table, "just header", odtect ); + gxv_odtect_add_range( table, (FT_ULong)( p - table ), + "just header", odtect ); /* Version 1.0 (always:2000) */ @@ -696,19 +698,19 @@ /* validate justData */ if ( 0 < horizOffset ) { - gxv_just_justData_validate( table + horizOffset, limit, valid ); - gxv_odtect_add_range( table + horizOffset, valid->subtable_length, + gxv_just_justData_validate( table + horizOffset, limit, gxvalid ); + gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length, "horizJustData", odtect ); } if ( 0 < vertOffset ) { - gxv_just_justData_validate( table + vertOffset, limit, valid ); - gxv_odtect_add_range( table + vertOffset, valid->subtable_length, + gxv_just_justData_validate( table + vertOffset, limit, gxvalid ); + gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length, "vertJustData", odtect ); } - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/src/gxvalid/gxvkern.c b/drivers/freetype/src/gxvalid/gxvkern.c index 557c5f1fe4..ee1ab36f70 100644 --- a/drivers/freetype/src/gxvalid/gxvkern.c +++ b/drivers/freetype/src/gxvalid/gxvkern.c @@ -4,8 +4,8 @@ /* */ /* TrueTypeGX/AAT kern table validation (body). */ /* */ -/* Copyright 2004-2007, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,20 +79,20 @@ #define GXV_KERN_DATA( field ) GXV_TABLE_DATA( kern, field ) -#define KERN_IS_CLASSIC( valid ) \ +#define KERN_IS_CLASSIC( gxvalid ) \ ( KERN_VERSION_CLASSIC == GXV_KERN_DATA( version ) ) -#define KERN_IS_NEW( valid ) \ +#define KERN_IS_NEW( gxvalid ) \ ( KERN_VERSION_NEW == GXV_KERN_DATA( version ) ) -#define KERN_DIALECT( valid ) \ +#define KERN_DIALECT( gxvalid ) \ GXV_KERN_DATA( dialect_request ) -#define KERN_ALLOWS_MS( valid ) \ - ( KERN_DIALECT( valid ) & KERN_DIALECT_MS ) -#define KERN_ALLOWS_APPLE( valid ) \ - ( KERN_DIALECT( valid ) & KERN_DIALECT_APPLE ) +#define KERN_ALLOWS_MS( gxvalid ) \ + ( KERN_DIALECT( gxvalid ) & KERN_DIALECT_MS ) +#define KERN_ALLOWS_APPLE( gxvalid ) \ + ( KERN_DIALECT( gxvalid ) & KERN_DIALECT_APPLE ) -#define GXV_KERN_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 4 ) -#define GXV_KERN_SUBTABLE_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 6 ) +#define GXV_KERN_HEADER_SIZE ( KERN_IS_NEW( gxvalid ) ? 8 : 4 ) +#define GXV_KERN_SUBTABLE_HEADER_SIZE ( KERN_IS_NEW( gxvalid ) ? 8 : 6 ) /*************************************************************************/ @@ -110,7 +110,7 @@ gxv_kern_subtable_fmt0_pairs_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nPairs, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort i; @@ -134,11 +134,11 @@ /* left */ gid_left = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( gid_left, valid ); + gxv_glyphid_validate( gid_left, gxvalid ); /* right */ gid_right = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( gid_right, valid ); + gxv_glyphid_validate( gid_right, gxvalid ); /* Pairs of left and right GIDs must be unique and sorted. */ GXV_TRACE(( "left gid = %u, right gid = %u\n", gid_left, gid_right )); @@ -171,7 +171,7 @@ static void gxv_kern_subtable_fmt0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; @@ -186,10 +186,10 @@ /* nPairs, searchRange, entrySelector, rangeShift */ GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid ); + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, gxvalid ); p += 2 + 2 + 2 + 2; - gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, valid ); + gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, gxvalid ); GXV_EXIT; } @@ -209,11 +209,11 @@ static void gxv_kern_subtable_fmt1_valueTable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_kern_fmt1_StateOptRecData optdata = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + (GXV_kern_fmt1_StateOptRecData)gxvalid->statetable.optdata; GXV_LIMIT_CHECK( 2 ); @@ -232,14 +232,14 @@ FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort o[4]; FT_UShort *l[4]; FT_UShort buff[5]; GXV_kern_fmt1_StateOptRecData optdata = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + (GXV_kern_fmt1_StateOptRecData)gxvalid->statetable.optdata; o[0] = classTable; @@ -251,7 +251,7 @@ l[2] = entryTable_length_p; l[3] = &(optdata->valueTable_length); - gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid ); + gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, gxvalid ); } @@ -265,7 +265,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort push; @@ -289,7 +289,7 @@ { GXV_kern_fmt1_StateOptRecData vt_rec = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + (GXV_kern_fmt1_StateOptRecData)gxvalid->statetable.optdata; FT_Bytes p; @@ -311,7 +311,7 @@ static void gxv_kern_subtable_fmt1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_kern_fmt1_StateOptRec vt_rec; @@ -319,18 +319,18 @@ GXV_NAME_ENTER( "kern subtable format 1" ); - valid->statetable.optdata = + gxvalid->statetable.optdata = &vt_rec; - valid->statetable.optdata_load_func = + gxvalid->statetable.optdata_load_func = gxv_kern_subtable_fmt1_valueTable_load; - valid->statetable.subtable_setup_func = + gxvalid->statetable.subtable_setup_func = gxv_kern_subtable_fmt1_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = + gxvalid->statetable.entry_validate_func = gxv_kern_subtable_fmt1_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); GXV_EXIT; } @@ -373,7 +373,7 @@ gxv_kern_subtable_fmt2_clstbl_validate( FT_Bytes table, FT_Bytes limit, GXV_kern_ClassSpec spec, - GXV_Validator valid ) + GXV_Validator gxvalid ) { const FT_String* tag = GXV_KERN_FMT2_DATA( class_tag[spec] ); GXV_odtect_Range odtect = GXV_KERN_FMT2_DATA( odtect ); @@ -391,13 +391,13 @@ GXV_TRACE(( " %s firstGlyph=%d, nGlyphs=%d\n", tag, firstGlyph, nGlyphs )); - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs - 1 ), valid ); + gxv_glyphid_validate( firstGlyph, gxvalid ); + gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs - 1 ), gxvalid ); gxv_array_getlimits_ushort( p, p + ( 2 * nGlyphs ), &( GXV_KERN_FMT2_DATA( offset_min[spec] ) ), &( GXV_KERN_FMT2_DATA( offset_max[spec] ) ), - valid ); + gxvalid ); gxv_odtect_add_range( table, 2 * nGlyphs, tag, odtect ); @@ -408,7 +408,7 @@ static void gxv_kern_subtable_fmt2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_ODTECT( 3, odtect ); GXV_kern_subtable_fmt2_DataRec fmt2_rec = @@ -439,10 +439,10 @@ GXV_LIMIT_CHECK( GXV_KERN_FMT2_DATA( array ) ); gxv_kern_subtable_fmt2_clstbl_validate( table + leftOffsetTable, limit, - GXV_KERN_CLS_L, valid ); + GXV_KERN_CLS_L, gxvalid ); gxv_kern_subtable_fmt2_clstbl_validate( table + rightOffsetTable, limit, - GXV_KERN_CLS_R, valid ); + GXV_KERN_CLS_R, gxvalid ); if ( GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_L] ) + GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_R] ) @@ -455,7 +455,7 @@ - GXV_KERN_FMT2_DATA( array ), "array", odtect ); - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); GXV_EXIT; } @@ -466,7 +466,7 @@ static void gxv_kern_subtable_fmt3_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; FT_UShort glyphCount; @@ -485,10 +485,10 @@ rightClassCount = FT_NEXT_BYTE( p ); flags = FT_NEXT_BYTE( p ); - if ( valid->face->num_glyphs != glyphCount ) + if ( gxvalid->face->num_glyphs != glyphCount ) { GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n", - valid->face->num_glyphs, glyphCount )); + gxvalid->face->num_glyphs, glyphCount )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } @@ -509,8 +509,8 @@ GXV_LIMIT_CHECK( glyphCount ); - gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid ); - p += valid->subtable_length; + gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, gxvalid ); + p += gxvalid->subtable_length; if ( leftClassCount < max ) FT_INVALID_DATA; @@ -524,8 +524,8 @@ GXV_LIMIT_CHECK( glyphCount ); - gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid ); - p += valid->subtable_length; + gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, gxvalid ); + p += gxvalid->subtable_length; if ( rightClassCount < max ) FT_INVALID_DATA; @@ -549,7 +549,7 @@ } } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -558,7 +558,7 @@ static FT_Bool gxv_kern_coverage_new_apple_validate( FT_UShort coverage, FT_UShort* format, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* new Apple-dialect */ #ifdef GXV_LOAD_TRACE_VARS @@ -567,7 +567,7 @@ FT_Bool kernVariation; #endif - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); /* reserved bits = 0 */ @@ -595,7 +595,7 @@ static FT_Bool gxv_kern_coverage_classic_apple_validate( FT_UShort coverage, FT_UShort* format, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* classic Apple-dialect */ #ifdef GXV_LOAD_TRACE_VARS @@ -605,7 +605,7 @@ /* check expected flags, but don't check if MS-dialect is impossible */ - if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( valid ) ) + if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( gxvalid ) ) return FALSE; /* reserved bits = 0 */ @@ -636,7 +636,7 @@ static FT_Bool gxv_kern_coverage_classic_microsoft_validate( FT_UShort coverage, FT_UShort* format, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* classic Microsoft-dialect */ #ifdef GXV_LOAD_TRACE_VARS @@ -646,7 +646,7 @@ FT_Bool override; #endif - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); /* reserved bits = 0 */ @@ -686,49 +686,49 @@ static GXV_kern_Dialect gxv_kern_coverage_validate( FT_UShort coverage, FT_UShort* format, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_kern_Dialect result = KERN_DIALECT_UNKNOWN; GXV_NAME_ENTER( "validating coverage" ); - GXV_TRACE(( "interprete coverage 0x%04x by Apple style\n", coverage )); + GXV_TRACE(( "interpret coverage 0x%04x by Apple style\n", coverage )); - if ( KERN_IS_NEW( valid ) ) + if ( KERN_IS_NEW( gxvalid ) ) { if ( gxv_kern_coverage_new_apple_validate( coverage, format, - valid ) ) + gxvalid ) ) { result = KERN_DIALECT_APPLE; goto Exit; } } - if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_APPLE( valid ) ) + if ( KERN_IS_CLASSIC( gxvalid ) && KERN_ALLOWS_APPLE( gxvalid ) ) { if ( gxv_kern_coverage_classic_apple_validate( coverage, format, - valid ) ) + gxvalid ) ) { result = KERN_DIALECT_APPLE; goto Exit; } } - if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_MS( valid ) ) + if ( KERN_IS_CLASSIC( gxvalid ) && KERN_ALLOWS_MS( gxvalid ) ) { if ( gxv_kern_coverage_classic_microsoft_validate( coverage, format, - valid ) ) + gxvalid ) ) { result = KERN_DIALECT_MS; goto Exit; } } - GXV_TRACE(( "cannot interprete coverage, broken kern subtable\n" )); + GXV_TRACE(( "cannot interpret coverage, broken kern subtable\n" )); Exit: GXV_EXIT; @@ -739,7 +739,7 @@ static void gxv_kern_subtable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_TRACE_VARS @@ -761,7 +761,7 @@ u16[1] = FT_NEXT_USHORT( p ); /* Apple: length_lo MS: length */ coverage = FT_NEXT_USHORT( p ); - switch ( gxv_kern_coverage_validate( coverage, &format, valid ) ) + switch ( gxv_kern_coverage_validate( coverage, &format, gxvalid ) ) { case KERN_DIALECT_MS: #ifdef GXV_LOAD_TRACE_VARS @@ -779,13 +779,13 @@ #ifdef GXV_LOAD_TRACE_VARS version = 0; #endif - length = ( u16[0] << 16 ) + u16[1]; + length = ( (FT_ULong)u16[0] << 16 ) + u16[1]; #ifdef GXV_LOAD_TRACE_VARS tupleIndex = 0; #endif GXV_TRACE(( "Subtable length = %d\n", length )); - if ( KERN_IS_NEW( valid ) ) + if ( KERN_IS_NEW( gxvalid ) ) { GXV_LIMIT_CHECK( 2 ); #ifdef GXV_LOAD_TRACE_VARS @@ -806,18 +806,18 @@ /* formats 1, 2, 3 require the position of the start of this subtable */ if ( format == 0 ) - gxv_kern_subtable_fmt0_validate( table, table + length, valid ); + gxv_kern_subtable_fmt0_validate( table, table + length, gxvalid ); else if ( format == 1 ) - gxv_kern_subtable_fmt1_validate( table, table + length, valid ); + gxv_kern_subtable_fmt1_validate( table, table + length, gxvalid ); else if ( format == 2 ) - gxv_kern_subtable_fmt2_validate( table, table + length, valid ); + gxv_kern_subtable_fmt2_validate( table, table + length, gxvalid ); else if ( format == 3 ) - gxv_kern_subtable_fmt3_validate( table, table + length, valid ); + gxv_kern_subtable_fmt3_validate( table, table + length, gxvalid ); else FT_INVALID_DATA; Exit: - valid->subtable_length = length; + gxvalid->subtable_length = length; GXV_EXIT; } @@ -837,8 +837,8 @@ GXV_kern_Dialect dialect_request, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_kern_DataRec kernrec; GXV_kern_Data kern = &kernrec; @@ -850,13 +850,13 @@ FT_UInt i; - valid->root = ftvalid; - valid->table_data = kern; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = kern; + gxvalid->face = face; FT_TRACE3(( "validating `kern' table\n" )); GXV_INIT; - KERN_DIALECT( valid ) = dialect_request; + KERN_DIALECT( gxvalid ) = dialect_request; GXV_LIMIT_CHECK( 2 ); GXV_KERN_DATA( version ) = (GXV_kern_Version)FT_NEXT_USHORT( p ); @@ -865,12 +865,12 @@ if ( 0x0001 < GXV_KERN_DATA( version ) ) FT_INVALID_FORMAT; - else if ( KERN_IS_CLASSIC( valid ) ) + else if ( KERN_IS_CLASSIC( gxvalid ) ) { GXV_LIMIT_CHECK( 2 ); nTables = FT_NEXT_USHORT( p ); } - else if ( KERN_IS_NEW( valid ) ) + else if ( KERN_IS_NEW( gxvalid ) ) { if ( classic_only ) FT_INVALID_FORMAT; @@ -886,8 +886,8 @@ { GXV_TRACE(( "validating subtable %d/%d\n", i, nTables )); /* p should be 32bit-aligned? */ - gxv_kern_subtable_validate( p, 0, valid ); - p += valid->subtable_length; + gxv_kern_subtable_validate( p, 0, gxvalid ); + p += gxvalid->subtable_length; } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/src/gxvalid/gxvlcar.c b/drivers/freetype/src/gxvalid/gxvlcar.c index f14fa5b131..d31b6410bd 100644 --- a/drivers/freetype/src/gxvalid/gxvlcar.c +++ b/drivers/freetype/src/gxvalid/gxvlcar.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT lcar table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,16 +66,16 @@ /*************************************************************************/ static void - gxv_lcar_partial_validate( FT_UShort partial, + gxv_lcar_partial_validate( FT_Short partial, FT_UShort glyph, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_NAME_ENTER( "partial" ); if ( GXV_LCAR_DATA( format ) != 1 ) goto Exit; - gxv_ctlPoint_validate( glyph, partial, valid ); + gxv_ctlPoint_validate( glyph, (FT_UShort)partial, gxvalid ); Exit: GXV_EXIT; @@ -84,10 +85,10 @@ static void gxv_lcar_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = valid->root->base + value_p->u; - FT_Bytes limit = valid->root->limit; + FT_Bytes p = gxvalid->root->base + value_p->u; + FT_Bytes limit = gxvalid->root->limit; FT_UShort count; FT_Short partial; FT_UShort i; @@ -102,7 +103,7 @@ for ( i = 0; i < count; i++ ) { partial = FT_NEXT_SHORT( p ); - gxv_lcar_partial_validate( partial, glyph, valid ); + gxv_lcar_partial_validate( partial, glyph, gxvalid ); } GXV_EXIT; @@ -113,7 +114,7 @@ +------ lcar --------------------+ | | | +===============+ | - | | looup header | | + | | lookup header | | | +===============+ | | | BinSrchHeader | | | +===============+ | @@ -148,7 +149,7 @@ gxv_lcar_LookupFmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -160,8 +161,8 @@ /* XXX: check range? */ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->root->base + offset; - limit = valid->root->limit; + p = gxvalid->root->base + offset; + limit = gxvalid->root->limit; GXV_LIMIT_CHECK ( 2 ); value.u = FT_NEXT_USHORT( p ); @@ -185,8 +186,8 @@ { FT_Bytes p = table; FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_lcar_DataRec lcarrec; GXV_lcar_Data lcar = &lcarrec; @@ -194,15 +195,15 @@ FT_Fixed version; - valid->root = ftvalid; - valid->table_data = lcar; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = lcar; + gxvalid->face = face; FT_TRACE3(( "validating `lcar' table\n" )); GXV_INIT; GXV_LIMIT_CHECK( 4 + 2 ); - version = FT_NEXT_ULONG( p ); + version = FT_NEXT_LONG( p ); GXV_LCAR_DATA( format ) = FT_NEXT_USHORT( p ); if ( version != 0x00010000UL) @@ -211,10 +212,10 @@ if ( GXV_LCAR_DATA( format ) > 1 ) FT_INVALID_FORMAT; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_lcar_LookupValue_validate; - valid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_lcar_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; + gxv_LookupTable_validate( p, limit, gxvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/src/gxvalid/gxvmod.c b/drivers/freetype/src/gxvalid/gxvmod.c index 278d47688a..e589a7fb79 100644 --- a/drivers/freetype/src/gxvalid/gxvmod.c +++ b/drivers/freetype/src/gxvalid/gxvmod.c @@ -4,8 +4,8 @@ /* */ /* FreeType's TrueTypeGX/AAT validation module implementation (body). */ /* */ -/* Copyright 2004-2006, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -235,14 +235,14 @@ static const FT_Service_GXvalidateRec gxvalid_interface = { - gxv_validate + gxv_validate /* validate */ }; static const FT_Service_CKERNvalidateRec ckernvalid_interface = { - classic_kern_validate + classic_kern_validate /* validate */ }; diff --git a/drivers/freetype/src/gxvalid/gxvmod.h b/drivers/freetype/src/gxvalid/gxvmod.h index 22732ba992..8b82e91070 100644 --- a/drivers/freetype/src/gxvalid/gxvmod.h +++ b/drivers/freetype/src/gxvalid/gxvmod.h @@ -5,7 +5,8 @@ /* FreeType's TrueTypeGX/AAT validation module implementation */ /* (specification). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,8 +26,8 @@ /***************************************************************************/ -#ifndef __GXVMOD_H__ -#define __GXVMOD_H__ +#ifndef GXVMOD_H_ +#define GXVMOD_H_ #include <ft2build.h> #include FT_MODULE_H @@ -44,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVMOD_H__ */ +#endif /* GXVMOD_H_ */ /* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort.c b/drivers/freetype/src/gxvalid/gxvmort.c index 5356e67ca7..b83a2b2c0f 100644 --- a/drivers/freetype/src/gxvalid/gxvmort.c +++ b/drivers/freetype/src/gxvalid/gxvmort.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT mort table validation (body). */ /* */ -/* Copyright 2005, 2013 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -40,7 +41,7 @@ static void gxv_mort_feature_validate( GXV_mort_feature f, - GXV_Validator valid ) + GXV_Validator gxvalid ) { if ( f->featureType >= gxv_feat_registry_length ) { @@ -89,7 +90,7 @@ gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, FT_ULong nFeatureFlags, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong i; @@ -106,23 +107,24 @@ f.enableFlags = FT_NEXT_ULONG( p ); f.disableFlags = FT_NEXT_ULONG( p ); - gxv_mort_feature_validate( &f, valid ); + gxv_mort_feature_validate( &f, gxvalid ); } if ( !IS_GXV_MORT_FEATURE_OFF( f ) ) FT_INVALID_DATA; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } FT_LOCAL_DEF( void ) gxv_mort_coverage_validate( FT_UShort coverage, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); +#ifdef FT_DEBUG_LEVEL_TRACE if ( coverage & 0x8000U ) GXV_TRACE(( " this subtable is for vertical text only\n" )); else @@ -141,6 +143,7 @@ if ( coverage & 0x1FF8 ) GXV_TRACE(( " coverage has non-zero bits in reserved area\n" )); +#endif } @@ -148,7 +151,7 @@ gxv_mort_subtables_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nSubtables, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -196,7 +199,7 @@ rest = length - ( 2 + 2 + 4 ); GXV_LIMIT_CHECK( rest ); - gxv_mort_coverage_validate( coverage, valid ); + gxv_mort_coverage_validate( coverage, gxvalid ); if ( type > 5 ) FT_INVALID_FORMAT; @@ -205,13 +208,13 @@ if ( func == NULL ) GXV_TRACE(( "morx type %d is reserved\n", type )); - func( p, p + rest, valid ); + func( p, p + rest, gxvalid ); p += rest; /* TODO: validate subFeatureFlags */ } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -220,7 +223,7 @@ static void gxv_mort_chain_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_UNUSED_VARS @@ -244,10 +247,10 @@ nSubtables = FT_NEXT_USHORT( p ); gxv_mort_featurearray_validate( p, table + chainLength, - nFeatureFlags, valid ); - p += valid->subtable_length; - gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid ); - valid->subtable_length = chainLength; + nFeatureFlags, gxvalid ); + p += gxvalid->subtable_length; + gxv_mort_subtables_validate( p, table + chainLength, nSubtables, gxvalid ); + gxvalid->subtable_length = chainLength; /* TODO: validate defaultFlags */ GXV_EXIT; @@ -259,8 +262,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; FT_Bytes p = table; FT_Bytes limit = 0; FT_ULong version; @@ -268,9 +271,9 @@ FT_ULong i; - valid->root = ftvalid; - valid->face = face; - limit = valid->root->limit; + gxvalid->root = ftvalid; + gxvalid->face = face; + limit = gxvalid->root->limit; FT_TRACE3(( "validating `mort' table\n" )); GXV_INIT; @@ -286,8 +289,8 @@ { GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); - gxv_mort_chain_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_mort_chain_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/src/gxvalid/gxvmort.h b/drivers/freetype/src/gxvalid/gxvmort.h index 1e5a1f5ab6..5fd228212a 100644 --- a/drivers/freetype/src/gxvalid/gxvmort.h +++ b/drivers/freetype/src/gxvalid/gxvmort.h @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT common definition for mort table (specification). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVMORT_H__ -#define __GXVMORT_H__ +#ifndef GXVMORT_H_ +#define GXVMORT_H_ #include "gxvalid.h" #include "gxvcommn.h" @@ -55,39 +56,39 @@ gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, FT_ULong nFeatureFlags, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_coverage_validate( FT_UShort coverage, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); -#endif /* __GXVMORT_H__ */ +#endif /* GXVMORT_H_ */ /* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmort0.c b/drivers/freetype/src/gxvalid/gxvmort0.c index b136ceda27..e11f5ddc49 100644 --- a/drivers/freetype/src/gxvalid/gxvmort0.c +++ b/drivers/freetype/src/gxvalid/gxvmort0.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type0 (Indic Script Rearrangement) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,7 +68,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort markFirst; FT_UShort dontAdvance; @@ -125,7 +126,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -135,14 +136,14 @@ GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); - valid->statetable.optdata = NULL; - valid->statetable.optdata_load_func = NULL; - valid->statetable.subtable_setup_func = NULL; - valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = + gxvalid->statetable.optdata = NULL; + gxvalid->statetable.optdata_load_func = NULL; + gxvalid->statetable.subtable_setup_func = NULL; + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type0_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmort1.c b/drivers/freetype/src/gxvalid/gxvmort1.c index 1c17a5d92a..fd761d0692 100644 --- a/drivers/freetype/src/gxvalid/gxvmort1.c +++ b/drivers/freetype/src/gxvalid/gxvmort1.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type1 (Contextual Substitution) subtable. */ /* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -53,12 +54,12 @@ static void gxv_mort_subtable_type1_substitutionTable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_mort_subtable_type1_StateOptRecData optdata = - (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type1_StateOptRecData)gxvalid->statetable.optdata; GXV_LIMIT_CHECK( 2 ); @@ -74,14 +75,14 @@ FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort o[4]; FT_UShort *l[4]; FT_UShort buff[5]; GXV_mort_subtable_type1_StateOptRecData optdata = - (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type1_StateOptRecData)gxvalid->statetable.optdata; o[0] = classTable; @@ -93,7 +94,7 @@ l[2] = entryTable_length_p; l[3] = &( optdata->substitutionTable_length ); - gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid ); + gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, gxvalid ); } @@ -102,7 +103,7 @@ FT_Short wordOffset, const FT_String* tag, FT_Byte state, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort substTable; FT_UShort substTable_limit; @@ -113,16 +114,16 @@ substTable = ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable; + (gxvalid->statetable.optdata))->substitutionTable; substTable_limit = (FT_UShort)( substTable + ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable_length ); + (gxvalid->statetable.optdata))->substitutionTable_length ); - valid->min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 ); - valid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 ); - valid->max_gid = (FT_UShort)( FT_MAX( valid->max_gid, - valid->face->num_glyphs ) ); + gxvalid->min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 ); + gxvalid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 ); + gxvalid->max_gid = (FT_UShort)( FT_MAX( gxvalid->max_gid, + gxvalid->face->num_glyphs ) ); /* XXX: check range? */ @@ -137,7 +138,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort setMark; @@ -155,7 +156,7 @@ setMark = (FT_UShort)( flags >> 15 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); #endif - reserved = (FT_Short)( flags & 0x3FFF ); + reserved = (FT_UShort)( flags & 0x3FFF ); markOffset = (FT_Short)( glyphOffset_p->ul >> 16 ); currentOffset = (FT_Short)( glyphOffset_p->ul ); @@ -169,29 +170,29 @@ gxv_mort_subtable_type1_offset_to_subst_validate( markOffset, "markOffset", state, - valid ); + gxvalid ); gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset, "currentOffset", state, - valid ); + gxvalid ); } static void gxv_mort_subtable_type1_substTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort num_gids = (FT_UShort)( ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable_length / 2 ); + (gxvalid->statetable.optdata))->substitutionTable_length / 2 ); FT_UShort i; GXV_NAME_ENTER( "validating contents of substitutionTable" ); - for ( i = 0; i < num_gids ; i ++ ) + for ( i = 0; i < num_gids; i++ ) { FT_UShort dst_gid; @@ -202,11 +203,11 @@ if ( dst_gid >= 0xFFFFU ) continue; - if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid ) + if ( dst_gid < gxvalid->min_gid || gxvalid->max_gid < dst_gid ) { GXV_TRACE(( "substTable include a strange gid[%d]=%d >" " out of define range (%d..%d)\n", - i, dst_gid, valid->min_gid, valid->max_gid )); + i, dst_gid, gxvalid->min_gid, gxvalid->max_gid )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } } @@ -223,7 +224,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -234,23 +235,23 @@ GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE ); - valid->statetable.optdata = + gxvalid->statetable.optdata = &st_rec; - valid->statetable.optdata_load_func = + gxvalid->statetable.optdata_load_func = gxv_mort_subtable_type1_substitutionTable_load; - valid->statetable.subtable_setup_func = + gxvalid->statetable.subtable_setup_func = gxv_mort_subtable_type1_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; - valid->statetable.entry_validate_func = + gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type1_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); gxv_mort_subtable_type1_substTable_validate( table + st_rec.substitutionTable, table + st_rec.substitutionTable + st_rec.substitutionTable_length, - valid ); + gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmort2.c b/drivers/freetype/src/gxvalid/gxvmort2.c index 9e08fb792a..08455dec6b 100644 --- a/drivers/freetype/src/gxvalid/gxvmort2.c +++ b/drivers/freetype/src/gxvalid/gxvmort2.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type2 (Ligature Substitution) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -57,11 +58,11 @@ static void gxv_mort_subtable_type2_opttable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table; + FT_Bytes p = table; GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type2_StateOptRecData)gxvalid->statetable.optdata; GXV_LIMIT_CHECK( 2 + 2 + 2 ); @@ -86,14 +87,14 @@ FT_UShort *classTable_length_p, FT_UShort *stateArray_length_p, FT_UShort *entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort o[6]; FT_UShort *l[6]; FT_UShort buff[7]; GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type2_StateOptRecData)gxvalid->statetable.optdata; GXV_NAME_ENTER( "subtable boundaries setup" ); @@ -111,7 +112,7 @@ l[4] = &(optdata->componentTable_length); l[5] = &(optdata->ligatureTable_length); - gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, valid ); + gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, gxvalid ); GXV_TRACE(( "classTable: offset=0x%04x length=0x%04x\n", classTable, *classTable_length_p )); @@ -137,11 +138,11 @@ gxv_mort_subtable_type2_ligActionOffset_validate( FT_Bytes table, FT_UShort ligActionOffset, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* access ligActionTable */ GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type2_StateOptRecData)gxvalid->statetable.optdata; FT_Bytes lat_base = table + optdata->ligActionTable; FT_Bytes p = table + ligActionOffset; @@ -214,7 +215,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort setComponent; @@ -236,16 +237,16 @@ if ( 0 < offset ) gxv_mort_subtable_type2_ligActionOffset_validate( table, offset, - valid ); + gxvalid ); } static void gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes table, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type2_StateOptRecData)gxvalid->statetable.optdata; FT_Bytes p = table + optdata->ligatureTable; FT_Bytes limit = table + optdata->ligatureTable @@ -264,7 +265,7 @@ GXV_LIMIT_CHECK( 2 ); lig_gid = FT_NEXT_USHORT( p ); - if ( valid->face->num_glyphs < lig_gid ) + if ( gxvalid->face->num_glyphs < lig_gid ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } } @@ -275,7 +276,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -286,23 +287,23 @@ GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ); - valid->statetable.optdata = + gxvalid->statetable.optdata = &lig_rec; - valid->statetable.optdata_load_func = + gxvalid->statetable.optdata_load_func = gxv_mort_subtable_type2_opttable_load; - valid->statetable.subtable_setup_func = + gxvalid->statetable.subtable_setup_func = gxv_mort_subtable_type2_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = + gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type2_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); - p += valid->subtable_length; - gxv_mort_subtable_type2_ligatureTable_validate( table, valid ); + p += gxvalid->subtable_length; + gxv_mort_subtable_type2_ligatureTable_validate( table, gxvalid ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmort4.c b/drivers/freetype/src/gxvalid/gxvmort4.c index 83470988c0..6f7bbb8710 100644 --- a/drivers/freetype/src/gxvalid/gxvmort4.c +++ b/drivers/freetype/src/gxvalid/gxvmort4.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type4 (Non-Contextual Glyph Substitution) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,11 +42,11 @@ static void gxv_mort_subtable_type4_lookupval_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); - gxv_glyphid_validate( value_p->u, valid ); + gxv_glyphid_validate( value_p->u, gxvalid ); } /* @@ -80,7 +81,7 @@ FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -91,7 +92,7 @@ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK( 2 ); @@ -104,7 +105,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -112,11 +113,11 @@ GXV_NAME_ENTER( "mort chain subtable type4 " "(Non-Contextual Glyph Substitution)" ); - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_mort_subtable_type4_lookupval_validate; - valid->lookupfmt4_trans = gxv_mort_subtable_type4_lookupfmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_mort_subtable_type4_lookupval_validate; + gxvalid->lookupfmt4_trans = gxv_mort_subtable_type4_lookupfmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); + gxv_LookupTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmort5.c b/drivers/freetype/src/gxvalid/gxvmort5.c index 32cfb03639..54ddbe2b15 100644 --- a/drivers/freetype/src/gxvalid/gxvmort5.c +++ b/drivers/freetype/src/gxvalid/gxvmort5.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type5 (Contextual Glyph Insertion) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -70,10 +71,10 @@ FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_mort_subtable_type5_StateOptRecData optdata = - (GXV_mort_subtable_type5_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type5_StateOptRecData)gxvalid->statetable.optdata; gxv_StateTable_subtable_setup( table_size, @@ -83,7 +84,7 @@ classTable_length_p, stateArray_length_p, entryTable_length_p, - valid ); + gxvalid ); optdata->classTable = classTable; optdata->stateArray = stateArray; @@ -100,7 +101,7 @@ FT_UShort count, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* * We don't know the range of insertion-glyph-list. @@ -109,7 +110,7 @@ FT_Bytes p = table + offset; GXV_mort_subtable_type5_StateOptRecData optdata = - (GXV_mort_subtable_type5_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type5_StateOptRecData)gxvalid->statetable.optdata; if ( optdata->classTable < offset && offset < optdata->classTable + *(optdata->classTable_length_p) ) @@ -145,7 +146,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_Bool setMark; @@ -184,7 +185,7 @@ currentInsertCount, table, limit, - valid ); + gxvalid ); } if ( 0 != markedInsertList && 0 != markedInsertCount ) @@ -193,7 +194,7 @@ markedInsertCount, table, limit, - valid ); + gxvalid ); } } @@ -201,7 +202,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -213,18 +214,18 @@ GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE5_HEADER_SIZE ); - valid->statetable.optdata = + gxvalid->statetable.optdata = et; - valid->statetable.optdata_load_func = + gxvalid->statetable.optdata_load_func = NULL; - valid->statetable.subtable_setup_func = + gxvalid->statetable.subtable_setup_func = gxv_mort_subtable_type5_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; - valid->statetable.entry_validate_func = + gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type5_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmorx.c b/drivers/freetype/src/gxvalid/gxvmorx.c index 5ae04d3212..a3abe435a6 100644 --- a/drivers/freetype/src/gxvalid/gxvmorx.c +++ b/drivers/freetype/src/gxvalid/gxvmorx.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT morx table validation (body). */ /* */ -/* Copyright 2005, 2008, 2013 by */ +/* Copyright 2005-2016 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -42,7 +42,7 @@ gxv_morx_subtables_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nSubtables, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -93,7 +93,7 @@ /* morx coverage consists of mort_coverage & 16bit padding */ gxv_mort_coverage_validate( (FT_UShort)( ( coverage >> 16 ) | coverage ), - valid ); + gxvalid ); if ( type > 5 ) FT_INVALID_FORMAT; @@ -101,13 +101,13 @@ if ( func == NULL ) GXV_TRACE(( "morx type %d is reserved\n", type )); - func( p, p + rest, valid ); + func( p, p + rest, gxvalid ); /* TODO: subFeatureFlags should be unique in a table? */ p += rest; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -116,7 +116,7 @@ static void gxv_morx_chain_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_UNUSED_VARS @@ -140,16 +140,16 @@ nSubtables = FT_NEXT_ULONG( p ); /* feature-array of morx is same with that of mort */ - gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid ); - p += valid->subtable_length; + gxv_mort_featurearray_validate( p, limit, nFeatureFlags, gxvalid ); + p += gxvalid->subtable_length; if ( nSubtables >= 0x10000L ) FT_INVALID_DATA; gxv_morx_subtables_validate( p, table + chainLength, - (FT_UShort)nSubtables, valid ); + (FT_UShort)nSubtables, gxvalid ); - valid->subtable_length = chainLength; + gxvalid->subtable_length = chainLength; /* TODO: defaultFlags should be compared with the flags in tables */ @@ -162,8 +162,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; FT_Bytes p = table; FT_Bytes limit = 0; FT_ULong version; @@ -171,8 +171,8 @@ FT_ULong i; - valid->root = ftvalid; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->face = face; FT_TRACE3(( "validating `morx' table\n" )); GXV_INIT; @@ -188,8 +188,8 @@ { GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); - gxv_morx_chain_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_morx_chain_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/src/gxvalid/gxvmorx.h b/drivers/freetype/src/gxvalid/gxvmorx.h index 28c1a44f6f..9ba25c14a4 100644 --- a/drivers/freetype/src/gxvalid/gxvmorx.h +++ b/drivers/freetype/src/gxvalid/gxvmorx.h @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT common definition for morx table (specification). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVMORX_H__ -#define __GXVMORX_H__ +#ifndef GXVMORX_H_ +#define GXVMORX_H_ #include "gxvalid.h" @@ -38,30 +39,30 @@ FT_LOCAL( void ) gxv_morx_subtable_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_morx_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_morx_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_morx_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_morx_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); -#endif /* __GXVMORX_H__ */ +#endif /* GXVMORX_H_ */ /* END */ diff --git a/drivers/freetype/src/gxvalid/gxvmorx0.c b/drivers/freetype/src/gxvalid/gxvmorx0.c index 6a736c1775..4abb7368f2 100644 --- a/drivers/freetype/src/gxvalid/gxvmorx0.c +++ b/drivers/freetype/src/gxvalid/gxvmorx0.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type0 (Indic Script Rearrangement) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +46,7 @@ GXV_XStateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort markFirst; @@ -85,7 +86,7 @@ FT_LOCAL_DEF( void ) gxv_morx_subtable_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -95,14 +96,14 @@ GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); - valid->xstatetable.optdata = NULL; - valid->xstatetable.optdata_load_func = NULL; - valid->xstatetable.subtable_setup_func = NULL; - valid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->xstatetable.entry_validate_func = + gxvalid->xstatetable.optdata = NULL; + gxvalid->xstatetable.optdata_load_func = NULL; + gxvalid->xstatetable.subtable_setup_func = NULL; + gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type0_entry_validate; - gxv_XStateTable_validate( p, limit, valid ); + gxv_XStateTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmorx1.c b/drivers/freetype/src/gxvalid/gxvmorx1.c index ce0009a16f..e581848c2b 100644 --- a/drivers/freetype/src/gxvalid/gxvmorx1.c +++ b/drivers/freetype/src/gxvalid/gxvmorx1.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type1 (Contextual Substitution) subtable. */ /* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -55,12 +56,12 @@ static void gxv_morx_subtable_type1_substitutionTable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type1_StateOptRecData)gxvalid->xstatetable.optdata; GXV_LIMIT_CHECK( 2 ); @@ -76,14 +77,14 @@ FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_ULong o[4]; FT_ULong *l[4]; FT_ULong buff[5]; GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type1_StateOptRecData)gxvalid->xstatetable.optdata; o[0] = classTable; @@ -95,7 +96,7 @@ l[2] = entryTable_length_p; l[3] = &(optdata->substitutionTable_length); - gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid ); + gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, gxvalid ); } @@ -106,7 +107,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_TRACE_VARS FT_UShort setMark; @@ -117,7 +118,7 @@ FT_Short currentIndex; GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type1_StateOptRecData)gxvalid->xstatetable.optdata; FT_UNUSED( state ); FT_UNUSED( table ); @@ -148,24 +149,24 @@ if ( optdata->substitutionTable_num_lookupTables < markIndex + 1 ) optdata->substitutionTable_num_lookupTables = - (FT_Short)( markIndex + 1 ); + (FT_UShort)( markIndex + 1 ); if ( optdata->substitutionTable_num_lookupTables < currentIndex + 1 ) optdata->substitutionTable_num_lookupTables = - (FT_Short)( currentIndex + 1 ); + (FT_UShort)( currentIndex + 1 ); } static void gxv_morx_subtable_type1_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); /* for the non-debugging case */ GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u )); - if ( value_p->u > valid->face->num_glyphs ) + if ( value_p->u > gxvalid->face->num_glyphs ) FT_INVALID_GLYPH_ID; } @@ -175,7 +176,7 @@ FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -186,7 +187,7 @@ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK ( 2 ); @@ -202,19 +203,19 @@ static void gxv_morx_subtable_type1_substitutionTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort i; GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type1_StateOptRecData)gxvalid->xstatetable.optdata; /* TODO: calculate offset/length for each lookupTables */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_morx_subtable_type1_LookupValue_validate; - valid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_morx_subtable_type1_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit; for ( i = 0; i < optdata->substitutionTable_num_lookupTables; i++ ) { @@ -224,7 +225,7 @@ GXV_LIMIT_CHECK( 4 ); offset = FT_NEXT_ULONG( p ); - gxv_LookupTable_validate( table + offset, limit, valid ); + gxv_LookupTable_validate( table + offset, limit, gxvalid ); } /* TODO: overlapping of lookupTables in substitutionTable */ @@ -239,7 +240,7 @@ FT_LOCAL_DEF( void ) gxv_morx_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -252,23 +253,23 @@ st_rec.substitutionTable_num_lookupTables = 0; - valid->xstatetable.optdata = + gxvalid->xstatetable.optdata = &st_rec; - valid->xstatetable.optdata_load_func = + gxvalid->xstatetable.optdata_load_func = gxv_morx_subtable_type1_substitutionTable_load; - valid->xstatetable.subtable_setup_func = + gxvalid->xstatetable.subtable_setup_func = gxv_morx_subtable_type1_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = + gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; - valid->xstatetable.entry_validate_func = + gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type1_entry_validate; - gxv_XStateTable_validate( p, limit, valid ); + gxv_XStateTable_validate( p, limit, gxvalid ); gxv_morx_subtable_type1_substitutionTable_validate( table + st_rec.substitutionTable, table + st_rec.substitutionTable + st_rec.substitutionTable_length, - valid ); + gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmorx2.c b/drivers/freetype/src/gxvalid/gxvmorx2.c index 9d2b0bc4af..9495cca489 100644 --- a/drivers/freetype/src/gxvalid/gxvmorx2.c +++ b/drivers/freetype/src/gxvalid/gxvmorx2.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type2 (Ligature Substitution) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,12 +59,12 @@ static void gxv_morx_subtable_type2_opttable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; GXV_LIMIT_CHECK( 4 + 4 + 4 ); @@ -88,14 +89,14 @@ FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_ULong o[6]; FT_ULong* l[6]; FT_ULong buff[7]; GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; GXV_NAME_ENTER( "subtable boundaries setup" ); @@ -113,7 +114,7 @@ l[4] = &(optdata->componentTable_length); l[5] = &(optdata->ligatureTable_length); - gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, valid ); + gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, gxvalid ); GXV_TRACE(( "classTable: offset=0x%08x length=0x%08x\n", classTable, *classTable_length_p )); @@ -142,11 +143,11 @@ gxv_morx_subtable_type2_ligActionIndex_validate( FT_Bytes table, FT_UShort ligActionIndex, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* access ligActionTable */ GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; FT_Bytes lat_base = table + optdata->ligActionTable; FT_Bytes p = lat_base + @@ -188,7 +189,8 @@ /* it is different from the location offset in mort */ if ( ( offset & 0x3FFF0000UL ) == 0x3FFF0000UL ) { /* negative offset */ - gid_limit = valid->face->num_glyphs - ( offset & 0x0000FFFFUL ); + gid_limit = gxvalid->face->num_glyphs - + (FT_Long)( offset & 0x0000FFFFUL ); if ( gid_limit > 0 ) return; @@ -198,9 +200,9 @@ offset & 0xFFFFU )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); } - else if ( ( offset & 0x3FFF0000UL ) == 0x0000000UL ) + else if ( ( offset & 0x3FFF0000UL ) == 0x00000000UL ) { /* positive offset */ - if ( (FT_Long)offset < valid->face->num_glyphs ) + if ( (FT_Long)offset < gxvalid->face->num_glyphs ) return; GXV_TRACE(( "ligature action table includes" @@ -225,7 +227,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort setComponent; @@ -253,16 +255,16 @@ if ( 0 < ligActionIndex ) gxv_morx_subtable_type2_ligActionIndex_validate( - table, ligActionIndex, valid ); + table, ligActionIndex, gxvalid ); } static void gxv_morx_subtable_type2_ligatureTable_validate( FT_Bytes table, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; FT_Bytes p = table + optdata->ligatureTable; FT_Bytes limit = table + optdata->ligatureTable @@ -281,7 +283,7 @@ GXV_LIMIT_CHECK( 2 ); lig_gid = FT_NEXT_USHORT( p ); - if ( lig_gid < valid->face->num_glyphs ) + if ( lig_gid < gxvalid->face->num_glyphs ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } } @@ -293,7 +295,7 @@ FT_LOCAL_DEF( void ) gxv_morx_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -304,21 +306,23 @@ GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE ); - valid->xstatetable.optdata = + gxvalid->xstatetable.optdata = &lig_rec; - valid->xstatetable.optdata_load_func = + gxvalid->xstatetable.optdata_load_func = gxv_morx_subtable_type2_opttable_load; - valid->xstatetable.subtable_setup_func = + gxvalid->xstatetable.subtable_setup_func = gxv_morx_subtable_type2_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = + gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_USHORT; - valid->xstatetable.entry_validate_func = + gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type2_entry_validate; - gxv_XStateTable_validate( p, limit, valid ); + gxv_XStateTable_validate( p, limit, gxvalid ); - p += valid->subtable_length; - gxv_morx_subtable_type2_ligatureTable_validate( table, valid ); +#if 0 + p += gxvalid->subtable_length; +#endif + gxv_morx_subtable_type2_ligatureTable_validate( table, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmorx4.c b/drivers/freetype/src/gxvalid/gxvmorx4.c index c0d2f78e39..3b7731bbce 100644 --- a/drivers/freetype/src/gxvalid/gxvmorx4.c +++ b/drivers/freetype/src/gxvalid/gxvmorx4.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for "morx" type4 (Non-Contextual Glyph Substitution) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,12 +42,12 @@ FT_LOCAL_DEF( void ) gxv_morx_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_NAME_ENTER( "morx chain subtable type4 " "(Non-Contextual Glyph Substitution)" ); - gxv_mort_subtable_type4_validate( table, limit, valid ); + gxv_mort_subtable_type4_validate( table, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvmorx5.c b/drivers/freetype/src/gxvalid/gxvmorx5.c index d8cf700797..0e96166c02 100644 --- a/drivers/freetype/src/gxvalid/gxvmorx5.c +++ b/drivers/freetype/src/gxvalid/gxvmorx5.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type5 (Contextual Glyph Insertion) subtable. */ /* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -64,12 +65,12 @@ static void gxv_morx_subtable_type5_insertionGlyphList_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_morx_subtable_type5_StateOptRecData optdata = - (GXV_morx_subtable_type5_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type5_StateOptRecData)gxvalid->xstatetable.optdata; GXV_LIMIT_CHECK( 4 ); @@ -85,14 +86,14 @@ FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_ULong o[4]; FT_ULong* l[4]; FT_ULong buff[5]; GXV_morx_subtable_type5_StateOptRecData optdata = - (GXV_morx_subtable_type5_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type5_StateOptRecData)gxvalid->xstatetable.optdata; o[0] = classTable; @@ -104,7 +105,7 @@ l[2] = entryTable_length_p; l[3] = &(optdata->insertionGlyphList_length); - gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid ); + gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, gxvalid ); } @@ -113,9 +114,9 @@ FT_UShort count, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table + table_index * 2; + FT_Bytes p = table + table_index * 2; #ifndef GXV_LOAD_TRACE_VARS @@ -143,7 +144,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_Bool setMark; @@ -180,20 +181,20 @@ gxv_morx_subtable_type5_InsertList_validate( currentInsertList, currentInsertCount, table, limit, - valid ); + gxvalid ); if ( markedInsertList && 0 != markedInsertCount ) gxv_morx_subtable_type5_InsertList_validate( markedInsertList, markedInsertCount, table, limit, - valid ); + gxvalid ); } FT_LOCAL_DEF( void ) gxv_morx_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -205,18 +206,18 @@ GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE5_HEADER_SIZE ); - valid->xstatetable.optdata = + gxvalid->xstatetable.optdata = et; - valid->xstatetable.optdata_load_func = + gxvalid->xstatetable.optdata_load_func = gxv_morx_subtable_type5_insertionGlyphList_load; - valid->xstatetable.subtable_setup_func = + gxvalid->xstatetable.subtable_setup_func = gxv_morx_subtable_type5_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = + gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; - valid->xstatetable.entry_validate_func = + gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type5_entry_validate; - gxv_XStateTable_validate( p, limit, valid ); + gxv_XStateTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/src/gxvalid/gxvopbd.c b/drivers/freetype/src/gxvalid/gxvopbd.c index e125060946..e3ba082e16 100644 --- a/drivers/freetype/src/gxvalid/gxvopbd.c +++ b/drivers/freetype/src/gxvalid/gxvopbd.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT opbd table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,11 +69,11 @@ static void gxv_opbd_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* offset in LookupTable is measured from the head of opbd table */ - FT_Bytes p = valid->root->base + value_p->u; - FT_Bytes limit = valid->root->limit; + FT_Bytes p = gxvalid->root->base + value_p->u; + FT_Bytes limit = gxvalid->root->limit; FT_Short delta_value; int i; @@ -90,7 +91,7 @@ if ( delta_value == -1 ) continue; - gxv_ctlPoint_validate( glyph, delta_value, valid ); + gxv_ctlPoint_validate( glyph, (FT_UShort)delta_value, gxvalid ); } else /* format 0, value is distance */ continue; @@ -134,12 +135,12 @@ gxv_opbd_LookupFmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_LookupValueDesc value; FT_UNUSED( lookuptbl_limit ); - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); /* XXX: check range? */ value.u = (FT_UShort)( base_value_p->u + @@ -162,8 +163,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_opbd_DataRec opbdrec; GXV_opbd_Data opbd = &opbdrec; FT_Bytes p = table; @@ -172,9 +173,9 @@ FT_ULong version; - valid->root = ftvalid; - valid->table_data = opbd; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = opbd; + gxvalid->face = face; FT_TRACE3(( "validating `opbd' table\n" )); GXV_INIT; @@ -196,12 +197,12 @@ if ( 0x0001 < GXV_OPBD_DATA( format ) ) FT_INVALID_FORMAT; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_opbd_LookupValue_validate; - valid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_opbd_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_LookupTable_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; if ( p > table + GXV_OPBD_DATA( valueOffset_min ) ) { diff --git a/drivers/freetype/src/gxvalid/gxvprop.c b/drivers/freetype/src/gxvalid/gxvprop.c index 0be21336f8..61b3aeee30 100644 --- a/drivers/freetype/src/gxvalid/gxvprop.c +++ b/drivers/freetype/src/gxvalid/gxvprop.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT prop table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -75,7 +76,7 @@ static void gxv_prop_zero_advance_validate( FT_UShort gid, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Face face; FT_Error error; @@ -84,7 +85,7 @@ GXV_NAME_ENTER( "zero advance" ); - face = valid->face; + face = gxvalid->face; error = FT_Load_Glyph( face, gid, @@ -109,10 +110,10 @@ static void gxv_prop_property_validate( FT_UShort property, FT_UShort glyph, - GXV_Validator valid ) + GXV_Validator gxvalid ) { if ( glyph != 0 && ( property & GXV_PROP_FLOATER ) ) - gxv_prop_zero_advance_validate( glyph, valid ); + gxv_prop_zero_advance_validate( glyph, gxvalid ); if ( property & GXV_PROP_USE_COMPLEMENTARY_BRACKET ) { @@ -145,7 +146,7 @@ else { /* The gid for complement must be the face. */ - gxv_glyphid_validate( (FT_UShort)( glyph + complement ), valid ); + gxv_glyphid_validate( (FT_UShort)( glyph + complement ), gxvalid ); } } else @@ -187,9 +188,9 @@ static void gxv_prop_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - gxv_prop_property_validate( value_p->u, glyph, valid ); + gxv_prop_property_validate( value_p->u, glyph, gxvalid ); } @@ -224,7 +225,7 @@ gxv_prop_LookupFmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -234,7 +235,7 @@ /* XXX: check range? */ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK ( 2 ); @@ -259,8 +260,8 @@ { FT_Bytes p = table; FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_prop_DataRec proprec; GXV_prop_Data prop = &proprec; @@ -270,15 +271,15 @@ FT_UShort defaultProp; - valid->root = ftvalid; - valid->table_data = prop; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = prop; + gxvalid->face = face; FT_TRACE3(( "validating `prop' table\n" )); GXV_INIT; GXV_LIMIT_CHECK( 4 + 2 + 2 ); - version = FT_NEXT_ULONG( p ); + version = FT_NEXT_LONG( p ); format = FT_NEXT_USHORT( p ); defaultProp = FT_NEXT_USHORT( p ); @@ -303,7 +304,7 @@ FT_INVALID_FORMAT; } - gxv_prop_property_validate( defaultProp, 0, valid ); + gxv_prop_property_validate( defaultProp, 0, gxvalid ); if ( format == 0 ) { @@ -315,11 +316,11 @@ /* format == 1 */ GXV_PROP_DATA( version ) = version; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_prop_LookupValue_validate; - valid->lookupfmt4_trans = gxv_prop_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_prop_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_prop_LookupFmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); + gxv_LookupTable_validate( p, limit, gxvalid ); Exit: FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/src/gxvalid/gxvtrak.c b/drivers/freetype/src/gxvalid/gxvtrak.c index 11fbd7ccfb..0f07c04e2a 100644 --- a/drivers/freetype/src/gxvalid/gxvtrak.c +++ b/drivers/freetype/src/gxvalid/gxvtrak.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT trak table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -48,7 +49,7 @@ /* * referred track table format specification: - * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6trak.html + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html * last update was 1996. * ---------------------------------------------- * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN @@ -93,9 +94,9 @@ gxv_trak_trackTable_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nTracks, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table; + FT_Bytes p = table; FT_Fixed track, t; FT_UShort nameIndex; @@ -110,7 +111,7 @@ GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) ); - for ( i = 0; i < nTracks; i ++ ) + for ( i = 0; i < nTracks; i++ ) { p = table + i * ( 4 + 2 + 2 ); track = FT_NEXT_LONG( p ); @@ -122,9 +123,9 @@ if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) ) GXV_TRAK_DATA( trackValueOffset_max ) = offset; - gxv_sfntName_validate( nameIndex, 256, 32767, valid ); + gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid ); - for ( j = i; j < nTracks; j ++ ) + for ( j = i; j < nTracks; j++ ) { p = table + j * ( 4 + 2 + 2 ); t = FT_NEXT_LONG( p ); @@ -134,7 +135,7 @@ } } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -142,7 +143,7 @@ static void gxv_trak_trackData_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort nTracks; @@ -161,34 +162,35 @@ nSizes = FT_NEXT_USHORT( p ); sizeTableOffset = FT_NEXT_ULONG( p ); - gxv_odtect_add_range( table, p - table, "trackData header", odtect ); + gxv_odtect_add_range( table, (FT_ULong)( p - table ), + "trackData header", odtect ); /* validate trackTable */ - gxv_trak_trackTable_validate( p, limit, nTracks, valid ); - gxv_odtect_add_range( p, valid->subtable_length, + gxv_trak_trackTable_validate( p, limit, nTracks, gxvalid ); + gxv_odtect_add_range( p, gxvalid->subtable_length, "trackTable", odtect ); /* sizeTable is array of FT_Fixed, don't check contents */ - p = valid->root->base + sizeTableOffset; + p = gxvalid->root->base + sizeTableOffset; GXV_LIMIT_CHECK( nSizes * 4 ); gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect ); /* validate trackValueOffet */ - p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min ); + p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min ); if ( limit - p < nTracks * nSizes * 2 ) GXV_TRACE(( "too short trackValue array\n" )); - p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max ); + p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_max ); GXV_LIMIT_CHECK( nSizes * 2 ); - gxv_odtect_add_range( valid->root->base + gxv_odtect_add_range( gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min ), GXV_TRAK_DATA( trackValueOffset_max ) - GXV_TRAK_DATA( trackValueOffset_min ) + nSizes * 2, "trackValue array", odtect ); - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); GXV_EXIT; } @@ -210,8 +212,8 @@ FT_Bytes p = table; FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_trak_DataRec trakrec; GXV_trak_Data trak = &trakrec; @@ -225,11 +227,11 @@ GXV_ODTECT( 3, odtect ); GXV_ODTECT_INIT( odtect ); - valid->root = ftvalid; - valid->table_data = trak; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = trak; + gxvalid->face = face; - limit = valid->root->limit; + limit = gxvalid->root->limit; FT_TRACE3(( "validating `trak' table\n" )); GXV_INIT; @@ -265,19 +267,19 @@ /* validate trackData */ if ( 0 < horizOffset ) { - gxv_trak_trackData_validate( table + horizOffset, limit, valid ); - gxv_odtect_add_range( table + horizOffset, valid->subtable_length, + gxv_trak_trackData_validate( table + horizOffset, limit, gxvalid ); + gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length, "horizJustData", odtect ); } if ( 0 < vertOffset ) { - gxv_trak_trackData_validate( table + vertOffset, limit, valid ); - gxv_odtect_add_range( table + vertOffset, valid->subtable_length, + gxv_trak_trackData_validate( table + vertOffset, limit, gxvalid ); + gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length, "vertJustData", odtect ); } - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/src/gxvalid/module.mk b/drivers/freetype/src/gxvalid/module.mk index 9fd098e2c5..b431384a5c 100644 --- a/drivers/freetype/src/gxvalid/module.mk +++ b/drivers/freetype/src/gxvalid/module.mk @@ -2,9 +2,9 @@ # FreeType 2 gxvalid module definition # -# Copyright 2004, 2005, 2006 -# by suzuki toshiya, Masatake YAMATO, Red Hat K.K., -# David Turner, Robert Wilhelm, and Werner Lemberg. +# Copyright 2004-2016 by +# suzuki toshiya, Masatake YAMATO, Red Hat K.K., +# 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, diff --git a/drivers/freetype/src/gxvalid/rules.mk b/drivers/freetype/src/gxvalid/rules.mk index 57bc0823db..424f2a6377 100644 --- a/drivers/freetype/src/gxvalid/rules.mk +++ b/drivers/freetype/src/gxvalid/rules.mk @@ -3,7 +3,8 @@ # -# Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., +# Copyright 2004-2016 by +# suzuki toshiya, Masatake YAMATO, Red Hat K.K., # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +21,10 @@ GXV_DIR := $(SRC_DIR)/gxvalid # compilation flags for the driver # -GXV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(GXV_DIR)) +GXV_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(GXV_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # GXV driver sources (i.e., C files) diff --git a/drivers/freetype/src/otvalid/Jamfile b/drivers/freetype/src/otvalid/Jamfile index b457143de4..eded89ab9f 100644 --- a/drivers/freetype/src/otvalid/Jamfile +++ b/drivers/freetype/src/otvalid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/otvalid Jamfile # -# Copyright 2004 by +# Copyright 2004-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,15 @@ SubDir FT2_TOP $(FT2_SRC_DIR) otvalid ; if $(FT2_MULTI) { - _sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod otvmath ; + _sources = otvbase + otvcommn + otvgdef + otvgpos + otvgsub + otvjstf + otvmath + otvmod + ; } else { diff --git a/drivers/freetype/src/otvalid/module.mk b/drivers/freetype/src/otvalid/module.mk index 9cadde55e4..b929cdbab0 100644 --- a/drivers/freetype/src/otvalid/module.mk +++ b/drivers/freetype/src/otvalid/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2004, 2006 by +# Copyright 2004-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/otvalid/otvalid.c b/drivers/freetype/src/otvalid/otvalid.c index d5c2b75abb..932a974a31 100644 --- a/drivers/freetype/src/otvalid/otvalid.c +++ b/drivers/freetype/src/otvalid/otvalid.c @@ -4,7 +4,7 @@ /* */ /* FreeType validator for OpenType tables (body only). */ /* */ -/* Copyright 2004, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/otvalid/otvalid.h b/drivers/freetype/src/otvalid/otvalid.h index eb99b9cc48..93438a0639 100644 --- a/drivers/freetype/src/otvalid/otvalid.h +++ b/drivers/freetype/src/otvalid/otvalid.h @@ -4,7 +4,7 @@ /* */ /* OpenType table validation (specification only). */ /* */ -/* Copyright 2004, 2008 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVALID_H__ -#define __OTVALID_H__ +#ifndef OTVALID_H_ +#define OTVALID_H_ #include <ft2build.h> @@ -72,7 +72,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVALID_H__ */ +#endif /* OTVALID_H_ */ /* END */ diff --git a/drivers/freetype/src/otvalid/otvbase.c b/drivers/freetype/src/otvalid/otvbase.c index d742d2dc95..e86e8bb2f0 100644 --- a/drivers/freetype/src/otvalid/otvbase.c +++ b/drivers/freetype/src/otvalid/otvbase.c @@ -4,7 +4,7 @@ /* */ /* OpenType BASE table validation (body). */ /* */ -/* Copyright 2004, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,7 +32,7 @@ static void otv_BaseCoord_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseCoordFormat; @@ -58,7 +58,7 @@ case 3: /* BaseCoordFormat3 */ OTV_LIMIT_CHECK( 2 ); /* DeviceTable */ - otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid ); break; default: @@ -71,7 +71,7 @@ static void otv_BaseTagList_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseTagCount; @@ -93,7 +93,7 @@ static void otv_BaseValues_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseCoordCount; @@ -112,7 +112,7 @@ /* BaseCoord */ for ( ; BaseCoordCount > 0; BaseCoordCount-- ) - otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; } @@ -120,7 +120,7 @@ static void otv_MinMax_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -144,11 +144,11 @@ OTV_SIZE_CHECK( MinCoord ); if ( MinCoord ) - otv_BaseCoord_validate( table + MinCoord, valid ); + otv_BaseCoord_validate( table + MinCoord, otvalid ); OTV_SIZE_CHECK( MaxCoord ); if ( MaxCoord ) - otv_BaseCoord_validate( table + MaxCoord, valid ); + otv_BaseCoord_validate( table + MaxCoord, otvalid ); OTV_LIMIT_CHECK( FeatMinMaxCount * 8 ); @@ -162,11 +162,11 @@ OTV_SIZE_CHECK( MinCoord ); if ( MinCoord ) - otv_BaseCoord_validate( table + MinCoord, valid ); + otv_BaseCoord_validate( table + MinCoord, otvalid ); OTV_SIZE_CHECK( MaxCoord ); if ( MaxCoord ) - otv_BaseCoord_validate( table + MaxCoord, valid ); + otv_BaseCoord_validate( table + MaxCoord, otvalid ); } OTV_EXIT; @@ -175,7 +175,7 @@ static void otv_BaseScript_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -198,11 +198,11 @@ OTV_SIZE_CHECK( BaseValues ); if ( BaseValues ) - otv_BaseValues_validate( table + BaseValues, valid ); + otv_BaseValues_validate( table + BaseValues, otvalid ); OTV_SIZE_CHECK( DefaultMinMax ); if ( DefaultMinMax ) - otv_MinMax_validate( table + DefaultMinMax, valid ); + otv_MinMax_validate( table + DefaultMinMax, otvalid ); OTV_LIMIT_CHECK( BaseLangSysCount * 6 ); @@ -211,7 +211,7 @@ { p += 4; /* skip BaseLangSysTag */ - otv_MinMax_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_MinMax_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; @@ -220,7 +220,7 @@ static void otv_BaseScriptList_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseScriptCount; @@ -241,7 +241,7 @@ p += 4; /* skip BaseScriptTag */ /* BaseScript */ - otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; @@ -250,7 +250,7 @@ static void otv_Axis_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -267,10 +267,10 @@ OTV_SIZE_CHECK( BaseTagList ); if ( BaseTagList ) - otv_BaseTagList_validate( table + BaseTagList, valid ); + otv_BaseTagList_validate( table + BaseTagList, otvalid ); /* BaseScriptList */ - otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; } @@ -280,16 +280,16 @@ otv_BASE_validate( FT_Bytes table, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; + FT_Bytes p = table; FT_UInt table_size; OTV_OPTIONAL_TABLE( HorizAxis ); OTV_OPTIONAL_TABLE( VertAxis ); - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating BASE table\n" )); OTV_INIT; @@ -304,12 +304,12 @@ OTV_OPTIONAL_OFFSET( HorizAxis ); OTV_SIZE_CHECK( HorizAxis ); if ( HorizAxis ) - otv_Axis_validate( table + HorizAxis, valid ); + otv_Axis_validate( table + HorizAxis, otvalid ); OTV_OPTIONAL_OFFSET( VertAxis ); OTV_SIZE_CHECK( VertAxis ); if ( VertAxis ) - otv_Axis_validate( table + VertAxis, valid ); + otv_Axis_validate( table + VertAxis, otvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/src/otvalid/otvcommn.c b/drivers/freetype/src/otvalid/otvcommn.c index a4f885b51f..2e88e102be 100644 --- a/drivers/freetype/src/otvalid/otvcommn.c +++ b/drivers/freetype/src/otvalid/otvcommn.c @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (body). */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,7 +39,7 @@ FT_LOCAL_DEF( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid, + OTV_Validator otvalid, FT_Int expected_count ) { FT_Bytes p = table; @@ -74,7 +74,7 @@ gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) + if ( gid >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; } @@ -104,7 +104,7 @@ if ( Start > End || StartCoverageIndex != total ) FT_INVALID_DATA; - if ( End >= valid->glyph_count ) + if ( End >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; if ( n > 0 && Start <= last ) @@ -219,7 +219,7 @@ FT_LOCAL_DEF( void ) otv_ClassDef_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt ClassFormat; @@ -249,7 +249,7 @@ OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ - if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count ) + if ( StartGlyph + GlyphCount - 1 >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; } break; @@ -276,7 +276,7 @@ if ( Start > End || ( n > 0 && Start <= last ) ) FT_INVALID_DATA; - if ( End >= valid->glyph_count ) + if ( End >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; last = End; @@ -305,7 +305,7 @@ FT_LOCAL_DEF( void ) otv_Device_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt StartSize, EndSize, DeltaFormat, count; @@ -339,12 +339,12 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->type_count */ - /* uses valid->type_funcs */ + /* uses otvalid->type_count */ + /* uses otvalid->type_funcs */ FT_LOCAL_DEF( void ) otv_Lookup_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LookupType, SubTableCount; @@ -360,10 +360,10 @@ OTV_TRACE(( " (type %d)\n", LookupType )); - if ( LookupType == 0 || LookupType > valid->type_count ) + if ( LookupType == 0 || LookupType > otvalid->type_count ) FT_INVALID_DATA; - validate = valid->type_funcs[LookupType - 1]; + validate = otvalid->type_funcs[LookupType - 1]; OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount )); @@ -371,7 +371,7 @@ /* SubTable */ for ( ; SubTableCount > 0; SubTableCount-- ) - validate( table + FT_NEXT_USHORT( p ), valid ); + validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; } @@ -381,7 +381,7 @@ FT_LOCAL_DEF( void ) otv_LookupList_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LookupCount; @@ -396,11 +396,11 @@ OTV_LIMIT_CHECK( LookupCount * 2 ); - valid->lookup_count = LookupCount; + otvalid->lookup_count = LookupCount; /* Lookup */ for ( ; LookupCount > 0; LookupCount-- ) - otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Lookup_validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; } @@ -421,11 +421,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->lookup_count */ + /* uses otvalid->lookup_count */ FT_LOCAL_DEF( void ) otv_Feature_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LookupCount; @@ -443,7 +443,7 @@ /* LookupListIndex */ for ( ; LookupCount > 0; LookupCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) FT_INVALID_DATA; OTV_EXIT; @@ -457,12 +457,12 @@ } - /* sets valid->lookup_count */ + /* sets otvalid->lookup_count */ FT_LOCAL_DEF( void ) otv_FeatureList_validate( FT_Bytes table, FT_Bytes lookups, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt FeatureCount; @@ -477,7 +477,7 @@ OTV_LIMIT_CHECK( FeatureCount * 2 ); - valid->lookup_count = otv_LookupList_get_count( lookups ); + otvalid->lookup_count = otv_LookupList_get_count( lookups ); /* FeatureRecord */ for ( ; FeatureCount > 0; FeatureCount-- ) @@ -485,7 +485,7 @@ p += 4; /* skip FeatureTag */ /* Feature */ - otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Feature_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; @@ -501,11 +501,11 @@ /*************************************************************************/ - /* uses valid->extra1 (number of features) */ + /* uses otvalid->extra1 (number of features) */ FT_LOCAL_DEF( void ) otv_LangSys_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt ReqFeatureIndex; @@ -522,14 +522,14 @@ OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex )); OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); - if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 ) + if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= otvalid->extra1 ) FT_INVALID_DATA; OTV_LIMIT_CHECK( FeatureCount * 2 ); /* FeatureIndex */ for ( ; FeatureCount > 0; FeatureCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; OTV_EXIT; @@ -546,7 +546,7 @@ FT_LOCAL_DEF( void ) otv_Script_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_UInt DefaultLangSys, LangSysCount; FT_Bytes p = table; @@ -561,7 +561,7 @@ OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount )); if ( DefaultLangSys != 0 ) - otv_LangSys_validate( table + DefaultLangSys, valid ); + otv_LangSys_validate( table + DefaultLangSys, otvalid ); OTV_LIMIT_CHECK( LangSysCount * 6 ); @@ -571,19 +571,19 @@ p += 4; /* skip LangSysTag */ /* LangSys */ - otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_LangSys_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; } - /* sets valid->extra1 (number of features) */ + /* sets otvalid->extra1 (number of features) */ FT_LOCAL_DEF( void ) otv_ScriptList_validate( FT_Bytes table, FT_Bytes features, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_UInt ScriptCount; FT_Bytes p = table; @@ -598,14 +598,14 @@ OTV_LIMIT_CHECK( ScriptCount * 6 ); - valid->extra1 = otv_Feature_get_count( features ); + otvalid->extra1 = otv_Feature_get_count( features ); /* ScriptRecord */ for ( ; ScriptCount > 0; ScriptCount-- ) { p += 4; /* skip ScriptTag */ - otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */ + otv_Script_validate( table + FT_NEXT_USHORT( p ), otvalid ); /* Script */ } OTV_EXIT; @@ -640,7 +640,7 @@ FT_LOCAL_DEF( void ) otv_x_Ox( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count; @@ -656,13 +656,13 @@ OTV_LIMIT_CHECK( Count * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; for ( ; Count > 0; Count-- ) - func( table + FT_NEXT_USHORT( p ), valid ); + func( table + FT_NEXT_USHORT( p ), otvalid ); - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } @@ -670,7 +670,7 @@ FT_LOCAL_DEF( void ) otv_u_C_x_Ox( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count, Coverage; @@ -687,27 +687,27 @@ OTV_TRACE(( " (Count = %d)\n", Count )); - otv_Coverage_validate( table + Coverage, valid, Count ); + otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)Count ); OTV_LIMIT_CHECK( Count * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; for ( ; Count > 0; Count-- ) - func( table + FT_NEXT_USHORT( p ), valid ); + func( table + FT_NEXT_USHORT( p ), otvalid ); - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } - /* uses valid->extra1 (if > 0: array value limit) */ + /* uses otvalid->extra1 (if > 0: array value limit) */ FT_LOCAL_DEF( void ) otv_x_ux( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count; @@ -722,10 +722,10 @@ OTV_LIMIT_CHECK( Count * 2 ); - if ( valid->extra1 ) + if ( otvalid->extra1 ) { for ( ; Count > 0; Count-- ) - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } @@ -736,11 +736,11 @@ /* `ux' in the function's name is not really correct since only x-1 */ /* elements are tested */ - /* uses valid->extra1 (array value limit) */ + /* uses otvalid->extra1 (array value limit) */ FT_LOCAL_DEF( void ) otv_x_y_ux_sy( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count1, Count2; @@ -766,7 +766,7 @@ if ( FT_NEXT_USHORT( p ) >= Count1 ) FT_INVALID_DATA; - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } @@ -777,11 +777,11 @@ /* `uy' in the function's name is not really correct since only y-1 */ /* elements are tested */ - /* uses valid->extra1 (array value limit) */ + /* uses otvalid->extra1 (array value limit) */ FT_LOCAL_DEF( void ) otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BacktrackCount, InputCount, LookaheadCount; @@ -825,7 +825,7 @@ if ( FT_NEXT_USHORT( p ) >= InputCount ) FT_INVALID_DATA; - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } @@ -833,11 +833,11 @@ } - /* sets valid->extra1 (valid->lookup_count) */ + /* sets otvalid->extra1 (valid->lookup_count) */ FT_LOCAL_DEF( void ) otv_u_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Coverage, ClassDef, ClassSetCount; @@ -855,14 +855,14 @@ OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ClassDef_validate( table + ClassDef, valid ); + otv_Coverage_validate( table + Coverage, otvalid, -1 ); + otv_ClassDef_validate( table + ClassDef, otvalid ); OTV_LIMIT_CHECK( ClassSetCount * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = valid->lookup_count; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; + otvalid->extra1 = otvalid->lookup_count; for ( ; ClassSetCount > 0; ClassSetCount-- ) { @@ -870,20 +870,20 @@ if ( offset ) - func( table + offset, valid ); + func( table + offset, otvalid ); } - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } - /* uses valid->lookup_count */ + /* uses otvalid->lookup_count */ FT_LOCAL_DEF( void ) otv_u_x_y_Ox_sy( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt GlyphCount, Count, count1; @@ -903,14 +903,14 @@ OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); for ( count1 = GlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); for ( ; Count > 0; Count-- ) { if ( FT_NEXT_USHORT( p ) >= GlyphCount ) FT_INVALID_DATA; - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) FT_INVALID_DATA; } @@ -918,11 +918,11 @@ } - /* sets valid->extra1 (valid->lookup_count) */ + /* sets otvalid->extra1 (valid->lookup_count) */ FT_LOCAL_DEF( void ) otv_u_O_O_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Coverage; @@ -944,17 +944,17 @@ OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); - otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_Coverage_validate( table + Coverage, otvalid, -1 ); - otv_ClassDef_validate( table + BacktrackClassDef, valid ); - otv_ClassDef_validate( table + InputClassDef, valid ); - otv_ClassDef_validate( table + LookaheadClassDef, valid ); + otv_ClassDef_validate( table + BacktrackClassDef, otvalid ); + otv_ClassDef_validate( table + InputClassDef, otvalid ); + otv_ClassDef_validate( table + LookaheadClassDef, otvalid ); OTV_LIMIT_CHECK( ChainClassSetCount * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = valid->lookup_count; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; + otvalid->extra1 = otvalid->lookup_count; for ( ; ChainClassSetCount > 0; ChainClassSetCount-- ) { @@ -962,20 +962,20 @@ if ( offset ) - func( table + offset, valid ); + func( table + offset, otvalid ); } - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } - /* uses valid->lookup_count */ + /* uses otvalid->lookup_count */ FT_LOCAL_DEF( void ) otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount; @@ -994,7 +994,7 @@ OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); InputGlyphCount = FT_NEXT_USHORT( p ); @@ -1003,7 +1003,7 @@ OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); for ( count1 = InputGlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -1012,7 +1012,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); count2 = FT_NEXT_USHORT( p ); @@ -1025,7 +1025,7 @@ if ( FT_NEXT_USHORT( p ) >= InputGlyphCount ) FT_INVALID_DATA; - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) FT_INVALID_DATA; } diff --git a/drivers/freetype/src/otvalid/otvcommn.h b/drivers/freetype/src/otvalid/otvcommn.h index 898887fc95..44e0c63793 100644 --- a/drivers/freetype/src/otvalid/otvcommn.h +++ b/drivers/freetype/src/otvalid/otvcommn.h @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (specification). */ /* */ -/* Copyright 2004, 2005, 2007, 2009 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVCOMMN_H__ -#define __OTVCOMMN_H__ +#ifndef OTVCOMMN_H_ +#define OTVCOMMN_H_ #include <ft2build.h> @@ -39,7 +39,7 @@ FT_BEGIN_HEADER typedef struct OTV_ValidatorRec_* OTV_Validator; typedef void (*OTV_Validate_Func)( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); typedef struct OTV_ValidatorRec_ { @@ -67,8 +67,8 @@ FT_BEGIN_HEADER #undef FT_INVALID_ -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid->root, _prefix ## _error ) +#define FT_INVALID_( _error ) \ + ft_validator_error( otvalid->root, FT_THROW( _error ) ) #define OTV_OPTIONAL_TABLE( _table ) FT_UShort _table; \ FT_Bytes _table ## _p @@ -81,7 +81,7 @@ FT_BEGIN_HEADER #define OTV_LIMIT_CHECK( _count ) \ FT_BEGIN_STMNT \ - if ( p + (_count) > valid->root->limit ) \ + if ( p + (_count) > otvalid->root->limit ) \ FT_INVALID_TOO_SHORT; \ FT_END_STMNT @@ -89,7 +89,7 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ if ( _size > 0 && _size < table_size ) \ { \ - if ( valid->root->level == FT_VALIDATE_PARANOID ) \ + if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \ FT_INVALID_OFFSET; \ else \ { \ @@ -117,79 +117,79 @@ FT_BEGIN_HEADER #ifdef FT_DEBUG_LEVEL_TRACE -#define OTV_NEST1( x ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ +#define OTV_NEST1( x ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->debug_function_name[0] = OTV_NAME( x ); \ FT_END_STMNT -#define OTV_NEST2( x, y ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ - valid->debug_function_name[1] = OTV_NAME( y ); \ +#define OTV_NEST2( x, y ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->func[1] = OTV_FUNC( y ); \ + otvalid->debug_function_name[0] = OTV_NAME( x ); \ + otvalid->debug_function_name[1] = OTV_NAME( y ); \ FT_END_STMNT -#define OTV_NEST3( x, y, z ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->func[2] = OTV_FUNC( z ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ - valid->debug_function_name[1] = OTV_NAME( y ); \ - valid->debug_function_name[2] = OTV_NAME( z ); \ +#define OTV_NEST3( x, y, z ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->func[1] = OTV_FUNC( y ); \ + otvalid->func[2] = OTV_FUNC( z ); \ + otvalid->debug_function_name[0] = OTV_NAME( x ); \ + otvalid->debug_function_name[1] = OTV_NAME( y ); \ + otvalid->debug_function_name[2] = OTV_NAME( z ); \ FT_END_STMNT -#define OTV_INIT valid->debug_indent = 0 +#define OTV_INIT otvalid->debug_indent = 0 -#define OTV_ENTER \ - FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", \ - valid->debug_function_name[valid->nesting_level] )); \ +#define OTV_ENTER \ + FT_BEGIN_STMNT \ + otvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", \ + otvalid->debug_function_name[otvalid->nesting_level] )); \ FT_END_STMNT -#define OTV_NAME_ENTER( name ) \ - FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", name )); \ +#define OTV_NAME_ENTER( name ) \ + FT_BEGIN_STMNT \ + otvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", name )); \ FT_END_STMNT -#define OTV_EXIT valid->debug_indent -= 2 +#define OTV_EXIT otvalid->debug_indent -= 2 -#define OTV_TRACE( s ) \ - FT_BEGIN_STMNT \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4( s ); \ +#define OTV_TRACE( s ) \ + FT_BEGIN_STMNT \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ + FT_TRACE4( s ); \ FT_END_STMNT #else /* !FT_DEBUG_LEVEL_TRACE */ -#define OTV_NEST1( x ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ +#define OTV_NEST1( x ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ FT_END_STMNT -#define OTV_NEST2( x, y ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ +#define OTV_NEST2( x, y ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->func[1] = OTV_FUNC( y ); \ FT_END_STMNT -#define OTV_NEST3( x, y, z ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->func[2] = OTV_FUNC( z ); \ +#define OTV_NEST3( x, y, z ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->func[1] = OTV_FUNC( y ); \ + otvalid->func[2] = OTV_FUNC( z ); \ FT_END_STMNT #define OTV_INIT do { } while ( 0 ) @@ -202,7 +202,7 @@ FT_BEGIN_HEADER #endif /* !FT_DEBUG_LEVEL_TRACE */ -#define OTV_RUN valid->func[0] +#define OTV_RUN otvalid->func[0] /*************************************************************************/ @@ -215,7 +215,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid, + OTV_Validator otvalid, FT_Int expected_count ); /* return first covered glyph */ @@ -241,7 +241,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_ClassDef_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -254,7 +254,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Device_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -267,11 +267,11 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Lookup_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); FT_LOCAL( void ) otv_LookupList_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -284,13 +284,13 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Feature_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /* lookups must already be validated */ FT_LOCAL( void ) otv_FeatureList_validate( FT_Bytes table, FT_Bytes lookups, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -303,7 +303,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_LangSys_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -316,13 +316,13 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Script_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /* features must already be validated */ FT_LOCAL( void ) otv_ScriptList_validate( FT_Bytes table, FT_Bytes features, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -349,7 +349,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_x_Ox ( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define AlternateSubstFormat1Func otv_u_C_x_Ox #define ChainContextPosFormat1Func otv_u_C_x_Ox @@ -361,7 +361,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_u_C_x_Ox( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define AlternateSetFunc otv_x_ux #define AttachPointFunc otv_x_ux @@ -372,7 +372,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_x_ux( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define PosClassRuleFunc otv_x_y_ux_sy #define PosRuleFunc otv_x_y_ux_sy @@ -381,7 +381,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_x_y_ux_sy( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ChainPosClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp #define ChainPosRuleFunc otv_x_ux_y_uy_z_uz_p_sp @@ -390,35 +390,35 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ContextPosFormat2Func otv_u_O_O_x_Onx #define ContextSubstFormat2Func otv_u_O_O_x_Onx FT_LOCAL( void ) otv_u_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ContextPosFormat3Func otv_u_x_y_Ox_sy #define ContextSubstFormat3Func otv_u_x_y_Ox_sy FT_LOCAL( void ) otv_u_x_y_Ox_sy( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ChainContextPosFormat2Func otv_u_O_O_O_O_x_Onx #define ChainContextSubstFormat2Func otv_u_O_O_O_O_x_Onx FT_LOCAL( void ) otv_u_O_O_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ChainContextPosFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp #define ChainContextSubstFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp FT_LOCAL( void ) otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); FT_LOCAL( FT_UInt ) @@ -431,7 +431,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVCOMMN_H__ */ +#endif /* OTVCOMMN_H_ */ /* END */ diff --git a/drivers/freetype/src/otvalid/otverror.h b/drivers/freetype/src/otvalid/otverror.h index b6f00c9dba..e7c8db0d58 100644 --- a/drivers/freetype/src/otvalid/otverror.h +++ b/drivers/freetype/src/otvalid/otverror.h @@ -4,7 +4,7 @@ /* */ /* OpenType validation module error codes (specification only). */ /* */ -/* Copyright 2004, 2005, 2012, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __OTVERROR_H__ -#define __OTVERROR_H__ +#ifndef OTVERROR_H_ +#define OTVERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX OTV_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __OTVERROR_H__ */ +#endif /* OTVERROR_H_ */ /* END */ diff --git a/drivers/freetype/src/otvalid/otvgdef.c b/drivers/freetype/src/otvalid/otvgdef.c index 3633ad0de1..f19e300e51 100644 --- a/drivers/freetype/src/otvalid/otvgdef.c +++ b/drivers/freetype/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ /* */ /* OpenType GDEF table validation (body). */ /* */ -/* Copyright 2004, 2005, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ static void otv_O_x_Ox( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_Bytes Coverage; @@ -61,20 +61,20 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( Coverage, valid, GlyphCount ); + otv_Coverage_validate( Coverage, otvalid, (FT_Int)GlyphCount ); if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) FT_INVALID_DATA; OTV_LIMIT_CHECK( GlyphCount * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = 0; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; + otvalid->extra1 = 0; for ( ; GlyphCount > 0; GlyphCount-- ) - func( table + FT_NEXT_USHORT( p ), valid ); + func( table + FT_NEXT_USHORT( p ), otvalid ); - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } @@ -92,7 +92,7 @@ static void otv_CaretValue_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt CaretValueFormat; @@ -122,7 +122,7 @@ OTV_LIMIT_CHECK( 2 ); /* DeviceTable */ - otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid ); break; default: @@ -141,7 +141,7 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->glyph_count */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_GDEF_validate( FT_Bytes table, @@ -150,8 +150,8 @@ FT_UInt glyph_count, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; FT_UInt table_size; FT_Bool need_MarkAttachClassDef; @@ -162,7 +162,7 @@ OTV_OPTIONAL_TABLE( MarkAttachClassDef ); - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating GDEF table\n" )); OTV_INIT; @@ -186,19 +186,19 @@ else table_size = 10; /* OpenType < 1.2 */ - valid->glyph_count = glyph_count; + otvalid->glyph_count = glyph_count; OTV_OPTIONAL_OFFSET( GlyphClassDef ); OTV_SIZE_CHECK( GlyphClassDef ); if ( GlyphClassDef ) - otv_ClassDef_validate( table + GlyphClassDef, valid ); + otv_ClassDef_validate( table + GlyphClassDef, otvalid ); OTV_OPTIONAL_OFFSET( AttachListOffset ); OTV_SIZE_CHECK( AttachListOffset ); if ( AttachListOffset ) { OTV_NEST2( AttachList, AttachPoint ); - OTV_RUN( table + AttachListOffset, valid ); + OTV_RUN( table + AttachListOffset, otvalid ); } OTV_OPTIONAL_OFFSET( LigCaretListOffset ); @@ -206,7 +206,7 @@ if ( LigCaretListOffset ) { OTV_NEST3( LigCaretList, LigGlyph, CaretValue ); - OTV_RUN( table + LigCaretListOffset, valid ); + OTV_RUN( table + LigCaretListOffset, otvalid ); } if ( need_MarkAttachClassDef ) @@ -214,7 +214,7 @@ OTV_OPTIONAL_OFFSET( MarkAttachClassDef ); OTV_SIZE_CHECK( MarkAttachClassDef ); if ( MarkAttachClassDef ) - otv_ClassDef_validate( table + MarkAttachClassDef, valid ); + otv_ClassDef_validate( table + MarkAttachClassDef, otvalid ); } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/src/otvalid/otvgpos.c b/drivers/freetype/src/otvalid/otvgpos.c index 49b46183a3..e904ea5d6c 100644 --- a/drivers/freetype/src/otvalid/otvgpos.c +++ b/drivers/freetype/src/otvalid/otvgpos.c @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validation (body). */ /* */ -/* Copyright 2002, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -57,7 +57,7 @@ static void otv_x_sxy( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count, count1, table_size; @@ -71,26 +71,26 @@ OTV_TRACE(( " (Count = %d)\n", Count )); - OTV_LIMIT_CHECK( Count * valid->extra1 * 2 ); + OTV_LIMIT_CHECK( Count * otvalid->extra1 * 2 ); - table_size = Count * valid->extra1 * 2 + 2; + table_size = Count * otvalid->extra1 * 2 + 2; for ( ; Count > 0; Count-- ) - for ( count1 = valid->extra1; count1 > 0; count1-- ) + for ( count1 = otvalid->extra1; count1 > 0; count1-- ) { OTV_OPTIONAL_TABLE( anchor_offset ); OTV_OPTIONAL_OFFSET( anchor_offset ); - if ( valid->extra2 ) + if ( otvalid->extra2 ) { OTV_SIZE_CHECK( anchor_offset ); if ( anchor_offset ) - otv_Anchor_validate( table + anchor_offset, valid ); + otv_Anchor_validate( table + anchor_offset, otvalid ); } else - otv_Anchor_validate( table + anchor_offset, valid ); + otv_Anchor_validate( table + anchor_offset, otvalid ); } OTV_EXIT; @@ -101,11 +101,11 @@ #define MarkLigPosFormat1Func otv_u_O_O_u_O_O #define MarkMarkPosFormat1Func otv_u_O_O_u_O_O - /* sets valid->extra1 (class count) */ + /* sets otvalid->extra1 (class count) */ static void otv_u_O_O_u_O_O( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Coverage1, Coverage2, ClassCount; @@ -124,18 +124,18 @@ Array1 = FT_NEXT_USHORT( p ); Array2 = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage1, valid, -1 ); - otv_Coverage_validate( table + Coverage2, valid, -1 ); + otv_Coverage_validate( table + Coverage1, otvalid, -1 ); + otv_Coverage_validate( table + Coverage2, otvalid, -1 ); - otv_MarkArray_validate( table + Array1, valid ); + otv_MarkArray_validate( table + Array1, otvalid ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = ClassCount; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; + otvalid->extra1 = ClassCount; - func( table + Array2, valid ); + func( table + Array2, otvalid ); - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } @@ -163,12 +163,12 @@ } - /* uses valid->extra3 (pointer to base table) */ + /* uses otvalid->extra3 (pointer to base table) */ static void otv_ValueRecord_validate( FT_Bytes table, FT_UInt format, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt count; @@ -222,11 +222,11 @@ /* ValueRecord is part of an array -- getting the correct table */ /* size is probably not worth the trouble */ - table_size = p - valid->extra3; + table_size = p - otvalid->extra3; OTV_SIZE_CHECK( device ); if ( device ) - otv_Device_validate( valid->extra3 + device, valid ); + otv_Device_validate( otvalid->extra3 + device, otvalid ); } format >>= 1; } @@ -245,7 +245,7 @@ static void otv_Anchor_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt AnchorFormat; @@ -285,11 +285,11 @@ OTV_SIZE_CHECK( XDeviceTable ); if ( XDeviceTable ) - otv_Device_validate( table + XDeviceTable, valid ); + otv_Device_validate( table + XDeviceTable, otvalid ); OTV_SIZE_CHECK( YDeviceTable ); if ( YDeviceTable ) - otv_Device_validate( table + YDeviceTable, valid ); + otv_Device_validate( table + YDeviceTable, otvalid ); } break; @@ -311,7 +311,7 @@ static void otv_MarkArray_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt MarkCount; @@ -331,7 +331,7 @@ { p += 2; /* skip Class */ /* MarkAnchor */ - otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Anchor_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; @@ -346,11 +346,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra3 (pointer to base table) */ + /* sets otvalid->extra3 (pointer to base table) */ static void otv_SinglePos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -363,7 +363,7 @@ OTV_TRACE(( " (format %d)\n", PosFormat )); - valid->extra3 = table; + otvalid->extra3 = table; switch ( PosFormat ) { @@ -376,8 +376,8 @@ Coverage = FT_NEXT_USHORT( p ); ValueFormat = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ + otv_Coverage_validate( table + Coverage, otvalid, -1 ); + otv_ValueRecord_validate( p, ValueFormat, otvalid ); /* Value */ } break; @@ -395,14 +395,16 @@ len_value = otv_value_length( ValueFormat ); - otv_Coverage_validate( table + Coverage, valid, ValueCount ); + otv_Coverage_validate( table + Coverage, + otvalid, + (FT_Int)ValueCount ); OTV_LIMIT_CHECK( ValueCount * len_value ); /* Value */ for ( ; ValueCount > 0; ValueCount-- ) { - otv_ValueRecord_validate( p, ValueFormat, valid ); + otv_ValueRecord_validate( p, ValueFormat, otvalid ); p += len_value; } } @@ -428,7 +430,7 @@ otv_PairSet_validate( FT_Bytes table, FT_UInt format1, FT_UInt format2, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt value_len1, value_len2, PairValueCount; @@ -452,11 +454,11 @@ p += 2; /* skip SecondGlyph */ if ( format1 ) - otv_ValueRecord_validate( p, format1, valid ); /* Value1 */ + otv_ValueRecord_validate( p, format1, otvalid ); /* Value1 */ p += value_len1; if ( format2 ) - otv_ValueRecord_validate( p, format2, valid ); /* Value2 */ + otv_ValueRecord_validate( p, format2, otvalid ); /* Value2 */ p += value_len2; } @@ -464,11 +466,11 @@ } - /* sets valid->extra3 (pointer to base table) */ + /* sets otvalid->extra3 (pointer to base table) */ static void otv_PairPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -481,7 +483,7 @@ OTV_TRACE(( " (format %d)\n", PosFormat )); - valid->extra3 = table; + otvalid->extra3 = table; switch ( PosFormat ) { @@ -498,14 +500,14 @@ OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); - otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_Coverage_validate( table + Coverage, otvalid, -1 ); OTV_LIMIT_CHECK( PairSetCount * 2 ); /* PairSetOffset */ for ( ; PairSetCount > 0; PairSetCount-- ) otv_PairSet_validate( table + FT_NEXT_USHORT( p ), - ValueFormat1, ValueFormat2, valid ); + ValueFormat1, ValueFormat2, otvalid ); } break; @@ -530,9 +532,9 @@ len_value1 = otv_value_length( ValueFormat1 ); len_value2 = otv_value_length( ValueFormat2 ); - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ClassDef_validate( table + ClassDef1, valid ); - otv_ClassDef_validate( table + ClassDef2, valid ); + otv_Coverage_validate( table + Coverage, otvalid, -1 ); + otv_ClassDef_validate( table + ClassDef1, otvalid ); + otv_ClassDef_validate( table + ClassDef2, otvalid ); OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 * ( len_value1 + len_value2 ) ); @@ -545,12 +547,12 @@ { if ( ValueFormat1 ) /* Value1 */ - otv_ValueRecord_validate( p, ValueFormat1, valid ); + otv_ValueRecord_validate( p, ValueFormat1, otvalid ); p += len_value1; if ( ValueFormat2 ) /* Value2 */ - otv_ValueRecord_validate( p, ValueFormat2, valid ); + otv_ValueRecord_validate( p, ValueFormat2, otvalid ); p += len_value2; } } @@ -575,7 +577,7 @@ static void otv_CursivePos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -605,7 +607,9 @@ OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); - otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); + otv_Coverage_validate( table + Coverage, + otvalid, + (FT_Int)EntryExitCount ); OTV_LIMIT_CHECK( EntryExitCount * 4 ); @@ -619,11 +623,11 @@ OTV_SIZE_CHECK( EntryAnchor ); if ( EntryAnchor ) - otv_Anchor_validate( table + EntryAnchor, valid ); + otv_Anchor_validate( table + EntryAnchor, otvalid ); OTV_SIZE_CHECK( ExitAnchor ); if ( ExitAnchor ) - otv_Anchor_validate( table + ExitAnchor, valid ); + otv_Anchor_validate( table + ExitAnchor, otvalid ); } } break; @@ -647,11 +651,11 @@ /* UNDOCUMENTED (in OpenType 1.5): */ /* BaseRecord tables can contain NULL pointers. */ - /* sets valid->extra2 (1) */ + /* sets otvalid->extra2 (1) */ static void otv_MarkBasePos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -667,9 +671,9 @@ switch ( PosFormat ) { case 1: - valid->extra2 = 1; + otvalid->extra2 = 1; OTV_NEST2( MarkBasePosFormat1, BaseArray ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -688,11 +692,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra2 (1) */ + /* sets otvalid->extra2 (1) */ static void otv_MarkLigPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -708,9 +712,9 @@ switch ( PosFormat ) { case 1: - valid->extra2 = 1; + otvalid->extra2 = 1; OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -729,11 +733,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra2 (0) */ + /* sets otvalid->extra2 (0) */ static void otv_MarkMarkPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -749,9 +753,9 @@ switch ( PosFormat ) { case 1: - valid->extra2 = 0; + otvalid->extra2 = 0; OTV_NEST2( MarkMarkPosFormat1, Mark2Array ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -770,11 +774,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (lookup count) */ + /* sets otvalid->extra1 (lookup count) */ static void otv_ContextPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -794,9 +798,9 @@ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ - valid->extra1 = valid->lookup_count; + otvalid->extra1 = otvalid->lookup_count; OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 2: @@ -805,12 +809,12 @@ /* meaningful results */ OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 3: OTV_NEST1( ContextPosFormat3 ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -829,11 +833,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (lookup count) */ + /* sets otvalid->extra1 (lookup count) */ static void otv_ChainContextPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -853,10 +857,10 @@ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ - valid->extra1 = valid->lookup_count; + otvalid->extra1 = otvalid->lookup_count; OTV_NEST3( ChainContextPosFormat1, ChainPosRuleSet, ChainPosRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 2: @@ -866,12 +870,12 @@ OTV_NEST3( ChainContextPosFormat2, ChainPosClassSet, ChainPosClassRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 3: OTV_NEST1( ChainContextPosFormat3 ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -890,11 +894,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->type_funcs */ + /* uses otvalid->type_funcs */ static void otv_ExtensionPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -923,8 +927,8 @@ if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 ) FT_INVALID_DATA; - validate = valid->type_funcs[ExtensionLookupType - 1]; - validate( table + ExtensionOffset, valid ); + validate = otvalid->type_funcs[ExtensionLookupType - 1]; + validate( table + ExtensionOffset, otvalid ); } break; @@ -950,17 +954,17 @@ }; - /* sets valid->type_count */ - /* sets valid->type_funcs */ + /* sets otvalid->type_count */ + /* sets otvalid->type_funcs */ FT_LOCAL_DEF( void ) otv_GPOS_subtable_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { - valid->type_count = 9; - valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; + otvalid->type_count = 9; + otvalid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; - otv_Lookup_validate( table, valid ); + otv_Lookup_validate( table, otvalid ); } @@ -972,7 +976,7 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->glyph_count */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_GPOS_validate( FT_Bytes table, @@ -980,12 +984,12 @@ FT_Validator ftvalid ) { OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; + OTV_Validator otvalid = &validrec; FT_Bytes p = table; FT_UInt ScriptList, FeatureList, LookupList; - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating GPOS table\n" )); OTV_INIT; @@ -999,16 +1003,16 @@ FeatureList = FT_NEXT_USHORT( p ); LookupList = FT_NEXT_USHORT( p ); - valid->type_count = 9; - valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; - valid->glyph_count = glyph_count; + otvalid->type_count = 9; + otvalid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; + otvalid->glyph_count = glyph_count; otv_LookupList_validate( table + LookupList, - valid ); + otvalid ); otv_FeatureList_validate( table + FeatureList, table + LookupList, - valid ); + otvalid ); otv_ScriptList_validate( table + ScriptList, table + FeatureList, - valid ); + otvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/src/otvalid/otvgpos.h b/drivers/freetype/src/otvalid/otvgpos.h index 14ca408261..2c09e64f97 100644 --- a/drivers/freetype/src/otvalid/otvgpos.h +++ b/drivers/freetype/src/otvalid/otvgpos.h @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validator (specification). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVGPOS_H__ -#define __OTVGPOS_H__ +#ifndef OTVGPOS_H_ +#define OTVGPOS_H_ FT_BEGIN_HEADER @@ -30,7 +30,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVGPOS_H__ */ +#endif /* OTVGPOS_H_ */ /* END */ diff --git a/drivers/freetype/src/otvalid/otvgsub.c b/drivers/freetype/src/otvalid/otvgsub.c index ed499d1e92..c2b28569f1 100644 --- a/drivers/freetype/src/otvalid/otvgsub.c +++ b/drivers/freetype/src/otvalid/otvgsub.c @@ -4,7 +4,7 @@ /* */ /* OpenType GSUB table validation (body). */ /* */ -/* Copyright 2004, 2005, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,11 +38,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->glyph_count */ + /* uses otvalid->glyph_count */ static void otv_SingleSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -68,14 +68,14 @@ Coverage = table + FT_NEXT_USHORT( p ); DeltaGlyphID = FT_NEXT_SHORT( p ); - otv_Coverage_validate( Coverage, valid, -1 ); + otv_Coverage_validate( Coverage, otvalid, -1 ); - idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; + idx = (FT_Long)otv_Coverage_get_first( Coverage ) + DeltaGlyphID; if ( idx < 0 ) FT_INVALID_DATA; - idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID; - if ( (FT_UInt)idx >= valid->glyph_count ) + idx = (FT_Long)otv_Coverage_get_last( Coverage ) + DeltaGlyphID; + if ( (FT_UInt)idx >= otvalid->glyph_count ) FT_INVALID_DATA; } break; @@ -91,13 +91,15 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( table + Coverage, valid, GlyphCount ); + otv_Coverage_validate( table + Coverage, + otvalid, + (FT_Int)GlyphCount ); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* Substitute */ for ( ; GlyphCount > 0; GlyphCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; } break; @@ -118,11 +120,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (glyph count) */ + /* sets otvalid->extra1 (glyph count) */ static void otv_MultipleSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -138,9 +140,9 @@ switch ( SubstFormat ) { case 1: - valid->extra1 = valid->glyph_count; + otvalid->extra1 = otvalid->glyph_count; OTV_NEST2( MultipleSubstFormat1, Sequence ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -159,11 +161,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (glyph count) */ + /* sets otvalid->extra1 (glyph count) */ static void otv_AlternateSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -179,9 +181,9 @@ switch ( SubstFormat ) { case 1: - valid->extra1 = valid->glyph_count; + otvalid->extra1 = otvalid->glyph_count; OTV_NEST2( AlternateSubstFormat1, AlternateSet ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -202,11 +204,11 @@ #define LigatureFunc otv_Ligature_validate - /* uses valid->glyph_count */ + /* uses otvalid->glyph_count */ static void otv_Ligature_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LigatureGlyph, CompCount; @@ -216,7 +218,7 @@ OTV_LIMIT_CHECK( 4 ); LigatureGlyph = FT_NEXT_USHORT( p ); - if ( LigatureGlyph >= valid->glyph_count ) + if ( LigatureGlyph >= otvalid->glyph_count ) FT_INVALID_DATA; CompCount = FT_NEXT_USHORT( p ); @@ -238,7 +240,7 @@ static void otv_LigatureSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -255,7 +257,7 @@ { case 1: OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -274,11 +276,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (lookup count) */ + /* sets otvalid->extra1 (lookup count) */ static void otv_ContextSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -298,9 +300,9 @@ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ - valid->extra1 = valid->lookup_count; + otvalid->extra1 = otvalid->lookup_count; OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 2: @@ -309,12 +311,12 @@ /* meaningful results */ OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 3: OTV_NEST1( ContextSubstFormat3 ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -333,11 +335,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (lookup count) */ + /* sets otvalid->extra1 (lookup count) */ static void otv_ChainContextSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -357,10 +359,10 @@ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ - valid->extra1 = valid->lookup_count; + otvalid->extra1 = otvalid->lookup_count; OTV_NEST3( ChainContextSubstFormat1, ChainSubRuleSet, ChainSubRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 2: @@ -370,12 +372,12 @@ OTV_NEST3( ChainContextSubstFormat2, ChainSubClassSet, ChainSubClassRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 3: OTV_NEST1( ChainContextSubstFormat3 ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -394,11 +396,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->type_funcs */ + /* uses otvalid->type_funcs */ static void otv_ExtensionSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -429,8 +431,8 @@ ExtensionLookupType > 8 ) FT_INVALID_DATA; - validate = valid->type_funcs[ExtensionLookupType - 1]; - validate( table + ExtensionOffset, valid ); + validate = otvalid->type_funcs[ExtensionLookupType - 1]; + validate( table + ExtensionOffset, otvalid ); } break; @@ -450,11 +452,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->glyph_count */ + /* uses otvalid->glyph_count */ static void otv_ReverseChainSingleSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table, Coverage; FT_UInt SubstFormat; @@ -477,12 +479,12 @@ OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); - otv_Coverage_validate( Coverage, valid, -1 ); + otv_Coverage_validate( Coverage, otvalid, -1 ); OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -491,7 +493,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); GlyphCount = FT_NEXT_USHORT( p ); @@ -504,7 +506,7 @@ /* Substitute */ for ( ; GlyphCount > 0; GlyphCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->glyph_count ) FT_INVALID_DATA; break; @@ -538,22 +540,22 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->type_count */ - /* sets valid->type_funcs */ - /* sets valid->glyph_count */ + /* sets otvalid->type_count */ + /* sets otvalid->type_funcs */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_GSUB_validate( FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; + FT_Bytes p = table; FT_UInt ScriptList, FeatureList, LookupList; - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating GSUB table\n" )); OTV_INIT; @@ -567,16 +569,16 @@ FeatureList = FT_NEXT_USHORT( p ); LookupList = FT_NEXT_USHORT( p ); - valid->type_count = 8; - valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; - valid->glyph_count = glyph_count; + otvalid->type_count = 8; + otvalid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; + otvalid->glyph_count = glyph_count; otv_LookupList_validate( table + LookupList, - valid ); + otvalid ); otv_FeatureList_validate( table + FeatureList, table + LookupList, - valid ); + otvalid ); otv_ScriptList_validate( table + ScriptList, table + FeatureList, - valid ); + otvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/src/otvalid/otvjstf.c b/drivers/freetype/src/otvalid/otvjstf.c index a616a23432..e19c1c1213 100644 --- a/drivers/freetype/src/otvalid/otvjstf.c +++ b/drivers/freetype/src/otvalid/otvjstf.c @@ -4,7 +4,7 @@ /* */ /* OpenType JSTF table validation (body). */ /* */ -/* Copyright 2004, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,13 +34,13 @@ #define JstfPriorityFunc otv_JstfPriority_validate #define JstfLookupFunc otv_GPOS_subtable_validate - /* uses valid->extra1 (GSUB lookup count) */ - /* uses valid->extra2 (GPOS lookup count) */ - /* sets valid->extra1 (counter) */ + /* uses otvalid->extra1 (GSUB lookup count) */ + /* uses otvalid->extra2 (GPOS lookup count) */ + /* sets otvalid->extra1 (counter) */ static void otv_JstfPriority_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -63,34 +63,34 @@ OTV_LIMIT_CHECK( 20 ); - gsub_lookup_count = valid->extra1; - gpos_lookup_count = valid->extra2; + gsub_lookup_count = otvalid->extra1; + gpos_lookup_count = otvalid->extra2; table_size = 20; - valid->extra1 = gsub_lookup_count; + otvalid->extra1 = gsub_lookup_count; OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB ); OTV_SIZE_CHECK( ShrinkageEnableGSUB ); if ( ShrinkageEnableGSUB ) - otv_x_ux( table + ShrinkageEnableGSUB, valid ); + otv_x_ux( table + ShrinkageEnableGSUB, otvalid ); OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB ); OTV_SIZE_CHECK( ShrinkageDisableGSUB ); if ( ShrinkageDisableGSUB ) - otv_x_ux( table + ShrinkageDisableGSUB, valid ); + otv_x_ux( table + ShrinkageDisableGSUB, otvalid ); - valid->extra1 = gpos_lookup_count; + otvalid->extra1 = gpos_lookup_count; OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS ); OTV_SIZE_CHECK( ShrinkageEnableGPOS ); if ( ShrinkageEnableGPOS ) - otv_x_ux( table + ShrinkageEnableGPOS, valid ); + otv_x_ux( table + ShrinkageEnableGPOS, otvalid ); OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS ); OTV_SIZE_CHECK( ShrinkageDisableGPOS ); if ( ShrinkageDisableGPOS ) - otv_x_ux( table + ShrinkageDisableGPOS, valid ); + otv_x_ux( table + ShrinkageDisableGPOS, otvalid ); OTV_OPTIONAL_OFFSET( ShrinkageJstfMax ); OTV_SIZE_CHECK( ShrinkageJstfMax ); @@ -98,32 +98,32 @@ { /* XXX: check lookup types? */ OTV_NEST2( JstfMax, JstfLookup ); - OTV_RUN( table + ShrinkageJstfMax, valid ); + OTV_RUN( table + ShrinkageJstfMax, otvalid ); } - valid->extra1 = gsub_lookup_count; + otvalid->extra1 = gsub_lookup_count; OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB ); OTV_SIZE_CHECK( ExtensionEnableGSUB ); if ( ExtensionEnableGSUB ) - otv_x_ux( table + ExtensionEnableGSUB, valid ); + otv_x_ux( table + ExtensionEnableGSUB, otvalid ); OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB ); OTV_SIZE_CHECK( ExtensionDisableGSUB ); if ( ExtensionDisableGSUB ) - otv_x_ux( table + ExtensionDisableGSUB, valid ); + otv_x_ux( table + ExtensionDisableGSUB, otvalid ); - valid->extra1 = gpos_lookup_count; + otvalid->extra1 = gpos_lookup_count; OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS ); OTV_SIZE_CHECK( ExtensionEnableGPOS ); if ( ExtensionEnableGPOS ) - otv_x_ux( table + ExtensionEnableGPOS, valid ); + otv_x_ux( table + ExtensionEnableGPOS, otvalid ); OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS ); OTV_SIZE_CHECK( ExtensionDisableGPOS ); if ( ExtensionDisableGPOS ) - otv_x_ux( table + ExtensionDisableGPOS, valid ); + otv_x_ux( table + ExtensionDisableGPOS, otvalid ); OTV_OPTIONAL_OFFSET( ExtensionJstfMax ); OTV_SIZE_CHECK( ExtensionJstfMax ); @@ -131,22 +131,22 @@ { /* XXX: check lookup types? */ OTV_NEST2( JstfMax, JstfLookup ); - OTV_RUN( table + ExtensionJstfMax, valid ); + OTV_RUN( table + ExtensionJstfMax, otvalid ); } - valid->extra1 = gsub_lookup_count; - valid->extra2 = gpos_lookup_count; + otvalid->extra1 = gsub_lookup_count; + otvalid->extra2 = gpos_lookup_count; OTV_EXIT; } - /* sets valid->extra (glyph count) */ - /* sets valid->func1 (otv_JstfPriority_validate) */ + /* sets otvalid->extra (glyph count) */ + /* sets otvalid->func1 (otv_JstfPriority_validate) */ static void otv_JstfScript_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -170,16 +170,16 @@ OTV_SIZE_CHECK( ExtGlyph ); if ( ExtGlyph ) { - valid->extra1 = valid->glyph_count; + otvalid->extra1 = otvalid->glyph_count; OTV_NEST1( ExtenderGlyph ); - OTV_RUN( table + ExtGlyph, valid ); + OTV_RUN( table + ExtGlyph, otvalid ); } OTV_SIZE_CHECK( DefJstfLangSys ); if ( DefJstfLangSys ) { OTV_NEST2( JstfLangSys, JstfPriority ); - OTV_RUN( table + DefJstfLangSys, valid ); + OTV_RUN( table + DefJstfLangSys, otvalid ); } OTV_LIMIT_CHECK( 6 * JstfLangSysCount ); @@ -190,16 +190,16 @@ { p += 4; /* skip JstfLangSysTag */ - OTV_RUN( table + FT_NEXT_USHORT( p ), valid ); + OTV_RUN( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; } - /* sets valid->extra1 (GSUB lookup count) */ - /* sets valid->extra2 (GPOS lookup count) */ - /* sets valid->glyph_count */ + /* sets otvalid->extra1 (GSUB lookup count) */ + /* sets otvalid->extra2 (GPOS lookup count) */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_JSTF_validate( FT_Bytes table, @@ -208,13 +208,14 @@ FT_UInt glyph_count, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; FT_UInt JstfScriptCount; - valid->root = ftvalid; + otvalid->root = ftvalid; + FT_TRACE3(( "validating JSTF table\n" )); OTV_INIT; @@ -231,16 +232,16 @@ OTV_LIMIT_CHECK( JstfScriptCount * 6 ); if ( gsub ) - valid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); + otvalid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); else - valid->extra1 = 0; + otvalid->extra1 = 0; if ( gpos ) - valid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); + otvalid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); else - valid->extra2 = 0; + otvalid->extra2 = 0; - valid->glyph_count = glyph_count; + otvalid->glyph_count = glyph_count; /* JstfScriptRecord */ for ( ; JstfScriptCount > 0; JstfScriptCount-- ) @@ -248,7 +249,7 @@ p += 4; /* skip JstfScriptTag */ /* JstfScript */ - otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), otvalid ); } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/src/otvalid/otvmath.c b/drivers/freetype/src/otvalid/otvmath.c index 96f841f2a9..6c785b6fda 100644 --- a/drivers/freetype/src/otvalid/otvmath.c +++ b/drivers/freetype/src/otvalid/otvmath.c @@ -4,7 +4,7 @@ /* */ /* OpenType MATH table validation (body). */ /* */ -/* Copyright 2007, 2008 by */ +/* Copyright 2007-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Written by George Williams. */ @@ -44,7 +44,7 @@ static void otv_MathConstants_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt i; @@ -66,7 +66,7 @@ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); } OTV_EXIT; @@ -84,11 +84,11 @@ static void otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, - OTV_Validator valid, + OTV_Validator otvalid, FT_Int isItalic ) { FT_Bytes p = table; - FT_UInt i, cnt, table_size ; + FT_UInt i, cnt, table_size; OTV_OPTIONAL_TABLE( Coverage ); OTV_OPTIONAL_TABLE( DeviceTableOffset ); @@ -108,7 +108,7 @@ table_size = 4 + 4 * cnt; OTV_SIZE_CHECK( Coverage ); - otv_Coverage_validate( table + Coverage, valid, cnt ); + otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); for ( i = 0; i < cnt; ++i ) { @@ -116,7 +116,7 @@ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); } OTV_EXIT; @@ -133,7 +133,7 @@ static void otv_MathKern_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt i, cnt, table_size; @@ -157,7 +157,7 @@ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); } /* One more Kerning value */ @@ -167,7 +167,7 @@ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); } OTV_EXIT; @@ -176,7 +176,7 @@ static void otv_MathKernInfo_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt i, j, cnt, table_size; @@ -196,7 +196,7 @@ table_size = 4 + 8 * cnt; OTV_SIZE_CHECK( Coverage ); - otv_Coverage_validate( table + Coverage, valid, cnt ); + otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); for ( i = 0; i < cnt; ++i ) { @@ -205,7 +205,7 @@ OTV_OPTIONAL_OFFSET( MKRecordOffset ); OTV_SIZE_CHECK( MKRecordOffset ); if ( MKRecordOffset ) - otv_MathKern_validate( table + MKRecordOffset, valid ); + otv_MathKern_validate( table + MKRecordOffset, otvalid ); } } @@ -223,7 +223,7 @@ static void otv_MathGlyphInfo_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; @@ -241,22 +241,22 @@ if ( MathItalicsCorrectionInfo ) otv_MathItalicsCorrectionInfo_validate( - table + MathItalicsCorrectionInfo, valid, TRUE ); + table + MathItalicsCorrectionInfo, otvalid, TRUE ); /* Italic correction and Top Accent Attachment have the same format */ if ( MathTopAccentAttachment ) otv_MathItalicsCorrectionInfo_validate( - table + MathTopAccentAttachment, valid, FALSE ); + table + MathTopAccentAttachment, otvalid, FALSE ); if ( ExtendedShapeCoverage ) { OTV_NAME_ENTER( "ExtendedShapeCoverage" ); - otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 ); + otv_Coverage_validate( table + ExtendedShapeCoverage, otvalid, -1 ); OTV_EXIT; } if ( MathKernInfo ) - otv_MathKernInfo_validate( table + MathKernInfo, valid ); + otv_MathKernInfo_validate( table + MathKernInfo, otvalid ); OTV_EXIT; } @@ -272,7 +272,7 @@ static void otv_GlyphAssembly_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt pcnt, table_size; @@ -294,7 +294,7 @@ OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); for ( i = 0; i < pcnt; ++i ) { @@ -302,7 +302,7 @@ gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) + if ( gid >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; p += 2*4; /* skip the Start, End, Full, and Flags fields */ } @@ -313,7 +313,7 @@ static void otv_MathGlyphConstruction_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt vcnt, table_size; @@ -338,14 +338,14 @@ gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) + if ( gid >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; p += 2; /* skip the size */ } OTV_SIZE_CHECK( GlyphAssembly ); if ( GlyphAssembly ) - otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); + otv_GlyphAssembly_validate( table+GlyphAssembly, otvalid ); /* OTV_EXIT; */ } @@ -353,7 +353,7 @@ static void otv_MathVariants_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt vcnt, hcnt, i, table_size; @@ -378,24 +378,24 @@ OTV_SIZE_CHECK( VCoverage ); if ( VCoverage ) - otv_Coverage_validate( table + VCoverage, valid, vcnt ); + otv_Coverage_validate( table + VCoverage, otvalid, (FT_Int)vcnt ); OTV_SIZE_CHECK( HCoverage ); if ( HCoverage ) - otv_Coverage_validate( table + HCoverage, valid, hcnt ); + otv_Coverage_validate( table + HCoverage, otvalid, (FT_Int)hcnt ); for ( i = 0; i < vcnt; ++i ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); - otv_MathGlyphConstruction_validate( table + Offset, valid ); + otv_MathGlyphConstruction_validate( table + Offset, otvalid ); } for ( i = 0; i < hcnt; ++i ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); - otv_MathGlyphConstruction_validate( table + Offset, valid ); + otv_MathGlyphConstruction_validate( table + Offset, otvalid ); } OTV_EXIT; @@ -410,20 +410,20 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->glyph_count */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_MATH_validate( FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; + FT_Bytes p = table; FT_UInt MathConstants, MathGlyphInfo, MathVariants; - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating MATH table\n" )); OTV_INIT; @@ -437,14 +437,14 @@ MathGlyphInfo = FT_NEXT_USHORT( p ); MathVariants = FT_NEXT_USHORT( p ); - valid->glyph_count = glyph_count; + otvalid->glyph_count = glyph_count; otv_MathConstants_validate( table + MathConstants, - valid ); + otvalid ); otv_MathGlyphInfo_validate( table + MathGlyphInfo, - valid ); + otvalid ); otv_MathVariants_validate ( table + MathVariants, - valid ); + otvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/src/otvalid/otvmod.c b/drivers/freetype/src/otvalid/otvmod.c index 37c6e869dd..972bd1baac 100644 --- a/drivers/freetype/src/otvalid/otvmod.c +++ b/drivers/freetype/src/otvalid/otvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's OpenType validation module implementation (body). */ /* */ -/* Copyright 2004-2008, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -240,7 +240,7 @@ static const FT_Service_OTvalidateRec otvalid_interface = { - otv_validate + otv_validate /* validate */ }; diff --git a/drivers/freetype/src/otvalid/otvmod.h b/drivers/freetype/src/otvalid/otvmod.h index f7e1550787..e464030ab0 100644 --- a/drivers/freetype/src/otvalid/otvmod.h +++ b/drivers/freetype/src/otvalid/otvmod.h @@ -5,7 +5,7 @@ /* FreeType's OpenType validation module implementation */ /* (specification). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __OTVMOD_H__ -#define __OTVMOD_H__ +#ifndef OTVMOD_H_ +#define OTVMOD_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVMOD_H__ */ +#endif /* OTVMOD_H_ */ /* END */ diff --git a/drivers/freetype/src/otvalid/rules.mk b/drivers/freetype/src/otvalid/rules.mk index 53bd41e5e7..077447fcb6 100644 --- a/drivers/freetype/src/otvalid/rules.mk +++ b/drivers/freetype/src/otvalid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004, 2007 by +# Copyright 2004-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ OTV_DIR := $(SRC_DIR)/otvalid # compilation flags for the driver # -OTV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(OTV_DIR)) +OTV_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(OTV_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # OTV driver sources (i.e., C files) diff --git a/drivers/freetype/src/pcf/Jamfile b/drivers/freetype/src/pcf/Jamfile index 752fcac2a1..9ebe6a2cbd 100644 --- a/drivers/freetype/src/pcf/Jamfile +++ b/drivers/freetype/src/pcf/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pcf Jamfile # -# Copyright 2001, 2003 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,10 @@ SubDir FT2_TOP $(FT2_SRC_DIR) pcf ; if $(FT2_MULTI) { - _sources = pcfdrivr pcfread pcfutil ; + _sources = pcfdrivr + pcfread + pcfutil + ; } else { diff --git a/drivers/freetype/src/pcf/pcf.h b/drivers/freetype/src/pcf/pcf.h index af0ffc3378..c726e5ec6b 100644 --- a/drivers/freetype/src/pcf/pcf.h +++ b/drivers/freetype/src/pcf/pcf.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCF_H__ -#define __PCF_H__ +#ifndef PCF_H_ +#define PCF_H_ #include <ft2build.h> @@ -148,9 +148,9 @@ FT_BEGIN_HEADER int nprops; PCF_Property properties; - FT_Long nmetrics; + FT_ULong nmetrics; PCF_Metric metrics; - FT_Long nencodings; + FT_ULong nencodings; PCF_Encoding encodings; FT_Short defaultChar; @@ -226,12 +226,13 @@ FT_BEGIN_HEADER #define GLYPHPADOPTIONS 4 /* I'm not sure about this */ FT_LOCAL( FT_Error ) - pcf_load_font( FT_Stream, - PCF_Face ); + pcf_load_font( FT_Stream stream, + PCF_Face face, + FT_Long face_index ); FT_END_HEADER -#endif /* __PCF_H__ */ +#endif /* PCF_H_ */ /* END */ diff --git a/drivers/freetype/src/pcf/pcfdrivr.c b/drivers/freetype/src/pcf/pcfdrivr.c index df25a645a0..0996d10793 100644 --- a/drivers/freetype/src/pcf/pcfdrivr.c +++ b/drivers/freetype/src/pcf/pcfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for pcf files - Copyright (C) 2000-2004, 2006-2011, 2013 by + Copyright (C) 2000-2004, 2006-2011, 2013, 2014 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -48,7 +48,7 @@ THE SOFTWARE. #define FT_COMPONENT trace_pcfread #include FT_SERVICE_BDF_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H /*************************************************************************/ @@ -64,7 +64,7 @@ THE SOFTWARE. typedef struct PCF_CMapRec_ { FT_CMapRec root; - FT_UInt num_encodings; + FT_ULong num_encodings; PCF_Encoding encodings; } PCF_CMapRec, *PCF_CMap; @@ -80,7 +80,7 @@ THE SOFTWARE. FT_UNUSED( init_data ); - cmap->num_encodings = (FT_UInt)face->nencodings; + cmap->num_encodings = face->nencodings; cmap->encodings = face->encodings; return FT_Err_Ok; @@ -104,7 +104,7 @@ THE SOFTWARE. { PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Encoding encodings = cmap->encodings; - FT_UInt min, max, mid; + FT_ULong min, max, mid; FT_UInt result = 0; @@ -117,7 +117,7 @@ THE SOFTWARE. mid = ( min + max ) >> 1; - code = encodings[mid].enc; + code = (FT_ULong)encodings[mid].enc; if ( charcode == code ) { @@ -141,7 +141,7 @@ THE SOFTWARE. { PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Encoding encodings = cmap->encodings; - FT_UInt min, max, mid; + FT_ULong min, max, mid; FT_ULong charcode = *acharcode + 1; FT_UInt result = 0; @@ -155,7 +155,7 @@ THE SOFTWARE. mid = ( min + max ) >> 1; - code = encodings[mid].enc; + code = (FT_ULong)encodings[mid].enc; if ( charcode == code ) { @@ -172,7 +172,7 @@ THE SOFTWARE. charcode = 0; if ( min < cmap->num_encodings ) { - charcode = encodings[min].enc; + charcode = (FT_ULong)encodings[min].enc; result = encodings[min].glyph + 1; } @@ -189,7 +189,7 @@ THE SOFTWARE. } - FT_CALLBACK_TABLE_DEF + static const FT_CMap_ClassRec pcf_cmap_class = { sizeof ( PCF_CMapRec ), @@ -218,25 +218,24 @@ THE SOFTWARE. FT_FREE( face->metrics ); /* free properties */ + if ( face->properties ) { - PCF_Property prop; - FT_Int i; + FT_Int i; - if ( face->properties ) + for ( i = 0; i < face->nprops; i++ ) { - for ( i = 0; i < face->nprops; i++ ) + PCF_Property prop = &face->properties[i]; + + + if ( prop ) { - prop = &face->properties[i]; - - if ( prop ) - { - FT_FREE( prop->name ); - if ( prop->isString ) - FT_FREE( prop->value.atom ); - } + FT_FREE( prop->name ); + if ( prop->isString ) + FT_FREE( prop->value.atom ); } } + FT_FREE( face->properties ); } @@ -264,16 +263,15 @@ THE SOFTWARE. FT_Parameter* params ) { PCF_Face face = (PCF_Face)pcfface; - FT_Error error = FT_Err_Ok; + FT_Error error; FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_TRACE2(( "PCF driver\n" )); - error = pcf_load_font( stream, face ); + error = pcf_load_font( stream, face, face_index ); if ( error ) { PCF_Face_Done( pcfface ); @@ -334,7 +332,7 @@ THE SOFTWARE. stream = pcfface->stream; - error = pcf_load_font( stream, face ); + error = pcf_load_font( stream, face, face_index ); if ( error ) goto Fail; @@ -347,6 +345,21 @@ THE SOFTWARE. #endif } + /* PCF cannot have multiple faces in a single font file. + * XXX: A non-zero face_index is already an invalid argument, but + * Type1, Type42 drivers have a convention to return + * an invalid argument error when the font could be + * opened by the specified driver. + */ + if ( face_index < 0 ) + goto Exit; + else if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) + { + FT_ERROR(( "PCF_Face_Init: invalid face index\n" )); + PCF_Face_Done( pcfface ); + return FT_THROW( Invalid_Argument ); + } + /* set up charmap */ { FT_String *charset_registry = face->charset_registry; @@ -420,9 +433,9 @@ THE SOFTWARE. FT_Select_Metrics( size->face, strike_index ); - size->metrics.ascender = accel->fontAscent << 6; - size->metrics.descender = -accel->fontDescent << 6; - size->metrics.max_advance = accel->maxbounds.characterWidth << 6; + size->metrics.ascender = accel->fontAscent * 64; + size->metrics.descender = -accel->fontDescent * 64; + size->metrics.max_advance = accel->maxbounds.characterWidth * 64; return FT_Err_Ok; } @@ -477,14 +490,20 @@ THE SOFTWARE. FT_Error error = FT_Err_Ok; FT_Bitmap* bitmap = &slot->bitmap; PCF_Metric metric; - FT_Offset bytes; + FT_ULong bytes; FT_UNUSED( load_flags ); - FT_TRACE4(( "load_glyph %d ---", glyph_index )); + FT_TRACE1(( "PCF_Glyph_Load: glyph index %d\n", glyph_index )); - if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs ) + if ( !face ) + { + error = FT_THROW( Invalid_Face_Handle ); + goto Exit; + } + + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -497,8 +516,10 @@ THE SOFTWARE. metric = face->metrics + glyph_index; - bitmap->rows = metric->ascent + metric->descent; - bitmap->width = metric->rightSideBearing - metric->leftSideBearing; + bitmap->rows = (unsigned int)( metric->ascent + + metric->descent ); + bitmap->width = (unsigned int)( metric->rightSideBearing - + metric->leftSideBearing ); bitmap->num_grays = 1; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; @@ -510,19 +531,19 @@ THE SOFTWARE. switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) { case 1: - bitmap->pitch = ( bitmap->width + 7 ) >> 3; + bitmap->pitch = (int)( ( bitmap->width + 7 ) >> 3 ); break; case 2: - bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; + bitmap->pitch = (int)( ( ( bitmap->width + 15 ) >> 4 ) << 1 ); break; case 4: - bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; + bitmap->pitch = (int)( ( ( bitmap->width + 31 ) >> 5 ) << 2 ); break; case 8: - bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; + bitmap->pitch = (int)( ( ( bitmap->width + 63 ) >> 6 ) << 3 ); break; default: @@ -530,7 +551,7 @@ THE SOFTWARE. } /* XXX: to do: are there cases that need repadding the bitmap? */ - bytes = bitmap->pitch * bitmap->rows; + bytes = (FT_ULong)bitmap->pitch * bitmap->rows; error = ft_glyphslot_alloc_bitmap( slot, (FT_ULong)bytes ); if ( error ) @@ -565,18 +586,16 @@ THE SOFTWARE. slot->bitmap_left = metric->leftSideBearing; slot->bitmap_top = metric->ascent; - slot->metrics.horiAdvance = metric->characterWidth << 6; - slot->metrics.horiBearingX = metric->leftSideBearing << 6; - slot->metrics.horiBearingY = metric->ascent << 6; - slot->metrics.width = ( metric->rightSideBearing - - metric->leftSideBearing ) << 6; - slot->metrics.height = bitmap->rows << 6; + slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 ); + slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 ); + slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 ); + slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing - + metric->leftSideBearing ) * 64 ); + slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); ft_synthesize_vertical_metrics( &slot->metrics, ( face->accel.fontAscent + - face->accel.fontDescent ) << 6 ); - - FT_TRACE4(( " --- ok\n" )); + face->accel.fontDescent ) * 64 ); Exit: return error; @@ -640,8 +659,8 @@ THE SOFTWARE. static const FT_Service_BDFRec pcf_service_bdf = { - (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, - (FT_BDF_GetPropertyFunc) pcf_get_bdf_property + (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) pcf_get_bdf_property /* get_property */ }; @@ -653,8 +672,8 @@ THE SOFTWARE. static const FT_ServiceDescRec pcf_services[] = { - { FT_SERVICE_ID_BDF, &pcf_service_bdf }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, + { FT_SERVICE_ID_BDF, &pcf_service_bdf }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PCF }, { NULL, NULL } }; @@ -681,32 +700,32 @@ THE SOFTWARE. 0x10000L, 0x20000L, - 0, + 0, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - pcf_driver_requester + 0, /* FT_Module_Constructor module_init */ + 0, /* FT_Module_Destructor module_done */ + pcf_driver_requester /* FT_Module_Requester get_interface */ }, sizeof ( PCF_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - PCF_Face_Init, - PCF_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + PCF_Face_Init, /* FT_Face_InitFunc init_face */ + PCF_Face_Done, /* FT_Face_DoneFunc done_face */ + 0, /* FT_Size_InitFunc init_size */ + 0, /* FT_Size_DoneFunc done_size */ + 0, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - PCF_Glyph_Load, + PCF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - PCF_Size_Request, - PCF_Size_Select + PCF_Size_Request, /* FT_Size_RequestFunc request_size */ + PCF_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/src/pcf/pcfdrivr.h b/drivers/freetype/src/pcf/pcfdrivr.h index 54614951b5..29d30497cd 100644 --- a/drivers/freetype/src/pcf/pcfdrivr.h +++ b/drivers/freetype/src/pcf/pcfdrivr.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFDRIVR_H__ -#define __PCFDRIVR_H__ +#ifndef PCFDRIVR_H_ +#define PCFDRIVR_H_ #include <ft2build.h> #include FT_INTERNAL_DRIVER_H @@ -42,7 +42,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFDRIVR_H__ */ +#endif /* PCFDRIVR_H_ */ /* END */ diff --git a/drivers/freetype/src/pcf/pcferror.h b/drivers/freetype/src/pcf/pcferror.h index e51fff8ea6..add8ef2230 100644 --- a/drivers/freetype/src/pcf/pcferror.h +++ b/drivers/freetype/src/pcf/pcferror.h @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PCFERROR_H__ -#define __PCFERROR_H__ +#ifndef PCFERROR_H_ +#define PCFERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PCF_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PCFERROR_H__ */ +#endif /* PCFERROR_H_ */ /* END */ diff --git a/drivers/freetype/src/pcf/pcfread.c b/drivers/freetype/src/pcf/pcfread.c index 3c1bb7dfa2..a86b45d6bf 100644 --- a/drivers/freetype/src/pcf/pcfread.c +++ b/drivers/freetype/src/pcf/pcfread.c @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000-2010, 2012, 2013 by + Copyright 2000-2010, 2012-2014 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -78,7 +78,7 @@ THE SOFTWARE. FT_FRAME_START( 16 ), FT_FRAME_ULONG_LE( type ), FT_FRAME_ULONG_LE( format ), - FT_FRAME_ULONG_LE( size ), + FT_FRAME_ULONG_LE( size ), /* rounded up to a multiple of 4 */ FT_FRAME_ULONG_LE( offset ), FT_FRAME_END }; @@ -95,16 +95,29 @@ THE SOFTWARE. FT_Memory memory = FT_FACE( face )->memory; FT_UInt n; + FT_ULong size; - if ( FT_STREAM_SEEK ( 0 ) || - FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) + + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ_FIELDS( pcf_toc_header, toc ) ) return FT_THROW( Cannot_Open_Resource ); - if ( toc->version != PCF_FILE_VERSION || - toc->count > FT_ARRAY_MAX( face->toc.tables ) || - toc->count == 0 ) + if ( toc->version != PCF_FILE_VERSION || + toc->count == 0 ) + return FT_THROW( Invalid_File_Format ); + + if ( stream->size < 16 ) return FT_THROW( Invalid_File_Format ); + /* we need 16 bytes per TOC entry */ + if ( toc->count > stream->size >> 4 ) + { + FT_TRACE0(( "pcf_read_TOC: adjusting number of tables" + " (from %d to %d)\n", + toc->count, stream->size >> 4 )); + toc->count = stream->size >> 4; + } + if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) return FT_THROW( Out_Of_Memory ); @@ -144,13 +157,62 @@ THE SOFTWARE. if ( ( tables[i].size > tables[i + 1].offset ) || ( tables[i].offset > tables[i + 1].offset - tables[i].size ) ) - return FT_THROW( Invalid_Offset ); + { + error = FT_THROW( Invalid_Offset ); + goto Exit; + } } if ( !have_change ) break; } + /* + * We now check whether the `size' and `offset' values are reasonable: + * `offset' + `size' must not exceed the stream size. + * + * Note, however, that X11's `pcfWriteFont' routine (used by the + * `bdftopcf' program to create PDF font files) has two special + * features. + * + * - It always assigns the accelerator table a size of 100 bytes in the + * TOC, regardless of its real size, which can vary between 34 and 72 + * bytes. + * + * - Due to the way the routine is designed, it ships out the last font + * table with its real size, ignoring the TOC's size value. Since + * the TOC size values are always rounded up to a multiple of 4, the + * difference can be up to three bytes for all tables except the + * accelerator table, for which the difference can be as large as 66 + * bytes. + * + */ + + tables = face->toc.tables; + size = stream->size; + + for ( n = 0; n < toc->count - 1; n++ ) + { + /* we need two checks to avoid overflow */ + if ( ( tables->size > size ) || + ( tables->offset > size - tables->size ) ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + tables++; + } + + /* only check `tables->offset' for last table element ... */ + if ( ( tables->offset > size ) ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + /* ... and adjust `tables->size' to the real value if necessary */ + if ( tables->size > size - tables->offset ) + tables->size = size - tables->offset; + #ifdef FT_DEBUG_LEVEL_TRACE { @@ -380,7 +442,7 @@ THE SOFTWARE. int i; - for ( i = 0 ; i < face->nprops && !found; i++ ) + for ( i = 0; i < face->nprops && !found; i++ ) { if ( !ft_strcmp( properties[i].name, prop ) ) found = 1; @@ -397,14 +459,14 @@ THE SOFTWARE. pcf_get_properties( FT_Stream stream, PCF_Face face ) { - PCF_ParseProperty props = 0; + PCF_ParseProperty props = NULL; PCF_Property properties = NULL; FT_ULong nprops, i; FT_ULong format, size; FT_Error error; FT_Memory memory = FT_FACE( face )->memory; FT_ULong string_size; - FT_String* strings = 0; + FT_String* strings = NULL; error = pcf_seek_to_table_type( stream, @@ -434,9 +496,9 @@ THE SOFTWARE. goto Bail; FT_TRACE4(( " nprop = %d (truncate %d props)\n", - (int)nprops, nprops - (int)nprops )); + (int)nprops, nprops - (FT_ULong)(int)nprops )); - nprops = (int)nprops; + nprops = (FT_ULong)(int)nprops; /* rough estimate */ if ( nprops > size / PCF_PROPERTY_SIZE ) @@ -569,7 +631,7 @@ THE SOFTWARE. FT_Error error; FT_Memory memory = FT_FACE( face )->memory; FT_ULong format, size; - PCF_Metric metrics = 0; + PCF_Metric metrics = NULL; FT_ULong nmetrics, i; @@ -631,24 +693,40 @@ THE SOFTWARE. return FT_THROW( Out_Of_Memory ); metrics = face->metrics; - for ( i = 0; i < nmetrics; i++ ) + for ( i = 0; i < nmetrics; i++, metrics++ ) { - error = pcf_get_metric( stream, format, metrics + i ); + error = pcf_get_metric( stream, format, metrics ); - metrics[i].bits = 0; + metrics->bits = 0; FT_TRACE5(( " idx %d: width=%d, " "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", i, - ( metrics + i )->characterWidth, - ( metrics + i )->leftSideBearing, - ( metrics + i )->rightSideBearing, - ( metrics + i )->ascent, - ( metrics + i )->descent, - ( metrics + i )->attributes )); + metrics->characterWidth, + metrics->leftSideBearing, + metrics->rightSideBearing, + metrics->ascent, + metrics->descent, + metrics->attributes )); if ( error ) break; + + /* sanity checks -- those values are used in `PCF_Glyph_Load' to */ + /* compute a glyph's bitmap dimensions, thus setting them to zero in */ + /* case of an error disables this particular glyph only */ + if ( metrics->rightSideBearing < metrics->leftSideBearing || + metrics->ascent + metrics->descent < 0 ) + { + metrics->characterWidth = 0; + metrics->leftSideBearing = 0; + metrics->rightSideBearing = 0; + metrics->ascent = 0; + metrics->descent = 0; + + FT_TRACE0(( "pcf_get_metrics:" + " invalid metrics for glyph %d\n", i )); + } } if ( error ) @@ -699,8 +777,7 @@ THE SOFTWARE. FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); - /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ - if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) + if ( nbitmaps != face->nmetrics ) return FT_THROW( Invalid_File_Format ); if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) @@ -728,9 +805,10 @@ THE SOFTWARE. if ( error ) goto Bail; - sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; + sizebitmaps = (FT_ULong)bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; - FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] )); + FT_TRACE4(( " padding %d implies a size of %ld\n", + i, bitmapSizes[i] )); } FT_TRACE4(( " %d bitmaps, padding index %ld\n", @@ -750,7 +828,7 @@ THE SOFTWARE. " invalid offset to bitmap data of glyph %d\n", i )); } else - face->metrics[i].bits = stream->pos + offsets[i]; + face->metrics[i].bits = stream->pos + (FT_ULong)offsets[i]; } face->bitmapsFormat = format; @@ -770,8 +848,10 @@ THE SOFTWARE. FT_ULong format, size; int firstCol, lastCol; int firstRow, lastRow; - int nencoding, encodingOffset; - int i, j, k; + FT_ULong nencoding; + FT_UShort encodingOffset; + int i, j; + FT_ULong k; PCF_Encoding encoding = NULL; @@ -812,12 +892,22 @@ THE SOFTWARE. if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return FT_THROW( Invalid_File_Format ); + /* sanity checks */ + if ( firstCol < 0 || + firstCol > lastCol || + lastCol > 0xFF || + firstRow < 0 || + firstRow > lastRow || + lastRow > 0xFF ) + return FT_THROW( Invalid_Table ); + FT_TRACE4(( "pdf_get_encodings:\n" )); FT_TRACE4(( " firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", firstCol, lastCol, firstRow, lastRow )); - nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 ); + nencoding = (FT_ULong)( lastCol - firstCol + 1 ) * + (FT_ULong)( lastRow - firstRow + 1 ); if ( FT_NEW_ARRAY( encoding, nencoding ) ) return FT_THROW( Out_Of_Memory ); @@ -831,15 +921,19 @@ THE SOFTWARE. { for ( j = firstCol; j <= lastCol; j++ ) { + /* X11's reference implementation uses the equivalent to */ + /* `FT_GET_SHORT', however PCF fonts with more than 32768 */ + /* characters (e.g. `unifont.pcf') clearly show that an */ + /* unsigned value is needed. */ if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - encodingOffset = FT_GET_SHORT(); + encodingOffset = FT_GET_USHORT(); else - encodingOffset = FT_GET_SHORT_LE(); + encodingOffset = FT_GET_USHORT_LE(); - if ( encodingOffset != -1 ) + if ( encodingOffset != 0xFFFFU ) { encoding[k].enc = i * 256 + j; - encoding[k].glyph = (FT_Short)encodingOffset; + encoding[k].glyph = encodingOffset; FT_TRACE5(( " code %d (0x%04X): idx %d\n", encoding[k].enc, encoding[k].enc, encoding[k].glyph )); @@ -1094,9 +1188,11 @@ THE SOFTWARE. FT_LOCAL_DEF( FT_Error ) pcf_load_font( FT_Stream stream, - PCF_Face face ) + PCF_Face face, + FT_Long face_index ) { - FT_Error error = FT_Err_Ok; + FT_Face root = FT_FACE( face ); + FT_Error error; FT_Memory memory = FT_FACE( face )->memory; FT_Bool hasBDFAccelerators; @@ -1105,6 +1201,13 @@ THE SOFTWARE. if ( error ) goto Exit; + root->num_faces = 1; + root->face_index = 0; + + /* If we are performing a simple font format check, exit immediately. */ + if ( face_index < 0 ) + return FT_Err_Ok; + error = pcf_get_properties( stream, face ); if ( error ) goto Exit; @@ -1147,15 +1250,12 @@ THE SOFTWARE. /* now construct the face object */ { - FT_Face root = FT_FACE( face ); PCF_Property prop; - root->num_faces = 1; - root->face_index = 0; - root->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_FAST_GLYPHS; + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -1179,7 +1279,7 @@ THE SOFTWARE. * * This implies bumping the number of `available' glyphs by 1. */ - root->num_glyphs = face->nmetrics + 1; + root->num_glyphs = (FT_Long)( face->nmetrics + 1 ); root->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) @@ -1192,51 +1292,91 @@ THE SOFTWARE. FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + /* for simplicity, we take absolute values of integer properties */ + #if 0 bsize->height = face->accel.maxbounds.ascent << 6; #endif - bsize->height = (FT_Short)( face->accel.fontAscent + - face->accel.fontDescent ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( face->accel.fontAscent + face->accel.fontDescent < 0 ) + FT_TRACE0(( "pcf_load_font: negative height\n" )); +#endif + bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + + face->accel.fontDescent ) ); prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop ) - bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative average width\n" )); +#endif + bsize->width = FT_ABS( (FT_Short)( ( prop->value.l ) + 5 ) / 10 ); + } else - bsize->width = (FT_Short)( bsize->height * 2/3 ); + bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative point size\n" )); +#endif /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = - (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); + bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), + 64 * 7200, + 72270L ); + } prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.l << 6; + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative pixel size\n" )); +#endif + bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; + } prop = pcf_find_property( face, "RESOLUTION_X" ); if ( prop ) - resolution_x = (FT_Short)prop->value.l; + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative X resolution\n" )); +#endif + resolution_x = FT_ABS( (FT_Short)prop->value.l ); + } prop = pcf_find_property( face, "RESOLUTION_Y" ); if ( prop ) - resolution_y = (FT_Short)prop->value.l; + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative Y resolution\n" )); +#endif + resolution_y = FT_ABS( (FT_Short)prop->value.l ); + } if ( bsize->y_ppem == 0 ) { bsize->y_ppem = bsize->size; if ( resolution_y ) - bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + bsize->y_ppem = FT_MulDiv( bsize->y_ppem, resolution_y, 72 ); } if ( resolution_x && resolution_y ) - bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + bsize->x_ppem = FT_MulDiv( bsize->y_ppem, + resolution_x, + resolution_y ); else bsize->x_ppem = bsize->y_ppem; } /* set up charset */ { - PCF_Property charset_registry = 0, charset_encoding = 0; + PCF_Property charset_registry, charset_encoding; charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); diff --git a/drivers/freetype/src/pcf/pcfread.h b/drivers/freetype/src/pcf/pcfread.h index c9524f1346..bed30e5030 100644 --- a/drivers/freetype/src/pcf/pcfread.h +++ b/drivers/freetype/src/pcf/pcfread.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFREAD_H__ -#define __PCFREAD_H__ +#ifndef PCFREAD_H_ +#define PCFREAD_H_ #include <ft2build.h> @@ -39,7 +39,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFREAD_H__ */ +#endif /* PCFREAD_H_ */ /* END */ diff --git a/drivers/freetype/src/pcf/pcfutil.c b/drivers/freetype/src/pcf/pcfutil.c index b91274f935..0451ee8def 100644 --- a/drivers/freetype/src/pcf/pcfutil.c +++ b/drivers/freetype/src/pcf/pcfutil.c @@ -66,11 +66,11 @@ in this Software without prior written authorization from The Open Group. TwoByteSwap( unsigned char* buf, size_t nbytes ) { - unsigned char c; - - for ( ; nbytes >= 2; nbytes -= 2, buf += 2 ) { + unsigned char c; + + c = buf[0]; buf[0] = buf[1]; buf[1] = c; @@ -85,11 +85,11 @@ in this Software without prior written authorization from The Open Group. FourByteSwap( unsigned char* buf, size_t nbytes ) { - unsigned char c; - - for ( ; nbytes >= 4; nbytes -= 4, buf += 4 ) { + unsigned char c; + + c = buf[0]; buf[0] = buf[3]; buf[3] = c; diff --git a/drivers/freetype/src/pcf/pcfutil.h b/drivers/freetype/src/pcf/pcfutil.h index ce10fb541d..be986e756b 100644 --- a/drivers/freetype/src/pcf/pcfutil.h +++ b/drivers/freetype/src/pcf/pcfutil.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFUTIL_H__ -#define __PCFUTIL_H__ +#ifndef PCFUTIL_H_ +#define PCFUTIL_H_ #include <ft2build.h> @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFUTIL_H__ */ +#endif /* PCFUTIL_H_ */ /* END */ diff --git a/drivers/freetype/src/pcf/rules.mk b/drivers/freetype/src/pcf/rules.mk index 78641528fa..1b55daf4f4 100644 --- a/drivers/freetype/src/pcf/rules.mk +++ b/drivers/freetype/src/pcf/rules.mk @@ -30,7 +30,10 @@ PCF_DIR := $(SRC_DIR)/pcf -PCF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) +PCF_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # pcf driver sources (i.e., C files) diff --git a/drivers/freetype/src/pfr/Jamfile b/drivers/freetype/src/pfr/Jamfile index 9e2f2b8d05..a5b294b79a 100644 --- a/drivers/freetype/src/pfr/Jamfile +++ b/drivers/freetype/src/pfr/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pfr Jamfile # -# Copyright 2002 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,13 @@ SubDir FT2_TOP $(FT2_SRC_DIR) pfr ; if $(FT2_MULTI) { - _sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ; + _sources = pfrcmap + pfrdrivr + pfrgload + pfrload + pfrobjs + pfrsbit + ; } else { diff --git a/drivers/freetype/src/pfr/module.mk b/drivers/freetype/src/pfr/module.mk index 8d1d28a9d2..bf7808c72f 100644 --- a/drivers/freetype/src/pfr/module.mk +++ b/drivers/freetype/src/pfr/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2006 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/pfr/pfr.c b/drivers/freetype/src/pfr/pfr.c index eb2c4edb7e..1a433960a5 100644 --- a/drivers/freetype/src/pfr/pfr.c +++ b/drivers/freetype/src/pfr/pfr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver component. */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/pfr/pfrcmap.c b/drivers/freetype/src/pfr/pfrcmap.c index 740c433d66..a1439c2e9f 100644 --- a/drivers/freetype/src/pfr/pfrcmap.c +++ b/drivers/freetype/src/pfr/pfrcmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR cmap handling (body). */ /* */ -/* Copyright 2002, 2007, 2009, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,11 +25,14 @@ FT_CALLBACK_DEF( FT_Error ) - pfr_cmap_init( PFR_CMap cmap ) + pfr_cmap_init( PFR_CMap cmap, + FT_Pointer pointer ) { FT_Error error = FT_Err_Ok; PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); + FT_UNUSED( pointer ); + cmap->num_chars = face->phy_font.num_chars; cmap->chars = face->phy_font.chars; @@ -67,14 +70,16 @@ pfr_cmap_char_index( PFR_CMap cmap, FT_UInt32 char_code ) { - FT_UInt min = 0; - FT_UInt max = cmap->num_chars; - FT_UInt mid; - PFR_Char gchar; + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; while ( min < max ) { + PFR_Char gchar; + FT_UInt mid; + + mid = min + ( max - min ) / 2; gchar = cmap->chars + mid; @@ -125,7 +130,7 @@ } if ( gchar->char_code < char_code ) - min = mid+1; + min = mid + 1; else max = mid; } diff --git a/drivers/freetype/src/pfr/pfrcmap.h b/drivers/freetype/src/pfr/pfrcmap.h index a626953054..4a8a4d0a67 100644 --- a/drivers/freetype/src/pfr/pfrcmap.h +++ b/drivers/freetype/src/pfr/pfrcmap.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR cmap handling (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRCMAP_H__ -#define __PFRCMAP_H__ +#ifndef PFRCMAP_H_ +#define PFRCMAP_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRCMAP_H__ */ +#endif /* PFRCMAP_H_ */ /* END */ diff --git a/drivers/freetype/src/pfr/pfrdrivr.c b/drivers/freetype/src/pfr/pfrdrivr.c index 4c43947bf4..b81c15e560 100644 --- a/drivers/freetype/src/pfr/pfrdrivr.c +++ b/drivers/freetype/src/pfr/pfrdrivr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver interface (body). */ /* */ -/* Copyright 2002-2004, 2006, 2008, 2010, 2011, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_SERVICE_PFR_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include "pfrdrivr.h" #include "pfrobjs.h" @@ -37,18 +37,20 @@ PFR_PhyFont phys = &face->phy_font; - pfr_face_get_kerning( pfrface, left, right, avector ); + (void)pfr_face_get_kerning( pfrface, left, right, avector ); /* convert from metrics to outline units when necessary */ if ( phys->outline_resolution != phys->metrics_resolution ) { if ( avector->x != 0 ) - avector->x = FT_MulDiv( avector->x, phys->outline_resolution, - phys->metrics_resolution ); + avector->x = FT_MulDiv( avector->x, + (FT_Long)phys->outline_resolution, + (FT_Long)phys->metrics_resolution ); if ( avector->y != 0 ) - avector->y = FT_MulDiv( avector->x, phys->outline_resolution, - phys->metrics_resolution ); + avector->y = FT_MulDiv( avector->y, + (FT_Long)phys->outline_resolution, + (FT_Long)phys->metrics_resolution ); } return FT_Err_Ok; @@ -118,10 +120,10 @@ if ( size ) { x_scale = FT_DivFix( size->metrics.x_ppem << 6, - phys->metrics_resolution ); + (FT_Long)phys->metrics_resolution ); y_scale = FT_DivFix( size->metrics.y_ppem << 6, - phys->metrics_resolution ); + (FT_Long)phys->metrics_resolution ); } if ( ametrics_x_scale ) @@ -134,12 +136,12 @@ } - FT_CALLBACK_TABLE_DEF + static const FT_Service_PfrMetricsRec pfr_metrics_service_rec = { - pfr_get_metrics, - pfr_face_get_kerning, - pfr_get_advance + pfr_get_metrics, /* get_metrics */ + pfr_face_get_kerning, /* get_kerning */ + pfr_get_advance /* get_advance */ }; @@ -151,7 +153,7 @@ static const FT_ServiceDescRec pfr_services[] = { { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PFR }, { NULL, NULL } }; @@ -179,31 +181,32 @@ 0x10000L, 0x20000L, - NULL, + 0, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - pfr_get_service + 0, /* FT_Module_Constructor module_init */ + 0, /* FT_Module_Destructor module_done */ + pfr_get_service /* FT_Module_Requester get_interface */ }, sizeof ( PFR_FaceRec ), sizeof ( PFR_SizeRec ), sizeof ( PFR_SlotRec ), - pfr_face_init, - pfr_face_done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - pfr_slot_init, - pfr_slot_done, + pfr_face_init, /* FT_Face_InitFunc init_face */ + pfr_face_done, /* FT_Face_DoneFunc done_face */ + 0, /* FT_Size_InitFunc init_size */ + 0, /* FT_Size_DoneFunc done_size */ + pfr_slot_init, /* FT_Slot_InitFunc init_slot */ + pfr_slot_done, /* FT_Slot_DoneFunc done_slot */ + + pfr_slot_load, /* FT_Slot_LoadFunc load_glyph */ - pfr_slot_load, + pfr_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - pfr_get_kerning, - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ - 0, /* FT_Size_RequestFunc */ - 0, /* FT_Size_SelectFunc */ + 0, /* FT_Size_RequestFunc request_size */ + 0, /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/src/pfr/pfrdrivr.h b/drivers/freetype/src/pfr/pfrdrivr.h index 75f86c5cdd..32b2d9eab3 100644 --- a/drivers/freetype/src/pfr/pfrdrivr.h +++ b/drivers/freetype/src/pfr/pfrdrivr.h @@ -4,7 +4,7 @@ /* */ /* High-level Type PFR driver interface (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRDRIVR_H__ -#define __PFRDRIVR_H__ +#ifndef PFRDRIVR_H_ +#define PFRDRIVR_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRDRIVR_H__ */ +#endif /* PFRDRIVR_H_ */ /* END */ diff --git a/drivers/freetype/src/pfr/pfrerror.h b/drivers/freetype/src/pfr/pfrerror.h index 94dc8c5e1c..9305f8fb58 100644 --- a/drivers/freetype/src/pfr/pfrerror.h +++ b/drivers/freetype/src/pfr/pfrerror.h @@ -4,7 +4,7 @@ /* */ /* PFR error codes (specification only). */ /* */ -/* Copyright 2002, 2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PFRERROR_H__ -#define __PFRERROR_H__ +#ifndef PFRERROR_H_ +#define PFRERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PFR_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PFRERROR_H__ */ +#endif /* PFRERROR_H_ */ /* END */ diff --git a/drivers/freetype/src/pfr/pfrgload.c b/drivers/freetype/src/pfr/pfrgload.c index 88b4d66a13..f9cd1f63bb 100644 --- a/drivers/freetype/src/pfr/pfrgload.c +++ b/drivers/freetype/src/pfr/pfrgload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR glyph loader (body). */ /* */ -/* Copyright 2002, 2003, 2005, 2007, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -92,8 +92,8 @@ if ( outline->n_contours > 0 ) first = outline->contours[outline->n_contours - 1]; - /* if the last point falls on the same location than the first one */ - /* we need to delete it */ + /* if the last point falls on the same location as the first one */ + /* we need to delete it */ if ( last > first ) { FT_Vector* p1 = outline->points + first; @@ -143,7 +143,7 @@ error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 ); if ( !error ) { - FT_UInt n = outline->n_points; + FT_Int n = outline->n_points; outline->points[n] = *to; @@ -215,8 +215,10 @@ /* check that there is space for a new contour and a new point */ error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 ); if ( !error ) + { /* add new start point */ error = pfr_glyph_line_to( glyph, to ); + } return error; } @@ -304,8 +306,8 @@ glyph->y_control = glyph->x_control + x_count; - mask = 0; - x = 0; + mask = 0; + x = 0; for ( i = 0; i < count; i++ ) { @@ -331,10 +333,10 @@ mask >>= 1; } - /* XXX: for now we ignore the secondary stroke and edge definitions */ - /* since we don't want to support native PFR hinting */ - /* */ - if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + /* XXX: we ignore the secondary stroke and edge definitions */ + /* since we don't support native PFR hinting */ + /* */ + if ( flags & PFR_GLYPH_SINGLE_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); if ( error ) @@ -366,27 +368,27 @@ switch ( format >> 4 ) { - case 0: /* end glyph */ + case 0: /* end glyph */ FT_TRACE6(( "- end glyph" )); args_count = 0; break; - case 1: /* general line operation */ + case 1: /* general line operation */ FT_TRACE6(( "- general line" )); goto Line1; - case 4: /* move to inside contour */ + case 4: /* move to inside contour */ FT_TRACE6(( "- move to inside" )); goto Line1; - case 5: /* move to outside contour */ + case 5: /* move to outside contour */ FT_TRACE6(( "- move to outside" )); Line1: args_format = format_low; args_count = 1; break; - case 2: /* horizontal line to */ + case 2: /* horizontal line to */ FT_TRACE6(( "- horizontal line to cx.%d", format_low )); if ( format_low >= x_count ) goto Failure; @@ -396,7 +398,7 @@ args_count = 0; break; - case 3: /* vertical line to */ + case 3: /* vertical line to */ FT_TRACE6(( "- vertical line to cy.%d", format_low )); if ( format_low >= y_count ) goto Failure; @@ -406,19 +408,19 @@ args_count = 0; break; - case 6: /* horizontal to vertical curve */ + case 6: /* horizontal to vertical curve */ FT_TRACE6(( "- hv curve " )); args_format = 0xB8E; args_count = 3; break; - case 7: /* vertical to horizontal curve */ + case 7: /* vertical to horizontal curve */ FT_TRACE6(( "- vh curve" )); args_format = 0xE2B; args_count = 3; break; - default: /* general curve to */ + default: /* general curve to */ FT_TRACE6(( "- general curve" )); args_count = 4; args_format = format_low; @@ -439,14 +441,14 @@ { case 0: /* 8-bit index */ PFR_CHECK( 1 ); - idx = PFR_NEXT_BYTE( p ); + idx = PFR_NEXT_BYTE( p ); if ( idx >= x_count ) goto Failure; cur->x = glyph->x_control[idx]; FT_TRACE7(( " cx#%d", idx )); break; - case 1: /* 16-bit value */ + case 1: /* 16-bit absolute value */ PFR_CHECK( 2 ); cur->x = PFR_NEXT_SHORT( p ); FT_TRACE7(( " x.%d", cur->x )); @@ -516,22 +518,22 @@ /* */ switch ( format >> 4 ) { - case 0: /* end glyph => EXIT */ + case 0: /* end glyph => EXIT */ pfr_glyph_end( glyph ); goto Exit; - case 1: /* line operations */ + case 1: /* line operations */ case 2: case 3: error = pfr_glyph_line_to( glyph, pos ); goto Test_Error; - case 4: /* move to inside contour */ - case 5: /* move to outside contour */ + case 4: /* move to inside contour */ + case 5: /* move to outside contour */ error = pfr_glyph_move_to( glyph, pos ); goto Test_Error; - default: /* curve operations */ + default: /* curve operations */ error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); Test_Error: /* test error condition */ @@ -577,10 +579,11 @@ /* ignore extra items when present */ /* */ - if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + if ( flags & PFR_GLYPH_COMPOUND_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); - if (error) goto Exit; + if ( error ) + goto Exit; } /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ @@ -632,14 +635,14 @@ if ( format & PFR_SUBGLYPH_XSCALE ) { PFR_CHECK( 2 ); - subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; + subglyph->x_scale = PFR_NEXT_SHORT( p ) * 16; } subglyph->y_scale = 0x10000L; if ( format & PFR_SUBGLYPH_YSCALE ) { PFR_CHECK( 2 ); - subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; + subglyph->y_scale = PFR_NEXT_SHORT( p ) * 16; } /* read offset */ @@ -693,7 +696,7 @@ if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) { PFR_CHECK( 3 ); - subglyph->gps_offset = PFR_NEXT_LONG( p ); + subglyph->gps_offset = PFR_NEXT_ULONG( p ); } else { @@ -736,7 +739,7 @@ if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) { - FT_Int n, old_count, count; + FT_UInt n, old_count, count; FT_GlyphLoader loader = glyph->loader; FT_Outline* base = &loader->base.outline; @@ -763,7 +766,7 @@ PFR_SubGlyph subglyph; - FT_TRACE4(( "subglyph %d:\n", n )); + FT_TRACE4(( " subglyph %d:\n", n )); subglyph = glyph->subs + old_count + n; old_points = base->n_points; diff --git a/drivers/freetype/src/pfr/pfrgload.h b/drivers/freetype/src/pfr/pfrgload.h index 7cc7a8702a..908d4378a4 100644 --- a/drivers/freetype/src/pfr/pfrgload.h +++ b/drivers/freetype/src/pfr/pfrgload.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR glyph loader (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRGLOAD_H__ -#define __PFRGLOAD_H__ +#ifndef PFRGLOAD_H_ +#define PFRGLOAD_H_ #include "pfrtypes.h" @@ -43,7 +43,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRGLOAD_H__ */ +#endif /* PFRGLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/pfr/pfrload.c b/drivers/freetype/src/pfr/pfrload.c index c19fceb1ee..e509e70b5d 100644 --- a/drivers/freetype/src/pfr/pfrload.c +++ b/drivers/freetype/src/pfr/pfrload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (body). */ /* */ -/* Copyright 2002-2005, 2007, 2009, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,93 @@ #define FT_COMPONENT trace_pfr + /* + * The overall structure of a PFR file is as follows. + * + * PFR header + * 58 bytes (contains nPhysFonts) + * + * Logical font directory (size at most 2^16 bytes) + * 2 bytes (nLogFonts) + * + nLogFonts * 5 bytes + * + * ==> nLogFonts <= 13106 + * + * Logical font section (size at most 2^24 bytes) + * nLogFonts * logFontRecord + * + * logFontRecord (size at most 2^16 bytes) + * 12 bytes (fontMatrix) + * + 1 byte (flags) + * + 0-5 bytes (depending on `flags') + * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') + * + 5 bytes (physical font info) + * + 0-1 bytes (depending on PFR header) + * + * ==> minimum size 18 bytes + * + * Physical font section (size at most 2^24 bytes) + * nPhysFonts * (physFontRecord + * + nBitmapSizes * nBmapChars * bmapCharRecord) + * + * physFontRecord (size at most 2^24 bytes) + * 14 bytes (font info) + * + 1 byte (flags) + * + 0-2 (depending on `flags') + * + 0-? (structure too complicated to be shown here; depending on + * `flags'; contains `nBitmapSizes' and `nBmapChars') + * + 3 bytes (nAuxBytes) + * + nAuxBytes + * + 1 byte (nBlueValues) + * + 2 * nBlueValues + * + 6 bytes (hinting data) + * + 2 bytes (nCharacters) + * + nCharacters * (4-10 bytes) (depending on `flags') + * + * ==> minimum size 27 bytes + * + * bmapCharRecord + * 4-7 bytes + * + * Glyph program strings (three possible types: simpleGps, compoundGps, + * and bitmapGps; size at most 2^24 bytes) + * simpleGps (size at most 2^16 bytes) + * 1 byte (flags) + * 1-2 bytes (n[XY]orus, depending on `flags') + * 0-(64+512*2) = 0-1088 bytes (depending on `n[XY]orus') + * 0-? (structure too complicated to be shown here; depending on + * `flags') + * 1-? glyph data (faintly resembling PS Type 1 charstrings) + * + * ==> minimum size 3 bytes + * + * compoundGps (size at most 2^16 bytes) + * 1 byte (nElements <= 63, flags) + * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') + * + nElements * (6-14 bytes) + * + * bitmapGps (size at most 2^16 bytes) + * 1 byte (flags) + * 3-13 bytes (position info, depending on `flags') + * 0-? bitmap data + * + * ==> minimum size 4 bytes + * + * PFR trailer + * 8 bytes + * + * + * ==> minimum size of a valid PFR: + * 58 (header) + * + 2 (nLogFonts) + * + 27 (1 physFontRecord) + * + 8 (trailer) + * ----- + * 95 bytes + * + */ + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -75,7 +162,8 @@ if ( extra->type == item_type ) { error = extra->parser( p, p + item_size, item_data ); - if ( error ) goto Exit; + if ( error ) + goto Exit; break; } @@ -179,11 +267,12 @@ if ( header->signature != 0x50465230L || /* "PFR0" */ header->version > 4 || header->header_size < 58 || - header->signature2 != 0x0d0a ) /* CR/LF */ + header->signature2 != 0x0D0A ) /* CR/LF */ { result = 0; } - return result; + + return result; } @@ -199,20 +288,37 @@ FT_LOCAL_DEF( FT_Error ) pfr_log_font_count( FT_Stream stream, FT_UInt32 section_offset, - FT_UInt *acount ) + FT_Long *acount ) { FT_Error error; FT_UInt count; FT_UInt result = 0; - if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) + if ( FT_STREAM_SEEK( section_offset ) || + FT_READ_USHORT( count ) ) + goto Exit; + + /* check maximum value and a rough minimum size: */ + /* - no more than 13106 log fonts */ + /* - we need 5 bytes for a log header record */ + /* - we need at least 18 bytes for a log font record */ + /* - the overall size is at least 95 bytes plus the */ + /* log header and log font records */ + if ( count > ( ( 1 << 16 ) - 2 ) / 5 || + 2 + count * 5 >= stream->size - section_offset || + 95 + count * ( 5 + 18 ) >= stream->size ) + { + FT_ERROR(( "pfr_log_font_count:" + " invalid number of logical fonts\n" )); + error = FT_THROW( Invalid_Table ); goto Exit; + } result = count; Exit: - *acount = result; + *acount = (FT_Long)result; return error; } @@ -254,13 +360,14 @@ FT_UInt local; - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_FRAME_ENTER( size ) ) goto Exit; p = stream->cursor; limit = p + size; - PFR_CHECK(13); + PFR_CHECK( 13 ); log_font->matrix[0] = PFR_NEXT_LONG( p ); log_font->matrix[1] = PFR_NEXT_LONG( p ); @@ -276,7 +383,7 @@ if ( flags & PFR_LOG_2BYTE_STROKE ) local++; - if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) + if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) local += 3; } if ( flags & PFR_LOG_BOLD ) @@ -308,10 +415,11 @@ if ( flags & PFR_LOG_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); - if (error) goto Fail; + if ( error ) + goto Fail; } - PFR_CHECK(5); + PFR_CHECK( 5 ); log_font->phys_size = PFR_NEXT_USHORT( p ); log_font->phys_offset = PFR_NEXT_ULONG( p ); if ( size_increment ) @@ -358,7 +466,7 @@ PFR_CHECK( 5 ); - p += 3; /* skip bctSize */ + p += 3; /* skip bctSize */ flags0 = PFR_NEXT_BYTE( p ); count = PFR_NEXT_BYTE( p ); @@ -434,12 +542,12 @@ } - /* Load font ID. This is a so-called "unique" name that is rather - * long and descriptive (like "Tiresias ScreenFont v7.51"). + /* Load font ID. This is a so-called `unique' name that is rather + * long and descriptive (like `Tiresias ScreenFont v7.51'). * * Note that a PFR font's family name is contained in an *undocumented* - * string of the "auxiliary data" portion of a physical font record. This - * may also contain the "real" style name! + * string of the `auxiliary data' portion of a physical font record. This + * may also contain the `real' style name! * * If no family name is present, the font ID is used instead for the * family. @@ -449,9 +557,9 @@ FT_Byte* limit, PFR_PhyFont phy_font ) { - FT_Error error = FT_Err_Ok; - FT_Memory memory = phy_font->memory; - FT_PtrDist len = limit - p; + FT_Error error = FT_Err_Ok; + FT_Memory memory = phy_font->memory; + FT_UInt len = (FT_UInt)( limit - p ); if ( phy_font->font_id != NULL ) @@ -507,7 +615,7 @@ Too_Short: error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_exta_item_load_stem_snaps:" + FT_ERROR(( "pfr_extra_item_load_stem_snaps:" " invalid stem snaps table\n" )); goto Exit; } @@ -525,8 +633,6 @@ FT_Memory memory = phy_font->memory; - FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); - if ( FT_NEW( item ) ) goto Exit; @@ -535,7 +641,8 @@ item->pair_count = PFR_NEXT_BYTE( p ); item->base_adj = PFR_NEXT_SHORT( p ); item->flags = PFR_NEXT_BYTE( p ); - item->offset = phy_font->offset + ( p - phy_font->cursor ); + item->offset = phy_font->offset + + (FT_Offset)( p - phy_font->cursor ); #ifndef PFR_CONFIG_NO_CHECKS item->pair_size = 3; @@ -611,7 +718,6 @@ } - static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = { { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, @@ -622,7 +728,8 @@ }; - /* Loads a name from the auxiliary data. Since this extracts undocumented + /* + * Load a name from the auxiliary data. Since this extracts undocumented * strings from the font file, we need to be careful here. */ static FT_Error @@ -636,12 +743,14 @@ FT_UInt n, ok; + if ( *astring ) + FT_FREE( *astring ); + if ( len > 0 && p[len - 1] == 0 ) len--; - /* check that each character is ASCII for making sure not to - load garbage - */ + /* check that each character is ASCII */ + /* for making sure not to load garbage */ ok = ( len > 0 ); for ( n = 0; n < len; n++ ) if ( p[n] < 32 || p[n] > 127 ) @@ -658,6 +767,7 @@ FT_MEM_COPY( result, p, len ); result[len] = 0; } + Exit: *astring = result; return error; @@ -728,7 +838,8 @@ phy_font->kern_items = NULL; phy_font->kern_items_tail = &phy_font->kern_items; - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_FRAME_ENTER( size ) ) goto Exit; phy_font->cursor = stream->cursor; @@ -756,16 +867,16 @@ /* load the extra items when present */ if ( flags & PFR_PHY_EXTRA_ITEMS ) { - error = pfr_extra_items_parse( &p, limit, - pfr_phy_font_extra_items, phy_font ); + error = pfr_extra_items_parse( &p, limit, + pfr_phy_font_extra_items, phy_font ); if ( error ) goto Fail; } - /* In certain fonts, the auxiliary bytes contain interesting */ - /* information. These are not in the specification but can be */ - /* guessed by looking at the content of a few PFR0 fonts. */ + /* In certain fonts, the auxiliary bytes contain interesting */ + /* information. These are not in the specification but can be */ + /* guessed by looking at the content of a few PFR0 fonts. */ PFR_CHECK( 3 ); num_aux = PFR_NEXT_ULONG( p ); @@ -775,7 +886,7 @@ FT_Byte* q2; - PFR_CHECK( num_aux ); + PFR_CHECK_SIZE( num_aux ); p += num_aux; while ( num_aux > 0 ) @@ -796,9 +907,8 @@ switch ( type ) { case 1: - /* this seems to correspond to the font's family name, - * padded to 16-bits with one zero when necessary - */ + /* this seems to correspond to the font's family name, padded to */ + /* an even number of bytes with a zero byte appended if needed */ error = pfr_aux_name_load( q, length - 4U, memory, &phy_font->family_name ); if ( error ) @@ -813,13 +923,11 @@ phy_font->ascent = PFR_NEXT_SHORT( q ); phy_font->descent = PFR_NEXT_SHORT( q ); phy_font->leading = PFR_NEXT_SHORT( q ); - q += 16; break; case 3: - /* this seems to correspond to the font's style name, - * padded to 16-bits with one zero when necessary - */ + /* this seems to correspond to the font's style name, padded to */ + /* an even number of bytes with a zero byte appended if needed */ error = pfr_aux_name_load( q, length - 4U, memory, &phy_font->style_name ); if ( error ) @@ -865,10 +973,7 @@ phy_font->num_chars = count = PFR_NEXT_USHORT( p ); - phy_font->chars_offset = offset + ( p - stream->cursor ); - - if ( FT_NEW_ARRAY( phy_font->chars, count ) ) - goto Fail; + phy_font->chars_offset = offset + (FT_Offset)( p - stream->cursor ); Size = 1 + 1 + 2; if ( flags & PFR_PHY_2BYTE_CHARCODE ) @@ -886,7 +991,10 @@ if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) Size += 1; - PFR_CHECK( count * Size ); + PFR_CHECK_SIZE( count * Size ); + + if ( FT_NEW_ARRAY( phy_font->chars, count ) ) + goto Fail; for ( n = 0; n < count; n++ ) { @@ -899,7 +1007,7 @@ cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) ? PFR_NEXT_SHORT( p ) - : (FT_Int) phy_font->standard_advance; + : phy_font->standard_advance; #if 0 cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) diff --git a/drivers/freetype/src/pfr/pfrload.h b/drivers/freetype/src/pfr/pfrload.h index ed010715d1..0f7a2bb239 100644 --- a/drivers/freetype/src/pfr/pfrload.h +++ b/drivers/freetype/src/pfr/pfrload.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRLOAD_H__ -#define __PFRLOAD_H__ +#ifndef PFRLOAD_H_ +#define PFRLOAD_H_ #include "pfrobjs.h" #include FT_INTERNAL_STREAM_H @@ -25,14 +25,19 @@ FT_BEGIN_HEADER + /* some size checks should be always done (mainly to prevent */ + /* excessive allocation for malformed data), ... */ +#define PFR_CHECK_SIZE( x ) do \ + { \ + if ( p + (x) > limit ) \ + goto Too_Short; \ + } while ( 0 ) + + /* ... and some only if intensive checking is explicitly requested */ #ifdef PFR_CONFIG_NO_CHECKS #define PFR_CHECK( x ) do { } while ( 0 ) #else -#define PFR_CHECK( x ) do \ - { \ - if ( p + (x) > limit ) \ - goto Too_Short; \ - } while ( 0 ) +#define PFR_CHECK PFR_CHECK_SIZE #endif #define PFR_NEXT_BYTE( p ) FT_NEXT_BYTE( p ) @@ -85,7 +90,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) pfr_log_font_count( FT_Stream stream, FT_UInt32 log_section_offset, - FT_UInt *acount ); + FT_Long *acount ); /* load a pfr logical font entry */ FT_LOCAL( FT_Error ) @@ -112,7 +117,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRLOAD_H__ */ +#endif /* PFRLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/pfr/pfrobjs.c b/drivers/freetype/src/pfr/pfrobjs.c index 75fc4c3f1f..769a3b6164 100644 --- a/drivers/freetype/src/pfr/pfrobjs.c +++ b/drivers/freetype/src/pfr/pfrobjs.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (body). */ /* */ -/* Copyright 2002-2008, 2010-2011, 2013 by */ +/* Copyright 2002-2016 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 "pfrsbit.h" #include FT_OUTLINE_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include FT_TRUETYPE_IDS_H #include "pfrerror.h" @@ -93,7 +94,7 @@ /* check face index */ { - FT_UInt num_faces; + FT_Long num_faces; error = pfr_log_font_count( stream, @@ -108,7 +109,7 @@ if ( face_index < 0 ) goto Exit; - if ( face_index >= pfrface->num_faces ) + if ( ( face_index & 0xFFFF ) >= pfrface->num_faces ) { FT_ERROR(( "pfr_face_init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -117,9 +118,11 @@ /* load the face */ error = pfr_log_font_load( - &face->log_font, stream, face_index, - face->header.log_dir_offset, - FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); + &face->log_font, + stream, + (FT_UInt)( face_index & 0xFFFF ), + face->header.log_dir_offset, + FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); if ( error ) goto Exit; @@ -135,12 +138,13 @@ PFR_PhyFont phy_font = &face->phy_font; - pfrface->face_index = face_index; - pfrface->num_glyphs = phy_font->num_chars + 1; - pfrface->face_flags = FT_FACE_FLAG_SCALABLE; + pfrface->face_index = face_index & 0xFFFF; + pfrface->num_glyphs = (FT_Long)phy_font->num_chars + 1; - /* if all characters point to the same gps_offset 0, we */ - /* assume that the font only contains bitmaps */ + pfrface->face_flags |= FT_FACE_FLAG_SCALABLE; + + /* if gps_offset == 0 for all characters, we */ + /* assume that the font only contains bitmaps */ { FT_UInt nn; @@ -162,7 +166,7 @@ } } - if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( phy_font->flags & PFR_PHY_VERTICAL ) @@ -176,7 +180,7 @@ if ( phy_font->num_kern_pairs > 0 ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; - /* If no family name was found in the "undocumented" auxiliary + /* If no family name was found in the `undocumented' auxiliary * data, use the font ID instead. This sucks but is better than * nothing. */ @@ -185,12 +189,12 @@ pfrface->family_name = phy_font->font_id; /* note that the style name can be NULL in certain PFR fonts, - * probably meaning "Regular" + * probably meaning `Regular' */ pfrface->style_name = phy_font->style_name; pfrface->num_fixed_sizes = 0; - pfrface->available_sizes = 0; + pfrface->available_sizes = NULL; pfrface->bbox = phy_font->bbox; pfrface->units_per_EM = (FT_UShort)phy_font->outline_resolution; @@ -216,13 +220,13 @@ strike = phy_font->strikes; for ( n = 0; n < count; n++, size++, strike++ ) { - size->height = (FT_UShort)strike->y_ppm; - size->width = (FT_UShort)strike->x_ppm; - size->size = strike->y_ppm << 6; - size->x_ppem = strike->x_ppm << 6; - size->y_ppem = strike->y_ppm << 6; + size->height = (FT_Short)strike->y_ppm; + size->width = (FT_Short)strike->x_ppm; + size->size = (FT_Pos)( strike->y_ppm << 6 ); + size->x_ppem = (FT_Pos)( strike->x_ppm << 6 ); + size->y_ppem = (FT_Pos)( strike->y_ppm << 6 ); } - pfrface->num_fixed_sizes = count; + pfrface->num_fixed_sizes = (FT_Int)count; } /* now compute maximum advance width */ @@ -262,13 +266,13 @@ error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); #if 0 - /* Select default charmap */ + /* select default charmap */ if ( pfrface->num_charmaps ) pfrface->charmap = pfrface->charmaps[0]; #endif } - /* check whether we've loaded any kerning pairs */ + /* check whether we have loaded any kerning pairs */ if ( phy_font->num_kern_pairs ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; } @@ -324,6 +328,8 @@ FT_ULong gps_offset; + FT_TRACE1(( "pfr_slot_load: glyph index %d\n", gindex )); + if ( gindex > 0 ) gindex--; @@ -362,7 +368,7 @@ FT_BBox cbox; FT_Glyph_Metrics* metrics = &pfrslot->metrics; FT_Pos advance; - FT_Int em_metrics, em_outline; + FT_UInt em_metrics, em_outline; FT_Bool scaling; @@ -386,7 +392,9 @@ em_outline = face->phy_font.outline_resolution; if ( em_metrics != em_outline ) - advance = FT_MulDiv( advance, em_outline, em_metrics ); + advance = FT_MulDiv( advance, + (FT_Long)em_outline, + (FT_Long)em_metrics ); if ( face->phy_font.flags & PFR_PHY_VERTICAL ) metrics->vertAdvance = advance; @@ -396,7 +404,7 @@ pfrslot->linearHoriAdvance = metrics->horiAdvance; pfrslot->linearVertAdvance = metrics->vertAdvance; - /* make-up vertical metrics(?) */ + /* make up vertical metrics(?) */ metrics->vertBearingX = 0; metrics->vertBearingY = 0; @@ -512,12 +520,12 @@ { FT_UInt count = item->pair_count; FT_UInt size = item->pair_size; - FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); + FT_UInt power = 1 << FT_MSB( 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_Bool twobytes = FT_BOOL( item->flags & PFR_KERN_2BYTE_CHAR ); + FT_Bool twobyte_adj = FT_BOOL( item->flags & PFR_KERN_2BYTE_ADJ ); FT_Byte* p; FT_UInt32 cpair; @@ -590,4 +598,5 @@ return error; } + /* END */ diff --git a/drivers/freetype/src/pfr/pfrobjs.h b/drivers/freetype/src/pfr/pfrobjs.h index f6aa8b44cc..335aca8854 100644 --- a/drivers/freetype/src/pfr/pfrobjs.h +++ b/drivers/freetype/src/pfr/pfrobjs.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (specification). */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFROBJS_H__ -#define __PFROBJS_H__ +#ifndef PFROBJS_H_ +#define PFROBJS_H_ #include "pfrtypes.h" @@ -90,7 +90,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFROBJS_H__ */ +#endif /* PFROBJS_H_ */ /* END */ diff --git a/drivers/freetype/src/pfr/pfrsbit.c b/drivers/freetype/src/pfr/pfrsbit.c index 2da1500707..144f50c0b3 100644 --- a/drivers/freetype/src/pfr/pfrsbit.c +++ b/drivers/freetype/src/pfr/pfrsbit.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (body). */ /* */ -/* Copyright 2002, 2003, 2006, 2009, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,11 +37,11 @@ typedef struct PFR_BitWriter_ { - FT_Byte* line; /* current line start */ - FT_Int pitch; /* line size in bytes */ - FT_Int width; /* width in pixels/bits */ - FT_Int rows; /* number of remaining rows to scan */ - FT_Int total; /* total number of bits to draw */ + FT_Byte* line; /* current line start */ + FT_Int pitch; /* line size in bytes */ + FT_UInt width; /* width in pixels/bits */ + FT_UInt rows; /* number of remaining rows to scan */ + FT_UInt total; /* total number of bits to draw */ } PFR_BitWriterRec, *PFR_BitWriter; @@ -59,7 +59,7 @@ if ( !decreasing ) { - writer->line += writer->pitch * ( target->rows-1 ); + writer->line += writer->pitch * (FT_Int)( target->rows - 1 ); writer->pitch = -writer->pitch; } } @@ -70,15 +70,15 @@ FT_Byte* p, FT_Byte* limit ) { - FT_Int n, reload; - FT_Int left = writer->width; + FT_UInt n, reload; + FT_UInt left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt val = 0; FT_UInt c = 0; - n = (FT_Int)( limit - p ) * 8; + n = (FT_UInt)( limit - p ) * 8; if ( n > writer->total ) n = writer->total; @@ -110,7 +110,7 @@ cur[0] = (FT_Byte)c; mask = 0x80; c = 0; - cur ++; + cur++; } } @@ -124,8 +124,9 @@ FT_Byte* p, FT_Byte* limit ) { - FT_Int n, phase, count, counts[2], reload; - FT_Int left = writer->width; + FT_Int phase, count, counts[2]; + FT_UInt n, reload; + FT_UInt left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt c = 0; @@ -175,7 +176,7 @@ if ( --left <= 0 ) { - cur[0] = (FT_Byte) c; + cur[0] = (FT_Byte)c; left = writer->width; mask = 0x80; @@ -188,7 +189,7 @@ cur[0] = (FT_Byte)c; mask = 0x80; c = 0; - cur ++; + cur++; } reload = ( --count <= 0 ); @@ -204,8 +205,9 @@ FT_Byte* p, FT_Byte* limit ) { - FT_Int n, phase, count, reload; - FT_Int left = writer->width; + FT_Int phase, count; + FT_UInt n, reload; + FT_UInt left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt c = 0; @@ -239,7 +241,7 @@ if ( --left <= 0 ) { - cur[0] = (FT_Byte) c; + cur[0] = (FT_Byte)c; c = 0; mask = 0x80; left = writer->width; @@ -252,7 +254,7 @@ cur[0] = (FT_Byte)c; c = 0; mask = 0x80; - cur ++; + cur++; } reload = ( --count <= 0 ); @@ -275,49 +277,99 @@ pfr_lookup_bitmap_data( FT_Byte* base, FT_Byte* limit, FT_UInt count, - FT_UInt flags, + FT_UInt* flags, FT_UInt char_code, FT_ULong* found_offset, FT_ULong* found_size ) { - FT_UInt left, right, char_len; - FT_Bool two = FT_BOOL( flags & 1 ); + FT_UInt min, max, char_len; + FT_Bool two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE ); FT_Byte* buff; char_len = 4; - if ( two ) char_len += 1; - if ( flags & 2 ) char_len += 1; - if ( flags & 4 ) char_len += 1; + if ( two ) + char_len += 1; + if ( *flags & PFR_BITMAP_2BYTE_SIZE ) + char_len += 1; + if ( *flags & PFR_BITMAP_3BYTE_OFFSET ) + char_len += 1; + + if ( !( *flags & PFR_BITMAP_CHARCODES_VALIDATED ) ) + { + FT_Byte* p; + FT_Byte* lim; + FT_UInt code; + FT_Long prev_code; - left = 0; - right = count; - while ( left < right ) - { - FT_UInt middle, code; + *flags |= PFR_BITMAP_VALID_CHARCODES; + prev_code = -1; + lim = base + count * char_len; + + if ( lim > limit ) + { + FT_TRACE0(( "pfr_lookup_bitmap_data:" + " number of bitmap records too large,\n" + " " + " thus ignoring all bitmaps in this strike\n" )); + *flags &= ~PFR_BITMAP_VALID_CHARCODES; + } + else + { + /* check whether records are sorted by code */ + for ( p = base; p < lim; p += char_len ) + { + if ( two ) + code = FT_PEEK_USHORT( p ); + else + code = *p; + + if ( (FT_Long)code <= prev_code ) + { + FT_TRACE0(( "pfr_lookup_bitmap_data:" + " bitmap records are not sorted,\n" + " " + " thus ignoring all bitmaps in this strike\n" )); + *flags &= ~PFR_BITMAP_VALID_CHARCODES; + break; + } + + prev_code = code; + } + } + + *flags |= PFR_BITMAP_CHARCODES_VALIDATED; + } + + /* ignore bitmaps in case table is not valid */ + /* (this might be sanitized, but PFR is dead...) */ + if ( !( *flags & PFR_BITMAP_VALID_CHARCODES ) ) + goto Fail; + + min = 0; + max = count; + /* binary search */ + while ( min < max ) + { + FT_UInt mid, code; - middle = ( left + right ) >> 1; - buff = base + middle * char_len; - /* check that we are not outside of the table -- */ - /* this is possible with broken fonts... */ - if ( buff + char_len > limit ) - goto Fail; + mid = ( min + max ) >> 1; + buff = base + mid * char_len; if ( two ) code = PFR_NEXT_USHORT( buff ); else code = PFR_NEXT_BYTE( buff ); - if ( code == char_code ) - goto Found_It; - - if ( code < char_code ) - left = middle; + if ( char_code < code ) + max = mid; + else if ( char_code > code ) + min = mid + 1; else - right = middle; + goto Found_It; } Fail: @@ -327,20 +379,20 @@ return; Found_It: - if ( flags & 2 ) + if ( *flags & PFR_BITMAP_2BYTE_SIZE ) *found_size = PFR_NEXT_USHORT( buff ); else *found_size = PFR_NEXT_BYTE( buff ); - if ( flags & 4 ) + if ( *flags & PFR_BITMAP_3BYTE_OFFSET ) *found_offset = PFR_NEXT_ULONG( buff ); else *found_offset = PFR_NEXT_USHORT( buff ); } - /* load bitmap metrics. "*padvance" must be set to the default value */ - /* before calling this function... */ + /* load bitmap metrics. `*padvance' must be set to the default value */ + /* before calling this function */ /* */ static FT_Error pfr_load_bitmap_metrics( FT_Byte** pdata, @@ -355,7 +407,7 @@ { FT_Error error = FT_Err_Ok; FT_Byte flags; - FT_Char b; + FT_Byte b; FT_Byte* p = *pdata; FT_Long xpos, ypos, advance; FT_UInt xsize, ysize; @@ -374,8 +426,8 @@ { case 0: PFR_CHECK( 1 ); - b = PFR_NEXT_INT8( p ); - xpos = b >> 4; + b = PFR_NEXT_BYTE( p ); + xpos = (FT_Char)b >> 4; ypos = ( (FT_Char)( b << 4 ) ) >> 4; break; @@ -442,7 +494,7 @@ case 1: PFR_CHECK( 1 ); - advance = PFR_NEXT_INT8( p ) << 8; + advance = PFR_NEXT_INT8( p ) * 256; break; case 2: @@ -507,8 +559,7 @@ break; default: - FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); - error = FT_THROW( Invalid_File_Format ); + ; } } @@ -541,7 +592,7 @@ character = &phys->chars[glyph_index]; - /* Look-up a bitmap strike corresponding to the current */ + /* look up a bitmap strike corresponding to the current */ /* character dimensions */ { FT_UInt n; @@ -552,9 +603,7 @@ { if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) - { goto Found_Strike; - } strike++; } @@ -565,17 +614,20 @@ Found_Strike: - /* Now lookup the glyph's position within the file */ + /* now look up the glyph's position within the file */ { FT_UInt char_len; char_len = 4; - if ( strike->flags & 1 ) char_len += 1; - if ( strike->flags & 2 ) char_len += 1; - if ( strike->flags & 4 ) char_len += 1; - - /* Access data directly in the frame to speed lookups */ + if ( strike->flags & PFR_BITMAP_2BYTE_CHARCODE ) + char_len += 1; + if ( strike->flags & PFR_BITMAP_2BYTE_SIZE ) + char_len += 1; + if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET ) + char_len += 1; + + /* access data directly in the frame to speed lookups */ if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) goto Exit; @@ -583,7 +635,7 @@ pfr_lookup_bitmap_data( stream->cursor, stream->limit, strike->num_bitmaps, - strike->flags, + &strike->flags, character->char_code, &gps_offset, &gps_size ); @@ -592,7 +644,7 @@ if ( gps_size == 0 ) { - /* Could not find a bitmap program string for this glyph */ + /* could not find a bitmap program string for this glyph */ error = FT_THROW( Invalid_Argument ); goto Exit; } @@ -609,16 +661,16 @@ advance = character->advance; if ( phys->metrics_resolution != phys->outline_resolution ) advance = FT_MulDiv( advance, - phys->outline_resolution, - phys->metrics_resolution ); + (FT_Long)phys->outline_resolution, + (FT_Long)phys->metrics_resolution ); glyph->root.linearHoriAdvance = advance; - /* compute default advance, i.e., scaled advance. This can be */ - /* overridden in the bitmap header of certain glyphs. */ + /* compute default advance, i.e., scaled advance; this can be */ + /* overridden in the bitmap header of certain glyphs */ advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8, character->advance, - phys->metrics_resolution ); + (FT_Long)phys->metrics_resolution ); if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) || FT_FRAME_ENTER( gps_size ) ) @@ -630,13 +682,66 @@ &xpos, &ypos, &xsize, &ysize, &advance, &format ); + if ( error ) + goto Exit1; /* - * XXX: on 16bit system, we return an error for huge bitmap - * which causes a size truncation, because truncated - * size properties makes bitmap glyph broken. + * Before allocating the target bitmap, we check whether the given + * bitmap dimensions are valid, depending on the image format. + * + * Format 0: We have a stream of pixels (with 8 pixels per byte). + * + * (xsize * ysize + 7) / 8 <= gps_size + * + * Format 1: Run-length encoding; the high nibble holds the number of + * white bits, the low nibble the number of black bits. In + * other words, a single byte can represent at most 15 + * pixels. + * + * xsize * ysize <= 15 * gps_size + * + * Format 2: Run-length encoding; the high byte holds the number of + * white bits, the low byte the number of black bits. In + * other words, two bytes can represent at most 255 pixels. + * + * xsize * ysize <= 255 * (gps_size + 1) / 2 */ - if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX ) + switch ( format ) + { + case 0: + if ( ( (FT_ULong)xsize * ysize + 7 ) / 8 > gps_size ) + error = FT_THROW( Invalid_Table ); + break; + case 1: + if ( (FT_ULong)xsize * ysize > 15 * gps_size ) + error = FT_THROW( Invalid_Table ); + break; + case 2: + if ( (FT_ULong)xsize * ysize > 255 * ( ( gps_size + 1 ) / 2 ) ) + error = FT_THROW( Invalid_Table ); + break; + default: + FT_ERROR(( "pfr_slot_load_bitmap: invalid image type\n" )); + error = FT_THROW( Invalid_Table ); + } + + if ( error ) + { + if ( FT_ERR_EQ( error, Invalid_Table ) ) + FT_ERROR(( "pfr_slot_load_bitmap: invalid bitmap dimensions\n" )); + goto Exit1; + } + + /* + * XXX: on 16bit systems we return an error for huge bitmaps + * that cause size truncation, because truncated + * size properties make bitmap glyphs broken. + */ + if ( xpos > FT_INT_MAX || + xpos < FT_INT_MIN || + ysize > FT_INT_MAX || + ypos > FT_INT_MAX - (FT_Long)ysize || + ypos + (FT_Long)ysize < FT_INT_MIN ) { FT_TRACE1(( "pfr_slot_load_bitmap:" )); FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n", @@ -651,16 +756,16 @@ /* Set up glyph bitmap and metrics */ /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */ - glyph->root.bitmap.width = (FT_Int)xsize; - glyph->root.bitmap.rows = (FT_Int)ysize; + glyph->root.bitmap.width = xsize; + glyph->root.bitmap.rows = ysize; glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3; glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ glyph->root.metrics.width = (FT_Pos)xsize << 6; glyph->root.metrics.height = (FT_Pos)ysize << 6; - glyph->root.metrics.horiBearingX = xpos << 6; - glyph->root.metrics.horiBearingY = ypos << 6; + glyph->root.metrics.horiBearingX = xpos * 64; + glyph->root.metrics.horiBearingY = ypos * 64; glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; glyph->root.metrics.vertBearingY = 0; @@ -668,26 +773,26 @@ /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */ glyph->root.bitmap_left = (FT_Int)xpos; - glyph->root.bitmap_top = (FT_Int)(ypos + ysize); + glyph->root.bitmap_top = (FT_Int)( ypos + (FT_Long)ysize ); /* Allocate and read bitmap data */ { - FT_ULong len = glyph->root.bitmap.pitch * ysize; + FT_ULong len = (FT_ULong)glyph->root.bitmap.pitch * ysize; error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); if ( !error ) - { error = pfr_load_bitmap_bits( p, stream->limit, format, - FT_BOOL(face->header.color_flags & 2), + FT_BOOL( face->header.color_flags & + PFR_FLAG_INVERT_BITMAP ), &glyph->root.bitmap ); - } } } + Exit1: FT_FRAME_EXIT(); } @@ -695,4 +800,5 @@ return error; } + /* END */ diff --git a/drivers/freetype/src/pfr/pfrsbit.h b/drivers/freetype/src/pfr/pfrsbit.h index 015e9e6dad..94ead28ca7 100644 --- a/drivers/freetype/src/pfr/pfrsbit.h +++ b/drivers/freetype/src/pfr/pfrsbit.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRSBIT_H__ -#define __PFRSBIT_H__ +#ifndef PFRSBIT_H_ +#define PFRSBIT_H_ #include "pfrobjs.h" @@ -30,7 +30,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFR_SBIT_H__ */ +#endif /* PFRSBIT_H_ */ /* END */ diff --git a/drivers/freetype/src/pfr/pfrtypes.h b/drivers/freetype/src/pfr/pfrtypes.h index 918310814c..bd6c2cd30c 100644 --- a/drivers/freetype/src/pfr/pfrtypes.h +++ b/drivers/freetype/src/pfr/pfrtypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR data structures (specification only). */ /* */ -/* Copyright 2002, 2003, 2005, 2007 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRTYPES_H__ -#define __PFRTYPES_H__ +#ifndef PFRTYPES_H_ +#define PFRTYPES_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -69,12 +69,8 @@ FT_BEGIN_HEADER /* used in `color_flags' field of the PFR_Header */ - typedef enum PFR_HeaderFlags_ - { - PFR_FLAG_BLACK_PIXEL = 1, - PFR_FLAG_INVERT_BITMAP = 2 - - } PFR_HeaderFlags; +#define PFR_FLAG_BLACK_PIXEL 0x01U +#define PFR_FLAG_INVERT_BITMAP 0x02U /************************************************************************/ @@ -96,36 +92,27 @@ FT_BEGIN_HEADER } PFR_LogFontRec, *PFR_LogFont; - typedef enum PFR_LogFlags_ - { - PFR_LOG_EXTRA_ITEMS = 0x40, - PFR_LOG_2BYTE_BOLD = 0x20, - PFR_LOG_BOLD = 0x10, - PFR_LOG_2BYTE_STROKE = 8, - PFR_LOG_STROKE = 4, - PFR_LINE_JOIN_MASK = 3 +#define PFR_LINE_JOIN_MITER 0x00U +#define PFR_LINE_JOIN_ROUND 0x01U +#define PFR_LINE_JOIN_BEVEL 0x02U +#define PFR_LINE_JOIN_MASK ( PFR_LINE_JOIN_ROUND | PFR_LINE_JOIN_BEVEL ) - } PFR_LogFlags; - - - typedef enum PFR_LineJoinFlags_ - { - PFR_LINE_JOIN_MITER = 0, - PFR_LINE_JOIN_ROUND = 1, - PFR_LINE_JOIN_BEVEL = 2 - - } PFR_LineJoinFlags; +#define PFR_LOG_STROKE 0x04U +#define PFR_LOG_2BYTE_STROKE 0x08U +#define PFR_LOG_BOLD 0x10U +#define PFR_LOG_2BYTE_BOLD 0x20U +#define PFR_LOG_EXTRA_ITEMS 0x40U /************************************************************************/ - typedef enum PFR_BitmapFlags_ - { - PFR_BITMAP_3BYTE_OFFSET = 4, - PFR_BITMAP_2BYTE_SIZE = 2, - PFR_BITMAP_2BYTE_CHARCODE = 1 +#define PFR_BITMAP_2BYTE_CHARCODE 0x01U +#define PFR_BITMAP_2BYTE_SIZE 0x02U +#define PFR_BITMAP_3BYTE_OFFSET 0x04U - } PFR_BitmapFlags; + /*not part of the specification but used for implementation */ +#define PFR_BITMAP_CHARCODES_VALIDATED 0x40U +#define PFR_BITMAP_VALID_CHARCODES 0x80U typedef struct PFR_BitmapCharRec_ @@ -137,15 +124,11 @@ FT_BEGIN_HEADER } PFR_BitmapCharRec, *PFR_BitmapChar; - typedef enum PFR_StrikeFlags_ - { - PFR_STRIKE_2BYTE_COUNT = 0x10, - PFR_STRIKE_3BYTE_OFFSET = 0x08, - PFR_STRIKE_3BYTE_SIZE = 0x04, - PFR_STRIKE_2BYTE_YPPM = 0x02, - PFR_STRIKE_2BYTE_XPPM = 0x01 - - } PFR_StrikeFlags; +#define PFR_STRIKE_2BYTE_XPPM 0x01U +#define PFR_STRIKE_2BYTE_YPPM 0x02U +#define PFR_STRIKE_3BYTE_SIZE 0x04U +#define PFR_STRIKE_3BYTE_OFFSET 0x08U +#define PFR_STRIKE_2BYTE_COUNT 0x10U typedef struct PFR_StrikeRec_ @@ -229,7 +212,7 @@ FT_BEGIN_HEADER FT_UInt metrics_resolution; FT_BBox bbox; FT_UInt flags; - FT_UInt standard_advance; + FT_Int standard_advance; FT_Int ascent; /* optional, bbox.yMax if not present */ FT_Int descent; /* optional, bbox.yMin if not present */ @@ -260,44 +243,35 @@ FT_BEGIN_HEADER PFR_KernItem* kern_items_tail; /* not part of the spec, but used during load */ - FT_Long bct_offset; + FT_ULong bct_offset; FT_Byte* cursor; } PFR_PhyFontRec, *PFR_PhyFont; - typedef enum PFR_PhyFlags_ - { - PFR_PHY_EXTRA_ITEMS = 0x80, - PFR_PHY_3BYTE_GPS_OFFSET = 0x20, - PFR_PHY_2BYTE_GPS_SIZE = 0x10, - PFR_PHY_ASCII_CODE = 0x08, - PFR_PHY_PROPORTIONAL = 0x04, - PFR_PHY_2BYTE_CHARCODE = 0x02, - PFR_PHY_VERTICAL = 0x01 - - } PFR_PhyFlags; +#define PFR_PHY_VERTICAL 0x01U +#define PFR_PHY_2BYTE_CHARCODE 0x02U +#define PFR_PHY_PROPORTIONAL 0x04U +#define PFR_PHY_ASCII_CODE 0x08U +#define PFR_PHY_2BYTE_GPS_SIZE 0x10U +#define PFR_PHY_3BYTE_GPS_OFFSET 0x20U +#define PFR_PHY_EXTRA_ITEMS 0x80U - typedef enum PFR_KernFlags_ - { - PFR_KERN_2BYTE_CHAR = 0x01, - PFR_KERN_2BYTE_ADJ = 0x02 - - } PFR_KernFlags; +#define PFR_KERN_2BYTE_CHAR 0x01U +#define PFR_KERN_2BYTE_ADJ 0x02U /************************************************************************/ - typedef enum PFR_GlyphFlags_ - { - PFR_GLYPH_IS_COMPOUND = 0x80, - PFR_GLYPH_EXTRA_ITEMS = 0x08, - PFR_GLYPH_1BYTE_XYCOUNT = 0x04, - PFR_GLYPH_XCOUNT = 0x02, - PFR_GLYPH_YCOUNT = 0x01 +#define PFR_GLYPH_YCOUNT 0x01U +#define PFR_GLYPH_XCOUNT 0x02U +#define PFR_GLYPH_1BYTE_XYCOUNT 0x04U + +#define PFR_GLYPH_SINGLE_EXTRA_ITEMS 0x08U +#define PFR_GLYPH_COMPOUND_EXTRA_ITEMS 0x40U - } PFR_GlyphFlags; +#define PFR_GLYPH_IS_COMPOUND 0x80U /* controlled coordinate */ @@ -321,14 +295,10 @@ FT_BEGIN_HEADER } PFR_SubGlyphRec, *PFR_SubGlyph; - typedef enum PFR_SubgGlyphFlags_ - { - PFR_SUBGLYPH_3BYTE_OFFSET = 0x80, - PFR_SUBGLYPH_2BYTE_SIZE = 0x40, - PFR_SUBGLYPH_YSCALE = 0x20, - PFR_SUBGLYPH_XSCALE = 0x10 - - } PFR_SubGlyphFlags; +#define PFR_SUBGLYPH_XSCALE 0x10U +#define PFR_SUBGLYPH_YSCALE 0x20U +#define PFR_SUBGLYPH_2BYTE_SIZE 0x40U +#define PFR_SUBGLYPH_3BYTE_OFFSET 0x80U typedef struct PFR_GlyphRec_ @@ -356,7 +326,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRTYPES_H__ */ +#endif /* PFRTYPES_H_ */ /* END */ diff --git a/drivers/freetype/src/pfr/rules.mk b/drivers/freetype/src/pfr/rules.mk index 60b96c7415..39bb9e941a 100644 --- a/drivers/freetype/src/pfr/rules.mk +++ b/drivers/freetype/src/pfr/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2003 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ PFR_DIR := $(SRC_DIR)/pfr # compilation flags for the driver # -PFR_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PFR_DIR)) +PFR_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PFR_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # pfr driver sources (i.e., C files) diff --git a/drivers/freetype/src/psaux/Jamfile b/drivers/freetype/src/psaux/Jamfile index faeded9044..9270eec687 100644 --- a/drivers/freetype/src/psaux/Jamfile +++ b/drivers/freetype/src/psaux/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/psaux Jamfile # -# Copyright 2001, 2002 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,8 +16,12 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psaux ; if $(FT2_MULTI) { - _sources = psauxmod psobjs t1decode t1cmap - psconv afmparse + _sources = afmparse + psauxmod + psconv + psobjs + t1cmap + t1decode ; } else diff --git a/drivers/freetype/src/psaux/afmparse.c b/drivers/freetype/src/psaux/afmparse.c index 6a40e110dc..9fb0ac0e2b 100644 --- a/drivers/freetype/src/psaux/afmparse.c +++ b/drivers/freetype/src/psaux/afmparse.c @@ -4,7 +4,7 @@ /* */ /* AFM parser (body). */ /* */ -/* Copyright 2006-2010, 2012, 2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -75,8 +75,8 @@ #define AFM_STREAM_KEY_BEGIN( stream ) \ (char*)( (stream)->cursor - 1 ) -#define AFM_STREAM_KEY_LEN( stream, key ) \ - ( (char*)(stream)->cursor - key - 1 ) +#define AFM_STREAM_KEY_LEN( stream, key ) \ + (FT_Offset)( (char*)(stream)->cursor - key - 1 ) #define AFM_STATUS_EOC( stream ) \ ( (stream)->status >= AFM_STREAM_STATUS_EOC ) @@ -369,11 +369,11 @@ FT_LOCAL_DEF( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_UInt n ) + FT_Int n ) { AFM_Stream stream = parser->stream; char* str; - FT_UInt i; + FT_Int i; if ( n > AFM_MAX_ARGUMENTS ) @@ -446,7 +446,7 @@ FT_Offset* len ) { AFM_Stream stream = parser->stream; - char* key = 0; /* make stupid compiler happy */ + char* key = NULL; /* make stupid compiler happy */ if ( line ) @@ -562,7 +562,7 @@ } - FT_LOCAL_DEF( FT_Error ) + static FT_Error afm_parser_read_int( AFM_Parser parser, FT_Int* aint ) { @@ -590,11 +590,17 @@ char* key; FT_Offset len; int n = -1; + FT_Int tmp; - if ( afm_parser_read_int( parser, &fi->NumTrackKern ) ) + if ( afm_parser_read_int( parser, &tmp ) ) goto Fail; + if ( tmp < 0 ) + goto Fail; + + fi->NumTrackKern = (FT_UInt)tmp; + if ( fi->NumTrackKern ) { FT_Memory memory = parser->memory; @@ -615,7 +621,7 @@ case AFM_TOKEN_TRACKKERN: n++; - if ( n >= fi->NumTrackKern ) + if ( n >= (int)fi->NumTrackKern ) goto Fail; tk = fi->TrackKerns + n; @@ -639,7 +645,7 @@ case AFM_TOKEN_ENDTRACKKERN: case AFM_TOKEN_ENDKERNDATA: case AFM_TOKEN_ENDFONTMETRICS: - fi->NumTrackKern = n + 1; + fi->NumTrackKern = (FT_UInt)( n + 1 ); return FT_Err_Ok; case AFM_TOKEN_UNKNOWN: @@ -688,11 +694,17 @@ char* key; FT_Offset len; int n = -1; + FT_Int tmp; + + if ( afm_parser_read_int( parser, &tmp ) ) + goto Fail; - if ( afm_parser_read_int( parser, &fi->NumKernPair ) ) + if ( tmp < 0 ) goto Fail; + fi->NumKernPair = (FT_UInt)tmp; + if ( fi->NumKernPair ) { FT_Memory memory = parser->memory; @@ -720,7 +732,7 @@ n++; - if ( n >= fi->NumKernPair ) + if ( n >= (int)fi->NumKernPair ) goto Fail; kp = fi->KernPairs + n; @@ -733,8 +745,9 @@ if ( r < 3 ) goto Fail; - kp->index1 = shared_vals[0].u.i; - kp->index2 = shared_vals[1].u.i; + /* index values can't be negative */ + kp->index1 = shared_vals[0].u.u; + kp->index2 = shared_vals[1].u.u; if ( token == AFM_TOKEN_KPY ) { kp->x = 0; @@ -752,7 +765,7 @@ case AFM_TOKEN_ENDKERNPAIRS: case AFM_TOKEN_ENDKERNDATA: case AFM_TOKEN_ENDFONTMETRICS: - fi->NumKernPair = n + 1; + fi->NumKernPair = (FT_UInt)( n + 1 ); ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ), afm_compare_kern_pairs ); @@ -815,7 +828,7 @@ static FT_Error afm_parser_skip_section( AFM_Parser parser, - FT_UInt n, + FT_Int n, AFM_Token end_section ) { char* key; diff --git a/drivers/freetype/src/psaux/afmparse.h b/drivers/freetype/src/psaux/afmparse.h index 35d96046c5..6d8b193ffc 100644 --- a/drivers/freetype/src/psaux/afmparse.h +++ b/drivers/freetype/src/psaux/afmparse.h @@ -4,7 +4,7 @@ /* */ /* AFM parser (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFMPARSE_H__ -#define __AFMPARSE_H__ +#ifndef AFMPARSE_H_ +#define AFMPARSE_H_ #include <ft2build.h> @@ -61,6 +61,7 @@ FT_BEGIN_HEADER char* s; FT_Fixed f; FT_Int i; + FT_UInt u; FT_Bool b; } u; @@ -72,7 +73,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_UInt n ); + FT_Int n ); /* read the next key from the next line or column */ FT_LOCAL( char* ) @@ -82,7 +83,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFMPARSE_H__ */ +#endif /* AFMPARSE_H_ */ /* END */ diff --git a/drivers/freetype/src/psaux/module.mk b/drivers/freetype/src/psaux/module.mk index 42bf6f5199..630c4f39dd 100644 --- a/drivers/freetype/src/psaux/module.mk +++ b/drivers/freetype/src/psaux/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/psaux/psaux.c b/drivers/freetype/src/psaux/psaux.c index a4b9c5c6e4..33b462ef15 100644 --- a/drivers/freetype/src/psaux/psaux.c +++ b/drivers/freetype/src/psaux/psaux.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript driver component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/psaux/psauxerr.h b/drivers/freetype/src/psaux/psauxerr.h index d52375f8cb..9739157fc4 100644 --- a/drivers/freetype/src/psaux/psauxerr.h +++ b/drivers/freetype/src/psaux/psauxerr.h @@ -4,7 +4,7 @@ /* */ /* PS auxiliary module error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __PSAUXERR_H__ -#define __PSAUXERR_H__ +#ifndef PSAUXERR_H_ +#define PSAUXERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSaux_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __PSAUXERR_H__ */ +#endif /* PSAUXERR_H_ */ /* END */ diff --git a/drivers/freetype/src/psaux/psauxmod.c b/drivers/freetype/src/psaux/psauxmod.c index 4b1249d49b..80805e6951 100644 --- a/drivers/freetype/src/psaux/psauxmod.c +++ b/drivers/freetype/src/psaux/psauxmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2006 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/psaux/psauxmod.h b/drivers/freetype/src/psaux/psauxmod.h index 1217236924..b1dbb06904 100644 --- a/drivers/freetype/src/psaux/psauxmod.h +++ b/drivers/freetype/src/psaux/psauxmod.h @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (specification). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSAUXMOD_H__ -#define __PSAUXMOD_H__ +#ifndef PSAUXMOD_H_ +#define PSAUXMOD_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSAUXMOD_H__ */ +#endif /* PSAUXMOD_H_ */ /* END */ diff --git a/drivers/freetype/src/psaux/psconv.c b/drivers/freetype/src/psaux/psconv.c index d0d8861c22..fdaca7fb5d 100644 --- a/drivers/freetype/src/psaux/psconv.c +++ b/drivers/freetype/src/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006, 2008, 2009, 2012-2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -124,7 +124,7 @@ if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) break; - c = ft_char_table[*p & 0x7f]; + c = ft_char_table[*p & 0x7F]; if ( c < 0 || c >= base ) break; @@ -245,12 +245,13 @@ if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) break; - c = ft_char_table[*p & 0x7f]; + c = ft_char_table[*p & 0x7F]; if ( c < 0 || c >= 10 ) break; - if ( decimal < 0xCCCCCCCL ) + /* only add digit if we don't overflow */ + if ( divider < 0xCCCCCCCL && decimal < 0xCCCCCCCL ) { decimal = decimal * 10 + c; @@ -488,8 +489,8 @@ if ( c OP 0x80 ) break; - c = ft_char_table[c & 0x7F]; - if ( (unsigned)c >= 16 ) + c = (FT_UInt)ft_char_table[c & 0x7F]; + if ( c >= 16 ) break; pad = ( pad << 4 ) | c; @@ -520,7 +521,7 @@ if ( *p OP 0x80 ) break; - c = ft_char_table[*p & 0x7f]; + c = ft_char_table[*p & 0x7F]; if ( (unsigned)c >= 16 ) break; diff --git a/drivers/freetype/src/psaux/psconv.h b/drivers/freetype/src/psaux/psconv.h index d91c762210..062de36413 100644 --- a/drivers/freetype/src/psaux/psconv.h +++ b/drivers/freetype/src/psaux/psconv.h @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (specification). */ /* */ -/* Copyright 2006, 2012 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSCONV_H__ -#define __PSCONV_H__ +#ifndef PSCONV_H_ +#define PSCONV_H_ #include <ft2build.h> @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSCONV_H__ */ +#endif /* PSCONV_H_ */ /* END */ diff --git a/drivers/freetype/src/psaux/psobjs.c b/drivers/freetype/src/psaux/psobjs.c index dd976d3a96..f208b5fc63 100644 --- a/drivers/freetype/src/psaux/psobjs.c +++ b/drivers/freetype/src/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -81,7 +81,7 @@ table->max_elems = count; table->init = 0xDEADBEEFUL; table->num_elems = 0; - table->block = 0; + table->block = NULL; table->capacity = 0; table->cursor = 0; @@ -165,10 +165,10 @@ /* reallocation fails. */ /* */ FT_LOCAL_DEF( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_UInt length ) { if ( idx < 0 || idx >= table->max_elems ) { @@ -176,12 +176,6 @@ return FT_THROW( Invalid_Argument ); } - if ( length < 0 ) - { - FT_ERROR(( "ps_table_add: invalid length\n" )); - return FT_THROW( Invalid_Argument ); - } - /* grow the base block if needed */ if ( table->cursor + length > table->capacity ) { @@ -600,6 +594,9 @@ error = FT_THROW( Invalid_File_Format ); } + if ( cur > limit ) + cur = limit; + parser->error = error; parser->cursor = cur; } @@ -625,8 +622,8 @@ token->type = T1_TOKEN_TYPE_NONE; - token->start = 0; - token->limit = 0; + token->start = NULL; + token->limit = NULL; /* first of all, skip leading whitespace */ ps_parser_skip_spaces( parser ); @@ -707,7 +704,7 @@ if ( !token->limit ) { - token->start = 0; + token->start = NULL; token->type = T1_TOKEN_TYPE_NONE; } @@ -847,6 +844,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' */ + /* */ + /* return number of successfully parsed values */ static FT_Int ps_tofixedarray( FT_Byte* *acur, @@ -930,7 +929,7 @@ FT_Memory memory ) { FT_Byte* cur = *cursor; - FT_PtrDist len = 0; + FT_UInt len = 0; FT_Int count; FT_String* result; FT_Error error; @@ -970,7 +969,7 @@ } } - len = cur - *cursor; + len = (FT_UInt)( cur - *cursor ); if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) return 0; @@ -1088,9 +1087,9 @@ for ( ; count > 0; count--, idx++ ) { - FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; + FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; FT_Long val; - FT_String* string; + FT_String* string = NULL; skip_spaces( &cur, limit ); @@ -1200,7 +1199,7 @@ result = ps_tofixedarray( &cur, limit, 4, temp, 0 ); - if ( result < 0 ) + if ( result < 4 ) { FT_ERROR(( "ps_parser_load_field:" " expected four integers in bounding box\n" )); @@ -1218,7 +1217,7 @@ case T1_FIELD_TYPE_MM_BBOX: { FT_Memory memory = parser->memory; - FT_Fixed* temp; + FT_Fixed* temp = NULL; FT_Int result; FT_UInt i; @@ -1228,20 +1227,22 @@ for ( i = 0; i < 4; i++ ) { - result = ps_tofixedarray( &cur, limit, max_objects, + result = ps_tofixedarray( &cur, limit, (FT_Int)max_objects, temp + i * max_objects, 0 ); - if ( result < 0 ) + if ( result < 0 || (FT_UInt)result < max_objects ) { FT_ERROR(( "ps_parser_load_field:" - " expected %d integers in the %s subarray\n" + " expected %d integer%s in the %s subarray\n" " " " of /FontBBox in the /Blend dictionary\n", - max_objects, + max_objects, max_objects > 1 ? "s" : "", i == 0 ? "first" : ( i == 1 ? "second" : ( i == 2 ? "third" : "fourth" ) ) )); error = FT_THROW( Invalid_File_Format ); + + FT_FREE( temp ); goto Exit; } @@ -1319,7 +1320,7 @@ goto Exit; } if ( (FT_UInt)num_elements > field->array_max ) - num_elements = field->array_max; + num_elements = (FT_Int)field->array_max; old_cursor = parser->cursor; old_limit = parser->limit; @@ -1336,7 +1337,15 @@ { parser->cursor = token->start; parser->limit = token->limit; - ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 ); + + error = ps_parser_load_field( parser, + &fieldrec, + objects, + max_objects, + 0 ); + if ( error ) + break; + fieldrec.offset += fieldrec.size; } @@ -1369,7 +1378,7 @@ ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, FT_Offset max_bytes, - FT_Long* pnum_bytes, + FT_ULong* pnum_bytes, FT_Bool delimiters ) { FT_Error error = FT_Err_Ok; @@ -1543,7 +1552,7 @@ FT_GlyphLoader_Rewind( loader ); builder->hints_globals = size->internal; - builder->hints_funcs = 0; + builder->hints_funcs = NULL; if ( hinting ) builder->hints_funcs = glyph->internal->glyph_hints; diff --git a/drivers/freetype/src/psaux/psobjs.h b/drivers/freetype/src/psaux/psobjs.h index e380c60dab..4c7178e79f 100644 --- a/drivers/freetype/src/psaux/psobjs.h +++ b/drivers/freetype/src/psaux/psobjs.h @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSOBJS_H__ -#define __PSOBJS_H__ +#ifndef PSOBJS_H_ +#define PSOBJS_H_ #include <ft2build.h> @@ -52,10 +52,10 @@ FT_BEGIN_HEADER FT_Memory memory ); FT_LOCAL( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ); + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_UInt length ); FT_LOCAL( void ) ps_table_done( PS_Table table ); @@ -112,7 +112,7 @@ FT_BEGIN_HEADER ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, FT_Offset max_bytes, - FT_Long* pnum_bytes, + FT_ULong* pnum_bytes, FT_Bool delimiters ); @@ -206,7 +206,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSOBJS_H__ */ +#endif /* PSOBJS_H_ */ /* END */ diff --git a/drivers/freetype/src/psaux/rules.mk b/drivers/freetype/src/psaux/rules.mk index 7a1be37b69..19787b5f82 100644 --- a/drivers/freetype/src/psaux/rules.mk +++ b/drivers/freetype/src/psaux/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ PSAUX_DIR := $(SRC_DIR)/psaux # compilation flags for the driver # -PSAUX_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) +PSAUX_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # PSAUX driver sources (i.e., C files) diff --git a/drivers/freetype/src/psaux/t1cmap.c b/drivers/freetype/src/psaux/t1cmap.c index 9e5bd34ffe..43abb98615 100644 --- a/drivers/freetype/src/psaux/t1cmap.c +++ b/drivers/freetype/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002, 2003, 2006, 2007, 2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,7 +39,7 @@ FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - cmap->num_glyphs = face->type1.num_glyphs; + cmap->num_glyphs = (FT_UInt)face->type1.num_glyphs; cmap->glyph_names = (const char* const*)face->type1.glyph_names; cmap->sid_to_string = psnames->adobe_std_strings; cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding @@ -120,8 +120,12 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_standard_init( T1_CMapStd cmap ) + t1_cmap_standard_init( T1_CMapStd cmap, + FT_Pointer pointer ) { + FT_UNUSED( pointer ); + + t1_cmap_std_init( cmap, 0 ); return 0; } @@ -142,8 +146,12 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_expert_init( T1_CMapStd cmap ) + t1_cmap_expert_init( T1_CMapStd cmap, + FT_Pointer pointer ) { + FT_UNUSED( pointer ); + + t1_cmap_std_init( cmap, 1 ); return 0; } @@ -172,14 +180,17 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_custom_init( T1_CMapCustom cmap ) + t1_cmap_custom_init( T1_CMapCustom cmap, + FT_Pointer pointer ) { T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); T1_Encoding encoding = &face->type1.encoding; + FT_UNUSED( pointer ); + - cmap->first = encoding->code_first; - cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); + cmap->first = (FT_UInt)encoding->code_first; + cmap->count = (FT_UInt)encoding->code_last - cmap->first; cmap->indices = encoding->char_index; FT_ASSERT( cmap->indices != NULL ); @@ -272,16 +283,19 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_unicode_init( PS_Unicodes unicodes ) + t1_cmap_unicode_init( PS_Unicodes unicodes, + FT_Pointer pointer ) { T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); FT_Memory memory = FT_FACE_MEMORY( face ); FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + FT_UNUSED( pointer ); + return psnames->unicodes_init( memory, unicodes, - face->type1.num_glyphs, + (FT_UInt)face->type1.num_glyphs, (PS_GetGlyphNameFunc)&psaux_get_glyph_name, (PS_FreeGlyphNameFunc)NULL, (FT_Pointer)face ); diff --git a/drivers/freetype/src/psaux/t1cmap.h b/drivers/freetype/src/psaux/t1cmap.h index 7ae65d2fa1..5e1277dc63 100644 --- a/drivers/freetype/src/psaux/t1cmap.h +++ b/drivers/freetype/src/psaux/t1cmap.h @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (specification). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1CMAP_H__ -#define __T1CMAP_H__ +#ifndef T1CMAP_H_ +#define T1CMAP_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -99,7 +99,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1CMAP_H__ */ +#endif /* T1CMAP_H_ */ /* END */ diff --git a/drivers/freetype/src/psaux/t1decode.c b/drivers/freetype/src/psaux/t1decode.c index 6ce370bfaa..98f6ce1c87 100644 --- a/drivers/freetype/src/psaux/t1decode.c +++ b/drivers/freetype/src/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_HASH_H #include FT_OUTLINE_H #include "t1decode.h" @@ -150,7 +151,7 @@ if ( name && name[0] == glyph_name[0] && ft_strcmp( name, glyph_name ) == 0 ) - return n; + return (FT_Int)n; } return -1; @@ -298,7 +299,7 @@ /* the seac operator must not be nested */ decoder->seac = TRUE; - error = t1_decoder_parse_glyph( decoder, bchar_index ); + error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index ); decoder->seac = FALSE; if ( error ) goto Exit; @@ -320,7 +321,7 @@ /* the seac operator must not be nested */ decoder->seac = TRUE; - error = t1_decoder_parse_glyph( decoder, achar_index ); + error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index ); decoder->seac = FALSE; if ( error ) goto Exit; @@ -381,10 +382,10 @@ /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ - (FT_PtrDist)(char*)&decoder ^ - (FT_PtrDist)(char*)&charstring_base ) & - FT_ULONG_MAX ) ; + seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed ^ + (FT_Offset)(char*)&decoder ^ + (FT_Offset)(char*)&charstring_base ) & + FT_ULONG_MAX ); seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; if ( seed == 0 ) seed = 0x7384; @@ -512,7 +513,7 @@ break; case 12: - if ( ip > limit ) + if ( ip >= limit ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " invalid escape (12+EOF)\n" )); @@ -669,7 +670,7 @@ if ( large_int ) FT_TRACE4(( " %ld", value )); else - FT_TRACE4(( " %ld", Fix2Int( value ) )); + FT_TRACE4(( " %ld", value / 65536 )); #endif *top++ = value; @@ -796,7 +797,8 @@ known_othersubr_result_cnt = 1; if ( hinter ) - hinter->reset( hinter->hints, builder->current->n_points ); + hinter->reset( hinter->hints, + (FT_UInt)builder->current->n_points ); break; case 12: @@ -861,7 +863,7 @@ *values++ = tmp; } - known_othersubr_result_cnt = num_points; + known_othersubr_result_cnt = (FT_Int)num_points; break; } @@ -879,8 +881,8 @@ idx = Fix2Int( top[0] ); - if ( idx < 0 || - idx + blend->num_designs > decoder->len_buildchar ) + if ( idx < 0 || + (FT_UInt)idx + blend->num_designs > decoder->len_buildchar ) goto Unexpected_OtherSubr; ft_memcpy( &decoder->buildchar[idx], @@ -1094,14 +1096,17 @@ /* close hints recording session */ if ( hinter ) { - if ( hinter->close( hinter->hints, builder->current->n_points ) ) + if ( hinter->close( hinter->hints, + (FT_UInt)builder->current->n_points ) ) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ - hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_mode ); + error = hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + if ( error ) + goto Fail; } /* add current outline to the glyph slot */ @@ -1344,7 +1349,20 @@ FT_TRACE4(( " callsubr" )); idx = Fix2Int( top[0] ); - if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) + + if ( decoder->subrs_hash ) + { + size_t* val = ft_hash_num_lookup( idx, + decoder->subrs_hash ); + + + if ( val ) + idx = *val; + else + idx = -1; + } + + if ( idx < 0 || idx >= decoder->num_subrs ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " invalid subrs index\n" )); @@ -1577,7 +1595,7 @@ /* retrieve PSNames interface from list of current modules */ { - FT_Service_PsCMaps psnames = 0; + FT_Service_PsCMaps psnames; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); diff --git a/drivers/freetype/src/psaux/t1decode.h b/drivers/freetype/src/psaux/t1decode.h index 00728db501..0f5adfa156 100644 --- a/drivers/freetype/src/psaux/t1decode.h +++ b/drivers/freetype/src/psaux/t1decode.h @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1DECODE_H__ -#define __T1DECODE_H__ +#ifndef T1DECODE_H_ +#define T1DECODE_H_ #include <ft2build.h> @@ -58,7 +58,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1DECODE_H__ */ +#endif /* T1DECODE_H_ */ /* END */ diff --git a/drivers/freetype/src/pshinter/Jamfile b/drivers/freetype/src/pshinter/Jamfile index 779f1b0b82..fcb225811e 100644 --- a/drivers/freetype/src/pshinter/Jamfile +++ b/drivers/freetype/src/pshinter/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pshinter Jamfile # -# Copyright 2001, 2003 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,12 @@ SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ; if $(FT2_MULTI) { - _sources = pshrec pshglob pshalgo pshmod pshpic ; + _sources = pshalgo + pshglob + pshmod + pshpic + pshrec + ; } else { diff --git a/drivers/freetype/src/pshinter/module.mk b/drivers/freetype/src/pshinter/module.mk index ed24eb7fa8..63110c46a6 100644 --- a/drivers/freetype/src/pshinter/module.mk +++ b/drivers/freetype/src/pshinter/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2001, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/pshinter/pshalgo.c b/drivers/freetype/src/pshinter/pshalgo.c index 343472ddb3..8f131be759 100644 --- a/drivers/freetype/src/pshinter/pshalgo.c +++ b/drivers/freetype/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001-2010, 2012, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -30,16 +30,14 @@ #ifdef DEBUG_HINTER - PSH_Hint_Table ps_debug_hint_table = 0; - PSH_HintFunc ps_debug_hint_func = 0; - PSH_Glyph ps_debug_glyph = 0; + PSH_Hint_Table ps_debug_hint_table = NULL; + PSH_HintFunc ps_debug_hint_func = NULL; + PSH_Glyph ps_debug_glyph = NULL; #endif #define COMPUTE_INFLEXS /* compute inflection points to optimize `S' */ /* and similar glyphs */ -#define STRONGER /* slightly increase the contrast of smooth */ - /* hinting */ /*************************************************************************/ @@ -67,13 +65,13 @@ { FT_FREE( table->zones ); table->num_zones = 0; - table->zone = 0; + table->zone = NULL; FT_FREE( table->sort ); FT_FREE( table->hints ); table->num_hints = 0; table->max_hints = 0; - table->sort_global = 0; + table->sort_global = NULL; } @@ -121,7 +119,7 @@ PSH_Hint hint2; - hint->parent = 0; + hint->parent = NULL; for ( ; count > 0; count--, sorted++ ) { hint2 = sorted[0]; @@ -194,7 +192,7 @@ table->sort_global = table->sort + count; table->num_hints = 0; table->num_zones = 0; - table->zone = 0; + table->zone = NULL; /* initialize the `table->hints' array */ { @@ -781,7 +779,7 @@ * It turns out though that minimizing the total number of lit * pixels is also important, so position C), with one edge * aligned with a pixel boundary is actually preferable - * to A). There are also more possibile positions for C) than + * to A). There are also more possible positions for C) than * for A) or B), so it involves less distortion of the overall * character shape. */ @@ -804,7 +802,7 @@ } /* We choose between B) and C) above based on the amount - * of fractinal stem width; for small amounts, choose + * of fractional stem width; for small amounts, choose * C) always, for large amounts, B) always, and inbetween, * pick whichever one involves less stem movement. */ @@ -890,9 +888,6 @@ /*************************************************************************/ /*************************************************************************/ -#define PSH_ZONE_MIN -3200000L -#define PSH_ZONE_MAX +3200000L - #define xxDEBUG_ZONES @@ -910,10 +905,6 @@ zone->max ); } -#else - -#define psh_print_zone( x ) do { } while ( 0 ) - #endif /* DEBUG_ZONES */ @@ -925,103 +916,9 @@ /*************************************************************************/ /*************************************************************************/ -#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 @@ -1149,7 +1046,7 @@ glyph->num_points = 0; glyph->num_contours = 0; - glyph->memory = 0; + glyph->memory = NULL; } @@ -1274,8 +1171,8 @@ FT_NEW_ARRAY( glyph->contours, outline->n_contours ) ) goto Exit; - glyph->num_points = outline->n_points; - glyph->num_contours = outline->n_contours; + glyph->num_points = (FT_UInt)outline->n_points; + glyph->num_contours = (FT_UInt)outline->n_contours; { FT_UInt first = 0, next, n; @@ -1285,15 +1182,15 @@ for ( n = 0; n < glyph->num_contours; n++ ) { - FT_Int count; + FT_UInt count; PSH_Point point; - next = outline->contours[n] + 1; + next = (FT_UInt)outline->contours[n] + 1; count = next - first; contour->start = points + first; - contour->count = (FT_UInt)count; + contour->count = count; if ( count > 0 ) { @@ -1406,7 +1303,6 @@ point = first; before = point; - after = point; do { @@ -1697,16 +1593,12 @@ mask++; for ( ; num_masks > 1; num_masks--, mask++ ) { - FT_UInt next; - FT_Int count; + FT_UInt next = FT_MIN( mask->end_point, glyph->num_points ); - next = mask->end_point > glyph->num_points - ? glyph->num_points - : mask->end_point; - count = next - first; - if ( count > 0 ) + if ( next > first ) { + FT_UInt count = next - first; PSH_Point point = glyph->points + first; @@ -2049,7 +1941,7 @@ /* count the number of strong points in this contour */ next = start + contour->count; fit_count = 0; - first = 0; + first = NULL; for ( point = start; point < next; point++ ) if ( psh_point_is_fitted( point ) ) @@ -2079,8 +1971,6 @@ start = first; do { - point = first; - /* skip consecutive fitted points */ for (;;) { diff --git a/drivers/freetype/src/pshinter/pshalgo.h b/drivers/freetype/src/pshinter/pshalgo.h index c70f31ea94..f1bda65013 100644 --- a/drivers/freetype/src/pshinter/pshalgo.h +++ b/drivers/freetype/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (specification). */ /* */ -/* Copyright 2001-2003, 2008, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHALGO_H__ -#define __PSHALGO_H__ +#ifndef PSHALGO_H_ +#define PSHALGO_H_ #include "pshrec.h" @@ -30,15 +30,12 @@ FT_BEGIN_HEADER /* handle to Hint structure */ typedef struct PSH_HintRec_* PSH_Hint; - /* hint bit-flags */ - typedef enum PSH_Hint_Flags_ - { - PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, - PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, - PSH_HINT_ACTIVE = 4, - PSH_HINT_FITTED = 8 - } PSH_Hint_Flags; + /* hint bit-flags */ +#define PSH_HINT_GHOST PS_HINT_FLAG_GHOST +#define PSH_HINT_BOTTOM PS_HINT_FLAG_BOTTOM +#define PSH_HINT_ACTIVE 4U +#define PSH_HINT_FITTED 8U #define psh_hint_is_active( x ) ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 ) @@ -49,6 +46,7 @@ FT_BEGIN_HEADER #define psh_hint_deactivate( x ) (x)->flags &= ~PSH_HINT_ACTIVE #define psh_hint_set_fitted( x ) (x)->flags |= PSH_HINT_FITTED + /* hint structure */ typedef struct PSH_HintRec_ { @@ -112,14 +110,12 @@ FT_BEGIN_HEADER #define PSH_DIR_IS_VERTICAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL ) - /* the following bit-flags are computed once by the glyph */ - /* analyzer, for both dimensions */ - enum - { - PSH_POINT_OFF = 1, /* point is off the curve */ - PSH_POINT_SMOOTH = 2, /* point is smooth */ - PSH_POINT_INFLEX = 4 /* point is inflection */ - }; + /* the following bit-flags are computed once by the glyph */ + /* analyzer, for both dimensions */ +#define PSH_POINT_OFF 1U /* point is off the curve */ +#define PSH_POINT_SMOOTH 2U /* point is smooth */ +#define PSH_POINT_INFLEX 4U /* point is inflection */ + #define psh_point_is_smooth( p ) ( (p)->flags & PSH_POINT_SMOOTH ) #define psh_point_is_off( p ) ( (p)->flags & PSH_POINT_OFF ) @@ -129,17 +125,16 @@ FT_BEGIN_HEADER #define psh_point_set_off( p ) (p)->flags |= PSH_POINT_OFF #define psh_point_set_inflex( p ) (p)->flags |= PSH_POINT_INFLEX + /* the following bit-flags are re-computed for each dimension */ - enum - { - PSH_POINT_STRONG = 16, /* point is strong */ - PSH_POINT_FITTED = 32, /* point is already fitted */ - PSH_POINT_EXTREMUM = 64, /* point is local extremum */ - PSH_POINT_POSITIVE = 128, /* extremum has positive contour flow */ - PSH_POINT_NEGATIVE = 256, /* extremum has negative contour flow */ - PSH_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */ - PSH_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */ - }; +#define PSH_POINT_STRONG 16U /* point is strong */ +#define PSH_POINT_FITTED 32U /* point is already fitted */ +#define PSH_POINT_EXTREMUM 64U /* point is local extremum */ +#define PSH_POINT_POSITIVE 128U /* extremum has positive contour flow */ +#define PSH_POINT_NEGATIVE 256U /* extremum has negative contour flow */ +#define PSH_POINT_EDGE_MIN 512U /* point is aligned to left/bottom stem edge */ +#define PSH_POINT_EDGE_MAX 1024U /* point is aligned to top/right stem edge */ + #define psh_point_is_strong( p ) ( (p)->flags2 & PSH_POINT_STRONG ) #define psh_point_is_fitted( p ) ( (p)->flags2 & PSH_POINT_FITTED ) @@ -240,7 +235,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHALGO_H__ */ +#endif /* PSHALGO_H_ */ /* END */ diff --git a/drivers/freetype/src/pshinter/pshglob.c b/drivers/freetype/src/pshinter/pshglob.c index 9285efc9e1..2ac5ef1558 100644 --- a/drivers/freetype/src/pshinter/pshglob.c +++ b/drivers/freetype/src/pshinter/pshglob.c @@ -5,7 +5,7 @@ /* PostScript hinter global hinting management (body). */ /* Inspired by the new auto-hinter module. */ /* */ -/* Copyright 2001-2004, 2006, 2010, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -23,7 +23,7 @@ #include "pshglob.h" #ifdef DEBUG_HINTER - PSH_Globals ps_debug_globals = 0; + PSH_Globals ps_debug_globals = NULL; #endif @@ -80,7 +80,7 @@ #if 0 - /* org_width is is font units, result in device pixels, 26.6 format */ + /* org_width is in font units, result in device pixels, 26.6 format */ FT_LOCAL_DEF( FT_Pos ) psh_dimension_snap_width( PSH_Dimension dimension, FT_Int org_width ) @@ -240,7 +240,7 @@ FT_Int family ) { PSH_Blue_Table top_table, bot_table; - FT_Int count_top, count_bot; + FT_UInt count_top, count_bot; if ( family ) @@ -339,7 +339,7 @@ bot = zone[1].org_bottom; delta = bot - top; - if ( delta < 2 * fuzz ) + if ( delta / 2 < fuzz ) zone[0].org_top = zone[1].org_bottom = top + delta / 2; else { @@ -369,7 +369,7 @@ { FT_UInt count; FT_UInt num; - PSH_Blue_Table table = 0; + PSH_Blue_Table table = NULL; /* */ /* Determine whether we need to suppress overshoots or */ @@ -635,7 +635,7 @@ FT_FREE( globals ); #ifdef DEBUG_HINTER - ps_debug_globals = 0; + ps_debug_globals = NULL; #endif } } @@ -750,14 +750,14 @@ } - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) psh_globals_set_scale( PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, FT_Fixed x_delta, FT_Fixed y_delta ) { - PSH_Dimension dim = &globals->dimension[0]; + PSH_Dimension dim; dim = &globals->dimension[0]; @@ -780,8 +780,6 @@ psh_globals_scale_widths( globals, 1 ); psh_blues_scale_zones( &globals->blues, y_scale, y_delta ); } - - return 0; } diff --git a/drivers/freetype/src/pshinter/pshglob.h b/drivers/freetype/src/pshinter/pshglob.h index c511626157..45c957b6ef 100644 --- a/drivers/freetype/src/pshinter/pshglob.h +++ b/drivers/freetype/src/pshinter/pshglob.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter global hinting management. */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHGLOB_H__ -#define __PSHGLOB_H__ +#ifndef PSHGLOB_H_ +#define PSHGLOB_H_ #include FT_FREETYPE_H @@ -167,7 +167,7 @@ FT_BEGIN_HEADER FT_Int org_width ); #endif - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) psh_globals_set_scale( PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, @@ -190,7 +190,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHGLOB_H__ */ +#endif /* PSHGLOB_H_ */ /* END */ diff --git a/drivers/freetype/src/pshinter/pshinter.c b/drivers/freetype/src/pshinter/pshinter.c index b35a2a91c5..614e0bb3d8 100644 --- a/drivers/freetype/src/pshinter/pshinter.c +++ b/drivers/freetype/src/pshinter/pshinter.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript Hinting module */ /* */ -/* Copyright 2001, 2003 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/pshinter/pshmod.c b/drivers/freetype/src/pshinter/pshmod.c index cdeaca18c9..fa4ad1f564 100644 --- a/drivers/freetype/src/pshinter/pshmod.c +++ b/drivers/freetype/src/pshinter/pshmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hinter module implementation (body). */ /* */ -/* Copyright 2001, 2002, 2007, 2009, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/pshinter/pshmod.h b/drivers/freetype/src/pshinter/pshmod.h index 0ae7e96f54..39112a9561 100644 --- a/drivers/freetype/src/pshinter/pshmod.h +++ b/drivers/freetype/src/pshinter/pshmod.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter module interface (specification). */ /* */ -/* Copyright 2001 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHMOD_H__ -#define __PSHMOD_H__ +#ifndef PSHMOD_H_ +#define PSHMOD_H_ #include <ft2build.h> @@ -33,7 +33,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHMOD_H__ */ +#endif /* PSHMOD_H_ */ /* END */ diff --git a/drivers/freetype/src/pshinter/pshnterr.h b/drivers/freetype/src/pshinter/pshnterr.h index 7cc180f0ca..7a94588b87 100644 --- a/drivers/freetype/src/pshinter/pshnterr.h +++ b/drivers/freetype/src/pshinter/pshnterr.h @@ -4,7 +4,7 @@ /* */ /* PS Hinter error codes (specification only). */ /* */ -/* Copyright 2003, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PSHNTERR_H__ -#define __PSHNTERR_H__ +#ifndef PSHNTERR_H_ +#define PSHNTERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSH_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PSHNTERR_H__ */ +#endif /* PSHNTERR_H_ */ /* END */ diff --git a/drivers/freetype/src/pshinter/pshpic.c b/drivers/freetype/src/pshinter/pshpic.c index 568f4ac4b0..d0a3d8ebc9 100644 --- a/drivers/freetype/src/pshinter/pshpic.c +++ b/drivers/freetype/src/pshinter/pshpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for pshinter module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/pshinter/pshpic.h b/drivers/freetype/src/pshinter/pshpic.h index b46f853113..75ee573544 100644 --- a/drivers/freetype/src/pshinter/pshpic.h +++ b/drivers/freetype/src/pshinter/pshpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for pshinter module. */ /* */ -/* Copyright 2009, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,10 @@ /***************************************************************************/ -#ifndef __PSHPIC_H__ -#define __PSHPIC_H__ +#ifndef PSHPIC_H_ +#define PSHPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H @@ -33,6 +31,8 @@ FT_BEGIN_HEADER #include FT_INTERNAL_POSTSCRIPT_HINTS_H +FT_BEGIN_HEADER + typedef struct PSHinterPIC_ { PSHinter_Interface pshinter_interface; @@ -51,13 +51,13 @@ FT_BEGIN_HEADER FT_Error pshinter_module_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __PSHPIC_H__ */ +#endif /* PSHPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/pshinter/pshrec.c b/drivers/freetype/src/pshinter/pshrec.c index cd66ea869a..d7cc4a0d21 100644 --- a/drivers/freetype/src/pshinter/pshrec.c +++ b/drivers/freetype/src/pshinter/pshrec.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hints recorder (body). */ /* */ -/* Copyright 2001-2004, 2007, 2009, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,7 +31,7 @@ #define FT_COMPONENT trace_pshrec #ifdef DEBUG_HINTER - PS_Hints ps_debug_hints = 0; + PS_Hints ps_debug_hints = NULL; int ps_debug_no_horz_hints = 0; int ps_debug_no_vert_hints = 0; #endif @@ -85,7 +85,7 @@ { FT_Error error = FT_Err_Ok; FT_UInt count; - PS_Hint hint = 0; + PS_Hint hint = NULL; count = table->num_hints; @@ -167,12 +167,12 @@ /* clear a given bit */ static void ps_mask_clear_bit( PS_Mask mask, - FT_Int idx ) + FT_UInt idx ) { FT_Byte* p; - if ( (FT_UInt)idx >= mask->num_bits ) + if ( idx >= mask->num_bits ) return; p = mask->bytes + ( idx >> 3 ); @@ -183,17 +183,14 @@ /* set a given bit, possibly grow the mask */ static FT_Error ps_mask_set_bit( PS_Mask mask, - FT_Int idx, + FT_UInt idx, FT_Memory memory ) { FT_Error error = FT_Err_Ok; FT_Byte* p; - if ( idx < 0 ) - goto Exit; - - if ( (FT_UInt)idx >= mask->num_bits ) + if ( idx >= mask->num_bits ) { error = ps_mask_ensure( mask, idx + 1, memory ); if ( error ) @@ -257,7 +254,7 @@ { FT_UInt count; FT_Error error = FT_Err_Ok; - PS_Mask mask = 0; + PS_Mask mask = NULL; count = table->num_masks; @@ -372,8 +369,8 @@ /* test whether two masks in a table intersect */ static FT_Int ps_mask_table_test_intersect( PS_Mask_Table table, - FT_Int index1, - FT_Int index2 ) + FT_UInt index1, + FT_UInt index2 ) { PS_Mask mask1 = table->masks + index1; PS_Mask mask2 = table->masks + index2; @@ -404,23 +401,25 @@ /* merge two masks, used by ps_mask_table_merge_all */ static FT_Error ps_mask_table_merge( PS_Mask_Table table, - FT_Int index1, - FT_Int index2, + FT_UInt index1, + FT_UInt index2, FT_Memory memory ) { - FT_UInt temp; FT_Error error = FT_Err_Ok; /* swap index1 and index2 so that index1 < index2 */ if ( index1 > index2 ) { + FT_UInt temp; + + temp = index1; index1 = index2; index2 = temp; } - if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks ) + if ( index1 < index2 && index2 < table->num_masks ) { /* we need to merge the bitsets of index1 and index2 with a */ /* simple union */ @@ -453,7 +452,7 @@ /* merge (unite) the bitsets */ read = mask2->bytes; write = mask1->bytes; - pos = (FT_UInt)( ( count2 + 7 ) >> 3 ); + pos = ( count2 + 7 ) >> 3; for ( ; pos > 0; pos-- ) { @@ -468,14 +467,17 @@ mask2->num_bits = 0; mask2->end_point = 0; - delta = table->num_masks - 1 - index2; /* number of masks to move */ + /* number of masks to move */ + delta = (FT_Int)( table->num_masks - 1 - index2 ); if ( delta > 0 ) { /* move to end of table for reuse */ PS_MaskRec dummy = *mask2; - ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) ); + ft_memmove( mask2, + mask2 + 1, + (FT_UInt)delta * sizeof ( PS_MaskRec ) ); mask2[delta] = dummy; } @@ -502,13 +504,19 @@ FT_Error error = FT_Err_Ok; - for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) + /* both loops go down to 0, thus FT_Int for index1 and index2 */ + for ( index1 = (FT_Int)table->num_masks - 1; index1 > 0; index1-- ) { for ( index2 = index1 - 1; index2 >= 0; index2-- ) { - if ( ps_mask_table_test_intersect( table, index1, index2 ) ) + if ( ps_mask_table_test_intersect( table, + (FT_UInt)index1, + (FT_UInt)index2 ) ) { - error = ps_mask_table_merge( table, index2, index1, memory ); + error = ps_mask_table_merge( table, + (FT_UInt)index2, + (FT_UInt)index1, + memory ); if ( error ) goto Exit; @@ -670,8 +678,8 @@ { PS_Mask mask; FT_UInt idx; - FT_UInt max = dim->hints.num_hints; - PS_Hint hint = dim->hints.hints; + FT_UInt max = dim->hints.num_hints; + PS_Hint hint = dim->hints.hints; for ( idx = 0; idx < max; idx++, hint++ ) @@ -742,17 +750,26 @@ } /* now, set the bits for our hints in the counter mask */ - error = ps_mask_set_bit( counter, hint1, memory ); - if ( error ) - goto Exit; + if ( hint1 >= 0 ) + { + error = ps_mask_set_bit( counter, (FT_UInt)hint1, memory ); + if ( error ) + goto Exit; + } - error = ps_mask_set_bit( counter, hint2, memory ); - if ( error ) - goto Exit; + if ( hint2 >= 0 ) + { + error = ps_mask_set_bit( counter, (FT_UInt)hint2, memory ); + if ( error ) + goto Exit; + } - error = ps_mask_set_bit( counter, hint3, memory ); - if ( error ) - goto Exit; + if ( hint3 >= 0 ) + { + error = ps_mask_set_bit( counter, (FT_UInt)hint3, memory ); + if ( error ) + goto Exit; + } Exit: return error; @@ -793,17 +810,16 @@ ps_dimension_done( &hints->dimension[1], memory ); hints->error = FT_Err_Ok; - hints->memory = 0; + hints->memory = NULL; } - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) ps_hints_init( PS_Hints hints, FT_Memory memory ) { FT_MEM_ZERO( hints, sizeof ( *hints ) ); hints->memory = memory; - return FT_Err_Ok; } @@ -812,78 +828,57 @@ ps_hints_open( PS_Hints hints, PS_Hint_Type hint_type ) { - switch ( hint_type ) - { - case PS_HINT_TYPE_1: - case PS_HINT_TYPE_2: - hints->error = FT_Err_Ok; - hints->hint_type = hint_type; - - ps_dimension_init( &hints->dimension[0] ); - ps_dimension_init( &hints->dimension[1] ); - break; + hints->error = FT_Err_Ok; + hints->hint_type = hint_type; - default: - hints->error = FT_THROW( Invalid_Argument ); - hints->hint_type = hint_type; - - FT_TRACE0(( "ps_hints_open: invalid charstring type\n" )); - break; - } + ps_dimension_init( &hints->dimension[0] ); + ps_dimension_init( &hints->dimension[1] ); } /* add one or more stems to the current hints table */ static void ps_hints_stem( PS_Hints hints, - FT_Int dimension, - FT_UInt count, + FT_UInt dimension, + FT_Int count, FT_Long* stems ) { - if ( !hints->error ) - { - /* limit "dimension" to 0..1 */ - if ( dimension < 0 || dimension > 1 ) - { - FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", - dimension )); - dimension = ( dimension != 0 ); - } + PS_Dimension dim; - /* record the stems in the current hints/masks table */ - switch ( hints->hint_type ) - { - case PS_HINT_TYPE_1: /* Type 1 "hstem" or "vstem" operator */ - case PS_HINT_TYPE_2: /* Type 2 "hstem" or "vstem" operator */ - { - PS_Dimension dim = &hints->dimension[dimension]; + if ( hints->error ) + return; - for ( ; count > 0; count--, stems += 2 ) - { - FT_Error error; - FT_Memory memory = hints->memory; + /* limit "dimension" to 0..1 */ + if ( dimension > 1 ) + { + FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", + dimension )); + dimension = ( dimension != 0 ); + } + /* record the stems in the current hints/masks table */ + /* (Type 1 & 2's `hstem' or `vstem' operators) */ + dim = &hints->dimension[dimension]; - error = ps_dimension_add_t1stem( - dim, (FT_Int)stems[0], (FT_Int)stems[1], - memory, NULL ); - if ( error ) - { - FT_ERROR(( "ps_hints_stem: could not add stem" - " (%d,%d) to hints table\n", stems[0], stems[1] )); + for ( ; count > 0; count--, stems += 2 ) + { + FT_Error error; + FT_Memory memory = hints->memory; - hints->error = error; - return; - } - } - break; - } - default: - FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n", - hints->hint_type )); - break; + error = ps_dimension_add_t1stem( dim, + (FT_Int)stems[0], + (FT_Int)stems[1], + memory, + NULL ); + if ( error ) + { + FT_ERROR(( "ps_hints_stem: could not add stem" + " (%d,%d) to hints table\n", stems[0], stems[1] )); + + hints->error = error; + return; } } } @@ -892,7 +887,7 @@ /* add one Type1 counter stem to the current hints table */ static void ps_hints_t1stem3( PS_Hints hints, - FT_Int dimension, + FT_UInt dimension, FT_Fixed* stems ) { FT_Error error = FT_Err_Ok; @@ -907,7 +902,7 @@ /* limit "dimension" to 0..1 */ - if ( dimension < 0 || dimension > 1 ) + if ( dimension > 1 ) { FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n", dimension )); @@ -1129,7 +1124,7 @@ static void t1_hints_stem( T1_Hints hints, - FT_Int dimension, + FT_UInt dimension, FT_Fixed* coords ) { FT_Pos stems[2]; @@ -1173,12 +1168,12 @@ static void t2_hints_stems( T2_Hints hints, - FT_Int dimension, + FT_UInt dimension, FT_Int count, FT_Fixed* coords ) { - FT_Pos stems[32], y, n; - FT_Int total = count; + FT_Pos stems[32], y; + FT_Int total = count, n; y = 0; diff --git a/drivers/freetype/src/pshinter/pshrec.h b/drivers/freetype/src/pshinter/pshrec.h index dcb3197f94..97e6f0ed51 100644 --- a/drivers/freetype/src/pshinter/pshrec.h +++ b/drivers/freetype/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001, 2002, 2003, 2006, 2008 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,8 @@ /**************************************************************************/ -#ifndef __PSHREC_H__ -#define __PSHREC_H__ +#ifndef PSHREC_H_ +#define PSHREC_H_ #include <ft2build.h> @@ -61,12 +61,8 @@ FT_BEGIN_HEADER /* hint flags */ - typedef enum PS_Hint_Flags_ - { - PS_HINT_FLAG_GHOST = 1, - PS_HINT_FLAG_BOTTOM = 2 - - } PS_Hint_Flags; +#define PS_HINT_FLAG_GHOST 1U +#define PS_HINT_FLAG_BOTTOM 2U /* hint descriptor */ @@ -141,7 +137,7 @@ FT_BEGIN_HEADER /* */ /* initialize hints recorder */ - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) ps_hints_init( PS_Hints hints, FT_Memory memory ); @@ -170,7 +166,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PS_HINTER_RECORD_H__ */ +#endif /* PSHREC_H_ */ /* END */ diff --git a/drivers/freetype/src/pshinter/rules.mk b/drivers/freetype/src/pshinter/rules.mk index 888ece1058..67ecf7862f 100644 --- a/drivers/freetype/src/pshinter/rules.mk +++ b/drivers/freetype/src/pshinter/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2001, 2003, 2011 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ PSHINTER_DIR := $(SRC_DIR)/pshinter # compilation flags for the driver # -PSHINTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) +PSHINTER_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # PSHINTER driver sources (i.e., C files) diff --git a/drivers/freetype/src/psnames/Jamfile b/drivers/freetype/src/psnames/Jamfile index 06c0dda66f..35b8a99c8f 100644 --- a/drivers/freetype/src/psnames/Jamfile +++ b/drivers/freetype/src/psnames/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/psnames Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,9 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psnames ; if $(FT2_MULTI) { - _sources = psmodule pspic ; + _sources = psmodule + pspic + ; } else { diff --git a/drivers/freetype/src/psnames/module.mk b/drivers/freetype/src/psnames/module.mk index a6e908257c..ba29af813c 100644 --- a/drivers/freetype/src/psnames/module.mk +++ b/drivers/freetype/src/psnames/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/psnames/psmodule.c b/drivers/freetype/src/psnames/psmodule.c index 0a5bcb7d2a..345402d7cc 100644 --- a/drivers/freetype/src/psnames/psmodule.c +++ b/drivers/freetype/src/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2003, 2005-2008, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -312,7 +312,7 @@ /* we first allocate the table */ table->num_maps = 0; - table->maps = 0; + table->maps = NULL; if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) { @@ -525,31 +525,31 @@ FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - (PS_Unicode_ValueFunc) ps_unicode_value, - (PS_Unicodes_InitFunc) ps_unicodes_init, - (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, - (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, + (PS_Unicode_ValueFunc) ps_unicode_value, /* unicode_value */ + (PS_Unicodes_InitFunc) ps_unicodes_init, /* unicodes_init */ + (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, /* unicodes_char_index */ + (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, /* unicodes_char_next */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ - t1_standard_encoding, - t1_expert_encoding ) + t1_standard_encoding, /* adobe_std_encoding */ + t1_expert_encoding ) /* adobe_expert_encoding */ #else FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - NULL, - NULL, - NULL, - NULL, + NULL, /* unicode_value */ + NULL, /* unicodes_init */ + NULL, /* unicodes_char_index */ + NULL, /* unicodes_char_next */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ - t1_standard_encoding, - t1_expert_encoding ) + t1_standard_encoding, /* adobe_std_encoding */ + t1_expert_encoding ) /* adobe_expert_encoding */ #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ @@ -563,7 +563,7 @@ psnames_get_service( FT_Module module, const char* service_id ) { - /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */ + /* PSCMAPS_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC FT_Library library; diff --git a/drivers/freetype/src/psnames/psmodule.h b/drivers/freetype/src/psnames/psmodule.h index 28fa14807c..ee3c6cb631 100644 --- a/drivers/freetype/src/psnames/psmodule.h +++ b/drivers/freetype/src/psnames/psmodule.h @@ -4,7 +4,7 @@ /* */ /* High-level PSNames module interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSMODULE_H__ -#define __PSMODULE_H__ +#ifndef PSMODULE_H_ +#define PSMODULE_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSMODULE_H__ */ +#endif /* PSMODULE_H_ */ /* END */ diff --git a/drivers/freetype/src/psnames/psnamerr.h b/drivers/freetype/src/psnames/psnamerr.h index acda7f967e..3a9f65323b 100644 --- a/drivers/freetype/src/psnames/psnamerr.h +++ b/drivers/freetype/src/psnames/psnamerr.h @@ -4,7 +4,7 @@ /* */ /* PS names module error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __PSNAMERR_H__ -#define __PSNAMERR_H__ +#ifndef PSNAMERR_H_ +#define PSNAMERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSnames_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __PSNAMERR_H__ */ +#endif /* PSNAMERR_H_ */ /* END */ diff --git a/drivers/freetype/src/psnames/psnames.c b/drivers/freetype/src/psnames/psnames.c index 1ede225dc9..e7b2c0b5ef 100644 --- a/drivers/freetype/src/psnames/psnames.c +++ b/drivers/freetype/src/psnames/psnames.c @@ -4,7 +4,7 @@ /* */ /* FreeType PSNames module component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/psnames/pspic.c b/drivers/freetype/src/psnames/pspic.c index 3820f65a74..a78ec5aa81 100644 --- a/drivers/freetype/src/psnames/pspic.c +++ b/drivers/freetype/src/psnames/pspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for psnames module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/psnames/pspic.h b/drivers/freetype/src/psnames/pspic.h index 6ff002c603..48348765cf 100644 --- a/drivers/freetype/src/psnames/pspic.h +++ b/drivers/freetype/src/psnames/pspic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for psnames module. */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,14 +16,13 @@ /***************************************************************************/ -#ifndef __PSPIC_H__ -#define __PSPIC_H__ +#ifndef PSPIC_H_ +#define PSPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H + #ifndef FT_CONFIG_OPTION_PIC #define PSCMAPS_SERVICES_GET pscmaps_services @@ -33,6 +32,9 @@ FT_BEGIN_HEADER #include FT_SERVICE_POSTSCRIPT_CMAPS_H + +FT_BEGIN_HEADER + typedef struct PSModulePIC_ { FT_ServiceDescRec* pscmaps_services; @@ -54,13 +56,13 @@ FT_BEGIN_HEADER FT_Error psnames_module_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __PSPIC_H__ */ +#endif /* PSPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/psnames/pstables.h b/drivers/freetype/src/psnames/pstables.h index 0a6637f985..eb827fa5ea 100644 --- a/drivers/freetype/src/psnames/pstables.h +++ b/drivers/freetype/src/psnames/pstables.h @@ -4,7 +4,7 @@ /* */ /* PostScript glyph names. */ /* */ -/* Copyright 2005, 2008, 2011 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/psnames/rules.mk b/drivers/freetype/src/psnames/rules.mk index 4cd39a8ccf..9849f4053a 100644 --- a/drivers/freetype/src/psnames/rules.mk +++ b/drivers/freetype/src/psnames/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003, 2011 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ PSNAMES_DIR := $(SRC_DIR)/psnames # compilation flags for the driver # -PSNAMES_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR)) +PSNAMES_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # PSNames driver sources (i.e., C files) @@ -46,7 +49,7 @@ PSNAMES_DRV_OBJ_S := $(OBJ_DIR)/psnames.$O # PSNames driver source file for single build # -PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psmodule.c +PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psnames.c # PSNames driver - single object diff --git a/drivers/freetype/src/raster/Jamfile b/drivers/freetype/src/raster/Jamfile index 4f60e87c78..2ec88f5601 100644 --- a/drivers/freetype/src/raster/Jamfile +++ b/drivers/freetype/src/raster/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/raster Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,10 @@ SubDir FT2_TOP $(FT2_SRC_DIR) raster ; if $(FT2_MULTI) { - _sources = ftraster ftrend1 rastpic ; + _sources = ftraster + ftrend1 + rastpic + ; } else { diff --git a/drivers/freetype/src/raster/ftmisc.h b/drivers/freetype/src/raster/ftmisc.h index 703155a429..981ce32279 100644 --- a/drivers/freetype/src/raster/ftmisc.h +++ b/drivers/freetype/src/raster/ftmisc.h @@ -5,7 +5,7 @@ /* Miscellaneous macros for stand-alone rasterizer (specification */ /* only). */ /* */ -/* Copyright 2005, 2009, 2010 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -24,8 +24,8 @@ /* */ /***************************************************/ -#ifndef __FTMISC_H__ -#define __FTMISC_H__ +#ifndef FTMISC_H_ +#define FTMISC_H_ /* memset */ @@ -37,7 +37,7 @@ #define FT_LOCAL_DEF( x ) static x - /* from include/freetype2/fttypes.h */ + /* from include/freetype/fttypes.h */ typedef unsigned char FT_Byte; typedef signed int FT_Int; @@ -54,7 +54,7 @@ (FT_ULong)_x4 ) - /* from include/freetype2/ftsystem.h */ + /* from include/freetype/ftsystem.h */ typedef struct FT_MemoryRec_* FT_Memory; @@ -136,7 +136,7 @@ return ( s > 0 ) ? d : -d; } -#endif /* __FTMISC_H__ */ +#endif /* FTMISC_H_ */ /* END */ diff --git a/drivers/freetype/src/raster/ftraster.c b/drivers/freetype/src/raster/ftraster.c index bbd503d97d..0fa2f2687f 100644 --- a/drivers/freetype/src/raster/ftraster.c +++ b/drivers/freetype/src/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2003, 2005, 2007-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,18 +18,18 @@ /*************************************************************************/ /* */ /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* defining the STANDALONE_ macro when compiling it. You also need to */ /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ /* directory. Typically, you should do something like */ /* */ /* - copy `src/raster/ftraster.c' (this file) to your current directory */ /* */ - /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' */ - /* to your current directory */ + /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */ + /* current directory */ /* */ - /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ + /* - compile `ftraster' with the STANDALONE_ macro defined, as in */ /* */ - /* cc -c -D_STANDALONE_ ftraster.c */ + /* cc -c -DSTANDALONE_ ftraster.c */ /* */ /* The renderer can be initialized with a call to */ /* `ft_standard_raster.raster_new'; a bitmap can be generated */ @@ -47,7 +47,11 @@ /* */ /*************************************************************************/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ + + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ +#define FT_RENDER_POOL_SIZE 16384L #define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> @@ -56,7 +60,7 @@ #include "ftmisc.h" #include "ftimage.h" -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include <ft2build.h> #include "ftraster.h" @@ -64,7 +68,7 @@ #include "rastpic.h" -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ /*************************************************************************/ @@ -150,14 +154,6 @@ /* define DEBUG_RASTER if you want to compile a debugging version */ /* #define DEBUG_RASTER */ - /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ - /* 5-levels anti-aliasing */ -/* #define FT_RASTER_OPTION_ANTI_ALIASING */ - - /* The size of the two-lines intermediate bitmap used */ - /* for anti-aliasing, in bytes. */ -#define RASTER_GRAY_LINES 2048 - /*************************************************************************/ /*************************************************************************/ @@ -177,7 +173,7 @@ #define FT_COMPONENT trace_raster -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /* Auxiliary macros for token concatenation. */ #define FT_ERR_XCAT( x, y ) x ## y @@ -199,6 +195,7 @@ #define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ #define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ #define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ #endif #ifndef FT_THROW @@ -227,7 +224,7 @@ raster_done_ \ }; -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include FT_INTERNAL_OBJECTS_H @@ -243,7 +240,7 @@ #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ #ifndef FT_MEM_SET @@ -318,7 +315,7 @@ typedef union Alignment_ { - long l; + Long l; void* p; void (*f)(void); @@ -334,9 +331,9 @@ /* values for the `flags' bit field */ -#define Flow_Up 0x8 -#define Overshoot_Top 0x10 -#define Overshoot_Bottom 0x20 +#define Flow_Up 0x08U +#define Overshoot_Top 0x10U +#define Overshoot_Bottom 0x20U /* States of each line, arc, and profile */ @@ -358,14 +355,14 @@ FT_F26Dot6 X; /* current coordinate during sweep */ PProfile link; /* link to next profile (various purposes) */ PLong offset; /* start of profile's data in render pool */ - unsigned flags; /* Bit 0-2: drop-out mode */ + UShort flags; /* Bit 0-2: drop-out mode */ /* Bit 3: profile orientation (up/down) */ /* Bit 4: is top profile? */ /* Bit 5: is bottom profile? */ - long height; /* profile's height in scanlines */ - long start; /* profile's starting scanline */ + Long height; /* profile's height in scanlines */ + Long start; /* profile's starting scanline */ - unsigned countL; /* number of lines to step before this */ + Int countL; /* number of lines to step before this */ /* profile becomes drawable */ PProfile next; /* next profile in same contour, used */ @@ -387,7 +384,7 @@ #define AlignProfileSize \ - ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) + ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) ) #undef RAS_ARG @@ -451,13 +448,21 @@ #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) #define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) -#define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half ) +#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << ras.scale_shift ) \ + : ( (x) << ras.scale_shift ) ) \ + - ras.precision_half ) #define IS_BOTTOM_OVERSHOOT( x ) \ (Bool)( CEILING( x ) - x >= ras.precision_half ) #define IS_TOP_OVERSHOOT( x ) \ (Bool)( x - FLOOR( x ) >= ras.precision_half ) +#if FT_RENDER_POOL_SIZE > 2048 +#define FT_MAX_BLACK_POOL ( FT_RENDER_POOL_SIZE / sizeof ( Long ) ) +#else +#define FT_MAX_BLACK_POOL ( 2048 / sizeof ( Long ) ) +#endif + /* The most used variables are positioned at the top of the structure. */ /* Thus, their offset can be coded with less opcodes, resulting in a */ /* smaller executable. */ @@ -514,9 +519,6 @@ Short traceIncr; /* sweep's increment in target bitmap */ - Short gray_min_x; /* current min x during gray rendering */ - Short gray_max_x; /* current max x during gray rendering */ - /* dispatch variables */ Function_Sweep_Init* Proc_Sweep_Init; @@ -529,45 +531,19 @@ Bool second_pass; /* indicates whether a horizontal pass */ /* should be performed to control */ /* drop-out accurately when calling */ - /* Render_Glyph. Note that there is */ - /* no horizontal pass during gray */ - /* rendering. */ + /* Render_Glyph. */ TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ black_TBand band_stack[16]; /* band stack used for sub-banding */ Int band_top; /* band stack top */ -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - Byte* grays; - - Byte gray_lines[RASTER_GRAY_LINES]; - /* Intermediate table used to render the */ - /* graylevels pixmaps. */ - /* gray_lines is a buffer holding two */ - /* monochrome scanlines */ - - Short gray_width; /* width in bytes of one monochrome */ - /* intermediate scanline of gray_lines. */ - /* Each gray pixel takes 2 bits long there */ - - /* The gray_lines must hold 2 lines, thus with size */ - /* in bytes of at least `gray_width*2'. */ - -#endif /* FT_RASTER_ANTI_ALIASING */ - }; typedef struct black_TRaster_ { - char* buffer; - long buffer_size; void* memory; - black_PWorker worker; - Byte grays[5]; - Short gray_width; } black_TRaster, *black_PRaster; @@ -583,70 +559,6 @@ #endif /* !FT_STATIC_RASTER */ -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - /* A lookup table used to quickly count set bits in four gray 2x2 */ - /* cells. The values of the table have been produced with the */ - /* following code: */ - /* */ - /* for ( i = 0; i < 256; i++ ) */ - /* { */ - /* l = 0; */ - /* j = i; */ - /* */ - /* for ( c = 0; c < 4; c++ ) */ - /* { */ - /* l <<= 4; */ - /* */ - /* if ( j & 0x80 ) l++; */ - /* if ( j & 0x40 ) l++; */ - /* */ - /* j = ( j << 2 ) & 0xFF; */ - /* } */ - /* printf( "0x%04X", l ); */ - /* } */ - /* */ - - static const short count_table[256] = - { - 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, - 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, - 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, - 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, - 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, - 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, - 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, - 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, - 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, - 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, - 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, - 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, - 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, - 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, - 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, - 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, - 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, - 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, - 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, - 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, - 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, - 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 - }; - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - - /*************************************************************************/ /*************************************************************************/ /** **/ @@ -677,11 +589,11 @@ * approximating it as a straight segment. The default value of 32 (for * low accuracy) corresponds to * - * 32 / 64 == 0.5 pixels , + * 32 / 64 == 0.5 pixels, * * while for the high accuracy case we have * - * 256/ (1 << 12) = 0.0625 pixels . + * 256 / (1 << 12) = 0.0625 pixels. * * `precision_jitter' is an epsilon threshold used in * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier @@ -764,13 +676,13 @@ if ( overshoot ) ras.cProfile->flags |= Overshoot_Bottom; - FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile )); + FT_TRACE6(( " new ascending profile = %p\n", ras.cProfile )); break; case Descending_State: if ( overshoot ) ras.cProfile->flags |= Overshoot_Top; - FT_TRACE6(( "New descending profile = %p\n", ras.cProfile )); + FT_TRACE6(( " new descending profile = %p\n", ras.cProfile )); break; default: @@ -825,7 +737,7 @@ PProfile oldProfile; - FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n", + FT_TRACE6(( " ending profile %p, start = %ld, height = %ld\n", ras.cProfile, ras.cProfile->start, h )); ras.cProfile->height = h; @@ -893,15 +805,14 @@ /* if it is <, simply insert it, ignore if == */ if ( n >= 0 && y > y_turns[n] ) - while ( n >= 0 ) + do { Int y2 = (Int)y_turns[n]; y_turns[n] = y; y = y2; - n--; - } + } while ( --n >= 0 ); if ( n < 0 ) { @@ -942,7 +853,7 @@ if ( n > 1 && p ) { - while ( n > 0 ) + do { Int bottom, top; @@ -970,8 +881,7 @@ return FAILURE; p = p->link; - n--; - } + } while ( --n ); } else ras.fProfile = NULL; @@ -1342,7 +1252,7 @@ start_arc = arc; - while ( arc >= start_arc && e <= e2 ) + do { ras.joint = FALSE; @@ -1375,7 +1285,7 @@ } arc -= degree; } - } + } while ( arc >= start_arc && e <= e2 ); Fin: ras.top = top; @@ -1813,7 +1723,7 @@ static Bool Decompose_Curve( RAS_ARGS UShort first, UShort last, - int flipped ) + Int flipped ) { FT_Vector v_last; FT_Vector v_control; @@ -1824,7 +1734,7 @@ FT_Vector* limit; char* tags; - unsigned tag; /* current point's state */ + UInt tag; /* current point's state */ points = ras.outline.points; @@ -1874,7 +1784,7 @@ v_start.x = ( v_start.x + v_last.x ) / 2; v_start.y = ( v_start.y + v_last.y ) / 2; - v_last = v_start; + /* v_last = v_start; */ } point--; tags--; @@ -2035,10 +1945,10 @@ /* rendering. */ /* */ static Bool - Convert_Glyph( RAS_ARGS int flipped ) + Convert_Glyph( RAS_ARGS Int flipped ) { - int i; - unsigned start; + Int i; + UInt start; ras.fProfile = NULL; @@ -2064,12 +1974,12 @@ ras.state = Unknown_State; ras.gProfile = NULL; - if ( Decompose_Curve( RAS_VARS (unsigned short)start, - ras.outline.contours[i], + if ( Decompose_Curve( RAS_VARS (UShort)start, + (UShort)ras.outline.contours[i], flipped ) ) return FAILURE; - start = ras.outline.contours[i] + 1; + start = (UShort)ras.outline.contours[i] + 1; /* we must now check whether the extreme arcs join or not */ if ( FRAC( ras.lastY ) == 0 && @@ -2083,7 +1993,8 @@ /* to be drawn. */ lastProfile = ras.cProfile; - if ( ras.cProfile->flags & Flow_Up ) + if ( ras.top != ras.cProfile->offset && + ( ras.cProfile->flags & Flow_Up ) ) o = IS_TOP_OVERSHOOT( ras.lastY ); else o = IS_BOTTOM_OVERSHOOT( ras.lastY ); @@ -2207,7 +2118,7 @@ while ( current ) { current->X = *current->offset; - current->offset += current->flags & Flow_Up ? 1 : -1; + current->offset += ( current->flags & Flow_Up ) ? 1 : -1; current->height--; current = current->link; } @@ -2267,10 +2178,7 @@ ras.traceIncr = (Short)-pitch; ras.traceOfs = -*min * pitch; if ( pitch > 0 ) - ras.traceOfs += ( ras.target.rows - 1 ) * pitch; - - ras.gray_min_x = 0; - ras.gray_max_x = 0; + ras.traceOfs += (Long)( ras.target.rows - 1 ) * pitch; } @@ -2284,23 +2192,34 @@ Long e1, e2; Byte* target; + Int dropOutControl = left->flags & 7; + FT_UNUSED( y ); FT_UNUSED( left ); FT_UNUSED( right ); + /* in high-precision mode, we need 12 digits after the comma to */ + /* represent multiples of 1/(1<<12) = 1/4096 */ + FT_TRACE7(( " y=%d x=[%.12f;%.12f], drop-out=%d", + y, + x1 / (double)ras.precision, + x2 / (double)ras.precision, + dropOutControl )); + /* Drop-out control */ e1 = TRUNC( CEILING( x1 ) ); - if ( x2 - x1 - ras.precision <= ras.precision_jitter ) + if ( dropOutControl != 2 && + x2 - x1 - ras.precision <= ras.precision_jitter ) e2 = e1; else e2 = TRUNC( FLOOR( x2 ) ); if ( e2 >= 0 && e1 < ras.bWidth ) { - int c1, c2; + Int c1, c2; Byte f1, f2; @@ -2309,17 +2228,14 @@ if ( e2 >= ras.bWidth ) e2 = ras.bWidth - 1; + FT_TRACE7(( " -> x=[%d;%d]", e1, e2 )); + c1 = (Short)( e1 >> 3 ); c2 = (Short)( e2 >> 3 ); f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); - if ( ras.gray_min_x > c1 ) - ras.gray_min_x = (short)c1; - if ( ras.gray_max_x < c2 ) - ras.gray_max_x = (short)c2; - target = ras.bTarget + ras.traceOfs + c1; c2 -= c1; @@ -2341,6 +2257,8 @@ else *target |= ( f1 & f2 ); } + + FT_TRACE7(( "\n" )); } @@ -2355,6 +2273,11 @@ Short c1, f1; + FT_TRACE7(( " y=%d x=[%.12f;%.12f]", + y, + x1 / (double)ras.precision, + x2 / (double)ras.precision )); + /* Drop-out control */ /* e2 x2 x1 e1 */ @@ -2387,6 +2310,8 @@ Int dropOutControl = left->flags & 7; + FT_TRACE7(( ", drop-out=%d", dropOutControl )); + if ( e1 == e2 + ras.precision ) { switch ( dropOutControl ) @@ -2433,14 +2358,14 @@ left->height <= 0 && !( left->flags & Overshoot_Top && x2 - x1 >= ras.precision_half ) ) - return; + goto Exit; /* lower stub test */ if ( right->next == left && left->start == y && !( left->flags & Overshoot_Bottom && x2 - x1 >= ras.precision_half ) ) - return; + goto Exit; if ( dropOutControl == 1 ) pxl = e2; @@ -2449,7 +2374,7 @@ break; default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ + goto Exit; /* no drop-out control */ } /* undocumented but confirmed: If the drop-out would result in a */ @@ -2470,26 +2395,26 @@ if ( e1 >= 0 && e1 < ras.bWidth && ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) - return; + goto Exit; } else - return; + goto Exit; } e1 = TRUNC( pxl ); if ( e1 >= 0 && e1 < ras.bWidth ) { + FT_TRACE7(( " -> x=%d (drop-out)", e1 )); + c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); - if ( ras.gray_min_x > c1 ) - ras.gray_min_x = c1; - if ( ras.gray_max_x < c1 ) - ras.gray_max_x = c1; - ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); } + + Exit: + FT_TRACE7(( "\n" )); } @@ -2536,32 +2461,39 @@ Long e1, e2; + FT_TRACE7(( " x=%d y=[%.12f;%.12f]", + y, + x1 / (double)ras.precision, + x2 / (double)ras.precision )); + e1 = CEILING( x1 ); e2 = FLOOR ( x2 ); if ( e1 == e2 ) { - Byte f1; - PByte bits; - - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - e1 = TRUNC( e1 ); - if ( e1 >= 0 && e1 < ras.target.rows ) + if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) { + Byte f1; + PByte bits; PByte p; - p = bits - e1 * ras.target.pitch; + FT_TRACE7(( " -> y=%d (drop-out)", e1 )); + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + p = bits - e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) - p += ( ras.target.rows - 1 ) * ras.target.pitch; + p += (Long)( ras.target.rows - 1 ) * ras.target.pitch; p[0] |= f1; } } + + FT_TRACE7(( "\n" )); } } @@ -2578,6 +2510,11 @@ Byte f1; + FT_TRACE7(( " x=%d y=[%.12f;%.12f]", + y, + x1 / (double)ras.precision, + x2 / (double)ras.precision )); + /* During the horizontal sweep, we only take care of drop-outs */ /* e1 + <-- pixel center */ @@ -2599,6 +2536,8 @@ Int dropOutControl = left->flags & 7; + FT_TRACE7(( ", dropout=%d", dropOutControl )); + if ( e1 == e2 + ras.precision ) { switch ( dropOutControl ) @@ -2620,14 +2559,14 @@ left->height <= 0 && !( left->flags & Overshoot_Top && x2 - x1 >= ras.precision_half ) ) - return; + goto Exit; /* leftmost stub test */ if ( right->next == left && left->start == y && !( left->flags & Overshoot_Bottom && x2 - x1 >= ras.precision_half ) ) - return; + goto Exit; if ( dropOutControl == 1 ) pxl = e2; @@ -2636,7 +2575,7 @@ break; default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ + goto Exit; /* no drop-out control */ } /* undocumented but confirmed: If the drop-out would result in a */ @@ -2644,7 +2583,7 @@ /* bounding box instead */ if ( pxl < 0 ) pxl = e1; - else if ( TRUNC( pxl ) >= ras.target.rows ) + else if ( (ULong)( TRUNC( pxl ) ) >= ras.target.rows ) pxl = e2; /* check that the other pixel isn't set */ @@ -2657,30 +2596,35 @@ bits -= e1 * ras.target.pitch; if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; + bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; - if ( e1 >= 0 && - e1 < ras.target.rows && - *bits & f1 ) - return; + if ( e1 >= 0 && + (ULong)e1 < ras.target.rows && + *bits & f1 ) + goto Exit; } else - return; + goto Exit; } - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - e1 = TRUNC( pxl ); - if ( e1 >= 0 && e1 < ras.target.rows ) + if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) { + FT_TRACE7(( " -> y=%d (drop-out)", e1 )); + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; + bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; bits[0] |= f1; } + + Exit: + FT_TRACE7(( "\n" )); } @@ -2692,249 +2636,6 @@ } -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - - /*************************************************************************/ - /* */ - /* Vertical Gray Sweep Procedure Set */ - /* */ - /* These two routines are used during the vertical gray-levels sweep */ - /* phase by the generic Draw_Sweep() function. */ - /* */ - /* NOTES */ - /* */ - /* - The target pixmap's width *must* be a multiple of 4. */ - /* */ - /* - You have to use the function Vertical_Sweep_Span() for the gray */ - /* span call. */ - /* */ - /*************************************************************************/ - - static void - Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, - Short* max ) - { - Long pitch, byte_len; - - - *min = *min & -2; - *max = ( *max + 3 ) & -2; - - ras.traceOfs = 0; - pitch = ras.target.pitch; - byte_len = -pitch; - ras.traceIncr = (Short)byte_len; - ras.traceG = ( *min / 2 ) * byte_len; - - if ( pitch > 0 ) - { - ras.traceG += ( ras.target.rows - 1 ) * pitch; - byte_len = -byte_len; - } - - ras.gray_min_x = (Short)byte_len; - ras.gray_max_x = -(Short)byte_len; - } - - - static void - Vertical_Gray_Sweep_Step( RAS_ARG ) - { - short* count = (short*)count_table; - Byte* grays; - - - ras.traceOfs += ras.gray_width; - - if ( ras.traceOfs > ras.gray_width ) - { - PByte pix; - - - pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; - grays = ras.grays; - - if ( ras.gray_max_x >= 0 ) - { - Long last_pixel = ras.target.width - 1; - Int last_cell = last_pixel >> 2; - Int last_bit = last_pixel & 3; - Bool over = 0; - - Int c1, c2; - PByte bit, bit2; - - - if ( ras.gray_max_x >= last_cell && last_bit != 3 ) - { - ras.gray_max_x = last_cell - 1; - over = 1; - } - - if ( ras.gray_min_x < 0 ) - ras.gray_min_x = 0; - - bit = ras.bTarget + ras.gray_min_x; - bit2 = bit + ras.gray_width; - - c1 = ras.gray_max_x - ras.gray_min_x; - - while ( c1 >= 0 ) - { - c2 = count[*bit] + count[*bit2]; - - if ( c2 ) - { - pix[0] = grays[(c2 >> 12) & 0x000F]; - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - pix[3] = grays[ c2 & 0x000F]; - - *bit = 0; - *bit2 = 0; - } - - bit++; - bit2++; - pix += 4; - c1--; - } - - if ( over ) - { - c2 = count[*bit] + count[*bit2]; - if ( c2 ) - { - switch ( last_bit ) - { - case 2: - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - case 1: - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - default: - pix[0] = grays[(c2 >> 12) & 0x000F]; - } - - *bit = 0; - *bit2 = 0; - } - } - } - - ras.traceOfs = 0; - ras.traceG += ras.traceIncr; - - ras.gray_min_x = 32000; - ras.gray_max_x = -32000; - } - } - - - static void - Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - /* nothing, really */ - FT_UNUSED_RASTER; - FT_UNUSED( y ); - FT_UNUSED( x1 ); - FT_UNUSED( x2 ); - FT_UNUSED( left ); - FT_UNUSED( right ); - } - - - static void - Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - PByte pixel; - - - /* During the horizontal sweep, we only take care of drop-outs */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - - if ( e1 > e2 ) - { - Int dropOutControl = left->flags & 7; - - - if ( e1 == e2 + ras.precision ) - { - switch ( dropOutControl ) - { - case 0: /* simple drop-outs including stubs */ - e1 = e2; - break; - - case 4: /* smart drop-outs including stubs */ - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; - - case 1: /* simple drop-outs excluding stubs */ - case 5: /* smart drop-outs excluding stubs */ - /* see Vertical_Sweep_Drop for details */ - - /* rightmost stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* leftmost stub test */ - if ( right->next == left && left->start == y ) - return; - - if ( dropOutControl == 1 ) - e1 = e2; - else - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - - break; - - default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ - } - } - else - return; - } - - if ( e1 >= 0 ) - { - Byte color; - - - if ( x2 - x1 >= ras.precision_half ) - color = ras.grays[2]; - else - color = ras.grays[1]; - - e1 = TRUNC( e1 ) / 2; - if ( e1 < ras.target.rows ) - { - pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; - if ( ras.target.pitch > 0 ) - pixel += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( pixel[0] == ras.grays[0] ) - pixel[0] = color; - } - } - } - - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - /*************************************************************************/ /* */ /* Generic Sweep Drawing routine */ @@ -3004,7 +2705,7 @@ while ( P ) { - P->countL = (UShort)( P->start - min_Y ); + P->countL = P->start - min_Y; P = P->link; } @@ -3267,7 +2968,7 @@ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ - FT_LOCAL_DEF( FT_Error ) + static FT_Error Render_Glyph( RAS_ARG ) { FT_Error error; @@ -3290,10 +2991,12 @@ ras.dropOutControl += 1; } - ras.second_pass = (FT_Byte)( !( ras.outline.flags & - FT_OUTLINE_SINGLE_PASS ) ); + ras.second_pass = (Bool)( !( ras.outline.flags & + FT_OUTLINE_SINGLE_PASS ) ); /* Vertical Sweep */ + FT_TRACE7(( "Vertical pass (ftraster)\n" )); + ras.Proc_Sweep_Init = Vertical_Sweep_Init; ras.Proc_Sweep_Span = Vertical_Sweep_Span; ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; @@ -3301,9 +3004,9 @@ ras.band_top = 0; ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); + ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 ); - ras.bWidth = (unsigned short)ras.target.width; + ras.bWidth = (UShort)ras.target.width; ras.bTarget = (Byte*)ras.target.buffer; if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) @@ -3312,6 +3015,8 @@ /* Horizontal Sweep */ if ( ras.second_pass && ras.dropOutControl != 2 ) { + FT_TRACE7(( "Horizontal pass (ftraster)\n" )); + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; ras.Proc_Sweep_Span = Horizontal_Sweep_Span; ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; @@ -3319,7 +3024,7 @@ ras.band_top = 0; ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); + ras.band_stack[0].y_max = (Short)( ras.target.width - 1 ); if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) return error; @@ -3329,118 +3034,10 @@ } -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Render_Gray_Glyph */ - /* */ - /* <Description> */ - /* Render a glyph with grayscaling. Sub-banding if needed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - Render_Gray_Glyph( RAS_ARG ) - { - Long pixel_width; - FT_Error error; - - - Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift + 1; - - if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) - ras.dropOutControl = 2; - else - { - if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) - ras.dropOutControl = 4; - else - ras.dropOutControl = 0; - - if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) - ras.dropOutControl += 1; - } - - ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); - - /* Vertical Sweep */ - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = 2 * ras.target.rows - 1; - - ras.bWidth = ras.gray_width; - pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); - - if ( ras.bWidth > pixel_width ) - ras.bWidth = pixel_width; - - ras.bWidth = ras.bWidth * 8; - ras.bTarget = (Byte*)ras.gray_lines; - ras.gTarget = (Byte*)ras.target.buffer; - - ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; - ras.Proc_Sweep_Span = Vertical_Sweep_Span; - ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; - ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; - - error = Render_Single_Pass( RAS_VARS 0 ); - if ( error ) - return error; - - /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 2 ) - { - ras.Proc_Sweep_Init = Horizontal_Sweep_Init; - ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; - ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; - ras.Proc_Sweep_Step = Horizontal_Sweep_Step; - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = ras.target.width * 2 - 1; - - error = Render_Single_Pass( RAS_VARS 1 ); - if ( error ) - return error; - } - - return Raster_Err_None; - } - -#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ - - FT_LOCAL_DEF( FT_Error ) - Render_Gray_Glyph( RAS_ARG ) - { - FT_UNUSED_RASTER; - - return FT_THROW( Unsupported ); - } - -#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ - - static void ft_black_init( black_PRaster 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; - - raster->gray_width = RASTER_GRAY_LINES / 2; -#else FT_UNUSED( raster ); -#endif } @@ -3448,7 +3045,7 @@ /**** a static object. *****/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ static int @@ -3475,7 +3072,7 @@ } -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ static int @@ -3509,73 +3106,46 @@ } -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ static void - ft_black_reset( black_PRaster raster, - char* pool_base, - long pool_size ) + ft_black_reset( FT_Raster raster, + PByte pool_base, + ULong pool_size ) { - if ( raster ) - { - if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 ) - { - black_PWorker worker = (black_PWorker)pool_base; - - - raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 ); - raster->buffer_size = (long)( pool_base + pool_size - - (char*)raster->buffer ); - raster->worker = worker; - } - else - { - raster->buffer = NULL; - raster->buffer_size = 0; - raster->worker = NULL; - } - } + FT_UNUSED( raster ); + FT_UNUSED( pool_base ); + FT_UNUSED( pool_size ); } - static void - ft_black_set_mode( black_PRaster raster, - unsigned long mode, - const char* palette ) + static int + ft_black_set_mode( FT_Raster raster, + ULong mode, + void* args ) { -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) - { - /* set 5-levels gray palette */ - 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 - FT_UNUSED( raster ); FT_UNUSED( mode ); - FT_UNUSED( palette ); + FT_UNUSED( args ); -#endif + return 0; } static int - ft_black_render( black_PRaster raster, + ft_black_render( FT_Raster raster, const FT_Raster_Params* params ) { const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; - black_PWorker worker; + black_TWorker worker[1]; + + Long buffer[FT_MAX_BLACK_POOL]; - if ( !raster || !raster->buffer || !raster->buffer_size ) + + if ( !raster ) return FT_THROW( Not_Ini ); if ( !outline ) @@ -3592,12 +3162,13 @@ outline->contours[outline->n_contours - 1] + 1 ) return FT_THROW( Invalid ); - worker = raster->worker; - /* this version of the raster does not support direct rendering, sorry */ if ( params->flags & FT_RASTER_FLAG_DIRECT ) return FT_THROW( Unsupported ); + if ( params->flags & FT_RASTER_FLAG_AA ) + return FT_THROW( Unsupported ); + if ( !target_map ) return FT_THROW( Invalid ); @@ -3608,33 +3179,40 @@ if ( !target_map->buffer ) return FT_THROW( Invalid ); + /* reject too large outline coordinates */ + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + for ( ; vec < limit; vec++ ) + { + if ( vec->x < -0x1000000L || vec->x > 0x1000000L || + vec->y < -0x1000000L || vec->y > 0x1000000L ) + return FT_THROW( Invalid ); + } + } + 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; + worker->buff = buffer; + worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ - FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); -#endif - - return ( params->flags & FT_RASTER_FLAG_AA ) - ? Render_Gray_Glyph( RAS_VAR ) - : Render_Glyph( RAS_VAR ); + return Render_Glyph( RAS_VAR ); } - FT_DEFINE_RASTER_FUNCS( ft_standard_raster, + FT_DEFINE_RASTER_FUNCS( + ft_standard_raster, + FT_GLYPH_FORMAT_OUTLINE, + (FT_Raster_New_Func) ft_black_new, (FT_Raster_Reset_Func) ft_black_reset, (FT_Raster_Set_Mode_Func)ft_black_set_mode, (FT_Raster_Render_Func) ft_black_render, - (FT_Raster_Done_Func) ft_black_done - ) + (FT_Raster_Done_Func) ft_black_done ) /* END */ diff --git a/drivers/freetype/src/raster/ftraster.h b/drivers/freetype/src/raster/ftraster.h index 80fe46deba..65cd5f9609 100644 --- a/drivers/freetype/src/raster/ftraster.h +++ b/drivers/freetype/src/raster/ftraster.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTRASTER_H__ -#define __FTRASTER_H__ +#ifndef FTRASTER_H_ +#define FTRASTER_H_ #include <ft2build.h> @@ -33,14 +33,14 @@ FT_BEGIN_HEADER /* Uncomment the following line if you are using ftraster.c as a */ /* standalone module, fully independent of FreeType. */ /* */ -/* #define _STANDALONE_ */ +/* #define STANDALONE_ */ FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; FT_END_HEADER -#endif /* __FTRASTER_H__ */ +#endif /* FTRASTER_H_ */ /* END */ diff --git a/drivers/freetype/src/raster/ftrend1.c b/drivers/freetype/src/raster/ftrend1.c index aa7f6d5664..494f112234 100644 --- a/drivers/freetype/src/raster/ftrend1.c +++ b/drivers/freetype/src/raster/ftrend1.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (body). */ /* */ -/* Copyright 1996-2003, 2005, 2006, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -104,7 +104,7 @@ { FT_Error error; FT_Outline* outline; - FT_BBox cbox; + FT_BBox cbox, cbox0; FT_UInt width, height, pitch; FT_Bitmap* bitmap; FT_Memory memory; @@ -120,38 +120,11 @@ } /* check rendering mode */ -#ifndef FT_CONFIG_OPTION_PIC if ( mode != FT_RENDER_MODE_MONO ) { /* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz == &ft_raster1_renderer_class ) - return FT_THROW( Cannot_Render_Glyph ); + return FT_THROW( Cannot_Render_Glyph ); } - else - { - /* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz == &ft_raster5_renderer_class ) - return FT_THROW( Cannot_Render_Glyph ); - } -#else /* FT_CONFIG_OPTION_PIC */ - /* When PIC is enabled, we cannot get to the class object */ - /* so instead we check the final character in the class name */ - /* ("raster5" or "raster1"). Yes this is a hack. */ - /* The "correct" thing to do is have different render function */ - /* for each of the classes. */ - if ( mode != FT_RENDER_MODE_MONO ) - { - /* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz->root.module_name[6] == '1' ) - return FT_THROW( Cannot_Render_Glyph ); - } - else - { - /* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz->root.module_name[6] == '5' ) - return FT_THROW( Cannot_Render_Glyph ); - } -#endif /* FT_CONFIG_OPTION_PIC */ outline = &slot->outline; @@ -160,14 +133,14 @@ FT_Outline_Translate( outline, origin->x, origin->y ); /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); + FT_Outline_Get_CBox( outline, &cbox0 ); /* undocumented but confirmed: bbox values get rounded */ #if 1 - cbox.xMin = FT_PIX_ROUND( cbox.xMin ); - cbox.yMin = FT_PIX_ROUND( cbox.yMin ); - cbox.xMax = FT_PIX_ROUND( cbox.xMax ); - cbox.yMax = FT_PIX_ROUND( cbox.yMax ); + cbox.xMin = FT_PIX_ROUND( cbox0.xMin ); + cbox.yMin = FT_PIX_ROUND( cbox0.yMin ); + cbox.xMax = FT_PIX_ROUND( cbox0.xMax ); + cbox.yMax = FT_PIX_ROUND( cbox0.yMax ); #else cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); @@ -175,8 +148,28 @@ cbox.yMax = FT_PIX_CEIL( cbox.yMax ); #endif + /* If either `width' or `height' round to 0, try */ + /* explicitly rounding up/down. In the case of */ + /* glyphs containing only one very narrow feature, */ + /* this gives the drop-out compensation in the scan */ + /* conversion code a chance to do its stuff. */ width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + if ( width == 0 ) + { + cbox.xMin = FT_PIX_FLOOR( cbox0.xMin ); + cbox.xMax = FT_PIX_CEIL( cbox0.xMax ); + + width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + } + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + if ( height == 0 ) + { + cbox.yMin = FT_PIX_FLOOR( cbox0.yMin ); + cbox.yMax = FT_PIX_CEIL( cbox0.yMax ); + + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + } if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX ) { @@ -194,23 +187,12 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - /* allocate new one, depends on pixel format */ - if ( !( mode & FT_RENDER_MODE_MONO ) ) - { - /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ - pitch = FT_PAD_CEIL( width, 4 ); - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->num_grays = 256; - } - else - { - pitch = ( ( width + 15 ) >> 4 ) << 1; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - } + pitch = ( ( width + 15 ) >> 4 ) << 1; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; bitmap->width = width; bitmap->rows = height; - bitmap->pitch = pitch; + bitmap->pitch = (int)pitch; if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) goto Exit; @@ -225,9 +207,6 @@ params.source = outline; params.flags = 0; - if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) - params.flags |= FT_RASTER_FLAG_AA; - /* render outline into the bitmap */ error = render->raster_render( render->raster, ¶ms ); @@ -272,35 +251,4 @@ ) - /* This renderer is _NOT_ part of the default modules; you will need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - /* */ - FT_DEFINE_RENDERER( ft_raster5_renderer_class, - - FT_MODULE_RENDERER, - sizeof ( FT_RendererRec ), - - "raster5", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , - - FT_GLYPH_FORMAT_OUTLINE, - - (FT_Renderer_RenderFunc) ft_raster1_render, - (FT_Renderer_TransformFunc)ft_raster1_transform, - (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, - (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - - (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET - ) - - /* END */ diff --git a/drivers/freetype/src/raster/ftrend1.h b/drivers/freetype/src/raster/ftrend1.h index 4cf128622a..a431f185d2 100644 --- a/drivers/freetype/src/raster/ftrend1.h +++ b/drivers/freetype/src/raster/ftrend1.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTREND1_H__ -#define __FTREND1_H__ +#ifndef FTREND1_H_ +#define FTREND1_H_ #include <ft2build.h> @@ -29,16 +29,10 @@ FT_BEGIN_HEADER FT_DECLARE_RENDERER( ft_raster1_renderer_class ) - /* this renderer is _NOT_ part of the default modules, you'll need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - /* */ - FT_DECLARE_RENDERER( ft_raster5_renderer_class ) - FT_END_HEADER -#endif /* __FTREND1_H__ */ +#endif /* FTREND1_H_ */ /* END */ diff --git a/drivers/freetype/src/raster/module.mk b/drivers/freetype/src/raster/module.mk index cbff5df96e..f4a5f8e838 100644 --- a/drivers/freetype/src/raster/module.mk +++ b/drivers/freetype/src/raster/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/raster/raster.c b/drivers/freetype/src/raster/raster.c index 1202a116cd..5b21dcbc6a 100644 --- a/drivers/freetype/src/raster/raster.c +++ b/drivers/freetype/src/raster/raster.c @@ -4,7 +4,7 @@ /* */ /* FreeType monochrome rasterer module component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/raster/rasterrs.h b/drivers/freetype/src/raster/rasterrs.h index ab85c002a3..44da7fca56 100644 --- a/drivers/freetype/src/raster/rasterrs.h +++ b/drivers/freetype/src/raster/rasterrs.h @@ -4,7 +4,7 @@ /* */ /* monochrome renderer error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __RASTERRS_H__ -#define __RASTERRS_H__ +#ifndef RASTERRS_H_ +#define RASTERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Raster_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __RASTERRS_H__ */ +#endif /* RASTERRS_H_ */ /* END */ diff --git a/drivers/freetype/src/raster/rastpic.c b/drivers/freetype/src/raster/rastpic.c index 5e9f7cc9c4..dcfa92eef7 100644 --- a/drivers/freetype/src/raster/rastpic.c +++ b/drivers/freetype/src/raster/rastpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for raster module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,8 +59,9 @@ FT_Memory memory = library->memory; - /* since this function also serves raster5 renderer, */ - /* it implements reference counting */ + /* XXX: since this function also served the no longer available */ + /* raster5 renderer it uses reference counting, which could */ + /* be removed now */ if ( pic_container->raster ) { ((RasterPIC*)pic_container->raster)->ref_count++; @@ -82,21 +83,6 @@ return error; } - - /* re-route these init and free functions to the above functions */ - FT_Error - ft_raster5_renderer_class_pic_init( FT_Library library ) - { - return ft_raster1_renderer_class_pic_init( library ); - } - - - void - ft_raster5_renderer_class_pic_free( FT_Library library ) - { - ft_raster1_renderer_class_pic_free( library ); - } - #endif /* FT_CONFIG_OPTION_PIC */ diff --git a/drivers/freetype/src/raster/rastpic.h b/drivers/freetype/src/raster/rastpic.h index e0ddba624e..7815876383 100644 --- a/drivers/freetype/src/raster/rastpic.h +++ b/drivers/freetype/src/raster/rastpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for raster module. */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,15 +16,15 @@ /***************************************************************************/ -#ifndef __RASTPIC_H__ -#define __RASTPIC_H__ +#ifndef RASTPIC_H_ +#define RASTPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H +FT_BEGIN_HEADER + #ifndef FT_CONFIG_OPTION_PIC #define FT_STANDARD_RASTER_GET ft_standard_raster @@ -48,22 +48,16 @@ FT_BEGIN_HEADER void ft_raster1_renderer_class_pic_free( FT_Library library ); - void - ft_raster5_renderer_class_pic_free( FT_Library library ); - FT_Error ft_raster1_renderer_class_pic_init( FT_Library library ); - FT_Error - ft_raster5_renderer_class_pic_init( FT_Library library ); - #endif /* FT_CONFIG_OPTION_PIC */ /* */ FT_END_HEADER -#endif /* __RASTPIC_H__ */ +#endif /* RASTPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/raster/rules.mk b/drivers/freetype/src/raster/rules.mk index 0e0b5e4ebd..929faa3a95 100644 --- a/drivers/freetype/src/raster/rules.mk +++ b/drivers/freetype/src/raster/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003, 2008, 2009, 2011 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -19,7 +19,10 @@ RASTER_DIR := $(SRC_DIR)/raster # compilation flags for the driver # -RASTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR)) +RASTER_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # raster driver sources (i.e., C files) diff --git a/drivers/freetype/src/sfnt/Jamfile b/drivers/freetype/src/sfnt/Jamfile index cb20b1b04b..089cc269ba 100644 --- a/drivers/freetype/src/sfnt/Jamfile +++ b/drivers/freetype/src/sfnt/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/sfnt Jamfile # -# Copyright 2001, 2002, 2004, 2005 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,18 @@ SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; if $(FT2_MULTI) { - _sources = sfobjs sfdriver ttcmap ttmtx ttpost ttload ttsbit ttkern ttbdf sfntpic ; + _sources = pngshim + sfdriver + sfntpic + sfobjs + ttbdf + ttcmap + ttkern + ttload + ttmtx + ttpost + ttsbit + ; } else { diff --git a/drivers/freetype/src/sfnt/module.mk b/drivers/freetype/src/sfnt/module.mk index 95fd6a3143..ca19e096a3 100644 --- a/drivers/freetype/src/sfnt/module.mk +++ b/drivers/freetype/src/sfnt/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/sfnt/pngshim.c b/drivers/freetype/src/sfnt/pngshim.c index 408f879c34..2815759ccb 100644 --- a/drivers/freetype/src/sfnt/pngshim.c +++ b/drivers/freetype/src/sfnt/pngshim.c @@ -4,7 +4,8 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013 by Google, Inc. */ +/* Copyright 2013-2016 by */ +/* Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,11 +37,11 @@ /* This code is freely based on cairo-png.c. There's so many ways */ /* to call libpng, and the way cairo does it is defacto standard. */ - static int - multiply_alpha( int alpha, - int color ) + static unsigned int + multiply_alpha( unsigned int alpha, + unsigned int color ) { - int temp = ( alpha * color ) + 0x80; + unsigned int temp = alpha * color + 0x80; return ( temp + ( temp >> 8 ) ) >> 8; @@ -81,10 +82,10 @@ blue = multiply_alpha( alpha, blue ); } - base[0] = blue; - base[1] = green; - base[2] = red; - base[3] = alpha; + base[0] = (unsigned char)blue; + base[1] = (unsigned char)green; + base[2] = (unsigned char)red; + base[3] = (unsigned char)alpha; } } } @@ -109,9 +110,9 @@ unsigned int blue = base[2]; - base[0] = blue; - base[1] = green; - base[2] = red; + base[0] = (unsigned char)blue; + base[1] = (unsigned char)green; + base[2] = (unsigned char)red; base[3] = 0xFF; } } @@ -122,14 +123,14 @@ error_callback( png_structp png, png_const_charp error_msg ) { - FT_Error* error = png_get_error_ptr( png ); + FT_Error* error = (FT_Error*)png_get_error_ptr( png ); FT_UNUSED( error_msg ); *error = FT_THROW( Out_Of_Memory ); #ifdef PNG_SETJMP_SUPPORTED - longjmp( png_jmpbuf( png ), 1 ); + ft_longjmp( png_jmpbuf( png ), 1 ); #endif /* if we get here, then we have no choice but to abort ... */ } @@ -159,7 +160,7 @@ if ( FT_FRAME_ENTER( length ) ) { - FT_Error* e = png_get_error_ptr( png ); + FT_Error* e = (FT_Error*)png_get_error_ptr( png ); *e = FT_THROW( Invalid_Stream_Read ); @@ -174,16 +175,18 @@ } - static FT_Error - Load_SBit_Png( FT_Bitmap* map, + FT_LOCAL_DEF( FT_Error ) + Load_SBit_Png( FT_GlyphSlot slot, FT_Int x_offset, FT_Int y_offset, FT_Int pix_bits, TT_SBit_Metrics metrics, FT_Memory memory, FT_Byte* data, - FT_UInt png_len ) + FT_UInt png_len, + FT_Bool populate_map_and_metrics ) { + FT_Bitmap *map = &slot->bitmap; FT_Error error = FT_Err_Ok; FT_StreamRec stream; @@ -193,12 +196,21 @@ int bitdepth, color_type, interlace; FT_Int i; - png_byte* *rows; + png_byte* *rows = NULL; /* pacify compiler */ - if ( x_offset < 0 || x_offset + metrics->width > map->width || - y_offset < 0 || y_offset + metrics->height > map->rows || - pix_bits != 32 || map->pixel_mode != FT_PIXEL_MODE_BGRA ) + if ( x_offset < 0 || + y_offset < 0 ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( !populate_map_and_metrics && + ( (FT_UInt)x_offset + metrics->width > map->width || + (FT_UInt)y_offset + metrics->height > map->rows || + pix_bits != 32 || + map->pixel_mode != FT_PIXEL_MODE_BGRA ) ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -238,11 +250,41 @@ &bitdepth, &color_type, &interlace, NULL, NULL ); - if ( error != FT_Err_Ok || - (FT_Int)imgWidth != metrics->width || - (FT_Int)imgHeight != metrics->height ) + if ( error || + ( !populate_map_and_metrics && + ( (FT_Int)imgWidth != metrics->width || + (FT_Int)imgHeight != metrics->height ) ) ) goto DestroyExit; + if ( populate_map_and_metrics ) + { + FT_ULong size; + + + metrics->width = (FT_UShort)imgWidth; + metrics->height = (FT_UShort)imgHeight; + + map->width = metrics->width; + map->rows = metrics->height; + map->pixel_mode = FT_PIXEL_MODE_BGRA; + map->pitch = (int)( map->width * 4 ); + map->num_grays = 256; + + /* reject too large bitmaps similarly to the rasterizer */ + if ( map->rows > 0x7FFF || map->width > 0x7FFF ) + { + error = FT_THROW( Array_Too_Large ); + goto DestroyExit; + } + + /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */ + size = map->rows * (FT_ULong)map->pitch; + + error = ft_glyphslot_alloc_bitmap( slot, size ); + if ( error ) + goto DestroyExit; + } + /* convert palette/gray image to rgb */ if ( color_type == PNG_COLOR_TYPE_PALETTE ) png_set_palette_to_rgb( png ); diff --git a/drivers/freetype/src/sfnt/pngshim.h b/drivers/freetype/src/sfnt/pngshim.h index 8a2e69ccf9..ff05871332 100644 --- a/drivers/freetype/src/sfnt/pngshim.h +++ b/drivers/freetype/src/sfnt/pngshim.h @@ -4,7 +4,8 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013 by Google, Inc. */ +/* Copyright 2013-2016 by */ +/* Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +17,8 @@ /***************************************************************************/ -#ifndef __PNGSHIM_H__ -#define __PNGSHIM_H__ +#ifndef PNGSHIM_H_ +#define PNGSHIM_H_ #include <ft2build.h> @@ -29,20 +30,21 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_OPTION_USE_PNG FT_LOCAL( FT_Error ) - Load_SBit_Png( FT_Bitmap* map, + Load_SBit_Png( FT_GlyphSlot slot, FT_Int x_offset, FT_Int y_offset, FT_Int pix_bits, TT_SBit_Metrics metrics, FT_Memory memory, FT_Byte* data, - FT_UInt png_len ); + FT_UInt png_len, + FT_Bool populate_map_and_metrics ); #endif FT_END_HEADER -#endif /* __PNGSHIM_H__ */ +#endif /* PNGSHIM_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/rules.mk b/drivers/freetype/src/sfnt/rules.mk index a6c956ab65..e9fc421567 100644 --- a/drivers/freetype/src/sfnt/rules.mk +++ b/drivers/freetype/src/sfnt/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002-2007, 2009, 2011, 2013 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ SFNT_DIR := $(SRC_DIR)/sfnt # compilation flags for the driver # -SFNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) +SFNT_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # SFNT driver sources (i.e., C files) diff --git a/drivers/freetype/src/sfnt/sfdriver.c b/drivers/freetype/src/sfnt/sfdriver.c index a368b8caea..47e8967752 100644 --- a/drivers/freetype/src/sfnt/sfdriver.c +++ b/drivers/freetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2007, 2009-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -75,36 +75,36 @@ switch ( tag ) { - case ft_sfnt_head: + case FT_SFNT_HEAD: table = &face->header; break; - case ft_sfnt_hhea: + case FT_SFNT_HHEA: table = &face->horizontal; break; - case ft_sfnt_vhea: - table = face->vertical_info ? &face->vertical : 0; + case FT_SFNT_VHEA: + table = face->vertical_info ? &face->vertical : NULL; break; - case ft_sfnt_os2: - table = face->os2.version == 0xFFFFU ? 0 : &face->os2; + case FT_SFNT_OS2: + table = face->os2.version == 0xFFFFU ? NULL : &face->os2; break; - case ft_sfnt_post: + case FT_SFNT_POST: table = &face->postscript; break; - case ft_sfnt_maxp: + case FT_SFNT_MAXP: table = &face->max_profile; break; - case ft_sfnt_pclt: - table = face->pclt.Version ? &face->pclt : 0; + case FT_SFNT_PCLT: + table = face->pclt.Version ? &face->pclt : NULL; break; default: - table = 0; + table = NULL; } return table; @@ -139,9 +139,9 @@ FT_DEFINE_SERVICE_SFNT_TABLEREC( sfnt_service_sfnt_table, - (FT_SFNT_TableLoadFunc)tt_face_load_any, - (FT_SFNT_TableGetFunc) get_sfnt_table, - (FT_SFNT_TableInfoFunc)sfnt_table_info ) + (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */ + (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */ + (FT_SFNT_TableInfoFunc)sfnt_table_info ) /* table_info */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -205,8 +205,8 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( sfnt_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) + (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) /* name_index */ #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -266,7 +266,7 @@ { FT_Stream stream = face->name_table.stream; FT_String* r = (FT_String*)result; - FT_Byte* p = (FT_Byte*)name->string; + FT_Char* p; if ( FT_STREAM_SEEK( name->stringOffset ) || @@ -280,11 +280,11 @@ goto Exit; } - p = (FT_Byte*)stream->cursor; + p = (FT_Char*)stream->cursor; for ( ; len > 0; len--, p += 2 ) { - if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 ) + if ( p[0] == 0 && p[1] >= 32 ) *r++ = p[1]; } *r = '\0'; @@ -330,7 +330,7 @@ FT_DEFINE_SERVICE_PSFONTNAMEREC( sfnt_service_ps_name, - (FT_PsName_GetFunc)sfnt_get_ps_name ) + (FT_PsName_GetFunc)sfnt_get_ps_name ) /* get_ps_font_name */ /* @@ -338,7 +338,7 @@ */ FT_DEFINE_SERVICE_TTCMAPSREC( tt_service_get_cmap_info, - (TT_CMap_Info_GetFunc)tt_get_cmap_info ) + (TT_CMap_Info_GetFunc)tt_get_cmap_info ) /* get_cmap_info */ #ifdef TT_CONFIG_OPTION_BDF @@ -381,8 +381,8 @@ FT_DEFINE_SERVICE_BDFRec( sfnt_service_bdf, - (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) + (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) /* get_property */ #endif /* TT_CONFIG_OPTION_BDF */ @@ -427,7 +427,7 @@ sfnt_get_interface( FT_Module module, const char* module_interface ) { - /* SFNT_SERVICES_GET derefers `library' in PIC mode */ + /* SFNT_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC FT_Library library; @@ -499,13 +499,15 @@ tt_face_load_hmtx, /* see `ttsbit.h' and `sfnt.h' */ - PUT_EMBEDDED_BITMAPS( tt_face_load_eblc ), - PUT_EMBEDDED_BITMAPS( tt_face_free_eblc ), + PUT_EMBEDDED_BITMAPS( tt_face_load_sbit ), + PUT_EMBEDDED_BITMAPS( tt_face_free_sbit ), PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), - tt_face_get_metrics + tt_face_get_metrics, + + tt_face_get_name ) diff --git a/drivers/freetype/src/sfnt/sfdriver.h b/drivers/freetype/src/sfnt/sfdriver.h index 5de25d51ca..2694488e20 100644 --- a/drivers/freetype/src/sfnt/sfdriver.h +++ b/drivers/freetype/src/sfnt/sfdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFDRIVER_H__ -#define __SFDRIVER_H__ +#ifndef SFDRIVER_H_ +#define SFDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SFDRIVER_H__ */ +#endif /* SFDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/sferrors.h b/drivers/freetype/src/sfnt/sferrors.h index e981e1d26f..c2f9fdfead 100644 --- a/drivers/freetype/src/sfnt/sferrors.h +++ b/drivers/freetype/src/sfnt/sferrors.h @@ -4,7 +4,7 @@ /* */ /* SFNT error codes (specification only). */ /* */ -/* Copyright 2001, 2004, 2012, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __SFERRORS_H__ -#define __SFERRORS_H__ +#ifndef SFERRORS_H_ +#define SFERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX SFNT_Err_ @@ -35,6 +35,7 @@ #include FT_ERRORS_H -#endif /* __SFERRORS_H__ */ +#endif /* SFERRORS_H_ */ + /* END */ diff --git a/drivers/freetype/src/sfnt/sfnt.c b/drivers/freetype/src/sfnt/sfnt.c index d62ed4e0b5..952d6d425a 100644 --- a/drivers/freetype/src/sfnt/sfnt.c +++ b/drivers/freetype/src/sfnt/sfnt.c @@ -4,7 +4,7 @@ /* */ /* Single object library component. */ /* */ -/* Copyright 1996-2006, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/sfnt/sfntpic.c b/drivers/freetype/src/sfnt/sfntpic.c index b3fb24b3f0..1f596c0936 100644 --- a/drivers/freetype/src/sfnt/sfntpic.c +++ b/drivers/freetype/src/sfnt/sfntpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/sfnt/sfntpic.h b/drivers/freetype/src/sfnt/sfntpic.h index b09a9141e0..5ce96d3938 100644 --- a/drivers/freetype/src/sfnt/sfntpic.h +++ b/drivers/freetype/src/sfnt/sfntpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,10 @@ /***************************************************************************/ -#ifndef __SFNTPIC_H__ -#define __SFNTPIC_H__ +#ifndef SFNTPIC_H_ +#define SFNTPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H @@ -31,7 +29,6 @@ FT_BEGIN_HEADER #define SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict #define SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name #define TT_SERVICE_CMAP_INFO_GET tt_service_get_cmap_info -#define SFNT_SERVICES_GET sfnt_services #define TT_CMAP_CLASSES_GET tt_cmap_classes #define SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table #define SFNT_SERVICE_BDF_GET sfnt_service_bdf @@ -56,6 +53,8 @@ FT_BEGIN_HEADER #include "ttcmap.h" +FT_BEGIN_HEADER + typedef struct sfntModulePIC_ { FT_ServiceDescRec* sfnt_services; @@ -83,8 +82,6 @@ FT_BEGIN_HEADER ( GET_PIC( library )->sfnt_service_ps_name ) #define TT_SERVICE_CMAP_INFO_GET \ ( GET_PIC( library )->tt_service_get_cmap_info ) -#define SFNT_SERVICES_GET \ - ( GET_PIC( library )->sfnt_services ) #define TT_CMAP_CLASSES_GET \ ( GET_PIC( library )->tt_cmap_classes ) #define SFNT_SERVICE_SFNT_TABLE_GET \ @@ -102,13 +99,14 @@ FT_BEGIN_HEADER FT_Error sfnt_module_class_pic_init( FT_Library library ); + +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __SFNTPIC_H__ */ +#endif /* SFNTPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/sfobjs.c b/drivers/freetype/src/sfnt/sfobjs.c index f975e71c3b..2e8c1ecde6 100644 --- a/drivers/freetype/src/sfnt/sfobjs.c +++ b/drivers/freetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2008, 2010-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,6 +27,7 @@ #include FT_TRUETYPE_TAGS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SFNT_NAMES_H +#include FT_GZIP_H #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -119,27 +120,9 @@ FT_Memory memory ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_get_name */ - /* */ - /* <Description> */ - /* Returns a given ENGLISH name record in ASCII. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* nameid :: The name id of the name record to return. */ - /* */ - /* <InOut> */ - /* name :: The address of a string pointer. NULL if no name is */ - /* present. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error + /* documentation is in sfnt.h */ + + FT_LOCAL_DEF( FT_Error ) tt_face_get_name( TT_Face face, FT_UShort nameid, FT_String** name ) @@ -347,6 +330,403 @@ } +#define WRITE_USHORT( p, v ) \ + do \ + { \ + *(p)++ = (FT_Byte)( (v) >> 8 ); \ + *(p)++ = (FT_Byte)( (v) >> 0 ); \ + \ + } while ( 0 ) + +#define WRITE_ULONG( p, v ) \ + do \ + { \ + *(p)++ = (FT_Byte)( (v) >> 24 ); \ + *(p)++ = (FT_Byte)( (v) >> 16 ); \ + *(p)++ = (FT_Byte)( (v) >> 8 ); \ + *(p)++ = (FT_Byte)( (v) >> 0 ); \ + \ + } while ( 0 ) + + + static void + sfnt_stream_close( FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( stream->base ); + + stream->size = 0; + stream->base = NULL; + stream->close = NULL; + } + + + FT_CALLBACK_DEF( int ) + compare_offsets( const void* a, + const void* b ) + { + WOFF_Table table1 = *(WOFF_Table*)a; + WOFF_Table table2 = *(WOFF_Table*)b; + + FT_ULong offset1 = table1->Offset; + FT_ULong offset2 = table2->Offset; + + + if ( offset1 > offset2 ) + return 1; + else if ( offset1 < offset2 ) + return -1; + else + return 0; + } + + + /* Replace `face->root.stream' with a stream containing the extracted */ + /* SFNT of a WOFF font. */ + + static FT_Error + woff_open_font( FT_Stream stream, + TT_Face face ) + { + FT_Memory memory = stream->memory; + FT_Error error = FT_Err_Ok; + + WOFF_HeaderRec woff; + WOFF_Table tables = NULL; + WOFF_Table* indices = NULL; + + FT_ULong woff_offset; + + FT_Byte* sfnt = NULL; + FT_Stream sfnt_stream = NULL; + + FT_Byte* sfnt_header; + FT_ULong sfnt_offset; + + FT_Int nn; + FT_ULong old_tag = 0; + + static const FT_Frame_Field woff_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WOFF_HeaderRec + + FT_FRAME_START( 44 ), + FT_FRAME_ULONG ( signature ), + FT_FRAME_ULONG ( flavor ), + FT_FRAME_ULONG ( length ), + FT_FRAME_USHORT( num_tables ), + FT_FRAME_USHORT( reserved ), + FT_FRAME_ULONG ( totalSfntSize ), + FT_FRAME_USHORT( majorVersion ), + FT_FRAME_USHORT( minorVersion ), + FT_FRAME_ULONG ( metaOffset ), + FT_FRAME_ULONG ( metaLength ), + FT_FRAME_ULONG ( metaOrigLength ), + FT_FRAME_ULONG ( privOffset ), + FT_FRAME_ULONG ( privLength ), + FT_FRAME_END + }; + + + FT_ASSERT( stream == face->root.stream ); + FT_ASSERT( FT_STREAM_POS() == 0 ); + + if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) ) + return error; + + /* Make sure we don't recurse back here or hit TTC code. */ + if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf ) + return FT_THROW( Invalid_Table ); + + /* Miscellaneous checks. */ + if ( woff.length != stream->size || + woff.num_tables == 0 || + 44 + woff.num_tables * 20UL >= woff.length || + 12 + woff.num_tables * 16UL >= woff.totalSfntSize || + ( woff.totalSfntSize & 3 ) != 0 || + ( woff.metaOffset == 0 && ( woff.metaLength != 0 || + woff.metaOrigLength != 0 ) ) || + ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) || + ( woff.privOffset == 0 && woff.privLength != 0 ) ) + { + FT_ERROR(( "woff_font_open: invalid WOFF header\n" )); + return FT_THROW( Invalid_Table ); + } + + /* Don't trust `totalSfntSize' before thorough checks. */ + if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) || + FT_NEW( sfnt_stream ) ) + goto Exit; + + sfnt_header = sfnt; + + /* Write sfnt header. */ + { + FT_UInt searchRange, entrySelector, rangeShift, x; + + + x = woff.num_tables; + entrySelector = 0; + while ( x ) + { + x >>= 1; + entrySelector += 1; + } + entrySelector--; + + searchRange = ( 1 << entrySelector ) * 16; + rangeShift = woff.num_tables * 16 - searchRange; + + WRITE_ULONG ( sfnt_header, woff.flavor ); + WRITE_USHORT( sfnt_header, woff.num_tables ); + WRITE_USHORT( sfnt_header, searchRange ); + WRITE_USHORT( sfnt_header, entrySelector ); + WRITE_USHORT( sfnt_header, rangeShift ); + } + + /* While the entries in the sfnt header must be sorted by the */ + /* tag value, the tables themselves are not. We thus have to */ + /* sort them by offset and check that they don't overlap. */ + + if ( FT_NEW_ARRAY( tables, woff.num_tables ) || + FT_NEW_ARRAY( indices, woff.num_tables ) ) + goto Exit; + + FT_TRACE2(( "\n" + " tag offset compLen origLen checksum\n" + " -------------------------------------------\n" )); + + if ( FT_FRAME_ENTER( 20L * woff.num_tables ) ) + goto Exit; + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = tables + nn; + + table->Tag = FT_GET_TAG4(); + table->Offset = FT_GET_ULONG(); + table->CompLength = FT_GET_ULONG(); + table->OrigLength = FT_GET_ULONG(); + table->CheckSum = FT_GET_ULONG(); + + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n", + (FT_Char)( table->Tag >> 24 ), + (FT_Char)( table->Tag >> 16 ), + (FT_Char)( table->Tag >> 8 ), + (FT_Char)( table->Tag ), + table->Offset, + table->CompLength, + table->OrigLength, + table->CheckSum )); + + if ( table->Tag <= old_tag ) + { + FT_FRAME_EXIT(); + + FT_ERROR(( "woff_font_open: table tags are not sorted\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + old_tag = table->Tag; + indices[nn] = table; + } + + FT_FRAME_EXIT(); + + /* Sort by offset. */ + + ft_qsort( indices, + woff.num_tables, + sizeof ( WOFF_Table ), + compare_offsets ); + + /* Check offsets and lengths. */ + + woff_offset = 44 + woff.num_tables * 20L; + sfnt_offset = 12 + woff.num_tables * 16L; + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = indices[nn]; + + + if ( table->Offset != woff_offset || + table->CompLength > woff.length || + table->Offset > woff.length - table->CompLength || + table->OrigLength > woff.totalSfntSize || + sfnt_offset > woff.totalSfntSize - table->OrigLength || + table->CompLength > table->OrigLength ) + { + FT_ERROR(( "woff_font_open: invalid table offsets\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + table->OrigOffset = sfnt_offset; + + /* The offsets must be multiples of 4. */ + woff_offset += ( table->CompLength + 3 ) & ~3U; + sfnt_offset += ( table->OrigLength + 3 ) & ~3U; + } + + /* + * Final checks! + * + * We don't decode and check the metadata block. + * We don't check table checksums either. + * But other than those, I think we implement all + * `MUST' checks from the spec. + */ + + if ( woff.metaOffset ) + { + if ( woff.metaOffset != woff_offset || + woff.metaOffset + woff.metaLength > woff.length ) + { + FT_ERROR(( "woff_font_open:" + " invalid `metadata' offset or length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* We have padding only ... */ + woff_offset += woff.metaLength; + } + + if ( woff.privOffset ) + { + /* ... if it isn't the last block. */ + woff_offset = ( woff_offset + 3 ) & ~3U; + + if ( woff.privOffset != woff_offset || + woff.privOffset + woff.privLength > woff.length ) + { + FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* No padding for the last block. */ + woff_offset += woff.privLength; + } + + if ( sfnt_offset != woff.totalSfntSize || + woff_offset != woff.length ) + { + FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* Now use `totalSfntSize'. */ + if ( FT_REALLOC( sfnt, + 12 + woff.num_tables * 16UL, + woff.totalSfntSize ) ) + goto Exit; + + sfnt_header = sfnt + 12; + + /* Write the tables. */ + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = tables + nn; + + + /* Write SFNT table entry. */ + WRITE_ULONG( sfnt_header, table->Tag ); + WRITE_ULONG( sfnt_header, table->CheckSum ); + WRITE_ULONG( sfnt_header, table->OrigOffset ); + WRITE_ULONG( sfnt_header, table->OrigLength ); + + /* Write table data. */ + if ( FT_STREAM_SEEK( table->Offset ) || + FT_FRAME_ENTER( table->CompLength ) ) + goto Exit; + + if ( table->CompLength == table->OrigLength ) + { + /* Uncompressed data; just copy. */ + ft_memcpy( sfnt + table->OrigOffset, + stream->cursor, + table->OrigLength ); + } + else + { +#ifdef FT_CONFIG_OPTION_USE_ZLIB + + /* Uncompress with zlib. */ + FT_ULong output_len = table->OrigLength; + + + error = FT_Gzip_Uncompress( memory, + sfnt + table->OrigOffset, &output_len, + stream->cursor, table->CompLength ); + if ( error ) + goto Exit; + if ( output_len != table->OrigLength ) + { + FT_ERROR(( "woff_font_open: compressed table length mismatch\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + +#else /* !FT_CONFIG_OPTION_USE_ZLIB */ + + error = FT_THROW( Unimplemented_Feature ); + goto Exit; + +#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ + } + + FT_FRAME_EXIT(); + + /* We don't check whether the padding bytes in the WOFF file are */ + /* actually '\0'. For the output, however, we do set them properly. */ + sfnt_offset = table->OrigOffset + table->OrigLength; + while ( sfnt_offset & 3 ) + { + sfnt[sfnt_offset] = '\0'; + sfnt_offset++; + } + } + + /* Ok! Finally ready. Swap out stream and return. */ + FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize ); + sfnt_stream->memory = stream->memory; + sfnt_stream->close = sfnt_stream_close; + + FT_Stream_Free( + face->root.stream, + ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); + + face->root.stream = sfnt_stream; + + face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + + Exit: + FT_FREE( tables ); + FT_FREE( indices ); + + if ( error ) + { + FT_FREE( sfnt ); + FT_Stream_Close( sfnt_stream ); + FT_FREE( sfnt_stream ); + } + + return error; + } + + +#undef WRITE_USHORT +#undef WRITE_ULONG + + /* Fill in face->ttc_header. If the font is not a TTC, it is */ /* synthesized into a TTC with one offset table. */ static FT_Error @@ -373,11 +753,28 @@ face->ttc_header.version = 0; face->ttc_header.count = 0; + retry: offset = FT_STREAM_POS(); if ( FT_READ_ULONG( tag ) ) return error; + if ( tag == TTAG_wOFF ) + { + FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" )); + + if ( FT_STREAM_SEEK( offset ) ) + return error; + + error = woff_open_font( stream, face ); + if ( error ) + return error; + + /* Swap out stream and retry! */ + stream = face->root.stream; + goto retry; + } + if ( tag != 0x00010000UL && tag != TTAG_ttcf && tag != TTAG_OTTO && @@ -444,13 +841,14 @@ FT_LOCAL_DEF( FT_Error ) sfnt_init_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { - FT_Error error; - FT_Library library = face->root.driver->root.library; - SFNT_Service sfnt; + FT_Error error; + FT_Library library = face->root.driver->root.library; + SFNT_Service sfnt; + FT_Int face_index; /* for now, parameters are unused */ @@ -480,22 +878,104 @@ if ( error ) return error; - FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index )); + /* Stream may have changed in sfnt_open_font. */ + stream = face->root.stream; + + FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index )); - if ( face_index < 0 ) - face_index = 0; + face_index = FT_ABS( face_instance_index ) & 0xFFFF; if ( face_index >= face->ttc_header.count ) - return FT_THROW( Invalid_Argument ); + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + face_index = 0; + } if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) return error; - /* check that we have a valid TrueType file */ + /* check whether we have a valid TrueType file */ error = sfnt->load_font_dir( face, stream ); if ( error ) return error; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + { + FT_ULong fvar_len; + + FT_ULong version; + FT_ULong offset; + + FT_UShort num_axes; + FT_UShort axis_size; + FT_UShort num_instances; + FT_UShort instance_size; + + FT_Int instance_index; + + + instance_index = FT_ABS( face_instance_index ) >> 16; + + /* test whether current face is a GX font with named instances */ + if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) || + fvar_len < 20 || + FT_READ_ULONG( version ) || + FT_READ_USHORT( offset ) || + FT_STREAM_SKIP( 2 ) || + FT_READ_USHORT( num_axes ) || + FT_READ_USHORT( axis_size ) || + FT_READ_USHORT( num_instances ) || + FT_READ_USHORT( instance_size ) ) + { + version = 0; + offset = 0; + num_axes = 0; + axis_size = 0; + num_instances = 0; + instance_size = 0; + } + + /* check that the data is bound by the table length; */ + /* based on similar code in function `TT_Get_MM_Var' */ + if ( version != 0x00010000UL || + axis_size != 20 || + num_axes > 0x3FFE || + instance_size != 4 + 4 * num_axes || + num_instances > 0x7EFF || + offset + + axis_size * num_axes + + instance_size * num_instances > fvar_len ) + num_instances = 0; + + /* we don't support Multiple Master CFFs yet */ + if ( !face->goto_table( face, TTAG_CFF, stream, 0 ) ) + num_instances = 0; + + /* we support at most 2^15 - 1 instances */ + if ( num_instances >= ( 1U << 15 ) - 1 ) + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + num_instances = 0; + } + + /* instance indices in `face_instance_index' start with index 1, */ + /* thus `>' and not `>=' */ + if ( instance_index > num_instances ) + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + num_instances = 0; + } + + face->root.style_flags = (FT_Long)num_instances << 16; + } +#endif + face->root.num_faces = face->ttc_header.count; face->root.face_index = face_index; @@ -504,7 +984,8 @@ #define LOAD_( x ) \ - do { \ + do \ + { \ FT_TRACE2(( "`" #x "' " )); \ FT_TRACE3(( "-->\n" )); \ \ @@ -519,7 +1000,8 @@ } while ( 0 ) #define LOADM_( x, vertical ) \ - do { \ + do \ + { \ FT_TRACE2(( "`%s" #x "' ", \ vertical ? "vertical " : "" )); \ FT_TRACE3(( "-->\n" )); \ @@ -535,7 +1017,8 @@ } while ( 0 ) #define GET_NAME( id, field ) \ - do { \ + do \ + { \ error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \ if ( error ) \ goto Exit; \ @@ -545,7 +1028,7 @@ FT_LOCAL_DEF( FT_Error ) sfnt_load_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { @@ -555,12 +1038,13 @@ #endif FT_Bool has_outline; FT_Bool is_apple_sbit; + FT_Bool is_apple_sbix; FT_Bool ignore_preferred_family = FALSE; FT_Bool ignore_preferred_subfamily = FALSE; SFNT_Service sfnt = (SFNT_Service)face->sfnt; - FT_UNUSED( face_index ); + FT_UNUSED( face_instance_index ); /* Check parameters */ @@ -608,6 +1092,13 @@ #endif is_apple_sbit = 0; + is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 ); + + /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf' + * outline rendered on top. We don't support that yet, so just ignore + * the 'glyf' outline and advertise it as a bitmap-only font. */ + if ( is_apple_sbix ) + has_outline = FALSE; /* if this font doesn't contain outlines, we try to load */ /* a `bhed' table */ @@ -619,7 +1110,7 @@ /* load the font header (`head' table) if this isn't an Apple */ /* sbit font file */ - if ( !is_apple_sbit ) + if ( !is_apple_sbit || is_apple_sbix ) { LOAD_( head ); if ( error ) @@ -803,6 +1294,10 @@ /* */ /* Compute face flags. */ /* */ + if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC || + face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ) + flags |= FT_FACE_FLAG_COLOR; /* color glyphs */ + if ( has_outline == TRUE ) flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */ @@ -871,7 +1366,7 @@ flags |= FT_STYLE_FLAG_ITALIC; } - root->style_flags = flags; + root->style_flags |= flags; /*********************************************************************/ /* */ @@ -931,7 +1426,7 @@ if ( em_size == 0 || face->os2.version == 0xFFFFU ) { - avgwidth = 0; + avgwidth = 1; em_size = 1; } @@ -1018,8 +1513,8 @@ root->ascender = face->horizontal.Ascender; root->descender = face->horizontal.Descender; - root->height = (FT_Short)( root->ascender - root->descender + - face->horizontal.Line_Gap ); + root->height = root->ascender - root->descender + + face->horizontal.Line_Gap; if ( !( root->ascender || root->descender ) ) { @@ -1030,23 +1525,24 @@ root->ascender = face->os2.sTypoAscender; root->descender = face->os2.sTypoDescender; - root->height = (FT_Short)( root->ascender - root->descender + - face->os2.sTypoLineGap ); + root->height = root->ascender - root->descender + + face->os2.sTypoLineGap; } else { root->ascender = (FT_Short)face->os2.usWinAscent; root->descender = -(FT_Short)face->os2.usWinDescent; - root->height = (FT_UShort)( root->ascender - root->descender ); + root->height = root->ascender - root->descender; } } } - root->max_advance_width = face->horizontal.advance_Width_Max; - root->max_advance_height = (FT_Short)( face->vertical_info - ? face->vertical.advance_Height_Max - : root->height ); + root->max_advance_width = + (FT_Short)face->horizontal.advance_Width_Max; + root->max_advance_height = + (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max + : root->height ); /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ /* Adjust underline position from top edge to centre of */ @@ -1156,7 +1652,7 @@ FT_FREE( face->postscript_name ); - face->sfnt = 0; + face->sfnt = NULL; } diff --git a/drivers/freetype/src/sfnt/sfobjs.h b/drivers/freetype/src/sfnt/sfobjs.h index 6241c93b39..60b5698edd 100644 --- a/drivers/freetype/src/sfnt/sfobjs.h +++ b/drivers/freetype/src/sfnt/sfobjs.h @@ -4,7 +4,7 @@ /* */ /* SFNT object management (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFOBJS_H__ -#define __SFOBJS_H__ +#ifndef SFOBJS_H_ +#define SFOBJS_H_ #include <ft2build.h> @@ -31,24 +31,29 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) sfnt_init_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ); FT_LOCAL( FT_Error ) sfnt_load_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ); FT_LOCAL( void ) sfnt_done_face( TT_Face face ); + FT_LOCAL( FT_Error ) + tt_face_get_name( TT_Face face, + FT_UShort nameid, + FT_String** name ); + FT_END_HEADER -#endif /* __SFDRIVER_H__ */ +#endif /* SFDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/ttbdf.c b/drivers/freetype/src/sfnt/ttbdf.c index 9401dae5f8..f891691118 100644 --- a/drivers/freetype/src/sfnt/ttbdf.c +++ b/drivers/freetype/src/sfnt/ttbdf.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded BDF properties (body). */ /* */ -/* Copyright 2005, 2006, 2010, 2013 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/sfnt/ttbdf.h b/drivers/freetype/src/sfnt/ttbdf.h index 48a10d6e9b..ae521c60b6 100644 --- a/drivers/freetype/src/sfnt/ttbdf.h +++ b/drivers/freetype/src/sfnt/ttbdf.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded BDF properties (specification). */ /* */ -/* Copyright 2005 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTBDF_H__ -#define __TTBDF_H__ +#ifndef TTBDF_H_ +#define TTBDF_H_ #include <ft2build.h> @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTBDF_H__ */ +#endif /* TTBDF_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/ttcmap.c b/drivers/freetype/src/sfnt/ttcmap.c index 1507202ea8..01255a887e 100644 --- a/drivers/freetype/src/sfnt/ttcmap.c +++ b/drivers/freetype/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002-2010, 2012, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -51,6 +51,13 @@ #define TT_NEXT_ULONG FT_NEXT_ULONG + /* Too large glyph index return values are caught in `FT_Get_Char_Index' */ + /* and `FT_Get_Next_Char' (the latter calls the internal `next' function */ + /* again in this case). To mark character code return values as invalid */ + /* it is sufficient to set the corresponding glyph index return value to */ + /* zero. */ + + FT_CALLBACK_DEF( FT_Error ) tt_cmap_init( TT_CMap cmap, FT_Byte* table ) @@ -88,10 +95,16 @@ tt_cmap0_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; - FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte* p; + FT_UInt length; + if ( table + 2 + 2 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); + if ( table + length > valid->limit || length < 262 ) FT_INVALID_TOO_SHORT; @@ -193,7 +206,7 @@ /***** FORMAT 2 *****/ /***** *****/ /***** This is used for certain CJK encodings that encode text in a *****/ - /***** mixed 8/16 bits encoding along the following lines: *****/ + /***** mixed 8/16 bits encoding along the following lines. *****/ /***** *****/ /***** * Certain byte values correspond to an 8-bit character code *****/ /***** (typically in the range 0..127 for ASCII compatibility). *****/ @@ -203,19 +216,19 @@ /***** second byte of a 2-byte character). *****/ /***** *****/ /***** The following charmap lookup and iteration functions all *****/ - /***** assume that the value "charcode" correspond to following: *****/ + /***** assume that the value `charcode' fulfills the following. *****/ /***** *****/ - /***** - For one byte characters, "charcode" is simply the *****/ + /***** - For one byte characters, `charcode' is simply the *****/ /***** character code. *****/ /***** *****/ - /***** - For two byte characters, "charcode" is the 2-byte *****/ - /***** character code in big endian format. More exactly: *****/ + /***** - For two byte characters, `charcode' is the 2-byte *****/ + /***** character code in big endian format. More precisely: *****/ /***** *****/ /***** (charcode >> 8) is the first byte value *****/ /***** (charcode & 0xFF) is the second byte value *****/ /***** *****/ - /***** Note that not all values of "charcode" are valid according *****/ - /***** to these rules, and the function moderately check the *****/ + /***** Note that not all values of `charcode' are valid according *****/ + /***** to these rules, and the function moderately checks the *****/ /***** arguments. *****/ /***** *****/ /*************************************************************************/ @@ -243,7 +256,7 @@ /* table, i.e., it is the corresponding sub-header index multiplied */ /* by 8. */ /* */ - /* Each sub-header has the following format: */ + /* Each sub-header has the following format. */ /* */ /* NAME OFFSET TYPE DESCRIPTION */ /* */ @@ -258,11 +271,11 @@ /* according to the specification. */ /* */ /* If a character code is contained within a given sub-header, then */ - /* mapping it to a glyph index is done as follows: */ + /* mapping it to a glyph index is done as follows. */ /* */ /* * The value of `offset' is read. This is a _byte_ distance from the */ /* location of the `offset' field itself into a slice of the */ - /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ + /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too). */ /* */ /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ /* no glyph for the charcode. Otherwise, the value of `delta' is */ @@ -279,13 +292,20 @@ tt_cmap2_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; /* skip format */ - FT_UInt length = TT_PEEK_USHORT( p ); + FT_Byte* p; + FT_UInt length; + FT_UInt n, max_subs; - FT_Byte* keys; /* keys table */ - FT_Byte* subs; /* sub-headers */ - FT_Byte* glyph_ids; /* glyph ID array */ + FT_Byte* keys; /* keys table */ + FT_Byte* subs; /* sub-headers */ + FT_Byte* glyph_ids; /* glyph ID array */ + + + if ( table + 2 + 2 > valid->limit ) + FT_INVALID_TOO_SHORT; + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); if ( table + length > valid->limit || length < 6 + 512 ) FT_INVALID_TOO_SHORT; @@ -313,16 +333,15 @@ FT_ASSERT( p == table + 518 ); subs = p; - glyph_ids = subs + (max_subs + 1) * 8; + glyph_ids = subs + ( max_subs + 1 ) * 8; if ( glyph_ids > valid->limit ) FT_INVALID_TOO_SHORT; /* parse sub-headers */ for ( n = 0; n <= max_subs; n++ ) { - FT_UInt first_code, code_count, offset; - FT_Int delta; - FT_Byte* ids; + FT_UInt first_code, code_count, offset; + FT_Int delta; first_code = TT_NEXT_USHORT( p ); @@ -344,8 +363,11 @@ /* check offset */ if ( offset != 0 ) { + FT_Byte* ids; + + ids = p - 2 + offset; - if ( ids < glyph_ids || ids + code_count*2 > table + length ) + if ( ids < glyph_ids || ids + code_count * 2 > table + length ) FT_INVALID_OFFSET; /* check glyph IDs */ @@ -360,7 +382,7 @@ idx = TT_NEXT_USHORT( p ); if ( idx != 0 ) { - idx = ( idx + delta ) & 0xFFFFU; + idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) FT_INVALID_GLYPH_ID; } @@ -421,6 +443,7 @@ } result = sub; } + Exit: return result; } @@ -457,9 +480,10 @@ idx = TT_PEEK_USHORT( p ); if ( idx != 0 ) - result = (FT_UInt)( idx + delta ) & 0xFFFFU; + result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; } } + return result; } @@ -509,7 +533,7 @@ if ( idx != 0 ) { - gindex = ( idx + delta ) & 0xFFFFU; + gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; if ( gindex != 0 ) { result = charcode; @@ -750,7 +774,7 @@ if ( charcode < cmap->cur_start ) charcode = cmap->cur_start; - for ( ;; ) + for (;;) { FT_Byte* values = cmap->cur_values; FT_UInt end = cmap->cur_end; @@ -771,7 +795,7 @@ if ( gindex != 0 ) { - gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); + gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; if ( gindex != 0 ) { cmap->cur_charcode = charcode; @@ -785,7 +809,7 @@ { do { - FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); + FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; if ( gindex != 0 ) @@ -816,16 +840,20 @@ tt_cmap4_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; /* skip format */ - FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte* p; + FT_UInt length; + FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; FT_UInt num_segs; FT_Error error = FT_Err_Ok; - if ( length < 16 ) + if ( table + 2 + 2 > valid->limit ) FT_INVALID_TOO_SHORT; + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); + /* in certain fonts, the `length' field is invalid and goes */ /* out of bound. We try to correct this here... */ if ( table + length > valid->limit ) @@ -836,6 +864,9 @@ length = (FT_UInt)( valid->limit - table ); } + if ( length < 16 ) + FT_INVALID_TOO_SHORT; + p = table + 6; num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ @@ -951,7 +982,7 @@ /* segment if it contains only a single character. */ /* */ /* We thus omit the test here, delaying it to the */ - /* routines which actually access the cmap. */ + /* routines that actually access the cmap. */ else if ( n != num_segs - 1 || !( start == 0xFFFFU && end == 0xFFFFU ) ) { @@ -971,7 +1002,7 @@ idx = FT_NEXT_USHORT( p ); if ( idx != 0 ) { - idx = (FT_UInt)( idx + delta ) & 0xFFFFU; + idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) FT_INVALID_GLYPH_ID; @@ -1004,12 +1035,17 @@ FT_UInt32* pcharcode, FT_Bool next ) { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt i, num_segs; FT_UInt32 charcode = *pcharcode; FT_UInt gindex = 0; FT_Byte* p; + FT_Byte* q; p = cmap->data + 6; @@ -1023,65 +1059,106 @@ if ( next ) charcode++; + if ( charcode > 0xFFFFU ) + return 0; + /* linear search */ - for ( ; charcode <= 0xFFFFU; charcode++ ) - { - FT_Byte* q; + p = cmap->data + 14; /* ends table */ + q = cmap->data + 16 + num_segs2; /* starts table */ + for ( i = 0; i < num_segs; i++ ) + { + end = TT_NEXT_USHORT( p ); + start = TT_NEXT_USHORT( q ); - p = cmap->data + 14; /* ends table */ - q = cmap->data + 16 + num_segs2; /* starts table */ + if ( charcode < start ) + { + if ( next ) + charcode = start; + else + break; + } - for ( i = 0; i < num_segs; i++ ) + Again: + if ( charcode <= end ) { - end = TT_NEXT_USHORT( p ); - start = TT_NEXT_USHORT( q ); + FT_Byte* r; - if ( charcode >= start && charcode <= end ) + + r = q - 2 + num_segs2; + delta = TT_PEEK_SHORT( r ); + r += num_segs2; + offset = TT_PEEK_USHORT( r ); + + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( i >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) { - p = q - 2 + num_segs2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - - /* some fonts have an incorrect last segment; */ - /* we have to catch it */ - if ( i >= num_segs - 1 && - start == 0xFFFFU && end == 0xFFFFU ) + if ( offset && r + offset + 2 > limit ) { - TT_Face face = (TT_Face)cmap->cmap.charmap.face; - FT_Byte* limit = face->cmap_table + face->cmap_size; + delta = 1; + offset = 0; + } + } + if ( offset == 0xFFFFU ) + continue; - if ( offset && p + offset + 2 > limit ) - { - delta = 1; - offset = 0; - } - } + if ( offset ) + { + r += offset + ( charcode - start ) * 2; - if ( offset == 0xFFFFU ) + /* if r > limit, the whole segment is invalid */ + if ( next && r > limit ) continue; - if ( offset ) + gindex = TT_PEEK_USHORT( r ); + if ( gindex ) { - p += offset + ( charcode - start ) * 2; - gindex = TT_PEEK_USHORT( p ); - if ( gindex != 0 ) - gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; + if ( gindex >= (FT_UInt)face->root.num_glyphs ) + gindex = 0; } - else - gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; + } + else + { + gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; - break; + if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) + { + /* we have an invalid glyph index; if there is an overflow, */ + /* we can adjust `charcode', otherwise the whole segment is */ + /* invalid */ + gindex = 0; + + if ( (FT_Int)charcode + delta < 0 && + (FT_Int)end + delta >= 0 ) + charcode = (FT_UInt)( -delta ); + + else if ( (FT_Int)charcode + delta < 0x10000L && + (FT_Int)end + delta >= 0x10000L ) + charcode = (FT_UInt)( 0x10000L - delta ); + + else + continue; + } + } + + if ( next && !gindex ) + { + if ( charcode >= 0xFFFFU ) + break; + + charcode++; + goto Again; } - } - if ( !next || gindex ) break; + } } - if ( next && gindex ) + if ( next ) *pcharcode = charcode; return gindex; @@ -1168,7 +1245,7 @@ mid = max + 1; /* search in segments before the current segment */ - for ( i = max ; i > 0; i-- ) + for ( i = max; i > 0; i-- ) { FT_UInt prev_end; FT_Byte* old_p; @@ -1272,10 +1349,10 @@ p += offset + ( charcode - start ) * 2; gindex = TT_PEEK_USHORT( p ); if ( gindex != 0 ) - gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; } else - gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; + gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; break; } @@ -1288,7 +1365,6 @@ /* if `charcode' is not in any segment, then `mid' is */ /* the segment nearest to `charcode' */ - /* */ if ( charcode > end ) { @@ -1421,7 +1497,7 @@ /* */ /* NAME OFFSET TYPE DESCRIPTION */ /* */ - /* format 0 USHORT must be 4 */ + /* format 0 USHORT must be 6 */ /* length 2 USHORT table length in bytes */ /* language 4 USHORT Mac language code */ /* */ @@ -1489,6 +1565,7 @@ p += 2 * idx; result = TT_PEEK_USHORT( p ); } + return result; } @@ -1509,7 +1586,7 @@ if ( char_code >= 0x10000UL ) - goto Exit; + return 0; if ( char_code < start ) char_code = start; @@ -1525,10 +1602,13 @@ result = char_code; break; } + + if ( char_code >= 0xFFFFU ) + return 0; + char_code++; } - Exit: *pchar_code = result; return gindex; } @@ -1580,7 +1660,7 @@ /***** *****/ /***** The purpose of this format is to easily map UTF-16 text to *****/ /***** glyph indices. Basically, the `char_code' must be in one of *****/ - /***** the following formats: *****/ + /***** the following formats. *****/ /***** *****/ /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ /***** Area (i.e. U+D800-U+DFFF). *****/ @@ -1593,7 +1673,7 @@ /***** The `is32' table embedded in the charmap indicates whether a *****/ /***** given 16-bit value is in the surrogates area or not. *****/ /***** *****/ - /***** So, for any given `char_code', we can assert the following: *****/ + /***** So, for any given `char_code', we can assert the following. *****/ /***** *****/ /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ /***** *****/ @@ -1647,7 +1727,8 @@ p = is32 + 8192; /* skip `is32' array */ num_groups = TT_NEXT_ULONG( p ); - if ( p + num_groups * 12 > valid->limit ) + /* p + num_groups * 12 > valid->limit ? */ + if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -1672,7 +1753,12 @@ if ( valid->level >= FT_VALIDATE_TIGHT ) { - if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_UInt32 d = end - start; + + + /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */ + if ( d > TT_VALID_GLYPH_COUNT( valid ) || + start_id >= TT_VALID_GLYPH_COUNT( valid ) - d ) FT_INVALID_GLYPH_ID; count = (FT_UInt32)( end - start + 1 ); @@ -1742,7 +1828,10 @@ if ( char_code <= end ) { - result = (FT_UInt)( start_id + char_code - start ); + if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) + return 0; + + result = (FT_UInt)( start_id + ( char_code - start ) ); break; } } @@ -1754,8 +1843,9 @@ tt_cmap8_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { + FT_Face face = cmap->cmap.charmap.face; FT_UInt32 result = 0; - FT_UInt32 char_code = *pchar_code + 1; + FT_UInt32 char_code; FT_UInt gindex = 0; FT_Byte* table = cmap->data; FT_Byte* p = table + 8204; @@ -1763,6 +1853,11 @@ FT_UInt32 start, end, start_id; + if ( *pchar_code >= 0xFFFFFFFFUL ) + return 0; + + char_code = *pchar_code + 1; + p = table + 8208; for ( ; num_groups > 0; num_groups-- ) @@ -1774,18 +1869,38 @@ if ( char_code < start ) char_code = start; + Again: if ( char_code <= end ) { - gindex = (FT_UInt)( char_code - start + start_id ); - if ( gindex != 0 ) + /* ignore invalid group */ + if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) + continue; + + gindex = (FT_UInt)( start_id + ( char_code - start ) ); + + /* does first element of group point to `.notdef' glyph? */ + if ( gindex == 0 ) { - result = char_code; - goto Exit; + if ( char_code >= 0xFFFFFFFFUL ) + break; + + char_code++; + goto Again; } + + /* if `gindex' is invalid, the remaining values */ + /* in this group are invalid, too */ + if ( gindex >= (FT_UInt)face->num_glyphs ) + { + gindex = 0; + continue; + } + + result = char_code; + break; } } - Exit: *pchar_code = result; return gindex; } @@ -1870,7 +1985,9 @@ count = TT_NEXT_ULONG( p ); if ( length > (FT_ULong)( valid->limit - table ) || - length < 20 + count * 2 ) + /* length < 20 + count * 2 ? */ + length < 20 || + ( length - 20 ) / 2 < count ) FT_INVALID_TOO_SHORT; /* check glyph indices */ @@ -1900,14 +2017,20 @@ FT_Byte* p = table + 12; FT_UInt32 start = TT_NEXT_ULONG( p ); FT_UInt32 count = TT_NEXT_ULONG( p ); - FT_UInt32 idx = (FT_ULong)( char_code - start ); + FT_UInt32 idx; + + + if ( char_code < start ) + return 0; + idx = char_code - start; if ( idx < count ) { p += 2 * idx; result = TT_PEEK_USHORT( p ); } + return result; } @@ -1917,7 +2040,7 @@ FT_UInt32 *pchar_code ) { FT_Byte* table = cmap->data; - FT_UInt32 char_code = *pchar_code + 1; + FT_UInt32 char_code; FT_UInt gindex = 0; FT_Byte* p = table + 12; FT_UInt32 start = TT_NEXT_ULONG( p ); @@ -1925,10 +2048,15 @@ FT_UInt32 idx; + if ( *pchar_code >= 0xFFFFFFFFUL ) + return 0; + + char_code = *pchar_code + 1; + if ( char_code < start ) char_code = start; - idx = (FT_UInt32)( char_code - start ); + idx = char_code - start; p += 2 * idx; for ( ; idx < count; idx++ ) @@ -1936,6 +2064,10 @@ gindex = TT_NEXT_USHORT( p ); if ( gindex != 0 ) break; + + if ( char_code >= 0xFFFFFFFFUL ) + return 0; + char_code++; } @@ -2042,9 +2174,9 @@ tt_cmap12_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p; - FT_ULong length; - FT_ULong num_groups; + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; if ( table + 16 > valid->limit ) @@ -2057,7 +2189,9 @@ num_groups = TT_NEXT_ULONG( p ); if ( length > (FT_ULong)( valid->limit - table ) || - length < 16 + 12 * num_groups ) + /* length < 16 + 12 * num_groups ? */ + length < 16 || + ( length - 16 ) / 12 < num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -2079,7 +2213,12 @@ if ( valid->level >= FT_VALIDATE_TIGHT ) { - if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_UInt32 d = end - start; + + + /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */ + if ( d > TT_VALID_GLYPH_COUNT( valid ) || + start_id >= TT_VALID_GLYPH_COUNT( valid ) - d ) FT_INVALID_GLYPH_ID; } @@ -2097,6 +2236,7 @@ static void tt_cmap12_next( TT_CMap12 cmap ) { + FT_Face face = cmap->cmap.cmap.charmap.face; FT_Byte* p; FT_ULong start, end, start_id, char_code; FT_ULong n; @@ -2108,8 +2248,6 @@ char_code = cmap->cur_charcode + 1; - n = cmap->cur_group; - for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) { p = cmap->cmap.data + 16 + 12 * n; @@ -2120,18 +2258,38 @@ if ( char_code < start ) char_code = start; - for ( ; char_code <= end; char_code++ ) + Again: + if ( char_code <= end ) { - gindex = (FT_UInt)( start_id + char_code - start ); + /* ignore invalid group */ + if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) + continue; - if ( gindex ) + gindex = (FT_UInt)( start_id + ( char_code - start ) ); + + /* does first element of group point to `.notdef' glyph? */ + if ( gindex == 0 ) { - cmap->cur_charcode = char_code;; - cmap->cur_gindex = gindex; - cmap->cur_group = n; + if ( char_code >= 0xFFFFFFFFUL ) + goto Fail; - return; + char_code++; + goto Again; + } + + /* if `gindex' is invalid, the remaining values */ + /* in this group are invalid, too */ + if ( gindex >= (FT_UInt)face->num_glyphs ) + { + gindex = 0; + continue; } + + cmap->cur_charcode = char_code; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; } } @@ -2161,7 +2319,12 @@ end = 0xFFFFFFFFUL; if ( next ) + { + if ( char_code >= 0xFFFFFFFFUL ) + return 0; + char_code++; + } min = 0; max = num_groups; @@ -2182,20 +2345,24 @@ else { start_id = TT_PEEK_ULONG( p ); - gindex = (FT_UInt)( start_id + char_code - start ); + /* reject invalid glyph index */ + if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) + gindex = 0; + else + gindex = (FT_UInt)( start_id + ( char_code - start ) ); break; } } if ( next ) { + FT_Face face = cmap->cmap.charmap.face; TT_CMap12 cmap12 = (TT_CMap12)cmap; /* if `char_code' is not in any group, then `mid' is */ /* the group nearest to `char_code' */ - /* */ if ( char_code > end ) { @@ -2208,6 +2375,9 @@ cmap12->cur_charcode = char_code; cmap12->cur_group = mid; + if ( gindex >= (FT_UInt)face->num_glyphs ) + gindex = 0; + if ( !gindex ) { tt_cmap12_next( cmap12 ); @@ -2218,8 +2388,7 @@ else cmap12->cur_gindex = gindex; - if ( gindex ) - *pchar_code = cmap12->cur_charcode; + *pchar_code = cmap12->cur_charcode; } return gindex; @@ -2239,23 +2408,17 @@ FT_UInt32 *pchar_code ) { TT_CMap12 cmap12 = (TT_CMap12)cmap; - FT_ULong gindex; + FT_UInt gindex; - if ( cmap12->cur_charcode >= 0xFFFFFFFFUL ) - return 0; - /* no need to search */ if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) { tt_cmap12_next( cmap12 ); if ( cmap12->valid ) { - gindex = cmap12->cur_gindex; - - /* XXX: check cur_charcode overflow is expected */ - if ( gindex ) - *pchar_code = (FT_UInt32)cmap12->cur_charcode; + gindex = cmap12->cur_gindex; + *pchar_code = (FT_UInt32)cmap12->cur_charcode; } else gindex = 0; @@ -2263,8 +2426,7 @@ else gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); - /* XXX: check gindex overflow is expected */ - return (FT_UInt32)gindex; + return gindex; } @@ -2381,7 +2543,9 @@ num_groups = TT_NEXT_ULONG( p ); if ( length > (FT_ULong)( valid->limit - table ) || - length < 16 + 12 * num_groups ) + /* length < 16 + 12 * num_groups ? */ + length < 16 || + ( length - 16 ) / 12 < num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -2421,6 +2585,7 @@ static void tt_cmap13_next( TT_CMap13 cmap ) { + FT_Face face = cmap->cmap.cmap.charmap.face; FT_Byte* p; FT_ULong start, end, glyph_id, char_code; FT_ULong n; @@ -2432,8 +2597,6 @@ char_code = cmap->cur_charcode + 1; - n = cmap->cur_group; - for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) { p = cmap->cmap.data + 16 + 12 * n; @@ -2448,9 +2611,9 @@ { gindex = (FT_UInt)glyph_id; - if ( gindex ) + if ( gindex && gindex < (FT_UInt)face->num_glyphs ) { - cmap->cur_charcode = char_code;; + cmap->cur_charcode = char_code; cmap->cur_gindex = gindex; cmap->cur_group = n; @@ -2485,7 +2648,12 @@ end = 0xFFFFFFFFUL; if ( next ) + { + if ( char_code >= 0xFFFFFFFFUL ) + return 0; + char_code++; + } min = 0; max = num_groups; @@ -2513,6 +2681,7 @@ if ( next ) { + FT_Face face = cmap->cmap.charmap.face; TT_CMap13 cmap13 = (TT_CMap13)cmap; @@ -2530,6 +2699,9 @@ cmap13->cur_charcode = char_code; cmap13->cur_group = mid; + if ( gindex >= (FT_UInt)face->num_glyphs ) + gindex = 0; + if ( !gindex ) { tt_cmap13_next( cmap13 ); @@ -2540,8 +2712,7 @@ else cmap13->cur_gindex = gindex; - if ( gindex ) - *pchar_code = cmap13->cur_charcode; + *pchar_code = cmap13->cur_charcode; } return gindex; @@ -2564,18 +2735,14 @@ FT_UInt gindex; - if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) - return 0; - /* no need to search */ if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) { tt_cmap13_next( cmap13 ); if ( cmap13->valid ) { - gindex = cmap13->cur_gindex; - if ( gindex ) - *pchar_code = cmap13->cur_charcode; + gindex = cmap13->cur_gindex; + *pchar_code = cmap13->cur_charcode; } else gindex = 0; @@ -2756,13 +2923,22 @@ tt_cmap14_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; - FT_ULong length = TT_NEXT_ULONG( p ); - FT_ULong num_selectors = TT_NEXT_ULONG( p ); + FT_Byte* p; + FT_ULong length; + FT_ULong num_selectors; + if ( table + 2 + 4 + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; + length = TT_NEXT_ULONG( p ); + num_selectors = TT_NEXT_ULONG( p ); + if ( length > (FT_ULong)( valid->limit - table ) || - length < 10 + 11 * num_selectors ) + /* length < 10 + 11 * num_selectors ? */ + length < 10 || + ( length - 10 ) / 11 < num_selectors ) FT_INVALID_TOO_SHORT; /* check selectors, they must be in increasing order */ @@ -2792,13 +2968,19 @@ /* through the normal Unicode cmap, no GIDs, just check order) */ if ( defOff != 0 ) { - FT_Byte* defp = table + defOff; - FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_Byte* defp = table + defOff; + FT_ULong numRanges; FT_ULong i; - FT_ULong lastBase = 0; + FT_ULong lastBase = 0; - if ( defp + numRanges * 4 > valid->limit ) + if ( defp + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + numRanges = TT_NEXT_ULONG( defp ); + + /* defp + numRanges * 4 > valid->limit ? */ + if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 ) FT_INVALID_TOO_SHORT; for ( i = 0; i < numRanges; ++i ) @@ -2820,12 +3002,18 @@ /* and the non-default table (these glyphs are specified here) */ if ( nondefOff != 0 ) { - FT_Byte* ndp = table + nondefOff; - FT_ULong numMappings = TT_NEXT_ULONG( ndp ); - FT_ULong i, lastUni = 0; + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings; + FT_ULong i, lastUni = 0; + + if ( ndp + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + numMappings = TT_NEXT_ULONG( ndp ); - if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) + /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */ + if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 ) FT_INVALID_TOO_SHORT; for ( i = 0; i < numMappings; ++i ) @@ -2916,7 +3104,7 @@ if ( char_code < start ) max = mid; - else if ( char_code > start+cnt ) + else if ( char_code > start + cnt ) min = mid + 1; else return TRUE; @@ -3208,7 +3396,6 @@ { FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); - FT_UInt32 *ret; FT_Int i; FT_ULong defOff; FT_ULong nondefOff; @@ -3242,6 +3429,8 @@ FT_Byte* dp; FT_UInt di, ni, k; + FT_UInt32 *ret; + p = cmap->data + nondefOff; dp = cmap->data + defOff; @@ -3269,7 +3458,7 @@ ni = 1; i = 0; - for ( ;; ) + for (;;) { if ( nuni > duni + dcnt ) { @@ -3447,23 +3636,14 @@ /* only recognize format 0 */ if ( TT_NEXT_USHORT( p ) != 0 ) { - p -= 2; FT_ERROR(( "tt_face_build_cmaps:" " unsupported `cmap' table format = %d\n", - TT_PEEK_USHORT( p ) )); + TT_PEEK_USHORT( p - 2 ) )); return FT_THROW( Invalid_Table ); } num_cmaps = TT_NEXT_USHORT( p ); -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE ) - FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n" - " subtable #%d and higher are loaded" - " but cannot be searched\n", - num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 )); -#endif - for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) { FT_CharMapRec charmap; diff --git a/drivers/freetype/src/sfnt/ttcmap.h b/drivers/freetype/src/sfnt/ttcmap.h index 0fde1676bf..2273cbd961 100644 --- a/drivers/freetype/src/sfnt/ttcmap.h +++ b/drivers/freetype/src/sfnt/ttcmap.h @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002-2005, 2009, 2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTCMAP_H__ -#define __TTCMAP_H__ +#ifndef TTCMAP_H_ +#define TTCMAP_H_ #include <ft2build.h> @@ -152,7 +152,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTCMAP_H__ */ +#endif /* TTCMAP_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/ttcmapc.h b/drivers/freetype/src/sfnt/ttcmapc.h index 2ea204309c..7c732fbd36 100644 --- a/drivers/freetype/src/sfnt/ttcmapc.h +++ b/drivers/freetype/src/sfnt/ttcmapc.h @@ -4,7 +4,7 @@ /* */ /* TT CMAP classes definitions (specification only). */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/sfnt/ttkern.c b/drivers/freetype/src/sfnt/ttkern.c index 60ee546d79..6f9fa522d5 100644 --- a/drivers/freetype/src/sfnt/ttkern.c +++ b/drivers/freetype/src/sfnt/ttkern.c @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -99,7 +99,7 @@ length = FT_NEXT_USHORT( p ); coverage = FT_NEXT_USHORT( p ); - if ( length <= 6 ) + if ( length <= 6 + 8 ) break; p_next += length; @@ -108,8 +108,8 @@ p_next = p_limit; /* only use horizontal kerning tables */ - if ( ( coverage & ~8 ) != 0x0001 || - p + 8 > p_limit ) + if ( ( coverage & ~8U ) != 0x0001 || + p + 8 > p_limit ) goto NextTable; num_pairs = FT_NEXT_USHORT( p ); @@ -183,7 +183,7 @@ FT_UInt right_glyph ) { FT_Int result = 0; - FT_UInt count, mask = 1; + FT_UInt count, mask; FT_Byte* p = face->kern_table; FT_Byte* p_limit = p + face->kern_table_size; @@ -196,7 +196,7 @@ count--, mask <<= 1 ) { FT_Byte* base = p; - FT_Byte* next = base; + FT_Byte* next; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt length = FT_NEXT_USHORT( p ); FT_UInt coverage = FT_NEXT_USHORT( p ); diff --git a/drivers/freetype/src/sfnt/ttkern.h b/drivers/freetype/src/sfnt/ttkern.h index df1da9b273..85dd5c31ae 100644 --- a/drivers/freetype/src/sfnt/ttkern.h +++ b/drivers/freetype/src/sfnt/ttkern.h @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2007 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTKERN_H__ -#define __TTKERN_H__ +#ifndef TTKERN_H_ +#define TTKERN_H_ #include <ft2build.h> @@ -46,7 +46,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTKERN_H__ */ +#endif /* TTKERN_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/ttload.c b/drivers/freetype/src/sfnt/ttload.c index fbe70f7974..2f5b2c3843 100644 --- a/drivers/freetype/src/sfnt/ttload.c +++ b/drivers/freetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2010, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -151,7 +151,8 @@ /* Here, we */ /* */ - /* - check that `num_tables' is valid (and adjust it if necessary) */ + /* - check that `num_tables' is valid (and adjust it if necessary); */ + /* also return the number of valid table entries */ /* */ /* - look for a `head' table, check its size, and parse it to check */ /* whether its `magic' field is correctly set */ @@ -167,7 +168,8 @@ /* */ static FT_Error check_table_dir( SFNT_Header sfnt, - FT_Stream stream ) + FT_Stream stream, + FT_UShort* valid ) { FT_Error error; FT_UShort nn, valid_entries = 0; @@ -207,11 +209,28 @@ } /* we ignore invalid tables */ - if ( table.Offset + table.Length > stream->size ) + + if ( table.Offset > stream->size ) { FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); continue; } + else if ( table.Length > stream->size - table.Offset ) + { + /* Some tables have such a simple structure that clipping its */ + /* contents is harmless. This also makes FreeType less sensitive */ + /* to invalid table lengths (which programs like Acroread seem to */ + /* ignore in general). */ + + if ( table.Tag == TTAG_hmtx || + table.Tag == TTAG_vmtx ) + valid_entries++; + else + { + FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); + continue; + } + } else valid_entries++; @@ -236,7 +255,8 @@ */ if ( table.Length < 0x36 ) { - FT_TRACE2(( "check_table_dir: `head' table too small\n" )); + FT_TRACE2(( "check_table_dir:" + " `head' or `bhed' table too small\n" )); error = FT_THROW( Table_Missing ); goto Exit; } @@ -246,12 +266,8 @@ goto Exit; if ( magic != 0x5F0F3CF5UL ) - { FT_TRACE2(( "check_table_dir:" - " no magic number found in `head' table\n")); - error = FT_THROW( Table_Missing ); - goto Exit; - } + " invalid magic number in `head' or `bhed' table\n")); if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) goto Exit; @@ -262,11 +278,11 @@ has_meta = 1; } - sfnt->num_tables = valid_entries; + *valid = valid_entries; - if ( sfnt->num_tables == 0 ) + if ( !valid_entries ) { - FT_TRACE2(( "check_table_dir: no tables found\n" )); + FT_TRACE2(( "check_table_dir: no valid tables found\n" )); error = FT_THROW( Unknown_File_Format ); goto Exit; } @@ -322,8 +338,7 @@ SFNT_HeaderRec sfnt; FT_Error error; FT_Memory memory = stream->memory; - TT_TableRec* entry; - FT_Int nn; + FT_UShort nn, valid_entries; static const FT_Frame_Field offset_table_fields[] = { @@ -364,56 +379,114 @@ if ( sfnt.format_tag != TTAG_OTTO ) { /* check first */ - error = check_table_dir( &sfnt, stream ); + error = check_table_dir( &sfnt, stream, &valid_entries ); if ( error ) { FT_TRACE2(( "tt_face_load_font_dir:" " invalid table directory for TrueType\n" )); - goto Exit; } } + else + valid_entries = sfnt.num_tables; - face->num_tables = sfnt.num_tables; + face->num_tables = valid_entries; face->format_tag = sfnt.format_tag; if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) goto Exit; - if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || - FT_FRAME_ENTER( face->num_tables * 16L ) ) + if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || + FT_FRAME_ENTER( sfnt.num_tables * 16L ) ) goto Exit; - entry = face->dir_tables; - FT_TRACE2(( "\n" " tag offset length checksum\n" " ----------------------------------\n" )); + valid_entries = 0; for ( nn = 0; nn < sfnt.num_tables; nn++ ) { - entry->Tag = FT_GET_TAG4(); - entry->CheckSum = FT_GET_ULONG(); - entry->Offset = FT_GET_LONG(); - entry->Length = FT_GET_LONG(); + TT_TableRec entry; + FT_UShort i; + FT_Bool duplicate; + - /* ignore invalid tables */ - if ( entry->Offset + entry->Length > stream->size ) + entry.Tag = FT_GET_TAG4(); + entry.CheckSum = FT_GET_ULONG(); + entry.Offset = FT_GET_ULONG(); + entry.Length = FT_GET_ULONG(); + + /* ignore invalid tables that can't be sanitized */ + + if ( entry.Offset > stream->size ) continue; + else if ( entry.Length > stream->size - entry.Offset ) + { + if ( entry.Tag == TTAG_hmtx || + entry.Tag == TTAG_vmtx ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong old_length = entry.Length; +#endif + + + /* make metrics table length a multiple of 4 */ + entry.Length = ( stream->size - entry.Offset ) & ~3U; + + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx" + " (sanitized; original length %08lx)", + (FT_Char)( entry.Tag >> 24 ), + (FT_Char)( entry.Tag >> 16 ), + (FT_Char)( entry.Tag >> 8 ), + (FT_Char)( entry.Tag ), + entry.Offset, + entry.Length, + entry.CheckSum, + old_length )); + } + else + continue; + } +#ifdef FT_DEBUG_LEVEL_TRACE else + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx", + (FT_Char)( entry.Tag >> 24 ), + (FT_Char)( entry.Tag >> 16 ), + (FT_Char)( entry.Tag >> 8 ), + (FT_Char)( entry.Tag ), + entry.Offset, + entry.Length, + entry.CheckSum )); +#endif + + /* ignore duplicate tables – the first one wins */ + duplicate = 0; + for ( i = 0; i < valid_entries; i++ ) { - FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n", - (FT_Char)( entry->Tag >> 24 ), - (FT_Char)( entry->Tag >> 16 ), - (FT_Char)( entry->Tag >> 8 ), - (FT_Char)( entry->Tag ), - entry->Offset, - entry->Length, - entry->CheckSum )); - entry++; + if ( face->dir_tables[i].Tag == entry.Tag ) + { + duplicate = 1; + break; + } + } + if ( duplicate ) + { + FT_TRACE2(( " (duplicate, ignored)\n" )); + continue; + } + else + { + FT_TRACE2(( "\n" )); + + /* we finally have a valid entry */ + face->dir_tables[valid_entries++] = entry; } } + /* final adjustment to number of tables */ + face->num_tables = valid_entries; + FT_FRAME_EXIT(); FT_TRACE2(( "table directory loaded\n\n" )); @@ -1006,7 +1079,8 @@ FT_FRAME_END }; - static const FT_Frame_Field os2_fields_extra[] = + /* `OS/2' version 1 and newer */ + static const FT_Frame_Field os2_fields_extra1[] = { FT_FRAME_START( 8 ), FT_FRAME_ULONG( ulCodePageRange1 ), @@ -1014,6 +1088,7 @@ FT_FRAME_END }; + /* `OS/2' version 2 and newer */ static const FT_Frame_Field os2_fields_extra2[] = { FT_FRAME_START( 10 ), @@ -1025,6 +1100,15 @@ FT_FRAME_END }; + /* `OS/2' version 5 and newer */ + static const FT_Frame_Field os2_fields_extra5[] = + { + FT_FRAME_START( 4 ), + FT_FRAME_USHORT( usLowerOpticalPointSize ), + FT_FRAME_USHORT( usUpperOpticalPointSize ), + FT_FRAME_END + }; + /* We now support old Mac fonts where the OS/2 table doesn't */ /* exist. Simply put, we set the `version' field to 0xFFFF */ @@ -1038,18 +1122,20 @@ if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) ) goto Exit; - os2->ulCodePageRange1 = 0; - os2->ulCodePageRange2 = 0; - os2->sxHeight = 0; - os2->sCapHeight = 0; - os2->usDefaultChar = 0; - os2->usBreakChar = 0; - os2->usMaxContext = 0; + os2->ulCodePageRange1 = 0; + os2->ulCodePageRange2 = 0; + os2->sxHeight = 0; + os2->sCapHeight = 0; + os2->usDefaultChar = 0; + os2->usBreakChar = 0; + os2->usMaxContext = 0; + os2->usLowerOpticalPointSize = 0; + os2->usUpperOpticalPointSize = 0xFFFF; if ( os2->version >= 0x0001 ) { /* only version 1 tables */ - if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) ) + if ( FT_STREAM_READ_FIELDS( os2_fields_extra1, os2 ) ) goto Exit; if ( os2->version >= 0x0002 ) @@ -1057,6 +1143,13 @@ /* only version 2 tables */ if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) ) goto Exit; + + if ( os2->version >= 0x0005 ) + { + /* only version 5 tables */ + if ( FT_STREAM_READ_FIELDS( os2_fields_extra5, os2 ) ) + goto Exit; + } } } @@ -1164,6 +1257,7 @@ FT_FRAME_USHORT( Style ), FT_FRAME_USHORT( TypeFamily ), FT_FRAME_USHORT( CapHeight ), + FT_FRAME_USHORT( SymbolSet ), FT_FRAME_BYTES ( TypeFace, 16 ), FT_FRAME_BYTES ( CharacterComplement, 8 ), FT_FRAME_BYTES ( FileName, 6 ), diff --git a/drivers/freetype/src/sfnt/ttload.h b/drivers/freetype/src/sfnt/ttload.h index 49a1aee163..bec42b94b4 100644 --- a/drivers/freetype/src/sfnt/ttload.h +++ b/drivers/freetype/src/sfnt/ttload.h @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTLOAD_H__ -#define __TTLOAD_H__ +#ifndef TTLOAD_H_ +#define TTLOAD_H_ #include <ft2build.h> @@ -106,7 +106,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTLOAD_H__ */ +#endif /* TTLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/ttmtx.c b/drivers/freetype/src/sfnt/ttmtx.c index 371a9edabe..186f873dae 100644 --- a/drivers/freetype/src/sfnt/ttmtx.c +++ b/drivers/freetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* Copyright 2006-2009, 2011-2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -183,22 +183,25 @@ /* tt_face_get_metrics */ /* */ /* <Description> */ - /* Returns the horizontal or vertical metrics in font units for a */ - /* given glyph. The metrics are the left side bearing (resp. top */ - /* side bearing) and advance width (resp. advance height). */ + /* Return the horizontal or vertical metrics in font units for a */ + /* given glyph. The values are the left side bearing (top side */ + /* bearing for vertical metrics) and advance width (advance height */ + /* for vertical metrics). */ /* */ /* <Input> */ - /* header :: A pointer to either the horizontal or vertical metrics */ - /* structure. */ + /* face :: A pointer to the TrueType face structure. */ /* */ - /* idx :: The glyph index. */ + /* vertical :: If set to TRUE, get vertical metrics. */ + /* */ + /* gindex :: The glyph index. */ /* */ /* <Output> */ - /* bearing :: The bearing, either left side or top side. */ + /* abearing :: The bearing, either left side or top side. */ /* */ - /* advance :: The advance width resp. advance height. */ + /* aadvance :: The advance width or advance height, depending on */ + /* the `vertical' flag. */ /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) tt_face_get_metrics( TT_Face face, FT_Bool vertical, FT_UInt gindex, @@ -271,8 +274,6 @@ *abearing = 0; *aadvance = 0; } - - return FT_Err_Ok; } diff --git a/drivers/freetype/src/sfnt/ttmtx.h b/drivers/freetype/src/sfnt/ttmtx.h index 8b91a113d8..78395def33 100644 --- a/drivers/freetype/src/sfnt/ttmtx.h +++ b/drivers/freetype/src/sfnt/ttmtx.h @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTMTX_H__ -#define __TTMTX_H__ +#ifndef TTMTX_H_ +#define TTMTX_H_ #include <ft2build.h> @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_Bool vertical ); - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) tt_face_get_metrics( TT_Face face, FT_Bool vertical, FT_UInt gindex, @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTMTX_H__ */ +#endif /* TTMTX_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/ttpost.c b/drivers/freetype/src/sfnt/ttpost.c index 47a85c0c9f..3277f1ec4f 100644 --- a/drivers/freetype/src/sfnt/ttpost.c +++ b/drivers/freetype/src/sfnt/ttpost.c @@ -2,10 +2,10 @@ /* */ /* ttpost.c */ /* */ -/* Postcript name table processing for TrueType and OpenType fonts */ +/* PostScript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2003, 2006-2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,7 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H -#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) +#define MAC_NAME( x ) (FT_String*)psnames->macintosh_name( (FT_UInt)(x) ) #else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -62,14 +62,14 @@ /* table of Mac names. Thus, it is possible to build a version of */ /* FreeType without the Type 1 driver & PSNames module. */ -#define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) +#define MAC_NAME( x ) (FT_String*)tt_post_default_names[x] - /* the 258 default Mac PS glyph names */ + /* the 258 default Mac PS glyph names; see file `tools/glnames.py' */ static const FT_String* const tt_post_default_names[258] = { /* 0 */ - ".notdef", ".null", "CR", "space", "exclam", + ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", /* 10 */ "quotesingle", "parenleft", "parenright", "asterisk", "plus", @@ -120,7 +120,7 @@ "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", /* 170 */ - "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", /* 180 */ "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", @@ -144,8 +144,8 @@ "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", /* 250 */ - "Idot", "Scedilla", "scedilla", "Cacute", "cacute", - "Ccaron", "ccaron", "dmacron", + "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dcroat", }; @@ -155,7 +155,7 @@ static FT_Error load_format_20( TT_Face face, FT_Stream stream, - FT_Long post_limit ) + FT_ULong post_limit ) { FT_Memory memory = stream->memory; FT_Error error; @@ -163,8 +163,8 @@ FT_Int num_glyphs; FT_UShort num_names; - FT_UShort* glyph_indices = 0; - FT_Char** name_strings = 0; + FT_UShort* glyph_indices = NULL; + FT_Char** name_strings = NULL; if ( FT_READ_USHORT( num_glyphs ) ) @@ -243,14 +243,17 @@ goto Fail1; } - if ( (FT_Int)len > post_limit || - FT_STREAM_POS() > post_limit - (FT_Int)len ) + if ( len > post_limit || + FT_STREAM_POS() > post_limit - len ) { + FT_Int d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS(); + + FT_ERROR(( "load_format_20:" " exceeding string length (%d)," " truncating at end of post table (%d byte left)\n", - len, post_limit - FT_STREAM_POS() )); - len = FT_MAX( 0, post_limit - FT_STREAM_POS() ); + len, d )); + len = (FT_UInt)FT_MAX( 0, d ); } if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) || @@ -307,13 +310,13 @@ static FT_Error load_format_25( TT_Face face, FT_Stream stream, - FT_Long post_limit ) + FT_ULong post_limit ) { FT_Memory memory = stream->memory; FT_Error error; FT_Int num_glyphs; - FT_Char* offset_table = 0; + FT_Char* offset_table = NULL; FT_UNUSED( post_limit ); @@ -377,7 +380,7 @@ FT_Error error; FT_Fixed format; FT_ULong post_len; - FT_Long post_limit; + FT_ULong post_limit; /* get a stream for the face's resource */ @@ -547,10 +550,7 @@ } if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */ - { - idx += table->offsets[idx]; - *PSname = MAC_NAME( idx ); - } + *PSname = MAC_NAME( (FT_Int)idx + table->offsets[idx] ); } /* nothing to do for format == 0x00030000L */ diff --git a/drivers/freetype/src/sfnt/ttpost.h b/drivers/freetype/src/sfnt/ttpost.h index 6f06d75a71..ede45fd84c 100644 --- a/drivers/freetype/src/sfnt/ttpost.h +++ b/drivers/freetype/src/sfnt/ttpost.h @@ -2,10 +2,10 @@ /* */ /* ttpost.h */ /* */ -/* Postcript name table processing for TrueType and OpenType fonts */ +/* PostScript name table processing for TrueType and OpenType fonts */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTPOST_H__ -#define __TTPOST_H__ +#ifndef TTPOST_H_ +#define TTPOST_H_ #include <ft2build.h> @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTPOST_H__ */ +#endif /* TTPOST_H_ */ /* END */ diff --git a/drivers/freetype/src/sfnt/ttsbit.c b/drivers/freetype/src/sfnt/ttsbit.c index cd3e5a4a00..e24e7d6cdd 100644 --- a/drivers/freetype/src/sfnt/ttsbit.c +++ b/drivers/freetype/src/sfnt/ttsbit.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 2005-2009, 2013 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Copyright 2013 by Google, Inc. */ @@ -28,6 +28,7 @@ #include "sferrors.h" +#include "ttmtx.h" #include "pngshim.h" @@ -42,25 +43,36 @@ FT_LOCAL_DEF( FT_Error ) - tt_face_load_eblc( TT_Face face, + tt_face_load_sbit( TT_Face face, FT_Stream stream ) { - FT_Error error = FT_Err_Ok; - FT_Fixed version; - FT_ULong num_strikes, table_size; - FT_Byte* p; - FT_Byte* p_limit; - FT_UInt count; + FT_Error error; + FT_ULong table_size; + face->sbit_table = NULL; + face->sbit_table_size = 0; + face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; face->sbit_num_strikes = 0; - /* this table is optional */ error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); - if ( error ) + if ( !error ) + face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC; + else + { error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); + if ( error ) + error = face->goto_table( face, TTAG_bloc, stream, &table_size ); + if ( !error ) + face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC; + } + if ( error ) - error = face->goto_table( face, TTAG_bloc, stream, &table_size ); + { + error = face->goto_table( face, TTAG_sbix, stream, &table_size ); + if ( !error ) + face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX; + } if ( error ) goto Exit; @@ -71,53 +83,144 @@ goto Exit; } - if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) - goto Exit; + switch ( (FT_UInt)face->sbit_table_type ) + { + case TT_SBIT_TABLE_TYPE_EBLC: + case TT_SBIT_TABLE_TYPE_CBLC: + { + FT_Byte* p; + FT_Fixed version; + FT_ULong num_strikes; + FT_UInt count; - face->sbit_table_size = table_size; - p = face->sbit_table; - p_limit = p + table_size; + if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) + goto Exit; - version = FT_NEXT_ULONG( p ); - num_strikes = FT_NEXT_ULONG( p ); + face->sbit_table_size = table_size; - if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) - { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; + p = face->sbit_table; + + version = FT_NEXT_LONG( p ); + num_strikes = FT_NEXT_ULONG( p ); + + if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL && + ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL ) + { + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + if ( num_strikes >= 0x10000UL ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* + * Count the number of strikes available in the table. We are a bit + * paranoid there and don't trust the data. + */ + count = (FT_UInt)num_strikes; + if ( 8 + 48UL * count > table_size ) + count = (FT_UInt)( ( table_size - 8 ) / 48 ); + + face->sbit_num_strikes = count; + } + break; + + case TT_SBIT_TABLE_TYPE_SBIX: + { + FT_UShort version; + FT_UShort flags; + FT_ULong num_strikes; + FT_UInt count; + + + if ( FT_FRAME_ENTER( 8 ) ) + goto Exit; + + version = FT_GET_USHORT(); + flags = FT_GET_USHORT(); + num_strikes = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + if ( version < 1 ) + { + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* Bit 0 must always be `1'. */ + /* Bit 1 controls the overlay of bitmaps with outlines. */ + /* All other bits should be zero. */ + if ( !( flags == 1 || flags == 3 ) || + num_strikes >= 0x10000UL ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* we currently don't support bit 1; however, it is better to */ + /* draw at least something... */ + if ( flags == 3 ) + FT_TRACE1(( "tt_face_load_sbit_strikes:" + " sbix overlay not supported yet\n" + " " + " expect bad rendering results\n" )); + + /* + * Count the number of strikes available in the table. We are a bit + * paranoid there and don't trust the data. + */ + count = (FT_UInt)num_strikes; + if ( 8 + 4UL * count > table_size ) + count = (FT_UInt)( ( table_size - 8 ) / 4 ); + + if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) ) + goto Exit; + + face->sbit_table_size = 8 + count * 4; + if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) ) + goto Exit; + + face->sbit_num_strikes = count; + } + break; + + default: + error = FT_THROW( Unknown_File_Format ); + break; } - /* - * Count the number of strikes available in the table. We are a bit - * paranoid there and don't trust the data. - */ - count = (FT_UInt)num_strikes; - if ( 8 + 48UL * count > table_size ) - count = (FT_UInt)( ( p_limit - p ) / 48 ); + if ( !error ) + FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes )); - face->sbit_num_strikes = count; + return FT_Err_Ok; - FT_TRACE3(( "sbit_num_strikes: %u\n", count )); Exit: - return error; + if ( error ) + { + if ( face->sbit_table ) + FT_FRAME_RELEASE( face->sbit_table ); + face->sbit_table_size = 0; + face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; + } - Fail: - FT_FRAME_RELEASE( face->sbit_table ); - face->sbit_table_size = 0; - goto Exit; + return error; } FT_LOCAL_DEF( void ) - tt_face_free_eblc( TT_Face face ) + tt_face_free_sbit( TT_Face face ) { FT_Stream stream = face->root.stream; FT_FRAME_RELEASE( face->sbit_table ); face->sbit_table_size = 0; + face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; face->sbit_num_strikes = 0; } @@ -136,28 +239,151 @@ FT_ULong strike_index, FT_Size_Metrics* metrics ) { - FT_Byte* strike; - - if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) return FT_THROW( Invalid_Argument ); - strike = face->sbit_table + 8 + strike_index * 48; + switch ( (FT_UInt)face->sbit_table_type ) + { + case TT_SBIT_TABLE_TYPE_EBLC: + case TT_SBIT_TABLE_TYPE_CBLC: + { + FT_Byte* strike; + FT_Char max_before_bl; + FT_Char min_after_bl; + - metrics->x_ppem = (FT_UShort)strike[44]; - metrics->y_ppem = (FT_UShort)strike[45]; + strike = face->sbit_table + 8 + strike_index * 48; - metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ - metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ - metrics->height = metrics->ascender - metrics->descender; + metrics->x_ppem = (FT_UShort)strike[44]; + metrics->y_ppem = (FT_UShort)strike[45]; - /* XXX: Is this correct? */ - metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ - strike[18] + /* max_width */ - (FT_Char)strike[23] /* min_advance_SB */ - ) << 6; + metrics->ascender = (FT_Char)strike[16] * 64; /* hori.ascender */ + metrics->descender = (FT_Char)strike[17] * 64; /* hori.descender */ - return FT_Err_Ok; + /* Due to fuzzy wording in the EBLC documentation, we find both */ + /* positive and negative values for `descender'. Additionally, */ + /* many fonts have both `ascender' and `descender' set to zero */ + /* (which is definitely wrong). MS Windows simply ignores all */ + /* those values... For these reasons we apply some heuristics */ + /* to get a reasonable, non-zero value for the height. */ + + max_before_bl = (FT_Char)strike[24]; + min_after_bl = (FT_Char)strike[25]; + + if ( metrics->descender > 0 ) + { + /* compare sign of descender with `min_after_bl' */ + if ( min_after_bl < 0 ) + metrics->descender = -metrics->descender; + } + + else if ( metrics->descender == 0 ) + { + if ( metrics->ascender == 0 ) + { + FT_TRACE2(( "tt_face_load_strike_metrics:" + " sanitizing invalid ascender and descender\n" + " " + " values for strike (%d, %d)\n", + metrics->x_ppem, metrics->y_ppem )); + + /* sanitize buggy ascender and descender values */ + if ( max_before_bl || min_after_bl ) + { + metrics->ascender = max_before_bl * 64; + metrics->descender = min_after_bl * 64; + } + else + { + metrics->ascender = metrics->y_ppem * 64; + metrics->descender = 0; + } + } + } + +#if 0 + else + ; /* if we have a negative descender, simply use it */ +#endif + + metrics->height = metrics->ascender - metrics->descender; + if ( metrics->height == 0 ) + { + FT_TRACE2(( "tt_face_load_strike_metrics:" + " sanitizing invalid height value\n" + " " + " for strike (%d, %d)\n", + metrics->x_ppem, metrics->y_ppem )); + metrics->height = metrics->y_ppem * 64; + metrics->descender = metrics->ascender - metrics->height; + } + + /* Is this correct? */ + metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ + strike[18] + /* max_width */ + (FT_Char)strike[23] /* min_advance_SB */ + ) * 64; + return FT_Err_Ok; + } + + case TT_SBIT_TABLE_TYPE_SBIX: + { + FT_Stream stream = face->root.stream; + FT_UInt offset; + FT_UShort upem, ppem, resolution; + TT_HoriHeader *hori; + FT_ULong table_size; + FT_Pos ppem_; /* to reduce casts */ + + FT_Error error; + FT_Byte* p; + + + p = face->sbit_table + 8 + 4 * strike_index; + offset = FT_NEXT_ULONG( p ); + + error = face->goto_table( face, TTAG_sbix, stream, &table_size ); + if ( error ) + return error; + + if ( offset + 4 > table_size ) + return FT_THROW( Invalid_File_Format ); + + if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) || + FT_FRAME_ENTER( 4 ) ) + return error; + + ppem = FT_GET_USHORT(); + resolution = FT_GET_USHORT(); + + FT_UNUSED( resolution ); /* What to do with this? */ + + FT_FRAME_EXIT(); + + upem = face->header.Units_Per_EM; + hori = &face->horizontal; + + metrics->x_ppem = ppem; + metrics->y_ppem = ppem; + + ppem_ = (FT_Pos)ppem; + + metrics->ascender = + FT_MulDiv( hori->Ascender, ppem_ * 64, upem ); + metrics->descender = + FT_MulDiv( hori->Descender, ppem_ * 64, upem ); + metrics->height = + FT_MulDiv( hori->Ascender - hori->Descender + hori->Line_Gap, + ppem_ * 64, upem ); + metrics->max_advance = + FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem ); + + return error; + } + + default: + return FT_THROW( Unknown_File_Format ); + } } @@ -234,9 +460,11 @@ p += 34; decoder->bit_depth = *p; - if ( decoder->strike_index_array > face->sbit_table_size || - decoder->strike_index_array + 8 * decoder->strike_index_count > - face->sbit_table_size ) + /* decoder->strike_index_array + */ + /* 8 * decoder->strike_index_count > face->sbit_table_size ? */ + if ( decoder->strike_index_array > face->sbit_table_size || + decoder->strike_index_count > + ( face->sbit_table_size - decoder->strike_index_array ) / 8 ) error = FT_THROW( Invalid_File_Format ); } @@ -253,13 +481,12 @@ static FT_Error - tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, - FT_UInt load_flags ) + tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) { FT_Error error = FT_Err_Ok; FT_UInt width, height; FT_Bitmap* map = decoder->bitmap; - FT_Long size; + FT_ULong size; if ( !decoder->metrics_loaded ) @@ -271,48 +498,39 @@ width = decoder->metrics->width; height = decoder->metrics->height; - map->width = (int)width; - map->rows = (int)height; + map->width = width; + map->rows = height; switch ( decoder->bit_depth ) { case 1: map->pixel_mode = FT_PIXEL_MODE_MONO; - map->pitch = ( map->width + 7 ) >> 3; + map->pitch = (int)( ( map->width + 7 ) >> 3 ); map->num_grays = 2; break; case 2: map->pixel_mode = FT_PIXEL_MODE_GRAY2; - map->pitch = ( map->width + 3 ) >> 2; + map->pitch = (int)( ( map->width + 3 ) >> 2 ); map->num_grays = 4; break; case 4: map->pixel_mode = FT_PIXEL_MODE_GRAY4; - map->pitch = ( map->width + 1 ) >> 1; + map->pitch = (int)( ( map->width + 1 ) >> 1 ); map->num_grays = 16; break; case 8: map->pixel_mode = FT_PIXEL_MODE_GRAY; - map->pitch = map->width; + map->pitch = (int)( map->width ); map->num_grays = 256; break; case 32: - if ( load_flags & FT_LOAD_COLOR ) - { - map->pixel_mode = FT_PIXEL_MODE_BGRA; - map->pitch = map->width * 4; - map->num_grays = 256; - } - else - { - map->pixel_mode = FT_PIXEL_MODE_GRAY; - map->pitch = map->width; - map->num_grays = 256; - } + map->pixel_mode = FT_PIXEL_MODE_BGRA; + map->pitch = (int)( map->width * 4 ); + map->num_grays = 256; break; default: @@ -320,7 +538,7 @@ goto Exit; } - size = map->rows * map->pitch; + size = map->rows * (FT_ULong)map->pitch; /* check that there is no empty image */ if ( size == 0 ) @@ -368,13 +586,20 @@ p += 3; } + else + { + /* avoid uninitialized data in case there is no vertical info -- */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + } decoder->metrics_loaded = 1; *pp = p; return FT_Err_Ok; Fail: - FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" )); + FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table\n" )); return FT_THROW( Invalid_Argument ); } @@ -382,33 +607,35 @@ /* forward declaration */ static FT_Error tt_sbit_decoder_load_image( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_UInt glyph_index, FT_Int x_pos, - FT_Int y_pos ); + FT_Int y_pos, + FT_UInt recurse_count ); - typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_Byte* p, - FT_Byte* plimit, - FT_Int x_pos, - FT_Int y_pos ); + typedef FT_Error (*TT_SBitDecoder_LoadFunc)( + TT_SBitDecoder decoder, + FT_Byte* p, + FT_Byte* plimit, + FT_Int x_pos, + FT_Int y_pos, + FT_UInt recurse_count ); static FT_Error tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; + FT_Int pitch, width, height, line_bits, h; + FT_UInt bit_height, bit_width; FT_Bitmap* bitmap; - FT_UNUSED( load_flags ); + FT_UNUSED( recurse_count ); /* check that we can write the glyph into the bitmap */ @@ -423,8 +650,8 @@ line_bits = width * decoder->bit_depth; - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) + if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width || + y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height ) { FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:" " invalid bitmap dimensions\n" )); @@ -538,19 +765,20 @@ static FT_Error tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits; + FT_Int pitch, width, height, line_bits, h, nbits; + FT_UInt bit_height, bit_width; FT_Bitmap* bitmap; FT_UShort rval; - FT_UNUSED( load_flags ); + FT_UNUSED( recurse_count ); /* check that we can write the glyph into the bitmap */ @@ -565,8 +793,8 @@ line_bits = width * decoder->bit_depth; - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) + if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width || + y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height ) { FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:" " invalid bitmap dimensions\n" )); @@ -581,6 +809,12 @@ goto Exit; } + if ( !line_bits || !height ) + { + /* nothing to do */ + goto Exit; + } + /* now do the blit */ /* adjust `line' to point to the first byte of the bitmap */ @@ -664,21 +898,21 @@ static FT_Error tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_UInt num_components, nn; - FT_Char horiBearingX = decoder->metrics->horiBearingX; - FT_Char horiBearingY = decoder->metrics->horiBearingY; - FT_Byte horiAdvance = decoder->metrics->horiAdvance; - FT_Char vertBearingX = decoder->metrics->vertBearingX; - FT_Char vertBearingY = decoder->metrics->vertBearingY; - FT_Byte vertAdvance = decoder->metrics->vertAdvance; + FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX; + FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY; + FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance; + FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX; + FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY; + FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance; if ( p + 2 > limit ) @@ -702,8 +936,11 @@ /* NB: a recursive call */ - error = tt_sbit_decoder_load_image( decoder, load_flags, gindex, - x_pos + dx, y_pos + dy ); + error = tt_sbit_decoder_load_image( decoder, + gindex, + x_pos + dx, + y_pos + dy, + recurse_count + 1 ); if ( error ) break; } @@ -732,16 +969,16 @@ static FT_Error tt_sbit_decoder_load_png( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_ULong png_len; - FT_UNUSED( load_flags ); + FT_UNUSED( recurse_count ); if ( limit - p < 4 ) @@ -759,14 +996,15 @@ goto Exit; } - error = Load_SBit_Png( decoder->bitmap, + error = Load_SBit_Png( decoder->face->root.glyph, x_pos, y_pos, decoder->bit_depth, decoder->metrics, decoder->stream->memory, p, - png_len ); + png_len, + FALSE ); Exit: if ( !error ) @@ -779,12 +1017,12 @@ static FT_Error tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_UInt glyph_format, FT_ULong glyph_start, FT_ULong glyph_size, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error; FT_Stream stream = decoder->stream; @@ -794,7 +1032,8 @@ /* seek into the EBDT table now */ - if ( glyph_start + glyph_size > decoder->ebdt_size ) + if ( !glyph_size || + glyph_start + glyph_size > decoder->ebdt_size ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -843,8 +1082,36 @@ break; case 2: - case 5: case 7: + { + /* Don't trust `glyph_format'. For example, Apple's main Korean */ + /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */ + /* format 7, but the data is format 6. We check whether we have */ + /* an excessive number of bytes in the image: If it is equal to */ + /* the value for a byte-aligned glyph, use the other loading */ + /* routine. */ + /* */ + /* Note that for some (width,height) combinations, where the */ + /* width is not a multiple of 8, the sizes for bit- and */ + /* byte-aligned data are equal, for example (7,7) or (15,6). We */ + /* then prefer what `glyph_format' specifies. */ + + FT_UInt width = decoder->metrics->width; + FT_UInt height = decoder->metrics->height; + + FT_UInt bit_size = ( width * height + 7 ) >> 3; + FT_UInt byte_size = height * ( ( width + 7 ) >> 3 ); + + + if ( bit_size < byte_size && + byte_size == (FT_UInt)( p_limit - p ) ) + loader = tt_sbit_decoder_load_byte_aligned; + else + loader = tt_sbit_decoder_load_bit_aligned; + } + break; + + case 5: loader = tt_sbit_decoder_load_bit_aligned; break; @@ -859,12 +1126,15 @@ loader = tt_sbit_decoder_load_compound; break; -#ifdef FT_CONFIG_OPTION_USE_PNG case 17: /* small metrics, PNG image data */ case 18: /* big metrics, PNG image data */ case 19: /* metrics in EBLC, PNG image data */ +#ifdef FT_CONFIG_OPTION_USE_PNG loader = tt_sbit_decoder_load_png; break; +#else + error = FT_THROW( Unimplemented_Feature ); + goto Fail; #endif /* FT_CONFIG_OPTION_USE_PNG */ default: @@ -874,64 +1144,12 @@ if ( !decoder->bitmap_allocated ) { - error = tt_sbit_decoder_alloc_bitmap( decoder, load_flags ); + error = tt_sbit_decoder_alloc_bitmap( decoder ); if ( error ) goto Fail; } - if ( decoder->bit_depth == 32 && - decoder->bitmap->pixel_mode != FT_PIXEL_MODE_BGRA ) - { - /* Flatten color bitmaps if color was not requested. */ - - FT_Library library = decoder->face->root.glyph->library; - FT_Memory memory = decoder->stream->memory; - - FT_Bitmap color, *orig; - - - if ( decoder->bitmap->pixel_mode != FT_PIXEL_MODE_GRAY || - x_pos != 0 || y_pos != 0 ) - { - /* Shouldn't happen. */ - error = FT_THROW( Invalid_Table ); - goto Fail; - } - - FT_Bitmap_New( &color ); - - color.rows = decoder->bitmap->rows; - color.width = decoder->bitmap->width; - color.pitch = color.width * 4; - color.pixel_mode = FT_PIXEL_MODE_BGRA; - - if ( FT_ALLOC( color.buffer, color.rows * color.pitch ) ) - goto Fail; - - orig = decoder->bitmap; - decoder->bitmap = &color; - - error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); - - decoder->bitmap = orig; - - /* explicitly test against FT_Err_Ok to avoid compiler warnings */ - /* (we do an assignment within a conditional) */ - if ( error || - ( error = FT_Bitmap_Convert( library, - &color, - decoder->bitmap, - 1 ) ) != FT_Err_Ok ) - { - FT_Bitmap_Done( library, &color ); - goto Fail; - } - - FT_Bitmap_Done( library, &color ); - } - - else - error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); + error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count ); } Fail: @@ -944,16 +1162,11 @@ static FT_Error tt_sbit_decoder_load_image( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_UInt glyph_index, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { - /* - * First, we find the correct strike range that applies to this - * glyph index. - */ - FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; FT_Byte* p_limit = decoder->eblc_limit; FT_ULong num_ranges = decoder->strike_index_count; @@ -961,6 +1174,17 @@ FT_ULong image_start = 0, image_end = 0, image_offset; + /* arbitrary recursion limit */ + if ( recurse_count > 100 ) + { + FT_TRACE4(( "tt_sbit_decoder_load_image:" + " recursion depth exceeded\n" )); + goto Failure; + } + + + /* First, we find the correct strike range that applies to this */ + /* glyph index. */ for ( ; num_ranges > 0; num_ranges-- ) { start = FT_NEXT_USHORT( p ); @@ -993,17 +1217,15 @@ switch ( index_format ) { case 1: /* 4-byte offsets relative to `image_offset' */ - { - p += 4 * ( glyph_index - start ); - if ( p + 8 > p_limit ) - goto NoBitmap; + p += 4 * ( glyph_index - start ); + if ( p + 8 > p_limit ) + goto NoBitmap; - image_start = FT_NEXT_ULONG( p ); - image_end = FT_NEXT_ULONG( p ); + image_start = FT_NEXT_ULONG( p ); + image_end = FT_NEXT_ULONG( p ); - if ( image_start == image_end ) /* missing glyph */ - goto NoBitmap; - } + if ( image_start == image_end ) /* missing glyph */ + goto NoBitmap; break; case 2: /* big metrics, constant image size */ @@ -1025,17 +1247,15 @@ break; case 3: /* 2-byte offsets relative to 'image_offset' */ - { - p += 2 * ( glyph_index - start ); - if ( p + 4 > p_limit ) - goto NoBitmap; + p += 2 * ( glyph_index - start ); + if ( p + 4 > p_limit ) + goto NoBitmap; - image_start = FT_NEXT_USHORT( p ); - image_end = FT_NEXT_USHORT( p ); + image_start = FT_NEXT_USHORT( p ); + image_end = FT_NEXT_USHORT( p ); - if ( image_start == image_end ) /* missing glyph */ - goto NoBitmap; - } + if ( image_start == image_end ) /* missing glyph */ + goto NoBitmap; break; case 4: /* sparse glyph array with (glyph,offset) pairs */ @@ -1049,7 +1269,8 @@ num_glyphs = FT_NEXT_ULONG( p ); /* overflow check for p + ( num_glyphs + 1 ) * 4 */ - if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) + if ( p + 4 > p_limit || + num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) goto NoBitmap; for ( mm = 0; mm < num_glyphs; mm++ ) @@ -1124,12 +1345,12 @@ image_format, glyph_index )); return tt_sbit_decoder_load_bitmap( decoder, - load_flags, image_format, image_start, image_end, x_pos, - y_pos ); + y_pos, + recurse_count ); Failure: return FT_THROW( Invalid_Table ); @@ -1142,6 +1363,130 @@ } + static FT_Error + tt_face_load_sbix_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ) + { + FT_UInt sbix_pos, strike_offset, glyph_start, glyph_end; + FT_ULong table_size; + FT_Int originOffsetX, originOffsetY; + FT_Tag graphicType; + FT_Int recurse_depth = 0; + + FT_Error error; + FT_Byte* p; + + FT_UNUSED( map ); + + + metrics->width = 0; + metrics->height = 0; + + p = face->sbit_table + 8 + 4 * strike_index; + strike_offset = FT_NEXT_ULONG( p ); + + error = face->goto_table( face, TTAG_sbix, stream, &table_size ); + if ( error ) + return error; + sbix_pos = FT_STREAM_POS(); + + retry: + if ( glyph_index > (FT_UInt)face->root.num_glyphs ) + return FT_THROW( Invalid_Argument ); + + if ( strike_offset >= table_size || + table_size - strike_offset < 4 + glyph_index * 4 + 8 ) + return FT_THROW( Invalid_File_Format ); + + if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) || + FT_FRAME_ENTER( 8 ) ) + return error; + + glyph_start = FT_GET_ULONG(); + glyph_end = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + if ( glyph_start == glyph_end ) + return FT_THROW( Invalid_Argument ); + if ( glyph_start > glyph_end || + glyph_end - glyph_start < 8 || + table_size - strike_offset < glyph_end ) + return FT_THROW( Invalid_File_Format ); + + if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) || + FT_FRAME_ENTER( glyph_end - glyph_start ) ) + return error; + + originOffsetX = FT_GET_SHORT(); + originOffsetY = FT_GET_SHORT(); + + graphicType = FT_GET_TAG4(); + + switch ( graphicType ) + { + case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ): + if ( recurse_depth < 4 ) + { + glyph_index = FT_GET_USHORT(); + FT_FRAME_EXIT(); + recurse_depth++; + goto retry; + } + error = FT_THROW( Invalid_File_Format ); + break; + + case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ): +#ifdef FT_CONFIG_OPTION_USE_PNG + error = Load_SBit_Png( face->root.glyph, + 0, + 0, + 32, + metrics, + stream->memory, + stream->cursor, + glyph_end - glyph_start - 8, + TRUE ); +#else + error = FT_THROW( Unimplemented_Feature ); +#endif + break; + + case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ): + case FT_MAKE_TAG( 't', 'i', 'f', 'f' ): + case FT_MAKE_TAG( 'r', 'g', 'b', 'l' ): /* used on iOS 7.1 */ + error = FT_THROW( Unknown_File_Format ); + break; + + default: + error = FT_THROW( Unimplemented_Feature ); + break; + } + + FT_FRAME_EXIT(); + + if ( !error ) + { + FT_Short abearing; + FT_UShort aadvance; + + + tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance ); + + metrics->horiBearingX = (FT_Short)originOffsetX; + metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height ); + metrics->horiAdvance = (FT_UShort)( aadvance * + face->root.size->metrics.x_ppem / + face->header.Units_Per_EM ); + } + + return error; + } + FT_LOCAL( FT_Error ) tt_face_load_sbit_image( TT_Face face, FT_ULong strike_index, @@ -1151,23 +1496,68 @@ FT_Bitmap *map, TT_SBit_MetricsRec *metrics ) { - TT_SBitDecoderRec decoder[1]; - FT_Error error; + FT_Error error = FT_Err_Ok; - FT_UNUSED( load_flags ); - FT_UNUSED( stream ); - FT_UNUSED( map ); + switch ( (FT_UInt)face->sbit_table_type ) + { + case TT_SBIT_TABLE_TYPE_EBLC: + case TT_SBIT_TABLE_TYPE_CBLC: + { + TT_SBitDecoderRec decoder[1]; - error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); - if ( !error ) + + error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); + if ( !error ) + { + error = tt_sbit_decoder_load_image( decoder, + glyph_index, + 0, + 0, + 0 ); + tt_sbit_decoder_done( decoder ); + } + } + break; + + case TT_SBIT_TABLE_TYPE_SBIX: + error = tt_face_load_sbix_image( face, + strike_index, + glyph_index, + stream, + map, + metrics ); + break; + + default: + error = FT_THROW( Unknown_File_Format ); + break; + } + + /* Flatten color bitmaps if color was not requested. */ + if ( !error && + !( load_flags & FT_LOAD_COLOR ) && + map->pixel_mode == FT_PIXEL_MODE_BGRA ) { - error = tt_sbit_decoder_load_image( decoder, - load_flags, - glyph_index, - 0, - 0 ); - tt_sbit_decoder_done( decoder ); + FT_Bitmap new_map; + FT_Library library = face->root.glyph->library; + + + FT_Bitmap_Init( &new_map ); + + /* Convert to 8bit grayscale. */ + error = FT_Bitmap_Convert( library, map, &new_map, 1 ); + if ( error ) + FT_Bitmap_Done( library, &new_map ); + else + { + map->pixel_mode = new_map.pixel_mode; + map->pitch = new_map.pitch; + map->num_grays = new_map.num_grays; + + ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer ); + face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP; + } } return error; diff --git a/drivers/freetype/src/sfnt/ttsbit.h b/drivers/freetype/src/sfnt/ttsbit.h index ea0b5f8ada..d8a8167083 100644 --- a/drivers/freetype/src/sfnt/ttsbit.h +++ b/drivers/freetype/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2008, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTSBIT_H__ -#define __TTSBIT_H__ +#ifndef TTSBIT_H_ +#define TTSBIT_H_ #include <ft2build.h> @@ -28,11 +28,11 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - tt_face_load_eblc( TT_Face face, + tt_face_load_sbit( TT_Face face, FT_Stream stream ); FT_LOCAL( void ) - tt_face_free_eblc( TT_Face face ); + tt_face_free_sbit( TT_Face face ); FT_LOCAL( FT_Error ) @@ -57,7 +57,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTSBIT_H__ */ +#endif /* TTSBIT_H_ */ /* END */ diff --git a/drivers/freetype/src/smooth/Jamfile b/drivers/freetype/src/smooth/Jamfile index a8496aa2c2..a388c11d91 100644 --- a/drivers/freetype/src/smooth/Jamfile +++ b/drivers/freetype/src/smooth/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/smooth Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,10 @@ SubDir FT2_TOP $(FT2_SRC_DIR) smooth ; if $(FT2_MULTI) { - _sources = ftgrays ftsmooth ftspic ; + _sources = ftgrays + ftsmooth + ftspic + ; } else { diff --git a/drivers/freetype/src/smooth/ftgrays.c b/drivers/freetype/src/smooth/ftgrays.c index 7532a35829..0bf3ac6ffb 100644 --- a/drivers/freetype/src/smooth/ftgrays.c +++ b/drivers/freetype/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2003, 2005-2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,7 @@ /*************************************************************************/ /* */ /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* defining the STANDALONE_ macro when compiling it. You also need to */ /* put the files `ftgrays.h' and `ftimage.h' into the current */ /* compilation directory. Typically, you could do something like */ /* */ @@ -27,9 +27,9 @@ /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ /* same directory */ /* */ - /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ + /* - compile `ftgrays' with the STANDALONE_ macro defined, as in */ /* */ - /* cc -c -D_STANDALONE_ ftgrays.c */ + /* cc -c -DSTANDALONE_ ftgrays.c */ /* */ /* The renderer can be initialized with a call to */ /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ @@ -91,13 +91,37 @@ #define FT_COMPONENT trace_smooth -#ifdef _STANDALONE_ +#ifdef STANDALONE_ + + + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ +#define FT_RENDER_POOL_SIZE 16384L /* Auxiliary macros for token concatenation. */ #define FT_ERR_XCAT( x, y ) x ## y #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) + +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) +#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) + + + /* + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. + */ +#define FT_HYPOT( x, y ) \ + ( x = FT_ABS( x ), \ + y = FT_ABS( y ), \ + x > y ? x + ( 3 * y >> 3 ) \ + : y + ( 3 * x >> 3 ) ) + /* define this to dump debugging information */ /* #define FT_DEBUG_LEVEL_TRACE */ @@ -112,8 +136,10 @@ #include <string.h> #include <setjmp.h> #include <limits.h> -#define FT_UINT_MAX UINT_MAX -#define FT_INT_MAX INT_MAX +#define FT_CHAR_BIT CHAR_BIT +#define FT_UINT_MAX UINT_MAX +#define FT_INT_MAX INT_MAX +#define FT_ULONG_MAX ULONG_MAX #define ft_memset memset @@ -231,7 +257,7 @@ typedef ptrdiff_t FT_PtrDist; }; -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include <ft2build.h> @@ -249,7 +275,7 @@ typedef ptrdiff_t FT_PtrDist; #define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ #ifndef FT_MEM_SET @@ -277,7 +303,7 @@ typedef ptrdiff_t FT_PtrDist; #else /* FT_STATIC_RASTER */ -#define RAS_ARG /* empty */ +#define RAS_ARG void #define RAS_ARG_ /* empty */ #define RAS_VAR /* empty */ #define RAS_VAR_ /* empty */ @@ -293,23 +319,65 @@ typedef ptrdiff_t FT_PtrDist; #undef TRUNC #undef SCALED -#define ONE_PIXEL ( 1L << PIXEL_BITS ) -#define PIXEL_MASK ( -1L << PIXEL_BITS ) +#define ONE_PIXEL ( 1 << PIXEL_BITS ) #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) -#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) +#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL ) #define FLOOR( x ) ( (x) & -ONE_PIXEL ) #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) #if PIXEL_BITS >= 6 -#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) +#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) ) #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) #else #define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) -#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) +#define DOWNSCALE( x ) ( (x) * ( 64 >> PIXEL_BITS ) ) #endif + /* Compute `dividend / divisor' and return both its quotient and */ + /* remainder, cast to a specific type. This macro also ensures that */ + /* the remainder is always positive. */ +#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \ + FT_BEGIN_STMNT \ + (quotient) = (type)( (dividend) / (divisor) ); \ + (remainder) = (type)( (dividend) % (divisor) ); \ + if ( (remainder) < 0 ) \ + { \ + (quotient)--; \ + (remainder) += (type)(divisor); \ + } \ + FT_END_STMNT + +#ifdef __arm__ + /* Work around a bug specific to GCC which make the compiler fail to */ + /* optimize a division and modulo operation on the same parameters */ + /* into a single call to `__aeabi_idivmod'. See */ + /* */ + /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */ +#undef FT_DIV_MOD +#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \ + FT_BEGIN_STMNT \ + (quotient) = (type)( (dividend) / (divisor) ); \ + (remainder) = (type)( (dividend) - (quotient) * (divisor) ); \ + if ( (remainder) < 0 ) \ + { \ + (quotient)--; \ + (remainder) += (type)(divisor); \ + } \ + FT_END_STMNT +#endif /* __arm__ */ + + + /* These macros speed up repetitive divisions by replacing them */ + /* with multiplications and right shifts. */ +#define FT_UDIVPREP( b ) \ + long b ## _r = (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) +#define FT_UDIV( a, b ) \ + ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \ + ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) + + /*************************************************************************/ /* */ /* TYPE DEFINITIONS */ @@ -319,38 +387,16 @@ typedef ptrdiff_t FT_PtrDist; /* need to define them to "float" or "double" when experimenting with */ /* new algorithms */ - typedef long TCoord; /* integer scanline/pixel coordinate */ typedef long TPos; /* sub-pixel coordinate */ - - /* determine the type used to store cell areas. This normally takes at */ - /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ - /* `long' instead of `int', otherwise bad things happen */ - -#if PIXEL_BITS <= 7 - - typedef int TArea; - -#else /* PIXEL_BITS >= 8 */ - - /* approximately determine the size of integers using an ANSI-C header */ -#if FT_UINT_MAX == 0xFFFFU - typedef long TArea; -#else - typedef int TArea; -#endif - -#endif /* PIXEL_BITS >= 8 */ - - - /* maximum number of gray spans in a call to the span callback */ -#define FT_MAX_GRAY_SPANS 32 + typedef int TCoord; /* integer scanline/pixel coordinate */ + typedef int TArea; /* cell areas, coordinate products */ typedef struct TCell_* PCell; typedef struct TCell_ { - TPos x; /* same with gray_TWorker.ex */ + TCoord x; /* same with gray_TWorker.ex */ TCoord cover; /* same with gray_TWorker.cover */ TArea area; PCell next; @@ -358,6 +404,17 @@ typedef ptrdiff_t FT_PtrDist; } TCell; + /* maximum number of gray spans in a call to the span callback */ +#define FT_MAX_GRAY_SPANS 32 + + /* maximum number of gray cells in the buffer */ +#if FT_RENDER_POOL_SIZE > 2048 +#define FT_MAX_GRAY_POOL ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) ) +#else +#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) ) +#endif + + #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ /* We disable the warning `structure was padded due to */ /* __declspec(align())' in order to compile cleanly with */ @@ -368,10 +425,12 @@ typedef ptrdiff_t FT_PtrDist; typedef struct gray_TWorker_ { + ft_jmp_buf jump_buffer; + TCoord ex, ey; - TPos min_ex, max_ex; - TPos min_ey, max_ey; - TPos count_ex, count_ey; + TCoord min_ex, max_ex; + TCoord min_ey, max_ey; + TCoord count_ex, count_ey; TArea area; TCoord cover; @@ -381,17 +440,10 @@ typedef ptrdiff_t FT_PtrDist; FT_PtrDist max_cells; FT_PtrDist num_cells; - TCoord cx, cy; TPos x, y; - TPos last_ey; - - FT_Vector bez_stack[32 * 3 + 1]; - int lev_stack[32]; - FT_Outline outline; FT_Bitmap target; - FT_BBox clip_box; FT_Span gray_spans[FT_MAX_GRAY_SPANS]; int num_gray_spans; @@ -400,16 +452,7 @@ typedef ptrdiff_t FT_PtrDist; void* render_span_data; int span_y; - int band_size; - int band_shoot; - - ft_jmp_buf jump_buffer; - - void* buffer; - long buffer_size; - PCell* ycells; - TPos ycount; } gray_TWorker, *gray_PWorker; @@ -427,80 +470,37 @@ typedef ptrdiff_t FT_PtrDist; typedef struct gray_TRaster_ { - void* buffer; - long buffer_size; - int band_size; void* memory; - gray_PWorker worker; } gray_TRaster, *gray_PRaster; +#ifdef FT_DEBUG_LEVEL_TRACE - /*************************************************************************/ - /* */ - /* Initialize the cells table. */ - /* */ - static void - gray_init_cells( RAS_ARG_ void* buffer, - long byte_size ) - { - ras.buffer = buffer; - ras.buffer_size = byte_size; - - ras.ycells = (PCell*) buffer; - ras.cells = NULL; - ras.max_cells = 0; - ras.num_cells = 0; - ras.area = 0; - ras.cover = 0; - ras.invalid = 1; - } - - - /*************************************************************************/ - /* */ - /* Compute the outline bounding box. */ - /* */ + /* to be called while in the debugger -- */ + /* this function causes a compiler warning since it is unused otherwise */ static void - gray_compute_cbox( RAS_ARG ) + gray_dump_cells( RAS_ARG ) { - FT_Outline* outline = &ras.outline; - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; + int yindex; - if ( outline->n_points <= 0 ) + for ( yindex = 0; yindex < ras.count_ey; yindex++ ) { - ras.min_ex = ras.max_ex = 0; - ras.min_ey = ras.max_ey = 0; - return; - } - - ras.min_ex = ras.max_ex = vec->x; - ras.min_ey = ras.max_ey = vec->y; - - vec++; + PCell cell; - for ( ; vec < limit; vec++ ) - { - TPos x = vec->x; - TPos y = vec->y; + printf( "%3d:", yindex ); - if ( x < ras.min_ex ) ras.min_ex = x; - if ( x > ras.max_ex ) ras.max_ex = x; - if ( y < ras.min_ey ) ras.min_ey = y; - if ( y > ras.max_ey ) ras.max_ey = y; + for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) + printf( " (%3d, c:%4d, a:%6d)", + cell->x, cell->cover, cell->area ); + printf( "\n" ); } - - /* truncate the bounding box to integer pixels */ - ras.min_ex = ras.min_ex >> 6; - ras.min_ey = ras.min_ey >> 6; - ras.max_ex = ( ras.max_ex + 63 ) >> 6; - ras.max_ey = ( ras.max_ey + 63 ) >> 6; } +#endif /* FT_DEBUG_LEVEL_TRACE */ + /*************************************************************************/ /* */ @@ -510,7 +510,7 @@ typedef ptrdiff_t FT_PtrDist; gray_find_cell( RAS_ARG ) { PCell *pcell, cell; - TPos x = ras.ex; + TCoord x = ras.ex; if ( x > ras.count_ex ) @@ -548,7 +548,7 @@ typedef ptrdiff_t FT_PtrDist; static void gray_record_cell( RAS_ARG ) { - if ( !ras.invalid && ( ras.area | ras.cover ) ) + if ( ras.area | ras.cover ) { PCell cell = gray_find_cell( RAS_VAR ); @@ -597,12 +597,12 @@ typedef ptrdiff_t FT_PtrDist; ras.area = 0; ras.cover = 0; + ras.ex = ex; + ras.ey = ey; } - ras.ex = ex; - ras.ey = ey; - ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey || - ex >= ras.count_ex ); + ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey || + ex >= ras.count_ex ); } @@ -615,21 +615,21 @@ typedef ptrdiff_t FT_PtrDist; TCoord ey ) { if ( ex > ras.max_ex ) - ex = (TCoord)( ras.max_ex ); + ex = ras.max_ex; if ( ex < ras.min_ex ) - ex = (TCoord)( ras.min_ex - 1 ); + ex = ras.min_ex - 1; ras.area = 0; ras.cover = 0; ras.ex = ex - ras.min_ex; ras.ey = ey - ras.min_ey; - ras.last_ey = SUBPIXELS( ey ); ras.invalid = 0; gray_set_cell( RAS_VAR_ ex, ey ); } +#ifndef FT_LONG64 /*************************************************************************/ /* */ @@ -642,17 +642,13 @@ typedef ptrdiff_t FT_PtrDist; TPos x2, TCoord y2 ) { - TCoord ex1, ex2, fx1, fx2, delta, mod; - long p, first, dx; + TCoord ex1, ex2, fx1, fx2, first, delta, mod; + TPos p, dx; int incr; - dx = x2 - x1; - ex1 = TRUNC( x1 ); ex2 = TRUNC( x2 ); - fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); - fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); /* trivial case. Happens often */ if ( y1 == y2 ) @@ -661,6 +657,9 @@ typedef ptrdiff_t FT_PtrDist; return; } + fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); + fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); + /* everything is located in a single cell. That is easy! */ /* */ if ( ex1 == ex2 ) @@ -677,6 +676,7 @@ typedef ptrdiff_t FT_PtrDist; p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); first = ONE_PIXEL; incr = 1; + dx = x2 - x1; if ( dx < 0 ) { @@ -686,13 +686,7 @@ typedef ptrdiff_t FT_PtrDist; dx = -dx; } - delta = (TCoord)( p / dx ); - mod = (TCoord)( p % dx ); - if ( mod < 0 ) - { - delta--; - mod += (TCoord)dx; - } + FT_DIV_MOD( TCoord, p, dx, delta, mod ); ras.area += (TArea)(( fx1 + first ) * delta); ras.cover += delta; @@ -706,18 +700,12 @@ typedef ptrdiff_t FT_PtrDist; TCoord lift, rem; - p = ONE_PIXEL * ( y2 - y1 + delta ); - lift = (TCoord)( p / dx ); - rem = (TCoord)( p % dx ); - if ( rem < 0 ) - { - lift--; - rem += (TCoord)dx; - } + p = ONE_PIXEL * ( y2 - y1 + delta ); + FT_DIV_MOD( TCoord, p, dx, lift, rem ); mod -= (int)dx; - while ( ex1 != ex2 ) + do { delta = lift; mod += rem; @@ -732,7 +720,7 @@ typedef ptrdiff_t FT_PtrDist; y1 += delta; ex1 += incr; gray_set_cell( RAS_VAR_ ex1, ey ); - } + } while ( ex1 != ex2 ); } delta = y2 - y1; @@ -749,38 +737,21 @@ typedef ptrdiff_t FT_PtrDist; gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) { - TCoord ey1, ey2, fy1, fy2, mod; - TPos dx, dy, x, x2; - long p, first; - int delta, rem, lift, incr; + TCoord ey1, ey2, fy1, fy2, first, delta, mod; + TPos p, dx, dy, x, x2; + int incr; - ey1 = TRUNC( ras.last_ey ); + ey1 = TRUNC( ras.y ); ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ - fy1 = (TCoord)( ras.y - ras.last_ey ); - fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); - - dx = to_x - ras.x; - dy = to_y - ras.y; - - /* XXX: we should do something about the trivial case where dx == 0, */ - /* as it happens very often! */ /* perform vertical clipping */ - { - TCoord min, max; - + if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || + ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) + goto End; - min = ey1; - max = ey2; - if ( ey1 > ey2 ) - { - min = ey2; - max = ey1; - } - if ( min >= ras.max_ey || max < ras.min_ey ) - goto End; - } + fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); + fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); /* everything is on a single scanline */ if ( ey1 == ey2 ) @@ -789,6 +760,9 @@ typedef ptrdiff_t FT_PtrDist; goto End; } + dx = to_x - ras.x; + dy = to_y - ras.y; + /* vertical line - avoid calling gray_render_scanline */ incr = 1; @@ -806,14 +780,14 @@ typedef ptrdiff_t FT_PtrDist; incr = -1; } - delta = (int)( first - fy1 ); + delta = first - fy1; ras.area += (TArea)two_fx * delta; ras.cover += delta; ey1 += incr; gray_set_cell( RAS_VAR_ ex, ey1 ); - delta = (int)( first + first - ONE_PIXEL ); + delta = first + first - ONE_PIXEL; area = (TArea)two_fx * delta; while ( ey1 != ey2 ) { @@ -824,7 +798,7 @@ typedef ptrdiff_t FT_PtrDist; gray_set_cell( RAS_VAR_ ex, ey1 ); } - delta = (int)( fy2 - ONE_PIXEL + first ); + delta = fy2 - ONE_PIXEL + first; ras.area += (TArea)two_fx * delta; ras.cover += delta; @@ -844,63 +818,191 @@ typedef ptrdiff_t FT_PtrDist; dy = -dy; } - delta = (int)( p / dy ); - mod = (int)( p % dy ); - if ( mod < 0 ) - { - delta--; - mod += (TCoord)dy; - } + FT_DIV_MOD( TCoord, p, dy, delta, mod ); x = ras.x + delta; - gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first ); ey1 += incr; gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); if ( ey1 != ey2 ) { - p = ONE_PIXEL * dx; - lift = (int)( p / dy ); - rem = (int)( p % dy ); - if ( rem < 0 ) - { - lift--; - rem += (int)dy; - } - mod -= (int)dy; + TCoord lift, rem; - while ( ey1 != ey2 ) + + p = ONE_PIXEL * dx; + FT_DIV_MOD( TCoord, p, dy, lift, rem ); + mod -= (TCoord)dy; + + do { delta = lift; mod += rem; if ( mod >= 0 ) { - mod -= (int)dy; + mod -= (TCoord)dy; delta++; } x2 = x + delta; - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), x2, - (TCoord)first ); + gray_render_scanline( RAS_VAR_ ey1, + x, ONE_PIXEL - first, + x2, first ); x = x2; ey1 += incr; gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); - } + } while ( ey1 != ey2 ); } - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), to_x, - fy2 ); + gray_render_scanline( RAS_VAR_ ey1, + x, ONE_PIXEL - first, + to_x, fy2 ); End: ras.x = to_x; ras.y = to_y; - ras.last_ey = SUBPIXELS( ey2 ); } +#else + + /*************************************************************************/ + /* */ + /* Render a straight line across multiple cells in any direction. */ + /* */ + static void + gray_render_line( RAS_ARG_ TPos to_x, + TPos to_y ) + { + TPos dx, dy, fx1, fy1, fx2, fy2; + TCoord ex1, ex2, ey1, ey2; + + + ey1 = TRUNC( ras.y ); + ey2 = TRUNC( to_y ); + + /* perform vertical clipping */ + if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || + ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) + goto End; + + ex1 = TRUNC( ras.x ); + ex2 = TRUNC( to_x ); + + fx1 = ras.x - SUBPIXELS( ex1 ); + fy1 = ras.y - SUBPIXELS( ey1 ); + + dx = to_x - ras.x; + dy = to_y - ras.y; + + if ( ex1 == ex2 && ey1 == ey2 ) /* inside one cell */ + ; + else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */ + { + ex1 = ex2; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } + else if ( dx == 0 ) + { + if ( dy > 0 ) /* vertical line up */ + do + { + fy2 = ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * fx1 * 2; + fy1 = 0; + ey1++; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ey1 != ey2 ); + else /* vertical line down */ + do + { + fy2 = 0; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * fx1 * 2; + fy1 = ONE_PIXEL; + ey1--; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ey1 != ey2 ); + } + else /* any other line */ + { + TPos prod = dx * fy1 - dy * fx1; + FT_UDIVPREP( dx ); + FT_UDIVPREP( dy ); + + + /* The fundamental value `prod' determines which side and the */ + /* exact coordinate where the line exits current cell. It is */ + /* also easily updated when moving from one cell to the next. */ + do + { + if ( prod <= 0 && + prod - dx * ONE_PIXEL > 0 ) /* left */ + { + fx2 = 0; + fy2 = (TPos)FT_UDIV( -prod, -dx ); + prod -= dy * ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = ONE_PIXEL; + fy1 = fy2; + ex1--; + } + else if ( prod - dx * ONE_PIXEL <= 0 && + prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */ + { + prod -= dx * ONE_PIXEL; + fx2 = (TPos)FT_UDIV( -prod, dy ); + fy2 = ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = fx2; + fy1 = 0; + ey1++; + } + else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 && + prod + dy * ONE_PIXEL >= 0 ) /* right */ + { + prod += dy * ONE_PIXEL; + fx2 = ONE_PIXEL; + fy2 = (TPos)FT_UDIV( prod, dx ); + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = 0; + fy1 = fy2; + ex1++; + } + else /* ( prod + dy * ONE_PIXEL < 0 && + prod > 0 ) down */ + { + fx2 = (TPos)FT_UDIV( prod, -dy ); + fy2 = 0; + prod += dx * ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = fx2; + fy1 = ONE_PIXEL; + ey1--; + } + + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ex1 != ex2 || ey1 != ey2 ); + } + + fx2 = to_x - SUBPIXELS( ex2 ); + fy2 = to_y - SUBPIXELS( ey2 ); + + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + + End: + ras.x = to_x; + ras.y = to_y; + } + +#endif static void gray_split_conic( FT_Vector* base ) @@ -926,73 +1028,64 @@ typedef ptrdiff_t FT_PtrDist; gray_render_conic( RAS_ARG_ const FT_Vector* control, const FT_Vector* to ) { + FT_Vector bez_stack[16 * 2 + 1]; /* enough to accommodate bisections */ + FT_Vector* arc = bez_stack; TPos dx, dy; - TPos min, max, y; - int top, level; - int* levels; - FT_Vector* arc; + int draw, split; - levels = ras.lev_stack; - - arc = ras.bez_stack; arc[0].x = UPSCALE( to->x ); arc[0].y = UPSCALE( to->y ); arc[1].x = UPSCALE( control->x ); arc[1].y = UPSCALE( control->y ); arc[2].x = ras.x; arc[2].y = ras.y; - top = 0; + + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( arc[0].y ) >= ras.max_ey && + TRUNC( arc[1].y ) >= ras.max_ey && + TRUNC( arc[2].y ) >= ras.max_ey ) || + ( TRUNC( arc[0].y ) < ras.min_ey && + TRUNC( arc[1].y ) < ras.min_ey && + TRUNC( arc[2].y ) < ras.min_ey ) ) + { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x ); dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y ); if ( dx < dy ) dx = dy; - if ( dx < ONE_PIXEL / 4 ) - goto Draw; - - /* short-cut the arc that crosses the current band */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; - - level = 0; - do + /* We can calculate the number of necessary bisections because */ + /* each bisection predictably reduces deviation exactly 4-fold. */ + /* Even 32-bit deviation would vanish after 16 bisections. */ + draw = 1; + while ( dx > ONE_PIXEL / 4 ) { - dx >>= 2; - level++; - } while ( dx > ONE_PIXEL / 4 ); - - levels[0] = level; + dx >>= 2; + draw <<= 1; + } + /* We use decrement counter to count the total number of segments */ + /* to draw starting from 2^level. Before each draw we split as */ + /* many times as there are trailing zeros in the counter. */ do { - level = levels[top]; - if ( level > 0 ) + split = 1; + while ( ( draw & split ) == 0 ) { gray_split_conic( arc ); arc += 2; - top++; - levels[top] = levels[top - 1] = level - 1; - continue; + split <<= 1; } - Draw: gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - top--; arc -= 2; - } while ( top >= 0 ); + } while ( --draw ); } @@ -1029,11 +1122,13 @@ typedef ptrdiff_t FT_PtrDist; const FT_Vector* control2, const FT_Vector* to ) { - FT_Vector* arc; - TPos min, max, y; + FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */ + FT_Vector* arc = bez_stack; + TPos dx, dy, dx_, dy_; + TPos dx1, dy1, dx2, dy2; + TPos L, s, s_limit; - arc = ras.bez_stack; arc[0].x = UPSCALE( to->x ); arc[0].y = UPSCALE( to->y ); arc[1].x = UPSCALE( control2->x ); @@ -1043,29 +1138,20 @@ typedef ptrdiff_t FT_PtrDist; arc[3].x = ras.x; arc[3].y = ras.y; - /* Short-cut the arc that crosses the current band. */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[2].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[3].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( arc[0].y ) >= ras.max_ey && + TRUNC( arc[1].y ) >= ras.max_ey && + TRUNC( arc[2].y ) >= ras.max_ey && + TRUNC( arc[3].y ) >= ras.max_ey ) || + ( TRUNC( arc[0].y ) < ras.min_ey && + TRUNC( arc[1].y ) < ras.min_ey && + TRUNC( arc[2].y ) < ras.min_ey && + TRUNC( arc[3].y ) < ras.min_ey ) ) + { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } for (;;) { @@ -1074,91 +1160,53 @@ typedef ptrdiff_t FT_PtrDist; /* F. Hain, at */ /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ - { - TPos dx, dy, dx_, dy_; - TPos dx1, dy1, dx2, dy2; - TPos L, s, s_limit; - - - /* dx and dy are x and y components of the P0-P3 chord vector. */ - dx = arc[3].x - arc[0].x; - dy = arc[3].y - arc[0].y; - - /* L is an (under)estimate of the Euclidean distance P0-P3. */ - /* */ - /* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated */ - /* with least maximum error by */ - /* */ - /* r_upperbound = dx + (sqrt(2) - 1) * dy , */ - /* */ - /* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */ - /* error of no more than 8.4%. */ - /* */ - /* Similarly, some elementary calculus shows that r can be */ - /* underestimated with least maximum error by */ - /* */ - /* r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx */ - /* + sqrt(2 - sqrt(2)) / 2 * dy . */ - /* */ - /* 236/256 and 97/256 are (under)estimates of the two algebraic */ - /* numbers, giving an error of no more than 8.1%. */ - - dx_ = FT_ABS( dx ); - dy_ = FT_ABS( dy ); - - /* This is the same as */ - /* */ - /* L = ( 236 * FT_MAX( dx_, dy_ ) */ - /* + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */ - L = ( dx_ > dy_ ? 236 * dx_ + 97 * dy_ - : 97 * dx_ + 236 * dy_ ) >> 8; - - /* Avoid possible arithmetic overflow below by splitting. */ - if ( L > 32767 ) - goto Split; - - /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ - s_limit = L * (TPos)( ONE_PIXEL / 6 ); - - /* s is L * the perpendicular distance from P1 to the line P0-P3. */ - dx1 = arc[1].x - arc[0].x; - dy1 = arc[1].y - arc[0].y; - s = FT_ABS( dy * dx1 - dx * dy1 ); - - if ( s > s_limit ) - goto Split; - - /* s is L * the perpendicular distance from P2 to the line P0-P3. */ - dx2 = arc[2].x - arc[0].x; - dy2 = arc[2].y - arc[0].y; - s = FT_ABS( dy * dx2 - dx * dy2 ); - - if ( s > s_limit ) - goto Split; - - /* Split super curvy segments where the off points are so far - from the chord that the angles P0-P1-P3 or P0-P2-P3 become - acute as detected by appropriate dot products. */ - if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || - dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) - goto Split; - - /* No reason to split. */ - goto Draw; - } + /* dx and dy are x and y components of the P0-P3 chord vector. */ + dx = dx_ = arc[3].x - arc[0].x; + dy = dy_ = arc[3].y - arc[0].y; - Split: - gray_split_cubic( arc ); - arc += 3; - continue; + L = FT_HYPOT( dx_, dy_ ); + + /* Avoid possible arithmetic overflow below by splitting. */ + if ( L > 32767 ) + goto Split; + + /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ + s_limit = L * (TPos)( ONE_PIXEL / 6 ); + + /* s is L * the perpendicular distance from P1 to the line P0-P3. */ + dx1 = arc[1].x - arc[0].x; + dy1 = arc[1].y - arc[0].y; + s = FT_ABS( dy * dx1 - dx * dy1 ); + + if ( s > s_limit ) + goto Split; + + /* s is L * the perpendicular distance from P2 to the line P0-P3. */ + dx2 = arc[2].x - arc[0].x; + dy2 = arc[2].y - arc[0].y; + s = FT_ABS( dy * dx2 - dx * dy2 ); + + if ( s > s_limit ) + goto Split; + + /* Split super curvy segments where the off points are so far + from the chord that the angles P0-P1-P3 or P0-P2-P3 become + acute as detected by appropriate dot products. */ + if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || + dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) + goto Split; - Draw: gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - if ( arc == ras.bez_stack ) + if ( arc == bez_stack ) return; arc -= 3; + continue; + + Split: + gray_split_cubic( arc ); + arc += 3; } } @@ -1171,7 +1219,8 @@ typedef ptrdiff_t FT_PtrDist; /* record current cell, if any */ - gray_record_cell( RAS_VAR ); + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); /* start to a new position */ x = UPSCALE( to->x ); @@ -1179,8 +1228,8 @@ typedef ptrdiff_t FT_PtrDist; gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); - worker->x = x; - worker->y = y; + ras.x = x; + ras.y = y; return 0; } @@ -1228,7 +1277,7 @@ typedef ptrdiff_t FT_PtrDist; /* first of all, compute the scanline offset */ p = (unsigned char*)map->buffer - y * map->pitch; if ( map->pitch >= 0 ) - p += (unsigned)( ( map->rows - 1 ) * map->pitch ); + p += ( map->rows - 1 ) * (unsigned int)map->pitch; for ( ; count > 0; count--, spans++ ) { @@ -1237,29 +1286,25 @@ typedef ptrdiff_t FT_PtrDist; if ( coverage ) { + unsigned char* q = p + spans->x; + + /* For small-spans it is faster to do it by ourselves than * calling `memset'. This is mainly due to the cost of the * function call. */ - if ( spans->len >= 8 ) - FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); - else + switch ( spans->len ) { - unsigned char* q = p + spans->x; - - - switch ( spans->len ) - { - case 7: *q++ = (unsigned char)coverage; - case 6: *q++ = (unsigned char)coverage; - case 5: *q++ = (unsigned char)coverage; - case 4: *q++ = (unsigned char)coverage; - case 3: *q++ = (unsigned char)coverage; - case 2: *q++ = (unsigned char)coverage; - case 1: *q = (unsigned char)coverage; - default: - ; - } + case 7: *q++ = coverage; + case 6: *q++ = coverage; + case 5: *q++ = coverage; + case 4: *q++ = coverage; + case 3: *q++ = coverage; + case 2: *q++ = coverage; + case 1: *q = coverage; + case 0: break; + default: + FT_MEM_SET( q, coverage, spans->len ); } } } @@ -1269,7 +1314,7 @@ typedef ptrdiff_t FT_PtrDist; static void gray_hline( RAS_ARG_ TCoord x, TCoord y, - TPos area, + TArea area, TCoord acount ) { int coverage; @@ -1301,16 +1346,8 @@ typedef ptrdiff_t FT_PtrDist; coverage = 255; } - y += (TCoord)ras.min_ey; - x += (TCoord)ras.min_ex; - - /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ - if ( x >= 32767 ) - x = 32767; - - /* FT_Span.y is an integer, so limit our coordinates appropriately */ - if ( y >= FT_INT_MAX ) - y = FT_INT_MAX; + y += ras.min_ey; + x += ras.min_ex; if ( coverage ) { @@ -1321,10 +1358,10 @@ typedef ptrdiff_t FT_PtrDist; /* see whether we can add this span to the current list */ count = ras.num_gray_spans; span = ras.gray_spans + count - 1; - if ( count > 0 && - ras.span_y == y && - (int)span->x + span->len == (int)x && - span->coverage == coverage ) + if ( span->coverage == coverage && + span->x + span->len == x && + ras.span_y == y && + count > 0 ) { span->len = (unsigned short)( span->len + acount ); return; @@ -1356,7 +1393,6 @@ typedef ptrdiff_t FT_PtrDist; ras.num_gray_spans = 0; ras.span_y = (int)y; - count = 0; span = ras.gray_spans; } else @@ -1372,48 +1408,21 @@ typedef ptrdiff_t FT_PtrDist; } -#ifdef FT_DEBUG_LEVEL_TRACE - - /* to be called while in the debugger -- */ - /* this function causes a compiler warning since it is unused otherwise */ - static void - gray_dump_cells( RAS_ARG ) - { - int yindex; - - - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - { - PCell cell; - - - printf( "%3d:", yindex ); - - for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) - printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); - printf( "\n" ); - } - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - static void - gray_sweep( RAS_ARG_ const FT_Bitmap* target ) + gray_sweep( RAS_ARG ) { int yindex; - FT_UNUSED( target ); - if ( ras.num_cells == 0 ) return; ras.num_gray_spans = 0; + ras.span_y = 0; FT_TRACE7(( "gray_sweep: start\n" )); - for ( yindex = 0; yindex < ras.ycount; yindex++ ) + for ( yindex = 0; yindex < ras.count_ey; yindex++ ) { PCell cell = ras.ycells[yindex]; TCoord cover = 0; @@ -1422,15 +1431,15 @@ typedef ptrdiff_t FT_PtrDist; for ( ; cell != NULL; cell = cell->next ) { - TPos area; + TArea area; if ( cell->x > x && cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + gray_hline( RAS_VAR_ x, yindex, (TArea)cover * ( ONE_PIXEL * 2 ), cell->x - x ); cover += cell->cover; - area = cover * ( ONE_PIXEL * 2 ) - cell->area; + area = (TArea)cover * ( ONE_PIXEL * 2 ) - cell->area; if ( area != 0 && cell->x >= 0 ) gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); @@ -1439,7 +1448,7 @@ typedef ptrdiff_t FT_PtrDist; } if ( cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + gray_hline( RAS_VAR_ x, yindex, (TArea)cover * ( ONE_PIXEL * 2 ), ras.count_ex - x ); } @@ -1470,11 +1479,11 @@ typedef ptrdiff_t FT_PtrDist; } -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /*************************************************************************/ /* */ - /* The following function should only compile in stand-alone mode, */ + /* The following functions should only compile in stand-alone mode, */ /* i.e., when building this component without the rest of FreeType. */ /* */ /*************************************************************************/ @@ -1532,7 +1541,10 @@ typedef ptrdiff_t FT_PtrDist; TPos delta; - if ( !outline || !func_interface ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !func_interface ) return FT_THROW( Invalid_Argument ); shift = func_interface->shift; @@ -1749,23 +1761,101 @@ typedef ptrdiff_t FT_PtrDist; return FT_THROW( Invalid_Outline ); } -#endif /* _STANDALONE_ */ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* that contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component, which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + /* <Note> */ + /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ + /* */ + + static void + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ) + { + TPos xMin, yMin, xMax, yMax; + + + if ( outline && acbox ) + { + if ( outline->n_points == 0 ) + { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } + else + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for ( ; vec < limit; vec++ ) + { + TPos x, y; + + + x = vec->x; + if ( x < xMin ) xMin = x; + if ( x > xMax ) xMax = x; + + y = vec->y; + if ( y < yMin ) yMin = y; + if ( y > yMax ) yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } + } + +#endif /* STANDALONE_ */ typedef struct gray_TBand_ { - TPos min, max; + TCoord min, max; } gray_TBand; - FT_DEFINE_OUTLINE_FUNCS(func_interface, - (FT_Outline_MoveTo_Func) gray_move_to, - (FT_Outline_LineTo_Func) gray_line_to, - (FT_Outline_ConicTo_Func)gray_conic_to, - (FT_Outline_CubicTo_Func)gray_cubic_to, - 0, - 0 - ) + + FT_DEFINE_OUTLINE_FUNCS( + func_interface, + + (FT_Outline_MoveTo_Func) gray_move_to, + (FT_Outline_LineTo_Func) gray_line_to, + (FT_Outline_ConicTo_Func)gray_conic_to, + (FT_Outline_CubicTo_Func)gray_cubic_to, + 0, + 0 ) + static int gray_convert_glyph_inner( RAS_ARG ) @@ -1781,11 +1871,20 @@ typedef ptrdiff_t FT_PtrDist; if ( ft_setjmp( ras.jump_buffer ) == 0 ) { error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); - gray_record_cell( RAS_VAR ); + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); + + FT_TRACE7(( "band [%d..%d]: %d cells\n", + ras.min_ey, ras.max_ey, ras.num_cells )); } else + { error = FT_THROW( Memory_Overflow ); + FT_TRACE7(( "band [%d..%d]: to be bisected\n", + ras.min_ey, ras.max_ey )); + } + return error; } @@ -1793,87 +1892,59 @@ typedef ptrdiff_t FT_PtrDist; static int gray_convert_glyph( RAS_ARG ) { - gray_TBand bands[40]; - gray_TBand* volatile band; - int volatile n, num_bands; - TPos volatile min, max, max_y; - FT_BBox* clip; - + TCell buffer[FT_MAX_GRAY_POOL]; + TCoord band_size = FT_MAX_GRAY_POOL / 8; + int num_bands; + TCoord min, max, max_y; + gray_TBand bands[32]; /* enough to accommodate bisections */ + gray_TBand* band; - /* Set up state in the raster object */ - gray_compute_cbox( RAS_VAR ); - - /* clip to target bitmap, exit if nothing to do */ - clip = &ras.clip_box; - - if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || - ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) - return 0; - - if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; - if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; - - if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; - if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; - - ras.count_ex = ras.max_ex - ras.min_ex; - ras.count_ey = ras.max_ey - ras.min_ey; /* set up vertical bands */ - num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); - if ( num_bands == 0 ) - num_bands = 1; - if ( num_bands >= 39 ) - num_bands = 39; - - ras.band_shoot = 0; + if ( ras.count_ey > band_size ) + { + /* two divisions rounded up */ + num_bands = (int)( ( ras.count_ey + band_size - 1) / band_size ); + band_size = ( ras.count_ey + num_bands - 1 ) / num_bands; + } min = ras.min_ey; max_y = ras.max_ey; - for ( n = 0; n < num_bands; n++, min = max ) + for ( ; min < max_y; min = max ) { - max = min + ras.band_size; - if ( n == num_bands - 1 || max > max_y ) + max = min + band_size; + if ( max > max_y ) max = max_y; bands[0].min = min; bands[0].max = max; band = bands; - while ( band >= bands ) + do { - TPos bottom, top, middle; - int error; + TCoord bottom, top, middle; + int error; - { - PCell cells_max; - int yindex; - long cell_start, cell_end, cell_mod; + /* memory management */ + { + size_t ycount = (size_t)( band->max - band->min ); + size_t cell_start; - ras.ycells = (PCell*)ras.buffer; - ras.ycount = band->max - band->min; - - cell_start = sizeof ( PCell ) * ras.ycount; - cell_mod = cell_start % sizeof ( TCell ); - if ( cell_mod > 0 ) - cell_start += sizeof ( TCell ) - cell_mod; - cell_end = ras.buffer_size; - cell_end -= cell_end % sizeof ( TCell ); + cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / + sizeof ( TCell ); - cells_max = (PCell)( (char*)ras.buffer + cell_end ); - ras.cells = (PCell)( (char*)ras.buffer + cell_start ); - if ( ras.cells >= cells_max ) + if ( FT_MAX_GRAY_POOL - cell_start < 2 ) goto ReduceBands; - ras.max_cells = cells_max - ras.cells; - if ( ras.max_cells < 2 ) - goto ReduceBands; + ras.cells = buffer + cell_start; + ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start ); - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - ras.ycells[yindex] = NULL; + ras.ycells = (PCell*)buffer; + while ( ycount ) + ras.ycells[--ycount] = NULL; } ras.num_cells = 0; @@ -1886,7 +1957,7 @@ typedef ptrdiff_t FT_PtrDist; if ( !error ) { - gray_sweep( RAS_VAR_ &ras.target ); + gray_sweep( RAS_VAR ); band--; continue; } @@ -1903,40 +1974,34 @@ typedef ptrdiff_t FT_PtrDist; /* be some problems. */ if ( middle == bottom ) { -#ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); -#endif return 1; } - if ( bottom-top >= ras.band_size ) - ras.band_shoot++; - band[1].min = bottom; band[1].max = middle; band[0].min = middle; band[0].max = top; band++; - } + } while ( band >= bands ); } - if ( ras.band_shoot > 8 && ras.band_size > 16 ) - ras.band_size = ras.band_size / 2; - return 0; } static int - gray_raster_render( gray_PRaster raster, + gray_raster_render( FT_Raster raster, const FT_Raster_Params* params ) { - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; - gray_PWorker worker; + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; + FT_BBox cbox, clip; + + gray_TWorker worker[1]; - if ( !raster || !raster->buffer || !raster->buffer_size ) + if ( !raster ) return FT_THROW( Invalid_Argument ); if ( !outline ) @@ -1953,8 +2018,6 @@ typedef ptrdiff_t FT_PtrDist; outline->contours[outline->n_contours - 1] + 1 ) return FT_THROW( Invalid_Outline ); - worker = raster->worker; - /* if direct mode is not set, we must have a target bitmap */ if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { @@ -1973,32 +2036,51 @@ typedef ptrdiff_t FT_PtrDist; if ( !( params->flags & FT_RASTER_FLAG_AA ) ) return FT_THROW( Invalid_Mode ); + FT_Outline_Get_CBox( outline, &cbox ); + + /* reject too large outline coordinates */ + if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L || + cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L ) + return FT_THROW( Invalid_Outline ); + + /* truncate the bounding box to integer pixels */ + cbox.xMin = cbox.xMin >> 6; + cbox.yMin = cbox.yMin >> 6; + cbox.xMax = ( cbox.xMax + 63 ) >> 6; + cbox.yMax = ( cbox.yMax + 63 ) >> 6; + /* compute clipping box */ if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { /* compute clip box from target pixmap */ - ras.clip_box.xMin = 0; - ras.clip_box.yMin = 0; - ras.clip_box.xMax = target_map->width; - ras.clip_box.yMax = target_map->rows; + clip.xMin = 0; + clip.yMin = 0; + clip.xMax = (FT_Pos)target_map->width; + clip.yMax = (FT_Pos)target_map->rows; } else if ( params->flags & FT_RASTER_FLAG_CLIP ) - ras.clip_box = params->clip_box; + clip = params->clip_box; else { - ras.clip_box.xMin = -32768L; - ras.clip_box.yMin = -32768L; - ras.clip_box.xMax = 32767L; - ras.clip_box.yMax = 32767L; + clip.xMin = -32768L; + clip.yMin = -32768L; + clip.xMax = 32767L; + clip.yMax = 32767L; } - gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); + /* clip to target bitmap, exit if nothing to do */ + ras.min_ex = FT_MAX( cbox.xMin, clip.xMin ); + ras.min_ey = FT_MAX( cbox.yMin, clip.yMin ); + ras.max_ex = FT_MIN( cbox.xMax, clip.xMax ); + ras.max_ey = FT_MIN( cbox.yMax, clip.yMax ); + + if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) + return 0; + + ras.count_ex = ras.max_ex - ras.min_ex; + ras.count_ey = ras.max_ey - ras.min_ey; ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = raster->band_size; - ras.num_gray_spans = 0; if ( params->flags & FT_RASTER_FLAG_DIRECT ) { @@ -2019,7 +2101,7 @@ typedef ptrdiff_t FT_PtrDist; /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ /**** a static object. *****/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ static int gray_raster_new( void* memory, @@ -2044,7 +2126,7 @@ typedef ptrdiff_t FT_PtrDist; FT_UNUSED( raster ); } -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ static int gray_raster_new( FT_Memory memory, @@ -2074,54 +2156,44 @@ typedef ptrdiff_t FT_PtrDist; FT_FREE( raster ); } -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ static void - gray_raster_reset( FT_Raster raster, - char* pool_base, - long pool_size ) + gray_raster_reset( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ) { - gray_PRaster rast = (gray_PRaster)raster; + FT_UNUSED( raster ); + FT_UNUSED( pool_base ); + FT_UNUSED( pool_size ); + } - if ( raster ) - { - if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 ) - { - gray_PWorker worker = (gray_PWorker)pool_base; - - - rast->worker = worker; - rast->buffer = pool_base + - ( ( sizeof ( gray_TWorker ) + - sizeof ( TCell ) - 1 ) & - ~( sizeof ( TCell ) - 1 ) ); - rast->buffer_size = (long)( ( pool_base + pool_size ) - - (char*)rast->buffer ) & - ~( sizeof ( TCell ) - 1 ); - rast->band_size = (int)( rast->buffer_size / - ( sizeof ( TCell ) * 8 ) ); - } - else - { - rast->buffer = NULL; - rast->buffer_size = 0; - rast->worker = NULL; - } - } + static int + gray_raster_set_mode( FT_Raster raster, + unsigned long mode, + void* args ) + { + FT_UNUSED( raster ); + FT_UNUSED( mode ); + FT_UNUSED( args ); + + + return 0; /* nothing to do */ } - FT_DEFINE_RASTER_FUNCS(ft_grays_raster, + FT_DEFINE_RASTER_FUNCS( + ft_grays_raster, + FT_GLYPH_FORMAT_OUTLINE, (FT_Raster_New_Func) gray_raster_new, (FT_Raster_Reset_Func) gray_raster_reset, - (FT_Raster_Set_Mode_Func)0, + (FT_Raster_Set_Mode_Func)gray_raster_set_mode, (FT_Raster_Render_Func) gray_raster_render, - (FT_Raster_Done_Func) gray_raster_done - ) + (FT_Raster_Done_Func) gray_raster_done ) /* END */ diff --git a/drivers/freetype/src/smooth/ftgrays.h b/drivers/freetype/src/smooth/ftgrays.h index f20f55f14b..21c2badcaf 100644 --- a/drivers/freetype/src/smooth/ftgrays.h +++ b/drivers/freetype/src/smooth/ftgrays.h @@ -4,7 +4,7 @@ /* */ /* FreeType smooth renderer declaration */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,15 +16,15 @@ /***************************************************************************/ -#ifndef __FTGRAYS_H__ -#define __FTGRAYS_H__ +#ifndef FTGRAYS_H_ +#define FTGRAYS_H_ #ifdef __cplusplus extern "C" { #endif -#ifdef _STANDALONE_ +#ifdef STANDALONE_ #include "ftimage.h" #else #include <ft2build.h> @@ -52,7 +52,7 @@ } #endif -#endif /* __FTGRAYS_H__ */ +#endif /* FTGRAYS_H_ */ /* END */ diff --git a/drivers/freetype/src/smooth/ftsmerrs.h b/drivers/freetype/src/smooth/ftsmerrs.h index 413d2f1f70..a759b91c17 100644 --- a/drivers/freetype/src/smooth/ftsmerrs.h +++ b/drivers/freetype/src/smooth/ftsmerrs.h @@ -4,7 +4,7 @@ /* */ /* smooth renderer error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FTSMERRS_H__ -#define __FTSMERRS_H__ +#ifndef FTSMERRS_H_ +#define FTSMERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Smooth_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __FTSMERRS_H__ */ +#endif /* FTSMERRS_H_ */ /* END */ diff --git a/drivers/freetype/src/smooth/ftsmooth.c b/drivers/freetype/src/smooth/ftsmooth.c index 89088cd091..79276765b1 100644 --- a/drivers/freetype/src/smooth/ftsmooth.c +++ b/drivers/freetype/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2006, 2009-2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -103,25 +103,24 @@ FT_Render_Mode required_mode ) { FT_Error error; - FT_Outline* outline = NULL; + FT_Outline* outline = &slot->outline; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Memory memory = render->root.memory; FT_BBox cbox; + FT_Pos x_shift = 0; + FT_Pos y_shift = 0; + FT_Pos x_left, y_top; FT_Pos width, height, pitch; #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_Pos height_org, width_org; #endif - FT_Bitmap* bitmap = &slot->bitmap; - FT_Memory memory = render->root.memory; FT_Int hmul = mode == FT_RENDER_MODE_LCD; FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; - FT_Pos x_shift = 0; - FT_Pos y_shift = 0; - FT_Pos x_left, y_top; FT_Raster_Params params; - FT_Bool have_translated_origin = FALSE; - FT_Bool have_outline_shifted = FALSE; - FT_Bool have_buffer = FALSE; + FT_Bool have_outline_shifted = FALSE; + FT_Bool have_buffer = FALSE; /* check glyph image format */ @@ -138,73 +137,45 @@ goto Exit; } - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ if ( origin ) { - FT_Outline_Translate( outline, origin->x, origin->y ); - have_translated_origin = TRUE; + x_shift = origin->x; + y_shift = origin->y; } /* compute the control box, and grid fit it */ + /* taking into account the origin shift */ FT_Outline_Get_CBox( outline, &cbox ); - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL( cbox.yMax ); + cbox.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax + y_shift ); - if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large:" - " xMin = %d, xMax = %d\n", - cbox.xMin >> 6, cbox.xMax >> 6 )); - error = FT_THROW( Raster_Overflow ); - goto Exit; - } - else - width = ( cbox.xMax - cbox.xMin ) >> 6; + x_shift -= cbox.xMin; + y_shift -= cbox.yMin; - if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large:" - " yMin = %d, yMax = %d\n", - cbox.yMin >> 6, cbox.yMax >> 6 )); - error = FT_THROW( Raster_Overflow ); - goto Exit; - } - else - height = ( cbox.yMax - cbox.yMin ) >> 6; + x_left = cbox.xMin >> 6; + y_top = cbox.yMax >> 6; + + width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6; + height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6; #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING width_org = width; height_org = height; #endif - /* release old bitmap buffer */ - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { - FT_FREE( bitmap->buffer ); - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - - /* allocate new one */ pitch = width; if ( hmul ) { - width = width * 3; - pitch = FT_PAD_CEIL( width, 4 ); + width *= 3; + pitch = FT_PAD_CEIL( width, 4 ); } if ( vmul ) height *= 3; - x_shift = (FT_Int) cbox.xMin; - y_shift = (FT_Int) cbox.yMin; - x_left = (FT_Int)( cbox.xMin >> 6 ); - y_top = (FT_Int)( cbox.yMax >> 6 ); - #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING if ( slot->library->lcd_filter_func ) @@ -214,23 +185,32 @@ if ( hmul ) { - x_shift -= 64 * ( extra >> 1 ); + x_shift += 64 * ( extra >> 1 ); + x_left -= extra >> 1; width += 3 * extra; pitch = FT_PAD_CEIL( width, 4 ); - x_left -= extra >> 1; } if ( vmul ) { - y_shift -= 64 * ( extra >> 1 ); - height += 3 * extra; + y_shift += 64 * ( extra >> 1 ); y_top += extra >> 1; + height += 3 * extra; } } #endif -#if FT_UINT_MAX > 0xFFFFU + /* + * XXX: on 16bit system, we return an error for huge bitmap + * to prevent an overflow. + */ + if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX || + x_left < FT_INT_MIN || y_top < FT_INT_MIN ) + { + error = FT_THROW( Invalid_Pixel_Size ); + goto Exit; + } /* Required check is (pitch * height < FT_ULONG_MAX), */ /* but we care realistic cases only. Always pitch <= width. */ @@ -242,25 +222,38 @@ goto Exit; } -#endif - - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->num_grays = 256; - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = pitch; - - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -x_shift, -y_shift ); - have_outline_shifted = TRUE; + /* release old bitmap buffer */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } - if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) + /* allocate new one */ + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)( pitch * height ) ) ) goto Exit; else have_buffer = TRUE; slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = (FT_Int)x_left; + slot->bitmap_top = (FT_Int)y_top; + + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + bitmap->width = (unsigned int)width; + bitmap->rows = (unsigned int)height; + bitmap->pitch = pitch; + + /* translate outline to render it into the bitmap */ + if ( x_shift || y_shift ) + { + FT_Outline_Translate( outline, x_shift, y_shift ); + have_outline_shifted = TRUE; + } + /* set up parameters */ params.target = bitmap; params.source = outline; @@ -366,20 +359,6 @@ #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - /* - * XXX: on 16bit system, we return an error for huge bitmap - * to prevent an overflow. - */ - if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) - { - error = FT_THROW( Invalid_Pixel_Size ); - goto Exit; - } - - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = (FT_Int)x_left; - slot->bitmap_top = (FT_Int)y_top; - /* everything is fine; don't deallocate buffer */ have_buffer = FALSE; @@ -387,9 +366,7 @@ Exit: if ( have_outline_shifted ) - FT_Outline_Translate( outline, x_shift, y_shift ); - if ( have_translated_origin ) - FT_Outline_Translate( outline, -origin->x, -origin->y ); + FT_Outline_Translate( outline, -x_shift, -y_shift ); if ( have_buffer ) { FT_FREE( bitmap->buffer ); diff --git a/drivers/freetype/src/smooth/ftsmooth.h b/drivers/freetype/src/smooth/ftsmooth.h index 3708790df1..c7c28c244c 100644 --- a/drivers/freetype/src/smooth/ftsmooth.h +++ b/drivers/freetype/src/smooth/ftsmooth.h @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSMOOTH_H__ -#define __FTSMOOTH_H__ +#ifndef FTSMOOTH_H_ +#define FTSMOOTH_H_ #include <ft2build.h> @@ -43,7 +43,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSMOOTH_H__ */ +#endif /* FTSMOOTH_H_ */ /* END */ diff --git a/drivers/freetype/src/smooth/ftspic.c b/drivers/freetype/src/smooth/ftspic.c index 67a2b8310c..6c2b2329b3 100644 --- a/drivers/freetype/src/smooth/ftspic.c +++ b/drivers/freetype/src/smooth/ftspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/smooth/ftspic.h b/drivers/freetype/src/smooth/ftspic.h index 334b51c3f1..fe76152770 100644 --- a/drivers/freetype/src/smooth/ftspic.h +++ b/drivers/freetype/src/smooth/ftspic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,14 +16,15 @@ /***************************************************************************/ -#ifndef __FTSPIC_H__ -#define __FTSPIC_H__ +#ifndef FTSPIC_H_ +#define FTSPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H + +FT_BEGIN_HEADER + #ifndef FT_CONFIG_OPTION_PIC #define FT_GRAYS_RASTER_GET ft_grays_raster @@ -68,7 +69,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSPIC_H__ */ +#endif /* FTSPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/smooth/module.mk b/drivers/freetype/src/smooth/module.mk index 47f6c04076..f3cb044039 100644 --- a/drivers/freetype/src/smooth/module.mk +++ b/drivers/freetype/src/smooth/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/smooth/rules.mk b/drivers/freetype/src/smooth/rules.mk index 88d0aa53ac..5e94f73519 100644 --- a/drivers/freetype/src/smooth/rules.mk +++ b/drivers/freetype/src/smooth/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003, 2011 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,9 +17,13 @@ # SMOOTH_DIR := $(SRC_DIR)/smooth + # compilation flags for the driver # -SMOOTH_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SMOOTH_DIR)) +SMOOTH_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(SMOOTH_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # smooth driver sources (i.e., C files) diff --git a/drivers/freetype/src/smooth/smooth.c b/drivers/freetype/src/smooth/smooth.c index a8ac51f9f8..97ca3e5995 100644 --- a/drivers/freetype/src/smooth/smooth.c +++ b/drivers/freetype/src/smooth/smooth.c @@ -4,7 +4,7 @@ /* */ /* FreeType anti-aliasing rasterer module component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/truetype/Jamfile b/drivers/freetype/src/truetype/Jamfile index a8cccfe137..ecbb2dbdd2 100644 --- a/drivers/freetype/src/truetype/Jamfile +++ b/drivers/freetype/src/truetype/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/truetype Jamfile # -# Copyright 2001, 2004 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,15 @@ SubDir FT2_TOP $(FT2_SRC_DIR) truetype ; if $(FT2_MULTI) { - _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ttpic ; + _sources = ttdriver + ttgload + ttgxvar + ttinterp + ttobjs + ttpic + ttpload + ttsubpix + ; } else { diff --git a/drivers/freetype/src/truetype/module.mk b/drivers/freetype/src/truetype/module.mk index baee81a773..80c9832b2c 100644 --- a/drivers/freetype/src/truetype/module.mk +++ b/drivers/freetype/src/truetype/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/truetype/rules.mk b/drivers/freetype/src/truetype/rules.mk index d4b69f578b..3bf7cf770d 100644 --- a/drivers/freetype/src/truetype/rules.mk +++ b/drivers/freetype/src/truetype/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2001, 2003-2004, 2011-2012 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ TT_DIR := $(SRC_DIR)/truetype # compilation flags for the driver # -TT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) +TT_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # TrueType driver sources (i.e., C files) diff --git a/drivers/freetype/src/truetype/truetype.c b/drivers/freetype/src/truetype/truetype.c index 576912b219..23e2ea00a7 100644 --- a/drivers/freetype/src/truetype/truetype.c +++ b/drivers/freetype/src/truetype/truetype.c @@ -4,7 +4,7 @@ /* */ /* FreeType TrueType driver component (body only). */ /* */ -/* Copyright 1996-2001, 2004, 2006, 2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/truetype/ttdriver.c b/drivers/freetype/src/truetype/ttdriver.c index fb25706ab8..c9d4081efe 100644 --- a/drivers/freetype/src/truetype/ttdriver.c +++ b/drivers/freetype/src/truetype/ttdriver.c @@ -4,7 +4,7 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include FT_MULTIPLE_MASTERS_H @@ -72,12 +72,17 @@ FT_UInt* interpreter_version = (FT_UInt*)value; -#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) - error = FT_ERR( Unimplemented_Feature ); - else + if ( *interpreter_version == TT_INTERPRETER_VERSION_35 +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + || *interpreter_version == TT_INTERPRETER_VERSION_38 #endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + || *interpreter_version == TT_INTERPRETER_VERSION_40 +#endif + ) driver->interpreter_version = *interpreter_version; + else + error = FT_ERR( Unimplemented_Feature ); return error; } @@ -117,8 +122,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( tt_service_properties, - (FT_Properties_SetFunc)tt_property_set, - (FT_Properties_GetFunc)tt_property_get ) + (FT_Properties_SetFunc)tt_property_set, /* set_property */ + (FT_Properties_GetFunc)tt_property_get ) /* get_property */ /*************************************************************************/ @@ -134,11 +139,6 @@ /*************************************************************************/ -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - /*************************************************************************/ /* */ /* <Function> */ @@ -191,9 +191,6 @@ } -#undef PAIR_TAG - - static FT_Error tt_get_advances( FT_Face ttface, FT_UInt start, @@ -202,7 +199,7 @@ FT_Fixed *advances ) { FT_UInt nn; - TT_Face face = (TT_Face) ttface; + TT_Face face = (TT_Face) ttface; /* XXX: TODO: check for sbits */ @@ -215,7 +212,8 @@ FT_UShort ah; - TT_Get_VMetrics( face, start + nn, &tsb, &ah ); + /* since we don't need `tsb', we use zero for `yMax' parameter */ + TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah ); advances[nn] = ah; } } @@ -235,6 +233,7 @@ return FT_Err_Ok; } + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -266,7 +265,7 @@ /* use the scaled metrics, even when tt_size_reset fails */ FT_Select_Metrics( size->face, strike_index ); - tt_size_reset( ttsize ); + tt_size_reset( ttsize ); /* ignore return value */ } else { @@ -369,7 +368,7 @@ return FT_THROW( Invalid_Size_Handle ); if ( !face ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Face_Handle ); #ifdef FT_CONFIG_OPTION_INCREMENTAL if ( glyph_index >= (FT_UInt)face->num_glyphs && @@ -424,22 +423,19 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, - (FT_Set_MM_Design_Func) NULL, - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, - (FT_Get_MM_Var_Func) TT_Get_MM_Var, - (FT_Set_Var_Design_Func)TT_Set_Var_Design ) + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)TT_Set_Var_Design ) /* set_var_design */ #endif + static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = { #ifdef TT_USE_BYTECODE_INTERPRETER -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_TRUETYPE_ENGINE_TYPE_UNPATENTED -#else FT_TRUETYPE_ENGINE_TYPE_PATENTED -#endif #else /* !TT_USE_BYTECODE_INTERPRETER */ @@ -448,14 +444,16 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ }; + FT_DEFINE_SERVICE_TTGLYFREC( tt_service_truetype_glyf, - (TT_Glyf_GetLocationFunc)tt_face_get_location ) + (TT_Glyf_GetLocationFunc)tt_face_get_location ) /* get_location */ + #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_DEFINE_SERVICEDESCREC5( tt_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, @@ -463,7 +461,7 @@ #else FT_DEFINE_SERVICEDESCREC4( tt_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) @@ -480,7 +478,7 @@ SFNT_Service sfnt; - /* TT_SERVICES_GET derefers `library' in PIC mode */ + /* TT_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC if ( !driver ) return NULL; @@ -541,31 +539,31 @@ 0x10000L, /* driver version == 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or above */ - (void*)0, /* driver specific interface */ + 0, /* module-specific interface */ - tt_driver_init, - tt_driver_done, - tt_get_interface, + tt_driver_init, /* FT_Module_Constructor module_init */ + tt_driver_done, /* FT_Module_Destructor module_done */ + tt_get_interface, /* FT_Module_Requester get_interface */ sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - tt_face_init, - tt_face_done, - tt_size_init, - tt_size_done, - tt_slot_init, - 0, /* FT_Slot_DoneFunc */ + tt_face_init, /* FT_Face_InitFunc init_face */ + tt_face_done, /* FT_Face_DoneFunc done_face */ + tt_size_init, /* FT_Size_InitFunc init_size */ + tt_size_done, /* FT_Size_DoneFunc done_size */ + tt_slot_init, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - tt_glyph_load, + tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - tt_get_kerning, - 0, /* FT_Face_AttachFunc */ - tt_get_advances, + tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - tt_size_request, - TT_SIZE_SELECT + tt_size_request, /* FT_Size_RequestFunc request_size */ + TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/drivers/freetype/src/truetype/ttdriver.h b/drivers/freetype/src/truetype/ttdriver.h index aae00f2617..74392bbd02 100644 --- a/drivers/freetype/src/truetype/ttdriver.h +++ b/drivers/freetype/src/truetype/ttdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level TrueType driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTDRIVER_H__ -#define __TTDRIVER_H__ +#ifndef TTDRIVER_H_ +#define TTDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTDRIVER_H__ */ +#endif /* TTDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/src/truetype/tterrors.h b/drivers/freetype/src/truetype/tterrors.h index 78d138fab2..895989f5fd 100644 --- a/drivers/freetype/src/truetype/tterrors.h +++ b/drivers/freetype/src/truetype/tterrors.h @@ -4,7 +4,7 @@ /* */ /* TrueType error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __TTERRORS_H__ -#define __TTERRORS_H__ +#ifndef TTERRORS_H_ +#define TTERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX TT_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __TTERRORS_H__ */ +#endif /* TTERRORS_H_ */ + /* END */ diff --git a/drivers/freetype/src/truetype/ttgload.c b/drivers/freetype/src/truetype/ttgload.c index f640a6c78e..8be9b6ae65 100644 --- a/drivers/freetype/src/truetype/ttgload.c +++ b/drivers/freetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2013 */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,7 @@ #include FT_TRUETYPE_TAGS_H #include FT_OUTLINE_H #include FT_TRUETYPE_DRIVER_H +#include FT_LIST_H #include "ttgload.h" #include "ttpload.h" @@ -85,92 +86,94 @@ /*************************************************************************/ /* */ /* Return the vertical metrics in font units for a given glyph. */ - /* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */ - /* table, typoAscender/Descender from the `OS/2' table would be used */ - /* instead, and if there were no `OS/2' table, use ascender/descender */ - /* from the `hhea' table. But that is not what Microsoft's rasterizer */ - /* apparently does: It uses the ppem value as the advance height, and */ - /* sets the top side bearing to be zero. */ + /* See macro `TT_LOADER_SET_PP' below for explanations. */ /* */ FT_LOCAL_DEF( void ) TT_Get_VMetrics( TT_Face face, FT_UInt idx, + FT_Pos yMax, FT_Short* tsb, FT_UShort* ah ) { if ( face->vertical_info ) ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah ); -#if 1 /* Empirically determined, at variance with what MS said */ - - else - { - *tsb = 0; - *ah = face->root.units_per_EM; - } - -#else /* This is what MS said to do. It isn't what they do, however. */ - else if ( face->os2.version != 0xFFFFU ) { - *tsb = face->os2.sTypoAscender; - *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; + *tsb = (FT_Short)( face->os2.sTypoAscender - yMax ); + *ah = (FT_UShort)FT_ABS( face->os2.sTypoAscender - + face->os2.sTypoDescender ); } + else { - *tsb = face->horizontal.Ascender; - *ah = face->horizontal.Ascender - face->horizontal.Descender; + *tsb = (FT_Short)( face->horizontal.Ascender - yMax ); + *ah = (FT_UShort)FT_ABS( face->horizontal.Ascender - + face->horizontal.Descender ); } -#endif - FT_TRACE5(( " advance height (font units): %d\n", *ah )); FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); } - static void + static FT_Error tt_get_metrics( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Face face = loader->face; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif + FT_Error error; + FT_Stream stream = loader->stream; + FT_Short left_bearing = 0, top_bearing = 0; FT_UShort advance_width = 0, advance_height = 0; + /* we must preserve the stream position */ + /* (which gets altered by the metrics functions) */ + FT_ULong pos = FT_STREAM_POS(); + TT_Get_HMetrics( face, glyph_index, &left_bearing, &advance_width ); TT_Get_VMetrics( face, glyph_index, + loader->bbox.yMax, &top_bearing, &advance_height ); + if ( FT_STREAM_SEEK( pos ) ) + return error; + loader->left_bearing = left_bearing; loader->advance = advance_width; loader->top_bearing = top_bearing; loader->vadvance = advance_height; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && + loader->exec ) { - if ( loader->exec ) - loader->exec->sph_tweak_flags = 0; + loader->exec->sph_tweak_flags = 0; - /* this may not be the right place for this, but it works */ - if ( loader->exec && loader->exec->ignore_x_mode ) - sph_set_tweaks( loader, glyph_index ); + /* This may not be the right place for this, but it works... */ + /* Note that we have to unconditionally load the tweaks since */ + /* it is possible that glyphs individually switch ClearType's */ + /* backwards compatibility mode on and off. */ + sph_set_tweaks( loader, glyph_index ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( !loader->linear_def ) { loader->linear_def = 1; loader->linear = advance_width; } + + return FT_Err_Ok; } @@ -180,7 +183,7 @@ tt_get_metrics_incr_overrides( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_Short left_bearing = 0, top_bearing = 0; FT_UShort advance_width = 0, advance_height = 0; @@ -246,29 +249,6 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ - /*************************************************************************/ - /* */ - /* Translates an array of coordinates. */ - /* */ - static void - translate_array( FT_UInt n, - FT_Vector* coords, - FT_Pos delta_x, - FT_Pos delta_y ) - { - FT_UInt k; - - - if ( delta_x ) - for ( k = 0; k < n; k++ ) - coords[k].x += delta_x; - - if ( delta_y ) - for ( k = 0; k < n; k++ ) - coords[k].y += delta_y; - } - - /*************************************************************************/ /* */ /* The following functions are used by default with TrueType fonts. */ @@ -350,9 +330,9 @@ FT_GlyphLoader gloader = load->gloader; FT_Int n_contours = load->n_contours; FT_Outline* outline; - TT_Face face = (TT_Face)load->face; FT_UShort n_ins; FT_Int n_points; + FT_ULong tmp; FT_Byte *flag, *flag_limit; FT_Byte c, count; @@ -409,7 +389,7 @@ /* reading the bytecode instructions */ load->glyph->control_len = 0; - load->glyph->control_data = 0; + load->glyph->control_data = NULL; if ( p + 2 > limit ) goto Invalid_Outline; @@ -418,14 +398,7 @@ FT_TRACE5(( " Instructions size: %u\n", n_ins )); - if ( n_ins > face->max_profile.maxSizeOfInstructions ) - { - FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", - n_ins )); - error = FT_THROW( Too_Many_Hints ); - goto Fail; - } - + /* check it */ if ( ( limit - p ) < n_ins ) { FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); @@ -437,10 +410,25 @@ if ( IS_HINTED( load->load_flags ) ) { + /* we don't trust `maxSizeOfInstructions' in the `maxp' table */ + /* and thus update the bytecode array size by ourselves */ + + tmp = load->exec->glyphSize; + error = Update_Max( load->exec->memory, + &tmp, + sizeof ( FT_Byte ), + (void*)&load->exec->glyphIns, + n_ins ); + + load->exec->glyphSize = (FT_UShort)tmp; + if ( error ) + return error; + load->glyph->control_len = n_ins; load->glyph->control_data = load->exec->glyphIns; - FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); + if ( n_ins ) + FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); } #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -550,8 +538,8 @@ *flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); } - outline->n_points = (FT_UShort)n_points; - outline->n_contours = (FT_Short) n_contours; + outline->n_points = (FT_Short)n_points; + outline->n_contours = (FT_Short)n_contours; load->cursor = p; @@ -614,15 +602,31 @@ goto Invalid_Composite; /* read arguments */ - if ( subglyph->flags & ARGS_ARE_WORDS ) + if ( subglyph->flags & ARGS_ARE_XY_VALUES ) { - subglyph->arg1 = FT_NEXT_SHORT( p ); - subglyph->arg2 = FT_NEXT_SHORT( p ); + if ( subglyph->flags & ARGS_ARE_WORDS ) + { + subglyph->arg1 = FT_NEXT_SHORT( p ); + subglyph->arg2 = FT_NEXT_SHORT( p ); + } + else + { + subglyph->arg1 = FT_NEXT_CHAR( p ); + subglyph->arg2 = FT_NEXT_CHAR( p ); + } } else { - subglyph->arg1 = FT_NEXT_CHAR( p ); - subglyph->arg2 = FT_NEXT_CHAR( p ); + if ( subglyph->flags & ARGS_ARE_WORDS ) + { + subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p ); + subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p ); + } + else + { + subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p ); + subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p ); + } } /* read transform */ @@ -631,20 +635,20 @@ if ( subglyph->flags & WE_HAVE_A_SCALE ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; yy = xx; } else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; } else if ( subglyph->flags & WE_HAVE_A_2X2 ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + xy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; } subglyph->transform.xx = xx; @@ -657,6 +661,7 @@ } while ( subglyph->flags & MORE_COMPONENTS ); gloader->current.num_subglyphs = num_subglyphs; + FT_TRACE5(( " %d components\n", num_subglyphs )); #ifdef TT_USE_BYTECODE_INTERPRETER @@ -702,9 +707,10 @@ FT_UInt start_point, FT_UInt start_contour ) { - zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); - zone->n_contours = (FT_Short) ( load->outline.n_contours - - start_contour ); + zone->n_points = (FT_UShort)load->outline.n_points - + (FT_UShort)start_point; + zone->n_contours = load->outline.n_contours - + (FT_Short)start_contour; zone->org = load->extra_points + start_point; zone->cur = load->outline.points + start_point; zone->orus = load->extra_points2 + start_point; @@ -727,16 +733,16 @@ TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Face face = (TT_Face)loader->face; +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif TT_GlyphZone zone = &loader->zone; - FT_Pos origin; #ifdef TT_USE_BYTECODE_INTERPRETER - FT_UInt n_ins; + FT_Long n_ins; #else FT_UNUSED( is_composite ); #endif @@ -745,25 +751,18 @@ #ifdef TT_USE_BYTECODE_INTERPRETER if ( loader->glyph->control_len > 0xFFFFL ) { - FT_TRACE1(( "TT_Hint_Glyph: too long instructions " )); - FT_TRACE1(( "(0x%lx byte) is truncated\n", + FT_TRACE1(( "TT_Hint_Glyph: too long instructions" )); + FT_TRACE1(( " (0x%lx byte) is truncated\n", loader->glyph->control_len )); } - n_ins = (FT_UInt)( loader->glyph->control_len ); -#endif + n_ins = loader->glyph->control_len; - origin = zone->cur[zone->n_points - 4].x; - origin = FT_PIX_ROUND( origin ) - origin; - if ( origin ) - translate_array( zone->n_points, zone->cur, origin, 0 ); - -#ifdef TT_USE_BYTECODE_INTERPRETER /* save original point position in org */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); /* Reset graphics state. */ - loader->exec->GS = ((TT_Size)loader->size)->GS; + loader->exec->GS = loader->size->GS; /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ /* completely refer to the (already) hinted subglyphs. */ @@ -776,16 +775,18 @@ } else { - loader->exec->metrics.x_scale = - ((TT_Size)loader->size)->metrics.x_scale; - loader->exec->metrics.y_scale = - ((TT_Size)loader->size)->metrics.y_scale; + loader->exec->metrics.x_scale = loader->size->metrics.x_scale; + loader->exec->metrics.y_scale = loader->size->metrics.y_scale; } #endif - /* round pp2 and pp4 */ + /* round phantom points */ + zone->cur[zone->n_points - 4].x = + FT_PIX_ROUND( zone->cur[zone->n_points - 4].x ); zone->cur[zone->n_points - 3].x = FT_PIX_ROUND( zone->cur[zone->n_points - 3].x ); + zone->cur[zone->n_points - 2].y = + FT_PIX_ROUND( zone->cur[zone->n_points - 2].y ); zone->cur[zone->n_points - 1].y = FT_PIX_ROUND( zone->cur[zone->n_points - 1].y ); @@ -793,25 +794,19 @@ if ( n_ins > 0 ) { - FT_Bool debug; FT_Error error; FT_GlyphLoader gloader = loader->gloader; FT_Outline current_outline = gloader->current.outline; - error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, - loader->exec->glyphIns, n_ins ); - if ( error ) - return error; + TT_Set_CodeRange( loader->exec, tt_coderange_glyph, + loader->exec->glyphIns, n_ins ); loader->exec->is_composite = is_composite; loader->exec->pts = *zone; - debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && - ((TT_Size)loader->size)->debug ); - - error = TT_Run_Context( loader->exec, debug ); + error = TT_Run_Context( loader->exec ); if ( error && loader->exec->pedantic_hinting ) return error; @@ -822,16 +817,23 @@ #endif - /* save glyph phantom points */ - if ( !loader->preserve_pps ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Save possibly modified glyph phantom points unless in v40 backwards */ + /* compatibility mode, where no movement on the x axis means no reason */ + /* to change bearings or advance widths. */ + if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + !loader->exec->backwards_compatibility ) ) { +#endif loader->pp1 = zone->cur[zone->n_points - 4]; loader->pp2 = zone->cur[zone->n_points - 3]; loader->pp3 = zone->cur[zone->n_points - 2]; loader->pp4 = zone->cur[zone->n_points - 1]; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL } +#endif -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) @@ -840,7 +842,7 @@ else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ return FT_Err_Ok; } @@ -884,28 +886,15 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( ((TT_Face)loader->face)->doblend ) + if ( loader->face->doblend ) { /* Deltas apply to the unscaled data. */ - FT_Vector* deltas; - FT_Memory memory = loader->face->memory; - FT_Int i; - - - error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), - loader->glyph_index, - &deltas, - n_points ); + error = TT_Vary_Apply_Glyph_Deltas( loader->face, + loader->glyph_index, + outline, + (FT_UInt)n_points ); if ( error ) return error; - - for ( i = 0; i < n_points; ++i ) - { - outline->points[i].x += deltas[i].x; - outline->points[i].y += deltas[i].y; - } - - FT_FREE( deltas ); } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -919,14 +908,14 @@ } { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Face face = (TT_Face)loader->face; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); FT_String* family = face->root.family_name; - FT_Int ppem = loader->size->metrics.x_ppem; + FT_UInt ppem = loader->size->metrics.x_ppem; FT_String* style = face->root.style_name; - FT_Int x_scale_factor = 1000; + FT_UInt x_scale_factor = 1000; #endif FT_Vector* vec = outline->points; @@ -938,7 +927,7 @@ FT_Bool do_scale = FALSE; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -953,9 +942,9 @@ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || x_scale_factor != 1000 ) { - x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale, - x_scale_factor, 1000 ); - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + x_scale = FT_MulDiv( loader->size->metrics.x_scale, + (FT_Long)x_scale_factor, 1000 ); + y_scale = loader->size->metrics.y_scale; /* compensate for any scaling by de/emboldening; */ /* the amount was determined via experimentation */ @@ -969,14 +958,14 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = ((TT_Size)loader->size)->metrics.x_scale; - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + x_scale = loader->size->metrics.x_scale; + y_scale = loader->size->metrics.y_scale; do_scale = TRUE; } @@ -1023,32 +1012,31 @@ FT_UInt start_point, FT_UInt num_base_points ) { - FT_GlyphLoader gloader = loader->gloader; - FT_Vector* base_vec = gloader->base.outline.points; - FT_UInt num_points = gloader->base.outline.n_points; + FT_GlyphLoader gloader = loader->gloader; + FT_Outline current; FT_Bool have_scale; FT_Pos x, y; + current.points = gloader->base.outline.points + + num_base_points; + current.n_points = gloader->base.outline.n_points - + (short)num_base_points; + have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2 ) ); /* perform the transform required for this subglyph */ if ( have_scale ) - { - FT_UInt i; - - - for ( i = num_base_points; i < num_points; i++ ) - FT_Vector_Transform( base_vec + i, &subglyph->transform ); - } + FT_Outline_Transform( ¤t, &subglyph->transform ); /* get offset */ if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) { - FT_UInt k = subglyph->arg1; - FT_UInt l = subglyph->arg2; + FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points; + FT_UInt k = (FT_UInt)subglyph->arg1; + FT_UInt l = (FT_UInt)subglyph->arg2; FT_Vector* p1; FT_Vector* p2; @@ -1077,9 +1065,9 @@ if ( !x && !y ) return FT_Err_Ok; - /* Use a default value dependent on */ - /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */ - /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */ + /* Use a default value dependent on */ + /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old */ + /* TT fonts which don't set the xxx_COMPONENT_OFFSET bit. */ if ( have_scale && #ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED @@ -1091,17 +1079,17 @@ #if 0 - /*************************************************************************/ - /* */ - /* This algorithm is what Apple documents. But it doesn't work. */ - /* */ + /*******************************************************************/ + /* */ + /* This algorithm is what Apple documents. But it doesn't work. */ + /* */ int a = subglyph->transform.xx > 0 ? subglyph->transform.xx : -subglyph->transform.xx; int b = subglyph->transform.yx > 0 ? subglyph->transform.yx : -subglyph->transform.yx; int c = subglyph->transform.xy > 0 ? subglyph->transform.xy : -subglyph->transform.xy; - int d = subglyph->transform.yy > 0 ? subglyph->transform.yy + int d = subglyph->transform.yy > 0 ? subglyph->transform.yy : -subglyph->transform.yy; int m = a > b ? a : b; int n = c > d ? c : d; @@ -1114,12 +1102,12 @@ x = FT_MulFix( x, m ); y = FT_MulFix( y, n ); -#else /* 0 */ +#else /* 1 */ - /*************************************************************************/ - /* */ - /* This algorithm is a guess and works much better than the above. */ - /* */ + /*******************************************************************/ + /* */ + /* This algorithm is a guess and works much better than the above. */ + /* */ FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx, subglyph->transform.xy ); FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy, @@ -1129,14 +1117,14 @@ x = FT_MulFix( x, mac_xscale ); y = FT_MulFix( y, mac_yscale ); -#endif /* 0 */ +#endif /* 1 */ } if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { - FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; - FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; + FT_Fixed x_scale = loader->size->metrics.x_scale; + FT_Fixed y_scale = loader->size->metrics.y_scale; x = FT_MulFix( x, x_scale ); @@ -1151,9 +1139,7 @@ } if ( x || y ) - translate_array( num_points - num_base_points, - base_vec + num_base_points, - x, y ); + FT_Outline_Translate( ¤t, x, y ); return FT_Err_Ok; } @@ -1215,24 +1201,26 @@ FT_TRACE5(( " Instructions size = %d\n", n_ins )); /* check it */ - max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions; + max_ins = loader->face->max_profile.maxSizeOfInstructions; if ( n_ins > max_ins ) { - /* acroread ignores this field, so we only do a rough safety check */ + /* don't trust `maxSizeOfInstructions'; */ + /* only do a rough safety check */ if ( (FT_Int)n_ins > loader->byte_len ) { - FT_TRACE1(( "TT_Process_Composite_Glyph: " - "too many instructions (%d) for glyph with length %d\n", + FT_TRACE1(( "TT_Process_Composite_Glyph:" + " too many instructions (%d) for glyph with length %d\n", n_ins, loader->byte_len )); return FT_THROW( Too_Many_Hints ); } - tmp = loader->exec->glyphSize; + tmp = loader->exec->glyphSize; error = Update_Max( loader->exec->memory, &tmp, sizeof ( FT_Byte ), (void*)&loader->exec->glyphIns, n_ins ); + loader->exec->glyphSize = (FT_UShort)tmp; if ( error ) return error; @@ -1254,7 +1242,7 @@ /* Some points are likely touched during execution of */ /* instructions on components. So let's untouch them. */ - for ( i = start_point; i < loader->zone.n_points; i++ ) + for ( i = 0; i < loader->zone.n_points; i++ ) loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; loader->zone.n_points += 4; @@ -1263,20 +1251,155 @@ } - /* Calculate the four phantom points. */ - /* The first two stand for horizontal origin and advance. */ - /* The last two stand for vertical origin and advance. */ -#define TT_LOADER_SET_PP( loader ) \ - do { \ - (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ - (loader)->pp1.y = 0; \ - (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ - (loader)->pp2.y = 0; \ - (loader)->pp3.x = 0; \ - (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax; \ - (loader)->pp4.x = 0; \ - (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ - } while ( 0 ) + /* + * Calculate the phantom points + * + * Defining the right side bearing (rsb) as + * + * rsb = aw - (lsb + xmax - xmin) + * + * (with `aw' the advance width, `lsb' the left side bearing, and `xmin' + * and `xmax' the glyph's minimum and maximum x value), the OpenType + * specification defines the initial position of horizontal phantom points + * as + * + * pp1 = (round(xmin - lsb), 0) , + * pp2 = (round(pp1 + aw), 0) . + * + * Note that the rounding to the grid (in the device space) is not + * documented currently in the specification. + * + * However, the specification lacks the precise definition of vertical + * phantom points. Greg Hitchcock provided the following explanation. + * + * - a `vmtx' table is present + * + * For any glyph, the minimum and maximum y values (`ymin' and `ymax') + * are given in the `glyf' table, the top side bearing (tsb) and advance + * height (ah) are given in the `vmtx' table. The bottom side bearing + * (bsb) is then calculated as + * + * bsb = ah - (tsb + ymax - ymin) , + * + * and the initial position of vertical phantom points is + * + * pp3 = (x, round(ymax + tsb)) , + * pp4 = (x, round(pp3 - ah)) . + * + * See below for value `x'. + * + * - no `vmtx' table in the font + * + * If there is an `OS/2' table, we set + * + * DefaultAscender = sTypoAscender , + * DefaultDescender = sTypoDescender , + * + * otherwise we use data from the `hhea' table: + * + * DefaultAscender = Ascender , + * DefaultDescender = Descender . + * + * With these two variables we can now set + * + * ah = DefaultAscender - sDefaultDescender , + * tsb = DefaultAscender - yMax , + * + * and proceed as if a `vmtx' table was present. + * + * Usually we have + * + * x = aw / 2 , (1) + * + * but there is one compatibility case where it can be set to + * + * x = -DefaultDescender - + * ((DefaultAscender - DefaultDescender - aw) / 2) . (2) + * + * and another one with + * + * x = 0 . (3) + * + * In Windows, the history of those values is quite complicated, + * depending on the hinting engine (that is, the graphics framework). + * + * framework from to formula + * ---------------------------------------------------------- + * GDI Windows 98 current (1) + * (Windows 2000 for NT) + * GDI+ Windows XP Windows 7 (2) + * GDI+ Windows 8 current (3) + * DWrite Windows 7 current (3) + * + * For simplicity, FreeType uses (1) for grayscale subpixel hinting and + * (3) for everything else. + * + */ + static void + tt_loader_set_pp( TT_Loader loader ) + { + FT_Bool subpixel_hinting = 0; + FT_Bool grayscale = 0; + FT_Bool use_aw_2 = 0; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face ); +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting + : 0; + grayscale = loader->exec ? loader->exec->grayscale + : 0; + } +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean + : 0; + grayscale = loader->exec ? loader->exec->grayscale_cleartype + : 0; + } +#endif + + use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale ); + + loader->pp1.x = loader->bbox.xMin - loader->left_bearing; + loader->pp1.y = 0; + loader->pp2.x = loader->pp1.x + loader->advance; + loader->pp2.y = 0; + + loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp3.y = loader->bbox.yMax + loader->top_bearing; + loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp4.y = loader->pp3.y - loader->vadvance; + } + + + /* a utility function to retrieve i-th node from given FT_List */ + static FT_ListNode + ft_list_get_node_at( FT_List list, + FT_UInt index ) + { + FT_ListNode cur; + + + if ( !list ) + return NULL; + + for ( cur = list->head; cur; cur = cur->next ) + { + if ( !index ) + return cur; + + index--; + } + + return NULL; + } /*************************************************************************/ @@ -1297,14 +1420,10 @@ FT_Error error = FT_Err_Ok; FT_Fixed x_scale, y_scale; FT_ULong offset; - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_GlyphLoader gloader = loader->gloader; FT_Bool opened_frame = 0; -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Vector* deltas = NULL; -#endif - #ifdef FT_CONFIG_OPTION_INCREMENTAL FT_StreamRec inc_stream; FT_Data glyph_data; @@ -1312,6 +1431,11 @@ #endif +#ifdef FT_DEBUG_LEVEL_TRACE + if ( recurse_count ) + FT_TRACE5(( " nesting level: %d\n", recurse_count )); +#endif + /* some fonts have an incorrect value of `maxComponentDepth', */ /* thus we allow depth 1 to catch the majority of them */ if ( recurse_count > 1 && @@ -1321,19 +1445,21 @@ goto Exit; } +#ifndef FT_CONFIG_OPTION_INCREMENTAL /* check glyph index */ if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) { error = FT_THROW( Invalid_Glyph_Index ); goto Exit; } +#endif loader->glyph_index = glyph_index; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = ((TT_Size)loader->size)->metrics.x_scale; - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + x_scale = loader->size->metrics.x_scale; + y_scale = loader->size->metrics.y_scale; } else { @@ -1341,8 +1467,6 @@ y_scale = 0x10000L; } - tt_get_metrics( loader, glyph_index ); - /* Set `offset' to the start of the glyph relative to the start of */ /* the `glyf' table, and `byte_len' to the length of the glyph in */ /* bytes. */ @@ -1366,7 +1490,8 @@ FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); FT_Stream_OpenMemory( &inc_stream, - glyph_data.pointer, glyph_data.length ); + glyph_data.pointer, + (FT_ULong)glyph_data.length ); loader->stream = &inc_stream; } @@ -1394,7 +1519,7 @@ error = face->access_glyph_frame( loader, glyph_index, loader->glyf_offset + offset, - loader->byte_len ); + (FT_UInt)loader->byte_len ); if ( error ) goto Exit; @@ -1402,7 +1527,17 @@ /* read glyph header first */ error = face->read_glyph_header( loader ); - if ( error || header_only ) + if ( error ) + goto Exit; + + /* the metrics must be computed after loading the glyph header */ + /* since we need the glyph's `yMax' value in case the vertical */ + /* metrics must be emulated */ + error = tt_get_metrics( loader, glyph_index ); + if ( error ) + goto Exit; + + if ( header_only ) goto Exit; } @@ -1413,12 +1548,16 @@ loader->bbox.yMin = 0; loader->bbox.yMax = 0; + error = tt_get_metrics( loader, glyph_index ); + if ( error ) + goto Exit; + if ( header_only ) goto Exit; /* must initialize points before (possibly) overriding */ /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); + tt_loader_set_pp( loader ); #ifdef FT_CONFIG_OPTION_INCREMENTAL tt_get_metrics_incr_overrides( loader, glyph_index ); @@ -1426,32 +1565,64 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( ((TT_Face)(loader->face))->doblend ) + if ( loader->face->doblend ) { - /* this must be done before scaling */ - FT_Memory memory = loader->face->memory; + /* a small outline structure with four elements for */ + /* communication with `TT_Vary_Apply_Glyph_Deltas' */ + FT_Vector points[4]; + char tags[4] = { 1, 1, 1, 1 }; + short contours[4] = { 0, 1, 2, 3 }; + FT_Outline outline; + + + points[0].x = loader->pp1.x; + points[0].y = loader->pp1.y; + points[1].x = loader->pp2.x; + points[1].y = loader->pp2.y; + + points[2].x = loader->pp3.x; + points[2].y = loader->pp3.y; + points[3].x = loader->pp4.x; + points[3].y = loader->pp4.y; + + outline.n_points = 4; + outline.n_contours = 4; + outline.points = points; + outline.tags = tags; + outline.contours = contours; - - error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), - glyph_index, &deltas, 4 ); + /* this must be done before scaling */ + error = TT_Vary_Apply_Glyph_Deltas( loader->face, + glyph_index, + &outline, + (FT_UInt)outline.n_points ); if ( error ) goto Exit; - loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y; - loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y; - loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y; - loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y; + loader->pp1.x = points[0].x; + loader->pp1.y = points[0].y; + loader->pp2.x = points[1].x; + loader->pp2.y = points[1].y; - FT_FREE( deltas ); + loader->pp3.x = points[2].x; + loader->pp3.y = points[2].y; + loader->pp4.x = points[3].x; + loader->pp4.y = points[3].y; } -#endif +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + /* scale phantom points, if necessary; */ + /* they get rounded in `TT_Hint_Glyph' */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + /* pp1.y and pp2.y are always zero */ + + loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale ); loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale ); loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); } @@ -1459,9 +1630,9 @@ goto Exit; } - /* must initialize points before (possibly) overriding */ - /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); + /* must initialize phantom points before (possibly) overriding */ + /* glyph metrics from the incremental interface */ + tt_loader_set_pp( loader ); #ifdef FT_CONFIG_OPTION_INCREMENTAL tt_get_metrics_incr_overrides( loader, glyph_index ); @@ -1497,13 +1668,51 @@ /* otherwise, load a composite! */ else if ( loader->n_contours == -1 ) { + FT_Memory memory = face->root.memory; + FT_UInt start_point; FT_UInt start_contour; FT_ULong ins_pos; /* position of composite instructions, if any */ + FT_ListNode node, node2; + + + /* + * We store the glyph index directly in the `node->data' pointer, + * following the glib solution (cf. macro `GUINT_TO_POINTER') with a + * double cast to make this portable. Note, however, that this needs + * pointers with a width of at least 32 bits. + */ - start_point = gloader->base.outline.n_points; - start_contour = gloader->base.outline.n_contours; + + /* clear the nodes filled by sibling chains */ + node = ft_list_get_node_at( &loader->composites, recurse_count ); + for ( node2 = node; node2; node2 = node2->next ) + node2->data = (void*)ULONG_MAX; + + /* check whether we already have a composite glyph with this index */ + if ( FT_List_Find( &loader->composites, + (void*)(unsigned long)glyph_index ) ) + { + FT_TRACE1(( "TT_Load_Composite_Glyph:" + " infinite recursion detected\n" )); + error = FT_THROW( Invalid_Composite ); + goto Exit; + } + + else if ( node ) + node->data = (void*)(unsigned long)glyph_index; + + else + { + if ( FT_NEW( node ) ) + goto Exit; + node->data = (void*)(unsigned long)glyph_index; + FT_List_Add( &loader->composites, node ); + } + + start_point = (FT_UInt)gloader->base.outline.n_points; + start_contour = (FT_UInt)gloader->base.outline.n_contours; /* for each subglyph, read composite header */ error = face->read_composite_glyph( loader ); @@ -1521,51 +1730,123 @@ if ( face->doblend ) { - FT_Int i, limit; + short i, limit; FT_SubGlyph subglyph; - FT_Memory memory = face->root.memory; + FT_Outline outline; + FT_Vector* points = NULL; + char* tags = NULL; + short* contours = NULL; + + + limit = (short)gloader->current.num_subglyphs; + + /* construct an outline structure for */ + /* communication with `TT_Vary_Apply_Glyph_Deltas' */ + outline.n_points = (short)( gloader->current.num_subglyphs + 4 ); + outline.n_contours = outline.n_points; - /* this provides additional offsets */ - /* for each component's translation */ + outline.points = NULL; + outline.tags = NULL; + outline.contours = NULL; - if ( ( error = TT_Vary_Get_Glyph_Deltas( + if ( FT_NEW_ARRAY( points, outline.n_points ) || + FT_NEW_ARRAY( tags, outline.n_points ) || + FT_NEW_ARRAY( contours, outline.n_points ) ) + goto Exit1; + + subglyph = gloader->current.subglyphs; + + for ( i = 0; i < limit; i++, subglyph++ ) + { + /* applying deltas for anchor points doesn't make sense, */ + /* but we don't have to specially check this since */ + /* unused delta values are zero anyways */ + points[i].x = subglyph->arg1; + points[i].y = subglyph->arg2; + tags[i] = 1; + contours[i] = i; + } + + points[i].x = loader->pp1.x; + points[i].y = loader->pp1.y; + tags[i] = 1; + contours[i] = i; + + i++; + points[i].x = loader->pp2.x; + points[i].y = loader->pp2.y; + tags[i] = 1; + contours[i] = i; + + i++; + points[i].x = loader->pp3.x; + points[i].y = loader->pp3.y; + tags[i] = 1; + contours[i] = i; + + i++; + points[i].x = loader->pp4.x; + points[i].y = loader->pp4.y; + tags[i] = 1; + contours[i] = i; + + outline.points = points; + outline.tags = tags; + outline.contours = contours; + + /* this call provides additional offsets */ + /* for each component's translation */ + if ( ( error = TT_Vary_Apply_Glyph_Deltas( face, glyph_index, - &deltas, - gloader->current.num_subglyphs + 4 )) != 0 ) - goto Exit; + &outline, + (FT_UInt)outline.n_points ) ) != 0 ) + goto Exit1; - subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; - limit = gloader->current.num_subglyphs; + subglyph = gloader->current.subglyphs; - for ( i = 0; i < limit; ++i, ++subglyph ) + for ( i = 0; i < limit; i++, subglyph++ ) { - if ( subglyph->flags & ARGS_ARE_XY_VALUES ) - { - /* XXX: overflow check for subglyph->{arg1,arg2}. */ - /* deltas[i].{x,y} must be within signed 16-bit, */ - /* but the restriction of summed delta is not clear */ - subglyph->arg1 += (FT_Int16)deltas[i].x; - subglyph->arg2 += (FT_Int16)deltas[i].y; - } + /* XXX: overflow check for subglyph->{arg1,arg2}. */ + /* Deltas must be within signed 16-bit, */ + /* but the restriction of summed deltas is not clear */ + subglyph->arg1 = (FT_Int16)points[i].x; + subglyph->arg2 = (FT_Int16)points[i].y; } - loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y; - loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y; - loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y; - loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y; + loader->pp1.x = points[i + 0].x; + loader->pp1.y = points[i + 0].y; + loader->pp2.x = points[i + 1].x; + loader->pp2.y = points[i + 1].y; + + loader->pp3.x = points[i + 2].x; + loader->pp3.y = points[i + 2].y; + loader->pp4.x = points[i + 3].x; + loader->pp4.y = points[i + 3].y; - FT_FREE( deltas ); + Exit1: + FT_FREE( outline.points ); + FT_FREE( outline.tags ); + FT_FREE( outline.contours ); + + if ( error ) + goto Exit; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + /* scale phantom points, if necessary; */ + /* they get rounded in `TT_Hint_Glyph' */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + /* pp1.y and pp2.y are always zero */ + + loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale ); loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale ); loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); } @@ -1586,7 +1867,7 @@ { FT_UInt n, num_base_points; - FT_SubGlyph subglyph = 0; + FT_SubGlyph subglyph = NULL; FT_UInt num_points = start_point; FT_UInt num_subglyphs = gloader->current.num_subglyphs; @@ -1615,16 +1896,19 @@ pp[2] = loader->pp3; pp[3] = loader->pp4; - num_base_points = gloader->base.outline.n_points; + num_base_points = (FT_UInt)gloader->base.outline.n_points; - error = load_truetype_glyph( loader, subglyph->index, - recurse_count + 1, FALSE ); + error = load_truetype_glyph( loader, + (FT_UInt)subglyph->index, + recurse_count + 1, + FALSE ); if ( error ) goto Exit; /* restore subglyph pointer */ subglyph = gloader->base.subglyphs + num_base_subgs + n; + /* restore phantom points if necessary */ if ( !( subglyph->flags & USE_MY_METRICS ) ) { loader->pp1 = pp[0]; @@ -1633,7 +1917,7 @@ loader->pp4 = pp[3]; } - num_points = gloader->base.outline.n_points; + num_points = (FT_UInt)gloader->base.outline.n_points; if ( num_points == num_base_points ) continue; @@ -1644,8 +1928,12 @@ /* (1): exists from the beginning */ /* (2): components that have been loaded so far */ /* (3): the newly loaded component */ - TT_Process_Composite_Component( loader, subglyph, start_point, - num_base_points ); + error = TT_Process_Composite_Component( loader, + subglyph, + start_point, + num_base_points ); + if ( error ) + goto Exit; } loader->stream = old_stream; @@ -1654,16 +1942,17 @@ /* process the glyph */ loader->ins_pos = ins_pos; if ( IS_HINTED( loader->load_flags ) && - #ifdef TT_USE_BYTECODE_INTERPRETER - subglyph->flags & WE_HAVE_INSTR && - #endif - num_points > start_point ) - TT_Process_Composite_Glyph( loader, start_point, start_contour ); - + { + error = TT_Process_Composite_Glyph( loader, + start_point, + start_contour ); + if ( error ) + goto Exit; + } } } else @@ -1699,15 +1988,16 @@ compute_glyph_metrics( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Face face = loader->face; +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif FT_BBox bbox; FT_Fixed y_scale; TT_GlyphSlot glyph = loader->glyph; - TT_Size size = (TT_Size)loader->size; + TT_Size size = loader->size; y_scale = 0x10000L; @@ -1727,9 +2017,18 @@ glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - /* adjust advance width to the value contained in the hdmx table */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) ) + /* Adjust advance width to the value contained in the hdmx table */ + /* unless FT_LOAD_COMPUTE_METRICS is set or backwards compatibility */ + /* mode of the v40 interpreter is active. See `ttinterp.h' for */ + /* details on backwards compatibility mode. */ + if ( +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + ( loader->exec && loader->exec->backwards_compatibility ) ) && +#endif + !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) && + !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) ) { FT_Byte* widthp; @@ -1738,7 +2037,7 @@ size->root.metrics.x_ppem, glyph_index ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -1752,15 +2051,15 @@ ( ( ignore_x_mode && loader->exec->compatible_widths ) || !ignore_x_mode || SPH_OPTION_BITMAP_WIDTHS ) ) - glyph->metrics.horiAdvance = *widthp << 6; + glyph->metrics.horiAdvance = *widthp * 64; } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { if ( widthp ) - glyph->metrics.horiAdvance = *widthp << 6; + glyph->metrics.horiAdvance = *widthp * 64; } } @@ -1891,7 +2190,7 @@ error = sfnt->load_sbit_image( face, size->strike_index, glyph_index, - (FT_Int)load_flags, + (FT_UInt)load_flags, stream, &glyph->bitmap, &metrics ); @@ -1900,16 +2199,16 @@ glyph->outline.n_points = 0; glyph->outline.n_contours = 0; - glyph->metrics.width = (FT_Pos)metrics.width << 6; - glyph->metrics.height = (FT_Pos)metrics.height << 6; + glyph->metrics.width = (FT_Pos)metrics.width * 64; + glyph->metrics.height = (FT_Pos)metrics.height * 64; - glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; - glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; - glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX * 64; + glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY * 64; + glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance * 64; - glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; - glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; - glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX * 64; + glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY * 64; + glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance * 64; glyph->format = FT_GLYPH_FORMAT_BITMAP; @@ -1938,11 +2237,17 @@ FT_Int32 load_flags, FT_Bool glyf_table_only ) { + FT_Error error; + TT_Face face; FT_Stream stream; #ifdef TT_USE_BYTECODE_INTERPRETER FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); #endif +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face ); +#endif face = (TT_Face)glyph->face; @@ -1956,72 +2261,97 @@ if ( IS_HINTED( load_flags ) && !glyf_table_only ) { TT_ExecContext exec; - FT_Bool grayscale; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); + FT_Bool grayscale = TRUE; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + FT_Bool subpixel_hinting_lean; + FT_Bool grayscale_cleartype; +#endif - FT_Bool subpixel_hinting = FALSE; - FT_Bool grayscale_hinting = TRUE; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + FT_Bool subpixel_hinting = FALSE; #if 0 /* not used yet */ FT_Bool compatible_widths; FT_Bool symmetrical_smoothing; FT_Bool bgr; + FT_Bool vertical_lcd; FT_Bool subpixel_positioned; + FT_Bool gray_cleartype; #endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ FT_Bool reexecute = FALSE; - if ( !size->cvt_ready ) + if ( size->bytecode_ready < 0 || size->cvt_ready < 0 ) { - FT_Error error = tt_size_ready_bytecode( size, pedantic ); - - + error = tt_size_ready_bytecode( size, pedantic ); if ( error ) return error; } + else if ( size->bytecode_ready ) + return size->bytecode_ready; + else if ( size->cvt_ready ) + return size->cvt_ready; /* query new execution context */ - exec = size->debug ? size->context - : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; + exec = size->context; if ( !exec ) return FT_THROW( Could_Not_Find_Context ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + subpixel_hinting_lean = TRUE; + grayscale_cleartype = !FT_BOOL( load_flags & + FT_LOAD_TARGET_LCD || + load_flags & + FT_LOAD_TARGET_LCD_V ); + exec->vertical_lcd_lean = FT_BOOL( load_flags & + FT_LOAD_TARGET_LCD_V ); + } + else + { + subpixel_hinting_lean = FALSE; + grayscale_cleartype = FALSE; + exec->vertical_lcd_lean = FALSE; + } +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { - subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) - != FT_RENDER_MODE_MONO ) && - SPH_OPTION_SET_SUBPIXEL ); + subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ) && + SPH_OPTION_SET_SUBPIXEL ); if ( subpixel_hinting ) - grayscale = grayscale_hinting = FALSE; + grayscale = FALSE; else if ( SPH_OPTION_SET_GRAYSCALE ) { - grayscale = grayscale_hinting = TRUE; - subpixel_hinting = FALSE; + grayscale = TRUE; + subpixel_hinting = FALSE; } else - grayscale = grayscale_hinting = FALSE; + grayscale = FALSE; if ( FT_IS_TRICKY( glyph->face ) ) - subpixel_hinting = grayscale_hinting = FALSE; + subpixel_hinting = FALSE; - exec->ignore_x_mode = subpixel_hinting || grayscale_hinting; + exec->ignore_x_mode = subpixel_hinting || grayscale; exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) exec->rasterizer_version = TT_INTERPRETER_VERSION_35; #if 1 exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; - exec->symmetrical_smoothing = FALSE; + exec->symmetrical_smoothing = TRUE; exec->bgr = FALSE; + exec->vertical_lcd = FALSE; exec->subpixel_positioned = TRUE; + exec->gray_cleartype = FALSE; #else /* 0 */ exec->compatible_widths = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != @@ -2032,24 +2362,37 @@ exec->bgr = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != TT_LOAD_BGR ); + exec->vertical_lcd = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + TT_LOAD_VERTICAL_LCD ); exec->subpixel_positioned = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != TT_LOAD_SUBPIXEL_POSITIONED ); + exec->gray_cleartype = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + TT_LOAD_GRAY_CLEARTYPE ); #endif /* 0 */ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + grayscale = FT_BOOL( !subpixel_hinting_lean && + FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ); + else +#endif grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - FT_RENDER_MODE_MONO ); - } + FT_RENDER_MODE_MONO ); - TT_Load_Context( exec, face, size ); + error = TT_Load_Context( exec, face, size ); + if ( error ) + return error; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -2066,25 +2409,53 @@ /* a change from mono to grayscale rendering (and vice versa) */ /* requires a re-execution of the CVT program */ - if ( grayscale != exec->grayscale_hinting ) + if ( grayscale != exec->grayscale ) { FT_TRACE4(( "tt_loader_init: grayscale hinting change," " re-executing `prep' table\n" )); - exec->grayscale_hinting = grayscale_hinting; - reexecute = TRUE; + exec->grayscale = grayscale; + reexecute = TRUE; } } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + /* a change from mono to subpixel rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( subpixel_hinting_lean != exec->subpixel_hinting_lean ) + { + FT_TRACE4(( "tt_loader_init: subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->subpixel_hinting_lean = subpixel_hinting_lean; + reexecute = TRUE; + } + + /* a change from colored to grayscale subpixel rendering (and */ + /* vice versa) requires a re-execution of the CVT program */ + if ( grayscale_cleartype != exec->grayscale_cleartype ) + { + FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->grayscale_cleartype = grayscale_cleartype; + reexecute = TRUE; + } + } +#endif + /* a change from mono to grayscale rendering (and vice versa) */ /* requires a re-execution of the CVT program */ if ( grayscale != exec->grayscale ) { - FT_TRACE4(( "tt_loader_init: grayscale change," + FT_TRACE4(( "tt_loader_init: grayscale hinting change," " re-executing `prep' table\n" )); exec->grayscale = grayscale; @@ -2099,10 +2470,12 @@ for ( i = 0; i < size->cvt_size; i++ ) size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - tt_size_run_prep( size, pedantic ); + error = tt_size_run_prep( size, pedantic ); + if ( error ) + return error; } - /* see whether the cvt program has disabled hinting */ + /* check whether the cvt program has disabled hinting */ if ( exec->GS.instruct_control & 1 ) load_flags |= FT_LOAD_NO_HINTING; @@ -2110,6 +2483,14 @@ if ( exec->GS.instruct_control & 2 ) exec->GS = tt_default_graphics_state; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* check whether we have a font hinted for ClearType -- */ + /* note that this flag can also be modified in a glyph's bytecode */ + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && + exec->GS.instruct_control & 4 ) + exec->ignore_x_mode = 0; +#endif + exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); loader->exec = exec; loader->instructions = exec->glyphIns; @@ -2130,8 +2511,7 @@ #endif { - FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); - + error = face->goto_table( face, TTAG_glyf, stream, 0 ); if ( FT_ERR_EQ( error, Table_Missing ) ) loader->glyf_offset = 0; @@ -2154,17 +2534,30 @@ loader->gloader = gloader; } - loader->load_flags = load_flags; + loader->load_flags = (FT_ULong)load_flags; - loader->face = (FT_Face)face; - loader->size = (FT_Size)size; + loader->face = face; + loader->size = size; loader->glyph = (FT_GlyphSlot)glyph; loader->stream = stream; + loader->composites.head = NULL; + loader->composites.tail = NULL; + return FT_Err_Ok; } + static void + tt_loader_done( TT_Loader loader ) + { + FT_List_Finalize( &loader->composites, + NULL, + loader->face->root.memory, + NULL ); + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -2202,7 +2595,7 @@ TT_LoaderRec loader; - error = FT_Err_Ok; + FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index )); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS @@ -2221,16 +2614,20 @@ /* for the bbox we need the header only */ (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + tt_loader_done( &loader ); glyph->linearHoriAdvance = loader.linear; - glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - - loader.vadvance; + glyph->linearVertAdvance = loader.vadvance; - /* sanity check: if `horiAdvance' in the sbit metric */ - /* structure isn't set, use `linearHoriAdvance' */ + /* sanity checks: if `xxxAdvance' in the sbit metric */ + /* structure isn't set, use `linearXXXAdvance' */ if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance ) glyph->metrics.horiAdvance = FT_MulFix( glyph->linearHoriAdvance, size->root.metrics.x_scale ); + if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance ) + glyph->metrics.vertAdvance = + FT_MulFix( glyph->linearVertAdvance, + size->root.metrics.y_scale ); } return FT_Err_Ok; @@ -2310,9 +2707,11 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ - compute_glyph_metrics( &loader, glyph_index ); + error = compute_glyph_metrics( &loader, glyph_index ); } + tt_loader_done( &loader ); + /* Set the `high precision' bit flag. */ /* This is _critical_ to get correct output for monochrome */ /* TrueType glyphs at all sizes using the bytecode interpreter. */ diff --git a/drivers/freetype/src/truetype/ttgload.h b/drivers/freetype/src/truetype/ttgload.h index 05f75882dc..bfa29e4ff8 100644 --- a/drivers/freetype/src/truetype/ttgload.h +++ b/drivers/freetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2006, 2008, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTGLOAD_H__ -#define __TTGLOAD_H__ +#ifndef TTGLOAD_H_ +#define TTGLOAD_H_ #include <ft2build.h> @@ -43,6 +43,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) TT_Get_VMetrics( TT_Face face, FT_UInt idx, + FT_Pos yMax, FT_Short* tsb, FT_UShort* ah ); @@ -55,7 +56,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTGLOAD_H__ */ +#endif /* TTGLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/truetype/ttgxvar.c b/drivers/freetype/src/truetype/ttgxvar.c index 7899d3671d..9a02c5a8c1 100644 --- a/drivers/freetype/src/truetype/ttgxvar.c +++ b/drivers/freetype/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader */ /* */ -/* Copyright 2004-2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ /* */ /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ /* */ - /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */ /* */ /* The documentation for `fvar' is inconsistent. At one point it says */ /* that `countSizePairs' should be 3, at another point 2. It should */ @@ -60,9 +60,9 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#define FT_Stream_FTell( stream ) \ +#define FT_Stream_FTell( stream ) \ (FT_ULong)( (stream)->cursor - (stream)->base ) -#define FT_Stream_SeekSet( stream, off ) \ +#define FT_Stream_SeekSet( stream, off ) \ ( (stream)->cursor = (stream)->base + (off) ) @@ -96,8 +96,8 @@ #define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0 -#define GX_PT_POINTS_ARE_WORDS 0x80 -#define GX_PT_POINT_RUN_COUNT_MASK 0x7F +#define GX_PT_POINTS_ARE_WORDS 0x80U +#define GX_PT_POINT_RUN_COUNT_MASK 0x7FU /*************************************************************************/ @@ -112,6 +112,8 @@ /* <Input> */ /* stream :: The data stream. */ /* */ + /* size :: The size of the table holding the data. */ + /* */ /* <Output> */ /* point_cnt :: The number of points read. A zero value means that */ /* all points in the glyph will be affected, without */ @@ -123,55 +125,77 @@ /* */ static FT_UShort* ft_var_readpackedpoints( FT_Stream stream, + FT_ULong size, FT_UInt *point_cnt ) { FT_UShort *points = NULL; - FT_Int n; - FT_Int runcnt; - FT_Int i; - FT_Int j; - FT_Int first; + FT_UInt n; + FT_UInt runcnt; + FT_UInt i, j; + FT_UShort first; FT_Memory memory = stream->memory; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); - *point_cnt = n = FT_GET_BYTE(); + *point_cnt = 0; + + n = FT_GET_BYTE(); if ( n == 0 ) return ALL_POINTS; if ( n & GX_PT_POINTS_ARE_WORDS ) - n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 ); + { + n &= GX_PT_POINT_RUN_COUNT_MASK; + n <<= 8; + n |= FT_GET_BYTE(); + } + + if ( n > size ) + { + FT_TRACE1(( "ft_var_readpackedpoints: number of points too large\n" )); + return NULL; + } if ( FT_NEW_ARRAY( points, n ) ) return NULL; + *point_cnt = n; + i = 0; while ( i < n ) { runcnt = FT_GET_BYTE(); if ( runcnt & GX_PT_POINTS_ARE_WORDS ) { - runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; - first = points[i++] = FT_GET_USHORT(); + runcnt &= GX_PT_POINT_RUN_COUNT_MASK; + first = FT_GET_USHORT(); + points[i++] = first; - if ( runcnt < 1 || i + runcnt >= n ) + if ( runcnt < 1 || i + runcnt > n ) goto Exit; - /* first point not included in runcount */ - for ( j = 0; j < runcnt; ++j ) - points[i++] = (FT_UShort)( first += FT_GET_USHORT() ); + /* first point not included in run count */ + for ( j = 0; j < runcnt; j++ ) + { + first += FT_GET_USHORT(); + points[i++] = first; + } } else { - first = points[i++] = FT_GET_BYTE(); + first = FT_GET_BYTE(); + points[i++] = first; - if ( runcnt < 1 || i + runcnt >= n ) + if ( runcnt < 1 || i + runcnt > n ) goto Exit; - for ( j = 0; j < runcnt; ++j ) - points[i++] = (FT_UShort)( first += FT_GET_BYTE() ); + for ( j = 0; j < runcnt; j++ ) + { + first += FT_GET_BYTE(); + points[i++] = first; + } } } @@ -180,12 +204,9 @@ } - enum - { - GX_DT_DELTAS_ARE_ZERO = 0x80, - GX_DT_DELTAS_ARE_WORDS = 0x40, - GX_DT_DELTA_RUN_COUNT_MASK = 0x3F - }; +#define GX_DT_DELTAS_ARE_ZERO 0x80U +#define GX_DT_DELTAS_ARE_WORDS 0x40U +#define GX_DT_DELTA_RUN_COUNT_MASK 0x3FU /*************************************************************************/ @@ -200,7 +221,9 @@ /* <Input> */ /* stream :: The data stream. */ /* */ - /* delta_cnt :: The number of to be read. */ + /* size :: The size of the table holding the data. */ + /* */ + /* delta_cnt :: The number of deltas to be read. */ /* */ /* <Return> */ /* An array of FT_Short containing the deltas for the affected */ @@ -210,18 +233,24 @@ /* */ static FT_Short* ft_var_readpackeddeltas( FT_Stream stream, - FT_Offset delta_cnt ) + FT_ULong size, + FT_UInt delta_cnt ) { FT_Short *deltas = NULL; - FT_UInt runcnt; - FT_Offset i; - FT_UInt j; + FT_UInt runcnt, cnt; + FT_UInt i, j; FT_Memory memory = stream->memory; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); + if ( delta_cnt > size ) + { + FT_TRACE1(( "ft_var_readpackeddeltas: number of points too large\n" )); + return NULL; + } + if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) return NULL; @@ -229,34 +258,30 @@ while ( i < delta_cnt ) { runcnt = FT_GET_BYTE(); + cnt = runcnt & GX_DT_DELTA_RUN_COUNT_MASK; + if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) { - /* runcnt zeroes get added */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) + /* `runcnt' zeroes get added */ + for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = 0; } else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) { - /* runcnt shorts from the stack */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) + /* `runcnt' shorts from the stack */ + for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = FT_GET_SHORT(); } else { - /* runcnt signed bytes from the stack */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) + /* `runcnt' signed bytes from the stack */ + for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = FT_GET_CHAR(); } - if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) ) + if ( j <= cnt ) { - /* Bad format */ + /* bad format */ FT_FREE( deltas ); return NULL; } @@ -281,12 +306,12 @@ static void ft_var_load_avar( TT_Face face ) { - FT_Stream stream = FT_FACE_STREAM(face); + FT_Stream stream = FT_FACE_STREAM( face ); FT_Memory memory = stream->memory; GX_Blend blend = face->blend; GX_AVarSegment segment; FT_Error error = FT_Err_Ok; - FT_ULong version; + FT_Long version; FT_Long axisCount; FT_Int i, j; FT_ULong table_len; @@ -294,9 +319,15 @@ FT_UNUSED( error ); + FT_TRACE2(( "AVAR " )); + blend->avar_checked = TRUE; - if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0 ) + error = face->goto_table( face, TTAG_avar, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing\n" )); return; + } if ( FT_FRAME_ENTER( table_len ) ) return; @@ -304,23 +335,37 @@ version = FT_GET_LONG(); axisCount = FT_GET_LONG(); - if ( version != 0x00010000L || - axisCount != (FT_Long)blend->mmvar->num_axis ) + if ( version != 0x00010000L ) + { + FT_TRACE2(( "bad table version\n" )); goto Exit; + } + + FT_TRACE2(( "loaded\n" )); + + if ( axisCount != (FT_Long)blend->mmvar->num_axis ) + { + FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `cvar'\n" + " table are different\n" )); + goto Exit; + } if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) ) goto Exit; segment = &blend->avar_segment[0]; - for ( i = 0; i < axisCount; ++i, ++segment ) + for ( i = 0; i < axisCount; i++, segment++ ) { + FT_TRACE5(( " axis %d:\n", i )); + segment->pairCount = FT_GET_USHORT(); - if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) + if ( (FT_ULong)segment->pairCount * 4 > table_len || + FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) { /* Failure. Free everything we have done so far. We must do */ /* it right now since loading the `avar' table is optional. */ - for ( j = i - 1; j >= 0; --j ) + for ( j = i - 1; j >= 0; j-- ) FT_FREE( blend->avar_segment[j].correspondence ); FT_FREE( blend->avar_segment ); @@ -328,13 +373,18 @@ goto Exit; } - for ( j = 0; j < segment->pairCount; ++j ) + for ( j = 0; j < segment->pairCount; j++ ) { - segment->correspondence[j].fromCoord = - FT_GET_SHORT() << 2; /* convert to Fixed */ - segment->correspondence[j].toCoord = - FT_GET_SHORT()<<2; /* convert to Fixed */ + /* convert to Fixed */ + segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4; + segment->correspondence[j].toCoord = FT_GET_SHORT() * 4; + + FT_TRACE5(( " mapping %.4f to %.4f\n", + segment->correspondence[j].fromCoord / 65536.0, + segment->correspondence[j].toCoord / 65536.0 )); } + + FT_TRACE5(( "\n" )); } Exit: @@ -361,8 +411,8 @@ /* ft_var_load_gvar */ /* */ /* <Description> */ - /* Parses the `gvar' table if present. If `fvar' is there, `gvar' */ - /* had better be there too. */ + /* Parse the `gvar' table if present. If `fvar' is there, `gvar' had */ + /* better be there too. */ /* */ /* <InOut> */ /* face :: The font face. */ @@ -373,7 +423,7 @@ static FT_Error ft_var_load_gvar( TT_Face face ) { - FT_Stream stream = FT_FACE_STREAM(face); + FT_Stream stream = FT_FACE_STREAM( face ); FT_Memory memory = stream->memory; GX_Blend blend = face->blend; FT_Error error; @@ -400,24 +450,67 @@ FT_FRAME_END }; - if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 ) + + FT_TRACE2(( "GVAR " )); + + if ( ( error = face->goto_table( face, + TTAG_gvar, + stream, + &table_len ) ) != 0 ) + { + FT_TRACE2(( "is missing\n" )); goto Exit; + } gvar_start = FT_STREAM_POS( ); if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) goto Exit; - blend->tuplecount = gvar_head.globalCoordCount; - blend->gv_glyphcnt = gvar_head.glyphCount; - offsetToData = gvar_start + gvar_head.offsetToData; + if ( gvar_head.version != 0x00010000L ) + { + FT_TRACE1(( "bad table version\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) + { + FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n" + " table are different\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* rough sanity check, ignoring offsets */ + if ( (FT_ULong)gvar_head.globalCoordCount * gvar_head.axisCount > + table_len / 2 ) + { + FT_TRACE1(( "ft_var_load_gvar:" + " invalid number of global coordinates\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } - if ( gvar_head.version != (FT_Long)0x00010000L || - gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) + /* rough sanity check: offsets can be either 2 or 4 bytes, */ + /* and a single variation needs at least 4 bytes per glyph */ + if ( (FT_ULong)gvar_head.glyphCount * + ( ( gvar_head.flags & 1 ) ? 8 : 6 ) > table_len ) { + FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } + FT_TRACE2(( "loaded\n" )); + + blend->gvar_size = table_len; + blend->tuplecount = gvar_head.globalCoordCount; + blend->gv_glyphcnt = gvar_head.glyphCount; + offsetToData = gvar_start + gvar_head.offsetToData; + + FT_TRACE5(( "gvar: there are %d shared coordinates:\n", + blend->tuplecount )); + if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) goto Exit; @@ -427,8 +520,8 @@ if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) goto Exit; - for ( i = 0; i <= blend->gv_glyphcnt; ++i ) - blend->glyphoffsets[i] = offsetToData + FT_GET_LONG(); + for ( i = 0; i <= blend->gv_glyphcnt; i++ ) + blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG(); FT_FRAME_EXIT(); } @@ -438,9 +531,9 @@ if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) goto Exit; - for ( i = 0; i <= blend->gv_glyphcnt; ++i ) + for ( i = 0; i <= blend->gv_glyphcnt; i++ ) blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; - /* XXX: Undocumented: `*2'! */ + /* XXX: Undocumented: `*2'! */ FT_FRAME_EXIT(); } @@ -451,14 +544,24 @@ gvar_head.axisCount * blend->tuplecount ) ) goto Exit; - if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || - FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) + if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || + FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) goto Exit; - for ( i = 0; i < blend->tuplecount; ++i ) - for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j ) + for ( i = 0; i < blend->tuplecount; i++ ) + { + FT_TRACE5(( " [ " )); + for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ ) + { blend->tuplecoords[i * gvar_head.axisCount + j] = - FT_GET_SHORT() << 2; /* convert to FT_Fixed */ + FT_GET_SHORT() * 4; /* convert to FT_Fixed */ + FT_TRACE5(( "%.4f ", + blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); + } + FT_TRACE5(( "]\n" )); + } + + FT_TRACE5(( "\n" )); FT_FRAME_EXIT(); } @@ -506,48 +609,100 @@ FT_Fixed apply = 0x10000L; - for ( i = 0; i < blend->num_axis; ++i ) + for ( i = 0; i < blend->num_axis; i++ ) { + FT_TRACE6(( " axis coordinate %d (%.4f):\n", + i, blend->normalizedcoords[i] / 65536.0 )); + if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) + FT_TRACE6(( " intermediate coordinates %d (%.4f, %.4f):\n", + i, + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + + /* It's not clear why (for intermediate tuples) we don't need */ + /* to check against start/end -- the documentation says we don't. */ + /* Similarly, it's unclear why we don't need to scale along the */ + /* axis. */ + if ( tuple_coords[i] == 0 ) - /* It's not clear why (for intermediate tuples) we don't need */ - /* to check against start/end -- the documentation says we don't. */ - /* Similarly, it's unclear why we don't need to scale along the */ - /* axis. */ + { + FT_TRACE6(( " tuple coordinate is zero, ignored\n", i )); continue; + } - else if ( blend->normalizedcoords[i] == 0 || - ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || - ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) + if ( blend->normalizedcoords[i] == 0 ) { + FT_TRACE6(( " axis coordinate is zero, stop\n" )); apply = 0; break; } - else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) - /* not an intermediate tuple */ - apply = FT_MulFix( apply, - blend->normalizedcoords[i] > 0 - ? blend->normalizedcoords[i] - : -blend->normalizedcoords[i] ); - - else if ( blend->normalizedcoords[i] <= im_start_coords[i] || - blend->normalizedcoords[i] >= im_end_coords[i] ) + if ( blend->normalizedcoords[i] == tuple_coords[i] ) { - apply = 0; - break; + FT_TRACE6(( " tuple coordinate value %.4f fits perfectly\n", + tuple_coords[i] / 65536.0 )); + /* `apply' does not change */ + continue; } - else if ( blend->normalizedcoords[i] < tuple_coords[i] ) - apply = FT_MulDiv( apply, - blend->normalizedcoords[i] - im_start_coords[i], - tuple_coords[i] - im_start_coords[i] ); + if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) + { + /* not an intermediate tuple */ - else + if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) || + blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) + { + FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n", + tuple_coords[i] / 65536.0 )); + apply = 0; + break; + } + + FT_TRACE6(( " tuple coordinate value %.4f fits\n", + tuple_coords[i] / 65536.0 )); apply = FT_MulDiv( apply, - im_end_coords[i] - blend->normalizedcoords[i], - im_end_coords[i] - tuple_coords[i] ); + blend->normalizedcoords[i], + tuple_coords[i] ); + } + else + { + /* intermediate tuple */ + + if ( blend->normalizedcoords[i] < im_start_coords[i] || + blend->normalizedcoords[i] > im_end_coords[i] ) + { + FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] is exceeded," + " stop\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = 0; + break; + } + + else if ( blend->normalizedcoords[i] < tuple_coords[i] ) + { + FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = FT_MulDiv( apply, + blend->normalizedcoords[i] - im_start_coords[i], + tuple_coords[i] - im_start_coords[i] ); + } + + else + { + FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = FT_MulDiv( apply, + im_end_coords[i] - blend->normalizedcoords[i], + im_end_coords[i] - tuple_coords[i] ); + } + } } + FT_TRACE6(( " apply factor is %.4f\n", apply / 65536.0 )); + return apply; } @@ -577,9 +732,9 @@ typedef struct fvar_axis_ { FT_ULong axisTag; - FT_ULong minValue; - FT_ULong defaultValue; - FT_ULong maxValue; + FT_Fixed minValue; + FT_Fixed defaultValue; + FT_Fixed maxValue; FT_UShort flags; FT_UShort nameID; @@ -600,7 +755,8 @@ /* TT_Get_MM_Var initializes the blend structure. */ /* */ /* <Output> */ - /* master :: The `fvar' data (must be freed by caller). */ + /* master :: The `fvar' data (must be freed by caller). Can be NULL, */ + /* which makes this function simply load MM support. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -647,25 +803,37 @@ FT_FRAME_START( 20 ), FT_FRAME_ULONG ( axisTag ), - FT_FRAME_ULONG ( minValue ), - FT_FRAME_ULONG ( defaultValue ), - FT_FRAME_ULONG ( maxValue ), + FT_FRAME_LONG ( minValue ), + FT_FRAME_LONG ( defaultValue ), + FT_FRAME_LONG ( maxValue ), FT_FRAME_USHORT( flags ), FT_FRAME_USHORT( nameID ), FT_FRAME_END }; + /* read the font data and set up the internal representation */ + /* if not already done */ + if ( face->blend == NULL ) { + FT_TRACE2(( "FVAR " )); + /* both `fvar' and `gvar' must be present */ - if ( (error = face->goto_table( face, TTAG_gvar, - stream, &table_len )) != 0 ) + if ( ( error = face->goto_table( face, TTAG_gvar, + stream, &table_len ) ) != 0 ) + { + FT_TRACE1(( "\n" + "TT_Get_MM_Var: `gvar' table is missing\n" )); goto Exit; + } - if ( (error = face->goto_table( face, TTAG_fvar, - stream, &table_len )) != 0 ) + if ( ( error = face->goto_table( face, TTAG_fvar, + stream, &table_len ) ) != 0 ) + { + FT_TRACE1(( "is missing\n" )); goto Exit; + } fvar_start = FT_STREAM_POS( ); @@ -673,7 +841,12 @@ goto Exit; if ( fvar_head.version != (FT_Long)0x00010000L || +#if 0 + /* fonts like `JamRegular.ttf' have an incorrect value for */ + /* `countSizePairs'; since value 2 is hard-coded in `fvar' */ + /* version 1.0, we simply ignore it */ fvar_head.countSizePairs != 2 || +#endif fvar_head.axisSize != 20 || /* axisCount limit implied by 16-bit instanceSize */ fvar_head.axisCount > 0x3FFE || @@ -683,10 +856,16 @@ fvar_head.offsetToData + fvar_head.axisCount * 20U + fvar_head.instanceCount * fvar_head.instanceSize > table_len ) { + FT_TRACE1(( "\n" + "TT_Get_MM_Var: invalid `fvar' header\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } + FT_TRACE2(( "loaded\n" )); + + FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount )); + if ( FT_NEW( face->blend ) ) goto Exit; @@ -702,6 +881,9 @@ goto Exit; face->blend->mmvar = mmvar; + /* set up pointers and offsets into the `mmvar' array; */ + /* the data gets filled in later on */ + mmvar->num_axis = fvar_head.axisCount; mmvar->num_designs = @@ -711,30 +893,32 @@ mmvar->num_namedstyles = fvar_head.instanceCount; mmvar->axis = - (FT_Var_Axis*)&(mmvar[1]); + (FT_Var_Axis*)&( mmvar[1] ); mmvar->namedstyle = - (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]); + (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] ); next_coords = - (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]); - for ( i = 0; i < fvar_head.instanceCount; ++i ) + (FT_Fixed*)&( mmvar->namedstyle[fvar_head.instanceCount] ); + for ( i = 0; i < fvar_head.instanceCount; i++ ) { mmvar->namedstyle[i].coords = next_coords; next_coords += fvar_head.axisCount; } next_name = (FT_String*)next_coords; - for ( i = 0; i < fvar_head.axisCount; ++i ) + for ( i = 0; i < fvar_head.axisCount; i++ ) { mmvar->axis[i].name = next_name; next_name += 5; } + /* now fill in the data */ + if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) ) goto Exit; a = mmvar->axis; - for ( i = 0; i < fvar_head.axisCount; ++i ) + for ( i = 0; i < fvar_head.axisCount; i++ ) { GX_FVar_Axis axis_rec; @@ -742,22 +926,30 @@ if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) goto Exit; a->tag = axis_rec.axisTag; - a->minimum = axis_rec.minValue; /* A Fixed */ - a->def = axis_rec.defaultValue; /* A Fixed */ - a->maximum = axis_rec.maxValue; /* A Fixed */ + a->minimum = axis_rec.minValue; + a->def = axis_rec.defaultValue; + a->maximum = axis_rec.maxValue; a->strid = axis_rec.nameID; a->name[0] = (FT_String)( a->tag >> 24 ); a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF ); a->name[2] = (FT_String)( ( a->tag >> 8 ) & 0xFF ); a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); - a->name[4] = 0; + a->name[4] = '\0'; - ++a; + FT_TRACE5(( " \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n", + a->name, + a->minimum / 65536.0, + a->def / 65536.0, + a->maximum / 65536.0 )); + + a++; } + FT_TRACE5(( "\n" )); + ns = mmvar->namedstyle; - for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns ) + for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) { if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) goto Exit; @@ -765,13 +957,15 @@ ns->strid = FT_GET_USHORT(); (void) /* flags = */ FT_GET_USHORT(); - for ( j = 0; j < fvar_head.axisCount; ++j ) - ns->coords[j] = FT_GET_ULONG(); /* A Fixed */ + for ( j = 0; j < fvar_head.axisCount; j++ ) + ns->coords[j] = FT_GET_LONG(); FT_FRAME_EXIT(); } } + /* fill the output array if requested */ + if ( master != NULL ) { FT_UInt n; @@ -782,36 +976,36 @@ FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); mmvar->axis = - (FT_Var_Axis*)&(mmvar[1]); + (FT_Var_Axis*)&( mmvar[1] ); mmvar->namedstyle = - (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]); + (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); next_coords = - (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]); + (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); - for ( n = 0; n < mmvar->num_namedstyles; ++n ) + for ( n = 0; n < mmvar->num_namedstyles; n++ ) { mmvar->namedstyle[n].coords = next_coords; next_coords += mmvar->num_axis; } - a = mmvar->axis; + a = mmvar->axis; next_name = (FT_String*)next_coords; - for ( n = 0; n < mmvar->num_axis; ++n ) + for ( n = 0; n < mmvar->num_axis; n++ ) { a->name = next_name; /* standard PostScript names for some standard apple tags */ if ( a->tag == TTAG_wght ) - a->name = (char *)"Weight"; + a->name = (char*)"Weight"; else if ( a->tag == TTAG_wdth ) - a->name = (char *)"Width"; + a->name = (char*)"Width"; else if ( a->tag == TTAG_opsz ) - a->name = (char *)"OpticalSize"; + a->name = (char*)"OpticalSize"; else if ( a->tag == TTAG_slnt ) - a->name = (char *)"Slant"; + a->name = (char*)"Slant"; next_name += 5; - ++a; + a++; } *master = mmvar; @@ -837,9 +1031,12 @@ /* Initialize the blend structure with `gvar' data. */ /* */ /* <Input> */ - /* num_coords :: Must be the axis count of the font. */ + /* num_coords :: The number of available coordinates. If it is */ + /* larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use the default value (0) for the remaining axes. */ /* */ - /* coords :: An array of num_coords, each between [-1,1]. */ + /* coords :: An array of `num_coords', each between [-1,1]. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -868,33 +1065,44 @@ if ( face->blend == NULL ) { - if ( (error = TT_Get_MM_Var( face, NULL)) != 0 ) + if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) goto Exit; } blend = face->blend; mmvar = blend->mmvar; - if ( num_coords != mmvar->num_axis ) + if ( num_coords > mmvar->num_axis ) { - error = FT_THROW( Invalid_Argument ); - goto Exit; + FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n", + mmvar->num_axis, num_coords )); + num_coords = mmvar->num_axis; } - for ( i = 0; i < num_coords; ++i ) + FT_TRACE5(( "normalized design coordinates:\n" )); + + for ( i = 0; i < num_coords; i++ ) + { + FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) { + FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n" + " is out of range [-1;1]\n", + coords[i] / 65536.0 )); error = FT_THROW( Invalid_Argument ); goto Exit; } + } + + FT_TRACE5(( "\n" )); if ( blend->glyphoffsets == NULL ) - if ( (error = ft_var_load_gvar( face )) != 0 ) + if ( ( error = ft_var_load_gvar( face ) ) != 0 ) goto Exit; if ( blend->normalizedcoords == NULL ) { - if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) ) + if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) ) goto Exit; manageCvt = mcvt_modify; @@ -906,7 +1114,8 @@ else { manageCvt = mcvt_retain; - for ( i = 0; i < num_coords; ++i ) + + for ( i = 0; i < num_coords; i++ ) { if ( blend->normalizedcoords[i] != coords[i] ) { @@ -915,13 +1124,22 @@ } } + for ( ; i < mmvar->num_axis; i++ ) + { + if ( blend->normalizedcoords[i] != 0 ) + { + manageCvt = mcvt_load; + break; + } + } + /* If we don't change the blend coords then we don't need to do */ /* anything to the cvt table. It will be correct. Otherwise we */ /* no longer have the original cvt (it was modified when we set */ /* the blend last time), so we must reload and then modify it. */ } - blend->num_axis = num_coords; + blend->num_axis = mmvar->num_axis; FT_MEM_COPY( blend->normalizedcoords, coords, num_coords * sizeof ( FT_Fixed ) ); @@ -938,13 +1156,13 @@ FT_FREE( face->cvt ); face->cvt = NULL; - tt_face_load_cvt( face, face->root.stream ); + error = tt_face_load_cvt( face, face->root.stream ); break; case mcvt_modify: /* The original cvt table is in memory. All we need to do is */ /* apply the `cvar' table (if any). */ - tt_face_vary_cvt( face, face->root.stream ); + error = tt_face_vary_cvt( face, face->root.stream ); break; case mcvt_retain: @@ -973,7 +1191,10 @@ /* Initialize the blend struct with `gvar' data. */ /* */ /* <Input> */ - /* num_coords :: This must be the axis count of the font. */ + /* num_coords :: The number of available coordinates. If it is */ + /* larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use the default values for the remaining axes. */ /* */ /* coords :: A coordinate array with `num_coords' elements. */ /* */ @@ -997,17 +1218,19 @@ if ( face->blend == NULL ) { - if ( (error = TT_Get_MM_Var( face, NULL )) != 0 ) + if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) goto Exit; } blend = face->blend; mmvar = blend->mmvar; - if ( num_coords != mmvar->num_axis ) + if ( num_coords > mmvar->num_axis ) { - error = FT_THROW( Invalid_Argument ); - goto Exit; + FT_TRACE2(( "TT_Set_Var_Design:" + " only using first %d of %d coordinates\n", + mmvar->num_axis, num_coords )); + num_coords = mmvar->num_axis; } /* Axis normalization is a two stage process. First we normalize */ @@ -1017,32 +1240,52 @@ if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) goto Exit; + FT_TRACE5(( "design coordinates:\n" )); + a = mmvar->axis; - for ( i = 0; i < mmvar->num_axis; ++i, ++a ) + for ( i = 0; i < num_coords; i++, a++ ) { + FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); if ( coords[i] > a->maximum || coords[i] < a->minimum ) { + FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n" + " is out of range [%.4f;%.4f]\n", + coords[i] / 65536.0, + a->minimum / 65536.0, + a->maximum / 65536.0 )); error = FT_THROW( Invalid_Argument ); goto Exit; } if ( coords[i] < a->def ) - normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def ); + normalized[i] = -FT_DivFix( coords[i] - a->def, + a->minimum - a->def ); else if ( a->maximum == a->def ) normalized[i] = 0; else - normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def ); + normalized[i] = FT_DivFix( coords[i] - a->def, + a->maximum - a->def ); } + FT_TRACE5(( "\n" )); + + for ( ; i < mmvar->num_axis; i++ ) + normalized[i] = 0; + if ( !blend->avar_checked ) ft_var_load_avar( face ); if ( blend->avar_segment != NULL ) { + FT_TRACE5(( "normalized design coordinates" + " before applying `avar' data:\n" )); + av = blend->avar_segment; - for ( i = 0; i < mmvar->num_axis; ++i, ++av ) + for ( i = 0; i < mmvar->num_axis; i++, av++ ) { - for ( j = 1; j < (FT_UInt)av->pairCount; ++j ) + for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) + { + FT_TRACE5(( " %.4f\n", normalized[i] / 65536.0 )); if ( normalized[i] < av->correspondence[j].fromCoord ) { normalized[i] = @@ -1054,10 +1297,11 @@ av->correspondence[j - 1].toCoord; break; } + } } } - error = TT_Set_MM_Blend( face, num_coords, normalized ); + error = TT_Set_MM_Blend( face, mmvar->num_axis, normalized ); Exit: FT_FREE( normalized ); @@ -1120,16 +1364,16 @@ if ( blend == NULL ) { - FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); - + FT_TRACE2(( "\n" + "tt_face_vary_cvt: no blend specified\n" )); error = FT_Err_Ok; goto Exit; } if ( face->cvt == NULL ) { - FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); - + FT_TRACE2(( "\n" + "tt_face_vary_cvt: no `cvt ' table\n" )); error = FT_Err_Ok; goto Exit; } @@ -1158,25 +1402,43 @@ goto FExit; } + FT_TRACE2(( "loaded\n" )); + if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) goto FExit; tupleCount = FT_GET_USHORT(); - offsetToData = table_start + FT_GET_USHORT(); + offsetToData = FT_GET_USHORT(); + + /* rough sanity test */ + if ( offsetToData + tupleCount * 4 > table_len ) + { + FT_TRACE2(( "tt_face_vary_cvt:" + " invalid CVT variation array header\n" )); + + error = FT_THROW( Invalid_Table ); + goto FExit; + } - /* The documentation implies there are flags packed into the */ - /* tuplecount, but John Jenkins says that shared points don't apply */ - /* to `cvar', and no other flags are defined. */ + offsetToData += table_start; - for ( i = 0; i < ( tupleCount & 0xFFF ); ++i ) + /* The documentation implies there are flags packed into */ + /* `tupleCount', but John Jenkins says that shared points don't apply */ + /* to `cvar', and no other flags are defined. */ + + FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount & 0xFFF )); + + for ( i = 0; i < ( tupleCount & 0xFFF ); i++ ) { FT_UInt tupleDataSize; FT_UInt tupleIndex; FT_Fixed apply; + FT_TRACE6(( " tuple %d:\n", i )); + tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); @@ -1185,8 +1447,8 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { - for ( j = 0; j < blend->num_axis; ++j ) - tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + for ( j = 0; j < blend->num_axis; j++ ) + tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ /* short frac to fixed */ } else @@ -1194,7 +1456,7 @@ /* skip this tuple; it makes no sense */ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - for ( j = 0; j < 2 * blend->num_axis; ++j ) + for ( j = 0; j < 2 * blend->num_axis; j++ ) (void)FT_GET_SHORT(); offsetToData += tupleDataSize; @@ -1203,10 +1465,10 @@ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { - for ( j = 0; j < blend->num_axis; ++j ) - im_start_coords[j] = FT_GET_SHORT() << 2; - for ( j = 0; j < blend->num_axis; ++j ) - im_end_coords[j] = FT_GET_SHORT() << 2; + for ( j = 0; j < blend->num_axis; j++ ) + im_start_coords[j] = FT_GET_SHORT() * 4; + for ( j = 0; j < blend->num_axis; j++ ) + im_end_coords[j] = FT_GET_SHORT() * 4; } apply = ft_var_apply_tuple( blend, @@ -1228,30 +1490,82 @@ FT_Stream_SeekSet( stream, offsetToData ); - localpoints = ft_var_readpackedpoints( stream, &point_count ); + localpoints = ft_var_readpackedpoints( stream, + table_len, + &point_count ); deltas = ft_var_readpackeddeltas( stream, + table_len, point_count == 0 ? face->cvt_size : point_count ); if ( localpoints == NULL || deltas == NULL ) - /* failure, ignore it */; + ; /* failure, ignore it */ else if ( localpoints == ALL_POINTS ) { +#ifdef FT_DEBUG_LEVEL_TRACE + int count = 0; +#endif + + + FT_TRACE7(( " CVT deltas:\n" )); + /* this means that there are deltas for every entry in cvt */ - for ( j = 0; j < face->cvt_size; ++j ) - face->cvt[j] = (FT_Short)( face->cvt[j] + + for ( j = 0; j < face->cvt_size; j++ ) + { + FT_Long orig_cvt = face->cvt[j]; + + + face->cvt[j] = (FT_Short)( orig_cvt + FT_MulFix( deltas[j], apply ) ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( orig_cvt != face->cvt[j] ) + { + FT_TRACE7(( " %d: %d -> %d\n", + j, orig_cvt, face->cvt[j] )); + count++; + } +#endif + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE7(( " none\n" )); +#endif } else { - for ( j = 0; j < point_count; ++j ) +#ifdef FT_DEBUG_LEVEL_TRACE + int count = 0; +#endif + + + FT_TRACE7(( " CVT deltas:\n" )); + + for ( j = 0; j < point_count; j++ ) { - int pindex = localpoints[j]; + int pindex = localpoints[j]; + FT_Long orig_cvt = face->cvt[pindex]; + - face->cvt[pindex] = (FT_Short)( face->cvt[pindex] + + face->cvt[pindex] = (FT_Short)( orig_cvt + FT_MulFix( deltas[j], apply ) ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( orig_cvt != face->cvt[pindex] ) + { + FT_TRACE7(( " %d: %d -> %d\n", + pindex, orig_cvt, face->cvt[pindex] )); + count++; + } +#endif } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE7(( " none\n" )); +#endif } if ( localpoints != ALL_POINTS ) @@ -1263,6 +1577,8 @@ FT_Stream_SeekSet( stream, here ); } + FT_TRACE5(( "\n" )); + FExit: FT_FRAME_EXIT(); @@ -1275,13 +1591,230 @@ } + /* Shift the original coordinates of all points between indices `p1' */ + /* and `p2', using the same difference as given by index `ref'. */ + + /* modeled after `af_iup_shift' */ + + static void + tt_delta_shift( int p1, + int p2, + int ref, + FT_Vector* in_points, + FT_Vector* out_points ) + { + int p; + FT_Vector delta; + + + delta.x = out_points[ref].x - in_points[ref].x; + delta.y = out_points[ref].y - in_points[ref].y; + + if ( delta.x == 0 && delta.y == 0 ) + return; + + for ( p = p1; p < ref; p++ ) + { + out_points[p].x += delta.x; + out_points[p].y += delta.y; + } + + for ( p = ref + 1; p <= p2; p++ ) + { + out_points[p].x += delta.x; + out_points[p].y += delta.y; + } + } + + + /* Interpolate the original coordinates of all points with indices */ + /* between `p1' and `p2', using `ref1' and `ref2' as the reference */ + /* point indices. */ + + /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */ + /* `Ins_IUP' */ + + static void + tt_delta_interpolate( int p1, + int p2, + int ref1, + int ref2, + FT_Vector* in_points, + FT_Vector* out_points ) + { + int p, i; + + FT_Pos out, in1, in2, out1, out2, d1, d2; + + + if ( p1 > p2 ) + return; + + /* handle both horizontal and vertical coordinates */ + for ( i = 0; i <= 1; i++ ) + { + /* shift array pointers so that we can access `foo.y' as `foo.x' */ + in_points = (FT_Vector*)( (FT_Pos*)in_points + i ); + out_points = (FT_Vector*)( (FT_Pos*)out_points + i ); + + if ( in_points[ref1].x > in_points[ref2].x ) + { + p = ref1; + ref1 = ref2; + ref2 = p; + } + + in1 = in_points[ref1].x; + in2 = in_points[ref2].x; + out1 = out_points[ref1].x; + out2 = out_points[ref2].x; + d1 = out1 - in1; + d2 = out2 - in2; + + if ( out1 == out2 || in1 == in2 ) + { + for ( p = p1; p <= p2; p++ ) + { + out = in_points[p].x; + + if ( out <= in1 ) + out += d1; + else if ( out >= in2 ) + out += d2; + else + out = out1; + + out_points[p].x = out; + } + } + else + { + FT_Fixed scale = FT_DivFix( out2 - out1, in2 - in1 ); + + + for ( p = p1; p <= p2; p++ ) + { + out = in_points[p].x; + + if ( out <= in1 ) + out += d1; + else if ( out >= in2 ) + out += d2; + else + out = out1 + FT_MulFix( out - in1, scale ); + + out_points[p].x = out; + } + } + } + } + + + /* Interpolate points without delta values, similar to */ + /* the `IUP' hinting instruction. */ + + /* modeled after `Ins_IUP */ + + static void + tt_handle_deltas( FT_Outline* outline, + FT_Vector* in_points, + FT_Bool* has_delta ) + { + FT_Vector* out_points; + + FT_Int first_point; + FT_Int end_point; + + FT_Int first_delta; + FT_Int cur_delta; + + FT_Int point; + FT_Short contour; + + + /* ignore empty outlines */ + if ( !outline->n_contours ) + return; + + out_points = outline->points; + + contour = 0; + point = 0; + + do + { + end_point = outline->contours[contour]; + first_point = point; + + /* search first point that has a delta */ + while ( point <= end_point && !has_delta[point] ) + point++; + + if ( point <= end_point ) + { + first_delta = point; + cur_delta = point; + + point++; + + while ( point <= end_point ) + { + /* search next point that has a delta */ + /* and interpolate intermediate points */ + if ( has_delta[point] ) + { + tt_delta_interpolate( cur_delta + 1, + point - 1, + cur_delta, + point, + in_points, + out_points ); + cur_delta = point; + } + + point++; + } + + /* shift contour if we only have a single delta */ + if ( cur_delta == first_delta ) + tt_delta_shift( first_point, + end_point, + cur_delta, + in_points, + out_points ); + else + { + /* otherwise handle remaining points */ + /* at the end and beginning of the contour */ + tt_delta_interpolate( cur_delta + 1, + end_point, + cur_delta, + first_delta, + in_points, + out_points ); + + if ( first_delta > 0 ) + tt_delta_interpolate( first_point, + first_delta - 1, + cur_delta, + first_delta, + in_points, + out_points ); + } + } + contour++; + + } while ( contour < outline->n_contours ); + } + + /*************************************************************************/ /* */ /* <Function> */ - /* TT_Vary_Get_Glyph_Deltas */ + /* TT_Vary_Apply_Glyph_Deltas */ /* */ /* <Description> */ - /* Load the appropriate deltas for the current glyph. */ + /* Apply the appropriate deltas to the current glyph. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ @@ -1291,22 +1824,24 @@ /* n_points :: The number of the points in the glyph, including */ /* phantom points. */ /* */ - /* <Output> */ - /* deltas :: The array of points to change. */ + /* <InOut> */ + /* outline :: The outline to change. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) - TT_Vary_Get_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, - FT_Vector* *deltas, - FT_UInt n_points ) + TT_Vary_Apply_Glyph_Deltas( TT_Face face, + FT_UInt glyph_index, + FT_Outline* outline, + FT_UInt n_points ) { FT_Stream stream = face->root.stream; FT_Memory memory = stream->memory; GX_Blend blend = face->blend; - FT_Vector* delta_xy = NULL; + + FT_Vector* points_org = NULL; + FT_Bool* has_delta = NULL; FT_Error error; FT_ULong glyph_start; @@ -1327,15 +1862,18 @@ if ( !face->doblend || blend == NULL ) return FT_THROW( Invalid_Argument ); - /* to be freed by the caller */ - if ( FT_NEW_ARRAY( delta_xy, n_points ) ) - goto Exit; - *deltas = delta_xy; - if ( glyph_index >= blend->gv_glyphcnt || blend->glyphoffsets[glyph_index] == blend->glyphoffsets[glyph_index + 1] ) - return FT_Err_Ok; /* no variation data for this glyph */ + { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " no variation data for this glyph\n" )); + return FT_Err_Ok; + } + + if ( FT_NEW_ARRAY( points_org, n_points ) || + FT_NEW_ARRAY( has_delta, n_points ) ) + goto Fail1; if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - @@ -1353,7 +1891,19 @@ goto Fail2; tupleCount = FT_GET_USHORT(); - offsetToData = glyph_start + FT_GET_USHORT(); + offsetToData = FT_GET_USHORT(); + + /* rough sanity test */ + if ( offsetToData + tupleCount * 4 > blend->gvar_size ) + { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " invalid glyph variation array header\n" )); + + error = FT_THROW( Invalid_Table ); + goto Fail2; + } + + offsetToData += glyph_start; if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) { @@ -1361,47 +1911,55 @@ FT_Stream_SeekSet( stream, offsetToData ); - sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); + sharedpoints = ft_var_readpackedpoints( stream, + blend->gvar_size, + &spoint_count ); offsetToData = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); } - for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i ) + FT_TRACE5(( "gvar: there are %d tuples:\n", + tupleCount & GX_TC_TUPLE_COUNT_MASK )); + + for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) { FT_UInt tupleDataSize; FT_UInt tupleIndex; FT_Fixed apply; + FT_TRACE6(( " tuple %d:\n", i )); + tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { - for ( j = 0; j < blend->num_axis; ++j ) - tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + for ( j = 0; j < blend->num_axis; j++ ) + tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ /* short frac to fixed */ } else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " invalid tuple index\n" )); + error = FT_THROW( Invalid_Table ); - goto Fail3; + goto Fail2; } else - { FT_MEM_COPY( tuple_coords, - &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis], + &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis], blend->num_axis * sizeof ( FT_Fixed ) ); - } if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { - for ( j = 0; j < blend->num_axis; ++j ) - im_start_coords[j] = FT_GET_SHORT() << 2; - for ( j = 0; j < blend->num_axis; ++j ) - im_end_coords[j] = FT_GET_SHORT() << 2; + for ( j = 0; j < blend->num_axis; j++ ) + im_start_coords[j] = FT_GET_SHORT() * 4; + for ( j = 0; j < blend->num_axis; j++ ) + im_end_coords[j] = FT_GET_SHORT() * 4; } apply = ft_var_apply_tuple( blend, @@ -1422,7 +1980,9 @@ { FT_Stream_SeekSet( stream, offsetToData ); - localpoints = ft_var_readpackedpoints( stream, &point_count ); + localpoints = ft_var_readpackedpoints( stream, + blend->gvar_size, + &point_count ); points = localpoints; } else @@ -1432,9 +1992,11 @@ } deltas_x = ft_var_readpackeddeltas( stream, + blend->gvar_size, point_count == 0 ? n_points : point_count ); deltas_y = ft_var_readpackeddeltas( stream, + blend->gvar_size, point_count == 0 ? n_points : point_count ); @@ -1443,24 +2005,104 @@ else if ( points == ALL_POINTS ) { +#ifdef FT_DEBUG_LEVEL_TRACE + int count = 0; +#endif + + + FT_TRACE7(( " point deltas:\n" )); + /* this means that there are deltas for every point in the glyph */ - for ( j = 0; j < n_points; ++j ) + for ( j = 0; j < n_points; j++ ) { - delta_xy[j].x += FT_MulFix( deltas_x[j], apply ); - delta_xy[j].y += FT_MulFix( deltas_y[j], apply ); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Vector point_org = outline->points[j]; +#endif + + + outline->points[j].x += FT_MulFix( deltas_x[j], apply ); + outline->points[j].y += FT_MulFix( deltas_y[j], apply ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( ( point_org.x != outline->points[j].x ) || + ( point_org.y != outline->points[j].y ) ) + { + FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", + j, + point_org.x, + point_org.y, + outline->points[j].x, + outline->points[j].y )); + count++; + } +#endif } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE7(( " none\n" )); +#endif } + else if ( localpoints == NULL ) + ; /* failure, ignore it */ + else { - for ( j = 0; j < point_count; ++j ) +#ifdef FT_DEBUG_LEVEL_TRACE + int count = 0; +#endif + + + /* we have to interpolate the missing deltas similar to the */ + /* IUP bytecode instruction */ + for ( j = 0; j < n_points; j++ ) + { + points_org[j] = outline->points[j]; + has_delta[j] = FALSE; + } + + for ( j = 0; j < point_count; j++ ) { - if ( localpoints[j] >= n_points ) + FT_UShort idx = localpoints[j]; + + + if ( idx >= n_points ) continue; - delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply ); - delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply ); + has_delta[idx] = TRUE; + + outline->points[idx].x += FT_MulFix( deltas_x[j], apply ); + outline->points[idx].y += FT_MulFix( deltas_y[j], apply ); } + + /* no need to handle phantom points here, */ + /* since solitary points can't be interpolated */ + tt_handle_deltas( outline, + points_org, + has_delta ); + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE7(( " point deltas:\n" )); + + for ( j = 0; j < n_points; j++) + { + if ( ( points_org[j].x != outline->points[j].x ) || + ( points_org[j].y != outline->points[j].y ) ) + { + FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", + j, + points_org[j].x, + points_org[j].y, + outline->points[j].x, + outline->points[j].y )); + count++; + } + } + + if ( !count ) + FT_TRACE7(( " none\n" )); +#endif } if ( localpoints != ALL_POINTS ) @@ -1473,22 +2115,21 @@ FT_Stream_SeekSet( stream, here ); } - Fail3: + FT_TRACE5(( "\n" )); + + Fail2: + if ( sharedpoints != ALL_POINTS ) + FT_FREE( sharedpoints ); FT_FREE( tuple_coords ); FT_FREE( im_start_coords ); FT_FREE( im_end_coords ); - Fail2: FT_FRAME_EXIT(); Fail1: - if ( error ) - { - FT_FREE( delta_xy ); - *deltas = NULL; - } + FT_FREE( points_org ); + FT_FREE( has_delta ); - Exit: return error; } @@ -1499,7 +2140,7 @@ /* tt_done_blend */ /* */ /* <Description> */ - /* Frees the blend internal data structure. */ + /* Free the blend internal data structure. */ /* */ FT_LOCAL_DEF( void ) tt_done_blend( FT_Memory memory, @@ -1515,7 +2156,7 @@ if ( blend->avar_segment != NULL ) { - for ( i = 0; i < blend->num_axis; ++i ) + for ( i = 0; i < blend->num_axis; i++ ) FT_FREE( blend->avar_segment[i].correspondence ); FT_FREE( blend->avar_segment ); } diff --git a/drivers/freetype/src/truetype/ttgxvar.h b/drivers/freetype/src/truetype/ttgxvar.h index 82dfc4431f..aa8f6ea592 100644 --- a/drivers/freetype/src/truetype/ttgxvar.h +++ b/drivers/freetype/src/truetype/ttgxvar.h @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader (specification) */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTGXVAR_H__ -#define __TTGXVAR_H__ +#ifndef TTGXVAR_H_ +#define TTGXVAR_H_ #include <ft2build.h> @@ -95,6 +95,8 @@ FT_BEGIN_HEADER FT_UInt gv_glyphcnt; FT_ULong* glyphoffsets; + FT_ULong gvar_size; + } GX_BlendRec; @@ -162,10 +164,10 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - TT_Vary_Get_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, - FT_Vector* *deltas, - FT_UInt n_points ); + TT_Vary_Apply_Glyph_Deltas( TT_Face face, + FT_UInt glyph_index, + FT_Outline* outline, + FT_UInt n_points ); FT_LOCAL( void ) @@ -176,7 +178,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTGXVAR_H__ */ +#endif /* TTGXVAR_H_ */ /* END */ diff --git a/drivers/freetype/src/truetype/ttinterp.c b/drivers/freetype/src/truetype/ttinterp.c index e7ffb987ce..8fe83c5ea8 100644 --- a/drivers/freetype/src/truetype/ttinterp.c +++ b/drivers/freetype/src/truetype/ttinterp.c @@ -4,8 +4,8 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2013 */ -/* by David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* Copyright 1996-2016 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 */ @@ -44,186 +44,34 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_ttinterp - /*************************************************************************/ - /* */ - /* In order to detect infinite loops in the code, we set up a counter */ - /* within the run loop. A single stroke of interpretation is now */ - /* limited to a maximum number of opcodes defined below. */ - /* */ -#define MAX_RUNNABLE_OPCODES 1000000L - - - /*************************************************************************/ - /* */ - /* There are two kinds of implementations: */ - /* */ - /* a. static implementation */ - /* */ - /* The current execution context is a static variable, which fields */ - /* are accessed directly by the interpreter during execution. The */ - /* context is named `cur'. */ - /* */ - /* This version is non-reentrant, of course. */ - /* */ - /* b. indirect implementation */ - /* */ - /* The current execution context is passed to _each_ function as its */ - /* first argument, and each field is thus accessed indirectly. */ - /* */ - /* This version is fully re-entrant. */ - /* */ - /* The idea is that an indirect implementation may be slower to execute */ - /* on low-end processors that are used in some systems (like 386s or */ - /* even 486s). */ - /* */ - /* As a consequence, the indirect implementation is now the default, as */ - /* its performance costs can be considered negligible in our context. */ - /* Note, however, that we kept the same source with macros because: */ - /* */ - /* - The code is kept very close in design to the Pascal code used for */ - /* development. */ - /* */ - /* - It's much more readable that way! */ - /* */ - /* - It's still open to experimentation and tuning. */ - /* */ - /*************************************************************************/ - - -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ - -#define CUR (*exc) /* see ttobjs.h */ - - /*************************************************************************/ - /* */ - /* This macro is used whenever `exec' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_EXEC FT_UNUSED( exc ) - -#else /* static implementation */ - -#define CUR cur - -#define FT_UNUSED_EXEC int __dummy = __dummy - - static - TT_ExecContextRec cur; /* static exec. context variable */ - /* apparently, we have a _lot_ of direct indexing when accessing */ - /* the static `cur', which makes the code bigger (due to all the */ - /* four bytes addresses). */ +#define NO_SUBPIXEL_HINTING \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_35 ) -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* The instruction argument stack. */ - /* */ -#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ - - - /*************************************************************************/ - /* */ - /* This macro is used whenever `args' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) - - -#define SUBPIXEL_HINTING \ - ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#define SUBPIXEL_HINTING_INFINALITY \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ TT_INTERPRETER_VERSION_38 ) +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#define SUBPIXEL_HINTING_MINIMAL \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_40 ) +#endif - /*************************************************************************/ - /* */ - /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ - /* increase readability of the code. */ - /* */ - /*************************************************************************/ - - -#define SKIP_Code() \ - SkipCode( EXEC_ARG ) - -#define GET_ShortIns() \ - GetShortIns( EXEC_ARG ) - -#define NORMalize( x, y, v ) \ - Normalize( EXEC_ARG_ x, y, v ) - -#define SET_SuperRound( scale, flags ) \ - SetSuperRound( EXEC_ARG_ scale, flags ) - -#define ROUND_None( d, c ) \ - Round_None( EXEC_ARG_ d, c ) - -#define INS_Goto_CodeRange( range, ip ) \ - Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) - -#define CUR_Func_move( z, p, d ) \ - CUR.func_move( EXEC_ARG_ z, p, d ) - -#define CUR_Func_move_orig( z, p, d ) \ - CUR.func_move_orig( EXEC_ARG_ z, p, d ) - -#define CUR_Func_round( d, c ) \ - CUR.func_round( EXEC_ARG_ d, c ) - -#define CUR_Func_read_cvt( index ) \ - CUR.func_read_cvt( EXEC_ARG_ index ) - -#define CUR_Func_write_cvt( index, val ) \ - CUR.func_write_cvt( EXEC_ARG_ index, val ) - -#define CUR_Func_move_cvt( index, val ) \ - CUR.func_move_cvt( EXEC_ARG_ index, val ) - -#define CURRENT_Ratio() \ - Current_Ratio( EXEC_ARG ) - -#define CURRENT_Ppem() \ - Current_Ppem( EXEC_ARG ) - -#define CUR_Ppem() \ - Cur_PPEM( EXEC_ARG ) - -#define INS_SxVTL( a, b, c, d ) \ - Ins_SxVTL( EXEC_ARG_ a, b, c, d ) - -#define COMPUTE_Funcs() \ - Compute_Funcs( EXEC_ARG ) - -#define COMPUTE_Round( a ) \ - Compute_Round( EXEC_ARG_ a ) - -#define COMPUTE_Point_Displacement( a, b, c, d ) \ - Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) - -#define MOVE_Zp2_Point( a, b, c, t ) \ - Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) - - -#define CUR_Func_project( v1, v2 ) \ - CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) - -#define CUR_Func_dualproj( v1, v2 ) \ - CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) - -#define CUR_fast_project( v ) \ - CUR.func_project( EXEC_ARG_ (v)->x, (v)->y ) +#define PROJECT( v1, v2 ) \ + exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) -#define CUR_fast_dualproj( v ) \ - CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y ) +#define DUALPROJ( v1, v2 ) \ + exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) +#define FAST_PROJECT( v ) \ + exc->func_project( exc, (v)->x, (v)->y ) - /*************************************************************************/ - /* */ - /* Instruction dispatch function, as used by the interpreter. */ - /* */ - typedef void (*TInstruction_Function)( INS_ARG ); +#define FAST_DUALPROJ( v ) \ + exc->func_dualproj( exc, (v)->x, (v)->y ) /*************************************************************************/ @@ -233,13 +81,6 @@ #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) - /*************************************************************************/ - /* */ - /* This macro computes (a*2^14)/b and complements TT_MulFix14. */ - /* */ -#define TT_DivFix14( a, b ) \ - FT_DivFix( a, (b) << 2 ) - #undef SUCCESS #define SUCCESS 0 @@ -247,16 +88,6 @@ #undef FAILURE #define FAILURE 1 -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define GUESS_VECTOR( V ) \ - if ( CUR.face->unpatented_hinting ) \ - { \ - CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \ - CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \ - } -#else -#define GUESS_VECTOR( V ) -#endif /*************************************************************************/ /* */ @@ -282,10 +113,7 @@ /* <InOut> */ /* exec :: The target execution context. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Goto_CodeRange( TT_ExecContext exec, FT_Int range, FT_Long IP ) @@ -303,14 +131,12 @@ /* which will return to the first byte *after* the code */ /* range, we test for IP <= Size instead of IP < Size. */ /* */ - FT_ASSERT( (FT_ULong)IP <= coderange->size ); + FT_ASSERT( IP <= coderange->size ); exec->code = coderange->base; exec->codeSize = coderange->size; exec->IP = IP; exec->curRange = range; - - return FT_Err_Ok; } @@ -332,10 +158,7 @@ /* <InOut> */ /* exec :: The target execution context. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Set_CodeRange( TT_ExecContext exec, FT_Int range, void* base, @@ -345,8 +168,6 @@ exec->codeRangeTable[range - 1].base = (FT_Byte*)base; exec->codeRangeTable[range - 1].size = length; - - return FT_Err_Ok; } @@ -364,13 +185,7 @@ /* <InOut> */ /* exec :: The target execution context. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Does not set the Error variable. */ - /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ) { @@ -378,8 +193,6 @@ exec->codeRangeTable[range - 1].base = NULL; exec->codeRangeTable[range - 1].size = 0; - - return FT_Err_Ok; } @@ -403,13 +216,10 @@ /* */ /* memory :: A handle to the parent memory object. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ /* <Note> */ /* Only the glyph loader and debugger should call this function. */ /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Done_Context( TT_ExecContext exec ) { FT_Memory memory = exec->memory; @@ -436,8 +246,6 @@ exec->face = NULL; FT_FREE( exec ); - - return FT_Err_Ok; } @@ -481,8 +289,8 @@ exec->stackSize = 0; exec->glyphSize = 0; - exec->stack = NULL; - exec->glyphIns = NULL; + exec->stack = NULL; + exec->glyphIns = NULL; exec->face = NULL; exec->size = NULL; @@ -524,7 +332,7 @@ FT_LOCAL_DEF( FT_Error ) Update_Max( FT_Memory memory, FT_ULong* size, - FT_Long multiplier, + FT_ULong multiplier, void* _pbuff, FT_ULong new_max ) { @@ -617,13 +425,13 @@ /* XXX: We reserve a little more elements on the stack to deal safely */ /* with broken fonts like arialbs, courbs, timesbs, etc. */ - tmp = exec->stackSize; + tmp = (FT_ULong)exec->stackSize; error = Update_Max( exec->memory, &tmp, sizeof ( FT_F26Dot6 ), (void*)&exec->stack, maxp->maxStackElements + 32 ); - exec->stackSize = (FT_UInt)tmp; + exec->stackSize = (FT_Long)tmp; if ( error ) return error; @@ -664,13 +472,10 @@ /* <InOut> */ /* size :: A handle to the target size object. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ /* <Note> */ /* Only the glyph loader and debugger should call this function. */ /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Save_Context( TT_ExecContext exec, TT_Size size ) { @@ -688,8 +493,6 @@ for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) size->codeRangeTable[i] = exec->codeRangeTable[i]; - - return FT_Err_Ok; } @@ -714,19 +517,10 @@ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ - /* <Note> */ - /* Only the glyph loader and debugger should call this function. */ - /* */ FT_LOCAL_DEF( FT_Error ) - TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ) + TT_Run_Context( TT_ExecContext exec ) { - FT_Error error; - - - if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) - != FT_Err_Ok ) - return error; + TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ); exec->zp0 = exec->pts; exec->zp1 = exec->pts; @@ -742,10 +536,6 @@ exec->GS.freeVector = exec->GS.projVector; exec->GS.dualVector = exec->GS.projVector; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - exec->GS.both_x_axis = TRUE; -#endif - exec->GS.round_state = 1; exec->GS.loop = 1; @@ -754,16 +544,7 @@ exec->top = 0; exec->callTop = 0; -#if 1 - FT_UNUSED( debug ); - return exec->face->interpreter( exec ); -#else - if ( !debug ) - return TT_RunIns( exec ); - else - return FT_Err_Ok; -#endif } @@ -781,10 +562,6 @@ { 0x4000, 0 }, { 0x4000, 0 }, -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - TRUE, -#endif - 1, 64, 1, TRUE, 68, 0, 0, 9, 3, 0, FALSE, 0, 1, 1, 1 @@ -796,32 +573,27 @@ FT_EXPORT_DEF( TT_ExecContext ) TT_New_Context( TT_Driver driver ) { - TT_ExecContext exec; - FT_Memory memory; + FT_Memory memory; + FT_Error error; + TT_ExecContext exec = NULL; - memory = driver->root.root.memory; - exec = driver->context; - - if ( !driver->context ) - { - FT_Error error; + if ( !driver ) + goto Fail; - /* allocate object */ - if ( FT_NEW( exec ) ) - goto Fail; + memory = driver->root.root.memory; - /* initialize it; in case of error this deallocates `exec' too */ - error = Init_Context( exec, memory ); - if ( error ) - goto Fail; + /* allocate object */ + if ( FT_NEW( exec ) ) + goto Fail; - /* store it into the driver */ - driver->context = exec; - } + /* initialize it; in case of error this deallocates `exec' too */ + error = Init_Context( exec, memory ); + if ( error ) + goto Fail; - return driver->context; + return exec; Fail: return NULL; @@ -868,8 +640,8 @@ /* SFvTL + */ PACK( 2, 0 ), /* SPvFS */ PACK( 2, 0 ), /* SFvFS */ PACK( 2, 0 ), - /* GPV */ PACK( 0, 2 ), - /* GFV */ PACK( 0, 2 ), + /* GPv */ PACK( 0, 2 ), + /* GFv */ PACK( 0, 2 ), /* SFvTPv */ PACK( 0, 0 ), /* ISECT */ PACK( 5, 0 ), @@ -998,8 +770,8 @@ /* INS_$83 */ PACK( 0, 0 ), /* INS_$84 */ PACK( 0, 0 ), /* ScanCTRL */ PACK( 1, 0 ), - /* SDPVTL[0] */ PACK( 2, 0 ), - /* SDPVTL[1] */ PACK( 2, 0 ), + /* SDPvTL[0] */ PACK( 2, 0 ), + /* SDPvTL[1] */ PACK( 2, 0 ), /* GetINFO */ PACK( 1, 1 ), /* IDEF */ PACK( 1, 0 ), /* ROLL */ PACK( 3, 3 ), @@ -1132,280 +904,284 @@ #ifdef FT_DEBUG_LEVEL_TRACE + /* the first hex digit gives the length of the opcode name; the space */ + /* after the digit is here just to increase readability of the source */ + /* code */ + static const char* const opcode_name[256] = { - "SVTCA y", - "SVTCA x", - "SPvTCA y", - "SPvTCA x", - "SFvTCA y", - "SFvTCA x", - "SPvTL ||", - "SPvTL +", - "SFvTL ||", - "SFvTL +", - "SPvFS", - "SFvFS", - "GPV", - "GFV", - "SFvTPv", - "ISECT", - - "SRP0", - "SRP1", - "SRP2", - "SZP0", - "SZP1", - "SZP2", - "SZPS", - "SLOOP", - "RTG", - "RTHG", - "SMD", - "ELSE", - "JMPR", - "SCvTCi", - "SSwCi", - "SSW", - - "DUP", - "POP", - "CLEAR", - "SWAP", - "DEPTH", - "CINDEX", - "MINDEX", - "AlignPTS", - "INS_$28", - "UTP", - "LOOPCALL", - "CALL", - "FDEF", - "ENDF", - "MDAP[0]", - "MDAP[1]", - - "IUP[0]", - "IUP[1]", - "SHP[0]", - "SHP[1]", - "SHC[0]", - "SHC[1]", - "SHZ[0]", - "SHZ[1]", - "SHPIX", - "IP", - "MSIRP[0]", - "MSIRP[1]", - "AlignRP", - "RTDG", - "MIAP[0]", - "MIAP[1]", - - "NPushB", - "NPushW", - "WS", - "RS", - "WCvtP", - "RCvt", - "GC[0]", - "GC[1]", - "SCFS", - "MD[0]", - "MD[1]", - "MPPEM", - "MPS", - "FlipON", - "FlipOFF", - "DEBUG", - - "LT", - "LTEQ", - "GT", - "GTEQ", - "EQ", - "NEQ", - "ODD", - "EVEN", - "IF", - "EIF", - "AND", - "OR", - "NOT", - "DeltaP1", - "SDB", - "SDS", - - "ADD", - "SUB", - "DIV", - "MUL", - "ABS", - "NEG", - "FLOOR", - "CEILING", - "ROUND[0]", - "ROUND[1]", - "ROUND[2]", - "ROUND[3]", - "NROUND[0]", - "NROUND[1]", - "NROUND[2]", - "NROUND[3]", - - "WCvtF", - "DeltaP2", - "DeltaP3", - "DeltaCn[0]", - "DeltaCn[1]", - "DeltaCn[2]", - "SROUND", - "S45Round", - "JROT", - "JROF", - "ROFF", - "INS_$7B", - "RUTG", - "RDTG", - "SANGW", - "AA", - - "FlipPT", - "FlipRgON", - "FlipRgOFF", - "INS_$83", - "INS_$84", - "ScanCTRL", - "SDVPTL[0]", - "SDVPTL[1]", - "GetINFO", - "IDEF", - "ROLL", - "MAX", - "MIN", - "ScanTYPE", - "InstCTRL", - "INS_$8F", - - "INS_$90", - "INS_$91", - "INS_$92", - "INS_$93", - "INS_$94", - "INS_$95", - "INS_$96", - "INS_$97", - "INS_$98", - "INS_$99", - "INS_$9A", - "INS_$9B", - "INS_$9C", - "INS_$9D", - "INS_$9E", - "INS_$9F", - - "INS_$A0", - "INS_$A1", - "INS_$A2", - "INS_$A3", - "INS_$A4", - "INS_$A5", - "INS_$A6", - "INS_$A7", - "INS_$A8", - "INS_$A9", - "INS_$AA", - "INS_$AB", - "INS_$AC", - "INS_$AD", - "INS_$AE", - "INS_$AF", - - "PushB[0]", - "PushB[1]", - "PushB[2]", - "PushB[3]", - "PushB[4]", - "PushB[5]", - "PushB[6]", - "PushB[7]", - "PushW[0]", - "PushW[1]", - "PushW[2]", - "PushW[3]", - "PushW[4]", - "PushW[5]", - "PushW[6]", - "PushW[7]", - - "MDRP[00]", - "MDRP[01]", - "MDRP[02]", - "MDRP[03]", - "MDRP[04]", - "MDRP[05]", - "MDRP[06]", - "MDRP[07]", - "MDRP[08]", - "MDRP[09]", - "MDRP[10]", - "MDRP[11]", - "MDRP[12]", - "MDRP[13]", - "MDRP[14]", - "MDRP[15]", - - "MDRP[16]", - "MDRP[17]", - "MDRP[18]", - "MDRP[19]", - "MDRP[20]", - "MDRP[21]", - "MDRP[22]", - "MDRP[23]", - "MDRP[24]", - "MDRP[25]", - "MDRP[26]", - "MDRP[27]", - "MDRP[28]", - "MDRP[29]", - "MDRP[30]", - "MDRP[31]", - - "MIRP[00]", - "MIRP[01]", - "MIRP[02]", - "MIRP[03]", - "MIRP[04]", - "MIRP[05]", - "MIRP[06]", - "MIRP[07]", - "MIRP[08]", - "MIRP[09]", - "MIRP[10]", - "MIRP[11]", - "MIRP[12]", - "MIRP[13]", - "MIRP[14]", - "MIRP[15]", - - "MIRP[16]", - "MIRP[17]", - "MIRP[18]", - "MIRP[19]", - "MIRP[20]", - "MIRP[21]", - "MIRP[22]", - "MIRP[23]", - "MIRP[24]", - "MIRP[25]", - "MIRP[26]", - "MIRP[27]", - "MIRP[28]", - "MIRP[29]", - "MIRP[30]", - "MIRP[31]" + "7 SVTCA y", + "7 SVTCA x", + "8 SPvTCA y", + "8 SPvTCA x", + "8 SFvTCA y", + "8 SFvTCA x", + "8 SPvTL ||", + "7 SPvTL +", + "8 SFvTL ||", + "7 SFvTL +", + "5 SPvFS", + "5 SFvFS", + "3 GPv", + "3 GFv", + "6 SFvTPv", + "5 ISECT", + + "4 SRP0", + "4 SRP1", + "4 SRP2", + "4 SZP0", + "4 SZP1", + "4 SZP2", + "4 SZPS", + "5 SLOOP", + "3 RTG", + "4 RTHG", + "3 SMD", + "4 ELSE", + "4 JMPR", + "6 SCvTCi", + "5 SSwCi", + "3 SSW", + + "3 DUP", + "3 POP", + "5 CLEAR", + "4 SWAP", + "5 DEPTH", + "6 CINDEX", + "6 MINDEX", + "8 AlignPTS", + "7 INS_$28", + "3 UTP", + "8 LOOPCALL", + "4 CALL", + "4 FDEF", + "4 ENDF", + "7 MDAP[0]", + "7 MDAP[1]", + + "6 IUP[0]", + "6 IUP[1]", + "6 SHP[0]", + "6 SHP[1]", + "6 SHC[0]", + "6 SHC[1]", + "6 SHZ[0]", + "6 SHZ[1]", + "5 SHPIX", + "2 IP", + "8 MSIRP[0]", + "8 MSIRP[1]", + "7 AlignRP", + "4 RTDG", + "7 MIAP[0]", + "7 MIAP[1]", + + "6 NPushB", + "6 NPushW", + "2 WS", + "2 RS", + "5 WCvtP", + "4 RCvt", + "5 GC[0]", + "5 GC[1]", + "4 SCFS", + "5 MD[0]", + "5 MD[1]", + "5 MPPEM", + "3 MPS", + "6 FlipON", + "7 FlipOFF", + "5 DEBUG", + + "2 LT", + "4 LTEQ", + "2 GT", + "4 GTEQ", + "2 EQ", + "3 NEQ", + "3 ODD", + "4 EVEN", + "2 IF", + "3 EIF", + "3 AND", + "2 OR", + "3 NOT", + "7 DeltaP1", + "3 SDB", + "3 SDS", + + "3 ADD", + "3 SUB", + "3 DIV", + "3 MUL", + "3 ABS", + "3 NEG", + "5 FLOOR", + "7 CEILING", + "8 ROUND[0]", + "8 ROUND[1]", + "8 ROUND[2]", + "8 ROUND[3]", + "9 NROUND[0]", + "9 NROUND[1]", + "9 NROUND[2]", + "9 NROUND[3]", + + "5 WCvtF", + "7 DeltaP2", + "7 DeltaP3", + "A DeltaCn[0]", + "A DeltaCn[1]", + "A DeltaCn[2]", + "6 SROUND", + "8 S45Round", + "4 JROT", + "4 JROF", + "4 ROFF", + "7 INS_$7B", + "4 RUTG", + "4 RDTG", + "5 SANGW", + "2 AA", + + "6 FlipPT", + "8 FlipRgON", + "9 FlipRgOFF", + "7 INS_$83", + "7 INS_$84", + "8 ScanCTRL", + "9 SDPvTL[0]", + "9 SDPvTL[1]", + "7 GetINFO", + "4 IDEF", + "4 ROLL", + "3 MAX", + "3 MIN", + "8 ScanTYPE", + "8 InstCTRL", + "7 INS_$8F", + + "7 INS_$90", + "7 INS_$91", + "7 INS_$92", + "7 INS_$93", + "7 INS_$94", + "7 INS_$95", + "7 INS_$96", + "7 INS_$97", + "7 INS_$98", + "7 INS_$99", + "7 INS_$9A", + "7 INS_$9B", + "7 INS_$9C", + "7 INS_$9D", + "7 INS_$9E", + "7 INS_$9F", + + "7 INS_$A0", + "7 INS_$A1", + "7 INS_$A2", + "7 INS_$A3", + "7 INS_$A4", + "7 INS_$A5", + "7 INS_$A6", + "7 INS_$A7", + "7 INS_$A8", + "7 INS_$A9", + "7 INS_$AA", + "7 INS_$AB", + "7 INS_$AC", + "7 INS_$AD", + "7 INS_$AE", + "7 INS_$AF", + + "8 PushB[0]", + "8 PushB[1]", + "8 PushB[2]", + "8 PushB[3]", + "8 PushB[4]", + "8 PushB[5]", + "8 PushB[6]", + "8 PushB[7]", + "8 PushW[0]", + "8 PushW[1]", + "8 PushW[2]", + "8 PushW[3]", + "8 PushW[4]", + "8 PushW[5]", + "8 PushW[6]", + "8 PushW[7]", + + "8 MDRP[00]", + "8 MDRP[01]", + "8 MDRP[02]", + "8 MDRP[03]", + "8 MDRP[04]", + "8 MDRP[05]", + "8 MDRP[06]", + "8 MDRP[07]", + "8 MDRP[08]", + "8 MDRP[09]", + "8 MDRP[10]", + "8 MDRP[11]", + "8 MDRP[12]", + "8 MDRP[13]", + "8 MDRP[14]", + "8 MDRP[15]", + + "8 MDRP[16]", + "8 MDRP[17]", + "8 MDRP[18]", + "8 MDRP[19]", + "8 MDRP[20]", + "8 MDRP[21]", + "8 MDRP[22]", + "8 MDRP[23]", + "8 MDRP[24]", + "8 MDRP[25]", + "8 MDRP[26]", + "8 MDRP[27]", + "8 MDRP[28]", + "8 MDRP[29]", + "8 MDRP[30]", + "8 MDRP[31]", + + "8 MIRP[00]", + "8 MIRP[01]", + "8 MIRP[02]", + "8 MIRP[03]", + "8 MIRP[04]", + "8 MIRP[05]", + "8 MIRP[06]", + "8 MIRP[07]", + "8 MIRP[08]", + "8 MIRP[09]", + "8 MIRP[10]", + "8 MIRP[11]", + "8 MIRP[12]", + "8 MIRP[13]", + "8 MIRP[14]", + "8 MIRP[15]", + + "8 MIRP[16]", + "8 MIRP[17]", + "8 MIRP[18]", + "8 MIRP[19]", + "8 MIRP[20]", + "8 MIRP[21]", + "8 MIRP[22]", + "8 MIRP[23]", + "8 MIRP[24]", + "8 MIRP[25]", + "8 MIRP[26]", + "8 MIRP[27]", + "8 MIRP[28]", + "8 MIRP[29]", + "8 MIRP[30]", + "8 MIRP[31]" }; #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -1437,8 +1213,107 @@ #undef PACK -#if 1 +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + +#if defined( __arm__ ) && \ + ( defined( __thumb2__ ) || !defined( __thumb__ ) ) + +#define TT_MulFix14 TT_MulFix14_arm + + static FT_Int32 + TT_MulFix14_arm( FT_Int32 a, + FT_Int b ) + { + FT_Int32 t, t2; + + +#if defined( __CC_ARM ) || defined( __ARMCC__ ) + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x2000 /* a += 0x2000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #14 /* a = t2 >> 14 */ + orr a, a, t, lsl #18 /* a |= t << 18 */ + } + +#elif defined( __GNUC__ ) + + __asm__ __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ +#if defined( __clang__ ) && defined( __thumb2__ ) + "add.w %0, %0, #0x2000\n\t" /* %0 += 0x2000 */ +#else + "add %0, %0, #0x2000\n\t" /* %0 += 0x2000 */ +#endif + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #14\n\t" /* %0 = %1 >> 16 */ + "orr %0, %0, %2, lsl #18\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) + : "cc" ); + +#endif + + return a; + } + +#endif /* __arm__ && ( __thumb2__ || !__thumb__ ) */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#if defined( __GNUC__ ) && \ + ( defined( __i386__ ) || defined( __x86_64__ ) ) + +#define TT_MulFix14 TT_MulFix14_long_long + + /* Temporarily disable the warning that C90 doesn't support `long long'. */ +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406 +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wlong-long" + + /* This is declared `noinline' because inlining the function results */ + /* in slower code. The `pure' attribute indicates that the result */ + /* only depends on the parameters. */ + static __attribute__(( noinline )) + __attribute__(( pure )) FT_Int32 + TT_MulFix14_long_long( FT_Int32 a, + FT_Int b ) + { + + long long ret = (long long)a * b; + + /* The following line assumes that right shifting of signed values */ + /* will actually preserve the sign bit. The exact behaviour is */ + /* undefined, but this is true on x86 and x86_64. */ + long long tmp = ret >> 63; + + + ret += 0x2000 + tmp; + + return (FT_Int32)( ret >> 14 ); + } + +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406 +#pragma GCC diagnostic pop +#endif + +#endif /* __GNUC__ && ( __i386__ || __x86_64__ ) */ + + +#ifndef TT_MulFix14 + + /* Compute (a*b)/2^14 with maximum accuracy and rounding. */ + /* This is optimized to be faster than calling FT_MulFix() */ + /* for platforms where sizeof(int) == 2. */ static FT_Int32 TT_MulFix14( FT_Int32 a, FT_Int b ) @@ -1470,37 +1345,50 @@ return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid; } -#else +#endif /* !TT_MulFix14 */ - /* compute (a*b)/2^14 with maximum accuracy and rounding */ - static FT_Int32 - TT_MulFix14( FT_Int32 a, - FT_Int b ) - { - FT_Int32 m, s, hi; - FT_UInt32 l, lo; +#if defined( __GNUC__ ) && \ + ( defined( __i386__ ) || \ + defined( __x86_64__ ) || \ + defined( __arm__ ) ) - /* compute ax*bx as 64-bit value */ - l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); - m = ( a >> 16 ) * b; +#define TT_DotFix14 TT_DotFix14_long_long - lo = l + ( (FT_UInt32)m << 16 ); - hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406 +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wlong-long" - /* divide the result by 2^14 with rounding */ - s = hi >> 31; - l = lo + (FT_UInt32)s; - hi += s + ( l < lo ); - lo = l; + static __attribute__(( pure )) FT_Int32 + TT_DotFix14_long_long( FT_Int32 ax, + FT_Int32 ay, + FT_Int bx, + FT_Int by ) + { + /* Temporarily disable the warning that C90 doesn't support */ + /* `long long'. */ - l = lo + 0x2000U; - hi += l < lo; + long long temp1 = (long long)ax * bx; + long long temp2 = (long long)ay * by; + + + temp1 += temp2; + temp2 = temp1 >> 63; + temp1 += 0x2000 + temp2; + + return (FT_Int32)( temp1 >> 14 ); - return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); } + +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406 +#pragma GCC diagnostic pop #endif +#endif /* __GNUC__ && (__arm__ || __i386__ || __x86_64__) */ + + +#ifndef TT_DotFix14 /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */ static FT_Int32 @@ -1543,6 +1431,8 @@ return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); } +#endif /* TT_DotFix14 */ + /*************************************************************************/ /* */ @@ -1557,48 +1447,43 @@ /* The aspect ratio in 16.16 format, always <= 1.0 . */ /* */ static FT_Long - Current_Ratio( EXEC_OP ) + Current_Ratio( TT_ExecContext exc ) { - if ( !CUR.tt_metrics.ratio ) + if ( !exc->tt_metrics.ratio ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; - else - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; - } - else -#endif - { - if ( CUR.GS.projVector.y == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; + if ( exc->GS.projVector.y == 0 ) + exc->tt_metrics.ratio = exc->tt_metrics.x_ratio; - else if ( CUR.GS.projVector.x == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + else if ( exc->GS.projVector.x == 0 ) + exc->tt_metrics.ratio = exc->tt_metrics.y_ratio; - else - { - FT_F26Dot6 x, y; + else + { + FT_F26Dot6 x, y; - x = TT_MulFix14( CUR.tt_metrics.x_ratio, - CUR.GS.projVector.x ); - y = TT_MulFix14( CUR.tt_metrics.y_ratio, - CUR.GS.projVector.y ); - CUR.tt_metrics.ratio = FT_Hypot( x, y ); - } + x = TT_MulFix14( exc->tt_metrics.x_ratio, + exc->GS.projVector.x ); + y = TT_MulFix14( exc->tt_metrics.y_ratio, + exc->GS.projVector.y ); + exc->tt_metrics.ratio = FT_Hypot( x, y ); } } - return CUR.tt_metrics.ratio; + return exc->tt_metrics.ratio; } - static FT_Long - Current_Ppem( EXEC_OP ) + FT_CALLBACK_DEF( FT_Long ) + Current_Ppem( TT_ExecContext exc ) + { + return exc->tt_metrics.ppem; + } + + + FT_CALLBACK_DEF( FT_Long ) + Current_Ppem_Stretched( TT_ExecContext exc ) { - return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() ); + return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) ); } @@ -1610,48 +1495,54 @@ FT_CALLBACK_DEF( FT_F26Dot6 ) - Read_CVT( EXEC_OP_ FT_ULong idx ) + Read_CVT( TT_ExecContext exc, + FT_ULong idx ) { - return CUR.cvt[idx]; + return exc->cvt[idx]; } FT_CALLBACK_DEF( FT_F26Dot6 ) - Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) + Read_CVT_Stretched( TT_ExecContext exc, + FT_ULong idx ) { - return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() ); + return FT_MulFix( exc->cvt[idx], Current_Ratio( exc ) ); } FT_CALLBACK_DEF( void ) - Write_CVT( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) + Write_CVT( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ) { - CUR.cvt[idx] = value; + exc->cvt[idx] = value; } FT_CALLBACK_DEF( void ) - Write_CVT_Stretched( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) + Write_CVT_Stretched( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ) { - CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() ); + exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) ); } FT_CALLBACK_DEF( void ) - Move_CVT( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) + Move_CVT( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ) { - CUR.cvt[idx] += value; + exc->cvt[idx] += value; } FT_CALLBACK_DEF( void ) - Move_CVT_Stretched( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) + Move_CVT_Stretched( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ) { - CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() ); + exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) ); } @@ -1671,12 +1562,12 @@ /* This one could become a macro. */ /* */ static FT_Short - GetShortIns( EXEC_OP ) + GetShortIns( TT_ExecContext exc ) { - /* Reading a byte stream so there is no endianess (DaveP) */ - CUR.IP += 2; - return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + - CUR.code[CUR.IP - 1] ); + /* Reading a byte stream so there is no endianness (DaveP) */ + exc->IP += 2; + return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) + + exc->code[exc->IP - 1] ); } @@ -1697,23 +1588,24 @@ /* SUCCESS or FAILURE. */ /* */ static FT_Bool - Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, - FT_ULong aIP ) + Ins_Goto_CodeRange( TT_ExecContext exc, + FT_Int aRange, + FT_Long aIP ) { TT_CodeRange* range; if ( aRange < 1 || aRange > 3 ) { - CUR.error = FT_THROW( Bad_Argument ); + exc->error = FT_THROW( Bad_Argument ); return FAILURE; } - range = &CUR.codeRangeTable[aRange - 1]; + range = &exc->codeRangeTable[aRange - 1]; if ( range->base == NULL ) /* invalid coderange */ { - CUR.error = FT_THROW( Invalid_CodeRange ); + exc->error = FT_THROW( Invalid_CodeRange ); return FAILURE; } @@ -1723,14 +1615,14 @@ if ( aIP > range->size ) { - CUR.error = FT_THROW( Code_Overflow ); + exc->error = FT_THROW( Code_Overflow ); return FAILURE; } - CUR.code = range->base; - CUR.codeSize = range->size; - CUR.IP = aIP; - CUR.curRange = aRange; + exc->code = range->base; + exc->codeSize = range->size; + exc->IP = aIP; + exc->curRange = aRange; return SUCCESS; } @@ -1753,37 +1645,57 @@ /* <InOut> */ /* zone :: The affected glyph zone. */ /* */ + /* <Note> */ + /* See `ttinterp.h' for details on backwards compatibility mode. */ + /* `Touches' the point. */ + /* */ static void - Direct_Move( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { FT_F26Dot6 v; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - v = CUR.GS.freeVector.x; + v = exc->GS.freeVector.x; if ( v != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + ( !exc->ignore_x_mode || + ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Exception to the post-IUP curfew: Allow the x component of */ + /* diagonal moves, but only post-IUP. DejaVu tries to adjust */ + /* diagonal stems like on `Z' and `z' post-IUP. */ + if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility ) + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + else +#endif + + if ( NO_SUBPIXEL_HINTING ) + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } - v = CUR.GS.freeVector.y; + v = exc->GS.freeVector.y; if ( v != 0 ) { - zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) ) +#endif + zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1808,26 +1720,23 @@ /* zone :: The affected glyph zone. */ /* */ static void - Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_Orig( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { FT_F26Dot6 v; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - v = CUR.GS.freeVector.x; + v = exc->GS.freeVector.x; if ( v != 0 ) - zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); + zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); - v = CUR.GS.freeVector.y; + v = exc->GS.freeVector.y; if ( v != 0 ) - zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); + zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); } @@ -1837,21 +1746,30 @@ /* */ /* The following versions are used whenever both vectors are both */ /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* See `ttinterp.h' for details on backwards compatibility mode. */ /* */ /*************************************************************************/ static void - Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_X( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { - FT_UNUSED_EXEC; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode ) + zone->cur[point].x += distance; + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility ) + zone->cur[point].x += distance; + else +#endif -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - !CUR.ignore_x_mode ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + if ( NO_SUBPIXEL_HINTING ) zone->cur[point].x += distance; zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; @@ -1859,14 +1777,21 @@ static void - Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_Y( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && exc->iupy_called ) ) +#endif + zone->cur[point].y += distance; - zone->cur[point].y += distance; - zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1881,22 +1806,24 @@ static void - Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_Orig_X( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); zone->org[point].x += distance; } static void - Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_Orig_Y( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); zone->org[point].y += distance; } @@ -1925,18 +1852,19 @@ /* before rounding. */ /* */ static FT_F26Dot6 - Round_None( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_None( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { val = distance + compensation; - if ( distance && val < 0 ) + if ( val < 0 ) val = 0; } else @@ -1966,20 +1894,19 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_To_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { - val = distance + compensation + 32; - if ( distance && val > 0 ) - val &= ~63; - else + val = FT_PIX_ROUND( distance + compensation ); + if ( val < 0 ) val = 0; } else @@ -1989,7 +1916,7 @@ val = 0; } - return val; + return val; } @@ -2010,25 +1937,26 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_To_Half_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { val = FT_PIX_FLOOR( distance + compensation ) + 32; - if ( distance && val < 0 ) - val = 0; + if ( val < 0 ) + val = 32; } else { val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); if ( val > 0 ) - val = 0; + val = -32; } return val; @@ -2052,25 +1980,24 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_Down_To_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { - val = distance + compensation; - if ( distance && val > 0 ) - val &= ~63; - else + val = FT_PIX_FLOOR( distance + compensation ); + if ( val < 0 ) val = 0; } else { - val = -( ( compensation - distance ) & -64 ); + val = -FT_PIX_FLOOR( compensation - distance ); if ( val > 0 ) val = 0; } @@ -2096,20 +2023,19 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_Up_To_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { - val = distance + compensation + 63; - if ( distance && val > 0 ) - val &= ~63; - else + val = FT_PIX_CEIL( distance + compensation ); + if ( val < 0 ) val = 0; } else @@ -2140,20 +2066,19 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_To_Double_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { - FT_F26Dot6 val; + FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { - val = distance + compensation + 16; - if ( distance && val > 0 ) - val &= ~31; - else + val = FT_PAD_ROUND( distance + compensation, 32 ); + if ( val < 0 ) val = 0; } else @@ -2184,33 +2109,34 @@ /* Rounded distance. */ /* */ /* <Note> */ - /* The TrueType specification says very few about the relationship */ + /* The TrueType specification says very little about the relationship */ /* between rounding and engine compensation. However, it seems from */ /* the description of super round that we should add the compensation */ /* before rounding. */ /* */ static FT_F26Dot6 - Round_Super( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_Super( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; if ( distance >= 0 ) { - val = ( distance - CUR.phase + CUR.threshold + compensation ) & - -CUR.period; - if ( distance && val < 0 ) - val = 0; - val += CUR.phase; + val = ( distance - exc->phase + exc->threshold + compensation ) & + -exc->period; + val += exc->phase; + if ( val < 0 ) + val = exc->phase; } else { - val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & - -CUR.period ); + val = -( ( exc->threshold - exc->phase - distance + compensation ) & + -exc->period ); + val -= exc->phase; if ( val > 0 ) - val = 0; - val -= CUR.phase; + val = -exc->phase; } return val; @@ -2238,27 +2164,28 @@ /* greater precision. */ /* */ static FT_F26Dot6 - Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_Super_45( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; if ( distance >= 0 ) { - val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / - CUR.period ) * CUR.period; - if ( distance && val < 0 ) - val = 0; - val += CUR.phase; + val = ( ( distance - exc->phase + exc->threshold + compensation ) / + exc->period ) * exc->period; + val += exc->phase; + if ( val < 0 ) + val = exc->phase; } else { - val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / - CUR.period ) * CUR.period ); + val = -( ( ( exc->threshold - exc->phase - distance + compensation ) / + exc->period ) * exc->period ); + val -= exc->phase; if ( val > 0 ) - val = 0; - val -= CUR.phase; + val = -exc->phase; } return val; @@ -2277,40 +2204,41 @@ /* round_mode :: The rounding mode to be used. */ /* */ static void - Compute_Round( EXEC_OP_ FT_Byte round_mode ) + Compute_Round( TT_ExecContext exc, + FT_Byte round_mode ) { switch ( round_mode ) { case TT_Round_Off: - CUR.func_round = (TT_Round_Func)Round_None; + exc->func_round = (TT_Round_Func)Round_None; break; case TT_Round_To_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Grid; + exc->func_round = (TT_Round_Func)Round_To_Grid; break; case TT_Round_Up_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + exc->func_round = (TT_Round_Func)Round_Up_To_Grid; break; case TT_Round_Down_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + exc->func_round = (TT_Round_Func)Round_Down_To_Grid; break; case TT_Round_To_Half_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + exc->func_round = (TT_Round_Func)Round_To_Half_Grid; break; case TT_Round_To_Double_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + exc->func_round = (TT_Round_Func)Round_To_Double_Grid; break; case TT_Round_Super: - CUR.func_round = (TT_Round_Func)Round_Super; + exc->func_round = (TT_Round_Func)Round_Super; break; case TT_Round_Super_45: - CUR.func_round = (TT_Round_Func)Round_Super_45; + exc->func_round = (TT_Round_Func)Round_Super_45; break; } } @@ -2330,57 +2258,58 @@ /* selector :: The SROUND opcode. */ /* */ static void - SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, - FT_Long selector ) + SetSuperRound( TT_ExecContext exc, + FT_F2Dot14 GridPeriod, + FT_Long selector ) { switch ( (FT_Int)( selector & 0xC0 ) ) { case 0: - CUR.period = GridPeriod / 2; + exc->period = GridPeriod / 2; break; case 0x40: - CUR.period = GridPeriod; + exc->period = GridPeriod; break; case 0x80: - CUR.period = GridPeriod * 2; + exc->period = GridPeriod * 2; break; /* This opcode is reserved, but... */ - case 0xC0: - CUR.period = GridPeriod; + exc->period = GridPeriod; break; } switch ( (FT_Int)( selector & 0x30 ) ) { case 0: - CUR.phase = 0; + exc->phase = 0; break; case 0x10: - CUR.phase = CUR.period / 4; + exc->phase = exc->period / 4; break; case 0x20: - CUR.phase = CUR.period / 2; + exc->phase = exc->period / 2; break; case 0x30: - CUR.phase = CUR.period * 3 / 4; + exc->phase = exc->period * 3 / 4; break; } if ( ( selector & 0x0F ) == 0 ) - CUR.threshold = CUR.period - 1; + exc->threshold = exc->period - 1; else - CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; + exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8; - CUR.period /= 256; - CUR.phase /= 256; - CUR.threshold /= 256; + /* convert to F26Dot6 format */ + exc->period >>= 8; + exc->phase >>= 8; + exc->threshold >>= 8; } @@ -2401,16 +2330,13 @@ /* The distance in F26dot6 format. */ /* */ static FT_F26Dot6 - Project( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) + Project( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, - CUR.GS.projVector.x, - CUR.GS.projVector.y ); + return TT_DotFix14( dx, dy, + exc->GS.projVector.x, + exc->GS.projVector.y ); } @@ -2431,12 +2357,13 @@ /* The distance in F26dot6 format. */ /* */ static FT_F26Dot6 - Dual_Project( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) + Dual_Project( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ) { - return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, - CUR.GS.dualVector.x, - CUR.GS.dualVector.y ); + return TT_DotFix14( dx, dy, + exc->GS.dualVector.x, + exc->GS.dualVector.y ); } @@ -2457,10 +2384,11 @@ /* The distance in F26dot6 format. */ /* */ static FT_F26Dot6 - Project_x( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) + Project_x( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); FT_UNUSED( dy ); return dx; @@ -2484,10 +2412,11 @@ /* The distance in F26dot6 format. */ /* */ static FT_F26Dot6 - Project_y( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) + Project_y( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); FT_UNUSED( dx ); return dy; @@ -2504,101 +2433,56 @@ /* to the current graphics state. */ /* */ static void - Compute_Funcs( EXEC_OP ) + Compute_Funcs( TT_ExecContext exc ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - /* If both vectors point rightwards along the x axis, set */ - /* `both-x-axis' true, otherwise set it false. The x values only */ - /* need be tested because the vector has been normalised to a unit */ - /* vector of length 0x4000 = unity. */ - CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 && - CUR.GS.freeVector.x == 0x4000 ); - - /* Throw away projection and freedom vector information */ - /* because the patents don't allow them to be stored. */ - /* The relevant US Patents are 5155805 and 5325479. */ - CUR.GS.projVector.x = 0; - CUR.GS.projVector.y = 0; - CUR.GS.freeVector.x = 0; - CUR.GS.freeVector.y = 0; - - if ( CUR.GS.both_x_axis ) - { - CUR.func_project = Project_x; - CUR.func_move = Direct_Move_X; - CUR.func_move_orig = Direct_Move_Orig_X; - } - else - { - CUR.func_project = Project_y; - CUR.func_move = Direct_Move_Y; - CUR.func_move_orig = Direct_Move_Orig_Y; - } - - if ( CUR.GS.dualVector.x == 0x4000 ) - CUR.func_dualproj = Project_x; - else if ( CUR.GS.dualVector.y == 0x4000 ) - CUR.func_dualproj = Project_y; - else - CUR.func_dualproj = Dual_Project; - - /* Force recalculation of cached aspect ratio */ - CUR.tt_metrics.ratio = 0; - - return; - } -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - if ( CUR.GS.freeVector.x == 0x4000 ) - CUR.F_dot_P = CUR.GS.projVector.x; - else if ( CUR.GS.freeVector.y == 0x4000 ) - CUR.F_dot_P = CUR.GS.projVector.y; + if ( exc->GS.freeVector.x == 0x4000 ) + exc->F_dot_P = exc->GS.projVector.x; + else if ( exc->GS.freeVector.y == 0x4000 ) + exc->F_dot_P = exc->GS.projVector.y; else - CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x + - (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >> - 14; - - if ( CUR.GS.projVector.x == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_x; - else if ( CUR.GS.projVector.y == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_y; + exc->F_dot_P = + ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x + + (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14; + + if ( exc->GS.projVector.x == 0x4000 ) + exc->func_project = (TT_Project_Func)Project_x; + else if ( exc->GS.projVector.y == 0x4000 ) + exc->func_project = (TT_Project_Func)Project_y; else - CUR.func_project = (TT_Project_Func)Project; + exc->func_project = (TT_Project_Func)Project; - if ( CUR.GS.dualVector.x == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_x; - else if ( CUR.GS.dualVector.y == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_y; + if ( exc->GS.dualVector.x == 0x4000 ) + exc->func_dualproj = (TT_Project_Func)Project_x; + else if ( exc->GS.dualVector.y == 0x4000 ) + exc->func_dualproj = (TT_Project_Func)Project_y; else - CUR.func_dualproj = (TT_Project_Func)Dual_Project; + exc->func_dualproj = (TT_Project_Func)Dual_Project; - CUR.func_move = (TT_Move_Func)Direct_Move; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; + exc->func_move = (TT_Move_Func)Direct_Move; + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig; - if ( CUR.F_dot_P == 0x4000L ) + if ( exc->F_dot_P == 0x4000L ) { - if ( CUR.GS.freeVector.x == 0x4000 ) + if ( exc->GS.freeVector.x == 0x4000 ) { - CUR.func_move = (TT_Move_Func)Direct_Move_X; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; + exc->func_move = (TT_Move_Func)Direct_Move_X; + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; } - else if ( CUR.GS.freeVector.y == 0x4000 ) + else if ( exc->GS.freeVector.y == 0x4000 ) { - CUR.func_move = (TT_Move_Func)Direct_Move_Y; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; + exc->func_move = (TT_Move_Func)Direct_Move_Y; + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; } } /* at small sizes, F_dot_P can become too small, resulting */ /* in overflows and `spikes' in a number of glyphs like `w'. */ - if ( FT_ABS( CUR.F_dot_P ) < 0x400L ) - CUR.F_dot_P = 0x4000L; + if ( FT_ABS( exc->F_dot_P ) < 0x400L ) + exc->F_dot_P = 0x4000L; /* Disable cached aspect ratio */ - CUR.tt_metrics.ratio = 0; + exc->tt_metrics.ratio = 0; } @@ -2621,36 +2505,31 @@ /* Returns FAILURE if a vector parameter is zero. */ /* */ /* <Note> */ - /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ + /* In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and */ /* R is undefined. */ /* */ static FT_Bool - Normalize( EXEC_OP_ FT_F26Dot6 Vx, - FT_F26Dot6 Vy, - FT_UnitVector* R ) + Normalize( FT_F26Dot6 Vx, + FT_F26Dot6 Vy, + FT_UnitVector* R ) { - FT_F26Dot6 W; + FT_Vector V; - FT_UNUSED_EXEC; - - if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L ) + if ( Vx == 0 && Vy == 0 ) { - if ( Vx == 0 && Vy == 0 ) - { - /* XXX: UNDOCUMENTED! It seems that it is possible to try */ - /* to normalize the vector (0,0). Return immediately. */ - return SUCCESS; - } - - Vx *= 0x4000; - Vy *= 0x4000; + /* XXX: UNDOCUMENTED! It seems that it is possible to try */ + /* to normalize the vector (0,0). Return immediately. */ + return SUCCESS; } - W = FT_Hypot( Vx, Vy ); + V.x = Vx; + V.y = Vy; + + FT_Vector_NormLen( &V ); - R->x = (FT_F2Dot14)TT_DivFix14( Vx, W ); - R->y = (FT_F2Dot14)TT_DivFix14( Vy, W ); + R->x = (FT_F2Dot14)( V.x / 4 ); + R->y = (FT_F2Dot14)( V.y / 4 ); return SUCCESS; } @@ -2663,1152 +2542,632 @@ /*************************************************************************/ - static FT_Bool - Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, - FT_UShort aIdx2, - FT_Int aOpc, - FT_UnitVector* Vec ) - { - FT_Long A, B, C; - FT_Vector* p1; - FT_Vector* p2; - - - if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || - BOUNDS( aIdx2, CUR.zp1.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return FAILURE; - } - - p1 = CUR.zp1.cur + aIdx2; - p2 = CUR.zp2.cur + aIdx1; - - A = p1->x - p2->x; - B = p1->y - p2->y; - - /* If p1 == p2, SPVTL and SFVTL behave the same as */ - /* SPVTCA[X] and SFVTCA[X], respectively. */ - /* */ - /* Confirmed by Greg Hitchcock. */ - - if ( A == 0 && B == 0 ) - { - A = 0x4000; - aOpc = 0; - } - - if ( ( aOpc & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, Vec ); - - return SUCCESS; - } - - - /* When not using the big switch statements, the interpreter uses a */ - /* call table defined later below in this source. Each opcode must */ - /* thus have a corresponding function, even trivial ones. */ - /* */ - /* They are all defined there. */ - -#define DO_SVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.projVector.x = A; \ - CUR.GS.dualVector.x = A; \ - \ - CUR.GS.freeVector.y = B; \ - CUR.GS.projVector.y = B; \ - CUR.GS.dualVector.y = B; \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.projVector.x = A; \ - CUR.GS.dualVector.x = A; \ - \ - CUR.GS.projVector.y = B; \ - CUR.GS.dualVector.y = B; \ - \ - GUESS_VECTOR( freeVector ); \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.freeVector.y = B; \ - \ - GUESS_VECTOR( projVector ); \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.projVector ) == SUCCESS ) \ - { \ - CUR.GS.dualVector = CUR.GS.projVector; \ - GUESS_VECTOR( freeVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.freeVector ) == SUCCESS ) \ - { \ - GUESS_VECTOR( projVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTPV \ - GUESS_VECTOR( projVector ); \ - CUR.GS.freeVector = CUR.GS.projVector; \ - COMPUTE_Funcs(); - - -#define DO_SPVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = (FT_Long)S; \ - \ - NORMalize( X, Y, &CUR.GS.projVector ); \ - \ - CUR.GS.dualVector = CUR.GS.projVector; \ - GUESS_VECTOR( freeVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = S; \ - \ - NORMalize( X, Y, &CUR.GS.freeVector ); \ - GUESS_VECTOR( projVector ); \ - COMPUTE_Funcs(); \ - } - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define DO_GPV \ - if ( CUR.face->unpatented_hinting ) \ - { \ - args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ - args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ - } \ - else \ - { \ - args[0] = CUR.GS.projVector.x; \ - args[1] = CUR.GS.projVector.y; \ - } -#else -#define DO_GPV \ - args[0] = CUR.GS.projVector.x; \ - args[1] = CUR.GS.projVector.y; -#endif - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define DO_GFV \ - if ( CUR.face->unpatented_hinting ) \ - { \ - args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ - args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ - } \ - else \ - { \ - args[0] = CUR.GS.freeVector.x; \ - args[1] = CUR.GS.freeVector.y; \ - } -#else -#define DO_GFV \ - args[0] = CUR.GS.freeVector.x; \ - args[1] = CUR.GS.freeVector.y; -#endif - - -#define DO_SRP0 \ - CUR.GS.rp0 = (FT_UShort)args[0]; - - -#define DO_SRP1 \ - CUR.GS.rp1 = (FT_UShort)args[0]; - - -#define DO_SRP2 \ - CUR.GS.rp2 = (FT_UShort)args[0]; - - -#define DO_RTHG \ - CUR.GS.round_state = TT_Round_To_Half_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; - - -#define DO_RTG \ - CUR.GS.round_state = TT_Round_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Grid; - - -#define DO_RTDG \ - CUR.GS.round_state = TT_Round_To_Double_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; - - -#define DO_RUTG \ - CUR.GS.round_state = TT_Round_Up_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; - - -#define DO_RDTG \ - CUR.GS.round_state = TT_Round_Down_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; - - -#define DO_ROFF \ - CUR.GS.round_state = TT_Round_Off; \ - CUR.func_round = (TT_Round_Func)Round_None; - - -#define DO_SROUND \ - SET_SuperRound( 0x4000, args[0] ); \ - CUR.GS.round_state = TT_Round_Super; \ - CUR.func_round = (TT_Round_Func)Round_Super; - - -#define DO_S45ROUND \ - SET_SuperRound( 0x2D41, args[0] ); \ - CUR.GS.round_state = TT_Round_Super_45; \ - CUR.func_round = (TT_Round_Func)Round_Super_45; - - -#define DO_SLOOP \ - if ( args[0] < 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - else \ - CUR.GS.loop = args[0]; - - -#define DO_SMD \ - CUR.GS.minimum_distance = args[0]; - - -#define DO_SCVTCI \ - CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; - - -#define DO_SSWCI \ - CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; - - -#define DO_SSW \ - CUR.GS.single_width_value = FT_MulFix( args[0], \ - CUR.tt_metrics.scale ); - - -#define DO_FLIPON \ - CUR.GS.auto_flip = TRUE; - - -#define DO_FLIPOFF \ - CUR.GS.auto_flip = FALSE; - - -#define DO_SDB \ - CUR.GS.delta_base = (FT_Short)args[0]; - - -#define DO_SDS \ - CUR.GS.delta_shift = (FT_Short)args[0]; - - -#define DO_MD /* nothing */ - - -#define DO_MPPEM \ - args[0] = CURRENT_Ppem(); - - - /* Note: The pointSize should be irrelevant in a given font program; */ - /* we thus decide to return only the ppem. */ -#if 0 - -#define DO_MPS \ - args[0] = CUR.metrics.pointSize; - -#else - -#define DO_MPS \ - args[0] = CURRENT_Ppem(); - -#endif /* 0 */ - - -#define DO_DUP \ - args[1] = args[0]; - - -#define DO_CLEAR \ - CUR.new_top = 0; - - -#define DO_SWAP \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - args[0] = args[1]; \ - args[1] = L; \ - } - - -#define DO_DEPTH \ - args[0] = CUR.top; - - -#define DO_CINDEX \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - \ - if ( L <= 0 || L > CUR.args ) \ - { \ - if ( CUR.pedantic_hinting ) \ - CUR.error = FT_THROW( Invalid_Reference ); \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR.stack[CUR.args - L]; \ - } - - -#define DO_JROT \ - if ( args[1] != 0 ) \ - { \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; \ - } - - -#define DO_JMPR \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; - - -#define DO_JROF \ - if ( args[1] == 0 ) \ - { \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; \ - } - - -#define DO_LT \ - args[0] = ( args[0] < args[1] ); - - -#define DO_LTEQ \ - args[0] = ( args[0] <= args[1] ); - - -#define DO_GT \ - args[0] = ( args[0] > args[1] ); - - -#define DO_GTEQ \ - args[0] = ( args[0] >= args[1] ); - - -#define DO_EQ \ - args[0] = ( args[0] == args[1] ); - - -#define DO_NEQ \ - args[0] = ( args[0] != args[1] ); - - -#define DO_ODD \ - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); - - -#define DO_EVEN \ - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); - - -#define DO_AND \ - args[0] = ( args[0] && args[1] ); - - -#define DO_OR \ - args[0] = ( args[0] || args[1] ); - - -#define DO_NOT \ - args[0] = !args[0]; - - -#define DO_ADD \ - args[0] += args[1]; - - -#define DO_SUB \ - args[0] -= args[1]; - - -#define DO_DIV \ - if ( args[1] == 0 ) \ - CUR.error = FT_THROW( Divide_By_Zero ); \ - else \ - args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); - - -#define DO_MUL \ - args[0] = FT_MulDiv( args[0], args[1], 64L ); - - -#define DO_ABS \ - args[0] = FT_ABS( args[0] ); - - -#define DO_NEG \ - args[0] = -args[0]; - - -#define DO_FLOOR \ - args[0] = FT_PIX_FLOOR( args[0] ); - - -#define DO_CEILING \ - args[0] = FT_PIX_CEIL( args[0] ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - -#define DO_RS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - ARRAY_BOUND_ERROR; \ - else \ - args[0] = 0; \ - } \ - else \ - { \ - /* subpixel hinting - avoid Typeman Dstroke and */ \ - /* IStroke and Vacuform rounds */ \ - \ - if ( SUBPIXEL_HINTING && \ - CUR.ignore_x_mode && \ - ( ( I == 24 && \ - ( CUR.face->sph_found_func_flags & \ - ( SPH_FDEF_SPACING_1 | \ - SPH_FDEF_SPACING_2 ) ) ) || \ - ( I == 22 && \ - ( CUR.sph_in_func_flags & \ - SPH_FDEF_TYPEMAN_STROKES ) ) || \ - ( I == 8 && \ - ( CUR.face->sph_found_func_flags & \ - SPH_FDEF_VACUFORM_ROUND_1 ) && \ - CUR.iup_called ) ) ) \ - args[0] = 0; \ - else \ - args[0] = CUR.storage[I]; \ - } \ - } - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - -#define DO_RS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - else \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR.storage[I]; \ - } - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#define DO_WS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.storage[I] = args[1]; \ - } - - -#define DO_RCVT \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - else \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR_Func_read_cvt( I ); \ - } - - -#define DO_WCVTP \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR_Func_write_cvt( I, args[1] ); \ - } - - -#define DO_WCVTF \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \ - } - - -#define DO_DEBUG \ - CUR.error = FT_THROW( Debug_OpCode ); - - -#define DO_ROUND \ - args[0] = CUR_Func_round( \ - args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); - - -#define DO_NROUND \ - args[0] = ROUND_None( args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); - - -#define DO_MAX \ - if ( args[1] > args[0] ) \ - args[0] = args[1]; - - -#define DO_MIN \ - if ( args[1] < args[0] ) \ - args[0] = args[1]; - - -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - -#undef ARRAY_BOUND_ERROR -#define ARRAY_BOUND_ERROR \ - { \ - CUR.error = FT_THROW( Invalid_Reference ); \ - return; \ - } +#define ARRAY_BOUND_ERROR \ + do \ + { \ + exc->error = FT_THROW( Invalid_Reference ); \ + return; \ + } while (0) /*************************************************************************/ /* */ - /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ - /* Opcode range: 0x00-0x01 */ - /* Stack: --> */ + /* MPPEM[]: Measure Pixel Per EM */ + /* Opcode range: 0x4B */ + /* Stack: --> Euint16 */ /* */ static void - Ins_SVTCA( INS_ARG ) + Ins_MPPEM( TT_ExecContext exc, + FT_Long* args ) { - DO_SVTCA + args[0] = exc->func_cur_ppem( exc ); } /*************************************************************************/ /* */ - /* SPVTCA[a]: Set PVector to Coordinate Axis */ - /* Opcode range: 0x02-0x03 */ - /* Stack: --> */ + /* MPS[]: Measure Point Size */ + /* Opcode range: 0x4C */ + /* Stack: --> Euint16 */ /* */ static void - Ins_SPVTCA( INS_ARG ) + Ins_MPS( TT_ExecContext exc, + FT_Long* args ) { - DO_SPVTCA + /* Note: The point size should be irrelevant in a given font program; */ + /* we thus decide to return only the PPEM value. */ +#if 0 + args[0] = exc->metrics.pointSize; +#else + args[0] = exc->func_cur_ppem( exc ); +#endif } /*************************************************************************/ /* */ - /* SFVTCA[a]: Set FVector to Coordinate Axis */ - /* Opcode range: 0x04-0x05 */ - /* Stack: --> */ + /* DUP[]: DUPlicate the stack's top element */ + /* Opcode range: 0x20 */ + /* Stack: StkElt --> StkElt StkElt */ /* */ static void - Ins_SFVTCA( INS_ARG ) + Ins_DUP( FT_Long* args ) { - DO_SFVTCA + args[1] = args[0]; } /*************************************************************************/ /* */ - /* SPVTL[a]: Set PVector To Line */ - /* Opcode range: 0x06-0x07 */ - /* Stack: uint32 uint32 --> */ + /* POP[]: POP the stack's top element */ + /* Opcode range: 0x21 */ + /* Stack: StkElt --> */ /* */ static void - Ins_SPVTL( INS_ARG ) + Ins_POP( void ) { - DO_SPVTL + /* nothing to do */ } /*************************************************************************/ /* */ - /* SFVTL[a]: Set FVector To Line */ - /* Opcode range: 0x08-0x09 */ - /* Stack: uint32 uint32 --> */ + /* CLEAR[]: CLEAR the entire stack */ + /* Opcode range: 0x22 */ + /* Stack: StkElt... --> */ /* */ static void - Ins_SFVTL( INS_ARG ) + Ins_CLEAR( TT_ExecContext exc ) { - DO_SFVTL + exc->new_top = 0; } /*************************************************************************/ /* */ - /* SFVTPV[]: Set FVector To PVector */ - /* Opcode range: 0x0E */ - /* Stack: --> */ + /* SWAP[]: SWAP the stack's top two elements */ + /* Opcode range: 0x23 */ + /* Stack: 2 * StkElt --> 2 * StkElt */ /* */ static void - Ins_SFVTPV( INS_ARG ) + Ins_SWAP( FT_Long* args ) { - DO_SFVTPV + FT_Long L; + + + L = args[0]; + args[0] = args[1]; + args[1] = L; } /*************************************************************************/ /* */ - /* SPVFS[]: Set PVector From Stack */ - /* Opcode range: 0x0A */ - /* Stack: f2.14 f2.14 --> */ + /* DEPTH[]: return the stack DEPTH */ + /* Opcode range: 0x24 */ + /* Stack: --> uint32 */ /* */ static void - Ins_SPVFS( INS_ARG ) + Ins_DEPTH( TT_ExecContext exc, + FT_Long* args ) { - DO_SPVFS + args[0] = exc->top; } /*************************************************************************/ /* */ - /* SFVFS[]: Set FVector From Stack */ - /* Opcode range: 0x0B */ - /* Stack: f2.14 f2.14 --> */ + /* LT[]: Less Than */ + /* Opcode range: 0x50 */ + /* Stack: int32? int32? --> bool */ /* */ static void - Ins_SFVFS( INS_ARG ) + Ins_LT( FT_Long* args ) { - DO_SFVFS + args[0] = ( args[0] < args[1] ); } /*************************************************************************/ /* */ - /* GPV[]: Get Projection Vector */ - /* Opcode range: 0x0C */ - /* Stack: ef2.14 --> ef2.14 */ + /* LTEQ[]: Less Than or EQual */ + /* Opcode range: 0x51 */ + /* Stack: int32? int32? --> bool */ /* */ static void - Ins_GPV( INS_ARG ) + Ins_LTEQ( FT_Long* args ) { - DO_GPV + args[0] = ( args[0] <= args[1] ); } /*************************************************************************/ - /* GFV[]: Get Freedom Vector */ - /* Opcode range: 0x0D */ - /* Stack: ef2.14 --> ef2.14 */ + /* */ + /* GT[]: Greater Than */ + /* Opcode range: 0x52 */ + /* Stack: int32? int32? --> bool */ /* */ static void - Ins_GFV( INS_ARG ) + Ins_GT( FT_Long* args ) { - DO_GFV + args[0] = ( args[0] > args[1] ); } /*************************************************************************/ /* */ - /* SRP0[]: Set Reference Point 0 */ - /* Opcode range: 0x10 */ - /* Stack: uint32 --> */ + /* GTEQ[]: Greater Than or EQual */ + /* Opcode range: 0x53 */ + /* Stack: int32? int32? --> bool */ /* */ static void - Ins_SRP0( INS_ARG ) + Ins_GTEQ( FT_Long* args ) { - DO_SRP0 + args[0] = ( args[0] >= args[1] ); } /*************************************************************************/ /* */ - /* SRP1[]: Set Reference Point 1 */ - /* Opcode range: 0x11 */ - /* Stack: uint32 --> */ + /* EQ[]: EQual */ + /* Opcode range: 0x54 */ + /* Stack: StkElt StkElt --> bool */ /* */ static void - Ins_SRP1( INS_ARG ) + Ins_EQ( FT_Long* args ) { - DO_SRP1 + args[0] = ( args[0] == args[1] ); } /*************************************************************************/ /* */ - /* SRP2[]: Set Reference Point 2 */ - /* Opcode range: 0x12 */ - /* Stack: uint32 --> */ + /* NEQ[]: Not EQual */ + /* Opcode range: 0x55 */ + /* Stack: StkElt StkElt --> bool */ /* */ static void - Ins_SRP2( INS_ARG ) + Ins_NEQ( FT_Long* args ) { - DO_SRP2 + args[0] = ( args[0] != args[1] ); } /*************************************************************************/ /* */ - /* RTHG[]: Round To Half Grid */ - /* Opcode range: 0x19 */ - /* Stack: --> */ + /* ODD[]: Is ODD */ + /* Opcode range: 0x56 */ + /* Stack: f26.6 --> bool */ /* */ static void - Ins_RTHG( INS_ARG ) + Ins_ODD( TT_ExecContext exc, + FT_Long* args ) { - DO_RTHG + args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 ); } /*************************************************************************/ /* */ - /* RTG[]: Round To Grid */ - /* Opcode range: 0x18 */ - /* Stack: --> */ + /* EVEN[]: Is EVEN */ + /* Opcode range: 0x57 */ + /* Stack: f26.6 --> bool */ /* */ static void - Ins_RTG( INS_ARG ) + Ins_EVEN( TT_ExecContext exc, + FT_Long* args ) { - DO_RTG + args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 ); } /*************************************************************************/ - /* RTDG[]: Round To Double Grid */ - /* Opcode range: 0x3D */ - /* Stack: --> */ + /* */ + /* AND[]: logical AND */ + /* Opcode range: 0x5A */ + /* Stack: uint32 uint32 --> uint32 */ /* */ static void - Ins_RTDG( INS_ARG ) + Ins_AND( FT_Long* args ) { - DO_RTDG + args[0] = ( args[0] && args[1] ); } /*************************************************************************/ - /* RUTG[]: Round Up To Grid */ - /* Opcode range: 0x7C */ - /* Stack: --> */ + /* */ + /* OR[]: logical OR */ + /* Opcode range: 0x5B */ + /* Stack: uint32 uint32 --> uint32 */ /* */ static void - Ins_RUTG( INS_ARG ) + Ins_OR( FT_Long* args ) { - DO_RUTG + args[0] = ( args[0] || args[1] ); } /*************************************************************************/ /* */ - /* RDTG[]: Round Down To Grid */ - /* Opcode range: 0x7D */ - /* Stack: --> */ + /* NOT[]: logical NOT */ + /* Opcode range: 0x5C */ + /* Stack: StkElt --> uint32 */ /* */ static void - Ins_RDTG( INS_ARG ) + Ins_NOT( FT_Long* args ) { - DO_RDTG + args[0] = !args[0]; } /*************************************************************************/ /* */ - /* ROFF[]: Round OFF */ - /* Opcode range: 0x7A */ - /* Stack: --> */ + /* ADD[]: ADD */ + /* Opcode range: 0x60 */ + /* Stack: f26.6 f26.6 --> f26.6 */ /* */ static void - Ins_ROFF( INS_ARG ) + Ins_ADD( FT_Long* args ) { - DO_ROFF + args[0] += args[1]; } /*************************************************************************/ /* */ - /* SROUND[]: Super ROUND */ - /* Opcode range: 0x76 */ - /* Stack: Eint8 --> */ + /* SUB[]: SUBtract */ + /* Opcode range: 0x61 */ + /* Stack: f26.6 f26.6 --> f26.6 */ /* */ static void - Ins_SROUND( INS_ARG ) + Ins_SUB( FT_Long* args ) { - DO_SROUND + args[0] -= args[1]; } /*************************************************************************/ /* */ - /* S45ROUND[]: Super ROUND 45 degrees */ - /* Opcode range: 0x77 */ - /* Stack: uint32 --> */ + /* DIV[]: DIVide */ + /* Opcode range: 0x62 */ + /* Stack: f26.6 f26.6 --> f26.6 */ /* */ static void - Ins_S45ROUND( INS_ARG ) + Ins_DIV( TT_ExecContext exc, + FT_Long* args ) { - DO_S45ROUND + if ( args[1] == 0 ) + exc->error = FT_THROW( Divide_By_Zero ); + else + args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); } /*************************************************************************/ /* */ - /* SLOOP[]: Set LOOP variable */ - /* Opcode range: 0x17 */ - /* Stack: int32? --> */ + /* MUL[]: MULtiply */ + /* Opcode range: 0x63 */ + /* Stack: f26.6 f26.6 --> f26.6 */ /* */ static void - Ins_SLOOP( INS_ARG ) + Ins_MUL( FT_Long* args ) { - DO_SLOOP + args[0] = FT_MulDiv( args[0], args[1], 64L ); } /*************************************************************************/ /* */ - /* SMD[]: Set Minimum Distance */ - /* Opcode range: 0x1A */ - /* Stack: f26.6 --> */ + /* ABS[]: ABSolute value */ + /* Opcode range: 0x64 */ + /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_SMD( INS_ARG ) + Ins_ABS( FT_Long* args ) { - DO_SMD + args[0] = FT_ABS( args[0] ); } /*************************************************************************/ /* */ - /* SCVTCI[]: Set Control Value Table Cut In */ - /* Opcode range: 0x1D */ - /* Stack: f26.6 --> */ + /* NEG[]: NEGate */ + /* Opcode range: 0x65 */ + /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_SCVTCI( INS_ARG ) + Ins_NEG( FT_Long* args ) { - DO_SCVTCI + args[0] = -args[0]; } /*************************************************************************/ /* */ - /* SSWCI[]: Set Single Width Cut In */ - /* Opcode range: 0x1E */ - /* Stack: f26.6 --> */ + /* FLOOR[]: FLOOR */ + /* Opcode range: 0x66 */ + /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_SSWCI( INS_ARG ) + Ins_FLOOR( FT_Long* args ) { - DO_SSWCI + args[0] = FT_PIX_FLOOR( args[0] ); } /*************************************************************************/ /* */ - /* SSW[]: Set Single Width */ - /* Opcode range: 0x1F */ - /* Stack: int32? --> */ + /* CEILING[]: CEILING */ + /* Opcode range: 0x67 */ + /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_SSW( INS_ARG ) + Ins_CEILING( FT_Long* args ) { - DO_SSW + args[0] = FT_PIX_CEIL( args[0] ); } /*************************************************************************/ /* */ - /* FLIPON[]: Set auto-FLIP to ON */ - /* Opcode range: 0x4D */ - /* Stack: --> */ + /* RS[]: Read Store */ + /* Opcode range: 0x43 */ + /* Stack: uint32 --> uint32 */ /* */ static void - Ins_FLIPON( INS_ARG ) + Ins_RS( TT_ExecContext exc, + FT_Long* args ) { - DO_FLIPON + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->storeSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + else + args[0] = 0; + } + else + { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* subpixel hinting - avoid Typeman Dstroke and */ + /* IStroke and Vacuform rounds */ + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( ( I == 24 && + ( exc->face->sph_found_func_flags & + ( SPH_FDEF_SPACING_1 | + SPH_FDEF_SPACING_2 ) ) ) || + ( I == 22 && + ( exc->sph_in_func_flags & + SPH_FDEF_TYPEMAN_STROKES ) ) || + ( I == 8 && + ( exc->face->sph_found_func_flags & + SPH_FDEF_VACUFORM_ROUND_1 ) && + exc->iup_called ) ) ) + args[0] = 0; + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + args[0] = exc->storage[I]; + } } /*************************************************************************/ /* */ - /* FLIPOFF[]: Set auto-FLIP to OFF */ - /* Opcode range: 0x4E */ - /* Stack: --> */ + /* WS[]: Write Store */ + /* Opcode range: 0x42 */ + /* Stack: uint32 uint32 --> */ /* */ static void - Ins_FLIPOFF( INS_ARG ) + Ins_WS( TT_ExecContext exc, + FT_Long* args ) { - DO_FLIPOFF + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->storeSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + } + else + exc->storage[I] = args[1]; } /*************************************************************************/ /* */ - /* SANGW[]: Set ANGle Weight */ - /* Opcode range: 0x7E */ - /* Stack: uint32 --> */ + /* WCVTP[]: Write CVT in Pixel units */ + /* Opcode range: 0x44 */ + /* Stack: f26.6 uint32 --> */ /* */ static void - Ins_SANGW( INS_ARG ) + Ins_WCVTP( TT_ExecContext exc, + FT_Long* args ) { - /* instruction not supported anymore */ + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->cvtSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + } + else + exc->func_write_cvt( exc, I, args[1] ); } /*************************************************************************/ /* */ - /* SDB[]: Set Delta Base */ - /* Opcode range: 0x5E */ - /* Stack: uint32 --> */ + /* WCVTF[]: Write CVT in Funits */ + /* Opcode range: 0x70 */ + /* Stack: uint32 uint32 --> */ /* */ static void - Ins_SDB( INS_ARG ) + Ins_WCVTF( TT_ExecContext exc, + FT_Long* args ) { - DO_SDB + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->cvtSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + } + else + exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale ); } /*************************************************************************/ /* */ - /* SDS[]: Set Delta Shift */ - /* Opcode range: 0x5F */ - /* Stack: uint32 --> */ + /* RCVT[]: Read CVT */ + /* Opcode range: 0x45 */ + /* Stack: uint32 --> f26.6 */ /* */ static void - Ins_SDS( INS_ARG ) + Ins_RCVT( TT_ExecContext exc, + FT_Long* args ) { - DO_SDS + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->cvtSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + else + args[0] = 0; + } + else + args[0] = exc->func_read_cvt( exc, I ); } /*************************************************************************/ /* */ - /* MPPEM[]: Measure Pixel Per EM */ - /* Opcode range: 0x4B */ - /* Stack: --> Euint16 */ + /* AA[]: Adjust Angle */ + /* Opcode range: 0x7F */ + /* Stack: uint32 --> */ /* */ static void - Ins_MPPEM( INS_ARG ) + Ins_AA( void ) { - DO_MPPEM + /* intentionally no longer supported */ } /*************************************************************************/ /* */ - /* MPS[]: Measure Point Size */ - /* Opcode range: 0x4C */ - /* Stack: --> Euint16 */ + /* DEBUG[]: DEBUG. Unsupported. */ + /* Opcode range: 0x4F */ + /* Stack: uint32 --> */ + /* */ + /* Note: The original instruction pops a value from the stack. */ /* */ static void - Ins_MPS( INS_ARG ) + Ins_DEBUG( TT_ExecContext exc ) { - DO_MPS + exc->error = FT_THROW( Debug_OpCode ); } /*************************************************************************/ /* */ - /* DUP[]: DUPlicate the top stack's element */ - /* Opcode range: 0x20 */ - /* Stack: StkElt --> StkElt StkElt */ + /* ROUND[ab]: ROUND value */ + /* Opcode range: 0x68-0x6B */ + /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_DUP( INS_ARG ) + Ins_ROUND( TT_ExecContext exc, + FT_Long* args ) { - DO_DUP + args[0] = exc->func_round( + exc, + args[0], + exc->tt_metrics.compensations[exc->opcode - 0x68] ); } /*************************************************************************/ /* */ - /* POP[]: POP the stack's top element */ - /* Opcode range: 0x21 */ - /* Stack: StkElt --> */ + /* NROUND[ab]: No ROUNDing of value */ + /* Opcode range: 0x6C-0x6F */ + /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_POP( INS_ARG ) + Ins_NROUND( TT_ExecContext exc, + FT_Long* args ) { - /* nothing to do */ + args[0] = Round_None( + exc, + args[0], + exc->tt_metrics.compensations[exc->opcode - 0x6C] ); } /*************************************************************************/ /* */ - /* CLEAR[]: CLEAR the entire stack */ - /* Opcode range: 0x22 */ - /* Stack: StkElt... --> */ + /* MAX[]: MAXimum */ + /* Opcode range: 0x68 */ + /* Stack: int32? int32? --> int32 */ /* */ static void - Ins_CLEAR( INS_ARG ) + Ins_MAX( FT_Long* args ) { - DO_CLEAR + if ( args[1] > args[0] ) + args[0] = args[1]; } /*************************************************************************/ /* */ - /* SWAP[]: SWAP the stack's top two elements */ - /* Opcode range: 0x23 */ - /* Stack: 2 * StkElt --> 2 * StkElt */ + /* MIN[]: MINimum */ + /* Opcode range: 0x69 */ + /* Stack: int32? int32? --> int32 */ /* */ static void - Ins_SWAP( INS_ARG ) + Ins_MIN( FT_Long* args ) { - DO_SWAP + if ( args[1] < args[0] ) + args[0] = args[1]; } /*************************************************************************/ /* */ - /* DEPTH[]: return the stack DEPTH */ - /* Opcode range: 0x24 */ - /* Stack: --> uint32 */ + /* MINDEX[]: Move INDEXed element */ + /* Opcode range: 0x26 */ + /* Stack: int32? --> StkElt */ /* */ static void - Ins_DEPTH( INS_ARG ) + Ins_MINDEX( TT_ExecContext exc, + FT_Long* args ) { - DO_DEPTH + FT_Long L, K; + + + L = args[0]; + + if ( L <= 0 || L > exc->args ) + { + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); + } + else + { + K = exc->stack[exc->args - L]; + + FT_ARRAY_MOVE( &exc->stack[exc->args - L ], + &exc->stack[exc->args - L + 1], + ( L - 1 ) ); + + exc->stack[exc->args - 1] = K; + } } @@ -3819,1364 +3178,1480 @@ /* Stack: int32 --> StkElt */ /* */ static void - Ins_CINDEX( INS_ARG ) + Ins_CINDEX( TT_ExecContext exc, + FT_Long* args ) { - DO_CINDEX + FT_Long L; + + + L = args[0]; + + if ( L <= 0 || L > exc->args ) + { + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); + args[0] = 0; + } + else + args[0] = exc->stack[exc->args - L]; } /*************************************************************************/ /* */ - /* EIF[]: End IF */ - /* Opcode range: 0x59 */ - /* Stack: --> */ + /* ROLL[]: ROLL top three elements */ + /* Opcode range: 0x8A */ + /* Stack: 3 * StkElt --> 3 * StkElt */ /* */ static void - Ins_EIF( INS_ARG ) + Ins_ROLL( FT_Long* args ) { - /* nothing to do */ - } + FT_Long A, B, C; - /*************************************************************************/ - /* */ - /* JROT[]: Jump Relative On True */ - /* Opcode range: 0x78 */ - /* Stack: StkElt int32 --> */ - /* */ - static void - Ins_JROT( INS_ARG ) - { - DO_JROT - } - + A = args[2]; + B = args[1]; + C = args[0]; - /*************************************************************************/ - /* */ - /* JMPR[]: JuMP Relative */ - /* Opcode range: 0x1C */ - /* Stack: int32 --> */ - /* */ - static void - Ins_JMPR( INS_ARG ) - { - DO_JMPR + args[2] = C; + args[1] = A; + args[0] = B; } /*************************************************************************/ /* */ - /* JROF[]: Jump Relative On False */ - /* Opcode range: 0x79 */ - /* Stack: StkElt int32 --> */ + /* MANAGING THE FLOW OF CONTROL */ /* */ - static void - Ins_JROF( INS_ARG ) - { - DO_JROF - } - - /*************************************************************************/ - /* */ - /* LT[]: Less Than */ - /* Opcode range: 0x50 */ - /* Stack: int32? int32? --> bool */ - /* */ - static void - Ins_LT( INS_ARG ) - { - DO_LT - } /*************************************************************************/ /* */ - /* LTEQ[]: Less Than or EQual */ - /* Opcode range: 0x51 */ - /* Stack: int32? int32? --> bool */ + /* SLOOP[]: Set LOOP variable */ + /* Opcode range: 0x17 */ + /* Stack: int32? --> */ /* */ static void - Ins_LTEQ( INS_ARG ) + Ins_SLOOP( TT_ExecContext exc, + FT_Long* args ) { - DO_LTEQ + if ( args[0] < 0 ) + exc->error = FT_THROW( Bad_Argument ); + else + exc->GS.loop = args[0]; } - /*************************************************************************/ - /* */ - /* GT[]: Greater Than */ - /* Opcode range: 0x52 */ - /* Stack: int32? int32? --> bool */ - /* */ - static void - Ins_GT( INS_ARG ) + static FT_Bool + SkipCode( TT_ExecContext exc ) { - DO_GT - } + exc->IP += exc->length; + if ( exc->IP < exc->codeSize ) + { + exc->opcode = exc->code[exc->IP]; - /*************************************************************************/ - /* */ - /* GTEQ[]: Greater Than or EQual */ - /* Opcode range: 0x53 */ - /* Stack: int32? int32? --> bool */ - /* */ - static void - Ins_GTEQ( INS_ARG ) - { - DO_GTEQ - } + exc->length = opcode_length[exc->opcode]; + if ( exc->length < 0 ) + { + if ( exc->IP + 1 >= exc->codeSize ) + goto Fail_Overflow; + exc->length = 2 - exc->length * exc->code[exc->IP + 1]; + } + if ( exc->IP + exc->length <= exc->codeSize ) + return SUCCESS; + } - /*************************************************************************/ - /* */ - /* EQ[]: EQual */ - /* Opcode range: 0x54 */ - /* Stack: StkElt StkElt --> bool */ - /* */ - static void - Ins_EQ( INS_ARG ) - { - DO_EQ + Fail_Overflow: + exc->error = FT_THROW( Code_Overflow ); + return FAILURE; } /*************************************************************************/ /* */ - /* NEQ[]: Not EQual */ - /* Opcode range: 0x55 */ - /* Stack: StkElt StkElt --> bool */ + /* IF[]: IF test */ + /* Opcode range: 0x58 */ + /* Stack: StkElt --> */ /* */ static void - Ins_NEQ( INS_ARG ) + Ins_IF( TT_ExecContext exc, + FT_Long* args ) { - DO_NEQ - } - + FT_Int nIfs; + FT_Bool Out; - /*************************************************************************/ - /* */ - /* ODD[]: Is ODD */ - /* Opcode range: 0x56 */ - /* Stack: f26.6 --> bool */ - /* */ - static void - Ins_ODD( INS_ARG ) - { - DO_ODD - } + if ( args[0] != 0 ) + return; - /*************************************************************************/ - /* */ - /* EVEN[]: Is EVEN */ - /* Opcode range: 0x57 */ - /* Stack: f26.6 --> bool */ - /* */ - static void - Ins_EVEN( INS_ARG ) - { - DO_EVEN - } + nIfs = 1; + Out = 0; + do + { + if ( SkipCode( exc ) == FAILURE ) + return; - /*************************************************************************/ - /* */ - /* AND[]: logical AND */ - /* Opcode range: 0x5A */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ - static void - Ins_AND( INS_ARG ) - { - DO_AND - } + switch ( exc->opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + case 0x1B: /* ELSE */ + Out = FT_BOOL( nIfs == 1 ); + break; - /*************************************************************************/ - /* */ - /* OR[]: logical OR */ - /* Opcode range: 0x5B */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ - static void - Ins_OR( INS_ARG ) - { - DO_OR + case 0x59: /* EIF */ + nIfs--; + Out = FT_BOOL( nIfs == 0 ); + break; + } + } while ( Out == 0 ); } /*************************************************************************/ /* */ - /* NOT[]: logical NOT */ - /* Opcode range: 0x5C */ - /* Stack: StkElt --> uint32 */ + /* ELSE[]: ELSE */ + /* Opcode range: 0x1B */ + /* Stack: --> */ /* */ static void - Ins_NOT( INS_ARG ) + Ins_ELSE( TT_ExecContext exc ) { - DO_NOT - } - + FT_Int nIfs; - /*************************************************************************/ - /* */ - /* ADD[]: ADD */ - /* Opcode range: 0x60 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static void - Ins_ADD( INS_ARG ) - { - DO_ADD - } + nIfs = 1; - /*************************************************************************/ - /* */ - /* SUB[]: SUBtract */ - /* Opcode range: 0x61 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static void - Ins_SUB( INS_ARG ) - { - DO_SUB - } + do + { + if ( SkipCode( exc ) == FAILURE ) + return; + switch ( exc->opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; - /*************************************************************************/ - /* */ - /* DIV[]: DIVide */ - /* Opcode range: 0x62 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static void - Ins_DIV( INS_ARG ) - { - DO_DIV + case 0x59: /* EIF */ + nIfs--; + break; + } + } while ( nIfs != 0 ); } /*************************************************************************/ /* */ - /* MUL[]: MULtiply */ - /* Opcode range: 0x63 */ - /* Stack: f26.6 f26.6 --> f26.6 */ + /* EIF[]: End IF */ + /* Opcode range: 0x59 */ + /* Stack: --> */ /* */ static void - Ins_MUL( INS_ARG ) + Ins_EIF( void ) { - DO_MUL + /* nothing to do */ } /*************************************************************************/ /* */ - /* ABS[]: ABSolute value */ - /* Opcode range: 0x64 */ - /* Stack: f26.6 --> f26.6 */ + /* JMPR[]: JuMP Relative */ + /* Opcode range: 0x1C */ + /* Stack: int32 --> */ /* */ static void - Ins_ABS( INS_ARG ) + Ins_JMPR( TT_ExecContext exc, + FT_Long* args ) { - DO_ABS + if ( args[0] == 0 && exc->args == 0 ) + exc->error = FT_THROW( Bad_Argument ); + exc->IP += args[0]; + if ( exc->IP < 0 || + ( exc->callTop > 0 && + exc->IP > exc->callStack[exc->callTop - 1].Def->end ) ) + exc->error = FT_THROW( Bad_Argument ); + exc->step_ins = FALSE; } /*************************************************************************/ /* */ - /* NEG[]: NEGate */ - /* Opcode range: 0x65 */ - /* Stack: f26.6 --> f26.6 */ + /* JROT[]: Jump Relative On True */ + /* Opcode range: 0x78 */ + /* Stack: StkElt int32 --> */ /* */ static void - Ins_NEG( INS_ARG ) + Ins_JROT( TT_ExecContext exc, + FT_Long* args ) { - DO_NEG + if ( args[1] != 0 ) + Ins_JMPR( exc, args ); } /*************************************************************************/ /* */ - /* FLOOR[]: FLOOR */ - /* Opcode range: 0x66 */ - /* Stack: f26.6 --> f26.6 */ + /* JROF[]: Jump Relative On False */ + /* Opcode range: 0x79 */ + /* Stack: StkElt int32 --> */ /* */ static void - Ins_FLOOR( INS_ARG ) + Ins_JROF( TT_ExecContext exc, + FT_Long* args ) { - DO_FLOOR + if ( args[1] == 0 ) + Ins_JMPR( exc, args ); } /*************************************************************************/ /* */ - /* CEILING[]: CEILING */ - /* Opcode range: 0x67 */ - /* Stack: f26.6 --> f26.6 */ + /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ /* */ - static void - Ins_CEILING( INS_ARG ) - { - DO_CEILING - } - - /*************************************************************************/ - /* */ - /* RS[]: Read Store */ - /* Opcode range: 0x43 */ - /* Stack: uint32 --> uint32 */ - /* */ - static void - Ins_RS( INS_ARG ) - { - DO_RS - } /*************************************************************************/ /* */ - /* WS[]: Write Store */ - /* Opcode range: 0x42 */ - /* Stack: uint32 uint32 --> */ + /* FDEF[]: Function DEFinition */ + /* Opcode range: 0x2C */ + /* Stack: uint32 --> */ /* */ static void - Ins_WS( INS_ARG ) + Ins_FDEF( TT_ExecContext exc, + FT_Long* args ) { - DO_WS - } - + FT_ULong n; + TT_DefRecord* rec; + TT_DefRecord* limit; - /*************************************************************************/ - /* */ - /* WCVTP[]: Write CVT in Pixel units */ - /* Opcode range: 0x44 */ - /* Stack: f26.6 uint32 --> */ - /* */ - static void - Ins_WCVTP( INS_ARG ) - { - DO_WCVTP - } +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* arguments to opcodes are skipped by `SKIP_Code' */ + FT_Byte opcode_pattern[9][12] = { + /* #0 inline delta function 1 */ + { + 0x4B, /* PPEM */ + 0x53, /* GTEQ */ + 0x23, /* SWAP */ + 0x4B, /* PPEM */ + 0x51, /* LTEQ */ + 0x5A, /* AND */ + 0x58, /* IF */ + 0x38, /* SHPIX */ + 0x1B, /* ELSE */ + 0x21, /* POP */ + 0x21, /* POP */ + 0x59 /* EIF */ + }, + /* #1 inline delta function 2 */ + { + 0x4B, /* PPEM */ + 0x54, /* EQ */ + 0x58, /* IF */ + 0x38, /* SHPIX */ + 0x1B, /* ELSE */ + 0x21, /* POP */ + 0x21, /* POP */ + 0x59 /* EIF */ + }, + /* #2 diagonal stroke function */ + { + 0x20, /* DUP */ + 0x20, /* DUP */ + 0xB0, /* PUSHB_1 */ + /* 1 */ + 0x60, /* ADD */ + 0x46, /* GC_cur */ + 0xB0, /* PUSHB_1 */ + /* 64 */ + 0x23, /* SWAP */ + 0x42 /* WS */ + }, + /* #3 VacuFormRound function */ + { + 0x45, /* RCVT */ + 0x23, /* SWAP */ + 0x46, /* GC_cur */ + 0x60, /* ADD */ + 0x20, /* DUP */ + 0xB0 /* PUSHB_1 */ + /* 38 */ + }, + /* #4 TTFautohint bytecode (old) */ + { + 0x20, /* DUP */ + 0x64, /* ABS */ + 0xB0, /* PUSHB_1 */ + /* 32 */ + 0x60, /* ADD */ + 0x66, /* FLOOR */ + 0x23, /* SWAP */ + 0xB0 /* PUSHB_1 */ + }, + /* #5 spacing function 1 */ + { + 0x01, /* SVTCA_x */ + 0xB0, /* PUSHB_1 */ + /* 24 */ + 0x43, /* RS */ + 0x58 /* IF */ + }, + /* #6 spacing function 2 */ + { + 0x01, /* SVTCA_x */ + 0x18, /* RTG */ + 0xB0, /* PUSHB_1 */ + /* 24 */ + 0x43, /* RS */ + 0x58 /* IF */ + }, + /* #7 TypeMan Talk DiagEndCtrl function */ + { + 0x01, /* SVTCA_x */ + 0x20, /* DUP */ + 0xB0, /* PUSHB_1 */ + /* 3 */ + 0x25, /* CINDEX */ + }, + /* #8 TypeMan Talk Align */ + { + 0x06, /* SPVTL */ + 0x7D, /* RDTG */ + }, + }; + FT_UShort opcode_patterns = 9; + FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; + FT_UShort i; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - /*************************************************************************/ - /* */ - /* WCVTF[]: Write CVT in Funits */ - /* Opcode range: 0x70 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_WCVTF( INS_ARG ) - { - DO_WCVTF - } + /* some font programs are broken enough to redefine functions! */ + /* We will then parse the current table. */ + rec = exc->FDefs; + limit = rec + exc->numFDefs; + n = (FT_ULong)args[0]; - /*************************************************************************/ - /* */ - /* RCVT[]: Read CVT */ - /* Opcode range: 0x45 */ - /* Stack: uint32 --> f26.6 */ - /* */ - static void - Ins_RCVT( INS_ARG ) - { - DO_RCVT - } + for ( ; rec < limit; rec++ ) + { + if ( rec->opc == n ) + break; + } + if ( rec == limit ) + { + /* check that there is enough room for new functions */ + if ( exc->numFDefs >= exc->maxFDefs ) + { + exc->error = FT_THROW( Too_Many_Function_Defs ); + return; + } + exc->numFDefs++; + } - /*************************************************************************/ - /* */ - /* AA[]: Adjust Angle */ - /* Opcode range: 0x7F */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_AA( INS_ARG ) - { - /* intentionally no longer supported */ - } + /* Although FDEF takes unsigned 32-bit integer, */ + /* func # must be within unsigned 16-bit integer */ + if ( n > 0xFFFFU ) + { + exc->error = FT_THROW( Too_Many_Function_Defs ); + return; + } + rec->range = exc->curRange; + rec->opc = (FT_UInt16)n; + rec->start = exc->IP + 1; + rec->active = TRUE; + rec->inline_delta = FALSE; + rec->sph_fdef_flags = 0x0000; - /*************************************************************************/ - /* */ - /* DEBUG[]: DEBUG. Unsupported. */ - /* Opcode range: 0x4F */ - /* Stack: uint32 --> */ - /* */ - /* Note: The original instruction pops a value from the stack. */ - /* */ - static void - Ins_DEBUG( INS_ARG ) - { - DO_DEBUG - } + if ( n > exc->maxFunc ) + exc->maxFunc = (FT_UInt16)n; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* We don't know for sure these are typeman functions, */ + /* however they are only active when RS 22 is called */ + if ( n >= 64 && n <= 66 ) + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES; +#endif - /*************************************************************************/ - /* */ - /* ROUND[ab]: ROUND value */ - /* Opcode range: 0x68-0x6B */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static void - Ins_ROUND( INS_ARG ) - { - DO_ROUND - } + /* Now skip the whole function definition. */ + /* We don't allow nested IDEFS & FDEFs. */ + while ( SkipCode( exc ) == SUCCESS ) + { - /*************************************************************************/ - /* */ - /* NROUND[ab]: No ROUNDing of value */ - /* Opcode range: 0x6C-0x6F */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static void - Ins_NROUND( INS_ARG ) - { - DO_NROUND - } +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + + if ( SUBPIXEL_HINTING_INFINALITY ) + { + for ( i = 0; i < opcode_patterns; i++ ) + { + if ( opcode_pointer[i] < opcode_size[i] && + exc->opcode == opcode_pattern[i][opcode_pointer[i]] ) + { + opcode_pointer[i] += 1; + if ( opcode_pointer[i] == opcode_size[i] ) + { + FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n", + i, n, + exc->face->root.family_name, + exc->face->root.style_name )); - /*************************************************************************/ - /* */ - /* MAX[]: MAXimum */ - /* Opcode range: 0x68 */ - /* Stack: int32? int32? --> int32 */ - /* */ - static void - Ins_MAX( INS_ARG ) - { - DO_MAX - } + switch ( i ) + { + case 0: + rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; + exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; + break; + case 1: + rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; + exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; + break; - /*************************************************************************/ - /* */ - /* MIN[]: MINimum */ - /* Opcode range: 0x69 */ - /* Stack: int32? int32? --> int32 */ - /* */ - static void - Ins_MIN( INS_ARG ) - { - DO_MIN - } + case 2: + switch ( n ) + { + /* needs to be implemented still */ + case 58: + rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; + exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; + } + break; + case 3: + switch ( n ) + { + case 0: + rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; + exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; + } + break; -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + case 4: + /* probably not necessary to detect anymore */ + rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; + exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; + break; + case 5: + switch ( n ) + { + case 0: + case 1: + case 2: + case 4: + case 7: + case 8: + rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; + exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1; + } + break; - /*************************************************************************/ - /* */ - /* The following functions are called as is within the switch statement. */ - /* */ - /*************************************************************************/ + case 6: + switch ( n ) + { + case 0: + case 1: + case 2: + case 4: + case 7: + case 8: + rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; + exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2; + } + break; + + case 7: + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + break; + + case 8: +#if 0 + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; +#endif + break; + } + opcode_pointer[i] = 0; + } + } + + else + opcode_pointer[i] = 0; + } + + /* Set sph_compatibility_mode only when deltas are detected */ + exc->face->sph_compatibility_mode = + ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | + ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); + } + +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + + switch ( exc->opcode ) + { + case 0x89: /* IDEF */ + case 0x2C: /* FDEF */ + exc->error = FT_THROW( Nested_DEFS ); + return; + + case 0x2D: /* ENDF */ + rec->end = exc->IP; + return; + } + } + } /*************************************************************************/ /* */ - /* MINDEX[]: Move INDEXed element */ - /* Opcode range: 0x26 */ - /* Stack: int32? --> StkElt */ + /* ENDF[]: END Function definition */ + /* Opcode range: 0x2D */ + /* Stack: --> */ /* */ static void - Ins_MINDEX( INS_ARG ) + Ins_ENDF( TT_ExecContext exc ) { - FT_Long L, K; + TT_CallRec* pRec; - L = args[0]; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + exc->sph_in_func_flags = 0x0000; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( L <= 0 || L > CUR.args ) + if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */ { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( ENDF_In_Exec_Stream ); + return; } - else - { - K = CUR.stack[CUR.args - L]; - FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], - &CUR.stack[CUR.args - L + 1], - ( L - 1 ) ); + exc->callTop--; + + pRec = &exc->callStack[exc->callTop]; - CUR.stack[CUR.args - 1] = K; + pRec->Cur_Count--; + + exc->step_ins = FALSE; + + if ( pRec->Cur_Count > 0 ) + { + exc->callTop++; + exc->IP = pRec->Def->start; } + else + /* Loop through the current function */ + Ins_Goto_CodeRange( exc, pRec->Caller_Range, pRec->Caller_IP ); + + /* Exit the current call frame. */ + + /* NOTE: If the last instruction of a program is a */ + /* CALL or LOOPCALL, the return address is */ + /* always out of the code range. This is a */ + /* valid address, and it is why we do not test */ + /* the result of Ins_Goto_CodeRange() here! */ } /*************************************************************************/ /* */ - /* ROLL[]: ROLL top three elements */ - /* Opcode range: 0x8A */ - /* Stack: 3 * StkElt --> 3 * StkElt */ + /* CALL[]: CALL function */ + /* Opcode range: 0x2B */ + /* Stack: uint32? --> */ /* */ static void - Ins_ROLL( INS_ARG ) + Ins_CALL( TT_ExecContext exc, + FT_Long* args ) { - FT_Long A, B, C; + FT_ULong F; + TT_CallRec* pCrec; + TT_DefRecord* def; - FT_UNUSED_EXEC; + /* first of all, check the index */ - A = args[2]; - B = args[1]; - C = args[0]; + F = (FT_ULong)args[0]; + if ( BOUNDSL( F, exc->maxFunc + 1 ) ) + goto Fail; - args[2] = C; - args[1] = A; - args[0] = B; + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font are defined in increasing order, starting from 0. This */ + /* means that we normally have */ + /* */ + /* exc->maxFunc+1 == exc->numFDefs */ + /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */ + /* */ + /* If this isn't true, we need to look up the function table. */ + + def = exc->FDefs + F; + if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F ) + { + /* look up the FDefs table */ + TT_DefRecord* limit; + + + def = exc->FDefs; + limit = def + exc->numFDefs; + + while ( def < limit && def->opc != F ) + def++; + + if ( def == limit ) + goto Fail; + } + + /* check that the function is active */ + if ( !def->active ) + goto Fail; + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( ( exc->iup_called && + ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || + ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) + goto Fail; + else + exc->sph_in_func_flags = def->sph_fdef_flags; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + + /* check the call stack */ + if ( exc->callTop >= exc->callSize ) + { + exc->error = FT_THROW( Stack_Overflow ); + return; + } + + pCrec = exc->callStack + exc->callTop; + + pCrec->Caller_Range = exc->curRange; + pCrec->Caller_IP = exc->IP + 1; + pCrec->Cur_Count = 1; + pCrec->Def = def; + + exc->callTop++; + + Ins_Goto_CodeRange( exc, def->range, def->start ); + + exc->step_ins = FALSE; + + return; + + Fail: + exc->error = FT_THROW( Invalid_Reference ); } /*************************************************************************/ /* */ - /* MANAGING THE FLOW OF CONTROL */ - /* */ - /* Instructions appear in the specification's order. */ + /* LOOPCALL[]: LOOP and CALL function */ + /* Opcode range: 0x2A */ + /* Stack: uint32? Eint16? --> */ /* */ - /*************************************************************************/ + static void + Ins_LOOPCALL( TT_ExecContext exc, + FT_Long* args ) + { + FT_ULong F; + TT_CallRec* pCrec; + TT_DefRecord* def; - static FT_Bool - SkipCode( EXEC_OP ) - { - CUR.IP += CUR.length; + /* first of all, check the index */ + F = (FT_ULong)args[1]; + if ( BOUNDSL( F, exc->maxFunc + 1 ) ) + goto Fail; + + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font are defined in increasing order, starting from 0. This */ + /* means that we normally have */ + /* */ + /* exc->maxFunc+1 == exc->numFDefs */ + /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */ + /* */ + /* If this isn't true, we need to look up the function table. */ - if ( CUR.IP < CUR.codeSize ) + def = exc->FDefs + F; + if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F ) { - CUR.opcode = CUR.code[CUR.IP]; + /* look up the FDefs table */ + TT_DefRecord* limit; - CUR.length = opcode_length[CUR.opcode]; - if ( CUR.length < 0 ) - { - if ( CUR.IP + 1 >= CUR.codeSize ) - goto Fail_Overflow; - CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; - } - if ( CUR.IP + CUR.length <= CUR.codeSize ) - return SUCCESS; - } + def = exc->FDefs; + limit = def + exc->numFDefs; - Fail_Overflow: - CUR.error = FT_THROW( Code_Overflow ); - return FAILURE; - } + while ( def < limit && def->opc != F ) + def++; + if ( def == limit ) + goto Fail; + } - /*************************************************************************/ - /* */ - /* IF[]: IF test */ - /* Opcode range: 0x58 */ - /* Stack: StkElt --> */ - /* */ - static void - Ins_IF( INS_ARG ) - { - FT_Int nIfs; - FT_Bool Out; + /* check that the function is active */ + if ( !def->active ) + goto Fail; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) + goto Fail; + else + exc->sph_in_func_flags = def->sph_fdef_flags; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( args[0] != 0 ) + /* check stack */ + if ( exc->callTop >= exc->callSize ) + { + exc->error = FT_THROW( Stack_Overflow ); return; + } - nIfs = 1; - Out = 0; - - do + if ( args[0] > 0 ) { - if ( SKIP_Code() == FAILURE ) - return; + pCrec = exc->callStack + exc->callTop; - switch ( CUR.opcode ) - { - case 0x58: /* IF */ - nIfs++; - break; + pCrec->Caller_Range = exc->curRange; + pCrec->Caller_IP = exc->IP + 1; + pCrec->Cur_Count = (FT_Int)args[0]; + pCrec->Def = def; - case 0x1B: /* ELSE */ - Out = FT_BOOL( nIfs == 1 ); - break; + exc->callTop++; - case 0x59: /* EIF */ - nIfs--; - Out = FT_BOOL( nIfs == 0 ); - break; - } - } while ( Out == 0 ); + Ins_Goto_CodeRange( exc, def->range, def->start ); + + exc->step_ins = FALSE; + } + + return; + + Fail: + exc->error = FT_THROW( Invalid_Reference ); } /*************************************************************************/ /* */ - /* ELSE[]: ELSE */ - /* Opcode range: 0x1B */ - /* Stack: --> */ + /* IDEF[]: Instruction DEFinition */ + /* Opcode range: 0x89 */ + /* Stack: Eint8 --> */ /* */ static void - Ins_ELSE( INS_ARG ) + Ins_IDEF( TT_ExecContext exc, + FT_Long* args ) { - FT_Int nIfs; + TT_DefRecord* def; + TT_DefRecord* limit; + - FT_UNUSED_ARG; + /* First of all, look for the same function in our table */ + def = exc->IDefs; + limit = def + exc->numIDefs; - nIfs = 1; + for ( ; def < limit; def++ ) + if ( def->opc == (FT_ULong)args[0] ) + break; - do + if ( def == limit ) { - if ( SKIP_Code() == FAILURE ) + /* check that there is enough room for a new instruction */ + if ( exc->numIDefs >= exc->maxIDefs ) + { + exc->error = FT_THROW( Too_Many_Instruction_Defs ); return; + } + exc->numIDefs++; + } - switch ( CUR.opcode ) - { - case 0x58: /* IF */ - nIfs++; - break; + /* opcode must be unsigned 8-bit integer */ + if ( 0 > args[0] || args[0] > 0x00FF ) + { + exc->error = FT_THROW( Too_Many_Instruction_Defs ); + return; + } - case 0x59: /* EIF */ - nIfs--; - break; + def->opc = (FT_Byte)args[0]; + def->start = exc->IP + 1; + def->range = exc->curRange; + def->active = TRUE; + + if ( (FT_ULong)args[0] > exc->maxIns ) + exc->maxIns = (FT_Byte)args[0]; + + /* Now skip the whole function definition. */ + /* We don't allow nested IDEFs & FDEFs. */ + + while ( SkipCode( exc ) == SUCCESS ) + { + switch ( exc->opcode ) + { + case 0x89: /* IDEF */ + case 0x2C: /* FDEF */ + exc->error = FT_THROW( Nested_DEFS ); + return; + case 0x2D: /* ENDF */ + return; } - } while ( nIfs != 0 ); + } } /*************************************************************************/ /* */ - /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ - /* */ - /* Instructions appear in the specification's order. */ + /* PUSHING DATA ONTO THE INTERPRETER STACK */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ - /* FDEF[]: Function DEFinition */ - /* Opcode range: 0x2C */ - /* Stack: uint32 --> */ + /* NPUSHB[]: PUSH N Bytes */ + /* Opcode range: 0x40 */ + /* Stack: --> uint32... */ /* */ static void - Ins_FDEF( INS_ARG ) + Ins_NPUSHB( TT_ExecContext exc, + FT_Long* args ) { - FT_ULong n; - TT_DefRecord* rec; - TT_DefRecord* limit; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* arguments to opcodes are skipped by `SKIP_Code' */ - FT_Byte opcode_pattern[9][12] = { - /* #0 inline delta function 1 */ - { - 0x4B, /* PPEM */ - 0x53, /* GTEQ */ - 0x23, /* SWAP */ - 0x4B, /* PPEM */ - 0x51, /* LTEQ */ - 0x5A, /* AND */ - 0x58, /* IF */ - 0x38, /* SHPIX */ - 0x1B, /* ELSE */ - 0x21, /* POP */ - 0x21, /* POP */ - 0x59 /* EIF */ - }, - /* #1 inline delta function 2 */ - { - 0x4B, /* PPEM */ - 0x54, /* EQ */ - 0x58, /* IF */ - 0x38, /* SHPIX */ - 0x1B, /* ELSE */ - 0x21, /* POP */ - 0x21, /* POP */ - 0x59 /* EIF */ - }, - /* #2 diagonal stroke function */ - { - 0x20, /* DUP */ - 0x20, /* DUP */ - 0xB0, /* PUSHB_1 */ - /* 1 */ - 0x60, /* ADD */ - 0x46, /* GC_cur */ - 0xB0, /* PUSHB_1 */ - /* 64 */ - 0x23, /* SWAP */ - 0x42 /* WS */ - }, - /* #3 VacuFormRound function */ - { - 0x45, /* RCVT */ - 0x23, /* SWAP */ - 0x46, /* GC_cur */ - 0x60, /* ADD */ - 0x20, /* DUP */ - 0xB0 /* PUSHB_1 */ - /* 38 */ - }, - /* #4 TTFautohint bytecode (old) */ - { - 0x20, /* DUP */ - 0x64, /* ABS */ - 0xB0, /* PUSHB_1 */ - /* 32 */ - 0x60, /* ADD */ - 0x66, /* FLOOR */ - 0x23, /* SWAP */ - 0xB0 /* PUSHB_1 */ - }, - /* #5 spacing function 1 */ - { - 0x01, /* SVTCA_x */ - 0xB0, /* PUSHB_1 */ - /* 24 */ - 0x43, /* RS */ - 0x58 /* IF */ - }, - /* #6 spacing function 2 */ - { - 0x01, /* SVTCA_x */ - 0x18, /* RTG */ - 0xB0, /* PUSHB_1 */ - /* 24 */ - 0x43, /* RS */ - 0x58 /* IF */ - }, - /* #7 TypeMan Talk DiagEndCtrl function */ - { - 0x01, /* SVTCA_x */ - 0x20, /* DUP */ - 0xB0, /* PUSHB_1 */ - /* 3 */ - 0x25, /* CINDEX */ - }, - /* #8 TypeMan Talk Align */ - { - 0x06, /* SPVTL */ - 0x7D, /* RDTG */ - }, - }; - FT_UShort opcode_patterns = 9; - FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; - FT_UShort i; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /* some font programs are broken enough to redefine functions! */ - /* We will then parse the current table. */ - - rec = CUR.FDefs; - limit = rec + CUR.numFDefs; - n = args[0]; - - for ( ; rec < limit; rec++ ) - { - if ( rec->opc == n ) - break; - } + FT_UShort L, K; - if ( rec == limit ) - { - /* check that there is enough room for new functions */ - if ( CUR.numFDefs >= CUR.maxFDefs ) - { - CUR.error = FT_THROW( Too_Many_Function_Defs ); - return; - } - CUR.numFDefs++; - } - /* Although FDEF takes unsigned 32-bit integer, */ - /* func # must be within unsigned 16-bit integer */ - if ( n > 0xFFFFU ) + L = (FT_UShort)exc->code[exc->IP + 1]; + + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) ) { - CUR.error = FT_THROW( Too_Many_Function_Defs ); + exc->error = FT_THROW( Stack_Overflow ); return; } - rec->range = CUR.curRange; - rec->opc = (FT_UInt16)n; - rec->start = CUR.IP + 1; - rec->active = TRUE; - rec->inline_delta = FALSE; - rec->sph_fdef_flags = 0x0000; + for ( K = 1; K <= L; K++ ) + args[K - 1] = exc->code[exc->IP + K + 1]; - if ( n > CUR.maxFunc ) - CUR.maxFunc = (FT_UInt16)n; + exc->new_top += L; + } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* We don't know for sure these are typeman functions, */ - /* however they are only active when RS 22 is called */ - if ( n >= 64 && n <= 66 ) - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES; -#endif - /* Now skip the whole function definition. */ - /* We don't allow nested IDEFS & FDEFs. */ + /*************************************************************************/ + /* */ + /* NPUSHW[]: PUSH N Words */ + /* Opcode range: 0x41 */ + /* Stack: --> int32... */ + /* */ + static void + Ins_NPUSHW( TT_ExecContext exc, + FT_Long* args ) + { + FT_UShort L, K; + + + L = (FT_UShort)exc->code[exc->IP + 1]; - while ( SKIP_Code() == SUCCESS ) + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) ) { + exc->error = FT_THROW( Stack_Overflow ); + return; + } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + exc->IP += 2; - if ( SUBPIXEL_HINTING ) - { - for ( i = 0; i < opcode_patterns; i++ ) - { - if ( opcode_pointer[i] < opcode_size[i] && - CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) - { - opcode_pointer[i] += 1; + for ( K = 0; K < L; K++ ) + args[K] = GetShortIns( exc ); - if ( opcode_pointer[i] == opcode_size[i] ) - { - FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n", - i, n, - CUR.face->root.family_name, - CUR.face->root.style_name )); + exc->step_ins = FALSE; + exc->new_top += L; + } - switch ( i ) - { - case 0: - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; - break; - case 1: - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; - CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; - break; + /*************************************************************************/ + /* */ + /* PUSHB[abc]: PUSH Bytes */ + /* Opcode range: 0xB0-0xB7 */ + /* Stack: --> uint32... */ + /* */ + static void + Ins_PUSHB( TT_ExecContext exc, + FT_Long* args ) + { + FT_UShort L, K; - case 2: - switch ( n ) - { - /* needs to be implemented still */ - case 58: - rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; - CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; - } - break; - case 3: - switch ( n ) - { - case 0: - rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; - } - break; + L = (FT_UShort)( exc->opcode - 0xB0 + 1 ); - case 4: - /* probably not necessary to detect anymore */ - rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; - break; + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) ) + { + exc->error = FT_THROW( Stack_Overflow ); + return; + } - case 5: - switch ( n ) - { - case 0: - case 1: - case 2: - case 4: - case 7: - case 8: - rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1; - } - break; + for ( K = 1; K <= L; K++ ) + args[K - 1] = exc->code[exc->IP + K]; + } - case 6: - switch ( n ) - { - case 0: - case 1: - case 2: - case 4: - case 7: - case 8: - rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; - CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2; - } - break; - case 7: - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - break; + /*************************************************************************/ + /* */ + /* PUSHW[abc]: PUSH Words */ + /* Opcode range: 0xB8-0xBF */ + /* Stack: --> int32... */ + /* */ + static void + Ins_PUSHW( TT_ExecContext exc, + FT_Long* args ) + { + FT_UShort L, K; - case 8: -#if 0 - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; -#endif - break; - } - opcode_pointer[i] = 0; - } - } - else - opcode_pointer[i] = 0; - } + L = (FT_UShort)( exc->opcode - 0xB8 + 1 ); - /* Set sph_compatibility_mode only when deltas are detected */ - CUR.face->sph_compatibility_mode = - ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | - ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); - } + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) ) + { + exc->error = FT_THROW( Stack_Overflow ); + return; + } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + exc->IP++; - switch ( CUR.opcode ) - { - case 0x89: /* IDEF */ - case 0x2C: /* FDEF */ - CUR.error = FT_THROW( Nested_DEFS ); - return; + for ( K = 0; K < L; K++ ) + args[K] = GetShortIns( exc ); - case 0x2D: /* ENDF */ - rec->end = CUR.IP; - return; - } - } + exc->step_ins = FALSE; } /*************************************************************************/ /* */ - /* ENDF[]: END Function definition */ - /* Opcode range: 0x2D */ - /* Stack: --> */ + /* MANAGING THE GRAPHICS STATE */ /* */ - static void - Ins_ENDF( INS_ARG ) - { - TT_CallRec* pRec; + /*************************************************************************/ - FT_UNUSED_ARG; + static FT_Bool + Ins_SxVTL( TT_ExecContext exc, + FT_UShort aIdx1, + FT_UShort aIdx2, + FT_UnitVector* Vec ) + { + FT_Long A, B, C; + FT_Vector* p1; + FT_Vector* p2; + + FT_Byte opcode = exc->opcode; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - CUR.sph_in_func_flags = 0x0000; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ + if ( BOUNDS( aIdx1, exc->zp2.n_points ) || + BOUNDS( aIdx2, exc->zp1.n_points ) ) { - CUR.error = FT_THROW( ENDF_In_Exec_Stream ); - return; + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); + return FAILURE; } - CUR.callTop--; + p1 = exc->zp1.cur + aIdx2; + p2 = exc->zp2.cur + aIdx1; - pRec = &CUR.callStack[CUR.callTop]; + A = p1->x - p2->x; + B = p1->y - p2->y; - pRec->Cur_Count--; + /* If p1 == p2, SPvTL and SFvTL behave the same as */ + /* SPvTCA[X] and SFvTCA[X], respectively. */ + /* */ + /* Confirmed by Greg Hitchcock. */ - CUR.step_ins = FALSE; + if ( A == 0 && B == 0 ) + { + A = 0x4000; + opcode = 0; + } - if ( pRec->Cur_Count > 0 ) + if ( ( opcode & 1 ) != 0 ) { - CUR.callTop++; - CUR.IP = pRec->Cur_Restart; + C = B; /* counter clockwise rotation */ + B = A; + A = -C; } - else - /* Loop through the current function */ - INS_Goto_CodeRange( pRec->Caller_Range, - pRec->Caller_IP ); - /* Exit the current call frame. */ + Normalize( A, B, Vec ); - /* NOTE: If the last instruction of a program is a */ - /* CALL or LOOPCALL, the return address is */ - /* always out of the code range. This is a */ - /* valid address, and it is why we do not test */ - /* the result of Ins_Goto_CodeRange() here! */ + return SUCCESS; } /*************************************************************************/ /* */ - /* CALL[]: CALL function */ - /* Opcode range: 0x2B */ - /* Stack: uint32? --> */ + /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ + /* Opcode range: 0x00-0x01 */ + /* Stack: --> */ + /* */ + /* SPvTCA[a]: Set PVector to Coordinate Axis */ + /* Opcode range: 0x02-0x03 */ + /* Stack: --> */ + /* */ + /* SFvTCA[a]: Set FVector to Coordinate Axis */ + /* Opcode range: 0x04-0x05 */ + /* Stack: --> */ /* */ static void - Ins_CALL( INS_ARG ) + Ins_SxyTCA( TT_ExecContext exc ) { - FT_ULong F; - TT_CallRec* pCrec; - TT_DefRecord* def; + FT_Short AA, BB; + FT_Byte opcode = exc->opcode; - /* first of all, check the index */ - - F = args[0]; - if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) - goto Fail; - /* Except for some old Apple fonts, all functions in a TrueType */ - /* font are defined in increasing order, starting from 0. This */ - /* means that we normally have */ - /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ - /* */ - /* If this isn't true, we need to look up the function table. */ + AA = (FT_Short)( ( opcode & 1 ) << 14 ); + BB = (FT_Short)( AA ^ 0x4000 ); - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + if ( opcode < 4 ) { - /* look up the FDefs table */ - TT_DefRecord* limit; - - - def = CUR.FDefs; - limit = def + CUR.numFDefs; - - while ( def < limit && def->opc != F ) - def++; + exc->GS.projVector.x = AA; + exc->GS.projVector.y = BB; - if ( def == limit ) - goto Fail; + exc->GS.dualVector.x = AA; + exc->GS.dualVector.y = BB; } - /* check that the function is active */ - if ( !def->active ) - goto Fail; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - ( ( CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) - goto Fail; - else - CUR.sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - /* check the call stack */ - if ( CUR.callTop >= CUR.callSize ) + if ( ( opcode & 2 ) == 0 ) { - CUR.error = FT_THROW( Stack_Overflow ); - return; + exc->GS.freeVector.x = AA; + exc->GS.freeVector.y = BB; } - pCrec = CUR.callStack + CUR.callTop; + Compute_Funcs( exc ); + } - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; - pCrec->Cur_Count = 1; - pCrec->Cur_Restart = def->start; - pCrec->Cur_End = def->end; - CUR.callTop++; + /*************************************************************************/ + /* */ + /* SPvTL[a]: Set PVector To Line */ + /* Opcode range: 0x06-0x07 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SPVTL( TT_ExecContext exc, + FT_Long* args ) + { + if ( Ins_SxVTL( exc, + (FT_UShort)args[1], + (FT_UShort)args[0], + &exc->GS.projVector ) == SUCCESS ) + { + exc->GS.dualVector = exc->GS.projVector; + Compute_Funcs( exc ); + } + } - INS_Goto_CodeRange( def->range, - def->start ); - CUR.step_ins = FALSE; + /*************************************************************************/ + /* */ + /* SFvTL[a]: Set FVector To Line */ + /* Opcode range: 0x08-0x09 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SFVTL( TT_ExecContext exc, + FT_Long* args ) + { + if ( Ins_SxVTL( exc, + (FT_UShort)args[1], + (FT_UShort)args[0], + &exc->GS.freeVector ) == SUCCESS ) + { + Compute_Funcs( exc ); + } + } - return; - Fail: - CUR.error = FT_THROW( Invalid_Reference ); + /*************************************************************************/ + /* */ + /* SFvTPv[]: Set FVector To PVector */ + /* Opcode range: 0x0E */ + /* Stack: --> */ + /* */ + static void + Ins_SFVTPV( TT_ExecContext exc ) + { + exc->GS.freeVector = exc->GS.projVector; + Compute_Funcs( exc ); } /*************************************************************************/ /* */ - /* LOOPCALL[]: LOOP and CALL function */ - /* Opcode range: 0x2A */ - /* Stack: uint32? Eint16? --> */ - /* */ + /* SPvFS[]: Set PVector From Stack */ + /* Opcode range: 0x0A */ + /* Stack: f2.14 f2.14 --> */ + /* */ static void - Ins_LOOPCALL( INS_ARG ) + Ins_SPVFS( TT_ExecContext exc, + FT_Long* args ) { - FT_ULong F; - TT_CallRec* pCrec; - TT_DefRecord* def; + FT_Short S; + FT_Long X, Y; - /* first of all, check the index */ - F = args[1]; - if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) - goto Fail; - - /* Except for some old Apple fonts, all functions in a TrueType */ - /* font are defined in increasing order, starting from 0. This */ - /* means that we normally have */ - /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ - /* */ - /* If this isn't true, we need to look up the function table. */ + /* Only use low 16bits, then sign extend */ + S = (FT_Short)args[1]; + Y = (FT_Long)S; + S = (FT_Short)args[0]; + X = (FT_Long)S; - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) - { - /* look up the FDefs table */ - TT_DefRecord* limit; + Normalize( X, Y, &exc->GS.projVector ); + exc->GS.dualVector = exc->GS.projVector; + Compute_Funcs( exc ); + } - def = CUR.FDefs; - limit = def + CUR.numFDefs; - while ( def < limit && def->opc != F ) - def++; + /*************************************************************************/ + /* */ + /* SFvFS[]: Set FVector From Stack */ + /* Opcode range: 0x0B */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SFVFS( TT_ExecContext exc, + FT_Long* args ) + { + FT_Short S; + FT_Long X, Y; - if ( def == limit ) - goto Fail; - } - /* check that the function is active */ - if ( !def->active ) - goto Fail; + /* Only use low 16bits, then sign extend */ + S = (FT_Short)args[1]; + Y = (FT_Long)S; + S = (FT_Short)args[0]; + X = S; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) - goto Fail; - else - CUR.sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + Normalize( X, Y, &exc->GS.freeVector ); + Compute_Funcs( exc ); + } - /* check stack */ - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - if ( args[0] > 0 ) - { - pCrec = CUR.callStack + CUR.callTop; + /*************************************************************************/ + /* */ + /* GPv[]: Get Projection Vector */ + /* Opcode range: 0x0C */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GPV( TT_ExecContext exc, + FT_Long* args ) + { + args[0] = exc->GS.projVector.x; + args[1] = exc->GS.projVector.y; + } - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; - pCrec->Cur_Count = (FT_Int)args[0]; - pCrec->Cur_Restart = def->start; - pCrec->Cur_End = def->end; - CUR.callTop++; + /*************************************************************************/ + /* */ + /* GFv[]: Get Freedom Vector */ + /* Opcode range: 0x0D */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GFV( TT_ExecContext exc, + FT_Long* args ) + { + args[0] = exc->GS.freeVector.x; + args[1] = exc->GS.freeVector.y; + } - INS_Goto_CodeRange( def->range, def->start ); - CUR.step_ins = FALSE; - } + /*************************************************************************/ + /* */ + /* SRP0[]: Set Reference Point 0 */ + /* Opcode range: 0x10 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP0( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.rp0 = (FT_UShort)args[0]; + } - return; - Fail: - CUR.error = FT_THROW( Invalid_Reference ); + /*************************************************************************/ + /* */ + /* SRP1[]: Set Reference Point 1 */ + /* Opcode range: 0x11 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP1( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.rp1 = (FT_UShort)args[0]; } /*************************************************************************/ /* */ - /* IDEF[]: Instruction DEFinition */ - /* Opcode range: 0x89 */ - /* Stack: Eint8 --> */ + /* SRP2[]: Set Reference Point 2 */ + /* Opcode range: 0x12 */ + /* Stack: uint32 --> */ /* */ static void - Ins_IDEF( INS_ARG ) + Ins_SRP2( TT_ExecContext exc, + FT_Long* args ) { - TT_DefRecord* def; - TT_DefRecord* limit; + exc->GS.rp2 = (FT_UShort)args[0]; + } - /* First of all, look for the same function in our table */ + /*************************************************************************/ + /* */ + /* SMD[]: Set Minimum Distance */ + /* Opcode range: 0x1A */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SMD( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.minimum_distance = args[0]; + } - def = CUR.IDefs; - limit = def + CUR.numIDefs; - for ( ; def < limit; def++ ) - if ( def->opc == (FT_ULong)args[0] ) - break; + /*************************************************************************/ + /* */ + /* SCVTCI[]: Set Control Value Table Cut In */ + /* Opcode range: 0x1D */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SCVTCI( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.control_value_cutin = (FT_F26Dot6)args[0]; + } - if ( def == limit ) - { - /* check that there is enough room for a new instruction */ - if ( CUR.numIDefs >= CUR.maxIDefs ) - { - CUR.error = FT_THROW( Too_Many_Instruction_Defs ); - return; - } - CUR.numIDefs++; - } - /* opcode must be unsigned 8-bit integer */ - if ( 0 > args[0] || args[0] > 0x00FF ) - { - CUR.error = FT_THROW( Too_Many_Instruction_Defs ); - return; - } + /*************************************************************************/ + /* */ + /* SSWCI[]: Set Single Width Cut In */ + /* Opcode range: 0x1E */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SSWCI( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.single_width_cutin = (FT_F26Dot6)args[0]; + } - def->opc = (FT_Byte)args[0]; - def->start = CUR.IP + 1; - def->range = CUR.curRange; - def->active = TRUE; - if ( (FT_ULong)args[0] > CUR.maxIns ) - CUR.maxIns = (FT_Byte)args[0]; + /*************************************************************************/ + /* */ + /* SSW[]: Set Single Width */ + /* Opcode range: 0x1F */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SSW( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.single_width_value = FT_MulFix( args[0], + exc->tt_metrics.scale ); + } - /* Now skip the whole function definition. */ - /* We don't allow nested IDEFs & FDEFs. */ - while ( SKIP_Code() == SUCCESS ) - { - switch ( CUR.opcode ) - { - case 0x89: /* IDEF */ - case 0x2C: /* FDEF */ - CUR.error = FT_THROW( Nested_DEFS ); - return; - case 0x2D: /* ENDF */ - return; - } - } + /*************************************************************************/ + /* */ + /* FLIPON[]: Set auto-FLIP to ON */ + /* Opcode range: 0x4D */ + /* Stack: --> */ + /* */ + static void + Ins_FLIPON( TT_ExecContext exc ) + { + exc->GS.auto_flip = TRUE; } /*************************************************************************/ /* */ - /* PUSHING DATA ONTO THE INTERPRETER STACK */ - /* */ - /* Instructions appear in the specification's order. */ + /* FLIPOFF[]: Set auto-FLIP to OFF */ + /* Opcode range: 0x4E */ + /* Stack: --> */ /* */ - /*************************************************************************/ + static void + Ins_FLIPOFF( TT_ExecContext exc ) + { + exc->GS.auto_flip = FALSE; + } /*************************************************************************/ /* */ - /* NPUSHB[]: PUSH N Bytes */ - /* Opcode range: 0x40 */ - /* Stack: --> uint32... */ + /* SANGW[]: Set ANGle Weight */ + /* Opcode range: 0x7E */ + /* Stack: uint32 --> */ /* */ static void - Ins_NPUSHB( INS_ARG ) + Ins_SANGW( void ) { - FT_UShort L, K; - + /* instruction not supported anymore */ + } - L = (FT_UShort)CUR.code[CUR.IP + 1]; - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } + /*************************************************************************/ + /* */ + /* SDB[]: Set Delta Base */ + /* Opcode range: 0x5E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDB( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.delta_base = (FT_UShort)args[0]; + } - for ( K = 1; K <= L; K++ ) - args[K - 1] = CUR.code[CUR.IP + K + 1]; - CUR.new_top += L; + /*************************************************************************/ + /* */ + /* SDS[]: Set Delta Shift */ + /* Opcode range: 0x5F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDS( TT_ExecContext exc, + FT_Long* args ) + { + if ( (FT_ULong)args[0] > 6UL ) + exc->error = FT_THROW( Bad_Argument ); + else + exc->GS.delta_shift = (FT_UShort)args[0]; } /*************************************************************************/ /* */ - /* NPUSHW[]: PUSH N Words */ - /* Opcode range: 0x41 */ - /* Stack: --> int32... */ + /* RTHG[]: Round To Half Grid */ + /* Opcode range: 0x19 */ + /* Stack: --> */ /* */ static void - Ins_NPUSHW( INS_ARG ) + Ins_RTHG( TT_ExecContext exc ) { - FT_UShort L, K; + exc->GS.round_state = TT_Round_To_Half_Grid; + exc->func_round = (TT_Round_Func)Round_To_Half_Grid; + } - L = (FT_UShort)CUR.code[CUR.IP + 1]; + /*************************************************************************/ + /* */ + /* RTG[]: Round To Grid */ + /* Opcode range: 0x18 */ + /* Stack: --> */ + /* */ + static void + Ins_RTG( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_To_Grid; + exc->func_round = (TT_Round_Func)Round_To_Grid; + } - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - CUR.IP += 2; + /*************************************************************************/ + /* RTDG[]: Round To Double Grid */ + /* Opcode range: 0x3D */ + /* Stack: --> */ + /* */ + static void + Ins_RTDG( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_To_Double_Grid; + exc->func_round = (TT_Round_Func)Round_To_Double_Grid; + } - for ( K = 0; K < L; K++ ) - args[K] = GET_ShortIns(); - CUR.step_ins = FALSE; - CUR.new_top += L; + /*************************************************************************/ + /* RUTG[]: Round Up To Grid */ + /* Opcode range: 0x7C */ + /* Stack: --> */ + /* */ + static void + Ins_RUTG( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_Up_To_Grid; + exc->func_round = (TT_Round_Func)Round_Up_To_Grid; } /*************************************************************************/ /* */ - /* PUSHB[abc]: PUSH Bytes */ - /* Opcode range: 0xB0-0xB7 */ - /* Stack: --> uint32... */ + /* RDTG[]: Round Down To Grid */ + /* Opcode range: 0x7D */ + /* Stack: --> */ /* */ static void - Ins_PUSHB( INS_ARG ) + Ins_RDTG( TT_ExecContext exc ) { - FT_UShort L, K; - - - L = (FT_UShort)( CUR.opcode - 0xB0 + 1 ); + exc->GS.round_state = TT_Round_Down_To_Grid; + exc->func_round = (TT_Round_Func)Round_Down_To_Grid; + } - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - for ( K = 1; K <= L; K++ ) - args[K - 1] = CUR.code[CUR.IP + K]; + /*************************************************************************/ + /* */ + /* ROFF[]: Round OFF */ + /* Opcode range: 0x7A */ + /* Stack: --> */ + /* */ + static void + Ins_ROFF( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_Off; + exc->func_round = (TT_Round_Func)Round_None; } /*************************************************************************/ /* */ - /* PUSHW[abc]: PUSH Words */ - /* Opcode range: 0xB8-0xBF */ - /* Stack: --> int32... */ + /* SROUND[]: Super ROUND */ + /* Opcode range: 0x76 */ + /* Stack: Eint8 --> */ /* */ static void - Ins_PUSHW( INS_ARG ) + Ins_SROUND( TT_ExecContext exc, + FT_Long* args ) { - FT_UShort L, K; - - - L = (FT_UShort)( CUR.opcode - 0xB8 + 1 ); - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = FT_THROW( Stack_Overflow ); - return; - } - - CUR.IP++; + SetSuperRound( exc, 0x4000, args[0] ); - for ( K = 0; K < L; K++ ) - args[K] = GET_ShortIns(); - - CUR.step_ins = FALSE; + exc->GS.round_state = TT_Round_Super; + exc->func_round = (TT_Round_Func)Round_Super; } /*************************************************************************/ /* */ - /* MANAGING THE GRAPHICS STATE */ - /* */ - /* Instructions appear in the specs' order. */ + /* S45ROUND[]: Super ROUND 45 degrees */ + /* Opcode range: 0x77 */ + /* Stack: uint32 --> */ /* */ - /*************************************************************************/ + static void + Ins_S45ROUND( TT_ExecContext exc, + FT_Long* args ) + { + SetSuperRound( exc, 0x2D41, args[0] ); + + exc->GS.round_state = TT_Round_Super_45; + exc->func_round = (TT_Round_Func)Round_Super_45; + } /*************************************************************************/ @@ -5189,7 +4664,8 @@ /* along the dual projection vector! */ /* */ static void - Ins_GC( INS_ARG ) + Ins_GC( TT_ExecContext exc, + FT_Long* args ) { FT_ULong L; FT_F26Dot6 R; @@ -5197,18 +4673,18 @@ L = (FT_ULong)args[0]; - if ( BOUNDSL( L, CUR.zp2.n_points ) ) + if ( BOUNDSL( L, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); R = 0; } else { - if ( CUR.opcode & 1 ) - R = CUR_fast_dualproj( &CUR.zp2.org[L] ); + if ( exc->opcode & 1 ) + R = FAST_DUALPROJ( &exc->zp2.org[L] ); else - R = CUR_fast_project( &CUR.zp2.cur[L] ); + R = FAST_PROJECT( &exc->zp2.cur[L] ); } args[0] = R; @@ -5226,7 +4702,8 @@ /* OA := OA + ( value - OA.p )/( f.p ) * f */ /* */ static void - Ins_SCFS( INS_ARG ) + Ins_SCFS( TT_ExecContext exc, + FT_Long* args ) { FT_Long K; FT_UShort L; @@ -5234,21 +4711,21 @@ L = (FT_UShort)args[0]; - if ( BOUNDS( L, CUR.zp2.n_points ) ) + if ( BOUNDS( L, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - K = CUR_fast_project( &CUR.zp2.cur[L] ); + K = FAST_PROJECT( &exc->zp2.cur[L] ); - CUR_Func_move( &CUR.zp2, L, args[1] - K ); + exc->func_move( exc, &exc->zp2, L, args[1] - K ); /* UNDOCUMENTED! The MS rasterizer does that with */ /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep2 == 0 ) - CUR.zp2.org[L] = CUR.zp2.cur[L]; + if ( exc->GS.gep2 == 0 ) + exc->zp2.org[L] = exc->zp2.cur[L]; } @@ -5268,7 +4745,8 @@ /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */ /* */ static void - Ins_MD( INS_ARG ) + Ins_MD( TT_ExecContext exc, + FT_Long* args ) { FT_UShort K, L; FT_F26Dot6 D; @@ -5277,61 +4755,62 @@ K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; - if ( BOUNDS( L, CUR.zp0.n_points ) || - BOUNDS( K, CUR.zp1.n_points ) ) + if ( BOUNDS( L, exc->zp0.n_points ) || + BOUNDS( K, exc->zp1.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); D = 0; } else { - if ( CUR.opcode & 1 ) - D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); + if ( exc->opcode & 1 ) + D = PROJECT( exc->zp0.cur + L, exc->zp1.cur + K ); else { /* XXX: UNDOCUMENTED: twilight zone special case */ - if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 ) { - FT_Vector* vec1 = CUR.zp0.org + L; - FT_Vector* vec2 = CUR.zp1.org + K; + FT_Vector* vec1 = exc->zp0.org + L; + FT_Vector* vec2 = exc->zp1.org + K; - D = CUR_Func_dualproj( vec1, vec2 ); + D = DUALPROJ( vec1, vec2 ); } else { - FT_Vector* vec1 = CUR.zp0.orus + L; - FT_Vector* vec2 = CUR.zp1.orus + K; + FT_Vector* vec1 = exc->zp0.orus + L; + FT_Vector* vec2 = exc->zp1.orus + K; - if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + if ( exc->metrics.x_scale == exc->metrics.y_scale ) { /* this should be faster */ - D = CUR_Func_dualproj( vec1, vec2 ); - D = FT_MulFix( D, CUR.metrics.x_scale ); + D = DUALPROJ( vec1, vec2 ); + D = FT_MulFix( D, exc->metrics.x_scale ); } else { FT_Vector vec; - vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); - vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); + vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale ); + vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale ); - D = CUR_fast_dualproj( &vec ); + D = FAST_DUALPROJ( &vec ); } } } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && FT_ABS( D ) == 64 ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + FT_ABS( D ) == 64 ) D += 1; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = D; } @@ -5339,61 +4818,63 @@ /*************************************************************************/ /* */ - /* SDPVTL[a]: Set Dual PVector to Line */ + /* SDPvTL[a]: Set Dual PVector to Line */ /* Opcode range: 0x86-0x87 */ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_SDPVTL( INS_ARG ) + Ins_SDPVTL( TT_ExecContext exc, + FT_Long* args ) { FT_Long A, B, C; FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ - FT_Int aOpc = CUR.opcode; + + FT_Byte opcode = exc->opcode; p1 = (FT_UShort)args[1]; p2 = (FT_UShort)args[0]; - if ( BOUNDS( p2, CUR.zp1.n_points ) || - BOUNDS( p1, CUR.zp2.n_points ) ) + if ( BOUNDS( p2, exc->zp1.n_points ) || + BOUNDS( p1, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } { - FT_Vector* v1 = CUR.zp1.org + p2; - FT_Vector* v2 = CUR.zp2.org + p1; + FT_Vector* v1 = exc->zp1.org + p2; + FT_Vector* v2 = exc->zp2.org + p1; A = v1->x - v2->x; B = v1->y - v2->y; - /* If v1 == v2, SDPVTL behaves the same as */ + /* If v1 == v2, SDPvTL behaves the same as */ /* SVTCA[X], respectively. */ /* */ /* Confirmed by Greg Hitchcock. */ if ( A == 0 && B == 0 ) { - A = 0x4000; - aOpc = 0; + A = 0x4000; + opcode = 0; } } - if ( ( aOpc & 1 ) != 0 ) + if ( ( opcode & 1 ) != 0 ) { C = B; /* counter clockwise rotation */ B = A; A = -C; } - NORMalize( A, B, &CUR.GS.dualVector ); + Normalize( A, B, &exc->GS.dualVector ); { - FT_Vector* v1 = CUR.zp1.cur + p2; - FT_Vector* v2 = CUR.zp2.cur + p1; + FT_Vector* v1 = exc->zp1.cur + p2; + FT_Vector* v2 = exc->zp2.cur + p1; A = v1->x - v2->x; @@ -5401,23 +4882,20 @@ if ( A == 0 && B == 0 ) { - A = 0x4000; - aOpc = 0; + A = 0x4000; + opcode = 0; } } - if ( ( aOpc & 1 ) != 0 ) + if ( ( opcode & 1 ) != 0 ) { C = B; /* counter clockwise rotation */ B = A; A = -C; } - NORMalize( A, B, &CUR.GS.projVector ); - - GUESS_VECTOR( freeVector ); - - COMPUTE_Funcs(); + Normalize( A, B, &exc->GS.projVector ); + Compute_Funcs( exc ); } @@ -5428,25 +4906,26 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SZP0( INS_ARG ) + Ins_SZP0( TT_ExecContext exc, + FT_Long* args ) { switch ( (FT_Int)args[0] ) { case 0: - CUR.zp0 = CUR.twilight; + exc->zp0 = exc->twilight; break; case 1: - CUR.zp0 = CUR.pts; + exc->zp0 = exc->pts; break; default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - CUR.GS.gep0 = (FT_UShort)args[0]; + exc->GS.gep0 = (FT_UShort)args[0]; } @@ -5457,25 +4936,26 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SZP1( INS_ARG ) + Ins_SZP1( TT_ExecContext exc, + FT_Long* args ) { switch ( (FT_Int)args[0] ) { case 0: - CUR.zp1 = CUR.twilight; + exc->zp1 = exc->twilight; break; case 1: - CUR.zp1 = CUR.pts; + exc->zp1 = exc->pts; break; default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - CUR.GS.gep1 = (FT_UShort)args[0]; + exc->GS.gep1 = (FT_UShort)args[0]; } @@ -5486,25 +4966,26 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SZP2( INS_ARG ) + Ins_SZP2( TT_ExecContext exc, + FT_Long* args ) { switch ( (FT_Int)args[0] ) { case 0: - CUR.zp2 = CUR.twilight; + exc->zp2 = exc->twilight; break; case 1: - CUR.zp2 = CUR.pts; + exc->zp2 = exc->pts; break; default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - CUR.GS.gep2 = (FT_UShort)args[0]; + exc->GS.gep2 = (FT_UShort)args[0]; } @@ -5515,60 +4996,93 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SZPS( INS_ARG ) + Ins_SZPS( TT_ExecContext exc, + FT_Long* args ) { switch ( (FT_Int)args[0] ) { case 0: - CUR.zp0 = CUR.twilight; + exc->zp0 = exc->twilight; break; case 1: - CUR.zp0 = CUR.pts; + exc->zp0 = exc->pts; break; default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - CUR.zp1 = CUR.zp0; - CUR.zp2 = CUR.zp0; + exc->zp1 = exc->zp0; + exc->zp2 = exc->zp0; - CUR.GS.gep0 = (FT_UShort)args[0]; - CUR.GS.gep1 = (FT_UShort)args[0]; - CUR.GS.gep2 = (FT_UShort)args[0]; + exc->GS.gep0 = (FT_UShort)args[0]; + exc->GS.gep1 = (FT_UShort)args[0]; + exc->GS.gep2 = (FT_UShort)args[0]; } /*************************************************************************/ /* */ /* INSTCTRL[]: INSTruction ConTRoL */ - /* Opcode range: 0x8e */ + /* Opcode range: 0x8E */ /* Stack: int32 int32 --> */ /* */ static void - Ins_INSTCTRL( INS_ARG ) + Ins_INSTCTRL( TT_ExecContext exc, + FT_Long* args ) { - FT_Long K, L; + FT_ULong K, L, Kf; - K = args[1]; - L = args[0]; + K = (FT_ULong)args[1]; + L = (FT_ULong)args[0]; - if ( K < 1 || K > 2 ) + /* selector values cannot be `OR'ed; */ + /* they are indices starting with index 1, not flags */ + if ( K < 1 || K > 3 ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } + /* convert index to flag value */ + Kf = 1 << ( K - 1 ); + if ( L != 0 ) - L = K; + { + /* arguments to selectors look like flag values */ + if ( L != Kf ) + { + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); + return; + } + } + + exc->GS.instruct_control &= ~(FT_Byte)Kf; + exc->GS.instruct_control |= (FT_Byte)L; - CUR.GS.instruct_control = FT_BOOL( - ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); + if ( K == 3 ) + { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* INSTCTRL modifying flag 3 also has an effect */ + /* outside of the CVT program */ + if ( SUBPIXEL_HINTING_INFINALITY ) + exc->ignore_x_mode = FT_BOOL( L == 4 ); +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Native ClearType fonts sign a waiver that turns off all backwards */ + /* compatibility hacks and lets them program points to the grid like */ + /* it's 1996. They might sign a waiver for just one glyph, though. */ + if ( SUBPIXEL_HINTING_MINIMAL ) + exc->backwards_compatibility = !FT_BOOL( L == 4 ); +#endif + } } @@ -5579,7 +5093,8 @@ /* Stack: uint32? --> */ /* */ static void - Ins_SCANCTRL( INS_ARG ) + Ins_SCANCTRL( TT_ExecContext exc, + FT_Long* args ) { FT_Int A; @@ -5589,32 +5104,32 @@ if ( A == 0xFF ) { - CUR.GS.scan_control = TRUE; + exc->GS.scan_control = TRUE; return; } else if ( A == 0 ) { - CUR.GS.scan_control = FALSE; + exc->GS.scan_control = FALSE; return; } - if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A ) - CUR.GS.scan_control = TRUE; + if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A ) + exc->GS.scan_control = TRUE; - if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = TRUE; + if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated ) + exc->GS.scan_control = TRUE; - if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = TRUE; + if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched ) + exc->GS.scan_control = TRUE; - if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A ) - CUR.GS.scan_control = FALSE; + if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A ) + exc->GS.scan_control = FALSE; - if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = FALSE; + if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated ) + exc->GS.scan_control = FALSE; - if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = FALSE; + if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched ) + exc->GS.scan_control = FALSE; } @@ -5625,10 +5140,11 @@ /* Stack: uint32? --> */ /* */ static void - Ins_SCANTYPE( INS_ARG ) + Ins_SCANTYPE( TT_ExecContext exc, + FT_Long* args ) { if ( args[0] >= 0 ) - CUR.GS.scan_type = (FT_Int)args[0]; + exc->GS.scan_type = (FT_Int)args[0]; } @@ -5636,8 +5152,6 @@ /* */ /* MANAGING OUTLINES */ /* */ - /* Instructions appear in the specification's order. */ - /* */ /*************************************************************************/ @@ -5648,43 +5162,50 @@ /* Stack: uint32... --> */ /* */ static void - Ins_FLIPPT( INS_ARG ) + Ins_FLIPPT( TT_ExecContext exc ) { FT_UShort point; - FT_UNUSED_ARG; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + goto Fail; +#endif - if ( CUR.top < CUR.GS.loop ) + if ( exc->top < exc->GS.loop ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Too_Few_Arguments ); goto Fail; } - while ( CUR.GS.loop > 0 ) + while ( exc->GS.loop > 0 ) { - CUR.args--; + exc->args--; - point = (FT_UShort)CUR.stack[CUR.args]; + point = (FT_UShort)exc->stack[exc->args]; - if ( BOUNDS( point, CUR.pts.n_points ) ) + if ( BOUNDS( point, exc->pts.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } else - CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; + exc->pts.tags[point] ^= FT_CURVE_TAG_ON; - CUR.GS.loop--; + exc->GS.loop--; } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -5695,24 +5216,34 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_FLIPRGON( INS_ARG ) + Ins_FLIPRGON( TT_ExecContext exc, + FT_Long* args ) { FT_UShort I, K, L; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + return; +#endif + K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; - if ( BOUNDS( K, CUR.pts.n_points ) || - BOUNDS( L, CUR.pts.n_points ) ) + if ( BOUNDS( K, exc->pts.n_points ) || + BOUNDS( L, exc->pts.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } for ( I = L; I <= K; I++ ) - CUR.pts.tags[I] |= FT_CURVE_TAG_ON; + exc->pts.tags[I] |= FT_CURVE_TAG_ON; } @@ -5723,53 +5254,64 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_FLIPRGOFF( INS_ARG ) + Ins_FLIPRGOFF( TT_ExecContext exc, + FT_Long* args ) { FT_UShort I, K, L; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + return; +#endif + K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; - if ( BOUNDS( K, CUR.pts.n_points ) || - BOUNDS( L, CUR.pts.n_points ) ) + if ( BOUNDS( K, exc->pts.n_points ) || + BOUNDS( L, exc->pts.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } for ( I = L; I <= K; I++ ) - CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; + exc->pts.tags[I] &= ~FT_CURVE_TAG_ON; } static FT_Bool - Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, - FT_F26Dot6* y, - TT_GlyphZone zone, - FT_UShort* refp ) + Compute_Point_Displacement( TT_ExecContext exc, + FT_F26Dot6* x, + FT_F26Dot6* y, + TT_GlyphZone zone, + FT_UShort* refp ) { TT_GlyphZoneRec zp; FT_UShort p; FT_F26Dot6 d; - if ( CUR.opcode & 1 ) + if ( exc->opcode & 1 ) { - zp = CUR.zp0; - p = CUR.GS.rp1; + zp = exc->zp0; + p = exc->GS.rp1; } else { - zp = CUR.zp1; - p = CUR.GS.rp2; + zp = exc->zp1; + p = exc->GS.rp2; } if ( BOUNDS( p, zp.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); *refp = 0; return FAILURE; } @@ -5777,70 +5319,47 @@ *zone = zp; *refp = p; - d = CUR_Func_project( zp.cur + p, zp.org + p ); + d = PROJECT( zp.cur + p, zp.org + p ); -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - { - *x = d; - *y = 0; - } - else - { - *x = 0; - *y = d; - } - } - else -#endif - { - *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P ); - *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P ); - } + *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P ); + *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P ); return SUCCESS; } + /* See `ttinterp.h' for details on backwards compatibility mode. */ static void - Move_Zp2_Point( EXEC_OP_ FT_UShort point, - FT_F26Dot6 dx, - FT_F26Dot6 dy, - FT_Bool touch ) + Move_Zp2_Point( TT_ExecContext exc, + FT_UShort point, + FT_F26Dot6 dx, + FT_F26Dot6 dy, + FT_Bool touch ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) + if ( exc->GS.freeVector.x != 0 ) { - if ( CUR.GS.both_x_axis ) - { - CUR.zp2.cur[point].x += dx; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; - } - else - { - CUR.zp2.cur[point].y += dy; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; - } - return; - } +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) ) #endif + exc->zp2.cur[point].x += dx; - if ( CUR.GS.freeVector.x != 0 ) - { - CUR.zp2.cur[point].x += dx; if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; } - if ( CUR.GS.freeVector.y != 0 ) + if ( exc->GS.freeVector.y != 0 ) { - CUR.zp2.cur[point].y += dy; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) ) +#endif + exc->zp2.cur[point].y += dy; + if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } @@ -5852,57 +5371,53 @@ /* Stack: uint32... --> */ /* */ static void - Ins_SHP( INS_ARG ) + Ins_SHP( TT_ExecContext exc ) { TT_GlyphZoneRec zp; FT_UShort refp; - FT_F26Dot6 dx, - dy; + FT_F26Dot6 dx, dy; FT_UShort point; - FT_UNUSED_ARG; - - if ( CUR.top < CUR.GS.loop ) + if ( exc->top < exc->GS.loop ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) ) return; - while ( CUR.GS.loop > 0 ) + while ( exc->GS.loop > 0 ) { - CUR.args--; - point = (FT_UShort)CUR.stack[CUR.args]; + exc->args--; + point = (FT_UShort)exc->stack[exc->args]; - if ( BOUNDS( point, CUR.zp2.n_points ) ) + if ( BOUNDS( point, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* doesn't follow Cleartype spec but produces better result */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) - MOVE_Zp2_Point( point, 0, dy, TRUE ); + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode ) + Move_Zp2_Point( exc, point, 0, dy, TRUE ); else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - MOVE_Zp2_Point( point, dx, dy, TRUE ); +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + Move_Zp2_Point( exc, point, dx, dy, TRUE ); - CUR.GS.loop--; + exc->GS.loop--; } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -5917,7 +5432,8 @@ /* zero which includes all points of it. */ /* */ static void - Ins_SHC( INS_ARG ) + Ins_SHC( TT_ExecContext exc, + FT_Long* args ) { TT_GlyphZoneRec zp; FT_UShort refp; @@ -5927,36 +5443,36 @@ FT_UShort start, limit, i; - contour = (FT_UShort)args[0]; - bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours; + contour = (FT_Short)args[0]; + bounds = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours; if ( BOUNDS( contour, bounds ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) ) return; if ( contour == 0 ) start = 0; else - start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 - - CUR.zp2.first_point ); + start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 - + exc->zp2.first_point ); /* we use the number of points if in the twilight zone */ - if ( CUR.GS.gep2 == 0 ) - limit = CUR.zp2.n_points; + if ( exc->GS.gep2 == 0 ) + limit = exc->zp2.n_points; else - limit = (FT_UShort)( CUR.zp2.contours[contour] - - CUR.zp2.first_point + 1 ); + limit = (FT_UShort)( exc->zp2.contours[contour] - + exc->zp2.first_point + 1 ); for ( i = start; i < limit; i++ ) { - if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, TRUE ); + if ( zp.cur != exc->zp2.cur || refp != i ) + Move_Zp2_Point( exc, i, dx, dy, TRUE ); } } @@ -5968,7 +5484,8 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SHZ( INS_ARG ) + Ins_SHZ( TT_ExecContext exc, + FT_Long* args ) { TT_GlyphZoneRec zp; FT_UShort refp; @@ -5980,30 +5497,30 @@ if ( BOUNDS( args[0], 2 ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) ) return; /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ /* Twilight zone has no real contours, so use `n_points'. */ /* Normal zone's `n_points' includes phantoms, so must */ /* use end of last contour. */ - if ( CUR.GS.gep2 == 0 ) - limit = (FT_UShort)CUR.zp2.n_points; - else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) - limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 ); + if ( exc->GS.gep2 == 0 ) + limit = (FT_UShort)exc->zp2.n_points; + else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 ) + limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 ); else limit = 0; /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ for ( i = 0; i < limit; i++ ) { - if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, FALSE ); + if ( zp.cur != exc->zp2.cur || refp != i ) + Move_Zp2_Point( exc, i, dx, dy, FALSE ); } } @@ -6015,148 +5532,152 @@ /* Stack: f26.6 uint32... --> */ /* */ static void - Ins_SHPIX( INS_ARG ) + Ins_SHPIX( TT_ExecContext exc, + FT_Long* args ) { FT_F26Dot6 dx, dy; FT_UShort point; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Int B1, B2; #endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + FT_Bool in_twilight = exc->GS.gep0 == 0 || \ + exc->GS.gep1 == 0 || \ + exc->GS.gep2 == 0; +#endif - if ( CUR.top < CUR.GS.loop + 1 ) + + if ( exc->top < exc->GS.loop + 1 ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - { - dx = (FT_UInt32)args[0]; - dy = 0; - } - else - { - dx = 0; - dy = (FT_UInt32)args[0]; - } - } - else -#endif - { - dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); - dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); - } + dx = TT_MulFix14( args[0], exc->GS.freeVector.x ); + dy = TT_MulFix14( args[0], exc->GS.freeVector.y ); - while ( CUR.GS.loop > 0 ) + while ( exc->GS.loop > 0 ) { - CUR.args--; + exc->args--; - point = (FT_UShort)CUR.stack[CUR.args]; + point = (FT_UShort)exc->stack[exc->args]; - if ( BOUNDS( point, CUR.zp2.n_points ) ) + if ( BOUNDS( point, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { - /* If not using ignore_x_mode rendering, allow ZP2 move. */ - /* If inline deltas aren't allowed, skip ZP2 move. */ - /* If using ignore_x_mode rendering, allow ZP2 point move if: */ - /* - freedom vector is y and sph_compatibility_mode is off */ - /* - the glyph is composite and the move is in the Y direction */ - /* - the glyph is specifically set to allow SHPIX moves */ - /* - the move is on a previously Y-touched point */ - - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) + /* If not using ignore_x_mode rendering, allow ZP2 move. */ + /* If inline deltas aren't allowed, skip ZP2 move. */ + /* If using ignore_x_mode rendering, allow ZP2 point move if: */ + /* - freedom vector is y and sph_compatibility_mode is off */ + /* - the glyph is composite and the move is in the Y direction */ + /* - the glyph is specifically set to allow SHPIX moves */ + /* - the move is on a previously Y-touched point */ + + if ( exc->ignore_x_mode ) { /* save point for later comparison */ - if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp2.cur[point].y; + if ( exc->GS.freeVector.y != 0 ) + B1 = exc->zp2.cur[point].y; else - B1 = CUR.zp2.cur[point].x; + B1 = exc->zp2.cur[point].x; - if ( !CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 ) + if ( !exc->face->sph_compatibility_mode && + exc->GS.freeVector.y != 0 ) { - MOVE_Zp2_Point( point, dx, dy, TRUE ); + Move_Zp2_Point( exc, point, dx, dy, TRUE ); /* save new point */ - if ( CUR.GS.freeVector.y != 0 ) + if ( exc->GS.freeVector.y != 0 ) { - B2 = CUR.zp2.cur[point].y; + B2 = exc->zp2.cur[point].y; /* reverse any disallowed moves */ - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - ( B1 & 63 ) != 0 && - ( B2 & 63 ) != 0 && - B1 != B2 ) - MOVE_Zp2_Point( point, -dx, -dy, TRUE ); + if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && + ( B1 & 63 ) != 0 && + ( B2 & 63 ) != 0 && + B1 != B2 ) + Move_Zp2_Point( exc, point, -dx, -dy, TRUE ); } } - else if ( CUR.face->sph_compatibility_mode ) + else if ( exc->face->sph_compatibility_mode ) { - if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) + if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) { dx = FT_PIX_ROUND( B1 + dx ) - B1; dy = FT_PIX_ROUND( B1 + dy ) - B1; } /* skip post-iup deltas */ - if ( CUR.iup_called && - ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || - ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) + if ( exc->iup_called && + ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || + ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) goto Skip; - if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && - ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || - ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || - ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) - MOVE_Zp2_Point( point, 0, dy, TRUE ); + if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || + ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) + Move_Zp2_Point( exc, point, 0, dy, TRUE ); /* save new point */ - if ( CUR.GS.freeVector.y != 0 ) + if ( exc->GS.freeVector.y != 0 ) { - B2 = CUR.zp2.cur[point].y; + B2 = exc->zp2.cur[point].y; /* reverse any disallowed moves */ if ( ( B1 & 63 ) == 0 && ( B2 & 63 ) != 0 && B1 != B2 ) - MOVE_Zp2_Point( point, 0, -dy, TRUE ); + Move_Zp2_Point( exc, point, 0, -dy, TRUE ); } } - else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) - MOVE_Zp2_Point( point, dx, dy, TRUE ); + else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) + Move_Zp2_Point( exc, point, dx, dy, TRUE ); } else - MOVE_Zp2_Point( point, dx, dy, TRUE ); + Move_Zp2_Point( exc, point, dx, dy, TRUE ); } + else +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + /* Special case: allow SHPIX to move points in the twilight zone. */ + /* Otherwise, treat SHPIX the same as DELTAP. Unbreaks various */ + /* fonts such as older versions of Rokkitt and DTL Argo T Light */ + /* that would glitch severly after calling ALIGNRP after a blocked */ + /* SHPIX. */ + if ( in_twilight || + ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ) ) ) + Move_Zp2_Point( exc, point, 0, dy, TRUE ); + } + else +#endif + Move_Zp2_Point( exc, point, dx, dy, TRUE ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY Skip: - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - MOVE_Zp2_Point( point, dx, dy, TRUE ); - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - CUR.GS.loop--; +#endif + exc->GS.loop--; } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -6167,65 +5688,63 @@ /* Stack: f26.6 uint32 --> */ /* */ static void - Ins_MSIRP( INS_ARG ) + Ins_MSIRP( TT_ExecContext exc, + FT_Long* args ) { - FT_UShort point; + FT_UShort point = 0; FT_F26Dot6 distance; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + FT_F26Dot6 control_value_cutin = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */ - - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { - control_value_cutin = CUR.GS.control_value_cutin; + control_value_cutin = exc->GS.control_value_cutin; - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) + if ( exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ point = (FT_UShort)args[0]; - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp1.n_points ) || + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } /* UNDOCUMENTED! The MS rasterizer does that with */ /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep1 == 0 ) + if ( exc->GS.gep1 == 0 ) { - CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; - CUR_Func_move_orig( &CUR.zp1, point, args[1] ); - CUR.zp1.cur[point] = CUR.zp1.org[point]; + exc->zp1.org[point] = exc->zp0.org[exc->GS.rp0]; + exc->func_move_orig( exc, &exc->zp1, point, args[1] ); + exc->zp1.cur[point] = exc->zp1.org[point]; } - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); + distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && FT_ABS( distance - args[1] ) >= control_value_cutin ) distance = args[1]; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - CUR_Func_move( &CUR.zp1, point, args[1] - distance ); + exc->func_move( exc, &exc->zp1, point, args[1] - distance ); - CUR.GS.rp1 = CUR.GS.rp0; - CUR.GS.rp2 = point; + exc->GS.rp1 = exc->GS.rp0; + exc->GS.rp2 = point; - if ( ( CUR.opcode & 1 ) != 0 ) - CUR.GS.rp0 = point; + if ( ( exc->opcode & 1 ) != 0 ) + exc->GS.rp0 = point; } @@ -6236,7 +5755,8 @@ /* Stack: uint32 --> */ /* */ static void - Ins_MDAP( INS_ARG ) + Ins_MDAP( TT_ExecContext exc, + FT_Long* args ) { FT_UShort point; FT_F26Dot6 cur_dist; @@ -6245,36 +5765,38 @@ point = (FT_UShort)args[0]; - if ( BOUNDS( point, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - if ( ( CUR.opcode & 1 ) != 0 ) + if ( ( exc->opcode & 1 ) != 0 ) { - cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( + cur_dist = FAST_PROJECT( &exc->zp0.cur[point] ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) + distance = Round_None( + exc, cur_dist, - CUR.tt_metrics.compensations[0] ) - cur_dist; + exc->tt_metrics.compensations[0] ) - cur_dist; else #endif - distance = CUR_Func_round( + distance = exc->func_round( + exc, cur_dist, - CUR.tt_metrics.compensations[0] ) - cur_dist; + exc->tt_metrics.compensations[0] ) - cur_dist; } else distance = 0; - CUR_Func_move( &CUR.zp0, point, distance ); + exc->func_move( exc, &exc->zp0, point, distance ); - CUR.GS.rp0 = point; - CUR.GS.rp1 = point; + exc->GS.rp0 = point; + exc->GS.rp1 = point; } @@ -6285,7 +5807,8 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_MIAP( INS_ARG ) + Ins_MIAP( TT_ExecContext exc, + FT_Long* args ) { FT_ULong cvtEntry; FT_UShort point; @@ -6294,24 +5817,24 @@ FT_F26Dot6 control_value_cutin; - control_value_cutin = CUR.GS.control_value_cutin; + control_value_cutin = exc->GS.control_value_cutin; cvtEntry = (FT_ULong)args[1]; point = (FT_UShort)args[0]; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - CUR.GS.freeVector.y == 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + exc->GS.freeVector.y == 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( BOUNDS( point, CUR.zp0.n_points ) || - BOUNDSL( cvtEntry, CUR.cvtSize ) ) + if ( BOUNDS( point, exc->zp0.n_points ) || + BOUNDSL( cvtEntry, exc->cvtSize ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } @@ -6335,56 +5858,58 @@ /* */ /* Confirmed by Greg Hitchcock. */ - distance = CUR_Func_read_cvt( cvtEntry ); + distance = exc->func_read_cvt( exc, cvtEntry ); - if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ + if ( exc->GS.gep0 == 0 ) /* If in twilight zone */ { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ /* Determined via experimentation and may be incorrect... */ - if ( !SUBPIXEL_HINTING || - ( !CUR.ignore_x_mode || - !CUR.face->sph_compatibility_mode ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, - CUR.GS.freeVector.x ); - CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, - CUR.GS.freeVector.y ), - CUR.zp0.cur[point] = CUR.zp0.org[point]; - } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && - distance > 0 && - CUR.GS.freeVector.y != 0 ) + if ( !( SUBPIXEL_HINTING_INFINALITY && + ( exc->ignore_x_mode && + exc->face->sph_compatibility_mode ) ) ) +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + exc->zp0.org[point].x = TT_MulFix14( distance, + exc->GS.freeVector.x ); + exc->zp0.org[point].y = TT_MulFix14( distance, + exc->GS.freeVector.y ), + exc->zp0.cur[point] = exc->zp0.org[point]; + } +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && + distance > 0 && + exc->GS.freeVector.y != 0 ) distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); + org_dist = FAST_PROJECT( &exc->zp0.cur[point] ); - if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ + if ( ( exc->opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ { if ( FT_ABS( distance - org_dist ) > control_value_cutin ) distance = org_dist; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( distance, - CUR.tt_metrics.compensations[0] ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) + distance = Round_None( exc, + distance, + exc->tt_metrics.compensations[0] ); else #endif - distance = CUR_Func_round( distance, - CUR.tt_metrics.compensations[0] ); + distance = exc->func_round( exc, + distance, + exc->tt_metrics.compensations[0] ); } - CUR_Func_move( &CUR.zp0, point, distance - org_dist ); + exc->func_move( exc, &exc->zp0, point, distance - org_dist ); Fail: - CUR.GS.rp0 = point; - CUR.GS.rp1 = point; + exc->GS.rp0 = point; + exc->GS.rp1 = point; } @@ -6395,29 +5920,30 @@ /* Stack: uint32 --> */ /* */ static void - Ins_MDRP( INS_ARG ) + Ins_MDRP( TT_ExecContext exc, + FT_Long* args ) { - FT_UShort point; + FT_UShort point = 0; FT_F26Dot6 org_dist, distance, minimum_distance; - minimum_distance = CUR.GS.minimum_distance; + minimum_distance = exc->GS.minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ point = (FT_UShort)args[0]; - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp1.n_points ) || + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } @@ -6426,74 +5952,77 @@ /* XXX: UNDOCUMENTED: twilight zone special case */ - if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 ) { - FT_Vector* vec1 = &CUR.zp1.org[point]; - FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0]; + FT_Vector* vec1 = &exc->zp1.org[point]; + FT_Vector* vec2 = &exc->zp0.org[exc->GS.rp0]; - org_dist = CUR_Func_dualproj( vec1, vec2 ); + org_dist = DUALPROJ( vec1, vec2 ); } else { - FT_Vector* vec1 = &CUR.zp1.orus[point]; - FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0]; + FT_Vector* vec1 = &exc->zp1.orus[point]; + FT_Vector* vec2 = &exc->zp0.orus[exc->GS.rp0]; - if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + if ( exc->metrics.x_scale == exc->metrics.y_scale ) { /* this should be faster */ - org_dist = CUR_Func_dualproj( vec1, vec2 ); - org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale ); + org_dist = DUALPROJ( vec1, vec2 ); + org_dist = FT_MulFix( org_dist, exc->metrics.x_scale ); } else { FT_Vector vec; - vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); - vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); + vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale ); + vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale ); - org_dist = CUR_fast_dualproj( &vec ); + org_dist = FAST_DUALPROJ( &vec ); } } /* single width cut-in test */ - if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < - CUR.GS.single_width_cutin ) + if ( FT_ABS( org_dist - exc->GS.single_width_value ) < + exc->GS.single_width_cutin ) { if ( org_dist >= 0 ) - org_dist = CUR.GS.single_width_value; + org_dist = exc->GS.single_width_value; else - org_dist = -CUR.GS.single_width_value; + org_dist = -exc->GS.single_width_value; } /* round flag */ - if ( ( CUR.opcode & 4 ) != 0 ) + if ( ( exc->opcode & 4 ) != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) + distance = Round_None( + exc, org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + exc->tt_metrics.compensations[exc->opcode & 3] ); else #endif - distance = CUR_Func_round( - org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + distance = exc->func_round( + exc, + org_dist, + exc->tt_metrics.compensations[exc->opcode & 3] ); } else - distance = ROUND_None( + distance = Round_None( + exc, org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + exc->tt_metrics.compensations[exc->opcode & 3] ); /* minimum distance flag */ - if ( ( CUR.opcode & 8 ) != 0 ) + if ( ( exc->opcode & 8 ) != 0 ) { if ( org_dist >= 0 ) { @@ -6509,17 +6038,16 @@ /* now move the point */ - org_dist = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); + org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); - CUR_Func_move( &CUR.zp1, point, distance - org_dist ); + exc->func_move( exc, &exc->zp1, point, distance - org_dist ); Fail: - CUR.GS.rp1 = CUR.GS.rp0; - CUR.GS.rp2 = point; + exc->GS.rp1 = exc->GS.rp0; + exc->GS.rp2 = point; - if ( ( CUR.opcode & 16 ) != 0 ) - CUR.GS.rp0 = point; + if ( ( exc->opcode & 16 ) != 0 ) + exc->GS.rp0 = point; } @@ -6530,7 +6058,8 @@ /* Stack: int32? uint32 --> */ /* */ static void - Ins_MIRP( INS_ARG ) + Ins_MIRP( TT_ExecContext exc, + FT_Long* args ) { FT_UShort point; FT_ULong cvtEntry; @@ -6541,100 +6070,99 @@ org_dist, control_value_cutin, minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Int B1 = 0; /* pacify compiler */ FT_Int B2 = 0; FT_Bool reverse_move = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - minimum_distance = CUR.GS.minimum_distance; - control_value_cutin = CUR.GS.control_value_cutin; + minimum_distance = exc->GS.minimum_distance; + control_value_cutin = exc->GS.control_value_cutin; point = (FT_UShort)args[0]; cvtEntry = (FT_ULong)( args[1] + 1 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp1.n_points ) || + BOUNDSL( cvtEntry, exc->cvtSize + 1 ) || + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } if ( !cvtEntry ) cvt_dist = 0; else - cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); + cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 ); /* single width test */ - if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) < - CUR.GS.single_width_cutin ) + if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) < + exc->GS.single_width_cutin ) { if ( cvt_dist >= 0 ) - cvt_dist = CUR.GS.single_width_value; + cvt_dist = exc->GS.single_width_value; else - cvt_dist = -CUR.GS.single_width_value; + cvt_dist = -exc->GS.single_width_value; } /* UNDOCUMENTED! The MS rasterizer does that with */ /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep1 == 0 ) + if ( exc->GS.gep1 == 0 ) { - CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + - TT_MulFix14( (FT_UInt32)cvt_dist, - CUR.GS.freeVector.x ); - CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + - TT_MulFix14( (FT_UInt32)cvt_dist, - CUR.GS.freeVector.y ); - CUR.zp1.cur[point] = CUR.zp1.org[point]; + exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x + + TT_MulFix14( cvt_dist, + exc->GS.freeVector.x ); + exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y + + TT_MulFix14( cvt_dist, + exc->GS.freeVector.y ); + exc->zp1.cur[point] = exc->zp1.org[point]; } - org_dist = CUR_Func_dualproj( &CUR.zp1.org[point], - &CUR.zp0.org[CUR.GS.rp0] ); - cur_dist = CUR_Func_project ( &CUR.zp1.cur[point], - &CUR.zp0.cur[CUR.GS.rp0] ); + org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] ); + cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] ); /* auto-flip test */ - if ( CUR.GS.auto_flip ) + if ( exc->GS.auto_flip ) { if ( ( org_dist ^ cvt_dist ) < 0 ) cvt_dist = -cvt_dist; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.y != 0 && + ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) { if ( cur_dist < -64 ) cvt_dist -= 16; else if ( cur_dist > 64 && cur_dist < 84 ) cvt_dist += 32; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* control value cut-in and round */ - if ( ( CUR.opcode & 4 ) != 0 ) + if ( ( exc->opcode & 4 ) != 0 ) { /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ /* refer to the same zone. */ - if ( CUR.GS.gep0 == CUR.GS.gep1 ) + if ( exc->GS.gep0 == exc->GS.gep1 ) { /* XXX: According to Greg Hitchcock, the following wording is */ /* the right one: */ @@ -6652,32 +6180,34 @@ cvt_dist = org_dist; } - distance = CUR_Func_round( + distance = exc->func_round( + exc, cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + exc->tt_metrics.compensations[exc->opcode & 3] ); } else { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* do cvt cut-in always in MIRP for sph */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.gep0 == CUR.GS.gep1 ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.gep0 == exc->GS.gep1 ) { if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) cvt_dist = org_dist; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - distance = ROUND_None( + distance = Round_None( + exc, cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + exc->tt_metrics.compensations[exc->opcode & 3] ); } /* minimum distance test */ - if ( ( CUR.opcode & 8 ) != 0 ) + if ( ( exc->opcode & 8 ) != 0 ) { if ( org_dist >= 0 ) { @@ -6691,62 +6221,62 @@ } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { - B1 = CUR.zp1.cur[point].y; + B1 = exc->zp1.cur[point].y; /* Round moves if necessary */ - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) + if ( exc->ignore_x_mode && + exc->GS.freeVector.y != 0 && + ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.opcode & 16 ) == 0 && - ( CUR.opcode & 8 ) == 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) + if ( exc->ignore_x_mode && + exc->GS.freeVector.y != 0 && + ( exc->opcode & 16 ) == 0 && + ( exc->opcode & 8 ) == 0 && + ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) distance += 64; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); + exc->func_move( exc, &exc->zp1, point, distance - cur_dist ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { - B2 = CUR.zp1.cur[point].y; + B2 = exc->zp1.cur[point].y; /* Reverse move if necessary */ - if ( CUR.ignore_x_mode ) + if ( exc->ignore_x_mode ) { - if ( CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 && - ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 ) + if ( exc->face->sph_compatibility_mode && + exc->GS.freeVector.y != 0 && + ( B1 & 63 ) == 0 && + ( B2 & 63 ) != 0 ) reverse_move = TRUE; - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - CUR.GS.freeVector.y != 0 && - ( B2 & 63 ) != 0 && - ( B1 & 63 ) != 0 ) + if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && + exc->GS.freeVector.y != 0 && + ( B2 & 63 ) != 0 && + ( B1 & 63 ) != 0 ) reverse_move = TRUE; } if ( reverse_move ) - CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) ); + exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ Fail: - CUR.GS.rp1 = CUR.GS.rp0; + exc->GS.rp1 = exc->GS.rp0; - if ( ( CUR.opcode & 16 ) != 0 ) - CUR.GS.rp0 = point; + if ( ( exc->opcode & 16 ) != 0 ) + exc->GS.rp0 = point; - CUR.GS.rp2 = point; + exc->GS.rp2 = point; } @@ -6757,61 +6287,59 @@ /* Stack: uint32 uint32... --> */ /* */ static void - Ins_ALIGNRP( INS_ARG ) + Ins_ALIGNRP( TT_ExecContext exc ) { FT_UShort point; FT_F26Dot6 distance; - FT_UNUSED_ARG; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->iup_called && + ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( CUR.top < CUR.GS.loop || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + if ( exc->top < exc->GS.loop || + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } - while ( CUR.GS.loop > 0 ) + while ( exc->GS.loop > 0 ) { - CUR.args--; + exc->args--; - point = (FT_UShort)CUR.stack[CUR.args]; + point = (FT_UShort)exc->stack[exc->args]; - if ( BOUNDS( point, CUR.zp1.n_points ) ) + if ( BOUNDS( point, exc->zp1.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } else { - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); + distance = PROJECT( exc->zp1.cur + point, + exc->zp0.cur + exc->GS.rp0 ); - CUR_Func_move( &CUR.zp1, point, -distance ); + exc->func_move( exc, &exc->zp1, point, -distance ); } - CUR.GS.loop--; + exc->GS.loop--; } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -6822,7 +6350,8 @@ /* Stack: 5 * uint32 --> */ /* */ static void - Ins_ISECT( INS_ARG ) + Ins_ISECT( TT_ExecContext exc, + FT_Long* args ) { FT_UShort point, a0, a1, @@ -6846,29 +6375,27 @@ b0 = (FT_UShort)args[3]; b1 = (FT_UShort)args[4]; - if ( BOUNDS( b0, CUR.zp0.n_points ) || - BOUNDS( b1, CUR.zp0.n_points ) || - BOUNDS( a0, CUR.zp1.n_points ) || - BOUNDS( a1, CUR.zp1.n_points ) || - BOUNDS( point, CUR.zp2.n_points ) ) + if ( BOUNDS( b0, exc->zp0.n_points ) || + BOUNDS( b1, exc->zp0.n_points ) || + BOUNDS( a0, exc->zp1.n_points ) || + BOUNDS( a1, exc->zp1.n_points ) || + BOUNDS( point, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } /* Cramer's rule */ - dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; - dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; - - dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; - day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; + dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x; + dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y; - dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; - dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; + dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x; + day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y; - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; + dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x; + dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y; discriminant = FT_MulDiv( dax, -dby, 0x40 ) + FT_MulDiv( day, dbx, 0x40 ); @@ -6890,22 +6417,26 @@ R.x = FT_MulDiv( val, dax, discriminant ); R.y = FT_MulDiv( val, day, discriminant ); - CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; - CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; + /* XXX: Block in backwards_compatibility and/or post-IUP? */ + exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x; + exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y; } else { /* else, take the middle of the middles of A and B */ - CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + - CUR.zp1.cur[a1].x + - CUR.zp0.cur[b0].x + - CUR.zp0.cur[b1].x ) / 4; - CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + - CUR.zp1.cur[a1].y + - CUR.zp0.cur[b0].y + - CUR.zp0.cur[b1].y ) / 4; + /* XXX: Block in backwards_compatibility and/or post-IUP? */ + exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x + + exc->zp1.cur[a1].x + + exc->zp0.cur[b0].x + + exc->zp0.cur[b1].x ) / 4; + exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y + + exc->zp1.cur[a1].y + + exc->zp0.cur[b0].y + + exc->zp0.cur[b1].y ) / 4; } + + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; } @@ -6916,7 +6447,8 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_ALIGNPTS( INS_ARG ) + Ins_ALIGNPTS( TT_ExecContext exc, + FT_Long* args ) { FT_UShort p1, p2; FT_F26Dot6 distance; @@ -6925,19 +6457,18 @@ p1 = (FT_UShort)args[0]; p2 = (FT_UShort)args[1]; - if ( BOUNDS( p1, CUR.zp1.n_points ) || - BOUNDS( p2, CUR.zp0.n_points ) ) + if ( BOUNDS( p1, exc->zp1.n_points ) || + BOUNDS( p2, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - distance = CUR_Func_project( CUR.zp0.cur + p2, - CUR.zp1.cur + p1 ) / 2; + distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2; - CUR_Func_move( &CUR.zp1, p1, distance ); - CUR_Func_move( &CUR.zp0, p2, -distance ); + exc->func_move( exc, &exc->zp1, p1, distance ); + exc->func_move( exc, &exc->zp0, p2, -distance ); } @@ -6951,50 +6482,48 @@ /* SOMETIMES, DUMBER CODE IS BETTER CODE */ static void - Ins_IP( INS_ARG ) + Ins_IP( TT_ExecContext exc ) { FT_F26Dot6 old_range, cur_range; FT_Vector* orus_base; FT_Vector* cur_base; FT_Int twilight; - FT_UNUSED_ARG; - - if ( CUR.top < CUR.GS.loop ) + if ( exc->top < exc->GS.loop ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } /* * We need to deal in a special way with the twilight zone. - * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0), + * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0), * for every n. */ - twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; + twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0; - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ) + if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } if ( twilight ) - orus_base = &CUR.zp0.org[CUR.GS.rp1]; + orus_base = &exc->zp0.org[exc->GS.rp1]; else - orus_base = &CUR.zp0.orus[CUR.GS.rp1]; + orus_base = &exc->zp0.orus[exc->GS.rp1]; - cur_base = &CUR.zp0.cur[CUR.GS.rp1]; + cur_base = &exc->zp0.cur[exc->GS.rp1]; /* XXX: There are some glyphs in some braindead but popular */ /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ /* calling IP[] with bad values of rp[12]. */ /* Do something sane when this odd thing happens. */ - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || - BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) + if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) || + BOUNDS( exc->GS.rp2, exc->zp1.n_points ) ) { old_range = 0; cur_range = 0; @@ -7002,62 +6531,60 @@ else { if ( twilight ) - old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], - orus_base ); - else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) - old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2], - orus_base ); + old_range = DUALPROJ( &exc->zp1.org[exc->GS.rp2], orus_base ); + else if ( exc->metrics.x_scale == exc->metrics.y_scale ) + old_range = DUALPROJ( &exc->zp1.orus[exc->GS.rp2], orus_base ); else { FT_Vector vec; - vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x, - CUR.metrics.x_scale ); - vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y, - CUR.metrics.y_scale ); + vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x, + exc->metrics.x_scale ); + vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y, + exc->metrics.y_scale ); - old_range = CUR_fast_dualproj( &vec ); + old_range = FAST_DUALPROJ( &vec ); } - cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); + cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base ); } - for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) + for ( ; exc->GS.loop > 0; --exc->GS.loop ) { - FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; + FT_UInt point = (FT_UInt)exc->stack[--exc->args]; FT_F26Dot6 org_dist, cur_dist, new_dist; /* check point bounds */ - if ( BOUNDS( point, CUR.zp2.n_points ) ) + if ( BOUNDS( point, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } continue; } if ( twilight ) - org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); - else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) - org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); + org_dist = DUALPROJ( &exc->zp2.org[point], orus_base ); + else if ( exc->metrics.x_scale == exc->metrics.y_scale ) + org_dist = DUALPROJ( &exc->zp2.orus[point], orus_base ); else { FT_Vector vec; - vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x, - CUR.metrics.x_scale ); - vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y, - CUR.metrics.y_scale ); + vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x, + exc->metrics.x_scale ); + vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y, + exc->metrics.y_scale ); - org_dist = CUR_fast_dualproj( &vec ); + org_dist = FAST_DUALPROJ( &vec ); } - cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); + cur_dist = PROJECT( &exc->zp2.cur[point], cur_base ); if ( org_dist ) { @@ -7068,25 +6595,34 @@ /* This is the same as what MS does for the invalid case: */ /* */ /* delta = (Original_Pt - Original_RP1) - */ - /* (Current_Pt - Current_RP1) */ + /* (Current_Pt - Current_RP1) ; */ /* */ /* In FreeType speak: */ /* */ - /* new_dist = cur_dist - */ - /* org_dist - cur_dist; */ + /* delta = org_dist - cur_dist . */ + /* */ + /* We move `point' by `new_dist - cur_dist' after leaving */ + /* this block, thus we have */ + /* */ + /* new_dist - cur_dist = delta , */ + /* new_dist - cur_dist = org_dist - cur_dist , */ + /* new_dist = org_dist . */ - new_dist = -org_dist; + new_dist = org_dist; } } else new_dist = 0; - CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); + exc->func_move( exc, + &exc->zp2, + (FT_UShort)point, + new_dist - cur_dist ); } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -7097,7 +6633,8 @@ /* Stack: uint32 --> */ /* */ static void - Ins_UTP( INS_ARG ) + Ins_UTP( TT_ExecContext exc, + FT_Long* args ) { FT_UShort point; FT_Byte mask; @@ -7105,22 +6642,22 @@ point = (FT_UShort)args[0]; - if ( BOUNDS( point, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } mask = 0xFF; - if ( CUR.GS.freeVector.x != 0 ) + if ( exc->GS.freeVector.x != 0 ) mask &= ~FT_CURVE_TAG_TOUCH_X; - if ( CUR.GS.freeVector.y != 0 ) + if ( exc->GS.freeVector.y != 0 ) mask &= ~FT_CURVE_TAG_TOUCH_Y; - CUR.zp0.tags[point] &= mask; + exc->zp0.tags[point] &= mask; } @@ -7165,7 +6702,7 @@ FT_UInt ref2 ) { FT_UInt i; - FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2; + FT_F26Dot6 orus1, orus2, org1, org2, cur1, cur2, delta1, delta2; if ( p1 > p2 ) @@ -7195,12 +6732,15 @@ org1 = worker->orgs[ref1].x; org2 = worker->orgs[ref2].x; - delta1 = worker->curs[ref1].x - org1; - delta2 = worker->curs[ref2].x - org2; + cur1 = worker->curs[ref1].x; + cur2 = worker->curs[ref2].x; + delta1 = cur1 - org1; + delta2 = cur2 - org2; - if ( orus1 == orus2 ) + if ( cur1 == cur2 || orus1 == orus2 ) { - /* simple shift of untouched points */ + + /* trivial snap or shift of untouched points */ for ( i = p1; i <= p2; i++ ) { FT_F26Dot6 x = worker->orgs[i].x; @@ -7208,9 +6748,13 @@ if ( x <= org1 ) x += delta1; - else + + else if ( x >= org2 ) x += delta2; + else + x = cur1; + worker->curs[i].x = x; } } @@ -7237,12 +6781,10 @@ if ( !scale_valid ) { scale_valid = 1; - scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ), - orus2 - orus1 ); + scale = FT_DivFix( cur2 - cur1, orus2 - orus1 ); } - x = ( org1 + delta1 ) + - FT_MulFix( worker->orus[i].x - orus1, scale ); + x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale ); } worker->curs[i].x = x; } @@ -7257,7 +6799,7 @@ /* Stack: --> */ /* */ static void - Ins_IUP( INS_ARG ) + Ins_IUP( TT_ExecContext exc ) { IUP_WorkerRec V; FT_Byte mask; @@ -7271,51 +6813,66 @@ FT_UInt point; /* current point */ FT_Short contour; /* current contour */ - FT_UNUSED_ARG; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + /* Allow IUP until it has been called on both axes. Immediately */ + /* return on subsequent ones. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + if ( exc->iupx_called && exc->iupy_called ) + return; + + if ( exc->opcode & 1 ) + exc->iupx_called = TRUE; + else + exc->iupy_called = TRUE; + } +#endif /* ignore empty outlines */ - if ( CUR.pts.n_contours == 0 ) + if ( exc->pts.n_contours == 0 ) return; - if ( CUR.opcode & 1 ) + if ( exc->opcode & 1 ) { mask = FT_CURVE_TAG_TOUCH_X; - V.orgs = CUR.pts.org; - V.curs = CUR.pts.cur; - V.orus = CUR.pts.orus; + V.orgs = exc->pts.org; + V.curs = exc->pts.cur; + V.orus = exc->pts.orus; } else { mask = FT_CURVE_TAG_TOUCH_Y; - V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); - V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); - V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); + V.orgs = (FT_Vector*)( (FT_Pos*)exc->pts.org + 1 ); + V.curs = (FT_Vector*)( (FT_Pos*)exc->pts.cur + 1 ); + V.orus = (FT_Vector*)( (FT_Pos*)exc->pts.orus + 1 ); } - V.max_points = CUR.pts.n_points; + V.max_points = exc->pts.n_points; contour = 0; point = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode ) { - CUR.iup_called = TRUE; - if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) + exc->iup_called = TRUE; + if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) return; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ do { - end_point = CUR.pts.contours[contour] - CUR.pts.first_point; + end_point = exc->pts.contours[contour] - exc->pts.first_point; first_point = point; - if ( BOUNDS ( end_point, CUR.pts.n_points ) ) - end_point = CUR.pts.n_points - 1; + if ( BOUNDS( end_point, exc->pts.n_points ) ) + end_point = exc->pts.n_points - 1; - while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) + while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 ) point++; if ( point <= end_point ) @@ -7327,7 +6884,7 @@ while ( point <= end_point ) { - if ( ( CUR.pts.tags[point] & mask ) != 0 ) + if ( ( exc->pts.tags[point] & mask ) != 0 ) { _iup_worker_interpolate( &V, cur_touched + 1, @@ -7359,7 +6916,7 @@ } } contour++; - } while ( contour < CUR.pts.n_contours ); + } while ( contour < exc->pts.n_contours ); } @@ -7370,61 +6927,42 @@ /* Stack: uint32 (2 * uint32)... --> */ /* */ static void - Ins_DELTAP( INS_ARG ) + Ins_DELTAP( TT_ExecContext exc, + FT_Long* args ) { - FT_ULong k, nump; + FT_ULong nump, k; FT_UShort A; - FT_ULong C; + FT_ULong C, P; FT_Long B; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_UShort B1, B2; - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->iup_called && + ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) goto Fail; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( CUR.face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( CUR.args < n ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - n = CUR.args; - } - - CUR.args -= n; - CUR.new_top = CUR.args; - return; - } -#endif +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; /* some points theoretically may occur more than once, thus UShort isn't enough */ for ( k = 1; k <= nump; k++ ) { - if ( CUR.args < 2 ) + if ( exc->args < 2 ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - CUR.args = 0; + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Too_Few_Arguments ); + exc->args = 0; goto Fail; } - CUR.args -= 2; + exc->args -= 2; - A = (FT_UShort)CUR.stack[CUR.args + 1]; - B = CUR.stack[CUR.args]; + A = (FT_UShort)exc->stack[exc->args + 1]; + B = exc->stack[exc->args]; /* XXX: Because some popular fonts contain some invalid DeltaP */ /* instructions, we simply ignore them when the stacked */ @@ -7432,11 +6970,11 @@ /* error. As a delta instruction doesn't change a glyph */ /* in great ways, this shouldn't be a problem. */ - if ( !BOUNDS( A, CUR.zp0.n_points ) ) + if ( !BOUNDS( A, exc->zp0.n_points ) ) { C = ( (FT_ULong)B & 0xF0 ) >> 4; - switch ( CUR.opcode ) + switch ( exc->opcode ) { case 0x5D: break; @@ -7450,95 +6988,102 @@ break; } - C += CUR.GS.delta_base; + C += exc->GS.delta_base; - if ( CURRENT_Ppem() == (FT_Long)C ) + if ( P == C ) { B = ( (FT_ULong)B & 0xF ) - 8; if ( B >= 0 ) B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); + B *= 1L << ( 6 - exc->GS.delta_shift ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { /* * Allow delta move if * - * - not using ignore_x_mode rendering - * - glyph is specifically set to allow it - * - glyph is composite and freedom vector is not subpixel - * vector + * - not using ignore_x_mode rendering, + * - glyph is specifically set to allow it, or + * - glyph is composite and freedom vector is not in subpixel + * direction. */ - if ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || - ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ) - CUR_Func_move( &CUR.zp0, A, B ); - - /* Otherwise apply subpixel hinting and */ - /* compatibility mode rules */ - else if ( CUR.ignore_x_mode ) + if ( !exc->ignore_x_mode || + ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || + ( exc->is_composite && exc->GS.freeVector.y != 0 ) ) + exc->func_move( exc, &exc->zp0, A, B ); + + /* Otherwise, apply subpixel hinting and compatibility mode */ + /* rules, always skipping deltas in subpixel direction. */ + else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 ) { - if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp0.cur[A].y; - else - B1 = CUR.zp0.cur[A].x; - -#if 0 - /* Standard Subpixel Hinting: Allow y move. */ - /* This messes up dejavu and may not be needed... */ - if ( !CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 ) - CUR_Func_move( &CUR.zp0, A, B ); - else -#endif /* 0 */ - - /* Compatibility Mode: Allow x or y move if point touched in */ - /* Y direction. */ - if ( CUR.face->sph_compatibility_mode && - !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) + /* save the y value of the point now; compare after move */ + B1 = (FT_UShort)exc->zp0.cur[A].y; + + /* Standard subpixel hinting: Allow y move for y-touched */ + /* points. This messes up DejaVu ... */ + if ( !exc->face->sph_compatibility_mode && + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) + exc->func_move( exc, &exc->zp0, A, B ); + + /* compatibility mode */ + else if ( exc->face->sph_compatibility_mode && + !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) { - /* save the y value of the point now; compare after move */ - B1 = CUR.zp0.cur[A].y; - - if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) + if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) B = FT_PIX_ROUND( B1 + B ) - B1; /* Allow delta move if using sph_compatibility_mode, */ /* IUP has not been called, and point is touched on Y. */ - if ( !CUR.iup_called && - ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) - CUR_Func_move( &CUR.zp0, A, B ); + if ( !exc->iup_called && + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) + exc->func_move( exc, &exc->zp0, A, B ); } - B2 = CUR.zp0.cur[A].y; + B2 = (FT_UShort)exc->zp0.cur[A].y; /* Reverse this move if it results in a disallowed move */ - if ( CUR.GS.freeVector.y != 0 && - ( ( CUR.face->sph_compatibility_mode && + if ( exc->GS.freeVector.y != 0 && + ( ( exc->face->sph_compatibility_mode && ( B1 & 63 ) == 0 && ( B2 & 63 ) != 0 ) || - ( ( CUR.sph_tweak_flags & + ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && ( B1 & 63 ) != 0 && ( B2 & 63 ) != 0 ) ) ) - CUR_Func_move( &CUR.zp0, A, -B ); + exc->func_move( exc, &exc->zp0, A, -B ); } } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + + { - CUR_Func_move( &CUR.zp0, A, B ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility */ + /* mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + if ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) ) + exc->func_move( exc, &exc->zp0, A, B ); + } + else +#endif + exc->func_move( exc, &exc->zp0, A, B ); + } } } else - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); } Fail: - CUR.new_top = CUR.args; + exc->new_top = exc->args; } @@ -7549,55 +7094,37 @@ /* Stack: uint32 (2 * uint32)... --> */ /* */ static void - Ins_DELTAC( INS_ARG ) + Ins_DELTAC( TT_ExecContext exc, + FT_Long* args ) { FT_ULong nump, k; - FT_ULong A, C; + FT_ULong A, C, P; FT_Long B; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( CUR.face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( CUR.args < n ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - n = CUR.args; - } - - CUR.args -= n; - CUR.new_top = CUR.args; - return; - } -#endif - + P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; for ( k = 1; k <= nump; k++ ) { - if ( CUR.args < 2 ) + if ( exc->args < 2 ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - CUR.args = 0; + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Too_Few_Arguments ); + exc->args = 0; goto Fail; } - CUR.args -= 2; + exc->args -= 2; - A = (FT_ULong)CUR.stack[CUR.args + 1]; - B = CUR.stack[CUR.args]; + A = (FT_ULong)exc->stack[exc->args + 1]; + B = exc->stack[exc->args]; - if ( BOUNDSL( A, CUR.cvtSize ) ) + if ( BOUNDSL( A, exc->cvtSize ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } @@ -7605,7 +7132,7 @@ { C = ( (FT_ULong)B & 0xF0 ) >> 4; - switch ( CUR.opcode ) + switch ( exc->opcode ) { case 0x73: break; @@ -7619,22 +7146,22 @@ break; } - C += CUR.GS.delta_base; + C += exc->GS.delta_base; - if ( CURRENT_Ppem() == (FT_Long)C ) + if ( P == C ) { B = ( (FT_ULong)B & 0xF ) - 8; if ( B >= 0 ) B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); + B *= 1L << ( 6 - exc->GS.delta_shift ); - CUR_Func_move_cvt( A, B ); + exc->func_move_cvt( exc, A, B ); } } } Fail: - CUR.new_top = CUR.args; + exc->new_top = exc->args; } @@ -7651,39 +7178,56 @@ /* Opcode range: 0x88 */ /* Stack: uint32 --> uint32 */ /* */ + /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May */ + /* 2015) not documented in the OpenType specification. */ + /* */ + /* Selector bit 11 is incorrectly described as bit 8, while the */ + /* real meaning of bit 8 (vertical LCD subpixels) stays */ + /* undocumented. The same mistake can be found in Greg Hitchcock's */ + /* whitepaper. */ + /* */ static void - Ins_GETINFO( INS_ARG ) + Ins_GETINFO( TT_ExecContext exc, + FT_Long* args ) { - FT_Long K; + FT_Long K; + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( exc->face ); K = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /********************************/ /* RASTERIZER VERSION */ /* Selector Bit: 0 */ /* Return Bit(s): 0-7 */ /* */ - if ( SUBPIXEL_HINTING && - ( args[0] & 1 ) != 0 && - CUR.ignore_x_mode ) + if ( SUBPIXEL_HINTING_INFINALITY && + ( args[0] & 1 ) != 0 && + exc->subpixel_hinting ) { - K = CUR.rasterizer_version; - FT_TRACE7(( "Setting rasterizer version %d\n", - CUR.rasterizer_version )); + if ( exc->ignore_x_mode ) + { + /* if in ClearType backwards compatibility mode, */ + /* we sometimes change the TrueType version dynamically */ + K = exc->rasterizer_version; + FT_TRACE6(( "Setting rasterizer version %d\n", + exc->rasterizer_version )); + } + else + K = TT_INTERPRETER_VERSION_38; } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( ( args[0] & 1 ) != 0 ) - K = TT_INTERPRETER_VERSION_35; + K = driver->interpreter_version; /********************************/ /* GLYPH ROTATED */ /* Selector Bit: 1 */ /* Return Bit(s): 8 */ /* */ - if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) + if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated ) K |= 0x80; /********************************/ @@ -7691,43 +7235,85 @@ /* Selector Bit: 2 */ /* Return Bit(s): 9 */ /* */ - if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) + if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched ) K |= 1 << 8; /********************************/ - /* HINTING FOR GRAYSCALE */ + /* BI-LEVEL HINTING AND */ + /* GRAYSCALE RENDERING */ /* Selector Bit: 5 */ /* Return Bit(s): 12 */ /* */ - if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) + if ( ( args[0] & 32 ) != 0 && exc->grayscale ) K |= 1 << 12; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL ) { - /********************************/ - /* HINTING FOR GRAYSCALE */ - /* Selector Bit: 5 */ - /* Return Bit(s): 12 */ - /* */ - if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting ) - K |= 1 << 12; - /********************************/ /* HINTING FOR SUBPIXEL */ /* Selector Bit: 6 */ /* Return Bit(s): 13 */ /* */ - if ( ( args[0] & 64 ) != 0 && - CUR.subpixel_hinting && - CUR.rasterizer_version >= 37 ) - { + /* v40 does subpixel hinting by default. */ + if ( ( args[0] & 64 ) != 0 ) K |= 1 << 13; - /* the stuff below is irrelevant if subpixel_hinting is not set */ + /********************************/ + /* VERTICAL LCD SUBPIXELS? */ + /* Selector Bit: 8 */ + /* Return Bit(s): 15 */ + /* */ + if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean ) + K |= 1 << 15; + + /********************************/ + /* SUBPIXEL POSITIONED? */ + /* Selector Bit: 10 */ + /* Return Bit(s): 17 */ + /* */ + /* XXX: FreeType supports it, dependent on what client does? */ + if ( ( args[0] & 1024 ) != 0 ) + K |= 1 << 17; + + /********************************/ + /* SYMMETRICAL SMOOTHING */ + /* Selector Bit: 11 */ + /* Return Bit(s): 18 */ + /* */ + /* The only smoothing method FreeType supports unless someone sets */ + /* FT_LOAD_TARGET_MONO. */ + if ( ( args[0] & 2048 ) != 0 ) + K |= 1 << 18; + + /********************************/ + /* CLEARTYPE HINTING AND */ + /* GRAYSCALE RENDERING */ + /* Selector Bit: 12 */ + /* Return Bit(s): 19 */ + /* */ + /* Grayscale rendering is what FreeType does anyway unless someone */ + /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */ + if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype ) + K |= 1 << 19; + } +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + + if ( SUBPIXEL_HINTING_INFINALITY && + exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 ) + { + + if ( exc->rasterizer_version >= 37 ) + { + /********************************/ + /* HINTING FOR SUBPIXEL */ + /* Selector Bit: 6 */ + /* Return Bit(s): 13 */ + /* */ + if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting ) + K |= 1 << 13; /********************************/ /* COMPATIBLE WIDTHS ENABLED */ @@ -7735,16 +7321,16 @@ /* Return Bit(s): 14 */ /* */ /* Functionality still needs to be added */ - if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) + if ( ( args[0] & 128 ) != 0 && exc->compatible_widths ) K |= 1 << 14; /********************************/ - /* SYMMETRICAL SMOOTHING */ + /* VERTICAL LCD SUBPIXELS? */ /* Selector Bit: 8 */ /* Return Bit(s): 15 */ /* */ /* Functionality still needs to be added */ - if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing ) + if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd ) K |= 1 << 15; /********************************/ @@ -7753,10 +7339,10 @@ /* Return Bit(s): 16 */ /* */ /* Functionality still needs to be added */ - if ( ( args[0] & 512 ) != 0 && CUR.bgr ) + if ( ( args[0] & 512 ) != 0 && exc->bgr ) K |= 1 << 16; - if ( CUR.rasterizer_version >= 38 ) + if ( exc->rasterizer_version >= 38 ) { /********************************/ /* SUBPIXEL POSITIONED? */ @@ -7764,345 +7350,74 @@ /* Return Bit(s): 17 */ /* */ /* Functionality still needs to be added */ - if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned ) + if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned ) K |= 1 << 17; + + /********************************/ + /* SYMMETRICAL SMOOTHING */ + /* Selector Bit: 11 */ + /* Return Bit(s): 18 */ + /* */ + /* Functionality still needs to be added */ + if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing ) + K |= 1 << 18; + + /********************************/ + /* GRAY CLEARTYPE */ + /* Selector Bit: 12 */ + /* Return Bit(s): 19 */ + /* */ + /* Functionality still needs to be added */ + if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype ) + K |= 1 << 19; } } } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = K; } static void - Ins_UNKNOWN( INS_ARG ) + Ins_UNKNOWN( TT_ExecContext exc ) { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; - - FT_UNUSED_ARG; + TT_DefRecord* def = exc->IDefs; + TT_DefRecord* limit = def + exc->numIDefs; for ( ; def < limit; def++ ) { - if ( (FT_Byte)def->opc == CUR.opcode && def->active ) + if ( (FT_Byte)def->opc == exc->opcode && def->active ) { TT_CallRec* call; - if ( CUR.callTop >= CUR.callSize ) + if ( exc->callTop >= exc->callSize ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); return; } - call = CUR.callStack + CUR.callTop++; + call = exc->callStack + exc->callTop++; - call->Caller_Range = CUR.curRange; - call->Caller_IP = CUR.IP + 1; + call->Caller_Range = exc->curRange; + call->Caller_IP = exc->IP + 1; call->Cur_Count = 1; - call->Cur_Restart = def->start; - call->Cur_End = def->end; + call->Def = def; - INS_Goto_CodeRange( def->range, def->start ); + Ins_Goto_CodeRange( exc, def->range, def->start ); - CUR.step_ins = FALSE; + exc->step_ins = FALSE; return; } } - CUR.error = FT_THROW( Invalid_Opcode ); + exc->error = FT_THROW( Invalid_Opcode ); } -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - static - TInstruction_Function Instruct_Dispatch[256] = - { - /* Opcodes are gathered in groups of 16. */ - /* Please keep the spaces as they are. */ - - /* SVTCA y */ Ins_SVTCA, - /* SVTCA x */ Ins_SVTCA, - /* SPvTCA y */ Ins_SPVTCA, - /* SPvTCA x */ Ins_SPVTCA, - /* SFvTCA y */ Ins_SFVTCA, - /* SFvTCA x */ Ins_SFVTCA, - /* SPvTL // */ Ins_SPVTL, - /* SPvTL + */ Ins_SPVTL, - /* SFvTL // */ Ins_SFVTL, - /* SFvTL + */ Ins_SFVTL, - /* SPvFS */ Ins_SPVFS, - /* SFvFS */ Ins_SFVFS, - /* GPV */ Ins_GPV, - /* GFV */ Ins_GFV, - /* SFvTPv */ Ins_SFVTPV, - /* ISECT */ Ins_ISECT, - - /* SRP0 */ Ins_SRP0, - /* SRP1 */ Ins_SRP1, - /* SRP2 */ Ins_SRP2, - /* SZP0 */ Ins_SZP0, - /* SZP1 */ Ins_SZP1, - /* SZP2 */ Ins_SZP2, - /* SZPS */ Ins_SZPS, - /* SLOOP */ Ins_SLOOP, - /* RTG */ Ins_RTG, - /* RTHG */ Ins_RTHG, - /* SMD */ Ins_SMD, - /* ELSE */ Ins_ELSE, - /* JMPR */ Ins_JMPR, - /* SCvTCi */ Ins_SCVTCI, - /* SSwCi */ Ins_SSWCI, - /* SSW */ Ins_SSW, - - /* DUP */ Ins_DUP, - /* POP */ Ins_POP, - /* CLEAR */ Ins_CLEAR, - /* SWAP */ Ins_SWAP, - /* DEPTH */ Ins_DEPTH, - /* CINDEX */ Ins_CINDEX, - /* MINDEX */ Ins_MINDEX, - /* AlignPTS */ Ins_ALIGNPTS, - /* INS_0x28 */ Ins_UNKNOWN, - /* UTP */ Ins_UTP, - /* LOOPCALL */ Ins_LOOPCALL, - /* CALL */ Ins_CALL, - /* FDEF */ Ins_FDEF, - /* ENDF */ Ins_ENDF, - /* MDAP[0] */ Ins_MDAP, - /* MDAP[1] */ Ins_MDAP, - - /* IUP[0] */ Ins_IUP, - /* IUP[1] */ Ins_IUP, - /* SHP[0] */ Ins_SHP, - /* SHP[1] */ Ins_SHP, - /* SHC[0] */ Ins_SHC, - /* SHC[1] */ Ins_SHC, - /* SHZ[0] */ Ins_SHZ, - /* SHZ[1] */ Ins_SHZ, - /* SHPIX */ Ins_SHPIX, - /* IP */ Ins_IP, - /* MSIRP[0] */ Ins_MSIRP, - /* MSIRP[1] */ Ins_MSIRP, - /* AlignRP */ Ins_ALIGNRP, - /* RTDG */ Ins_RTDG, - /* MIAP[0] */ Ins_MIAP, - /* MIAP[1] */ Ins_MIAP, - - /* NPushB */ Ins_NPUSHB, - /* NPushW */ Ins_NPUSHW, - /* WS */ Ins_WS, - /* RS */ Ins_RS, - /* WCvtP */ Ins_WCVTP, - /* RCvt */ Ins_RCVT, - /* GC[0] */ Ins_GC, - /* GC[1] */ Ins_GC, - /* SCFS */ Ins_SCFS, - /* MD[0] */ Ins_MD, - /* MD[1] */ Ins_MD, - /* MPPEM */ Ins_MPPEM, - /* MPS */ Ins_MPS, - /* FlipON */ Ins_FLIPON, - /* FlipOFF */ Ins_FLIPOFF, - /* DEBUG */ Ins_DEBUG, - - /* LT */ Ins_LT, - /* LTEQ */ Ins_LTEQ, - /* GT */ Ins_GT, - /* GTEQ */ Ins_GTEQ, - /* EQ */ Ins_EQ, - /* NEQ */ Ins_NEQ, - /* ODD */ Ins_ODD, - /* EVEN */ Ins_EVEN, - /* IF */ Ins_IF, - /* EIF */ Ins_EIF, - /* AND */ Ins_AND, - /* OR */ Ins_OR, - /* NOT */ Ins_NOT, - /* DeltaP1 */ Ins_DELTAP, - /* SDB */ Ins_SDB, - /* SDS */ Ins_SDS, - - /* ADD */ Ins_ADD, - /* SUB */ Ins_SUB, - /* DIV */ Ins_DIV, - /* MUL */ Ins_MUL, - /* ABS */ Ins_ABS, - /* NEG */ Ins_NEG, - /* FLOOR */ Ins_FLOOR, - /* CEILING */ Ins_CEILING, - /* ROUND[0] */ Ins_ROUND, - /* ROUND[1] */ Ins_ROUND, - /* ROUND[2] */ Ins_ROUND, - /* ROUND[3] */ Ins_ROUND, - /* NROUND[0] */ Ins_NROUND, - /* NROUND[1] */ Ins_NROUND, - /* NROUND[2] */ Ins_NROUND, - /* NROUND[3] */ Ins_NROUND, - - /* WCvtF */ Ins_WCVTF, - /* DeltaP2 */ Ins_DELTAP, - /* DeltaP3 */ Ins_DELTAP, - /* DeltaCn[0] */ Ins_DELTAC, - /* DeltaCn[1] */ Ins_DELTAC, - /* DeltaCn[2] */ Ins_DELTAC, - /* SROUND */ Ins_SROUND, - /* S45Round */ Ins_S45ROUND, - /* JROT */ Ins_JROT, - /* JROF */ Ins_JROF, - /* ROFF */ Ins_ROFF, - /* INS_0x7B */ Ins_UNKNOWN, - /* RUTG */ Ins_RUTG, - /* RDTG */ Ins_RDTG, - /* SANGW */ Ins_SANGW, - /* AA */ Ins_AA, - - /* FlipPT */ Ins_FLIPPT, - /* FlipRgON */ Ins_FLIPRGON, - /* FlipRgOFF */ Ins_FLIPRGOFF, - /* INS_0x83 */ Ins_UNKNOWN, - /* INS_0x84 */ Ins_UNKNOWN, - /* ScanCTRL */ Ins_SCANCTRL, - /* SDPVTL[0] */ Ins_SDPVTL, - /* SDPVTL[1] */ Ins_SDPVTL, - /* GetINFO */ Ins_GETINFO, - /* IDEF */ Ins_IDEF, - /* ROLL */ Ins_ROLL, - /* MAX */ Ins_MAX, - /* MIN */ Ins_MIN, - /* ScanTYPE */ Ins_SCANTYPE, - /* InstCTRL */ Ins_INSTCTRL, - /* INS_0x8F */ Ins_UNKNOWN, - - /* INS_0x90 */ Ins_UNKNOWN, - /* INS_0x91 */ Ins_UNKNOWN, - /* INS_0x92 */ Ins_UNKNOWN, - /* INS_0x93 */ Ins_UNKNOWN, - /* INS_0x94 */ Ins_UNKNOWN, - /* INS_0x95 */ Ins_UNKNOWN, - /* INS_0x96 */ Ins_UNKNOWN, - /* INS_0x97 */ Ins_UNKNOWN, - /* INS_0x98 */ Ins_UNKNOWN, - /* INS_0x99 */ Ins_UNKNOWN, - /* INS_0x9A */ Ins_UNKNOWN, - /* INS_0x9B */ Ins_UNKNOWN, - /* INS_0x9C */ Ins_UNKNOWN, - /* INS_0x9D */ Ins_UNKNOWN, - /* INS_0x9E */ Ins_UNKNOWN, - /* INS_0x9F */ Ins_UNKNOWN, - - /* INS_0xA0 */ Ins_UNKNOWN, - /* INS_0xA1 */ Ins_UNKNOWN, - /* INS_0xA2 */ Ins_UNKNOWN, - /* INS_0xA3 */ Ins_UNKNOWN, - /* INS_0xA4 */ Ins_UNKNOWN, - /* INS_0xA5 */ Ins_UNKNOWN, - /* INS_0xA6 */ Ins_UNKNOWN, - /* INS_0xA7 */ Ins_UNKNOWN, - /* INS_0xA8 */ Ins_UNKNOWN, - /* INS_0xA9 */ Ins_UNKNOWN, - /* INS_0xAA */ Ins_UNKNOWN, - /* INS_0xAB */ Ins_UNKNOWN, - /* INS_0xAC */ Ins_UNKNOWN, - /* INS_0xAD */ Ins_UNKNOWN, - /* INS_0xAE */ Ins_UNKNOWN, - /* INS_0xAF */ Ins_UNKNOWN, - - /* PushB[0] */ Ins_PUSHB, - /* PushB[1] */ Ins_PUSHB, - /* PushB[2] */ Ins_PUSHB, - /* PushB[3] */ Ins_PUSHB, - /* PushB[4] */ Ins_PUSHB, - /* PushB[5] */ Ins_PUSHB, - /* PushB[6] */ Ins_PUSHB, - /* PushB[7] */ Ins_PUSHB, - /* PushW[0] */ Ins_PUSHW, - /* PushW[1] */ Ins_PUSHW, - /* PushW[2] */ Ins_PUSHW, - /* PushW[3] */ Ins_PUSHW, - /* PushW[4] */ Ins_PUSHW, - /* PushW[5] */ Ins_PUSHW, - /* PushW[6] */ Ins_PUSHW, - /* PushW[7] */ Ins_PUSHW, - - /* MDRP[00] */ Ins_MDRP, - /* MDRP[01] */ Ins_MDRP, - /* MDRP[02] */ Ins_MDRP, - /* MDRP[03] */ Ins_MDRP, - /* MDRP[04] */ Ins_MDRP, - /* MDRP[05] */ Ins_MDRP, - /* MDRP[06] */ Ins_MDRP, - /* MDRP[07] */ Ins_MDRP, - /* MDRP[08] */ Ins_MDRP, - /* MDRP[09] */ Ins_MDRP, - /* MDRP[10] */ Ins_MDRP, - /* MDRP[11] */ Ins_MDRP, - /* MDRP[12] */ Ins_MDRP, - /* MDRP[13] */ Ins_MDRP, - /* MDRP[14] */ Ins_MDRP, - /* MDRP[15] */ Ins_MDRP, - - /* MDRP[16] */ Ins_MDRP, - /* MDRP[17] */ Ins_MDRP, - /* MDRP[18] */ Ins_MDRP, - /* MDRP[19] */ Ins_MDRP, - /* MDRP[20] */ Ins_MDRP, - /* MDRP[21] */ Ins_MDRP, - /* MDRP[22] */ Ins_MDRP, - /* MDRP[23] */ Ins_MDRP, - /* MDRP[24] */ Ins_MDRP, - /* MDRP[25] */ Ins_MDRP, - /* MDRP[26] */ Ins_MDRP, - /* MDRP[27] */ Ins_MDRP, - /* MDRP[28] */ Ins_MDRP, - /* MDRP[29] */ Ins_MDRP, - /* MDRP[30] */ Ins_MDRP, - /* MDRP[31] */ Ins_MDRP, - - /* MIRP[00] */ Ins_MIRP, - /* MIRP[01] */ Ins_MIRP, - /* MIRP[02] */ Ins_MIRP, - /* MIRP[03] */ Ins_MIRP, - /* MIRP[04] */ Ins_MIRP, - /* MIRP[05] */ Ins_MIRP, - /* MIRP[06] */ Ins_MIRP, - /* MIRP[07] */ Ins_MIRP, - /* MIRP[08] */ Ins_MIRP, - /* MIRP[09] */ Ins_MIRP, - /* MIRP[10] */ Ins_MIRP, - /* MIRP[11] */ Ins_MIRP, - /* MIRP[12] */ Ins_MIRP, - /* MIRP[13] */ Ins_MIRP, - /* MIRP[14] */ Ins_MIRP, - /* MIRP[15] */ Ins_MIRP, - - /* MIRP[16] */ Ins_MIRP, - /* MIRP[17] */ Ins_MIRP, - /* MIRP[18] */ Ins_MIRP, - /* MIRP[19] */ Ins_MIRP, - /* MIRP[20] */ Ins_MIRP, - /* MIRP[21] */ Ins_MIRP, - /* MIRP[22] */ Ins_MIRP, - /* MIRP[23] */ Ins_MIRP, - /* MIRP[24] */ Ins_MIRP, - /* MIRP[25] */ Ins_MIRP, - /* MIRP[26] */ Ins_MIRP, - /* MIRP[27] */ Ins_MIRP, - /* MIRP[28] */ Ins_MIRP, - /* MIRP[29] */ Ins_MIRP, - /* MIRP[30] */ Ins_MIRP, - /* MIRP[31] */ Ins_MIRP - }; - - -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - /*************************************************************************/ /* */ /* RUN */ @@ -8130,8 +7445,6 @@ /* */ /* THIS IS THE INTERPRETER'S MAIN LOOP. */ /* */ - /* Instructions appear in the specification's order. */ - /* */ /*************************************************************************/ @@ -8143,7 +7456,7 @@ FT_Long ins_counter = 0; /* executed instructions counter */ FT_UShort i; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Byte opcode_pattern[1][2] = { /* #8 TypeMan Talk Align */ { @@ -8154,106 +7467,136 @@ FT_UShort opcode_patterns = 1; FT_UShort opcode_pointer[1] = { 0 }; FT_UShort opcode_size[1] = { 1 }; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - cur = *exc; -#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + exc->iup_called = FALSE; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Toggle backwards compatibility according to what font says, except */ + /* when it's a `tricky' font that heavily relies on the interpreter to */ + /* render glyphs correctly, e.g. DFKai-SB. Backwards compatibility */ + /* hacks may break it. */ + if ( SUBPIXEL_HINTING_MINIMAL && + !FT_IS_TRICKY( &exc->face->root ) ) + exc->backwards_compatibility = !( exc->GS.instruct_control & 4 ); + else + exc->backwards_compatibility = FALSE; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - CUR.iup_called = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + exc->iupx_called = FALSE; + exc->iupy_called = FALSE; +#endif - /* set CVT functions */ - CUR.tt_metrics.ratio = 0; - if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) + /* set PPEM and CVT functions */ + exc->tt_metrics.ratio = 0; + if ( exc->metrics.x_ppem != exc->metrics.y_ppem ) { /* non-square pixels, use the stretched routines */ - CUR.func_read_cvt = Read_CVT_Stretched; - CUR.func_write_cvt = Write_CVT_Stretched; - CUR.func_move_cvt = Move_CVT_Stretched; + exc->func_cur_ppem = Current_Ppem_Stretched; + exc->func_read_cvt = Read_CVT_Stretched; + exc->func_write_cvt = Write_CVT_Stretched; + exc->func_move_cvt = Move_CVT_Stretched; } else { /* square pixels, use normal routines */ - CUR.func_read_cvt = Read_CVT; - CUR.func_write_cvt = Write_CVT; - CUR.func_move_cvt = Move_CVT; + exc->func_cur_ppem = Current_Ppem; + exc->func_read_cvt = Read_CVT; + exc->func_write_cvt = Write_CVT; + exc->func_move_cvt = Move_CVT; } - COMPUTE_Funcs(); - COMPUTE_Round( (FT_Byte)exc->GS.round_state ); + Compute_Funcs( exc ); + Compute_Round( exc, (FT_Byte)exc->GS.round_state ); do { - CUR.opcode = CUR.code[CUR.IP]; + exc->opcode = exc->code[exc->IP]; - FT_TRACE7(( " " )); - FT_TRACE7(( opcode_name[CUR.opcode] )); - FT_TRACE7(( "\n" )); +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Long cnt = FT_MIN( 8, exc->top ); + FT_Long n; + + + /* if tracing level is 7, show current code position */ + /* and the first few stack elements also */ + FT_TRACE6(( " " )); + FT_TRACE7(( "%06d ", exc->IP )); + FT_TRACE6(( opcode_name[exc->opcode] + 2 )); + FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A' + ? 2 + : 12 - ( *opcode_name[exc->opcode] - '0' ), + "#" )); + for ( n = 1; n <= cnt; n++ ) + FT_TRACE7(( " %d", exc->stack[exc->top - n] )); + FT_TRACE6(( "\n" )); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ - if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) + if ( ( exc->length = opcode_length[exc->opcode] ) < 0 ) { - if ( CUR.IP + 1 >= CUR.codeSize ) + if ( exc->IP + 1 >= exc->codeSize ) goto LErrorCodeOverflow_; - CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; + exc->length = 2 - exc->length * exc->code[exc->IP + 1]; } - if ( CUR.IP + CUR.length > CUR.codeSize ) + if ( exc->IP + exc->length > exc->codeSize ) goto LErrorCodeOverflow_; /* First, let's check for empty stack and overflow */ - CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); + exc->args = exc->top - ( Pop_Push_Count[exc->opcode] >> 4 ); /* `args' is the top of the stack once arguments have been popped. */ /* One can also interpret it as the index of the last argument. */ - if ( CUR.args < 0 ) + if ( exc->args < 0 ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Too_Few_Arguments ); + exc->error = FT_THROW( Too_Few_Arguments ); goto LErrorLabel_; } /* push zeroes onto the stack */ - for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ ) - CUR.stack[i] = 0; - CUR.args = 0; + for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ ) + exc->stack[i] = 0; + exc->args = 0; } - CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); + exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 ); /* `new_top' is the new top of the stack, after the instruction's */ /* execution. `top' will be set to `new_top' after the `switch' */ /* statement. */ - if ( CUR.new_top > CUR.stackSize ) + if ( exc->new_top > exc->stackSize ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); goto LErrorLabel_; } - CUR.step_ins = TRUE; - CUR.error = FT_Err_Ok; + exc->step_ins = TRUE; + exc->error = FT_Err_Ok; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { for ( i = 0; i < opcode_patterns; i++ ) { - if ( opcode_pointer[i] < opcode_size[i] && - CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) + if ( opcode_pointer[i] < opcode_size[i] && + exc->opcode == opcode_pattern[i][opcode_pointer[i]] ) { opcode_pointer[i] += 1; if ( opcode_pointer[i] == opcode_size[i] ) { - FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n", + FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n", i, - CUR.face->root.family_name, - CUR.face->root.style_name )); + exc->face->root.family_name, + exc->face->root.style_name )); switch ( i ) { @@ -8268,17 +7611,11 @@ } } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - -#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { - FT_Long* args = CUR.stack + CUR.args; - FT_Byte opcode = CUR.opcode; - - -#undef ARRAY_BOUND_ERROR -#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref + FT_Long* args = exc->stack + exc->args; + FT_Byte opcode = exc->opcode; switch ( opcode ) @@ -8289,581 +7626,543 @@ case 0x03: /* SPvTCA x */ case 0x04: /* SFvTCA y */ case 0x05: /* SFvTCA x */ - { - FT_Short AA, BB; - - - AA = (FT_Short)( ( opcode & 1 ) << 14 ); - BB = (FT_Short)( AA ^ 0x4000 ); - - if ( opcode < 4 ) - { - CUR.GS.projVector.x = AA; - CUR.GS.projVector.y = BB; - - CUR.GS.dualVector.x = AA; - CUR.GS.dualVector.y = BB; - } - else - { - GUESS_VECTOR( projVector ); - } - - if ( ( opcode & 2 ) == 0 ) - { - CUR.GS.freeVector.x = AA; - CUR.GS.freeVector.y = BB; - } - else - { - GUESS_VECTOR( freeVector ); - } - - COMPUTE_Funcs(); - } + Ins_SxyTCA( exc ); break; case 0x06: /* SPvTL // */ case 0x07: /* SPvTL + */ - DO_SPVTL + Ins_SPVTL( exc, args ); break; case 0x08: /* SFvTL // */ case 0x09: /* SFvTL + */ - DO_SFVTL + Ins_SFVTL( exc, args ); break; case 0x0A: /* SPvFS */ - DO_SPVFS + Ins_SPVFS( exc, args ); break; case 0x0B: /* SFvFS */ - DO_SFVFS + Ins_SFVFS( exc, args ); break; - case 0x0C: /* GPV */ - DO_GPV + case 0x0C: /* GPv */ + Ins_GPV( exc, args ); break; - case 0x0D: /* GFV */ - DO_GFV + case 0x0D: /* GFv */ + Ins_GFV( exc, args ); break; case 0x0E: /* SFvTPv */ - DO_SFVTPV + Ins_SFVTPV( exc ); break; case 0x0F: /* ISECT */ - Ins_ISECT( EXEC_ARG_ args ); + Ins_ISECT( exc, args ); break; case 0x10: /* SRP0 */ - DO_SRP0 + Ins_SRP0( exc, args ); break; case 0x11: /* SRP1 */ - DO_SRP1 + Ins_SRP1( exc, args ); break; case 0x12: /* SRP2 */ - DO_SRP2 + Ins_SRP2( exc, args ); break; case 0x13: /* SZP0 */ - Ins_SZP0( EXEC_ARG_ args ); + Ins_SZP0( exc, args ); break; case 0x14: /* SZP1 */ - Ins_SZP1( EXEC_ARG_ args ); + Ins_SZP1( exc, args ); break; case 0x15: /* SZP2 */ - Ins_SZP2( EXEC_ARG_ args ); + Ins_SZP2( exc, args ); break; case 0x16: /* SZPS */ - Ins_SZPS( EXEC_ARG_ args ); + Ins_SZPS( exc, args ); break; case 0x17: /* SLOOP */ - DO_SLOOP + Ins_SLOOP( exc, args ); break; case 0x18: /* RTG */ - DO_RTG + Ins_RTG( exc ); break; case 0x19: /* RTHG */ - DO_RTHG + Ins_RTHG( exc ); break; case 0x1A: /* SMD */ - DO_SMD + Ins_SMD( exc, args ); break; case 0x1B: /* ELSE */ - Ins_ELSE( EXEC_ARG_ args ); + Ins_ELSE( exc ); break; case 0x1C: /* JMPR */ - DO_JMPR + Ins_JMPR( exc, args ); break; case 0x1D: /* SCVTCI */ - DO_SCVTCI + Ins_SCVTCI( exc, args ); break; case 0x1E: /* SSWCI */ - DO_SSWCI + Ins_SSWCI( exc, args ); break; case 0x1F: /* SSW */ - DO_SSW + Ins_SSW( exc, args ); break; case 0x20: /* DUP */ - DO_DUP + Ins_DUP( args ); break; case 0x21: /* POP */ - /* nothing :-) */ + Ins_POP(); break; case 0x22: /* CLEAR */ - DO_CLEAR + Ins_CLEAR( exc ); break; case 0x23: /* SWAP */ - DO_SWAP + Ins_SWAP( args ); break; case 0x24: /* DEPTH */ - DO_DEPTH + Ins_DEPTH( exc, args ); break; case 0x25: /* CINDEX */ - DO_CINDEX + Ins_CINDEX( exc, args ); break; case 0x26: /* MINDEX */ - Ins_MINDEX( EXEC_ARG_ args ); + Ins_MINDEX( exc, args ); break; case 0x27: /* ALIGNPTS */ - Ins_ALIGNPTS( EXEC_ARG_ args ); + Ins_ALIGNPTS( exc, args ); break; case 0x28: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); break; case 0x29: /* UTP */ - Ins_UTP( EXEC_ARG_ args ); + Ins_UTP( exc, args ); break; case 0x2A: /* LOOPCALL */ - Ins_LOOPCALL( EXEC_ARG_ args ); + Ins_LOOPCALL( exc, args ); break; case 0x2B: /* CALL */ - Ins_CALL( EXEC_ARG_ args ); + Ins_CALL( exc, args ); break; case 0x2C: /* FDEF */ - Ins_FDEF( EXEC_ARG_ args ); + Ins_FDEF( exc, args ); break; case 0x2D: /* ENDF */ - Ins_ENDF( EXEC_ARG_ args ); + Ins_ENDF( exc ); break; case 0x2E: /* MDAP */ case 0x2F: /* MDAP */ - Ins_MDAP( EXEC_ARG_ args ); + Ins_MDAP( exc, args ); break; case 0x30: /* IUP */ case 0x31: /* IUP */ - Ins_IUP( EXEC_ARG_ args ); + Ins_IUP( exc ); break; case 0x32: /* SHP */ case 0x33: /* SHP */ - Ins_SHP( EXEC_ARG_ args ); + Ins_SHP( exc ); break; case 0x34: /* SHC */ case 0x35: /* SHC */ - Ins_SHC( EXEC_ARG_ args ); + Ins_SHC( exc, args ); break; case 0x36: /* SHZ */ case 0x37: /* SHZ */ - Ins_SHZ( EXEC_ARG_ args ); + Ins_SHZ( exc, args ); break; case 0x38: /* SHPIX */ - Ins_SHPIX( EXEC_ARG_ args ); + Ins_SHPIX( exc, args ); break; case 0x39: /* IP */ - Ins_IP( EXEC_ARG_ args ); + Ins_IP( exc ); break; case 0x3A: /* MSIRP */ case 0x3B: /* MSIRP */ - Ins_MSIRP( EXEC_ARG_ args ); + Ins_MSIRP( exc, args ); break; case 0x3C: /* AlignRP */ - Ins_ALIGNRP( EXEC_ARG_ args ); + Ins_ALIGNRP( exc ); break; case 0x3D: /* RTDG */ - DO_RTDG + Ins_RTDG( exc ); break; case 0x3E: /* MIAP */ case 0x3F: /* MIAP */ - Ins_MIAP( EXEC_ARG_ args ); + Ins_MIAP( exc, args ); break; case 0x40: /* NPUSHB */ - Ins_NPUSHB( EXEC_ARG_ args ); + Ins_NPUSHB( exc, args ); break; case 0x41: /* NPUSHW */ - Ins_NPUSHW( EXEC_ARG_ args ); + Ins_NPUSHW( exc, args ); break; case 0x42: /* WS */ - DO_WS - break; - - Set_Invalid_Ref: - CUR.error = FT_THROW( Invalid_Reference ); + Ins_WS( exc, args ); break; case 0x43: /* RS */ - DO_RS + Ins_RS( exc, args ); break; case 0x44: /* WCVTP */ - DO_WCVTP + Ins_WCVTP( exc, args ); break; case 0x45: /* RCVT */ - DO_RCVT + Ins_RCVT( exc, args ); break; case 0x46: /* GC */ case 0x47: /* GC */ - Ins_GC( EXEC_ARG_ args ); + Ins_GC( exc, args ); break; case 0x48: /* SCFS */ - Ins_SCFS( EXEC_ARG_ args ); + Ins_SCFS( exc, args ); break; case 0x49: /* MD */ case 0x4A: /* MD */ - Ins_MD( EXEC_ARG_ args ); + Ins_MD( exc, args ); break; case 0x4B: /* MPPEM */ - DO_MPPEM + Ins_MPPEM( exc, args ); break; case 0x4C: /* MPS */ - DO_MPS + Ins_MPS( exc, args ); break; case 0x4D: /* FLIPON */ - DO_FLIPON + Ins_FLIPON( exc ); break; case 0x4E: /* FLIPOFF */ - DO_FLIPOFF + Ins_FLIPOFF( exc ); break; case 0x4F: /* DEBUG */ - DO_DEBUG + Ins_DEBUG( exc ); break; case 0x50: /* LT */ - DO_LT + Ins_LT( args ); break; case 0x51: /* LTEQ */ - DO_LTEQ + Ins_LTEQ( args ); break; case 0x52: /* GT */ - DO_GT + Ins_GT( args ); break; case 0x53: /* GTEQ */ - DO_GTEQ + Ins_GTEQ( args ); break; case 0x54: /* EQ */ - DO_EQ + Ins_EQ( args ); break; case 0x55: /* NEQ */ - DO_NEQ + Ins_NEQ( args ); break; case 0x56: /* ODD */ - DO_ODD + Ins_ODD( exc, args ); break; case 0x57: /* EVEN */ - DO_EVEN + Ins_EVEN( exc, args ); break; case 0x58: /* IF */ - Ins_IF( EXEC_ARG_ args ); + Ins_IF( exc, args ); break; case 0x59: /* EIF */ - /* do nothing */ + Ins_EIF(); break; case 0x5A: /* AND */ - DO_AND + Ins_AND( args ); break; case 0x5B: /* OR */ - DO_OR + Ins_OR( args ); break; case 0x5C: /* NOT */ - DO_NOT + Ins_NOT( args ); break; case 0x5D: /* DELTAP1 */ - Ins_DELTAP( EXEC_ARG_ args ); + Ins_DELTAP( exc, args ); break; case 0x5E: /* SDB */ - DO_SDB + Ins_SDB( exc, args ); break; case 0x5F: /* SDS */ - DO_SDS + Ins_SDS( exc, args ); break; case 0x60: /* ADD */ - DO_ADD + Ins_ADD( args ); break; case 0x61: /* SUB */ - DO_SUB + Ins_SUB( args ); break; case 0x62: /* DIV */ - DO_DIV + Ins_DIV( exc, args ); break; case 0x63: /* MUL */ - DO_MUL + Ins_MUL( args ); break; case 0x64: /* ABS */ - DO_ABS + Ins_ABS( args ); break; case 0x65: /* NEG */ - DO_NEG + Ins_NEG( args ); break; case 0x66: /* FLOOR */ - DO_FLOOR + Ins_FLOOR( args ); break; case 0x67: /* CEILING */ - DO_CEILING + Ins_CEILING( args ); break; case 0x68: /* ROUND */ case 0x69: /* ROUND */ case 0x6A: /* ROUND */ case 0x6B: /* ROUND */ - DO_ROUND + Ins_ROUND( exc, args ); break; case 0x6C: /* NROUND */ case 0x6D: /* NROUND */ case 0x6E: /* NRRUND */ case 0x6F: /* NROUND */ - DO_NROUND + Ins_NROUND( exc, args ); break; case 0x70: /* WCVTF */ - DO_WCVTF + Ins_WCVTF( exc, args ); break; case 0x71: /* DELTAP2 */ case 0x72: /* DELTAP3 */ - Ins_DELTAP( EXEC_ARG_ args ); + Ins_DELTAP( exc, args ); break; case 0x73: /* DELTAC0 */ case 0x74: /* DELTAC1 */ case 0x75: /* DELTAC2 */ - Ins_DELTAC( EXEC_ARG_ args ); + Ins_DELTAC( exc, args ); break; case 0x76: /* SROUND */ - DO_SROUND + Ins_SROUND( exc, args ); break; case 0x77: /* S45Round */ - DO_S45ROUND + Ins_S45ROUND( exc, args ); break; case 0x78: /* JROT */ - DO_JROT + Ins_JROT( exc, args ); break; case 0x79: /* JROF */ - DO_JROF + Ins_JROF( exc, args ); break; case 0x7A: /* ROFF */ - DO_ROFF + Ins_ROFF( exc ); break; case 0x7B: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); break; case 0x7C: /* RUTG */ - DO_RUTG + Ins_RUTG( exc ); break; case 0x7D: /* RDTG */ - DO_RDTG + Ins_RDTG( exc ); break; case 0x7E: /* SANGW */ - case 0x7F: /* AA */ - /* nothing - obsolete */ + Ins_SANGW(); + break; + + case 0x7F: /* AA */ + Ins_AA(); break; case 0x80: /* FLIPPT */ - Ins_FLIPPT( EXEC_ARG_ args ); + Ins_FLIPPT( exc ); break; case 0x81: /* FLIPRGON */ - Ins_FLIPRGON( EXEC_ARG_ args ); + Ins_FLIPRGON( exc, args ); break; case 0x82: /* FLIPRGOFF */ - Ins_FLIPRGOFF( EXEC_ARG_ args ); + Ins_FLIPRGOFF( exc, args ); break; case 0x83: /* UNKNOWN */ case 0x84: /* UNKNOWN */ - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); break; case 0x85: /* SCANCTRL */ - Ins_SCANCTRL( EXEC_ARG_ args ); + Ins_SCANCTRL( exc, args ); break; - case 0x86: /* SDPVTL */ - case 0x87: /* SDPVTL */ - Ins_SDPVTL( EXEC_ARG_ args ); + case 0x86: /* SDPvTL */ + case 0x87: /* SDPvTL */ + Ins_SDPVTL( exc, args ); break; case 0x88: /* GETINFO */ - Ins_GETINFO( EXEC_ARG_ args ); + Ins_GETINFO( exc, args ); break; case 0x89: /* IDEF */ - Ins_IDEF( EXEC_ARG_ args ); + Ins_IDEF( exc, args ); break; case 0x8A: /* ROLL */ - Ins_ROLL( EXEC_ARG_ args ); + Ins_ROLL( args ); break; case 0x8B: /* MAX */ - DO_MAX + Ins_MAX( args ); break; case 0x8C: /* MIN */ - DO_MIN + Ins_MIN( args ); break; case 0x8D: /* SCANTYPE */ - Ins_SCANTYPE( EXEC_ARG_ args ); + Ins_SCANTYPE( exc, args ); break; case 0x8E: /* INSTCTRL */ - Ins_INSTCTRL( EXEC_ARG_ args ); + Ins_INSTCTRL( exc, args ); break; case 0x8F: - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); break; default: if ( opcode >= 0xE0 ) - Ins_MIRP( EXEC_ARG_ args ); + Ins_MIRP( exc, args ); else if ( opcode >= 0xC0 ) - Ins_MDRP( EXEC_ARG_ args ); + Ins_MDRP( exc, args ); else if ( opcode >= 0xB8 ) - Ins_PUSHW( EXEC_ARG_ args ); + Ins_PUSHW( exc, args ); else if ( opcode >= 0xB0 ) - Ins_PUSHB( EXEC_ARG_ args ); + Ins_PUSHB( exc, args ); else - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); } - } -#else - - Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); - -#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - if ( CUR.error ) + if ( exc->error ) { - switch ( CUR.error ) + switch ( exc->error ) { /* looking for redefined instructions */ case FT_ERR( Invalid_Opcode ): { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; + TT_DefRecord* def = exc->IDefs; + TT_DefRecord* limit = def + exc->numIDefs; for ( ; def < limit; def++ ) { - if ( def->active && CUR.opcode == (FT_Byte)def->opc ) + if ( def->active && exc->opcode == (FT_Byte)def->opc ) { TT_CallRec* callrec; - if ( CUR.callTop >= CUR.callSize ) + if ( exc->callTop >= exc->callSize ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); goto LErrorLabel_; } - callrec = &CUR.callStack[CUR.callTop]; + callrec = &exc->callStack[exc->callTop]; - callrec->Caller_Range = CUR.curRange; - callrec->Caller_IP = CUR.IP + 1; + callrec->Caller_Range = exc->curRange; + callrec->Caller_IP = exc->IP + 1; callrec->Cur_Count = 1; - callrec->Cur_Restart = def->start; - callrec->Cur_End = def->end; + callrec->Def = def; - if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) + if ( Ins_Goto_CodeRange( exc, + def->range, + def->start ) == FAILURE ) goto LErrorLabel_; goto LSuiteLabel_; @@ -8871,7 +8170,7 @@ } } - CUR.error = FT_THROW( Invalid_Opcode ); + exc->error = FT_THROW( Invalid_Opcode ); goto LErrorLabel_; #if 0 @@ -8889,56 +8188,49 @@ } } - CUR.top = CUR.new_top; + exc->top = exc->new_top; - if ( CUR.step_ins ) - CUR.IP += CUR.length; + if ( exc->step_ins ) + exc->IP += exc->length; /* increment instruction counter and check if we didn't */ /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) return FT_THROW( Execution_Too_Long ); LSuiteLabel_: - if ( CUR.IP >= CUR.codeSize ) + if ( exc->IP >= exc->codeSize ) { - if ( CUR.callTop > 0 ) + if ( exc->callTop > 0 ) { - CUR.error = FT_THROW( Code_Overflow ); + exc->error = FT_THROW( Code_Overflow ); goto LErrorLabel_; } else goto LNo_Error_; } - } while ( !CUR.instruction_trap ); + } while ( !exc->instruction_trap ); LNo_Error_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - return FT_Err_Ok; LErrorCodeOverflow_: - CUR.error = FT_THROW( Code_Overflow ); + exc->error = FT_THROW( Code_Overflow ); LErrorLabel_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - /* If any errors have occurred, function tables may be broken. */ /* Force a re-execution of `prep' and `fpgm' tables if no */ /* bytecode debugger is run. */ - if ( CUR.error && !CUR.instruction_trap ) + if ( exc->error && + !exc->instruction_trap && + exc->curRange == tt_coderange_glyph ) { - FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); - exc->size->cvt_ready = FALSE; + FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error )); + exc->size->bytecode_ready = -1; + exc->size->cvt_ready = -1; } - return CUR.error; + return exc->error; } diff --git a/drivers/freetype/src/truetype/ttinterp.h b/drivers/freetype/src/truetype/ttinterp.h index 69f5011ed4..df7ce51f1c 100644 --- a/drivers/freetype/src/truetype/ttinterp.h +++ b/drivers/freetype/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (specification). */ /* */ -/* Copyright 1996-2007, 2010, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTINTERP_H__ -#define __TTINTERP_H__ +#ifndef TTINTERP_H_ +#define TTINTERP_H_ #include <ft2build.h> #include "ttobjs.h" @@ -26,23 +26,6 @@ FT_BEGIN_HEADER -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ - -#define EXEC_OP_ TT_ExecContext exc, -#define EXEC_OP TT_ExecContext exc -#define EXEC_ARG_ exc, -#define EXEC_ARG exc - -#else /* static implementation */ - -#define EXEC_OP_ /* void */ -#define EXEC_OP /* void */ -#define EXEC_ARG_ /* void */ -#define EXEC_ARG /* void */ - -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - /*************************************************************************/ /* */ /* Rounding mode constants. */ @@ -67,29 +50,38 @@ FT_BEGIN_HEADER /* Rounding function */ typedef FT_F26Dot6 - (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ); + (*TT_Round_Func)( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ); /* Point displacement along the freedom vector routine */ typedef void - (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ); + (*TT_Move_Func)( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ); /* Distance projection along one of the projection vectors */ typedef FT_F26Dot6 - (*TT_Project_Func)( EXEC_OP_ FT_Pos dx, - FT_Pos dy ); + (*TT_Project_Func)( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ); + + /* getting current ppem. Take care of non-square pixels if necessary */ + typedef FT_Long + (*TT_Cur_Ppem_Func)( TT_ExecContext exc ); /* reading a cvt value. Take care of non-square pixels if necessary */ typedef FT_F26Dot6 - (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx ); + (*TT_Get_CVT_Func)( TT_ExecContext exc, + FT_ULong idx ); /* setting or moving a cvt value. Take care of non-square pixels */ /* if necessary */ typedef void - (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ); + (*TT_Set_CVT_Func)( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ); /*************************************************************************/ @@ -101,13 +93,13 @@ FT_BEGIN_HEADER FT_Int Caller_Range; FT_Long Caller_IP; FT_Long Cur_Count; - FT_Long Cur_Restart; - FT_Long Cur_End; + + TT_DefRecord *Def; /* either FDEF or IDEF */ } TT_CallRec, *TT_CallStack; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -146,7 +138,7 @@ FT_BEGIN_HEADER } SPH_Font_Class; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /*************************************************************************/ @@ -166,11 +158,11 @@ FT_BEGIN_HEADER FT_Long top; /* top of exec. stack */ - FT_UInt stackSize; /* size of exec. stack */ + FT_Long stackSize; /* size of exec. stack */ FT_Long* stack; /* current exec. stack */ FT_Long args; - FT_UInt new_top; /* new top after exec. */ + FT_Long new_top; /* new top after exec. */ TT_GlyphZoneRec zp0, /* zone records */ zp1, @@ -228,11 +220,6 @@ FT_BEGIN_HEADER FT_F26Dot6 phase; /* `SuperRounding' */ FT_F26Dot6 threshold; -#if 0 - /* this seems to be unused */ - FT_Int cur_ppem; /* ppem along the current proj vector */ -#endif - FT_Bool instruction_trap; /* If `True', the interpreter will */ /* exit after each instruction */ @@ -254,29 +241,159 @@ FT_BEGIN_HEADER TT_Move_Func func_move; /* current point move function */ TT_Move_Func func_move_orig; /* move original position function */ + TT_Cur_Ppem_Func func_cur_ppem; /* get current proj. ppem value */ + TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ - FT_Bool grayscale; /* are we hinting for grayscale? */ - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + FT_Bool grayscale; /* bi-level hinting and */ + /* grayscale rendering */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* + * Modern TrueType fonts are usually rendered through Microsoft's + * collection of rendering techniques called ClearType (e.g., subpixel + * rendering and subpixel hinting). When ClearType was introduced, most + * fonts were not ready. Microsoft decided to implement a backwards + * compatibility mode that employed several simple to complicated + * assumptions and tricks that modified the interpretation of the + * bytecode contained in these fonts to make them look ClearType-y + * somehow. Most (web)fonts that were released since then have come to + * rely on these hacks to render correctly, even some of Microsoft's + * flagship ClearType fonts (Calibri, Cambria, Segoe UI). + * + * The minimal subpixel hinting code (interpreter version 40) employs a + * small list of font-agnostic hacks to bludgeon non-native-ClearType + * fonts (except tricky ones[1]) into submission. It will not try to + * toggle hacks for specific fonts for performance and complexity + * reasons. The focus is on modern (web)fonts rather than legacy fonts + * that were made for black-and-white rendering. + * + * Major hacks + * + * - Any point movement on the x axis is ignored (cf. `Direct_Move' and + * `Direct_Move_X'). This has the smallest code footprint and single + * biggest effect. The ClearType way to increase resolution is + * supersampling the x axis, the FreeType way is ignoring instructions + * on the x axis, which gives the same result in the majority of + * cases. + * + * - Points are not moved post-IUP (neither on the x nor on the y axis), + * except the x component of diagonal moves post-IUP (cf. + * `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point'). Post-IUP + * changes are commonly used to `fix' pixel patterns which has little + * use outside monochrome rendering. + * + * - SHPIX and DELTAP don't execute unless moving a composite on the + * y axis or moving a previously y touched point. SHPIX additionally + * denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP'). + * Both instructions are commonly used to `fix' pixel patterns for + * monochrome or Windows's GDI rendering but make little sense for + * FreeType rendering. Both can distort the outline. See [2] for + * details. + * + * - The hdmx table and modifications to phantom points are ignored. + * Bearings and advance widths remain unchanged (except rounding them + * outside the interpreter!), cf. `compute_glyph_metrics' and + * `TT_Hint_Glyph'. Letting non-native-ClearType fonts modify spacing + * might mess up spacing. + * + * Minor hacks + * + * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP. This + * prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at + * various sizes. + * + * (Post-IUP is the state after both IUP[x] and IUP[y] have been + * executed.) + * + * The best results are achieved for fonts that were from the outset + * designed with ClearType in mind, meaning they leave the x axis mostly + * alone and don't mess with the `final' outline to produce more + * pleasing pixel patterns. The harder the designer tried to produce + * very specific patterns (`superhinting') for pre-ClearType-displays, + * the worse the results. + * + * Microsoft defines a way to turn off backwards compatibility and + * interpret instructions as before (called `native ClearType')[2][3]. + * The font designer then regains full control and is responsible for + * making the font work correctly with ClearType without any + * hand-holding by the interpreter or rasterizer[4]. The v40 + * interpreter assumes backwards compatibility by default, which can be + * turned off the same way by executing the following in the control + * program (cf. `Ins_INSTCTRL'). + * + * #PUSH 4,3 + * INSTCTRL[] + * + * [1] Tricky fonts as FreeType defines them rely on the bytecode + * interpreter to display correctly. Hacks can interfere with them, + * so they get treated like native ClearType fonts (v40 with + * backwards compatibility turned off). Cf. `TT_RunIns'. + * + * [2] Proposed by Microsoft's Greg Hitchcock in + * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + * + * [3] Beat Stamm describes it in more detail: + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec12 + * + * [4] The list of `native ClearType' fonts is small at the time of this + * writing; I found the following on a Windows 10 Update 1511 + * installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft + * JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold), + * SimSun, NSimSun, and Yu Gothic. + * + */ + + /* Using v40 implies subpixel hinting. Used to detect interpreter */ + /* version switches. `_lean' to differentiate from the Infinality */ + /* `subpixel_hinting', which is managed differently. */ + FT_Bool subpixel_hinting_lean; + + /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */ + /* `_lean' to differentiate from the Infinality `vertical_lcd', which */ + /* is managed differently. */ + FT_Bool vertical_lcd_lean; + + /* Default to backwards compatibility mode in v40 interpreter. If */ + /* this is false, it implies the interpreter is in v35 or in native */ + /* ClearType mode. */ + FT_Bool backwards_compatibility; + + /* Useful for detecting and denying post-IUP trickery that is usually */ + /* used to fix pixel patterns (`superhinting'). */ + FT_Bool iupx_called; + FT_Bool iupy_called; + + /* ClearType hinting and grayscale rendering, as used by Universal */ + /* Windows Platform apps (Windows 8 and above). Like the standard */ + /* colorful ClearType mode, it utilizes a vastly increased virtual */ + /* resolution on the x axis. Different from bi-level hinting and */ + /* grayscale rendering, the old mode from Win9x days that roughly */ + /* adheres to the physical pixel grid on both axes. */ + FT_Bool grayscale_cleartype; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Round_Func func_round_sphn; /* subpixel rounding function */ - FT_Bool grayscale_hinting; /* Using grayscale hinting? */ FT_Bool subpixel_hinting; /* Using subpixel hinting? */ - FT_Bool native_hinting; /* Using native hinting? */ FT_Bool ignore_x_mode; /* Standard rendering mode for */ /* subpixel hinting. On if gray */ - /* or subpixel hinting is on ) */ + /* or subpixel hinting is on. */ - /* The following 4 aren't fully implemented but here for MS rasterizer */ + /* The following 6 aren't fully implemented but here for MS rasterizer */ /* compatibility. */ FT_Bool compatible_widths; /* compatible widths? */ FT_Bool symmetrical_smoothing; /* symmetrical_smoothing? */ FT_Bool bgr; /* bgr instead of rgb? */ + FT_Bool vertical_lcd; /* long side of LCD subpixel */ + /* rectangles is horizontal */ FT_Bool subpixel_positioned; /* subpixel positioned */ /* (DirectWrite ClearType)? */ + FT_Bool gray_cleartype; /* ClearType hinting but */ + /* grayscale rendering */ FT_Int rasterizer_version; /* MS rasterizer version */ @@ -288,7 +405,7 @@ FT_BEGIN_HEADER FT_ULong sph_in_func_flags; /* flags to indicate if in */ /* special functions */ -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ } TT_ExecContextRec; @@ -297,18 +414,18 @@ FT_BEGIN_HEADER #ifdef TT_USE_BYTECODE_INTERPRETER - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Goto_CodeRange( TT_ExecContext exec, FT_Int range, FT_Long IP ); - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Set_CodeRange( TT_ExecContext exec, FT_Int range, void* base, FT_Long length ); - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ); @@ -316,7 +433,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) Update_Max( FT_Memory memory, FT_ULong* size, - FT_Long multiplier, + FT_ULong multiplier, void* _pbuff, FT_ULong new_max ); #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -340,13 +457,14 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* Only the glyph loader and debugger should call this function. */ + /* (And right now only the glyph loader uses it.) */ /* */ FT_EXPORT( TT_ExecContext ) TT_New_Context( TT_Driver driver ); #ifdef TT_USE_BYTECODE_INTERPRETER - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Done_Context( TT_ExecContext exec ); FT_LOCAL( FT_Error ) @@ -354,13 +472,12 @@ FT_BEGIN_HEADER TT_Face face, TT_Size size ); - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Save_Context( TT_ExecContext exec, TT_Size ins ); FT_LOCAL( FT_Error ) - TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ); + TT_Run_Context( TT_ExecContext exec ); #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -391,7 +508,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTINTERP_H__ */ +#endif /* TTINTERP_H_ */ /* END */ diff --git a/drivers/freetype/src/truetype/ttobjs.c b/drivers/freetype/src/truetype/ttobjs.c index 7897efa77a..ed3be2dbee 100644 --- a/drivers/freetype/src/truetype/ttobjs.c +++ b/drivers/freetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ /* */ /* Objects manager (body). */ /* */ -/* Copyright 1996-2013 */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,10 +32,6 @@ #include "ttinterp.h" #endif -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#include FT_TRUETYPE_UNPATENTED_H -#endif - #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.h" #endif @@ -150,20 +146,21 @@ tt_check_trickyness_family( FT_String* name ) { -#define TRICK_NAMES_MAX_CHARACTERS 16 -#define TRICK_NAMES_COUNT 8 +#define TRICK_NAMES_MAX_CHARACTERS 19 +#define TRICK_NAMES_COUNT 9 static const char trick_names[TRICK_NAMES_COUNT] [TRICK_NAMES_MAX_CHARACTERS + 1] = { - "DFKaiSho-SB", /* dfkaisb.ttf */ + "DFKaiSho-SB", /* dfkaisb.ttf */ "DFKaiShu", - "DFKai-SB", /* kaiu.ttf */ - "HuaTianKaiTi?", /* htkt2.ttf */ - "HuaTianSongTi?", /* htst3.ttf */ - "MingLiU", /* mingliu.ttf & mingliu.ttc */ - "PMingLiU", /* mingliu.ttc */ - "MingLi43", /* mingli.ttf */ + "DFKai-SB", /* kaiu.ttf */ + "HuaTianKaiTi?", /* htkt2.ttf */ + "HuaTianSongTi?", /* htst3.ttf */ + "Ming(for ISO10646)", /* hkscsiic.ttf & iicore.ttf */ + "MingLiU", /* mingliu.ttf & mingliu.ttc */ + "PMingLiU", /* mingliu.ttc */ + "MingLi43", /* mingli.ttf */ }; int nn; @@ -190,7 +187,7 @@ { FT_Error error; FT_UInt32 checksum = 0; - int i; + FT_UInt i; if ( FT_FRAME_ENTER( length ) ) @@ -199,8 +196,8 @@ for ( ; length > 3; length -= 4 ) checksum += (FT_UInt32)FT_GET_ULONG(); - for ( i = 3; length > 0; length --, i-- ) - checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) ); + for ( i = 3; length > 0; length--, i-- ) + checksum += (FT_UInt32)FT_GET_BYTE() << ( i * 8 ); FT_FRAME_EXIT(); @@ -245,7 +242,7 @@ tt_check_trickyness_sfnt_ids( TT_Face face ) { #define TRICK_SFNT_IDS_PER_FACE 3 -#define TRICK_SFNT_IDS_NUM_FACES 17 +#define TRICK_SFNT_IDS_NUM_FACES 18 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] [TRICK_SFNT_IDS_PER_FACE] = { @@ -255,89 +252,94 @@ #define TRICK_SFNT_ID_prep 2 { /* MingLiU 1995 */ - { 0x05bcf058, 0x000002e4 }, /* cvt */ - { 0x28233bf1, 0x000087c4 }, /* fpgm */ - { 0xa344a1ea, 0x000001e1 } /* prep */ + { 0x05BCF058UL, 0x000002E4UL }, /* cvt */ + { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ + { 0xA344A1EAUL, 0x000001E1UL } /* prep */ }, { /* MingLiU 1996- */ - { 0x05bcf058, 0x000002e4 }, /* cvt */ - { 0x28233bf1, 0x000087c4 }, /* fpgm */ - { 0xa344a1eb, 0x000001e1 } /* prep */ + { 0x05BCF058UL, 0x000002E4UL }, /* cvt */ + { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ + { 0xA344A1EBUL, 0x000001E1UL } /* prep */ }, { /* DFKaiShu */ - { 0x11e5ead4, 0x00000350 }, /* cvt */ - { 0x5a30ca3b, 0x00009063 }, /* fpgm */ - { 0x13a42602, 0x0000007e } /* prep */ + { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ + { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */ + { 0x13A42602UL, 0x0000007EUL } /* prep */ + }, + { /* DFKaiShu2 */ + { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ + { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */ + { 0x13A42602UL, 0x0000007EUL } /* prep */ }, { /* HuaTianKaiTi */ - { 0xfffbfffc, 0x00000008 }, /* cvt */ - { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */ - { 0x70020112, 0x00000008 } /* prep */ + { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ + { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */ + { 0x70020112UL, 0x00000008UL } /* prep */ }, { /* HuaTianSongTi */ - { 0xfffbfffc, 0x00000008 }, /* cvt */ - { 0x0a5a0483, 0x00017c39 }, /* fpgm */ - { 0x70020112, 0x00000008 } /* prep */ + { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ + { 0x0A5A0483UL, 0x00017C39UL }, /* fpgm */ + { 0x70020112UL, 0x00000008UL } /* prep */ }, { /* NEC fadpop7.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40c92555, 0x000000e5 }, /* fpgm */ - { 0xa39b58e3, 0x0000117c } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x40C92555UL, 0x000000E5UL }, /* fpgm */ + { 0xA39B58E3UL, 0x0000117CUL } /* prep */ }, { /* NEC fadrei5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x33c41652, 0x000000e5 }, /* fpgm */ - { 0x26d6c52a, 0x00000f6a } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x33C41652UL, 0x000000E5UL }, /* fpgm */ + { 0x26D6C52AUL, 0x00000F6AUL } /* prep */ }, { /* NEC fangot7.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x6db1651d, 0x0000019d }, /* fpgm */ - { 0x6c6e4b03, 0x00002492 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x6DB1651DUL, 0x0000019DUL }, /* fpgm */ + { 0x6C6E4B03UL, 0x00002492UL } /* prep */ }, { /* NEC fangyo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40c92555, 0x000000e5 }, /* fpgm */ - { 0xde51fad0, 0x0000117c } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x40C92555UL, 0x000000E5UL }, /* fpgm */ + { 0xDE51FAD0UL, 0x0000117CUL } /* prep */ }, { /* NEC fankyo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x85e47664, 0x000000e5 }, /* fpgm */ - { 0xa6c62831, 0x00001caa } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x85E47664UL, 0x000000E5UL }, /* fpgm */ + { 0xA6C62831UL, 0x00001CAAUL } /* prep */ }, { /* NEC fanrgo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x2d891cfd, 0x0000019d }, /* fpgm */ - { 0xa0604633, 0x00001de8 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x2D891CFDUL, 0x0000019DUL }, /* fpgm */ + { 0xA0604633UL, 0x00001DE8UL } /* prep */ }, { /* NEC fangot5.ttc */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40aa774c, 0x000001cb }, /* fpgm */ - { 0x9b5caa96, 0x00001f9a } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x40AA774CUL, 0x000001CBUL }, /* fpgm */ + { 0x9B5CAA96UL, 0x00001F9AUL } /* prep */ }, { /* NEC fanmin3.ttc */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x0d3de9cb, 0x00000141 }, /* fpgm */ - { 0xd4127766, 0x00002280 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x0D3DE9CBUL, 0x00000141UL }, /* fpgm */ + { 0xD4127766UL, 0x00002280UL } /* prep */ }, { /* NEC FA-Gothic, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x4a692698, 0x000001f0 }, /* fpgm */ - { 0x340d4346, 0x00001fca } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x4A692698UL, 0x000001F0UL }, /* fpgm */ + { 0x340D4346UL, 0x00001FCAUL } /* prep */ }, { /* NEC FA-Minchou, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0xcd34c604, 0x00000166 }, /* fpgm */ - { 0x6cf31046, 0x000022b0 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0xCD34C604UL, 0x00000166UL }, /* fpgm */ + { 0x6CF31046UL, 0x000022B0UL } /* prep */ }, { /* NEC FA-RoundGothicB, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x5da75315, 0x0000019d }, /* fpgm */ - { 0x40745a5f, 0x000022e0 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x5DA75315UL, 0x0000019DUL }, /* fpgm */ + { 0x40745A5FUL, 0x000022E0UL } /* prep */ }, { /* NEC FA-RoundGothicM, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0xf055fc48, 0x000001c2 }, /* fpgm */ - { 0x3900ded3, 0x00001e18 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0xF055FC48UL, 0x000001C2UL }, /* fpgm */ + { 0x3900DED3UL, 0x00001E18UL } /* prep */ } }; @@ -396,11 +398,11 @@ for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) { if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) return TRUE; } @@ -489,7 +491,10 @@ /* <Input> */ /* stream :: The source font stream. */ /* */ - /* face_index :: The index of the font face in the resource. */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: Number of additional generic parameters. Ignored. */ /* */ @@ -532,6 +537,10 @@ /* check that we have a valid TrueType file */ error = sfnt->init_face( stream, face, face_index, num_params, params ); + + /* Stream may have changed. */ + stream = face->root.stream; + if ( error ) goto Exit; @@ -594,7 +603,7 @@ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; } -#else +#else /* !FT_CONFIG_OPTION_INCREMENTAL */ if ( !error ) error = tt_face_load_loca( face, stream ); @@ -618,32 +627,55 @@ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; } -#endif +#endif /* !FT_CONFIG_OPTION_INCREMENTAL */ } -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_Bool unpatented_hinting; - int i; - + FT_Int instance_index = face_index >> 16; - /* Determine whether unpatented hinting is to be used for this face. */ - unpatented_hinting = FT_BOOL - ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); - for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) - if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) - unpatented_hinting = TRUE; + if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && + instance_index > 0 ) + { + error = TT_Get_MM_Var( face, NULL ); + if ( error ) + goto Exit; - if ( !unpatented_hinting ) - ttface->internal->ignore_unpatented_hinter = TRUE; + if ( face->blend->mmvar->namedstyle ) + { + FT_Memory memory = ttface->memory; + + FT_Var_Named_Style* named_style; + FT_String* style_name; + + + /* in `face_index', the instance index starts with value 1 */ + named_style = face->blend->mmvar->namedstyle + instance_index - 1; + error = sfnt->get_name( face, + (FT_UShort)named_style->strid, + &style_name ); + if ( error ) + goto Exit; + + /* set style name; if already set, replace it */ + if ( face->root.style_name ) + FT_FREE( face->root.style_name ); + face->root.style_name = style_name; + + /* finally, select the named instance */ + error = TT_Set_Var_Design( face, + face->blend->mmvar->num_axis, + named_style->coords ); + if ( error ) + goto Exit; + } + } } -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && - !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* initialize standard glyph loading routines */ TT_Init_Glyph_Loading( face ); @@ -746,16 +778,11 @@ FT_Error error; - /* debugging instances have their own context */ - if ( size->debug ) - exec = size->context; - else - exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; - - if ( !exec ) - return FT_THROW( Could_Not_Find_Context ); + exec = size->context; - TT_Load_Context( exec, face, size ); + error = TT_Load_Context( exec, face, size ); + if ( error ) + return error; exec->callTop = 0; exec->top = 0; @@ -788,7 +815,7 @@ TT_Set_CodeRange( exec, tt_coderange_font, face->font_program, - face->font_program_size ); + (FT_Long)face->font_program_size ); /* disable CVT and glyph programs coderange */ TT_Clear_CodeRange( exec, tt_coderange_cvt ); @@ -796,18 +823,16 @@ if ( face->font_program_size > 0 ) { - error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); + TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); - if ( !error ) - { - FT_TRACE4(( "Executing `fpgm' table.\n" )); - - error = face->interpreter( exec ); - } + FT_TRACE4(( "Executing `fpgm' table.\n" )); + error = face->interpreter( exec ); } else error = FT_Err_Ok; + size->bytecode_ready = error; + if ( !error ) TT_Save_Context( exec, size ); @@ -840,16 +865,11 @@ FT_Error error; - /* debugging instances have their own context */ - if ( size->debug ) - exec = size->context; - else - exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; - - if ( !exec ) - return FT_THROW( Could_Not_Find_Context ); + exec = size->context; - TT_Load_Context( exec, face, size ); + error = TT_Load_Context( exec, face, size ); + if ( error ) + return error; exec->callTop = 0; exec->top = 0; @@ -861,24 +881,23 @@ TT_Set_CodeRange( exec, tt_coderange_cvt, face->cvt_program, - face->cvt_program_size ); + (FT_Long)face->cvt_program_size ); TT_Clear_CodeRange( exec, tt_coderange_glyph ); if ( face->cvt_program_size > 0 ) { - error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); + TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); - if ( !error && !size->debug ) - { - FT_TRACE4(( "Executing `prep' table.\n" )); + FT_TRACE4(( "Executing `prep' table.\n" )); - error = face->interpreter( exec ); - } + error = face->interpreter( exec ); } else error = FT_Err_Ok; + size->cvt_ready = error; + /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */ /* graphics state variables to be modified by the CVT program. */ @@ -907,10 +926,6 @@ return error; } -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - -#ifdef TT_USE_BYTECODE_INTERPRETER static void tt_size_done_bytecode( FT_Size ftsize ) @@ -919,12 +934,10 @@ TT_Face face = (TT_Face)ftsize->face; FT_Memory memory = face->root.memory; - - if ( size->debug ) + if ( size->context ) { - /* the debug context must be deleted by the debugger itself */ + TT_Done_Context( size->context ); size->context = NULL; - size->debug = FALSE; } FT_FREE( size->cvt ); @@ -948,8 +961,8 @@ size->max_func = 0; size->max_ins = 0; - size->bytecode_ready = 0; - size->cvt_ready = 0; + size->bytecode_ready = -1; + size->cvt_ready = -1; } @@ -963,14 +976,25 @@ TT_Size size = (TT_Size)ftsize; TT_Face face = (TT_Face)ftsize->face; FT_Memory memory = face->root.memory; - FT_Int i; FT_UShort n_twilight; TT_MaxProfile* maxp = &face->max_profile; - size->bytecode_ready = 1; - size->cvt_ready = 0; + /* clean up bytecode related data */ + FT_FREE( size->function_defs ); + FT_FREE( size->instruction_defs ); + FT_FREE( size->cvt ); + FT_FREE( size->storage ); + + if ( size->context ) + TT_Done_Context( size->context ); + tt_glyphzone_done( &size->twilight ); + + size->bytecode_ready = -1; + size->cvt_ready = -1; + + size->context = TT_New_Context( (TT_Driver)face->root.driver ); size->max_function_defs = maxp->maxFunctionDefs; size->max_instruction_defs = maxp->maxInstructionDefs; @@ -992,9 +1016,11 @@ metrics->rotated = FALSE; metrics->stretched = FALSE; - /* set default compensation (all 0) */ - for ( i = 0; i < 4; i++ ) - metrics->compensations[i] = 0; + /* set default engine compensation */ + metrics->compensations[0] = 0; /* gray */ + metrics->compensations[1] = 0; /* black */ + metrics->compensations[2] = 0; /* white */ + metrics->compensations[3] = 0; /* reserved */ } /* allocate function defs, instruction defs, cvt, and storage area */ @@ -1030,7 +1056,15 @@ } /* Fine, now run the font program! */ + + /* In case of an error while executing `fpgm', we intentionally don't */ + /* clean up immediately – bugs in the `fpgm' are so fundamental that */ + /* all following hinting calls should fail. Additionally, `fpgm' is */ + /* to be executed just once; calling it again is completely useless */ + /* and might even lead to extremely slow behaviour if it is malformed */ + /* (containing an infinite loop, for example). */ error = tt_size_run_fpgm( size, pedantic ); + return error; Exit: if ( error ) @@ -1047,15 +1081,14 @@ FT_Error error = FT_Err_Ok; - if ( !size->bytecode_ready ) - { + if ( size->bytecode_ready < 0 ) error = tt_size_init_bytecode( (FT_Size)size, pedantic ); - if ( error ) - goto Exit; - } + + if ( error || size->bytecode_ready ) + goto Exit; /* rescale CVT when needed */ - if ( !size->cvt_ready ) + if ( size->cvt_ready < 0 ) { FT_UInt i; TT_Face face = (TT_Face)size->root.face; @@ -1082,8 +1115,6 @@ size->GS = tt_default_graphics_state; error = tt_size_run_prep( size, pedantic ); - if ( !error ) - size->cvt_ready = 1; } Exit: @@ -1113,9 +1144,10 @@ TT_Size size = (TT_Size)ttsize; FT_Error error = FT_Err_Ok; + #ifdef TT_USE_BYTECODE_INTERPRETER - size->bytecode_ready = 0; - size->cvt_ready = 0; + size->bytecode_ready = -1; + size->cvt_ready = -1; #endif size->ttmetrics.valid = FALSE; @@ -1143,8 +1175,7 @@ #ifdef TT_USE_BYTECODE_INTERPRETER - if ( size->bytecode_ready ) - tt_size_done_bytecode( ttsize ); + tt_size_done_bytecode( ttsize ); #endif size->ttmetrics.valid = FALSE; @@ -1224,7 +1255,7 @@ } #ifdef TT_USE_BYTECODE_INTERPRETER - size->cvt_ready = 0; + size->cvt_ready = -1; #endif /* TT_USE_BYTECODE_INTERPRETER */ if ( !error ) @@ -1256,14 +1287,12 @@ TT_Driver driver = (TT_Driver)ttdriver; - - if ( !TT_New_Context( driver ) ) - return FT_THROW( Could_Not_Find_Context ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - driver->interpreter_version = TT_INTERPRETER_VERSION_38; -#else driver->interpreter_version = TT_INTERPRETER_VERSION_35; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + driver->interpreter_version = TT_INTERPRETER_VERSION_38; +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + driver->interpreter_version = TT_INTERPRETER_VERSION_40; #endif #else /* !TT_USE_BYTECODE_INTERPRETER */ @@ -1290,20 +1319,7 @@ FT_LOCAL_DEF( void ) tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ { -#ifdef TT_USE_BYTECODE_INTERPRETER - TT_Driver driver = (TT_Driver)ttdriver; - - - /* destroy the execution context */ - if ( driver->context ) - { - TT_Done_Context( driver->context ); - driver->context = NULL; - } -#else FT_UNUSED( ttdriver ); -#endif - } diff --git a/drivers/freetype/src/truetype/ttobjs.h b/drivers/freetype/src/truetype/ttobjs.h index a11dd3752a..ed61a7d517 100644 --- a/drivers/freetype/src/truetype/ttobjs.h +++ b/drivers/freetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2009, 2011-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTOBJS_H__ -#define __TTOBJS_H__ +#ifndef TTOBJS_H_ +#define TTOBJS_H_ #include <ft2build.h> @@ -39,17 +39,6 @@ FT_BEGIN_HEADER typedef struct TT_DriverRec_* TT_Driver; - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_Instance */ - /* */ - /* <Description> */ - /* A handle to a TrueType size object. */ - /* */ - typedef struct TT_SizeRec_* TT_Size; - - /*************************************************************************/ /* */ /* <Type> */ @@ -83,10 +72,6 @@ FT_BEGIN_HEADER FT_UnitVector projVector; FT_UnitVector freeVector; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_Bool both_x_axis; -#endif - FT_Long loop; FT_F26Dot6 minimum_distance; FT_Int round_state; @@ -95,8 +80,8 @@ FT_BEGIN_HEADER FT_F26Dot6 control_value_cutin; FT_F26Dot6 single_width_cutin; FT_F26Dot6 single_width_value; - FT_Short delta_base; - FT_Short delta_shift; + FT_UShort delta_base; + FT_UShort delta_shift; FT_Byte instruct_control; /* According to Greg Hitchcock from Microsoft, the `scan_control' */ @@ -160,7 +145,7 @@ FT_BEGIN_HEADER typedef struct TT_CodeRange_ { FT_Byte* base; - FT_ULong size; + FT_Long size; } TT_CodeRange; @@ -324,17 +309,12 @@ FT_BEGIN_HEADER TT_GlyphZoneRec twilight; /* The instance's twilight zone */ - /* debugging variables */ - - /* When using the debugger, we must keep the */ - /* execution context tied to the instance */ - /* object rather than asking it on demand. */ - - FT_Bool debug; TT_ExecContext context; - FT_Bool bytecode_ready; - FT_Bool cvt_ready; + /* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */ + /* otherwise it is the returned error code */ + FT_Error bytecode_ready; + FT_Error cvt_ready; #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -349,7 +329,6 @@ FT_BEGIN_HEADER { FT_DriverRec root; - TT_ExecContext context; /* execution context */ TT_GlyphZoneRec zone; /* glyph loader points zone */ FT_UInt interpreter_version; @@ -436,7 +415,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTOBJS_H__ */ +#endif /* TTOBJS_H_ */ /* END */ diff --git a/drivers/freetype/src/truetype/ttpic.c b/drivers/freetype/src/truetype/ttpic.c index edefae72c5..54a5b8bed6 100644 --- a/drivers/freetype/src/truetype/ttpic.c +++ b/drivers/freetype/src/truetype/ttpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for truetype module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/truetype/ttpic.h b/drivers/freetype/src/truetype/ttpic.h index cfb4ee6281..f725865c5c 100644 --- a/drivers/freetype/src/truetype/ttpic.h +++ b/drivers/freetype/src/truetype/ttpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for truetype module. */ /* */ -/* Copyright 2009, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,11 +16,12 @@ /***************************************************************************/ -#ifndef __TTPIC_H__ -#define __TTPIC_H__ +#ifndef TTPIC_H_ +#define TTPIC_H_ -FT_BEGIN_HEADER +#include FT_INTERNAL_PIC_H + #ifndef FT_CONFIG_OPTION_PIC @@ -37,6 +38,8 @@ FT_BEGIN_HEADER #include FT_SERVICE_PROPERTIES_H +FT_BEGIN_HEADER + typedef struct TTModulePIC_ { FT_ServiceDescRec* tt_services; @@ -68,14 +71,13 @@ FT_BEGIN_HEADER FT_Error tt_driver_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ - -FT_END_HEADER - -#endif /* __TTPIC_H__ */ +#endif /* TTPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/truetype/ttpload.c b/drivers/freetype/src/truetype/ttpload.c index 9723a515b9..ca158ac50b 100644 --- a/drivers/freetype/src/truetype/ttpload.c +++ b/drivers/freetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (body). */ /* */ -/* Copyright 1996-2002, 2004-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -118,40 +118,52 @@ /* we only handle the case where `maxp' gives a larger value */ if ( face->num_locations <= (FT_ULong)face->root.num_glyphs ) { - FT_Long new_loca_len = - ( (FT_Long)( face->root.num_glyphs ) + 1 ) << shift; + FT_ULong new_loca_len = + ( (FT_ULong)face->root.num_glyphs + 1 ) << shift; TT_Table entry = face->dir_tables; TT_Table limit = entry + face->num_tables; - FT_Long pos = FT_Stream_Pos( stream ); - FT_Long dist = 0x7FFFFFFFL; + FT_Long pos = (FT_Long)FT_STREAM_POS(); + FT_Long dist = 0x7FFFFFFFL; + FT_Bool found = 0; /* compute the distance to next table in font file */ for ( ; entry < limit; entry++ ) { - FT_Long diff = entry->Offset - pos; + FT_Long diff = (FT_Long)entry->Offset - pos; if ( diff > 0 && diff < dist ) - dist = diff; + { + dist = diff; + found = 1; + } } - if ( entry == limit ) + if ( !found ) { /* `loca' is the last table */ - dist = stream->size - pos; + dist = (FT_Long)stream->size - pos; } - if ( new_loca_len <= dist ) + if ( new_loca_len <= (FT_ULong)dist ) { - face->num_locations = face->root.num_glyphs + 1; + face->num_locations = (FT_ULong)face->root.num_glyphs + 1; table_len = new_loca_len; FT_TRACE2(( "adjusting num_locations to %d\n", face->num_locations )); } + else + { + face->root.num_glyphs = face->num_locations + ? (FT_Long)face->num_locations - 1 : 0; + + FT_TRACE2(( "adjusting num_glyphs to %d\n", + face->root.num_glyphs )); + } } } @@ -214,7 +226,8 @@ if ( pos1 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," + " too large offset=0x%08lx found for gid=0x%04lx,\n" + " " " exceeding the end of glyf table (0x%08lx)\n", pos1, gindex, face->glyf_len )); *asize = 0; @@ -224,7 +237,8 @@ if ( pos2 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," + " too large offset=0x%08lx found for gid=0x%04lx,\n" + " " " truncate at the end of glyf table (0x%08lx)\n", pos2, gindex + 1, face->glyf_len )); pos2 = face->glyf_len; @@ -508,9 +522,9 @@ record_size = FT_NEXT_ULONG( p ); /* The maximum number of bytes in an hdmx device record is the */ - /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ - /* the reason why `record_size' is a long (which we read as */ - /* unsigned long for convenience). In practice, two bytes */ + /* maximum number of glyphs + 2; this is 0xFFFF + 2, thus */ + /* explaining why `record_size' is a long (which we read as */ + /* unsigned long for convenience). In practice, two bytes are */ /* sufficient to hold the size value. */ /* */ /* There are at least two fonts, HANNOM-A and HANNOM-B version */ @@ -522,8 +536,10 @@ record_size &= 0xFFFFU; /* The limit for `num_records' is a heuristic value. */ - - if ( version != 0 || num_records > 255 || record_size > 0x10001L ) + if ( version != 0 || + num_records > 255 || + record_size > 0x10001L || + record_size < 4 ) { error = FT_THROW( Invalid_File_Format ); goto Fail; diff --git a/drivers/freetype/src/truetype/ttpload.h b/drivers/freetype/src/truetype/ttpload.h index f61ac079ce..aa2e38e6e7 100644 --- a/drivers/freetype/src/truetype/ttpload.h +++ b/drivers/freetype/src/truetype/ttpload.h @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTPLOAD_H__ -#define __TTPLOAD_H__ +#ifndef TTPLOAD_H_ +#define TTPLOAD_H_ #include <ft2build.h> @@ -69,7 +69,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTPLOAD_H__ */ +#endif /* TTPLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/truetype/ttsubpix.c b/drivers/freetype/src/truetype/ttsubpix.c index 28470ad655..03950960a4 100644 --- a/drivers/freetype/src/truetype/ttsubpix.c +++ b/drivers/freetype/src/truetype/ttsubpix.c @@ -4,7 +4,7 @@ /* */ /* TrueType Subpixel Hinting. */ /* */ -/* Copyright 2010-2013 by */ +/* Copyright 2010-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,7 +27,7 @@ #include "ttsubpix.h" -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -63,8 +63,8 @@ /* rules below. A blank entry "" is required at the end of these! */ #define FAMILY_CLASS_RULES_SIZE 7 - static const SPH_Font_Class FAMILY_CLASS_Rules - [FAMILY_CLASS_RULES_SIZE] = + static const SPH_Font_Class FAMILY_CLASS_Rules + [FAMILY_CLASS_RULES_SIZE] = { { "MS Legacy Fonts", { "Aharoni", @@ -223,8 +223,8 @@ /* rules below. A blank entry "" is required at the end of these! */ #define STYLE_CLASS_RULES_SIZE 5 - const SPH_Font_Class STYLE_CLASS_Rules - [STYLE_CLASS_RULES_SIZE] = + static const SPH_Font_Class STYLE_CLASS_Rules + [STYLE_CLASS_RULES_SIZE] = { { "Regular Class", { "Regular", @@ -279,18 +279,18 @@ /* Force special legacy fixes for fonts. */ #define COMPATIBILITY_MODE_RULES_SIZE 1 - const SPH_TweakRule COMPATIBILITY_MODE_Rules - [COMPATIBILITY_MODE_RULES_SIZE] = + static const SPH_TweakRule COMPATIBILITY_MODE_Rules + [COMPATIBILITY_MODE_RULES_SIZE] = { - { "-", 0, "", 0 }, + { "Verdana Clones", 0, "", 0 }, }; /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting. */ #define PIXEL_HINTING_RULES_SIZE 2 - const SPH_TweakRule PIXEL_HINTING_Rules - [PIXEL_HINTING_RULES_SIZE] = + static const SPH_TweakRule PIXEL_HINTING_Rules + [PIXEL_HINTING_RULES_SIZE] = { /* these characters are almost always safe */ { "Courier New", 12, "Italic", 'z' }, @@ -301,8 +301,8 @@ /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */ #define DO_SHPIX_RULES_SIZE 1 - const SPH_TweakRule DO_SHPIX_Rules - [DO_SHPIX_RULES_SIZE] = + static const SPH_TweakRule DO_SHPIX_Rules + [DO_SHPIX_RULES_SIZE] = { { "-", 0, "", 0 }, }; @@ -312,8 +312,8 @@ /* boundary and don't move that point to a Y pixel boundary. */ #define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 4 - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules - [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = + static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules + [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = { /* fix vwxyz thinness*/ { "Consolas", 0, "", 0 }, @@ -328,8 +328,8 @@ #define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions + [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = { /* Fixes < and > */ { "Courier New", 0, "Regular", 0 }, @@ -340,8 +340,8 @@ /* boundary and don't move that point to a Y pixel boundary. */ #define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE 2 - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules - [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] = + static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules + [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] = { /* Maintain thickness of diagonal in 'N' */ { "Times New Roman", 0, "Regular/Bold Class", 'N' }, @@ -352,8 +352,8 @@ /* Skip Y moves that move a point off a Y pixel boundary. */ #define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 1 - const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules - [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = + static const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules + [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = { { "-", 0, "", 0 }, }; @@ -361,8 +361,8 @@ #define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + static const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions + [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = { { "-", 0, "", 0 }, }; @@ -371,8 +371,8 @@ /* Round moves that don't move a point to a Y pixel boundary. */ #define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 2 - const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules - [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = + static const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules + [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = { /* Droid font instructions don't snap Y to pixels */ { "Droid Sans", 0, "Regular/Italic Class", 0 }, @@ -382,8 +382,8 @@ #define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions - [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + static const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions + [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = { { "-", 0, "", 0 }, }; @@ -392,8 +392,8 @@ /* Allow a Direct_Move along X freedom vector if matched. */ #define ALLOW_X_DMOVE_RULES_SIZE 1 - const SPH_TweakRule ALLOW_X_DMOVE_Rules - [ALLOW_X_DMOVE_RULES_SIZE] = + static const SPH_TweakRule ALLOW_X_DMOVE_Rules + [ALLOW_X_DMOVE_RULES_SIZE] = { /* Fixes vanishing diagonal in 4 */ { "Verdana", 0, "Regular", '4' }, @@ -403,8 +403,8 @@ /* Return MS rasterizer version 35 if matched. */ #define RASTERIZER_35_RULES_SIZE 8 - const SPH_TweakRule RASTERIZER_35_Rules - [RASTERIZER_35_RULES_SIZE] = + static const SPH_TweakRule RASTERIZER_35_Rules + [RASTERIZER_35_RULES_SIZE] = { /* This seems to be the only way to make these look good */ { "Times New Roman", 0, "Regular", 'i' }, @@ -421,8 +421,8 @@ /* Don't round to the subpixel grid. Round to pixel grid. */ #define NORMAL_ROUND_RULES_SIZE 1 - const SPH_TweakRule NORMAL_ROUND_Rules - [NORMAL_ROUND_RULES_SIZE] = + static const SPH_TweakRule NORMAL_ROUND_Rules + [NORMAL_ROUND_RULES_SIZE] = { /* Fix serif thickness for certain ppems */ /* Can probably be generalized somehow */ @@ -433,8 +433,8 @@ /* Skip IUP instructions if matched. */ #define SKIP_IUP_RULES_SIZE 1 - const SPH_TweakRule SKIP_IUP_Rules - [SKIP_IUP_RULES_SIZE] = + static const SPH_TweakRule SKIP_IUP_Rules + [SKIP_IUP_RULES_SIZE] = { { "Arial", 13, "Regular", 'a' }, }; @@ -443,8 +443,8 @@ /* Skip MIAP Twilight hack if matched. */ #define MIAP_HACK_RULES_SIZE 1 - const SPH_TweakRule MIAP_HACK_Rules - [MIAP_HACK_RULES_SIZE] = + static const SPH_TweakRule MIAP_HACK_Rules + [MIAP_HACK_RULES_SIZE] = { { "Geneva", 12, "", 0 }, }; @@ -453,8 +453,8 @@ /* Skip DELTAP instructions if matched. */ #define ALWAYS_SKIP_DELTAP_RULES_SIZE 23 - const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules - [ALWAYS_SKIP_DELTAP_RULES_SIZE] = + static const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules + [ALWAYS_SKIP_DELTAP_RULES_SIZE] = { { "Georgia", 0, "Regular", 'k' }, /* fix various problems with e in different versions */ @@ -489,8 +489,8 @@ /* Always do DELTAP instructions if matched. */ #define ALWAYS_DO_DELTAP_RULES_SIZE 1 - const SPH_TweakRule ALWAYS_DO_DELTAP_Rules - [ALWAYS_DO_DELTAP_RULES_SIZE] = + static const SPH_TweakRule ALWAYS_DO_DELTAP_Rules + [ALWAYS_DO_DELTAP_RULES_SIZE] = { { "-", 0, "", 0 }, }; @@ -744,7 +744,7 @@ #endif /* FORCE_NATURAL_WIDTHS */ - FT_LOCAL_DEF( FT_Bool ) + static FT_Bool is_member_of_family_class( const FT_String* detected_font_name, const FT_String* rule_font_name ) { @@ -779,7 +779,7 @@ } - FT_LOCAL_DEF( FT_Bool ) + static FT_Bool is_member_of_style_class( const FT_String* detected_font_style, const FT_String* rule_font_style ) { @@ -903,9 +903,9 @@ sph_set_tweaks( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_String* family = face->root.family_name; - int ppem = loader->size->metrics.x_ppem; + FT_UInt ppem = loader->size->metrics.x_ppem; FT_String* style = face->root.style_name; @@ -956,7 +956,7 @@ if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 ) { loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - loader->exec->size->cvt_ready = FALSE; + loader->exec->size->cvt_ready = -1; tt_size_ready_bytecode( loader->exec->size, @@ -971,7 +971,7 @@ SPH_OPTION_SET_RASTERIZER_VERSION ) { loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - loader->exec->size->cvt_ready = FALSE; + loader->exec->size->cvt_ready = -1; tt_size_ready_bytecode( loader->exec->size, @@ -1000,12 +1000,12 @@ } } -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#else /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* ANSI C doesn't like empty source files */ typedef int _tt_subpix_dummy; -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* END */ diff --git a/drivers/freetype/src/truetype/ttsubpix.h b/drivers/freetype/src/truetype/ttsubpix.h index 8a54fc7cc7..86844da666 100644 --- a/drivers/freetype/src/truetype/ttsubpix.h +++ b/drivers/freetype/src/truetype/ttsubpix.h @@ -4,7 +4,7 @@ /* */ /* TrueType Subpixel Hinting. */ /* */ -/* Copyright 2010-2013 by */ +/* Copyright 2010-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTSUBPIX_H__ -#define __TTSUBPIX_H__ +#ifndef TTSUBPIX_H_ +#define TTSUBPIX_H_ #include <ft2build.h> #include "ttobjs.h" @@ -27,7 +27,7 @@ FT_BEGIN_HEADER -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -50,26 +50,26 @@ FT_BEGIN_HEADER /* Tweak flags that are set for each glyph by the below rules. */ /* */ /* */ -#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001 -#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002 -#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004 -#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008 -#define SPH_TWEAK_DEEMBOLDEN 0x0000010 -#define SPH_TWEAK_DO_SHPIX 0x0000020 -#define SPH_TWEAK_EMBOLDEN 0x0000040 -#define SPH_TWEAK_MIAP_HACK 0x0000080 -#define SPH_TWEAK_NORMAL_ROUND 0x0000100 -#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200 -#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400 -#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800 -#define SPH_TWEAK_PIXEL_HINTING 0x0001000 -#define SPH_TWEAK_RASTERIZER_35 0x0002000 -#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000 -#define SPH_TWEAK_SKIP_IUP 0x0008000 -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000 -#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000 -#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000 -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000 +#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001UL +#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002UL +#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004UL +#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008UL +#define SPH_TWEAK_DEEMBOLDEN 0x0000010UL +#define SPH_TWEAK_DO_SHPIX 0x0000020UL +#define SPH_TWEAK_EMBOLDEN 0x0000040UL +#define SPH_TWEAK_MIAP_HACK 0x0000080UL +#define SPH_TWEAK_NORMAL_ROUND 0x0000100UL +#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200UL +#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400UL +#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800UL +#define SPH_TWEAK_PIXEL_HINTING 0x0001000UL +#define SPH_TWEAK_RASTERIZER_35 0x0002000UL +#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000UL +#define SPH_TWEAK_SKIP_IUP 0x0008000UL +#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000UL +#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000UL +#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000UL +#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000UL FT_LOCAL( FT_Bool ) @@ -100,11 +100,12 @@ FT_BEGIN_HEADER #define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE #define SPH_OPTION_SET_RASTERIZER_VERSION 38 -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ FT_END_HEADER -#endif /* __TTSUBPIX_H__ */ +#endif /* TTSUBPIX_H_ */ + /* END */ diff --git a/drivers/freetype/src/type1/Jamfile b/drivers/freetype/src/type1/Jamfile index 8e366baae5..948b40854a 100644 --- a/drivers/freetype/src/type1/Jamfile +++ b/drivers/freetype/src/type1/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/type1 Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,13 @@ SubDir FT2_TOP $(FT2_SRC_DIR) type1 ; if $(FT2_MULTI) { - _sources = t1afm t1driver t1objs t1load t1gload t1parse ; + _sources = t1afm + t1driver + t1gload + t1load + t1objs + t1parse + ; } else { diff --git a/drivers/freetype/src/type1/module.mk b/drivers/freetype/src/type1/module.mk index ade0210d76..d7ab520c74 100644 --- a/drivers/freetype/src/type1/module.mk +++ b/drivers/freetype/src/type1/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/type1/rules.mk b/drivers/freetype/src/type1/rules.mk index 15087b0304..bdec29479f 100644 --- a/drivers/freetype/src/type1/rules.mk +++ b/drivers/freetype/src/type1/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ T1_DIR := $(SRC_DIR)/type1 # compilation flags for the driver # -T1_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T1_DIR)) +T1_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(T1_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Type1 driver sources (i.e., C files) diff --git a/drivers/freetype/src/type1/t1afm.c b/drivers/freetype/src/type1/t1afm.c index de9c1997c4..bbd843c1c3 100644 --- a/drivers/freetype/src/type1/t1afm.c +++ b/drivers/freetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -169,8 +169,8 @@ goto Exit; /* now, read each kern pair */ - kp = fi->KernPairs; - limit = p + 4 * fi->NumKernPair; + kp = fi->KernPairs; + limit = p + 4 * fi->NumKernPair; /* PFM kerning data are stored by encoding rather than glyph index, */ /* so find the PostScript charmap of this font and install it */ @@ -197,7 +197,7 @@ /* encoding of first glyph (1 byte) */ /* encoding of second glyph (1 byte) */ /* offset (little-endian short) */ - for ( ; p < limit ; p += 4 ) + for ( ; p < limit; p += 4 ) { kp->index1 = FT_Get_Char_Index( t1_face, p[0] ); kp->index2 = FT_Get_Char_Index( t1_face, p[1] ); @@ -239,9 +239,19 @@ AFM_ParserRec parser; AFM_FontInfo fi = NULL; FT_Error error = FT_ERR( Unknown_File_Format ); - T1_Font t1_font = &( (T1_Face)t1_face )->type1; + T1_Face face = (T1_Face)t1_face; + T1_Font t1_font = &face->type1; + if ( face->afm_data ) + { + FT_TRACE1(( "T1_Read_Metrics:" + " Freeing previously attached metrics data.\n" )); + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); + + face->afm_data = NULL; + } + if ( FT_NEW( fi ) || FT_FRAME_ENTER( stream->size ) ) goto Exit; @@ -250,7 +260,7 @@ fi->Ascender = t1_font->font_bbox.yMax; fi->Descender = t1_font->font_bbox.yMin; - psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; + psaux = (PSAux_Service)face->psaux; if ( psaux->afm_parser_funcs ) { error = psaux->afm_parser_funcs->init( &parser, @@ -298,7 +308,7 @@ if ( fi->NumKernPair ) { t1_face->face_flags |= FT_FACE_FLAG_KERNING; - ( (T1_Face)t1_face )->afm_data = fi; + face->afm_data = fi; fi = NULL; } } @@ -362,7 +372,7 @@ FT_Fixed* kerning ) { AFM_FontInfo fi = (AFM_FontInfo)( (T1_Face)face )->afm_data; - FT_Int i; + FT_UInt i; if ( !fi ) diff --git a/drivers/freetype/src/type1/t1afm.h b/drivers/freetype/src/type1/t1afm.h index 8eb1764de7..3a864f2379 100644 --- a/drivers/freetype/src/type1/t1afm.h +++ b/drivers/freetype/src/type1/t1afm.h @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1AFM_H__ -#define __T1AFM_H__ +#ifndef T1AFM_H_ +#define T1AFM_H_ #include <ft2build.h> #include "t1objs.h" @@ -48,7 +48,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1AFM_H__ */ +#endif /* T1AFM_H_ */ /* END */ diff --git a/drivers/freetype/src/type1/t1driver.c b/drivers/freetype/src/type1/t1driver.c index 697288d66d..f1e60d4523 100644 --- a/drivers/freetype/src/type1/t1driver.c +++ b/drivers/freetype/src/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,10 +29,11 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_MULTIPLE_MASTERS_H #include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H @@ -87,8 +88,8 @@ static const FT_Service_GlyphDictRec t1_service_glyph_dict = { - (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t1_get_name_index + (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)t1_get_name_index /* name_index */ }; @@ -106,7 +107,7 @@ static const FT_Service_PsFontNameRec t1_service_ps_name = { - (FT_PsName_GetFunc)t1_get_ps_name + (FT_PsName_GetFunc)t1_get_ps_name /* get_ps_font_name */ }; @@ -118,11 +119,11 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = { - (FT_Get_MM_Func) T1_Get_Multi_Master, - (FT_Set_MM_Design_Func) T1_Set_MM_Design, - (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, - (FT_Get_MM_Var_Func) T1_Get_MM_Var, - (FT_Set_Var_Design_Func)T1_Set_Var_Design + (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ + (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)T1_Set_Var_Design /* set_var_design */ }; #endif @@ -176,9 +177,11 @@ PS_Dict_Keys key, FT_UInt idx, void *value, - FT_Long value_len ) + FT_Long value_len_ ) { - FT_Long retval = -1; + FT_ULong retval = 0; /* always >= 1 if valid */ + FT_ULong value_len = value_len_ < 0 ? 0 : (FT_ULong)value_len_; + T1_Face t1face = (T1_Face)face; T1_Font type1 = &t1face->type1; @@ -225,7 +228,7 @@ if ( idx < sizeof ( type1->font_bbox ) / sizeof ( type1->font_bbox.xMin ) ) { - FT_Fixed val = 0; + FT_Fixed val = 0; retval = sizeof ( val ); @@ -258,7 +261,7 @@ break; case PS_DICT_FONT_NAME: - retval = (FT_Long)( ft_strlen( type1->font_name ) + 1 ); + retval = ft_strlen( type1->font_name ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_name ), retval ); break; @@ -278,7 +281,7 @@ case PS_DICT_CHAR_STRING_KEY: if ( idx < (FT_UInt)type1->num_glyphs ) { - retval = (FT_Long)( ft_strlen( type1->glyph_names[idx] ) + 1 ); + retval = ft_strlen( type1->glyph_names[idx] ) + 1; if ( value && value_len >= retval ) { ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval ); @@ -290,7 +293,7 @@ case PS_DICT_CHAR_STRING: if ( idx < (FT_UInt)type1->num_glyphs ) { - retval = (FT_Long)( type1->charstrings_len[idx] + 1 ); + retval = type1->charstrings_len[idx] + 1; if ( value && value_len >= retval ) { ft_memcpy( value, (void *)( type1->charstrings[idx] ), @@ -310,7 +313,7 @@ if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY && idx < (FT_UInt)type1->encoding.num_chars ) { - retval = (FT_Long)( ft_strlen( type1->encoding.char_name[idx] ) + 1 ); + retval = ft_strlen( type1->encoding.char_name[idx] ) + 1; if ( value && value_len >= retval ) { ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ), @@ -327,13 +330,37 @@ break; case PS_DICT_SUBR: - if ( idx < (FT_UInt)type1->num_subrs ) { - retval = (FT_Long)( type1->subrs_len[idx] + 1 ); - if ( value && value_len >= retval ) + FT_Bool ok = 0; + + + if ( type1->subrs_hash ) { - ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + /* convert subr index to array index */ + size_t* val = ft_hash_num_lookup( (FT_Int)idx, + type1->subrs_hash ); + + + if ( val ) + { + idx = *val; + ok = 1; + } + } + else + { + if ( idx < (FT_UInt)type1->num_subrs ) + ok = 1; + } + + if ( ok ) + { + retval = type1->subrs_len[idx] + 1; + if ( value && value_len >= retval ) + { + ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); + ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + } } } break; @@ -523,31 +550,31 @@ break; case PS_DICT_VERSION: - retval = (FT_Long)( ft_strlen( type1->font_info.version ) + 1 ); + retval = ft_strlen( type1->font_info.version ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.version ), retval ); break; case PS_DICT_NOTICE: - retval = (FT_Long)( ft_strlen( type1->font_info.notice ) + 1 ); + retval = ft_strlen( type1->font_info.notice ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.notice ), retval ); break; case PS_DICT_FULL_NAME: - retval = (FT_Long)( ft_strlen( type1->font_info.full_name ) + 1 ); + retval = ft_strlen( type1->font_info.full_name ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.full_name ), retval ); break; case PS_DICT_FAMILY_NAME: - retval = (FT_Long)( ft_strlen( type1->font_info.family_name ) + 1 ); + retval = ft_strlen( type1->font_info.family_name ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.family_name ), retval ); break; case PS_DICT_WEIGHT: - retval = (FT_Long)( ft_strlen( type1->font_info.weight ) + 1 ); + retval = ft_strlen( type1->font_info.weight ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.weight ), retval ); break; @@ -557,29 +584,26 @@ if ( value && value_len >= retval ) *((FT_Long *)value) = type1->font_info.italic_angle; break; - - default: - break; } - return retval; + return retval == 0 ? -1 : (FT_Long)retval; } static const FT_Service_PsInfoRec t1_service_ps_info = { - (PS_GetFontInfoFunc) t1_ps_get_font_info, - (PS_GetFontExtraFunc) t1_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t1_ps_get_font_private, - (PS_GetFontValueFunc) t1_ps_get_font_value, + (PS_GetFontInfoFunc) t1_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) t1_ps_get_font_extra, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, /* ps_has_glyph_names */ + (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */ + (PS_GetFontValueFunc) t1_ps_get_font_value, /* ps_get_font_value */ }; #ifndef T1_CONFIG_OPTION_NO_AFM static const FT_Service_KerningRec t1_service_kerning = { - T1_Get_Track_Kerning, + T1_Get_Track_Kerning, /* get_track */ }; #endif @@ -593,7 +617,7 @@ { { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name }, { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_1 }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TYPE_1 }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, #ifndef T1_CONFIG_OPTION_NO_AFM @@ -690,36 +714,37 @@ 0x10000L, 0x20000L, - 0, /* format interface */ + 0, /* module-specific interface */ - T1_Driver_Init, - T1_Driver_Done, - Get_Interface, + T1_Driver_Init, /* FT_Module_Constructor module_init */ + T1_Driver_Done, /* FT_Module_Destructor module_done */ + Get_Interface, /* FT_Module_Requester get_interface */ }, sizeof ( T1_FaceRec ), sizeof ( T1_SizeRec ), sizeof ( T1_GlyphSlotRec ), - T1_Face_Init, - T1_Face_Done, - T1_Size_Init, - T1_Size_Done, - T1_GlyphSlot_Init, - T1_GlyphSlot_Done, + T1_Face_Init, /* FT_Face_InitFunc init_face */ + T1_Face_Done, /* FT_Face_DoneFunc done_face */ + T1_Size_Init, /* FT_Size_InitFunc init_size */ + T1_Size_Done, /* FT_Size_DoneFunc done_size */ + T1_GlyphSlot_Init, /* FT_Slot_InitFunc init_slot */ + T1_GlyphSlot_Done, /* FT_Slot_DoneFunc done_slot */ - T1_Load_Glyph, + T1_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ #ifdef T1_CONFIG_OPTION_NO_AFM - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ #else - Get_Kerning, - T1_Read_Metrics, + Get_Kerning, /* FT_Face_GetKerningFunc get_kerning */ + T1_Read_Metrics, /* FT_Face_AttachFunc attach_file */ #endif - T1_Get_Advances, - T1_Size_Request, - 0 /* FT_Size_SelectFunc */ + T1_Get_Advances, /* FT_Face_GetAdvancesFunc get_advances */ + + T1_Size_Request, /* FT_Size_RequestFunc request_size */ + 0 /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/src/type1/t1driver.h b/drivers/freetype/src/type1/t1driver.h index 639cd4a7ad..78d8e38aa9 100644 --- a/drivers/freetype/src/type1/t1driver.h +++ b/drivers/freetype/src/type1/t1driver.h @@ -4,7 +4,7 @@ /* */ /* High-level Type 1 driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1DRIVER_H__ -#define __T1DRIVER_H__ +#ifndef T1DRIVER_H_ +#define T1DRIVER_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1DRIVER_H__ */ +#endif /* T1DRIVER_H_ */ /* END */ diff --git a/drivers/freetype/src/type1/t1errors.h b/drivers/freetype/src/type1/t1errors.h index 8740530eef..9ba470ed6c 100644 --- a/drivers/freetype/src/type1/t1errors.h +++ b/drivers/freetype/src/type1/t1errors.h @@ -4,7 +4,7 @@ /* */ /* Type 1 error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __T1ERRORS_H__ -#define __T1ERRORS_H__ +#ifndef T1ERRORS_H_ +#define T1ERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX T1_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __T1ERRORS_H__ */ +#endif /* T1ERRORS_H_ */ /* END */ diff --git a/drivers/freetype/src/type1/t1gload.c b/drivers/freetype/src/type1/t1gload.c index 23478d1288..ea36f64142 100644 --- a/drivers/freetype/src/type1/t1gload.c +++ b/drivers/freetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2006, 2008-2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -54,7 +54,7 @@ /*************************************************************************/ - FT_LOCAL_DEF( FT_Error ) + static FT_Error T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, FT_UInt glyph_index, FT_Data* char_string ) @@ -92,7 +92,7 @@ if ( !error ) error = decoder->funcs.parse_charstrings( decoder, (FT_Byte*)char_string->pointer, - char_string->length ); + (FT_UInt)char_string->length ); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -183,6 +183,7 @@ decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -194,7 +195,7 @@ for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) { /* now get load the unscaled outline */ - error = T1_Parse_Glyph( &decoder, glyph_index ); + (void)T1_Parse_Glyph( &decoder, (FT_UInt)glyph_index ); if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) *max_advance = decoder.builder.advance.x; @@ -245,9 +246,10 @@ decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; - decoder.num_subrs = type1->num_subrs; - decoder.subrs = type1->subrs; - decoder.subrs_len = type1->subrs_len; + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -300,6 +302,8 @@ goto Exit; } + FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index )); + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); if ( load_flags & FT_LOAD_NO_RECURSE ) @@ -344,6 +348,7 @@ decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -393,7 +398,6 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &t1glyph->metrics; - FT_Vector advance; /* copy the _unscaled_ advance width */ @@ -425,23 +429,26 @@ #if 1 /* apply the font matrix, if any */ - if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx || - font_matrix.xy != 0 || font_matrix.yx != 0 ) + if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + { FT_Outline_Transform( &t1glyph->outline, &font_matrix ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, + font_matrix.xx ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, + font_matrix.yy ); + } + if ( font_offset.x || font_offset.y ) + { FT_Outline_Translate( &t1glyph->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; + metrics->horiAdvance += font_offset.x; + metrics->vertAdvance += font_offset.y; + } #endif if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) @@ -502,7 +509,7 @@ /* Set the control data to null - it is no longer available if */ /* loaded incrementally. */ - t1glyph->control_data = 0; + t1glyph->control_data = NULL; t1glyph->control_len = 0; } #endif diff --git a/drivers/freetype/src/type1/t1gload.h b/drivers/freetype/src/type1/t1gload.h index 0bdea3a8d5..975f227853 100644 --- a/drivers/freetype/src/type1/t1gload.h +++ b/drivers/freetype/src/type1/t1gload.h @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2008, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1GLOAD_H__ -#define __T1GLOAD_H__ +#ifndef T1GLOAD_H_ +#define T1GLOAD_H_ #include <ft2build.h> @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1GLOAD_H__ */ +#endif /* T1GLOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/type1/t1load.c b/drivers/freetype/src/type1/t1load.c index 1c834a17bb..c981adcf2c 100644 --- a/drivers/freetype/src/type1/t1load.c +++ b/drivers/freetype/src/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -66,6 +66,7 @@ #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H #include FT_INTERNAL_CALC_H +#include FT_INTERNAL_HASH_H #include "t1load.h" #include "t1errors.h" @@ -226,7 +227,7 @@ /* Given a normalized (blend) coordinate, figure out the design */ /* coordinate appropriate for that value. */ /* */ - FT_LOCAL_DEF( FT_Fixed ) + static FT_Fixed mm_axis_unmap( PS_DesignMap axismap, FT_Fixed ncv ) { @@ -255,7 +256,7 @@ /* Given a vector of weights, one for each design, figure out the */ /* normalized axis coordinates which gave rise to those weights. */ /* */ - FT_LOCAL_DEF( void ) + static void mm_weights_unmap( FT_Fixed* weights, FT_Fixed* axiscoords, FT_UInt axis_count ) @@ -325,7 +326,7 @@ /* Point to axes after MM_Var struct */ mmvar->namedstyle = NULL; - for ( i = 0 ; i < mmaster.num_axis; ++i ) + for ( i = 0; i < mmaster.num_axis; ++i ) { mmvar->axis[i].name = mmaster.axis[i].name; mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); @@ -336,6 +337,9 @@ mmvar->axis[i].strid = ~0U; /* Does not apply */ mmvar->axis[i].tag = ~0U; /* Does not apply */ + if ( !mmvar->axis[i].name ) + continue; + if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 ) @@ -368,46 +372,43 @@ FT_Fixed* coords ) { PS_Blend blend = face->blend; - FT_Error error; FT_UInt n, m; - error = FT_ERR( Invalid_Argument ); + if ( !blend ) + return FT_THROW( Invalid_Argument ); - if ( blend && blend->num_axis == num_coords ) - { - /* recompute the weight vector from the blend coordinates */ - error = FT_Err_Ok; + if ( num_coords > blend->num_axis ) + num_coords = blend->num_axis; - for ( n = 0; n < blend->num_designs; n++ ) - { - FT_Fixed result = 0x10000L; /* 1.0 fixed */ + /* recompute the weight vector from the blend coordinates */ + for ( n = 0; n < blend->num_designs; n++ ) + { + FT_Fixed result = 0x10000L; /* 1.0 fixed */ - for ( m = 0; m < blend->num_axis; m++ ) - { - FT_Fixed factor; + for ( m = 0; m < blend->num_axis; m++ ) + { + FT_Fixed factor; - /* get current blend axis position */ - factor = coords[m]; - if ( factor < 0 ) - factor = 0; - if ( factor > 0x10000L ) - factor = 0x10000L; + /* get current blend axis position; */ + /* use a default value if we don't have a coordinate */ + factor = m < num_coords ? coords[m] : 0x8000; + if ( factor < 0 ) + factor = 0; + if ( factor > 0x10000L ) + factor = 0x10000L; - if ( ( n & ( 1 << m ) ) == 0 ) - factor = 0x10000L - factor; + if ( ( n & ( 1 << m ) ) == 0 ) + factor = 0x10000L - factor; - result = FT_MulFix( result, factor ); - } - blend->weight_vector[n] = result; + result = FT_MulFix( result, factor ); } - - error = FT_Err_Ok; + blend->weight_vector[n] = result; } - return error; + return FT_Err_Ok; } @@ -417,68 +418,72 @@ FT_Long* coords ) { PS_Blend blend = face->blend; - FT_Error error; FT_UInt n, p; + FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; - error = FT_ERR( Invalid_Argument ); - if ( blend && blend->num_axis == num_coords ) - { - /* compute the blend coordinates through the blend design map */ - FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; + if ( !blend ) + return FT_THROW( Invalid_Argument ); + if ( num_coords > blend->num_axis ) + num_coords = blend->num_axis; - for ( n = 0; n < blend->num_axis; n++ ) - { - FT_Long design = coords[n]; - FT_Fixed the_blend; - PS_DesignMap map = blend->design_map + n; - FT_Long* designs = map->design_points; - FT_Fixed* blends = map->blend_points; - FT_Int before = -1, after = -1; + /* compute the blend coordinates through the blend design map */ + for ( n = 0; n < blend->num_axis; n++ ) + { + FT_Long design; + FT_Fixed the_blend; + PS_DesignMap map = blend->design_map + n; + FT_Long* designs = map->design_points; + FT_Fixed* blends = map->blend_points; + FT_Int before = -1, after = -1; - for ( p = 0; p < (FT_UInt)map->num_points; p++ ) - { - FT_Long p_design = designs[p]; + /* use a default value if we don't have a coordinate */ + if ( n < num_coords ) + design = coords[n]; + else + design = ( designs[map->num_points - 1] - designs[0] ) / 2; - /* exact match? */ - if ( design == p_design ) - { - the_blend = blends[p]; - goto Found; - } + for ( p = 0; p < (FT_UInt)map->num_points; p++ ) + { + FT_Long p_design = designs[p]; - if ( design < p_design ) - { - after = p; - break; - } - before = p; + /* exact match? */ + if ( design == p_design ) + { + the_blend = blends[p]; + goto Found; } - /* now interpolate if necessary */ - if ( before < 0 ) - the_blend = blends[0]; + if ( design < p_design ) + { + after = (FT_Int)p; + break; + } - else if ( after < 0 ) - the_blend = blends[map->num_points - 1]; + before = (FT_Int)p; + } - else - the_blend = FT_MulDiv( design - designs[before], - blends [after] - blends [before], - designs[after] - designs[before] ); + /* now interpolate if necessary */ + if ( before < 0 ) + the_blend = blends[0]; - Found: - final_blends[n] = the_blend; - } + else if ( after < 0 ) + the_blend = blends[map->num_points - 1]; + + else + the_blend = FT_MulDiv( design - designs[before], + blends [after] - blends [before], + designs[after] - designs[before] ); - error = T1_Set_MM_Blend( face, num_coords, final_blends ); + Found: + final_blends[n] = the_blend; } - return error; + return T1_Set_MM_Blend( face, blend->num_axis, final_blends ); } @@ -492,20 +497,17 @@ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Long lcoords[4]; /* maximum axis count is 4 */ - FT_UInt i; - FT_Error error; + FT_Long lcoords[T1_MAX_MM_AXIS]; + FT_UInt i; + + if ( num_coords > T1_MAX_MM_AXIS ) + num_coords = T1_MAX_MM_AXIS; - error = FT_ERR( Invalid_Argument ); - if ( num_coords <= 4 && num_coords > 0 ) - { - for ( i = 0; i < num_coords; ++i ) - lcoords[i] = FIXED_TO_INT( coords[i] ); - error = T1_Set_MM_Design( face, num_coords, lcoords ); - } + for ( i = 0; i < num_coords; ++i ) + lcoords[i] = FIXED_TO_INT( coords[i] ); - return error; + return T1_Set_MM_Design( face, num_coords, lcoords ); } @@ -601,23 +603,32 @@ /* each token is an immediate containing the name of the axis */ for ( n = 0; n < num_axis; n++ ) { - T1_Token token = axis_tokens + n; - FT_Byte* name; - FT_PtrDist len; + T1_Token token = axis_tokens + n; + FT_Byte* name; + FT_UInt len; /* skip first slash, if any */ if ( token->start[0] == '/' ) token->start++; - len = token->limit - token->start; + len = (FT_UInt)( token->limit - token->start ); if ( len == 0 ) { error = FT_THROW( Invalid_File_Format ); goto Exit; } - if ( FT_ALLOC( blend->axis_names[n], (FT_Long)( len + 1 ) ) ) + name = (FT_Byte*)blend->axis_names[n]; + if ( name ) + { + FT_TRACE0(( "parse_blend_axis_types:" + " overwriting axis name `%s' with `%*.s'\n", + name, len, token->start )); + FT_FREE( name ); + } + + if ( FT_ALLOC( blend->axis_names[n], len + 1 ) ) goto Exit; name = (FT_Byte*)blend->axis_names[n]; @@ -694,7 +705,9 @@ } num_axis = n_axis; - error = t1_allocate_blend( face, num_designs, num_axis ); + error = t1_allocate_blend( face, + (FT_UInt)num_designs, + (FT_UInt)num_axis ); if ( error ) goto Exit; blend = face->blend; @@ -759,7 +772,7 @@ old_cursor = parser->root.cursor; old_limit = parser->root.limit; - error = t1_allocate_blend( face, 0, num_axis ); + error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); if ( error ) goto Exit; blend = face->blend; @@ -787,6 +800,13 @@ goto Exit; } + if ( map->design_points ) + { + FT_ERROR(( "parse_blend_design_map: duplicate table\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + /* allocate design map data */ if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) ) goto Exit; @@ -850,7 +870,7 @@ if ( !blend || !blend->num_designs ) { - error = t1_allocate_blend( face, num_designs, 0 ); + error = t1_allocate_blend( face, (FT_UInt)num_designs, 0 ); if ( error ) goto Exit; blend = face->blend; @@ -892,8 +912,8 @@ parse_buildchar( T1_Face face, T1_Loader loader ) { - face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 ); - + face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser, + 0, NULL, 0 ); return; } @@ -1040,9 +1060,11 @@ } + /* return 1 in case of success */ + static int read_binary_data( T1_Parser parser, - FT_Long* size, + FT_ULong* size, FT_Byte** base, FT_Bool incremental ) { @@ -1074,7 +1096,7 @@ if ( s >= 0 && s < limit - *base ) { parser->root.cursor += s + 1; - *size = s; + *size = (FT_ULong)s; return !parser->root.error; } } @@ -1105,9 +1127,10 @@ FT_Int result; + /* input is scaled by 1000 to accommodate default FontMatrix */ result = T1_ToFixedArray( parser, 6, temp, 3 ); - if ( result < 0 ) + if ( result < 6 ) { parser->root.error = FT_THROW( Invalid_File_Format ); return; @@ -1122,15 +1145,12 @@ return; } - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ - - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); - - /* we need to scale the values by 1.0/temp_scale */ + /* atypical case */ if ( temp_scale != 0x10000L ) { + /* set units per EM based on FontMatrix values */ + root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + temp[0] = FT_DivFix( temp[0], temp_scale ); temp[1] = FT_DivFix( temp[1], temp_scale ); temp[2] = FT_DivFix( temp[2], temp_scale ); @@ -1192,10 +1212,27 @@ else count = (FT_Int)T1_ToInt( parser ); + /* only composite fonts (which we don't support) */ + /* can have larger values */ + if ( count > 256 ) + { + FT_ERROR(( "parse_encoding: invalid encoding array size\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + T1_Skip_Spaces( parser ); if ( parser->root.cursor >= limit ) return; + /* PostScript happily allows overwriting of encoding arrays */ + if ( encode->char_index ) + { + FT_FREE( encode->char_index ); + FT_FREE( encode->char_name ); + T1_Release_Table( char_table ); + } + /* we use a T1_Table to store our charnames */ loader->num_chars = encode->num_chars = count; if ( FT_NEW_ARRAY( encode->char_index, count ) || @@ -1213,7 +1250,7 @@ char* notdef = (char *)".notdef"; - T1_Add_Table( char_table, n, notdef, 8 ); + (void)T1_Add_Table( char_table, n, notdef, 8 ); } /* Now we need to read records of the form */ @@ -1274,13 +1311,20 @@ { charcode = (FT_Int)T1_ToInt( parser ); T1_Skip_Spaces( parser ); + + /* protect against invalid charcode */ + if ( cur == parser->root.cursor ) + { + parser->root.error = FT_THROW( Unknown_File_Format ); + return; + } } cur = parser->root.cursor; if ( cur + 2 < limit && *cur == '/' && n < count ) { - FT_PtrDist len; + FT_UInt len; cur++; @@ -1292,7 +1336,7 @@ if ( parser->root.error ) return; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); parser->root.error = T1_Add_Table( char_table, charcode, cur, len + 1 ); @@ -1361,6 +1405,8 @@ FT_Memory memory = parser->root.memory; FT_Error error; FT_Int num_subrs; + FT_UInt count; + FT_Hash hash = NULL; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -1380,6 +1426,49 @@ } num_subrs = (FT_Int)T1_ToInt( parser ); + if ( num_subrs < 0 ) + { + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + /* we certainly need more than 8 bytes per subroutine */ + if ( parser->root.limit > parser->root.cursor && + num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 ) + { + /* + * There are two possibilities. Either the font contains an invalid + * value for `num_subrs', or we have a subsetted font where the + * subroutine indices are not adjusted, e.g. + * + * /Subrs 812 array + * dup 0 { ... } NP + * dup 51 { ... } NP + * dup 681 { ... } NP + * ND + * + * In both cases, we use a number hash that maps from subr indices to + * actual array elements. + */ + + FT_TRACE0(( "parse_subrs: adjusting number of subroutines" + " (from %d to %d)\n", + num_subrs, + ( parser->root.limit - parser->root.cursor ) >> 3 )); + num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3; + + if ( !hash ) + { + if ( FT_NEW( hash ) ) + goto Fail; + + loader->subrs_hash = hash; + + error = ft_hash_num_init( hash, memory ); + if ( error ) + goto Fail; + } + } /* position the parser right before the `dup' of the first subr */ T1_Skip_PS_Token( parser ); /* `array' */ @@ -1400,9 +1489,10 @@ /* */ /* `index' + binary data */ /* */ - for (;;) + for ( count = 0; ; count++ ) { - FT_Long idx, size; + FT_Long idx; + FT_ULong size; FT_Byte* base; @@ -1435,6 +1525,14 @@ T1_Skip_Spaces ( parser ); } + /* if we use a hash, the subrs index is the key, and a running */ + /* counter specified for `T1_Add_Table' acts as the value */ + if ( hash ) + { + ft_hash_num_insert( idx, count, hash, memory ); + idx = count; + } + /* with synthetic fonts it is possible we get here twice */ if ( loader->num_subrs ) continue; @@ -1446,13 +1544,13 @@ /* */ if ( face->type1.private_dict.lenIV >= 0 ) { - FT_Byte* temp; + FT_Byte* temp = NULL; /* some fonts define empty subr records -- this is not totally */ /* compliant to the specification (which says they should at */ /* least contain a `return'), but we support them anyway */ - if ( size < face->type1.private_dict.lenIV ) + if ( size < (FT_ULong)face->type1.private_dict.lenIV ) { error = FT_THROW( Invalid_File_Format ); goto Fail; @@ -1463,7 +1561,7 @@ goto Fail; FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); - size -= face->type1.private_dict.lenIV; + size -= (FT_ULong)face->type1.private_dict.lenIV; error = T1_Add_Table( table, (FT_Int)idx, temp + face->type1.private_dict.lenIV, size ); FT_FREE( temp ); @@ -1500,10 +1598,10 @@ PSAux_Service psaux = (PSAux_Service)face->psaux; - FT_Byte* cur; + FT_Byte* cur = parser->root.cursor; FT_Byte* limit = parser->root.limit; FT_Int n, num_glyphs; - FT_UInt notdef_index = 0; + FT_Int notdef_index = 0; FT_Byte notdef_found = 0; @@ -1514,6 +1612,15 @@ goto Fail; } + /* we certainly need more than 8 bytes per glyph */ + if ( num_glyphs > ( limit - cur ) >> 3 ) + { + FT_TRACE0(( "parse_charstrings: adjusting number of glyphs" + " (from %d to %d)\n", + num_glyphs, ( limit - cur ) >> 3 )); + num_glyphs = ( limit - cur ) >> 3; + } + /* some fonts like Optima-Oblique not only define the /CharStrings */ /* array but access it also */ if ( num_glyphs == 0 || parser->root.error ) @@ -1550,7 +1657,7 @@ for (;;) { - FT_Long size; + FT_ULong size; FT_Byte* base; @@ -1591,22 +1698,27 @@ } T1_Skip_PS_Token( parser ); + if ( parser->root.cursor >= limit ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } if ( parser->root.error ) return; if ( *cur == '/' ) { - FT_PtrDist len; + FT_UInt len; - if ( cur + 1 >= limit ) + if ( cur + 2 >= limit ) { error = FT_THROW( Invalid_File_Format ); goto Fail; } cur++; /* skip `/' */ - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) return; @@ -1636,10 +1748,10 @@ if ( face->type1.private_dict.lenIV >= 0 && n < num_glyphs + TABLE_EXTEND ) { - FT_Byte* temp; + FT_Byte* temp = NULL; - if ( size <= face->type1.private_dict.lenIV ) + if ( size <= (FT_ULong)face->type1.private_dict.lenIV ) { error = FT_THROW( Invalid_File_Format ); goto Fail; @@ -1650,7 +1762,7 @@ goto Fail; FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); - size -= face->type1.private_dict.lenIV; + size -= (FT_ULong)face->type1.private_dict.lenIV; error = T1_Add_Table( code_table, n, temp + face->type1.private_dict.lenIV, size ); FT_FREE( temp ); @@ -1828,15 +1940,11 @@ }; -#define T1_FIELD_COUNT \ - ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) ) - - static FT_Error parse_dict( T1_Face face, T1_Loader loader, FT_Byte* base, - FT_Long size ) + FT_ULong size ) { T1_Parser parser = &loader->parser; FT_Byte *limit, *start_binary = NULL; @@ -1892,7 +2000,7 @@ else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' && have_integer ) { - FT_Long s; + FT_ULong s; FT_Byte* b; @@ -1905,7 +2013,7 @@ else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' && have_integer ) { - FT_Long s; + FT_ULong s; FT_Byte* b; @@ -1918,7 +2026,7 @@ /* look for immediates */ else if ( *cur == '/' && cur + 2 < limit ) { - FT_PtrDist len; + FT_UInt len; cur++; @@ -1928,7 +2036,7 @@ if ( parser->root.error ) goto Exit; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); if ( len > 0 && len < 22 && parser->root.cursor < limit ) { @@ -1945,9 +2053,9 @@ if ( !name ) break; - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char *)name ) && - ft_memcmp( cur, name, len ) == 0 ) + if ( cur[0] == name[0] && + len == ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) { /* We found it -- run the parsing callback! */ /* We record every instance of every field */ @@ -2036,17 +2144,6 @@ FT_UNUSED( face ); FT_MEM_ZERO( loader, sizeof ( *loader ) ); - loader->num_glyphs = 0; - loader->num_chars = 0; - - /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - loader->subrs.init = 0; - loader->swap_table.init = 0; - loader->fontdata = 0; - loader->keywords_encountered = 0; } @@ -2054,6 +2151,7 @@ t1_done_loader( T1_Loader loader ) { T1_Parser parser = &loader->parser; + FT_Memory memory = parser->root.memory; /* finalize tables */ @@ -2063,6 +2161,10 @@ T1_Release_Table( &loader->swap_table ); T1_Release_Table( &loader->subrs ); + /* finalize hash */ + ft_hash_num_free( loader->subrs_hash, memory ); + FT_FREE( loader->subrs_hash ); + /* finalize parser */ T1_Finalize_Parser( parser ); } @@ -2179,11 +2281,15 @@ if ( loader.subrs.init ) { - loader.subrs.init = 0; type1->num_subrs = loader.num_subrs; type1->subrs_block = loader.subrs.block; type1->subrs = loader.subrs.elements; type1->subrs_len = loader.subrs.lengths; + type1->subrs_hash = loader.subrs_hash; + + /* prevent `t1_done_loader' from freeing the propagated data */ + loader.subrs.init = 0; + loader.subrs_hash = NULL; } if ( !IS_INCREMENTAL ) @@ -2202,14 +2308,13 @@ /* the `lengths' field must be released later */ type1->glyph_names_block = loader.glyph_names.block; type1->glyph_names = (FT_String**)loader.glyph_names.elements; - loader.glyph_names.block = 0; - loader.glyph_names.elements = 0; + loader.glyph_names.block = NULL; + loader.glyph_names.elements = NULL; /* we must now build type1.encoding when we have a custom array */ if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) { FT_Int charcode, idx, min_char, max_char; - FT_Byte* char_name; FT_Byte* glyph_name; @@ -2224,6 +2329,9 @@ charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) { + FT_Byte* char_name; + + type1->encoding.char_index[charcode] = 0; type1->encoding.char_name [charcode] = (char *)".notdef"; diff --git a/drivers/freetype/src/type1/t1load.h b/drivers/freetype/src/type1/t1load.h index 546fc33530..b96fe5a746 100644 --- a/drivers/freetype/src/type1/t1load.h +++ b/drivers/freetype/src/type1/t1load.h @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006, 2007 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1LOAD_H__ -#define __T1LOAD_H__ +#ifndef T1LOAD_H_ +#define T1LOAD_H_ #include <ft2build.h> @@ -46,6 +46,7 @@ FT_BEGIN_HEADER FT_Int num_subrs; PS_TableRec subrs; + FT_Hash subrs_hash; FT_Bool fontdata; FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */ @@ -96,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1LOAD_H__ */ +#endif /* T1LOAD_H_ */ /* END */ diff --git a/drivers/freetype/src/type1/t1objs.c b/drivers/freetype/src/type1/t1objs.c index 837b7911d4..a009117133 100644 --- a/drivers/freetype/src/type1/t1objs.c +++ b/drivers/freetype/src/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2009, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,7 +67,7 @@ "pshinter" ); return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) - : 0 ; + : 0; } @@ -86,7 +86,7 @@ if ( funcs ) funcs->destroy( (PSH_Globals)size->root.internal ); - size->root.internal = 0; + size->root.internal = NULL; } } @@ -144,7 +144,7 @@ FT_LOCAL_DEF( void ) T1_GlyphSlot_Done( FT_GlyphSlot slot ) { - slot->internal->glyph_hints = 0; + slot->internal->glyph_hints = NULL; } @@ -224,7 +224,7 @@ } T1_Done_Blend( face ); - face->blend = 0; + face->blend = NULL; #endif /* release font info strings */ @@ -247,6 +247,9 @@ FT_FREE( type1->subrs ); FT_FREE( type1->subrs_len ); + ft_hash_num_free( type1->subrs_hash, memory ); + FT_FREE( type1->subrs_hash ); + FT_FREE( type1->subrs_block ); FT_FREE( type1->charstrings_block ); FT_FREE( type1->glyph_names_block ); @@ -345,7 +348,7 @@ goto Exit; /* check the face index */ - if ( face_index > 0 ) + if ( ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -364,10 +367,10 @@ root->num_glyphs = type1->num_glyphs; root->face_index = 0; - root->face_flags = FT_FACE_FLAG_SCALABLE | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_GLYPH_NAMES | - FT_FACE_FLAG_HINTER; + root->face_flags |= FT_FACE_FLAG_SCALABLE | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_GLYPH_NAMES | + FT_FACE_FLAG_HINTER; if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -375,9 +378,6 @@ if ( face->blend ) root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; - /* XXX: TODO -- add kerning with .afm support */ - - /* The following code to extract the family and the style is very */ /* simplistic and might get some things wrong. For a full-featured */ /* algorithm you might have a look at the whitepaper given at */ @@ -457,7 +457,7 @@ /* no embedded bitmap support */ root->num_fixed_sizes = 0; - root->available_sizes = 0; + root->available_sizes = NULL; root->bbox.xMin = type1->font_bbox.xMin >> 16; root->bbox.yMin = type1->font_bbox.yMin >> 16; diff --git a/drivers/freetype/src/type1/t1objs.h b/drivers/freetype/src/type1/t1objs.h index 54ccbb996a..94fbdee9ae 100644 --- a/drivers/freetype/src/type1/t1objs.h +++ b/drivers/freetype/src/type1/t1objs.h @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2006, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1OBJS_H__ -#define __T1OBJS_H__ +#ifndef T1OBJS_H_ +#define T1OBJS_H_ #include <ft2build.h> @@ -154,7 +154,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1OBJS_H__ */ +#endif /* T1OBJS_H_ */ /* END */ diff --git a/drivers/freetype/src/type1/t1parse.c b/drivers/freetype/src/type1/t1parse.c index 106e4e7ecd..563d9f37bb 100644 --- a/drivers/freetype/src/type1/t1parse.c +++ b/drivers/freetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2005, 2008, 2009, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -143,13 +143,13 @@ FT_ULong size; - psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + psaux->ps_parser_funcs->init( &parser->root, NULL, NULL, memory ); parser->stream = stream; parser->base_len = 0; - parser->base_dict = 0; + parser->base_dict = NULL; parser->private_len = 0; - parser->private_dict = 0; + parser->private_dict = NULL; parser->in_pfb = 0; parser->in_memory = 0; parser->single_block = 0; @@ -273,7 +273,7 @@ /* made of several segments. We thus first read the number of */ /* segments to compute the total size of the private dictionary */ /* then re-read them into memory. */ - FT_Long start_pos = FT_STREAM_POS(); + FT_ULong start_pos = FT_STREAM_POS(); FT_UShort tag; @@ -332,17 +332,18 @@ /* dictionary block in the heap. */ /* first of all, look at the `eexec' keyword */ - FT_Byte* cur = parser->base_dict; - FT_Byte* limit = cur + parser->base_len; - FT_Byte c; + FT_Byte* cur = parser->base_dict; + FT_Byte* limit = cur + parser->base_len; + FT_Pointer pos_lf; + FT_Bool test_cr; Again: for (;;) { - c = cur[0]; - if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ - /* whitespace + 4 chars */ + if ( cur[0] == 'e' && + cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ + /* whitespace + 4 chars */ { if ( cur[1] == 'e' && cur[2] == 'x' && @@ -372,8 +373,15 @@ while ( cur < limit ) { - if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) - goto Found; + if ( cur[0] == 'e' && + cur + 5 < limit ) + { + if ( cur[1] == 'e' && + cur[2] == 'x' && + cur[3] == 'e' && + cur[4] == 'c' ) + goto Found; + } T1_Skip_PS_Token( parser ); if ( parser->root.error ) @@ -387,6 +395,15 @@ cur = limit; limit = parser->base_dict + parser->base_len; + + if ( cur >= limit ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " premature end in private dictionary\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + goto Again; /* now determine where to write the _encrypted_ binary private */ @@ -400,15 +417,26 @@ cur = parser->root.cursor; limit = parser->root.limit; - /* according to the Type1 spec, the first cipher byte must not be */ + /* According to the Type 1 spec, the first cipher byte must not be */ /* an ASCII whitespace character code (blank, tab, carriage return */ /* or line feed). We have seen Type 1 fonts with two line feed */ /* characters... So skip now all whitespace character codes. */ - while ( cur < limit && - ( *cur == ' ' || - *cur == '\t' || - *cur == '\r' || - *cur == '\n' ) ) + /* */ + /* On the other hand, Adobe's Type 1 parser handles fonts just */ + /* fine that are violating this limitation, so we add a heuristic */ + /* test to stop at \r only if it is not used for EOL. */ + + pos_lf = ft_memchr( cur, '\n', (size_t)( limit - cur ) ); + test_cr = FT_BOOL( !pos_lf || + pos_lf > ft_memchr( cur, + '\r', + (size_t)( limit - cur ) ) ); + + while ( cur < limit && + ( *cur == ' ' || + *cur == '\t' || + (test_cr && *cur == '\r' ) || + *cur == '\n' ) ) ++cur; if ( cur >= limit ) { @@ -418,7 +446,7 @@ goto Exit; } - size = (FT_ULong)( parser->base_len - ( cur - parser->base_dict ) ); + size = parser->base_len - (FT_ULong)( cur - parser->base_dict ); if ( parser->in_memory ) { @@ -432,7 +460,7 @@ parser->single_block = 1; parser->private_dict = parser->base_dict; parser->private_len = size; - parser->base_dict = 0; + parser->base_dict = NULL; parser->base_len = 0; } @@ -448,7 +476,7 @@ ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) { /* ASCII hexadecimal encoding */ - FT_Long len; + FT_ULong len; parser->root.cursor = cur; diff --git a/drivers/freetype/src/type1/t1parse.h b/drivers/freetype/src/type1/t1parse.h index fb1c8a8830..affa818e63 100644 --- a/drivers/freetype/src/type1/t1parse.h +++ b/drivers/freetype/src/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2008 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1PARSE_H__ -#define __T1PARSE_H__ +#ifndef T1PARSE_H_ +#define T1PARSE_H_ #include <ft2build.h> @@ -77,12 +77,6 @@ FT_BEGIN_HEADER #define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) -#define T1_Done_Table( p ) \ - do \ - { \ - if ( (p)->funcs.done ) \ - (p)->funcs.done( p ); \ - } while ( 0 ) #define T1_Release_Table( p ) \ do \ { \ @@ -129,7 +123,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1PARSE_H__ */ +#endif /* T1PARSE_H_ */ /* END */ diff --git a/drivers/freetype/src/type1/t1tokens.h b/drivers/freetype/src/type1/t1tokens.h index e37276b908..a84f291a6b 100644 --- a/drivers/freetype/src/type1/t1tokens.h +++ b/drivers/freetype/src/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/type1/type1.c b/drivers/freetype/src/type1/type1.c index ccc12be103..bb8aca97f9 100644 --- a/drivers/freetype/src/type1/type1.c +++ b/drivers/freetype/src/type1/type1.c @@ -4,7 +4,7 @@ /* */ /* FreeType Type 1 driver component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/type42/Jamfile b/drivers/freetype/src/type42/Jamfile index 00371d54f3..a504ad17d3 100644 --- a/drivers/freetype/src/type42/Jamfile +++ b/drivers/freetype/src/type42/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/type42 Jamfile # -# Copyright 2002 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,10 @@ SubDir FT2_TOP $(FT2_SRC_DIR) type42 ; if $(FT2_MULTI) { - _sources = t42objs t42parse t42drivr ; + _sources = t42drivr + t42objs + t42parse + ; } else { diff --git a/drivers/freetype/src/type42/module.mk b/drivers/freetype/src/type42/module.mk index b3f10a8d3c..a7e27b7236 100644 --- a/drivers/freetype/src/type42/module.mk +++ b/drivers/freetype/src/type42/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2006 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/type42/rules.mk b/drivers/freetype/src/type42/rules.mk index eac1081eb1..80710eff67 100644 --- a/drivers/freetype/src/type42/rules.mk +++ b/drivers/freetype/src/type42/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2003, 2008 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ T42_DIR := $(SRC_DIR)/type42 # compilation flags for the driver # -T42_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T42_DIR)) +T42_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(T42_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Type42 driver source diff --git a/drivers/freetype/src/type42/t42drivr.c b/drivers/freetype/src/type42/t42drivr.c index 3ad1bde79f..c63ed0c812 100644 --- a/drivers/freetype/src/type42/t42drivr.c +++ b/drivers/freetype/src/type42/t42drivr.c @@ -4,7 +4,7 @@ /* */ /* High-level Type 42 driver interface (body). */ /* */ -/* Copyright 2002-2004, 2006, 2007, 2009, 2011, 2013 by */ +/* Copyright 2002-2016 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,7 +41,7 @@ #include "t42error.h" #include FT_INTERNAL_DEBUG_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_GLYPH_DICT_H #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_POSTSCRIPT_INFO_H @@ -90,8 +90,8 @@ static const FT_Service_GlyphDictRec t42_service_glyph_dict = { - (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t42_get_name_index + (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)t42_get_name_index /* name_index */ }; @@ -110,7 +110,7 @@ static const FT_Service_PsFontNameRec t42_service_ps_font_name = { - (FT_PsName_GetFunc)t42_get_ps_font_name + (FT_PsName_GetFunc)t42_get_ps_font_name /* get_ps_font_name */ }; @@ -161,11 +161,12 @@ static const FT_Service_PsInfoRec t42_service_ps_info = { - (PS_GetFontInfoFunc) t42_ps_get_font_info, - (PS_GetFontExtraFunc) t42_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t42_ps_get_font_private, - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) t42_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) t42_ps_get_font_extra, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, /* ps_has_glyph_names */ + (PS_GetFontPrivateFunc)t42_ps_get_font_private, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ }; @@ -180,7 +181,7 @@ { FT_SERVICE_ID_GLYPH_DICT, &t42_service_glyph_dict }, { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t42_service_ps_font_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &t42_service_ps_info }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_42 }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TYPE_42 }, { NULL, NULL } }; @@ -212,32 +213,32 @@ 0x10000L, 0x20000L, - 0, /* format interface */ + 0, /* module-specific interface */ - T42_Driver_Init, - T42_Driver_Done, - T42_Get_Interface, + T42_Driver_Init, /* FT_Module_Constructor module_init */ + T42_Driver_Done, /* FT_Module_Destructor module_done */ + T42_Get_Interface, /* FT_Module_Requester get_interface */ }, sizeof ( T42_FaceRec ), sizeof ( T42_SizeRec ), sizeof ( T42_GlyphSlotRec ), - T42_Face_Init, - T42_Face_Done, - T42_Size_Init, - T42_Size_Done, - T42_GlyphSlot_Init, - T42_GlyphSlot_Done, + T42_Face_Init, /* FT_Face_InitFunc init_face */ + T42_Face_Done, /* FT_Face_DoneFunc done_face */ + T42_Size_Init, /* FT_Size_InitFunc init_size */ + T42_Size_Done, /* FT_Size_DoneFunc done_size */ + T42_GlyphSlot_Init, /* FT_Slot_InitFunc init_slot */ + T42_GlyphSlot_Done, /* FT_Slot_DoneFunc done_slot */ - T42_GlyphSlot_Load, + T42_GlyphSlot_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - 0, /* FT_Face_GetAdvancesFunc */ - T42_Size_Request, - T42_Size_Select + T42_Size_Request, /* FT_Size_RequestFunc request_size */ + T42_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/src/type42/t42drivr.h b/drivers/freetype/src/type42/t42drivr.h index 9a1e97e30e..6ddfb639d5 100644 --- a/drivers/freetype/src/type42/t42drivr.h +++ b/drivers/freetype/src/type42/t42drivr.h @@ -4,7 +4,8 @@ /* */ /* High-level Type 42 driver interface (specification). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42DRIVR_H__ -#define __T42DRIVR_H__ +#ifndef T42DRIVR_H_ +#define T42DRIVR_H_ #include <ft2build.h> @@ -36,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42DRIVR_H__ */ +#endif /* T42DRIVR_H_ */ /* END */ diff --git a/drivers/freetype/src/type42/t42error.h b/drivers/freetype/src/type42/t42error.h index 217ae8bd52..e1097cc81e 100644 --- a/drivers/freetype/src/type42/t42error.h +++ b/drivers/freetype/src/type42/t42error.h @@ -4,7 +4,7 @@ /* */ /* Type 42 error codes (specification only). */ /* */ -/* Copyright 2002, 2003, 2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __T42ERROR_H__ -#define __T42ERROR_H__ +#ifndef T42ERROR_H_ +#define T42ERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX T42_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __T42ERROR_H__ */ +#endif /* T42ERROR_H_ */ /* END */ diff --git a/drivers/freetype/src/type42/t42objs.c b/drivers/freetype/src/type42/t42objs.c index 18e2c0b625..4672c6e164 100644 --- a/drivers/freetype/src/type42/t42objs.c +++ b/drivers/freetype/src/type42/t42objs.c @@ -4,8 +4,8 @@ /* */ /* Type 42 objects manager (body). */ /* */ -/* Copyright 2002-2009, 2011, 2013 */ -/* by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -47,6 +47,12 @@ if ( FT_ALLOC( face->ttf_data, 12 ) ) goto Exit; + /* while parsing the font we always update `face->ttf_size' so that */ + /* even in case of buggy data (which might lead to premature end of */ + /* scanning without causing an error) the call to `FT_Open_Face' in */ + /* `T42_Face_Init' passes the correct size */ + face->ttf_size = 12; + error = t42_parser_init( parser, face->root.stream, memory, @@ -86,8 +92,8 @@ /* the `lengths' field must be released later */ type1->glyph_names_block = loader.glyph_names.block; type1->glyph_names = (FT_String**)loader.glyph_names.elements; - loader.glyph_names.block = 0; - loader.glyph_names.elements = 0; + loader.glyph_names.block = NULL; + loader.glyph_names.elements = NULL; /* we must now build type1.encoding when we have a custom array */ if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) @@ -171,7 +177,6 @@ FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_UNUSED( stream ); @@ -203,7 +208,7 @@ goto Exit; /* check the face index */ - if ( face_index > 0 ) + if ( ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "T42_Face_Init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -219,16 +224,13 @@ root->num_charmaps = 0; root->face_index = 0; - root->face_flags = FT_FACE_FLAG_SCALABLE | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_GLYPH_NAMES; + root->face_flags |= FT_FACE_FLAG_SCALABLE | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_GLYPH_NAMES; if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - /* We only set this flag if we have the patented bytecode interpreter. */ - /* There are no known `tricky' Type42 fonts that could be loaded with */ - /* the unpatented interpreter. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER root->face_flags |= FT_FACE_FLAG_HINTER; #endif @@ -280,14 +282,16 @@ /* no embedded bitmap support */ root->num_fixed_sizes = 0; - root->available_sizes = 0; + root->available_sizes = NULL; /* Load the TTF font embedded in the T42 font */ { FT_Open_Args args; - args.flags = FT_OPEN_MEMORY; + args.flags = FT_OPEN_MEMORY | FT_OPEN_DRIVER; + args.driver = FT_Get_Module( FT_FACE_LIBRARY( face ), + "truetype" ); args.memory_base = face->ttf_data; args.memory_size = face->ttf_size; @@ -454,8 +458,8 @@ FT_FREE( face->unicode_map.maps ); face->unicode_map.num_maps = 0; - face->root.family_name = 0; - face->root.style_name = 0; + face->root.family_name = NULL; + face->root.style_name = NULL; } @@ -507,7 +511,7 @@ FT_Face face = size->face; T42_Face t42face = (T42_Face)face; FT_Size ttsize; - FT_Error error = FT_Err_Ok; + FT_Error error; error = FT_New_Size( t42face->ttf_face, &ttsize ); @@ -625,10 +629,10 @@ slot->bitmap_left = 0; slot->bitmap_top = 0; slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; + slot->subglyphs = NULL; + slot->control_data = NULL; slot->control_len = 0; - slot->other = 0; + slot->other = NULL; slot->format = FT_GLYPH_FORMAT_NONE; slot->linearHoriAdvance = 0; @@ -645,9 +649,16 @@ FT_Error error; T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph; T42_Size t42size = (T42_Size)size; + T42_Face t42face = (T42_Face)size->face; FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; + FT_TRACE1(( "T42_GlyphSlot_Load: glyph index %d\n", glyph_index )); + + /* map T42 glyph index to embedded TTF's glyph index */ + glyph_index = (FT_UInt)ft_atol( + (const char *)t42face->type1.charstrings[glyph_index] ); + t42_glyphslot_clear( t42slot->ttslot ); error = ttclazz->load_glyph( t42slot->ttslot, t42size->ttsize, diff --git a/drivers/freetype/src/type42/t42objs.h b/drivers/freetype/src/type42/t42objs.h index 02d13259be..87a40452f4 100644 --- a/drivers/freetype/src/type42/t42objs.h +++ b/drivers/freetype/src/type42/t42objs.h @@ -4,7 +4,8 @@ /* */ /* Type 42 objects manager (specification). */ /* */ -/* Copyright 2002, 2003, 2006, 2007, 2011 by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42OBJS_H__ -#define __T42OBJS_H__ +#ifndef T42OBJS_H_ +#define T42OBJS_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -55,7 +56,6 @@ FT_BEGIN_HEADER { FT_DriverRec root; FT_Driver_Class ttclazz; - void* extension_component; } T42_DriverRec, *T42_Driver; @@ -118,7 +118,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42OBJS_H__ */ +#endif /* T42OBJS_H_ */ /* END */ diff --git a/drivers/freetype/src/type42/t42parse.c b/drivers/freetype/src/type42/t42parse.c index 3cdd8a1acf..f948916afa 100644 --- a/drivers/freetype/src/type42/t42parse.c +++ b/drivers/freetype/src/type42/t42parse.c @@ -4,7 +4,7 @@ /* */ /* Type 42 font parser (body). */ /* */ -/* Copyright 2002-2013 by */ +/* Copyright 2002-2016 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -104,12 +104,6 @@ #define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) -#define T1_Done_Table( p ) \ - do \ - { \ - if ( (p)->funcs.done ) \ - (p)->funcs.done( p ); \ - } while ( 0 ) #define T1_Release_Table( p ) \ do \ { \ @@ -148,11 +142,11 @@ FT_Long size; - psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + psaux->ps_parser_funcs->init( &parser->root, NULL, NULL, memory ); parser->stream = stream; parser->base_len = 0; - parser->base_dict = 0; + parser->base_dict = NULL; parser->in_memory = 0; /*******************************************************************/ @@ -184,7 +178,7 @@ if ( error || FT_STREAM_SEEK( 0 ) ) goto Exit; - size = stream->size; + size = (FT_Long)stream->size; /* now, try to load `size' bytes of the `base' dictionary we */ /* found previously */ @@ -252,22 +246,29 @@ T42_Parser parser = &loader->parser; FT_Matrix* matrix = &face->type1.font_matrix; FT_Vector* offset = &face->type1.font_offset; - FT_Face root = (FT_Face)&face->root; FT_Fixed temp[6]; FT_Fixed temp_scale; + FT_Int result; - (void)T1_ToFixedArray( parser, 6, temp, 3 ); + result = T1_ToFixedArray( parser, 6, temp, 0 ); - temp_scale = FT_ABS( temp[3] ); + if ( result < 6 ) + { + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ + temp_scale = FT_ABS( temp[3] ); - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + if ( temp_scale == 0 ) + { + FT_ERROR(( "t42_parse_font_matrix: invalid font matrix\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } - /* we need to scale the values by 1.0/temp_scale */ + /* atypical case */ if ( temp_scale != 0x10000L ) { temp[0] = FT_DivFix( temp[0], temp_scale ); @@ -275,7 +276,7 @@ temp[2] = FT_DivFix( temp[2], temp_scale ); temp[4] = FT_DivFix( temp[4], temp_scale ); temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; + temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; } matrix->xx = temp[0]; @@ -314,7 +315,7 @@ if ( ft_isdigit( *cur ) || *cur == '[' ) { T1_Encoding encode = &face->type1.encoding; - FT_UInt count, n; + FT_Int count, n; PS_Table char_table = &loader->encoding_table; FT_Memory memory = parser->root.memory; FT_Error error; @@ -329,12 +330,29 @@ parser->root.cursor++; } else - count = (FT_UInt)T1_ToInt( parser ); + count = (FT_Int)T1_ToInt( parser ); + + /* only composite fonts (which we don't support) */ + /* can have larger values */ + if ( count > 256 ) + { + FT_ERROR(( "t42_parse_encoding: invalid encoding array size\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } T1_Skip_Spaces( parser ); if ( parser->root.cursor >= limit ) return; + /* PostScript happily allows overwriting of encoding arrays */ + if ( encode->char_index ) + { + FT_FREE( encode->char_index ); + FT_FREE( encode->char_name ); + T1_Release_Table( char_table ); + } + /* we use a T1_Table to store our charnames */ loader->num_chars = encode->num_chars = count; if ( FT_NEW_ARRAY( encode->char_index, count ) || @@ -352,7 +370,7 @@ char* notdef = (char *)".notdef"; - T1_Add_Table( char_table, n, notdef, 8 ); + (void)T1_Add_Table( char_table, n, notdef, 8 ); } /* Now we need to read records of the form */ @@ -413,23 +431,32 @@ { charcode = (FT_Int)T1_ToInt( parser ); T1_Skip_Spaces( parser ); + + /* protect against invalid charcode */ + if ( cur == parser->root.cursor ) + { + parser->root.error = FT_THROW( Unknown_File_Format ); + return; + } } cur = parser->root.cursor; - if ( *cur == '/' && cur + 2 < limit && n < count ) + if ( cur + 2 < limit && *cur == '/' && n < count ) { - FT_PtrDist len; + FT_UInt len; cur++; parser->root.cursor = cur; T1_Skip_PS_Token( parser ); + if ( parser->root.cursor >= limit ) + return; if ( parser->root.error ) return; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); parser->root.error = T1_Add_Table( char_table, charcode, cur, len + 1 ); @@ -439,6 +466,19 @@ n++; } + else if ( only_immediates ) + { + /* Since the current position is not updated for */ + /* immediates-only mode we would get an infinite loop if */ + /* we don't do anything here. */ + /* */ + /* This encoding array is not valid according to the */ + /* type42 specification (it might be an encoding for a CID */ + /* type42 font, however), so we conclude that this font is */ + /* NOT a type42 font. */ + parser->root.error = FT_THROW( Unknown_File_Format ); + return; + } } else { @@ -450,8 +490,8 @@ T1_Skip_Spaces( parser ); } - face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; - parser->root.cursor = cur; + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; } /* Otherwise, we should have either `StandardEncoding', */ @@ -471,10 +511,7 @@ face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; else - { - FT_ERROR(( "t42_parse_encoding: invalid token\n" )); - parser->root.error = FT_THROW( Invalid_File_Format ); - } + parser->root.error = FT_ERR( Ignore ); } } @@ -498,9 +535,9 @@ FT_Byte* limit = parser->root.limit; FT_Error error; FT_Int num_tables = 0; - FT_ULong count, ttf_size = 0; + FT_Long count; - FT_Long n, string_size, old_string_size, real_size; + FT_ULong n, string_size, old_string_size, real_size; FT_Byte* string_buf = NULL; FT_Bool allocated = 0; @@ -538,6 +575,9 @@ while ( parser->root.cursor < limit ) { + FT_ULong size; + + cur = parser->root.cursor; if ( *cur == ']' ) @@ -553,7 +593,13 @@ goto Exit; /* don't include delimiters */ - string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); + string_size = (FT_ULong)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); + if ( !string_size ) + { + FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) goto Fail; @@ -562,11 +608,14 @@ parser->root.cursor = cur; (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 ); old_string_size = string_size; - string_size = real_size; + string_size = real_size; } else if ( ft_isdigit( *cur ) ) { + FT_Long tmp; + + if ( allocated ) { FT_ERROR(( "t42_parse_sfnts: " @@ -575,13 +624,15 @@ goto Fail; } - string_size = T1_ToInt( parser ); - if ( string_size < 0 ) + tmp = T1_ToInt( parser ); + if ( tmp < 0 ) { FT_ERROR(( "t42_parse_sfnts: invalid string size\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } + else + string_size = (FT_ULong)tmp; T1_Skip_PS_Token( parser ); /* `RD' */ if ( parser->root.error ) @@ -589,9 +640,9 @@ string_buf = parser->root.cursor + 1; /* one space after `RD' */ - if ( limit - parser->root.cursor < string_size ) + if ( (FT_ULong)( limit - parser->root.cursor ) <= string_size ) { - FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); + FT_ERROR(( "t42_parse_sfnts: too much binary data\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } @@ -618,6 +669,11 @@ goto Fail; } + /* The whole TTF is now loaded into `string_buf'. We are */ + /* checking its contents while copying it to `ttf_data'. */ + + size = (FT_ULong)( limit - parser->root.cursor ); + for ( n = 0; n < string_size; n++ ) { switch ( status ) @@ -631,18 +687,25 @@ } else { - num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; - status = BEFORE_TABLE_DIR; - ttf_size = 12 + 16 * num_tables; + num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; + status = BEFORE_TABLE_DIR; + face->ttf_size = 12 + 16 * num_tables; - if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) + if ( (FT_Long)size < face->ttf_size ) + { + FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + if ( FT_REALLOC( face->ttf_data, 12, face->ttf_size ) ) goto Fail; } /* fall through */ case BEFORE_TABLE_DIR: /* the offset table is read; read the table directory */ - if ( count < ttf_size ) + if ( count < face->ttf_size ) { face->ttf_data[count++] = string_buf[n]; continue; @@ -659,26 +722,32 @@ len = FT_PEEK_ULONG( p ); + if ( len > size || + face->ttf_size > (FT_Long)( size - len ) ) + { + FT_ERROR(( "t42_parse_sfnts:" + " invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } /* Pad to a 4-byte boundary length */ - ttf_size += ( len + 3 ) & ~3; + face->ttf_size += (FT_Long)( ( len + 3 ) & ~3U ); } - status = OTHER_TABLES; - face->ttf_size = ttf_size; + status = OTHER_TABLES; - /* there are no more than 256 tables, so no size check here */ if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, - ttf_size + 1 ) ) + face->ttf_size + 1 ) ) goto Fail; } /* fall through */ case OTHER_TABLES: /* all other tables are just copied */ - if ( count >= ttf_size ) + if ( count >= face->ttf_size ) { - FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); + FT_ERROR(( "t42_parse_sfnts: too much binary data\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } @@ -716,8 +785,8 @@ FT_Byte* cur; FT_Byte* limit = parser->root.limit; - FT_UInt n; - FT_UInt notdef_index = 0; + FT_Int n; + FT_Int notdef_index = 0; FT_Byte notdef_found = 0; @@ -732,15 +801,32 @@ if ( ft_isdigit( *parser->root.cursor ) ) { - loader->num_glyphs = (FT_UInt)T1_ToInt( parser ); + loader->num_glyphs = T1_ToInt( parser ); if ( parser->root.error ) return; + if ( loader->num_glyphs < 0 ) + { + FT_ERROR(( "t42_parse_encoding: invalid number of glyphs\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* we certainly need more than 4 bytes per glyph */ + if ( loader->num_glyphs > ( limit - parser->root.cursor ) >> 2 ) + { + FT_TRACE0(( "t42_parse_charstrings: adjusting number of glyphs" + " (from %d to %d)\n", + loader->num_glyphs, + ( limit - parser->root.cursor ) >> 2 )); + loader->num_glyphs = ( limit - parser->root.cursor ) >> 2; + } + } else if ( *parser->root.cursor == '<' ) { /* We have `<< ... >>'. Count the number of `/' in the dictionary */ /* to get its size. */ - FT_UInt count = 0; + FT_Int count = 0; T1_Skip_PS_Token( parser ); @@ -781,6 +867,15 @@ /* initialize tables */ + /* contrary to Type1, we disallow multiple CharStrings arrays */ + if ( swap_table->init ) + { + FT_ERROR(( "t42_parse_charstrings:" + " only one CharStrings array allowed\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + error = psaux->ps_table_funcs->init( code_table, loader->num_glyphs, memory ); @@ -804,8 +899,13 @@ for (;;) { - /* The format is simple: */ - /* `/glyphname' + index [+ def] */ + /* We support two formats. */ + /* */ + /* `/glyphname' + index [+ `def'] */ + /* `(glyphname)' [+ `cvn'] + index [+ `def'] */ + /* */ + /* The latter format gets created by the */ + /* LilyPond typesetting program. */ T1_Skip_Spaces( parser ); @@ -824,15 +924,22 @@ break; T1_Skip_PS_Token( parser ); + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } if ( parser->root.error ) return; - if ( *cur == '/' ) + if ( *cur == '/' || *cur == '(' ) { - FT_PtrDist len; + FT_UInt len; + FT_Bool have_literal = ( *cur == '(' ); - if ( cur + 1 >= limit ) + if ( cur + ( have_literal ? 3 : 2 ) >= limit ) { FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = FT_THROW( Invalid_File_Format ); @@ -840,7 +947,9 @@ } cur++; /* skip `/' */ - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); + if ( have_literal ) + len--; error = T1_Add_Table( name_table, n, cur, len + 1 ); if ( error ) @@ -860,6 +969,9 @@ T1_Skip_Spaces( parser ); + if ( have_literal ) + T1_Skip_PS_Token( parser ); + cur = parser->root.cursor; (void)T1_ToInt( parser ); @@ -870,7 +982,7 @@ goto Fail; } - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); error = T1_Add_Table( code_table, n, cur, len + 1 ); if ( error ) @@ -1091,7 +1203,7 @@ /* look for immediates */ else if ( *cur == '/' && cur + 2 < limit ) { - FT_PtrDist len; + FT_UInt len; cur++; @@ -1101,7 +1213,7 @@ if ( parser->root.error ) goto Exit; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); if ( len > 0 && len < 22 && parser->root.cursor < limit ) { @@ -1120,9 +1232,9 @@ if ( !name ) continue; - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char *)name ) && - ft_memcmp( cur, name, len ) == 0 ) + if ( cur[0] == name[0] && + len == ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) { /* we found it -- run the parsing callback! */ parser->root.error = t42_load_keyword( face, diff --git a/drivers/freetype/src/type42/t42parse.h b/drivers/freetype/src/type42/t42parse.h index f77ec4af4f..ba9e857190 100644 --- a/drivers/freetype/src/type42/t42parse.h +++ b/drivers/freetype/src/type42/t42parse.h @@ -4,7 +4,8 @@ /* */ /* Type 42 font parser (specification). */ /* */ -/* Copyright 2002, 2003 by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42PARSE_H__ -#define __T42PARSE_H__ +#ifndef T42PARSE_H_ +#define T42PARSE_H_ #include "t42objs.h" @@ -42,11 +43,11 @@ FT_BEGIN_HEADER { T42_ParserRec parser; /* parser used to read the stream */ - FT_UInt num_chars; /* number of characters in encoding */ + FT_Int num_chars; /* number of characters in encoding */ PS_TableRec encoding_table; /* PS_Table used to store the */ /* encoding character names */ - FT_UInt num_glyphs; + FT_Int num_glyphs; PS_TableRec glyph_names; PS_TableRec charstrings; PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ @@ -84,7 +85,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42PARSE_H__ */ +#endif /* T42PARSE_H_ */ /* END */ diff --git a/drivers/freetype/src/type42/t42types.h b/drivers/freetype/src/type42/t42types.h index c7c2db490d..850a156e45 100644 --- a/drivers/freetype/src/type42/t42types.h +++ b/drivers/freetype/src/type42/t42types.h @@ -4,7 +4,8 @@ /* */ /* Type 42 font data types (specification only). */ /* */ -/* Copyright 2002, 2003, 2006, 2008 by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42TYPES_H__ -#define __T42TYPES_H__ +#ifndef T42TYPES_H_ +#define T42TYPES_H_ #include <ft2build.h> @@ -39,7 +40,7 @@ FT_BEGIN_HEADER const void* afm_data; #endif FT_Byte* ttf_data; - FT_ULong ttf_size; + FT_Long ttf_size; FT_Face ttf_face; FT_CharMapRec charmaprecs[2]; FT_CharMap charmaps[2]; @@ -50,7 +51,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42TYPES_H__ */ +#endif /* T42TYPES_H_ */ /* END */ diff --git a/drivers/freetype/src/type42/type42.c b/drivers/freetype/src/type42/type42.c index d13df56b10..0d17a9b1dc 100644 --- a/drivers/freetype/src/type42/type42.c +++ b/drivers/freetype/src/type42/type42.c @@ -4,7 +4,7 @@ /* */ /* FreeType Type 42 driver component. */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/src/winfonts/Jamfile b/drivers/freetype/src/winfonts/Jamfile index 71cf5678e8..d81165e921 100644 --- a/drivers/freetype/src/winfonts/Jamfile +++ b/drivers/freetype/src/winfonts/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/winfonts Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/winfonts/fnterrs.h b/drivers/freetype/src/winfonts/fnterrs.h index 463ba77ee2..6835d3e64f 100644 --- a/drivers/freetype/src/winfonts/fnterrs.h +++ b/drivers/freetype/src/winfonts/fnterrs.h @@ -4,7 +4,7 @@ /* */ /* Win FNT/FON error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FNTERRS_H__ -#define __FNTERRS_H__ +#ifndef FNTERRS_H_ +#define FNTERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX FNT_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __FNTERRS_H__ */ +#endif /* FNTERRS_H_ */ /* END */ diff --git a/drivers/freetype/src/winfonts/module.mk b/drivers/freetype/src/winfonts/module.mk index b44d7f0570..83da5732f1 100644 --- a/drivers/freetype/src/winfonts/module.mk +++ b/drivers/freetype/src/winfonts/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/src/winfonts/rules.mk b/drivers/freetype/src/winfonts/rules.mk index 71a7df2d8a..2fd7b822a2 100644 --- a/drivers/freetype/src/winfonts/rules.mk +++ b/drivers/freetype/src/winfonts/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -18,7 +18,10 @@ FNT_DIR := $(SRC_DIR)/winfonts -FNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(FNT_DIR)) +FNT_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(FNT_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Windows driver sources (i.e., C files) diff --git a/drivers/freetype/src/winfonts/winfnt.c b/drivers/freetype/src/winfonts/winfnt.c index e8055c0898..1c74ccd5ab 100644 --- a/drivers/freetype/src/winfonts/winfnt.c +++ b/drivers/freetype/src/winfonts/winfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2004, 2006-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2003 Huw D M Davies for Codeweavers */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ @@ -28,7 +28,7 @@ #include "winfnt.h" #include "fnterrs.h" #include FT_SERVICE_WINFNT_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H /*************************************************************************/ /* */ @@ -72,12 +72,12 @@ FT_FRAME_START( 248 ), FT_FRAME_ULONG_LE ( magic ), /* PE00 */ - FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */ + FT_FRAME_USHORT_LE ( machine ), /* 0x014C - i386 */ FT_FRAME_USHORT_LE ( number_of_sections ), FT_FRAME_SKIP_BYTES( 12 ), FT_FRAME_USHORT_LE ( size_of_optional_header ), FT_FRAME_SKIP_BYTES( 2 ), - FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */ + FT_FRAME_USHORT_LE ( magic32 ), /* 0x10B */ FT_FRAME_SKIP_BYTES( 110 ), FT_FRAME_ULONG_LE ( rsrc_virtual_address ), FT_FRAME_ULONG_LE ( rsrc_size ), @@ -201,7 +201,7 @@ FT_FREE( font->family_name ); FT_FREE( font ); - face->font = 0; + face->font = NULL; } @@ -269,15 +269,18 @@ static FT_Error fnt_face_get_dll_font( FNT_Face face, - FT_Int face_index ) + FT_Int face_instance_index ) { FT_Error error; FT_Stream stream = FT_FACE( face )->stream; FT_Memory memory = FT_FACE( face )->memory; WinMZ_HeaderRec mz_header; + FT_Long face_index; - face->font = 0; + face->font = NULL; + + face_index = FT_ABS( face_instance_index ) & 0xFFFF; /* does it begin with an MZ header? */ if ( FT_STREAM_SEEK( 0 ) || @@ -317,6 +320,21 @@ size_shift = FT_GET_USHORT_LE(); + /* Microsoft's specification of the executable-file header format */ + /* for `New Executable' (NE) doesn't give a limit for the */ + /* alignment shift count; however, in 1985, the year of the */ + /* specification release, only 32bit values were supported, thus */ + /* anything larger than 16 doesn't make sense in general, given */ + /* that file offsets are 16bit values, shifted by the alignment */ + /* shift count */ + if ( size_shift > 16 ) + { + FT_TRACE2(( "invalid alignment shift count for resource data\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + for (;;) { FT_UShort type_id, count; @@ -331,8 +349,8 @@ if ( type_id == 0x8008U ) { font_count = count; - font_offset = (FT_ULong)( FT_STREAM_POS() + 4 + - ( stream->cursor - stream->limit ) ); + font_offset = FT_STREAM_POS() + 4 + + (FT_ULong)( stream->cursor - stream->limit ); break; } @@ -359,19 +377,20 @@ face->root.num_faces = font_count; + if ( face_instance_index < 0 ) + goto Exit; + if ( face_index >= font_count ) { error = FT_THROW( Invalid_Argument ); goto Exit; } - else if ( face_index < 0 ) - goto Exit; if ( FT_NEW( face->font ) ) goto Exit; - if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) || - FT_FRAME_ENTER( 12 ) ) + if ( FT_STREAM_SEEK( font_offset + (FT_ULong)face_index * 12 ) || + FT_FRAME_ENTER( 12 ) ) goto Fail; face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; @@ -391,7 +410,7 @@ WinPE_RsrcDirEntryRec dir_entry1, dir_entry2, dir_entry3; WinPE_RsrcDataEntryRec data_entry; - FT_Long root_dir_offset, name_dir_offset, lang_dir_offset; + FT_ULong root_dir_offset, name_dir_offset, lang_dir_offset; FT_UShort i, j, k; @@ -412,9 +431,9 @@ pe32_header.rsrc_size )); if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ || - pe32_header.machine != 0x014c /* i386 */ || - pe32_header.size_of_optional_header != 0xe0 /* FIXME */ || - pe32_header.magic32 != 0x10b ) + pe32_header.machine != 0x014C /* i386 */ || + pe32_header.size_of_optional_header != 0xE0 /* FIXME */ || + pe32_header.magic32 != 0x10B ) { FT_TRACE2(( "this file has an invalid PE header\n" )); error = FT_THROW( Invalid_File_Format ); @@ -591,11 +610,14 @@ static FT_Error - fnt_cmap_init( FNT_CMap cmap ) + fnt_cmap_init( FNT_CMap cmap, + FT_Pointer pointer ) { FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); FNT_Font font = face->font; + FT_UNUSED( pointer ); + cmap->first = (FT_UInt32) font->header.first_char; cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 ); @@ -686,13 +708,14 @@ static FT_Error FNT_Face_Init( FT_Stream stream, FT_Face fntface, /* FNT_Face */ - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { FNT_Face face = (FNT_Face)fntface; FT_Error error; FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Int face_index; FT_UNUSED( num_params ); FT_UNUSED( params ); @@ -700,9 +723,11 @@ FT_TRACE2(( "Windows FNT driver\n" )); + face_index = FT_ABS( face_instance_index ) & 0xFFFF; + /* try to load font from a DLL */ - error = fnt_face_get_dll_font( face, face_index ); - if ( !error && face_index < 0 ) + error = fnt_face_get_dll_font( face, face_instance_index ); + if ( !error && face_instance_index < 0 ) goto Exit; if ( FT_ERR_EQ( error, Unknown_File_Format ) ) @@ -723,10 +748,11 @@ if ( !error ) { + if ( face_instance_index < 0 ) + goto Exit; + if ( face_index > 0 ) error = FT_THROW( Invalid_Argument ); - else if ( face_index < 0 ) - goto Exit; } } @@ -736,15 +762,15 @@ /* we now need to fill the root FT_Face fields */ /* with relevant information */ { - FT_Face root = FT_FACE( face ); - FNT_Font font = face->font; - FT_PtrDist family_size; + FT_Face root = FT_FACE( face ); + FNT_Font font = face->font; + FT_ULong family_size; root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL; + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL; if ( font->header.avg_width == font->header.max_width ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -766,9 +792,9 @@ FT_UShort x_res, y_res; - bsize->width = font->header.avg_width; - bsize->height = (FT_Short)( - font->header.pixel_height + font->header.external_leading ); + bsize->width = (FT_Short)font->header.avg_width; + bsize->height = (FT_Short)( font->header.pixel_height + + font->header.external_leading ); bsize->size = font->header.nominal_point_size << 6; x_res = font->header.horizontal_resolution; @@ -961,7 +987,7 @@ FNT_Font font; FT_Error error = FT_Err_Ok; FT_Byte* p; - FT_Int len; + FT_UInt len; FT_Bitmap* bitmap = &slot->bitmap; FT_ULong offset; FT_Bool new_format; @@ -971,32 +997,44 @@ if ( !face ) { - error = FT_THROW( Invalid_Argument ); + error = FT_THROW( Invalid_Face_Handle ); goto Exit; } font = face->font; - if ( !font || + if ( !font || glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) ) { error = FT_THROW( Invalid_Argument ); goto Exit; } + FT_TRACE1(( "FNT_Load_Glyph: glyph index %d\n", glyph_index )); + if ( glyph_index > 0 ) glyph_index--; /* revert to real index */ else - glyph_index = font->header.default_char; /* the .notdef glyph */ + glyph_index = font->header.default_char; /* the `.notdef' glyph */ new_format = FT_BOOL( font->header.version == 0x300 ); len = new_format ? 6 : 4; - /* jump to glyph entry */ - p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index; + /* get glyph width and offset */ + offset = ( new_format ? 148 : 118 ) + len * glyph_index; - bitmap->width = FT_NEXT_SHORT_LE( p ); + if ( offset >= font->header.file_size - 2 - ( new_format ? 4 : 2 ) ) + { + FT_TRACE2(( "invalid FNT offset\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + p = font->fnt_frame + offset; + + bitmap->width = FT_NEXT_USHORT_LE( p ); + + /* jump to glyph entry */ if ( new_format ) offset = FT_NEXT_ULONG_LE( p ); else @@ -1015,16 +1053,16 @@ /* allocate and build bitmap */ { FT_Memory memory = FT_FACE_MEMORY( slot->face ); - FT_Int pitch = ( bitmap->width + 7 ) >> 3; + FT_UInt pitch = ( bitmap->width + 7 ) >> 3; FT_Byte* column; FT_Byte* write; - bitmap->pitch = pitch; + bitmap->pitch = (int)pitch; bitmap->rows = font->header.pixel_height; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - if ( offset + pitch * bitmap->rows >= font->header.file_size ) + if ( offset + pitch * bitmap->rows > font->header.file_size ) { FT_TRACE2(( "invalid bitmap width\n" )); error = FT_THROW( Invalid_File_Format ); @@ -1054,14 +1092,14 @@ slot->format = FT_GLYPH_FORMAT_BITMAP; /* now set up metrics */ - slot->metrics.width = bitmap->width << 6; - slot->metrics.height = bitmap->rows << 6; - slot->metrics.horiAdvance = bitmap->width << 6; + slot->metrics.width = (FT_Pos)( bitmap->width << 6 ); + slot->metrics.height = (FT_Pos)( bitmap->rows << 6 ); + slot->metrics.horiAdvance = (FT_Pos)( bitmap->width << 6 ); slot->metrics.horiBearingX = 0; slot->metrics.horiBearingY = slot->bitmap_top << 6; ft_synthesize_vertical_metrics( &slot->metrics, - bitmap->rows << 6 ); + (FT_Pos)( bitmap->rows << 6 ) ); Exit: return error; @@ -1083,7 +1121,7 @@ static const FT_Service_WinFntRec winfnt_service_rec = { - winfnt_get_header + winfnt_get_header /* get_header */ }; /* @@ -1093,8 +1131,8 @@ static const FT_ServiceDescRec winfnt_services[] = { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT }, - { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_WINFNT }, + { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, { NULL, NULL } }; @@ -1123,32 +1161,32 @@ 0x10000L, 0x20000L, - 0, + 0, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - winfnt_get_service + 0, /* FT_Module_Constructor module_init */ + 0, /* FT_Module_Destructor module_done */ + winfnt_get_service /* FT_Module_Requester get_interface */ }, sizeof ( FNT_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - FNT_Face_Init, - FNT_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + FNT_Face_Init, /* FT_Face_InitFunc init_face */ + FNT_Face_Done, /* FT_Face_DoneFunc done_face */ + 0, /* FT_Size_InitFunc init_size */ + 0, /* FT_Size_DoneFunc done_size */ + 0, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - FNT_Load_Glyph, + FNT_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - FNT_Size_Request, - FNT_Size_Select + FNT_Size_Request, /* FT_Size_RequestFunc request_size */ + FNT_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/src/winfonts/winfnt.h b/drivers/freetype/src/winfonts/winfnt.h index b7a80736d8..9a4f32d5b0 100644 --- a/drivers/freetype/src/winfonts/winfnt.h +++ b/drivers/freetype/src/winfonts/winfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ /* */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __WINFNT_H__ -#define __WINFNT_H__ +#ifndef WINFNT_H_ +#define WINFNT_H_ #include <ft2build.h> @@ -165,7 +165,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __WINFNT_H__ */ +#endif /* WINFNT_H_ */ /* END */ -- cgit v1.2.3